Revert r136253, r136263, r136269, r136313, r136325, r136326, r136329, r136338,

r136339, r136341, r136369, r136387, r136392, r136396, r136429, r136430, r136444,
r136445, r136446, r136253 pending review.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136556 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling 2011-07-30 05:42:50 +00:00
parent efd7919618
commit 10c6d12a9f
31 changed files with 110 additions and 1034 deletions

View File

@ -124,7 +124,6 @@
<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>
@ -3024,14 +3023,13 @@ should not be exposed to source languages.</p>
control flow, not values (the one exception being the
'<a href="#i_invoke"><tt>invoke</tt></a>' instruction).</p>
<p>There are eight different terminator instructions: the
<p>There are seven 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, the
'<a href="#i_resume"><tt>resume</tt></a>' instruction, and the
'<a href="#i_unwind"><tt>unwind</tt></a>' instruction, and the
'<a href="#i_unreachable"><tt>unreachable</tt></a>' instruction.</p>
<!-- _______________________________________________________________________ -->
@ -3354,35 +3352,6 @@ that the invoke/unwind semantics are likely to change in future versions.</p>
<!-- _______________________________________________________________________ -->
<h4>
<a name="i_resume">'<tt>resume</tt>' Instruction</a>
</h4>
<div>
<h5>Syntax:</h5>
<pre>
resume &lt;type&gt; &lt;value&gt;
</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>

View File

