LoopPassManager.h 23 KB

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