blob: 3ad2c6b3f622339ae0b1f63cddab8ebe246f9183 [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"
Gupta Kumar, Sanjiv61908882018-06-29 13:06:35 +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
36
37#include "bounds_check_elimination.h"
38#include "cha_guard_optimization.h"
39#include "code_sinking.h"
40#include "constant_folding.h"
41#include "constructor_fence_redundancy_elimination.h"
42#include "dead_code_elimination.h"
David Sehr9e734c72018-01-04 17:56:19 -080043#include "dex/code_item_accessors-inl.h"
Vladimir Markoa0431112018-06-25 09:32:54 +010044#include "driver/compiler_options.h"
Aart Bik2ca10eb2017-11-15 15:17:53 -080045#include "driver/dex_compilation_unit.h"
46#include "gvn.h"
47#include "induction_var_analysis.h"
48#include "inliner.h"
49#include "instruction_simplifier.h"
50#include "intrinsics.h"
51#include "licm.h"
52#include "load_store_analysis.h"
53#include "load_store_elimination.h"
54#include "loop_optimization.h"
55#include "scheduler.h"
56#include "select_generator.h"
57#include "sharpening.h"
58#include "side_effects_analysis.h"
59
60// Decide between default or alternative pass name.
61
Roland Levillain75be2832014-10-17 17:02:00 +010062namespace art {
Aart Bik2ca10eb2017-11-15 15:17:53 -080063
64const char* OptimizationPassName(OptimizationPass pass) {
65 switch (pass) {
66 case OptimizationPass::kSideEffectsAnalysis:
67 return SideEffectsAnalysis::kSideEffectsAnalysisPassName;
68 case OptimizationPass::kInductionVarAnalysis:
69 return HInductionVarAnalysis::kInductionPassName;
70 case OptimizationPass::kLoadStoreAnalysis:
71 return LoadStoreAnalysis::kLoadStoreAnalysisPassName;
72 case OptimizationPass::kGlobalValueNumbering:
73 return GVNOptimization::kGlobalValueNumberingPassName;
74 case OptimizationPass::kInvariantCodeMotion:
75 return LICM::kLoopInvariantCodeMotionPassName;
76 case OptimizationPass::kLoopOptimization:
77 return HLoopOptimization::kLoopOptimizationPassName;
78 case OptimizationPass::kBoundsCheckElimination:
79 return BoundsCheckElimination::kBoundsCheckEliminationPassName;
80 case OptimizationPass::kLoadStoreElimination:
81 return LoadStoreElimination::kLoadStoreEliminationPassName;
82 case OptimizationPass::kConstantFolding:
83 return HConstantFolding::kConstantFoldingPassName;
84 case OptimizationPass::kDeadCodeElimination:
85 return HDeadCodeElimination::kDeadCodeEliminationPassName;
86 case OptimizationPass::kInliner:
87 return HInliner::kInlinerPassName;
88 case OptimizationPass::kSharpening:
89 return HSharpening::kSharpeningPassName;
90 case OptimizationPass::kSelectGenerator:
91 return HSelectGenerator::kSelectGeneratorPassName;
92 case OptimizationPass::kInstructionSimplifier:
93 return InstructionSimplifier::kInstructionSimplifierPassName;
94 case OptimizationPass::kIntrinsicsRecognizer:
95 return IntrinsicsRecognizer::kIntrinsicsRecognizerPassName;
96 case OptimizationPass::kCHAGuardOptimization:
97 return CHAGuardOptimization::kCHAGuardOptimizationPassName;
98 case OptimizationPass::kCodeSinking:
99 return CodeSinking::kCodeSinkingPassName;
100 case OptimizationPass::kConstructorFenceRedundancyElimination:
101 return ConstructorFenceRedundancyElimination::kCFREPassName;
102 case OptimizationPass::kScheduling:
103 return HInstructionScheduling::kInstructionSchedulingPassName;
104#ifdef ART_ENABLE_CODEGEN_arm
105 case OptimizationPass::kInstructionSimplifierArm:
106 return arm::InstructionSimplifierArm::kInstructionSimplifierArmPassName;
107#endif
108#ifdef ART_ENABLE_CODEGEN_arm64
109 case OptimizationPass::kInstructionSimplifierArm64:
110 return arm64::InstructionSimplifierArm64::kInstructionSimplifierArm64PassName;
111#endif
112#ifdef ART_ENABLE_CODEGEN_mips
113 case OptimizationPass::kPcRelativeFixupsMips:
114 return mips::PcRelativeFixups::kPcRelativeFixupsMipsPassName;
115 case OptimizationPass::kInstructionSimplifierMips:
116 return mips::InstructionSimplifierMips::kInstructionSimplifierMipsPassName;
117#endif
118#ifdef ART_ENABLE_CODEGEN_x86
119 case OptimizationPass::kPcRelativeFixupsX86:
120 return x86::PcRelativeFixups::kPcRelativeFixupsX86PassName;
121#endif
122#if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64)
123 case OptimizationPass::kX86MemoryOperandGeneration:
124 return x86::X86MemoryOperandGeneration::kX86MemoryOperandGenerationPassName;
Gupta Kumar, Sanjiv61908882018-06-29 13:06:35 +0530125 case OptimizationPass::kInstructionSimplifierX86:
126 return x86::InstructionSimplifierX86::kInstructionSimplifierX86PassName;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800127#endif
Aart Bik2e148682018-04-18 16:11:12 -0700128 case OptimizationPass::kNone:
129 LOG(FATAL) << "kNone does not represent an actual pass";
130 UNREACHABLE();
Aart Bik2ca10eb2017-11-15 15:17:53 -0800131 }
132}
133
Aart Bik2e148682018-04-18 16:11:12 -0700134#define X(x) if (pass_name == OptimizationPassName((x))) return (x)
Aart Bik2ca10eb2017-11-15 15:17:53 -0800135
Aart Bik2e148682018-04-18 16:11:12 -0700136OptimizationPass OptimizationPassByName(const std::string& pass_name) {
Aart Bik2ca10eb2017-11-15 15:17:53 -0800137 X(OptimizationPass::kBoundsCheckElimination);
138 X(OptimizationPass::kCHAGuardOptimization);
139 X(OptimizationPass::kCodeSinking);
140 X(OptimizationPass::kConstantFolding);
141 X(OptimizationPass::kConstructorFenceRedundancyElimination);
142 X(OptimizationPass::kDeadCodeElimination);
143 X(OptimizationPass::kGlobalValueNumbering);
144 X(OptimizationPass::kInductionVarAnalysis);
145 X(OptimizationPass::kInliner);
146 X(OptimizationPass::kInstructionSimplifier);
147 X(OptimizationPass::kIntrinsicsRecognizer);
148 X(OptimizationPass::kInvariantCodeMotion);
149 X(OptimizationPass::kLoadStoreAnalysis);
150 X(OptimizationPass::kLoadStoreElimination);
151 X(OptimizationPass::kLoopOptimization);
152 X(OptimizationPass::kScheduling);
153 X(OptimizationPass::kSelectGenerator);
154 X(OptimizationPass::kSharpening);
155 X(OptimizationPass::kSideEffectsAnalysis);
156#ifdef ART_ENABLE_CODEGEN_arm
157 X(OptimizationPass::kInstructionSimplifierArm);
158#endif
159#ifdef ART_ENABLE_CODEGEN_arm64
160 X(OptimizationPass::kInstructionSimplifierArm64);
161#endif
162#ifdef ART_ENABLE_CODEGEN_mips
163 X(OptimizationPass::kPcRelativeFixupsMips);
164 X(OptimizationPass::kInstructionSimplifierMips);
165#endif
166#ifdef ART_ENABLE_CODEGEN_x86
167 X(OptimizationPass::kPcRelativeFixupsX86);
168 X(OptimizationPass::kX86MemoryOperandGeneration);
Gupta Kumar, Sanjiv61908882018-06-29 13:06:35 +0530169 X(OptimizationPass::kInstructionSimplifierX86);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800170#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,
184 CompilerDriver* driver,
185 const DexCompilationUnit& dex_compilation_unit,
186 VariableSizedHandleScope* handles) {
187 ArenaVector<HOptimization*> optimizations(allocator->Adapter());
188
189 // Some optimizations require SideEffectsAnalysis or HInductionVarAnalysis
190 // instances. This method uses the nearest instance preceeding it in the pass
191 // name list or fails fatally if no such analysis can be found.
192 SideEffectsAnalysis* most_recent_side_effects = nullptr;
193 HInductionVarAnalysis* most_recent_induction = nullptr;
194 LoadStoreAnalysis* most_recent_lsa = nullptr;
195
196 // Loop over the requested optimizations.
197 for (size_t i = 0; i < length; i++) {
Aart Bik2e148682018-04-18 16:11:12 -0700198 OptimizationPass pass = definitions[i].pass;
199 const char* alt_name = definitions[i].pass_name;
200 const char* pass_name = alt_name != nullptr
Aart Bik2ca10eb2017-11-15 15:17:53 -0800201 ? alt_name
202 : OptimizationPassName(pass);
203 HOptimization* opt = nullptr;
204
205 switch (pass) {
206 //
207 // Analysis passes (kept in most recent for subsequent passes).
208 //
209 case OptimizationPass::kSideEffectsAnalysis:
Aart Bik2e148682018-04-18 16:11:12 -0700210 opt = most_recent_side_effects = new (allocator) SideEffectsAnalysis(graph, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800211 break;
212 case OptimizationPass::kInductionVarAnalysis:
Aart Bik2e148682018-04-18 16:11:12 -0700213 opt = most_recent_induction = new (allocator) HInductionVarAnalysis(graph, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800214 break;
215 case OptimizationPass::kLoadStoreAnalysis:
Aart Bik2e148682018-04-18 16:11:12 -0700216 opt = most_recent_lsa = new (allocator) LoadStoreAnalysis(graph, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800217 break;
218 //
219 // Passes that need prior analysis.
220 //
221 case OptimizationPass::kGlobalValueNumbering:
222 CHECK(most_recent_side_effects != nullptr);
Aart Bik2e148682018-04-18 16:11:12 -0700223 opt = new (allocator) GVNOptimization(graph, *most_recent_side_effects, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800224 break;
225 case OptimizationPass::kInvariantCodeMotion:
226 CHECK(most_recent_side_effects != nullptr);
Aart Bik2e148682018-04-18 16:11:12 -0700227 opt = new (allocator) LICM(graph, *most_recent_side_effects, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800228 break;
229 case OptimizationPass::kLoopOptimization:
230 CHECK(most_recent_induction != nullptr);
Aart Bik2e148682018-04-18 16:11:12 -0700231 opt = new (allocator) HLoopOptimization(
Vladimir Markoa0431112018-06-25 09:32:54 +0100232 graph, &codegen->GetCompilerOptions(), most_recent_induction, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800233 break;
234 case OptimizationPass::kBoundsCheckElimination:
235 CHECK(most_recent_side_effects != nullptr && most_recent_induction != nullptr);
236 opt = new (allocator) BoundsCheckElimination(
Aart Bik2e148682018-04-18 16:11:12 -0700237 graph, *most_recent_side_effects, most_recent_induction, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800238 break;
239 case OptimizationPass::kLoadStoreElimination:
240 CHECK(most_recent_side_effects != nullptr && most_recent_induction != nullptr);
241 opt = new (allocator) LoadStoreElimination(
Aart Bik2e148682018-04-18 16:11:12 -0700242 graph, *most_recent_side_effects, *most_recent_lsa, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800243 break;
244 //
245 // Regular passes.
246 //
247 case OptimizationPass::kConstantFolding:
Aart Bik2e148682018-04-18 16:11:12 -0700248 opt = new (allocator) HConstantFolding(graph, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800249 break;
250 case OptimizationPass::kDeadCodeElimination:
Aart Bik2e148682018-04-18 16:11:12 -0700251 opt = new (allocator) HDeadCodeElimination(graph, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800252 break;
253 case OptimizationPass::kInliner: {
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800254 CodeItemDataAccessor accessor(*dex_compilation_unit.GetDexFile(),
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800255 dex_compilation_unit.GetCodeItem());
Aart Bik2ca10eb2017-11-15 15:17:53 -0800256 opt = new (allocator) HInliner(graph, // outer_graph
257 graph, // outermost_graph
258 codegen,
259 dex_compilation_unit, // outer_compilation_unit
260 dex_compilation_unit, // outermost_compilation_unit
261 driver,
262 handles,
263 stats,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800264 accessor.RegistersSize(),
Aart Bik2ca10eb2017-11-15 15:17:53 -0800265 /* total_number_of_instructions */ 0,
266 /* parent */ nullptr,
267 /* depth */ 0,
Aart Bik2e148682018-04-18 16:11:12 -0700268 pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800269 break;
270 }
271 case OptimizationPass::kSharpening:
Aart Bik2e148682018-04-18 16:11:12 -0700272 opt = new (allocator) HSharpening(graph, codegen, driver, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800273 break;
274 case OptimizationPass::kSelectGenerator:
Aart Bik2e148682018-04-18 16:11:12 -0700275 opt = new (allocator) HSelectGenerator(graph, handles, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800276 break;
277 case OptimizationPass::kInstructionSimplifier:
Aart Bik2e148682018-04-18 16:11:12 -0700278 opt = new (allocator) InstructionSimplifier(graph, codegen, driver, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800279 break;
280 case OptimizationPass::kIntrinsicsRecognizer:
Aart Bik2e148682018-04-18 16:11:12 -0700281 opt = new (allocator) IntrinsicsRecognizer(graph, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800282 break;
283 case OptimizationPass::kCHAGuardOptimization:
Aart Bik2e148682018-04-18 16:11:12 -0700284 opt = new (allocator) CHAGuardOptimization(graph, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800285 break;
286 case OptimizationPass::kCodeSinking:
Aart Bik2e148682018-04-18 16:11:12 -0700287 opt = new (allocator) CodeSinking(graph, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800288 break;
289 case OptimizationPass::kConstructorFenceRedundancyElimination:
Aart Bik2e148682018-04-18 16:11:12 -0700290 opt = new (allocator) ConstructorFenceRedundancyElimination(graph, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800291 break;
292 case OptimizationPass::kScheduling:
293 opt = new (allocator) HInstructionScheduling(
Vladimir Markoa0431112018-06-25 09:32:54 +0100294 graph, codegen->GetCompilerOptions().GetInstructionSet(), codegen, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800295 break;
296 //
297 // Arch-specific passes.
298 //
299#ifdef ART_ENABLE_CODEGEN_arm
300 case OptimizationPass::kInstructionSimplifierArm:
301 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
302 opt = new (allocator) arm::InstructionSimplifierArm(graph, stats);
303 break;
304#endif
305#ifdef ART_ENABLE_CODEGEN_arm64
306 case OptimizationPass::kInstructionSimplifierArm64:
307 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
308 opt = new (allocator) arm64::InstructionSimplifierArm64(graph, stats);
309 break;
310#endif
311#ifdef ART_ENABLE_CODEGEN_mips
312 case OptimizationPass::kPcRelativeFixupsMips:
313 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
314 opt = new (allocator) mips::PcRelativeFixups(graph, codegen, stats);
315 break;
316 case OptimizationPass::kInstructionSimplifierMips:
317 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
318 opt = new (allocator) mips::InstructionSimplifierMips(graph, codegen, stats);
319 break;
320#endif
321#ifdef ART_ENABLE_CODEGEN_x86
322 case OptimizationPass::kPcRelativeFixupsX86:
323 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
324 opt = new (allocator) x86::PcRelativeFixups(graph, codegen, stats);
325 break;
326 case OptimizationPass::kX86MemoryOperandGeneration:
327 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
328 opt = new (allocator) x86::X86MemoryOperandGeneration(graph, codegen, stats);
329 break;
Gupta Kumar, Sanjiv61908882018-06-29 13:06:35 +0530330 case OptimizationPass::kInstructionSimplifierX86:
331 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
332 opt = new (allocator) x86::InstructionSimplifierX86(graph, codegen, stats);
333 break;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800334#endif
Aart Bik2e148682018-04-18 16:11:12 -0700335 case OptimizationPass::kNone:
336 LOG(FATAL) << "kNone does not represent an actual pass";
337 UNREACHABLE();
Aart Bik2ca10eb2017-11-15 15:17:53 -0800338 } // switch
339
340 // Add each next optimization to result vector.
341 CHECK(opt != nullptr);
Aart Bik2e148682018-04-18 16:11:12 -0700342 DCHECK_STREQ(pass_name, opt->GetPassName()); // sanity
Aart Bik2ca10eb2017-11-15 15:17:53 -0800343 optimizations.push_back(opt);
344 }
345
346 return optimizations;
347}
348
Roland Levillain75be2832014-10-17 17:02:00 +0100349} // namespace art