@ -188,11 +188,7 @@ typedef enum {
/* Atomic operators */
LLVMFence = 55,
LLVMAtomicCmpXchg = 56,
LLVMAtomicRMW = 57,
/* Exception Handling Operators */
LLVMLandingPad = 58,
LLVMResume = 59
LLVMAtomicRMW = 57
} LLVMOpcode;
@ -284,11 +280,6 @@ typedef enum {
LLVMRealPredicateTrue /**< Always true (always folded) */
} LLVMRealPredicate;
typedef enum {
LLVMCatch, /**< A catch clause */
LLVMFilter /**< A filter clause */
} LLVMLandingPadClauseTy;
void LLVMInitializeCore(LLVMPassRegistryRef R);
@ -475,7 +466,6 @@ LLVMTypeRef LLVMX86MMXType(void);
macro(GetElementPtrInst) \
macro(InsertElementInst) \
macro(InsertValueInst) \
macro(LandingPadInst) \
macro(PHINode) \
macro(SelectInst) \
macro(ShuffleVectorInst) \
@ -487,7 +477,6 @@ LLVMTypeRef LLVMX86MMXType(void);
macro(SwitchInst) \
macro(UnreachableInst) \
macro(UnwindInst) \
macro(ResumeInst) \
macro(UnaryInstruction) \
macro(AllocaInst) \
macro(CastInst) \
@ -836,7 +825,6 @@ LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn,
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 */
@ -846,13 +834,6 @@ void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal,
/* 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);

View File

@ -274,7 +274,7 @@ namespace bitc {
FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE
FUNC_CODE_INST_PHI = 16, // PHI: [ty, val0,bb0, ...]
FUNC_CODE_INST_RESUME = 17, // RESUME: [opval]
// 17 is unused.
// 18 is unused.
FUNC_CODE_INST_ALLOCA = 19, // ALLOCA: [instty, op, align]
FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol]
@ -302,13 +302,11 @@ namespace bitc {
FUNC_CODE_DEBUG_LOC = 35, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal]
FUNC_CODE_INST_FENCE = 36, // FENCE: [ordering, synchscope]
FUNC_CODE_INST_LANDINGPAD = 37, // LANDINGPAD: [ty,val,val,num,id0,val0...]
FUNC_CODE_INST_CMPXCHG = 38, // CMPXCHG: [ptrty,ptr,cmp,new, align, vol,
FUNC_CODE_INST_CMPXCHG = 37, // CMPXCHG: [ptrty,ptr,cmp,new, align, vol,
// ordering, synchscope]
FUNC_CODE_INST_ATOMICRMW = 39 // ATOMICRMW: [ptrty,ptr,val, operation,
FUNC_CODE_INST_ATOMICRMW = 38 // ATOMICRMW: [ptrty,ptr,val, operation,
// align, vol,
// ordering, synchscope]
};
} // End bitc namespace
} // End llvm namespace

View File

@ -220,11 +220,6 @@ void AddCatchInfo(const CallInst &I,
void CopyCatchInfo(const BasicBlock *SuccBB, const BasicBlock *LPad,
MachineModuleInfo *MMI, FunctionLoweringInfo &FLI);
/// AddLandingPadInfo - Extract the exception handling information from the
/// landingpad instruction and add them to the specified machine module info.
void AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI,
MachineBasicBlock *MBB);
} // end namespace llvm
#endif

View File

@ -100,80 +100,79 @@ HANDLE_TERM_INST ( 3, Switch , SwitchInst)
HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst)
HANDLE_TERM_INST ( 5, Invoke , InvokeInst)
HANDLE_TERM_INST ( 6, Unwind , UnwindInst)
HANDLE_TERM_INST ( 7, Resume , ResumeInst)
HANDLE_TERM_INST ( 8, Unreachable, UnreachableInst)
LAST_TERM_INST ( 8)
HANDLE_TERM_INST ( 7, Unreachable, UnreachableInst)
LAST_TERM_INST ( 7)
// Standard binary operators...
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)
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)
// Logical operators (integer operands)
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)
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)
// Memory operators...
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 )
HANDLE_MEMORY_INST(32, AtomicCmpXchg , AtomicCmpXchgInst )
HANDLE_MEMORY_INST(33, AtomicRMW , AtomicRMWInst )
LAST_MEMORY_INST(33)
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 )
HANDLE_MEMORY_INST(31, AtomicCmpXchg , AtomicCmpXchgInst )
HANDLE_MEMORY_INST(32, AtomicRMW , AtomicRMWInst )
LAST_MEMORY_INST(32)
// Cast operators ...
// NOTE: The order matters here because CastInst::isEliminableCastPair
// NOTE: (see Instructions.cpp) encodes a table based on this ordering.
FIRST_CAST_INST(34)
HANDLE_CAST_INST(34, Trunc , TruncInst ) // Truncate integers
HANDLE_CAST_INST(35, ZExt , ZExtInst ) // Zero extend integers
HANDLE_CAST_INST(36, SExt , SExtInst ) // Sign extend integers
HANDLE_CAST_INST(37, FPToUI , FPToUIInst ) // floating point -> UInt
HANDLE_CAST_INST(38, FPToSI , FPToSIInst ) // floating point -> SInt
HANDLE_CAST_INST(39, UIToFP , UIToFPInst ) // UInt -> floating point
HANDLE_CAST_INST(40, SIToFP , SIToFPInst ) // SInt -> floating point
HANDLE_CAST_INST(41, FPTrunc , FPTruncInst ) // Truncate floating point
HANDLE_CAST_INST(42, FPExt , FPExtInst ) // Extend floating point
HANDLE_CAST_INST(43, PtrToInt, PtrToIntInst) // Pointer -> Integer
HANDLE_CAST_INST(44, IntToPtr, IntToPtrInst) // Integer -> Pointer
HANDLE_CAST_INST(45, BitCast , BitCastInst ) // Type cast
LAST_CAST_INST(45)
FIRST_CAST_INST(33)
HANDLE_CAST_INST(33, Trunc , TruncInst ) // Truncate integers
HANDLE_CAST_INST(34, ZExt , ZExtInst ) // Zero extend integers
HANDLE_CAST_INST(35, SExt , SExtInst ) // Sign extend integers
HANDLE_CAST_INST(36, FPToUI , FPToUIInst ) // floating point -> UInt
HANDLE_CAST_INST(37, FPToSI , FPToSIInst ) // floating point -> SInt
HANDLE_CAST_INST(38, UIToFP , UIToFPInst ) // UInt -> floating point
HANDLE_CAST_INST(39, SIToFP , SIToFPInst ) // SInt -> floating point
HANDLE_CAST_INST(40, FPTrunc , FPTruncInst ) // Truncate floating point
HANDLE_CAST_INST(41, FPExt , FPExtInst ) // Extend floating point
HANDLE_CAST_INST(42, PtrToInt, PtrToIntInst) // Pointer -> Integer
HANDLE_CAST_INST(43, IntToPtr, IntToPtrInst) // Integer -> Pointer
HANDLE_CAST_INST(44, BitCast , BitCastInst ) // Type cast
LAST_CAST_INST(44)
// Other operators...
FIRST_OTHER_INST(46)
HANDLE_OTHER_INST(46, ICmp , ICmpInst ) // Integer comparison instruction
HANDLE_OTHER_INST(47, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(48, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(49, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(50, Select , SelectInst ) // select instruction
HANDLE_OTHER_INST(51, UserOp1, Instruction) // May be used internally in a pass
HANDLE_OTHER_INST(52, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(53, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(54, ExtractElement, ExtractElementInst)// extract from vector
HANDLE_OTHER_INST(55, InsertElement, InsertElementInst) // insert into vector
HANDLE_OTHER_INST(56, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
HANDLE_OTHER_INST(57, ExtractValue, ExtractValueInst)// extract from aggregate
HANDLE_OTHER_INST(58, InsertValue, InsertValueInst) // insert into aggregate
HANDLE_OTHER_INST(59, LandingPad, LandingPadInst) // Landing pad instruction.
LAST_OTHER_INST(59)
FIRST_OTHER_INST(45)
HANDLE_OTHER_INST(45, ICmp , ICmpInst ) // Integer comparison instruction
HANDLE_OTHER_INST(46, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(47, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(48, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(49, Select , SelectInst ) // select instruction
HANDLE_OTHER_INST(50, UserOp1, Instruction) // May be used internally in a pass
HANDLE_OTHER_INST(51, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(52, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(53, ExtractElement, ExtractElementInst)// extract from vector
HANDLE_OTHER_INST(54, InsertElement, InsertElementInst) // insert into vector
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)
#undef FIRST_TERM_INST
#undef HANDLE_TERM_INST

View File

@ -2028,122 +2028,6 @@ struct OperandTraits<PHINode> : public HungoffOperandTraits<2> {
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(Function *PersFn, unsigned NumReservedValues, const Twine &NameStr);
explicit LandingPadInst(Type *RetTy, Function *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, Function *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, Function *PersonalityFn,
unsigned NumReservedValues,
const Twine &NameStr = "",
Instruction *InsertBefore = 0) {
return new LandingPadInst(RetTy, PersonalityFn, NumReservedValues, NameStr,
InsertBefore);
}
static LandingPadInst *Create(Type *RetTy, Function *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 Function *getPersonalityFn() const {
return cast<Function>(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, Constant *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.
Constant *getClauseValue(unsigned I) const {
assert(I + 1 < getNumOperands() && "Index too large!");
return cast<Constant>(OperandList[I + 1]);
}
/// getNumClauses - Get the number of clauses for this landing pad.
unsigned getNumClauses() const { return getNumOperands() - 1; }
/// reserveClauses - Grow the size of the operand list to accomodate the new
/// number of clauses.
void reserveClauses(unsigned Size);
// 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
@ -2733,10 +2617,6 @@ public:
Op<-1>() = reinterpret_cast<Value*>(B);
}
// getLandingPad - Get the landingpad instruction from the landing pad block
// (the unwind destination).
LandingPadInst *getLandingPad() const;
BasicBlock *getSuccessor(unsigned i) const {
assert(i < 2 && "Successor # out of range for invoke!");
return i == 0 ? getNormalDest() : getUnwindDest();
@ -2835,59 +2715,6 @@ private:
virtual void setSuccessorV(unsigned idx, BasicBlock *B);
};
//===----------------------------------------------------------------------===//
// 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
//===----------------------------------------------------------------------===//

View File

@ -479,10 +479,6 @@ public:
return Insert(new UnwindInst(Context));
}
ResumeInst *CreateResume(Value *Exn) {
return Insert(ResumeInst::Create(Context, Exn));
}
UnreachableInst *CreateUnreachable() {
return Insert(new UnreachableInst(Context));
}
@ -1208,11 +1204,6 @@ public:
return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name);
}
Value *CreateLandingPad(Type *Ty, Function *PersFn, unsigned NumClauses,
const Twine &Name = "") {
return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses, Name));
}
//===--------------------------------------------------------------------===//
// Utility creation methods
//===--------------------------------------------------------------------===//

View File

@ -163,7 +163,6 @@ public:
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);}
@ -195,7 +194,6 @@ public:
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

View File

@ -584,11 +584,6 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(x);
KEYWORD(blockaddress);
KEYWORD(personality);
KEYWORD(cleanup);
KEYWORD(catch);
KEYWORD(filter);
#undef KEYWORD
// Keywords for types.
@ -641,7 +636,6 @@ lltok::Kind LLLexer::LexIdentifier() {
INSTKEYWORD(switch, Switch);
INSTKEYWORD(indirectbr, IndirectBr);
INSTKEYWORD(invoke, Invoke);
INSTKEYWORD(resume, Resume);
INSTKEYWORD(unwind, Unwind);
INSTKEYWORD(unreachable, Unreachable);
@ -658,7 +652,6 @@ lltok::Kind LLLexer::LexIdentifier() {
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
@ -686,6 +679,7 @@ lltok::Kind LLLexer::LexIdentifier() {
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]+

View File

@ -2885,7 +2885,6 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
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:
@ -2945,7 +2944,6 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
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.
@ -3255,18 +3253,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
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.
@ -3514,58 +3501,6 @@ int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) {
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, Constant*>, 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, cast<Constant>(V)));
} while (EatIfPresent(lltok::comma));
}
LandingPadInst *LP = LandingPadInst::Create(Ty, cast<Function>(PersFn),
Clauses.size());
LP->setCleanup(IsCleanup);
for (SmallVectorImpl<std::pair<LandingPadInst::ClauseType,
Constant*> >::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

View File

@ -347,7 +347,6 @@ namespace llvm {
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);
@ -360,7 +359,6 @@ namespace llvm {
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);

View File

@ -124,9 +124,7 @@ namespace lltok {
kw_fptoui, kw_fptosi, kw_inttoptr, kw_ptrtoint, kw_bitcast,
kw_select, kw_va_arg,
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_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_unwind,
kw_unreachable,
kw_alloca, kw_load, kw_store, kw_fence, kw_cmpxchg, kw_atomicrmw,
@ -149,8 +147,8 @@ namespace lltok {
// Type valued tokens (TyVal).
Type,
APFloat, // APFloatVal
APSInt // APSInt
APFloat, // APFloatVal
APSInt // APSInt
};
} // end namespace lltok
} // end namespace llvm

View File

@ -2508,14 +2508,6 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
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);
@ -2543,38 +2535,6 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
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, cast<Function>(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, cast<Constant>(Val));
}
I = LP;
break;
}
case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align]
if (Record.size() != 4)
return Error("Invalid ALLOCA record");

View File

@ -1143,10 +1143,6 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
}
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;
@ -1166,20 +1162,6 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
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()));

View File

@ -63,8 +63,6 @@ namespace {
typedef SmallPtrSet<BasicBlock*, 8> BBSet;
BBSet LandingPads;
bool InsertUnwindResumeCalls();
bool NormalizeLandingPads();
bool LowerUnwindsAndResumes();
bool MoveExceptionValueCalls();
@ -660,67 +658,13 @@ Instruction *DwarfEHPrepare::CreateExceptionValueCall(BasicBlock *BB) {
return CallInst::Create(ExceptionValueIntrinsic, "eh.value.call", Start);
}
/// InsertUnwindResumeCalls - Convert the ResumeInsts that are still present
/// into calls to the appropriate _Unwind_Resume function.
bool DwarfEHPrepare::InsertUnwindResumeCalls() {
SmallVector<ResumeInst*, 16> Resumes;
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
for (BasicBlock::iterator II = I->begin(), IE = I->end(); II != IE; ++II)
if (ResumeInst *RI = dyn_cast<ResumeInst>(II))
Resumes.push_back(RI);
if (Resumes.empty())
return false;
// Find the rewind function if we didn't already.
if (!RewindFunction) {
LLVMContext &Ctx = Resumes[0]->getContext();
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
Type::getInt8PtrTy(Ctx), false);
const char *RewindName = TLI->getLibcallName(RTLIB::UNWIND_RESUME);
RewindFunction = F->getParent()->getOrInsertFunction(RewindName, FTy);
}
// Create the basic block where the _Unwind_Resume call will live.
LLVMContext &Ctx = F->getContext();
BasicBlock *UnwindBB = BasicBlock::Create(Ctx, "unwind_resume", F);
PHINode *PN = PHINode::Create(Type::getInt8PtrTy(Ctx), Resumes.size(),
"exn.obj", UnwindBB);
// Extract the exception object from the ResumeInst and add it to the PHI node
// that feeds the _Unwind_Resume call.
for (SmallVectorImpl<ResumeInst*>::iterator
I = Resumes.begin(), E = Resumes.end(); I != E; ++I) {
ResumeInst *RI = *I;
BranchInst::Create(UnwindBB, RI->getParent());
ExtractValueInst *ExnObj = ExtractValueInst::Create(RI->getOperand(0),
0, "exn.obj", RI);
PN->addIncoming(ExnObj, RI->getParent());
RI->eraseFromParent();
}
// Call the function.
CallInst *CI = CallInst::Create(RewindFunction, PN, "", UnwindBB);
CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME));
// We never expect _Unwind_Resume to return.
new UnreachableInst(Ctx, UnwindBB);
return true;
}
bool DwarfEHPrepare::runOnFunction(Function &Fn) {
bool Changed = false;
// Initialize internal state.
DT = &getAnalysis<DominatorTree>(); // FIXME: We won't need this with the new EH.
DT = &getAnalysis<DominatorTree>();
F = &Fn;
if (InsertUnwindResumeCalls()) {
// FIXME: The reset of this function can go once the new EH is done.
LandingPads.clear();
return true;
}
// Ensure that only unwind edges end at landing pads (a landing pad is a
// basic block where an invoke unwind edge ends).
Changed |= NormalizeLandingPads();

View File

@ -454,37 +454,3 @@ void llvm::CopyCatchInfo(const BasicBlock *SuccBB, const BasicBlock *LPad,
break;
}
}
//--------- NEW EH - Begin ---------
/// AddLandingPadInfo - Extract the exception handling information from the
/// landingpad instruction and add them to the specified machine module info.
void llvm::AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI,
MachineBasicBlock *MBB) {
MMI.addPersonality(MBB, I.getPersonalityFn());
if (I.isCleanup())
MMI.addCleanup(MBB);
for (unsigned i = 0, e = I.getNumClauses(); i != e; ) {
switch (I.getClauseType(i)) {
case LandingPadInst::Catch:
MMI.addCatchTypeInfo(MBB, dyn_cast<GlobalVariable>(I.getClauseValue(i)));
++i;
break;
case LandingPadInst::Filter: {
// Add filters in a list.
SmallVector<const GlobalVariable*, 4> FilterList;
do {
FilterList.push_back(cast<GlobalVariable>(I.getClauseValue(i)));
++i;
} while (i != e && I.getClauseType(i) == LandingPadInst::Filter);
MMI.addFilterTypeInfo(MBB, FilterList);
break;
}
}
}
}
//--------- NEW EH - End ---------

View File

@ -1810,50 +1810,6 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
void SelectionDAGBuilder::visitUnwind(const UnwindInst &I) {
}
void SelectionDAGBuilder::visitResume(const ResumeInst &RI) {
llvm_unreachable("SelectionDAGBuilder shouldn't visit resume instructions!");
}
void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &LP) {
// FIXME: Handle this
assert(FuncInfo.MBB->isLandingPad() &&
"Call to landingpad not in landing pad!");
MachineBasicBlock *MBB = FuncInfo.MBB;
MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
AddLandingPadInfo(LP, MMI, MBB);
SmallVector<EVT, 2> ValueVTs;
ComputeValueVTs(TLI, LP.getType(), ValueVTs);
// Insert the EXCEPTIONADDR instruction.
assert(FuncInfo.MBB->isLandingPad() &&
"Call to eh.exception not in landing pad!");
SDVTList VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other);
SDValue Ops[2];
Ops[0] = DAG.getRoot();
SDValue Op1 = DAG.getNode(ISD::EXCEPTIONADDR, getCurDebugLoc(), VTs, Ops, 1);
SDValue Chain = Op1.getValue(1);
// Insert the EHSELECTION instruction.
VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other);
Ops[0] = Op1;
Ops[1] = Chain;
SDValue Op2 = DAG.getNode(ISD::EHSELECTION, getCurDebugLoc(), VTs, Ops, 2);
Chain = Op2.getValue(1);
Op2 = DAG.getSExtOrTrunc(Op2, getCurDebugLoc(), MVT::i32);
Ops[0] = Op1;
Ops[1] = Op2;
SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
&Ops[0], 2);
std::pair<SDValue, SDValue> RetPair = std::make_pair(Res, Chain);
setValue(&LP, RetPair.first);
DAG.setRoot(RetPair.second);
}
/// handleSmallSwitchCaseRange - Emit a series of specific tests (suitable for
/// small case ranges).
bool SelectionDAGBuilder::handleSmallSwitchRange(CaseRec& CR,

View File

@ -467,7 +467,6 @@ public:
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);
@ -512,7 +511,6 @@ private:
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);

View File

@ -113,11 +113,9 @@ namespace {
while (StateBB != StateE) {
BasicBlock *CurBB = StateBB++;
// Branches and invokes do not escape, only unwind, resume, and return
// do.
// Branches and invokes do not escape, only unwind and return do.
TerminatorInst *TI = CurBB->getTerminator();
if (!isa<UnwindInst>(TI) && !isa<ReturnInst>(TI) &&
!isa<ResumeInst>(TI))
if (!isa<UnwindInst>(TI) && !isa<ReturnInst>(TI))
continue;
Builder.SetInsertPoint(TI->getParent(), TI);

View File

@ -288,12 +288,10 @@ namespace {
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);

View File

@ -1064,11 +1064,6 @@ void CppWriter::printInstruction(const Instruction *I,
}
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;";
@ -1428,9 +1423,6 @@ void CppWriter::printInstruction(const Instruction *I,
Out << "\", " << bbname << ");";
break;
}
case Instruction::LandingPad: {
break;
}
}
DefinedValues.insert(I);
nl(Out);

View File

@ -2506,7 +2506,7 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
CallStack.pop_back(); // return from fn.
return true; // We succeeded at evaluating this ctor!
} else {
// invoke, unwind, resume, unreachable.
// invoke, unwind, unreachable.
return false; // Cannot handle this terminator.
}

View File

@ -732,11 +732,9 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
}
}
// 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)))
// 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)))
return EraseInstFromFunction(CI);
break;
}

View File

@ -515,7 +515,6 @@ private:
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);
@ -529,7 +528,6 @@ private:
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*/ }

