blob: e1b97b4aac3911cccd83245cc16e9cc95cd8f239 [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
Vladimir Markod3e9c622020-08-05 12:20:28 +010020#include "critical_native_abi_fixup_arm.h"
Aart Bik2ca10eb2017-11-15 15:17:53 -080021#include "instruction_simplifier_arm.h"
22#endif
23#ifdef ART_ENABLE_CODEGEN_arm64
24#include "instruction_simplifier_arm64.h"
25#endif
Aart Bik2ca10eb2017-11-15 15:17:53 -080026#ifdef ART_ENABLE_CODEGEN_x86
27#include "pc_relative_fixups_x86.h"
Shalini Salomi Bodapatidd121f62018-10-26 15:03:53 +053028#include "instruction_simplifier_x86.h"
Aart Bik2ca10eb2017-11-15 15:17:53 -080029#endif
30#if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64)
31#include "x86_memory_gen.h"
32#endif
Shalini Salomi Bodapatidd121f62018-10-26 15:03:53 +053033#ifdef ART_ENABLE_CODEGEN_x86_64
34#include "instruction_simplifier_x86_64.h"
35#endif
Aart Bik2ca10eb2017-11-15 15:17:53 -080036
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"
Aart Bik2ca10eb2017-11-15 15:17:53 -080052#include "load_store_elimination.h"
53#include "loop_optimization.h"
54#include "scheduler.h"
55#include "select_generator.h"
56#include "sharpening.h"
57#include "side_effects_analysis.h"
Santiago Aboy Solanesd4229602023-01-03 16:20:50 +000058#include "write_barrier_elimination.h"
Aart Bik2ca10eb2017-11-15 15:17:53 -080059
60// Decide between default or alternative pass name.
61
VladimĂ­r Marko434d9682022-11-04 14:04:17 +000062namespace art HIDDEN {
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;
Aart Bik2ca10eb2017-11-15 15:17:53 -080070 case OptimizationPass::kGlobalValueNumbering:
71 return GVNOptimization::kGlobalValueNumberingPassName;
72 case OptimizationPass::kInvariantCodeMotion:
73 return LICM::kLoopInvariantCodeMotionPassName;
74 case OptimizationPass::kLoopOptimization:
75 return HLoopOptimization::kLoopOptimizationPassName;
76 case OptimizationPass::kBoundsCheckElimination:
77 return BoundsCheckElimination::kBoundsCheckEliminationPassName;
78 case OptimizationPass::kLoadStoreElimination:
79 return LoadStoreElimination::kLoadStoreEliminationPassName;
80 case OptimizationPass::kConstantFolding:
81 return HConstantFolding::kConstantFoldingPassName;
82 case OptimizationPass::kDeadCodeElimination:
83 return HDeadCodeElimination::kDeadCodeEliminationPassName;
84 case OptimizationPass::kInliner:
85 return HInliner::kInlinerPassName;
Aart Bik2ca10eb2017-11-15 15:17:53 -080086 case OptimizationPass::kSelectGenerator:
87 return HSelectGenerator::kSelectGeneratorPassName;
Evgeny Astigeevich6587d912020-06-12 10:51:43 +010088 case OptimizationPass::kAggressiveInstructionSimplifier:
Aart Bik2ca10eb2017-11-15 15:17:53 -080089 case OptimizationPass::kInstructionSimplifier:
90 return InstructionSimplifier::kInstructionSimplifierPassName;
Aart Bik2ca10eb2017-11-15 15:17:53 -080091 case OptimizationPass::kCHAGuardOptimization:
92 return CHAGuardOptimization::kCHAGuardOptimizationPassName;
93 case OptimizationPass::kCodeSinking:
94 return CodeSinking::kCodeSinkingPassName;
95 case OptimizationPass::kConstructorFenceRedundancyElimination:
96 return ConstructorFenceRedundancyElimination::kCFREPassName;
97 case OptimizationPass::kScheduling:
98 return HInstructionScheduling::kInstructionSchedulingPassName;
Santiago Aboy Solanesd4229602023-01-03 16:20:50 +000099 case OptimizationPass::kWriteBarrierElimination:
100 return WriteBarrierElimination::kWBEPassName;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800101#ifdef ART_ENABLE_CODEGEN_arm
102 case OptimizationPass::kInstructionSimplifierArm:
103 return arm::InstructionSimplifierArm::kInstructionSimplifierArmPassName;
Vladimir Markod3e9c622020-08-05 12:20:28 +0100104 case OptimizationPass::kCriticalNativeAbiFixupArm:
105 return arm::CriticalNativeAbiFixupArm::kCriticalNativeAbiFixupArmPassName;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800106#endif
107#ifdef ART_ENABLE_CODEGEN_arm64
108 case OptimizationPass::kInstructionSimplifierArm64:
109 return arm64::InstructionSimplifierArm64::kInstructionSimplifierArm64PassName;
110#endif
Aart Bik2ca10eb2017-11-15 15:17:53 -0800111#ifdef ART_ENABLE_CODEGEN_x86
112 case OptimizationPass::kPcRelativeFixupsX86:
113 return x86::PcRelativeFixups::kPcRelativeFixupsX86PassName;
Shalini Salomi Bodapatidd121f62018-10-26 15:03:53 +0530114 case OptimizationPass::kInstructionSimplifierX86:
115 return x86::InstructionSimplifierX86::kInstructionSimplifierX86PassName;
116#endif
117#ifdef ART_ENABLE_CODEGEN_x86_64
118 case OptimizationPass::kInstructionSimplifierX86_64:
119 return x86_64::InstructionSimplifierX86_64::kInstructionSimplifierX86_64PassName;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800120#endif
121#if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64)
122 case OptimizationPass::kX86MemoryOperandGeneration:
123 return x86::X86MemoryOperandGeneration::kX86MemoryOperandGenerationPassName;
124#endif
Aart Bik2e148682018-04-18 16:11:12 -0700125 case OptimizationPass::kNone:
126 LOG(FATAL) << "kNone does not represent an actual pass";
127 UNREACHABLE();
Aart Bik2ca10eb2017-11-15 15:17:53 -0800128 }
129}
130
Aart Bik2e148682018-04-18 16:11:12 -0700131#define X(x) if (pass_name == OptimizationPassName((x))) return (x)
Aart Bik2ca10eb2017-11-15 15:17:53 -0800132
Aart Bik2e148682018-04-18 16:11:12 -0700133OptimizationPass OptimizationPassByName(const std::string& pass_name) {
Aart Bik2ca10eb2017-11-15 15:17:53 -0800134 X(OptimizationPass::kBoundsCheckElimination);
135 X(OptimizationPass::kCHAGuardOptimization);
136 X(OptimizationPass::kCodeSinking);
137 X(OptimizationPass::kConstantFolding);
138 X(OptimizationPass::kConstructorFenceRedundancyElimination);
139 X(OptimizationPass::kDeadCodeElimination);
140 X(OptimizationPass::kGlobalValueNumbering);
141 X(OptimizationPass::kInductionVarAnalysis);
142 X(OptimizationPass::kInliner);
143 X(OptimizationPass::kInstructionSimplifier);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800144 X(OptimizationPass::kInvariantCodeMotion);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800145 X(OptimizationPass::kLoadStoreElimination);
146 X(OptimizationPass::kLoopOptimization);
147 X(OptimizationPass::kScheduling);
148 X(OptimizationPass::kSelectGenerator);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800149 X(OptimizationPass::kSideEffectsAnalysis);
150#ifdef ART_ENABLE_CODEGEN_arm
151 X(OptimizationPass::kInstructionSimplifierArm);
Vladimir Markod3e9c622020-08-05 12:20:28 +0100152 X(OptimizationPass::kCriticalNativeAbiFixupArm);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800153#endif
154#ifdef ART_ENABLE_CODEGEN_arm64
155 X(OptimizationPass::kInstructionSimplifierArm64);
156#endif
Aart Bik2ca10eb2017-11-15 15:17:53 -0800157#ifdef ART_ENABLE_CODEGEN_x86
158 X(OptimizationPass::kPcRelativeFixupsX86);
159 X(OptimizationPass::kX86MemoryOperandGeneration);
160#endif
Aart Bik2e148682018-04-18 16:11:12 -0700161 LOG(FATAL) << "Cannot find optimization " << pass_name;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800162 UNREACHABLE();
163}
164
165#undef X
166
167ArenaVector<HOptimization*> ConstructOptimizations(
168 const OptimizationDef definitions[],
169 size_t length,
170 ArenaAllocator* allocator,
171 HGraph* graph,
172 OptimizingCompilerStats* stats,
173 CodeGenerator* codegen,
Vladimir Marko02ca05a2020-05-12 13:58:51 +0100174 const DexCompilationUnit& dex_compilation_unit) {
Aart Bik2ca10eb2017-11-15 15:17:53 -0800175 ArenaVector<HOptimization*> optimizations(allocator->Adapter());
176
177 // Some optimizations require SideEffectsAnalysis or HInductionVarAnalysis
178 // instances. This method uses the nearest instance preceeding it in the pass
179 // name list or fails fatally if no such analysis can be found.
180 SideEffectsAnalysis* most_recent_side_effects = nullptr;
181 HInductionVarAnalysis* most_recent_induction = nullptr;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800182
183 // Loop over the requested optimizations.
184 for (size_t i = 0; i < length; i++) {
Aart Bik2e148682018-04-18 16:11:12 -0700185 OptimizationPass pass = definitions[i].pass;
186 const char* alt_name = definitions[i].pass_name;
187 const char* pass_name = alt_name != nullptr
Aart Bik2ca10eb2017-11-15 15:17:53 -0800188 ? alt_name
189 : OptimizationPassName(pass);
190 HOptimization* opt = nullptr;
191
192 switch (pass) {
193 //
194 // Analysis passes (kept in most recent for subsequent passes).
195 //
196 case OptimizationPass::kSideEffectsAnalysis:
Aart Bik2e148682018-04-18 16:11:12 -0700197 opt = most_recent_side_effects = new (allocator) SideEffectsAnalysis(graph, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800198 break;
199 case OptimizationPass::kInductionVarAnalysis:
Santiago Aboy Solanes3633fe42023-01-12 16:10:05 +0000200 opt = most_recent_induction =
201 new (allocator) HInductionVarAnalysis(graph, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800202 break;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800203 //
204 // Passes that need prior analysis.
205 //
206 case OptimizationPass::kGlobalValueNumbering:
207 CHECK(most_recent_side_effects != nullptr);
Aart Bik2e148682018-04-18 16:11:12 -0700208 opt = new (allocator) GVNOptimization(graph, *most_recent_side_effects, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800209 break;
210 case OptimizationPass::kInvariantCodeMotion:
211 CHECK(most_recent_side_effects != nullptr);
Aart Bik2e148682018-04-18 16:11:12 -0700212 opt = new (allocator) LICM(graph, *most_recent_side_effects, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800213 break;
214 case OptimizationPass::kLoopOptimization:
215 CHECK(most_recent_induction != nullptr);
Aart Bik2e148682018-04-18 16:11:12 -0700216 opt = new (allocator) HLoopOptimization(
Artem Serovc8150b52019-07-31 18:28:00 +0100217 graph, *codegen, most_recent_induction, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800218 break;
219 case OptimizationPass::kBoundsCheckElimination:
220 CHECK(most_recent_side_effects != nullptr && most_recent_induction != nullptr);
221 opt = new (allocator) BoundsCheckElimination(
Aart Bik2e148682018-04-18 16:11:12 -0700222 graph, *most_recent_side_effects, most_recent_induction, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800223 break;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800224 //
225 // Regular passes.
226 //
227 case OptimizationPass::kConstantFolding:
Santiago Aboy Solanes8c3b58a2022-08-15 13:21:59 +0000228 opt = new (allocator) HConstantFolding(graph, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800229 break;
230 case OptimizationPass::kDeadCodeElimination:
Aart Bik2e148682018-04-18 16:11:12 -0700231 opt = new (allocator) HDeadCodeElimination(graph, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800232 break;
233 case OptimizationPass::kInliner: {
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800234 CodeItemDataAccessor accessor(*dex_compilation_unit.GetDexFile(),
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800235 dex_compilation_unit.GetCodeItem());
Aart Bik2ca10eb2017-11-15 15:17:53 -0800236 opt = new (allocator) HInliner(graph, // outer_graph
237 graph, // outermost_graph
238 codegen,
239 dex_compilation_unit, // outer_compilation_unit
240 dex_compilation_unit, // outermost_compilation_unit
Aart Bik2ca10eb2017-11-15 15:17:53 -0800241 stats,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800242 accessor.RegistersSize(),
Andreas Gampe3db70682018-12-26 15:12:03 -0800243 /* total_number_of_instructions= */ 0,
244 /* parent= */ nullptr,
245 /* depth= */ 0,
Santiago Aboy Solanes8efb1a62022-06-24 11:16:35 +0100246 /* try_catch_inlining_allowed= */ true,
Aart Bik2e148682018-04-18 16:11:12 -0700247 pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800248 break;
249 }
Aart Bik2ca10eb2017-11-15 15:17:53 -0800250 case OptimizationPass::kSelectGenerator:
Vladimir Marko02ca05a2020-05-12 13:58:51 +0100251 opt = new (allocator) HSelectGenerator(graph, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800252 break;
253 case OptimizationPass::kInstructionSimplifier:
Vladimir Markobb089b62018-06-28 17:30:16 +0100254 opt = new (allocator) InstructionSimplifier(graph, codegen, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800255 break;
Evgeny Astigeevich6587d912020-06-12 10:51:43 +0100256 case OptimizationPass::kAggressiveInstructionSimplifier:
257 opt = new (allocator) InstructionSimplifier(graph,
258 codegen,
259 stats,
260 pass_name,
261 /* use_all_optimizations_ = */ true);
262 break;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800263 case OptimizationPass::kCHAGuardOptimization:
Aart Bik2e148682018-04-18 16:11:12 -0700264 opt = new (allocator) CHAGuardOptimization(graph, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800265 break;
266 case OptimizationPass::kCodeSinking:
Aart Bik2e148682018-04-18 16:11:12 -0700267 opt = new (allocator) CodeSinking(graph, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800268 break;
269 case OptimizationPass::kConstructorFenceRedundancyElimination:
Aart Bik2e148682018-04-18 16:11:12 -0700270 opt = new (allocator) ConstructorFenceRedundancyElimination(graph, stats, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800271 break;
Vladimir Marko3224f382020-06-23 14:19:53 +0100272 case OptimizationPass::kLoadStoreElimination:
273 opt = new (allocator) LoadStoreElimination(graph, stats, pass_name);
274 break;
Santiago Aboy Solanesd4229602023-01-03 16:20:50 +0000275 case OptimizationPass::kWriteBarrierElimination:
276 opt = new (allocator) WriteBarrierElimination(graph, stats, pass_name);
277 break;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800278 case OptimizationPass::kScheduling:
279 opt = new (allocator) HInstructionScheduling(
Vladimir Markoa0431112018-06-25 09:32:54 +0100280 graph, codegen->GetCompilerOptions().GetInstructionSet(), codegen, pass_name);
Aart Bik2ca10eb2017-11-15 15:17:53 -0800281 break;
282 //
283 // Arch-specific passes.
284 //
285#ifdef ART_ENABLE_CODEGEN_arm
286 case OptimizationPass::kInstructionSimplifierArm:
287 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
288 opt = new (allocator) arm::InstructionSimplifierArm(graph, stats);
289 break;
Vladimir Markod3e9c622020-08-05 12:20:28 +0100290 case OptimizationPass::kCriticalNativeAbiFixupArm:
291 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
292 opt = new (allocator) arm::CriticalNativeAbiFixupArm(graph, stats);
293 break;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800294#endif
295#ifdef ART_ENABLE_CODEGEN_arm64
296 case OptimizationPass::kInstructionSimplifierArm64:
297 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
298 opt = new (allocator) arm64::InstructionSimplifierArm64(graph, stats);
299 break;
300#endif
Aart Bik2ca10eb2017-11-15 15:17:53 -0800301#ifdef ART_ENABLE_CODEGEN_x86
302 case OptimizationPass::kPcRelativeFixupsX86:
303 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
304 opt = new (allocator) x86::PcRelativeFixups(graph, codegen, stats);
305 break;
306 case OptimizationPass::kX86MemoryOperandGeneration:
307 DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
308 opt = new (allocator) x86::X86MemoryOperandGeneration(graph, codegen, stats);
309 break;
Shalini Salomi Bodapatidd121f62018-10-26 15:03:53 +0530310 case OptimizationPass::kInstructionSimplifierX86:
311 opt = new (allocator) x86::InstructionSimplifierX86(graph, codegen, stats);
312 break;
313#endif
314#ifdef ART_ENABLE_CODEGEN_x86_64
315 case OptimizationPass::kInstructionSimplifierX86_64:
316 opt = new (allocator) x86_64::InstructionSimplifierX86_64(graph, codegen, stats);
317 break;
Aart Bik2ca10eb2017-11-15 15:17:53 -0800318#endif
Aart Bik2e148682018-04-18 16:11:12 -0700319 case OptimizationPass::kNone:
320 LOG(FATAL) << "kNone does not represent an actual pass";
321 UNREACHABLE();
Aart Bik2ca10eb2017-11-15 15:17:53 -0800322 } // switch
323
324 // Add each next optimization to result vector.
325 CHECK(opt != nullptr);
David Srbecky346fd962020-07-27 16:51:00 +0100326 DCHECK_STREQ(pass_name, opt->GetPassName()); // Consistency check.
Aart Bik2ca10eb2017-11-15 15:17:53 -0800327 optimizations.push_back(opt);
328 }
329
330 return optimizations;
331}
332
Roland Levillain75be2832014-10-17 17:02:00 +0100333} // namespace art