summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/optimizing/cha_guard_optimization.cc2
-rw-r--r--compiler/optimizing/constant_folding.cc2
-rw-r--r--compiler/optimizing/prepare_for_register_allocation.cc76
-rw-r--r--compiler/optimizing/prepare_for_register_allocation.h25
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);