summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/IR/Attributes.h6
-rw-r--r--llvm/include/llvm/IR/CallSite.h4
-rw-r--r--llvm/include/llvm/IR/Instructions.h8
-rw-r--r--llvm/lib/IR/Attributes.cpp7
-rw-r--r--llvm/lib/IR/Instructions.cpp26
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!");
OpenPOWER on IntegriCloud