MachineModuleInfo: Move HasSplitStack handling to AsmPrinter

This is used to emit one field in doFinalization for the module. We
can accumulate this when emitting all individual functions directly in
the AsmPrinter, rather than accumulating additional state in
MachineModuleInfo.

Move the special case behavior predicate into MachineFrameInfo to
share it. This now promotes it to generic behavior. I'm assuming this
is fine because no other target implements adjustForSegmentedStacks,
or has tests using the split-stack attribute.
This commit is contained in:
Matt Arsenault 2022-04-17 10:47:38 -04:00
parent 8544523dcb
commit d7938b1a81
9 changed files with 44 additions and 58 deletions

View File

@ -210,6 +210,16 @@ private:
/// CFISection type the module needs i.e. either .eh_frame or .debug_frame.
CFISection ModuleCFISection = CFISection::None;
/// True if the module contains split-stack functions. This is used to
/// emit .note.GNU-split-stack section as required by the linker for
/// special handling split-stack function calling no-split-stack function.
bool HasSplitStack = false;
/// True if the module contains no-split-stack functions. This is used to emit
/// .note.GNU-no-split-stack section when it also contains functions without a
/// split stack prologue.
bool HasNoSplitStack = false;
protected:
explicit AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);

View File

@ -385,6 +385,20 @@ public:
bool hasPatchPoint() const { return HasPatchPoint; }
void setHasPatchPoint(bool s = true) { HasPatchPoint = s; }
/// Return true if this function requires a split stack prolog, even if it
/// uses no stack space. This is only meaningful for functions where
/// MachineFunction::shouldSplitStack() returns true.
//
// For non-leaf functions we have to allow for the possibility that the call
// is to a non-split function, as in PR37807. This function could also take
// the address of a non-split function. When the linker tries to adjust its
// non-existent prologue, it would fail with an error. Mark the object file so
// that such failures are not errors. See this Go language bug-report
// https://go-review.googlesource.com/c/go/+/148819/
bool needsSplitStackProlog() const {
return getStackSize() != 0 || hasTailCall();
}
/// Return the minimum frame object index.
int getObjectIndexBegin() const { return -NumFixedObjects; }

View File

@ -129,16 +129,6 @@ class MachineModuleInfo {
/// comments in lib/Target/X86/X86FrameLowering.cpp for more details.
bool UsesMorestackAddr;
/// True if the module contains split-stack functions. This is used to
/// emit .note.GNU-split-stack section as required by the linker for
/// special handling split-stack function calling no-split-stack function.
bool HasSplitStack;
/// True if the module contains no-split-stack functions. This is used to
/// emit .note.GNU-no-split-stack section when it also contains split-stack
/// functions.
bool HasNosplitStack;
/// Maps IR Functions to their corresponding MachineFunctions.
DenseMap<const Function*, std::unique_ptr<MachineFunction>> MachineFunctions;
/// Next unique number available for a MachineFunction.
@ -213,22 +203,6 @@ public:
UsesMorestackAddr = b;
}
bool hasSplitStack() const {
return HasSplitStack;
}
void setHasSplitStack(bool b) {
HasSplitStack = b;
}
bool hasNosplitStack() const {
return HasNosplitStack;
}
void setHasNosplitStack(bool b) {
HasNosplitStack = b;
}
/// Return the symbol to be used for the specified basic block when its
/// address is taken. This cannot be its normal LBB label because the block
/// may be accessed outside its containing function.

View File

