44TEST(InvariantValueRedirectionTests, TestGamma)
52 { controlType, valueType, valueType },
53 { valueType, valueType });
56 auto & rvsdg = rvsdgModule->Rvsdg();
59 rvsdg.GetRootRegion(),
62 auto c = lambdaNode->GetFunctionArguments()[0];
63 auto x = lambdaNode->GetFunctionArguments()[1];
64 auto y = lambdaNode->GetFunctionArguments()[2];
67 auto gammaInput1 = gammaNode1->AddEntryVar(c);
68 auto gammaInput2 = gammaNode1->AddEntryVar(x);
69 auto gammaInput3 = gammaNode1->AddEntryVar(y);
72 auto gammaInput4 = gammaNode2->AddEntryVar(gammaInput2.branchArgument[0]);
73 auto gammaInput5 = gammaNode2->AddEntryVar(gammaInput3.branchArgument[0]);
74 gammaNode2->AddExitVar(gammaInput4.branchArgument);
75 gammaNode2->AddExitVar(gammaInput5.branchArgument);
77 gammaNode1->AddExitVar({ gammaNode2->output(0), gammaInput2.branchArgument[1] });
78 gammaNode1->AddExitVar({ gammaNode2->output(1), gammaInput3.branchArgument[1] });
80 auto lambdaOutput = lambdaNode->finalize({ gammaNode1->output(0), gammaNode1->output(1) });
88 EXPECT_EQ(lambdaNode->GetFunctionResults()[0]->origin(), x);
89 EXPECT_EQ(lambdaNode->GetFunctionResults()[1]->origin(), y);
92TEST(InvariantValueRedirectionTests, testGammaControlConstantRedirection_Success)
97 auto valueType = TestType::createValueType();
98 auto controlType = ControlType::Create(2);
99 auto functionType = FunctionType::Create({}, { controlType });
102 auto & rvsdg = rvsdgModule->Rvsdg();
104 auto lambdaNode = LambdaNode::Create(
105 rvsdg.GetRootRegion(),
108 auto outerPredicate = TestOperation::createNode(lambdaNode->subregion(), {}, { controlType });
109 auto outerGammaNode = GammaNode::create(outerPredicate->output(0), 2);
112 auto innerPredicate0 =
113 TestOperation::createNode(outerGammaNode->subregion(0), {}, { controlType });
114 auto innerGammaNode0 = GammaNode::create(innerPredicate0->output(0), 2);
117 auto & ctlConstant00 = ControlConstantOperation::createFalse(*innerGammaNode0->subregion(0));
123 auto innerGammeNode0ExitVar = innerGammaNode0->AddExitVar({ &ctlConstant00, &ctlConstant01 });
126 auto innerPredicate1 =
127 TestOperation::createNode(outerGammaNode->subregion(1), {}, { controlType });
128 auto innerGammaNode1 = GammaNode::create(innerPredicate1->output(0), 2);
131 auto & ctlConstant10 = ControlConstantOperation::createFalse(*innerGammaNode1->subregion(0));
137 auto innerGammeNode1ExitVar = innerGammaNode1->AddExitVar({ &ctlConstant10, &ctlConstant11 });
140 auto outerGammaNodeExitVar =
141 outerGammaNode->AddExitVar({ innerGammeNode0ExitVar.output, innerGammeNode1ExitVar.output });
143 auto lambdaOutput = lambdaNode->finalize({ outerGammaNodeExitVar.output });
145 GraphExport::Create(*lambdaOutput,
"test");
152 EXPECT_FALSE(Region::containsNodeType<GammaNode>(*lambdaNode->subregion(),
false));
156 auto [ctlConstantNode, ctlConstantOp] = TryGetSimpleNodeAndOptionalOp<ControlConstantOperation>(
157 *lambdaNode->GetFunctionResults()[0]->origin());
158 EXPECT_NE(ctlConstantOp,
nullptr);
159 EXPECT_EQ(ctlConstantOp->value().nalternatives(), 2);
160 EXPECT_EQ(ctlConstantOp->value().alternative(), 0);
163TEST(InvariantValueRedirectionTests, testGammaControlConstantRedirection_Failure)
168 auto valueType = TestType::createValueType();
169 auto controlType = ControlType::Create(2);
170 auto functionType = FunctionType::Create({}, { controlType });
173 auto & rvsdg = rvsdgModule->Rvsdg();
175 auto lambdaNode = LambdaNode::Create(
176 rvsdg.GetRootRegion(),
179 auto outerPredicate = TestOperation::createNode(lambdaNode->subregion(), {}, { controlType });
180 auto outerGammaNode = GammaNode::create(outerPredicate->output(0), 2);
183 auto innerPredicate0 =
184 TestOperation::createNode(outerGammaNode->subregion(0), {}, { controlType });
185 auto innerGammaNode0 = GammaNode::create(innerPredicate0->output(0), 2);
188 auto & ctlConstant00 = ControlConstantOperation::createTrue(*innerGammaNode0->subregion(0));
194 auto innerGammeNode0ExitVar = innerGammaNode0->AddExitVar({ &ctlConstant00, &ctlConstant01 });
197 auto innerPredicate1 =
198 TestOperation::createNode(outerGammaNode->subregion(1), {}, { controlType });
199 auto innerGammaNode1 = GammaNode::create(innerPredicate1->output(0), 2);
202 auto & ctlConstant10 = ControlConstantOperation::createFalse(*innerGammaNode1->subregion(0));
208 auto innerGammeNode1ExitVar = innerGammaNode1->AddExitVar({ &ctlConstant10, &ctlConstant11 });
211 auto outerGammaNodeExitVar =
212 outerGammaNode->AddExitVar({ innerGammeNode0ExitVar.output, innerGammeNode1ExitVar.output });
214 auto lambdaOutput = lambdaNode->finalize({ outerGammaNodeExitVar.output });
216 GraphExport::Create(*lambdaOutput,
"test");
225 EXPECT_TRUE(Region::containsNodeType<GammaNode>(*lambdaNode->subregion(),
false));
228 EXPECT_EQ(lambdaNode->GetFunctionResults()[0]->origin(), outerGammaNodeExitVar.output);
231TEST(InvariantValueRedirectionTests, testGammaIntegerConstantRedirection_Success)
236 auto i32Type = BitType::Create(32);
237 auto valueType = TestType::createValueType();
238 auto controlType = ControlType::Create(2);
239 auto functionType = FunctionType::Create({}, { i32Type });
242 auto & rvsdg = rvsdgModule->Rvsdg();
244 auto lambdaNode = LambdaNode::Create(
245 rvsdg.GetRootRegion(),
248 auto outerPredicate = TestOperation::createNode(lambdaNode->subregion(), {}, { controlType });
249 auto outerGammaNode = GammaNode::create(outerPredicate->output(0), 2);
252 auto innerPredicate0 =
253 TestOperation::createNode(outerGammaNode->subregion(0), {}, { controlType });
254 auto innerGammaNode0 = GammaNode::create(innerPredicate0->output(0), 2);
257 auto & intConstant00 =
264 auto innerGammeNode0ExitVar = innerGammaNode0->AddExitVar({ &intConstant00, &intConstant01 });
267 auto innerPredicate1 =
268 TestOperation::createNode(outerGammaNode->subregion(1), {}, { controlType });
269 auto innerGammaNode1 = GammaNode::create(innerPredicate1->output(0), 2);
272 auto & intConstant10 =
279 auto innerGammeNode1ExitVar = innerGammaNode1->AddExitVar({ &intConstant10, &intConstant11 });
282 auto outerGammaNodeExitVar =
283 outerGammaNode->AddExitVar({ innerGammeNode0ExitVar.output, innerGammeNode1ExitVar.output });
285 auto lambdaOutput = lambdaNode->finalize({ outerGammaNodeExitVar.output });
287 GraphExport::Create(*lambdaOutput,
"test");
294 EXPECT_FALSE(Region::containsNodeType<GammaNode>(*lambdaNode->subregion(),
false));
298 auto [intConstantNode, intConstantOp] = TryGetSimpleNodeAndOptionalOp<IntegerConstantOperation>(
299 *lambdaNode->GetFunctionResults()[0]->origin());
300 EXPECT_NE(intConstantOp,
nullptr);
301 EXPECT_EQ(intConstantOp->Representation().nbits(), 32);
302 EXPECT_EQ(intConstantOp->Representation().to_uint(), 0);
305TEST(InvariantValueRedirectionTests, testGammaIntegerConstantRedirection_Failure)
310 auto i32Type = BitType::Create(32);
311 auto valueType = TestType::createValueType();
312 auto controlType = ControlType::Create(2);
313 auto functionType = FunctionType::Create({}, { i32Type });
316 auto & rvsdg = rvsdgModule->Rvsdg();
318 auto lambdaNode = LambdaNode::Create(
319 rvsdg.GetRootRegion(),
322 auto outerPredicate = TestOperation::createNode(lambdaNode->subregion(), {}, { controlType });
323 auto outerGammaNode = GammaNode::create(outerPredicate->output(0), 2);
326 auto innerPredicate0 =
327 TestOperation::createNode(outerGammaNode->subregion(0), {}, { controlType });
328 auto innerGammaNode0 = GammaNode::create(innerPredicate0->output(0), 2);
331 auto & intConstant00 =
338 auto innerGammeNode0ExitVar = innerGammaNode0->AddExitVar({ &intConstant00, &intConstant01 });
341 auto innerPredicate1 =
342 TestOperation::createNode(outerGammaNode->subregion(1), {}, { controlType });
343 auto innerGammaNode1 = GammaNode::create(innerPredicate1->output(0), 2);
346 auto & intConstant10 =
353 auto innerGammeNode1ExitVar = innerGammaNode1->AddExitVar({ &intConstant10, &intConstant11 });
356 auto outerGammaNodeExitVar =
357 outerGammaNode->AddExitVar({ innerGammeNode0ExitVar.output, innerGammeNode1ExitVar.output });
359 auto lambdaOutput = lambdaNode->finalize({ outerGammaNodeExitVar.output });
361 GraphExport::Create(*lambdaOutput,
"test");
370 EXPECT_TRUE(Region::containsNodeType<GammaNode>(*lambdaNode->subregion(),
false));
373 EXPECT_EQ(lambdaNode->GetFunctionResults()[0]->origin(), outerGammaNodeExitVar.output);
376TEST(InvariantValueRedirectionTests, TestTheta)
385 { controlType, valueType, ioStateType },
386 { controlType, valueType, ioStateType });
389 auto & rvsdg = rvsdgModule->Rvsdg();
392 rvsdg.GetRootRegion(),
395 auto c = lambdaNode->GetFunctionArguments()[0];
396 auto x = lambdaNode->GetFunctionArguments()[1];
397 auto l = lambdaNode->GetFunctionArguments()[2];
400 auto thetaVar1 = thetaNode1->AddLoopVar(c);
401 auto thetaVar2 = thetaNode1->AddLoopVar(x);
402 auto thetaVar3 = thetaNode1->AddLoopVar(l);
405 auto thetaVar4 = thetaNode2->AddLoopVar(thetaVar1.pre);
406 thetaNode2->AddLoopVar(thetaVar2.pre);
407 auto thetaVar5 = thetaNode2->AddLoopVar(thetaVar3.pre);
408 thetaNode2->set_predicate(thetaVar4.pre);
410 thetaVar3.post->divert_to(thetaVar5.output);
411 thetaNode1->set_predicate(thetaVar1.pre);
414 lambdaNode->finalize({ thetaVar1.output, thetaVar2.output, thetaVar3.output });
422 EXPECT_EQ(lambdaNode->GetFunctionResults()[0]->origin(), c);
423 EXPECT_EQ(lambdaNode->GetFunctionResults()[1]->origin(), x);
424 EXPECT_EQ(lambdaNode->GetFunctionResults()[2]->origin(), thetaVar3.output);
427TEST(InvariantValueRedirectionTests, testThetaConstantRedirection)
432 auto i32Type = BitType::Create(32);
433 auto ctlType = ControlType::Create(2);
435 auto valueType = TestType::createValueType();
436 auto functionType = FunctionType::Create(
437 { i32Type, ctlType, fpType, valueType },
438 { i32Type, ctlType, fpType, valueType });
441 auto & rvsdg = rvsdgModule->Rvsdg();
443 auto lambdaNode = LambdaNode::Create(
444 rvsdg.GetRootRegion(),
446 auto lambdaArguments = lambdaNode->GetFunctionArguments();
448 auto thetaNode = ThetaNode::create(lambdaNode->subregion());
449 auto thetaVar1 = thetaNode->AddLoopVar(lambdaArguments[0]);
450 auto thetaVar2 = thetaNode->AddLoopVar(lambdaArguments[1]);
451 auto thetaVar3 = thetaNode->AddLoopVar(lambdaArguments[2]);
452 auto thetaVar4 = thetaNode->AddLoopVar(lambdaArguments[3]);
455 auto & ctlConstant = ControlConstantOperation::createFalse(*thetaNode->subregion());
460 thetaVar1.post->divert_to(intConstant.output(0));
461 thetaVar2.post->divert_to(&ctlConstant);
462 thetaVar3.post->divert_to(fpConstant.output(0));
463 thetaVar4.post->divert_to(undefConstant);
465 auto lambdaOutput = lambdaNode->finalize(
466 { thetaVar1.output, thetaVar2.output, thetaVar3.output, thetaVar4.output });
468 GraphExport::Create(*lambdaOutput,
"test");
475 auto [constantNode, constantOp] =
477 *lambdaNode->GetFunctionResults()[0]->origin());
478 EXPECT_NE(constantOp,
nullptr);
479 EXPECT_EQ(constantOp->Representation().to_uint(), 1);
483 auto [constantNode, constantOp] =
485 *lambdaNode->GetFunctionResults()[1]->origin());
486 EXPECT_NE(constantOp,
nullptr);
487 EXPECT_EQ(constantOp->value().nalternatives(), 2);
488 EXPECT_EQ(constantOp->value().alternative(), 0);
493 *lambdaNode->GetFunctionResults()[2]->origin());
494 EXPECT_NE(constantOp,
nullptr);
495 EXPECT_EQ(constantOp->constant().convertToDouble(), 0.0);
500 *lambdaNode->GetFunctionResults()[3]->origin());
501 EXPECT_NE(constantOp,
nullptr);
502 EXPECT_EQ(constantOp->GetType(), *valueType);
506TEST(InvariantValueRedirectionTests, TestCall)
516 { controlType, valueType, valueType, ioStateType, memoryStateType },
517 { valueType, valueType, ioStateType, memoryStateType });
520 auto & rvsdg = rvsdgModule->Rvsdg();
525 rvsdg.GetRootRegion(),
528 auto controlArgument = lambdaNode->GetFunctionArguments()[0];
529 auto xArgument = lambdaNode->GetFunctionArguments()[1];
530 auto yArgument = lambdaNode->GetFunctionArguments()[2];
531 auto ioStateArgument = lambdaNode->GetFunctionArguments()[3];
532 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[4];
535 auto gammaInputX = gammaNode->AddEntryVar(xArgument);
536 auto gammaInputY = gammaNode->AddEntryVar(yArgument);
537 auto gammaInputIOState = gammaNode->AddEntryVar(ioStateArgument);
538 auto gammaInputMemoryState = gammaNode->AddEntryVar(memoryStateArgument);
540 gammaNode->AddExitVar({ gammaInputY.branchArgument[0], gammaInputY.branchArgument[1] });
542 gammaNode->AddExitVar({ gammaInputX.branchArgument[0], gammaInputX.branchArgument[1] });
543 auto gammaOutputIOState = gammaNode->AddExitVar(
544 { gammaInputIOState.branchArgument[0], gammaInputIOState.branchArgument[1] });
545 auto gammaOutputMemoryState = gammaNode->AddExitVar(
546 { gammaInputMemoryState.branchArgument[0], gammaInputMemoryState.branchArgument[1] });
548 lambdaOutputTest1 = lambdaNode->finalize({ gammaOutputX.output,
550 gammaOutputIOState.output,
551 gammaOutputMemoryState.output });
557 { valueType, valueType, ioStateType, memoryStateType },
558 { valueType, valueType, ioStateType, memoryStateType });
561 rvsdg.GetRootRegion(),
563 auto xArgument = lambdaNode->GetFunctionArguments()[0];
564 auto yArgument = lambdaNode->GetFunctionArguments()[1];
565 auto ioStateArgument = lambdaNode->GetFunctionArguments()[2];
566 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[3];
567 auto lambdaArgumentTest1 = lambdaNode->AddContextVar(*lambdaOutputTest1).inner;
575 { controlResult, xArgument, yArgument, ioStateArgument, memoryStateArgument });
577 lambdaOutputTest2 = lambdaNode->finalize(outputs(&callNode));
586 EXPECT_EQ(lambdaNode.GetFunctionResults().size(), 4u);
587 EXPECT_EQ(lambdaNode.GetFunctionResults()[0]->origin(), lambdaNode.GetFunctionArguments()[1]);
588 EXPECT_EQ(lambdaNode.GetFunctionResults()[1]->origin(), lambdaNode.GetFunctionArguments()[0]);
589 EXPECT_EQ(lambdaNode.GetFunctionResults()[2]->origin(), lambdaNode.GetFunctionArguments()[2]);
590 EXPECT_EQ(lambdaNode.GetFunctionResults()[3]->origin(), lambdaNode.GetFunctionArguments()[3]);
593TEST(InvariantValueRedirectionTests, TestCallWithMemoryStateNodes)
637 { controlType, valueType, ioStateType, memoryStateType },
638 { valueType, ioStateType, memoryStateType });
641 auto & rvsdg = rvsdgModule->Rvsdg();
646 rvsdg.GetRootRegion(),
649 auto controlArgument = lambdaNode->GetFunctionArguments()[0];
650 auto xArgument = lambdaNode->GetFunctionArguments()[1];
651 auto ioStateArgument = lambdaNode->GetFunctionArguments()[2];
652 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[3];
654 auto & lambdaEntrySplitNode =
659 auto gammaInputX = gammaNode->AddEntryVar(xArgument);
660 auto gammaInputMemoryState1 = gammaNode->AddEntryVar(lambdaEntrySplitNode.output(0));
661 auto gammaInputMemoryState2 = gammaNode->AddEntryVar(lambdaEntrySplitNode.output(1));
663 auto gammaOutputX = gammaNode->AddExitVar(gammaInputX.branchArgument);
664 auto gammaOutputMemoryState1 = gammaNode->AddExitVar(gammaInputMemoryState1.branchArgument);
665 auto gammaOutputMemoryState2 = gammaNode->AddExitVar(gammaInputMemoryState2.branchArgument);
668 *lambdaNode->subregion(),
669 { gammaOutputMemoryState1.output, gammaOutputMemoryState2.output },
672 lambdaOutputTest1 = lambdaNode->finalize(
673 { gammaOutputX.output, ioStateArgument, lambdaExitMergeNode.output(0) });
679 { valueType, ioStateType, memoryStateType },
680 { valueType, ioStateType, memoryStateType });
683 rvsdg.GetRootRegion(),
685 auto xArgument = lambdaNode->GetFunctionArguments()[0];
686 auto ioStateArgument = lambdaNode->GetFunctionArguments()[1];
687 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[2];
688 auto lambdaArgumentTest1 = lambdaNode->AddContextVar(*lambdaOutputTest1).inner;
690 auto & lambdaEntrySplitNode =
694 *lambdaNode->subregion(),
695 outputs(&lambdaEntrySplitNode),
704 { controlResult, xArgument, ioStateArgument, callEntryMergeNode.output(0) });
711 *lambdaNode->subregion(),
712 outputs(&callExitSplitNode),
715 lambdaOutputTest2 = lambdaNode->finalize({ callNode.output(0),
717 lambdaExitMergeNode.output(0) });
726 EXPECT_EQ(lambdaNode.GetFunctionResults().size(), 3u);
727 EXPECT_EQ(lambdaNode.GetFunctionResults()[0]->origin(), lambdaNode.GetFunctionArguments()[0]);
728 EXPECT_EQ(lambdaNode.GetFunctionResults()[1]->origin(), lambdaNode.GetFunctionArguments()[1]);
733 EXPECT_TRUE(lambdaEntrySplit && lambdaEntrySplit->noutputs() == 2);
734 EXPECT_TRUE(lambdaExitMerge && lambdaExitMerge->ninputs() == 2);
735 EXPECT_EQ(lambdaExitMerge->input(0)->origin(), lambdaEntrySplit->output(1));
736 EXPECT_EQ(lambdaExitMerge->input(1)->origin(), lambdaEntrySplit->output(0));
739TEST(InvariantValueRedirectionTests, TestCallWithMissingMemoryStateNodes)
750 auto valueType = TestType::createValueType();
751 auto int32Type = BitType::Create(32);
752 auto functionType = FunctionType::Create(
753 { valueType, ioStateType, memoryStateType },
754 { int32Type, ioStateType, memoryStateType });
757 auto & rvsdg = rvsdgModule->Rvsdg();
759 Output * lambdaOutputTest1 =
nullptr;
761 auto lambdaNode = LambdaNode::Create(
762 rvsdg.GetRootRegion(),
765 auto xArgument = lambdaNode->GetFunctionArguments()[0];
766 auto ioStateArgument = lambdaNode->GetFunctionArguments()[1];
767 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[2];
776 { memoryStateArgument },
780 *lambdaNode->subregion(),
781 { storeNode.output(0) },
784 lambdaOutputTest1 = lambdaNode->finalize(
785 { zeroNode.output(0), ioStateArgument, lambdaExitMergeNode.output(0) });
788 Output * lambdaOutputTest2 =
nullptr;
790 auto lambdaNode = LambdaNode::Create(
791 rvsdg.GetRootRegion(),
793 auto xArgument = lambdaNode->GetFunctionArguments()[0];
794 auto ioStateArgument = lambdaNode->GetFunctionArguments()[1];
795 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[2];
796 auto lambdaArgumentTest = lambdaNode->AddContextVar(*lambdaOutputTest1).inner;
798 auto & lambdaEntrySplitNode =
802 *lambdaNode->subregion(),
803 outputs(&lambdaEntrySplitNode),
809 { xArgument, ioStateArgument, callEntryMergeNode.output(0) });
816 *lambdaNode->subregion(),
817 outputs(&callExitSplitNode),
820 lambdaOutputTest2 = lambdaNode->finalize({ callNode.output(0),
822 lambdaExitMergeNode.output(0) });
823 GraphExport::Create(*lambdaOutputTest2,
"test2");
826 std::cout << view(&rvsdg.GetRootRegion()) << std::flush;
830 std::cout << view(&rvsdg.GetRootRegion()) << std::flush;
834 const auto & lambdaNode1 = AssertGetOwnerNode<LambdaNode>(*lambdaOutputTest1);
837 EXPECT_EQ(lambdaEntrySplit1,
nullptr);
838 EXPECT_TRUE(lambdaExitMerge1 && lambdaExitMerge1->ninputs() == 1);
840 const auto & lambdaNode2 = AssertGetOwnerNode<LambdaNode>(*lambdaOutputTest2);
843 EXPECT_TRUE(lambdaEntrySplit2 && lambdaEntrySplit2->noutputs() == 1);
844 EXPECT_TRUE(lambdaExitMerge2 && lambdaExitMerge2->ninputs() == 1);
845 const auto & [callExitSplitNode, _] =
846 TryGetSimpleNodeAndOptionalOp<CallExitMemoryStateSplitOperation>(
847 *lambdaExitMerge2->input(0)->origin());
848 EXPECT_EQ(callExitSplitNode->noutputs(), 1u);
849 const auto & [callNode, calOperation] =
850 TryGetSimpleNodeAndOptionalOp<CallOperation>(*callExitSplitNode->input(0)->origin());
851 EXPECT_EQ(callNode->noutputs(), 3u);
852 EXPECT_EQ(callNode->ninputs(), 4u);
854 const auto & [callEntryMergeNode, callEntryMergeOperation] =
855 TryGetSimpleNodeAndOptionalOp<CallEntryMemoryStateMergeOperation>(*memoryStateInput.origin());
856 EXPECT_EQ(callEntryMergeNode->ninputs(), 1u);
857 EXPECT_EQ(callEntryMergeNode->input(0)->origin(), lambdaEntrySplit2->output(0));
860TEST(InvariantValueRedirectionTests, TestCallWithDifferentExternalCompression)
915 const auto functionType =
916 FunctionType::Create({ ioStateType, memoryStateType }, { ioStateType, memoryStateType });
919 auto & rvsdg = rvsdgModule->Rvsdg();
921 Output * callee0Output =
nullptr;
923 auto lambdaNode = LambdaNode::Create(
924 rvsdg.GetRootRegion(),
927 auto ioStateArgument = lambdaNode->GetFunctionArguments()[0];
928 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[1];
930 auto & lambdaEntrySplitNode =
932 auto modifiedExternal = TestOperation::createNode(
933 lambdaNode->subregion(),
934 { lambdaEntrySplitNode.output(0) },
935 { memoryStateType });
937 *lambdaNode->subregion(),
938 { modifiedExternal->output(0),
939 lambdaEntrySplitNode.output(1),
940 lambdaEntrySplitNode.output(2) },
943 callee0Output = lambdaNode->finalize({ ioStateArgument, lambdaExitMergeNode.output(0) });
946 Output * callee3Output =
nullptr;
948 auto lambdaNode = LambdaNode::Create(
949 rvsdg.GetRootRegion(),
952 auto ioStateArgument = lambdaNode->GetFunctionArguments()[0];
953 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[1];
955 auto & lambdaEntrySplitNode =
957 auto modifiedMemory3 = TestOperation::createNode(
958 lambdaNode->subregion(),
959 { lambdaEntrySplitNode.output(2) },
960 { memoryStateType });
962 *lambdaNode->subregion(),
963 { lambdaEntrySplitNode.output(0),
964 lambdaEntrySplitNode.output(1),
965 modifiedMemory3->output(0) },
968 callee3Output = lambdaNode->finalize({ ioStateArgument, lambdaExitMergeNode.output(0) });
978 auto lambdaNode = LambdaNode::Create(
979 rvsdg.GetRootRegion(),
982 auto ioStateArgument = lambdaNode->GetFunctionArguments()[0];
983 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[1];
984 auto callee0Argument = lambdaNode->AddContextVar(*callee0Output).inner;
985 auto callee3Argument = lambdaNode->AddContextVar(*callee3Output).inner;
987 lambdaEntrySplitNode =
991 *lambdaNode->subregion(),
992 outputs(lambdaEntrySplitNode),
997 { ioStateArgument, callEntryMergeNodeA->output(0) });
1003 *lambdaNode->subregion(),
1004 outputs(callExitSplitNodeA),
1015 *lambdaNode->subregion(),
1016 outputs(callExitSplitNodeB),
1019 lambdaNode->finalize(
1027 ASSERT_EQ(lambdaEntrySplitNode->
noutputs(), 3u);
1028 ASSERT_EQ(callEntryMergeNodeA->
ninputs(), 3u);
1029 ASSERT_EQ(callExitSplitNodeA->
noutputs(), 3u);
1030 ASSERT_EQ(callEntryMergeNodeB->
ninputs(), 3u);
1031 ASSERT_EQ(callExitSplitNodeB->
noutputs(), 3u);
1032 ASSERT_EQ(lambdaExitMergeNode->
ninputs(), 3u);
1035 EXPECT_EQ(callEntryMergeNodeA->
input(0)->
origin(), lambdaEntrySplitNode->
output(0));
1036 EXPECT_EQ(callEntryMergeNodeB->
input(0)->
origin(), callExitSplitNodeA->
output(0));
1037 EXPECT_EQ(lambdaExitMergeNode->
input(0)->
origin(), callExitSplitNodeB->
output(0));
1040 EXPECT_EQ(callEntryMergeNodeA->
input(1)->
origin(), lambdaEntrySplitNode->
output(1));
1041 EXPECT_EQ(callEntryMergeNodeB->
input(1)->
origin(), lambdaEntrySplitNode->
output(1));
1042 EXPECT_EQ(lambdaExitMergeNode->
input(1)->
origin(), lambdaEntrySplitNode->
output(1));
1045 EXPECT_EQ(callEntryMergeNodeA->
input(2)->
origin(), lambdaEntrySplitNode->
output(2));
1046 EXPECT_EQ(callEntryMergeNodeB->
input(2)->
origin(), callExitSplitNodeA->
output(2));
1047 EXPECT_EQ(lambdaExitMergeNode->
input(2)->
origin(), callExitSplitNodeA->
output(2));
1069TEST(InvariantValueRedirectionTests, testThetaGammaRedirection)
1075 auto valueType = TestType::createValueType();
1076 auto controlType = ControlType::Create(2);
1077 const auto functionType = FunctionType::Create({ valueType, valueType }, { valueType });
1080 auto & rvsdg = rvsdgModule->Rvsdg();
1082 auto lambdaNode = LambdaNode::Create(
1083 rvsdg.GetRootRegion(),
1086 auto functionArgument0 = lambdaNode->GetFunctionArguments()[0];
1087 auto functionArgument1 = lambdaNode->GetFunctionArguments()[1];
1089 auto thetaNode = ThetaNode::create(lambdaNode->subregion());
1090 auto loopVar0 = thetaNode->AddLoopVar(functionArgument0);
1091 auto loopVar1 = thetaNode->AddLoopVar(functionArgument1);
1093 auto dummyNodeTheta = TestOperation::createNode(thetaNode->subregion(), {}, { valueType });
1096 TestOperation::createNode(thetaNode->subregion(), {}, { controlType })->output(0);
1097 auto gammaNode = GammaNode::create(predicate, 2);
1098 auto entryVar0 = gammaNode->AddEntryVar(loopVar0.pre);
1099 auto entryVar1 = gammaNode->AddEntryVar(dummyNodeTheta->output(0));
1101 auto dummyNodeGamma0 = TestOperation::createNode(gammaNode->subregion(0), {}, { valueType });
1102 auto dummyNodeGamma1 = TestOperation::createNode(gammaNode->subregion(1), {}, { valueType });
1104 auto controlConstant0 =
1106 auto controlConstant1 =
1109 auto controlExitVar = gammaNode->AddExitVar({ controlConstant0, controlConstant1 });
1111 gammaNode->AddExitVar({ dummyNodeGamma0->output(0), entryVar0.branchArgument[1] });
1113 gammaNode->AddExitVar({ entryVar1.branchArgument[0], dummyNodeGamma1->output(0) });
1115 thetaNode->predicate()->divert_to(controlExitVar.output);
1116 loopVar0.post->divert_to(exitVar0.output);
1117 loopVar1.post->divert_to(exitVar1.output);
1119 auto lambdaOutput = lambdaNode->finalize({ loopVar1.output });
1121 GraphExport::Create(*lambdaOutput,
"test");
1129 auto loopVars = thetaNode->GetLoopVars();
1130 EXPECT_EQ(loopVars.size(), 2u);
1137 EXPECT_EQ(loopVars[0].post->origin(), loopVars[0].pre);
1145 EXPECT_EQ(loopVars[1].post->origin(), dummyNodeTheta->output(0));
1148TEST(InvariantValueRedirectionTests, testLoadWithDeadLoadedValue)
1154 const auto valueType = TestType::createValueType();
1157 const auto functionType = FunctionType::Create(
1158 { pointerType, memoryStateType, memoryStateType },
1159 { memoryStateType, memoryStateType });
1162 auto & rvsdg = rvsdgModule->Rvsdg();
1164 auto lambdaNode = LambdaNode::Create(
1165 rvsdg.GetRootRegion(),
1168 auto addressArgument = lambdaNode->GetFunctionArguments()[0];
1169 auto memoryStateArgument1 = lambdaNode->GetFunctionArguments()[1];
1170 auto memoryStateArgument2 = lambdaNode->GetFunctionArguments()[2];
1174 { memoryStateArgument1, memoryStateArgument2 },
1178 auto lambdaOutput = lambdaNode->finalize({ loadNode.output(1), loadNode.output(2) });
1180 GraphExport::Create(*lambdaOutput,
"test");
1189 EXPECT_EQ(lambdaNode->subregion()->numNodes(), 0u);
1190 EXPECT_EQ(lambdaNode->GetFunctionResults()[0]->origin(), memoryStateArgument1);
1191 EXPECT_EQ(lambdaNode->GetFunctionResults()[1]->origin(), memoryStateArgument2);
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, const std::vector< rvsdg::Output * > &operands, std::vector< MemoryNodeId > memoryNodeIds)
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &operand, std::vector< MemoryNodeId > memoryNodeIds)