LLVM: lib/Transforms/Utils/LoopPeel.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
43#include
44#include
45#include
46#include
47
48using namespace llvm;
51
52#define DEBUG_TYPE "loop-peel"
53
54STATISTIC(NumPeeled, "Number of loops peeled");
55STATISTIC(NumPeeledEnd, "Number of loops peeled from end");
56
57namespace llvm {
60 cl::desc("Set the unroll peeling count, for testing purposes"));
61
64 cl::desc("Allows loops to be peeled when the dynamic "
65 "trip count is known to be low."));
66
70 cl::desc("Allows loop nests to be peeled."));
71
74 cl::desc("Max average trip count which will cause loop peeling."));
75
78 cl::desc("Force a peel count regardless of profiling information."));
79
83 "Disable advance peeling. Issues for convergent targets (D134803)."));
84
87 cl::desc("Enable peeling to convert Phi nodes into IVs"));
88
90
92}
93
94
96
97 if (!L->isLoopSimplifyForm())
98 return false;
100 return true;
101
103 L->getUniqueNonLatchExitBlocks(Exits);
104
105
106
107
108
109
110
111
113}
114
115namespace {
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195class PhiAnalyzer {
196public:
197 PhiAnalyzer(const Loop &L, unsigned MaxIterations, bool PeelForIV);
198
199
200
201 std::optional calculateIterationsToPeel();
202
203protected:
204 enum class PeelCounterType {
205 Invariant,
206 Induction,
207 };
208
209 using PeelCounterValue = std::pair<unsigned, PeelCounterType>;
210 using PeelCounter = std::optional;
211 const PeelCounter Unknown = std::nullopt;
212
213
214 PeelCounter addOne(PeelCounter PC) const {
215 if (PC == Unknown)
216 return Unknown;
217 auto [Val, Ty] = *PC;
218 return (Val + 1 <= MaxIterations) ? PeelCounter({Val + 1, Ty}) : Unknown;
219 }
220
221
222 PeelCounter makeZero(PeelCounterType Ty) const {
223 return PeelCounter({0, Ty});
224 }
225
226
227
228 PeelCounter calculate(const Value &);
229
230
231
232 PeelCounter mergeTwoCounters(const Instruction &CmpOrBinaryOp,
233 const PeelCounterValue &LHS,
234 const PeelCounterValue &RHS) const;
235
236
237
238 bool isInductionPHI(const PHINode *Phi) const;
239
240 const Loop &L;
241 const unsigned MaxIterations;
242 const bool PeelForIV;
243
244
245 SmallDenseMap<const Value *, PeelCounter> IterationsToInvarianceOrInduction;
246};
247
248PhiAnalyzer::PhiAnalyzer(const Loop &L, unsigned MaxIterations, bool PeelForIV)
249 : L(L), MaxIterations(MaxIterations), PeelForIV(PeelForIV) {
250 assert(canPeel(&L) && "loop is not suitable for peeling");
251 assert(MaxIterations > 0 && "no peeling is allowed?");
252}
253
254
255
256
257
258bool PhiAnalyzer::isInductionPHI(const PHINode *Phi) const {
259
261 if (Latch == nullptr)
262 return false;
263
264 Value *Cur = Phi->getIncomingValueForBlock(Latch);
265 SmallPtrSet<Value *, 4> Visited;
266 bool VisitBinOp = false;
267
268
269
270
271 while (true) {
272 if (Cur == Phi)
273 break;
274
275
276 if (!Visited.insert(Cur).second)
277 return false;
278
280 if ( ||
.contains(I))
281 return false;
282
284 Cur = Cast->getOperand(0);
286 if (BinOp->getOpcode() != Instruction::Add &&
287 BinOp->getOpcode() != Instruction::Sub)
288 return false;
290 return false;
291
292 VisitBinOp = true;
293 Cur = BinOp->getOperand(0);
294 } else {
295 return false;
296 }
297 }
298
299
300 return VisitBinOp;
301}
302
303
304
305
306
307
308
309PhiAnalyzer::PeelCounter
310PhiAnalyzer::mergeTwoCounters(const Instruction &CmpOrBinaryOp,
311 const PeelCounterValue &LHS,
312 const PeelCounterValue &RHS) const {
313 auto &[LVal, LTy] = LHS;
314 auto &[RVal, RTy] = RHS;
315 unsigned NewVal = std::max(LVal, RVal);
316
317 if (LTy == PeelCounterType::Induction || RTy == PeelCounterType::Induction) {
319 if (BinOp->getOpcode() == Instruction::Add ||
320 BinOp->getOpcode() == Instruction::Sub)
321 return PeelCounter({NewVal, PeelCounterType::Induction});
322 }
324 }
325 return PeelCounter({NewVal, PeelCounterType::Invariant});
326}
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342PhiAnalyzer::PeelCounter PhiAnalyzer::calculate(const Value &V) {
343
344
345
347 IterationsToInvarianceOrInduction.try_emplace(&V, Unknown);
348 if (!Inserted)
349 return I->second;
350
351 if (L.isLoopInvariant(&V))
352
353 return (IterationsToInvarianceOrInduction[&V] =
354 makeZero(PeelCounterType::Invariant));
356 if (Phi->getParent() != L.getHeader()) {
357
358 assert(IterationsToInvarianceOrInduction[&V] == Unknown &&
359 "unexpected value saved");
361 }
362
363
364 if (PeelForIV && isInductionPHI(Phi))
365 return (IterationsToInvarianceOrInduction[&V] =
366 makeZero(PeelCounterType::Induction));
367
368
369 Value *Input = Phi->getIncomingValueForBlock(L.getLoopLatch());
370 PeelCounter Iterations = calculate(*Input);
371 assert(IterationsToInvarianceOrInduction[Input] == Iterations &&
372 "unexpected value saved");
373 return (IterationsToInvarianceOrInduction[Phi] = addOne(Iterations));
374 }
377
378 PeelCounter LHS = calculate(*I->getOperand(0));
381 PeelCounter RHS = calculate(*I->getOperand(1));
384 return (IterationsToInvarianceOrInduction[I] =
385 mergeTwoCounters(*I, *LHS, *RHS));
386 }
387 if (I->isCast())
388
389 return (IterationsToInvarianceOrInduction[I] =
390 calculate(*I->getOperand(0)));
391 }
392
393
394
395 assert(IterationsToInvarianceOrInduction[&V] == Unknown &&
396 "unexpected value saved");
398}
399
400std::optional PhiAnalyzer::calculateIterationsToPeel() {
401 unsigned Iterations = 0;
402 for (auto &PHI : L.getHeader()->phis()) {
403 PeelCounter ToInvarianceOrInduction = calculate(PHI);
404 if (ToInvarianceOrInduction != Unknown) {
405 unsigned Val = ToInvarianceOrInduction->first;
406 assert(Val <= MaxIterations && "bad result in phi analysis");
407 Iterations = std::max(Iterations, Val);
408 if (Iterations == MaxIterations)
409 break;
410 }
411 }
412 assert((Iterations <= MaxIterations) && "bad result in phi analysis");
413 return Iterations ? std::optional(Iterations) : std::nullopt;
414}
415
416}
417
418
419
420
421
425
426
427 if (L.getExitingBlock())
428 return 0;
429
430
431
433 L.getUniqueNonLatchExitBlocks(Exits);
436 }))
437 return 0;
438
439
440
441
442
443
445 BasicBlock *Latch = L.getLoopLatch();
447 const DataLayout &DL = L.getHeader()->getDataLayout();
450 if (I.mayWriteToMemory())
451 return 0;
452
455
456
457 if (BB == Header)
458 continue;
460 Value *Ptr = LI->getPointerOperand();
461 if (DT.dominates(BB, Latch) && L.isLoopInvariant(Ptr) &&
464 }
465 }
466 }
468 L.getExitingBlocks(ExitingBlocks);
469 if (any_of(ExitingBlocks, [&LoadUsers](BasicBlock *Exiting) {
471 }))
472 return 1;
473 return 0;
474}
475
479 return false;
480
481
482
483
484
485
486 BasicBlock *Latch = L.getLoopLatch();
492 return Latch && Latch == L.getExitingBlock() &&
502}
503
504
505
506
512 return false;
513
515 SCEVExpander Expander(SE, L.getHeader()->getDataLayout(), "loop-peel");
518 L.getLoopPredecessor()->getTerminator()))
519 return false;
520
527
529 RightSCEV) &&
531}
532
533
534
535
536
537
538
539
540
541
542
543
544static std::pair<unsigned, unsigned>
547 assert(L.isLoopSimplifyForm() && "Loop needs to be in loop simplify form");
548 unsigned DesiredPeelCount = 0;
549 unsigned DesiredPeelCountLast = 0;
550
551
554 MaxPeelCount =
555 std::min((unsigned)SC->getAPInt().getLimitedValue() - 1, MaxPeelCount);
556
557
558
559
560 auto PeelWhilePredicateIsKnown =
561 [&](unsigned &PeelCount, const SCEV *&IterVal, const SCEV *BoundSCEV,
563 while (PeelCount < MaxPeelCount &&
565 IterVal = SE.getAddExpr(IterVal, Step);
566 ++PeelCount;
567 }
569 BoundSCEV);
570 };
571
572 const unsigned MaxDepth = 4;
573 std::function<void(Value *, unsigned)> ComputePeelCount =
574 [&](Value *Condition, unsigned Depth) -> void {
576 return;
577
578 Value *LeftVal, *RightVal;
581 ComputePeelCount(LeftVal, Depth + 1);
582 ComputePeelCount(RightVal, Depth + 1);
583 return;
584 }
585
588 return;
589
590 const SCEV *LeftSCEV = SE.getSCEV(LeftVal);
591 const SCEV *RightSCEV = SE.getSCEV(RightVal);
592
593
594
596 return;
597
598
599
604 } else
605 return;
606 }
607
609
610
611
613 return;
616 return;
617
618
619
620 unsigned NewPeelCount = DesiredPeelCount;
621
624
625
626
627
630
632 if (!PeelWhilePredicateIsKnown(NewPeelCount, IterVal, RightSCEV, Step,
633 Pred)) {
635 DesiredPeelCountLast = 1;
636 return;
637 }
638
639
640
641
642 const SCEV *NextIterVal = SE.getAddExpr(IterVal, Step);
645 RightSCEV) &&
648 if (NewPeelCount >= MaxPeelCount)
649 return;
650 ++NewPeelCount;
651 }
652
653 DesiredPeelCount = std::max(DesiredPeelCount, NewPeelCount);
654 DesiredPeelCountLast = std::max(DesiredPeelCountLast, NewPeelCount);
655 };
656
658 if (->getType()->isIntegerTy())
659 return;
661 const SCEV *BoundSCEV, *IterSCEV;
662 if (L.isLoopInvariant(LHS)) {
665 } else if (L.isLoopInvariant(RHS)) {
668 } else
669 return;
671
672 if (!AddRec || !AddRec->isAffine() || AddRec->getLoop() != &L)
673 return;
674 const SCEV *Step = AddRec->getStepRecurrence(SE);
675 bool IsSigned = MinMax->isSigned();
676
677
683 else
684 return;
685
686 if (!(IsSigned ? AddRec->hasNoSignedWrap() : AddRec->hasNoUnsignedWrap()))
687 return;
688 unsigned NewPeelCount = DesiredPeelCount;
689 const SCEV *IterVal = AddRec->evaluateAtIteration(
690 SE.getConstant(AddRec->getType(), NewPeelCount), SE);
691 if (!PeelWhilePredicateIsKnown(NewPeelCount, IterVal, BoundSCEV, Step,
692 Pred)) {
694 DesiredPeelCountLast = 1;
695 return;
696 }
697 DesiredPeelCount = NewPeelCount;
698 };
699
703 ComputePeelCount(SI->getCondition(), 0);
705 ComputePeelCountMinMax(MinMax);
706 }
707
709 if (!BI || BI->isUnconditional())
710 continue;
711
712
713 if (L.getLoopLatch() == BB)
714 continue;
715
716 ComputePeelCount(BI->getCondition(), 0);
717 }
718
719 return {DesiredPeelCount, DesiredPeelCountLast};
720}
721
722
723
724
725
727 BasicBlock *Latch = L->getLoopLatch();
728 if (!Latch)
729 return true;
730
732 if (!LatchBR || LatchBR->getNumSuccessors() != 2 || !L->isLoopExiting(Latch))
733 return true;
734
736 LatchBR->getSuccessor(1) == L->getHeader()) &&
737 "At least one edge out of the latch must go to the header");
738
740 L->getUniqueNonLatchExitBlocks(ExitBlocks);
743 });
744}
745
746
747
753 assert(LoopSize > 0 && "Zero loop size is not allowed!");
754
755
756 unsigned TargetPeelCount = PP.PeelCount;
760 return;
761
762
763
764
766 return;
767
768
770 if (UserPeelCount) {
772 << " iterations.\n");
775 return;
776 }
777
778
780 return;
781
782
783 if (2 * LoopSize > Threshold)
784 return;
785
786 unsigned AlreadyPeeled = 0;
788 AlreadyPeeled = *Peeled;
789
791 return;
792
793
795 MaxPeelCount = std::min(MaxPeelCount, Threshold / LoopSize - 1);
796
797
798
799 unsigned DesiredPeelCount = TargetPeelCount;
800
801
802
803
804
805
806 if (MaxPeelCount > DesiredPeelCount) {
807
809 .calculateIterationsToPeel();
810 if (NumPeels)
811 DesiredPeelCount = std::max(DesiredPeelCount, *NumPeels);
812 }
813
814 const auto &[CountToEliminateCmps, CountToEliminateCmpsLast] =
816 DesiredPeelCount = std::max(DesiredPeelCount, CountToEliminateCmps);
817
818 if (DesiredPeelCount == 0)
820
821 if (DesiredPeelCount > 0) {
822 DesiredPeelCount = std::min(DesiredPeelCount, MaxPeelCount);
823
824 assert(DesiredPeelCount > 0 && "Wrong loop size estimation?");
827 << " iteration(s) to turn"
828 << " some Phis into invariants or inductions.\n");
832 return;
833 }
834 }
835
836 if (CountToEliminateCmpsLast > 0) {
837 unsigned DesiredPeelCountLast =
838 std::min(CountToEliminateCmpsLast, MaxPeelCount);
839
840 assert(DesiredPeelCountLast > 0 && "Wrong loop size estimation?");
843 << " iteration(s) to turn"
844 << " some Phis into invariants.\n");
845 PP.PeelCount = DesiredPeelCountLast;
848 return;
849 }
850 }
851
852
853
854 if (TripCount)
855 return;
856
857
859 return;
860
861
862
863
864
865 if (L->getHeader()->getParent()->hasProfileData()) {
867 return;
869 if (!EstimatedTripCount)
870 return;
871
872 LLVM_DEBUG(dbgs() << "Profile-based estimated trip count is "
873 << *EstimatedTripCount << "\n");
874
875 if (*EstimatedTripCount + AlreadyPeeled <= MaxPeelCount) {
876 unsigned PeelCount = *EstimatedTripCount;
877 LLVM_DEBUG(dbgs() << "Peeling first " << PeelCount << " iterations.\n");
879 return;
880 }
881 LLVM_DEBUG(dbgs() << "Already peel count: " << AlreadyPeeled << "\n");
883 LLVM_DEBUG(dbgs() << "Loop cost: " << LoopSize << "\n");
884 LLVM_DEBUG(dbgs() << "Max peel cost: " << Threshold << "\n");
886 << (Threshold / LoopSize - 1) << "\n");
887 }
888}
889
890
891
892
893
894
895
896
897
898
899
900
902 Loop *L, unsigned IterNumber, bool PeelLast, BasicBlock *InsertTop,
904 SmallVectorImpl<std::pair<BasicBlock *, BasicBlock *>> &ExitEdges,
910 BasicBlock *Latch = L->getLoopLatch();
911 BasicBlock *PreHeader = L->getLoopPreheader();
912
913 Function *F = Header->getParent();
916 Loop *ParentLoop = L->getParentLoop();
917
918
919
923
924
925
926
927 if (ParentLoop && LI->getLoopFor(*BB) == L)
929
930 VMap[*BB] = NewBB;
931
932
933 if (DT) {
934 if (Header == *BB)
936 else {
938
940 }
941 }
942 }
943
944 {
945
946
947
948 std::string Ext = (Twine("Peel") + Twine(IterNumber)).str();
950 Header->getContext(), Ext);
951 }
952
953
954
955 for (Loop *ChildLoop : *L) {
956 cloneLoop(ChildLoop, ParentLoop, VMap, LI, nullptr);
957 }
958
959
960
961
962
964
965
966
968 if (PeelLast) {
969
970
971 assert(IterNumber == 0 && "Only peeling a single iteration implemented.");
973 LatchTerm->setSuccessor(0, InsertBot);
974 LatchTerm->setSuccessor(1, InsertBot);
975 } else {
977
978
979
980 for (unsigned idx = 0, e = LatchTerm->getNumSuccessors(); idx < e; ++idx) {
981 if (LatchTerm->getSuccessor(idx) == Header) {
982 LatchTerm->setSuccessor(idx, InsertBot);
983 break;
984 }
985 }
986 }
987 if (DT)
989
990
991
992
993
994 if (PeelLast) {
995
996
997
998
1004 if (OrigPreHeader)
1006 OrigPreHeader);
1007
1009 Latch);
1010 VMap[&*I] = PN;
1011 }
1012 } else {
1013
1014
1015
1016
1019 if (IterNumber == 0) {
1021 } else {
1024 if (LatchInst && L->contains(LatchInst))
1025 VMap[&*I] = LVMap[LatchInst];
1026 else
1027 VMap[&*I] = LatchVal;
1028 }
1030 }
1031 }
1032
1033
1034
1035
1036
1037 for (auto Edge : ExitEdges)
1038 for (PHINode &PHI : Edge.second->phis()) {
1039 Value *LatchVal = PHI.getIncomingValueForBlock(Edge.first);
1041 if (LatchInst && L->contains(LatchInst))
1042 LatchVal = VMap[LatchVal];
1045 }
1046
1047
1048
1049 for (auto KV : VMap)
1050 LVMap[KV.first] = KV.second;
1051}
1052
1053TargetTransformInfo::PeelingPreferences
1056 std::optional UserAllowPeeling,
1057 std::optional UserAllowProfileBasedPeeling,
1058 bool UnrollingSpecficValues) {
1060
1061
1067
1068
1069 TTI.getPeelingPreferences(L, SE, PP);
1070
1071
1072 if (UnrollingSpecficValues) {
1079 }
1080
1081
1082 if (UserAllowPeeling)
1084 if (UserAllowProfileBasedPeeling)
1086
1087 return PP;
1088}
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1102 assert(PeelCount > 0 && "Attempt to peel out zero iterations?");
1103 assert(canPeel(L) && "Attempt to peel a loop which is not peelable?");
1105 "when peeling the last iteration, the loop must be supported and can "
1106 "only peel a single iteration");
1107
1109 LoopBlocks.perform(LI);
1110
1111 BasicBlock *Header = L->getHeader();
1112 BasicBlock *PreHeader = L->getLoopPreheader();
1113 BasicBlock *Latch = L->getLoopLatch();
1115 L->getExitEdges(ExitEdges);
1116
1117
1118
1119
1120
1122 for (auto *BB : L->blocks()) {
1123 auto *BBDomNode = DT.getNode(BB);
1125 for (auto *ChildDomNode : BBDomNode->children()) {
1126 auto *ChildBB = ChildDomNode->getBlock();
1127 if (!L->contains(ChildBB))
1128 ChildrenToUpdate.push_back(ChildBB);
1129 }
1130
1131
1132
1133
1135 for (auto *ChildBB : ChildrenToUpdate)
1136 NonLoopBlocksIDom[ChildBB] = NewIDom;
1137 }
1138
1139 Function *F = Header->getParent();
1140
1141
1146 if (PeelLast) {
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171 BasicBlock *Exit = L->getExitBlock();
1172 for (PHINode &P : Exit->phis())
1173 ExitValues[&P] = P.getIncomingValueForBlock(Latch);
1174
1176
1177 InsertTop = SplitEdge(Latch, Exit, &DT, LI);
1179
1180 InsertTop->setName(Exit->getName() + ".peel.begin");
1181 InsertBot->setName(Exit->getName() + ".peel.next");
1182 NewPreHeader = nullptr;
1183
1184
1185
1186
1187
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1200
1201
1203 double Freq = 1 / ExitP.toDouble();
1204
1205
1206
1207 assert(Freq >= 1.0 && "expected freq >= 1 due to initial iteration");
1208 double NewFreq = std::max(Freq - 1, 1.0);
1211 }
1212 }
1213 } else {
1214 NewPreHeader = SplitEdge(PreHeader, Header, &DT, LI);
1216
1218 Value *BTCValue =
1222 B.CreateICmpNE(BTCValue, ConstantInt::get(BTCValue->getType(), 0));
1223 auto *BI = B.CreateCondBr(Cond, NewPreHeader, InsertTop);
1228 if (HasBranchWeights) {
1229
1230
1231
1232
1233
1234
1235
1236
1237 if (L->getExitBlock() == OrigLatchBr->getSuccessor(0))
1238 std::swap(Weights[0], Weights[1]);
1240 }
1242
1243
1245 }
1246 } else {
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292 InsertTop = SplitEdge(PreHeader, Header, &DT, LI);
1295
1296 InsertTop->setName(Header->getName() + ".peel.begin");
1297 InsertBot->setName(Header->getName() + ".peel.next");
1298 NewPreHeader->setName(PreHeader->getName() + ".peel.newph");
1299 }
1300
1303
1304
1305
1308
1309
1311 for (unsigned Iter = 0; Iter < PeelCount; ++Iter) {
1313
1314 cloneLoopBlocks(L, Iter, PeelLast, InsertTop, InsertBot,
1315 NewPreHeader ? PreHeader : nullptr, ExitEdges, NewBlocks,
1316 LoopBlocks, VMap, LVMap, &DT, LI,
1317 LoopLocalNoAliasDeclScopes, *SE);
1318
1319
1320
1322
1323 if (Iter == 0) {
1324 if (PeelLast) {
1325
1326
1327
1328
1329
1330
1331 auto *Cmp =
1332 cast(L->getLoopLatch()->getTerminator()->getOperand(0));
1334 Cmp->setOperand(
1335 1, B.CreateSub(Cmp->getOperand(1),
1336 ConstantInt::get(Cmp->getOperand(1)->getType(), 1)));
1337 } else {
1338
1339 for (auto BBIDom : NonLoopBlocksIDom)
1342 }
1343 }
1344
1345#ifdef EXPENSIVE_CHECKS
1346 assert(DT.verify(DominatorTree::VerificationLevel::Fast));
1347#endif
1348
1349
1350
1352 LatchTermCopy->setMetadata(LLVMContext::MD_loop, nullptr);
1353
1354 InsertTop = InsertBot;
1356 InsertBot->setName(Header->getName() + ".peel.next");
1357
1358 F->splice(InsertTop->getIterator(), F, NewBlocks[0]->getIterator(),
1359 F->end());
1360 }
1361
1362 if (PeelLast) {
1363
1364
1365 for (const auto &[P, E] : ExitValues) {
1367 if (ExitInst && L->contains(ExitInst))
1368 P->replaceAllUsesWith(&*VMap[ExitInst]);
1369 else
1370 P->replaceAllUsesWith(E);
1371 P->eraseFromParent();
1372 }
1374 } else {
1375
1376
1379 Value *NewVal = PHI->getIncomingValueForBlock(Latch);
1381 if (LatchInst && L->contains(LatchInst))
1382 NewVal = LVMap[LatchInst];
1383
1384 PHI->setIncomingValueForBlock(NewPreHeader, NewVal);
1385 }
1386 }
1387
1388
1389 unsigned AlreadyPeeled = 0;
1391 AlreadyPeeled = *Peeled;
1392 unsigned TotalPeeled = AlreadyPeeled + PeelCount;
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1413 unsigned EstimatedTripCountNew = *EstimatedTripCount;
1414 if (EstimatedTripCountNew < TotalPeeled)
1415 EstimatedTripCountNew = 0;
1416 else
1417 EstimatedTripCountNew -= TotalPeeled;
1419 }
1420
1421 if (Loop *ParentLoop = L->getParentLoop())
1422 L = ParentLoop;
1423
1424
1427
1428#ifdef EXPENSIVE_CHECKS
1429
1430 assert(DT.verify(DominatorTree::VerificationLevel::Fast));
1431#endif
1432
1433
1434 simplifyLoop(L, &DT, LI, SE, AC, nullptr, PreserveLCSSA);
1435
1436 NumPeeled++;
1437 NumPeeledEnd += PeelLast;
1438
1439 return true;
1440}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
static bool shouldPeelLastIteration(Loop &L, CmpPredicate Pred, const SCEVAddRecExpr *LeftAR, const SCEV *RightSCEV, ScalarEvolution &SE, const TargetTransformInfo &TTI)
Returns true if the last iteration can be peeled off and the condition (Pred LeftAR,...
Definition LoopPeel.cpp:507
static bool violatesLegacyMultiExitLoopCheck(Loop *L)
This "heuristic" exactly matches implicit behavior which used to exist inside getLoopEstimatedTripCou...
Definition LoopPeel.cpp:726
static std::pair< unsigned, unsigned > countToEliminateCompares(Loop &L, unsigned MaxPeelCount, ScalarEvolution &SE, const TargetTransformInfo &TTI)
Definition LoopPeel.cpp:545
static void cloneLoopBlocks(Loop *L, unsigned IterNumber, bool PeelLast, BasicBlock *InsertTop, BasicBlock *InsertBot, BasicBlock *OrigPreHeader, SmallVectorImpl< std::pair< BasicBlock *, BasicBlock * > > &ExitEdges, SmallVectorImpl< BasicBlock * > &NewBlocks, LoopBlocksDFS &LoopBlocks, ValueToValueMapTy &VMap, ValueToValueMapTy &LVMap, DominatorTree *DT, LoopInfo *LI, ArrayRef< MDNode * > LoopLocalNoAliasDeclScopes, ScalarEvolution &SE)
Clones the body of the loop L, putting it between InsertTop and InsertBot.
Definition LoopPeel.cpp:901
static unsigned peelToTurnInvariantLoadsDereferenceable(Loop &L, DominatorTree &DT, AssumptionCache *AC)
Definition LoopPeel.cpp:422
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This pass exposes codegen information to IR-level passes.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI const CallInst * getTerminatingDeoptimizeCall() const
Returns the call instruction calling @llvm.experimental.deoptimize prior to the terminating return in...
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Conditional or Unconditional Branch instruction.
unsigned getNumSuccessors() const
BasicBlock * getSuccessor(unsigned i) const
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
A parsed version of the target data layout string in and methods for querying it.
DomTreeNodeBase * getIDom() const
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
Add a new node to the dominator tree information.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI Instruction * findNearestCommonDominator(Instruction *I1, Instruction *I2) const
Find the nearest instruction I that dominates both I1 and I2, in the sense that a result produced bef...
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI void setSuccessor(unsigned Idx, BasicBlock *BB)
Update the specified successor to point at the provided block.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
Store the result of a depth first search within basic blocks contained by a single loop.
std::vector< BasicBlock * >::const_reverse_iterator RPOIterator
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
This class represents min/max intrinsics.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
This node represents a polynomial recurrence on the trip count of the specified loop.
LLVM_ABI const SCEV * evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const
Return the value of this chain of recurrences at the specified iteration number.
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values.
const Loop * getLoop() const
This class represents a constant integer value.
This class uses information about analyze scalars to rewrite expressions in canonical form.
bool isHighCostExpansion(ArrayRef< const SCEV * > Exprs, Loop *L, unsigned Budget, const TargetTransformInfo *TTI, const Instruction *At)
Return true for expressions that can't be evaluated at runtime within given Budget.
LLVM_ABI Value * expandCodeFor(const SCEV *SH, Type *Ty, BasicBlock::iterator I)
Insert code to directly compute the specified SCEV expression into the program.
bool hasNoSelfWrap() const
This class represents an analyzed expression in the program.
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
static LLVM_ABI LoopGuards collect(const Loop *L, ScalarEvolution &SE)
Collect rewrite map for loop guards for loop L, together with flags indicating if NUW and NSW can be ...
The main scalar evolution driver.
const SCEV * getConstantMaxBackedgeTakenCount(const Loop *L)
When successful, this returns a SCEVConstant that is greater than or equal to (i.e.
LLVM_ABI bool isKnownNegative(const SCEV *S)
Test if the given expression is known to be negative.
LLVM_ABI bool isKnownNonZero(const SCEV *S)
Test if the given expression is known to be non-zero.
LLVM_ABI const SCEV * getBackedgeTakenCount(const Loop *L, ExitCountKind Kind=Exact)
If the specified loop has a predictable backedge-taken count, return it, otherwise return a SCEVCould...
LLVM_ABI const SCEV * getConstant(ConstantInt *V)
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
LLVM_ABI bool isKnownPositive(const SCEV *S)
Test if the given expression is known to be positive.
LLVM_ABI void forgetTopmostLoop(const Loop *L)
LLVM_ABI void forgetBlockAndLoopDispositions(Value *V=nullptr)
Called when the client has changed the disposition of values in a loop or block.
LLVM_ABI const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI void forgetLcssaPhiWithNewPredecessor(Loop *L, PHINode *V)
Forget LCSSA phi node V of loop L to which a new predecessor was added, such that it may no longer be...
LLVM_ABI std::optional< MonotonicPredicateType > getMonotonicPredicateType(const SCEVAddRecExpr *LHS, ICmpInst::Predicate Pred)
If, for all loop invariant X, the predicate "LHS `Pred` X" is monotonically increasing or decreasing,...
LLVM_ABI const SCEV * applyLoopGuards(const SCEV *Expr, const Loop *L)
Try to apply information from loop guards for L to Expr.
LLVM_ABI std::optional< bool > evaluatePredicate(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS)
Check whether the condition described by Pred, LHS, and RHS is true or false.
LLVM_ABI const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI bool isKnownPredicate(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS)
Test if the given expression is known to satisfy the condition described by Pred, LHS,...
This class represents the LLVM 'select' instruction.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool isIntegerTy() const
True if this is an instance of IntegerType.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
self_iterator getIterator()
@ BasicBlock
Various leaf nodes.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
class_match< BasicBlock > m_BasicBlock()
Match an arbitrary basic block value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
cst_pred_ty< is_one > m_scev_One()
Match an integer 1.
specificloop_ty m_SpecificLoop(const Loop *L)
SCEVAffineAddRec_match< Op0_t, Op1_t, class_match< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
bool match(const SCEV *S, const Pattern &P)
class_match< const SCEV > m_SCEV()
initializer< Ty > init(const Ty &Val)
NodeAddr< PhiNode * > Phi
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE, AssumptionCache *AC, MemorySSAUpdater *MSSAU, bool PreserveLCSSA)
Simplify each loop in a loop nest recursively.
FunctionAddr VTableAddr Value
LLVM_ABI std::optional< unsigned > getLoopEstimatedTripCount(Loop *L, unsigned *EstimatedLoopInvocationWeight=nullptr)
Return either:
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
static cl::opt< bool > DisableAdvancedPeeling("disable-advanced-peeling", cl::init(false), cl::Hidden, cl::desc("Disable advance peeling. Issues for convergent targets (D134803)."))
static cl::opt< bool > UnrollAllowPeeling("unroll-allow-peeling", cl::init(true), cl::Hidden, cl::desc("Allows loops to be peeled when the dynamic " "trip count is known to be low."))
LLVM_ABI bool IsBlockFollowedByDeoptOrUnreachable(const BasicBlock *BB)
Check if we can prove that all paths starting from this block converge to a block that either has a @...
static cl::opt< bool > EnablePeelingForIV("enable-peeling-for-iv", cl::init(false), cl::Hidden, cl::desc("Enable peeling to convert Phi nodes into IVs"))
LLVM_ABI BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, bool MapAtoms=true)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
bool canPeel(const Loop *L)
Definition LoopPeel.cpp:95
bool canPeelLastIteration(const Loop &L, ScalarEvolution &SE)
Returns true if the last iteration of L can be peeled off.
Definition LoopPeel.cpp:476
LLVM_ABI void addStringMetadataToLoop(Loop *TheLoop, const char *MDString, unsigned V=0)
Set input string into loop metadata by keeping other values intact.
LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected, bool ElideAllZero=false)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
static const char * PeeledCountMetaData
Definition LoopPeel.cpp:89
DomTreeNodeBase< BasicBlock > DomTreeNode
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
TargetTransformInfo::PeelingPreferences gatherPeelingPreferences(Loop *L, ScalarEvolution &SE, const TargetTransformInfo &TTI, std::optional< bool > UserAllowPeeling, std::optional< bool > UserAllowProfileBasedPeeling, bool UnrollingSpecficValues=false)
Definition LoopPeel.cpp:1054
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void computePeelCount(Loop *L, unsigned LoopSize, TargetTransformInfo::PeelingPreferences &PP, unsigned TripCount, DominatorTree &DT, ScalarEvolution &SE, const TargetTransformInfo &TTI, AssumptionCache *AC=nullptr, unsigned Threshold=UINT_MAX)
Definition LoopPeel.cpp:748
LLVM_ABI cl::opt< unsigned > SCEVCheapExpansionBudget
BranchProbability getLoopProbability(Loop *L)
Based on branch weight metadata, return either:
static cl::opt< unsigned > UnrollForcePeelCount("unroll-force-peel-count", cl::init(0), cl::Hidden, cl::desc("Force a peel count regardless of profiling information."))
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI std::optional< int > getOptionalIntLoopAttribute(const Loop *TheLoop, StringRef Name)
Find named metadata for a loop with an integer value.
bool setLoopProbability(Loop *L, BranchProbability P)
Set branch weight metadata for the latch of L to indicate that, at the end of any iteration,...
static cl::opt< bool > UnrollAllowLoopNestsPeeling("unroll-allow-loop-nests-peeling", cl::init(false), cl::Hidden, cl::desc("Allows loop nests to be peeled."))
static cl::opt< unsigned > UnrollPeelMaxCount("unroll-peel-max-count", cl::init(7), cl::Hidden, cl::desc("Max average trip count which will cause loop peeling."))
LLVM_ABI void cloneAndAdaptNoAliasScopes(ArrayRef< MDNode * > NoAliasDeclScopes, ArrayRef< BasicBlock * > NewBlocks, LLVMContext &Context, StringRef Ext)
Clone the specified noalias decl scopes.
LLVM_ABI void remapInstructionsInBlocks(ArrayRef< BasicBlock * > Blocks, ValueToValueMapTy &VMap)
Remaps instructions in Blocks using the mapping in VMap.
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
LLVM_ABI bool isDereferenceablePointer(const Value *V, Type *Ty, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Return true if this is always a dereferenceable pointer.
LLVM_ABI bool setLoopEstimatedTripCount(Loop *L, unsigned EstimatedTripCount, std::optional< unsigned > EstimatedLoopInvocationWeight=std::nullopt)
Set llvm.loop.estimated_trip_count with the value EstimatedTripCount in the loop metadata of L.
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="", bool Before=false)
Split the specified block at the specified instruction.
cl::opt< bool > ProfcheckDisableMetadataFixes("profcheck-disable-metadata-fixes", cl::Hidden, cl::init(false), cl::desc("Disable metadata propagation fixes discovered through Issue #147390"))
LLVM_ABI void identifyNoAliasScopesToClone(ArrayRef< BasicBlock * > BBs, SmallVectorImpl< MDNode * > &NoAliasDeclScopes)
Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified basic blocks and extract ...
LLVM_ABI BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
LLVM_ABI bool formLCSSA(Loop &L, const DominatorTree &DT, const LoopInfo *LI, ScalarEvolution *SE)
Put loop into LCSSA form.
bool peelLoop(Loop *L, unsigned PeelCount, bool PeelLast, LoopInfo *LI, ScalarEvolution *SE, DominatorTree &DT, AssumptionCache *AC, bool PreserveLCSSA, ValueToValueMapTy &VMap)
VMap is the value-map that maps instructions from the original loop to instructions in the last peele...
Definition LoopPeel.cpp:1099
static cl::opt< unsigned > UnrollPeelCount("unroll-peel-count", cl::Hidden, cl::desc("Set the unroll peeling count, for testing purposes"))
LLVM_ABI Loop * cloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM, LoopInfo *LI, LPPassManager *LPM)
Recursively clone the specified loop and all of its children, mapping the blocks with the specified m...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool AllowPeeling
Allow peeling off loop iterations.
bool AllowLoopNestsPeeling
Allow peeling off loop iterations for loop nests.
bool PeelLast
Peel off the last PeelCount loop iterations.
bool PeelProfiledIterations
Allow peeling basing on profile.
unsigned PeelCount
A forced peeling factor (the number of bodied of the original loop that should be peeled off before t...