[llvm-commits] [llvm] r136253 - in /llvm/trunk: docs/ include/llvm-c/ include/llvm/ include/llvm/Bitcode/ include/llvm/Support/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Target/CBackend/ lib/Target/CppBackend/ lib/Transforms/IPO/ lib/Transforms/InstCombine/ lib/Transforms/Scalar/ lib/VMCore/ test/Feature/

Bill Wendling isanbard at gmail.com
Wed Jul 27 13:18:04 PDT 2011


Author: void
Date: Wed Jul 27 15:18:04 2011
New Revision: 136253

URL: http://llvm.org/viewvc/llvm-project?rev=136253&view=rev
Log:
Merge the contents from exception-handling-rewrite to the mainline.

This adds the new instructions 'landingpad' and 'resume'.

Added:
    llvm/trunk/test/Feature/exceptionhandling.ll
Modified:
    llvm/trunk/docs/LangRef.html
    llvm/trunk/include/llvm-c/Core.h
    llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
    llvm/trunk/include/llvm/Instruction.def
    llvm/trunk/include/llvm/Instructions.h
    llvm/trunk/include/llvm/Support/IRBuilder.h
    llvm/trunk/include/llvm/Support/InstVisitor.h
    llvm/trunk/lib/AsmParser/LLLexer.cpp
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/AsmParser/LLParser.h
    llvm/trunk/lib/AsmParser/LLToken.h
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
    llvm/trunk/lib/CodeGen/ShadowStackGC.cpp
    llvm/trunk/lib/Target/CBackend/CBackend.cpp
    llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp
    llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
    llvm/trunk/lib/Transforms/Scalar/SCCP.cpp
    llvm/trunk/lib/VMCore/AsmWriter.cpp
    llvm/trunk/lib/VMCore/Core.cpp
    llvm/trunk/lib/VMCore/Instruction.cpp
    llvm/trunk/lib/VMCore/Instructions.cpp
    llvm/trunk/lib/VMCore/Verifier.cpp

Modified: llvm/trunk/docs/LangRef.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.html (original)
+++ llvm/trunk/docs/LangRef.html Wed Jul 27 15:18:04 2011
@@ -123,6 +123,7 @@
           <li><a href="#i_indirectbr">'<tt>indirectbr</tt>' Instruction</a></li>
           <li><a href="#i_invoke">'<tt>invoke</tt>' Instruction</a></li>
           <li><a href="#i_unwind">'<tt>unwind</tt>'  Instruction</a></li>
+          <li><a href="#i_resume">'<tt>resume</tt>'  Instruction</a></li>
           <li><a href="#i_unreachable">'<tt>unreachable</tt>' Instruction</a></li>
         </ol>
       </li>
@@ -2942,13 +2943,14 @@
    control flow, not values (the one exception being the
    '<a href="#i_invoke"><tt>invoke</tt></a>' instruction).</p>
 
-<p>There are seven different terminator instructions: the
+<p>There are eight different terminator instructions: the
    '<a href="#i_ret"><tt>ret</tt></a>' instruction, the
    '<a href="#i_br"><tt>br</tt></a>' instruction, the
    '<a href="#i_switch"><tt>switch</tt></a>' instruction, the
    '<a href="#i_indirectbr">'<tt>indirectbr</tt></a>' Instruction, the
    '<a href="#i_invoke"><tt>invoke</tt></a>' instruction, the
-   '<a href="#i_unwind"><tt>unwind</tt></a>' instruction, and the
+   '<a href="#i_unwind"><tt>unwind</tt></a>' instruction, the
+   '<a href="#i_resume"><tt>resume</tt></a>' instruction, and the
    '<a href="#i_unreachable"><tt>unreachable</tt></a>' instruction.</p>
 
 <!-- _______________________________________________________________________ -->
@@ -3272,6 +3274,35 @@
 <!-- _______________________________________________________________________ -->
 
 <h4>
+  <a name="i_resume">'<tt>resume</tt>' Instruction</a>
+</h4>
+
+<div>
+
+<h5>Syntax:</h5>
+<pre>
+  resume <type> <value>
+</pre>
+
+<h5>Overview:</h5>
+<p>The '<tt>resume</tt>' instruction is a terminator instruction that has no
+   successors. Its operand must have the same type as the result of any
+   '<tt>landingpad</tt>' instruction in the same function.</p>
+
+<h5>Semantics:</h5>
+<p>The '<tt>resume</tt>' instruction resumes propagation of an existing
+   (in-flight) exception.</p>
+
+<h5>Example:</h5>
+<pre>
+ resume { i8*, i32 } %exn
+</pre>
+
+</div>
+
+<!-- _______________________________________________________________________ -->
+
+<h4>
   <a name="i_unreachable">'<tt>unreachable</tt>' Instruction</a>
 </h4>
 

Modified: llvm/trunk/include/llvm-c/Core.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/include/llvm-c/Core.h (original)
+++ llvm/trunk/include/llvm-c/Core.h Wed Jul 27 15:18:04 2011
@@ -126,67 +126,69 @@
   LLVMIndirectBr     = 4,
   LLVMInvoke         = 5,
   LLVMUnwind         = 6,
-  LLVMUnreachable    = 7,
+  LLVMResume         = 7,
+  LLVMUnreachable    = 8,
 
   /* Standard Binary Operators */
-  LLVMAdd            = 8,
-  LLVMFAdd           = 9,
-  LLVMSub            = 10,
-  LLVMFSub           = 11,
-  LLVMMul            = 12,
-  LLVMFMul           = 13,
-  LLVMUDiv           = 14,
-  LLVMSDiv           = 15,
-  LLVMFDiv           = 16,
-  LLVMURem           = 17,
-  LLVMSRem           = 18,
-  LLVMFRem           = 19,
+  LLVMAdd            = 9,
+  LLVMFAdd           = 10,
+  LLVMSub            = 11,
+  LLVMFSub           = 12,
+  LLVMMul            = 13,
+  LLVMFMul           = 14,
+  LLVMUDiv           = 15,
+  LLVMSDiv           = 16,
+  LLVMFDiv           = 17,
+  LLVMURem           = 18,
+  LLVMSRem           = 19,
+  LLVMFRem           = 20,
 
   /* Logical Operators */
-  LLVMShl            = 20,
-  LLVMLShr           = 21,
-  LLVMAShr           = 22,
-  LLVMAnd            = 23,
-  LLVMOr             = 24,
-  LLVMXor            = 25,
+  LLVMShl            = 21,
+  LLVMLShr           = 22,
+  LLVMAShr           = 23,
+  LLVMAnd            = 24,
+  LLVMOr             = 25,
+  LLVMXor            = 26,
 
   /* Memory Operators */
-  LLVMAlloca         = 26,
-  LLVMLoad           = 27,
-  LLVMStore          = 28,
-  LLVMGetElementPtr  = 29,
+  LLVMAlloca         = 27,
+  LLVMLoad           = 28,
+  LLVMStore          = 29,
+  LLVMGetElementPtr  = 30,
 
   /* Cast Operators */
