// 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"
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_; }
};
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