26TEST(CommonNodeEliminationTests, test_simple)
34 auto & graph = rm.
Rvsdg();
40 auto n1 = TestOperation::createNode(&graph.GetRootRegion(), {}, { vt })->output(0);
41 auto n2 = TestOperation::createNode(&graph.GetRootRegion(), {}, { vt })->output(0);
43 auto u1 = TestOperation::createNode(&graph.GetRootRegion(), { z }, { vt })->output(0);
45 auto b1 = TestOperation::createNode(&graph.GetRootRegion(), { x, y }, { vt })->output(0);
46 auto b2 = TestOperation::createNode(&graph.GetRootRegion(), { x, y }, { vt })->output(0);
47 auto b3 = TestOperation::createNode(&graph.GetRootRegion(), { n1, z }, { vt })->output(0);
48 auto b4 = TestOperation::createNode(&graph.GetRootRegion(), { n2, z }, { vt })->output(0);
63 EXPECT_EQ(graph.GetRootRegion().result(0)->origin(), graph.GetRootRegion().result(1)->origin());
64 EXPECT_EQ(graph.GetRootRegion().result(3)->origin(), graph.GetRootRegion().result(4)->origin());
65 EXPECT_EQ(graph.GetRootRegion().result(5)->origin(), graph.GetRootRegion().result(6)->origin());
68TEST(CommonNodeEliminationTests, test_gamma)
77 auto & graph = rm.
Rvsdg();
84 auto u1 = TestOperation::createNode(&graph.GetRootRegion(), { x }, { vt })->output(0);
85 auto u2 = TestOperation::createNode(&graph.GetRootRegion(), { x }, { vt })->output(0);
89 auto ev1 = gamma->AddEntryVar(u1);
90 auto ev2 = gamma->AddEntryVar(u2);
91 auto ev3 = gamma->AddEntryVar(y);
92 auto ev4 = gamma->AddEntryVar(z);
93 auto ev5 = gamma->AddEntryVar(z);
95 auto n1 = TestOperation::createNode(gamma->subregion(0), {}, { vt })->output(0);
96 auto n2 = TestOperation::createNode(gamma->subregion(0), {}, { vt })->output(0);
97 auto n3 = TestOperation::createNode(gamma->subregion(0), {}, { vt })->output(0);
99 gamma->AddExitVar({ ev1.branchArgument[0], ev1.branchArgument[1] });
100 gamma->AddExitVar({ ev2.branchArgument[0], ev2.branchArgument[1] });
101 gamma->AddExitVar({ ev3.branchArgument[0], ev3.branchArgument[1] });
102 gamma->AddExitVar({ n1, ev3.branchArgument[1] });
103 gamma->AddExitVar({ n2, ev3.branchArgument[1] });
104 gamma->AddExitVar({ n3, ev3.branchArgument[1] });
105 gamma->AddExitVar({ ev5.branchArgument[0], ev4.branchArgument[1] });
116 auto subregion0 = gamma->subregion(0);
117 auto subregion1 = gamma->subregion(1);
118 EXPECT_EQ(gamma->input(1)->origin(), gamma->input(2)->origin());
119 EXPECT_EQ(subregion0->result(0)->origin(), subregion0->result(1)->origin());
120 EXPECT_EQ(subregion0->result(3)->origin(), subregion0->result(4)->origin());
121 EXPECT_EQ(subregion0->result(3)->origin(), subregion0->result(5)->origin());
122 EXPECT_EQ(subregion1->result(0)->origin(), subregion1->result(1)->origin());
123 EXPECT_EQ(graph.GetRootRegion().result(0)->origin(), graph.GetRootRegion().result(1)->origin());
129 EXPECT_EQ(argument0->input(), argument1->input());
132TEST(CommonNodeEliminationTests, test_gamma_congruent_exit_vars)
165 auto & graph = rm.
Rvsdg();
173 auto entryVarA = gamma->AddEntryVar(importA);
174 auto entryVarB = gamma->AddEntryVar(importB);
177 auto exitVarA = gamma->AddExitVar({ entryVarA.branchArgument[0], entryVarA.branchArgument[1] });
178 auto exitVarB = gamma->AddExitVar({ entryVarB.branchArgument[0], entryVarB.branchArgument[1] });
181 auto exitVarX = gamma->AddExitVar({ entryVarA.branchArgument[0], entryVarB.branchArgument[1] });
182 auto exitVarY = gamma->AddExitVar({ entryVarA.branchArgument[0], entryVarB.branchArgument[1] });
183 auto exitVarZ = gamma->AddExitVar({ entryVarB.branchArgument[0], entryVarA.branchArgument[1] });
198 EXPECT_EQ(exportA.origin(), importA);
199 EXPECT_EQ(exportB.origin(), importB);
202 EXPECT_EQ(exportX.origin(), exitVarX.output);
203 EXPECT_EQ(exportY.origin(), exitVarX.output);
204 EXPECT_EQ(exitVarY.output->nusers(), 0u);
207 EXPECT_EQ(exportZ.origin(), exitVarZ.output);
210TEST(CommonNodeEliminationTests, test_theta)
219 auto & graph = rm.
Rvsdg();
225 auto region = theta->subregion();
227 auto lv1 = theta->AddLoopVar(c);
228 auto lv2 = theta->AddLoopVar(x);
229 auto lv3 = theta->AddLoopVar(x);
230 auto lv4 = theta->AddLoopVar(x);
232 auto u1 = TestOperation::createNode(region, { lv2.pre }, {
vt })->output(0);
233 auto u2 = TestOperation::createNode(region, { lv3.pre }, {
vt })->output(0);
234 auto b1 = TestOperation::createNode(region, { lv3.pre, lv4.pre }, {
vt })->output(0);
236 lv2.post->divert_to(u1);
237 lv3.post->divert_to(u2);
238 lv4.post->divert_to(b1);
240 theta->set_predicate(lv1.pre);
254 EXPECT_EQ(un1->input(0)->origin(), un2->input(0)->origin());
255 EXPECT_EQ(bn1->input(0)->origin(), un1->input(0)->origin());
256 EXPECT_EQ(bn1->input(1)->origin(), region->argument(3));
257 EXPECT_EQ(region->result(2)->origin(), region->result(3)->origin());
258 EXPECT_EQ(graph.GetRootRegion().result(0)->origin(), graph.GetRootRegion().result(1)->origin());
261TEST(CommonNodeEliminationTests, test_theta2)
270 auto & graph = rm.
Rvsdg();
276 auto region = theta->subregion();
278 auto lv1 = theta->AddLoopVar(c);
279 auto lv2 = theta->AddLoopVar(x);
280 auto lv3 = theta->AddLoopVar(x);
282 auto u1 = TestOperation::createNode(region, { lv2.pre }, {
vt })->output(0);
283 auto u2 = TestOperation::createNode(region, { lv3.pre }, {
vt })->output(0);
284 auto b1 = TestOperation::createNode(region, { u2, u2 }, {
vt })->output(0);
286 lv2.post->divert_to(u1);
287 lv3.post->divert_to(b1);
289 theta->set_predicate(lv1.pre);
299 EXPECT_EQ(lv2.post->origin(), u1);
300 EXPECT_NE(lv2.pre->nusers(), 0u);
301 EXPECT_NE(lv3.pre->nusers(), 0u);
304TEST(CommonNodeEliminationTests, test_theta3)
313 auto & graph = rm.
Rvsdg();
319 auto r1 = theta1->subregion();
321 auto lv1 = theta1->AddLoopVar(c);
322 auto lv2 = theta1->AddLoopVar(x);
323 auto lv3 = theta1->AddLoopVar(x);
324 auto lv4 = theta1->AddLoopVar(x);
327 auto r2 = theta2->subregion();
328 auto p = theta2->AddLoopVar(lv1.pre);
329 auto p2 = theta2->AddLoopVar(lv2.pre);
330 auto p3 = theta2->AddLoopVar(lv3.pre);
331 auto p4 = theta2->AddLoopVar(lv4.pre);
332 theta2->set_predicate(p.pre);
334 auto u1 = TestOperation::createNode(r1, { p2.output }, {
vt });
335 auto b1 = TestOperation::createNode(r1, { p3.output, p3.output }, {
vt });
336 auto u2 = TestOperation::createNode(r1, { p4.output }, {
vt });
338 lv2.post->divert_to(u1->output(0));
339 lv3.post->divert_to(b1->output(0));
340 lv4.post->divert_to(u1->output(0));
342 theta1->set_predicate(lv1.pre);
353 EXPECT_EQ(r1->result(2)->origin(), r1->result(4)->origin());
354 EXPECT_EQ(u1->input(0)->origin(), u2->input(0)->origin());
355 EXPECT_EQ(r2->result(2)->origin(), r2->result(4)->origin());
356 EXPECT_EQ(theta2->input(1)->origin(), theta2->input(3)->origin());
357 EXPECT_NE(r1->result(3)->origin(), r1->result(4)->origin());
358 EXPECT_NE(r2->result(3)->origin(), r2->result(4)->origin());
361TEST(CommonNodeEliminationTests, test_theta4)
370 auto & graph = rm.
Rvsdg();
377 auto region = theta->subregion();
379 auto lv1 = theta->AddLoopVar(c);
380 auto lv2 = theta->AddLoopVar(x);
381 auto lv3 = theta->AddLoopVar(x);
382 auto lv4 = theta->AddLoopVar(y);
383 auto lv5 = theta->AddLoopVar(y);
384 auto lv6 = theta->AddLoopVar(x);
385 auto lv7 = theta->AddLoopVar(x);
387 auto u1 = TestOperation::createNode(region, { lv2.pre }, {
vt });
388 auto b1 = TestOperation::createNode(region, { lv3.pre, lv3.pre }, {
vt });
390 lv2.post->divert_to(lv4.pre);
391 lv3.post->divert_to(lv5.pre);
392 lv4.post->divert_to(u1->output(0));
393 lv5.post->divert_to(b1->output(0));
395 theta->set_predicate(lv1.pre);
407 EXPECT_NE(ex1.origin(), ex2.origin());
408 EXPECT_NE(lv2.pre->nusers(), 0u);
409 EXPECT_NE(lv3.pre->nusers(), 0u);
410 EXPECT_EQ(lv6.post->origin(), lv7.post->origin());
413TEST(CommonNodeEliminationTests, test_theta5)
421 auto & graph = rm.
Rvsdg();
428 auto region = theta->subregion();
430 auto lv0 = theta->AddLoopVar(c);
431 auto lv1 = theta->AddLoopVar(x);
432 auto lv2 = theta->AddLoopVar(x);
433 auto lv3 = theta->AddLoopVar(y);
434 auto lv4 = theta->AddLoopVar(y);
436 lv1.post->divert_to(lv3.pre);
437 lv2.post->divert_to(lv4.pre);
439 theta->set_predicate(lv0.pre);
451 EXPECT_EQ(ex1.origin(), ex2.origin());
452 EXPECT_EQ(ex3.origin(), ex4.origin());
453 EXPECT_EQ(region->result(4)->origin(), region->result(5)->origin());
454 EXPECT_EQ(region->result(2)->origin(), region->result(3)->origin());
457TEST(CommonNodeEliminationTests, MultipleThetas)
463 const auto valueType = TestType::createValueType();
466 auto & rvsdg = rvsdgModule.
Rvsdg();
471 auto thetaNode1 = ThetaNode::create(&rvsdg.GetRootRegion());
472 auto loopVariable1 = thetaNode1->AddLoopVar(&i0);
474 TestOperation::createNode(thetaNode1->subregion(), { loopVariable1.pre }, { valueType });
475 loopVariable1.post->divert_to(node1->output(0));
478 auto thetaNode2 = ThetaNode::create(&rvsdg.GetRootRegion());
479 auto predicate = &ControlConstantOperation::create(*thetaNode2->subregion(), 2, 1);
480 thetaNode2->set_predicate(predicate);
481 auto loopVariable2 = thetaNode2->AddLoopVar(&i0);
483 TestOperation::createNode(thetaNode1->subregion(), { loopVariable2.pre }, { valueType });
484 loopVariable2.post->divert_to(node2->output(0));
487 auto thetaNode3 = ThetaNode::create(&rvsdg.GetRootRegion());
488 auto loopVariable3 = thetaNode3->AddLoopVar(loopVariable1.output);
489 auto loopVariable4 = thetaNode3->AddLoopVar(loopVariable2.output);
505 EXPECT_NE(x1.origin(), x2.origin());
508TEST(CommonNodeEliminationTests, MultipleThetasPassthrough)
514 const auto valueType = TestType::createValueType();
517 auto & rvsdg = rvsdgModule.
Rvsdg();
522 auto thetaNode1 = ThetaNode::create(&rvsdg.GetRootRegion());
523 auto loopVariable1 = thetaNode1->AddLoopVar(&i0);
526 auto thetaNode2 = ThetaNode::create(&rvsdg.GetRootRegion());
527 auto predicate = &ControlConstantOperation::create(*thetaNode2->subregion(), 2, 1);
528 thetaNode2->set_predicate(predicate);
529 auto loopVariable2 = thetaNode2->AddLoopVar(&i0);
532 auto thetaNode3 = ThetaNode::create(&rvsdg.GetRootRegion());
533 auto loopVariable3 = thetaNode3->AddLoopVar(loopVariable1.output);
534 auto loopVariable4 = thetaNode3->AddLoopVar(loopVariable2.output);
551 EXPECT_EQ(x1.origin(), x2.origin());
554TEST(CommonNodeEliminationTests, test_lambda)
563 auto & graph = rm.Rvsdg();
568 graph.GetRootRegion(),
569 LlvmLambdaOperation::Create(ft,
"f", Linkage::externalLinkage));
571 auto d1 = lambda->AddContextVar(*x).inner;
572 auto d2 = lambda->AddContextVar(*x).inner;
574 auto b1 = TestOperation::createNode(lambda->subregion(), { d1, d2 }, { vt })->output(0);
576 auto output = lambda->finalize({ b1 });
586 EXPECT_EQ(bn1->input(0)->origin(), bn1->input(1)->origin());
589TEST(CommonNodeEliminationTests, test_phi)
597 auto & graph = rm.Rvsdg();
602 pb.
begin(&graph.GetRootRegion());
613 LlvmLambdaOperation::Create(ft,
"f", Linkage::externalLinkage));
614 auto cv1 = lambda1->AddContextVar(*d1.inner).inner;
615 auto f1 = lambda1->finalize({ cv1 });
619 LlvmLambdaOperation::Create(ft,
"f", Linkage::externalLinkage));
620 auto cv2 = lambda2->AddContextVar(*d2.inner).inner;
621 auto f2 = lambda2->finalize({ cv2 });
623 r1.result->divert_to(f1);
624 r2.result->divert_to(f2);
641TEST(CommonNodeEliminationTests, EmptyTheta)
647 auto valueType = TestType::createValueType();
648 auto controlType = ControlType::Create(2);
651 auto & rvsdg = rvsdgModule.
Rvsdg();
653 auto thetaNode = ThetaNode::create(&rvsdg.GetRootRegion());
655 auto node1 = TestOperation::createNode(thetaNode->subregion(), {}, { valueType });
657 TestOperation::createNode(thetaNode->subregion(), { node1->output(0) }, { valueType });
659 TestOperation::createNode(thetaNode->subregion(), { node1->output(0) }, { valueType });
660 auto node4 = TestOperation::createNode(
661 thetaNode->subregion(),
662 { node2->output(0), node3->output(0) },
665 thetaNode->set_predicate(node4->output(0));
673 thetaNode->subregion()->prune(
false);
679 EXPECT_EQ(thetaNode->subregion()->numNodes(), 3u);
682TEST(CommonNodeEliminationTests, GammaInTheta)
712 const auto valueType = TestType::createValueType();
715 auto & rvsdg = rvsdgModule.
Rvsdg();
717 auto & constant10 = BitConstantOperation::create(rvsdg.GetRootRegion(), { 32, 10 });
719 auto thetaNode = ThetaNode::create(&rvsdg.GetRootRegion());
720 auto loopVar1 = thetaNode->AddLoopVar(&constant10);
721 auto loopVar2 = thetaNode->AddLoopVar(&constant10);
722 auto & thetaRegion = *thetaNode->subregion();
724 auto & control0 = ControlConstantOperation::create(thetaRegion, 2, 0);
725 auto gammaNode = GammaNode::create(&control0, 2);
726 auto entryVar1 = gammaNode->AddEntryVar(loopVar1.pre);
727 auto entryVar2 = gammaNode->AddEntryVar(loopVar2.pre);
729 gammaNode->AddExitVar({ entryVar1.branchArgument[0], entryVar2.branchArgument[1] }).output;
731 auto user1 = TestOperation::createNode(&thetaRegion, { gammaOutput }, {});
733 auto & constant6 = BitConstantOperation::create(thetaRegion, { 32, 6 });
734 auto & constant7 = BitConstantOperation::create(thetaRegion, { 32, 7 });
735 loopVar1.post->divert_to(&constant6);
736 loopVar2.post->divert_to(&constant7);
743 const auto & user1Origin = *user1->input(0)->origin();
744 EXPECT_EQ(TryGetOwnerNode<GammaNode>(user1Origin), gammaNode);
747TEST(CommonNodeEliminationTests, InvariantThetaInTheta)
803 auto & graph = rm.
Rvsdg();
805 auto controlType = ControlType::Create(2);
807 auto & zero = *IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 0).output(0);
809 auto & theta0 = *ThetaNode::create(&graph.GetRootRegion());
810 auto loopVarX0 = theta0.AddLoopVar(&zero);
811 auto loopVarY0 = theta0.AddLoopVar(&zero);
814 auto & five = *IntegerConstantOperation::Create(*theta0.subregion(), 32, 5).output(0);
815 auto & theta1 = *ThetaNode::create(theta0.subregion());
816 auto loopVarZ1 = theta1.AddLoopVar(&five);
817 auto loopVarY1 = theta1.AddLoopVar(loopVarY0.pre);
818 auto & predicate1 = ControlConstantOperation::create(*theta1.subregion(), 2, 0);
819 theta1.set_predicate(&predicate1);
821 auto & one = *IntegerConstantOperation::Create(*theta0.subregion(), 32, 1).output(0);
822 auto & plus1Node = IntegerAddOperation::createNode(32, *loopVarX0.pre, one);
823 auto & xPlus1 = *plus1Node.output(0);
825 auto & two = *IntegerConstantOperation::Create(*theta0.subregion(), 32, 2).output(0);
826 auto & plus2Node = IntegerAddOperation::createNode(32, *loopVarY1.output, two);
827 auto & yPlus2 = *plus2Node.output(0);
829 auto & ten = *IntegerConstantOperation::Create(*theta0.subregion(), 32, 10).output(0);
830 auto & slt = *IntegerSltOperation::createNode(32, xPlus1, ten).output(0);
831 auto & predicate0 = *MatchOperation::CreateNode(slt, { { 1, 1 } }, 0, 2).output(0);
833 theta0.set_predicate(&predicate0);
834 loopVarX0.post->divert_to(&xPlus1);
835 loopVarY0.post->divert_to(&yPlus2);
847 EXPECT_TRUE(loopVarZ1.output->IsDead());
848 EXPECT_TRUE(loopVarY1.output->IsDead());
851 EXPECT_EQ(plus1Node.input(0)->origin(), loopVarX0.pre);
852 EXPECT_EQ(plus2Node.input(0)->origin(), loopVarY0.pre);
855TEST(CommonNodeEliminationTests, InvariantLoopOutputs)
892 auto & graph = rm.
Rvsdg();
894 const auto bit32 = BitType::Create(32);
896 auto & zero = *IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 0).output(0);
897 auto & undefValue = *UndefValueOperation::Create(graph.GetRootRegion(), bit32);
899 auto theta = ThetaNode::create(&graph.GetRootRegion());
900 auto region = theta->subregion();
902 auto lvX = theta->AddLoopVar(&undefValue);
903 auto lvY = theta->AddLoopVar(&zero);
904 auto lvZ = theta->AddLoopVar(&undefValue);
906 auto & controlGamma = ControlConstantOperation::create(*region, 2, 0);
907 auto gamma = GammaNode::create(&controlGamma, 2);
909 auto entryY = gamma->AddEntryVar(lvY.pre);
910 auto & exitY = *gamma->AddExitVar({ entryY.branchArgument[0], entryY.branchArgument[1] }).output;
912 lvX.post->divert_to(&exitY);
913 lvY.post->divert_to(&exitY);
914 lvZ.post->divert_to(lvY.pre);
916 auto & exportX = GraphExport::Create(*lvX.output,
"x");
917 auto & exportY = GraphExport::Create(*lvY.output,
"y");
918 auto & exportZ = GraphExport::Create(*lvZ.output,
"z");
925 EXPECT_EQ(exportX.origin(), &zero);
926 EXPECT_EQ(exportY.origin(), &zero);
927 EXPECT_EQ(exportZ.origin(), &zero);