-  LLVMTrunc          = 30,
-  LLVMZExt           = 31,
-  LLVMSExt           = 32,
-  LLVMFPToUI         = 33,
-  LLVMFPToSI         = 34,
-  LLVMUIToFP         = 35,
-  LLVMSIToFP         = 36,
-  LLVMFPTrunc        = 37,
-  LLVMFPExt          = 38,
-  LLVMPtrToInt       = 39,
-  LLVMIntToPtr       = 40,
-  LLVMBitCast        = 41,
+  LLVMTrunc          = 31,
+  LLVMZExt           = 32,
+  LLVMSExt           = 33,
+  LLVMFPToUI         = 34,
+  LLVMFPToSI         = 35,
+  LLVMUIToFP         = 36,
+  LLVMSIToFP         = 37,
+  LLVMFPTrunc        = 38,
+  LLVMFPExt          = 39,
+  LLVMPtrToInt       = 40,
+  LLVMIntToPtr       = 41,
+  LLVMBitCast        = 42,
 
   /* Other Operators */
-  LLVMICmp           = 42,
-  LLVMFCmp           = 43,
-  LLVMPHI            = 44,
-  LLVMCall           = 45,
-  LLVMSelect         = 46,
+  LLVMICmp           = 43,
+  LLVMFCmp           = 44,
+  LLVMPHI            = 45,
+  LLVMCall           = 46,
+  LLVMSelect         = 47,
   /* UserOp1 */
   /* UserOp2 */
-  LLVMVAArg          = 49,
-  LLVMExtractElement = 50,
-  LLVMInsertElement  = 51,
-  LLVMShuffleVector  = 52,
-  LLVMExtractValue   = 53,
-  LLVMInsertValue    = 54,
+  LLVMVAArg          = 50,
+  LLVMExtractElement = 51,
+  LLVMInsertElement  = 52,
+  LLVMShuffleVector  = 53,
+  LLVMExtractValue   = 54,
+  LLVMInsertValue    = 55,
+  LLVMLandingPad     = 56,
 
   /* Atomic operators */
-  LLVMFence          = 55
+  LLVMFence          = 57
 } LLVMOpcode;
 
 typedef enum {
@@ -277,6 +279,11 @@
   LLVMRealPredicateTrue   /**< Always true (always folded) */
 } LLVMRealPredicate;
 
+typedef enum {
+  LLVMCatch,              /**< A catch clause   */
+  LLVMFilter              /**< A filter clause  */
+} LLVMLandingPadClauseTy;
+
 void LLVMInitializeCore(LLVMPassRegistryRef R);
 
 
@@ -463,6 +470,7 @@
       macro(GetElementPtrInst)              \
       macro(InsertElementInst)              \
       macro(InsertValueInst)                \
+      macro(LandingPadInst)                 \
       macro(PHINode)                        \
       macro(SelectInst)                     \
       macro(ShuffleVectorInst)              \
@@ -474,6 +482,7 @@
         macro(SwitchInst)                   \
         macro(UnreachableInst)              \
         macro(UnwindInst)                   \
+        macro(ResumeInst)                   \
     macro(UnaryInstruction)                 \
       macro(AllocaInst)                     \
       macro(CastInst)                       \
@@ -822,6 +831,7 @@
                              LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
                              const char *Name);
 LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef);
+LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn);
 LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef);
 
 /* Add a case to the switch instruction */
@@ -831,6 +841,13 @@
 /* Add a destination to the indirectbr instruction */
 void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest);
 
+/* Add a clause to the landingpad instruction */
+void LLVMAddClause(LLVMValueRef LandingPad, LLVMLandingPadClauseTy ClauseTy,
+                   LLVMValueRef ClauseVal);
+
+/* Set the 'cleanup' flag in the landingpad instruction */
+void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val);
+
 /* Arithmetic */
 LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
                           const char *Name);

Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original)
+++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Wed Jul 27 15:18:04 2011
@@ -257,7 +257,7 @@
     FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE
 
     FUNC_CODE_INST_PHI         = 16, // PHI:        [ty, val0,bb0, ...]
-    // 17 is unused.
+    FUNC_CODE_INST_RESUME      = 17, // RESUME:     [opval]
     // 18 is unused.
     FUNC_CODE_INST_ALLOCA      = 19, // ALLOCA:     [instty, op, align]
     FUNC_CODE_INST_LOAD        = 20, // LOAD:       [opty, op, align, vol]
@@ -284,7 +284,8 @@
     FUNC_CODE_INST_CALL        = 34, // CALL:       [attr, fnty, fnid, args...]
 
     FUNC_CODE_DEBUG_LOC        = 35, // DEBUG_LOC:  [Line,Col,ScopeVal, IAVal]
-    FUNC_CODE_INST_FENCE       = 36  // FENCE: [ordering, synchscope]
+    FUNC_CODE_INST_FENCE       = 36, // FENCE: [ordering, synchscope]
+    FUNC_CODE_INST_LANDINGPAD  = 37  // LANDINGPAD: [ty,val,val,num,id0,val0...]
   };
 } // End bitc namespace
 } // End llvm namespace

Modified: llvm/trunk/include/llvm/Instruction.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instruction.def?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Instruction.def (original)
+++ llvm/trunk/include/llvm/Instruction.def Wed Jul 27 15:18:04 2011
@@ -100,41 +100,42 @@
 HANDLE_TERM_INST  ( 4, IndirectBr , IndirectBrInst)
 HANDLE_TERM_INST  ( 5, Invoke     , InvokeInst)
 HANDLE_TERM_INST  ( 6, Unwind     , UnwindInst)
-HANDLE_TERM_INST  ( 7, Unreachable, UnreachableInst)
-  LAST_TERM_INST  ( 7)
+HANDLE_TERM_INST  ( 7, Resume     , ResumeInst)
+HANDLE_TERM_INST  ( 8, Unreachable, UnreachableInst)
+  LAST_TERM_INST  ( 8)
 
 // Standard binary operators...
- FIRST_BINARY_INST( 8)
-HANDLE_BINARY_INST( 8, Add  , BinaryOperator)
-HANDLE_BINARY_INST( 9, FAdd  , BinaryOperator)
-HANDLE_BINARY_INST(10, Sub  , BinaryOperator)
-HANDLE_BINARY_INST(11, FSub  , BinaryOperator)
-HANDLE_BINARY_INST(12, Mul  , BinaryOperator)
-HANDLE_BINARY_INST(13, FMul  , BinaryOperator)
-HANDLE_BINARY_INST(14, UDiv , BinaryOperator)
-HANDLE_BINARY_INST(15, SDiv , BinaryOperator)
-HANDLE_BINARY_INST(16, FDiv , BinaryOperator)
-HANDLE_BINARY_INST(17, URem , BinaryOperator)
-HANDLE_BINARY_INST(18, SRem , BinaryOperator)
-HANDLE_BINARY_INST(19, FRem , BinaryOperator)
+ FIRST_BINARY_INST( 9)
+HANDLE_BINARY_INST( 9, Add  , BinaryOperator)
+HANDLE_BINARY_INST(10, FAdd , BinaryOperator)
+HANDLE_BINARY_INST(11, Sub  , BinaryOperator)
+HANDLE_BINARY_INST(12, FSub , BinaryOperator)
+HANDLE_BINARY_INST(13, Mul  , BinaryOperator)
+HANDLE_BINARY_INST(14, FMul , BinaryOperator)
+HANDLE_BINARY_INST(15, UDiv , BinaryOperator)
+HANDLE_BINARY_INST(16, SDiv , BinaryOperator)
+HANDLE_BINARY_INST(17, FDiv , BinaryOperator)
+HANDLE_BINARY_INST(18, URem , BinaryOperator)
+HANDLE_BINARY_INST(19, SRem , BinaryOperator)
+HANDLE_BINARY_INST(20, FRem , BinaryOperator)
 
 // Logical operators (integer operands)
