Create and use an llvm.eh.sjlj.functioncontext intrinsic.
authorBill Wendling <isanbard@gmail.com>
Wed, 28 Sep 2011 03:36:43 +0000 (03:36 +0000)
committerBill Wendling <isanbard@gmail.com>
Wed, 28 Sep 2011 03:36:43 +0000 (03:36 +0000)
This intrinsic is used to pass the index of the function context to the back-end
for further processing. The back-end is in charge of filling in the rest of the
entries.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140676 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineFrameInfo.h
include/llvm/Intrinsics.td
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
lib/CodeGen/SjLjEHPrepare.cpp

index 4ea6aa3396a9aa82ba81217f33ed91daa2a8f465..b347ca8e680a85114a55d0eb54b0389fafc405bc 100644 (file)
@@ -174,6 +174,10 @@ class MachineFrameInfo {
   /// StackProtectorIdx - The frame index for the stack protector.
   int StackProtectorIdx;
 
+  /// FunctionContextIdx - The frame index for the function context. Used for
+  /// SjLj exceptions.
+  int FunctionContextIdx;
+
   /// MaxCallFrameSize - This contains the size of the largest call frame if the
   /// target uses frame setup/destroy pseudo instructions (as defined in the
   /// TargetFrameInfo class).  This information is important for frame pointer
@@ -220,6 +224,7 @@ public:
     AdjustsStack = false;
     HasCalls = false;
     StackProtectorIdx = -1;
+    FunctionContextIdx = -1;
     MaxCallFrameSize = 0;
     CSIValid = false;
     LocalFrameSize = 0;
@@ -244,6 +249,11 @@ public:
   int getStackProtectorIndex() const { return StackProtectorIdx; }
   void setStackProtectorIndex(int I) { StackProtectorIdx = I; }
 
+  /// getFunctionContextIndex/setFunctionContextIndex - Return the index for the
+  /// function context object. This object is used for SjLj exceptions.
+  int getFunctionContextIndex() const { return FunctionContextIdx; }
+  void setFunctionContextIndex(int I) { FunctionContextIdx = I; }
+
   /// isFrameAddressTaken - This method may be called any time after instruction
   /// selection is complete to determine if there is a call to
   /// \@llvm.frameaddress in this function.
index c526301bf9182a29f3dd4f70bb9cdf8040b3b87b..1b7a0d15e1286752ea242f99fabf240d1f02a55d 100644 (file)
@@ -322,12 +322,13 @@ def int_eh_unwind_init: Intrinsic<[]>,
 def int_eh_dwarf_cfa  : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>;
 
 let Properties = [IntrNoMem] in {
-  def int_eh_sjlj_lsda    : Intrinsic<[llvm_ptr_ty]>;
-  def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>;
+  def int_eh_sjlj_lsda             : Intrinsic<[llvm_ptr_ty]>;
+  def int_eh_sjlj_callsite         : Intrinsic<[], [llvm_i32_ty]>;
+  def int_eh_sjlj_functioncontext  : Intrinsic<[], [llvm_ptr_ty]>;
 }
 def int_eh_sjlj_dispatch_setup : Intrinsic<[], [llvm_i32_ty]>;
-def int_eh_sjlj_setjmp  : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
-def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>;
+def int_eh_sjlj_setjmp         : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
+def int_eh_sjlj_longjmp        : Intrinsic<[], [llvm_ptr_ty]>;
 
 //===---------------- Generic Variable Attribute Intrinsics----------------===//
 //
index 9d86c759b823e5e47187efa991df8c6e6a4c20a5..b2b93c9ff57a1dba845cc85a216e0bc9a0e6cee7 100644 (file)
@@ -4754,6 +4754,14 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
     MMI.setCurrentCallSite(CI->getZExtValue());
     return 0;
   }
+  case Intrinsic::eh_sjlj_functioncontext: {
+    // Get and store the index of the function context.
+    MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
+    AllocaInst *FnCtx = cast<AllocaInst>(I.getArgOperand(0));
+    int FI = FuncInfo.StaticAllocaMap[FnCtx];
+    MFI->setFunctionContextIndex(FI);
+    return 0;
+  }
   case Intrinsic::eh_sjlj_setjmp: {
     setValue(&I, DAG.getNode(ISD::EH_SJLJ_SETJMP, dl, MVT::i32, getRoot(),
                              getValue(I.getArgOperand(0))));
index baa70b961b994b1bf1a11712edd181ebb2a1a123..9749a7e1191633c51b13737fcef25f9604bb255f 100644 (file)
@@ -721,6 +721,12 @@ void SjLjEHPass::setupFunctionContext(Function &F,
   AllocaInst *FuncCtx =
     new AllocaInst(FunctionContextTy, 0, Align, "fn_context", EntryBB->begin());
 
+  // Store a pointer to the function context so that the back-end will know
+  // where to look for it.
+  CallInst::Create(Intrinsic::getDeclaration(F.getParent(),
+                                            Intrinsic::eh_sjlj_functioncontext),
+                   FuncCtx, "", EntryBB->getTerminator());
+
   // Fill in the function context structure.
   Value *Idxs[2];
   Type *Int32Ty = Type::getInt32Ty(F.getContext());