llvm.org GIT mirror llvm / 3710416
[PM] Teach the loop PM to run LoopSimplify prior to the loop pipeline. This adds the last remaining core feature of the loop pass pipeline in the new PM and removes the last of the really egregious hacks in the LICM tests. Sadly, this requires really substantial changes in the unittests in order to provide and maintain simplified loops. This is particularly hard because for example LoopSimplify will try to fold undef branches to an ideal direction and simplify the loop accordingly. Differential Revision: https://reviews.llvm.org/D28766 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292709 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 2 years ago
6 changed file(s) with 269 addition(s) and 110 deletion(s). Raw diff Collapse all Expand all
5151 #include "llvm/IR/Dominators.h"
5252 #include "llvm/IR/PassManager.h"
5353 #include "llvm/Transforms/Utils/LCSSA.h"
54 #include "llvm/Transforms/Utils/LoopSimplify.h"
5455
5556 namespace llvm {
5657
249250 : public PassInfoMixin> {
250251 public:
251252 explicit FunctionToLoopPassAdaptor(LoopPassT Pass) : Pass(std::move(Pass)) {
253 LoopCanonicalizationFPM.addPass(LoopSimplifyPass());
252254 LoopCanonicalizationFPM.addPass(LCSSAPass());
253255 }
254256
458458 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: FunctionToLoopPassAdaptor
459459 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: LoopAnalysis
460460 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: DominatorTreeAnalysis
461 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: AssumptionAnalysis
462 ; CHECK-REPEAT-LOOP-PASS-NEXT: Invalidating all non-preserved analyses
461463 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
462464 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: AAManager
463465 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: TargetLibraryAnalysis
464 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: AssumptionAnalysis
465466 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: ScalarEvolutionAnalysis
466467 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: TargetIRAnalysis
467468 ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting Loop pass manager run
477478 ; CHECK-REPEAT-LOOP-PASS-NEXT: Finished Loop pass manager run
478479 ; CHECK-REPEAT-LOOP-PASS-NEXT: Finished Loop pass manager run
479480 ; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Function pass manager run
481 ; CHECK-REPEAT-LOOP-PASS-NEXT: Invalidating all non-preserved analyses
480482 ; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Module pass manager run
481483
482484 define void @foo(i1 %x, i8* %p1, i8* %p2) {
9393 ; CHECK-O-NEXT: Running pass: SimplifyCFGPass
9494 ; CHECK-O-NEXT: Running pass: InstCombinePass
9595 ; CHECK-O-NEXT: Running pass: FunctionToLoopPassAdaptor<{{.*}}LoopStandardAnalysisResults{{.*}}>
96 ; CHECK-O-NEXT: Invalidating analysis: ScalarEvolutionAnalysis
97 ; CHECK-O-NEXT: Running analysis: ScalarEvolutionAnalysis
9698 ; CHECK-O-NEXT: Starting Loop pass manager run.
9799 ; CHECK-O-NEXT: Finished Loop pass manager run.
98100 ; CHECK-Os-NEXT: Running pass: MergedLoadStoreMotionPass
0 ; RUN: opt -S -basicaa -licm < %s | FileCheck %s
1 ; RUN: opt -aa-pipeline=basic-aa -passes='loop-simplify,require,require,require,require,loop(simplify-cfg,licm)' -S < %s | FileCheck %s
1 ; RUN: opt -aa-pipeline=basic-aa -passes='require,loop(simplify-cfg,licm)' -S < %s | FileCheck %s
2
23 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
34 target triple = "x86_64-unknown-linux-gnu"
45
0 ; RUN: opt -S -basicaa -licm < %s | FileCheck %s
1 ; RUN: opt -aa-pipeline=basic-aa -passes='loop-simplify,require,require,require,require,loop(simplify-cfg,licm)' -S < %s | FileCheck %s
1 ; RUN: opt -aa-pipeline=basic-aa -passes='require,loop(simplify-cfg,licm)' -S < %s | FileCheck %s
2
23 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
34 target triple = "x86_64-unknown-linux-gnu"
45
243243
244244 public:
245245 LoopPassManagerTest()
246 : M(parseIR(Context, "define void @f() {\n"
247 "entry:\n"
248 " br label %loop.0\n"
249 "loop.0:\n"
250 " br i1 undef, label %loop.0.0, label %end\n"
251 "loop.0.0:\n"
252 " br i1 undef, label %loop.0.0, label %loop.0.1\n"
253 "loop.0.1:\n"
254 " br i1 undef, label %loop.0.1, label %loop.0\n"
255 "end:\n"
256 " ret void\n"
257 "}\n"
258 "\n"
259 "define void @g() {\n"
260 "entry:\n"
261 " br label %loop.g.0\n"
262 "loop.g.0:\n"
263 " br i1 undef, label %loop.g.0, label %end\n"
264 "end:\n"
265 " ret void\n"
266 "}\n")),
246 : M(parseIR(Context,
247 "define void @f(i1* %ptr) {\n"
248 "entry:\n"
249 " br label %loop.0\n"
250 "loop.0:\n"
251 " %cond.0 = load volatile i1, i1* %ptr\n"
252 " br i1 %cond.0, label %loop.0.0.ph, label %end\n"
253 "loop.0.0.ph:\n"
254 " br label %loop.0.0\n"
255 "loop.0.0:\n"
256 " %cond.0.0 = load volatile i1, i1* %ptr\n"
257 " br i1 %cond.0.0, label %loop.0.0, label %loop.0.1.ph\n"
258 "loop.0.1.ph:\n"
259 " br label %loop.0.1\n"
260 "loop.0.1:\n"
261 " %cond.0.1 = load volatile i1, i1* %ptr\n"
262 " br i1 %cond.0.1, label %loop.0.1, label %loop.0.latch\n"
263 "loop.0.latch:\n"
264 " br label %loop.0\n"
265 "end:\n"
266 " ret void\n"
267 "}\n"
268 "\n"
269 "define void @g(i1* %ptr) {\n"
270 "entry:\n"
271 " br label %loop.g.0\n"
272 "loop.g.0:\n"
273 " %cond.0 = load volatile i1, i1* %ptr\n"
274 " br i1 %cond.0, label %loop.g.0, label %end\n"
275 "end:\n"
276 " ret void\n"
277 "}\n")),
267278 LAM(true), FAM(true), MAM(true) {
268279 // Register our mock analysis.
269280 LAM.registerPass([&] { return MLAHandle.getAnalysis(); });
819830
820831 TEST_F(LoopPassManagerTest, LoopChildInsertion) {
821832 // Super boring module with three loops in a single loop nest.
822 M = parseIR(Context, "define void @f() {\n"
833 M = parseIR(Context, "define void @f(i1* %ptr) {\n"
823834 "entry:\n"
824835 " br label %loop.0\n"
825836 "loop.0:\n"
826 " br i1 undef, label %loop.0.0, label %end\n"
837 " %cond.0 = load volatile i1, i1* %ptr\n"
838 " br i1 %cond.0, label %loop.0.0.ph, label %end\n"
839 "loop.0.0.ph:\n"
840 " br label %loop.0.0\n"
827841 "loop.0.0:\n"
828 " br i1 undef, label %loop.0.0, label %loop.0.1\n"
842 " %cond.0.0 = load volatile i1, i1* %ptr\n"
843 " br i1 %cond.0.0, label %loop.0.0, label %loop.0.1.ph\n"
844 "loop.0.1.ph:\n"
845 " br label %loop.0.1\n"
829846 "loop.0.1:\n"
830 " br i1 undef, label %loop.0.1, label %loop.0.2\n"
847 " %cond.0.1 = load volatile i1, i1* %ptr\n"
848 " br i1 %cond.0.1, label %loop.0.1, label %loop.0.2.ph\n"
849 "loop.0.2.ph:\n"
850 " br label %loop.0.2\n"
831851 "loop.0.2:\n"
832 " br i1 undef, label %loop.0.2, label %loop.0\n"
852 " %cond.0.2 = load volatile i1, i1* %ptr\n"
853 " br i1 %cond.0.2, label %loop.0.2, label %loop.0.latch\n"
854 "loop.0.latch:\n"
855 " br label %loop.0\n"
833856 "end:\n"
834857 " ret void\n"
835858 "}\n");
838861 // easily.
839862 Function &F = *M->begin();
840863 ASSERT_THAT(F, HasName("f"));
864 Argument &Ptr = *F.arg_begin();
841865 auto BBI = F.begin();
842866 BasicBlock &EntryBB = *BBI++;
843867 ASSERT_THAT(EntryBB, HasName("entry"));
844868 BasicBlock &Loop0BB = *BBI++;
845869 ASSERT_THAT(Loop0BB, HasName("loop.0"));
870 BasicBlock &Loop00PHBB = *BBI++;
871 ASSERT_THAT(Loop00PHBB, HasName("loop.0.0.ph"));
846872 BasicBlock &Loop00BB = *BBI++;
847873 ASSERT_THAT(Loop00BB, HasName("loop.0.0"));
874 BasicBlock &Loop01PHBB = *BBI++;
875 ASSERT_THAT(Loop01PHBB, HasName("loop.0.1.ph"));
848876 BasicBlock &Loop01BB = *BBI++;
849877 ASSERT_THAT(Loop01BB, HasName("loop.0.1"));
878 BasicBlock &Loop02PHBB = *BBI++;
879 ASSERT_THAT(Loop02PHBB, HasName("loop.0.2.ph"));
850880 BasicBlock &Loop02BB = *BBI++;
851881 ASSERT_THAT(Loop02BB, HasName("loop.0.2"));
882 BasicBlock &Loop0LatchBB = *BBI++;
883 ASSERT_THAT(Loop0LatchBB, HasName("loop.0.latch"));
852884 BasicBlock &EndBB = *BBI++;
853885 ASSERT_THAT(EndBB, HasName("end"));
854886 ASSERT_THAT(BBI, F.end());
887 auto CreateCondBr = [&](BasicBlock *TrueBB, BasicBlock *FalseBB,
888 const char *Name, BasicBlock *BB) {
889 auto *Cond = new LoadInst(&Ptr, Name, /*isVolatile*/ true, BB);
890 BranchInst::Create(TrueBB, FalseBB, Cond, BB);
891 };
855892
856893 // Build the pass managers and register our pipeline. We build a single loop
857894 // pass pipeline consisting of three mock pass runs over each loop. After
886923
887924 // When running over the middle loop, the second run inserts two new child
888925 // loops, inserting them and itself into the worklist.
889 BasicBlock *NewLoop010BB;
926 BasicBlock *NewLoop010BB, *NewLoop01LatchBB;
890927 EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
891928 .WillOnce(Invoke([&](Loop &L, LoopAnalysisManager &AM,
892929 LoopStandardAnalysisResults &AR,
893930 LPMUpdater &Updater) {
894931 auto *NewLoop = new Loop();
895932 L.addChildLoop(NewLoop);
896 NewLoop010BB = BasicBlock::Create(Context, "loop.0.1.0", &F, &Loop02BB);
897 BranchInst::Create(&Loop01BB, NewLoop010BB,
898 UndefValue::get(Type::getInt1Ty(Context)),
899 NewLoop010BB);
900 Loop01BB.getTerminator()->replaceUsesOfWith(&Loop01BB, NewLoop010BB);
901 AR.DT.addNewBlock(NewLoop010BB, &Loop01BB);
933 auto *NewLoop010PHBB =
934 BasicBlock::Create(Context, "loop.0.1.0.ph", &F, &Loop02PHBB);
935 NewLoop010BB =
936 BasicBlock::Create(Context, "loop.0.1.0", &F, &Loop02PHBB);
937 NewLoop01LatchBB =
938 BasicBlock::Create(Context, "loop.0.1.latch", &F, &Loop02PHBB);
939 Loop01BB.getTerminator()->replaceUsesOfWith(&Loop01BB, NewLoop010PHBB);
940 BranchInst::Create(NewLoop010BB, NewLoop010PHBB);
941 CreateCondBr(NewLoop01LatchBB, NewLoop010BB, "cond.0.1.0",
942 NewLoop010BB);
943 BranchInst::Create(&Loop01BB, NewLoop01LatchBB);
944 AR.DT.addNewBlock(NewLoop010PHBB, &Loop01BB);
945 AR.DT.addNewBlock(NewLoop010BB, NewLoop010PHBB);
946 AR.DT.addNewBlock(NewLoop01LatchBB, NewLoop010BB);
947 AR.DT.verifyDomTree();
948 L.addBasicBlockToLoop(NewLoop010PHBB, AR.LI);
902949 NewLoop->addBasicBlockToLoop(NewLoop010BB, AR.LI);
950 L.addBasicBlockToLoop(NewLoop01LatchBB, AR.LI);
951 NewLoop->verifyLoop();
952 L.verifyLoop();
903953 Updater.addChildLoops({NewLoop});
904954 return PreservedAnalyses::all();
905955 }));
920970 // In the second run over the middle loop after we've visited the new child,
921971 // we add another child to check that we can repeatedly add children, and add
922972 // children to a loop that already has children.
923 BasicBlock *NewLoop011BB;
924973 EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
925974 .WillOnce(Invoke([&](Loop &L, LoopAnalysisManager &AM,
926975 LoopStandardAnalysisResults &AR,
927976 LPMUpdater &Updater) {
928977 auto *NewLoop = new Loop();
929978 L.addChildLoop(NewLoop);
930 NewLoop011BB = BasicBlock::Create(Context, "loop.0.1.1", &F, &Loop02BB);
931 BranchInst::Create(&Loop01BB, NewLoop011BB,
932 UndefValue::get(Type::getInt1Ty(Context)),
933 NewLoop011BB);
934 NewLoop010BB->getTerminator()->replaceUsesOfWith(&Loop01BB,
935 NewLoop011BB);
936 AR.DT.addNewBlock(NewLoop011BB, NewLoop010BB);
979 auto *NewLoop011PHBB = BasicBlock::Create(Context, "loop.0.1.1.ph", &F, NewLoop01LatchBB);
980 auto *NewLoop011BB = BasicBlock::Create(Context, "loop.0.1.1", &F, NewLoop01LatchBB);
981 NewLoop010BB->getTerminator()->replaceUsesOfWith(NewLoop01LatchBB,
982 NewLoop011PHBB);
983 BranchInst::Create(NewLoop011BB, NewLoop011PHBB);
984 CreateCondBr(NewLoop01LatchBB, NewLoop011BB, "cond.0.1.1",
985 NewLoop011BB);
986 AR.DT.addNewBlock(NewLoop011PHBB, NewLoop010BB);
987 auto *NewDTNode = AR.DT.addNewBlock(NewLoop011BB, NewLoop011PHBB);
988 AR.DT.changeImmediateDominator(AR.DT[NewLoop01LatchBB], NewDTNode);
989 AR.DT.verifyDomTree();
990 L.addBasicBlockToLoop(NewLoop011PHBB, AR.LI);
937991 NewLoop->addBasicBlockToLoop(NewLoop011BB, AR.LI);
992 NewLoop->verifyLoop();
993 L.verifyLoop();
938994 Updater.addChildLoops({NewLoop});
939995 return PreservedAnalyses::all();
940996 }));
9761032 TEST_F(LoopPassManagerTest, LoopPeerInsertion) {
9771033 // Super boring module with two loop nests and loop nest with two child
9781034 // loops.
979 M = parseIR(Context, "define void @f() {\n"
1035 M = parseIR(Context, "define void @f(i1* %ptr) {\n"
9801036 "entry:\n"
9811037 " br label %loop.0\n"
9821038 "loop.0:\n"
983 " br i1 undef, label %loop.0.0, label %loop.2\n"
1039 " %cond.0 = load volatile i1, i1* %ptr\n"
1040 " br i1 %cond.0, label %loop.0.0.ph, label %loop.2.ph\n"
1041 "loop.0.0.ph:\n"
1042 " br label %loop.0.0\n"
9841043 "loop.0.0:\n"
985 " br i1 undef, label %loop.0.0, label %loop.0.2\n"
1044 " %cond.0.0 = load volatile i1, i1* %ptr\n"
1045 " br i1 %cond.0.0, label %loop.0.0, label %loop.0.2.ph\n"
1046 "loop.0.2.ph:\n"
1047 " br label %loop.0.2\n"
9861048 "loop.0.2:\n"
987 " br i1 undef, label %loop.0.2, label %loop.0\n"
1049 " %cond.0.2 = load volatile i1, i1* %ptr\n"
1050 " br i1 %cond.0.2, label %loop.0.2, label %loop.0.latch\n"
1051 "loop.0.latch:\n"
1052 " br label %loop.0\n"
1053 "loop.2.ph:\n"
1054 " br label %loop.2\n"
9881055 "loop.2:\n"
989 " br i1 undef, label %loop.2, label %end\n"
1056 " %cond.2 = load volatile i1, i1* %ptr\n"
1057 " br i1 %cond.2, label %loop.2, label %end\n"
9901058 "end:\n"
9911059 " ret void\n"
9921060 "}\n");
9951063 // easily.
9961064 Function &F = *M->begin();
9971065 ASSERT_THAT(F, HasName("f"));
1066 Argument &Ptr = *F.arg_begin();
9981067 auto BBI = F.begin();
9991068 BasicBlock &EntryBB = *BBI++;
10001069 ASSERT_THAT(EntryBB, HasName("entry"));
10011070 BasicBlock &Loop0BB = *BBI++;
10021071 ASSERT_THAT(Loop0BB, HasName("loop.0"));
1072 BasicBlock &Loop00PHBB = *BBI++;
1073 ASSERT_THAT(Loop00PHBB, HasName("loop.0.0.ph"));
10031074 BasicBlock &Loop00BB = *BBI++;
10041075 ASSERT_THAT(Loop00BB, HasName("loop.0.0"));
1076 BasicBlock &Loop02PHBB = *BBI++;
1077 ASSERT_THAT(Loop02PHBB, HasName("loop.0.2.ph"));
10051078 BasicBlock &Loop02BB = *BBI++;
10061079 ASSERT_THAT(Loop02BB, HasName("loop.0.2"));
1080 BasicBlock &Loop0LatchBB = *BBI++;
1081 ASSERT_THAT(Loop0LatchBB, HasName("loop.0.latch"));
1082 BasicBlock &Loop2PHBB = *BBI++;
1083 ASSERT_THAT(Loop2PHBB, HasName("loop.2.ph"));
10071084 BasicBlock &Loop2BB = *BBI++;
10081085 ASSERT_THAT(Loop2BB, HasName("loop.2"));
10091086 BasicBlock &EndBB = *BBI++;
10101087 ASSERT_THAT(EndBB, HasName("end"));
10111088 ASSERT_THAT(BBI, F.end());
1012 Constant *Undefi1 = UndefValue::get(Type::getInt1Ty(Context));
1089 auto CreateCondBr = [&](BasicBlock *TrueBB, BasicBlock *FalseBB,
1090 const char *Name, BasicBlock *BB) {
1091 auto *Cond = new LoadInst(&Ptr, Name, /*isVolatile*/ true, BB);
1092 BranchInst::Create(TrueBB, FalseBB, Cond, BB);
1093 };
10131094
10141095 // Build the pass managers and register our pipeline. We build a single loop
10151096 // pass pipeline consisting of three mock pass runs over each loop. After
10361117 EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
10371118
10381119 // On the second run, we insert a sibling loop.
1039 BasicBlock *NewLoop01BB;
10401120 EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
10411121 .WillOnce(Invoke([&](Loop &L, LoopAnalysisManager &AM,
10421122 LoopStandardAnalysisResults &AR,
10431123 LPMUpdater &Updater) {
10441124 auto *NewLoop = new Loop();
10451125 L.getParentLoop()->addChildLoop(NewLoop);
1046 NewLoop01BB = BasicBlock::Create(Context, "loop.0.1", &F, &Loop02BB);
1047 BranchInst::Create(&Loop02BB, NewLoop01BB, Undefi1, NewLoop01BB);
1048 Loop00BB.getTerminator()->replaceUsesOfWith(&Loop02BB, NewLoop01BB);
1049 auto *NewDTNode = AR.DT.addNewBlock(NewLoop01BB, &Loop00BB);
1050 AR.DT.changeImmediateDominator(AR.DT[&Loop02BB], NewDTNode);
1126 auto *NewLoop01PHBB = BasicBlock::Create(Context, "loop.0.1.ph", &F, &Loop02PHBB);
1127 auto *NewLoop01BB = BasicBlock::Create(Context, "loop.0.1", &F, &Loop02PHBB);
1128 BranchInst::Create(NewLoop01BB, NewLoop01PHBB);
1129 CreateCondBr(&Loop02PHBB, NewLoop01BB, "cond.0.1", NewLoop01BB);
1130 Loop00BB.getTerminator()->replaceUsesOfWith(&Loop02PHBB, NewLoop01PHBB);
1131 AR.DT.addNewBlock(NewLoop01PHBB, &Loop00BB);
1132 auto *NewDTNode = AR.DT.addNewBlock(NewLoop01BB, NewLoop01PHBB);
1133 AR.DT.changeImmediateDominator(AR.DT[&Loop02PHBB], NewDTNode);
1134 AR.DT.verifyDomTree();
1135 L.getParentLoop()->addBasicBlockToLoop(NewLoop01PHBB, AR.LI);
10511136 NewLoop->addBasicBlockToLoop(NewLoop01BB, AR.LI);
1137 L.getParentLoop()->verifyLoop();
10521138 Updater.addSiblingLoops({NewLoop});
10531139 return PreservedAnalyses::all();
10541140 }));
10811167 L.getParentLoop()->addChildLoop(NewLoops[0]);
10821168 L.getParentLoop()->addChildLoop(NewLoops[1]);
10831169 NewLoops[1]->addChildLoop(NewLoops[2]);
1170 auto *NewLoop03PHBB =
1171 BasicBlock::Create(Context, "loop.0.3.ph", &F, &Loop0LatchBB);
10841172 auto *NewLoop03BB =
1085 BasicBlock::Create(Context, "loop.0.3", &F, &Loop2BB);
1173 BasicBlock::Create(Context, "loop.0.3", &F, &Loop0LatchBB);
1174 auto *NewLoop04PHBB =
1175 BasicBlock::Create(Context, "loop.0.4.ph", &F, &Loop0LatchBB);
10861176 auto *NewLoop04BB =
1087 BasicBlock::Create(Context, "loop.0.4", &F, &Loop2BB);
1177 BasicBlock::Create(Context, "loop.0.4", &F, &Loop0LatchBB);
1178 auto *NewLoop040PHBB =
1179 BasicBlock::Create(Context, "loop.0.4.0.ph", &F, &Loop0LatchBB);
10881180 auto *NewLoop040BB =
1089 BasicBlock::Create(Context, "loop.0.4.0", &F, &Loop2BB);
1090 Loop02BB.getTerminator()->replaceUsesOfWith(&Loop0BB, NewLoop03BB);
1091 BranchInst::Create(NewLoop04BB, NewLoop03BB, Undefi1, NewLoop03BB);
1092 BranchInst::Create(&Loop0BB, NewLoop040BB, Undefi1, NewLoop04BB);
1093 BranchInst::Create(NewLoop04BB, NewLoop040BB, Undefi1, NewLoop040BB);
1094 AR.DT.addNewBlock(NewLoop03BB, &Loop02BB);
1095 AR.DT.addNewBlock(NewLoop04BB, NewLoop03BB);
1096 AR.DT.addNewBlock(NewLoop040BB, NewLoop04BB);
1181 BasicBlock::Create(Context, "loop.0.4.0", &F, &Loop0LatchBB);
1182 auto *NewLoop04LatchBB =
1183 BasicBlock::Create(Context, "loop.0.4.latch", &F, &Loop0LatchBB);
1184 Loop02BB.getTerminator()->replaceUsesOfWith(&Loop0LatchBB, NewLoop03PHBB);
1185 BranchInst::Create(NewLoop03BB, NewLoop03PHBB);
1186 CreateCondBr(NewLoop04PHBB, NewLoop03BB, "cond.0.3", NewLoop03BB);
1187 BranchInst::Create(NewLoop04BB, NewLoop04PHBB);
1188 CreateCondBr(&Loop0LatchBB, NewLoop040PHBB, "cond.0.4", NewLoop04BB);
1189 BranchInst::Create(NewLoop040BB, NewLoop040PHBB);
1190 CreateCondBr(NewLoop04LatchBB, NewLoop040BB, "cond.0.4.0", NewLoop040BB);
1191 BranchInst::Create(NewLoop04BB, NewLoop04LatchBB);
1192 AR.DT.addNewBlock(NewLoop03PHBB, &Loop02BB);
1193 AR.DT.addNewBlock(NewLoop03BB, NewLoop03PHBB);
1194 AR.DT.addNewBlock(NewLoop04PHBB, NewLoop03BB);
1195 auto *NewDTNode = AR.DT.addNewBlock(NewLoop04BB, NewLoop04PHBB);
1196 AR.DT.changeImmediateDominator(AR.DT[&Loop0LatchBB], NewDTNode);
1197 AR.DT.addNewBlock(NewLoop040PHBB, NewLoop04BB);
1198 AR.DT.addNewBlock(NewLoop040BB, NewLoop040PHBB);
1199 AR.DT.addNewBlock(NewLoop04LatchBB, NewLoop040BB);
1200 AR.DT.verifyDomTree();
1201 L.getParentLoop()->addBasicBlockToLoop(NewLoop03PHBB, AR.LI);
10971202 NewLoops[0]->addBasicBlockToLoop(NewLoop03BB, AR.LI);
1203 L.getParentLoop()->addBasicBlockToLoop(NewLoop04PHBB, AR.LI);
10981204 NewLoops[1]->addBasicBlockToLoop(NewLoop04BB, AR.LI);
1205 NewLoops[1]->addBasicBlockToLoop(NewLoop040PHBB, AR.LI);
10991206 NewLoops[2]->addBasicBlockToLoop(NewLoop040BB, AR.LI);
1207 NewLoops[1]->addBasicBlockToLoop(NewLoop04LatchBB, AR.LI);
1208 L.getParentLoop()->verifyLoop();
11001209 Updater.addSiblingLoops({NewLoops[0], NewLoops[1]});
11011210 return PreservedAnalyses::all();
11021211 }));
11351244 LPMUpdater &Updater) {
11361245 auto *NewLoop = new Loop();
11371246 AR.LI.addTopLevelLoop(NewLoop);
1247 auto *NewLoop1PHBB = BasicBlock::Create(Context, "loop.1.ph", &F, &Loop2BB);
11381248 auto *NewLoop1BB = BasicBlock::Create(Context, "loop.1", &F, &Loop2BB);
1139 BranchInst::Create(&Loop2BB, NewLoop1BB, Undefi1, NewLoop1BB);
1140 Loop0BB.getTerminator()->replaceUsesOfWith(&Loop2BB, NewLoop1BB);
1141 auto *NewDTNode = AR.DT.addNewBlock(NewLoop1BB, &Loop0BB);
1142 AR.DT.changeImmediateDominator(AR.DT[&Loop2BB], NewDTNode);
1249 BranchInst::Create(NewLoop1BB, NewLoop1PHBB);
1250 CreateCondBr(&Loop2PHBB, NewLoop1BB, "cond.1", NewLoop1BB);
1251 Loop0BB.getTerminator()->replaceUsesOfWith(&Loop2PHBB, NewLoop1PHBB);
1252 AR.DT.addNewBlock(NewLoop1PHBB, &Loop0BB);
1253 auto *NewDTNode = AR.DT.addNewBlock(NewLoop1BB, NewLoop1PHBB);
1254 AR.DT.changeImmediateDominator(AR.DT[&Loop2PHBB], NewDTNode);
1255 AR.DT.verifyDomTree();
11431256 NewLoop->addBasicBlockToLoop(NewLoop1BB, AR.LI);
1257 NewLoop->verifyLoop();
11441258 Updater.addSiblingLoops({NewLoop});
11451259 return PreservedAnalyses::all();
11461260 }));
11701284 // Build a module with a single loop nest that contains one outer loop with
11711285 // three subloops, and one of those with its own subloop. We will
11721286 // incrementally delete all of these to test different deletion scenarios.
1173 M = parseIR(Context, "define void @f() {\n"
1287 M = parseIR(Context, "define void @f(i1* %ptr) {\n"
11741288 "entry:\n"
11751289 " br label %loop.0\n"
11761290 "loop.0:\n"
1177 " br i1 undef, label %loop.0.0, label %end\n"
1291 " %cond.0 = load volatile i1, i1* %ptr\n"
1292 " br i1 %cond.0, label %loop.0.0.ph, label %end\n"
1293 "loop.0.0.ph:\n"
1294 " br label %loop.0.0\n"
11781295 "loop.0.0:\n"
1179 " br i1 undef, label %loop.0.0, label %loop.0.1\n"
1296 " %cond.0.0 = load volatile i1, i1* %ptr\n"
1297 " br i1 %cond.0.0, label %loop.0.0, label %loop.0.1.ph\n"
1298 "loop.0.1.ph:\n"
1299 " br label %loop.0.1\n"
11801300 "loop.0.1:\n"
1181 " br i1 undef, label %loop.0.1, label %loop.0.2\n"
1301 " %cond.0.1 = load volatile i1, i1* %ptr\n"
1302 " br i1 %cond.0.1, label %loop.0.1, label %loop.0.2.ph\n"
1303 "loop.0.2.ph:\n"
1304 " br label %loop.0.2\n"
11821305 "loop.0.2:\n"
1183 " br i1 undef, label %loop.0.2.0, label %loop.0\n"
1306 " %cond.0.2 = load volatile i1, i1* %ptr\n"
1307 " br i1 %cond.0.2, label %loop.0.2.0.ph, label %loop.0.latch\n"
1308 "loop.0.2.0.ph:\n"
1309 " br label %loop.0.2.0\n"
11841310 "loop.0.2.0:\n"
1185 " br i1 undef, label %loop.0.2.0, label %loop.0.2\n"
1311 " %cond.0.2.0 = load volatile i1, i1* %ptr\n"
1312 " br i1 %cond.0.2.0, label %loop.0.2.0, label %loop.0.2.latch\n"
1313 "loop.0.2.latch:\n"
1314 " br label %loop.0.2\n"
1315 "loop.0.latch:\n"
1316 " br label %loop.0\n"
11861317 "end:\n"
11871318 " ret void\n"
11881319 "}\n");
11911322 // easily.
11921323 Function &F = *M->begin();
11931324 ASSERT_THAT(F, HasName("f"));
1325 Argument &Ptr = *F.arg_begin();
11941326 auto BBI = F.begin();
11951327 BasicBlock &EntryBB = *BBI++;
11961328 ASSERT_THAT(EntryBB, HasName("entry"));
11971329 BasicBlock &Loop0BB = *BBI++;
11981330 ASSERT_THAT(Loop0BB, HasName("loop.0"));
1331 BasicBlock &Loop00PHBB = *BBI++;
1332 ASSERT_THAT(Loop00PHBB, HasName("loop.0.0.ph"));
11991333 BasicBlock &Loop00BB = *BBI++;
12001334 ASSERT_THAT(Loop00BB, HasName("loop.0.0"));
1335 BasicBlock &Loop01PHBB = *BBI++;
1336 ASSERT_THAT(Loop01PHBB, HasName("loop.0.1.ph"));
12011337 BasicBlock &Loop01BB = *BBI++;
12021338 ASSERT_THAT(Loop01BB, HasName("loop.0.1"));
1339 BasicBlock &Loop02PHBB = *BBI++;
1340 ASSERT_THAT(Loop02PHBB, HasName("loop.0.2.ph"));
12031341 BasicBlock &Loop02BB = *BBI++;
12041342 ASSERT_THAT(Loop02BB, HasName("loop.0.2"));
1343 BasicBlock &Loop020PHBB = *BBI++;
1344 ASSERT_THAT(Loop020PHBB, HasName("loop.0.2.0.ph"));
12051345 BasicBlock &Loop020BB = *BBI++;
12061346 ASSERT_THAT(Loop020BB, HasName("loop.0.2.0"));
1347 BasicBlock &Loop02LatchBB = *BBI++;
1348 ASSERT_THAT(Loop02LatchBB, HasName("loop.0.2.latch"));
1349 BasicBlock &Loop0LatchBB = *BBI++;
1350 ASSERT_THAT(Loop0LatchBB, HasName("loop.0.latch"));
12071351 BasicBlock &EndBB = *BBI++;
12081352 ASSERT_THAT(EndBB, HasName("end"));
12091353 ASSERT_THAT(BBI, F.end());
1210 Constant *Undefi1 = UndefValue::get(Type::getInt1Ty(Context));
12111354
12121355 // Helper to do the actual deletion of a loop. We directly encode this here
12131356 // to isolate ourselves from the rest of LLVM and for simplicity. Here we can
12141357 // egregiously cheat based on knowledge of the test case. For example, we
12151358 // have no PHI nodes and there is always a single i-dom.
1216 auto DeleteLoopBlocks = [](Loop &L, BasicBlock &IDomBB,
1359 auto RemoveLoop = [](Loop &L, BasicBlock &IDomBB,
12171360 LoopStandardAnalysisResults &AR,
12181361 LPMUpdater &Updater) {
1219 for (BasicBlock *LoopBB : L.blocks()) {
1362 assert(L.empty() && "Can only delete leaf loops with this routine!");
1363 SmallVector LoopBBs(L.block_begin(), L.block_end());
1364 Updater.markLoopAsDeleted(L);
1365 IDomBB.getTerminator()->replaceUsesOfWith(L.getHeader(),
1366 L.getUniqueExitBlock());
1367 for (BasicBlock *LoopBB : LoopBBs) {
12201368 SmallVector ChildNodes(AR.DT[LoopBB]->begin(),
12211369 AR.DT[LoopBB]->end());
12221370 for (DomTreeNode *ChildNode : ChildNodes)
12231371 AR.DT.changeImmediateDominator(ChildNode, AR.DT[&IDomBB]);
12241372 AR.DT.eraseNode(LoopBB);
1373 AR.LI.removeBlock(LoopBB);
12251374 LoopBB->dropAllReferences();
12261375 }
1227 SmallVector LoopBBs(L.block_begin(), L.block_end());
1228 Updater.markLoopAsDeleted(L);
1229 AR.LI.markAsRemoved(&L);
12301376 for (BasicBlock *LoopBB : LoopBBs)
12311377 LoopBB->eraseFromParent();
1378
1379 if (Loop *ParentL = L.getParentLoop())
1380 return ParentL->removeChildLoop(find(*ParentL, &L));
1381
1382 return AR.LI.removeLoop(find(AR.LI, &L));
12321383 };
12331384
12341385 // Build up the pass managers.
12711422 .WillOnce(
12721423 Invoke([&](Loop &L, LoopAnalysisManager &AM,
12731424 LoopStandardAnalysisResults &AR, LPMUpdater &Updater) {
1425 Loop *ParentL = L.getParentLoop();
12741426 AR.SE.forgetLoop(&L);
1275 Loop00BB.getTerminator()->replaceUsesOfWith(&Loop01BB, &Loop02BB);
1276 DeleteLoopBlocks(L, Loop00BB, AR, Updater);
1427 delete RemoveLoop(L, Loop01PHBB, AR, Updater);
1428 ParentL->verifyLoop();
12771429 return PreservedAnalyses::all();
12781430 }));
12791431
13141466
13151467 EXPECT_CALL(MLPHandle, run(HasName("loop.0.2"), _, _, _))
13161468 .WillOnce(Invoke(getLoopAnalysisResult));
1317 BasicBlock *NewLoop03BB;
1469 BasicBlock *NewLoop03PHBB;
13181470 EXPECT_CALL(MLPHandle, run(HasName("loop.0.2"), _, _, _))
13191471 .WillOnce(
13201472 Invoke([&](Loop &L, LoopAnalysisManager &AM,
13211473 LoopStandardAnalysisResults &AR, LPMUpdater &Updater) {
1322 // Delete the inner loop first. we also do this manually because we
1323 // want to preserve the loop object and reuse it.
1474 // Remove the inner loop first but retain it to reuse later.
13241475 AR.SE.forgetLoop(*L.begin());
1325 Loop02BB.getTerminator()->replaceUsesOfWith(&Loop020BB, &Loop02BB);
1326 assert(std::next((*L.begin())->block_begin()) ==
1327 (*L.begin())->block_end() &&
1328 "There should only be one block.");
1329 assert(AR.DT[&Loop020BB]->getNumChildren() == 0 &&
1330 "Cannot have children in the domtree!");
1331 AR.DT.eraseNode(&Loop020BB);
1332 Updater.markLoopAsDeleted(**L.begin());
1333 AR.LI.removeBlock(&Loop020BB);
1334 auto *OldL = L.removeChildLoop(L.begin());
1335 Loop020BB.eraseFromParent();
1476 auto *OldL = RemoveLoop(**L.begin(), Loop020PHBB, AR, Updater);
13361477
13371478 auto *ParentL = L.getParentLoop();
13381479 AR.SE.forgetLoop(&L);
1339 Loop00BB.getTerminator()->replaceUsesOfWith(&Loop02BB, &Loop0BB);
1340 DeleteLoopBlocks(L, Loop00BB, AR, Updater);
1480 delete RemoveLoop(L, Loop02PHBB, AR, Updater);
13411481
13421482 // Now insert a new sibling loop, reusing a loop pointer.
13431483 ParentL->addChildLoop(OldL);
1344 NewLoop03BB = BasicBlock::Create(Context, "loop.0.3", &F, &EndBB);
1345 BranchInst::Create(&Loop0BB, NewLoop03BB, Undefi1, NewLoop03BB);
1346 Loop00BB.getTerminator()->replaceUsesOfWith(&Loop0BB, NewLoop03BB);
1347 AR.DT.addNewBlock(NewLoop03BB, &Loop00BB);
1484 NewLoop03PHBB =
1485 BasicBlock::Create(Context, "loop.0.3.ph", &F, &Loop0LatchBB);
1486 auto *NewLoop03BB =
1487 BasicBlock::Create(Context, "loop.0.3", &F, &Loop0LatchBB);
1488 BranchInst::Create(NewLoop03BB, NewLoop03PHBB);
1489 auto *Cond = new LoadInst(&Ptr, "cond.0.3", /*isVolatile*/ true,
1490 NewLoop03BB);
1491 BranchInst::Create(&Loop0LatchBB, NewLoop03BB, Cond, NewLoop03BB);
1492 Loop02PHBB.getTerminator()->replaceUsesOfWith(&Loop0LatchBB,
1493 NewLoop03PHBB);
1494 AR.DT.addNewBlock(NewLoop03PHBB, &Loop02PHBB);
1495 AR.DT.addNewBlock(NewLoop03BB, NewLoop03PHBB);
1496 AR.DT.changeImmediateDominator(AR.DT[&Loop0LatchBB],
1497 AR.DT[NewLoop03BB]);
1498 AR.DT.verifyDomTree();
1499 ParentL->addBasicBlockToLoop(NewLoop03PHBB, AR.LI);
13481500 OldL->addBasicBlockToLoop(NewLoop03BB, AR.LI);
1501 OldL->verifyLoop();
1502 ParentL->verifyLoop();
13491503 Updater.addSiblingLoops({OldL});
13501504 return PreservedAnalyses::all();
13511505 }));
13781532 Invoke([&](Loop &L, LoopAnalysisManager &AM,
13791533 LoopStandardAnalysisResults &AR, LPMUpdater &Updater) {
13801534 AR.SE.forgetLoop(&L);
1381 Loop0BB.getTerminator()->replaceUsesOfWith(&Loop00BB, NewLoop03BB);
1382 DeleteLoopBlocks(L, Loop0BB, AR, Updater);
1535 delete RemoveLoop(L, Loop00PHBB, AR, Updater);
13831536 return PreservedAnalyses::all();
13841537 }));
13851538
13901543 Invoke([&](Loop &L, LoopAnalysisManager &AM,
13911544 LoopStandardAnalysisResults &AR, LPMUpdater &Updater) {
13921545 AR.SE.forgetLoop(&L);
1393 Loop0BB.getTerminator()->replaceUsesOfWith(NewLoop03BB, &Loop0BB);
1394 DeleteLoopBlocks(L, Loop0BB, AR, Updater);
1546 delete RemoveLoop(L, *NewLoop03PHBB, AR, Updater);
13951547 return PreservedAnalyses::all();
13961548 }));
13971549
14021554 Invoke([&](Loop &L, LoopAnalysisManager &AM,
14031555 LoopStandardAnalysisResults &AR, LPMUpdater &Updater) {
14041556 AR.SE.forgetLoop(&L);
1405 EntryBB.getTerminator()->replaceUsesOfWith(&Loop0BB, &EndBB);
1406 DeleteLoopBlocks(L, EntryBB, AR, Updater);
1557 delete RemoveLoop(L, EntryBB, AR, Updater);
14071558 return PreservedAnalyses::all();
14081559 }));
14091560