Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/unittests/compiler/effect-control-linearizer-unittest.cc')
-rw-r--r--deps/v8/test/unittests/compiler/effect-control-linearizer-unittest.cc235
1 files changed, 235 insertions, 0 deletions
diff --git a/deps/v8/test/unittests/compiler/effect-control-linearizer-unittest.cc b/deps/v8/test/unittests/compiler/effect-control-linearizer-unittest.cc
index 925ae9b5e70..53b7e3a85c5 100644
--- a/deps/v8/test/unittests/compiler/effect-control-linearizer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/effect-control-linearizer-unittest.cc
@@ -292,6 +292,241 @@ TEST_F(EffectControlLinearizerTest, CloneBranch) {
IsBranch(cond2, control2)))))));
}
+TEST_F(EffectControlLinearizerTest, UnreachableThenBranch) {
+ Schedule schedule(zone());
+
+ // Create the graph.
+ Node* unreachable = graph()->NewNode(common()->Unreachable(),
+ graph()->start(), graph()->start());
+ Node* branch =
+ graph()->NewNode(common()->Branch(), Int32Constant(0), graph()->start());
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* true_throw = graph()->NewNode(common()->Throw(), unreachable, if_true);
+
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* false_throw =
+ graph()->NewNode(common()->Throw(), unreachable, if_false);
+
+ graph()->SetEnd(graph()->NewNode(common()->End(0)));
+
+ // Build the basic block structure.
+ BasicBlock* start = schedule.start();
+ schedule.rpo_order()->push_back(start);
+ start->set_rpo_number(0);
+
+ BasicBlock* tblock = AddBlockToSchedule(&schedule);
+ BasicBlock* fblock = AddBlockToSchedule(&schedule);
+
+ // Populate the basic blocks with nodes.
+ schedule.AddNode(start, graph()->start());
+ schedule.AddNode(start, unreachable);
+ schedule.AddBranch(start, branch, tblock, fblock);
+
+ schedule.AddNode(tblock, if_true);
+ schedule.AddThrow(tblock, true_throw);
+ NodeProperties::MergeControlToEnd(graph(), common(), true_throw);
+
+ schedule.AddNode(fblock, if_false);
+ schedule.AddThrow(fblock, false_throw);
+ NodeProperties::MergeControlToEnd(graph(), common(), false_throw);
+
+ ASSERT_THAT(end(), IsEnd(IsThrow(), IsThrow()));
+ ASSERT_THAT(end()->op()->ControlInputCount(), 2);
+
+ // Run the state effect linearizer, maintaining the schedule.
+ LinearizeEffectControl(
+ jsgraph(), &schedule, zone(), source_positions(), node_origins(),
+ MaskArrayIndexEnable::kDoNotMaskArrayIndex, MaintainSchedule::kMaintain);
+
+ // Initial block with the unreachable should be connected directly to end
+ // without any of the subsiquent blocks.
+ ASSERT_THAT(end(), IsEnd(IsThrow()));
+ ASSERT_THAT(end()->op()->ControlInputCount(), 1);
+ ASSERT_THAT(schedule.start()->SuccessorCount(), 1);
+ ASSERT_THAT(schedule.end()->PredecessorCount(), 1);
+ ASSERT_THAT(schedule.end()->PredecessorAt(0), start);
+}
+
+TEST_F(EffectControlLinearizerTest, UnreachableThenDiamond) {
+ Schedule schedule(zone());
+
+ // Create the graph.
+ Node* unreachable = graph()->NewNode(common()->Unreachable(),
+ graph()->start(), graph()->start());
+ Node* branch =
+ graph()->NewNode(common()->Branch(), Int32Constant(0), graph()->start());
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+
+ Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+ Node* throw_node = graph()->NewNode(common()->Throw(), unreachable, if_false);
+ graph()->SetEnd(graph()->NewNode(common()->End(0)));
+
+ // Build the basic block structure.
+ BasicBlock* start = schedule.start();
+ schedule.rpo_order()->push_back(start);
+ start->set_rpo_number(0);
+
+ BasicBlock* tblock = AddBlockToSchedule(&schedule);
+ BasicBlock* fblock = AddBlockToSchedule(&schedule);
+ BasicBlock* mblock = AddBlockToSchedule(&schedule);
+
+ // Populate the basic blocks with nodes.
+ schedule.AddNode(start, graph()->start());
+ schedule.AddNode(start, unreachable);
+ schedule.AddBranch(start, branch, tblock, fblock);
+
+ schedule.AddNode(tblock, if_true);
+ schedule.AddGoto(tblock, mblock);
+
+ schedule.AddNode(fblock, if_false);
+ schedule.AddGoto(fblock, mblock);
+
+ schedule.AddNode(mblock, merge);
+ schedule.AddThrow(mblock, throw_node);
+ NodeProperties::MergeControlToEnd(graph(), common(), throw_node);
+
+ ASSERT_THAT(end(), IsEnd(IsThrow()));
+ ASSERT_THAT(end()->op()->ControlInputCount(), 1);
+
+ // Run the state effect linearizer, maintaining the schedule.
+ LinearizeEffectControl(
+ jsgraph(), &schedule, zone(), source_positions(), node_origins(),
+ MaskArrayIndexEnable::kDoNotMaskArrayIndex, MaintainSchedule::kMaintain);
+
+ // Initial block with the unreachable should be connected directly to end
+ // without any of the subsiquent blocks.
+ ASSERT_THAT(end(), IsEnd(IsThrow()));
+ ASSERT_THAT(end()->op()->ControlInputCount(), 1);
+ ASSERT_THAT(schedule.start()->SuccessorCount(), 1);
+ ASSERT_THAT(schedule.end()->PredecessorCount(), 1);
+ ASSERT_THAT(schedule.end()->PredecessorAt(0), start);
+}
+
+TEST_F(EffectControlLinearizerTest, UnreachableThenLoop) {
+ Schedule schedule(zone());
+
+ // Create the graph.
+ Node* unreachable = graph()->NewNode(common()->Unreachable(),
+ graph()->start(), graph()->start());
+ Node* loop = graph()->NewNode(common()->Loop(1), graph()->start());
+
+ Node* cond = Int32Constant(0);
+ Node* branch = graph()->NewNode(common()->Branch(), cond, loop);
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+
+ loop->AppendInput(zone(), if_false);
+ NodeProperties::ChangeOp(loop, common()->Loop(2));
+
+ Node* throw_node = graph()->NewNode(common()->Throw(), unreachable, if_false);
+ graph()->SetEnd(graph()->NewNode(common()->End(0)));
+
+ // Build the basic block structure.
+ BasicBlock* start = schedule.start();
+ schedule.rpo_order()->push_back(start);
+ start->set_rpo_number(0);
+
+ BasicBlock* lblock = AddBlockToSchedule(&schedule);
+ BasicBlock* fblock = AddBlockToSchedule(&schedule);
+ BasicBlock* tblock = AddBlockToSchedule(&schedule);
+
+ // Populate the basic blocks with nodes.
+ schedule.AddNode(start, graph()->start());
+ schedule.AddNode(start, unreachable);
+ schedule.AddGoto(start, lblock);
+
+ schedule.AddNode(lblock, loop);
+ schedule.AddNode(lblock, cond);
+ schedule.AddBranch(lblock, branch, tblock, fblock);
+
+ schedule.AddNode(fblock, if_false);
+ schedule.AddGoto(fblock, lblock);
+
+ schedule.AddNode(tblock, if_true);
+ schedule.AddThrow(tblock, throw_node);
+ NodeProperties::MergeControlToEnd(graph(), common(), throw_node);
+
+ ASSERT_THAT(end(), IsEnd(IsThrow()));
+ ASSERT_THAT(end()->op()->ControlInputCount(), 1);
+
+ // Run the state effect linearizer, maintaining the schedule.
+ LinearizeEffectControl(
+ jsgraph(), &schedule, zone(), source_positions(), node_origins(),
+ MaskArrayIndexEnable::kDoNotMaskArrayIndex, MaintainSchedule::kMaintain);
+
+ // Initial block with the unreachable should be connected directly to end
+ // without any of the subsiquent blocks.
+ ASSERT_THAT(end(), IsEnd(IsThrow()));
+ ASSERT_THAT(end()->op()->ControlInputCount(), 1);
+ ASSERT_THAT(schedule.start()->SuccessorCount(), 1);
+ ASSERT_THAT(schedule.end()->PredecessorCount(), 1);
+ ASSERT_THAT(schedule.end()->PredecessorAt(0), start);
+}
+
+TEST_F(EffectControlLinearizerTest, UnreachableInChangedBlockThenBranch) {
+ Schedule schedule(zone());
+
+ // Create the graph.
+ Node* truncate = graph()->NewNode(simplified()->TruncateTaggedToWord32(),
+ NumberConstant(1.1));
+ Node* unreachable = graph()->NewNode(common()->Unreachable(),
+ graph()->start(), graph()->start());
+ Node* branch =
+ graph()->NewNode(common()->Branch(), Int32Constant(0), graph()->start());
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* true_throw = graph()->NewNode(common()->Throw(), unreachable, if_true);
+
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* false_throw =
+ graph()->NewNode(common()->Throw(), unreachable, if_false);
+
+ graph()->SetEnd(graph()->NewNode(common()->End(0)));
+
+ // Build the basic block structure.
+ BasicBlock* start = schedule.start();
+ schedule.rpo_order()->push_back(start);
+ start->set_rpo_number(0);
+
+ BasicBlock* tblock = AddBlockToSchedule(&schedule);
+ BasicBlock* fblock = AddBlockToSchedule(&schedule);
+
+ // Populate the basic blocks with nodes.
+ schedule.AddNode(start, graph()->start());
+ schedule.AddNode(start, truncate);
+ schedule.AddNode(start, unreachable);
+ schedule.AddBranch(start, branch, tblock, fblock);
+
+ schedule.AddNode(tblock, if_true);
+ schedule.AddThrow(tblock, true_throw);
+ NodeProperties::MergeControlToEnd(graph(), common(), true_throw);
+
+ schedule.AddNode(fblock, if_false);
+ schedule.AddThrow(fblock, false_throw);
+ NodeProperties::MergeControlToEnd(graph(), common(), false_throw);
+
+ ASSERT_THAT(end(), IsEnd(IsThrow(), IsThrow()));
+ ASSERT_THAT(end()->op()->ControlInputCount(), 2);
+
+ // Run the state effect linearizer, maintaining the schedule.
+ LinearizeEffectControl(
+ jsgraph(), &schedule, zone(), source_positions(), node_origins(),
+ MaskArrayIndexEnable::kDoNotMaskArrayIndex, MaintainSchedule::kMaintain);
+
+ // Start block now branches due to the lowering of TruncateTaggedToWord32, but
+ // then re-merges and the unreachable should be connected directly to end
+ // without any of the subsiquent blocks.
+ ASSERT_THAT(end(), IsEnd(IsThrow()));
+ ASSERT_THAT(end()->op()->ControlInputCount(), 1);
+ ASSERT_THAT(schedule.end()->PredecessorCount(), 1);
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8