blob: 0850f42a9adaa7e67bf5df642f5bbcf26aa2f263 [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
Andreas Gampe53c913b2014-08-12 23:19:23 -070020#include "base/casts.h"
Andreas Gampe0b9203e2015-01-22 20:39:27 -080021#include "compiler_ir.h"
22#include "dex_flags.h"
James C Scott4f596682014-05-01 05:52:04 -070023#include "pass_me.h"
Andreas Gampe0b9203e2015-01-22 20:39:27 -080024#include "mir_graph.h"
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -080025
26namespace art {
27
28/**
Vladimir Markobe0e5462014-02-26 11:24:15 +000029 * @class CacheFieldLoweringInfo
30 * @brief Cache the lowering info for fields used by IGET/IPUT/SGET/SPUT insns.
31 */
James C Scott4f596682014-05-01 05:52:04 -070032class CacheFieldLoweringInfo : public PassME {
Vladimir Markobe0e5462014-02-26 11:24:15 +000033 public:
James C Scott4f596682014-05-01 05:52:04 -070034 CacheFieldLoweringInfo() : PassME("CacheFieldLoweringInfo", kNoNodes) {
Vladimir Markobe0e5462014-02-26 11:24:15 +000035 }
36
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070037 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -070038 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -070039 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
40 DCHECK(c_unit != nullptr);
41 c_unit->mir_graph->DoCacheFieldLoweringInfo();
Vladimir Markobe0e5462014-02-26 11:24:15 +000042 }
Vladimir Marko3d73ba22014-03-06 15:18:04 +000043
James C Scott4f596682014-05-01 05:52:04 -070044 bool Gate(const PassDataHolder* data) const {
45 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -070046 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
47 DCHECK(c_unit != nullptr);
48 return c_unit->mir_graph->HasFieldAccess();
Vladimir Marko3d73ba22014-03-06 15:18:04 +000049 }
Vladimir Markobe0e5462014-02-26 11:24:15 +000050};
51
52/**
Vladimir Markof096aad2014-01-23 15:51:58 +000053 * @class CacheMethodLoweringInfo
54 * @brief Cache the lowering info for methods called by INVOKEs.
55 */
James C Scott4f596682014-05-01 05:52:04 -070056class CacheMethodLoweringInfo : public PassME {
Vladimir Markof096aad2014-01-23 15:51:58 +000057 public:
James C Scott4f596682014-05-01 05:52:04 -070058 CacheMethodLoweringInfo() : PassME("CacheMethodLoweringInfo", kNoNodes) {
Vladimir Markof096aad2014-01-23 15:51:58 +000059 }
60
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070061 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -070062 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -070063 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
64 DCHECK(c_unit != nullptr);
65 c_unit->mir_graph->DoCacheMethodLoweringInfo();
Vladimir Markof096aad2014-01-23 15:51:58 +000066 }
Vladimir Marko3d73ba22014-03-06 15:18:04 +000067
James C Scott4f596682014-05-01 05:52:04 -070068 bool Gate(const PassDataHolder* data) const {
69 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -070070 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
71 DCHECK(c_unit != nullptr);
72 return c_unit->mir_graph->HasInvokes();
Vladimir Marko3d73ba22014-03-06 15:18:04 +000073 }
Vladimir Markof096aad2014-01-23 15:51:58 +000074};
75
76/**
Razvan A Lupusorucb804742014-07-09 16:42:19 -070077 * @class SpecialMethodInliner
78 * @brief Performs method inlining pass on special kinds of methods.
79 * @details Special methods are methods that fall in one of the following categories:
80 * empty, instance getter, instance setter, argument return, and constant return.
Vladimir Marko9820b7c2014-01-02 16:40:37 +000081 */
Razvan A Lupusorucb804742014-07-09 16:42:19 -070082class SpecialMethodInliner : public PassME {
Vladimir Marko9820b7c2014-01-02 16:40:37 +000083 public:
Razvan A Lupusorucb804742014-07-09 16:42:19 -070084 SpecialMethodInliner() : PassME("SpecialMethodInliner") {
Vladimir Marko9820b7c2014-01-02 16:40:37 +000085 }
86
James C Scott4f596682014-05-01 05:52:04 -070087 bool Gate(const PassDataHolder* data) const {
88 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -070089 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
90 DCHECK(c_unit != nullptr);
91 return c_unit->mir_graph->InlineSpecialMethodsGate();
Vladimir Marko9820b7c2014-01-02 16:40:37 +000092 }
93
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070094 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -070095 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -070096 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
97 DCHECK(c_unit != nullptr);
98 c_unit->mir_graph->InlineSpecialMethodsStart();
Vladimir Marko9820b7c2014-01-02 16:40:37 +000099 }
100
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700101 bool Worker(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700102 DCHECK(data != nullptr);
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700103 PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700104 CompilationUnit* c_unit = pass_me_data_holder->c_unit;
105 DCHECK(c_unit != nullptr);
James C Scott4f596682014-05-01 05:52:04 -0700106 BasicBlock* bb = pass_me_data_holder->bb;
107 DCHECK(bb != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700108 c_unit->mir_graph->InlineSpecialMethods(bb);
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000109 // No need of repeating, so just return false.
110 return false;
111 }
112
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700113 void End(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700114 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700115 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
116 DCHECK(c_unit != nullptr);
117 c_unit->mir_graph->InlineSpecialMethodsEnd();
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000118 }
119};
120
121/**
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800122 * @class CodeLayout
123 * @brief Perform the code layout pass.
124 */
James C Scott4f596682014-05-01 05:52:04 -0700125class CodeLayout : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800126 public:
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700127 CodeLayout() : PassME("CodeLayout", kAllNodes, kOptimizationBasicBlockChange, "2_post_layout_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800128 }
129
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700130 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700131 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700132 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
133 DCHECK(c_unit != nullptr);
134 c_unit->mir_graph->VerifyDataflow();
135 c_unit->mir_graph->ClearAllVisitedFlags();
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800136 }
137
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700138 bool Worker(PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800139};
140
141/**
Vladimir Marko67c72b82014-10-09 12:26:10 +0100142 * @class NullCheckElimination
143 * @brief Null check elimination pass.
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800144 */
Vladimir Marko67c72b82014-10-09 12:26:10 +0100145class NullCheckElimination : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800146 public:
Vladimir Marko67c72b82014-10-09 12:26:10 +0100147 NullCheckElimination()
Vladimir Marko7baa6f82014-10-09 18:01:24 +0100148 : PassME("NCE", kRepeatingPreOrderDFSTraversal, "3_post_nce_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800149 }
150
Vladimir Marko67c72b82014-10-09 12:26:10 +0100151 bool Gate(const PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700152 DCHECK(data != nullptr);
Vladimir Marko67c72b82014-10-09 12:26:10 +0100153 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700154 DCHECK(c_unit != nullptr);
Vladimir Marko67c72b82014-10-09 12:26:10 +0100155 return c_unit->mir_graph->EliminateNullChecksGate();
Vladimir Markobfea9c22014-01-17 17:49:33 +0000156 }
157
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700158 bool Worker(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700159 DCHECK(data != nullptr);
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700160 PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700161 CompilationUnit* c_unit = pass_me_data_holder->c_unit;
162 DCHECK(c_unit != nullptr);
James C Scott4f596682014-05-01 05:52:04 -0700163 BasicBlock* bb = pass_me_data_holder->bb;
164 DCHECK(bb != nullptr);
Vladimir Marko67c72b82014-10-09 12:26:10 +0100165 return c_unit->mir_graph->EliminateNullChecks(bb);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800166 }
Vladimir Markobfea9c22014-01-17 17:49:33 +0000167
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700168 void End(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700169 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700170 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
171 DCHECK(c_unit != nullptr);
Vladimir Marko67c72b82014-10-09 12:26:10 +0100172 c_unit->mir_graph->EliminateNullChecksEnd();
173 }
174};
175
James C Scott4f596682014-05-01 05:52:04 -0700176class ClassInitCheckElimination : public PassME {
Vladimir Markobfea9c22014-01-17 17:49:33 +0000177 public:
Vladimir Marko622bdbe2014-06-19 14:59:05 +0100178 ClassInitCheckElimination()
Vladimir Marko7baa6f82014-10-09 18:01:24 +0100179 : PassME("ClInitCheckElimination", kRepeatingPreOrderDFSTraversal) {
Vladimir Markobfea9c22014-01-17 17:49:33 +0000180 }
181
James C Scott4f596682014-05-01 05:52:04 -0700182 bool Gate(const PassDataHolder* data) const {
183 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700184 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
185 DCHECK(c_unit != nullptr);
186 return c_unit->mir_graph->EliminateClassInitChecksGate();
Vladimir Markobfea9c22014-01-17 17:49:33 +0000187 }
188
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700189 bool Worker(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700190 DCHECK(data != nullptr);
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700191 PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700192 CompilationUnit* c_unit = pass_me_data_holder->c_unit;
193 DCHECK(c_unit != nullptr);
James C Scott4f596682014-05-01 05:52:04 -0700194 BasicBlock* bb = pass_me_data_holder->bb;
195 DCHECK(bb != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700196 return c_unit->mir_graph->EliminateClassInitChecks(bb);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000197 }
198
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700199 void End(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700200 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700201 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
202 DCHECK(c_unit != nullptr);
203 c_unit->mir_graph->EliminateClassInitChecksEnd();
Vladimir Markobfea9c22014-01-17 17:49:33 +0000204 }
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800205};
206
207/**
Vladimir Marko95a05972014-05-30 10:01:32 +0100208 * @class GlobalValueNumberingPass
209 * @brief Performs the global value numbering pass.
210 */
211class GlobalValueNumberingPass : public PassME {
212 public:
213 GlobalValueNumberingPass()
Vladimir Marko55fff042014-07-10 12:42:52 +0100214 : PassME("GVN", kLoopRepeatingTopologicalSortTraversal, "4_post_gvn_cfg") {
Vladimir Marko95a05972014-05-30 10:01:32 +0100215 }
216
Vladimir Marko55fff042014-07-10 12:42:52 +0100217 bool Gate(const PassDataHolder* data) const OVERRIDE {
Vladimir Marko95a05972014-05-30 10:01:32 +0100218 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700219 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
220 DCHECK(c_unit != nullptr);
221 return c_unit->mir_graph->ApplyGlobalValueNumberingGate();
Vladimir Marko95a05972014-05-30 10:01:32 +0100222 }
223
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700224 bool Worker(PassDataHolder* data) const {
Vladimir Marko95a05972014-05-30 10:01:32 +0100225 DCHECK(data != nullptr);
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700226 PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700227 CompilationUnit* c_unit = pass_me_data_holder->c_unit;
228 DCHECK(c_unit != nullptr);
Vladimir Marko95a05972014-05-30 10:01:32 +0100229 BasicBlock* bb = pass_me_data_holder->bb;
230 DCHECK(bb != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700231 return c_unit->mir_graph->ApplyGlobalValueNumbering(bb);
Vladimir Marko95a05972014-05-30 10:01:32 +0100232 }
233
Vladimir Marko55fff042014-07-10 12:42:52 +0100234 void End(PassDataHolder* data) const OVERRIDE {
Vladimir Marko95a05972014-05-30 10:01:32 +0100235 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700236 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
237 DCHECK(c_unit != nullptr);
238 c_unit->mir_graph->ApplyGlobalValueNumberingEnd();
Vladimir Marko95a05972014-05-30 10:01:32 +0100239 }
240};
241
242/**
Vladimir Marko7a01dc22015-01-02 17:00:44 +0000243 * @class DeadCodeEliminationPass
244 * @brief Performs the GVN-based dead code elimination pass.
245 */
246class DeadCodeEliminationPass : public PassME {
247 public:
248 DeadCodeEliminationPass() : PassME("DCE", kPreOrderDFSTraversal, "4_post_dce_cfg") {
249 }
250
251 bool Gate(const PassDataHolder* data) const OVERRIDE {
252 DCHECK(data != nullptr);
253 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
254 DCHECK(c_unit != nullptr);
255 return c_unit->mir_graph->EliminateDeadCodeGate();
256 }
257
258 bool Worker(PassDataHolder* data) const {
259 DCHECK(data != nullptr);
260 PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
261 CompilationUnit* c_unit = pass_me_data_holder->c_unit;
262 DCHECK(c_unit != nullptr);
263 BasicBlock* bb = pass_me_data_holder->bb;
264 DCHECK(bb != nullptr);
265 return c_unit->mir_graph->EliminateDeadCode(bb);
266 }
267
268 void End(PassDataHolder* data) const OVERRIDE {
269 DCHECK(data != nullptr);
270 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
271 DCHECK(c_unit != nullptr);
272 c_unit->mir_graph->EliminateDeadCodeEnd();
273 down_cast<PassMEDataHolder*>(data)->dirty = !c_unit->mir_graph->MirSsaRepUpToDate();
274 }
275};
276
277/**
Vladimir Marko95a05972014-05-30 10:01:32 +0100278 * @class BBCombine
279 * @brief Perform the basic block combination pass.
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800280 */
James C Scott4f596682014-05-01 05:52:04 -0700281class BBCombine : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800282 public:
James C Scott4f596682014-05-01 05:52:04 -0700283 BBCombine() : PassME("BBCombine", kPreOrderDFSTraversal, "5_post_bbcombine_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800284 }
285
James C Scott4f596682014-05-01 05:52:04 -0700286 bool Gate(const PassDataHolder* data) const {
287 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700288 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
289 DCHECK(c_unit != nullptr);
Vladimir Marko312eb252014-10-07 15:01:57 +0100290 return c_unit->mir_graph->HasTryCatchBlocks() ||
291 ((c_unit->disable_opt & (1 << kSuppressExceptionEdges)) != 0);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800292 }
293
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700294 bool Worker(PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800295};
296
297/**
Vladimir Marko066f9e42015-01-16 16:04:43 +0000298 * @class ConstantPropagation
299 * @brief Perform a constant propagation pass.
300 */
301class ConstantPropagation : public PassME {
302 public:
303 ConstantPropagation() : PassME("ConstantPropagation") {
304 }
305
306 void Start(PassDataHolder* data) const {
307 DCHECK(data != nullptr);
308 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
309 DCHECK(c_unit != nullptr);
310 c_unit->mir_graph->InitializeConstantPropagation();
311 }
312
313 bool Worker(PassDataHolder* data) const {
314 DCHECK(data != nullptr);
315 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
316 DCHECK(c_unit != nullptr);
317 BasicBlock* bb = down_cast<PassMEDataHolder*>(data)->bb;
318 DCHECK(bb != nullptr);
319 c_unit->mir_graph->DoConstantPropagation(bb);
320 // No need of repeating, so just return false.
321 return false;
322 }
323};
324
325/**
326 * @class MethodUseCount
327 * @brief Count the register uses of the method
328 */
329class MethodUseCount : public PassME {
330 public:
331 MethodUseCount() : PassME("UseCount") {
332 }
333
334 bool Worker(PassDataHolder* data) const;
335
336 bool Gate(const PassDataHolder* data) const;
337};
338
339/**
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800340 * @class BasicBlock Optimizations
341 * @brief Any simple BasicBlock optimization can be put here.
342 */
James C Scott4f596682014-05-01 05:52:04 -0700343class BBOptimizations : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800344 public:
Vladimir Marko341e4252014-12-19 10:29:51 +0000345 BBOptimizations()
346 : PassME("BBOptimizations", kNoNodes, kOptimizationBasicBlockChange, "5_post_bbo_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800347 }
348
James C Scott4f596682014-05-01 05:52:04 -0700349 bool Gate(const PassDataHolder* data) const {
350 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700351 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
352 DCHECK(c_unit != nullptr);
353 return ((c_unit->disable_opt & (1 << kBBOpt)) == 0);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800354 }
355
Vladimir Markoffda4992014-12-18 17:05:58 +0000356 void Start(PassDataHolder* data) const {
357 DCHECK(data != nullptr);
358 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
359 DCHECK(c_unit != nullptr);
360 c_unit->mir_graph->BasicBlockOptimizationStart();
361
362 /*
363 * This pass has a different ordering depending on the suppress exception,
364 * so do the pass here for now:
365 * - Later, the Start should just change the ordering and we can move the extended
366 * creation into the pass driver's main job with a new iterator
367 */
368 c_unit->mir_graph->BasicBlockOptimization();
369 }
370
371 void End(PassDataHolder* data) const {
372 DCHECK(data != nullptr);
373 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
374 DCHECK(c_unit != nullptr);
375 c_unit->mir_graph->BasicBlockOptimizationEnd();
Vladimir Marko341e4252014-12-19 10:29:51 +0000376 down_cast<PassMEDataHolder*>(data)->dirty = !c_unit->mir_graph->DfsOrdersUpToDate();
Vladimir Markoffda4992014-12-18 17:05:58 +0000377 }
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800378};
379
Vladimir Marko8b858e12014-11-27 14:52:37 +0000380/**
381 * @class SuspendCheckElimination
382 * @brief Any simple BasicBlock optimization can be put here.
383 */
384class SuspendCheckElimination : public PassME {
385 public:
386 SuspendCheckElimination()
387 : PassME("SuspendCheckElimination", kTopologicalSortTraversal, "6_post_sce_cfg") {
388 }
389
390 bool Gate(const PassDataHolder* data) const {
391 DCHECK(data != nullptr);
392 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
393 DCHECK(c_unit != nullptr);
394 return c_unit->mir_graph->EliminateSuspendChecksGate();
395 }
396
397 bool Worker(PassDataHolder* data) const {
398 DCHECK(data != nullptr);
399 PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
400 CompilationUnit* c_unit = pass_me_data_holder->c_unit;
401 DCHECK(c_unit != nullptr);
402 BasicBlock* bb = pass_me_data_holder->bb;
403 DCHECK(bb != nullptr);
404 return c_unit->mir_graph->EliminateSuspendChecks(bb);
405 }
Vladimir Marko8b858e12014-11-27 14:52:37 +0000406};
407
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800408} // namespace art
409
410#endif // ART_COMPILER_DEX_BB_OPTIMIZATIONS_H_