From bbd733e4ef277eff19bf9a6601032da081e9b68f Mon Sep 17 00:00:00 2001 From: David Brazdil Date: Tue, 18 Aug 2015 17:48:17 +0100 Subject: ART: Enable basic optimizations for try/catch Generating code for try/catch methods requires having run at least the instruction simplifier to remove redundant suspend checks. This patch enables the first group of optimizations when try/catch is present. Enabled optimizations: 1) IntrinsicsRecognizer Does not modify the graph, only sets HInvoke::intrinsic_. 2) ConstantFolding Does not deal with throwing instructions. 3) InstructionSimplifier May remove a throwing instruction (e.g. LoadClass in VisitCheckCast), or may turn a throwing instruction into a non-throwing one (ArraySet). Their corresponding catch phi inputs are not removed but correctness is preserved. 4) ReferenceTypePropagation Does not modify the graph, only sets type properties. Typing of LoadException from catch handler information was added. 5) DeadCodeElimination Removing individual instructions is fine (same as 3). Removal of dead blocks was disabled for try/catch. Change-Id: I2722c3229eb8aaf326391e07f522dbf5186774b8 --- compiler/optimizing/optimizing_compiler.cc | 35 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'compiler/optimizing/optimizing_compiler.cc') diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 866e71705f..bd40c9f639 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -359,11 +359,6 @@ static bool IsInstructionSetSupported(InstructionSet instruction_set) { || instruction_set == kX86_64; } -static bool CanOptimize(const DexFile::CodeItem& code_item) { - // TODO: We currently cannot optimize methods with try/catch. - return code_item.tries_size_ == 0; -} - static void RunOptimizations(HOptimization* optimizations[], size_t length, PassObserver* pass_observer) { @@ -470,6 +465,13 @@ static void RunOptimizations(HGraph* graph, RunOptimizations(optimizations1, arraysize(optimizations1), pass_observer); + if (graph->HasTryCatch()) { + // TODO: Update the optimizations below to work correctly under try/catch + // semantics. The optimizations above suffice for running codegen + // in the meanwhile. + return; + } + MaybeRunInliner(graph, driver, stats, dex_compilation_unit, pass_observer, handles); HOptimization* optimizations2[] = { @@ -529,6 +531,10 @@ CompiledMethod* OptimizingCompiler::CompileOptimized(HGraph* graph, RunOptimizations(graph, compiler_driver, compilation_stats_.get(), dex_compilation_unit, pass_observer, &handles); + if (graph->HasTryCatch()) { + return nullptr; + } + AllocateRegisters(graph, codegen, pass_observer); CodeVectorAllocator allocator; @@ -717,7 +723,6 @@ CompiledMethod* OptimizingCompiler::TryCompile(const DexFile::CodeItem* code_ite } } - bool can_optimize = CanOptimize(*code_item); bool can_allocate_registers = RegisterAllocator::CanAllocateRegistersFor(*graph, instruction_set); // `run_optimizations_` is set explicitly (either through a compiler filter @@ -738,16 +743,12 @@ CompiledMethod* OptimizingCompiler::TryCompile(const DexFile::CodeItem* code_ite } } - if (can_optimize) { - return CompileOptimized(graph, - codegen.get(), - compiler_driver, - dex_compilation_unit, - &pass_observer); - } - } - - if (shouldOptimize && can_allocate_registers) { + return CompileOptimized(graph, + codegen.get(), + compiler_driver, + dex_compilation_unit, + &pass_observer); + } else if (shouldOptimize && can_allocate_registers) { LOG(FATAL) << "Could not allocate registers in optimizing compiler"; UNREACHABLE(); } else if (can_use_baseline) { @@ -755,8 +756,6 @@ CompiledMethod* OptimizingCompiler::TryCompile(const DexFile::CodeItem* code_ite if (!run_optimizations_) { MaybeRecordStat(MethodCompilationStat::kNotOptimizedDisabled); - } else if (!can_optimize) { - MaybeRecordStat(MethodCompilationStat::kNotOptimizedTryCatch); } else if (!can_allocate_registers) { MaybeRecordStat(MethodCompilationStat::kNotOptimizedRegisterAllocator); } -- cgit v1.2.3-59-g8ed1b