6 #include <gtest/gtest.h>
18 TEST(MemoryStateOperationTests, MemoryStateSplitEquality)
27 TestOperation operation3({ memoryStateType }, { memoryStateType, memoryStateType });
30 EXPECT_EQ(operation1, operation1);
31 EXPECT_NE(operation1, operation2);
32 EXPECT_NE(operation1, operation3);
35 TEST(MemoryStateOperationTests, MemoryStateSplitNormalizeSingleResult)
53 jlm::rvsdg::ReduceNode<MemoryStateSplitOperation>(
61 EXPECT_EQ(ex.origin(), &ix);
64 TEST(MemoryStateOperationTests, MemoryStateSplitNormalizeNestedSplits)
87 jlm::rvsdg::ReduceNode<MemoryStateSplitOperation>(
90 jlm::rvsdg::ReduceNode<MemoryStateSplitOperation>(
99 auto [splitNode, splitOperation] =
100 TryGetSimpleNodeAndOptionalOp<MemoryStateSplitOperation>(*ex0.origin());
101 EXPECT_TRUE(splitNode && splitOperation);
109 EXPECT_EQ(splitNode->noutputs(), 7u);
110 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin()), splitNode);
111 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex1.origin()), splitNode);
112 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex2.origin()), splitNode);
113 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex3.origin()), splitNode);
114 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex4.origin()), splitNode);
117 TEST(MemoryStateOperationTests, MemoryStateSplitNormalizeSplitMerge)
139 jlm::rvsdg::ReduceNode<MemoryStateSplitOperation>(
147 EXPECT_EQ(ex0.origin(), &ix0);
148 EXPECT_EQ(ex1.origin(), &ix1);
149 EXPECT_EQ(ex2.origin(), &ix2);
152 TEST(MemoryStateOperationTests, MemoryStateMergeEquality)
161 TestOperation operation3({ memoryStateType, memoryStateType }, { memoryStateType });
164 EXPECT_EQ(operation1, operation1);
165 EXPECT_NE(operation1, operation2);
166 EXPECT_NE(operation1, operation3);
169 TEST(MemoryStateOperationTests, MemoryStateMergeNormalizeSingleOperand)
187 ReduceNode<MemoryStateMergeOperation>(
195 EXPECT_EQ(ex.origin(), &ix);
198 TEST(MemoryStateOperationTests, MemoryStateMergeNormalizeDuplicateOperands)
217 ReduceNode<MemoryStateMergeOperation>(
225 auto [mergeNode, mergeOperation] =
226 TryGetSimpleNodeAndOptionalOp<MemoryStateMergeOperation>(*ex.origin());
227 EXPECT_TRUE(mergeNode && mergeOperation);
229 EXPECT_EQ(mergeNode->ninputs(), 2u);
232 TEST(MemoryStateOperationTests, MemoryStateMergeNormalizeNestedMerges)
257 ReduceNode<MemoryStateMergeOperation>(
265 auto [mergeNode, mergeOperation] =
266 TryGetSimpleNodeAndOptionalOp<MemoryStateMergeOperation>(*ex.origin());
267 EXPECT_TRUE(mergeNode && mergeOperation);
269 EXPECT_EQ(mergeNode->ninputs(), 5u);
272 TEST(MemoryStateOperationTests, MemoryStateMergeNormalizeNestedSplits)
288 splitNode0.output(1),
289 splitNode1.output(0),
290 splitNode1.output(1),
304 auto [node, mergeOperation] =
305 TryGetSimpleNodeAndOptionalOp<MemoryStateMergeOperation>(*ex.origin());
306 EXPECT_TRUE(node && mergeOperation);
308 EXPECT_EQ(node->ninputs(), 5u);
309 EXPECT_EQ(node->input(0)->origin(), &ix0);
310 EXPECT_EQ(node->input(1)->origin(), &ix0);
311 EXPECT_EQ(node->input(2)->origin(), &ix1);
312 EXPECT_EQ(node->input(3)->origin(), &ix1);
313 EXPECT_EQ(node->input(4)->origin(), &ix2);
316 TEST(MemoryStateOperationTests, MemoryStateJoin_NormalizeSingleOperand)
329 auto & ex = GraphExport::Create(*mergeNode.output(0),
"x");
340 EXPECT_EQ(ex.origin(), &ix);
343 TEST(MemoryStateOperationTests, MemoryStateJoin_NormalizeDuplicateOperands)
358 auto & x0 = GraphExport::Create(*node0.output(0),
"x0");
359 auto & x1 = GraphExport::Create(*node1.output(0),
"x1");
373 auto [joinNode, joinOperation] =
374 TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(*x0.origin());
375 EXPECT_TRUE(joinNode && joinOperation);
377 EXPECT_EQ(joinNode->ninputs(), 2u);
378 EXPECT_EQ(joinNode->input(0)->origin(), &i0);
379 EXPECT_EQ(joinNode->input(1)->origin(), &i1);
383 EXPECT_EQ(x1.origin(), &i0);
387 TEST(MemoryStateOperationTests, MemoryStateJoin_NormalizeNestedJoins)
409 auto & ex = GraphExport::Create(*joinNode3.output(0),
"x");
420 auto [joinNode, joinOperation] =
421 TryGetSimpleNodeAndOptionalOp<MemoryStateJoinOperation>(*ex.origin());
422 EXPECT_TRUE(joinNode && joinOperation);
424 EXPECT_EQ(joinNode->ninputs(), 6u);
425 EXPECT_EQ(joinNode->input(0)->origin(), &ix0);
426 EXPECT_EQ(joinNode->input(1)->origin(), &ix1);
427 EXPECT_EQ(joinNode->input(2)->origin(), &ix2);
428 EXPECT_EQ(joinNode->input(3)->origin(), &ix3);
429 EXPECT_EQ(joinNode->input(4)->origin(), &ix4);
430 EXPECT_EQ(joinNode->input(5)->origin(), &ix5);
433 TEST(MemoryStateOperationTests, LambdaEntryMemStateOperatorEquality)
443 const TestOperation operation4({ memoryStateType }, { memoryStateType, memoryStateType });
446 EXPECT_EQ(operation1, operation1);
447 EXPECT_NE(operation1, operation2);
448 EXPECT_NE(operation1, operation3);
449 EXPECT_NE(operation1, operation4);
452 TEST(MemoryStateOperationTests, LambdaExitMemStateOperatorEquality)
462 TestOperation operation4({ memoryStateType, memoryStateType }, { memoryStateType });
465 EXPECT_EQ(operation1, operation1);
466 EXPECT_NE(operation1, operation2);
467 EXPECT_NE(operation1, operation3);
468 EXPECT_NE(operation1, operation3);
471 TEST(MemoryStateOperationTests, LambdaExitMemoryStateMergeNormalizeLoad)
477 const auto bit32Type = BitType::Create(32);
479 const auto valueType = TestType::createValueType();
492 { loadNode.output(1), &memState1 },
497 { &memState2, &memState1 },
500 auto & x = GraphExport::Create(*lambdaExitMergeNode1.output(0),
"x");
501 auto & y = GraphExport::Create(*lambdaExitMergeNode2.output(0),
"y");
502 GraphExport::Create(*loadNode.output(0),
"z");
507 const auto success = jlm::rvsdg::ReduceNode<LambdaExitMemoryStateMergeOperation>(
509 *jlm::util::assertedCast<SimpleNode>(&lambdaExitMergeNode1));
515 EXPECT_TRUE(success);
519 const auto [memStateMerge1Node, memStateMerge1Operation] =
520 TryGetSimpleNodeAndOptionalOp<LambdaExitMemoryStateMergeOperation>(*x.origin());
521 EXPECT_NE(memStateMerge1Node, &lambdaExitMergeNode1);
522 EXPECT_EQ(memStateMerge1Node->ninputs(), 2u);
523 EXPECT_EQ(memStateMerge1Node->input(0)->origin(), allocaResults[1]);
524 EXPECT_EQ(memStateMerge1Node->input(1)->origin(), &memState1);
525 EXPECT_EQ(memStateMerge1Operation->getMemoryNodeIds(), std::vector<MemoryNodeId>({ 1, 2 }));
528 const auto memStateMerge2Node = TryGetOwnerNode<Node>(*y.origin());
529 EXPECT_EQ(memStateMerge2Node, &lambdaExitMergeNode2);
532 TEST(MemoryStateOperationTests, LambdaExitMemoryStateMergeNormalizeStore)
538 const auto bit32Type = BitType::Create(32);
540 const auto valueType = TestType::createValueType();
553 { storeNode.output(0), &memState1 },
558 { &memState2, &memState1 },
561 auto & x = GraphExport::Create(*lambdaExitMergeNode1.output(0),
"x");
562 auto & y = GraphExport::Create(*lambdaExitMergeNode2.output(0),
"y");
567 const auto success = jlm::rvsdg::ReduceNode<LambdaExitMemoryStateMergeOperation>(
569 *jlm::util::assertedCast<SimpleNode>(&lambdaExitMergeNode1));
575 EXPECT_TRUE(success);
579 const auto [memStateMerge1Node, memStateMerge1Operation] =
580 TryGetSimpleNodeAndOptionalOp<LambdaExitMemoryStateMergeOperation>(*x.origin());
581 EXPECT_NE(memStateMerge1Node, &lambdaExitMergeNode1);
582 EXPECT_EQ(memStateMerge1Node->ninputs(), 2u);
583 EXPECT_EQ(memStateMerge1Node->input(0)->origin(), allocaResults[1]);
584 EXPECT_EQ(memStateMerge1Node->input(1)->origin(), &memState1);
585 EXPECT_EQ(memStateMerge1Operation->getMemoryNodeIds(), std::vector<MemoryNodeId>({ 1, 2 }));
588 const auto memStateMerge2Node = TryGetOwnerNode<Node>(*y.origin());
589 EXPECT_EQ(memStateMerge2Node, &lambdaExitMergeNode2);
592 TEST(MemoryStateOperationTests, LambdaExitMemoryStateMergeNormalizeAlloca)
598 const auto bit32Type = BitType::Create(32);
600 const auto valueType = TestType::createValueType();
611 { allocaResults[1], &memState1 },
616 { &memState2, &memState1 },
619 auto & x = GraphExport::Create(*lambdaExitMergeNode1.output(0),
"x");
620 auto & y = GraphExport::Create(*lambdaExitMergeNode2.output(0),
"y");
625 const auto success = jlm::rvsdg::ReduceNode<LambdaExitMemoryStateMergeOperation>(
627 *jlm::util::assertedCast<SimpleNode>(&lambdaExitMergeNode1));
633 EXPECT_TRUE(success);
637 const auto [memStateMerge1Node, memStateMerge1Operation] =
638 TryGetSimpleNodeAndOptionalOp<LambdaExitMemoryStateMergeOperation>(*x.origin());
639 EXPECT_NE(memStateMerge1Node, &lambdaExitMergeNode1);
640 EXPECT_EQ(memStateMerge1Node->ninputs(), 2u);
641 EXPECT_EQ(memStateMerge1Operation->getMemoryNodeIds(), std::vector<MemoryNodeId>({ 1, 2 }));
642 const auto undefNode = TryGetOwnerNode<Node>(*memStateMerge1Node->input(0)->origin());
643 EXPECT_NE(undefNode,
nullptr);
644 EXPECT_EQ(memStateMerge1Node->input(1)->origin(), &memState1);
647 const auto memStateMerge2Node = TryGetOwnerNode<Node>(*y.origin());
648 EXPECT_EQ(memStateMerge2Node, &lambdaExitMergeNode2);
651 TEST(MemoryStateOperationTests, CallEntryMemStateOperatorEquality)
661 TestOperation operation4({ memoryStateType, memoryStateType }, { memoryStateType });
664 EXPECT_EQ(operation1, operation1);
665 EXPECT_NE(operation1, operation2);
666 EXPECT_NE(operation1, operation3);
667 EXPECT_NE(operation1, operation3);
670 TEST(MemoryStateOperationTests, CallExitMemStateOperatorEquality)
680 const TestOperation operation4({ memoryStateType }, { memoryStateType, memoryStateType });
683 EXPECT_EQ(operation1, operation1);
684 EXPECT_NE(operation1, operation2);
685 EXPECT_NE(operation1, operation3);
686 EXPECT_NE(operation1, operation4);
TEST(MemoryStateOperationTests, MemoryStateSplitEquality)
static std::vector< rvsdg::Output * > create(std::shared_ptr< const rvsdg::Type > allocatedType, rvsdg::Output *count, const size_t alignment)
static std::optional< std::vector< rvsdg::Output * > > NormalizeLoadFromAlloca(const LambdaExitMemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > NormalizeStoreToAlloca(const LambdaExitMemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, const std::vector< rvsdg::Output * > &operands, const std::vector< MemoryNodeId > &memoryNodeIds)
static std::optional< std::vector< rvsdg::Output * > > NormalizeAlloca(const LambdaExitMemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, std::unique_ptr< LoadNonVolatileOperation > loadOperation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > NormalizeDuplicateOperands(const MemoryStateJoinOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes duplicated operands from the MemoryStateJoinOperation.
static std::optional< std::vector< rvsdg::Output * > > NormalizeNestedJoins(const MemoryStateJoinOperation &operation, const std::vector< rvsdg::Output * > &operands)
Fuses nested MemoryStateJoinOperation nodes into a single node.
static std::optional< std::vector< rvsdg::Output * > > NormalizeSingleOperand(const MemoryStateJoinOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes the MemoryStateJoinOperation as it has only a single operand, i.e., no joining is performed.
static rvsdg::SimpleNode & CreateNode(const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > NormalizeNestedMerges(const MemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
Fuses nested merges into a single merge.
static rvsdg::SimpleNode & CreateNode(const std::vector< rvsdg::Output * > &operands)
static rvsdg::Output * Create(const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > NormalizeMergeSplit(const MemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
Fuses nested splits into a single merge.
static std::optional< std::vector< rvsdg::Output * > > NormalizeSingleOperand(const MemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes the MemoryStateMergeOperation as it has only a single operand, i.e., no merging is performed.
static std::optional< std::vector< rvsdg::Output * > > NormalizeDuplicateOperands(const MemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes duplicated operands from the MemoryStateMergeOperation.
static std::optional< std::vector< rvsdg::Output * > > NormalizeNestedSplits(const MemoryStateSplitOperation &operation, const std::vector< rvsdg::Output * > &operands)
Fuses nested splits into a single split.
static std::optional< std::vector< rvsdg::Output * > > NormalizeSingleResult(const MemoryStateSplitOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes the MemoryStateSplitOperation as it has only a single result, i.e., no splitting is performed...
static std::optional< std::vector< rvsdg::Output * > > NormalizeSplitMerge(const MemoryStateSplitOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes an idempotent split-merge pair.
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &operand, const size_t numResults)
static std::shared_ptr< const MemoryStateType > Create()
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &address, rvsdg::Output &value, const std::vector< rvsdg::Output * > &memoryStates, size_t alignment)
static GraphExport & Create(Output &origin, std::string name)
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Region & GetRootRegion() const noexcept
size_t numNodes() const noexcept
Global memory state passed between functions.
std::string view(const rvsdg::Region *region)