summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/CGSCCPassManager.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2017-07-15 08:08:19 +0000
committerChandler Carruth <chandlerc@gmail.com>2017-07-15 08:08:19 +0000
commitf59a838720b53930be3ba59ba9f8a075cbc1b413 (patch)
tree46961a20992518c8d1ec4f9fe99c8cfa9a79e798 /llvm/lib/Analysis/CGSCCPassManager.cpp
parentf217c7b7e20ed00ff6595b93177a08733982f84c (diff)
downloadbcm5719-llvm-f59a838720b53930be3ba59ba9f8a075cbc1b413.tar.gz
bcm5719-llvm-f59a838720b53930be3ba59ba9f8a075cbc1b413.zip
[PM/LCG] Teach the LazyCallGraph to maintain reference edges from every
function to every defined function known to LLVM as a library function. LLVM can introduce calls to these functions either by replacing other library calls or by recognizing patterns (such as memset_pattern or vector math patterns) and replacing those with calls. When these library functions are actually defined in the module, we need to have reference edges to them initially so that we visit them during the CGSCC walk in the right order and can effectively rebuild the call graph afterward. This was discovered when building code with Fortify enabled as that is a common case of both inline definitions of library calls and simplifications of code into calling them. This can in extreme cases of LTO-ing with libc introduce *many* more reference edges. I discussed a bunch of different options with folks but all of them are unsatisfying. They either make the graph operations substantially more complex even when there are *no* defined libfuncs, or they introduce some other complexity into the callgraph. So this patch goes with the simplest possible solution of actual synthetic reference edges. If this proves to be a memory problem, I'm happy to implement one of the clever techniques to save memory here. llvm-svn: 308088
Diffstat (limited to 'llvm/lib/Analysis/CGSCCPassManager.cpp')
-rw-r--r--llvm/lib/Analysis/CGSCCPassManager.cpp9
1 files changed, 7 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/CGSCCPassManager.cpp b/llvm/lib/Analysis/CGSCCPassManager.cpp
index 3ddefc6520a..74b5d79ebac 100644
--- a/llvm/lib/Analysis/CGSCCPassManager.cpp
+++ b/llvm/lib/Analysis/CGSCCPassManager.cpp
@@ -433,7 +433,7 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass(
if (Visited.insert(C).second)
Worklist.push_back(C);
- LazyCallGraph::visitReferences(Worklist, Visited, [&](Function &Referee) {
+ auto VisitRef = [&](Function &Referee) {
Node &RefereeN = *G.lookup(Referee);
Edge *E = N->lookup(RefereeN);
// FIXME: Similarly to new calls, we also currently preclude
@@ -444,7 +444,12 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass(
RetainedEdges.insert(&RefereeN);
if (E->isCall())
DemotedCallTargets.insert(&RefereeN);
- });
+ };
+ LazyCallGraph::visitReferences(Worklist, Visited, VisitRef);
+
+ // Include synthetic reference edges to known, defined lib functions.
+ for (auto *F : G.getLibFunctions())
+ VisitRef(*F);
// First remove all of the edges that are no longer present in this function.
// We have to build a list of dead targets first and then remove them as the
OpenPOWER on IntegriCloud