diff options
author | Hal Finkel <hfinkel@anl.gov> | 2016-07-10 23:01:32 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2016-07-10 23:01:32 +0000 |
commit | e87ad547efec70e15a727d3e8d3d7df6e14e5c99 (patch) | |
tree | f04aead430f92dd9ff679d3393bf4d8433eccf3a /llvm/lib/IR | |
parent | d7e03a5bd9f8b109dc7b88024b443b87e4d96354 (diff) | |
download | bcm5719-llvm-e87ad547efec70e15a727d3e8d3d7df6e14e5c99.tar.gz bcm5719-llvm-e87ad547efec70e15a727d3e8d3d7df6e14e5c99.zip |
Add getReturnedArgOperand to Call/InvokeInst, CallSite
In order to make the optimizer smarter about using the 'returned' argument
attribute (generally, but motivated by my llvm.noalias intrinsic work), add a
utility function to Call/InvokeInst, and CallSite, to make it easy to get the
returned call argument (when one exists).
P.S. There is already an unfortunate amount of code duplication between
CallInst and InvokeInst, and this adds to it. We should probably clean that up
separately.
Differential Revision: http://reviews.llvm.org/D22204
llvm-svn: 275031
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r-- | llvm/lib/IR/Attributes.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/IR/Instructions.cpp | 26 |
2 files changed, 31 insertions, 2 deletions
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!"); |