1 //===- LoopPassManager.h - Loop pass management -----------------*- C++ -*-===// 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 /// \file 9 /// 10 /// This header provides classes for managing a pipeline of passes over loops 11 /// in LLVM IR. 12 /// 13 /// The primary loop pass pipeline is managed in a very particular way to 14 /// provide a set of core guarantees: 15 /// 1) Loops are, where possible, in simplified form. 16 /// 2) Loops are *always* in LCSSA form. 17 /// 3) A collection of Loop-specific analysis results are available: 18 /// - LoopInfo 19 /// - DominatorTree 20 /// - ScalarEvolution 21 /// - AAManager 22 /// 4) All loop passes preserve #1 (where possible), #2, and #3. 23 /// 5) Loop passes run over each loop in the loop nest from the innermost to 24 /// the outermost. Specifically, all inner loops are processed before 25 /// passes run over outer loops. When running the pipeline across an inner 26 /// loop creates new inner loops, those are added and processed in this 27 /// order as well. 28 /// 29 /// This process is designed to facilitate transformations which simplify, 30 /// reduce, and remove loops. For passes which are more oriented towards 31 /// optimizing loops, especially optimizing loop *nests* instead of single 32 /// loops in isolation, this framework is less interesting. 33 /// 34 //===----------------------------------------------------------------------===// 35 36 #ifndef LLVM_TRANSFORMS_SCALAR_LOOPPASSMANAGER_H 37 #define LLVM_TRANSFORMS_SCALAR_LOOPPASSMANAGER_H 38 39 #include "llvm/ADT/PriorityWorklist.h" 40 #include "llvm/Analysis/LoopAnalysisManager.h" 41 #include "llvm/Analysis/LoopInfo.h" 42 #include "llvm/Analysis/LoopNestAnalysis.h" 43 #include "llvm/IR/PassManager.h" 44 #include "llvm/Transforms/Utils/LCSSA.h" 45 #include "llvm/Transforms/Utils/LoopSimplify.h" 46 #include "llvm/Transforms/Utils/LoopUtils.h" 47 #include <memory> 48 49 namespace llvm { 50 51 // Forward declarations of an update tracking API used in the pass manager. 52 class LPMUpdater; 53 class PassInstrumentation; 54 55 namespace { 56 57 template <typename PassT> 58 using HasRunOnLoopT = decltype(std::declval<PassT>().run( 59 std::declval<Loop &>(), std::declval<LoopAnalysisManager &>(), 60 std::declval<LoopStandardAnalysisResults &>(), 61 std::declval<LPMUpdater &>())); 62 63 } // namespace 64 65 // Explicit specialization and instantiation declarations for the pass manager. 66 // See the comments on the definition of the specialization for details on how 67 // it differs from the primary template. 68 template <> 69 class PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, 70 LPMUpdater &> 71 : public PassInfoMixin< 72 PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, 73 LPMUpdater &>> { 74 public: 75 explicit PassManager() = default; 76 77 // FIXME: These are equivalent to the default move constructor/move 78 // assignment. However, using = default triggers linker errors due to the 79 // explicit instantiations below. Find a way to use the default and remove the 80 // duplicated code here. PassManager(PassManager && Arg)81 PassManager(PassManager &&Arg) 82 : IsLoopNestPass(std::move(Arg.IsLoopNestPass)), 83 LoopPasses(std::move(Arg.LoopPasses)), 84 LoopNestPasses(std::move(Arg.LoopNestPasses)) {} 85 86 PassManager &operator=(PassManager &&RHS) { 87 IsLoopNestPass = std::move(RHS.IsLoopNestPass); 88 LoopPasses = std::move(RHS.LoopPasses); 89 LoopNestPasses = std::move(RHS.LoopNestPasses); 90 return *this; 91 } 92 93 PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, 94 LoopStandardAnalysisResults &AR, LPMUpdater &U); 95 96 void printPipeline(raw_ostream &OS, 97 function_ref<StringRef(StringRef)> MapClassName2PassName); 98 /// Add either a loop pass or a loop-nest pass to the pass manager. Append \p 99 /// Pass to the list of loop passes if it has a dedicated \fn run() method for 100 /// loops and to the list of loop-nest passes if the \fn run() method is for 101 /// loop-nests instead. Also append whether \p Pass is loop-nest pass or not 102 /// to the end of \var IsLoopNestPass so we can easily identify the types of 103 /// passes in the pass manager later. 104 template <typename PassT> 105 LLVM_ATTRIBUTE_MINSIZE 106 std::enable_if_t<is_detected<HasRunOnLoopT, PassT>::value> addPass(PassT && Pass)107 addPass(PassT &&Pass) { 108 using LoopPassModelT = 109 detail::PassModel<Loop, PassT, PreservedAnalyses, LoopAnalysisManager, 110 LoopStandardAnalysisResults &, LPMUpdater &>; 111 IsLoopNestPass.push_back(false); 112 // Do not use make_unique or emplace_back, they cause too many template 113 // instantiations, causing terrible compile times. 114 LoopPasses.push_back(std::unique_ptr<LoopPassConceptT>( 115 new LoopPassModelT(std::forward<PassT>(Pass)))); 116 } 117 118 template <typename PassT> 119 LLVM_ATTRIBUTE_MINSIZE 120 std::enable_if_t<!is_detected<HasRunOnLoopT, PassT>::value> addPass(PassT && Pass)121 addPass(PassT &&Pass) { 122 using LoopNestPassModelT = 123 detail::PassModel<LoopNest, PassT, PreservedAnalyses, 124 LoopAnalysisManager, LoopStandardAnalysisResults &, 125 LPMUpdater &>; 126 IsLoopNestPass.push_back(true); 127 // Do not use make_unique or emplace_back, they cause too many template 128 // instantiations, causing terrible compile times. 129 LoopNestPasses.push_back(std::unique_ptr<LoopNestPassConceptT>( 130 new LoopNestPassModelT(std::forward<PassT>(Pass)))); 131 } 132 133 // Specializations of `addPass` for `RepeatedPass`. These are necessary since 134 // `RepeatedPass` has a templated `run` method that will result in incorrect 135 // detection of `HasRunOnLoopT`. 136 template <typename PassT> 137 LLVM_ATTRIBUTE_MINSIZE 138 std::enable_if_t<is_detected<HasRunOnLoopT, PassT>::value> addPass(RepeatedPass<PassT> && Pass)139 addPass(RepeatedPass<PassT> &&Pass) { 140 using RepeatedLoopPassModelT = 141 detail::PassModel<Loop, RepeatedPass<PassT>, PreservedAnalyses, 142 LoopAnalysisManager, LoopStandardAnalysisResults &, 143 LPMUpdater &>; 144 IsLoopNestPass.push_back(false); 145 // Do not use make_unique or emplace_back, they cause too many template 146 // instantiations, causing terrible compile times. 147 LoopPasses.push_back(std::unique_ptr<LoopPassConceptT>( 148 new RepeatedLoopPassModelT(std::move(Pass)))); 149 } 150 151 template <typename PassT> 152 LLVM_ATTRIBUTE_MINSIZE 153 std::enable_if_t<!is_detected<HasRunOnLoopT, PassT>::value> addPass(RepeatedPass<PassT> && Pass)154 addPass(RepeatedPass<PassT> &&Pass) { 155 using RepeatedLoopNestPassModelT = 156 detail::PassModel<LoopNest, RepeatedPass<PassT>, PreservedAnalyses, 157 LoopAnalysisManager, LoopStandardAnalysisResults &, 158 LPMUpdater &>; 159 IsLoopNestPass.push_back(true); 160 // Do not use make_unique or emplace_back, they cause too many template 161 // instantiations, causing terrible compile times. 162 LoopNestPasses.push_back(std::unique_ptr<LoopNestPassConceptT>( 163 new RepeatedLoopNestPassModelT(std::move(Pass)))); 164 } 165 isEmpty()166 bool isEmpty() const { return LoopPasses.empty() && LoopNestPasses.empty(); } 167 isRequired()168 static bool isRequired() { return true; } 169 getNumLoopPasses()170 size_t getNumLoopPasses() const { return LoopPasses.size(); } getNumLoopNestPasses()171 size_t getNumLoopNestPasses() const { return LoopNestPasses.size(); } 172 173 protected: 174 using LoopPassConceptT = 175 detail::PassConcept<Loop, LoopAnalysisManager, 176 LoopStandardAnalysisResults &, LPMUpdater &>; 177 using LoopNestPassConceptT = 178 detail::PassConcept<LoopNest, LoopAnalysisManager, 179 LoopStandardAnalysisResults &, LPMUpdater &>; 180 181 // BitVector that identifies whether the passes are loop passes or loop-nest 182 // passes (true for loop-nest passes). 183 BitVector IsLoopNestPass; 184 std::vector<std::unique_ptr<LoopPassConceptT>> LoopPasses; 185 std::vector<std::unique_ptr<LoopNestPassConceptT>> LoopNestPasses; 186 187 /// Run either a loop pass or a loop-nest pass. Returns `std::nullopt` if 188 /// PassInstrumentation's BeforePass returns false. Otherwise, returns the 189 /// preserved analyses of the pass. 190 template <typename IRUnitT, typename PassT> 191 std::optional<PreservedAnalyses> 192 runSinglePass(IRUnitT &IR, PassT &Pass, LoopAnalysisManager &AM, 193 LoopStandardAnalysisResults &AR, LPMUpdater &U, 194 PassInstrumentation &PI); 195 196 PreservedAnalyses runWithLoopNestPasses(Loop &L, LoopAnalysisManager &AM, 197 LoopStandardAnalysisResults &AR, 198 LPMUpdater &U); 199 PreservedAnalyses runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM, 200 LoopStandardAnalysisResults &AR, 201 LPMUpdater &U); 202 203 private: getLoopFromIR(Loop & L)204 static const Loop &getLoopFromIR(Loop &L) { return L; } getLoopFromIR(LoopNest & LN)205 static const Loop &getLoopFromIR(LoopNest &LN) { 206 return LN.getOutermostLoop(); 207 } 208 }; 209 210 /// The Loop pass manager. 211 /// 212 /// See the documentation for the PassManager template for details. It runs 213 /// a sequence of Loop passes over each Loop that the manager is run over. This 214 /// typedef serves as a convenient way to refer to this construct. 215 typedef PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, 216 LPMUpdater &> 217 LoopPassManager; 218 219 /// A partial specialization of the require analysis template pass to forward 220 /// the extra parameters from a transformation's run method to the 221 /// AnalysisManager's getResult. 222 template <typename AnalysisT> 223 struct RequireAnalysisPass<AnalysisT, Loop, LoopAnalysisManager, 224 LoopStandardAnalysisResults &, LPMUpdater &> 225 : PassInfoMixin< 226 RequireAnalysisPass<AnalysisT, Loop, LoopAnalysisManager, 227 LoopStandardAnalysisResults &, LPMUpdater &>> { 228 PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, 229 LoopStandardAnalysisResults &AR, LPMUpdater &) { 230 (void)AM.template getResult<AnalysisT>(L, AR); 231 return PreservedAnalyses::all(); 232 } 233 void printPipeline(raw_ostream &OS, 234 function_ref<StringRef(StringRef)> MapClassName2PassName) { 235 auto ClassName = AnalysisT::name(); 236 auto PassName = MapClassName2PassName(ClassName); 237 OS << "require<" << PassName << ">"; 238 } 239 }; 240 241 /// An alias template to easily name a require analysis loop pass. 242 template <typename AnalysisT> 243 using RequireAnalysisLoopPass = 244 RequireAnalysisPass<AnalysisT, Loop, LoopAnalysisManager, 245 LoopStandardAnalysisResults &, LPMUpdater &>; 246 247 class FunctionToLoopPassAdaptor; 248 249 /// This class provides an interface for updating the loop pass manager based 250 /// on mutations to the loop nest. 251 /// 252 /// A reference to an instance of this class is passed as an argument to each 253 /// Loop pass, and Loop passes should use it to update LPM infrastructure if 254 /// they modify the loop nest structure. 255 /// 256 /// \c LPMUpdater comes with two modes: the loop mode and the loop-nest mode. In 257 /// loop mode, all the loops in the function will be pushed into the worklist 258 /// and when new loops are added to the pipeline, their subloops are also 259 /// inserted recursively. On the other hand, in loop-nest mode, only top-level 260 /// loops are contained in the worklist and the addition of new (top-level) 261 /// loops will not trigger the addition of their subloops. 262 class LPMUpdater { 263 public: 264 /// This can be queried by loop passes which run other loop passes (like pass 265 /// managers) to know whether the loop needs to be skipped due to updates to 266 /// the loop nest. 267 /// 268 /// If this returns true, the loop object may have been deleted, so passes 269 /// should take care not to touch the object. 270 bool skipCurrentLoop() const { return SkipCurrentLoop; } 271 272 /// Loop passes should use this method to indicate they have deleted a loop 273 /// from the nest. 274 /// 275 /// Note that this loop must either be the current loop or a subloop of the 276 /// current loop. This routine must be called prior to removing the loop from 277 /// the loop nest. 278 /// 279 /// If this is called for the current loop, in addition to clearing any 280 /// state, this routine will mark that the current loop should be skipped by 281 /// the rest of the pass management infrastructure. 282 void markLoopAsDeleted(Loop &L, llvm::StringRef Name) { 283 LAM.clear(L, Name); 284 assert((&L == CurrentL || CurrentL->contains(&L)) && 285 "Cannot delete a loop outside of the " 286 "subloop tree currently being processed."); 287 if (&L == CurrentL) 288 SkipCurrentLoop = true; 289 } 290 291 void setParentLoop(Loop *L) { 292 #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS 293 ParentL = L; 294 #endif 295 } 296 297 /// Loop passes should use this method to indicate they have added new child 298 /// loops of the current loop. 299 /// 300 /// \p NewChildLoops must contain only the immediate children. Any nested 301 /// loops within them will be visited in postorder as usual for the loop pass 302 /// manager. 303 void addChildLoops(ArrayRef<Loop *> NewChildLoops) { 304 assert(!LoopNestMode && 305 "Child loops should not be pushed in loop-nest mode."); 306 // Insert ourselves back into the worklist first, as this loop should be 307 // revisited after all the children have been processed. 308 Worklist.insert(CurrentL); 309 310 #ifndef NDEBUG 311 for (Loop *NewL : NewChildLoops) 312 assert(NewL->getParentLoop() == CurrentL && "All of the new loops must " 313 "be immediate children of " 314 "the current loop!"); 315 #endif 316 317 appendLoopsToWorklist(NewChildLoops, Worklist); 318 319 // Also skip further processing of the current loop--it will be revisited 320 // after all of its newly added children are accounted for. 321 SkipCurrentLoop = true; 322 } 323 324 /// Loop passes should use this method to indicate they have added new 325 /// sibling loops to the current loop. 326 /// 327 /// \p NewSibLoops must only contain the immediate sibling loops. Any nested 328 /// loops within them will be visited in postorder as usual for the loop pass 329 /// manager. 330 void addSiblingLoops(ArrayRef<Loop *> NewSibLoops) { 331 #if defined(LLVM_ENABLE_ABI_BREAKING_CHECKS) && !defined(NDEBUG) 332 for (Loop *NewL : NewSibLoops) 333 assert(NewL->getParentLoop() == ParentL && 334 "All of the new loops must be siblings of the current loop!"); 335 #endif 336 337 if (LoopNestMode) 338 Worklist.insert(NewSibLoops); 339 else 340 appendLoopsToWorklist(NewSibLoops, Worklist); 341 342 // No need to skip the current loop or revisit it, as sibling loops 343 // shouldn't impact anything. 344 } 345 346 /// Restart the current loop. 347 /// 348 /// Loop passes should call this method to indicate the current loop has been 349 /// sufficiently changed that it should be re-visited from the begining of 350 /// the loop pass pipeline rather than continuing. 351 void revisitCurrentLoop() { 352 // Tell the currently in-flight pipeline to stop running. 353 SkipCurrentLoop = true; 354 355 // And insert ourselves back into the worklist. 356 Worklist.insert(CurrentL); 357 } 358 359 bool isLoopNestChanged() const { 360 return LoopNestChanged; 361 } 362 363 /// Loopnest passes should use this method to indicate if the 364 /// loopnest has been modified. 365 void markLoopNestChanged(bool Changed) { 366 LoopNestChanged = Changed; 367 } 368 369 private: 370 friend class llvm::FunctionToLoopPassAdaptor; 371 372 /// The \c FunctionToLoopPassAdaptor's worklist of loops to process. 373 SmallPriorityWorklist<Loop *, 4> &Worklist; 374 375 /// The analysis manager for use in the current loop nest. 376 LoopAnalysisManager &LAM; 377 378 Loop *CurrentL; 379 bool SkipCurrentLoop; 380 const bool LoopNestMode; 381 bool LoopNestChanged; 382 383 #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS 384 // In debug builds we also track the parent loop to implement asserts even in 385 // the face of loop deletion. 386 Loop *ParentL; 387 #endif 388 389 LPMUpdater(SmallPriorityWorklist<Loop *, 4> &Worklist, 390 LoopAnalysisManager &LAM, bool LoopNestMode = false, 391 bool LoopNestChanged = false) 392 : Worklist(Worklist), LAM(LAM), LoopNestMode(LoopNestMode), 393 LoopNestChanged(LoopNestChanged) {} 394 }; 395 396 template <typename IRUnitT, typename PassT> 397 std::optional<PreservedAnalyses> LoopPassManager::runSinglePass( 398 IRUnitT &IR, PassT &Pass, LoopAnalysisManager &AM, 399 LoopStandardAnalysisResults &AR, LPMUpdater &U, PassInstrumentation &PI) { 400 // Get the loop in case of Loop pass and outermost loop in case of LoopNest 401 // pass which is to be passed to BeforePass and AfterPass call backs. 402 const Loop &L = getLoopFromIR(IR); 403 // Check the PassInstrumentation's BeforePass callbacks before running the 404 // pass, skip its execution completely if asked to (callback returns false). 405 if (!PI.runBeforePass<Loop>(*Pass, L)) 406 return std::nullopt; 407 408 PreservedAnalyses PA = Pass->run(IR, AM, AR, U); 409 410 // do not pass deleted Loop into the instrumentation 411 if (U.skipCurrentLoop()) 412 PI.runAfterPassInvalidated<IRUnitT>(*Pass, PA); 413 else 414 PI.runAfterPass<Loop>(*Pass, L, PA); 415 return PA; 416 } 417 418 /// Adaptor that maps from a function to its loops. 419 /// 420 /// Designed to allow composition of a LoopPass(Manager) and a 421 /// FunctionPassManager. Note that if this pass is constructed with a \c 422 /// FunctionAnalysisManager it will run the \c LoopAnalysisManagerFunctionProxy 423 /// analysis prior to running the loop passes over the function to enable a \c 424 /// LoopAnalysisManager to be used within this run safely. 425 /// 426 /// The adaptor comes with two modes: the loop mode and the loop-nest mode, and 427 /// the worklist updater lived inside will be in the same mode as the adaptor 428 /// (refer to the documentation of \c LPMUpdater for more detailed explanation). 429 /// Specifically, in loop mode, all loops in the funciton will be pushed into 430 /// the worklist and processed by \p Pass, while only top-level loops are 431 /// processed in loop-nest mode. Please refer to the various specializations of 432 /// \fn createLoopFunctionToLoopPassAdaptor to see when loop mode and loop-nest 433 /// mode are used. 434 class FunctionToLoopPassAdaptor 435 : public PassInfoMixin<FunctionToLoopPassAdaptor> { 436 public: 437 using PassConceptT = 438 detail::PassConcept<Loop, LoopAnalysisManager, 439 LoopStandardAnalysisResults &, LPMUpdater &>; 440 441 explicit FunctionToLoopPassAdaptor(std::unique_ptr<PassConceptT> Pass, 442 bool UseMemorySSA = false, 443 bool UseBlockFrequencyInfo = false, 444 bool UseBranchProbabilityInfo = false, 445 bool LoopNestMode = false) 446 : Pass(std::move(Pass)), UseMemorySSA(UseMemorySSA), 447 UseBlockFrequencyInfo(UseBlockFrequencyInfo), 448 UseBranchProbabilityInfo(UseBranchProbabilityInfo), 449 LoopNestMode(LoopNestMode) { 450 LoopCanonicalizationFPM.addPass(LoopSimplifyPass()); 451 LoopCanonicalizationFPM.addPass(LCSSAPass()); 452 } 453 454 /// Runs the loop passes across every loop in the function. 455 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 456 void printPipeline(raw_ostream &OS, 457 function_ref<StringRef(StringRef)> MapClassName2PassName); 458 459 static bool isRequired() { return true; } 460 461 bool isLoopNestMode() const { return LoopNestMode; } 462 463 private: 464 std::unique_ptr<PassConceptT> Pass; 465 466 FunctionPassManager LoopCanonicalizationFPM; 467 468 bool UseMemorySSA = false; 469 bool UseBlockFrequencyInfo = false; 470 bool UseBranchProbabilityInfo = false; 471 const bool LoopNestMode; 472 }; 473 474 /// A function to deduce a loop pass type and wrap it in the templated 475 /// adaptor. 476 /// 477 /// If \p Pass is a loop pass, the returned adaptor will be in loop mode. 478 template <typename LoopPassT> 479 inline std::enable_if_t<is_detected<HasRunOnLoopT, LoopPassT>::value, 480 FunctionToLoopPassAdaptor> 481 createFunctionToLoopPassAdaptor(LoopPassT &&Pass, bool UseMemorySSA = false, 482 bool UseBlockFrequencyInfo = false, 483 bool UseBranchProbabilityInfo = false) { 484 using PassModelT = 485 detail::PassModel<Loop, LoopPassT, PreservedAnalyses, LoopAnalysisManager, 486 LoopStandardAnalysisResults &, LPMUpdater &>; 487 // Do not use make_unique, it causes too many template instantiations, 488 // causing terrible compile times. 489 return FunctionToLoopPassAdaptor( 490 std::unique_ptr<FunctionToLoopPassAdaptor::PassConceptT>( 491 new PassModelT(std::forward<LoopPassT>(Pass))), 492 UseMemorySSA, UseBlockFrequencyInfo, UseBranchProbabilityInfo, false); 493 } 494 495 /// If \p Pass is a loop-nest pass, \p Pass will first be wrapped into a 496 /// \c LoopPassManager and the returned adaptor will be in loop-nest mode. 497 template <typename LoopNestPassT> 498 inline std::enable_if_t<!is_detected<HasRunOnLoopT, LoopNestPassT>::value, 499 FunctionToLoopPassAdaptor> 500 createFunctionToLoopPassAdaptor(LoopNestPassT &&Pass, bool UseMemorySSA = false, 501 bool UseBlockFrequencyInfo = false, 502 bool UseBranchProbabilityInfo = false) { 503 LoopPassManager LPM; 504 LPM.addPass(std::forward<LoopNestPassT>(Pass)); 505 using PassModelT = 506 detail::PassModel<Loop, LoopPassManager, PreservedAnalyses, 507 LoopAnalysisManager, LoopStandardAnalysisResults &, 508 LPMUpdater &>; 509 // Do not use make_unique, it causes too many template instantiations, 510 // causing terrible compile times. 511 return FunctionToLoopPassAdaptor( 512 std::unique_ptr<FunctionToLoopPassAdaptor::PassConceptT>( 513 new PassModelT(std::move(LPM))), 514 UseMemorySSA, UseBlockFrequencyInfo, UseBranchProbabilityInfo, true); 515 } 516 517 /// If \p Pass is an instance of \c LoopPassManager, the returned adaptor will 518 /// be in loop-nest mode if the pass manager contains only loop-nest passes. 519 template <> 520 inline FunctionToLoopPassAdaptor 521 createFunctionToLoopPassAdaptor<LoopPassManager>( 522 LoopPassManager &&LPM, bool UseMemorySSA, bool UseBlockFrequencyInfo, 523 bool UseBranchProbabilityInfo) { 524 // Check if LPM contains any loop pass and if it does not, returns an adaptor 525 // in loop-nest mode. 526 using PassModelT = 527 detail::PassModel<Loop, LoopPassManager, PreservedAnalyses, 528 LoopAnalysisManager, LoopStandardAnalysisResults &, 529 LPMUpdater &>; 530 bool LoopNestMode = (LPM.getNumLoopPasses() == 0); 531 // Do not use make_unique, it causes too many template instantiations, 532 // causing terrible compile times. 533 return FunctionToLoopPassAdaptor( 534 std::unique_ptr<FunctionToLoopPassAdaptor::PassConceptT>( 535 new PassModelT(std::move(LPM))), 536 UseMemorySSA, UseBlockFrequencyInfo, UseBranchProbabilityInfo, 537 LoopNestMode); 538 } 539 540 /// Pass for printing a loop's contents as textual IR. 541 class PrintLoopPass : public PassInfoMixin<PrintLoopPass> { 542 raw_ostream &OS; 543 std::string Banner; 544 545 public: 546 PrintLoopPass(); 547 PrintLoopPass(raw_ostream &OS, const std::string &Banner = ""); 548 549 PreservedAnalyses run(Loop &L, LoopAnalysisManager &, 550 LoopStandardAnalysisResults &, LPMUpdater &); 551 }; 552 } 553 554 #endif // LLVM_TRANSFORMS_SCALAR_LOOPPASSMANAGER_H 555