View File

@ -250,33 +250,20 @@ namespace {
PHINode *InnerSelectorPHI;
SmallVector<Value*, 8> UnwindDestPHIValues;
// New EH:
BasicBlock *OuterResumeDest; //< Destination of the invoke's unwind.
BasicBlock *InnerResumeDest; //< Destination for the callee's resume.
LandingPadInst *CallerLPad; //< LandingPadInst associated with the invoke.
PHINode *InnerEHValuesPHI; //< PHI for EH values from landingpad insts.
public:
InvokeInliningInfo(InvokeInst *II)
: OuterUnwindDest(II->getUnwindDest()), OuterSelector(0),
InnerUnwindDest(0), InnerExceptionPHI(0), InnerSelectorPHI(0),
InvokeInliningInfo(InvokeInst *II) :
OuterUnwindDest(II->getUnwindDest()), OuterSelector(0),
InnerUnwindDest(0), InnerExceptionPHI(0), InnerSelectorPHI(0) {
OuterResumeDest(II->getUnwindDest()), InnerResumeDest(0),
CallerLPad(0), InnerEHValuesPHI(0) {
// If there are PHI nodes in the unwind destination block, we need to keep
// track of which values came into them from the invoke before removing
// the edge from this block.
llvm::BasicBlock *InvokeBB = II->getParent();
BasicBlock::iterator I = OuterUnwindDest->begin();
for (; isa<PHINode>(I); ++I) {
// If there are PHI nodes in the unwind destination block, we
// need to keep track of which values came into them from the
// invoke before removing the edge from this block.
llvm::BasicBlock *invokeBB = II->getParent();
for (BasicBlock::iterator I = OuterUnwindDest->begin();
isa<PHINode>(I); ++I) {
// Save the value to use for this edge.
PHINode *PHI = cast<PHINode>(I);
UnwindDestPHIValues.push_back(PHI->getIncomingValueForBlock(InvokeBB));
}
// FIXME: With the new EH, this if/dyn_cast should be a 'cast'.
if (LandingPadInst *LPI = dyn_cast<LandingPadInst>(I)) {
CallerLPad = LPI;
PHINode *phi = cast<PHINode>(I);
UnwindDestPHIValues.push_back(phi->getIncomingValueForBlock(invokeBB));
}
}
@ -293,30 +280,21 @@ namespace {
}
BasicBlock *getInnerUnwindDest();
BasicBlock *getInnerUnwindDest_new();
LandingPadInst *getLandingPadInst() const { return CallerLPad; }
bool forwardEHResume(CallInst *call, BasicBlock *src);
/// forwardResume - Forward the 'resume' instruction to the caller's landing
/// pad block. When the landing pad block has only one predecessor, this is
/// a simple branch. When there is more than one predecessor, we need to
/// split the landing pad block after the landingpad instruction and jump
/// to there.
void forwardResume(ResumeInst *RI);
/// addIncomingPHIValuesFor - Add incoming-PHI values to the unwind
/// destination block for the given basic block, using the values for the
/// original invoke's source block.
/// Add incoming-PHI values to the unwind destination block for
/// the given basic block, using the values for the original
/// invoke's source block.
void addIncomingPHIValuesFor(BasicBlock *BB) const {
addIncomingPHIValuesForInto(BB, OuterUnwindDest);
}
void addIncomingPHIValuesForInto(BasicBlock *src, BasicBlock *dest) const {
BasicBlock::iterator I = dest->begin();
for (unsigned i = 0, e = UnwindDestPHIValues.size(); i != e; ++i, ++I) {
PHINode *PHI = cast<PHINode>(I);
PHI->addIncoming(UnwindDestPHIValues[i], src);
PHINode *phi = cast<PHINode>(I);
phi->addIncoming(UnwindDestPHIValues[i], src);
}
}
};
@ -426,59 +404,6 @@ bool InvokeInliningInfo::forwardEHResume(CallInst *call, BasicBlock *src) {
return true;
}
/// Get or create a target for the branch from ResumeInsts.
BasicBlock *InvokeInliningInfo::getInnerUnwindDest_new() {
if (InnerResumeDest) return InnerResumeDest;
// Split the landing pad.
BasicBlock::iterator SplitPoint = CallerLPad; ++SplitPoint;
InnerResumeDest =
OuterResumeDest->splitBasicBlock(SplitPoint,
OuterResumeDest->getName() + ".body");
// The number of incoming edges we expect to the inner landing pad.
const unsigned PHICapacity = 2;
// Create corresponding new PHIs for all the PHIs in the outer landing pad.
BasicBlock::iterator InsertPoint = InnerResumeDest->begin();
BasicBlock::iterator I = OuterResumeDest->begin();
for (unsigned i = 0, e = UnwindDestPHIValues.size(); i != e; ++i, ++I) {
PHINode *OuterPHI = cast<PHINode>(I);
PHINode *InnerPHI = PHINode::Create(OuterPHI->getType(), PHICapacity,
OuterPHI->getName() + ".lpad-body",
InsertPoint);
OuterPHI->replaceAllUsesWith(InnerPHI);
InnerPHI->addIncoming(OuterPHI, OuterResumeDest);
}
// Create a PHI for the exception values.
InnerEHValuesPHI = PHINode::Create(CallerLPad->getType(), PHICapacity,
"eh.lpad-body", InsertPoint);
CallerLPad->replaceAllUsesWith(InnerEHValuesPHI);
InnerEHValuesPHI->addIncoming(CallerLPad, OuterResumeDest);
// All done.
return InnerResumeDest;
}
/// forwardResume - Forward the 'resume' instruction to the caller's landing pad
/// block. When the landing pad block has only one predecessor, this is a simple
/// branch. When there is more than one predecessor, we need to split the
/// landing pad block after the landingpad instruction and jump to there.
void InvokeInliningInfo::forwardResume(ResumeInst *RI) {
BasicBlock *Dest = getInnerUnwindDest_new();
BasicBlock *Src = RI->getParent();
BranchInst::Create(Dest, Src);
// Update the PHIs in the destination. They were inserted in an order which
// makes this work.
addIncomingPHIValuesForInto(Src, Dest);
InnerEHValuesPHI->addIncoming(RI->getOperand(0), Src);
RI->eraseFromParent();
}
/// [LIBUNWIND] Check whether this selector is "only cleanups":
/// call i32 @llvm.eh.selector(blah, blah, i32 0)
static bool isCleanupOnlySelector(EHSelectorInst *selector) {
@ -496,19 +421,9 @@ static bool isCleanupOnlySelector(EHSelectorInst *selector) {
/// Returns true to indicate that the next block should be skipped.
static bool HandleCallsInBlockInlinedThroughInvoke(BasicBlock *BB,
InvokeInliningInfo &Invoke) {
LandingPadInst *LPI = Invoke.getLandingPadInst();
for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) {
Instruction *I = BBI++;
if (LPI) // FIXME: This won't be NULL in the new EH.
if (LandingPadInst *L = dyn_cast<LandingPadInst>(I)) {
unsigned NumClauses = LPI->getNumClauses();
L->reserveClauses(NumClauses);
for (unsigned i = 0; i != NumClauses; ++i)
L->addClause(LPI->getClauseType(i), LPI->getClauseValue(i));
}
// We only need to check for function calls: inlined invoke
// instructions require no special handling.
CallInst *CI = dyn_cast<CallInst>(I);
@ -642,10 +557,6 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
// there is now a new entry in them.
Invoke.addIncomingPHIValuesFor(BB);
}
if (ResumeInst *RI = dyn_cast<ResumeInst>(BB->getTerminator())) {
Invoke.forwardResume(RI);
}
}
// Now that everything is happy, we have one final detail. The PHI nodes in
@ -918,40 +829,6 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) {
return false;
}
// Find the personality function used by the landing pads of the caller. If it
// exists, then check to see that it matches the personality function used in
// the callee.
for (Function::const_iterator
I = Caller->begin(), E = Caller->end(); I != E; ++I)
if (const InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator())) {
const BasicBlock *BB = II->getUnwindDest();
// FIXME: This 'isa' here should become go away once the new EH system is
// in place.
if (!isa<LandingPadInst>(BB->getFirstNonPHI()))
continue;
const LandingPadInst *LP = cast<LandingPadInst>(BB->getFirstNonPHI());
const Value *CallerPersFn = LP->getPersonalityFn();
// If the personality functions match, then we can perform the
// inlining. Otherwise, we can't inline.
// TODO: This isn't 100% true. Some personality functions are proper
// supersets of others and can be used in place of the other.
for (Function::const_iterator
I = CalledFunc->begin(), E = CalledFunc->end(); I != E; ++I)
if (const InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator())) {
const BasicBlock *BB = II->getUnwindDest();
// FIXME: This 'if/dyn_cast' here should become a normal 'cast' once
// the new EH system is in place.
if (const LandingPadInst *LP =
dyn_cast<LandingPadInst>(BB->getFirstNonPHI()))
if (CallerPersFn != LP->getPersonalityFn())
return false;
break;
}
break;
}
// Get an iterator to the last basic block in the function, which will have
// the new function inlined after it.
//

