diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/gvn.cc | 9 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 3 | ||||
-rw-r--r-- | compiler/optimizing/optimization.cc | 8 | ||||
-rw-r--r-- | compiler/optimizing/optimization.h | 1 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 3 |
5 files changed, 22 insertions, 2 deletions
diff --git a/compiler/optimizing/gvn.cc b/compiler/optimizing/gvn.cc index cd3b07065c..8a5a4742ba 100644 --- a/compiler/optimizing/gvn.cc +++ b/compiler/optimizing/gvn.cc @@ -359,7 +359,8 @@ class GlobalValueNumberer : public ValueObject { side_effects_(side_effects), sets_(graph->GetBlocks().size(), nullptr, allocator_.Adapter(kArenaAllocGvn)), visited_blocks_( - &allocator_, graph->GetBlocks().size(), /* expandable= */ false, kArenaAllocGvn) {} + &allocator_, graph->GetBlocks().size(), /* expandable= */ false, kArenaAllocGvn), + did_optimization_(false) {} bool Run(); @@ -403,6 +404,9 @@ class GlobalValueNumberer : public ValueObject { // visited/unvisited Boolean. ArenaBitVector visited_blocks_; + // True if GVN did at least one removal. + bool did_optimization_; + DISALLOW_COPY_AND_ASSIGN(GlobalValueNumberer); }; @@ -415,7 +419,7 @@ bool GlobalValueNumberer::Run() { for (HBasicBlock* block : graph_->GetReversePostOrder()) { VisitBasicBlock(block); } - return true; + return did_optimization_; } void GlobalValueNumberer::VisitBasicBlock(HBasicBlock* block) { @@ -508,6 +512,7 @@ void GlobalValueNumberer::VisitBasicBlock(HBasicBlock* block) { // Or current is used by a phi, and we don't do OrderInputs() on a phi anyway. current->ReplaceWith(existing); current->GetBlock()->RemoveInstruction(current); + did_optimization_ = true; } else { set->Kill(current->GetSideEffects()); set->Add(current); diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index abc5dae016..931050855c 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -709,6 +709,9 @@ bool InstructionSimplifierVisitor::TryReplaceWithRotateRegisterSubPattern(HBinar void InstructionSimplifierVisitor::VisitNullCheck(HNullCheck* null_check) { HInstruction* obj = null_check->InputAt(0); + // Note we don't do `CanEnsureNotNullAt` here. If we do that, we may get rid of a NullCheck but + // what we should do instead is coalesce them. This is what GVN does, and so InstructionSimplifier + // doesn't do this. if (!obj->CanBeNull()) { null_check->ReplaceWith(obj); null_check->GetBlock()->RemoveInstruction(null_check); diff --git a/compiler/optimizing/optimization.cc b/compiler/optimizing/optimization.cc index ef1f36ab08..bd8fbdf1d2 100644 --- a/compiler/optimizing/optimization.cc +++ b/compiler/optimizing/optimization.cc @@ -55,6 +55,7 @@ #include "licm.h" #include "load_store_elimination.h" #include "loop_optimization.h" +#include "reference_type_propagation.h" #include "scheduler.h" #include "select_generator.h" #include "sharpening.h" @@ -98,6 +99,8 @@ const char* OptimizationPassName(OptimizationPass pass) { return CodeSinking::kCodeSinkingPassName; case OptimizationPass::kConstructorFenceRedundancyElimination: return ConstructorFenceRedundancyElimination::kCFREPassName; + case OptimizationPass::kReferenceTypePropagation: + return ReferenceTypePropagation::kReferenceTypePropagationPassName; case OptimizationPass::kScheduling: return HInstructionScheduling::kInstructionSchedulingPassName; case OptimizationPass::kWriteBarrierElimination: @@ -154,6 +157,7 @@ OptimizationPass OptimizationPassByName(const std::string& pass_name) { X(OptimizationPass::kInvariantCodeMotion); X(OptimizationPass::kLoadStoreElimination); X(OptimizationPass::kLoopOptimization); + X(OptimizationPass::kReferenceTypePropagation); X(OptimizationPass::kScheduling); X(OptimizationPass::kSelectGenerator); X(OptimizationPass::kSideEffectsAnalysis); @@ -287,6 +291,10 @@ ArenaVector<HOptimization*> ConstructOptimizations( case OptimizationPass::kLoadStoreElimination: opt = new (allocator) LoadStoreElimination(graph, stats, pass_name); break; + case OptimizationPass::kReferenceTypePropagation: + opt = new (allocator) ReferenceTypePropagation( + graph, dex_compilation_unit.GetDexCache(), /* is_first_run= */ false, pass_name); + break; case OptimizationPass::kWriteBarrierElimination: opt = new (allocator) WriteBarrierElimination(graph, stats, pass_name); break; diff --git a/compiler/optimizing/optimization.h b/compiler/optimizing/optimization.h index 8bc9da49fc..abc4361b44 100644 --- a/compiler/optimizing/optimization.h +++ b/compiler/optimizing/optimization.h @@ -81,6 +81,7 @@ enum class OptimizationPass { kInvariantCodeMotion, kLoadStoreElimination, kLoopOptimization, + kReferenceTypePropagation, kScheduling, kSelectGenerator, kSideEffectsAnalysis, diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 89edbed54d..b15657355f 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -665,6 +665,9 @@ void OptimizingCompiler::RunOptimizations(HGraph* graph, OptDef(OptimizationPass::kSideEffectsAnalysis, "side_effects$before_gvn"), OptDef(OptimizationPass::kGlobalValueNumbering), + OptDef(OptimizationPass::kReferenceTypePropagation, + "reference_type_propagation$after_gvn", + OptimizationPass::kGlobalValueNumbering), // Simplification (TODO: only if GVN occurred). OptDef(OptimizationPass::kSelectGenerator), OptDef(OptimizationPass::kConstantFolding, |