CGSCCPassManager.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- CGSCCPassManager.h - Call graph 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 passes over SCCs of the call
  16. /// graph. These passes form an important component of LLVM's interprocedural
  17. /// optimizations. Because they operate on the SCCs of the call graph, and they
  18. /// traverse the graph in post-order, they can effectively do pair-wise
  19. /// interprocedural optimizations for all call edges in the program while
  20. /// incrementally refining it and improving the context of these pair-wise
  21. /// optimizations. At each call site edge, the callee has already been
  22. /// optimized as much as is possible. This in turn allows very accurate
  23. /// analysis of it for IPO.
  24. ///
  25. /// A secondary more general goal is to be able to isolate optimization on
  26. /// unrelated parts of the IR module. This is useful to ensure our
  27. /// optimizations are principled and don't miss oportunities where refinement
  28. /// of one part of the module influences transformations in another part of the
  29. /// module. But this is also useful if we want to parallelize the optimizations
  30. /// across common large module graph shapes which tend to be very wide and have
  31. /// large regions of unrelated cliques.
  32. ///
  33. /// To satisfy these goals, we use the LazyCallGraph which provides two graphs
  34. /// nested inside each other (and built lazily from the bottom-up): the call
  35. /// graph proper, and a reference graph. The reference graph is super set of
  36. /// the call graph and is a conservative approximation of what could through
  37. /// scalar or CGSCC transforms *become* the call graph. Using this allows us to
  38. /// ensure we optimize functions prior to them being introduced into the call
  39. /// graph by devirtualization or other technique, and thus ensures that
  40. /// subsequent pair-wise interprocedural optimizations observe the optimized
  41. /// form of these functions. The (potentially transitive) reference
  42. /// reachability used by the reference graph is a conservative approximation
  43. /// that still allows us to have independent regions of the graph.
  44. ///
  45. /// FIXME: There is one major drawback of the reference graph: in its naive
  46. /// form it is quadratic because it contains a distinct edge for each
  47. /// (potentially indirect) reference, even if are all through some common
  48. /// global table of function pointers. This can be fixed in a number of ways
  49. /// that essentially preserve enough of the normalization. While it isn't
  50. /// expected to completely preclude the usability of this, it will need to be
  51. /// addressed.
  52. ///
  53. ///
  54. /// All of these issues are made substantially more complex in the face of
  55. /// mutations to the call graph while optimization passes are being run. When
  56. /// mutations to the call graph occur we want to achieve two different things:
  57. ///
  58. /// - We need to update the call graph in-flight and invalidate analyses
  59. /// cached on entities in the graph. Because of the cache-based analysis
  60. /// design of the pass manager, it is essential to have stable identities for
  61. /// the elements of the IR that passes traverse, and to invalidate any
  62. /// analyses cached on these elements as the mutations take place.
  63. ///
  64. /// - We want to preserve the incremental and post-order traversal of the
  65. /// graph even as it is refined and mutated. This means we want optimization
  66. /// to observe the most refined form of the call graph and to do so in
  67. /// post-order.
  68. ///
  69. /// To address this, the CGSCC manager uses both worklists that can be expanded
  70. /// by passes which transform the IR, and provides invalidation tests to skip
  71. /// entries that become dead. This extra data is provided to every SCC pass so
  72. /// that it can carefully update the manager's traversal as the call graph
  73. /// mutates.
  74. ///
  75. /// We also provide support for running function passes within the CGSCC walk,
  76. /// and there we provide automatic update of the call graph including of the
  77. /// pass manager to reflect call graph changes that fall out naturally as part
  78. /// of scalar transformations.
  79. ///
  80. /// The patterns used to ensure the goals of post-order visitation of the fully
  81. /// refined graph:
  82. ///
  83. /// 1) Sink toward the "bottom" as the graph is refined. This means that any
  84. /// iteration continues in some valid post-order sequence after the mutation
  85. /// has altered the structure.
  86. ///
  87. /// 2) Enqueue in post-order, including the current entity. If the current
  88. /// entity's shape changes, it and everything after it in post-order needs
  89. /// to be visited to observe that shape.
  90. ///
  91. //===----------------------------------------------------------------------===//
  92. #ifndef LLVM_ANALYSIS_CGSCCPASSMANAGER_H
  93. #define LLVM_ANALYSIS_CGSCCPASSMANAGER_H
  94. #include "llvm/ADT/MapVector.h"
  95. #include "llvm/Analysis/LazyCallGraph.h"
  96. #include "llvm/IR/PassManager.h"
  97. #include "llvm/IR/ValueHandle.h"
  98. #include "llvm/Support/raw_ostream.h"
  99. #include <cassert>
  100. #include <utility>
  101. namespace llvm {
  102. class Function;
  103. class Value;
  104. template <typename T, unsigned int N> class SmallPriorityWorklist;
  105. struct CGSCCUpdateResult;
  106. class Module;
  107. // Allow debug logging in this inline function.
  108. #define DEBUG_TYPE "cgscc"
  109. /// Extern template declaration for the analysis set for this IR unit.
  110. extern template class AllAnalysesOn<LazyCallGraph::SCC>;
  111. extern template class AnalysisManager<LazyCallGraph::SCC, LazyCallGraph &>;
  112. /// The CGSCC analysis manager.
  113. ///
  114. /// See the documentation for the AnalysisManager template for detail
  115. /// documentation. This type serves as a convenient way to refer to this
  116. /// construct in the adaptors and proxies used to integrate this into the larger
  117. /// pass manager infrastructure.
  118. using CGSCCAnalysisManager =
  119. AnalysisManager<LazyCallGraph::SCC, LazyCallGraph &>;
  120. // Explicit specialization and instantiation declarations for the pass manager.
  121. // See the comments on the definition of the specialization for details on how
  122. // it differs from the primary template.
  123. template <>
  124. PreservedAnalyses
  125. PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &,
  126. CGSCCUpdateResult &>::run(LazyCallGraph::SCC &InitialC,
  127. CGSCCAnalysisManager &AM,
  128. LazyCallGraph &G, CGSCCUpdateResult &UR);
  129. extern template class PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager,
  130. LazyCallGraph &, CGSCCUpdateResult &>;
  131. /// The CGSCC pass manager.
  132. ///
  133. /// See the documentation for the PassManager template for details. It runs
  134. /// a sequence of SCC passes over each SCC that the manager is run over. This
  135. /// type serves as a convenient way to refer to this construct.
  136. using CGSCCPassManager =
  137. PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &,
  138. CGSCCUpdateResult &>;
  139. /// An explicit specialization of the require analysis template pass.
  140. template <typename AnalysisT>
  141. struct RequireAnalysisPass<AnalysisT, LazyCallGraph::SCC, CGSCCAnalysisManager,
  142. LazyCallGraph &, CGSCCUpdateResult &>
  143. : PassInfoMixin<RequireAnalysisPass<AnalysisT, LazyCallGraph::SCC,
  144. CGSCCAnalysisManager, LazyCallGraph &,
  145. CGSCCUpdateResult &>> {
  146. PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
  147. LazyCallGraph &CG, CGSCCUpdateResult &) {
  148. (void)AM.template getResult<AnalysisT>(C, CG);
  149. return PreservedAnalyses::all();
  150. }
  151. void printPipeline(raw_ostream &OS,
  152. function_ref<StringRef(StringRef)> MapClassName2PassName) {
  153. auto ClassName = AnalysisT::name();
  154. auto PassName = MapClassName2PassName(ClassName);
  155. OS << "require<" << PassName << ">";
  156. }
  157. };
  158. /// A proxy from a \c CGSCCAnalysisManager to a \c Module.
  159. using CGSCCAnalysisManagerModuleProxy =
  160. InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>;
  161. /// We need a specialized result for the \c CGSCCAnalysisManagerModuleProxy so
  162. /// it can have access to the call graph in order to walk all the SCCs when
  163. /// invalidating things.
  164. template <> class CGSCCAnalysisManagerModuleProxy::Result {
  165. public:
  166. explicit Result(CGSCCAnalysisManager &InnerAM, LazyCallGraph &G)
  167. : InnerAM(&InnerAM), G(&G) {}
  168. /// Accessor for the analysis manager.
  169. CGSCCAnalysisManager &getManager() { return *InnerAM; }
  170. /// Handler for invalidation of the Module.
  171. ///
  172. /// If the proxy analysis itself is preserved, then we assume that the set of
  173. /// SCCs in the Module hasn't changed. Thus any pointers to SCCs in the
  174. /// CGSCCAnalysisManager are still valid, and we don't need to call \c clear
  175. /// on the CGSCCAnalysisManager.
  176. ///
  177. /// Regardless of whether this analysis is marked as preserved, all of the
  178. /// analyses in the \c CGSCCAnalysisManager are potentially invalidated based
  179. /// on the set of preserved analyses.
  180. bool invalidate(Module &M, const PreservedAnalyses &PA,
  181. ModuleAnalysisManager::Invalidator &Inv);
  182. private:
  183. CGSCCAnalysisManager *InnerAM;
  184. LazyCallGraph *G;
  185. };
  186. /// Provide a specialized run method for the \c CGSCCAnalysisManagerModuleProxy
  187. /// so it can pass the lazy call graph to the result.
  188. template <>
  189. CGSCCAnalysisManagerModuleProxy::Result
  190. CGSCCAnalysisManagerModuleProxy::run(Module &M, ModuleAnalysisManager &AM);
  191. // Ensure the \c CGSCCAnalysisManagerModuleProxy is provided as an extern
  192. // template.
  193. extern template class InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>;
  194. extern template class OuterAnalysisManagerProxy<
  195. ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph &>;
  196. /// A proxy from a \c ModuleAnalysisManager to an \c SCC.
  197. using ModuleAnalysisManagerCGSCCProxy =
  198. OuterAnalysisManagerProxy<ModuleAnalysisManager, LazyCallGraph::SCC,
  199. LazyCallGraph &>;
  200. /// Support structure for SCC passes to communicate updates the call graph back
  201. /// to the CGSCC pass manager infrastructure.
  202. ///
  203. /// The CGSCC pass manager runs SCC passes which are allowed to update the call
  204. /// graph and SCC structures. This means the structure the pass manager works
  205. /// on is mutating underneath it. In order to support that, there needs to be
  206. /// careful communication about the precise nature and ramifications of these
  207. /// updates to the pass management infrastructure.
  208. ///
  209. /// All SCC passes will have to accept a reference to the management layer's
  210. /// update result struct and use it to reflect the results of any CG updates
  211. /// performed.
  212. ///
  213. /// Passes which do not change the call graph structure in any way can just
  214. /// ignore this argument to their run method.
  215. struct CGSCCUpdateResult {
  216. /// Worklist of the RefSCCs queued for processing.
  217. ///
  218. /// When a pass refines the graph and creates new RefSCCs or causes them to
  219. /// have a different shape or set of component SCCs it should add the RefSCCs
  220. /// to this worklist so that we visit them in the refined form.
  221. ///
  222. /// This worklist is in reverse post-order, as we pop off the back in order
  223. /// to observe RefSCCs in post-order. When adding RefSCCs, clients should add
  224. /// them in reverse post-order.
  225. SmallPriorityWorklist<LazyCallGraph::RefSCC *, 1> &RCWorklist;
  226. /// Worklist of the SCCs queued for processing.
  227. ///
  228. /// When a pass refines the graph and creates new SCCs or causes them to have
  229. /// a different shape or set of component functions it should add the SCCs to
  230. /// this worklist so that we visit them in the refined form.
  231. ///
  232. /// Note that if the SCCs are part of a RefSCC that is added to the \c
  233. /// RCWorklist, they don't need to be added here as visiting the RefSCC will
  234. /// be sufficient to re-visit the SCCs within it.
  235. ///
  236. /// This worklist is in reverse post-order, as we pop off the back in order
  237. /// to observe SCCs in post-order. When adding SCCs, clients should add them
  238. /// in reverse post-order.
  239. SmallPriorityWorklist<LazyCallGraph::SCC *, 1> &CWorklist;
  240. /// The set of invalidated RefSCCs which should be skipped if they are found
  241. /// in \c RCWorklist.
  242. ///
  243. /// This is used to quickly prune out RefSCCs when they get deleted and
  244. /// happen to already be on the worklist. We use this primarily to avoid
  245. /// scanning the list and removing entries from it.
  246. SmallPtrSetImpl<LazyCallGraph::RefSCC *> &InvalidatedRefSCCs;
  247. /// The set of invalidated SCCs which should be skipped if they are found
  248. /// in \c CWorklist.
  249. ///
  250. /// This is used to quickly prune out SCCs when they get deleted and happen
  251. /// to already be on the worklist. We use this primarily to avoid scanning
  252. /// the list and removing entries from it.
  253. SmallPtrSetImpl<LazyCallGraph::SCC *> &InvalidatedSCCs;
  254. /// If non-null, the updated current \c SCC being processed.
  255. ///
  256. /// This is set when a graph refinement takes place and the "current" point
  257. /// in the graph moves "down" or earlier in the post-order walk. This will
  258. /// often cause the "current" SCC to be a newly created SCC object and the
  259. /// old one to be added to the above worklist. When that happens, this
  260. /// pointer is non-null and can be used to continue processing the "top" of
  261. /// the post-order walk.
  262. LazyCallGraph::SCC *UpdatedC;
  263. /// Preserved analyses across SCCs.
  264. ///
  265. /// We specifically want to allow CGSCC passes to mutate ancestor IR
  266. /// (changing both the CG structure and the function IR itself). However,
  267. /// this means we need to take special care to correctly mark what analyses
  268. /// are preserved *across* SCCs. We have to track this out-of-band here
  269. /// because within the main `PassManager` infrastructure we need to mark
  270. /// everything within an SCC as preserved in order to avoid repeatedly
  271. /// invalidating the same analyses as we unnest pass managers and adaptors.
  272. /// So we track the cross-SCC version of the preserved analyses here from any
  273. /// code that does direct invalidation of SCC analyses, and then use it
  274. /// whenever we move forward in the post-order walk of SCCs before running
  275. /// passes over the new SCC.
  276. PreservedAnalyses CrossSCCPA;
  277. /// A hacky area where the inliner can retain history about inlining
  278. /// decisions that mutated the call graph's SCC structure in order to avoid
  279. /// infinite inlining. See the comments in the inliner's CG update logic.
  280. ///
  281. /// FIXME: Keeping this here seems like a big layering issue, we should look
  282. /// for a better technique.
  283. SmallDenseSet<std::pair<LazyCallGraph::Node *, LazyCallGraph::SCC *>, 4>
  284. &InlinedInternalEdges;
  285. /// Weak VHs to keep track of indirect calls for the purposes of detecting
  286. /// devirtualization.
  287. ///
  288. /// This is a map to avoid having duplicate entries. If a Value is
  289. /// deallocated, its corresponding WeakTrackingVH will be nulled out. When
  290. /// checking if a Value is in the map or not, also check if the corresponding
  291. /// WeakTrackingVH is null to avoid issues with a new Value sharing the same
  292. /// address as a deallocated one.
  293. SmallMapVector<Value *, WeakTrackingVH, 16> IndirectVHs;
  294. };
  295. /// The core module pass which does a post-order walk of the SCCs and
  296. /// runs a CGSCC pass over each one.
  297. ///
  298. /// Designed to allow composition of a CGSCCPass(Manager) and
  299. /// a ModulePassManager. Note that this pass must be run with a module analysis
  300. /// manager as it uses the LazyCallGraph analysis. It will also run the
  301. /// \c CGSCCAnalysisManagerModuleProxy analysis prior to running the CGSCC
  302. /// pass over the module to enable a \c FunctionAnalysisManager to be used
  303. /// within this run safely.
  304. class ModuleToPostOrderCGSCCPassAdaptor
  305. : public PassInfoMixin<ModuleToPostOrderCGSCCPassAdaptor> {
  306. public:
  307. using PassConceptT =
  308. detail::PassConcept<LazyCallGraph::SCC, CGSCCAnalysisManager,
  309. LazyCallGraph &, CGSCCUpdateResult &>;
  310. explicit ModuleToPostOrderCGSCCPassAdaptor(std::unique_ptr<PassConceptT> Pass)
  311. : Pass(std::move(Pass)) {}
  312. ModuleToPostOrderCGSCCPassAdaptor(ModuleToPostOrderCGSCCPassAdaptor &&Arg)
  313. : Pass(std::move(Arg.Pass)) {}
  314. friend void swap(ModuleToPostOrderCGSCCPassAdaptor &LHS,
  315. ModuleToPostOrderCGSCCPassAdaptor &RHS) {
  316. std::swap(LHS.Pass, RHS.Pass);
  317. }
  318. ModuleToPostOrderCGSCCPassAdaptor &
  319. operator=(ModuleToPostOrderCGSCCPassAdaptor RHS) {
  320. swap(*this, RHS);
  321. return *this;
  322. }
  323. /// Runs the CGSCC pass across every SCC in the module.
  324. PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
  325. void printPipeline(raw_ostream &OS,
  326. function_ref<StringRef(StringRef)> MapClassName2PassName) {
  327. OS << "cgscc(";
  328. Pass->printPipeline(OS, MapClassName2PassName);
  329. OS << ")";
  330. }
  331. static bool isRequired() { return true; }
  332. private:
  333. std::unique_ptr<PassConceptT> Pass;
  334. };
  335. /// A function to deduce a function pass type and wrap it in the
  336. /// templated adaptor.
  337. template <typename CGSCCPassT>
  338. ModuleToPostOrderCGSCCPassAdaptor
  339. createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT &&Pass) {
  340. using PassModelT = detail::PassModel<LazyCallGraph::SCC, CGSCCPassT,
  341. PreservedAnalyses, CGSCCAnalysisManager,
  342. LazyCallGraph &, CGSCCUpdateResult &>;
  343. // Do not use make_unique, it causes too many template instantiations,
  344. // causing terrible compile times.
  345. return ModuleToPostOrderCGSCCPassAdaptor(
  346. std::unique_ptr<ModuleToPostOrderCGSCCPassAdaptor::PassConceptT>(
  347. new PassModelT(std::forward<CGSCCPassT>(Pass))));
  348. }
  349. /// A proxy from a \c FunctionAnalysisManager to an \c SCC.
  350. ///
  351. /// When a module pass runs and triggers invalidation, both the CGSCC and
  352. /// Function analysis manager proxies on the module get an invalidation event.
  353. /// We don't want to fully duplicate responsibility for most of the
  354. /// invalidation logic. Instead, this layer is only responsible for SCC-local
  355. /// invalidation events. We work with the module's FunctionAnalysisManager to
  356. /// invalidate function analyses.
  357. class FunctionAnalysisManagerCGSCCProxy
  358. : public AnalysisInfoMixin<FunctionAnalysisManagerCGSCCProxy> {
  359. public:
  360. class Result {
  361. public:
  362. explicit Result() : FAM(nullptr) {}
  363. explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
  364. void updateFAM(FunctionAnalysisManager &FAM) { this->FAM = &FAM; }
  365. /// Accessor for the analysis manager.
  366. FunctionAnalysisManager &getManager() {
  367. assert(FAM);
  368. return *FAM;
  369. }
  370. bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA,
  371. CGSCCAnalysisManager::Invalidator &Inv);
  372. private:
  373. FunctionAnalysisManager *FAM;
  374. };
  375. /// Computes the \c FunctionAnalysisManager and stores it in the result proxy.
  376. Result run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &);
  377. private:
  378. friend AnalysisInfoMixin<FunctionAnalysisManagerCGSCCProxy>;
  379. static AnalysisKey Key;
  380. };
  381. extern template class OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>;
  382. /// A proxy from a \c CGSCCAnalysisManager to a \c Function.
  383. using CGSCCAnalysisManagerFunctionProxy =
  384. OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>;
  385. /// Helper to update the call graph after running a function pass.
  386. ///
  387. /// Function passes can only mutate the call graph in specific ways. This
  388. /// routine provides a helper that updates the call graph in those ways
  389. /// including returning whether any changes were made and populating a CG
  390. /// update result struct for the overall CGSCC walk.
  391. LazyCallGraph::SCC &updateCGAndAnalysisManagerForFunctionPass(
  392. LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N,
  393. CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR,
  394. FunctionAnalysisManager &FAM);
  395. /// Helper to update the call graph after running a CGSCC pass.
  396. ///
  397. /// CGSCC passes can only mutate the call graph in specific ways. This
  398. /// routine provides a helper that updates the call graph in those ways
  399. /// including returning whether any changes were made and populating a CG
  400. /// update result struct for the overall CGSCC walk.
  401. LazyCallGraph::SCC &updateCGAndAnalysisManagerForCGSCCPass(
  402. LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N,
  403. CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR,
  404. FunctionAnalysisManager &FAM);
  405. /// Adaptor that maps from a SCC to its functions.
  406. ///
  407. /// Designed to allow composition of a FunctionPass(Manager) and
  408. /// a CGSCCPassManager. Note that if this pass is constructed with a pointer
  409. /// to a \c CGSCCAnalysisManager it will run the
  410. /// \c FunctionAnalysisManagerCGSCCProxy analysis prior to running the function
  411. /// pass over the SCC to enable a \c FunctionAnalysisManager to be used
  412. /// within this run safely.
  413. class CGSCCToFunctionPassAdaptor
  414. : public PassInfoMixin<CGSCCToFunctionPassAdaptor> {
  415. public:
  416. using PassConceptT = detail::PassConcept<Function, FunctionAnalysisManager>;
  417. explicit CGSCCToFunctionPassAdaptor(std::unique_ptr<PassConceptT> Pass,
  418. bool EagerlyInvalidate, bool NoRerun)
  419. : Pass(std::move(Pass)), EagerlyInvalidate(EagerlyInvalidate),
  420. NoRerun(NoRerun) {}
  421. CGSCCToFunctionPassAdaptor(CGSCCToFunctionPassAdaptor &&Arg)
  422. : Pass(std::move(Arg.Pass)), EagerlyInvalidate(Arg.EagerlyInvalidate),
  423. NoRerun(Arg.NoRerun) {}
  424. friend void swap(CGSCCToFunctionPassAdaptor &LHS,
  425. CGSCCToFunctionPassAdaptor &RHS) {
  426. std::swap(LHS.Pass, RHS.Pass);
  427. }
  428. CGSCCToFunctionPassAdaptor &operator=(CGSCCToFunctionPassAdaptor RHS) {
  429. swap(*this, RHS);
  430. return *this;
  431. }
  432. /// Runs the function pass across every function in the module.
  433. PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
  434. LazyCallGraph &CG, CGSCCUpdateResult &UR);
  435. void printPipeline(raw_ostream &OS,
  436. function_ref<StringRef(StringRef)> MapClassName2PassName) {
  437. OS << "function";
  438. if (EagerlyInvalidate)
  439. OS << "<eager-inv>";
  440. OS << "(";
  441. Pass->printPipeline(OS, MapClassName2PassName);
  442. OS << ")";
  443. }
  444. static bool isRequired() { return true; }
  445. private:
  446. std::unique_ptr<PassConceptT> Pass;
  447. bool EagerlyInvalidate;
  448. bool NoRerun;
  449. };
  450. /// A function to deduce a function pass type and wrap it in the
  451. /// templated adaptor.
  452. template <typename FunctionPassT>
  453. CGSCCToFunctionPassAdaptor
  454. createCGSCCToFunctionPassAdaptor(FunctionPassT &&Pass,
  455. bool EagerlyInvalidate = false,
  456. bool NoRerun = false) {
  457. using PassModelT =
  458. detail::PassModel<Function, FunctionPassT, PreservedAnalyses,
  459. FunctionAnalysisManager>;
  460. // Do not use make_unique, it causes too many template instantiations,
  461. // causing terrible compile times.
  462. return CGSCCToFunctionPassAdaptor(
  463. std::unique_ptr<CGSCCToFunctionPassAdaptor::PassConceptT>(
  464. new PassModelT(std::forward<FunctionPassT>(Pass))),
  465. EagerlyInvalidate, NoRerun);
  466. }
  467. // A marker to determine if function passes should be run on a function within a
  468. // CGSCCToFunctionPassAdaptor. This is used to prevent running an expensive
  469. // function pass (manager) on a function multiple times if SCC mutations cause a
  470. // function to be visited multiple times and the function is not modified by
  471. // other SCC passes.
  472. class ShouldNotRunFunctionPassesAnalysis
  473. : public AnalysisInfoMixin<ShouldNotRunFunctionPassesAnalysis> {
  474. public:
  475. static AnalysisKey Key;
  476. struct Result {};
  477. Result run(Function &F, FunctionAnalysisManager &FAM) { return Result(); }
  478. };
  479. /// A helper that repeats an SCC pass each time an indirect call is refined to
  480. /// a direct call by that pass.
  481. ///
  482. /// While the CGSCC pass manager works to re-visit SCCs and RefSCCs as they
  483. /// change shape, we may also want to repeat an SCC pass if it simply refines
  484. /// an indirect call to a direct call, even if doing so does not alter the
  485. /// shape of the graph. Note that this only pertains to direct calls to
  486. /// functions where IPO across the SCC may be able to compute more precise
  487. /// results. For intrinsics, we assume scalar optimizations already can fully
  488. /// reason about them.
  489. ///
  490. /// This repetition has the potential to be very large however, as each one
  491. /// might refine a single call site. As a consequence, in practice we use an
  492. /// upper bound on the number of repetitions to limit things.
  493. class DevirtSCCRepeatedPass : public PassInfoMixin<DevirtSCCRepeatedPass> {
  494. public:
  495. using PassConceptT =
  496. detail::PassConcept<LazyCallGraph::SCC, CGSCCAnalysisManager,
  497. LazyCallGraph &, CGSCCUpdateResult &>;
  498. explicit DevirtSCCRepeatedPass(std::unique_ptr<PassConceptT> Pass,
  499. int MaxIterations)
  500. : Pass(std::move(Pass)), MaxIterations(MaxIterations) {}
  501. /// Runs the wrapped pass up to \c MaxIterations on the SCC, iterating
  502. /// whenever an indirect call is refined.
  503. PreservedAnalyses run(LazyCallGraph::SCC &InitialC, CGSCCAnalysisManager &AM,
  504. LazyCallGraph &CG, CGSCCUpdateResult &UR);
  505. void printPipeline(raw_ostream &OS,
  506. function_ref<StringRef(StringRef)> MapClassName2PassName) {
  507. OS << "devirt<" << MaxIterations << ">(";
  508. Pass->printPipeline(OS, MapClassName2PassName);
  509. OS << ")";
  510. }
  511. private:
  512. std::unique_ptr<PassConceptT> Pass;
  513. int MaxIterations;
  514. };
  515. /// A function to deduce a function pass type and wrap it in the
  516. /// templated adaptor.
  517. template <typename CGSCCPassT>
  518. DevirtSCCRepeatedPass createDevirtSCCRepeatedPass(CGSCCPassT &&Pass,
  519. int MaxIterations) {
  520. using PassModelT = detail::PassModel<LazyCallGraph::SCC, CGSCCPassT,
  521. PreservedAnalyses, CGSCCAnalysisManager,
  522. LazyCallGraph &, CGSCCUpdateResult &>;
  523. // Do not use make_unique, it causes too many template instantiations,
  524. // causing terrible compile times.
  525. return DevirtSCCRepeatedPass(
  526. std::unique_ptr<DevirtSCCRepeatedPass::PassConceptT>(
  527. new PassModelT(std::forward<CGSCCPassT>(Pass))),
  528. MaxIterations);
  529. }
  530. // Clear out the debug logging macro.
  531. #undef DEBUG_TYPE
  532. } // end namespace llvm
  533. #endif // LLVM_ANALYSIS_CGSCCPASSMANAGER_H
  534. #ifdef __GNUC__
  535. #pragma GCC diagnostic pop
  536. #endif