56TEST(DeadNodeEliminationTests, Gamma1)
65 auto & graph = rvsdgModule.
Rvsdg();
71 auto ev1 = gamma->AddEntryVar(x);
72 auto ev2 = gamma->AddEntryVar(y);
73 auto ev3 = gamma->AddEntryVar(x);
77 { ev2.branchArgument[1] },
81 gamma->AddExitVar(ev1.branchArgument);
82 gamma->AddExitVar({ ev2.branchArgument[0], t });
83 gamma->AddExitVar({ ev3.branchArgument[0], ev1.branchArgument[1] });
94 EXPECT_EQ(gamma->noutputs(), 2u);
95 EXPECT_EQ(gamma->subregion(1)->numNodes(), 0u);
96 EXPECT_EQ(gamma->subregion(1)->narguments(), 3u);
97 EXPECT_EQ(gamma->ninputs(), 3u);
98 EXPECT_EQ(graph.GetRootRegion().narguments(), 2u);
134TEST(DeadNodeEliminationTests, Theta)
144 auto & graph = rvsdgModule.
Rvsdg();
151 auto lv1 = theta->AddLoopVar(x);
152 auto lv2 = theta->AddLoopVar(y);
153 auto lv3 = theta->AddLoopVar(z);
154 auto lv4 = theta->AddLoopVar(y);
156 lv1.post->divert_to(lv2.pre);
157 lv2.post->divert_to(lv1.pre);
159 auto t = TestOperation::createNode(theta->subregion(), { lv3.pre }, { valueType })->output(0);
160 lv3.post->divert_to(t);
161 lv4.post->divert_to(lv2.pre);
163 auto c = TestOperation::createNode(theta->subregion(), {}, { controlType })->output(0);
164 theta->set_predicate(c);
175 EXPECT_EQ(theta->noutputs(), 3u);
176 EXPECT_EQ(theta->subregion()->numNodes(), 1u);
177 EXPECT_EQ(graph.GetRootRegion().narguments(), 2u);
180TEST(DeadNodeEliminationTests, NestedTheta)
189 auto & graph = rvsdgModule.
Rvsdg();
196 auto lvo1 = outerTheta->AddLoopVar(c);
197 auto lvo2 = outerTheta->AddLoopVar(x);
198 auto lvo3 = outerTheta->AddLoopVar(y);
202 auto lvi1 = innerTheta->AddLoopVar(lvo1.pre);
203 auto lvi2 = innerTheta->AddLoopVar(lvo2.pre);
204 auto lvi3 = innerTheta->AddLoopVar(lvo3.pre);
206 lvi2.post->divert_to(lvi3.pre);
208 innerTheta->set_predicate(lvi1.pre);
210 lvo2.post->divert_to(lvi2.output);
211 lvo3.post->divert_to(lvi2.output);
213 outerTheta->set_predicate(lvo1.pre);
223 EXPECT_EQ(outerTheta->noutputs(), 3u);
267TEST(DeadNodeEliminationTests, Lambda)
276 auto & graph = rvsdgModule.
Rvsdg();
281 graph.GetRootRegion(),
282 LlvmLambdaOperation::Create(
285 Linkage::externalLinkage));
287 auto cv1 = lambda->AddContextVar(*x).inner;
288 auto cv2 = lambda->AddContextVar(*y).inner;
289 TestOperation::createNode(
291 { lambda->GetFunctionArguments()[0], cv1 },
294 auto output = lambda->finalize({ lambda->GetFunctionArguments()[0], cv2 });
304 EXPECT_EQ(lambda->subregion()->numNodes(), 0u);
305 EXPECT_EQ(graph.GetRootRegion().narguments(), 1u);
308TEST(DeadNodeEliminationTests, Phi)
314 auto valueType = TestType::createValueType();
315 auto functionType = FunctionType::Create({ valueType }, { valueType });
318 auto & rvsdg = rvsdgModule.Rvsdg();
327 LlvmLambdaOperation::Create(functionType,
"f1", Linkage::externalLinkage));
328 auto f2Argument = lambda1->AddContextVar(rv2).inner;
329 auto xArgument = lambda1->AddContextVar(dx).inner;
333 { lambda1->GetFunctionArguments()[0], f2Argument, xArgument },
334 std::vector<std::shared_ptr<const Type>>{ valueType, functionType, valueType },
335 std::vector<std::shared_ptr<const Type>>{ valueType })
338 return lambda1->finalize({ result });
345 LlvmLambdaOperation::Create(functionType,
"f2", Linkage::externalLinkage));
346 auto f1Argument = lambda2->AddContextVar(rv1).inner;
347 lambda2->AddContextVar(dy);
350 { lambda2->GetFunctionArguments()[0], f1Argument },
351 std::vector<std::shared_ptr<const Type>>{ valueType, functionType },
352 std::vector<std::shared_ptr<const Type>>{ valueType })
355 return lambda2->finalize({ result });
362 LlvmLambdaOperation::Create(functionType,
"f3", Linkage::externalLinkage));
363 auto zArgument = lambda3->AddContextVar(dz).inner;
366 { lambda3->GetFunctionArguments()[0], zArgument },
367 std::vector<std::shared_ptr<const Type>>{ valueType, valueType },
368 std::vector<std::shared_ptr<const Type>>{ valueType })
371 return lambda3->finalize({ result });
374 auto setupF4 = [&](
Region & region)
378 LlvmLambdaOperation::Create(functionType,
"f4", Linkage::externalLinkage));
379 return lambda->finalize({ lambda->GetFunctionArguments()[0] });
383 phiBuilder.
begin(&rvsdg.GetRootRegion());
384 auto & phiSubregion = *phiBuilder.
subregion();
386 auto rv1 = phiBuilder.
AddFixVar(functionType);
387 auto rv2 = phiBuilder.
AddFixVar(functionType);
388 auto rv3 = phiBuilder.
AddFixVar(functionType);
389 auto rv4 = phiBuilder.
AddFixVar(functionType);
394 auto f1 = setupF1(phiSubregion, *rv2.recref, *dx.inner);
395 auto f2 = setupF2(phiSubregion, *rv1.recref, *dy.inner);
396 auto f3 = setupF3(phiSubregion, *dz.inner);
397 auto f4 = setupF4(phiSubregion);
399 rv1.result->divert_to(f1);
400 rv2.result->divert_to(f2);
401 rv3.result->divert_to(f3);
402 rv4.result->divert_to(f4);
403 auto phiNode = phiBuilder.
end();
414 EXPECT_EQ(phiNode->noutputs(), 3u);
415 EXPECT_EQ(phiNode->output(0), rv1.output);
416 EXPECT_EQ(phiNode->output(1), rv2.output);
417 EXPECT_EQ(phiNode->output(2), rv4.output);
418 EXPECT_EQ(phiSubregion.nresults(), 3u);
419 EXPECT_EQ(phiSubregion.result(0), rv1.result);
420 EXPECT_EQ(phiSubregion.result(1), rv2.result);
421 EXPECT_EQ(phiSubregion.result(2), rv4.result);
422 EXPECT_EQ(phiSubregion.narguments(), 4u);
423 EXPECT_EQ(phiSubregion.argument(0), rv1.recref);
424 EXPECT_EQ(phiSubregion.argument(1), rv2.recref);
425 EXPECT_EQ(phiSubregion.argument(2), rv4.recref);
426 EXPECT_EQ(phiSubregion.argument(3), dx.inner);
427 EXPECT_EQ(phiNode->ninputs(), 1u);
428 EXPECT_EQ(phiNode->input(0), dx.input);
431TEST(DeadNodeEliminationTests, Delta)
437 auto valueType = TestType::createValueType();
440 auto & rvsdg = rvsdgModule.
Rvsdg();
447 &rvsdg.GetRootRegion(),
448 LlvmDeltaOperation::Create(valueType,
"delta", Linkage::externalLinkage,
"",
false, 4));
450 auto xArgument = deltaNode->AddContextVar(*x).inner;
451 deltaNode->AddContextVar(*y);
452 auto zArgument = deltaNode->AddContextVar(*z).inner;
456 std::vector<std::shared_ptr<const Type>>{ valueType },
457 std::vector<std::shared_ptr<const Type>>{ valueType })
462 std::vector<std::shared_ptr<const Type>>{ valueType },
463 std::vector<std::shared_ptr<const Type>>{ valueType });
465 auto deltaOutput = &deltaNode->finalize(result);
474 EXPECT_EQ(deltaNode->subregion()->numNodes(), 1u);
475 EXPECT_EQ(deltaNode->ninputs(), 1u);
478TEST(DeadNodeEliminationTests, LoadNodes)
484 const auto pointerType = PointerType::Create();
485 const auto memoryStateType = MemoryStateType::Create();
486 const auto valueType = TestType::createValueType();
489 auto & rvsdg = rvsdgModule.
Rvsdg();
491 auto lambdaNode = LambdaNode::Create(
492 rvsdg.GetRootRegion(),
493 LlvmLambdaOperation::Create(
494 FunctionType::Create({ pointerType, memoryStateType }, { memoryStateType }),
496 Linkage::externalLinkage));
497 auto addressArgument = lambdaNode->GetFunctionArguments()[0];
498 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[1];
500 auto & oneNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 1);
501 auto allocaResults = AllocaOperation::create(pointerType, oneNode.output(0), 4);
503 auto & storeNode = StoreNonVolatileOperation::CreateNode(
506 { allocaResults[1] },
509 auto & allocaLoadNode = LoadNonVolatileOperation::CreateNode(
511 { storeNode.output(0) },
515 auto & loadNode = LoadNonVolatileOperation::CreateNode(
516 *allocaLoadNode.output(0),
517 { memoryStateArgument },
521 auto & lambdaExitMergeNode = LambdaExitMemoryStateMergeOperation::CreateNode(
522 *lambdaNode->subregion(),
523 { allocaLoadNode.output(1), loadNode.output(1) },
526 auto lambdaOutput = lambdaNode->finalize({ lambdaExitMergeNode.output(0) });
527 GraphExport::Create(*lambdaOutput,
"f");
538 Region::containsOperation<LoadNonVolatileOperation>(*lambdaNode->subregion(),
false));
539 EXPECT_EQ(lambdaNode->subregion()->numNodes(), 4u);