[llvm] r233209 - WinEH: Create an unwind help alloca for __CxxFrameHandler3 xdata tables
Reid Kleckner
reid at kleckner.net
Wed Mar 25 13:10:36 PDT 2015
Author: rnk
Date: Wed Mar 25 15:10:36 2015
New Revision: 233209
URL: http://llvm.org/viewvc/llvm-project?rev=233209&view=rev
Log:
WinEH: Create an unwind help alloca for __CxxFrameHandler3 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.
Modified:
llvm/trunk/docs/ExceptionHandling.rst
llvm/trunk/include/llvm/IR/Intrinsics.td
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
llvm/trunk/lib/IR/Verifier.cpp
llvm/trunk/test/CodeGen/WinEH/cppeh-catch-unwind.ll
Modified: llvm/trunk/docs/ExceptionHandling.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ExceptionHandling.rst?rev=233209&r1=233208&r2=233209&view=diff
==============================================================================
--- llvm/trunk/docs/ExceptionHandling.rst (original)
+++ llvm/trunk/docs/ExceptionHandling.rst Wed Mar 25 15:10:36 2015
@@ -539,6 +539,18 @@ In order to preserve the structure of th
must be followed by an ':ref:`indirectbr <i_indirectbr>`' instruction that jumps
to the result of the intrinsic call.
+``llvm.eh.unwindhelp``
+----------------------
+
+.. code-block:: llvm
+
+ void @llvm.eh.unwindhelp(i8*)
+
+This intrinsic designates the provided static alloca as the unwind help object.
+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
+memory treated as two 32-bit integers.
+
SJLJ Intrinsics
---------------
Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=233209&r1=233208&r2=233209&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/IR/Intrinsics.td Wed Mar 25 15:10:36 2015
@@ -421,6 +421,10 @@ def int_eh_endcatch : Intrinsic<[], []>;
// Represents the list of actions to take when an exception is thrown.
def int_eh_actions : Intrinsic<[llvm_ptr_ty], [llvm_vararg_ty], []>;
+// Designates the provided static alloca as the unwind help object. Required
+// for WinEH.
+def int_eh_unwindhelp : Intrinsic<[], [llvm_ptr_ty], []>;
+
// __builtin_unwind_init is an undocumented GCC intrinsic that causes all
// callee-saved registers to be saved and restored (regardless of whether they
// are used) in the calling function. It is used by libgcc_eh.
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=233209&r1=233208&r2=233209&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Mar 25 15:10:36 2015
@@ -5446,6 +5446,16 @@ SelectionDAGBuilder::visitIntrinsicCall(
case Intrinsic::eh_begincatch:
case Intrinsic::eh_endcatch:
llvm_unreachable("begin/end catch intrinsics not lowered in codegen");
+ case Intrinsic::eh_unwindhelp: {
+ AllocaInst *Slot =
+ cast<AllocaInst>(I.getArgOperand(0)->stripPointerCasts());
+ assert(FuncInfo.StaticAllocaMap.count(Slot) &&
+ "can only use static allocas with llvm.eh.unwindhelp");
+ int FI = FuncInfo.StaticAllocaMap[Slot];
+ // TODO: Save this in the not-yet-existant WinEHFuncInfo struct.
+ (void)FI;
+ return nullptr;
+ }
}
}
Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=233209&r1=233208&r2=233209&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Wed Mar 25 15:10:36 2015
@@ -601,6 +601,19 @@ bool WinEHPrepare::prepareExceptionHandl
Builder.SetInsertPoint(&F.getEntryBlock().back());
Builder.CreateCall(FrameEscapeFn, AllocasToEscape);
+ // Insert an alloca for the EH state in the entry block. On x86, we will also
+ // insert stores to update the EH state, but on other ISAs, the runtime does
+ // it for us.
+ // FIXME: This record is different on x86.
+ Type *UnwindHelpTy = Type::getInt64Ty(Context);
+ AllocaInst *UnwindHelp =
+ new AllocaInst(UnwindHelpTy, "unwindhelp", &F.getEntryBlock().front());
+ Builder.CreateStore(llvm::ConstantInt::get(UnwindHelpTy, -2), UnwindHelp);
+ Function *UnwindHelpFn =
+ Intrinsic::getDeclaration(M, Intrinsic::eh_unwindhelp);
+ Builder.CreateCall(UnwindHelpFn,
+ Builder.CreateBitCast(UnwindHelp, Int8PtrType));
+
// Clean up the handler action maps we created for this function
DeleteContainerSeconds(CatchHandlerMap);
CatchHandlerMap.clear();
Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=233209&r1=233208&r2=233209&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Wed Mar 25 15:10:36 2015
@@ -2908,6 +2908,13 @@ void Verifier::visitIntrinsicFunctionCal
break;
}
+ case Intrinsic::eh_unwindhelp: {
+ auto *AI = dyn_cast<AllocaInst>(CI.getArgOperand(0)->stripPointerCasts());
+ Assert(AI && AI->isStaticAlloca(),
+ "llvm.eh.unwindhelp requires a static alloca", &CI);
+ break;
+ }
+
case Intrinsic::experimental_gc_statepoint:
Assert(!CI.isInlineAsm(),
"gc.statepoint support for inline assembly unimplemented", &CI);
Modified: llvm/trunk/test/CodeGen/WinEH/cppeh-catch-unwind.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/cppeh-catch-unwind.ll?rev=233209&r1=233208&r2=233209&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/cppeh-catch-unwind.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/cppeh-catch-unwind.ll Wed Mar 25 15:10:36 2015
@@ -33,10 +33,13 @@ $"\01??_R0H at 8" = comdat any
; CHECK-LABEL: define void @"\01?test@@YAXXZ"() #0 {
; CHECK: entry:
+; CHECK: [[UNWIND_HELP:\%.+]] = alloca i64
; CHECK: [[OBJ_PTR:\%.+]] = alloca %class.SomeClass
; CHECK: [[TMP0:\%.+]] = alloca i32, align 4
; CHECK: [[TMP1:\%.+]] = alloca i32, align 4
; CHECK: call void (...)* @llvm.frameescape(i32* [[TMP1]], %class.SomeClass* [[OBJ_PTR]], i32* [[TMP0]])
+; CHECK: [[UNWIND_HELP_i8:\%.+]] = bitcast i64* [[UNWIND_HELP]] to i8*
+; CHECK: call void @llvm.eh.unwindhelp(i8* [[UNWIND_HELP_i8]])
; CHECK: %call = invoke %class.SomeClass* @"\01??0SomeClass@@QEAA at XZ"(%class.SomeClass* %obj)
; CHECK: to label %invoke.cont unwind label %[[LPAD_LABEL:lpad[0-9]+]]
More information about the llvm-commits
mailing list