diff options
-rw-r--r-- | compiler/optimizing/cha_guard_optimization.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/constant_folding.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/prepare_for_register_allocation.cc | 76 | ||||
-rw-r--r-- | compiler/optimizing/prepare_for_register_allocation.h | 25 |
4 files changed, 61 insertions, 44 deletions
diff --git a/compiler/optimizing/cha_guard_optimization.cc b/compiler/optimizing/cha_guard_optimization.cc index 20a763cf6d..fb9d220a7b 100644 --- a/compiler/optimizing/cha_guard_optimization.cc +++ b/compiler/optimizing/cha_guard_optimization.cc @@ -30,7 +30,7 @@ namespace art HIDDEN { // As a consequence, we decided not to rely on other passes to remove them // (such as GVN or instruction simplifier). -class CHAGuardVisitor : HGraphVisitor { +class CHAGuardVisitor final : public HGraphVisitor { public: explicit CHAGuardVisitor(HGraph* graph) : HGraphVisitor(graph), diff --git a/compiler/optimizing/constant_folding.cc b/compiler/optimizing/constant_folding.cc index e31de9e1da..0ec60b5ead 100644 --- a/compiler/optimizing/constant_folding.cc +++ b/compiler/optimizing/constant_folding.cc @@ -72,7 +72,7 @@ class HConstantFoldingVisitor final : public HGraphDelegateVisitor { // This visitor tries to simplify operations with an absorbing input, // yielding a constant. For example `input * 0` is replaced by a // null constant. -class InstructionWithAbsorbingInputSimplifier : public HGraphVisitor { +class InstructionWithAbsorbingInputSimplifier final : public HGraphVisitor { public: explicit InstructionWithAbsorbingInputSimplifier(HGraph* graph) : HGraphVisitor(graph) {} diff --git a/compiler/optimizing/prepare_for_register_allocation.cc b/compiler/optimizing/prepare_for_register_allocation.cc index 7453e58d3b..1eb340a9b4 100644 --- a/compiler/optimizing/prepare_for_register_allocation.cc +++ b/compiler/optimizing/prepare_for_register_allocation.cc @@ -19,37 +19,69 @@ #include "dex/dex_file_types.h" #include "driver/compiler_options.h" #include "jni/jni_internal.h" +#include "nodes.h" #include "optimizing_compiler_stats.h" #include "well_known_classes.h" namespace art HIDDEN { -void PrepareForRegisterAllocation::Run() { +class PrepareForRegisterAllocationVisitor final : public HGraphDelegateVisitor { + public: + PrepareForRegisterAllocationVisitor(HGraph* graph, + const CompilerOptions& compiler_options, + OptimizingCompilerStats* stats) + : HGraphDelegateVisitor(graph, stats), + compiler_options_(compiler_options) {} + + private: + void VisitCheckCast(HCheckCast* check_cast) override; + void VisitInstanceOf(HInstanceOf* instance_of) override; + void VisitNullCheck(HNullCheck* check) override; + void VisitDivZeroCheck(HDivZeroCheck* check) override; + void VisitBoundsCheck(HBoundsCheck* check) override; + void VisitBoundType(HBoundType* bound_type) override; + void VisitArraySet(HArraySet* instruction) override; + void VisitClinitCheck(HClinitCheck* check) override; + void VisitCondition(HCondition* condition) override; + void VisitConstructorFence(HConstructorFence* constructor_fence) override; + void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) override; + void VisitDeoptimize(HDeoptimize* deoptimize) override; + void VisitTypeConversion(HTypeConversion* instruction) override; + + bool CanMoveClinitCheck(HInstruction* input, HInstruction* user) const; + bool CanEmitConditionAt(HCondition* condition, HInstruction* user) const; + + const CompilerOptions& compiler_options_; +}; + +bool PrepareForRegisterAllocation::Run() { + PrepareForRegisterAllocationVisitor visitor(graph_, compiler_options_, stats_); // Order does not matter. - for (HBasicBlock* block : GetGraph()->GetReversePostOrder()) { + for (HBasicBlock* block : graph_->GetReversePostOrder()) { // No need to visit the phis. for (HInstructionIteratorHandleChanges inst_it(block->GetInstructions()); !inst_it.Done(); inst_it.Advance()) { - inst_it.Current()->Accept(this); + inst_it.Current()->Accept(&visitor); } } + return true; } -void PrepareForRegisterAllocation::VisitCheckCast(HCheckCast* check_cast) { +void PrepareForRegisterAllocationVisitor::VisitCheckCast(HCheckCast* check_cast) { // Record only those bitstring type checks that make it to the codegen stage. if (check_cast->GetTypeCheckKind() == TypeCheckKind::kBitstringCheck) { MaybeRecordStat(stats_, MethodCompilationStat::kBitstringTypeCheck); } } -void PrepareForRegisterAllocation::VisitInstanceOf(HInstanceOf* instance_of) { +void PrepareForRegisterAllocationVisitor::VisitInstanceOf(HInstanceOf* instance_of) { // Record only those bitstring type checks that make it to the codegen stage. if (instance_of->GetTypeCheckKind() == TypeCheckKind::kBitstringCheck) { MaybeRecordStat(stats_, MethodCompilationStat::kBitstringTypeCheck); } } -void PrepareForRegisterAllocation::VisitNullCheck(HNullCheck* check) { +void PrepareForRegisterAllocationVisitor::VisitNullCheck(HNullCheck* check) { check->ReplaceWith(check->InputAt(0)); if (compiler_options_.GetImplicitNullChecks()) { HInstruction* next = check->GetNext(); @@ -66,11 +98,11 @@ void PrepareForRegisterAllocation::VisitNullCheck(HNullCheck* check) { } } -void PrepareForRegisterAllocation::VisitDivZeroCheck(HDivZeroCheck* check) { +void PrepareForRegisterAllocationVisitor::VisitDivZeroCheck(HDivZeroCheck* check) { check->ReplaceWith(check->InputAt(0)); } -void PrepareForRegisterAllocation::VisitDeoptimize(HDeoptimize* deoptimize) { +void PrepareForRegisterAllocationVisitor::VisitDeoptimize(HDeoptimize* deoptimize) { if (deoptimize->GuardsAnInput()) { // Replace the uses with the actual guarded instruction. deoptimize->ReplaceWith(deoptimize->GuardedInput()); @@ -78,7 +110,7 @@ void PrepareForRegisterAllocation::VisitDeoptimize(HDeoptimize* deoptimize) { } } -void PrepareForRegisterAllocation::VisitBoundsCheck(HBoundsCheck* check) { +void PrepareForRegisterAllocationVisitor::VisitBoundsCheck(HBoundsCheck* check) { check->ReplaceWith(check->InputAt(0)); if (check->IsStringCharAt()) { // Add a fake environment for String.charAt() inline info as we want the exception @@ -96,14 +128,14 @@ void PrepareForRegisterAllocation::VisitBoundsCheck(HBoundsCheck* check) { } } -void PrepareForRegisterAllocation::VisitBoundType(HBoundType* bound_type) { +void PrepareForRegisterAllocationVisitor::VisitBoundType(HBoundType* bound_type) { bound_type->ReplaceWith(bound_type->InputAt(0)); bound_type->GetBlock()->RemoveInstruction(bound_type); } -void PrepareForRegisterAllocation::VisitArraySet(HArraySet* instruction) { +void PrepareForRegisterAllocationVisitor::VisitArraySet(HArraySet* instruction) { HInstruction* value = instruction->GetValue(); - // PrepareForRegisterAllocation::VisitBoundType may have replaced a + // PrepareForRegisterAllocationVisitor::VisitBoundType may have replaced a // BoundType (as value input of this ArraySet) with a NullConstant. // If so, this ArraySet no longer needs a type check. if (value->IsNullConstant()) { @@ -114,7 +146,7 @@ void PrepareForRegisterAllocation::VisitArraySet(HArraySet* instruction) { } } -void PrepareForRegisterAllocation::VisitClinitCheck(HClinitCheck* check) { +void PrepareForRegisterAllocationVisitor::VisitClinitCheck(HClinitCheck* check) { // Try to find a static invoke or a new-instance from which this check originated. HInstruction* implicit_clinit = nullptr; for (const HUseListNode<HInstruction*>& use : check->GetUses()) { @@ -174,8 +206,8 @@ void PrepareForRegisterAllocation::VisitClinitCheck(HClinitCheck* check) { } } -bool PrepareForRegisterAllocation::CanEmitConditionAt(HCondition* condition, - HInstruction* user) const { +bool PrepareForRegisterAllocationVisitor::CanEmitConditionAt(HCondition* condition, + HInstruction* user) const { if (condition->GetNext() != user) { return false; } @@ -196,7 +228,7 @@ bool PrepareForRegisterAllocation::CanEmitConditionAt(HCondition* condition, return false; } -void PrepareForRegisterAllocation::VisitCondition(HCondition* condition) { +void PrepareForRegisterAllocationVisitor::VisitCondition(HCondition* condition) { if (condition->HasOnlyOneNonEnvironmentUse()) { HInstruction* user = condition->GetUses().front().GetUser(); if (CanEmitConditionAt(condition, user)) { @@ -205,7 +237,8 @@ void PrepareForRegisterAllocation::VisitCondition(HCondition* condition) { } } -void PrepareForRegisterAllocation::VisitConstructorFence(HConstructorFence* constructor_fence) { +void PrepareForRegisterAllocationVisitor::VisitConstructorFence( + HConstructorFence* constructor_fence) { // Trivially remove redundant HConstructorFence when it immediately follows an HNewInstance // to an uninitialized class. In this special case, the art_quick_alloc_object_resolved // will already have the 'dmb' which is strictly stronger than an HConstructorFence. @@ -245,7 +278,8 @@ void PrepareForRegisterAllocation::VisitConstructorFence(HConstructorFence* cons constructor_fence->RemoveAllInputs(); } -void PrepareForRegisterAllocation::VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) { +void PrepareForRegisterAllocationVisitor::VisitInvokeStaticOrDirect( + HInvokeStaticOrDirect* invoke) { if (invoke->IsStaticWithExplicitClinitCheck()) { HInstruction* last_input = invoke->GetInputs().back(); DCHECK(last_input->IsLoadClass()) @@ -261,8 +295,8 @@ void PrepareForRegisterAllocation::VisitInvokeStaticOrDirect(HInvokeStaticOrDire } } -bool PrepareForRegisterAllocation::CanMoveClinitCheck(HInstruction* input, - HInstruction* user) const { +bool PrepareForRegisterAllocationVisitor::CanMoveClinitCheck(HInstruction* input, + HInstruction* user) const { // Determine if input and user come from the same dex instruction, so that we can move // the clinit check responsibility from one to the other, i.e. from HClinitCheck (user) // to HLoadClass (input), or from HClinitCheck (input) to HInvokeStaticOrDirect (user), @@ -313,7 +347,7 @@ bool PrepareForRegisterAllocation::CanMoveClinitCheck(HInstruction* input, return true; } -void PrepareForRegisterAllocation::VisitTypeConversion(HTypeConversion* instruction) { +void PrepareForRegisterAllocationVisitor::VisitTypeConversion(HTypeConversion* instruction) { // For simplicity, our code generators don't handle implicit type conversion, so ensure // there are none before hitting codegen. if (instruction->IsImplicitConversion()) { diff --git a/compiler/optimizing/prepare_for_register_allocation.h b/compiler/optimizing/prepare_for_register_allocation.h index f53c8a1285..1c312a3e9c 100644 --- a/compiler/optimizing/prepare_for_register_allocation.h +++ b/compiler/optimizing/prepare_for_register_allocation.h @@ -18,7 +18,7 @@ #define ART_COMPILER_OPTIMIZING_PREPARE_FOR_REGISTER_ALLOCATION_H_ #include "base/macros.h" -#include "nodes.h" +#include "optimization.h" namespace art HIDDEN { @@ -30,37 +30,20 @@ class OptimizingCompilerStats; * For example it changes uses of null checks and bounds checks to the original * objects, to avoid creating a live range for these checks. */ -class PrepareForRegisterAllocation final : public HGraphDelegateVisitor { +class PrepareForRegisterAllocation final : public HOptimization { public: PrepareForRegisterAllocation(HGraph* graph, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats = nullptr) - : HGraphDelegateVisitor(graph, stats), + : HOptimization(graph, kPrepareForRegisterAllocationPassName, stats), compiler_options_(compiler_options) {} - void Run(); + bool Run() override; static constexpr const char* kPrepareForRegisterAllocationPassName = "prepare_for_register_allocation"; private: - void VisitCheckCast(HCheckCast* check_cast) override; - void VisitInstanceOf(HInstanceOf* instance_of) override; - void VisitNullCheck(HNullCheck* check) override; - void VisitDivZeroCheck(HDivZeroCheck* check) override; - void VisitBoundsCheck(HBoundsCheck* check) override; - void VisitBoundType(HBoundType* bound_type) override; - void VisitArraySet(HArraySet* instruction) override; - void VisitClinitCheck(HClinitCheck* check) override; - void VisitCondition(HCondition* condition) override; - void VisitConstructorFence(HConstructorFence* constructor_fence) override; - void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) override; - void VisitDeoptimize(HDeoptimize* deoptimize) override; - void VisitTypeConversion(HTypeConversion* instruction) override; - - bool CanMoveClinitCheck(HInstruction* input, HInstruction* user) const; - bool CanEmitConditionAt(HCondition* condition, HInstruction* user) const; - const CompilerOptions& compiler_options_; DISALLOW_COPY_AND_ASSIGN(PrepareForRegisterAllocation); |