View File

@ -1731,9 +1731,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
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);
@ -1756,33 +1753,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
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)) {

View File

@ -1683,22 +1683,10 @@ LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn,
Name));
}
LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty,
LLVMValueRef PersFn, unsigned NumClauses,
const char *Name) {
return wrap(unwrap(B)->CreateLandingPad(unwrap(Ty),
cast<Function>(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());
}
@ -1712,17 +1700,6 @@ void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest) {
unwrap<IndirectBrInst>(IndirectBr)->addDestination(unwrap(Dest));
}
void LLVMAddClause(LLVMValueRef LandingPad, LLVMLandingPadClauseTy ClauseTy,
LLVMValueRef ClauseVal) {
unwrap<LandingPadInst>(LandingPad)->
addClause(static_cast<LandingPadInst::ClauseType>(ClauseTy),
cast<Constant>(unwrap(ClauseVal)));
}
void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val) {
unwrap<LandingPadInst>(LandingPad)->setCleanup(Val);
}
/*--.. Arithmetic ..........................................................--*/
LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,

View File

@ -101,7 +101,6 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
case Switch: return "switch";
case IndirectBr: return "indirectbr";
case Invoke: return "invoke";
case Resume: return "resume";
case Unwind: return "unwind";
case Unreachable: return "unreachable";
@ -162,7 +161,6 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
case ShuffleVector: return "shufflevector";
case ExtractValue: return "extractvalue";
case InsertValue: return "insertvalue";
case LandingPad: return "landingpad";
default: return "<Invalid operator> ";
}

