[llvm-commits] [llvm-gcc-4.2] r78626 - in /llvm-gcc-4.2/trunk/gcc: c-decl.c cp/except.c except.c except.h libfuncs.h llvm-backend.cpp llvm-convert.cpp llvm-internal.h objc/objc-act.c

Jim Grosbach grosbach at apple.com
Mon Aug 10 17:10:16 PDT 2009


Author: grosbach
Date: Mon Aug 10 19:10:16 2009
New Revision: 78626

URL: http://llvm.org/viewvc/llvm-project?rev=78626&view=rev
Log:
SjLj based exception handling unwinding support. This patch is nasty, brutish
and short. Well, it's kinda short. Definitely nasty and brutish.

The front-end generates the register/unregister calls into the SjLj runtime,
call-site indices and landing pad dispatch. The back end fills in the LSDA
with the call-site information provided by the front end. Catch blocks are
not yet implemented.

Built on Darwin and verified no llvm-core "make check" regressions.


Modified:
    llvm-gcc-4.2/trunk/gcc/c-decl.c
    llvm-gcc-4.2/trunk/gcc/cp/except.c
    llvm-gcc-4.2/trunk/gcc/except.c
    llvm-gcc-4.2/trunk/gcc/except.h
    llvm-gcc-4.2/trunk/gcc/libfuncs.h
    llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-internal.h
    llvm-gcc-4.2/trunk/gcc/objc/objc-act.c

Modified: llvm-gcc-4.2/trunk/gcc/c-decl.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-decl.c?rev=78626&r1=78625&r2=78626&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/c-decl.c (original)
+++ llvm-gcc-4.2/trunk/gcc/c-decl.c Mon Aug 10 19:10:16 2009
@@ -3586,6 +3586,10 @@
     = llvm_init_one_libfunc (USING_SJLJ_EXCEPTIONS
                              ? "__gcc_personality_sj0"
                              : "__gcc_personality_v0");
