CallGraphSCCPass.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //===- CallGraphSCCPass.h - Pass that operates BU on call graph -*- 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. //
  9. // This file defines the CallGraphSCCPass class, which is used for passes which
  10. // are implemented as bottom-up traversals on the call graph. Because there may
  11. // be cycles in the call graph, passes of this type operate on the call-graph in
  12. // SCC order: that is, they process function bottom-up, except for recursive
  13. // functions, which they process all at once.
  14. //
  15. // These passes are inherently interprocedural, and are required to keep the
  16. // call graph up-to-date if they do anything which could modify it.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
  20. #define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
  21. #include "llvm/ADT/ArrayRef.h"
  22. #include "llvm/Pass.h"
  23. #include <vector>
  24. namespace llvm {
  25. class CallGraph;
  26. class CallGraphNode;
  27. class CallGraphSCC;
  28. class PMStack;
  29. class CallGraphSCCPass : public Pass {
  30. public:
  31. explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {}
  32. /// createPrinterPass - Get a pass that prints the Module
  33. /// corresponding to a CallGraph.
  34. Pass *createPrinterPass(raw_ostream &OS,
  35. const std::string &Banner) const override;
  36. using llvm::Pass::doInitialization;
  37. using llvm::Pass::doFinalization;
  38. /// doInitialization - This method is called before the SCC's of the program
  39. /// has been processed, allowing the pass to do initialization as necessary.
  40. virtual bool doInitialization(CallGraph &CG) {
  41. return false;
  42. }
  43. /// runOnSCC - This method should be implemented by the subclass to perform
  44. /// whatever action is necessary for the specified SCC. Note that
  45. /// non-recursive (or only self-recursive) functions will have an SCC size of
  46. /// 1, where recursive portions of the call graph will have SCC size > 1.
  47. ///
  48. /// SCC passes that add or delete functions to the SCC are required to update
  49. /// the SCC list, otherwise stale pointers may be dereferenced.
  50. virtual bool runOnSCC(CallGraphSCC &SCC) = 0;
  51. /// doFinalization - This method is called after the SCC's of the program has
  52. /// been processed, allowing the pass to do final cleanup as necessary.
  53. virtual bool doFinalization(CallGraph &CG) {
  54. return false;
  55. }
  56. /// Assign pass manager to manager this pass
  57. void assignPassManager(PMStack &PMS, PassManagerType PMT) override;
  58. /// Return what kind of Pass Manager can manage this pass.
  59. PassManagerType getPotentialPassManagerType() const override {
  60. return PMT_CallGraphPassManager;
  61. }
  62. /// getAnalysisUsage - For this class, we declare that we require and preserve
  63. /// the call graph. If the derived class implements this method, it should
  64. /// always explicitly call the implementation here.
  65. void getAnalysisUsage(AnalysisUsage &Info) const override;
  66. protected:
  67. /// Optional passes call this function to check whether the pass should be
  68. /// skipped. This is the case when optimization bisect is over the limit.
  69. bool skipSCC(CallGraphSCC &SCC) const;
  70. };
  71. /// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
  72. class CallGraphSCC {
  73. const CallGraph &CG; // The call graph for this SCC.
  74. void *Context; // The CGPassManager object that is vending this.
  75. std::vector<CallGraphNode *> Nodes;
  76. public:
  77. CallGraphSCC(CallGraph &cg, void *context) : CG(cg), Context(context) {}
  78. void initialize(ArrayRef<CallGraphNode *> NewNodes) {
  79. Nodes.assign(NewNodes.begin(), NewNodes.end());
  80. }
  81. bool isSingular() const { return Nodes.size() == 1; }
  82. unsigned size() const { return Nodes.size(); }
  83. /// ReplaceNode - This informs the SCC and the pass manager that the specified
  84. /// Old node has been deleted, and New is to be used in its place.
  85. void ReplaceNode(CallGraphNode *Old, CallGraphNode *New);
  86. /// DeleteNode - This informs the SCC and the pass manager that the specified
  87. /// Old node has been deleted.
  88. void DeleteNode(CallGraphNode *Old);
  89. using iterator = std::vector<CallGraphNode *>::const_iterator;
  90. iterator begin() const { return Nodes.begin(); }
  91. iterator end() const { return Nodes.end(); }
  92. const CallGraph &getCallGraph() { return CG; }
  93. };
  94. void initializeDummyCGSCCPassPass(PassRegistry &);
  95. /// This pass is required by interprocedural register allocation. It forces
  96. /// codegen to follow bottom up order on call graph.
  97. class DummyCGSCCPass : public CallGraphSCCPass {
  98. public:
  99. static char ID;
  100. DummyCGSCCPass() : CallGraphSCCPass(ID) {
  101. PassRegistry &Registry = *PassRegistry::getPassRegistry();
  102. initializeDummyCGSCCPassPass(Registry);
  103. }
  104. bool runOnSCC(CallGraphSCC &SCC) override { return false; }
  105. void getAnalysisUsage(AnalysisUsage &AU) const override {
  106. AU.setPreservesAll();
  107. }
  108. };
  109. } // end namespace llvm
  110. #endif // LLVM_ANALYSIS_CALLGRAPHSCCPASS_H