Jlm
IOStateEliminationTests.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2025 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #include <gtest/gtest.h>
7 
11 #include <jlm/rvsdg/gamma.hpp>
13 #include <jlm/rvsdg/view.hpp>
14 
15 TEST(IOStateEliminationTests, testCall)
16 {
17  using namespace jlm::hls;
18  using namespace jlm::llvm;
19  using namespace jlm::rvsdg;
20 
21  // Arrange
22  auto memoryStateType = MemoryStateType::Create();
23  auto ioStateType = IOStateType::Create();
24  const auto functionType =
25  FunctionType::Create({ ioStateType, memoryStateType }, { ioStateType, memoryStateType });
26 
27  jlm::llvm::LlvmRvsdgModule rvsdgModule(jlm::util::FilePath(""), "", "");
28  auto & rvsdg = rvsdgModule.Rvsdg();
29 
30  auto & i0 = jlm::rvsdg::GraphImport::Create(rvsdg, functionType, "g");
31 
32  const auto lambdaNode = LambdaNode::Create(
33  rvsdg.GetRootRegion(),
34  LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
35 
36  auto ioStateArgument = lambdaNode->GetFunctionArguments()[0];
37  auto memoryStateArgument = lambdaNode->GetFunctionArguments()[1];
38  const auto functionCv = lambdaNode->AddContextVar(i0);
39 
40  auto & callNode = CallOperation::CreateNode(
41  functionCv.inner,
42  functionType,
43  { ioStateArgument, memoryStateArgument });
44 
45  const auto lambdaOutput = lambdaNode->finalize({ callNode.output(0), callNode.output(1) });
46 
47  GraphExport::Create(*lambdaOutput, "f");
48 
49  view(rvsdg, stdout);
50 
51  // Act
52  IOStateElimination ioStateElimination;
54  ioStateElimination.Run(rvsdgModule, statisticsCollector);
55 
56  view(rvsdg, stdout);
57 
58  // Assert
59  EXPECT_TRUE(callNode.output(0)->IsDead());
60  EXPECT_EQ(lambdaNode->GetFunctionResults()[0]->origin(), ioStateArgument);
61 }
62 
63 TEST(IOStateEliminationTests, testNesting)
64 {
65  using namespace jlm::hls;
66  using namespace jlm::llvm;
67  using namespace jlm::rvsdg;
68 
69  // Arrange
70  auto ioStateType = IOStateType::Create();
71  auto memoryStateType = MemoryStateType::Create();
72  auto controlType = ControlType::Create(2);
73  const auto functionType = FunctionType::Create(
74  { controlType, ioStateType, memoryStateType },
75  { ioStateType, memoryStateType });
76 
77  jlm::llvm::LlvmRvsdgModule rvsdgModule(jlm::util::FilePath(""), "", "");
78  auto & rvsdg = rvsdgModule.Rvsdg();
79 
80  const auto lambdaNode = LambdaNode::Create(
81  rvsdg.GetRootRegion(),
82  LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
83 
84  auto controlArgument = lambdaNode->GetFunctionArguments()[0];
85  auto ioStateArgument = lambdaNode->GetFunctionArguments()[1];
86  auto memoryStateArgument = lambdaNode->GetFunctionArguments()[2];
87 
88  auto gammaNode = GammaNode::create(controlArgument, 2);
89 
90  auto entryVar = gammaNode->AddEntryVar(ioStateArgument);
91 
92  auto node1 = TestOperation::createNode(
93  gammaNode->subregion(0),
94  { entryVar.branchArgument[0] },
95  { ioStateType });
96 
97  auto node2 =
98  TestOperation::createNode(gammaNode->subregion(0), { node1->output(0) }, { ioStateType });
99 
100  auto exitVar = gammaNode->AddExitVar({ node2->output(0), entryVar.branchArgument[1] });
101 
102  const auto lambdaOutput = lambdaNode->finalize({ exitVar.output, memoryStateArgument });
103 
104  GraphExport::Create(*lambdaOutput, "f");
105 
106  view(rvsdg, stdout);
107 
108  // Act
109  IOStateElimination ioStateElimination;
111  ioStateElimination.Run(rvsdgModule, statisticsCollector);
112 
113  view(rvsdg, stdout);
114 
115  // Assert
116  EXPECT_TRUE(node1->output(0)->IsDead());
117  EXPECT_TRUE(node2->output(0)->IsDead());
118  EXPECT_TRUE(exitVar.output->IsDead());
119  EXPECT_EQ(lambdaNode->GetFunctionResults()[0]->origin(), ioStateArgument);
120 
121  EXPECT_EQ(gammaNode->GetEntryVars().size(), 3);
122 }
static jlm::util::StatisticsCollector statisticsCollector
TEST(IOStateEliminationTests, testCall)
void Run(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
static rvsdg::SimpleNode & CreateNode(rvsdg::Region &region, std::unique_ptr< CallOperation > callOperation, const std::vector< rvsdg::Output * > &operands)
Definition: call.hpp:489
static std::shared_ptr< const IOStateType > Create()
Definition: types.cpp:343
static std::unique_ptr< LlvmLambdaOperation > Create(std::shared_ptr< const jlm::rvsdg::FunctionType > type, std::string name, const jlm::llvm::Linkage &linkage, jlm::llvm::CallingConvention callingConvention, jlm::llvm::AttributeSet attributes)
Definition: lambda.hpp:84
static std::shared_ptr< const MemoryStateType > Create()
Definition: types.cpp:379
static std::shared_ptr< const ControlType > Create(std::size_t nalternatives)
Instantiates control type.
Definition: control.cpp:50
static std::shared_ptr< const FunctionType > Create(std::vector< std::shared_ptr< const jlm::rvsdg::Type >> argumentTypes, std::vector< std::shared_ptr< const jlm::rvsdg::Type >> resultTypes)
static GammaNode * create(jlm::rvsdg::Output *predicate, size_t nalternatives)
Definition: gamma.hpp:161
static GraphExport & Create(Output &origin, std::string name)
Definition: graph.cpp:62
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Definition: graph.cpp:36
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
Definition: lambda.cpp:140
static SimpleNode * createNode(Region *region, const std::vector< Output * > &operands, std::vector< std::shared_ptr< const Type >> resultTypes)
Global memory state passed between functions.
std::string view(const rvsdg::Region *region)
Definition: view.cpp:142