diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/IR/Attributes.h | 6 | ||||
-rw-r--r-- | llvm/include/llvm/IR/CallSite.h | 4 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Instructions.h | 8 | ||||
-rw-r--r-- | llvm/lib/IR/Attributes.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/IR/Instructions.cpp | 26 |
5 files changed, 47 insertions, 4 deletions
diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h index 52d1a46602a..af1bf0a354e 100644 --- a/llvm/include/llvm/IR/Attributes.h +++ b/llvm/include/llvm/IR/Attributes.h @@ -338,8 +338,10 @@ public: bool hasFnAttribute(Attribute::AttrKind Kind) const; /// \brief Return true if the specified attribute is set for at least one - /// parameter or for the return value. - bool hasAttrSomewhere(Attribute::AttrKind Kind) const; + /// parameter or for the return value. If Index is not nullptr, the index + /// of a parameter with the specified attribute is provided. + bool hasAttrSomewhere(Attribute::AttrKind Kind, + unsigned *Index = nullptr) const; /// \brief Return the attribute object that exists at the given index. Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const; diff --git a/llvm/include/llvm/IR/CallSite.h b/llvm/include/llvm/IR/CallSite.h index 3229d86651a..9c977aef941 100644 --- a/llvm/include/llvm/IR/CallSite.h +++ b/llvm/include/llvm/IR/CallSite.h @@ -273,6 +273,10 @@ public: CALLSITE_DELEGATE_GETTER(getArgOperand(i)); } + ValTy *getReturnedArgOperand() const { + CALLSITE_DELEGATE_GETTER(getReturnedArgOperand()); + } + bool isInlineAsm() const { if (isCall()) return cast<CallInst>(getInstruction())->isInlineAsm(); diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h index 15623ab0a71..be077725f7b 100644 --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -1597,6 +1597,10 @@ public: return getOperandUse(i); } + /// If one of the arguments has the 'returned' attribute, return its + /// operand value. Otherwise, return nullptr. + Value *getReturnedArgOperand() const; + /// getCallingConv/setCallingConv - Get or set the calling convention of this /// function call. CallingConv::ID getCallingConv() const { @@ -3566,6 +3570,10 @@ public: return getOperandUse(i); } + /// If one of the arguments has the 'returned' attribute, return its + /// operand value. Otherwise, return nullptr. + Value *getReturnedArgOperand() const; + /// getCallingConv/setCallingConv - Get or set the calling convention of this /// function call. CallingConv::ID getCallingConv() const { diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index b0a4cb6be55..d774c1ae9df 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -1108,14 +1108,17 @@ bool AttributeSet::hasFnAttribute(Attribute::AttrKind Kind) const { return pImpl && pImpl->hasFnAttribute(Kind); } -bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr) const { +bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr, + unsigned *Index) const { if (!pImpl) return false; for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) for (AttributeSetImpl::iterator II = pImpl->begin(I), IE = pImpl->end(I); II != IE; ++II) - if (II->hasAttribute(Attr)) + if (II->hasAttribute(Attr)) { + if (Index) *Index = pImpl->getSlotIndex(I); return true; + } return false; } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 6f60d15c52c..b9c693ff19a 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -331,6 +331,19 @@ CallInst *CallInst::Create(CallInst *CI, ArrayRef<OperandBundleDef> OpB, return NewCI; } +Value *CallInst::getReturnedArgOperand() const { + unsigned Index; + + if (AttributeList.hasAttrSomewhere(Attribute::Returned, &Index) && Index) + return getArgOperand(Index-1); + if (const Function *F = getCalledFunction()) + if (F->getAttributes().hasAttrSomewhere(Attribute::Returned, &Index) && + Index) + return getArgOperand(Index-1); + + return nullptr; +} + void CallInst::addAttribute(unsigned i, Attribute::AttrKind Kind) { AttributeSet PAL = getAttributes(); PAL = PAL.addAttribute(getContext(), i, Kind); @@ -688,6 +701,19 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) { return setSuccessor(idx, B); } +Value *InvokeInst::getReturnedArgOperand() const { + unsigned Index; + + if (AttributeList.hasAttrSomewhere(Attribute::Returned, &Index) && Index) + return getArgOperand(Index-1); + if (const Function *F = getCalledFunction()) + if (F->getAttributes().hasAttrSomewhere(Attribute::Returned, &Index) && + Index) + return getArgOperand(Index-1); + + return nullptr; +} + bool InvokeInst::paramHasAttr(unsigned i, Attribute::AttrKind Kind) const { assert(i < (getNumArgOperands() + 1) && "Param index out of bounds!"); |