-HANDLE_BINARY_INST(20, Shl  , BinaryOperator) // Shift left  (logical)
-HANDLE_BINARY_INST(21, LShr , BinaryOperator) // Shift right (logical)
-HANDLE_BINARY_INST(22, AShr , BinaryOperator) // Shift right (arithmetic)
-HANDLE_BINARY_INST(23, And  , BinaryOperator)
-HANDLE_BINARY_INST(24, Or   , BinaryOperator)
-HANDLE_BINARY_INST(25, Xor  , BinaryOperator)
-  LAST_BINARY_INST(25)
+HANDLE_BINARY_INST(21, Shl  , BinaryOperator) // Shift left  (logical)
+HANDLE_BINARY_INST(22, LShr , BinaryOperator) // Shift right (logical)
+HANDLE_BINARY_INST(23, AShr , BinaryOperator) // Shift right (arithmetic)
+HANDLE_BINARY_INST(24, And  , BinaryOperator)
+HANDLE_BINARY_INST(25, Or   , BinaryOperator)
+HANDLE_BINARY_INST(26, Xor  , BinaryOperator)
+  LAST_BINARY_INST(26)
 
 // Memory operators...
- FIRST_MEMORY_INST(26)
-HANDLE_MEMORY_INST(26, Alloca, AllocaInst)  // Stack management
-HANDLE_MEMORY_INST(27, Load  , LoadInst  )  // Memory manipulation instrs
-HANDLE_MEMORY_INST(28, Store , StoreInst )
-HANDLE_MEMORY_INST(29, GetElementPtr, GetElementPtrInst)
-HANDLE_MEMORY_INST(30, Fence , FenceInst )
-  LAST_MEMORY_INST(30)
+ FIRST_MEMORY_INST(27)
+HANDLE_MEMORY_INST(27, Alloca, AllocaInst)  // Stack management
+HANDLE_MEMORY_INST(28, Load  , LoadInst  )  // Memory manipulation instrs
+HANDLE_MEMORY_INST(29, Store , StoreInst )
+HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst)
+HANDLE_MEMORY_INST(31, Fence , FenceInst )
+  LAST_MEMORY_INST(31)
 
 // Cast operators ...
 // NOTE: The order matters here because CastInst::isEliminableCastPair 
@@ -169,8 +170,8 @@
 HANDLE_OTHER_INST(55, ShuffleVector, ShuffleVectorInst)  // shuffle two vectors.
 HANDLE_OTHER_INST(56, ExtractValue, ExtractValueInst)// extract from aggregate
 HANDLE_OTHER_INST(57, InsertValue, InsertValueInst)  // insert into aggregate
-
-  LAST_OTHER_INST(57)
+HANDLE_OTHER_INST(58, LandingPad, LandingPadInst)  // Landing pad instruction.
+  LAST_OTHER_INST(58)
 
 #undef  FIRST_TERM_INST
 #undef HANDLE_TERM_INST

Modified: llvm/trunk/include/llvm/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Instructions.h (original)
+++ llvm/trunk/include/llvm/Instructions.h Wed Jul 27 15:18:04 2011
@@ -1775,6 +1775,116 @@
 
 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PHINode, Value)
 
+//===----------------------------------------------------------------------===//
+//                           LandingPadInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// LandingPadInst - The landingpad instruction holds all of the information
+/// necessary to generate correct exception handling. The landingpad instruction
+/// cannot be moved from the top of a landing pad block, which itself is
+/// accessible only from the 'unwind' edge of an invoke.
+///
+class LandingPadInst : public Instruction {
+  /// ReservedSpace - The number of operands actually allocated.  NumOperands is
+  /// the number actually in use.
+  unsigned ReservedSpace;
+
+  /// IsCleanup - True if the landingpad instruction is also a cleanup.
+  bool IsCleanup;
+  LandingPadInst(const LandingPadInst &LP);
+public:
+  enum ClauseType { Catch, Filter };
+private:
+  /// ClauseIdxs - This indexes into the OperandList, indicating what the
+  /// values are at a given index.
+  SmallVector<ClauseType, 8> ClauseIdxs;
+
+  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
+  // Allocate space for exactly zero operands.
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+  void growOperands();
+  void init(Value *PersFn, unsigned NumReservedValues, const Twine &NameStr);
+
+  explicit LandingPadInst(Type *RetTy, Value *PersonalityFn,
+                          unsigned NumReservedValues, const Twine &NameStr,
+                          Instruction *InsertBefore)
+    : Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertBefore),
+      IsCleanup(false) {
+    init(PersonalityFn, 1 + NumReservedValues, NameStr);
+  }
+  explicit LandingPadInst(Type *RetTy, Value *PersonalityFn,
+                          unsigned NumReservedValues, const Twine &NameStr,
+                          BasicBlock *InsertAtEnd)
+    : Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertAtEnd),
+      IsCleanup(false) {
+    init(PersonalityFn, 1 + NumReservedValues, NameStr);
+  }
+protected:
+  virtual LandingPadInst *clone_impl() const;
+public:
+  static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn,
+                                unsigned NumReservedValues,
+                                const Twine &NameStr = "",
+                                Instruction *InsertBefore = 0) {
+    return new LandingPadInst(RetTy, PersonalityFn, NumReservedValues, NameStr,
+                              InsertBefore);
+  }
+  static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn,
+                                unsigned NumReservedValues,
+                                const Twine &NameStr, BasicBlock *InsertAtEnd) {
+    return new LandingPadInst(RetTy, PersonalityFn, NumReservedValues, NameStr,
+                              InsertAtEnd);
+  }
+  ~LandingPadInst();
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  /// getPersonalityFn - Get the personality function associated with this
+  /// landing pad.
+  const Value *getPersonalityFn() const { return getOperand(0); }
+
+  // Simple accessors.
+  bool isCleanup() const { return IsCleanup; }
+  void setCleanup(bool Val) { IsCleanup = Val; }
+
+  /// addClause - Add a clause to the landing pad.
+  void addClause(ClauseType CT, Value *ClauseVal);
+
+  /// getClauseType - Return the type of the clause at this index. The two
+  /// supported clauses are Catch and Filter.
+  ClauseType getClauseType(unsigned I) const {
+    assert(I < ClauseIdxs.size() && "Index too large!");
+    return ClauseIdxs[I];
+  }
+
+  /// getClauseValue - Return the value of the clause at this index.
+  Value *getClauseValue(unsigned I) const {
+    assert(I + 1 < getNumOperands() && "Index too large!");
+    return OperandList[I + 1];
+  }
+
+  /// getNumClauses - Get the number of clauses for this landing pad.
+  unsigned getNumClauses() const { return getNumOperands() - 1; }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const LandingPadInst *) { return true; }
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::LandingPad;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+template <>
+struct OperandTraits<LandingPadInst> : public HungoffOperandTraits<2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(LandingPadInst, Value)
 
 //===----------------------------------------------------------------------===//
 //                               ReturnInst Class
@@ -2463,6 +2573,59 @@
 };
 
 //===----------------------------------------------------------------------===//
