blob: 43dcdf4504689062fa6724abf209c44d14b68474 [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
James C Scott4f596682014-05-01 05:52:04 -0700146 void Start(const PassDataHolder* data) const {
147 DCHECK(data != nullptr);
148 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
149 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800150 cUnit->mir_graph->InitializeSSATransformation();
151 }
152
James C Scott4f596682014-05-01 05:52:04 -0700153 void End(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800154};
155
156/**
157 * @class ConstantPropagation
158 * @brief Perform a constant propagation pass.
159 */
James C Scott4f596682014-05-01 05:52:04 -0700160class ConstantPropagation : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800161 public:
James C Scott4f596682014-05-01 05:52:04 -0700162 ConstantPropagation() : PassME("ConstantPropagation") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800163 }
164
James C Scott4f596682014-05-01 05:52:04 -0700165 bool Worker(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800166
James C Scott4f596682014-05-01 05:52:04 -0700167 void Start(const PassDataHolder* data) const {
168 DCHECK(data != nullptr);
169 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
170 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800171 cUnit->mir_graph->InitializeConstantPropagation();
172 }
173};
174
175/**
176 * @class InitRegLocations
177 * @brief Initialize Register Locations.
178 */
James C Scott4f596682014-05-01 05:52:04 -0700179class InitRegLocations : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800180 public:
James C Scott4f596682014-05-01 05:52:04 -0700181 InitRegLocations() : PassME("InitRegLocation", kNoNodes) {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800182 }
183
James C Scott4f596682014-05-01 05:52:04 -0700184 void Start(const PassDataHolder* data) const {
185 DCHECK(data != nullptr);
186 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
187 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800188 cUnit->mir_graph->InitRegLocations();
189 }
190};
191
192/**
193 * @class MethodUseCount
194 * @brief Count the register uses of the method
195 */
James C Scott4f596682014-05-01 05:52:04 -0700196class MethodUseCount : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800197 public:
James C Scott4f596682014-05-01 05:52:04 -0700198 MethodUseCount() : PassME("UseCount") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800199 }
200
James C Scott4f596682014-05-01 05:52:04 -0700201 bool Worker(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800202
James C Scott4f596682014-05-01 05:52:04 -0700203 bool Gate(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800204};
205
206/**
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800207 * @class NullCheckEliminationAndTypeInference
208 * @brief Null check elimination and type inference.
209 */
James C Scott4f596682014-05-01 05:52:04 -0700210class NullCheckEliminationAndTypeInference : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800211 public:
Vladimir Marko75ba13f2014-01-28 12:15:24 +0000212 NullCheckEliminationAndTypeInference()
James C Scott4f596682014-05-01 05:52:04 -0700213 : PassME("NCE_TypeInference", kRepeatingPreOrderDFSTraversal, "4_post_nce_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800214 }
215
James C Scott4f596682014-05-01 05:52:04 -0700216 void Start(const PassDataHolder* data) const {
217 DCHECK(data != nullptr);
218 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
219 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000220 cUnit->mir_graph->EliminateNullChecksAndInferTypesStart();
221 }
222
James C Scott4f596682014-05-01 05:52:04 -0700223 bool Worker(const PassDataHolder* data) const {
224 DCHECK(data != nullptr);
225 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data);
226 CompilationUnit* cUnit = pass_me_data_holder->c_unit;
227 DCHECK(cUnit != nullptr);
228 BasicBlock* bb = pass_me_data_holder->bb;
229 DCHECK(bb != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800230 return cUnit->mir_graph->EliminateNullChecksAndInferTypes(bb);
231 }
Vladimir Markobfea9c22014-01-17 17:49:33 +0000232
James C Scott4f596682014-05-01 05:52:04 -0700233 void End(const PassDataHolder* data) const {
234 DCHECK(data != nullptr);
235 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
236 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000237 cUnit->mir_graph->EliminateNullChecksAndInferTypesEnd();
238 }
239};
240
James C Scott4f596682014-05-01 05:52:04 -0700241class ClassInitCheckElimination : public PassME {
Vladimir Markobfea9c22014-01-17 17:49:33 +0000242 public:
James C Scott4f596682014-05-01 05:52:04 -0700243 ClassInitCheckElimination() : PassME("ClInitCheckElimination", kRepeatingPreOrderDFSTraversal) {
Vladimir Markobfea9c22014-01-17 17:49:33 +0000244 }
245
James C Scott4f596682014-05-01 05:52:04 -0700246 bool Gate(const PassDataHolder* data) const {
247 DCHECK(data != nullptr);
248 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
249 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000250 return cUnit->mir_graph->EliminateClassInitChecksGate();
251 }
252
James C Scott4f596682014-05-01 05:52:04 -0700253 bool Worker(const PassDataHolder* data) const {
254 DCHECK(data != nullptr);
255 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data);
256 CompilationUnit* cUnit = pass_me_data_holder->c_unit;
257 DCHECK(cUnit != nullptr);
258 BasicBlock* bb = pass_me_data_holder->bb;
259 DCHECK(bb != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000260 return cUnit->mir_graph->EliminateClassInitChecks(bb);
261 }
262
James C Scott4f596682014-05-01 05:52:04 -0700263 void End(const PassDataHolder* data) const {
264 DCHECK(data != nullptr);
265 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
266 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000267 cUnit->mir_graph->EliminateClassInitChecksEnd();
268 }
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800269};
270
271/**
272 * @class NullCheckEliminationAndTypeInference
273 * @brief Null check elimination and type inference.
274 */
James C Scott4f596682014-05-01 05:52:04 -0700275class BBCombine : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800276 public:
James C Scott4f596682014-05-01 05:52:04 -0700277 BBCombine() : PassME("BBCombine", kPreOrderDFSTraversal, "5_post_bbcombine_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800278 }
279
James C Scott4f596682014-05-01 05:52:04 -0700280 bool Gate(const PassDataHolder* data) const {
281 DCHECK(data != nullptr);
282 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
283 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800284 return ((cUnit->disable_opt & (1 << kSuppressExceptionEdges)) != 0);
285 }
286
James C Scott4f596682014-05-01 05:52:04 -0700287 bool Worker(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800288};
289
290/**
291 * @class BasicBlock Optimizations
292 * @brief Any simple BasicBlock optimization can be put here.
293 */
James C Scott4f596682014-05-01 05:52:04 -0700294class BBOptimizations : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800295 public:
James C Scott4f596682014-05-01 05:52:04 -0700296 BBOptimizations() : PassME("BBOptimizations", kNoNodes, "5_post_bbo_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800297 }
298
James C Scott4f596682014-05-01 05:52:04 -0700299 bool Gate(const PassDataHolder* data) const {
300 DCHECK(data != nullptr);
301 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
302 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800303 return ((cUnit->disable_opt & (1 << kBBOpt)) == 0);
304 }
305
James C Scott4f596682014-05-01 05:52:04 -0700306 void Start(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800307};
308
309} // namespace art
310
311#endif // ART_COMPILER_DEX_BB_OPTIMIZATIONS_H_