diff options
author | Hal Finkel <hfinkel@anl.gov> | 2016-07-16 07:21:28 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2016-07-16 07:21:28 +0000 |
commit | 660096b26045e2be00d5a7eb8df15ae3d45cc5c5 (patch) | |
tree | 6d60dc9e537fa1ad5b24d7209a9d7b7104317734 /llvm/lib/Transforms/IPO/FunctionAttrs.cpp | |
parent | 04b5330ccdf93e3d051c7abe67303dd2dc973303 (diff) | |
download | llvm-660096b26045e2be00d5a7eb8df15ae3d45cc5c5.zip llvm-660096b26045e2be00d5a7eb8df15ae3d45cc5c5.tar.gz llvm-660096b26045e2be00d5a7eb8df15ae3d45cc5c5.tar.bz2 |
Revert "Revert r275027 - Let FuncAttrs infer the 'returned' argument attribute"
This reverts commit r275042; the initial commit triggered self-hosting failures
on ARM/AArch64. James Molloy identified the problematic backend code, which has
been disabled in r275677. Trying again...
Original commit message:
Let FuncAttrs infer the 'returned' argument attribute
A function can have one argument with the 'returned' attribute, indicating that
the associated argument is always the return value of the function. Add
FuncAttrs inference logic.
llvm-svn: 275678
Diffstat (limited to 'llvm/lib/Transforms/IPO/FunctionAttrs.cpp')
-rw-r--r-- | llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index fff5440..9c9e482 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -42,6 +42,7 @@ using namespace llvm; STATISTIC(NumReadNone, "Number of functions marked readnone"); STATISTIC(NumReadOnly, "Number of functions marked readonly"); STATISTIC(NumNoCapture, "Number of arguments marked nocapture"); +STATISTIC(NumReturned, "Number of arguments marked returned"); STATISTIC(NumReadNoneArg, "Number of arguments marked readnone"); STATISTIC(NumReadOnlyArg, "Number of arguments marked readonly"); STATISTIC(NumNoAlias, "Number of function returns marked noalias"); @@ -483,6 +484,53 @@ determinePointerReadAttrs(Argument *A, return IsRead ? Attribute::ReadOnly : Attribute::ReadNone; } +/// Deduce returned attributes for the SCC. +static bool addArgumentReturnedAttrs(const SCCNodeSet &SCCNodes) { + bool Changed = false; + + AttrBuilder B; + B.addAttribute(Attribute::Returned); + + // Check each function in turn, determining if an argument is always returned. + for (Function *F : SCCNodes) { + // We can infer and propagate function attributes only when we know that the + // definition we'll get at link time is *exactly* the definition we see now. + // For more details, see GlobalValue::mayBeDerefined. + if (!F->hasExactDefinition()) + continue; + + if (F->getReturnType()->isVoidTy()) + continue; + + auto FindRetArg = [&]() -> Value * { + Value *RetArg = nullptr; + for (BasicBlock &BB : *F) + if (auto *Ret = dyn_cast<ReturnInst>(BB.getTerminator())) { + // Note that stripPointerCasts should look through functions with + // returned arguments. + Value *RetVal = Ret->getReturnValue()->stripPointerCasts(); + if (RetVal->getType() == F->getReturnType() && isa<Argument>(RetVal)) { + if (!RetArg) + RetArg = RetVal; + else if (RetArg != RetVal) + return nullptr; + } + } + + return RetArg; + }; + + if (Value *RetArg = FindRetArg()) { + auto *A = cast<Argument>(RetArg); + A->addAttr(AttributeSet::get(F->getContext(), A->getArgNo() + 1, B)); + ++NumReturned; + Changed = true; + } + } + + return Changed; +} + /// Deduce nocapture attributes for the SCC. static bool addArgumentAttrs(const SCCNodeSet &SCCNodes) { bool Changed = false; @@ -1024,6 +1072,7 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C, } bool Changed = false; + Changed |= addArgumentReturnedAttrs(SCCNodes); Changed |= addReadAttrs(SCCNodes, AARGetter); Changed |= addArgumentAttrs(SCCNodes); @@ -1089,6 +1138,7 @@ static bool runImpl(CallGraphSCC &SCC, AARGetterT AARGetter) { SCCNodes.insert(F); } + Changed |= addArgumentReturnedAttrs(SCCNodes); Changed |= addReadAttrs(SCCNodes, AARGetter); Changed |= addArgumentAttrs(SCCNodes); |