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