+//                              ResumeInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// ResumeInst - Resume the propagation of an exception.
+///
+class ResumeInst : public TerminatorInst {
+  ResumeInst(const ResumeInst &RI);
+
+  explicit ResumeInst(LLVMContext &C, Value *Exn, Instruction *InsertBefore=0);
+  ResumeInst(LLVMContext &C, Value *Exn, BasicBlock *InsertAtEnd);
+protected:
+  virtual ResumeInst *clone_impl() const;
+public:
+  static ResumeInst *Create(LLVMContext &C, Value *Exn,
+                            Instruction *InsertBefore = 0) {
+    return new(1) ResumeInst(C, Exn, InsertBefore);
+  }
+  static ResumeInst *Create(LLVMContext &C, Value *Exn,
+                            BasicBlock *InsertAtEnd) {
+    return new(1) ResumeInst(C, Exn, InsertAtEnd);
+  }
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  /// Convenience accessor.
+  Value *getResumeValue() const { return Op<0>(); }
+
+  unsigned getNumSuccessors() const { return 0; }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const ResumeInst *) { return true; }
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::Resume;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+private:
+  virtual BasicBlock *getSuccessorV(unsigned idx) const;
+  virtual unsigned getNumSuccessorsV() const;
+  virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+};
+
+template <>
+struct OperandTraits<ResumeInst> :
+    public FixedNumOperandTraits<ResumeInst, 1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
+
+//===----------------------------------------------------------------------===//
 //                           UnreachableInst Class
 //===----------------------------------------------------------------------===//
 

Modified: llvm/trunk/include/llvm/Support/IRBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IRBuilder.h?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/IRBuilder.h (original)
+++ llvm/trunk/include/llvm/Support/IRBuilder.h Wed Jul 27 15:18:04 2011
@@ -479,6 +479,10 @@
     return Insert(new UnwindInst(Context));
   }
 
+  ResumeInst *CreateResume(Value *Exn) {
+    return Insert(ResumeInst::Create(Context, Exn));
+  }
+
   UnreachableInst *CreateUnreachable() {
     return Insert(new UnreachableInst(Context));
   }
@@ -1194,6 +1198,11 @@
     return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name);
   }
 
+  Value *CreateLandingPad(Type *Ty, Value *PersFn, unsigned NumClauses,
+                          const Twine &Name = "") {
+    return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses, Name));
+  }
+
   //===--------------------------------------------------------------------===//
   // Utility creation methods
   //===--------------------------------------------------------------------===//

Modified: llvm/trunk/include/llvm/Support/InstVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/InstVisitor.h?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/InstVisitor.h (original)
+++ llvm/trunk/include/llvm/Support/InstVisitor.h Wed Jul 27 15:18:04 2011
@@ -163,6 +163,7 @@
   RetTy visitIndirectBrInst(IndirectBrInst &I)      { DELEGATE(TerminatorInst);}
   RetTy visitInvokeInst(InvokeInst &I)              { DELEGATE(TerminatorInst);}
   RetTy visitUnwindInst(UnwindInst &I)              { DELEGATE(TerminatorInst);}
+  RetTy visitResumeInst(ResumeInst &I)              { DELEGATE(TerminatorInst);}
   RetTy visitUnreachableInst(UnreachableInst &I)    { DELEGATE(TerminatorInst);}
   RetTy visitICmpInst(ICmpInst &I)                  { DELEGATE(CmpInst);}
   RetTy visitFCmpInst(FCmpInst &I)                  { DELEGATE(CmpInst);}
@@ -192,6 +193,7 @@
   RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); }
   RetTy visitExtractValueInst(ExtractValueInst &I)  { DELEGATE(Instruction);}
   RetTy visitInsertValueInst(InsertValueInst &I)    { DELEGATE(Instruction); }
+  RetTy visitLandingPadInst(LandingPadInst &I)      { DELEGATE(Instruction); }
 
   // Next level propagators: If the user does not overload a specific
   // instruction type, they can overload one of these to get the whole class

Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Wed Jul 27 15:18:04 2011
@@ -581,6 +581,11 @@
 
   KEYWORD(x);
   KEYWORD(blockaddress);
+
+  KEYWORD(personality);
+  KEYWORD(cleanup);
+  KEYWORD(catch);
+  KEYWORD(filter);
 #undef KEYWORD
 
   // Keywords for types.
@@ -633,6 +638,7 @@
   INSTKEYWORD(switch,      Switch);
   INSTKEYWORD(indirectbr,  IndirectBr);
   INSTKEYWORD(invoke,      Invoke);
+  INSTKEYWORD(resume,      Resume);
   INSTKEYWORD(unwind,      Unwind);
   INSTKEYWORD(unreachable, Unreachable);
 
@@ -647,6 +653,7 @@
   INSTKEYWORD(shufflevector,  ShuffleVector);
   INSTKEYWORD(extractvalue,   ExtractValue);
   INSTKEYWORD(insertvalue,    InsertValue);
+  INSTKEYWORD(landingpad,     LandingPad);
 #undef INSTKEYWORD
 
   // Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by
@@ -674,7 +681,6 @@
   return lltok::Error;
 }
 
-
 /// Lex0x: Handle productions that start with 0x, knowing that it matches and
 /// that this is not a label:
 ///    HexFPConstant     0x[0-9A-Fa-f]+

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Wed Jul 27 15:18:04 2011
@@ -2885,6 +2885,7 @@
   case lltok::kw_switch:      return ParseSwitch(Inst, PFS);
   case lltok::kw_indirectbr:  return ParseIndirectBr(Inst, PFS);
   case lltok::kw_invoke:      return ParseInvoke(Inst, PFS);
+  case lltok::kw_resume:      return ParseResume(Inst, PFS);
   // Binary Operators.
   case lltok::kw_add:
   case lltok::kw_sub:
@@ -2944,6 +2945,7 @@
   case lltok::kw_insertelement:  return ParseInsertElement(Inst, PFS);
   case lltok::kw_shufflevector:  return ParseShuffleVector(Inst, PFS);
   case lltok::kw_phi:            return ParsePHI(Inst, PFS);
+  case lltok::kw_landingpad:     return ParseLandingPad(Inst, PFS);
   case lltok::kw_call:           return ParseCall(Inst, PFS, false);
   case lltok::kw_tail:           return ParseCall(Inst, PFS, true);
   // Memory.
@@ -3247,7 +3249,18 @@
   return false;
 }
 
+/// ParseResume
+///   ::= 'resume' TypeAndValue
+bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) {
+  Value *Exn; LocTy ExnLoc;
+  LocTy Loc = Lex.getLoc();
+  if (ParseTypeAndValue(Exn, ExnLoc, PFS))
+    return true;
 
+  ResumeInst *RI = ResumeInst::Create(Context, Exn);
+  Inst = RI;
+  return false;
+}
 
 //===----------------------------------------------------------------------===//
 // Binary Operators.
@@ -3495,6 +3508,56 @@
   return AteExtraComma ? InstExtraComma : InstNormal;
 }
 
