blob: 2b097b5c732eb432f059ad810bd15a407d1d2dea [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()
James C Scott4f596682014-05-01 05:52:04 -0700142 : PassME("NCE_TypeInference", kRepeatingPreOrderDFSTraversal, "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:
James C Scott4f596682014-05-01 05:52:04 -0700172 ClassInitCheckElimination() : PassME("ClInitCheckElimination", kRepeatingPreOrderDFSTraversal) {
Vladimir Markobfea9c22014-01-17 17:49:33 +0000173 }
174
James C Scott4f596682014-05-01 05:52:04 -0700175 bool Gate(const PassDataHolder* data) const {
176 DCHECK(data != nullptr);
177 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
178 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000179 return cUnit->mir_graph->EliminateClassInitChecksGate();
180 }
181
James C Scott4f596682014-05-01 05:52:04 -0700182 bool Worker(const PassDataHolder* data) const {
183 DCHECK(data != nullptr);
184 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data);
185 CompilationUnit* cUnit = pass_me_data_holder->c_unit;
186 DCHECK(cUnit != nullptr);
187 BasicBlock* bb = pass_me_data_holder->bb;
188 DCHECK(bb != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000189 return cUnit->mir_graph->EliminateClassInitChecks(bb);
190 }
191
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 Beylere1f65bc2014-06-09 10:18:26 -0700194 CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
James C Scott4f596682014-05-01 05:52:04 -0700195 DCHECK(cUnit != nullptr);
Vladimir Markobfea9c22014-01-17 17:49:33 +0000196 cUnit->mir_graph->EliminateClassInitChecksEnd();
197 }
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800198};
199
200/**
201 * @class NullCheckEliminationAndTypeInference
202 * @brief Null check elimination and type inference.
203 */
James C Scott4f596682014-05-01 05:52:04 -0700204class BBCombine : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800205 public:
James C Scott4f596682014-05-01 05:52:04 -0700206 BBCombine() : PassME("BBCombine", kPreOrderDFSTraversal, "5_post_bbcombine_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800207 }
208
James C Scott4f596682014-05-01 05:52:04 -0700209 bool Gate(const PassDataHolder* data) const {
210 DCHECK(data != nullptr);
211 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
212 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800213 return ((cUnit->disable_opt & (1 << kSuppressExceptionEdges)) != 0);
214 }
215
James C Scott4f596682014-05-01 05:52:04 -0700216 bool Worker(const PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800217};
218
219/**
220 * @class BasicBlock Optimizations
221 * @brief Any simple BasicBlock optimization can be put here.
222 */
James C Scott4f596682014-05-01 05:52:04 -0700223class BBOptimizations : public PassME {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800224 public:
James C Scott4f596682014-05-01 05:52:04 -0700225 BBOptimizations() : PassME("BBOptimizations", kNoNodes, "5_post_bbo_cfg") {
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800226 }
227
James C Scott4f596682014-05-01 05:52:04 -0700228 bool Gate(const PassDataHolder* data) const {
229 DCHECK(data != nullptr);
230 CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
231 DCHECK(cUnit != nullptr);
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800232 return ((cUnit->disable_opt & (1 << kBBOpt)) == 0);
233 }
234
Jean Christophe Beylere1f65bc2014-06-09 10:18:26 -0700235 void Start(PassDataHolder* data) const;
Jean Christophe Beyler4e97c532014-01-07 10:07:18 -0800236};
237
238} // namespace art
239
240#endif // ART_COMPILER_DEX_BB_OPTIMIZATIONS_H_