summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2015-10-07 00:27:33 +0000
committerReid Kleckner <rnk@google.com>2015-10-07 00:27:33 +0000
commit72ba70418f1d2801c5707768da9533f46d6a773f (patch)
tree3fd58552d5a966bedba0c66ee928c0d2ae89dfbe /llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
parentee59282bfd2dfc0175591176c3e45c8ecf0931cf (diff)
downloadbcm5719-llvm-72ba70418f1d2801c5707768da9533f46d6a773f.tar.gz
bcm5719-llvm-72ba70418f1d2801c5707768da9533f46d6a773f.zip
[SEH] Add llvm.eh.exceptioncode intrinsic
This will support the Clang __exception_code intrinsic. llvm-svn: 249492
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp41
1 files changed, 35 insertions, 6 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index c20270d9a7e..bd60bba318c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -922,14 +922,46 @@ void SelectionDAGISel::DoInstructionSelection() {
PostprocessISelDAG();
}
+static bool hasExceptionPointerOrCodeUser(const CatchPadInst *CPI) {
+ for (const User *U : CPI->users()) {
+ if (const IntrinsicInst *EHPtrCall = dyn_cast<IntrinsicInst>(U)) {
+ Intrinsic::ID IID = EHPtrCall->getIntrinsicID();
+ if (IID == Intrinsic::eh_exceptionpointer ||
+ IID == Intrinsic::eh_exceptioncode)
+ return true;
+ }
+ }
+ return false;
+}
+
/// PrepareEHLandingPad - Emit an EH_LABEL, set up live-in registers, and
/// do other setup for EH landing-pad blocks.
bool SelectionDAGISel::PrepareEHLandingPad() {
MachineBasicBlock *MBB = FuncInfo->MBB;
-
+ const BasicBlock *LLVMBB = MBB->getBasicBlock();
const TargetRegisterClass *PtrRC =
TLI->getRegClassFor(TLI->getPointerTy(CurDAG->getDataLayout()));
+ // Catchpads have one live-in register, which typically holds the exception
+ // pointer or code.
+ if (const auto *CPI = dyn_cast<CatchPadInst>(LLVMBB->getFirstNonPHI())) {
+ if (hasExceptionPointerOrCodeUser(CPI)) {
+ // Get or create the virtual register to hold the pointer or code. Mark
+ // the live in physreg and copy into the vreg.
+ MCPhysReg EHPhysReg = TLI->getExceptionPointerRegister();
+ assert(EHPhysReg && "target lacks exception pointer register");
+ FuncInfo->ExceptionPointerVirtReg = MBB->addLiveIn(EHPhysReg, PtrRC);
+ unsigned VReg = FuncInfo->getCatchPadExceptionPointerVReg(CPI, PtrRC);
+ BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(),
+ TII->get(TargetOpcode::COPY), VReg)
+ .addReg(EHPhysReg, RegState::Kill);
+ }
+ return true;
+ }
+
+ if (!LLVMBB->isLandingPad())
+ return true;
+
// Add a label to mark the beginning of the landing pad. Deletion of the
// landing pad can thus be detected via the MachineModuleInfo.
MCSymbol *Label = MF->getMMI().addLandingPad(MBB);
@@ -943,7 +975,6 @@ bool SelectionDAGISel::PrepareEHLandingPad() {
// If this personality function uses funclets, we need to split the landing
// pad into several BBs.
- const BasicBlock *LLVMBB = MBB->getBasicBlock();
const Constant *Personality = MF->getFunction()->getPersonalityFn();
if (const auto *PF = dyn_cast<Function>(Personality->stripPointerCasts()))
MF->getMMI().addPersonality(PF);
@@ -1159,10 +1190,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
// Setup an EH landing-pad block.
FuncInfo->ExceptionPointerVirtReg = 0;
FuncInfo->ExceptionSelectorVirtReg = 0;
- if (LLVMBB->isLandingPad())
- if (!PrepareEHLandingPad())
- continue;
-
+ if (!PrepareEHLandingPad())
+ continue;
// Before doing SelectionDAG ISel, see if FastISel has been requested.
if (FastIS) {
OpenPOWER on IntegriCloud