28TEST(LoadChainSeparationTests, LoadNonVolatile)
35 const auto pointerType = PointerType::Create();
36 const auto memoryStateType = MemoryStateType::Create();
37 const auto ioStateType = IOStateType::Create();
38 const auto valueType = TestType::createValueType();
39 const auto functionType = FunctionType::Create(
40 { pointerType, ioStateType, memoryStateType },
41 { ioStateType, memoryStateType });
44 auto & rvsdg = rvsdgModule.Rvsdg();
46 auto lambdaNode = LambdaNode::Create(
47 rvsdg.GetRootRegion(),
48 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
50 auto & addressArgument = *lambdaNode->GetFunctionArguments()[0];
51 auto & ioStateArgument = *lambdaNode->GetFunctionArguments()[1];
52 auto & memoryStateArgument = *lambdaNode->GetFunctionArguments()[2];
54 auto & lambdaEntrySplitNode =
55 LambdaEntryMemoryStateSplitOperation::CreateNode(memoryStateArgument, { 0, 1 });
57 auto & loadNode1 = LoadNonVolatileOperation::CreateNode(
59 { lambdaEntrySplitNode.output(0), lambdaEntrySplitNode.output(1) },
63 auto & loadNode2 = LoadNonVolatileOperation::CreateNode(
65 { loadNode1.output(1), loadNode1.output(2) },
70 LoadNonVolatileOperation::CreateNode(addressArgument, { loadNode2.output(2) }, valueType, 4);
72 auto & lambdaExitMergeNode = LambdaExitMemoryStateMergeOperation::CreateNode(
73 *lambdaNode->subregion(),
74 { loadNode2.output(1), loadNode3.output(1) },
77 lambdaNode->finalize({ &ioStateArgument, lambdaExitMergeNode.output(0) });
94 auto [joinNode, joinOperation] = TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(
95 *lambdaExitMergeNode.input(0)->origin());
96 EXPECT_TRUE(joinNode && joinOperation);
97 EXPECT_EQ(joinNode->ninputs(), 2u);
99 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*joinNode->input(0)->origin()), &loadNode2);
100 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*joinNode->input(1)->origin()), &loadNode1);
102 EXPECT_EQ(loadNode1.input(1)->origin(), lambdaEntrySplitNode.output(0));
103 EXPECT_EQ(loadNode1.input(2)->origin(), lambdaEntrySplitNode.output(1));
105 EXPECT_EQ(loadNode2.input(1)->origin(), lambdaEntrySplitNode.output(0));
106 EXPECT_EQ(loadNode2.input(2)->origin(), lambdaEntrySplitNode.output(1));
111 auto [joinNode, joinOperation] = TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(
112 *lambdaExitMergeNode.input(1)->origin());
113 EXPECT_TRUE(joinNode && joinOperation);
114 EXPECT_EQ(joinNode->ninputs(), 3u);
116 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*joinNode->input(0)->origin()), &loadNode3);
117 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*joinNode->input(1)->origin()), &loadNode2);
118 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*joinNode->input(2)->origin()), &loadNode1);
120 EXPECT_EQ(loadNode3.input(1)->origin(), lambdaEntrySplitNode.output(1));
124TEST(LoadChainSeparationTests, LoadVolatile)
131 const auto pointerType = PointerType::Create();
132 const auto ioStateType = IOStateType::Create();
133 const auto memoryStateType = MemoryStateType::Create();
134 const auto valueType = TestType::createValueType();
135 const auto functionType = FunctionType::Create(
136 { pointerType, ioStateType, memoryStateType },
137 { ioStateType, memoryStateType });
140 auto & rvsdg = rvsdgModule.Rvsdg();
142 auto lambdaNode = LambdaNode::Create(
143 rvsdg.GetRootRegion(),
144 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
146 auto & addressArgument = *lambdaNode->GetFunctionArguments()[0];
147 auto & ioStateArgument = *lambdaNode->GetFunctionArguments()[1];
148 auto & memoryStateArgument = *lambdaNode->GetFunctionArguments()[2];
150 auto & loadNode1 = LoadVolatileOperation::CreateNode(
153 { &memoryStateArgument },
157 auto & loadNode2 = LoadVolatileOperation::CreateNode(
159 LoadVolatileOperation::IOStateOutput(loadNode1),
160 { &*LoadOperation::MemoryStateOutputs(loadNode1).begin() },
164 lambdaNode->finalize({ &ioStateArgument, loadNode2.output(2) });
180 auto [joinNode, joinOperation] = TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(
181 *GetMemoryStateRegionResult(*lambdaNode).
origin());
182 EXPECT_TRUE(joinNode && joinOperation);
183 EXPECT_EQ(joinNode->ninputs(), 2u);
185 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*joinNode->input(0)->origin()), &loadNode2);
186 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*joinNode->input(1)->origin()), &loadNode1);
188 EXPECT_EQ(loadNode1.input(2)->origin(), &memoryStateArgument);
189 EXPECT_EQ(loadNode2.input(2)->origin(), &memoryStateArgument);
192TEST(LoadChainSeparationTests, SingleLoad)
199 const auto pointerType = PointerType::Create();
200 const auto ioStateType = IOStateType::Create();
201 const auto memoryStateType = MemoryStateType::Create();
202 const auto valueType = TestType::createValueType();
203 const auto functionType = FunctionType::Create(
204 { pointerType, ioStateType, memoryStateType },
205 { ioStateType, memoryStateType });
208 auto & rvsdg = rvsdgModule.Rvsdg();
210 auto lambdaNode = LambdaNode::Create(
211 rvsdg.GetRootRegion(),
212 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
214 auto & addressArgument = *lambdaNode->GetFunctionArguments()[0];
215 auto & ioStateArgument = *lambdaNode->GetFunctionArguments()[1];
216 auto & memoryStateArgument = *lambdaNode->GetFunctionArguments()[2];
219 LoadNonVolatileOperation::CreateNode(addressArgument, { &memoryStateArgument }, valueType, 4);
221 lambdaNode->finalize({ &ioStateArgument, loadNode.output(1) });
235 TryGetOwnerNode<SimpleNode>(*GetMemoryStateRegionResult(*lambdaNode).
origin()),
237 EXPECT_EQ(LoadOperation::MemoryStateInputs(loadNode).begin()->origin(), &memoryStateArgument);
240TEST(LoadChainSeparationTests, LoadAndStore)
247 const auto pointerType = PointerType::Create();
248 const auto memoryStateType = MemoryStateType::Create();
249 const auto ioStateType = IOStateType::Create();
250 const auto valueType = TestType::createValueType();
251 const auto functionType = FunctionType::Create(
252 { pointerType, ioStateType, memoryStateType },
253 { ioStateType, memoryStateType });
256 auto & rvsdg = rvsdgModule.Rvsdg();
258 auto lambdaNode = LambdaNode::Create(
259 rvsdg.GetRootRegion(),
260 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
262 auto & addressArgument = *lambdaNode->GetFunctionArguments()[0];
263 auto & ioStateArgument = *lambdaNode->GetFunctionArguments()[1];
264 auto & memoryStateArgument = *lambdaNode->GetFunctionArguments()[2];
266 auto valueNode = TestOperation::createNode(lambdaNode->subregion(), {}, { valueType });
269 LoadNonVolatileOperation::CreateNode(addressArgument, { &memoryStateArgument }, valueType, 4);
272 LoadNonVolatileOperation::CreateNode(addressArgument, { loadNode1.output(1) }, valueType, 4);
274 auto & storeNode1 = StoreNonVolatileOperation::CreateNode(
276 *valueNode->output(0),
277 { loadNode2.output(1) },
281 LoadNonVolatileOperation::CreateNode(addressArgument, { storeNode1.output(0) }, valueType, 4);
284 LoadNonVolatileOperation::CreateNode(addressArgument, { loadNode3.output(1) }, valueType, 4);
286 auto & storeNode2 = StoreNonVolatileOperation::CreateNode(
288 *valueNode->output(0),
289 { loadNode4.output(1) },
293 LoadNonVolatileOperation::CreateNode(addressArgument, { storeNode2.output(0) }, valueType, 4);
295 lambdaNode->finalize({ &ioStateArgument, loadNode5.output(1) });
309 auto [joinNode, joinOperation] =
310 TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(*storeNode2.input(2)->origin());
311 EXPECT_TRUE(joinOperation);
312 EXPECT_EQ(joinNode->ninputs(), 2u);
316 auto [joinNode, joinOperation] =
317 TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(*storeNode1.input(2)->origin());
318 EXPECT_TRUE(joinOperation);
319 EXPECT_EQ(joinNode->ninputs(), 2u);
323TEST(LoadChainSeparationTests, GammaWithOnlyLoads)
330 const auto pointerType = PointerType::Create();
331 const auto memoryStateType = MemoryStateType::Create();
332 const auto ioStateType = IOStateType::Create();
333 const auto valueType = TestType::createValueType();
334 const auto controlType = ControlType::Create(2);
335 const auto functionType = FunctionType::Create(
336 { controlType, pointerType, ioStateType, memoryStateType },
337 { ioStateType, memoryStateType });
340 auto & rvsdg = rvsdgModule.Rvsdg();
342 auto lambdaNode = LambdaNode::Create(
343 rvsdg.GetRootRegion(),
344 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
346 auto & controlArgument = *lambdaNode->GetFunctionArguments()[0];
347 auto & addressArgument = *lambdaNode->GetFunctionArguments()[1];
348 auto & ioStateArgument = *lambdaNode->GetFunctionArguments()[2];
349 auto & memoryStateArgument = *lambdaNode->GetFunctionArguments()[3];
352 LoadNonVolatileOperation::CreateNode(addressArgument, { &memoryStateArgument }, valueType, 4);
355 LoadNonVolatileOperation::CreateNode(addressArgument, { loadNode1.output(1) }, valueType, 4);
357 auto gammaNode = GammaNode::create(&controlArgument, 2);
358 auto addressEntryVar = gammaNode->AddEntryVar(&addressArgument);
359 auto memoryStateEntryVar = gammaNode->AddEntryVar(loadNode2.output(1));
362 auto & loadNode3 = LoadNonVolatileOperation::CreateNode(
363 *addressEntryVar.branchArgument[0],
364 { memoryStateEntryVar.branchArgument[0] },
368 auto & loadNode4 = LoadNonVolatileOperation::CreateNode(
369 *addressEntryVar.branchArgument[0],
370 { loadNode3.output(1) },
375 auto & loadNode5 = LoadNonVolatileOperation::CreateNode(
376 *addressEntryVar.branchArgument[1],
377 { memoryStateEntryVar.branchArgument[1] },
381 auto memoryStateExitVar = gammaNode->AddExitVar({ loadNode4.output(1), loadNode5.output(1) });
383 auto & loadNode6 = LoadNonVolatileOperation::CreateNode(
385 { memoryStateExitVar.output },
390 LoadNonVolatileOperation::CreateNode(addressArgument, { loadNode6.output(1) }, valueType, 4);
392 lambdaNode->finalize({ &ioStateArgument, loadNode7.output(1) });
406 auto [joinNode, joinOperation] = TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(
407 *GetMemoryStateRegionResult(*lambdaNode).
origin());
408 EXPECT_TRUE(joinOperation);
409 EXPECT_EQ(joinNode->ninputs(), 2u);
413 auto [joinNode, joinOperation] = TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(
414 *gammaNode->GetExitVars()[0].branchResult[0]->origin());
415 EXPECT_TRUE(joinOperation);
416 EXPECT_EQ(joinNode->ninputs(), 2u);
420 auto [joinNode, joinOperation] = TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(
421 *gammaNode->GetEntryVars()[1].input->origin());
422 EXPECT_TRUE(joinOperation);
423 EXPECT_EQ(joinNode->ninputs(), 2u);
427TEST(LoadChainSeparationTests, GammaWithLoadsAndStores)
434 const auto pointerType = PointerType::Create();
435 const auto ioStateType = IOStateType::Create();
436 const auto memoryStateType = MemoryStateType::Create();
437 const auto valueType = TestType::createValueType();
438 const auto controlType = ControlType::Create(2);
439 const auto functionType = FunctionType::Create(
440 { controlType, pointerType, ioStateType, memoryStateType },
441 { ioStateType, memoryStateType });
444 auto & rvsdg = rvsdgModule.Rvsdg();
446 auto lambdaNode = LambdaNode::Create(
447 rvsdg.GetRootRegion(),
448 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
450 auto & controlArgument = *lambdaNode->GetFunctionArguments()[0];
451 auto & addressArgument = *lambdaNode->GetFunctionArguments()[1];
452 auto & ioStateArgument = *lambdaNode->GetFunctionArguments()[2];
453 auto & memoryStateArgument = *lambdaNode->GetFunctionArguments()[3];
456 LoadNonVolatileOperation::CreateNode(addressArgument, { &memoryStateArgument }, valueType, 4);
458 auto gammaNode = GammaNode::create(&controlArgument, 2);
459 auto addressEntryVar = gammaNode->AddEntryVar(&addressArgument);
460 auto memoryStateEntryVar = gammaNode->AddEntryVar(loadNode1.output(1));
463 auto & loadNode2 = LoadNonVolatileOperation::CreateNode(
464 *addressEntryVar.branchArgument[0],
465 { memoryStateEntryVar.branchArgument[0] },
469 auto & loadNode3 = LoadNonVolatileOperation::CreateNode(
470 *addressEntryVar.branchArgument[0],
471 { loadNode2.output(1) },
476 auto value = TestOperation::createNode(gammaNode->subregion(1), {}, { valueType });
477 auto & storeNode = StoreNonVolatileOperation::CreateNode(
478 *addressEntryVar.branchArgument[1],
480 { memoryStateEntryVar.branchArgument[1] },
483 auto & loadNode4 = LoadNonVolatileOperation::CreateNode(
484 *addressEntryVar.branchArgument[1],
485 { storeNode.output(0) },
489 auto memoryStateExitVar = gammaNode->AddExitVar({ loadNode3.output(1), loadNode4.output(1) });
491 auto & loadNode5 = LoadNonVolatileOperation::CreateNode(
493 { memoryStateExitVar.output },
498 LoadNonVolatileOperation::CreateNode(addressArgument, { loadNode5.output(1) }, valueType, 4);
500 lambdaNode->finalize({ &ioStateArgument, loadNode6.output(1) });
514 auto [joinNode, joinOperation] = TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(
515 *GetMemoryStateRegionResult(*lambdaNode).
origin());
516 EXPECT_TRUE(joinOperation);
517 EXPECT_EQ(joinNode->ninputs(), 2u);
521 auto [joinNode, joinOperation] = TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(
522 *gammaNode->GetExitVars()[0].branchResult[0]->origin());
523 EXPECT_TRUE(joinOperation);
524 EXPECT_EQ(joinNode->ninputs(), 2u);
528TEST(LoadChainSeparationTests, ThetaWithLoadsOnly)
535 const auto pointerType = PointerType::Create();
536 const auto memoryStateType = MemoryStateType::Create();
537 const auto ioStateType = IOStateType::Create();
538 const auto valueType = TestType::createValueType();
539 const auto controlType = ControlType::Create(2);
540 const auto functionType = FunctionType::Create(
541 { controlType, pointerType, ioStateType, memoryStateType },
542 { ioStateType, memoryStateType });
545 auto & rvsdg = rvsdgModule.Rvsdg();
547 auto lambdaNode = LambdaNode::Create(
548 rvsdg.GetRootRegion(),
549 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
551 auto & addressArgument = *lambdaNode->GetFunctionArguments()[1];
552 auto & ioStateArgument = *lambdaNode->GetFunctionArguments()[2];
553 auto & memoryStateArgument = *lambdaNode->GetFunctionArguments()[3];
556 LoadNonVolatileOperation::CreateNode(addressArgument, { &memoryStateArgument }, valueType, 4);
559 LoadNonVolatileOperation::CreateNode(addressArgument, { loadNode1.output(1) }, valueType, 4);
561 auto thetaNode = ThetaNode::create(lambdaNode->subregion());
563 auto addressLoopVar = thetaNode->AddLoopVar(&addressArgument);
564 auto memoryStateLoopVar = thetaNode->AddLoopVar(loadNode2.output(1));
566 auto & loadNode3 = LoadNonVolatileOperation::CreateNode(
568 { memoryStateLoopVar.pre },
572 auto & loadNode4 = LoadNonVolatileOperation::CreateNode(
574 { loadNode3.output(1) },
578 memoryStateLoopVar.post->divert_to(loadNode4.output(1));
580 auto & loadNode5 = LoadNonVolatileOperation::CreateNode(
582 { memoryStateLoopVar.output },
587 LoadNonVolatileOperation::CreateNode(addressArgument, { loadNode5.output(1) }, valueType, 4);
589 lambdaNode->finalize({ &ioStateArgument, loadNode6.output(1) });
603 auto [joinNode, joinOperation] =
604 TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(*memoryStateLoopVar.post->origin());
605 EXPECT_TRUE(joinOperation);
606 EXPECT_EQ(joinNode->ninputs(), 2u);
611 auto [joinNode, joinOperation] = TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(
612 *GetMemoryStateRegionResult(*lambdaNode).
origin());
613 EXPECT_TRUE(joinOperation);
614 EXPECT_EQ(joinNode->ninputs(), 5u);
618TEST(LoadChainSeparationTests, ExternalCall)
625 const auto pointerType = PointerType::Create();
626 const auto memoryStateType = MemoryStateType::Create();
627 const auto ioStateType = IOStateType::Create();
628 const auto valueType = TestType::createValueType();
629 const auto controlType = ControlType::Create(2);
630 const auto functionType = FunctionType::Create(
631 { controlType, pointerType, ioStateType, memoryStateType },
632 { ioStateType, memoryStateType });
633 const auto externalFunctionType =
634 FunctionType::Create({ ioStateType, memoryStateType }, { ioStateType, memoryStateType });
637 auto & rvsdg = rvsdgModule.Rvsdg();
641 auto lambdaNode = LambdaNode::Create(
642 rvsdg.GetRootRegion(),
643 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
645 auto & addressArgument = *lambdaNode->GetFunctionArguments()[1];
646 auto & ioStateArgument = *lambdaNode->GetFunctionArguments()[2];
647 auto & memoryStateArgument = *lambdaNode->GetFunctionArguments()[3];
648 auto externalFunctionCtxVar = lambdaNode->AddContextVar(externalFunction);
650 auto & lambdaEntrySplitNode =
651 LambdaEntryMemoryStateSplitOperation::CreateNode(memoryStateArgument, { 0, 1 });
653 auto & loadNode1 = LoadNonVolatileOperation::CreateNode(
655 { lambdaEntrySplitNode.output(0) },
660 LoadNonVolatileOperation::CreateNode(addressArgument, { loadNode1.output(1) }, valueType, 4);
662 auto & loadNode3 = LoadNonVolatileOperation::CreateNode(
664 { lambdaEntrySplitNode.output(1) },
669 LoadNonVolatileOperation::CreateNode(addressArgument, { loadNode3.output(1) }, valueType, 4);
671 auto & callEntryMergeNode = CallEntryMemoryStateMergeOperation::CreateNode(
672 *lambdaNode->subregion(),
673 { loadNode2.output(1), loadNode4.output(1) },
676 auto & callNode = CallOperation::CreateNode(
677 externalFunctionCtxVar.inner,
678 externalFunctionType,
679 { &ioStateArgument, callEntryMergeNode.output(0) });
681 auto & callExitSplitNode =
682 CallExitMemoryStateSplitOperation::CreateNode(*callNode.output(1), { 0, 1 });
684 auto & loadNode5 = LoadNonVolatileOperation::CreateNode(
686 { callExitSplitNode.output(0) },
691 LoadNonVolatileOperation::CreateNode(addressArgument, { loadNode5.output(1) }, valueType, 4);
693 auto & loadNode7 = LoadNonVolatileOperation::CreateNode(
695 { callExitSplitNode.output(1) },
700 LoadNonVolatileOperation::CreateNode(addressArgument, { loadNode7.output(1) }, valueType, 4);
702 auto & lambdaExitMergeNode = LambdaExitMemoryStateMergeOperation::CreateNode(
703 *lambdaNode->subregion(),
704 { loadNode6.output(1), loadNode8.output(1) },
707 lambdaNode->finalize({ callNode.output(0), lambdaExitMergeNode.output(0) });
721 auto [joinNode, joinOperation] = TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(
722 *lambdaExitMergeNode.input(0)->origin());
723 EXPECT_TRUE(joinOperation);
725 EXPECT_EQ(joinNode->input(0)->origin(), loadNode6.output(1));
726 EXPECT_EQ(loadNode6.input(1)->origin(), callExitSplitNode.output(0));
728 EXPECT_EQ(joinNode->input(1)->origin(), loadNode5.output(1));
729 EXPECT_EQ(loadNode5.input(1)->origin(), callExitSplitNode.output(0));
733 auto [joinNode, joinOperation] = TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(
734 *lambdaExitMergeNode.input(1)->origin());
735 EXPECT_TRUE(joinOperation);
737 EXPECT_EQ(joinNode->input(0)->origin(), loadNode8.output(1));
738 EXPECT_EQ(loadNode8.input(1)->origin(), callExitSplitNode.output(1));
740 EXPECT_EQ(joinNode->input(1)->origin(), loadNode7.output(1));
741 EXPECT_EQ(loadNode7.input(1)->origin(), callExitSplitNode.output(1));
745 auto [joinNode, joinOperation] = TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(
746 *callEntryMergeNode.input(0)->origin());
747 EXPECT_TRUE(joinOperation);
749 EXPECT_EQ(joinNode->input(0)->origin(), loadNode2.output(1));
750 EXPECT_EQ(loadNode2.input(1)->origin(), lambdaEntrySplitNode.output(0));
752 EXPECT_EQ(joinNode->input(1)->origin(), loadNode1.output(1));
753 EXPECT_EQ(loadNode1.input(1)->origin(), lambdaEntrySplitNode.output(0));
757 auto [joinNode, joinOperation] = TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(
758 *callEntryMergeNode.input(1)->origin());
759 EXPECT_TRUE(joinOperation);
761 EXPECT_EQ(joinNode->input(0)->origin(), loadNode4.output(1));
762 EXPECT_EQ(loadNode4.input(1)->origin(), lambdaEntrySplitNode.output(1));
764 EXPECT_EQ(joinNode->input(1)->origin(), loadNode3.output(1));
765 EXPECT_EQ(loadNode3.input(1)->origin(), lambdaEntrySplitNode.output(1));
769TEST(LoadChainSeparationTests, DeadOutputs)
776 const auto bit32Type = BitType::Create(32);
777 const auto pointerType = PointerType::Create();
778 const auto memoryStateType = MemoryStateType::Create();
779 const auto ioStateType = IOStateType::Create();
780 const auto valueType = TestType::createValueType();
781 const auto functionType = FunctionType::Create(
782 { pointerType, valueType, ioStateType, memoryStateType },
783 { valueType, ioStateType, memoryStateType });
786 auto & rvsdg = rvsdgModule.Rvsdg();
788 auto lambdaNode = LambdaNode::Create(
789 rvsdg.GetRootRegion(),
790 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
791 auto & addressArgument = *lambdaNode->GetFunctionArguments()[0];
792 auto & valueArgument = *lambdaNode->GetFunctionArguments()[1];
793 auto & ioStateArgument = *lambdaNode->GetFunctionArguments()[2];
794 auto & memoryStateArgument = *lambdaNode->GetFunctionArguments()[3];
796 auto & storeNode = StoreNonVolatileOperation::CreateNode(
799 { &memoryStateArgument },
803 LoadNonVolatileOperation::CreateNode(addressArgument, { storeNode.output(0) }, valueType, 4);
806 LoadNonVolatileOperation::CreateNode(addressArgument, { loadNode1.output(1) }, valueType, 4);
808 auto undefValue = UndefValueOperation::Create(*lambdaNode->subregion(), memoryStateType);
810 lambdaNode->finalize({
826 EXPECT_TRUE(loadNode1.output(1)->IsDead());
827 EXPECT_EQ(loadNode1.input(1)->origin(), storeNode.output(0));
828 EXPECT_TRUE(loadNode2.output(1)->IsDead());
829 EXPECT_EQ(loadNode2.input(1)->origin(), storeNode.output(0));
832TEST(LoadChainSeperationTests, StoreInThetaWithMultipleUsers)
839 const auto bit32Type = BitType::Create(32);
840 const auto controlType = ControlType::Create(2);
841 const auto valueType = TestType::createValueType();
842 const auto memoryStateType = MemoryStateType::Create();
843 const auto ioStateType = IOStateType::Create();
844 const auto pointerType = PointerType::Create();
845 const auto functionType = FunctionType::Create(
846 { ioStateType, memoryStateType },
847 { valueType, ioStateType, memoryStateType });
850 auto & rvsdg = rvsdgModule.Rvsdg();
852 auto lambdaNode = LambdaNode::Create(
853 rvsdg.GetRootRegion(),
854 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
855 auto & ioStateArgument = *lambdaNode->GetFunctionArguments()[0];
856 auto & memoryStateArgument = *lambdaNode->GetFunctionArguments()[1];
858 auto sizeNode = TestOperation::createNode(lambdaNode->subregion(), {}, { bit32Type });
859 auto allocaResults = AllocaOperation::create(valueType, sizeNode->output(0), 4);
861 auto lambdaValueNode = TestOperation::createNode(lambdaNode->subregion(), {}, { valueType });
862 auto & lambdaStoreNode = StoreNonVolatileOperation::CreateNode(
864 *lambdaValueNode->output(0),
865 { allocaResults[1] },
869 auto thetaNode = ThetaNode::create(lambdaNode->subregion());
870 auto loopVar1 = thetaNode->AddLoopVar(&memoryStateArgument);
871 auto loopVar2 = thetaNode->AddLoopVar(lambdaStoreNode.output(0));
873 auto thetaAddressNode = TestOperation::createNode(thetaNode->subregion(), {}, { pointerType });
874 auto thetaValueNode = TestOperation::createNode(thetaNode->subregion(), {}, { valueType });
875 auto & thetaLoadNode = LoadNonVolatileOperation::CreateNode(
876 *thetaAddressNode->output(0),
880 auto & thetaStoreNode = StoreNonVolatileOperation::CreateNode(
881 *thetaAddressNode->output(0),
882 *thetaValueNode->output(0),
883 { thetaLoadNode.output(1) },
887 auto gammaPredicateNode = TestOperation::createNode(thetaNode->subregion(), {}, { controlType });
888 auto gammaNode = GammaNode::create(gammaPredicateNode->output(0), 2);
890 auto entryVar1 = gammaNode->AddEntryVar(thetaStoreNode.output(0));
891 auto entryVar2 = gammaNode->AddEntryVar(loopVar1.pre);
893 auto gammaAddressNode = TestOperation::createNode(gammaNode->subregion(1), {}, { pointerType });
894 auto gammaValueNode = TestOperation::createNode(gammaNode->subregion(1), {}, { valueType });
895 auto & gammaStoreNode = StoreNonVolatileOperation::CreateNode(
896 *gammaAddressNode->output(0),
897 *gammaValueNode->output(0),
898 { entryVar2.branchArgument[1] },
902 gammaNode->AddExitVar({ entryVar1.branchArgument[0], entryVar1.branchArgument[1] });
903 auto exitVar2 = gammaNode->AddExitVar({ entryVar2.branchArgument[0], gammaStoreNode.output(0) });
906 loopVar1.post->divert_to(exitVar2.output);
907 loopVar2.post->divert_to(thetaStoreNode.output(0));
910 auto & lambdaLoadNode =
911 LoadNonVolatileOperation::CreateNode(*allocaResults[0], { loopVar2.output }, valueType, 4);
914 lambdaNode->finalize({ lambdaLoadNode.output(0), &ioStateArgument, loopVar1.output });
916 GraphExport::Create(*lambdaOutput,
"f");
929 EXPECT_EQ(lambdaNode->subregion()->numNodes(), 6u);
930 EXPECT_EQ(thetaNode->subregion()->numNodes(), 7u);
931 EXPECT_EQ(gammaNode->subregion(0)->numNodes(), 0u);
932 EXPECT_EQ(gammaNode->subregion(1)->numNodes(), 3u);
934 EXPECT_NE(TryGetOwnerNode<ThetaNode>(*GetMemoryStateRegionResult(*lambdaNode).
origin()),
nullptr);
935 EXPECT_NE(TryGetOwnerNode<ThetaNode>(*lambdaLoadNode.input(1)->origin()),
nullptr);