LLVM: lib/Transforms/Scalar/LICM.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
86#include
87#include
88using namespace llvm;
89
90namespace llvm {
92}
93
94#define DEBUG_TYPE "licm"
95
96STATISTIC(NumCreatedBlocks, "Number of blocks created");
97STATISTIC(NumClonedBranches, "Number of branches cloned");
98STATISTIC(NumSunk, "Number of instructions sunk out of loop");
99STATISTIC(NumHoisted, "Number of instructions hoisted out of loop");
100STATISTIC(NumMovedLoads, "Number of load insts hoisted or sunk");
101STATISTIC(NumMovedCalls, "Number of call insts hoisted or sunk");
102STATISTIC(NumPromotionCandidates, "Number of promotion candidates");
103STATISTIC(NumLoadPromoted, "Number of load-only promotions");
104STATISTIC(NumLoadStorePromoted, "Number of load and store promotions");
106 "Number of min/max expressions hoisted out of the loop");
108 "Number of geps reassociated and hoisted out of the loop");
109STATISTIC(NumAddSubHoisted, "Number of add/subtract expressions reassociated "
110 "and hoisted out of the loop");
111STATISTIC(NumFPAssociationsHoisted, "Number of invariant FP expressions "
112 "reassociated and hoisted out of the loop");
114 "Number of invariant int expressions "
115 "reassociated and hoisted out of the loop");
116STATISTIC(NumBOAssociationsHoisted, "Number of invariant BinaryOp expressions "
117 "reassociated and hoisted out of the loop");
118
119
122 cl::desc("Disable memory promotion in LICM pass"));
123
126 cl::desc("Enable control flow (and PHI) hoisting in LICM"));
127
130 cl::desc("Force thread model single in LICM pass"));
131
134 cl::desc("Max num uses visited for identifying load "
135 "invariance in loop using invariant start (default = 8)"));
136
140 "Set upper limit for the number of transformations performed "
141 "during a single round of hoisting the reassociated expressions."));
142
146 "Set upper limit for the number of transformations performed "
147 "during a single round of hoisting the reassociated expressions."));
148
149
150
151
152
153
154
155
156
159 cl::desc("Enable imprecision in LICM in pathological cases, in exchange "
160 "for faster compile. Caps the MemorySSA clobbering calls."));
161
162
163
164
167 cl::desc("[LICM & MemorySSA] When MSSA in LICM is disabled, this has no "
168 "effect. When MSSA in LICM is enabled, then this is the maximum "
169 "number of accesses allowed to be present in a loop in order to "
170 "enable memory promotion."));
171
176 bool &FoldableInLoop, bool LoopNestMode);
192 bool InvariantGroup);
195
203
206
210
214 std::pair<SmallSetVector<Value *, 8>, bool>;
217
218namespace {
219struct LoopInvariantCodeMotion {
224
225 LoopInvariantCodeMotion(unsigned LicmMssaOptCap,
226 unsigned LicmMssaNoAccForPromotionCap,
227 bool LicmAllowSpeculation)
228 : LicmMssaOptCap(LicmMssaOptCap),
229 LicmMssaNoAccForPromotionCap(LicmMssaNoAccForPromotionCap),
230 LicmAllowSpeculation(LicmAllowSpeculation) {}
231
232private:
233 unsigned LicmMssaOptCap;
234 unsigned LicmMssaNoAccForPromotionCap;
235 bool LicmAllowSpeculation;
236};
237
238struct LegacyLICMPass : public LoopPass {
239 static char ID;
240 LegacyLICMPass(
243 bool LicmAllowSpeculation = true)
244 : LoopPass(ID), LICM(LicmMssaOptCap, LicmMssaNoAccForPromotionCap,
245 LicmAllowSpeculation) {
247 }
248
250 if (skipLoop(L))
251 return false;
252
253 LLVM_DEBUG(dbgs() << "Perform LICM on Loop with header at block "
254 << L->getHeader()->getNameOrAsOperand() << "\n");
255
256 Function *F = L->getHeader()->getParent();
257
258 auto *SE = getAnalysisIfAvailable();
259 MemorySSA *MSSA = &getAnalysis().getMSSA();
260
261
262
264 return LICM.runOnLoop(
265 L, &getAnalysis().getAAResults(),
266 &getAnalysis().getLoopInfo(),
267 &getAnalysis().getDomTree(),
268 &getAnalysis().getAssumptionCache(*F),
269 &getAnalysis().getTLI(*F),
270 &getAnalysis().getTTI(*F),
271 SE ? &SE->getSE() : nullptr, MSSA, &ORE);
272 }
273
274
275
276
277 void getAnalysisUsage(AnalysisUsage &AU) const override {
289 }
290
291private:
292 LoopInvariantCodeMotion LICM;
293};
294}
295
298 if (!AR.MSSA)
300 false);
301
302
303
304
306
309 if (!LICM.runOnLoop(&L, &AR.AA, &AR.LI, &AR.DT, &AR.AC, &AR.TLI, &AR.TTI,
312
315
316 return PA;
317}
318
322 OS, MapClassName2PassName);
323
324 OS << '<';
326 OS << '>';
327}
328
332 if (!AR.MSSA)
334 false);
335
336
337
338
340
343
345 bool Changed = LICM.runOnLoop(&OutermostLoop, &AR.AA, &AR.LI, &AR.DT, &AR.AC,
346 &AR.TLI, &AR.TTI, &AR.SE, AR.MSSA, &ORE, true);
347
348 if (!Changed)
350
352
356
357 return PA;
358}
359
363 OS, MapClassName2PassName);
364
365 OS << '<';
367 OS << '>';
368}
369
370char LegacyLICMPass::ID = 0;
372 false, false)
380
382
386 IsSink, L, MSSA) {}
387
389 unsigned LicmMssaOptCap, unsigned LicmMssaNoAccForPromotionCap, bool IsSink,
391 : LicmMssaOptCap(LicmMssaOptCap),
392 LicmMssaNoAccForPromotionCap(LicmMssaNoAccForPromotionCap),
393 IsSink(IsSink) {
394 unsigned AccessCapCount = 0;
395 for (auto *BB : L.getBlocks())
397 for (const auto &MA : *Accesses) {
398 (void)MA;
399 ++AccessCapCount;
402 return;
403 }
404 }
405}
406
407
408
409
416 bool LoopNestMode) {
417 bool Changed = false;
418
419 assert(L->isLCSSAForm(*DT) && "Loop is not in LCSSA form.");
420
421
422
424 return false;
425 }
426
427
428
429
430
431
432
433
434
435
437 return llvm::any_of(*BB, [](Instruction &I) {
438 IntrinsicInst *II = dyn_cast(&I);
439 return II && II->getIntrinsicID() == Intrinsic::coro_suspend;
440 });
441 });
442
445 true, *L, *MSSA);
446
447
448 BasicBlock *Preheader = L->getLoopPreheader();
449
450
453
454
455
456
457
458
459
460
461
462
463 if (L->hasDedicatedExits())
464 Changed |=
465 LoopNestMode
467 TLI, TTI, L, MSSAU, &SafetyInfo, Flags, ORE)
469 MSSAU, &SafetyInfo, Flags, ORE);
470 Flags.setIsSink(false);
471 if (Preheader)
472 Changed |= hoistRegion(DT->getNode(L->getHeader()), AA, LI, DT, AC, TLI, L,
473 MSSAU, SE, &SafetyInfo, Flags, ORE, LoopNestMode,
474 LicmAllowSpeculation);
475
476
477
478
479
480
481
482
484 .tooManyMemoryAccesses() && !HasCoroSuspendInst) {
485
487 L->getUniqueExitBlocks(ExitBlocks);
488
489
491 return isa(Exit->getTerminator());
492 });
493
494 if (!HasCatchSwitch) {
498 MSSAInsertPts.reserve(ExitBlocks.size());
499 for (BasicBlock *ExitBlock : ExitBlocks) {
500 InsertPts.push_back(ExitBlock->getFirstInsertionPt());
501 MSSAInsertPts.push_back(nullptr);
502 }
503
505
506
507
508 bool Promoted = false;
509 bool LocalPromoted;
510 do {
511 LocalPromoted = false;
512 for (auto [PointerMustAliases, HasReadsOutsideSet] :
515 PointerMustAliases, ExitBlocks, InsertPts, MSSAInsertPts, PIC, LI,
516 DT, AC, TLI, TTI, L, MSSAU, &SafetyInfo, ORE,
517 LicmAllowSpeculation, HasReadsOutsideSet);
518 }
519 Promoted |= LocalPromoted;
520 } while (LocalPromoted);
521
522
523
524
525
526
527
528 if (Promoted)
530
531 Changed |= Promoted;
532 }
533 }
534
535
536
537
538 assert(L->isLCSSAForm(*DT) && "Loop not left in LCSSA form after LICM!");
539 assert((L->isOutermost() || L->getParentLoop()->isLCSSAForm(*DT)) &&
540 "Parent loop not left in LCSSA form after LICM!");
541
544
545 if (Changed && SE)
547 return Changed;
548}
549
550
551
552
553
554
561
562
563 assert(N != nullptr && AA != nullptr && LI != nullptr && DT != nullptr &&
564 CurLoop != nullptr && SafetyInfo != nullptr &&
565 "Unexpected input to sinkRegion.");
566
567
568
569
572
573 bool Changed = false;
575
577 continue;
578
581
582
583
585 LLVM_DEBUG(dbgs() << "LICM deleting dead inst: " << I << '\n');
588 ++II;
590 Changed = true;
591 continue;
592 }
593
594
595
596
597
598
599 bool FoldableInLoop = false;
600 bool LoopNestMode = OutermostLoop != nullptr;
601 if (.mayHaveSideEffects() &&
603 SafetyInfo, TTI, FoldableInLoop,
604 LoopNestMode) &&
606 if (sink(I, LI, DT, CurLoop, SafetyInfo, MSSAU, ORE)) {
607 if (!FoldableInLoop) {
608 ++II;
611 }
612 Changed = true;
613 }
614 }
615 }
616 }
619 return Changed;
620}
621
629
630 bool Changed = false;
632 Worklist.insert(CurLoop);
634 while (!Worklist.empty()) {
637 MSSAU, SafetyInfo, Flags, ORE, CurLoop);
638 }
639 return Changed;
640}
641
642namespace {
643
644
645
646
647
648
649
650class ControlFlowHoister {
651private:
652
655 Loop *CurLoop;
657
658
659
661
662
663
665
666public:
669 : LI(LI), DT(DT), CurLoop(CurLoop), MSSAU(MSSAU) {}
670
671 void registerPossiblyHoistableBranch(BranchInst *BI) {
672
675 return;
676
677
678
679
682 if (!CurLoop->contains(TrueDest) || !CurLoop->contains(FalseDest) ||
683 TrueDest == FalseDest)
684 return;
685
686
687
688
689
690
695 if (TrueDestSucc.count(FalseDest)) {
696 CommonSucc = FalseDest;
697 } else if (FalseDestSucc.count(TrueDest)) {
698 CommonSucc = TrueDest;
699 } else {
701
702 if (TrueDestSucc.size() == 1)
703 CommonSucc = *TrueDestSucc.begin();
704
705
706
707 else if (!TrueDestSucc.empty()) {
709 auto IsSucc = [&](BasicBlock &BB) { return TrueDestSucc.count(&BB); };
711 assert(It != F->end() && "Could not find successor in function");
712 CommonSucc = &*It;
713 }
714 }
715
716
717
718
719
720
721
722
723 if (CommonSucc && DT->dominates(BI, CommonSucc))
724 HoistableBranches[BI] = CommonSucc;
725 }
726
727 bool canHoistPHI(PHINode *PN) {
728
730 return false;
731
732
736 PredecessorBlocks.insert(PredBB);
737
738
739
740
741
743 return false;
744 for (auto &Pair : HoistableBranches) {
745 if (Pair.second == BB) {
746
747
748 if (Pair.first->getSuccessor(0) == BB) {
749 PredecessorBlocks.erase(Pair.first->getParent());
750 PredecessorBlocks.erase(Pair.first->getSuccessor(1));
751 } else if (Pair.first->getSuccessor(1) == BB) {
752 PredecessorBlocks.erase(Pair.first->getParent());
753 PredecessorBlocks.erase(Pair.first->getSuccessor(0));
754 } else {
755 PredecessorBlocks.erase(Pair.first->getSuccessor(0));
756 PredecessorBlocks.erase(Pair.first->getSuccessor(1));
757 }
758 }
759 }
760
761
762 return PredecessorBlocks.empty();
763 }
764
768
769 if (HoistDestinationMap.count(BB))
770 return HoistDestinationMap[BB];
771
772
773 auto HasBBAsSuccessor =
775 return BB != Pair.second && (Pair.first->getSuccessor(0) == BB ||
776 Pair.first->getSuccessor(1) == BB);
777 };
778 auto It = llvm::find_if(HoistableBranches, HasBBAsSuccessor);
779
780
782 if (It == HoistableBranches.end()) {
785 << " as hoist destination for "
787 HoistDestinationMap[BB] = InitialPreheader;
788 return InitialPreheader;
789 }
791 assert(std::find_if(++It, HoistableBranches.end(), HasBBAsSuccessor) ==
792 HoistableBranches.end() &&
793 "BB is expected to be the target of at most one branch");
794
798 BasicBlock *CommonSucc = HoistableBranches[BI];
800
801
802 auto CreateHoistedBlock = [&](BasicBlock *Orig) {
803 if (HoistDestinationMap.count(Orig))
804 return HoistDestinationMap[Orig];
807 HoistDestinationMap[Orig] = New;
811 ++NumCreatedBlocks;
813 << " as hoist destination for " << Orig->getName()
814 << "\n");
815 return New;
816 };
817 BasicBlock *HoistTrueDest = CreateHoistedBlock(TrueDest);
818 BasicBlock *HoistFalseDest = CreateHoistedBlock(FalseDest);
819 BasicBlock *HoistCommonSucc = CreateHoistedBlock(CommonSucc);
820
821
823
824
826 assert(TargetSucc && "Expected hoist target to have a single successor");
827 HoistCommonSucc->moveBefore(TargetSucc);
829 }
831 HoistTrueDest->moveBefore(HoistCommonSucc);
833 }
835 HoistFalseDest->moveBefore(HoistCommonSucc);
837 }
838
839
840
841 if (HoistTarget == InitialPreheader) {
842
846
850
851
852 for (auto &Pair : HoistDestinationMap)
853 if (Pair.second == InitialPreheader && Pair.first != BI->getParent())
854 Pair.second = HoistCommonSucc;
855 }
856
857
861 ++NumClonedBranches;
862
864 "Hoisting blocks should not have destroyed preheader");
865 return HoistDestinationMap[BB];
866 }
867};
868}
869
870
871
872
873
874
882 bool AllowSpeculation) {
883
884 assert(N != nullptr && AA != nullptr && LI != nullptr && DT != nullptr &&
885 CurLoop != nullptr && SafetyInfo != nullptr &&
886 "Unexpected input to hoistRegion.");
887
888 ControlFlowHoister CFH(LI, DT, CurLoop, MSSAU);
889
890
891
893
894
895
896
899 bool Changed = false;
902
903
904 if (!LoopNestMode && inSubLoop(BB, CurLoop, LI))
905 continue;
906
908
909
910
911
912
913
914
918 I, DT, TLI, CurLoop, SafetyInfo, ORE,
919 Preheader->getTerminator(), AC, AllowSpeculation)) {
920 hoist(I, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB), SafetyInfo,
921 MSSAU, SE, ORE);
923 Changed = true;
924 continue;
925 }
926
927
928
929 if (I.getOpcode() == Instruction::FDiv && I.hasAllowReciprocal() &&
931 auto Divisor = I.getOperand(1);
932 auto One = llvm::ConstantFP::get(Divisor->getType(), 1.0);
933 auto ReciprocalDivisor = BinaryOperator::CreateFDiv(One, Divisor);
934 ReciprocalDivisor->setFastMathFlags(I.getFastMathFlags());
936 ReciprocalDivisor->insertBefore(&I);
937 ReciprocalDivisor->setDebugLoc(I.getDebugLoc());
938
939 auto Product =
940 BinaryOperator::CreateFMul(I.getOperand(0), ReciprocalDivisor);
941 Product->setFastMathFlags(I.getFastMathFlags());
943 Product->insertAfter(&I);
944 Product->setDebugLoc(I.getDebugLoc());
945 I.replaceAllUsesWith(Product);
947
948 hoist(*ReciprocalDivisor, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB),
949 SafetyInfo, MSSAU, SE, ORE);
950 HoistedInstructions.push_back(ReciprocalDivisor);
951 Changed = true;
952 continue;
953 }
954
955 auto IsInvariantStart = [&](Instruction &I) {
956 using namespace PatternMatch;
957 return I.use_empty() &&
958 match(&I, m_IntrinsicIntrinsic::invariant\_start());
959 };
960 auto MustExecuteWithoutWritesBefore = [&](Instruction &I) {
963 };
964 if ((IsInvariantStart(I) || isGuard(&I)) &&
966 MustExecuteWithoutWritesBefore(I)) {
967 hoist(I, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB), SafetyInfo,
968 MSSAU, SE, ORE);
970 Changed = true;
971 continue;
972 }
973
974 if (PHINode *PN = dyn_cast(&I)) {
975 if (CFH.canHoistPHI(PN)) {
976
977
981 hoist(*PN, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB), SafetyInfo,
982 MSSAU, SE, ORE);
983 assert(DT->dominates(PN, BB) && "Conditional PHIs not expected");
984 Changed = true;
985 continue;
986 }
987 }
988
989
990
992 Changed = true;
993 continue;
994 }
995
996
997
998 if (BranchInst *BI = dyn_cast(&I))
999 CFH.registerPossiblyHoistableBranch(BI);
1000 }
1001 }
1002
1003
1004
1005
1006
1007
1008
1009
1014 [&](Use &U) { return DT->dominates(I, U); })) {
1017 if (!HoistPoint || !DT->dominates(HoistPoint->getParent(), Dominator)) {
1018 if (HoistPoint)
1020 "New hoist point expected to dominate old hoist point");
1022 }
1024 << HoistPoint->getParent()->getNameOrAsOperand()
1025 << ": " << *I << "\n");
1027 SE);
1028 HoistPoint = I;
1029 Changed = true;
1030 }
1031 }
1032 }
1035
1036
1037
1038#ifdef EXPENSIVE_CHECKS
1039 if (Changed) {
1040 assert(DT->verify(DominatorTree::VerificationLevel::Fast) &&
1041 "Dominator tree verification failed");
1043 }
1044#endif
1045
1046 return Changed;
1047}
1048
1049
1050
1051
1052
1054 Loop *CurLoop) {
1057 const TypeSize LocSizeInBits = DL.getTypeSizeInBits(LI->getType());
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1069 return false;
1070
1071
1072
1073 if (isa(Addr))
1074 return false;
1075
1076 unsigned UsesVisited = 0;
1077
1078
1079 for (auto *U : Addr->users()) {
1080
1082 return false;
1084
1085
1086 if ( || II->getIntrinsicID() != Intrinsic::invariant_start ||
1087 ->use_empty())
1088 continue;
1089 ConstantInt *InvariantSize = cast(II->getArgOperand(0));
1090
1091
1093 continue;
1095
1096
1097
1098
1099 if (LocSizeInBits.getFixedValue() <= InvariantSizeInBits &&
1101 return true;
1102 }
1103
1104 return false;
1105}
1106
1107namespace {
1108
1109
1110
1111bool isHoistableAndSinkableInst(Instruction &I) {
1112
1113 return (isa(I) || isa(I) || isa(I) ||
1114 isa(I) || isa(I) || isa(I) ||
1120}
1121
1123 for (auto *BB : L->getBlocks())
1125 return false;
1126 return true;
1127}
1128
1129
1132 for (auto *BB : L->getBlocks())
1134 int NotAPhi = 0;
1135 for (const auto &Acc : *Accs) {
1136 if (isa(&Acc))
1137 continue;
1138 const auto *MUD = cast(&Acc);
1139 if (MUD->getMemoryInst() != I || NotAPhi++ == 1)
1140 return false;
1141 }
1142 }
1143 return true;
1144}
1145}
1146
1151
1152 if (Flags.tooManyClobberingCalls())
1154
1157 Flags.incrementClobberingCalls();
1158 return Source;
1159}
1160
1163 bool TargetExecutesOncePerLoop,
1166
1167 if (!isHoistableAndSinkableInst(I))
1168 return false;
1169
1171
1172 if (LoadInst *LI = dyn_cast(&I)) {
1173 if (!LI->isUnordered())
1174 return false;
1175
1176
1177
1179 return true;
1180 if (LI->hasMetadata(LLVMContext::MD_invariant_load))
1181 return true;
1182
1183 if (LI->isAtomic() && !TargetExecutesOncePerLoop)
1184 return false;
1185
1186
1188 return true;
1189
1191
1192 bool InvariantGroup = LI->hasMetadata(LLVMContext::MD_invariant_group);
1193
1195 MSSA, MU, CurLoop, I, Flags, InvariantGroup);
1196
1197
1199 ORE->emit([&]() {
1201 DEBUG_TYPE, "LoadWithLoopInvariantAddressInvalidated", LI)
1202 << "failed to move load with loop-invariant address "
1203 "because the loop may invalidate its value";
1204 });
1205
1207 } else if (CallInst *CI = dyn_cast(&I)) {
1208
1209 if (isa(I))
1210 return false;
1211
1212
1213 if (CI->mayThrow())
1214 return false;
1215
1216
1217
1218
1219
1220 if (CI->isConvergent())
1221 return false;
1222
1223
1224
1225
1226
1227
1228 if (CI->getFunction()->isPresplitCoroutine())
1229 return false;
1230
1231 using namespace PatternMatch;
1232 if (match(CI, m_IntrinsicIntrinsic::assume()))
1233
1234 return true;
1235
1236
1238
1240 return true;
1242
1243
1244
1246
1247 for (Value *Op : CI->args())
1248 if (Op->getType()->isPointerTy() &&
1250 MSSA, cast(MSSA->getMemoryAccess(CI)), CurLoop, I,
1251 Flags, false))
1252 return false;
1253 return true;
1254 }
1255
1256
1257
1258 if (isReadOnly(MSSAU, CurLoop))
1259 return true;
1260 }
1261
1262
1263
1264
1265 return false;
1266 } else if (auto *FI = dyn_cast(&I)) {
1267
1268
1269 return isOnlyMemoryAccess(FI, CurLoop, MSSAU);
1270 } else if (auto *SI = dyn_cast(&I)) {
1271 if (!SI->isUnordered())
1272 return false;
1273
1274
1275
1276
1277
1278
1279 if (isOnlyMemoryAccess(SI, CurLoop, MSSAU))
1280 return true;
1281
1282
1283 if (Flags.tooManyMemoryAccesses())
1284 return false;
1285
1289
1291 CurLoop->contains(Source->getBlock()))
1292 return false;
1293
1294
1295
1296
1297
1298
1299 for (auto *BB : CurLoop->getBlocks())
1301 for (const auto &MA : *Accesses)
1302 if (const auto *MU = dyn_cast(&MA)) {
1306 CurLoop->contains(MD->getBlock()))
1307 return false;
1308
1309
1310
1311
1312 if (!Flags.getIsSink() && !MSSA->dominates(SIMD, MU))
1313 return false;
1314 } else if (const auto *MD = dyn_cast(&MA)) {
1315 if (auto *LI = dyn_cast(MD->getMemoryInst())) {
1316 (void)LI;
1317 assert(!LI->isUnordered() && "Expected unordered load");
1318 return false;
1319 }
1320
1321 if (auto *CI = dyn_cast(MD->getMemoryInst())) {
1322
1323
1324
1327 return false;
1328 }
1329 }
1330 }
1331 return true;
1332 }
1333
1334 assert(.mayReadOrWriteMemory() && "unhandled aliasing");
1335
1336
1337
1338 return true;
1339}
1340
1341
1342
1343
1344
1345
1348 if (IncValue != &I)
1349 return false;
1350
1351 return true;
1352}
1353
1354
1357 if (auto *GEP = dyn_cast(&I)) {
1361 return false;
1362
1363
1364
1366 for (const User *U : GEP->users()) {
1367 const Instruction *UI = cast(U);
1368 if (CurLoop->contains(UI) &&
1370 (!isa(UI) && !isa(UI))))
1371 return false;
1372 }
1373 return true;
1374 }
1375
1376 return false;
1377}
1378
1379
1380
1381
1382
1383
1384
1388 bool &FoldableInLoop, bool LoopNestMode) {
1389 const auto &BlockColors = SafetyInfo->getBlockColors();
1391 for (const User *U : I.users()) {
1392 const Instruction *UI = cast(U);
1393 if (const PHINode *PN = dyn_cast(UI)) {
1395
1397 return false;
1398
1399
1400
1401 if (isa(I))
1402 if (!BlockColors.empty() &&
1403 BlockColors.find(const_cast<BasicBlock *>(BB))->second.size() != 1)
1404 return false;
1405
1406 if (LoopNestMode) {
1407 while (isa(UI) && UI->hasOneUser() &&
1410 break;
1411 UI = cast(UI->user_back());
1412 }
1413 }
1414 }
1415
1416 if (CurLoop->contains(UI)) {
1417 if (IsFoldable) {
1418 FoldableInLoop = true;
1419 continue;
1420 }
1421 return false;
1422 }
1423 }
1424 return true;
1425}
1426
1431 if (auto *CI = dyn_cast(&I)) {
1432 const auto &BlockColors = SafetyInfo->getBlockColors();
1433
1434
1435
1436
1438 for (unsigned BundleIdx = 0, BundleEnd = CI->getNumOperandBundles();
1439 BundleIdx != BundleEnd; ++BundleIdx) {
1440 OperandBundleUse Bundle = CI->getOperandBundleAt(BundleIdx);
1442 continue;
1443
1445 }
1446
1447 if (!BlockColors.empty()) {
1448 const ColorVector &CV = BlockColors.find(&ExitBlock)->second;
1449 assert(CV.size() == 1 && "non-unique color for exit block!");
1454 }
1455
1457 New->copyMetadata(*CI);
1458 } else {
1459 New = I.clone();
1460 }
1461
1463 if (.getName().empty())
1464 New->setName(I.getName() + ".le");
1465
1467
1468
1469
1472 false);
1473 if (NewMemAcc) {
1474 if (auto *MemDef = dyn_cast(NewMemAcc))
1475 MSSAU.insertDef(MemDef, true);
1476 else {
1477 auto *MemUse = cast(NewMemAcc);
1478 MSSAU.insertUse(MemUse, true);
1479 }
1480 }
1481 }
1482
1483
1484
1485
1486
1487
1488
1489
1490 for (Use &Op : New->operands())
1492 auto *OInst = cast(Op.get());
1495 OInst->getName() + ".lcssa");
1499 Op = OpPN;
1500 }
1501 return New;
1502}
1503
1508 I.eraseFromParent();
1509}
1510
1517 I.moveBefore(*Dest->getParent(), Dest);
1518 if (MemoryUseOrDef *OldMemAcc = cast_or_null(
1520 MSSAU.moveToPlace(OldMemAcc, Dest->getParent(),
1522 if (SE)
1524}
1525
1532 "Expect only trivially replaceable PHI");
1535 auto It = SunkCopies.find(ExitBlock);
1536 if (It != SunkCopies.end())
1537 New = It->second;
1538 else
1540 *I, *ExitBlock, *TPN, LI, SafetyInfo, MSSAU);
1541 return New;
1542}
1543
1547 return false;
1548
1549
1550
1551
1553 return false;
1555 if (isa(BBPred->getTerminator()))
1556 return false;
1557 }
1558 return true;
1559}
1560
1565#ifndef NDEBUG
1569 ExitBlocks.end());
1570#endif
1572 assert(ExitBlockSet.count(ExitBB) && "Expect the PHI is in an exit block.");
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606 const auto &BlockColors = SafetyInfo->getBlockColors();
1608 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
1609 while (!PredBBs.empty()) {
1612 "Expect all predecessors are in the loop");
1615 ExitBB, PredBB, ".split.loop.exit", &DTU, LI, MSSAU, true);
1616
1617
1618
1619 if (!BlockColors.empty())
1620
1621
1622
1623 SafetyInfo->copyColors(NewPred, PredBB);
1624 }
1625 PredBBs.remove(PredBB);
1626 }
1627}
1628
1629
1630
1631
1632
1633
1637 bool Changed = false;
1638 LLVM_DEBUG(dbgs() << "LICM sinking instruction: " << I << "\n");
1639
1640
1641
1644 auto *User = cast(*UI);
1645 Use &U = UI.getUse();
1646 ++UI;
1647
1649 continue;
1650
1653 Changed = true;
1654 continue;
1655 }
1656
1657
1659
1660
1661
1662
1666 Changed = true;
1667 continue;
1668 }
1669
1670 VisitedUsers.insert(PN);
1672 continue;
1673
1675 return Changed;
1676
1677
1678
1680
1681
1682
1683 UI = I.user_begin();
1684 UE = I.user_end();
1685 }
1686
1687 if (VisitedUsers.empty())
1688 return Changed;
1689
1690 ORE->emit([&]() {
1692 << "sinking " << ore::NV("Inst", &I);
1693 });
1694 if (isa(I))
1695 ++NumMovedLoads;
1696 else if (isa(I))
1697 ++NumMovedCalls;
1698 ++NumSunk;
1699
1700#ifndef NDEBUG
1704 ExitBlocks.end());
1705#endif
1706
1707
1709
1710
1711
1712
1713
1714
1716 for (auto *UI : Users) {
1717 auto *User = cast(UI);
1718
1720 continue;
1721
1724 "The LCSSA PHI is not in an exit block!");
1725
1726
1728 PN, &I, LI, SunkCopies, SafetyInfo, CurLoop, MSSAU);
1729
1730 New->dropLocation();
1733 Changed = true;
1734 }
1735 return Changed;
1736}
1737
1738
1739
1740
1746 << I << "\n");
1747 ORE->emit([&]() {
1750 });
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760 if ((I.hasMetadataOtherThanDebugLoc() || isa(I)) &&
1761
1762
1763
1765 I.dropUBImplyingAttrsAndMetadata();
1766
1767 if (isa(I))
1768
1770 else
1771
1773 MSSAU, SE);
1774
1775 I.updateLocationAfterHoist();
1776
1777 if (isa(I))
1778 ++NumMovedLoads;
1779 else if (isa(I))
1780 ++NumMovedCalls;
1781 ++NumHoisted;
1782}
1783
1784
1785
1786
1792 if (AllowSpeculation &&
1794 return true;
1795
1796 bool GuaranteedToExecute =
1798
1799 if (!GuaranteedToExecute) {
1800 auto *LI = dyn_cast(&Inst);
1801 if (LI && CurLoop->isLoopInvariant(LI->getPointerOperand()))
1802 ORE->emit([&]() {
1804 DEBUG_TYPE, "LoadWithLoopInvariantAddressCondExecuted", LI)
1805 << "failed to hoist load with loop-invariant address "
1806 "because load is conditionally executed";
1807 });
1808 }
1809
1810 return GuaranteedToExecute;
1811}
1812
1813namespace {
1815 Value *SomePtr;
1823 Align Alignment;
1824 bool UnorderedAtomic;
1827 bool CanInsertStoresInExitBlocks;
1829
1830
1831
1832
1835 return V;
1836
1838
1839
1841 I->getName() + ".lcssa");
1845 return PN;
1846 }
1847
1848public:
1854 Align Alignment, bool UnorderedAtomic, const AAMDNodes &AATags,
1855 ICFLoopSafetyInfo &SafetyInfo, bool CanInsertStoresInExitBlocks)
1857 LoopInsertPts(LIP), MSSAInsertPts(MSSAIP), PredCache(PIC), MSSAU(MSSAU),
1858 LI(li), DL(std::move(dl)), Alignment(Alignment),
1859 UnorderedAtomic(UnorderedAtomic), AATags(AATags),
1860 SafetyInfo(SafetyInfo),
1861 CanInsertStoresInExitBlocks(CanInsertStoresInExitBlocks), Uses(Insts) {}
1862
1863 void insertStoresInLoopExitBlocks() {
1864
1865
1866
1867
1869 for (unsigned i = 0, e = LoopExitBlocks.size(); i != e; ++i) {
1870 BasicBlock *ExitBlock = LoopExitBlocks[i];
1871 Value *LiveInValue = SSA.GetValueInMiddleOfBlock(ExitBlock);
1872 LiveInValue = maybeInsertLCSSAPHI(LiveInValue, ExitBlock);
1873 Value *Ptr = maybeInsertLCSSAPHI(SomePtr, ExitBlock);
1876 if (UnorderedAtomic)
1877 NewSI->setOrdering(AtomicOrdering::Unordered);
1880
1881
1882 if (i == 0) {
1883
1884
1885
1887 NewID = cast_or_null(
1888 NewSI->getMetadata(LLVMContext::MD_DIAssignID));
1889 } else {
1890
1891
1892 NewSI->setMetadata(LLVMContext::MD_DIAssignID, NewID);
1893 }
1894
1895 if (AATags)
1897
1898 MemoryAccess *MSSAInsertPoint = MSSAInsertPts[i];
1900 if (!MSSAInsertPoint) {
1903 } else {
1904 NewMemAcc =
1906 }
1907 MSSAInsertPts[i] = NewMemAcc;
1908 MSSAU.insertDef(cast(NewMemAcc), true);
1909
1910 }
1911 }
1912
1913 void doExtraRewritesBeforeFinalDeletion() override {
1914 if (CanInsertStoresInExitBlocks)
1915 insertStoresInLoopExitBlocks();
1916 }
1917
1918 void instructionDeleted(Instruction *I) const override {
1921 }
1922
1923 bool shouldDelete(Instruction *I) const override {
1924 if (isa(I))
1925 return CanInsertStoresInExitBlocks;
1926 return true;
1927 }
1928};
1929
1930bool isNotCapturedBeforeOrInLoop(const Value *V, const Loop *L,
1932
1933
1934
1935
1937 true,
1938 L->getHeader()->getTerminator(), DT);
1939}
1940
1941
1942
1943bool isNotVisibleOnUnwindInLoop(const Value *Object, const Loop *L,
1945 bool RequiresNoCaptureBeforeUnwind;
1947 return false;
1948
1949 return !RequiresNoCaptureBeforeUnwind ||
1950 isNotCapturedBeforeOrInLoop(Object, L, DT);
1951}
1952
1955
1956
1958 isNotCapturedBeforeOrInLoop(Object, L, DT)) ||
1960}
1961
1962}
1963
1964
1965
1966
1967
1968
1978 bool HasReadsOutsideSet) {
1979
1980 assert(LI != nullptr && DT != nullptr && CurLoop != nullptr &&
1981 SafetyInfo != nullptr &&
1982 "Unexpected Input to promoteLoopAccessesToScalars");
1983
1985 dbgs() << "Trying to promote set of must-aliased pointers:\n";
1986 for (Value *Ptr : PointerMustAliases)
1987 dbgs() << " " << *Ptr << "\n";
1988 });
1989 ++NumPromotionCandidates;
1990
1991 Value *SomePtr = *PointerMustAliases.begin();
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031 bool DereferenceableInPH = false;
2032 bool StoreIsGuanteedToExecute = false;
2033 bool LoadIsGuaranteedToExecute = false;
2034 bool FoundLoadToPromote = false;
2035
2036
2037 enum {
2038 StoreSafe,
2039 StoreUnsafe,
2040 StoreSafetyUnknown,
2041 } StoreSafety = StoreSafetyUnknown;
2042
2044
2045
2046
2047 Align Alignment;
2048
2049 bool SawUnorderedAtomic = false;
2050 bool SawNotAtomic = false;
2052
2054
2055
2056
2057 if (HasReadsOutsideSet)
2058 StoreSafety = StoreUnsafe;
2059
2060 if (StoreSafety == StoreSafetyUnknown && SafetyInfo->anyBlockMayThrow()) {
2061
2062
2063
2064
2065
2067 if (!isNotVisibleOnUnwindInLoop(Object, CurLoop, DT))
2068 StoreSafety = StoreUnsafe;
2069 }
2070
2071
2072
2073
2074 Type *AccessTy = nullptr;
2075 for (Value *ASIV : PointerMustAliases) {
2076 for (Use &U : ASIV->uses()) {
2077
2078 Instruction *UI = dyn_cast(U.getUser());
2079 if (!UI || !CurLoop->contains(UI))
2080 continue;
2081
2082
2083
2084 if (LoadInst *Load = dyn_cast(UI)) {
2085 if (!Load->isUnordered())
2086 return false;
2087
2088 SawUnorderedAtomic |= Load->isAtomic();
2089 SawNotAtomic |= !Load->isAtomic();
2090 FoundLoadToPromote = true;
2091
2092 Align InstAlignment = Load->getAlign();
2093
2094 if (!LoadIsGuaranteedToExecute)
2095 LoadIsGuaranteedToExecute =
2097
2098
2099
2100
2101
2102 if (!DereferenceableInPH || (InstAlignment > Alignment))
2104 *Load, DT, TLI, CurLoop, SafetyInfo, ORE,
2105 Preheader->getTerminator(), AC, AllowSpeculation)) {
2106 DereferenceableInPH = true;
2107 Alignment = std::max(Alignment, InstAlignment);
2108 }
2109 } else if (const StoreInst *Store = dyn_cast(UI)) {
2110
2111
2113 continue;
2114 if (!Store->isUnordered())
2115 return false;
2116
2117 SawUnorderedAtomic |= Store->isAtomic();
2118 SawNotAtomic |= !Store->isAtomic();
2119
2120
2121
2122
2123
2124
2125 Align InstAlignment = Store->getAlign();
2126 bool GuaranteedToExecute =
2128 StoreIsGuanteedToExecute |= GuaranteedToExecute;
2129 if (GuaranteedToExecute) {
2130 DereferenceableInPH = true;
2131 if (StoreSafety == StoreSafetyUnknown)
2132 StoreSafety = StoreSafe;
2133 Alignment = std::max(Alignment, InstAlignment);
2134 }
2135
2136
2137
2138
2139
2140
2141
2142 if (StoreSafety == StoreSafetyUnknown &&
2144 return DT->dominates(Store->getParent(), Exit);
2145 }))
2146 StoreSafety = StoreSafe;
2147
2148
2149
2150 if (!DereferenceableInPH) {
2152 Store->getPointerOperand(), Store->getValueOperand()->getType(),
2153 Store->getAlign(), MDL, Preheader->getTerminator(), AC, DT, TLI);
2154 }
2155 } else
2156 continue;
2157
2158 if (!AccessTy)
2161 return false;
2162
2163
2164 if (LoopUses.empty()) {
2165
2167 } else if (AATags) {
2169 }
2170
2172 }
2173 }
2174
2175
2176
2177
2178
2179 if (SawUnorderedAtomic && SawNotAtomic)
2180 return false;
2181
2182
2183
2184
2185 if (SawUnorderedAtomic && Alignment < MDL.getTypeStoreSize(AccessTy))
2186 return false;
2187
2188
2189 if (!DereferenceableInPH) {
2190 LLVM_DEBUG(dbgs() << "Not promoting: Not dereferenceable in preheader\n");
2191 return false;
2192 }
2193
2194
2195
2196
2197
2198 if (StoreSafety == StoreSafetyUnknown) {
2200 bool ExplicitlyDereferenceableOnly;
2201 if (isWritableObject(Object, ExplicitlyDereferenceableOnly) &&
2202 (!ExplicitlyDereferenceableOnly ||
2204 isThreadLocalObject(Object, CurLoop, DT, TTI))
2205 StoreSafety = StoreSafe;
2206 }
2207
2208
2209
2210 if (StoreSafety != StoreSafe && !FoundLoadToPromote)
2211
2212 return false;
2213
2214
2215 if (StoreSafety == StoreSafe) {
2216 LLVM_DEBUG(dbgs() << "LICM: Promoting load/store of the value: " << *SomePtr
2217 << '\n');
2218 ++NumLoadStorePromoted;
2219 } else {
2220 LLVM_DEBUG(dbgs() << "LICM: Promoting load of the value: " << *SomePtr
2221 << '\n');
2222 ++NumLoadPromoted;
2223 }
2224
2225 ORE->emit([&]() {
2227 LoopUses[0])
2228 << "Moving accesses to memory location out of the loop";
2229 });
2230
2231
2232 std::vector<DILocation *> LoopUsesLocs;
2233 for (auto *U : LoopUses)
2234 LoopUsesLocs.push_back(U->getDebugLoc().get());
2236
2237
2240 LoopPromoter Promoter(SomePtr, LoopUses, SSA, ExitBlocks, InsertPts,
2241 MSSAInsertPts, PIC, MSSAU, *LI, DL, Alignment,
2242 SawUnorderedAtomic,
2243 StoreIsGuanteedToExecute ? AATags : AAMDNodes(),
2244 *SafetyInfo, StoreSafety == StoreSafe);
2245
2246
2247
2248 LoadInst *PreheaderLoad = nullptr;
2249 if (FoundLoadToPromote || !StoreIsGuanteedToExecute) {
2250 PreheaderLoad =
2251 new LoadInst(AccessTy, SomePtr, SomePtr->getName() + ".promoted",
2253 if (SawUnorderedAtomic)
2257 if (AATags && LoadIsGuaranteedToExecute)
2259
2262 MemoryUse *NewMemUse = cast(PreheaderLoadMemoryAccess);
2263 MSSAU.insertUse(NewMemUse, true);
2264 SSA.AddAvailableValue(Preheader, PreheaderLoad);
2265 } else {
2267 }
2268
2271
2272
2273 Promoter.run(LoopUses);
2274
2277
2278 if (PreheaderLoad && PreheaderLoad->use_empty())
2280
2281 return true;
2282}
2283
2286 for (const BasicBlock *BB : L->blocks())
2288 for (const auto &Access : *Accesses)
2289 if (const auto *MUD = dyn_cast(&Access))
2290 Fn(MUD->getMemoryInst());
2291}
2292
2293
2294
2299
2300 auto IsPotentiallyPromotable = [L](const Instruction *I) {
2301 if (const auto *SI = dyn_cast(I))
2302 return L->isLoopInvariant(SI->getPointerOperand());
2303 if (const auto *LI = dyn_cast(I))
2304 return L->isLoopInvariant(LI->getPointerOperand());
2305 return false;
2306 };
2307
2308
2311 if (IsPotentiallyPromotable(I)) {
2312 AttemptingPromotion.insert(I);
2314 }
2315 });
2316
2317
2320 if (!AS.isForwardingAliasSet() && AS.isMod() && AS.isMustAlias())
2322
2323 if (Sets.empty())
2324 return {};
2325
2326
2328 if (AttemptingPromotion.contains(I))
2329 return;
2330
2332 ModRefInfo MR = Pair.getPointer()->aliasesUnknownInst(I, BatchAA);
2333
2334 if (isModSet(MR))
2335 return true;
2336 if (isRefSet(MR)) {
2337
2338 Pair.setInt(true);
2339
2340
2341 return !Pair.getPointer()->isRef();
2342 }
2343 return false;
2344 });
2345 });
2346
2348 for (auto [Set, HasReadsOutsideSet] : Sets) {
2350 for (const auto &MemLoc : *Set)
2351 PointerMustAliases.insert(const_cast<Value *>(MemLoc.Ptr));
2352 Result.emplace_back(std::move(PointerMustAliases), HasReadsOutsideSet);
2353 }
2354
2356}
2357
2361 bool InvariantGroup) {
2362
2363 if (!Flags.getIsSink()) {
2364
2365
2366
2367
2368
2369
2370
2371
2372
2376 CurLoop->contains(Source->getBlock()) &&
2377 !(InvariantGroup && Source->getBlock() == CurLoop->getHeader() && isa(Source));
2378 }
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397 if (Flags.tooManyMemoryAccesses())
2398 return true;
2399 for (auto *BB : CurLoop->getBlocks())
2401 return true;
2402
2405
2406 return false;
2407}
2408
2410 if (const auto *Accesses = MSSA.getBlockDefs(&BB))
2411 for (const auto &MA : *Accesses)
2412 if (const auto *MD = dyn_cast(&MA))
2414 return true;
2415 return false;
2416}
2417
2418
2419
2420
2424 using namespace PatternMatch;
2425 Value *Cond1, *Cond2;
2429
2430 } else
2431 return false;
2432
2436 return false;
2438 return false;
2440 return false;
2441 if (L.isLoopInvariant(LHS)) {
2444 }
2445 if (L.isLoopInvariant(LHS) || !L.isLoopInvariant(RHS))
2446 return false;
2449 return true;
2450 };
2452 Value *LHS1, *LHS2, *RHS1, *RHS2;
2453 if (!MatchICmpAgainstInvariant(Cond1, P1, LHS1, RHS1) ||
2454 !MatchICmpAgainstInvariant(Cond2, P2, LHS2, RHS2))
2455 return false;
2457 if (!MatchingPred || LHS1 != LHS2)
2458 return false;
2459
2460
2465 "Relational predicate is either less (or equal) or greater (or equal)!");
2467 ? (UseMin ? Intrinsic::smin : Intrinsic::smax)
2468 : (UseMin ? Intrinsic::umin : Intrinsic::umax);
2469 auto *Preheader = L.getLoopPreheader();
2470 assert(Preheader && "Loop is not in simplify form?");
2472
2473
2474
2475
2476 if (isa(I))
2479 id, RHS1, RHS2, nullptr,
2482 (UseMin ? "min" : "max"));
2489 I.replaceAllUsesWith(NewCond);
2491 eraseInstruction(*cast(Cond1), SafetyInfo, MSSAU);
2492 eraseInstruction(*cast(Cond2), SafetyInfo, MSSAU);
2493 return true;
2494}
2495
2496
2497
2501 auto *GEP = dyn_cast(&I);
2502 if ()
2503 return false;
2504
2505 auto *Src = dyn_cast(GEP->getPointerOperand());
2506 if (!Src || !Src->hasOneUse() || !L.contains(Src))
2507 return false;
2508
2509 Value *SrcPtr = Src->getPointerOperand();
2510 auto LoopInvariant = [&](Value *V) { return L.isLoopInvariant(V); };
2511 if (!L.isLoopInvariant(SrcPtr) || (GEP->indices(), LoopInvariant))
2512 return false;
2513
2514
2515
2516
2517
2518 if (all_of(Src->indices(), LoopInvariant))
2519 return false;
2520
2521
2522
2523
2527 };
2528 bool IsInBounds = Src->isInBounds() && GEP->isInBounds() &&
2531
2532 BasicBlock *Preheader = L.getLoopPreheader();
2534 Value *NewSrc = Builder.CreateGEP(GEP->getSourceElementType(), SrcPtr,
2536 "invariant.gep", IsInBounds);
2538 Value *NewGEP = Builder.CreateGEP(Src->getSourceElementType(), NewSrc,
2540 IsInBounds);
2541 GEP->replaceAllUsesWith(NewGEP);
2544 return true;
2545}
2546
2547
2548
2553 assert(!L.isLoopInvariant(VariantLHS) && "Precondition.");
2554 assert(L.isLoopInvariant(InvariantRHS) && "Precondition.");
2555
2557
2558
2559 using namespace PatternMatch;
2560 Value *VariantOp, *InvariantOp;
2561 if (IsSigned &&
2563 return false;
2564 if (!IsSigned &&
2566 return false;
2567
2568
2569
2570 if (L.isLoopInvariant(VariantOp))
2571 std::swap(VariantOp, InvariantOp);
2572 if (L.isLoopInvariant(VariantOp) || !L.isLoopInvariant(InvariantOp))
2573 return false;
2574
2575
2576
2577
2578
2579 auto &DL = L.getHeader()->getDataLayout();
2583 return false;
2584 if (!IsSigned &&
2587 return false;
2588 auto *Preheader = L.getLoopPreheader();
2589 assert(Preheader && "Loop is not in simplify form?");
2591 Value *NewCmpOp =
2592 Builder.CreateSub(InvariantRHS, InvariantOp, "invariant.op",
2593 !IsSigned, IsSigned);
2597 eraseInstruction(cast(*VariantLHS), SafetyInfo, MSSAU);
2598 return true;
2599}
2600
2601
2602
2603
2608 assert(!L.isLoopInvariant(VariantLHS) && "Precondition.");
2609 assert(L.isLoopInvariant(InvariantRHS) && "Precondition.");
2610
2612
2613
2614 using namespace PatternMatch;
2615 Value *VariantOp, *InvariantOp;
2616 if (IsSigned &&
2618 return false;
2619 if (!IsSigned &&
2621 return false;
2622
2623 bool VariantSubtracted = false;
2624
2625
2626
2627 if (L.isLoopInvariant(VariantOp)) {
2628 std::swap(VariantOp, InvariantOp);
2629 VariantSubtracted = true;
2631 }
2632 if (L.isLoopInvariant(VariantOp) || !L.isLoopInvariant(InvariantOp))
2633 return false;
2634
2635
2636
2637
2638
2639
2640 auto &DL = L.getHeader()->getDataLayout();
2642 if (VariantSubtracted && IsSigned) {
2643
2646 return false;
2647 } else if (VariantSubtracted && !IsSigned) {
2648
2651 return false;
2652 } else if (!VariantSubtracted && IsSigned) {
2653
2656 return false;
2657 } else {
2658
2661 return false;
2662 }
2663 auto *Preheader = L.getLoopPreheader();
2664 assert(Preheader && "Loop is not in simplify form?");
2666 Value *NewCmpOp =
2667 VariantSubtracted
2668 ? Builder.CreateSub(InvariantOp, InvariantRHS, "invariant.op",
2669 !IsSigned, IsSigned)
2670 : Builder.CreateAdd(InvariantOp, InvariantRHS, "invariant.op",
2671 !IsSigned, IsSigned);
2675 eraseInstruction(cast(*VariantLHS), SafetyInfo, MSSAU);
2676 return true;
2677}
2678
2679
2683 using namespace PatternMatch;
2687 return false;
2688
2689
2690 if (L.isLoopInvariant(LHS)) {
2693 }
2694
2695
2696 if (L.isLoopInvariant(LHS) || !L.isLoopInvariant(RHS) || ->hasOneUse())
2697 return false;
2698
2699
2700
2701 if (hoistAdd(Pred, LHS, RHS, cast(I), L, SafetyInfo, MSSAU, AC, DT))
2702 return true;
2703
2704 if (hoistSub(Pred, LHS, RHS, cast(I), L, SafetyInfo, MSSAU, AC, DT))
2705 return true;
2706
2707 return false;
2708}
2709
2711 unsigned FPOpcode) {
2712 if (I->getOpcode() == IntOpcode)
2713 return true;
2714 if (I->getOpcode() == FPOpcode && I->hasAllowReassoc() &&
2715 I->hasNoSignedZeros())
2716 return true;
2717 return false;
2718}
2719
2720
2721
2722
2723
2724
2730 return false;
2731 Value *VariantOp = I.getOperand(0);
2732 Value *InvariantOp = I.getOperand(1);
2733 if (L.isLoopInvariant(VariantOp))
2734 std::swap(VariantOp, InvariantOp);
2735 if (L.isLoopInvariant(VariantOp) || !L.isLoopInvariant(InvariantOp))
2736 return false;
2737 Value *Factor = InvariantOp;
2738
2739
2743 if (BinaryOperator *VariantBinOp = dyn_cast(VariantOp))
2744 Worklist.push_back(VariantBinOp);
2745 while (!Worklist.empty()) {
2748 return false;
2749 if (isReassociableOp(BO, Instruction::Add, Instruction::FAdd) &&
2750 isa(BO->getOperand(0)) &&
2751 isa(BO->getOperand(1))) {
2755 continue;
2756 }
2757 if ((BO, Instruction::Mul, Instruction::FMul) ||
2758 L.isLoopInvariant(BO))
2759 return false;
2762 if (L.isLoopInvariant(U0))
2764 else if (L.isLoopInvariant(U1))
2766 else
2767 return false;
2768 unsigned Limit = I.getType()->isIntOrIntVectorTy()
2771 if (Changes.size() > Limit)
2772 return false;
2773 }
2774 if (Changes.empty())
2775 return false;
2776
2777
2778 if (I.getType()->isIntOrIntVectorTy()) {
2779 for (auto *Add : Adds)
2780 Add->dropPoisonGeneratingFlags();
2781 }
2782
2783
2784 auto *Preheader = L.getLoopPreheader();
2785 assert(Preheader && "Loop is not in simplify form?");
2787 for (auto *U : Changes) {
2788 assert(L.isLoopInvariant(U->get()));
2789 auto *Ins = cast(U->getUser());
2791 if (I.getType()->isIntOrIntVectorTy()) {
2792 Mul = Builder.CreateMul(U->get(), Factor, "factor.op.mul");
2793
2794 Ins->dropPoisonGeneratingFlags();
2795 } else
2796 Mul = Builder.CreateFMulFMF(U->get(), Factor, Ins, "factor.op.fmul");
2797
2798
2799 unsigned OpIdx = U->getOperandNo();
2800 auto *LHS = OpIdx == 0 ? Mul : Ins->getOperand(0);
2801 auto *RHS = OpIdx == 1 ? Mul : Ins->getOperand(1);
2802 auto *NewBO =
2804 Ins->getName() + ".reass", Ins->getIterator());
2805 NewBO->copyIRFlags(Ins);
2806 if (VariantOp == Ins)
2807 VariantOp = NewBO;
2808 Ins->replaceAllUsesWith(NewBO);
2810 }
2811
2812 I.replaceAllUsesWith(VariantOp);
2814 return true;
2815}
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2831 auto *BO = dyn_cast(&I);
2832 if (!BO || !BO->isAssociative())
2833 return false;
2834
2836 bool LVInRHS = L.isLoopInvariant(BO->getOperand(0));
2837 auto *BO0 = dyn_cast(BO->getOperand(LVInRHS));
2838 if (!BO0 || BO0->getOpcode() != Opcode || !BO0->isAssociative() ||
2839 BO0->hasNUsesOrMore(3))
2840 return false;
2841
2842 Value *LV = BO0->getOperand(0);
2843 Value *C1 = BO0->getOperand(1);
2844 Value *C2 = BO->getOperand(!LVInRHS);
2845
2846 assert(BO->isCommutative() && BO0->isCommutative() &&
2847 "Associativity implies commutativity");
2848 if (L.isLoopInvariant(LV) && !L.isLoopInvariant(C1))
2850 if (L.isLoopInvariant(LV) || !L.isLoopInvariant(C1) || !L.isLoopInvariant(C2))
2851 return false;
2852
2853 auto *Preheader = L.getLoopPreheader();
2854 assert(Preheader && "Loop is not in simplify form?");
2855
2857 auto *Inv = Builder.CreateBinOp(Opcode, C1, C2, "invariant.op");
2858
2860 Opcode, LV, Inv, BO->getName() + ".reass", BO->getIterator());
2861
2862
2863 if (Opcode == Instruction::Add && BO->hasNoUnsignedWrap() &&
2864 BO0->hasNoUnsignedWrap()) {
2865
2866 if (auto *I = dyn_cast(Inv))
2867 I->setHasNoUnsignedWrap(true);
2868 NewBO->setHasNoUnsignedWrap(true);
2869 } else if (Opcode == Instruction::FAdd || Opcode == Instruction::FMul) {
2870
2871 FastMathFlags Intersect = BO->getFastMathFlags() & BO0->getFastMathFlags();
2872 if (auto *I = dyn_cast(Inv))
2873 I->setFastMathFlags(Intersect);
2874 NewBO->setFastMathFlags(Intersect);
2875 }
2876
2877 BO->replaceAllUsesWith(NewBO);
2879
2880
2881
2882 if (BO0->use_empty())
2884
2885 return true;
2886}
2887
2892
2893
2894
2896 ++NumHoisted;
2897 ++NumMinMaxHoisted;
2898 return true;
2899 }
2900
2901
2902 if (hoistGEP(I, L, SafetyInfo, MSSAU, AC, DT)) {
2903 ++NumHoisted;
2904 ++NumGEPsHoisted;
2905 return true;
2906 }
2907
2908
2909 if (hoistAddSub(I, L, SafetyInfo, MSSAU, AC, DT)) {
2910 ++NumHoisted;
2911 ++NumAddSubHoisted;
2912 return true;
2913 }
2914
2915 bool IsInt = I.getType()->isIntOrIntVectorTy();
2917 ++NumHoisted;
2918 if (IsInt)
2919 ++NumIntAssociationsHoisted;
2920 else
2921 ++NumFPAssociationsHoisted;
2922 return true;
2923 }
2924
2926 ++NumHoisted;
2927 ++NumBOAssociationsHoisted;
2928 return true;
2929 }
2930
2931 return false;
2932}
2933
2934
2935
2936
2938 assert(CurLoop->contains(BB) && "Only valid if BB is IN the loop");
2939 return LI->getLoopFor(BB) != CurLoop;
2940}
unsigned const MachineRegisterInfo * MRI
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
iv Induction Variable Users
static bool isReassociableOp(Instruction *I, unsigned IntOpcode, unsigned FPOpcode)
static bool isNotUsedOrFoldableInLoop(const Instruction &I, const Loop *CurLoop, const LoopSafetyInfo *SafetyInfo, TargetTransformInfo *TTI, bool &FoldableInLoop, bool LoopNestMode)
Return true if the only users of this instruction are outside of the loop.
static bool hoistGEP(Instruction &I, Loop &L, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU, AssumptionCache *AC, DominatorTree *DT)
Reassociate gep (gep ptr, idx1), idx2 to gep (gep ptr, idx2), idx1 if this allows hoisting the inner ...
static cl::opt< bool > SingleThread("licm-force-thread-model-single", cl::Hidden, cl::init(false), cl::desc("Force thread model single in LICM pass"))
static void splitPredecessorsOfLoopExit(PHINode *PN, DominatorTree *DT, LoopInfo *LI, const Loop *CurLoop, LoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU)
static cl::opt< unsigned > FPAssociationUpperLimit("licm-max-num-fp-reassociations", cl::init(5U), cl::Hidden, cl::desc("Set upper limit for the number of transformations performed " "during a single round of hoisting the reassociated expressions."))
static bool isFoldableInLoop(const Instruction &I, const Loop *CurLoop, const TargetTransformInfo *TTI)
Return true if the instruction is foldable in the loop.
static bool hoistMinMax(Instruction &I, Loop &L, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU)
Try to simplify things like (A < INV_1 AND icmp A < INV_2) into (A < min(INV_1, INV_2)),...
static void moveInstructionBefore(Instruction &I, BasicBlock::iterator Dest, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU, ScalarEvolution *SE)
static Instruction * cloneInstructionInExitBlock(Instruction &I, BasicBlock &ExitBlock, PHINode &PN, const LoopInfo *LI, const LoopSafetyInfo *SafetyInfo, MemorySSAUpdater &MSSAU)
static cl::opt< bool > ControlFlowHoisting("licm-control-flow-hoisting", cl::Hidden, cl::init(false), cl::desc("Enable control flow (and PHI) hoisting in LICM"))
static bool pointerInvalidatedByLoop(MemorySSA *MSSA, MemoryUse *MU, Loop *CurLoop, Instruction &I, SinkAndHoistLICMFlags &Flags, bool InvariantGroup)
static bool hoistAdd(ICmpInst::Predicate Pred, Value *VariantLHS, Value *InvariantRHS, ICmpInst &ICmp, Loop &L, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU, AssumptionCache *AC, DominatorTree *DT)
Try to turn things like "LV + C1 < C2" into "LV < C2 - C1".
static MemoryAccess * getClobberingMemoryAccess(MemorySSA &MSSA, BatchAAResults &BAA, SinkAndHoistLICMFlags &Flags, MemoryUseOrDef *MA)
static SmallVector< PointersAndHasReadsOutsideSet, 0 > collectPromotionCandidates(MemorySSA *MSSA, AliasAnalysis *AA, Loop *L)
static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop, BasicBlock *Dest, ICFLoopSafetyInfo *SafetyInfo, MemorySSAUpdater &MSSAU, ScalarEvolution *SE, OptimizationRemarkEmitter *ORE)
When an instruction is found to only use loop invariant operands that is safe to hoist,...
static bool canSplitPredecessors(PHINode *PN, LoopSafetyInfo *SafetyInfo)
static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT, const Loop *CurLoop, ICFLoopSafetyInfo *SafetyInfo, MemorySSAUpdater &MSSAU, OptimizationRemarkEmitter *ORE)
When an instruction is found to only be used outside of the loop, this function moves it to the exit ...
static bool hoistAddSub(Instruction &I, Loop &L, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU, AssumptionCache *AC, DominatorTree *DT)
Reassociate and hoist add/sub expressions.
static bool hoistMulAddAssociation(Instruction &I, Loop &L, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU, AssumptionCache *AC, DominatorTree *DT)
Try to reassociate expressions like ((A1 * B1) + (A2 * B2) + ...) * C where A1, A2,...
static cl::opt< uint32_t > MaxNumUsesTraversed("licm-max-num-uses-traversed", cl::Hidden, cl::init(8), cl::desc("Max num uses visited for identifying load " "invariance in loop using invariant start (default = 8)"))
cl::opt< unsigned > IntAssociationUpperLimit("licm-max-num-int-reassociations", cl::init(5U), cl::Hidden, cl::desc("Set upper limit for the number of transformations performed " "during a single round of hoisting the reassociated expressions."))
static void foreachMemoryAccess(MemorySSA *MSSA, Loop *L, function_ref< void(Instruction *)> Fn)
static bool isLoadInvariantInLoop(LoadInst *LI, DominatorTree *DT, Loop *CurLoop)
static Instruction * sinkThroughTriviallyReplaceablePHI(PHINode *TPN, Instruction *I, LoopInfo *LI, SmallDenseMap< BasicBlock *, Instruction *, 32 > &SunkCopies, const LoopSafetyInfo *SafetyInfo, const Loop *CurLoop, MemorySSAUpdater &MSSAU)
static bool inSubLoop(BasicBlock *BB, Loop *CurLoop, LoopInfo *LI)
Little predicate that returns true if the specified basic block is in a subloop of the current one,...
static bool hoistSub(ICmpInst::Predicate Pred, Value *VariantLHS, Value *InvariantRHS, ICmpInst &ICmp, Loop &L, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU, AssumptionCache *AC, DominatorTree *DT)
Try to reassociate and hoist the following two patterns: LV - C1 < C2 --> LV < C1 + C2,...
static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU)
static bool isSafeToExecuteUnconditionally(Instruction &Inst, const DominatorTree *DT, const TargetLibraryInfo *TLI, const Loop *CurLoop, const LoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE, const Instruction *CtxI, AssumptionCache *AC, bool AllowSpeculation)
Only sink or hoist an instruction if it is not a trapping instruction, or if the instruction is known...
static bool hoistArithmetics(Instruction &I, Loop &L, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU, AssumptionCache *AC, DominatorTree *DT)
Aggregates various functions for hoisting computations out of loop.
static bool isTriviallyReplaceablePHI(const PHINode &PN, const Instruction &I)
Returns true if a PHINode is a trivially replaceable with an Instruction.
std::pair< SmallSetVector< Value *, 8 >, bool > PointersAndHasReadsOutsideSet
static cl::opt< bool > DisablePromotion("disable-licm-promotion", cl::Hidden, cl::init(false), cl::desc("Disable memory promotion in LICM pass"))
Memory promotion is enabled by default.
static bool hoistBOAssociation(Instruction &I, Loop &L, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU, AssumptionCache *AC, DominatorTree *DT)
Reassociate associative binary expressions of the form.
static bool pointerInvalidatedByBlock(BasicBlock &BB, MemorySSA &MSSA, MemoryUse &MU)
This file defines the interface for the loop nest analysis.
Machine Loop Invariant Code Motion
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
uint64_t IntrinsicInst * II
PassInstrumentationCallbacks PIC
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file provides a priority worklist.
Remove Loads Into Fake Uses
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines generic set operations that may be used on set's of different types,...
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.
ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, bool IgnoreLocals=false)
Returns a bitmask that should be unconditionally applied to the ModRef info of a memory location.
MemoryEffects getMemoryEffects(const CallBase *Call)
Return the behavior of the given call site.
void add(const MemoryLocation &Loc)
These methods are used to add different types of instructions to the alias sets.
A container for analyses that lazily runs them and caches their results.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
void replaceSuccessorsPhiUsesWith(BasicBlock *Old, BasicBlock *New)
Update all phi nodes in this basic block's successors to refer to basic block New instead of basic bl...
iterator begin()
Instruction iterator methods.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
InstListType::const_iterator getFirstNonPHIIt() const
Iterator returning form of getFirstNonPHI.
const Instruction * getFirstNonPHI() const
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
const Function * getParent() const
Return the enclosing method, or null if none.
const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
InstListType::iterator iterator
Instruction iterators...
LLVMContext & getContext() const
Get the context in which this basic block lives.
void moveBefore(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it into the function that MovePos lives ...
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...
bool canSplitPredecessors() const
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
Conditional or Unconditional Branch instruction.
bool isConditional() const
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
void setPredicate(Predicate P)
Set the predicate for this instruction to the specified value.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
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...
static std::optional< CmpPredicate > getMatching(CmpPredicate A, CmpPredicate B)
Compares two CmpPredicates taking samesign into account and returns the canonicalized CmpPredicate if...
This is the shared class of boolean and integer constants.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
static DILocation * getMergedLocations(ArrayRef< DILocation * > Locs)
Try to combine the vector of locations passed as input in a single one.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
TypeSize getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type.
iterator find(const_arg_type_t< KeyT > Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
DomTreeNodeBase * getIDom() const
Analysis pass which computes a DominatorTree.
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.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Convenience struct for specifying and reasoning about fast-math flags.
This implementation of LoopSafetyInfo use ImplicitControlFlowTracking to give precise answers on "may...
bool doesNotWriteMemoryBefore(const BasicBlock *BB, const Loop *CurLoop) const
Returns true if we could not execute a memory-modifying instruction before we enter BB under assumpti...
void removeInstruction(const Instruction *Inst)
Inform safety info that we are planning to remove the instruction Inst from its block.
bool isGuaranteedToExecute(const Instruction &Inst, const DominatorTree *DT, const Loop *CurLoop) const override
Returns true if the instruction in a loop is guaranteed to execute at least once (under the assumptio...
bool anyBlockMayThrow() const override
Returns true iff any block of the loop for which this info is contains an instruction that may throw ...
void computeLoopSafetyInfo(const Loop *CurLoop) override
Computes safety information for a loop checks loop body & header for the possibility of may throw exc...
void insertInstructionTo(const Instruction *Inst, const BasicBlock *BB)
Inform the safety info that we are planning to insert a new instruction Inst into the basic block BB.
This instruction compares its operands according to the predicate given to the constructor.
static bool isGE(Predicate P)
Return true if the predicate is SGE or UGE.
static bool isLT(Predicate P)
Return true if the predicate is SLT or ULT.
static bool isGT(Predicate P)
Return true if the predicate is SGT or UGT.
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
static bool isLE(Predicate P)
Return true if the predicate is SLE or ULE.
Value * CreateFreeze(Value *V, const Twine &Name="")
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateFMulFMF(Value *L, Value *R, FMFSource FMFSource, const Twine &Name="", MDNode *FPMD=nullptr)
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
void mergeDIAssignID(ArrayRef< const Instruction * > SourceInstructions)
Merge the DIAssignID metadata from this instruction and those attached to instructions in SourceInstr...
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
void setAAMetadata(const AAMDNodes &N)
Sets the AA metadata on this instruction from the AAMDNodes structure.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
A wrapper class for inspecting calls to intrinsic functions.
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
This is an important class for using LLVM in a threaded context.
PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
This is an alternative analysis pass to BlockFrequencyInfoWrapperPass.
static void getLazyBFIAnalysisUsage(AnalysisUsage &AU)
Helper for client passes to set up the analysis usage on behalf of this pass.
This is an alternative analysis pass to BranchProbabilityInfoWrapperPass.
An instruction for reading from memory.
void setAlignment(Align Align)
Value * getPointerOperand()
void setOrdering(AtomicOrdering Ordering)
Sets the ordering constraint of this load instruction.
Analysis pass that exposes the LoopInfo for a function.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
BlockT * getHeader() const
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
ArrayRef< BlockT * > getBlocks() const
Get a list of the basic blocks which make up this loop.
void getUniqueExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all unique successor blocks of this loop.
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
Wrapper class to LoopBlocksDFS that provides a standard begin()/end() interface for the DFS reverse p...
void perform(const LoopInfo *LI)
Traverse the loop blocks and store the DFS result.
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
The legacy pass manager's analysis pass to compute loop information.
bool wouldBeOutOfLoopUseRequiringLCSSA(const Value *V, const BasicBlock *ExitBB) const
This class represents a loop nest and can be used to query its properties.
Function * getParent() const
Return the function to which the loop-nest belongs.
Loop & getOutermostLoop() const
Return the outermost loop in the loop nest.
Captures loop safety information.
void copyColors(BasicBlock *New, BasicBlock *Old)
Copy colors of block Old into the block New.
const DenseMap< BasicBlock *, ColorVector > & getBlockColors() const
Returns block colors map that is used to update funclet operand bundles.
virtual bool isGuaranteedToExecute(const Instruction &Inst, const DominatorTree *DT, const Loop *CurLoop) const =0
Returns true if the instruction in a loop is guaranteed to execute at least once (under the assumptio...
Represents a single loop in the control flow graph.
bool hasLoopInvariantOperands(const Instruction *I) const
Return true if all the operands of the specified instruction are loop invariant.
bool isLoopInvariant(const Value *V) const
Return true if the specified value is loop invariant.
BasicBlock * getBlock() const
bool doesNotAccessMemory() const
Whether this function accesses no memory.
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
An analysis that produces MemorySSA for a function.
MemorySSA * getMemorySSA() const
Get handle on MemorySSA.
void insertDef(MemoryDef *Def, bool RenameUses=false)
Insert a definition into the MemorySSA IR.
void insertUse(MemoryUse *Use, bool RenameUses=false)
MemoryAccess * createMemoryAccessInBB(Instruction *I, MemoryAccess *Definition, const BasicBlock *BB, MemorySSA::InsertionPlace Point, bool CreationMustSucceed=true)
Create a MemoryAccess in MemorySSA at a specified point in a block.
void removeMemoryAccess(MemoryAccess *, bool OptimizePhis=false)
Remove a MemoryAccess from MemorySSA, including updating all definitions and uses.
MemoryUseOrDef * createMemoryAccessAfter(Instruction *I, MemoryAccess *Definition, MemoryAccess *InsertPt)
Create a MemoryAccess in MemorySSA after an existing MemoryAccess.
void moveToPlace(MemoryUseOrDef *What, BasicBlock *BB, MemorySSA::InsertionPlace Where)
void wireOldPredecessorsToNewImmediatePredecessor(BasicBlock *Old, BasicBlock *New, ArrayRef< BasicBlock * > Preds, bool IdenticalEdgesWereMerged=true)
A new empty BasicBlock (New) now branches directly to Old.
MemoryAccess * getClobberingMemoryAccess(const Instruction *I, BatchAAResults &AA)
Given a memory Mod/Ref/ModRef'ing instruction, calling this will give you the nearest dominating Memo...
Legacy analysis pass which computes MemorySSA.
Encapsulates MemorySSA, including all data associated with memory accesses.
const AccessList * getBlockAccesses(const BasicBlock *BB) const
Return the list of MemoryAccess's for a given basic block.
MemorySSAWalker * getSkipSelfWalker()
bool dominates(const MemoryAccess *A, const MemoryAccess *B) const
Given two memory accesses in potentially different blocks, determine whether MemoryAccess A dominates...
void verifyMemorySSA(VerificationLevel=VerificationLevel::Fast) const
Verify that MemorySSA is self consistent (IE definitions dominate all uses, uses appear in the right ...
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
const DefsList * getBlockDefs(const BasicBlock *BB) const
Return the list of MemoryDef's and MemoryPhi's for a given basic block.
bool locallyDominates(const MemoryAccess *A, const MemoryAccess *B) const
Given two memory accesses in the same basic block, determine whether MemoryAccess A dominates MemoryA...
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
Class that has the common methods + fields of memory uses/defs.
MemoryAccess * getDefiningAccess() const
Get the access that produces the memory state used by this Use.
Represents read-only accesses to memory.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
op_range incoming_values()
void setIncomingBlock(unsigned i, BasicBlock *BB)
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
PointerIntPair - This class implements a pair of a pointer and small integer.
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
PredIteratorCache - This class is an extremely trivial cache for predecessor iterator queries.
size_t size(BasicBlock *BB)
ArrayRef< BasicBlock * > get(BasicBlock *BB)
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
bool empty() const
Determine if the PriorityWorklist is empty or not.
bool insert(const T &X)
Insert a new element into the PriorityWorklist.
Helper class for SSA formation on a set of values defined in multiple blocks.
The main scalar evolution driver.
void forgetBlockAndLoopDispositions(Value *V=nullptr)
Called when the client has changed the disposition of values in a loop or block.
void forgetLoopDispositions()
Called when the client has changed the disposition of values in this loop.
bool remove(const value_type &X)
Remove an item from the set vector.
bool empty() const
Determine if the SetVector is empty or not.
iterator begin()
Get an iterator to the beginning of the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
Flags controlling how much is checked when sinking or hoisting instructions.
SinkAndHoistLICMFlags(unsigned LicmMssaOptCap, unsigned LicmMssaNoAccForPromotionCap, bool IsSink, Loop &L, MemorySSA &MSSA)
unsigned LicmMssaNoAccForPromotionCap
A version of PriorityWorklist that selects small size optimized data structures for the vector and ma...
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
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.
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
void setAlignment(Align Align)
void setOrdering(AtomicOrdering Ordering)
Sets the ordering constraint of this store instruction.
static unsigned getPointerOperandIndex()
StringRef - Represent a constant reference to a string, i.e.
Provides information about what library functions are available for the current target.
Wrapper pass for TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
bool isSingleThreaded() const
@ TCK_SizeAndLatency
The weighted sum of size and latency.
@ TCC_Free
Expected to fold away in lowering.
InstructionCost getInstructionCost(const User *U, ArrayRef< const Value * > Operands, TargetCostKind CostKind) const
Estimate the cost of a given IR user when lowered.
TinyPtrVector - This class is specialized for cases where there are normally 0 or 1 element in a vect...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUser() const
Return true if there is exactly one user of this value.
std::string getNameOrAsOperand() const
bool hasOneUse() const
Return true if there is exactly one use of this value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
user_iterator_impl< User > user_iterator
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
OneUse_match< T > m_OneUse(const T &SubPattern)
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWSub(const LHS &L, const RHS &R)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
initializer< Ty > init(const Ty &Val)
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
void ReplaceInstWithInst(BasicBlock *BB, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
@ NeverOverflows
Never overflows.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT, Loop *CurLoop, MemorySSAUpdater &MSSAU, bool TargetExecutesOncePerLoop, SinkAndHoistLICMFlags &LICMFlags, OptimizationRemarkEmitter *ORE=nullptr)
Returns true if is legal to hoist or sink this instruction disregarding the possible introduction of ...
auto pred_end(const MachineBasicBlock *BB)
void set_intersect(S1Ty &S1, const S2Ty &S2)
set_intersect(A, B) - Compute A := A ^ B Identical to set_intersection, except that it works on set<>...
void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
void initializeLegacyLICMPassPass(PassRegistry &)
bool isDereferenceableAndAlignedPointer(const Value *V, Type *Ty, Align Alignment, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Returns true if V is always a dereferenceable pointer with alignment greater or equal than requested.
bool formLCSSARecursively(Loop &L, const DominatorTree &DT, const LoopInfo *LI, ScalarEvolution *SE)
Put a loop nest into LCSSA form.
bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, bool StoreCaptures, const Instruction *I, const DominatorTree *DT, bool IncludeI=false, unsigned MaxUsesToExplore=0, const LoopInfo *LI=nullptr)
PointerMayBeCapturedBefore - Return true if this pointer value may be captured by the enclosing funct...
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
auto pred_size(const MachineBasicBlock *BB)
SmallVector< BasicBlock *, 16 > collectChildrenInLoop(DominatorTree *DT, DomTreeNode *N, const Loop *CurLoop)
Does a BFS from a given node to all of its children inside a given loop.
bool hoistRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *, AssumptionCache *, TargetLibraryInfo *, Loop *, MemorySSAUpdater &, ScalarEvolution *, ICFLoopSafetyInfo *, SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *, bool, bool AllowSpeculation)
Walk the specified region of the CFG (defined by all blocks dominated by the specified block,...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
bool isGuard(const User *U)
Returns true iff U has semantics of a guard expressed in a form of call of llvm.experimental....
auto reverse(ContainerTy &&C)
OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS, const SimplifyQuery &SQ)
bool isModSet(const ModRefInfo MRI)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool isModOrRefSet(const ModRefInfo MRI)
bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
bool isNotVisibleOnUnwind(const Value *Object, bool &RequiresNoCaptureBeforeUnwind)
Return true if Object memory is not visible after an unwind, in the sense that program semantics cann...
void getLoopAnalysisUsage(AnalysisUsage &AU)
Helper to consistently add the set of standard passes to a loop pass's AnalysisUsage.
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
BasicBlock * SplitBlockPredecessors(BasicBlock *BB, ArrayRef< BasicBlock * > Preds, const char *Suffix, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool PreserveLCSSA=false)
This method introduces at least one new basic block into the function and moves some of the predecess...
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
bool VerifyMemorySSA
Enables verification of MemorySSA.
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
bool salvageKnowledge(Instruction *I, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr)
Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert if before I.
bool hasDisableLICMTransformsHint(const Loop *L)
Look for the loop attribute that disables the LICM transformation heuristics.
OverflowResult computeOverflowForSignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const SimplifyQuery &SQ)
@ Mul
Product of integers.
void appendLoopsToWorklist(RangeT &&, SmallPriorityWorklist< Loop *, 4 > &)
Utility that implements appending of loops onto a worklist given a range.
bool isIdentifiedFunctionLocal(const Value *V)
Return true if V is umabigously identified at the function-level.
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.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
OverflowResult computeOverflowForUnsignedSub(const Value *LHS, const Value *RHS, const SimplifyQuery &SQ)
auto pred_begin(const MachineBasicBlock *BB)
PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
auto predecessors(const MachineBasicBlock *BB)
Type * getLoadStoreType(const Value *I)
A helper function that returns the type of a load or store instruction.
bool sinkRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *, TargetLibraryInfo *, TargetTransformInfo *, Loop *CurLoop, MemorySSAUpdater &, ICFLoopSafetyInfo *, SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *, Loop *OutermostLoop=nullptr)
Walk the specified region of the CFG (defined by all blocks dominated by the specified block,...
OverflowResult computeOverflowForUnsignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const SimplifyQuery &SQ)
cl::opt< unsigned > SetLicmMssaNoAccForPromotionCap
bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
bool promoteLoopAccessesToScalars(const SmallSetVector< Value *, 8 > &, SmallVectorImpl< BasicBlock * > &, SmallVectorImpl< BasicBlock::iterator > &, SmallVectorImpl< MemoryAccess * > &, PredIteratorCache &, LoopInfo *, DominatorTree *, AssumptionCache *AC, const TargetLibraryInfo *, TargetTransformInfo *, Loop *, MemorySSAUpdater &, ICFLoopSafetyInfo *, OptimizationRemarkEmitter *, bool AllowSpeculation, bool HasReadsOutsideSet)
Try to promote memory values to scalars by sinking stores out of the loop and moving loads to before ...
cl::opt< unsigned > SetLicmMssaOptCap
bool sinkRegionForLoopNest(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *, TargetLibraryInfo *, TargetTransformInfo *, Loop *, MemorySSAUpdater &, ICFLoopSafetyInfo *, SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *)
Call sinkRegion on loops contained within the specified loop in order from innermost to outermost.
bool isWritableObject(const Value *Object, bool &ExplicitlyDereferenceableOnly)
Return true if the Object is writable, in the sense that any location based on this pointer that can ...
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
AAMDNodes merge(const AAMDNodes &Other) const
Given two sets of AAMDNodes applying to potentially different locations, determine the best AAMDNodes...
This struct is a compact representation of a valid (non-zero power of two) alignment.
unsigned MssaNoAccForPromotionCap
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
TargetTransformInfo & TTI
A lightweight accessor for an operand bundle meant to be passed around by value.
uint32_t getTagID() const
Return the tag of this operand bundle as an integer.
A CRTP mix-in to automatically provide informational APIs needed for passes.