@ -257,6 +257,8 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
bool AsmPrinter::doInitialization(Module &M) {
auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>();
MMI = MMIWP ? &MMIWP->getMMI() : nullptr;
HasSplitStack = false;
HasNoSplitStack = false;
// Initialize TargetLoweringObjectFile.
const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
@ -1921,10 +1923,10 @@ bool AsmPrinter::doFinalization(Module &M) {
// Emit .note.GNU-split-stack and .note.GNU-no-split-stack sections if
// split-stack is used.
if (TM.getTargetTriple().isOSBinFormatELF() && MMI->hasSplitStack()) {
if (TM.getTargetTriple().isOSBinFormatELF() && HasSplitStack) {
OutStreamer->SwitchSection(
OutContext.getELFSection(".note.GNU-split-stack", ELF::SHT_PROGBITS, 0));
if (MMI->hasNosplitStack())
if (HasNoSplitStack)
OutStreamer->SwitchSection(
OutContext.getELFSection(".note.GNU-no-split-stack", ELF::SHT_PROGBITS, 0));
}
@ -1991,6 +1993,16 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
this->MF = &MF;
const Function &F = MF.getFunction();
// Record that there are split-stack functions, so we will emit a special
// section to tell the linker.
if (MF.shouldSplitStack()) {
HasSplitStack = true;
if (!MF.getFrameInfo().needsSplitStackProlog())
HasNoSplitStack = true;
} else
HasNoSplitStack = true;
// Get the function symbol.
if (!MAI->needsFunctionDescriptors()) {
CurrentFnSym = getSymbol(&MF.getFunction());

View File

@ -203,7 +203,6 @@ void MachineModuleInfo::initialize() {
CurCallSite = 0;
NextFnNum = 0;
UsesMSVCFloatingPoint = UsesMorestackAddr = false;
HasSplitStack = HasNosplitStack = false;
AddrLabelSymbols = nullptr;
DbgInfoAvailable = false;
}
@ -232,8 +231,6 @@ MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI)
CurCallSite = MMI.CurCallSite;
UsesMSVCFloatingPoint = MMI.UsesMSVCFloatingPoint;
UsesMorestackAddr = MMI.UsesMorestackAddr;
HasSplitStack = MMI.HasSplitStack;
HasNosplitStack = MMI.HasNosplitStack;
AddrLabelSymbols = MMI.AddrLabelSymbols;
ExternalContext = MMI.ExternalContext;
TheModule = MMI.TheModule;

View File

@ -1144,11 +1144,7 @@ void PEI::insertPrologEpilogCode(MachineFunction &MF) {
if (MF.shouldSplitStack()) {
for (MachineBasicBlock *SaveBlock : SaveBlocks)
TFI.adjustForSegmentedStacks(MF, *SaveBlock);
// Record that there are split-stack functions, so we will emit a
// special section to tell the linker.
MF.getMMI().setHasSplitStack(true);
} else
MF.getMMI().setHasNosplitStack(true);
}
// Emit additional code that is required to explicitly handle the stack in
// HiPE native code (if needed) when loaded in the Erlang/OTP runtime. The

View File

@ -24,6 +24,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"

View File

@ -2506,19 +2506,10 @@ void ARMFrameLowering::adjustForSegmentedStacks(
ARMFunctionInfo *ARMFI = MF.getInfo<ARMFunctionInfo>();
DebugLoc DL;
uint64_t StackSize = MFI.getStackSize();
// Do not generate a prologue for leaf functions with a stack of size zero.
// For non-leaf functions we have to allow for the possibility that the
// callis to a non-split function, as in PR37807. This function could also
// take the address of a non-split function. When the linker tries to adjust
// its non-existent prologue, it would fail with an error. Mark the object
// file so that such failures are not errors. See this Go language bug-report
// https://go-review.googlesource.com/c/go/+/148819/
if (StackSize == 0 && !MFI.hasTailCall()) {
MF.getMMI().setHasNosplitStack(true);
if (!MFI.needsSplitStackProlog())
return;
}
uint64_t StackSize = MFI.getStackSize();
// Use R4 and R5 as scratch registers.
// We save R4 and R5 before use and restore them before leaving the function.

View File

@ -2944,17 +2944,8 @@ void X86FrameLowering::adjustForSegmentedStacks(
// prologue.
StackSize = MFI.getStackSize();
// Do not generate a prologue for leaf functions with a stack of size zero.
// For non-leaf functions we have to allow for the possibility that the
// callis to a non-split function, as in PR37807. This function could also
// take the address of a non-split function. When the linker tries to adjust
// its non-existent prologue, it would fail with an error. Mark the object
// file so that such failures are not errors. See this Go language bug-report
// https://go-review.googlesource.com/c/go/+/148819/
if (StackSize == 0 && !MFI.hasTailCall()) {
MF.getMMI().setHasNosplitStack(true);
if (!MFI.needsSplitStackProlog())
return;
}
MachineBasicBlock *allocMBB = MF.CreateMachineBasicBlock();
MachineBasicBlock *checkMBB = MF.CreateMachineBasicBlock();