X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FIR%2FInstructions.h;h=d979b393066f5a13fc7fa180d3577a755864b582;hb=1676f595b1f7017f61df5ca72876341570d4ba9c;hp=60ead82e0e24d27a63220f2b2ec0127a85c6ef9a;hpb=2431442e6760031935001d82b6ebb4cf2812a57e;p=oota-llvm.git diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 60ead82e0e2..d979b393066 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -1473,8 +1473,14 @@ public: /// getArgOperand/setArgOperand - Return/set the i-th call argument. /// - Value *getArgOperand(unsigned i) const { return getOperand(i); } - void setArgOperand(unsigned i, Value *v) { setOperand(i, v); } + Value *getArgOperand(unsigned i) const { + assert(i < getNumArgOperands() && "Out of bounds!"); + return getOperand(i); + } + void setArgOperand(unsigned i, Value *v) { + assert(i < getNumArgOperands() && "Out of bounds!"); + setOperand(i, v); + } /// arg_operands - iteration adapter for range-for loops. iterator_range arg_operands() { @@ -1489,8 +1495,14 @@ public: } /// \brief Wrappers for getting the \c Use of a call argument. - const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); } - Use &getArgOperandUse(unsigned i) { return getOperandUse(i); } + const Use &getArgOperandUse(unsigned i) const { + assert(i < getNumArgOperands() && "Out of bounds!"); + return getOperandUse(i); + } + Use &getArgOperandUse(unsigned i) { + assert(i < getNumArgOperands() && "Out of bounds!"); + return getOperandUse(i); + } /// getCallingConv/setCallingConv - Get or set the calling convention of this /// function call. @@ -1595,6 +1607,15 @@ public: addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly); } + /// @brief Determine if the call can access memmory only using pointers based + /// on its arguments. + bool onlyAccessesArgMemory() const { + return hasFnAttr(Attribute::ArgMemOnly); + } + void setOnlyAccessesArgMemory() { + addAttribute(AttributeSet::FunctionIndex, Attribute::ArgMemOnly); + } + /// \brief Determine if the call cannot return. bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); } void setDoesNotReturn() { @@ -1613,6 +1634,12 @@ public: addAttribute(AttributeSet::FunctionIndex, Attribute::NoDuplicate); } + /// \brief Determine if the call is convergent + bool isConvergent() const { return hasFnAttr(Attribute::Convergent); } + void setConvergent() { + addAttribute(AttributeSet::FunctionIndex, Attribute::Convergent); + } + /// \brief Determine if the call returns a structure through first /// pointer argument. bool hasStructRetAttr() const { @@ -2731,7 +2758,7 @@ public: void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < getNumSuccessors() && "Successor # out of range for Branch!"); - *(&Op<-1>() - idx) = (Value*)NewSucc; + *(&Op<-1>() - idx) = NewSucc; } /// \brief Swap the successors of this branch instruction. @@ -3047,7 +3074,7 @@ public: } void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < getNumSuccessors() && "Successor # out of range for switch!"); - setOperand(idx*2+1, (Value*)NewSucc); + setOperand(idx * 2 + 1, NewSucc); } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -3147,7 +3174,7 @@ public: return cast(getOperand(i+1)); } void setSuccessor(unsigned i, BasicBlock *NewSucc) { - setOperand(i+1, (Value*)NewSucc); + setOperand(i + 1, NewSucc); } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -3259,8 +3286,14 @@ public: /// getArgOperand/setArgOperand - Return/set the i-th invoke argument. /// - Value *getArgOperand(unsigned i) const { return getOperand(i); } - void setArgOperand(unsigned i, Value *v) { setOperand(i, v); } + Value *getArgOperand(unsigned i) const { + assert(i < getNumArgOperands() && "Out of bounds!"); + return getOperand(i); + } + void setArgOperand(unsigned i, Value *v) { + assert(i < getNumArgOperands() && "Out of bounds!"); + setOperand(i, v); + } /// arg_operands - iteration adapter for range-for loops. iterator_range arg_operands() { @@ -3273,8 +3306,14 @@ public: } /// \brief Wrappers for getting the \c Use of a invoke argument. - const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); } - Use &getArgOperandUse(unsigned i) { return getOperandUse(i); } + const Use &getArgOperandUse(unsigned i) const { + assert(i < getNumArgOperands() && "Out of bounds!"); + return getOperandUse(i); + } + Use &getArgOperandUse(unsigned i) { + assert(i < getNumArgOperands() && "Out of bounds!"); + return getOperandUse(i); + } /// getCallingConv/setCallingConv - Get or set the calling convention of this /// function call. @@ -3364,6 +3403,15 @@ public: addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly); } + /// @brief Determine if the call access memmory only using it's pointer + /// arguments. + bool onlyAccessesArgMemory() const { + return hasFnAttr(Attribute::ArgMemOnly); + } + void setOnlyAccessesArgMemory() { + addAttribute(AttributeSet::FunctionIndex, Attribute::ArgMemOnly); + } + /// \brief Determine if the call cannot return. bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); } void setDoesNotReturn() { @@ -3552,140 +3600,34 @@ struct OperandTraits : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value) //===----------------------------------------------------------------------===// -// CleanupReturnInst Class +// CatchEndPadInst 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(V) && classof(cast(V)); - } - +class CatchEndPadInst : public TerminatorInst { private: - BasicBlock *getSuccessorV(unsigned Idx) const override; - unsigned getNumSuccessorsV() const override; - void setSuccessorV(unsigned Idx, BasicBlock *B) override; + CatchEndPadInst(const CatchEndPadInst &RI); - // 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 - : public VariadicOperandTraits {}; - -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); + CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values, + Instruction *InsertBefore = nullptr); + CatchEndPadInst(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; + CatchEndPadInst *cloneImpl() const; public: - static CatchEndBlockInst *Create(LLVMContext &C, - BasicBlock *UnwindBB = nullptr, - Instruction *InsertBefore = nullptr) { + static CatchEndPadInst *Create(LLVMContext &C, BasicBlock *UnwindBB = nullptr, + Instruction *InsertBefore = nullptr) { unsigned Values = UnwindBB ? 1 : 0; - return new (Values) CatchEndBlockInst(C, UnwindBB, Values, InsertBefore); + return new (Values) CatchEndPadInst(C, UnwindBB, Values, InsertBefore); } - static CatchEndBlockInst *Create(LLVMContext &C, BasicBlock *UnwindBB, - BasicBlock *InsertAtEnd) { + static CatchEndPadInst *Create(LLVMContext &C, BasicBlock *UnwindBB, + BasicBlock *InsertAtEnd) { unsigned Values = UnwindBB ? 1 : 0; - return new (Values) CatchEndBlockInst(C, UnwindBB, Values, InsertAtEnd); + return new (Values) CatchEndPadInst(C, UnwindBB, Values, InsertAtEnd); } /// Provide fast operand accessors @@ -3697,7 +3639,9 @@ public: /// Convenience accessor. Returns null if there is no return value. unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; } - BasicBlock *getUnwindDest() const { return cast(Op<-1>()); } + BasicBlock *getUnwindDest() const { + return hasUnwindDest() ? cast(Op<-1>()) : nullptr; + } void setUnwindDest(BasicBlock *NewDest) { assert(NewDest); Op<-1>() = NewDest; @@ -3705,7 +3649,7 @@ public: // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { - return (I->getOpcode() == Instruction::CatchEndBlock); + return (I->getOpcode() == Instruction::CatchEndPad); } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); @@ -3716,7 +3660,6 @@ private: 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) { @@ -3725,61 +3668,58 @@ private: }; template <> -struct OperandTraits - : public VariadicOperandTraits {}; +struct OperandTraits + : public VariadicOperandTraits {}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchEndBlockInst, Value) +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchEndPadInst, Value) //===----------------------------------------------------------------------===// -// CatchBlockInst Class +// CatchPadInst Class //===----------------------------------------------------------------------===// -class CatchBlockInst : public TerminatorInst { +class CatchPadInst : public TerminatorInst { private: void init(BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, const Twine &NameStr); - CatchBlockInst(const CatchBlockInst &CBI); + CatchPadInst(const CatchPadInst &CPI); - explicit CatchBlockInst(Type *RetTy, BasicBlock *IfNormal, - BasicBlock *IfException, ArrayRef Args, - unsigned Values, const Twine &NameStr, - Instruction *InsertBefore); - explicit CatchBlockInst(Type *RetTy, BasicBlock *IfNormal, - BasicBlock *IfException, ArrayRef Args, - unsigned Values, const Twine &NameStr, - BasicBlock *InsertAtEnd); + explicit CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException, + ArrayRef Args, unsigned Values, + const Twine &NameStr, Instruction *InsertBefore); + explicit CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException, + ArrayRef 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; + CatchPadInst *cloneImpl() const; public: - static CatchBlockInst *Create(Type *RetTy, BasicBlock *IfNormal, - BasicBlock *IfException, ArrayRef Args, - const Twine &NameStr = "", - Instruction *InsertBefore = nullptr) { + static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException, + ArrayRef Args, const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { unsigned Values = unsigned(Args.size()) + 2; - return new (Values) CatchBlockInst(RetTy, IfNormal, IfException, Args, - Values, NameStr, InsertBefore); + return new (Values) CatchPadInst(IfNormal, IfException, Args, Values, + NameStr, InsertBefore); } - static CatchBlockInst *Create(Type *RetTy, BasicBlock *IfNormal, - BasicBlock *IfException, ArrayRef Args, - const Twine &NameStr, BasicBlock *InsertAtEnd) { + static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException, + ArrayRef Args, const Twine &NameStr, + BasicBlock *InsertAtEnd) { unsigned Values = unsigned(Args.size()) + 2; - return new (Values) CatchBlockInst(RetTy, IfNormal, IfException, Args, - Values, NameStr, InsertAtEnd); + return new (Values) + CatchPadInst(IfNormal, IfException, Args, Values, NameStr, InsertAtEnd); } /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - /// getNumArgOperands - Return the number of catchblock arguments. + /// getNumArgOperands - Return the number of catchpad arguments. /// unsigned getNumArgOperands() const { return getNumOperands() - 2; } - /// getArgOperand/setArgOperand - Return/set the i-th catchblock argument. + /// 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); } @@ -3794,31 +3734,31 @@ public: return iterator_range(op_begin(), op_end() - 2); } - /// \brief Wrappers for getting the \c Use of a catchblock argument. + /// \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); } // get*Dest - Return the destination basic blocks... BasicBlock *getNormalDest() const { return cast(Op<-2>()); } BasicBlock *getUnwindDest() const { return cast(Op<-1>()); } - void setNormalDest(BasicBlock *B) { Op<-2>() = reinterpret_cast(B); } - void setUnwindDest(BasicBlock *B) { Op<-1>() = reinterpret_cast(B); } + void setNormalDest(BasicBlock *B) { Op<-2>() = B; } + void setUnwindDest(BasicBlock *B) { Op<-1>() = B; } BasicBlock *getSuccessor(unsigned i) const { - assert(i < 2 && "Successor # out of range for catchblock!"); + assert(i < 2 && "Successor # out of range for catchpad!"); return i == 0 ? getNormalDest() : getUnwindDest(); } void setSuccessor(unsigned idx, BasicBlock *NewSucc) { - assert(idx < 2 && "Successor # out of range for catchblock!"); - *(&Op<-2>() + idx) = reinterpret_cast(NewSucc); + assert(idx < 2 && "Successor # out of range for catchpad!"); + *(&Op<-2>() + idx) = 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; + return I->getOpcode() == Instruction::CatchPad; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); @@ -3831,53 +3771,49 @@ private: }; template <> -struct OperandTraits - : public VariadicOperandTraits {}; +struct OperandTraits + : public VariadicOperandTraits {}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchBlockInst, Value) +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchPadInst, Value) //===----------------------------------------------------------------------===// -// TerminateBlockInst Class +// TerminatePadInst Class //===----------------------------------------------------------------------===// -class TerminateBlockInst : public TerminatorInst { +class TerminatePadInst : public TerminatorInst { private: - void init(BasicBlock *BB, ArrayRef Args, const Twine &NameStr); + void init(BasicBlock *BB, ArrayRef Args); - TerminateBlockInst(const TerminateBlockInst &TBI); + TerminatePadInst(const TerminatePadInst &TPI); - explicit TerminateBlockInst(LLVMContext &C, BasicBlock *BB, - ArrayRef Args, unsigned Values, - const Twine &NameStr, Instruction *InsertBefore); - explicit TerminateBlockInst(LLVMContext &C, BasicBlock *BB, - ArrayRef Args, unsigned Values, - const Twine &NameStr, BasicBlock *InsertAtEnd); + explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB, + ArrayRef Args, unsigned Values, + Instruction *InsertBefore); + explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB, + ArrayRef Args, unsigned Values, + BasicBlock *InsertAtEnd); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; - TerminateBlockInst *cloneImpl() const; + TerminatePadInst *cloneImpl() const; public: - static TerminateBlockInst *Create(LLVMContext &C, BasicBlock *BB = nullptr, - ArrayRef Args = {}, - const Twine &NameStr = "", - Instruction *InsertBefore = nullptr) { + static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB = nullptr, + ArrayRef Args = None, + Instruction *InsertBefore = nullptr) { unsigned Values = unsigned(Args.size()); if (BB) ++Values; - return new (Values) - TerminateBlockInst(C, BB, Args, Values, NameStr, InsertBefore); + return new (Values) TerminatePadInst(C, BB, Args, Values, InsertBefore); } - static TerminateBlockInst *Create(LLVMContext &C, BasicBlock *BB, - ArrayRef Args, - const Twine &NameStr, - BasicBlock *InsertAtEnd) { + static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB, + ArrayRef Args, + BasicBlock *InsertAtEnd) { unsigned Values = unsigned(Args.size()); if (BB) ++Values; - return new (Values) - TerminateBlockInst(C, BB, Args, Values, NameStr, InsertAtEnd); + return new (Values) TerminatePadInst(C, BB, Args, Values, InsertAtEnd); } /// Provide fast operand accessors @@ -3886,7 +3822,7 @@ public: bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; } bool unwindsToCaller() const { return !hasUnwindDest(); } - /// getNumArgOperands - Return the number of terminateblock arguments. + /// getNumArgOperands - Return the number of terminatepad arguments. /// unsigned getNumArgOperands() const { unsigned NumOperands = getNumOperands(); @@ -3895,7 +3831,7 @@ public: return NumOperands; } - /// getArgOperand/setArgOperand - Return/set the i-th terminateblock argument. + /// getArgOperand/setArgOperand - Return/set the i-th terminatepad argument. /// Value *getArgOperand(unsigned i) const { return getOperand(i); } void setArgOperand(unsigned i, Value *v) { setOperand(i, v); } @@ -3922,7 +3858,7 @@ public: return iterator_range(op_begin(), arg_end()); } - /// \brief Wrappers for getting the \c Use of a terminateblock argument. + /// \brief Wrappers for getting the \c Use of a terminatepad argument. const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); } Use &getArgOperandUse(unsigned i) { return getOperandUse(i); } @@ -3934,14 +3870,14 @@ public: } void setUnwindDest(BasicBlock *B) { assert(B && hasUnwindDest()); - Op<-1>() = reinterpret_cast(B); + Op<-1>() = 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; + return I->getOpcode() == Instruction::TerminatePad; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); @@ -3960,43 +3896,40 @@ private: }; template <> -struct OperandTraits - : public VariadicOperandTraits {}; +struct OperandTraits + : public VariadicOperandTraits {}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(TerminateBlockInst, Value) +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(TerminatePadInst, Value) //===----------------------------------------------------------------------===// -// CleanupBlockInst Class +// CleanupPadInst Class //===----------------------------------------------------------------------===// -class CleanupBlockInst : public Instruction { +class CleanupPadInst : public Instruction { private: void init(ArrayRef Args, const Twine &NameStr); - CleanupBlockInst(const CleanupBlockInst &TBI); + CleanupPadInst(const CleanupPadInst &CPI); - explicit CleanupBlockInst(Type *RetTy, ArrayRef Args, - const Twine &NameStr, Instruction *InsertBefore); - explicit CleanupBlockInst(Type *RetTy, ArrayRef Args, - const Twine &NameStr, BasicBlock *InsertAtEnd); + explicit CleanupPadInst(LLVMContext &C, ArrayRef Args, + const Twine &NameStr, Instruction *InsertBefore); + explicit CleanupPadInst(LLVMContext &C, ArrayRef Args, + const Twine &NameStr, BasicBlock *InsertAtEnd); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; - CleanupBlockInst *cloneImpl() const; + CleanupPadInst *cloneImpl() const; public: - static CleanupBlockInst *Create(Type *RetTy, ArrayRef Args, - const Twine &NameStr = "", - Instruction *InsertBefore = nullptr) { - return new (Args.size()) - CleanupBlockInst(RetTy, Args, NameStr, InsertBefore); + static CleanupPadInst *Create(LLVMContext &C, ArrayRef Args, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertBefore); } - static CleanupBlockInst *Create(Type *RetTy, ArrayRef Args, - const Twine &NameStr, - BasicBlock *InsertAtEnd) { - return new (Args.size()) - CleanupBlockInst(RetTy, Args, NameStr, InsertAtEnd); + static CleanupPadInst *Create(LLVMContext &C, ArrayRef Args, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertAtEnd); } /// Provide fast operand accessors @@ -4004,7 +3937,7 @@ public: // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { - return I->getOpcode() == Instruction::CleanupBlock; + return I->getOpcode() == Instruction::CleanupPad; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); @@ -4012,10 +3945,10 @@ public: }; template <> -struct OperandTraits - : public VariadicOperandTraits {}; +struct OperandTraits + : public VariadicOperandTraits {}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupBlockInst, Value) +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupPadInst, Value) //===----------------------------------------------------------------------===// // CatchReturnInst Class @@ -4024,10 +3957,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupBlockInst, Value) 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); + void init(CatchPadInst *CatchPad, BasicBlock *BB); + CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB, + Instruction *InsertBefore); + CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB, + BasicBlock *InsertAtEnd); protected: // Note: Instruction needs to be a friend here to call cloneImpl. @@ -4035,20 +3969,34 @@ protected: CatchReturnInst *cloneImpl() const; public: - static CatchReturnInst *Create(BasicBlock *BB, + static CatchReturnInst *Create(CatchPadInst *CatchPad, BasicBlock *BB, Instruction *InsertBefore = nullptr) { - return new (1) CatchReturnInst(BB, InsertBefore); + assert(CatchPad); + assert(BB); + return new (2) CatchReturnInst(CatchPad, BB, InsertBefore); } - static CatchReturnInst *Create(BasicBlock *BB, BasicBlock *InsertAtEnd) { - return new (1) CatchReturnInst(BB, InsertAtEnd); + static CatchReturnInst *Create(CatchPadInst *CatchPad, BasicBlock *BB, + BasicBlock *InsertAtEnd) { + assert(CatchPad); + assert(BB); + return new (2) CatchReturnInst(CatchPad, BB, InsertAtEnd); } /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); /// Convenience accessors. - BasicBlock *getSuccessor() const { return cast(Op<0>()); } - void setSuccessor(BasicBlock *NewSucc) { Op<0>() = (Value *)NewSucc; } + CatchPadInst *getCatchPad() const { return cast(Op<0>()); } + void setCatchPad(CatchPadInst *CatchPad) { + assert(CatchPad); + Op<0>() = CatchPad; + } + + BasicBlock *getSuccessor() const { return cast(Op<1>()); } + void setSuccessor(BasicBlock *NewSucc) { + assert(NewSucc); + Op<1>() = NewSucc; + } unsigned getNumSuccessors() const { return 1; } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -4067,10 +4015,190 @@ private: template <> struct OperandTraits - : public FixedNumOperandTraits {}; + : public FixedNumOperandTraits {}; 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(Op<-1>()); + } + void setCleanupPad(CleanupPadInst *CleanupPad) { + assert(CleanupPad); + Op<-1>() = CleanupPad; + } + + BasicBlock *getUnwindDest() const { + return hasUnwindDest() ? cast(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(V) && classof(cast(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 + : public VariadicOperandTraits {}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupEndPadInst, Value) + +//===----------------------------------------------------------------------===// +// CleanupReturnInst Class +//===----------------------------------------------------------------------===// + +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); + +protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + CleanupReturnInst *cloneImpl() const; + +public: + static CleanupReturnInst *Create(CleanupPadInst *CleanupPad, + BasicBlock *UnwindBB = nullptr, + Instruction *InsertBefore = nullptr) { + assert(CleanupPad); + unsigned Values = 1; + if (UnwindBB) + ++Values; + return new (Values) + CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertBefore); + } + static CleanupReturnInst *Create(CleanupPadInst *CleanupPad, + BasicBlock *UnwindBB, + BasicBlock *InsertAtEnd) { + assert(CleanupPad); + unsigned Values = 1; + if (UnwindBB) + ++Values; + return new (Values) + CleanupReturnInst(CleanupPad, 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. + CleanupPadInst *getCleanupPad() const { + return cast(Op<-1>()); + } + void setCleanupPad(CleanupPadInst *CleanupPad) { + assert(CleanupPad); + Op<-1>() = CleanupPad; + } + + unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; } + + BasicBlock *getUnwindDest() const { + return hasUnwindDest() ? cast(Op<-2>()) : nullptr; + } + void setUnwindDest(BasicBlock *NewDest) { + assert(NewDest); + assert(hasUnwindDest()); + 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::CleanupRet); + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(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 + : public VariadicOperandTraits {}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value) + //===----------------------------------------------------------------------===// // UnreachableInst Class //===----------------------------------------------------------------------===//