[turbofan] Implement simplistic checkpoint reducer.

This adds a very simplistic reduction of {CheckPoint} nodes via the new
{CheckpointElimination}, eliminating redundant check points that appear
in an effect chain of operations that are all {kNoWrite}. Such a chain
allows an arbitrary check point to be chosen. The current approach will
end up choosing the first one for all deopts in the chain.

R=bmeurer@chromium.org
TEST=unittests/CheckpointEliminationTest.CheckPointChain
BUG=v8:5021

Review-Url: https://codereview.chromium.org/2022913003
Cr-Commit-Position: refs/heads/master@{#36634}
This commit is contained in:
mstarzinger 2016-06-01 01:38:32 -07:00 committed by Commit bot
parent f42c9e93c8
commit 7ecf1a059b
7 changed files with 137 additions and 0 deletions

View File

@ -840,6 +840,8 @@ v8_source_set("v8_base") {
"src/compiler/bytecode-graph-builder.cc",
"src/compiler/bytecode-graph-builder.h",
"src/compiler/c-linkage.cc",
"src/compiler/checkpoint-elimination.cc",
"src/compiler/checkpoint-elimination.h",
"src/compiler/coalesced-live-ranges.cc",
"src/compiler/coalesced-live-ranges.h",
"src/compiler/code-assembler.cc",

View File

@ -0,0 +1,43 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/checkpoint-elimination.h"
#include "src/compiler/node-properties.h"
namespace v8 {
namespace internal {
namespace compiler {
CheckpointElimination::CheckpointElimination(Editor* editor)
: AdvancedReducer(editor) {}
namespace {
// The given checkpoint is redundant if it is effect-wise dominated by another
// checkpoint and there is no observable write in between. For now we consider
// a linear effect chain only instead of true effect-wise dominance.
bool IsRedundantCheckPoint(Node* node) {
Node* effect = NodeProperties::GetEffectInput(node);
while (effect->op()->HasProperty(Operator::kNoWrite) &&
effect->op()->EffectInputCount() == 1) {
if (effect->opcode() == IrOpcode::kCheckPoint) return true;
effect = NodeProperties::GetEffectInput(effect);
}
return false;
}
} // namespace
Reduction CheckpointElimination::Reduce(Node* node) {
if (node->opcode() != IrOpcode::kCheckPoint) return NoChange();
if (IsRedundantCheckPoint(node)) {
return Replace(NodeProperties::GetEffectInput(node));
}
return NoChange();
}
} // namespace compiler
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,27 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_COMPILER_CHECKPOINT_ELIMINATION_H_
#define V8_COMPILER_CHECKPOINT_ELIMINATION_H_
#include "src/compiler/graph-reducer.h"
namespace v8 {
namespace internal {
namespace compiler {
// Performs elimination of redundant checkpoints within the graph.
class CheckpointElimination final : public AdvancedReducer {
public:
explicit CheckpointElimination(Editor* editor);
~CheckpointElimination() final {}
Reduction Reduce(Node* node) final;
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_CHECKPOINT_ELIMINATION_H_

View File

@ -14,6 +14,7 @@
#include "src/compiler/basic-block-instrumentor.h"
#include "src/compiler/branch-elimination.h"
#include "src/compiler/bytecode-graph-builder.h"
#include "src/compiler/checkpoint-elimination.h"
#include "src/compiler/code-generator.h"
#include "src/compiler/common-operator-reducer.h"
#include "src/compiler/control-flow-optimizer.h"
@ -891,6 +892,7 @@ struct TypedLoweringPhase {
? JSIntrinsicLowering::kDeoptimizationEnabled
: JSIntrinsicLowering::kDeoptimizationDisabled);
SimplifiedOperatorReducer simple_reducer(data->jsgraph());
CheckpointElimination checkpoint_elimination(&graph_reducer);
CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
data->common(), data->machine());
AddReducer(data, &graph_reducer, &dead_code_elimination);
@ -902,6 +904,7 @@ struct TypedLoweringPhase {
AddReducer(data, &graph_reducer, &intrinsic_lowering);
AddReducer(data, &graph_reducer, &load_elimination);
AddReducer(data, &graph_reducer, &simple_reducer);
AddReducer(data, &graph_reducer, &checkpoint_elimination);
AddReducer(data, &graph_reducer, &common_reducer);
graph_reducer.ReduceGraph();
}

View File

@ -505,6 +505,8 @@
'compiler/bytecode-graph-builder.cc',
'compiler/bytecode-graph-builder.h',
'compiler/c-linkage.cc',
'compiler/checkpoint-elimination.cc',
'compiler/checkpoint-elimination.h',
'compiler/coalesced-live-ranges.cc',
'compiler/coalesced-live-ranges.h',
'compiler/code-generator-impl.h',

View File

@ -0,0 +1,59 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/checkpoint-elimination.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/operator.h"
#include "test/unittests/compiler/graph-reducer-unittest.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"
using testing::StrictMock;
namespace v8 {
namespace internal {
namespace compiler {
class CheckpointEliminationTest : public GraphTest {
public:
CheckpointEliminationTest() : GraphTest() {}
~CheckpointEliminationTest() override {}
protected:
Reduction Reduce(AdvancedReducer::Editor* editor, Node* node) {
CheckpointElimination reducer(editor);
return reducer.Reduce(node);
}
Reduction Reduce(Node* node) {
StrictMock<MockAdvancedReducerEditor> editor;
return Reduce(&editor, node);
}
};
namespace {
const Operator kOpNoWrite(0, Operator::kNoWrite, "OpNoWrite", 0, 1, 0, 0, 1, 0);
} // namespace
// -----------------------------------------------------------------------------
// CheckPoint
TEST_F(CheckpointEliminationTest, CheckPointChain) {
Node* const control = graph()->start();
Node* frame_state = EmptyFrameState();
Node* checkpoint1 = graph()->NewNode(common()->CheckPoint(), frame_state,
graph()->start(), control);
Node* effect_link = graph()->NewNode(&kOpNoWrite, checkpoint1);
Node* checkpoint2 = graph()->NewNode(common()->CheckPoint(), frame_state,
effect_link, control);
Reduction r = Reduce(checkpoint2);
ASSERT_TRUE(r.Changed());
EXPECT_EQ(effect_link, r.replacement());
}
} // namespace compiler
} // namespace internal
} // namespace v8

View File

@ -41,6 +41,7 @@
'cancelable-tasks-unittest.cc',
'char-predicates-unittest.cc',
'compiler/branch-elimination-unittest.cc',
'compiler/checkpoint-elimination-unittest.cc',
'compiler/coalesced-live-ranges-unittest.cc',
'compiler/common-operator-reducer-unittest.cc',
'compiler/common-operator-unittest.cc',