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