25TEST(RvsdgToIpGraphConverterTests, GammaWithMatch)
32 auto valueType = TestType::createValueType();
40 rvsdgModule.Rvsdg().GetRootRegion(),
41 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
44 MatchOperation::CreateNode(*lambdaNode->GetFunctionArguments()[0], { { 0, 0 } }, 1, 2);
45 auto gamma = GammaNode::create(matchNode.output(0), 2);
46 auto gammaInput1 = gamma->AddEntryVar(lambdaNode->GetFunctionArguments()[1]);
47 auto gammaInput2 = gamma->AddEntryVar(lambdaNode->GetFunctionArguments()[2]);
49 gamma->AddExitVar({ gammaInput1.branchArgument[0], gammaInput2.branchArgument[1] });
51 auto lambdaOutput = lambdaNode->finalize({ gammaOutput.output });
52 GraphExport::Create(*lambdaOutput,
"");
54 view(rvsdgModule.Rvsdg(), stdout);
58 auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
59 print(*module, stdout);
62 auto & ipg =
module->ipgraph();
63 EXPECT_EQ(ipg.nnodes(), 1u);
65 auto cfg =
dynamic_cast<const FunctionNode &
>(*ipg.begin()).cfg();
66 EXPECT_EQ(cfg->nnodes(), 4u);
69TEST(RvsdgToIpGraphConverterTests, GammaWithoutMatch)
84 rvsdgModule.Rvsdg().GetRootRegion(),
85 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
88 auto gammaInput1 = gammaNode->AddEntryVar(lambdaNode->GetFunctionArguments()[1]);
89 auto gammaInput2 = gammaNode->AddEntryVar(lambdaNode->GetFunctionArguments()[2]);
91 gammaNode->AddExitVar({ gammaInput1.branchArgument[0], gammaInput2.branchArgument[1] });
93 auto lambdaOutput = lambdaNode->finalize({ gammaOutput.output });
94 GraphExport::Create(*lambdaOutput,
"");
100 auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
101 print(*module, stdout);
104 auto & ipg =
module->ipgraph();
105 EXPECT_EQ(ipg.nnodes(), 1u);
107 auto cfg =
dynamic_cast<const FunctionNode &
>(*ipg.begin()).cfg();
108 EXPECT_EQ(cfg->nnodes(), 4u);
111TEST(RvsdgToIpGraphConverterTests, EmptyGammaWithTwoSubregionsAndMatch)
126 rvsdgModule.Rvsdg().GetRootRegion(),
127 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
128 const auto conditionValue = lambdaNode->GetFunctionArguments()[0];
129 const auto trueValue = lambdaNode->GetFunctionArguments()[1];
130 const auto falseValue = lambdaNode->GetFunctionArguments()[2];
133 auto & matchNode = MatchOperation::CreateNode(*conditionValue, { { caseValue, 0 } }, 1, 2);
136 auto [inputTrue, branchArgumentTrue] = gammaNode->AddEntryVar(trueValue);
137 auto [inputFalse, branchArgumentFalse] = gammaNode->AddEntryVar(falseValue);
138 auto [_, gammaOutput] = gammaNode->AddExitVar({ branchArgumentTrue[0], branchArgumentFalse[1] });
140 const auto lambdaOutput = lambdaNode->finalize({ gammaOutput });
141 GraphExport::Create(*lambdaOutput,
"");
143 view(rvsdgModule.Rvsdg(), stdout);
148 RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
149 print(*module, stdout);
152 const auto & ipGraph =
module->ipgraph();
153 EXPECT_EQ(ipGraph.nnodes(), 1u);
155 const auto controlFlowGraph =
dynamic_cast<const FunctionNode &
>(*ipGraph.begin()).cfg();
156 EXPECT_TRUE(is_closed(*controlFlowGraph));
159TEST(RvsdgToIpGraphConverterTests, EmptyGammaWithTwoSubregions)
174 rvsdgModule.Rvsdg().GetRootRegion(),
175 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
176 const auto trueValue = lambdaNode->GetFunctionArguments()[1];
177 const auto falseValue = lambdaNode->GetFunctionArguments()[2];
180 MatchOperation::CreateNode(*lambdaNode->GetFunctionArguments()[0], { { 0, 0 } }, 1, 2);
184 *gammaNode0->subregion(0),
187 *gammaNode0->subregion(1),
189 auto c = gammaNode0->AddExitVar({ c0.output(0),
c1.output(0) });
192 auto [inputTrue, branchArgumentTrue] = gammaNode1->AddEntryVar(trueValue);
193 auto [inputFalse, branchArgumentFalse] = gammaNode1->AddEntryVar(falseValue);
194 auto [_, gammaOutput] = gammaNode1->AddExitVar({ branchArgumentFalse[0], branchArgumentTrue[1] });
196 const auto lambdaOutput = lambdaNode->finalize({ gammaOutput });
197 GraphExport::Create(*lambdaOutput,
"");
199 view(rvsdgModule.Rvsdg(), stdout);
204 RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
205 print(*module, stdout);
208 const auto & ipGraph =
module->ipgraph();
209 EXPECT_EQ(ipGraph.nnodes(), 1u);
211 const auto controlFlowGraph =
dynamic_cast<const FunctionNode &
>(*ipGraph.begin()).cfg();
212 EXPECT_TRUE(
is_closed(*controlFlowGraph));
215TEST(RvsdgToIpGraphConverterTests, EmptyGammaWithThreeSubregions)
230 rvsdgModule.Rvsdg().GetRootRegion(),
231 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
233 auto & matchNode = MatchOperation::CreateNode(
234 *lambdaNode->GetFunctionArguments()[0],
235 { { 0, 0 }, { 1, 1 } },
240 auto gammaInput1 = gammaNode->AddEntryVar(lambdaNode->GetFunctionArguments()[1]);
241 auto gammaInput2 = gammaNode->AddEntryVar(lambdaNode->GetFunctionArguments()[2]);
242 auto gammaOutput = gammaNode->AddExitVar({ gammaInput1.branchArgument[0],
243 gammaInput1.branchArgument[1],
244 gammaInput2.branchArgument[2] });
246 auto lambdaOutput = lambdaNode->finalize({ gammaOutput.output });
247 GraphExport::Create(*lambdaOutput,
"");
253 auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
254 print(*module, stdout);
257 auto & ipg =
module->ipgraph();
258 EXPECT_EQ(ipg.nnodes(), 1u);
260 auto cfg =
dynamic_cast<const FunctionNode &
>(*ipg.begin()).cfg();
264TEST(RvsdgToIpGraphConverterTests, PartialEmptyGamma)
279 rvsdgModule.Rvsdg().GetRootRegion(),
280 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
283 MatchOperation::CreateNode(*lambdaNode->GetFunctionArguments()[0], { { 0, 0 } }, 1, 2);
284 auto gammaNode = GammaNode::create(matchNode.output(0), 2);
285 auto gammaInput = gammaNode->AddEntryVar(lambdaNode->GetFunctionArguments()[1]);
286 auto output = TestOperation::createNode(
287 gammaNode->subregion(1),
288 { gammaInput.branchArgument[1] },
291 auto gammaOutput = gammaNode->AddExitVar({ gammaInput.branchArgument[0], output });
293 auto lambdaOutput = lambdaNode->finalize({ gammaOutput.output });
295 GraphExport::Create(*lambdaOutput,
"");
301 auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
304 auto & ipg =
module->ipgraph();
305 EXPECT_EQ(ipg.nnodes(), 1u);
307 auto cfg =
dynamic_cast<const FunctionNode &
>(*ipg.begin()).cfg();
308 std::cout << ControlFlowGraph::ToAscii(*cfg) << std::flush;
313TEST(RvsdgToIpGraphConverterTests, RecursiveData)
319 auto vt = TestType::createValueType();
320 auto pt = PointerType::Create();
324 auto imp = &LlvmGraphImport::createGlobalImport(
329 Linkage::externalLinkage,
340 Output *delta1 =
nullptr, *delta2 =
nullptr;
342 auto delta = DeltaNode::Create(
344 LlvmDeltaOperation::Create(
vt,
"delta1", Linkage::externalLinkage,
"",
false, 4));
345 auto dep1 = delta->AddContextVar(*fixVar2.recref).inner;
346 auto dep2 = delta->AddContextVar(*dep.inner).inner;
347 delta1 = &delta->finalize(
348 TestOperation::createNode(delta->subregion(), { dep1, dep2 }, { vt })->output(0));
352 auto delta = DeltaNode::Create(
354 LlvmDeltaOperation::Create(
vt,
"delta2", Linkage::externalLinkage,
"",
false, 4));
355 auto dep1 = delta->AddContextVar(*fixVar1.recref).inner;
356 auto dep2 = delta->AddContextVar(*dep.inner).inner;
357 delta2 = &delta->finalize(
358 TestOperation::createNode(delta->subregion(), { dep1, dep2 }, { vt })->output(0));
361 fixVar1.result->divert_to(delta1);
362 fixVar2.result->divert_to(delta2);
364 auto phi = phiBuilder.
end();
365 GraphExport::Create(*phi->output(0),
"");
367 view(rm.
Rvsdg(), stdout);
371 auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rm, statisticsCollector);
372 print(*module, stdout);
375 auto & ipGraph =
module->ipgraph();
376 EXPECT_EQ(ipGraph.nnodes(), 3u);
378 auto delta1Node = ipGraph.find(
"delta1");
379 auto delta2Node = ipGraph.find(
"delta2");
380 auto importNode = ipGraph.find(
"import");
381 EXPECT_EQ(delta1Node->numDependencies(), 2u);
382 for (
auto depNode : *delta1Node)
384 EXPECT_TRUE(depNode == delta2Node || depNode == importNode);
387 EXPECT_EQ(delta2Node->numDependencies(), 2u);
388 for (
auto depNode : *delta2Node)
390 EXPECT_TRUE(depNode == delta1Node || depNode == importNode);
393 EXPECT_EQ(importNode->numDependencies(), 0u);
412TEST(RvsdgToIpGraphConverterTests, NestedLoopWithCall)
419 auto ioStateType = IOStateType::Create();
420 auto memoryStateType = MemoryStateType::Create();
421 auto pointerType = PointerType::Create();
423 FunctionType::Create({ ioStateType, memoryStateType }, { ioStateType, memoryStateType });
426 auto & rvsdg = rvsdgModule.Rvsdg();
428 auto & opaque = LlvmGraphImport::createFunctionImport(
432 Linkage::externalLinkage,
433 CallingConvention::Default);
435 auto lambdaNode = LambdaNode::Create(
436 rvsdg.GetRootRegion(),
437 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
438 auto ioStateArgument = lambdaNode->GetFunctionArguments()[0];
439 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[1];
440 auto opaqueCtxVar = lambdaNode->AddContextVar(opaque);
442 auto outerThetaNode = ThetaNode::create(lambdaNode->subregion());
443 auto outerIOStateLoopVar = outerThetaNode->AddLoopVar(ioStateArgument);
444 auto outerMemoryStateLoopVar = outerThetaNode->AddLoopVar(memoryStateArgument);
445 auto outerOpaque = outerThetaNode->AddLoopVar(opaqueCtxVar.inner);
447 auto innerThetaNode = ThetaNode::create(outerThetaNode->subregion());
448 auto innerIOStateLoopVar = innerThetaNode->AddLoopVar(outerIOStateLoopVar.pre);
449 auto innerMemoryStateLoopVar = innerThetaNode->AddLoopVar(outerMemoryStateLoopVar.pre);
450 auto innerOpaque = innerThetaNode->AddLoopVar(outerOpaque.pre);
452 auto & callNode = CallOperation::CreateNode(
455 { innerIOStateLoopVar.pre, innerMemoryStateLoopVar.pre });
457 innerIOStateLoopVar.post->divert_to(callNode.output(0));
458 innerMemoryStateLoopVar.post->divert_to(callNode.output(1));
460 outerIOStateLoopVar.post->divert_to(innerIOStateLoopVar.output);
461 outerMemoryStateLoopVar.post->divert_to(innerMemoryStateLoopVar.output);
462 outerOpaque.post->divert_to(innerOpaque.output);
465 lambdaNode->finalize({ outerIOStateLoopVar.output, outerMemoryStateLoopVar.output });
467 GraphExport::Create(*lambdaOutput,
"f");
469 view(rvsdgModule.Rvsdg(), stdout);
476 print(*ipGraphModule, stdout);
482 auto & ipGraph = ipGraphModule->ipgraph();
483 EXPECT_EQ(ipGraph.nnodes(), 2u);
485 auto functionNode = ipGraph.find(
"f");
486 auto importNode = ipGraph.find(
"opaque");
487 EXPECT_EQ(functionNode->numDependencies(), 1u);
488 EXPECT_EQ(importNode->numDependencies(), 0u);
489 EXPECT_EQ(*functionNode->begin(), importNode);
491 auto controlFlowGraph =
dynamic_cast<const FunctionNode *
>(ipGraph.find(
"f"))->cfg();
492 EXPECT_EQ(controlFlowGraph->nnodes(), 5u);
494 for (
auto & basicBlock : *controlFlowGraph)
497 EXPECT_TRUE(numSsaPhis == 2 || numSsaPhis == 0);
517 auto [valueType, name, linkage, isConstant, alignment] = GetParam();
519 const auto pointerType = PointerType::Create();
522 [[maybe_unused]]
auto &
import = LlvmGraphImport::createGlobalImport(
531 view(rvsdgModule.
Rvsdg(), stdout);
535 const auto ipGraphModule =
538 print(*ipGraphModule, stdout);
541 const auto & ipGraph = ipGraphModule->ipgraph();
542 EXPECT_EQ(ipGraph.nnodes(), 1u);
544 const auto dataNode =
dynamic_cast<const DataNode *
>(&*ipGraph.begin());
545 EXPECT_NE(dataNode,
nullptr);
547 EXPECT_EQ(dataNode->GetValueType(), valueType);
548 EXPECT_EQ(dataNode->name(), name);
549 EXPECT_EQ(dataNode->linkage(), linkage);
550 EXPECT_EQ(dataNode->constant(), isConstant);
551 EXPECT_EQ(dataNode->getAlignment(), alignment);