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

Bill Wendling isanbard at gmail.com
Tue Sep 6 17:50:54 PDT 2011


Author: void
Date: Tue Sep  6 19:50:54 2011
New Revision: 139212

URL: http://llvm.org/viewvc/llvm-project?rev=139212&view=rev
Log:
Reapply r138984 with changes suggested by Duncan:

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
    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=139212&r1=139211&r2=139212&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Sep  6 19:50:54 2011
@@ -188,7 +188,6 @@
   GreatestAlignment = TheTarget->getFrameLowering()->getStackAlignment();
   SeenVLA = NULL;
 
-  CatchAll = 0;
   ExceptionValue = 0;
   ExceptionSelectorValue = 0;
   FuncEHException = 0;
@@ -2164,25 +2163,6 @@
                                               Intrinsic::eh_selector);
   FuncEHGetTypeID = Intrinsic::getDeclaration(TheModule,
                                               Intrinsic::eh_typeid_for);
-
-  CatchAll = TheModule->getGlobalVariable("llvm.eh.catch.all.value");
-  if (!CatchAll && lang_eh_catch_all) {
-    Constant *Init = 0;
-    tree catch_all_type = lang_eh_catch_all();
-    if (catch_all_type == NULL_TREE)
-      // Use a C++ style null catch-all object.
-      Init = Constant::getNullValue(Type::getInt8PtrTy(Context));
-    else
-      // This language has a type that catches all others.
-      Init = cast<Constant>(Emit(catch_all_type, 0));
-
-    CatchAll = new GlobalVariable(*TheModule, Init->getType(), true,
-                                  GlobalVariable::LinkOnceAnyLinkage,
-                                  Init, "llvm.eh.catch.all.value");
-    CatchAll->setUnnamedAddr(true);
-    CatchAll->setSection("llvm.metadata");
-    AttributeUsedGlobals.insert(CatchAll);
-  }
 }
 
 /// getPostPad - Return the post landing pad for the given exception handling
@@ -2205,9 +2185,10 @@
 
 /// EmitLandingPads - Emit EH landing pads.
 void TreeToLLVM::EmitLandingPads() {
-  std::vector<Value*> Args;
   std::vector<struct eh_region *> Handlers;
 
+  Type *UnwindDataTy = StructType::get(Builder.getInt8PtrTy(),
+                                       Builder.getInt32Ty(), NULL);
   for (unsigned i = 1; i < LandingPads.size(); ++i) {
     BasicBlock *LandingPad = LandingPads[i];
 
@@ -2225,11 +2206,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 +2235,34 @@
 
       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(Constant::getNullValue(Type::getInt8PtrTy(Context)));
           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 {
@@ -2279,32 +2271,14 @@
       }
     }
 
-    if (can_throw_external_1(i, false)) {
-      if (HasCleanup) {
-        if (Args.size() == 2 || 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));
-        } 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);
-        }
-      }
-    }
+    if (can_throw_external_1(i, false) && HasCleanup)
+      LPadInst->setCleanup(true);
 
-    // 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 +2398,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);
 }
 
 //===----------------------------------------------------------------------===//

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=139212&r1=139211&r2=139212&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Tue Sep  6 19:50:54 2011
@@ -317,9 +317,6 @@
   /// PostPads - The post landing pad for a given EH region.
   IndexedMap<BasicBlock *> PostPads;
 
-  /// CatchAll - Language specific catch-all object.
-  GlobalVariable *CatchAll;
-
   /// ExceptionValue - Is the local to receive the current exception.
   Value *ExceptionValue;
 





More information about the llvm-commits mailing list