[turbofan] Nodes are killed by resetting all their inputs to zero.

TEST=compiler-unittests,mjsunit/numops-fuzz
R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/540253003

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23725 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
bmeurer@chromium.org 2014-09-05 11:10:28 +00:00
parent ddf358ca6b
commit aed44ecee3
5 changed files with 23 additions and 17 deletions

View File

@ -20,7 +20,8 @@ namespace compiler {
namespace { namespace {
SimpleOperator OP0(0, Operator::kNoWrite, 0, 0, "op0"); SimpleOperator OP0(0, Operator::kNoWrite, 0, 1, "op0");
SimpleOperator OP1(1, Operator::kNoProperties, 1, 1, "op1");
struct MockReducer : public Reducer { struct MockReducer : public Reducer {
@ -73,6 +74,19 @@ class GraphReducerTest : public TestWithZone {
}; };
TEST_F(GraphReducerTest, NodeIsDeadAfterReplace) {
StrictMock<MockReducer> r;
Node* node0 = graph()->NewNode(&OP0);
Node* node1 = graph()->NewNode(&OP1, node0);
Node* node2 = graph()->NewNode(&OP1, node0);
EXPECT_CALL(r, Reduce(node1)).WillOnce(Return(Reducer::Replace(node2)));
ReduceNode(node1, &r);
EXPECT_FALSE(node0->IsDead());
EXPECT_TRUE(node1->IsDead());
EXPECT_FALSE(node2->IsDead());
}
TEST_F(GraphReducerTest, ReduceOnceForEveryReducer) { TEST_F(GraphReducerTest, ReduceOnceForEveryReducer) {
StrictMock<MockReducer> r1, r2; StrictMock<MockReducer> r1, r2;
Node* node0 = graph()->NewNode(&OP0); Node* node0 = graph()->NewNode(&OP0);
@ -95,17 +109,6 @@ TEST_F(GraphReducerTest, ReduceAgainAfterChanged) {
ReduceNode(node0, &r1, &r2, &r3); ReduceNode(node0, &r1, &r2, &r3);
} }
TEST_F(GraphReducerTest, OperatorIsNullAfterReplace) {
StrictMock<MockReducer> r;
Node* node0 = graph()->NewNode(&OP0);
Node* node1 = graph()->NewNode(&OP0);
EXPECT_CALL(r, Reduce(node0)).WillOnce(Return(Reducer::Replace(node1)));
ReduceNode(node0, &r);
EXPECT_EQ(NULL, node0->op());
EXPECT_EQ(&OP0, node1->op());
}
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8

View File

@ -14,7 +14,6 @@ void Node::Kill() {
DCHECK_NOT_NULL(op()); DCHECK_NOT_NULL(op());
RemoveAllInputs(); RemoveAllInputs();
DCHECK(uses().empty()); DCHECK(uses().empty());
set_op(NULL);
} }

View File

@ -53,6 +53,8 @@ class Node FINAL : public GenericNode<NodeData, Node> {
: GenericNode<NodeData, Node>(graph, input_count) {} : GenericNode<NodeData, Node>(graph, input_count) {}
void Initialize(const Operator* op) { set_op(op); } void Initialize(const Operator* op) { set_op(op); }
bool IsDead() const { return InputCount() > 0 && InputAt(0) == NULL; }
void Kill(); void Kill();
void CollectProjections(ZoneVector<Node*>* projections); void CollectProjections(ZoneVector<Node*>* projections);

View File

@ -15,6 +15,7 @@ namespace compiler {
namespace { namespace {
const SimpleOperator kOp0(0, Operator::kNoProperties, 0, 1, "op0"); const SimpleOperator kOp0(0, Operator::kNoProperties, 0, 1, "op0");
const SimpleOperator kOp1(1, Operator::kNoProperties, 1, 1, "op1");
} // namespace } // namespace
@ -44,11 +45,12 @@ TEST_F(ValueNumberingReducerTest, AllInputsAreChecked) {
} }
TEST_F(ValueNumberingReducerTest, KilledNodesAreNeverReturned) { TEST_F(ValueNumberingReducerTest, DeadNodesAreNeverReturned) {
Node* n1 = graph()->NewNode(&kOp0); Node* n0 = graph()->NewNode(&kOp0);
Node* n1 = graph()->NewNode(&kOp1, n0);
EXPECT_FALSE(Reduce(n1).Changed()); EXPECT_FALSE(Reduce(n1).Changed());
n1->Kill(); n1->Kill();
EXPECT_FALSE(Reduce(graph()->NewNode(&kOp0)).Changed()); EXPECT_FALSE(Reduce(graph()->NewNode(&kOp1, n0)).Changed());
} }

View File

@ -59,7 +59,7 @@ ValueNumberingReducer::~ValueNumberingReducer() {}
Reduction ValueNumberingReducer::Reduce(Node* node) { Reduction ValueNumberingReducer::Reduce(Node* node) {
Entry** head = &buckets_[HashCode(node) % arraysize(buckets_)]; Entry** head = &buckets_[HashCode(node) % arraysize(buckets_)];
for (Entry* entry = *head; entry; entry = entry->next()) { for (Entry* entry = *head; entry; entry = entry->next()) {
if (entry->node()->op() == NULL) continue; if (entry->node()->IsDead()) continue;
if (entry->node() == node) return NoChange(); if (entry->node() == node) return NoChange();
if (Equals(node, entry->node())) { if (Equals(node, entry->node())) {
return Replace(entry->node()); return Replace(entry->node());