Skip to content

Commit 72ba704

Browse files
committedOct 7, 2015
[SEH] Add llvm.eh.exceptioncode intrinsic
This will support the Clang __exception_code intrinsic. llvm-svn: 249492
1 parent ee59282 commit 72ba704

File tree

10 files changed

+87
-21
lines changed

10 files changed

+87
-21
lines changed
 

Diff for: ‎llvm/include/llvm/CodeGen/FunctionLoweringInfo.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ class FunctionLoweringInfo {
7272
/// ValueMap - Since we emit code for the function a basic block at a time,
7373
/// we must remember which virtual registers hold the values for
7474
/// cross-basic-block values.
75-
DenseMap<const Value*, unsigned> ValueMap;
75+
DenseMap<const Value *, unsigned> ValueMap;
76+
77+
/// Track virtual registers created for exception pointers.
78+
DenseMap<const Value *, unsigned> CatchPadExceptionPointers;
7679

7780
// Keep track of frame indices allocated for statepoints as they could be used
7881
// across basic block boundaries.
@@ -234,6 +237,9 @@ class FunctionLoweringInfo {
234237
/// getArgumentFrameIndex - Get frame index for the byval argument.
235238
int getArgumentFrameIndex(const Argument *A);
236239

240+
unsigned getCatchPadExceptionPointerVReg(const Value *CPI,
241+
const TargetRegisterClass *RC);
242+
237243
private:
238244
void addSEHHandlersForLPads(ArrayRef<const LandingPadInst *> LPads);
239245

Diff for: ‎llvm/include/llvm/IR/Intrinsics.td

+5-1
Original file line numberDiff line numberDiff line change
@@ -441,10 +441,14 @@ def int_eh_endcatch : Intrinsic<[], []>;
441441
def int_eh_exceptionpointer : Intrinsic<[llvm_anyptr_ty], [llvm_token_ty],
442442
[IntrNoMem]>;
443443

444+
// Gets the exception code from a catchpad token. Only used on some platforms.
445+
def int_eh_exceptioncode : Intrinsic<[llvm_i32_ty], [llvm_token_ty], [IntrNoMem]>;
446+
444447
// Represents the list of actions to take when an exception is thrown.
445448
def int_eh_actions : Intrinsic<[llvm_ptr_ty], [llvm_vararg_ty], []>;
446449

447-
def int_eh_exceptioncode : Intrinsic<[llvm_i32_ty], [], [IntrReadMem]>;
450+
// FIXME: Remove this when landing pad EH can be removed.
451+
def int_eh_exceptioncode_old : Intrinsic<[llvm_i32_ty], [], [IntrReadMem]>;
448452

449453
// __builtin_unwind_init is an undocumented GCC intrinsic that causes all
450454
// callee-saved registers to be saved and restored (regardless of whether they

Diff for: ‎llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,17 @@ int FunctionLoweringInfo::getArgumentFrameIndex(const Argument *A) {
577577
return 0;
578578
}
579579

580+
unsigned FunctionLoweringInfo::getCatchPadExceptionPointerVReg(
581+
const Value *CPI, const TargetRegisterClass *RC) {
582+
MachineRegisterInfo &MRI = MF->getRegInfo();
583+
auto I = CatchPadExceptionPointers.insert({CPI, 0});
584+
unsigned &VReg = I.first->second;
585+
if (I.second)
586+
VReg = MRI.createVirtualRegister(RC);
587+
assert(VReg && "null vreg in exception pointer table!");
588+
return VReg;
589+
}
590+
580591
/// ComputeUsesVAFloatArgument - Determine if any floating-point values are
581592
/// being passed to this variadic function, and set the MachineModuleInfo's
582593
/// usesVAFloatArgument flag if so. This flag is used to emit an undefined

Diff for: ‎llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

+15-1
Original file line numberDiff line numberDiff line change
@@ -5240,7 +5240,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
52405240
case Intrinsic::eh_begincatch:
52415241
case Intrinsic::eh_endcatch:
52425242
llvm_unreachable("begin/end catch intrinsics not lowered in codegen");
5243-
case Intrinsic::eh_exceptioncode: {
5243+
case Intrinsic::eh_exceptioncode_old: {
52445244
unsigned Reg = TLI.getExceptionPointerRegister();
52455245
assert(Reg && "cannot get exception code on this platform");
52465246
MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
@@ -5253,6 +5253,20 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
52535253
setValue(&I, N);
52545254
return nullptr;
52555255
}
5256+
5257+
case Intrinsic::eh_exceptionpointer:
5258+
case Intrinsic::eh_exceptioncode: {
5259+
// Get the exception pointer vreg, copy from it, and resize it to fit.
5260+
const auto *CPI = cast<CatchPadInst>(I.getArgOperand(0));
5261+
MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
5262+
const TargetRegisterClass *PtrRC = TLI.getRegClassFor(PtrVT);
5263+
unsigned VReg = FuncInfo.getCatchPadExceptionPointerVReg(CPI, PtrRC);
5264+
SDValue N =
5265+
DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(), VReg, PtrVT);
5266+
N = DAG.getZExtOrTrunc(N, getCurSDLoc(), MVT::i32);
5267+
setValue(&I, N);
5268+
return nullptr;
5269+
}
52565270
}
52575271
}
52585272

