Jlm
RegionAwareModRefSummarizerTests.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Nico Reißmann <nico.reissmann@gmail.com>
3  * Copyright 2025 Håvard Krogstie <krogstie.havard@gmail.com>
4  * See COPYING for terms of redistribution.
5  */
6 
7 #include <gtest/gtest.h>
8 
9 #include <jlm/llvm/DotWriter.hpp>
18 #include <jlm/llvm/TestRvsdgs.hpp>
19 #include <jlm/rvsdg/UnitType.hpp>
20 #include <jlm/rvsdg/view.hpp>
21 #include <jlm/util/Statistics.hpp>
22 
23 static std::unique_ptr<jlm::llvm::aa::PointsToGraph>
25 {
26  jlm::llvm::aa::Andersen andersen;
27  return andersen.Analyze(rvsdgModule);
28 }
29 
30 // Helper for comparing HashSets of MemoryNodes without needing explicit constructors
31 static bool
35 {
36  return receivedMemoryNodes == expectedMemoryNodes;
37 }
38 
39 TEST(RegionAwareModRefSummarizerTests, TestStore1)
40 {
41  /*
42  * Arrange
43  */
44  auto ValidateProvider = [](const jlm::llvm::StoreTest1 & test,
45  const jlm::llvm::aa::ModRefSummary & modRefSummary,
46  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
47  {
48  auto allocaAMemoryNode = pointsToGraph.getNodeForAlloca(*test.alloca_a);
49 
50  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda);
51  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
52 
53  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda);
54  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
55 
56  auto storeANode =
57  jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(test.alloca_a->output(0)->SingleUser());
58  EXPECT_TRUE(jlm::rvsdg::is<jlm::llvm::StoreNonVolatileOperation>(storeANode));
59 
60  auto & storeANodes = modRefSummary.GetSimpleNodeModRef(*storeANode);
61  EXPECT_TRUE(setsEqual(storeANodes, { allocaAMemoryNode }));
62  };
63 
65  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
66 
67  auto pointsToGraph = RunAndersen(test.module());
68  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*PointsToGraph);
69 
70  /*
71  * Act
72  */
73  auto modRefSummary =
75 
76  /*
77  * Assert
78  */
79  ValidateProvider(test, *modRefSummary, *pointsToGraph);
80 }
81 
82 TEST(RegionAwareModRefSummarizerTests, TestStore2)
83 {
84  /*
85  * Arrange
86  */
87  auto ValidateProvider = [](const jlm::llvm::StoreTest2 & test,
88  const jlm::llvm::aa::ModRefSummary & modRefSummary,
89  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
90  {
91  auto allocaAMemoryNode = pointsToGraph.getNodeForAlloca(*test.alloca_a);
92  auto allocaBMemoryNode = pointsToGraph.getNodeForAlloca(*test.alloca_b);
93  auto allocaPMemoryNode = pointsToGraph.getNodeForAlloca(*test.alloca_p);
94  auto allocaXMemoryNode = pointsToGraph.getNodeForAlloca(*test.alloca_x);
95  auto allocaYMemoryNode = pointsToGraph.getNodeForAlloca(*test.alloca_y);
96 
97  jlm::util::HashSet expectedMemoryNodes{ allocaAMemoryNode,
98  allocaBMemoryNode,
99  allocaPMemoryNode,
100  allocaXMemoryNode,
101  allocaYMemoryNode };
102 
103  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda);
104  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
105 
106  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda);
107  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
108  };
109 
111  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
112 
113  auto pointsToGraph = RunAndersen(test.module());
114  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*PointsToGraph);
115 
116  /*
117  * Act
118  */
119  auto modRefSummary =
121 
122  /*
123  * Assert
124  */
125  ValidateProvider(test, *modRefSummary, *pointsToGraph);
126 }
127 
128 TEST(RegionAwareModRefSummarizerTests, TestLoad1)
129 {
130  /*
131  * Arrange
132  */
133  auto ValidateProvider = [](const jlm::llvm::LoadTest1 & test,
134  const jlm::llvm::aa::ModRefSummary & modRefSummary,
135  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
136  {
137  auto externalMemoryNode = pointsToGraph.getExternalMemoryNode();
138 
139  auto lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda);
140  EXPECT_TRUE(setsEqual(lambdaEntryNodes, { externalMemoryNode }));
141 
142  auto lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda);
143  EXPECT_TRUE(setsEqual(lambdaExitNodes, { externalMemoryNode }));
144  };
145 
147  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
148 
149  auto pointsToGraph = RunAndersen(test.module());
150  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph);
151 
152  /*
153  * Act
154  */
155  auto modRefSummary =
157 
158  /*
159  * Assert
160  */
161  ValidateProvider(test, *modRefSummary, *pointsToGraph);
162 }
163 
164 TEST(RegionAwareModRefSummarizerTests, TestLoad2)
165 {
166  /*
167  * Arrange
168  */
169  auto ValidateProvider =
170  [](const jlm::llvm::LoadTest2 & test, const jlm::llvm::aa::ModRefSummary & modRefSummary)
171  {
172  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda);
173  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
174 
175  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda);
176  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
177  };
178 
180  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
181 
182  auto pointsToGraph = RunAndersen(test.module());
183  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph);
184 
185  /*
186  * Act
187  */
188  auto modRefSummary =
190 
191  /*
192  * Assert
193  */
194  ValidateProvider(test, *modRefSummary);
195 }
196 
197 TEST(RegionAwareModRefSummarizerTests, TestLoadFromUndef)
198 {
199  /*
200  * Arrange
201  */
202  auto ValidateProvider = [](const jlm::llvm::LoadFromUndefTest & test,
203  const jlm::llvm::aa::ModRefSummary & modRefSummary,
205  {
206  auto numLambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.Lambda()).Size();
207  auto numLambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.Lambda()).Size();
208 
209  EXPECT_EQ(numLambdaEntryNodes, 0u);
210  EXPECT_EQ(numLambdaExitNodes, 0u);
211  };
212 
214  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
215 
216  auto pointsToGraph = RunAndersen(test.module());
217  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph);
218 
219  /*
220  * Act
221  */
222  auto modRefSummary =
224 
225  /*
226  * Assert
227  */
228  ValidateProvider(test, *modRefSummary, *pointsToGraph);
229 }
230 
231 TEST(RegionAwareModRefSummarizerTests, TestCall1)
232 {
233  /*
234  * Arrange
235  */
236  auto ValidateProvider = [](const jlm::llvm::CallTest1 & test,
237  const jlm::llvm::aa::ModRefSummary & modRefSummary,
238  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
239  {
240  auto allocaXMemoryNode = pointsToGraph.getNodeForAlloca(*test.alloca_x);
241  auto allocaYMemoryNode = pointsToGraph.getNodeForAlloca(*test.alloca_y);
242  auto allocaZMemoryNode = pointsToGraph.getNodeForAlloca(*test.alloca_z);
243 
244  /*
245  * Validate function f
246  */
247  {
248  auto & lambdaFEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_f);
249  EXPECT_TRUE(setsEqual(lambdaFEntryNodes, { allocaXMemoryNode, allocaYMemoryNode }));
250 
251  auto & lambdaFExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_f);
252  EXPECT_TRUE(setsEqual(lambdaFExitNodes, { allocaXMemoryNode, allocaYMemoryNode }));
253  }
254 
255  /*
256  * Validate function g
257  */
258  {
259  auto & lambdaGEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_g);
260  EXPECT_TRUE(setsEqual(lambdaGEntryNodes, { allocaZMemoryNode }));
261 
262  auto & lambdaGExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_g);
263  EXPECT_TRUE(setsEqual(lambdaGExitNodes, { allocaZMemoryNode }));
264  }
265 
266  /*
267  * Validate function h
268  */
269  {
270  auto & lambdaHEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_h);
271  EXPECT_TRUE(setsEqual(lambdaHEntryNodes, {}));
272 
273  auto & callFNodes = modRefSummary.GetSimpleNodeModRef(test.CallF());
274  EXPECT_TRUE(setsEqual(callFNodes, { allocaXMemoryNode, allocaYMemoryNode }));
275 
276  auto & callGNodes = modRefSummary.GetSimpleNodeModRef(test.CallG());
277  EXPECT_TRUE(setsEqual(callGNodes, { allocaZMemoryNode }));
278 
279  auto & lambdaHExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_h);
280  EXPECT_TRUE(setsEqual(lambdaHExitNodes, {}));
281  }
282  };
283 
285  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
286 
287  auto pointsToGraph = RunAndersen(test.module());
288  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*PointsToGraph);
289 
290  /*
291  * Act
292  */
293  auto modRefSummary =
295 
296  /*
297  * Assert
298  */
299  ValidateProvider(test, *modRefSummary, *pointsToGraph);
300 }
301 
302 TEST(RegionAwareModRefSummarizerTests, TestCall2)
303 {
304  /*
305  * Arrange
306  */
307  auto ValidateProvider = [](const jlm::llvm::CallTest2 & test,
308  const jlm::llvm::aa::ModRefSummary & modRefSummary,
309  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
310  {
311  auto mallocMemoryNode = pointsToGraph.getNodeForMalloc(*test.malloc);
312 
313  /*
314  * Validate function create
315  */
316  {
317  auto & lambdaCreateEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_create);
318  EXPECT_TRUE(setsEqual(lambdaCreateEntryNodes, { mallocMemoryNode }));
319 
320  auto & lambdaCreateExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_create);
321  EXPECT_TRUE(setsEqual(lambdaCreateExitNodes, { mallocMemoryNode }));
322  }
323 
324  /*
325  * Validate function destroy
326  */
327  {
328  auto & lambdaDestroyEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_destroy);
329  EXPECT_TRUE(setsEqual(lambdaDestroyEntryNodes, { mallocMemoryNode }));
330 
331  auto & lambdaDestroyExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_destroy);
332  EXPECT_TRUE(setsEqual(lambdaDestroyExitNodes, { mallocMemoryNode }));
333  }
334 
335  /*
336  * Validate function test
337  */
338  {
339  auto & lambdaTestEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_test);
340  EXPECT_TRUE(setsEqual(lambdaTestEntryNodes, { mallocMemoryNode }));
341 
342  auto & callCreate1Nodes = modRefSummary.GetSimpleNodeModRef(test.CallCreate1());
343  EXPECT_TRUE(setsEqual(callCreate1Nodes, { mallocMemoryNode }));
344 
345  auto & callCreate2Nodes = modRefSummary.GetSimpleNodeModRef(test.CallCreate2());
346  EXPECT_TRUE(setsEqual(callCreate2Nodes, { mallocMemoryNode }));
347 
348  auto & callDestroy1Nodes = modRefSummary.GetSimpleNodeModRef(test.CallDestroy1());
349  EXPECT_TRUE(setsEqual(callDestroy1Nodes, { mallocMemoryNode }));
350 
351  auto & callDestroy2Nodes = modRefSummary.GetSimpleNodeModRef(test.CallDestroy2());
352  EXPECT_TRUE(setsEqual(callDestroy2Nodes, { mallocMemoryNode }));
353 
354  auto & lambdaTestExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_test);
355  EXPECT_TRUE(setsEqual(lambdaTestExitNodes, { mallocMemoryNode }));
356  }
357  };
358 
360  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
361 
362  auto pointsToGraph = RunAndersen(test.module());
363  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*PointsToGraph);
364 
365  /*
366  * Act
367  */
368  auto modRefSummary =
370 
371  /*
372  * Assert
373  */
374  ValidateProvider(test, *modRefSummary, *pointsToGraph);
375 }
376 
377 TEST(RegionAwareModRefSummarizerTests, TestIndirectCall)
378 {
379  /*
380  * Arrange
381  */
382  auto ValidateProvider = [](const jlm::llvm::IndirectCallTest1 & test,
383  const jlm::llvm::aa::ModRefSummary & modRefSummary,
384  [[maybe_unused]] const jlm::llvm::aa::PointsToGraph & pointsToGraph)
385  {
386  /*
387  * Validate function four
388  */
389  {
390  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaFour());
391  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
392 
393  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaFour());
394  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
395  }
396 
397  /*
398  * Validate function three
399  */
400  {
401  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaThree());
402  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
403 
404  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaThree());
405  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
406  }
407 
408  /*
409  * Validate function indcall
410  */
411  {
412  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaIndcall());
413  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
414 
415  auto & callNodes = modRefSummary.GetSimpleNodeModRef(test.CallIndcall());
416  EXPECT_TRUE(setsEqual(callNodes, {}));
417 
418  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaIndcall());
419  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
420  }
421 
422  /*
423  * Validate function test
424  */
425  {
426  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaTest());
427  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
428 
429  auto & callFourNodes = modRefSummary.GetSimpleNodeModRef(test.CallFour());
430  EXPECT_TRUE(setsEqual(callFourNodes, {}));
431 
432  auto & callThreeNodes = modRefSummary.GetSimpleNodeModRef(test.CallThree());
433  EXPECT_TRUE(setsEqual(callThreeNodes, {}));
434 
435  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaTest());
436  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
437  }
438  };
439 
441  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
442 
443  auto pointsToGraph = RunAndersen(test.module());
444  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*PointsToGraph);
445 
446  /*
447  * Act
448  */
449  auto modRefSummary =
451 
452  /*
453  * Assert
454  */
455  ValidateProvider(test, *modRefSummary, *pointsToGraph);
456 }
457 
458 TEST(RegionAwareModRefSummarizerTests, TestIndirectCall2)
459 {
460  /*
461  * Arrange
462  */
463  auto ValidateProvider = [](const jlm::llvm::IndirectCallTest2 & test,
464  const jlm::llvm::aa::ModRefSummary & modRefSummary,
465  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
466  {
467  auto deltaG1MemoryNode = pointsToGraph.getNodeForDelta(test.GetDeltaG1());
468  auto deltaG2MemoryNode = pointsToGraph.getNodeForDelta(test.GetDeltaG2());
469 
470  auto allocaPxMemoryNode = pointsToGraph.getNodeForAlloca(test.GetAllocaPx());
471  auto allocaPyMemoryNode = pointsToGraph.getNodeForAlloca(test.GetAllocaPy());
472  auto allocaPzMemoryNode = pointsToGraph.getNodeForAlloca(test.GetAllocaPz());
473 
474  const jlm::util::HashSet pX = {
475  allocaPxMemoryNode,
476  };
477  const jlm::util::HashSet pY = {
478  allocaPyMemoryNode,
479  };
480  const jlm::util::HashSet pZ = {
481  allocaPzMemoryNode,
482  };
483  const jlm::util::HashSet pXZ = { allocaPxMemoryNode, allocaPzMemoryNode };
484  const jlm::util::HashSet pXYZG1G2 = { allocaPxMemoryNode,
485  allocaPyMemoryNode,
486  allocaPzMemoryNode,
487  deltaG1MemoryNode,
488  deltaG2MemoryNode };
489  const jlm::util::HashSet pG1G2 = { deltaG1MemoryNode, deltaG2MemoryNode };
490 
491  /*
492  * Validate function four()
493  */
494  {
495  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaFour());
496  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
497 
498  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaFour());
499  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
500  }
501 
502  /*
503  * Validate function three()
504  */
505  {
506  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaThree());
507  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
508 
509  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaThree());
510  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
511  }
512 
513  /*
514  * Validate function i()
515  */
516  {
517  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaI());
518  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
519 
520  auto & callNodes = modRefSummary.GetSimpleNodeModRef(test.GetIndirectCall());
521  EXPECT_TRUE(setsEqual(callNodes, {}));
522 
523  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaI());
524  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
525  }
526 
527  /*
528  * Validate function x()
529  */
530  {
531  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaX());
532  EXPECT_TRUE(setsEqual(lambdaEntryNodes, pXZ));
533 
534  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaX());
535  EXPECT_TRUE(setsEqual(lambdaExitNodes, pXZ));
536  }
537 
538  /*
539  * Validate function y()
540  */
541  {
542  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaY());
543  EXPECT_TRUE(setsEqual(lambdaEntryNodes, pY));
544 
545  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaY());
546  EXPECT_TRUE(setsEqual(lambdaExitNodes, pY));
547  }
548 
549  /*
550  * Validate function test()
551  */
552  {
553  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaTest());
554  EXPECT_TRUE(setsEqual(lambdaEntryNodes, pG1G2));
555 
556  auto & callXNodes = modRefSummary.GetSimpleNodeModRef(test.GetTestCallX());
557  EXPECT_TRUE(setsEqual(callXNodes, pX));
558 
559  auto & callYNodes = modRefSummary.GetSimpleNodeModRef(test.GetCallY());
560  EXPECT_TRUE(setsEqual(callYNodes, pY));
561 
562  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaTest());
563  EXPECT_TRUE(setsEqual(lambdaExitNodes, pG1G2));
564  }
565 
566  /*
567  * Validate function test2()
568  */
569  {
570  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaTest2());
571  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
572 
573  auto & callXNodes = modRefSummary.GetSimpleNodeModRef(test.GetTest2CallX());
574  EXPECT_TRUE(setsEqual(callXNodes, pZ));
575 
576  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaTest2());
577  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
578  }
579  };
580 
582  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
583 
584  auto pointsToGraph = RunAndersen(test.module());
585  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*PointsToGraph);
586 
587  /*
588  * Act
589  */
590  auto modRefSummary =
592 
593  /*
594  * Assert
595  */
596  ValidateProvider(test, *modRefSummary, *pointsToGraph);
597 }
598 
599 TEST(RegionAwareModRefSummarizerTests, TestGamma)
600 {
601  /*
602  * Arrange
603  */
604  auto ValidateProvider = [](const jlm::llvm::GammaTest & test,
605  const jlm::llvm::aa::ModRefSummary & modRefSummary,
606  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
607  {
608  auto externalMemoryNode = pointsToGraph.getExternalMemoryNode();
609 
610  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda);
611  EXPECT_TRUE(setsEqual(lambdaEntryNodes, { externalMemoryNode }));
612 
613  auto gammaEntryNodes = modRefSummary.GetGammaEntryModRef(*test.gamma);
614  EXPECT_TRUE(setsEqual(gammaEntryNodes, {}));
615 
616  auto gammaExitNodes = modRefSummary.GetGammaExitModRef(*test.gamma);
617  EXPECT_TRUE(setsEqual(gammaExitNodes, {}));
618 
619  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda);
620  EXPECT_TRUE(setsEqual(lambdaExitNodes, { externalMemoryNode }));
621  };
622 
624  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
625 
626  auto pointsToGraph = RunAndersen(test.module());
627  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph);
628 
629  /*
630  * Act
631  */
632  auto modRefSummary =
634 
635  /*
636  * Assert
637  */
638  ValidateProvider(test, *modRefSummary, *pointsToGraph);
639 }
640 
641 TEST(RegionAwareModRefSummarizerTests, TestTheta)
642 {
643  /*
644  * Arrange
645  */
646  auto ValidateProvider = [](const jlm::llvm::ThetaTest & test,
647  const jlm::llvm::aa::ModRefSummary & modRefSummary,
648  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
649  {
650  auto externalMemoryNode = pointsToGraph.getExternalMemoryNode();
651 
652  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda);
653  EXPECT_TRUE(setsEqual(lambdaEntryNodes, { externalMemoryNode }));
654 
655  auto & thetaEntryExitNodes = modRefSummary.GetThetaModRef(*test.theta);
656  EXPECT_TRUE(setsEqual(thetaEntryExitNodes, { externalMemoryNode }));
657 
658  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda);
659  EXPECT_TRUE(setsEqual(lambdaExitNodes, { externalMemoryNode }));
660  };
661 
663  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
664 
665  auto pointsToGraph = RunAndersen(test.module());
666  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph);
667 
668  /*
669  * Act
670  */
671  auto modRefSummary =
673 
674  /*
675  * Assert
676  */
677  ValidateProvider(test, *modRefSummary, *pointsToGraph);
678 }
679 
680 TEST(RegionAwareModRefSummarizerTests, TestDelta1)
681 {
682  /*
683  * Arrange
684  */
685  auto ValidateProvider = [](const jlm::llvm::DeltaTest1 & test,
686  const jlm::llvm::aa::ModRefSummary & modRefSummary,
687  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
688  {
689  auto deltaFNode = pointsToGraph.getNodeForDelta(*test.delta_f);
690 
691  /*
692  * Validate function g
693  */
694  {
695  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_g);
696  EXPECT_TRUE(setsEqual(lambdaEntryNodes, { deltaFNode }));
697 
698  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_g);
699  EXPECT_TRUE(setsEqual(lambdaExitNodes, { deltaFNode }));
700  }
701 
702  /*
703  * Validate function h
704  */
705  {
706  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_h);
707  EXPECT_TRUE(setsEqual(lambdaEntryNodes, { deltaFNode }));
708 
709  auto & callEntryNodes = modRefSummary.GetSimpleNodeModRef(test.CallG());
710  EXPECT_TRUE(setsEqual(callEntryNodes, { deltaFNode }));
711 
712  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_h);
713  EXPECT_TRUE(setsEqual(lambdaExitNodes, { deltaFNode }));
714  }
715  };
716 
718  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
719 
720  auto pointsToGraph = RunAndersen(test.module());
721  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph);
722 
723  /*
724  * Act
725  */
726  auto modRefSummary =
728 
729  /*
730  * Assert
731  */
732  ValidateProvider(test, *modRefSummary, *pointsToGraph);
733 }
734 
735 TEST(RegionAwareModRefSummarizerTests, TestDelta2)
736 {
737  /*
738  * Arrange
739  */
740  auto ValidateProvider = [](const jlm::llvm::DeltaTest2 & test,
741  const jlm::llvm::aa::ModRefSummary & modRefSummary,
742  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
743  {
744  auto deltaD1Node = pointsToGraph.getNodeForDelta(*test.delta_d1);
745  auto deltaD2Node = pointsToGraph.getNodeForDelta(*test.delta_d2);
746 
747  /*
748  * Validate function f1
749  */
750  {
751  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_f1);
752  EXPECT_TRUE(setsEqual(lambdaEntryNodes, { deltaD1Node }));
753 
754  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_f1);
755  EXPECT_TRUE(setsEqual(lambdaExitNodes, { deltaD1Node }));
756  }
757 
758  /*
759  * Validate function f2
760  */
761  {
762  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_f2);
763  EXPECT_TRUE(setsEqual(lambdaEntryNodes, { deltaD1Node, deltaD2Node }));
764 
765  auto & callEntryNodes = modRefSummary.GetSimpleNodeModRef(test.CallF1());
766  EXPECT_TRUE(setsEqual(callEntryNodes, { deltaD1Node }));
767 
768  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_f2);
769  EXPECT_TRUE(setsEqual(lambdaExitNodes, { deltaD1Node, deltaD2Node }));
770  }
771  };
772 
774  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
775 
776  auto pointsToGraph = RunAndersen(test.module());
777  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph);
778 
779  /*
780  * Act
781  */
782  auto modRefSummary =
784 
785  /*
786  * Assert
787  */
788  ValidateProvider(test, *modRefSummary, *pointsToGraph);
789 }
790 
791 TEST(RegionAwareModRefSummarizerTests, TestImports)
792 {
793  /*
794  * Arrange
795  */
796  auto ValidateProvider = [](const jlm::llvm::ImportTest & test,
797  const jlm::llvm::aa::ModRefSummary & modRefSummary,
798  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
799  {
800  auto importD1Node = pointsToGraph.getNodeForImport(*test.import_d1);
801  auto importD2Node = pointsToGraph.getNodeForImport(*test.import_d2);
802 
803  /*
804  * Validate function f1
805  */
806  {
807  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_f1);
808  EXPECT_TRUE(setsEqual(lambdaEntryNodes, { importD1Node }));
809 
810  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_f1);
811  EXPECT_TRUE(setsEqual(lambdaExitNodes, { importD1Node }));
812  }
813 
814  /*
815  * Validate function f2
816  */
817  {
818  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_f2);
819  EXPECT_TRUE(setsEqual(lambdaEntryNodes, { importD1Node, importD2Node }));
820 
821  auto & callNodes = modRefSummary.GetSimpleNodeModRef(test.CallF1());
822  EXPECT_TRUE(setsEqual(callNodes, { importD1Node }));
823 
824  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_f2);
825  EXPECT_TRUE(setsEqual(lambdaExitNodes, { importD1Node, importD2Node }));
826  }
827  };
828 
830  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
831 
832  auto pointsToGraph = RunAndersen(test.module());
833  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph);
834 
835  /*
836  * Act
837  */
838  auto modRefSummary =
840 
841  /*
842  * Assert
843  */
844  ValidateProvider(test, *modRefSummary, *pointsToGraph);
845 }
846 
847 TEST(RegionAwareModRefSummarizerTests, TestPhi1)
848 {
849  /*
850  * Arrange
851  */
852  auto ValidateProvider = [](const jlm::llvm::PhiTest1 & test,
853  const jlm::llvm::aa::ModRefSummary & modRefSummary,
854  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
855  {
856  auto resultAllocaNode = pointsToGraph.getNodeForAlloca(*test.alloca);
857 
858  /*
859  * Validate function fib
860  */
861  {
862  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_fib);
863  EXPECT_TRUE(setsEqual(lambdaEntryNodes, { resultAllocaNode }));
864 
865  auto & callFibM1Nodes = modRefSummary.GetSimpleNodeModRef(test.CallFibm1());
866  EXPECT_TRUE(setsEqual(callFibM1Nodes, { resultAllocaNode }));
867 
868  auto & callFibM2Nodes = modRefSummary.GetSimpleNodeModRef(test.CallFibm2());
869  EXPECT_TRUE(setsEqual(callFibM2Nodes, { resultAllocaNode }));
870 
871  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_fib);
872  EXPECT_TRUE(setsEqual(lambdaExitNodes, { resultAllocaNode }));
873  }
874 
875  /*
876  * Validate function test
877  */
878  {
879  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.lambda_test);
880  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
881 
882  auto & callNodes = modRefSummary.GetSimpleNodeModRef(test.CallFib());
883  EXPECT_TRUE(setsEqual(callNodes, { resultAllocaNode }));
884 
885  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.lambda_test);
886  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
887  }
888  };
889 
890  jlm::llvm::PhiTest1 test;
891  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
892 
893  auto pointsToGraph = RunAndersen(test.module());
894  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph);
895 
896  /*
897  * Act
898  */
899  auto modRefSummary =
901 
902  /*
903  * Assert
904  */
905  ValidateProvider(test, *modRefSummary, *pointsToGraph);
906 }
907 
908 TEST(RegionAwareModRefSummarizerTests, TestPhi2)
909 {
910  /*
911  * Arrange
912  */
913  auto ValidateProvider = [](const jlm::llvm::PhiTest2 & test,
914  const jlm::llvm::aa::ModRefSummary & modRefSummary,
915  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
916  {
917  auto pTestAllocaMemoryNode = pointsToGraph.getNodeForAlloca(test.GetPTestAlloca());
918  auto paAllocaMemoryNode = pointsToGraph.getNodeForAlloca(test.GetPaAlloca());
919  [[maybe_unused]] auto pbAllocaMemoryNode = pointsToGraph.getNodeForAlloca(test.GetPbAlloca());
920  auto pcAllocaMemoryNode = pointsToGraph.getNodeForAlloca(test.GetPcAlloca());
921  auto pdAllocaMemoryNode = pointsToGraph.getNodeForAlloca(test.GetPdAlloca());
922 
923  jlm::util::HashSet pTestAC({ pTestAllocaMemoryNode, paAllocaMemoryNode, pcAllocaMemoryNode });
924  jlm::util::HashSet pTestBD({ pTestAllocaMemoryNode, pbAllocaMemoryNode, pdAllocaMemoryNode });
925  jlm::util::HashSet pTestCD({ pTestAllocaMemoryNode, pcAllocaMemoryNode, pdAllocaMemoryNode });
926  jlm::util::HashSet pTestAD({ pTestAllocaMemoryNode, paAllocaMemoryNode, pdAllocaMemoryNode });
927  jlm::util::HashSet pTestACD(
928  { pTestAllocaMemoryNode, paAllocaMemoryNode, pcAllocaMemoryNode, pdAllocaMemoryNode });
929 
930  /*
931  * Validate function eight()
932  */
933  {
934  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaEight());
935  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
936 
937  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaEight());
938  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
939  }
940 
941  /*
942  * Validate function i()
943  */
944  {
945  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaI());
946  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
947 
948  auto & callNodes = modRefSummary.GetSimpleNodeModRef(test.GetIndirectCall());
949  EXPECT_TRUE(setsEqual(callNodes, {}));
950 
951  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaI());
952  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
953  }
954 
955  /*
956  * Validate function a()
957  */
958  {
959  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaA());
960  EXPECT_TRUE(setsEqual(lambdaEntryNodes, pTestCD));
961 
962  auto & callBNodes = modRefSummary.GetSimpleNodeModRef(test.GetCallB());
963  EXPECT_TRUE(setsEqual(callBNodes, pTestAD));
964 
965  auto & callDNodes = modRefSummary.GetSimpleNodeModRef(test.GetCallD());
966  EXPECT_TRUE(setsEqual(callDNodes, pTestAC));
967 
968  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaA());
969  EXPECT_TRUE(setsEqual(lambdaExitNodes, pTestCD));
970  }
971 
972  /*
973  * Validate function b()
974  */
975  {
976  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaB());
977  EXPECT_TRUE(setsEqual(lambdaEntryNodes, pTestAD));
978 
979  auto & callINodes = modRefSummary.GetSimpleNodeModRef(test.GetCallI());
980  EXPECT_TRUE(setsEqual(callINodes, {}));
981 
982  auto & callCNodes = modRefSummary.GetSimpleNodeModRef(test.GetCallC());
983  EXPECT_TRUE(setsEqual(callCNodes, pTestBD));
984 
985  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaB());
986  EXPECT_TRUE(setsEqual(lambdaExitNodes, pTestAD));
987  }
988 
989  /*
990  * Validate function c()
991  */
992  {
993  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaC());
994  EXPECT_TRUE(setsEqual(lambdaEntryNodes, pTestBD));
995 
996  auto & callNodes = modRefSummary.GetSimpleNodeModRef(test.GetCallAFromC());
997  EXPECT_TRUE(setsEqual(callNodes, pTestCD));
998 
999  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaC());
1000  EXPECT_TRUE(setsEqual(lambdaExitNodes, pTestBD));
1001  }
1002 
1003  /*
1004  * Validate function d()
1005  */
1006  {
1007  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaD());
1008  EXPECT_TRUE(setsEqual(lambdaEntryNodes, pTestAC));
1009 
1010  auto & callNodes = modRefSummary.GetSimpleNodeModRef(test.GetCallAFromD());
1011  EXPECT_TRUE(setsEqual(callNodes, pTestCD));
1012 
1013  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaD());
1014  EXPECT_TRUE(setsEqual(lambdaExitNodes, pTestAC));
1015  }
1016 
1017  /*
1018  * Validate function test()
1019  */
1020  {
1021  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.GetLambdaTest());
1022  EXPECT_TRUE(setsEqual(lambdaEntryNodes, {}));
1023 
1024  auto & callNodes = modRefSummary.GetSimpleNodeModRef(test.GetCallAFromTest());
1025  EXPECT_TRUE(setsEqual(callNodes, { pTestAllocaMemoryNode }));
1026 
1027  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.GetLambdaTest());
1028  EXPECT_TRUE(setsEqual(lambdaExitNodes, {}));
1029  }
1030  };
1031 
1032  jlm::llvm::PhiTest2 test;
1033  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
1034 
1035  auto pointsToGraph = RunAndersen(test.module());
1036  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph);
1037 
1038  /*
1039  * Act
1040  */
1041  auto modRefSummary =
1043 
1044  /*
1045  * Assert
1046  */
1047  ValidateProvider(test, *modRefSummary, *pointsToGraph);
1048 }
1049 
1050 TEST(RegionAwareModRefSummarizerTests, TestPhiWithDelta)
1051 {
1052  // Assert
1054  std::unordered_map<const jlm::rvsdg::Output *, std::string> outputMap;
1055  // std::cout << jlm::rvsdg::view(&test.graph().GetRootRegion(), outputMap) << std::flush;
1056 
1057  auto pointsToGraph = RunAndersen(test.module());
1058  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph, outputMap) << std::flush;
1059 
1060  // Act
1061  auto modRefSummary =
1063 
1064  // Assert
1065  // Nothing needs to be validated as there are only phi and delta nodes in the RVSDG.
1066 }
1067 
1068 TEST(RegionAwareModRefSummarizerTests, TestMemcpy)
1069 {
1070  /*
1071  * Arrange
1072  */
1073  auto ValidateProvider = [](const jlm::llvm::MemcpyTest & test,
1074  const jlm::llvm::aa::ModRefSummary & modRefSummary,
1075  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
1076  {
1077  auto localArrayMemoryNode = pointsToGraph.getNodeForDelta(test.LocalArray());
1078  auto globalArrayMemoryNode = pointsToGraph.getNodeForDelta(test.GlobalArray());
1079 
1080  /*
1081  * Validate function f
1082  */
1083  {
1084  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.LambdaF());
1085  EXPECT_TRUE(setsEqual(lambdaEntryNodes, { globalArrayMemoryNode }));
1086 
1087  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.LambdaF());
1088  EXPECT_TRUE(setsEqual(lambdaExitNodes, { globalArrayMemoryNode }));
1089  }
1090 
1091  /*
1092  * Validate function g
1093  */
1094  {
1095  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(test.LambdaG());
1096  EXPECT_TRUE(setsEqual(lambdaEntryNodes, { localArrayMemoryNode, globalArrayMemoryNode }));
1097 
1098  auto & callNodes = modRefSummary.GetSimpleNodeModRef(test.CallF());
1099  EXPECT_TRUE(setsEqual(callNodes, { globalArrayMemoryNode }));
1100 
1101  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(test.LambdaG());
1102  EXPECT_TRUE(setsEqual(lambdaExitNodes, { localArrayMemoryNode, globalArrayMemoryNode }));
1103  }
1104  };
1105 
1106  jlm::llvm::MemcpyTest test;
1107  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
1108 
1109  auto pointsToGraph = RunAndersen(test.module());
1110  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*PointsToGraph);
1111 
1112  /*
1113  * Act
1114  */
1115  auto modRefSummary =
1117 
1118  /*
1119  * Assert
1120  */
1121  ValidateProvider(test, *modRefSummary, *pointsToGraph);
1122 }
1123 
1124 TEST(RegionAwareModRefSummarizerTests, TestEscapedMemory1)
1125 {
1126  /*
1127  * Arrange
1128  */
1129  auto ValidateProvider = [](const jlm::llvm::EscapedMemoryTest1 & test,
1130  const jlm::llvm::aa::ModRefSummary & modRefSummary,
1131  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
1132  {
1133  auto deltaBMemoryNode = pointsToGraph.getNodeForDelta(*test.DeltaB);
1134  // Delta A, X and Y have been compressed into the external memory node
1135  auto externalMemoryNode = pointsToGraph.getExternalMemoryNode();
1136 
1137  jlm::util::HashSet expectedMemoryNodes{ deltaBMemoryNode, externalMemoryNode };
1138 
1139  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.LambdaTest);
1140  EXPECT_TRUE(setsEqual(lambdaEntryNodes, expectedMemoryNodes));
1141 
1142  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.LambdaTest);
1143  EXPECT_TRUE(setsEqual(lambdaExitNodes, expectedMemoryNodes));
1144  };
1145 
1147  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
1148 
1149  auto pointsToGraph = RunAndersen(test.module());
1150  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph);
1151 
1152  /*
1153  * Act
1154  */
1155  auto modRefSummary =
1157 
1158  /*
1159  * Assert
1160  */
1161  ValidateProvider(test, *modRefSummary, *pointsToGraph);
1162 }
1163 
1164 TEST(RegionAwareModRefSummarizerTests, TestEscapedMemory2)
1165 {
1166  /*
1167  * Arrange
1168  */
1169  auto ValidateProvider = [](const jlm::llvm::EscapedMemoryTest2 & test,
1170  const jlm::llvm::aa::ModRefSummary & modRefSummary,
1171  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
1172  {
1173  auto returnAddressMallocMemoryNode = pointsToGraph.getNodeForMalloc(*test.ReturnAddressMalloc);
1174  auto callExternalFunction1MallocMemoryNode =
1175  pointsToGraph.getNodeForMalloc(*test.CallExternalFunction1Malloc);
1176 
1177  auto externalMemoryNode = pointsToGraph.getExternalMemoryNode();
1178 
1179  /*
1180  * Validate ReturnAddress function
1181  */
1182  {
1183  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.ReturnAddressFunction);
1184  EXPECT_TRUE(setsEqual(lambdaEntryNodes, { returnAddressMallocMemoryNode }));
1185 
1186  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.ReturnAddressFunction);
1187  EXPECT_TRUE(setsEqual(lambdaExitNodes, { returnAddressMallocMemoryNode }));
1188  }
1189 
1190  /*
1191  * Validate CallExternalFunction1 function
1192  */
1193  {
1194  // The returnAddressMallocMemoryNode is compressed into the external node
1195  jlm::util::HashSet expectedMemoryNodes{ callExternalFunction1MallocMemoryNode,
1196  externalMemoryNode };
1197 
1198  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.CallExternalFunction1);
1199  EXPECT_TRUE(setsEqual(lambdaEntryNodes, expectedMemoryNodes));
1200 
1201  auto & callNodes = modRefSummary.GetSimpleNodeModRef(*test.ExternalFunction1Call);
1202  EXPECT_TRUE(setsEqual(callNodes, expectedMemoryNodes));
1203 
1204  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.CallExternalFunction1);
1205  EXPECT_TRUE(setsEqual(lambdaExitNodes, expectedMemoryNodes));
1206  }
1207 
1208  /*
1209  * Validate CallExternalFunction2 function
1210  */
1211  {
1212  // The function only does a call, and a load of unknown, so everything can be compressed
1214  externalMemoryNode
1215  };
1216 
1217  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.CallExternalFunction2);
1218  EXPECT_TRUE(setsEqual(lambdaEntryNodes, expectedMemoryNodes));
1219 
1220  auto & callNodes = modRefSummary.GetSimpleNodeModRef(*test.ExternalFunction2Call);
1221  EXPECT_TRUE(setsEqual(callNodes, expectedMemoryNodes));
1222 
1223  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.CallExternalFunction2);
1224  EXPECT_TRUE(setsEqual(lambdaExitNodes, expectedMemoryNodes));
1225  }
1226  };
1227 
1229  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
1230 
1231  auto pointsToGraph = RunAndersen(test.module());
1232  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph);
1233 
1234  /*
1235  * Act
1236  */
1237  auto modRefSummary =
1239 
1240  /*
1241  * Assert
1242  */
1243  ValidateProvider(test, *modRefSummary, *pointsToGraph);
1244 }
1245 
1246 TEST(RegionAwareModRefSummarizerTests, TestEscapedMemory3)
1247 {
1248  /*
1249  * Arrange
1250  */
1251  auto ValidateProvider = [](const jlm::llvm::EscapedMemoryTest3 & test,
1252  const jlm::llvm::aa::ModRefSummary & modRefSummary,
1253  const jlm::llvm::aa::PointsToGraph & pointsToGraph)
1254  {
1255  auto externalMemoryNode = pointsToGraph.getExternalMemoryNode();
1256 
1257  // DeltaGlobal has been compressed into the externalMemoryNode
1258  jlm::util::HashSet expectedMemoryNodes{ externalMemoryNode };
1259 
1260  auto & lambdaEntryNodes = modRefSummary.GetLambdaEntryModRef(*test.LambdaTest);
1261  EXPECT_TRUE(setsEqual(lambdaEntryNodes, expectedMemoryNodes));
1262 
1263  auto & callNodes = modRefSummary.GetSimpleNodeModRef(*test.CallExternalFunction);
1264  EXPECT_TRUE(setsEqual(callNodes, expectedMemoryNodes));
1265 
1266  auto & lambdaExitNodes = modRefSummary.GetLambdaExitModRef(*test.LambdaTest);
1267  EXPECT_TRUE(setsEqual(lambdaExitNodes, expectedMemoryNodes));
1268  };
1269 
1271  // jlm::rvsdg::view(test.graph().GetRootRegion(), stdout);
1272 
1273  auto pointsToGraph = RunAndersen(test.module());
1274  // std::cout << jlm::llvm::aa::PointsToGraph::dumpDot(*pointsToGraph);
1275 
1276  /*
1277  * Act
1278  */
1279  auto modRefSummary =
1281 
1282  /*
1283  * Assert
1284  */
1285  ValidateProvider(test, *modRefSummary, *pointsToGraph);
1286 }
1287 
1288 TEST(RegionAwareModRefSummarizerTests, testSetjmpHandling)
1289 {
1290  using namespace jlm;
1291  using namespace jlm::llvm;
1292 
1293  // Creates the RVSDG equivalent of the program
1294  //
1295  // void opaque();
1296  // int _setjmp(jmp_buf*);
1297  //
1298  // jmp_buf buf;
1299  //
1300  // static void h() {
1301  // opaque(); // This call should have a in its Mod/Ref set
1302  // }
1303  //
1304  // static void k() {
1305  // // This call does nothing
1306  // }
1307  //
1308  // static void g(int* p) {
1309  // if (_setjmp(&buf))
1310  // return;
1311  // else {
1312  // *p = 10;
1313  // h(); // This call should have a in its Mod/Ref set
1314  // k(); // Nothing should be routed into this call
1315  // }
1316  // }
1317  //
1318  // int f() {
1319  // int a;
1320  // g(a);
1321  // return a;
1322  // }
1323 
1324  // Arrange
1325  LlvmRvsdgModule rvsdgModule(jlm::util::FilePath(""), "", "");
1326  auto & graph = rvsdgModule.Rvsdg();
1327  auto & rootRegion = graph.GetRootRegion();
1328 
1329  const auto ioStateType = IOStateType::Create();
1330  const auto memoryStateType = MemoryStateType::Create();
1331  const auto pointerType = PointerType::Create();
1332  const auto int32Type = rvsdg::BitType::Create(32);
1333  // We don't care about the type of the jmp_buf, just use an array
1334  const auto jmpBufType = ArrayType::Create(int32Type, 34);
1335  const auto unitType = rvsdg::UnitType::Create();
1336 
1337  const auto unitFunctionType = rvsdg::FunctionType::Create(
1338  { ioStateType, memoryStateType },
1339  { ioStateType, memoryStateType });
1340 
1341  const auto setjmpFunctionType = rvsdg::FunctionType::Create(
1342  { pointerType, ioStateType, memoryStateType },
1343  { int32Type, ioStateType, memoryStateType });
1344 
1345  const auto gFunctionType = rvsdg::FunctionType::Create(
1346  { pointerType, ioStateType, memoryStateType },
1347  { ioStateType, memoryStateType });
1348 
1349  const auto fFunctionType = rvsdg::FunctionType::Create(
1350  { ioStateType, memoryStateType },
1351  { int32Type, ioStateType, memoryStateType });
1352 
1353  auto & opaqueImport = LlvmGraphImport::createFunctionImport(
1354  graph,
1355  unitFunctionType,
1356  "opaque",
1359 
1360  auto & setjmpImport = LlvmGraphImport::createFunctionImport(
1361  graph,
1362  setjmpFunctionType,
1363  "_setjmp",
1366 
1367  auto & bufGlobal = *rvsdg::DeltaNode::Create(
1368  &rootRegion,
1369  DeltaOperation::Create(jmpBufType, "buf", Linkage::externalLinkage, "", false, 4));
1370  bufGlobal.finalize(UndefValueOperation::Create(*bufGlobal.subregion(), jmpBufType));
1371 
1372  rvsdg::SimpleNode * callOpaqueNode = nullptr;
1373  rvsdg::SimpleNode * callHNode = nullptr;
1374  rvsdg::SimpleNode * callKNode = nullptr;
1375  rvsdg::SimpleNode * allocaNode = nullptr;
1376 
1377  auto & hLambdaNode = *rvsdg::LambdaNode::Create(
1378  rootRegion,
1379  LlvmLambdaOperation::Create(unitFunctionType, "h", Linkage::internalLinkage));
1380  {
1381  const auto arguments = hLambdaNode.GetFunctionArguments();
1382  auto ioState = arguments.at(0);
1383  auto memoryState = arguments.at(1);
1384 
1385  const auto opaqueCtxVar = hLambdaNode.AddContextVar(opaqueImport);
1386 
1387  const auto call =
1388  CallOperation::Create(opaqueCtxVar.inner, unitFunctionType, { ioState, memoryState });
1389  callOpaqueNode = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*call[0]);
1390  ioState = call[0];
1391  memoryState = call[1];
1392 
1393  hLambdaNode.finalize({ ioState, memoryState });
1394  }
1395 
1396  auto & kLambdaNode = *rvsdg::LambdaNode::Create(
1397  rootRegion,
1398  LlvmLambdaOperation::Create(unitFunctionType, "k", Linkage::internalLinkage));
1399  {
1400  const auto arguments = kLambdaNode.GetFunctionArguments();
1401  kLambdaNode.finalize({ arguments.at(0), arguments.at(1) });
1402  }
1403 
1404  auto & gLambdaNode = *rvsdg::LambdaNode::Create(
1405  rootRegion,
1407  {
1408  const auto arguments = gLambdaNode.GetFunctionArguments();
1409  const auto p = arguments.at(0);
1410  auto ioState = arguments.at(1);
1411  auto memoryState = arguments.at(2);
1412 
1413  const auto setjmpCtxVar = gLambdaNode.AddContextVar(setjmpImport);
1414  const auto bufCtxVar = gLambdaNode.AddContextVar(bufGlobal.output());
1415  const auto hCtxVar = gLambdaNode.AddContextVar(*hLambdaNode.output());
1416  const auto kCtxVar = gLambdaNode.AddContextVar(*kLambdaNode.output());
1417 
1418  const auto setjmpCall = CallOperation::Create(
1419  setjmpCtxVar.inner,
1420  setjmpFunctionType,
1421  { bufCtxVar.inner, ioState, memoryState });
1422  auto & setjmpResult = *setjmpCall[0];
1423  ioState = setjmpCall[1];
1424  memoryState = setjmpCall[2];
1425 
1426  auto & matchOutput = *rvsdg::MatchOperation::Create(setjmpResult, { { 0, 0 } }, 1, 2);
1427  auto & gammaNode = rvsdg::GammaNode::Create(matchOutput, 2, { unitType, unitType });
1428  auto pEntryVar = gammaNode.AddEntryVar(p);
1429  auto hEntryVar = gammaNode.AddEntryVar(hCtxVar.inner);
1430  auto kEntryVar = gammaNode.AddEntryVar(kCtxVar.inner);
1431  auto ioStateEntryVar = gammaNode.AddEntryVar(ioState);
1432  auto memoryStateEntryVar = gammaNode.AddEntryVar(memoryState);
1433  auto & elseRegion = *gammaNode.subregion(0);
1434  const auto constant10 = IntegerConstantOperation::Create(elseRegion, 32, 10).output(0);
1435  const auto storeOutputs = StoreNonVolatileOperation::Create(
1436  pEntryVar.branchArgument[0],
1437  constant10,
1438  { memoryStateEntryVar.branchArgument[0] },
1439  4);
1440 
1441  const auto hCall = CallOperation::Create(
1442  hEntryVar.branchArgument[0],
1443  unitFunctionType,
1444  { ioStateEntryVar.branchArgument[0], storeOutputs[0] });
1445  callHNode = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*hCall[0]);
1446 
1447  const auto kCall = CallOperation::Create(
1448  kEntryVar.branchArgument[0],
1449  unitFunctionType,
1450  { hCall[0], hCall[1] });
1451  callKNode = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*kCall[0]);
1452 
1453  ioState = gammaNode.AddExitVar({ kCall[0], ioStateEntryVar.branchArgument[1] }).output;
1454  memoryState = gammaNode.AddExitVar({ kCall[1], memoryStateEntryVar.branchArgument[1] }).output;
1455 
1456  gLambdaNode.finalize({ ioState, memoryState });
1457  }
1458 
1459  auto & fLambdaNode = *rvsdg::LambdaNode::Create(
1460  rootRegion,
1462  {
1463  const auto arguments = fLambdaNode.GetFunctionArguments();
1464  const auto ioStateIn = arguments.at(0);
1465  const auto memoryStateIn = arguments.at(1);
1466 
1467  const auto gCtxVar = fLambdaNode.AddContextVar(*gLambdaNode.output());
1468 
1469  const auto constant1 =
1470  IntegerConstantOperation::Create(*fLambdaNode.subregion(), 32, 1).output(0);
1471  const auto aAlloca = AllocaOperation::create(int32Type, constant1, 4);
1472  allocaNode = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*aAlloca[0]);
1473 
1474  auto & memoryStateJoin =
1475  rvsdg::CreateOpNode<MemoryStateJoinOperation>({ memoryStateIn, aAlloca[1] }, 2);
1476 
1477  const auto gCall = CallOperation::Create(
1478  gCtxVar.inner,
1479  gFunctionType,
1480  { aAlloca[0], ioStateIn, memoryStateJoin.output(0) });
1481 
1482  auto loadOutputs = LoadNonVolatileOperation::Create(aAlloca[0], { gCall[1] }, int32Type, 4);
1483 
1484  fLambdaNode.finalize({ loadOutputs[0], gCall[0], loadOutputs[1] });
1485  }
1486 
1487  rvsdg::GraphExport::Create(*fLambdaNode.output(), "f");
1488 
1490  LlvmDotWriter writer;
1491  writer.WriteGraphs(gw, rootRegion, true);
1492  // gw.outputAllGraphs(std::cout, util::graph::OutputFormat::Dot);
1493 
1494  // Act
1496  util::StatisticsCollector collector(settings);
1497  const auto ptg = RunAndersen(rvsdgModule);
1498  const auto modRefSummary = aa::RegionAwareModRefSummarizer::Create(rvsdgModule, *ptg, collector);
1499 
1500  // Assert
1501  EXPECT_NE(callOpaqueNode, nullptr);
1502  EXPECT_NE(callHNode, nullptr);
1503  EXPECT_NE(callKNode, nullptr);
1504  EXPECT_NE(allocaNode, nullptr);
1505 
1506  const auto allocaPtgNode = ptg->getNodeForAlloca(*allocaNode);
1507 
1508  // The call to h() within g() should contain a in its Mod/Ref set
1509  const auto callHModRef = modRefSummary->GetSimpleNodeModRef(*callHNode);
1510  EXPECT_TRUE(callHModRef.Contains(allocaPtgNode));
1511 
1512  // The call to k() should NOT contain a in its Mod/Ref set
1513  const auto callKModRef = modRefSummary->GetSimpleNodeModRef(*callKNode);
1514  EXPECT_FALSE(callKModRef.Contains(allocaPtgNode));
1515 
1516  // The call to opaque() within h() only contains the external memory node,
1517  // since the memory node representing a has been compressed into it
1518  const auto callOpaqueModRef = modRefSummary->GetSimpleNodeModRef(*callOpaqueNode);
1519  EXPECT_EQ(callOpaqueModRef.Size(), 1);
1520 
1521  // Check the statistics to ensure that the right functions in the call graph were marked
1522  auto & statistic = *collector.CollectedStatistics().begin();
1523  // Only k() is not in the same SCC as <external>
1524  EXPECT_EQ(statistic.GetMeasurementValue<uint64_t>("#CallGraphSccs"), 2u);
1525  // g(), k() and h() are the only functions within an active setjmp
1526  EXPECT_EQ(statistic.GetMeasurementValue<uint64_t>("#FunctionsCallingSetjmp"), 1u);
1527 }
1528 
1529 TEST(RegionAwareModRefSummarizerTests, TestEscapedFunction)
1530 {
1531  using namespace jlm;
1532  using namespace jlm::llvm;
1533 
1550  LlvmRvsdgModule rvsdgModule(util::FilePath(""), "", "");
1551  auto & graph = rvsdgModule.Rvsdg();
1552  auto & rootRegion = graph.GetRootRegion();
1553 
1554  const auto ioStateType = IOStateType::Create();
1555  const auto memoryStateType = MemoryStateType::Create();
1556  const auto int32Type = rvsdg::BitType::Create(32);
1557 
1558  const auto opaqueFunctionType = rvsdg::FunctionType::Create(
1559  { ioStateType, memoryStateType },
1560  { ioStateType, memoryStateType });
1561 
1562  const auto fFunctionType = rvsdg::FunctionType::Create(
1563  { ioStateType, memoryStateType },
1564  { int32Type, ioStateType, memoryStateType });
1565 
1566  auto & opaqueImport = LlvmGraphImport::createFunctionImport(
1567  graph,
1568  opaqueFunctionType,
1569  "opaque",
1572 
1573  auto & global = *rvsdg::DeltaNode::Create(
1574  &rootRegion,
1575  DeltaOperation::Create(int32Type, "global", Linkage::internalLinkage, "", false, 4));
1576  global.finalize(IntegerConstantOperation::Create(*global.subregion(), 32, 0).output(0));
1577 
1578  rvsdg::SimpleNode * opaqueCallNode = nullptr;
1579  auto & fLambdaNode = *rvsdg::LambdaNode::Create(
1580  rootRegion,
1582  {
1583  const auto arguments = fLambdaNode.GetFunctionArguments();
1584  auto ioState = arguments.at(0);
1585  auto memoryState = arguments.at(1);
1586 
1587  const auto globalCtxVar = fLambdaNode.AddContextVar(global.output());
1588  const auto opaqueCtxVar = fLambdaNode.AddContextVar(opaqueImport);
1589 
1590  const auto loadOutputs =
1591  LoadNonVolatileOperation::Create(globalCtxVar.inner, { memoryState }, int32Type, 4);
1592  const auto one = IntegerConstantOperation::Create(*fLambdaNode.subregion(), 32, 1).output(0);
1593  const auto incrementedGlobal =
1594  rvsdg::CreateOpNode<IntegerAddOperation>({ loadOutputs[0], one }, 32).output(0);
1595  const auto storeOutputs = StoreNonVolatileOperation::Create(
1596  globalCtxVar.inner,
1597  incrementedGlobal,
1598  { loadOutputs[1] },
1599  4);
1600 
1601  const auto opaqueCall =
1602  CallOperation::Create(opaqueCtxVar.inner, opaqueFunctionType, { ioState, storeOutputs[0] });
1603  opaqueCallNode = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*opaqueCall[0]);
1604  ioState = opaqueCall[0];
1605  memoryState = opaqueCall[1];
1606 
1607  const auto returnLoadOutputs =
1608  LoadNonVolatileOperation::Create(globalCtxVar.inner, { memoryState }, int32Type, 4);
1609 
1610  fLambdaNode.finalize({ returnLoadOutputs[0], ioState, returnLoadOutputs[1] });
1611  }
1612 
1613  rvsdg::GraphExport::Create(*fLambdaNode.output(), "f");
1614 
1615  const auto pointsToGraph = RunAndersen(rvsdgModule);
1616  const auto modRefSummary = aa::RegionAwareModRefSummarizer::Create(rvsdgModule, *pointsToGraph);
1617 
1618  const auto globalMemoryNode = pointsToGraph->getNodeForDelta(global);
1619  const auto externalMemoryNode = pointsToGraph->getExternalMemoryNode();
1620  const util::HashSet expectedMemoryNodes{ globalMemoryNode, externalMemoryNode };
1621 
1622  const auto & opaqueCallModRef = modRefSummary->GetSimpleNodeModRef(*opaqueCallNode);
1623  EXPECT_TRUE(setsEqual(opaqueCallModRef, expectedMemoryNodes));
1624 }
1625 
1626 TEST(RegionAwareModRefSummarizerTests, TestStatistics)
1627 {
1628  using namespace jlm;
1629 
1630  // Arrange
1631  jlm::llvm::LoadTest2 test;
1632  auto pointsToGraph = RunAndersen(test.module());
1633 
1634  util::StatisticsCollectorSettings statisticsCollectorSettings(
1636  util::StatisticsCollector statisticsCollector(statisticsCollectorSettings);
1637 
1638  // Act
1640  test.module(),
1641  *pointsToGraph,
1643 
1644  // Assert
1646  auto & statistics = *statisticsCollector.CollectedStatistics().begin();
1647 
1648  EXPECT_EQ(statistics.GetMeasurementValue<uint64_t>("#RvsdgNodes"), 18u);
1649  EXPECT_EQ(statistics.GetMeasurementValue<uint64_t>("#RvsdgRegions"), 2u);
1650  EXPECT_EQ(statistics.GetMeasurementValue<uint64_t>("#PointsToGraphMemoryNodes"), 7u);
1651  EXPECT_EQ(statistics.GetMeasurementValue<uint64_t>("#SimpleAllocas"), 5u);
1652  EXPECT_EQ(statistics.GetMeasurementValue<uint64_t>("#NonReentrantAllocas"), 5u);
1653  EXPECT_EQ(statistics.GetMeasurementValue<uint64_t>("#CallGraphSccs"), 2u);
1654 
1655  EXPECT_TRUE(statistics.HasTimer("CallGraphTimer"));
1656  EXPECT_TRUE(statistics.HasTimer("AllocasDeadInSccsTimer"));
1657  EXPECT_TRUE(statistics.HasTimer("SimpleAllocasSetTimer"));
1658  EXPECT_TRUE(statistics.HasTimer("NonReentrantAllocaSetsTimer"));
1659  EXPECT_TRUE(statistics.HasTimer("CreateExternalModRefSetTimer"));
1660  EXPECT_TRUE(statistics.HasTimer("AnnotationTimer"));
1661  EXPECT_TRUE(statistics.HasTimer("SolvingTimer"));
1662 }
static jlm::util::StatisticsCollector statisticsCollector
static bool setsEqual(const jlm::util::HashSet< jlm::llvm::aa::PointsToGraph::NodeIndex > &receivedMemoryNodes, const jlm::util::HashSet< jlm::llvm::aa::PointsToGraph::NodeIndex > &expectedMemoryNodes)
static std::unique_ptr< jlm::llvm::aa::PointsToGraph > RunAndersen(jlm::llvm::LlvmRvsdgModule &rvsdgModule)
TEST(RegionAwareModRefSummarizerTests, TestStore1)
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 ArrayType > Create(std::shared_ptr< const Type > type, size_t nelements)
Definition: types.hpp:98
static std::vector< rvsdg::Output * > Create(rvsdg::Output *function, std::shared_ptr< const rvsdg::FunctionType > functionType, const std::vector< rvsdg::Output * > &arguments)
Definition: call.hpp:464
CallTest1 class.
Definition: TestRvsdgs.hpp:425
rvsdg::SimpleNode * alloca_y
Definition: TestRvsdgs.hpp:448
const rvsdg::SimpleNode & CallG() const noexcept
Definition: TestRvsdgs.hpp:438
rvsdg::SimpleNode * alloca_z
Definition: TestRvsdgs.hpp:449
jlm::rvsdg::LambdaNode * lambda_g
Definition: TestRvsdgs.hpp:444
jlm::rvsdg::LambdaNode * lambda_f
Definition: TestRvsdgs.hpp:443
rvsdg::SimpleNode * alloca_x
Definition: TestRvsdgs.hpp:447
const rvsdg::SimpleNode & CallF() const noexcept
Definition: TestRvsdgs.hpp:432
jlm::rvsdg::LambdaNode * lambda_h
Definition: TestRvsdgs.hpp:445
CallTest2 class.
Definition: TestRvsdgs.hpp:488
jlm::rvsdg::LambdaNode * lambda_test
Definition: TestRvsdgs.hpp:516
const rvsdg::SimpleNode & CallCreate2() const noexcept
Definition: TestRvsdgs.hpp:497
jlm::rvsdg::LambdaNode * lambda_create
Definition: TestRvsdgs.hpp:514
const rvsdg::SimpleNode & CallDestroy2() const noexcept
Definition: TestRvsdgs.hpp:509
jlm::rvsdg::LambdaNode * lambda_destroy
Definition: TestRvsdgs.hpp:515
const rvsdg::SimpleNode & CallDestroy1() const noexcept
Definition: TestRvsdgs.hpp:503
const rvsdg::SimpleNode & CallCreate1() const noexcept
Definition: TestRvsdgs.hpp:491
rvsdg::SimpleNode * malloc
Definition: TestRvsdgs.hpp:518
static std::unique_ptr< DeltaOperation > Create(std::shared_ptr< const rvsdg::Type > type, const std::string &name, const Linkage &linkage, std::string section, bool constant, const size_t alignment)
Definition: delta.hpp:84
DeltaTest1 class.
jlm::rvsdg::DeltaNode * delta_f
jlm::rvsdg::LambdaNode * lambda_h
jlm::rvsdg::LambdaNode * lambda_g
const rvsdg::SimpleNode & CallG() const noexcept
DeltaTest2 class.
jlm::rvsdg::LambdaNode * lambda_f2
jlm::rvsdg::LambdaNode * lambda_f1
const rvsdg::SimpleNode & CallF1() const noexcept
jlm::rvsdg::DeltaNode * delta_d2
jlm::rvsdg::DeltaNode * delta_d1
EscapedMemoryTest1 class.
jlm::rvsdg::DeltaNode * DeltaB
jlm::rvsdg::LambdaNode * LambdaTest
EscapedMemoryTest2 class.
jlm::rvsdg::LambdaNode * CallExternalFunction2
rvsdg::SimpleNode * ExternalFunction1Call
rvsdg::SimpleNode * ReturnAddressMalloc
jlm::rvsdg::LambdaNode * CallExternalFunction1
rvsdg::SimpleNode * ExternalFunction2Call
jlm::rvsdg::LambdaNode * ReturnAddressFunction
rvsdg::SimpleNode * CallExternalFunction1Malloc
EscapedMemoryTest3 class.
rvsdg::SimpleNode * CallExternalFunction
jlm::rvsdg::LambdaNode * LambdaTest
GammaTest class.
Definition: TestRvsdgs.hpp:961
rvsdg::GammaNode * gamma
Definition: TestRvsdgs.hpp:969
jlm::rvsdg::LambdaNode * lambda
Definition: TestRvsdgs.hpp:967
static std::shared_ptr< const IOStateType > Create()
Definition: types.cpp:343
ImportTest class.
jlm::rvsdg::LambdaNode * lambda_f1
jlm::rvsdg::LambdaNode * lambda_f2
jlm::rvsdg::GraphImport * import_d2
jlm::rvsdg::GraphImport * import_d1
const rvsdg::SimpleNode & CallF1() const noexcept
IndirectCallTest1 class.
Definition: TestRvsdgs.hpp:566
const jlm::rvsdg::LambdaNode & GetLambdaTest() const noexcept
Definition: TestRvsdgs.hpp:605
const jlm::rvsdg::LambdaNode & GetLambdaIndcall() const noexcept
Definition: TestRvsdgs.hpp:599
const rvsdg::SimpleNode & CallThree() const noexcept
Definition: TestRvsdgs.hpp:575
const jlm::rvsdg::LambdaNode & GetLambdaFour() const noexcept
Definition: TestRvsdgs.hpp:593
const rvsdg::SimpleNode & CallIndcall() const noexcept
Definition: TestRvsdgs.hpp:569
const jlm::rvsdg::LambdaNode & GetLambdaThree() const noexcept
Definition: TestRvsdgs.hpp:587
const rvsdg::SimpleNode & CallFour() const noexcept
Definition: TestRvsdgs.hpp:581
IndirectCallTest2 class.
Definition: TestRvsdgs.hpp:687
rvsdg::SimpleNode & GetCallY() const noexcept
Definition: TestRvsdgs.hpp:774
rvsdg::SimpleNode & GetTest2CallX() const noexcept
Definition: TestRvsdgs.hpp:768
jlm::rvsdg::LambdaNode & GetLambdaI() const noexcept
Definition: TestRvsdgs.hpp:714
jlm::rvsdg::LambdaNode & GetLambdaFour() const noexcept
Definition: TestRvsdgs.hpp:708
jlm::rvsdg::LambdaNode & GetLambdaTest() const noexcept
Definition: TestRvsdgs.hpp:732
jlm::rvsdg::LambdaNode & GetLambdaTest2() const noexcept
Definition: TestRvsdgs.hpp:738
jlm::rvsdg::SimpleNode & GetAllocaPy() const noexcept
Definition: TestRvsdgs.hpp:786
jlm::rvsdg::LambdaNode & GetLambdaX() const noexcept
Definition: TestRvsdgs.hpp:720
rvsdg::SimpleNode & GetIndirectCall() const noexcept
Definition: TestRvsdgs.hpp:744
jlm::rvsdg::LambdaNode & GetLambdaY() const noexcept
Definition: TestRvsdgs.hpp:726
jlm::rvsdg::SimpleNode & GetAllocaPz() const noexcept
Definition: TestRvsdgs.hpp:792
jlm::rvsdg::DeltaNode & GetDeltaG2() const noexcept
Definition: TestRvsdgs.hpp:696
rvsdg::SimpleNode & GetTestCallX() const noexcept
Definition: TestRvsdgs.hpp:762
jlm::rvsdg::DeltaNode & GetDeltaG1() const noexcept
Definition: TestRvsdgs.hpp:690
jlm::rvsdg::LambdaNode & GetLambdaThree() const noexcept
Definition: TestRvsdgs.hpp:702
jlm::rvsdg::SimpleNode & GetAllocaPx() const noexcept
Definition: TestRvsdgs.hpp:780
static rvsdg::Node & Create(rvsdg::Region &region, IntegerValueRepresentation representation)
static LlvmGraphImport & createFunctionImport(rvsdg::Graph &graph, std::shared_ptr< const rvsdg::FunctionType > functionType, std::string name, Linkage linkage, CallingConvention callingConvention)
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)
Definition: lambda.hpp:84
LoadFromUndefTest class.
Definition: TestRvsdgs.hpp:236
const jlm::rvsdg::LambdaNode & Lambda() const noexcept
Definition: TestRvsdgs.hpp:243
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
LoadTest1 class.
Definition: TestRvsdgs.hpp:161
jlm::rvsdg::LambdaNode * lambda
Definition: TestRvsdgs.hpp:167
LoadTest2 class.
Definition: TestRvsdgs.hpp:200
jlm::rvsdg::LambdaNode * lambda
Definition: TestRvsdgs.hpp:206
MemcpyTest class.
const jlm::rvsdg::DeltaNode & LocalArray() const noexcept
const jlm::rvsdg::DeltaNode & GlobalArray() const noexcept
const rvsdg::SimpleNode & CallF() const noexcept
const jlm::rvsdg::LambdaNode & LambdaF() const noexcept
const jlm::rvsdg::LambdaNode & LambdaG() const noexcept
static std::shared_ptr< const MemoryStateType > Create()
Definition: types.cpp:379
PhiTest1 class.
rvsdg::SimpleNode * alloca
jlm::rvsdg::LambdaNode * lambda_test
const rvsdg::SimpleNode & CallFibm2() const noexcept
jlm::rvsdg::LambdaNode * lambda_fib
const rvsdg::SimpleNode & CallFib() const noexcept
const rvsdg::SimpleNode & CallFibm1() const noexcept
PhiTest2 class.
jlm::rvsdg::LambdaNode & GetLambdaTest() const noexcept
jlm::rvsdg::LambdaNode & GetLambdaA() const noexcept
jlm::rvsdg::SimpleNode & GetPdAlloca() const noexcept
rvsdg::SimpleNode & GetCallB() const noexcept
jlm::rvsdg::LambdaNode & GetLambdaEight() const noexcept
jlm::rvsdg::LambdaNode & GetLambdaD() const noexcept
rvsdg::SimpleNode & GetCallD() const noexcept
jlm::rvsdg::SimpleNode & GetPTestAlloca() const noexcept
rvsdg::SimpleNode & GetCallAFromTest() const noexcept
jlm::rvsdg::SimpleNode & GetPcAlloca() const noexcept
rvsdg::SimpleNode & GetCallC() const noexcept
rvsdg::SimpleNode & GetIndirectCall() const noexcept
jlm::rvsdg::LambdaNode & GetLambdaI() const noexcept
rvsdg::SimpleNode & GetCallAFromD() const noexcept
jlm::rvsdg::SimpleNode & GetPaAlloca() const noexcept
rvsdg::SimpleNode & GetCallI() const noexcept
jlm::rvsdg::LambdaNode & GetLambdaB() const noexcept
jlm::rvsdg::LambdaNode & GetLambdaC() const noexcept
rvsdg::SimpleNode & GetCallAFromC() const noexcept
jlm::rvsdg::SimpleNode & GetPbAlloca() const noexcept
static std::shared_ptr< const PointerType > Create()
Definition: types.cpp:45
jlm::llvm::LlvmRvsdgModule & module()
Definition: TestRvsdgs.hpp:34
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *address, const Variable *value, const Variable *state, size_t alignment)
Definition: Store.hpp:304
StoreTest1 class.
Definition: TestRvsdgs.hpp:89
rvsdg::SimpleNode * alloca_a
Definition: TestRvsdgs.hpp:99
jlm::rvsdg::LambdaNode * lambda
Definition: TestRvsdgs.hpp:95
StoreTest2 class.
Definition: TestRvsdgs.hpp:127
rvsdg::SimpleNode * alloca_p
Definition: TestRvsdgs.hpp:141
jlm::rvsdg::LambdaNode * lambda
Definition: TestRvsdgs.hpp:133
rvsdg::SimpleNode * alloca_y
Definition: TestRvsdgs.hpp:140
rvsdg::SimpleNode * alloca_x
Definition: TestRvsdgs.hpp:139
rvsdg::SimpleNode * alloca_b
Definition: TestRvsdgs.hpp:138
rvsdg::SimpleNode * alloca_a
Definition: TestRvsdgs.hpp:137
ThetaTest class.
jlm::rvsdg::LambdaNode * lambda
jlm::rvsdg::ThetaNode * theta
static jlm::rvsdg::Output * Create(rvsdg::Region &region, std::shared_ptr< const jlm::rvsdg::Type > type)
Definition: operators.hpp:1055
std::unique_ptr< PointsToGraph > Analyze(const rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
Definition: Andersen.cpp:1531
static std::unique_ptr< ModRefSummary > Create(const rvsdg::RvsdgModule &rvsdgModule, const PointsToGraph &pointsToGraph, util::StatisticsCollector &statisticsCollector)
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
Definition: type.cpp:45
static DeltaNode * Create(rvsdg::Region *parent, std::unique_ptr< DeltaOperation > op)
Definition: delta.hpp:313
util::graph::Graph & WriteGraphs(util::graph::Writer &writer, const Region &region, bool emitTypeGraph)
Definition: DotWriter.cpp:198
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 GammaNode & Create(jlm::rvsdg::Output &predicate, size_t numAlternatives, std::vector< std::shared_ptr< const Type >> matchContentTypes)
Definition: gamma.hpp:167
EntryVar AddEntryVar(rvsdg::Output *origin)
Routes a variable into the gamma branches.
Definition: gamma.cpp:260
static GraphExport & Create(Output &origin, std::string name)
Definition: graph.cpp:62
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
Definition: lambda.cpp:140
static Output * Create(Output &predicate, const std::unordered_map< uint64_t, uint64_t > &mapping, const uint64_t defaultAlternative, const size_t numAlternatives)
Definition: control.hpp:242
NodeOutput * output(size_t index) const noexcept
Definition: node.hpp:650
rvsdg::Input & SingleUser() noexcept
Definition: node.hpp:347
Graph & Rvsdg() noexcept
Definition: RvsdgModule.hpp:57
NodeOutput * output(size_t index) const noexcept
Definition: simple-node.hpp:88
static std::shared_ptr< const UnitType > Create()
Definition: UnitType.cpp:33
StatisticsRange CollectedStatistics() const noexcept
Definition: Statistics.hpp:528
size_t NumCollectedStatistics() const noexcept
Definition: Statistics.hpp:535
Global memory state passed between functions.