100#define DEBUG_TYPE "loop-idiom"
102STATISTIC(NumMemSet,
"Number of memset's formed from loop stores");
103STATISTIC(NumMemCpy,
"Number of memcpy's formed from loop load+stores");
104STATISTIC(NumMemMove,
"Number of memmove's formed from loop load+stores");
105STATISTIC(NumStrLen,
"Number of strlen's and wcslen's formed from loop loads");
107 NumShiftUntilBitTest,
108 "Number of uncountable loops recognized as 'shift until bitttest' idiom");
110 "Number of uncountable loops recognized as 'shift until zero' idiom");
116 cl::desc(
"Options to disable Loop Idiom Recognize Pass."),
123 cl::desc(
"Proceed with loop idiom recognize pass, but do "
124 "not convert loop(s) to memset."),
131 cl::desc(
"Proceed with loop idiom recognize pass, but do "
132 "not convert loop(s) to memcpy."),
139 cl::desc(
"Proceed with loop idiom recognize pass, but do "
140 "not convert loop(s) to strlen."),
147 cl::desc(
"Proceed with loop idiom recognize pass, "
148 "enable conversion of loop(s) to wcslen."),
155 cl::desc(
"Proceed with loop idiom recognize pass, "
156 "but do not do hash-recognize analysis."),
164class LoopIdiomRecognize {
165 const ScalarOptions &Opts;
166 Loop *CurLoop =
nullptr;
175 bool ApplyCodeSizeHeuristics;
176 std::unique_ptr<MemorySSAUpdater> MSSAU;
179 explicit LoopIdiomRecognize(
const ScalarOptions &Opts,
AliasAnalysis *
AA,
188 MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
191 bool runOnLoop(
Loop *L);
194 using StoreList = SmallVector<StoreInst *, 8>;
195 using StoreListMap = MapVector<Value *, StoreList>;
197 StoreListMap StoreRefsForMemset;
198 StoreListMap StoreRefsForMemsetPattern;
199 StoreList StoreRefsForMemcpy;
201 bool HasMemsetPattern;
205 enum LegalStoreKind {
210 UnorderedAtomicMemcpy,
218 bool runOnCountableLoop();
219 bool runOnLoopBlock(BasicBlock *BB,
const SCEV *BECount,
220 SmallVectorImpl<BasicBlock *> &ExitBlocks);
222 void collectStores(BasicBlock *BB);
223 LegalStoreKind isLegalStore(StoreInst *SI);
224 enum class ForMemset {
No,
Yes };
225 bool processLoopStores(SmallVectorImpl<StoreInst *> &SL,
const SCEV *BECount,
228 template <
typename MemInst>
229 bool processLoopMemIntrinsic(
231 bool (LoopIdiomRecognize::*Processor)(MemInst *,
const SCEV *),
232 const SCEV *BECount);
233 bool processLoopMemCpy(MemCpyInst *MCI,
const SCEV *BECount);
234 bool processLoopMemSet(MemSetInst *MSI,
const SCEV *BECount);
236 bool processLoopStridedStore(
Value *DestPtr,
const SCEV *StoreSizeSCEV,
237 MaybeAlign StoreAlignment,
Value *StoredVal,
238 Instruction *TheStore,
239 SmallPtrSetImpl<Instruction *> &Stores,
240 const SCEVAddRecExpr *Ev,
const SCEV *BECount,
241 bool IsNegStride,
bool IsLoopMemset =
false);
242 bool processLoopStoreOfLoopLoad(StoreInst *SI,
const SCEV *BECount);
243 bool processLoopStoreOfLoopLoad(
Value *DestPtr,
Value *SourcePtr,
244 const SCEV *StoreSize, MaybeAlign StoreAlign,
245 MaybeAlign LoadAlign, Instruction *TheStore,
246 Instruction *TheLoad,
247 const SCEVAddRecExpr *StoreEv,
248 const SCEVAddRecExpr *LoadEv,
249 const SCEV *BECount);
250 bool avoidLIRForMultiBlockLoop(
bool IsMemset =
false,
251 bool IsLoopMemset =
false);
252 bool optimizeCRCLoop(
const PolynomialInfo &Info);
253 void optimizeCRCLoopUsingClmul(
const PolynomialInfo &Info);
254 void optimizeCRCLoopUsingTableLookup(
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();
301 LoopIdiomRecognize LIR(Opts, &AR.
AA, &AR.
DT, &AR.
LI, &AR.
SE, &AR.
TLI, &AR.
TTI,
303 if (!LIR.runOnLoop(&L))
314 I->eraseFromParent();
323bool LoopIdiomRecognize::runOnLoop(
Loop *L) {
327 if (!
L->getLoopPreheader())
332 if (Name ==
"memset" || Name ==
"memcpy" || Name ==
"strlen" ||
337 ApplyCodeSizeHeuristics =
338 L->getHeader()->getParent()->hasOptSize() && Opts.use_lir_code_size_heurs;
340 HasMemset =
TLI->has(LibFunc_memset);
346 HasMemsetPattern =
TLI->has(LibFunc_memset_pattern16);
347 HasMemcpy =
TLI->has(LibFunc_memcpy);
349 if (HasMemset || HasMemsetPattern ||
350 Opts.loop_idiom_force_memset_pattern_intrinsic || HasMemcpy ||
353 return runOnCountableLoop();
355 return runOnNoncountableLoop();
358bool LoopIdiomRecognize::runOnCountableLoop() {
361 "runOnCountableLoop() called on a loop without a predictable"
362 "backedge-taken count");
380 if (SafetyInfo.anyBlockMayThrow())
383 bool MadeChange =
false;
391 MadeChange |= runOnLoopBlock(BB, BECount, ExitBlocks);
398 MadeChange |= optimizeCRCLoop(*Res);
430 if (
DL->isBigEndian())
442 Type *CTy =
C->getType();
449LoopIdiomRecognize::LegalStoreKind
452 if (
SI->isVolatile())
453 return LegalStoreKind::None;
455 if (!
SI->isUnordered())
456 return LegalStoreKind::None;
459 if (
SI->getMetadata(LLVMContext::MD_nontemporal))
460 return LegalStoreKind::None;
462 Value *StoredVal =
SI->getValueOperand();
463 Value *StorePtr =
SI->getPointerOperand();
465 if (
DL->hasUnstableRepresentation(StoredVal->
getType()))
466 return LegalStoreKind::None;
475 bool MustPreserveExternalState =
DL->hasExternalState(StoredVal->
getType()) &&
484 return LegalStoreKind::None;
493 return LegalStoreKind::None;
504 bool UnorderedAtomic =
SI->isUnordered() && !
SI->isSimple();
508 if (!MustPreserveExternalState && !UnorderedAtomic && HasMemset &&
514 return LegalStoreKind::Memset;
516 if (!MustPreserveExternalState && !UnorderedAtomic &&
517 (HasMemsetPattern || Opts.loop_idiom_force_memset_pattern_intrinsic) &&
523 return LegalStoreKind::MemsetPattern;
530 unsigned StoreSize =
DL->getTypeStoreSize(
SI->getValueOperand()->getType());
532 if (StoreSize != StrideAP && StoreSize != -StrideAP)
533 return LegalStoreKind::None;
540 return LegalStoreKind::None;
543 return LegalStoreKind::None;
553 return LegalStoreKind::None;
556 UnorderedAtomic = UnorderedAtomic || LI->
isAtomic();
557 return UnorderedAtomic ? LegalStoreKind::UnorderedAtomicMemcpy
558 : LegalStoreKind::Memcpy;
561 return LegalStoreKind::None;
564void LoopIdiomRecognize::collectStores(
BasicBlock *BB) {
565 StoreRefsForMemset.clear();
566 StoreRefsForMemsetPattern.clear();
567 StoreRefsForMemcpy.clear();
574 switch (isLegalStore(
SI)) {
575 case LegalStoreKind::None:
578 case LegalStoreKind::Memset: {
581 StoreRefsForMemset[Ptr].push_back(
SI);
583 case LegalStoreKind::MemsetPattern: {
586 StoreRefsForMemsetPattern[Ptr].push_back(
SI);
588 case LegalStoreKind::Memcpy:
589 case LegalStoreKind::UnorderedAtomicMemcpy:
590 StoreRefsForMemcpy.push_back(
SI);
593 assert(
false &&
"unhandled return value");
602bool LoopIdiomRecognize::runOnLoopBlock(
612 bool MadeChange =
false;
619 for (
auto &SL : StoreRefsForMemset)
620 MadeChange |= processLoopStores(SL.second, BECount, ForMemset::Yes);
622 for (
auto &SL : StoreRefsForMemsetPattern)
623 MadeChange |= processLoopStores(SL.second, BECount, ForMemset::No);
626 for (
auto &
SI : StoreRefsForMemcpy)
627 MadeChange |= processLoopStoreOfLoopLoad(
SI, BECount);
629 MadeChange |= processLoopMemIntrinsic<MemCpyInst>(
630 BB, &LoopIdiomRecognize::processLoopMemCpy, BECount);
631 MadeChange |= processLoopMemIntrinsic<MemSetInst>(
632 BB, &LoopIdiomRecognize::processLoopMemSet, BECount);
639 const SCEV *BECount, ForMemset For) {
647 for (
unsigned i = 0, e = SL.
size(); i < e; ++i) {
648 assert(SL[i]->
isSimple() &&
"Expected only non-volatile stores.");
650 Value *FirstStoredVal = SL[i]->getValueOperand();
651 Value *FirstStorePtr = SL[i]->getPointerOperand();
655 unsigned FirstStoreSize =
DL->getTypeStoreSize(SL[i]->getValueOperand()->
getType());
658 if (FirstStride == FirstStoreSize || -FirstStride == FirstStoreSize) {
663 Value *FirstSplatValue =
nullptr;
664 Constant *FirstPatternValue =
nullptr;
666 if (For == ForMemset::Yes) {
676 assert((FirstSplatValue || FirstPatternValue) &&
677 "Expected either splat value or pattern value.");
685 for (j = i + 1;
j <
e; ++
j)
687 for (j = i;
j > 0; --
j)
690 for (
auto &k : IndexQueue) {
691 assert(SL[k]->
isSimple() &&
"Expected only non-volatile stores.");
692 Value *SecondStorePtr = SL[
k]->getPointerOperand();
697 if (FirstStride != SecondStride)
700 Value *SecondStoredVal = SL[
k]->getValueOperand();
701 Value *SecondSplatValue =
nullptr;
702 Constant *SecondPatternValue =
nullptr;
704 if (For == ForMemset::Yes)
709 assert((SecondSplatValue || SecondPatternValue) &&
710 "Expected either splat value or pattern value.");
713 if (For == ForMemset::Yes) {
714 if (FirstSplatValue != SecondSplatValue)
717 if (FirstPatternValue != SecondPatternValue)
722 ConsecutiveChain[SL[i]] = SL[
k];
742 unsigned StoreSize = 0;
745 while (Tails.
count(
I) || Heads.count(
I)) {
746 if (TransformedStores.
count(
I))
750 StoreSize +=
DL->getTypeStoreSize(
I->getValueOperand()->getType());
752 I = ConsecutiveChain[
I];
762 if (StoreSize != Stride && StoreSize != -Stride)
765 bool IsNegStride = StoreSize == -Stride;
769 if (processLoopStridedStore(StorePtr, StoreSizeSCEV,
771 HeadStore, AdjacentStores, StoreEv, BECount,
783template <
typename MemInst>
784bool LoopIdiomRecognize::processLoopMemIntrinsic(
786 bool (LoopIdiomRecognize::*Processor)(MemInst *,
const SCEV *),
787 const SCEV *BECount) {
788 bool MadeChange =
false;
794 if (!(this->*Processor)(
MI, BECount))
808bool LoopIdiomRecognize::processLoopMemCpy(
MemCpyInst *MCI,
809 const SCEV *BECount) {
822 if (!Dest || !Source)
830 const APInt *StoreStrideValue, *LoadStrideValue;
841 if ((SizeInBytes >> 32) != 0)
849 if (SizeInBytes != *StoreStrideValue && SizeInBytes != -*StoreStrideValue) {
852 <<
ore::NV(
"Inst",
"memcpy") <<
" in "
854 <<
" function will not be hoisted: "
855 <<
ore::NV(
"Reason",
"memcpy size is not equal to stride");
860 int64_t StoreStrideInt = StoreStrideValue->
getSExtValue();
861 int64_t LoadStrideInt = LoadStrideValue->
getSExtValue();
863 if (StoreStrideInt != LoadStrideInt)
866 return processLoopStoreOfLoopLoad(
873bool LoopIdiomRecognize::processLoopMemSet(
MemSetInst *MSI,
874 const SCEV *BECount) {
890 const SCEV *PointerStrideSCEV;
899 bool IsNegStride =
false;
902 if (IsConstantSize) {
912 if (SizeInBytes != *Stride && SizeInBytes != -*Stride)
915 IsNegStride = SizeInBytes == -*Stride;
923 if (
Pointer->getType()->getPointerAddressSpace() != 0) {
939 LLVM_DEBUG(
dbgs() <<
" MemsetSizeSCEV: " << *MemsetSizeSCEV <<
"\n"
940 <<
" PositiveStrideSCEV: " << *PositiveStrideSCEV
943 if (PositiveStrideSCEV != MemsetSizeSCEV) {
946 const SCEV *FoldedPositiveStride =
948 const SCEV *FoldedMemsetSize =
952 <<
" FoldedMemsetSize: " << *FoldedMemsetSize <<
"\n"
953 <<
" FoldedPositiveStride: " << *FoldedPositiveStride
956 if (FoldedPositiveStride != FoldedMemsetSize) {
981 assert(SplatByte &&
"expected a bytewise splat value to match against");
983 if (!
SI || !
SI->isSimple() || !L->isLoopInvariant(
SI->getValueOperand()))
998 Value *SplatByte =
nullptr,
1007 const APInt *BECst, *ConstSize;
1011 std::optional<uint64_t> SizeInt = ConstSize->
tryZExtValue();
1013 if (BEInt && SizeInt)
1025 bool TrySameByteValue = !AccessSize.
isPrecise() && SplatByte &&
DL;
1042 Type *IntPtr,
const SCEV *StoreSizeSCEV,
1045 if (!StoreSizeSCEV->
isOne()) {
1060 const SCEV *StoreSizeSCEV,
Loop *CurLoop,
1062 const SCEV *TripCountSCEV =
1078 LenUse = &MSP->getLengthUse();
1080 LenUse = &
MI->getLengthUse();
1089 constexpr uint64_t MaxBoundedLen = 1 << 16;
1091 if (ElemsPerIter > MaxBoundedLen)
1093 const APInt *MaxBTC;
1096 if (MaxBTC->
uge(MaxBoundedLen))
1102 if (MaxLen > MaxBoundedLen)
1113 LenUse->getOperandNo(),
1120bool LoopIdiomRecognize::processLoopStridedStore(
1124 const SCEV *BECount,
bool IsNegStride,
bool IsLoopMemset) {
1130 "inline mem intrinsics should be filtered out by callers");
1143 Type *DestInt8PtrTy = Builder.getPtrTy(DestAS);
1154 if (!Expander.isSafeToExpand(Start))
1163 Expander.expandCodeFor(Start, DestInt8PtrTy, Preheader->
getTerminator());
1176 StoreSizeSCEV, *
AA, Stores, SplatValue,
DL))
1179 if (avoidLIRForMultiBlockLoop(
true, IsLoopMemset))
1190 std::optional<int64_t> BytesWritten;
1194 (HasMemsetPattern || Opts.loop_idiom_force_memset_pattern_intrinsic)) {
1195 const SCEV *TripCountS =
1197 if (!Expander.isSafeToExpand(TripCountS))
1200 if (!ConstStoreSize)
1202 Value *TripCount = Expander.expandCodeFor(TripCountS, IntIdxTy,
1204 PatternRepsPerTrip = (ConstStoreSize->
getValue()->getZExtValue() * 8) /
1205 DL->getTypeSizeInBits(PatternValue->
getType());
1210 PatternRepsPerTrip == 1
1212 : Builder.CreateMul(TripCount,
1214 PatternRepsPerTrip));
1220 const SCEV *NumBytesS =
1221 getNumBytes(BECount, IntIdxTy, StoreSizeSCEV, CurLoop,
DL, SE);
1225 if (!Expander.isSafeToExpand(NumBytesS))
1228 Expander.expandCodeFor(NumBytesS, IntIdxTy, Preheader->
getTerminator());
1230 BytesWritten = CI->getZExtValue();
1232 assert(MemsetArg &&
"MemsetArg should have been set");
1236 AATags = AATags.
merge(
Store->getAAMetadata());
1238 AATags = AATags.
extendTo(BytesWritten.value());
1244 NewCall = Builder.CreateMemSet(BasePtr, SplatValue, MemsetArg,
1251 }
else if (Opts.loop_idiom_force_memset_pattern_intrinsic ||
1255 NewCall = Builder.CreateIntrinsicWithoutFolding(
1256 Intrinsic::experimental_memset_pattern,
1257 {DestInt8PtrTy, PatternValue->
getType(), IntIdxTy},
1258 {
BasePtr, PatternValue, MemsetArg,
1263 assert(PatternRepsPerTrip != 0 &&
"PatternRepsPerTrip must be set");
1273 MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB(
1279 <<
" from store to: " << *Ev <<
" at: " << *TheStore
1285 R <<
"Transformed loop-strided store in "
1287 <<
" function into a call to "
1290 if (!Stores.empty())
1292 for (
auto *
I : Stores) {
1293 R <<
ore::NV(
"FromBlock",
I->getParent()->getName())
1301 for (
auto *
I : Stores) {
1303 MSSAU->removeMemoryAccess(
I,
true);
1307 MSSAU->getMemorySSA()->verifyMemorySSA();
1309 ExpCleaner.markResultUsed();
1316bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
StoreInst *
SI,
1317 const SCEV *BECount) {
1318 assert(
SI->isUnordered() &&
"Expected only non-volatile non-ordered stores.");
1320 Value *StorePtr =
SI->getPointerOperand();
1322 unsigned StoreSize =
DL->getTypeStoreSize(
SI->getValueOperand()->getType());
1335 return processLoopStoreOfLoopLoad(StorePtr, LoadPtr, StoreSizeSCEV,
1337 StoreEv, LoadEv, BECount);
1341class MemmoveVerifier {
1343 explicit MemmoveVerifier(
const SCEV &LoadStart,
const SCEV &StoreStart,
1344 ScalarEvolution &SE)
1345 :
DL(SE.getDataLayout()),
1346 Off(
dyn_cast<SCEVConstant>(SE.getMinusSCEV(&StoreStart, &LoadStart))),
1348 IsSameObject(
Off != nullptr) {}
1350 bool loadAndStoreMayFormMemmove(
unsigned StoreSize,
bool IsNegStride,
1351 const Instruction &TheLoad,
1352 bool IsMemCpy)
const {
1355 if (!
Off || !BasePtr)
1357 const APInt &OffVal =
Off->getAPInt();
1362 NullBase->getPointerType()->getPointerAddressSpace()))
1369 LoadSize =
DL.getTypeSizeInBits(TheLoad.
getType()).getFixedValue() / 8;
1370 if (LoadSize != StoreSize)
1375 if (IsNegStride ? OffVal.
slt(LoadSize) : OffVal.
sgt(-LoadSize))
1381 const DataLayout &
DL;
1382 const SCEVConstant *
Off;
1386 const bool IsSameObject;
1390bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
1400 "inline mem intrinsics should be filtered out by callers");
1420 assert(ConstStoreSize &&
"store size is expected to be a constant");
1423 bool IsNegStride = StoreSize == -Stride;
1436 Value *StoreBasePtr = Expander.expandCodeFor(
1437 StrStart, Builder.getPtrTy(StrAS), Preheader->
getTerminator());
1449 IgnoredInsts.
insert(TheStore);
1452 const StringRef InstRemark = IsMemCpy ?
"memcpy" :
"load and store";
1454 bool LoopAccessStore =
1456 StoreSizeSCEV, *
AA, IgnoredInsts);
1457 if (LoopAccessStore) {
1463 IgnoredInsts.
insert(TheLoad);
1465 BECount, StoreSizeSCEV, *
AA, IgnoredInsts)) {
1469 <<
ore::NV(
"Inst", InstRemark) <<
" in "
1471 <<
" function will not be hoisted: "
1472 <<
ore::NV(
"Reason",
"The loop may access store location");
1476 IgnoredInsts.
erase(TheLoad);
1489 Value *LoadBasePtr = Expander.expandCodeFor(LdStart, Builder.getPtrTy(LdAS),
1494 MemmoveVerifier
Verifier(*LdStart, *StrStart, *SE);
1495 if (IsMemCpy && !
Verifier.IsSameObject)
1496 IgnoredInsts.
erase(TheStore);
1498 StoreSizeSCEV, *
AA, IgnoredInsts)) {
1501 <<
ore::NV(
"Inst", InstRemark) <<
" in "
1503 <<
" function will not be hoisted: "
1504 <<
ore::NV(
"Reason",
"The loop may access load location");
1510 bool UseMemMove = IsMemCpy ?
Verifier.IsSameObject : LoopAccessStore;
1519 assert((StoreAlign && LoadAlign) &&
1520 "Expect unordered load/store to have align.");
1521 if (*StoreAlign < StoreSize || *LoadAlign < StoreSize)
1528 if (StoreSize >
TTI->getAtomicMemIntrinsicMaxElementSize())
1533 if (!
Verifier.loadAndStoreMayFormMemmove(StoreSize, IsNegStride, *TheLoad,
1537 if (avoidLIRForMultiBlockLoop())
1542 const SCEV *NumBytesS =
1543 getNumBytes(BECount, IntIdxTy, StoreSizeSCEV, CurLoop,
DL, SE);
1546 Expander.expandCodeFor(NumBytesS, IntIdxTy, Preheader->
getTerminator());
1550 AATags = AATags.
merge(StoreAATags);
1552 AATags = AATags.
extendTo(CI->getZExtValue());
1562 NewCall = Builder.CreateMemMove(StoreBasePtr, StoreAlign, LoadBasePtr,
1563 LoadAlign, NumBytes,
1567 Builder.CreateMemCpy(StoreBasePtr, StoreAlign, LoadBasePtr, LoadAlign,
1568 NumBytes,
false, AATags);
1573 NewCall = Builder.CreateElementUnorderedAtomicMemCpy(
1574 StoreBasePtr, *StoreAlign, LoadBasePtr, *LoadAlign, NumBytes, StoreSize,
1581 MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB(
1587 <<
" from load ptr=" << *LoadEv <<
" at: " << *TheLoad
1589 <<
" from store ptr=" << *StoreEv <<
" at: " << *TheStore
1595 <<
"Formed a call to "
1597 <<
"() intrinsic from " <<
ore::NV(
"Inst", InstRemark)
1608 MSSAU->removeMemoryAccess(TheStore,
true);
1611 MSSAU->getMemorySSA()->verifyMemorySSA();
1616 ExpCleaner.markResultUsed();
1623bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(
bool IsMemset,
1624 bool IsLoopMemset) {
1625 if (ApplyCodeSizeHeuristics && CurLoop->
getNumBlocks() > 1) {
1626 if (CurLoop->
isOutermost() && (!IsMemset || !IsLoopMemset)) {
1628 <<
" : LIR " << (IsMemset ?
"Memset" :
"Memcpy")
1629 <<
" avoided: multi-block top-level loop\n");
1637bool LoopIdiomRecognize::optimizeCRCLoop(
const PolynomialInfo &Info) {
1657 TTI->getArithmeticInstrCost(Instruction::Xor, CRCTy, CostKind);
1659 TTI->getArithmeticInstrCost(Instruction::LShr, CRCTy, CostKind);
1661 TTI->getArithmeticInstrCost(Instruction::And, CRCTy, CostKind);
1666 TTI->getMemoryOpCost(Instruction::Load, CRCTy,
DL->getABITypeAlign(CRCTy),
1667 DL->getDefaultGlobalsAddressSpace(), CostKind);
1668 auto ClmulCost = [&](
unsigned BW) {
1671 return TTI->getIntrinsicInstrCost(Attrs, CostKind);
1676 (2 * ShiftCost + 2 * XorCost + AndCost + SelectCost) *
Info.TripCount;
1681 Info.TripCount % 8 != 0
1683 : (LoadCost + XorCost + 2 * ShiftCost) * (
Info.TripCount / 8);
1687 ClmulCost(CRCBW +
Info.TripCount) +
1688 2 * XorCost + 2 * ShiftCost + AndCost;
1694 <<
"CRC loop costs: original="
1695 <<
ore::NV(
"OrigLoopCost", OrigLoopCost)
1696 <<
", table=" <<
ore::NV(
"TableStrategyCost", TableStrategyCost)
1697 <<
", clmul=" <<
ore::NV(
"ClmulStrategyCost", ClmulStrategyCost);
1700 auto ReportMissed = [&](
StringRef Reason) {
1705 <<
"CRC loop not optimized: " << Reason;
1712 <<
"CRC loop optimized using " <<
ore::NV(
"Strategy", Strategy)
1717 switch (Opts.loop_idiom_crc_strategy) {
1719 ReportMissed(
"disabled by user");
1724 if (
Info.TripCount % 8 == 0) {
1725 optimizeCRCLoopUsingTableLookup(Info);
1726 ReportOptimized(
"table",
"forced by user");
1729 ReportMissed(
"table strategy forced, but not possible");
1732 optimizeCRCLoopUsingClmul(Info);
1733 ReportOptimized(
"clmul",
"forced by user");
1741 if (ApplyCodeSizeHeuristics) {
1742 ReportMissed(
"optimizing for size");
1747 if (std::min(TableStrategyCost, ClmulStrategyCost) >= OrigLoopCost) {
1748 ReportMissed(
"no profitable strategy");
1752 if (TableStrategyCost <= ClmulStrategyCost) {
1753 optimizeCRCLoopUsingTableLookup(Info);
1754 ReportOptimized(
"table",
"most profitable strategy");
1756 optimizeCRCLoopUsingClmul(Info);
1757 ReportOptimized(
"clmul",
"most profitable strategy");
1766void LoopIdiomRecognize::optimizeCRCLoopUsingClmul(
const PolynomialInfo &Info) {
1775 unsigned TC =
Info.TripCount;
1786 ConstantInt::get(Ctx, Mu.zextOrTrunc(ClmulMuTy->
getBitWidth()));
1787 Value *GenPolyConst =
1788 ConstantInt::get(Ctx, FullGenPoly.zext(ClmulGPTy->
getBitWidth()));
1795 bool SetupShiftNeeded =
Info.IsBigEndian && TC != CRCBW;
1811 Value *ClmulMuInput =
1812 Builder.CreateZExtOrTrunc(
Info.LHS, SetupTy,
"crc.cast");
1818 Data = Builder.CreateZExtOrTrunc(
Data, SetupTy,
"data.cast");
1820 ClmulMuInput = Builder.CreateXor(ClmulMuInput,
Data,
"xor.crc.data");
1824 if (SetupShiftNeeded) {
1827 ? Builder.CreateShl(ClmulMuInput, TC - CRCBW,
"crc.align.tc")
1828 : Builder.CreateLShr(ClmulMuInput, CRCBW - TC,
"crc.align.tc");
1833 if (SetupTy->getBitWidth() > TC) {
1836 ClmulMuInput = Builder.CreateAnd(ClmulMuInput, Mask,
"crc.tcbits");
1842 Builder.CreateZExtOrTrunc(ClmulMuInput, ClmulMuTy,
"tcbits.cast");
1843 Value *ClmulMu = Builder.CreateBinaryIntrinsic(
1844 Intrinsic::clmul, ClmulMuInput, MuConst, {},
"clmul.mu");
1847 Value *ClmulGPInput =
1848 Info.IsBigEndian ? Builder.CreateLShr(ClmulMu, TC,
"quot.lshr") : ClmulMu;
1853 Builder.CreateZExtOrTrunc(ClmulGPInput, ClmulGPTy,
"quot.cast");
1854 Value *ClmulGP = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, ClmulGPInput,
1861 Value *CRCNext = Builder.CreateZExt(
Info.LHS, ClmulGPTy,
"crc.recast");
1862 if (
Info.IsBigEndian)
1863 CRCNext = Builder.CreateShl(CRCNext, TC,
"crc.shl");
1866 CRCNext = Builder.CreateXor(CRCNext, ClmulGP,
"xor.crc.mult");
1867 if (!
Info.IsBigEndian)
1868 CRCNext = Builder.CreateLShr(CRCNext, TC,
"crc.lshr");
1871 CRCNext = Builder.CreateTrunc(CRCNext, CRCTy,
"crc.next");
1874 Info.ComputedValue->replaceUsesOutsideBlock(CRCNext, CurLoop->
getLoopLatch());
1888 Ctx, BrInst->getSuccessor(0) == CurLoop->
getExitBlock()));
1893void LoopIdiomRecognize::optimizeCRCLoopUsingTableLookup(
1895 assert(
Info.TripCount % 8 == 0 &&
"A byte-multiple trip count is required");
1901 std::array<Constant *, 256> CRCConstants;
1903 CRCConstants.begin(),
1904 [CRCTy](
const APInt &
E) { return ConstantInt::get(CRCTy, E); });
1926 unsigned NewBTC = (
Info.TripCount / 8) - 1;
1933 Value *ExitLimit = ConstantInt::get(
IV->getType(), NewBTC);
1935 Value *NewExitCond =
1936 Builder.CreateICmp(ExitPred,
IV, ExitLimit,
"exit.cond");
1958 Op = CRCBW > 8 ? Builder.CreateLShr(
Op, CRCBW - 8, Name)
1959 : Builder.CreateShl(
Op, 8 - CRCBW, Name);
1961 return LoByte(Builder,
Op, Name +
".lo.byte");
1965 Builder.disableGEPCanonicalization();
1969 PHINode *CRCPhi = Builder.CreatePHI(CRCTy, 2,
"crc");
1973 Value *CRC = CRCPhi;
1977 Value *Indexer = CRC;
1985 Value *IVBits = Builder.CreateZExtOrTrunc(
1986 Builder.CreateShl(
IV, 3,
"iv.bits"), DataTy,
"iv.indexer");
1987 Value *DataIndexer =
1988 Info.IsBigEndian ? Builder.CreateShl(
Data, IVBits,
"data.indexer")
1989 : Builder.CreateLShr(
Data, IVBits,
"data.indexer");
1990 Indexer = Builder.CreateXor(
1992 Builder.CreateZExtOrTrunc(Indexer, DataTy,
"crc.indexer.cast"),
1993 "crc.data.indexer");
1996 Indexer =
Info.IsBigEndian ? HiIdx(Builder, Indexer,
"indexer.hi")
1997 : LoByte(Builder, Indexer,
"indexer.lo");
2000 Indexer = Builder.CreateZExt(
2005 Value *CRCTableGEP =
2006 Builder.CreateInBoundsGEP(CRCTy, GV, Indexer,
"tbl.ptradd");
2007 Instruction *CRCTableLd = Builder.CreateLoad(CRCTy, CRCTableGEP,
"tbl.ld");
2011 auto *NewMemAcc = MSSAU->createMemoryAccessInBB(
2012 CRCTableLd,
nullptr, CRCTableLd->getParent(),
2019 Value *CRCNext = CRCTableLd;
2022 ? Builder.CreateShl(CRC, 8,
"crc.be.shift")
2023 : Builder.CreateLShr(CRC, 8,
"crc.le.shift");
2024 CRCNext = Builder.CreateXor(CRCShift, CRCTableLd,
"crc.next");
2029 Info.ComputedValue->replaceUsesOutsideBlock(CRCNext,
2039 MSSAU->getMemorySSA()->verifyMemorySSA();
2043bool LoopIdiomRecognize::runOnNoncountableLoop() {
2046 <<
"] Noncountable Loop %"
2049 return recognizePopcount() || recognizeAndInsertFFS() ||
2050 recognizeShiftUntilBitTest() || recognizeShiftUntilZero() ||
2051 recognizeShiftUntilLessThan() || recognizeAndInsertStrLen();
2061 bool JmpOnZero =
false) {
2067 if (!CmpZero || !CmpZero->isZero())
2078 return Cond->getOperand(0);
2085class StrlenVerifier {
2087 explicit StrlenVerifier(
const Loop *CurLoop, ScalarEvolution *SE)
2088 : CurLoop(CurLoop), SE(SE) {}
2090 bool isValidStrlenIdiom() {
2109 if (!LoopBody || LoopBody->
size() >= 15)
2130 const SCEV *LoadEv = SE->
getSCEV(IncPtr);
2143 if (OpWidth != 8 && OpWidth != 16 && OpWidth != 32)
2145 if (StepSize != OpWidth / 8)
2147 if (OpWidth >= 16) {
2148 if (OpWidth != WcharSize * 8)
2153 Align OperandAlign =
DL.getABITypeAlign(OperandType);
2154 if (LoopLoad->
getAlign() < OperandAlign) {
2164 for (Instruction &
I : *LoopBody)
2165 if (
I.mayHaveSideEffects())
2172 for (PHINode &PN : LoopExitBB->
phis()) {
2176 const SCEV *Ev = SE->
getSCEV(&PN);
2186 if (!AddRecEv || !AddRecEv->
isAffine())
2200 const Loop *CurLoop;
2201 ScalarEvolution *SE;
2204 ConstantInt *StepSizeCI;
2205 const SCEV *LoadBaseEv;
2270bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
2274 StrlenVerifier
Verifier(CurLoop, SE);
2276 if (!
Verifier.isValidStrlenIdiom())
2283 assert(Preheader && LoopBody && LoopExitBB &&
2284 "Should be verified to be valid by StrlenVerifier");
2299 Builder.SetCurrentDebugLocation(CurLoop->
getStartLoc());
2301 Value *MaterialzedBase = Expander.expandCodeFor(
2303 Builder.GetInsertPoint());
2305 Value *StrLenFunc =
nullptr;
2311 assert(StrLenFunc &&
"Failed to emit strlen function.");
2330 StrlenEv,
Base->getType())));
2332 Value *MaterializedPHI = Expander.expandCodeFor(NewEv, NewEv->
getType(),
2333 Builder.GetInsertPoint());
2348 "loop body must have a successor that is it self");
2350 ? Builder.getFalse()
2351 : Builder.getTrue();
2356 LLVM_DEBUG(
dbgs() <<
" Formed strlen idiom: " << *StrLenFunc <<
"\n");
2360 <<
"Transformed " << StrLenFunc->
getName() <<
" loop idiom";
2385 return Cond->getOperand(0);
2396 if (PhiX && PhiX->getParent() == LoopEntry &&
2397 (PhiX->getOperand(0) == DefX || PhiX->
getOperand(1) == DefX))
2464 if (DefX->
getOpcode() != Instruction::LShr)
2467 IntrinID = Intrinsic::ctlz;
2469 if (!Shft || !Shft->
isOne())
2483 if (Inst.
getOpcode() != Instruction::Add)
2535 Value *VarX1, *VarX0;
2538 DefX2 = CountInst =
nullptr;
2539 VarX1 = VarX0 =
nullptr;
2540 PhiX = CountPhi =
nullptr;
2553 if (!DefX2 || DefX2->
getOpcode() != Instruction::And)
2564 if (!SubOneOp || SubOneOp->
getOperand(0) != VarX1)
2570 (SubOneOp->
getOpcode() == Instruction::Add &&
2583 CountInst =
nullptr;
2586 if (Inst.
getOpcode() != Instruction::Add)
2590 if (!Inc || !Inc->
isOne())
2598 bool LiveOutLoop =
false;
2627 CntInst = CountInst;
2667 Value *VarX =
nullptr;
2681 if (!DefX || !DefX->
isShift())
2683 IntrinID = DefX->
getOpcode() == Instruction::Shl ? Intrinsic::cttz :
2686 if (!Shft || !Shft->
isOne())
2711 if (Inst.
getOpcode() != Instruction::Add)
2734bool LoopIdiomRecognize::isProfitableToInsertFFS(
Intrinsic::ID IntrinID,
2735 Value *InitX,
bool ZeroCheck,
2736 size_t CanonicalSize) {
2754bool LoopIdiomRecognize::insertFFSIfProfitable(
Intrinsic::ID IntrinID,
2758 bool IsCntPhiUsedOutsideLoop =
false;
2761 IsCntPhiUsedOutsideLoop =
true;
2764 bool IsCntInstUsedOutsideLoop =
false;
2767 IsCntInstUsedOutsideLoop =
true;
2772 if (IsCntInstUsedOutsideLoop && IsCntPhiUsedOutsideLoop)
2778 bool ZeroCheck =
false;
2787 if (!IsCntPhiUsedOutsideLoop) {
2805 size_t IdiomCanonicalSize = 6;
2806 if (!isProfitableToInsertFFS(IntrinID, InitX, ZeroCheck, IdiomCanonicalSize))
2809 transformLoopToCountable(IntrinID, PH, CntInst, CntPhi, InitX, DefX,
2811 IsCntPhiUsedOutsideLoop);
2818bool LoopIdiomRecognize::recognizeAndInsertFFS() {
2833 return insertFFSIfProfitable(IntrinID, InitX, DefX, CntPhi, CntInst);
2836bool LoopIdiomRecognize::recognizeShiftUntilLessThan() {
2847 APInt LoopThreshold;
2849 CntPhi, DefX, LoopThreshold))
2852 if (LoopThreshold == 2) {
2854 return insertFFSIfProfitable(IntrinID, InitX, DefX, CntPhi, CntInst);
2858 if (LoopThreshold != 4)
2876 APInt PreLoopThreshold;
2878 PreLoopThreshold != 2)
2881 bool ZeroCheck =
true;
2890 size_t IdiomCanonicalSize = 6;
2891 if (!isProfitableToInsertFFS(IntrinID, InitX, ZeroCheck, IdiomCanonicalSize))
2895 transformLoopToCountable(IntrinID, PH, CntInst, CntPhi, InitX, DefX,
2906bool LoopIdiomRecognize::recognizePopcount() {
2920 if (LoopBody->
size() >= 20) {
2948 transformLoopToPopcount(PreCondBB, CntInst, CntPhi, Val);
3002void LoopIdiomRecognize::transformLoopToCountable(
3005 bool ZeroCheck,
bool IsCntPhiUsedOutsideLoop,
bool InsertSub) {
3008 Builder.SetCurrentDebugLocation(
DL);
3017 if (IsCntPhiUsedOutsideLoop) {
3018 if (DefX->
getOpcode() == Instruction::AShr)
3019 InitXNext = Builder.CreateAShr(InitX, 1);
3020 else if (DefX->
getOpcode() == Instruction::LShr)
3021 InitXNext = Builder.CreateLShr(InitX, 1);
3022 else if (DefX->
getOpcode() == Instruction::Shl)
3023 InitXNext = Builder.CreateShl(InitX, 1);
3031 Count = Builder.CreateSub(
3034 Count = Builder.CreateSub(
Count, ConstantInt::get(CountTy, 1));
3036 if (IsCntPhiUsedOutsideLoop)
3037 Count = Builder.CreateAdd(
Count, ConstantInt::get(CountTy, 1));
3039 NewCount = Builder.CreateZExtOrTrunc(NewCount, CntInst->
getType());
3046 if (!InitConst || !InitConst->
isZero())
3047 NewCount = Builder.CreateAdd(NewCount, CntInitVal);
3051 NewCount = Builder.CreateSub(CntInitVal, NewCount);
3069 Builder.SetInsertPoint(LbCond);
3071 TcPhi, ConstantInt::get(CountTy, 1),
"tcdec",
false,
true));
3080 LbCond->
setOperand(1, ConstantInt::get(CountTy, 0));
3084 if (IsCntPhiUsedOutsideLoop)
3094void LoopIdiomRecognize::transformLoopToPopcount(
BasicBlock *PreCondBB,
3107 Value *PopCnt, *NewCount, *TripCnt;
3113 if (NewCount != PopCnt)
3122 if (!InitConst || !InitConst->
isZero()) {
3123 NewCount = Builder.CreateAdd(NewCount, CntInitVal);
3135 Value *Opnd0 = TripCnt;
3136 Value *Opnd1 = ConstantInt::get(TripCnt->
getType(), 0);
3141 Builder.CreateICmp(PreCond->
getPredicate(), Opnd0, Opnd1));
3142 PreCondBr->setCondition(NewPreCond);
3176 Builder.SetInsertPoint(LbCond);
3178 Builder.CreateSub(TcPhi, ConstantInt::get(Ty, 1),
"tcdec",
3188 LbCond->
setOperand(1, ConstantInt::get(Ty, 0));
3209 template <
typename ITy>
bool match(ITy *V)
const {
3210 return L->isLoopInvariant(V) &&
SubPattern.match(V);
3215template <
typename Ty>
3246 " Performing shift-until-bittest idiom detection.\n");
3256 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3263 Value *CmpLHS, *CmpRHS;
3274 auto MatchVariableBitMask = [&]() {
3284 auto MatchDecomposableConstantBitMask = [&]() {
3286 CmpLHS, CmpRHS,
Pred,
true,
3288 if (Res && Res->Mask.isPowerOf2()) {
3292 BitMask = ConstantInt::get(CurrX->
getType(), Res->Mask);
3293 BitPos = ConstantInt::get(CurrX->
getType(), Res->Mask.logBase2());
3299 if (!MatchVariableBitMask() && !MatchDecomposableConstantBitMask()) {
3306 if (!CurrXPN || CurrXPN->getParent() != LoopHeaderBB) {
3311 BaseX = CurrXPN->getIncomingValueForBlock(LoopPreheaderBB);
3316 "Expected BaseX to be available in the preheader!");
3327 "Should only get equality predicates here.");
3337 if (TrueBB != LoopHeaderBB) {
3353 unsigned Bitwidth =
X->getType()->getScalarSizeInBits();
3354 if (!Pos || Bitwidth == 1 || Pos->getValue().uge(Bitwidth))
3384 if (ZeroSuccessor != Preheader)
3387 return Mask->countr_one() >= Pos->getZExtValue();
3442bool LoopIdiomRecognize::recognizeShiftUntilBitTest() {
3443 bool MadeChange =
false;
3445 Value *
X, *BitMask, *BitPos, *XCurr;
3450 " shift-until-bittest idiom detection failed.\n");
3460 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3463 assert(SuccessorBB &&
"There is only a single successor.");
3468 bool IsRightShift = XNext->
getOpcode() == Instruction::LShr;
3469 Intrinsic::ID IntrID = IsRightShift ? Intrinsic::cttz : Intrinsic::ctlz;
3470 Type *Ty =
X->getType();
3475 X, BitPos, LoopPreheaderBB, *
DL, DT)) {
3490 " Intrinsic is too costly, not beneficial\n");
3493 if (
TTI->getArithmeticInstrCost(XNext->
getOpcode(), Ty, CostKind) >
3505 std::optional<BasicBlock::iterator> InsertPt = std::nullopt;
3507 InsertPt = BitPosI->getInsertionPointAfterDef();
3515 return U.getUser() != BitPosFrozen;
3517 BitPos = BitPosFrozen;
3522 Value *LoopBackedgeTakenCount;
3524 Value *ShiftedX = Builder.CreateLShr(
X, BitPos);
3525 LoopBackedgeTakenCount = Builder.CreateIntrinsic(
3526 IntrID, Ty, {ShiftedX, Builder.getTrue()});
3530 BitPos->
getName() +
".lowbitmask");
3532 Builder.CreateOr(LowBitMask, BitMask, BitPos->
getName() +
".mask");
3533 Value *XMasked = Builder.CreateAnd(
X, Mask,
X->getName() +
".masked");
3534 Value *XMaskedNumLeadingZeros = Builder.CreateIntrinsic(
3535 IntrID, Ty, {XMasked, Builder.getTrue()},
3536 nullptr, XMasked->
getName() +
".numleadingzeros");
3537 Value *XMaskedNumActiveBits = Builder.CreateSub(
3539 XMasked->
getName() +
".numactivebits",
3540 true, Bitwidth != 2);
3541 Value *XMaskedLeadingOnePos = Builder.CreateAdd(
3543 XMasked->
getName() +
".leadingonepos",
false,
3546 LoopBackedgeTakenCount = Builder.CreateSub(
3547 BitPos, XMaskedLeadingOnePos,
3548 CurLoop->
getName() +
".backedgetakencount",
true,
3553 Value *LoopTripCount =
3554 Builder.CreateAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
3555 CurLoop->
getName() +
".tripcount",
true,
3562 Value *NewX = IsRightShift ? Builder.CreateLShr(
X, LoopBackedgeTakenCount)
3563 : Builder.CreateShl(
X, LoopBackedgeTakenCount);
3566 I->copyIRFlags(XNext,
true);
3574 NewXNext = Builder.CreateLShr(NewX, ConstantInt::get(Ty, 1));
3581 NewXNext = Builder.CreateShl(
X, LoopTripCount);
3586 NewXNext = Builder.CreateShl(NewX, ConstantInt::get(Ty, 1));
3591 I->copyIRFlags(XNext,
true);
3602 Builder.SetInsertPoint(LoopHeaderBB->
begin());
3603 auto *
IV = Builder.CreatePHI(Ty, 2, CurLoop->
getName() +
".iv");
3609 Builder.CreateAdd(
IV, ConstantInt::get(Ty, 1),
IV->getName() +
".next",
3610 true, Bitwidth != 2);
3613 auto *IVCheck = Builder.CreateICmpEQ(IVNext, LoopTripCount,
3614 CurLoop->
getName() +
".ivcheck");
3616 const bool HasBranchWeights =
3619 auto *BI = Builder.CreateCondBr(IVCheck, SuccessorBB, LoopHeaderBB);
3620 if (HasBranchWeights) {
3622 std::swap(BranchWeights[0], BranchWeights[1]);
3632 IV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
3633 IV->addIncoming(IVNext, LoopHeaderBB);
3644 ++NumShiftUntilBitTest;
3680 const SCEV *&ExtraOffsetExpr,
3681 bool &InvertedCond) {
3683 " Performing shift-until-zero idiom detection.\n");
3696 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3707 !
match(ValShiftedIsZero,
3721 IntrinID = ValShifted->
getOpcode() == Instruction::Shl ? Intrinsic::cttz
3730 else if (
match(NBits,
3734 ExtraOffsetExpr = SE->
getSCEV(ExtraOffset);
3742 if (!IVPN || IVPN->getParent() != LoopHeaderBB) {
3747 Start = IVPN->getIncomingValueForBlock(LoopPreheaderBB);
3758 "Should only get equality predicates here.");
3769 if (FalseBB != LoopHeaderBB) {
3780 if (ValShifted->
getOpcode() == Instruction::AShr &&
3844bool LoopIdiomRecognize::recognizeShiftUntilZero() {
3845 bool MadeChange =
false;
3851 const SCEV *ExtraOffsetExpr;
3854 Start, Val, ExtraOffsetExpr, InvertedCond)) {
3856 " shift-until-zero idiom detection failed.\n");
3866 assert(LoopPreheaderBB &&
"There is always a loop preheader.");
3869 assert(SuccessorBB &&
"There is only a single successor.");
3872 Builder.SetCurrentDebugLocation(
IV->getDebugLoc());
3888 " Intrinsic is too costly, not beneficial\n");
3895 bool OffsetIsZero = ExtraOffsetExpr->
isZero();
3899 Value *ValNumLeadingZeros = Builder.CreateIntrinsic(
3900 IntrID, Ty, {Val, Builder.getFalse()},
3901 nullptr, Val->
getName() +
".numleadingzeros");
3902 Value *ValNumActiveBits = Builder.CreateSub(
3904 Val->
getName() +
".numactivebits",
true,
3908 Expander.setInsertPoint(&*Builder.GetInsertPoint());
3909 Value *ExtraOffset = Expander.expandCodeFor(ExtraOffsetExpr);
3911 Value *ValNumActiveBitsOffset = Builder.CreateAdd(
3912 ValNumActiveBits, ExtraOffset, ValNumActiveBits->
getName() +
".offset",
3913 OffsetIsZero,
true);
3914 Value *IVFinal = Builder.CreateIntrinsic(Intrinsic::smax, {Ty},
3915 {ValNumActiveBitsOffset,
Start},
3916 nullptr,
"iv.final");
3919 IVFinal, Start, CurLoop->
getName() +
".backedgetakencount",
3920 OffsetIsZero,
true));
3924 Value *LoopTripCount =
3925 Builder.CreateAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
3926 CurLoop->
getName() +
".tripcount",
true,
3932 IV->replaceUsesOutsideBlock(IVFinal, LoopHeaderBB);
3937 Builder.SetInsertPoint(LoopHeaderBB->
begin());
3938 auto *CIV = Builder.CreatePHI(Ty, 2, CurLoop->
getName() +
".iv");
3943 Builder.CreateAdd(CIV, ConstantInt::get(Ty, 1), CIV->getName() +
".next",
3944 true, Bitwidth != 2);
3947 auto *CIVCheck = Builder.CreateICmpEQ(CIVNext, LoopTripCount,
3948 CurLoop->
getName() +
".ivcheck");
3949 auto *NewIVCheck = CIVCheck;
3951 NewIVCheck = Builder.CreateNot(CIVCheck);
3952 NewIVCheck->takeName(ValShiftedIsZero);
3956 auto *IVDePHId = Builder.CreateAdd(CIV, Start,
"",
false,
3958 IVDePHId->takeName(
IV);
3963 const bool HasBranchWeights =
3966 auto *BI = Builder.CreateCondBr(CIVCheck, SuccessorBB, LoopHeaderBB);
3967 if (HasBranchWeights) {
3969 std::swap(BranchWeights[0], BranchWeights[1]);
3977 CIV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
3978 CIV->addIncoming(CIVNext, LoopHeaderBB);
3986 IV->replaceAllUsesWith(IVDePHId);
3987 IV->eraseFromParent();
3996 ++NumShiftUntilZero;
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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 void addRangeAttrFromTripCount(CallInst *NewCall, uint64_t ElemsPerIter, Loop *L, ScalarEvolution *SE)
Add a range to the length (or, for memset.pattern, the count) of a newly formed memset/memset....
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 bool isRightShiftBitTestKnownToTerminate(Value *X, Value *BitPos, BasicBlock *Preheader, const DataLayout &DL, DominatorTree *DT)
static const SCEV * getStartForNegStride(const SCEV *Start, const SCEV *BECount, Type *IntPtr, const SCEV *StoreSizeSCEV, ScalarEvolution *SE)
static APInt getStoreStride(const SCEVAddRecExpr *StoreEv)
match_LoopInvariant< Ty > m_LoopInvariant(const Ty &M, const Loop *L)
Matches if the value is loop-invariant.
static bool isSameByteValueStore(Instruction &I, Value *SplatByte, Loop *L, const DataLayout &DL)
Return true if I is a (simple, loop-invariant-valued) store of the same bytewise value SplatByte.
static void deleteDeadInstruction(Instruction *I)
This file implements a map that provides insertion order iteration.
This file provides utility analysis objects describing memory locations.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
This file contains the declarations for profiling metadata utility functions.
SmallVector< MachineOperand, 4 > Cond
verify safepoint Safepoint IR Verifier
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static SymbolRef::Type getType(const Symbol *Sym)
static const uint32_t IV[8]
Class for arbitrary precision integers.
std::optional< uint64_t > tryZExtValue() const
Get zero extended value if possible.
uint64_t getZExtValue() const
Get zero extended value.
bool sgt(const APInt &RHS) const
Signed greater than comparison.
unsigned getBitWidth() const
Return the number of bits in the APInt.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
bool slt(const APInt &RHS) const
Signed less than comparison.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
int64_t getSExtValue() const
Get sign extended value.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
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 getFirstNonPHIOrAlloca() const
Returns an iterator to the first instruction in this block that is not a PHINode, a static alloca,...
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...
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
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_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 class represents a range of values.
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const
Returns the type of a GEP index in AddressSpace.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This class represents a freeze function that returns random concrete value if an operand is either a ...
PointerType * getType() const
Global values are always pointers.
@ PrivateLinkage
Like Internal, but omit from symbol table.
static LLVM_ABI CRCTable genSarwateTable(const APInt &GenPoly, bool IsBigEndian)
Generate a lookup table of 256 entries by interleaving the generating polynomial.
static LLVM_ABI std::pair< APInt, APInt > genBarrettConstants(const PolynomialInfo &Info)
Auxilary entry point after analysis to generate constants for a GF(2) Barrett Reduction.
This instruction compares its operands according to the predicate given to the constructor.
bool isEquality() const
Return true if this predicate is either EQ or NE.
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
Common base class shared among various IRBuilders.
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static InstructionCost getInvalid(CostType Val=0)
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI void setAAMetadata(const AAMDNodes &N)
Sets the AA metadata on this instruction from the AAMDNodes structure.
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
iterator_range< user_iterator > users()
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.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
Class to represent integer types.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
This is an important class for using LLVM in a threaded context.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
An instruction for reading from memory.
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
Value * getPointerOperand()
bool isVolatile() const
Return true if this is a load from a volatile memory location.
bool isAtomic() const
Return true if this load has an atomic ordering.
Align getAlign() const
Return the alignment of the access that is being performed.
static LocationSize precise(uint64_t Value)
static constexpr LocationSize afterPointer()
Any location after the base pointer (but still within the underlying object).
bool contains(const LoopT *L) const
Return true if the specified loop is contained within this loop.
bool isOutermost() const
Return true if the loop does not have a parent (natural) loop.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
unsigned getNumBlocks() const
Get the number of blocks in this loop in constant time.
unsigned getNumBackEdges() const
Calculate the number of back edges to the loop header.
BlockT * getHeader() const
BlockT * getExitBlock() const
If getExitBlocks would return exactly one block, return that block.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
ArrayRef< BlockT * > getBlocks() const
Get a list of the basic blocks which make up this loop.
void getUniqueExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all unique successor blocks of this loop.
block_iterator block_begin() const
BlockT * getUniqueExitBlock() const
If getUniqueExitBlocks would return exactly one block, return that block.
LLVM_ABI PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
LLVM_ABI DebugLoc getStartLoc() const
Return the debug location of the start of this loop.
LLVM_ABI bool isLoopInvariant(const Value *V) const
Return true if the specified value is loop invariant.
LLVM_ABI ICmpInst * getLatchCmpInst() const
Get the latch condition instruction.
StringRef getName() const
LLVM_ABI 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.
unsigned getWCharSize() const
Returns the size of the wchar_t type from the "wchar_size" module flag, or the triple default when th...
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This node represents a polynomial recurrence on the trip count of the specified loop.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values.
SCEVUse getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
This class represents a constant integer value.
ConstantInt * getValue() const
const APInt & getAPInt() const
Helper to remove instructions inserted during SCEV expansion, unless they are marked as used.
This class uses information about analyze scalars to rewrite expressions in canonical form.
SCEVUse getOperand(unsigned i) const
This class represents an analyzed expression in the program.
LLVM_ABI bool isOne() const
Return true if the expression is a constant one.
static constexpr auto FlagNUW
LLVM_ABI bool isZero() const
Return true if the expression is a constant zero.
LLVM_ABI bool isNonConstantNegative() const
Return true if the specified scev is negated, but not a constant.
Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
const SCEV * getConstantMaxBackedgeTakenCount(const Loop *L)
When successful, this returns a SCEVConstant that is greater than or equal to (i.e.
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 * 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 * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEVFlags Flags=SCEV::FlagNone, unsigned Depth=0)
Return LHS-RHS.
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 SCEVUse getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlagsPair Flags={}, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
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 uint32_t getMinTrailingZeros(const SCEV *S, const Instruction *CtxI=nullptr)
Determine the minimum number of zero bits that S is guaranteed to end in (at every loop iteration).
LLVM_ABI SCEVUse getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlagsPair Flags={}, unsigned Depth=0)
Get a canonical multiply 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 * getNegativeSCEV(const SCEV *V, SCEVFlags Flags=SCEV::FlagNone)
Return the SCEV object corresponding to -V.
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 ...
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.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
A Use represents the edge between a Value definition and its users.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
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 Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
OperandType
Operands are tagged with one of the values of this enum.
match_combine_and< Ty... > m_CombineAnd(const Ty &...Ps)
Combine pattern matchers matching all of Ps patterns.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
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.
is_zero< true > m_Zero()
Match any null constant or a vector with all elements equal to 0.
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.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
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)
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
bool isSimple(Instruction *I)
This is an optimization pass for GlobalISel generic memory operations.
static cl::opt< bool, true > DisableLIRPHashRecognize("disable-" DEBUG_TYPE "-hashrecognize", cl::desc("Proceed with loop idiom recognize pass, " "but do not do hash-recognize analysis."), cl::location(DisableLIRP::HashRecognize), cl::init(false), cl::ReallyHidden)
constexpr uint64_t maxUIntN(uint64_t N)
Gets the maximum value for a N-bit unsigned integer.
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
static cl::opt< bool, true > EnableLIRPWcslen("disable-loop-idiom-wcslen", cl::desc("Proceed with loop idiom recognize pass, " "enable conversion of loop(s) to wcslen."), cl::location(DisableLIRP::Wcslen), cl::init(false), cl::ReallyHidden)
static cl::opt< bool, true > DisableLIRPMemcpy("disable-" DEBUG_TYPE "-memcpy", cl::desc("Proceed with loop idiom recognize pass, but do " "not convert loop(s) to memcpy."), cl::location(DisableLIRP::Memcpy), cl::init(false), cl::ReallyHidden)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
static cl::opt< bool, true > DisableLIRPStrlen("disable-loop-idiom-strlen", cl::desc("Proceed with loop idiom recognize pass, but do " "not convert loop(s) to strlen."), cl::location(DisableLIRP::Strlen), cl::init(false), cl::ReallyHidden)
@ Store
The extracted value is stored (ExtractElement only).
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
const ScalarOptions & getScalarOptions(const LLVMContext &C)
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 bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isModOrRefSet(const ModRefInfo MRI)
LLVM_ABI bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, SmallPtrSetImpl< PHINode * > *KnownNonDeadPHIs=nullptr)
If the specified value is an effectively dead PHI node, due to being a def-use chain of single-use no...
LLVM_ABI Value * emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the strlen function to the builder, for the specified pointer.
LLVM_ABI bool VerifyMemorySSA
Enables verification of MemorySSA.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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...
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
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.
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, 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)
unsigned Log2(Align A)
Returns the log2 of the alignment.
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)
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)