56
56
#include " llvm/Transforms/Utils/LCSSA.h"
57
57
#include " llvm/Transforms/Utils/LoopSimplify.h"
58
58
#include " llvm/Transforms/Utils/LoopUtils.h"
59
+ #include < memory>
59
60
60
61
namespace llvm {
61
62
@@ -105,7 +106,7 @@ using RequireAnalysisLoopPass =
105
106
RequireAnalysisPass<AnalysisT, Loop, LoopAnalysisManager,
106
107
LoopStandardAnalysisResults &, LPMUpdater &>;
107
108
108
- template < typename LoopPassT> class FunctionToLoopPassAdaptor ;
109
+ class FunctionToLoopPassAdaptor ;
109
110
110
111
// / This class provides an interface for updating the loop pass manager based
111
112
// / on mutations to the loop nest.
@@ -200,7 +201,7 @@ class LPMUpdater {
200
201
}
201
202
202
203
private:
203
- template < typename LoopPassT> friend class llvm ::FunctionToLoopPassAdaptor;
204
+ friend class llvm ::FunctionToLoopPassAdaptor;
204
205
205
206
// / The \c FunctionToLoopPassAdaptor's worklist of loops to process.
206
207
SmallPriorityWorklist<Loop *, 4 > &Worklist;
@@ -229,11 +230,15 @@ class LPMUpdater {
229
230
// / FunctionAnalysisManager it will run the \c LoopAnalysisManagerFunctionProxy
230
231
// / analysis prior to running the loop passes over the function to enable a \c
231
232
// / LoopAnalysisManager to be used within this run safely.
232
- template <typename LoopPassT>
233
233
class FunctionToLoopPassAdaptor
234
- : public PassInfoMixin<FunctionToLoopPassAdaptor<LoopPassT> > {
234
+ : public PassInfoMixin<FunctionToLoopPassAdaptor> {
235
235
public:
236
- explicit FunctionToLoopPassAdaptor (LoopPassT Pass, bool UseMemorySSA = false ,
236
+ using PassConceptT =
237
+ detail::PassConcept<Loop, LoopAnalysisManager,
238
+ LoopStandardAnalysisResults &, LPMUpdater &>;
239
+
240
+ explicit FunctionToLoopPassAdaptor (std::unique_ptr<PassConceptT> Pass,
241
+ bool UseMemorySSA = false ,
237
242
bool UseBlockFrequencyInfo = false ,
238
243
bool DebugLogging = false )
239
244
: Pass(std::move(Pass)), LoopCanonicalizationFPM(DebugLogging),
@@ -244,156 +249,12 @@ class FunctionToLoopPassAdaptor
244
249
}
245
250
246
251
// / Runs the loop passes across every loop in the function.
247
- PreservedAnalyses run (Function &F, FunctionAnalysisManager &AM) {
248
- // Before we even compute any loop analyses, first run a miniature function
249
- // pass pipeline to put loops into their canonical form. Note that we can
250
- // directly build up function analyses after this as the function pass
251
- // manager handles all the invalidation at that layer.
252
- PassInstrumentation PI = AM.getResult <PassInstrumentationAnalysis>(F);
253
-
254
- PreservedAnalyses PA = PreservedAnalyses::all ();
255
- // Check the PassInstrumentation's BeforePass callbacks before running the
256
- // canonicalization pipeline.
257
- if (PI.runBeforePass <Function>(LoopCanonicalizationFPM, F)) {
258
- PA = LoopCanonicalizationFPM.run (F, AM);
259
- PI.runAfterPass <Function>(LoopCanonicalizationFPM, F, PA);
260
- }
261
-
262
- // Get the loop structure for this function
263
- LoopInfo &LI = AM.getResult <LoopAnalysis>(F);
264
-
265
- // If there are no loops, there is nothing to do here.
266
- if (LI.empty ())
267
- return PA;
268
-
269
- // Get the analysis results needed by loop passes.
270
- MemorySSA *MSSA = UseMemorySSA
271
- ? (&AM.getResult <MemorySSAAnalysis>(F).getMSSA ())
272
- : nullptr ;
273
- BlockFrequencyInfo *BFI = UseBlockFrequencyInfo && F.hasProfileData ()
274
- ? (&AM.getResult <BlockFrequencyAnalysis>(F))
275
- : nullptr ;
276
- LoopStandardAnalysisResults LAR = {AM.getResult <AAManager>(F),
277
- AM.getResult <AssumptionAnalysis>(F),
278
- AM.getResult <DominatorTreeAnalysis>(F),
279
- AM.getResult <LoopAnalysis>(F),
280
- AM.getResult <ScalarEvolutionAnalysis>(F),
281
- AM.getResult <TargetLibraryAnalysis>(F),
282
- AM.getResult <TargetIRAnalysis>(F),
283
- BFI,
284
- MSSA};
285
-
286
- // Setup the loop analysis manager from its proxy. It is important that
287
- // this is only done when there are loops to process and we have built the
288
- // LoopStandardAnalysisResults object. The loop analyses cached in this
289
- // manager have access to those analysis results and so it must invalidate
290
- // itself when they go away.
291
- auto &LAMFP = AM.getResult <LoopAnalysisManagerFunctionProxy>(F);
292
- if (UseMemorySSA)
293
- LAMFP.markMSSAUsed ();
294
- LoopAnalysisManager &LAM = LAMFP.getManager ();
295
-
296
- // A postorder worklist of loops to process.
297
- SmallPriorityWorklist<Loop *, 4 > Worklist;
298
-
299
- // Register the worklist and loop analysis manager so that loop passes can
300
- // update them when they mutate the loop nest structure.
301
- LPMUpdater Updater (Worklist, LAM);
302
-
303
- // Add the loop nests in the reverse order of LoopInfo. See method
304
- // declaration.
305
- appendLoopsToWorklist (LI, Worklist);
306
-
307
- #ifndef NDEBUG
308
- PI.pushBeforeNonSkippedPassCallback ([&LAR, &LI](StringRef PassID, Any IR) {
309
- if (isSpecialPass (PassID, {" PassManager" }))
310
- return ;
311
- assert (any_isa<const Loop *>(IR));
312
- const Loop *L = any_cast<const Loop *>(IR);
313
- assert (L && " Loop should be valid for printing" );
314
-
315
- // Verify the loop structure and LCSSA form before visiting the loop.
316
- L->verifyLoop ();
317
- assert (L->isRecursivelyLCSSAForm (LAR.DT , LI) &&
318
- " Loops must remain in LCSSA form!" );
319
- });
320
- #endif
321
-
322
- do {
323
- Loop *L = Worklist.pop_back_val ();
324
-
325
- // Reset the update structure for this loop.
326
- Updater.CurrentL = L;
327
- Updater.SkipCurrentLoop = false ;
328
-
329
- #ifndef NDEBUG
330
- // Save a parent loop pointer for asserts.
331
- Updater.ParentL = L->getParentLoop ();
332
- #endif
333
- // Check the PassInstrumentation's BeforePass callbacks before running the
334
- // pass, skip its execution completely if asked to (callback returns
335
- // false).
336
- if (!PI.runBeforePass <Loop>(Pass, *L))
337
- continue ;
338
-
339
- PreservedAnalyses PassPA;
340
- {
341
- TimeTraceScope TimeScope (Pass.name ());
342
- PassPA = Pass.run (*L, LAM, LAR, Updater);
343
- }
344
-
345
- // Do not pass deleted Loop into the instrumentation.
346
- if (Updater.skipCurrentLoop ())
347
- PI.runAfterPassInvalidated <Loop>(Pass, PassPA);
348
- else
349
- PI.runAfterPass <Loop>(Pass, *L, PassPA);
350
-
351
- // FIXME: We should verify the set of analyses relevant to Loop passes
352
- // are preserved.
353
-
354
- // If the loop hasn't been deleted, we need to handle invalidation here.
355
- if (!Updater.skipCurrentLoop ())
356
- // We know that the loop pass couldn't have invalidated any other
357
- // loop's analyses (that's the contract of a loop pass), so directly
358
- // handle the loop analysis manager's invalidation here.
359
- LAM.invalidate (*L, PassPA);
360
-
361
- // Then intersect the preserved set so that invalidation of module
362
- // analyses will eventually occur when the module pass completes.
363
- PA.intersect (std::move (PassPA));
364
- } while (!Worklist.empty ());
365
-
366
- #ifndef NDEBUG
367
- PI.popBeforeNonSkippedPassCallback ();
368
- #endif
369
-
370
- // By definition we preserve the proxy. We also preserve all analyses on
371
- // Loops. This precludes *any* invalidation of loop analyses by the proxy,
372
- // but that's OK because we've taken care to invalidate analyses in the
373
- // loop analysis manager incrementally above.
374
- PA.preserveSet <AllAnalysesOn<Loop>>();
375
- PA.preserve <LoopAnalysisManagerFunctionProxy>();
376
- // We also preserve the set of standard analyses.
377
- PA.preserve <DominatorTreeAnalysis>();
378
- PA.preserve <LoopAnalysis>();
379
- PA.preserve <ScalarEvolutionAnalysis>();
380
- if (UseBlockFrequencyInfo && F.hasProfileData ())
381
- PA.preserve <BlockFrequencyAnalysis>();
382
- if (UseMemorySSA)
383
- PA.preserve <MemorySSAAnalysis>();
384
- // FIXME: What we really want to do here is preserve an AA category, but
385
- // that concept doesn't exist yet.
386
- PA.preserve <AAManager>();
387
- PA.preserve <BasicAA>();
388
- PA.preserve <GlobalsAA>();
389
- PA.preserve <SCEVAA>();
390
- return PA;
391
- }
252
+ PreservedAnalyses run (Function &F, FunctionAnalysisManager &AM);
392
253
393
254
static bool isRequired () { return true ; }
394
255
395
256
private:
396
- LoopPassT Pass;
257
+ std::unique_ptr<PassConceptT> Pass;
397
258
398
259
FunctionPassManager LoopCanonicalizationFPM;
399
260
@@ -404,12 +265,16 @@ class FunctionToLoopPassAdaptor
404
265
// / A function to deduce a loop pass type and wrap it in the templated
405
266
// / adaptor.
406
267
template <typename LoopPassT>
407
- FunctionToLoopPassAdaptor<LoopPassT>
268
+ FunctionToLoopPassAdaptor
408
269
createFunctionToLoopPassAdaptor (LoopPassT Pass, bool UseMemorySSA = false ,
409
270
bool UseBlockFrequencyInfo = false ,
410
271
bool DebugLogging = false ) {
411
- return FunctionToLoopPassAdaptor<LoopPassT>(
412
- std::move (Pass), UseMemorySSA, UseBlockFrequencyInfo, DebugLogging);
272
+ using PassModelT =
273
+ detail::PassModel<Loop, LoopPassT, PreservedAnalyses, LoopAnalysisManager,
274
+ LoopStandardAnalysisResults &, LPMUpdater &>;
275
+ return FunctionToLoopPassAdaptor (
276
+ std::make_unique<PassModelT>(std::move (Pass)), UseMemorySSA,
277
+ UseBlockFrequencyInfo, DebugLogging);
413
278
}
414
279
415
280
// / Pass for printing a loop's contents as textual IR.
0 commit comments