+/// ParseLandingPad
+///   ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'?
+///       (ClauseID ClauseList)+
+/// ClauseID
+///   ::= 'catch'
+///   ::= 'filter'
+/// ClauseList
+///   ::= TypeAndValue (',' TypeAndValue)*
+bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
+  Type *Ty = 0; LocTy TyLoc;
+  Value *PersFn; LocTy PersFnLoc;
+  LocTy LPLoc = Lex.getLoc();
+
+  if (ParseType(Ty, TyLoc) ||
+      ParseToken(lltok::kw_personality, "expected 'personality'") ||
+      ParseTypeAndValue(PersFn, PersFnLoc, PFS))
+    return true;
+
+  bool IsCleanup = EatIfPresent(lltok::kw_cleanup);
+
+  SmallVector<std::pair<LandingPadInst::ClauseType, Value*>, 16> Clauses;
+  while (Lex.getKind() == lltok::kw_catch || Lex.getKind() == lltok::kw_filter){
+    LandingPadInst::ClauseType CT;
+    if (Lex.getKind() == lltok::kw_catch) {
+      CT = LandingPadInst::Catch;
+      ParseToken(lltok::kw_catch, "expected 'catch'");
+    } else {
+      CT = LandingPadInst::Filter;
+      ParseToken(lltok::kw_filter, "expected 'filter'");
+    }
+
+    do {
+      Value *V; LocTy VLoc;
+      if (ParseTypeAndValue(V, VLoc, PFS))
+        return true;
+      Clauses.push_back(std::make_pair(CT, V));
+    } while (EatIfPresent(lltok::comma));
+  }
+
+  LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, Clauses.size());
+  LP->setCleanup(IsCleanup);
+
+  for (SmallVectorImpl<std::pair<LandingPadInst::ClauseType, Value*> >::iterator
+         I = Clauses.begin(), E = Clauses.end(); I != E; ++I)
+    LP->addClause(I->first, I->second);
+
+  Inst = LP;
+  return false;
+}
+
 /// ParseCall
 ///   ::= 'tail'? 'call' OptionalCallingConv OptionalAttrs Type Value
 ///       ParameterList OptionalAttrs

Modified: llvm/trunk/lib/AsmParser/LLParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.h (original)
+++ llvm/trunk/lib/AsmParser/LLParser.h Wed Jul 27 15:18:04 2011
@@ -347,6 +347,7 @@
     bool ParseSwitch(Instruction *&Inst, PerFunctionState &PFS);
     bool ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS);
     bool ParseInvoke(Instruction *&Inst, PerFunctionState &PFS);
+    bool ParseResume(Instruction *&Inst, PerFunctionState &PFS);
 
     bool ParseArithmetic(Instruction *&I, PerFunctionState &PFS, unsigned Opc,
                          unsigned OperandType);
@@ -359,6 +360,7 @@
     bool ParseInsertElement(Instruction *&I, PerFunctionState &PFS);
     bool ParseShuffleVector(Instruction *&I, PerFunctionState &PFS);
     int ParsePHI(Instruction *&I, PerFunctionState &PFS);
+    bool ParseLandingPad(Instruction *&I, PerFunctionState &PFS);
     bool ParseCall(Instruction *&I, PerFunctionState &PFS, bool isTail);
     int ParseAlloc(Instruction *&I, PerFunctionState &PFS);
     int ParseLoad(Instruction *&I, PerFunctionState &PFS, bool isVolatile);

Modified: llvm/trunk/lib/AsmParser/LLToken.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLToken.h (original)
+++ llvm/trunk/lib/AsmParser/LLToken.h Wed Jul 27 15:18:04 2011
@@ -121,7 +121,9 @@
     kw_fptoui, kw_fptosi, kw_inttoptr, kw_ptrtoint, kw_bitcast,
     kw_select, kw_va_arg,
 
-    kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_unwind,
+    kw_landingpad, kw_personality, kw_cleanup, kw_catch, kw_filter,
+
+    kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_unwind, kw_resume,
     kw_unreachable,
 
     kw_alloca, kw_load, kw_store, kw_fence, kw_getelementptr,
@@ -143,8 +145,8 @@
     // Type valued tokens (TyVal).
     Type,
 
-    APFloat,  // APFloatVal
-    APSInt // APSInt
+    APFloat,           // APFloatVal
+    APSInt             // APSInt
   };
 } // end namespace lltok
 } // end namespace llvm

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Wed Jul 27 15:18:04 2011
@@ -2491,6 +2491,14 @@
       cast<InvokeInst>(I)->setAttributes(PAL);
       break;
     }
+    case bitc::FUNC_CODE_INST_RESUME: { // RESUME: [opval]
+      unsigned Idx = 0;
+      Value *Val = 0;
+      if (getValueTypePair(Record, Idx, NextValueNo, Val))
+        return Error("Invalid RESUME record");
+      I = ResumeInst::Create(Context, Val);
+      break;
+    }
     case bitc::FUNC_CODE_INST_UNWIND: // UNWIND
       I = new UnwindInst(Context);
       InstructionList.push_back(I);
@@ -2518,6 +2526,37 @@
       break;
     }
 
+    case bitc::FUNC_CODE_INST_LANDINGPAD: {
+      // LANDINGPAD: [ty, val, val, num, (id0,val0 ...)?]
+      unsigned Idx = 0;
+      if (Record.size() < 4)
+        return Error("Invalid LANDINGPAD record");
+      Type *Ty = getTypeByID(Record[Idx++]);
+      if (!Ty) return Error("Invalid LANDINGPAD record");
+      Value *PersFn = 0;
+      if (getValueTypePair(Record, Idx, NextValueNo, PersFn))
+        return Error("Invalid LANDINGPAD record");
+
+      bool IsCleanup = !!Record[Idx++];
+      unsigned NumClauses = Record[Idx++];
+      LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, NumClauses);
+      LP->setCleanup(IsCleanup);
+      for (unsigned J = 0; J != NumClauses; ++J) {
+        LandingPadInst::ClauseType CT =
+          LandingPadInst::ClauseType(Record[Idx++]);
+        Value *Val = 0;
+        if (getValueTypePair(Record, Idx, NextValueNo, Val)) {
+          delete LP;
+          return Error("Invalid LANDINGPAD record");
+        }
+
+        LP->addClause(CT, Val);
+      }
+
+      I = LP;
+      break;
+    }
+
     case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align]
       if (Record.size() != 4)
         return Error("Invalid ALLOCA record");

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Wed Jul 27 15:18:04 2011
@@ -1126,6 +1126,10 @@
     }
     break;
   }
+  case Instruction::Resume:
+    Code = bitc::FUNC_CODE_INST_RESUME;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    break;
   case Instruction::Unwind:
     Code = bitc::FUNC_CODE_INST_UNWIND;
     break;
@@ -1145,6 +1149,20 @@
     break;
   }
 
+  case Instruction::LandingPad: {
+    const LandingPadInst &LP = cast<LandingPadInst>(I);
+    Code = bitc::FUNC_CODE_INST_LANDINGPAD;
+    Vals.push_back(VE.getTypeID(LP.getType()));
+    PushValueAndType(LP.getPersonalityFn(), InstID, Vals, VE);
+    Vals.push_back(LP.isCleanup());
+    Vals.push_back(LP.getNumClauses());
+    for (unsigned I = 0, E = LP.getNumClauses(); I != E; ++I) {
+      Vals.push_back(LP.getClauseType(I));
+      PushValueAndType(LP.getClauseValue(I), InstID, Vals, VE);
+    }
+    break;
+  }
+
   case Instruction::Alloca:
     Code = bitc::FUNC_CODE_INST_ALLOCA;
     Vals.push_back(VE.getTypeID(I.getType()));

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Jul 27 15:18:04 2011
@@ -914,6 +914,10 @@
   llvm_unreachable("SelectionDAGBuilder shouldn't visit PHI nodes!");
 }
 
