[llvm] r233354 - WinEH: Create a parent frame alloca for HandlerType xdata tables

Kaylor, Andrew andrew.kaylor at intel.com
Fri Mar 27 10:26:29 PDT 2015


In all the cases I’ve seen with other compilers, the parent frame pointer is stored at a location above the stack pointer of the catch handler.  I think the address of this location needs to be calculated.  I don’t think the location needs to be provided by the handler.

I could be wrong, of course.

-Andy

From: David Majnemer [mailto:david.majnemer at gmail.com]
Sent: Friday, March 27, 2015 10:05 AM
To: Kaylor, Andrew
Cc: llvm-commits at cs.uiuc.edu
Subject: Re: [llvm] r233354 - WinEH: Create a parent frame alloca for HandlerType xdata tables



On Fri, Mar 27, 2015 at 9:52 AM, Kaylor, Andrew <andrew.kaylor at intel.com<mailto:andrew.kaylor at intel.com>> wrote:
This doesn't look the way I would have expected it to.

Why are you creating an alloca for the parent frame pointer?  I would have expected the intrinisic to return a pointer to the stack offset where the parent frame pointer needs to be stored and the catch handler to store it directly there.

The parent frame pointer needs to be stored to the catch handlers stack at an offset known to the compiler.  It seems quite natural to represent this as an alloca whose address is escaped to a builtin.


-Andy

-----Original Message-----
From: llvm-commits-bounces at cs.uiuc.edu<mailto:llvm-commits-bounces at cs.uiuc.edu> [mailto:llvm-commits-bounces at cs.uiuc.edu<mailto:llvm-commits-bounces at cs.uiuc.edu>] On Behalf Of David Majnemer
Sent: Thursday, March 26, 2015 9:17 PM
To: llvm-commits at cs.uiuc.edu<mailto:llvm-commits at cs.uiuc.edu>
Subject: [llvm] r233354 - WinEH: Create a parent frame alloca for HandlerType xdata tables

Author: majnemer
Date: Thu Mar 26 23:17:07 2015
New Revision: 233354

URL: http://llvm.org/viewvc/llvm-project?rev=233354&view=rev
Log:
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.

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=233354&r1=233353&r2=233354&view=diff
==============================================================================
--- llvm/trunk/docs/ExceptionHandling.rst (original)
+++ llvm/trunk/docs/ExceptionHandling.rst Thu Mar 26 23:17:07 2015
@@ -551,6 +551,17 @@ This object is used by Windows native ex  where xdata unwind information is used. It is typically an 8 byte chunk of  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
 ---------------

Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=233354&r1=233353&r2=233354&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/IR/Intrinsics.td Thu Mar 26 23:17:07 2015
@@ -425,6 +425,10 @@ def int_eh_actions : Intrinsic<[llvm_ptr  // for WinEH.
 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  // 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=233354&r1=233353&r2=233354&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Thu Mar
+++ 26 23:17:07 2015
@@ -5446,13 +5446,23 @@ SelectionDAGBuilder::visitIntrinsicCall(
   case Intrinsic::eh_begincatch:
   case Intrinsic::eh_endcatch:
     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: {
     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.
+    // TODO: Save this in the not-yet-existent 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=233354&r1=233353&r2=233354&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Thu Mar 26 23:17:07 2015
@@ -695,6 +695,16 @@ bool WinEHPrepare::outlineHandler(Action
   if (!LPadMap.isInitialized())
     LPadMap.mapLandingPad(LPad);
   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();
     Director.reset(new WinEHCatchDirector(Handler, Sel, VarInfo, LPadMap));
     LPadMap.remapSelector(VMap, ConstantInt::get(Type::getInt32Ty(Context), 1));

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=233354&r1=233353&r2=233354&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Thu Mar 26 23:17:07 2015
@@ -2909,6 +2909,13 @@ void Verifier::visitIntrinsicFunctionCal
     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: {
     auto *AI = dyn_cast<AllocaInst>(CI.getArgOperand(0)->stripPointerCasts());
     Assert(AI && AI->isStaticAlloca(),

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=233354&r1=233353&r2=233354&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/cppeh-catch-unwind.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/cppeh-catch-unwind.ll Thu Mar 26
+++ 23:17:07 2015
@@ -180,6 +180,9 @@ eh.resume:

 ; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*) {  ; 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:   [[TMP1_PTR:\%.+]] = bitcast i8* [[RECOVER_TMP1]] to i32*
 ; CHECK:   call void @"\01?handle_exception@@YAXXZ"()
@@ -196,6 +199,9 @@ eh.resume:

 ; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch1"(i8*, i8*) {  ; 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:   [[TMP0_PTR:\%.+]] = bitcast i8* [[RECOVER_TMP0]] to i32*
 ; CHECK:   invoke void @"\01?handle_exception@@YAXXZ"()


_______________________________________________
llvm-commits mailing list
llvm-commits at cs.uiuc.edu<mailto:llvm-commits at cs.uiuc.edu>
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150327/f0a7c84b/attachment.html>


More information about the llvm-commits mailing list