[llvm-commits] [llvm-gcc-4.2] r79058 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h

Jim Grosbach grosbach at apple.com
Fri Aug 14 16:46:17 PDT 2009


Author: grosbach
Date: Fri Aug 14 18:46:16 2009
New Revision: 79058

URL: http://llvm.org/viewvc/llvm-project?rev=79058&view=rev
Log:
Postpone generation of eh.sjlj.setjmp for SJLJ based exception handling till
we've processed the function body. Thus we can get a better answer about
whether we actually need to add this function to the context stack.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-internal.h

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=79058&r1=79057&r2=79058&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Fri Aug 14 18:46:16 2009
@@ -637,73 +637,15 @@
   // Register the frame with the unwind machinery if there are exception
   // handling regions in the function.
   if (USING_SJLJ_EXCEPTIONS && current_function_has_exception_handlers()) {
-
-    CreateExceptionValues();
-
-    // Create a function context on the stack
-    FunctionContext =
-      CreateTempLoc (ConvertType(sjlj_fc_type_node));
-    llvm::Value *Idxs[2];
-    Idxs[0] = ConstantInt::get(llvm::Type::getInt32Ty(Context), 0);
-
-    // Assign the unwind personality function address
-    Idxs[1] = ConstantInt::get(llvm::Type::getInt32Ty(Context), 3);
-    Value *FieldPtr = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2,
-                                         "personality_gep");
-    const Type *FieldTy =
-      cast<PointerType>(FieldPtr->getType())->getElementType();
-    Value *Val =
-      Builder.CreateBitCast(DECL_LLVM(llvm_eh_personality_libfunc), FieldTy);
-    Builder.CreateStore(Val, FieldPtr);
-
-    // Load the address for the language specific data area (LSDA)
-    Idxs[1] = ConstantInt::get(llvm::Type::getInt32Ty(Context), 4);
-    FieldPtr
-      = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2, "lsda_gep");
-    FieldTy = cast<PointerType>(FieldPtr->getType())->getElementType();
-    Val = 
-      Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
-                                                   Intrinsic::eh_sjlj_lsda),
-                         "eh_lsda");
-    Builder.CreateStore(Val, FieldPtr);
-
-    // builtin_setjmp() stuff goes here.
-    //   1. Save the frame pointer.
-    Idxs[1] = ConstantInt::get(llvm::Type::getInt32Ty(Context), 5);
-    FieldPtr
-      = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2, "jbuf_gep");
-    Idxs[1] = ConstantInt::get(llvm::Type::getInt32Ty(Context), 0);
-    Value *ElemPtr
-      = Builder.CreateGEP (FieldPtr, Idxs, Idxs+2, "jbuf_fp_gep");
-    FieldTy = cast<PointerType>(ElemPtr->getType())->getElementType();
-    // FIXME: The EmitBuiltinExtractReturnAddr() function comes close to
-    //  what we want here. Refactor it so that it does, or make a common
-    //  helper function.
-    Val = Builder.CreateCall
-      (Intrinsic::getDeclaration(TheModule, Intrinsic::frameaddress),
-       ConstantInt::get(llvm::Type::getInt32Ty(Context), 0));
-    Val = BitCastToType(Val, FieldTy);
-    Builder.CreateStore(Val, ElemPtr);
-
-    FieldPtr = BitCastToType(FieldPtr, 
-                             llvm::Type::getInt8Ty(Context)->getPointerTo());
-    Value *DispatchVal = Builder.CreateCall
-      (Intrinsic::getDeclaration(TheModule, Intrinsic::eh_sjlj_setjmp),
-       FieldPtr);
-    // check the return value of the setjmp. non-zero goes to dispatcher
-    Value *Zero = ConstantInt::get(llvm::Type::getInt32Ty(Context), 0);
-    Value *Compare = Builder.CreateICmpEQ(DispatchVal, Zero);
-
-    // Branch on the compare.
-    DispatchBB = BasicBlock::Create(Context, "dispatch");
-    BasicBlock *PostEntryBB = BasicBlock::Create(Context, "post_entry");
-    Builder.CreateCondBr(Compare, PostEntryBB, DispatchBB);
+    // We have exception regions, but we may or may not actually end up
+    // needing to actively do anything about it. We'll know at the end
+    // of the function by whether any landing pads have been created.
+    // So for now, we just create a block for where to add the necessary
+    // bits.
+    SjLjEHSetupBB = BasicBlock::Create(Context, "setup_sjlj_eh");
+    Builder.CreateBr(SjLjEHSetupBB);
+    PostEntryBB = BasicBlock::Create(Context, "post_entry");
     EmitBlock(PostEntryBB);
