blob: 8864a123013001e58e716560d1efeb571045cedf [file] [log] [blame]
Roland Levillain75be2832014-10-17 17:02:00 +01001/*
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#include "optimization.h"
18
Aart Bik2ca10eb2017-11-15 15:17:53 -080019#ifdef ART_ENABLE_CODEGEN_arm
20#include "instruction_simplifier_arm.h"
21#endif
22#ifdef ART_ENABLE_CODEGEN_arm64
23#include "instruction_simplifier_arm64.h"
24#endif
25#ifdef ART_ENABLE_CODEGEN_mips
26#include "instruction_simplifier_mips.h"
27#include "pc_relative_fixups_mips.h"
28#endif
29#ifdef ART_ENABLE_CODEGEN_x86
30#include "pc_relative_fixups_x86.h"
Shalini Salomi Bodapatidd121f62018-10-26 15:03:53 +053031#include "instruction_simplifier_x86.h"
Aart Bik2ca10eb2017-11-15 15:17:53 -080032#endif
33#if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64)
34#include "x86_memory_gen.h"
35#endif
Shalini Salomi Bodapatidd121f62018-10-26 15:03:53 +053036#ifdef ART_ENABLE_CODEGEN_x86_64
37#include "instruction_simplifier_x86_64.h"
38#endif
Aart Bik2ca10eb2017-11-15 15:17:53 -080039
40#include "bounds_check_elimination.h"
41#include "cha_guard_optimization.h"
42#include "code_sinking.h"
43#include "constant_folding.h"
44#include "constructor_fence_redundancy_elimination.h"
45#include "dead_code_elimination.h"
David Sehr9e734c72018-01-04 17:56:19 -080046#include "dex/code_item_accessors-inl.h"
Vladimir Markoa0431112018-06-25 09:32:54 +010047#include "driver/compiler_options.h"
Aart Bik2ca10eb2017-11-15 15:17:53 -080048#include "driver/dex_compilation_unit.h"
49#include "gvn.h"
50#include "induction_var_analysis.h"
51#include "inliner.h"
52#include "instruction_simplifier.h"
53#include "intrinsics.h"
54#include "licm.h"
55#include "load_store_analysis.h"
56#include "load_store_elimination.h"
57#include "loop_optimization.h"
58#include "scheduler.h"
59#include "select_generator.h"
60#include "sharpening.h"
61#include "side_effects_analysis.h"
62
63// Decide between default or alternative pass name.
64
Roland Levillain75be2832014-10-17 17:02:00 +010065namespace art {
Aart Bik2ca10eb2017-11-15 15:17:53 -080066
67const char* OptimizationPassName(OptimizationPass pass) {
68 switch (pass) {
69 case OptimizationPass::kSideEffectsAnalysis:
70 return SideEffectsAnalysis::kSideEffectsAnalysisPassName;
71 case OptimizationPass::kInductionVarAnalysis:
72 return HInductionVarAnalysis::kInductionPassName;
73 case OptimizationPass::kLoadStoreAnalysis:
74 return LoadStoreAnalysis::kLoadStoreAnalysisPassName;
75 case OptimizationPass::kGlobalValueNumbering:
76 return GVNOptimization::kGlobalValueNumberingPassName;
77 case OptimizationPass::kInvariantCodeMotion:
78 return LICM::kLoopInvariantCodeMotionPassName;
79 case OptimizationPass::kLoopOptimization:
80 return HLoopOptimization::kLoopOptimizationPassName;
81 case OptimizationPass::kBoundsCheckElimination:
82 return BoundsCheckElimination::kBoundsCheckEliminationPassName;
83 case OptimizationPass::kLoadStoreElimination:
84 return LoadStoreElimination::kLoadStoreEliminationPassName;
85 case OptimizationPass::kConstantFolding:
86 return HConstantFolding::kConstantFoldingPassName;
87 case OptimizationPass::kDeadCodeElimination:
88 return HDeadCodeElimination::kDeadCodeEliminationPassName;
89 case OptimizationPass::kInliner:
90 return HInliner::kInlinerPassName;
Aart Bik2ca10eb2017-11-15 15:17:53 -080091 case OptimizationPass::kSelectGenerator:
92 return HSelectGenerator::kSelectGeneratorPassName;
93 case OptimizationPass::kInstructionSimplifier:
94 return InstructionSimplifier::kInstructionSimplifierPassName;
Aart Bik2ca10eb2017-11-15 15:17:53 -080095 case OptimizationPass::kCHAGuardOptimization:
96 return CHAGuardOptimization::kCHAGuardOptimizationPassName;
97 case OptimizationPass::kCodeSinking:
98 return CodeSinking::kCodeSinkingPassName;
99 case OptimizationPass::kConstructorFenceRedundancyElimination:
100 return ConstructorFenceRedundancyElimination::kCFREPassName;
101 case OptimizationPass::kScheduling:
102 return HInstructionScheduling::kInstructionSchedulingPassName;
103#ifdef ART_ENABLE_CODEGEN_arm
104 case OptimizationPass::kInstructionSimplifierArm:
105 return arm::InstructionSimplifierArm::kInstructionSimplifierArmPassName;
106#endif
107#ifdef ART_ENABLE_CODEGEN_arm64
108 case OptimizationPass::kInstructionSimplifierArm64:
109 return arm64::InstructionSimplifierArm64::kInstructionSimplifierArm64PassName;
110#endif
111#ifdef ART_ENABLE_CODEGEN_mips
112 case OptimizationPass::kPcRelativeFixupsMips:
113 return mips::PcRelativeFixups::kPcRelativeFixupsMipsPassName;
114 case OptimizationPass::kInstructionSimplifierMips:
115 return mips::InstructionSimplifierMips::kInstructionSimplifierMipsPassName;
116#endif
117#ifdef ART_ENABLE_CODEGEN_x86
118 case OptimizationPass::kPcRelativeFixupsX86:
119 return x86::PcRelativeFixups::kPcRelativeFixupsX86PassName;
Shalini Salomi Bodapatidd121f62018-10-26 15:03:53 +0530120 case OptimizationPass::kInstructionSimplifierX86:
121 return x86::InstructionSimplifierX86::kInstructionSimplifierX86PassName;
122#endif
123#ifdef ART_ENABLE_CODEGEN_x86_64
124 case OptimizationPass::kInstructionSimplifierX86_64:
125 return x86_64::InstructionSimplifierX86_64::kInstructionSimplifierX86_64PassName;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800126#endif
127#if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64)
128 case OptimizationPass::kX86MemoryOperandGeneration:
129 return x86::X86MemoryOperandGeneration::kX86MemoryOperandGenerationPassName;
130#endif
Aart Bik2e148682018-04-18 16:11:12 -0700131 case OptimizationPass::kNone:
132 LOG(FATAL) << "kNone does not represent an actual pass";
133 UNREACHABLE();
Aart Bik2ca10eb2017-11-15 15:17:53 -0800134 }
135}
136
Aart Bik2e148682018-04-18 16:11:12 -0700137#define X(x) if (pass_name == OptimizationPassName((x))) return (x)
Aart Bik2ca10eb2017-11-15 15:17:53 -0800138
Aart Bik2e148682018-04-18 16:11:12 -0700139OptimizationPass OptimizationPassByName(const std::string& pass_name) {
Aart Bik2ca10eb2017-11-15 15:17:53 -0800140 X(OptimizationPass::kBoundsCheckElimination);
141 X(OptimizationPass::kCHAGuardOptimization);
142 X(OptimizationPass::kCodeSinking);
143 X(OptimizationPass::kConstantFolding);
144 X(OptimizationPass::kConstructorFenceRedundancyElimination);
145 X(OptimizationPass::kDeadCodeElimination);
146 X(OptimizationPass::kGlobalValueNumbering);
147 X(OptimizationPass::kInductionVarAnalysis);
148 X(OptimizationPass::kInliner);
149 X(OptimizationPass::kInstructionSimplifier);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800150 X(OptimizationPass::kInvariantCodeMotion);
151 X(OptimizationPass::kLoadStoreAnalysis);
152 X(OptimizationPass::kLoadStoreElimination);
153 X(OptimizationPass::kLoopOptimization);
154 X(OptimizationPass::kScheduling);
155 X(OptimizationPass::kSelectGenerator);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800156 X(OptimizationPass::kSideEffectsAnalysis);
157#ifdef ART_ENABLE_CODEGEN_arm
158 X(OptimizationPass::kInstructionSimplifierArm);
159#endif
160#ifdef ART_ENABLE_CODEGEN_arm64
161 X(OptimizationPass::kInstructionSimplifierArm64);
162#endif
163#ifdef ART_ENABLE_CODEGEN_mips
164 X(OptimizationPass::kPcRelativeFixupsMips);
165 X(OptimizationPass::kInstructionSimplifierMips);
166#endif
167#ifdef ART_ENABLE_CODEGEN_x86
168 X(OptimizationPass::kPcRelativeFixupsX86);
169 X(OptimizationPass::kX86MemoryOperandGeneration);
170#endif
Aart Bik2e148682018-04-18 16:11:12 -0700171 LOG(FATAL) << "Cannot find optimization " << pass_name;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800172 UNREACHABLE();
173}
174
175#undef X
176
177ArenaVector<HOptimization*> ConstructOptimizations(
178 const OptimizationDef definitions[],
179 size_t length,
180 ArenaAllocator* allocator,
181 HGraph* graph,
182 OptimizingCompilerStats* stats,
183 CodeGenerator* codegen,
Aart Bik2ca10eb2017-11-15 15:17:53 -0800184 const DexCompilationUnit& dex_compilation_unit,
185 VariableSizedHandleScope* handles) {
186 ArenaVector<HOptimization*> optimizations(allocator->Adapter());
187
188 // Some optimizations require SideEffectsAnalysis or HInductionVarAnalysis
189 // instances. This method uses the nearest instance preceeding it in the pass
190 // name list or fails fatally if no such analysis can be found.
191 SideEffectsAnalysis* most_recent_side_effects = nullptr;
192 HInductionVarAnalysis* most_recent_induction = nullptr;
193 LoadStoreAnalysis* most_recent_lsa = nullptr;
194
195 // Loop over the requested optimizations.
196 for (size_t i = 0; i < length; i++) {
Aart Bik2e148682018-04-18 16:11:12 -0700197 OptimizationPass pass = definitions[i].pass;
198 const char* alt_name = definitions[i].pass_name;
199 const char* pass_name = alt_name != nullptr
Aart Bik2ca10eb2017-11-15 15:17:53 -0800200 ? alt_name
201 : OptimizationPassName(pass);
202 HOptimization* opt = nullptr;
203
204 switch (pass) {
205 //
206 // Analysis passes (kept in most recent for subsequent passes).
207 //
208 case OptimizationPass::kSideEffectsAnalysis:
Aart Bik2e148682018-04-18 16:11:12 -0700209 opt = most_recent_side_effects = new (allocator) SideEffectsAnalysis(graph, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800210 break;
211 case OptimizationPass::kInductionVarAnalysis:
Aart Bik2e148682018-04-18 16:11:12 -0700212 opt = most_recent_induction = new (allocator) HInductionVarAnalysis(graph, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800213 break;
214 case OptimizationPass::kLoadStoreAnalysis:
Aart Bik2e148682018-04-18 16:11:12 -0700215 opt = most_recent_lsa = new (allocator) LoadStoreAnalysis(graph, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800216 break;
217 //
218 // Passes that need prior analysis.
219 //
220 case OptimizationPass::kGlobalValueNumbering:
221 CHECK(most_recent_side_effects != nullptr);
Aart Bik2e148682018-04-18 16:11:12 -0700222 opt = new (allocator) GVNOptimization(graph, *most_recent_side_effects, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800223 break;
224 case OptimizationPass::kInvariantCodeMotion:
225 CHECK(most_recent_side_effects != nullptr);
Aart Bik2e148682018-04-18 16:11:12 -0700226 opt = new (allocator) LICM(graph, *most_recent_side_effects, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800227 break;
228 case OptimizationPass::kLoopOptimization:
229 CHECK(most_recent_induction != nullptr);
Aart Bik2e148682018-04-18 16:11:12 -0700230 opt = new (allocator) HLoopOptimization(
Vladimir Markoa0431112018-06-25 09:32:54 +0100231 graph, &codegen->GetCompilerOptions(), most_recent_induction, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800232 break;
233 case OptimizationPass::kBoundsCheckElimination:
234 CHECK(most_recent_side_effects != nullptr && most_recent_induction != nullptr);
235 opt = new (allocator) BoundsCheckElimination(
Aart Bik2e148682018-04-18 16:11:12 -0700236 graph, *most_recent_side_effects, most_recent_induction, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800237 break;
238 case OptimizationPass::kLoadStoreElimination:
239 CHECK(most_recent_side_effects != nullptr && most_recent_induction != nullptr);
240 opt = new (allocator) LoadStoreElimination(
Aart Bik2e148682018-04-18 16:11:12 -0700241 graph, *most_recent_side_effects, *most_recent_lsa, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800242 break;
243 //
244 // Regular passes.
245 //
246 case OptimizationPass::kConstantFolding:
Aart Bik2e148682018-04-18 16:11:12 -0700247 opt = new (allocator) HConstantFolding(graph, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800248 break;
249 case OptimizationPass::kDeadCodeElimination:
Aart Bik2e148682018-04-18 16:11:12 -0700250 opt = new (allocator) HDeadCodeElimination(graph, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800251 break;
252 case OptimizationPass::kInliner: {
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800253 CodeItemDataAccessor accessor(*dex_compilation_unit.GetDexFile(),
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800254 dex_compilation_unit.GetCodeItem());
Aart Bik2ca10eb2017-11-15 15:17:53 -0800255 opt = new (allocator) HInliner(graph, // outer_graph
256 graph, // outermost_graph
257 codegen,
258 dex_compilation_unit, // outer_compilation_unit
259 dex_compilation_unit, // outermost_compilation_unit
Aart Bik2ca10eb2017-11-15 15:17:53 -0800260 handles,
261 stats,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800262 accessor.RegistersSize(),
Andreas Gampe3db70682018-12-26 15:12:03 -0800263 /* total_number_of_instructions= */ 0,
264 /* parent= */ nullptr,
265 /* depth= */ 0,
Aart Bik2e148682018-04-18 16:11:12 -0700266 pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800267 break;
268 }
Aart Bik2ca10eb2017-11-15 15:17:53 -0800269 case OptimizationPass::kSelectGenerator:
Aart Bik2e148682018-04-18 16:11:12 -0700270 opt = new (allocator) HSelectGenerator(graph, handles, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800271 break;
272 case OptimizationPass::kInstructionSimplifier:
Vladimir Markobb089b62018-06-28 17:30:16 +0100273 opt = new (allocator) InstructionSimplifier(graph, codegen, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800274 break;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800275 case OptimizationPass::kCHAGuardOptimization:
Aart Bik2e148682018-04-18 16:11:12 -0700276 opt = new (allocator) CHAGuardOptimization(graph, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800277 break;
278 case OptimizationPass::kCodeSinking:
Aart Bik2e148682018-04-18 16:11:12 -0700279 opt = new (allocator) CodeSinking(graph, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800280 break;
281 case OptimizationPass::kConstructorFenceRedundancyElimination:
Aart Bik2e148682018-04-18 16:11:12 -0700282 opt = new (allocator) ConstructorFenceRedundancyElimination(graph, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800283 break;
284 case OptimizationPass::kScheduling:
285 opt = new (allocator) HInstructionScheduling(
Vladimir Markoa0431112018-06-25 09:32:54 +0100286 graph, codegen->GetCompilerOptions().GetInstructionSet(), codegen, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800287 break;
288 //
289 // Arch-specific passes.
290 //
291#ifdef ART_ENABLE_CODEGEN_arm
292 case OptimizationPass::kInstructionSimplifierArm:
293 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
294 opt = new (allocator) arm::InstructionSimplifierArm(graph, stats);
295 break;
296#endif
297#ifdef ART_ENABLE_CODEGEN_arm64
298 case OptimizationPass::kInstructionSimplifierArm64:
299 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
300 opt = new (allocator) arm64::InstructionSimplifierArm64(graph, stats);
301 break;
302#endif
303#ifdef ART_ENABLE_CODEGEN_mips
304 case OptimizationPass::kPcRelativeFixupsMips:
305 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
306 opt = new (allocator) mips::PcRelativeFixups(graph, codegen, stats);
307 break;
308 case OptimizationPass::kInstructionSimplifierMips:
309 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
310 opt = new (allocator) mips::InstructionSimplifierMips(graph, codegen, stats);
311 break;
312#endif
313#ifdef ART_ENABLE_CODEGEN_x86
314 case OptimizationPass::kPcRelativeFixupsX86:
315 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
316 opt = new (allocator) x86::PcRelativeFixups(graph, codegen, stats);
317 break;
318 case OptimizationPass::kX86MemoryOperandGeneration:
319 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
320 opt = new (allocator) x86::X86MemoryOperandGeneration(graph, codegen, stats);
321 break;
Shalini Salomi Bodapatidd121f62018-10-26 15:03:53 +0530322 case OptimizationPass::kInstructionSimplifierX86:
323 opt = new (allocator) x86::InstructionSimplifierX86(graph, codegen, stats);
324 break;
325#endif
326#ifdef ART_ENABLE_CODEGEN_x86_64
327 case OptimizationPass::kInstructionSimplifierX86_64:
328 opt = new (allocator) x86_64::InstructionSimplifierX86_64(graph, codegen, stats);
329 break;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800330#endif
Aart Bik2e148682018-04-18 16:11:12 -0700331 case OptimizationPass::kNone:
332 LOG(FATAL) << "kNone does not represent an actual pass";
333 UNREACHABLE();
Aart Bik2ca10eb2017-11-15 15:17:53 -0800334 } // switch
335
336 // Add each next optimization to result vector.
337 CHECK(opt != nullptr);
Aart Bik2e148682018-04-18 16:11:12 -0700338 DCHECK_STREQ(pass_name, opt->GetPassName()); // sanity
Aart Bik2ca10eb2017-11-15 15:17:53 -0800339 optimizations.push_back(opt);
340 }
341
342 return optimizations;
343}
344
Roland Levillain75be2832014-10-17 17:02:00 +0100345} // namespace art