98#define DEBUG_TYPE "loop-idiom"
100STATISTIC(NumMemSet,
"Number of memset's formed from loop stores");
101STATISTIC(NumMemCpy,
"Number of memcpy's formed from loop load+stores");
102STATISTIC(NumMemMove,
"Number of memmove's formed from loop load+stores");
103STATISTIC(NumStrLen,
"Number of strlen's and wcslen's formed from loop loads");
105 NumShiftUntilBitTest,
106 "Number of uncountable loops recognized as 'shift until bitttest' idiom");
108 "Number of uncountable loops recognized as 'shift until zero' idiom");
114 cl::desc(
"Options to disable Loop Idiom Recognize Pass."),
121 cl::desc(
"Proceed with loop idiom recognize pass, but do "
122 "not convert loop(s) to memset."),
129 cl::desc(
"Proceed with loop idiom recognize pass, but do "
130 "not convert loop(s) to memcpy."),
137 cl::desc(
"Proceed with loop idiom recognize pass, but do "
138 "not convert loop(s) to strlen."),
145 cl::desc(
"Proceed with loop idiom recognize pass, "
146 "enable conversion of loop(s) to wcslen."),
153 cl::desc(
"Proceed with loop idiom recognize pass, "
154 "but do not optimize CRC loops."),
159 "use-lir-code-size-heurs",
160 cl::desc(
"Use loop idiom recognition code size heuristics when compiling "
165 "loop-idiom-force-memset-pattern-intrinsic",
166 cl::desc(
"Use memset.pattern intrinsic whenever possible"),
cl::init(
false),
175class LoopIdiomRecognize {
176 Loop *CurLoop =
nullptr;
185 bool ApplyCodeSizeHeuristics;
186 std::unique_ptr<MemorySSAUpdater> MSSAU;
195 :
AA(
AA), DT(DT), LI(LI), SE(SE), TLI(TLI),
TTI(
TTI),
DL(
DL), ORE(ORE) {
197 MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
200 bool runOnLoop(Loop *L);
203 using StoreList = SmallVector<StoreInst *, 8>;
204 using StoreListMap = MapVector<Value *, StoreList>;
206 StoreListMap StoreRefsForMemset;
207 StoreListMap StoreRefsForMemsetPattern;
208 StoreList StoreRefsForMemcpy;
210 bool HasMemsetPattern;
214 enum LegalStoreKind {
219 UnorderedAtomicMemcpy,
227 bool runOnCountableLoop();
228 bool runOnLoopBlock(BasicBlock *BB,
const SCEV *BECount,
229 SmallVectorImpl<BasicBlock *> &ExitBlocks);
231 void collectStores(BasicBlock *BB);
232 LegalStoreKind isLegalStore(StoreInst *SI);
233 enum class ForMemset {
No,
Yes };
234 bool processLoopStores(SmallVectorImpl<StoreInst *> &SL,
const SCEV *BECount,
237 template <
typename MemInst>
238 bool processLoopMemIntrinsic(
240 bool (LoopIdiomRecognize::*Processor)(MemInst *,
const SCEV *),
241 const SCEV *BECount);
242 bool processLoopMemCpy(MemCpyInst *MCI,
const SCEV *BECount);
243 bool processLoopMemSet(MemSetInst *MSI,
const SCEV *BECount);
245 bool processLoopStridedStore(
Value *DestPtr,
const SCEV *StoreSizeSCEV,
246 MaybeAlign StoreAlignment,
Value *StoredVal,
247 Instruction *TheStore,
248 SmallPtrSetImpl<Instruction *> &Stores,
249 const SCEVAddRecExpr *Ev,
const SCEV *BECount,
250 bool IsNegStride,
bool IsLoopMemset =
false);
251 bool processLoopStoreOfLoopLoad(StoreInst *SI,
const SCEV *BECount);
252 bool processLoopStoreOfLoopLoad(
Value *DestPtr,
Value *SourcePtr,
253 const SCEV *StoreSize, MaybeAlign StoreAlign,
254 MaybeAlign LoadAlign, Instruction *TheStore,
255 Instruction *TheLoad,
256 const SCEVAddRecExpr *StoreEv,
257 const SCEVAddRecExpr *LoadEv,
258 const SCEV *BECount);
259 bool avoidLIRForMultiBlockLoop(
bool IsMemset =
false,
260 bool IsLoopMemset =
false);
261 bool optimizeCRCLoop(
const PolynomialInfo &Info);
267 bool runOnNoncountableLoop();
269 bool recognizePopcount();
270 void transformLoopToPopcount(BasicBlock *PreCondBB, Instruction *CntInst,
271 PHINode *CntPhi,
Value *Var);
273 bool ZeroCheck,
size_t CanonicalSize);
275 Instruction *DefX, PHINode *CntPhi,
276 Instruction *CntInst);
277 bool recognizeAndInsertFFS();
278 bool recognizeShiftUntilLessThan();
279 void transformLoopToCountable(
Intrinsic::ID IntrinID, BasicBlock *PreCondBB,
280 Instruction *CntInst, PHINode *CntPhi,
281 Value *Var, Instruction *DefX,
283 bool IsCntPhiUsedOutsideLoop,
284 bool InsertSub =
false);
286 bool recognizeShiftUntilBitTest();
287 bool recognizeShiftUntilZero();
288 bool recognizeAndInsertStrLen();
300 const auto *
DL = &L.getHeader()->getDataLayout();
307 LoopIdiomRecognize LIR(&AR.
AA, &AR.
DT, &AR.
LI, &AR.
SE, &AR.
TLI, &AR.
TTI,
309 if (!LIR.runOnLoop(&L))
320 I->eraseFromParent();
329bool LoopIdiomRecognize::runOnLoop(
Loop *L) {
333 if (!
L->getLoopPreheader())
338 if (Name ==
"memset" || Name ==
"memcpy" || Name ==
"strlen" ||
343 ApplyCodeSizeHeuristics =
346 HasMemset = TLI->
has(LibFunc_memset);
352 HasMemsetPattern = TLI->
has(LibFunc_memset_pattern16);
353 HasMemcpy = TLI->
has(LibFunc_memcpy);
358 return runOnCountableLoop();
360 return runOnNoncountableLoop();
363bool LoopIdiomRecognize::runOnCountableLoop() {
366 "runOnCountableLoop() called on a loop without a predictable"
367 "backedge-taken count");
389 bool MadeChange =
false;
397 MadeChange |= runOnLoopBlock(BB, BECount, ExitBlocks);
404 optimizeCRCLoop(*Res);
439 if (
DL->isBigEndian())
451 Type *CTy =
C->getType();
458LoopIdiomRecognize::LegalStoreKind
461 if (
SI->isVolatile())
462 return LegalStoreKind::None;
464 if (!
SI->isUnordered())
465 return LegalStoreKind::None;
468 if (
SI->getMetadata(LLVMContext::MD_nontemporal))
469 return LegalStoreKind::None;
471 Value *StoredVal =
SI->getValueOperand();
472 Value *StorePtr =
SI->getPointerOperand();
474 if (
DL->hasUnstableRepresentation(StoredVal->
getType()))
475 return LegalStoreKind::None;
484 bool MustPreserveExternalState =
DL->hasExternalState(StoredVal->
getType()) &&
493 return LegalStoreKind::None;
502 return LegalStoreKind::None;
513 bool UnorderedAtomic =
SI->isUnordered() && !
SI->isSimple();
517 if (!MustPreserveExternalState && !UnorderedAtomic && HasMemset &&
523 return LegalStoreKind::Memset;
525 if (!MustPreserveExternalState && !UnorderedAtomic &&
532 return LegalStoreKind::MemsetPattern;
539 unsigned StoreSize =
DL->getTypeStoreSize(
SI->getValueOperand()->getType());
541 if (StoreSize != StrideAP && StoreSize != -StrideAP)
542 return LegalStoreKind::None;
549 return LegalStoreKind::None;
552 return LegalStoreKind::None;
562 return LegalStoreKind::None;
565 UnorderedAtomic = UnorderedAtomic || LI->
isAtomic();
566 return UnorderedAtomic ? LegalStoreKind::UnorderedAtomicMemcpy
567 : LegalStoreKind::Memcpy;
570 return LegalStoreKind::None;
573void LoopIdiomRecognize::collectStores(
BasicBlock *BB) {
574 StoreRefsForMemset.clear();
575 StoreRefsForMemsetPattern.clear();
576 StoreRefsForMemcpy.clear();
583 switch (isLegalStore(
SI)) {
584 case LegalStoreKind::None:
587 case LegalStoreKind::Memset: {
590 StoreRefsForMemset[Ptr].push_back(
SI);
592 case LegalStoreKind::MemsetPattern: {
595 StoreRefsForMemsetPattern[Ptr].push_back(
SI);
597 case LegalStoreKind::Memcpy:
598 case LegalStoreKind::UnorderedAtomicMemcpy:
599 StoreRefsForMemcpy.push_back(
SI);
602 assert(
false &&
"unhandled return value");
611bool LoopIdiomRecognize::runOnLoopBlock(
621 bool MadeChange =
false;
628 for (
auto &SL : StoreRefsForMemset)
629 MadeChange |= processLoopStores(SL.second, BECount, ForMemset::Yes);
631 for (
auto &SL : StoreRefsForMemsetPattern)
632 MadeChange |= processLoopStores(SL.second, BECount, ForMemset::No);
635 for (
auto &
SI : StoreRefsForMemcpy)
636 MadeChange |= processLoopStoreOfLoopLoad(
SI, BECount);
638 MadeChange |= processLoopMemIntrinsic<MemCpyInst>(
639 BB, &LoopIdiomRecognize::processLoopMemCpy, BECount);
640 MadeChange |= processLoopMemIntrinsic<MemSetInst>(
641 BB, &LoopIdiomRecognize::processLoopMemSet, BECount);
648 const SCEV *BECount, ForMemset For) {
656 for (
unsigned i = 0, e = SL.
size(); i < e; ++i) {
657 assert(SL[i]->
isSimple() &&
"Expected only non-volatile stores.");
659 Value *FirstStoredVal = SL[i]->getValueOperand();
660 Value *FirstStorePtr = SL[i]->getPointerOperand();
664 unsigned FirstStoreSize =
DL->getTypeStoreSize(SL[i]->getValueOperand()->
getType());
667 if (FirstStride == FirstStoreSize || -FirstStride == FirstStoreSize) {
672 Value *FirstSplatValue =
nullptr;
673 Constant *FirstPatternValue =
nullptr;
675 if (For == ForMemset::Yes)
680 assert((FirstSplatValue || FirstPatternValue) &&
681 "Expected either splat value or pattern value.");
689 for (j = i + 1;
j <
e; ++
j)
691 for (j = i;
j > 0; --
j)
694 for (
auto &k : IndexQueue) {
695 assert(SL[k]->
isSimple() &&
"Expected only non-volatile stores.");
696 Value *SecondStorePtr = SL[
k]->getPointerOperand();
701 if (FirstStride != SecondStride)
704 Value *SecondStoredVal = SL[
k]->getValueOperand();
705 Value *SecondSplatValue =
nullptr;
706 Constant *SecondPatternValue =
nullptr;
708 if (For == ForMemset::Yes)
713 assert((SecondSplatValue || SecondPatternValue) &&
714 "Expected either splat value or pattern value.");
717 if (For == ForMemset::Yes) {
719 FirstSplatValue = SecondSplatValue;
720 if (FirstSplatValue != SecondSplatValue)
724 FirstPatternValue = SecondPatternValue;
725 if (FirstPatternValue != SecondPatternValue)
730 ConsecutiveChain[SL[i]] = SL[
k];
750 unsigned StoreSize = 0;
753 while (Tails.
count(
I) || Heads.count(
I)) {
754 if (TransformedStores.
count(
I))
758 StoreSize +=
DL->getTypeStoreSize(
I->getValueOperand()->getType());
760 I = ConsecutiveChain[
I];
770 if (StoreSize != Stride && StoreSize != -Stride)
773 bool IsNegStride = StoreSize == -Stride;
777 if (processLoopStridedStore(StorePtr, StoreSizeSCEV,
779 HeadStore, AdjacentStores, StoreEv, BECount,
791template <
typename MemInst>
792bool LoopIdiomRecognize::processLoopMemIntrinsic(
794 bool (LoopIdiomRecognize::*Processor)(MemInst *,
const SCEV *),
795 const SCEV *BECount) {
796 bool MadeChange =
false;
802 if (!(this->*Processor)(
MI, BECount))
816bool LoopIdiomRecognize::processLoopMemCpy(
MemCpyInst *MCI,
817 const SCEV *BECount) {
828 if (!Dest || !Source)
836 const APInt *StoreStrideValue, *LoadStrideValue;
847 if ((SizeInBytes >> 32) != 0)
855 if (SizeInBytes != *StoreStrideValue && SizeInBytes != -*StoreStrideValue) {
858 <<
ore::NV(
"Inst",
"memcpy") <<
" in "
860 <<
" function will not be hoisted: "
861 <<
ore::NV(
"Reason",
"memcpy size is not equal to stride");
866 int64_t StoreStrideInt = StoreStrideValue->
getSExtValue();
867 int64_t LoadStrideInt = LoadStrideValue->
getSExtValue();
869 if (StoreStrideInt != LoadStrideInt)
872 return processLoopStoreOfLoopLoad(
879bool LoopIdiomRecognize::processLoopMemSet(
MemSetInst *MSI,
880 const SCEV *BECount) {
895 const SCEV *PointerStrideSCEV;
904 bool IsNegStride =
false;
907 if (IsConstantSize) {
917 if (SizeInBytes != *Stride && SizeInBytes != -*Stride)
920 IsNegStride = SizeInBytes == -*Stride;
928 if (
Pointer->getType()->getPointerAddressSpace() != 0) {
944 LLVM_DEBUG(
dbgs() <<
" MemsetSizeSCEV: " << *MemsetSizeSCEV <<
"\n"
945 <<
" PositiveStrideSCEV: " << *PositiveStrideSCEV
948 if (PositiveStrideSCEV != MemsetSizeSCEV) {
951 const SCEV *FoldedPositiveStride =
953 const SCEV *FoldedMemsetSize =
957 <<
" FoldedMemsetSize: " << *FoldedMemsetSize <<
"\n"
958 <<
" FoldedPositiveStride: " << *FoldedPositiveStride
961 if (FoldedPositiveStride != FoldedMemsetSize) {
986 assert(SplatByte &&
"expected a bytewise splat value to match against");
988 if (!
SI || !
SI->isSimple() || !L->isLoopInvariant(
SI->getValueOperand()))
1000 const SCEV *BECount,
1003 Value *SplatByte =
nullptr,
1012 const APInt *BECst, *ConstSize;
1016 std::optional<uint64_t> SizeInt = ConstSize->
tryZExtValue();
1018 if (BEInt && SizeInt)
1030 bool TrySameByteValue = !AccessSize.
isPrecise() && SplatByte &&
DL;
1047 Type *IntPtr,
const SCEV *StoreSizeSCEV,
1050 if (!StoreSizeSCEV->
isOne()) {
1065 const SCEV *StoreSizeSCEV,
Loop *CurLoop,
1067 const SCEV *TripCountSCEV =
1076bool LoopIdiomRecognize::processLoopStridedStore(
1080 const SCEV *BECount,
bool IsNegStride,
bool IsLoopMemset) {
1092 Type *DestInt8PtrTy = Builder.getPtrTy(DestAS);
1103 if (!Expander.isSafeToExpand(Start))
1112 Expander.expandCodeFor(Start, DestInt8PtrTy, Preheader->
getTerminator());
1125 StoreSizeSCEV, *
AA, Stores, SplatValue,
DL))
1128 if (avoidLIRForMultiBlockLoop(
true, IsLoopMemset))
1139 std::optional<int64_t> BytesWritten;
1142 const SCEV *TripCountS =
1144 if (!Expander.isSafeToExpand(TripCountS))
1147 if (!ConstStoreSize)
1149 Value *TripCount = Expander.expandCodeFor(TripCountS, IntIdxTy,
1151 uint64_t PatternRepsPerTrip =
1152 (ConstStoreSize->
getValue()->getZExtValue() * 8) /
1153 DL->getTypeSizeInBits(PatternValue->
getType());
1158 PatternRepsPerTrip == 1
1160 : Builder.CreateMul(TripCount,
1162 PatternRepsPerTrip));
1168 const SCEV *NumBytesS =
1169 getNumBytes(BECount, IntIdxTy, StoreSizeSCEV, CurLoop,
DL, SE);
1173 if (!Expander.isSafeToExpand(NumBytesS))
1176 Expander.expandCodeFor(NumBytesS, IntIdxTy, Preheader->
getTerminator());
1178 BytesWritten = CI->getZExtValue();
1180 assert(MemsetArg &&
"MemsetArg should have been set");
1184 AATags = AATags.
merge(
Store->getAAMetadata());
1186 AATags = AATags.
extendTo(BytesWritten.value());
1192 NewCall = Builder.CreateMemSet(BasePtr, SplatValue, MemsetArg,
1199 NewCall = Builder.CreateIntrinsicWithoutFolding(
1200 Intrinsic::experimental_memset_pattern,
1201 {DestInt8PtrTy, PatternValue->
getType(), IntIdxTy},
1202 {
BasePtr, PatternValue, MemsetArg,
1215 MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB(
1221 <<
" from store to: " << *Ev <<
" at: " << *TheStore
1227 R <<
"Transformed loop-strided store in "
1229 <<
" function into a call to "
1232 if (!Stores.empty())
1234 for (
auto *
I : Stores) {
1235 R <<
ore::NV(
"FromBlock",
I->getParent()->getName())
1243 for (
auto *
I : Stores) {
1245 MSSAU->removeMemoryAccess(
I,
true);
1249 MSSAU->getMemorySSA()->verifyMemorySSA();
1251 ExpCleaner.markResultUsed();
1258bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
StoreInst *
SI,
1259 const SCEV *BECount) {
1260 assert(
SI->isUnordered() &&
"Expected only non-volatile non-ordered stores.");
1262 Value *StorePtr =
SI->getPointerOperand();
1264 unsigned StoreSize =
DL->getTypeStoreSize(
SI->getValueOperand()->getType());
1277 return processLoopStoreOfLoopLoad(StorePtr, LoadPtr, StoreSizeSCEV,
1279 StoreEv, LoadEv, BECount);
1283class MemmoveVerifier {
1285 explicit MemmoveVerifier(
const Value &LoadBasePtr,
const Value &StoreBasePtr,
1286 const DataLayout &
DL)
1288 LoadBasePtr.stripPointerCasts(), LoadOff,
DL)),
1290 StoreBasePtr.stripPointerCasts(), StoreOff,
DL)),
1291 IsSameObject(BP1 == BP2) {}
1293 bool loadAndStoreMayFormMemmove(
unsigned StoreSize,
bool IsNegStride,
1294 const Instruction &TheLoad,
1295 bool IsMemCpy)
const {
1299 if ((!IsNegStride && LoadOff <= StoreOff) ||
1300 (IsNegStride && LoadOff >= StoreOff))
1306 DL.getTypeSizeInBits(TheLoad.
getType()).getFixedValue() / 8;
1307 if (BP1 != BP2 || LoadSize != int64_t(StoreSize))
1309 if ((!IsNegStride && LoadOff < StoreOff + int64_t(StoreSize)) ||
1310 (IsNegStride && LoadOff + LoadSize > StoreOff))
1317 const DataLayout &
DL;
1318 int64_t LoadOff = 0;
1319 int64_t StoreOff = 0;
1324 const bool IsSameObject;
1328bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
1358 assert(ConstStoreSize &&
"store size is expected to be a constant");
1361 bool IsNegStride = StoreSize == -Stride;
1374 Value *StoreBasePtr = Expander.expandCodeFor(
1375 StrStart, Builder.getPtrTy(StrAS), Preheader->
getTerminator());
1387 IgnoredInsts.
insert(TheStore);
1390 const StringRef InstRemark = IsMemCpy ?
"memcpy" :
"load and store";
1392 bool LoopAccessStore =
1394 StoreSizeSCEV, *
AA, IgnoredInsts);
1395 if (LoopAccessStore) {
1401 IgnoredInsts.
insert(TheLoad);
1403 BECount, StoreSizeSCEV, *
AA, IgnoredInsts)) {
1407 <<
ore::NV(
"Inst", InstRemark) <<
" in "
1409 <<
" function will not be hoisted: "
1410 <<
ore::NV(
"Reason",
"The loop may access store location");
1414 IgnoredInsts.
erase(TheLoad);
1427 Value *LoadBasePtr = Expander.expandCodeFor(LdStart, Builder.getPtrTy(LdAS),
1432 MemmoveVerifier
Verifier(*LoadBasePtr, *StoreBasePtr, *
DL);
1433 if (IsMemCpy && !
Verifier.IsSameObject)
1434 IgnoredInsts.
erase(TheStore);
1436 StoreSizeSCEV, *
AA, IgnoredInsts)) {
1439 <<
ore::NV(
"Inst", InstRemark) <<
" in "
1441 <<
" function will not be hoisted: "
1442 <<
ore::NV(
"Reason",
"The loop may access load location");
1448 bool UseMemMove = IsMemCpy ?
Verifier.IsSameObject : LoopAccessStore;
1457 assert((StoreAlign && LoadAlign) &&
1458 "Expect unordered load/store to have align.");
1459 if (*StoreAlign < StoreSize || *LoadAlign < StoreSize)
1466 if (StoreSize >
TTI->getAtomicMemIntrinsicMaxElementSize())
1471 if (!
Verifier.loadAndStoreMayFormMemmove(StoreSize, IsNegStride, *TheLoad,
1475 if (avoidLIRForMultiBlockLoop())
1480 const SCEV *NumBytesS =
1481 getNumBytes(BECount, IntIdxTy, StoreSizeSCEV, CurLoop,
DL, SE);
1484 Expander.expandCodeFor(NumBytesS, IntIdxTy, Preheader->
getTerminator());
1488 AATags = AATags.
merge(StoreAATags);
1490 AATags = AATags.
extendTo(CI->getZExtValue());
1500 NewCall = Builder.CreateMemMove(StoreBasePtr, StoreAlign, LoadBasePtr,
1501 LoadAlign, NumBytes,
1505 Builder.CreateMemCpy(StoreBasePtr, StoreAlign, LoadBasePtr, LoadAlign,
1506 NumBytes,
false, AATags);
1511 NewCall = Builder.CreateElementUnorderedAtomicMemCpy(
1512 StoreBasePtr, *StoreAlign, LoadBasePtr, *LoadAlign, NumBytes, StoreSize,
1518 MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB(
1524 <<
" from load ptr=" << *LoadEv <<
" at: " << *TheLoad
1526 <<
" from store ptr=" << *StoreEv <<
" at: " << *TheStore
1532 <<
"Formed a call to "
1534 <<
"() intrinsic from " <<
ore::NV(
"Inst", InstRemark)
1545 MSSAU->removeMemoryAccess(TheStore,
true);
1548 MSSAU->getMemorySSA()->verifyMemorySSA();
1553 ExpCleaner.markResultUsed();
1560bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(
bool IsMemset,
1561 bool IsLoopMemset) {
1562 if (ApplyCodeSizeHeuristics && CurLoop->
getNumBlocks() > 1) {
1563 if (CurLoop->
isOutermost() && (!IsMemset || !IsLoopMemset)) {
1565 <<
" : LIR " << (IsMemset ?
"Memset" :
"Memcpy")
1566 <<
" avoided: multi-block top-level loop\n");
1574bool LoopIdiomRecognize::optimizeCRCLoop(
const PolynomialInfo &Info) {
1589 std::array<Constant *, 256> CRCConstants;
1591 CRCConstants.begin(),
1592 [CRCTy](
const APInt &
E) { return ConstantInt::get(CRCTy, E); });
1614 unsigned NewBTC = (
Info.TripCount / 8) - 1;
1621 Value *ExitLimit = ConstantInt::get(
IV->getType(), NewBTC);
1623 Value *NewExitCond =
1624 Builder.CreateICmp(ExitPred,
IV, ExitLimit,
"exit.cond");
1643 Type *OpTy =
Op->getType();
1647 return LoByte(Builder,
1648 CRCBW > 8 ? Builder.CreateLShr(
1649 Op, ConstantInt::get(OpTy, CRCBW - 8), Name)
1659 PHINode *CRCPhi = Builder.CreatePHI(CRCTy, 2,
"crc");
1663 Value *CRC = CRCPhi;
1667 Value *Indexer = CRC;
1675 Value *IVBits = Builder.CreateZExtOrTrunc(
1676 Builder.CreateShl(
IV, 3,
"iv.bits"), DataTy,
"iv.indexer");
1677 Value *DataIndexer =
1678 Info.IsBigEndian ? Builder.CreateShl(
Data, IVBits,
"data.indexer")
1679 : Builder.CreateLShr(
Data, IVBits,
"data.indexer");
1680 Indexer = Builder.CreateXor(
1682 Builder.CreateZExtOrTrunc(Indexer, DataTy,
"crc.indexer.cast"),
1683 "crc.data.indexer");
1686 Indexer =
Info.IsBigEndian ? HiIdx(Builder, Indexer,
"indexer.hi")
1687 : LoByte(Builder, Indexer,
"indexer.lo");
1690 Indexer = Builder.CreateZExt(
1695 Value *CRCTableGEP =
1696 Builder.CreateInBoundsGEP(CRCTy, GV, Indexer,
"tbl.ptradd");
1697 Value *CRCTableLd = Builder.CreateLoad(CRCTy, CRCTableGEP,
"tbl.ld");
1701 Value *CRCNext = CRCTableLd;
1704 ? Builder.CreateShl(CRC, 8,
"crc.be.shift")
1705 : Builder.CreateLShr(CRC, 8,
"crc.le.shift");
1706 CRCNext = Builder.CreateXor(CRCShift, CRCTableLd,
"crc.next");
1711 Info.ComputedValue->replaceUsesOutsideBlock(CRCNext,
1724bool LoopIdiomRecognize::runOnNoncountableLoop() {
1727 <<
"] Noncountable Loop %"
1730 return recognizePopcount() || recognizeAndInsertFFS() ||
1731 recognizeShiftUntilBitTest() || recognizeShiftUntilZero() ||
1732 recognizeShiftUntilLessThan() || recognizeAndInsertStrLen();
1742 bool JmpOnZero =
false) {
1748 if (!CmpZero || !CmpZero->isZero())
1759 return Cond->getOperand(0);
1766class StrlenVerifier {
1768 explicit StrlenVerifier(
const Loop *CurLoop, ScalarEvolution *SE,
1769 const TargetLibraryInfo *TLI)
1770 : CurLoop(CurLoop), SE(SE), TLI(TLI) {}
1772 bool isValidStrlenIdiom() {
1791 if (!LoopBody || LoopBody->
size() >= 15)
1812 const SCEV *LoadEv = SE->
getSCEV(IncPtr);
1825 if (OpWidth != StepSize * 8)
1827 if (OpWidth != 8 && OpWidth != 16 && OpWidth != 32)
1830 if (OpWidth != WcharSize * 8)
1834 for (Instruction &
I : *LoopBody)
1835 if (
I.mayHaveSideEffects())
1842 for (PHINode &PN : LoopExitBB->
phis()) {
1846 const SCEV *Ev = SE->
getSCEV(&PN);
1856 if (!AddRecEv || !AddRecEv->
isAffine())
1870 const Loop *CurLoop;
1871 ScalarEvolution *SE;
1872 const TargetLibraryInfo *TLI;
1875 ConstantInt *StepSizeCI;
1876 const SCEV *LoadBaseEv;
1941bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
1945 StrlenVerifier
Verifier(CurLoop, SE, TLI);
1947 if (!
Verifier.isValidStrlenIdiom())
1954 assert(Preheader && LoopBody && LoopExitBB &&
1955 "Should be verified to be valid by StrlenVerifier");
1970 Builder.SetCurrentDebugLocation(CurLoop->
getStartLoc());
1972 Value *MaterialzedBase = Expander.expandCodeFor(
1974 Builder.GetInsertPoint());
1976 Value *StrLenFunc =
nullptr;
1978 StrLenFunc =
emitStrLen(MaterialzedBase, Builder, *
DL, TLI);
1980 StrLenFunc =
emitWcsLen(MaterialzedBase, Builder, *
DL, TLI);
1982 assert(StrLenFunc &&
"Failed to emit strlen function.");
2001 StrlenEv,
Base->getType())));
2003 Value *MaterializedPHI = Expander.expandCodeFor(NewEv, NewEv->
getType(),
2004 Builder.GetInsertPoint());
2019 "loop body must have a successor that is it self");
2021 ? Builder.getFalse()
2022 : Builder.getTrue();
2027 LLVM_DEBUG(
dbgs() <<
" Formed strlen idiom: " << *StrLenFunc <<
"\n");
2031 <<
"Transformed " << StrLenFunc->
getName() <<
" loop idiom";
2056 return Cond->getOperand(0);
2067 if (PhiX && PhiX->getParent() == LoopEntry &&
2068 (PhiX->getOperand(0) == DefX || PhiX->
getOperand(1) == DefX))
2135 if (DefX->
getOpcode() != Instruction::LShr)
2138 IntrinID = Intrinsic::ctlz;
2140 if (!Shft || !Shft->
isOne())
2154 if (Inst.
getOpcode() != Instruction::Add)
2206 Value *VarX1, *VarX0;
2209 DefX2 = CountInst =
nullptr;
2210 VarX1 = VarX0 =
nullptr;
2211 PhiX = CountPhi =
nullptr;
2224 if (!DefX2 || DefX2->
getOpcode() != Instruction::And)
2235 if (!SubOneOp || SubOneOp->
getOperand(0) != VarX1)
2241 (SubOneOp->
getOpcode() == Instruction::Add &&
2254 CountInst =
nullptr;
2257 if (Inst.
getOpcode() != Instruction::Add)
2261 if (!Inc || !Inc->
isOne())
2269 bool LiveOutLoop =
false;
2298 CntInst = CountInst;
2338 Value *VarX =
nullptr;
2352 if (!DefX || !DefX->
isShift())
2354 IntrinID = DefX->
getOpcode() == Instruction::Shl ? Intrinsic::cttz :
2357 if (!Shft || !Shft->
isOne())
2382 if (Inst.
getOpcode() != Instruction::Add)
2405bool LoopIdiomRecognize::isProfitableToInsertFFS(
Intrinsic::ID IntrinID,
2406 Value *InitX,
bool ZeroCheck,
2407 size_t CanonicalSize) {
2425bool LoopIdiomRecognize::insertFFSIfProfitable(
Intrinsic::ID IntrinID,
2429 bool IsCntPhiUsedOutsideLoop =
false;
2432 IsCntPhiUsedOutsideLoop =
true;
2435 bool IsCntInstUsedOutsideLoop =
false;
2438 IsCntInstUsedOutsideLoop =
true;
2443 if (IsCntInstUsedOutsideLoop && IsCntPhiUsedOutsideLoop)
2449 bool ZeroCheck =
false;
2458 if (!IsCntPhiUsedOutsideLoop) {
2477 size_t IdiomCanonicalSize = 6;
2478 if (!isProfitableToInsertFFS(IntrinID, InitX, ZeroCheck, IdiomCanonicalSize))
2481 transformLoopToCountable(IntrinID, PH, CntInst, CntPhi, InitX, DefX,
2483 IsCntPhiUsedOutsideLoop);
2490bool LoopIdiomRecognize::recognizeAndInsertFFS() {
2505 return insertFFSIfProfitable(IntrinID, InitX, DefX, CntPhi, CntInst);
2508bool LoopIdiomRecognize::recognizeShiftUntilLessThan() {
2519 APInt LoopThreshold;
2521 CntPhi, DefX, LoopThreshold))
2524 if (LoopThreshold == 2) {
2526 return insertFFSIfProfitable(IntrinID, InitX, DefX, CntPhi, CntInst);
2530 if (LoopThreshold != 4)
2548 APInt PreLoopThreshold;
2550 PreLoopThreshold != 2)
2553 bool ZeroCheck =
true;
2562 size_t IdiomCanonicalSize = 6;
2563 if (!isProfitableToInsertFFS(IntrinID, InitX, ZeroCheck, IdiomCanonicalSize))
2567 transformLoopToCountable(IntrinID, PH, CntInst, CntPhi, InitX, DefX,
2578bool LoopIdiomRecognize::recognizePopcount() {
2592 if (LoopBody->
size() >= 20) {
2620 transformLoopToPopcount(PreCondBB, CntInst, CntPhi, Val);
2674void LoopIdiomRecognize::transformLoopToCountable(
2677 bool ZeroCheck,
bool IsCntPhiUsedOutsideLoop,
bool InsertSub) {
2680 Builder.SetCurrentDebugLocation(
DL);
2689 if (IsCntPhiUsedOutsideLoop) {
2690 if (DefX->
getOpcode() == Instruction::AShr)
2691 InitXNext = Builder.CreateAShr(InitX, 1);
2692 else if (DefX->
getOpcode() == Instruction::LShr)
2693 InitXNext = Builder.CreateLShr(InitX, 1);
2694 else if (DefX->
getOpcode() == Instruction::Shl)
2695 InitXNext = Builder.CreateShl(InitX, 1);
2703 Count = Builder.CreateSub(
2706 Count = Builder.CreateSub(
Count, ConstantInt::get(CountTy, 1));
2708 if (IsCntPhiUsedOutsideLoop)
2709 Count = Builder.CreateAdd(
Count, ConstantInt::get(CountTy, 1));
2711 NewCount = Builder.CreateZExtOrTrunc(NewCount, CntInst->
getType());
2718 if (!InitConst || !InitConst->
isZero())
2719 NewCount = Builder.CreateAdd(NewCount, CntInitVal);
2723 NewCount = Builder.CreateSub(CntInitVal, NewCount);
2741 Builder.SetInsertPoint(LbCond);
2743 TcPhi, ConstantInt::get(CountTy, 1),
"tcdec",
false,
true));
2752 LbCond->
setOperand(1, ConstantInt::get(CountTy, 0));
2756 if (IsCntPhiUsedOutsideLoop)
2766void LoopIdiomRecognize::transformLoopToPopcount(
BasicBlock *PreCondBB,
2779 Value *PopCnt, *PopCntZext, *NewCount, *TripCnt;
2782 NewCount = PopCntZext =
2785 if (NewCount != PopCnt)
2794 if (!InitConst || !InitConst->
isZero()) {
2795 NewCount = Builder.CreateAdd(NewCount, CntInitVal);
2807 Value *Opnd0 = PopCntZext;
2808 Value *Opnd1 = ConstantInt::get(PopCntZext->
getType(), 0);
2813 Builder.CreateICmp(PreCond->
getPredicate(), Opnd0, Opnd1));
2814 PreCondBr->setCondition(NewPreCond);
2848 Builder.SetInsertPoint(LbCond);
2850 Builder.CreateSub(TcPhi, ConstantInt::get(Ty, 1),
2851 "tcdec",
false,
true));
2860 LbCond->
setOperand(1, ConstantInt::get(Ty, 0));
2881 template <
typename ITy>
bool match(ITy *V)
const {
2882 return L->isLoopInvariant(V) &&
SubPattern.match(V);
2887template <
typename Ty>
2918 " Performing shift-until-bittest idiom detection.\n");
2928 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
2935 Value *CmpLHS, *CmpRHS;
2946 auto MatchVariableBitMask = [&]() {
2956 auto MatchDecomposableConstantBitMask = [&]() {
2958 CmpLHS, CmpRHS, Pred,
true,
2960 if (Res && Res->Mask.isPowerOf2()) {
2964 BitMask = ConstantInt::get(CurrX->
getType(), Res->Mask);
2965 BitPos = ConstantInt::get(CurrX->
getType(), Res->Mask.logBase2());
2971 if (!MatchVariableBitMask() && !MatchDecomposableConstantBitMask()) {
2978 if (!CurrXPN || CurrXPN->getParent() != LoopHeaderBB) {
2983 BaseX = CurrXPN->getIncomingValueForBlock(LoopPreheaderBB);
2988 "Expected BaseX to be available in the preheader!");
2999 "Should only get equality predicates here.");
3009 if (TrueBB != LoopHeaderBB) {
3068bool LoopIdiomRecognize::recognizeShiftUntilBitTest() {
3069 bool MadeChange =
false;
3071 Value *
X, *BitMask, *BitPos, *XCurr;
3076 " shift-until-bittest idiom detection failed.\n");
3086 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3089 assert(SuccessorBB &&
"There is only a single successor.");
3095 Type *Ty =
X->getType();
3109 " Intrinsic is too costly, not beneficial\n");
3112 if (
TTI->getArithmeticInstrCost(Instruction::Shl, Ty,
CostKind) >
3124 std::optional<BasicBlock::iterator> InsertPt = std::nullopt;
3126 InsertPt = BitPosI->getInsertionPointAfterDef();
3134 return U.getUser() != BitPosFrozen;
3136 BitPos = BitPosFrozen;
3142 BitPos->
getName() +
".lowbitmask");
3144 Builder.CreateOr(LowBitMask, BitMask, BitPos->
getName() +
".mask");
3145 Value *XMasked = Builder.CreateAnd(
X, Mask,
X->getName() +
".masked");
3146 Value *XMaskedNumLeadingZeros = Builder.CreateIntrinsic(
3147 IntrID, Ty, {XMasked, Builder.getTrue()},
3148 nullptr, XMasked->
getName() +
".numleadingzeros");
3149 Value *XMaskedNumActiveBits = Builder.CreateSub(
3151 XMasked->
getName() +
".numactivebits",
true,
3153 Value *XMaskedLeadingOnePos =
3155 XMasked->
getName() +
".leadingonepos",
false,
3158 Value *LoopBackedgeTakenCount = Builder.CreateSub(
3159 BitPos, XMaskedLeadingOnePos, CurLoop->
getName() +
".backedgetakencount",
3163 Value *LoopTripCount =
3164 Builder.CreateAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
3165 CurLoop->
getName() +
".tripcount",
true,
3172 Value *NewX = Builder.CreateShl(
X, LoopBackedgeTakenCount);
3175 I->copyIRFlags(XNext,
true);
3187 NewXNext = Builder.CreateShl(
X, LoopTripCount);
3192 NewXNext = Builder.CreateShl(NewX, ConstantInt::get(Ty, 1));
3197 I->copyIRFlags(XNext,
true);
3208 Builder.SetInsertPoint(LoopHeaderBB, LoopHeaderBB->
begin());
3209 auto *
IV = Builder.CreatePHI(Ty, 2, CurLoop->
getName() +
".iv");
3215 Builder.CreateAdd(
IV, ConstantInt::get(Ty, 1),
IV->getName() +
".next",
3216 true, Bitwidth != 2);
3219 auto *IVCheck = Builder.CreateICmpEQ(IVNext, LoopTripCount,
3220 CurLoop->
getName() +
".ivcheck");
3222 const bool HasBranchWeights =
3226 auto *BI = Builder.CreateCondBr(IVCheck, SuccessorBB, LoopHeaderBB);
3227 if (HasBranchWeights) {
3229 std::swap(BranchWeights[0], BranchWeights[1]);
3239 IV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
3240 IV->addIncoming(IVNext, LoopHeaderBB);
3251 ++NumShiftUntilBitTest;
3287 const SCEV *&ExtraOffsetExpr,
3288 bool &InvertedCond) {
3290 " Performing shift-until-zero idiom detection.\n");
3303 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3314 !
match(ValShiftedIsZero,
3328 IntrinID = ValShifted->
getOpcode() == Instruction::Shl ? Intrinsic::cttz
3337 else if (
match(NBits,
3341 ExtraOffsetExpr = SE->
getSCEV(ExtraOffset);
3349 if (!IVPN || IVPN->getParent() != LoopHeaderBB) {
3354 Start = IVPN->getIncomingValueForBlock(LoopPreheaderBB);
3365 "Should only get equality predicates here.");
3376 if (FalseBB != LoopHeaderBB) {
3387 if (ValShifted->
getOpcode() == Instruction::AShr &&
3451bool LoopIdiomRecognize::recognizeShiftUntilZero() {
3452 bool MadeChange =
false;
3458 const SCEV *ExtraOffsetExpr;
3461 Start, Val, ExtraOffsetExpr, InvertedCond)) {
3463 " shift-until-zero idiom detection failed.\n");
3473 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3476 assert(SuccessorBB &&
"There is only a single successor.");
3479 Builder.SetCurrentDebugLocation(
IV->getDebugLoc());
3495 " Intrinsic is too costly, not beneficial\n");
3502 bool OffsetIsZero = ExtraOffsetExpr->
isZero();
3506 Value *ValNumLeadingZeros = Builder.CreateIntrinsic(
3507 IntrID, Ty, {Val, Builder.getFalse()},
3508 nullptr, Val->
getName() +
".numleadingzeros");
3509 Value *ValNumActiveBits = Builder.CreateSub(
3511 Val->
getName() +
".numactivebits",
true,
3515 Expander.setInsertPoint(&*Builder.GetInsertPoint());
3516 Value *ExtraOffset = Expander.expandCodeFor(ExtraOffsetExpr);
3518 Value *ValNumActiveBitsOffset = Builder.CreateAdd(
3519 ValNumActiveBits, ExtraOffset, ValNumActiveBits->
getName() +
".offset",
3520 OffsetIsZero,
true);
3521 Value *IVFinal = Builder.CreateIntrinsic(Intrinsic::smax, {Ty},
3522 {ValNumActiveBitsOffset,
Start},
3523 nullptr,
"iv.final");
3526 IVFinal, Start, CurLoop->
getName() +
".backedgetakencount",
3527 OffsetIsZero,
true));
3531 Value *LoopTripCount =
3532 Builder.CreateAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
3533 CurLoop->
getName() +
".tripcount",
true,
3539 IV->replaceUsesOutsideBlock(IVFinal, LoopHeaderBB);
3544 Builder.SetInsertPoint(LoopHeaderBB, LoopHeaderBB->
begin());
3545 auto *CIV = Builder.CreatePHI(Ty, 2, CurLoop->
getName() +
".iv");
3550 Builder.CreateAdd(CIV, ConstantInt::get(Ty, 1), CIV->getName() +
".next",
3551 true, Bitwidth != 2);
3554 auto *CIVCheck = Builder.CreateICmpEQ(CIVNext, LoopTripCount,
3555 CurLoop->
getName() +
".ivcheck");
3556 auto *NewIVCheck = CIVCheck;
3558 NewIVCheck = Builder.CreateNot(CIVCheck);
3559 NewIVCheck->takeName(ValShiftedIsZero);
3563 auto *IVDePHId = Builder.CreateAdd(CIV, Start,
"",
false,
3565 IVDePHId->takeName(
IV);
3570 const bool HasBranchWeights =
3574 auto *BI = Builder.CreateCondBr(CIVCheck, SuccessorBB, LoopHeaderBB);
3575 if (HasBranchWeights) {
3577 std::swap(BranchWeights[0], BranchWeights[1]);
3585 CIV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
3586 CIV->addIncoming(CIVNext, LoopHeaderBB);
3594 IV->replaceAllUsesWith(IVDePHId);
3595 IV->eraseFromParent();
3604 ++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< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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")))
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)
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, 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 ...
This file contains the declarations for profiling metadata utility functions.
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]
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.
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.
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...
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.
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.
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.
LLVM_ABI 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)
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element 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.
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.
@ C
The default llvm calling convention, compatible with C.
@ 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)
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
DiagnosticInfoOptimizationBase::Argument NV
DiagnosticInfoOptimizationBase::setExtraArgs setExtraArgs
This is an optimization pass for GlobalISel generic memory operations.
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)
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.
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.
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.
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.
static cl::opt< bool, true > DisableLIRPHashRecognize("disable-" DEBUG_TYPE "-hashrecognize", cl::desc("Proceed with loop idiom recognize pass, " "but do not optimize CRC loops."), cl::location(DisableLIRP::HashRecognize), cl::init(false), cl::ReallyHidden)
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)
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...
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.
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)