Index: test/unittests/compiler/control-reducer-unittest.cc |
diff --git a/test/unittests/compiler/control-reducer-unittest.cc b/test/unittests/compiler/control-reducer-unittest.cc |
index 5e9b0ef4b1b532c0b1f6a5c29de39de4f96be270..76f25580bd2cbd5a7cdde2d000e50d3b35ac0fe5 100644 |
--- a/test/unittests/compiler/control-reducer-unittest.cc |
+++ b/test/unittests/compiler/control-reducer-unittest.cc |
@@ -3,6 +3,7 @@ |
// found in the LICENSE file. |
#include "src/compiler/control-reducer.h" |
+#include "src/compiler/graph-visualizer.h" |
#include "src/compiler/js-graph.h" |
#include "src/compiler/js-operator.h" |
#include "src/compiler/machine-operator.h" |
@@ -20,14 +21,34 @@ namespace v8 { |
namespace internal { |
namespace compiler { |
-class ControlReducerTest : public GraphTest { |
+class ControlReducerTest : public TypedGraphTest { |
+ public: |
+ ControlReducerTest() |
+ : TypedGraphTest(1), |
+ machine_(zone()), |
+ javascript_(zone()), |
+ jsgraph_(isolate(), graph(), common(), &javascript_, &machine_) {} |
+ |
protected: |
+ MachineOperatorBuilder machine_; |
+ JSOperatorBuilder javascript_; |
+ JSGraph jsgraph_; |
+ |
void ReduceGraph() { |
- JSOperatorBuilder javascript(zone()); |
- MachineOperatorBuilder machine(zone()); |
- JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine); |
- ControlReducer::ReduceGraph(zone(), &jsgraph, common()); |
+ if (FLAG_trace_turbo_graph) { |
+ OFStream os(stdout); |
+ os << "-- Graph before control reduction" << std::endl; |
+ os << AsRPO(*graph()); |
+ } |
+ ControlReducer::ReduceGraph(zone(), jsgraph(), common()); |
+ if (FLAG_trace_turbo_graph) { |
+ OFStream os(stdout); |
+ os << "-- Graph after control reduction" << std::endl; |
+ os << AsRPO(*graph()); |
+ } |
} |
+ |
+ JSGraph* jsgraph() { return &jsgraph_; } |
}; |
@@ -119,6 +140,145 @@ TEST_F(ControlReducerTest, NonTerminatingLoopWithDeadEnd) { |
IsIfTrue(CaptureEq(&branch)))))))))); |
} |
+ |
+TEST_F(ControlReducerTest, PhiAsInputToBranch_true) { |
+ Node* p0 = Parameter(0); |
+ Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start()); |
+ Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
+ Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
+ Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
+ Node* phi1 = graph()->NewNode(common()->Phi(kMachInt32, 2), |
+ jsgraph()->Int32Constant(1), |
+ jsgraph()->Int32Constant(2), merge1); |
+ |
+ Node* branch2 = graph()->NewNode(common()->Branch(), phi1, merge1); |
+ Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); |
+ Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); |
+ Node* merge2 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); |
+ Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2), |
+ jsgraph()->Int32Constant(11), |
+ jsgraph()->Int32Constant(22), merge2); |
+ |
+ Node* ret = |
+ graph()->NewNode(common()->Return(), result, graph()->start(), merge2); |
+ graph()->end()->ReplaceInput(0, ret); |
+ |
+ ReduceGraph(); |
+ |
+ // First diamond is not reduced. |
+ EXPECT_THAT(merge1, IsMerge(IsIfTrue(branch1), IsIfFalse(branch1))); |
+ |
+ // Second diamond should be folded away. |
+ EXPECT_THAT(graph()->end(), |
+ IsEnd(IsReturn(IsInt32Constant(11), graph()->start(), merge1))); |
+} |
+ |
+ |
+TEST_F(ControlReducerTest, PhiAsInputToBranch_false) { |
+ Node* p0 = Parameter(0); |
+ Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start()); |
+ Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
+ Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
+ Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
+ Node* phi1 = graph()->NewNode(common()->Phi(kMachInt32, 2), |
+ jsgraph()->Int32Constant(0), |
+ jsgraph()->BooleanConstant(false), merge1); |
+ |
+ Node* branch2 = graph()->NewNode(common()->Branch(), phi1, merge1); |
+ Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); |
+ Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); |
+ Node* merge2 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); |
+ Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2), |
+ jsgraph()->Int32Constant(11), |
+ jsgraph()->Int32Constant(22), merge2); |
+ |
+ Node* ret = |
+ graph()->NewNode(common()->Return(), result, graph()->start(), merge2); |
+ graph()->end()->ReplaceInput(0, ret); |
+ |
+ ReduceGraph(); |
+ |
+ // First diamond is not reduced. |
+ EXPECT_THAT(merge1, IsMerge(IsIfTrue(branch1), IsIfFalse(branch1))); |
+ |
+ // Second diamond should be folded away. |
+ EXPECT_THAT(graph()->end(), |
+ IsEnd(IsReturn(IsInt32Constant(22), graph()->start(), merge1))); |
+} |
+ |
+ |
+TEST_F(ControlReducerTest, PhiAsInputToBranch_unknown_true) { |
+ Node* p0 = Parameter(0); |
+ Node* phi0 = graph()->NewNode(common()->Phi(kMachInt32, 2), p0, |
+ jsgraph()->Int32Constant(1), graph()->start()); |
+ Node* branch1 = graph()->NewNode(common()->Branch(), phi0, graph()->start()); |
+ Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
+ Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
+ Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
+ Node* phi1 = graph()->NewNode(common()->Phi(kMachInt32, 2), |
+ jsgraph()->Int32Constant(111), |
+ jsgraph()->Int32Constant(222), merge1); |
+ |
+ Node* ret = |
+ graph()->NewNode(common()->Return(), phi1, graph()->start(), merge1); |
+ graph()->end()->ReplaceInput(0, ret); |
+ |
+ ReduceGraph(); |
+ |
+ // Branch should not be folded. |
+ EXPECT_THAT(phi1, |
+ IsPhi(kMachInt32, IsInt32Constant(111), IsInt32Constant(222), |
+ IsMerge(IsIfTrue(branch1), IsIfFalse(branch1)))); |
+ EXPECT_THAT(graph()->end(), IsEnd(IsReturn(phi1, graph()->start(), merge1))); |
+} |
+ |
+ |
+TEST_F(ControlReducerTest, RangeAsInputToBranch_true1) { |
+ Node* p0 = Parameter(Type::Range(1, 2, zone()), 0); |
+ Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start()); |
+ Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
+ Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
+ Node* merge1 = graph()->NewNode(common()->Merge(1), if_true1, if_false1); |
+ Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2), |
+ jsgraph()->Int32Constant(11), |
+ jsgraph()->Int32Constant(44), merge1); |
+ |
+ Node* ret = |
+ graph()->NewNode(common()->Return(), result, graph()->start(), merge1); |
+ graph()->end()->ReplaceInput(0, ret); |
+ |
+ ReduceGraph(); |
+ |
+ // Diamond should be folded away. |
+ EXPECT_THAT( |
+ graph()->end(), |
+ IsEnd(IsReturn(IsInt32Constant(11), graph()->start(), graph()->start()))); |
+} |
+ |
+ |
+TEST_F(ControlReducerTest, RangeAsInputToBranch_true2) { |
+ Node* p0 = Parameter(Type::Range(-2, -1, zone()), 0); |
+ Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start()); |
+ Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
+ Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
+ Node* merge1 = graph()->NewNode(common()->Merge(1), if_true1, if_false1); |
+ Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2), |
+ jsgraph()->Int32Constant(11), |
+ jsgraph()->Int32Constant(44), merge1); |
+ |
+ Node* ret = |
+ graph()->NewNode(common()->Return(), result, graph()->start(), merge1); |
+ graph()->end()->ReplaceInput(0, ret); |
+ |
+ ReduceGraph(); |
+ |
+ // Diamond should be folded away. |
+ EXPECT_THAT( |
+ graph()->end(), |
+ IsEnd(IsReturn(IsInt32Constant(11), graph()->start(), graph()->start()))); |
+} |
+ |
+ |
} // namespace compiler |
} // namespace internal |
} // namespace v8 |