[attrs] Consolidate the test for a non-SCC, non-convergent function call

with the test for a non-convergent intrinsic call.

While it is possible to use the call records to search for function
calls, we're going to do an instruction scan anyways to find the
intrinsics, we can handle both cases while scanning instructions. This
will also make the logic more amenable to the new pass manager which
doesn't use the same call graph structure.

My next patch will remove use of CallGraphNode entirely and allow this
code to work with both the old and new pass manager. Fortunately, it
should also get strictly simpler without changing functionality.

llvm-svn: 260666
This commit is contained in:
Chandler Carruth 2016-02-12 09:23:53 +00:00
parent 79355776e3
commit 057df3d423
1 changed files with 14 additions and 20 deletions

View File

@ -959,27 +959,21 @@ static bool removeConvergentAttrs(const CallGraphSCC &SCC,
if (F->hasFnAttribute(Attribute::OptimizeNone))
return false;
// Can't remove convergent if any of F's callees -- ignoring functions in
// the SCC itself -- are convergent.
if (llvm::any_of(*CGN, [&](const CallGraphNode::CallRecord &CR) {
Function *F = CR.second->getFunction();
return SCCNodes.count(F) == 0 && (!F || F->isConvergent());
}))
return false;
for (Instruction &I : instructions(*F))
if (auto CS = CallSite(&I)) {
// Can't remove convergent if any of F's callees -- ignoring functions
// in the SCC itself -- are convergent. This needs to consider both
// function calls and intrinsic calls. We also assume indirect calls
// might call a convergent function.
// FIXME: We should revisit this when we put convergent onto calls
// instead of functions so that indirect calls which should be
// convergent are required to be marked as such.
Function *Callee = CS.getCalledFunction();
if (!Callee || (SCCNodes.count(Callee) == 0 && Callee->isConvergent()))
return false;
}
// CGN doesn't contain calls to intrinsics, so iterate over all of F's
// callsites, looking for any calls to convergent intrinsics. If we find
// one, F must remain marked as convergent.
auto IsConvergentIntrinsicCall = [](Instruction &I) {
CallSite CS(cast<Value>(&I));
if (!CS)
return false;
Function *Callee = CS.getCalledFunction();
return Callee && Callee->isIntrinsic() && Callee->isConvergent();
};
return !llvm::any_of(*F, [=](BasicBlock &BB) {
return llvm::any_of(BB, IsConvergentIntrinsicCall);
});
return true;
};
// We can remove the convergent attr from functions in the SCC if they all