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

Duncan Sands baldrick at free.fr
Fri Mar 14 10:51:45 PDT 2008


Author: baldrick
Date: Fri Mar 14 12:51:45 2008
New Revision: 48365

URL: http://llvm.org/viewvc/llvm-project?rev=48365&view=rev
Log:
Enforce must-not-throw regions using invoke+terminate
("terminate" depends on the language) rather than by
using the 'nounwind' attribute.  This conceptually
simplifies the meaning of 'nounwind' at a small cost
in code size, which could in theory be eliminated by
an appropriate codegen pass.  The key change is in
except.c.

Modified:
    llvm-gcc-4.2/trunk/gcc/except.c
    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/except.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/except.c?rev=48365&r1=48364&r2=48365&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/except.c (original)
+++ llvm-gcc-4.2/trunk/gcc/except.c Fri Mar 14 12:51:45 2008
@@ -2650,13 +2650,21 @@
 	 inline a subroutine that contains handlers, and that will
 	 change the value of saw_any_handlers.  */
 
+/* LLVM local begin */
+#ifndef ENABLE_LLVM
       if ((info && info->saw_any_handlers) || !cfun->after_inlining)
 	{
+#endif
+/* LLVM local end */
 	  add_reachable_handler (info, region, region);
 	  return RNL_CAUGHT;
+/* LLVM local begin */
+#ifndef ENABLE_LLVM
 	}
       else
 	return RNL_BLOCKED;
+#endif
+/* LLVM local end */
 
     case ERT_THROW:
     case ERT_UNKNOWN:

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=48365&r1=48364&r2=48365&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Fri Mar 14 12:51:45 2008
@@ -66,7 +66,6 @@
 #include "rtl.h"
 #include "libfuncs.h"
 #include "tree-flow.h"
-extern bool tree_could_throw_p(tree);  // tree-flow.h uses non-C++ C constructs.
 extern int get_pointer_alignment (tree exp, unsigned int max_align);
 extern enum machine_mode reg_raw_mode[FIRST_PSEUDO_REGISTER];
 }
@@ -350,7 +349,7 @@
 TreeToLLVM::TreeToLLVM(tree fndecl) : TD(getTargetData()) {
   FnDecl = fndecl;
   Fn = 0;
-  ReturnBB = UnwindBB = NoUnwindBB = 0;
+  ReturnBB = UnwindBB = 0;
   
   if (TheDebugInfo) {
     expanded_location Location = expand_location(DECL_SOURCE_LOCATION (fndecl));
@@ -769,7 +768,6 @@
   EmitLandingPads();
   EmitPostPads();
   EmitUnwindBlock();
-  EmitNoUnwindBlock();
 
   // If this function takes the address of a label, emit the indirect goto
   // block.
@@ -2081,16 +2079,13 @@
 
     if (TargetBB) {
       Builder.CreateBr(TargetBB);
-    } else if (can_throw_external_1(i, true)) {
+    } else {
+      assert(can_throw_external_1(i, true) &&
+             "Must-not-throw region handled by runtime?");
       // Unwinding continues in the caller.
       if (!UnwindBB)
         UnwindBB = new BasicBlock("Unwind");
       Builder.CreateBr(UnwindBB);
-    } else {
-      // Unwinding in a must_not_throw region - notify the runtime.
-      if (!NoUnwindBB)
-        NoUnwindBB = new BasicBlock("NoUnwind");
-      Builder.CreateBr(NoUnwindBB);
     }
 
     Handlers.clear();
@@ -2110,22 +2105,6 @@
   }
 }
 
-/// EmitNoUnwindBlock - Emit the lazily created EH illegal-unwind block.
-void TreeToLLVM::EmitNoUnwindBlock() {
-  if (NoUnwindBB) {
-    CreateExceptionValues();
-    EmitBlock(NoUnwindBB);
-    // Fetch and store exception handler.
-    Value *Arg = Builder.CreateLoad(ExceptionValue, "eh_ptr");
-    assert(llvm_unwind_resume_libfunc && "no unwind resume function!");
-    CallInst *Call =
-      Builder.CreateCall(DECL_LLVM(llvm_unwind_resume_libfunc), Arg);
-    // Illegal unwind - notify the runtime.
-    Call->setDoesNotThrow();
-    Builder.CreateUnreachable();
-  }
-}
-
 //===----------------------------------------------------------------------===//
 //                           ... Expressions ...
 //===----------------------------------------------------------------------===//
