LLVM  12.0.0git
RegionPass.cpp
Go to the documentation of this file.
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 //===----------------------------------------------------------------------===//
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"
22 using namespace llvm;
23 
24 #define DEBUG_TYPE "regionpassmgr"
25 
26 //===----------------------------------------------------------------------===//
27 // RGPassManager
28 //
29 
30 char RGPassManager::ID = 0;
31 
34  RI = nullptr;
35  CurrentRegion = nullptr;
36 }
37 
38 // Recurse through all subregions and all regions into RQ.
39 static void addRegionIntoQueue(Region &R, std::deque<Region *> &RQ) {
40  RQ.push_back(&R);
41  for (const auto &E : R)
42  addRegionIntoQueue(*E, RQ);
43 }
44 
45 /// Pass Manager itself does not invalidate any analysis info.
47  Info.addRequired<RegionInfoPass>();
48  Info.setPreservesAll();
49 }
50 
51 /// run - Execute all of the passes scheduled for execution. Keep track of
52 /// whether any of the passes modifies the function, and if so, return true.
54  RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
55  bool Changed = false;
56 
57  // Collect inherited analysis from Module level pass manager.
59 
61 
62  if (RQ.empty()) // No regions, skip calling finalizers
63  return false;
64 
65  // Initialization
66  for (Region *R : RQ) {
67  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
69  Changed |= RP->doInitialization(R, *this);
70  }
71  }
72 
73  // Walk Regions
74  while (!RQ.empty()) {
75 
76  CurrentRegion = RQ.back();
77 
78  // Run all passes on the current Region.
79  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
81 
84  CurrentRegion->getNameStr());
86  }
87 
89 
90  bool LocalChanged = false;
91  {
92  PassManagerPrettyStackEntry X(P, *CurrentRegion->getEntry());
93 
94  TimeRegion PassTimer(getPassTimer(P));
95 #ifdef EXPENSIVE_CHECKS
96  uint64_t RefHash = StructuralHash(F);
97 #endif
98  LocalChanged = P->runOnRegion(CurrentRegion, *this);
99 
100 #ifdef EXPENSIVE_CHECKS
101  if (!LocalChanged && (RefHash != StructuralHash(F))) {
102  llvm::errs() << "Pass modifies its input and doesn't report it: "
103  << P->getPassName() << "\n";
104  llvm_unreachable("Pass modifies its input and doesn't report it");
105  }
106 #endif
107 
108  Changed |= LocalChanged;
109  }
110 
112  if (LocalChanged)
114  CurrentRegion->getNameStr());
116  }
117 
118  // Manually check that this region is still healthy. This is done
119  // instead of relying on RegionInfo::verifyRegion since RegionInfo
120  // is a function pass and it's really expensive to verify every
121  // Region in the function every time. That level of checking can be
122  // enabled with the -verify-region-info option.
123  {
124  TimeRegion PassTimer(getPassTimer(P));
125  CurrentRegion->verifyRegion();
126  }
127 
128  // Then call the regular verifyAnalysis functions.
130 
131  if (LocalChanged)
136  ? "<deleted>"
137  : CurrentRegion->getNameStr(),
138  ON_REGION_MSG);
139  }
140 
141  // Pop the region from queue after running all passes.
142  RQ.pop_back();
143 
144  // Free all region nodes created in region passes.
145  RI->clearNodeCache();
146  }
147 
148  // Finalization
149  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
151  Changed |= P->doFinalization();
152  }
153 
154  // Print the region tree after all pass.
155  LLVM_DEBUG(dbgs() << "\nRegion tree of function " << F.getName()
156  << " after all region Pass:\n";
157  RI->dump(); dbgs() << "\n";);
158 
159  return Changed;
160 }
161 
162 /// Print passes managed by this manager
164  errs().indent(Offset*2) << "Region Pass Manager\n";
165  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
167  P->dumpPassStructure(Offset + 1);
168  dumpLastUses(P, Offset+1);
169  }
170 }
171 
172 namespace {
173 //===----------------------------------------------------------------------===//
174 // PrintRegionPass
175 class PrintRegionPass : public RegionPass {
176 private:
177  std::string Banner;
178  raw_ostream &Out; // raw_ostream to print on.
179 
180 public:
181  static char ID;
182  PrintRegionPass(const std::string &B, raw_ostream &o)
183  : RegionPass(ID), Banner(B), Out(o) {}
184 
185  void getAnalysisUsage(AnalysisUsage &AU) const override {
186  AU.setPreservesAll();
187  }
188 
189  bool runOnRegion(Region *R, RGPassManager &RGM) override {
190  Out << Banner;
191  for (const auto *BB : R->blocks()) {
192  if (BB)
193  BB->print(Out);
194  else
195  Out << "Printing <null> Block";
196  }
197 
198  return false;
199  }
200 
201  StringRef getPassName() const override { return "Print Region IR"; }
202 };
203 
204 char PrintRegionPass::ID = 0;
205 } //end anonymous namespace
206 
207 //===----------------------------------------------------------------------===//
208 // RegionPass
209 
210 // Check if this pass is suitable for the current RGPassManager, if
211 // available. This pass P is not suitable for a RGPassManager if P
212 // is not preserving higher level analysis info used by other
213 // RGPassManager passes. In such case, pop RGPassManager from the
214 // stack. This will force assignPassManager() to create new
215 // LPPassManger as expected.
217 
218  // Find RGPassManager
219  while (!PMS.empty() &&
221  PMS.pop();
222 
223 
224  // If this pass is destroying high level information that is used
225  // by other passes that are managed by LPM then do not insert
226  // this pass in current LPM. Use new RGPassManager.
227  if (PMS.top()->getPassManagerType() == PMT_RegionPassManager &&
228  !PMS.top()->preserveHigherLevelAnalysis(this))
229  PMS.pop();
230 }
231 
232 /// Assign pass manager to manage this pass.
234  PassManagerType PreferredType) {
235  // Find RGPassManager
236  while (!PMS.empty() &&
238  PMS.pop();
239 
240  RGPassManager *RGPM;
241 
242  // Create new Region Pass Manager if it does not exist.
244  RGPM = (RGPassManager*)PMS.top();
245  else {
246 
247  assert (!PMS.empty() && "Unable to create Region Pass Manager");
248  PMDataManager *PMD = PMS.top();
249 
250  // [1] Create new Region Pass Manager
251  RGPM = new RGPassManager();
252  RGPM->populateInheritedAnalysis(PMS);
253 
254  // [2] Set up new manager's top level manager
255  PMTopLevelManager *TPM = PMD->getTopLevelManager();
256  TPM->addIndirectPassManager(RGPM);
257 
258  // [3] Assign manager to manage this new manager. This may create
259  // and push new managers into PMS
260  TPM->schedulePass(RGPM);
261 
262  // [4] Push new manager into PMS
263  PMS.push(RGPM);
264  }
265 
266  RGPM->add(this);
267 }
268 
269 /// Get the printer pass
271  const std::string &Banner) const {
272  return new PrintRegionPass(Banner, O);
273 }
274 
275 static std::string getDescription(const Region &R) {
276  return "region";
277 }
278 
280  Function &F = *R.getEntry()->getParent();
281  OptPassGate &Gate = F.getContext().getOptPassGate();
282  if (Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(R)))
283  return true;
284 
285  if (F.hasOptNone()) {
286  // Report this only once per function.
287  if (R.getEntry() == &F.getEntryBlock())
288  LLVM_DEBUG(dbgs() << "Skipping pass '" << getPassName()
289  << "' on function " << F.getName() << "\n");
290  return true;
291  }
292  return false;
293 }
PMTopLevelManager * TPM
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
bool preserveHigherLevelAnalysis(Pass *P)
PassManagerType
Different types of internal pass managers.
Definition: Pass.h:52
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
This class represents lattice values for constants.
Definition: AllocatorList.h:23
void dumpLastUses(Pass *P, unsigned Offset) const
Pass * createPrinterPass(raw_ostream &O, const std::string &Banner) const override
Get a pass to print the LLVM IR in the region.
Definition: RegionPass.cpp:270
Extensions to this class implement mechanisms to disable passes and individual optimizations at compi...
Definition: OptBisect.h:26
static void addRegionIntoQueue(Region &R, std::deque< Region * > &RQ)
Definition: RegionPass.cpp:39
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
bool skipRegion(Region &R) const
Optional passes call this function to check whether the pass should be skipped.
Definition: RegionPass.cpp:279
F(f)
void dumpPassInfo(Pass *P, enum PassDebuggingString S1, enum PassDebuggingString S2, StringRef Msg)
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:76
The pass manager to schedule RegionPasses.
Definition: RegionPass.h:86
virtual bool shouldRunPass(const Pass *P, StringRef IRDescription)
IRDescription is a textual description of the IR unit the pass is running over.
Definition: OptBisect.h:32
PMTopLevelManager manages LastUser info and collects common APIs used by top level pass managers.
Timer * getPassTimer(Pass *)
Request the timer for this legacy-pass-manager's pass instance.
The TimeRegion class is used as a helper class to call the startTimer() and stopTimer() methods of th...
Definition: Timer.h:140
void schedulePass(Pass *P)
Schedule pass P for execution.
void verifyPreservedAnalysis(Pass *P)
verifyPreservedAnalysis – Verify analysis presreved by pass P.
void populateInheritedAnalysis(PMStack &PMS)
static char ID
Definition: RegionPass.h:92
This header defines classes/functions to handle pass execution timing information with interfaces for...
PMStack - This class implements a stack data structure of PMDataManager pointers.
void initializeAnalysisImpl(Pass *P)
All Required analyses should be available to the pass as it runs! Here we fill in the AnalysisImpls m...
virtual bool isEnabled() const
isEnabled() should return true before calling shouldRunPass().
Definition: OptBisect.h:37
PassManagerPrettyStackEntry - This is used to print informative information about what pass is runnin...
RegionT * getTopLevelRegion() const
Definition: RegionInfo.h:866
bool isPassDebuggingExecutionsOrMore() const
isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions or higher is specified.
void add(Pass *P, bool ProcessAnalysis=true)
Add pass P into the PassVector.
Analysis containing CSE Info
Definition: CSEInfo.cpp:25
void dumpPassStructure(unsigned Offset) override
Print passes managed by this manager.
Definition: RegionPass.cpp:163
#define P(N)
void assignPassManager(PMStack &PMS, PassManagerType PMT=PMT_RegionPassManager) override
Assign pass manager to manage this pass.
Definition: RegionPass.cpp:233
void preparePassManager(PMStack &PMS) override
Check if available pass managers are suitable for this pass or not.
Definition: RegionPass.cpp:216
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static std::string getDescription(const Region &R)
Definition: RegionPass.cpp:275
A pass that runs on each Region in a function.
Definition: RegionPass.h:31
void addIndirectPassManager(PMDataManager *Manager)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
virtual PassManagerType getPassManagerType() const
Represent the analysis usage information of a pass.
bool runOnFunction(Function &F) override
Execute all of the passes scheduled for execution.
Definition: RegionPass.cpp:53
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
Pass * getContainedPass(unsigned N)
Get passes contained by this manager.
Definition: RegionPass.h:113
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint64_t Offset
void recordAvailableAnalysis(Pass *P)
Augment AvailableAnalysis by adding analysis made available by pass P.
BlockT * getEntry() const
Get the entry BasicBlock of the Region.
Definition: RegionInfo.h:322
void dumpRequiredSet(const Pass *P) const
void removeNotPreservedAnalysis(Pass *P)
Remove Analysis that is not preserved by the pass.
uint32_t Index
void removeDeadPasses(Pass *P, StringRef Msg, enum PassDebuggingString)
Remove dead passes used by P.
This file declares the interface for bisecting optimizations.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
void setPreservesAll()
Set by analyses that do not transform their input at all.
std::string getNameStr() const
Returns the name of the Region.
void verifyRegion() const
Verify if the region is a correct region.
RGPassManager.
Definition: Pass.h:58
void push(PMDataManager *PM)
PMDataManager provides the common place to manage the analysis data used by pass managers.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
PMDataManager * top() const
void clearNodeCache()
Clear the Node Cache for all Regions.
Definition: RegionInfo.h:871
unsigned getNumContainedPasses() const
bool empty() const
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:50
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
void getAnalysisUsage(AnalysisUsage &Info) const override
Pass Manager itself does not invalidate any analysis info.
Definition: RegionPass.cpp:46
#define LLVM_DEBUG(X)
Definition: Debug.h:122
void dumpPreservedSet(const Pass *P) const