mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 21:32:10 +00:00
WinEH: Create a parent frame alloca for HandlerType xdata tables
We don't have any logic to emit those tables yet, so the SDAG lowering of this intrinsic is just a stub. We can see the intrinsic in the prepared IR, though. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233354 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6284bcd95b
commit
db573736fd
@ -551,6 +551,17 @@ This object is used by Windows native exception handling on non-x86 platforms
|
|||||||
where xdata unwind information is used. It is typically an 8 byte chunk of
|
where xdata unwind information is used. It is typically an 8 byte chunk of
|
||||||
memory treated as two 32-bit integers.
|
memory treated as two 32-bit integers.
|
||||||
|
|
||||||
|
``llvm.eh.parentframe``
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
.. code-block:: llvm
|
||||||
|
|
||||||
|
void @llvm.eh.parentframe(i8*)
|
||||||
|
|
||||||
|
This intrinsic designates the provided static alloca as the object which holds
|
||||||
|
the address of the parent frame.
|
||||||
|
This object is used by Windows native exception handling on non-x86 platforms
|
||||||
|
where xdata unwind information is used.
|
||||||
|
|
||||||
SJLJ Intrinsics
|
SJLJ Intrinsics
|
||||||
---------------
|
---------------
|
||||||
|
@ -425,6 +425,10 @@ def int_eh_actions : Intrinsic<[llvm_ptr_ty], [llvm_vararg_ty], []>;
|
|||||||
// for WinEH.
|
// for WinEH.
|
||||||
def int_eh_unwindhelp : Intrinsic<[], [llvm_ptr_ty], []>;
|
def int_eh_unwindhelp : Intrinsic<[], [llvm_ptr_ty], []>;
|
||||||
|
|
||||||
|
// Designates the provided static alloca as the object which holds the address
|
||||||
|
// of the parent frame. Required for WinEH.
|
||||||
|
def int_eh_parentframe : Intrinsic<[], [llvm_ptrptr_ty], []>;
|
||||||
|
|
||||||
// __builtin_unwind_init is an undocumented GCC intrinsic that causes all
|
// __builtin_unwind_init is an undocumented GCC intrinsic that causes all
|
||||||
// callee-saved registers to be saved and restored (regardless of whether they
|
// callee-saved registers to be saved and restored (regardless of whether they
|
||||||
// are used) in the calling function. It is used by libgcc_eh.
|
// are used) in the calling function. It is used by libgcc_eh.
|
||||||
|
@ -5446,13 +5446,23 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
|||||||
case Intrinsic::eh_begincatch:
|
case Intrinsic::eh_begincatch:
|
||||||
case Intrinsic::eh_endcatch:
|
case Intrinsic::eh_endcatch:
|
||||||
llvm_unreachable("begin/end catch intrinsics not lowered in codegen");
|
llvm_unreachable("begin/end catch intrinsics not lowered in codegen");
|
||||||
|
case Intrinsic::eh_parentframe: {
|
||||||
|
AllocaInst *Slot =
|
||||||
|
cast<AllocaInst>(I.getArgOperand(0)->stripPointerCasts());
|
||||||
|
assert(FuncInfo.StaticAllocaMap.count(Slot) &&
|
||||||
|
"can only use static allocas with llvm.eh.parentframe");
|
||||||
|
int FI = FuncInfo.StaticAllocaMap[Slot];
|
||||||
|
// TODO: Save this in the not-yet-existent WinEHFuncInfo struct.
|
||||||
|
(void)FI;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
case Intrinsic::eh_unwindhelp: {
|
case Intrinsic::eh_unwindhelp: {
|
||||||
AllocaInst *Slot =
|
AllocaInst *Slot =
|
||||||
cast<AllocaInst>(I.getArgOperand(0)->stripPointerCasts());
|
cast<AllocaInst>(I.getArgOperand(0)->stripPointerCasts());
|
||||||
assert(FuncInfo.StaticAllocaMap.count(Slot) &&
|
assert(FuncInfo.StaticAllocaMap.count(Slot) &&
|
||||||
"can only use static allocas with llvm.eh.unwindhelp");
|
"can only use static allocas with llvm.eh.unwindhelp");
|
||||||
int FI = FuncInfo.StaticAllocaMap[Slot];
|
int FI = FuncInfo.StaticAllocaMap[Slot];
|
||||||
// TODO: Save this in the not-yet-existant WinEHFuncInfo struct.
|
// TODO: Save this in the not-yet-existent WinEHFuncInfo struct.
|
||||||
(void)FI;
|
(void)FI;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -695,6 +695,16 @@ bool WinEHPrepare::outlineHandler(ActionHandler *Action, Function *SrcFn,
|
|||||||
if (!LPadMap.isInitialized())
|
if (!LPadMap.isInitialized())
|
||||||
LPadMap.mapLandingPad(LPad);
|
LPadMap.mapLandingPad(LPad);
|
||||||
if (auto *CatchAction = dyn_cast<CatchHandler>(Action)) {
|
if (auto *CatchAction = dyn_cast<CatchHandler>(Action)) {
|
||||||
|
// Insert an alloca for the object which holds the address of the parent's
|
||||||
|
// frame pointer. The stack offset of this object needs to be encoded in
|
||||||
|
// xdata.
|
||||||
|
AllocaInst *ParentFrame = new AllocaInst(Int8PtrType, "parentframe", Entry);
|
||||||
|
Builder.CreateStore(&Handler->getArgumentList().back(), ParentFrame,
|
||||||
|
/*isStore=*/true);
|
||||||
|
Function *ParentFrameFn =
|
||||||
|
Intrinsic::getDeclaration(M, Intrinsic::eh_parentframe);
|
||||||
|
Builder.CreateCall(ParentFrameFn, ParentFrame);
|
||||||
|
|
||||||
Constant *Sel = CatchAction->getSelector();
|
Constant *Sel = CatchAction->getSelector();
|
||||||
Director.reset(new WinEHCatchDirector(Handler, Sel, VarInfo, LPadMap));
|
Director.reset(new WinEHCatchDirector(Handler, Sel, VarInfo, LPadMap));
|
||||||
LPadMap.remapSelector(VMap, ConstantInt::get(Type::getInt32Ty(Context), 1));
|
LPadMap.remapSelector(VMap, ConstantInt::get(Type::getInt32Ty(Context), 1));
|
||||||
|
@ -2909,6 +2909,13 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Intrinsic::eh_parentframe: {
|
||||||
|
auto *AI = dyn_cast<AllocaInst>(CI.getArgOperand(0)->stripPointerCasts());
|
||||||
|
Assert(AI && AI->isStaticAlloca(),
|
||||||
|
"llvm.eh.parentframe requires a static alloca", &CI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Intrinsic::eh_unwindhelp: {
|
case Intrinsic::eh_unwindhelp: {
|
||||||
auto *AI = dyn_cast<AllocaInst>(CI.getArgOperand(0)->stripPointerCasts());
|
auto *AI = dyn_cast<AllocaInst>(CI.getArgOperand(0)->stripPointerCasts());
|
||||||
Assert(AI && AI->isStaticAlloca(),
|
Assert(AI && AI->isStaticAlloca(),
|
||||||
|
@ -180,6 +180,9 @@ eh.resume: ; preds = %catch.dispatch7
|
|||||||
|
|
||||||
; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*) {
|
; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*) {
|
||||||
; CHECK: entry:
|
; CHECK: entry:
|
||||||
|
; CHECK: [[PARENTFRAME:\%.+]] = alloca i8*
|
||||||
|
; CHECK: store volatile i8* %1, i8** [[PARENTFRAME]]
|
||||||
|
; CHECK: call void @llvm.eh.parentframe(i8** [[PARENTFRAME]])
|
||||||
; CHECK: [[RECOVER_TMP1:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
|
; CHECK: [[RECOVER_TMP1:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
|
||||||
; CHECK: [[TMP1_PTR:\%.+]] = bitcast i8* [[RECOVER_TMP1]] to i32*
|
; CHECK: [[TMP1_PTR:\%.+]] = bitcast i8* [[RECOVER_TMP1]] to i32*
|
||||||
; CHECK: call void @"\01?handle_exception@@YAXXZ"()
|
; CHECK: call void @"\01?handle_exception@@YAXXZ"()
|
||||||
@ -196,6 +199,9 @@ eh.resume: ; preds = %catch.dispatch7
|
|||||||
|
|
||||||
; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch1"(i8*, i8*) {
|
; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch1"(i8*, i8*) {
|
||||||
; CHECK: entry:
|
; CHECK: entry:
|
||||||
|
; CHECK: [[PARENTFRAME:\%.+]] = alloca i8*
|
||||||
|
; CHECK: store volatile i8* %1, i8** [[PARENTFRAME]]
|
||||||
|
; CHECK: call void @llvm.eh.parentframe(i8** [[PARENTFRAME]])
|
||||||
; CHECK: [[RECOVER_TMP0:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
|
; CHECK: [[RECOVER_TMP0:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
|
||||||
; CHECK: [[TMP0_PTR:\%.+]] = bitcast i8* [[RECOVER_TMP0]] to i32*
|
; CHECK: [[TMP0_PTR:\%.+]] = bitcast i8* [[RECOVER_TMP0]] to i32*
|
||||||
; CHECK: invoke void @"\01?handle_exception@@YAXXZ"()
|
; CHECK: invoke void @"\01?handle_exception@@YAXXZ"()
|
||||||
|
Loading…
Reference in New Issue
Block a user