6 #include <gtest/gtest.h>
21 TEST(MemoryConverterTests, TestTraceArgument)
29 std::cout <<
"Function Setup" << std::endl;
38 rvsdgModule->Rvsdg().GetRootRegion(),
42 auto loadAddress = lambda->GetFunctionArguments()[0];
43 auto memoryStateArgument = lambda->GetFunctionArguments()[3];
46 { memoryStateArgument },
50 auto storeAddress = lambda->GetFunctionArguments()[1];
51 auto storeData = lambda->GetFunctionArguments()[2];
55 auto lambdaOutput = lambda->finalize({ storeOutput[0] });
64 EXPECT_EQ(tracedPointerNodesVector.size(), 2);
65 EXPECT_EQ(tracedPointerNodesVector[0].loadNodes.size(), 1);
66 EXPECT_EQ(tracedPointerNodesVector[0].storeNodes.size(), 0);
68 tracedPointerNodesVector[0].decoupleNodes.size(),
70 EXPECT_EQ(tracedPointerNodesVector[1].loadNodes.size(), 0);
71 EXPECT_EQ(tracedPointerNodesVector[1].storeNodes.size(), 1);
72 EXPECT_EQ(tracedPointerNodesVector[1].decoupleNodes.size(), 0);
75 TEST(MemoryConverterTests, TestLoad)
83 std::cout <<
"Function Setup" << std::endl;
89 rvsdgModule->Rvsdg().GetRootRegion(),
93 auto loadAddress = lambda->GetFunctionArguments()[0];
94 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
97 { memoryStateArgument },
101 auto lambdaOutput = lambda->finalize({ loadOutput[0], loadOutput[1] });
113 auto region = &rvsdgModule->Rvsdg().GetRootRegion();
114 EXPECT_EQ(region->numNodes(), 1);
115 lambda = jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(region->Nodes().begin().ptr());
118 auto lambdaRegion = lambda->subregion();
119 EXPECT_EQ(lambdaRegion->numNodes(), 3);
120 EXPECT_EQ(lambdaRegion->narguments(), 3);
121 EXPECT_EQ(lambdaRegion->nresults(), 3);
124 EXPECT_TRUE(is<MemoryStateType>(lambdaRegion->result(1)->origin()->Type()));
128 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(lambdaRegion->result(0)->origin())->node();
129 EXPECT_TRUE(is<jlm::hls::LoadOperation>(loadNode));
133 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(lambdaRegion->result(1)->origin())->node();
134 EXPECT_TRUE(is<jlm::hls::LoadOperation>(loadNode));
138 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(lambdaRegion->result(2)->origin())->node();
139 EXPECT_TRUE(is<MemoryRequestOperation>(requestNode));
143 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(loadNode->input(2)->origin())->node();
144 EXPECT_TRUE(is<MemoryResponseOperation>(responseNode));
147 auto responseSource = responseNode->input(0)->origin();
148 auto regionArgument = jlm::util::assertedCast<jlm::rvsdg::RegionArgument>(responseSource);
149 EXPECT_EQ(regionArgument->index(), 2);
152 TEST(MemoryConverterTests, TestStore)
160 std::cout <<
"Function Setup" << std::endl;
168 rvsdgModule->Rvsdg().GetRootRegion(),
172 auto storeAddress = lambda->GetFunctionArguments()[0];
173 auto storeData = lambda->GetFunctionArguments()[1];
174 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
178 auto lambdaOutput = lambda->finalize({ storeOutput[0] });
190 auto region = &rvsdgModule->Rvsdg().GetRootRegion();
191 EXPECT_EQ(region->numNodes(), 1);
192 lambda = jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(region->Nodes().begin().ptr());
195 auto lambdaRegion = lambda->subregion();
196 EXPECT_EQ(lambdaRegion->numNodes(), 4);
197 EXPECT_EQ(lambdaRegion->narguments(), 4);
198 EXPECT_EQ(lambdaRegion->nresults(), 2);
200 EXPECT_TRUE(is<MemoryStateType>(lambdaRegion->result(0)->origin()->Type()));
202 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(lambdaRegion->result(0)->origin())->node();
204 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(bufferNode->input(0)->origin())->node();
205 EXPECT_TRUE(is<jlm::hls::StoreOperation>(storeNode));
207 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(lambdaRegion->result(1)->origin())->node();
208 EXPECT_TRUE(is<MemoryRequestOperation>(requestNode));
211 auto requestSource = requestNode->input(0)->origin();
212 storeNode = jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(requestSource)->node();
213 EXPECT_TRUE(is<jlm::hls::StoreOperation>(storeNode));
216 TEST(MemoryConverterTests, TestLoadStore)
224 std::cout <<
"Function Setup" << std::endl;
232 rvsdgModule->Rvsdg().GetRootRegion(),
236 auto loadAddress = lambda->GetFunctionArguments()[0];
237 auto storeData = lambda->GetFunctionArguments()[1];
238 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
241 { memoryStateArgument },
247 auto lambdaOutput = lambda->finalize({ storeOutput[0] });
259 auto region = &rvsdgModule->Rvsdg().GetRootRegion();
260 EXPECT_EQ(region->numNodes(), 1);
261 lambda = jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(region->Nodes().begin().ptr());
264 auto lambdaRegion = lambda->subregion();
265 EXPECT_EQ(lambdaRegion->numNodes(), 7);
266 EXPECT_EQ(lambdaRegion->narguments(), 5);
267 EXPECT_EQ(lambdaRegion->nresults(), 3);
269 std::cout << lambdaRegion->result(0)->origin()->Type()->debug_string() << std::endl;
270 EXPECT_TRUE(is<MemoryStateType>(lambdaRegion->result(0)->origin()->Type()));
272 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(lambdaRegion->result(0)->origin())->node();
274 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(bufferNode->input(0)->origin())->node();
275 EXPECT_TRUE(is<jlm::hls::StoreOperation>(storeNode));
276 auto firstRequestNode =
277 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(lambdaRegion->result(1)->origin())->node();
278 EXPECT_TRUE(is<MemoryRequestOperation>(firstRequestNode));
279 auto secondRequestNode =
280 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(lambdaRegion->result(2)->origin())->node();
281 EXPECT_TRUE(is<MemoryRequestOperation>(secondRequestNode));
283 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(storeNode->input(0)->origin())->node();
284 EXPECT_TRUE(is<jlm::hls::LoadOperation>(loadNode));
286 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(loadNode->input(2)->origin())->node();
287 EXPECT_TRUE(is<MemoryResponseOperation>(responseNode));
290 TEST(MemoryConverterTests, TestThetaLoad)
298 std::cout <<
"Function Setup" << std::endl;
308 rvsdgModule->Rvsdg().GetRootRegion(),
314 auto idv = theta->AddLoopVar(lambda->GetFunctionArguments()[0]);
315 auto lvs = theta->AddLoopVar(lambda->GetFunctionArguments()[1]);
316 auto lve = theta->AddLoopVar(lambda->GetFunctionArguments()[2]);
317 auto arm = jlm::rvsdg::CreateOpNode<jlm::rvsdg::bitadd_op>({ idv.pre, lvs.pre }, 32).output(0);
318 auto cmp = jlm::rvsdg::CreateOpNode<jlm::rvsdg::bitult_op>({ arm, lve.pre }, 32).output(0);
320 idv.post->divert_to(arm);
321 theta->set_predicate(matchNode.output(0));
324 auto loadAddress = theta->AddLoopVar(lambda->GetFunctionArguments()[3]);
325 auto memoryStateArgument = theta->AddLoopVar(lambda->GetFunctionArguments()[4]);
328 { memoryStateArgument.pre },
331 loadAddress.post->divert_to(loadOutput[0]);
332 memoryStateArgument.post->divert_to(loadOutput[1]);
334 auto lambdaOutput = lambda->finalize({ theta->output(3), theta->output(4) });
337 auto lambdaRegion = lambda->subregion();
346 auto & entryMemoryStateSplitInput = lambdaRegion->argument(4)->SingleUser();
347 auto * entryMemoryStateSplitNode =
348 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(entryMemoryStateSplitInput);
349 EXPECT_TRUE(is<LambdaEntryMemoryStateSplitOperation>(entryMemoryStateSplitNode));
350 auto exitMemoryStateMergeNode =
351 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(lambdaRegion->result(1)->origin())->node();
352 EXPECT_TRUE(is<LambdaExitMemoryStateMergeOperation>(exitMemoryStateMergeNode));
358 EXPECT_TRUE(jlm::rvsdg::Region::ContainsNodeType<LoopNode>(*lambdaRegion,
true));
365 EXPECT_TRUE(jlm::rvsdg::Region::ContainsOperation<StateGateOperation>(*lambdaRegion,
true));
367 jlm::rvsdg::Region::ContainsOperation<MemoryStateSplitOperation>(*lambdaRegion,
true));
369 jlm::rvsdg::Region::ContainsOperation<MemoryStateMergeOperation>(*lambdaRegion,
true));
378 auto region = &rvsdgModule->Rvsdg().GetRootRegion();
379 EXPECT_EQ(region->numNodes(), 1);
380 lambda = jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(region->Nodes().begin().ptr());
381 lambdaRegion = lambda->subregion();
383 EXPECT_TRUE(jlm::rvsdg::Region::ContainsOperation<MemoryResponseOperation>(*lambdaRegion,
true));
384 EXPECT_TRUE(jlm::rvsdg::Region::ContainsOperation<MemoryRequestOperation>(*lambdaRegion,
true));
388 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(lambdaRegion->result(2)->origin())->node();
389 EXPECT_TRUE(is<MemoryRequestOperation>(requestNode));
393 jlm::util::assertedCast<const jlm::rvsdg::StructuralOutput>(requestNode->input(0)->origin());
394 auto loopNode = jlm::util::assertedCast<const jlm::rvsdg::StructuralNode>(loopOutput->node());
395 EXPECT_NE(
dynamic_cast<const LoopNode *
>(loopNode),
nullptr);
397 auto & thetaResult = loopOutput->results;
398 EXPECT_EQ(thetaResult.size(), 1);
401 jlm::util::assertedCast<const jlm::rvsdg::NodeOutput>(thetaResult.first()->origin())->node();
402 EXPECT_TRUE(is<DecoupledLoadOperation>(loadNode));
405 jlm::util::assertedCast<const jlm::rvsdg::RegionArgument>(loadNode->input(1)->origin());
406 auto thetaInput = thetaArgument->input();
410 jlm::util::assertedCast<const jlm::rvsdg::NodeOutput>(thetaInput->origin())->node();
411 EXPECT_TRUE(is<MemoryResponseOperation>(responseNode));
414 EXPECT_TRUE(is<jlm::rvsdg::RegionArgument>(responseNode->input(0)->origin()));
417 TEST(MemoryConverterTests, TestThetaStore)
425 std::cout <<
"Function Setup" << std::endl;
436 rvsdgModule->Rvsdg().GetRootRegion(),
442 auto idv = theta->AddLoopVar(lambda->GetFunctionArguments()[0]);
443 auto lvs = theta->AddLoopVar(lambda->GetFunctionArguments()[1]);
444 auto lve = theta->AddLoopVar(lambda->GetFunctionArguments()[2]);
445 auto arm = jlm::rvsdg::CreateOpNode<jlm::rvsdg::bitadd_op>({ idv.pre, lvs.pre }, 32).output(0);
446 auto cmp = jlm::rvsdg::CreateOpNode<jlm::rvsdg::bitult_op>({ arm, lve.pre }, 32).output(0);
448 idv.post->divert_to(arm);
449 theta->set_predicate(matchNode.output(0));
452 auto storeAddress = theta->AddLoopVar(lambda->GetFunctionArguments()[3]);
453 auto storeData = theta->AddLoopVar(lambda->GetFunctionArguments()[4]);
454 auto memoryStateArgument = theta->AddLoopVar(lambda->GetFunctionArguments()[5]);
458 { memoryStateArgument.pre },
460 memoryStateArgument.post->divert_to(storeOutput[0]);
462 auto lambdaOutput = lambda->finalize({ theta->output(5) });
465 auto lambdaRegion = lambda->subregion();
474 auto & entryMemoryStateSplitInput = lambdaRegion->argument(5)->SingleUser();
475 auto * entryMemoryStateSplitNode =
476 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(entryMemoryStateSplitInput);
477 EXPECT_TRUE(is<LambdaEntryMemoryStateSplitOperation>(entryMemoryStateSplitNode));
478 auto exitMemoryStateMergeNode =
479 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(lambdaRegion->result(0)->origin())->node();
480 EXPECT_TRUE(is<LambdaExitMemoryStateMergeOperation>(exitMemoryStateMergeNode));
486 EXPECT_TRUE(jlm::rvsdg::Region::ContainsNodeType<LoopNode>(*lambdaRegion,
true));
494 jlm::rvsdg::Region::ContainsOperation<MemoryStateSplitOperation>(*lambdaRegion,
true));
496 jlm::rvsdg::Region::ContainsOperation<MemoryStateMergeOperation>(*lambdaRegion,
true));
505 auto region = &rvsdgModule->Rvsdg().GetRootRegion();
506 EXPECT_EQ(region->numNodes(), 1);
507 lambda = jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(region->Nodes().begin().ptr());
508 lambdaRegion = lambda->subregion();
510 EXPECT_TRUE(jlm::rvsdg::Region::ContainsOperation<MemoryRequestOperation>(*lambdaRegion,
true));
514 jlm::util::assertedCast<jlm::rvsdg::NodeOutput>(lambdaRegion->result(1)->origin())->node();
515 EXPECT_TRUE(is<MemoryRequestOperation>(requestNode));
519 jlm::util::assertedCast<const jlm::rvsdg::StructuralOutput>(requestNode->input(0)->origin());
520 auto loopNode = jlm::util::assertedCast<const jlm::rvsdg::StructuralNode>(loopOutput->node());
521 EXPECT_NE(
dynamic_cast<const LoopNode *
>(loopNode),
nullptr);
523 auto & thetaResult = loopOutput->results;
524 EXPECT_EQ(thetaResult.size(), 1);
527 jlm::util::assertedCast<const jlm::rvsdg::NodeOutput>(thetaResult.first()->origin())->node();
528 EXPECT_TRUE(is<jlm::hls::StoreOperation>(storeNode));
531 jlm::util::assertedCast<const jlm::rvsdg::NodeOutput>(storeNode->input(2)->origin())->node();
532 EXPECT_TRUE(is<MuxOperation>(ndMuxNode));
534 EXPECT_TRUE(is<jlm::rvsdg::RegionArgument>(ndMuxNode->input(2)->origin()));
static jlm::util::StatisticsCollector statisticsCollector
TEST(MemoryConverterTests, TestTraceArgument)
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::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *address, const Variable *value, const Variable *state, size_t alignment)
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
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 GraphExport & Create(Output &origin, std::string name)
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
static Node & CreateNode(Output &predicate, const std::unordered_map< uint64_t, uint64_t > &mapping, const uint64_t defaultAlternative, const size_t numAlternatives)
static ThetaNode * create(rvsdg::Region *parent)
std::vector< TracedPointerNodes > TracePointerArguments(const rvsdg::LambdaNode *lambda)
Global memory state passed between functions.
std::string view(const rvsdg::Region *region)