blob: 02d532798c633658427ec204466a254bccc6f5da [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/**
Jeff Hao848f70a2014-01-15 13:49:50 -080029 * @class String Change
30 * @brief Converts calls to String.<init> to StringFactory instead.
31 */
32class StringChange : public PassME {
33 public:
34 StringChange() : PassME("StringChange", kNoNodes) {
35 }
36
37 void Start(PassDataHolder* data) const {
38 DCHECK(data != nullptr);
39 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
40 DCHECK(c_unit != nullptr);
41 c_unit->mir_graph->StringChange();
42 }
43
44 bool Gate(const PassDataHolder* data) const {
45 DCHECK(data != nullptr);
46 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
47 DCHECK(c_unit != nullptr);
48 return c_unit->mir_graph->HasInvokes();
49 }
50};
51
52/**
Vladimir Markobe0e5462014-02-26 11:24:15 +000053 * @class CacheFieldLoweringInfo
54 * @brief Cache the lowering info for fields used by IGET/IPUT/SGET/SPUT insns.
55 */
James C Scott4f596682014-05-01 05:52:04 -070056class CacheFieldLoweringInfo : public PassME {
Vladimir Markobe0e5462014-02-26 11:24:15 +000057 public:
James C Scott4f596682014-05-01 05:52:04 -070058 CacheFieldLoweringInfo() : PassME("CacheFieldLoweringInfo", kNoNodes) {
Vladimir Markobe0e5462014-02-26 11:24:15 +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->DoCacheFieldLoweringInfo();
Vladimir Markobe0e5462014-02-26 11:24:15 +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->HasFieldAccess();
Vladimir Marko3d73ba22014-03-06 15:18:04 +000073 }
Vladimir Markobe0e5462014-02-26 11:24:15 +000074};
75
76/**
Vladimir Markof096aad2014-01-23 15:51:58 +000077 * @class CacheMethodLoweringInfo
78 * @brief Cache the lowering info for methods called by INVOKEs.
79 */
James C Scott4f596682014-05-01 05:52:04 -070080class CacheMethodLoweringInfo : public PassME {
Vladimir Markof096aad2014-01-23 15:51:58 +000081 public:
James C Scott4f596682014-05-01 05:52:04 -070082 CacheMethodLoweringInfo() : PassME("CacheMethodLoweringInfo", kNoNodes) {
Vladimir Markof096aad2014-01-23 15:51:58 +000083 }
84
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070085 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -070086 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -070087 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
88 DCHECK(c_unit != nullptr);
89 c_unit->mir_graph->DoCacheMethodLoweringInfo();
Vladimir Markof096aad2014-01-23 15:51:58 +000090 }
Vladimir Marko3d73ba22014-03-06 15:18:04 +000091
James C Scott4f596682014-05-01 05:52:04 -070092 bool Gate(const PassDataHolder* data) const {
93 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -070094 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
95 DCHECK(c_unit != nullptr);
96 return c_unit->mir_graph->HasInvokes();
Vladimir Marko3d73ba22014-03-06 15:18:04 +000097 }
Vladimir Markof096aad2014-01-23 15:51:58 +000098};
99
100/**
Razvan A Lupusorucb804742014-07-09 16:42:19 -0700101 * @class SpecialMethodInliner
102 * @brief Performs method inlining pass on special kinds of methods.
103 * @details Special methods are methods that fall in one of the following categories:
104 * empty, instance getter, instance setter, argument return, and constant return.
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000105 */
Razvan A Lupusorucb804742014-07-09 16:42:19 -0700106class SpecialMethodInliner : public PassME {
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000107 public:
Razvan A Lupusorucb804742014-07-09 16:42:19 -0700108 SpecialMethodInliner() : PassME("SpecialMethodInliner") {
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000109 }
110
James C Scott4f596682014-05-01 05:52:04 -0700111 bool Gate(const PassDataHolder* data) const {
112 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700113 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
114 DCHECK(c_unit != nullptr);
115 return c_unit->mir_graph->InlineSpecialMethodsGate();
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000116 }
117
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700118 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700119 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700120 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
121 DCHECK(c_unit != nullptr);
122 c_unit->mir_graph->InlineSpecialMethodsStart();
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000123 }
124
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700125 bool Worker(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700126 DCHECK(data != nullptr);
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700127 PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700128 CompilationUnit* c_unit = pass_me_data_holder->c_unit;
129 DCHECK(c_unit != nullptr);
James C Scott4f596682014-05-01 05:52:04 -0700130 BasicBlock* bb = pass_me_data_holder->bb;
131 DCHECK(bb != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700132 c_unit->mir_graph->InlineSpecialMethods(bb);
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000133 // No need of repeating, so just return false.
134 return false;
135 }
136
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700137 void End(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700138 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700139 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
140 DCHECK(c_unit != nullptr);
141 c_unit->mir_graph->InlineSpecialMethodsEnd();
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000142 }
143};
144
145/**
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800146 * @class CodeLayout
147 * @brief Perform the code layout pass.
148 */
James C Scott4f596682014-05-01 05:52:04 -0700149class CodeLayout : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800150 public:
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700151 CodeLayout() : PassME("CodeLayout", kAllNodes, kOptimizationBasicBlockChange, "2_post_layout_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800152 }
153
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700154 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700155 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700156 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
157 DCHECK(c_unit != nullptr);
158 c_unit->mir_graph->VerifyDataflow();
159 c_unit->mir_graph->ClearAllVisitedFlags();
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800160 }
161
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700162 bool Worker(PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800163};
164
165/**
Vladimir Marko67c72b82014-10-09 12:26:10 +0100166 * @class NullCheckElimination
167 * @brief Null check elimination pass.
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800168 */
Vladimir Marko67c72b82014-10-09 12:26:10 +0100169class NullCheckElimination : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800170 public:
Vladimir Marko67c72b82014-10-09 12:26:10 +0100171 NullCheckElimination()
Vladimir Marko7baa6f82014-10-09 18:01:24 +0100172 : PassME("NCE", kRepeatingPreOrderDFSTraversal, "3_post_nce_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800173 }
174
Vladimir Marko67c72b82014-10-09 12:26:10 +0100175 bool Gate(const PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700176 DCHECK(data != nullptr);
Vladimir Marko67c72b82014-10-09 12:26:10 +0100177 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700178 DCHECK(c_unit != nullptr);
Vladimir Marko67c72b82014-10-09 12:26:10 +0100179 return c_unit->mir_graph->EliminateNullChecksGate();
Vladimir Markobfea9c22014-01-17 17:49:33 +0000180 }
181
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700182 bool Worker(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700183 DCHECK(data != nullptr);
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700184 PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700185 CompilationUnit* c_unit = pass_me_data_holder->c_unit;
186 DCHECK(c_unit != nullptr);
James C Scott4f596682014-05-01 05:52:04 -0700187 BasicBlock* bb = pass_me_data_holder->bb;
188 DCHECK(bb != nullptr);
Vladimir Marko67c72b82014-10-09 12:26:10 +0100189 return c_unit->mir_graph->EliminateNullChecks(bb);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800190 }
Vladimir Markobfea9c22014-01-17 17:49:33 +0000191
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700192 void End(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700193 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700194 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
195 DCHECK(c_unit != nullptr);
Vladimir Marko67c72b82014-10-09 12:26:10 +0100196 c_unit->mir_graph->EliminateNullChecksEnd();
197 }
198};
199
James C Scott4f596682014-05-01 05:52:04 -0700200class ClassInitCheckElimination : public PassME {
Vladimir Markobfea9c22014-01-17 17:49:33 +0000201 public:
Vladimir Marko622bdbe2014-06-19 14:59:05 +0100202 ClassInitCheckElimination()
Vladimir Marko7baa6f82014-10-09 18:01:24 +0100203 : PassME("ClInitCheckElimination", kRepeatingPreOrderDFSTraversal) {
Vladimir Markobfea9c22014-01-17 17:49:33 +0000204 }
205
James C Scott4f596682014-05-01 05:52:04 -0700206 bool Gate(const PassDataHolder* data) const {
207 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700208 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
209 DCHECK(c_unit != nullptr);
210 return c_unit->mir_graph->EliminateClassInitChecksGate();
Vladimir Markobfea9c22014-01-17 17:49:33 +0000211 }
212
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700213 bool Worker(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700214 DCHECK(data != nullptr);
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700215 PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700216 CompilationUnit* c_unit = pass_me_data_holder->c_unit;
217 DCHECK(c_unit != nullptr);
James C Scott4f596682014-05-01 05:52:04 -0700218 BasicBlock* bb = pass_me_data_holder->bb;
219 DCHECK(bb != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700220 return c_unit->mir_graph->EliminateClassInitChecks(bb);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000221 }
222
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700223 void End(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700224 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700225 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
226 DCHECK(c_unit != nullptr);
227 c_unit->mir_graph->EliminateClassInitChecksEnd();
Vladimir Markobfea9c22014-01-17 17:49:33 +0000228 }
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800229};
230
231/**
Vladimir Marko95a05972014-05-30 10:01:32 +0100232 * @class GlobalValueNumberingPass
233 * @brief Performs the global value numbering pass.
234 */
235class GlobalValueNumberingPass : public PassME {
236 public:
237 GlobalValueNumberingPass()
Vladimir Marko55fff042014-07-10 12:42:52 +0100238 : PassME("GVN", kLoopRepeatingTopologicalSortTraversal, "4_post_gvn_cfg") {
Vladimir Marko95a05972014-05-30 10:01:32 +0100239 }
240
Vladimir Marko55fff042014-07-10 12:42:52 +0100241 bool Gate(const PassDataHolder* data) const OVERRIDE {
Vladimir Marko95a05972014-05-30 10:01:32 +0100242 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700243 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
244 DCHECK(c_unit != nullptr);
245 return c_unit->mir_graph->ApplyGlobalValueNumberingGate();
Vladimir Marko95a05972014-05-30 10:01:32 +0100246 }
247
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700248 bool Worker(PassDataHolder* data) const {
Vladimir Marko95a05972014-05-30 10:01:32 +0100249 DCHECK(data != nullptr);
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700250 PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700251 CompilationUnit* c_unit = pass_me_data_holder->c_unit;
252 DCHECK(c_unit != nullptr);
Vladimir Marko95a05972014-05-30 10:01:32 +0100253 BasicBlock* bb = pass_me_data_holder->bb;
254 DCHECK(bb != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700255 return c_unit->mir_graph->ApplyGlobalValueNumbering(bb);
Vladimir Marko95a05972014-05-30 10:01:32 +0100256 }
257
Vladimir Marko55fff042014-07-10 12:42:52 +0100258 void End(PassDataHolder* data) const OVERRIDE {
Vladimir Marko95a05972014-05-30 10:01:32 +0100259 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700260 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
261 DCHECK(c_unit != nullptr);
262 c_unit->mir_graph->ApplyGlobalValueNumberingEnd();
Vladimir Marko95a05972014-05-30 10:01:32 +0100263 }
264};
265
266/**
Vladimir Marko7a01dc22015-01-02 17:00:44 +0000267 * @class DeadCodeEliminationPass
268 * @brief Performs the GVN-based dead code elimination pass.
269 */
270class DeadCodeEliminationPass : public PassME {
271 public:
272 DeadCodeEliminationPass() : PassME("DCE", kPreOrderDFSTraversal, "4_post_dce_cfg") {
273 }
274
275 bool Gate(const PassDataHolder* data) const OVERRIDE {
276 DCHECK(data != nullptr);
277 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
278 DCHECK(c_unit != nullptr);
279 return c_unit->mir_graph->EliminateDeadCodeGate();
280 }
281
282 bool Worker(PassDataHolder* data) const {
283 DCHECK(data != nullptr);
284 PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
285 CompilationUnit* c_unit = pass_me_data_holder->c_unit;
286 DCHECK(c_unit != nullptr);
287 BasicBlock* bb = pass_me_data_holder->bb;
288 DCHECK(bb != nullptr);
289 return c_unit->mir_graph->EliminateDeadCode(bb);
290 }
291
292 void End(PassDataHolder* data) const OVERRIDE {
293 DCHECK(data != nullptr);
294 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
295 DCHECK(c_unit != nullptr);
296 c_unit->mir_graph->EliminateDeadCodeEnd();
Vladimir Markoad677272015-04-20 10:48:13 +0100297 }
298};
299
300/**
301 * @class GlobalValueNumberingCleanupPass
302 * @brief Performs the cleanup after global value numbering pass and the dependent
303 * dead code elimination pass that needs the GVN data.
304 */
305class GlobalValueNumberingCleanupPass : public PassME {
306 public:
307 GlobalValueNumberingCleanupPass()
308 : PassME("GVNCleanup", kNoNodes, "") {
309 }
310
311 void Start(PassDataHolder* data) const OVERRIDE {
312 DCHECK(data != nullptr);
313 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
314 DCHECK(c_unit != nullptr);
315 return c_unit->mir_graph->GlobalValueNumberingCleanup();
Vladimir Marko7a01dc22015-01-02 17:00:44 +0000316 }
317};
318
319/**
Vladimir Marko95a05972014-05-30 10:01:32 +0100320 * @class BBCombine
321 * @brief Perform the basic block combination pass.
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800322 */
James C Scott4f596682014-05-01 05:52:04 -0700323class BBCombine : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800324 public:
James C Scott4f596682014-05-01 05:52:04 -0700325 BBCombine() : PassME("BBCombine", kPreOrderDFSTraversal, "5_post_bbcombine_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800326 }
327
James C Scott4f596682014-05-01 05:52:04 -0700328 bool Gate(const PassDataHolder* data) const {
329 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700330 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
331 DCHECK(c_unit != nullptr);
Vladimir Marko312eb252014-10-07 15:01:57 +0100332 return c_unit->mir_graph->HasTryCatchBlocks() ||
333 ((c_unit->disable_opt & (1 << kSuppressExceptionEdges)) != 0);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800334 }
335
Jean Christophe Beyler09321df2014-07-18 15:33:57 -0700336 bool Worker(PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800337};
338
339/**
Vladimir Marko066f9e42015-01-16 16:04:43 +0000340 * @class ConstantPropagation
341 * @brief Perform a constant propagation pass.
342 */
343class ConstantPropagation : public PassME {
344 public:
345 ConstantPropagation() : PassME("ConstantPropagation") {
346 }
347
348 void Start(PassDataHolder* data) const {
349 DCHECK(data != nullptr);
350 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
351 DCHECK(c_unit != nullptr);
352 c_unit->mir_graph->InitializeConstantPropagation();
353 }
354
355 bool Worker(PassDataHolder* data) const {
356 DCHECK(data != nullptr);
357 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
358 DCHECK(c_unit != nullptr);
359 BasicBlock* bb = down_cast<PassMEDataHolder*>(data)->bb;
360 DCHECK(bb != nullptr);
361 c_unit->mir_graph->DoConstantPropagation(bb);
362 // No need of repeating, so just return false.
363 return false;
364 }
365};
366
367/**
368 * @class MethodUseCount
369 * @brief Count the register uses of the method
370 */
371class MethodUseCount : public PassME {
372 public:
373 MethodUseCount() : PassME("UseCount") {
374 }
375
376 bool Worker(PassDataHolder* data) const;
377
378 bool Gate(const PassDataHolder* data) const;
379};
380
381/**
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800382 * @class BasicBlock Optimizations
383 * @brief Any simple BasicBlock optimization can be put here.
384 */
James C Scott4f596682014-05-01 05:52:04 -0700385class BBOptimizations : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800386 public:
Vladimir Marko341e4252014-12-19 10:29:51 +0000387 BBOptimizations()
388 : PassME("BBOptimizations", kNoNodes, kOptimizationBasicBlockChange, "5_post_bbo_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800389 }
390
James C Scott4f596682014-05-01 05:52:04 -0700391 bool Gate(const PassDataHolder* data) const {
392 DCHECK(data != nullptr);
Jean Christophe Beyler75bcc372014-09-04 08:15:11 -0700393 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
394 DCHECK(c_unit != nullptr);
395 return ((c_unit->disable_opt & (1 << kBBOpt)) == 0);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800396 }
397
Vladimir Markoffda4992014-12-18 17:05:58 +0000398 void Start(PassDataHolder* data) const {
399 DCHECK(data != nullptr);
400 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
401 DCHECK(c_unit != nullptr);
402 c_unit->mir_graph->BasicBlockOptimizationStart();
403
404 /*
405 * This pass has a different ordering depending on the suppress exception,
406 * so do the pass here for now:
407 * - Later, the Start should just change the ordering and we can move the extended
408 * creation into the pass driver's main job with a new iterator
409 */
410 c_unit->mir_graph->BasicBlockOptimization();
411 }
412
413 void End(PassDataHolder* data) const {
414 DCHECK(data != nullptr);
415 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
416 DCHECK(c_unit != nullptr);
417 c_unit->mir_graph->BasicBlockOptimizationEnd();
Vladimir Marko341e4252014-12-19 10:29:51 +0000418 down_cast<PassMEDataHolder*>(data)->dirty = !c_unit->mir_graph->DfsOrdersUpToDate();
Vladimir Markoffda4992014-12-18 17:05:58 +0000419 }
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800420};
421
Vladimir Marko8b858e12014-11-27 14:52:37 +0000422/**
423 * @class SuspendCheckElimination
424 * @brief Any simple BasicBlock optimization can be put here.
425 */
426class SuspendCheckElimination : public PassME {
427 public:
428 SuspendCheckElimination()
429 : PassME("SuspendCheckElimination", kTopologicalSortTraversal, "6_post_sce_cfg") {
430 }
431
432 bool Gate(const PassDataHolder* data) const {
433 DCHECK(data != nullptr);
434 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
435 DCHECK(c_unit != nullptr);
436 return c_unit->mir_graph->EliminateSuspendChecksGate();
437 }
438
439 bool Worker(PassDataHolder* data) const {
440 DCHECK(data != nullptr);
441 PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
442 CompilationUnit* c_unit = pass_me_data_holder->c_unit;
443 DCHECK(c_unit != nullptr);
444 BasicBlock* bb = pass_me_data_holder->bb;
445 DCHECK(bb != nullptr);
446 return c_unit->mir_graph->EliminateSuspendChecks(bb);
447 }
Vladimir Marko8b858e12014-11-27 14:52:37 +0000448};
449
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800450} // namespace art
451
452#endif // ART_COMPILER_DEX_BB_OPTIMIZATIONS_H_