+  llvm_unwind_sjlj_register_libfunc 
+    = llvm_init_one_libfunc ("_Unwind_SjLj_Register");
+  llvm_unwind_sjlj_unregister_libfunc
+    = llvm_init_one_libfunc ("_Unwind_SjLj_Unregister");
 #else
   eh_personality_libfunc
     = init_one_libfunc (USING_SJLJ_EXCEPTIONS

Modified: llvm-gcc-4.2/trunk/gcc/cp/except.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/except.c?rev=78626&r1=78625&r2=78626&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/cp/except.c (original)
+++ llvm-gcc-4.2/trunk/gcc/cp/except.c Mon Aug 10 19:10:16 2009
@@ -97,6 +97,10 @@
     = llvm_init_one_libfunc (USING_SJLJ_EXCEPTIONS
                              ? "__gxx_personality_sj0"
                              : "__gxx_personality_v0");
+  llvm_unwind_sjlj_register_libfunc 
+    = llvm_init_one_libfunc ("_Unwind_SjLj_Register");
+  llvm_unwind_sjlj_unregister_libfunc
+    = llvm_init_one_libfunc ("_Unwind_SjLj_Unregister");
 #else
   eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
 					     ? "__gxx_personality_sj0"

Modified: llvm-gcc-4.2/trunk/gcc/except.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/except.c?rev=78626&r1=78625&r2=78626&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/except.c (original)
+++ llvm-gcc-4.2/trunk/gcc/except.c Mon Aug 10 19:10:16 2009
@@ -115,12 +115,21 @@
   htab_t type_to_runtime_map;
 
 /* Describe the SjLj_Function_Context structure.  */
+#ifndef ENABLE_LLVM
 static GTY(()) tree sjlj_fc_type_node;
 static int sjlj_fc_call_site_ofs;
 static int sjlj_fc_data_ofs;
 static int sjlj_fc_personality_ofs;
 static int sjlj_fc_lsda_ofs;
 static int sjlj_fc_jbuf_ofs;
+#else
+tree sjlj_fc_type_node;
+int sjlj_fc_call_site_ofs;
+int sjlj_fc_data_ofs;
+int sjlj_fc_personality_ofs;
+int sjlj_fc_lsda_ofs;
+int sjlj_fc_jbuf_ofs;
+#endif
 
 /* Describes one exception region.  */
 struct eh_region GTY(())
@@ -276,7 +285,7 @@
 static hashval_t ehspec_filter_hash (const void *);
 static int add_ttypes_entry (htab_t, tree);
 static int add_ehspec_entry (htab_t, htab_t, tree);
-static void assign_filter_values (void);
+/*static void assign_filter_values (void); */
 static void build_post_landing_pads (void);
 static void connect_post_landing_pads (void);
 static void dw2_build_landing_pads (void);
@@ -1376,7 +1385,7 @@
    we use lots of landing pads, and so every type or list can share
    the same filter value, which saves table space.  */
 
-static void
+/*static*/ void
 assign_filter_values (void)
 {
   int i;

Modified: llvm-gcc-4.2/trunk/gcc/except.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/except.h?rev=78626&r1=78625&r2=78626&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/except.h (original)
+++ llvm-gcc-4.2/trunk/gcc/except.h Mon Aug 10 19:10:16 2009
@@ -57,6 +57,7 @@
 /* After initial rtl generation, call back to finish generating
    exception support code.  */
 extern void finish_eh_generation (void);
+extern void assign_filter_values (void);
 
 extern void init_eh (void);
 extern void init_eh_for_function (void);
@@ -124,6 +125,13 @@
 extern struct eh_region *get_eh_region (unsigned);
 extern tree get_eh_type_list (struct eh_region *);
 extern tree lookup_type_for_runtime (tree);
+
+extern GTY(()) tree sjlj_fc_type_node;
+extern int sjlj_fc_call_site_ofs;
+extern int sjlj_fc_data_ofs;
+extern int sjlj_fc_personality_ofs;
+extern int sjlj_fc_lsda_ofs;
+extern int sjlj_fc_jbuf_ofs;
 #endif
 /* LLVM local end */
 

Modified: llvm-gcc-4.2/trunk/gcc/libfuncs.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/libfuncs.h?rev=78626&r1=78625&r2=78626&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/libfuncs.h (original)
+++ llvm-gcc-4.2/trunk/gcc/libfuncs.h Mon Aug 10 19:10:16 2009
@@ -82,9 +82,15 @@
 #ifdef ENABLE_LLVM
 #define llvm_unwind_resume_libfunc	(llvm_libfunc_table[LTI_unwind_resume])
 #define llvm_eh_personality_libfunc	(llvm_libfunc_table[LTI_eh_personality])
+#define llvm_unwind_sjlj_register_libfunc \
+  (llvm_libfunc_table[LTI_unwind_sjlj_register])
+#define llvm_unwind_sjlj_unregister_libfunc \
+  (llvm_libfunc_table[LTI_unwind_sjlj_unregister])
 #else
 #define llvm_unwind_resume_libfunc	unwind_resume_libfunc
 #define llvm_eh_personality_libfunc	eh_personality_libfunc
+#define llvm_unwind_sjlj_register_libfunc unwind_sjlj_register_libfunc
+#define llvm_unwind_sjlj_unregister_libfunc unwind_sjlj_unregister_libfunc
 #endif
 /* LLVM LOCAL end */
 

Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=78626&r1=78625&r2=78626&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Mon Aug 10 19:10:16 2009
@@ -59,6 +59,7 @@
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "except.h"
 #include "flags.h"
 #include "tree.h"
 #include "diagnostic.h"
@@ -499,7 +500,10 @@
 /// known at codegen time.
 void performLateBackendInitialization(void) {
   // The Ada front-end sets flag_exceptions only after processing the file.
-  ExceptionHandling = flag_exceptions;
+  if (USING_SJLJ_EXCEPTIONS)
+    SjLjExceptionHandling = flag_exceptions;
+  else
+    DwarfExceptionHandling = flag_exceptions;
   for (Module::iterator I = TheModule->begin(), E = TheModule->end();
        I != E; ++I)
     if (!I->isDeclaration()) {

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=78626&r1=78625&r2=78626&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Aug 10 19:10:16 2009
@@ -158,7 +158,7 @@
     TD(getTargetData()), Builder(Context, *TheFolder) {
   FnDecl = fndecl;
   Fn = 0;
-  ReturnBB = UnwindBB = 0;
+  ReturnBB = UnwindBB = DispatchBB = 0;
   ReturnOffset = 0;
   
   if (TheDebugInfo) {
@@ -632,7 +632,78 @@
     if (!DECL_LLVM_SET_P(TREE_VALUE(t)))
       EmitAutomaticVariableDecl(TREE_VALUE(t));
   }
-  
+
+  // 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::Int32Ty, 0);
+
+    // Assign the unwind personality function address
+    Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 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::Int32Ty, 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::Int32Ty, 5);
+    FieldPtr
+      = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2, "jbuf_gep");
+    Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 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::Int32Ty, 0));
+    Val = BitCastToType(Val, FieldTy);
+    Builder.CreateStore(Val, ElemPtr);
+
+    FieldPtr = BitCastToType(FieldPtr, llvm::Type::Int8Ty->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::Int32Ty, 0);
+    Value *Compare = Builder.CreateICmpEQ(DispatchVal, Zero);
+
+    // Branch on the compare.
+    DispatchBB = BasicBlock::Create("dispatch");
+    BasicBlock *PostEntryBB = BasicBlock::Create("post_entry");
+    Builder.CreateCondBr(Compare, PostEntryBB, DispatchBB);
+    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.
   ReturnBB = BasicBlock::Create("return");
 }
