/// getAlignment - Return the alignment of the memory that is being allocated
/// by the instruction.
///
- unsigned getAlignment() const { return (1u << SubclassData) >> 1; }
+ unsigned getAlignment() const {
+ return (1u << getSubclassDataFromInstruction()) >> 1;
+ }
void setAlignment(unsigned Align);
/// isStaticAlloca - Return true if this alloca is in the entry block of the
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
+private:
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
};
/// isVolatile - Return true if this is a load from a volatile memory
/// location.
///
- bool isVolatile() const { return SubclassData & 1; }
+ bool isVolatile() const { return getSubclassDataFromInstruction() & 1; }
/// setVolatile - Specify whether this is a volatile load or not.
///
void setVolatile(bool V) {
- SubclassData = (SubclassData & ~1) | (V ? 1 : 0);
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+ (V ? 1 : 0));
}
/// getAlignment - Return the alignment of the access that is being performed
///
unsigned getAlignment() const {
- return (1 << (SubclassData>>1)) >> 1;
+ return (1 << (getSubclassDataFromInstruction() >> 1)) >> 1;
}
void setAlignment(unsigned Align);
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
+private:
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
};
/// isVolatile - Return true if this is a load from a volatile memory
/// location.
///
- bool isVolatile() const { return SubclassData & 1; }
+ bool isVolatile() const { return getSubclassDataFromInstruction() & 1; }
/// setVolatile - Specify whether this is a volatile load or not.
///
void setVolatile(bool V) {
- SubclassData = (SubclassData & ~1) | (V ? 1 : 0);
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+ (V ? 1 : 0));
}
/// Transparently provide more efficient getOperand methods.
/// getAlignment - Return the alignment of the access that is being performed
///
unsigned getAlignment() const {
- return (1 << (SubclassData>>1)) >> 1;
+ return (1 << (getSubclassDataFromInstruction() >> 1)) >> 1;
}
void setAlignment(unsigned Align);
+ Value *getValueOperand() { return getOperand(0); }
+ const Value *getValueOperand() const { return getOperand(0); }
+
Value *getPointerOperand() { return getOperand(1); }
const Value *getPointerOperand() const { return getOperand(1); }
static unsigned getPointerOperandIndex() { return 1U; }
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
+private:
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
};
template <>
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to ICmp instruction are not of the same type!");
// Check that the operands are the right type
- assert((getOperand(0)->getType()->isIntOrIntVector() ||
- isa<PointerType>(getOperand(0)->getType())) &&
+ assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
+ getOperand(0)->getType()->isPointerTy()) &&
"Invalid operand types for ICmp instruction");
}
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to ICmp instruction are not of the same type!");
// Check that the operands are the right type
- assert((getOperand(0)->getType()->isIntOrIntVector() ||
- isa<PointerType>(getOperand(0)->getType())) &&
+ assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
+ getOperand(0)->getType()->isPointerTy()) &&
"Invalid operand types for ICmp instruction");
}
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to ICmp instruction are not of the same type!");
// Check that the operands are the right type
- assert((getOperand(0)->getType()->isIntOrIntVector() ||
- isa<PointerType>(getOperand(0)->getType())) &&
+ assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
+ getOperand(0)->getType()->isPointerTy()) &&
"Invalid operand types for ICmp instruction");
}
/// (e.g. ult).
/// @brief Swap operands and adjust predicate.
void swapOperands() {
- SubclassData = getSwappedPredicate();
+ setPredicate(getSwappedPredicate());
Op<0>().swap(Op<1>());
}
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to FCmp instruction are not of the same type!");
// Check that the operands are the right type
- assert(getOperand(0)->getType()->isFPOrFPVector() &&
+ assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
"Invalid operand types for FCmp instruction");
}
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to FCmp instruction are not of the same type!");
// Check that the operands are the right type
- assert(getOperand(0)->getType()->isFPOrFPVector() &&
+ assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
"Invalid operand types for FCmp instruction");
}
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to FCmp instruction are not of the same type!");
// Check that the operands are the right type
- assert(getOperand(0)->getType()->isFPOrFPVector() &&
+ assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
"Invalid operand types for FCmp instruction");
}
/// @returns true if the predicate of this instruction is EQ or NE.
/// @brief Determine if this is an equality predicate.
bool isEquality() const {
- return SubclassData == FCMP_OEQ || SubclassData == FCMP_ONE ||
- SubclassData == FCMP_UEQ || SubclassData == FCMP_UNE;
+ return getPredicate() == FCMP_OEQ || getPredicate() == FCMP_ONE ||
+ getPredicate() == FCMP_UEQ || getPredicate() == FCMP_UNE;
}
/// @returns true if the predicate of this instruction is commutative.
/// @brief Determine if this is a commutative predicate.
bool isCommutative() const {
return isEquality() ||
- SubclassData == FCMP_FALSE ||
- SubclassData == FCMP_TRUE ||
- SubclassData == FCMP_ORD ||
- SubclassData == FCMP_UNO;
+ getPredicate() == FCMP_FALSE ||
+ getPredicate() == FCMP_TRUE ||
+ getPredicate() == FCMP_ORD ||
+ getPredicate() == FCMP_UNO;
}
/// @returns true if the predicate is relational (not EQ or NE).
/// (e.g. ult).
/// @brief Swap operands and adjust predicate.
void swapOperands() {
- SubclassData = getSwappedPredicate();
+ setPredicate(getSwappedPredicate());
Op<0>().swap(Op<1>());
}
}
};
-//===----------------------------------------------------------------------===//
-// CallInst Class
//===----------------------------------------------------------------------===//
/// CallInst - This class represents a function call, abstracting a target
/// 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
/// hold the calling convention of the call.
///
-
class CallInst : public Instruction {
AttrListPtr AttributeList; ///< parameter attributes for call
CallInst(const CallInst &CI);
/// 3. Bitcast the result of the malloc call to the specified type.
static Instruction *CreateMalloc(Instruction *InsertBefore,
const Type *IntPtrTy, const Type *AllocTy,
- Value *ArraySize = 0,
+ Value *AllocSize, Value *ArraySize = 0,
const Twine &Name = "");
static Instruction *CreateMalloc(BasicBlock *InsertAtEnd,
const Type *IntPtrTy, const Type *AllocTy,
- Value *ArraySize = 0, Function* MallocF = 0,
+ Value *AllocSize, Value *ArraySize = 0,
+ Function* MallocF = 0,
const Twine &Name = "");
/// CreateFree - Generate the IR for a call to the builtin free function.
static void CreateFree(Value* Source, Instruction *InsertBefore);
~CallInst();
- bool isTailCall() const { return SubclassData & 1; }
+ bool isTailCall() const { return getSubclassDataFromInstruction() & 1; }
void setTailCall(bool isTC = true) {
- SubclassData = (SubclassData & ~1) | unsigned(isTC);
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+ unsigned(isTC));
}
+ /// @deprecated these "define hacks" will go away soon
+ /// @brief coerce out-of-tree code to abandon the low-level interfaces
+ /// @detail see below comments and update your code to high-level interfaces
+ /// in LLVM v2.8-only code
+ /// - getOperand(N+1) ---> getArgOperand(N)
+ /// - setOperand(N+1, V) ---> setArgOperand(N, V)
+ /// - getNumOperands() ---> getNumArgOperands()+1 // note the "+1"!
+ ///
+ /// in backward compatible code please consult llvm/Support/CallSite.h,
+ /// you should create a callsite using the CallInst pointer and call its
+ /// methods
+ ///
+# define public private
+# define protected private
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+# undef public
+# undef protected
+public:
+
+ enum { ArgOffset = 1 }; ///< temporary, do not use for new code!
+ unsigned getNumArgOperands() const { return getNumOperands() - 1; }
+ Value *getArgOperand(unsigned i) const { return getOperand(i + ArgOffset); }
+ void setArgOperand(unsigned i, Value *v) { setOperand(i + ArgOffset, v); }
+
+ /// Provide compile-time errors for accessing operand 0
+ /// @deprecated these will go away soon
+ /// @detail see below comments and update your code to high-level interfaces
+ /// - getOperand(0) ---> getCalledValue(), or possibly getCalledFunction
+ /// - setOperand(0, V) ---> setCalledFunction(V)
+ ///
+private:
+ void getOperand(void*); // NO IMPL ---> use getCalledValue (or possibly
+ // getCalledFunction) instead
+ void setOperand(void*, Value*); // NO IMPL ---> use setCalledFunction instead
+public:
/// getCallingConv/setCallingConv - Get or set the calling convention of this
/// function call.
CallingConv::ID getCallingConv() const {
- return static_cast<CallingConv::ID>(SubclassData >> 1);
+ return static_cast<CallingConv::ID>(getSubclassDataFromInstruction() >> 1);
}
void setCallingConv(CallingConv::ID CC) {
- SubclassData = (SubclassData & 1) | (static_cast<unsigned>(CC) << 1);
+ setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
+ (static_cast<unsigned>(CC) << 1));
}
/// getAttributes - Return the parameter attributes for this call.
unsigned getParamAlignment(unsigned i) const {
return AttributeList.getParamAlignment(i);
}
+
+ /// @brief Return true if the call should not be inlined.
+ bool isNoInline() const { return paramHasAttr(~0, Attribute::NoInline); }
+ void setIsNoInline(bool Value = true) {
+ if (Value) addAttribute(~0, Attribute::NoInline);
+ else removeAttribute(~0, Attribute::NoInline);
+ }
/// @brief Determine if the call does not access memory.
bool doesNotAccessMemory() const {
}
/// @brief Determine if the call cannot return.
- bool doesNotReturn() const {
- return paramHasAttr(~0, Attribute::NoReturn);
- }
+ bool doesNotReturn() const { return paramHasAttr(~0, Attribute::NoReturn); }
void setDoesNotReturn(bool DoesNotReturn = true) {
if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn);
else removeAttribute(~0, Attribute::NoReturn);
}
/// @brief Determine if the call cannot unwind.
- bool doesNotThrow() const {
- return paramHasAttr(~0, Attribute::NoUnwind);
- }
+ bool doesNotThrow() const { return paramHasAttr(~0, Attribute::NoUnwind); }
void setDoesNotThrow(bool DoesNotThrow = true) {
if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind);
else removeAttribute(~0, Attribute::NoUnwind);
/// indirect function invocation.
///
Function *getCalledFunction() const {
- return dyn_cast<Function>(Op<0>());
+ return dyn_cast<Function>(Op<ArgOffset -1>());
}
/// getCalledValue - Get a pointer to the function that is invoked by this
/// instruction.
- const Value *getCalledValue() const { return Op<0>(); }
- Value *getCalledValue() { return Op<0>(); }
+ const Value *getCalledValue() const { return Op<ArgOffset -1>(); }
+ Value *getCalledValue() { return Op<ArgOffset -1>(); }
/// setCalledFunction - Set the function called.
void setCalledFunction(Value* Fn) {
- Op<0>() = Fn;
+ Op<ArgOffset -1>() = Fn;
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
+private:
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
};
template <>
->getElementType())->getReturnType(),
Instruction::Call,
OperandTraits<CallInst>::op_end(this) - (ArgEnd - ArgBegin + 1),
- (unsigned)(ArgEnd - ArgBegin + 1), InsertAtEnd) {
+ unsigned(ArgEnd - ArgBegin + 1), InsertAtEnd) {
init(Func, ArgBegin, ArgEnd, NameStr,
typename std::iterator_traits<InputIterator>::iterator_category());
}
typename std::iterator_traits<InputIterator>::iterator_category());
}
+
+// Note: if you get compile errors about private methods then
+// please update your code to use the high-level operand
+// interfaces. See line 943 above.
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CallInst, Value)
//===----------------------------------------------------------------------===//
return i/2;
}
- /// getIncomingBlock - Return incoming basic block #i.
+ /// getIncomingBlock - Return incoming basic block number @p i.
///
BasicBlock *getIncomingBlock(unsigned i) const {
return cast<BasicBlock>(getOperand(i*2+1));
};
template <>
-struct OperandTraits<ReturnInst> : public OptionalOperandTraits<> {
+struct OperandTraits<ReturnInst> : public VariadicOperandTraits<> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ReturnInst, Value)
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+ unsigned getNumArgOperands() const { return getNumOperands() - 3; }
+ Value *getArgOperand(unsigned i) const { return getOperand(i); }
+ void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+
/// getCallingConv/setCallingConv - Get or set the calling convention of this
/// function call.
CallingConv::ID getCallingConv() const {
- return static_cast<CallingConv::ID>(SubclassData);
+ return static_cast<CallingConv::ID>(getSubclassDataFromInstruction());
}
void setCallingConv(CallingConv::ID CC) {
- SubclassData = static_cast<unsigned>(CC);
+ setInstructionSubclassData(static_cast<unsigned>(CC));
}
/// getAttributes - Return the parameter attributes for this invoke.
return AttributeList.getParamAlignment(i);
}
+ /// @brief Return true if the call should not be inlined.
+ bool isNoInline() const { return paramHasAttr(~0, Attribute::NoInline); }
+ void setIsNoInline(bool Value = true) {
+ if (Value) addAttribute(~0, Attribute::NoInline);
+ else removeAttribute(~0, Attribute::NoInline);
+ }
+
/// @brief Determine if the call does not access memory.
bool doesNotAccessMemory() const {
return paramHasAttr(~0, Attribute::ReadNone);
}
/// @brief Determine if the call cannot return.
- bool doesNotReturn() const {
- return paramHasAttr(~0, Attribute::NoReturn);
- }
+ bool doesNotReturn() const { return paramHasAttr(~0, Attribute::NoReturn); }
void setDoesNotReturn(bool DoesNotReturn = true) {
if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn);
else removeAttribute(~0, Attribute::NoReturn);
}
/// @brief Determine if the call cannot unwind.
- bool doesNotThrow() const {
- return paramHasAttr(~0, Attribute::NoUnwind);
- }
+ bool doesNotThrow() const { return paramHasAttr(~0, Attribute::NoUnwind); }
void setDoesNotThrow(bool DoesNotThrow = true) {
if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind);
else removeAttribute(~0, Attribute::NoUnwind);
/// indirect function invocation.
///
Function *getCalledFunction() const {
- return dyn_cast<Function>(getOperand(0));
+ return dyn_cast<Function>(Op<-3>());
}
/// getCalledValue - Get a pointer to the function that is invoked by this
/// instruction
- const Value *getCalledValue() const { return getOperand(0); }
- Value *getCalledValue() { return getOperand(0); }
+ const Value *getCalledValue() const { return Op<-3>(); }
+ Value *getCalledValue() { return Op<-3>(); }
+
+ /// setCalledFunction - Set the function called.
+ void setCalledFunction(Value* Fn) {
+ Op<-3>() = Fn;
+ }
// get*Dest - Return the destination basic blocks...
BasicBlock *getNormalDest() const {
- return cast<BasicBlock>(getOperand(1));
+ return cast<BasicBlock>(Op<-2>());
}
BasicBlock *getUnwindDest() const {
- return cast<BasicBlock>(getOperand(2));
+ return cast<BasicBlock>(Op<-1>());
}
void setNormalDest(BasicBlock *B) {
- setOperand(1, (Value*)B);
+ Op<-2>() = reinterpret_cast<Value*>(B);
}
-
void setUnwindDest(BasicBlock *B) {
- setOperand(2, (Value*)B);
+ Op<-1>() = reinterpret_cast<Value*>(B);
}
BasicBlock *getSuccessor(unsigned i) const {
void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
assert(idx < 2 && "Successor # out of range for invoke!");
- setOperand(idx+1, (Value*)NewSucc);
+ *(&Op<-2>() + idx) = reinterpret_cast<Value*>(NewSucc);
}
unsigned getNumSuccessors() const { return 2; }
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
+
private:
virtual BasicBlock *getSuccessorV(unsigned idx) const;
virtual unsigned getNumSuccessorsV() const;
virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
};
template <>