summaryrefslogtreecommitdiff
path: root/compiler/optimizing/optimization.cc
diff options
context:
space:
mode:
authorAart Bik <ajcbik@google.com>2017-11-15 15:17:53 -0800
committerAart Bik <ajcbik@google.com>2017-11-20 10:38:26 -0800
commit2ca10eb3f47ef3c2535c137853f7a63d10bb908b (patch)
tree3684d1d5ef4791795b64620e97f952896c5a2011 /compiler/optimizing/optimization.cc
parent02f41015a0933f146b886c62bb5b02c322ddf882 (diff)
Refactored optimization passes setup.
Rationale: Refactors the way we set up optimization passes in the compiler into a more centralized approach. The refactoring also found some "holes" in the existing mechanism (missing string lookup in the debugging mechanism, or inablity to set alternative name for optimizations that may repeat). Bug: 64538565 Test: test-art-host test-art-target Change-Id: Ie5e0b70f67ac5acc706db91f64612dff0e561f83
Diffstat (limited to 'compiler/optimizing/optimization.cc')
-rw-r--r--compiler/optimizing/optimization.cc312
1 files changed, 312 insertions, 0 deletions
diff --git a/compiler/optimizing/optimization.cc b/compiler/optimizing/optimization.cc
index 1e68ca2802..7edb642c5b 100644
--- a/compiler/optimizing/optimization.cc
+++ b/compiler/optimizing/optimization.cc
@@ -16,5 +16,317 @@
#include "optimization.h"
+#ifdef ART_ENABLE_CODEGEN_arm
+#include "instruction_simplifier_arm.h"
+#endif
+#ifdef ART_ENABLE_CODEGEN_arm64
+#include "instruction_simplifier_arm64.h"
+#endif
+#ifdef ART_ENABLE_CODEGEN_mips
+#include "instruction_simplifier_mips.h"
+#include "pc_relative_fixups_mips.h"
+#endif
+#ifdef ART_ENABLE_CODEGEN_x86
+#include "pc_relative_fixups_x86.h"
+#endif
+#if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64)
+#include "x86_memory_gen.h"
+#endif
+
+#include "bounds_check_elimination.h"
+#include "cha_guard_optimization.h"
+#include "code_sinking.h"
+#include "constant_folding.h"
+#include "constructor_fence_redundancy_elimination.h"
+#include "dead_code_elimination.h"
+#include "driver/dex_compilation_unit.h"
+#include "gvn.h"
+#include "induction_var_analysis.h"
+#include "inliner.h"
+#include "instruction_simplifier.h"
+#include "intrinsics.h"
+#include "licm.h"
+#include "load_store_analysis.h"
+#include "load_store_elimination.h"
+#include "loop_optimization.h"
+#include "scheduler.h"
+#include "select_generator.h"
+#include "sharpening.h"
+#include "side_effects_analysis.h"
+
+// Decide between default or alternative pass name.
+
namespace art {
+
+const char* OptimizationPassName(OptimizationPass pass) {
+ switch (pass) {
+ case OptimizationPass::kSideEffectsAnalysis:
+ return SideEffectsAnalysis::kSideEffectsAnalysisPassName;
+ case OptimizationPass::kInductionVarAnalysis:
+ return HInductionVarAnalysis::kInductionPassName;
+ case OptimizationPass::kLoadStoreAnalysis:
+ return LoadStoreAnalysis::kLoadStoreAnalysisPassName;
+ case OptimizationPass::kGlobalValueNumbering:
+ return GVNOptimization::kGlobalValueNumberingPassName;
+ case OptimizationPass::kInvariantCodeMotion:
+ return LICM::kLoopInvariantCodeMotionPassName;
+ case OptimizationPass::kLoopOptimization:
+ return HLoopOptimization::kLoopOptimizationPassName;
+ case OptimizationPass::kBoundsCheckElimination:
+ return BoundsCheckElimination::kBoundsCheckEliminationPassName;
+ case OptimizationPass::kLoadStoreElimination:
+ return LoadStoreElimination::kLoadStoreEliminationPassName;
+ case OptimizationPass::kConstantFolding:
+ return HConstantFolding::kConstantFoldingPassName;
+ case OptimizationPass::kDeadCodeElimination:
+ return HDeadCodeElimination::kDeadCodeEliminationPassName;
+ case OptimizationPass::kInliner:
+ return HInliner::kInlinerPassName;
+ case OptimizationPass::kSharpening:
+ return HSharpening::kSharpeningPassName;
+ case OptimizationPass::kSelectGenerator:
+ return HSelectGenerator::kSelectGeneratorPassName;
+ case OptimizationPass::kInstructionSimplifier:
+ return InstructionSimplifier::kInstructionSimplifierPassName;
+ case OptimizationPass::kIntrinsicsRecognizer:
+ return IntrinsicsRecognizer::kIntrinsicsRecognizerPassName;
+ case OptimizationPass::kCHAGuardOptimization:
+ return CHAGuardOptimization::kCHAGuardOptimizationPassName;
+ case OptimizationPass::kCodeSinking:
+ return CodeSinking::kCodeSinkingPassName;
+ case OptimizationPass::kConstructorFenceRedundancyElimination:
+ return ConstructorFenceRedundancyElimination::kCFREPassName;
+ case OptimizationPass::kScheduling:
+ return HInstructionScheduling::kInstructionSchedulingPassName;
+#ifdef ART_ENABLE_CODEGEN_arm
+ case OptimizationPass::kInstructionSimplifierArm:
+ return arm::InstructionSimplifierArm::kInstructionSimplifierArmPassName;
+#endif
+#ifdef ART_ENABLE_CODEGEN_arm64
+ case OptimizationPass::kInstructionSimplifierArm64:
+ return arm64::InstructionSimplifierArm64::kInstructionSimplifierArm64PassName;
+#endif
+#ifdef ART_ENABLE_CODEGEN_mips
+ case OptimizationPass::kPcRelativeFixupsMips:
+ return mips::PcRelativeFixups::kPcRelativeFixupsMipsPassName;
+ case OptimizationPass::kInstructionSimplifierMips:
+ return mips::InstructionSimplifierMips::kInstructionSimplifierMipsPassName;
+#endif
+#ifdef ART_ENABLE_CODEGEN_x86
+ case OptimizationPass::kPcRelativeFixupsX86:
+ return x86::PcRelativeFixups::kPcRelativeFixupsX86PassName;
+#endif
+#if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64)
+ case OptimizationPass::kX86MemoryOperandGeneration:
+ return x86::X86MemoryOperandGeneration::kX86MemoryOperandGenerationPassName;
+#endif
+ }
+}
+
+#define X(x) if (name == OptimizationPassName((x))) return (x)
+
+OptimizationPass OptimizationPassByName(const std::string& name) {
+ X(OptimizationPass::kBoundsCheckElimination);
+ X(OptimizationPass::kCHAGuardOptimization);
+ X(OptimizationPass::kCodeSinking);
+ X(OptimizationPass::kConstantFolding);
+ X(OptimizationPass::kConstructorFenceRedundancyElimination);
+ X(OptimizationPass::kDeadCodeElimination);
+ X(OptimizationPass::kGlobalValueNumbering);
+ X(OptimizationPass::kInductionVarAnalysis);
+ X(OptimizationPass::kInliner);
+ X(OptimizationPass::kInstructionSimplifier);
+ X(OptimizationPass::kIntrinsicsRecognizer);
+ X(OptimizationPass::kInvariantCodeMotion);
+ X(OptimizationPass::kLoadStoreAnalysis);
+ X(OptimizationPass::kLoadStoreElimination);
+ X(OptimizationPass::kLoopOptimization);
+ X(OptimizationPass::kScheduling);
+ X(OptimizationPass::kSelectGenerator);
+ X(OptimizationPass::kSharpening);
+ X(OptimizationPass::kSideEffectsAnalysis);
+#ifdef ART_ENABLE_CODEGEN_arm
+ X(OptimizationPass::kInstructionSimplifierArm);
+#endif
+#ifdef ART_ENABLE_CODEGEN_arm64
+ X(OptimizationPass::kInstructionSimplifierArm64);
+#endif
+#ifdef ART_ENABLE_CODEGEN_mips
+ X(OptimizationPass::kPcRelativeFixupsMips);
+ X(OptimizationPass::kInstructionSimplifierMips);
+#endif
+#ifdef ART_ENABLE_CODEGEN_x86
+ X(OptimizationPass::kPcRelativeFixupsX86);
+ X(OptimizationPass::kX86MemoryOperandGeneration);
+#endif
+ LOG(FATAL) << "Cannot find optimization " << name;
+ UNREACHABLE();
+}
+
+#undef X
+
+ArenaVector<HOptimization*> ConstructOptimizations(
+ const OptimizationDef definitions[],
+ size_t length,
+ ArenaAllocator* allocator,
+ HGraph* graph,
+ OptimizingCompilerStats* stats,
+ CodeGenerator* codegen,
+ CompilerDriver* driver,
+ const DexCompilationUnit& dex_compilation_unit,
+ VariableSizedHandleScope* handles) {
+ ArenaVector<HOptimization*> optimizations(allocator->Adapter());
+
+ // Some optimizations require SideEffectsAnalysis or HInductionVarAnalysis
+ // instances. This method uses the nearest instance preceeding it in the pass
+ // name list or fails fatally if no such analysis can be found.
+ SideEffectsAnalysis* most_recent_side_effects = nullptr;
+ HInductionVarAnalysis* most_recent_induction = nullptr;
+ LoadStoreAnalysis* most_recent_lsa = nullptr;
+
+ // Loop over the requested optimizations.
+ for (size_t i = 0; i < length; i++) {
+ OptimizationPass pass = definitions[i].first;
+ const char* alt_name = definitions[i].second;
+ const char* name = alt_name != nullptr
+ ? alt_name
+ : OptimizationPassName(pass);
+ HOptimization* opt = nullptr;
+
+ switch (pass) {
+ //
+ // Analysis passes (kept in most recent for subsequent passes).
+ //
+ case OptimizationPass::kSideEffectsAnalysis:
+ opt = most_recent_side_effects = new (allocator) SideEffectsAnalysis(graph, name);
+ break;
+ case OptimizationPass::kInductionVarAnalysis:
+ opt = most_recent_induction = new (allocator) HInductionVarAnalysis(graph, name);
+ break;
+ case OptimizationPass::kLoadStoreAnalysis:
+ opt = most_recent_lsa = new (allocator) LoadStoreAnalysis(graph, name);
+ break;
+ //
+ // Passes that need prior analysis.
+ //
+ case OptimizationPass::kGlobalValueNumbering:
+ CHECK(most_recent_side_effects != nullptr);
+ opt = new (allocator) GVNOptimization(graph, *most_recent_side_effects, name);
+ break;
+ case OptimizationPass::kInvariantCodeMotion:
+ CHECK(most_recent_side_effects != nullptr);
+ opt = new (allocator) LICM(graph, *most_recent_side_effects, stats, name);
+ break;
+ case OptimizationPass::kLoopOptimization:
+ CHECK(most_recent_induction != nullptr);
+ opt = new (allocator) HLoopOptimization(graph, driver, most_recent_induction, stats, name);
+ break;
+ case OptimizationPass::kBoundsCheckElimination:
+ CHECK(most_recent_side_effects != nullptr && most_recent_induction != nullptr);
+ opt = new (allocator) BoundsCheckElimination(
+ graph, *most_recent_side_effects, most_recent_induction, name);
+ break;
+ case OptimizationPass::kLoadStoreElimination:
+ CHECK(most_recent_side_effects != nullptr && most_recent_induction != nullptr);
+ opt = new (allocator) LoadStoreElimination(
+ graph, *most_recent_side_effects, *most_recent_lsa, stats, name);
+ break;
+ //
+ // Regular passes.
+ //
+ case OptimizationPass::kConstantFolding:
+ opt = new (allocator) HConstantFolding(graph, name);
+ break;
+ case OptimizationPass::kDeadCodeElimination:
+ opt = new (allocator) HDeadCodeElimination(graph, stats, name);
+ break;
+ case OptimizationPass::kInliner: {
+ size_t number_of_dex_registers = dex_compilation_unit.GetCodeItem()->registers_size_;
+ opt = new (allocator) HInliner(graph, // outer_graph
+ graph, // outermost_graph
+ codegen,
+ dex_compilation_unit, // outer_compilation_unit
+ dex_compilation_unit, // outermost_compilation_unit
+ driver,
+ handles,
+ stats,
+ number_of_dex_registers,
+ /* total_number_of_instructions */ 0,
+ /* parent */ nullptr,
+ /* depth */ 0,
+ name);
+ break;
+ }
+ case OptimizationPass::kSharpening:
+ opt = new (allocator) HSharpening(
+ graph, codegen, dex_compilation_unit, driver, handles, name);
+ break;
+ case OptimizationPass::kSelectGenerator:
+ opt = new (allocator) HSelectGenerator(graph, handles, stats, name);
+ break;
+ case OptimizationPass::kInstructionSimplifier:
+ opt = new (allocator) InstructionSimplifier(graph, codegen, driver, stats, name);
+ break;
+ case OptimizationPass::kIntrinsicsRecognizer:
+ opt = new (allocator) IntrinsicsRecognizer(graph, stats, name);
+ break;
+ case OptimizationPass::kCHAGuardOptimization:
+ opt = new (allocator) CHAGuardOptimization(graph, name);
+ break;
+ case OptimizationPass::kCodeSinking:
+ opt = new (allocator) CodeSinking(graph, stats, name);
+ break;
+ case OptimizationPass::kConstructorFenceRedundancyElimination:
+ opt = new (allocator) ConstructorFenceRedundancyElimination(graph, stats, name);
+ break;
+ case OptimizationPass::kScheduling:
+ opt = new (allocator) HInstructionScheduling(
+ graph, driver->GetInstructionSet(), codegen, name);
+ break;
+ //
+ // Arch-specific passes.
+ //
+#ifdef ART_ENABLE_CODEGEN_arm
+ case OptimizationPass::kInstructionSimplifierArm:
+ DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
+ opt = new (allocator) arm::InstructionSimplifierArm(graph, stats);
+ break;
+#endif
+#ifdef ART_ENABLE_CODEGEN_arm64
+ case OptimizationPass::kInstructionSimplifierArm64:
+ DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
+ opt = new (allocator) arm64::InstructionSimplifierArm64(graph, stats);
+ break;
+#endif
+#ifdef ART_ENABLE_CODEGEN_mips
+ case OptimizationPass::kPcRelativeFixupsMips:
+ DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
+ opt = new (allocator) mips::PcRelativeFixups(graph, codegen, stats);
+ break;
+ case OptimizationPass::kInstructionSimplifierMips:
+ DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
+ opt = new (allocator) mips::InstructionSimplifierMips(graph, codegen, stats);
+ break;
+#endif
+#ifdef ART_ENABLE_CODEGEN_x86
+ case OptimizationPass::kPcRelativeFixupsX86:
+ DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
+ opt = new (allocator) x86::PcRelativeFixups(graph, codegen, stats);
+ break;
+ case OptimizationPass::kX86MemoryOperandGeneration:
+ DCHECK(alt_name == nullptr) << "arch-specific pass does not support alternative name";
+ opt = new (allocator) x86::X86MemoryOperandGeneration(graph, codegen, stats);
+ break;
+#endif
+ } // switch
+
+ // Add each next optimization to result vector.
+ CHECK(opt != nullptr);
+ DCHECK_STREQ(name, opt->GetPassName()); // sanity
+ optimizations.push_back(opt);
+ }
+
+ return optimizations;
+}
+
} // namespace art