@@ -640,7 +711,16 @@
 Function *TreeToLLVM::FinishFunctionBody() {
   // Insert the return block at the end of the function.
   EmitBlock(ReturnBB);
-  
+
+  if (USING_SJLJ_EXCEPTIONS) {
+    // 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);
+    }
+  }
+
   SmallVector <Value *, 4> RetVals;
 
   // If the function returns a value, get it into a register and return it now.
@@ -700,9 +780,16 @@
     Builder.CreateAggregateRet(RetVals.data(), RetVals.size());
 
   // Emit pending exception handling code.
-  EmitLandingPads();
-  EmitPostPads();
-  EmitUnwindBlock();
+  if (USING_SJLJ_EXCEPTIONS) {
+    EmitSjLjLandingPads();
+    EmitPostPads();
+    EmitSjLjDispatcher();
+    EmitUnwindBlock();
+  } else {
+    EmitLandingPads();
+    EmitPostPads();
+    EmitUnwindBlock();
+  }
 
   // If this function takes the address of a label, emit the indirect goto
   // block.
@@ -1925,6 +2012,151 @@
   ((std::vector<struct eh_region *> *)data)->push_back(region);
 }
 
+/// EmitSjLjDispatcher - Emit SJLJ EH dispatcher
+void TreeToLLVM::EmitSjLjDispatcher () {
+  if (DispatchBB) {
+    EmitBlock(DispatchBB);
+    // Get the call_site value
+    llvm::Value *Idxs[2];
+    Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+    Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 1);
+    Value *FieldPtr = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2,
+                                  "call_site_gep");
+    Value *CallSite = Builder.CreateLoad(FieldPtr, "call_site");
+
+    // Figure out which landing pad to go to via the call_site
+    // FIXME: would this be better as a switch? Probably.
+    for (unsigned region = 1 ; region < LandingPads.size() ; ++region) {
+      if (LandingPads[region]) {
+        Value *RegionNo = ConstantInt::get(llvm::Type::Int32Ty, region - 1);
+        Value *Compare = Builder.CreateICmpEQ(CallSite, RegionNo);
+        // Branch on the compare.
+        BasicBlock *NextDispatch = BasicBlock::Create("dispatch");
+        Builder.CreateCondBr(Compare, LandingPads[region], NextDispatch);
+        EmitBlock(NextDispatch);
+      }
+    }
+    Builder.CreateBr(LandingPads[1]);
+  }
+}
+
+
+/// EmitSjLjLandingPads - Emit EH landing pads.
+void TreeToLLVM::EmitSjLjLandingPads() {
+  std::vector<Value*> Args;
+  std::vector<struct eh_region *> Handlers;
+
+  for (unsigned i = 1; i < LandingPads.size(); ++i) {
+    BasicBlock *LandingPad = LandingPads[i];
+
+    if (!LandingPad)
+      continue;
+
+    CreateExceptionValues();
+
+    EmitBlock(LandingPad);
+
+    // Fetch and store the exception selector.
+    // Get the exception value from the function context
+    llvm::Value *Idxs[2];
+    Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+    Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 2);
+    Value *FieldPtr
+      = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2, "jbuf_gep");
+    Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+    Value *ElemPtr
+      = Builder.CreateGEP (FieldPtr, Idxs, Idxs+2, "jbuf_exc_gep");
+    Value *Ex = Builder.CreateLoad (ElemPtr);
+    const Type *ExceptionValueTy =
+      cast<PointerType>(ExceptionValue->getType())->getElementType();
+    Ex = CastToAnyType(Ex, false, ExceptionValueTy, false);
+    Builder.CreateStore(Ex, ExceptionValue);
+
+
+    // The exception and the personality function.
+    Args.push_back(Builder.CreateLoad(ExceptionValue, "eh_ptr"));
+    assert(llvm_eh_personality_libfunc
+           && "no exception handling personality function!");
+    Args.push_back(BitCastToType(DECL_LLVM(llvm_eh_personality_libfunc),
+                                 PointerType::getUnqual(Type::Int8Ty)));
+    // Add selections for each handler.
+    foreach_reachable_handler(i, false, AddHandler, &Handlers);
+
+    for (std::vector<struct eh_region *>::iterator I = Handlers.begin(),
+         E = Handlers.end(); I != E; ++I) {
+      struct eh_region *region = *I;
+
+      // Create a post landing pad for the handler.
+      getPostPad(get_eh_region_number(region));
+      int RegionKind = classify_eh_handler(region);
+      if (RegionKind < 0) {
+        // Filter - note the length.
+        tree TypeList = get_eh_type_list(region);
+        unsigned Length = list_length(TypeList);
+        Args.reserve(Args.size() + Length + 1);
+        Args.push_back(ConstantInt::get(Type::Int32Ty, Length + 1));
+
+        // Add the type infos.
+        for (; TypeList; TypeList = TREE_CHAIN(TypeList)) {
+          tree TType = lookup_type_for_runtime(TREE_VALUE(TypeList));
+          Args.push_back(Emit(TType, 0));
+        }
+      } else if (RegionKind > 0) {
+        // Catch.
+        tree TypeList = get_eh_type_list(region);
+
+        if (!TypeList) {
+          // Catch-all - push a null pointer.
+          Args.push_back(Constant::getNullValue(
+              PointerType::getUnqual(Type::Int8Ty)));
+        } else {
+          // Add the type infos.
+          for (; TypeList; TypeList = TREE_CHAIN(TypeList)) {
+            tree TType = lookup_type_for_runtime(TREE_VALUE(TypeList));
+            Args.push_back(Emit(TType, 0));
+          }
+        }
+      }
+    }
+    if (can_throw_external_1(i, false)) {
+      // Some exceptions from this region may not be caught by any handler.
+      // Since invokes are required to branch to the unwind label no matter
+      // what exception is being unwound, append a catch-all.
+
+      // The representation of a catch-all is language specific.
+      Value *Catch_All;
+      if (!lang_eh_catch_all) {
+        // Use a "cleanup" - this should be good enough for most languages.
+        Catch_All = ConstantInt::get(Type::Int32Ty, 0);
+      } else {
+        tree catch_all_type = lang_eh_catch_all();
+        if (catch_all_type == NULL_TREE)
+          // Use a C++ style null catch-all object.
+          Catch_All =
+            Constant::getNullValue(PointerType::getUnqual(Type::Int8Ty));
+        else
+          // This language has a type that catches all others.
+          Catch_All = Emit(catch_all_type, 0);
+      }
+      Args.push_back(Catch_All);
+    }
+    // Add this in when we do catch() blocks
+#if 0
+    // Emit the selector call.
+    Value *Select = Builder.CreateCall(FuncEHSelector, Args.begin(), Args.end(),
+                                       "eh_select");
+    Builder.CreateStore(Select, ExceptionSelectorValue);
+#endif
+    // Branch to the post landing pad for the first reachable handler.
+    assert(!Handlers.empty() && "Landing pad but no handler?");
+    Builder.CreateBr(getPostPad(get_eh_region_number(*Handlers.begin())));
+
+    Handlers.clear();
+    Args.clear();
+  }
+}
+
+
 /// EmitLandingPads - Emit EH landing pads.
 void TreeToLLVM::EmitLandingPads() {
   std::vector<Value*> Args;
@@ -2022,7 +2254,6 @@
     Value *Select = Builder.CreateCall(FuncEHSelector, Args.begin(), Args.end(),
                                        "eh_select");
     Builder.CreateStore(Select, ExceptionSelectorValue);
-
     // Branch to the post landing pad for the first reachable handler.
     assert(!Handlers.empty() && "Landing pad but no handler?");
     Builder.CreateBr(getPostPad(get_eh_region_number(*Handlers.begin())));
@@ -2151,6 +2382,17 @@
   if (UnwindBB) {
     CreateExceptionValues();
     EmitBlock(UnwindBB);
+    if (USING_SJLJ_EXCEPTIONS) {
+      // Mark the call_site as -1 since we're signalling to continue
+      // the unwind now.
+      llvm::Value *Idxs[2];
+      Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+      Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 1);
+      Value *FieldPtr = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2,
+                                           "call_site_gep");
+      const Type *FieldTy = cast<PointerType>(FieldPtr->getType())->getElementType();
+      Builder.CreateStore(ConstantInt::get(FieldTy, (uint64_t)-1, true), FieldPtr);
+    }
     // Fetch and store exception handler.
     Value *Arg = Builder.CreateLoad(ExceptionValue, "eh_ptr");
     assert(llvm_unwind_resume_libfunc && "no unwind resume function!");