@@ -2447,26 +2426,26 @@
 /// result, otherwise store it in DestLoc.
 Value *TreeToLLVM::EmitCallOf(Value *Callee, tree exp, const MemRef *DestLoc,
                               const PAListPtr &InPAL) {
+  BasicBlock *LandingPad = 0; // Non-zero indicates an invoke.
+
   PAListPtr PAL = InPAL;
   if (PAL.isEmpty() && isa<Function>(Callee))
     PAL = cast<Function>(Callee)->getParamAttrs();
 
-  // Determine if we need to generate an invoke instruction (instead of a simple
-  // call) and if so, what the exception destination will be.
-  BasicBlock *LandingPad = 0;
-  bool NoUnwind =
-    (PAL.paramHasAttr(0, ParamAttr::NoUnwind)) ||
-    !tree_could_throw_p(exp);
+  if (!tree_could_throw_p(exp))
+    // This call does not throw - mark it 'nounwind'.
+    PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
 
-  // Do not turn nounwind calls into invokes.
-  if (!NoUnwind) {
+  if (!PAL.paramHasAttr(0, ParamAttr::NoUnwind)) {
+    // This call may throw.  Determine if we need to generate
+    // an invoke rather than a simple call.
     int RegionNo = lookup_stmt_eh_region(exp);
 
     // Is the call contained in an exception handling region?
     if (RegionNo > 0) {
       // Are there any exception handlers for this region?
       if (can_throw_internal_1(RegionNo, false)) {
-        // Turn the call into an invoke.
+        // There are - turn the call into an invoke.
         LandingPads.grow(RegionNo);
         BasicBlock *&ThisPad = LandingPads[RegionNo];
 
@@ -2476,17 +2455,12 @@
 
         LandingPad = ThisPad;
       } else {
-        // Can this call unwind out of the current function?
-        NoUnwind = !can_throw_external_1(RegionNo, false);
+        assert(can_throw_external_1(RegionNo, false) &&
+               "Must-not-throw region handled by runtime?");
       }
     }
   }
 
-  if (NoUnwind)
-    // This particular call does not unwind even though the callee may
-    // unwind in general.  Add the 'nounwind' attribute to the call.
-    PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
-
   SmallVector<Value*, 16> CallOperands;
   CallingConv::ID CallingConvention;
   FunctionCallArgumentConversion Client(exp, CallOperands, CallingConvention,
@@ -3455,16 +3429,13 @@
       getPostPad(get_eh_region_number(*I));
 
     Builder.CreateBr(getPostPad(get_eh_region_number(*Handlers.begin())));
-  } else if (can_throw_external_1(RegionNo, true)) {
+  } else {
+    assert(can_throw_external_1(RegionNo, true) &&
+           "Must-not-throw region handled by runtime?");
     // Unwinding continues in the caller.
     if (!UnwindBB)
       UnwindBB = new BasicBlock("Unwind");
     Builder.CreateBr(UnwindBB);
-  } else {
-    // Unwinding in a must_not_throw region - notify the runtime.
-    if (!NoUnwindBB)
-      NoUnwindBB = new BasicBlock("NoUnwind");
-    Builder.CreateBr(NoUnwindBB);
   }
 
   EmitBlock(new BasicBlock(""));

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=48365&r1=48364&r2=48365&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Fri Mar 14 12:51:45 2008
@@ -274,7 +274,6 @@
   Function *Fn;
   BasicBlock *ReturnBB;
   BasicBlock *UnwindBB;
-  BasicBlock *NoUnwindBB;
 
   // State that changes as the function is emitted.
 
@@ -432,9 +431,6 @@
   /// EmitUnwindBlock - Emit the lazily created EH unwind block.
   void EmitUnwindBlock();
 
-  /// EmitNoUnwindBlock - Emit the lazily created EH illegal-unwind block.
-  void EmitNoUnwindBlock();
-
 private: // Helpers for exception handling.
 
   /// CreateExceptionValues - Create values used internally by exception





More information about the llvm-commits mailing list