diff options
Diffstat (limited to 'deps/v8/test/cctest/compiler/test-node.cc')
-rw-r--r-- | deps/v8/test/cctest/compiler/test-node.cc | 815 |
1 files changed, 815 insertions, 0 deletions
diff --git a/deps/v8/test/cctest/compiler/test-node.cc b/deps/v8/test/cctest/compiler/test-node.cc new file mode 100644 index 000000000..6fe8573a2 --- /dev/null +++ b/deps/v8/test/cctest/compiler/test-node.cc @@ -0,0 +1,815 @@ +// Copyright 2013 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 <functional> + +#include "src/v8.h" + +#include "graph-tester.h" +#include "src/compiler/generic-node-inl.h" +#include "src/compiler/node.h" +#include "src/compiler/operator.h" + +using namespace v8::internal; +using namespace v8::internal::compiler; + +static SimpleOperator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite, + 0, 0, "dummy"); + +TEST(NodeAllocation) { + GraphTester graph; + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator); + CHECK(n2->id() != n1->id()); +} + + +TEST(NodeWithOpcode) { + GraphTester graph; + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator); + CHECK(n1->op() == &dummy_operator); + CHECK(n2->op() == &dummy_operator); +} + + +TEST(NodeInputs1) { + GraphTester graph; + Node* n0 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0); + CHECK_EQ(1, n2->InputCount()); + CHECK(n0 == n2->InputAt(0)); +} + + +TEST(NodeInputs2) { + GraphTester graph; + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0, n1); + CHECK_EQ(2, n2->InputCount()); + CHECK(n0 == n2->InputAt(0)); + CHECK(n1 == n2->InputAt(1)); +} + + +TEST(NodeInputs3) { + GraphTester graph; + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0, n1, n1); + CHECK_EQ(3, n2->InputCount()); + CHECK(n0 == n2->InputAt(0)); + CHECK(n1 == n2->InputAt(1)); + CHECK(n1 == n2->InputAt(2)); +} + + +TEST(NodeInputIteratorEmpty) { + GraphTester graph; + Node* n1 = graph.NewNode(&dummy_operator); + Node::Inputs::iterator i(n1->inputs().begin()); + int input_count = 0; + for (; i != n1->inputs().end(); ++i) { + input_count++; + } + CHECK_EQ(0, input_count); +} + + +TEST(NodeInputIteratorOne) { + GraphTester graph; + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + Node::Inputs::iterator i(n1->inputs().begin()); + CHECK_EQ(1, n1->InputCount()); + CHECK_EQ(n0, *i); + ++i; + CHECK(n1->inputs().end() == i); +} + + +TEST(NodeUseIteratorEmpty) { + GraphTester graph; + Node* n1 = graph.NewNode(&dummy_operator); + Node::Uses::iterator i(n1->uses().begin()); + int use_count = 0; + for (; i != n1->uses().end(); ++i) { + Node::Edge edge(i.edge()); + USE(edge); + use_count++; + } + CHECK_EQ(0, use_count); +} + + +TEST(NodeUseIteratorOne) { + GraphTester graph; + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + Node::Uses::iterator i(n0->uses().begin()); + CHECK_EQ(n1, *i); + ++i; + CHECK(n0->uses().end() == i); +} + + +TEST(NodeUseIteratorReplaceNoUses) { + GraphTester graph; + Node* n0 = graph.NewNode(&dummy_operator); + Node* n3 = graph.NewNode(&dummy_operator); + n0->ReplaceUses(n3); + CHECK(n0->uses().begin() == n0->uses().end()); +} + + +TEST(NodeUseIteratorReplaceUses) { + GraphTester graph; + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + Node* n2 = graph.NewNode(&dummy_operator, n0); + Node* n3 = graph.NewNode(&dummy_operator); + Node::Uses::iterator i1(n0->uses().begin()); + CHECK_EQ(n1, *i1); + ++i1; + CHECK_EQ(n2, *i1); + n0->ReplaceUses(n3); + Node::Uses::iterator i2(n3->uses().begin()); + CHECK_EQ(n1, *i2); + ++i2; + CHECK_EQ(n2, *i2); + Node::Inputs::iterator i3(n1->inputs().begin()); + CHECK_EQ(n3, *i3); + ++i3; + CHECK(n1->inputs().end() == i3); + Node::Inputs::iterator i4(n2->inputs().begin()); + CHECK_EQ(n3, *i4); + ++i4; + CHECK(n2->inputs().end() == i4); +} + + +TEST(NodeUseIteratorReplaceUsesSelf) { + GraphTester graph; + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + Node* n3 = graph.NewNode(&dummy_operator); + + n1->ReplaceInput(0, n1); // Create self-reference. + + Node::Uses::iterator i1(n1->uses().begin()); + CHECK_EQ(n1, *i1); + + n1->ReplaceUses(n3); + + CHECK(n1->uses().begin() == n1->uses().end()); + + Node::Uses::iterator i2(n3->uses().begin()); + CHECK_EQ(n1, *i2); + ++i2; + CHECK(n1->uses().end() == i2); +} + + +TEST(ReplaceInput) { + GraphTester graph; + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator); + Node* n3 = graph.NewNode(&dummy_operator, n0, n1, n2); + Node::Inputs::iterator i1(n3->inputs().begin()); + CHECK(n0 == *i1); + CHECK_EQ(n0, n3->InputAt(0)); + ++i1; + CHECK_EQ(n1, *i1); + CHECK_EQ(n1, n3->InputAt(1)); + ++i1; + CHECK_EQ(n2, *i1); + CHECK_EQ(n2, n3->InputAt(2)); + ++i1; + CHECK(i1 == n3->inputs().end()); + + Node::Uses::iterator i2(n1->uses().begin()); + CHECK_EQ(n3, *i2); + ++i2; + CHECK(i2 == n1->uses().end()); + + Node* n4 = graph.NewNode(&dummy_operator); + Node::Uses::iterator i3(n4->uses().begin()); + CHECK(i3 == n4->uses().end()); + + n3->ReplaceInput(1, n4); + + Node::Uses::iterator i4(n1->uses().begin()); + CHECK(i4 == n1->uses().end()); + + Node::Uses::iterator i5(n4->uses().begin()); + CHECK_EQ(n3, *i5); + ++i5; + CHECK(i5 == n4->uses().end()); + + Node::Inputs::iterator i6(n3->inputs().begin()); + CHECK(n0 == *i6); + CHECK_EQ(n0, n3->InputAt(0)); + ++i6; + CHECK_EQ(n4, *i6); + CHECK_EQ(n4, n3->InputAt(1)); + ++i6; + CHECK_EQ(n2, *i6); + CHECK_EQ(n2, n3->InputAt(2)); + ++i6; + CHECK(i6 == n3->inputs().end()); +} + + +TEST(OwnedBy) { + GraphTester graph; + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + + CHECK(!n0->OwnedBy(n1)); + CHECK(!n1->OwnedBy(n0)); + + Node* n2 = graph.NewNode(&dummy_operator, n0); + CHECK(n0->OwnedBy(n2)); + CHECK(!n2->OwnedBy(n0)); + + Node* n3 = graph.NewNode(&dummy_operator, n0); + CHECK(!n0->OwnedBy(n2)); + CHECK(!n0->OwnedBy(n3)); + CHECK(!n2->OwnedBy(n0)); + CHECK(!n3->OwnedBy(n0)); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + CHECK(n0->OwnedBy(n1)); + CHECK(!n1->OwnedBy(n0)); + Node* n2 = graph.NewNode(&dummy_operator, n0); + CHECK(!n0->OwnedBy(n1)); + CHECK(!n0->OwnedBy(n2)); + CHECK(!n1->OwnedBy(n0)); + CHECK(!n1->OwnedBy(n2)); + CHECK(!n2->OwnedBy(n0)); + CHECK(!n2->OwnedBy(n1)); + + Node* n3 = graph.NewNode(&dummy_operator); + n2->ReplaceInput(0, n3); + + CHECK(n0->OwnedBy(n1)); + CHECK(!n1->OwnedBy(n0)); + CHECK(!n1->OwnedBy(n0)); + CHECK(!n1->OwnedBy(n2)); + CHECK(!n2->OwnedBy(n0)); + CHECK(!n2->OwnedBy(n1)); + CHECK(n3->OwnedBy(n2)); + CHECK(!n2->OwnedBy(n3)); + } +} + + +TEST(Uses) { + GraphTester graph; + + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + CHECK_EQ(1, n0->UseCount()); + printf("A: %d vs %d\n", n0->UseAt(0)->id(), n1->id()); + CHECK(n0->UseAt(0) == n1); + Node* n2 = graph.NewNode(&dummy_operator, n0); + CHECK_EQ(2, n0->UseCount()); + printf("B: %d vs %d\n", n0->UseAt(1)->id(), n2->id()); + CHECK(n0->UseAt(1) == n2); + Node* n3 = graph.NewNode(&dummy_operator, n0); + CHECK_EQ(3, n0->UseCount()); + CHECK(n0->UseAt(2) == n3); +} + + +TEST(Inputs) { + GraphTester graph; + + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + Node* n2 = graph.NewNode(&dummy_operator, n0); + Node* n3 = graph.NewNode(&dummy_operator, n0, n1, n2); + CHECK_EQ(3, n3->InputCount()); + CHECK(n3->InputAt(0) == n0); + CHECK(n3->InputAt(1) == n1); + CHECK(n3->InputAt(2) == n2); + Node* n4 = graph.NewNode(&dummy_operator, n0, n1, n2); + n3->AppendInput(graph.zone(), n4); + CHECK_EQ(4, n3->InputCount()); + CHECK(n3->InputAt(0) == n0); + CHECK(n3->InputAt(1) == n1); + CHECK(n3->InputAt(2) == n2); + CHECK(n3->InputAt(3) == n4); + Node* n5 = graph.NewNode(&dummy_operator, n4); + n3->AppendInput(graph.zone(), n4); + CHECK_EQ(5, n3->InputCount()); + CHECK(n3->InputAt(0) == n0); + CHECK(n3->InputAt(1) == n1); + CHECK(n3->InputAt(2) == n2); + CHECK(n3->InputAt(3) == n4); + CHECK(n3->InputAt(4) == n4); + + // Make sure uses have been hooked op correctly. + Node::Uses uses(n4->uses()); + Node::Uses::iterator current = uses.begin(); + CHECK(current != uses.end()); + CHECK(*current == n3); + ++current; + CHECK(current != uses.end()); + CHECK(*current == n5); + ++current; + CHECK(current != uses.end()); + CHECK(*current == n3); + ++current; + CHECK(current == uses.end()); +} + + +TEST(AppendInputsAndIterator) { + GraphTester graph; + + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + Node* n2 = graph.NewNode(&dummy_operator, n0, n1); + + Node::Inputs inputs(n2->inputs()); + Node::Inputs::iterator current = inputs.begin(); + CHECK(current != inputs.end()); + CHECK(*current == n0); + ++current; + CHECK(current != inputs.end()); + CHECK(*current == n1); + ++current; + CHECK(current == inputs.end()); + + Node* n3 = graph.NewNode(&dummy_operator); + n2->AppendInput(graph.zone(), n3); + inputs = n2->inputs(); + current = inputs.begin(); + CHECK(current != inputs.end()); + CHECK(*current == n0); + CHECK_EQ(0, current.index()); + ++current; + CHECK(current != inputs.end()); + CHECK(*current == n1); + CHECK_EQ(1, current.index()); + ++current; + CHECK(current != inputs.end()); + CHECK(*current == n3); + CHECK_EQ(2, current.index()); + ++current; + CHECK(current == inputs.end()); +} + + +TEST(NullInputsSimple) { + GraphTester graph; + + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + Node* n2 = graph.NewNode(&dummy_operator, n0, n1); + CHECK_EQ(2, n2->InputCount()); + + CHECK(n0 == n2->InputAt(0)); + CHECK(n1 == n2->InputAt(1)); + CHECK_EQ(2, n0->UseCount()); + n2->ReplaceInput(0, NULL); + CHECK(NULL == n2->InputAt(0)); + CHECK(n1 == n2->InputAt(1)); + CHECK_EQ(1, n0->UseCount()); +} + + +TEST(NullInputsAppended) { + GraphTester graph; + + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + Node* n2 = graph.NewNode(&dummy_operator, n0); + Node* n3 = graph.NewNode(&dummy_operator, n0); + n3->AppendInput(graph.zone(), n1); + n3->AppendInput(graph.zone(), n2); + CHECK_EQ(3, n3->InputCount()); + + CHECK(n0 == n3->InputAt(0)); + CHECK(n1 == n3->InputAt(1)); + CHECK(n2 == n3->InputAt(2)); + CHECK_EQ(1, n1->UseCount()); + n3->ReplaceInput(1, NULL); + CHECK(n0 == n3->InputAt(0)); + CHECK(NULL == n3->InputAt(1)); + CHECK(n2 == n3->InputAt(2)); + CHECK_EQ(0, n1->UseCount()); +} + + +TEST(ReplaceUsesFromAppendedInputs) { + GraphTester graph; + + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + Node* n2 = graph.NewNode(&dummy_operator, n0); + Node* n3 = graph.NewNode(&dummy_operator); + n2->AppendInput(graph.zone(), n1); + n2->AppendInput(graph.zone(), n0); + CHECK_EQ(0, n3->UseCount()); + CHECK_EQ(3, n0->UseCount()); + n0->ReplaceUses(n3); + CHECK_EQ(0, n0->UseCount()); + CHECK_EQ(3, n3->UseCount()); + + Node::Uses uses(n3->uses()); + Node::Uses::iterator current = uses.begin(); + CHECK(current != uses.end()); + CHECK(*current == n1); + ++current; + CHECK(current != uses.end()); + CHECK(*current == n2); + ++current; + CHECK(current != uses.end()); + CHECK(*current == n2); + ++current; + CHECK(current == uses.end()); +} + + +template <bool result> +struct FixedPredicate { + bool operator()(const Node* node) const { return result; } +}; + + +TEST(ReplaceUsesIfWithFixedPredicate) { + GraphTester graph; + + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + Node* n2 = graph.NewNode(&dummy_operator, n0); + Node* n3 = graph.NewNode(&dummy_operator); + + CHECK_EQ(0, n2->UseCount()); + n2->ReplaceUsesIf(FixedPredicate<true>(), n1); + CHECK_EQ(0, n2->UseCount()); + n2->ReplaceUsesIf(FixedPredicate<false>(), n1); + CHECK_EQ(0, n2->UseCount()); + + CHECK_EQ(0, n3->UseCount()); + n3->ReplaceUsesIf(FixedPredicate<true>(), n1); + CHECK_EQ(0, n3->UseCount()); + n3->ReplaceUsesIf(FixedPredicate<false>(), n1); + CHECK_EQ(0, n3->UseCount()); + + CHECK_EQ(2, n0->UseCount()); + CHECK_EQ(0, n1->UseCount()); + n0->ReplaceUsesIf(FixedPredicate<false>(), n1); + CHECK_EQ(2, n0->UseCount()); + CHECK_EQ(0, n1->UseCount()); + n0->ReplaceUsesIf(FixedPredicate<true>(), n1); + CHECK_EQ(0, n0->UseCount()); + CHECK_EQ(2, n1->UseCount()); + + n1->AppendInput(graph.zone(), n1); + CHECK_EQ(3, n1->UseCount()); + n1->AppendInput(graph.zone(), n3); + CHECK_EQ(1, n3->UseCount()); + n3->ReplaceUsesIf(FixedPredicate<true>(), n1); + CHECK_EQ(4, n1->UseCount()); + CHECK_EQ(0, n3->UseCount()); + n1->ReplaceUsesIf(FixedPredicate<false>(), n3); + CHECK_EQ(4, n1->UseCount()); + CHECK_EQ(0, n3->UseCount()); +} + + +TEST(ReplaceUsesIfWithEqualTo) { + GraphTester graph; + + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + Node* n2 = graph.NewNode(&dummy_operator, n0, n1); + + CHECK_EQ(0, n2->UseCount()); + n2->ReplaceUsesIf(std::bind1st(std::equal_to<Node*>(), n1), n0); + CHECK_EQ(0, n2->UseCount()); + + CHECK_EQ(2, n0->UseCount()); + CHECK_EQ(1, n1->UseCount()); + n1->ReplaceUsesIf(std::bind1st(std::equal_to<Node*>(), n0), n0); + CHECK_EQ(2, n0->UseCount()); + CHECK_EQ(1, n1->UseCount()); + n0->ReplaceUsesIf(std::bind2nd(std::equal_to<Node*>(), n2), n1); + CHECK_EQ(1, n0->UseCount()); + CHECK_EQ(2, n1->UseCount()); +} + + +TEST(ReplaceInputMultipleUses) { + GraphTester graph; + + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0); + n2->ReplaceInput(0, n1); + CHECK_EQ(0, n0->UseCount()); + CHECK_EQ(1, n1->UseCount()); + + Node* n3 = graph.NewNode(&dummy_operator, n0); + n3->ReplaceInput(0, n1); + CHECK_EQ(0, n0->UseCount()); + CHECK_EQ(2, n1->UseCount()); +} + + +TEST(TrimInputCountInline) { + GraphTester graph; + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + n1->TrimInputCount(1); + CHECK_EQ(1, n1->InputCount()); + CHECK_EQ(n0, n1->InputAt(0)); + CHECK_EQ(1, n0->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + n1->TrimInputCount(0); + CHECK_EQ(0, n1->InputCount()); + CHECK_EQ(0, n0->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0, n1); + n2->TrimInputCount(2); + CHECK_EQ(2, n2->InputCount()); + CHECK_EQ(1, n0->UseCount()); + CHECK_EQ(1, n1->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0, n1); + n2->TrimInputCount(1); + CHECK_EQ(1, n2->InputCount()); + CHECK_EQ(1, n0->UseCount()); + CHECK_EQ(0, n1->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0, n1); + n2->TrimInputCount(0); + CHECK_EQ(0, n2->InputCount()); + CHECK_EQ(0, n0->UseCount()); + CHECK_EQ(0, n1->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0, n0); + n2->TrimInputCount(1); + CHECK_EQ(1, n2->InputCount()); + CHECK_EQ(1, n0->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0, n0); + n2->TrimInputCount(0); + CHECK_EQ(0, n2->InputCount()); + CHECK_EQ(0, n0->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } +} + + +TEST(TrimInputCountOutOfLine1) { + GraphTester graph; + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + n1->AppendInput(graph.zone(), n0); + n1->TrimInputCount(1); + CHECK_EQ(1, n1->InputCount()); + CHECK_EQ(n0, n1->InputAt(0)); + CHECK_EQ(1, n0->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + n1->AppendInput(graph.zone(), n0); + CHECK_EQ(1, n1->InputCount()); + n1->TrimInputCount(0); + CHECK_EQ(0, n1->InputCount()); + CHECK_EQ(0, n0->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator); + n2->AppendInput(graph.zone(), n0); + n2->AppendInput(graph.zone(), n1); + CHECK_EQ(2, n2->InputCount()); + n2->TrimInputCount(2); + CHECK_EQ(2, n2->InputCount()); + CHECK_EQ(n0, n2->InputAt(0)); + CHECK_EQ(n1, n2->InputAt(1)); + CHECK_EQ(1, n0->UseCount()); + CHECK_EQ(1, n1->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator); + n2->AppendInput(graph.zone(), n0); + n2->AppendInput(graph.zone(), n1); + CHECK_EQ(2, n2->InputCount()); + n2->TrimInputCount(1); + CHECK_EQ(1, n2->InputCount()); + CHECK_EQ(n0, n2->InputAt(0)); + CHECK_EQ(1, n0->UseCount()); + CHECK_EQ(0, n1->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator); + n2->AppendInput(graph.zone(), n0); + n2->AppendInput(graph.zone(), n1); + CHECK_EQ(2, n2->InputCount()); + n2->TrimInputCount(0); + CHECK_EQ(0, n2->InputCount()); + CHECK_EQ(0, n0->UseCount()); + CHECK_EQ(0, n1->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator); + n2->AppendInput(graph.zone(), n0); + n2->AppendInput(graph.zone(), n0); + CHECK_EQ(2, n2->InputCount()); + CHECK_EQ(2, n0->UseCount()); + n2->TrimInputCount(1); + CHECK_EQ(1, n2->InputCount()); + CHECK_EQ(1, n0->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator); + n2->AppendInput(graph.zone(), n0); + n2->AppendInput(graph.zone(), n0); + CHECK_EQ(2, n2->InputCount()); + CHECK_EQ(2, n0->UseCount()); + n2->TrimInputCount(0); + CHECK_EQ(0, n2->InputCount()); + CHECK_EQ(0, n0->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } +} + + +TEST(TrimInputCountOutOfLine2) { + GraphTester graph; + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0); + n2->AppendInput(graph.zone(), n1); + CHECK_EQ(2, n2->InputCount()); + n2->TrimInputCount(2); + CHECK_EQ(2, n2->InputCount()); + CHECK_EQ(n0, n2->InputAt(0)); + CHECK_EQ(n1, n2->InputAt(1)); + CHECK_EQ(1, n0->UseCount()); + CHECK_EQ(1, n1->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0); + n2->AppendInput(graph.zone(), n1); + CHECK_EQ(2, n2->InputCount()); + n2->TrimInputCount(1); + CHECK_EQ(1, n2->InputCount()); + CHECK_EQ(n0, n2->InputAt(0)); + CHECK_EQ(1, n0->UseCount()); + CHECK_EQ(0, n1->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0); + n2->AppendInput(graph.zone(), n1); + CHECK_EQ(2, n2->InputCount()); + n2->TrimInputCount(0); + CHECK_EQ(0, n2->InputCount()); + CHECK_EQ(0, n0->UseCount()); + CHECK_EQ(0, n1->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0); + n2->AppendInput(graph.zone(), n0); + CHECK_EQ(2, n2->InputCount()); + CHECK_EQ(2, n0->UseCount()); + n2->TrimInputCount(1); + CHECK_EQ(1, n2->InputCount()); + CHECK_EQ(1, n0->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n2 = graph.NewNode(&dummy_operator, n0); + n2->AppendInput(graph.zone(), n0); + CHECK_EQ(2, n2->InputCount()); + CHECK_EQ(2, n0->UseCount()); + n2->TrimInputCount(0); + CHECK_EQ(0, n2->InputCount()); + CHECK_EQ(0, n0->UseCount()); + CHECK_EQ(0, n2->UseCount()); + } +} + + +TEST(RemoveAllInputs) { + GraphTester graph; + + for (int i = 0; i < 2; i++) { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + Node* n2; + if (i == 0) { + n2 = graph.NewNode(&dummy_operator, n0, n1); + } else { + n2 = graph.NewNode(&dummy_operator, n0); + n2->AppendInput(graph.zone(), n1); // with out-of-line input. + } + + n0->RemoveAllInputs(); + CHECK_EQ(0, n0->InputCount()); + + CHECK_EQ(2, n0->UseCount()); + n1->RemoveAllInputs(); + CHECK_EQ(1, n1->InputCount()); + CHECK_EQ(1, n0->UseCount()); + CHECK_EQ(NULL, n1->InputAt(0)); + + CHECK_EQ(1, n1->UseCount()); + n2->RemoveAllInputs(); + CHECK_EQ(2, n2->InputCount()); + CHECK_EQ(0, n0->UseCount()); + CHECK_EQ(0, n1->UseCount()); + CHECK_EQ(NULL, n2->InputAt(0)); + CHECK_EQ(NULL, n2->InputAt(1)); + } + + { + Node* n0 = graph.NewNode(&dummy_operator); + Node* n1 = graph.NewNode(&dummy_operator, n0); + n1->ReplaceInput(0, n1); // self-reference. + + CHECK_EQ(0, n0->UseCount()); + CHECK_EQ(1, n1->UseCount()); + n1->RemoveAllInputs(); + CHECK_EQ(1, n1->InputCount()); + CHECK_EQ(0, n1->UseCount()); + CHECK_EQ(NULL, n1->InputAt(0)); + } +} |