]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | //===- 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" | |
223e47cc | 18 | #include "llvm/Support/Debug.h" |
85aaf69f | 19 | #include "llvm/Support/Timer.h" |
223e47cc LB |
20 | using namespace llvm; |
21 | ||
1a4d82fc JJ |
22 | #define DEBUG_TYPE "regionpassmgr" |
23 | ||
223e47cc LB |
24 | //===----------------------------------------------------------------------===// |
25 | // RGPassManager | |
26 | // | |
27 | ||
28 | char RGPassManager::ID = 0; | |
29 | ||
30 | RGPassManager::RGPassManager() | |
31 | : FunctionPass(ID), PMDataManager() { | |
32 | skipThisRegion = false; | |
33 | redoThisRegion = false; | |
1a4d82fc JJ |
34 | RI = nullptr; |
35 | CurrentRegion = nullptr; | |
223e47cc LB |
36 | } |
37 | ||
38 | // Recurse through all subregions and all regions into RQ. | |
1a4d82fc JJ |
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); | |
223e47cc LB |
43 | } |
44 | ||
45 | /// Pass Manager itself does not invalidate any analysis info. | |
46 | void RGPassManager::getAnalysisUsage(AnalysisUsage &Info) const { | |
1a4d82fc | 47 | Info.addRequired<RegionInfoPass>(); |
223e47cc LB |
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. | |
53 | bool RGPassManager::runOnFunction(Function &F) { | |
1a4d82fc | 54 | RI = &getAnalysis<RegionInfoPass>().getRegionInfo(); |
223e47cc LB |
55 | bool Changed = false; |
56 | ||
57 | // Collect inherited analysis from Module level pass manager. | |
58 | populateInheritedAnalysis(TPM->activeStack); | |
59 | ||
1a4d82fc | 60 | addRegionIntoQueue(*RI->getTopLevelRegion(), RQ); |
223e47cc LB |
61 | |
62 | if (RQ.empty()) // No regions, skip calling finalizers | |
63 | return false; | |
64 | ||
65 | // Initialization | |
66 | for (std::deque<Region *>::const_iterator I = RQ.begin(), E = RQ.end(); | |
67 | I != E; ++I) { | |
68 | Region *R = *I; | |
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 | dumpPassInfo(P, EXECUTION_MSG, ON_REGION_MSG, | |
87 | CurrentRegion->getNameStr()); | |
88 | dumpRequiredSet(P); | |
89 | ||
90 | initializeAnalysisImpl(P); | |
91 | ||
92 | { | |
93 | PassManagerPrettyStackEntry X(P, *CurrentRegion->getEntry()); | |
94 | ||
95 | TimeRegion PassTimer(getPassTimer(P)); | |
96 | Changed |= P->runOnRegion(CurrentRegion, *this); | |
97 | } | |
98 | ||
99 | if (Changed) | |
100 | dumpPassInfo(P, MODIFICATION_MSG, ON_REGION_MSG, | |
101 | skipThisRegion ? "<deleted>" : | |
102 | CurrentRegion->getNameStr()); | |
103 | dumpPreservedSet(P); | |
104 | ||
105 | if (!skipThisRegion) { | |
106 | // Manually check that this region is still healthy. This is done | |
107 | // instead of relying on RegionInfo::verifyRegion since RegionInfo | |
108 | // is a function pass and it's really expensive to verify every | |
109 | // Region in the function every time. That level of checking can be | |
110 | // enabled with the -verify-region-info option. | |
111 | { | |
112 | TimeRegion PassTimer(getPassTimer(P)); | |
113 | CurrentRegion->verifyRegion(); | |
114 | } | |
115 | ||
116 | // Then call the regular verifyAnalysis functions. | |
117 | verifyPreservedAnalysis(P); | |
118 | } | |
119 | ||
120 | removeNotPreservedAnalysis(P); | |
121 | recordAvailableAnalysis(P); | |
122 | removeDeadPasses(P, | |
123 | skipThisRegion ? "<deleted>" : | |
124 | CurrentRegion->getNameStr(), | |
125 | ON_REGION_MSG); | |
126 | ||
127 | if (skipThisRegion) | |
128 | // Do not run other passes on this region. | |
129 | break; | |
130 | } | |
131 | ||
132 | // If the region was deleted, release all the region passes. This frees up | |
133 | // some memory, and avoids trouble with the pass manager trying to call | |
134 | // verifyAnalysis on them. | |
135 | if (skipThisRegion) | |
136 | for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { | |
137 | Pass *P = getContainedPass(Index); | |
138 | freePass(P, "<deleted>", ON_REGION_MSG); | |
139 | } | |
140 | ||
141 | // Pop the region from queue after running all passes. | |
142 | RQ.pop_back(); | |
143 | ||
144 | if (redoThisRegion) | |
145 | RQ.push_back(CurrentRegion); | |
146 | ||
147 | // Free all region nodes created in region passes. | |
148 | RI->clearNodeCache(); | |
149 | } | |
150 | ||
151 | // Finalization | |
152 | for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { | |
153 | RegionPass *P = (RegionPass*)getContainedPass(Index); | |
154 | Changed |= P->doFinalization(); | |
155 | } | |
156 | ||
157 | // Print the region tree after all pass. | |
158 | DEBUG( | |
159 | dbgs() << "\nRegion tree of function " << F.getName() | |
160 | << " after all region Pass:\n"; | |
161 | RI->dump(); | |
162 | dbgs() << "\n"; | |
163 | ); | |
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; | |
223e47cc LB |
188 | PrintRegionPass(const std::string &B, raw_ostream &o) |
189 | : RegionPass(ID), Banner(B), Out(o) {} | |
190 | ||
1a4d82fc | 191 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
223e47cc LB |
192 | AU.setPreservesAll(); |
193 | } | |
194 | ||
1a4d82fc | 195 | bool runOnRegion(Region *R, RGPassManager &RGM) override { |
223e47cc | 196 | Out << Banner; |
1a4d82fc JJ |
197 | for (const auto &BB : R->blocks()) { |
198 | if (BB) | |
199 | BB->print(Out); | |
200 | else | |
201 | Out << "Printing <null> Block"; | |
202 | } | |
223e47cc LB |
203 | |
204 | return false; | |
205 | } | |
206 | }; | |
207 | ||
208 | char PrintRegionPass::ID = 0; | |
209 | } //end anonymous namespace | |
210 | ||
211 | //===----------------------------------------------------------------------===// | |
212 | // RegionPass | |
213 | ||
214 | // Check if this pass is suitable for the current RGPassManager, if | |
215 | // available. This pass P is not suitable for a RGPassManager if P | |
216 | // is not preserving higher level analysis info used by other | |
217 | // RGPassManager passes. In such case, pop RGPassManager from the | |
218 | // stack. This will force assignPassManager() to create new | |
219 | // LPPassManger as expected. | |
220 | void RegionPass::preparePassManager(PMStack &PMS) { | |
221 | ||
222 | // Find RGPassManager | |
223 | while (!PMS.empty() && | |
224 | PMS.top()->getPassManagerType() > PMT_RegionPassManager) | |
225 | PMS.pop(); | |
226 | ||
227 | ||
228 | // If this pass is destroying high level information that is used | |
229 | // by other passes that are managed by LPM then do not insert | |
230 | // this pass in current LPM. Use new RGPassManager. | |
231 | if (PMS.top()->getPassManagerType() == PMT_RegionPassManager && | |
232 | !PMS.top()->preserveHigherLevelAnalysis(this)) | |
233 | PMS.pop(); | |
234 | } | |
235 | ||
236 | /// Assign pass manager to manage this pass. | |
237 | void RegionPass::assignPassManager(PMStack &PMS, | |
238 | PassManagerType PreferredType) { | |
239 | // Find RGPassManager | |
240 | while (!PMS.empty() && | |
241 | PMS.top()->getPassManagerType() > PMT_RegionPassManager) | |
242 | PMS.pop(); | |
243 | ||
244 | RGPassManager *RGPM; | |
245 | ||
246 | // Create new Region Pass Manager if it does not exist. | |
247 | if (PMS.top()->getPassManagerType() == PMT_RegionPassManager) | |
248 | RGPM = (RGPassManager*)PMS.top(); | |
249 | else { | |
250 | ||
251 | assert (!PMS.empty() && "Unable to create Region Pass Manager"); | |
252 | PMDataManager *PMD = PMS.top(); | |
253 | ||
254 | // [1] Create new Region Pass Manager | |
255 | RGPM = new RGPassManager(); | |
256 | RGPM->populateInheritedAnalysis(PMS); | |
257 | ||
258 | // [2] Set up new manager's top level manager | |
259 | PMTopLevelManager *TPM = PMD->getTopLevelManager(); | |
260 | TPM->addIndirectPassManager(RGPM); | |
261 | ||
262 | // [3] Assign manager to manage this new manager. This may create | |
263 | // and push new managers into PMS | |
264 | TPM->schedulePass(RGPM); | |
265 | ||
266 | // [4] Push new manager into PMS | |
267 | PMS.push(RGPM); | |
268 | } | |
269 | ||
270 | RGPM->add(this); | |
271 | } | |
272 | ||
273 | /// Get the printer pass | |
274 | Pass *RegionPass::createPrinterPass(raw_ostream &O, | |
275 | const std::string &Banner) const { | |
276 | return new PrintRegionPass(Banner, O); | |
277 | } |