blob: 6eccb0ecb7bd296fca07136ced661f7d9c524a8c [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/**
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
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070089 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -070090 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -070091 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -070092 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
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700108 void End(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700109 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700110 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -0700111 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:
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700122 CodeLayout() : PassME("CodeLayout", kAllNodes, kOptimizationBasicBlockChange, "2_post_layout_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800123 }
124
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700125 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700126 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700127 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -0700128 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/**
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800136 * @class NullCheckEliminationAndTypeInference
137 * @brief Null check elimination and type inference.
138 */
James C Scott4f596682014-05-01 05:52:04 -0700139class NullCheckEliminationAndTypeInference : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800140 public:
Vladimir Marko75ba13f2014-01-28 12:15:24 +0000141 NullCheckEliminationAndTypeInference()
Vladimir Marko622bdbe2014-06-19 14:59:05 +0100142 : PassME("NCE_TypeInference", kRepeatingTopologicalSortTraversal, "4_post_nce_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800143 }
144
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700145 void Start(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700146 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700147 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -0700148 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000149 cUnit->mir_graph->EliminateNullChecksAndInferTypesStart();
150 }
151
James C Scott4f596682014-05-01 05:52:04 -0700152 bool Worker(const PassDataHolder* data) const {
153 DCHECK(data != nullptr);
154 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data);
155 CompilationUnit* cUnit = pass_me_data_holder->c_unit;
156 DCHECK(cUnit != nullptr);
157 BasicBlock* bb = pass_me_data_holder->bb;
158 DCHECK(bb != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800159 return cUnit->mir_graph->EliminateNullChecksAndInferTypes(bb);
160 }
Vladimir Markobfea9c22014-01-17 17:49:33 +0000161
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700162 void End(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700163 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700164 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -0700165 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000166 cUnit->mir_graph->EliminateNullChecksAndInferTypesEnd();
167 }
168};
169
James C Scott4f596682014-05-01 05:52:04 -0700170class ClassInitCheckElimination : public PassME {
Vladimir Markobfea9c22014-01-17 17:49:33 +0000171 public:
Vladimir Marko622bdbe2014-06-19 14:59:05 +0100172 ClassInitCheckElimination()
173 : PassME("ClInitCheckElimination", kRepeatingTopologicalSortTraversal) {
Vladimir Markobfea9c22014-01-17 17:49:33 +0000174 }
175
James C Scott4f596682014-05-01 05:52:04 -0700176 bool Gate(const PassDataHolder* data) const {
177 DCHECK(data != nullptr);
178 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
179 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000180 return cUnit->mir_graph->EliminateClassInitChecksGate();
181 }
182
James C Scott4f596682014-05-01 05:52:04 -0700183 bool Worker(const PassDataHolder* data) const {
184 DCHECK(data != nullptr);
185 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data);
186 CompilationUnit* cUnit = pass_me_data_holder->c_unit;
187 DCHECK(cUnit != nullptr);
188 BasicBlock* bb = pass_me_data_holder->bb;
189 DCHECK(bb != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000190 return cUnit->mir_graph->EliminateClassInitChecks(bb);
191 }
192
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700193 void End(PassDataHolder* data) const {
James C Scott4f596682014-05-01 05:52:04 -0700194 DCHECK(data != nullptr);
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700195 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -0700196 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000197 cUnit->mir_graph->EliminateClassInitChecksEnd();
198 }
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800199};
200
201/**
202 * @class NullCheckEliminationAndTypeInference
203 * @brief Null check elimination and type inference.
204 */
James C Scott4f596682014-05-01 05:52:04 -0700205class BBCombine : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800206 public:
James C Scott4f596682014-05-01 05:52:04 -0700207 BBCombine() : PassME("BBCombine", kPreOrderDFSTraversal, "5_post_bbcombine_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800208 }
209
James C Scott4f596682014-05-01 05:52:04 -0700210 bool Gate(const PassDataHolder* data) const {
211 DCHECK(data != nullptr);
212 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
213 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800214 return ((cUnit->disable_opt & (1 << kSuppressExceptionEdges)) != 0);
215 }
216
James C Scott4f596682014-05-01 05:52:04 -0700217 bool Worker(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800218};
219
220/**
221 * @class BasicBlock Optimizations
222 * @brief Any simple BasicBlock optimization can be put here.
223 */
James C Scott4f596682014-05-01 05:52:04 -0700224class BBOptimizations : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800225 public:
James C Scott4f596682014-05-01 05:52:04 -0700226 BBOptimizations() : PassME("BBOptimizations", kNoNodes, "5_post_bbo_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800227 }
228
James C Scott4f596682014-05-01 05:52:04 -0700229 bool Gate(const PassDataHolder* data) const {
230 DCHECK(data != nullptr);
231 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
232 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800233 return ((cUnit->disable_opt & (1 << kBBOpt)) == 0);
234 }
235
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700236 void Start(PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800237};
238
239} // namespace art
240
241#endif // ART_COMPILER_DEX_BB_OPTIMIZATIONS_H_