21TEST(LoadOperationTests, OperationEquality)
29 auto pointerType = PointerType::Create();
35 TestOperation operation5({ PointerType::Create() }, { PointerType::Create() });
38 EXPECT_EQ(operation1, operation1);
39 EXPECT_NE(operation1, operation2);
40 EXPECT_NE(operation1, operation3);
41 EXPECT_NE(operation1, operation4);
42 EXPECT_NE(operation1, operation5);
45TEST(LoadOperationTests, TestCopy)
50 auto memoryType = MemoryStateType::Create();
52 auto pointerType = PointerType::Create();
61 auto loadResults = LoadNonVolatileOperation::Create(address1, { memoryState1 }, valueType, 4);
65 EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
66 auto copiedNode = node->copy(&graph.
GetRootRegion(), { address2, memoryState2 });
71 jlm::util::assertedCast<jlm::rvsdg::SimpleNode>(copiedNode)->GetOperation());
74TEST(LoadOperationTests, TestLoadAllocaReduction)
79 auto mt = MemoryStateType::Create();
85 auto alloca1 = AllocaOperation::create(bt, size, 4);
86 auto alloca2 = AllocaOperation::create(bt, size, 4);
87 auto mux = MemoryStateMergeOperation::Create({ alloca1[1] });
89 LoadNonVolatileOperation::CreateNode(*alloca1[0], { alloca1[1], alloca2[1], mux }, bt, 4);
97 LoadNonVolatileOperation::NormalizeLoadAlloca,
105 EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
106 EXPECT_EQ(node->ninputs(), 3u);
107 EXPECT_EQ(node->input(1)->origin(), alloca1[1]);
108 EXPECT_EQ(node->input(2)->origin(), mux);
111TEST(LoadOperationTests, TestDuplicateStateReduction)
116 const auto memoryType = MemoryStateType::Create();
118 const auto pointerType = PointerType::Create();
126 auto & loadNode = LoadNonVolatileOperation::CreateNode(*a, { s1, s2, s1, s2, s3 }, valueType, 4);
139 LoadNonVolatileOperation::NormalizeDuplicateStates,
145 EXPECT_TRUE(success);
147 EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
148 EXPECT_EQ(node->ninputs(), 4u);
149 EXPECT_EQ(node->noutputs(), 4u);
151 EXPECT_EQ(exA.origin(), node->output(0));
152 EXPECT_EQ(exS1.origin(), node->output(1));
153 EXPECT_EQ(exS2.origin(), node->output(2));
154 EXPECT_EQ(exS3.origin(), node->output(1));
155 EXPECT_EQ(exS4.origin(), node->output(2));
156 EXPECT_EQ(exS5.origin(), node->output(3));
159TEST(LoadOperationTests, TestLoadStoreStateReduction)
169 auto alloca1 = AllocaOperation::create(bt, size, 4);
170 auto alloca2 = AllocaOperation::create(bt, size, 4);
171 auto store1 = StoreNonVolatileOperation::Create(alloca1[0], size, { alloca1[1] }, 4);
172 auto store2 = StoreNonVolatileOperation::Create(alloca2[0], size, { alloca2[1] }, 4);
175 LoadNonVolatileOperation::CreateNode(*alloca1[0], { store1[0], store2[0] }, bt, 4);
176 auto & loadNode2 = LoadNonVolatileOperation::CreateNode(*alloca1[0], { store1[0] }, bt, 8);
185 LoadNonVolatileOperation::NormalizeLoadStoreState,
188 LoadNonVolatileOperation::NormalizeLoadStoreState,
195 EXPECT_TRUE(success1);
197 EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
198 EXPECT_EQ(node->ninputs(), 2u);
200 EXPECT_FALSE(success2);
202 EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
203 EXPECT_EQ(node->ninputs(), 2u);
206TEST(LoadOperationTests, TestLoadStoreReduction_Success)
212 auto pt = PointerType::Create();
213 auto mt = MemoryStateType::Create();
220 auto s1 = StoreNonVolatileOperation::Create(a, v, { s }, 4)[0];
221 auto & loadNode = LoadNonVolatileOperation::CreateNode(*a, { s1 },
vt, 4);
230 LoadNonVolatileOperation::NormalizeLoadStore,
236 EXPECT_TRUE(success);
238 EXPECT_EQ(x1.origin(), v);
239 EXPECT_EQ(x2.origin(), s1);
246TEST(LoadOperationTests, LoadStoreReduction_DifferentValueOperandType)
251 const auto pointerType = PointerType::Create();
252 const auto memoryStateType = MemoryStateType::Create();
259 auto & storeNode = StoreNonVolatileOperation::CreateNode(address, value, { memoryState }, 4);
260 auto & loadNode = LoadNonVolatileOperation::CreateNode(
273 LoadNonVolatileOperation::NormalizeLoadStore,
280 EXPECT_FALSE(success);
282 const auto expectedLoadNode =
284 EXPECT_EQ(expectedLoadNode, &loadNode);
285 EXPECT_EQ(expectedLoadNode->ninputs(), 2u);
287 const auto expectedStoreNode =
289 EXPECT_EQ(expectedStoreNode, &storeNode);
292TEST(LoadOperationTests, normalizeMemoryHoistBarrierAddress)
297 const auto pointerType = PointerType::Create();
298 const auto memoryStateType = MemoryStateType::Create();
300 const auto ioStateType = IOStateType::Create();
308 auto allocaResults = AllocaOperation::create(bit32Type, sizeImport, 4);
309 auto & hoistBarrierNode =
310 MemoryHoistBarrierOperation::createNode(*allocaResults[0], *ioStateImport, 0);
312 auto & loadNode1 = LoadNonVolatileOperation::CreateNode(
313 *hoistBarrierNode.output(0),
314 { allocaResults[1] },
319 LoadNonVolatileOperation::CreateNode(*addressImport, { memoryStateImport }, bit32Type, 4);
328 LoadNonVolatileOperation::normalizeMemoryHoistBarrierAddress,
332 LoadNonVolatileOperation::normalizeMemoryHoistBarrierAddress,
339 EXPECT_TRUE(successLoadNode1);
346 EXPECT_FALSE(successLoadNode2);
352TEST(LoadOperationTests, normalizeMemoryHoistBarrierAddress_Gamma)
358 const auto pointerType = PointerType::Create();
359 const auto memoryStateType = MemoryStateType::Create();
361 const auto ioStateType = IOStateType::Create();
362 const auto controlType = ControlType::Create(2);
365 const auto sizeImport = &GraphImport::Create(graph, bit32Type,
"value");
366 const auto controlImport = &GraphImport::Create(graph, controlType,
"control");
367 auto ioStateImport = &GraphImport::Create(graph, ioStateType,
"ioState");
368 auto valueImport = &GraphImport::Create(graph, bit32Type,
"value");
370 auto allocaResults = AllocaOperation::create(bit32Type, sizeImport, 4);
372 auto gammaNode = GammaNode::create(controlImport, 2);
373 auto addressEntryVar = gammaNode->AddEntryVar(allocaResults[0]);
374 auto memoryStateEntryVar = gammaNode->AddEntryVar(allocaResults[1]);
375 auto ioStateEntryVar = gammaNode->AddEntryVar(ioStateImport);
376 auto valueEntryVar = gammaNode->AddEntryVar(valueImport);
378 auto & hoistBarrierNode = MemoryHoistBarrierOperation::createNode(
379 *addressEntryVar.branchArgument[0],
380 *ioStateEntryVar.branchArgument[0],
383 auto & loadNode = LoadNonVolatileOperation::CreateNode(
384 *hoistBarrierNode.output(0),
385 { memoryStateEntryVar.branchArgument[0] },
389 auto exitVar = gammaNode->AddExitVar({ loadNode.output(0), valueEntryVar.branchArgument[1] });
391 GraphExport::Create(*exitVar.output,
"load1");
397 LoadNonVolatileOperation::normalizeMemoryHoistBarrierAddress,
405 EXPECT_TRUE(successLoadNode);
408 EXPECT_EQ(gammaNode->subregion(0)->numNodes(), 1u);
413 addressEntryVar.branchArgument[0]);
416TEST(LoadOperationTests, normalizeMemoryHoistBarrierAddress_GEP)
421 const auto pointerType = PointerType::Create();
422 const auto memoryStateType = MemoryStateType::Create();
424 const auto ioStateType = IOStateType::Create();
425 const auto arrayType = ArrayType::Create(bit32Type, 10);
431 auto & zeroNode = IntegerConstantOperation::Create(graph.
GetRootRegion(), 32, 0);
432 auto & twoNode = IntegerConstantOperation::Create(graph.
GetRootRegion(), 32, 2);
433 auto & tenNode = IntegerConstantOperation::Create(graph.
GetRootRegion(), 32, 10);
435 auto allocaResults = AllocaOperation::create(arrayType, sizeImport, 4);
437 auto & gepNode1 = GetElementPtrOperation::createNode(
439 { zeroNode.output(0), twoNode.output(0) },
441 auto & hoistBarrierNode1 =
442 MemoryHoistBarrierOperation::createNode(*gepNode1.output(0), *ioStateImport, 0);
443 auto & loadNode1 = LoadNonVolatileOperation::CreateNode(
444 *hoistBarrierNode1.output(0),
445 { allocaResults[1] },
449 auto & gepNode2 = GetElementPtrOperation::createNode(
451 { zeroNode.output(0), tenNode.output(0) },
453 auto & hoistBarrierNode2 =
454 MemoryHoistBarrierOperation::createNode(*gepNode2.output(0), *ioStateImport, 0);
455 auto & loadNode2 = LoadNonVolatileOperation::CreateNode(
456 *hoistBarrierNode2.output(0),
457 { allocaResults[1] },
468 LoadNonVolatileOperation::normalizeMemoryHoistBarrierAddress,
472 LoadNonVolatileOperation::normalizeMemoryHoistBarrierAddress,
480 EXPECT_TRUE(successLoadNode1);
489 EXPECT_FALSE(successLoadNode2);
492 hoistBarrierNode2.output(0));
496TEST(LoadOperationTests, LoadVolatileOperationEquality)
504 auto pointerType = PointerType::Create();
510 TestOperation operation5({ PointerType::Create() }, { PointerType::Create() });
513 EXPECT_EQ(operation1, operation1);
514 EXPECT_NE(operation1, operation2);
515 EXPECT_NE(operation1, operation3);
516 EXPECT_NE(operation1, operation4);
517 EXPECT_NE(operation1, operation5);
559TEST(LoadOperationTests, NodeCopy)
566 auto pointerType = PointerType::Create();
567 auto iOStateType = IOStateType::Create();
568 auto memoryType = MemoryStateType::Create();
569 auto valueType = TestType::createValueType();
581 { &address1, &iOState1, &memoryState1 },
587 auto copiedNode = loadNode.copy(&graph.
GetRootRegion(), { &address2, &iOState2, &memoryState2 });
591 &jlm::util::assertedCast<SimpleNode>(copiedNode)->GetOperation());
592 EXPECT_NE(copiedOperation,
nullptr);
593 EXPECT_EQ(LoadOperation::AddressInput(*copiedNode).origin(), &address2);
594 EXPECT_EQ(LoadVolatileOperation::IOStateInput(*copiedNode).origin(), &iOState2);
595 EXPECT_EQ(*copiedOperation->GetLoadedType(), *valueType);