RegionPass.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. //===- RegionPass.cpp - Region Pass and Region Pass Manager ---------------===//
  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 implements RegionPass and RGPassManager. All region optimization
  10. // and transformation passes are derived from RegionPass. RGPassManager is
  11. // responsible for managing RegionPasses.
  12. // Most of this code has been COPIED from LoopPass.cpp
  13. //
  14. //===----------------------------------------------------------------------===//
  15. #include "llvm/Analysis/RegionPass.h"
  16. #include "llvm/Analysis/RegionInfo.h"
  17. #include "llvm/IR/OptBisect.h"
  18. #include "llvm/IR/PassTimingInfo.h"
  19. #include "llvm/IR/PrintPasses.h"
  20. #include "llvm/Support/Debug.h"
  21. #include "llvm/Support/Timer.h"
  22. #include "llvm/Support/raw_ostream.h"
  23. using namespace llvm;
  24. #define DEBUG_TYPE "regionpassmgr"
  25. //===----------------------------------------------------------------------===//
  26. // RGPassManager
  27. //
  28. char RGPassManager::ID = 0;
  29. RGPassManager::RGPassManager() : FunctionPass(ID) {
  30. RI = nullptr;
  31. CurrentRegion = nullptr;
  32. }
  33. // Recurse through all subregions and all regions into RQ.
  34. static void addRegionIntoQueue(Region &R, std::deque<Region *> &RQ) {
  35. RQ.push_back(&R);
  36. for (const auto &E : R)
  37. addRegionIntoQueue(*E, RQ);
  38. }
  39. /// Pass Manager itself does not invalidate any analysis info.
  40. void RGPassManager::getAnalysisUsage(AnalysisUsage &Info) const {
  41. Info.addRequired<RegionInfoPass>();
  42. Info.setPreservesAll();
  43. }
  44. /// run - Execute all of the passes scheduled for execution. Keep track of
  45. /// whether any of the passes modifies the function, and if so, return true.
  46. bool RGPassManager::runOnFunction(Function &F) {
  47. RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
  48. bool Changed = false;
  49. // Collect inherited analysis from Module level pass manager.
  50. populateInheritedAnalysis(TPM->activeStack);
  51. addRegionIntoQueue(*RI->getTopLevelRegion(), RQ);
  52. if (RQ.empty()) // No regions, skip calling finalizers
  53. return false;
  54. // Initialization
  55. for (Region *R : RQ) {
  56. for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
  57. RegionPass *RP = (RegionPass *)getContainedPass(Index);
  58. Changed |= RP->doInitialization(R, *this);
  59. }
  60. }
  61. // Walk Regions
  62. while (!RQ.empty()) {
  63. CurrentRegion = RQ.back();
  64. // Run all passes on the current Region.
  65. for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
  66. RegionPass *P = (RegionPass*)getContainedPass(Index);
  67. if (isPassDebuggingExecutionsOrMore()) {
  68. dumpPassInfo(P, EXECUTION_MSG, ON_REGION_MSG,
  69. CurrentRegion->getNameStr());
  70. dumpRequiredSet(P);
  71. }
  72. initializeAnalysisImpl(P);
  73. bool LocalChanged = false;
  74. {
  75. PassManagerPrettyStackEntry X(P, *CurrentRegion->getEntry());
  76. TimeRegion PassTimer(getPassTimer(P));
  77. #ifdef EXPENSIVE_CHECKS
  78. uint64_t RefHash = P->structuralHash(F);
  79. #endif
  80. LocalChanged = P->runOnRegion(CurrentRegion, *this);
  81. #ifdef EXPENSIVE_CHECKS
  82. if (!LocalChanged && (RefHash != P->structuralHash(F))) {
  83. llvm::errs() << "Pass modifies its input and doesn't report it: "
  84. << P->getPassName() << "\n";
  85. llvm_unreachable("Pass modifies its input and doesn't report it");
  86. }
  87. #endif
  88. Changed |= LocalChanged;
  89. }
  90. if (isPassDebuggingExecutionsOrMore()) {
  91. if (LocalChanged)
  92. dumpPassInfo(P, MODIFICATION_MSG, ON_REGION_MSG,
  93. CurrentRegion->getNameStr());
  94. dumpPreservedSet(P);
  95. }
  96. // Manually check that this region is still healthy. This is done
  97. // instead of relying on RegionInfo::verifyRegion since RegionInfo
  98. // is a function pass and it's really expensive to verify every
  99. // Region in the function every time. That level of checking can be
  100. // enabled with the -verify-region-info option.
  101. {
  102. TimeRegion PassTimer(getPassTimer(P));
  103. CurrentRegion->verifyRegion();
  104. }
  105. // Then call the regular verifyAnalysis functions.
  106. verifyPreservedAnalysis(P);
  107. if (LocalChanged)
  108. removeNotPreservedAnalysis(P);
  109. recordAvailableAnalysis(P);
  110. removeDeadPasses(P,
  111. (!isPassDebuggingExecutionsOrMore())
  112. ? "<deleted>"
  113. : CurrentRegion->getNameStr(),
  114. ON_REGION_MSG);
  115. }
  116. // Pop the region from queue after running all passes.
  117. RQ.pop_back();
  118. // Free all region nodes created in region passes.
  119. RI->clearNodeCache();
  120. }
  121. // Finalization
  122. for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
  123. RegionPass *P = (RegionPass*)getContainedPass(Index);
  124. Changed |= P->doFinalization();
  125. }
  126. // Print the region tree after all pass.
  127. LLVM_DEBUG(dbgs() << "\nRegion tree of function " << F.getName()
  128. << " after all region Pass:\n";
  129. RI->dump(); dbgs() << "\n";);
  130. return Changed;
  131. }
  132. /// Print passes managed by this manager
  133. void RGPassManager::dumpPassStructure(unsigned Offset) {
  134. errs().indent(Offset*2) << "Region Pass Manager\n";
  135. for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
  136. Pass *P = getContainedPass(Index);
  137. P->dumpPassStructure(Offset + 1);
  138. dumpLastUses(P, Offset+1);
  139. }
  140. }
  141. namespace {
  142. //===----------------------------------------------------------------------===//
  143. // PrintRegionPass
  144. class PrintRegionPass : public RegionPass {
  145. private:
  146. std::string Banner;
  147. raw_ostream &Out; // raw_ostream to print on.
  148. public:
  149. static char ID;
  150. PrintRegionPass(const std::string &B, raw_ostream &o)
  151. : RegionPass(ID), Banner(B), Out(o) {}
  152. void getAnalysisUsage(AnalysisUsage &AU) const override {
  153. AU.setPreservesAll();
  154. }
  155. bool runOnRegion(Region *R, RGPassManager &RGM) override {
  156. if (!isFunctionInPrintList(R->getEntry()->getParent()->getName()))
  157. return false;
  158. Out << Banner;
  159. for (const auto *BB : R->blocks()) {
  160. if (BB)
  161. BB->print(Out);
  162. else
  163. Out << "Printing <null> Block";
  164. }
  165. return false;
  166. }
  167. StringRef getPassName() const override { return "Print Region IR"; }
  168. };
  169. char PrintRegionPass::ID = 0;
  170. } //end anonymous namespace
  171. //===----------------------------------------------------------------------===//
  172. // RegionPass
  173. // Check if this pass is suitable for the current RGPassManager, if
  174. // available. This pass P is not suitable for a RGPassManager if P
  175. // is not preserving higher level analysis info used by other
  176. // RGPassManager passes. In such case, pop RGPassManager from the
  177. // stack. This will force assignPassManager() to create new
  178. // LPPassManger as expected.
  179. void RegionPass::preparePassManager(PMStack &PMS) {
  180. // Find RGPassManager
  181. while (!PMS.empty() &&
  182. PMS.top()->getPassManagerType() > PMT_RegionPassManager)
  183. PMS.pop();
  184. // If this pass is destroying high level information that is used
  185. // by other passes that are managed by LPM then do not insert
  186. // this pass in current LPM. Use new RGPassManager.
  187. if (PMS.top()->getPassManagerType() == PMT_RegionPassManager &&
  188. !PMS.top()->preserveHigherLevelAnalysis(this))
  189. PMS.pop();
  190. }
  191. /// Assign pass manager to manage this pass.
  192. void RegionPass::assignPassManager(PMStack &PMS,
  193. PassManagerType PreferredType) {
  194. // Find RGPassManager
  195. while (!PMS.empty() &&
  196. PMS.top()->getPassManagerType() > PMT_RegionPassManager)
  197. PMS.pop();
  198. RGPassManager *RGPM;
  199. // Create new Region Pass Manager if it does not exist.
  200. if (PMS.top()->getPassManagerType() == PMT_RegionPassManager)
  201. RGPM = (RGPassManager*)PMS.top();
  202. else {
  203. assert (!PMS.empty() && "Unable to create Region Pass Manager");
  204. PMDataManager *PMD = PMS.top();
  205. // [1] Create new Region Pass Manager
  206. RGPM = new RGPassManager();
  207. RGPM->populateInheritedAnalysis(PMS);
  208. // [2] Set up new manager's top level manager
  209. PMTopLevelManager *TPM = PMD->getTopLevelManager();
  210. TPM->addIndirectPassManager(RGPM);
  211. // [3] Assign manager to manage this new manager. This may create
  212. // and push new managers into PMS
  213. TPM->schedulePass(RGPM);
  214. // [4] Push new manager into PMS
  215. PMS.push(RGPM);
  216. }
  217. RGPM->add(this);
  218. }
  219. /// Get the printer pass
  220. Pass *RegionPass::createPrinterPass(raw_ostream &O,
  221. const std::string &Banner) const {
  222. return new PrintRegionPass(Banner, O);
  223. }
  224. static std::string getDescription(const Region &R) {
  225. return "region";
  226. }
  227. bool RegionPass::skipRegion(Region &R) const {
  228. Function &F = *R.getEntry()->getParent();
  229. OptPassGate &Gate = F.getContext().getOptPassGate();
  230. if (Gate.isEnabled() &&
  231. !Gate.shouldRunPass(this->getPassName(), getDescription(R)))
  232. return true;
  233. if (F.hasOptNone()) {
  234. // Report this only once per function.
  235. if (R.getEntry() == &F.getEntryBlock())
  236. LLVM_DEBUG(dbgs() << "Skipping pass '" << getPassName()
  237. << "' on function " << F.getName() << "\n");
  238. return true;
  239. }
  240. return false;
  241. }