40TEST(InvariantValueRedirectionTests, TestGamma)
48 { controlType, valueType, valueType },
49 { valueType, valueType });
52 auto & rvsdg = rvsdgModule->Rvsdg();
55 rvsdg.GetRootRegion(),
58 auto c = lambdaNode->GetFunctionArguments()[0];
59 auto x = lambdaNode->GetFunctionArguments()[1];
60 auto y = lambdaNode->GetFunctionArguments()[2];
63 auto gammaInput1 = gammaNode1->AddEntryVar(c);
64 auto gammaInput2 = gammaNode1->AddEntryVar(x);
65 auto gammaInput3 = gammaNode1->AddEntryVar(y);
68 auto gammaInput4 = gammaNode2->AddEntryVar(gammaInput2.branchArgument[0]);
69 auto gammaInput5 = gammaNode2->AddEntryVar(gammaInput3.branchArgument[0]);
70 gammaNode2->AddExitVar(gammaInput4.branchArgument);
71 gammaNode2->AddExitVar(gammaInput5.branchArgument);
73 gammaNode1->AddExitVar({ gammaNode2->output(0), gammaInput2.branchArgument[1] });
74 gammaNode1->AddExitVar({ gammaNode2->output(1), gammaInput3.branchArgument[1] });
76 auto lambdaOutput = lambdaNode->finalize({ gammaNode1->output(0), gammaNode1->output(1) });
84 EXPECT_EQ(lambdaNode->GetFunctionResults()[0]->origin(), x);
85 EXPECT_EQ(lambdaNode->GetFunctionResults()[1]->origin(), y);
88TEST(InvariantValueRedirectionTests, TestTheta)
93 auto ioStateType = IOStateType::Create();
97 { controlType, valueType, ioStateType },
98 { controlType, valueType, ioStateType });
101 auto & rvsdg = rvsdgModule->Rvsdg();
104 rvsdg.GetRootRegion(),
107 auto c = lambdaNode->GetFunctionArguments()[0];
108 auto x = lambdaNode->GetFunctionArguments()[1];
109 auto l = lambdaNode->GetFunctionArguments()[2];
112 auto thetaVar1 = thetaNode1->AddLoopVar(c);
113 auto thetaVar2 = thetaNode1->AddLoopVar(x);
114 auto thetaVar3 = thetaNode1->AddLoopVar(l);
117 auto thetaVar4 = thetaNode2->AddLoopVar(thetaVar1.pre);
118 thetaNode2->AddLoopVar(thetaVar2.pre);
119 auto thetaVar5 = thetaNode2->AddLoopVar(thetaVar3.pre);
120 thetaNode2->set_predicate(thetaVar4.pre);
122 thetaVar3.post->divert_to(thetaVar5.output);
123 thetaNode1->set_predicate(thetaVar1.pre);
126 lambdaNode->finalize({ thetaVar1.output, thetaVar2.output, thetaVar3.output });
134 EXPECT_EQ(lambdaNode->GetFunctionResults()[0]->origin(), c);
135 EXPECT_EQ(lambdaNode->GetFunctionResults()[1]->origin(), x);
136 EXPECT_EQ(lambdaNode->GetFunctionResults()[2]->origin(), thetaVar3.output);
139TEST(InvariantValueRedirectionTests, TestCall)
144 auto ioStateType = IOStateType::Create();
145 auto memoryStateType = MemoryStateType::Create();
149 { controlType, valueType, valueType, ioStateType, memoryStateType },
150 { valueType, valueType, ioStateType, memoryStateType });
153 auto & rvsdg = rvsdgModule->Rvsdg();
158 rvsdg.GetRootRegion(),
159 LlvmLambdaOperation::Create(functionTypeTest1,
"test1", Linkage::externalLinkage));
161 auto controlArgument = lambdaNode->GetFunctionArguments()[0];
162 auto xArgument = lambdaNode->GetFunctionArguments()[1];
163 auto yArgument = lambdaNode->GetFunctionArguments()[2];
164 auto ioStateArgument = lambdaNode->GetFunctionArguments()[3];
165 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[4];
168 auto gammaInputX = gammaNode->AddEntryVar(xArgument);
169 auto gammaInputY = gammaNode->AddEntryVar(yArgument);
170 auto gammaInputIOState = gammaNode->AddEntryVar(ioStateArgument);
171 auto gammaInputMemoryState = gammaNode->AddEntryVar(memoryStateArgument);
173 gammaNode->AddExitVar({ gammaInputY.branchArgument[0], gammaInputY.branchArgument[1] });
175 gammaNode->AddExitVar({ gammaInputX.branchArgument[0], gammaInputX.branchArgument[1] });
176 auto gammaOutputIOState = gammaNode->AddExitVar(
177 { gammaInputIOState.branchArgument[0], gammaInputIOState.branchArgument[1] });
178 auto gammaOutputMemoryState = gammaNode->AddExitVar(
179 { gammaInputMemoryState.branchArgument[0], gammaInputMemoryState.branchArgument[1] });
181 lambdaOutputTest1 = lambdaNode->finalize({ gammaOutputX.output,
183 gammaOutputIOState.output,
184 gammaOutputMemoryState.output });
190 { valueType, valueType, ioStateType, memoryStateType },
191 { valueType, valueType, ioStateType, memoryStateType });
194 rvsdg.GetRootRegion(),
195 LlvmLambdaOperation::Create(functionType,
"test2", Linkage::externalLinkage));
196 auto xArgument = lambdaNode->GetFunctionArguments()[0];
197 auto yArgument = lambdaNode->GetFunctionArguments()[1];
198 auto ioStateArgument = lambdaNode->GetFunctionArguments()[2];
199 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[3];
200 auto lambdaArgumentTest1 = lambdaNode->AddContextVar(*lambdaOutputTest1).inner;
205 auto & callNode = CallOperation::CreateNode(
208 { controlResult, xArgument, yArgument, ioStateArgument, memoryStateArgument });
210 lambdaOutputTest2 = lambdaNode->finalize(outputs(&callNode));
219 EXPECT_EQ(lambdaNode.GetFunctionResults().size(), 4u);
220 EXPECT_EQ(lambdaNode.GetFunctionResults()[0]->origin(), lambdaNode.GetFunctionArguments()[1]);
221 EXPECT_EQ(lambdaNode.GetFunctionResults()[1]->origin(), lambdaNode.GetFunctionArguments()[0]);
222 EXPECT_EQ(lambdaNode.GetFunctionResults()[2]->origin(), lambdaNode.GetFunctionArguments()[2]);
223 EXPECT_EQ(lambdaNode.GetFunctionResults()[3]->origin(), lambdaNode.GetFunctionArguments()[3]);
226TEST(InvariantValueRedirectionTests, TestCallWithMemoryStateNodes)
263 EXPECT_EQ(aa::PointsToGraph::externalMemoryNode, 0u);
265 auto ioStateType = IOStateType::Create();
266 auto memoryStateType = MemoryStateType::Create();
270 { controlType, valueType, ioStateType, memoryStateType },
271 { valueType, ioStateType, memoryStateType });
274 auto & rvsdg = rvsdgModule->Rvsdg();
279 rvsdg.GetRootRegion(),
280 LlvmLambdaOperation::Create(functionTypeTest1,
"test1", Linkage::externalLinkage));
282 auto controlArgument = lambdaNode->GetFunctionArguments()[0];
283 auto xArgument = lambdaNode->GetFunctionArguments()[1];
284 auto ioStateArgument = lambdaNode->GetFunctionArguments()[2];
285 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[3];
287 auto & lambdaEntrySplitNode =
288 LambdaEntryMemoryStateSplitOperation::CreateNode(*memoryStateArgument, { 1, 2 });
292 auto gammaInputX = gammaNode->AddEntryVar(xArgument);
293 auto gammaInputMemoryState1 = gammaNode->AddEntryVar(lambdaEntrySplitNode.output(0));
294 auto gammaInputMemoryState2 = gammaNode->AddEntryVar(lambdaEntrySplitNode.output(1));
296 auto gammaOutputX = gammaNode->AddExitVar(gammaInputX.branchArgument);
297 auto gammaOutputMemoryState1 = gammaNode->AddExitVar(gammaInputMemoryState1.branchArgument);
298 auto gammaOutputMemoryState2 = gammaNode->AddExitVar(gammaInputMemoryState2.branchArgument);
300 auto & lambdaExitMergeNode = LambdaExitMemoryStateMergeOperation::CreateNode(
301 *lambdaNode->subregion(),
302 { gammaOutputMemoryState1.output, gammaOutputMemoryState2.output },
305 lambdaOutputTest1 = lambdaNode->finalize(
306 { gammaOutputX.output, ioStateArgument, lambdaExitMergeNode.output(0) });
312 { valueType, ioStateType, memoryStateType },
313 { valueType, ioStateType, memoryStateType });
316 rvsdg.GetRootRegion(),
317 LlvmLambdaOperation::Create(functionType,
"test2", Linkage::externalLinkage));
318 auto xArgument = lambdaNode->GetFunctionArguments()[0];
319 auto ioStateArgument = lambdaNode->GetFunctionArguments()[1];
320 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[2];
321 auto lambdaArgumentTest1 = lambdaNode->AddContextVar(*lambdaOutputTest1).inner;
323 auto & lambdaEntrySplitNode =
324 LambdaEntryMemoryStateSplitOperation::CreateNode(*memoryStateArgument, { 1, 2 });
326 auto & callEntryMergeNode = CallEntryMemoryStateMergeOperation::CreateNode(
327 *lambdaNode->subregion(),
328 outputs(&lambdaEntrySplitNode),
334 auto & callNode = CallOperation::CreateNode(
337 { controlResult, xArgument, ioStateArgument, callEntryMergeNode.output(0) });
339 auto & callExitSplitNode = CallExitMemoryStateSplitOperation::CreateNode(
340 CallOperation::GetMemoryStateOutput(callNode),
343 auto & lambdaExitMergeNode = LambdaExitMemoryStateMergeOperation::CreateNode(
344 *lambdaNode->subregion(),
345 outputs(&callExitSplitNode),
348 lambdaOutputTest2 = lambdaNode->finalize({ callNode.output(0),
349 &CallOperation::GetIOStateOutput(callNode),
350 lambdaExitMergeNode.output(0) });
359 EXPECT_EQ(lambdaNode.GetFunctionResults().size(), 3u);
360 EXPECT_EQ(lambdaNode.GetFunctionResults()[0]->origin(), lambdaNode.GetFunctionArguments()[0]);
361 EXPECT_EQ(lambdaNode.GetFunctionResults()[1]->origin(), lambdaNode.GetFunctionArguments()[1]);
363 auto lambdaEntrySplit = tryGetMemoryStateEntrySplit(lambdaNode);
364 auto lambdaExitMerge = tryGetMemoryStateExitMerge(lambdaNode);
366 EXPECT_TRUE(lambdaEntrySplit && lambdaEntrySplit->noutputs() == 2);
367 EXPECT_TRUE(lambdaExitMerge && lambdaExitMerge->ninputs() == 2);
368 EXPECT_EQ(lambdaExitMerge->input(0)->origin(), lambdaEntrySplit->output(1));
369 EXPECT_EQ(lambdaExitMerge->input(1)->origin(), lambdaEntrySplit->output(0));
372TEST(InvariantValueRedirectionTests, TestCallWithMissingMemoryStateNodes)
379 EXPECT_EQ(aa::PointsToGraph::externalMemoryNode, 0u);
381 auto ioStateType = IOStateType::Create();
382 auto memoryStateType = MemoryStateType::Create();
383 auto valueType = TestType::createValueType();
384 auto int32Type = BitType::Create(32);
385 auto functionType = FunctionType::Create(
386 { valueType, ioStateType, memoryStateType },
387 { int32Type, ioStateType, memoryStateType });
390 auto & rvsdg = rvsdgModule->Rvsdg();
392 Output * lambdaOutputTest1 =
nullptr;
394 auto lambdaNode = LambdaNode::Create(
395 rvsdg.GetRootRegion(),
396 LlvmLambdaOperation::Create(functionType,
"test", Linkage::externalLinkage));
398 auto xArgument = lambdaNode->GetFunctionArguments()[0];
399 auto ioStateArgument = lambdaNode->GetFunctionArguments()[1];
400 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[2];
402 auto & zeroNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 0);
403 auto & oneNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 1);
404 auto allocaResults = AllocaOperation::create(valueType, oneNode.output(0), 4);
406 auto & storeNode = StoreNonVolatileOperation::CreateNode(
409 { memoryStateArgument },
412 auto & lambdaExitMergeNode = LambdaExitMemoryStateMergeOperation::CreateNode(
413 *lambdaNode->subregion(),
414 { storeNode.output(0) },
417 lambdaOutputTest1 = lambdaNode->finalize(
418 { zeroNode.output(0), ioStateArgument, lambdaExitMergeNode.output(0) });
421 Output * lambdaOutputTest2 =
nullptr;
423 auto lambdaNode = LambdaNode::Create(
424 rvsdg.GetRootRegion(),
425 LlvmLambdaOperation::Create(functionType,
"test2", Linkage::externalLinkage));
426 auto xArgument = lambdaNode->GetFunctionArguments()[0];
427 auto ioStateArgument = lambdaNode->GetFunctionArguments()[1];
428 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[2];
429 auto lambdaArgumentTest = lambdaNode->AddContextVar(*lambdaOutputTest1).inner;
431 auto & lambdaEntrySplitNode =
432 LambdaEntryMemoryStateSplitOperation::CreateNode(*memoryStateArgument, { 1 });
434 auto & callEntryMergeNode = CallEntryMemoryStateMergeOperation::CreateNode(
435 *lambdaNode->subregion(),
436 outputs(&lambdaEntrySplitNode),
439 auto & callNode = CallOperation::CreateNode(
442 { xArgument, ioStateArgument, callEntryMergeNode.output(0) });
444 auto & callExitSplitNode = CallExitMemoryStateSplitOperation::CreateNode(
445 CallOperation::GetMemoryStateOutput(callNode),
448 auto & lambdaExitMergeNode = LambdaExitMemoryStateMergeOperation::CreateNode(
449 *lambdaNode->subregion(),
450 outputs(&callExitSplitNode),
453 lambdaOutputTest2 = lambdaNode->finalize({ callNode.output(0),
454 &CallOperation::GetIOStateOutput(callNode),
455 lambdaExitMergeNode.output(0) });
456 GraphExport::Create(*lambdaOutputTest2,
"test2");
459 std::cout << view(&rvsdg.GetRootRegion()) << std::flush;
463 std::cout << view(&rvsdg.GetRootRegion()) << std::flush;
467 const auto & lambdaNode1 = AssertGetOwnerNode<LambdaNode>(*lambdaOutputTest1);
468 const auto lambdaEntrySplit1 = tryGetMemoryStateEntrySplit(lambdaNode1);
469 const auto lambdaExitMerge1 = tryGetMemoryStateExitMerge(lambdaNode1);
470 EXPECT_EQ(lambdaEntrySplit1,
nullptr);
471 EXPECT_TRUE(lambdaExitMerge1 && lambdaExitMerge1->ninputs() == 1);
473 const auto & lambdaNode2 = AssertGetOwnerNode<LambdaNode>(*lambdaOutputTest2);
474 const auto lambdaEntrySplit2 = tryGetMemoryStateEntrySplit(lambdaNode2);
475 const auto lambdaExitMerge2 = tryGetMemoryStateExitMerge(lambdaNode2);
476 EXPECT_TRUE(lambdaEntrySplit2 && lambdaEntrySplit2->noutputs() == 1);
477 EXPECT_TRUE(lambdaExitMerge2 && lambdaExitMerge2->ninputs() == 1);
478 const auto & [callExitSplitNode, _] =
479 TryGetSimpleNodeAndOptionalOp<CallExitMemoryStateSplitOperation>(
480 *lambdaExitMerge2->input(0)->origin());
481 EXPECT_EQ(callExitSplitNode->noutputs(), 1u);
482 const auto & [callNode, calOperation] =
483 TryGetSimpleNodeAndOptionalOp<CallOperation>(*callExitSplitNode->input(0)->origin());
484 EXPECT_EQ(callNode->noutputs(), 3u);
485 EXPECT_EQ(callNode->ninputs(), 4u);
486 const auto & memoryStateInput = CallOperation::GetMemoryStateInput(*callNode);
487 const auto & [callEntryMergeNode, callEntryMergeOperation] =
488 TryGetSimpleNodeAndOptionalOp<CallEntryMemoryStateMergeOperation>(*memoryStateInput.origin());
489 EXPECT_EQ(callEntryMergeNode->ninputs(), 1u);
490 EXPECT_EQ(callEntryMergeNode->input(0)->origin(), lambdaEntrySplit2->output(0));
493TEST(InvariantValueRedirectionTests, TestCallWithDifferentExternalCompression)
544 EXPECT_EQ(aa::PointsToGraph::externalMemoryNode, 0u);
546 const auto ioStateType = IOStateType::Create();
547 const auto memoryStateType = MemoryStateType::Create();
548 const auto functionType =
549 FunctionType::Create({ ioStateType, memoryStateType }, { ioStateType, memoryStateType });
552 auto & rvsdg = rvsdgModule->Rvsdg();
554 Output * callee0Output =
nullptr;
556 auto lambdaNode = LambdaNode::Create(
557 rvsdg.GetRootRegion(),
558 LlvmLambdaOperation::Create(functionType,
"callee0", Linkage::externalLinkage));
560 auto ioStateArgument = lambdaNode->GetFunctionArguments()[0];
561 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[1];
563 auto & lambdaEntrySplitNode =
564 LambdaEntryMemoryStateSplitOperation::CreateNode(*memoryStateArgument, { 0, 1, 3 });
565 auto modifiedExternal = TestOperation::createNode(
566 lambdaNode->subregion(),
567 { lambdaEntrySplitNode.output(0) },
568 { memoryStateType });
569 auto & lambdaExitMergeNode = LambdaExitMemoryStateMergeOperation::CreateNode(
570 *lambdaNode->subregion(),
571 { modifiedExternal->output(0),
572 lambdaEntrySplitNode.output(1),
573 lambdaEntrySplitNode.output(2) },
576 callee0Output = lambdaNode->finalize({ ioStateArgument, lambdaExitMergeNode.output(0) });
579 Output * callee3Output =
nullptr;
581 auto lambdaNode = LambdaNode::Create(
582 rvsdg.GetRootRegion(),
583 LlvmLambdaOperation::Create(functionType,
"callee3", Linkage::externalLinkage));
585 auto ioStateArgument = lambdaNode->GetFunctionArguments()[0];
586 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[1];
588 auto & lambdaEntrySplitNode =
589 LambdaEntryMemoryStateSplitOperation::CreateNode(*memoryStateArgument, { 0, 1, 3 });
590 auto modifiedMemory3 = TestOperation::createNode(
591 lambdaNode->subregion(),
592 { lambdaEntrySplitNode.output(2) },
593 { memoryStateType });
594 auto & lambdaExitMergeNode = LambdaExitMemoryStateMergeOperation::CreateNode(
595 *lambdaNode->subregion(),
596 { lambdaEntrySplitNode.output(0),
597 lambdaEntrySplitNode.output(1),
598 modifiedMemory3->output(0) },
601 callee3Output = lambdaNode->finalize({ ioStateArgument, lambdaExitMergeNode.output(0) });
611 auto lambdaNode = LambdaNode::Create(
612 rvsdg.GetRootRegion(),
613 LlvmLambdaOperation::Create(functionType,
"caller", Linkage::externalLinkage));
615 auto ioStateArgument = lambdaNode->GetFunctionArguments()[0];
616 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[1];
617 auto callee0Argument = lambdaNode->AddContextVar(*callee0Output).inner;
618 auto callee3Argument = lambdaNode->AddContextVar(*callee3Output).inner;
620 lambdaEntrySplitNode =
621 &LambdaEntryMemoryStateSplitOperation::CreateNode(*memoryStateArgument, { 0, 1, 2 });
623 callEntryMergeNodeA = &CallEntryMemoryStateMergeOperation::CreateNode(
624 *lambdaNode->subregion(),
625 outputs(lambdaEntrySplitNode),
627 auto & callNodeA = CallOperation::CreateNode(
630 { ioStateArgument, callEntryMergeNodeA->output(0) });
631 callExitSplitNodeA = &CallExitMemoryStateSplitOperation::CreateNode(
632 CallOperation::GetMemoryStateOutput(callNodeA),
635 callEntryMergeNodeB = &CallEntryMemoryStateMergeOperation::CreateNode(
636 *lambdaNode->subregion(),
637 outputs(callExitSplitNodeA),
639 auto & callNodeB = CallOperation::CreateNode(
642 { &CallOperation::GetIOStateOutput(callNodeA), callEntryMergeNodeB->output(0) });
643 callExitSplitNodeB = &CallExitMemoryStateSplitOperation::CreateNode(
644 CallOperation::GetMemoryStateOutput(callNodeB),
647 lambdaExitMergeNode = &LambdaExitMemoryStateMergeOperation::CreateNode(
648 *lambdaNode->subregion(),
649 outputs(callExitSplitNodeB),
652 lambdaNode->finalize(
653 { &CallOperation::GetIOStateOutput(callNodeB), lambdaExitMergeNode->output(0) });
660 ASSERT_EQ(lambdaEntrySplitNode->
noutputs(), 3u);
661 ASSERT_EQ(callEntryMergeNodeA->
ninputs(), 3u);
662 ASSERT_EQ(callExitSplitNodeA->
noutputs(), 3u);
663 ASSERT_EQ(callEntryMergeNodeB->
ninputs(), 3u);
664 ASSERT_EQ(callExitSplitNodeB->
noutputs(), 3u);
665 ASSERT_EQ(lambdaExitMergeNode->
ninputs(), 3u);
668 EXPECT_EQ(callEntryMergeNodeA->
input(0)->
origin(), lambdaEntrySplitNode->
output(0));
669 EXPECT_EQ(callEntryMergeNodeB->
input(0)->
origin(), callExitSplitNodeA->
output(0));
670 EXPECT_EQ(lambdaExitMergeNode->
input(0)->
origin(), callExitSplitNodeB->
output(0));
673 EXPECT_EQ(callEntryMergeNodeA->
input(1)->
origin(), lambdaEntrySplitNode->
output(1));
674 EXPECT_EQ(callEntryMergeNodeB->
input(1)->
origin(), lambdaEntrySplitNode->
output(1));
675 EXPECT_EQ(lambdaExitMergeNode->
input(1)->
origin(), lambdaEntrySplitNode->
output(1));
678 EXPECT_EQ(callEntryMergeNodeA->
input(2)->
origin(), lambdaEntrySplitNode->
output(2));
679 EXPECT_EQ(callEntryMergeNodeB->
input(2)->
origin(), callExitSplitNodeA->
output(2));
680 EXPECT_EQ(lambdaExitMergeNode->
input(2)->
origin(), callExitSplitNodeA->
output(2));
702TEST(InvariantValueRedirectionTests, testThetaGammaRedirection)
708 auto valueType = TestType::createValueType();
709 auto controlType = ControlType::Create(2);
710 const auto functionType = FunctionType::Create({ valueType, valueType }, { valueType });
713 auto & rvsdg = rvsdgModule->Rvsdg();
715 auto lambdaNode = LambdaNode::Create(
716 rvsdg.GetRootRegion(),
717 LlvmLambdaOperation::Create(functionType,
"test", Linkage::externalLinkage));
719 auto functionArgument0 = lambdaNode->GetFunctionArguments()[0];
720 auto functionArgument1 = lambdaNode->GetFunctionArguments()[1];
722 auto thetaNode = ThetaNode::create(lambdaNode->subregion());
723 auto loopVar0 = thetaNode->AddLoopVar(functionArgument0);
724 auto loopVar1 = thetaNode->AddLoopVar(functionArgument1);
726 auto dummyNodeTheta = TestOperation::createNode(thetaNode->subregion(), {}, { valueType });
729 TestOperation::createNode(thetaNode->subregion(), {}, { controlType })->output(0);
730 auto gammaNode = GammaNode::create(predicate, 2);
731 auto entryVar0 = gammaNode->AddEntryVar(loopVar0.pre);
732 auto entryVar1 = gammaNode->AddEntryVar(dummyNodeTheta->output(0));
734 auto dummyNodeGamma0 = TestOperation::createNode(gammaNode->subregion(0), {}, { valueType });
735 auto dummyNodeGamma1 = TestOperation::createNode(gammaNode->subregion(1), {}, { valueType });
737 auto controlConstant0 =
739 auto controlConstant1 =
742 auto controlExitVar = gammaNode->AddExitVar({ controlConstant0, controlConstant1 });
744 gammaNode->AddExitVar({ dummyNodeGamma0->output(0), entryVar0.branchArgument[1] });
746 gammaNode->AddExitVar({ entryVar1.branchArgument[0], dummyNodeGamma1->output(0) });
748 thetaNode->predicate()->divert_to(controlExitVar.output);
749 loopVar0.post->divert_to(exitVar0.output);
750 loopVar1.post->divert_to(exitVar1.output);
752 auto lambdaOutput = lambdaNode->finalize({ loopVar1.output });
754 GraphExport::Create(*lambdaOutput,
"test");
762 auto loopVars = thetaNode->GetLoopVars();
763 EXPECT_EQ(loopVars.size(), 2u);
770 EXPECT_EQ(loopVars[0].post->origin(), loopVars[0].pre);
778 EXPECT_EQ(loopVars[1].post->origin(), dummyNodeTheta->output(0));
781TEST(InvariantValueRedirectionTests, testLoadWithDeadLoadedValue)
787 const auto valueType = TestType::createValueType();
788 const auto pointerType = PointerType::Create();
789 const auto memoryStateType = MemoryStateType::Create();
790 const auto functionType = FunctionType::Create(
791 { pointerType, memoryStateType, memoryStateType },
792 { memoryStateType, memoryStateType });
795 auto & rvsdg = rvsdgModule->Rvsdg();
797 auto lambdaNode = LambdaNode::Create(
798 rvsdg.GetRootRegion(),
799 LlvmLambdaOperation::Create(functionType,
"test", Linkage::externalLinkage));
801 auto addressArgument = lambdaNode->GetFunctionArguments()[0];
802 auto memoryStateArgument1 = lambdaNode->GetFunctionArguments()[1];
803 auto memoryStateArgument2 = lambdaNode->GetFunctionArguments()[2];
805 auto & loadNode = LoadNonVolatileOperation::CreateNode(
807 { memoryStateArgument1, memoryStateArgument2 },
811 auto lambdaOutput = lambdaNode->finalize({ loadNode.output(1), loadNode.output(2) });
813 GraphExport::Create(*lambdaOutput,
"test");
822 EXPECT_EQ(lambdaNode->subregion()->numNodes(), 0u);
823 EXPECT_EQ(lambdaNode->GetFunctionResults()[0]->origin(), memoryStateArgument1);
824 EXPECT_EQ(lambdaNode->GetFunctionResults()[1]->origin(), memoryStateArgument2);