LCOV - code coverage report
Current view: top level - lib/Analysis - RegionPass.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 70 106 66.0 %
Date: 2018-02-25 19:55:18 Functions: 7 14 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- RegionPass.cpp - Region Pass and Region Pass Manager ---------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file implements RegionPass and RGPassManager. All region optimization
      11             : // and transformation passes are derived from RegionPass. RGPassManager is
      12             : // responsible for managing RegionPasses.
      13             : // Most of this code has been COPIED from LoopPass.cpp
      14             : //
      15             : //===----------------------------------------------------------------------===//
      16             : #include "llvm/Analysis/RegionPass.h"
      17             : #include "llvm/IR/OptBisect.h"
      18             : #include "llvm/Support/Debug.h"
      19             : #include "llvm/Support/Timer.h"
      20             : #include "llvm/Support/raw_ostream.h"
      21             : using namespace llvm;
      22             : 
      23             : #define DEBUG_TYPE "regionpassmgr"
      24             : 
      25             : //===----------------------------------------------------------------------===//
      26             : // RGPassManager
      27             : //
      28             : 
      29             : char RGPassManager::ID = 0;
      30             : 
      31        4193 : RGPassManager::RGPassManager()
      32        4193 :   : FunctionPass(ID), PMDataManager() {
      33        4193 :   skipThisRegion = false;
      34        4193 :   redoThisRegion = false;
      35        4193 :   RI = nullptr;
      36        4193 :   CurrentRegion = nullptr;
      37        4193 : }
      38             : 
      39             : // Recurse through all subregions and all regions  into RQ.
      40       27786 : static void addRegionIntoQueue(Region &R, std::deque<Region *> &RQ) {
      41       55572 :   RQ.push_back(&R);
      42       34460 :   for (const auto &E : R)
      43        6674 :     addRegionIntoQueue(*E, RQ);
      44       27786 : }
      45             : 
      46             : /// Pass Manager itself does not invalidate any analysis info.
      47        4193 : void RGPassManager::getAnalysisUsage(AnalysisUsage &Info) const {
      48             :   Info.addRequired<RegionInfoPass>();
      49             :   Info.setPreservesAll();
      50        4193 : }
      51             : 
      52             : /// run - Execute all of the passes scheduled for execution.  Keep track of
      53             : /// whether any of the passes modifies the function, and if so, return true.
      54       21112 : bool RGPassManager::runOnFunction(Function &F) {
      55       42224 :   RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
      56             :   bool Changed = false;
      57             : 
      58             :   // Collect inherited analysis from Module level pass manager.
      59       21112 :   populateInheritedAnalysis(TPM->activeStack);
      60             : 
      61       21112 :   addRegionIntoQueue(*RI->getTopLevelRegion(), RQ);
      62             : 
      63       21112 :   if (RQ.empty()) // No regions, skip calling finalizers
      64             :     return false;
      65             : 
      66             :   // Initialization
      67       48898 :   for (Region *R : RQ) {
      68      121594 :     for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
      69             :       RegionPass *RP = (RegionPass *)getContainedPass(Index);
      70       46904 :       Changed |= RP->doInitialization(R, *this);
      71             :     }
      72             :   }
      73             : 
      74             :   // Walk Regions
      75       48809 :   while (!RQ.empty()) {
      76             : 
      77       27742 :     CurrentRegion  = RQ.back();
      78       27742 :     skipThisRegion = false;
      79       27742 :     redoThisRegion = false;
      80             : 
      81             :     // Run all passes on the current Region.
      82      120984 :     for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
      83             :       RegionPass *P = (RegionPass*)getContainedPass(Index);
      84             : 
      85       46666 :       if (isPassDebuggingExecutionsOrMore()) {
      86           0 :         dumpPassInfo(P, EXECUTION_MSG, ON_REGION_MSG,
      87           0 :                      CurrentRegion->getNameStr());
      88           0 :         dumpRequiredSet(P);
      89             :       }
      90             : 
      91       46666 :       initializeAnalysisImpl(P);
      92             : 
      93             :       {
      94       93332 :         PassManagerPrettyStackEntry X(P, *CurrentRegion->getEntry());
      95             : 
      96       46666 :         TimeRegion PassTimer(getPassTimer(P));
      97       46666 :         Changed |= P->runOnRegion(CurrentRegion, *this);
      98             :       }
      99             : 
     100       46622 :       if (isPassDebuggingExecutionsOrMore()) {
     101           0 :         if (Changed)
     102           0 :           dumpPassInfo(P, MODIFICATION_MSG, ON_REGION_MSG,
     103           0 :                        skipThisRegion ? "<deleted>" :
     104           0 :                                       CurrentRegion->getNameStr());
     105           0 :         dumpPreservedSet(P);
     106             :       }
     107             : 
     108       46622 :       if (!skipThisRegion) {
     109             :         // Manually check that this region is still healthy. This is done
     110             :         // instead of relying on RegionInfo::verifyRegion since RegionInfo
     111             :         // is a function pass and it's really expensive to verify every
     112             :         // Region in the function every time. That level of checking can be
     113             :         // enabled with the -verify-region-info option.
     114             :         {
     115       46622 :           TimeRegion PassTimer(getPassTimer(P));
     116       46622 :           CurrentRegion->verifyRegion();
     117             :         }
     118             : 
     119             :         // Then call the regular verifyAnalysis functions.
     120       46621 :         verifyPreservedAnalysis(P);
     121             :       }
     122             : 
     123       46621 :       removeNotPreservedAnalysis(P);
     124       46621 :       recordAvailableAnalysis(P);
     125       46621 :       removeDeadPasses(P,
     126       93242 :                        (!isPassDebuggingExecutionsOrMore() || skipThisRegion) ?
     127           0 :                        "<deleted>" :  CurrentRegion->getNameStr(),
     128             :                        ON_REGION_MSG);
     129             : 
     130       46621 :       if (skipThisRegion)
     131             :         // Do not run other passes on this region.
     132             :         break;
     133             :     }
     134             : 
     135             :     // If the region was deleted, release all the region passes. This frees up
     136             :     // some memory, and avoids trouble with the pass manager trying to call
     137             :     // verifyAnalysis on them.
     138       27697 :     if (skipThisRegion)
     139           0 :       for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
     140             :         Pass *P = getContainedPass(Index);
     141           0 :         freePass(P, "<deleted>", ON_REGION_MSG);
     142             :       }
     143             : 
     144             :     // Pop the region from queue after running all passes.
     145       27697 :     RQ.pop_back();
     146             : 
     147       27697 :     if (redoThisRegion)
     148           0 :       RQ.push_back(CurrentRegion);
     149             : 
     150             :     // Free all region nodes created in region passes.
     151       27697 :     RI->clearNodeCache();
     152             :   }
     153             : 
     154             :   // Finalization
     155       74341 :   for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
     156             :     RegionPass *P = (RegionPass*)getContainedPass(Index);
     157       26637 :     Changed |= P->doFinalization();
     158             :   }
     159             : 
     160             :   // Print the region tree after all pass.
     161             :   DEBUG(
     162             :     dbgs() << "\nRegion tree of function " << F.getName()
     163             :            << " after all region Pass:\n";
     164             :     RI->dump();
     165             :     dbgs() << "\n";
     166             :     );
     167             : 
     168             :   return Changed;
     169             : }
     170             : 
     171             : /// Print passes managed by this manager
     172           0 : void RGPassManager::dumpPassStructure(unsigned Offset) {
     173           0 :   errs().indent(Offset*2) << "Region Pass Manager\n";
     174           0 :   for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
     175             :     Pass *P = getContainedPass(Index);
     176           0 :     P->dumpPassStructure(Offset + 1);
     177           0 :     dumpLastUses(P, Offset+1);
     178             :   }
     179           0 : }
     180             : 
     181             : namespace {
     182             : //===----------------------------------------------------------------------===//
     183             : // PrintRegionPass
     184           0 : class PrintRegionPass : public RegionPass {
     185             : private:
     186             :   std::string Banner;
     187             :   raw_ostream &Out;       // raw_ostream to print on.
     188             : 
     189             : public:
     190             :   static char ID;
     191             :   PrintRegionPass(const std::string &B, raw_ostream &o)
     192           0 :       : RegionPass(ID), Banner(B), Out(o) {}
     193             : 
     194           0 :   void getAnalysisUsage(AnalysisUsage &AU) const override {
     195             :     AU.setPreservesAll();
     196           0 :   }
     197             : 
     198           0 :   bool runOnRegion(Region *R, RGPassManager &RGM) override {
     199           0 :     Out << Banner;
     200           0 :     for (const auto *BB : R->blocks()) {
     201           0 :       if (BB)
     202           0 :         BB->print(Out);
     203             :       else
     204           0 :         Out << "Printing <null> Block";
     205             :     }
     206             : 
     207           0 :     return false;
     208             :   }
     209             : 
     210           0 :   StringRef getPassName() const override { return "Print Region IR"; }
     211             : };
     212             : 
     213             : char PrintRegionPass::ID = 0;
     214             : }  //end anonymous namespace
     215             : 
     216             : //===----------------------------------------------------------------------===//
     217             : // RegionPass
     218             : 
     219             : // Check if this pass is suitable for the current RGPassManager, if
     220             : // available. This pass P is not suitable for a RGPassManager if P
     221             : // is not preserving higher level analysis info used by other
     222             : // RGPassManager passes. In such case, pop RGPassManager from the
     223             : // stack. This will force assignPassManager() to create new
     224             : // LPPassManger as expected.
     225        9337 : void RegionPass::preparePassManager(PMStack &PMS) {
     226             : 
     227             :   // Find RGPassManager
     228       18674 :   while (!PMS.empty() &&
     229        9337 :          PMS.top()->getPassManagerType() > PMT_RegionPassManager)
     230           0 :     PMS.pop();
     231             : 
     232             : 
     233             :   // If this pass is destroying high level information that is used
     234             :   // by other passes that are managed by LPM then do not insert
     235             :   // this pass in current LPM. Use new RGPassManager.
     236       13159 :   if (PMS.top()->getPassManagerType() == PMT_RegionPassManager &&
     237        3822 :     !PMS.top()->preserveHigherLevelAnalysis(this))
     238           0 :     PMS.pop();
     239        9337 : }
     240             : 
     241             : /// Assign pass manager to manage this pass.
     242        9337 : void RegionPass::assignPassManager(PMStack &PMS,
     243             :                                  PassManagerType PreferredType) {
     244             :   // Find RGPassManager
     245       18674 :   while (!PMS.empty() &&
     246        9337 :          PMS.top()->getPassManagerType() > PMT_RegionPassManager)
     247           0 :     PMS.pop();
     248             : 
     249             :   RGPassManager *RGPM;
     250             : 
     251             :   // Create new Region Pass Manager if it does not exist.
     252        9337 :   if (PMS.top()->getPassManagerType() == PMT_RegionPassManager)
     253        5144 :     RGPM = (RGPassManager*)PMS.top();
     254             :   else {
     255             : 
     256             :     assert (!PMS.empty() && "Unable to create Region Pass Manager");
     257             :     PMDataManager *PMD = PMS.top();
     258             : 
     259             :     // [1] Create new Region Pass Manager
     260        4193 :     RGPM = new RGPassManager();
     261             :     RGPM->populateInheritedAnalysis(PMS);
     262             : 
     263             :     // [2] Set up new manager's top level manager
     264        4193 :     PMTopLevelManager *TPM = PMD->getTopLevelManager();
     265        4193 :     TPM->addIndirectPassManager(RGPM);
     266             : 
     267             :     // [3] Assign manager to manage this new manager. This may create
     268             :     // and push new managers into PMS
     269        4193 :     TPM->schedulePass(RGPM);
     270             : 
     271             :     // [4] Push new manager into PMS
     272        4193 :     PMS.push(RGPM);
     273             :   }
     274             : 
     275        9337 :   RGPM->add(this);
     276        9337 : }
     277             : 
     278             : /// Get the printer pass
     279           0 : Pass *RegionPass::createPrinterPass(raw_ostream &O,
     280             :                                   const std::string &Banner) const {
     281           0 :   return new PrintRegionPass(Banner, O);
     282             : }
     283             : 
     284       12500 : bool RegionPass::skipRegion(Region &R) const {
     285       12500 :   Function &F = *R.getEntry()->getParent();
     286       12500 :   if (!F.getContext().getOptBisect().shouldRunPass(this, R))
     287             :     return true;
     288             : 
     289       12500 :   if (F.hasFnAttribute(Attribute::OptimizeNone)) {
     290             :     // Report this only once per function.
     291             :     if (R.getEntry() == &F.getEntryBlock())
     292             :       DEBUG(dbgs() << "Skipping pass '" << getPassName()
     293             :             << "' on function " << F.getName() << "\n");
     294           0 :     return true;
     295             :   }
     296             :   return false;
     297             : }

Generated by: LCOV version 1.13