summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2011-08-12 20:24:12 +0000
committerBill Wendling <isanbard@gmail.com>2011-08-12 20:24:12 +0000
commite6e8826870bee3facb04f950f0bd725f8a88623d (patch)
tree5fe10abfdbebc25ea75271004fe7afae60a3943e /include
parent79628e92e1f903d50340d4cd3d1ea8c5fff63a87 (diff)
downloadllvm-e6e8826870bee3facb04f950f0bd725f8a88623d.tar.gz
llvm-e6e8826870bee3facb04f950f0bd725f8a88623d.tar.bz2
llvm-e6e8826870bee3facb04f950f0bd725f8a88623d.tar.xz
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137501 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm-c/Core.h15
-rw-r--r--include/llvm/BasicBlock.h9
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h5
-rw-r--r--include/llvm/Instruction.def3
-rw-r--r--include/llvm/Instructions.h109
-rw-r--r--include/llvm/Support/IRBuilder.h5
-rw-r--r--include/llvm/Support/InstVisitor.h1
7 files changed, 143 insertions, 4 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index 0acf5a23af..2562757a2e 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -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);
diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h
index 3b953c06a8..d5966290a1 100644
--- a/include/llvm/BasicBlock.h
+++ b/include/llvm/BasicBlock.h
@@ -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
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index e2e5f0b087..4b0dcc3623 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -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
diff --git a/include/llvm/Instruction.def b/include/llvm/Instruction.def
index 2e02b670cf..d36e4be1d9 100644
--- a/include/llvm/Instruction.def
+++ b/include/llvm/Instruction.def
@@ -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
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index 4103362dd8..2b681abbbd 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -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();
diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h
index 133b1c3fd5..782800173f 100644
--- a/include/llvm/Support/IRBuilder.h
+++ b/include/llvm/Support/IRBuilder.h
@@ -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
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h
index 591de6f40d..a661c4fac6 100644
--- a/include/llvm/Support/InstVisitor.h
+++ b/include/llvm/Support/InstVisitor.h
@@ -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