Skip to content

Commit f748c2b

Browse files
phatesjalander
andauthored
CNE: Fix handling of theta nodes without loop variables (phate#1519)
The subregions of structural nodes without arguments were never visited in CNE's mark phase, leading ultimately to problems in the divert phase as no congruence sets could be found for nodes in such subregions. Closes phate#1482 Co-authored-by: Magnus Sjalander <work@sjalander.com>
1 parent bc046c5 commit f748c2b

File tree

2 files changed

+67
-18
lines changed

2 files changed

+67
-18
lines changed

jlm/llvm/opt/CommonNodeElimination.cpp

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -642,30 +642,38 @@ markSubregionsFromInputs(
642642

643643
for (auto & subregion : node.Subregions())
644644
{
645-
// create a partitioning of the region arguments
646-
std::vector<size_t> partitions(subregion.narguments());
647-
// Arguments that do not belong to any input are given partition keys higher than any real index
648-
size_t nextUniquePartitionKey = context.numCongruenceSets();
649-
650-
for (const auto argument : subregion.Arguments())
645+
if (subregion.narguments() == 0)
651646
{
652-
if (const auto input = argument->input())
647+
markRegion(subregion, context);
648+
}
649+
else
650+
{
651+
// create a partitioning of the region arguments
652+
std::vector<size_t> partitions(subregion.narguments());
653+
// Arguments that do not belong to any input are given partition keys higher than any real
654+
// index
655+
size_t nextUniquePartitionKey = context.numCongruenceSets();
656+
657+
for (const auto argument : subregion.Arguments())
653658
{
654-
// If the argument corresponds to an input, use the partition key of the input
655-
partitions[argument->index()] = context.getSetFor(*input->origin());
659+
if (const auto input = argument->input())
660+
{
661+
// If the argument corresponds to an input, use the partition key of the input
662+
partitions[argument->index()] = context.getSetFor(*input->origin());
663+
}
664+
else
665+
{
666+
// Otherwise make sure the argument is not partitioned with any other argument
667+
partitions[argument->index()] = nextUniquePartitionKey++;
668+
}
656669
}
657-
else
670+
671+
if (partitionArguments(subregion, partitions, context))
658672
{
659-
// Otherwise make sure the argument is not partitioned with any other argument
660-
partitions[argument->index()] = nextUniquePartitionKey++;
673+
anyChanges = true;
674+
markRegion(subregion, context);
661675
}
662676
}
663-
664-
if (partitionArguments(subregion, partitions, context))
665-
{
666-
anyChanges = true;
667-
markRegion(subregion, context);
668-
}
669677
}
670678

671679
return anyChanges;

tests/jlm/llvm/opt/CommonNodeEliminationTests.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,3 +556,44 @@ TEST(CommonNodeEliminationTests, test_phi)
556556
jlm::rvsdg::AssertGetOwnerNode<jlm::rvsdg::LambdaNode>(*f1).input(0)->origin(),
557557
jlm::rvsdg::AssertGetOwnerNode<jlm::rvsdg::LambdaNode>(*f2).input(0)->origin());
558558
}
559+
560+
TEST(CommonNodeEliminationTests, EmptyTheta)
561+
{
562+
using namespace jlm::llvm;
563+
using namespace jlm::rvsdg;
564+
565+
// Arrange
566+
auto valueType = TestType::createValueType();
567+
auto controlType = ControlType::Create(2);
568+
569+
LlvmRvsdgModule rvsdgModule(jlm::util::FilePath(""), "", "");
570+
auto & rvsdg = rvsdgModule.Rvsdg();
571+
572+
auto thetaNode = ThetaNode::create(&rvsdg.GetRootRegion());
573+
574+
auto node1 = TestOperation::createNode(thetaNode->subregion(), {}, { valueType });
575+
auto node2 =
576+
TestOperation::createNode(thetaNode->subregion(), { node1->output(0) }, { valueType });
577+
auto node3 =
578+
TestOperation::createNode(thetaNode->subregion(), { node1->output(0) }, { valueType });
579+
auto node4 = TestOperation::createNode(
580+
thetaNode->subregion(),
581+
{ node2->output(0), node3->output(0) },
582+
{ controlType });
583+
584+
thetaNode->set_predicate(node4->output(0));
585+
586+
view(rvsdg, stdout);
587+
588+
// Act
589+
CommonNodeElimination commonNodeElimination;
590+
commonNodeElimination.Run(rvsdgModule, statisticsCollector);
591+
592+
thetaNode->subregion()->prune(false);
593+
594+
view(rvsdg, stdout);
595+
596+
// Assert
597+
// We expect that node2 and node3 are unified in the theta subregion
598+
EXPECT_EQ(thetaNode->subregion()->numNodes(), 3);
599+
}

0 commit comments

Comments
 (0)