blob: d1d5ad9715eff8fd53a212a776fefce1093537e2 [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
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070034 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -070035 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070036 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -070037 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
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070058 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -070059 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070060 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -070061 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/**
Razvan A Lupusorucb804742014-07-09 16:42:19 -070074 * @class SpecialMethodInliner
75 * @brief Performs method inlining pass on special kinds of methods.
76 * @details Special methods are methods that fall in one of the following categories:
77 * empty, instance getter, instance setter, argument return, and constant return.
Vladimir Marko9820b7c2014-01-02 16:40:37 +000078 */
Razvan A Lupusorucb804742014-07-09 16:42:19 -070079class SpecialMethodInliner : public PassME {
Vladimir Marko9820b7c2014-01-02 16:40:37 +000080 public:
Razvan A Lupusorucb804742014-07-09 16:42:19 -070081 SpecialMethodInliner() : PassME("SpecialMethodInliner") {
Vladimir Marko9820b7c2014-01-02 16:40:37 +000082 }
83
James C Scott4f596682014-05-01 05:52:04 -070084 bool Gate(const PassDataHolder* data) const {
85 DCHECK(data != nullptr);
86 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
87 DCHECK(cUnit != nullptr);
Razvan A Lupusorucb804742014-07-09 16:42:19 -070088 return cUnit->mir_graph->InlineSpecialMethodsGate();
Vladimir Marko9820b7c2014-01-02 16:40:37 +000089 }
90
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070091 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -070092 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070093 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -070094 DCHECK(cUnit != nullptr);
Razvan A Lupusorucb804742014-07-09 16:42:19 -070095 cUnit->mir_graph->InlineSpecialMethodsStart();
Vladimir Marko9820b7c2014-01-02 16:40:37 +000096 }
97
James C Scott4f596682014-05-01 05:52:04 -070098 bool Worker(const PassDataHolder* data) const {
99 DCHECK(data != nullptr);
100 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data);
101 CompilationUnit* cUnit = pass_me_data_holder->c_unit;
102 DCHECK(cUnit != nullptr);
103 BasicBlock* bb = pass_me_data_holder->bb;
104 DCHECK(bb != nullptr);
Razvan A Lupusorucb804742014-07-09 16:42:19 -0700105 cUnit->mir_graph->InlineSpecialMethods(bb);
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000106 // No need of repeating, so just return false.
107 return false;
108 }
109
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700110 void End(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700111 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700112 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -0700113 DCHECK(cUnit != nullptr);
Razvan A Lupusorucb804742014-07-09 16:42:19 -0700114 cUnit->mir_graph->InlineSpecialMethodsEnd();
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000115 }
116};
117
118/**
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800119 * @class CodeLayout
120 * @brief Perform the code layout pass.
121 */
James C Scott4f596682014-05-01 05:52:04 -0700122class CodeLayout : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800123 public:
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700124 CodeLayout() : PassME("CodeLayout", kAllNodes, kOptimizationBasicBlockChange, "2_post_layout_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800125 }
126
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700127 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700128 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700129 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -0700130 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800131 cUnit->mir_graph->VerifyDataflow();
132 }
133
James C Scott4f596682014-05-01 05:52:04 -0700134 bool Worker(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800135};
136
137/**
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800138 * @class NullCheckEliminationAndTypeInference
139 * @brief Null check elimination and type inference.
140 */
James C Scott4f596682014-05-01 05:52:04 -0700141class NullCheckEliminationAndTypeInference : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800142 public:
Vladimir Marko75ba13f2014-01-28 12:15:24 +0000143 NullCheckEliminationAndTypeInference()
Vladimir Marko622bdbe2014-06-19 14:59:05 +0100144 : PassME("NCE_TypeInference", kRepeatingTopologicalSortTraversal, "4_post_nce_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800145 }
146
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700147 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700148 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700149 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -0700150 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000151 cUnit->mir_graph->EliminateNullChecksAndInferTypesStart();
152 }
153
James C Scott4f596682014-05-01 05:52:04 -0700154 bool Worker(const PassDataHolder* data) const {
155 DCHECK(data != nullptr);
156 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data);
157 CompilationUnit* cUnit = pass_me_data_holder->c_unit;
158 DCHECK(cUnit != nullptr);
159 BasicBlock* bb = pass_me_data_holder->bb;
160 DCHECK(bb != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800161 return cUnit->mir_graph->EliminateNullChecksAndInferTypes(bb);
162 }
Vladimir Markobfea9c22014-01-17 17:49:33 +0000163
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700164 void End(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700165 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700166 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -0700167 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000168 cUnit->mir_graph->EliminateNullChecksAndInferTypesEnd();
169 }
170};
171
James C Scott4f596682014-05-01 05:52:04 -0700172class ClassInitCheckElimination : public PassME {
Vladimir Markobfea9c22014-01-17 17:49:33 +0000173 public:
Vladimir Marko622bdbe2014-06-19 14:59:05 +0100174 ClassInitCheckElimination()
175 : PassME("ClInitCheckElimination", kRepeatingTopologicalSortTraversal) {
Vladimir Markobfea9c22014-01-17 17:49:33 +0000176 }
177
James C Scott4f596682014-05-01 05:52:04 -0700178 bool Gate(const PassDataHolder* data) const {
179 DCHECK(data != nullptr);
180 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
181 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000182 return cUnit->mir_graph->EliminateClassInitChecksGate();
183 }
184
James C Scott4f596682014-05-01 05:52:04 -0700185 bool Worker(const PassDataHolder* data) const {
186 DCHECK(data != nullptr);
187 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data);
188 CompilationUnit* cUnit = pass_me_data_holder->c_unit;
189 DCHECK(cUnit != nullptr);
190 BasicBlock* bb = pass_me_data_holder->bb;
191 DCHECK(bb != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000192 return cUnit->mir_graph->EliminateClassInitChecks(bb);
193 }
194
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700195 void End(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700196 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700197 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -0700198 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000199 cUnit->mir_graph->EliminateClassInitChecksEnd();
200 }
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800201};
202
203/**
Vladimir Marko95a05972014-05-30 10:01:32 +0100204 * @class GlobalValueNumberingPass
205 * @brief Performs the global value numbering pass.
206 */
207class GlobalValueNumberingPass : public PassME {
208 public:
209 GlobalValueNumberingPass()
210 : PassME("GVN", kRepeatingTopologicalSortTraversal, "4_post_gvn_cfg") {
211 }
212
213 bool Gate(const PassDataHolder* data) const {
214 DCHECK(data != nullptr);
215 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
216 DCHECK(cUnit != nullptr);
217 return cUnit->mir_graph->ApplyGlobalValueNumberingGate();
218 }
219
220 bool Worker(const PassDataHolder* data) const {
221 DCHECK(data != nullptr);
222 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data);
223 CompilationUnit* cUnit = pass_me_data_holder->c_unit;
224 DCHECK(cUnit != nullptr);
225 BasicBlock* bb = pass_me_data_holder->bb;
226 DCHECK(bb != nullptr);
227 return cUnit->mir_graph->ApplyGlobalValueNumbering(bb);
228 }
229
230 void End(PassDataHolder* data) const {
231 DCHECK(data != nullptr);
232 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
233 DCHECK(cUnit != nullptr);
234 cUnit->mir_graph->ApplyGlobalValueNumberingEnd();
235 }
236};
237
238/**
239 * @class BBCombine
240 * @brief Perform the basic block combination pass.
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800241 */
James C Scott4f596682014-05-01 05:52:04 -0700242class BBCombine : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800243 public:
James C Scott4f596682014-05-01 05:52:04 -0700244 BBCombine() : PassME("BBCombine", kPreOrderDFSTraversal, "5_post_bbcombine_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800245 }
246
James C Scott4f596682014-05-01 05:52:04 -0700247 bool Gate(const PassDataHolder* data) const {
248 DCHECK(data != nullptr);
249 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
250 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800251 return ((cUnit->disable_opt & (1 << kSuppressExceptionEdges)) != 0);
252 }
253
James C Scott4f596682014-05-01 05:52:04 -0700254 bool Worker(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800255};
256
257/**
258 * @class BasicBlock Optimizations
259 * @brief Any simple BasicBlock optimization can be put here.
260 */
James C Scott4f596682014-05-01 05:52:04 -0700261class BBOptimizations : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800262 public:
James C Scott4f596682014-05-01 05:52:04 -0700263 BBOptimizations() : PassME("BBOptimizations", kNoNodes, "5_post_bbo_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800264 }
265
James C Scott4f596682014-05-01 05:52:04 -0700266 bool Gate(const PassDataHolder* data) const {
267 DCHECK(data != nullptr);
268 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
269 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800270 return ((cUnit->disable_opt & (1 << kBBOpt)) == 0);
271 }
272
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700273 void Start(PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800274};
275
276} // namespace art
277
278#endif // ART_COMPILER_DEX_BB_OPTIMIZATIONS_H_