6 #include <gtest/gtest.h>
20 TEST(UnusedStateRemovalTests, TestGamma)
28 auto & rvsdg = rvsdgModule->Rvsdg();
37 auto gammaInput1 = gammaNode->AddEntryVar(x);
38 auto gammaInput2 = gammaNode->AddEntryVar(y);
39 auto gammaInput3 = gammaNode->AddEntryVar(z);
40 auto gammaInput4 = gammaNode->AddEntryVar(x);
41 auto gammaInput5 = gammaNode->AddEntryVar(x);
42 auto gammaInput6 = gammaNode->AddEntryVar(x);
43 auto gammaInput7 = gammaNode->AddEntryVar(x);
45 auto gammaOutput1 = gammaNode->AddExitVar(gammaInput1.branchArgument);
47 gammaNode->AddExitVar({ gammaInput2.branchArgument[0], gammaInput3.branchArgument[1] });
49 gammaNode->AddExitVar({ gammaInput4.branchArgument[0], gammaInput5.branchArgument[1] });
51 gammaNode->AddExitVar({ gammaInput6.branchArgument[0], gammaInput6.branchArgument[1] });
53 gammaNode->AddExitVar({ gammaInput6.branchArgument[0], gammaInput7.branchArgument[1] });
66 EXPECT_EQ(gammaNode->ninputs(), 7);
67 EXPECT_EQ(gammaNode->noutputs(), 4);
68 EXPECT_EQ(gammaInput2.input->index(), 1);
69 EXPECT_EQ(gammaOutput2.output->index(), 0);
76 TEST(UnusedStateRemovalTests, TestTheta)
83 auto functionType = FunctionType::Create(
84 { ControlType::Create(2), valueType, valueType, valueType },
88 auto & rvsdg = rvsdgModule->Rvsdg();
95 auto thetaNode = ThetaNode::create(&rvsdg.GetRootRegion());
97 auto loopVarP = thetaNode->AddLoopVar(importP);
98 auto loopVarX = thetaNode->AddLoopVar(importX);
99 auto loopVarY = thetaNode->AddLoopVar(importY);
100 auto loopVarZ = thetaNode->AddLoopVar(importZ);
102 loopVarY.post->divert_to(loopVarZ.pre);
103 loopVarZ.post->divert_to(loopVarY.pre);
104 thetaNode->set_predicate(loopVarP.pre);
106 auto & exportP = GraphExport::Create(*loopVarP.output,
"p");
107 auto & exportX = GraphExport::Create(*loopVarX.output,
"x");
108 auto & exportY = GraphExport::Create(*loopVarY.output,
"y");
109 auto & exportZ = GraphExport::Create(*loopVarZ.output,
"z");
116 EXPECT_EQ(thetaNode->ninputs(), 3);
117 EXPECT_EQ(thetaNode->noutputs(), 3);
119 EXPECT_EQ(TryGetOwnerNode<ThetaNode>(*exportP.origin()), thetaNode);
120 EXPECT_EQ(exportX.origin(), importX);
121 EXPECT_EQ(TryGetOwnerNode<ThetaNode>(*exportY.origin()), thetaNode);
122 EXPECT_EQ(TryGetOwnerNode<ThetaNode>(*exportZ.origin()), thetaNode);
125 TEST(UnusedStateRemovalTests, TestLambda)
133 { valueType, valueType },
134 { valueType, valueType, valueType, valueType });
137 auto & rvsdg = rvsdgModule->Rvsdg();
142 rvsdg.GetRootRegion(),
144 auto argument0 = lambdaNode->GetFunctionArguments()[0];
145 auto argument1 = lambdaNode->GetFunctionArguments()[1];
146 auto argument2 = lambdaNode->AddContextVar(*x).inner;
147 auto argument3 = lambdaNode->AddContextVar(*x).inner;
149 auto result1 = jlm::rvsdg::CreateOpNode<TestOperation>(
151 std::vector<std::shared_ptr<const Type>>{ valueType },
152 std::vector<std::shared_ptr<const Type>>{ valueType })
155 auto result3 = jlm::rvsdg::CreateOpNode<TestOperation>(
157 std::vector<std::shared_ptr<const Type>>{ valueType },
158 std::vector<std::shared_ptr<const Type>>{ valueType })
161 auto lambdaOutput = lambdaNode->finalize({ argument0, result1, argument2, result3 });
170 EXPECT_EQ(rvsdg.GetRootRegion().numNodes(), 1);
171 auto & newLambdaNode =
173 EXPECT_EQ(newLambdaNode.ninputs(), 2);
174 EXPECT_EQ(newLambdaNode.subregion()->narguments(), 3);
175 EXPECT_EQ(newLambdaNode.subregion()->nresults(), 2);
188 TEST(UnusedStateRemovalTests, TestUsedMemoryState)
196 std::cout <<
"Function Setup" << std::endl;
202 rvsdgModule->Rvsdg().GetRootRegion(),
206 auto functionArguments = lambda->GetFunctionArguments();
208 functionArguments[0],
209 { functionArguments[1] },
213 auto lambdaOutput = lambda->finalize({ loadOutput[1] });
224 auto * node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(
225 *rvsdgModule->Rvsdg().GetRootRegion().result(0)->origin());
226 auto lambdaSubregion = jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(node)->subregion();
227 EXPECT_EQ(lambdaSubregion->nresults(), 1);
228 EXPECT_TRUE(is<MemoryStateType>(lambdaSubregion->result(0)->Type()));
231 TEST(UnusedStateRemovalTests, TestUnusedMemoryState)
239 std::cout <<
"Function Setup" << std::endl;
245 rvsdgModule->Rvsdg().GetRootRegion(),
249 auto functionArguments = lambda->GetFunctionArguments();
251 functionArguments[0],
252 { functionArguments[1] },
256 auto lambdaOutput = lambda->finalize({ loadOutput[1], functionArguments[2] });
266 auto * node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(
267 *rvsdgModule->Rvsdg().GetRootRegion().result(0)->origin());
268 auto lambdaSubregion = jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(node)->subregion();
270 EXPECT_EQ(lambdaSubregion->narguments(), 2);
271 EXPECT_EQ(lambdaSubregion->nresults(), 1);
272 EXPECT_TRUE(is<MemoryStateType>(lambdaSubregion->result(0)->Type()));
275 TEST(UnusedStateRemovalTests, TestInvariantMemoryState)
283 std::cout <<
"Function Setup" << std::endl;
289 rvsdgModule->Rvsdg().GetRootRegion(),
292 auto functionArguments = lambda->GetFunctionArguments();
295 auto & memoryStateSplitNode =
300 functionArguments[0],
301 { memoryStateSplitNode.output(0) },
306 std::vector<jlm::rvsdg::Output *>
outputs;
308 *lambda->subregion(),
309 { loadOutput[1], memoryStateSplitNode.output(1) },
312 auto lambdaOutput = lambda->finalize({ memoryStateMerge.output(0) });
323 auto * node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(
324 *rvsdgModule->Rvsdg().GetRootRegion().result(0)->origin());
325 auto lambdaSubregion = jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(node)->subregion();
327 EXPECT_EQ(lambdaSubregion->narguments(), 2);
328 EXPECT_EQ(lambdaSubregion->nresults(), 1);
329 EXPECT_TRUE(is<MemoryStateType>(lambdaSubregion->result(0)->Type()));
330 EXPECT_TRUE(jlm::rvsdg::Region::ContainsOperation<LambdaEntryMemoryStateSplitOperation>(
333 EXPECT_TRUE(jlm::rvsdg::Region::ContainsOperation<LambdaExitMemoryStateMergeOperation>(
static jlm::util::StatisticsCollector statisticsCollector
TEST(UnusedStateRemovalTests, TestGamma)
static void CreateAndRun(rvsdg::RvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector)
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &operand, std::vector< MemoryNodeId > memoryNodeIds)
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, const std::vector< rvsdg::Output * > &operands, const std::vector< MemoryNodeId > &memoryNodeIds)
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)
static std::unique_ptr< LlvmRvsdgModule > Create(const util::FilePath &sourceFileName, const std::string &targetTriple, const std::string &dataLayout)
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *address, const Variable *state, std::shared_ptr< const rvsdg::Type > loadedType, size_t alignment)
static std::shared_ptr< const MemoryStateType > Create()
static std::shared_ptr< const PointerType > Create()
static std::shared_ptr< const ControlType > Create(std::size_t nalternatives)
Instantiates control type.
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)
static GraphExport & Create(Output &origin, std::string name)
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
static std::shared_ptr< const TestType > createValueType()
Global memory state passed between functions.
std::string view(const rvsdg::Region *region)
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)