-
-    // Register the context and note that this call cannot throw
-    CallInst *RegisterCall = 
-      Builder.CreateCall(DECL_LLVM(llvm_unwind_sjlj_register_libfunc),
-                       FunctionContext.Ptr);
   }
 
   // Create a new block for the return node, but don't insert it yet.
@@ -711,16 +653,93 @@
 }
 
 Function *TreeToLLVM::FinishFunctionBody() {
+  // If we're using SJLJ exceptions and there are any landing pads for this
+  // function, we need to insert the setup code in the prologue, and add
+  // the unregister call here.
+  if (USING_SJLJ_EXCEPTIONS && current_function_has_exception_handlers()) {
+    // Send the current BB to the return block just like it would if we
+    // weren't doing this bit.
+    Builder.CreateBr(ReturnBB);
+
+    assert(SjLjEHSetupBB && "Exception handling needed but no setup block??");
+    EmitBlock(SjLjEHSetupBB);
+
+    if (LandingPads.size() > 0) {
+      // Get a pointer to the function context
+      llvm::Value *Idxs[2];
+      Idxs[0] = ConstantInt::get(Type::getInt32Ty(Context), 0);
+
+      // Assign the unwind personality function address
+      Idxs[1] = ConstantInt::get(Type::getInt32Ty(Context), 3);
+      Value *FieldPtr = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2,
+                                           "personality_gep");
+      const Type *FieldTy =
+        cast<PointerType>(FieldPtr->getType())->getElementType();
+      Value *Val =
+        Builder.CreateBitCast(DECL_LLVM(llvm_eh_personality_libfunc), FieldTy);
+      Builder.CreateStore(Val, FieldPtr);
+
+      // Load the address for the language specific data area (LSDA)
+      Idxs[1] = ConstantInt::get(Type::getInt32Ty(Context), 4);
+      FieldPtr
+        = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2, "lsda_gep");
+      FieldTy = cast<PointerType>(FieldPtr->getType())->getElementType();
+      Val =
+        Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
+                                                     Intrinsic::eh_sjlj_lsda),
+                           "eh_lsda");
+      Builder.CreateStore(Val, FieldPtr);
+
+      // builtin_setjmp() stuff goes here.
+      //   1. Save the frame pointer.
+      Idxs[1] = ConstantInt::get(Type::getInt32Ty(Context), 5);
+      FieldPtr
+        = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2, "jbuf_gep");
+      Idxs[1] = ConstantInt::get(Type::getInt32Ty(Context), 0);
+      Value *ElemPtr
+        = Builder.CreateGEP (FieldPtr, Idxs, Idxs+2, "jbuf_fp_gep");
+      FieldTy = cast<PointerType>(ElemPtr->getType())->getElementType();
+      // FIXME: The EmitBuiltinExtractReturnAddr() function comes close to
+      //  what we want here. Refactor it so that it does, or make a common
+      //  helper function.
+      Val = Builder.CreateCall
+        (Intrinsic::getDeclaration(TheModule, Intrinsic::frameaddress),
+         ConstantInt::get(Type::getInt32Ty(Context), 0));
+      Val = BitCastToType(Val, FieldTy);
+      Builder.CreateStore(Val, ElemPtr);
+
+      FieldPtr = 
+        BitCastToType(FieldPtr, Type::getInt8Ty(Context)->getPointerTo());
+      Value *DispatchVal = Builder.CreateCall
+        (Intrinsic::getDeclaration(TheModule, Intrinsic::eh_sjlj_setjmp),
+         FieldPtr);
+      // check the return value of the setjmp. non-zero goes to dispatcher
+      Value *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
+      Value *Compare = Builder.CreateICmpEQ(DispatchVal, Zero);
+
+      // Branch on the compare.
+      DispatchBB = BasicBlock::Create(Context, "dispatch");
+      BasicBlock *PostSetupBB = BasicBlock::Create(Context, "sjlj_eh_register");
+      Builder.CreateCondBr(Compare, PostSetupBB, DispatchBB);
+      EmitBlock(PostSetupBB);
+
+      // Register the context and note that this call cannot throw
+      CallInst *RegisterCall =
+        Builder.CreateCall(DECL_LLVM(llvm_unwind_sjlj_register_libfunc),
+                           FunctionContext.Ptr);
+    }
+    // Go back to the end of the prologue
+    Builder.CreateBr(PostEntryBB);
+  }
+
   // Insert the return block at the end of the function.
   EmitBlock(ReturnBB);
 
