• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_COMPILER_DEX_POST_OPT_PASSES_H_
18 #define ART_COMPILER_DEX_POST_OPT_PASSES_H_
19 
20 #include "compiler_internals.h"
21 #include "pass_me.h"
22 
23 namespace art {
24 
25 /**
26  * @class InitializeData
27  * @brief There is some data that needs to be initialized before performing
28  * the post optimization passes.
29  */
30 class InitializeData : public PassME {
31  public:
InitializeData()32   InitializeData() : PassME("InitializeData") {
33   }
34 
Start(PassDataHolder * data)35   void Start(PassDataHolder* data) const {
36     // New blocks may have been inserted so the first thing we do is ensure that
37     // the c_unit's number of blocks matches the actual count of basic blocks.
38     DCHECK(data != nullptr);
39     CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
40     DCHECK(c_unit != nullptr);
41     c_unit->mir_graph.get()->InitializeBasicBlockData();
42     c_unit->mir_graph.get()->SSATransformationStart();
43   }
44 };
45 
46 /**
47  * @class MethodUseCount
48  * @brief Count the register uses of the method
49  */
50 class MethodUseCount : public PassME {
51  public:
MethodUseCount()52   MethodUseCount() : PassME("UseCount") {
53   }
54 
55   bool Worker(const PassDataHolder* data) const;
56 
57   bool Gate(const PassDataHolder* data) const;
58 };
59 
60 /**
61  * @class ClearPhiInformation
62  * @brief Clear the PHI nodes from the CFG.
63  */
64 class ClearPhiInstructions : public PassME {
65  public:
ClearPhiInstructions()66   ClearPhiInstructions() : PassME("ClearPhiInstructions") {
67   }
68 
69   bool Worker(const PassDataHolder* data) const;
70 };
71 
72 /**
73  * @class CalculatePredecessors
74  * @brief Calculate the predecessor BitVector of each Basicblock.
75  */
76 class CalculatePredecessors : public PassME {
77  public:
CalculatePredecessors()78   CalculatePredecessors() : PassME("CalculatePredecessors") {
79   }
80 
81   void Start(PassDataHolder* data) const;
82 };
83 
84 /**
85  * @class DFSOrders
86  * @brief Compute the DFS order of the MIR graph
87  */
88 class DFSOrders : public PassME {
89  public:
DFSOrders()90   DFSOrders() : PassME("DFSOrders") {
91   }
92 
Start(PassDataHolder * data)93   void Start(PassDataHolder* data) const {
94     DCHECK(data != nullptr);
95     CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
96     DCHECK(c_unit != nullptr);
97     c_unit->mir_graph.get()->ComputeDFSOrders();
98   }
99 };
100 
101 /**
102  * @class BuildDomination
103  * @brief Build the domination information of the MIR Graph
104  */
105 class BuildDomination : public PassME {
106  public:
BuildDomination()107   BuildDomination() : PassME("BuildDomination") {
108   }
109 
Start(PassDataHolder * data)110   void Start(PassDataHolder* data) const {
111     DCHECK(data != nullptr);
112     CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
113     DCHECK(c_unit != nullptr);
114     c_unit->mir_graph.get()->ComputeDominators();
115     c_unit->mir_graph.get()->CompilerInitializeSSAConversion();
116   }
117 
End(PassDataHolder * data)118   void End(PassDataHolder* data) const {
119     DCHECK(data != nullptr);
120     CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
121     DCHECK(c_unit != nullptr);
122     // Verify the dataflow information after the pass.
123     if (c_unit->enable_debug & (1 << kDebugVerifyDataflow)) {
124       c_unit->mir_graph->VerifyDataflow();
125     }
126   }
127 };
128 
129 /**
130  * @class TopologicalSortOrders
131  * @brief Compute the topological sort order of the MIR graph
132  */
133 class TopologicalSortOrders : public PassME {
134  public:
TopologicalSortOrders()135   TopologicalSortOrders() : PassME("TopologicalSortOrders") {
136   }
137 
Start(PassDataHolder * data)138   void Start(PassDataHolder* data) const {
139     DCHECK(data != nullptr);
140     CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
141     DCHECK(c_unit != nullptr);
142     c_unit->mir_graph.get()->ComputeTopologicalSortOrder();
143   }
144 };
145 
146 /**
147  * @class DefBlockMatrix
148  * @brief Calculate the matrix of definition per basic block
149  */
150 class DefBlockMatrix : public PassME {
151  public:
DefBlockMatrix()152   DefBlockMatrix() : PassME("DefBlockMatrix") {
153   }
154 
Start(PassDataHolder * data)155   void Start(PassDataHolder* data) const {
156     DCHECK(data != nullptr);
157     CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
158     DCHECK(c_unit != nullptr);
159     c_unit->mir_graph.get()->ComputeDefBlockMatrix();
160   }
161 };
162 
163 /**
164  * @class CreatePhiNodes
165  * @brief Pass to create the phi nodes after SSA calculation
166  */
167 class CreatePhiNodes : public PassME {
168  public:
CreatePhiNodes()169   CreatePhiNodes() : PassME("CreatePhiNodes") {
170   }
171 
Start(PassDataHolder * data)172   void Start(PassDataHolder* data) const {
173     DCHECK(data != nullptr);
174     CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
175     DCHECK(c_unit != nullptr);
176     c_unit->mir_graph.get()->InsertPhiNodes();
177   }
178 };
179 
180 /**
181  * @class ClearVisitedFlag
182  * @brief Pass to clear the visited flag for all basic blocks.
183  */
184 
185 class ClearVisitedFlag : public PassME {
186  public:
ClearVisitedFlag()187   ClearVisitedFlag() : PassME("ClearVisitedFlag") {
188   }
189 
Start(PassDataHolder * data)190   void Start(PassDataHolder* data) const {
191     DCHECK(data != nullptr);
192     CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
193     DCHECK(c_unit != nullptr);
194     c_unit->mir_graph.get()->ClearAllVisitedFlags();
195   }
196 };
197 
198 /**
199  * @class SSAConversion
200  * @brief Pass for SSA conversion of MIRs
201  */
202 class SSAConversion : public PassME {
203  public:
SSAConversion()204   SSAConversion() : PassME("SSAConversion") {
205   }
206 
Start(PassDataHolder * data)207   void Start(PassDataHolder* data) const {
208     DCHECK(data != nullptr);
209     CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
210     DCHECK(c_unit != nullptr);
211     MIRGraph *mir_graph = c_unit->mir_graph.get();
212     mir_graph->DoDFSPreOrderSSARename(mir_graph->GetEntryBlock());
213   }
214 };
215 
216 /**
217  * @class PhiNodeOperands
218  * @brief Pass to insert the Phi node operands to basic blocks
219  */
220 class PhiNodeOperands : public PassME {
221  public:
PhiNodeOperands()222   PhiNodeOperands() : PassME("PhiNodeOperands", kPreOrderDFSTraversal) {
223   }
224 
Worker(const PassDataHolder * data)225   bool Worker(const PassDataHolder* data) const {
226     DCHECK(data != nullptr);
227     CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
228     DCHECK(c_unit != nullptr);
229     BasicBlock* bb = down_cast<const PassMEDataHolder*>(data)->bb;
230     DCHECK(bb != nullptr);
231     c_unit->mir_graph->InsertPhiNodeOperands(bb);
232     // No need of repeating, so just return false.
233     return false;
234   }
235 };
236 
237 /**
238  * @class InitRegLocations
239  * @brief Initialize Register Locations.
240  */
241 class PerformInitRegLocations : public PassME {
242  public:
PerformInitRegLocations()243   PerformInitRegLocations() : PassME("PerformInitRegLocation") {
244   }
245 
Start(PassDataHolder * data)246   void Start(PassDataHolder* data) const {
247     DCHECK(data != nullptr);
248     CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
249     DCHECK(c_unit != nullptr);
250     c_unit->mir_graph->InitRegLocations();
251   }
252 };
253 
254 /**
255  * @class ConstantPropagation
256  * @brief Perform a constant propagation pass.
257  */
258 class ConstantPropagation : public PassME {
259  public:
ConstantPropagation()260   ConstantPropagation() : PassME("ConstantPropagation") {
261   }
262 
Worker(const PassDataHolder * data)263   bool Worker(const PassDataHolder* data) const {
264     DCHECK(data != nullptr);
265     CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
266     DCHECK(c_unit != nullptr);
267     BasicBlock* bb = down_cast<const PassMEDataHolder*>(data)->bb;
268     DCHECK(bb != nullptr);
269     c_unit->mir_graph->DoConstantPropagation(bb);
270     // No need of repeating, so just return false.
271     return false;
272   }
273 
Start(PassDataHolder * data)274   void Start(PassDataHolder* data) const {
275     DCHECK(data != nullptr);
276     CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
277     DCHECK(c_unit != nullptr);
278     c_unit->mir_graph->InitializeConstantPropagation();
279   }
280 };
281 
282 /**
283  * @class FreeData
284  * @brief There is some data that needs to be freed after performing the post optimization passes.
285  */
286 class FreeData : public PassME {
287  public:
FreeData()288   FreeData() : PassME("FreeData") {
289   }
290 
End(PassDataHolder * data)291   void End(PassDataHolder* data) const {
292     DCHECK(data != nullptr);
293     CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
294     DCHECK(c_unit != nullptr);
295     c_unit->mir_graph.get()->SSATransformationEnd();
296   }
297 };
298 
299 }  // namespace art
300 
301 #endif  // ART_COMPILER_DEX_POST_OPT_PASSES_H_
302