[llvm-commits] [llvm-gcc-4.2] r138984 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Bill Wendling isanbard at gmail.com
Thu Sep 1 16:39:57 PDT 2011


Author: void
Date: Thu Sep  1 18:39:57 2011
New Revision: 138984

URL: http://llvm.org/viewvc/llvm-project?rev=138984&view=rev
Log:
Update to use the new EH scheme.

This uses the landingpad instruction in place of the llvm.eh.exception and
llvm.eh.selector calls. The values returned by the instruction are always
stored. The 'resume' instruction replaces the direct call to _Unwind_Resume.

This is based partially off of dragonegg's EH implementation.

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

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=138984&r1=138983&r2=138984&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Sep  1 18:39:57 2011
@@ -2205,9 +2205,19 @@
 
 /// EmitLandingPads - Emit EH landing pads.
 void TreeToLLVM::EmitLandingPads() {
-  std::vector<Value*> Args;
   std::vector<struct eh_region *> Handlers;
 
+  Constant *CatchAllVal = 0;
+  tree catch_all_type = lang_eh_catch_all();
+  if (catch_all_type == NULL_TREE)
+    // Use a C++ style null catch-all object.
+    CatchAllVal = Constant::getNullValue(Type::getInt8PtrTy(Context));
+  else
+    // This language has a type that catches all others.
+    CatchAllVal = cast<Constant>(Emit(catch_all_type, 0));
+
+  Type *UnwindDataTy = StructType::get(Builder.getInt8PtrTy(),
+                                       Builder.getInt32Ty(), NULL);
   for (unsigned i = 1; i < LandingPads.size(); ++i) {
     BasicBlock *LandingPad = LandingPads[i];
 
@@ -2225,11 +2235,19 @@
     // Fetch and store the exception selector.
 
     // 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),
-                                 Type::getInt8PtrTy(Context)));
+    LandingPadInst *LPadInst =
+      Builder.CreateLandingPad(UnwindDataTy,
+                               BitCastToType(DECL_LLVM(llvm_eh_personality_libfunc),
+                                             Type::getInt8PtrTy(Context)),
+                               0, "exc");
+
+    Value *ExcPtr = Builder.CreateExtractValue(LPadInst, 0, "exc_ptr");
+    Builder.CreateStore(ExcPtr, ExceptionValue);
+
+    Value *Select = Builder.CreateExtractValue(LPadInst, 1, "filter");
+    Builder.CreateStore(Select, ExceptionSelectorValue);
 
     // Add selections for each handler.
     foreach_reachable_handler(i, false, AddHandler, &Handlers);
@@ -2246,31 +2264,33 @@
 
       int RegionKind = classify_eh_handler(region);
       if (RegionKind < 0) {
-        // Filter - note the length.
+        // Filter.
         tree TypeList = get_eh_type_list(region);
-        unsigned Length = list_length(TypeList);
-        Args.reserve(Args.size() + Length + 1);
-        Args.push_back(ConstantInt::get(Type::getInt32Ty(Context), Length + 1));
 
         // Add the type infos.
+        std::vector<Constant*> TypeInfos;
         for (; TypeList; TypeList = TREE_CHAIN(TypeList)) {
           tree TType = lookup_type_for_runtime(TREE_VALUE(TypeList));
-          Args.push_back(Emit(TType, 0));
+          TypeInfos.push_back(cast<Constant>(Emit(TType, 0)));
         }
+
+        // Add the list of typeinfos as a filter clause.
+        ArrayType *FilterTy = ArrayType::get(Builder.getInt8PtrTy(),
+                                             TypeInfos.size());
+        LPadInst->addClause(ConstantArray::get(FilterTy, TypeInfos));
       } else if (RegionKind > 0) {
         // Catch.
         tree TypeList = get_eh_type_list(region);
 
         if (!TypeList) {
           // Catch-all - push the catch-all object.
-          assert(CatchAll && "Language did not define lang_eh_catch_all?");
-          Args.push_back(CatchAll);
+          LPadInst->addClause(CatchAllVal);
           HasCatchAll = true;
         } 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));
+            LPadInst->addClause(Emit(TType, 0));
           }
         }
       } else {
@@ -2281,30 +2301,26 @@
 
     if (can_throw_external_1(i, false)) {
       if (HasCleanup) {
-        if (Args.size() == 2 || USING_SJLJ_EXCEPTIONS || !lang_eh_catch_all) {
+        if (LPadInst->getNumClauses() == 0 || USING_SJLJ_EXCEPTIONS || !lang_eh_catch_all) {
           // Insert the sentinal indicating that this is a cleanup-only
           // selector.  It may also be the representation of a catch-all for
           // some languages.
-          Args.push_back(ConstantInt::get(Type::getInt32Ty(Context), 0));
+          LPadInst->setCleanup(true);
         } else if (!HasCatchAll) {
           // 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.
-          assert(CatchAll && "Language did not define lang_eh_catch_all?");
-          Args.push_back(CatchAll);
+          assert(CatchAllVal && "Language did not define lang_eh_catch_all?");
+          LPadInst->addClause(CatchAllVal);
         }
       }
     }
 
-    // Emit the selector call.
-    Value *Select = Builder.CreateCall(FuncEHSelector, Args, "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())));
 
     Handlers.clear();
-    Args.clear();
   }
 }
 
@@ -2424,29 +2440,19 @@
 
 /// EmitUnwindBlock - Emit the lazily created EH unwind block.
 void TreeToLLVM::EmitUnwindBlock() {
-  if (UnwindBB) {
-    CreateExceptionValues();
-    EmitBlock(UnwindBB);
-    // Fetch and store exception handler.
-    Value *Arg = Builder.CreateLoad(ExceptionValue, "eh_ptr");
-    assert(llvm_unwind_resume_libfunc && "no unwind resume function!");
-
-    // As we're emitting a naked call (not an expression) going through
-    // EmitCallOf would be wasteful and incorrect. Manually adjust
-    // the calling convention for this call here if necessary.
-#ifdef TARGET_ADJUST_LLVM_CC
-    tree fntype = TREE_TYPE(llvm_unwind_resume_libfunc);
-    CallingConv::ID CallingConvention = CallingConv::C;
+  if (!UnwindBB) return;
 
-    TARGET_ADJUST_LLVM_CC(CallingConvention, fntype);
-    CallInst *Call = Builder.CreateCall(DECL_LLVM(llvm_unwind_resume_libfunc),
-                                        Arg);
-    Call->setCallingConv(CallingConvention);
-#else
-    Builder.CreateCall(DECL_LLVM(llvm_unwind_resume_libfunc), Arg);
-#endif
-    Builder.CreateUnreachable();
-  }
+  CreateExceptionValues();
+  EmitBlock(UnwindBB);
+
+  Value *ExcPtr = Builder.CreateLoad(ExceptionValue, "eh_ptr");
+  Value *Filter = Builder.CreateLoad(ExceptionSelectorValue, "eh_sel");
+  Type *UnwindDataTy = StructType::get(Builder.getInt8PtrTy(),
+                                       Builder.getInt32Ty(), NULL);
+  Value *UnwindData = UndefValue::get(UnwindDataTy);
+  UnwindData = Builder.CreateInsertValue(UnwindData, ExcPtr, 0, "exc_ptr");
+  UnwindData = Builder.CreateInsertValue(UnwindData, Filter, 1, "filter");
+  Builder.CreateResume(UnwindData);
 }
 
 //===----------------------------------------------------------------------===//





More information about the llvm-commits mailing list