Changeset View
Changeset View
Standalone View
Standalone View
include/llvm/IR/Instructions.h
Show First 20 Lines • Show All 1,344 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
/// CallInst - This class represents a function call, abstracting a target | /// CallInst - This class represents a function call, abstracting a target | ||||
/// machine's calling convention. This class uses low bit of the SubClassData | /// machine's calling convention. This class uses low bit of the SubClassData | ||||
/// field to indicate whether or not this is a tail call. The rest of the bits | /// field to indicate whether or not this is a tail call. The rest of the bits | ||||
/// hold the calling convention of the call. | /// hold the calling convention of the call. | ||||
/// | /// | ||||
class CallInst : public Instruction { | class CallInst : public Instruction, public OperandBundleUser<CallInst> { | ||||
AttributeSet AttributeList; ///< parameter attributes for call | AttributeSet AttributeList; ///< parameter attributes for call | ||||
FunctionType *FTy; | FunctionType *FTy; | ||||
CallInst(const CallInst &CI); | CallInst(const CallInst &CI); | ||||
void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr) { | void init(Value *Func, ArrayRef<Value *> Args, | ||||
ArrayRef<OperandBundleSetDef> Bundles, const Twine &NameStr) { | |||||
init(cast<FunctionType>( | init(cast<FunctionType>( | ||||
cast<PointerType>(Func->getType())->getElementType()), | cast<PointerType>(Func->getType())->getElementType()), | ||||
Func, Args, NameStr); | Func, Args, Bundles, NameStr); | ||||
} | } | ||||
void init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args, | void init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args, | ||||
const Twine &NameStr); | ArrayRef<OperandBundleSetDef> Bundles, const Twine &NameStr); | ||||
void init(Value *Func, const Twine &NameStr); | void init(Value *Func, const Twine &NameStr); | ||||
/// Construct a CallInst given a range of arguments. | /// Construct a CallInst given a range of arguments. | ||||
/// \brief Construct a CallInst from a range of arguments | /// \brief Construct a CallInst from a range of arguments | ||||
inline CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args, | inline CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args, | ||||
const Twine &NameStr, Instruction *InsertBefore); | ArrayRef<OperandBundleSetDef> Bundles, const Twine &NameStr, | ||||
inline CallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr, | Instruction *InsertBefore); | ||||
inline CallInst(Value *Func, ArrayRef<Value *> Args, | |||||
ArrayRef<OperandBundleSetDef> Bundles, const Twine &NameStr, | |||||
Instruction *InsertBefore) | Instruction *InsertBefore) | ||||
: CallInst(cast<FunctionType>( | : CallInst(cast<FunctionType>( | ||||
cast<PointerType>(Func->getType())->getElementType()), | cast<PointerType>(Func->getType())->getElementType()), | ||||
Func, Args, NameStr, InsertBefore) {} | Func, Args, Bundles, NameStr, InsertBefore) {} | ||||
inline CallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr, | |||||
Instruction *InsertBefore) | |||||
: CallInst(Func, Args, None, NameStr, InsertBefore) {} | |||||
/// Construct a CallInst given a range of arguments. | /// Construct a CallInst given a range of arguments. | ||||
/// \brief Construct a CallInst from a range of arguments | /// \brief Construct a CallInst from a range of arguments | ||||
inline CallInst(Value *Func, ArrayRef<Value *> Args, | inline CallInst(Value *Func, ArrayRef<Value *> Args, | ||||
const Twine &NameStr, BasicBlock *InsertAtEnd); | ArrayRef<OperandBundleSetDef> Bundles, const Twine &NameStr, | ||||
BasicBlock *InsertAtEnd); | |||||
explicit CallInst(Value *F, const Twine &NameStr, | explicit CallInst(Value *F, const Twine &NameStr, | ||||
Instruction *InsertBefore); | Instruction *InsertBefore); | ||||
CallInst(Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd); | CallInst(Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd); | ||||
friend class OperandBundleUser<CallInst>; | |||||
bool hasDescriptor() const { return HasDescriptor; } | |||||
protected: | protected: | ||||
// Note: Instruction needs to be a friend here to call cloneImpl. | // Note: Instruction needs to be a friend here to call cloneImpl. | ||||
friend class Instruction; | friend class Instruction; | ||||
CallInst *cloneImpl() const; | CallInst *cloneImpl() const; | ||||
public: | public: | ||||
static CallInst *Create(Value *Func, | static CallInst *Create(Value *Func, ArrayRef<Value *> Args, | ||||
ArrayRef<Value *> Args, | ArrayRef<OperandBundleSetDef> Bundles = None, | ||||
const Twine &NameStr = "", | const Twine &NameStr = "", | ||||
Instruction *InsertBefore = nullptr) { | Instruction *InsertBefore = nullptr) { | ||||
return Create(cast<FunctionType>( | return Create(cast<FunctionType>( | ||||
cast<PointerType>(Func->getType())->getElementType()), | cast<PointerType>(Func->getType())->getElementType()), | ||||
Func, Args, NameStr, InsertBefore); | Func, Args, Bundles, NameStr, InsertBefore); | ||||
} | |||||
static CallInst *Create(Value *Func, ArrayRef<Value *> Args, | |||||
const Twine &NameStr, | |||||
Instruction *InsertBefore = nullptr) { | |||||
return Create(cast<FunctionType>( | |||||
cast<PointerType>(Func->getType())->getElementType()), | |||||
Func, Args, None, NameStr, InsertBefore); | |||||
} | } | ||||
static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args, | static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args, | ||||
const Twine &NameStr = "", | const Twine &NameStr, | ||||
Instruction *InsertBefore = nullptr) { | Instruction *InsertBefore = nullptr) { | ||||
return new (unsigned(Args.size() + 1)) | return new (unsigned(Args.size() + 1)) | ||||
CallInst(Ty, Func, Args, NameStr, InsertBefore); | CallInst(Ty, Func, Args, None, NameStr, InsertBefore); | ||||
} | } | ||||
static CallInst *Create(Value *Func, | static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args, | ||||
ArrayRef<Value *> Args, | ArrayRef<OperandBundleSetDef> Bundles = None, | ||||
const Twine &NameStr = "", | |||||
Instruction *InsertBefore = nullptr) { | |||||
const unsigned TotalOps = | |||||
unsigned(Args.size()) + CountBundleInputs(Bundles) + 1; | |||||
const unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); | |||||
JosephTremoulet: Should we pad this to pointer-align the `StringMapEntry<uint32_t> *Tag` field of the… | |||||
sanjoyAuthorUnsubmitted Not Done ReplyInline ActionsPlease do check my math, but after this current round of changes, I think the Tag field should be aligned. Now, the layout of a User (in 64bit platforms) with a BundleOpInfo should be BundleOpInfo[0] // addr is 8x Tag // addr is 8x uint32_t // addr is 8(x + 1) uint32_t // addr is 8(x + 1) + 4 BundleOpInfo[1] // addr is 8(x + 2) ... ... BundleOpInfo[1, 2, 3] ... DescriptorInfo // addr is 8y intptr_t // addr is 8y Use[] // addr is 8(y + 1) ... User // addr is 8(y + 1 + 3 * # uses) For 32 bit platforms, things should roughly stay the same, except the uint32_ts will take up one whole word instead. However, I'm sure if the Begin and End fields should be uint32_ts, instead of being a native int. What do you think? sanjoy: Please do check my math, but after this current round of changes, I think the `Tag` field… | |||||
Not Done ReplyInline ActionsI agree with your math. I think leaving Begin and End as uint32_t makes sense; I doubt this would be the only weak link if someone tried to put 2^32 operands on a call, and even if we were to run on a platform with an odd pointer size, I'd expect sizeof(BundleOpInfo) to be a multiple of it by virtue of the Tag pointer field. JosephTremoulet: I agree with your math. I think leaving `Begin` and `End` as `uint32_t` makes sense; I doubt… | |||||
return new (TotalOps, DescriptorBytes) | |||||
CallInst(Ty, Func, Args, Bundles, NameStr, InsertBefore); | |||||
} | |||||
static CallInst *Create(Value *Func, ArrayRef<Value *> Args, | |||||
ArrayRef<OperandBundleSetDef> Bundles, | |||||
const Twine &NameStr, BasicBlock *InsertAtEnd) { | |||||
const unsigned TotalOps = | |||||
unsigned(Args.size()) + CountBundleInputs(Bundles) + 1; | |||||
const unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); | |||||
return new (TotalOps, DescriptorBytes) | |||||
CallInst(Func, Args, Bundles, NameStr, InsertAtEnd); | |||||
} | |||||
static CallInst *Create(Value *Func, ArrayRef<Value *> Args, | |||||
const Twine &NameStr, BasicBlock *InsertAtEnd) { | const Twine &NameStr, BasicBlock *InsertAtEnd) { | ||||
return new(unsigned(Args.size() + 1)) | return new (unsigned(Args.size() + 1)) | ||||
CallInst(Func, Args, NameStr, InsertAtEnd); | CallInst(Func, Args, None, NameStr, InsertAtEnd); | ||||
} | } | ||||
static CallInst *Create(Value *F, const Twine &NameStr = "", | static CallInst *Create(Value *F, const Twine &NameStr = "", | ||||
Instruction *InsertBefore = nullptr) { | Instruction *InsertBefore = nullptr) { | ||||
return new(1) CallInst(F, NameStr, InsertBefore); | return new(1) CallInst(F, NameStr, InsertBefore); | ||||
} | } | ||||
static CallInst *Create(Value *F, const Twine &NameStr, | static CallInst *Create(Value *F, const Twine &NameStr, | ||||
BasicBlock *InsertAtEnd) { | BasicBlock *InsertAtEnd) { | ||||
return new(1) CallInst(F, NameStr, InsertAtEnd); | return new(1) CallInst(F, NameStr, InsertAtEnd); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | setInstructionSubclassData((getSubclassDataFromInstruction() & ~3) | | ||||
unsigned(TCK)); | unsigned(TCK)); | ||||
} | } | ||||
/// Provide fast operand accessors | /// Provide fast operand accessors | ||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | ||||
/// getNumArgOperands - Return the number of call arguments. | /// getNumArgOperands - Return the number of call arguments. | ||||
/// | /// | ||||
unsigned getNumArgOperands() const { return getNumOperands() - 1; } | unsigned getNumArgOperands() const { | ||||
return getNumOperands() - getNumTotalBundleOperands() - 1; | |||||
} | |||||
/// getArgOperand/setArgOperand - Return/set the i-th call argument. | /// getArgOperand/setArgOperand - Return/set the i-th call argument. | ||||
/// | /// | ||||
Value *getArgOperand(unsigned i) const { | Value *getArgOperand(unsigned i) const { | ||||
assert(i < getNumArgOperands() && "Out of bounds!"); | assert(i < getNumArgOperands() && "Out of bounds!"); | ||||
return getOperand(i); | return getOperand(i); | ||||
} | } | ||||
void setArgOperand(unsigned i, Value *v) { | void setArgOperand(unsigned i, Value *v) { | ||||
assert(i < getNumArgOperands() && "Out of bounds!"); | assert(i < getNumArgOperands() && "Out of bounds!"); | ||||
setOperand(i, v); | setOperand(i, v); | ||||
} | } | ||||
/// arg_operands - iteration adapter for range-for loops. | /// arg_operands - iteration adapter for range-for loops. | ||||
iterator_range<op_iterator> arg_operands() { | iterator_range<op_iterator> arg_operands() { | ||||
// The last operand in the op list is the callee - it's not one of the args | // The last operand in the op list is the callee - it's not one of the args | ||||
// so we don't want to iterate over it. | // so we don't want to iterate over it. | ||||
return iterator_range<op_iterator>(op_begin(), op_end() - 1); | return iterator_range<op_iterator>( | ||||
op_begin(), op_end() - getNumTotalBundleOperands() - 1); | |||||
} | } | ||||
/// arg_operands - iteration adapter for range-for loops. | /// arg_operands - iteration adapter for range-for loops. | ||||
iterator_range<const_op_iterator> arg_operands() const { | iterator_range<const_op_iterator> arg_operands() const { | ||||
return iterator_range<const_op_iterator>(op_begin(), op_end() - 1); | return iterator_range<const_op_iterator>( | ||||
op_begin(), op_end() - getNumTotalBundleOperands() - 1); | |||||
} | } | ||||
/// \brief Wrappers for getting the \c Use of a call argument. | /// \brief Wrappers for getting the \c Use of a call argument. | ||||
const Use &getArgOperandUse(unsigned i) const { | const Use &getArgOperandUse(unsigned i) const { | ||||
assert(i < getNumArgOperands() && "Out of bounds!"); | assert(i < getNumArgOperands() && "Out of bounds!"); | ||||
return getOperandUse(i); | return getOperandUse(i); | ||||
} | } | ||||
Use &getArgOperandUse(unsigned i) { | Use &getArgOperandUse(unsigned i) { | ||||
▲ Show 20 Lines • Show All 198 Lines • ▼ Show 20 Lines | private: | ||||
} | } | ||||
}; | }; | ||||
template <> | template <> | ||||
struct OperandTraits<CallInst> : public VariadicOperandTraits<CallInst, 1> { | struct OperandTraits<CallInst> : public VariadicOperandTraits<CallInst, 1> { | ||||
}; | }; | ||||
CallInst::CallInst(Value *Func, ArrayRef<Value *> Args, | CallInst::CallInst(Value *Func, ArrayRef<Value *> Args, | ||||
const Twine &NameStr, BasicBlock *InsertAtEnd) | ArrayRef<OperandBundleSetDef> Bundles, const Twine &NameStr, | ||||
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) | BasicBlock *InsertAtEnd) | ||||
: Instruction( | |||||
cast<FunctionType>(cast<PointerType>(Func->getType()) | |||||
->getElementType())->getReturnType(), | ->getElementType())->getReturnType(), | ||||
Instruction::Call, | Instruction::Call, OperandTraits<CallInst>::op_end(this) - | ||||
OperandTraits<CallInst>::op_end(this) - (Args.size() + 1), | (Args.size() + CountBundleInputs(Bundles) + 1), | ||||
unsigned(Args.size() + 1), InsertAtEnd) { | unsigned(Args.size() + CountBundleInputs(Bundles) + 1), InsertAtEnd) { | ||||
init(Func, Args, NameStr); | init(Func, Args, Bundles, NameStr); | ||||
} | } | ||||
CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args, | CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args, | ||||
const Twine &NameStr, Instruction *InsertBefore) | ArrayRef<OperandBundleSetDef> Bundles, const Twine &NameStr, | ||||
Instruction *InsertBefore) | |||||
: Instruction(Ty->getReturnType(), Instruction::Call, | : Instruction(Ty->getReturnType(), Instruction::Call, | ||||
OperandTraits<CallInst>::op_end(this) - (Args.size() + 1), | OperandTraits<CallInst>::op_end(this) - | ||||
unsigned(Args.size() + 1), InsertBefore) { | (Args.size() + CountBundleInputs(Bundles) + 1), | ||||
init(Ty, Func, Args, NameStr); | unsigned(Args.size() + CountBundleInputs(Bundles) + 1), | ||||
InsertBefore) { | |||||
init(Ty, Func, Args, Bundles, NameStr); | |||||
} | } | ||||
// Note: if you get compile errors about private methods then | // Note: if you get compile errors about private methods then | ||||
// please update your code to use the high-level operand | // please update your code to use the high-level operand | ||||
// interfaces. See line 943 above. | // interfaces. See line 943 above. | ||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CallInst, Value) | DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CallInst, Value) | ||||
▲ Show 20 Lines • Show All 1,461 Lines • ▼ Show 20 Lines | |||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
// InvokeInst Class | // InvokeInst Class | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
/// InvokeInst - Invoke instruction. The SubclassData field is used to hold the | /// InvokeInst - Invoke instruction. The SubclassData field is used to hold the | ||||
/// calling convention of the call. | /// calling convention of the call. | ||||
/// | /// | ||||
class InvokeInst : public TerminatorInst { | class InvokeInst : public TerminatorInst, public OperandBundleUser<InvokeInst> { | ||||
AttributeSet AttributeList; | AttributeSet AttributeList; | ||||
FunctionType *FTy; | FunctionType *FTy; | ||||
InvokeInst(const InvokeInst &BI); | InvokeInst(const InvokeInst &BI); | ||||
void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, | void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, | ||||
ArrayRef<Value *> Args, const Twine &NameStr) { | ArrayRef<Value *> Args, ArrayRef<OperandBundleSetDef> Bundles, | ||||
const Twine &NameStr) { | |||||
init(cast<FunctionType>( | init(cast<FunctionType>( | ||||
cast<PointerType>(Func->getType())->getElementType()), | cast<PointerType>(Func->getType())->getElementType()), | ||||
Func, IfNormal, IfException, Args, NameStr); | Func, IfNormal, IfException, Args, Bundles, NameStr); | ||||
} | } | ||||
void init(FunctionType *FTy, Value *Func, BasicBlock *IfNormal, | void init(FunctionType *FTy, Value *Func, BasicBlock *IfNormal, | ||||
BasicBlock *IfException, ArrayRef<Value *> Args, | BasicBlock *IfException, ArrayRef<Value *> Args, | ||||
const Twine &NameStr); | ArrayRef<OperandBundleSetDef> Bundles, const Twine &NameStr); | ||||
/// Construct an InvokeInst given a range of arguments. | /// Construct an InvokeInst given a range of arguments. | ||||
/// | /// | ||||
/// \brief Construct an InvokeInst from a range of arguments | /// \brief Construct an InvokeInst from a range of arguments | ||||
inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, | inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, | ||||
ArrayRef<Value *> Args, unsigned Values, | ArrayRef<Value *> Args, | ||||
ArrayRef<OperandBundleSetDef> Bundles, unsigned Values, | |||||
const Twine &NameStr, Instruction *InsertBefore) | const Twine &NameStr, Instruction *InsertBefore) | ||||
: InvokeInst(cast<FunctionType>( | : InvokeInst(cast<FunctionType>( | ||||
cast<PointerType>(Func->getType())->getElementType()), | cast<PointerType>(Func->getType())->getElementType()), | ||||
Func, IfNormal, IfException, Args, Values, NameStr, | Func, IfNormal, IfException, Args, Bundles, Values, NameStr, | ||||
InsertBefore) {} | InsertBefore) {} | ||||
inline InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, | inline InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, | ||||
BasicBlock *IfException, ArrayRef<Value *> Args, | BasicBlock *IfException, ArrayRef<Value *> Args, | ||||
unsigned Values, const Twine &NameStr, | ArrayRef<OperandBundleSetDef> Bundles, unsigned Values, | ||||
Instruction *InsertBefore); | const Twine &NameStr, Instruction *InsertBefore); | ||||
/// Construct an InvokeInst given a range of arguments. | /// Construct an InvokeInst given a range of arguments. | ||||
/// | /// | ||||
/// \brief Construct an InvokeInst from a range of arguments | /// \brief Construct an InvokeInst from a range of arguments | ||||
inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, | inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, | ||||
ArrayRef<Value *> Args, unsigned Values, | ArrayRef<Value *> Args, | ||||
ArrayRef<OperandBundleSetDef> Bundles, unsigned Values, | |||||
const Twine &NameStr, BasicBlock *InsertAtEnd); | const Twine &NameStr, BasicBlock *InsertAtEnd); | ||||
friend class OperandBundleUser<InvokeInst>; | |||||
bool hasDescriptor() const { return HasDescriptor; } | |||||
protected: | protected: | ||||
// Note: Instruction needs to be a friend here to call cloneImpl. | // Note: Instruction needs to be a friend here to call cloneImpl. | ||||
friend class Instruction; | friend class Instruction; | ||||
InvokeInst *cloneImpl() const; | InvokeInst *cloneImpl() const; | ||||
public: | public: | ||||
static InvokeInst *Create(Value *Func, | static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, | ||||
BasicBlock *IfNormal, BasicBlock *IfException, | BasicBlock *IfException, ArrayRef<Value *> Args, | ||||
ArrayRef<Value *> Args, const Twine &NameStr = "", | const Twine &NameStr, | ||||
Instruction *InsertBefore = nullptr) { | Instruction *InsertBefore = nullptr) { | ||||
return Create(cast<FunctionType>( | return Create(cast<FunctionType>( | ||||
cast<PointerType>(Func->getType())->getElementType()), | cast<PointerType>(Func->getType())->getElementType()), | ||||
Func, IfNormal, IfException, Args, NameStr, InsertBefore); | Func, IfNormal, IfException, Args, None, NameStr, | ||||
InsertBefore); | |||||
} | } | ||||
static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, | static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, | ||||
BasicBlock *IfException, ArrayRef<Value *> Args, | BasicBlock *IfException, ArrayRef<Value *> Args, | ||||
ArrayRef<OperandBundleSetDef> Bundles = None, | |||||
const Twine &NameStr = "", | const Twine &NameStr = "", | ||||
Instruction *InsertBefore = nullptr) { | Instruction *InsertBefore = nullptr) { | ||||
return Create(cast<FunctionType>( | |||||
cast<PointerType>(Func->getType())->getElementType()), | |||||
Func, IfNormal, IfException, Args, Bundles, 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; | unsigned Values = unsigned(Args.size()) + 3; | ||||
return new (Values) InvokeInst(Ty, Func, IfNormal, IfException, Args, | return new (Values) InvokeInst(Ty, Func, IfNormal, IfException, Args, None, | ||||
Values, NameStr, InsertBefore); | Values, NameStr, InsertBefore); | ||||
} | } | ||||
static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, | |||||
BasicBlock *IfException, ArrayRef<Value *> Args, | |||||
ArrayRef<OperandBundleSetDef> Bundles = None, | |||||
const Twine &NameStr = "", | |||||
Instruction *InsertBefore = nullptr) { | |||||
unsigned Values = unsigned(Args.size()) + CountBundleInputs(Bundles) + 3; | |||||
unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); | |||||
return new (Values, DescriptorBytes) | |||||
InvokeInst(Ty, Func, IfNormal, IfException, Args, Bundles, Values, | |||||
NameStr, InsertBefore); | |||||
} | |||||
static InvokeInst *Create(Value *Func, | static InvokeInst *Create(Value *Func, | ||||
BasicBlock *IfNormal, BasicBlock *IfException, | BasicBlock *IfNormal, BasicBlock *IfException, | ||||
ArrayRef<Value *> Args, const Twine &NameStr, | ArrayRef<Value *> Args, const Twine &NameStr, | ||||
BasicBlock *InsertAtEnd) { | BasicBlock *InsertAtEnd) { | ||||
unsigned Values = unsigned(Args.size()) + 3; | unsigned Values = unsigned(Args.size()) + 3; | ||||
return new(Values) InvokeInst(Func, IfNormal, IfException, Args, | return new (Values) InvokeInst(Func, IfNormal, IfException, Args, None, | ||||
Values, NameStr, InsertAtEnd); | Values, NameStr, InsertAtEnd); | ||||
} | } | ||||
static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, | |||||
BasicBlock *IfException, ArrayRef<Value *> Args, | |||||
ArrayRef<OperandBundleSetDef> Bundles, | |||||
const Twine &NameStr, BasicBlock *InsertAtEnd) { | |||||
unsigned Values = unsigned(Args.size()) + CountBundleInputs(Bundles) + 3; | |||||
unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); | |||||
return new (Values, DescriptorBytes) | |||||
InvokeInst(Func, IfNormal, IfException, Args, Bundles, Values, NameStr, | |||||
InsertAtEnd); | |||||
} | |||||
/// Provide fast operand accessors | /// Provide fast operand accessors | ||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | ||||
FunctionType *getFunctionType() const { return FTy; } | FunctionType *getFunctionType() const { return FTy; } | ||||
void mutateFunctionType(FunctionType *FTy) { | void mutateFunctionType(FunctionType *FTy) { | ||||
mutateType(FTy->getReturnType()); | mutateType(FTy->getReturnType()); | ||||
this->FTy = FTy; | this->FTy = FTy; | ||||
} | } | ||||
/// getNumArgOperands - Return the number of invoke arguments. | /// getNumArgOperands - Return the number of invoke arguments. | ||||
/// | /// | ||||
unsigned getNumArgOperands() const { return getNumOperands() - 3; } | unsigned getNumArgOperands() const { | ||||
return getNumOperands() - getNumTotalBundleOperands() - 3; | |||||
} | |||||
/// getArgOperand/setArgOperand - Return/set the i-th invoke argument. | /// getArgOperand/setArgOperand - Return/set the i-th invoke argument. | ||||
/// | /// | ||||
Value *getArgOperand(unsigned i) const { | Value *getArgOperand(unsigned i) const { | ||||
assert(i < getNumArgOperands() && "Out of bounds!"); | assert(i < getNumArgOperands() && "Out of bounds!"); | ||||
return getOperand(i); | return getOperand(i); | ||||
} | } | ||||
void setArgOperand(unsigned i, Value *v) { | void setArgOperand(unsigned i, Value *v) { | ||||
assert(i < getNumArgOperands() && "Out of bounds!"); | assert(i < getNumArgOperands() && "Out of bounds!"); | ||||
setOperand(i, v); | setOperand(i, v); | ||||
} | } | ||||
/// arg_operands - iteration adapter for range-for loops. | /// arg_operands - iteration adapter for range-for loops. | ||||
iterator_range<op_iterator> arg_operands() { | iterator_range<op_iterator> arg_operands() { | ||||
return iterator_range<op_iterator>(op_begin(), op_end() - 3); | return iterator_range<op_iterator>( | ||||
op_begin(), op_end() - getNumTotalBundleOperands() - 3); | |||||
} | } | ||||
/// arg_operands - iteration adapter for range-for loops. | /// arg_operands - iteration adapter for range-for loops. | ||||
iterator_range<const_op_iterator> arg_operands() const { | iterator_range<const_op_iterator> arg_operands() const { | ||||
return iterator_range<const_op_iterator>(op_begin(), op_end() - 3); | return iterator_range<const_op_iterator>( | ||||
op_begin(), op_end() - getNumTotalBundleOperands() - 3); | |||||
} | } | ||||
/// \brief Wrappers for getting the \c Use of a invoke argument. | /// \brief Wrappers for getting the \c Use of a invoke argument. | ||||
const Use &getArgOperandUse(unsigned i) const { | const Use &getArgOperandUse(unsigned i) const { | ||||
assert(i < getNumArgOperands() && "Out of bounds!"); | assert(i < getNumArgOperands() && "Out of bounds!"); | ||||
return getOperandUse(i); | return getOperandUse(i); | ||||
} | } | ||||
Use &getArgOperandUse(unsigned i) { | Use &getArgOperandUse(unsigned i) { | ||||
▲ Show 20 Lines • Show All 206 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
template <> | template <> | ||||
struct OperandTraits<InvokeInst> : public VariadicOperandTraits<InvokeInst, 3> { | struct OperandTraits<InvokeInst> : public VariadicOperandTraits<InvokeInst, 3> { | ||||
}; | }; | ||||
InvokeInst::InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, | InvokeInst::InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, | ||||
BasicBlock *IfException, ArrayRef<Value *> Args, | BasicBlock *IfException, ArrayRef<Value *> Args, | ||||
unsigned Values, const Twine &NameStr, | ArrayRef<OperandBundleSetDef> Bundles, unsigned Values, | ||||
Instruction *InsertBefore) | const Twine &NameStr, Instruction *InsertBefore) | ||||
: TerminatorInst(Ty->getReturnType(), Instruction::Invoke, | : TerminatorInst(Ty->getReturnType(), Instruction::Invoke, | ||||
OperandTraits<InvokeInst>::op_end(this) - Values, Values, | OperandTraits<InvokeInst>::op_end(this) - Values, Values, | ||||
InsertBefore) { | InsertBefore) { | ||||
init(Ty, Func, IfNormal, IfException, Args, NameStr); | init(Ty, Func, IfNormal, IfException, Args, Bundles, NameStr); | ||||
} | } | ||||
InvokeInst::InvokeInst(Value *Func, | InvokeInst::InvokeInst(Value *Func, BasicBlock *IfNormal, | ||||
BasicBlock *IfNormal, BasicBlock *IfException, | BasicBlock *IfException, ArrayRef<Value *> Args, | ||||
ArrayRef<Value *> Args, unsigned Values, | ArrayRef<OperandBundleSetDef> Bundles, unsigned Values, | ||||
const Twine &NameStr, BasicBlock *InsertAtEnd) | const Twine &NameStr, BasicBlock *InsertAtEnd) | ||||
: TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType()) | : TerminatorInst( | ||||
cast<FunctionType>(cast<PointerType>(Func->getType()) | |||||
->getElementType())->getReturnType(), | ->getElementType())->getReturnType(), | ||||
Instruction::Invoke, | Instruction::Invoke, OperandTraits<InvokeInst>::op_end(this) - Values, | ||||
OperandTraits<InvokeInst>::op_end(this) - Values, | |||||
Values, InsertAtEnd) { | Values, InsertAtEnd) { | ||||
init(Func, IfNormal, IfException, Args, NameStr); | init(Func, IfNormal, IfException, Args, Bundles, NameStr); | ||||
} | } | ||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value) | DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value) | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
// ResumeInst Class | // ResumeInst Class | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
▲ Show 20 Lines • Show All 1,115 Lines • Show Last 20 Lines |
Should we pad this to pointer-align the StringMapEntry<uint32_t> *Tag field of the BundleOpInfos (and likewise for the other CallInst::Create overload and the two InvokeInst::Creates)?