X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FIR%2FCallSite.h;h=f7bfb47a5b4446edbd495b979f6350cf40a03df5;hp=dd3ebf228a0b4bfd206582262c1d344dadb7a3e3;hb=db61103ea811b2fc0443e6438da3067a19ba1793;hpb=a6abdebd6a1ddf26c963c6f19b50cc75e5b83f4a diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index dd3ebf228a0..f7bfb47a5b4 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -118,6 +118,43 @@ public: /// 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 { assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!"); return *(arg_begin() + ArgNo); @@ -139,8 +176,7 @@ public: /// it. unsigned getArgumentNo(const Use *U) const { assert(getInstruction() && "Not a call or invoke instruction!"); - assert(arg_begin() <= U && U < arg_end() - && "Argument # out of range!"); + assert(isArgOperand(U) && "Argument # out of range!"); return U - arg_begin(); } @@ -148,21 +184,27 @@ public: /// 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 { - assert(getInstruction() && "Not a call or invoke instruction!"); - // Skip non-arguments - return (*this)->op_begin(); - } - - 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()); } + /// 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; @@ -182,7 +224,7 @@ public: return (*this)->op_end() - (isCall() ? 1 : 3); } iterator_range data_ops() const { - return iterator_range(data_operands_begin(), data_operands_end()); + return make_range(data_operands_begin(), data_operands_end()); } bool data_operands_empty() const { return data_operands_end() == data_operands_begin(); @@ -268,6 +310,11 @@ public: CALLSITE_DELEGATE_GETTER(hasFnAttr(A)); } + /// \brief Return true if this function has the given attribute. + bool hasFnAttr(StringRef A) const { + CALLSITE_DELEGATE_GETTER(hasFnAttr(A)); + } + /// \brief Return true if the call or the callee has the given attribute. bool paramHasAttr(unsigned i, Attribute::AttrKind A) const { CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A)); @@ -363,7 +410,7 @@ public: CALLSITE_DELEGATE_SETTER(setDoesNotThrow()); } - int getNumOperandBundles() const { + unsigned getNumOperandBundles() const { CALLSITE_DELEGATE_GETTER(getNumOperandBundles()); } @@ -371,21 +418,51 @@ public: CALLSITE_DELEGATE_GETTER(hasOperandBundles()); } - int getNumTotalBundleOperands() const { + unsigned getBundleOperandsStartIndex() const { + CALLSITE_DELEGATE_GETTER(getBundleOperandsStartIndex()); + } + + unsigned getBundleOperandsEndIndex() const { + CALLSITE_DELEGATE_GETTER(getBundleOperandsEndIndex()); + } + + unsigned getNumTotalBundleOperands() const { CALLSITE_DELEGATE_GETTER(getNumTotalBundleOperands()); } - OperandBundleUse getOperandBundle(unsigned Index) const { - CALLSITE_DELEGATE_GETTER(getOperandBundle(Index)); + 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)); + } + + 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 + 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); @@ -446,18 +523,6 @@ public: } private: - unsigned getArgumentEndOffset() const { - 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 { if (isCall()) // Skip Callee return cast(getInstruction())->op_end() - 1;