X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FIR%2FInstructions.h;h=aba48ca6fa9e09f7fb95cd50ca92753ac6bed13c;hp=e0a368a8d4d93702c4dad670a01b2130bab06e45;hb=db61103ea811b2fc0443e6438da3067a19ba1793;hpb=5ff590799654e01ceea6383932fc25e8e622c46a diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index e0a368a8d4d..aba48ca6fa9 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -18,10 +18,12 @@ #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" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" #include "llvm/Support/ErrorHandling.h" #include @@ -73,8 +75,13 @@ return (Ord == Release || /// AllocaInst - an instruction to allocate memory on the stack /// class AllocaInst : public UnaryInstruction { + Type *AllocatedType; + protected: - AllocaInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + AllocaInst *cloneImpl() const; + public: explicit AllocaInst(Type *Ty, Value *ArraySize = nullptr, const Twine &Name = "", @@ -113,7 +120,10 @@ public: /// getAllocatedType - Return the type that is being allocated by the /// instruction. /// - Type *getAllocatedType() const; + Type *getAllocatedType() const { return AllocatedType; } + /// \brief for use only in special circumstances that need to generically + /// transform a whole instruction (eg: IR linking and vectorization). + void setAllocatedType(Type *Ty) { AllocatedType = Ty; } /// getAlignment - Return the alignment of the memory that is being allocated /// by the instruction. @@ -149,6 +159,7 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -157,7 +168,6 @@ private: } }; - //===----------------------------------------------------------------------===// // LoadInst Class //===----------------------------------------------------------------------===// @@ -167,16 +177,28 @@ private: /// class LoadInst : public UnaryInstruction { void AssertOK(); + protected: - LoadInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + LoadInst *cloneImpl() const; + public: LoadInst(Value *Ptr, const Twine &NameStr, Instruction *InsertBefore); LoadInst(Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd); - LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile = false, + LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile = false, Instruction *InsertBefore = nullptr); + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile = false, + Instruction *InsertBefore = nullptr) + : LoadInst(cast(Ptr->getType())->getElementType(), Ptr, + NameStr, isVolatile, InsertBefore) {} LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, BasicBlock *InsertAtEnd); - LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, + Instruction *InsertBefore = nullptr) + : LoadInst(cast(Ptr->getType())->getElementType(), Ptr, + NameStr, isVolatile, Align, InsertBefore) {} + LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, Instruction *InsertBefore = nullptr); LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, BasicBlock *InsertAtEnd); @@ -196,9 +218,13 @@ public: LoadInst(Value *Ptr, const char *NameStr, Instruction *InsertBefore); LoadInst(Value *Ptr, const char *NameStr, BasicBlock *InsertAtEnd); + LoadInst(Type *Ty, Value *Ptr, const char *NameStr = nullptr, + bool isVolatile = false, Instruction *InsertBefore = nullptr); explicit LoadInst(Value *Ptr, const char *NameStr = nullptr, bool isVolatile = false, - Instruction *InsertBefore = nullptr); + Instruction *InsertBefore = nullptr) + : LoadInst(cast(Ptr->getType())->getElementType(), Ptr, + NameStr, isVolatile, InsertBefore) {} LoadInst(Value *Ptr, const char *NameStr, bool isVolatile, BasicBlock *InsertAtEnd); @@ -266,7 +292,6 @@ public: return getPointerOperand()->getType()->getPointerAddressSpace(); } - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Load; @@ -274,6 +299,7 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -282,7 +308,6 @@ private: } }; - //===----------------------------------------------------------------------===// // StoreInst Class //===----------------------------------------------------------------------===// @@ -292,8 +317,12 @@ private: class StoreInst : public Instruction { void *operator new(size_t, unsigned) = delete; void AssertOK(); + protected: - StoreInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + StoreInst *cloneImpl() const; + public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -317,7 +346,6 @@ public: SynchronizationScope SynchScope, BasicBlock *InsertAtEnd); - /// isVolatile - Return true if this is a store to a volatile memory /// location. /// @@ -395,6 +423,7 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -418,8 +447,12 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value) class FenceInst : public Instruction { void *operator new(size_t, unsigned) = delete; void Init(AtomicOrdering Ordering, SynchronizationScope SynchScope); + protected: - FenceInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + FenceInst *cloneImpl() const; + public: // allocate space for exactly zero operands void *operator new(size_t s) { @@ -466,6 +499,7 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -487,8 +521,12 @@ class AtomicCmpXchgInst : public Instruction { void Init(Value *Ptr, Value *Cmp, Value *NewVal, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SynchronizationScope SynchScope); + protected: - AtomicCmpXchgInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + AtomicCmpXchgInst *cloneImpl() const; + public: // allocate space for exactly three operands void *operator new(size_t s) { @@ -615,6 +653,7 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -640,8 +679,12 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicCmpXchgInst, Value) /// class AtomicRMWInst : public Instruction { void *operator new(size_t, unsigned) = delete; + protected: - AtomicRMWInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + AtomicRMWInst *cloneImpl() const; + public: /// This enumeration lists the possible modifications atomicrmw can make. In /// the descriptions, 'p' is the pointer to the instruction's memory location, @@ -759,6 +802,7 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: void Init(BinOp Operation, Value *Ptr, Value *Val, AtomicOrdering Ordering, SynchronizationScope SynchScope); @@ -792,6 +836,11 @@ inline Type *checkGEPType(Type *Ty) { /// access elements of arrays and structs /// class GetElementPtrInst : public Instruction { + Type *SourceElementType; + Type *ResultElementType; + + void anchor() override; + GetElementPtrInst(const GetElementPtrInst &GEPI); void init(Value *Ptr, ArrayRef IdxList, const Twine &NameStr); @@ -807,13 +856,23 @@ class GetElementPtrInst : public Instruction { const Twine &NameStr, BasicBlock *InsertAtEnd); protected: - GetElementPtrInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + GetElementPtrInst *cloneImpl() const; + public: static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr, ArrayRef IdxList, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { unsigned Values = 1 + unsigned(IdxList.size()); + if (!PointeeType) + PointeeType = + cast(Ptr->getType()->getScalarType())->getElementType(); + else + assert( + PointeeType == + cast(Ptr->getType()->getScalarType())->getElementType()); return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values, NameStr, InsertBefore); } @@ -822,6 +881,13 @@ public: const Twine &NameStr, BasicBlock *InsertAtEnd) { unsigned Values = 1 + unsigned(IdxList.size()); + if (!PointeeType) + PointeeType = + cast(Ptr->getType()->getScalarType())->getElementType(); + else + assert( + PointeeType == + cast(Ptr->getType()->getScalarType())->getElementType()); return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values, NameStr, InsertAtEnd); } @@ -867,12 +933,16 @@ public: return cast(Instruction::getType()); } - Type *getSourceElementType() const { - return cast(getPointerOperandType()->getScalarType()) - ->getElementType(); - } + Type *getSourceElementType() const { return SourceElementType; } - Type *getResultElementType() const { return getType()->getElementType(); } + void setSourceElementType(Type *Ty) { SourceElementType = Ty; } + void setResultElementType(Type *Ty) { ResultElementType = Ty; } + + Type *getResultElementType() const { + assert(ResultElementType == + cast(getType()->getScalarType())->getElementType()); + return ResultElementType; + } /// \brief Returns the address space of this instruction's pointer type. unsigned getAddressSpace() const { @@ -920,18 +990,24 @@ public: /// GetGEPReturnType - Returns the pointer type returned by the GEP /// instruction, which may be a vector of pointers. static Type *getGEPReturnType(Value *Ptr, ArrayRef IdxList) { - Type *PtrTy = - PointerType::get(checkGEPType(getIndexedType( - cast(Ptr->getType()->getScalarType()) - ->getElementType(), - IdxList)), - Ptr->getType()->getPointerAddressSpace()); + return getGEPReturnType( + cast(Ptr->getType()->getScalarType())->getElementType(), + Ptr, IdxList); + } + static Type *getGEPReturnType(Type *ElTy, Value *Ptr, + ArrayRef IdxList) { + Type *PtrTy = PointerType::get(checkGEPType(getIndexedType(ElTy, IdxList)), + Ptr->getType()->getPointerAddressSpace()); // Vector GEP if (Ptr->getType()->isVectorTy()) { - unsigned NumElem = cast(Ptr->getType())->getNumElements(); + unsigned NumElem = Ptr->getType()->getVectorNumElements(); return VectorType::get(PtrTy, NumElem); } - + for (Value *Index : IdxList) + if (Index->getType()->isVectorTy()) { + unsigned NumElem = Index->getType()->getVectorNumElements(); + return VectorType::get(PtrTy, NumElem); + } // Scalar GEP return PtrTy; } @@ -989,27 +1065,31 @@ GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, ArrayRef IdxList, unsigned Values, const Twine &NameStr, Instruction *InsertBefore) - : Instruction(getGEPReturnType(Ptr, IdxList), GetElementPtr, + : Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr, OperandTraits::op_end(this) - Values, - Values, InsertBefore) { + Values, InsertBefore), + SourceElementType(PointeeType), + ResultElementType(getIndexedType(PointeeType, IdxList)) { + assert(ResultElementType == + cast(getType()->getScalarType())->getElementType()); init(Ptr, IdxList, NameStr); - assert(!PointeeType || PointeeType == getSourceElementType()); } GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, ArrayRef IdxList, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd) - : Instruction(getGEPReturnType(Ptr, IdxList), GetElementPtr, + : Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr, OperandTraits::op_end(this) - Values, - Values, InsertAtEnd) { + Values, InsertAtEnd), + SourceElementType(PointeeType), + ResultElementType(getIndexedType(PointeeType, IdxList)) { + assert(ResultElementType == + cast(getType()->getScalarType())->getElementType()); init(Ptr, IdxList, NameStr); - assert(!PointeeType || PointeeType == getSourceElementType()); } - DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) - //===----------------------------------------------------------------------===// // ICmpInst Class //===----------------------------------------------------------------------===// @@ -1019,6 +1099,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) /// must be identical types. /// \brief Represent an integer comparison operator. class ICmpInst: public CmpInst { + void anchor() override; + void AssertOK() { assert(getPredicate() >= CmpInst::FIRST_ICMP_PREDICATE && getPredicate() <= CmpInst::LAST_ICMP_PREDICATE && @@ -1032,8 +1114,11 @@ class ICmpInst: public CmpInst { } protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical ICmpInst - ICmpInst *clone_impl() const override; + ICmpInst *cloneImpl() const; + public: /// \brief Constructor with insert-before-instruction semantics. ICmpInst( @@ -1151,7 +1236,6 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - }; //===----------------------------------------------------------------------===// @@ -1164,8 +1248,11 @@ public: /// \brief Represents a floating point comparison operator. class FCmpInst: public CmpInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical FCmpInst - FCmpInst *clone_impl() const override; + FCmpInst *cloneImpl() const; + public: /// \brief Constructor with insert-before-instruction semantics. FCmpInst( @@ -1272,40 +1359,102 @@ public: /// field to indicate whether or not this is a tail call. The rest of the bits /// hold the calling convention of the call. /// -class CallInst : public Instruction { +class CallInst : public Instruction, + public OperandBundleUser { AttributeSet AttributeList; ///< parameter attributes for call + FunctionType *FTy; CallInst(const CallInst &CI); - void init(Value *Func, ArrayRef Args, const Twine &NameStr); + void init(Value *Func, ArrayRef Args, + ArrayRef Bundles, const Twine &NameStr) { + init(cast( + cast(Func->getType())->getElementType()), + Func, Args, Bundles, NameStr); + } + void init(FunctionType *FTy, Value *Func, ArrayRef Args, + ArrayRef Bundles, const Twine &NameStr); void init(Value *Func, const Twine &NameStr); /// Construct a CallInst given a range of arguments. /// \brief Construct a CallInst from a range of arguments + inline CallInst(FunctionType *Ty, Value *Func, ArrayRef Args, + ArrayRef Bundles, const Twine &NameStr, + Instruction *InsertBefore); inline CallInst(Value *Func, ArrayRef Args, - const Twine &NameStr, Instruction *InsertBefore); + ArrayRef Bundles, const Twine &NameStr, + Instruction *InsertBefore) + : CallInst(cast( + cast(Func->getType())->getElementType()), + Func, Args, Bundles, NameStr, InsertBefore) {} + + inline CallInst(Value *Func, ArrayRef Args, const Twine &NameStr, + Instruction *InsertBefore) + : CallInst(Func, Args, None, NameStr, InsertBefore) {} /// Construct a CallInst given a range of arguments. /// \brief Construct a CallInst from a range of arguments inline CallInst(Value *Func, ArrayRef Args, - const Twine &NameStr, BasicBlock *InsertAtEnd); + ArrayRef Bundles, const Twine &NameStr, + BasicBlock *InsertAtEnd); explicit CallInst(Value *F, const Twine &NameStr, Instruction *InsertBefore); CallInst(Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd); + + friend class OperandBundleUser; + bool hasDescriptor() const { return HasDescriptor; } + protected: - CallInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + CallInst *cloneImpl() const; + public: - static CallInst *Create(Value *Func, - ArrayRef Args, + static CallInst *Create(Value *Func, ArrayRef Args, + ArrayRef Bundles = None, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + return Create(cast( + cast(Func->getType())->getElementType()), + Func, Args, Bundles, NameStr, InsertBefore); + } + static CallInst *Create(Value *Func, ArrayRef Args, + const Twine &NameStr, + Instruction *InsertBefore = nullptr) { + return Create(cast( + cast(Func->getType())->getElementType()), + Func, Args, None, NameStr, InsertBefore); + } + static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef Args, + const Twine &NameStr, + Instruction *InsertBefore = nullptr) { + return new (unsigned(Args.size() + 1)) + CallInst(Ty, Func, Args, None, NameStr, InsertBefore); + } + static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef Args, + ArrayRef Bundles = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { - return new(unsigned(Args.size() + 1)) - CallInst(Func, Args, NameStr, InsertBefore); + const unsigned TotalOps = + unsigned(Args.size()) + CountBundleInputs(Bundles) + 1; + const unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); + + return new (TotalOps, DescriptorBytes) + CallInst(Ty, Func, Args, Bundles, NameStr, InsertBefore); + } + static CallInst *Create(Value *Func, ArrayRef Args, + ArrayRef Bundles, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + const unsigned TotalOps = + unsigned(Args.size()) + CountBundleInputs(Bundles) + 1; + const unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); + + return new (TotalOps, DescriptorBytes) + CallInst(Func, Args, Bundles, NameStr, InsertAtEnd); } - static CallInst *Create(Value *Func, - ArrayRef Args, + static CallInst *Create(Value *Func, ArrayRef Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return new(unsigned(Args.size() + 1)) - CallInst(Func, Args, NameStr, InsertAtEnd); + return new (unsigned(Args.size() + 1)) + CallInst(Func, Args, None, NameStr, InsertAtEnd); } static CallInst *Create(Value *F, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { @@ -1315,6 +1464,16 @@ public: BasicBlock *InsertAtEnd) { return new(1) CallInst(F, NameStr, InsertAtEnd); } + + /// \brief Create a clone of \p CI with a different set of operand bundles and + /// insert it before \p InsertPt. + /// + /// The returned call instruction is identical \p CI in every way except that + /// the operand bundles for the new instruction are set to the operand bundles + /// in \p Bundles. + static CallInst *Create(CallInst *CI, ArrayRef Bundles, + Instruction *InsertPt = nullptr); + /// CreateMalloc - Generate the IR for a call to malloc: /// 1. Compute the malloc call's argument as the specified type's size, /// possibly multiplied by the array size if the array size is not @@ -1337,17 +1496,29 @@ public: ~CallInst() override; + FunctionType *getFunctionType() const { return FTy; } + + void mutateFunctionType(FunctionType *FTy) { + mutateType(FTy->getReturnType()); + this->FTy = FTy; + } + // Note that 'musttail' implies 'tail'. - enum TailCallKind { TCK_None = 0, TCK_Tail = 1, TCK_MustTail = 2 }; + enum TailCallKind { TCK_None = 0, TCK_Tail = 1, TCK_MustTail = 2, + TCK_NoTail = 3 }; TailCallKind getTailCallKind() const { return TailCallKind(getSubclassDataFromInstruction() & 3); } bool isTailCall() const { - return (getSubclassDataFromInstruction() & 3) != TCK_None; + unsigned Kind = getSubclassDataFromInstruction() & 3; + return Kind == TCK_Tail || Kind == TCK_MustTail; } bool isMustTailCall() const { return (getSubclassDataFromInstruction() & 3) == TCK_MustTail; } + bool isNoTailCall() const { + return (getSubclassDataFromInstruction() & 3) == TCK_NoTail; + } void setTailCall(bool isTC = true) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~3) | unsigned(isTC ? TCK_Tail : TCK_None)); @@ -1362,28 +1533,58 @@ public: /// getNumArgOperands - Return the number of call arguments. /// - unsigned getNumArgOperands() const { return getNumOperands() - 1; } + unsigned getNumArgOperands() const { + return getNumOperands() - getNumTotalBundleOperands() - 1; + } /// 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); + } + + /// \brief Return the iterator pointing to the beginning of the argument list. + op_iterator arg_begin() { return op_begin(); } + + /// \brief Return the iterator pointing to the end of the argument list. + op_iterator arg_end() { + // [ call args ], [ operand bundles ], callee + return op_end() - getNumTotalBundleOperands() - 1; + }; - /// arg_operands - iteration adapter for range-for loops. + /// \brief Iteration adapter for range-for loops. iterator_range arg_operands() { - // The last operand in the op list is the callee - it's not one of the args - // so we don't want to iterate over it. - return iterator_range(op_begin(), op_end() - 1); + return make_range(arg_begin(), arg_end()); } - /// arg_operands - iteration adapter for range-for loops. + /// \brief Return the iterator pointing to the beginning of the argument list. + const_op_iterator arg_begin() const { return op_begin(); } + + /// \brief Return the iterator pointing to the end of the argument list. + const_op_iterator arg_end() const { + // [ call args ], [ operand bundles ], callee + return op_end() - getNumTotalBundleOperands() - 1; + }; + + /// \brief Iteration adapter for range-for loops. iterator_range arg_operands() const { - return iterator_range(op_begin(), op_end() - 1); + return make_range(arg_begin(), arg_end()); } /// \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. @@ -1391,8 +1592,10 @@ public: return static_cast(getSubclassDataFromInstruction() >> 2); } void setCallingConv(CallingConv::ID CC) { + auto ID = static_cast(CC); + assert(!(ID & ~CallingConv::MaxID) && "Unsupported calling convention"); setInstructionSubclassData((getSubclassDataFromInstruction() & 3) | - (static_cast(CC) << 2)); + (ID << 2)); } /// getAttributes - Return the parameter attributes for this call. @@ -1406,6 +1609,9 @@ public: /// addAttribute - adds the attribute to the list of attributes. void addAttribute(unsigned i, Attribute::AttrKind attr); + /// addAttribute - adds the attribute to the list of attributes. + void addAttribute(unsigned i, StringRef Kind, StringRef Value); + /// removeAttribute - removes the attribute from the list of attributes. void removeAttribute(unsigned i, Attribute attr); @@ -1423,9 +1629,29 @@ public: return hasFnAttrImpl(A); } + /// \brief Determine whether this call has the given attribute. + bool hasFnAttr(StringRef A) const { + return hasFnAttrImpl(A); + } + /// \brief Determine whether the call or the callee has the given attributes. bool paramHasAttr(unsigned i, Attribute::AttrKind A) const; + /// \brief Return true if the data operand at index \p i has the attribute \p + /// A. + /// + /// Data operands include call arguments and values used in operand bundles, + /// but does not include the callee operand. This routine dispatches to the + /// underlying AttributeList or the OperandBundleUser as appropriate. + /// + /// The index \p i is interpreted as + /// + /// \p i == Attribute::ReturnIndex -> the return value + /// \p i in [1, arg_size + 1) -> argument number (\p i - 1) + /// \p i in [arg_size + 1, data_operand_size + 1) -> bundle operand at index + /// (\p i - 1) in the operand list. + bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind A) const; + /// \brief Extract the alignment for a call or parameter (0=unknown). unsigned getParamAlignment(unsigned i) const { return AttributeList.getParamAlignment(i); @@ -1437,6 +1663,19 @@ public: return AttributeList.getDereferenceableBytes(i); } + /// \brief Extract the number of dereferenceable_or_null bytes for a call or + /// parameter (0=unknown). + uint64_t getDereferenceableOrNullBytes(unsigned i) const { + return AttributeList.getDereferenceableOrNullBytes(i); + } + + /// @brief Determine if the parameter or return value is marked with NoAlias + /// attribute. + /// @param n The parameter to check. 1 is the first parameter, 0 is the return + bool doesNotAlias(unsigned n) const { + return AttributeList.hasAttribute(n, Attribute::NoAlias); + } + /// \brief Return true if the call should not be treated as a call to a /// builtin. bool isNoBuiltin() const { @@ -1474,6 +1713,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() { @@ -1492,9 +1740,18 @@ 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 { + if (getNumArgOperands() == 0) + return false; + // Be friendly and also check the callee. return paramHasAttr(1, Attribute::StructRet); } @@ -1518,6 +1775,14 @@ public: /// setCalledFunction - Set the function called. void setCalledFunction(Value* Fn) { + setCalledFunction( + cast(cast(Fn->getType())->getElementType()), + Fn); + } + void setCalledFunction(FunctionType *FTy, Value *Fn) { + this->FTy = FTy; + assert(FTy == cast( + cast(Fn->getType())->getElementType())); Op<-1>() = Fn; } @@ -1533,9 +1798,21 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: + template bool hasFnAttrImpl(AttrKind A) const { + if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A)) + return true; + + // Operand bundles override attributes on the called function, but don't + // override attributes directly present on the call instruction. + if (isFnAttrDisallowedByOpBundle(A)) + return false; - bool hasFnAttrImpl(Attribute::AttrKind A) const; + if (const Function *F = getCalledFunction()) + return F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, A); + return false; + } // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -1549,26 +1826,28 @@ struct OperandTraits : public VariadicOperandTraits { }; CallInst::CallInst(Value *Func, ArrayRef Args, - const Twine &NameStr, BasicBlock *InsertAtEnd) - : Instruction(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Call, - OperandTraits::op_end(this) - (Args.size() + 1), - unsigned(Args.size() + 1), InsertAtEnd) { - init(Func, Args, NameStr); + ArrayRef Bundles, const Twine &NameStr, + BasicBlock *InsertAtEnd) + : Instruction( + cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Call, OperandTraits::op_end(this) - + (Args.size() + CountBundleInputs(Bundles) + 1), + unsigned(Args.size() + CountBundleInputs(Bundles) + 1), InsertAtEnd) { + init(Func, Args, Bundles, NameStr); } -CallInst::CallInst(Value *Func, ArrayRef Args, - const Twine &NameStr, Instruction *InsertBefore) - : Instruction(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Call, - OperandTraits::op_end(this) - (Args.size() + 1), - unsigned(Args.size() + 1), InsertBefore) { - init(Func, Args, NameStr); +CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef Args, + ArrayRef Bundles, const Twine &NameStr, + Instruction *InsertBefore) + : Instruction(Ty->getReturnType(), Instruction::Call, + OperandTraits::op_end(this) - + (Args.size() + CountBundleInputs(Bundles) + 1), + unsigned(Args.size() + CountBundleInputs(Bundles) + 1), + InsertBefore) { + init(Ty, Func, Args, Bundles, NameStr); } - // Note: if you get compile errors about private methods then // please update your code to use the high-level operand // interfaces. See line 943 above. @@ -1602,8 +1881,12 @@ class SelectInst : public Instruction { init(C, S1, S2); setName(NameStr); } + protected: - SelectInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + SelectInst *cloneImpl() const; + public: static SelectInst *Create(Value *C, Value *S1, Value *S2, const Twine &NameStr = "", @@ -1658,7 +1941,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectInst, Value) /// class VAArgInst : public UnaryInstruction { protected: - VAArgInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + VAArgInst *cloneImpl() const; public: VAArgInst(Value *List, Type *Ty, const Twine &NameStr = "", @@ -1697,8 +1982,11 @@ class ExtractElementInst : public Instruction { Instruction *InsertBefore = nullptr); ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); + protected: - ExtractElementInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + ExtractElementInst *cloneImpl() const; public: static ExtractElementInst *Create(Value *Vec, Value *Idx, @@ -1725,7 +2013,6 @@ public: return cast(getVectorOperand()->getType()); } - /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -1756,10 +2043,13 @@ class InsertElementInst : public Instruction { InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr = "", Instruction *InsertBefore = nullptr); - InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, - const Twine &NameStr, BasicBlock *InsertAtEnd); + InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr, + BasicBlock *InsertAtEnd); + protected: - InsertElementInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + InsertElementInst *cloneImpl() const; public: static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx, @@ -1812,7 +2102,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value) /// class ShuffleVectorInst : public Instruction { protected: - ShuffleVectorInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + ShuffleVectorInst *cloneImpl() const; public: // allocate space for exactly three operands @@ -1866,7 +2158,6 @@ public: return Mask; } - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ShuffleVector; @@ -1909,11 +2200,12 @@ class ExtractValueInst : public UnaryInstruction { const Twine &NameStr, BasicBlock *InsertAtEnd); // allocate space for exactly one operand - void *operator new(size_t s) { - return User::operator new(s, 1); - } + void *operator new(size_t s) { return User::operator new(s, 1); } + protected: - ExtractValueInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + ExtractValueInst *cloneImpl() const; public: static ExtractValueInst *Create(Value *Agg, @@ -1940,7 +2232,7 @@ public: inline idx_iterator idx_begin() const { return Indices.begin(); } inline idx_iterator idx_end() const { return Indices.end(); } inline iterator_range indices() const { - return iterator_range(idx_begin(), idx_end()); + return make_range(idx_begin(), idx_end()); } Value *getAggregateOperand() { @@ -1991,7 +2283,6 @@ ExtractValueInst::ExtractValueInst(Value *Agg, init(Idxs, NameStr); } - //===----------------------------------------------------------------------===// // InsertValueInst Class //===----------------------------------------------------------------------===// @@ -2021,13 +2312,17 @@ class InsertValueInst : public Instruction { /// Constructors - These two constructors are convenience methods because one /// and two index insertvalue instructions are so common. - InsertValueInst(Value *Agg, Value *Val, - unsigned Idx, const Twine &NameStr = "", - Instruction *InsertBefore = nullptr); InsertValueInst(Value *Agg, Value *Val, unsigned Idx, - const Twine &NameStr, BasicBlock *InsertAtEnd); + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr); + InsertValueInst(Value *Agg, Value *Val, unsigned Idx, const Twine &NameStr, + BasicBlock *InsertAtEnd); + protected: - InsertValueInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + InsertValueInst *cloneImpl() const; + public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -2054,7 +2349,7 @@ public: inline idx_iterator idx_begin() const { return Indices.begin(); } inline idx_iterator idx_end() const { return Indices.end(); } inline iterator_range indices() const { - return iterator_range(idx_begin(), idx_end()); + return make_range(idx_begin(), idx_end()); } Value *getAggregateOperand() { @@ -2135,6 +2430,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value) // scientist's overactive imagination. // class PHINode : public Instruction { + void anchor() override; + void *operator new(size_t, unsigned) = delete; /// ReservedSpace - The number of operands actually allocated. NumOperands is /// the number actually in use. @@ -2142,7 +2439,7 @@ class PHINode : public Instruction { PHINode(const PHINode &PN); // allocate space for exactly zero operands void *operator new(size_t s) { - return User::operator new(s, 0); + return User::operator new(s); } explicit PHINode(Type *Ty, unsigned NumReservedValues, const Twine &NameStr = "", @@ -2150,7 +2447,7 @@ class PHINode : public Instruction { : Instruction(Ty, Instruction::PHI, nullptr, 0, InsertBefore), ReservedSpace(NumReservedValues) { setName(NameStr); - OperandList = allocHungoffUses(ReservedSpace); + allocHungoffUses(ReservedSpace); } PHINode(Type *Ty, unsigned NumReservedValues, const Twine &NameStr, @@ -2158,15 +2455,21 @@ class PHINode : public Instruction { : Instruction(Ty, Instruction::PHI, nullptr, 0, InsertAtEnd), ReservedSpace(NumReservedValues) { setName(NameStr); - OperandList = allocHungoffUses(ReservedSpace); + allocHungoffUses(ReservedSpace); } + protected: // allocHungoffUses - this is more complicated than the generic // User::allocHungoffUses, because we have to allocate Uses for the incoming // values and pointers to the incoming blocks, all in one allocation. - Use *allocHungoffUses(unsigned) const; + void allocHungoffUses(unsigned N) { + User::allocHungoffUses(N, /* IsPhi */ true); + } + + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + PHINode *cloneImpl() const; - PHINode *clone_impl() const override; public: /// Constructors - NumReservedValues is a hint for the number of incoming /// edges that this phi node will have (use 0 if you really have no idea). @@ -2179,7 +2482,6 @@ public: const Twine &NameStr, BasicBlock *InsertAtEnd) { return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd); } - ~PHINode() override; /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -2212,6 +2514,8 @@ public: op_range incoming_values() { return operands(); } + const_op_range incoming_values() const { return operands(); } + /// getNumIncomingValues - Return the number of incoming edges /// unsigned getNumIncomingValues() const { return getNumOperands(); } @@ -2222,6 +2526,9 @@ public: return getOperand(i); } void setIncomingValue(unsigned i, Value *V) { + assert(V && "PHI node got a null value!"); + assert(getType() == V->getType() && + "All operands to PHI node must be the same type as the PHI node!"); setOperand(i, V); } static unsigned getOperandNumForIncomingValue(unsigned i) { @@ -2253,22 +2560,19 @@ public: } void setIncomingBlock(unsigned i, BasicBlock *BB) { + assert(BB && "PHI node got a null basic block!"); block_begin()[i] = BB; } /// addIncoming - Add an incoming value to the end of the PHI list /// void addIncoming(Value *V, BasicBlock *BB) { - assert(V && "PHI node got a null value!"); - assert(BB && "PHI node got a null basic block!"); - assert(getType() == V->getType() && - "All operands to PHI node must be the same type as the PHI node!"); - if (NumOperands == ReservedSpace) + if (getNumOperands() == ReservedSpace) growOperands(); // Get more space! // Initialize some new operands. - ++NumOperands; - setIncomingValue(NumOperands - 1, V); - setIncomingBlock(NumOperands - 1, BB); + setNumHungOffUseOperands(getNumOperands() + 1); + setIncomingValue(getNumOperands() - 1, V); + setIncomingBlock(getNumOperands() - 1, BB); } /// removeIncomingValue - Remove an incoming value. This is useful if a @@ -2314,7 +2618,8 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - private: + +private: void growOperands(); }; @@ -2341,44 +2646,41 @@ class LandingPadInst : public Instruction { /// the number actually in use. unsigned ReservedSpace; LandingPadInst(const LandingPadInst &LP); + public: enum ClauseType { Catch, Filter }; + private: void *operator new(size_t, unsigned) = delete; // Allocate space for exactly zero operands. void *operator new(size_t s) { - return User::operator new(s, 0); + return User::operator new(s); } void growOperands(unsigned Size); - void init(Value *PersFn, unsigned NumReservedValues, const Twine &NameStr); + void init(unsigned NumReservedValues, const Twine &NameStr); + + explicit LandingPadInst(Type *RetTy, unsigned NumReservedValues, + const Twine &NameStr, Instruction *InsertBefore); + explicit LandingPadInst(Type *RetTy, unsigned NumReservedValues, + const Twine &NameStr, BasicBlock *InsertAtEnd); - explicit LandingPadInst(Type *RetTy, Value *PersonalityFn, - unsigned NumReservedValues, const Twine &NameStr, - Instruction *InsertBefore); - explicit LandingPadInst(Type *RetTy, Value *PersonalityFn, - unsigned NumReservedValues, const Twine &NameStr, - BasicBlock *InsertAtEnd); protected: - LandingPadInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + LandingPadInst *cloneImpl() const; + public: /// Constructors - NumReservedClauses is a hint for the number of incoming /// clauses that this landingpad will have (use 0 if you really have no idea). - static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn, - unsigned NumReservedClauses, + static LandingPadInst *Create(Type *RetTy, unsigned NumReservedClauses, const Twine &NameStr = "", Instruction *InsertBefore = nullptr); - static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn, - unsigned NumReservedClauses, + static LandingPadInst *Create(Type *RetTy, unsigned NumReservedClauses, const Twine &NameStr, BasicBlock *InsertAtEnd); - ~LandingPadInst() override; /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - /// getPersonalityFn - Get the personality function associated with this - /// landing pad. - Value *getPersonalityFn() const { return getOperand(0); } - /// isCleanup - Return 'true' if this landingpad instruction is a /// cleanup. I.e., it should be run when unwinding even if its landing pad /// doesn't catch the exception. @@ -2396,21 +2698,21 @@ public: /// Get the value of the clause at index Idx. Use isCatch/isFilter to /// determine what type of clause this is. Constant *getClause(unsigned Idx) const { - return cast(OperandList[Idx + 1]); + return cast(getOperandList()[Idx]); } /// isCatch - Return 'true' if the clause and index Idx is a catch clause. bool isCatch(unsigned Idx) const { - return !isa(OperandList[Idx + 1]->getType()); + return !isa(getOperandList()[Idx]->getType()); } /// isFilter - Return 'true' if the clause and index Idx is a filter clause. bool isFilter(unsigned Idx) const { - return isa(OperandList[Idx + 1]->getType()); + return isa(getOperandList()[Idx]->getType()); } /// getNumClauses - Get the number of clauses for this landing pad. - unsigned getNumClauses() const { return getNumOperands() - 1; } + unsigned getNumClauses() const { return getNumOperands(); } /// reserveClauses - Grow the size of the operand list to accommodate the new /// number of clauses. @@ -2426,7 +2728,7 @@ public: }; template <> -struct OperandTraits : public HungoffOperandTraits<2> { +struct OperandTraits : public HungoffOperandTraits<1> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(LandingPadInst, Value) @@ -2458,8 +2760,12 @@ private: Instruction *InsertBefore = nullptr); ReturnInst(LLVMContext &C, Value *retVal, BasicBlock *InsertAtEnd); explicit ReturnInst(LLVMContext &C, BasicBlock *InsertAtEnd); + protected: - ReturnInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + ReturnInst *cloneImpl() const; + public: static ReturnInst* Create(LLVMContext &C, Value *retVal = nullptr, Instruction *InsertBefore = nullptr) { @@ -2491,7 +2797,8 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - private: + +private: BasicBlock *getSuccessorV(unsigned idx) const override; unsigned getNumSuccessorsV() const override; void setSuccessorV(unsigned idx, BasicBlock *B) override; @@ -2530,8 +2837,12 @@ class BranchInst : public TerminatorInst { BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd); BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, BasicBlock *InsertAtEnd); + protected: - BranchInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + BranchInst *cloneImpl() const; + public: static BranchInst *Create(BasicBlock *IfTrue, Instruction *InsertBefore = nullptr) { @@ -2574,7 +2885,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. @@ -2591,6 +2902,7 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: BasicBlock *getSuccessorV(unsigned idx) const override; unsigned getNumSuccessorsV() const override; @@ -2622,7 +2934,7 @@ class SwitchInst : public TerminatorInst { void growOperands(); // allocate space for exactly zero operands void *operator new(size_t s) { - return User::operator new(s, 0); + return User::operator new(s); } /// SwitchInst ctor - Create a new switch instruction, specifying a value to /// switch on and a default destination. The number of additional cases can @@ -2637,22 +2949,23 @@ class SwitchInst : public TerminatorInst { /// constructor also autoinserts at the end of the specified BasicBlock. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd); + protected: - SwitchInst *clone_impl() const override; -public: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + SwitchInst *cloneImpl() const; +public: // -2 static const unsigned DefaultPseudoIndex = static_cast(~0L-1); template class CaseIteratorT { protected: - SwitchInstTy *SI; unsigned Index; public: - typedef CaseIteratorT Self; /// Initializes case iterator for given SwitchInst and for given @@ -2743,8 +3056,7 @@ public: typedef CaseIteratorT ParentTy; public: - - CaseIt(const ParentTy& Src) : ParentTy(Src) {} + CaseIt(const ParentTy &Src) : ParentTy(Src) {} CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {} /// Sets the new value for current case. @@ -2769,8 +3081,6 @@ public: return new SwitchInst(Value, Default, NumCases, InsertAtEnd); } - ~SwitchInst() override; - /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -2816,12 +3126,12 @@ public: /// cases - iteration adapter for range-for loops. iterator_range cases() { - return iterator_range(case_begin(), case_end()); + return make_range(case_begin(), case_end()); } /// cases - iteration adapter for range-for loops. iterator_range cases() const { - return iterator_range(case_begin(), case_end()); + return make_range(case_begin(), case_end()); } /// Returns an iterator that points to the default case. @@ -2889,7 +3199,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: @@ -2899,6 +3209,7 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: BasicBlock *getSuccessorV(unsigned idx) const override; unsigned getNumSuccessorsV() const override; @@ -2911,7 +3222,6 @@ struct OperandTraits : public HungoffOperandTraits<2> { DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value) - //===----------------------------------------------------------------------===// // IndirectBrInst Class //===----------------------------------------------------------------------===// @@ -2931,7 +3241,7 @@ class IndirectBrInst : public TerminatorInst { void growOperands(); // allocate space for exactly zero operands void *operator new(size_t s) { - return User::operator new(s, 0); + return User::operator new(s); } /// IndirectBrInst ctor - Create a new indirectbr instruction, specifying an /// Address to jump to. The number of expected destinations can be specified @@ -2944,8 +3254,12 @@ class IndirectBrInst : public TerminatorInst { /// here to make memory allocation more efficient. This constructor also /// autoinserts at the end of the specified BasicBlock. IndirectBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd); + protected: - IndirectBrInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + IndirectBrInst *cloneImpl() const; + public: static IndirectBrInst *Create(Value *Address, unsigned NumDests, Instruction *InsertBefore = nullptr) { @@ -2955,7 +3269,6 @@ public: BasicBlock *InsertAtEnd) { return new IndirectBrInst(Address, NumDests, InsertAtEnd); } - ~IndirectBrInst() override; /// Provide fast operand accessors. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -2965,7 +3278,6 @@ public: const Value *getAddress() const { return getOperand(0); } void setAddress(Value *V) { setOperand(0, V); } - /// getNumDestinations - return the number of possible destinations in this /// indirectbr instruction. unsigned getNumDestinations() const { return getNumOperands()-1; } @@ -2987,7 +3299,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: @@ -2997,6 +3309,7 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: BasicBlock *getSuccessorV(unsigned idx) const override; unsigned getNumSuccessorsV() const override; @@ -3009,7 +3322,6 @@ struct OperandTraits : public HungoffOperandTraits<1> { DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value) - //===----------------------------------------------------------------------===// // InvokeInst Class //===----------------------------------------------------------------------===// @@ -3017,70 +3329,187 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value) /// InvokeInst - Invoke instruction. The SubclassData field is used to hold the /// calling convention of the call. /// -class InvokeInst : public TerminatorInst { +class InvokeInst : public TerminatorInst, + public OperandBundleUser { AttributeSet AttributeList; + FunctionType *FTy; InvokeInst(const InvokeInst &BI); void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef Args, const Twine &NameStr); + ArrayRef Args, ArrayRef Bundles, + const Twine &NameStr) { + init(cast( + cast(Func->getType())->getElementType()), + Func, IfNormal, IfException, Args, Bundles, NameStr); + } + void init(FunctionType *FTy, Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef Args, + ArrayRef Bundles, const Twine &NameStr); /// Construct an InvokeInst given a range of arguments. /// /// \brief Construct an InvokeInst from a range of arguments inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef Args, unsigned Values, + ArrayRef Args, ArrayRef Bundles, + unsigned Values, const Twine &NameStr, + Instruction *InsertBefore) + : InvokeInst(cast( + cast(Func->getType())->getElementType()), + Func, IfNormal, IfException, Args, Bundles, Values, NameStr, + InsertBefore) {} + + inline InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef Args, + ArrayRef Bundles, unsigned Values, const Twine &NameStr, Instruction *InsertBefore); - /// Construct an InvokeInst given a range of arguments. /// /// \brief Construct an InvokeInst from a range of arguments inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef Args, unsigned Values, - const Twine &NameStr, BasicBlock *InsertAtEnd); + ArrayRef Args, ArrayRef Bundles, + unsigned Values, const Twine &NameStr, + BasicBlock *InsertAtEnd); + + friend class OperandBundleUser; + bool hasDescriptor() const { return HasDescriptor; } + protected: - InvokeInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + InvokeInst *cloneImpl() const; + public: - static InvokeInst *Create(Value *Func, - BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef Args, const Twine &NameStr = "", + static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef Args, + const Twine &NameStr, + Instruction *InsertBefore = nullptr) { + return Create(cast( + cast(Func->getType())->getElementType()), + Func, IfNormal, IfException, Args, None, NameStr, + InsertBefore); + } + static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef Args, + ArrayRef Bundles = None, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + return Create(cast( + cast(Func->getType())->getElementType()), + Func, IfNormal, IfException, Args, Bundles, NameStr, + InsertBefore); + } + static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef Args, + const Twine &NameStr, Instruction *InsertBefore = nullptr) { unsigned Values = unsigned(Args.size()) + 3; - return new(Values) InvokeInst(Func, IfNormal, IfException, Args, - Values, NameStr, InsertBefore); + return new (Values) InvokeInst(Ty, Func, IfNormal, IfException, Args, None, + Values, NameStr, InsertBefore); + } + static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef Args, + ArrayRef Bundles = None, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + unsigned Values = unsigned(Args.size()) + CountBundleInputs(Bundles) + 3; + unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); + + return new (Values, DescriptorBytes) + InvokeInst(Ty, Func, IfNormal, IfException, Args, Bundles, Values, + NameStr, InsertBefore); } static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { unsigned Values = unsigned(Args.size()) + 3; - return new(Values) InvokeInst(Func, IfNormal, IfException, Args, - Values, NameStr, InsertAtEnd); + return new (Values) InvokeInst(Func, IfNormal, IfException, Args, None, + Values, NameStr, InsertAtEnd); } + static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef Args, + ArrayRef Bundles, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + unsigned Values = unsigned(Args.size()) + CountBundleInputs(Bundles) + 3; + unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); + + return new (Values, DescriptorBytes) + InvokeInst(Func, IfNormal, IfException, Args, Bundles, Values, NameStr, + InsertAtEnd); + } + + /// \brief Create a clone of \p II with a different set of operand bundles and + /// insert it before \p InsertPt. + /// + /// The returned invoke instruction is identical to \p II in every way except + /// that the operand bundles for the new instruction are set to the operand + /// bundles in \p Bundles. + static InvokeInst *Create(InvokeInst *II, ArrayRef Bundles, + Instruction *InsertPt = nullptr); /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + FunctionType *getFunctionType() const { return FTy; } + + void mutateFunctionType(FunctionType *FTy) { + mutateType(FTy->getReturnType()); + this->FTy = FTy; + } + /// getNumArgOperands - Return the number of invoke arguments. /// - unsigned getNumArgOperands() const { return getNumOperands() - 3; } + unsigned getNumArgOperands() const { + return getNumOperands() - getNumTotalBundleOperands() - 3; + } /// 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); + } + + /// \brief Return the iterator pointing to the beginning of the argument list. + op_iterator arg_begin() { return op_begin(); } + + /// \brief Return the iterator pointing to the end of the argument list. + op_iterator arg_end() { + // [ invoke args ], [ operand bundles ], normal dest, unwind dest, callee + return op_end() - getNumTotalBundleOperands() - 3; + }; - /// arg_operands - iteration adapter for range-for loops. + /// \brief Iteration adapter for range-for loops. iterator_range arg_operands() { - return iterator_range(op_begin(), op_end() - 3); + return make_range(arg_begin(), arg_end()); } - /// arg_operands - iteration adapter for range-for loops. + /// \brief Return the iterator pointing to the beginning of the argument list. + const_op_iterator arg_begin() const { return op_begin(); } + + /// \brief Return the iterator pointing to the end of the argument list. + const_op_iterator arg_end() const { + // [ invoke args ], [ operand bundles ], normal dest, unwind dest, callee + return op_end() - getNumTotalBundleOperands() - 3; + }; + + /// \brief Iteration adapter for range-for loops. iterator_range arg_operands() const { - return iterator_range(op_begin(), op_end() - 3); + return make_range(arg_begin(), arg_end()); } /// \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. @@ -3088,7 +3517,9 @@ public: return static_cast(getSubclassDataFromInstruction()); } void setCallingConv(CallingConv::ID CC) { - setInstructionSubclassData(static_cast(CC)); + auto ID = static_cast(CC); + assert(!(ID & ~CallingConv::MaxID) && "Unsupported calling convention"); + setInstructionSubclassData(ID); } /// getAttributes - Return the parameter attributes for this invoke. @@ -3119,9 +3550,30 @@ public: return hasFnAttrImpl(A); } + /// \brief Determine whether this call has the given attribute. + bool hasFnAttr(StringRef A) const { + return hasFnAttrImpl(A); + } + /// \brief Determine whether the call or the callee has the given attributes. bool paramHasAttr(unsigned i, Attribute::AttrKind A) const; + /// \brief Return true if the data operand at index \p i has the attribute \p + /// A. + /// + /// Data operands include invoke arguments and values used in operand bundles, + /// but does not include the invokee operand, or the two successor blocks. + /// This routine dispatches to the underlying AttributeList or the + /// OperandBundleUser as appropriate. + /// + /// The index \p i is interpreted as + /// + /// \p i == Attribute::ReturnIndex -> the return value + /// \p i in [1, arg_size + 1) -> argument number (\p i - 1) + /// \p i in [arg_size + 1, data_operand_size + 1) -> bundle operand at index + /// (\p i - 1) in the operand list. + bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind A) const; + /// \brief Extract the alignment for a call or parameter (0=unknown). unsigned getParamAlignment(unsigned i) const { return AttributeList.getParamAlignment(i); @@ -3133,6 +3585,19 @@ public: return AttributeList.getDereferenceableBytes(i); } + /// \brief Extract the number of dereferenceable_or_null bytes for a call or + /// parameter (0=unknown). + uint64_t getDereferenceableOrNullBytes(unsigned i) const { + return AttributeList.getDereferenceableOrNullBytes(i); + } + + /// @brief Determine if the parameter or return value is marked with NoAlias + /// attribute. + /// @param n The parameter to check. 1 is the first parameter, 0 is the return + bool doesNotAlias(unsigned n) const { + return AttributeList.hasAttribute(n, Attribute::NoAlias); + } + /// \brief Return true if the call should not be treated as a call to a /// builtin. bool isNoBuiltin() const { @@ -3164,6 +3629,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() { @@ -3185,6 +3659,9 @@ public: /// \brief Determine if the call returns a structure through first /// pointer argument. bool hasStructRetAttr() const { + if (getNumArgOperands() == 0) + return false; + // Be friendly and also check the callee. return paramHasAttr(1, Attribute::StructRet); } @@ -3208,6 +3685,14 @@ public: /// setCalledFunction - Set the function called. void setCalledFunction(Value* Fn) { + setCalledFunction( + cast(cast(Fn->getType())->getElementType()), + Fn); + } + void setCalledFunction(FunctionType *FTy, Value *Fn) { + this->FTy = FTy; + assert(FTy == cast( + cast(Fn->getType())->getElementType())); Op<-3>() = Fn; } @@ -3254,7 +3739,19 @@ private: unsigned getNumSuccessorsV() const override; void setSuccessorV(unsigned idx, BasicBlock *B) override; - bool hasFnAttrImpl(Attribute::AttrKind A) const; + template bool hasFnAttrImpl(AttrKind A) const { + if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A)) + return true; + + // Operand bundles override attributes on the called function, but don't + // override attributes directly present on the invoke instruction. + if (isFnAttrDisallowedByOpBundle(A)) + return false; + + if (const Function *F = getCalledFunction()) + return F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, A); + return false; + } // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -3267,27 +3764,25 @@ template <> struct OperandTraits : public VariadicOperandTraits { }; -InvokeInst::InvokeInst(Value *Func, - BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef Args, unsigned Values, +InvokeInst::InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef Args, + ArrayRef Bundles, unsigned Values, const Twine &NameStr, Instruction *InsertBefore) - : TerminatorInst(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Invoke, - OperandTraits::op_end(this) - Values, - Values, InsertBefore) { - init(Func, IfNormal, IfException, Args, NameStr); + : TerminatorInst(Ty->getReturnType(), Instruction::Invoke, + OperandTraits::op_end(this) - Values, Values, + InsertBefore) { + init(Ty, Func, IfNormal, IfException, Args, Bundles, NameStr); } -InvokeInst::InvokeInst(Value *Func, - BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef Args, unsigned Values, +InvokeInst::InvokeInst(Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef Args, + ArrayRef Bundles, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd) - : TerminatorInst(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Invoke, - OperandTraits::op_end(this) - Values, - Values, InsertAtEnd) { - init(Func, IfNormal, IfException, Args, NameStr); + : TerminatorInst( + cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Invoke, OperandTraits::op_end(this) - Values, + Values, InsertAtEnd) { + init(Func, IfNormal, IfException, Args, Bundles, NameStr); } DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value) @@ -3304,8 +3799,12 @@ class ResumeInst : public TerminatorInst { explicit ResumeInst(Value *Exn, Instruction *InsertBefore=nullptr); ResumeInst(Value *Exn, BasicBlock *InsertAtEnd); + protected: - ResumeInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + ResumeInst *cloneImpl() const; + public: static ResumeInst *Create(Value *Exn, Instruction *InsertBefore = nullptr) { return new(1) ResumeInst(Exn, InsertBefore); @@ -3329,6 +3828,7 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: BasicBlock *getSuccessorV(unsigned idx) const override; unsigned getNumSuccessorsV() const override; @@ -3342,6 +3842,432 @@ struct OperandTraits : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value) +//===----------------------------------------------------------------------===// +// 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); + + /// 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; + CatchSwitchInst *cloneImpl() const; + +public: + static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + return new CatchSwitchInst(ParentPad, UnwindDest, NumHandlers, NameStr, + InsertBefore); + } + static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, const Twine &NameStr, + BasicBlock *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(); } + BasicBlock *getUnwindDest() const { + if (hasUnwindDest()) + return cast(getOperand(1)); + return nullptr; + } + void setUnwindDest(BasicBlock *UnwindDest) { + assert(UnwindDest); + assert(hasUnwindDest()); + setOperand(1, UnwindDest); + } + + /// 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: + static BasicBlock *handler_helper(Value *V) { return cast(V); } + static const BasicBlock *handler_helper(const Value *V) { + return cast(V); + } + +public: + typedef std::pointer_to_unary_function DerefFnTy; + typedef mapped_iterator handler_iterator; + typedef iterator_range handler_range; + + + typedef std::pointer_to_unary_function + ConstDerefFnTy; + typedef mapped_iterator const_handler_iterator; + typedef iterator_range const_handler_range; + + /// 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)); + } + + /// 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)); + } + + /// handlers - iteration adapter for range-for loops. + handler_range handlers() { + return make_range(handler_begin(), handler_end()); + } + + /// handlers - iteration adapter for range-for loops. + const_handler_range handlers() const { + return make_range(handler_begin(), handler_end()); + } + + /// 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); + + void removeHandler(handler_iterator HI); + + unsigned getNumSuccessors() const { return getNumOperands() - 1; } + BasicBlock *getSuccessor(unsigned Idx) const { + assert(Idx < getNumSuccessors() && + "Successor # out of range for catchswitch!"); + return cast(getOperand(Idx + 1)); + } + void setSuccessor(unsigned Idx, BasicBlock *NewSucc) { + assert(Idx < getNumSuccessors() && + "Successor # out of range for catchswitch!"); + setOperand(Idx + 1, NewSucc); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::CatchSwitch; + } + 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; +}; + +template <> +struct OperandTraits : public HungoffOperandTraits<2> {}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchSwitchInst, Value) + +//===----------------------------------------------------------------------===// +// CleanupPadInst Class +//===----------------------------------------------------------------------===// +class CleanupPadInst : public FuncletPadInst { +private: + explicit CleanupPadInst(Value *ParentPad, ArrayRef Args, + unsigned Values, const Twine &NameStr, + Instruction *InsertBefore) + : FuncletPadInst(Instruction::CleanupPad, ParentPad, Args, Values, + NameStr, InsertBefore) {} + explicit CleanupPadInst(Value *ParentPad, ArrayRef Args, + unsigned Values, const Twine &NameStr, + BasicBlock *InsertAtEnd) + : FuncletPadInst(Instruction::CleanupPad, ParentPad, Args, Values, + NameStr, InsertAtEnd) {} + +public: + static CleanupPadInst *Create(Value *ParentPad, ArrayRef Args = None, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + unsigned Values = 1 + Args.size(); + return new (Values) + CleanupPadInst(ParentPad, Args, Values, NameStr, InsertBefore); + } + static CleanupPadInst *Create(Value *ParentPad, ArrayRef Args, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + unsigned Values = 1 + Args.size(); + return new (Values) + CleanupPadInst(ParentPad, Args, Values, NameStr, InsertAtEnd); + } + + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::CleanupPad; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// CatchPadInst Class +//===----------------------------------------------------------------------===// +class CatchPadInst : public FuncletPadInst { +private: + explicit CatchPadInst(Value *CatchSwitch, ArrayRef Args, + unsigned Values, const Twine &NameStr, + Instruction *InsertBefore) + : FuncletPadInst(Instruction::CatchPad, CatchSwitch, Args, Values, + NameStr, InsertBefore) {} + explicit CatchPadInst(Value *CatchSwitch, ArrayRef Args, + unsigned Values, const Twine &NameStr, + BasicBlock *InsertAtEnd) + : FuncletPadInst(Instruction::CatchPad, CatchSwitch, Args, Values, + NameStr, InsertAtEnd) {} + +public: + static CatchPadInst *Create(Value *CatchSwitch, ArrayRef 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 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(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(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// CatchReturnInst Class +//===----------------------------------------------------------------------===// + +class CatchReturnInst : public TerminatorInst { + CatchReturnInst(const CatchReturnInst &RI); + + 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. + friend class Instruction; + CatchReturnInst *cloneImpl() const; + +public: + static CatchReturnInst *Create(Value *CatchPad, BasicBlock *BB, + Instruction *InsertBefore = nullptr) { + assert(CatchPad); + assert(BB); + return new (2) CatchReturnInst(CatchPad, BB, InsertBefore); + } + static CatchReturnInst *Create(Value *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. + 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; } + + 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); + } + 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; +}; + +template <> +struct OperandTraits + : public FixedNumOperandTraits {}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value) + +//===----------------------------------------------------------------------===// +// CleanupReturnInst Class +//===----------------------------------------------------------------------===// + +class CleanupReturnInst : public TerminatorInst { +private: + CleanupReturnInst(const CleanupReturnInst &RI); + + 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. + friend class Instruction; + CleanupReturnInst *cloneImpl() const; + +public: + static CleanupReturnInst *Create(Value *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(Value *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<0>()); + } + void setCleanupPad(CleanupPadInst *CleanupPad) { + assert(CleanupPad); + Op<0>() = CleanupPad; + } + + unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; } + + BasicBlock *getUnwindDest() const { + return hasUnwindDest() ? cast(Op<1>()) : nullptr; + } + void setUnwindDest(BasicBlock *NewDest) { + assert(NewDest); + assert(hasUnwindDest()); + 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::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 //===----------------------------------------------------------------------===// @@ -3353,8 +4279,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value) /// class UnreachableInst : public TerminatorInst { void *operator new(size_t, unsigned) = delete; + protected: - UnreachableInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + UnreachableInst *cloneImpl() const; public: // allocate space for exactly zero operands @@ -3373,6 +4302,7 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: BasicBlock *getSuccessorV(unsigned idx) const override; unsigned getNumSuccessorsV() const override; @@ -3386,8 +4316,10 @@ private: /// \brief This class represents a truncation of integer types. class TruncInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical TruncInst - TruncInst *clone_impl() const override; + TruncInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3422,8 +4354,10 @@ public: /// \brief This class represents zero extension of integer types. class ZExtInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical ZExtInst - ZExtInst *clone_impl() const override; + ZExtInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3458,8 +4392,10 @@ public: /// \brief This class represents a sign extension of integer types. class SExtInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical SExtInst - SExtInst *clone_impl() const override; + SExtInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3494,8 +4430,10 @@ public: /// \brief This class represents a truncation of floating point types. class FPTruncInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical FPTruncInst - FPTruncInst *clone_impl() const override; + FPTruncInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3530,8 +4468,10 @@ public: /// \brief This class represents an extension of floating point types. class FPExtInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical FPExtInst - FPExtInst *clone_impl() const override; + FPExtInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3566,8 +4506,10 @@ public: /// \brief This class represents a cast unsigned integer to floating point. class UIToFPInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical UIToFPInst - UIToFPInst *clone_impl() const override; + UIToFPInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3602,8 +4544,10 @@ public: /// \brief This class represents a cast from signed integer to floating point. class SIToFPInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical SIToFPInst - SIToFPInst *clone_impl() const override; + SIToFPInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3638,8 +4582,10 @@ public: /// \brief This class represents a cast from floating point to unsigned integer class FPToUIInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical FPToUIInst - FPToUIInst *clone_impl() const override; + FPToUIInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3674,8 +4620,10 @@ public: /// \brief This class represents a cast from floating point to signed integer. class FPToSIInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical FPToSIInst - FPToSIInst *clone_impl() const override; + FPToSIInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3726,8 +4674,10 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical IntToPtrInst - IntToPtrInst *clone_impl() const override; + IntToPtrInst *cloneImpl() const; /// \brief Returns the address space of this instruction's pointer type. unsigned getAddressSpace() const { @@ -3750,8 +4700,10 @@ public: /// \brief This class represents a cast from a pointer to an integer class PtrToIntInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical PtrToIntInst - PtrToIntInst *clone_impl() const override; + PtrToIntInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3798,8 +4750,10 @@ public: /// \brief This class represents a no-op cast from one type to another. class BitCastInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical BitCastInst - BitCastInst *clone_impl() const override; + BitCastInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3835,8 +4789,10 @@ public: /// one address space to another. class AddrSpaceCastInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical AddrSpaceCastInst - AddrSpaceCastInst *clone_impl() const override; + AddrSpaceCastInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics