mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
Initial commit of the 'landingpad' instruction.
This implements the 'landingpad' instruction. It's used to indicate that a basic block is a landing pad. There are several restrictions on its use (see LangRef.html for more detail). These restrictions allow the exception handling code to gather the information it needs in a much more sane way. This patch has the definition, implementation, C interface, parsing, and bitcode support in it. llvm-svn: 137501
This commit is contained in:
parent
7b426d97ad
commit
4cbbcd4f82
@ -6022,7 +6022,7 @@ freestanding environments and non-C-based languages.</p>
|
||||
<resultval> = landingpad <somety> personality <type> <pers_fn> cleanup <clause>*
|
||||
|
||||
<clause> := catch <type> <value>
|
||||
<clause> := filter <type> <value> {, <type> <value>}*
|
||||
<clause> := filter <array constant type> <array constant>
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
@ -6041,9 +6041,11 @@ freestanding environments and non-C-based languages.</p>
|
||||
<tt>cleanup</tt> flag indicates that the landing pad block is a cleanup.</p>
|
||||
|
||||
<p>A <tt>clause</tt> begins with the clause type — <tt>catch</tt>
|
||||
or <tt>filter</tt> — and contains a list of global variables
|
||||
representing the "types" that may be caught or filtered respectively. The
|
||||
'<tt>landingpad</tt>' instruction must contain <em>at least</em>
|
||||
or <tt>filter</tt> — and contains the global variable representing the
|
||||
"type" that may be caught or filtered respectively. Unlike the
|
||||
<tt>catch</tt> clause, the <tt>filter</tt> clause takes an array constant as
|
||||
its argument. Use "<tt>[0 x i8**] undef</tt>" for a filter which cannot
|
||||
throw. The '<tt>landingpad</tt>' instruction must contain <em>at least</em>
|
||||
one <tt>clause</tt> or the <tt>cleanup</tt> flag.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
@ -6083,7 +6085,7 @@ freestanding environments and non-C-based languages.</p>
|
||||
;; A landing pad which can catch an integer and can only throw a double.
|
||||
%res = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
|
||||
catch i8** @_ZTIi
|
||||
filter i8** @_ZTId
|
||||
filter [1 x i8**] [@_ZTId]
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
@ -191,7 +191,8 @@ typedef enum {
|
||||
LLVMAtomicRMW = 57,
|
||||
|
||||
/* Exception Handling Operators */
|
||||
LLVMResume = 58
|
||||
LLVMResume = 58,
|
||||
LLVMLandingPad = 59
|
||||
|
||||
} LLVMOpcode;
|
||||
|
||||
@ -283,6 +284,11 @@ typedef enum {
|
||||
LLVMRealPredicateTrue /**< Always true (always folded) */
|
||||
} LLVMRealPredicate;
|
||||
|
||||
typedef enum {
|
||||
LLVMLandingPadCatch, /**< A catch clause */
|
||||
LLVMLandingPadFilter /**< A filter clause */
|
||||
} LLVMLandingPadClauseTy;
|
||||
|
||||
void LLVMInitializeCore(LLVMPassRegistryRef R);
|
||||
|
||||
|
||||
@ -469,6 +475,7 @@ LLVMTypeRef LLVMX86MMXType(void);
|
||||
macro(GetElementPtrInst) \
|
||||
macro(InsertElementInst) \
|
||||
macro(InsertValueInst) \
|
||||
macro(LandingPadInst) \
|
||||
macro(PHINode) \
|
||||
macro(SelectInst) \
|
||||
macro(ShuffleVectorInst) \
|
||||
@ -837,6 +844,12 @@ void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal,
|
||||
/* Add a destination to the indirectbr instruction */
|
||||
void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest);
|
||||
|
||||
/* Add a catch or filter clause to the landingpad instruction */
|
||||
void LLVMAddClause(LLVMValueRef LandingPad, 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);
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class LandingPadInst;
|
||||
class TerminatorInst;
|
||||
class LLVMContext;
|
||||
class BlockAddress;
|
||||
@ -258,6 +259,14 @@ public:
|
||||
/// to refer to basic block New instead of to us.
|
||||
void replaceSuccessorsPhiUsesWith(BasicBlock *New);
|
||||
|
||||
/// isLandingPad - Return true if this basic block is a landing pad. I.e.,
|
||||
/// it's the destination of the 'unwind' edge of an invoke instruction.
|
||||
bool isLandingPad() const;
|
||||
|
||||
/// getLandingPadInst() - Return the landingpad instruction associated with
|
||||
/// the landing pad.
|
||||
LandingPadInst *getLandingPadInst();
|
||||
|
||||
private:
|
||||
/// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress
|
||||
/// objects using it. This is almost always 0, sometimes one, possibly but
|
||||
|
@ -308,9 +308,10 @@ namespace bitc {
|
||||
// align, vol,
|
||||
// ordering, synchscope]
|
||||
FUNC_CODE_INST_RESUME = 39, // RESUME: [opval]
|
||||
FUNC_CODE_INST_LOADATOMIC = 40, // LOAD: [opty, op, align, vol,
|
||||
FUNC_CODE_INST_LANDINGPAD = 40, // LANDINGPAD: [ty,val,val,num,id0,val0...]
|
||||
FUNC_CODE_INST_LOADATOMIC = 41, // LOAD: [opty, op, align, vol,
|
||||
// ordering, synchscope]
|
||||
FUNC_CODE_INST_STOREATOMIC = 41 // STORE: [ptrty,ptr,val, align, vol
|
||||
FUNC_CODE_INST_STOREATOMIC = 42 // STORE: [ptrty,ptr,val, align, vol
|
||||
// ordering, synchscope]
|
||||
};
|
||||
} // End bitc namespace
|
||||
|
@ -172,7 +172,8 @@ 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
|
||||
LAST_OTHER_INST(58)
|
||||
HANDLE_OTHER_INST(59, LandingPad, LandingPadInst) // Landing pad instruction.
|
||||
LAST_OTHER_INST(59)
|
||||
|
||||
#undef FIRST_TERM_INST
|
||||
#undef HANDLE_TERM_INST
|
||||
|
@ -2106,6 +2106,111 @@ 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. This uses the
|
||||
/// SubclassData field in Value to store whether or not the landingpad is a
|
||||
/// cleanup.
|
||||
///
|
||||
class LandingPadInst : public Instruction {
|
||||
/// ReservedSpace - The number of operands actually allocated. NumOperands is
|
||||
/// the number actually in use.
|
||||
unsigned ReservedSpace;
|
||||
LandingPadInst(const LandingPadInst &LP);
|
||||
public:
|
||||
enum ClauseType { Catch, Filter };
|
||||
private:
|
||||
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(unsigned Size);
|
||||
void init(Value *PersFn, unsigned NumReservedValues, const Twine &NameStr);
|
||||
|
||||
explicit LandingPadInst(Type *RetTy, Value *PersonalityFn,
|
||||
unsigned NumReservedValues, const Twine &NameStr,
|
||||
Instruction *InsertBefore);
|
||||
explicit LandingPadInst(Type *RetTy, Value *PersonalityFn,
|
||||
unsigned NumReservedValues, const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd);
|
||||
protected:
|
||||
virtual LandingPadInst *clone_impl() const;
|
||||
public:
|
||||
/// Constructors - NumReservedClauses is a hint for the number of incoming
|
||||
/// clauses that this landingpad will have (use 0 if you really have no idea).
|
||||
static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn,
|
||||
unsigned NumReservedClauses,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0);
|
||||
static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn,
|
||||
unsigned NumReservedClauses,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
~LandingPadInst();
|
||||
|
||||
/// Provide fast operand accessors
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
|
||||
/// getPersonalityFn - Get the personality function associated with this
|
||||
/// landing pad.
|
||||
Value *getPersonalityFn() const { return getOperand(0); }
|
||||
|
||||
/// isCleanup - Return 'true' if this landingpad instruction is a
|
||||
/// cleanup. I.e., it should be run when unwinding even if its landing pad
|
||||
/// doesn't catch the exception.
|
||||
bool isCleanup() const { return getSubclassDataFromInstruction() & 1; }
|
||||
|
||||
/// setCleanup - Indicate that this landingpad instruction is a cleanup.
|
||||
void setCleanup(bool V) {
|
||||
setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
|
||||
(V ? 1 : 0));
|
||||
}
|
||||
|
||||
/// addClause - Add a catch or filter clause to the landing pad.
|
||||
void addClause(Value *ClauseVal);
|
||||
|
||||
/// getClause - Get the value of the clause at index Idx. Use isCatch/isFilter
|
||||
/// to determine what type of clause this is.
|
||||
Value *getClause(unsigned Idx) const { return OperandList[Idx + 1]; }
|
||||
|
||||
/// isCatch - Return 'true' if the clause and index Idx is a catch clause.
|
||||
bool isCatch(unsigned Idx) const {
|
||||
return !isa<ArrayType>(OperandList[Idx + 1]->getType());
|
||||
}
|
||||
|
||||
/// isFilter - Return 'true' if the clause and index Idx is a filter clause.
|
||||
bool isFilter(unsigned Idx) const {
|
||||
return isa<ArrayType>(OperandList[Idx + 1]->getType());
|
||||
}
|
||||
|
||||
/// 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) { growOperands(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
|
||||
@ -2695,6 +2800,10 @@ public:
|
||||
Op<-1>() = reinterpret_cast<Value*>(B);
|
||||
}
|
||||
|
||||
/// getLandingPadInst - Get the landingpad instruction from the landing pad
|
||||
/// block (the unwind destination).
|
||||
LandingPadInst *getLandingPadInst() const;
|
||||
|
||||
BasicBlock *getSuccessor(unsigned i) const {
|
||||
assert(i < 2 && "Successor # out of range for invoke!");
|
||||
return i == 0 ? getNormalDest() : getUnwindDest();
|
||||
|
@ -1204,6 +1204,11 @@ public:
|
||||
return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name);
|
||||
}
|
||||
|
||||
LandingPadInst *CreateLandingPad(Type *Ty, Value *PersFn, unsigned NumClauses,
|
||||
const Twine &Name = "") {
|
||||
return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses, Name));
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Utility creation methods
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -195,6 +195,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
|
||||
|
@ -584,6 +584,11 @@ lltok::Kind LLLexer::LexIdentifier() {
|
||||
|
||||
KEYWORD(x);
|
||||
KEYWORD(blockaddress);
|
||||
|
||||
KEYWORD(personality);
|
||||
KEYWORD(cleanup);
|
||||
KEYWORD(catch);
|
||||
KEYWORD(filter);
|
||||
#undef KEYWORD
|
||||
|
||||
// Keywords for types.
|
||||
@ -653,6 +658,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
|
||||
|
@ -2945,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.
|
||||
@ -3519,6 +3520,47 @@ int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) {
|
||||
return AteExtraComma ? InstExtraComma : InstNormal;
|
||||
}
|
||||
|
||||
/// ParseLandingPad
|
||||
/// ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'? Clause+
|
||||
/// Clause
|
||||
/// ::= 'catch' TypeAndValue
|
||||
/// ::= 'filter'
|
||||
/// ::= 'filter' 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;
|
||||
|
||||
LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, 0);
|
||||
LP->setCleanup(EatIfPresent(lltok::kw_cleanup));
|
||||
|
||||
while (Lex.getKind() == lltok::kw_catch || Lex.getKind() == lltok::kw_filter){
|
||||
LandingPadInst::ClauseType CT;
|
||||
if (EatIfPresent(lltok::kw_catch))
|
||||
CT = LandingPadInst::Catch;
|
||||
else if (EatIfPresent(lltok::kw_filter))
|
||||
CT = LandingPadInst::Filter;
|
||||
else
|
||||
return TokError("expected 'catch' or 'filter' clause type");
|
||||
|
||||
Value *V; LocTy VLoc;
|
||||
if (ParseTypeAndValue(V, VLoc, PFS)) {
|
||||
delete LP;
|
||||
return true;
|
||||
}
|
||||
|
||||
LP->addClause(V);
|
||||
}
|
||||
|
||||
Inst = LP;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ParseCall
|
||||
/// ::= 'tail'? 'call' OptionalCallingConv OptionalAttrs Type Value
|
||||
/// ParameterList OptionalAttrs
|
||||
|
@ -360,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,
|
||||
|
@ -124,6 +124,8 @@ 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_unreachable,
|
||||
|
||||
|
@ -2543,6 +2543,44 @@ 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++]); (void)CT;
|
||||
Value *Val;
|
||||
|
||||
if (getValueTypePair(Record, Idx, NextValueNo, Val)) {
|
||||
delete LP;
|
||||
return Error("Invalid LANDINGPAD record");
|
||||
}
|
||||
|
||||
assert((CT != LandingPadInst::Catch ||
|
||||
!isa<ArrayType>(Val->getType())) &&
|
||||
"Catch clause has a invalid type!");
|
||||
assert((CT != LandingPadInst::Filter ||
|
||||
isa<ArrayType>(Val->getType())) &&
|
||||
"Filter clause has invalid type!");
|
||||
LP->addClause(Val);
|
||||
}
|
||||
|
||||
I = LP;
|
||||
break;
|
||||
}
|
||||
|
||||
case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align]
|
||||
if (Record.size() != 4)
|
||||
return Error("Invalid ALLOCA record");
|
||||
|
@ -1165,6 +1165,23 @@ 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) {
|
||||
if (LP.isCatch(I))
|
||||
Vals.push_back(LandingPadInst::Catch);
|
||||
else
|
||||
Vals.push_back(LandingPadInst::Filter);
|
||||
PushValueAndType(LP.getClause(I), InstID, Vals, VE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Instruction::Alloca:
|
||||
Code = bitc::FUNC_CODE_INST_ALLOCA;
|
||||
Vals.push_back(VE.getTypeID(I.getType()));
|
||||
|
@ -2985,6 +2985,9 @@ void SelectionDAGBuilder::visitExtractValue(const ExtractValueInst &I) {
|
||||
&Values[0], NumValValues));
|
||||
}
|
||||
|
||||
void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &I) {
|
||||
}
|
||||
|
||||
void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
|
||||
SDValue N = getValue(I.getOperand(0));
|
||||
Type *Ty = I.getOperand(0)->getType();
|
||||
|
@ -512,6 +512,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);
|
||||
|
@ -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);
|
||||
|
@ -1748,6 +1748,24 @@ 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(I.getOperand(0), true); Out << '\n';
|
||||
|
||||
if (LPI->isCleanup())
|
||||
Out << " cleanup";
|
||||
|
||||
for (unsigned i = 0, e = LPI->getNumClauses(); i != e; ++i) {
|
||||
if (i != 0 || LPI->isCleanup()) Out << "\n";
|
||||
if (LPI->isCatch(i))
|
||||
Out << " catch ";
|
||||
else
|
||||
Out << " filter ";
|
||||
|
||||
writeOperand(LPI->getClause(i), true);
|
||||
}
|
||||
} else if (isa<ReturnInst>(I) && !Operand) {
|
||||
Out << " void";
|
||||
} else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
|
||||
|
@ -348,3 +348,15 @@ void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// isLandingPad - Return true if this basic block is a landing pad. I.e., it's
|
||||
/// the destination of the 'unwind' edge of an invoke instruction.
|
||||
bool BasicBlock::isLandingPad() const {
|
||||
return isa<LandingPadInst>(getFirstNonPHI());
|
||||
}
|
||||
|
||||
/// getLandingPadInst() - Return the landingpad instruction associated with
|
||||
/// the landing pad.
|
||||
LandingPadInst *BasicBlock::getLandingPadInst() {
|
||||
return dyn_cast<LandingPadInst>(getFirstNonPHI());
|
||||
}
|
||||
|
@ -1683,6 +1683,14 @@ 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 LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn) {
|
||||
return wrap(unwrap(B)->CreateResume(unwrap(Exn)));
|
||||
}
|
||||
@ -1700,6 +1708,15 @@ void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest) {
|
||||
unwrap<IndirectBrInst>(IndirectBr)->addDestination(unwrap(Dest));
|
||||
}
|
||||
|
||||
void LLVMAddClause(LLVMValueRef LandingPad, LLVMValueRef ClauseVal) {
|
||||
unwrap<LandingPadInst>(LandingPad)->
|
||||
addClause(cast<Constant>(unwrap(ClauseVal)));
|
||||
}
|
||||
|
||||
void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val) {
|
||||
unwrap<LandingPadInst>(LandingPad)->setCleanup(Val);
|
||||
}
|
||||
|
||||
/*--.. Arithmetic ..........................................................--*/
|
||||
|
||||
LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
|
@ -162,6 +162,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,88 @@ Value *PHINode::hasConstantValue() const {
|
||||
return ConstantValue;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LandingPadInst Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
LandingPadInst::LandingPadInst(Type *RetTy, Value *PersonalityFn,
|
||||
unsigned NumReservedValues, const Twine &NameStr,
|
||||
Instruction *InsertBefore)
|
||||
: Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertBefore) {
|
||||
init(PersonalityFn, 1 + NumReservedValues, NameStr);
|
||||
}
|
||||
|
||||
LandingPadInst::LandingPadInst(Type *RetTy, Value *PersonalityFn,
|
||||
unsigned NumReservedValues, const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertAtEnd) {
|
||||
init(PersonalityFn, 1 + NumReservedValues, 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];
|
||||
|
||||
setCleanup(LP.isCleanup());
|
||||
}
|
||||
|
||||
LandingPadInst::~LandingPadInst() {
|
||||
dropHungoffUses();
|
||||
}
|
||||
|
||||
LandingPadInst *LandingPadInst::Create(Type *RetTy, Value *PersonalityFn,
|
||||
unsigned NumReservedClauses,
|
||||
const Twine &NameStr,
|
||||
Instruction *InsertBefore) {
|
||||
return new LandingPadInst(RetTy, PersonalityFn, NumReservedClauses, NameStr,
|
||||
InsertBefore);
|
||||
}
|
||||
|
||||
LandingPadInst *LandingPadInst::Create(Type *RetTy, Value *PersonalityFn,
|
||||
unsigned NumReservedClauses,
|
||||
const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
return new LandingPadInst(RetTy, PersonalityFn, NumReservedClauses, NameStr,
|
||||
InsertAtEnd);
|
||||
}
|
||||
|
||||
void LandingPadInst::init(Value *PersFn, unsigned NumReservedValues,
|
||||
const Twine &NameStr) {
|
||||
ReservedSpace = NumReservedValues;
|
||||
NumOperands = 1;
|
||||
OperandList = allocHungoffUses(ReservedSpace);
|
||||
OperandList[0] = PersFn;
|
||||
setName(NameStr);
|
||||
setCleanup(false);
|
||||
}
|
||||
|
||||
/// 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 Size) {
|
||||
unsigned e = getNumOperands();
|
||||
if (ReservedSpace >= e + Size) return;
|
||||
ReservedSpace = (e + Size / 2) * 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(Value *Val) {
|
||||
unsigned OpNo = getNumOperands();
|
||||
growOperands(1);
|
||||
assert(OpNo < ReservedSpace && "Growing didn't work!");
|
||||
++NumOperands;
|
||||
OperandList[OpNo] = Val;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CallInst Implementation
|
||||
@ -494,6 +576,9 @@ void InvokeInst::removeAttribute(unsigned i, Attributes attr) {
|
||||
setAttributes(PAL);
|
||||
}
|
||||
|
||||
LandingPadInst *InvokeInst::getLandingPadInst() const {
|
||||
return cast<LandingPadInst>(getUnwindDest()->getFirstNonPHI());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ReturnInst Implementation
|
||||
@ -3344,6 +3429,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);
|
||||
}
|
||||
|
@ -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;
|
||||
@ -165,6 +175,7 @@ namespace {
|
||||
|
||||
visit(F);
|
||||
InstsInThisBlock.clear();
|
||||
PersonalityFn = 0;
|
||||
|
||||
// If this is a real pass, in a pass manager, we must abort before
|
||||
// returning back to the pass manager, or else the pass manager may try to
|
||||
@ -284,6 +295,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,
|
||||
@ -1401,6 +1413,39 @@ 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.
|
||||
Assert1(LPI.getParent()->getLandingPadInst() == &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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user