#define LLVM_IR_INSTRUCTIONS_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallVector.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 <iterator>
/// 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 = "",
const Twine &Name, BasicBlock *InsertAtEnd);
// Out of line virtual method, so the vtable, etc. has a home.
- virtual ~AllocaInst();
+ ~AllocaInst() override;
/// isArrayAllocation - Return true if there is an allocation size parameter
/// to the allocation instruction that is not 1.
/// 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.
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<PointerType>(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<PointerType>(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);
- LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+ LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align,
+ AtomicOrdering Order, SynchronizationScope SynchScope = CrossThread,
+ Instruction *InsertBefore = nullptr)
+ : LoadInst(cast<PointerType>(Ptr->getType())->getElementType(), Ptr,
+ NameStr, isVolatile, Align, Order, SynchScope, InsertBefore) {}
+ LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
unsigned Align, AtomicOrdering Order,
SynchronizationScope SynchScope = CrossThread,
Instruction *InsertBefore = nullptr);
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<PointerType>(Ptr->getType())->getElementType(), Ptr,
+ NameStr, isVolatile, InsertBefore) {}
LoadInst(Value *Ptr, const char *NameStr, bool isVolatile,
BasicBlock *InsertAtEnd);
/// StoreInst - an instruction for storing to memory
///
class StoreInst : public Instruction {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ 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) {
/// FenceInst - an instruction for ordering other memory operations
///
class FenceInst : public Instruction {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ 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) {
/// there. Returns the value that was loaded.
///
class AtomicCmpXchgInst : public Instruction {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
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) {
/// the old value.
///
class AtomicRMWInst : public Instruction {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ 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,
/// access elements of arrays and structs
///
class GetElementPtrInst : public Instruction {
+ Type *SourceElementType;
+ Type *ResultElementType;
+
GetElementPtrInst(const GetElementPtrInst &GEPI);
void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr);
/// list of indices. The first ctor can optionally insert before an existing
/// instruction, the second appends the new instruction to the specified
/// BasicBlock.
- inline GetElementPtrInst(Value *Ptr, ArrayRef<Value *> IdxList,
- unsigned Values, const Twine &NameStr,
- Instruction *InsertBefore);
- inline GetElementPtrInst(Value *Ptr, ArrayRef<Value *> IdxList,
- unsigned Values, const Twine &NameStr,
- BasicBlock *InsertAtEnd);
+ inline GetElementPtrInst(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, unsigned Values,
+ const Twine &NameStr, Instruction *InsertBefore);
+ inline GetElementPtrInst(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, unsigned Values,
+ 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(Value *Ptr, ArrayRef<Value *> IdxList,
+ static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
unsigned Values = 1 + unsigned(IdxList.size());
- return new(Values)
- GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertBefore);
- }
- static GetElementPtrInst *Create(Value *Ptr, ArrayRef<Value *> IdxList,
+ if (!PointeeType)
+ PointeeType =
+ cast<PointerType>(Ptr->getType()->getScalarType())->getElementType();
+ else
+ assert(
+ PointeeType ==
+ cast<PointerType>(Ptr->getType()->getScalarType())->getElementType());
+ return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values,
+ NameStr, InsertBefore);
+ }
+ static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
unsigned Values = 1 + unsigned(IdxList.size());
- return new(Values)
- GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertAtEnd);
+ if (!PointeeType)
+ PointeeType =
+ cast<PointerType>(Ptr->getType()->getScalarType())->getElementType();
+ else
+ assert(
+ PointeeType ==
+ cast<PointerType>(Ptr->getType()->getScalarType())->getElementType());
+ return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values,
+ NameStr, InsertAtEnd);
}
/// Create an "inbounds" getelementptr. See the documentation for the
ArrayRef<Value *> IdxList,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr){
- GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertBefore);
+ return CreateInBounds(nullptr, Ptr, IdxList, NameStr, InsertBefore);
+ }
+ static GetElementPtrInst *
+ CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef<Value *> IdxList,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
+ GetElementPtrInst *GEP =
+ Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore);
GEP->setIsInBounds(true);
return GEP;
}
ArrayRef<Value *> IdxList,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
- GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertAtEnd);
+ return CreateInBounds(nullptr, Ptr, IdxList, NameStr, InsertAtEnd);
+ }
+ static GetElementPtrInst *CreateInBounds(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ GetElementPtrInst *GEP =
+ Create(PointeeType, Ptr, IdxList, NameStr, InsertAtEnd);
GEP->setIsInBounds(true);
return GEP;
}
return cast<SequentialType>(Instruction::getType());
}
+ Type *getSourceElementType() const { return SourceElementType; }
+
+ void setSourceElementType(Type *Ty) { SourceElementType = Ty; }
+ void setResultElementType(Type *Ty) { ResultElementType = Ty; }
+
+ Type *getResultElementType() const {
+ assert(ResultElementType ==
+ cast<PointerType>(getType()->getScalarType())->getElementType());
+ return ResultElementType;
+ }
+
/// \brief Returns the address space of this instruction's pointer type.
unsigned getAddressSpace() const {
// Note that this is always the same as the pointer operand's address space
/// Null is returned if the indices are invalid for the specified
/// pointer type.
///
- static Type *getIndexedType(Type *Ptr, ArrayRef<Value *> IdxList);
- static Type *getIndexedType(Type *Ptr, ArrayRef<Constant *> IdxList);
- static Type *getIndexedType(Type *Ptr, ArrayRef<uint64_t> IdxList);
+ static Type *getIndexedType(Type *Ty, ArrayRef<Value *> IdxList);
+ static Type *getIndexedType(Type *Ty, ArrayRef<Constant *> IdxList);
+ static Type *getIndexedType(Type *Ty, ArrayRef<uint64_t> IdxList);
inline op_iterator idx_begin() { return op_begin()+1; }
inline const_op_iterator idx_begin() const { return op_begin()+1; }
/// GetGEPReturnType - Returns the pointer type returned by the GEP
/// instruction, which may be a vector of pointers.
static Type *getGEPReturnType(Value *Ptr, ArrayRef<Value *> IdxList) {
- Type *PtrTy = PointerType::get(checkGEPType(
- getIndexedType(Ptr->getType(), IdxList)),
+ return getGEPReturnType(
+ cast<PointerType>(Ptr->getType()->getScalarType())->getElementType(),
+ Ptr, IdxList);
+ }
+ static Type *getGEPReturnType(Type *ElTy, Value *Ptr,
+ ArrayRef<Value *> IdxList) {
+ Type *PtrTy = PointerType::get(checkGEPType(getIndexedType(ElTy, IdxList)),
Ptr->getType()->getPointerAddressSpace());
// Vector GEP
if (Ptr->getType()->isVectorTy()) {
- unsigned NumElem = cast<VectorType>(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;
}
public VariadicOperandTraits<GetElementPtrInst, 1> {
};
-GetElementPtrInst::GetElementPtrInst(Value *Ptr,
- ArrayRef<Value *> IdxList,
- unsigned Values,
+GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, unsigned Values,
const Twine &NameStr,
Instruction *InsertBefore)
- : Instruction(getGEPReturnType(Ptr, IdxList),
- GetElementPtr,
- OperandTraits<GetElementPtrInst>::op_end(this) - Values,
- Values, InsertBefore) {
+ : Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr,
+ OperandTraits<GetElementPtrInst>::op_end(this) - Values,
+ Values, InsertBefore),
+ SourceElementType(PointeeType),
+ ResultElementType(getIndexedType(PointeeType, IdxList)) {
+ assert(ResultElementType ==
+ cast<PointerType>(getType()->getScalarType())->getElementType());
init(Ptr, IdxList, NameStr);
}
-GetElementPtrInst::GetElementPtrInst(Value *Ptr,
- ArrayRef<Value *> IdxList,
- unsigned Values,
+GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, unsigned Values,
const Twine &NameStr,
BasicBlock *InsertAtEnd)
- : Instruction(getGEPReturnType(Ptr, IdxList),
- GetElementPtr,
- OperandTraits<GetElementPtrInst>::op_end(this) - Values,
- Values, InsertAtEnd) {
+ : Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr,
+ OperandTraits<GetElementPtrInst>::op_end(this) - Values,
+ Values, InsertAtEnd),
+ SourceElementType(PointeeType),
+ ResultElementType(getIndexedType(PointeeType, IdxList)) {
+ assert(ResultElementType ==
+ cast<PointerType>(getType()->getScalarType())->getElementType());
init(Ptr, IdxList, NameStr);
}
}
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(
/// \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(
/// @returns true if the predicate of this instruction is EQ or NE.
/// \brief Determine if this is an equality predicate.
- bool isEquality() const {
- return getPredicate() == FCMP_OEQ || getPredicate() == FCMP_ONE ||
- getPredicate() == FCMP_UEQ || getPredicate() == FCMP_UNE;
+ static bool isEquality(Predicate Pred) {
+ return Pred == FCMP_OEQ || Pred == FCMP_ONE || Pred == FCMP_UEQ ||
+ Pred == FCMP_UNE;
}
+ /// @returns true if the predicate of this instruction is EQ or NE.
+ /// \brief Determine if this is an equality predicate.
+ bool isEquality() const { return isEquality(getPredicate()); }
+
/// @returns true if the predicate of this instruction is commutative.
/// \brief Determine if this is a commutative predicate.
bool isCommutative() const {
///
class CallInst : public Instruction {
AttributeSet AttributeList; ///< parameter attributes for call
+ FunctionType *FTy;
CallInst(const CallInst &CI);
- void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr);
+ void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr) {
+ init(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, Args, NameStr);
+ }
+ void init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
+ 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(Value *Func, ArrayRef<Value *> Args,
+ inline CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr, Instruction *InsertBefore);
+ inline CallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr,
+ Instruction *InsertBefore)
+ : CallInst(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, Args, NameStr, InsertBefore) {}
/// Construct a CallInst given a range of arguments.
/// \brief Construct a CallInst from a range of arguments
Instruction *InsertBefore);
CallInst(Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd);
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<Value *> Args,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
- return new(unsigned(Args.size() + 1))
- CallInst(Func, Args, NameStr, InsertBefore);
+ return Create(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, Args, NameStr, InsertBefore);
+ }
+ static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
+ return new (unsigned(Args.size() + 1))
+ CallInst(Ty, Func, Args, NameStr, InsertBefore);
}
static CallInst *Create(Value *Func,
ArrayRef<Value *> Args,
static Instruction* CreateFree(Value* Source, Instruction *InsertBefore);
static Instruction* CreateFree(Value* Source, BasicBlock *InsertAtEnd);
- ~CallInst();
+ ~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 };
/// 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<op_iterator> arg_operands() {
}
/// \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.
/// 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);
+ /// \brief adds the dereferenceable attribute to the list of attributes.
+ void addDereferenceableAttr(unsigned i, uint64_t Bytes);
+
+ /// \brief adds the dereferenceable_or_null attribute to the list of
+ /// attributes.
+ void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes);
+
/// \brief Determine whether this call has the given attribute.
bool hasFnAttr(Attribute::AttrKind A) const {
assert(A != Attribute::NoBuiltin &&
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;
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 Return true if the call should not be treated as a call to a
/// builtin.
bool isNoBuiltin() const {
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() {
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 {
/// setCalledFunction - Set the function called.
void setCalledFunction(Value* Fn) {
+ setCalledFunction(
+ cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType()),
+ Fn);
+ }
+ void setCalledFunction(FunctionType *FTy, Value *Fn) {
+ this->FTy = FTy;
+ assert(FTy == cast<FunctionType>(
+ cast<PointerType>(Fn->getType())->getElementType()));
Op<-1>() = Fn;
}
}
private:
- bool hasFnAttrImpl(Attribute::AttrKind A) const;
+ template<typename AttrKind>
+ bool hasFnAttrImpl(AttrKind A) const {
+ if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A))
+ return true;
+ 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.
init(Func, Args, NameStr);
}
-CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
+CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr, Instruction *InsertBefore)
- : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
- ->getElementType())->getReturnType(),
- Instruction::Call,
- OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
- unsigned(Args.size() + 1), InsertBefore) {
- init(Func, Args, NameStr);
+ : Instruction(Ty->getReturnType(), Instruction::Call,
+ OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
+ unsigned(Args.size() + 1), InsertBefore) {
+ init(Ty, Func, Args, NameStr);
}
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 = "",
///
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 = "",
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,
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,
///
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
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,
typedef const unsigned* idx_iterator;
inline idx_iterator idx_begin() const { return Indices.begin(); }
inline idx_iterator idx_end() const { return Indices.end(); }
+ inline iterator_range<idx_iterator> indices() const {
+ return iterator_range<idx_iterator>(idx_begin(), idx_end());
+ }
Value *getAggregateOperand() {
return getOperand(0);
class InsertValueInst : public Instruction {
SmallVector<unsigned, 4> Indices;
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
InsertValueInst(const InsertValueInst &IVI);
void init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
const Twine &NameStr);
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) {
typedef const unsigned* idx_iterator;
inline idx_iterator idx_begin() const { return Indices.begin(); }
inline idx_iterator idx_end() const { return Indices.end(); }
+ inline iterator_range<idx_iterator> indices() const {
+ return iterator_range<idx_iterator>(idx_begin(), idx_end());
+ }
Value *getAggregateOperand() {
return getOperand(0);
// scientist's overactive imagination.
//
class PHINode : public Instruction {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
/// ReservedSpace - The number of operands actually allocated. NumOperands is
/// the number actually in use.
unsigned ReservedSpace;
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 = "",
: Instruction(Ty, Instruction::PHI, nullptr, 0, InsertBefore),
ReservedSpace(NumReservedValues) {
setName(NameStr);
- OperandList = allocHungoffUses(ReservedSpace);
+ allocHungoffUses(ReservedSpace);
}
PHINode(Type *Ty, unsigned NumReservedValues, const Twine &NameStr,
: 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).
const Twine &NameStr, BasicBlock *InsertAtEnd) {
return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd);
}
- ~PHINode();
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
return block_begin() + getNumOperands();
}
+ 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(); }
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
public:
enum ClauseType { Catch, Filter };
private:
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ 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();
/// 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.
/// 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<Constant>(OperandList[Idx + 1]);
+ return cast<Constant>(getOperandList()[Idx]);
}
/// isCatch - Return 'true' if the clause and index Idx is a catch clause.
bool isCatch(unsigned Idx) const {
- return !isa<ArrayType>(OperandList[Idx + 1]->getType());
+ return !isa<ArrayType>(getOperandList()[Idx]->getType());
}
/// isFilter - Return 'true' if the clause and index Idx is a filter clause.
bool isFilter(unsigned Idx) const {
- return isa<ArrayType>(OperandList[Idx + 1]->getType());
+ return isa<ArrayType>(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.
};
template <>
-struct OperandTraits<LandingPadInst> : public HungoffOperandTraits<2> {
+struct OperandTraits<LandingPadInst> : public HungoffOperandTraits<1> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(LandingPadInst, Value)
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) {
static ReturnInst* Create(LLVMContext &C, BasicBlock *InsertAtEnd) {
return new(0) ReturnInst(C, InsertAtEnd);
}
- virtual ~ReturnInst();
+ ~ReturnInst() override;
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
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) {
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.
/// SwitchInst - Multiway switch
///
class SwitchInst : public TerminatorInst {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
unsigned ReservedSpace;
// Operand[0] = Value to switch on
// Operand[1] = Default basic block destination
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
SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
BasicBlock *InsertAtEnd);
protected:
- SwitchInst *clone_impl() const override;
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ SwitchInst *cloneImpl() const;
+
public:
// -2
return new SwitchInst(Value, Default, NumCases, InsertAtEnd);
}
- ~SwitchInst();
-
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
}
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:
/// IndirectBrInst - Indirect Branch Instruction.
///
class IndirectBrInst : public TerminatorInst {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
unsigned ReservedSpace;
// Operand[0] = Value to switch on
// Operand[1] = Default basic block destination
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
/// 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) {
BasicBlock *InsertAtEnd) {
return new IndirectBrInst(Address, NumDests, InsertAtEnd);
}
- ~IndirectBrInst();
/// Provide fast operand accessors.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
return cast<BasicBlock>(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:
///
class InvokeInst : public TerminatorInst {
AttributeSet AttributeList;
+ FunctionType *FTy;
InvokeInst(const InvokeInst &BI);
void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
- ArrayRef<Value *> Args, const Twine &NameStr);
+ ArrayRef<Value *> Args, const Twine &NameStr) {
+ init(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, IfNormal, IfException, Args, NameStr);
+ }
+ void init(FunctionType *FTy, Value *Func, BasicBlock *IfNormal,
+ BasicBlock *IfException, ArrayRef<Value *> Args,
+ 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<Value *> Args, unsigned Values,
- const Twine &NameStr, Instruction *InsertBefore);
-
+ const Twine &NameStr, Instruction *InsertBefore)
+ : InvokeInst(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, IfNormal, IfException, Args, Values, NameStr,
+ InsertBefore) {}
+
+ inline InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
+ BasicBlock *IfException, ArrayRef<Value *> Args,
+ unsigned Values, const Twine &NameStr,
+ Instruction *InsertBefore);
/// Construct an InvokeInst given a range of arguments.
///
/// \brief Construct an InvokeInst from a range of arguments
ArrayRef<Value *> Args, unsigned Values,
const Twine &NameStr, BasicBlock *InsertAtEnd);
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<Value *> Args, const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
+ return Create(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, IfNormal, IfException, Args, NameStr, InsertBefore);
+ }
+ static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
+ BasicBlock *IfException, ArrayRef<Value *> 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,
+ Values, NameStr, InsertBefore);
}
static InvokeInst *Create(Value *Func,
BasicBlock *IfNormal, BasicBlock *IfException,
/// 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; }
/// 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<op_iterator> arg_operands() {
}
/// \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.
/// removeAttribute - removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute attr);
+ /// \brief adds the dereferenceable attribute to the list of attributes.
+ void addDereferenceableAttr(unsigned i, uint64_t Bytes);
+
+ /// \brief adds the dereferenceable_or_null attribute to the list of
+ /// attributes.
+ void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes);
+
/// \brief Determine whether this call has the given attribute.
bool hasFnAttr(Attribute::AttrKind A) const {
assert(A != Attribute::NoBuiltin &&
uint64_t getDereferenceableBytes(unsigned i) const {
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 Return true if the call should not be treated as a call to a
/// builtin.
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() {
/// setCalledFunction - Set the function called.
void setCalledFunction(Value* Fn) {
+ setCalledFunction(
+ cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType()),
+ Fn);
+ }
+ void setCalledFunction(FunctionType *FTy, Value *Fn) {
+ this->FTy = FTy;
+ assert(FTy == cast<FunctionType>(
+ cast<PointerType>(Fn->getType())->getElementType()));
Op<-3>() = Fn;
}
struct OperandTraits<InvokeInst> : public VariadicOperandTraits<InvokeInst, 3> {
};
-InvokeInst::InvokeInst(Value *Func,
- BasicBlock *IfNormal, BasicBlock *IfException,
- ArrayRef<Value *> Args, unsigned Values,
- const Twine &NameStr, Instruction *InsertBefore)
- : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
- ->getElementType())->getReturnType(),
- Instruction::Invoke,
- OperandTraits<InvokeInst>::op_end(this) - Values,
- Values, InsertBefore) {
- init(Func, IfNormal, IfException, Args, NameStr);
+InvokeInst::InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
+ BasicBlock *IfException, ArrayRef<Value *> Args,
+ unsigned Values, const Twine &NameStr,
+ Instruction *InsertBefore)
+ : TerminatorInst(Ty->getReturnType(), Instruction::Invoke,
+ OperandTraits<InvokeInst>::op_end(this) - Values, Values,
+ InsertBefore) {
+ init(Ty, Func, IfNormal, IfException, Args, NameStr);
}
InvokeInst::InvokeInst(Value *Func,
BasicBlock *IfNormal, BasicBlock *IfException,
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);
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
+//===----------------------------------------------------------------------===//
+// CatchEndPadInst Class
+//===----------------------------------------------------------------------===//
+
+class CatchEndPadInst : public TerminatorInst {
+private:
+ CatchEndPadInst(const CatchEndPadInst &RI);
+
+ void init(BasicBlock *UnwindBB);
+ CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
+ Instruction *InsertBefore = nullptr);
+ CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
+ BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ CatchEndPadInst *cloneImpl() const;
+
+public:
+ static CatchEndPadInst *Create(LLVMContext &C, BasicBlock *UnwindBB = nullptr,
+ Instruction *InsertBefore = nullptr) {
+ unsigned Values = UnwindBB ? 1 : 0;
+ return new (Values) CatchEndPadInst(C, UnwindBB, Values, InsertBefore);
+ }
+ static CatchEndPadInst *Create(LLVMContext &C, BasicBlock *UnwindBB,
+ BasicBlock *InsertAtEnd) {
+ unsigned Values = UnwindBB ? 1 : 0;
+ return new (Values) CatchEndPadInst(C, UnwindBB, Values, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
+ bool unwindsToCaller() const { return !hasUnwindDest(); }
+
+ /// Convenience accessor. Returns null if there is no return value.
+ unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
+
+ BasicBlock *getUnwindDest() const {
+ return hasUnwindDest() ? cast<BasicBlock>(Op<-1>()) : nullptr;
+ }
+ void setUnwindDest(BasicBlock *NewDest) {
+ assert(NewDest);
+ Op<-1>() = NewDest;
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::CatchEndPad);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ BasicBlock *getSuccessorV(unsigned Idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<CatchEndPadInst>
+ : public VariadicOperandTraits<CatchEndPadInst> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchEndPadInst, Value)
+
+//===----------------------------------------------------------------------===//
+// CatchPadInst Class
+//===----------------------------------------------------------------------===//
+
+class CatchPadInst : public TerminatorInst {
+private:
+ void init(BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, const Twine &NameStr);
+
+ CatchPadInst(const CatchPadInst &CPI);
+
+ explicit CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, Instruction *InsertBefore);
+ explicit CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ CatchPadInst *cloneImpl() const;
+
+public:
+ static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
+ unsigned Values = unsigned(Args.size()) + 2;
+ return new (Values) CatchPadInst(IfNormal, IfException, Args, Values,
+ NameStr, InsertBefore);
+ }
+ static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ unsigned Values = unsigned(Args.size()) + 2;
+ return new (Values)
+ CatchPadInst(IfNormal, IfException, Args, Values, NameStr, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// getNumArgOperands - Return the number of catchpad arguments.
+ ///
+ unsigned getNumArgOperands() const { return getNumOperands() - 2; }
+
+ /// 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); }
+
+ /// arg_operands - iteration adapter for range-for loops.
+ iterator_range<op_iterator> arg_operands() {
+ return iterator_range<op_iterator>(op_begin(), op_end() - 2);
+ }
+
+ /// arg_operands - iteration adapter for range-for loops.
+ iterator_range<const_op_iterator> arg_operands() const {
+ return iterator_range<const_op_iterator>(op_begin(), op_end() - 2);
+ }
+
+ /// \brief Wrappers for getting the \c Use of a 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<BasicBlock>(Op<-2>()); }
+ BasicBlock *getUnwindDest() const { return cast<BasicBlock>(Op<-1>()); }
+ void setNormalDest(BasicBlock *B) { Op<-2>() = B; }
+ void setUnwindDest(BasicBlock *B) { Op<-1>() = B; }
+
+ BasicBlock *getSuccessor(unsigned i) const {
+ 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 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::CatchPad;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ BasicBlock *getSuccessorV(unsigned idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned idx, BasicBlock *B) override;
+};
+
+template <>
+struct OperandTraits<CatchPadInst>
+ : public VariadicOperandTraits<CatchPadInst, /*MINARITY=*/2> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchPadInst, Value)
+
+//===----------------------------------------------------------------------===//
+// TerminatePadInst Class
+//===----------------------------------------------------------------------===//
+
+class TerminatePadInst : public TerminatorInst {
+private:
+ void init(BasicBlock *BB, ArrayRef<Value *> Args);
+
+ TerminatePadInst(const TerminatePadInst &TPI);
+
+ explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB,
+ ArrayRef<Value *> Args, unsigned Values,
+ Instruction *InsertBefore);
+ explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB,
+ ArrayRef<Value *> Args, unsigned Values,
+ BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ TerminatePadInst *cloneImpl() const;
+
+public:
+ static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB = nullptr,
+ ArrayRef<Value *> Args = None,
+ Instruction *InsertBefore = nullptr) {
+ unsigned Values = unsigned(Args.size());
+ if (BB)
+ ++Values;
+ return new (Values) TerminatePadInst(C, BB, Args, Values, InsertBefore);
+ }
+ static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB,
+ ArrayRef<Value *> Args,
+ BasicBlock *InsertAtEnd) {
+ unsigned Values = unsigned(Args.size());
+ if (BB)
+ ++Values;
+ return new (Values) TerminatePadInst(C, BB, Args, Values, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
+ bool unwindsToCaller() const { return !hasUnwindDest(); }
+
+ /// getNumArgOperands - Return the number of terminatepad arguments.
+ ///
+ unsigned getNumArgOperands() const {
+ unsigned NumOperands = getNumOperands();
+ if (hasUnwindDest())
+ return NumOperands - 1;
+ return NumOperands;
+ }
+
+ /// 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); }
+
+ const_op_iterator arg_end() const {
+ if (hasUnwindDest())
+ return op_end() - 1;
+ return op_end();
+ }
+
+ op_iterator arg_end() {
+ if (hasUnwindDest())
+ return op_end() - 1;
+ return op_end();
+ }
+
+ /// arg_operands - iteration adapter for range-for loops.
+ iterator_range<op_iterator> arg_operands() {
+ return iterator_range<op_iterator>(op_begin(), arg_end());
+ }
+
+ /// arg_operands - iteration adapter for range-for loops.
+ iterator_range<const_op_iterator> arg_operands() const {
+ return iterator_range<const_op_iterator>(op_begin(), arg_end());
+ }
+
+ /// \brief Wrappers for getting the \c Use of a terminatepad argument.
+ const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
+ Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
+
+ // get*Dest - Return the destination basic blocks...
+ BasicBlock *getUnwindDest() const {
+ if (!hasUnwindDest())
+ return nullptr;
+ return cast<BasicBlock>(Op<-1>());
+ }
+ void setUnwindDest(BasicBlock *B) {
+ assert(B && hasUnwindDest());
+ Op<-1>() = 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::TerminatePad;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ BasicBlock *getSuccessorV(unsigned idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned idx, BasicBlock *B) override;
+
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<TerminatePadInst>
+ : public VariadicOperandTraits<TerminatePadInst, /*MINARITY=*/1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(TerminatePadInst, Value)
+
+//===----------------------------------------------------------------------===//
+// CleanupPadInst Class
+//===----------------------------------------------------------------------===//
+
+class CleanupPadInst : public Instruction {
+private:
+ void init(ArrayRef<Value *> Args, const Twine &NameStr);
+
+ CleanupPadInst(const CleanupPadInst &CPI);
+
+ explicit CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args,
+ const Twine &NameStr, Instruction *InsertBefore);
+ explicit CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ CleanupPadInst *cloneImpl() const;
+
+public:
+ static CleanupPadInst *Create(LLVMContext &C, ArrayRef<Value *> Args,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
+ return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertBefore);
+ }
+ static CleanupPadInst *Create(LLVMContext &C, ArrayRef<Value *> Args,
+ const Twine &NameStr, BasicBlock *InsertAtEnd) {
+ return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::CleanupPad;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+template <>
+struct OperandTraits<CleanupPadInst>
+ : public VariadicOperandTraits<CleanupPadInst, /*MINARITY=*/0> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupPadInst, Value)
+
+//===----------------------------------------------------------------------===//
+// CatchReturnInst Class
+//===----------------------------------------------------------------------===//
+
+class CatchReturnInst : public TerminatorInst {
+ CatchReturnInst(const CatchReturnInst &RI);
+
+ void init(CatchPadInst *CatchPad, BasicBlock *BB);
+ CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB,
+ Instruction *InsertBefore);
+ CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB,
+ BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ CatchReturnInst *cloneImpl() const;
+
+public:
+ static CatchReturnInst *Create(CatchPadInst *CatchPad, BasicBlock *BB,
+ Instruction *InsertBefore = nullptr) {
+ assert(CatchPad);
+ assert(BB);
+ return new (2) CatchReturnInst(CatchPad, BB, InsertBefore);
+ }
+ 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.
+ CatchPadInst *getCatchPad() const { return cast<CatchPadInst>(Op<0>()); }
+ void setCatchPad(CatchPadInst *CatchPad) {
+ assert(CatchPad);
+ Op<0>() = CatchPad;
+ }
+
+ BasicBlock *getSuccessor() const { return cast<BasicBlock>(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:
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::CatchRet);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ BasicBlock *getSuccessorV(unsigned Idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+};
+
+template <>
+struct OperandTraits<CatchReturnInst>
+ : public FixedNumOperandTraits<CatchReturnInst, 2> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value)
+
+//===----------------------------------------------------------------------===//
+// CleanupEndPadInst Class
+//===----------------------------------------------------------------------===//
+
+class CleanupEndPadInst : public TerminatorInst {
+private:
+ CleanupEndPadInst(const CleanupEndPadInst &CEPI);
+
+ void init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB);
+ CleanupEndPadInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB,
+ unsigned Values, Instruction *InsertBefore = nullptr);
+ CleanupEndPadInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB,
+ unsigned Values, BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ CleanupEndPadInst *cloneImpl() const;
+
+public:
+ static CleanupEndPadInst *Create(CleanupPadInst *CleanupPad,
+ BasicBlock *UnwindBB = nullptr,
+ Instruction *InsertBefore = nullptr) {
+ unsigned Values = UnwindBB ? 2 : 1;
+ return new (Values)
+ CleanupEndPadInst(CleanupPad, UnwindBB, Values, InsertBefore);
+ }
+ static CleanupEndPadInst *Create(CleanupPadInst *CleanupPad,
+ BasicBlock *UnwindBB,
+ BasicBlock *InsertAtEnd) {
+ unsigned Values = UnwindBB ? 2 : 1;
+ return new (Values)
+ CleanupEndPadInst(CleanupPad, UnwindBB, Values, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
+ bool unwindsToCaller() const { return !hasUnwindDest(); }
+
+ unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
+
+ /// Convenience accessors
+ CleanupPadInst *getCleanupPad() const {
+ return cast<CleanupPadInst>(Op<-1>());
+ }
+ void setCleanupPad(CleanupPadInst *CleanupPad) {
+ assert(CleanupPad);
+ Op<-1>() = CleanupPad;
+ }
+
+ BasicBlock *getUnwindDest() const {
+ return hasUnwindDest() ? cast<BasicBlock>(Op<-2>()) : nullptr;
+ }
+ void setUnwindDest(BasicBlock *NewDest) {
+ assert(hasUnwindDest());
+ assert(NewDest);
+ Op<-2>() = NewDest;
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::CleanupEndPad);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ BasicBlock *getSuccessorV(unsigned Idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<CleanupEndPadInst>
+ : public VariadicOperandTraits<CleanupEndPadInst, /*MINARITY=*/1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupEndPadInst, Value)
+
+//===----------------------------------------------------------------------===//
+// CleanupReturnInst Class
+//===----------------------------------------------------------------------===//
+
+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<CleanupPadInst>(Op<-1>());
+ }
+ void setCleanupPad(CleanupPadInst *CleanupPad) {
+ assert(CleanupPad);
+ Op<-1>() = CleanupPad;
+ }
+
+ unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
+
+ BasicBlock *getUnwindDest() const {
+ return hasUnwindDest() ? cast<BasicBlock>(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<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ BasicBlock *getSuccessorV(unsigned Idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<CleanupReturnInst>
+ : public VariadicOperandTraits<CleanupReturnInst, /*MINARITY=*/1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value)
+
//===----------------------------------------------------------------------===//
// UnreachableInst Class
//===----------------------------------------------------------------------===//
/// end of the block cannot be reached.
///
class UnreachableInst : public TerminatorInst {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ 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
/// \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
/// \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
/// \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
/// \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
/// \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
/// \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
/// \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
/// \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
/// \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
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 {
/// \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
/// \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
/// 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