99#define DEBUG_TYPE "loop-idiom"
101STATISTIC(NumMemSet,
"Number of memset's formed from loop stores");
102STATISTIC(NumMemCpy,
"Number of memcpy's formed from loop load+stores");
103STATISTIC(NumMemMove,
"Number of memmove's formed from loop load+stores");
104STATISTIC(NumStrLen,
"Number of strlen's and wcslen's formed from loop loads");
106 NumShiftUntilBitTest,
107 "Number of uncountable loops recognized as 'shift until bitttest' idiom");
109 "Number of uncountable loops recognized as 'shift until zero' idiom");
115 cl::desc(
"Options to disable Loop Idiom Recognize Pass."),
122 cl::desc(
"Proceed with loop idiom recognize pass, but do "
123 "not convert loop(s) to memset."),
130 cl::desc(
"Proceed with loop idiom recognize pass, but do "
131 "not convert loop(s) to memcpy."),
138 cl::desc(
"Proceed with loop idiom recognize pass, but do "
139 "not convert loop(s) to strlen."),
146 cl::desc(
"Proceed with loop idiom recognize pass, "
147 "enable conversion of loop(s) to wcslen."),
154 cl::desc(
"Proceed with loop idiom recognize pass, "
155 "but do not do hash-recognize analysis."),
160 "use-lir-code-size-heurs",
161 cl::desc(
"Use loop idiom recognition code size heuristics when compiling "
166 "loop-idiom-force-memset-pattern-intrinsic",
167 cl::desc(
"Use memset.pattern intrinsic whenever possible"),
cl::init(
false),
178 cl::desc(
"Preferred strategy for optimizing CRC loops"),
181 "Do not optimize CRC loops"),
183 "Use costing to determine strategy"),
185 "Use a Sarwate table when possible"),
187 "Use carry-less multiplication when possible")));
195class LoopIdiomRecognize {
196 Loop *CurLoop =
nullptr;
205 bool ApplyCodeSizeHeuristics;
206 std::unique_ptr<MemorySSAUpdater> MSSAU;
215 :
AA(
AA), DT(DT), LI(LI), SE(SE), TLI(TLI),
TTI(
TTI),
DL(
DL), ORE(ORE) {
217 MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
220 bool runOnLoop(Loop *L);
223 using StoreList = SmallVector<StoreInst *, 8>;
224 using StoreListMap = MapVector<Value *, StoreList>;
226 StoreListMap StoreRefsForMemset;
227 StoreListMap StoreRefsForMemsetPattern;
228 StoreList StoreRefsForMemcpy;
230 bool HasMemsetPattern;
234 enum LegalStoreKind {
239 UnorderedAtomicMemcpy,
247 bool runOnCountableLoop();
248 bool runOnLoopBlock(BasicBlock *BB,
const SCEV *BECount,
249 SmallVectorImpl<BasicBlock *> &ExitBlocks);
251 void collectStores(BasicBlock *BB);
252 LegalStoreKind isLegalStore(StoreInst *SI);
253 enum class ForMemset {
No,
Yes };
254 bool processLoopStores(SmallVectorImpl<StoreInst *> &SL,
const SCEV *BECount,
257 template <
typename MemInst>
258 bool processLoopMemIntrinsic(
260 bool (LoopIdiomRecognize::*Processor)(MemInst *,
const SCEV *),
261 const SCEV *BECount);
262 bool processLoopMemCpy(MemCpyInst *MCI,
const SCEV *BECount);
263 bool processLoopMemSet(MemSetInst *MSI,
const SCEV *BECount);
265 bool processLoopStridedStore(
Value *DestPtr,
const SCEV *StoreSizeSCEV,
266 MaybeAlign StoreAlignment,
Value *StoredVal,
267 Instruction *TheStore,
268 SmallPtrSetImpl<Instruction *> &Stores,
269 const SCEVAddRecExpr *Ev,
const SCEV *BECount,
270 bool IsNegStride,
bool IsLoopMemset =
false);
271 bool processLoopStoreOfLoopLoad(StoreInst *SI,
const SCEV *BECount);
272 bool processLoopStoreOfLoopLoad(
Value *DestPtr,
Value *SourcePtr,
273 const SCEV *StoreSize, MaybeAlign StoreAlign,
274 MaybeAlign LoadAlign, Instruction *TheStore,
275 Instruction *TheLoad,
276 const SCEVAddRecExpr *StoreEv,
277 const SCEVAddRecExpr *LoadEv,
278 const SCEV *BECount);
279 bool avoidLIRForMultiBlockLoop(
bool IsMemset =
false,
280 bool IsLoopMemset =
false);
281 bool optimizeCRCLoop(
const PolynomialInfo &Info);
282 void optimizeCRCLoopUsingClmul(
const PolynomialInfo &Info);
283 void optimizeCRCLoopUsingTableLookup(
const PolynomialInfo &Info);
289 bool runOnNoncountableLoop();
291 bool recognizePopcount();
292 void transformLoopToPopcount(BasicBlock *PreCondBB, Instruction *CntInst,
293 PHINode *CntPhi,
Value *Var);
295 bool ZeroCheck,
size_t CanonicalSize);
297 Instruction *DefX, PHINode *CntPhi,
298 Instruction *CntInst);
299 bool recognizeAndInsertFFS();
300 bool recognizeShiftUntilLessThan();
301 void transformLoopToCountable(
Intrinsic::ID IntrinID, BasicBlock *PreCondBB,
302 Instruction *CntInst, PHINode *CntPhi,
303 Value *Var, Instruction *DefX,
305 bool IsCntPhiUsedOutsideLoop,
306 bool InsertSub =
false);
308 bool recognizeShiftUntilBitTest();
309 bool recognizeShiftUntilZero();
310 bool recognizeAndInsertStrLen();
322 const auto *
DL = &L.getHeader()->getDataLayout();
329 LoopIdiomRecognize LIR(&AR.
AA, &AR.
DT, &AR.
LI, &AR.
SE, &AR.
TLI, &AR.
TTI,
331 if (!LIR.runOnLoop(&L))
342 I->eraseFromParent();
351bool LoopIdiomRecognize::runOnLoop(
Loop *L) {
355 if (!
L->getLoopPreheader())
360 if (Name ==
"memset" || Name ==
"memcpy" || Name ==
"strlen" ||
365 ApplyCodeSizeHeuristics =
368 HasMemset = TLI->
has(LibFunc_memset);
374 HasMemsetPattern = TLI->
has(LibFunc_memset_pattern16);
375 HasMemcpy = TLI->
has(LibFunc_memcpy);
380 return runOnCountableLoop();
382 return runOnNoncountableLoop();
385bool LoopIdiomRecognize::runOnCountableLoop() {
388 "runOnCountableLoop() called on a loop without a predictable"
389 "backedge-taken count");
411 bool MadeChange =
false;
419 MadeChange |= runOnLoopBlock(BB, BECount, ExitBlocks);
425 MadeChange |= optimizeCRCLoop(*Res);
460 if (
DL->isBigEndian())
472 Type *CTy =
C->getType();
479LoopIdiomRecognize::LegalStoreKind
482 if (
SI->isVolatile())
483 return LegalStoreKind::None;
485 if (!
SI->isUnordered())
486 return LegalStoreKind::None;
489 if (
SI->getMetadata(LLVMContext::MD_nontemporal))
490 return LegalStoreKind::None;
492 Value *StoredVal =
SI->getValueOperand();
493 Value *StorePtr =
SI->getPointerOperand();
495 if (
DL->hasUnstableRepresentation(StoredVal->
getType()))
496 return LegalStoreKind::None;
505 bool MustPreserveExternalState =
DL->hasExternalState(StoredVal->
getType()) &&
514 return LegalStoreKind::None;
523 return LegalStoreKind::None;
534 bool UnorderedAtomic =
SI->isUnordered() && !
SI->isSimple();
538 if (!MustPreserveExternalState && !UnorderedAtomic && HasMemset &&
544 return LegalStoreKind::Memset;
546 if (!MustPreserveExternalState && !UnorderedAtomic &&
553 return LegalStoreKind::MemsetPattern;
560 unsigned StoreSize =
DL->getTypeStoreSize(
SI->getValueOperand()->getType());
562 if (StoreSize != StrideAP && StoreSize != -StrideAP)
563 return LegalStoreKind::None;
570 return LegalStoreKind::None;
573 return LegalStoreKind::None;
583 return LegalStoreKind::None;
586 UnorderedAtomic = UnorderedAtomic || LI->
isAtomic();
587 return UnorderedAtomic ? LegalStoreKind::UnorderedAtomicMemcpy
588 : LegalStoreKind::Memcpy;
591 return LegalStoreKind::None;
594void LoopIdiomRecognize::collectStores(
BasicBlock *BB) {
595 StoreRefsForMemset.clear();
596 StoreRefsForMemsetPattern.clear();
597 StoreRefsForMemcpy.clear();
604 switch (isLegalStore(
SI)) {
605 case LegalStoreKind::None:
608 case LegalStoreKind::Memset: {
611 StoreRefsForMemset[Ptr].push_back(
SI);
613 case LegalStoreKind::MemsetPattern: {
616 StoreRefsForMemsetPattern[Ptr].push_back(
SI);
618 case LegalStoreKind::Memcpy:
619 case LegalStoreKind::UnorderedAtomicMemcpy:
620 StoreRefsForMemcpy.push_back(
SI);
623 assert(
false &&
"unhandled return value");
632bool LoopIdiomRecognize::runOnLoopBlock(
642 bool MadeChange =
false;
649 for (
auto &SL : StoreRefsForMemset)
650 MadeChange |= processLoopStores(SL.second, BECount, ForMemset::Yes);
652 for (
auto &SL : StoreRefsForMemsetPattern)
653 MadeChange |= processLoopStores(SL.second, BECount, ForMemset::No);
656 for (
auto &
SI : StoreRefsForMemcpy)
657 MadeChange |= processLoopStoreOfLoopLoad(
SI, BECount);
659 MadeChange |= processLoopMemIntrinsic<MemCpyInst>(
660 BB, &LoopIdiomRecognize::processLoopMemCpy, BECount);
661 MadeChange |= processLoopMemIntrinsic<MemSetInst>(
662 BB, &LoopIdiomRecognize::processLoopMemSet, BECount);
669 const SCEV *BECount, ForMemset For) {
677 for (
unsigned i = 0, e = SL.
size(); i < e; ++i) {
678 assert(SL[i]->
isSimple() &&
"Expected only non-volatile stores.");
680 Value *FirstStoredVal = SL[i]->getValueOperand();
681 Value *FirstStorePtr = SL[i]->getPointerOperand();
685 unsigned FirstStoreSize =
DL->getTypeStoreSize(SL[i]->getValueOperand()->
getType());
688 if (FirstStride == FirstStoreSize || -FirstStride == FirstStoreSize) {
693 Value *FirstSplatValue =
nullptr;
694 Constant *FirstPatternValue =
nullptr;
696 if (For == ForMemset::Yes)
701 assert((FirstSplatValue || FirstPatternValue) &&
702 "Expected either splat value or pattern value.");
710 for (j = i + 1;
j <
e; ++
j)
712 for (j = i;
j > 0; --
j)
715 for (
auto &k : IndexQueue) {
716 assert(SL[k]->
isSimple() &&
"Expected only non-volatile stores.");
717 Value *SecondStorePtr = SL[
k]->getPointerOperand();
722 if (FirstStride != SecondStride)
725 Value *SecondStoredVal = SL[
k]->getValueOperand();
726 Value *SecondSplatValue =
nullptr;
727 Constant *SecondPatternValue =
nullptr;
729 if (For == ForMemset::Yes)
734 assert((SecondSplatValue || SecondPatternValue) &&
735 "Expected either splat value or pattern value.");
738 if (For == ForMemset::Yes) {
740 FirstSplatValue = SecondSplatValue;
741 if (FirstSplatValue != SecondSplatValue)
745 FirstPatternValue = SecondPatternValue;
746 if (FirstPatternValue != SecondPatternValue)
751 ConsecutiveChain[SL[i]] = SL[
k];
771 unsigned StoreSize = 0;
774 while (Tails.
count(
I) || Heads.count(
I)) {
775 if (TransformedStores.
count(
I))
779 StoreSize +=
DL->getTypeStoreSize(
I->getValueOperand()->getType());
781 I = ConsecutiveChain[
I];
791 if (StoreSize != Stride && StoreSize != -Stride)
794 bool IsNegStride = StoreSize == -Stride;
798 if (processLoopStridedStore(StorePtr, StoreSizeSCEV,
800 HeadStore, AdjacentStores, StoreEv, BECount,
812template <
typename MemInst>
813bool LoopIdiomRecognize::processLoopMemIntrinsic(
815 bool (LoopIdiomRecognize::*Processor)(MemInst *,
const SCEV *),
816 const SCEV *BECount) {
817 bool MadeChange =
false;
823 if (!(this->*Processor)(
MI, BECount))
837bool LoopIdiomRecognize::processLoopMemCpy(
MemCpyInst *MCI,
838 const SCEV *BECount) {
849 if (!Dest || !Source)
857 const APInt *StoreStrideValue, *LoadStrideValue;
868 if ((SizeInBytes >> 32) != 0)
876 if (SizeInBytes != *StoreStrideValue && SizeInBytes != -*StoreStrideValue) {
879 <<
ore::NV(
"Inst",
"memcpy") <<
" in "
881 <<
" function will not be hoisted: "
882 <<
ore::NV(
"Reason",
"memcpy size is not equal to stride");
887 int64_t StoreStrideInt = StoreStrideValue->
getSExtValue();
888 int64_t LoadStrideInt = LoadStrideValue->
getSExtValue();
890 if (StoreStrideInt != LoadStrideInt)
893 return processLoopStoreOfLoopLoad(
900bool LoopIdiomRecognize::processLoopMemSet(
MemSetInst *MSI,
901 const SCEV *BECount) {
916 const SCEV *PointerStrideSCEV;
925 bool IsNegStride =
false;
928 if (IsConstantSize) {
938 if (SizeInBytes != *Stride && SizeInBytes != -*Stride)
941 IsNegStride = SizeInBytes == -*Stride;
949 if (
Pointer->getType()->getPointerAddressSpace() != 0) {
965 LLVM_DEBUG(
dbgs() <<
" MemsetSizeSCEV: " << *MemsetSizeSCEV <<
"\n"
966 <<
" PositiveStrideSCEV: " << *PositiveStrideSCEV
969 if (PositiveStrideSCEV != MemsetSizeSCEV) {
972 const SCEV *FoldedPositiveStride =
974 const SCEV *FoldedMemsetSize =
978 <<
" FoldedMemsetSize: " << *FoldedMemsetSize <<
"\n"
979 <<
" FoldedPositiveStride: " << *FoldedPositiveStride
982 if (FoldedPositiveStride != FoldedMemsetSize) {
1007 assert(SplatByte &&
"expected a bytewise splat value to match against");
1009 if (!
SI || !
SI->isSimple() || !L->isLoopInvariant(
SI->getValueOperand()))
1021 const SCEV *BECount,
1024 Value *SplatByte =
nullptr,
1033 const APInt *BECst, *ConstSize;
1037 std::optional<uint64_t> SizeInt = ConstSize->
tryZExtValue();
1039 if (BEInt && SizeInt)
1051 bool TrySameByteValue = !AccessSize.
isPrecise() && SplatByte &&
DL;
1068 Type *IntPtr,
const SCEV *StoreSizeSCEV,
1071 if (!StoreSizeSCEV->
isOne()) {
1086 const SCEV *StoreSizeSCEV,
Loop *CurLoop,
1088 const SCEV *TripCountSCEV =
1097bool LoopIdiomRecognize::processLoopStridedStore(
1101 const SCEV *BECount,
bool IsNegStride,
bool IsLoopMemset) {
1113 Type *DestInt8PtrTy = Builder.getPtrTy(DestAS);
1124 if (!Expander.isSafeToExpand(Start))
1133 Expander.expandCodeFor(Start, DestInt8PtrTy, Preheader->
getTerminator());
1146 StoreSizeSCEV, *
AA, Stores, SplatValue,
DL))
1149 if (avoidLIRForMultiBlockLoop(
true, IsLoopMemset))
1160 std::optional<int64_t> BytesWritten;
1163 const SCEV *TripCountS =
1165 if (!Expander.isSafeToExpand(TripCountS))
1168 if (!ConstStoreSize)
1170 Value *TripCount = Expander.expandCodeFor(TripCountS, IntIdxTy,
1172 uint64_t PatternRepsPerTrip =
1173 (ConstStoreSize->
getValue()->getZExtValue() * 8) /
1174 DL->getTypeSizeInBits(PatternValue->
getType());
1179 PatternRepsPerTrip == 1
1181 : Builder.CreateMul(TripCount,
1183 PatternRepsPerTrip));
1189 const SCEV *NumBytesS =
1190 getNumBytes(BECount, IntIdxTy, StoreSizeSCEV, CurLoop,
DL, SE);
1194 if (!Expander.isSafeToExpand(NumBytesS))
1197 Expander.expandCodeFor(NumBytesS, IntIdxTy, Preheader->
getTerminator());
1199 BytesWritten = CI->getZExtValue();
1201 assert(MemsetArg &&
"MemsetArg should have been set");
1205 AATags = AATags.
merge(
Store->getAAMetadata());
1207 AATags = AATags.
extendTo(BytesWritten.value());
1213 NewCall = Builder.CreateMemSet(BasePtr, SplatValue, MemsetArg,
1220 NewCall = Builder.CreateIntrinsicWithoutFolding(
1221 Intrinsic::experimental_memset_pattern,
1222 {DestInt8PtrTy, PatternValue->
getType(), IntIdxTy},
1223 {
BasePtr, PatternValue, MemsetArg,
1236 MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB(
1242 <<
" from store to: " << *Ev <<
" at: " << *TheStore
1248 R <<
"Transformed loop-strided store in "
1250 <<
" function into a call to "
1253 if (!Stores.empty())
1255 for (
auto *
I : Stores) {
1256 R <<
ore::NV(
"FromBlock",
I->getParent()->getName())
1264 for (
auto *
I : Stores) {
1266 MSSAU->removeMemoryAccess(
I,
true);
1270 MSSAU->getMemorySSA()->verifyMemorySSA();
1272 ExpCleaner.markResultUsed();
1279bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
StoreInst *
SI,
1280 const SCEV *BECount) {
1281 assert(
SI->isUnordered() &&
"Expected only non-volatile non-ordered stores.");
1283 Value *StorePtr =
SI->getPointerOperand();
1285 unsigned StoreSize =
DL->getTypeStoreSize(
SI->getValueOperand()->getType());
1298 return processLoopStoreOfLoopLoad(StorePtr, LoadPtr, StoreSizeSCEV,
1300 StoreEv, LoadEv, BECount);
1304class MemmoveVerifier {
1306 explicit MemmoveVerifier(
const SCEV &LoadStart,
const SCEV &StoreStart,
1307 ScalarEvolution &SE)
1308 :
DL(SE.getDataLayout()),
1309 Off(
dyn_cast<SCEVConstant>(SE.getMinusSCEV(&StoreStart, &LoadStart))),
1311 IsSameObject(
Off != nullptr) {}
1313 bool loadAndStoreMayFormMemmove(
unsigned StoreSize,
bool IsNegStride,
1314 const Instruction &TheLoad,
1315 bool IsMemCpy)
const {
1318 if (!Off || !BasePtr)
1320 const APInt &OffVal =
Off->getAPInt();
1325 NullBase->getPointerType()->getPointerAddressSpace()))
1332 LoadSize =
DL.getTypeSizeInBits(TheLoad.
getType()).getFixedValue() / 8;
1333 if (LoadSize != StoreSize)
1338 if (IsNegStride ? OffVal.
slt(LoadSize) : OffVal.
sgt(-LoadSize))
1344 const DataLayout &
DL;
1345 const SCEVConstant *
Off;
1349 const bool IsSameObject;
1353bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
1383 assert(ConstStoreSize &&
"store size is expected to be a constant");
1386 bool IsNegStride = StoreSize == -Stride;
1399 Value *StoreBasePtr = Expander.expandCodeFor(
1400 StrStart, Builder.getPtrTy(StrAS), Preheader->
getTerminator());
1412 IgnoredInsts.
insert(TheStore);
1415 const StringRef InstRemark = IsMemCpy ?
"memcpy" :
"load and store";
1417 bool LoopAccessStore =
1419 StoreSizeSCEV, *
AA, IgnoredInsts);
1420 if (LoopAccessStore) {
1426 IgnoredInsts.
insert(TheLoad);
1428 BECount, StoreSizeSCEV, *
AA, IgnoredInsts)) {
1432 <<
ore::NV(
"Inst", InstRemark) <<
" in "
1434 <<
" function will not be hoisted: "
1435 <<
ore::NV(
"Reason",
"The loop may access store location");
1439 IgnoredInsts.
erase(TheLoad);
1452 Value *LoadBasePtr = Expander.expandCodeFor(LdStart, Builder.getPtrTy(LdAS),
1457 MemmoveVerifier
Verifier(*LdStart, *StrStart, *SE);
1458 if (IsMemCpy && !
Verifier.IsSameObject)
1459 IgnoredInsts.
erase(TheStore);
1461 StoreSizeSCEV, *
AA, IgnoredInsts)) {
1464 <<
ore::NV(
"Inst", InstRemark) <<
" in "
1466 <<
" function will not be hoisted: "
1467 <<
ore::NV(
"Reason",
"The loop may access load location");
1473 bool UseMemMove = IsMemCpy ?
Verifier.IsSameObject : LoopAccessStore;
1482 assert((StoreAlign && LoadAlign) &&
1483 "Expect unordered load/store to have align.");
1484 if (*StoreAlign < StoreSize || *LoadAlign < StoreSize)
1491 if (StoreSize >
TTI->getAtomicMemIntrinsicMaxElementSize())
1496 if (!
Verifier.loadAndStoreMayFormMemmove(StoreSize, IsNegStride, *TheLoad,
1500 if (avoidLIRForMultiBlockLoop())
1505 const SCEV *NumBytesS =
1506 getNumBytes(BECount, IntIdxTy, StoreSizeSCEV, CurLoop,
DL, SE);
1509 Expander.expandCodeFor(NumBytesS, IntIdxTy, Preheader->
getTerminator());
1513 AATags = AATags.
merge(StoreAATags);
1515 AATags = AATags.
extendTo(CI->getZExtValue());
1525 NewCall = Builder.CreateMemMove(StoreBasePtr, StoreAlign, LoadBasePtr,
1526 LoadAlign, NumBytes,
1530 Builder.CreateMemCpy(StoreBasePtr, StoreAlign, LoadBasePtr, LoadAlign,
1531 NumBytes,
false, AATags);
1536 NewCall = Builder.CreateElementUnorderedAtomicMemCpy(
1537 StoreBasePtr, *StoreAlign, LoadBasePtr, *LoadAlign, NumBytes, StoreSize,
1543 MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB(
1549 <<
" from load ptr=" << *LoadEv <<
" at: " << *TheLoad
1551 <<
" from store ptr=" << *StoreEv <<
" at: " << *TheStore
1557 <<
"Formed a call to "
1559 <<
"() intrinsic from " <<
ore::NV(
"Inst", InstRemark)
1570 MSSAU->removeMemoryAccess(TheStore,
true);
1573 MSSAU->getMemorySSA()->verifyMemorySSA();
1578 ExpCleaner.markResultUsed();
1585bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(
bool IsMemset,
1586 bool IsLoopMemset) {
1587 if (ApplyCodeSizeHeuristics && CurLoop->
getNumBlocks() > 1) {
1588 if (CurLoop->
isOutermost() && (!IsMemset || !IsLoopMemset)) {
1590 <<
" : LIR " << (IsMemset ?
"Memset" :
"Memcpy")
1591 <<
" avoided: multi-block top-level loop\n");
1599bool LoopIdiomRecognize::optimizeCRCLoop(
const PolynomialInfo &Info) {
1619 TTI->getArithmeticInstrCost(Instruction::Xor, CRCTy,
CostKind);
1621 TTI->getArithmeticInstrCost(Instruction::LShr, CRCTy,
CostKind);
1623 TTI->getArithmeticInstrCost(Instruction::And, CRCTy,
CostKind);
1628 TTI->getMemoryOpCost(Instruction::Load, CRCTy,
DL->getABITypeAlign(CRCTy),
1629 DL->getDefaultGlobalsAddressSpace(),
CostKind);
1630 auto ClmulCost = [&](
unsigned BW) {
1633 return TTI->getIntrinsicInstrCost(Attrs,
CostKind);
1638 (2 * ShiftCost + 2 * XorCost + AndCost + SelectCost) *
Info.TripCount;
1643 Info.TripCount % 8 != 0
1645 : (LoadCost + XorCost + 2 * ShiftCost) * (
Info.TripCount / 8);
1649 ClmulCost(CRCBW +
Info.TripCount) +
1650 2 * XorCost + 2 * ShiftCost + AndCost;
1656 <<
"CRC loop costs: original="
1657 <<
ore::NV(
"OrigLoopCost", OrigLoopCost)
1658 <<
", table=" <<
ore::NV(
"TableStrategyCost", TableStrategyCost)
1659 <<
", clmul=" <<
ore::NV(
"ClmulStrategyCost", ClmulStrategyCost);
1662 auto ReportMissed = [&](
StringRef Reason) {
1667 <<
"CRC loop not optimized: " << Reason;
1674 <<
"CRC loop optimized using " <<
ore::NV(
"Strategy", Strategy)
1681 ReportMissed(
"disabled by user");
1686 if (
Info.TripCount % 8 == 0) {
1687 optimizeCRCLoopUsingTableLookup(Info);
1688 ReportOptimized(
"table",
"forced by user");
1691 ReportMissed(
"table strategy forced, but not possible");
1694 optimizeCRCLoopUsingClmul(Info);
1695 ReportOptimized(
"clmul",
"forced by user");
1703 if (ApplyCodeSizeHeuristics) {
1704 ReportMissed(
"optimizing for size");
1709 if (std::min(TableStrategyCost, ClmulStrategyCost) >= OrigLoopCost) {
1710 ReportMissed(
"no profitable strategy");
1714 if (TableStrategyCost <= ClmulStrategyCost) {
1715 optimizeCRCLoopUsingTableLookup(Info);
1716 ReportOptimized(
"table",
"most profitable strategy");
1718 optimizeCRCLoopUsingClmul(Info);
1719 ReportOptimized(
"clmul",
"most profitable strategy");
1728void LoopIdiomRecognize::optimizeCRCLoopUsingClmul(
const PolynomialInfo &Info) {
1737 unsigned TC =
Info.TripCount;
1748 ConstantInt::get(Ctx, Mu.zextOrTrunc(ClmulMuTy->
getBitWidth()));
1749 Value *GenPolyConst =
1750 ConstantInt::get(Ctx, FullGenPoly.zext(ClmulGPTy->
getBitWidth()));
1757 bool SetupShiftNeeded =
Info.IsBigEndian && TC != CRCBW;
1773 Value *ClmulMuInput =
1774 Builder.CreateZExtOrTrunc(
Info.LHS, SetupTy,
"crc.cast");
1780 Data = Builder.CreateZExtOrTrunc(
Data, SetupTy,
"data.cast");
1782 ClmulMuInput = Builder.CreateXor(ClmulMuInput,
Data,
"xor.crc.data");
1786 if (SetupShiftNeeded) {
1789 ? Builder.CreateShl(ClmulMuInput, TC - CRCBW,
"crc.align.tc")
1790 : Builder.CreateLShr(ClmulMuInput, CRCBW - TC,
"crc.align.tc");
1795 if (SetupTy->getBitWidth() > TC) {
1798 ClmulMuInput = Builder.CreateAnd(ClmulMuInput, Mask,
"crc.tcbits");
1804 Builder.CreateZExtOrTrunc(ClmulMuInput, ClmulMuTy,
"tcbits.cast");
1805 Value *ClmulMu = Builder.CreateBinaryIntrinsic(
1806 Intrinsic::clmul, ClmulMuInput, MuConst, {},
"clmul.mu");
1809 Value *ClmulGPInput =
1810 Info.IsBigEndian ? Builder.CreateLShr(ClmulMu, TC,
"quot.lshr") : ClmulMu;
1815 Builder.CreateZExtOrTrunc(ClmulGPInput, ClmulGPTy,
"quot.cast");
1816 Value *ClmulGP = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, ClmulGPInput,
1823 Value *CRCNext = Builder.CreateZExt(
Info.LHS, ClmulGPTy,
"crc.recast");
1824 if (
Info.IsBigEndian)
1825 CRCNext = Builder.CreateShl(CRCNext, TC,
"crc.shl");
1828 CRCNext = Builder.CreateXor(CRCNext, ClmulGP,
"xor.crc.mult");
1829 if (!
Info.IsBigEndian)
1830 CRCNext = Builder.CreateLShr(CRCNext, TC,
"crc.lshr");
1833 CRCNext = Builder.CreateTrunc(CRCNext, CRCTy,
"crc.next");
1836 Info.ComputedValue->replaceUsesOutsideBlock(CRCNext, CurLoop->
getLoopLatch());
1850 Ctx, BrInst->getSuccessor(0) == CurLoop->
getExitBlock()));
1855void LoopIdiomRecognize::optimizeCRCLoopUsingTableLookup(
1857 assert(
Info.TripCount % 8 == 0 &&
"A byte-multiple trip count is required");
1863 std::array<Constant *, 256> CRCConstants;
1865 CRCConstants.begin(),
1866 [CRCTy](
const APInt &
E) { return ConstantInt::get(CRCTy, E); });
1888 unsigned NewBTC = (
Info.TripCount / 8) - 1;
1895 Value *ExitLimit = ConstantInt::get(
IV->getType(), NewBTC);
1897 Value *NewExitCond =
1898 Builder.CreateICmp(ExitPred,
IV, ExitLimit,
"exit.cond");
1920 Op = CRCBW > 8 ? Builder.CreateLShr(
Op, CRCBW - 8, Name)
1921 : Builder.CreateShl(
Op, 8 - CRCBW, Name);
1923 return LoByte(Builder,
Op, Name +
".lo.byte");
1931 PHINode *CRCPhi = Builder.CreatePHI(CRCTy, 2,
"crc");
1935 Value *CRC = CRCPhi;
1939 Value *Indexer = CRC;
1947 Value *IVBits = Builder.CreateZExtOrTrunc(
1948 Builder.CreateShl(
IV, 3,
"iv.bits"), DataTy,
"iv.indexer");
1949 Value *DataIndexer =
1950 Info.IsBigEndian ? Builder.CreateShl(
Data, IVBits,
"data.indexer")
1951 : Builder.CreateLShr(
Data, IVBits,
"data.indexer");
1952 Indexer = Builder.CreateXor(
1954 Builder.CreateZExtOrTrunc(Indexer, DataTy,
"crc.indexer.cast"),
1955 "crc.data.indexer");
1958 Indexer =
Info.IsBigEndian ? HiIdx(Builder, Indexer,
"indexer.hi")
1959 : LoByte(Builder, Indexer,
"indexer.lo");
1962 Indexer = Builder.CreateZExt(
1967 Value *CRCTableGEP =
1968 Builder.CreateInBoundsGEP(CRCTy, GV, Indexer,
"tbl.ptradd");
1969 Instruction *CRCTableLd = Builder.CreateLoad(CRCTy, CRCTableGEP,
"tbl.ld");
1973 auto *NewMemAcc = MSSAU->createMemoryAccessInBB(
1974 CRCTableLd,
nullptr, CRCTableLd->getParent(),
1981 Value *CRCNext = CRCTableLd;
1984 ? Builder.CreateShl(CRC, 8,
"crc.be.shift")
1985 : Builder.CreateLShr(CRC, 8,
"crc.le.shift");
1986 CRCNext = Builder.CreateXor(CRCShift, CRCTableLd,
"crc.next");
1991 Info.ComputedValue->replaceUsesOutsideBlock(CRCNext,
2001 MSSAU->getMemorySSA()->verifyMemorySSA();
2005bool LoopIdiomRecognize::runOnNoncountableLoop() {
2008 <<
"] Noncountable Loop %"
2011 return recognizePopcount() || recognizeAndInsertFFS() ||
2012 recognizeShiftUntilBitTest() || recognizeShiftUntilZero() ||
2013 recognizeShiftUntilLessThan() || recognizeAndInsertStrLen();
2023 bool JmpOnZero =
false) {
2029 if (!CmpZero || !CmpZero->isZero())
2040 return Cond->getOperand(0);
2047class StrlenVerifier {
2049 explicit StrlenVerifier(
const Loop *CurLoop, ScalarEvolution *SE,
2050 const TargetLibraryInfo *TLI)
2051 : CurLoop(CurLoop), SE(SE), TLI(TLI) {}
2053 bool isValidStrlenIdiom() {
2072 if (!LoopBody || LoopBody->
size() >= 15)
2093 const SCEV *LoadEv = SE->
getSCEV(IncPtr);
2106 if (OpWidth != StepSize * 8)
2108 if (OpWidth != 8 && OpWidth != 16 && OpWidth != 32)
2111 if (OpWidth != WcharSize * 8)
2115 for (Instruction &
I : *LoopBody)
2116 if (
I.mayHaveSideEffects())
2123 for (PHINode &PN : LoopExitBB->
phis()) {
2127 const SCEV *Ev = SE->
getSCEV(&PN);
2137 if (!AddRecEv || !AddRecEv->
isAffine())
2151 const Loop *CurLoop;
2152 ScalarEvolution *SE;
2153 const TargetLibraryInfo *TLI;
2156 ConstantInt *StepSizeCI;
2157 const SCEV *LoadBaseEv;
2222bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
2226 StrlenVerifier
Verifier(CurLoop, SE, TLI);
2228 if (!
Verifier.isValidStrlenIdiom())
2235 assert(Preheader && LoopBody && LoopExitBB &&
2236 "Should be verified to be valid by StrlenVerifier");
2251 Builder.SetCurrentDebugLocation(CurLoop->
getStartLoc());
2253 Value *MaterialzedBase = Expander.expandCodeFor(
2255 Builder.GetInsertPoint());
2257 Value *StrLenFunc =
nullptr;
2259 StrLenFunc =
emitStrLen(MaterialzedBase, Builder, *
DL, TLI);
2261 StrLenFunc =
emitWcsLen(MaterialzedBase, Builder, *
DL, TLI);
2263 assert(StrLenFunc &&
"Failed to emit strlen function.");
2282 StrlenEv,
Base->getType())));
2284 Value *MaterializedPHI = Expander.expandCodeFor(NewEv, NewEv->
getType(),
2285 Builder.GetInsertPoint());
2300 "loop body must have a successor that is it self");
2302 ? Builder.getFalse()
2303 : Builder.getTrue();
2308 LLVM_DEBUG(
dbgs() <<
" Formed strlen idiom: " << *StrLenFunc <<
"\n");
2312 <<
"Transformed " << StrLenFunc->
getName() <<
" loop idiom";
2337 return Cond->getOperand(0);
2348 if (PhiX && PhiX->getParent() == LoopEntry &&
2349 (PhiX->getOperand(0) == DefX || PhiX->
getOperand(1) == DefX))
2416 if (DefX->
getOpcode() != Instruction::LShr)
2419 IntrinID = Intrinsic::ctlz;
2421 if (!Shft || !Shft->
isOne())
2435 if (Inst.
getOpcode() != Instruction::Add)
2487 Value *VarX1, *VarX0;
2490 DefX2 = CountInst =
nullptr;
2491 VarX1 = VarX0 =
nullptr;
2492 PhiX = CountPhi =
nullptr;
2505 if (!DefX2 || DefX2->
getOpcode() != Instruction::And)
2516 if (!SubOneOp || SubOneOp->
getOperand(0) != VarX1)
2522 (SubOneOp->
getOpcode() == Instruction::Add &&
2535 CountInst =
nullptr;
2538 if (Inst.
getOpcode() != Instruction::Add)
2542 if (!Inc || !Inc->
isOne())
2550 bool LiveOutLoop =
false;
2579 CntInst = CountInst;
2619 Value *VarX =
nullptr;
2633 if (!DefX || !DefX->
isShift())
2635 IntrinID = DefX->
getOpcode() == Instruction::Shl ? Intrinsic::cttz :
2638 if (!Shft || !Shft->
isOne())
2663 if (Inst.
getOpcode() != Instruction::Add)
2686bool LoopIdiomRecognize::isProfitableToInsertFFS(
Intrinsic::ID IntrinID,
2687 Value *InitX,
bool ZeroCheck,
2688 size_t CanonicalSize) {
2706bool LoopIdiomRecognize::insertFFSIfProfitable(
Intrinsic::ID IntrinID,
2710 bool IsCntPhiUsedOutsideLoop =
false;
2713 IsCntPhiUsedOutsideLoop =
true;
2716 bool IsCntInstUsedOutsideLoop =
false;
2719 IsCntInstUsedOutsideLoop =
true;
2724 if (IsCntInstUsedOutsideLoop && IsCntPhiUsedOutsideLoop)
2730 bool ZeroCheck =
false;
2739 if (!IsCntPhiUsedOutsideLoop) {
2758 size_t IdiomCanonicalSize = 6;
2759 if (!isProfitableToInsertFFS(IntrinID, InitX, ZeroCheck, IdiomCanonicalSize))
2762 transformLoopToCountable(IntrinID, PH, CntInst, CntPhi, InitX, DefX,
2764 IsCntPhiUsedOutsideLoop);
2771bool LoopIdiomRecognize::recognizeAndInsertFFS() {
2786 return insertFFSIfProfitable(IntrinID, InitX, DefX, CntPhi, CntInst);
2789bool LoopIdiomRecognize::recognizeShiftUntilLessThan() {
2800 APInt LoopThreshold;
2802 CntPhi, DefX, LoopThreshold))
2805 if (LoopThreshold == 2) {
2807 return insertFFSIfProfitable(IntrinID, InitX, DefX, CntPhi, CntInst);
2811 if (LoopThreshold != 4)
2829 APInt PreLoopThreshold;
2831 PreLoopThreshold != 2)
2834 bool ZeroCheck =
true;
2843 size_t IdiomCanonicalSize = 6;
2844 if (!isProfitableToInsertFFS(IntrinID, InitX, ZeroCheck, IdiomCanonicalSize))
2848 transformLoopToCountable(IntrinID, PH, CntInst, CntPhi, InitX, DefX,
2859bool LoopIdiomRecognize::recognizePopcount() {
2873 if (LoopBody->
size() >= 20) {
2901 transformLoopToPopcount(PreCondBB, CntInst, CntPhi, Val);
2955void LoopIdiomRecognize::transformLoopToCountable(
2958 bool ZeroCheck,
bool IsCntPhiUsedOutsideLoop,
bool InsertSub) {
2961 Builder.SetCurrentDebugLocation(
DL);
2970 if (IsCntPhiUsedOutsideLoop) {
2971 if (DefX->
getOpcode() == Instruction::AShr)
2972 InitXNext = Builder.CreateAShr(InitX, 1);
2973 else if (DefX->
getOpcode() == Instruction::LShr)
2974 InitXNext = Builder.CreateLShr(InitX, 1);
2975 else if (DefX->
getOpcode() == Instruction::Shl)
2976 InitXNext = Builder.CreateShl(InitX, 1);
2984 Count = Builder.CreateSub(
2987 Count = Builder.CreateSub(
Count, ConstantInt::get(CountTy, 1));
2989 if (IsCntPhiUsedOutsideLoop)
2990 Count = Builder.CreateAdd(
Count, ConstantInt::get(CountTy, 1));
2992 NewCount = Builder.CreateZExtOrTrunc(NewCount, CntInst->
getType());
2999 if (!InitConst || !InitConst->
isZero())
3000 NewCount = Builder.CreateAdd(NewCount, CntInitVal);
3004 NewCount = Builder.CreateSub(CntInitVal, NewCount);
3022 Builder.SetInsertPoint(LbCond);
3024 TcPhi, ConstantInt::get(CountTy, 1),
"tcdec",
false,
true));
3033 LbCond->
setOperand(1, ConstantInt::get(CountTy, 0));
3037 if (IsCntPhiUsedOutsideLoop)
3047void LoopIdiomRecognize::transformLoopToPopcount(
BasicBlock *PreCondBB,
3060 Value *PopCnt, *PopCntZext, *NewCount, *TripCnt;
3063 NewCount = PopCntZext =
3066 if (NewCount != PopCnt)
3075 if (!InitConst || !InitConst->
isZero()) {
3076 NewCount = Builder.CreateAdd(NewCount, CntInitVal);
3088 Value *Opnd0 = PopCntZext;
3089 Value *Opnd1 = ConstantInt::get(PopCntZext->
getType(), 0);
3094 Builder.CreateICmp(PreCond->
getPredicate(), Opnd0, Opnd1));
3095 PreCondBr->setCondition(NewPreCond);
3129 Builder.SetInsertPoint(LbCond);
3131 Builder.CreateSub(TcPhi, ConstantInt::get(Ty, 1),
3132 "tcdec",
false,
true));
3141 LbCond->
setOperand(1, ConstantInt::get(Ty, 0));
3162 template <
typename ITy>
bool match(ITy *V)
const {
3163 return L->isLoopInvariant(V) &&
SubPattern.match(V);
3168template <
typename Ty>
3199 " Performing shift-until-bittest idiom detection.\n");
3209 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3216 Value *CmpLHS, *CmpRHS;
3227 auto MatchVariableBitMask = [&]() {
3237 auto MatchDecomposableConstantBitMask = [&]() {
3239 CmpLHS, CmpRHS, Pred,
true,
3241 if (Res && Res->Mask.isPowerOf2()) {
3245 BitMask = ConstantInt::get(CurrX->
getType(), Res->Mask);
3246 BitPos = ConstantInt::get(CurrX->
getType(), Res->Mask.logBase2());
3252 if (!MatchVariableBitMask() && !MatchDecomposableConstantBitMask()) {
3259 if (!CurrXPN || CurrXPN->getParent() != LoopHeaderBB) {
3264 BaseX = CurrXPN->getIncomingValueForBlock(LoopPreheaderBB);
3269 "Expected BaseX to be available in the preheader!");
3280 "Should only get equality predicates here.");
3290 if (TrueBB != LoopHeaderBB) {
3349bool LoopIdiomRecognize::recognizeShiftUntilBitTest() {
3350 bool MadeChange =
false;
3352 Value *
X, *BitMask, *BitPos, *XCurr;
3357 " shift-until-bittest idiom detection failed.\n");
3367 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3370 assert(SuccessorBB &&
"There is only a single successor.");
3376 Type *Ty =
X->getType();
3390 " Intrinsic is too costly, not beneficial\n");
3393 if (
TTI->getArithmeticInstrCost(Instruction::Shl, Ty,
CostKind) >
3405 std::optional<BasicBlock::iterator> InsertPt = std::nullopt;
3407 InsertPt = BitPosI->getInsertionPointAfterDef();
3415 return U.getUser() != BitPosFrozen;
3417 BitPos = BitPosFrozen;
3423 BitPos->
getName() +
".lowbitmask");
3425 Builder.CreateOr(LowBitMask, BitMask, BitPos->
getName() +
".mask");
3426 Value *XMasked = Builder.CreateAnd(
X, Mask,
X->getName() +
".masked");
3427 Value *XMaskedNumLeadingZeros = Builder.CreateIntrinsic(
3428 IntrID, Ty, {XMasked, Builder.getTrue()},
3429 nullptr, XMasked->
getName() +
".numleadingzeros");
3430 Value *XMaskedNumActiveBits = Builder.CreateSub(
3432 XMasked->
getName() +
".numactivebits",
true,
3434 Value *XMaskedLeadingOnePos =
3436 XMasked->
getName() +
".leadingonepos",
false,
3439 Value *LoopBackedgeTakenCount = Builder.CreateSub(
3440 BitPos, XMaskedLeadingOnePos, CurLoop->
getName() +
".backedgetakencount",
3444 Value *LoopTripCount =
3445 Builder.CreateAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
3446 CurLoop->
getName() +
".tripcount",
true,
3453 Value *NewX = Builder.CreateShl(
X, LoopBackedgeTakenCount);
3456 I->copyIRFlags(XNext,
true);
3468 NewXNext = Builder.CreateShl(
X, LoopTripCount);
3473 NewXNext = Builder.CreateShl(NewX, ConstantInt::get(Ty, 1));
3478 I->copyIRFlags(XNext,
true);
3489 Builder.SetInsertPoint(LoopHeaderBB, LoopHeaderBB->
begin());
3490 auto *
IV = Builder.CreatePHI(Ty, 2, CurLoop->
getName() +
".iv");
3496 Builder.CreateAdd(
IV, ConstantInt::get(Ty, 1),
IV->getName() +
".next",
3497 true, Bitwidth != 2);
3500 auto *IVCheck = Builder.CreateICmpEQ(IVNext, LoopTripCount,
3501 CurLoop->
getName() +
".ivcheck");
3503 const bool HasBranchWeights =
3507 auto *BI = Builder.CreateCondBr(IVCheck, SuccessorBB, LoopHeaderBB);
3508 if (HasBranchWeights) {
3510 std::swap(BranchWeights[0], BranchWeights[1]);
3520 IV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
3521 IV->addIncoming(IVNext, LoopHeaderBB);
3532 ++NumShiftUntilBitTest;
3568 const SCEV *&ExtraOffsetExpr,
3569 bool &InvertedCond) {
3571 " Performing shift-until-zero idiom detection.\n");
3584 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3595 !
match(ValShiftedIsZero,
3609 IntrinID = ValShifted->
getOpcode() == Instruction::Shl ? Intrinsic::cttz
3618 else if (
match(NBits,
3622 ExtraOffsetExpr = SE->
getSCEV(ExtraOffset);
3630 if (!IVPN || IVPN->getParent() != LoopHeaderBB) {
3635 Start = IVPN->getIncomingValueForBlock(LoopPreheaderBB);
3646 "Should only get equality predicates here.");
3657 if (FalseBB != LoopHeaderBB) {
3668 if (ValShifted->
getOpcode() == Instruction::AShr &&
3732bool LoopIdiomRecognize::recognizeShiftUntilZero() {
3733 bool MadeChange =
false;
3739 const SCEV *ExtraOffsetExpr;
3742 Start, Val, ExtraOffsetExpr, InvertedCond)) {
3744 " shift-until-zero idiom detection failed.\n");
3754 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3757 assert(SuccessorBB &&
"There is only a single successor.");
3760 Builder.SetCurrentDebugLocation(
IV->getDebugLoc());
3776 " Intrinsic is too costly, not beneficial\n");
3783 bool OffsetIsZero = ExtraOffsetExpr->
isZero();
3787 Value *ValNumLeadingZeros = Builder.CreateIntrinsic(
3788 IntrID, Ty, {Val, Builder.getFalse()},
3789 nullptr, Val->
getName() +
".numleadingzeros");
3790 Value *ValNumActiveBits = Builder.CreateSub(
3792 Val->
getName() +
".numactivebits",
true,
3796 Expander.setInsertPoint(&*Builder.GetInsertPoint());
3797 Value *ExtraOffset = Expander.expandCodeFor(ExtraOffsetExpr);
3799 Value *ValNumActiveBitsOffset = Builder.CreateAdd(
3800 ValNumActiveBits, ExtraOffset, ValNumActiveBits->
getName() +
".offset",
3801 OffsetIsZero,
true);
3802 Value *IVFinal = Builder.CreateIntrinsic(Intrinsic::smax, {Ty},
3803 {ValNumActiveBitsOffset,
Start},
3804 nullptr,
"iv.final");
3807 IVFinal, Start, CurLoop->
getName() +
".backedgetakencount",
3808 OffsetIsZero,
true));
3812 Value *LoopTripCount =
3813 Builder.CreateAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
3814 CurLoop->
getName() +
".tripcount",
true,
3820 IV->replaceUsesOutsideBlock(IVFinal, LoopHeaderBB);
3825 Builder.SetInsertPoint(LoopHeaderBB, LoopHeaderBB->
begin());
3826 auto *CIV = Builder.CreatePHI(Ty, 2, CurLoop->
getName() +
".iv");
3831 Builder.CreateAdd(CIV, ConstantInt::get(Ty, 1), CIV->getName() +
".next",
3832 true, Bitwidth != 2);
3835 auto *CIVCheck = Builder.CreateICmpEQ(CIVNext, LoopTripCount,
3836 CurLoop->
getName() +
".ivcheck");
3837 auto *NewIVCheck = CIVCheck;
3839 NewIVCheck = Builder.CreateNot(CIVCheck);
3840 NewIVCheck->takeName(ValShiftedIsZero);
3844 auto *IVDePHId = Builder.CreateAdd(CIV, Start,
"",
false,
3846 IVDePHId->takeName(
IV);
3851 const bool HasBranchWeights =
3855 auto *BI = Builder.CreateCondBr(CIVCheck, SuccessorBB, LoopHeaderBB);
3856 if (HasBranchWeights) {
3858 std::swap(BranchWeights[0], BranchWeights[1]);
3866 CIV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
3867 CIV->addIncoming(CIVNext, LoopHeaderBB);
3875 IV->replaceAllUsesWith(IVDePHId);
3876 IV->eraseFromParent();
3885 ++NumShiftUntilZero;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
This file defines the DenseMap class.
ManagedStatic< HTTPClientCleanup > Cleanup
static bool mayLoopAccessLocation(Value *Ptr, ModRefInfo Access, Loop *L, const SCEV *BECount, unsigned StoreSize, AliasAnalysis &AA, SmallPtrSetImpl< Instruction * > &Ignored)
mayLoopAccessLocation - Return true if the specified loop might access the specified pointer location...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
This file defines an InstructionCost class that is used when calculating the cost of an instruction,...
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static PHINode * getRecurrenceVar(Value *VarX, Instruction *DefX, BasicBlock *LoopEntry)
static Value * createPopcntIntrinsic(IRBuilder<> &IRBuilder, Value *Val, const DebugLoc &DL)
static Value * matchShiftULTCondition(CondBrInst *BI, BasicBlock *LoopEntry, APInt &Threshold)
Check if the given conditional branch is based on an unsigned less-than comparison between a variable...
static bool detectShiftUntilLessThanIdiom(Loop *CurLoop, const DataLayout &DL, Intrinsic::ID &IntrinID, Value *&InitX, Instruction *&CntInst, PHINode *&CntPhi, Instruction *&DefX, APInt &Threshold)
Return true if the idiom is detected in the loop.
static Value * matchCondition(CondBrInst *BI, BasicBlock *LoopEntry, bool JmpOnZero=false)
Check if the given conditional branch is based on the comparison between a variable and zero,...
static bool detectShiftUntilBitTestIdiom(Loop *CurLoop, Value *&BaseX, Value *&BitMask, Value *&BitPos, Value *&CurrX, Instruction *&NextX)
Return true if the idiom is detected in the loop.
static bool detectPopcountIdiom(Loop *CurLoop, BasicBlock *PreCondBB, Instruction *&CntInst, PHINode *&CntPhi, Value *&Var)
Return true iff the idiom is detected in the loop.
static Constant * getMemSetPatternValue(Value *V, const DataLayout *DL)
getMemSetPatternValue - If a strided store of the specified value is safe to turn into a memset....
static const SCEV * getNumBytes(const SCEV *BECount, Type *IntPtr, const SCEV *StoreSizeSCEV, Loop *CurLoop, const DataLayout *DL, ScalarEvolution *SE)
Compute the number of bytes as a SCEV from the backedge taken count.
static bool detectShiftUntilZeroIdiom(Loop *CurLoop, const DataLayout &DL, Intrinsic::ID &IntrinID, Value *&InitX, Instruction *&CntInst, PHINode *&CntPhi, Instruction *&DefX)
Return true if the idiom is detected in the loop.
static Value * createFFSIntrinsic(IRBuilder<> &IRBuilder, Value *Val, const DebugLoc &DL, bool ZeroCheck, Intrinsic::ID IID)
static const SCEV * getStartForNegStride(const SCEV *Start, const SCEV *BECount, Type *IntPtr, const SCEV *StoreSizeSCEV, ScalarEvolution *SE)
static APInt getStoreStride(const SCEVAddRecExpr *StoreEv)
match_LoopInvariant< Ty > m_LoopInvariant(const Ty &M, const Loop *L)
Matches if the value is loop-invariant.
static bool isSameByteValueStore(Instruction &I, Value *SplatByte, Loop *L, const DataLayout &DL)
Return true if I is a (simple, loop-invariant-valued) store of the same bytewise value SplatByte.
static void deleteDeadInstruction(Instruction *I)
This file implements a map that provides insertion order iteration.
This file provides utility analysis objects describing memory locations.
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 ...
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
verify safepoint Safepoint IR Verifier
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
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)
static SymbolRef::Type getType(const Symbol *Sym)
static const uint32_t IV[8]
Class for arbitrary precision integers.
std::optional< uint64_t > tryZExtValue() const
Get zero extended value if possible.
uint64_t getZExtValue() const
Get zero extended value.
bool sgt(const APInt &RHS) const
Signed greater than comparison.
unsigned getBitWidth() const
Return the number of bits in the APInt.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
bool slt(const APInt &RHS) const
Signed less than comparison.
int64_t getSExtValue() const
Get sign extended value.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
const Function * getParent() const
Return the enclosing method, or null if none.
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 BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const Instruction & front() const
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI const_iterator getFirstNonPHIOrDbgOrAlloca() const
Returns an iterator to the first instruction in this block that is not a PHINode, a debug intrinsic,...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
LLVM_ABI const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
BinaryOps getOpcode() const
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
This class represents a function call, abstracting a target machine's calling convention.
void setPredicate(Predicate P)
Set the predicate for this instruction to the specified value.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLE
signed less or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_ULT
unsigned less than
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
Conditional Branch instruction.
void setCondition(Value *V)
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
This is the shared class of boolean and integer constants.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const
Returns the type of a GEP index in AddressSpace.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
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.
This class represents a freeze function that returns random concrete value if an operand is either a ...
PointerType * getType() const
Global values are always pointers.
@ PrivateLinkage
Like Internal, but omit from symbol table.
static LLVM_ABI CRCTable genSarwateTable(const APInt &GenPoly, bool IsBigEndian)
Generate a lookup table of 256 entries by interleaving the generating polynomial.
static LLVM_ABI std::pair< APInt, APInt > genBarrettConstants(const PolynomialInfo &Info)
Auxilary entry point after analysis to generate constants for a GF(2) Barrett Reduction.
This instruction compares its operands according to the predicate given to the constructor.
bool isEquality() const
Return true if this predicate is either EQ or NE.
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
Common base class shared among various IRBuilders.
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static InstructionCost getInvalid(CostType Val=0)
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI void setAAMetadata(const AAMDNodes &N)
Sets the AA metadata on this instruction from the AAMDNodes structure.
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Class to represent integer types.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
This is an important class for using LLVM in a threaded context.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
An instruction for reading from memory.
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
Value * getPointerOperand()
bool isVolatile() const
Return true if this is a load from a volatile memory location.
Align getAlign() const
Return the alignment of the access that is being performed.
static LocationSize precise(uint64_t Value)
static constexpr LocationSize afterPointer()
Any location after the base pointer (but still within the underlying object).
bool contains(const LoopT *L) const
Return true if the specified loop is contained within this loop.
bool isOutermost() const
Return true if the loop does not have a parent (natural) loop.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
unsigned getNumBlocks() const
Get the number of blocks in this loop in constant time.
unsigned getNumBackEdges() const
Calculate the number of back edges to the loop header.
BlockT * getHeader() const
BlockT * getExitBlock() const
If getExitBlocks would return exactly one block, return that block.
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.
block_iterator block_begin() const
BlockT * getUniqueExitBlock() const
If getUniqueExitBlocks would return exactly one block, return that block.
LLVM_ABI PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
DebugLoc getStartLoc() const
Return the debug location of the start of this loop.
bool isLoopInvariant(const Value *V) const
Return true if the specified value is loop invariant.
ICmpInst * getLatchCmpInst() const
Get the latch condition instruction.
StringRef getName() const
PHINode * getCanonicalInductionVariable() const
Check to see if the loop has a canonical induction variable: an integer recurrence that starts at 0 a...
This class wraps the llvm.memcpy intrinsic.
Value * getLength() const
Value * getDest() const
This is just like getRawDest, but it strips off any cast instructions (including addrspacecast) that ...
MaybeAlign getDestAlign() const
bool isForceInlined() const
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
MaybeAlign getSourceAlign() const
Value * getSource() const
This is just like getRawSource, but it strips off any cast instructions that feed it,...
Representation for a specific memory location.
An analysis that produces MemorySSA for a function.
Encapsulates MemorySSA, including all data associated with memory accesses.
A Module instance is used to store all the information related to an LLVM module.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
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 LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
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.
This node represents a polynomial recurrence on the trip count of the specified loop.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values.
SCEVUse getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
This class represents a constant integer value.
ConstantInt * getValue() const
const APInt & getAPInt() const
Helper to remove instructions inserted during SCEV expansion, unless they are marked as used.
This class uses information about analyze scalars to rewrite expressions in canonical form.
SCEVUse getOperand(unsigned i) const
This class represents an analyzed expression in the program.
LLVM_ABI bool isOne() const
Return true if the expression is a constant one.
static constexpr auto FlagNUW
LLVM_ABI bool isZero() const
Return true if the expression is a constant zero.
LLVM_ABI bool isNonConstantNegative() const
Return true if the specified scev is negated, but not a constant.
Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
const DataLayout & getDataLayout() const
Return the DataLayout associated with the module this SCEV instance is operating on.
LLVM_ABI bool isKnownNonNegative(const SCEV *S)
Test if the given expression is known to be non-negative.
LLVM_ABI const SCEV * getNegativeSCEV(const SCEV *V, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
Return the SCEV object corresponding to -V.
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...
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
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.
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI const SCEV * getTripCountFromExitCount(const SCEV *ExitCount)
A version of getTripCountFromExitCount below which always picks an evaluation type which can not resu...
LLVM_ABI void forgetLoop(const Loop *L)
This method should be called by the client when it has changed a loop in a way that may effect Scalar...
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 isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI bool hasLoopInvariantBackedgeTakenCount(const Loop *L)
Return true if the specified loop has an analyzable loop-invariant backedge-taken count.
LLVM_ABI const SCEV * getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
LLVM_ABI const SCEV * getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI const SCEV * applyLoopGuards(const SCEV *Expr, const Loop *L)
Try to apply information from loop guards for L to Expr.
LLVM_ABI const SCEV * getTruncateOrZeroExtend(const SCEV *V, Type *Ty, unsigned Depth=0)
Return a SCEV corresponding to a conversion of the input value to the specified type.
LLVM_ABI const SCEV * getTruncateOrSignExtend(const SCEV *V, Type *Ty, unsigned Depth=0)
Return a SCEV corresponding to a conversion of the input value to the specified type.
A vector that has set insertion semantics.
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
Simple and conservative implementation of LoopSafetyInfo that can give false-positive answers to its ...
void computeLoopSafetyInfo(const Loop *CurLoop) override
Computes safety information for a loop checks loop body & header for the possibility of may throw exc...
bool anyBlockMayThrow() const override
Returns true iff any block of the loop for which this info is contains an instruction that may throw ...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
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.
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.
An instruction for storing to memory.
Value * getValueOperand()
Value * getPointerOperand()
Represent a constant reference to a string, i.e.
Provides information about what library functions are available for the current target.
unsigned getWCharSize(const Module &M) const
Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
bool has(LibFunc F) const
Tests whether a library function is available.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
A Use represents the edge between a Value definition and its users.
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 hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
LLVM_ABI void replaceUsesOutsideBlock(Value *V, BasicBlock *BB)
replaceUsesOutsideBlock - Go through the uses list for this definition and make each use point to "V"...
LLVM_ABI bool replaceUsesWithIf(Value *New, llvm::function_ref< bool(Use &U)> ShouldReplace)
Go through the uses list for this definition and make each use point to "V" if the callback ShouldRep...
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Value handle that is nullable, but tries to track the Value.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
OperandType
Operands are tagged with one of the values of this enum.
match_combine_and< Ty... > m_CombineAnd(const Ty &...Ps)
Combine pattern matchers matching all of Ps patterns.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
bool match(Val *V, const Pattern &P)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
auto m_BasicBlock()
Match an arbitrary basic block value and ignore it.
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)
Matches shift operations.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
bind_cst_ty m_scev_APInt(const APInt *&C)
Match an SCEV constant and bind it to an APInt.
specificloop_ty m_SpecificLoop(const Loop *L)
bool match(const SCEV *S, const Pattern &P)
specificscev_ty m_scev_Specific(const SCEV *S)
Match if we have a specific specified SCEV.
SCEVAffineAddRec_match< Op0_t, Op1_t, match_isa< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
DiagnosticInfoOptimizationBase::Argument NV
DiagnosticInfoOptimizationBase::setExtraArgs setExtraArgs
bool isSimple(Instruction *I)
This is an optimization pass for GlobalISel generic memory operations.
static cl::opt< bool, true > DisableLIRPHashRecognize("disable-" DEBUG_TYPE "-hashrecognize", cl::desc("Proceed with loop idiom recognize pass, " "but do not do hash-recognize analysis."), cl::location(DisableLIRP::HashRecognize), cl::init(false), cl::ReallyHidden)
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
static cl::opt< bool, true > EnableLIRPWcslen("disable-loop-idiom-wcslen", cl::desc("Proceed with loop idiom recognize pass, " "enable conversion of loop(s) to wcslen."), cl::location(DisableLIRP::Wcslen), cl::init(false), cl::ReallyHidden)
static cl::opt< bool, true > DisableLIRPMemcpy("disable-" DEBUG_TYPE "-memcpy", cl::desc("Proceed with loop idiom recognize pass, but do " "not convert loop(s) to memcpy."), cl::location(DisableLIRP::Memcpy), cl::init(false), cl::ReallyHidden)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
static cl::opt< bool, true > DisableLIRPStrlen("disable-loop-idiom-strlen", cl::desc("Proceed with loop idiom recognize pass, but do " "not convert loop(s) to strlen."), cl::location(DisableLIRP::Strlen), cl::init(false), cl::ReallyHidden)
@ Store
The extracted value is stored (ExtractElement only).
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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...
static cl::opt< bool > ForceMemsetPatternIntrinsic("loop-idiom-force-memset-pattern-intrinsic", cl::desc("Use memset.pattern intrinsic whenever possible"), cl::init(false), cl::Hidden)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI bool isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI, LibFunc TheLibFunc)
Check whether the library function is available on target and also that it in the current Module is a...
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...
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
auto dyn_cast_or_null(const Y &Val)
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
LLVM_ABI bool isMustProgress(const Loop *L)
Return true if this loop can be assumed to make progress.
static cl::opt< CRCStrategyKind > CRCStrategy(DEBUG_TYPE "-crc-strategy", cl::desc("Preferred strategy for optimizing CRC loops"), cl::init(CRCStrategyKind::Auto), cl::Hidden, cl::values(clEnumValN(CRCStrategyKind::Disable, "disable", "Do not optimize CRC loops"), clEnumValN(CRCStrategyKind::Auto, "auto", "Use costing to determine strategy"), clEnumValN(CRCStrategyKind::Table, "table", "Use a Sarwate table when possible"), clEnumValN(CRCStrategyKind::Clmul, "clmul", "Use carry-less multiplication when possible")))
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isModOrRefSet(const ModRefInfo MRI)
LLVM_ABI bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, SmallPtrSetImpl< PHINode * > *KnownNonDeadPHIs=nullptr)
If the specified value is an effectively dead PHI node, due to being a def-use chain of single-use no...
LLVM_ABI Value * emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the strlen function to the builder, for the specified pointer.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
@ ModRef
The access may reference and may modify the value stored in memory.
@ Mod
The access may modify the value stored in memory.
LLVM_ABI bool VerifyMemorySSA
Enables verification of MemorySSA.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
LLVM_ABI bool isConsecutiveAccess(Value *A, Value *B, const DataLayout &DL, ScalarEvolution &SE, bool CheckType=true)
Returns true if the memory operations A and B are consecutive.
DWARFExpression::Operation Op
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
LLVM_ABI Value * emitWcsLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the wcslen function to the builder, for the specified pointer.
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<X> - Return the argument parameter cast to the specified type.
LLVM_ABI PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
LLVM_ABI Value * isBytewiseValue(Value *V, const DataLayout &DL)
If the specified value can be set by repeating the same byte in memory, return the i8 value that it i...
static cl::opt< bool > UseLIRCodeSizeHeurs("use-lir-code-size-heurs", cl::desc("Use loop idiom recognition code size heuristics when compiling " "with -Os/-Oz"), cl::init(true), cl::Hidden)
static cl::opt< bool, true > DisableLIRPMemset("disable-" DEBUG_TYPE "-memset", cl::desc("Proceed with loop idiom recognize pass, but do " "not convert loop(s) to memset."), cl::location(DisableLIRP::Memset), cl::init(false), cl::ReallyHidden)
static cl::opt< bool, true > DisableLIRPAll("disable-" DEBUG_TYPE "-all", cl::desc("Options to disable Loop Idiom Recognize Pass."), cl::location(DisableLIRP::All), cl::init(false), cl::ReallyHidden)
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
LLVM_ABI std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
@ Auto
Determine whether to use color based on the command line argument and the raw_ostream.
SCEVUseT< const SCEV * > SCEVUse
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...
LLVM_ABI AAMDNodes merge(const AAMDNodes &Other) const
Given two sets of AAMDNodes applying to potentially different locations, determine the best AAMDNodes...
AAMDNodes extendTo(ssize_t Len) const
Create a new AAMDNode that describes this AAMDNode after extending it to apply to a series of bytes o...
static LLVM_ABI bool Memcpy
When true, Memcpy is disabled.
static LLVM_ABI bool Wcslen
When true, Wcslen is disabled.
static LLVM_ABI bool Strlen
When true, Strlen is disabled.
static LLVM_ABI bool HashRecognize
When true, HashRecognize is disabled.
static LLVM_ABI bool Memset
When true, Memset is disabled.
static LLVM_ABI bool All
When true, the entire pass is disabled.
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
TargetTransformInfo & TTI
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
The structure that is returned when a polynomial algorithm was recognized by the analysis.
Match loop-invariant value.
match_LoopInvariant(const SubPattern_t &SP, const Loop *L)