93using namespace SCEVPatternMatch;
95#define DEBUG_TYPE "loop-idiom"
97STATISTIC(NumMemSet,
"Number of memset's formed from loop stores");
98STATISTIC(NumMemCpy,
"Number of memcpy's formed from loop load+stores");
99STATISTIC(NumMemMove,
"Number of memmove's formed from loop load+stores");
100STATISTIC(NumStrLen,
"Number of strlen's and wcslen's formed from loop loads");
102 NumShiftUntilBitTest,
103 "Number of uncountable loops recognized as 'shift until bitttest' idiom");
105 "Number of uncountable loops recognized as 'shift until zero' idiom");
110 cl::desc(
"Options to disable Loop Idiom Recognize Pass."),
117 cl::desc(
"Proceed with loop idiom recognize pass, but do "
118 "not convert loop(s) to memset."),
125 cl::desc(
"Proceed with loop idiom recognize pass, but do "
126 "not convert loop(s) to memcpy."),
133 cl::desc(
"Proceed with loop idiom recognize pass, but do "
134 "not convert loop(s) to strlen."),
141 cl::desc(
"Proceed with loop idiom recognize pass, "
142 "enable conversion of loop(s) to wcslen."),
147 "use-lir-code-size-heurs",
148 cl::desc(
"Use loop idiom recognition code size heuristics when compiling "
153 "loop-idiom-force-memset-pattern-intrinsic",
154 cl::desc(
"Use memset.pattern intrinsic whenever possible"),
cl::init(
false),
159class LoopIdiomRecognize {
160 Loop *CurLoop =
nullptr;
169 bool ApplyCodeSizeHeuristics;
170 std::unique_ptr<MemorySSAUpdater> MSSAU;
179 : AA(AA), DT(DT), LI(LI), SE(SE), TLI(TLI),
TTI(
TTI),
DL(
DL), ORE(ORE) {
181 MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
184 bool runOnLoop(
Loop *L);
190 StoreListMap StoreRefsForMemset;
191 StoreListMap StoreRefsForMemsetPattern;
192 StoreList StoreRefsForMemcpy;
194 bool HasMemsetPattern;
198 enum LegalStoreKind {
203 UnorderedAtomicMemcpy,
211 bool runOnCountableLoop();
216 LegalStoreKind isLegalStore(
StoreInst *SI);
217 enum class ForMemset {
No,
Yes };
221 template <
typename MemInst>
222 bool processLoopMemIntrinsic(
224 bool (LoopIdiomRecognize::*Processor)(MemInst *,
const SCEV *),
225 const SCEV *BECount);
229 bool processLoopStridedStore(
Value *DestPtr,
const SCEV *StoreSizeSCEV,
234 bool IsNegStride,
bool IsLoopMemset =
false);
235 bool processLoopStoreOfLoopLoad(
StoreInst *SI,
const SCEV *BECount);
236 bool processLoopStoreOfLoopLoad(
Value *DestPtr,
Value *SourcePtr,
242 const SCEV *BECount);
243 bool avoidLIRForMultiBlockLoop(
bool IsMemset =
false,
244 bool IsLoopMemset =
false);
250 bool runOnNoncountableLoop();
252 bool recognizePopcount();
256 bool ZeroCheck,
size_t CanonicalSize);
260 bool recognizeAndInsertFFS();
261 bool recognizeShiftUntilLessThan();
266 bool IsCntPhiUsedOutsideLoop,
267 bool InsertSub =
false);
269 bool recognizeShiftUntilBitTest();
270 bool recognizeShiftUntilZero();
271 bool recognizeAndInsertStrLen();
283 const auto *
DL = &L.getHeader()->getDataLayout();
290 LoopIdiomRecognize LIR(&AR.
AA, &AR.
DT, &AR.
LI, &AR.
SE, &AR.
TLI, &AR.
TTI,
292 if (!LIR.runOnLoop(&L))
303 I->eraseFromParent();
312bool LoopIdiomRecognize::runOnLoop(
Loop *L) {
316 if (!
L->getLoopPreheader())
321 if (
Name ==
"memset" ||
Name ==
"memcpy" ||
Name ==
"strlen" ||
326 ApplyCodeSizeHeuristics =
329 HasMemset = TLI->
has(LibFunc_memset);
335 HasMemsetPattern = TLI->
has(LibFunc_memset_pattern16);
336 HasMemcpy = TLI->
has(LibFunc_memcpy);
340 return runOnCountableLoop();
342 return runOnNoncountableLoop();
345bool LoopIdiomRecognize::runOnCountableLoop() {
347 assert(!isa<SCEVCouldNotCompute>(BECount) &&
348 "runOnCountableLoop() called on a loop without a predictable"
349 "backedge-taken count");
371 bool MadeChange =
false;
379 MadeChange |= runOnLoopBlock(BB, BECount, ExitBlocks);
405 if (!
C || isa<ConstantExpr>(
C))
414 if (
DL->isBigEndian())
426 Type *CTy =
C->getType();
433LoopIdiomRecognize::LegalStoreKind
434LoopIdiomRecognize::isLegalStore(
StoreInst *SI) {
436 if (
SI->isVolatile())
437 return LegalStoreKind::None;
439 if (!
SI->isUnordered())
440 return LegalStoreKind::None;
443 if (
SI->getMetadata(LLVMContext::MD_nontemporal))
444 return LegalStoreKind::None;
446 Value *StoredVal =
SI->getValueOperand();
447 Value *StorePtr =
SI->getPointerOperand();
452 return LegalStoreKind::None;
460 return LegalStoreKind::None;
469 return LegalStoreKind::None;
480 bool UnorderedAtomic =
SI->isUnordered() && !
SI->isSimple();
489 return LegalStoreKind::Memset;
497 return LegalStoreKind::MemsetPattern;
504 unsigned StoreSize =
DL->getTypeStoreSize(
SI->getValueOperand()->getType());
506 if (StoreSize != StrideAP && StoreSize != -StrideAP)
507 return LegalStoreKind::None;
510 LoadInst *LI = dyn_cast<LoadInst>(
SI->getValueOperand());
514 return LegalStoreKind::None;
517 return LegalStoreKind::None;
527 return LegalStoreKind::None;
530 UnorderedAtomic = UnorderedAtomic || LI->
isAtomic();
531 return UnorderedAtomic ? LegalStoreKind::UnorderedAtomicMemcpy
532 : LegalStoreKind::Memcpy;
535 return LegalStoreKind::None;
538void LoopIdiomRecognize::collectStores(
BasicBlock *BB) {
539 StoreRefsForMemset.clear();
540 StoreRefsForMemsetPattern.clear();
541 StoreRefsForMemcpy.clear();
548 switch (isLegalStore(SI)) {
549 case LegalStoreKind::None:
552 case LegalStoreKind::Memset: {
555 StoreRefsForMemset[
Ptr].push_back(SI);
557 case LegalStoreKind::MemsetPattern: {
560 StoreRefsForMemsetPattern[
Ptr].push_back(SI);
562 case LegalStoreKind::Memcpy:
563 case LegalStoreKind::UnorderedAtomicMemcpy:
564 StoreRefsForMemcpy.push_back(SI);
567 assert(
false &&
"unhandled return value");
576bool LoopIdiomRecognize::runOnLoopBlock(
586 bool MadeChange =
false;
593 for (
auto &SL : StoreRefsForMemset)
594 MadeChange |= processLoopStores(SL.second, BECount, ForMemset::Yes);
596 for (
auto &SL : StoreRefsForMemsetPattern)
597 MadeChange |= processLoopStores(SL.second, BECount, ForMemset::No);
600 for (
auto &SI : StoreRefsForMemcpy)
601 MadeChange |= processLoopStoreOfLoopLoad(SI, BECount);
603 MadeChange |= processLoopMemIntrinsic<MemCpyInst>(
604 BB, &LoopIdiomRecognize::processLoopMemCpy, BECount);
605 MadeChange |= processLoopMemIntrinsic<MemSetInst>(
606 BB, &LoopIdiomRecognize::processLoopMemSet, BECount);
613 const SCEV *BECount, ForMemset For) {
621 for (
unsigned i = 0, e = SL.
size(); i < e; ++i) {
622 assert(SL[i]->
isSimple() &&
"Expected only non-volatile stores.");
624 Value *FirstStoredVal = SL[i]->getValueOperand();
625 Value *FirstStorePtr = SL[i]->getPointerOperand();
627 cast<SCEVAddRecExpr>(SE->
getSCEV(FirstStorePtr));
629 unsigned FirstStoreSize =
DL->getTypeStoreSize(SL[i]->getValueOperand()->
getType());
632 if (FirstStride == FirstStoreSize || -FirstStride == FirstStoreSize) {
637 Value *FirstSplatValue =
nullptr;
638 Constant *FirstPatternValue =
nullptr;
640 if (For == ForMemset::Yes)
645 assert((FirstSplatValue || FirstPatternValue) &&
646 "Expected either splat value or pattern value.");
654 for (j = i + 1;
j <
e; ++
j)
656 for (j = i;
j > 0; --
j)
659 for (
auto &k : IndexQueue) {
660 assert(SL[k]->
isSimple() &&
"Expected only non-volatile stores.");
661 Value *SecondStorePtr = SL[
k]->getPointerOperand();
663 cast<SCEVAddRecExpr>(SE->
getSCEV(SecondStorePtr));
666 if (FirstStride != SecondStride)
669 Value *SecondStoredVal = SL[
k]->getValueOperand();
670 Value *SecondSplatValue =
nullptr;
671 Constant *SecondPatternValue =
nullptr;
673 if (For == ForMemset::Yes)
678 assert((SecondSplatValue || SecondPatternValue) &&
679 "Expected either splat value or pattern value.");
682 if (For == ForMemset::Yes) {
683 if (isa<UndefValue>(FirstSplatValue))
684 FirstSplatValue = SecondSplatValue;
685 if (FirstSplatValue != SecondSplatValue)
688 if (isa<UndefValue>(FirstPatternValue))
689 FirstPatternValue = SecondPatternValue;
690 if (FirstPatternValue != SecondPatternValue)
695 ConsecutiveChain[SL[i]] = SL[
k];
704 bool Changed =
false;
715 unsigned StoreSize = 0;
718 while (Tails.
count(
I) || Heads.count(
I)) {
719 if (TransformedStores.
count(
I))
723 StoreSize +=
DL->getTypeStoreSize(
I->getValueOperand()->getType());
725 I = ConsecutiveChain[
I];
735 if (StoreSize != Stride && StoreSize != -Stride)
738 bool IsNegStride = StoreSize == -Stride;
742 if (processLoopStridedStore(StorePtr, StoreSizeSCEV,
744 HeadStore, AdjacentStores, StoreEv, BECount,
756template <
typename MemInst>
757bool LoopIdiomRecognize::processLoopMemIntrinsic(
759 bool (LoopIdiomRecognize::*Processor)(MemInst *,
const SCEV *),
760 const SCEV *BECount) {
761 bool MadeChange =
false;
765 if (MemInst *
MI = dyn_cast<MemInst>(Inst)) {
767 if (!(this->*Processor)(
MI, BECount))
781bool LoopIdiomRecognize::processLoopMemCpy(
MemCpyInst *MCI,
782 const SCEV *BECount) {
793 if (!Dest || !Source)
801 const APInt *StoreStrideValue, *LoadStrideValue;
812 if ((SizeInBytes >> 32) != 0)
820 if (SizeInBytes != *StoreStrideValue && SizeInBytes != -*StoreStrideValue) {
823 <<
ore::NV(
"Inst",
"memcpy") <<
" in "
825 <<
" function will not be hoisted: "
826 <<
ore::NV(
"Reason",
"memcpy size is not equal to stride");
831 int64_t StoreStrideInt = StoreStrideValue->
getSExtValue();
832 int64_t LoadStrideInt = LoadStrideValue->
getSExtValue();
834 if (StoreStrideInt != LoadStrideInt)
837 return processLoopStoreOfLoopLoad(
840 cast<SCEVAddRecExpr>(StoreEv), cast<SCEVAddRecExpr>(LoadEv), BECount);
844bool LoopIdiomRecognize::processLoopMemSet(
MemSetInst *MSI,
845 const SCEV *BECount) {
860 const SCEV *PointerStrideSCEV;
869 bool IsNegStride =
false;
870 const bool IsConstantSize = isa<ConstantInt>(MSI->
getLength());
872 if (IsConstantSize) {
882 if (SizeInBytes != *Stride && SizeInBytes != -*Stride)
885 IsNegStride = SizeInBytes == -*Stride;
893 if (
Pointer->getType()->getPointerAddressSpace() != 0) {
906 const SCEV *PositiveStrideSCEV =
909 LLVM_DEBUG(
dbgs() <<
" MemsetSizeSCEV: " << *MemsetSizeSCEV <<
"\n"
910 <<
" PositiveStrideSCEV: " << *PositiveStrideSCEV
913 if (PositiveStrideSCEV != MemsetSizeSCEV) {
916 const SCEV *FoldedPositiveStride =
918 const SCEV *FoldedMemsetSize =
922 <<
" FoldedMemsetSize: " << *FoldedMemsetSize <<
"\n"
923 <<
" FoldedPositiveStride: " << *FoldedPositiveStride
926 if (FoldedPositiveStride != FoldedMemsetSize) {
943 cast<SCEVAddRecExpr>(Ev), BECount, IsNegStride,
952 const SCEV *BECount,
const SCEV *StoreSizeSCEV,
962 const APInt *BECst, *ConstSize;
966 std::optional<uint64_t> SizeInt = ConstSize->
tryZExtValue();
968 if (BEInt && SizeInt)
990 Type *IntPtr,
const SCEV *StoreSizeSCEV,
993 if (!StoreSizeSCEV->
isOne()) {
1008 const SCEV *StoreSizeSCEV,
Loop *CurLoop,
1010 const SCEV *TripCountSCEV =
1019bool LoopIdiomRecognize::processLoopStridedStore(
1023 const SCEV *BECount,
bool IsNegStride,
bool IsLoopMemset) {
1035 Type *DestInt8PtrTy = Builder.getPtrTy(DestAS);
1038 bool Changed =
false;
1046 if (!Expander.isSafeToExpand(Start))
1055 Expander.expandCodeFor(Start, DestInt8PtrTy, Preheader->
getTerminator());
1067 StoreSizeSCEV, *AA, Stores))
1070 if (avoidLIRForMultiBlockLoop(
true, IsLoopMemset))
1082 std::optional<int64_t> BytesWritten;
1085 const SCEV *TripCountS =
1087 if (!Expander.isSafeToExpand(TripCountS))
1089 const SCEVConstant *ConstStoreSize = dyn_cast<SCEVConstant>(StoreSizeSCEV);
1090 if (!ConstStoreSize)
1092 Value *TripCount = Expander.expandCodeFor(TripCountS, IntIdxTy,
1096 DL->getTypeSizeInBits(PatternValue->
getType());
1101 PatternRepsPerTrip == 1
1103 : Builder.CreateMul(TripCount,
1105 PatternRepsPerTrip));
1106 if (
auto *CI = dyn_cast<ConstantInt>(TripCount))
1111 const SCEV *NumBytesS =
1112 getNumBytes(BECount, IntIdxTy, StoreSizeSCEV, CurLoop,
DL, SE);
1116 if (!Expander.isSafeToExpand(NumBytesS))
1119 Expander.expandCodeFor(NumBytesS, IntIdxTy, Preheader->
getTerminator());
1120 if (
auto *CI = dyn_cast<ConstantInt>(MemsetArg))
1121 BytesWritten = CI->getZExtValue();
1123 assert(MemsetArg &&
"MemsetArg should have been set");
1127 AATags = AATags.
merge(
Store->getAAMetadata());
1129 AATags = AATags.
extendTo(BytesWritten.value());
1135 NewCall = Builder.CreateMemSet(BasePtr, SplatValue, MemsetArg,
1140 assert(isa<SCEVConstant>(StoreSizeSCEV) &&
"Expected constant store size");
1142 NewCall = Builder.CreateIntrinsic(
1143 Intrinsic::experimental_memset_pattern,
1144 {DestInt8PtrTy, PatternValue->
getType(), IntIdxTy},
1145 {
BasePtr, PatternValue, MemsetArg,
1148 cast<MemSetPatternInst>(NewCall)->setDestAlignment(*StoreAlignment);
1158 MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB(
1160 MSSAU->insertDef(cast<MemoryDef>(NewMemAcc),
true);
1164 <<
" from store to: " << *Ev <<
" at: " << *TheStore
1170 R <<
"Transformed loop-strided store in "
1172 <<
" function into a call to "
1175 if (!Stores.empty())
1177 for (
auto *
I : Stores) {
1178 R <<
ore::NV(
"FromBlock",
I->getParent()->getName())
1186 for (
auto *
I : Stores) {
1188 MSSAU->removeMemoryAccess(
I,
true);
1192 MSSAU->getMemorySSA()->verifyMemorySSA();
1194 ExpCleaner.markResultUsed();
1201bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
StoreInst *SI,
1202 const SCEV *BECount) {
1203 assert(
SI->isUnordered() &&
"Expected only non-volatile non-ordered stores.");
1205 Value *StorePtr =
SI->getPointerOperand();
1207 unsigned StoreSize =
DL->getTypeStoreSize(
SI->getValueOperand()->getType());
1210 LoadInst *LI = cast<LoadInst>(
SI->getValueOperand());
1220 return processLoopStoreOfLoopLoad(StorePtr, LoadPtr, StoreSizeSCEV,
1222 StoreEv, LoadEv, BECount);
1226class MemmoveVerifier {
1228 explicit MemmoveVerifier(
const Value &LoadBasePtr,
const Value &StoreBasePtr,
1231 LoadBasePtr.stripPointerCasts(), LoadOff,
DL)),
1233 StoreBasePtr.stripPointerCasts(), StoreOff,
DL)),
1234 IsSameObject(BP1 == BP2) {}
1236 bool loadAndStoreMayFormMemmove(
unsigned StoreSize,
bool IsNegStride,
1238 bool IsMemCpy)
const {
1242 if ((!IsNegStride && LoadOff <= StoreOff) ||
1243 (IsNegStride && LoadOff >= StoreOff))
1249 DL.getTypeSizeInBits(TheLoad.
getType()).getFixedValue() / 8;
1250 if (BP1 != BP2 || LoadSize != int64_t(StoreSize))
1252 if ((!IsNegStride && LoadOff < StoreOff + int64_t(StoreSize)) ||
1253 (IsNegStride && LoadOff + LoadSize > StoreOff))
1261 int64_t LoadOff = 0;
1262 int64_t StoreOff = 0;
1267 const bool IsSameObject;
1271bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
1280 if (
auto *MCI = dyn_cast<MemCpyInst>(TheStore); MCI && MCI->
isForceInlined())
1292 bool Changed =
false;
1298 const SCEVConstant *ConstStoreSize = dyn_cast<SCEVConstant>(StoreSizeSCEV);
1301 assert(ConstStoreSize &&
"store size is expected to be a constant");
1304 bool IsNegStride = StoreSize == -Stride;
1317 Value *StoreBasePtr = Expander.expandCodeFor(
1318 StrStart, Builder.getPtrTy(StrAS), Preheader->
getTerminator());
1330 IgnoredInsts.
insert(TheStore);
1332 bool IsMemCpy = isa<MemCpyInst>(TheStore);
1333 const StringRef InstRemark = IsMemCpy ?
"memcpy" :
"load and store";
1335 bool LoopAccessStore =
1337 StoreSizeSCEV, *AA, IgnoredInsts);
1338 if (LoopAccessStore) {
1344 IgnoredInsts.
insert(TheLoad);
1346 BECount, StoreSizeSCEV, *AA, IgnoredInsts)) {
1350 <<
ore::NV(
"Inst", InstRemark) <<
" in "
1352 <<
" function will not be hoisted: "
1353 <<
ore::NV(
"Reason",
"The loop may access store location");
1357 IgnoredInsts.
erase(TheLoad);
1370 Value *LoadBasePtr = Expander.expandCodeFor(LdStart, Builder.getPtrTy(LdAS),
1375 MemmoveVerifier
Verifier(*LoadBasePtr, *StoreBasePtr, *
DL);
1376 if (IsMemCpy && !
Verifier.IsSameObject)
1377 IgnoredInsts.
erase(TheStore);
1379 StoreSizeSCEV, *AA, IgnoredInsts)) {
1382 <<
ore::NV(
"Inst", InstRemark) <<
" in "
1384 <<
" function will not be hoisted: "
1385 <<
ore::NV(
"Reason",
"The loop may access load location");
1391 bool UseMemMove = IsMemCpy ?
Verifier.IsSameObject : LoopAccessStore;
1400 assert((StoreAlign && LoadAlign) &&
1401 "Expect unordered load/store to have align.");
1402 if (*StoreAlign < StoreSize || *LoadAlign < StoreSize)
1414 if (!
Verifier.loadAndStoreMayFormMemmove(StoreSize, IsNegStride, *TheLoad,
1418 if (avoidLIRForMultiBlockLoop())
1423 const SCEV *NumBytesS =
1424 getNumBytes(BECount, IntIdxTy, StoreSizeSCEV, CurLoop,
DL, SE);
1427 Expander.expandCodeFor(NumBytesS, IntIdxTy, Preheader->
getTerminator());
1431 AATags = AATags.
merge(StoreAATags);
1432 if (
auto CI = dyn_cast<ConstantInt>(NumBytes))
1433 AATags = AATags.
extendTo(CI->getZExtValue());
1443 NewCall = Builder.CreateMemMove(StoreBasePtr, StoreAlign, LoadBasePtr,
1444 LoadAlign, NumBytes,
1448 Builder.CreateMemCpy(StoreBasePtr, StoreAlign, LoadBasePtr, LoadAlign,
1449 NumBytes,
false, AATags);
1454 NewCall = Builder.CreateElementUnorderedAtomicMemCpy(
1455 StoreBasePtr, *StoreAlign, LoadBasePtr, *LoadAlign, NumBytes, StoreSize,
1461 MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB(
1463 MSSAU->insertDef(cast<MemoryDef>(NewMemAcc),
true);
1467 <<
" from load ptr=" << *LoadEv <<
" at: " << *TheLoad
1469 <<
" from store ptr=" << *StoreEv <<
" at: " << *TheStore
1475 <<
"Formed a call to "
1477 <<
"() intrinsic from " <<
ore::NV(
"Inst", InstRemark)
1488 MSSAU->removeMemoryAccess(TheStore,
true);
1491 MSSAU->getMemorySSA()->verifyMemorySSA();
1496 ExpCleaner.markResultUsed();
1503bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(
bool IsMemset,
1504 bool IsLoopMemset) {
1505 if (ApplyCodeSizeHeuristics && CurLoop->
getNumBlocks() > 1) {
1506 if (CurLoop->
isOutermost() && (!IsMemset || !IsLoopMemset)) {
1508 <<
" : LIR " << (IsMemset ?
"Memset" :
"Memcpy")
1509 <<
" avoided: multi-block top-level loop\n");
1517bool LoopIdiomRecognize::runOnNoncountableLoop() {
1520 <<
"] Noncountable Loop %"
1523 return recognizePopcount() || recognizeAndInsertFFS() ||
1524 recognizeShiftUntilBitTest() || recognizeShiftUntilZero() ||
1525 recognizeShiftUntilLessThan() || recognizeAndInsertStrLen();
1535 bool JmpOnZero =
false) {
1543 auto *CmpZero = dyn_cast<ConstantInt>(
Cond->getOperand(1));
1544 if (!CmpZero || !CmpZero->isZero())
1555 return Cond->getOperand(0);
1562class StrlenVerifier {
1566 : CurLoop(CurLoop), SE(SE), TLI(TLI) {}
1568 bool isValidStrlenIdiom() {
1590 if (!LoopBody || LoopBody->
size() >= 15)
1598 LoadInst *LoopLoad = dyn_cast<LoadInst>(LoopCond);
1622 if (OpWidth != StepSize * 8)
1624 if (OpWidth != 8 && OpWidth != 16 && OpWidth != 32)
1627 if (OpWidth != WcharSize * 8)
1632 if (
I.mayHaveSideEffects())
1653 if (!AddRecEv || !AddRecEv->
isAffine())
1667 const Loop *CurLoop;
1673 const SCEV *LoadBaseEv;
1738bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
1742 StrlenVerifier
Verifier(CurLoop, SE, TLI);
1744 if (!
Verifier.isValidStrlenIdiom())
1751 assert(Preheader && LoopBody && LoopExitBB && LoopTerm &&
1752 "Should be verified to be valid by StrlenVerifier");
1767 Builder.SetCurrentDebugLocation(CurLoop->
getStartLoc());
1770 Value *MaterialzedBase = Expander.expandCodeFor(
1772 Builder.GetInsertPoint());
1774 Value *StrLenFunc =
nullptr;
1776 StrLenFunc =
emitStrLen(MaterialzedBase, Builder, *
DL, TLI);
1778 StrLenFunc =
emitWcsLen(MaterialzedBase, Builder, *
DL, TLI);
1780 assert(StrLenFunc &&
"Failed to emit strlen function.");
1799 StrlenEv,
Base->getType())));
1801 Value *MaterializedPHI = Expander.expandCodeFor(NewEv, NewEv->
getType(),
1802 Builder.GetInsertPoint());
1818 "loop body must have a successor that is it self");
1820 ? Builder.getFalse()
1821 : Builder.getTrue();
1826 LLVM_DEBUG(
dbgs() <<
" Formed strlen idiom: " << *StrLenFunc <<
"\n");
1830 <<
"Transformed " << StrLenFunc->
getName() <<
" loop idiom";
1858 return Cond->getOperand(0);
1868 auto *PhiX = dyn_cast<PHINode>(VarX);
1869 if (PhiX && PhiX->getParent() == LoopEntry &&
1870 (PhiX->getOperand(0) == DefX || PhiX->
getOperand(1) == DefX))
1916 dyn_cast<BranchInst>(LoopEntry->
getTerminator()), LoopEntry,
1918 DefX = dyn_cast<Instruction>(
T);
1923 if (!DefX || !isa<PHINode>(DefX))
1926 PHINode *VarPhi = cast<PHINode>(DefX);
1936 if (DefX->
getOpcode() != Instruction::LShr)
1939 IntrinID = Intrinsic::ctlz;
1941 if (!Shft || !Shft->
isOne())
1955 if (Inst.
getOpcode() != Instruction::Add)
2007 Value *VarX1, *VarX0;
2010 DefX2 = CountInst =
nullptr;
2011 VarX1 = VarX0 =
nullptr;
2012 PhiX = CountPhi =
nullptr;
2018 dyn_cast<BranchInst>(LoopEntry->
getTerminator()), LoopEntry))
2019 DefX2 = dyn_cast<Instruction>(
T);
2026 if (!DefX2 || DefX2->
getOpcode() != Instruction::And)
2031 if ((SubOneOp = dyn_cast<BinaryOperator>(DefX2->
getOperand(0))))
2035 SubOneOp = dyn_cast<BinaryOperator>(DefX2->
getOperand(1));
2037 if (!SubOneOp || SubOneOp->
getOperand(0) != VarX1)
2043 (SubOneOp->
getOpcode() == Instruction::Add &&
2056 CountInst =
nullptr;
2059 if (Inst.
getOpcode() != Instruction::Add)
2063 if (!Inc || !Inc->
isOne())
2071 bool LiveOutLoop =
false;
2073 if ((cast<Instruction>(U))->
getParent() != LoopEntry) {
2093 auto *PreCondBr = dyn_cast<BranchInst>(PreCondBB->
getTerminator());
2098 CntInst = CountInst;
2138 Value *VarX =
nullptr;
2147 dyn_cast<BranchInst>(LoopEntry->
getTerminator()), LoopEntry))
2148 DefX = dyn_cast<Instruction>(
T);
2153 if (!DefX || !DefX->
isShift())
2155 IntrinID = DefX->
getOpcode() == Instruction::Shl ? Intrinsic::cttz :
2158 if (!Shft || !Shft->
isOne())
2183 if (Inst.
getOpcode() != Instruction::Add)
2206bool LoopIdiomRecognize::isProfitableToInsertFFS(
Intrinsic::ID IntrinID,
2207 Value *InitX,
bool ZeroCheck,
2208 size_t CanonicalSize) {
2215 std::distance(InstWithoutDebugIt.begin(), InstWithoutDebugIt.end());
2229bool LoopIdiomRecognize::insertFFSIfProfitable(
Intrinsic::ID IntrinID,
2233 bool IsCntPhiUsedOutsideLoop =
false;
2235 if (!CurLoop->
contains(cast<Instruction>(U))) {
2236 IsCntPhiUsedOutsideLoop =
true;
2239 bool IsCntInstUsedOutsideLoop =
false;
2241 if (!CurLoop->
contains(cast<Instruction>(U))) {
2242 IsCntInstUsedOutsideLoop =
true;
2247 if (IsCntInstUsedOutsideLoop && IsCntPhiUsedOutsideLoop)
2253 bool ZeroCheck =
false;
2262 if (!IsCntPhiUsedOutsideLoop) {
2266 auto *PreCondBI = dyn_cast<BranchInst>(PreCondBB->getTerminator());
2281 size_t IdiomCanonicalSize = 6;
2282 if (!isProfitableToInsertFFS(IntrinID, InitX, ZeroCheck, IdiomCanonicalSize))
2285 transformLoopToCountable(IntrinID, PH, CntInst, CntPhi, InitX, DefX,
2287 IsCntPhiUsedOutsideLoop);
2294bool LoopIdiomRecognize::recognizeAndInsertFFS() {
2309 return insertFFSIfProfitable(IntrinID, InitX, DefX, CntPhi, CntInst);
2312bool LoopIdiomRecognize::recognizeShiftUntilLessThan() {
2323 APInt LoopThreshold;
2325 CntPhi, DefX, LoopThreshold))
2328 if (LoopThreshold == 2) {
2330 return insertFFSIfProfitable(IntrinID, InitX, DefX, CntPhi, CntInst);
2334 if (LoopThreshold != 4)
2339 if (!CurLoop->
contains(cast<Instruction>(U)))
2348 auto *PreCondBI = dyn_cast<BranchInst>(PreCondBB->getTerminator());
2352 APInt PreLoopThreshold;
2354 PreLoopThreshold != 2)
2357 bool ZeroCheck =
true;
2366 size_t IdiomCanonicalSize = 6;
2367 if (!isProfitableToInsertFFS(IntrinID, InitX, ZeroCheck, IdiomCanonicalSize))
2371 transformLoopToCountable(IntrinID, PH, CntInst, CntPhi, InitX, DefX,
2382bool LoopIdiomRecognize::recognizePopcount() {
2396 if (LoopBody->
size() >= 20) {
2414 auto *PreCondBI = dyn_cast<BranchInst>(PreCondBB->getTerminator());
2415 if (!PreCondBI || PreCondBI->isUnconditional())
2424 transformLoopToPopcount(PreCondBB, CntInst, CntPhi, Val);
2430 Value *Ops[] = {Val};
2482void LoopIdiomRecognize::transformLoopToCountable(
2485 bool ZeroCheck,
bool IsCntPhiUsedOutsideLoop,
bool InsertSub) {
2490 Builder.SetCurrentDebugLocation(
DL);
2499 if (IsCntPhiUsedOutsideLoop) {
2500 if (DefX->
getOpcode() == Instruction::AShr)
2501 InitXNext = Builder.CreateAShr(InitX, 1);
2502 else if (DefX->
getOpcode() == Instruction::LShr)
2503 InitXNext = Builder.CreateLShr(InitX, 1);
2504 else if (DefX->
getOpcode() == Instruction::Shl)
2505 InitXNext = Builder.CreateShl(InitX, 1);
2513 Count = Builder.CreateSub(
2516 Count = Builder.CreateSub(Count, ConstantInt::get(CountTy, 1));
2517 Value *NewCount = Count;
2518 if (IsCntPhiUsedOutsideLoop)
2519 Count = Builder.CreateAdd(Count, ConstantInt::get(CountTy, 1));
2521 NewCount = Builder.CreateZExtOrTrunc(NewCount, CntInst->
getType());
2524 if (cast<ConstantInt>(CntInst->
getOperand(1))->isOne()) {
2527 ConstantInt *InitConst = dyn_cast<ConstantInt>(CntInitVal);
2528 if (!InitConst || !InitConst->
isZero())
2529 NewCount = Builder.CreateAdd(NewCount, CntInitVal);
2533 NewCount = Builder.CreateSub(CntInitVal, NewCount);
2546 ICmpInst *LbCond = cast<ICmpInst>(LbBr->getCondition());
2551 Builder.SetInsertPoint(LbCond);
2552 Instruction *TcDec = cast<Instruction>(Builder.CreateSub(
2553 TcPhi, ConstantInt::get(CountTy, 1),
"tcdec",
false,
true));
2562 LbCond->
setOperand(1, ConstantInt::get(CountTy, 0));
2566 if (IsCntPhiUsedOutsideLoop)
2576void LoopIdiomRecognize::transformLoopToPopcount(
BasicBlock *PreCondBB,
2580 auto *PreCondBr = cast<BranchInst>(PreCondBB->
getTerminator());
2589 Value *PopCnt, *PopCntZext, *NewCount, *TripCnt;
2592 NewCount = PopCntZext =
2593 Builder.CreateZExtOrTrunc(PopCnt, cast<IntegerType>(CntPhi->
getType()));
2595 if (NewCount != PopCnt)
2596 (cast<Instruction>(NewCount))->setDebugLoc(
DL);
2603 ConstantInt *InitConst = dyn_cast<ConstantInt>(CntInitVal);
2604 if (!InitConst || !InitConst->
isZero()) {
2605 NewCount = Builder.CreateAdd(NewCount, CntInitVal);
2606 (cast<Instruction>(NewCount))->setDebugLoc(
DL);
2615 ICmpInst *PreCond = cast<ICmpInst>(PreCondBr->getCondition());
2617 Value *Opnd0 = PopCntZext;
2618 Value *Opnd1 = ConstantInt::get(PopCntZext->
getType(), 0);
2622 ICmpInst *NewPreCond = cast<ICmpInst>(
2623 Builder.CreateICmp(PreCond->
getPredicate(), Opnd0, Opnd1));
2624 PreCondBr->setCondition(NewPreCond);
2652 ICmpInst *LbCond = cast<ICmpInst>(LbBr->getCondition());
2658 Builder.SetInsertPoint(LbCond);
2660 Builder.CreateSub(TcPhi, ConstantInt::get(Ty, 1),
2661 "tcdec",
false,
true));
2670 LbCond->
setOperand(1, ConstantInt::get(Ty, 0));
2689 : SubPattern(SP), L(L) {}
2691 template <
typename ITy>
bool match(ITy *V)
const {
2692 return L->isLoopInvariant(V) && SubPattern.match(V);
2697template <
typename Ty>
2728 " Performing shift-until-bittest idiom detection.\n");
2738 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
2740 using namespace PatternMatch;
2745 Value *CmpLHS, *CmpRHS;
2756 auto MatchVariableBitMask = [&]() {
2766 auto MatchDecomposableConstantBitMask = [&]() {
2768 CmpLHS, CmpRHS, Pred,
true,
2770 if (Res && Res->Mask.isPowerOf2()) {
2774 BitMask = ConstantInt::get(CurrX->
getType(), Res->Mask);
2775 BitPos = ConstantInt::get(CurrX->
getType(), Res->Mask.logBase2());
2781 if (!MatchVariableBitMask() && !MatchDecomposableConstantBitMask()) {
2787 auto *CurrXPN = dyn_cast<PHINode>(CurrX);
2788 if (!CurrXPN || CurrXPN->getParent() != LoopHeaderBB) {
2793 BaseX = CurrXPN->getIncomingValueForBlock(LoopPreheaderBB);
2795 dyn_cast<Instruction>(CurrXPN->getIncomingValueForBlock(LoopHeaderBB));
2798 "Expected BaseX to be available in the preheader!");
2809 "Should only get equality predicates here.");
2819 if (TrueBB != LoopHeaderBB) {
2878bool LoopIdiomRecognize::recognizeShiftUntilBitTest() {
2879 bool MadeChange =
false;
2881 Value *
X, *BitMask, *BitPos, *XCurr;
2886 " shift-until-bittest idiom detection failed.\n");
2896 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
2899 assert(SuccessorBB &&
"There is only a single successor.");
2902 Builder.SetCurrentDebugLocation(cast<Instruction>(XCurr)->
getDebugLoc());
2905 Type *Ty =
X->getType();
2919 " Intrinsic is too costly, not beneficial\n");
2934 std::optional<BasicBlock::iterator> InsertPt = std::nullopt;
2935 if (
auto *BitPosI = dyn_cast<Instruction>(BitPos))
2936 InsertPt = BitPosI->getInsertionPointAfterDef();
2944 return U.getUser() != BitPosFrozen;
2946 BitPos = BitPosFrozen;
2952 BitPos->
getName() +
".lowbitmask");
2954 Builder.CreateOr(LowBitMask, BitMask, BitPos->
getName() +
".mask");
2955 Value *XMasked = Builder.CreateAnd(
X, Mask,
X->getName() +
".masked");
2956 CallInst *XMaskedNumLeadingZeros = Builder.CreateIntrinsic(
2957 IntrID, Ty, {XMasked, Builder.getTrue()},
2958 nullptr, XMasked->
getName() +
".numleadingzeros");
2959 Value *XMaskedNumActiveBits = Builder.CreateSub(
2961 XMasked->
getName() +
".numactivebits",
true,
2963 Value *XMaskedLeadingOnePos =
2965 XMasked->
getName() +
".leadingonepos",
false,
2968 Value *LoopBackedgeTakenCount = Builder.CreateSub(
2969 BitPos, XMaskedLeadingOnePos, CurLoop->
getName() +
".backedgetakencount",
2973 Value *LoopTripCount =
2974 Builder.CreateAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
2975 CurLoop->
getName() +
".tripcount",
true,
2982 Value *NewX = Builder.CreateShl(
X, LoopBackedgeTakenCount);
2984 if (
auto *
I = dyn_cast<Instruction>(NewX))
2985 I->copyIRFlags(XNext,
true);
2997 NewXNext = Builder.CreateShl(
X, LoopTripCount);
3002 NewXNext = Builder.CreateShl(NewX, ConstantInt::get(Ty, 1));
3006 if (
auto *
I = dyn_cast<Instruction>(NewXNext))
3007 I->copyIRFlags(XNext,
true);
3018 Builder.SetInsertPoint(LoopHeaderBB, LoopHeaderBB->
begin());
3019 auto *
IV = Builder.CreatePHI(Ty, 2, CurLoop->
getName() +
".iv");
3025 Builder.CreateAdd(
IV, ConstantInt::get(Ty, 1),
IV->getName() +
".next",
3026 true, Bitwidth != 2);
3029 auto *IVCheck = Builder.CreateICmpEQ(IVNext, LoopTripCount,
3030 CurLoop->
getName() +
".ivcheck");
3031 Builder.CreateCondBr(IVCheck, SuccessorBB, LoopHeaderBB);
3035 IV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
3036 IV->addIncoming(IVNext, LoopHeaderBB);
3047 ++NumShiftUntilBitTest;
3083 const SCEV *&ExtraOffsetExpr,
3084 bool &InvertedCond) {
3086 " Performing shift-until-zero idiom detection.\n");
3099 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3101 using namespace PatternMatch;
3110 !
match(ValShiftedIsZero,
3124 IntrinID = ValShifted->
getOpcode() == Instruction::Shl ? Intrinsic::cttz
3133 else if (
match(NBits,
3137 ExtraOffsetExpr = SE->
getSCEV(ExtraOffset);
3144 auto *IVPN = dyn_cast<PHINode>(
IV);
3145 if (!IVPN || IVPN->getParent() != LoopHeaderBB) {
3150 Start = IVPN->getIncomingValueForBlock(LoopPreheaderBB);
3151 IVNext = dyn_cast<Instruction>(IVPN->getIncomingValueForBlock(LoopHeaderBB));
3161 "Should only get equality predicates here.");
3172 if (FalseBB != LoopHeaderBB) {
3183 if (ValShifted->
getOpcode() == Instruction::AShr &&
3247bool LoopIdiomRecognize::recognizeShiftUntilZero() {
3248 bool MadeChange =
false;
3254 const SCEV *ExtraOffsetExpr;
3257 Start, Val, ExtraOffsetExpr, InvertedCond)) {
3259 " shift-until-zero idiom detection failed.\n");
3269 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3272 assert(SuccessorBB &&
"There is only a single successor.");
3275 Builder.SetCurrentDebugLocation(
IV->getDebugLoc());
3291 " Intrinsic is too costly, not beneficial\n");
3298 bool OffsetIsZero = ExtraOffsetExpr->
isZero();
3302 CallInst *ValNumLeadingZeros = Builder.CreateIntrinsic(
3303 IntrID, Ty, {Val, Builder.getFalse()},
3304 nullptr, Val->
getName() +
".numleadingzeros");
3305 Value *ValNumActiveBits = Builder.CreateSub(
3307 Val->
getName() +
".numactivebits",
true,
3311 Expander.setInsertPoint(&*Builder.GetInsertPoint());
3312 Value *ExtraOffset = Expander.expandCodeFor(ExtraOffsetExpr);
3314 Value *ValNumActiveBitsOffset = Builder.CreateAdd(
3315 ValNumActiveBits, ExtraOffset, ValNumActiveBits->
getName() +
".offset",
3316 OffsetIsZero,
true);
3317 Value *IVFinal = Builder.CreateIntrinsic(Intrinsic::smax, {Ty},
3318 {ValNumActiveBitsOffset, Start},
3319 nullptr,
"iv.final");
3321 auto *LoopBackedgeTakenCount = cast<Instruction>(Builder.CreateSub(
3322 IVFinal, Start, CurLoop->
getName() +
".backedgetakencount",
3323 OffsetIsZero,
true));
3327 Value *LoopTripCount =
3328 Builder.CreateAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
3329 CurLoop->
getName() +
".tripcount",
true,
3335 IV->replaceUsesOutsideBlock(IVFinal, LoopHeaderBB);
3340 Builder.SetInsertPoint(LoopHeaderBB, LoopHeaderBB->
begin());
3341 auto *CIV = Builder.CreatePHI(Ty, 2, CurLoop->
getName() +
".iv");
3346 Builder.CreateAdd(CIV, ConstantInt::get(Ty, 1), CIV->getName() +
".next",
3347 true, Bitwidth != 2);
3350 auto *CIVCheck = Builder.CreateICmpEQ(CIVNext, LoopTripCount,
3351 CurLoop->
getName() +
".ivcheck");
3352 auto *NewIVCheck = CIVCheck;
3354 NewIVCheck = Builder.CreateNot(CIVCheck);
3355 NewIVCheck->takeName(ValShiftedIsZero);
3359 auto *IVDePHId = Builder.CreateAdd(CIV, Start,
"",
false,
3361 IVDePHId->takeName(
IV);
3365 Builder.CreateCondBr(CIVCheck, SuccessorBB, LoopHeaderBB);
3369 CIV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
3370 CIV->addIncoming(CIVNext, LoopHeaderBB);
3378 IV->replaceAllUsesWith(IVDePHId);
3379 IV->eraseFromParent();
3388 ++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< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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")))
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static const 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,...
static Value * matchCondition(BranchInst *BI, BasicBlock *LoopEntry, bool JmpOnZero=false)
Check if the given conditional branch is based on the comparison between a variable and zero,...
static PHINode * getRecurrenceVar(Value *VarX, Instruction *DefX, BasicBlock *LoopEntry)
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 > ForceMemsetPatternIntrinsic("loop-idiom-force-memset-pattern-intrinsic", cl::desc("Use memset.pattern intrinsic whenever possible"), cl::init(false), cl::Hidden)
static CallInst * createFFSIntrinsic(IRBuilder<> &IRBuilder, Value *Val, const DebugLoc &DL, bool ZeroCheck, Intrinsic::ID IID)
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 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 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 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)
static CallInst * createPopcntIntrinsic(IRBuilder<> &IRBuilder, Value *Val, const DebugLoc &DL)
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 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)
static const SCEV * getStartForNegStride(const SCEV *Start, const SCEV *BECount, Type *IntPtr, const SCEV *StoreSizeSCEV, ScalarEvolution *SE)
static APInt getStoreStride(const SCEVAddRecExpr *StoreEv)
static Value * matchShiftULTCondition(BranchInst *BI, BasicBlock *LoopEntry, APInt &Threshold)
Check if the given conditional branch is based on an unsigned less-than comparison between a variable...
match_LoopInvariant< Ty > m_LoopInvariant(const Ty &M, const Loop *L)
Matches if the value is loop-invariant.
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)
static void deleteDeadInstruction(Instruction *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 DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
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 ...
const SmallVectorImpl< MachineOperand > & Cond
static bool isSimple(Instruction *I)
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]
A private abstract base class describing the concept of an individual alias analysis implementation.
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
Check whether or not an instruction may read or write the optionally specified memory location.
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.
unsigned getBitWidth() const
Return the number of bits in the APInt.
int64_t getSExtValue() const
Get sign extended value.
A container for analyses that lazily runs them and caches their results.
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.
LLVM_ABI iterator_range< filter_iterator< BasicBlock::const_iterator, std::function< bool(const Instruction &)> > > instructionsWithoutDebug(bool SkipPseudoOp=true) const
Return a const iterator range over the instructions in the block, skipping any debug instructions.
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
const Instruction & front() const
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const Function * getParent() const
Return the enclosing method, or null if none.
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 if the block is well formed or null if the block is not well forme...
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
Conditional or Unconditional Branch instruction.
void setCondition(Value *V)
bool isConditional() const
unsigned getNumSuccessors() const
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() 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...
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.
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 ...
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.
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
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 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.
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 in this loop.
bool isOutermost() const
Return true if the loop does not have a parent (natural) loop.
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.
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.
bool isLoopInvariant(const Value *V, bool HasCoroSuspendInst=false) const
Return true if the specified value is loop invariant.
DebugLoc getStartLoc() const
Return the debug location of the start of this loop.
StringRef getName() const
This class implements a map that also provides access to all stored values in a deterministic order.
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.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
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.
const SCEV * getStart() const
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values.
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.
const SCEV * 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.
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.
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
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 * 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 const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
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 * applyLoopGuards(const SCEV *Expr, const Loop *L)
Try to apply information from loop guards for L to Expr.
LLVM_ABI const SCEV * getMulExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
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 * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI 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 key_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()
StringRef - 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.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
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.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
LLVM_ABI unsigned getIntegerBitWidth() const
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
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.
iterator_range< user_iterator > users()
LLVM_ABI void 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 void replaceUsesOutsideBlock(Value *V, BasicBlock *BB)
replaceUsesOutsideBlock - Go through the uses list for this definition and make each use point to "V"...
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
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.
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.
@ C
The default llvm calling convention, compatible with C.
OperandType
Operands are tagged with one of the values of this enum.
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)
bind_ty< 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.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
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.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
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)
class_match< BasicBlock > m_BasicBlock()
Match an arbitrary basic block value and ignore it.
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.
class_match< const SCEVConstant > m_SCEVConstant()
specificloop_ty m_SpecificLoop(const Loop *L)
SCEVAffineAddRec_match< Op0_t, Op1_t, class_match< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
bool match(const SCEV *S, const Pattern &P)
specificscev_ty m_scev_Specific(const SCEV *S)
Match if we have a specific specified SCEV.
class_match< const SCEV > m_SCEV()
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
DiagnosticInfoOptimizationBase::setExtraArgs setExtraArgs
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
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.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
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 bool isMustProgress(const Loop *L)
Return true if this loop can be assumed to make progress.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isModOrRefSet(const ModRefInfo MRI)
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.
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.
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.
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 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...
LLVM_ABI bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
If the specified value is an effectively dead PHI node, due to being a def-use chain of single-use no...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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.
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.
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 bool Wcslen
When true, Wcslen is disabled.
static bool Strlen
When true, Strlen is disabled.
static bool Memset
When true, Memset is disabled.
static bool All
When true, the entire pass is disabled.
static bool Memcpy
When true, Memcpy 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.
Match loop-invariant value.
match_LoopInvariant(const SubPattern_t &SP, const Loop *L)