RegionInfo.cpp 6.5 KB

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