+void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &) {
+  // FIXME: Handle this
+}
+
 void SelectionDAGBuilder::visit(unsigned Opcode, const User &I) {
   // Note: this doesn't use InstVisitor, because it has to work with
   // ConstantExpr's in addition to instructions.
@@ -1808,6 +1812,10 @@
 void SelectionDAGBuilder::visitUnwind(const UnwindInst &I) {
 }
 
+void SelectionDAGBuilder::visitResume(const ResumeInst &RI) {
+  // FIXME: Handle this
+}
+
 /// handleSmallSwitchCaseRange - Emit a series of specific tests (suitable for
 /// small case ranges).
 bool SelectionDAGBuilder::handleSmallSwitchRange(CaseRec& CR,

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h Wed Jul 27 15:18:04 2011
@@ -453,6 +453,7 @@
 private:
   // These all get lowered before this pass.
   void visitInvoke(const InvokeInst &I);
+  void visitResume(const ResumeInst &I);
   void visitUnwind(const UnwindInst &I);
 
   void visitBinary(const User &I, unsigned OpCode);
@@ -497,6 +498,7 @@
 
   void visitExtractValue(const ExtractValueInst &I);
   void visitInsertValue(const InsertValueInst &I);
+  void visitLandingPad(const LandingPadInst &I);
 
   void visitGetElementPtr(const User &I);
   void visitSelect(const User &I);

Modified: llvm/trunk/lib/CodeGen/ShadowStackGC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ShadowStackGC.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ShadowStackGC.cpp (original)
+++ llvm/trunk/lib/CodeGen/ShadowStackGC.cpp Wed Jul 27 15:18:04 2011
@@ -113,9 +113,11 @@
         while (StateBB != StateE) {
           BasicBlock *CurBB = StateBB++;
 
-          // Branches and invokes do not escape, only unwind and return do.
+          // Branches and invokes do not escape, only unwind, resume, and return
+          // do.
           TerminatorInst *TI = CurBB->getTerminator();
-          if (!isa<UnwindInst>(TI) && !isa<ReturnInst>(TI))
+          if (!isa<UnwindInst>(TI) && !isa<ReturnInst>(TI) &&
+              !isa<ResumeInst>(TI))
             continue;
 
           Builder.SetInsertPoint(TI->getParent(), TI);

Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original)
+++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Wed Jul 27 15:18:04 2011
@@ -288,10 +288,12 @@
     void visitInvokeInst(InvokeInst &I) {
       llvm_unreachable("Lowerinvoke pass didn't work!");
     }
-
     void visitUnwindInst(UnwindInst &I) {
       llvm_unreachable("Lowerinvoke pass didn't work!");
     }
+    void visitResumeInst(ResumeInst &I) {
+      llvm_unreachable("Lowerinvoke pass didn't work!");
+    }
     void visitUnreachableInst(UnreachableInst &I);
 
     void visitPHINode(PHINode &I);

Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original)
+++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Wed Jul 27 15:18:04 2011
@@ -1064,6 +1064,11 @@
     }
     break;
   }
+  case Instruction::Resume: {
+    Out << "ResumeInst::Create(mod->getContext(), " << opNames[0]
+        << ", " << bbname << ");";
+    break;
+  }
   case Instruction::Invoke: {
     const InvokeInst* inv = cast<InvokeInst>(I);
     Out << "std::vector<Value*> " << iName << "_params;";
@@ -1423,6 +1428,9 @@
     Out << "\", " << bbname << ");";
     break;
   }
+  case Instruction::LandingPad: {
+    break;
+  }
   }
   DefinedValues.insert(I);
   nl(Out);

Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Wed Jul 27 15:18:04 2011
@@ -2506,7 +2506,7 @@
         CallStack.pop_back();  // return from fn.
         return true;  // We succeeded at evaluating this ctor!
       } else {
-        // invoke, unwind, unreachable.
+        // invoke, unwind, resume, unreachable.
         return false;  // Cannot handle this terminator.
       }
 

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Wed Jul 27 15:18:04 2011
@@ -732,9 +732,11 @@
       }
     }
     
-    // If the stack restore is in a return/unwind block and if there are no
-    // allocas or calls between the restore and the return, nuke the restore.
-    if (!CannotRemove && (isa<ReturnInst>(TI) || isa<UnwindInst>(TI)))
+    // If the stack restore is in a return, resume, or unwind block and if there
+    // are no allocas or calls between the restore and the return, nuke the
+    // restore.
+    if (!CannotRemove && (isa<ReturnInst>(TI) || isa<ResumeInst>(TI) ||
+                          isa<UnwindInst>(TI)))
       return EraseInstFromFunction(CI);
     break;
   }

Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Wed Jul 27 15:18:04 2011
@@ -515,6 +515,7 @@
   void visitShuffleVectorInst(ShuffleVectorInst &I);
   void visitExtractValueInst(ExtractValueInst &EVI);
   void visitInsertValueInst(InsertValueInst &IVI);
+  void visitLandingPadInst(LandingPadInst &I) { markAnythingOverdefined(&I); }
 
   // Instructions that cannot be folded away.
   void visitStoreInst     (StoreInst &I);
@@ -528,6 +529,7 @@
     visitTerminatorInst(II);
   }
   void visitCallSite      (CallSite CS);
+  void visitResumeInst    (TerminatorInst &I) { /*returns void*/ }
   void visitUnwindInst    (TerminatorInst &I) { /*returns void*/ }
   void visitUnreachableInst(TerminatorInst &I) { /*returns void*/ }
   void visitFenceInst     (FenceInst &I) { /*returns void*/ }

Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/AsmWriter.cpp (original)
+++ llvm/trunk/lib/VMCore/AsmWriter.cpp Wed Jul 27 15:18:04 2011
@@ -1710,6 +1710,9 @@
       writeOperand(I.getOperand(i), true);
     }
     Out << ']';
+  } else if (isa<ResumeInst>(I)) {
+    Out << ' ';
+    writeOperand(Operand, true);
   } else if (const PHINode *PN = dyn_cast<PHINode>(&I)) {
     Out << ' ';
     TypePrinter.print(I.getType(), Out);
@@ -1732,6 +1735,33 @@
     writeOperand(I.getOperand(1), true);
     for (const unsigned *i = IVI->idx_begin(), *e = IVI->idx_end(); i != e; ++i)
       Out << ", " << *i;
+  } else if (const LandingPadInst *LPI = dyn_cast<LandingPadInst>(&I)) {
+    Out << ' ';
+    TypePrinter.print(I.getType(), Out);
+    Out << " personality ";
+    writeOperand(LPI->getPersonalityFn(), true); Out << '\n';
+
+    if (LPI->isCleanup())
+      Out << "          cleanup";
+
+    for (unsigned i = 0, e = LPI->getNumClauses(); i != e; ) {
+      if (i != 0 || LPI->isCleanup()) Out << "\n";
+
+      SmallVector<const Value*, 8> Vals;
+      LandingPadInst::ClauseType CT = LPI->getClauseType(i);
+      for (; i != e && LPI->getClauseType(i) == CT; ++i)
+        Vals.push_back(LPI->getClauseValue(i));
+
+      if (CT == LandingPadInst::Catch)
+        Out << "          catch ";
+      else
+        Out << "          filter ";
+
+      for (unsigned II = 0, IE = Vals.size(); II != IE; ++II) {
+        if (II != 0) Out << ", ";
+        writeOperand(Vals[II], true);
+      }
+    }
   } else if (isa<ReturnInst>(I) && !Operand) {
     Out << " void";
   } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {

Modified: llvm/trunk/lib/VMCore/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Core.cpp (original)
+++ llvm/trunk/lib/VMCore/Core.cpp Wed Jul 27 15:18:04 2011
@@ -1683,10 +1683,21 @@
                                       Name));
 }
 
+LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty,
+                                 LLVMValueRef PersFn, unsigned NumClauses,
+                                 const char *Name) {
+  return wrap(unwrap(B)->CreateLandingPad(unwrap(Ty), unwrap(PersFn),
+                                          NumClauses, Name));
+}
+
 LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef B) {
   return wrap(unwrap(B)->CreateUnwind());
 }
 
+LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn) {
+  return wrap(unwrap(B)->CreateResume(unwrap(Exn)));
+}
+
 LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef B) {
   return wrap(unwrap(B)->CreateUnreachable());
 }
@@ -1700,6 +1711,17 @@
   unwrap<IndirectBrInst>(IndirectBr)->addDestination(unwrap(Dest));
 }
 
+void LLVMAddClause(LLVMValueRef LandingPad, LLVMLandingPadClauseTy ClauseTy,
+                   LLVMValueRef ClauseVal) {
+  unwrap<LandingPadInst>(LandingPad)->
+    addClause(static_cast<LandingPadInst::ClauseType>(ClauseTy),
+              unwrap(ClauseVal));
+}
+
+void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val) {
+  unwrap<LandingPadInst>(LandingPad)->setCleanup(Val);
+}
+
 /*--.. Arithmetic ..........................................................--*/
 
 LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,

Modified: llvm/trunk/lib/VMCore/Instruction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Instruction.cpp (original)
+++ llvm/trunk/lib/VMCore/Instruction.cpp Wed Jul 27 15:18:04 2011
@@ -101,6 +101,7 @@
   case Switch: return "switch";
   case IndirectBr: return "indirectbr";
   case Invoke: return "invoke";
+  case Resume: return "resume";
   case Unwind: return "unwind";
   case Unreachable: return "unreachable";
 
@@ -159,6 +160,7 @@
   case ShuffleVector:  return "shufflevector";
   case ExtractValue:   return "extractvalue";
   case InsertValue:    return "insertvalue";
+  case LandingPad:     return "landingpad";
 
   default: return "<Invalid operator> ";
   }

Modified: llvm/trunk/lib/VMCore/Instructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Instructions.cpp (original)
+++ llvm/trunk/lib/VMCore/Instructions.cpp Wed Jul 27 15:18:04 2011
@@ -166,6 +166,63 @@
   return ConstantValue;
 }
 
+//===----------------------------------------------------------------------===//
+//                       LandingPadInst Implementation
+//===----------------------------------------------------------------------===//
+
+void LandingPadInst::init(Value *PersFn, unsigned NumReservedValues,
+                          const Twine &NameStr) {
+  ReservedSpace = NumReservedValues;
+  NumOperands = 1;
+  OperandList = allocHungoffUses(ReservedSpace);
+  OperandList[0] = PersFn;
+  setName(NameStr);
+}
+
+LandingPadInst::LandingPadInst(const LandingPadInst &LP)
+  : Instruction(LP.getType(), Instruction::LandingPad,
+                allocHungoffUses(LP.getNumOperands()), LP.getNumOperands()),
+    ReservedSpace(LP.getNumOperands()) {
+  Use *OL = OperandList, *InOL = LP.OperandList;
+  for (unsigned I = 0, E = ReservedSpace; I != E; ++I)
+    OL[I] = InOL[I];
+
+  for (SmallVectorImpl<ClauseType>::const_iterator
+         I = LP.ClauseIdxs.begin(), E = LP.ClauseIdxs.end(); I != E; ++I)
+    ClauseIdxs.push_back(*I);
+
+  IsCleanup = LP.IsCleanup;
+  SubclassOptionalData = LP.SubclassOptionalData;
+}
+
+LandingPadInst::~LandingPadInst() {
+  dropHungoffUses();
+}
+
+/// growOperands - grow operands - This grows the operand list in response to a
+/// push_back style of operation. This grows the number of ops by 2 times.
+void LandingPadInst::growOperands() {
+  unsigned e = getNumOperands();
+  ReservedSpace = e * 2;
+
+  Use *NewOps = allocHungoffUses(ReservedSpace);
+  Use *OldOps = OperandList;
+  for (unsigned i = 0; i != e; ++i)
+      NewOps[i] = OldOps[i];
+
+  OperandList = NewOps;
+  Use::zap(OldOps, OldOps + e, true);
+}
+
+void LandingPadInst::addClause(ClauseType CT, Value *ClauseVal) {
+  unsigned OpNo = getNumOperands();
+  if (OpNo + 1 > ReservedSpace)
+    growOperands();
+  assert(OpNo < ReservedSpace && "Growing didn't work!");
+  ClauseIdxs.push_back(CT);
+  ++NumOperands;
+  OperandList[OpNo] = ClauseVal;
+}
 
 //===----------------------------------------------------------------------===//
 //                        CallInst Implementation
@@ -574,6 +631,42 @@
 }
 
 //===----------------------------------------------------------------------===//
+//                        ResumeInst Implementation
+//===----------------------------------------------------------------------===//
+
+ResumeInst::ResumeInst(const ResumeInst &RI)
+  : TerminatorInst(Type::getVoidTy(RI.getContext()), Instruction::Resume,
+                   OperandTraits<ResumeInst>::op_begin(this), 1) {
+  Op<0>() = RI.Op<0>();
+  SubclassOptionalData = RI.SubclassOptionalData;
+}
+
+ResumeInst::ResumeInst(LLVMContext &C, Value *Exn, Instruction *InsertBefore)
+  : TerminatorInst(Type::getVoidTy(C), Instruction::Resume,
+                   OperandTraits<ResumeInst>::op_begin(this), 1, InsertBefore) {
+  Op<0>() = Exn;
+}
+
+ResumeInst::ResumeInst(LLVMContext &C, Value *Exn, BasicBlock *InsertAtEnd)
+  : TerminatorInst(Type::getVoidTy(C), Instruction::Resume,
+                   OperandTraits<ResumeInst>::op_begin(this), 1, InsertAtEnd) {
+  Op<0>() = Exn;
+}
+
+unsigned ResumeInst::getNumSuccessorsV() const {
+  return getNumSuccessors();
+}
+
+void ResumeInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
+  llvm_unreachable("ResumeInst has no successors!");
+}
+
+BasicBlock *ResumeInst::getSuccessorV(unsigned idx) const {
+  llvm_unreachable("ResumeInst has no successors!");
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
 //                      UnreachableInst Implementation
 //===----------------------------------------------------------------------===//
 
@@ -592,11 +685,11 @@
 }
 
 void UnreachableInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
-  llvm_unreachable("UnwindInst has no successors!");
+  llvm_unreachable("UnreachableInst has no successors!");
 }
 
 BasicBlock *UnreachableInst::getSuccessorV(unsigned idx) const {
-  llvm_unreachable("UnwindInst has no successors!");
+  llvm_unreachable("UnreachableInst has no successors!");
   return 0;
 }
 
@@ -3122,6 +3215,10 @@
   return new PHINode(*this);
 }
 
+LandingPadInst *LandingPadInst::clone_impl() const {
+  return new LandingPadInst(*this);
+}
+
 ReturnInst *ReturnInst::clone_impl() const {
   return new(getNumOperands()) ReturnInst(*this);
 }
@@ -3143,6 +3240,10 @@
   return new(getNumOperands()) InvokeInst(*this);
 }
 
