RegionInfo.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. //===- RegionInfo.cpp - SESE region detection analysis --------------------===//
  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. // Detects single entry single exit regions in the control flow graph.
  9. //===----------------------------------------------------------------------===//
  10. #include "llvm/Analysis/RegionInfo.h"
  11. #include "llvm/ADT/Statistic.h"
  12. #include "llvm/InitializePasses.h"
  13. #ifndef NDEBUG
  14. #include "llvm/Analysis/RegionPrinter.h"
  15. #endif
  16. #include "llvm/Analysis/RegionInfoImpl.h"
  17. #include "llvm/Config/llvm-config.h"
  18. #include "llvm/IR/Function.h"
  19. #include "llvm/Support/CommandLine.h"
  20. #include "llvm/Support/Compiler.h"
  21. using namespace llvm;
  22. #define DEBUG_TYPE "region"
  23. namespace llvm {
  24. template class RegionBase<RegionTraits<Function>>;
  25. template class RegionNodeBase<RegionTraits<Function>>;
  26. template class RegionInfoBase<RegionTraits<Function>>;
  27. } // end namespace llvm
  28. STATISTIC(numRegions, "The # of regions");
  29. STATISTIC(numSimpleRegions, "The # of simple regions");
  30. // Always verify if expensive checking is enabled.
  31. static cl::opt<bool,true>
  32. VerifyRegionInfoX(
  33. "verify-region-info",
  34. cl::location(RegionInfoBase<RegionTraits<Function>>::VerifyRegionInfo),
  35. cl::desc("Verify region info (time consuming)"));
  36. static cl::opt<Region::PrintStyle, true> printStyleX("print-region-style",
  37. cl::location(RegionInfo::printStyle),
  38. cl::Hidden,
  39. cl::desc("style of printing regions"),
  40. cl::values(
  41. clEnumValN(Region::PrintNone, "none", "print no details"),
  42. clEnumValN(Region::PrintBB, "bb",
  43. "print regions in detail with block_iterator"),
  44. clEnumValN(Region::PrintRN, "rn",
  45. "print regions in detail with element_iterator")));
  46. //===----------------------------------------------------------------------===//
  47. // Region implementation
  48. //
  49. Region::Region(BasicBlock *Entry, BasicBlock *Exit,
  50. RegionInfo* RI,
  51. DominatorTree *DT, Region *Parent) :
  52. RegionBase<RegionTraits<Function>>(Entry, Exit, RI, DT, Parent) {
  53. }
  54. Region::~Region() = default;
  55. //===----------------------------------------------------------------------===//
  56. // RegionInfo implementation
  57. //
  58. RegionInfo::RegionInfo() = default;
  59. RegionInfo::~RegionInfo() = default;
  60. bool RegionInfo::invalidate(Function &F, const PreservedAnalyses &PA,
  61. FunctionAnalysisManager::Invalidator &) {
  62. // Check whether the analysis, all analyses on functions, or the function's
  63. // CFG has been preserved.
  64. auto PAC = PA.getChecker<RegionInfoAnalysis>();
  65. return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() ||
  66. PAC.preservedSet<CFGAnalyses>());
  67. }
  68. void RegionInfo::updateStatistics(Region *R) {
  69. ++numRegions;
  70. // TODO: Slow. Should only be enabled if -stats is used.
  71. if (R->isSimple())
  72. ++numSimpleRegions;
  73. }
  74. void RegionInfo::recalculate(Function &F, DominatorTree *DT_,
  75. PostDominatorTree *PDT_, DominanceFrontier *DF_) {
  76. DT = DT_;
  77. PDT = PDT_;
  78. DF = DF_;
  79. TopLevelRegion = new Region(&F.getEntryBlock(), nullptr,
  80. this, DT, nullptr);
  81. updateStatistics(TopLevelRegion);
  82. calculate(F);
  83. }
  84. #ifndef NDEBUG
  85. void RegionInfo::view() { viewRegion(this); }
  86. void RegionInfo::viewOnly() { viewRegionOnly(this); }
  87. #endif
  88. //===----------------------------------------------------------------------===//
  89. // RegionInfoPass implementation
  90. //
  91. RegionInfoPass::RegionInfoPass() : FunctionPass(ID) {
  92. initializeRegionInfoPassPass(*PassRegistry::getPassRegistry());
  93. }
  94. RegionInfoPass::~RegionInfoPass() = default;
  95. bool RegionInfoPass::runOnFunction(Function &F) {
  96. releaseMemory();
  97. auto DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
  98. auto PDT = &getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
  99. auto DF = &getAnalysis<DominanceFrontierWrapperPass>().getDominanceFrontier();
  100. RI.recalculate(F, DT, PDT, DF);
  101. return false;
  102. }
  103. void RegionInfoPass::releaseMemory() {
  104. RI.releaseMemory();
  105. }
  106. void RegionInfoPass::verifyAnalysis() const {
  107. RI.verifyAnalysis();
  108. }
  109. void RegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
  110. AU.setPreservesAll();
  111. AU.addRequiredTransitive<DominatorTreeWrapperPass>();
  112. AU.addRequired<PostDominatorTreeWrapperPass>();
  113. AU.addRequired<DominanceFrontierWrapperPass>();
  114. }
  115. void RegionInfoPass::print(raw_ostream &OS, const Module *) const {
  116. RI.print(OS);
  117. }
  118. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  119. LLVM_DUMP_METHOD void RegionInfoPass::dump() const {
  120. RI.dump();
  121. }
  122. #endif
  123. char RegionInfoPass::ID = 0;
  124. INITIALIZE_PASS_BEGIN(RegionInfoPass, "regions",
  125. "Detect single entry single exit regions", true, true)
  126. INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
  127. INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
  128. INITIALIZE_PASS_DEPENDENCY(DominanceFrontierWrapperPass)
  129. INITIALIZE_PASS_END(RegionInfoPass, "regions",
  130. "Detect single entry single exit regions", true, true)
  131. // Create methods available outside of this file, to use them
  132. // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
  133. // the link time optimization.
  134. namespace llvm {
  135. FunctionPass *createRegionInfoPass() {
  136. return new RegionInfoPass();
  137. }
  138. } // end namespace llvm
  139. //===----------------------------------------------------------------------===//
  140. // RegionInfoAnalysis implementation
  141. //
  142. AnalysisKey RegionInfoAnalysis::Key;
  143. RegionInfo RegionInfoAnalysis::run(Function &F, FunctionAnalysisManager &AM) {
  144. RegionInfo RI;
  145. auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
  146. auto *PDT = &AM.getResult<PostDominatorTreeAnalysis>(F);
  147. auto *DF = &AM.getResult<DominanceFrontierAnalysis>(F);
  148. RI.recalculate(F, DT, PDT, DF);
  149. return RI;
  150. }
  151. RegionInfoPrinterPass::RegionInfoPrinterPass(raw_ostream &OS)
  152. : OS(OS) {}
  153. PreservedAnalyses RegionInfoPrinterPass::run(Function &F,
  154. FunctionAnalysisManager &AM) {
  155. OS << "Region Tree for function: " << F.getName() << "\n";
  156. AM.getResult<RegionInfoAnalysis>(F).print(OS);
  157. return PreservedAnalyses::all();
  158. }
  159. PreservedAnalyses RegionInfoVerifierPass::run(Function &F,
  160. FunctionAnalysisManager &AM) {
  161. AM.getResult<RegionInfoAnalysis>(F).verifyAnalysis();
  162. return PreservedAnalyses::all();
  163. }