#define LLVM_IR_CALLSITE_H
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Instructions.h"
class InvokeInst;
template <typename FunTy = const Function,
+ typename BBTy = const BasicBlock,
typename ValTy = const Value,
typename UserTy = const User,
+ typename UseTy = const Use,
typename InstrTy = const Instruction,
typename CallTy = const CallInst,
typename InvokeTy = const InvokeInst,
class CallSiteBase {
protected:
PointerIntPair<InstrTy*, 1, bool> I;
-public:
- CallSiteBase() : I(0, false) {}
+
+ CallSiteBase() : I(nullptr, false) {}
CallSiteBase(CallTy *CI) : I(CI, true) { assert(CI); }
CallSiteBase(InvokeTy *II) : I(II, false) { assert(II); }
- CallSiteBase(ValTy *II) { *this = get(II); }
-protected:
+ explicit CallSiteBase(ValTy *II) { *this = get(II); }
+
+private:
/// CallSiteBase::get - This static method is sort of like a constructor. It
/// will create an appropriate call site for a Call or Invoke instruction, but
/// it can also create a null initialized CallSiteBase object for something
}
return CallSiteBase();
}
+
public:
/// isCall - true if a CallInst is enclosed.
/// Note that !isCall() does not mean it is an InvokeInst enclosed,
InstrTy *getInstruction() const { return I.getPointer(); }
InstrTy *operator->() const { return I.getPointer(); }
- LLVM_EXPLICIT operator bool() const { return I.getPointer(); }
+ explicit operator bool() const { return I.getPointer(); }
+
+ /// Get the basic block containing the call site
+ BBTy* getParent() const { return getInstruction()->getParent(); }
/// getCalledValue - Return the pointer to function that is being called.
///
/// isCallee - Determine whether the passed iterator points to the
/// callee operand's Use.
- ///
- bool isCallee(Value::const_use_iterator UI) const {
- return getCallee() == &UI.getUse();
+ bool isCallee(Value::const_user_iterator UI) const {
+ return isCallee(&UI.getUse());
+ }
+
+ /// Determine whether this Use is the callee operand's Use.
+ bool isCallee(const Use *U) const { return getCallee() == U; }
+
+ /// \brief Determine whether the passed iterator points to an argument
+ /// operand.
+ bool isArgOperand(Value::const_user_iterator UI) const {
+ return isArgOperand(&UI.getUse());
+ }
+
+ /// \brief Determine whether the passed use points to an argument operand.
+ bool isArgOperand(const Use *U) const {
+ assert(getInstruction() == U->getUser());
+ return arg_begin() <= U && U < arg_end();
+ }
+
+ /// \brief Determine whether the passed iterator points to a bundle operand.
+ bool isBundleOperand(Value::const_user_iterator UI) const {
+ return isBundleOperand(&UI.getUse());
+ }
+
+ /// \brief Determine whether the passed use points to a bundle operand.
+ bool isBundleOperand(const Use *U) const {
+ assert(getInstruction() == U->getUser());
+ if (!hasOperandBundles())
+ return false;
+ unsigned OperandNo = U - (*this)->op_begin();
+ return getBundleOperandsStartIndex() <= OperandNo &&
+ OperandNo < getBundleOperandsEndIndex();
+ }
+
+ /// \brief Determine whether the passed iterator points to a data operand.
+ bool isDataOperand(Value::const_user_iterator UI) const {
+ return isDataOperand(&UI.getUse());
+ }
+
+ /// \brief Determine whether the passed use points to a data operand.
+ bool isDataOperand(const Use *U) const {
+ return data_operands_begin() <= U && U < data_operands_end();
}
ValTy *getArgument(unsigned ArgNo) const {
/// Given a value use iterator, returns the argument that corresponds to it.
/// Iterator must actually correspond to an argument.
- unsigned getArgumentNo(Value::const_use_iterator I) const {
+ unsigned getArgumentNo(Value::const_user_iterator I) const {
+ return getArgumentNo(&I.getUse());
+ }
+
+ /// Given a use for an argument, get the argument number that corresponds to
+ /// it.
+ unsigned getArgumentNo(const Use *U) const {
assert(getInstruction() && "Not a call or invoke instruction!");
- assert(arg_begin() <= &I.getUse() && &I.getUse() < arg_end()
- && "Argument # out of range!");
- return &I.getUse() - arg_begin();
+ assert(isArgOperand(U) && "Argument # out of range!");
+ return U - arg_begin();
}
/// arg_iterator - The type of iterator to use when looping over actual
/// arguments at this call site.
typedef IterTy arg_iterator;
- /// arg_begin/arg_end - Return iterators corresponding to the actual argument
- /// list for a call site.
- IterTy arg_begin() const {
+ iterator_range<IterTy> args() const {
+ return make_range(arg_begin(), arg_end());
+ }
+ bool arg_empty() const { return arg_end() == arg_begin(); }
+ unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
+
+ /// Given a value use iterator, returns the data operand that corresponds to
+ /// it.
+ /// Iterator must actually correspond to a data operand.
+ unsigned getDataOperandNo(Value::const_user_iterator UI) const {
+ return getDataOperandNo(&UI.getUse());
+ }
+
+ /// Given a use for a data operand, get the data operand number that
+ /// corresponds to it.
+ unsigned getDataOperandNo(const Use *U) const {
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ assert(isDataOperand(U) && "Data operand # out of range!");
+ return U - data_operands_begin();
+ }
+
+ /// Type of iterator to use when looping over data operands at this call site
+ /// (see below).
+ typedef IterTy data_operand_iterator;
+
+ /// data_operands_begin/data_operands_end - Return iterators iterating over
+ /// the call / invoke argument list and bundle operands. For invokes, this is
+ /// the set of instruction operands except the invoke target and the two
+ /// successor blocks; and for calls this is the set of instruction operands
+ /// except the call target.
+
+ IterTy data_operands_begin() const {
assert(getInstruction() && "Not a call or invoke instruction!");
- // Skip non-arguments
return (*this)->op_begin();
}
+ IterTy data_operands_end() const {
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ return (*this)->op_end() - (isCall() ? 1 : 3);
+ }
+ iterator_range<IterTy> data_ops() const {
+ return make_range(data_operands_begin(), data_operands_end());
+ }
+ bool data_operands_empty() const {
+ return data_operands_end() == data_operands_begin();
+ }
+ unsigned data_operands_size() const {
+ return std::distance(data_operands_begin(), data_operands_end());
+ }
- IterTy arg_end() const { return (*this)->op_end() - getArgumentEndOffset(); }
- bool arg_empty() const { return arg_end() == arg_begin(); }
- unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
-
/// getType - Return the type of the instruction that generated this call site
///
Type *getType() const { return (*this)->getType(); }
///
FunTy *getCaller() const { return (*this)->getParent()->getParent(); }
+ /// \brief Tests if this call site must be tail call optimized. Only a
+ /// CallInst can be tail call optimized.
+ bool isMustTailCall() const {
+ return isCall() && cast<CallInst>(getInstruction())->isMustTailCall();
+ }
+
+ /// \brief Tests if this call site is marked as a tail call.
+ bool isTailCall() const {
+ return isCall() && cast<CallInst>(getInstruction())->isTailCall();
+ }
+
#define CALLSITE_DELEGATE_GETTER(METHOD) \
InstrTy *II = getInstruction(); \
return isCall() \
else \
cast<InvokeInst>(II)->METHOD
+ unsigned getNumArgOperands() const {
+ CALLSITE_DELEGATE_GETTER(getNumArgOperands());
+ }
+
+ ValTy *getArgOperand(unsigned i) const {
+ CALLSITE_DELEGATE_GETTER(getArgOperand(i));
+ }
+
+ bool isInlineAsm() const {
+ if (isCall())
+ return cast<CallInst>(getInstruction())->isInlineAsm();
+ return false;
+ }
+
/// getCallingConv/setCallingConv - get or set the calling convention of the
/// call.
CallingConv::ID getCallingConv() const {
CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
}
+ FunctionType *getFunctionType() const {
+ CALLSITE_DELEGATE_GETTER(getFunctionType());
+ }
+
+ void mutateFunctionType(FunctionType *Ty) const {
+ CALLSITE_DELEGATE_SETTER(mutateFunctionType(Ty));
+ }
+
/// getAttributes/setAttributes - get or set the parameter attributes of
/// the call.
const AttributeSet &getAttributes() const {
CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A));
}
+ /// \brief Return true if the data operand at index \p i directly or
+ /// indirectly has the attribute \p A.
+ ///
+ /// Normal call or invoke arguments have per operand attributes, as specified
+ /// in the attribute set attached to this instruction, while operand bundle
+ /// operands may have some attributes implied by the type of its containing
+ /// operand bundle.
+ bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind A) const {
+ CALLSITE_DELEGATE_GETTER(dataOperandHasImpliedAttr(i, A));
+ }
+
/// @brief Extract the alignment for a call or parameter (0=unknown).
uint16_t getParamAlignment(uint16_t i) const {
CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
}
+ /// @brief Extract the number of dereferenceable bytes for a call or
+ /// parameter (0=unknown).
+ uint64_t getDereferenceableBytes(uint16_t i) const {
+ CALLSITE_DELEGATE_GETTER(getDereferenceableBytes(i));
+ }
+
+ /// @brief Extract the number of dereferenceable_or_null bytes for a call or
+ /// parameter (0=unknown).
+ uint64_t getDereferenceableOrNullBytes(uint16_t i) const {
+ CALLSITE_DELEGATE_GETTER(getDereferenceableOrNullBytes(i));
+ }
+
+ /// @brief Determine if the parameter or return value is marked with NoAlias
+ /// attribute.
+ /// @param n The parameter to check. 1 is the first parameter, 0 is the return
+ bool doesNotAlias(unsigned n) const {
+ CALLSITE_DELEGATE_GETTER(doesNotAlias(n));
+ }
+
/// \brief Return true if the call should not be treated as a call to a
/// builtin.
bool isNoBuiltin() const {
CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory());
}
+ /// @brief Determine if the call can access memmory only using pointers based
+ /// on its arguments.
+ bool onlyAccessesArgMemory() const {
+ CALLSITE_DELEGATE_GETTER(onlyAccessesArgMemory());
+ }
+ void setOnlyAccessesArgMemory() {
+ CALLSITE_DELEGATE_SETTER(setOnlyAccessesArgMemory());
+ }
+
/// @brief Determine if the call cannot return.
bool doesNotReturn() const {
CALLSITE_DELEGATE_GETTER(doesNotReturn());
CALLSITE_DELEGATE_SETTER(setDoesNotThrow());
}
+ unsigned getNumOperandBundles() const {
+ CALLSITE_DELEGATE_GETTER(getNumOperandBundles());
+ }
+
+ bool hasOperandBundles() const {
+ CALLSITE_DELEGATE_GETTER(hasOperandBundles());
+ }
+
+ unsigned getBundleOperandsStartIndex() const {
+ CALLSITE_DELEGATE_GETTER(getBundleOperandsStartIndex());
+ }
+
+ unsigned getBundleOperandsEndIndex() const {
+ CALLSITE_DELEGATE_GETTER(getBundleOperandsEndIndex());
+ }
+
+ unsigned getNumTotalBundleOperands() const {
+ CALLSITE_DELEGATE_GETTER(getNumTotalBundleOperands());
+ }
+
+ OperandBundleUse getOperandBundleAt(unsigned Index) const {
+ CALLSITE_DELEGATE_GETTER(getOperandBundleAt(Index));
+ }
+
+ Optional<OperandBundleUse> getOperandBundle(StringRef Name) const {
+ CALLSITE_DELEGATE_GETTER(getOperandBundle(Name));
+ }
+
+ Optional<OperandBundleUse> getOperandBundle(uint32_t ID) const {
+ CALLSITE_DELEGATE_GETTER(getOperandBundle(ID));
+ }
+
+ IterTy arg_begin() const {
+ CALLSITE_DELEGATE_GETTER(arg_begin());
+ }
+
+ IterTy arg_end() const {
+ CALLSITE_DELEGATE_GETTER(arg_end());
+ }
+
#undef CALLSITE_DELEGATE_GETTER
#undef CALLSITE_DELEGATE_SETTER
- /// @brief Determine whether this argument is not captured.
- bool doesNotCapture(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attribute::NoCapture);
+ void getOperandBundlesAsDefs(SmallVectorImpl<OperandBundleDef> &Defs) const {
+ const Instruction *II = getInstruction();
+ // Since this is actually a getter that "looks like" a setter, don't use the
+ // above macros to avoid confusion.
+ if (isCall())
+ cast<CallInst>(II)->getOperandBundlesAsDefs(Defs);
+ else
+ cast<InvokeInst>(II)->getOperandBundlesAsDefs(Defs);
+ }
+
+ /// @brief Determine whether this data operand is not captured.
+ bool doesNotCapture(unsigned OpNo) const {
+ return dataOperandHasImpliedAttr(OpNo + 1, Attribute::NoCapture);
}
/// @brief Determine whether this argument is passed by value.
return paramHasAttr(arg_size(), Attribute::InAlloca);
}
- bool doesNotAccessMemory(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attribute::ReadNone);
+ bool doesNotAccessMemory(unsigned OpNo) const {
+ return dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadNone);
+ }
+
+ bool onlyReadsMemory(unsigned OpNo) const {
+ return dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadOnly) ||
+ dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadNone);
}
- bool onlyReadsMemory(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attribute::ReadOnly) ||
- paramHasAttr(ArgNo + 1, Attribute::ReadNone);
+ /// @brief Return true if the return value is known to be not null.
+ /// This may be because it has the nonnull attribute, or because at least
+ /// one byte is dereferenceable and the pointer is in addrspace(0).
+ bool isReturnNonNull() const {
+ if (paramHasAttr(0, Attribute::NonNull))
+ return true;
+ else if (getDereferenceableBytes(0) > 0 &&
+ getType()->getPointerAddressSpace() == 0)
+ return true;
+
+ return false;
}
/// hasArgument - Returns true if this CallSite passes the given Value* as an
}
private:
- unsigned getArgumentEndOffset() const {
- if (isCall())
- return 1; // Skip Callee
- else
- return 3; // Skip BB, BB, Callee
- }
-
IterTy getCallee() const {
if (isCall()) // Skip Callee
return cast<CallInst>(getInstruction())->op_end() - 1;
}
};
-class CallSite : public CallSiteBase<Function, Value, User, Instruction,
- CallInst, InvokeInst, User::op_iterator> {
- typedef CallSiteBase<Function, Value, User, Instruction,
- CallInst, InvokeInst, User::op_iterator> Base;
+class CallSite : public CallSiteBase<Function, BasicBlock, Value, User, Use,
+ Instruction, CallInst, InvokeInst,
+ User::op_iterator> {
public:
CallSite() {}
- CallSite(Base B) : Base(B) {}
- CallSite(Value* V) : Base(V) {}
- CallSite(CallInst *CI) : Base(CI) {}
- CallSite(InvokeInst *II) : Base(II) {}
- CallSite(Instruction *II) : Base(II) {}
+ CallSite(CallSiteBase B) : CallSiteBase(B) {}
+ CallSite(CallInst *CI) : CallSiteBase(CI) {}
+ CallSite(InvokeInst *II) : CallSiteBase(II) {}
+ explicit CallSite(Instruction *II) : CallSiteBase(II) {}
+ explicit CallSite(Value *V) : CallSiteBase(V) {}
bool operator==(const CallSite &CS) const { return I == CS.I; }
bool operator!=(const CallSite &CS) const { return I != CS.I; }
/// ImmutableCallSite - establish a view to a call site for examination
class ImmutableCallSite : public CallSiteBase<> {
- typedef CallSiteBase<> Base;
public:
- ImmutableCallSite(const Value* V) : Base(V) {}
- ImmutableCallSite(const CallInst *CI) : Base(CI) {}
- ImmutableCallSite(const InvokeInst *II) : Base(II) {}
- ImmutableCallSite(const Instruction *II) : Base(II) {}
- ImmutableCallSite(CallSite CS) : Base(CS.getInstruction()) {}
+ ImmutableCallSite() {}
+ ImmutableCallSite(const CallInst *CI) : CallSiteBase(CI) {}
+ ImmutableCallSite(const InvokeInst *II) : CallSiteBase(II) {}
+ explicit ImmutableCallSite(const Instruction *II) : CallSiteBase(II) {}
+ explicit ImmutableCallSite(const Value *V) : CallSiteBase(V) {}
+ ImmutableCallSite(CallSite CS) : CallSiteBase(CS.getInstruction()) {}
};
} // End llvm namespace