summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/X86/X86FrameLowering.cpp13
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp26
-rw-r--r--llvm/lib/Target/X86/X86WinEHState.cpp110
3 files changed, 51 insertions, 98 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index 72baa078661..4fbe3613d1e 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -1252,7 +1252,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
assert(classifyEHPersonality(Fn->getPersonalityFn()) ==
EHPersonality::MSVC_CXX);
unsigned FrameReg;
- int FI = MMI.getWinEHFuncInfo(Fn).EHRegNodeFrameIndex;
+ int FI = MF.getWinEHFuncInfo()->EHRegNodeFrameIndex;
int64_t EHRegOffset = getFrameIndexReference(MF, FI, FrameReg);
// ESP is the first field, so no extra displacement is needed.
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32mr)), FrameReg,
@@ -1292,7 +1292,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
// and the GC can recover it.
unsigned PSPSlotOffset = getPSPSlotOffsetFromSP(MF);
auto PSPInfo = MachinePointerInfo::getFixedStack(
- MF, MF.getMMI().getWinEHFuncInfo(Fn).PSPSymFrameIdx);
+ MF, MF.getWinEHFuncInfo()->PSPSymFrameIdx);
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64mr)), StackPtr, false,
PSPSlotOffset)
.addReg(StackPtr)
@@ -1401,8 +1401,7 @@ static bool isFuncletReturnInstr(MachineInstr *MI) {
// frame with only a single offset reported for the entire method.
unsigned
X86FrameLowering::getPSPSlotOffsetFromSP(const MachineFunction &MF) const {
- MachineModuleInfo &MMI = MF.getMMI();
- WinEHFuncInfo &Info = MMI.getWinEHFuncInfo(MF.getFunction());
+ const WinEHFuncInfo &Info = *MF.getWinEHFuncInfo();
// getFrameIndexReferenceFromSP has an out ref parameter for the stack
// pointer register; pass a dummy that we ignore
unsigned SPReg;
@@ -2592,9 +2591,7 @@ MachineBasicBlock::iterator X86FrameLowering::restoreWin32EHStackPointers(
MachineFunction &MF = *MBB.getParent();
unsigned FramePtr = TRI->getFrameRegister(MF);
unsigned BasePtr = TRI->getBaseRegister();
- MachineModuleInfo &MMI = MF.getMMI();
- const Function *Fn = MF.getFunction();
- WinEHFuncInfo &FuncInfo = MMI.getWinEHFuncInfo(Fn);
+ WinEHFuncInfo &FuncInfo = *MF.getWinEHFuncInfo();
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
MachineFrameInfo *MFI = MF.getFrameInfo();
@@ -2679,7 +2676,7 @@ void X86FrameLowering::processFunctionBeforeFrameFinalized(
int64_t UnwindHelpOffset = MinFixedObjOffset - SlotSize;
int UnwindHelpFI =
MFI->CreateFixedObject(SlotSize, UnwindHelpOffset, /*Immutable=*/false);
- MF.getMMI().getWinEHFuncInfo(Fn).UnwindHelpFrameIdx = UnwindHelpFI;
+ MF.getWinEHFuncInfo()->UnwindHelpFrameIdx = UnwindHelpFI;
// Store -2 into UnwindHelp on function entry. We have to scan forwards past
// other frame setup instructions.
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index c944e3deec5..2be35511f18 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2721,8 +2721,6 @@ SDValue X86TargetLowering::LowerFormalArguments(
MFI->CreateFixedObject(1, StackSize, true));
}
- MachineModuleInfo &MMI = MF.getMMI();
-
// Figure out if XMM registers are in use.
assert(!(Subtarget->useSoftFloat() &&
Fn->hasFnAttribute(Attribute::NoImplicitFloat)) &&
@@ -2878,7 +2876,7 @@ SDValue X86TargetLowering::LowerFormalArguments(
FuncInfo->setArgumentStackSize(StackSize);
- if (MMI.hasWinEHFuncInfo(Fn)) {
+ if (WinEHFuncInfo *EHInfo = MF.getWinEHFuncInfo()) {
EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn());
if (Personality == EHPersonality::CoreCLR) {
assert(Is64Bit);
@@ -2891,7 +2889,7 @@ SDValue X86TargetLowering::LowerFormalArguments(
// how far this slot is from the bottom (since they allocate just enough
// space to accomodate holding this slot at the correct offset).
int PSPSymFI = MFI->CreateStackObject(8, 8, /*isSS=*/false);
- MMI.getWinEHFuncInfo(MF.getFunction()).PSPSymFrameIdx = PSPSymFI;
+ EHInfo->PSPSymFrameIdx = PSPSymFI;
}
}
@@ -16940,6 +16938,24 @@ static SDValue LowerSEHRESTOREFRAME(SDValue Op, const X86Subtarget *Subtarget,
return Chain;
}
+static SDValue MarkEHRegistrationNode(SDValue Op, SelectionDAG &DAG) {
+ MachineFunction &MF = DAG.getMachineFunction();
+ SDValue Chain = Op.getOperand(0);
+ SDValue RegNode = Op.getOperand(2);
+ WinEHFuncInfo *EHInfo = MF.getWinEHFuncInfo();
+ if (!EHInfo)
+ report_fatal_error("EH registrations only live in functions using WinEH");
+
+ // Cast the operand to an alloca, and remember the frame index.
+ auto *FINode = dyn_cast<FrameIndexSDNode>(RegNode);
+ if (!FINode)
+ report_fatal_error("llvm.x86.seh.ehregnode expects a static alloca");
+ EHInfo->EHRegNodeFrameIndex = FINode->getIndex();
+
+ // Return the chain operand without making any DAG nodes.
+ return Chain;
+}
+
/// \brief Lower intrinsics for TRUNCATE_TO_MEM case
/// return truncate Store/MaskedStore Node
static SDValue LowerINTRINSIC_TRUNCATE_TO_MEM(const SDValue & Op,
@@ -16985,6 +17001,8 @@ static SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, const X86Subtarget *Subtarget,
if (!IntrData) {
if (IntNo == llvm::Intrinsic::x86_seh_restoreframe)
return LowerSEHRESTOREFRAME(Op, Subtarget, DAG);
+ else if (IntNo == llvm::Intrinsic::x86_seh_ehregnode)
+ return MarkEHRegistrationNode(Op, DAG);
return SDValue();
}
diff --git a/llvm/lib/Target/X86/X86WinEHState.cpp b/llvm/lib/Target/X86/X86WinEHState.cpp
index db717385da6..8a5aa40bc7f 100644
--- a/llvm/lib/Target/X86/X86WinEHState.cpp
+++ b/llvm/lib/Target/X86/X86WinEHState.cpp
@@ -66,18 +66,13 @@ private:
void linkExceptionRegistration(IRBuilder<> &Builder, Function *Handler);
void unlinkExceptionRegistration(IRBuilder<> &Builder);
- void addCXXStateStores(Function &F, WinEHFuncInfo &FuncInfo);
- void addSEHStateStores(Function &F, WinEHFuncInfo &FuncInfo);
- void addStateStoresToFunclet(Value *ParentRegNode, WinEHFuncInfo &FuncInfo,
- Function &F, int BaseState);
+ void addStateStores(Function &F, WinEHFuncInfo &FuncInfo);
void insertStateNumberStore(Value *ParentRegNode, Instruction *IP, int State);
Value *emitEHLSDA(IRBuilder<> &Builder, Function *F);
Function *generateLSDAInEAXThunk(Function *ParentFunc);
- int escapeRegNode(Function &F);
-
// Module-level type getters.
Type *getEHLinkRegistrationType();
Type *getSEHRegistrationType();
@@ -178,26 +173,13 @@ bool WinEHStatePass::runOnFunction(Function &F) {
emitExceptionRegistrationRecord(&F);
- auto *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
- // If MMI is null, create our own WinEHFuncInfo. This only happens in opt
- // tests.
- std::unique_ptr<WinEHFuncInfo> FuncInfoPtr;
- if (!MMI)
- FuncInfoPtr.reset(new WinEHFuncInfo());
- WinEHFuncInfo &FuncInfo =
- *(MMI ? &MMI->getWinEHFuncInfo(&F) : FuncInfoPtr.get());
-
- FuncInfo.EHRegNode = RegNode;
-
- switch (Personality) {
- default: llvm_unreachable("unexpected personality function");
- case EHPersonality::MSVC_CXX:
- addCXXStateStores(F, FuncInfo);
- break;
- case EHPersonality::MSVC_X86SEH:
- addSEHStateStores(F, FuncInfo);
- break;
- }
+ // The state numbers calculated here in IR must agree with what we calculate
+ // later on for the MachineFunction. In particular, if an IR pass deletes an
+ // unreachable EH pad after this point before machine CFG construction, we
+ // will be in trouble. If this assumption is ever broken, we should turn the
+ // numbers into an immutable analysis pass.
+ WinEHFuncInfo FuncInfo;
+ addStateStores(F, FuncInfo);
// Reset per-function state.
PersonalityFn = nullptr;
@@ -418,65 +400,21 @@ void WinEHStatePass::unlinkExceptionRegistration(IRBuilder<> &Builder) {
Builder.CreateStore(Next, FSZero);
}
-void WinEHStatePass::addCXXStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
- // Set up RegNodeEscapeIndex
- int RegNodeEscapeIndex = escapeRegNode(F);
- FuncInfo.EHRegNodeEscapeIndex = RegNodeEscapeIndex;
-
- calculateWinCXXEHStateNumbers(&F, FuncInfo);
- addStateStoresToFunclet(RegNode, FuncInfo, F, -1);
-}
-
-/// Assign every distinct landingpad a unique state number for SEH. Unlike C++
-/// EH, we can use this very simple algorithm while C++ EH cannot because catch
-/// handlers aren't outlined and the runtime doesn't have to figure out which
-/// catch handler frame to unwind to.
-void WinEHStatePass::addSEHStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
- // Remember and return the index that we used. We save it in WinEHFuncInfo so
- // that we can lower llvm.x86.seh.recoverfp later in filter functions without
- // too much trouble.
- int RegNodeEscapeIndex = escapeRegNode(F);
- FuncInfo.EHRegNodeEscapeIndex = RegNodeEscapeIndex;
-
- calculateSEHStateNumbers(&F, FuncInfo);
- addStateStoresToFunclet(RegNode, FuncInfo, F, -1);
-}
-
-/// Escape RegNode so that we can access it from child handlers. Find the call
-/// to localescape, if any, in the entry block and append RegNode to the list
-/// of arguments.
-int WinEHStatePass::escapeRegNode(Function &F) {
- // Find the call to localescape and extract its arguments.
- IntrinsicInst *EscapeCall = nullptr;
- for (Instruction &I : F.getEntryBlock()) {
- IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
- if (II && II->getIntrinsicID() == Intrinsic::localescape) {
- EscapeCall = II;
- break;
- }
- }
- SmallVector<Value *, 8> Args;
- if (EscapeCall) {
- auto Ops = EscapeCall->arg_operands();
- Args.append(Ops.begin(), Ops.end());
- }
- Args.push_back(RegNode);
-
- // Replace the call (if it exists) with new one. Otherwise, insert at the end
- // of the entry block.
- Instruction *InsertPt = EscapeCall;
- if (!EscapeCall)
- InsertPt = F.getEntryBlock().getTerminator();
- IRBuilder<> Builder(InsertPt);
- Builder.CreateCall(FrameEscape, Args);
- if (EscapeCall)
- EscapeCall->eraseFromParent();
- return Args.size() - 1;
-}
+void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
+ // Mark the registration node. The backend needs to know which alloca it is so
+ // that it can recover the original frame pointer.
+ IRBuilder<> Builder(RegNode->getParent(), std::next(RegNode->getIterator()));
+ Value *RegNodeI8 = Builder.CreateBitCast(RegNode, Builder.getInt8PtrTy());
+ Builder.CreateCall(
+ Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_ehregnode),
+ {RegNodeI8});
+
+ // Calculate state numbers.
+ if (isAsynchronousEHPersonality(Personality))
+ calculateSEHStateNumbers(&F, FuncInfo);
+ else
+ calculateWinCXXEHStateNumbers(&F, FuncInfo);
-void WinEHStatePass::addStateStoresToFunclet(Value *ParentRegNode,
- WinEHFuncInfo &FuncInfo,
- Function &F, int BaseState) {
// Iterate all the instructions and emit state number stores.
for (BasicBlock &BB : F) {
for (Instruction &I : BB) {
@@ -485,14 +423,14 @@ void WinEHStatePass::addStateStoresToFunclet(Value *ParentRegNode,
// an unwind. Ensure they are in the -1 state.
if (CI->doesNotThrow())
continue;
- insertStateNumberStore(ParentRegNode, CI, BaseState);
+ insertStateNumberStore(RegNode, CI, -1);
} else if (auto *II = dyn_cast<InvokeInst>(&I)) {
// Look up the state number of the landingpad this unwinds to.
Instruction *PadInst = II->getUnwindDest()->getFirstNonPHI();
// FIXME: Why does this assertion fail?
//assert(FuncInfo.EHPadStateMap.count(PadInst) && "EH Pad has no state!");
int State = FuncInfo.EHPadStateMap[PadInst];
- insertStateNumberStore(ParentRegNode, II, State);
+ insertStateNumberStore(RegNode, II, State);
}
}
}
OpenPOWER on IntegriCloud