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

Generated by: LCOV version 1.13