diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 | 
| commit | 145449b1e420787bb99721a429341fa6be3adfb6 (patch) | |
| tree | 1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/Analysis/CGSCCPassManager.cpp | |
| parent | ecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff) | |
Diffstat (limited to 'llvm/lib/Analysis/CGSCCPassManager.cpp')
| -rw-r--r-- | llvm/lib/Analysis/CGSCCPassManager.cpp | 39 | 
1 files changed, 18 insertions, 21 deletions
| diff --git a/llvm/lib/Analysis/CGSCCPassManager.cpp b/llvm/lib/Analysis/CGSCCPassManager.cpp index c60b70ae5b69..b2e7422bbf8b 100644 --- a/llvm/lib/Analysis/CGSCCPassManager.cpp +++ b/llvm/lib/Analysis/CGSCCPassManager.cpp @@ -9,6 +9,7 @@  #include "llvm/Analysis/CGSCCPassManager.h"  #include "llvm/ADT/ArrayRef.h"  #include "llvm/ADT/Optional.h" +#include "llvm/ADT/PriorityWorklist.h"  #include "llvm/ADT/STLExtras.h"  #include "llvm/ADT/SetVector.h"  #include "llvm/ADT/SmallPtrSet.h" @@ -27,7 +28,6 @@  #include "llvm/Support/ErrorHandling.h"  #include "llvm/Support/TimeProfiler.h"  #include "llvm/Support/raw_ostream.h" -#include <algorithm>  #include <cassert>  #include <iterator> @@ -164,9 +164,9 @@ ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {        InlinedInternalEdges;    CGSCCUpdateResult UR = { -      RCWorklist, CWorklist, InvalidRefSCCSet,         InvalidSCCSet, -      nullptr,    nullptr,   PreservedAnalyses::all(), InlinedInternalEdges, -      {}}; +      RCWorklist,           CWorklist, InvalidRefSCCSet, +      InvalidSCCSet,        nullptr,   PreservedAnalyses::all(), +      InlinedInternalEdges, {}};    // Request PassInstrumentation from analysis manager, will use it to run    // instrumenting callbacks for the passes later. @@ -174,9 +174,8 @@ ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {    PreservedAnalyses PA = PreservedAnalyses::all();    CG.buildRefSCCs(); -  for (auto RCI = CG.postorder_ref_scc_begin(), -            RCE = CG.postorder_ref_scc_end(); -       RCI != RCE;) { +  for (LazyCallGraph::RefSCC &RC : +       llvm::make_early_inc_range(CG.postorder_ref_sccs())) {      assert(RCWorklist.empty() &&             "Should always start with an empty RefSCC worklist");      // The postorder_ref_sccs range we are walking is lazily constructed, so @@ -190,7 +189,7 @@ ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {      //      // We also eagerly increment the iterator to the next position because      // the CGSCC passes below may delete the current RefSCC. -    RCWorklist.insert(&*RCI++); +    RCWorklist.insert(&RC);      do {        LazyCallGraph::RefSCC *RC = RCWorklist.pop_back_val(); @@ -230,11 +229,15 @@ ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {            LLVM_DEBUG(dbgs() << "Skipping redundant run on SCC: " << *C << "\n");            continue;          } -        if (&C->getOuterRefSCC() != RC) { -          LLVM_DEBUG(dbgs() << "Skipping an SCC that is now part of some other " -                               "RefSCC...\n"); -          continue; -        } +        // We used to also check if the current SCC is part of the current +        // RefSCC and bail if it wasn't, since it should be in RCWorklist. +        // However, this can cause compile time explosions in some cases on +        // modules with a huge RefSCC. If a non-trivial amount of SCCs in the +        // huge RefSCC can become their own child RefSCC, we create one child +        // RefSCC, bail on the current RefSCC, visit the child RefSCC, revisit +        // the huge RefSCC, and repeat. By visiting all SCCs in the original +        // RefSCC we create all the child RefSCCs in one pass of the RefSCC, +        // rather one pass of the RefSCC creating one child RefSCC at a time.          // Ensure we can proxy analysis updates from the CGSCC analysis manager          // into the the Function analysis manager by getting a proxy here. @@ -264,11 +267,8 @@ ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {            // Check that we didn't miss any update scenario.            assert(!InvalidSCCSet.count(C) && "Processing an invalid SCC!");            assert(C->begin() != C->end() && "Cannot have an empty SCC!"); -          assert(&C->getOuterRefSCC() == RC && -                 "Processing an SCC in a different RefSCC!");            LastUpdatedC = UR.UpdatedC; -          UR.UpdatedRC = nullptr;            UR.UpdatedC = nullptr;            // Check the PassInstrumentation's BeforePass callbacks before @@ -290,7 +290,6 @@ ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {            // Update the SCC and RefSCC if necessary.            C = UR.UpdatedC ? UR.UpdatedC : C; -          RC = UR.UpdatedRC ? UR.UpdatedRC : RC;            if (UR.UpdatedC) {              // If we're updating the SCC, also update the FAM inside the proxy's @@ -1213,10 +1212,8 @@ static LazyCallGraph::SCC &updateCGAndAnalysisManagerForPass(    assert(!UR.InvalidatedRefSCCs.count(RC) && "Invalidated the current RefSCC!");    assert(&C->getOuterRefSCC() == RC && "Current SCC not in current RefSCC!"); -  // Record the current RefSCC and SCC for higher layers of the CGSCC pass -  // manager now that all the updates have been applied. -  if (RC != &InitialRC) -    UR.UpdatedRC = RC; +  // Record the current SCC for higher layers of the CGSCC pass manager now that +  // all the updates have been applied.    if (C != &InitialC)      UR.UpdatedC = C; | 