-  if (USING_SJLJ_EXCEPTIONS) {
+  if (USING_SJLJ_EXCEPTIONS && LandingPads.size() > 0) {
     // Un-register the frame with the unwind machinery if there are exception
     // handling regions in the function.
-    if (current_function_has_exception_handlers()) {
-      Builder.CreateCall(DECL_LLVM(llvm_unwind_sjlj_unregister_libfunc),
-                         FunctionContext.Ptr);
-    }
+    Builder.CreateCall(DECL_LLVM(llvm_unwind_sjlj_unregister_libfunc),
+                       FunctionContext.Ptr);
   }
 
   SmallVector <Value *, 4> RetVals;
@@ -1998,6 +2017,9 @@
                                               (IntPtr == Type::getInt32Ty(Context) ?
                                                Intrinsic::eh_typeid_for_i32 :
                                                Intrinsic::eh_typeid_for_i64));
+  // For SJLJ, create a function context on the stack
+  if (USING_SJLJ_EXCEPTIONS)
+    FunctionContext = CreateTempLoc (ConvertType(sjlj_fc_type_node));
 }
 
 /// getPostPad - Return the post landing pad for the given exception handling
@@ -2021,7 +2043,10 @@
 /// EmitSjLjDispatcher - Emit SJLJ EH dispatcher
 void TreeToLLVM::EmitSjLjDispatcher () {
   if (DispatchBB) {
+    assert(LandingPads.size() > 0 && "Dispatch block without landing pads?");
+
     EmitBlock(DispatchBB);
+
     // Get the call_site value
     llvm::Value *Idxs[2];
     Idxs[0] = ConstantInt::get(llvm::Type::getInt32Ty(Context), 0);
@@ -2906,6 +2931,7 @@
         LandingPad = ThisPad;
 
         if (USING_SJLJ_EXCEPTIONS) {
+          CreateExceptionValues();
           // Mark the call site so we'll dispatch to the right landing pad
           // when we get an exception passed back.
           llvm::Value *Idxs[2];
@@ -2913,8 +2939,6 @@
           Idxs[1] = ConstantInt::get(llvm::Type::getInt32Ty(Context), 1);
           Value *FieldPtr = Builder.CreateGEP (FunctionContext.Ptr,
                                                Idxs, Idxs+2, "call_site_gep");
-//          FieldPtr = BitCastToType(FieldPtr,
-//                                   llvm::Type::getInt32Ty(Context)->getPointerTo());
           const Type *FieldTy = 
             cast<PointerType>(FieldPtr->getType())->getElementType();
           Constant *CallSiteIdx = ConstantInt::get(FieldTy, RegionNo, true);

Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=79058&r1=79057&r2=79058&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Fri Aug 14 18:46:16 2009
@@ -295,6 +295,8 @@
   const TargetData &TD;
   tree_node *FnDecl;
   Function *Fn;
+  BasicBlock *SjLjEHSetupBB;
+  BasicBlock *PostEntryBB;
   BasicBlock *ReturnBB;
   BasicBlock *UnwindBB;
   BasicBlock *DispatchBB;





More information about the llvm-commits mailing list