[llvm] r235037 - [WinEH] Try to make the MachineFunction CFG more accurate
Reid Kleckner
reid at kleckner.net
Wed Apr 15 11:48:15 PDT 2015
Author: rnk
Date: Wed Apr 15 13:48:15 2015
New Revision: 235037
URL: http://llvm.org/viewvc/llvm-project?rev=235037&view=rev
Log:
[WinEH] Try to make the MachineFunction CFG more accurate
This avoids emitting code for unreachable landingpad blocks that contain
calls to llvm.eh.actions and indirectbr.
It's also a first step towards unifying the SEH and WinEH lowering
codepaths. I'm keeping the old fan-in lowering of SEH around until the
preparation version works well enough that we can switch over without
breaking existing users.
Modified:
llvm/trunk/lib/CodeGen/AsmPrinter/Win64Exception.cpp
llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
llvm/trunk/test/CodeGen/WinEH/cppeh-prepared-catch.ll
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/Win64Exception.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/Win64Exception.cpp?rev=235037&r1=235036&r2=235037&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/Win64Exception.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/Win64Exception.cpp Wed Apr 15 13:48:15 2015
@@ -108,8 +108,13 @@ void Win64Exception::endFunction(const M
if (!shouldEmitPersonality && !shouldEmitMoves)
return;
- // Map all labels and get rid of any dead landing pads.
- MMI->TidyLandingPads();
+ EHPersonality Per = MMI->getPersonalityType();
+
+ // Get rid of any dead landing pads if we're not using a Windows EH scheme. In
+ // Windows EH schemes, the landing pad is not actually reachable. It only
+ // exists so that we can emit the right table data.
+ if (!isMSVCEHPersonality(Per))
+ MMI->TidyLandingPads();
if (shouldEmitPersonality) {
Asm->OutStreamer.PushSection();
@@ -119,7 +124,6 @@ void Win64Exception::endFunction(const M
// Emit the tables appropriate to the personality function in use. If we
// don't recognize the personality, assume it uses an Itanium-style LSDA.
- EHPersonality Per = MMI->getPersonalityType();
if (Per == EHPersonality::MSVC_Win64SEH)
emitCSpecificHandlerTable();
else if (Per == EHPersonality::MSVC_CXX)
Modified: llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp?rev=235037&r1=235036&r2=235037&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp Wed Apr 15 13:48:15 2015
@@ -570,10 +570,13 @@ const Function *MachineModuleInfo::getPe
}
EHPersonality MachineModuleInfo::getPersonalityType() {
- if (PersonalityTypeCache == EHPersonality::Unknown)
- PersonalityTypeCache = classifyEHPersonality(getPersonality());
+ if (PersonalityTypeCache == EHPersonality::Unknown) {
+ if (const Function *F = getPersonality())
+ PersonalityTypeCache = classifyEHPersonality(F);
+ }
return PersonalityTypeCache;
}
+
/// getPersonalityIndex - Return unique index for current personality
/// function. NULL/first personality function should always get zero index.
unsigned MachineModuleInfo::getPersonalityIndex() const {
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=235037&r1=235036&r2=235037&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Apr 15 13:48:15 2015
@@ -933,53 +933,74 @@ void SelectionDAGISel::PrepareEHLandingP
const LandingPadInst *LPadInst = LLVMBB->getLandingPadInst();
MF->getMMI().addPersonality(
MBB, cast<Function>(LPadInst->getPersonalityFn()->stripPointerCasts()));
- if (MF->getMMI().getPersonalityType() == EHPersonality::MSVC_Win64SEH) {
- // Make virtual registers and a series of labels that fill in values for the
- // clauses.
- auto &RI = MF->getRegInfo();
- FuncInfo->ExceptionSelectorVirtReg = RI.createVirtualRegister(PtrRC);
+ EHPersonality Personality = MF->getMMI().getPersonalityType();
- // Get all invoke BBs that will unwind into the clause BBs.
+ if (isMSVCEHPersonality(Personality)) {
+ SmallVector<MachineBasicBlock *, 4> ClauseBBs;
+ const IntrinsicInst *Actions =
+ dyn_cast<IntrinsicInst>(LLVMBB->getFirstInsertionPt());
+ // Get all invoke BBs that unwind to this landingpad.
SmallVector<MachineBasicBlock *, 4> InvokeBBs(MBB->pred_begin(),
MBB->pred_end());
+ if (Actions && Actions->getIntrinsicID() == Intrinsic::eh_actions) {
+ // If this is a call to llvm.eh.actions followed by indirectbr, then we've
+ // run WinEHPrepare, and we should remove this block from the machine CFG.
+ // Mark the targets of the indirectbr as landingpads instead.
+ for (const BasicBlock *LLVMSucc : successors(LLVMBB)) {
+ MachineBasicBlock *ClauseBB = FuncInfo->MBBMap[LLVMSucc];
+ // Add the edge from the invoke to the clause.
+ for (MachineBasicBlock *InvokeBB : InvokeBBs)
+ InvokeBB->addSuccessor(ClauseBB);
+ }
+ } else {
+ // Otherwise, we haven't done the preparation, and we need to invent some
+ // clause basic blocks that branch into the landingpad.
+ // FIXME: Remove this code once SEH preparation works.
+
+ // Make virtual registers and a series of labels that fill in values for
+ // the clauses.
+ auto &RI = MF->getRegInfo();
+ FuncInfo->ExceptionSelectorVirtReg = RI.createVirtualRegister(PtrRC);
+
+ // Emit separate machine basic blocks with separate labels for each clause
+ // before the main landing pad block.
+ MachineInstrBuilder SelectorPHI = BuildMI(
+ *MBB, MBB->begin(), SDB->getCurDebugLoc(),
+ TII->get(TargetOpcode::PHI), FuncInfo->ExceptionSelectorVirtReg);
+ for (unsigned I = 0, E = LPadInst->getNumClauses(); I != E; ++I) {
+ // Skip filter clauses, we can't implement them.
+ if (LPadInst->isFilter(I))
+ continue;
+
+ MachineBasicBlock *ClauseBB = MF->CreateMachineBasicBlock(LLVMBB);
+ MF->insert(MBB, ClauseBB);
+
+ // Add the edge from the invoke to the clause.
+ for (MachineBasicBlock *InvokeBB : InvokeBBs)
+ InvokeBB->addSuccessor(ClauseBB);
+
+ // Mark the clause as a landing pad or MI passes will delete it.
+ ClauseBB->setIsLandingPad();
+
+ GlobalValue *ClauseGV = ExtractTypeInfo(LPadInst->getClause(I));
+
+ // Start the BB with a label.
+ MCSymbol *ClauseLabel = MF->getMMI().addClauseForLandingPad(MBB);
+ BuildMI(*ClauseBB, ClauseBB->begin(), SDB->getCurDebugLoc(), II)
+ .addSym(ClauseLabel);
+
+ // Construct a simple BB that defines a register with the typeid
+ // constant.
+ FuncInfo->MBB = ClauseBB;
+ FuncInfo->InsertPt = ClauseBB->end();
+ unsigned VReg = SDB->visitLandingPadClauseBB(ClauseGV, MBB);
+ CurDAG->setRoot(SDB->getRoot());
+ SDB->clear();
+ CodeGenAndEmitDAG();
- // Emit separate machine basic blocks with separate labels for each clause
- // before the main landing pad block.
- MachineInstrBuilder SelectorPHI = BuildMI(
- *MBB, MBB->begin(), SDB->getCurDebugLoc(), TII->get(TargetOpcode::PHI),
- FuncInfo->ExceptionSelectorVirtReg);
- for (unsigned I = 0, E = LPadInst->getNumClauses(); I != E; ++I) {
- // Skip filter clauses, we can't implement them yet.
- if (LPadInst->isFilter(I))
- continue;
-
- MachineBasicBlock *ClauseBB = MF->CreateMachineBasicBlock(LLVMBB);
- MF->insert(MBB, ClauseBB);
-
- // Add the edge from the invoke to the clause.
- for (MachineBasicBlock *InvokeBB : InvokeBBs)
- InvokeBB->addSuccessor(ClauseBB);
-
- // Mark the clause as a landing pad or MI passes will delete it.
- ClauseBB->setIsLandingPad();
-
- GlobalValue *ClauseGV = ExtractTypeInfo(LPadInst->getClause(I));
-
- // Start the BB with a label.
- MCSymbol *ClauseLabel = MF->getMMI().addClauseForLandingPad(MBB);
- BuildMI(*ClauseBB, ClauseBB->begin(), SDB->getCurDebugLoc(), II)
- .addSym(ClauseLabel);
-
- // Construct a simple BB that defines a register with the typeid constant.
- FuncInfo->MBB = ClauseBB;
- FuncInfo->InsertPt = ClauseBB->end();
- unsigned VReg = SDB->visitLandingPadClauseBB(ClauseGV, MBB);
- CurDAG->setRoot(SDB->getRoot());
- SDB->clear();
- CodeGenAndEmitDAG();
-
- // Add the typeid virtual register to the phi in the main landing pad.
- SelectorPHI.addReg(VReg).addMBB(ClauseBB);
+ // Add the typeid virtual register to the phi in the main landing pad.
+ SelectorPHI.addReg(VReg).addMBB(ClauseBB);
+ }
}
// Remove the edge from the invoke to the lpad.
@@ -990,12 +1011,14 @@ void SelectionDAGISel::PrepareEHLandingP
// pad block.
FuncInfo->MBB = MBB;
FuncInfo->InsertPt = MBB->end();
+
+ // Transfer EH state number assigned to the IR block to the MBB.
+ if (Personality == EHPersonality::MSVC_CXX) {
+ WinEHFuncInfo &FI = MF->getMMI().getWinEHFuncInfo(MF->getFunction());
+ MF->getMMI().addWinEHState(MBB, FI.LandingPadStateMap[LPadInst]);
+ }
return;
}
- if (MF->getMMI().getPersonalityType() == EHPersonality::MSVC_CXX) {
- WinEHFuncInfo &FuncInfo = MF->getMMI().getWinEHFuncInfo(MF->getFunction());
- MF->getMMI().addWinEHState(MBB, FuncInfo.LandingPadStateMap[LPadInst]);
- }
// Mark exception register as live in.
if (unsigned Reg = TLI->getExceptionPointerRegister())
@@ -1173,7 +1196,7 @@ void SelectionDAGISel::SelectAllBasicBlo
// Setup an EH landing-pad block.
FuncInfo->ExceptionPointerVirtReg = 0;
FuncInfo->ExceptionSelectorVirtReg = 0;
- if (FuncInfo->MBB->isLandingPad())
+ if (LLVMBB->isLandingPad())
PrepareEHLandingPad();
// Before doing SelectionDAG ISel, see if FastISel has been requested.
Modified: llvm/trunk/test/CodeGen/WinEH/cppeh-prepared-catch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/cppeh-prepared-catch.ll?rev=235037&r1=235036&r2=235037&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/cppeh-prepared-catch.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/cppeh-prepared-catch.ll Wed Apr 15 13:48:15 2015
@@ -50,6 +50,8 @@ lpad1:
}
; CHECK-LABEL: "?f@@YAXXZ.catch":
+; No code should be generated for the indirectbr.
+; CHECK-NOT: jmpq *
; CHECK: .seh_handlerdata
; CHECK: .long ("$cppxdata$?f@@YAXXZ")@IMGREL
@@ -72,6 +74,8 @@ lpad:
}
; CHECK-LABEL: "?f@@YAXXZ.catch1":
+; No code should be generated for the indirectbr.
+; CHECK-NOT: jmpq *
; CHECK: ".L?f@@YAXXZ.catch1$parent_frame_offset" = 16
; CHECK: movq %rdx, 16(%rsp)
; CHECK: .seh_handlerdata
@@ -112,6 +116,8 @@ try.cont8:
}
; CHECK-LABEL: "?f@@YAXXZ":
+; No code should be generated for the indirectbr.
+; CHECK-NOT: jmpq *
; CHECK: .seh_handlerdata
; CHECK-NEXT: .long ("$cppxdata$?f@@YAXXZ")@IMGREL
; CHECK-NEXT:"$cppxdata$?f@@YAXXZ":
More information about the llvm-commits
mailing list