6 #include <gtest/gtest.h>
15 static std::unique_ptr<jlm::llvm::aa::PointsToGraph>
21 return andersen.
Analyze(module);
31 [[nodiscard]]
static bool
35 const std::unordered_set<jlm::llvm::aa::PointsToGraph::NodeIndex> & expectedTargets)
39 std::unordered_set<PointsToGraph::NodeIndex> actualTargets;
41 actualTargets.insert(target);
46 actualTargets.insert(target);
48 return actualTargets == expectedTargets;
58 [[nodiscard]]
static bool
61 const std::unordered_set<jlm::llvm::aa::PointsToGraph::NodeIndex> & nodes)
70 return expected == actual;
73 TEST(AndersenTests, TestStore1)
82 EXPECT_EQ(ptg->numAllocaNodes(), 4u);
83 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
84 EXPECT_EQ(ptg->numMappedRegisters(), 5u);
86 auto alloca_a = ptg->getNodeForAlloca(*test.
alloca_a);
87 auto alloca_b = ptg->getNodeForAlloca(*test.
alloca_b);
88 auto alloca_c = ptg->getNodeForAlloca(*test.
alloca_c);
89 auto alloca_d = ptg->getNodeForAlloca(*test.
alloca_d);
91 auto palloca_a = ptg->getNodeForRegister(*test.
alloca_a->
output(0));
92 auto palloca_b = ptg->getNodeForRegister(*test.
alloca_b->
output(0));
93 auto palloca_c = ptg->getNodeForRegister(*test.
alloca_c->
output(0));
94 auto palloca_d = ptg->getNodeForRegister(*test.
alloca_d->
output(0));
96 auto lambda = ptg->getNodeForLambda(*test.
lambda);
97 auto plambda = ptg->getNodeForRegister(*test.
lambda->
output());
115 TEST(AndersenTests, TestStore2)
120 EXPECT_EQ(ptg->numAllocaNodes(), 5u);
121 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
122 EXPECT_EQ(ptg->numMappedRegisters(), 6u);
124 auto alloca_a = ptg->getNodeForAlloca(*test.
alloca_a);
125 auto alloca_b = ptg->getNodeForAlloca(*test.
alloca_b);
126 auto alloca_x = ptg->getNodeForAlloca(*test.
alloca_x);
127 auto alloca_y = ptg->getNodeForAlloca(*test.
alloca_y);
128 auto alloca_p = ptg->getNodeForAlloca(*test.
alloca_p);
130 auto palloca_a = ptg->getNodeForRegister(*test.
alloca_a->
output(0));
131 auto palloca_b = ptg->getNodeForRegister(*test.
alloca_b->
output(0));
132 auto palloca_x = ptg->getNodeForRegister(*test.
alloca_x->
output(0));
133 auto palloca_y = ptg->getNodeForRegister(*test.
alloca_y->
output(0));
134 auto palloca_p = ptg->getNodeForRegister(*test.
alloca_p->
output(0));
136 auto lambda = ptg->getNodeForLambda(*test.
lambda);
137 auto plambda = ptg->getNodeForRegister(*test.
lambda->
output());
143 EXPECT_TRUE(
TargetsExactly(*ptg, alloca_p, { alloca_x, alloca_y }));
162 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
163 EXPECT_EQ(ptg->numMappedRegisters(), 3u);
165 auto loadResult = ptg->getNodeForRegister(*test.
load_p->
output(0));
167 auto lambda = ptg->getNodeForLambda(*test.
lambda);
168 auto lambdaOutput = ptg->getNodeForRegister(*test.
lambda->
output());
171 EXPECT_TRUE(
TargetsExactly(*ptg, loadResult, { lambda, ptg->getExternalMemoryNode() }));
174 EXPECT_TRUE(
TargetsExactly(*ptg, lambdaArgument0, { lambda, ptg->getExternalMemoryNode() }));
184 EXPECT_EQ(ptg->numAllocaNodes(), 5u);
185 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
186 EXPECT_EQ(ptg->numMappedRegisters(), 8u);
188 auto alloca_a = ptg->getNodeForAlloca(*test.
alloca_a);
189 auto alloca_b = ptg->getNodeForAlloca(*test.
alloca_b);
190 auto alloca_x = ptg->getNodeForAlloca(*test.
alloca_x);
191 auto alloca_y = ptg->getNodeForAlloca(*test.
alloca_y);
192 auto alloca_p = ptg->getNodeForAlloca(*test.
alloca_p);
194 auto pload_x = ptg->getNodeForRegister(*test.
load_x->
output(0));
195 auto pload_a = ptg->getNodeForRegister(*test.
load_a->
output(0));
197 auto lambdaMemoryNode = ptg->getNodeForLambda(*test.
lambda);
200 EXPECT_TRUE(
TargetsExactly(*ptg, alloca_y, { alloca_a, alloca_b }));
209 TEST(AndersenTests, TestLoadFromUndef)
214 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
215 EXPECT_EQ(ptg->numMappedRegisters(), 2u);
217 auto lambdaMemoryNode = ptg->getNodeForLambda(test.
Lambda());
224 TEST(AndersenTests, TestGetElementPtr)
229 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
230 EXPECT_EQ(ptg->numMappedRegisters(), 4u);
233 auto lambda = ptg->getNodeForLambda(*test.
lambda);
238 EXPECT_EQ(gepX, gepY);
240 EXPECT_TRUE(
TargetsExactly(*ptg, gepX, { lambda, ptg->getExternalMemoryNode() }));
245 TEST(AndersenTests, TestBitCast)
250 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
251 EXPECT_EQ(ptg->numMappedRegisters(), 3u);
253 auto lambda = ptg->getNodeForLambda(*test.
lambda);
254 auto lambdaOut = ptg->getNodeForRegister(*test.
lambda->
output());
256 auto bitCast = ptg->getNodeForRegister(*test.
bitCast->
output(0));
259 EXPECT_TRUE(
TargetsExactly(*ptg, lambdaArg, { lambda, ptg->getExternalMemoryNode() }));
260 EXPECT_TRUE(
TargetsExactly(*ptg, bitCast, { lambda, ptg->getExternalMemoryNode() }));
265 TEST(AndersenTests, TestConstantPointerNull)
270 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
271 EXPECT_EQ(ptg->numMappedRegisters(), 3u);
273 auto lambda = ptg->getNodeForLambda(*test.
lambda);
274 auto lambdaOut = ptg->getNodeForRegister(*test.
lambda->
output());
280 EXPECT_TRUE(
TargetsExactly(*ptg, lambdaArg, { lambda, ptg->getExternalMemoryNode() }));
286 TEST(AndersenTests, TestBits2Ptr)
291 EXPECT_EQ(ptg->numLambdaNodes(), 2u);
292 EXPECT_EQ(ptg->numMappedRegisters(), 5u);
294 auto lambdaTestMemoryNode = ptg->getNodeForLambda(test.
GetLambdaTest());
295 auto externalMemoryNode = ptg->getExternalMemoryNode();
300 EXPECT_TRUE(
TargetsExactly(*ptg, callOutput0, { lambdaTestMemoryNode, externalMemoryNode }));
301 EXPECT_TRUE(
TargetsExactly(*ptg, bits2ptr, { lambdaTestMemoryNode, externalMemoryNode }));
311 EXPECT_EQ(ptg->numAllocaNodes(), 3u);
312 EXPECT_EQ(ptg->numLambdaNodes(), 3u);
313 EXPECT_EQ(ptg->numMappedRegisters(), 12u);
315 auto alloca_x = ptg->getNodeForAlloca(*test.
alloca_x);
316 auto alloca_y = ptg->getNodeForAlloca(*test.
alloca_y);
317 auto alloca_z = ptg->getNodeForAlloca(*test.
alloca_z);
319 auto palloca_x = ptg->getNodeForRegister(*test.
alloca_x->
output(0));
320 auto palloca_y = ptg->getNodeForRegister(*test.
alloca_y->
output(0));
321 auto palloca_z = ptg->getNodeForRegister(*test.
alloca_z->
output(0));
323 auto lambda_f = ptg->getNodeForLambda(*test.
lambda_f);
324 auto lambda_g = ptg->getNodeForLambda(*test.
lambda_g);
325 auto lambda_h = ptg->getNodeForLambda(*test.
lambda_h);
327 auto plambda_f = ptg->getNodeForRegister(*test.
lambda_f->
output());
328 auto plambda_g = ptg->getNodeForRegister(*test.
lambda_g->
output());
329 auto plambda_h = ptg->getNodeForRegister(*test.
lambda_h->
output());
365 EXPECT_EQ(ptg->numLambdaNodes(), 3u);
366 EXPECT_EQ(ptg->numMallocNodes(), 1u);
367 EXPECT_EQ(ptg->numImportNodes(), 0u);
368 EXPECT_EQ(ptg->numMappedRegisters(), 11u);
370 auto lambda_create = ptg->getNodeForLambda(*test.
lambda_create);
373 auto lambda_destroy = ptg->getNodeForLambda(*test.
lambda_destroy);
375 auto lambda_destroy_arg =
378 auto lambda_test = ptg->getNodeForLambda(*test.
lambda_test);
386 auto malloc = ptg->getNodeForMalloc(*test.
malloc);
387 auto malloc_out = ptg->getNodeForRegister(*test.
malloc->
output(0));
389 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_create_out, { lambda_create }));
391 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_destroy_out, { lambda_destroy }));
392 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_destroy_arg, { malloc }));
394 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_test_out, { lambda_test }));
395 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_test_cv1, { lambda_create }));
396 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_test_cv2, { lambda_destroy }));
406 TEST(AndersenTests, TestIndirectCall1)
411 EXPECT_EQ(ptg->numLambdaNodes(), 4u);
412 EXPECT_EQ(ptg->numImportNodes(), 0u);
413 EXPECT_EQ(ptg->numMappedRegisters(), 11u);
418 auto lambda_four = ptg->getNodeForLambda(test.
GetLambdaFour());
423 auto lambda_indcall_arg =
426 auto lambda_test = ptg->getNodeForLambda(test.
GetLambdaTest());
432 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_three_out, { lambda_three }));
434 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_four_out, { lambda_four }));
436 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_indcall_out, { lambda_indcall }));
437 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_indcall_arg, { lambda_three, lambda_four }));
439 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_test_out, { lambda_test }));
440 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_test_cv0, { lambda_indcall }));
441 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_test_cv1, { lambda_four }));
442 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_test_cv2, { lambda_three }));
447 TEST(AndersenTests, TestIndirectCall2)
452 EXPECT_EQ(ptg->numAllocaNodes(), 3u);
453 EXPECT_EQ(ptg->numLambdaNodes(), 7u);
454 EXPECT_EQ(ptg->numDeltaNodes(), 2u);
455 EXPECT_EQ(ptg->numMappedRegisters(), 27u);
460 auto lambdaFour = ptg->getNodeForLambda(test.
GetLambdaFour());
463 EXPECT_TRUE(
TargetsExactly(*ptg, lambdaThreeOutput, { lambdaThree }));
464 EXPECT_TRUE(
TargetsExactly(*ptg, lambdaFourOutput, { lambdaFour }));
467 TEST(AndersenTests, TestExternalCall1)
472 EXPECT_EQ(ptg->numAllocaNodes(), 2u);
473 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
474 EXPECT_EQ(ptg->numImportNodes(), 1u);
475 EXPECT_EQ(ptg->numMappedRegisters(), 10u);
477 auto lambdaF = ptg->getNodeForLambda(test.
LambdaF());
482 auto callResult = ptg->getNodeForRegister(*test.
CallG().
output(0));
484 auto externalMemory = ptg->getExternalMemoryNode();
486 EXPECT_TRUE(
TargetsExactly(*ptg, lambdaFArgument0, { lambdaF, importG, externalMemory }));
487 EXPECT_TRUE(
TargetsExactly(*ptg, lambdaFArgument1, { lambdaF, importG, externalMemory }));
488 EXPECT_TRUE(
TargetsExactly(*ptg, callResult, { lambdaF, importG, externalMemory }));
496 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
497 EXPECT_EQ(ptg->numMappedRegisters(), 15u);
499 auto lambda = ptg->getNodeForLambda(*test.
lambda);
501 for (
size_t n = 1; n < 5; n++)
504 EXPECT_TRUE(
TargetsExactly(*ptg, lambdaArgument, { lambda, ptg->getExternalMemoryNode() }));
508 EXPECT_EQ(entryvars.size(), 4u);
509 for (
const auto & entryvar : entryvars)
511 auto argument0 = ptg->getNodeForRegister(*entryvar.branchArgument[0]);
512 auto argument1 = ptg->getNodeForRegister(*entryvar.branchArgument[1]);
514 EXPECT_TRUE(
TargetsExactly(*ptg, argument0, { lambda, ptg->getExternalMemoryNode() }));
515 EXPECT_TRUE(
TargetsExactly(*ptg, argument1, { lambda, ptg->getExternalMemoryNode() }));
518 for (
size_t n = 0; n < 4; n++)
520 auto gammaOutput = ptg->getNodeForRegister(*test.
gamma->
GetExitVars()[0].output);
521 EXPECT_TRUE(
TargetsExactly(*ptg, gammaOutput, { lambda, ptg->getExternalMemoryNode() }));
532 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
533 EXPECT_EQ(ptg->numMappedRegisters(), 5u);
535 auto lambda = ptg->getNodeForLambda(*test.
lambda);
537 auto lambdaOutput = ptg->getNodeForRegister(*test.
lambda->
output());
539 auto gepOutput = ptg->getNodeForRegister(*test.
gep->
output(0));
541 auto thetaArgument2 = ptg->getNodeForRegister(*test.
theta->
GetLoopVars()[2].pre);
542 auto thetaOutput2 = ptg->getNodeForRegister(*test.
theta->
output(2));
544 EXPECT_TRUE(
TargetsExactly(*ptg, lambdaArgument1, { lambda, ptg->getExternalMemoryNode() }));
547 EXPECT_TRUE(
TargetsExactly(*ptg, gepOutput, { lambda, ptg->getExternalMemoryNode() }));
549 EXPECT_TRUE(
TargetsExactly(*ptg, thetaArgument2, { lambda, ptg->getExternalMemoryNode() }));
550 EXPECT_TRUE(
TargetsExactly(*ptg, thetaOutput2, { lambda, ptg->getExternalMemoryNode() }));
555 TEST(AndersenTests, TestDelta1)
560 EXPECT_EQ(ptg->numDeltaNodes(), 1u);
561 EXPECT_EQ(ptg->numLambdaNodes(), 2u);
562 EXPECT_EQ(ptg->numMappedRegisters(), 6u);
564 auto delta_f = ptg->getNodeForDelta(*test.
delta_f);
565 auto pdelta_f = ptg->getNodeForRegister(test.
delta_f->
output());
567 auto lambda_g = ptg->getNodeForLambda(*test.
lambda_g);
568 auto plambda_g = ptg->getNodeForRegister(*test.
lambda_g->
output());
571 auto lambda_h = ptg->getNodeForLambda(*test.
lambda_h);
572 auto plambda_h = ptg->getNodeForRegister(*test.
lambda_h->
output());
589 TEST(AndersenTests, TestDelta2)
594 EXPECT_EQ(ptg->numDeltaNodes(), 2u);
595 EXPECT_EQ(ptg->numLambdaNodes(), 2u);
596 EXPECT_EQ(ptg->numMappedRegisters(), 8u);
598 auto delta_d1 = ptg->getNodeForDelta(*test.
delta_d1);
599 auto delta_d1_out = ptg->getNodeForRegister(test.
delta_d1->
output());
601 auto delta_d2 = ptg->getNodeForDelta(*test.
delta_d2);
602 auto delta_d2_out = ptg->getNodeForRegister(test.
delta_d2->
output());
604 auto lambda_f1 = ptg->getNodeForLambda(*test.
lambda_f1);
605 auto lambda_f1_out = ptg->getNodeForRegister(*test.
lambda_f1->
output());
608 auto lambda_f2 = ptg->getNodeForLambda(*test.
lambda_f2);
609 auto lambda_f2_out = ptg->getNodeForRegister(*test.
lambda_f2->
output());
620 EXPECT_EQ(lambda_f1_cvd1, delta_d1_out);
621 EXPECT_EQ(lambda_f2_cvd1, delta_d1_out);
622 EXPECT_EQ(lambda_f2_cvd2, delta_d2_out);
623 EXPECT_EQ(lambda_f2_cvf1, lambda_f1_out);
628 TEST(AndersenTests, TestImports)
633 EXPECT_EQ(ptg->numLambdaNodes(), 2u);
634 EXPECT_EQ(ptg->numImportNodes(), 2u);
635 EXPECT_EQ(ptg->numMappedRegisters(), 8u);
637 auto d1 = ptg->getNodeForImport(*test.
import_d1);
638 auto import_d1 = ptg->getNodeForRegister(*test.
import_d1);
640 auto d2 = ptg->getNodeForImport(*test.
import_d2);
641 auto import_d2 = ptg->getNodeForRegister(*test.
import_d2);
643 auto lambda_f1 = ptg->getNodeForLambda(*test.
lambda_f1);
644 auto lambda_f1_out = ptg->getNodeForRegister(*test.
lambda_f1->
output());
647 auto lambda_f2 = ptg->getNodeForLambda(*test.
lambda_f2);
648 auto lambda_f2_out = ptg->getNodeForRegister(*test.
lambda_f2->
output());
659 EXPECT_EQ(lambda_f1_cvd1, import_d1);
660 EXPECT_EQ(lambda_f2_cvd1, import_d1);
661 EXPECT_EQ(lambda_f2_cvd2, import_d2);
662 EXPECT_EQ(lambda_f2_cvf1, lambda_f1_out);
672 EXPECT_EQ(ptg->numAllocaNodes(), 1u);
673 EXPECT_EQ(ptg->numLambdaNodes(), 2u);
674 EXPECT_EQ(ptg->numMappedRegisters(), 16u);
676 auto lambda_fib = ptg->getNodeForLambda(*test.
lambda_fib);
680 auto lambda_test = ptg->getNodeForLambda(*test.
lambda_test);
683 auto phi_rv = ptg->getNodeForRegister(*test.
phi->
GetFixVars()[0].output);
684 auto phi_rv_arg = ptg->getNodeForRegister(*test.
phi->
GetFixVars()[0].recref);
686 auto gamma_result = ptg->getNodeForRegister(*test.
gamma->
GetEntryVars()[1].branchArgument[0]);
687 auto gamma_fib = ptg->getNodeForRegister(*test.
gamma->
GetEntryVars()[2].branchArgument[0]);
689 auto alloca = ptg->getNodeForAlloca(*test.
alloca);
690 auto alloca_out = ptg->getNodeForRegister(*test.
alloca->
output(0));
692 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_fib_out, { lambda_fib }));
695 EXPECT_TRUE(
TargetsExactly(*ptg, lambda_test_out, { lambda_test }));
697 EXPECT_EQ(phi_rv, lambda_fib_out);
708 TEST(AndersenTests, TestExternalMemory)
713 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
714 EXPECT_EQ(ptg->numMappedRegisters(), 3u);
716 auto lambdaF = ptg->getNodeForLambda(*test.
LambdaF);
720 EXPECT_TRUE(
TargetsExactly(*ptg, lambdaFArgument0, { lambdaF, ptg->getExternalMemoryNode() }));
721 EXPECT_TRUE(
TargetsExactly(*ptg, lambdaFArgument1, { lambdaF, ptg->getExternalMemoryNode() }));
726 TEST(AndersenTests, TestEscapedMemory1)
731 EXPECT_EQ(ptg->numDeltaNodes(), 4u);
732 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
733 EXPECT_EQ(ptg->numMappedRegisters(), 10u);
737 auto loadNode1Output = ptg->getNodeForRegister(*test.
LoadNode1->
output(0));
739 auto deltaA = ptg->getNodeForDelta(*test.
DeltaA);
740 auto deltaB = ptg->getNodeForDelta(*test.
DeltaB);
741 auto deltaX = ptg->getNodeForDelta(*test.
DeltaX);
742 auto deltaY = ptg->getNodeForDelta(*test.
DeltaY);
743 auto lambdaTest = ptg->getNodeForLambda(*test.
LambdaTest);
744 auto externalMemory = ptg->getExternalMemoryNode();
749 { deltaA, deltaX, deltaY, lambdaTest, externalMemory }));
754 { deltaA, deltaX, deltaY, lambdaTest, externalMemory }));
756 EXPECT_TRUE(
EscapedIsExactly(*ptg, { lambdaTest, deltaA, deltaX, deltaY }));
759 TEST(AndersenTests, TestEscapedMemory2)
764 EXPECT_EQ(ptg->numImportNodes(), 2u);
765 EXPECT_EQ(ptg->numLambdaNodes(), 3u);
766 EXPECT_EQ(ptg->numMallocNodes(), 2u);
767 EXPECT_EQ(ptg->numMappedRegisters(), 10u);
774 auto externalMemory = ptg->getExternalMemoryNode();
778 auto externalFunction2CallResult =
783 externalFunction2CallResult,
784 { returnAddressFunction,
785 callExternalFunction1,
786 callExternalFunction2,
789 callExternalFunction1Malloc,
790 externalFunction1Import,
791 externalFunction2Import }));
795 { returnAddressFunction,
796 callExternalFunction1,
797 callExternalFunction2,
799 callExternalFunction1Malloc,
800 externalFunction1Import,
801 externalFunction2Import }));
804 TEST(AndersenTests, TestEscapedMemory3)
809 EXPECT_EQ(ptg->numDeltaNodes(), 1u);
810 EXPECT_EQ(ptg->numImportNodes(), 1u);
811 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
812 EXPECT_EQ(ptg->numMappedRegisters(), 5u);
814 auto lambdaTest = ptg->getNodeForLambda(*test.
LambdaTest);
815 auto deltaGlobal = ptg->getNodeForDelta(*test.
DeltaGlobal);
817 auto externalMemory = ptg->getExternalMemoryNode();
823 callExternalFunctionResult,
824 { lambdaTest, deltaGlobal, importExternalFunction, externalMemory }));
826 EXPECT_TRUE(
EscapedIsExactly(*ptg, { lambdaTest, deltaGlobal, importExternalFunction }));
829 TEST(AndersenTests, TestMemcpy)
834 EXPECT_EQ(ptg->numDeltaNodes(), 2u);
835 EXPECT_EQ(ptg->numLambdaNodes(), 2u);
836 EXPECT_EQ(ptg->numMappedRegisters(), 11u);
838 auto localArray = ptg->getNodeForDelta(test.
LocalArray());
839 auto globalArray = ptg->getNodeForDelta(test.
GlobalArray());
844 auto lambdaF = ptg->getNodeForLambda(test.
LambdaF());
845 auto lambdaG = ptg->getNodeForLambda(test.
LambdaG());
850 EXPECT_TRUE(
EscapedIsExactly(*ptg, { globalArray, localArray, lambdaF, lambdaG }));
853 TEST(AndersenTests, TestLinkedList)
858 EXPECT_EQ(ptg->numAllocaNodes(), 1u);
859 EXPECT_EQ(ptg->numDeltaNodes(), 1u);
860 EXPECT_EQ(ptg->numLambdaNodes(), 1u);
862 auto allocaNode = ptg->getNodeForAlloca(test.
GetAlloca());
863 auto deltaMyListNode = ptg->getNodeForDelta(test.
GetDeltaMyList());
864 auto lambdaNextNode = ptg->getNodeForLambda(test.
GetLambdaNext());
865 auto externalMemoryNode = ptg->getExternalMemoryNode();
868 TargetsExactly(*ptg, allocaNode, { deltaMyListNode, lambdaNextNode, externalMemoryNode }));
872 { deltaMyListNode, lambdaNextNode, externalMemoryNode }));
875 TEST(AndersenTests, TestStatistics)
891 EXPECT_EQ(statistics.GetMeasurementValue<uint64_t>(
"#StoreConstraints"), 0u);
892 EXPECT_EQ(statistics.GetMeasurementValue<uint64_t>(
"#LoadConstraints"), 1u);
893 EXPECT_EQ(statistics.GetMeasurementValue<uint64_t>(
"#PointsToGraphNodes"), ptg->numNodes());
894 EXPECT_GT(statistics.GetTimerElapsedNanoseconds(
"AnalysisTimer"), 0u);
897 TEST(AndersenTests, TestConfiguration)
903 config.EnableOfflineVariableSubstitution(
false);
904 config.EnableOfflineConstraintNormalization(
true);
908 auto configString = config.ToString();
911 EXPECT_FALSE(config.IsOfflineVariableSubstitutionEnabled());
912 EXPECT_TRUE(config.IsOfflineConstraintNormalizationEnabled());
914 EXPECT_EQ(configString.find(
"OVS"), std::string::npos);
915 EXPECT_NE(configString.find(
"NORM"), std::string::npos);
916 EXPECT_NE(configString.find(
"Solver=Naive"), std::string::npos);
921 config.SetWorklistSolverPolicy(policy);
922 config.EnableOfflineVariableSubstitution(
false);
923 config.EnableOnlineCycleDetection(
true);
926 configString = config.ToString();
929 EXPECT_NE(configString.find(
"Solver=Worklist"), std::string::npos);
930 EXPECT_NE(configString.find(
"Policy=TwoPhaseLeastRecentlyFired"), std::string::npos);
931 EXPECT_EQ(configString.find(
"OVS"), std::string::npos);
932 EXPECT_NE(configString.find(
"OnlineCD"), std::string::npos);
935 config.EnableOnlineCycleDetection(
false);
936 config.EnableHybridCycleDetection(
true);
939 configString = config.ToString();
942 EXPECT_EQ(configString.find(
"OnlineCD"), std::string::npos);
943 EXPECT_NE(configString.find(
"HybridCD"), std::string::npos);
946 TEST(AndersenTests, TestConstructPointsToGraph)
993 auto allocaNode = ptg->getNodeForAlloca(rvsdg.
GetAllocaNode());
997 auto lambdaNode = ptg->getNodeForLambda(rvsdg.
GetLambdaNode());
999 auto mallocNode = ptg->getNodeForMalloc(rvsdg.
GetMallocNode());
1001 auto deltaNode = ptg->getNodeForDelta(rvsdg.
GetDeltaNode());
1002 auto deltaRNode = ptg->getNodeForRegister(rvsdg.
GetDeltaOutput());
1004 auto externalMemory = ptg->getExternalMemoryNode();
1008 EXPECT_TRUE(
TargetsExactly(*ptg, allocaRNode, { allocaNode, importNode }));
1010 EXPECT_EQ(allocaRNode, importRNode);
1012 EXPECT_EQ(allocaRNode, deltaRNode);
1020 TargetsExactly(*ptg, mallocRNode, { mallocNode, deltaNode, importNode, externalMemory }));
1027 EXPECT_NE(lambdaRNode, mallocNode);
1032 EXPECT_TRUE(ptg->isExternallyAvailable(deltaNode));
1033 EXPECT_TRUE(ptg->isTargetingAllExternallyAvailable(deltaNode));
1034 EXPECT_TRUE(
TargetsExactly(*ptg, deltaNode, { deltaNode, importNode, externalMemory }));
1038 EXPECT_TRUE(ptg->isExternallyAvailable(importNode));
1039 EXPECT_TRUE(ptg->isTargetingAllExternallyAvailable(importNode));
1040 EXPECT_TRUE(
TargetsExactly(*ptg, importNode, { deltaNode, importNode, externalMemory }));
1044 EXPECT_FALSE(ptg->isTargetingAllExternallyAvailable(lambdaNode));
1045 EXPECT_FALSE(ptg->isExternallyAvailable(lambdaNode));
1050 EXPECT_EQ(ptg->getExplicitTargets(externalMemory).Size(), 0u);
1051 EXPECT_TRUE(
TargetsExactly(*ptg, externalMemory, { deltaNode, importNode, externalMemory }));
1055 unsigned int expectedNumNodes = 5 * 2 + 1 - 2;
1056 EXPECT_EQ(ptg->numNodes(), expectedNumNodes);
1059 auto [numExplicitEdges, numTotalEdges] = ptg->numEdges();
1060 unsigned int expectedNumExplicitEdges = 2 + 1 + 1 + 1 + 1;
1061 EXPECT_EQ(numExplicitEdges, expectedNumExplicitEdges);
1063 unsigned int expectedNumTotalEdges = 2 + 1 + 4 + 1 + 1 + 3 + 3 + 0 + 3;
1064 EXPECT_EQ(numTotalEdges, expectedNumTotalEdges);
static bool TargetsExactly(const jlm::llvm::aa::PointsToGraph &pointsToGraph, const jlm::llvm::aa::PointsToGraph::NodeIndex ptgNode, const std::unordered_set< jlm::llvm::aa::PointsToGraph::NodeIndex > &expectedTargets)
Checks that the given PointsToGraph node points to exactly the given set of target nodes.
TEST(AndersenTests, TestStore1)
static bool EscapedIsExactly(const jlm::llvm::aa::PointsToGraph &pointsToGraph, const std::unordered_set< jlm::llvm::aa::PointsToGraph::NodeIndex > &nodes)
Checks that the set of Memory Nodes escaping the PointsToGraph is exactly equal to the given set of n...
static std::unique_ptr< jlm::llvm::aa::PointsToGraph > RunAndersen(jlm::llvm::LlvmRvsdgModule &module)
static jlm::util::StatisticsCollector statisticsCollector
RVSDG module with one of each memory node type.
const rvsdg::SimpleNode & GetAllocaNode() const noexcept
const rvsdg::Output & GetLambdaOutput() const noexcept
const jlm::rvsdg::LambdaNode & GetLambdaNode() const noexcept
const jlm::rvsdg::Output & GetAllocaOutput() const noexcept
const rvsdg::Output & GetDeltaOutput() const noexcept
const llvm::LlvmGraphImport & GetImportOutput() const noexcept
const rvsdg::SimpleNode & GetMallocNode() const noexcept
const jlm::rvsdg::DeltaNode & GetDeltaNode() const noexcept
const jlm::rvsdg::Output & GetMallocOutput() const noexcept
jlm::rvsdg::LambdaNode * lambda
const jlm::rvsdg::LambdaNode & GetLambdaTest() const noexcept
const rvsdg::Node & GetBitsToPtrNode() const noexcept
const rvsdg::SimpleNode & GetCallNode() const noexcept
rvsdg::SimpleNode * alloca_y
rvsdg::SimpleNode * alloca_z
jlm::rvsdg::LambdaNode * lambda_g
jlm::rvsdg::LambdaNode * lambda_f
rvsdg::SimpleNode * alloca_x
jlm::rvsdg::LambdaNode * lambda_h
jlm::rvsdg::LambdaNode * lambda_test
const rvsdg::SimpleNode & CallCreate2() const noexcept
jlm::rvsdg::LambdaNode * lambda_create
jlm::rvsdg::LambdaNode * lambda_destroy
const rvsdg::SimpleNode & CallCreate1() const noexcept
rvsdg::SimpleNode * malloc
ConstantPointerNullTest class.
jlm::rvsdg::LambdaNode * lambda
rvsdg::Node * constantPointerNullNode
jlm::rvsdg::DeltaNode * delta_f
jlm::rvsdg::LambdaNode * lambda_h
jlm::rvsdg::LambdaNode * lambda_g
jlm::rvsdg::LambdaNode * lambda_f2
jlm::rvsdg::LambdaNode * lambda_f1
jlm::rvsdg::DeltaNode * delta_d2
jlm::rvsdg::DeltaNode * delta_d1
EscapedMemoryTest1 class.
jlm::rvsdg::DeltaNode * DeltaX
jlm::rvsdg::DeltaNode * DeltaA
jlm::rvsdg::DeltaNode * DeltaB
jlm::rvsdg::LambdaNode * LambdaTest
rvsdg::SimpleNode * LoadNode1
jlm::rvsdg::DeltaNode * DeltaY
EscapedMemoryTest2 class.
jlm::rvsdg::LambdaNode * CallExternalFunction2
rvsdg::SimpleNode * ReturnAddressMalloc
jlm::rvsdg::LambdaNode * CallExternalFunction1
rvsdg::SimpleNode * ExternalFunction2Call
jlm::rvsdg::LambdaNode * ReturnAddressFunction
jlm::rvsdg::GraphImport * ExternalFunction1Import
jlm::rvsdg::GraphImport * ExternalFunction2Import
rvsdg::SimpleNode * CallExternalFunction1Malloc
EscapedMemoryTest3 class.
rvsdg::SimpleNode * CallExternalFunction
jlm::rvsdg::GraphImport * ImportExternalFunction
jlm::rvsdg::DeltaNode * DeltaGlobal
jlm::rvsdg::LambdaNode * LambdaTest
const jlm::rvsdg::GraphImport & ExternalGArgument() const noexcept
const jlm::rvsdg::LambdaNode & LambdaF() const noexcept
const rvsdg::SimpleNode & CallG() const noexcept
ExternalMemoryTest class.
jlm::rvsdg::LambdaNode * LambdaF
jlm::rvsdg::LambdaNode * lambda
rvsdg::Node * getElementPtrX
rvsdg::Node * getElementPtrY
jlm::rvsdg::LambdaNode * lambda
jlm::rvsdg::LambdaNode * lambda_f1
jlm::rvsdg::LambdaNode * lambda_f2
jlm::rvsdg::GraphImport * import_d2
jlm::rvsdg::GraphImport * import_d1
const jlm::rvsdg::LambdaNode & GetLambdaTest() const noexcept
const jlm::rvsdg::LambdaNode & GetLambdaIndcall() const noexcept
const jlm::rvsdg::LambdaNode & GetLambdaFour() const noexcept
const jlm::rvsdg::LambdaNode & GetLambdaThree() const noexcept
jlm::rvsdg::LambdaNode & GetLambdaFour() const noexcept
jlm::rvsdg::LambdaNode & GetLambdaThree() const noexcept
const jlm::rvsdg::DeltaNode & GetDeltaMyList() const noexcept
const rvsdg::SimpleNode & GetAlloca() const noexcept
const jlm::rvsdg::LambdaNode & GetLambdaNext() const noexcept
const jlm::rvsdg::LambdaNode & Lambda() const noexcept
const rvsdg::Node * UndefValueNode() const noexcept
jlm::rvsdg::LambdaNode * lambda
rvsdg::SimpleNode * load_a
rvsdg::SimpleNode * alloca_p
jlm::rvsdg::LambdaNode * lambda
rvsdg::SimpleNode * alloca_y
rvsdg::SimpleNode * load_x
rvsdg::SimpleNode * alloca_a
rvsdg::SimpleNode * alloca_x
rvsdg::SimpleNode * alloca_b
const jlm::rvsdg::DeltaNode & LocalArray() const noexcept
const jlm::rvsdg::DeltaNode & GlobalArray() const noexcept
const jlm::rvsdg::LambdaNode & LambdaF() const noexcept
const jlm::rvsdg::LambdaNode & LambdaG() const noexcept
const rvsdg::SimpleNode & Memcpy() const noexcept
rvsdg::SimpleNode * alloca
jlm::rvsdg::LambdaNode * lambda_test
jlm::rvsdg::LambdaNode * lambda_fib
jlm::rvsdg::PhiNode * phi
jlm::llvm::LlvmRvsdgModule & module()
rvsdg::SimpleNode * alloca_c
rvsdg::SimpleNode * alloca_a
rvsdg::SimpleNode * alloca_d
jlm::rvsdg::LambdaNode * lambda
rvsdg::SimpleNode * alloca_b
rvsdg::SimpleNode * alloca_p
jlm::rvsdg::LambdaNode * lambda
rvsdg::SimpleNode * alloca_y
rvsdg::SimpleNode * alloca_x
rvsdg::SimpleNode * alloca_b
rvsdg::SimpleNode * alloca_a
jlm::rvsdg::LambdaNode * lambda
jlm::rvsdg::ThetaNode * theta
static Configuration NaiveSolverConfiguration() noexcept
static std::unique_ptr< PointsToGraph > ConstructPointsToGraphFromPointerObjectSet(const PointerObjectSet &set, Statistics &statistics)
std::unique_ptr< PointsToGraph > Analyze(const rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
@ TwoPhaseLeastRecentlyFired
PointerObjectIndex CreateMallocMemoryObject(const rvsdg::SimpleNode &mallocNode, bool canPoint)
PointerObjectIndex UnifyPointerObjects(PointerObjectIndex object1, PointerObjectIndex object2)
PointerObjectIndex CreateDummyRegisterPointerObject()
PointerObjectIndex CreateGlobalMemoryObject(const rvsdg::DeltaNode &deltaNode, bool canPoint)
void MapRegisterToExistingPointerObject(const rvsdg::Output &rvsdgOutput, PointerObjectIndex pointerObject)
PointerObjectIndex CreateRegisterPointerObject(const rvsdg::Output &rvsdgOutput)
bool AddToPointsToSet(PointerObjectIndex pointer, PointerObjectIndex pointee)
PointerObjectIndex CreateAllocaMemoryObject(const rvsdg::SimpleNode &allocaNode, bool canPoint)
bool MarkAsPointingToExternal(PointerObjectIndex index)
PointerObjectIndex CreateFunctionMemoryObject(const rvsdg::LambdaNode &lambdaNode)
PointerObjectIndex CreateImportMemoryObject(const LlvmGraphImport &importNode, bool canPoint)
bool MarkAsEscaped(PointerObjectIndex index)
const util::HashSet< NodeIndex > & getExplicitTargets(NodeIndex index) const
bool isTargetingAllExternallyAvailable(NodeIndex index) const
const std::vector< NodeIndex > & getExternallyAvailableNodes() const noexcept
NodeIndex getExternalMemoryNode() const noexcept
rvsdg::Output & output() const noexcept
std::vector< ExitVar > GetExitVars() const
Gets all exit variables for this gamma.
std::vector< EntryVar > GetEntryVars() const
Gets all entry variables for this gamma.
std::vector< rvsdg::Output * > GetFunctionArguments() const
rvsdg::Output * output() const noexcept
std::vector< ContextVar > GetContextVars() const noexcept
Gets all bound context variables.
NodeOutput * output(size_t index) const noexcept
std::vector< FixVar > GetFixVars() const noexcept
Gets all fixpoint variables.
NodeInput * input(size_t index) const noexcept
NodeOutput * output(size_t index) const noexcept
StructuralOutput * output(size_t index) const noexcept
std::vector< LoopVar > GetLoopVars() const
Returns all loop variables.
bool insert(ItemType item)
StatisticsRange CollectedStatistics() const noexcept
size_t NumCollectedStatistics() const noexcept
Global memory state passed between functions.