Jlm
Loading...
Searching...
No Matches
LoadTests.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2017 Nico Reißmann <nico.reissmann@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
6#include <gtest/gtest.h>
7
15#include <jlm/rvsdg/gamma.hpp>
19#include <jlm/rvsdg/view.hpp>
20
21TEST(LoadOperationTests, OperationEquality)
22{
23 using namespace jlm::llvm;
24 using namespace jlm::rvsdg;
25
26 // Arrange
27 MemoryStateType memoryType;
29 auto pointerType = PointerType::Create();
30
31 LoadNonVolatileOperation operation1(valueType, 2, 4);
32 LoadNonVolatileOperation operation2(pointerType, 2, 4);
33 LoadNonVolatileOperation operation3(valueType, 4, 4);
34 LoadNonVolatileOperation operation4(valueType, 2, 8);
35 TestOperation operation5({ PointerType::Create() }, { PointerType::Create() });
36
37 // Assert
38 EXPECT_EQ(operation1, operation1);
39 EXPECT_NE(operation1, operation2); // loaded type differs
40 EXPECT_NE(operation1, operation3); // number of memory states differs
41 EXPECT_NE(operation1, operation4); // alignment differs
42 EXPECT_NE(operation1, operation5); // operation differs
43}
44
45TEST(LoadOperationTests, TestCopy)
46{
47 using namespace jlm::llvm;
48
49 // Arrange
50 auto memoryType = MemoryStateType::Create();
52 auto pointerType = PointerType::Create();
53
55 auto address1 = &jlm::rvsdg::GraphImport::Create(graph, pointerType, "address1");
56 auto memoryState1 = &jlm::rvsdg::GraphImport::Create(graph, memoryType, "memoryState1");
57
58 auto address2 = &jlm::rvsdg::GraphImport::Create(graph, pointerType, "address2");
59 auto memoryState2 = &jlm::rvsdg::GraphImport::Create(graph, memoryType, "memoryState2");
60
61 auto loadResults = LoadNonVolatileOperation::Create(address1, { memoryState1 }, valueType, 4);
62
63 // Act
64 auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(*loadResults[0]);
65 EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
66 auto copiedNode = node->copy(&graph.GetRootRegion(), { address2, memoryState2 });
67
68 // Assert
69 EXPECT_EQ(
70 node->GetOperation(),
71 jlm::util::assertedCast<jlm::rvsdg::SimpleNode>(copiedNode)->GetOperation());
72}
73
74TEST(LoadOperationTests, TestLoadAllocaReduction)
75{
76 using namespace jlm::llvm;
77
78 // Arrange
79 auto mt = MemoryStateType::Create();
80 auto bt = jlm::rvsdg::BitType::Create(32);
81
83 auto size = &jlm::rvsdg::GraphImport::Create(graph, bt, "v");
84
85 auto alloca1 = AllocaOperation::create(bt, size, 4);
86 auto alloca2 = AllocaOperation::create(bt, size, 4);
87 auto mux = MemoryStateMergeOperation::Create({ alloca1[1] });
88 auto & loadNode =
89 LoadNonVolatileOperation::CreateNode(*alloca1[0], { alloca1[1], alloca2[1], mux }, bt, 4);
90
91 auto & ex = jlm::rvsdg::GraphExport::Create(*loadNode.output(0), "l");
92
93 jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
94
95 // Act
97 LoadNonVolatileOperation::NormalizeLoadAlloca,
98 loadNode);
99 graph.PruneNodes();
100
101 jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
102
103 // Assert
104 auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*ex.origin());
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);
109}
110
111TEST(LoadOperationTests, TestDuplicateStateReduction)
112{
113 using namespace jlm::llvm;
114
115 // Arrange
116 const auto memoryType = MemoryStateType::Create();
117 const auto valueType = jlm::rvsdg::TestType::createValueType();
118 const auto pointerType = PointerType::Create();
119
120 jlm::rvsdg::Graph graph;
121 const auto a = &jlm::rvsdg::GraphImport::Create(graph, pointerType, "a");
122 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, memoryType, "s1");
123 auto s2 = &jlm::rvsdg::GraphImport::Create(graph, memoryType, "s2");
124 auto s3 = &jlm::rvsdg::GraphImport::Create(graph, memoryType, "s3");
125
126 auto & loadNode = LoadNonVolatileOperation::CreateNode(*a, { s1, s2, s1, s2, s3 }, valueType, 4);
127
128 auto & exA = jlm::rvsdg::GraphExport::Create(*loadNode.output(0), "exA");
129 auto & exS1 = jlm::rvsdg::GraphExport::Create(*loadNode.output(1), "exS1");
130 auto & exS2 = jlm::rvsdg::GraphExport::Create(*loadNode.output(2), "exS2");
131 auto & exS3 = jlm::rvsdg::GraphExport::Create(*loadNode.output(3), "exS3");
132 auto & exS4 = jlm::rvsdg::GraphExport::Create(*loadNode.output(4), "exS4");
133 auto & exS5 = jlm::rvsdg::GraphExport::Create(*loadNode.output(5), "exS5");
134
135 view(&graph.GetRootRegion(), stdout);
136
137 // Act
139 LoadNonVolatileOperation::NormalizeDuplicateStates,
140 loadNode);
141
142 view(&graph.GetRootRegion(), stdout);
143
144 // Assert
145 EXPECT_TRUE(success);
146 const auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*exA.origin());
147 EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
148 EXPECT_EQ(node->ninputs(), 4u); // 1 address + 3 states
149 EXPECT_EQ(node->noutputs(), 4u); // 1 loaded value + 3 states
150
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));
157}
158
159TEST(LoadOperationTests, TestLoadStoreStateReduction)
160{
161 using namespace jlm::llvm;
162
163 // Arrange
164 auto bt = jlm::rvsdg::BitType::Create(32);
165
166 jlm::rvsdg::Graph graph;
167 auto size = &jlm::rvsdg::GraphImport::Create(graph, bt, "v");
168
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);
173
174 auto & loadNode1 =
175 LoadNonVolatileOperation::CreateNode(*alloca1[0], { store1[0], store2[0] }, bt, 4);
176 auto & loadNode2 = LoadNonVolatileOperation::CreateNode(*alloca1[0], { store1[0] }, bt, 8);
177
178 auto & ex1 = jlm::rvsdg::GraphExport::Create(*loadNode1.output(0), "l1");
179 auto & ex2 = jlm::rvsdg::GraphExport::Create(*loadNode2.output(0), "l2");
180
181 jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
182
183 // Act
185 LoadNonVolatileOperation::NormalizeLoadStoreState,
186 loadNode1);
188 LoadNonVolatileOperation::NormalizeLoadStoreState,
189 loadNode2);
190 graph.PruneNodes();
191
192 jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
193
194 // Assert
195 EXPECT_TRUE(success1);
196 auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*ex1.origin());
197 EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
198 EXPECT_EQ(node->ninputs(), 2u);
199
200 EXPECT_FALSE(success2);
202 EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
203 EXPECT_EQ(node->ninputs(), 2u);
204}
205
206TEST(LoadOperationTests, TestLoadStoreReduction_Success)
207{
208 using namespace jlm::llvm;
209
210 // Arrange
212 auto pt = PointerType::Create();
213 auto mt = MemoryStateType::Create();
214
215 jlm::rvsdg::Graph graph;
216 auto a = &jlm::rvsdg::GraphImport::Create(graph, pt, "address");
217 auto v = &jlm::rvsdg::GraphImport::Create(graph, vt, "value");
218 auto s = &jlm::rvsdg::GraphImport::Create(graph, mt, "state");
219
220 auto s1 = StoreNonVolatileOperation::Create(a, v, { s }, 4)[0];
221 auto & loadNode = LoadNonVolatileOperation::CreateNode(*a, { s1 }, vt, 4);
222
223 auto & x1 = jlm::rvsdg::GraphExport::Create(*loadNode.output(0), "value");
224 auto & x2 = jlm::rvsdg::GraphExport::Create(*loadNode.output(1), "state");
225
226 jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
227
228 // Act
230 LoadNonVolatileOperation::NormalizeLoadStore,
231 loadNode);
232
233 view(&graph.GetRootRegion(), stdout);
234
235 // Assert
236 EXPECT_TRUE(success);
237 EXPECT_EQ(graph.GetRootRegion().numNodes(), 1u);
238 EXPECT_EQ(x1.origin(), v);
239 EXPECT_EQ(x2.origin(), s1);
240}
241
246TEST(LoadOperationTests, LoadStoreReduction_DifferentValueOperandType)
247{
248 using namespace jlm::llvm;
249
250 // Arrange
251 const auto pointerType = PointerType::Create();
252 const auto memoryStateType = MemoryStateType::Create();
253
254 jlm::rvsdg::Graph graph;
255 auto & address = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address");
256 auto & value = jlm::rvsdg::GraphImport::Create(graph, jlm::rvsdg::BitType::Create(32), "value");
257 auto memoryState = &jlm::rvsdg::GraphImport::Create(graph, memoryStateType, "memoryState");
258
259 auto & storeNode = StoreNonVolatileOperation::CreateNode(address, value, { memoryState }, 4);
260 auto & loadNode = LoadNonVolatileOperation::CreateNode(
261 address,
262 outputs(&storeNode),
264 4);
265
266 auto & exportedValue = jlm::rvsdg::GraphExport::Create(*loadNode.output(0), "v");
267 jlm::rvsdg::GraphExport::Create(*loadNode.output(1), "s");
268
269 view(&graph.GetRootRegion(), stdout);
270
271 // Act
273 LoadNonVolatileOperation::NormalizeLoadStore,
274 loadNode);
275 graph.PruneNodes();
276
277 view(&graph.GetRootRegion(), stdout);
278
279 // Assert
280 EXPECT_FALSE(success);
281
282 const auto expectedLoadNode =
283 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*exportedValue.origin());
284 EXPECT_EQ(expectedLoadNode, &loadNode);
285 EXPECT_EQ(expectedLoadNode->ninputs(), 2u);
286
287 const auto expectedStoreNode =
288 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*expectedLoadNode->input(1)->origin());
289 EXPECT_EQ(expectedStoreNode, &storeNode);
290}
291
292TEST(LoadOperationTests, normalizeMemoryHoistBarrierAddress)
293{
294 using namespace jlm::llvm;
295
296 // Arrange
297 const auto pointerType = PointerType::Create();
298 const auto memoryStateType = MemoryStateType::Create();
299 const auto bit32Type = jlm::rvsdg::BitType::Create(32);
300 const auto ioStateType = IOStateType::Create();
301
302 jlm::rvsdg::Graph graph;
303 const auto addressImport = &jlm::rvsdg::GraphImport::Create(graph, pointerType, "address");
304 const auto sizeImport = &jlm::rvsdg::GraphImport::Create(graph, bit32Type, "value");
305 auto memoryStateImport = &jlm::rvsdg::GraphImport::Create(graph, memoryStateType, "memState");
306 auto ioStateImport = &jlm::rvsdg::GraphImport::Create(graph, ioStateType, "ioState");
307
308 auto allocaResults = AllocaOperation::create(bit32Type, sizeImport, 4);
309 auto & hoistBarrierNode =
310 MemoryHoistBarrierOperation::createNode(*allocaResults[0], *ioStateImport, 0);
311
312 auto & loadNode1 = LoadNonVolatileOperation::CreateNode(
313 *hoistBarrierNode.output(0),
314 { allocaResults[1] },
315 bit32Type,
316 4);
317
318 auto & loadNode2 =
319 LoadNonVolatileOperation::CreateNode(*addressImport, { memoryStateImport }, bit32Type, 4);
320
321 auto & ex1 = jlm::rvsdg::GraphExport::Create(*loadNode1.output(0), "store1");
322 auto & ex2 = jlm::rvsdg::GraphExport::Create(*loadNode2.output(0), "store2");
323
324 jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
325
326 // Act
327 const auto successLoadNode1 = jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
328 LoadNonVolatileOperation::normalizeMemoryHoistBarrierAddress,
329 loadNode1);
330
331 const auto successLoadNode2 = jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
332 LoadNonVolatileOperation::normalizeMemoryHoistBarrierAddress,
333 loadNode2);
334 graph.PruneNodes();
335
336 jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
337
338 // Assert
339 EXPECT_TRUE(successLoadNode1);
340 EXPECT_EQ(
341 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*ex1.origin())->input(0)->origin(),
342 allocaResults[0]);
343
344 // There is no MemoryHoistBarrierOperation node as producer for the load address. We expect the
345 // normalization not to trigger.
346 EXPECT_FALSE(successLoadNode2);
347 EXPECT_EQ(
348 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*ex2.origin())->input(0)->origin(),
349 addressImport);
350}
351
352TEST(LoadOperationTests, normalizeMemoryHoistBarrierAddress_Gamma)
353{
354 using namespace jlm::llvm;
355 using namespace jlm::rvsdg;
356
357 // Arrange
358 const auto pointerType = PointerType::Create();
359 const auto memoryStateType = MemoryStateType::Create();
360 const auto bit32Type = jlm::rvsdg::BitType::Create(32);
361 const auto ioStateType = IOStateType::Create();
362 const auto controlType = ControlType::Create(2);
363
364 Graph graph;
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");
369
370 auto allocaResults = AllocaOperation::create(bit32Type, sizeImport, 4);
371
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);
377
378 auto & hoistBarrierNode = MemoryHoistBarrierOperation::createNode(
379 *addressEntryVar.branchArgument[0],
380 *ioStateEntryVar.branchArgument[0],
381 0);
382
383 auto & loadNode = LoadNonVolatileOperation::CreateNode(
384 *hoistBarrierNode.output(0),
385 { memoryStateEntryVar.branchArgument[0] },
386 bit32Type,
387 4);
388
389 auto exitVar = gammaNode->AddExitVar({ loadNode.output(0), valueEntryVar.branchArgument[1] });
390
391 GraphExport::Create(*exitVar.output, "load1");
392
393 view(&graph.GetRootRegion(), stdout);
394
395 // Act
396 const auto successLoadNode = jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
397 LoadNonVolatileOperation::normalizeMemoryHoistBarrierAddress,
398 loadNode);
399
400 graph.PruneNodes();
401
402 view(&graph.GetRootRegion(), stdout);
403
404 // Assert
405 EXPECT_TRUE(successLoadNode);
406 // There should only be the load node left.
407 // The MemoryHoistBarrierOperation node should have been pruned.
408 EXPECT_EQ(gammaNode->subregion(0)->numNodes(), 1u);
409 EXPECT_EQ(
410 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*exitVar.branchResult[0]->origin())
411 ->input(0)
412 ->origin(),
413 addressEntryVar.branchArgument[0]);
414}
415
416TEST(LoadOperationTests, normalizeMemoryHoistBarrierAddress_GEP)
417{
418 using namespace jlm::llvm;
419
420 // Arrange
421 const auto pointerType = PointerType::Create();
422 const auto memoryStateType = MemoryStateType::Create();
423 const auto bit32Type = jlm::rvsdg::BitType::Create(32);
424 const auto ioStateType = IOStateType::Create();
425 const auto arrayType = ArrayType::Create(bit32Type, 10);
426
427 jlm::rvsdg::Graph graph;
428 const auto sizeImport = &jlm::rvsdg::GraphImport::Create(graph, bit32Type, "value");
429 auto ioStateImport = &jlm::rvsdg::GraphImport::Create(graph, ioStateType, "ioState");
430
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);
434
435 auto allocaResults = AllocaOperation::create(arrayType, sizeImport, 4);
436
437 auto & gepNode1 = GetElementPtrOperation::createNode(
438 *allocaResults[0],
439 { zeroNode.output(0), twoNode.output(0) },
440 arrayType);
441 auto & hoistBarrierNode1 =
442 MemoryHoistBarrierOperation::createNode(*gepNode1.output(0), *ioStateImport, 0);
443 auto & loadNode1 = LoadNonVolatileOperation::CreateNode(
444 *hoistBarrierNode1.output(0),
445 { allocaResults[1] },
446 bit32Type,
447 4);
448
449 auto & gepNode2 = GetElementPtrOperation::createNode(
450 *allocaResults[0],
451 { zeroNode.output(0), tenNode.output(0) },
452 arrayType);
453 auto & hoistBarrierNode2 =
454 MemoryHoistBarrierOperation::createNode(*gepNode2.output(0), *ioStateImport, 0);
455 auto & loadNode2 = LoadNonVolatileOperation::CreateNode(
456 *hoistBarrierNode2.output(0),
457 { allocaResults[1] },
458 bit32Type,
459 4);
460
461 auto & ex1 = jlm::rvsdg::GraphExport::Create(*loadNode1.output(0), "store1");
462 auto & ex2 = jlm::rvsdg::GraphExport::Create(*loadNode2.output(0), "store2");
463
464 jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
465
466 // Act
467 const auto successLoadNode1 = jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
468 LoadNonVolatileOperation::normalizeMemoryHoistBarrierAddress,
469 loadNode1);
470
471 const auto successLoadNode2 = jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
472 LoadNonVolatileOperation::normalizeMemoryHoistBarrierAddress,
473 loadNode2);
474 graph.PruneNodes();
475
476 jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
477
478 // Assert
479 {
480 EXPECT_TRUE(successLoadNode1);
481 EXPECT_EQ(
482 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*ex1.origin())->input(0)->origin(),
483 gepNode1.output(0));
484 }
485
486 {
487 // The offset computed by the GEP + the loaded size exceeds the array, we expect the
488 // MemoryHoistBarrierOperation node to not be removed.
489 EXPECT_FALSE(successLoadNode2);
490 EXPECT_EQ(
491 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*ex2.origin())->input(0)->origin(),
492 hoistBarrierNode2.output(0));
493 }
494}
495
496TEST(LoadOperationTests, LoadVolatileOperationEquality)
497{
498 using namespace jlm::llvm;
499 using namespace jlm::rvsdg;
500
501 // Arrange
502 MemoryStateType memoryType;
503 auto valueType = jlm::rvsdg::TestType::createValueType();
504 auto pointerType = PointerType::Create();
505
506 LoadVolatileOperation operation1(valueType, 2, 4);
507 LoadVolatileOperation operation2(pointerType, 2, 4);
508 LoadVolatileOperation operation3(valueType, 4, 4);
509 LoadVolatileOperation operation4(valueType, 2, 8);
510 TestOperation operation5({ PointerType::Create() }, { PointerType::Create() });
511
512 // Assert
513 EXPECT_EQ(operation1, operation1);
514 EXPECT_NE(operation1, operation2); // loaded type differs
515 EXPECT_NE(operation1, operation3); // number of memory states differs
516 EXPECT_NE(operation1, operation4); // alignment differs
517 EXPECT_NE(operation1, operation5); // operation differs
518}
519
520TEST(LoadOperationTests, OperationCopy)
521{
522 using namespace jlm::llvm;
523
524 // Arrange
525 MemoryStateType memoryType;
526 auto valueType = jlm::rvsdg::TestType::createValueType();
527 PointerType pointerType;
528
529 LoadVolatileOperation operation(valueType, 2, 4);
530
531 // Act
532 auto copiedOperation = operation.copy();
533
534 // Assert
535 EXPECT_EQ(*copiedOperation, operation);
536}
537
538TEST(LoadOperationTests, OperationAccessors)
539{
540 using namespace jlm::llvm;
541
542 // Arrange
543 MemoryStateType memoryType;
544 auto valueType = jlm::rvsdg::TestType::createValueType();
545 PointerType pointerType;
546
547 size_t alignment = 4;
548 size_t numMemoryStates = 2;
549 LoadVolatileOperation operation(valueType, numMemoryStates, alignment);
550
551 // Assert
552 EXPECT_EQ(operation.GetLoadedType(), valueType);
553 EXPECT_EQ(operation.NumMemoryStates(), numMemoryStates);
554 EXPECT_EQ(operation.GetAlignment(), alignment);
555 EXPECT_EQ(operation.narguments(), numMemoryStates + 2); // [address, ioState, memoryStates]
556 EXPECT_EQ(operation.nresults(), numMemoryStates + 2); // [loadedValue, ioState, memoryStates]
557}
558
559TEST(LoadOperationTests, NodeCopy)
560{
561 using namespace jlm::llvm;
562 using namespace jlm::rvsdg;
563 using namespace jlm::util;
564
565 // Arrange
566 auto pointerType = PointerType::Create();
567 auto iOStateType = IOStateType::Create();
568 auto memoryType = MemoryStateType::Create();
569 auto valueType = TestType::createValueType();
570
571 jlm::rvsdg::Graph graph;
572 auto & address1 = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address1");
573 auto & iOState1 = jlm::rvsdg::GraphImport::Create(graph, iOStateType, "iOState1");
574 auto & memoryState1 = jlm::rvsdg::GraphImport::Create(graph, memoryType, "memoryState1");
575
576 auto & address2 = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address2");
577 auto & iOState2 = jlm::rvsdg::GraphImport::Create(graph, iOStateType, "iOState2");
578 auto & memoryState2 = jlm::rvsdg::GraphImport::Create(graph, memoryType, "memoryState2");
579
581 { &address1, &iOState1, &memoryState1 },
582 valueType,
583 1,
584 4);
585
586 // Act
587 auto copiedNode = loadNode.copy(&graph.GetRootRegion(), { &address2, &iOState2, &memoryState2 });
588
589 // Assert
590 auto copiedOperation = dynamic_cast<const LoadVolatileOperation *>(
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);
596}
static const auto vt
Definition PullTests.cpp:16
size_t NumMemoryStates() const noexcept
Definition Load.hpp:69
std::shared_ptr< const rvsdg::Type > GetLoadedType() const noexcept
Definition Load.hpp:63
size_t GetAlignment() const noexcept
Definition Load.hpp:57
std::unique_ptr< Operation > copy() const override
Definition Load.cpp:424
Memory state type class.
Definition types.hpp:477
PointerType class.
Definition types.hpp:25
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
Definition type.cpp:45
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
Region & GetRootRegion() const noexcept
Definition graph.hpp:99
void PruneNodes()
Definition graph.hpp:116
size_t numNodes() const noexcept
Definition region.hpp:510
size_t nresults() const noexcept
Definition operation.cpp:30
size_t narguments() const noexcept
Definition operation.cpp:17
static std::shared_ptr< const TestType > createValueType()
Definition TestType.cpp:67
TEST(LoadTests, LoadConversion)
Definition LoadTests.cpp:17
Global memory state passed between functions.
std::string view(const rvsdg::Region *region)
Definition view.cpp:142
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872