CallGraphSCCPass.h 5.2 KB

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