[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:
parent
f42c9e93c8
commit
7ecf1a059b
2
BUILD.gn
2
BUILD.gn
@ -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",
|
||||
|
43
src/compiler/checkpoint-elimination.cc
Normal file
43
src/compiler/checkpoint-elimination.cc
Normal 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
|
27
src/compiler/checkpoint-elimination.h
Normal file
27
src/compiler/checkpoint-elimination.h
Normal 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_
|
@ -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();
|
||||
}
|
||||
|
@ -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',
|
||||
|
59
test/unittests/compiler/checkpoint-elimination-unittest.cc
Normal file
59
test/unittests/compiler/checkpoint-elimination-unittest.cc
Normal 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
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user