summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm-c/Core.h14
-rw-r--r--llvm/include/llvm/Bitcode/LLVMBitCodes.h6
-rw-r--r--llvm/include/llvm/IR/BasicBlock.h3
-rw-r--r--llvm/include/llvm/IR/IRBuilder.h32
-rw-r--r--llvm/include/llvm/IR/InstVisitor.h6
-rw-r--r--llvm/include/llvm/IR/InstrTypes.h16
-rw-r--r--llvm/include/llvm/IR/Instruction.def142
-rw-r--r--llvm/include/llvm/IR/Instruction.h14
-rw-r--r--llvm/include/llvm/IR/Instructions.h520
9 files changed, 684 insertions, 69 deletions
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index 713894f5763..48ae289f966 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -248,7 +248,13 @@ typedef enum {
/* Exception Handling Operators */
LLVMResume = 58,
- LLVMLandingPad = 59
+ LLVMLandingPad = 59,
+ LLVMCleanupRet = 61,
+ LLVMCatchRet = 62,
+ LLVMCatchBlock = 63,
+ LLVMTerminateBlock = 64,
+ LLVMCleanupBlock = 65,
+ LLVMCatchEndBlock = 66
} LLVMOpcode;
@@ -1203,6 +1209,7 @@ LLVMTypeRef LLVMX86MMXType(void);
macro(InsertElementInst) \
macro(InsertValueInst) \
macro(LandingPadInst) \
+ macro(CleanupBlockInst) \
macro(PHINode) \
macro(SelectInst) \
macro(ShuffleVectorInst) \
@@ -1215,6 +1222,11 @@ LLVMTypeRef LLVMX86MMXType(void);
macro(SwitchInst) \
macro(UnreachableInst) \
macro(ResumeInst) \
+ macro(CleanupReturnInst) \
+ macro(CatchReturnInst) \
+ macro(CatchBlockInst) \
+ macro(TerminateBlockInst) \
+ macro(CatchEndBlockInst) \
macro(UnaryInstruction) \
macro(AllocaInst) \
macro(CastInst) \
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index 605c4172dd8..28452757fb2 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -354,6 +354,12 @@ namespace bitc {
FUNC_CODE_INST_CMPXCHG = 46, // CMPXCHG: [ptrty,ptr,valty,cmp,new, align,
// vol,ordering,synchscope]
FUNC_CODE_INST_LANDINGPAD = 47, // LANDINGPAD: [ty,val,num,id0,val0...]
+ FUNC_CODE_INST_CLEANUPRET = 48, // CLEANUPRET: [] or [val] or [bb#] or [val,bb#]
+ FUNC_CODE_INST_CATCHRET = 49, // CATCHRET: [bb#]
+ FUNC_CODE_INST_CATCHBLOCK = 50, // CATCHBLOCK: [ty,val,val,num,args...]
+ FUNC_CODE_INST_TERMINATEBLOCK = 51, // TERMINATEBLOCK: [bb#,num,args...]
+ FUNC_CODE_INST_CLEANUPBLOCK = 52, // CLEANUPBLOCK: [num,args...]
+ FUNC_CODE_INST_CATCHENDBLOCK = 53, // CATCHENDBLOCK: [] or [bb#]
};
enum UseListCodes {
diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h
index 66581bfedbe..5189d8f6a46 100644
--- a/llvm/include/llvm/IR/BasicBlock.h
+++ b/llvm/include/llvm/IR/BasicBlock.h
@@ -309,6 +309,9 @@ public:
/// basic block \p New instead of to it.
void replaceSuccessorsPhiUsesWith(BasicBlock *New);
+ /// \brief Return true if this basic block is an exception handling block.
+ bool isEHBlock() const { return getFirstNonPHI()->isEHBlock(); }
+
/// \brief Return true if this basic block is a landing pad.
///
/// Being a ``landing pad'' means that the basic block is the destination of
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index e6b5393c339..9f6fd3453fd 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -672,6 +672,38 @@ public:
return Insert(ResumeInst::Create(Exn));
}
+ CleanupReturnInst *CreateCleanupRet(BasicBlock *UnwindBB = nullptr,
+ Value *RetVal = nullptr) {
+ return Insert(CleanupReturnInst::Create(Context, RetVal, UnwindBB));
+ }
+
+ CatchBlockInst *CreateCatchBlock(Type *Ty, BasicBlock *NormalDest,
+ BasicBlock *UnwindDest,
+ ArrayRef<Value *> Args,
+ const Twine &Name = "") {
+ return Insert(CatchBlockInst::Create(Ty, NormalDest, UnwindDest, Args),
+ Name);
+ }
+
+ CatchEndBlockInst *CreateCatchEndBlock(BasicBlock *UnwindBB = nullptr) {
+ return Insert(CatchEndBlockInst::Create(Context, UnwindBB));
+ }
+
+ TerminateBlockInst *CreateTerminateBlock(BasicBlock *NormalDest = nullptr,
+ ArrayRef<Value *> Args = {},
+ const Twine &Name = "") {
+ return Insert(TerminateBlockInst::Create(Context, NormalDest, Args), Name);
+ }
+
+ CleanupBlockInst *CreateCleanupBlock(Type *Ty, ArrayRef<Value *> Args,
+ const Twine &Name = "") {
+ return Insert(CleanupBlockInst::Create(Ty, Args), Name);
+ }
+
+ CatchReturnInst *CreateCatchRet(BasicBlock *BB) {
+ return Insert(CatchReturnInst::Create(BB));
+ }
+
UnreachableInst *CreateUnreachable() {
return Insert(new UnreachableInst(Context));
}
diff --git a/llvm/include/llvm/IR/InstVisitor.h b/llvm/include/llvm/IR/InstVisitor.h
index 581e860b838..37841c77162 100644
--- a/llvm/include/llvm/IR/InstVisitor.h
+++ b/llvm/include/llvm/IR/InstVisitor.h
@@ -169,6 +169,11 @@ public:
RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);}
RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);}
RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitCleanupReturnInst(CleanupReturnInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitCatchReturnInst(CatchReturnInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitCatchBlockInst(CatchBlockInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitCatchEndBlockInst(CatchEndBlockInst &I) { DELEGATE(TerminatorInst); }
+ RetTy visitTerminateBlockInst(TerminateBlockInst &I) { DELEGATE(TerminatorInst);}
RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(UnaryInstruction);}
@@ -200,6 +205,7 @@ public:
RetTy visitExtractValueInst(ExtractValueInst &I){ DELEGATE(UnaryInstruction);}
RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); }
RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); }
+ RetTy visitCleanupBlockInst(CleanupBlockInst &I) { DELEGATE(Instruction); }
// Handle the special instrinsic instruction classes.
RetTy visitDbgDeclareInst(DbgDeclareInst &I) { DELEGATE(DbgInfoIntrinsic);}
diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index b791ded0e19..318fb2ef0bf 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -75,6 +75,22 @@ public:
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
+
+ // \brief Returns true if this terminator relates to exception handling.
+ bool isExceptional() const {
+ switch (getOpcode()) {
+ case Instruction::CatchBlock:
+ case Instruction::CatchEndBlock:
+ case Instruction::CatchRet:
+ case Instruction::CleanupRet:
+ case Instruction::Invoke:
+ case Instruction::Resume:
+ case Instruction::TerminateBlock:
+ return true;
+ default:
+ return false;
+ }
+ }
};
diff --git a/llvm/include/llvm/IR/Instruction.def b/llvm/include/llvm/IR/Instruction.def
index d46314cc761..801cc44a86e 100644
--- a/llvm/include/llvm/IR/Instruction.def
+++ b/llvm/include/llvm/IR/Instruction.def
@@ -94,86 +94,92 @@
// instructions for it to be a well formed basic block.
//
FIRST_TERM_INST ( 1)
-HANDLE_TERM_INST ( 1, Ret , ReturnInst)
-HANDLE_TERM_INST ( 2, Br , BranchInst)
-HANDLE_TERM_INST ( 3, Switch , SwitchInst)
-HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst)
-HANDLE_TERM_INST ( 5, Invoke , InvokeInst)
-HANDLE_TERM_INST ( 6, Resume , ResumeInst)
-HANDLE_TERM_INST ( 7, Unreachable, UnreachableInst)
- LAST_TERM_INST ( 7)
+HANDLE_TERM_INST ( 1, Ret , ReturnInst)
+HANDLE_TERM_INST ( 2, Br , BranchInst)
+HANDLE_TERM_INST ( 3, Switch , SwitchInst)
+HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst)
+HANDLE_TERM_INST ( 5, Invoke , InvokeInst)
+HANDLE_TERM_INST ( 6, Resume , ResumeInst)
+HANDLE_TERM_INST ( 7, Unreachable , UnreachableInst)
+HANDLE_TERM_INST ( 8, CleanupRet , CleanupReturnInst)
+HANDLE_TERM_INST ( 9, CatchRet , CatchReturnInst)
+HANDLE_TERM_INST (10, CatchBlock , CatchBlockInst)
+HANDLE_TERM_INST (11, TerminateBlock, TerminateBlockInst)
+HANDLE_TERM_INST (12, CatchEndBlock , CatchEndBlockInst)
+ LAST_TERM_INST (12)
// 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(13)
+HANDLE_BINARY_INST(13, Add , BinaryOperator)
+HANDLE_BINARY_INST(14, FAdd , BinaryOperator)
+HANDLE_BINARY_INST(15, Sub , BinaryOperator)
+HANDLE_BINARY_INST(16, FSub , BinaryOperator)
+HANDLE_BINARY_INST(17, Mul , BinaryOperator)
+HANDLE_BINARY_INST(18, FMul , BinaryOperator)
+HANDLE_BINARY_INST(19, UDiv , BinaryOperator)
+HANDLE_BINARY_INST(20, SDiv , BinaryOperator)
+HANDLE_BINARY_INST(21, FDiv , BinaryOperator)
+HANDLE_BINARY_INST(22, URem , BinaryOperator)
+HANDLE_BINARY_INST(23, SRem , BinaryOperator)
+HANDLE_BINARY_INST(24, 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(25, Shl , BinaryOperator) // Shift left (logical)
+HANDLE_BINARY_INST(26, LShr , BinaryOperator) // Shift right (logical)
+HANDLE_BINARY_INST(27, AShr , BinaryOperator) // Shift right (arithmetic)
+HANDLE_BINARY_INST(28, And , BinaryOperator)
+HANDLE_BINARY_INST(29, Or , BinaryOperator)
+HANDLE_BINARY_INST(30, Xor , BinaryOperator)
+ LAST_BINARY_INST(30)
// 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 )
-HANDLE_MEMORY_INST(31, AtomicCmpXchg , AtomicCmpXchgInst )
-HANDLE_MEMORY_INST(32, AtomicRMW , AtomicRMWInst )
- LAST_MEMORY_INST(32)
+ FIRST_MEMORY_INST(31)
+HANDLE_MEMORY_INST(31, Alloca, AllocaInst) // Stack management
+HANDLE_MEMORY_INST(32, Load , LoadInst ) // Memory manipulation instrs
+HANDLE_MEMORY_INST(33, Store , StoreInst )
+HANDLE_MEMORY_INST(34, GetElementPtr, GetElementPtrInst)
+HANDLE_MEMORY_INST(35, Fence , FenceInst )
+HANDLE_MEMORY_INST(36, AtomicCmpXchg , AtomicCmpXchgInst )
+HANDLE_MEMORY_INST(37, AtomicRMW , AtomicRMWInst )
+ LAST_MEMORY_INST(37)
// Cast operators ...
// NOTE: The order matters here because CastInst::isEliminableCastPair
// NOTE: (see Instructions.cpp) encodes a table based on this ordering.
- FIRST_CAST_INST(33)
-HANDLE_CAST_INST(33, Trunc , TruncInst ) // Truncate integers
-HANDLE_CAST_INST(34, ZExt , ZExtInst ) // Zero extend integers
-HANDLE_CAST_INST(35, SExt , SExtInst ) // Sign extend integers
-HANDLE_CAST_INST(36, FPToUI , FPToUIInst ) // floating point -> UInt
-HANDLE_CAST_INST(37, FPToSI , FPToSIInst ) // floating point -> SInt
-HANDLE_CAST_INST(38, UIToFP , UIToFPInst ) // UInt -> floating point
-HANDLE_CAST_INST(39, SIToFP , SIToFPInst ) // SInt -> floating point
-HANDLE_CAST_INST(40, FPTrunc , FPTruncInst ) // Truncate floating point
-HANDLE_CAST_INST(41, FPExt , FPExtInst ) // Extend floating point
-HANDLE_CAST_INST(42, PtrToInt, PtrToIntInst) // Pointer -> Integer
-HANDLE_CAST_INST(43, IntToPtr, IntToPtrInst) // Integer -> Pointer
-HANDLE_CAST_INST(44, BitCast , BitCastInst ) // Type cast
-HANDLE_CAST_INST(45, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast
- LAST_CAST_INST(45)
+ FIRST_CAST_INST(38)
+HANDLE_CAST_INST(38, Trunc , TruncInst ) // Truncate integers
+HANDLE_CAST_INST(39, ZExt , ZExtInst ) // Zero extend integers
+HANDLE_CAST_INST(40, SExt , SExtInst ) // Sign extend integers
+HANDLE_CAST_INST(41, FPToUI , FPToUIInst ) // floating point -> UInt
+HANDLE_CAST_INST(42, FPToSI , FPToSIInst ) // floating point -> SInt
+HANDLE_CAST_INST(43, UIToFP , UIToFPInst ) // UInt -> floating point
+HANDLE_CAST_INST(44, SIToFP , SIToFPInst ) // SInt -> floating point
+HANDLE_CAST_INST(45, FPTrunc , FPTruncInst ) // Truncate floating point
+HANDLE_CAST_INST(46, FPExt , FPExtInst ) // Extend floating point
+HANDLE_CAST_INST(47, PtrToInt, PtrToIntInst) // Pointer -> Integer
+HANDLE_CAST_INST(48, IntToPtr, IntToPtrInst) // Integer -> Pointer
+HANDLE_CAST_INST(49, BitCast , BitCastInst ) // Type cast
+HANDLE_CAST_INST(50, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast
+ LAST_CAST_INST(50)
// Other operators...
- FIRST_OTHER_INST(46)
-HANDLE_OTHER_INST(46, ICmp , ICmpInst ) // Integer comparison instruction
-HANDLE_OTHER_INST(47, FCmp , FCmpInst ) // Floating point comparison instr.
-HANDLE_OTHER_INST(48, PHI , PHINode ) // PHI node instruction
-HANDLE_OTHER_INST(49, Call , CallInst ) // Call a function
-HANDLE_OTHER_INST(50, Select , SelectInst ) // select instruction
-HANDLE_OTHER_INST(51, UserOp1, Instruction) // May be used internally in a pass
-HANDLE_OTHER_INST(52, UserOp2, Instruction) // Internal to passes only
-HANDLE_OTHER_INST(53, VAArg , VAArgInst ) // vaarg instruction
-HANDLE_OTHER_INST(54, ExtractElement, ExtractElementInst)// extract from vector
-HANDLE_OTHER_INST(55, InsertElement, InsertElementInst) // insert into vector
-HANDLE_OTHER_INST(56, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
-HANDLE_OTHER_INST(57, ExtractValue, ExtractValueInst)// extract from aggregate
-HANDLE_OTHER_INST(58, InsertValue, InsertValueInst) // insert into aggregate
-HANDLE_OTHER_INST(59, LandingPad, LandingPadInst) // Landing pad instruction.
- LAST_OTHER_INST(59)
+ FIRST_OTHER_INST(51)
+HANDLE_OTHER_INST(51, ICmp , ICmpInst ) // Integer comparison instruction
+HANDLE_OTHER_INST(52, FCmp , FCmpInst ) // Floating point comparison instr.
+HANDLE_OTHER_INST(53, PHI , PHINode ) // PHI node instruction
+HANDLE_OTHER_INST(54, Call , CallInst ) // Call a function
+HANDLE_OTHER_INST(55, Select , SelectInst ) // select instruction
+HANDLE_OTHER_INST(56, UserOp1, Instruction) // May be used internally in a pass
+HANDLE_OTHER_INST(57, UserOp2, Instruction) // Internal to passes only
+HANDLE_OTHER_INST(58, VAArg , VAArgInst ) // vaarg instruction
+HANDLE_OTHER_INST(59, ExtractElement, ExtractElementInst)// extract from vector
+HANDLE_OTHER_INST(60, InsertElement, InsertElementInst) // insert into vector
+HANDLE_OTHER_INST(61, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
+HANDLE_OTHER_INST(62, ExtractValue, ExtractValueInst)// extract from aggregate
+HANDLE_OTHER_INST(63, InsertValue, InsertValueInst) // insert into aggregate
+HANDLE_OTHER_INST(64, LandingPad, LandingPadInst) // Landing pad instruction.
+HANDLE_OTHER_INST(65, CleanupBlock, CleanupBlockInst)
+ LAST_OTHER_INST(65)
#undef FIRST_TERM_INST
#undef HANDLE_TERM_INST
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index 31f363f70a5..a81c97db96e 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -388,6 +388,20 @@ public:
return mayWriteToMemory() || mayThrow() || !mayReturn();
}
+ /// \brief Return true if the instruction is a variety of EH-block.
+ bool isEHBlock() const {
+ switch (getOpcode()) {
+ case Instruction::CatchBlock:
+ case Instruction::CatchEndBlock:
+ case Instruction::CleanupBlock:
+ case Instruction::LandingPad:
+ case Instruction::TerminateBlock:
+ return true;
+ default:
+ return false;
+ }
+ }
+
/// clone() - Create a copy of 'this' instruction that is identical in all
/// ways except the following:
/// * The instruction has no parent
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index 62723e44c0c..82c9a69838f 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -3552,6 +3552,526 @@ struct OperandTraits<ResumeInst> :
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
//===----------------------------------------------------------------------===//
+// CleanupReturnInst Class
+//===----------------------------------------------------------------------===//
+
+class CleanupReturnInst : public TerminatorInst {
+ CleanupReturnInst(const CleanupReturnInst &RI);
+
+private:
+ void init(Value *RetVal, BasicBlock *UnwindBB);
+ CleanupReturnInst(LLVMContext &C, Value *RetVal, BasicBlock *UnwindBB,
+ unsigned Values, Instruction *InsertBefore = nullptr);
+ CleanupReturnInst(LLVMContext &C, Value *RetVal, BasicBlock *UnwindBB,
+ unsigned Values, BasicBlock *InsertAtEnd);
+
+ int getUnwindLabelOpIdx() const {
+ assert(hasUnwindDest());
+ return 0;
+ }
+
+ int getRetValOpIdx() const {
+ assert(hasReturnValue());
+ if (hasUnwindDest())
+ return 1;
+ return 0;
+ }
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ CleanupReturnInst *cloneImpl() const;
+
+public:
+ static CleanupReturnInst *Create(LLVMContext &C,
+ Value *RetVal = nullptr,
+ BasicBlock *UnwindBB = nullptr,
+ Instruction *InsertBefore = nullptr) {
+ unsigned Values = 0;
+ if (RetVal)
+ ++Values;
+ if (UnwindBB)
+ ++Values;
+ return new (Values)
+ CleanupReturnInst(C, RetVal, UnwindBB, Values, InsertBefore);
+ }
+ static CleanupReturnInst *Create(LLVMContext &C, Value *RetVal,
+ BasicBlock *UnwindBB,
+ BasicBlock *InsertAtEnd) {
+ unsigned Values = 0;
+ if (RetVal)
+ ++Values;
+ if (UnwindBB)
+ ++Values;
+ return new (Values)
+ CleanupReturnInst(C, RetVal, UnwindBB, Values, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
+ bool unwindsToCaller() const { return !hasUnwindDest(); }
+ bool hasReturnValue() const { return getSubclassDataFromInstruction() & 2; }
+
+ /// Convenience accessor. Returns null if there is no return value.
+ Value *getReturnValue() const {
+ if (!hasReturnValue())
+ return nullptr;
+ return getOperand(getRetValOpIdx());
+ }
+ void setReturnValue(Value *RetVal) {
+ assert(hasReturnValue());
+ setOperand(getRetValOpIdx(), RetVal);
+ }
+
+ unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
+
+ BasicBlock *getUnwindDest() const;
+ void setUnwindDest(BasicBlock *NewDest);
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::CleanupRet);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ BasicBlock *getSuccessorV(unsigned Idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<CleanupReturnInst>
+ : public VariadicOperandTraits<CleanupReturnInst> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value)
+
+//===----------------------------------------------------------------------===//
+// CatchEndBlockInst Class
+//===----------------------------------------------------------------------===//
+
+class CatchEndBlockInst : public TerminatorInst {
+ CatchEndBlockInst(const CatchEndBlockInst &RI);
+
+private:
+ void init(BasicBlock *UnwindBB);
+ CatchEndBlockInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
+ Instruction *InsertBefore = nullptr);
+ CatchEndBlockInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
+ BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ CatchEndBlockInst *cloneImpl() const;
+
+public:
+ static CatchEndBlockInst *Create(LLVMContext &C,
+ BasicBlock *UnwindBB = nullptr,
+ Instruction *InsertBefore = nullptr) {
+ unsigned Values = UnwindBB ? 1 : 0;
+ return new (Values) CatchEndBlockInst(C, UnwindBB, Values, InsertBefore);
+ }
+ static CatchEndBlockInst *Create(LLVMContext &C, BasicBlock *UnwindBB,
+ BasicBlock *InsertAtEnd) {
+ unsigned Values = UnwindBB ? 1 : 0;
+ return new (Values) CatchEndBlockInst(C, UnwindBB, Values, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
+ bool unwindsToCaller() const { return !hasUnwindDest(); }
+
+ /// Convenience accessor. Returns null if there is no return value.
+ unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
+
+ BasicBlock *getUnwindDest() const { return cast<BasicBlock>(Op<-1>()); }
+ void setUnwindDest(BasicBlock *NewDest) {
+ assert(NewDest);
+ Op<-1>() = NewDest;
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::CatchEndBlock);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ BasicBlock *getSuccessorV(unsigned Idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+
+private:
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<CatchEndBlockInst>
+ : public VariadicOperandTraits<CatchEndBlockInst> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchEndBlockInst, Value)
+
+//===----------------------------------------------------------------------===//
+// CatchBlockInst Class
+//===----------------------------------------------------------------------===//
+
+class CatchBlockInst : public TerminatorInst {
+private:
+ void init(BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, const Twine &NameStr);
+
+ CatchBlockInst(const CatchBlockInst &CBI);
+
+ explicit CatchBlockInst(Type *RetTy, BasicBlock *IfNormal,
+ BasicBlock *IfException, ArrayRef<Value *> Args,
+ unsigned Values, const Twine &NameStr,
+ Instruction *InsertBefore);
+ explicit CatchBlockInst(Type *RetTy, BasicBlock *IfNormal,
+ BasicBlock *IfException, ArrayRef<Value *> Args,
+ unsigned Values, const Twine &NameStr,
+ BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ CatchBlockInst *cloneImpl() const;
+
+public:
+ static CatchBlockInst *Create(Type *RetTy, BasicBlock *IfNormal,
+ BasicBlock *IfException, ArrayRef<Value *> Args,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
+ unsigned Values = unsigned(Args.size()) + 2;
+ return new (Values) CatchBlockInst(RetTy, IfNormal, IfException, Args,
+ Values, NameStr, InsertBefore);
+ }
+ static CatchBlockInst *Create(Type *RetTy, BasicBlock *IfNormal,
+ BasicBlock *IfException, ArrayRef<Value *> Args,
+ const Twine &NameStr, BasicBlock *InsertAtEnd) {
+ unsigned Values = unsigned(Args.size()) + 2;
+ return new (Values) CatchBlockInst(RetTy, IfNormal, IfException, Args,
+ Values, NameStr, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// getNumArgOperands - Return the number of catchblock arguments.
+ ///
+ unsigned getNumArgOperands() const { return getNumOperands() - 2; }
+
+ /// getArgOperand/setArgOperand - Return/set the i-th catchblock argument.
+ ///
+ Value *getArgOperand(unsigned i) const { return getOperand(i); }
+ void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+
+ /// arg_operands - iteration adapter for range-for loops.
+ iterator_range<op_iterator> arg_operands() {
+ return iterator_range<op_iterator>(op_begin(), op_end() - 2);
+ }
+
+ /// arg_operands - iteration adapter for range-for loops.
+ iterator_range<const_op_iterator> arg_operands() const {
+ return iterator_range<const_op_iterator>(op_begin(), op_end() - 2);
+ }
+
+ /// \brief Wrappers for getting the \c Use of a catchblock argument.
+ const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
+ Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
+
+ // get*Dest - Return the destination basic blocks...
+ BasicBlock *getNormalDest() const { return cast<BasicBlock>(Op<-2>()); }
+ BasicBlock *getUnwindDest() const { return cast<BasicBlock>(Op<-1>()); }
+ void setNormalDest(BasicBlock *B) { Op<-2>() = reinterpret_cast<Value *>(B); }
+ void setUnwindDest(BasicBlock *B) { Op<-1>() = reinterpret_cast<Value *>(B); }
+
+ BasicBlock *getSuccessor(unsigned i) const {
+ assert(i < 2 && "Successor # out of range for invoke!");
+ return i == 0 ? getNormalDest() : getUnwindDest();
+ }
+
+ void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
+ assert(idx < 2 && "Successor # out of range for invoke!");
+ *(&Op<-2>() + idx) = reinterpret_cast<Value *>(NewSucc);
+ }
+
+ unsigned getNumSuccessors() const { return 2; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::CatchBlock;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ BasicBlock *getSuccessorV(unsigned idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned idx, BasicBlock *B) override;
+};
+
+template <>
+struct OperandTraits<CatchBlockInst>
+ : public VariadicOperandTraits<CatchBlockInst, /*MINARITY=*/2> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchBlockInst, Value)
+
+//===----------------------------------------------------------------------===//
+// TerminateBlockInst Class
+//===----------------------------------------------------------------------===//
+
+class TerminateBlockInst : public TerminatorInst {
+private:
+ void init(BasicBlock *BB, ArrayRef<Value *> Args, const Twine &NameStr);
+
+ TerminateBlockInst(const TerminateBlockInst &TBI);
+
+ explicit TerminateBlockInst(LLVMContext &C, BasicBlock *BB,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, Instruction *InsertBefore);
+ explicit TerminateBlockInst(LLVMContext &C, BasicBlock *BB,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ TerminateBlockInst *cloneImpl() const;
+
+public:
+ static TerminateBlockInst *Create(LLVMContext &C, BasicBlock *BB = nullptr,
+ ArrayRef<Value *> Args = {},
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
+ unsigned Values = unsigned(Args.size());
+ if (BB)
+ ++Values;
+ return new (Values)
+ TerminateBlockInst(C, BB, Args, Values, NameStr, InsertBefore);
+ }
+ static TerminateBlockInst *Create(LLVMContext &C, BasicBlock *BB,
+ ArrayRef<Value *> Args,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ unsigned Values = unsigned(Args.size());
+ if (BB)
+ ++Values;
+ return new (Values)
+ TerminateBlockInst(C, BB, Args, Values, NameStr, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
+ bool unwindsToCaller() const { return !hasUnwindDest(); }
+
+ /// getNumArgOperands - Return the number of terminateblock arguments.
+ ///
+ unsigned getNumArgOperands() const {
+ unsigned NumOperands = getNumOperands();
+ if (hasUnwindDest())
+ return NumOperands - 1;
+ return NumOperands;
+ }
+
+ /// getArgOperand/setArgOperand - Return/set the i-th terminateblock argument.
+ ///
+ Value *getArgOperand(unsigned i) const { return getOperand(i); }
+ void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+
+ const_op_iterator arg_end() const {
+ if (hasUnwindDest())
+ return op_end() - 1;
+ return op_end();
+ }
+
+ op_iterator arg_end() {
+ if (hasUnwindDest())
+ return op_end() - 1;
+ return op_end();
+ }
+
+ /// arg_operands - iteration adapter for range-for loops.
+ iterator_range<op_iterator> arg_operands() {
+ return iterator_range<op_iterator>(op_begin(), arg_end());
+ }
+
+ /// arg_operands - iteration adapter for range-for loops.
+ iterator_range<const_op_iterator> arg_operands() const {
+ return iterator_range<const_op_iterator>(op_begin(), arg_end());
+ }
+
+ /// \brief Wrappers for getting the \c Use of a terminateblock argument.
+ const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
+ Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
+
+ // get*Dest - Return the destination basic blocks...
+ BasicBlock *getUnwindDest() const {
+ if (!hasUnwindDest())
+ return nullptr;
+ return cast<BasicBlock>(Op<-1>());
+ }
+ void setUnwindDest(BasicBlock *B) {
+ assert(B && hasUnwindDest());
+ Op<-1>() = reinterpret_cast<Value *>(B);
+ }
+
+ unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::TerminateBlock;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ BasicBlock *getSuccessorV(unsigned idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned idx, BasicBlock *B) override;
+
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<TerminateBlockInst>
+ : public VariadicOperandTraits<TerminateBlockInst, /*MINARITY=*/1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(TerminateBlockInst, Value)
+
+//===----------------------------------------------------------------------===//
+// CleanupBlockInst Class
+//===----------------------------------------------------------------------===//
+
+class CleanupBlockInst : public Instruction {
+private:
+ void init(ArrayRef<Value *> Args, const Twine &NameStr);
+
+ CleanupBlockInst(const CleanupBlockInst &TBI);
+
+ explicit CleanupBlockInst(Type *RetTy, ArrayRef<Value *> Args,
+ const Twine &NameStr, Instruction *InsertBefore);
+ explicit CleanupBlockInst(Type *RetTy, ArrayRef<Value *> Args,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ CleanupBlockInst *cloneImpl() const;
+
+public:
+ static CleanupBlockInst *Create(Type *RetTy, ArrayRef<Value *> Args,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
+ return new (Args.size())
+ CleanupBlockInst(RetTy, Args, NameStr, InsertBefore);
+ }
+ static CleanupBlockInst *Create(Type *RetTy, ArrayRef<Value *> Args,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ return new (Args.size())
+ CleanupBlockInst(RetTy, Args, NameStr, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::CleanupBlock;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+template <>
+struct OperandTraits<CleanupBlockInst>
+ : public VariadicOperandTraits<CleanupBlockInst, /*MINARITY=*/0> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupBlockInst, Value)
+
+//===----------------------------------------------------------------------===//
+// CatchReturnInst Class
+//===----------------------------------------------------------------------===//
+
+class CatchReturnInst : public TerminatorInst {
+ CatchReturnInst(const CatchReturnInst &RI);
+
+private:
+ void init(Value *RetVal, BasicBlock *UnwindBB);
+ CatchReturnInst(BasicBlock *BB, Instruction *InsertBefore = nullptr);
+ CatchReturnInst(BasicBlock *BB, BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ CatchReturnInst *cloneImpl() const;
+
+public:
+ static CatchReturnInst *Create(BasicBlock *BB,
+ Instruction *InsertBefore = nullptr) {
+ return new (1) CatchReturnInst(BB, InsertBefore);
+ }
+ static CatchReturnInst *Create(BasicBlock *BB, BasicBlock *InsertAtEnd) {
+ return new (1) CatchReturnInst(BB, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// Convenience accessors.
+ BasicBlock *getSuccessor() const { return cast<BasicBlock>(Op<0>()); }
+ void setSuccessor(BasicBlock *NewSucc) { Op<0>() = (Value *)NewSucc; }
+ unsigned getNumSuccessors() const { return 1; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::CatchRet);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ BasicBlock *getSuccessorV(unsigned Idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+};
+
+template <>
+struct OperandTraits<CatchReturnInst>
+ : public FixedNumOperandTraits<CatchReturnInst, /*ARITY=*/1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value)
+
+//===----------------------------------------------------------------------===//
// UnreachableInst Class
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud