diff options
Diffstat (limited to 'llvm/include')
-rw-r--r-- | llvm/include/llvm-c/Core.h | 10 | ||||
-rw-r--r-- | llvm/include/llvm/Analysis/EHPersonalities.h | 11 | ||||
-rw-r--r-- | llvm/include/llvm/Bitcode/LLVMBitCodes.h | 5 | ||||
-rw-r--r-- | llvm/include/llvm/CodeGen/WinEHFuncInfo.h | 6 | ||||
-rw-r--r-- | llvm/include/llvm/IR/IRBuilder.h | 30 | ||||
-rw-r--r-- | llvm/include/llvm/IR/InstVisitor.h | 8 | ||||
-rw-r--r-- | llvm/include/llvm/IR/InstrTypes.h | 73 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Instruction.def | 120 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Instruction.h | 16 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Instructions.h | 508 | ||||
-rw-r--r-- | llvm/include/llvm/Transforms/Utils/Local.h | 4 |
11 files changed, 431 insertions, 360 deletions
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index 8157e9cf869..e84dd39092f 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -254,8 +254,7 @@ typedef enum { LLVMCatchPad = 63, LLVMTerminatePad = 64, LLVMCleanupPad = 65, - LLVMCatchEndPad = 66, - LLVMCleanupEndPad = 67 + LLVMCatchSwitch = 66 } LLVMOpcode; typedef enum { @@ -1211,7 +1210,6 @@ LLVMTypeRef LLVMX86MMXType(void); macro(InsertElementInst) \ macro(InsertValueInst) \ macro(LandingPadInst) \ - macro(CleanupPadInst) \ macro(PHINode) \ macro(SelectInst) \ macro(ShuffleVectorInst) \ @@ -1226,10 +1224,10 @@ LLVMTypeRef LLVMX86MMXType(void); macro(ResumeInst) \ macro(CleanupReturnInst) \ macro(CatchReturnInst) \ - macro(CatchPadInst) \ macro(TerminatePadInst) \ - macro(CatchEndPadInst) \ - macro(CleanupEndPadInst) \ + macro(FuncletPadInst) \ + macro(CatchPadInst) \ + macro(CleanupPadInst) \ macro(UnaryInstruction) \ macro(AllocaInst) \ macro(CastInst) \ diff --git a/llvm/include/llvm/Analysis/EHPersonalities.h b/llvm/include/llvm/Analysis/EHPersonalities.h index 4a56728fbb4..59e9672b88e 100644 --- a/llvm/include/llvm/Analysis/EHPersonalities.h +++ b/llvm/include/llvm/Analysis/EHPersonalities.h @@ -10,9 +10,12 @@ #ifndef LLVM_ANALYSIS_EHPERSONALITIES_H #define LLVM_ANALYSIS_EHPERSONALITIES_H +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/ErrorHandling.h" namespace llvm { +class BasicBlock; class Function; class Value; @@ -78,6 +81,14 @@ inline bool isNoOpWithoutInvoke(EHPersonality Pers) { bool canSimplifyInvokeNoUnwind(const Function *F); +typedef TinyPtrVector<BasicBlock *> ColorVector; + +/// \brief If an EH funclet personality is in use (see isFuncletEHPersonality), +/// this will recompute which blocks are in which funclet. It is possible that +/// some blocks are in multiple funclets. Consider this analysis to be +/// expensive. +DenseMap<BasicBlock *, ColorVector> colorEHFunclets(Function &F); + } // end namespace llvm #endif diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index 55fe05938e6..9bd3c9ea061 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -423,9 +423,8 @@ enum { BITCODE_CURRENT_EPOCH = 0 }; FUNC_CODE_INST_CATCHPAD = 50, // CATCHPAD: [bb#,bb#,num,args...] FUNC_CODE_INST_TERMINATEPAD = 51, // TERMINATEPAD: [bb#,num,args...] FUNC_CODE_INST_CLEANUPPAD = 52, // CLEANUPPAD: [num,args...] - FUNC_CODE_INST_CATCHENDPAD = 53, // CATCHENDPAD: [] or [bb#] - FUNC_CODE_INST_CLEANUPENDPAD = 54, // CLEANUPENDPAD: [val] or [val,bb#] - + FUNC_CODE_INST_CATCHSWITCH = 53, // CATCHSWITCH: [num,args...] or [num,args...,bb] + // 54 is unused. FUNC_CODE_OPERAND_BUNDLE = 55, // OPERAND_BUNDLE: [tag#, value...] }; diff --git a/llvm/include/llvm/CodeGen/WinEHFuncInfo.h b/llvm/include/llvm/CodeGen/WinEHFuncInfo.h index 5e8bb56eb61..599f8595043 100644 --- a/llvm/include/llvm/CodeGen/WinEHFuncInfo.h +++ b/llvm/include/llvm/CodeGen/WinEHFuncInfo.h @@ -89,9 +89,11 @@ struct ClrEHUnwindMapEntry { struct WinEHFuncInfo { DenseMap<const Instruction *, int> EHPadStateMap; + DenseMap<const FuncletPadInst *, int> FuncletBaseStateMap; + DenseMap<const InvokeInst *, int> InvokeStateMap; DenseMap<const CatchReturnInst *, const BasicBlock *> CatchRetSuccessorColorMap; - DenseMap<MCSymbol *, std::pair<int, MCSymbol *>> InvokeToStateMap; + DenseMap<MCSymbol *, std::pair<int, MCSymbol *>> LabelToStateMap; SmallVector<CxxUnwindMapEntry, 4> CxxUnwindMap; SmallVector<WinEHTryBlockMapEntry, 4> TryBlockMap; SmallVector<SEHUnwindMapEntry, 4> SEHUnwindMap; @@ -101,7 +103,7 @@ struct WinEHFuncInfo { int getLastStateNumber() const { return CxxUnwindMap.size() - 1; } - void addIPToStateRange(const BasicBlock *PadBB, MCSymbol *InvokeBegin, + void addIPToStateRange(const InvokeInst *II, MCSymbol *InvokeBegin, MCSymbol *InvokeEnd); int EHRegNodeFrameIndex = INT_MAX; diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index 5f0aa3374ee..2425c31c166 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -708,29 +708,29 @@ public: return Insert(CleanupReturnInst::Create(CleanupPad, UnwindBB)); } - CleanupEndPadInst *CreateCleanupEndPad(CleanupPadInst *CleanupPad, - BasicBlock *UnwindBB = nullptr) { - return Insert(CleanupEndPadInst::Create(CleanupPad, UnwindBB)); - } - - CatchPadInst *CreateCatchPad(BasicBlock *NormalDest, BasicBlock *UnwindDest, - ArrayRef<Value *> Args, const Twine &Name = "") { - return Insert(CatchPadInst::Create(NormalDest, UnwindDest, Args), Name); + CatchSwitchInst *CreateCatchSwitch(Value *ParentPad, BasicBlock *UnwindBB, + unsigned NumHandlers, + const Twine &Name = "") { + return Insert(CatchSwitchInst::Create(ParentPad, UnwindBB, NumHandlers), + Name); } - CatchEndPadInst *CreateCatchEndPad(BasicBlock *UnwindBB = nullptr) { - return Insert(CatchEndPadInst::Create(Context, UnwindBB)); + CatchPadInst *CreateCatchPad(Value *ParentPad, ArrayRef<Value *> Args, + const Twine &Name = "") { + return Insert(CatchPadInst::Create(ParentPad, Args), Name); } - TerminatePadInst *CreateTerminatePad(BasicBlock *UnwindBB = nullptr, - ArrayRef<Value *> Args = {}, + TerminatePadInst *CreateTerminatePad(Value *ParentPad, + BasicBlock *UnwindBB = nullptr, + ArrayRef<Value *> Args = None, const Twine &Name = "") { - return Insert(TerminatePadInst::Create(Context, UnwindBB, Args), Name); + return Insert(TerminatePadInst::Create(ParentPad, UnwindBB, Args), Name); } - CleanupPadInst *CreateCleanupPad(ArrayRef<Value *> Args, + CleanupPadInst *CreateCleanupPad(Value *ParentPad, + ArrayRef<Value *> Args = None, const Twine &Name = "") { - return Insert(CleanupPadInst::Create(Context, Args), Name); + return Insert(CleanupPadInst::Create(ParentPad, Args), Name); } CatchReturnInst *CreateCatchRet(CatchPadInst *CatchPad, BasicBlock *BB) { diff --git a/llvm/include/llvm/IR/InstVisitor.h b/llvm/include/llvm/IR/InstVisitor.h index 0fe88980b41..d848f91b27b 100644 --- a/llvm/include/llvm/IR/InstVisitor.h +++ b/llvm/include/llvm/IR/InstVisitor.h @@ -170,10 +170,8 @@ public: RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);} RetTy visitCleanupReturnInst(CleanupReturnInst &I) { DELEGATE(TerminatorInst);} - RetTy visitCleanupEndPadInst(CleanupEndPadInst &I) { DELEGATE(TerminatorInst); } RetTy visitCatchReturnInst(CatchReturnInst &I) { DELEGATE(TerminatorInst); } - RetTy visitCatchPadInst(CatchPadInst &I) { DELEGATE(TerminatorInst);} - RetTy visitCatchEndPadInst(CatchEndPadInst &I) { DELEGATE(TerminatorInst); } + RetTy visitCatchSwitchInst(CatchSwitchInst &I) { DELEGATE(TerminatorInst);} RetTy visitTerminatePadInst(TerminatePadInst &I) { DELEGATE(TerminatorInst);} RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);} @@ -206,7 +204,9 @@ public: RetTy visitExtractValueInst(ExtractValueInst &I){ DELEGATE(UnaryInstruction);} RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); } RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); } - RetTy visitCleanupPadInst(CleanupPadInst &I) { DELEGATE(Instruction); } + RetTy visitFuncletPadInst(FuncletPadInst &I) { DELEGATE(Instruction); } + RetTy visitCleanupPadInst(CleanupPadInst &I) { DELEGATE(FuncletPadInst); } + RetTy visitCatchPadInst(CatchPadInst &I) { DELEGATE(FuncletPadInst); } // 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 2a092726665..76430857994 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -82,10 +82,8 @@ public: // \brief Returns true if this terminator relates to exception handling. bool isExceptional() const { switch (getOpcode()) { - case Instruction::CatchPad: - case Instruction::CatchEndPad: + case Instruction::CatchSwitch: case Instruction::CatchRet: - case Instruction::CleanupEndPad: case Instruction::CleanupRet: case Instruction::Invoke: case Instruction::Resume: @@ -1112,6 +1110,75 @@ struct OperandTraits<CmpInst> : public FixedNumOperandTraits<CmpInst, 2> { DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value) +//===----------------------------------------------------------------------===// +// FuncletPadInst Class +//===----------------------------------------------------------------------===// +class FuncletPadInst : public Instruction { +private: + void init(Value *ParentPad, ArrayRef<Value *> Args, const Twine &NameStr); + + FuncletPadInst(const FuncletPadInst &CPI); + + explicit FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad, + ArrayRef<Value *> Args, unsigned Values, + const Twine &NameStr, Instruction *InsertBefore); + explicit FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad, + 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; + friend class CatchPadInst; + friend class CleanupPadInst; + FuncletPadInst *cloneImpl() const; + +public: + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + /// getNumArgOperands - Return the number of funcletpad arguments. + /// + unsigned getNumArgOperands() const { return getNumOperands() - 1; } + + /// Convenience accessors + + /// \brief Return the outer EH-pad this funclet is nested within. + /// + /// Note: This returns the associated CatchSwitchInst if this FuncletPadInst + /// is a CatchPadInst. + Value *getParentPad() const { return Op<-1>(); } + void setParentPad(Value *ParentPad) { + assert(ParentPad); + Op<-1>() = ParentPad; + } + + /// getArgOperand/setArgOperand - Return/set the i-th funcletpad 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. + op_range arg_operands() { return op_range(op_begin(), op_end() - 1); } + + /// arg_operands - iteration adapter for range-for loops. + const_op_range arg_operands() const { + return const_op_range(op_begin(), op_end() - 1); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const Instruction *I) { return I->isFuncletPad(); } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +template <> +struct OperandTraits<FuncletPadInst> + : public VariadicOperandTraits<FuncletPadInst, /*MINARITY=*/1> {}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(FuncletPadInst, Value) + /// \brief A lightweight accessor for an operand bundle meant to be passed /// around by value. struct OperandBundleUse { diff --git a/llvm/include/llvm/IR/Instruction.def b/llvm/include/llvm/IR/Instruction.def index 54e4083d15f..1f30e305196 100644 --- a/llvm/include/llvm/IR/Instruction.def +++ b/llvm/include/llvm/IR/Instruction.def @@ -74,6 +74,20 @@ #define LAST_CAST_INST(num) #endif +#ifndef FIRST_FUNCLETPAD_INST +#define FIRST_FUNCLETPAD_INST(num) +#endif +#ifndef HANDLE_FUNCLETPAD_INST +#ifndef HANDLE_INST +#define HANDLE_FUNCLETPAD_INST(num, opcode, Class) +#else +#define HANDLE_FUNCLETPAD_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class) +#endif +#endif +#ifndef LAST_FUNCLETPAD_INST +#define LAST_FUNCLETPAD_INST(num) +#endif + #ifndef FIRST_OTHER_INST #define FIRST_OTHER_INST(num) #endif @@ -102,65 +116,68 @@ 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, CatchPad , CatchPadInst) +HANDLE_TERM_INST (10, CatchSwitch , CatchSwitchInst) HANDLE_TERM_INST (11, TerminatePad , TerminatePadInst) -HANDLE_TERM_INST (12, CatchEndPad , CatchEndPadInst) -HANDLE_TERM_INST (13, CleanupEndPad , CleanupEndPadInst) - LAST_TERM_INST (13) + LAST_TERM_INST (11) // Standard binary operators... - FIRST_BINARY_INST(14) -HANDLE_BINARY_INST(14, Add , BinaryOperator) -HANDLE_BINARY_INST(15, FAdd , BinaryOperator) -HANDLE_BINARY_INST(16, Sub , BinaryOperator) -HANDLE_BINARY_INST(17, FSub , BinaryOperator) -HANDLE_BINARY_INST(18, Mul , BinaryOperator) -HANDLE_BINARY_INST(19, FMul , BinaryOperator) -HANDLE_BINARY_INST(20, UDiv , BinaryOperator) -HANDLE_BINARY_INST(21, SDiv , BinaryOperator) -HANDLE_BINARY_INST(22, FDiv , BinaryOperator) -HANDLE_BINARY_INST(23, URem , BinaryOperator) -HANDLE_BINARY_INST(24, SRem , BinaryOperator) -HANDLE_BINARY_INST(25, FRem , BinaryOperator) + FIRST_BINARY_INST(12) +HANDLE_BINARY_INST(12, Add , BinaryOperator) +HANDLE_BINARY_INST(13, FAdd , BinaryOperator) +HANDLE_BINARY_INST(14, Sub , BinaryOperator) +HANDLE_BINARY_INST(15, FSub , BinaryOperator) +HANDLE_BINARY_INST(16, Mul , BinaryOperator) +HANDLE_BINARY_INST(17, FMul , BinaryOperator) +HANDLE_BINARY_INST(18, UDiv , BinaryOperator) +HANDLE_BINARY_INST(19, SDiv , BinaryOperator) +HANDLE_BINARY_INST(20, FDiv , BinaryOperator) +HANDLE_BINARY_INST(21, URem , BinaryOperator) +HANDLE_BINARY_INST(22, SRem , BinaryOperator) +HANDLE_BINARY_INST(23, FRem , BinaryOperator) // Logical operators (integer operands) -HANDLE_BINARY_INST(26, Shl , BinaryOperator) // Shift left (logical) -HANDLE_BINARY_INST(27, LShr , BinaryOperator) // Shift right (logical) -HANDLE_BINARY_INST(28, AShr , BinaryOperator) // Shift right (arithmetic) -HANDLE_BINARY_INST(29, And , BinaryOperator) -HANDLE_BINARY_INST(30, Or , BinaryOperator) -HANDLE_BINARY_INST(31, Xor , BinaryOperator) - LAST_BINARY_INST(31) +HANDLE_BINARY_INST(24, Shl , BinaryOperator) // Shift left (logical) +HANDLE_BINARY_INST(25, LShr , BinaryOperator) // Shift right (logical) +HANDLE_BINARY_INST(26, AShr , BinaryOperator) // Shift right (arithmetic) +HANDLE_BINARY_INST(27, And , BinaryOperator) +HANDLE_BINARY_INST(28, Or , BinaryOperator) +HANDLE_BINARY_INST(29, Xor , BinaryOperator) + LAST_BINARY_INST(29) // Memory operators... - FIRST_MEMORY_INST(32) -HANDLE_MEMORY_INST(32, Alloca, AllocaInst) // Stack management -HANDLE_MEMORY_INST(33, Load , LoadInst ) // Memory manipulation instrs -HANDLE_MEMORY_INST(34, Store , StoreInst ) -HANDLE_MEMORY_INST(35, GetElementPtr, GetElementPtrInst) -HANDLE_MEMORY_INST(36, Fence , FenceInst ) -HANDLE_MEMORY_INST(37, AtomicCmpXchg , AtomicCmpXchgInst ) -HANDLE_MEMORY_INST(38, AtomicRMW , AtomicRMWInst ) - LAST_MEMORY_INST(38) + FIRST_MEMORY_INST(30) +HANDLE_MEMORY_INST(30, Alloca, AllocaInst) // Stack management +HANDLE_MEMORY_INST(31, Load , LoadInst ) // Memory manipulation instrs +HANDLE_MEMORY_INST(32, Store , StoreInst ) +HANDLE_MEMORY_INST(33, GetElementPtr, GetElementPtrInst) +HANDLE_MEMORY_INST(34, Fence , FenceInst ) +HANDLE_MEMORY_INST(35, AtomicCmpXchg , AtomicCmpXchgInst ) +HANDLE_MEMORY_INST(36, AtomicRMW , AtomicRMWInst ) + LAST_MEMORY_INST(36) // Cast operators ... // NOTE: The order matters here because CastInst::isEliminableCastPair // NOTE: (see Instructions.cpp) encodes a table based on this ordering. - FIRST_CAST_INST(39) -HANDLE_CAST_INST(39, Trunc , TruncInst ) // Truncate integers -HANDLE_CAST_INST(40, ZExt , ZExtInst ) // Zero extend integers -HANDLE_CAST_INST(41, SExt , SExtInst ) // Sign extend integers -HANDLE_CAST_INST(42, FPToUI , FPToUIInst ) // floating point -> UInt -HANDLE_CAST_INST(43, FPToSI , FPToSIInst ) // floating point -> SInt -HANDLE_CAST_INST(44, UIToFP , UIToFPInst ) // UInt -> floating point -HANDLE_CAST_INST(45, SIToFP , SIToFPInst ) // SInt -> floating point -HANDLE_CAST_INST(46, FPTrunc , FPTruncInst ) // Truncate floating point -HANDLE_CAST_INST(47, FPExt , FPExtInst ) // Extend floating point -HANDLE_CAST_INST(48, PtrToInt, PtrToIntInst) // Pointer -> Integer -HANDLE_CAST_INST(49, IntToPtr, IntToPtrInst) // Integer -> Pointer -HANDLE_CAST_INST(50, BitCast , BitCastInst ) // Type cast -HANDLE_CAST_INST(51, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast - LAST_CAST_INST(51) + FIRST_CAST_INST(37) +HANDLE_CAST_INST(37, Trunc , TruncInst ) // Truncate integers +HANDLE_CAST_INST(38, ZExt , ZExtInst ) // Zero extend integers +HANDLE_CAST_INST(39, SExt , SExtInst ) // Sign extend integers +HANDLE_CAST_INST(40, FPToUI , FPToUIInst ) // floating point -> UInt +HANDLE_CAST_INST(41, FPToSI , FPToSIInst ) // floating point -> SInt +HANDLE_CAST_INST(42, UIToFP , UIToFPInst ) // UInt -> floating point +HANDLE_CAST_INST(43, SIToFP , SIToFPInst ) // SInt -> floating point +HANDLE_CAST_INST(44, FPTrunc , FPTruncInst ) // Truncate floating point +HANDLE_CAST_INST(45, FPExt , FPExtInst ) // Extend floating point +HANDLE_CAST_INST(46, PtrToInt, PtrToIntInst) // Pointer -> Integer +HANDLE_CAST_INST(47, IntToPtr, IntToPtrInst) // Integer -> Pointer +HANDLE_CAST_INST(48, BitCast , BitCastInst ) // Type cast +HANDLE_CAST_INST(49, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast + LAST_CAST_INST(49) + + FIRST_FUNCLETPAD_INST(50) +HANDLE_FUNCLETPAD_INST(50, CleanupPad, CleanupPadInst) +HANDLE_FUNCLETPAD_INST(51, CatchPad , CatchPadInst) + LAST_FUNCLETPAD_INST(51) // Other operators... FIRST_OTHER_INST(52) @@ -178,8 +195,7 @@ HANDLE_OTHER_INST(62, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. HANDLE_OTHER_INST(63, ExtractValue, ExtractValueInst)// extract from aggregate HANDLE_OTHER_INST(64, InsertValue, InsertValueInst) // insert into aggregate HANDLE_OTHER_INST(65, LandingPad, LandingPadInst) // Landing pad instruction. -HANDLE_OTHER_INST(66, CleanupPad, CleanupPadInst) - LAST_OTHER_INST(66) + LAST_OTHER_INST(65) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST @@ -197,6 +213,10 @@ HANDLE_OTHER_INST(66, CleanupPad, CleanupPadInst) #undef HANDLE_CAST_INST #undef LAST_CAST_INST +#undef FIRST_FUNCLETPAD_INST +#undef HANDLE_FUNCLETPAD_INST +#undef LAST_FUNCLETPAD_INST + #undef FIRST_OTHER_INST #undef HANDLE_OTHER_INST #undef LAST_OTHER_INST diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h index 77ba87c6b66..d7456a2c2fc 100644 --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -109,6 +109,7 @@ public: bool isBinaryOp() const { return isBinaryOp(getOpcode()); } bool isShift() { return isShift(getOpcode()); } bool isCast() const { return isCast(getOpcode()); } + bool isFuncletPad() const { return isFuncletPad(getOpcode()); } static const char* getOpcodeName(unsigned OpCode); @@ -141,6 +142,11 @@ public: return OpCode >= CastOpsBegin && OpCode < CastOpsEnd; } + /// @brief Determine if the OpCode is one of the FuncletPadInst instructions. + static inline bool isFuncletPad(unsigned OpCode) { + return OpCode >= FuncletPadOpsBegin && OpCode < FuncletPadOpsEnd; + } + //===--------------------------------------------------------------------===// // Metadata manipulation. //===--------------------------------------------------------------------===// @@ -386,10 +392,9 @@ public: /// \brief Return true if the instruction is a variety of EH-block. bool isEHPad() const { switch (getOpcode()) { + case Instruction::CatchSwitch: case Instruction::CatchPad: - case Instruction::CatchEndPad: case Instruction::CleanupPad: - case Instruction::CleanupEndPad: case Instruction::LandingPad: case Instruction::TerminatePad: return true; @@ -478,6 +483,13 @@ public: #include "llvm/IR/Instruction.def" }; + enum FuncletPadOps { +#define FIRST_FUNCLETPAD_INST(N) FuncletPadOpsBegin = N, +#define HANDLE_FUNCLETPAD_INST(N, OPC, CLASS) OPC = N, +#define LAST_FUNCLETPAD_INST(N) FuncletPadOpsEnd = N+1 +#include "llvm/IR/Instruction.def" + }; + enum OtherOps { #define FIRST_OTHER_INST(N) OtherOpsBegin = N, #define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N, diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h index 84ab72138f0..e8171db4005 100644 --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -18,6 +18,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/iterator_range.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/CallingConv.h" @@ -3819,181 +3820,176 @@ struct OperandTraits<ResumeInst> : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value) //===----------------------------------------------------------------------===// -// CatchEndPadInst Class +// CatchSwitchInst Class //===----------------------------------------------------------------------===// +class CatchSwitchInst : public TerminatorInst { + void *operator new(size_t, unsigned) = delete; + /// ReservedSpace - The number of operands actually allocated. NumOperands is + /// the number actually in use. + unsigned ReservedSpace; + // Operand[0] = Outer scope + // Operand[1] = Unwind block destination + // Operand[n] = BasicBlock to go to on match + CatchSwitchInst(const CatchSwitchInst &CSI); + void init(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumReserved); + void growOperands(unsigned Size); + // allocate space for exactly zero operands + void *operator new(size_t s) { return User::operator new(s); } + /// CatchSwitchInst ctor - Create a new switch instruction, specifying a + /// default destination. The number of additional handlers can be specified + /// here to make memory allocation more efficient. + /// This constructor can also autoinsert before another instruction. + CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, const Twine &NameStr, + Instruction *InsertBefore); -class CatchEndPadInst : public TerminatorInst { -private: - CatchEndPadInst(const CatchEndPadInst &RI); - - void init(BasicBlock *UnwindBB); - CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values, - Instruction *InsertBefore = nullptr); - CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values, + /// CatchSwitchInst ctor - Create a new switch instruction, specifying a + /// default destination. The number of additional handlers can be specified + /// here to make memory allocation more efficient. + /// This constructor also autoinserts at the end of the specified BasicBlock. + CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, const Twine &NameStr, BasicBlock *InsertAtEnd); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; - CatchEndPadInst *cloneImpl() const; + CatchSwitchInst *cloneImpl() const; public: - static CatchEndPadInst *Create(LLVMContext &C, BasicBlock *UnwindBB = nullptr, + static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, + const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { - unsigned Values = UnwindBB ? 1 : 0; - return new (Values) CatchEndPadInst(C, UnwindBB, Values, InsertBefore); + return new CatchSwitchInst(ParentPad, UnwindDest, NumHandlers, NameStr, + InsertBefore); } - static CatchEndPadInst *Create(LLVMContext &C, BasicBlock *UnwindBB, + static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, const Twine &NameStr, BasicBlock *InsertAtEnd) { - unsigned Values = UnwindBB ? 1 : 0; - return new (Values) CatchEndPadInst(C, UnwindBB, Values, InsertAtEnd); + return new CatchSwitchInst(ParentPad, UnwindDest, NumHandlers, NameStr, + InsertAtEnd); } /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + // Accessor Methods for CatchSwitch stmt + Value *getParentPad() const { return getOperand(0); } + void setParentPad(Value *ParentPad) { setOperand(0, ParentPad); } + + // Accessor Methods for CatchSwitch stmt 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 hasUnwindDest() ? cast<BasicBlock>(Op<-1>()) : nullptr; + if (hasUnwindDest()) + return cast<BasicBlock>(getOperand(1)); + return nullptr; } - void setUnwindDest(BasicBlock *NewDest) { - assert(NewDest); - Op<-1>() = NewDest; + void setUnwindDest(BasicBlock *UnwindDest) { + assert(UnwindDest); + assert(hasUnwindDest()); + setOperand(1, UnwindDest); } - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { - return (I->getOpcode() == Instruction::CatchEndPad); - } - static inline bool classof(const Value *V) { - return isa<Instruction>(V) && classof(cast<Instruction>(V)); + /// getNumHandlers - return the number of 'handlers' in this catchswitch + /// instruction, except the default handler + unsigned getNumHandlers() const { + if (hasUnwindDest()) + return getNumOperands() - 2; + return getNumOperands() - 1; } 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); + static BasicBlock *handler_helper(Value *V) { return cast<BasicBlock>(V); } + static const BasicBlock *handler_helper(const Value *V) { + return cast<BasicBlock>(V); } -}; - -template <> -struct OperandTraits<CatchEndPadInst> - : public VariadicOperandTraits<CatchEndPadInst> {}; - -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchEndPadInst, Value) - -//===----------------------------------------------------------------------===// -// CatchPadInst Class -//===----------------------------------------------------------------------===// - -class CatchPadInst : public TerminatorInst { -private: - void init(BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef<Value *> Args, const Twine &NameStr); - - CatchPadInst(const CatchPadInst &CPI); - - explicit CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef<Value *> Args, unsigned Values, - const Twine &NameStr, Instruction *InsertBefore); - explicit CatchPadInst(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; - CatchPadInst *cloneImpl() const; public: - static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef<Value *> Args, const Twine &NameStr = "", - Instruction *InsertBefore = nullptr) { - unsigned Values = unsigned(Args.size()) + 2; - return new (Values) CatchPadInst(IfNormal, IfException, Args, Values, - NameStr, InsertBefore); - } - static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef<Value *> Args, const Twine &NameStr, - BasicBlock *InsertAtEnd) { - unsigned Values = unsigned(Args.size()) + 2; - return new (Values) - CatchPadInst(IfNormal, IfException, Args, Values, NameStr, InsertAtEnd); - } + typedef std::pointer_to_unary_function<Value *, BasicBlock *> DerefFnTy; + typedef mapped_iterator<op_iterator, DerefFnTy> handler_iterator; + typedef iterator_range<handler_iterator> handler_range; - /// Provide fast operand accessors - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - /// getNumArgOperands - Return the number of catchpad arguments. - /// - unsigned getNumArgOperands() const { return getNumOperands() - 2; } + typedef std::pointer_to_unary_function<const Value *, const BasicBlock *> + ConstDerefFnTy; + typedef mapped_iterator<const_op_iterator, ConstDerefFnTy> const_handler_iterator; + typedef iterator_range<const_handler_iterator> const_handler_range; - /// getArgOperand/setArgOperand - Return/set the i-th catchpad argument. - /// - Value *getArgOperand(unsigned i) const { return getOperand(i); } - void setArgOperand(unsigned i, Value *v) { setOperand(i, v); } + /// Returns an iterator that points to the first handler in CatchSwitchInst. + handler_iterator handler_begin() { + op_iterator It = op_begin() + 1; + if (hasUnwindDest()) + ++It; + return handler_iterator(It, DerefFnTy(handler_helper)); + } + /// Returns an iterator that points to the first handler in the + /// CatchSwitchInst. + const_handler_iterator handler_begin() const { + const_op_iterator It = op_begin() + 1; + if (hasUnwindDest()) + ++It; + return const_handler_iterator(It, ConstDerefFnTy(handler_helper)); + } - /// arg_operands - iteration adapter for range-for loops. - iterator_range<op_iterator> arg_operands() { - return make_range(op_begin(), op_end() - 2); + /// Returns a read-only iterator that points one past the last + /// handler in the CatchSwitchInst. + handler_iterator handler_end() { + return handler_iterator(op_end(), DerefFnTy(handler_helper)); + } + /// Returns an iterator that points one past the last handler in the + /// CatchSwitchInst. + const_handler_iterator handler_end() const { + return const_handler_iterator(op_end(), ConstDerefFnTy(handler_helper)); } - /// arg_operands - iteration adapter for range-for loops. - iterator_range<const_op_iterator> arg_operands() const { - return make_range(op_begin(), op_end() - 2); + /// handlers - iteration adapter for range-for loops. + handler_range handlers() { + return make_range(handler_begin(), handler_end()); } - /// \brief Wrappers for getting the \c Use of a catchpad argument. - const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); } - Use &getArgOperandUse(unsigned i) { return getOperandUse(i); } + /// handlers - iteration adapter for range-for loops. + const_handler_range handlers() const { + return make_range(handler_begin(), handler_end()); + } - // 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>() = B; } - void setUnwindDest(BasicBlock *B) { Op<-1>() = B; } + /// addHandler - Add an entry to the switch instruction... + /// Note: + /// This action invalidates handler_end(). Old handler_end() iterator will + /// point to the added handler. + void addHandler(BasicBlock *Dest); - BasicBlock *getSuccessor(unsigned i) const { - assert(i < 2 && "Successor # out of range for catchpad!"); - return i == 0 ? getNormalDest() : getUnwindDest(); + unsigned getNumSuccessors() const { return getNumOperands() - 1; } + BasicBlock *getSuccessor(unsigned Idx) const { + assert(Idx < getNumSuccessors() && + "Successor # out of range for catchswitch!"); + return cast<BasicBlock>(getOperand(Idx + 1)); } - - void setSuccessor(unsigned idx, BasicBlock *NewSucc) { - assert(idx < 2 && "Successor # out of range for catchpad!"); - *(&Op<-2>() + idx) = NewSucc; + void setSuccessor(unsigned Idx, BasicBlock *NewSucc) { + assert(Idx < getNumSuccessors() && + "Successor # out of range for catchswitch!"); + setOperand(Idx + 1, 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::CatchPad; + return I->getOpcode() == Instruction::CatchSwitch; } static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } private: - BasicBlock *getSuccessorV(unsigned idx) const override; + BasicBlock *getSuccessorV(unsigned Idx) const override; unsigned getNumSuccessorsV() const override; - void setSuccessorV(unsigned idx, BasicBlock *B) override; + void setSuccessorV(unsigned Idx, BasicBlock *B) override; }; template <> -struct OperandTraits<CatchPadInst> - : public VariadicOperandTraits<CatchPadInst, /*MINARITY=*/2> {}; +struct OperandTraits<CatchSwitchInst> : public HungoffOperandTraits<2> {}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchPadInst, Value) +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchSwitchInst, Value) //===----------------------------------------------------------------------===// // TerminatePadInst Class @@ -4001,14 +3997,14 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchPadInst, Value) class TerminatePadInst : public TerminatorInst { private: - void init(BasicBlock *BB, ArrayRef<Value *> Args); + void init(Value *ParentPad, BasicBlock *BB, ArrayRef<Value *> Args); TerminatePadInst(const TerminatePadInst &TPI); - explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB, + explicit TerminatePadInst(Value *ParentPad, BasicBlock *BB, ArrayRef<Value *> Args, unsigned Values, Instruction *InsertBefore); - explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB, + explicit TerminatePadInst(Value *ParentPad, BasicBlock *BB, ArrayRef<Value *> Args, unsigned Values, BasicBlock *InsertAtEnd); @@ -4018,21 +4014,23 @@ protected: TerminatePadInst *cloneImpl() const; public: - static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB = nullptr, + static TerminatePadInst *Create(Value *ParentPad, BasicBlock *BB = nullptr, ArrayRef<Value *> Args = None, Instruction *InsertBefore = nullptr) { - unsigned Values = unsigned(Args.size()); + unsigned Values = unsigned(Args.size()) + 1; if (BB) ++Values; - return new (Values) TerminatePadInst(C, BB, Args, Values, InsertBefore); + return new (Values) + TerminatePadInst(ParentPad, BB, Args, Values, InsertBefore); } - static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB, + static TerminatePadInst *Create(Value *ParentPad, BasicBlock *BB, ArrayRef<Value *> Args, BasicBlock *InsertAtEnd) { - unsigned Values = unsigned(Args.size()); + unsigned Values = unsigned(Args.size()) + 1; if (BB) ++Values; - return new (Values) TerminatePadInst(C, BB, Args, Values, InsertAtEnd); + return new (Values) + TerminatePadInst(ParentPad, BB, Args, Values, InsertAtEnd); } /// Provide fast operand accessors @@ -4046,8 +4044,15 @@ public: unsigned getNumArgOperands() const { unsigned NumOperands = getNumOperands(); if (hasUnwindDest()) - return NumOperands - 1; - return NumOperands; + return NumOperands - 2; + return NumOperands - 1; + } + + /// Convenience accessors + Value *getParentPad() const { return Op<-1>(); } + void setParentPad(Value *ParentPad) { + assert(ParentPad); + Op<-1>() = ParentPad; } /// getArgOperand/setArgOperand - Return/set the i-th terminatepad argument. @@ -4055,26 +4060,29 @@ public: Value *getArgOperand(unsigned i) const { return getOperand(i); } void setArgOperand(unsigned i, Value *v) { setOperand(i, v); } + const_op_iterator arg_begin() const { return op_begin(); } + op_iterator arg_begin() { return op_begin(); } + const_op_iterator arg_end() const { if (hasUnwindDest()) - return op_end() - 1; - return op_end(); + return op_end() - 2; + return op_end() - 1; } op_iterator arg_end() { if (hasUnwindDest()) - return op_end() - 1; - return op_end(); + return op_end() - 2; + return op_end() - 1; } /// arg_operands - iteration adapter for range-for loops. iterator_range<op_iterator> arg_operands() { - return make_range(op_begin(), arg_end()); + return make_range(arg_begin(), arg_end()); } /// arg_operands - iteration adapter for range-for loops. iterator_range<const_op_iterator> arg_operands() const { - return make_range(op_begin(), arg_end()); + return make_range(arg_begin(), arg_end()); } /// \brief Wrappers for getting the \c Use of a terminatepad argument. @@ -4085,11 +4093,11 @@ public: BasicBlock *getUnwindDest() const { if (!hasUnwindDest()) return nullptr; - return cast<BasicBlock>(Op<-1>()); + return cast<BasicBlock>(Op<-2>()); } void setUnwindDest(BasicBlock *B) { assert(B && hasUnwindDest()); - Op<-1>() = B; + Op<-2>() = B; } unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; } @@ -4121,40 +4129,37 @@ struct OperandTraits<TerminatePadInst> DEFINE_TRANSPARENT_OPERAND_ACCESSORS(TerminatePadInst, Value) //===----------------------------------------------------------------------===// -// CleanupPadInst Class +// CleanupPadInst Class //===----------------------------------------------------------------------===// - -class CleanupPadInst : public Instruction { +class CleanupPadInst : public FuncletPadInst { private: - void init(ArrayRef<Value *> Args, const Twine &NameStr); - - CleanupPadInst(const CleanupPadInst &CPI); - - explicit CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args, - const Twine &NameStr, Instruction *InsertBefore); - explicit CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args, - const Twine &NameStr, BasicBlock *InsertAtEnd); - -protected: - // Note: Instruction needs to be a friend here to call cloneImpl. - friend class Instruction; - CleanupPadInst *cloneImpl() const; + explicit CleanupPadInst(Value *ParentPad, ArrayRef<Value *> Args, + unsigned Values, const Twine &NameStr, + Instruction *InsertBefore) + : FuncletPadInst(Instruction::CleanupPad, ParentPad, Args, Values, + NameStr, InsertBefore) {} + explicit CleanupPadInst(Value *ParentPad, ArrayRef<Value *> Args, + unsigned Values, const Twine &NameStr, + BasicBlock *InsertAtEnd) + : FuncletPadInst(Instruction::CleanupPad, ParentPad, Args, Values, + NameStr, InsertAtEnd) {} public: - static CleanupPadInst *Create(LLVMContext &C, ArrayRef<Value *> Args, + static CleanupPadInst *Create(Value *ParentPad, ArrayRef<Value *> Args = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { - return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertBefore); + unsigned Values = 1 + Args.size(); + return new (Values) + CleanupPadInst(ParentPad, Args, Values, NameStr, InsertBefore); } - static CleanupPadInst *Create(LLVMContext &C, ArrayRef<Value *> Args, + static CleanupPadInst *Create(Value *ParentPad, ArrayRef<Value *> Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertAtEnd); + unsigned Values = 1 + Args.size(); + return new (Values) + CleanupPadInst(ParentPad, Args, Values, NameStr, InsertAtEnd); } - /// Provide fast operand accessors - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - - // Methods for support type inquiry through isa, cast, and dyn_cast: + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::CleanupPad; } @@ -4163,11 +4168,54 @@ public: } }; -template <> -struct OperandTraits<CleanupPadInst> - : public VariadicOperandTraits<CleanupPadInst, /*MINARITY=*/0> {}; +//===----------------------------------------------------------------------===// +// CatchPadInst Class +//===----------------------------------------------------------------------===// +class CatchPadInst : public FuncletPadInst { +private: + explicit CatchPadInst(Value *CatchSwitch, ArrayRef<Value *> Args, + unsigned Values, const Twine &NameStr, + Instruction *InsertBefore) + : FuncletPadInst(Instruction::CatchPad, CatchSwitch, Args, Values, + NameStr, InsertBefore) {} + explicit CatchPadInst(Value *CatchSwitch, ArrayRef<Value *> Args, + unsigned Values, const Twine &NameStr, + BasicBlock *InsertAtEnd) + : FuncletPadInst(Instruction::CatchPad, CatchSwitch, Args, Values, + NameStr, InsertAtEnd) {} -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupPadInst, Value) +public: + static CatchPadInst *Create(Value *CatchSwitch, ArrayRef<Value *> Args, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + unsigned Values = 1 + Args.size(); + return new (Values) + CatchPadInst(CatchSwitch, Args, Values, NameStr, InsertBefore); + } + static CatchPadInst *Create(Value *CatchSwitch, ArrayRef<Value *> Args, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + unsigned Values = 1 + Args.size(); + return new (Values) + CatchPadInst(CatchSwitch, Args, Values, NameStr, InsertAtEnd); + } + + /// Convenience accessors + CatchSwitchInst *getCatchSwitch() const { + return cast<CatchSwitchInst>(Op<-1>()); + } + void setCatchSwitch(Value *CatchSwitch) { + assert(CatchSwitch); + Op<-1>() = CatchSwitch; + } + + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::CatchPad; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; //===----------------------------------------------------------------------===// // CatchReturnInst Class @@ -4176,11 +4224,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupPadInst, Value) class CatchReturnInst : public TerminatorInst { CatchReturnInst(const CatchReturnInst &RI); - void init(CatchPadInst *CatchPad, BasicBlock *BB); - CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB, - Instruction *InsertBefore); - CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB, - BasicBlock *InsertAtEnd); + void init(Value *CatchPad, BasicBlock *BB); + CatchReturnInst(Value *CatchPad, BasicBlock *BB, Instruction *InsertBefore); + CatchReturnInst(Value *CatchPad, BasicBlock *BB, BasicBlock *InsertAtEnd); protected: // Note: Instruction needs to be a friend here to call cloneImpl. @@ -4188,13 +4234,13 @@ protected: CatchReturnInst *cloneImpl() const; public: - static CatchReturnInst *Create(CatchPadInst *CatchPad, BasicBlock *BB, + static CatchReturnInst *Create(Value *CatchPad, BasicBlock *BB, Instruction *InsertBefore = nullptr) { assert(CatchPad); assert(BB); return new (2) CatchReturnInst(CatchPad, BB, InsertBefore); } - static CatchReturnInst *Create(CatchPadInst *CatchPad, BasicBlock *BB, + static CatchReturnInst *Create(Value *CatchPad, BasicBlock *BB, BasicBlock *InsertAtEnd) { assert(CatchPad); assert(BB); @@ -4218,6 +4264,10 @@ public: } unsigned getNumSuccessors() const { return 1; } + Value *getParentPad() const { + return getCatchPad()->getCatchSwitch()->getParentPad(); + } + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::CatchRet); @@ -4239,93 +4289,6 @@ struct OperandTraits<CatchReturnInst> DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value) //===----------------------------------------------------------------------===// -// CleanupEndPadInst Class -//===----------------------------------------------------------------------===// - -class CleanupEndPadInst : public TerminatorInst { -private: - CleanupEndPadInst(const CleanupEndPadInst &CEPI); - - void init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB); - CleanupEndPadInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB, - unsigned Values, Instruction *InsertBefore = nullptr); - CleanupEndPadInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB, - unsigned Values, BasicBlock *InsertAtEnd); - -protected: - // Note: Instruction needs to be a friend here to call cloneImpl. - friend class Instruction; - CleanupEndPadInst *cloneImpl() const; - -public: - static CleanupEndPadInst *Create(CleanupPadInst *CleanupPad, - BasicBlock *UnwindBB = nullptr, - Instruction *InsertBefore = nullptr) { - unsigned Values = UnwindBB ? 2 : 1; - return new (Values) - CleanupEndPadInst(CleanupPad, UnwindBB, Values, InsertBefore); - } - static CleanupEndPadInst *Create(CleanupPadInst *CleanupPad, - BasicBlock *UnwindBB, - BasicBlock *InsertAtEnd) { - unsigned Values = UnwindBB ? 2 : 1; - return new (Values) - CleanupEndPadInst(CleanupPad, UnwindBB, Values, InsertAtEnd); - } - - /// Provide fast operand accessors - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - - bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; } - bool unwindsToCaller() const { return !hasUnwindDest(); } - - unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; } - - /// Convenience accessors - CleanupPadInst *getCleanupPad() const { - return cast<CleanupPadInst>(Op<-1>()); - } - void setCleanupPad(CleanupPadInst *CleanupPad) { - assert(CleanupPad); - Op<-1>() = CleanupPad; - } - - BasicBlock *getUnwindDest() const { - return hasUnwindDest() ? cast<BasicBlock>(Op<-2>()) : nullptr; - } - void setUnwindDest(BasicBlock *NewDest) { - assert(hasUnwindDest()); - assert(NewDest); - Op<-2>() = NewDest; - } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { - return (I->getOpcode() == Instruction::CleanupEndPad); - } - 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<CleanupEndPadInst> - : public VariadicOperandTraits<CleanupEndPadInst, /*MINARITY=*/1> {}; - -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupEndPadInst, Value) - -//===----------------------------------------------------------------------===// // CleanupReturnInst Class //===----------------------------------------------------------------------===// @@ -4333,11 +4296,11 @@ class CleanupReturnInst : public TerminatorInst { private: CleanupReturnInst(const CleanupReturnInst &RI); - void init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB); - CleanupReturnInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB, - unsigned Values, Instruction *InsertBefore = nullptr); - CleanupReturnInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB, - unsigned Values, BasicBlock *InsertAtEnd); + void init(Value *CleanupPad, BasicBlock *UnwindBB); + CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, unsigned Values, + Instruction *InsertBefore = nullptr); + CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, unsigned Values, + BasicBlock *InsertAtEnd); protected: // Note: Instruction needs to be a friend here to call cloneImpl. @@ -4345,7 +4308,7 @@ protected: CleanupReturnInst *cloneImpl() const; public: - static CleanupReturnInst *Create(CleanupPadInst *CleanupPad, + static CleanupReturnInst *Create(Value *CleanupPad, BasicBlock *UnwindBB = nullptr, Instruction *InsertBefore = nullptr) { assert(CleanupPad); @@ -4355,8 +4318,7 @@ public: return new (Values) CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertBefore); } - static CleanupReturnInst *Create(CleanupPadInst *CleanupPad, - BasicBlock *UnwindBB, + static CleanupReturnInst *Create(Value *CleanupPad, BasicBlock *UnwindBB, BasicBlock *InsertAtEnd) { assert(CleanupPad); unsigned Values = 1; @@ -4374,22 +4336,22 @@ public: /// Convenience accessor. CleanupPadInst *getCleanupPad() const { - return cast<CleanupPadInst>(Op<-1>()); + return cast<CleanupPadInst>(Op<0>()); } void setCleanupPad(CleanupPadInst *CleanupPad) { assert(CleanupPad); - Op<-1>() = CleanupPad; + Op<0>() = CleanupPad; } unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; } BasicBlock *getUnwindDest() const { - return hasUnwindDest() ? cast<BasicBlock>(Op<-2>()) : nullptr; + return hasUnwindDest() ? cast<BasicBlock>(Op<1>()) : nullptr; } void setUnwindDest(BasicBlock *NewDest) { assert(NewDest); assert(hasUnwindDest()); - Op<-2>() = NewDest; + Op<1>() = NewDest; } // Methods for support type inquiry through isa, cast, and dyn_cast: diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h index 1d707a1e530..6fe1a03919e 100644 --- a/llvm/include/llvm/Transforms/Utils/Local.h +++ b/llvm/include/llvm/Transforms/Utils/Local.h @@ -289,8 +289,8 @@ bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress, DIBuilder &Builder, bool Deref, int Offset = 0); /// Replace 'BB's terminator with one that does not have an unwind successor -/// block. Rewrites `invoke` to `call`, `catchendpad unwind label %foo` to -/// `catchendpad unwind to caller`, etc. Updates any PHIs in unwind successor. +/// block. Rewrites `invoke` to `call`, `terminatepad unwind label %foo` to +/// `terminatepad unwind to caller`, etc. Updates any PHIs in unwind successor. /// /// \param BB Block whose terminator will be replaced. Its terminator must /// have an unwind successor. |