blob: 550d2545a1500ccf3518f63307476ff535882e26 [file] [log] [blame]
Jean Christophe Beyler2469e602014-05-06 20:36:55 -07001/*
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
Narayan Kamathfd5a8522014-05-30 11:58:09 +010017#ifndef ART_COMPILER_DEX_POST_OPT_PASSES_H_
18#define ART_COMPILER_DEX_POST_OPT_PASSES_H_
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070019
Andreas Gampe53c913b2014-08-12 23:19:23 -070020#include "dex/quick/mir_to_lir.h"
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070021#include "compiler_internals.h"
22#include "pass_me.h"
23
24namespace art {
25
26/**
27 * @class InitializeData
28 * @brief There is some data that needs to be initialized before performing
29 * the post optimization passes.
30 */
31class InitializeData : public PassME {
32 public:
33 InitializeData() : PassME("InitializeData") {
34 }
35
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070036 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070037 // New blocks may have been inserted so the first thing we do is ensure that
38 // the c_unit's number of blocks matches the actual count of basic blocks.
39 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070040 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070041 DCHECK(c_unit != nullptr);
42 c_unit->mir_graph.get()->InitializeBasicBlockData();
43 c_unit->mir_graph.get()->SSATransformationStart();
44 }
45};
46
47/**
48 * @class MethodUseCount
49 * @brief Count the register uses of the method
50 */
51class MethodUseCount : public PassME {
52 public:
53 MethodUseCount() : PassME("UseCount") {
54 }
55
56 bool Worker(const PassDataHolder* data) const;
57
58 bool Gate(const PassDataHolder* data) const;
59};
60
61/**
62 * @class ClearPhiInformation
63 * @brief Clear the PHI nodes from the CFG.
64 */
65class ClearPhiInstructions : public PassME {
66 public:
67 ClearPhiInstructions() : PassME("ClearPhiInstructions") {
68 }
69
70 bool Worker(const PassDataHolder* data) const;
71};
72
73/**
74 * @class CalculatePredecessors
75 * @brief Calculate the predecessor BitVector of each Basicblock.
76 */
77class CalculatePredecessors : public PassME {
78 public:
79 CalculatePredecessors() : PassME("CalculatePredecessors") {
80 }
81
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070082 void Start(PassDataHolder* data) const;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070083};
84
85/**
86 * @class DFSOrders
87 * @brief Compute the DFS order of the MIR graph
88 */
89class DFSOrders : public PassME {
90 public:
91 DFSOrders() : PassME("DFSOrders") {
92 }
93
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070094 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070095 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070096 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070097 DCHECK(c_unit != nullptr);
98 c_unit->mir_graph.get()->ComputeDFSOrders();
99 }
100};
101
102/**
103 * @class BuildDomination
104 * @brief Build the domination information of the MIR Graph
105 */
106class BuildDomination : public PassME {
107 public:
108 BuildDomination() : PassME("BuildDomination") {
109 }
110
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700111 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700112 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700113 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700114 DCHECK(c_unit != nullptr);
115 c_unit->mir_graph.get()->ComputeDominators();
116 c_unit->mir_graph.get()->CompilerInitializeSSAConversion();
117 }
118
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700119 void End(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700120 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700121 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700122 DCHECK(c_unit != nullptr);
123 // Verify the dataflow information after the pass.
124 if (c_unit->enable_debug & (1 << kDebugVerifyDataflow)) {
125 c_unit->mir_graph->VerifyDataflow();
126 }
127 }
128};
129
130/**
Vladimir Marko622bdbe2014-06-19 14:59:05 +0100131 * @class TopologicalSortOrders
132 * @brief Compute the topological sort order of the MIR graph
133 */
134class TopologicalSortOrders : public PassME {
135 public:
136 TopologicalSortOrders() : PassME("TopologicalSortOrders") {
137 }
138
139 void Start(PassDataHolder* data) const {
140 DCHECK(data != nullptr);
141 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
142 DCHECK(c_unit != nullptr);
143 c_unit->mir_graph.get()->ComputeTopologicalSortOrder();
144 }
145};
146
147/**
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700148 * @class DefBlockMatrix
149 * @brief Calculate the matrix of definition per basic block
150 */
151class DefBlockMatrix : public PassME {
152 public:
153 DefBlockMatrix() : PassME("DefBlockMatrix") {
154 }
155
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700156 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700157 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700158 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700159 DCHECK(c_unit != nullptr);
160 c_unit->mir_graph.get()->ComputeDefBlockMatrix();
161 }
162};
163
164/**
165 * @class CreatePhiNodes
166 * @brief Pass to create the phi nodes after SSA calculation
167 */
168class CreatePhiNodes : public PassME {
169 public:
170 CreatePhiNodes() : PassME("CreatePhiNodes") {
171 }
172
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700173 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700174 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700175 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700176 DCHECK(c_unit != nullptr);
177 c_unit->mir_graph.get()->InsertPhiNodes();
178 }
179};
180
181/**
182 * @class ClearVisitedFlag
183 * @brief Pass to clear the visited flag for all basic blocks.
184 */
185
186class ClearVisitedFlag : public PassME {
187 public:
188 ClearVisitedFlag() : PassME("ClearVisitedFlag") {
189 }
190
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700191 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700192 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700193 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700194 DCHECK(c_unit != nullptr);
195 c_unit->mir_graph.get()->ClearAllVisitedFlags();
196 }
197};
198
199/**
200 * @class SSAConversion
201 * @brief Pass for SSA conversion of MIRs
202 */
203class SSAConversion : public PassME {
204 public:
205 SSAConversion() : PassME("SSAConversion") {
206 }
207
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700208 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700209 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700210 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700211 DCHECK(c_unit != nullptr);
212 MIRGraph *mir_graph = c_unit->mir_graph.get();
213 mir_graph->DoDFSPreOrderSSARename(mir_graph->GetEntryBlock());
214 }
215};
216
217/**
218 * @class PhiNodeOperands
219 * @brief Pass to insert the Phi node operands to basic blocks
220 */
221class PhiNodeOperands : public PassME {
222 public:
223 PhiNodeOperands() : PassME("PhiNodeOperands", kPreOrderDFSTraversal) {
224 }
225
226 bool Worker(const PassDataHolder* data) const {
227 DCHECK(data != nullptr);
228 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
229 DCHECK(c_unit != nullptr);
230 BasicBlock* bb = down_cast<const PassMEDataHolder*>(data)->bb;
231 DCHECK(bb != nullptr);
232 c_unit->mir_graph->InsertPhiNodeOperands(bb);
233 // No need of repeating, so just return false.
234 return false;
235 }
236};
237
238/**
239 * @class InitRegLocations
240 * @brief Initialize Register Locations.
241 */
242class PerformInitRegLocations : public PassME {
243 public:
244 PerformInitRegLocations() : PassME("PerformInitRegLocation") {
245 }
246
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700247 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700248 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700249 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700250 DCHECK(c_unit != nullptr);
251 c_unit->mir_graph->InitRegLocations();
252 }
253};
254
255/**
256 * @class ConstantPropagation
257 * @brief Perform a constant propagation pass.
258 */
259class ConstantPropagation : public PassME {
260 public:
261 ConstantPropagation() : PassME("ConstantPropagation") {
262 }
263
264 bool Worker(const PassDataHolder* data) const {
265 DCHECK(data != nullptr);
266 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
267 DCHECK(c_unit != nullptr);
268 BasicBlock* bb = down_cast<const PassMEDataHolder*>(data)->bb;
269 DCHECK(bb != nullptr);
270 c_unit->mir_graph->DoConstantPropagation(bb);
271 // No need of repeating, so just return false.
272 return false;
273 }
274
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700275 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700276 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700277 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700278 DCHECK(c_unit != nullptr);
279 c_unit->mir_graph->InitializeConstantPropagation();
280 }
281};
282
283/**
284 * @class FreeData
285 * @brief There is some data that needs to be freed after performing the post optimization passes.
286 */
287class FreeData : public PassME {
288 public:
289 FreeData() : PassME("FreeData") {
290 }
291
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700292 void End(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700293 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700294 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700295 DCHECK(c_unit != nullptr);
296 c_unit->mir_graph.get()->SSATransformationEnd();
297 }
298};
299
300} // namespace art
301
Narayan Kamathfd5a8522014-05-30 11:58:09 +0100302#endif // ART_COMPILER_DEX_POST_OPT_PASSES_H_