+ResumeInst *ResumeInst::clone_impl() const {
+  return new(1) ResumeInst(*this);
+}
+
 UnwindInst *UnwindInst::clone_impl() const {
   LLVMContext &Context = getContext();
   return new UnwindInst(Context);

Modified: llvm/trunk/lib/VMCore/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=136253&r1=136252&r2=136253&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp (original)
+++ llvm/trunk/lib/VMCore/Verifier.cpp Wed Jul 27 15:18:04 2011
@@ -35,6 +35,12 @@
 //  * It is illegal to have a ret instruction that returns a value that does not
 //    agree with the function return value type.
 //  * Function call argument types match the function prototype
+//  * A landing pad is defined by a landingpad instruction, and can be jumped to
+//    only by the unwind edge of an invoke instruction.
+//  * A landingpad instruction must be the first non-PHI instruction in the
+//    block.
+//  * All landingpad instructions must use the same personality function with
+//    the same function.
 //  * All other things that are tested by asserts spread about the code...
 //
 //===----------------------------------------------------------------------===//
@@ -131,18 +137,22 @@
     /// already.
     SmallPtrSet<MDNode *, 32> MDNodes;
 
+    /// PersonalityFn - The personality function referenced by the
+    /// LandingPadInsts. All LandingPadInsts within the same function must use
+    /// the same personality function.
+    const Value *PersonalityFn;
+
     Verifier()
-      : FunctionPass(ID), 
-      Broken(false), RealPass(true), action(AbortProcessAction),
-      Mod(0), Context(0), DT(0), MessagesStr(Messages) {
-        initializeVerifierPass(*PassRegistry::getPassRegistry());
-      }
+      : FunctionPass(ID), Broken(false), RealPass(true),
+        action(AbortProcessAction), Mod(0), Context(0), DT(0),
+        MessagesStr(Messages), PersonalityFn(0) {
+      initializeVerifierPass(*PassRegistry::getPassRegistry());
+    }
     explicit Verifier(VerifierFailureAction ctn)
-      : FunctionPass(ID), 
-      Broken(false), RealPass(true), action(ctn), Mod(0), Context(0), DT(0),
-      MessagesStr(Messages) {
-        initializeVerifierPass(*PassRegistry::getPassRegistry());
-      }
+      : FunctionPass(ID), Broken(false), RealPass(true), action(ctn), Mod(0),
+        Context(0), DT(0), MessagesStr(Messages), PersonalityFn(0) {
+      initializeVerifierPass(*PassRegistry::getPassRegistry());
+    }
 
     bool doInitialization(Module &M) {
       Mod = &M;
@@ -282,6 +292,7 @@
     void visitAllocaInst(AllocaInst &AI);
     void visitExtractValueInst(ExtractValueInst &EVI);
     void visitInsertValueInst(InsertValueInst &IVI);
+    void visitLandingPadInst(LandingPadInst &LPI);
 
     void VerifyCallSite(CallSite CS);
     bool PerformTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty,
@@ -1321,7 +1332,7 @@
   Assert1(Ordering == Acquire || Ordering == Release ||
           Ordering == AcquireRelease || Ordering == SequentiallyConsistent,
           "fence instructions may only have "
-          " acquire, release, acq_rel, or seq_cst ordering.", &FI);
+          "acquire, release, acq_rel, or seq_cst ordering.", &FI);
   visitInstruction(FI);
 }
 
@@ -1343,6 +1354,42 @@
   visitInstruction(IVI);
 }
 
+void Verifier::visitLandingPadInst(LandingPadInst &LPI) {
+  BasicBlock *BB = LPI.getParent();
+
+  // The landingpad instruction is ill-formed if it doesn't have any clauses and
+  // isn't a cleanup.
+  Assert1(LPI.getNumClauses() > 0 || LPI.isCleanup(),
+          "LandingPadInst needs at least one clause or to be a cleanup.", &LPI);
+
+  // The landingpad instruction defines its parent as a landing pad block. The
+  // landing pad block may be branched to only by the unwind edge of an invoke.
+  for (pred_iterator I = pred_begin(BB), E = pred_end(BB); I != E; ++I) {
+    const InvokeInst *II = dyn_cast<InvokeInst>((*I)->getTerminator());
+    Assert1(II && II->getUnwindDest() == BB,
+            "Block containing LandingPadInst must be jumped to "
+            "only by the unwind edge of an invoke.", &LPI);
+  }
+
+  // The landingpad instruction must be the first non-PHI instruction in the
+  // block.
+  BasicBlock::iterator I = BB->begin(), E = BB->end();
+  while (I != E && isa<PHINode>(I))
+    ++I;
+  Assert1(I != E && isa<LandingPadInst>(I) && I == LPI,
+          "LandingPadInst not the first non-PHI instruction in the block.",
+          &LPI);
+
+  // The personality functions for all landingpad instructions within the same
+  // function should match.
+  if (PersonalityFn)
+    Assert1(LPI.getPersonalityFn() == PersonalityFn,
+            "Personality function doesn't match others in function", &LPI);
+  PersonalityFn = LPI.getPersonalityFn();
+
+  visitInstruction(LPI);
+}
+
 /// verifyInstruction - Verify that an instruction is well formed.
 ///
 void Verifier::visitInstruction(Instruction &I) {

Added: llvm/trunk/test/Feature/exceptionhandling.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/exceptionhandling.ll?rev=136253&view=auto
==============================================================================
--- llvm/trunk/test/Feature/exceptionhandling.ll (added)
+++ llvm/trunk/test/Feature/exceptionhandling.ll Wed Jul 27 15:18:04 2011
@@ -0,0 +1,54 @@
+; RUN: llvm-as < %s | llvm-dis > %t1.ll
+; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll
+; RUN: diff %t1.ll %t2.ll
+
+ at _ZTIc = external constant i8*
+ at _ZTId = external constant i8*
+ at _ZTIPKc = external constant i8*
+ at .str = private unnamed_addr constant [16 x i8] c"caught char %c\0A\00", align 1
+
+define void @_Z3barv() uwtable optsize alwaysinline ssp {
+entry:
+  invoke void @_Z3quxv() optsize
+          to label %try.cont unwind label %lpad
+
+invoke.cont4:                                     ; preds = %lpad
+  %eh.obj = extractvalue {i8*, i32} %exn, 0
+  %tmp0 = tail call i8* @__cxa_begin_catch(i8* %eh.obj) nounwind
+  %exn.scalar = load i8* %tmp0, align 1
+  %conv = sext i8 %exn.scalar to i32
+  %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([16 x i8]* @.str, i64 0, i64 0), i32 %conv) optsize
+  tail call void @__cxa_end_catch() nounwind
+  br label %try.cont
+
+try.cont:                                         ; preds = %entry, %invoke.cont4
+  ret void
+
+lpad:                                             ; preds = %entry
+  %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+            cleanup
+            catch i8** @_ZTIc
+            filter i8** @_ZTIPKc
+            catch i8** @_ZTId
+  %tmp1 = extractvalue {i8*, i32} %exn, 1
+  %tmp2 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIc to i8*)) nounwind
+  %tmp3 = icmp eq i32 %tmp1, %tmp2
+  br i1 %tmp3, label %invoke.cont4, label %eh.resume
+
+eh.resume:
+  resume { i8*, i32 } %exn
+}
+
+declare void @_Z3quxv() optsize
+
+declare i32 @__gxx_personality_v0(...)
+
+declare i32 @llvm.eh.typeid.for(i8*) nounwind
+
+declare void @llvm.eh.resume(i8*, i32)
+
+declare i8* @__cxa_begin_catch(i8*)
+
+declare i32 @printf(i8* nocapture, ...) nounwind optsize
+
+declare void @__cxa_end_catch()





More information about the llvm-commits mailing list