#define LLVM_IR_INSTRUCTIONS_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/Constant.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/OperandTraits.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Use.h"
+#include "llvm/IR/User.h"
#include "llvm/Support/AtomicOrdering.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
-#include <iterator>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
namespace llvm {
class APInt;
class ConstantInt;
-class ConstantRange;
class DataLayout;
class LLVMContext;
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
AllocaInst *cloneImpl() const;
public:
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
LoadInst *cloneImpl() const;
public:
unsigned Align, AtomicOrdering Order,
SynchronizationScope SynchScope,
BasicBlock *InsertAtEnd);
-
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,
/// An instruction for storing to memory.
class StoreInst : public Instruction {
- void *operator new(size_t, unsigned) = delete;
void AssertOK();
protected:
// 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) {
- return User::operator new(s, 2);
- }
StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore);
StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd);
StoreInst(Value *Val, Value *Ptr, bool isVolatile = false,
SynchronizationScope SynchScope,
BasicBlock *InsertAtEnd);
+ // allocate space for exactly two operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 2);
+ }
+
+ void *operator new(size_t, unsigned) = delete;
+
/// Return true if this is a store to a volatile memory location.
bool isVolatile() const { return getSubclassDataFromInstruction() & 1; }
/// An instruction for ordering other memory operations.
class FenceInst : public Instruction {
- void *operator new(size_t, unsigned) = delete;
void Init(AtomicOrdering Ordering, SynchronizationScope SynchScope);
protected:
// 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) {
- return User::operator new(s, 0);
- }
-
// Ordering may only be Acquire, Release, AcquireRelease, or
// SequentiallyConsistent.
FenceInst(LLVMContext &C, AtomicOrdering Ordering,
SynchronizationScope SynchScope,
BasicBlock *InsertAtEnd);
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+
+ void *operator new(size_t, unsigned) = delete;
+
/// Returns the ordering effect of this fence.
AtomicOrdering getOrdering() const {
return AtomicOrdering(getSubclassDataFromInstruction() >> 1);
/// there. Returns the value that was loaded.
///
class AtomicCmpXchgInst : public Instruction {
- void *operator new(size_t, unsigned) = delete;
void Init(Value *Ptr, Value *Cmp, Value *NewVal,
AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
SynchronizationScope SynchScope);
protected:
// 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) {
- return User::operator new(s, 3);
- }
AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
AtomicOrdering SuccessOrdering,
AtomicOrdering FailureOrdering,
SynchronizationScope SynchScope,
BasicBlock *InsertAtEnd);
+ // allocate space for exactly three operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 3);
+ }
+
+ void *operator new(size_t, unsigned) = delete;
+
/// Return true if this is a cmpxchg from a volatile memory
/// location.
///
/// the old value.
///
class AtomicRMWInst : public Instruction {
- void *operator new(size_t, unsigned) = delete;
-
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
AtomicRMWInst *cloneImpl() const;
public:
BAD_BINOP
};
- // allocate space for exactly two operands
- void *operator new(size_t s) {
- return User::operator new(s, 2);
- }
AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val,
AtomicOrdering Ordering, SynchronizationScope SynchScope,
Instruction *InsertBefore = nullptr);
AtomicOrdering Ordering, SynchronizationScope SynchScope,
BasicBlock *InsertAtEnd);
+ // allocate space for exactly two operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 2);
+ }
+
+ void *operator new(size_t, unsigned) = delete;
+
BinOp getOperation() const {
return static_cast<BinOp>(getSubclassDataFromInstruction() >> 5);
}
private:
void Init(BinOp Operation, Value *Ptr, Value *Val,
AtomicOrdering Ordering, SynchronizationScope SynchScope);
+
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
void setInstructionSubclassData(unsigned short D) {
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
GetElementPtrInst *cloneImpl() const;
public:
return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values,
NameStr, InsertBefore);
}
+
static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
ArrayRef<Value *> IdxList,
const Twine &NameStr,
Instruction *InsertBefore = nullptr){
return CreateInBounds(nullptr, Ptr, IdxList, NameStr, InsertBefore);
}
+
static GetElementPtrInst *
CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef<Value *> IdxList,
const Twine &NameStr = "",
GEP->setIsInBounds(true);
return GEP;
}
+
static GetElementPtrInst *CreateInBounds(Value *Ptr,
ArrayRef<Value *> IdxList,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
return CreateInBounds(nullptr, Ptr, IdxList, NameStr, InsertAtEnd);
}
+
static GetElementPtrInst *CreateInBounds(Type *PointeeType, Value *Ptr,
ArrayRef<Value *> IdxList,
const Twine &NameStr,
cast<PointerType>(getType()->getScalarType())->getElementType());
init(Ptr, IdxList, NameStr);
}
+
GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr,
ArrayRef<Value *> IdxList, unsigned Values,
const Twine &NameStr,
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical ICmpInst
ICmpInst *cloneImpl() const;
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical FCmpInst
FCmpInst *cloneImpl() const;
///
class CallInst : public Instruction,
public OperandBundleUser<CallInst, User::op_iterator> {
+ friend class OperandBundleUser<CallInst, User::op_iterator>;
+
AttributeSet AttributeList; ///< parameter attributes for call
FunctionType *FTy;
+
CallInst(const CallInst &CI);
- void init(Value *Func, ArrayRef<Value *> Args,
- ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr) {
- init(cast<FunctionType>(
- cast<PointerType>(Func->getType())->getElementType()),
- Func, Args, Bundles, NameStr);
- }
- void init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
- ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr);
- void init(Value *Func, const Twine &NameStr);
/// Construct a CallInst given a range of arguments.
/// Construct a CallInst from a range of arguments
inline CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr,
Instruction *InsertBefore);
+
inline CallInst(Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr,
Instruction *InsertBefore)
explicit CallInst(Value *F, const Twine &NameStr,
Instruction *InsertBefore);
+
CallInst(Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd);
- friend class OperandBundleUser<CallInst, User::op_iterator>;
+ void init(Value *Func, ArrayRef<Value *> Args,
+ ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr) {
+ init(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, Args, Bundles, NameStr);
+ }
+ void init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
+ ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr);
+ void init(Value *Func, const Twine &NameStr);
+
bool hasDescriptor() const { return HasDescriptor; }
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
CallInst *cloneImpl() const;
public:
+ ~CallInst() override;
+
static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles = None,
const Twine &NameStr = "",
cast<PointerType>(Func->getType())->getElementType()),
Func, Args, Bundles, NameStr, InsertBefore);
}
+
static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr,
Instruction *InsertBefore = nullptr) {
cast<PointerType>(Func->getType())->getElementType()),
Func, Args, None, 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, None, NameStr, InsertBefore);
}
+
static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles = None,
const Twine &NameStr = "",
return new (TotalOps, DescriptorBytes)
CallInst(Ty, Func, Args, Bundles, NameStr, InsertBefore);
}
+
static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles,
const Twine &NameStr, BasicBlock *InsertAtEnd) {
return new (TotalOps, DescriptorBytes)
CallInst(Func, Args, Bundles, NameStr, InsertAtEnd);
}
+
static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr, BasicBlock *InsertAtEnd) {
return new (unsigned(Args.size() + 1))
CallInst(Func, Args, None, NameStr, InsertAtEnd);
}
+
static CallInst *Create(Value *F, const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
return new(1) CallInst(F, NameStr, InsertBefore);
}
+
static CallInst *Create(Value *F, const Twine &NameStr,
BasicBlock *InsertAtEnd) {
return new(1) CallInst(F, NameStr, InsertAtEnd);
ArrayRef<OperandBundleDef> Bundles,
BasicBlock *InsertAtEnd);
- ~CallInst() override;
-
FunctionType *getFunctionType() const { return FTy; }
void mutateFunctionType(FunctionType *FTy) {
TailCallKind getTailCallKind() const {
return TailCallKind(getSubclassDataFromInstruction() & 3);
}
+
bool isTailCall() const {
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));
}
+
void setTailCallKind(TailCallKind TCK) {
setInstructionSubclassData((getSubclassDataFromInstruction() & ~3) |
unsigned(TCK));
/// This class represents the LLVM 'select' instruction.
///
class SelectInst : public Instruction {
- void init(Value *C, Value *S1, Value *S2) {
- assert(!areInvalidOperands(C, S1, S2) && "Invalid operands for select");
- Op<0>() = C;
- Op<1>() = S1;
- Op<2>() = S2;
- }
-
SelectInst(Value *C, Value *S1, Value *S2, const Twine &NameStr,
Instruction *InsertBefore)
: Instruction(S1->getType(), Instruction::Select,
init(C, S1, S2);
setName(NameStr);
}
+
SelectInst(Value *C, Value *S1, Value *S2, const Twine &NameStr,
BasicBlock *InsertAtEnd)
: Instruction(S1->getType(), Instruction::Select,
setName(NameStr);
}
+ void init(Value *C, Value *S1, Value *S2) {
+ assert(!areInvalidOperands(C, S1, S2) && "Invalid operands for select");
+ Op<0>() = C;
+ Op<1>() = S1;
+ Op<2>() = S2;
+ }
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
SelectInst *cloneImpl() const;
public:
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
VAArgInst *cloneImpl() const;
public:
: UnaryInstruction(Ty, VAArg, List, InsertBefore) {
setName(NameStr);
}
+
VAArgInst(Value *List, Type *Ty, const Twine &NameStr,
BasicBlock *InsertAtEnd)
: UnaryInstruction(Ty, VAArg, List, InsertAtEnd) {
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
ExtractElementInst *cloneImpl() const;
public:
Instruction *InsertBefore = nullptr) {
return new(2) ExtractElementInst(Vec, Idx, NameStr, InsertBefore);
}
+
static ExtractElementInst *Create(Value *Vec, Value *Idx,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
InsertElementInst *cloneImpl() const;
public:
Instruction *InsertBefore = nullptr) {
return new(3) InsertElementInst(Vec, NewElt, Idx, NameStr, InsertBefore);
}
+
static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
ShuffleVectorInst *cloneImpl() const;
public:
- // allocate space for exactly three operands
- void *operator new(size_t s) {
- return User::operator new(s, 3);
- }
ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
const Twine &NameStr = "",
Instruction *InsertBefor = nullptr);
ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
const Twine &NameStr, BasicBlock *InsertAtEnd);
+ // allocate space for exactly three operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 3);
+ }
+
/// Return true if a shufflevector instruction can be
/// formed with the specified operands.
static bool isValidOperands(const Value *V1, const Value *V2,
SmallVector<unsigned, 4> Indices;
ExtractValueInst(const ExtractValueInst &EVI);
- void init(ArrayRef<unsigned> Idxs, const Twine &NameStr);
-
/// Constructors - Create a extractvalue instruction with a base aggregate
/// value and a list of indices. The first ctor can optionally insert before
/// an existing instruction, the second appends the new instruction to the
// allocate space for exactly one operand
void *operator new(size_t s) { return User::operator new(s, 1); }
+ void init(ArrayRef<unsigned> Idxs, const Twine &NameStr);
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
ExtractValueInst *cloneImpl() const;
public:
return new
ExtractValueInst(Agg, Idxs, NameStr, InsertBefore);
}
+
static ExtractValueInst *Create(Value *Agg,
ArrayRef<unsigned> Idxs,
const Twine &NameStr,
ExtractValue, Agg, InsertBefore) {
init(Idxs, NameStr);
}
+
ExtractValueInst::ExtractValueInst(Value *Agg,
ArrayRef<unsigned> Idxs,
const Twine &NameStr,
class InsertValueInst : public Instruction {
SmallVector<unsigned, 4> Indices;
- void *operator new(size_t, unsigned) = delete;
InsertValueInst(const InsertValueInst &IVI);
- void init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
- const Twine &NameStr);
/// Constructors - Create a insertvalue instruction with a base aggregate
/// value, a value to insert, and a list of indices. The first ctor can
InsertValueInst(Value *Agg, Value *Val, unsigned Idx, const Twine &NameStr,
BasicBlock *InsertAtEnd);
+ void init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
+ const Twine &NameStr);
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
InsertValueInst *cloneImpl() const;
public:
return User::operator new(s, 2);
}
+ void *operator new(size_t, unsigned) = delete;
+
static InsertValueInst *Create(Value *Agg, Value *Val,
ArrayRef<unsigned> Idxs,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertBefore);
}
+
static InsertValueInst *Create(Value *Agg, Value *Val,
ArrayRef<unsigned> Idxs,
const Twine &NameStr,
2, InsertBefore) {
init(Agg, Val, Idxs, NameStr);
}
+
InsertValueInst::InsertValueInst(Value *Agg,
Value *Val,
ArrayRef<unsigned> Idxs,
// scientist's overactive imagination.
//
class PHINode : public Instruction {
- void anchor() override;
-
- void *operator new(size_t, unsigned) = delete;
/// 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);
- }
+
explicit PHINode(Type *Ty, unsigned NumReservedValues,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr)
allocHungoffUses(ReservedSpace);
}
+ void *operator new(size_t s) {
+ return User::operator new(s);
+ }
+
+ void anchor() override;
+
protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+
+ PHINode *cloneImpl() const;
+
// 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.
User::allocHungoffUses(N, /* IsPhi */ true);
}
- // Note: Instruction needs to be a friend here to call cloneImpl.
- friend class Instruction;
- PHINode *cloneImpl() const;
-
public:
+ void *operator new(size_t, unsigned) = delete;
+
/// 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).
static PHINode *Create(Type *Ty, unsigned NumReservedValues,
Instruction *InsertBefore = nullptr) {
return new PHINode(Ty, NumReservedValues, NameStr, InsertBefore);
}
+
static PHINode *Create(Type *Ty, unsigned NumReservedValues,
const Twine &NameStr, BasicBlock *InsertAtEnd) {
return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd);
/// The number of operands actually allocated. NumOperands is
/// the number actually in use.
unsigned ReservedSpace;
+
LandingPadInst(const LandingPadInst &LP);
public:
enum ClauseType { Catch, Filter };
private:
- void *operator new(size_t, unsigned) = delete;
+ explicit LandingPadInst(Type *RetTy, unsigned NumReservedValues,
+ const Twine &NameStr, Instruction *InsertBefore);
+ explicit LandingPadInst(Type *RetTy, unsigned NumReservedValues,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+
// Allocate space for exactly zero operands.
void *operator new(size_t s) {
return User::operator new(s);
}
+
void growOperands(unsigned Size);
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);
-
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
LandingPadInst *cloneImpl() const;
public:
+ void *operator new(size_t, unsigned) = delete;
+
/// 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, unsigned NumReservedClauses,
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
ReturnInst *cloneImpl() const;
public:
+ ~ReturnInst() override;
+
static ReturnInst* Create(LLVMContext &C, Value *retVal = nullptr,
Instruction *InsertBefore = nullptr) {
return new(!!retVal) ReturnInst(C, retVal, InsertBefore);
}
+
static ReturnInst* Create(LLVMContext &C, Value *retVal,
BasicBlock *InsertAtEnd) {
return new(!!retVal) ReturnInst(C, retVal, InsertAtEnd);
}
+
static ReturnInst* Create(LLVMContext &C, BasicBlock *InsertAtEnd) {
return new(0) ReturnInst(C, InsertAtEnd);
}
- ~ReturnInst() override;
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
/// they don't have to check for cond/uncond branchness. These are mostly
/// accessed relative from op_end().
BranchInst(const BranchInst &BI);
- void AssertOK();
// BranchInst constructors (where {B, T, F} are blocks, and C is a condition):
// BranchInst(BB *B) - 'br B'
// BranchInst(BB* T, BB *F, Value *C) - 'br C, T, F'
BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
BasicBlock *InsertAtEnd);
+ void AssertOK();
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
BranchInst *cloneImpl() const;
public:
Instruction *InsertBefore = nullptr) {
return new(1) BranchInst(IfTrue, InsertBefore);
}
+
static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse,
Value *Cond, Instruction *InsertBefore = nullptr) {
return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertBefore);
}
+
static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *InsertAtEnd) {
return new(1) BranchInst(IfTrue, InsertAtEnd);
}
+
static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse,
Value *Cond, BasicBlock *InsertAtEnd) {
return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertAtEnd);
/// Multiway switch
///
class SwitchInst : public TerminatorInst {
- void *operator new(size_t, unsigned) = delete;
unsigned ReservedSpace;
+
// Operand[0] = Value to switch on
// Operand[1] = Default basic block destination
// Operand[2n ] = Value to match
// Operand[2n+1] = BasicBlock to go to on match
SwitchInst(const SwitchInst &SI);
- void init(Value *Value, BasicBlock *Default, unsigned NumReserved);
- void growOperands();
- // allocate space for exactly zero operands
- void *operator new(size_t s) {
- return User::operator new(s);
- }
+
/// Create a new switch instruction, specifying a value to switch on and a
/// default destination. The number of additional cases can be specified here
/// to make memory allocation more efficient. This constructor can also
SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
BasicBlock *InsertAtEnd);
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) {
+ return User::operator new(s);
+ }
+
+ void init(Value *Value, BasicBlock *Default, unsigned NumReserved);
+ void growOperands();
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
SwitchInst *cloneImpl() const;
public:
+ void *operator new(size_t, unsigned) = delete;
+
// -2
static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1);
ConstCaseIt;
class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> {
-
typedef CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> ParentTy;
public:
Instruction *InsertBefore = nullptr) {
return new SwitchInst(Value, Default, NumCases, InsertBefore);
}
+
static SwitchInst *Create(Value *Value, BasicBlock *Default,
unsigned NumCases, BasicBlock *InsertAtEnd) {
return new SwitchInst(Value, Default, NumCases, InsertAtEnd);
CaseIt case_begin() {
return CaseIt(this, 0);
}
+
/// Returns a read-only iterator that points to the first case in the
/// SwitchInst.
ConstCaseIt case_begin() const {
CaseIt case_end() {
return CaseIt(this, getNumCases());
}
+
/// Returns a read-only iterator that points one past the last in the
/// SwitchInst.
ConstCaseIt case_end() const {
/// Indirect Branch Instruction.
///
class IndirectBrInst : public TerminatorInst {
- void *operator new(size_t, unsigned) = delete;
unsigned ReservedSpace;
+
// Operand[0] = Address to jump to
// Operand[n+1] = n-th destination
IndirectBrInst(const IndirectBrInst &IBI);
- void init(Value *Address, unsigned NumDests);
- void growOperands();
- // allocate space for exactly zero operands
- void *operator new(size_t s) {
- return User::operator new(s);
- }
+
/// Create a new indirectbr instruction, specifying an
/// Address to jump to. The number of expected destinations can be specified
/// here to make memory allocation more efficient. This constructor can also
/// autoinserts at the end of the specified BasicBlock.
IndirectBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd);
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) {
+ return User::operator new(s);
+ }
+
+ void init(Value *Address, unsigned NumDests);
+ void growOperands();
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
IndirectBrInst *cloneImpl() const;
public:
+ void *operator new(size_t, unsigned) = delete;
+
static IndirectBrInst *Create(Value *Address, unsigned NumDests,
Instruction *InsertBefore = nullptr) {
return new IndirectBrInst(Address, NumDests, InsertBefore);
}
+
static IndirectBrInst *Create(Value *Address, unsigned NumDests,
BasicBlock *InsertAtEnd) {
return new IndirectBrInst(Address, NumDests, InsertAtEnd);
///
class InvokeInst : public TerminatorInst,
public OperandBundleUser<InvokeInst, User::op_iterator> {
+ friend class OperandBundleUser<InvokeInst, User::op_iterator>;
+
AttributeSet AttributeList;
FunctionType *FTy;
+
InvokeInst(const InvokeInst &BI);
- void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
- ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles,
- const Twine &NameStr) {
- init(cast<FunctionType>(
- cast<PointerType>(Func->getType())->getElementType()),
- Func, IfNormal, IfException, Args, Bundles, NameStr);
- }
- void init(FunctionType *FTy, Value *Func, BasicBlock *IfNormal,
- BasicBlock *IfException, ArrayRef<Value *> Args,
- ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr);
/// Construct an InvokeInst given a range of arguments.
///
unsigned Values, const Twine &NameStr,
BasicBlock *InsertAtEnd);
- friend class OperandBundleUser<InvokeInst, User::op_iterator>;
bool hasDescriptor() const { return HasDescriptor; }
+ void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles,
+ const Twine &NameStr) {
+ init(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, IfNormal, IfException, Args, Bundles, NameStr);
+ }
+
+ void init(FunctionType *FTy, Value *Func, BasicBlock *IfNormal,
+ BasicBlock *IfException, ArrayRef<Value *> Args,
+ ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr);
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
InvokeInst *cloneImpl() const;
public:
Func, IfNormal, IfException, Args, None, NameStr,
InsertBefore);
}
+
static InvokeInst *Create(Value *Func, BasicBlock *IfNormal,
BasicBlock *IfException, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles = None,
Func, IfNormal, IfException, Args, Bundles, NameStr,
InsertBefore);
}
+
static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
BasicBlock *IfException, ArrayRef<Value *> Args,
const Twine &NameStr,
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<Value *> Args,
ArrayRef<OperandBundleDef> Bundles = None,
InvokeInst(Ty, Func, IfNormal, IfException, Args, Bundles, Values,
NameStr, InsertBefore);
}
+
static InvokeInst *Create(Value *Func,
BasicBlock *IfNormal, BasicBlock *IfException,
ArrayRef<Value *> Args, const Twine &NameStr,
InsertBefore) {
init(Ty, Func, IfNormal, IfException, Args, Bundles, NameStr);
}
+
InvokeInst::InvokeInst(Value *Func, BasicBlock *IfNormal,
BasicBlock *IfException, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles, unsigned Values,
protected:
// 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);
}
+
static ResumeInst *Create(Value *Exn, BasicBlock *InsertAtEnd) {
return new(1) ResumeInst(Exn, InsertAtEnd);
}
// CatchSwitchInst Class
//===----------------------------------------------------------------------===//
class CatchSwitchInst : public TerminatorInst {
- void *operator new(size_t, unsigned) = delete;
/// 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); }
+
/// Create a new switch instruction, specifying a
/// default destination. The number of additional handlers can be specified
/// here to make memory allocation more efficient.
unsigned NumHandlers, const Twine &NameStr,
BasicBlock *InsertAtEnd);
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) { return User::operator new(s); }
+
+ void init(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumReserved);
+ void growOperands(unsigned Size);
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
CatchSwitchInst *cloneImpl() const;
public:
+ void *operator new(size_t, unsigned) = delete;
+
static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest,
unsigned NumHandlers,
const Twine &NameStr = "",
return new CatchSwitchInst(ParentPad, UnwindDest, NumHandlers, NameStr,
InsertBefore);
}
+
static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest,
unsigned NumHandlers, const Twine &NameStr,
BasicBlock *InsertAtEnd) {
typedef std::pointer_to_unary_function<Value *, BasicBlock *> DerefFnTy;
typedef mapped_iterator<op_iterator, DerefFnTy> handler_iterator;
typedef iterator_range<handler_iterator> handler_range;
-
-
typedef std::pointer_to_unary_function<const Value *, const BasicBlock *>
ConstDerefFnTy;
typedef mapped_iterator<const_op_iterator, ConstDerefFnTy> const_handler_iterator;
++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 {
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 new (Values)
CleanupPadInst(ParentPad, Args, Values, NameStr, InsertBefore);
}
+
static CleanupPadInst *Create(Value *ParentPad, ArrayRef<Value *> Args,
const Twine &NameStr, BasicBlock *InsertAtEnd) {
unsigned Values = 1 + Args.size();
return new (Values)
CatchPadInst(CatchSwitch, Args, Values, NameStr, InsertBefore);
}
+
static CatchPadInst *Create(Value *CatchSwitch, ArrayRef<Value *> Args,
const Twine &NameStr, BasicBlock *InsertAtEnd) {
unsigned Values = 1 + Args.size();
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);
+ void init(Value *CatchPad, BasicBlock *BB);
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
CatchReturnInst *cloneImpl() const;
public:
assert(BB);
return new (2) CatchReturnInst(CatchPad, BB, InsertBefore);
}
+
static CatchReturnInst *Create(Value *CatchPad, BasicBlock *BB,
BasicBlock *InsertAtEnd) {
assert(CatchPad);
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);
+ void init(Value *CleanupPad, BasicBlock *UnwindBB);
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
CleanupReturnInst *cloneImpl() const;
public:
return new (Values)
CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertBefore);
}
+
static CleanupReturnInst *Create(Value *CleanupPad, BasicBlock *UnwindBB,
BasicBlock *InsertAtEnd) {
assert(CleanupPad);
/// end of the block cannot be reached.
///
class UnreachableInst : public TerminatorInst {
- void *operator new(size_t, unsigned) = delete;
-
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
UnreachableInst *cloneImpl() const;
public:
+ explicit UnreachableInst(LLVMContext &C, Instruction *InsertBefore = nullptr);
+ explicit UnreachableInst(LLVMContext &C, BasicBlock *InsertAtEnd);
+
// allocate space for exactly zero operands
void *operator new(size_t s) {
return User::operator new(s, 0);
}
- explicit UnreachableInst(LLVMContext &C, Instruction *InsertBefore = nullptr);
- explicit UnreachableInst(LLVMContext &C, BasicBlock *InsertAtEnd);
+
+ void *operator new(size_t, unsigned) = delete;
unsigned getNumSuccessors() const { return 0; }
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical TruncInst
TruncInst *cloneImpl() const;
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical ZExtInst
ZExtInst *cloneImpl() const;
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical SExtInst
SExtInst *cloneImpl() const;
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical FPTruncInst
FPTruncInst *cloneImpl() const;
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical FPExtInst
FPExtInst *cloneImpl() const;
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical UIToFPInst
UIToFPInst *cloneImpl() const;
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical SIToFPInst
SIToFPInst *cloneImpl() const;
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical FPToUIInst
FPToUIInst *cloneImpl() const;
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical FPToSIInst
FPToSIInst *cloneImpl() const;
/// This class represents a cast from an integer to a pointer.
class IntToPtrInst : public CastInst {
public:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+
/// Constructor with insert-before-instruction semantics
IntToPtrInst(
Value *S, ///< The value to be converted
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
- // Note: Instruction needs to be a friend here to call cloneImpl.
- friend class Instruction;
/// Clone an identical IntToPtrInst.
IntToPtrInst *cloneImpl() const;
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical PtrToIntInst.
PtrToIntInst *cloneImpl() const;
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical BitCastInst.
BitCastInst *cloneImpl() const;
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
/// Clone an identical AddrSpaceCastInst.
AddrSpaceCastInst *cloneImpl() const;
}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_IR_INSTRUCTIONS_H