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