blob: 71de14450b7e8a977e295f5073e09934c18ef7e7 [file] [log] [blame]
Tobias Grosser23c83412010-10-20 01:54:44 +00001//===- 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 these codes are COPY from LoopPass.cpp
14//
15//===----------------------------------------------------------------------===//
16#include "llvm/Analysis/RegionPass.h"
17#include "llvm/Analysis/RegionIterator.h"
18#include "llvm/Support/Timer.h"
19
Tobias Grosser23c83412010-10-20 01:54:44 +000020#include "llvm/Support/Debug.h"
21using namespace llvm;
22
Chandler Carruthf1221bd2014-04-22 02:48:03 +000023#define DEBUG_TYPE "regionpassmgr"
24
Tobias Grosser23c83412010-10-20 01:54:44 +000025//===----------------------------------------------------------------------===//
26// RGPassManager
27//
28
29char RGPassManager::ID = 0;
30
Andrew Trick08966212011-08-29 17:07:00 +000031RGPassManager::RGPassManager()
32 : FunctionPass(ID), PMDataManager() {
Tobias Grosser23c83412010-10-20 01:54:44 +000033 skipThisRegion = false;
34 redoThisRegion = false;
Craig Topper9f008862014-04-15 04:59:12 +000035 RI = nullptr;
36 CurrentRegion = nullptr;
Tobias Grosser23c83412010-10-20 01:54:44 +000037}
38
39// Recurse through all subregions and all regions into RQ.
David Blaikieec649ac2014-04-15 18:32:43 +000040static void addRegionIntoQueue(Region &R, std::deque<Region *> &RQ) {
41 RQ.push_back(&R);
42 for (const auto &E : R)
43 addRegionIntoQueue(*E, RQ);
Tobias Grosser23c83412010-10-20 01:54:44 +000044}
45
46/// Pass Manager itself does not invalidate any analysis info.
47void RGPassManager::getAnalysisUsage(AnalysisUsage &Info) const {
48 Info.addRequired<RegionInfo>();
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.
54bool RGPassManager::runOnFunction(Function &F) {
55 RI = &getAnalysis<RegionInfo>();
56 bool Changed = false;
57
58 // Collect inherited analysis from Module level pass manager.
59 populateInheritedAnalysis(TPM->activeStack);
60
David Blaikieec649ac2014-04-15 18:32:43 +000061 addRegionIntoQueue(*RI->getTopLevelRegion(), RQ);
Tobias Grosser23c83412010-10-20 01:54:44 +000062
63 if (RQ.empty()) // No regions, skip calling finalizers
64 return false;
65
66 // Initialization
67 for (std::deque<Region *>::const_iterator I = RQ.begin(), E = RQ.end();
68 I != E; ++I) {
69 Region *R = *I;
70 for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
71 RegionPass *RP = (RegionPass *)getContainedPass(Index);
72 Changed |= RP->doInitialization(R, *this);
73 }
74 }
75
76 // Walk Regions
77 while (!RQ.empty()) {
78
79 CurrentRegion = RQ.back();
80 skipThisRegion = false;
81 redoThisRegion = false;
82
83 // Run all passes on the current Region.
84 for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
85 RegionPass *P = (RegionPass*)getContainedPass(Index);
86
87 dumpPassInfo(P, EXECUTION_MSG, ON_REGION_MSG,
88 CurrentRegion->getNameStr());
89 dumpRequiredSet(P);
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 (Changed)
101 dumpPassInfo(P, MODIFICATION_MSG, ON_REGION_MSG,
102 skipThisRegion ? "<deleted>" :
103 CurrentRegion->getNameStr());
104 dumpPreservedSet(P);
105
106 if (!skipThisRegion) {
107 // Manually check that this region is still healthy. This is done
108 // instead of relying on RegionInfo::verifyRegion since RegionInfo
109 // is a function pass and it's really expensive to verify every
110 // Region in the function every time. That level of checking can be
111 // enabled with the -verify-region-info option.
112 {
113 TimeRegion PassTimer(getPassTimer(P));
114 CurrentRegion->verifyRegion();
115 }
116
117 // Then call the regular verifyAnalysis functions.
118 verifyPreservedAnalysis(P);
119 }
120
121 removeNotPreservedAnalysis(P);
122 recordAvailableAnalysis(P);
123 removeDeadPasses(P,
124 skipThisRegion ? "<deleted>" :
125 CurrentRegion->getNameStr(),
126 ON_REGION_MSG);
127
128 if (skipThisRegion)
129 // Do not run other passes on this region.
130 break;
131 }
132
133 // If the region was deleted, release all the region passes. This frees up
134 // some memory, and avoids trouble with the pass manager trying to call
135 // verifyAnalysis on them.
136 if (skipThisRegion)
137 for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
138 Pass *P = getContainedPass(Index);
139 freePass(P, "<deleted>", ON_REGION_MSG);
140 }
141
142 // Pop the region from queue after running all passes.
143 RQ.pop_back();
144
145 if (redoThisRegion)
146 RQ.push_back(CurrentRegion);
147
148 // Free all region nodes created in region passes.
149 RI->clearNodeCache();
150 }
151
152 // Finalization
153 for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
154 RegionPass *P = (RegionPass*)getContainedPass(Index);
155 Changed |= P->doFinalization();
156 }
157
158 // Print the region tree after all pass.
159 DEBUG(
160 dbgs() << "\nRegion tree of function " << F.getName()
161 << " after all region Pass:\n";
162 RI->dump();
163 dbgs() << "\n";
164 );
165
166 return Changed;
167}
168
169/// Print passes managed by this manager
170void RGPassManager::dumpPassStructure(unsigned Offset) {
171 errs().indent(Offset*2) << "Region Pass Manager\n";
172 for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
173 Pass *P = getContainedPass(Index);
174 P->dumpPassStructure(Offset + 1);
175 dumpLastUses(P, Offset+1);
176 }
177}
178
179namespace {
180//===----------------------------------------------------------------------===//
181// PrintRegionPass
182class PrintRegionPass : public RegionPass {
183private:
184 std::string Banner;
185 raw_ostream &Out; // raw_ostream to print on.
186
187public:
188 static char ID;
Tobias Grosser23c83412010-10-20 01:54:44 +0000189 PrintRegionPass(const std::string &B, raw_ostream &o)
190 : RegionPass(ID), Banner(B), Out(o) {}
191
Craig Toppere9ba7592014-03-05 07:30:04 +0000192 void getAnalysisUsage(AnalysisUsage &AU) const override {
Tobias Grosser23c83412010-10-20 01:54:44 +0000193 AU.setPreservesAll();
194 }
195
Craig Toppere9ba7592014-03-05 07:30:04 +0000196 bool runOnRegion(Region *R, RGPassManager &RGM) override {
Tobias Grosser23c83412010-10-20 01:54:44 +0000197 Out << Banner;
Richard Trieua23043c2014-06-09 22:53:16 +0000198 for (const auto &BB : R->blocks()) {
Richard Trieuc1485222014-06-21 02:43:02 +0000199 if (BB)
200 BB->print(Out);
201 else
202 Out << "Printing <null> Block";
Richard Trieua23043c2014-06-09 22:53:16 +0000203 }
Tobias Grosser23c83412010-10-20 01:54:44 +0000204
205 return false;
206 }
207};
208
209char PrintRegionPass::ID = 0;
210} //end anonymous namespace
211
212//===----------------------------------------------------------------------===//
213// RegionPass
214
215// Check if this pass is suitable for the current RGPassManager, if
216// available. This pass P is not suitable for a RGPassManager if P
217// is not preserving higher level analysis info used by other
218// RGPassManager passes. In such case, pop RGPassManager from the
219// stack. This will force assignPassManager() to create new
220// LPPassManger as expected.
221void RegionPass::preparePassManager(PMStack &PMS) {
222
223 // Find RGPassManager
224 while (!PMS.empty() &&
225 PMS.top()->getPassManagerType() > PMT_RegionPassManager)
226 PMS.pop();
227
228
229 // If this pass is destroying high level information that is used
230 // by other passes that are managed by LPM then do not insert
231 // this pass in current LPM. Use new RGPassManager.
232 if (PMS.top()->getPassManagerType() == PMT_RegionPassManager &&
233 !PMS.top()->preserveHigherLevelAnalysis(this))
234 PMS.pop();
235}
236
237/// Assign pass manager to manage this pass.
238void RegionPass::assignPassManager(PMStack &PMS,
239 PassManagerType PreferredType) {
240 // Find RGPassManager
241 while (!PMS.empty() &&
242 PMS.top()->getPassManagerType() > PMT_RegionPassManager)
243 PMS.pop();
244
245 RGPassManager *RGPM;
246
247 // Create new Region Pass Manager if it does not exist.
248 if (PMS.top()->getPassManagerType() == PMT_RegionPassManager)
249 RGPM = (RGPassManager*)PMS.top();
250 else {
251
252 assert (!PMS.empty() && "Unable to create Region Pass Manager");
253 PMDataManager *PMD = PMS.top();
254
Hongbin Zhengcd5afc52011-05-05 13:59:38 +0000255 // [1] Create new Region Pass Manager
Andrew Trick08966212011-08-29 17:07:00 +0000256 RGPM = new RGPassManager();
Tobias Grosser23c83412010-10-20 01:54:44 +0000257 RGPM->populateInheritedAnalysis(PMS);
258
259 // [2] Set up new manager's top level manager
260 PMTopLevelManager *TPM = PMD->getTopLevelManager();
261 TPM->addIndirectPassManager(RGPM);
262
263 // [3] Assign manager to manage this new manager. This may create
264 // and push new managers into PMS
Tobias Grosserf3e1ada2010-12-12 21:58:28 +0000265 TPM->schedulePass(RGPM);
Tobias Grosser23c83412010-10-20 01:54:44 +0000266
267 // [4] Push new manager into PMS
268 PMS.push(RGPM);
269 }
270
271 RGPM->add(this);
272}
273
274/// Get the printer pass
275Pass *RegionPass::createPrinterPass(raw_ostream &O,
276 const std::string &Banner) const {
277 return new PrintRegionPass(Banner, O);
278}