X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=include%2Fllvm%2FSupport%2FCallSite.h;h=d2c47b53ed3efa8e0da6b8f8695d20e3e7118909;hb=b0dcfa5c1f78305b125f4b710f467c16c9948354;hp=9f527e2df6cf9874c8dca34d324619d2a96358e4;hpb=c8b82ccbcf3b2e2384d2c0b5176e7b0b40b7f82f;p=oota-llvm.git diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h index 9f527e2df6c..d2c47b53ed3 100644 --- a/include/llvm/Support/CallSite.h +++ b/include/llvm/Support/CallSite.h @@ -26,11 +26,10 @@ #ifndef LLVM_SUPPORT_CALLSITE_H #define LLVM_SUPPORT_CALLSITE_H -#include "llvm/Attributes.h" #include "llvm/ADT/PointerIntPair.h" -#include "llvm/BasicBlock.h" -#include "llvm/CallingConv.h" -#include "llvm/Instruction.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/Instructions.h" namespace llvm { @@ -49,15 +48,10 @@ protected: PointerIntPair I; public: CallSiteBase() : I(0, false) {} - CallSiteBase(CallTy *CI) : I(reinterpret_cast(CI), true) {} - CallSiteBase(InvokeTy *II) : I(reinterpret_cast(II), false) {} + CallSiteBase(CallTy *CI) : I(CI, true) { assert(CI); } + CallSiteBase(InvokeTy *II) : I(II, false) { assert(II); } CallSiteBase(ValTy *II) { *this = get(II); } - CallSiteBase(InstrTy *II) { - assert(II && "Null instruction given?"); - *this = get(II); - assert(I.getPointer()); - } - +protected: /// 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 @@ -66,13 +60,13 @@ public: static CallSiteBase get(ValTy *V) { if (InstrTy *II = dyn_cast(V)) { if (II->getOpcode() == Instruction::Call) - return CallSiteBase(reinterpret_cast(II)); + return CallSiteBase(static_cast(II)); else if (II->getOpcode() == Instruction::Invoke) - return CallSiteBase(reinterpret_cast(II)); + return CallSiteBase(static_cast(II)); } return CallSiteBase(); } - +public: /// isCall - true if a CallInst is enclosed. /// Note that !isCall() does not mean it is an InvokeInst enclosed, /// it also could signify a NULL Instruction pointer. @@ -84,9 +78,9 @@ public: InstrTy *getInstruction() const { return I.getPointer(); } InstrTy *operator->() const { return I.getPointer(); } - operator bool() const { return I.getPointer(); } + LLVM_EXPLICIT operator bool() const { return I.getPointer(); } - /// getCalledValue - Return the pointer to function that is being called... + /// getCalledValue - Return the pointer to function that is being called. /// ValTy *getCalledValue() const { assert(getInstruction() && "Not a call or invoke instruction!"); @@ -100,7 +94,7 @@ public: return dyn_cast(getCalledValue()); } - /// setCalledFunction - Set the callee to the specified value... + /// setCalledFunction - Set the callee to the specified value. /// void setCalledFunction(Value *V) { assert(getInstruction() && "Not a call or invoke instruction!"); @@ -116,13 +110,13 @@ public: ValTy *getArgument(unsigned ArgNo) const { assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!"); - return *(arg_begin()+ArgNo); + return *(arg_begin() + ArgNo); } void setArgument(unsigned ArgNo, Value* newVal) { assert(getInstruction() && "Not a call or invoke instruction!"); assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!"); - getInstruction()->setOperand(getArgumentOffset() + ArgNo, newVal); + getInstruction()->setOperand(ArgNo, newVal); } /// Given a value use iterator, returns the argument that corresponds to it. @@ -135,7 +129,7 @@ public: } /// arg_iterator - The type of iterator to use when looping over actual - /// arguments at this call site... + /// arguments at this call site. typedef IterTy arg_iterator; /// arg_begin/arg_end - Return iterators corresponding to the actual argument @@ -143,121 +137,191 @@ public: IterTy arg_begin() const { assert(getInstruction() && "Not a call or invoke instruction!"); // Skip non-arguments - return (*this)->op_begin() + getArgumentOffset(); + return (*this)->op_begin(); } 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()); } -private: - /// Returns the operand number of the first argument - unsigned getArgumentOffset() const { - if (isCall()) - return 1; // Skip Function (ATM) - else - return 0; // Args are at the front - } - - unsigned getArgumentEndOffset() const { - if (isCall()) - return 0; // Unchanged (ATM) - else - return 3; // Skip BB, BB, Function - } - - IterTy getCallee() const { - // FIXME: this is slow, since we do not have the fast versions - // of the op_*() functions here. See CallSite::getCallee. - // - if (isCall()) - return getInstruction()->op_begin(); // Unchanged (ATM) - else - return getInstruction()->op_end() - 3; // Skip BB, BB, Function - } -}; - -/// 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) {} -}; + /// getType - Return the type of the instruction that generated this call site + /// + Type *getType() const { return (*this)->getType(); } -class CallSite : public CallSiteBase { - typedef CallSiteBase _Base; -public: - CallSite() {} - CallSite(_Base B) : _Base(B) {} - CallSite(CallInst *CI) : _Base(CI) {} - CallSite(InvokeInst *II) : _Base(II) {} - CallSite(Instruction *II) : _Base(II) {} + /// getCaller - Return the caller function for this call site + /// + FunTy *getCaller() const { return (*this)->getParent()->getParent(); } - bool operator==(const CallSite &CS) const { return I == CS.I; } - bool operator!=(const CallSite &CS) const { return I != CS.I; } +#define CALLSITE_DELEGATE_GETTER(METHOD) \ + InstrTy *II = getInstruction(); \ + return isCall() \ + ? cast(II)->METHOD \ + : cast(II)->METHOD - /// CallSite::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 CallSite object for something which is - /// NOT a call site. - /// - static CallSite get(Value *V) { - return _Base::get(V); - } +#define CALLSITE_DELEGATE_SETTER(METHOD) \ + InstrTy *II = getInstruction(); \ + if (isCall()) \ + cast(II)->METHOD; \ + else \ + cast(II)->METHOD /// getCallingConv/setCallingConv - get or set the calling convention of the /// call. - CallingConv::ID getCallingConv() const; - void setCallingConv(CallingConv::ID CC); + CallingConv::ID getCallingConv() const { + CALLSITE_DELEGATE_GETTER(getCallingConv()); + } + void setCallingConv(CallingConv::ID CC) { + CALLSITE_DELEGATE_SETTER(setCallingConv(CC)); + } /// getAttributes/setAttributes - get or set the parameter attributes of /// the call. - const AttrListPtr &getAttributes() const; - void setAttributes(const AttrListPtr &PAL); + const AttributeSet &getAttributes() const { + CALLSITE_DELEGATE_GETTER(getAttributes()); + } + void setAttributes(const AttributeSet &PAL) { + CALLSITE_DELEGATE_SETTER(setAttributes(PAL)); + } - /// paramHasAttr - whether the call or the callee has the given attribute. - bool paramHasAttr(uint16_t i, Attributes attr) const; + /// \brief Return true if this function has the given attribute. + bool hasFnAttr(Attribute::AttrKind 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)); + } /// @brief Extract the alignment for a call or parameter (0=unknown). - uint16_t getParamAlignment(uint16_t i) const; + uint16_t getParamAlignment(uint16_t i) const { + CALLSITE_DELEGATE_GETTER(getParamAlignment(i)); + } + + /// \brief Return true if the call should not be treated as a call to a + /// builtin. + bool isNoBuiltin() const { + CALLSITE_DELEGATE_GETTER(isNoBuiltin()); + } /// @brief Return true if the call should not be inlined. - bool isNoInline() const; - void setIsNoInline(bool Value = true); - + bool isNoInline() const { + CALLSITE_DELEGATE_GETTER(isNoInline()); + } + void setIsNoInline(bool Value = true) { + CALLSITE_DELEGATE_SETTER(setIsNoInline(Value)); + } + /// @brief Determine if the call does not access memory. - bool doesNotAccessMemory() const; - void setDoesNotAccessMemory(bool doesNotAccessMemory = true); + bool doesNotAccessMemory() const { + CALLSITE_DELEGATE_GETTER(doesNotAccessMemory()); + } + void setDoesNotAccessMemory() { + CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory()); + } /// @brief Determine if the call does not access or only reads memory. - bool onlyReadsMemory() const; - void setOnlyReadsMemory(bool onlyReadsMemory = true); + bool onlyReadsMemory() const { + CALLSITE_DELEGATE_GETTER(onlyReadsMemory()); + } + void setOnlyReadsMemory() { + CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory()); + } /// @brief Determine if the call cannot return. - bool doesNotReturn() const; - void setDoesNotReturn(bool doesNotReturn = true); + bool doesNotReturn() const { + CALLSITE_DELEGATE_GETTER(doesNotReturn()); + } + void setDoesNotReturn() { + CALLSITE_DELEGATE_SETTER(setDoesNotReturn()); + } /// @brief Determine if the call cannot unwind. - bool doesNotThrow() const; - void setDoesNotThrow(bool doesNotThrow = true); + bool doesNotThrow() const { + CALLSITE_DELEGATE_GETTER(doesNotThrow()); + } + void setDoesNotThrow() { + CALLSITE_DELEGATE_SETTER(setDoesNotThrow()); + } - /// getType - Return the type of the instruction that generated this call site - /// - const Type *getType() const { return (*this)->getType(); } +#undef CALLSITE_DELEGATE_GETTER +#undef CALLSITE_DELEGATE_SETTER - /// getCaller - Return the caller function for this call site - /// - Function *getCaller() const { return (*this)->getParent()->getParent(); } + /// @brief Determine whether this argument is not captured. + bool doesNotCapture(unsigned ArgNo) const { + return paramHasAttr(ArgNo + 1, Attribute::NoCapture); + } + + /// @brief Determine whether this argument is passed by value. + bool isByValArgument(unsigned ArgNo) const { + return paramHasAttr(ArgNo + 1, Attribute::ByVal); + } + + /// @brief Determine whether this argument is passed in an alloca. + bool isInAllocaArgument(unsigned ArgNo) const { + return paramHasAttr(ArgNo + 1, Attribute::InAlloca); + } + + /// @brief Determine whether this argument is passed by value or in an alloca. + bool isByValOrInAllocaArgument(unsigned ArgNo) const { + return paramHasAttr(ArgNo + 1, Attribute::ByVal) || + paramHasAttr(ArgNo + 1, Attribute::InAlloca); + } + + /// @brief Determine if there are any inalloca arguments. + bool hasInAllocaArgument() const { + return getAttributes().hasAttrSomewhere(Attribute::InAlloca); + } + + bool doesNotAccessMemory(unsigned ArgNo) const { + return paramHasAttr(ArgNo + 1, Attribute::ReadNone); + } + + bool onlyReadsMemory(unsigned ArgNo) const { + return paramHasAttr(ArgNo + 1, Attribute::ReadOnly) || + paramHasAttr(ArgNo + 1, Attribute::ReadNone); + } /// hasArgument - Returns true if this CallSite passes the given Value* as an /// argument to the called function. - bool hasArgument(const Value *Arg) const; + bool hasArgument(const Value *Arg) const { + for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E; + ++AI) + if (AI->get() == Arg) + return true; + return false; + } +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(getInstruction())->op_end() - 1; + else // Skip BB, BB, Callee + return cast(getInstruction())->op_end() - 3; + } +}; + +class CallSite : public CallSiteBase { + typedef CallSiteBase Base; +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) {} + + bool operator==(const CallSite &CS) const { return I == CS.I; } + bool operator!=(const CallSite &CS) const { return I != CS.I; } bool operator<(const CallSite &CS) const { return getInstruction() < CS.getInstruction(); } @@ -266,6 +330,17 @@ private: User::op_iterator getCallee() const; }; +/// 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()) {} +}; + } // End llvm namespace #endif