34TEST(IOBarrierEliminationTests, testLambdaArgument)
39 auto i32Type = BitType::Create(32);
42 auto functionType = FunctionType::Create({ pointerType, ioStateType }, { i32Type, ioStateType });
45 auto & rvsdg = rvsdgModule->Rvsdg();
47 auto lambdaNode = LambdaNode::Create(
48 rvsdg.GetRootRegion(),
50 auto ptrArgument = lambdaNode->GetFunctionArguments()[0];
51 auto ioStateArgument = lambdaNode->GetFunctionArguments()[1];
53 auto & hoistBarrierNode =
59 auto lambdaOutput = lambdaNode->finalize({ loadNode.output(0), ioStateArgument });
60 GraphExport::Create(*lambdaOutput,
"test");
68 EXPECT_TRUE(Region::containsOperation<MemoryHoistBarrierOperation>(rvsdg.GetRootRegion(),
true));
71TEST(IOBarrierEliminationTests, testSizeIsRespected)
76 auto i8Type = BitType::Create(8);
77 auto i32Type = BitType::Create(32);
81 FunctionType::Create({ pointerType, ioStateType }, { i8Type, i32Type, ioStateType });
84 auto & rvsdg = rvsdgModule->Rvsdg();
86 auto lambdaNode = LambdaNode::Create(
87 rvsdg.GetRootRegion(),
89 auto ptrArgument = lambdaNode->GetFunctionArguments()[0];
90 auto ioStateArgument = lambdaNode->GetFunctionArguments()[1];
95 TestOperation::createNode(lambdaNode->subregion(), { ioStateArgument }, { ioStateType });
97 auto & hoistBarrierNode =
104 lambdaNode->finalize({ loadNode1.output(0), loadNode2.output(0), testNode->output(0) });
105 GraphExport::Create(*lambdaOutput,
"test");
113 EXPECT_TRUE(Region::containsOperation<MemoryHoistBarrierOperation>(rvsdg.GetRootRegion(),
true));
116TEST(IOBarrierEliminationTests, testSuccess)
121 auto i32Type = BitType::Create(32);
122 auto i64Type = BitType::Create(64);
126 FunctionType::Create({ pointerType, ioStateType }, { i64Type, i32Type, ioStateType });
129 auto & rvsdg = rvsdgModule->Rvsdg();
131 auto lambdaNode = LambdaNode::Create(
132 rvsdg.GetRootRegion(),
134 auto ptrArgument = lambdaNode->GetFunctionArguments()[0];
135 auto ioStateArgument = lambdaNode->GetFunctionArguments()[1];
140 TestOperation::createNode(lambdaNode->subregion(), { ioStateArgument }, { ioStateType });
142 auto & hoistBarrierNode =
149 lambdaNode->finalize({ loadNode1.output(0), loadNode2.output(0), testNode->output(0) });
150 GraphExport::Create(*lambdaOutput,
"test");
158 EXPECT_FALSE(Region::containsOperation<MemoryHoistBarrierOperation>(rvsdg.GetRootRegion(),
true));
161TEST(IOBarrierEliminationTests, testInvidiualIOBarrierUserRerouting)
166 auto i8Type = BitType::Create(8);
167 auto i32Type = BitType::Create(32);
168 auto i64Type = BitType::Create(64);
172 FunctionType::Create({ pointerType, ioStateType }, { i32Type, i8Type, i64Type, ioStateType });
175 auto & rvsdg = rvsdgModule->Rvsdg();
177 auto lambdaNode = LambdaNode::Create(
178 rvsdg.GetRootRegion(),
180 auto ptrArgument = lambdaNode->GetFunctionArguments()[0];
181 auto ioStateArgument = lambdaNode->GetFunctionArguments()[1];
186 TestOperation::createNode(lambdaNode->subregion(), { ioStateArgument }, { ioStateType });
188 auto & hoistBarrierNode =
197 auto lambdaOutput = lambdaNode->finalize(
198 { load32Node.output(0), load8Node.output(0), load64Node.output(0), testNode->output(0) });
199 GraphExport::Create(*lambdaOutput,
"test");
205 EXPECT_TRUE(Region::containsOperation<MemoryHoistBarrierOperation>(rvsdg.GetRootRegion(),
true));
216 EXPECT_NE(mhbOp,
nullptr);
217 EXPECT_EQ(mhbOp->getDereferenceableSize(), 4);
221TEST(IOBarrierEliminationTests, testGamma)
226 auto i32Type = BitType::Create(32);
227 auto i64Type = BitType::Create(64);
228 auto controlType = ControlType::Create(2);
231 auto functionType = FunctionType::Create(
232 { pointerType, controlType, ioStateType },
233 { i32Type, i32Type, ioStateType });
236 auto & rvsdg = rvsdgModule->Rvsdg();
238 auto lambdaNode = LambdaNode::Create(
239 rvsdg.GetRootRegion(),
241 auto ptrArgument = lambdaNode->GetFunctionArguments()[0];
242 auto controlArgument = lambdaNode->GetFunctionArguments()[1];
243 auto ioStateArgument = lambdaNode->GetFunctionArguments()[2];
247 auto gammaNode = GammaNode::create(controlArgument, 2);
248 auto ptrEntryVar = gammaNode->AddEntryVar(ptrArgument);
249 auto ioStateEntryVar = gammaNode->AddEntryVar(ioStateArgument);
253 *ptrEntryVar.branchArgument[0],
254 *ioStateEntryVar.branchArgument[0],
261 *ptrEntryVar.branchArgument[1],
262 *ioStateEntryVar.branchArgument[1],
267 TestOperation::createNode(gammaNode->subregion(1), { load64Node.output(0) }, { i32Type });
270 auto i32ExitVar = gammaNode->AddExitVar({ load32Node.output(0), testNode->output(0) });
271 auto ioStateExitVar = gammaNode->AddExitVar(
272 { ioStateEntryVar.branchArgument[0], ioStateEntryVar.branchArgument[1] });
275 lambdaNode->finalize({ loadNode.output(0), i32ExitVar.output, ioStateExitVar.output });
276 GraphExport::Create(*lambdaOutput,
"test");
284 Region::containsOperation<MemoryHoistBarrierOperation>(*gammaNode->subregion(0),
true));
288 Region::containsOperation<MemoryHoistBarrierOperation>(*gammaNode->subregion(1),
true));
291TEST(IOBarrierEliminationTests, testOnlyLoadsInGamma)
296 auto i32Type = BitType::Create(32);
297 auto controlType = ControlType::Create(2);
301 FunctionType::Create({ pointerType, controlType, ioStateType }, { i32Type, ioStateType });
304 auto & rvsdg = rvsdgModule->Rvsdg();
306 auto lambdaNode = LambdaNode::Create(
307 rvsdg.GetRootRegion(),
309 auto ptrArgument = lambdaNode->GetFunctionArguments()[0];
310 auto controlArgument = lambdaNode->GetFunctionArguments()[1];
311 auto ioStateArgument = lambdaNode->GetFunctionArguments()[2];
313 auto outerGammaNode = GammaNode::create(controlArgument, 2);
314 auto outerPtrEntryVar = outerGammaNode->AddEntryVar(ptrArgument);
315 auto outerCtlEntryVar = outerGammaNode->AddEntryVar(controlArgument);
316 auto outerIOStateEntryVar = outerGammaNode->AddEntryVar(ioStateArgument);
320 *outerPtrEntryVar.branchArgument[0],
321 *outerIOStateEntryVar.branchArgument[0],
326 auto innerGammaNode = GammaNode::create(outerCtlEntryVar.branchArgument[1], 2);
327 auto innerPtrEntryVar = innerGammaNode->AddEntryVar(outerPtrEntryVar.branchArgument[1]);
328 auto innerIOStateEntryVar = innerGammaNode->AddEntryVar(outerIOStateEntryVar.branchArgument[1]);
332 *innerPtrEntryVar.branchArgument[0],
333 *innerIOStateEntryVar.branchArgument[0],
339 *innerPtrEntryVar.branchArgument[1],
340 *innerIOStateEntryVar.branchArgument[1],
345 auto innerI32ExitVar =
346 innerGammaNode->AddExitVar({ load32Node2.output(0), load32Node3.output(0) });
347 auto innerIOStateExitVar = innerGammaNode->AddExitVar(
348 { innerIOStateEntryVar.branchArgument[0], innerIOStateEntryVar.branchArgument[1] });
351 auto outerI32ExitVar =
352 outerGammaNode->AddExitVar({ load32Node1.output(0), innerI32ExitVar.output });
353 auto outerIOStateExitVar = outerGammaNode->AddExitVar(
354 { outerIOStateEntryVar.branchArgument[0], innerIOStateExitVar.output });
356 auto lambdaOutput = lambdaNode->finalize({ outerI32ExitVar.output, outerIOStateExitVar.output });
357 GraphExport::Create(*lambdaOutput,
"test");
366 *outerPtrEntryVar.input->origin());
367 EXPECT_NE(mhbOp,
nullptr);
368 EXPECT_EQ(mhbOp->getDereferenceableSize(), 0u);
375 *innerPtrEntryVar.input->origin());
376 EXPECT_NE(mhbOp,
nullptr);
377 EXPECT_EQ(mhbOp->getDereferenceableSize(), 4u);
381TEST(IOBarrierEliminationTests, testOnlyLoadsInGammaFailure)
386 auto i32Type = BitType::Create(32);
387 auto controlType = ControlType::Create(2);
391 FunctionType::Create({ pointerType, controlType, ioStateType }, { i32Type, ioStateType });
394 auto & rvsdg = rvsdgModule->Rvsdg();
396 auto lambdaNode = LambdaNode::Create(
397 rvsdg.GetRootRegion(),
399 auto ptrArgument = lambdaNode->GetFunctionArguments()[0];
400 auto controlArgument = lambdaNode->GetFunctionArguments()[1];
401 auto ioStateArgument = lambdaNode->GetFunctionArguments()[2];
403 auto gammaNode = GammaNode::create(controlArgument, 2);
404 auto ptrEntryVar = gammaNode->AddEntryVar(ptrArgument);
405 auto ioStateEntryVar = gammaNode->AddEntryVar(ioStateArgument);
409 *ptrEntryVar.branchArgument[0],
410 *ioStateEntryVar.branchArgument[0],
415 auto testNode = TestOperation::createNode(
416 gammaNode->subregion(1),
417 { ioStateEntryVar.branchArgument[1] },
420 *ptrEntryVar.branchArgument[1],
421 *testNode->output(0),
426 auto outerI32ExitVar = gammaNode->AddExitVar({ load32Node1.output(0), load32Node2.output(0) });
427 auto outerIOStateExitVar =
428 gammaNode->AddExitVar({ ioStateEntryVar.branchArgument[0], testNode->output(0) });
430 auto lambdaOutput = lambdaNode->finalize({ outerI32ExitVar.output, outerIOStateExitVar.output });
431 GraphExport::Create(*lambdaOutput,
"test");
439 Region::containsOperation<MemoryHoistBarrierOperation>(*lambdaNode->subregion(),
false));
442TEST(IOBarrierEliminationTests, testLoadsInGammaNoReturn)
447 auto i32Type = BitType::Create(32);
448 auto controlType = ControlType::Create(2);
452 FunctionType::Create({ pointerType, controlType, ioStateType }, { i32Type, ioStateType });
455 auto & rvsdg = rvsdgModule->Rvsdg();
457 auto lambdaNode = LambdaNode::Create(
458 rvsdg.GetRootRegion(),
460 auto ptrArgument = lambdaNode->GetFunctionArguments()[0];
461 auto controlArgument = lambdaNode->GetFunctionArguments()[1];
462 auto ioStateArgument = lambdaNode->GetFunctionArguments()[2];
464 auto upperGammaNode = GammaNode::create(controlArgument, 2);
465 auto upperPtrEntryVar = upperGammaNode->AddEntryVar(ptrArgument);
466 auto upperIOStateEntryVar = upperGammaNode->AddEntryVar(ioStateArgument);
470 *upperPtrEntryVar.branchArgument[0],
471 *upperIOStateEntryVar.branchArgument[0],
476 auto testNode = TestOperation::createNode(
477 upperGammaNode->subregion(1),
478 { upperIOStateEntryVar.branchArgument[1] },
481 *upperPtrEntryVar.branchArgument[1],
482 *testNode->output(0),
487 auto upperI32ExitVar =
488 upperGammaNode->AddExitVar({ load32Node1.output(0), load32Node2.output(0) });
489 auto upperIOStateExitVar =
490 upperGammaNode->AddExitVar({ upperIOStateEntryVar.branchArgument[0], testNode->output(0) });
492 auto lowerGammaNode = GammaNode::create(controlArgument, 2);
493 auto lowerPtrEntryVar = lowerGammaNode->AddEntryVar(ptrArgument);
494 auto lowerIOStateEntryVar = lowerGammaNode->AddEntryVar(upperIOStateExitVar.output);
498 *lowerPtrEntryVar.branchArgument[0],
499 *lowerIOStateEntryVar.branchArgument[0],
505 *lowerPtrEntryVar.branchArgument[1],
506 *lowerIOStateEntryVar.branchArgument[1],
511 auto lowerI32ExitVar =
512 lowerGammaNode->AddExitVar({ load32Node3.output(0), load32Node4.output(0) });
513 auto lowerIOStateExitVar = lowerGammaNode->AddExitVar(
514 { lowerIOStateEntryVar.branchArgument[0], lowerIOStateEntryVar.branchArgument[1] });
516 auto testNode2 = TestOperation::createNode(
517 lambdaNode->subregion(),
518 { upperI32ExitVar.output, lowerI32ExitVar.output },
521 auto lambdaOutput = lambdaNode->finalize({ testNode2->output(0), lowerIOStateExitVar.output });
522 GraphExport::Create(*lambdaOutput,
"test");
530 Region::containsOperation<MemoryHoistBarrierOperation>(*lowerGammaNode->subregion(0),
false));
532 Region::containsOperation<MemoryHoistBarrierOperation>(*lowerGammaNode->subregion(1),
false));
537 auto [mhbNode, mhbOpt] = TryGetSimpleNodeAndOptionalOp<MemoryHoistBarrierOperation>(
538 *lowerPtrEntryVar.input->origin());
539 EXPECT_NE(mhbOpt,
nullptr);
540 EXPECT_EQ(mhbOpt->getDereferenceableSize(), 0u);
545 Region::containsOperation<MemoryHoistBarrierOperation>(*upperGammaNode->subregion(0),
false));
547 Region::containsOperation<MemoryHoistBarrierOperation>(*upperGammaNode->subregion(1),
false));
550TEST(IOBarrierEliminationTest, testNormalizeation)
557 auto functionType = FunctionType::Create(
558 { pointerType, ioStateType },
559 { pointerType, pointerType, pointerType, pointerType, pointerType, ioStateType });
563 auto lambdaNode = LambdaNode::Create(
564 rvsdg.GetRootRegion(),
566 auto ptrArgument = lambdaNode->GetFunctionArguments()[0];
567 auto ioStateArgument = lambdaNode->GetFunctionArguments()[1];
569 auto & hoistBarrierNode0 =
572 auto structuralNode = TestStructuralNode::create(lambdaNode->subregion(), 2);
573 auto ptrInputVar = structuralNode->addInputWithArguments(*ptrArgument);
574 auto ioStateInputVar = structuralNode->addInputWithArguments(*ioStateArgument);
578 *ptrInputVar.argument[0],
579 *ioStateInputVar.argument[0],
586 auto ptrOutputVar1 = structuralNode->addOutputWithResults(
587 { hoistBarrierNode1.output(0), ptrInputVar.argument[1] });
589 structuralNode->addOutputWithResults({ ptrInputVar.argument[0], ptrInputVar.argument[1] });
590 auto ioStateOutputVar = structuralNode->addOutputWithResults(
591 { ioStateInputVar.argument[0], ioStateInputVar.argument[1] });
593 auto & hoistBarrierNode2 =
596 auto & hoistBarrierNode3 =
599 auto lambdaOutput = lambdaNode->finalize({ hoistBarrierNode0.output(0),
600 hoistBarrierNode2.output(0),
601 ptrOutputVar1.output,
602 ptrOutputVar2.output,
603 hoistBarrierNode3.output(0),
604 ioStateOutputVar.output });
605 GraphExport::Create(*lambdaOutput,
"test");
611 EXPECT_EQ(ptrArgument->nusers(), 1);
612 EXPECT_EQ(ptrInputVar.argument[0]->nusers(), 1);
613 EXPECT_EQ(ptrOutputVar1.output->nusers(), 1);
615 EXPECT_EQ(ptrInputVar.input->origin(), hoistBarrierNode0.output(0));
616 EXPECT_EQ(ptrOutputVar2.result[0]->origin(), hoistBarrierNode1.output(0));
617 EXPECT_EQ(lambdaNode->GetFunctionResults()[2]->origin(), hoistBarrierNode2.output(0));
620 hoistBarrierNode0.output(0));
628 auto i32Type = BitType::Create(32);
629 auto controlType = ControlType::Create(2);
633 auto functionType = FunctionType::Create(
634 { pointerType, i32Type, controlType, ioStateType, memoryState },
635 { i32Type, ioStateType, memoryState });
638 auto & rvsdg = rvsdgModule->Rvsdg();
640 auto lambdaNode = LambdaNode::Create(
641 rvsdg.GetRootRegion(),
643 auto ptrArgument = lambdaNode->GetFunctionArguments()[0];
644 auto i32Argument = lambdaNode->GetFunctionArguments()[1];
645 auto controlArgument = lambdaNode->GetFunctionArguments()[2];
646 auto ioStateArgument = lambdaNode->GetFunctionArguments()[3];
647 auto memoryStateArgument = lambdaNode->GetFunctionArguments()[4];
652 auto gammaNode = GammaNode::create(controlArgument, 2);
653 auto ptrEntryVar = gammaNode->AddEntryVar(ptrArgument);
654 auto ioStateEntryVar = gammaNode->AddEntryVar(ioStateArgument);
655 auto i32EntryVar = gammaNode->AddEntryVar(i32Argument);
656 auto memoryStateEntryVar = gammaNode->AddEntryVar(storeNode.output(0));
660 *ptrEntryVar.branchArgument[0],
661 *ioStateEntryVar.branchArgument[0],
664 *hoistBarrierNode.output(0),
665 { memoryStateEntryVar.branchArgument[0] },
672 auto i32ExitVar = gammaNode->AddExitVar(
674 auto ioStateExitVar = gammaNode->AddExitVar(
675 { ioStateEntryVar.branchArgument[0], ioStateEntryVar.branchArgument[1] });
676 auto memoryStateExitVar =
677 gammaNode->AddExitVar({ load32Node.output(1), memoryStateEntryVar.branchArgument[1] });
680 lambdaNode->finalize({ i32ExitVar.output, ioStateExitVar.output, memoryStateExitVar.output });
681 GraphExport::Create(*lambdaOutput,
"test");
689 Region::containsOperation<MemoryHoistBarrierOperation>(*lambdaNode->subregion(),
true));
692TEST(IOBarrierEliminationTests, testNormalizationFromLoadedAddress)
697 auto i32Type = BitType::Create(32);
700 auto controlType = ControlType::Create(2);
701 auto functionType = FunctionType::Create({ pointerType, ioStateType }, { i32Type, ioStateType });
704 auto & rvsdg = rvsdgModule->Rvsdg();
706 auto lambdaNode = LambdaNode::Create(
707 rvsdg.GetRootRegion(),
709 auto ptrArgument = lambdaNode->GetFunctionArguments()[0];
710 auto ioStateArgument = lambdaNode->GetFunctionArguments()[1];
721 auto testNode = TestOperation::createNode(lambdaNode->subregion(), {}, { controlType });
722 auto gammaNode = GammaNode::create(testNode->output(0), 2);
725 auto ioStateEntryVar = gammaNode->AddEntryVar(ioStateArgument);
729 *ptrEntryVar.branchArgument[0],
730 *ioStateEntryVar.branchArgument[0],
738 auto i32ExitVar = gammaNode->AddExitVar(
740 auto ioStateExitVar = gammaNode->AddExitVar(
741 { ioStateEntryVar.branchArgument[0], ioStateEntryVar.branchArgument[1] });
743 auto lambdaOutput = lambdaNode->finalize({ i32ExitVar.output, ioStateExitVar.output });
744 GraphExport::Create(*lambdaOutput,
"test");
751 EXPECT_EQ(ptrEntryVar.input->origin(), hoistBarrierNode1.output(0));