| 1 | //===- CGSCCPassManager.cpp - Managing & running CGSCC passes -------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "llvm/Analysis/CGSCCPassManager.h" |
| 10 | #include "llvm/ADT/ArrayRef.h" |
| 11 | #include "llvm/ADT/PriorityWorklist.h" |
| 12 | #include "llvm/ADT/STLExtras.h" |
| 13 | #include "llvm/ADT/SetVector.h" |
| 14 | #include "llvm/ADT/SmallPtrSet.h" |
| 15 | #include "llvm/ADT/SmallVector.h" |
| 16 | #include "llvm/ADT/Statistic.h" |
| 17 | #include "llvm/ADT/iterator_range.h" |
| 18 | #include "llvm/Analysis/LazyCallGraph.h" |
| 19 | #include "llvm/IR/Constant.h" |
| 20 | #include "llvm/IR/InstIterator.h" |
| 21 | #include "llvm/IR/Instruction.h" |
| 22 | #include "llvm/IR/PassManager.h" |
| 23 | #include "llvm/IR/PassManagerImpl.h" |
| 24 | #include "llvm/IR/ValueHandle.h" |
| 25 | #include "llvm/Support/Casting.h" |
| 26 | #include "llvm/Support/CommandLine.h" |
| 27 | #include "llvm/Support/Compiler.h" |
| 28 | #include "llvm/Support/Debug.h" |
| 29 | #include "llvm/Support/ErrorHandling.h" |
| 30 | #include "llvm/Support/raw_ostream.h" |
| 31 | #include <cassert> |
| 32 | #include <optional> |
| 33 | |
| 34 | #define DEBUG_TYPE "cgscc" |
| 35 | |
| 36 | using namespace llvm; |
| 37 | |
| 38 | STATISTIC(LargestCGSCC, "Number of functions in the largest SCC" ); |
| 39 | |
| 40 | // Explicit template instantiations and specialization definitions for core |
| 41 | // template typedefs. |
| 42 | namespace llvm { |
| 43 | static cl::opt<bool> AbortOnMaxDevirtIterationsReached( |
| 44 | "abort-on-max-devirt-iterations-reached" , |
| 45 | cl::desc("Abort when the max iterations for devirtualization CGSCC repeat " |
| 46 | "pass is reached" )); |
| 47 | |
| 48 | AnalysisKey ShouldNotRunFunctionPassesAnalysis::Key; |
| 49 | |
| 50 | // Explicit instantiations for the core proxy templates. |
| 51 | template class LLVM_EXPORT_TEMPLATE AllAnalysesOn<LazyCallGraph::SCC>; |
| 52 | template class LLVM_EXPORT_TEMPLATE |
| 53 | AnalysisManager<LazyCallGraph::SCC, LazyCallGraph &>; |
| 54 | template class PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, |
| 55 | LazyCallGraph &, CGSCCUpdateResult &>; |
| 56 | template class LLVM_EXPORT_TEMPLATE |
| 57 | InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>; |
| 58 | template class LLVM_EXPORT_TEMPLATE OuterAnalysisManagerProxy< |
| 59 | ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph &>; |
| 60 | template class LLVM_EXPORT_TEMPLATE |
| 61 | OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>; |
| 62 | |
| 63 | /// Explicitly specialize the pass manager run method to handle call graph |
| 64 | /// updates. |
| 65 | template <> |
| 66 | PreservedAnalyses |
| 67 | PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, |
| 68 | CGSCCUpdateResult &>::run(LazyCallGraph::SCC &InitialC, |
| 69 | CGSCCAnalysisManager &AM, |
| 70 | LazyCallGraph &G, CGSCCUpdateResult &UR) { |
| 71 | // Request PassInstrumentation from analysis manager, will use it to run |
| 72 | // instrumenting callbacks for the passes later. |
| 73 | PassInstrumentation PI = |
| 74 | AM.getResult<PassInstrumentationAnalysis>(IR&: InitialC, ExtraArgs&: G); |
| 75 | |
| 76 | PreservedAnalyses PA = PreservedAnalyses::all(); |
| 77 | |
| 78 | // The SCC may be refined while we are running passes over it, so set up |
| 79 | // a pointer that we can update. |
| 80 | LazyCallGraph::SCC *C = &InitialC; |
| 81 | |
| 82 | // Get Function analysis manager from its proxy. |
| 83 | FunctionAnalysisManager &FAM = |
| 84 | AM.getCachedResult<FunctionAnalysisManagerCGSCCProxy>(IR&: *C)->getManager(); |
| 85 | |
| 86 | for (auto &Pass : Passes) { |
| 87 | // Check the PassInstrumentation's BeforePass callbacks before running the |
| 88 | // pass, skip its execution completely if asked to (callback returns false). |
| 89 | if (!PI.runBeforePass(Pass: *Pass, IR: *C)) |
| 90 | continue; |
| 91 | |
| 92 | LargestCGSCC.updateMax(V: C->size()); |
| 93 | |
| 94 | PreservedAnalyses PassPA = Pass->run(IR&: *C, AM, ExtraArgs&: G, ExtraArgs&: UR); |
| 95 | |
| 96 | // Update the SCC if necessary. |
| 97 | C = UR.UpdatedC ? UR.UpdatedC : C; |
| 98 | if (UR.UpdatedC) { |
| 99 | // If C is updated, also create a proxy and update FAM inside the result. |
| 100 | auto *ResultFAMCP = |
| 101 | &AM.getResult<FunctionAnalysisManagerCGSCCProxy>(IR&: *C, ExtraArgs&: G); |
| 102 | ResultFAMCP->updateFAM(FAM); |
| 103 | } |
| 104 | |
| 105 | // Intersect the final preserved analyses to compute the aggregate |
| 106 | // preserved set for this pass manager. |
| 107 | PA.intersect(Arg: PassPA); |
| 108 | |
| 109 | // If the CGSCC pass wasn't able to provide a valid updated SCC, the |
| 110 | // current SCC may simply need to be skipped if invalid. |
| 111 | if (UR.InvalidatedSCCs.count(Ptr: C)) { |
| 112 | PI.runAfterPassInvalidated<LazyCallGraph::SCC>(Pass: *Pass, PA: PassPA); |
| 113 | LLVM_DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n" ); |
| 114 | break; |
| 115 | } |
| 116 | |
| 117 | // Check that we didn't miss any update scenario. |
| 118 | assert(C->begin() != C->end() && "Cannot have an empty SCC!" ); |
| 119 | |
| 120 | // Update the analysis manager as each pass runs and potentially |
| 121 | // invalidates analyses. |
| 122 | AM.invalidate(IR&: *C, PA: PassPA); |
| 123 | |
| 124 | PI.runAfterPass<LazyCallGraph::SCC>(Pass: *Pass, IR: *C, PA: PassPA); |
| 125 | } |
| 126 | |
| 127 | // Before we mark all of *this* SCC's analyses as preserved below, intersect |
| 128 | // this with the cross-SCC preserved analysis set. This is used to allow |
| 129 | // CGSCC passes to mutate ancestor SCCs and still trigger proper invalidation |
| 130 | // for them. |
| 131 | UR.CrossSCCPA.intersect(Arg: PA); |
| 132 | |
| 133 | // Invalidation was handled after each pass in the above loop for the current |
| 134 | // SCC. Therefore, the remaining analysis results in the AnalysisManager are |
| 135 | // preserved. We mark this with a set so that we don't need to inspect each |
| 136 | // one individually. |
| 137 | PA.preserveSet<AllAnalysesOn<LazyCallGraph::SCC>>(); |
| 138 | |
| 139 | return PA; |
| 140 | } |
| 141 | |
| 142 | PreservedAnalyses |
| 143 | ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) { |
| 144 | // Setup the CGSCC analysis manager from its proxy. |
| 145 | CGSCCAnalysisManager &CGAM = |
| 146 | AM.getResult<CGSCCAnalysisManagerModuleProxy>(IR&: M).getManager(); |
| 147 | |
| 148 | // Get the call graph for this module. |
| 149 | LazyCallGraph &CG = AM.getResult<LazyCallGraphAnalysis>(IR&: M); |
| 150 | |
| 151 | // Get Function analysis manager from its proxy. |
| 152 | FunctionAnalysisManager &FAM = |
| 153 | AM.getCachedResult<FunctionAnalysisManagerModuleProxy>(IR&: M)->getManager(); |
| 154 | |
| 155 | // We keep worklists to allow us to push more work onto the pass manager as |
| 156 | // the passes are run. |
| 157 | SmallPriorityWorklist<LazyCallGraph::RefSCC *, 1> RCWorklist; |
| 158 | SmallPriorityWorklist<LazyCallGraph::SCC *, 1> CWorklist; |
| 159 | |
| 160 | // Keep sets for invalidated SCCs that should be skipped when |
| 161 | // iterating off the worklists. |
| 162 | SmallPtrSet<LazyCallGraph::SCC *, 4> InvalidSCCSet; |
| 163 | |
| 164 | SmallDenseSet<std::pair<LazyCallGraph::Node *, LazyCallGraph::SCC *>, 4> |
| 165 | InlinedInternalEdges; |
| 166 | |
| 167 | SmallVector<Function *, 4> DeadFunctions; |
| 168 | |
| 169 | CGSCCUpdateResult UR = {.CWorklist: CWorklist, |
| 170 | .InvalidatedSCCs: InvalidSCCSet, |
| 171 | .UpdatedC: nullptr, |
| 172 | .CrossSCCPA: PreservedAnalyses::all(), |
| 173 | .InlinedInternalEdges: InlinedInternalEdges, |
| 174 | .DeadFunctions: DeadFunctions, |
| 175 | .IndirectVHs: {}}; |
| 176 | |
| 177 | // Request PassInstrumentation from analysis manager, will use it to run |
| 178 | // instrumenting callbacks for the passes later. |
| 179 | PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(IR&: M); |
| 180 | |
| 181 | PreservedAnalyses PA = PreservedAnalyses::all(); |
| 182 | CG.buildRefSCCs(); |
| 183 | for (LazyCallGraph::RefSCC &RC : |
| 184 | llvm::make_early_inc_range(Range: CG.postorder_ref_sccs())) { |
| 185 | assert(RCWorklist.empty() && |
| 186 | "Should always start with an empty RefSCC worklist" ); |
| 187 | // The postorder_ref_sccs range we are walking is lazily constructed, so |
| 188 | // we only push the first one onto the worklist. The worklist allows us |
| 189 | // to capture *new* RefSCCs created during transformations. |
| 190 | // |
| 191 | // We really want to form RefSCCs lazily because that makes them cheaper |
| 192 | // to update as the program is simplified and allows us to have greater |
| 193 | // cache locality as forming a RefSCC touches all the parts of all the |
| 194 | // functions within that RefSCC. |
| 195 | // |
| 196 | // We also eagerly increment the iterator to the next position because |
| 197 | // the CGSCC passes below may delete the current RefSCC. |
| 198 | RCWorklist.insert(X: &RC); |
| 199 | |
| 200 | do { |
| 201 | LazyCallGraph::RefSCC *RC = RCWorklist.pop_back_val(); |
| 202 | assert(CWorklist.empty() && |
| 203 | "Should always start with an empty SCC worklist" ); |
| 204 | |
| 205 | LLVM_DEBUG(dbgs() << "Running an SCC pass across the RefSCC: " << *RC |
| 206 | << "\n" ); |
| 207 | |
| 208 | // The top of the worklist may *also* be the same SCC we just ran over |
| 209 | // (and invalidated for). Keep track of that last SCC we processed due |
| 210 | // to SCC update to avoid redundant processing when an SCC is both just |
| 211 | // updated itself and at the top of the worklist. |
| 212 | LazyCallGraph::SCC *LastUpdatedC = nullptr; |
| 213 | |
| 214 | // Push the initial SCCs in reverse post-order as we'll pop off the |
| 215 | // back and so see this in post-order. |
| 216 | for (LazyCallGraph::SCC &C : llvm::reverse(C&: *RC)) |
| 217 | CWorklist.insert(X: &C); |
| 218 | |
| 219 | do { |
| 220 | LazyCallGraph::SCC *C = CWorklist.pop_back_val(); |
| 221 | // Due to call graph mutations, we may have invalid SCCs or SCCs from |
| 222 | // other RefSCCs in the worklist. The invalid ones are dead and the |
| 223 | // other RefSCCs should be queued above, so we just need to skip both |
| 224 | // scenarios here. |
| 225 | if (InvalidSCCSet.count(Ptr: C)) { |
| 226 | LLVM_DEBUG(dbgs() << "Skipping an invalid SCC...\n" ); |
| 227 | continue; |
| 228 | } |
| 229 | if (LastUpdatedC == C) { |
| 230 | LLVM_DEBUG(dbgs() << "Skipping redundant run on SCC: " << *C << "\n" ); |
| 231 | continue; |
| 232 | } |
| 233 | // We used to also check if the current SCC is part of the current |
| 234 | // RefSCC and bail if it wasn't, since it should be in RCWorklist. |
| 235 | // However, this can cause compile time explosions in some cases on |
| 236 | // modules with a huge RefSCC. If a non-trivial amount of SCCs in the |
| 237 | // huge RefSCC can become their own child RefSCC, we create one child |
| 238 | // RefSCC, bail on the current RefSCC, visit the child RefSCC, revisit |
| 239 | // the huge RefSCC, and repeat. By visiting all SCCs in the original |
| 240 | // RefSCC we create all the child RefSCCs in one pass of the RefSCC, |
| 241 | // rather one pass of the RefSCC creating one child RefSCC at a time. |
| 242 | |
| 243 | // Ensure we can proxy analysis updates from the CGSCC analysis manager |
| 244 | // into the Function analysis manager by getting a proxy here. |
| 245 | // This also needs to update the FunctionAnalysisManager, as this may be |
| 246 | // the first time we see this SCC. |
| 247 | CGAM.getResult<FunctionAnalysisManagerCGSCCProxy>(IR&: *C, ExtraArgs&: CG).updateFAM( |
| 248 | FAM); |
| 249 | |
| 250 | // Each time we visit a new SCC pulled off the worklist, |
| 251 | // a transformation of a child SCC may have also modified this parent |
| 252 | // and invalidated analyses. So we invalidate using the update record's |
| 253 | // cross-SCC preserved set. This preserved set is intersected by any |
| 254 | // CGSCC pass that handles invalidation (primarily pass managers) prior |
| 255 | // to marking its SCC as preserved. That lets us track everything that |
| 256 | // might need invalidation across SCCs without excessive invalidations |
| 257 | // on a single SCC. |
| 258 | // |
| 259 | // This essentially allows SCC passes to freely invalidate analyses |
| 260 | // of any ancestor SCC. If this becomes detrimental to successfully |
| 261 | // caching analyses, we could force each SCC pass to manually |
| 262 | // invalidate the analyses for any SCCs other than themselves which |
| 263 | // are mutated. However, that seems to lose the robustness of the |
| 264 | // pass-manager driven invalidation scheme. |
| 265 | CGAM.invalidate(IR&: *C, PA: UR.CrossSCCPA); |
| 266 | |
| 267 | do { |
| 268 | // Check that we didn't miss any update scenario. |
| 269 | assert(!InvalidSCCSet.count(C) && "Processing an invalid SCC!" ); |
| 270 | assert(C->begin() != C->end() && "Cannot have an empty SCC!" ); |
| 271 | |
| 272 | LastUpdatedC = UR.UpdatedC; |
| 273 | UR.UpdatedC = nullptr; |
| 274 | |
| 275 | // Check the PassInstrumentation's BeforePass callbacks before |
| 276 | // running the pass, skip its execution completely if asked to |
| 277 | // (callback returns false). |
| 278 | if (!PI.runBeforePass<LazyCallGraph::SCC>(Pass: *Pass, IR: *C)) |
| 279 | continue; |
| 280 | |
| 281 | PreservedAnalyses PassPA = Pass->run(IR&: *C, AM&: CGAM, ExtraArgs&: CG, ExtraArgs&: UR); |
| 282 | |
| 283 | // Update the SCC and RefSCC if necessary. |
| 284 | C = UR.UpdatedC ? UR.UpdatedC : C; |
| 285 | |
| 286 | if (UR.UpdatedC) { |
| 287 | // If we're updating the SCC, also update the FAM inside the proxy's |
| 288 | // result. |
| 289 | CGAM.getResult<FunctionAnalysisManagerCGSCCProxy>(IR&: *C, ExtraArgs&: CG).updateFAM( |
| 290 | FAM); |
| 291 | } |
| 292 | |
| 293 | // Intersect with the cross-SCC preserved set to capture any |
| 294 | // cross-SCC invalidation. |
| 295 | UR.CrossSCCPA.intersect(Arg: PassPA); |
| 296 | // Intersect the preserved set so that invalidation of module |
| 297 | // analyses will eventually occur when the module pass completes. |
| 298 | PA.intersect(Arg: PassPA); |
| 299 | |
| 300 | // If the CGSCC pass wasn't able to provide a valid updated SCC, |
| 301 | // the current SCC may simply need to be skipped if invalid. |
| 302 | if (UR.InvalidatedSCCs.count(Ptr: C)) { |
| 303 | PI.runAfterPassInvalidated<LazyCallGraph::SCC>(Pass: *Pass, PA: PassPA); |
| 304 | LLVM_DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n" ); |
| 305 | break; |
| 306 | } |
| 307 | |
| 308 | // Check that we didn't miss any update scenario. |
| 309 | assert(C->begin() != C->end() && "Cannot have an empty SCC!" ); |
| 310 | |
| 311 | // We handle invalidating the CGSCC analysis manager's information |
| 312 | // for the (potentially updated) SCC here. Note that any other SCCs |
| 313 | // whose structure has changed should have been invalidated by |
| 314 | // whatever was updating the call graph. This SCC gets invalidated |
| 315 | // late as it contains the nodes that were actively being |
| 316 | // processed. |
| 317 | CGAM.invalidate(IR&: *C, PA: PassPA); |
| 318 | |
| 319 | PI.runAfterPass<LazyCallGraph::SCC>(Pass: *Pass, IR: *C, PA: PassPA); |
| 320 | |
| 321 | // The pass may have restructured the call graph and refined the |
| 322 | // current SCC and/or RefSCC. We need to update our current SCC and |
| 323 | // RefSCC pointers to follow these. Also, when the current SCC is |
| 324 | // refined, re-run the SCC pass over the newly refined SCC in order |
| 325 | // to observe the most precise SCC model available. This inherently |
| 326 | // cannot cycle excessively as it only happens when we split SCCs |
| 327 | // apart, at most converging on a DAG of single nodes. |
| 328 | // FIXME: If we ever start having RefSCC passes, we'll want to |
| 329 | // iterate there too. |
| 330 | if (UR.UpdatedC) |
| 331 | LLVM_DEBUG(dbgs() |
| 332 | << "Re-running SCC passes after a refinement of the " |
| 333 | "current SCC: " |
| 334 | << *UR.UpdatedC << "\n" ); |
| 335 | |
| 336 | // Note that both `C` and `RC` may at this point refer to deleted, |
| 337 | // invalid SCC and RefSCCs respectively. But we will short circuit |
| 338 | // the processing when we check them in the loop above. |
| 339 | } while (UR.UpdatedC); |
| 340 | } while (!CWorklist.empty()); |
| 341 | |
| 342 | // We only need to keep internal inlined edge information within |
| 343 | // a RefSCC, clear it to save on space and let the next time we visit |
| 344 | // any of these functions have a fresh start. |
| 345 | InlinedInternalEdges.clear(); |
| 346 | } while (!RCWorklist.empty()); |
| 347 | } |
| 348 | |
| 349 | CG.removeDeadFunctions(DeadFs: DeadFunctions); |
| 350 | for (Function *DeadF : DeadFunctions) |
| 351 | DeadF->eraseFromParent(); |
| 352 | |
| 353 | #if defined(EXPENSIVE_CHECKS) |
| 354 | // Verify that the call graph is still valid. |
| 355 | CG.verify(); |
| 356 | #endif |
| 357 | |
| 358 | // By definition we preserve the call garph, all SCC analyses, and the |
| 359 | // analysis proxies by handling them above and in any nested pass managers. |
| 360 | PA.preserveSet<AllAnalysesOn<LazyCallGraph::SCC>>(); |
| 361 | PA.preserve<LazyCallGraphAnalysis>(); |
| 362 | PA.preserve<CGSCCAnalysisManagerModuleProxy>(); |
| 363 | PA.preserve<FunctionAnalysisManagerModuleProxy>(); |
| 364 | return PA; |
| 365 | } |
| 366 | |
| 367 | PreservedAnalyses DevirtSCCRepeatedPass::run(LazyCallGraph::SCC &InitialC, |
| 368 | CGSCCAnalysisManager &AM, |
| 369 | LazyCallGraph &CG, |
| 370 | CGSCCUpdateResult &UR) { |
| 371 | PreservedAnalyses PA = PreservedAnalyses::all(); |
| 372 | PassInstrumentation PI = |
| 373 | AM.getResult<PassInstrumentationAnalysis>(IR&: InitialC, ExtraArgs&: CG); |
| 374 | |
| 375 | // The SCC may be refined while we are running passes over it, so set up |
| 376 | // a pointer that we can update. |
| 377 | LazyCallGraph::SCC *C = &InitialC; |
| 378 | |
| 379 | // Struct to track the counts of direct and indirect calls in each function |
| 380 | // of the SCC. |
| 381 | struct CallCount { |
| 382 | int Direct; |
| 383 | int Indirect; |
| 384 | }; |
| 385 | |
| 386 | // Put value handles on all of the indirect calls and return the number of |
| 387 | // direct calls for each function in the SCC. |
| 388 | auto ScanSCC = [](LazyCallGraph::SCC &C, |
| 389 | SmallMapVector<Value *, WeakTrackingVH, 16> &CallHandles) { |
| 390 | assert(CallHandles.empty() && "Must start with a clear set of handles." ); |
| 391 | |
| 392 | SmallDenseMap<Function *, CallCount> CallCounts; |
| 393 | CallCount CountLocal = {.Direct: 0, .Indirect: 0}; |
| 394 | for (LazyCallGraph::Node &N : C) { |
| 395 | CallCount &Count = |
| 396 | CallCounts.insert(KV: std::make_pair(x: &N.getFunction(), y&: CountLocal)) |
| 397 | .first->second; |
| 398 | for (Instruction &I : instructions(F&: N.getFunction())) |
| 399 | if (auto *CB = dyn_cast<CallBase>(Val: &I)) { |
| 400 | if (CB->getCalledFunction()) { |
| 401 | ++Count.Direct; |
| 402 | } else { |
| 403 | ++Count.Indirect; |
| 404 | CallHandles.insert(KV: {CB, WeakTrackingVH(CB)}); |
| 405 | } |
| 406 | } |
| 407 | } |
| 408 | |
| 409 | return CallCounts; |
| 410 | }; |
| 411 | |
| 412 | UR.IndirectVHs.clear(); |
| 413 | // Populate the initial call handles and get the initial call counts. |
| 414 | auto CallCounts = ScanSCC(*C, UR.IndirectVHs); |
| 415 | |
| 416 | for (int Iteration = 0;; ++Iteration) { |
| 417 | if (!PI.runBeforePass<LazyCallGraph::SCC>(Pass: *Pass, IR: *C)) |
| 418 | continue; |
| 419 | |
| 420 | PreservedAnalyses PassPA = Pass->run(IR&: *C, AM, ExtraArgs&: CG, ExtraArgs&: UR); |
| 421 | |
| 422 | PA.intersect(Arg: PassPA); |
| 423 | |
| 424 | // If the CGSCC pass wasn't able to provide a valid updated SCC, the |
| 425 | // current SCC may simply need to be skipped if invalid. |
| 426 | if (UR.InvalidatedSCCs.count(Ptr: C)) { |
| 427 | PI.runAfterPassInvalidated<LazyCallGraph::SCC>(Pass: *Pass, PA: PassPA); |
| 428 | LLVM_DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n" ); |
| 429 | break; |
| 430 | } |
| 431 | |
| 432 | // Update the analysis manager with each run and intersect the total set |
| 433 | // of preserved analyses so we're ready to iterate. |
| 434 | AM.invalidate(IR&: *C, PA: PassPA); |
| 435 | |
| 436 | PI.runAfterPass<LazyCallGraph::SCC>(Pass: *Pass, IR: *C, PA: PassPA); |
| 437 | |
| 438 | // If the SCC structure has changed, bail immediately and let the outer |
| 439 | // CGSCC layer handle any iteration to reflect the refined structure. |
| 440 | if (UR.UpdatedC && UR.UpdatedC != C) |
| 441 | break; |
| 442 | |
| 443 | assert(C->begin() != C->end() && "Cannot have an empty SCC!" ); |
| 444 | |
| 445 | // Check whether any of the handles were devirtualized. |
| 446 | bool Devirt = llvm::any_of(Range&: UR.IndirectVHs, P: [](auto &P) -> bool { |
| 447 | if (P.second) { |
| 448 | if (CallBase *CB = dyn_cast<CallBase>(P.second)) { |
| 449 | if (CB->getCalledFunction()) { |
| 450 | LLVM_DEBUG(dbgs() << "Found devirtualized call: " << *CB << "\n" ); |
| 451 | return true; |
| 452 | } |
| 453 | } |
| 454 | } |
| 455 | return false; |
| 456 | }); |
| 457 | |
| 458 | // Rescan to build up a new set of handles and count how many direct |
| 459 | // calls remain. If we decide to iterate, this also sets up the input to |
| 460 | // the next iteration. |
| 461 | UR.IndirectVHs.clear(); |
| 462 | auto NewCallCounts = ScanSCC(*C, UR.IndirectVHs); |
| 463 | |
| 464 | // If we haven't found an explicit devirtualization already see if we |
| 465 | // have decreased the number of indirect calls and increased the number |
| 466 | // of direct calls for any function in the SCC. This can be fooled by all |
| 467 | // manner of transformations such as DCE and other things, but seems to |
| 468 | // work well in practice. |
| 469 | if (!Devirt) |
| 470 | // Iterate over the keys in NewCallCounts, if Function also exists in |
| 471 | // CallCounts, make the check below. |
| 472 | for (auto &Pair : NewCallCounts) { |
| 473 | auto &CallCountNew = Pair.second; |
| 474 | auto CountIt = CallCounts.find(Val: Pair.first); |
| 475 | if (CountIt != CallCounts.end()) { |
| 476 | const auto &CallCountOld = CountIt->second; |
| 477 | if (CallCountOld.Indirect > CallCountNew.Indirect && |
| 478 | CallCountOld.Direct < CallCountNew.Direct) { |
| 479 | Devirt = true; |
| 480 | break; |
| 481 | } |
| 482 | } |
| 483 | } |
| 484 | |
| 485 | if (!Devirt) { |
| 486 | break; |
| 487 | } |
| 488 | |
| 489 | // Otherwise, if we've already hit our max, we're done. |
| 490 | if (Iteration >= MaxIterations) { |
| 491 | if (AbortOnMaxDevirtIterationsReached) |
| 492 | report_fatal_error(reason: "Max devirtualization iterations reached" ); |
| 493 | LLVM_DEBUG( |
| 494 | dbgs() << "Found another devirtualization after hitting the max " |
| 495 | "number of repetitions (" |
| 496 | << MaxIterations << ") on SCC: " << *C << "\n" ); |
| 497 | break; |
| 498 | } |
| 499 | |
| 500 | LLVM_DEBUG( |
| 501 | dbgs() << "Repeating an SCC pass after finding a devirtualization in: " |
| 502 | << *C << "\n" ); |
| 503 | |
| 504 | // Move over the new call counts in preparation for iterating. |
| 505 | CallCounts = std::move(NewCallCounts); |
| 506 | } |
| 507 | |
| 508 | // Note that we don't add any preserved entries here unlike a more normal |
| 509 | // "pass manager" because we only handle invalidation *between* iterations, |
| 510 | // not after the last iteration. |
| 511 | return PA; |
| 512 | } |
| 513 | |
| 514 | PreservedAnalyses CGSCCToFunctionPassAdaptor::run(LazyCallGraph::SCC &C, |
| 515 | CGSCCAnalysisManager &AM, |
| 516 | LazyCallGraph &CG, |
| 517 | CGSCCUpdateResult &UR) { |
| 518 | // Setup the function analysis manager from its proxy. |
| 519 | FunctionAnalysisManager &FAM = |
| 520 | AM.getResult<FunctionAnalysisManagerCGSCCProxy>(IR&: C, ExtraArgs&: CG).getManager(); |
| 521 | |
| 522 | SmallVector<LazyCallGraph::Node *, 4> Nodes(llvm::make_pointer_range(Range&: C)); |
| 523 | |
| 524 | // The SCC may get split while we are optimizing functions due to deleting |
| 525 | // edges. If this happens, the current SCC can shift, so keep track of |
| 526 | // a pointer we can overwrite. |
| 527 | LazyCallGraph::SCC *CurrentC = &C; |
| 528 | |
| 529 | LLVM_DEBUG(dbgs() << "Running function passes across an SCC: " << C << "\n" ); |
| 530 | |
| 531 | PreservedAnalyses PA = PreservedAnalyses::all(); |
| 532 | for (LazyCallGraph::Node *N : Nodes) { |
| 533 | // Skip nodes from other SCCs. These may have been split out during |
| 534 | // processing. We'll eventually visit those SCCs and pick up the nodes |
| 535 | // there. |
| 536 | if (CG.lookupSCC(N&: *N) != CurrentC) |
| 537 | continue; |
| 538 | |
| 539 | Function &F = N->getFunction(); |
| 540 | |
| 541 | if (NoRerun && FAM.getCachedResult<ShouldNotRunFunctionPassesAnalysis>(IR&: F)) |
| 542 | continue; |
| 543 | |
| 544 | PassInstrumentation PI = FAM.getResult<PassInstrumentationAnalysis>(IR&: F); |
| 545 | if (!PI.runBeforePass<Function>(Pass: *Pass, IR: F)) |
| 546 | continue; |
| 547 | |
| 548 | PreservedAnalyses PassPA = Pass->run(IR&: F, AM&: FAM); |
| 549 | |
| 550 | // We know that the function pass couldn't have invalidated any other |
| 551 | // function's analyses (that's the contract of a function pass), so |
| 552 | // directly handle the function analysis manager's invalidation here. |
| 553 | FAM.invalidate(IR&: F, PA: EagerlyInvalidate ? PreservedAnalyses::none() : PassPA); |
| 554 | |
| 555 | PI.runAfterPass<Function>(Pass: *Pass, IR: F, PA: PassPA); |
| 556 | |
| 557 | // Then intersect the preserved set so that invalidation of module |
| 558 | // analyses will eventually occur when the module pass completes. |
| 559 | PA.intersect(Arg: std::move(PassPA)); |
| 560 | |
| 561 | // If the call graph hasn't been preserved, update it based on this |
| 562 | // function pass. This may also update the current SCC to point to |
| 563 | // a smaller, more refined SCC. |
| 564 | auto PAC = PA.getChecker<LazyCallGraphAnalysis>(); |
| 565 | if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) { |
| 566 | CurrentC = &updateCGAndAnalysisManagerForFunctionPass(G&: CG, C&: *CurrentC, N&: *N, |
| 567 | AM, UR, FAM); |
| 568 | assert(CG.lookupSCC(*N) == CurrentC && |
| 569 | "Current SCC not updated to the SCC containing the current node!" ); |
| 570 | } |
| 571 | } |
| 572 | |
| 573 | // By definition we preserve the proxy. And we preserve all analyses on |
| 574 | // Functions. This precludes *any* invalidation of function analyses by the |
| 575 | // proxy, but that's OK because we've taken care to invalidate analyses in |
| 576 | // the function analysis manager incrementally above. |
| 577 | PA.preserveSet<AllAnalysesOn<Function>>(); |
| 578 | PA.preserve<FunctionAnalysisManagerCGSCCProxy>(); |
| 579 | |
| 580 | // We've also ensured that we updated the call graph along the way. |
| 581 | PA.preserve<LazyCallGraphAnalysis>(); |
| 582 | |
| 583 | return PA; |
| 584 | } |
| 585 | |
| 586 | bool CGSCCAnalysisManagerModuleProxy::Result::invalidate( |
| 587 | Module &M, const PreservedAnalyses &PA, |
| 588 | ModuleAnalysisManager::Invalidator &Inv) { |
| 589 | // If literally everything is preserved, we're done. |
| 590 | if (PA.areAllPreserved()) |
| 591 | return false; // This is still a valid proxy. |
| 592 | |
| 593 | // If this proxy or the call graph is going to be invalidated, we also need |
| 594 | // to clear all the keys coming from that analysis. |
| 595 | // |
| 596 | // We also directly invalidate the FAM's module proxy if necessary, and if |
| 597 | // that proxy isn't preserved we can't preserve this proxy either. We rely on |
| 598 | // it to handle module -> function analysis invalidation in the face of |
| 599 | // structural changes and so if it's unavailable we conservatively clear the |
| 600 | // entire SCC layer as well rather than trying to do invalidation ourselves. |
| 601 | auto PAC = PA.getChecker<CGSCCAnalysisManagerModuleProxy>(); |
| 602 | if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Module>>()) || |
| 603 | Inv.invalidate<LazyCallGraphAnalysis>(IR&: M, PA) || |
| 604 | Inv.invalidate<FunctionAnalysisManagerModuleProxy>(IR&: M, PA)) { |
| 605 | InnerAM->clear(); |
| 606 | |
| 607 | // And the proxy itself should be marked as invalid so that we can observe |
| 608 | // the new call graph. This isn't strictly necessary because we cheat |
| 609 | // above, but is still useful. |
| 610 | return true; |
| 611 | } |
| 612 | |
| 613 | // Directly check if the relevant set is preserved so we can short circuit |
| 614 | // invalidating SCCs below. |
| 615 | bool AreSCCAnalysesPreserved = |
| 616 | PA.allAnalysesInSetPreserved<AllAnalysesOn<LazyCallGraph::SCC>>(); |
| 617 | |
| 618 | // Ok, we have a graph, so we can propagate the invalidation down into it. |
| 619 | G->buildRefSCCs(); |
| 620 | for (auto &RC : G->postorder_ref_sccs()) |
| 621 | for (auto &C : RC) { |
| 622 | std::optional<PreservedAnalyses> InnerPA; |
| 623 | |
| 624 | // Check to see whether the preserved set needs to be adjusted based on |
| 625 | // module-level analysis invalidation triggering deferred invalidation |
| 626 | // for this SCC. |
| 627 | if (auto *OuterProxy = |
| 628 | InnerAM->getCachedResult<ModuleAnalysisManagerCGSCCProxy>(IR&: C)) |
| 629 | for (const auto &OuterInvalidationPair : |
| 630 | OuterProxy->getOuterInvalidations()) { |
| 631 | AnalysisKey *OuterAnalysisID = OuterInvalidationPair.first; |
| 632 | const auto &InnerAnalysisIDs = OuterInvalidationPair.second; |
| 633 | if (Inv.invalidate(ID: OuterAnalysisID, IR&: M, PA)) { |
| 634 | if (!InnerPA) |
| 635 | InnerPA = PA; |
| 636 | for (AnalysisKey *InnerAnalysisID : InnerAnalysisIDs) |
| 637 | InnerPA->abandon(ID: InnerAnalysisID); |
| 638 | } |
| 639 | } |
| 640 | |
| 641 | // Check if we needed a custom PA set. If so we'll need to run the inner |
| 642 | // invalidation. |
| 643 | if (InnerPA) { |
| 644 | InnerAM->invalidate(IR&: C, PA: *InnerPA); |
| 645 | continue; |
| 646 | } |
| 647 | |
| 648 | // Otherwise we only need to do invalidation if the original PA set didn't |
| 649 | // preserve all SCC analyses. |
| 650 | if (!AreSCCAnalysesPreserved) |
| 651 | InnerAM->invalidate(IR&: C, PA); |
| 652 | } |
| 653 | |
| 654 | // Return false to indicate that this result is still a valid proxy. |
| 655 | return false; |
| 656 | } |
| 657 | |
| 658 | template <> |
| 659 | CGSCCAnalysisManagerModuleProxy::Result |
| 660 | CGSCCAnalysisManagerModuleProxy::run(Module &M, ModuleAnalysisManager &AM) { |
| 661 | // Force the Function analysis manager to also be available so that it can |
| 662 | // be accessed in an SCC analysis and proxied onward to function passes. |
| 663 | // FIXME: It is pretty awkward to just drop the result here and assert that |
| 664 | // we can find it again later. |
| 665 | (void)AM.getResult<FunctionAnalysisManagerModuleProxy>(IR&: M); |
| 666 | |
| 667 | return Result(*InnerAM, AM.getResult<LazyCallGraphAnalysis>(IR&: M)); |
| 668 | } |
| 669 | |
| 670 | AnalysisKey FunctionAnalysisManagerCGSCCProxy::Key; |
| 671 | |
| 672 | FunctionAnalysisManagerCGSCCProxy::Result |
| 673 | FunctionAnalysisManagerCGSCCProxy::run(LazyCallGraph::SCC &C, |
| 674 | CGSCCAnalysisManager &AM, |
| 675 | LazyCallGraph &CG) { |
| 676 | // Note: unconditionally getting checking that the proxy exists may get it at |
| 677 | // this point. There are cases when this is being run unnecessarily, but |
| 678 | // it is cheap and having the assertion in place is more valuable. |
| 679 | auto &MAMProxy = AM.getResult<ModuleAnalysisManagerCGSCCProxy>(IR&: C, ExtraArgs&: CG); |
| 680 | Module &M = *C.begin()->getFunction().getParent(); |
| 681 | bool ProxyExists = |
| 682 | MAMProxy.cachedResultExists<FunctionAnalysisManagerModuleProxy>(IR&: M); |
| 683 | assert(ProxyExists && |
| 684 | "The CGSCC pass manager requires that the FAM module proxy is run " |
| 685 | "on the module prior to entering the CGSCC walk" ); |
| 686 | (void)ProxyExists; |
| 687 | |
| 688 | // We just return an empty result. The caller will use the updateFAM interface |
| 689 | // to correctly register the relevant FunctionAnalysisManager based on the |
| 690 | // context in which this proxy is run. |
| 691 | return Result(); |
| 692 | } |
| 693 | |
| 694 | bool FunctionAnalysisManagerCGSCCProxy::Result::invalidate( |
| 695 | LazyCallGraph::SCC &C, const PreservedAnalyses &PA, |
| 696 | CGSCCAnalysisManager::Invalidator &Inv) { |
| 697 | // If literally everything is preserved, we're done. |
| 698 | if (PA.areAllPreserved()) |
| 699 | return false; // This is still a valid proxy. |
| 700 | |
| 701 | // All updates to preserve valid results are done below, so we don't need to |
| 702 | // invalidate this proxy. |
| 703 | // |
| 704 | // Note that in order to preserve this proxy, a module pass must ensure that |
| 705 | // the FAM has been completely updated to handle the deletion of functions. |
| 706 | // Specifically, any FAM-cached results for those functions need to have been |
| 707 | // forcibly cleared. When preserved, this proxy will only invalidate results |
| 708 | // cached on functions *still in the module* at the end of the module pass. |
| 709 | auto PAC = PA.getChecker<FunctionAnalysisManagerCGSCCProxy>(); |
| 710 | if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<LazyCallGraph::SCC>>()) { |
| 711 | for (LazyCallGraph::Node &N : C) |
| 712 | FAM->invalidate(IR&: N.getFunction(), PA); |
| 713 | |
| 714 | return false; |
| 715 | } |
| 716 | |
| 717 | // Directly check if the relevant set is preserved. |
| 718 | bool AreFunctionAnalysesPreserved = |
| 719 | PA.allAnalysesInSetPreserved<AllAnalysesOn<Function>>(); |
| 720 | |
| 721 | // Now walk all the functions to see if any inner analysis invalidation is |
| 722 | // necessary. |
| 723 | for (LazyCallGraph::Node &N : C) { |
| 724 | Function &F = N.getFunction(); |
| 725 | std::optional<PreservedAnalyses> FunctionPA; |
| 726 | |
| 727 | // Check to see whether the preserved set needs to be pruned based on |
| 728 | // SCC-level analysis invalidation that triggers deferred invalidation |
| 729 | // registered with the outer analysis manager proxy for this function. |
| 730 | if (auto *OuterProxy = |
| 731 | FAM->getCachedResult<CGSCCAnalysisManagerFunctionProxy>(IR&: F)) |
| 732 | for (const auto &OuterInvalidationPair : |
| 733 | OuterProxy->getOuterInvalidations()) { |
| 734 | AnalysisKey *OuterAnalysisID = OuterInvalidationPair.first; |
| 735 | const auto &InnerAnalysisIDs = OuterInvalidationPair.second; |
| 736 | if (Inv.invalidate(ID: OuterAnalysisID, IR&: C, PA)) { |
| 737 | if (!FunctionPA) |
| 738 | FunctionPA = PA; |
| 739 | for (AnalysisKey *InnerAnalysisID : InnerAnalysisIDs) |
| 740 | FunctionPA->abandon(ID: InnerAnalysisID); |
| 741 | } |
| 742 | } |
| 743 | |
| 744 | // Check if we needed a custom PA set, and if so we'll need to run the |
| 745 | // inner invalidation. |
| 746 | if (FunctionPA) { |
| 747 | FAM->invalidate(IR&: F, PA: *FunctionPA); |
| 748 | continue; |
| 749 | } |
| 750 | |
| 751 | // Otherwise we only need to do invalidation if the original PA set didn't |
| 752 | // preserve all function analyses. |
| 753 | if (!AreFunctionAnalysesPreserved) |
| 754 | FAM->invalidate(IR&: F, PA); |
| 755 | } |
| 756 | |
| 757 | // Return false to indicate that this result is still a valid proxy. |
| 758 | return false; |
| 759 | } |
| 760 | |
| 761 | } // end namespace llvm |
| 762 | |
| 763 | /// When a new SCC is created for the graph we first update the |
| 764 | /// FunctionAnalysisManager in the Proxy's result. |
| 765 | /// As there might be function analysis results cached for the functions now in |
| 766 | /// that SCC, two forms of updates are required. |
| 767 | /// |
| 768 | /// First, a proxy from the SCC to the FunctionAnalysisManager needs to be |
| 769 | /// created so that any subsequent invalidation events to the SCC are |
| 770 | /// propagated to the function analysis results cached for functions within it. |
| 771 | /// |
| 772 | /// Second, if any of the functions within the SCC have analysis results with |
| 773 | /// outer analysis dependencies, then those dependencies would point to the |
| 774 | /// *wrong* SCC's analysis result. We forcibly invalidate the necessary |
| 775 | /// function analyses so that they don't retain stale handles. |
| 776 | static void updateNewSCCFunctionAnalyses(LazyCallGraph::SCC &C, |
| 777 | LazyCallGraph &G, |
| 778 | CGSCCAnalysisManager &AM, |
| 779 | FunctionAnalysisManager &FAM) { |
| 780 | AM.getResult<FunctionAnalysisManagerCGSCCProxy>(IR&: C, ExtraArgs&: G).updateFAM(FAM); |
| 781 | |
| 782 | // Now walk the functions in this SCC and invalidate any function analysis |
| 783 | // results that might have outer dependencies on an SCC analysis. |
| 784 | for (LazyCallGraph::Node &N : C) { |
| 785 | Function &F = N.getFunction(); |
| 786 | |
| 787 | auto *OuterProxy = |
| 788 | FAM.getCachedResult<CGSCCAnalysisManagerFunctionProxy>(IR&: F); |
| 789 | if (!OuterProxy) |
| 790 | // No outer analyses were queried, nothing to do. |
| 791 | continue; |
| 792 | |
| 793 | // Forcibly abandon all the inner analyses with dependencies, but |
| 794 | // invalidate nothing else. |
| 795 | auto PA = PreservedAnalyses::all(); |
| 796 | for (const auto &OuterInvalidationPair : |
| 797 | OuterProxy->getOuterInvalidations()) { |
| 798 | const auto &InnerAnalysisIDs = OuterInvalidationPair.second; |
| 799 | for (AnalysisKey *InnerAnalysisID : InnerAnalysisIDs) |
| 800 | PA.abandon(ID: InnerAnalysisID); |
| 801 | } |
| 802 | |
| 803 | // Now invalidate anything we found. |
| 804 | FAM.invalidate(IR&: F, PA); |
| 805 | } |
| 806 | } |
| 807 | |
| 808 | /// Helper function to update both the \c CGSCCAnalysisManager \p AM and the \c |
| 809 | /// CGSCCPassManager's \c CGSCCUpdateResult \p UR based on a range of newly |
| 810 | /// added SCCs. |
| 811 | /// |
| 812 | /// The range of new SCCs must be in postorder already. The SCC they were split |
| 813 | /// out of must be provided as \p C. The current node being mutated and |
| 814 | /// triggering updates must be passed as \p N. |
| 815 | /// |
| 816 | /// This function returns the SCC containing \p N. This will be either \p C if |
| 817 | /// no new SCCs have been split out, or it will be the new SCC containing \p N. |
| 818 | template <typename SCCRangeT> |
| 819 | static LazyCallGraph::SCC * |
| 820 | incorporateNewSCCRange(const SCCRangeT &NewSCCRange, LazyCallGraph &G, |
| 821 | LazyCallGraph::Node &N, LazyCallGraph::SCC *C, |
| 822 | CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR) { |
| 823 | using SCC = LazyCallGraph::SCC; |
| 824 | |
| 825 | if (NewSCCRange.empty()) |
| 826 | return C; |
| 827 | |
| 828 | // Add the current SCC to the worklist as its shape has changed. |
| 829 | UR.CWorklist.insert(X: C); |
| 830 | LLVM_DEBUG(dbgs() << "Enqueuing the existing SCC in the worklist:" << *C |
| 831 | << "\n" ); |
| 832 | |
| 833 | SCC *OldC = C; |
| 834 | |
| 835 | // Update the current SCC. Note that if we have new SCCs, this must actually |
| 836 | // change the SCC. |
| 837 | assert(C != &*NewSCCRange.begin() && |
| 838 | "Cannot insert new SCCs without changing current SCC!" ); |
| 839 | C = &*NewSCCRange.begin(); |
| 840 | assert(G.lookupSCC(N) == C && "Failed to update current SCC!" ); |
| 841 | |
| 842 | // If we had a cached FAM proxy originally, we will want to create more of |
| 843 | // them for each SCC that was split off. |
| 844 | FunctionAnalysisManager *FAM = nullptr; |
| 845 | if (auto *FAMProxy = |
| 846 | AM.getCachedResult<FunctionAnalysisManagerCGSCCProxy>(IR&: *OldC)) |
| 847 | FAM = &FAMProxy->getManager(); |
| 848 | |
| 849 | // We need to propagate an invalidation call to all but the newly current SCC |
| 850 | // because the outer pass manager won't do that for us after splitting them. |
| 851 | // FIXME: We should accept a PreservedAnalysis from the CG updater so that if |
| 852 | // there are preserved analysis we can avoid invalidating them here for |
| 853 | // split-off SCCs. |
| 854 | // We know however that this will preserve any FAM proxy so go ahead and mark |
| 855 | // that. |
| 856 | auto PA = PreservedAnalyses::allInSet<AllAnalysesOn<Function>>(); |
| 857 | PA.preserve<FunctionAnalysisManagerCGSCCProxy>(); |
| 858 | AM.invalidate(IR&: *OldC, PA); |
| 859 | |
| 860 | // Ensure the now-current SCC's function analyses are updated. |
| 861 | if (FAM) |
| 862 | updateNewSCCFunctionAnalyses(C&: *C, G, AM, FAM&: *FAM); |
| 863 | |
| 864 | for (SCC &NewC : llvm::reverse(llvm::drop_begin(NewSCCRange))) { |
| 865 | assert(C != &NewC && "No need to re-visit the current SCC!" ); |
| 866 | assert(OldC != &NewC && "Already handled the original SCC!" ); |
| 867 | UR.CWorklist.insert(X: &NewC); |
| 868 | LLVM_DEBUG(dbgs() << "Enqueuing a newly formed SCC:" << NewC << "\n" ); |
| 869 | |
| 870 | // Ensure new SCCs' function analyses are updated. |
| 871 | if (FAM) |
| 872 | updateNewSCCFunctionAnalyses(C&: NewC, G, AM, FAM&: *FAM); |
| 873 | |
| 874 | // Also propagate a normal invalidation to the new SCC as only the current |
| 875 | // will get one from the pass manager infrastructure. |
| 876 | AM.invalidate(IR&: NewC, PA); |
| 877 | } |
| 878 | return C; |
| 879 | } |
| 880 | |
| 881 | static LazyCallGraph::SCC &updateCGAndAnalysisManagerForPass( |
| 882 | LazyCallGraph &G, LazyCallGraph::SCC &InitialC, LazyCallGraph::Node &N, |
| 883 | CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, |
| 884 | FunctionAnalysisManager &FAM, bool FunctionPass) { |
| 885 | using Node = LazyCallGraph::Node; |
| 886 | using Edge = LazyCallGraph::Edge; |
| 887 | using SCC = LazyCallGraph::SCC; |
| 888 | using RefSCC = LazyCallGraph::RefSCC; |
| 889 | |
| 890 | RefSCC &InitialRC = InitialC.getOuterRefSCC(); |
| 891 | SCC *C = &InitialC; |
| 892 | RefSCC *RC = &InitialRC; |
| 893 | Function &F = N.getFunction(); |
| 894 | |
| 895 | // Walk the function body and build up the set of retained, promoted, and |
| 896 | // demoted edges. |
| 897 | SmallVector<Constant *, 16> Worklist; |
| 898 | SmallPtrSet<Constant *, 16> Visited; |
| 899 | SmallPtrSet<Node *, 16> RetainedEdges; |
| 900 | SmallSetVector<Node *, 4> PromotedRefTargets; |
| 901 | SmallSetVector<Node *, 4> DemotedCallTargets; |
| 902 | SmallSetVector<Node *, 4> NewCallEdges; |
| 903 | SmallSetVector<Node *, 4> NewRefEdges; |
| 904 | |
| 905 | // First walk the function and handle all called functions. We do this first |
| 906 | // because if there is a single call edge, whether there are ref edges is |
| 907 | // irrelevant. |
| 908 | for (Instruction &I : instructions(F)) { |
| 909 | if (auto *CB = dyn_cast<CallBase>(Val: &I)) { |
| 910 | if (Function *Callee = CB->getCalledFunction()) { |
| 911 | if (Visited.insert(Ptr: Callee).second && !Callee->isDeclaration()) { |
| 912 | Node *CalleeN = G.lookup(F: *Callee); |
| 913 | assert(CalleeN && |
| 914 | "Visited function should already have an associated node" ); |
| 915 | Edge *E = N->lookup(N&: *CalleeN); |
| 916 | assert((E || !FunctionPass) && |
| 917 | "No function transformations should introduce *new* " |
| 918 | "call edges! Any new calls should be modeled as " |
| 919 | "promoted existing ref edges!" ); |
| 920 | bool Inserted = RetainedEdges.insert(Ptr: CalleeN).second; |
| 921 | (void)Inserted; |
| 922 | assert(Inserted && "We should never visit a function twice." ); |
| 923 | if (!E) |
| 924 | NewCallEdges.insert(X: CalleeN); |
| 925 | else if (!E->isCall()) |
| 926 | PromotedRefTargets.insert(X: CalleeN); |
| 927 | } |
| 928 | } else { |
| 929 | // We can miss devirtualization if an indirect call is created then |
| 930 | // promoted before updateCGAndAnalysisManagerForPass runs. |
| 931 | auto *Entry = UR.IndirectVHs.find(Key: CB); |
| 932 | if (Entry == UR.IndirectVHs.end()) |
| 933 | UR.IndirectVHs.insert(KV: {CB, WeakTrackingVH(CB)}); |
| 934 | else if (!Entry->second) |
| 935 | Entry->second = WeakTrackingVH(CB); |
| 936 | } |
| 937 | } |
| 938 | } |
| 939 | |
| 940 | // Now walk all references. |
| 941 | for (Instruction &I : instructions(F)) |
| 942 | for (Value *Op : I.operand_values()) |
| 943 | if (auto *OpC = dyn_cast<Constant>(Val: Op)) |
| 944 | if (Visited.insert(Ptr: OpC).second) |
| 945 | Worklist.push_back(Elt: OpC); |
| 946 | |
| 947 | auto VisitRef = [&](Function &Referee) { |
| 948 | Node *RefereeN = G.lookup(F: Referee); |
| 949 | assert(RefereeN && |
| 950 | "Visited function should already have an associated node" ); |
| 951 | Edge *E = N->lookup(N&: *RefereeN); |
| 952 | assert((E || !FunctionPass) && |
| 953 | "No function transformations should introduce *new* ref " |
| 954 | "edges! Any new ref edges would require IPO which " |
| 955 | "function passes aren't allowed to do!" ); |
| 956 | bool Inserted = RetainedEdges.insert(Ptr: RefereeN).second; |
| 957 | (void)Inserted; |
| 958 | assert(Inserted && "We should never visit a function twice." ); |
| 959 | if (!E) |
| 960 | NewRefEdges.insert(X: RefereeN); |
| 961 | else if (E->isCall()) |
| 962 | DemotedCallTargets.insert(X: RefereeN); |
| 963 | }; |
| 964 | LazyCallGraph::visitReferences(Worklist, Visited, Callback: VisitRef); |
| 965 | |
| 966 | // Handle new ref edges. |
| 967 | for (Node *RefTarget : NewRefEdges) { |
| 968 | SCC &TargetC = *G.lookupSCC(N&: *RefTarget); |
| 969 | RefSCC &TargetRC = TargetC.getOuterRefSCC(); |
| 970 | (void)TargetRC; |
| 971 | // TODO: This only allows trivial edges to be added for now. |
| 972 | #ifdef EXPENSIVE_CHECKS |
| 973 | assert((RC == &TargetRC || |
| 974 | RC->isAncestorOf(TargetRC)) && "New ref edge is not trivial!" ); |
| 975 | #endif |
| 976 | RC->insertTrivialRefEdge(SourceN&: N, TargetN&: *RefTarget); |
| 977 | } |
| 978 | |
| 979 | // Handle new call edges. |
| 980 | for (Node *CallTarget : NewCallEdges) { |
| 981 | SCC &TargetC = *G.lookupSCC(N&: *CallTarget); |
| 982 | RefSCC &TargetRC = TargetC.getOuterRefSCC(); |
| 983 | (void)TargetRC; |
| 984 | // TODO: This only allows trivial edges to be added for now. |
| 985 | #ifdef EXPENSIVE_CHECKS |
| 986 | assert((RC == &TargetRC || |
| 987 | RC->isAncestorOf(TargetRC)) && "New call edge is not trivial!" ); |
| 988 | #endif |
| 989 | // Add a trivial ref edge to be promoted later on alongside |
| 990 | // PromotedRefTargets. |
| 991 | RC->insertTrivialRefEdge(SourceN&: N, TargetN&: *CallTarget); |
| 992 | } |
| 993 | |
| 994 | // Include synthetic reference edges to known, defined lib functions. |
| 995 | for (auto *LibFn : G.getLibFunctions()) |
| 996 | // While the list of lib functions doesn't have repeats, don't re-visit |
| 997 | // anything handled above. |
| 998 | if (!Visited.count(Ptr: LibFn)) |
| 999 | VisitRef(*LibFn); |
| 1000 | |
| 1001 | // First remove all of the edges that are no longer present in this function. |
| 1002 | // The first step makes these edges uniformly ref edges and accumulates them |
| 1003 | // into a separate data structure so removal doesn't invalidate anything. |
| 1004 | SmallVector<Node *, 4> DeadTargets; |
| 1005 | for (Edge &E : *N) { |
| 1006 | if (RetainedEdges.count(Ptr: &E.getNode())) |
| 1007 | continue; |
| 1008 | |
| 1009 | SCC &TargetC = *G.lookupSCC(N&: E.getNode()); |
| 1010 | RefSCC &TargetRC = TargetC.getOuterRefSCC(); |
| 1011 | if (&TargetRC == RC && E.isCall()) { |
| 1012 | if (C != &TargetC) { |
| 1013 | // For separate SCCs this is trivial. |
| 1014 | RC->switchTrivialInternalEdgeToRef(SourceN&: N, TargetN&: E.getNode()); |
| 1015 | } else { |
| 1016 | // Now update the call graph. |
| 1017 | C = incorporateNewSCCRange(NewSCCRange: RC->switchInternalEdgeToRef(SourceN&: N, TargetN&: E.getNode()), |
| 1018 | G, N, C, AM, UR); |
| 1019 | } |
| 1020 | } |
| 1021 | |
| 1022 | // Now that this is ready for actual removal, put it into our list. |
| 1023 | DeadTargets.push_back(Elt: &E.getNode()); |
| 1024 | } |
| 1025 | // Remove the easy cases quickly and actually pull them out of our list. |
| 1026 | llvm::erase_if(C&: DeadTargets, P: [&](Node *TargetN) { |
| 1027 | SCC &TargetC = *G.lookupSCC(N&: *TargetN); |
| 1028 | RefSCC &TargetRC = TargetC.getOuterRefSCC(); |
| 1029 | |
| 1030 | // We can't trivially remove internal targets, so skip |
| 1031 | // those. |
| 1032 | if (&TargetRC == RC) |
| 1033 | return false; |
| 1034 | |
| 1035 | LLVM_DEBUG(dbgs() << "Deleting outgoing edge from '" << N << "' to '" |
| 1036 | << *TargetN << "'\n" ); |
| 1037 | RC->removeOutgoingEdge(SourceN&: N, TargetN&: *TargetN); |
| 1038 | return true; |
| 1039 | }); |
| 1040 | |
| 1041 | // Next demote all the call edges that are now ref edges. This helps make |
| 1042 | // the SCCs small which should minimize the work below as we don't want to |
| 1043 | // form cycles that this would break. |
| 1044 | for (Node *RefTarget : DemotedCallTargets) { |
| 1045 | SCC &TargetC = *G.lookupSCC(N&: *RefTarget); |
| 1046 | RefSCC &TargetRC = TargetC.getOuterRefSCC(); |
| 1047 | |
| 1048 | // The easy case is when the target RefSCC is not this RefSCC. This is |
| 1049 | // only supported when the target RefSCC is a child of this RefSCC. |
| 1050 | if (&TargetRC != RC) { |
| 1051 | #ifdef EXPENSIVE_CHECKS |
| 1052 | assert(RC->isAncestorOf(TargetRC) && |
| 1053 | "Cannot potentially form RefSCC cycles here!" ); |
| 1054 | #endif |
| 1055 | RC->switchOutgoingEdgeToRef(SourceN&: N, TargetN&: *RefTarget); |
| 1056 | LLVM_DEBUG(dbgs() << "Switch outgoing call edge to a ref edge from '" << N |
| 1057 | << "' to '" << *RefTarget << "'\n" ); |
| 1058 | continue; |
| 1059 | } |
| 1060 | |
| 1061 | // We are switching an internal call edge to a ref edge. This may split up |
| 1062 | // some SCCs. |
| 1063 | if (C != &TargetC) { |
| 1064 | // For separate SCCs this is trivial. |
| 1065 | RC->switchTrivialInternalEdgeToRef(SourceN&: N, TargetN&: *RefTarget); |
| 1066 | continue; |
| 1067 | } |
| 1068 | |
| 1069 | // Now update the call graph. |
| 1070 | C = incorporateNewSCCRange(NewSCCRange: RC->switchInternalEdgeToRef(SourceN&: N, TargetN&: *RefTarget), G, N, |
| 1071 | C, AM, UR); |
| 1072 | } |
| 1073 | |
| 1074 | // We added a ref edge earlier for new call edges, promote those to call edges |
| 1075 | // alongside PromotedRefTargets. |
| 1076 | PromotedRefTargets.insert_range(R&: NewCallEdges); |
| 1077 | |
| 1078 | // Now promote ref edges into call edges. |
| 1079 | for (Node *CallTarget : PromotedRefTargets) { |
| 1080 | SCC &TargetC = *G.lookupSCC(N&: *CallTarget); |
| 1081 | RefSCC &TargetRC = TargetC.getOuterRefSCC(); |
| 1082 | |
| 1083 | // The easy case is when the target RefSCC is not this RefSCC. This is |
| 1084 | // only supported when the target RefSCC is a child of this RefSCC. |
| 1085 | if (&TargetRC != RC) { |
| 1086 | #ifdef EXPENSIVE_CHECKS |
| 1087 | assert(RC->isAncestorOf(TargetRC) && |
| 1088 | "Cannot potentially form RefSCC cycles here!" ); |
| 1089 | #endif |
| 1090 | RC->switchOutgoingEdgeToCall(SourceN&: N, TargetN&: *CallTarget); |
| 1091 | LLVM_DEBUG(dbgs() << "Switch outgoing ref edge to a call edge from '" << N |
| 1092 | << "' to '" << *CallTarget << "'\n" ); |
| 1093 | continue; |
| 1094 | } |
| 1095 | LLVM_DEBUG(dbgs() << "Switch an internal ref edge to a call edge from '" |
| 1096 | << N << "' to '" << *CallTarget << "'\n" ); |
| 1097 | |
| 1098 | // Otherwise we are switching an internal ref edge to a call edge. This |
| 1099 | // may merge away some SCCs, and we add those to the UpdateResult. We also |
| 1100 | // need to make sure to update the worklist in the event SCCs have moved |
| 1101 | // before the current one in the post-order sequence |
| 1102 | bool HasFunctionAnalysisProxy = false; |
| 1103 | auto InitialSCCIndex = RC->find(C&: *C) - RC->begin(); |
| 1104 | bool FormedCycle = RC->switchInternalEdgeToCall( |
| 1105 | SourceN&: N, TargetN&: *CallTarget, MergeCB: [&](ArrayRef<SCC *> MergedSCCs) { |
| 1106 | for (SCC *MergedC : MergedSCCs) { |
| 1107 | assert(MergedC != &TargetC && "Cannot merge away the target SCC!" ); |
| 1108 | |
| 1109 | HasFunctionAnalysisProxy |= |
| 1110 | AM.getCachedResult<FunctionAnalysisManagerCGSCCProxy>( |
| 1111 | IR&: *MergedC) != nullptr; |
| 1112 | |
| 1113 | // Mark that this SCC will no longer be valid. |
| 1114 | UR.InvalidatedSCCs.insert(Ptr: MergedC); |
| 1115 | |
| 1116 | // FIXME: We should really do a 'clear' here to forcibly release |
| 1117 | // memory, but we don't have a good way of doing that and |
| 1118 | // preserving the function analyses. |
| 1119 | auto PA = PreservedAnalyses::allInSet<AllAnalysesOn<Function>>(); |
| 1120 | PA.preserve<FunctionAnalysisManagerCGSCCProxy>(); |
| 1121 | AM.invalidate(IR&: *MergedC, PA); |
| 1122 | } |
| 1123 | }); |
| 1124 | |
| 1125 | // If we formed a cycle by creating this call, we need to update more data |
| 1126 | // structures. |
| 1127 | if (FormedCycle) { |
| 1128 | C = &TargetC; |
| 1129 | assert(G.lookupSCC(N) == C && "Failed to update current SCC!" ); |
| 1130 | |
| 1131 | // If one of the invalidated SCCs had a cached proxy to a function |
| 1132 | // analysis manager, we need to create a proxy in the new current SCC as |
| 1133 | // the invalidated SCCs had their functions moved. |
| 1134 | if (HasFunctionAnalysisProxy) |
| 1135 | AM.getResult<FunctionAnalysisManagerCGSCCProxy>(IR&: *C, ExtraArgs&: G).updateFAM(FAM); |
| 1136 | |
| 1137 | // Any analyses cached for this SCC are no longer precise as the shape |
| 1138 | // has changed by introducing this cycle. However, we have taken care to |
| 1139 | // update the proxies so it remains valide. |
| 1140 | auto PA = PreservedAnalyses::allInSet<AllAnalysesOn<Function>>(); |
| 1141 | PA.preserve<FunctionAnalysisManagerCGSCCProxy>(); |
| 1142 | AM.invalidate(IR&: *C, PA); |
| 1143 | } |
| 1144 | auto NewSCCIndex = RC->find(C&: *C) - RC->begin(); |
| 1145 | // If we have actually moved an SCC to be topologically "below" the current |
| 1146 | // one due to merging, we will need to revisit the current SCC after |
| 1147 | // visiting those moved SCCs. |
| 1148 | // |
| 1149 | // It is critical that we *do not* revisit the current SCC unless we |
| 1150 | // actually move SCCs in the process of merging because otherwise we may |
| 1151 | // form a cycle where an SCC is split apart, merged, split, merged and so |
| 1152 | // on infinitely. |
| 1153 | if (InitialSCCIndex < NewSCCIndex) { |
| 1154 | // Put our current SCC back onto the worklist as we'll visit other SCCs |
| 1155 | // that are now definitively ordered prior to the current one in the |
| 1156 | // post-order sequence, and may end up observing more precise context to |
| 1157 | // optimize the current SCC. |
| 1158 | UR.CWorklist.insert(X: C); |
| 1159 | LLVM_DEBUG(dbgs() << "Enqueuing the existing SCC in the worklist: " << *C |
| 1160 | << "\n" ); |
| 1161 | // Enqueue in reverse order as we pop off the back of the worklist. |
| 1162 | for (SCC &MovedC : llvm::reverse(C: make_range(x: RC->begin() + InitialSCCIndex, |
| 1163 | y: RC->begin() + NewSCCIndex))) { |
| 1164 | UR.CWorklist.insert(X: &MovedC); |
| 1165 | LLVM_DEBUG(dbgs() << "Enqueuing a newly earlier in post-order SCC: " |
| 1166 | << MovedC << "\n" ); |
| 1167 | } |
| 1168 | } |
| 1169 | } |
| 1170 | |
| 1171 | assert(!UR.InvalidatedSCCs.count(C) && "Invalidated the current SCC!" ); |
| 1172 | assert(&C->getOuterRefSCC() == RC && "Current SCC not in current RefSCC!" ); |
| 1173 | |
| 1174 | // Record the current SCC for higher layers of the CGSCC pass manager now that |
| 1175 | // all the updates have been applied. |
| 1176 | if (C != &InitialC) |
| 1177 | UR.UpdatedC = C; |
| 1178 | |
| 1179 | return *C; |
| 1180 | } |
| 1181 | |
| 1182 | LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass( |
| 1183 | LazyCallGraph &G, LazyCallGraph::SCC &InitialC, LazyCallGraph::Node &N, |
| 1184 | CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, |
| 1185 | FunctionAnalysisManager &FAM) { |
| 1186 | return updateCGAndAnalysisManagerForPass(G, InitialC, N, AM, UR, FAM, |
| 1187 | /* FunctionPass */ true); |
| 1188 | } |
| 1189 | LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForCGSCCPass( |
| 1190 | LazyCallGraph &G, LazyCallGraph::SCC &InitialC, LazyCallGraph::Node &N, |
| 1191 | CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, |
| 1192 | FunctionAnalysisManager &FAM) { |
| 1193 | return updateCGAndAnalysisManagerForPass(G, InitialC, N, AM, UR, FAM, |
| 1194 | /* FunctionPass */ false); |
| 1195 | } |
| 1196 | |