@@ -2652,6 +2894,26 @@
           ThisPad = BasicBlock::Create("lpad");
 
         LandingPad = ThisPad;
+
+        if (USING_SJLJ_EXCEPTIONS) {
+          // Mark the call site so we'll dispatch to the right landing pad
+          // when we get an exception passed back.
+          llvm::Value *Idxs[2];
+          Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+          Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 1);
+          Value *FieldPtr = Builder.CreateGEP (FunctionContext.Ptr,
+                                               Idxs, Idxs+2, "call_site_gep");
+//          FieldPtr = BitCastToType(FieldPtr,
+//                                   llvm::Type::Int32Ty->getPointerTo());
+          const Type *FieldTy = 
+            cast<PointerType>(FieldPtr->getType())->getElementType();
+          Constant *CallSiteIdx = ConstantInt::get(FieldTy, RegionNo, true);
+          Builder.CreateStore(CallSiteIdx, FieldPtr);
+          // Tell the back end what the call-site value is
+          Builder.CreateCall
+            (Intrinsic::getDeclaration(TheModule, Intrinsic::eh_sjlj_callsite),
+             CallSiteIdx);
+        }
       } else {
         assert(can_throw_external_1(RegionNo, false) &&
                "Must-not-throw region handled by runtime?");

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=78626&r1=78625&r2=78626&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Mon Aug 10 19:10:16 2009
@@ -297,7 +297,9 @@
   Function *Fn;
   BasicBlock *ReturnBB;
   BasicBlock *UnwindBB;
+  BasicBlock *DispatchBB;
   unsigned ReturnOffset;
+  MemRef FunctionContext; // For SJLJ exception handling
 
   // State that changes as the function is emitted.
 
@@ -451,6 +453,12 @@
   Value *EmitMemMove(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
   Value *EmitMemSet(Value *DestPtr, Value *SrcVal, Value *Size, unsigned Align);
 
+  /// EmitSjLjDispatcher - Emit SJLJ EH dispatcher
+  void EmitSjLjDispatcher();
+
+  /// EmitSjLjLandingPads - Emit SJLJ EH landing pads.
+  void EmitSjLjLandingPads();
+
   /// EmitLandingPads - Emit EH landing pads.
   void EmitLandingPads();
 

Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/objc-act.c?rev=78626&r1=78625&r2=78626&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original)
+++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Mon Aug 10 19:10:16 2009
@@ -8291,6 +8291,10 @@
 #ifdef ENABLE_LLVM
       llvm_eh_personality_libfunc
         = llvm_init_one_libfunc ("__objc_personality_v0");
+      llvm_unwind_sjlj_register_libfunc 
+        = llvm_init_one_libfunc ("_Unwind_SjLj_Register");
+      llvm_unwind_sjlj_unregister_libfunc
+        = llvm_init_one_libfunc ("_Unwind_SjLj_Unregister");
 #else
       eh_personality_libfunc
         = init_one_libfunc ("__objc_personality_v0");





More information about the llvm-commits mailing list