View File

@ -166,77 +166,6 @@ Value *PHINode::hasConstantValue() const {
return ConstantValue;
}
//===----------------------------------------------------------------------===//
// LandingPadInst Implementation
//===----------------------------------------------------------------------===//
void LandingPadInst::init(Function *PersFn, unsigned NumReservedValues,
const Twine &NameStr) {
ReservedSpace = NumReservedValues;
NumOperands = 1;
OperandList = allocHungoffUses(ReservedSpace);
OperandList[0] = (Value*)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::reserveClauses(unsigned Size) {
unsigned e = getNumOperands();
if (ReservedSpace >= e + Size) return;
ReservedSpace = e + Size;
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, Constant *ClauseVal) {
unsigned OpNo = getNumOperands();
if (OpNo + 1 > ReservedSpace)
growOperands();
assert(OpNo < ReservedSpace && "Growing didn't work!");
ClauseIdxs.push_back(CT);
++NumOperands;
OperandList[OpNo] = (Value*)ClauseVal;
}
//===----------------------------------------------------------------------===//
// CallInst Implementation
@ -565,9 +494,6 @@ void InvokeInst::removeAttribute(unsigned i, Attributes attr) {
setAttributes(PAL);
}
LandingPadInst *InvokeInst::getLandingPad() const {
return cast<LandingPadInst>(getUnwindDest()->getFirstNonPHI());
}
//===----------------------------------------------------------------------===//
// ReturnInst Implementation
@ -647,42 +573,6 @@ BasicBlock *UnwindInst::getSuccessorV(unsigned idx) const {
return 0;
}
//===----------------------------------------------------------------------===//
// 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
//===----------------------------------------------------------------------===//
@ -702,11 +592,11 @@ unsigned UnreachableInst::getNumSuccessorsV() const {
}
void UnreachableInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
llvm_unreachable("UnreachableInst has no successors!");
llvm_unreachable("UnwindInst has no successors!");
}
BasicBlock *UnreachableInst::getSuccessorV(unsigned idx) const {
llvm_unreachable("UnreachableInst has no successors!");
llvm_unreachable("UnwindInst has no successors!");
return 0;
}
@ -3343,10 +3233,6 @@ PHINode *PHINode::clone_impl() const {
return new PHINode(*this);
}
LandingPadInst *LandingPadInst::clone_impl() const {
return new LandingPadInst(*this);
}
ReturnInst *ReturnInst::clone_impl() const {
return new(getNumOperands()) ReturnInst(*this);
}
@ -3368,10 +3254,6 @@ InvokeInst *InvokeInst::clone_impl() const {
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);

