96#define DEBUG_TYPE "loop-idiom"
98STATISTIC(NumMemSet,
"Number of memset's formed from loop stores");
99STATISTIC(NumMemCpy,
"Number of memcpy's formed from loop load+stores");
100STATISTIC(NumMemMove,
"Number of memmove's formed from loop load+stores");
101STATISTIC(NumStrLen,
"Number of strlen's and wcslen's formed from loop loads");
103 NumShiftUntilBitTest,
104 "Number of uncountable loops recognized as 'shift until bitttest' idiom");
106 "Number of uncountable loops recognized as 'shift until zero' idiom");
111 cl::desc(
"Options to disable Loop Idiom Recognize Pass."),
118 cl::desc(
"Proceed with loop idiom recognize pass, but do "
119 "not convert loop(s) to memset."),
126 cl::desc(
"Proceed with loop idiom recognize pass, but do "
127 "not convert loop(s) to memcpy."),
134 cl::desc(
"Proceed with loop idiom recognize pass, but do "
135 "not convert loop(s) to strlen."),
142 cl::desc(
"Proceed with loop idiom recognize pass, "
143 "enable conversion of loop(s) to wcslen."),
150 cl::desc(
"Proceed with loop idiom recognize pass, "
151 "but do not optimize CRC loops."),
156 "use-lir-code-size-heurs",
157 cl::desc(
"Use loop idiom recognition code size heuristics when compiling "
162 "loop-idiom-force-memset-pattern-intrinsic",
163 cl::desc(
"Use memset.pattern intrinsic whenever possible"),
cl::init(
false),
168class LoopIdiomRecognize {
169 Loop *CurLoop =
nullptr;
178 bool ApplyCodeSizeHeuristics;
179 std::unique_ptr<MemorySSAUpdater> MSSAU;
188 :
AA(
AA), DT(DT), LI(LI), SE(SE), TLI(TLI),
TTI(
TTI),
DL(
DL), ORE(ORE) {
190 MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
193 bool runOnLoop(Loop *L);
196 using StoreList = SmallVector<StoreInst *, 8>;
197 using StoreListMap = MapVector<Value *, StoreList>;
199 StoreListMap StoreRefsForMemset;
200 StoreListMap StoreRefsForMemsetPattern;
201 StoreList StoreRefsForMemcpy;
203 bool HasMemsetPattern;
207 enum LegalStoreKind {
212 UnorderedAtomicMemcpy,
220 bool runOnCountableLoop();
221 bool runOnLoopBlock(BasicBlock *BB,
const SCEV *BECount,
222 SmallVectorImpl<BasicBlock *> &ExitBlocks);
224 void collectStores(BasicBlock *BB);
225 LegalStoreKind isLegalStore(StoreInst *SI);
226 enum class ForMemset {
No,
Yes };
227 bool processLoopStores(SmallVectorImpl<StoreInst *> &SL,
const SCEV *BECount,
230 template <
typename MemInst>
231 bool processLoopMemIntrinsic(
233 bool (LoopIdiomRecognize::*Processor)(MemInst *,
const SCEV *),
234 const SCEV *BECount);
235 bool processLoopMemCpy(MemCpyInst *MCI,
const SCEV *BECount);
236 bool processLoopMemSet(MemSetInst *MSI,
const SCEV *BECount);
238 bool processLoopStridedStore(
Value *DestPtr,
const SCEV *StoreSizeSCEV,
239 MaybeAlign StoreAlignment,
Value *StoredVal,
240 Instruction *TheStore,
241 SmallPtrSetImpl<Instruction *> &Stores,
242 const SCEVAddRecExpr *Ev,
const SCEV *BECount,
243 bool IsNegStride,
bool IsLoopMemset =
false);
244 bool processLoopStoreOfLoopLoad(StoreInst *SI,
const SCEV *BECount);
245 bool processLoopStoreOfLoopLoad(
Value *DestPtr,
Value *SourcePtr,
246 const SCEV *StoreSize, MaybeAlign StoreAlign,
247 MaybeAlign LoadAlign, Instruction *TheStore,
248 Instruction *TheLoad,
249 const SCEVAddRecExpr *StoreEv,
250 const SCEVAddRecExpr *LoadEv,
251 const SCEV *BECount);
252 bool avoidLIRForMultiBlockLoop(
bool IsMemset =
false,
253 bool IsLoopMemset =
false);
254 bool optimizeCRCLoop(
const PolynomialInfo &
Info);
260 bool runOnNoncountableLoop();
262 bool recognizePopcount();
263 void transformLoopToPopcount(BasicBlock *PreCondBB, Instruction *CntInst,
264 PHINode *CntPhi,
Value *Var);
266 bool ZeroCheck,
size_t CanonicalSize);
268 Instruction *DefX, PHINode *CntPhi,
269 Instruction *CntInst);
270 bool recognizeAndInsertFFS();
271 bool recognizeShiftUntilLessThan();
272 void transformLoopToCountable(
Intrinsic::ID IntrinID, BasicBlock *PreCondBB,
273 Instruction *CntInst, PHINode *CntPhi,
274 Value *Var, Instruction *DefX,
276 bool IsCntPhiUsedOutsideLoop,
277 bool InsertSub =
false);
279 bool recognizeShiftUntilBitTest();
280 bool recognizeShiftUntilZero();
281 bool recognizeAndInsertStrLen();
293 const auto *
DL = &L.getHeader()->getDataLayout();
300 std::optional<PolynomialInfo> HR;
302 LoopIdiomRecognize LIR(&AR.
AA, &AR.
DT, &AR.
LI, &AR.
SE, &AR.
TLI, &AR.
TTI,
304 if (!LIR.runOnLoop(&L))
315 I->eraseFromParent();
324bool LoopIdiomRecognize::runOnLoop(
Loop *L) {
328 if (!
L->getLoopPreheader())
333 if (Name ==
"memset" || Name ==
"memcpy" || Name ==
"strlen" ||
338 ApplyCodeSizeHeuristics =
341 HasMemset = TLI->
has(LibFunc_memset);
347 HasMemsetPattern = TLI->
has(LibFunc_memset_pattern16);
348 HasMemcpy = TLI->
has(LibFunc_memcpy);
353 return runOnCountableLoop();
355 return runOnNoncountableLoop();
358bool LoopIdiomRecognize::runOnCountableLoop() {
361 "runOnCountableLoop() called on a loop without a predictable"
362 "backedge-taken count");
384 bool MadeChange =
false;
392 MadeChange |= runOnLoopBlock(BB, BECount, ExitBlocks);
399 optimizeCRCLoop(*Res);
434 if (
DL->isBigEndian())
446 Type *CTy =
C->getType();
453LoopIdiomRecognize::LegalStoreKind
456 if (
SI->isVolatile())
457 return LegalStoreKind::None;
459 if (!
SI->isUnordered())
460 return LegalStoreKind::None;
463 if (
SI->getMetadata(LLVMContext::MD_nontemporal))
464 return LegalStoreKind::None;
466 Value *StoredVal =
SI->getValueOperand();
467 Value *StorePtr =
SI->getPointerOperand();
472 return LegalStoreKind::None;
480 return LegalStoreKind::None;
489 return LegalStoreKind::None;
500 bool UnorderedAtomic =
SI->isUnordered() && !
SI->isSimple();
509 return LegalStoreKind::Memset;
517 return LegalStoreKind::MemsetPattern;
524 unsigned StoreSize =
DL->getTypeStoreSize(
SI->getValueOperand()->getType());
526 if (StoreSize != StrideAP && StoreSize != -StrideAP)
527 return LegalStoreKind::None;
534 return LegalStoreKind::None;
537 return LegalStoreKind::None;
547 return LegalStoreKind::None;
550 UnorderedAtomic = UnorderedAtomic || LI->
isAtomic();
551 return UnorderedAtomic ? LegalStoreKind::UnorderedAtomicMemcpy
552 : LegalStoreKind::Memcpy;
555 return LegalStoreKind::None;
558void LoopIdiomRecognize::collectStores(
BasicBlock *BB) {
559 StoreRefsForMemset.clear();
560 StoreRefsForMemsetPattern.clear();
561 StoreRefsForMemcpy.clear();
568 switch (isLegalStore(
SI)) {
569 case LegalStoreKind::None:
572 case LegalStoreKind::Memset: {
575 StoreRefsForMemset[
Ptr].push_back(
SI);
577 case LegalStoreKind::MemsetPattern: {
580 StoreRefsForMemsetPattern[
Ptr].push_back(
SI);
582 case LegalStoreKind::Memcpy:
583 case LegalStoreKind::UnorderedAtomicMemcpy:
584 StoreRefsForMemcpy.push_back(
SI);
587 assert(
false &&
"unhandled return value");
596bool LoopIdiomRecognize::runOnLoopBlock(
606 bool MadeChange =
false;
613 for (
auto &SL : StoreRefsForMemset)
614 MadeChange |= processLoopStores(SL.second, BECount, ForMemset::Yes);
616 for (
auto &SL : StoreRefsForMemsetPattern)
617 MadeChange |= processLoopStores(SL.second, BECount, ForMemset::No);
620 for (
auto &
SI : StoreRefsForMemcpy)
621 MadeChange |= processLoopStoreOfLoopLoad(
SI, BECount);
623 MadeChange |= processLoopMemIntrinsic<MemCpyInst>(
624 BB, &LoopIdiomRecognize::processLoopMemCpy, BECount);
625 MadeChange |= processLoopMemIntrinsic<MemSetInst>(
626 BB, &LoopIdiomRecognize::processLoopMemSet, BECount);
633 const SCEV *BECount, ForMemset For) {
641 for (
unsigned i = 0, e = SL.
size(); i < e; ++i) {
642 assert(SL[i]->
isSimple() &&
"Expected only non-volatile stores.");
644 Value *FirstStoredVal = SL[i]->getValueOperand();
645 Value *FirstStorePtr = SL[i]->getPointerOperand();
649 unsigned FirstStoreSize =
DL->getTypeStoreSize(SL[i]->getValueOperand()->
getType());
652 if (FirstStride == FirstStoreSize || -FirstStride == FirstStoreSize) {
657 Value *FirstSplatValue =
nullptr;
658 Constant *FirstPatternValue =
nullptr;
660 if (For == ForMemset::Yes)
665 assert((FirstSplatValue || FirstPatternValue) &&
666 "Expected either splat value or pattern value.");
674 for (j = i + 1;
j <
e; ++
j)
676 for (j = i;
j > 0; --
j)
679 for (
auto &k : IndexQueue) {
680 assert(SL[k]->
isSimple() &&
"Expected only non-volatile stores.");
681 Value *SecondStorePtr = SL[
k]->getPointerOperand();
686 if (FirstStride != SecondStride)
689 Value *SecondStoredVal = SL[
k]->getValueOperand();
690 Value *SecondSplatValue =
nullptr;
691 Constant *SecondPatternValue =
nullptr;
693 if (For == ForMemset::Yes)
698 assert((SecondSplatValue || SecondPatternValue) &&
699 "Expected either splat value or pattern value.");
702 if (For == ForMemset::Yes) {
704 FirstSplatValue = SecondSplatValue;
705 if (FirstSplatValue != SecondSplatValue)
709 FirstPatternValue = SecondPatternValue;
710 if (FirstPatternValue != SecondPatternValue)
715 ConsecutiveChain[SL[i]] = SL[
k];
735 unsigned StoreSize = 0;
738 while (Tails.
count(
I) || Heads.count(
I)) {
739 if (TransformedStores.
count(
I))
743 StoreSize +=
DL->getTypeStoreSize(
I->getValueOperand()->getType());
745 I = ConsecutiveChain[
I];
755 if (StoreSize != Stride && StoreSize != -Stride)
758 bool IsNegStride = StoreSize == -Stride;
762 if (processLoopStridedStore(StorePtr, StoreSizeSCEV,
764 HeadStore, AdjacentStores, StoreEv, BECount,
776template <
typename MemInst>
777bool LoopIdiomRecognize::processLoopMemIntrinsic(
779 bool (LoopIdiomRecognize::*Processor)(MemInst *,
const SCEV *),
780 const SCEV *BECount) {
781 bool MadeChange =
false;
787 if (!(this->*Processor)(
MI, BECount))
801bool LoopIdiomRecognize::processLoopMemCpy(
MemCpyInst *MCI,
802 const SCEV *BECount) {
813 if (!Dest || !Source)
821 const APInt *StoreStrideValue, *LoadStrideValue;
832 if ((SizeInBytes >> 32) != 0)
840 if (SizeInBytes != *StoreStrideValue && SizeInBytes != -*StoreStrideValue) {
843 <<
ore::NV(
"Inst",
"memcpy") <<
" in "
845 <<
" function will not be hoisted: "
846 <<
ore::NV(
"Reason",
"memcpy size is not equal to stride");
851 int64_t StoreStrideInt = StoreStrideValue->
getSExtValue();
852 int64_t LoadStrideInt = LoadStrideValue->
getSExtValue();
854 if (StoreStrideInt != LoadStrideInt)
857 return processLoopStoreOfLoopLoad(
864bool LoopIdiomRecognize::processLoopMemSet(
MemSetInst *MSI,
865 const SCEV *BECount) {
880 const SCEV *PointerStrideSCEV;
889 bool IsNegStride =
false;
892 if (IsConstantSize) {
902 if (SizeInBytes != *Stride && SizeInBytes != -*Stride)
905 IsNegStride = SizeInBytes == -*Stride;
913 if (
Pointer->getType()->getPointerAddressSpace() != 0) {
926 const SCEV *PositiveStrideSCEV =
929 LLVM_DEBUG(
dbgs() <<
" MemsetSizeSCEV: " << *MemsetSizeSCEV <<
"\n"
930 <<
" PositiveStrideSCEV: " << *PositiveStrideSCEV
933 if (PositiveStrideSCEV != MemsetSizeSCEV) {
936 const SCEV *FoldedPositiveStride =
938 const SCEV *FoldedMemsetSize =
942 <<
" FoldedMemsetSize: " << *FoldedMemsetSize <<
"\n"
943 <<
" FoldedPositiveStride: " << *FoldedPositiveStride
946 if (FoldedPositiveStride != FoldedMemsetSize) {
972 const SCEV *BECount,
const SCEV *StoreSizeSCEV,
982 const APInt *BECst, *ConstSize;
986 std::optional<uint64_t> SizeInt = ConstSize->
tryZExtValue();
988 if (BEInt && SizeInt)
1010 Type *IntPtr,
const SCEV *StoreSizeSCEV,
1013 if (!StoreSizeSCEV->
isOne()) {
1028 const SCEV *StoreSizeSCEV,
Loop *CurLoop,
1030 const SCEV *TripCountSCEV =
1039bool LoopIdiomRecognize::processLoopStridedStore(
1043 const SCEV *BECount,
bool IsNegStride,
bool IsLoopMemset) {
1055 Type *DestInt8PtrTy = Builder.getPtrTy(DestAS);
1066 if (!Expander.isSafeToExpand(Start))
1075 Expander.expandCodeFor(Start, DestInt8PtrTy, Preheader->
getTerminator());
1087 StoreSizeSCEV, *
AA, Stores))
1090 if (avoidLIRForMultiBlockLoop(
true, IsLoopMemset))
1102 std::optional<int64_t> BytesWritten;
1105 const SCEV *TripCountS =
1107 if (!Expander.isSafeToExpand(TripCountS))
1110 if (!ConstStoreSize)
1112 Value *TripCount = Expander.expandCodeFor(TripCountS, IntIdxTy,
1114 uint64_t PatternRepsPerTrip =
1115 (ConstStoreSize->
getValue()->getZExtValue() * 8) /
1116 DL->getTypeSizeInBits(PatternValue->
getType());
1121 PatternRepsPerTrip == 1
1123 : Builder.CreateMul(TripCount,
1125 PatternRepsPerTrip));
1131 const SCEV *NumBytesS =
1132 getNumBytes(BECount, IntIdxTy, StoreSizeSCEV, CurLoop,
DL, SE);
1136 if (!Expander.isSafeToExpand(NumBytesS))
1139 Expander.expandCodeFor(NumBytesS, IntIdxTy, Preheader->
getTerminator());
1141 BytesWritten = CI->getZExtValue();
1143 assert(MemsetArg &&
"MemsetArg should have been set");
1147 AATags = AATags.
merge(
Store->getAAMetadata());
1149 AATags = AATags.
extendTo(BytesWritten.value());
1155 NewCall = Builder.CreateMemSet(BasePtr, SplatValue, MemsetArg,
1162 NewCall = Builder.CreateIntrinsic(
1163 Intrinsic::experimental_memset_pattern,
1164 {DestInt8PtrTy, PatternValue->
getType(), IntIdxTy},
1165 {
BasePtr, PatternValue, MemsetArg,
1178 MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB(
1184 <<
" from store to: " << *Ev <<
" at: " << *TheStore
1190 R <<
"Transformed loop-strided store in "
1192 <<
" function into a call to "
1195 if (!Stores.empty())
1197 for (
auto *
I : Stores) {
1198 R <<
ore::NV(
"FromBlock",
I->getParent()->getName())
1206 for (
auto *
I : Stores) {
1208 MSSAU->removeMemoryAccess(
I,
true);
1212 MSSAU->getMemorySSA()->verifyMemorySSA();
1214 ExpCleaner.markResultUsed();
1221bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
StoreInst *
SI,
1222 const SCEV *BECount) {
1223 assert(
SI->isUnordered() &&
"Expected only non-volatile non-ordered stores.");
1225 Value *StorePtr =
SI->getPointerOperand();
1227 unsigned StoreSize =
DL->getTypeStoreSize(
SI->getValueOperand()->getType());
1240 return processLoopStoreOfLoopLoad(StorePtr, LoadPtr, StoreSizeSCEV,
1242 StoreEv, LoadEv, BECount);
1246class MemmoveVerifier {
1248 explicit MemmoveVerifier(
const Value &LoadBasePtr,
const Value &StoreBasePtr,
1249 const DataLayout &
DL)
1251 LoadBasePtr.stripPointerCasts(), LoadOff,
DL)),
1253 StoreBasePtr.stripPointerCasts(), StoreOff,
DL)),
1254 IsSameObject(BP1 == BP2) {}
1256 bool loadAndStoreMayFormMemmove(
unsigned StoreSize,
bool IsNegStride,
1257 const Instruction &TheLoad,
1258 bool IsMemCpy)
const {
1262 if ((!IsNegStride && LoadOff <= StoreOff) ||
1263 (IsNegStride && LoadOff >= StoreOff))
1269 DL.getTypeSizeInBits(TheLoad.
getType()).getFixedValue() / 8;
1270 if (BP1 != BP2 || LoadSize != int64_t(StoreSize))
1272 if ((!IsNegStride && LoadOff < StoreOff + int64_t(StoreSize)) ||
1273 (IsNegStride && LoadOff + LoadSize > StoreOff))
1280 const DataLayout &
DL;
1281 int64_t LoadOff = 0;
1282 int64_t StoreOff = 0;
1287 const bool IsSameObject;
1291bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
1321 assert(ConstStoreSize &&
"store size is expected to be a constant");
1324 bool IsNegStride = StoreSize == -Stride;
1337 Value *StoreBasePtr = Expander.expandCodeFor(
1338 StrStart, Builder.getPtrTy(StrAS), Preheader->
getTerminator());
1350 IgnoredInsts.
insert(TheStore);
1353 const StringRef InstRemark = IsMemCpy ?
"memcpy" :
"load and store";
1355 bool LoopAccessStore =
1357 StoreSizeSCEV, *
AA, IgnoredInsts);
1358 if (LoopAccessStore) {
1364 IgnoredInsts.
insert(TheLoad);
1366 BECount, StoreSizeSCEV, *
AA, IgnoredInsts)) {
1370 <<
ore::NV(
"Inst", InstRemark) <<
" in "
1372 <<
" function will not be hoisted: "
1373 <<
ore::NV(
"Reason",
"The loop may access store location");
1377 IgnoredInsts.
erase(TheLoad);
1390 Value *LoadBasePtr = Expander.expandCodeFor(LdStart, Builder.getPtrTy(LdAS),
1395 MemmoveVerifier
Verifier(*LoadBasePtr, *StoreBasePtr, *
DL);
1396 if (IsMemCpy && !
Verifier.IsSameObject)
1397 IgnoredInsts.
erase(TheStore);
1399 StoreSizeSCEV, *
AA, IgnoredInsts)) {
1402 <<
ore::NV(
"Inst", InstRemark) <<
" in "
1404 <<
" function will not be hoisted: "
1405 <<
ore::NV(
"Reason",
"The loop may access load location");
1411 bool UseMemMove = IsMemCpy ?
Verifier.IsSameObject : LoopAccessStore;
1420 assert((StoreAlign && LoadAlign) &&
1421 "Expect unordered load/store to have align.");
1422 if (*StoreAlign < StoreSize || *LoadAlign < StoreSize)
1429 if (StoreSize >
TTI->getAtomicMemIntrinsicMaxElementSize())
1434 if (!
Verifier.loadAndStoreMayFormMemmove(StoreSize, IsNegStride, *TheLoad,
1438 if (avoidLIRForMultiBlockLoop())
1443 const SCEV *NumBytesS =
1444 getNumBytes(BECount, IntIdxTy, StoreSizeSCEV, CurLoop,
DL, SE);
1447 Expander.expandCodeFor(NumBytesS, IntIdxTy, Preheader->
getTerminator());
1451 AATags = AATags.
merge(StoreAATags);
1453 AATags = AATags.
extendTo(CI->getZExtValue());
1463 NewCall = Builder.CreateMemMove(StoreBasePtr, StoreAlign, LoadBasePtr,
1464 LoadAlign, NumBytes,
1468 Builder.CreateMemCpy(StoreBasePtr, StoreAlign, LoadBasePtr, LoadAlign,
1469 NumBytes,
false, AATags);
1474 NewCall = Builder.CreateElementUnorderedAtomicMemCpy(
1475 StoreBasePtr, *StoreAlign, LoadBasePtr, *LoadAlign, NumBytes, StoreSize,
1481 MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB(
1487 <<
" from load ptr=" << *LoadEv <<
" at: " << *TheLoad
1489 <<
" from store ptr=" << *StoreEv <<
" at: " << *TheStore
1495 <<
"Formed a call to "
1497 <<
"() intrinsic from " <<
ore::NV(
"Inst", InstRemark)
1508 MSSAU->removeMemoryAccess(TheStore,
true);
1511 MSSAU->getMemorySSA()->verifyMemorySSA();
1516 ExpCleaner.markResultUsed();
1523bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(
bool IsMemset,
1524 bool IsLoopMemset) {
1525 if (ApplyCodeSizeHeuristics && CurLoop->
getNumBlocks() > 1) {
1526 if (CurLoop->
isOutermost() && (!IsMemset || !IsLoopMemset)) {
1528 <<
" : LIR " << (IsMemset ?
"Memset" :
"Memcpy")
1529 <<
" avoided: multi-block top-level loop\n");
1552 std::array<Constant *, 256> CRCConstants;
1554 CRCConstants.begin(),
1555 [CRCTy](
const APInt &
E) { return ConstantInt::get(CRCTy, E); });
1577 unsigned NewBTC = (
Info.TripCount / 8) - 1;
1584 Value *ExitLimit = ConstantInt::get(
IV->getType(), NewBTC);
1586 Value *NewExitCond =
1587 Builder.CreateICmp(ExitPred,
IV, ExitLimit,
"exit.cond");
1601 Type *OpTy =
Op->getType();
1604 ? Builder.
CreateAnd(
Op, ConstantInt::get(OpTy, 0XFF), Name)
1609 Type *OpTy =
Op->getType();
1613 return LoByte(Builder,
1614 CRCBW > 8 ? Builder.CreateLShr(
1615 Op, ConstantInt::get(OpTy, CRCBW - 8), Name)
1625 PHINode *CRCPhi = Builder.CreatePHI(CRCTy, 2,
"crc");
1629 Value *CRC = CRCPhi;
1633 Value *Indexer = CRC;
1641 Value *IVBits = Builder.CreateZExtOrTrunc(
1642 Builder.CreateShl(
IV, 3,
"iv.bits"), DataTy,
"iv.indexer");
1643 Value *DataIndexer =
1644 Info.ByteOrderSwapped
1645 ? Builder.CreateShl(
Data, IVBits,
"data.indexer")
1646 : Builder.CreateLShr(
Data, IVBits,
"data.indexer");
1647 Indexer = Builder.CreateXor(
1649 Builder.CreateZExtOrTrunc(Indexer, DataTy,
"crc.indexer.cast"),
1650 "crc.data.indexer");
1653 Indexer =
Info.ByteOrderSwapped ? HiIdx(Builder, Indexer,
"indexer.hi")
1654 : LoByte(Builder, Indexer,
"indexer.lo");
1657 Indexer = Builder.CreateZExt(
1662 Value *CRCTableGEP =
1663 Builder.CreateInBoundsGEP(CRCTy, GV, Indexer,
"tbl.ptradd");
1664 Value *CRCTableLd = Builder.CreateLoad(CRCTy, CRCTableGEP,
"tbl.ld");
1668 Value *CRCNext = CRCTableLd;
1671 ? Builder.CreateShl(CRC, 8,
"crc.be.shift")
1672 : Builder.CreateLShr(CRC, 8,
"crc.le.shift");
1673 CRCNext = Builder.CreateXor(CRCShift, CRCTableLd,
"crc.next");
1678 Info.ComputedValue->replaceUsesOutsideBlock(CRCNext,
1691bool LoopIdiomRecognize::runOnNoncountableLoop() {
1694 <<
"] Noncountable Loop %"
1697 return recognizePopcount() || recognizeAndInsertFFS() ||
1698 recognizeShiftUntilBitTest() || recognizeShiftUntilZero() ||
1699 recognizeShiftUntilLessThan() || recognizeAndInsertStrLen();
1709 bool JmpOnZero =
false) {
1718 if (!CmpZero || !CmpZero->isZero())
1729 return Cond->getOperand(0);
1736class StrlenVerifier {
1738 explicit StrlenVerifier(
const Loop *CurLoop, ScalarEvolution *SE,
1739 const TargetLibraryInfo *TLI)
1740 : CurLoop(CurLoop), SE(SE), TLI(TLI) {}
1742 bool isValidStrlenIdiom() {
1764 if (!LoopBody || LoopBody->
size() >= 15)
1783 const SCEV *LoadEv = SE->
getSCEV(IncPtr);
1796 if (OpWidth != StepSize * 8)
1798 if (OpWidth != 8 && OpWidth != 16 && OpWidth != 32)
1801 if (OpWidth != WcharSize * 8)
1805 for (Instruction &
I : *LoopBody)
1806 if (
I.mayHaveSideEffects())
1813 for (PHINode &PN : LoopExitBB->
phis()) {
1817 const SCEV *Ev = SE->
getSCEV(&PN);
1827 if (!AddRecEv || !AddRecEv->
isAffine())
1841 const Loop *CurLoop;
1842 ScalarEvolution *SE;
1843 const TargetLibraryInfo *TLI;
1846 ConstantInt *StepSizeCI;
1847 const SCEV *LoadBaseEv;
1912bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
1916 StrlenVerifier
Verifier(CurLoop, SE, TLI);
1918 if (!
Verifier.isValidStrlenIdiom())
1925 assert(Preheader && LoopBody && LoopExitBB && LoopTerm &&
1926 "Should be verified to be valid by StrlenVerifier");
1941 Builder.SetCurrentDebugLocation(CurLoop->
getStartLoc());
1944 Value *MaterialzedBase = Expander.expandCodeFor(
1946 Builder.GetInsertPoint());
1948 Value *StrLenFunc =
nullptr;
1950 StrLenFunc =
emitStrLen(MaterialzedBase, Builder, *
DL, TLI);
1952 StrLenFunc =
emitWcsLen(MaterialzedBase, Builder, *
DL, TLI);
1954 assert(StrLenFunc &&
"Failed to emit strlen function.");
1973 StrlenEv,
Base->getType())));
1975 Value *MaterializedPHI = Expander.expandCodeFor(NewEv, NewEv->
getType(),
1976 Builder.GetInsertPoint());
1992 "loop body must have a successor that is it self");
1994 ? Builder.getFalse()
1995 : Builder.getTrue();
2000 LLVM_DEBUG(
dbgs() <<
" Formed strlen idiom: " << *StrLenFunc <<
"\n");
2004 <<
"Transformed " << StrLenFunc->
getName() <<
" loop idiom";
2032 return Cond->getOperand(0);
2043 if (PhiX && PhiX->getParent() == LoopEntry &&
2044 (PhiX->getOperand(0) == DefX || PhiX->
getOperand(1) == DefX))
2110 if (DefX->
getOpcode() != Instruction::LShr)
2113 IntrinID = Intrinsic::ctlz;
2115 if (!Shft || !Shft->
isOne())
2129 if (Inst.
getOpcode() != Instruction::Add)
2181 Value *VarX1, *VarX0;
2184 DefX2 = CountInst =
nullptr;
2185 VarX1 = VarX0 =
nullptr;
2186 PhiX = CountPhi =
nullptr;
2200 if (!DefX2 || DefX2->
getOpcode() != Instruction::And)
2211 if (!SubOneOp || SubOneOp->
getOperand(0) != VarX1)
2217 (SubOneOp->
getOpcode() == Instruction::Add &&
2230 CountInst =
nullptr;
2233 if (Inst.
getOpcode() != Instruction::Add)
2237 if (!Inc || !Inc->
isOne())
2245 bool LiveOutLoop =
false;
2272 CntInst = CountInst;
2312 Value *VarX =
nullptr;
2327 if (!DefX || !DefX->
isShift())
2329 IntrinID = DefX->
getOpcode() == Instruction::Shl ? Intrinsic::cttz :
2332 if (!Shft || !Shft->
isOne())
2357 if (Inst.
getOpcode() != Instruction::Add)
2380bool LoopIdiomRecognize::isProfitableToInsertFFS(
Intrinsic::ID IntrinID,
2381 Value *InitX,
bool ZeroCheck,
2382 size_t CanonicalSize) {
2389 std::distance(InstWithoutDebugIt.begin(), InstWithoutDebugIt.end());
2403bool LoopIdiomRecognize::insertFFSIfProfitable(
Intrinsic::ID IntrinID,
2407 bool IsCntPhiUsedOutsideLoop =
false;
2410 IsCntPhiUsedOutsideLoop =
true;
2413 bool IsCntInstUsedOutsideLoop =
false;
2416 IsCntInstUsedOutsideLoop =
true;
2421 if (IsCntInstUsedOutsideLoop && IsCntPhiUsedOutsideLoop)
2427 bool ZeroCheck =
false;
2436 if (!IsCntPhiUsedOutsideLoop) {
2455 size_t IdiomCanonicalSize = 6;
2456 if (!isProfitableToInsertFFS(IntrinID, InitX, ZeroCheck, IdiomCanonicalSize))
2459 transformLoopToCountable(IntrinID, PH, CntInst, CntPhi, InitX, DefX,
2461 IsCntPhiUsedOutsideLoop);
2468bool LoopIdiomRecognize::recognizeAndInsertFFS() {
2483 return insertFFSIfProfitable(IntrinID, InitX, DefX, CntPhi, CntInst);
2486bool LoopIdiomRecognize::recognizeShiftUntilLessThan() {
2497 APInt LoopThreshold;
2499 CntPhi, DefX, LoopThreshold))
2502 if (LoopThreshold == 2) {
2504 return insertFFSIfProfitable(IntrinID, InitX, DefX, CntPhi, CntInst);
2508 if (LoopThreshold != 4)
2526 APInt PreLoopThreshold;
2528 PreLoopThreshold != 2)
2531 bool ZeroCheck =
true;
2540 size_t IdiomCanonicalSize = 6;
2541 if (!isProfitableToInsertFFS(IntrinID, InitX, ZeroCheck, IdiomCanonicalSize))
2545 transformLoopToCountable(IntrinID, PH, CntInst, CntPhi, InitX, DefX,
2556bool LoopIdiomRecognize::recognizePopcount() {
2570 if (LoopBody->
size() >= 20) {
2589 if (!PreCondBI || PreCondBI->isUnconditional())
2598 transformLoopToPopcount(PreCondBB, CntInst, CntPhi, Val);
2656void LoopIdiomRecognize::transformLoopToCountable(
2659 bool ZeroCheck,
bool IsCntPhiUsedOutsideLoop,
bool InsertSub) {
2664 Builder.SetCurrentDebugLocation(
DL);
2673 if (IsCntPhiUsedOutsideLoop) {
2674 if (DefX->
getOpcode() == Instruction::AShr)
2675 InitXNext = Builder.CreateAShr(InitX, 1);
2676 else if (DefX->
getOpcode() == Instruction::LShr)
2677 InitXNext = Builder.CreateLShr(InitX, 1);
2678 else if (DefX->
getOpcode() == Instruction::Shl)
2679 InitXNext = Builder.CreateShl(InitX, 1);
2687 Count = Builder.CreateSub(
2690 Count = Builder.CreateSub(
Count, ConstantInt::get(CountTy, 1));
2692 if (IsCntPhiUsedOutsideLoop)
2693 Count = Builder.CreateAdd(
Count, ConstantInt::get(CountTy, 1));
2695 NewCount = Builder.CreateZExtOrTrunc(NewCount, CntInst->
getType());
2702 if (!InitConst || !InitConst->
isZero())
2703 NewCount = Builder.CreateAdd(NewCount, CntInitVal);
2707 NewCount = Builder.CreateSub(CntInitVal, NewCount);
2725 Builder.SetInsertPoint(LbCond);
2727 TcPhi, ConstantInt::get(CountTy, 1),
"tcdec",
false,
true));
2736 LbCond->
setOperand(1, ConstantInt::get(CountTy, 0));
2740 if (IsCntPhiUsedOutsideLoop)
2750void LoopIdiomRecognize::transformLoopToPopcount(
BasicBlock *PreCondBB,
2763 Value *PopCnt, *PopCntZext, *NewCount, *TripCnt;
2766 NewCount = PopCntZext =
2769 if (NewCount != PopCnt)
2778 if (!InitConst || !InitConst->
isZero()) {
2779 NewCount = Builder.CreateAdd(NewCount, CntInitVal);
2791 Value *Opnd0 = PopCntZext;
2792 Value *Opnd1 = ConstantInt::get(PopCntZext->
getType(), 0);
2797 Builder.CreateICmp(PreCond->
getPredicate(), Opnd0, Opnd1));
2798 PreCondBr->setCondition(NewPreCond);
2832 Builder.SetInsertPoint(LbCond);
2834 Builder.CreateSub(TcPhi, ConstantInt::get(Ty, 1),
2835 "tcdec",
false,
true));
2844 LbCond->
setOperand(1, ConstantInt::get(Ty, 0));
2865 template <
typename ITy>
bool match(ITy *V)
const {
2866 return L->isLoopInvariant(V) &&
SubPattern.match(V);
2871template <
typename Ty>
2902 " Performing shift-until-bittest idiom detection.\n");
2912 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
2919 Value *CmpLHS, *CmpRHS;
2930 auto MatchVariableBitMask = [&]() {
2940 auto MatchDecomposableConstantBitMask = [&]() {
2942 CmpLHS, CmpRHS, Pred,
true,
2944 if (Res && Res->Mask.isPowerOf2()) {
2948 BitMask = ConstantInt::get(CurrX->
getType(), Res->Mask);
2949 BitPos = ConstantInt::get(CurrX->
getType(), Res->Mask.logBase2());
2955 if (!MatchVariableBitMask() && !MatchDecomposableConstantBitMask()) {
2962 if (!CurrXPN || CurrXPN->getParent() != LoopHeaderBB) {
2967 BaseX = CurrXPN->getIncomingValueForBlock(LoopPreheaderBB);
2972 "Expected BaseX to be available in the preheader!");
2983 "Should only get equality predicates here.");
2993 if (TrueBB != LoopHeaderBB) {
3052bool LoopIdiomRecognize::recognizeShiftUntilBitTest() {
3053 bool MadeChange =
false;
3055 Value *
X, *BitMask, *BitPos, *XCurr;
3060 " shift-until-bittest idiom detection failed.\n");
3070 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3073 assert(SuccessorBB &&
"There is only a single successor.");
3079 Type *Ty =
X->getType();
3093 " Intrinsic is too costly, not beneficial\n");
3096 if (
TTI->getArithmeticInstrCost(Instruction::Shl, Ty,
CostKind) >
3108 std::optional<BasicBlock::iterator> InsertPt = std::nullopt;
3110 InsertPt = BitPosI->getInsertionPointAfterDef();
3118 return U.getUser() != BitPosFrozen;
3120 BitPos = BitPosFrozen;
3126 BitPos->
getName() +
".lowbitmask");
3128 Builder.CreateOr(LowBitMask, BitMask, BitPos->
getName() +
".mask");
3129 Value *XMasked = Builder.CreateAnd(
X, Mask,
X->getName() +
".masked");
3130 CallInst *XMaskedNumLeadingZeros = Builder.CreateIntrinsic(
3131 IntrID, Ty, {XMasked, Builder.getTrue()},
3132 nullptr, XMasked->
getName() +
".numleadingzeros");
3133 Value *XMaskedNumActiveBits = Builder.CreateSub(
3135 XMasked->
getName() +
".numactivebits",
true,
3137 Value *XMaskedLeadingOnePos =
3139 XMasked->
getName() +
".leadingonepos",
false,
3142 Value *LoopBackedgeTakenCount = Builder.CreateSub(
3143 BitPos, XMaskedLeadingOnePos, CurLoop->
getName() +
".backedgetakencount",
3147 Value *LoopTripCount =
3148 Builder.CreateAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
3149 CurLoop->
getName() +
".tripcount",
true,
3156 Value *NewX = Builder.CreateShl(
X, LoopBackedgeTakenCount);
3159 I->copyIRFlags(XNext,
true);
3171 NewXNext = Builder.CreateShl(
X, LoopTripCount);
3176 NewXNext = Builder.CreateShl(NewX, ConstantInt::get(Ty, 1));
3181 I->copyIRFlags(XNext,
true);
3192 Builder.SetInsertPoint(LoopHeaderBB, LoopHeaderBB->
begin());
3193 auto *
IV = Builder.CreatePHI(Ty, 2, CurLoop->
getName() +
".iv");
3199 Builder.CreateAdd(
IV, ConstantInt::get(Ty, 1),
IV->getName() +
".next",
3200 true, Bitwidth != 2);
3203 auto *IVCheck = Builder.CreateICmpEQ(IVNext, LoopTripCount,
3204 CurLoop->
getName() +
".ivcheck");
3205 Builder.CreateCondBr(IVCheck, SuccessorBB, LoopHeaderBB);
3209 IV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
3210 IV->addIncoming(IVNext, LoopHeaderBB);
3221 ++NumShiftUntilBitTest;
3257 const SCEV *&ExtraOffsetExpr,
3258 bool &InvertedCond) {
3260 " Performing shift-until-zero idiom detection.\n");
3273 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3284 !
match(ValShiftedIsZero,
3298 IntrinID = ValShifted->
getOpcode() == Instruction::Shl ? Intrinsic::cttz
3307 else if (
match(NBits,
3311 ExtraOffsetExpr = SE->
getSCEV(ExtraOffset);
3319 if (!IVPN || IVPN->getParent() != LoopHeaderBB) {
3324 Start = IVPN->getIncomingValueForBlock(LoopPreheaderBB);
3335 "Should only get equality predicates here.");
3346 if (FalseBB != LoopHeaderBB) {
3357 if (ValShifted->
getOpcode() == Instruction::AShr &&
3421bool LoopIdiomRecognize::recognizeShiftUntilZero() {
3422 bool MadeChange =
false;
3428 const SCEV *ExtraOffsetExpr;
3431 Start, Val, ExtraOffsetExpr, InvertedCond)) {
3433 " shift-until-zero idiom detection failed.\n");
3443 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3446 assert(SuccessorBB &&
"There is only a single successor.");
3449 Builder.SetCurrentDebugLocation(
IV->getDebugLoc());
3465 " Intrinsic is too costly, not beneficial\n");
3472 bool OffsetIsZero = ExtraOffsetExpr->
isZero();
3476 CallInst *ValNumLeadingZeros = Builder.CreateIntrinsic(
3477 IntrID, Ty, {Val, Builder.getFalse()},
3478 nullptr, Val->
getName() +
".numleadingzeros");
3479 Value *ValNumActiveBits = Builder.CreateSub(
3481 Val->
getName() +
".numactivebits",
true,
3485 Expander.setInsertPoint(&*Builder.GetInsertPoint());
3486 Value *ExtraOffset = Expander.expandCodeFor(ExtraOffsetExpr);
3488 Value *ValNumActiveBitsOffset = Builder.CreateAdd(
3489 ValNumActiveBits, ExtraOffset, ValNumActiveBits->
getName() +
".offset",
3490 OffsetIsZero,
true);
3491 Value *IVFinal = Builder.CreateIntrinsic(Intrinsic::smax, {Ty},
3492 {ValNumActiveBitsOffset,
Start},
3493 nullptr,
"iv.final");
3496 IVFinal, Start, CurLoop->
getName() +
".backedgetakencount",
3497 OffsetIsZero,
true));
3501 Value *LoopTripCount =
3502 Builder.CreateAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
3503 CurLoop->
getName() +
".tripcount",
true,
3509 IV->replaceUsesOutsideBlock(IVFinal, LoopHeaderBB);
3514 Builder.SetInsertPoint(LoopHeaderBB, LoopHeaderBB->
begin());
3515 auto *CIV = Builder.CreatePHI(Ty, 2, CurLoop->
getName() +
".iv");
3520 Builder.CreateAdd(CIV, ConstantInt::get(Ty, 1), CIV->getName() +
".next",
3521 true, Bitwidth != 2);
3524 auto *CIVCheck = Builder.CreateICmpEQ(CIVNext, LoopTripCount,
3525 CurLoop->
getName() +
".ivcheck");
3526 auto *NewIVCheck = CIVCheck;
3528 NewIVCheck = Builder.CreateNot(CIVCheck);
3529 NewIVCheck->takeName(ValShiftedIsZero);
3533 auto *IVDePHId = Builder.CreateAdd(CIV, Start,
"",
false,
3535 IVDePHId->takeName(
IV);
3539 Builder.CreateCondBr(CIVCheck, SuccessorBB, LoopHeaderBB);
3543 CIV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
3544 CIV->addIncoming(CIVNext, LoopHeaderBB);
3552 IV->replaceAllUsesWith(IVDePHId);
3553 IV->eraseFromParent();
3562 ++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")
Analysis containing CSE Info
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.
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,...
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
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, 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)
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 TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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 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.
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 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...
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 CRCTable genSarwateTable(const APInt &GenPoly, bool ByteOrderSwapped)
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.
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.
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
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.
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.
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.
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.
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.
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 * 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.
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.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
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.
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.
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.
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::Argument NV
DiagnosticInfoOptimizationBase::setExtraArgs setExtraArgs
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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...
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
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.
FunctionAddr VTableAddr Count
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.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
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.
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.
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...
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....
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.
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 HashRecognize
When true, HashRecognize 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.
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)