mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Merge the contents from exception-handling-rewrite to the mainline.
This adds the new instructions 'landingpad' and 'resume'. llvm-svn: 136253
This commit is contained in:
parent
624acaffd7
commit
b20cfdfe95
@ -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 @@ 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 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>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
@ -3271,6 +3273,35 @@ 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 <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>
|
||||
|
@ -126,67 +126,69 @@ typedef enum {
|
||||
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 @@ typedef enum {
|
||||
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 @@ LLVMTypeRef LLVMX86MMXType(void);
|
||||
macro(GetElementPtrInst) \
|
||||
macro(InsertElementInst) \
|
||||
macro(InsertValueInst) \
|
||||
macro(LandingPadInst) \
|
||||
macro(PHINode) \
|
||||
macro(SelectInst) \
|
||||
macro(ShuffleVectorInst) \
|
||||
@ -474,6 +482,7 @@ LLVMTypeRef LLVMX86MMXType(void);
|
||||
macro(SwitchInst) \
|
||||
macro(UnreachableInst) \
|
||||
macro(UnwindInst) \
|
||||
macro(ResumeInst) \
|
||||
macro(UnaryInstruction) \
|
||||
macro(AllocaInst) \
|
||||
macro(CastInst) \
|
||||
@ -822,6 +831,7 @@ 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 */
|
||||
@ -831,6 +841,13 @@ 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);
|
||||
|
@ -257,7 +257,7 @@ namespace bitc {
|
||||
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 @@ namespace bitc {
|
||||
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
|
||||
|
@ -100,41 +100,42 @@ 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, 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(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)
|
||||
HANDLE_OTHER_INST(58, LandingPad, LandingPadInst) // Landing pad instruction.
|
||||
LAST_OTHER_INST(58)
|
||||
|
||||
#undef FIRST_TERM_INST
|
||||
#undef HANDLE_TERM_INST
|
||||
|
@ -1775,6 +1775,116 @@ 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(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
|
||||
@ -2462,6 +2572,59 @@ 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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -479,6 +479,10 @@ public:
|
||||
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 @@ public:
|
||||
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
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -163,6 +163,7 @@ 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);}
|
||||
@ -192,6 +193,7 @@ 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
|
||||
|
@ -581,6 +581,11 @@ lltok::Kind LLLexer::LexIdentifier() {
|
||||
|
||||
KEYWORD(x);
|
||||
KEYWORD(blockaddress);
|
||||
|
||||
KEYWORD(personality);
|
||||
KEYWORD(cleanup);
|
||||
KEYWORD(catch);
|
||||
KEYWORD(filter);
|
||||
#undef KEYWORD
|
||||
|
||||
// Keywords for types.
|
||||
@ -633,6 +638,7 @@ lltok::Kind LLLexer::LexIdentifier() {
|
||||
INSTKEYWORD(switch, Switch);
|
||||
INSTKEYWORD(indirectbr, IndirectBr);
|
||||
INSTKEYWORD(invoke, Invoke);
|
||||
INSTKEYWORD(resume, Resume);
|
||||
INSTKEYWORD(unwind, Unwind);
|
||||
INSTKEYWORD(unreachable, Unreachable);
|
||||
|
||||
@ -647,6 +653,7 @@ 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
|
||||
@ -674,7 +681,6 @@ 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]+
|
||||
|
@ -2885,6 +2885,7 @@ 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:
|
||||
@ -2944,6 +2945,7 @@ 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.
|
||||
@ -3247,7 +3249,18 @@ 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.
|
||||
@ -3495,6 +3508,56 @@ 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, 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
|
||||
|
@ -347,6 +347,7 @@ 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);
|
||||
@ -359,6 +360,7 @@ 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);
|
||||
|
@ -121,7 +121,9 @@ namespace lltok {
|
||||
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 @@ namespace lltok {
|
||||
// Type valued tokens (TyVal).
|
||||
Type,
|
||||
|
||||
APFloat, // APFloatVal
|
||||
APSInt // APSInt
|
||||
APFloat, // APFloatVal
|
||||
APSInt // APSInt
|
||||
};
|
||||
} // end namespace lltok
|
||||
} // end namespace llvm
|
||||
|
@ -2491,6 +2491,14 @@ 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);
|
||||
@ -2518,6 +2526,37 @@ 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, 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");
|
||||
|
@ -1126,6 +1126,10 @@ 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;
|
||||
@ -1145,6 +1149,20 @@ 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()));
|
||||
|
@ -914,6 +914,10 @@ void SelectionDAGBuilder::visitPHI(const PHINode &) {
|
||||
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::visitInvoke(const InvokeInst &I) {
|
||||
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,
|
||||
|
@ -453,6 +453,7 @@ 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);
|
||||
@ -497,6 +498,7 @@ 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);
|
||||
|
@ -113,9 +113,11 @@ namespace {
|
||||
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);
|
||||
|
@ -288,10 +288,12 @@ 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);
|
||||
|
@ -1064,6 +1064,11 @@ 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;";
|
||||
@ -1423,6 +1428,9 @@ void CppWriter::printInstruction(const Instruction *I,
|
||||
Out << "\", " << bbname << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::LandingPad: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
DefinedValues.insert(I);
|
||||
nl(Out);
|
||||
|
@ -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, unreachable.
|
||||
// invoke, unwind, resume, unreachable.
|
||||
return false; // Cannot handle this terminator.
|
||||
}
|
||||
|
||||
|
@ -732,9 +732,11 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
@ -515,6 +515,7 @@ 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);
|
||||
@ -528,6 +529,7 @@ 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*/ }
|
||||
|
@ -1710,6 +1710,9 @@ 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);
|
||||
@ -1732,6 +1735,33 @@ 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)) {
|
||||
|
@ -1683,10 +1683,21 @@ 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), 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 @@ 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),
|
||||
unwrap(ClauseVal));
|
||||
}
|
||||
|
||||
void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val) {
|
||||
unwrap<LandingPadInst>(LandingPad)->setCleanup(Val);
|
||||
}
|
||||
|
||||
/*--.. Arithmetic ..........................................................--*/
|
||||
|
||||
LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
|
@ -101,6 +101,7 @@ 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";
|
||||
|
||||
@ -159,6 +160,7 @@ 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> ";
|
||||
}
|
||||
|
@ -166,6 +166,63 @@ Value *PHINode::hasConstantValue() const {
|
||||
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
|
||||
@ -573,6 +630,42 @@ 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
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -592,11 +685,11 @@ unsigned UnreachableInst::getNumSuccessorsV() const {
|
||||
}
|
||||
|
||||
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 @@ 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);
|
||||
}
|
||||
@ -3143,6 +3240,10 @@ 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);
|
||||
|
@ -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 @@ 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) {
|
||||
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 @@ 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,
|
||||
@ -1321,7 +1332,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);
|
||||
}
|
||||
|
||||
@ -1343,6 +1354,42 @@ 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) {
|
||||
|
54
test/Feature/exceptionhandling.ll
Normal file
54
test/Feature/exceptionhandling.ll
Normal file
@ -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
|
||||
|
||||
@_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()
|
Loading…
x
Reference in New Issue
Block a user