blob: 3a529f2096beedd49a39bde3c6c9c75f3477c61c [file] [log] [blame]
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -08001/*
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_BB_OPTIMIZATIONS_H_
18#define ART_COMPILER_DEX_BB_OPTIMIZATIONS_H_
19
20#include "compiler_internals.h"
James C Scott4f596682014-05-01 05:52:04 -070021#include "pass_me.h"
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -080022
23namespace art {
24
25/**
Vladimir Markobe0e5462014-02-26 11:24:15 +000026 * @class CacheFieldLoweringInfo
27 * @brief Cache the lowering info for fields used by IGET/IPUT/SGET/SPUT insns.
28 */
James C Scott4f596682014-05-01 05:52:04 -070029class CacheFieldLoweringInfo : public PassME {
Vladimir Markobe0e5462014-02-26 11:24:15 +000030 public:
James C Scott4f596682014-05-01 05:52:04 -070031 CacheFieldLoweringInfo() : PassME("CacheFieldLoweringInfo", kNoNodes) {
Vladimir Markobe0e5462014-02-26 11:24:15 +000032 }
33
James C Scott4f596682014-05-01 05:52:04 -070034 void Start(const PassDataHolder* data) const {
35 DCHECK(data != nullptr);
36 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
37 DCHECK(cUnit != nullptr);
Vladimir Markobe0e5462014-02-26 11:24:15 +000038 cUnit->mir_graph->DoCacheFieldLoweringInfo();
39 }
Vladimir Marko3d73ba22014-03-06 15:18:04 +000040
James C Scott4f596682014-05-01 05:52:04 -070041 bool Gate(const PassDataHolder* data) const {
42 DCHECK(data != nullptr);
43 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
44 DCHECK(cUnit != nullptr);
Vladimir Marko3d73ba22014-03-06 15:18:04 +000045 return cUnit->mir_graph->HasFieldAccess();
46 }
Vladimir Markobe0e5462014-02-26 11:24:15 +000047};
48
49/**
Vladimir Markof096aad2014-01-23 15:51:58 +000050 * @class CacheMethodLoweringInfo
51 * @brief Cache the lowering info for methods called by INVOKEs.
52 */
James C Scott4f596682014-05-01 05:52:04 -070053class CacheMethodLoweringInfo : public PassME {
Vladimir Markof096aad2014-01-23 15:51:58 +000054 public:
James C Scott4f596682014-05-01 05:52:04 -070055 CacheMethodLoweringInfo() : PassME("CacheMethodLoweringInfo", kNoNodes) {
Vladimir Markof096aad2014-01-23 15:51:58 +000056 }
57
James C Scott4f596682014-05-01 05:52:04 -070058 void Start(const PassDataHolder* data) const {
59 DCHECK(data != nullptr);
60 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
61 DCHECK(cUnit != nullptr);
Vladimir Markof096aad2014-01-23 15:51:58 +000062 cUnit->mir_graph->DoCacheMethodLoweringInfo();
63 }
Vladimir Marko3d73ba22014-03-06 15:18:04 +000064
James C Scott4f596682014-05-01 05:52:04 -070065 bool Gate(const PassDataHolder* data) const {
66 DCHECK(data != nullptr);
67 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
68 DCHECK(cUnit != nullptr);
Vladimir Marko3d73ba22014-03-06 15:18:04 +000069 return cUnit->mir_graph->HasInvokes();
70 }
Vladimir Markof096aad2014-01-23 15:51:58 +000071};
72
73/**
Vladimir Marko9820b7c2014-01-02 16:40:37 +000074 * @class CallInlining
75 * @brief Perform method inlining pass.
76 */
James C Scott4f596682014-05-01 05:52:04 -070077class CallInlining : public PassME {
Vladimir Marko9820b7c2014-01-02 16:40:37 +000078 public:
James C Scott4f596682014-05-01 05:52:04 -070079 CallInlining() : PassME("CallInlining") {
Vladimir Marko9820b7c2014-01-02 16:40:37 +000080 }
81
James C Scott4f596682014-05-01 05:52:04 -070082 bool Gate(const PassDataHolder* data) const {
83 DCHECK(data != nullptr);
84 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
85 DCHECK(cUnit != nullptr);
Vladimir Marko9820b7c2014-01-02 16:40:37 +000086 return cUnit->mir_graph->InlineCallsGate();
87 }
88
James C Scott4f596682014-05-01 05:52:04 -070089 void Start(const PassDataHolder* data) const {
90 DCHECK(data != nullptr);
91 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
92 DCHECK(cUnit != nullptr);
Vladimir Marko9820b7c2014-01-02 16:40:37 +000093 cUnit->mir_graph->InlineCallsStart();
94 }
95
James C Scott4f596682014-05-01 05:52:04 -070096 bool Worker(const PassDataHolder* data) const {
97 DCHECK(data != nullptr);
98 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data);
99 CompilationUnit* cUnit = pass_me_data_holder->c_unit;
100 DCHECK(cUnit != nullptr);
101 BasicBlock* bb = pass_me_data_holder->bb;
102 DCHECK(bb != nullptr);
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000103 cUnit->mir_graph->InlineCalls(bb);
104 // No need of repeating, so just return false.
105 return false;
106 }
107
James C Scott4f596682014-05-01 05:52:04 -0700108 void End(const PassDataHolder* data) const {
109 DCHECK(data != nullptr);
110 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
111 DCHECK(cUnit != nullptr);
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000112 cUnit->mir_graph->InlineCallsEnd();
113 }
114};
115
116/**
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800117 * @class CodeLayout
118 * @brief Perform the code layout pass.
119 */
James C Scott4f596682014-05-01 05:52:04 -0700120class CodeLayout : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800121 public:
James C Scott4f596682014-05-01 05:52:04 -0700122 CodeLayout() : PassME("CodeLayout", "2_post_layout_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800123 }
124
James C Scott4f596682014-05-01 05:52:04 -0700125 void Start(const PassDataHolder* data) const {
126 DCHECK(data != nullptr);
127 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
128 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800129 cUnit->mir_graph->VerifyDataflow();
130 }
131
James C Scott4f596682014-05-01 05:52:04 -0700132 bool Worker(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800133};
134
135/**
136 * @class SSATransformation
137 * @brief Perform an SSA representation pass on the CompilationUnit.
138 */
James C Scott4f596682014-05-01 05:52:04 -0700139class SSATransformation : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800140 public:
James C Scott4f596682014-05-01 05:52:04 -0700141 SSATransformation() : PassME("SSATransformation", kPreOrderDFSTraversal, "3_post_ssa_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800142 }
143
James C Scott4f596682014-05-01 05:52:04 -0700144 bool Worker(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800145
Vladimir Markoa5b8fde2014-05-23 15:16:44 +0100146 void Start(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800147
James C Scott4f596682014-05-01 05:52:04 -0700148 void End(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800149};
150
151/**
152 * @class ConstantPropagation
153 * @brief Perform a constant propagation pass.
154 */
James C Scott4f596682014-05-01 05:52:04 -0700155class ConstantPropagation : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800156 public:
James C Scott4f596682014-05-01 05:52:04 -0700157 ConstantPropagation() : PassME("ConstantPropagation") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800158 }
159
James C Scott4f596682014-05-01 05:52:04 -0700160 bool Worker(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800161
James C Scott4f596682014-05-01 05:52:04 -0700162 void Start(const PassDataHolder* data) const {
163 DCHECK(data != nullptr);
164 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
165 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800166 cUnit->mir_graph->InitializeConstantPropagation();
167 }
168};
169
170/**
171 * @class InitRegLocations
172 * @brief Initialize Register Locations.
173 */
James C Scott4f596682014-05-01 05:52:04 -0700174class InitRegLocations : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800175 public:
James C Scott4f596682014-05-01 05:52:04 -0700176 InitRegLocations() : PassME("InitRegLocation", kNoNodes) {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800177 }
178
James C Scott4f596682014-05-01 05:52:04 -0700179 void Start(const PassDataHolder* data) const {
180 DCHECK(data != nullptr);
181 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
182 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800183 cUnit->mir_graph->InitRegLocations();
184 }
185};
186
187/**
188 * @class MethodUseCount
189 * @brief Count the register uses of the method
190 */
James C Scott4f596682014-05-01 05:52:04 -0700191class MethodUseCount : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800192 public:
James C Scott4f596682014-05-01 05:52:04 -0700193 MethodUseCount() : PassME("UseCount") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800194 }
195
James C Scott4f596682014-05-01 05:52:04 -0700196 bool Worker(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800197
James C Scott4f596682014-05-01 05:52:04 -0700198 bool Gate(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800199};
200
201/**
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800202 * @class NullCheckEliminationAndTypeInference
203 * @brief Null check elimination and type inference.
204 */
James C Scott4f596682014-05-01 05:52:04 -0700205class NullCheckEliminationAndTypeInference : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800206 public:
Vladimir Marko75ba13f2014-01-28 12:15:24 +0000207 NullCheckEliminationAndTypeInference()
James C Scott4f596682014-05-01 05:52:04 -0700208 : PassME("NCE_TypeInference", kRepeatingPreOrderDFSTraversal, "4_post_nce_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800209 }
210
James C Scott4f596682014-05-01 05:52:04 -0700211 void Start(const PassDataHolder* data) const {
212 DCHECK(data != nullptr);
213 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
214 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000215 cUnit->mir_graph->EliminateNullChecksAndInferTypesStart();
216 }
217
James C Scott4f596682014-05-01 05:52:04 -0700218 bool Worker(const PassDataHolder* data) const {
219 DCHECK(data != nullptr);
220 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data);
221 CompilationUnit* cUnit = pass_me_data_holder->c_unit;
222 DCHECK(cUnit != nullptr);
223 BasicBlock* bb = pass_me_data_holder->bb;
224 DCHECK(bb != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800225 return cUnit->mir_graph->EliminateNullChecksAndInferTypes(bb);
226 }
Vladimir Markobfea9c22014-01-17 17:49:33 +0000227
James C Scott4f596682014-05-01 05:52:04 -0700228 void End(const PassDataHolder* data) const {
229 DCHECK(data != nullptr);
230 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
231 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000232 cUnit->mir_graph->EliminateNullChecksAndInferTypesEnd();
233 }
234};
235
James C Scott4f596682014-05-01 05:52:04 -0700236class ClassInitCheckElimination : public PassME {
Vladimir Markobfea9c22014-01-17 17:49:33 +0000237 public:
James C Scott4f596682014-05-01 05:52:04 -0700238 ClassInitCheckElimination() : PassME("ClInitCheckElimination", kRepeatingPreOrderDFSTraversal) {
Vladimir Markobfea9c22014-01-17 17:49:33 +0000239 }
240
James C Scott4f596682014-05-01 05:52:04 -0700241 bool Gate(const PassDataHolder* data) const {
242 DCHECK(data != nullptr);
243 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
244 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000245 return cUnit->mir_graph->EliminateClassInitChecksGate();
246 }
247
James C Scott4f596682014-05-01 05:52:04 -0700248 bool Worker(const PassDataHolder* data) const {
249 DCHECK(data != nullptr);
250 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data);
251 CompilationUnit* cUnit = pass_me_data_holder->c_unit;
252 DCHECK(cUnit != nullptr);
253 BasicBlock* bb = pass_me_data_holder->bb;
254 DCHECK(bb != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000255 return cUnit->mir_graph->EliminateClassInitChecks(bb);
256 }
257
James C Scott4f596682014-05-01 05:52:04 -0700258 void End(const PassDataHolder* data) const {
259 DCHECK(data != nullptr);
260 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
261 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000262 cUnit->mir_graph->EliminateClassInitChecksEnd();
263 }
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800264};
265
266/**
267 * @class NullCheckEliminationAndTypeInference
268 * @brief Null check elimination and type inference.
269 */
James C Scott4f596682014-05-01 05:52:04 -0700270class BBCombine : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800271 public:
James C Scott4f596682014-05-01 05:52:04 -0700272 BBCombine() : PassME("BBCombine", kPreOrderDFSTraversal, "5_post_bbcombine_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800273 }
274
James C Scott4f596682014-05-01 05:52:04 -0700275 bool Gate(const PassDataHolder* data) const {
276 DCHECK(data != nullptr);
277 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
278 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800279 return ((cUnit->disable_opt & (1 << kSuppressExceptionEdges)) != 0);
280 }
281
James C Scott4f596682014-05-01 05:52:04 -0700282 bool Worker(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800283};
284
285/**
286 * @class BasicBlock Optimizations
287 * @brief Any simple BasicBlock optimization can be put here.
288 */
James C Scott4f596682014-05-01 05:52:04 -0700289class BBOptimizations : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800290 public:
James C Scott4f596682014-05-01 05:52:04 -0700291 BBOptimizations() : PassME("BBOptimizations", kNoNodes, "5_post_bbo_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800292 }
293
James C Scott4f596682014-05-01 05:52:04 -0700294 bool Gate(const PassDataHolder* data) const {
295 DCHECK(data != nullptr);
296 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
297 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800298 return ((cUnit->disable_opt & (1 << kBBOpt)) == 0);
299 }
300
James C Scott4f596682014-05-01 05:52:04 -0700301 void Start(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800302};
303
304} // namespace art
305
306#endif // ART_COMPILER_DEX_BB_OPTIMIZATIONS_H_