CGSCCPassManager.h 27 KB

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