diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2017-09-14 08:33:57 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2017-09-14 08:33:57 +0000 |
commit | 7376ae88eb452423be3ced3f8e288da1aefd604b (patch) | |
tree | 7ab8321a76daa9c110b6d9302fb331bf30fff7f7 /llvm/lib/Analysis/CGSCCPassManager.cpp | |
parent | 561f5408c950361700a1c19fa1a97a79c394d8d6 (diff) | |
download | bcm5719-llvm-7376ae88eb452423be3ced3f8e288da1aefd604b.tar.gz bcm5719-llvm-7376ae88eb452423be3ced3f8e288da1aefd604b.zip |
[PM/CGSCC] Teach the CGSCC pass manager components to gracefully handle
invalidated SCCs even when we do not have an updated SCC to redirect
towards.
This comes up in a fairly subtle and surprising circumstance: we need to
have a connected but internal node in the call graph which later becomes
a disconnected island, and then gets deleted. All of this needs to
happen mid-CGSCC walk. Because it is disconnected, we have no way of
computing a new "current" SCC when it gets deleted. Instead, we need to
explicitly check for a deleted "current" SCC and bail out of the current
CGSCC step. This will bubble all the way up to the post-order walk and
then resume correctly.
I've included minimal tests for this bug. The specific behavior
matches something we've seen in the wild with the new PM combined with
ThinLTO and sample PGO, but I've not yet confirmed whether this is the
only issue there.
llvm-svn: 313242
Diffstat (limited to 'llvm/lib/Analysis/CGSCCPassManager.cpp')
-rw-r--r-- | llvm/lib/Analysis/CGSCCPassManager.cpp | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/CGSCCPassManager.cpp b/llvm/lib/Analysis/CGSCCPassManager.cpp index 9e6384437fb..cd115c97ef6 100644 --- a/llvm/lib/Analysis/CGSCCPassManager.cpp +++ b/llvm/lib/Analysis/CGSCCPassManager.cpp @@ -72,8 +72,13 @@ PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, // Update the SCC if necessary. C = UR.UpdatedC ? UR.UpdatedC : C; + // If the CGSCC pass wasn't able to provide a valid updated SCC, the + // current SCC may simply need to be skipped if invalid. + if (UR.InvalidatedSCCs.count(C)) { + DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n"); + break; + } // Check that we didn't miss any update scenario. - assert(!UR.InvalidatedSCCs.count(C) && "Processing an invalid SCC!"); assert(C->begin() != C->end() && "Cannot have an empty SCC!"); // Update the analysis manager as each pass runs and potentially |