31TEST(LoopStrengthReductionTests, SimpleArithmeticCandidateOperation)
40 const auto memoryStateType = MemoryStateType::Create();
43 auto & graph = rvsdgModule.
Rvsdg();
47 const auto & c0 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 0);
50 const auto memoryState = theta->AddLoopVar(mem);
51 const auto lv1 = theta->AddLoopVar(c0.output(0));
53 const auto &
c2 = IntegerConstantOperation::Create(*theta->subregion(), 32, 2);
56 const auto & c3 = IntegerConstantOperation::Create(*theta->subregion(), 32, 3);
61 { mulNode.output(0), memoryState.pre },
64 const auto & c5 = IntegerConstantOperation::Create(*theta->subregion(), 32, 5);
68 const auto matchResult =
71 theta->set_predicate(matchResult);
72 lv1.post->divert_to(addNode.output(0));
73 memoryState.post->divert_to(testOperation->output(0));
80 const auto numLoopVarsBefore = theta->GetLoopVars().size();
88 const auto numLoopVarsAfter = theta->GetLoopVars().size();
93 EXPECT_EQ(numLoopVarsAfter, numLoopVarsBefore + 1);
95 auto newIV = theta->GetLoopVars()[numLoopVarsAfter - 1];
98 const auto & IVInputNode =
101 const auto & constantOperation =
103 EXPECT_NE(constantOperation,
nullptr);
104 EXPECT_EQ(constantOperation->Representation().to_uint(), 0u);
107 const auto & IVPostOrigin =
112 EXPECT_EQ(IVPostOrigin->input(0)->origin(), newIV.pre);
115 const auto & addRhsInputNode =
118 const auto & rhsConstantOperation =
120 EXPECT_NE(rhsConstantOperation,
nullptr);
121 EXPECT_EQ(rhsConstantOperation->Representation().to_uint(), 6u);
124 EXPECT_EQ(testOperation->input(0)->origin(), newIV.pre);
127TEST(LoopStrengthReductionTests, CandidateOperationDependentOnInvalidInductionVariable)
135 const auto memoryStateType = MemoryStateType::Create();
138 auto & graph = rvsdgModule.
Rvsdg();
142 const auto & c0 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 0);
145 const auto memoryState = theta->AddLoopVar(mem);
146 const auto lv1 = theta->AddLoopVar(c0.output(0));
148 const auto &
c2 = IntegerConstantOperation::Create(*theta->subregion(), 32, 2);
151 const auto & c3 = IntegerConstantOperation::Create(*theta->subregion(), 32, 3);
156 { mulNode2.output(0), memoryState.pre },
157 { memoryStateType });
159 const auto & c5 = IntegerConstantOperation::Create(*theta->subregion(), 32, 5);
163 const auto matchResult =
166 theta->set_predicate(matchResult);
167 lv1.post->divert_to(mulNode1.output(0));
168 memoryState.post->divert_to(testOperation->output(0));
175 const auto numLoopVarsBefore = theta->GetLoopVars().size();
183 const auto numLoopVarsAfter = theta->GetLoopVars().size();
188 EXPECT_EQ(numLoopVarsAfter, numLoopVarsBefore);
191 EXPECT_EQ(testOperation->input(0)->origin(), mulNode2.output(0));
194TEST(LoopStrengthReductionTests, NestedArithmeticCandidateOperation)
206 const auto memoryStateType = MemoryStateType::Create();
209 auto & graph = rvsdgModule.
Rvsdg();
213 const auto & c0 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 0);
216 const auto memoryState = theta->AddLoopVar(mem);
217 const auto lv1 = theta->AddLoopVar(c0.output(0));
219 const auto &
c2 = IntegerConstantOperation::Create(*theta->subregion(), 32, 2);
222 const auto & c3 = IntegerConstantOperation::Create(*theta->subregion(), 32, 3);
225 const auto &
c1 = IntegerConstantOperation::Create(*theta->subregion(), 32, 1);
231 { addNode2.output(0), memoryState.pre },
232 { memoryStateType });
234 const auto & c5 = IntegerConstantOperation::Create(*theta->subregion(), 32, 5);
238 const auto matchResult =
241 theta->set_predicate(matchResult);
242 lv1.post->divert_to(addNode1.output(0));
243 memoryState.post->divert_to(testOperation->output(0));
250 const auto numLoopVarsBefore = theta->GetLoopVars().size();
258 const auto numLoopVarsAfter = theta->GetLoopVars().size();
263 EXPECT_EQ(numLoopVarsAfter, numLoopVarsBefore + 1);
265 auto newIV = theta->GetLoopVars()[numLoopVarsAfter - 1];
268 const auto & IVInputNode =
271 const auto & constantOperation =
273 EXPECT_NE(constantOperation,
nullptr);
274 EXPECT_EQ(constantOperation->Representation().to_uint(), 1u);
277 const auto & IVPostOrigin =
281 EXPECT_EQ(IVPostOrigin->input(0)->origin(), newIV.pre);
283 const auto & addRhsInputNode =
286 const auto & rhsConstantOperation =
288 EXPECT_NE(rhsConstantOperation,
nullptr);
289 EXPECT_EQ(rhsConstantOperation->Representation().to_uint(), 6u);
292 EXPECT_EQ(testOperation->input(0)->origin(), newIV.pre);
295TEST(LoopStrengthReductionTests, NestedArithmeticCandidateOperationWithUsersForBoth)
305 const auto memoryStateType = MemoryStateType::Create();
308 auto & graph = rvsdgModule.
Rvsdg();
312 const auto & c0 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 0);
315 const auto memoryState = theta->AddLoopVar(mem);
316 const auto lv1 = theta->AddLoopVar(c0.output(0));
318 const auto &
c2 = IntegerConstantOperation::Create(*theta->subregion(), 32, 2);
321 const auto & c3 = IntegerConstantOperation::Create(*theta->subregion(), 32, 3);
324 const auto &
c1 = IntegerConstantOperation::Create(*theta->subregion(), 32, 1);
330 { mulNode.output(0), memoryState.pre },
331 { memoryStateType });
335 { addNode2.output(0), testOperation1->output(0) },
336 { memoryStateType });
338 const auto & c5 = IntegerConstantOperation::Create(*theta->subregion(), 32, 5);
342 const auto matchResult =
345 theta->set_predicate(matchResult);
346 lv1.post->divert_to(addNode1.output(0));
347 memoryState.post->divert_to(testOperation2->output(0));
354 const auto numLoopVarsBefore = theta->GetLoopVars().size();
362 const auto numLoopVarsAfter = theta->GetLoopVars().size();
367 EXPECT_EQ(numLoopVarsAfter, numLoopVarsBefore + 2);
369 auto newIV1 = theta->GetLoopVars()[numLoopVarsAfter - 1];
370 auto newIV2 = theta->GetLoopVars()[numLoopVarsAfter - 2];
373 const auto & IV1InputNode =
376 auto constantOperation1 =
378 EXPECT_NE(constantOperation1,
nullptr);
379 EXPECT_EQ(constantOperation1->Representation().to_uint(), 1u);
381 const auto & IV2InputNode =
384 auto constantOperation2 =
386 EXPECT_NE(constantOperation2,
nullptr);
387 EXPECT_EQ(constantOperation2->Representation().to_uint(), 0u);
390 const auto & IV1PostOrigin =
394 EXPECT_EQ(IV1PostOrigin->input(0)->origin(), newIV1.pre);
396 const auto & addRhsInputNode1 =
399 const auto & rhsConstantOperation1 =
401 EXPECT_NE(rhsConstantOperation1,
nullptr);
402 EXPECT_EQ(rhsConstantOperation1->Representation().to_uint(), 6u);
404 const auto & IV2PostOrigin =
408 EXPECT_EQ(IV2PostOrigin->input(0)->origin(), newIV2.pre);
410 const auto & addRhsInputNode2 =
413 const auto & rhsConstantOperation2 =
415 EXPECT_NE(rhsConstantOperation2,
nullptr);
416 EXPECT_EQ(rhsConstantOperation2->Representation().to_uint(), 6u);
419 EXPECT_EQ(testOperation1->input(0)->origin(), newIV2.pre);
420 EXPECT_EQ(testOperation2->input(0)->origin(), newIV1.pre);
423TEST(LoopStrengthReductionTests, SimpleGEPCandidateOperation)
433 const auto intArrayType = ArrayType::Create(intType, 5);
434 const auto pointerType = PointerType::Create();
435 const auto memoryStateType = MemoryStateType::Create();
438 auto & graph = rvsdgModule.
Rvsdg();
443 const auto & c0_1 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 0);
446 const auto memoryState = theta->AddLoopVar(mem);
447 const auto lv1 = theta->AddLoopVar(c0_1.output(0));
448 const auto lv2 = theta->AddLoopVar(arrPtr);
450 const auto &
c2 = IntegerConstantOperation::Create(*theta->subregion(), 32, 2);
453 const auto & c3 = IntegerConstantOperation::Create(*theta->subregion(), 32, 3);
456 auto & sExtNode = SExtOperation::create(64, *mulNode.output(0));
458 const auto & c0_2 = IntegerConstantOperation::Create(*theta->subregion(), 64, 0);
460 GetElementPtrOperation::create(lv2.pre, { c0_2.output(0), &sExtNode }, intArrayType);
462 auto loadOutputs = LoadNonVolatileOperation::Create(gep, { memoryState.pre }, intType, 32);
467 StoreNonVolatileOperation::Create(gep, subNode.output(0), { loadOutputs[1] }, 4);
468 const auto & c5 = IntegerConstantOperation::Create(*theta->subregion(), 32, 5);
472 const auto matchResult =
475 lv1.post->divert_to(addNode1.output(0));
476 memoryState.post->divert_to(storeOutputs[0]);
477 theta->set_predicate(matchResult);
484 const auto numLoopVarsBefore = theta->GetLoopVars().size();
486 std::vector<jlm::rvsdg::Input *> oldGepNodeUsers;
494 const auto numLoopVarsAfter = theta->GetLoopVars().size();
499 EXPECT_EQ(numLoopVarsAfter, numLoopVarsBefore + 1);
500 auto newIV = theta->GetLoopVars()[numLoopVarsAfter - 1];
503 const auto & IVPostOrigin =
506 const auto & gepOperation =
508 EXPECT_NE(gepOperation,
nullptr);
512 EXPECT_EQ(IVPostOrigin->input(0)->origin(), newIV.pre);
514 const auto & gepIndexInputNode =
517 const auto & constantOperation =
519 EXPECT_NE(constantOperation,
nullptr);
520 EXPECT_EQ(constantOperation->Representation().nbits(), 64u);
521 EXPECT_EQ(constantOperation->Representation().to_uint(), 24u);
525 EXPECT_NE(loadNode,
nullptr);
527 EXPECT_EQ(LoadOperation::AddressInput(*loadNode).origin(), newIV.pre);
530 EXPECT_NE(storeNode,
nullptr);
532 EXPECT_EQ(StoreOperation::AddressInput(*storeNode).origin(), newIV.pre);
535TEST(LoopStrengthReductionTests, GEPCandidateOperationWithNAryStart)
546 const auto intArrayType = ArrayType::Create(intType, 5);
547 const auto pointerType = PointerType::Create();
548 const auto memoryStateType = MemoryStateType::Create();
551 auto & graph = rvsdgModule.
Rvsdg();
556 const auto & c0_1 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 0);
559 const auto memoryState = theta->AddLoopVar(mem);
560 const auto lv1 = theta->AddLoopVar(c0_1.output(0));
561 const auto lv2 = theta->AddLoopVar(arrPtr);
563 const auto &
c2 = IntegerConstantOperation::Create(*theta->subregion(), 32, 2);
566 const auto & c3 = IntegerConstantOperation::Create(*theta->subregion(), 32, 3);
568 const auto & c4 = IntegerConstantOperation::Create(*theta->subregion(), 32, 4);
572 auto & sExtNode = SExtOperation::create(64, *addNode2.output(0));
574 const auto & c0_2 = IntegerConstantOperation::Create(*theta->subregion(), 64, 0);
576 GetElementPtrOperation::create(lv2.pre, { c0_2.output(0), &sExtNode }, intArrayType);
578 const auto & c10 = IntegerConstantOperation::Create(*theta->subregion(), 32, 10);
580 auto storeOutputs = StoreNonVolatileOperation::Create(gep, c10.output(0), { memoryState.pre }, 4);
581 const auto & c5 = IntegerConstantOperation::Create(*theta->subregion(), 32, 5);
585 const auto matchResult =
588 lv1.post->divert_to(addNode1.output(0));
589 memoryState.post->divert_to(storeOutputs[0]);
590 theta->set_predicate(matchResult);
597 const auto numLoopVarsBefore = theta->GetLoopVars().size();
599 std::vector<jlm::rvsdg::Input *> oldGepNodeUsers;
607 const auto numLoopVarsAfter = theta->GetLoopVars().size();
612 EXPECT_EQ(numLoopVarsAfter, numLoopVarsBefore + 1);
613 auto newIV = theta->GetLoopVars()[numLoopVarsAfter - 1];
617 const auto & newIVInputNode =
620 auto lhs = newIVInputNode->input(0)->origin();
621 auto rhs = newIVInputNode->input(1)->origin();
622 EXPECT_EQ(lhs, arrPtr);
625 const auto & constantOperation =
627 EXPECT_NE(constantOperation,
nullptr);
628 EXPECT_EQ(constantOperation->Representation().to_uint(), 16u);
631 const auto & IVPostOrigin =
634 const auto & stepGepOperation =
636 EXPECT_NE(stepGepOperation,
nullptr);
641 const auto & gepIndexInputNode =
644 const auto & indexConstantOperation =
646 EXPECT_NE(indexConstantOperation,
nullptr);
647 EXPECT_EQ(indexConstantOperation->Representation().nbits(), 64u);
648 EXPECT_EQ(indexConstantOperation->Representation().to_uint(), 24u);
652 EXPECT_NE(storeNode,
nullptr);
654 EXPECT_EQ(StoreOperation::AddressInput(*storeNode).origin(), newIV.pre);
657TEST(LoopStrengthReductionTests, CandidateOperationInNestedLoopTest)
666 const auto memoryStateType = MemoryStateType::Create();
669 auto & graph = rvsdgModule.
Rvsdg();
673 const auto & c0 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 0);
676 const auto memoryState1 = theta1->AddLoopVar(mem);
677 const auto lv1_1 = theta1->AddLoopVar(c0.output(0));
679 const auto &
c1 = IntegerConstantOperation::Create(*theta1->subregion(), 32, 1);
682 const auto & c5 = IntegerConstantOperation::Create(*theta1->subregion(), 32, 5);
685 const auto matchResult1 =
688 theta1->set_predicate(matchResult1);
689 lv1_1.post->divert_to(addNode1.output(0));
693 const auto lv1_2 = theta2->AddLoopVar(lv1_1.pre);
694 const auto lv2 = theta2->AddLoopVar(
c1.output(0));
695 const auto memoryState2 = theta2->AddLoopVar(memoryState1.pre);
697 const auto &
c2 = IntegerConstantOperation::Create(*theta2->subregion(), 32, 2);
700 const auto & c3 = IntegerConstantOperation::Create(*theta2->subregion(), 32, 3);
703 const auto & c10 = IntegerConstantOperation::Create(*theta2->subregion(), 32, 10);
706 const auto matchResult2 =
711 { mulNode.output(0), memoryState2.pre },
712 { memoryStateType });
714 theta2->set_predicate(matchResult2);
715 lv2.post->divert_to(addNode2.output(0));
716 memoryState2.post->divert_to(testOperation->output(0));
718 memoryState1.post->divert_to(memoryState2.output);
724 const auto outerNumLoopVarsBefore = theta1->GetLoopVars().size();
725 const auto innerNumLoopVarsBefore = theta2->GetLoopVars().size();
733 const auto outerNumLoopVarsAfter = theta1->GetLoopVars().size();
734 const auto innerNumLoopVarsAfter = theta2->GetLoopVars().size();
739 EXPECT_EQ(outerNumLoopVarsAfter, outerNumLoopVarsBefore + 1);
740 EXPECT_EQ(innerNumLoopVarsAfter, innerNumLoopVarsBefore + 1);
742 auto outerNewIV = theta1->GetLoopVars()[outerNumLoopVarsAfter - 1];
743 auto innerNewIV = theta2->GetLoopVars()[innerNumLoopVarsAfter - 1];
746 const auto & outerIVInputNode =
749 const auto & constantOperation =
751 EXPECT_NE(constantOperation,
nullptr);
752 EXPECT_EQ(constantOperation->Representation().to_uint(), 0u);
755 const auto & outerIVPostOrigin =
759 EXPECT_EQ(outerIVPostOrigin->input(0)->origin(), outerNewIV.pre);
761 const auto & addRhsInputNode =
764 const auto & rhsConstantOperation =
766 EXPECT_NE(rhsConstantOperation,
nullptr);
767 EXPECT_EQ(rhsConstantOperation->Representation().to_uint(), 3u);
770 EXPECT_EQ(innerNewIV.input->origin(), outerNewIV.pre);
772 EXPECT_EQ(innerNewIV.post->origin(), innerNewIV.pre);
775 EXPECT_EQ(testOperation->input(0)->origin(), innerNewIV.pre);
778TEST(LoopStrengthReductionTests, CandidateOperationInNestedLoopWithGammaTest)
787 const auto memoryStateType = MemoryStateType::Create();
791 auto & graph = rvsdgModule.
Rvsdg();
797 const auto & c0 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 0);
798 auto ev1 = gamma1->AddEntryVar(c0.output(0));
799 auto mem1 = gamma1->AddEntryVar(m);
803 const auto memoryState1 = theta1->AddLoopVar(mem1.branchArgument[1]);
804 const auto lv1_1 = theta1->AddLoopVar(ev1.branchArgument[1]);
806 const auto &
c1 = IntegerConstantOperation::Create(*theta1->subregion(), 32, 1);
809 const auto & c5 = IntegerConstantOperation::Create(*theta1->subregion(), 32, 5);
812 const auto matchResult1 =
815 theta1->set_predicate(matchResult1);
816 lv1_1.post->divert_to(addNode1.output(0));
818 const auto & c10 = IntegerConstantOperation::Create(*theta1->subregion(), 32, 10);
821 const auto matchResult2 =
825 auto ev2 = gamma2->AddEntryVar(
c1.output(0));
826 auto mem2 = gamma2->AddEntryVar(memoryState1.pre);
827 auto ev3 = gamma2->AddEntryVar(lv1_1.pre);
831 const auto lv2 = theta2->AddLoopVar(ev2.branchArgument[1]);
832 const auto lv1_2 = theta2->AddLoopVar(ev3.branchArgument[1]);
833 const auto memoryState2 = theta2->AddLoopVar(mem2.branchArgument[1]);
835 const auto &
c2 = IntegerConstantOperation::Create(*theta2->subregion(), 32, 2);
838 const auto & c3 = IntegerConstantOperation::Create(*theta2->subregion(), 32, 3);
841 const auto & c10_2 = IntegerConstantOperation::Create(*theta2->subregion(), 32, 10);
844 const auto matchResult3 =
849 { mulNode.output(0), memoryState2.pre },
850 { memoryStateType });
852 theta2->set_predicate(matchResult3);
853 lv2.post->divert_to(addNode2.output(0));
854 memoryState2.post->divert_to(testOperation->output(0));
856 auto exitVar1 = gamma2->AddExitVar({ mem2.branchArgument[0], memoryState2.output });
857 memoryState1.post->divert_to(exitVar1.output);
858 auto exitVar2 = gamma1->AddExitVar({ mem1.branchArgument[0], memoryState1.output });
865 const auto outerNumLoopVarsBefore = theta1->GetLoopVars().size();
866 const auto innerNumLoopVarsBefore = theta2->GetLoopVars().size();
868 const auto outerNumEntryVarsBefore = gamma1->GetEntryVars().size();
869 const auto innerNumEntryVarsBefore = gamma2->GetEntryVars().size();
877 const auto outerNumLoopVarsAfter = theta1->GetLoopVars().size();
878 const auto innerNumLoopVarsAfter = theta2->GetLoopVars().size();
880 const auto outerNumEntryVarsAfter = gamma1->GetEntryVars().size();
881 const auto innerNumEntryVarsAfter = gamma2->GetEntryVars().size();
886 EXPECT_EQ(outerNumLoopVarsAfter, outerNumLoopVarsBefore + 1);
887 EXPECT_EQ(innerNumLoopVarsAfter, innerNumLoopVarsBefore + 1);
890 EXPECT_EQ(innerNumEntryVarsAfter, innerNumEntryVarsBefore + 1);
891 EXPECT_EQ(outerNumEntryVarsAfter, outerNumEntryVarsBefore);
893 auto outerNewIV = theta1->GetLoopVars()[outerNumLoopVarsAfter - 1];
894 auto innerNewIV = theta2->GetLoopVars()[innerNumLoopVarsAfter - 1];
897 const auto & outerIVInputNode =
900 const auto & constantOperation =
902 EXPECT_NE(constantOperation,
nullptr);
903 EXPECT_EQ(constantOperation->Representation().to_uint(), 0u);
906 const auto & outerIVPostOrigin =
910 EXPECT_EQ(outerIVPostOrigin->input(0)->origin(), outerNewIV.pre);
912 const auto & addRhsInputNode =
915 const auto & rhsConstantOperation =
917 EXPECT_NE(rhsConstantOperation,
nullptr);
918 EXPECT_EQ(rhsConstantOperation->Representation().to_uint(), 3u);
921 auto innerNewEV = gamma2->GetEntryVars()[innerNumEntryVarsAfter - 1];
923 EXPECT_EQ(innerNewEV.input->origin(), outerNewIV.pre);
926 EXPECT_EQ(innerNewIV.input->origin(), innerNewEV.branchArgument[1]);
929 EXPECT_EQ(innerNewIV.post->origin(), innerNewIV.pre);
932 EXPECT_EQ(testOperation->input(0)->origin(), innerNewIV.pre);
935TEST(LoopStrengthReductionTests, CandidateOperationInThreeLevelNestedLoopTest)
943 const auto memoryStateType = MemoryStateType::Create();
946 auto & graph = rvsdgModule.
Rvsdg();
950 const auto & c0 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 0);
953 const auto memoryState1 = theta1->AddLoopVar(mem);
954 const auto lv1_1 = theta1->AddLoopVar(c0.output(0));
956 const auto &
c1 = IntegerConstantOperation::Create(*theta1->subregion(), 32, 1);
959 const auto & c5 = IntegerConstantOperation::Create(*theta1->subregion(), 32, 5);
962 const auto matchResult1 =
965 theta1->set_predicate(matchResult1);
966 lv1_1.post->divert_to(addNode1.output(0));
970 const auto lv1_2 = theta2->AddLoopVar(lv1_1.pre);
971 const auto lv2 = theta2->AddLoopVar(
c1.output(0));
972 const auto memoryState2 = theta2->AddLoopVar(memoryState1.pre);
974 const auto &
c2 = IntegerConstantOperation::Create(*theta2->subregion(), 32, 2);
977 const auto & c10 = IntegerConstantOperation::Create(*theta2->subregion(), 32, 10);
980 const auto matchResult2 =
983 theta2->set_predicate(matchResult2);
984 lv2.post->divert_to(addNode2.output(0));
988 const auto lv1_3 = theta3->AddLoopVar(lv1_2.pre);
989 const auto lv3 = theta3->AddLoopVar(
c2.output(0));
990 const auto memoryState3 = theta3->AddLoopVar(memoryState2.pre);
992 const auto & c4 = IntegerConstantOperation::Create(*theta3->subregion(), 32, 4);
995 const auto & c3 = IntegerConstantOperation::Create(*theta3->subregion(), 32, 3);
998 const auto & c20 = IntegerConstantOperation::Create(*theta3->subregion(), 32, 20);
1001 const auto matchResult3 =
1005 theta3->subregion(),
1006 { mulNode.output(0), memoryState3.pre },
1007 { memoryStateType });
1009 theta3->set_predicate(matchResult3);
1010 lv3.post->divert_to(addNode3.output(0));
1011 memoryState3.post->divert_to(testOperation->output(0));
1013 lv1_2.post->divert_to(lv1_3.output);
1014 memoryState2.post->divert_to(memoryState3.output);
1016 memoryState1.post->divert_to(memoryState2.output);
1022 const auto outerNumLoopVarsBefore = theta1->GetLoopVars().size();
1023 const auto middleNumLoopVarsBefore = theta2->GetLoopVars().size();
1024 const auto innerNumLoopVarsBefore = theta3->GetLoopVars().size();
1032 const auto outerNumLoopVarsAfter = theta1->GetLoopVars().size();
1033 const auto middleNumLoopVarsAfter = theta2->GetLoopVars().size();
1034 const auto innerNumLoopVarsAfter = theta3->GetLoopVars().size();
1039 EXPECT_EQ(outerNumLoopVarsAfter, outerNumLoopVarsBefore + 1);
1040 EXPECT_EQ(middleNumLoopVarsAfter, middleNumLoopVarsBefore + 1);
1041 EXPECT_EQ(innerNumLoopVarsAfter, innerNumLoopVarsBefore + 1);
1043 auto outerNewIV = theta1->GetLoopVars()[outerNumLoopVarsAfter - 1];
1044 auto middleNewIV = theta2->GetLoopVars()[middleNumLoopVarsAfter - 1];
1045 auto innerNewIV = theta3->GetLoopVars()[innerNumLoopVarsAfter - 1];
1048 const auto & outerIVInputNode =
1051 const auto & constantOperation =
1053 EXPECT_NE(constantOperation,
nullptr);
1054 EXPECT_EQ(constantOperation->Representation().to_uint(), 0u);
1057 const auto & outerIVPostOrigin =
1061 EXPECT_EQ(outerIVPostOrigin->input(0)->origin(), outerNewIV.pre);
1063 const auto & addRhsInputNode =
1066 const auto & rhsConstantOperation =
1068 EXPECT_NE(rhsConstantOperation,
nullptr);
1069 EXPECT_EQ(rhsConstantOperation->Representation().to_uint(), 3u);
1072 EXPECT_EQ(middleNewIV.input->origin(), outerNewIV.pre);
1074 EXPECT_EQ(middleNewIV.post->origin(), middleNewIV.pre);
1077 EXPECT_EQ(innerNewIV.input->origin(), middleNewIV.pre);
1079 EXPECT_EQ(innerNewIV.post->origin(), innerNewIV.pre);
1082 EXPECT_EQ(testOperation->input(0)->origin(), innerNewIV.pre);
1085TEST(LoopStrengthReductionTests, CandidateOperationWithInitTest)
1095 const auto memoryStateType = MemoryStateType::Create();
1098 auto & graph = rvsdgModule.
Rvsdg();
1105 graph.GetRootRegion(),
1106 LlvmLambdaOperation::Create(
1109 Linkage::externalLinkage));
1110 auto cv1 = lambda->AddContextVar(*mem).inner;
1111 auto cv2 = lambda->AddContextVar(*i).inner;
1112 auto cv3 = lambda->AddContextVar(*k).inner;
1116 const auto memoryState = theta->AddLoopVar(cv1);
1117 const auto lv1 = theta->AddLoopVar(cv2);
1118 const auto lv2 = theta->AddLoopVar(cv3);
1122 const auto & c3 = IntegerConstantOperation::Create(*theta->subregion(), 32, 3);
1127 { mulNode.output(0), memoryState.pre },
1128 { memoryStateType });
1130 const auto & c5 = IntegerConstantOperation::Create(*theta->subregion(), 32, 5);
1134 const auto matchResult =
1137 theta->set_predicate(matchResult);
1138 lv1.post->divert_to(addNode.output(0));
1139 memoryState.post->divert_to(testOperation->output(0));
1141 auto res = lambda->finalize({ memoryState.output });
1148 const auto numLoopVarsBefore = theta->GetLoopVars().size();
1156 const auto numLoopVarsAfter = theta->GetLoopVars().size();
1160 EXPECT_EQ(numLoopVarsAfter, numLoopVarsBefore + 2);
1162 auto newIV1 = theta->GetLoopVars()[numLoopVarsAfter - 1];
1163 auto newIV2 = theta->GetLoopVars()[numLoopVarsAfter - 2];
1167 const auto & IV1InputNode =
1170 auto lhs1 = IV1InputNode->input(0)->origin();
1171 auto rhs1 = IV1InputNode->input(1)->origin();
1172 EXPECT_EQ(lhs1, cv2);
1175 const auto & constantOperation =
1177 EXPECT_NE(constantOperation,
nullptr);
1178 EXPECT_EQ(constantOperation->Representation().to_uint(), 3u);
1182 const auto & IV2InputNode =
1185 auto lhs2 = IV2InputNode->input(0)->origin();
1186 auto rhs2 = IV2InputNode->input(1)->origin();
1187 EXPECT_EQ(lhs2, cv3);
1190 const auto & constantOperation2 =
1192 EXPECT_NE(constantOperation2,
nullptr);
1193 EXPECT_EQ(constantOperation2->Representation().to_uint(), 3u);
1196 const auto & IV1PostOrigin =
1200 EXPECT_EQ(IV1PostOrigin->input(0)->origin(), newIV1.pre);
1202 EXPECT_EQ(IV1PostOrigin->input(1)->origin(), newIV2.pre);
1205 EXPECT_EQ(testOperation->input(0)->origin(), newIV1.pre);
1208TEST(LoopStrengthReductionTests, CandidateOperationWithInitAndTracingTest)
1224 const auto memoryStateType = MemoryStateType::Create();
1227 auto & graph = rvsdgModule.
Rvsdg();
1232 graph.GetRootRegion(),
1233 LlvmLambdaOperation::Create(
1236 Linkage::externalLinkage));
1237 auto cv1 = lambda->AddContextVar(*mem).inner;
1238 auto cv2 = lambda->AddContextVar(*a).inner;
1240 const auto & c0 = IntegerConstantOperation::Create(*lambda->subregion(), 32, 0);
1243 const auto memoryState1 = theta1->AddLoopVar(cv1);
1244 const auto lv1_1 = theta1->AddLoopVar(c0.output(0));
1245 const auto lv2_1 = theta1->AddLoopVar(cv2);
1247 const auto &
c1 = IntegerConstantOperation::Create(*theta1->subregion(), 32, 1);
1250 const auto & c5 = IntegerConstantOperation::Create(*theta1->subregion(), 32, 5);
1253 const auto matchResult1 =
1256 theta1->set_predicate(matchResult1);
1257 lv1_1.post->divert_to(addNode1.output(0));
1261 const auto lv1_2 = theta2->AddLoopVar(lv1_1.pre);
1262 const auto lv2_2 = theta2->AddLoopVar(lv2_1.pre);
1263 const auto lv3 = theta2->AddLoopVar(
c1.output(0));
1264 const auto memoryState2 = theta2->AddLoopVar(memoryState1.pre);
1266 const auto &
c2 = IntegerConstantOperation::Create(*theta2->subregion(), 32, 2);
1269 const auto & c3 = IntegerConstantOperation::Create(*theta2->subregion(), 32, 3);
1275 const auto & c10 = IntegerConstantOperation::Create(*theta2->subregion(), 32, 10);
1278 const auto matchResult2 =
1282 theta2->subregion(),
1283 { subNode.output(0), memoryState2.pre },
1284 { memoryStateType });
1286 theta2->set_predicate(matchResult2);
1287 lv3.post->divert_to(addNode2.output(0));
1288 memoryState2.post->divert_to(testOperation->output(0));
1290 memoryState1.post->divert_to(memoryState2.output);
1291 auto res = lambda->finalize({ memoryState1.output });
1297 const auto outerNumLoopVarsBefore = theta1->GetLoopVars().size();
1298 const auto innerNumLoopVarsBefore = theta2->GetLoopVars().size();
1306 const auto outerNumLoopVarsAfter = theta1->GetLoopVars().size();
1307 const auto innerNumLoopVarsAfter = theta2->GetLoopVars().size();
1312 EXPECT_EQ(outerNumLoopVarsAfter, outerNumLoopVarsBefore + 1);
1313 EXPECT_EQ(innerNumLoopVarsAfter, innerNumLoopVarsBefore + 1);
1315 auto outerNewIV = theta1->GetLoopVars()[outerNumLoopVarsAfter - 1];
1316 auto innerNewIV = theta2->GetLoopVars()[innerNumLoopVarsAfter - 1];
1320 const auto & outerIVInputNode =
1323 auto lhs = outerIVInputNode->input(0)->origin();
1324 auto rhs = outerIVInputNode->input(1)->origin();
1325 EXPECT_EQ(lhs, cv2);
1328 const auto & constantOperation =
1330 EXPECT_EQ(constantOperation->Representation().to_uint(), 3u);
1333 const auto & outerIVPostOrigin =
1337 EXPECT_EQ(outerIVPostOrigin->input(0)->origin(), outerNewIV.pre);
1339 const auto & addRhsInputNode =
1342 const auto & rhsConstantOperation =
1344 EXPECT_EQ(rhsConstantOperation->Representation().to_int(), -1);
1347 EXPECT_EQ(innerNewIV.input->origin(), outerNewIV.pre);
1349 EXPECT_EQ(innerNewIV.post->origin(), innerNewIV.pre);
1352 EXPECT_EQ(testOperation->input(0)->origin(), innerNewIV.pre);