Diff for: ‎llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

+35-6
Original file line numberDiff line numberDiff line change
@@ -922,14 +922,46 @@ void SelectionDAGISel::DoInstructionSelection() {
922922
PostprocessISelDAG();
923923
}
924924

925+
static bool hasExceptionPointerOrCodeUser(const CatchPadInst *CPI) {
926+
for (const User *U : CPI->users()) {
927+
if (const IntrinsicInst *EHPtrCall = dyn_cast<IntrinsicInst>(U)) {
928+
Intrinsic::ID IID = EHPtrCall->getIntrinsicID();
929+
if (IID == Intrinsic::eh_exceptionpointer ||
930+
IID == Intrinsic::eh_exceptioncode)
931+
return true;
932+
}
933+
}
934+
return false;
935+
}
936+
925937
/// PrepareEHLandingPad - Emit an EH_LABEL, set up live-in registers, and
926938
/// do other setup for EH landing-pad blocks.
927939
bool SelectionDAGISel::PrepareEHLandingPad() {
928940
MachineBasicBlock *MBB = FuncInfo->MBB;
929-
941+
const BasicBlock *LLVMBB = MBB->getBasicBlock();
930942
const TargetRegisterClass *PtrRC =
931943
TLI->getRegClassFor(TLI->getPointerTy(CurDAG->getDataLayout()));
932944

945+
// Catchpads have one live-in register, which typically holds the exception
946+
// pointer or code.
947+
if (const auto *CPI = dyn_cast<CatchPadInst>(LLVMBB->getFirstNonPHI())) {
948+
if (hasExceptionPointerOrCodeUser(CPI)) {
949+
// Get or create the virtual register to hold the pointer or code. Mark
950+
// the live in physreg and copy into the vreg.
951+
MCPhysReg EHPhysReg = TLI->getExceptionPointerRegister();
952+
assert(EHPhysReg && "target lacks exception pointer register");
953+
FuncInfo->ExceptionPointerVirtReg = MBB->addLiveIn(EHPhysReg, PtrRC);
954+
unsigned VReg = FuncInfo->getCatchPadExceptionPointerVReg(CPI, PtrRC);
955+
BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(),
956+
TII->get(TargetOpcode::COPY), VReg)
957+
.addReg(EHPhysReg, RegState::Kill);
958+
}
959+
return true;
960+
}
961+
962+
if (!LLVMBB->isLandingPad())
963+
return true;
964+
933965
// Add a label to mark the beginning of the landing pad. Deletion of the
934966
// landing pad can thus be detected via the MachineModuleInfo.
935967
MCSymbol *Label = MF->getMMI().addLandingPad(MBB);
@@ -943,7 +975,6 @@ bool SelectionDAGISel::PrepareEHLandingPad() {
943975

944976
// If this personality function uses funclets, we need to split the landing
945977
// pad into several BBs.
946-
const BasicBlock *LLVMBB = MBB->getBasicBlock();
947978
const Constant *Personality = MF->getFunction()->getPersonalityFn();
948979
if (const auto *PF = dyn_cast<Function>(Personality->stripPointerCasts()))
949980
MF->getMMI().addPersonality(PF);
@@ -1159,10 +1190,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
11591190
// Setup an EH landing-pad block.
11601191
FuncInfo->ExceptionPointerVirtReg = 0;
11611192
FuncInfo->ExceptionSelectorVirtReg = 0;
1162-
if (LLVMBB->isLandingPad())
1163-
if (!PrepareEHLandingPad())
1164-
continue;
1165-
1193+
if (!PrepareEHLandingPad())
1194+
continue;
11661195

11671196
// Before doing SelectionDAG ISel, see if FastISel has been requested.
11681197
if (FastIS) {

Diff for: ‎llvm/lib/CodeGen/WinEHPrepare.cpp

+9-8
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,7 @@ void WinEHPrepare::processSEHCatchHandler(CatchHandler *CatchAction,
16141614
}
16151615
IRBuilder<> Builder(HandlerBB->getFirstInsertionPt());
16161616
Function *EHCodeFn = Intrinsic::getDeclaration(
1617-
StartBB->getParent()->getParent(), Intrinsic::eh_exceptioncode);
1617+
StartBB->getParent()->getParent(), Intrinsic::eh_exceptioncode_old);
16181618
Value *Code = Builder.CreateCall(EHCodeFn, {}, "sehcode");
16191619
Code = Builder.CreateIntToPtr(Code, SEHExceptionCodeSlot->getAllocatedType());
16201620
Builder.CreateStore(Code, SEHExceptionCodeSlot);
@@ -3019,12 +3019,11 @@ colorFunclets(Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks,
30193019
// Mark this as a funclet head as a member of itself.
30203020
FuncletBlocks[Visiting].insert(Visiting);
30213021
// Queue exits with the parent color.
3022-
for (User *Exit : VisitingHead->users()) {
3023-
for (BasicBlock *Succ :
3024-
successors(cast<Instruction>(Exit)->getParent())) {
3025-
if (BlockColors[Succ].insert(Color).second) {
3026-
Worklist.push_back({Succ, Color});
3027-
}
3022+
for (User *U : VisitingHead->users()) {
3023+
if (auto *Exit = dyn_cast<TerminatorInst>(U)) {
3024+
for (BasicBlock *Succ : successors(Exit->getParent()))
3025+
if (BlockColors[Succ].insert(Color).second)
3026+
Worklist.push_back({Succ, Color});
30283027
}
30293028
}
30303029
// Handle CatchPad specially since its successors need different colors.
@@ -3124,7 +3123,9 @@ void llvm::calculateCatchReturnSuccessorColors(const Function *Fn,
31243123

31253124
// The users of a catchpad are always catchrets.
31263125
for (User *Exit : CatchPad->users()) {
3127-
auto *CatchReturn = cast<CatchReturnInst>(Exit);
3126+
auto *CatchReturn = dyn_cast<CatchReturnInst>(Exit);
3127+
if (!CatchReturn)
3128+
continue;
31283129
BasicBlock *CatchRetSuccessor = CatchReturn->getSuccessor();
31293130
std::set<BasicBlock *> &SuccessorColors = BlockColors[CatchRetSuccessor];
31303131
assert(SuccessorColors.size() == 1 && "Expected BB to be monochrome!");

Diff for: ‎llvm/lib/IR/Verifier.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -3681,6 +3681,7 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) {
36813681
"gc.relocate: relocating a pointer shouldn't change its address space", CS);
36823682
break;
36833683
}
3684+
case Intrinsic::eh_exceptioncode:
36843685
case Intrinsic::eh_exceptionpointer: {
36853686
Assert(isa<CatchPadInst>(CS.getArgOperand(0)),
36863687
"eh.exceptionpointer argument must be a catchpad", CS);

Diff for: ‎llvm/test/CodeGen/WinEH/seh-exception-code.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ __try.cont: ; preds = %invoke.cont, %__exc
5252
; CHECK: landingpad
5353
; CHECK: indirectbr i8* %{{[^,]*}}, [label %[[except_split1:.*]]]
5454
; CHECK: [[except_split1]]:
55-
; CHECK: call i32 @llvm.eh.exceptioncode()
55+
; CHECK: call i32 @llvm.eh.exceptioncode.old()
5656
; CHECK: br label %__except
5757
;
5858
; CHECK: landingpad
5959
; CHECK: indirectbr i8* %{{[^,]*}}, [label %[[except_split2:.*]]]
6060
; CHECK: [[except_split2]]:
61-
; CHECK: call i32 @llvm.eh.exceptioncode()
61+
; CHECK: call i32 @llvm.eh.exceptioncode.old()
6262
; CHECK: br label %__except
6363
;
6464
; CHECK: __except:

Diff for: ‎llvm/test/CodeGen/WinEH/seh-exception-code2.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,5 @@ entry:
8787
; CHECK-NEXT: indirectbr i8* %{{[^,]*}}, [label %__except]
8888
;
8989
; CHECK: __except:
90-
; CHECK: call i32 @llvm.eh.exceptioncode()
90+
; CHECK: call i32 @llvm.eh.exceptioncode.old()
9191
; CHECK: call i32 (i8*, ...) @printf

Diff for: ‎llvm/test/CodeGen/WinEH/seh-resume-phi.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ eh.resume:
5555
; CHECK-NEXT: indirectbr {{.*}} [label %__except]
5656
;
5757
; CHECK: __except:
58-
; CHECK: call i32 @llvm.eh.exceptioncode()
58+
; CHECK: call i32 @llvm.eh.exceptioncode.old()
5959
; CHECK: invoke void @might_crash(i8* %{{.*}})
6060
; CHECK: landingpad { i8*, i32 }
6161
; CHECK-NEXT: cleanup

0 commit comments

Comments
 (0)
Please sign in to comment.