LCOV - code coverage report
Current view: top level - lib/Analysis - RegionPass.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 70 105 66.7 %
Date: 2018-10-20 13:21:21 Functions: 7 12 58.3 %
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/IR/PassTimingInfo.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        4495 : RGPassManager::RGPassManager()
      33        4495 :   : FunctionPass(ID), PMDataManager() {
      34        4495 :   skipThisRegion = false;
      35        4495 :   redoThisRegion = false;
      36        4495 :   RI = nullptr;
      37        4495 :   CurrentRegion = nullptr;
      38        4495 : }
      39             : 
      40             : // Recurse through all subregions and all regions  into RQ.
      41       31241 : static void addRegionIntoQueue(Region &R, std::deque<Region *> &RQ) {
      42       62482 :   RQ.push_back(&R);
      43       38283 :   for (const auto &E : R)
      44        7042 :     addRegionIntoQueue(*E, RQ);
      45       31241 : }
      46             : 
      47             : /// Pass Manager itself does not invalidate any analysis info.
      48        4495 : void RGPassManager::getAnalysisUsage(AnalysisUsage &Info) const {
      49             :   Info.addRequired<RegionInfoPass>();
      50             :   Info.setPreservesAll();
      51        4495 : }
      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       24199 : bool RGPassManager::runOnFunction(Function &F) {
      56       24199 :   RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
      57             :   bool Changed = false;
      58             : 
      59             :   // Collect inherited analysis from Module level pass manager.
      60       24199 :   populateInheritedAnalysis(TPM->activeStack);
      61             : 
      62       24199 :   addRegionIntoQueue(*RI->getTopLevelRegion(), RQ);
      63             : 
      64       24199 :   if (RQ.empty()) // No regions, skip calling finalizers
      65             :     return false;
      66             : 
      67             :   // Initialization
      68       55440 :   for (Region *R : RQ) {
      69       82762 :     for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
      70             :       RegionPass *RP = (RegionPass *)getContainedPass(Index);
      71       51521 :       Changed |= RP->doInitialization(R, *this);
      72             :     }
      73             :   }
      74             : 
      75             :   // Walk Regions
      76       55351 :   while (!RQ.empty()) {
      77             : 
      78       31197 :     CurrentRegion  = RQ.back();
      79       31197 :     skipThisRegion = false;
      80       31197 :     redoThisRegion = false;
      81             : 
      82             :     // Run all passes on the current Region.
      83       82435 :     for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
      84             :       RegionPass *P = (RegionPass*)getContainedPass(Index);
      85             : 
      86       51283 :       if (isPassDebuggingExecutionsOrMore()) {
      87           0 :         dumpPassInfo(P, EXECUTION_MSG, ON_REGION_MSG,
      88           0 :                      CurrentRegion->getNameStr());
      89           0 :         dumpRequiredSet(P);
      90             :       }
      91             : 
      92       51283 :       initializeAnalysisImpl(P);
      93             : 
      94             :       {
      95      102566 :         PassManagerPrettyStackEntry X(P, *CurrentRegion->getEntry());
      96             : 
      97       51283 :         TimeRegion PassTimer(getPassTimer(P));
      98       51283 :         Changed |= P->runOnRegion(CurrentRegion, *this);
      99             :       }
     100             : 
     101       51239 :       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       51239 :       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       51239 :           TimeRegion PassTimer(getPassTimer(P));
     117       51239 :           CurrentRegion->verifyRegion();
     118             :         }
     119             : 
     120             :         // Then call the regular verifyAnalysis functions.
     121       51238 :         verifyPreservedAnalysis(P);
     122             :       }
     123             : 
     124       51238 :       removeNotPreservedAnalysis(P);
     125       51238 :       recordAvailableAnalysis(P);
     126       51238 :       removeDeadPasses(P,
     127       51238 :                        (!isPassDebuggingExecutionsOrMore() || skipThisRegion) ?
     128           0 :                        "<deleted>" :  CurrentRegion->getNameStr(),
     129             :                        ON_REGION_MSG);
     130             : 
     131       51238 :       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       31152 :     if (skipThisRegion)
     140           0 :       for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
     141             :         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       31152 :     RQ.pop_back();
     147             : 
     148       31152 :     if (redoThisRegion)
     149           0 :       RQ.push_back(CurrentRegion);
     150             : 
     151             :     // Free all region nodes created in region passes.
     152       31152 :     RI->clearNodeCache();
     153             :   }
     154             : 
     155             :   // Finalization
     156       53948 :   for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
     157             :     RegionPass *P = (RegionPass*)getContainedPass(Index);
     158       29794 :     Changed |= P->doFinalization();
     159             :   }
     160             : 
     161             :   // Print the region tree after all pass.
     162             :   LLVM_DEBUG(dbgs() << "\nRegion tree of function " << F.getName()
     163             :                     << " after all region Pass:\n";
     164             :              RI->dump(); dbgs() << "\n";);
     165             : 
     166             :   return Changed;
     167             : }
     168             : 
     169             : /// Print passes managed by this manager
     170           0 : void RGPassManager::dumpPassStructure(unsigned Offset) {
     171           0 :   errs().indent(Offset*2) << "Region Pass Manager\n";
     172           0 :   for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
     173             :     Pass *P = getContainedPass(Index);
     174           0 :     P->dumpPassStructure(Offset + 1);
     175           0 :     dumpLastUses(P, Offset+1);
     176             :   }
     177           0 : }
     178             : 
     179             : namespace {
     180             : //===----------------------------------------------------------------------===//
     181             : // PrintRegionPass
     182             : class PrintRegionPass : public RegionPass {
     183             : private:
     184             :   std::string Banner;
     185             :   raw_ostream &Out;       // raw_ostream to print on.
     186             : 
     187             : public:
     188             :   static char ID;
     189             :   PrintRegionPass(const std::string &B, raw_ostream &o)
     190           0 :       : RegionPass(ID), Banner(B), Out(o) {}
     191             : 
     192           0 :   void getAnalysisUsage(AnalysisUsage &AU) const override {
     193             :     AU.setPreservesAll();
     194           0 :   }
     195             : 
     196           0 :   bool runOnRegion(Region *R, RGPassManager &RGM) override {
     197           0 :     Out << Banner;
     198           0 :     for (const auto *BB : R->blocks()) {
     199           0 :       if (BB)
     200           0 :         BB->print(Out);
     201             :       else
     202           0 :         Out << "Printing <null> Block";
     203             :     }
     204             : 
     205           0 :     return false;
     206             :   }
     207             : 
     208           0 :   StringRef getPassName() const override { return "Print Region IR"; }
     209             : };
     210             : 
     211             : char PrintRegionPass::ID = 0;
     212             : }  //end anonymous namespace
     213             : 
     214             : //===----------------------------------------------------------------------===//
     215             : // RegionPass
     216             : 
     217             : // Check if this pass is suitable for the current RGPassManager, if
     218             : // available. This pass P is not suitable for a RGPassManager if P
     219             : // is not preserving higher level analysis info used by other
     220             : // RGPassManager passes. In such case, pop RGPassManager from the
     221             : // stack. This will force assignPassManager() to create new
     222             : // LPPassManger as expected.
     223        9681 : void RegionPass::preparePassManager(PMStack &PMS) {
     224             : 
     225             :   // Find RGPassManager
     226        9681 :   while (!PMS.empty() &&
     227        9681 :          PMS.top()->getPassManagerType() > PMT_RegionPassManager)
     228           0 :     PMS.pop();
     229             : 
     230             : 
     231             :   // If this pass is destroying high level information that is used
     232             :   // by other passes that are managed by LPM then do not insert
     233             :   // this pass in current LPM. Use new RGPassManager.
     234       13537 :   if (PMS.top()->getPassManagerType() == PMT_RegionPassManager &&
     235        3856 :     !PMS.top()->preserveHigherLevelAnalysis(this))
     236           0 :     PMS.pop();
     237        9681 : }
     238             : 
     239             : /// Assign pass manager to manage this pass.
     240        9681 : void RegionPass::assignPassManager(PMStack &PMS,
     241             :                                  PassManagerType PreferredType) {
     242             :   // Find RGPassManager
     243        9681 :   while (!PMS.empty() &&
     244        9681 :          PMS.top()->getPassManagerType() > PMT_RegionPassManager)
     245           0 :     PMS.pop();
     246             : 
     247             :   RGPassManager *RGPM;
     248             : 
     249             :   // Create new Region Pass Manager if it does not exist.
     250        9681 :   if (PMS.top()->getPassManagerType() == PMT_RegionPassManager)
     251        5186 :     RGPM = (RGPassManager*)PMS.top();
     252             :   else {
     253             : 
     254             :     assert (!PMS.empty() && "Unable to create Region Pass Manager");
     255             :     PMDataManager *PMD = PMS.top();
     256             : 
     257             :     // [1] Create new Region Pass Manager
     258        4495 :     RGPM = new RGPassManager();
     259             :     RGPM->populateInheritedAnalysis(PMS);
     260             : 
     261             :     // [2] Set up new manager's top level manager
     262        4495 :     PMTopLevelManager *TPM = PMD->getTopLevelManager();
     263        4495 :     TPM->addIndirectPassManager(RGPM);
     264             : 
     265             :     // [3] Assign manager to manage this new manager. This may create
     266             :     // and push new managers into PMS
     267        4495 :     TPM->schedulePass(RGPM);
     268             : 
     269             :     // [4] Push new manager into PMS
     270        4495 :     PMS.push(RGPM);
     271             :   }
     272             : 
     273        9681 :   RGPM->add(this);
     274        9681 : }
     275             : 
     276             : /// Get the printer pass
     277           0 : Pass *RegionPass::createPrinterPass(raw_ostream &O,
     278             :                                   const std::string &Banner) const {
     279           0 :   return new PrintRegionPass(Banner, O);
     280             : }
     281             : 
     282       13134 : bool RegionPass::skipRegion(Region &R) const {
     283       13134 :   Function &F = *R.getEntry()->getParent();
     284       13134 :   if (!F.getContext().getOptPassGate().shouldRunPass(this, R))
     285             :     return true;
     286             : 
     287       13134 :   if (F.hasFnAttribute(Attribute::OptimizeNone)) {
     288             :     // Report this only once per function.
     289             :     if (R.getEntry() == &F.getEntryBlock())
     290             :       LLVM_DEBUG(dbgs() << "Skipping pass '" << getPassName()
     291             :                         << "' on function " << F.getName() << "\n");
     292           0 :     return true;
     293             :   }
     294             :   return false;
     295             : }

Generated by: LCOV version 1.13