xref: /freebsd/contrib/llvm-project/llvm/lib/Analysis/RegionPass.cpp (revision 6be3386466ab79a84b48429ae66244f21526d3df)
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