X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=include%2Fllvm%2FIR%2FCallSite.h;h=8556dda163b8b324833a1c195d1de41edb67a800;hb=e6bc7d1f0d765d1e67a1c5d6c7a4f36677810c8e;hp=1da025f802f34504f3244cb64fe22ddd657dc1b5;hpb=cd52a7a381a73c53ec4ef517ad87f19808cb1a28;p=oota-llvm.git diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index 1da025f802f..8556dda163b 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -38,8 +38,10 @@ class CallInst; class InvokeInst; template () 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. /// ValTy *getCalledValue() const { @@ -152,11 +158,39 @@ public: IterTy arg_end() const { return (*this)->op_end() - getArgumentEndOffset(); } iterator_range args() const { - return iterator_range(arg_begin(), arg_end()); + 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()); } + /// 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!"); + 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 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()); + } + /// getType - Return the type of the instruction that generated this call site /// Type *getType() const { return (*this)->getType(); } @@ -189,6 +223,20 @@ public: else \ cast(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(getInstruction())->isInlineAsm(); + return false; + } + /// getCallingConv/setCallingConv - get or set the calling convention of the /// call. CallingConv::ID getCallingConv() const { @@ -225,6 +273,17 @@ public: 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)); @@ -235,13 +294,20 @@ public: 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 { @@ -272,6 +338,15 @@ public: 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()); @@ -288,12 +363,46 @@ public: CALLSITE_DELEGATE_SETTER(setDoesNotThrow()); } + int getNumOperandBundles() const { + CALLSITE_DELEGATE_GETTER(getNumOperandBundles()); + } + + bool hasOperandBundles() const { + CALLSITE_DELEGATE_GETTER(hasOperandBundles()); + } + + int getNumTotalBundleOperands() const { + CALLSITE_DELEGATE_GETTER(getNumTotalBundleOperands()); + } + + OperandBundleUse getOperandBundleAt(unsigned Index) const { + CALLSITE_DELEGATE_GETTER(getOperandBundleAt(Index)); + } + + Optional getOperandBundle(StringRef Name) const { + CALLSITE_DELEGATE_GETTER(getOperandBundle(Name)); + } + + Optional getOperandBundle(uint32_t ID) const { + CALLSITE_DELEGATE_GETTER(getOperandBundle(ID)); + } + #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 &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(II)->getOperandBundlesAsDefs(Defs); + else + cast(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. @@ -318,13 +427,13 @@ public: 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 ArgNo) const { - return paramHasAttr(ArgNo + 1, Attribute::ReadOnly) || - paramHasAttr(ArgNo + 1, Attribute::ReadNone); + bool onlyReadsMemory(unsigned OpNo) const { + return dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadOnly) || + dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadNone); } /// @brief Return true if the return value is known to be not null. @@ -352,10 +461,15 @@ public: private: unsigned getArgumentEndOffset() const { - if (isCall()) - return 1; // Skip Callee - else - return 3; // Skip BB, BB, Callee + if (isCall()) { + // Skip [ operand bundles ], Callee + auto *CI = cast(getInstruction()); + return 1 + CI->getNumTotalBundleOperands(); + } else { + // Skip [ operand bundles ], BB, BB, Callee + auto *II = cast(getInstruction()); + return 3 + II->getNumTotalBundleOperands(); + } } IterTy getCallee() const { @@ -366,8 +480,9 @@ private: } }; -class CallSite : public CallSiteBase { +class CallSite : public CallSiteBase { public: CallSite() {} CallSite(CallSiteBase B) : CallSiteBase(B) {}