Jlm
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 
14 #include <jlm/rvsdg/gamma.hpp>
17 #include <jlm/rvsdg/TestType.hpp>
18 #include <jlm/rvsdg/view.hpp>
19 
20 TEST(LoadOperationTests, OperationEquality)
21 {
22  using namespace jlm::llvm;
23  using namespace jlm::rvsdg;
24 
25  // Arrange
26  MemoryStateType memoryType;
27  auto valueType = jlm::rvsdg::TestType::createValueType();
28  auto pointerType = PointerType::Create();
29 
30  LoadNonVolatileOperation operation1(valueType, 2, 4);
31  LoadNonVolatileOperation operation2(pointerType, 2, 4);
32  LoadNonVolatileOperation operation3(valueType, 4, 4);
33  LoadNonVolatileOperation operation4(valueType, 2, 8);
34  TestOperation operation5({ PointerType::Create() }, { PointerType::Create() });
35 
36  // Assert
37  EXPECT_EQ(operation1, operation1);
38  EXPECT_NE(operation1, operation2); // loaded type differs
39  EXPECT_NE(operation1, operation3); // number of memory states differs
40  EXPECT_NE(operation1, operation4); // alignment differs
41  EXPECT_NE(operation1, operation5); // operation differs
42 }
43 
44 TEST(LoadOperationTests, TestCopy)
45 {
46  using namespace jlm::llvm;
47 
48  // Arrange
49  auto memoryType = MemoryStateType::Create();
50  auto valueType = jlm::rvsdg::TestType::createValueType();
51  auto pointerType = PointerType::Create();
52 
53  jlm::rvsdg::Graph graph;
54  auto address1 = &jlm::rvsdg::GraphImport::Create(graph, pointerType, "address1");
55  auto memoryState1 = &jlm::rvsdg::GraphImport::Create(graph, memoryType, "memoryState1");
56 
57  auto address2 = &jlm::rvsdg::GraphImport::Create(graph, pointerType, "address2");
58  auto memoryState2 = &jlm::rvsdg::GraphImport::Create(graph, memoryType, "memoryState2");
59 
60  auto loadResults = LoadNonVolatileOperation::Create(address1, { memoryState1 }, valueType, 4);
61 
62  // Act
63  auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(*loadResults[0]);
64  EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
65  auto copiedNode = node->copy(&graph.GetRootRegion(), { address2, memoryState2 });
66 
67  // Assert
68  EXPECT_EQ(
69  node->GetOperation(),
70  jlm::util::assertedCast<jlm::rvsdg::SimpleNode>(copiedNode)->GetOperation());
71 }
72 
73 TEST(LoadOperationTests, TestLoadAllocaReduction)
74 {
75  using namespace jlm::llvm;
76 
77  // Arrange
78  auto mt = MemoryStateType::Create();
79  auto bt = jlm::rvsdg::BitType::Create(32);
80 
81  jlm::rvsdg::Graph graph;
82  auto size = &jlm::rvsdg::GraphImport::Create(graph, bt, "v");
83 
84  auto alloca1 = AllocaOperation::create(bt, size, 4);
85  auto alloca2 = AllocaOperation::create(bt, size, 4);
86  auto mux = MemoryStateMergeOperation::Create({ alloca1[1] });
87  auto & loadNode =
88  LoadNonVolatileOperation::CreateNode(*alloca1[0], { alloca1[1], alloca2[1], mux }, bt, 4);
89 
90  auto & ex = jlm::rvsdg::GraphExport::Create(*loadNode.output(0), "l");
91 
92  jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
93 
94  // Act
95  jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
97  loadNode);
98  graph.PruneNodes();
99 
100  jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
101 
102  // Assert
103  auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*ex.origin());
104  EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
105  EXPECT_EQ(node->ninputs(), 3u);
106  EXPECT_EQ(node->input(1)->origin(), alloca1[1]);
107  EXPECT_EQ(node->input(2)->origin(), mux);
108 }
109 
110 TEST(LoadOperationTests, TestDuplicateStateReduction)
111 {
112  using namespace jlm::llvm;
113 
114  // Arrange
115  const auto memoryType = MemoryStateType::Create();
116  const auto valueType = jlm::rvsdg::TestType::createValueType();
117  const auto pointerType = PointerType::Create();
118 
119  jlm::rvsdg::Graph graph;
120  const auto a = &jlm::rvsdg::GraphImport::Create(graph, pointerType, "a");
121  auto s1 = &jlm::rvsdg::GraphImport::Create(graph, memoryType, "s1");
122  auto s2 = &jlm::rvsdg::GraphImport::Create(graph, memoryType, "s2");
123  auto s3 = &jlm::rvsdg::GraphImport::Create(graph, memoryType, "s3");
124 
125  auto & loadNode = LoadNonVolatileOperation::CreateNode(*a, { s1, s2, s1, s2, s3 }, valueType, 4);
126 
127  auto & exA = jlm::rvsdg::GraphExport::Create(*loadNode.output(0), "exA");
128  auto & exS1 = jlm::rvsdg::GraphExport::Create(*loadNode.output(1), "exS1");
129  auto & exS2 = jlm::rvsdg::GraphExport::Create(*loadNode.output(2), "exS2");
130  auto & exS3 = jlm::rvsdg::GraphExport::Create(*loadNode.output(3), "exS3");
131  auto & exS4 = jlm::rvsdg::GraphExport::Create(*loadNode.output(4), "exS4");
132  auto & exS5 = jlm::rvsdg::GraphExport::Create(*loadNode.output(5), "exS5");
133 
134  view(&graph.GetRootRegion(), stdout);
135 
136  // Act
137  const auto success = jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
139  loadNode);
140 
141  view(&graph.GetRootRegion(), stdout);
142 
143  // Assert
144  EXPECT_TRUE(success);
145  const auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*exA.origin());
146  EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
147  EXPECT_EQ(node->ninputs(), 4u); // 1 address + 3 states
148  EXPECT_EQ(node->noutputs(), 4u); // 1 loaded value + 3 states
149 
150  EXPECT_EQ(exA.origin(), node->output(0));
151  EXPECT_EQ(exS1.origin(), node->output(1));
152  EXPECT_EQ(exS2.origin(), node->output(2));
153  EXPECT_EQ(exS3.origin(), node->output(1));
154  EXPECT_EQ(exS4.origin(), node->output(2));
155  EXPECT_EQ(exS5.origin(), node->output(3));
156 }
157 
158 TEST(LoadOperationTests, TestLoadStoreStateReduction)
159 {
160  using namespace jlm::llvm;
161 
162  // Arrange
163  auto bt = jlm::rvsdg::BitType::Create(32);
164 
165  jlm::rvsdg::Graph graph;
166  auto size = &jlm::rvsdg::GraphImport::Create(graph, bt, "v");
167 
168  auto alloca1 = AllocaOperation::create(bt, size, 4);
169  auto alloca2 = AllocaOperation::create(bt, size, 4);
170  auto store1 = StoreNonVolatileOperation::Create(alloca1[0], size, { alloca1[1] }, 4);
171  auto store2 = StoreNonVolatileOperation::Create(alloca2[0], size, { alloca2[1] }, 4);
172 
173  auto & loadNode1 =
174  LoadNonVolatileOperation::CreateNode(*alloca1[0], { store1[0], store2[0] }, bt, 4);
175  auto & loadNode2 = LoadNonVolatileOperation::CreateNode(*alloca1[0], { store1[0] }, bt, 8);
176 
177  auto & ex1 = jlm::rvsdg::GraphExport::Create(*loadNode1.output(0), "l1");
178  auto & ex2 = jlm::rvsdg::GraphExport::Create(*loadNode2.output(0), "l2");
179 
180  jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
181 
182  // Act
183  const auto success1 = jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
185  loadNode1);
186  const auto success2 = jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
188  loadNode2);
189  graph.PruneNodes();
190 
191  jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
192 
193  // Assert
194  EXPECT_TRUE(success1);
195  auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*ex1.origin());
196  EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
197  EXPECT_EQ(node->ninputs(), 2u);
198 
199  EXPECT_FALSE(success2);
200  node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*ex2.origin());
201  EXPECT_TRUE(is<LoadNonVolatileOperation>(node));
202  EXPECT_EQ(node->ninputs(), 2u);
203 }
204 
205 TEST(LoadOperationTests, TestLoadStoreReduction_Success)
206 {
207  using namespace jlm::llvm;
208 
209  // Arrange
211  auto pt = PointerType::Create();
212  auto mt = MemoryStateType::Create();
213 
214  jlm::rvsdg::Graph graph;
215  auto a = &jlm::rvsdg::GraphImport::Create(graph, pt, "address");
216  auto v = &jlm::rvsdg::GraphImport::Create(graph, vt, "value");
217  auto s = &jlm::rvsdg::GraphImport::Create(graph, mt, "state");
218 
219  auto s1 = StoreNonVolatileOperation::Create(a, v, { s }, 4)[0];
220  auto & loadNode = LoadNonVolatileOperation::CreateNode(*a, { s1 }, vt, 4);
221 
222  auto & x1 = jlm::rvsdg::GraphExport::Create(*loadNode.output(0), "value");
223  auto & x2 = jlm::rvsdg::GraphExport::Create(*loadNode.output(1), "state");
224 
225  jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
226 
227  // Act
228  const auto success = jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
230  loadNode);
231 
232  view(&graph.GetRootRegion(), stdout);
233 
234  // Assert
235  EXPECT_TRUE(success);
236  EXPECT_EQ(graph.GetRootRegion().numNodes(), 1u);
237  EXPECT_EQ(x1.origin(), v);
238  EXPECT_EQ(x2.origin(), s1);
239 }
240 
245 TEST(LoadOperationTests, LoadStoreReduction_DifferentValueOperandType)
246 {
247  using namespace jlm::llvm;
248 
249  // Arrange
250  const auto pointerType = PointerType::Create();
251  const auto memoryStateType = MemoryStateType::Create();
252 
253  jlm::rvsdg::Graph graph;
254  auto & address = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address");
255  auto & value = jlm::rvsdg::GraphImport::Create(graph, jlm::rvsdg::BitType::Create(32), "value");
256  auto memoryState = &jlm::rvsdg::GraphImport::Create(graph, memoryStateType, "memoryState");
257 
258  auto & storeNode = StoreNonVolatileOperation::CreateNode(address, value, { memoryState }, 4);
259  auto & loadNode = LoadNonVolatileOperation::CreateNode(
260  address,
261  outputs(&storeNode),
263  4);
264 
265  auto & exportedValue = jlm::rvsdg::GraphExport::Create(*loadNode.output(0), "v");
266  jlm::rvsdg::GraphExport::Create(*loadNode.output(1), "s");
267 
268  view(&graph.GetRootRegion(), stdout);
269 
270  // Act
271  const auto success = jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
273  loadNode);
274  graph.PruneNodes();
275 
276  view(&graph.GetRootRegion(), stdout);
277 
278  // Assert
279  EXPECT_FALSE(success);
280 
281  const auto expectedLoadNode =
282  jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*exportedValue.origin());
283  EXPECT_EQ(expectedLoadNode, &loadNode);
284  EXPECT_EQ(expectedLoadNode->ninputs(), 2u);
285 
286  const auto expectedStoreNode =
287  jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*expectedLoadNode->input(1)->origin());
288  EXPECT_EQ(expectedStoreNode, &storeNode);
289 }
290 
291 TEST(LoadOperationTests, IOBarrierAllocaAddressNormalization)
292 {
293  using namespace jlm::llvm;
294 
295  // Arrange
296  const auto valueType = jlm::rvsdg::TestType::createValueType();
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(valueType, sizeImport, 4);
309  auto & ioBarrierNode = jlm::rvsdg::CreateOpNode<IOBarrierOperation>(
310  { allocaResults[0], ioStateImport },
311  pointerType);
312 
313  auto & loadNode1 = LoadNonVolatileOperation::CreateNode(
314  *ioBarrierNode.output(0),
315  { allocaResults[1] },
316  valueType,
317  4);
318 
319  auto & loadNode2 =
320  LoadNonVolatileOperation::CreateNode(*addressImport, { memoryStateImport }, valueType, 4);
321 
322  auto & ex1 = jlm::rvsdg::GraphExport::Create(*loadNode1.output(0), "store1");
323  auto & ex2 = jlm::rvsdg::GraphExport::Create(*loadNode2.output(0), "store2");
324 
325  jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
326 
327  // Act
328  const auto successLoadNode1 = jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
330  loadNode1);
331 
332  const auto successLoadNode2 = jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
334  loadNode2);
335  graph.PruneNodes();
336 
337  jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
338 
339  // Assert
340  EXPECT_TRUE(successLoadNode1);
341  EXPECT_EQ(
342  jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*ex1.origin())->input(0)->origin(),
343  allocaResults[0]);
344 
345  // There is no IOBarrierOperation node as producer for the load address. We expect the
346  // normalization not to trigger.
347  EXPECT_FALSE(successLoadNode2);
348  EXPECT_EQ(
349  jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*ex2.origin())->input(0)->origin(),
350  addressImport);
351 }
352 
353 TEST(LoadOperationTests, IOBarrierAllocaAddressNormalization_Gamma)
354 {
355  using namespace jlm::llvm;
356  using namespace jlm::rvsdg;
357 
358  // Arrange
359  const auto valueType = TestType::createValueType();
360  const auto pointerType = PointerType::Create();
361  const auto memoryStateType = MemoryStateType::Create();
362  const auto bit32Type = jlm::rvsdg::BitType::Create(32);
363  const auto ioStateType = IOStateType::Create();
364  const auto controlType = ControlType::Create(2);
365 
366  Graph graph;
367  const auto sizeImport = &jlm::rvsdg::GraphImport::Create(graph, bit32Type, "value");
368  const auto controlImport = &jlm::rvsdg::GraphImport::Create(graph, controlType, "control");
369  auto ioStateImport = &jlm::rvsdg::GraphImport::Create(graph, ioStateType, "ioState");
370  auto valueImport = &jlm::rvsdg::GraphImport::Create(graph, valueType, "value");
371 
372  auto allocaResults = AllocaOperation::create(valueType, sizeImport, 4);
373 
374  auto gammaNode = GammaNode::create(controlImport, 2);
375  auto addressEntryVar = gammaNode->AddEntryVar(allocaResults[0]);
376  auto memoryStateEntryVar = gammaNode->AddEntryVar(allocaResults[1]);
377  auto ioStateEntryVar = gammaNode->AddEntryVar(ioStateImport);
378  auto valueEntryVar = gammaNode->AddEntryVar(valueImport);
379 
380  auto & ioBarrierNode = jlm::rvsdg::CreateOpNode<IOBarrierOperation>(
381  { addressEntryVar.branchArgument[0], ioStateEntryVar.branchArgument[0] },
382  pointerType);
383 
384  auto & loadNode = LoadNonVolatileOperation::CreateNode(
385  *ioBarrierNode.output(0),
386  { memoryStateEntryVar.branchArgument[0] },
387  valueType,
388  4);
389 
390  auto exitVar = gammaNode->AddExitVar({ loadNode.output(0), valueEntryVar.branchArgument[1] });
391 
392  GraphExport::Create(*exitVar.output, "load1");
393 
394  view(&graph.GetRootRegion(), stdout);
395 
396  // Act
397  const auto successLoadNode = jlm::rvsdg::ReduceNode<LoadNonVolatileOperation>(
399  loadNode);
400 
401  graph.PruneNodes();
402 
403  view(&graph.GetRootRegion(), stdout);
404 
405  // Assert
406  EXPECT_TRUE(successLoadNode);
407  // There should only be the load node left.
408  // The IOBarrier node should have been pruned.
409  EXPECT_EQ(gammaNode->subregion(0)->numNodes(), 1u);
410  EXPECT_EQ(
411  jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*exitVar.branchResult[0]->origin())
412  ->input(0)
413  ->origin(),
414  addressEntryVar.branchArgument[0]);
415 }
416 
417 TEST(LoadOperationTests, LoadVolatileOperationEquality)
418 {
419  using namespace jlm::llvm;
420  using namespace jlm::rvsdg;
421 
422  // Arrange
423  MemoryStateType memoryType;
424  auto valueType = jlm::rvsdg::TestType::createValueType();
425  auto pointerType = PointerType::Create();
426 
427  LoadVolatileOperation operation1(valueType, 2, 4);
428  LoadVolatileOperation operation2(pointerType, 2, 4);
429  LoadVolatileOperation operation3(valueType, 4, 4);
430  LoadVolatileOperation operation4(valueType, 2, 8);
431  TestOperation operation5({ PointerType::Create() }, { PointerType::Create() });
432 
433  // Assert
434  EXPECT_EQ(operation1, operation1);
435  EXPECT_NE(operation1, operation2); // loaded type differs
436  EXPECT_NE(operation1, operation3); // number of memory states differs
437  EXPECT_NE(operation1, operation4); // alignment differs
438  EXPECT_NE(operation1, operation5); // operation differs
439 }
440 
441 TEST(LoadOperationTests, OperationCopy)
442 {
443  using namespace jlm::llvm;
444 
445  // Arrange
446  MemoryStateType memoryType;
447  auto valueType = jlm::rvsdg::TestType::createValueType();
448  PointerType pointerType;
449 
450  LoadVolatileOperation operation(valueType, 2, 4);
451 
452  // Act
453  auto copiedOperation = operation.copy();
454 
455  // Assert
456  EXPECT_EQ(*copiedOperation, operation);
457 }
458 
459 TEST(LoadOperationTests, OperationAccessors)
460 {
461  using namespace jlm::llvm;
462 
463  // Arrange
464  MemoryStateType memoryType;
465  auto valueType = jlm::rvsdg::TestType::createValueType();
466  PointerType pointerType;
467 
468  size_t alignment = 4;
469  size_t numMemoryStates = 2;
470  LoadVolatileOperation operation(valueType, numMemoryStates, alignment);
471 
472  // Assert
473  EXPECT_EQ(operation.GetLoadedType(), valueType);
474  EXPECT_EQ(operation.NumMemoryStates(), numMemoryStates);
475  EXPECT_EQ(operation.GetAlignment(), alignment);
476  EXPECT_EQ(operation.narguments(), numMemoryStates + 2); // [address, ioState, memoryStates]
477  EXPECT_EQ(operation.nresults(), numMemoryStates + 2); // [loadedValue, ioState, memoryStates]
478 }
479 
480 TEST(LoadOperationTests, NodeCopy)
481 {
482  using namespace jlm::llvm;
483  using namespace jlm::rvsdg;
484  using namespace jlm::util;
485 
486  // Arrange
487  auto pointerType = PointerType::Create();
488  auto iOStateType = IOStateType::Create();
489  auto memoryType = MemoryStateType::Create();
490  auto valueType = TestType::createValueType();
491 
492  jlm::rvsdg::Graph graph;
493  auto & address1 = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address1");
494  auto & iOState1 = jlm::rvsdg::GraphImport::Create(graph, iOStateType, "iOState1");
495  auto & memoryState1 = jlm::rvsdg::GraphImport::Create(graph, memoryType, "memoryState1");
496 
497  auto & address2 = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address2");
498  auto & iOState2 = jlm::rvsdg::GraphImport::Create(graph, iOStateType, "iOState2");
499  auto & memoryState2 = jlm::rvsdg::GraphImport::Create(graph, memoryType, "memoryState2");
500 
501  auto & loadNode = jlm::rvsdg::CreateOpNode<LoadVolatileOperation>(
502  { &address1, &iOState1, &memoryState1 },
503  valueType,
504  1,
505  4);
506 
507  // Act
508  auto copiedNode = loadNode.copy(&graph.GetRootRegion(), { &address2, &iOState2, &memoryState2 });
509 
510  // Assert
511  auto copiedOperation = dynamic_cast<const LoadVolatileOperation *>(
512  &jlm::util::assertedCast<SimpleNode>(copiedNode)->GetOperation());
513  EXPECT_NE(copiedOperation, nullptr);
514  EXPECT_EQ(LoadOperation::AddressInput(*copiedNode).origin(), &address2);
515  EXPECT_EQ(LoadVolatileOperation::IOStateInput(*copiedNode).origin(), &iOState2);
516  EXPECT_EQ(*copiedOperation->GetLoadedType(), *valueType);
517 }
static const auto vt
Definition: PullTests.cpp:16
static std::vector< rvsdg::Output * > create(std::shared_ptr< const rvsdg::Type > allocatedType, rvsdg::Output *count, const size_t alignment)
Definition: alloca.hpp:131
static std::shared_ptr< const IOStateType > Create()
Definition: types.cpp:343
static rvsdg::SimpleNode & CreateNode(rvsdg::Region &region, std::unique_ptr< LoadNonVolatileOperation > loadOperation, const std::vector< rvsdg::Output * > &operands)
Definition: Load.hpp:466
static std::optional< std::vector< rvsdg::Output * > > NormalizeIOBarrierAllocaAddress(const LoadNonVolatileOperation &operation, const std::vector< rvsdg::Output * > &operands)
Redirect the address operand of the LoadNonVolatileOperation from an IOBarrierOperation when it can b...
Definition: Load.cpp:338
static std::optional< std::vector< rvsdg::Output * > > NormalizeLoadStoreState(const LoadNonVolatileOperation &operation, const std::vector< rvsdg::Output * > &operands)
If the producer of a load's address is an alloca operation, then we can remove all state edges origin...
Definition: Load.cpp:316
static std::optional< std::vector< rvsdg::Output * > > NormalizeDuplicateStates(const LoadNonVolatileOperation &operation, const std::vector< rvsdg::Output * > &operands)
Remove duplicated state operands.
Definition: Load.cpp:327
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *address, const Variable *state, std::shared_ptr< const rvsdg::Type > loadedType, size_t alignment)
Definition: Load.hpp:444
static std::optional< std::vector< rvsdg::Output * > > NormalizeLoadAlloca(const LoadNonVolatileOperation &operation, const std::vector< rvsdg::Output * > &operands)
If the producer of a load's address is an alloca operation, then we can remove all state edges origin...
Definition: Load.cpp:305
static std::optional< std::vector< rvsdg::Output * > > NormalizeLoadStore(const LoadNonVolatileOperation &operation, const std::vector< rvsdg::Output * > &operands)
Forwards the value from a store operation.
Definition: Load.cpp:244
size_t NumMemoryStates() const noexcept
Definition: Load.hpp:69
std::shared_ptr< const rvsdg::Type > GetLoadedType() const noexcept
Definition: Load.hpp:63
static rvsdg::Input & AddressInput(const rvsdg::Node &node) noexcept
Definition: Load.hpp:75
size_t GetAlignment() const noexcept
Definition: Load.hpp:57
static rvsdg::Input & IOStateInput(const rvsdg::Node &node) noexcept
Definition: Load.hpp:225
std::unique_ptr< Operation > copy() const override
Definition: Load.cpp:382
static rvsdg::Output * Create(const std::vector< rvsdg::Output * > &operands)
Memory state type class.
Definition: types.hpp:477
static std::shared_ptr< const MemoryStateType > Create()
Definition: types.cpp:379
PointerType class.
Definition: types.hpp:25
static std::shared_ptr< const PointerType > Create()
Definition: types.cpp:45
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *address, const Variable *value, const Variable *state, size_t alignment)
Definition: Store.hpp:304
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &address, rvsdg::Output &value, const std::vector< rvsdg::Output * > &memoryStates, size_t alignment)
Definition: Store.hpp:323
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
void PruneNodes()
Definition: graph.hpp:116
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
Output * origin() const noexcept
Definition: node.hpp:58
size_t numNodes() const noexcept
Definition: region.hpp:481
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
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
Definition: node.hpp:1058