blob: 55ae8744511c3b3755800baddce1e300c7813de0 [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/**
Vladimir Markoffda4992014-12-18 17:05:58 +000027 * @class PassMEMirSsaRep
28 * @brief Convenience class for passes that check MIRGraph::MirSsaRepUpToDate().
29 */
30class PassMEMirSsaRep : public PassME {
31 public:
32 PassMEMirSsaRep(const char* name, DataFlowAnalysisMode type = kAllNodes)
33 : PassME(name, type) {
34 }
35
36 bool Gate(const PassDataHolder* data) const OVERRIDE {
37 DCHECK(data != nullptr);
38 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
39 DCHECK(c_unit != nullptr);
40 return !c_unit->mir_graph->MirSsaRepUpToDate();
41 }
42};
43
44/**
45 * @class InitializeSSATransformation
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070046 * @brief There is some data that needs to be initialized before performing
47 * the post optimization passes.
48 */
Vladimir Markoffda4992014-12-18 17:05:58 +000049class InitializeSSATransformation : public PassMEMirSsaRep {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070050 public:
Vladimir Markoffda4992014-12-18 17:05:58 +000051 InitializeSSATransformation() : PassMEMirSsaRep("InitializeSSATransformation", kNoNodes) {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070052 }
53
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070054 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070055 // New blocks may have been inserted so the first thing we do is ensure that
56 // the c_unit's number of blocks matches the actual count of basic blocks.
57 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070058 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070059 DCHECK(c_unit != nullptr);
Vladimir Markoffda4992014-12-18 17:05:58 +000060 c_unit->mir_graph->SSATransformationStart();
61 c_unit->mir_graph->CompilerInitializeSSAConversion();
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070062 }
63};
64
65/**
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070066 * @class ClearPhiInformation
67 * @brief Clear the PHI nodes from the CFG.
68 */
Vladimir Markoffda4992014-12-18 17:05:58 +000069class ClearPhiInstructions : public PassMEMirSsaRep {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070070 public:
Vladimir Markoffda4992014-12-18 17:05:58 +000071 ClearPhiInstructions() : PassMEMirSsaRep("ClearPhiInstructions") {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070072 }
73
Jean Christophe Beyler09321df2014-07-18 15:33:57 -070074 bool Worker(PassDataHolder* data) const;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070075};
76
77/**
78 * @class CalculatePredecessors
79 * @brief Calculate the predecessor BitVector of each Basicblock.
80 */
81class CalculatePredecessors : public PassME {
82 public:
Vladimir Markoaa7b8a32014-10-15 11:35:44 +010083 CalculatePredecessors() : PassME("CalculatePredecessors", kNoNodes) {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070084 }
85
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070086 void Start(PassDataHolder* data) const;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070087};
88
89/**
90 * @class DFSOrders
91 * @brief Compute the DFS order of the MIR graph
92 */
93class DFSOrders : public PassME {
94 public:
Vladimir Markoaa7b8a32014-10-15 11:35:44 +010095 DFSOrders() : PassME("DFSOrders", kNoNodes) {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -070096 }
97
Vladimir Marko312eb252014-10-07 15:01:57 +010098 bool Gate(const PassDataHolder* data) const {
99 DCHECK(data != nullptr);
100 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
101 DCHECK(c_unit != nullptr);
102 return !c_unit->mir_graph->DfsOrdersUpToDate();
103 }
104
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700105 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700106 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700107 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700108 DCHECK(c_unit != nullptr);
109 c_unit->mir_graph.get()->ComputeDFSOrders();
110 }
111};
112
113/**
114 * @class BuildDomination
115 * @brief Build the domination information of the MIR Graph
116 */
117class BuildDomination : public PassME {
118 public:
Vladimir Markoaa7b8a32014-10-15 11:35:44 +0100119 BuildDomination() : PassME("BuildDomination", kNoNodes) {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700120 }
121
Vladimir Markoffda4992014-12-18 17:05:58 +0000122 bool Gate(const PassDataHolder* data) const {
123 DCHECK(data != nullptr);
124 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
125 DCHECK(c_unit != nullptr);
126 return !c_unit->mir_graph->DominationUpToDate();
127 }
128
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700129 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700130 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700131 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700132 DCHECK(c_unit != nullptr);
Vladimir Markoffda4992014-12-18 17:05:58 +0000133 c_unit->mir_graph->ComputeDominators();
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700134 }
135
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700136 void End(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700137 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700138 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700139 DCHECK(c_unit != nullptr);
140 // Verify the dataflow information after the pass.
141 if (c_unit->enable_debug & (1 << kDebugVerifyDataflow)) {
142 c_unit->mir_graph->VerifyDataflow();
143 }
144 }
145};
146
147/**
Vladimir Marko622bdbe2014-06-19 14:59:05 +0100148 * @class TopologicalSortOrders
149 * @brief Compute the topological sort order of the MIR graph
150 */
151class TopologicalSortOrders : public PassME {
152 public:
Vladimir Markoaa7b8a32014-10-15 11:35:44 +0100153 TopologicalSortOrders() : PassME("TopologicalSortOrders", kNoNodes) {
Vladimir Marko622bdbe2014-06-19 14:59:05 +0100154 }
155
Vladimir Markoffda4992014-12-18 17:05:58 +0000156 bool Gate(const PassDataHolder* data) const {
157 DCHECK(data != nullptr);
158 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
159 DCHECK(c_unit != nullptr);
160 return !c_unit->mir_graph->TopologicalOrderUpToDate();
161 }
162
Vladimir Marko622bdbe2014-06-19 14:59:05 +0100163 void Start(PassDataHolder* data) const {
164 DCHECK(data != nullptr);
165 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
166 DCHECK(c_unit != nullptr);
167 c_unit->mir_graph.get()->ComputeTopologicalSortOrder();
168 }
169};
170
171/**
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700172 * @class DefBlockMatrix
173 * @brief Calculate the matrix of definition per basic block
174 */
Vladimir Markoffda4992014-12-18 17:05:58 +0000175class DefBlockMatrix : public PassMEMirSsaRep {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700176 public:
Vladimir Markoffda4992014-12-18 17:05:58 +0000177 DefBlockMatrix() : PassMEMirSsaRep("DefBlockMatrix", kNoNodes) {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700178 }
179
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700180 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700181 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700182 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700183 DCHECK(c_unit != nullptr);
184 c_unit->mir_graph.get()->ComputeDefBlockMatrix();
185 }
186};
187
188/**
189 * @class CreatePhiNodes
190 * @brief Pass to create the phi nodes after SSA calculation
191 */
Vladimir Markoffda4992014-12-18 17:05:58 +0000192class CreatePhiNodes : public PassMEMirSsaRep {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700193 public:
Vladimir Markoffda4992014-12-18 17:05:58 +0000194 CreatePhiNodes() : PassMEMirSsaRep("CreatePhiNodes", kNoNodes) {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700195 }
196
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700197 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700198 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700199 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700200 DCHECK(c_unit != nullptr);
201 c_unit->mir_graph.get()->InsertPhiNodes();
202 }
203};
204
205/**
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700206 * @class SSAConversion
207 * @brief Pass for SSA conversion of MIRs
208 */
Vladimir Markoffda4992014-12-18 17:05:58 +0000209class SSAConversion : public PassMEMirSsaRep {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700210 public:
Vladimir Markoffda4992014-12-18 17:05:58 +0000211 SSAConversion() : PassMEMirSsaRep("SSAConversion", kNoNodes) {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700212 }
213
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700214 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700215 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700216 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700217 DCHECK(c_unit != nullptr);
218 MIRGraph *mir_graph = c_unit->mir_graph.get();
Vladimir Markoffda4992014-12-18 17:05:58 +0000219 mir_graph->ClearAllVisitedFlags();
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700220 mir_graph->DoDFSPreOrderSSARename(mir_graph->GetEntryBlock());
221 }
222};
223
224/**
225 * @class PhiNodeOperands
226 * @brief Pass to insert the Phi node operands to basic blocks
227 */
Vladimir Markoffda4992014-12-18 17:05:58 +0000228class PhiNodeOperands : public PassMEMirSsaRep {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700229 public:
Vladimir Markoffda4992014-12-18 17:05:58 +0000230 PhiNodeOperands() : PassMEMirSsaRep("PhiNodeOperands", kPreOrderDFSTraversal) {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700231 }
232
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700233 bool Worker(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700234 DCHECK(data != nullptr);
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700235 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700236 DCHECK(c_unit != nullptr);
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700237 BasicBlock* bb = down_cast<PassMEDataHolder*>(data)->bb;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700238 DCHECK(bb != nullptr);
239 c_unit->mir_graph->InsertPhiNodeOperands(bb);
240 // No need of repeating, so just return false.
241 return false;
242 }
243};
244
245/**
246 * @class InitRegLocations
247 * @brief Initialize Register Locations.
248 */
Vladimir Markoffda4992014-12-18 17:05:58 +0000249class PerformInitRegLocations : public PassMEMirSsaRep {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700250 public:
Vladimir Markoffda4992014-12-18 17:05:58 +0000251 PerformInitRegLocations() : PassMEMirSsaRep("PerformInitRegLocation", kNoNodes) {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700252 }
253
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700254 void Start(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700255 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700256 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700257 DCHECK(c_unit != nullptr);
258 c_unit->mir_graph->InitRegLocations();
259 }
260};
261
262/**
Vladimir Marko066f9e42015-01-16 16:04:43 +0000263 * @class TypeInference
264 * @brief Type inference pass.
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700265 */
Vladimir Marko066f9e42015-01-16 16:04:43 +0000266class TypeInference : public PassMEMirSsaRep {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700267 public:
Vladimir Marko066f9e42015-01-16 16:04:43 +0000268 TypeInference() : PassMEMirSsaRep("TypeInference", kRepeatingPreOrderDFSTraversal) {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700269 }
270
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700271 bool Worker(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700272 DCHECK(data != nullptr);
Vladimir Marko066f9e42015-01-16 16:04:43 +0000273 PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
274 CompilationUnit* c_unit = pass_me_data_holder->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700275 DCHECK(c_unit != nullptr);
Vladimir Marko066f9e42015-01-16 16:04:43 +0000276 BasicBlock* bb = pass_me_data_holder->bb;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700277 DCHECK(bb != nullptr);
Vladimir Marko066f9e42015-01-16 16:04:43 +0000278 return c_unit->mir_graph->InferTypes(bb);
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700279 }
280};
281
282/**
Vladimir Markoffda4992014-12-18 17:05:58 +0000283 * @class FinishSSATransformation
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700284 * @brief There is some data that needs to be freed after performing the post optimization passes.
285 */
Vladimir Markoffda4992014-12-18 17:05:58 +0000286class FinishSSATransformation : public PassMEMirSsaRep {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700287 public:
Vladimir Markoffda4992014-12-18 17:05:58 +0000288 FinishSSATransformation() : PassMEMirSsaRep("FinishSSATransformation", kNoNodes) {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700289 }
290
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700291 void End(PassDataHolder* data) const {
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700292 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700293 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700294 DCHECK(c_unit != nullptr);
295 c_unit->mir_graph.get()->SSATransformationEnd();
296 }
297};
298
299} // namespace art
300
Narayan Kamathfd5a8522014-05-30 11:58:09 +0100301#endif // ART_COMPILER_DEX_POST_OPT_PASSES_H_