View File

@ -35,12 +35,6 @@
// * 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...
//
//===----------------------------------------------------------------------===//
@ -137,22 +131,18 @@ namespace {
/// 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), PersonalityFn(0) {
initializeVerifierPass(*PassRegistry::getPassRegistry());
}
: FunctionPass(ID),
Broken(false), RealPass(true), action(AbortProcessAction),
Mod(0), Context(0), DT(0), MessagesStr(Messages) {
initializeVerifierPass(*PassRegistry::getPassRegistry());
}
explicit Verifier(VerifierFailureAction ctn)
: FunctionPass(ID), Broken(false), RealPass(true), action(ctn), Mod(0),
Context(0), DT(0), MessagesStr(Messages), PersonalityFn(0) {
initializeVerifierPass(*PassRegistry::getPassRegistry());
}
: FunctionPass(ID),
Broken(false), RealPass(true), action(ctn), Mod(0), Context(0), DT(0),
MessagesStr(Messages) {
initializeVerifierPass(*PassRegistry::getPassRegistry());
}
bool doInitialization(Module &M) {
Mod = &M;
@ -294,7 +284,6 @@ namespace {
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,
@ -1372,7 +1361,7 @@ void Verifier::visitFenceInst(FenceInst &FI) {
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);
}
@ -1394,42 +1383,6 @@ void Verifier::visitInsertValueInst(InsertValueInst &IVI) {
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) {

View File

@ -1,54 +0,0 @@
; RUN: llvm-as < %s | llvm-dis > %t1.ll
; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll
; RUN: diff %t1.ll %t2.ll
@_ZTIc = external constant i8*
@_ZTId = external constant i8*
@_ZTIPKc = external constant i8*
@.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()