25TEST(NodeHoistingTests, simpleGamma)
31 const auto controlType = ControlType::Create(2);
32 const auto valueType = TestType::createValueType();
33 const auto functionType = FunctionType::Create(
41 auto & rvsdg = rvsdgModule.Rvsdg();
43 auto lambdaNode = LambdaNode::Create(
44 rvsdg.GetRootRegion(),
45 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
46 auto controlArgument = lambdaNode->GetFunctionArguments()[0];
47 auto valueArgument = lambdaNode->GetFunctionArguments()[1];
49 auto gammaNode = GammaNode::create(controlArgument, 2);
50 auto entryVar = gammaNode->AddEntryVar(valueArgument);
53 auto constantNode = TestOperation::createNode(gammaNode->subregion(0), {}, { valueType });
54 auto binaryNode = TestOperation::createNode(
55 gammaNode->subregion(0),
56 { entryVar.branchArgument[0], constantNode->output(0) },
60 auto unaryNode = TestOperation::createNode(
61 gammaNode->subregion(1),
62 { entryVar.branchArgument[1] },
65 auto exitVar = gammaNode->AddExitVar({ binaryNode->output(0), unaryNode->output(0) });
67 auto lambdaOutput = lambdaNode->finalize({ exitVar.output });
69 GraphExport::Create(*lambdaOutput,
"x");
82 EXPECT_EQ(lambdaNode->subregion()->numNodes(), 4u);
85 EXPECT_EQ(gammaNode->subregion(0)->numNodes(), 0u);
86 EXPECT_EQ(gammaNode->subregion(1)->numNodes(), 0u);
89TEST(NodeHoistingTests, nestedGamma)
95 const auto controlType = ControlType::Create(2);
96 const auto valueType = TestType::createValueType();
97 const auto functionType = FunctionType::Create(
105 auto & rvsdg = rvsdgModule.Rvsdg();
107 auto lambdaNode = LambdaNode::Create(
108 rvsdg.GetRootRegion(),
109 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
110 auto controlArgument = lambdaNode->GetFunctionArguments()[0];
111 auto valueArgument = lambdaNode->GetFunctionArguments()[1];
113 auto gammaNode1 = GammaNode::create(controlArgument, 2);
114 auto controlEntryVar = gammaNode1->AddEntryVar(controlArgument);
115 auto valueEntryVar1 = gammaNode1->AddEntryVar(valueArgument);
118 auto constantNode1 = TestOperation::createNode(gammaNode1->subregion(0), {}, { valueType });
120 auto gammaNode2 = GammaNode::create(controlEntryVar.branchArgument[0], 2);
121 auto valueEntryVar2 = gammaNode2->AddEntryVar(valueEntryVar1.branchArgument[0]);
122 auto valueEntryVar3 = gammaNode2->AddEntryVar(constantNode1->output(0));
125 auto binaryNode = TestOperation::createNode(
126 gammaNode1->subregion(0),
127 { valueEntryVar2.branchArgument[0], valueEntryVar3.branchArgument[0] },
131 auto unaryNode = TestOperation::createNode(
132 gammaNode1->subregion(1),
133 { valueEntryVar2.branchArgument[1] },
136 auto exitVar1 = gammaNode2->AddExitVar({ binaryNode->output(0), unaryNode->output(0) });
139 auto constantNode2 = TestOperation::createNode(gammaNode1->subregion(1), {}, { valueType });
141 auto exitVar2 = gammaNode1->AddExitVar({ exitVar1.output, constantNode2->output(0) });
143 auto lambdaOutput = lambdaNode->finalize({ exitVar2.output });
145 GraphExport::Create(*lambdaOutput,
"x");
158 EXPECT_EQ(lambdaNode->subregion()->numNodes(), 5u);
161 EXPECT_EQ(gammaNode1->subregion(0)->numNodes(), 1u);
162 EXPECT_EQ(gammaNode1->subregion(1)->numNodes(), 0u);
165 EXPECT_EQ(gammaNode2->subregion(0)->numNodes(), 0u);
166 EXPECT_EQ(gammaNode2->subregion(1)->numNodes(), 0u);
169TEST(NodeHoistingTests, simpleTheta)
175 auto controlType = ControlType::Create(2);
176 const auto valueType = TestType::createValueType();
177 const auto functionType = FunctionType::Create(
185 auto & rvsdg = rvsdgModule.Rvsdg();
187 auto lambdaNode = LambdaNode::Create(
188 rvsdg.GetRootRegion(),
189 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
190 auto controlArgument = lambdaNode->GetFunctionArguments()[0];
191 auto valueArgument = lambdaNode->GetFunctionArguments()[1];
193 auto thetaNode = ThetaNode::create(lambdaNode->subregion());
195 auto lv1 = thetaNode->AddLoopVar(controlArgument);
196 auto lv2 = thetaNode->AddLoopVar(valueArgument);
197 auto lv3 = thetaNode->AddLoopVar(valueArgument);
198 auto lv4 = thetaNode->AddLoopVar(valueArgument);
200 auto node1 = TestOperation::createNode(thetaNode->subregion(), {}, { valueType });
201 auto node2 = TestOperation::createNode(
202 thetaNode->subregion(),
203 { node1->output(0), lv3.pre },
205 auto node3 = TestOperation::createNode(
206 thetaNode->subregion(),
207 { lv2.pre, node2->output(0) },
210 TestOperation::createNode(thetaNode->subregion(), { lv3.pre, lv4.pre }, { valueType });
212 lv2.post->divert_to(node3->output(0));
213 lv4.post->divert_to(node4->output(0));
215 thetaNode->set_predicate(lv1.pre);
217 lambdaNode->finalize({ thetaNode->output(1) });
230 EXPECT_EQ(lambdaNode->subregion()->numNodes(), 3u);
231 EXPECT_EQ(thetaNode->subregion()->numNodes(), 2u);
233 EXPECT_EQ(lv2.post->origin(), node3->output(0));
234 EXPECT_EQ(lv4.post->origin(), node4->output(0));
237TEST(NodeHoistingTests, invariantMemoryOperation)
243 const auto memoryStateType = MemoryStateType::Create();
244 const auto pointerType = PointerType::Create();
245 const auto controlType = ControlType::Create(2);
246 const auto valueType = TestType::createValueType();
247 const auto functionType = FunctionType::Create(
248 { controlType, pointerType, valueType, memoryStateType },
249 { memoryStateType });
252 auto & rvsdg = rvsdgModule.Rvsdg();
254 auto lambdaNode = LambdaNode::Create(
255 rvsdg.GetRootRegion(),
256 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
257 auto controlArgument = lambdaNode->GetFunctionArguments()[0];
258 auto pointerArgument = lambdaNode->GetFunctionArguments()[1];
259 auto valueArgument = lambdaNode->GetFunctionArguments()[2];
260 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[3];
262 auto thetaNode = ThetaNode::create(lambdaNode->subregion());
264 auto lvc = thetaNode->AddLoopVar(controlArgument);
265 auto lva = thetaNode->AddLoopVar(pointerArgument);
266 auto lvv = thetaNode->AddLoopVar(valueArgument);
267 auto lvs = thetaNode->AddLoopVar(memoryStateArgument);
269 auto & storeNode = StoreNonVolatileOperation::CreateNode(*lva.pre, *lvv.pre, { lvs.pre }, 4);
271 lvs.post->divert_to(storeNode.output(0));
272 thetaNode->set_predicate(lvc.pre);
274 lambdaNode->finalize({ lvs.output });
287 EXPECT_EQ(lambdaNode->subregion()->numNodes(), 2u);
288 EXPECT_EQ(thetaNode->subregion()->numNodes(), 0u);
291TEST(NodeHoistingTests, statefulOperations)
297 auto controlType = ControlType::Create(2);
298 auto valueType = TestType::createValueType();
299 auto stateType = TestType::createStateType();
300 const auto functionType = FunctionType::Create(
309 auto & rvsdg = rvsdgModule.Rvsdg();
311 auto lambdaNode = LambdaNode::Create(
312 rvsdg.GetRootRegion(),
313 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
314 auto controlArgument = lambdaNode->GetFunctionArguments()[0];
315 auto valueArgument = lambdaNode->GetFunctionArguments()[1];
316 auto stateArgument = lambdaNode->GetFunctionArguments()[2];
318 auto gammaNode1 = GammaNode::create(controlArgument, 2);
319 auto controlEntryVar = gammaNode1->AddEntryVar(controlArgument);
320 auto valueEntryVar1 = gammaNode1->AddEntryVar(valueArgument);
321 auto stateEntryVar = gammaNode1->AddEntryVar(stateArgument);
323 auto stateNode = TestOperation::createNode(
324 gammaNode1->subregion(0),
325 { valueEntryVar1.branchArgument[0], stateEntryVar.branchArgument[0] },
328 auto gammaNode2 = GammaNode::create(controlEntryVar.branchArgument[0], 2);
329 auto valueEntryVar2 = gammaNode2->AddEntryVar(stateNode->output(0));
330 auto valueEntryVar3 = gammaNode2->AddEntryVar(valueEntryVar1.branchArgument[0]);
332 auto binaryNode = TestOperation::createNode(
333 gammaNode2->subregion(0),
334 { valueEntryVar2.branchArgument[0], valueEntryVar3.branchArgument[0] },
338 gammaNode2->AddExitVar({ binaryNode->output(0), valueEntryVar2.branchArgument[1] });
340 auto exitVar = gammaNode1->AddExitVar({ exitVar2.output, valueEntryVar1.branchArgument[1] });
342 lambdaNode->finalize({ exitVar.output });
358 EXPECT_EQ(lambdaNode->subregion()->numNodes(), 1u);
361 EXPECT_EQ(gammaNode1->subregion(0)->numNodes(), 3u);
362 EXPECT_EQ(gammaNode1->subregion(1)->numNodes(), 0u);
364 EXPECT_EQ(gammaNode2->subregion(0)->numNodes(), 0u);
365 EXPECT_EQ(gammaNode2->subregion(1)->numNodes(), 0u);
368TEST(NodeHoistingTests, controlConstants)
403 auto controlType = ControlType::Create(2);
404 auto int32Type = BitType::Create(32);
405 auto memoryStateType = MemoryStateType::Create();
406 auto ioStateType = IOStateType::Create();
407 const auto functionType = FunctionType::Create(
408 { ioStateType, memoryStateType },
409 { int32Type, ioStateType, memoryStateType });
412 auto & rvsdg = rvsdgModule.Rvsdg();
414 auto lambdaNode = LambdaNode::Create(
415 rvsdg.GetRootRegion(),
416 LlvmLambdaOperation::Create(functionType,
"func", Linkage::externalLinkage));
418 auto ioStateArgument = lambdaNode->GetFunctionArguments()[0];
419 auto memStateArgument = lambdaNode->GetFunctionArguments()[1];
422 auto thetaNode = ThetaNode::create(lambdaNode->subregion());
423 auto thetaUndef = UndefValueOperation::Create(*lambdaNode->subregion(), controlType);
424 auto thetaCtrlLoopVar = thetaNode->AddLoopVar(thetaUndef);
425 auto & thetaInnerCtrl1 = ControlConstantOperation::create(*thetaNode->subregion(), 2, 1);
426 thetaCtrlLoopVar.post->divert_to(&thetaInnerCtrl1);
429 auto & gamma1 = GammaNode::Create(*thetaCtrlLoopVar.output, 2, {});
432 auto & gamma1Ctrl1 = ControlConstantOperation::create(*gamma1.subregion(0), 2, 1);
433 auto & gamma1Ctrl0 = ControlConstantOperation::create(*gamma1.subregion(1), 2, 0);
434 auto gamma1Exit = gamma1.AddExitVar({ &gamma1Ctrl1, &gamma1Ctrl0 });
437 auto & gamma2 = GammaNode::Create(*gamma1Exit.output, 2, {});
440 auto & gamma2Int3 = *IntegerConstantOperation::Create(*gamma2.subregion(0), 32, 3).output(0);
441 auto & gamma2Int7 = *IntegerConstantOperation::Create(*gamma2.subregion(1), 32, 7).output(0);
443 auto gamma2Exit = gamma2.AddExitVar({ &gamma2Int3, &gamma2Int7 });
445 lambdaNode->finalize({ gamma2Exit.output, ioStateArgument, memStateArgument });
462 EXPECT_EQ(lambdaNode->subregion()->numNodes(), 6u);
465 EXPECT_EQ(thetaNode->subregion()->numNodes(), 2u);
466 auto thetaPredicateOwner = TryGetOwnerNode<SimpleNode>(*thetaNode->predicate()->origin());
467 EXPECT_TRUE(thetaPredicateOwner);
468 EXPECT_EQ(thetaPredicateOwner->region(), thetaNode->subregion());
469 auto thetaPostOwner = TryGetOwnerNode<SimpleNode>(*thetaCtrlLoopVar.post->origin());
470 EXPECT_TRUE(thetaPostOwner);
471 EXPECT_EQ(thetaPostOwner->region(), thetaNode->subregion());
474 EXPECT_EQ(gamma1.subregion(0)->numNodes(), 1u);
475 auto gamma1LeftCtrlOwner = TryGetOwnerNode<SimpleNode>(*gamma1Exit.branchResult[0]->origin());
476 EXPECT_TRUE(gamma1LeftCtrlOwner);
477 EXPECT_EQ(gamma1LeftCtrlOwner->region(), gamma1.subregion(0));
479 EXPECT_EQ(gamma1.subregion(1)->numNodes(), 1u);
480 auto gamma1RightCtrlOwner = TryGetOwnerNode<SimpleNode>(*gamma1Exit.branchResult[1]->origin());
481 EXPECT_TRUE(gamma1RightCtrlOwner);
482 EXPECT_EQ(gamma1RightCtrlOwner->region(), gamma1.subregion(1));
485 EXPECT_EQ(gamma2.subregion(0)->numNodes(), 0u);
486 EXPECT_EQ(gamma2.subregion(1)->numNodes(), 0u);