46#include "llvm/Config/llvm-config.h"
69#include "llvm/IR/IntrinsicsAArch64.h"
113#define DEBUG_TYPE "codegenprepare"
116STATISTIC(NumPHIsElim,
"Number of trivial PHIs eliminated");
117STATISTIC(NumGEPsElim,
"Number of GEPs converted to casts");
118STATISTIC(NumCmpUses,
"Number of uses of Cmp expressions replaced with uses of "
120STATISTIC(NumCastUses,
"Number of uses of Cast expressions replaced with uses "
122STATISTIC(NumMemoryInsts,
"Number of memory instructions whose address "
123 "computations were sunk");
125 "Number of phis created when address "
126 "computations were sunk to memory instructions");
128 "Number of select created when address "
129 "computations were sunk to memory instructions");
130STATISTIC(NumExtsMoved,
"Number of [s|z]ext instructions combined with loads");
131STATISTIC(NumExtUses,
"Number of uses of [s|z]ext instructions optimized");
133 "Number of and mask instructions added to form ext loads");
134STATISTIC(NumAndUses,
"Number of uses of and mask instructions optimized");
135STATISTIC(NumRetsDup,
"Number of return instructions duplicated");
136STATISTIC(NumDbgValueMoved,
"Number of debug value instructions moved");
137STATISTIC(NumSelectsExpanded,
"Number of selects turned into branches");
138STATISTIC(NumStoreExtractExposed,
"Number of store(extractelement) exposed");
142 cl::desc(
"Disable branch optimizations in CodeGenPrepare"));
146 cl::desc(
"Disable GC optimizations in CodeGenPrepare"));
151 cl::desc(
"Disable select to branch conversion."));
155 cl::desc(
"Address sinking in CGP using GEPs."));
159 cl::desc(
"Enable sinking and/cmp into branches."));
163 cl::desc(
"Disable store(extract) optimizations in CodeGenPrepare"));
167 cl::desc(
"Stress test store(extract) optimizations in CodeGenPrepare"));
171 cl::desc(
"Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in "
176 cl::desc(
"Stress test ext(promotable(ld)) -> promoted(ext(ld)) "
177 "optimization in CodeGenPrepare"));
181 cl::desc(
"Disable protection against removing loop preheaders"));
185 cl::desc(
"Use profile info to add section prefix for hot/cold functions"));
188 "profile-unknown-in-special-section",
cl::Hidden,
189 cl::desc(
"In profiling mode like sampleFDO, if a function doesn't have "
190 "profile, we cannot tell the function is cold for sure because "
191 "it may be a function newly added without ever being sampled. "
192 "With the flag enabled, compiler can put such profile unknown "
193 "functions into a special section, so runtime system can choose "
194 "to handle it in a different way than .text section, to save "
195 "RAM for example. "));
199 cl::desc(
"Use the basic-block-sections profile to determine the text "
200 "section prefix for hot functions. Functions with "
201 "basic-block-sections profile will be placed in `.text.hot` "
202 "regardless of their FDO profile info. Other functions won't be "
203 "impacted, i.e., their prefixes will be decided by FDO/sampleFDO "
208 cl::desc(
"Skip merging empty blocks if (frequency of empty block) / "
209 "(frequency of destination block) is greater than this ratio"));
213 cl::desc(
"Force store splitting no matter what the target query says."));
217 cl::desc(
"Enable merging of redundant sexts when one is dominating"
223 cl::desc(
"Disables combining addressing modes with different parts "
224 "in optimizeMemoryInst."));
228 cl::desc(
"Allow creation of Phis in Address sinking."));
232 cl::desc(
"Allow creation of selects in Address sinking."));
236 cl::desc(
"Allow combining of BaseReg field in Address sinking."));
240 cl::desc(
"Allow combining of BaseGV field in Address sinking."));
244 cl::desc(
"Allow combining of BaseOffs field in Address sinking."));
248 cl::desc(
"Allow combining of ScaledReg field in Address sinking."));
253 cl::desc(
"Enable splitting large offset of GEP."));
257 cl::desc(
"Enable ICMP_EQ to ICMP_S(L|G)T conversion."));
261 cl::desc(
"Enable BFI update verification for "
266 cl::desc(
"Enable converting phi types in CodeGenPrepare"));
270 cl::desc(
"Least BB number of huge function."));
275 cl::desc(
"Max number of address users to look at"));
279 cl::desc(
"Disable elimination of dead PHI nodes."));
307class TypePromotionTransaction;
309class CodeGenPrepare {
310 friend class CodeGenPrepareLegacyPass;
311 const TargetMachine *TM =
nullptr;
312 const TargetSubtargetInfo *SubtargetInfo =
nullptr;
313 const TargetLowering *TLI =
nullptr;
314 const TargetRegisterInfo *TRI =
nullptr;
315 const TargetTransformInfo *TTI =
nullptr;
316 const BasicBlockSectionsProfileReader *BBSectionsProfileReader =
nullptr;
317 const TargetLibraryInfo *TLInfo =
nullptr;
318 DomTreeUpdater *DTU =
nullptr;
319 LoopInfo *LI =
nullptr;
320 BlockFrequencyInfo *BFI;
321 BranchProbabilityInfo *BPI;
322 ProfileSummaryInfo *PSI =
nullptr;
333 ValueMap<Value *, WeakTrackingVH> SunkAddrs;
336 SetOfInstrs InsertedInsts;
340 InstrToOrigTy PromotedInsts;
343 SetOfInstrs RemovedInsts;
346 DenseMap<Value *, Instruction *> SeenChainsForSExt;
351 MapVector<AssertingVH<Value>,
356 SmallSet<AssertingVH<Value>, 2> NewGEPBases;
359 DenseMap<AssertingVH<GetElementPtrInst>,
int> LargeOffsetGEPID;
362 ValueToSExts ValToSExtendedUses;
368 const DataLayout *DL =
nullptr;
371 CodeGenPrepare() =
default;
372 CodeGenPrepare(
const TargetMachine *TM) : TM(TM){};
374 bool IsHugeFunc =
false;
380 SmallPtrSet<BasicBlock *, 32> FreshBBs;
382 void releaseMemory() {
384 InsertedInsts.clear();
385 PromotedInsts.clear();
392 template <
typename F>
393 void resetIteratorIfInvalidatedWhileCalling(BasicBlock *BB,
F f) {
397 Value *CurValue = &*CurInstIterator;
398 WeakTrackingVH IterHandle(CurValue);
404 if (IterHandle != CurValue) {
405 CurInstIterator = BB->
begin();
411 DominatorTree &getDT() {
return DTU->getDomTree(); }
413 void removeAllAssertingVHReferences(
Value *V);
416 bool eliminateMostlyEmptyBlocks(
Function &
F,
bool &ResetLI);
417 BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB);
418 bool canMergeBlocks(
const BasicBlock *BB,
const BasicBlock *DestBB)
const;
419 bool eliminateMostlyEmptyBlock(BasicBlock *BB);
420 bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB,
422 bool makeBitReverse(Instruction &
I);
424 bool optimizeInst(Instruction *
I, ModifyDT &ModifiedDT);
425 bool optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
Type *AccessTy,
427 bool optimizeGatherScatterInst(Instruction *MemoryInst,
Value *Ptr);
428 bool optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
429 ModifyDT &ModifiedDT);
430 bool optimizeInlineAsmInst(CallInst *CS);
432 bool optimizeExt(Instruction *&
I);
433 bool optimizeExtUses(Instruction *
I);
434 bool optimizeLoadExt(LoadInst *
Load);
435 bool optimizeShiftInst(BinaryOperator *BO);
436 bool optimizeFunnelShift(IntrinsicInst *Fsh);
437 bool optimizeSelectInst(SelectInst *SI);
438 bool optimizeShuffleVectorInst(ShuffleVectorInst *SVI);
439 bool optimizeSwitchType(SwitchInst *SI);
440 bool optimizeSwitchPhiConstants(SwitchInst *SI);
441 bool optimizeSwitchInst(SwitchInst *SI);
442 bool optimizeExtractElementInst(Instruction *Inst);
443 bool dupRetToEnableTailCallOpts(BasicBlock *BB, ModifyDT &ModifiedDT);
444 bool fixupDbgVariableRecord(DbgVariableRecord &
I);
445 bool fixupDbgVariableRecordsOnInst(Instruction &
I);
448 bool canFormExtLd(
const SmallVectorImpl<Instruction *> &MovedExts,
449 LoadInst *&LI, Instruction *&Inst,
bool HasPromoted);
450 bool tryToPromoteExts(TypePromotionTransaction &TPT,
451 const SmallVectorImpl<Instruction *> &Exts,
452 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
453 unsigned CreatedInstsCost = 0);
455 bool splitLargeGEPOffsets();
456 bool optimizePhiType(PHINode *Inst, SmallPtrSetImpl<PHINode *> &Visited,
457 SmallPtrSetImpl<Instruction *> &DeletedInstrs);
459 bool performAddressTypePromotion(
460 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
461 bool HasPromoted, TypePromotionTransaction &TPT,
462 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts);
464 bool simplifyOffsetableRelocate(GCStatepointInst &
I);
466 bool tryToSinkFreeOperands(Instruction *
I);
467 bool replaceMathCmpWithIntrinsic(BinaryOperator *BO,
Value *Arg0,
Value *Arg1,
469 bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT);
470 bool optimizeURem(Instruction *Rem);
471 bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
472 bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
473 bool unfoldPowerOf2Test(CmpInst *Cmp);
482 CodeGenPrepareLegacyPass() : FunctionPass(ID) {}
486 StringRef getPassName()
const override {
return "CodeGen Prepare"; }
488 void getAnalysisUsage(AnalysisUsage &AU)
const override {
496 AU.
addRequired<BranchProbabilityInfoWrapperPass>();
504char CodeGenPrepareLegacyPass::ID = 0;
506bool CodeGenPrepareLegacyPass::runOnFunction(
Function &
F) {
509 auto TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
510 CodeGenPrepare CGP(TM);
511 CGP.DL = &
F.getDataLayout();
514 CGP.TRI = CGP.SubtargetInfo->getRegisterInfo();
515 CGP.TLInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
516 CGP.TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
517 CGP.LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
518 CGP.BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
519 CGP.BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
520 CGP.PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
522 getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
523 CGP.BBSectionsProfileReader = BBSPRWP ? &BBSPRWP->getBBSPR() :
nullptr;
524 DomTreeUpdater DTUpdater(
525 &getAnalysis<DominatorTreeWrapperPass>().
getDomTree(),
526 DomTreeUpdater::UpdateStrategy::Lazy);
527 CGP.DTU = &DTUpdater;
533 "Optimize for code generation",
false,
false)
545 return new CodeGenPrepareLegacyPass();
550 CodeGenPrepare CGP(TM);
563 DL = &
F.getDataLayout();
576 "analysis to be available");
577 BBSectionsProfileReader =
580 DomTreeUpdater::UpdateStrategy::Lazy);
586 bool EverMadeChange =
false;
588 OptSize =
F.hasOptSize();
593 (void)
F.setSectionPrefix(
"hot");
598 if (
F.hasFnAttribute(Attribute::Hot) ||
599 PSI->isFunctionHotInCallGraph(&
F, *BFI))
600 (void)
F.setSectionPrefix(
"hot");
604 else if (PSI->isFunctionColdInCallGraph(&
F, *BFI) ||
605 F.hasFnAttribute(Attribute::Cold))
606 (void)
F.setSectionPrefix(
"unlikely");
608 PSI->isFunctionHotnessUnknown(
F))
609 (void)
F.setSectionPrefix(
"unknown");
615 const DenseMap<unsigned int, unsigned int> &BypassWidths =
618 while (BB !=
nullptr) {
631 EverMadeChange |= eliminateAssumptions(
F);
633 auto resetLoopInfo = [
this]() {
640 bool ResetLI =
false;
641 EverMadeChange |= eliminateMostlyEmptyBlocks(
F, ResetLI);
646 EverMadeChange |= splitBranchCondition(
F);
652 EverMadeChange |=
Split;
658 assert(getDT().
verify(DominatorTree::VerificationLevel::Fast) &&
659 "Incorrect DominatorTree updates in CGP");
669 bool MadeChange =
true;
670 bool FuncIterated =
false;
680 if (FuncIterated && !FreshBBs.
contains(&BB))
683 ModifyDT ModifiedDTOnIteration = ModifyDT::NotModifyDT;
699 else if (FuncIterated)
704 if (ModifiedDTOnIteration != ModifyDT::NotModifyDT)
709 FuncIterated = IsHugeFunc;
712 MadeChange |= mergeSExts(
F);
713 if (!LargeOffsetGEPMap.
empty())
714 MadeChange |= splitLargeGEPOffsets();
715 MadeChange |= optimizePhiTypes(
F);
718 eliminateFallThrough(
F);
722 assert(getDT().
verify(DominatorTree::VerificationLevel::Fast) &&
723 "Incorrect DominatorTree updates in CGP");
730 for (Instruction *
I : RemovedInsts)
733 EverMadeChange |= MadeChange;
734 SeenChainsForSExt.
clear();
735 ValToSExtendedUses.clear();
736 RemovedInsts.clear();
737 LargeOffsetGEPMap.
clear();
738 LargeOffsetGEPID.
clear();
752 SmallSetVector<BasicBlock *, 8> WorkList;
753 for (BasicBlock &BB :
F) {
759 for (BasicBlock *Succ : Successors)
765 MadeChange |= !WorkList.
empty();
766 while (!WorkList.
empty()) {
772 for (BasicBlock *Succ : Successors)
782 if (EverMadeChange || MadeChange)
783 MadeChange |= eliminateFallThrough(
F);
785 EverMadeChange |= MadeChange;
790 for (BasicBlock &BB :
F)
791 for (Instruction &
I : BB)
794 for (
auto &
I : Statepoints)
795 EverMadeChange |= simplifyOffsetableRelocate(*
I);
800 EverMadeChange |= placeDbgValues(
F);
801 EverMadeChange |= placePseudoProbes(
F);
808 return EverMadeChange;
811bool CodeGenPrepare::eliminateAssumptions(
Function &
F) {
812 bool MadeChange =
false;
813 for (BasicBlock &BB :
F) {
814 CurInstIterator = BB.begin();
815 while (CurInstIterator != BB.end()) {
820 Assume->eraseFromParent();
822 resetIteratorIfInvalidatedWhileCalling(&BB, [&]() {
833void CodeGenPrepare::removeAllAssertingVHReferences(
Value *V) {
834 LargeOffsetGEPMap.
erase(V);
835 NewGEPBases.
erase(V);
843 auto VecI = LargeOffsetGEPMap.
find(
GEP->getPointerOperand());
844 if (VecI == LargeOffsetGEPMap.
end())
847 auto &GEPVector = VecI->second;
850 if (GEPVector.empty())
851 LargeOffsetGEPMap.
erase(VecI);
855[[maybe_unused]]
void CodeGenPrepare::verifyBFIUpdates(
Function &
F) {
856 DominatorTree NewDT(
F);
859 BranchProbabilityInfo NewBPI(
F, NewCI, TLInfo);
860 BlockFrequencyInfo NewBFI(
F, NewBPI, NewCI);
861 NewBFI.verifyMatch(*BFI);
867bool CodeGenPrepare::eliminateFallThrough(
Function &
F) {
869 SmallPtrSet<BasicBlock *, 8> Preds;
877 BasicBlock *SinglePred = BB->getSinglePredecessor();
880 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
893 FreshBBs.
insert(SinglePred);
901 for (
auto *Pred : Preds)
909BasicBlock *CodeGenPrepare::findDestBlockOfMergeableEmptyBlock(BasicBlock *BB) {
918 if (BBI != BB->
begin()) {
929 if (!canMergeBlocks(BB, DestBB))
939bool CodeGenPrepare::eliminateMostlyEmptyBlocks(
Function &
F,
bool &ResetLI) {
940 SmallPtrSet<BasicBlock *, 16> Preheaders;
942 while (!LoopList.empty()) {
943 Loop *
L = LoopList.pop_back_val();
945 if (BasicBlock *Preheader =
L->getLoopPreheader())
946 Preheaders.
insert(Preheader);
950 bool MadeChange =
false;
951 SmallPtrSet<PHINode *, 32> KnownNonDeadPHIs;
963 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
965 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.
count(BB)))
968 ResetLI |= eliminateMostlyEmptyBlock(BB);
974bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB,
1025 SmallPtrSet<BasicBlock *, 16> SameIncomingValueBBs;
1030 if (DestBBPred == BB)
1034 return DestPN.getIncomingValueForBlock(BB) ==
1035 DestPN.getIncomingValueForBlock(DestBBPred);
1037 SameIncomingValueBBs.
insert(DestBBPred);
1043 if (SameIncomingValueBBs.
count(Pred))
1046 BlockFrequency PredFreq = BFI->getBlockFreq(Pred);
1047 BlockFrequency
BBFreq = BFI->getBlockFreq(BB);
1049 for (
auto *SameValueBB : SameIncomingValueBBs)
1050 if (SameValueBB->getUniquePredecessor() == Pred &&
1051 DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
1052 BBFreq += BFI->getBlockFreq(SameValueBB);
1055 return !Limit || PredFreq <= *Limit;
1061bool CodeGenPrepare::canMergeBlocks(
const BasicBlock *BB,
1062 const BasicBlock *DestBB)
const {
1066 for (
const PHINode &PN : BB->
phis()) {
1067 for (
const User *U : PN.users()) {
1076 for (
unsigned I = 0,
E = UPN->getNumIncomingValues();
I !=
E; ++
I) {
1079 Insn->
getParent() != UPN->getIncomingBlock(
I))
1094 SmallPtrSet<const BasicBlock *, 16> BBPreds;
1097 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1098 BBPreds.
insert(BBPN->getIncomingBlock(i));
1106 if (BBPreds.
count(Pred)) {
1107 for (
const PHINode &PN : DestBB->
phis()) {
1108 const Value *
V1 = PN.getIncomingValueForBlock(Pred);
1109 const Value *V2 = PN.getIncomingValueForBlock(BB);
1113 if (V2PN->getParent() == BB)
1114 V2 = V2PN->getIncomingValueForBlock(Pred);
1133 E = OldI->user_end();
1146bool CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
1156 if (SinglePred != DestBB) {
1157 assert(SinglePred == BB &&
1158 "Single predecessor not the same as predecessor");
1167 FreshBBs.
insert(SinglePred);
1168 FreshBBs.
erase(DestBB);
1176 for (PHINode &PN : DestBB->
phis()) {
1178 Value *InVal = PN.removeIncomingValue(BB,
false);
1183 if (InValPhi && InValPhi->
getParent() == BB) {
1192 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1193 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1196 PN.addIncoming(InVal, Pred);
1210 SmallPtrSet<BasicBlock *, 8> SeenPreds;
1214 if (!PredOfDestBB.contains(Pred)) {
1215 if (SeenPreds.
insert(Pred).second)
1216 DTUpdates.
push_back({DominatorTree::Insert, Pred, DestBB});
1221 if (SeenPreds.
insert(Pred).second)
1222 DTUpdates.
push_back({DominatorTree::Delete, Pred, BB});
1224 DTUpdates.
push_back({DominatorTree::Delete, BB, DestBB});
1244 for (
auto *ThisRelocate : AllRelocateCalls) {
1245 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1246 ThisRelocate->getDerivedPtrIndex());
1247 RelocateIdxMap.
insert(std::make_pair(
K, ThisRelocate));
1249 for (
auto &Item : RelocateIdxMap) {
1250 std::pair<unsigned, unsigned>
Key = Item.first;
1251 if (
Key.first ==
Key.second)
1256 auto BaseKey = std::make_pair(
Key.first,
Key.first);
1259 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1260 if (MaybeBase == RelocateIdxMap.
end())
1265 RelocateInstMap[MaybeBase->second].push_back(
I);
1273 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1276 if (!
Op ||
Op->getZExtValue() > 20)
1280 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1290 bool MadeChange =
false;
1297 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1298 &*R != RelocatedBase; ++R)
1302 RelocatedBase->
moveBefore(RI->getIterator());
1309 "Not relocating a derived object of the original base object");
1310 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1315 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1325 if (!Derived || Derived->getPointerOperand() !=
Base)
1334 "Should always have one since it's not a terminator");
1338 Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
1362 Value *ActualRelocatedBase = RelocatedBase;
1363 if (RelocatedBase->
getType() !=
Base->getType()) {
1364 ActualRelocatedBase =
1365 Builder.CreateBitCast(RelocatedBase,
Base->getType());
1367 Value *Replacement =
1368 Builder.CreateGEP(Derived->getSourceElementType(), ActualRelocatedBase,
1374 Value *ActualReplacement = Replacement;
1375 if (Replacement->
getType() != ToReplace->getType()) {
1377 Builder.CreateBitCast(Replacement, ToReplace->
getType());
1380 ToReplace->eraseFromParent();
1404bool CodeGenPrepare::simplifyOffsetableRelocate(GCStatepointInst &
I) {
1405 bool MadeChange =
false;
1407 for (
auto *U :
I.users())
1414 if (AllRelocateCalls.
size() < 2)
1419 MapVector<GCRelocateInst *, SmallVector<GCRelocateInst *, 0>> RelocateInstMap;
1421 if (RelocateInstMap.
empty())
1424 for (
auto &Item : RelocateInstMap)
1438 bool MadeChange =
false;
1441 Use &TheUse = UI.getUse();
1448 UserBB = PN->getIncomingBlock(TheUse);
1456 if (
User->isEHPad())
1466 if (UserBB == DefBB)
1470 CastInst *&InsertedCast = InsertedCasts[UserBB];
1472 if (!InsertedCast) {
1480 TheUse = InsertedCast;
1499 if (!SrcInst || SrcInst->getParent() == BCI->
getParent() ||
1500 SrcInst->isTerminator())
1504 Type *SrcTy = SrcInst->getType();
1518 bool IsCrossDomain = DestTy->
isFPOrFPVectorTy() != SrcTy->isFPOrFPVectorTy();
1521 unsigned NativeWidth =
DL.getPointerSizeInBits();
1522 bool IsLargeScalar =
1524 DL.getTypeSizeInBits(DestTy).getFixedValue() > NativeWidth;
1526 if (IsCrossDomain || IsLargeScalar)
1532 : std::next(SrcInst->getIterator());
1549 ASC->getDestAddressSpace()))
1604static std::optional<std::pair<Instruction *, Constant *>>
1607 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1608 return std::nullopt;
1611 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1612 return std::nullopt;
1616 return std::make_pair(IVInc, Step);
1617 return std::nullopt;
1630 return IVInc->first ==
I;
1634bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
1638 auto IsReplacableIVIncrement = [
this, &
Cmp](BinaryOperator *BO) {
1642 assert(L &&
"L should not be null after isIVIncrement()");
1644 if (LI->getLoopFor(
Cmp->getParent()) != L)
1657 return BO->
hasOneUse() && DT.dominates(
Cmp->getParent(),
L->getLoopLatch());
1659 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1682 if (BO->
getOpcode() == Instruction::Add &&
1683 IID == Intrinsic::usub_with_overflow) {
1690 for (Instruction &Iter : *
Cmp->getParent()) {
1693 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1698 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1701 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1702 if (BO->
getOpcode() != Instruction::Xor) {
1703 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1707 "Patterns with XOr should use the BO only in the compare");
1708 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1710 Cmp->eraseFromParent();
1720 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1728 B = ConstantInt::get(
B->getType(), 1);
1736 for (
User *U :
A->users()) {
1747bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp,
1748 ModifyDT &ModifiedDT) {
1749 bool EdgeCase =
false;
1751 BinaryOperator *
Add;
1756 A =
Add->getOperand(0);
1757 B =
Add->getOperand(1);
1763 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1769 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1772 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1773 Intrinsic::uadd_with_overflow))
1777 ModifiedDT = ModifyDT::ModifyInstDT;
1781bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
1782 ModifyDT &ModifiedDT) {
1789 ICmpInst::Predicate Pred =
Cmp->getPredicate();
1790 if (Pred == ICmpInst::ICMP_UGT) {
1792 Pred = ICmpInst::ICMP_ULT;
1796 B = ConstantInt::get(
B->getType(), 1);
1797 Pred = ICmpInst::ICMP_ULT;
1802 Pred = ICmpInst::ICMP_ULT;
1804 if (Pred != ICmpInst::ICMP_ULT)
1811 BinaryOperator *
Sub =
nullptr;
1812 for (User *U : CmpVariableOperand->
users()) {
1820 const APInt *CmpC, *AddC;
1832 Sub->hasNUsesOrMore(1)))
1838 if (
Sub->getParent() !=
Cmp->getParent() && !
Sub->hasOneUse())
1841 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1842 Cmp, Intrinsic::usub_with_overflow))
1846 ModifiedDT = ModifyDT::ModifyInstDT;
1853bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1866 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1872 Type *OpTy =
X->getType();
1880 if (Pred == ICmpInst::ICMP_EQ) {
1881 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1882 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1884 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1890 if (IsPowerOf2OrZeroTest ||
1901 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1910 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1913 Cmp->replaceAllUsesWith(NewCmp);
1933 bool UsedInPhiOrCurrentBlock =
any_of(Cmp->users(), [Cmp](
User *U) {
1934 return isa<PHINode>(U) ||
1935 cast<Instruction>(U)->getParent() == Cmp->getParent();
1940 if (UsedInPhiOrCurrentBlock && Cmp->getOperand(0)->getType()->isIntegerTy() &&
1941 Cmp->getOperand(0)->getType()->getScalarSizeInBits() >
1942 DL.getLargestLegalIntTypeSizeInBits())
1948 bool MadeChange =
false;
1951 Use &TheUse = UI.getUse();
1966 if (UserBB == DefBB)
1970 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1976 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1983 TheUse = InsertedCmp;
1989 if (Cmp->use_empty()) {
1990 Cmp->eraseFromParent();
2027 for (
User *U : Cmp->users()) {
2049 if (CmpBB != FalseBB)
2052 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
2066 for (
User *U : Cmp->users()) {
2068 BI->swapSuccessors();
2074 SI->swapProfMetadata();
2086 Value *Op0 = Cmp->getOperand(0);
2087 Value *Op1 = Cmp->getOperand(1);
2096 unsigned NumInspected = 0;
2099 if (++NumInspected > 128)
2107 if (GoodToSwap > 0) {
2108 Cmp->swapOperands();
2128 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
2131 auto [ClassVal, ClassTest] =
2137 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2141 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
2142 Cmp->replaceAllUsesWith(IsFPClass);
2150 Value *Incr, *RemAmt;
2155 Value *AddInst, *AddOffset;
2158 if (PN !=
nullptr) {
2160 AddOffset =
nullptr;
2178 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2182 if (!L->contains(Rem))
2186 if (!L->isLoopInvariant(RemAmt))
2190 if (AddOffset && !L->isLoopInvariant(AddOffset))
2211 AddInstOut = AddInst;
2212 AddOffsetOut = AddOffset;
2231 Value *AddOffset, *RemAmt, *AddInst;
2234 AddOffset, LoopIncrPN))
2259 assert(AddOffset &&
"We found an add but missing values");
2277 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2282 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2287 NewRem->
addIncoming(Start, L->getLoopPreheader());
2292 FreshBBs.
insert(L->getLoopLatch());
2303bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2309bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2313 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2316 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2319 if (unfoldPowerOf2Test(Cmp))
2340 SetOfInstrs &InsertedInsts) {
2343 assert(!InsertedInsts.count(AndI) &&
2344 "Attempting to optimize already optimized and instruction");
2345 (void)InsertedInsts;
2359 for (
auto *U : AndI->
users()) {
2367 if (!CmpC || !CmpC->
isZero())
2382 Use &TheUse = UI.getUse();
2400 TheUse = InsertedAnd;
2417 if (
User->getOpcode() != Instruction::And ||
2423 if ((Cimm & (Cimm + 1)).getBoolValue())
2437 bool MadeChange =
false;
2440 TruncE = TruncI->user_end();
2441 TruncUI != TruncE;) {
2443 Use &TruncTheUse = TruncUI.getUse();
2468 if (UserBB == TruncUserBB)
2472 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2474 if (!InsertedShift && !InsertedTrunc) {
2478 if (ShiftI->
getOpcode() == Instruction::AShr)
2480 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2483 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2491 TruncInsertPt.setHeadBit(
true);
2492 assert(TruncInsertPt != TruncUserBB->
end());
2496 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2497 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2501 TruncTheUse = InsertedTrunc;
2534 bool MadeChange =
false;
2538 Use &TheUse = UI.getUse();
2552 if (UserBB == DefBB) {
2580 if (!InsertedShift) {
2584 if (ShiftI->
getOpcode() == Instruction::AShr)
2586 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2589 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2597 TheUse = InsertedShift;
2645 unsigned SizeInBits = Ty->getScalarSizeInBits();
2646 if (Ty->isVectorTy())
2657 nullptr,
"cond.false");
2659 FreshBBs.
insert(CallBlock);
2666 SplitPt.setHeadBit(
true);
2668 nullptr,
"cond.end");
2670 FreshBBs.
insert(EndBlock);
2674 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2681 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2682 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2683 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2689 Builder.SetInsertPoint(EndBlock, EndBlock->
begin());
2690 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2700 ModifiedDT = ModifyDT::ModifyBBDT;
2704bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2708 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2716 for (
auto &Arg : CI->
args()) {
2721 if (!Arg->getType()->isPointerTy())
2723 APInt
Offset(
DL->getIndexSizeInBits(
2726 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2733 if (AllocaSize && AllocaSize->getKnownMinValue() >= MinSize + Offset2)
2751 MaybeAlign MIDestAlign =
MI->getDestAlign();
2752 if (!MIDestAlign || DestAlign > *MIDestAlign)
2753 MI->setDestAlignment(DestAlign);
2755 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2757 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2758 MTI->setSourceAlignment(SrcAlign);
2768 for (
auto &Arg : CI->
args()) {
2769 if (!Arg->getType()->isPointerTy())
2771 unsigned AS = Arg->getType()->getPointerAddressSpace();
2772 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2778 switch (
II->getIntrinsicID()) {
2781 case Intrinsic::assume:
2783 case Intrinsic::allow_runtime_check:
2784 case Intrinsic::allow_ubsan_check:
2785 case Intrinsic::experimental_widenable_condition: {
2789 if (
II->use_empty()) {
2790 II->eraseFromParent();
2794 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2799 case Intrinsic::objectsize:
2801 case Intrinsic::is_constant:
2803 case Intrinsic::aarch64_stlxr:
2804 case Intrinsic::aarch64_stxr: {
2813 InsertedInsts.insert(ExtVal);
2817 case Intrinsic::launder_invariant_group: {
2818 Value *ArgVal =
II->getArgOperand(0);
2819 auto it = LargeOffsetGEPMap.
find(
II);
2820 if (it != LargeOffsetGEPMap.
end()) {
2824 auto GEPs = std::move(it->second);
2825 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2830 II->eraseFromParent();
2833 case Intrinsic::cttz:
2834 case Intrinsic::ctlz:
2838 case Intrinsic::fshl:
2839 case Intrinsic::fshr:
2840 return optimizeFunnelShift(
II);
2841 case Intrinsic::masked_gather:
2842 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2843 case Intrinsic::masked_scatter:
2844 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2845 case Intrinsic::masked_load:
2848 if (VT->getNumElements() == 1) {
2849 Value *PtrVal =
II->getArgOperand(0);
2851 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2856 case Intrinsic::masked_store:
2860 if (VT->getNumElements() == 1) {
2861 Value *PtrVal =
II->getArgOperand(1);
2863 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2868 case Intrinsic::umul_with_overflow:
2869 return optimizeMulWithOverflow(
II,
false, ModifiedDT);
2870 case Intrinsic::smul_with_overflow:
2871 return optimizeMulWithOverflow(
II,
true, ModifiedDT);
2874 SmallVector<Value *, 2> PtrOps;
2877 while (!PtrOps.
empty()) {
2880 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2894 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2896 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2906 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2907 if (!
F->getReturnType()->isPointerTy())
2910 GlobalVariable *UniformValue =
nullptr;
2911 for (
auto &BB : *
F) {
2916 else if (V != UniformValue)
2924 return UniformValue;
2927 if (
Callee->hasExactDefinition()) {
2928 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2929 bool MadeChange =
false;
2955 switch (
II->getIntrinsicID()) {
2956 case Intrinsic::memset:
2957 case Intrinsic::memcpy:
2958 case Intrinsic::memmove:
2965 if (Callee && TLInfo)
2967 case LibFunc_strcpy:
2968 case LibFunc_strncpy:
2969 case LibFunc_strcat:
2970 case LibFunc_strncat:
3011bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
3012 ModifyDT &ModifiedDT) {
3020 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
3022 PHINode *PN =
nullptr;
3023 ExtractValueInst *EVI =
nullptr;
3024 BitCastInst *BCI =
nullptr;
3044 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
3050 return II->getIntrinsicID() == Intrinsic::lifetime_end;
3056 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
3058 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
3080 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
3087 auto MayBePermittedAsTailCall = [&](
const auto *CI) {
3104 MayBePermittedAsTailCall(CI)) {
3125 MayBePermittedAsTailCall(CI)) {
3132 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
3134 if (!VisitedBBs.
insert(Pred).second)
3136 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
3138 if (CI && CI->
use_empty() && MayBePermittedAsTailCall(CI)) {
3153 for (
auto const &TailCallBB : TailCallBBs) {
3163 BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB));
3164 BFI->setBlockFreq(BB,
3165 (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB)));
3166 ModifiedDT = ModifyDT::ModifyBBDT;
3175 for (
auto *CI : CallInsts) {
3176 for (
auto const *FakeUse : FakeUses) {
3177 auto *ClonedInst = FakeUse->clone();
3195struct ExtAddrMode :
public TargetLowering::AddrMode {
3196 Value *BaseReg =
nullptr;
3197 Value *ScaledReg =
nullptr;
3198 Value *OriginalValue =
nullptr;
3199 bool InBounds =
true;
3203 BaseRegField = 0x01,
3205 BaseOffsField = 0x04,
3206 ScaledRegField = 0x08,
3208 MultipleFields = 0xff
3211 ExtAddrMode() =
default;
3213 void print(raw_ostream &OS)
const;
3220 if (ScaledReg == From)
3224 FieldName
compare(
const ExtAddrMode &other) {
3227 if (BaseReg && other.
BaseReg &&
3229 return MultipleFields;
3230 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3231 return MultipleFields;
3234 return MultipleFields;
3237 if (InBounds != other.InBounds)
3238 return MultipleFields;
3241 unsigned Result = NoField;
3244 if (BaseGV != other.BaseGV)
3246 if (BaseOffs != other.BaseOffs)
3249 Result |= ScaledRegField;
3252 if (Scale && other.
Scale && Scale != other.
Scale)
3256 return MultipleFields;
3258 return static_cast<FieldName
>(
Result);
3268 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3279 case ScaledRegField:
3286 void SetCombinedField(FieldName
Field,
Value *V,
3287 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3292 case ExtAddrMode::BaseRegField:
3295 case ExtAddrMode::BaseGVField:
3298 assert(BaseReg ==
nullptr);
3302 case ExtAddrMode::ScaledRegField:
3307 for (
const ExtAddrMode &AM : AddrModes)
3313 case ExtAddrMode::BaseOffsField:
3316 assert(ScaledReg ==
nullptr);
3326static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3332#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3333void ExtAddrMode::print(raw_ostream &OS)
const {
3334 bool NeedPlus =
false;
3340 BaseGV->printAsOperand(OS,
false);
3345 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3350 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3351 BaseReg->printAsOperand(OS,
false);
3355 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3378class TypePromotionTransaction {
3382 class TypePromotionAction {
3390 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3392 virtual ~TypePromotionAction() =
default;
3399 virtual void undo() = 0;
3404 virtual void commit() {
3410 class InsertionHandler {
3419 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3422 bool HasPrevInstruction;
3426 InsertionHandler(Instruction *Inst) {
3434 if (HasPrevInstruction) {
3442 void insert(Instruction *Inst) {
3443 if (HasPrevInstruction) {
3455 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3460 class OperandSetter :
public TypePromotionAction {
3469 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3470 : TypePromotionAction(Inst), Idx(Idx) {
3472 <<
"for:" << *Inst <<
"\n"
3473 <<
"with:" << *NewVal <<
"\n");
3479 void undo()
override {
3481 <<
"for: " << *Inst <<
"\n"
3482 <<
"with: " << *Origin <<
"\n");
3489 class OperandsHider :
public TypePromotionAction {
3491 SmallVector<Value *, 4> OriginalValues;
3495 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3498 OriginalValues.
reserve(NumOpnds);
3499 for (
unsigned It = 0; It < NumOpnds; ++It) {
3511 void undo()
override {
3513 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3519 class TruncBuilder :
public TypePromotionAction {
3526 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3528 Builder.SetCurrentDebugLocation(
DebugLoc());
3529 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3534 Value *getBuiltValue() {
return Val; }
3537 void undo()
override {
3540 IVal->eraseFromParent();
3545 class SExtBuilder :
public TypePromotionAction {
3552 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3553 : TypePromotionAction(InsertPt) {
3555 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3560 Value *getBuiltValue() {
return Val; }
3563 void undo()
override {
3566 IVal->eraseFromParent();
3571 class ZExtBuilder :
public TypePromotionAction {
3578 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3579 : TypePromotionAction(InsertPt) {
3581 Builder.SetCurrentDebugLocation(
DebugLoc());
3582 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3587 Value *getBuiltValue() {
return Val; }
3590 void undo()
override {
3593 IVal->eraseFromParent();
3598 class TypeMutator :
public TypePromotionAction {
3604 TypeMutator(Instruction *Inst,
Type *NewTy)
3605 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3606 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3612 void undo()
override {
3613 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3620 class UsesReplacer :
public TypePromotionAction {
3622 struct InstructionAndIdx {
3629 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3630 : Inst(Inst), Idx(Idx) {}
3636 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3646 UsesReplacer(Instruction *Inst,
Value *New)
3647 : TypePromotionAction(Inst),
New(
New) {
3648 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3651 for (Use &U : Inst->
uses()) {
3653 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3664 void undo()
override {
3666 for (InstructionAndIdx &Use : OriginalUses)
3667 Use.Inst->setOperand(
Use.Idx, Inst);
3672 for (DbgVariableRecord *DVR : DbgVariableRecords)
3673 DVR->replaceVariableLocationOp(New, Inst);
3678 class InstructionRemover :
public TypePromotionAction {
3680 InsertionHandler Inserter;
3684 OperandsHider Hider;
3687 UsesReplacer *Replacer =
nullptr;
3690 SetOfInstrs &RemovedInsts;
3697 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3698 Value *New =
nullptr)
3699 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3700 RemovedInsts(RemovedInsts) {
3702 Replacer =
new UsesReplacer(Inst, New);
3703 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3704 RemovedInsts.insert(Inst);
3711 ~InstructionRemover()
override {
delete Replacer; }
3713 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3714 InstructionRemover(
const InstructionRemover &other) =
delete;
3718 void undo()
override {
3719 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3720 Inserter.insert(Inst);
3724 RemovedInsts.erase(Inst);
3732 using ConstRestorationPt =
const TypePromotionAction *;
3734 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3735 : RemovedInsts(RemovedInsts) {}
3742 void rollback(ConstRestorationPt Point);
3745 ConstRestorationPt getRestorationPoint()
const;
3750 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3759 void mutateType(Instruction *Inst,
Type *NewTy);
3762 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3775 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3777 SetOfInstrs &RemovedInsts;
3782void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3784 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3785 Inst, Idx, NewVal));
3788void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3791 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3792 Inst, RemovedInsts, NewVal));
3795void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3798 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3801void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3803 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3806Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3807 std::unique_ptr<TruncBuilder> Ptr(
new TruncBuilder(Opnd, Ty));
3808 Value *Val = Ptr->getBuiltValue();
3809 Actions.push_back(std::move(Ptr));
3813Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3815 std::unique_ptr<SExtBuilder> Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3816 Value *Val = Ptr->getBuiltValue();
3817 Actions.push_back(std::move(Ptr));
3821Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3823 std::unique_ptr<ZExtBuilder> Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3824 Value *Val = Ptr->getBuiltValue();
3825 Actions.push_back(std::move(Ptr));
3829TypePromotionTransaction::ConstRestorationPt
3830TypePromotionTransaction::getRestorationPoint()
const {
3831 return !Actions.empty() ? Actions.back().get() :
nullptr;
3834bool TypePromotionTransaction::commit() {
3835 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3842void TypePromotionTransaction::rollback(
3843 TypePromotionTransaction::ConstRestorationPt Point) {
3844 while (!Actions.empty() && Point != Actions.back().get()) {
3845 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3855class AddressingModeMatcher {
3856 SmallVectorImpl<Instruction *> &AddrModeInsts;
3857 const TargetLowering &TLI;
3858 const TargetRegisterInfo &
TRI;
3859 const DataLayout &
DL;
3861 const std::function<
const DominatorTree &()> getDTFn;
3874 const SetOfInstrs &InsertedInsts;
3877 InstrToOrigTy &PromotedInsts;
3880 TypePromotionTransaction &TPT;
3883 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3887 bool IgnoreProfitability;
3890 bool OptSize =
false;
3892 ProfileSummaryInfo *PSI;
3893 BlockFrequencyInfo *BFI;
3895 AddressingModeMatcher(
3896 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3897 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3898 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3899 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3900 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3901 TypePromotionTransaction &TPT,
3902 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3903 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI)
3904 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3905 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3906 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3907 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3908 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI), BFI(BFI) {
3909 IgnoreProfitability =
false;
3921 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3922 SmallVectorImpl<Instruction *> &AddrModeInsts,
3923 const TargetLowering &TLI,
const LoopInfo &LI,
3924 const std::function<
const DominatorTree &()> getDTFn,
3925 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3926 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3927 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3928 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
3931 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3932 AccessTy, AS, MemoryInst, Result,
3933 InsertedInsts, PromotedInsts, TPT,
3934 LargeOffsetGEP, OptSize, PSI, BFI)
3942 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3944 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3945 bool *MovedAway =
nullptr);
3946 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3947 ExtAddrMode &AMBefore,
3948 ExtAddrMode &AMAfter);
3949 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3950 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3951 Value *PromotedOperand)
const;
3957class PhiNodeSetIterator {
3958 PhiNodeSet *
const Set;
3959 size_t CurrentIndex = 0;
3964 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3966 PhiNodeSetIterator &operator++();
3982 friend class PhiNodeSetIterator;
3984 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3985 using iterator = PhiNodeSetIterator;
4000 size_t FirstValidElement = 0;
4006 bool insert(PHINode *Ptr) {
4007 if (NodeMap.insert(std::make_pair(Ptr,
NodeList.
size())).second) {
4017 bool erase(PHINode *Ptr) {
4018 if (NodeMap.erase(Ptr)) {
4019 SkipRemovedElements(FirstValidElement);
4029 FirstValidElement = 0;
4035 if (FirstValidElement == 0)
4036 SkipRemovedElements(FirstValidElement);
4037 return PhiNodeSetIterator(
this, FirstValidElement);
4044 size_t size()
const {
return NodeMap.size(); }
4047 size_t count(PHINode *Ptr)
const {
return NodeMap.count(Ptr); }
4055 void SkipRemovedElements(
size_t &CurrentIndex) {
4057 auto it = NodeMap.find(NodeList[CurrentIndex]);
4060 if (it != NodeMap.end() && it->second == CurrentIndex)
4067PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
4070PHINode *PhiNodeSetIterator::operator*()
const {
4072 "PhiNodeSet access out of range");
4073 return Set->NodeList[CurrentIndex];
4076PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
4078 "PhiNodeSet access out of range");
4080 Set->SkipRemovedElements(CurrentIndex);
4084bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
4085 return CurrentIndex ==
RHS.CurrentIndex;
4088bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
4089 return !((*this) ==
RHS);
4095class SimplificationTracker {
4096 DenseMap<Value *, Value *> Storage;
4099 PhiNodeSet AllPhiNodes;
4101 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
4106 auto SV = Storage.
find(V);
4107 if (SV == Storage.
end())
4115 void ReplacePhi(PHINode *From, PHINode *To) {
4116 Value *OldReplacement = Get(From);
4117 while (OldReplacement != From) {
4120 OldReplacement = Get(From);
4122 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
4125 AllPhiNodes.erase(From);
4129 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
4131 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
4133 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
4135 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4137 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4139 void destroyNewNodes(
Type *CommonType) {
4142 for (
auto *
I : AllPhiNodes) {
4143 I->replaceAllUsesWith(Dummy);
4144 I->eraseFromParent();
4146 AllPhiNodes.clear();
4147 for (
auto *
I : AllSelectNodes) {
4148 I->replaceAllUsesWith(Dummy);
4149 I->eraseFromParent();
4151 AllSelectNodes.clear();
4156class AddressingModeCombiner {
4157 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4158 typedef std::pair<PHINode *, PHINode *> PHIPair;
4165 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4168 bool AllAddrModesTrivial =
true;
4171 Type *CommonType =
nullptr;
4173 const DataLayout &
DL;
4179 Value *CommonValue =
nullptr;
4182 AddressingModeCombiner(
const DataLayout &
DL,
Value *OriginalValue)
4183 :
DL(
DL), Original(OriginalValue) {}
4185 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4188 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4193 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4197 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4200 if (AddrModes.
empty()) {
4208 ExtAddrMode::FieldName ThisDifferentField =
4209 AddrModes[0].compare(NewAddrMode);
4210 if (DifferentField == ExtAddrMode::NoField)
4211 DifferentField = ThisDifferentField;
4212 else if (DifferentField != ThisDifferentField)
4213 DifferentField = ExtAddrMode::MultipleFields;
4216 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4219 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4224 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4229 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4230 !NewAddrMode.HasBaseReg);
4247 bool combineAddrModes() {
4249 if (AddrModes.
size() == 0)
4253 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4258 if (AllAddrModesTrivial)
4261 if (!addrModeCombiningAllowed())
4267 FoldAddrToValueMapping
Map;
4268 if (!initializeMap(Map))
4271 CommonValue = findCommon(Map);
4273 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4274 return CommonValue !=
nullptr;
4280 void eraseCommonValueIfDead() {
4281 if (CommonValue && CommonValue->
use_empty())
4283 CommonInst->eraseFromParent();
4291 bool initializeMap(FoldAddrToValueMapping &Map) {
4294 SmallVector<Value *, 2> NullValue;
4296 for (
auto &AM : AddrModes) {
4300 if (CommonType && CommonType !=
Type)
4303 Map[AM.OriginalValue] = DV;
4308 assert(CommonType &&
"At least one non-null value must be!");
4309 for (
auto *V : NullValue)
4337 Value *findCommon(FoldAddrToValueMapping &Map) {
4345 SimplificationTracker
ST;
4350 InsertPlaceholders(Map, TraverseOrder, ST);
4353 FillPlaceholders(Map, TraverseOrder, ST);
4356 ST.destroyNewNodes(CommonType);
4361 unsigned PhiNotMatchedCount = 0;
4363 ST.destroyNewNodes(CommonType);
4367 auto *
Result =
ST.Get(
Map.find(Original)->second);
4369 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4370 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4377 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4378 SmallSetVector<PHIPair, 8> &Matcher,
4379 PhiNodeSet &PhiNodesToMatch) {
4382 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4385 SmallSet<PHIPair, 8> Visited;
4386 while (!WorkList.
empty()) {
4388 if (!Visited.
insert(Item).second)
4395 for (
auto *
B : Item.first->blocks()) {
4396 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4397 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4398 if (FirstValue == SecondValue)
4408 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4413 if (Matcher.
count({FirstPhi, SecondPhi}))
4418 if (MatchedPHIs.
insert(FirstPhi).second)
4419 Matcher.
insert({FirstPhi, SecondPhi});
4421 WorkList.
push_back({FirstPhi, SecondPhi});
4430 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4431 unsigned &PhiNotMatchedCount) {
4435 SmallSetVector<PHIPair, 8> Matched;
4436 SmallPtrSet<PHINode *, 8> WillNotMatch;
4437 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4438 while (PhiNodesToMatch.size()) {
4439 PHINode *
PHI = *PhiNodesToMatch.begin();
4442 WillNotMatch.
clear();
4446 bool IsMatched =
false;
4447 for (
auto &
P :
PHI->getParent()->phis()) {
4449 if (PhiNodesToMatch.count(&
P))
4451 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4461 for (
auto MV : Matched)
4462 ST.ReplacePhi(MV.first, MV.second);
4467 if (!AllowNewPhiNodes)
4470 PhiNotMatchedCount += WillNotMatch.
size();
4471 for (
auto *
P : WillNotMatch)
4472 PhiNodesToMatch.erase(
P);
4477 void FillPlaceholders(FoldAddrToValueMapping &Map,
4478 SmallVectorImpl<Value *> &TraverseOrder,
4479 SimplificationTracker &ST) {
4480 while (!TraverseOrder.
empty()) {
4482 assert(
Map.contains(Current) &&
"No node to fill!!!");
4488 auto *TrueValue = CurrentSelect->getTrueValue();
4489 assert(
Map.contains(TrueValue) &&
"No True Value!");
4490 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4491 auto *FalseValue = CurrentSelect->getFalseValue();
4492 assert(
Map.contains(FalseValue) &&
"No False Value!");
4493 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4500 assert(
Map.contains(PV) &&
"No predecessor Value!");
4501 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4512 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4513 SmallVectorImpl<Value *> &TraverseOrder,
4514 SimplificationTracker &ST) {
4517 "Address must be a Phi or Select node");
4520 while (!Worklist.
empty()) {
4523 if (
Map.contains(Current))
4534 CurrentSelect->getName(),
4535 CurrentSelect->getIterator(), CurrentSelect);
4539 Worklist.
push_back(CurrentSelect->getTrueValue());
4540 Worklist.
push_back(CurrentSelect->getFalseValue());
4548 ST.insertNewPhi(
PHI);
4554 bool addrModeCombiningAllowed() {
4557 switch (DifferentField) {
4560 case ExtAddrMode::BaseRegField:
4562 case ExtAddrMode::BaseGVField:
4564 case ExtAddrMode::BaseOffsField:
4566 case ExtAddrMode::ScaledRegField:
4576bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4581 return matchAddr(ScaleReg,
Depth);
4592 ExtAddrMode TestAddrMode =
AddrMode;
4596 TestAddrMode.
Scale += Scale;
4610 ConstantInt *CI =
nullptr;
4611 Value *AddLHS =
nullptr;
4615 TestAddrMode.InBounds =
false;
4632 auto GetConstantStep =
4633 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4636 return std::nullopt;
4639 return std::nullopt;
4647 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4648 return std::nullopt;
4650 return std::make_pair(IVInc->first, ConstantStep->getValue());
4651 return std::nullopt;
4666 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4673 APInt Step = IVStep->second;
4675 if (
Offset.isSignedIntN(64)) {
4676 TestAddrMode.InBounds =
false;
4678 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4683 getDTFn().
dominates(IVInc, MemoryInst)) {
4703 switch (
I->getOpcode()) {
4704 case Instruction::BitCast:
4705 case Instruction::AddrSpaceCast:
4707 if (
I->getType() ==
I->getOperand(0)->getType())
4709 return I->getType()->isIntOrPtrTy();
4710 case Instruction::PtrToInt:
4713 case Instruction::IntToPtr:
4716 case Instruction::Add:
4718 case Instruction::Mul:
4719 case Instruction::Shl:
4722 case Instruction::GetElementPtr:
4750class TypePromotionHelper {
4753 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4754 Instruction *ExtOpnd,
bool IsSExt) {
4755 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4756 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4760 if (It->second.getInt() == ExtTy)
4766 ExtTy = BothExtension;
4768 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4775 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4776 Instruction *Opnd,
bool IsSExt) {
4777 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4778 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4779 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4780 return It->second.getPointer();
4795 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4796 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4800 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4813 static Value *promoteOperandForTruncAndAnyExt(
4814 Instruction *Ext, TypePromotionTransaction &TPT,
4815 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4816 SmallVectorImpl<Instruction *> *Exts,
4817 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4828 static Value *promoteOperandForOther(Instruction *Ext,
4829 TypePromotionTransaction &TPT,
4830 InstrToOrigTy &PromotedInsts,
4831 unsigned &CreatedInstsCost,
4832 SmallVectorImpl<Instruction *> *Exts,
4833 SmallVectorImpl<Instruction *> *Truncs,
4834 const TargetLowering &TLI,
bool IsSExt);
4837 static Value *signExtendOperandForOther(
4838 Instruction *Ext, TypePromotionTransaction &TPT,
4839 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4840 SmallVectorImpl<Instruction *> *Exts,
4841 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4842 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4843 Exts, Truncs, TLI,
true);
4847 static Value *zeroExtendOperandForOther(
4848 Instruction *Ext, TypePromotionTransaction &TPT,
4849 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4850 SmallVectorImpl<Instruction *> *Exts,
4851 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4852 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4853 Exts, Truncs, TLI,
false);
4858 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4859 InstrToOrigTy &PromotedInsts,
4860 unsigned &CreatedInstsCost,
4861 SmallVectorImpl<Instruction *> *Exts,
4862 SmallVectorImpl<Instruction *> *Truncs,
4863 const TargetLowering &TLI);
4874 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4875 const TargetLowering &TLI,
4876 const InstrToOrigTy &PromotedInsts);
4881bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4882 Type *ConsideredExtType,
4883 const InstrToOrigTy &PromotedInsts,
4903 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4904 (IsSExt && BinOp->hasNoSignedWrap())))
4908 if ((Inst->
getOpcode() == Instruction::And ||
4913 if (Inst->
getOpcode() == Instruction::Xor) {
4916 if (!Cst->getValue().isAllOnes())
4925 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4935 if (ExtInst->hasOneUse()) {
4937 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4970 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4983TypePromotionHelper::Action TypePromotionHelper::getAction(
4984 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4985 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
4987 "Unexpected instruction type");
4994 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
5007 return promoteOperandForTruncAndAnyExt;
5013 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
5016Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
5017 Instruction *SExt, TypePromotionTransaction &TPT,
5018 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5019 SmallVectorImpl<Instruction *> *Exts,
5020 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
5024 Value *ExtVal = SExt;
5025 bool HasMergedNonFreeExt =
false;
5029 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
5032 TPT.replaceAllUsesWith(SExt, ZExt);
5033 TPT.eraseInstruction(SExt);
5038 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
5040 CreatedInstsCost = 0;
5044 TPT.eraseInstruction(SExtOpnd);
5052 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
5060 TPT.eraseInstruction(ExtInst, NextVal);
5064Value *TypePromotionHelper::promoteOperandForOther(
5065 Instruction *Ext, TypePromotionTransaction &TPT,
5066 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5067 SmallVectorImpl<Instruction *> *Exts,
5068 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
5073 CreatedInstsCost = 0;
5079 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
5082 ITrunc->moveAfter(ExtOpnd);
5087 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
5090 TPT.setOperand(Ext, 0, ExtOpnd);
5100 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
5102 TPT.mutateType(ExtOpnd, Ext->
getType());
5104 TPT.replaceAllUsesWith(Ext, ExtOpnd);
5107 for (
int OpIdx = 0, EndOpIdx = ExtOpnd->
getNumOperands(); OpIdx != EndOpIdx;
5111 !shouldExtOperand(ExtOpnd, OpIdx)) {
5120 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
5122 TPT.setOperand(ExtOpnd, OpIdx, ConstantInt::get(Ext->
getType(), CstVal));
5133 Value *ValForExtOpnd = IsSExt
5134 ? TPT.createSExt(ExtOpnd, Opnd, Ext->
getType())
5135 : TPT.createZExt(ExtOpnd, Opnd, Ext->
getType());
5136 TPT.setOperand(ExtOpnd, OpIdx, ValForExtOpnd);
5138 if (!InstForExtOpnd)
5144 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5147 TPT.eraseInstruction(Ext);
5159bool AddressingModeMatcher::isPromotionProfitable(
5160 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5161 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5166 if (NewCost > OldCost)
5168 if (NewCost < OldCost)
5187bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5199 case Instruction::PtrToInt:
5202 case Instruction::IntToPtr: {
5210 case Instruction::BitCast:
5220 case Instruction::AddrSpaceCast: {
5228 case Instruction::Add: {
5231 ExtAddrMode BackupAddrMode =
AddrMode;
5232 unsigned OldSize = AddrModeInsts.
size();
5237 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5238 TPT.getRestorationPoint();
5242 int First = 0, Second = 1;
5253 AddrModeInsts.
resize(OldSize);
5254 TPT.rollback(LastKnownGood);
5264 AddrModeInsts.
resize(OldSize);
5265 TPT.rollback(LastKnownGood);
5271 case Instruction::Mul:
5272 case Instruction::Shl: {
5276 if (!
RHS ||
RHS->getBitWidth() > 64)
5278 int64_t Scale = Opcode == Instruction::Shl
5279 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5280 :
RHS->getSExtValue();
5284 case Instruction::GetElementPtr: {
5287 int VariableOperand = -1;
5288 unsigned VariableScale = 0;
5290 int64_t ConstantOffset = 0;
5292 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5294 const StructLayout *SL =
DL.getStructLayout(STy);
5305 if (ConstantInt *CI =
5307 const APInt &CVal = CI->
getValue();
5314 if (VariableOperand != -1)
5318 VariableOperand = i;
5319 VariableScale = TypeSize;
5326 if (VariableOperand == -1) {
5327 AddrMode.BaseOffs += ConstantOffset;
5333 AddrMode.BaseOffs -= ConstantOffset;
5337 ConstantOffset > 0) {
5350 BasicBlock *Parent = BaseI ? BaseI->getParent()
5351 : &
GEP->getFunction()->getEntryBlock();
5353 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5361 ExtAddrMode BackupAddrMode =
AddrMode;
5362 unsigned OldSize = AddrModeInsts.
size();
5365 AddrMode.BaseOffs += ConstantOffset;
5374 AddrModeInsts.
resize(OldSize);
5382 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5387 AddrModeInsts.
resize(OldSize);
5392 AddrMode.BaseOffs += ConstantOffset;
5393 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5394 VariableScale,
Depth)) {
5397 AddrModeInsts.
resize(OldSize);
5404 case Instruction::SExt:
5405 case Instruction::ZExt: {
5412 TypePromotionHelper::Action TPH =
5413 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5417 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5418 TPT.getRestorationPoint();
5419 unsigned CreatedInstsCost = 0;
5421 Value *PromotedOperand =
5422 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5437 assert(PromotedOperand &&
5438 "TypePromotionHelper should have filtered out those cases");
5440 ExtAddrMode BackupAddrMode =
AddrMode;
5441 unsigned OldSize = AddrModeInsts.
size();
5443 if (!matchAddr(PromotedOperand,
Depth) ||
5448 !isPromotionProfitable(CreatedInstsCost,
5449 ExtCost + (AddrModeInsts.
size() - OldSize),
5452 AddrModeInsts.
resize(OldSize);
5453 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5454 TPT.rollback(LastKnownGood);
5459 AddrMode.replaceWith(Ext, PromotedOperand);
5462 case Instruction::Call:
5464 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5480bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5483 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5484 TPT.getRestorationPoint();
5508 ExtAddrMode BackupAddrMode =
AddrMode;
5509 unsigned OldSize = AddrModeInsts.
size();
5512 bool MovedAway =
false;
5513 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5521 if (
I->hasOneUse() ||
5522 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5529 AddrModeInsts.
resize(OldSize);
5530 TPT.rollback(LastKnownGood);
5533 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5535 TPT.rollback(LastKnownGood);
5562 TPT.rollback(LastKnownGood);
5581 if (OpInfo.CallOperandVal == OpVal &&
5583 !OpInfo.isIndirect))
5599 if (!ConsideredInsts.
insert(
I).second)
5607 for (
Use &U :
I->uses()) {
5615 MemoryUses.push_back({&U, LI->getType()});
5622 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5629 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5636 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5646 if (!
find(PtrOps, U.get()))
5649 MemoryUses.push_back({&U, AccessTy});
5654 if (CI->hasFnAttr(Attribute::Cold)) {
5672 PSI, BFI, SeenInsts))
5683 unsigned SeenInsts = 0;
5686 PSI, BFI, SeenInsts);
5694bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5696 Value *KnownLive2) {
5698 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5739bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5740 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5741 if (IgnoreProfitability)
5759 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5760 ScaledReg =
nullptr;
5764 if (!BaseReg && !ScaledReg)
5785 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5788 Type *AddressAccessTy = Pair.second;
5789 unsigned AS =
Address->getType()->getPointerAddressSpace();
5795 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5797 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5798 TPT.getRestorationPoint();
5799 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5800 AddressAccessTy, AS, UserI, Result,
5801 InsertedInsts, PromotedInsts, TPT,
5802 LargeOffsetGEP, OptSize, PSI, BFI);
5803 Matcher.IgnoreProfitability =
true;
5811 TPT.rollback(LastKnownGood);
5817 MatchedAddrModeInsts.
clear();
5827 return I->getParent() != BB;
5843 return std::next(AddrInst->getIterator());
5854 Earliest = UserInst;
5879bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5880 Type *AccessTy,
unsigned AddrSpace) {
5885 SmallVector<Value *, 8> worklist;
5886 SmallPtrSet<Value *, 16> Visited;
5892 bool PhiOrSelectSeen =
false;
5893 SmallVector<Instruction *, 16> AddrModeInsts;
5894 AddressingModeCombiner AddrModes(*
DL, Addr);
5895 TypePromotionTransaction TPT(RemovedInsts);
5896 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5897 TPT.getRestorationPoint();
5898 while (!worklist.
empty()) {
5910 if (!Visited.
insert(V).second)
5916 PhiOrSelectSeen =
true;
5923 PhiOrSelectSeen =
true;
5930 AddrModeInsts.
clear();
5931 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5936 auto getDTFn = [
this]() ->
const DominatorTree & {
return getDT(); };
5937 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5938 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5939 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5942 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5947 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5948 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5951 NewAddrMode.OriginalValue =
V;
5952 if (!AddrModes.addNewAddrMode(NewAddrMode))
5959 if (!AddrModes.combineAddrModes()) {
5960 TPT.rollback(LastKnownGood);
5966 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5972 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5986 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
6008 <<
" for " << *MemoryInst <<
"\n");
6012 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6018 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
6020 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6022 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6029 <<
" for " << *MemoryInst <<
"\n");
6030 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
6041 if (ResultPtr ||
AddrMode.Scale != 1)
6062 GlobalValue *BaseGV =
AddrMode.BaseGV;
6063 if (BaseGV !=
nullptr) {
6068 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
6077 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
6078 if (!ResultPtr &&
AddrMode.BaseReg) {
6082 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
6083 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
6092 }
else if (!ResultPtr) {
6106 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
6119 "We can't transform if ScaledReg is too narrow");
6120 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
6124 V = Builder.CreateMul(
6127 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6138 if (ResultPtr->
getType() != I8PtrTy)
6139 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6140 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6153 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6155 SunkAddr = ResultPtr;
6157 if (ResultPtr->
getType() != I8PtrTy)
6158 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6159 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6166 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6172 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
6174 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6176 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6186 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6187 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6188 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6190 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6194 <<
" for " << *MemoryInst <<
"\n");
6205 if (
V->getType()->isPointerTy())
6206 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6208 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
6217 }
else if (
V->getType()->isPointerTy()) {
6218 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6221 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
6230 I->eraseFromParent();
6234 V = Builder.CreateMul(
6237 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6243 GlobalValue *BaseGV =
AddrMode.BaseGV;
6244 if (BaseGV !=
nullptr) {
6247 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6251 Value *
V = Builder.CreatePtrToInt(BaseGVPtr,
IntPtrTy,
"sunkaddr");
6253 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6262 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6270 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6276 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6281 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6282 RecursivelyDeleteTriviallyDeadInstructions(
6283 Repl, TLInfo, nullptr,
6284 [&](Value *V) { removeAllAssertingVHReferences(V); });
6308bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6314 if (!
GEP->hasIndices())
6322 SmallVector<Value *, 2>
Ops(
GEP->operands());
6324 bool RewriteGEP =
false;
6333 unsigned FinalIndex =
Ops.size() - 1;
6338 for (
unsigned i = 1; i < FinalIndex; ++i) {
6343 C =
C->getSplatValue();
6345 if (!CI || !CI->
isZero())
6352 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6356 if (!
C || !
C->isZero()) {
6357 Ops[FinalIndex] =
V;
6365 if (!RewriteGEP &&
Ops.size() == 2)
6372 Type *SourceTy =
GEP->getSourceElementType();
6373 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6377 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6378 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6379 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6389 if (
Ops.size() != 2) {
6399 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6413 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6414 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6417 Intrinsic::masked_gather) {
6421 Intrinsic::masked_scatter);
6436 Ptr, TLInfo,
nullptr,
6437 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6448 if (
I->hasNUsesOrMore(3))
6451 for (
User *U :
I->users()) {
6453 if (!Extract || Extract->getNumIndices() != 1)
6456 unsigned Index = Extract->getIndices()[0];
6458 MulExtract = Extract;
6459 else if (Index == 1)
6460 OverflowExtract = Extract;
6487bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
6488 ModifyDT &ModifiedDT) {
6495 ExtractValueInst *MulExtract =
nullptr, *OverflowExtract =
nullptr;
6500 InsertedInsts.insert(
I);
6511 OverflowEntryBB->
takeName(
I->getParent());
6517 NoOverflowBB->
moveAfter(OverflowEntryBB);
6525 Value *LoLHS = Builder.CreateTrunc(
LHS, LegalTy,
"lo.lhs");
6526 Value *HiLHS = Builder.CreateLShr(
LHS, VTHalfBitWidth,
"lhs.lsr");
6527 HiLHS = Builder.CreateTrunc(HiLHS, LegalTy,
"hi.lhs");
6530 Value *LoRHS = Builder.CreateTrunc(
RHS, LegalTy,
"lo.rhs");
6531 Value *HiRHS = Builder.CreateLShr(
RHS, VTHalfBitWidth,
"rhs.lsr");
6532 HiRHS = Builder.CreateTrunc(HiRHS, LegalTy,
"hi.rhs");
6534 Value *IsAnyBitTrue;
6537 Builder.CreateAShr(LoLHS, VTHalfBitWidth - 1,
"sign.lo.lhs");
6539 Builder.CreateAShr(LoRHS, VTHalfBitWidth - 1,
"sign.lo.rhs");
6540 Value *XorLHS = Builder.CreateXor(HiLHS, SignLoLHS);
6541 Value *XorRHS = Builder.CreateXor(HiRHS, SignLoRHS);
6542 Value *
Or = Builder.CreateOr(XorLHS, XorRHS,
"or.lhs.rhs");
6543 IsAnyBitTrue = Builder.CreateCmp(ICmpInst::ICMP_NE,
Or,
6544 ConstantInt::getNullValue(
Or->getType()));
6546 Value *CmpLHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiLHS,
6547 ConstantInt::getNullValue(LegalTy));
6548 Value *CmpRHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiRHS,
6549 ConstantInt::getNullValue(LegalTy));
6550 IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS,
"or.lhs.rhs");
6552 Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
6555 Builder.SetInsertPoint(NoOverflowBB);
6556 Value *ExtLoLHS, *ExtLoRHS;
6558 ExtLoLHS = Builder.CreateSExt(LoLHS, Ty,
"lo.lhs.ext");
6559 ExtLoRHS = Builder.CreateSExt(LoRHS, Ty,
"lo.rhs.ext");
6561 ExtLoLHS = Builder.CreateZExt(LoLHS, Ty,
"lo.lhs.ext");
6562 ExtLoRHS = Builder.CreateZExt(LoRHS, Ty,
"lo.rhs.ext");
6565 Value *
Mul = Builder.CreateMul(ExtLoLHS, ExtLoRHS,
"mul.overflow.no");
6570 OverflowResBB->
setName(
"overflow.res");
6573 Builder.CreateBr(OverflowResBB);
6581 PHINode *OverflowResPHI = Builder.CreatePHI(Ty, 2),
6583 Builder.CreatePHI(IntegerType::getInt1Ty(
I->getContext()), 2);
6595 if (OverflowExtract) {
6596 OverflowExtract->replaceAllUsesWith(OverflowFlagPHI);
6597 OverflowExtract->eraseFromParent();
6602 I->removeFromParent();
6604 I->insertInto(OverflowBB, OverflowBB->
end());
6605 Builder.SetInsertPoint(OverflowBB, OverflowBB->
end());
6607 Value *OverflowFlag = Builder.CreateExtractValue(
I, {1},
"overflow.flag");
6608 Builder.CreateBr(OverflowResBB);
6612 OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
6614 DTU->
applyUpdates({{DominatorTree::Insert, OverflowEntryBB, OverflowBB},
6615 {DominatorTree::Insert, OverflowEntryBB, NoOverflowBB},
6616 {DominatorTree::Insert, NoOverflowBB, OverflowResBB},
6617 {DominatorTree::Delete, OverflowEntryBB, OverflowResBB},
6618 {DominatorTree::Insert, OverflowBB, OverflowResBB}});
6620 ModifiedDT = ModifyDT::ModifyBBDT;
6626bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6627 bool MadeChange =
false;
6629 const TargetRegisterInfo *
TRI =
6634 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6640 OpInfo.isIndirect) {
6642 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6705bool CodeGenPrepare::tryToPromoteExts(
6706 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6707 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6708 unsigned CreatedInstsCost) {
6709 bool Promoted =
false;
6712 for (
auto *
I : Exts) {
6727 TypePromotionHelper::Action TPH =
6728 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6737 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6738 TPT.getRestorationPoint();
6739 SmallVector<Instruction *, 4> NewExts;
6740 unsigned NewCreatedInstsCost = 0;
6743 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6744 &NewExts,
nullptr, *TLI);
6746 "TypePromotionHelper should have filtered out those cases");
6756 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6759 TotalCreatedInstsCost =
6760 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6762 (TotalCreatedInstsCost > 1 ||
6764 (ExtCost == 0 && NewExts.
size() > 1))) {
6768 TPT.rollback(LastKnownGood);
6773 SmallVector<Instruction *, 2> NewlyMovedExts;
6774 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6775 bool NewPromoted =
false;
6776 for (
auto *ExtInst : NewlyMovedExts) {
6786 ProfitablyMovedExts.
push_back(MovedExt);
6793 TPT.rollback(LastKnownGood);
6804bool CodeGenPrepare::mergeSExts(
Function &
F) {
6806 for (
auto &Entry : ValToSExtendedUses) {
6807 SExts &Insts =
Entry.second;
6809 for (Instruction *Inst : Insts) {
6813 bool inserted =
false;
6814 for (
auto &Pt : CurPts) {
6817 RemovedInsts.insert(Pt);
6818 Pt->removeFromParent();
6829 RemovedInsts.insert(Inst);
6836 CurPts.push_back(Inst);
6878bool CodeGenPrepare::splitLargeGEPOffsets() {
6880 for (
auto &Entry : LargeOffsetGEPMap) {
6882 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6883 &LargeOffsetGEPs =
Entry.second;
6884 auto compareGEPOffset =
6885 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6886 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6887 if (
LHS.first ==
RHS.first)
6889 if (
LHS.second !=
RHS.second)
6890 return LHS.second <
RHS.second;
6891 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6894 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6897 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6899 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6900 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6901 Value *NewBaseGEP =
nullptr;
6903 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6904 GetElementPtrInst *
GEP) {
6905 LLVMContext &Ctx =
GEP->getContext();
6906 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6908 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6920 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), &getDT(), LI);
6923 NewBaseInsertPt = std::next(BaseI->getIterator());
6930 IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
6936 NewBaseGEP = OldBase;
6937 if (NewBaseGEP->
getType() != I8PtrTy)
6938 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6940 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6941 NewGEPBases.
insert(NewBaseGEP);
6947 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6948 BaseOffset = PreferBase;
6951 createNewBase(BaseOffset, OldBase, BaseGEP);
6954 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6955 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6956 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6957 int64_t
Offset = LargeOffsetGEP->second;
6958 if (
Offset != BaseOffset) {
6965 GEP->getResultElementType(),
6966 GEP->getAddressSpace())) {
6972 NewBaseGEP =
nullptr;
6977 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6982 createNewBase(BaseOffset, OldBase,
GEP);
6986 Value *NewGEP = NewBaseGEP;
6987 if (
Offset != BaseOffset) {
6990 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6994 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6995 GEP->eraseFromParent();
7002bool CodeGenPrepare::optimizePhiType(
7003 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
7004 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
7009 Type *PhiTy =
I->getType();
7010 Type *ConvertTy =
nullptr;
7012 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
7015 SmallVector<Instruction *, 4> Worklist;
7017 SmallPtrSet<PHINode *, 4> PhiNodes;
7018 SmallPtrSet<ConstantData *, 4>
Constants;
7021 SmallPtrSet<Instruction *, 4> Defs;
7022 SmallPtrSet<Instruction *, 4>
Uses;
7028 bool AnyAnchored =
false;
7030 while (!Worklist.
empty()) {
7035 for (
Value *V :
Phi->incoming_values()) {
7037 if (!PhiNodes.
count(OpPhi)) {
7038 if (!Visited.
insert(OpPhi).second)
7044 if (!OpLoad->isSimple())
7046 if (Defs.
insert(OpLoad).second)
7049 if (Defs.
insert(OpEx).second)
7053 ConvertTy = OpBC->getOperand(0)->getType();
7054 if (OpBC->getOperand(0)->getType() != ConvertTy)
7056 if (Defs.
insert(OpBC).second) {
7069 for (User *V :
II->users()) {
7071 if (!PhiNodes.
count(OpPhi)) {
7072 if (Visited.
count(OpPhi))
7079 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
7081 Uses.insert(OpStore);
7084 ConvertTy = OpBC->getType();
7085 if (OpBC->getType() != ConvertTy)
7089 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
7096 if (!ConvertTy || !AnyAnchored || PhiTy == ConvertTy ||
7100 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
7101 << *ConvertTy <<
"\n");
7106 for (ConstantData *
C : Constants)
7108 for (Instruction *
D : Defs) {
7110 ValMap[
D] =
D->getOperand(0);
7114 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
7117 for (PHINode *Phi : PhiNodes)
7119 Phi->getName() +
".tc",
Phi->getIterator());
7121 for (PHINode *Phi : PhiNodes) {
7123 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
7125 Phi->getIncomingBlock(i));
7129 for (Instruction *U :
Uses) {
7134 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
7144bool CodeGenPrepare::optimizePhiTypes(
Function &
F) {
7149 SmallPtrSet<PHINode *, 4> Visited;
7150 SmallPtrSet<Instruction *, 4> DeletedInstrs;
7154 for (
auto &Phi : BB.
phis())
7155 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
7158 for (
auto *
I : DeletedInstrs) {
7160 I->eraseFromParent();
7168bool CodeGenPrepare::canFormExtLd(
7169 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
7170 Instruction *&Inst,
bool HasPromoted) {
7171 for (
auto *MovedExtInst : MovedExts) {
7174 Inst = MovedExtInst;
7226bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7227 bool AllowPromotionWithoutCommonHeader =
false;
7232 *Inst, AllowPromotionWithoutCommonHeader);
7233 TypePromotionTransaction TPT(RemovedInsts);
7234 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7235 TPT.getRestorationPoint();
7237 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7240 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7243 LoadInst *LI =
nullptr;
7248 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7249 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7254 Inst = ExtFedByLoad;
7259 if (ATPConsiderable &&
7260 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7261 HasPromoted, TPT, SpeculativelyMovedExts))
7264 TPT.rollback(LastKnownGood);
7273bool CodeGenPrepare::performAddressTypePromotion(
7274 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7275 bool HasPromoted, TypePromotionTransaction &TPT,
7276 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7277 bool Promoted =
false;
7278 SmallPtrSet<Instruction *, 1> UnhandledExts;
7279 bool AllSeenFirst =
true;
7280 for (
auto *
I : SpeculativelyMovedExts) {
7281 Value *HeadOfChain =
I->getOperand(0);
7282 auto AlreadySeen = SeenChainsForSExt.
find(HeadOfChain);
7285 if (AlreadySeen != SeenChainsForSExt.
end()) {
7286 if (AlreadySeen->second !=
nullptr)
7287 UnhandledExts.
insert(AlreadySeen->second);
7288 AllSeenFirst =
false;
7292 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7293 SpeculativelyMovedExts.size() == 1)) {
7297 for (
auto *
I : SpeculativelyMovedExts) {
7298 Value *HeadOfChain =
I->getOperand(0);
7299 SeenChainsForSExt[HeadOfChain] =
nullptr;
7300 ValToSExtendedUses[HeadOfChain].push_back(
I);
7303 Inst = SpeculativelyMovedExts.pop_back_val();
7308 for (
auto *
I : SpeculativelyMovedExts) {
7309 Value *HeadOfChain =
I->getOperand(0);
7310 SeenChainsForSExt[HeadOfChain] = Inst;
7315 if (!AllSeenFirst && !UnhandledExts.
empty())
7316 for (
auto *VisitedSExt : UnhandledExts) {
7317 if (RemovedInsts.count(VisitedSExt))
7319 TypePromotionTransaction TPT(RemovedInsts);
7321 SmallVector<Instruction *, 2> Chains;
7323 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7327 for (
auto *
I : Chains) {
7328 Value *HeadOfChain =
I->getOperand(0);
7330 SeenChainsForSExt[HeadOfChain] =
nullptr;
7331 ValToSExtendedUses[HeadOfChain].push_back(
I);
7337bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7342 Value *Src =
I->getOperand(0);
7343 if (Src->hasOneUse())
7355 bool DefIsLiveOut =
false;
7356 for (User *U :
I->users()) {
7361 if (UserBB == DefBB)
7363 DefIsLiveOut =
true;
7370 for (User *U : Src->users()) {
7373 if (UserBB == DefBB)
7382 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7384 bool MadeChange =
false;
7390 if (UserBB == DefBB)
7394 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7396 if (!InsertedTrunc) {
7399 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7401 InsertedInsts.insert(InsertedTrunc);
7464bool CodeGenPrepare::optimizeLoadExt(LoadInst *
Load) {
7465 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7469 if (
Load->hasOneUse() &&
7475 SmallVector<Instruction *, 8> WorkList;
7476 SmallPtrSet<Instruction *, 16> Visited;
7477 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7478 SmallVector<Instruction *, 8> DropFlags;
7479 for (
auto *U :
Load->users())
7491 while (!WorkList.
empty()) {
7495 if (!Visited.
insert(
I).second)
7500 for (
auto *U :
Phi->users())
7505 switch (
I->getOpcode()) {
7506 case Instruction::And: {
7510 APInt AndBits = AndC->getValue();
7511 DemandBits |= AndBits;
7513 if (AndBits.
ugt(WidestAndBits))
7514 WidestAndBits = AndBits;
7515 if (AndBits == WidestAndBits &&
I->getOperand(0) ==
Load)
7520 case Instruction::Shl: {
7525 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7530 case Instruction::Trunc: {
7533 DemandBits.setLowBits(TruncBitWidth);
7543 uint32_t ActiveBits = DemandBits.getActiveBits();
7555 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7556 WidestAndBits != DemandBits)
7559 LLVMContext &Ctx =
Load->getType()->getContext();
7560 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7571 Builder.CreateAnd(
Load, ConstantInt::get(Ctx, DemandBits)));
7574 InsertedInsts.insert(NewAnd);
7579 NewAnd->setOperand(0,
Load);
7582 for (
auto *
And : AndsToMaybeRemove)
7587 if (&*CurInstIterator ==
And)
7588 CurInstIterator = std::next(
And->getIterator());
7589 And->eraseFromParent();
7594 for (
auto *Inst : DropFlags)
7608 TTI->isExpensiveToSpeculativelyExecute(
I);
7626 uint64_t Max = std::max(TrueWeight, FalseWeight);
7627 uint64_t Sum = TrueWeight + FalseWeight;
7630 if (Probability >
TTI->getPredictableBranchThreshold())
7640 if (!Cmp || !Cmp->hasOneUse())
7663 assert(DefSI->getCondition() ==
SI->getCondition() &&
7664 "The condition of DefSI does not match with SI");
7665 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7668 assert(V &&
"Failed to get select true/false value");
7672bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7696 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7697 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7698 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7699 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7705bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7707 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7708 "Expected a funnel shift");
7732 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7733 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7734 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7742bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7754 It !=
SI->getParent()->
end(); ++It) {
7756 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7763 SelectInst *LastSI = ASI.
back();
7766 CurInstIterator = std::next(LastSI->
getIterator());
7770 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7771 fixupDbgVariableRecordsOnInst(*SI);
7773 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7776 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7779 TargetLowering::SelectSupportKind SelectKind;
7780 if (
SI->getType()->isVectorTy())
7781 SelectKind = TargetLowering::ScalarCondVectorVal;
7783 SelectKind = TargetLowering::ScalarValSelect;
7820 SmallVector<Instruction *> TrueInstrs, FalseInstrs;
7821 for (SelectInst *SI : ASI) {
7833 SplitPt.setHeadBit(
true);
7836 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7841 UncondBrInst *TrueBranch =
nullptr;
7842 UncondBrInst *FalseBranch =
nullptr;
7843 if (TrueInstrs.
size() == 0) {
7848 }
else if (FalseInstrs.
size() == 0) {
7865 EndBlock->
setName(
"select.end");
7867 TrueBlock->
setName(
"select.true.sink");
7869 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7870 :
"select.false.sink");
7874 FreshBBs.
insert(TrueBlock);
7876 FreshBBs.
insert(FalseBlock);
7877 FreshBBs.
insert(EndBlock);
7882 static const unsigned MD[] = {
7883 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7884 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7889 for (Instruction *
I : TrueInstrs)
7891 for (Instruction *
I : FalseInstrs)
7898 if (TrueBlock ==
nullptr)
7899 TrueBlock = StartBlock;
7900 else if (FalseBlock ==
nullptr)
7901 FalseBlock = StartBlock;
7917 SI->eraseFromParent();
7919 ++NumSelectsExpanded;
7923 CurInstIterator = StartBlock->
end();
7930bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7942 "Expected a type of the same size!");
7948 Value *BC1 = Builder.CreateBitCast(
7950 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7951 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7955 SVI, TLInfo,
nullptr,
7956 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7963 !
Op->isTerminator() && !
Op->isEHPad())
7969bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7984 for (Use *U :
reverse(OpsToSink)) {
7996 SetVector<Instruction *> MaybeDead;
7997 DenseMap<Instruction *, Instruction *> NewInstructions;
7998 for (Use *U : ToReplace) {
8007 FreshBBs.
insert(OpDef->getParent());
8010 NewInstructions[UI] = NI;
8015 InsertedInsts.insert(NI);
8021 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
8022 It->second->setOperand(
U->getOperandNo(), NI);
8029 for (
auto *
I : MaybeDead) {
8030 if (!
I->hasNUsesOrMore(1)) {
8032 I->eraseFromParent();
8039bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
8045 unsigned RegWidth =
RegType.getSizeInBits();
8056 auto *NewType = Type::getIntNTy(
Context, RegWidth);
8065 ExtType = Instruction::SExt;
8068 if (Arg->hasSExtAttr())
8069 ExtType = Instruction::SExt;
8070 if (Arg->hasZExtAttr())
8071 ExtType = Instruction::ZExt;
8077 SI->setCondition(ExtInst);
8078 for (
auto Case :
SI->cases()) {
8079 const APInt &NarrowConst = Case.getCaseValue()->getValue();
8080 APInt WideConst = (ExtType == Instruction::ZExt)
8081 ? NarrowConst.
zext(RegWidth)
8082 : NarrowConst.
sext(RegWidth);
8083 Case.setValue(ConstantInt::get(
Context, WideConst));
8089bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
8096 Value *Condition =
SI->getCondition();
8105 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
8106 ConstantInt *CaseValue = Case.getCaseValue();
8107 BasicBlock *CaseBB = Case.getCaseSuccessor();
8110 bool CheckedForSinglePred =
false;
8111 for (PHINode &
PHI : CaseBB->
phis()) {
8112 Type *PHIType =
PHI.getType();
8120 if (PHIType == ConditionType || TryZExt) {
8122 bool SkipCase =
false;
8123 Value *Replacement =
nullptr;
8124 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
8125 Value *PHIValue =
PHI.getIncomingValue(
I);
8126 if (PHIValue != CaseValue) {
8135 if (
PHI.getIncomingBlock(
I) != SwitchBB)
8140 if (!CheckedForSinglePred) {
8141 CheckedForSinglePred =
true;
8142 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
8148 if (Replacement ==
nullptr) {
8149 if (PHIValue == CaseValue) {
8150 Replacement = Condition;
8153 Replacement = Builder.CreateZExt(Condition, PHIType);
8156 PHI.setIncomingValue(
I, Replacement);
8167bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
8168 bool Changed = optimizeSwitchType(SI);
8169 Changed |= optimizeSwitchPhiConstants(SI);
8190class VectorPromoteHelper {
8192 const DataLayout &
DL;
8195 const TargetLowering &TLI;
8198 const TargetTransformInfo &
TTI;
8204 SmallVector<Instruction *, 4> InstsToBePromoted;
8207 unsigned StoreExtractCombineCost;
8216 if (InstsToBePromoted.
empty())
8218 return InstsToBePromoted.
back();
8224 unsigned getTransitionOriginalValueIdx()
const {
8226 "Other kind of transitions are not supported yet");
8233 unsigned getTransitionIdx()
const {
8235 "Other kind of transitions are not supported yet");
8243 Type *getTransitionType()
const {
8254 void promoteImpl(Instruction *ToBePromoted);
8258 bool isProfitableToPromote() {
8259 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8263 Type *PromotedType = getTransitionType();
8266 unsigned AS =
ST->getPointerAddressSpace();
8284 for (
const auto &Inst : InstsToBePromoted) {
8292 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8304 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8305 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8306 return ScalarCost > VectorCost;
8318 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8333 if (!
EC.isScalable()) {
8334 SmallVector<Constant *, 4> ConstVec;
8336 for (
unsigned Idx = 0; Idx !=
EC.getKnownMinValue(); ++Idx) {
8337 if (Idx == ExtractIdx)
8345 "Generate scalable vector for non-splat is unimplemented");
8350 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8351 unsigned OperandIdx) {
8354 if (OperandIdx != 1)
8356 switch (
Use->getOpcode()) {
8359 case Instruction::SDiv:
8360 case Instruction::UDiv:
8361 case Instruction::SRem:
8362 case Instruction::URem:
8364 case Instruction::FDiv:
8365 case Instruction::FRem:
8366 return !
Use->hasNoNaNs();
8372 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8373 const TargetTransformInfo &
TTI, Instruction *Transition,
8374 unsigned CombineCost)
8375 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8376 StoreExtractCombineCost(CombineCost) {
8377 assert(Transition &&
"Do not know how to promote null");
8381 bool canPromote(
const Instruction *ToBePromoted)
const {
8388 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8393 for (
const Use &U : ToBePromoted->
operands()) {
8394 const Value *Val =
U.get();
8395 if (Val == getEndOfTransition()) {
8417 void enqueueForPromotion(Instruction *ToBePromoted) {
8418 InstsToBePromoted.push_back(ToBePromoted);
8422 void recordCombineInstruction(Instruction *ToBeCombined) {
8424 CombineInst = ToBeCombined;
8434 if (InstsToBePromoted.empty() || !CombineInst)
8442 for (
auto &ToBePromoted : InstsToBePromoted)
8443 promoteImpl(ToBePromoted);
8444 InstsToBePromoted.clear();
8451void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8461 "The type of the result of the transition does not match "
8466 Type *TransitionTy = getTransitionType();
8471 for (Use &U : ToBePromoted->
operands()) {
8473 Value *NewVal =
nullptr;
8474 if (Val == Transition)
8475 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8482 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8486 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8489 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8495bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8496 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8511 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8512 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost);
8519 if (ToBePromoted->
getParent() != Parent) {
8520 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8522 <<
") than the transition (" << Parent->
getName()
8527 if (VPH.canCombine(ToBePromoted)) {
8529 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8530 VPH.recordCombineInstruction(ToBePromoted);
8532 NumStoreExtractExposed +=
Changed;
8537 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8540 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8542 VPH.enqueueForPromotion(ToBePromoted);
8543 Inst = ToBePromoted;
8583 Type *StoreType =
SI.getValueOperand()->getType();
8592 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8593 DL.getTypeSizeInBits(StoreType) == 0)
8596 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8598 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8614 if (!
match(
SI.getValueOperand(),
8621 if (!
LValue->getType()->isIntegerTy() ||
8622 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8624 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8643 if (LBC && LBC->getParent() !=
SI.getParent())
8644 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8645 if (HBC && HBC->getParent() !=
SI.getParent())
8646 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8648 bool IsLE =
SI.getDataLayout().isLittleEndian();
8649 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8650 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8651 Value *Addr =
SI.getPointerOperand();
8652 Align Alignment =
SI.getAlign();
8653 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8654 if (IsOffsetStore) {
8655 Addr = Builder.CreateGEP(
8656 SplitStoreType, Addr,
8664 Builder.CreateAlignedStore(V, Addr, Alignment);
8667 CreateSplitStore(
LValue,
false);
8668 CreateSplitStore(HValue,
true);
8671 SI.eraseFromParent();
8679 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8761 if (GEPIOpI->getParent() != SrcBlock)
8766 if (auto *I = dyn_cast<Instruction>(Usr)) {
8767 if (I->getParent() != SrcBlock) {
8775 std::vector<GetElementPtrInst *> UGEPIs;
8778 for (User *Usr : GEPIOp->
users()) {
8797 if (UGEPI->getOperand(0) != GEPIOp)
8799 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8801 if (GEPIIdx->getType() !=
8809 UGEPIs.push_back(UGEPI);
8811 if (UGEPIs.size() == 0)
8814 for (GetElementPtrInst *UGEPI : UGEPIs) {
8816 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8823 for (GetElementPtrInst *UGEPI : UGEPIs) {
8824 UGEPI->setOperand(0, GEPI);
8826 auto NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8827 Constant *NewUGEPIIdx = ConstantInt::get(GEPIIdx->getType(), NewIdx);
8828 UGEPI->setOperand(1, NewUGEPIIdx);
8830 auto SourceFlags = GEPI->getNoWrapFlags();
8833 UGEPI->getNoWrapFlags().intersectForOffsetAdd(SourceFlags);
8835 if (NewIdx.
isNegative() && TargetFlags.hasNoUnsignedWrap())
8836 TargetFlags = TargetFlags.withoutNoUnsignedWrap();
8837 UGEPI->setNoWrapFlags(TargetFlags);
8843 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8845 "GEPIOp is used outside SrcBlock");
8869 Value *
X = Cmp->getOperand(0);
8870 if (!
X->hasUseList())
8875 for (
auto *U :
X->users()) {
8879 (UI->
getParent() != Branch->getParent() &&
8880 UI->
getParent() != Branch->getSuccessor(0) &&
8881 UI->
getParent() != Branch->getSuccessor(1)) ||
8882 (UI->
getParent() != Branch->getParent() &&
8883 !UI->
getParent()->getSinglePredecessor()))
8889 if (UI->
getParent() != Branch->getParent())
8893 ConstantInt::get(UI->
getType(), 0));
8895 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8899 if (Cmp->isEquality() &&
8904 if (UI->
getParent() != Branch->getParent())
8907 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8908 ConstantInt::get(UI->
getType(), 0));
8910 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8918bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8919 bool AnyChange =
false;
8920 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8924 if (InsertedInsts.count(
I))
8933 LargeOffsetGEPMap.erase(
P);
8935 P->eraseFromParent();
8966 I, LI->getLoopFor(
I->getParent()), *
TTI))
8974 TargetLowering::TypeExpandInteger) {
8978 I, LI->getLoopFor(
I->getParent()), *
TTI))
8981 bool MadeChange = optimizeExt(
I);
8982 return MadeChange | optimizeExtUses(
I);
8989 if (optimizeCmp(Cmp, ModifiedDT))
8993 if (optimizeURem(
I))
8997 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8998 bool Modified = optimizeLoadExt(LI);
9007 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
9008 unsigned AS =
SI->getPointerAddressSpace();
9009 return optimizeMemoryInst(
I,
SI->getOperand(1),
9010 SI->getOperand(0)->getType(), AS);
9014 unsigned AS = RMW->getPointerAddressSpace();
9015 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
9019 unsigned AS = CmpX->getPointerAddressSpace();
9020 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
9021 CmpX->getCompareOperand()->getType(), AS);
9031 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
9032 BinOp->
getOpcode() == Instruction::LShr)) {
9040 if (GEPI->hasAllZeroIndices()) {
9042 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
9043 GEPI->getName(), GEPI->getIterator());
9044 NC->setDebugLoc(GEPI->getDebugLoc());
9047 GEPI, TLInfo,
nullptr,
9048 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9050 optimizeInst(
NC, ModifiedDT);
9068 if (Const0 || Const1) {
9069 if (!Const0 || !Const1) {
9070 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
9076 FI->eraseFromParent();
9083 if (tryToSinkFreeOperands(
I))
9086 switch (
I->getOpcode()) {
9087 case Instruction::Shl:
9088 case Instruction::LShr:
9089 case Instruction::AShr:
9091 case Instruction::Call:
9093 case Instruction::Select:
9095 case Instruction::ShuffleVector:
9097 case Instruction::Switch:
9099 case Instruction::ExtractElement:
9101 case Instruction::CondBr:
9110bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
9111 if (!
I.getType()->isIntegerTy() ||
9116 SmallVector<Instruction *, 4> Insts;
9122 &
I, TLInfo,
nullptr,
9123 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9130bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
9132 bool MadeChange =
false;
9135 CurInstIterator = BB.
begin();
9136 ModifiedDT = ModifyDT::NotModifyDT;
9137 while (CurInstIterator != BB.
end()) {
9138 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
9139 if (ModifiedDT != ModifyDT::NotModifyDT) {
9148 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
9150 bool MadeBitReverse =
true;
9151 while (MadeBitReverse) {
9152 MadeBitReverse =
false;
9154 if (makeBitReverse(
I)) {
9155 MadeBitReverse = MadeChange =
true;
9160 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
9165bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
9166 bool AnyChange =
false;
9167 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
9168 AnyChange |= fixupDbgVariableRecord(DVR);
9174bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
9175 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
9176 DVR.
Type != DbgVariableRecord::LocationType::Assign)
9180 bool AnyChange =
false;
9181 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
9183 for (
Value *Location : LocationOps) {
9184 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9213bool CodeGenPrepare::placeDbgValues(
Function &
F) {
9214 bool MadeChange =
false;
9215 DominatorTree &DT = getDT();
9217 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9218 SmallVector<Instruction *, 4> VIs;
9219 for (
Value *V : DbgItem->location_ops())
9227 for (Instruction *VI : VIs) {
9228 if (
VI->isTerminator())
9233 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9244 if (VIs.size() > 1) {
9247 <<
"Unable to find valid location for Debug Value, undefing:\n"
9249 DbgItem->setKillLocation();
9254 << *DbgItem <<
' ' << *VI);
9261 for (BasicBlock &BB :
F) {
9267 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9269 DbgProcessor(&DVR, &Insn);
9280bool CodeGenPrepare::placePseudoProbes(
Function &
F) {
9281 bool MadeChange =
false;
9284 auto FirstInst =
Block.getFirstInsertionPt();
9285 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9289 while (
I !=
Block.end()) {
9291 II->moveBefore(FirstInst);
9321bool CodeGenPrepare::splitBranchCondition(
Function &
F) {
9325 bool MadeChange =
false;
9326 for (
auto &BB :
F) {
9339 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9347 Value *Cond1, *Cond2;
9350 Opc = Instruction::And;
9353 Opc = Instruction::Or;
9363 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9377 Br1->setCondition(Cond1);
9382 if (
Opc == Instruction::And)
9383 Br1->setSuccessor(0, TmpBB);
9385 Br1->setSuccessor(1, TmpBB);
9390 I->removeFromParent();
9391 I->insertBefore(Br2->getIterator());
9403 if (
Opc == Instruction::Or)
9407 TBB->replacePhiUsesWith(&BB, TmpBB);
9410 for (PHINode &PN : FBB->
phis()) {
9415 if (
Loop *L = LI->getLoopFor(&BB))
9416 L->addBasicBlockToLoop(TmpBB, *LI);
9420 DTU->
applyUpdates({{DominatorTree::Insert, &BB, TmpBB},
9421 {DominatorTree::Insert, TmpBB,
TBB},
9422 {DominatorTree::Insert, TmpBB, FBB},
9423 {DominatorTree::Delete, &BB,
TBB}});
9427 if (
Opc == Instruction::Or) {
9449 uint64_t NewTrueWeight = TrueWeight;
9450 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9454 NewTrueWeight = TrueWeight;
9455 NewFalseWeight = 2 * FalseWeight;
9480 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9481 uint64_t NewFalseWeight = FalseWeight;
9485 NewTrueWeight = 2 * TrueWeight;
9486 NewFalseWeight = FalseWeight;
static unsigned getIntrinsicID(const SDNode *N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
This file contains the simple types necessary to represent the attributes associated with functions a...
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool sinkAndCmp0Expression(Instruction *AndI, const TargetLowering &TLI, SetOfInstrs &InsertedInsts)
Duplicate and sink the given 'and' instruction into user blocks where it is used in a compare to allo...
static bool SinkShiftAndTruncate(BinaryOperator *ShiftI, Instruction *User, ConstantInt *CI, DenseMap< BasicBlock *, BinaryOperator * > &InsertedShifts, const TargetLowering &TLI, const DataLayout &DL)
Sink both shift and truncate instruction to the use of truncate's BB.
static bool getGEPSmallConstantIntOffsetV(GetElementPtrInst *GEP, SmallVectorImpl< Value * > &OffsetV)
static bool sinkSelectOperand(const TargetTransformInfo *TTI, Value *V)
Check if V (an operand of a select instruction) is an expensive instruction that is only used once.
static bool isExtractBitsCandidateUse(Instruction *User)
Check if the candidates could be combined with a shift instruction, which includes:
static cl::opt< unsigned > MaxAddressUsersToScan("cgp-max-address-users-to-scan", cl::init(100), cl::Hidden, cl::desc("Max number of address users to look at"))
static bool optimizeBitCast(BitCastInst *BCI, const TargetLowering &TLI, const DataLayout &DL)
Hoists bitcasts to the source block to reduce register pressure.
static cl::opt< bool > OptimizePhiTypes("cgp-optimize-phi-types", cl::Hidden, cl::init(true), cl::desc("Enable converting phi types in CodeGenPrepare"))
static cl::opt< bool > DisableStoreExtract("disable-cgp-store-extract", cl::Hidden, cl::init(false), cl::desc("Disable store(extract) optimizations in CodeGenPrepare"))
static bool foldFCmpToFPClassTest(CmpInst *Cmp, const TargetLowering &TLI, const DataLayout &DL)
static cl::opt< bool > ProfileUnknownInSpecialSection("profile-unknown-in-special-section", cl::Hidden, cl::desc("In profiling mode like sampleFDO, if a function doesn't have " "profile, we cannot tell the function is cold for sure because " "it may be a function newly added without ever being sampled. " "With the flag enabled, compiler can put such profile unknown " "functions into a special section, so runtime system can choose " "to handle it in a different way than .text section, to save " "RAM for example. "))
static bool OptimizeExtractBits(BinaryOperator *ShiftI, ConstantInt *CI, const TargetLowering &TLI, const DataLayout &DL)
Sink the shift right instruction into user blocks if the uses could potentially be combined with this...
static cl::opt< bool > DisableExtLdPromotion("disable-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), cl::desc("Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in " "CodeGenPrepare"))
static cl::opt< bool > DisablePreheaderProtect("disable-preheader-prot", cl::Hidden, cl::init(false), cl::desc("Disable protection against removing loop preheaders"))
static cl::opt< bool > AddrSinkCombineBaseOffs("addr-sink-combine-base-offs", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseOffs field in Address sinking."))
static bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI, const DataLayout &DL)
If the specified cast instruction is a noop copy (e.g.
static bool splitMergedValStore(StoreInst &SI, const DataLayout &DL, const TargetLowering &TLI)
For the instruction sequence of store below, F and I values are bundled together as an i64 value befo...
static bool SinkCast(CastInst *CI)
Sink the specified cast instruction into its user blocks.
static bool swapICmpOperandsToExposeCSEOpportunities(CmpInst *Cmp)
Many architectures use the same instruction for both subtract and cmp.
static cl::opt< bool > AddrSinkCombineBaseReg("addr-sink-combine-base-reg", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseReg field in Address sinking."))
static bool FindAllMemoryUses(Instruction *I, SmallVectorImpl< std::pair< Use *, Type * > > &MemoryUses, SmallPtrSetImpl< Instruction * > &ConsideredInsts, const TargetLowering &TLI, const TargetRegisterInfo &TRI, bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI, unsigned &SeenInsts)
Recursively walk all the uses of I until we find a memory use.
static cl::opt< bool > StressStoreExtract("stress-cgp-store-extract", cl::Hidden, cl::init(false), cl::desc("Stress test store(extract) optimizations in CodeGenPrepare"))
static bool isFormingBranchFromSelectProfitable(const TargetTransformInfo *TTI, const TargetLowering *TLI, SelectInst *SI)
Returns true if a SelectInst should be turned into an explicit branch.
static std::optional< std::pair< Instruction *, Constant * > > getIVIncrement(const PHINode *PN, const LoopInfo *LI)
If given PN is an inductive variable with value IVInc coming from the backedge, and on each iteration...
static cl::opt< bool > AddrSinkCombineBaseGV("addr-sink-combine-base-gv", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseGV field in Address sinking."))
static cl::opt< bool > AddrSinkUsingGEPs("addr-sink-using-gep", cl::Hidden, cl::init(true), cl::desc("Address sinking in CGP using GEPs."))
static Value * getTrueOrFalseValue(SelectInst *SI, bool isTrue, const SmallPtrSet< const Instruction *, 2 > &Selects)
If isTrue is true, return the true value of SI, otherwise return false value of SI.
static cl::opt< bool > DisableBranchOpts("disable-cgp-branch-opts", cl::Hidden, cl::init(false), cl::desc("Disable branch optimizations in CodeGenPrepare"))
static cl::opt< bool > EnableTypePromotionMerge("cgp-type-promotion-merge", cl::Hidden, cl::desc("Enable merging of redundant sexts when one is dominating" " the other."), cl::init(true))
static cl::opt< bool > ProfileGuidedSectionPrefix("profile-guided-section-prefix", cl::Hidden, cl::init(true), cl::desc("Use profile info to add section prefix for hot/cold functions"))
static cl::opt< unsigned > HugeFuncThresholdInCGPP("cgpp-huge-func", cl::init(10000), cl::Hidden, cl::desc("Least BB number of huge function."))
static cl::opt< bool > AddrSinkNewSelects("addr-sink-new-select", cl::Hidden, cl::init(true), cl::desc("Allow creation of selects in Address sinking."))
static bool foldURemOfLoopIncrement(Instruction *Rem, const DataLayout *DL, const LoopInfo *LI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
static bool optimizeBranch(CondBrInst *Branch, const TargetLowering &TLI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
static bool tryUnmergingGEPsAcrossIndirectBr(GetElementPtrInst *GEPI, const TargetTransformInfo *TTI)
static bool IsOperandAMemoryOperand(CallInst *CI, InlineAsm *IA, Value *OpVal, const TargetLowering &TLI, const TargetRegisterInfo &TRI)
Check to see if all uses of OpVal by the specified inline asm call are due to memory operands.
static bool isIntrinsicOrLFToBeTailCalled(const TargetLibraryInfo *TLInfo, const CallInst *CI)
static void replaceAllUsesWith(Value *Old, Value *New, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
Replace all old uses with new ones, and push the updated BBs into FreshBBs.
static cl::opt< bool > ForceSplitStore("force-split-store", cl::Hidden, cl::init(false), cl::desc("Force store splitting no matter what the target query says."))
static bool matchOverflowPattern(Instruction *&I, ExtractValueInst *&MulExtract, ExtractValueInst *&OverflowExtract)
static void computeBaseDerivedRelocateMap(const SmallVectorImpl< GCRelocateInst * > &AllRelocateCalls, MapVector< GCRelocateInst *, SmallVector< GCRelocateInst *, 0 > > &RelocateInstMap)
static bool simplifyRelocatesOffABase(GCRelocateInst *RelocatedBase, const SmallVectorImpl< GCRelocateInst * > &Targets)
static cl::opt< bool > AddrSinkCombineScaledReg("addr-sink-combine-scaled-reg", cl::Hidden, cl::init(true), cl::desc("Allow combining of ScaledReg field in Address sinking."))
static bool foldICmpWithDominatingICmp(CmpInst *Cmp, const TargetLowering &TLI)
For pattern like:
static bool MightBeFoldableInst(Instruction *I)
This is a little filter, which returns true if an addressing computation involving I might be folded ...
static bool matchIncrement(const Instruction *IVInc, Instruction *&LHS, Constant *&Step)
static cl::opt< bool > EnableGEPOffsetSplit("cgp-split-large-offset-gep", cl::Hidden, cl::init(true), cl::desc("Enable splitting large offset of GEP."))
static cl::opt< bool > DisableComplexAddrModes("disable-complex-addr-modes", cl::Hidden, cl::init(false), cl::desc("Disables combining addressing modes with different parts " "in optimizeMemoryInst."))
static cl::opt< bool > EnableICMP_EQToICMP_ST("cgp-icmp-eq2icmp-st", cl::Hidden, cl::init(false), cl::desc("Enable ICMP_EQ to ICMP_S(L|G)T conversion."))
static cl::opt< bool > VerifyBFIUpdates("cgp-verify-bfi-updates", cl::Hidden, cl::init(false), cl::desc("Enable BFI update verification for " "CodeGenPrepare."))
static cl::opt< bool > BBSectionsGuidedSectionPrefix("bbsections-guided-section-prefix", cl::Hidden, cl::init(true), cl::desc("Use the basic-block-sections profile to determine the text " "section prefix for hot functions. Functions with " "basic-block-sections profile will be placed in `.text.hot` " "regardless of their FDO profile info. Other functions won't be " "impacted, i.e., their prefixes will be decided by FDO/sampleFDO " "profiles."))
static bool isRemOfLoopIncrementWithLoopInvariant(Instruction *Rem, const LoopInfo *LI, Value *&RemAmtOut, Value *&AddInstOut, Value *&AddOffsetOut, PHINode *&LoopIncrPNOut)
static bool isIVIncrement(const Value *V, const LoopInfo *LI)
static cl::opt< bool > DisableGCOpts("disable-cgp-gc-opts", cl::Hidden, cl::init(false), cl::desc("Disable GC optimizations in CodeGenPrepare"))
static bool GEPSequentialConstIndexed(GetElementPtrInst *GEP)
static void DbgInserterHelper(DbgVariableRecord *DVR, BasicBlock::iterator VI)
static bool isPromotedInstructionLegal(const TargetLowering &TLI, const DataLayout &DL, Value *Val)
Check whether or not Val is a legal instruction for TLI.
static cl::opt< uint64_t > FreqRatioToSkipMerge("cgp-freq-ratio-to-skip-merge", cl::Hidden, cl::init(2), cl::desc("Skip merging empty blocks if (frequency of empty block) / " "(frequency of destination block) is greater than this ratio"))
static BasicBlock::iterator findInsertPos(Value *Addr, Instruction *MemoryInst, Value *SunkAddr)
static bool IsNonLocalValue(Value *V, BasicBlock *BB)
Return true if the specified values are defined in a different basic block than BB.
static cl::opt< bool > EnableAndCmpSinking("enable-andcmp-sinking", cl::Hidden, cl::init(true), cl::desc("Enable sinking and/cmp into branches."))
static bool despeculateCountZeros(IntrinsicInst *CountZeros, DomTreeUpdater *DTU, LoopInfo *LI, const TargetLowering *TLI, const DataLayout *DL, ModifyDT &ModifiedDT, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
If counting leading or trailing zeros is an expensive operation and a zero input is defined,...
static bool sinkCmpExpression(CmpInst *Cmp, const TargetLowering &TLI, const DataLayout &DL)
Sink the given CmpInst into user blocks to reduce the number of virtual registers that must be create...
static bool hasSameExtUse(Value *Val, const TargetLowering &TLI)
Check if all the uses of Val are equivalent (or free) zero or sign extensions.
static cl::opt< bool > StressExtLdPromotion("stress-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), cl::desc("Stress test ext(promotable(ld)) -> promoted(ext(ld)) " "optimization in CodeGenPrepare"))
static bool matchUAddWithOverflowConstantEdgeCases(CmpInst *Cmp, BinaryOperator *&Add)
Match special-case patterns that check for unsigned add overflow.
static cl::opt< bool > DisableSelectToBranch("disable-cgp-select2branch", cl::Hidden, cl::init(false), cl::desc("Disable select to branch conversion."))
static cl::opt< bool > DisableDeletePHIs("disable-cgp-delete-phis", cl::Hidden, cl::init(false), cl::desc("Disable elimination of dead PHI nodes."))
static cl::opt< bool > AddrSinkNewPhis("addr-sink-new-phis", cl::Hidden, cl::init(false), cl::desc("Allow creation of Phis in Address sinking."))
Defines an IR pass for CodeGen Prepare.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
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 declares the LLVM IR specialization of the GenericCycle templates.
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
static Value * getCondition(Instruction *I)
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU)
Register const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the PointerIntPair class.
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static DominatorTree getDomTree(Function &F)
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, const MachineInstr &B)
Remove Loads Into Fake Uses
static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
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::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, unsigned CombineOpc=0)
This file describes how to lower LLVM code to machine code.
static cl::opt< bool > DisableSelectOptimize("disable-select-optimize", cl::init(true), cl::Hidden, cl::desc("Disable the select-optimization pass from running"))
Disable the select optimization pass.
Target-Independent Code Generator Pass Configuration Options pass.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
static Constant * getConstantVector(MVT VT, ArrayRef< APInt > Bits, const APInt &Undefs, LLVMContext &C)
Class for arbitrary precision integers.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isNegative() const
Determine sign of this APInt.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
unsigned getSignificantBits() const
Get the minimum bit size for this signed APInt.
unsigned logBase2() const
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
int64_t getSExtValue() const
Get sign extended value.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
void setAlignment(Align Align)
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addRequired()
Represent a constant reference to an array (0 or more elements consecutively in memory),...
An instruction that atomically checks whether a specified value is in a memory location,...
static unsigned getPointerOperandIndex()
an instruction that atomically reads a memory location, combines it with another value,...
static unsigned getPointerOperandIndex()
Analysis pass providing the BasicBlockSectionsProfileReader.
LLVM_ABI bool isFunctionHot(StringRef FuncName) const
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
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 void insertDbgRecordBefore(DbgRecord *DR, InstListType::iterator Here)
Insert a DbgRecord into a block at the position given by Here.
InstListType::const_iterator const_iterator
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
LLVM_ABI InstListType::const_iterator getFirstNonPHIOrDbg(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic,...
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
LLVM_ABI void insertDbgRecordAfter(DbgRecord *DR, Instruction *I)
Insert a DbgRecord into a block at the position given by I.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
This class represents a no-op cast from one type to another.
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI void setBlockFreq(const BasicBlock *BB, BlockFrequency Freq)
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
Analysis pass which computes BranchProbabilityInfo.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
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...
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Conditional Branch instruction.
static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
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)
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI void removeFromParent()
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LocationType Type
Classification of the debug-info record that this DbgVariableRecord represents.
LLVM_ABI void replaceVariableLocationOp(Value *OldValue, Value *NewValue, bool AllowEmpty=false)
LLVM_ABI iterator_range< location_op_iterator > location_ops() const
Get the locations corresponding to the variable referenced by the debug info intrinsic.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
LLVM_ABI void deleteBB(BasicBlock *DelBB)
Delete DelBB.
Analysis pass which computes a DominatorTree.
static constexpr UpdateKind Insert
Legacy analysis pass which computes a DominatorTree.
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 instruction compares its operands according to the predicate given to the constructor.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionPass class - This class is used to implement most global optimizations.
const BasicBlock & getEntryBlock() const
LLVM_ABI const Value * getStatepoint() const
The statepoint with which this gc.relocate is associated.
Represents calls to the gc.relocate intrinsic.
unsigned getBasePtrIndex() const
The index into the associate statepoint's argument list which contains the base pointer of the pointe...
void compute(FunctionT &F)
Compute the cycle info for a function.
DomTreeT & getDomTree()
Flush DomTree updates and return DomTree.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
void flush()
Apply all pending updates to available trees and flush all BasicBlocks awaiting deletion.
bool isBBPendingDeletion(BasicBlockT *DelBB) const
Returns true if DelBB is awaiting deletion.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static LLVM_ABI Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)
Returns the result type of a getelementptr with the given source element type and indexes.
LLVM_ABI bool canIncreaseAlignment() const
Returns true if the alignment of the value can be unilaterally increased.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
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.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
LLVM_ABI bool isDebugOrPseudoInst() const LLVM_READONLY
Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
user_iterator_impl< Instruction > user_iterator
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
LLVM_ABI void moveAfter(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Instruction * user_back()
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
iterator_range< user_iterator > users()
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
user_iterator user_begin()
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
LLVM_ABI std::optional< simple_ilist< DbgRecord >::iterator > getDbgReinsertionPosition()
Return an iterator to the position of the "Next" DbgRecord after this instruction,...
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
LLVM_ABI void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
An instruction for reading from memory.
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
Analysis pass that exposes the LoopInfo for a function.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
The legacy pass manager's analysis pass to compute loop information.
Represents a single loop in the control flow graph.
static MVT getIntegerVT(unsigned BitWidth)
This class implements a map that also provides access to all stored values in a deterministic order.
iterator find(const KeyT &Key)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
op_range incoming_values()
Value * getIncomingValueForBlock(const BasicBlock *BB) const
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
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...
PointerIntPair - This class implements a pair of a pointer and small integer.
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.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
void clear()
Completely clear the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
VectorType * getType() const
Overload to return most specific vector type.
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.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator erase(const_iterator CI)
typename SuperClass::iterator iterator
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.
static unsigned getPointerOperandIndex()
TypeSize getElementOffset(unsigned Idx) const
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
LibFunc getLibFunc(StringRef funcName) const
Searches for a particular function name.
int InstructionOpcodeToISD(unsigned Opcode) const
Get the ISD node that corresponds to the Instruction class opcode.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool isSelectSupported(SelectSupportKind) const
virtual bool isEqualityCmpFoldedWithSignedCmp() const
Return true if instruction generated for equality comparison is folded with instruction generated for...
virtual bool shouldFormOverflowOp(unsigned Opcode, EVT VT, bool MathUsed) const
Try to convert math with an overflow comparison into the corresponding DAG node operation.
virtual bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const
Return if the target supports combining a chain like:
virtual bool shouldOptimizeMulOverflowWithZeroHighBits(LLVMContext &Context, EVT VT) const
bool isExtLoad(const LoadInst *Load, const Instruction *Ext, const DataLayout &DL) const
Return true if Load and Ext can form an ExtLoad.
virtual bool isSExtCheaperThanZExt(EVT FromTy, EVT ToTy) const
Return true if sign-extension from FromTy to ToTy is cheaper than zero-extension.
const TargetMachine & getTargetMachine() const
virtual bool isCtpopFast(EVT VT) const
Return true if ctpop instruction is fast.
virtual bool isFreeAddrSpaceCast(const DataLayout &DL, unsigned SrcAS, unsigned DestAS) const
Returns true if a cast from SrcAS to DestAS is "cheap", such that e.g.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
bool enableExtLdPromotion() const
Return true if the target wants to use the optimization that turns ext(promotableInst1(....
virtual unsigned getNumRegisters(LLVMContext &Context, EVT VT, std::optional< MVT > RegisterVT=std::nullopt) const
Return the number of registers that this ValueType will eventually require.
virtual bool isCheapToSpeculateCttz(Type *Ty) const
Return true if it is cheap to speculate a call to intrinsic cttz.
bool isJumpExpensive() const
Return true if Flow Control is an expensive operation that should be avoided.
bool hasExtractBitsInsn() const
Return true if the target has BitExtract instructions.
virtual bool allowsMisalignedMemoryAccesses(EVT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *=nullptr) const
Determine if the target supports unaligned memory accesses.
bool isSlowDivBypassed() const
Returns true if target has indicated at least one type should be bypassed.
virtual bool isTruncateFree(Type *FromTy, Type *ToTy) const
Return true if it's free to truncate a value of type FromTy to type ToTy.
virtual bool hasMultipleConditionRegisters(EVT VT) const
Does the target have multiple (allocatable) condition registers that can be used to store the results...
virtual EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
virtual MVT getPreferredSwitchConditionType(LLVMContext &Context, EVT ConditionVT) const
Returns preferred type for switch condition.
bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const
Return true if the specified condition code is legal for a comparison of the specified types on this ...
virtual bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx, unsigned &Cost) const
Return true if the target can combine store(extractelement VectorTy,Idx).
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual bool shouldConsiderGEPOffsetSplit() const
bool isExtFree(const Instruction *I) const
Return true if the extension represented by I is free.
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
bool isPredictableSelectExpensive() const
Return true if selects are only cheaper than branches if the branch is unlikely to be predicted right...
virtual bool isMultiStoresCheaperThanBitsMerge(EVT LTy, EVT HTy) const
Return true if it is cheaper to split the store of a merged int val from a pair of smaller values int...
virtual bool getAddrModeArguments(const IntrinsicInst *, SmallVectorImpl< Value * > &, Type *&) const
CodeGenPrepare sinks address calculations into the same BB as Load/Store instructions reading the add...
const DenseMap< unsigned int, unsigned int > & getBypassSlowDivWidths() const
Returns map of slow types for division or remainder with corresponding fast types.
virtual bool isCheapToSpeculateCtlz(Type *Ty) const
Return true if it is cheap to speculate a call to intrinsic ctlz.
virtual bool useSoftFloat() const
virtual int64_t getPreferredLargeGEPBaseOffset(int64_t MinOffset, int64_t MaxOffset) const
Return the prefered common base offset.
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
virtual bool shouldAlignPointerArgs(CallInst *, unsigned &, Align &) const
Return true if the pointer arguments to CI should be aligned by aligning the object whose address is ...
virtual Type * shouldConvertSplatType(ShuffleVectorInst *SVI) const
Given a shuffle vector SVI representing a vector splat, return a new scalar type of size equal to SVI...
bool isLoadLegal(EVT ValVT, EVT MemVT, Align Alignment, unsigned AddrSpace, unsigned ExtType, bool Atomic) const
Return true if the specified load with extension is legal on this target.
virtual bool addressingModeSupportsTLS(const GlobalValue &) const
Returns true if the targets addressing mode can target thread local storage (TLS).
virtual bool shouldConvertPhiType(Type *From, Type *To) const
Given a set in interconnected phis of type 'From' that are loaded/stored or bitcast to type 'To',...
virtual bool isFAbsFree(EVT VT) const
Return true if an fabs operation is free to the point where it is never worthwhile to replace it with...
virtual bool preferZeroCompareBranch() const
Return true if the heuristic to prefer icmp eq zero should be used in code gen prepare.
virtual bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AddrSpace, Instruction *I=nullptr) const
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
virtual bool optimizeExtendOrTruncateConversion(Instruction *I, Loop *L, const TargetTransformInfo &TTI) const
Try to optimize extending or truncating conversion instructions (like zext, trunc,...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
std::vector< AsmOperandInfo > AsmOperandInfoVector
virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL, const TargetRegisterInfo *TRI, const CallBase &Call) const
Split up the constraint string from the inline assembly value into the specific constraints and their...
virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op, SelectionDAG *DAG=nullptr) const
Determines the constraint code and constraint type to use for the specific AsmOperandInfo,...
virtual bool mayBeEmittedAsTailCall(const CallInst *) const
Return true if the target may be able emit the call instruction as a tail call.
virtual bool isNoopAddrSpaceCast(const DataLayout &DL, unsigned SrcAS, unsigned DestAS) const
Returns true if a cast between SrcAS and DestAS is a noop.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
unsigned EnableFastISel
EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...
Target-Independent Code Generator Pass Configuration Options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
virtual bool addrSinkUsingGEPs() const
Sink addresses into blocks using GEP instructions rather than pointer casts and arithmetic.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
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 Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
BasicBlock * getSuccessor(unsigned i=0) const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
LLVM_ABI bool isUsedInBasicBlock(const BasicBlock *BB) const
Check if this value is used in the specified basic block.
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
iterator_range< use_iterator > uses()
void mutateType(Type *Ty)
Mutate the type of this Value to be of the specified 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.
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
bool pointsToAliveValue() const
int getNumOccurrences() const
constexpr ScalarTy getFixedValue() const
constexpr bool isNonZero() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned getAddrMode(MCInstrInfo const &MCII, MCInst const &MCI)
@ BasicBlock
Various leaf nodes.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
AllOnesConstantMatch m_AllOnes()
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
match_bind< PHINode > m_Phi(PHINode *&PN)
Match a PHI node, capturing it if we match.
auto m_Cmp()
Matches any compare instruction and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(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::Xor > m_Xor(const LHS &L, const RHS &R)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
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.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap, true > m_c_NUWAdd(const LHS &L, const RHS &R)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_Ctpop(const Opnd0 &Op0)
auto m_Constant()
Match an arbitrary Constant and ignore it.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
UAddWithOverflow_match< LHS_t, RHS_t, Sum_t > m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S)
Match an icmp instruction checking for unsigned overflow on addition.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
auto m_Undef()
Match an arbitrary undef constant.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale)
Compare two scaled numbers.
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ User
could "use" a pointer
NodeAddr< PhiNode * > Phi
NodeAddr< UseNode * > Use
SmallVector< Node, 4 > NodeList
friend class Instruction
Iterator for Instructions in a `BasicBlock.
LLVM_ABI iterator begin() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool RemoveRedundantDbgInstrs(BasicBlock *BB)
Try to remove redundant dbg.value instructions from given basic block.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
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.
LLVM_ABI bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions=false, const TargetLibraryInfo *TLI=nullptr, DomTreeUpdater *DTU=nullptr)
If a terminator instruction is predicated on a constant value, convert it into an unconditional branc...
LLVM_ABI bool bypassSlowDivision(BasicBlock *BB, const DenseMap< unsigned int, unsigned int > &BypassWidth, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BranchProbabilityInfo *BPI=nullptr)
This optimization identifies DIV instructions in a BB that can be profitably bypassed and carried out...
LLVM_ABI void findDbgValues(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)
Finds the dbg.values describing a value.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
APInt operator*(APInt a, uint64_t RHS)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
auto successors(const MachineBasicBlock *BB)
@ Load
The value being inserted comes from a load (InsertElement only).
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI ReturnInst * FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, BasicBlock *Pred, DomTreeUpdater *DTU=nullptr)
This method duplicates the specified return instruction into a predecessor which ends in an unconditi...
bool operator!=(uint64_t V1, const APInt &V2)
constexpr from_range_t from_range
LLVM_ABI BasicBlock * splitBlockBefore(BasicBlock *Old, BasicBlock::iterator SplitPt, DomTreeUpdater *DTU, LoopInfo *LI, MemorySSAUpdater *MSSAU, const Twine &BBName="")
Split the specified block at the specified instruction SplitPt.
LLVM_ABI Instruction * SplitBlockAndInsertIfElse(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ElseBlock=nullptr)
Similar to SplitBlockAndInsertIfThen, but the inserted block is on the false path of the branch.
LLVM_ABI bool SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr, DomTreeUpdater *DTU=nullptr)
LLVM_ABI bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, SmallPtrSetImpl< PHINode * > *KnownNonDeadPHIs=nullptr)
Examine each PHI in the given block and delete it if it is dead.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
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...
constexpr std::enable_if_t< std::is_signed_v< T >, std::pair< T, bool > > AddOverflow(T X, T Y)
Add two signed integers, computing the two's complement truncated result, returning a pair {result,...
LLVM_ABI void DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, bool KeepOneInputPHIs=false)
Delete the specified block, which must have no predecessors.
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
auto unique(Range &&R, Predicate P)
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
LLVM_ABI bool hasBranchWeightOrigin(const Instruction &I)
Check if Branch Weight Metadata has an "expected" field from an llvm.expect* intrinsic.
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
auto dyn_cast_or_null(const Y &Val)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
LLVM_ABI bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, SmallSetVector< Instruction *, 8 > *UnsimplifiedUsers=nullptr)
Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively.
auto reverse(ContainerTy &&C)
LLVM_ABI bool recognizeBSwapOrBitReverseIdiom(Instruction *I, bool MatchBSwaps, bool MatchBitReversals, SmallVectorImpl< Instruction * > &InsertedInsts)
Try to match a bswap or bitreverse idiom.
void sort(IteratorTy Start, IteratorTy End)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI void SplitBlockAndInsertIfThenElse(Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
generic_gep_type_iterator<> gep_type_iterator
LLVM_ABI FunctionPass * createCodeGenPrepareLegacyPass()
createCodeGenPrepareLegacyPass - Transform the code to expose more pattern matching during instructio...
LLVM_ABI ISD::CondCode getFCmpCondCode(FCmpInst::Predicate Pred)
getFCmpCondCode - Return the ISD condition code corresponding to the given LLVM IR floating-point con...
LLVM_ABI bool VerifyLoopInfo
Enable verification of loop info.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
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.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI bool attributesPermitTailCall(const Function *F, const Instruction *I, const ReturnInst *Ret, const TargetLoweringBase &TLI, bool *AllowDifferingSizes=nullptr)
Test if given that the input instruction is in the tail call position, if there is an attribute misma...
LLVM_ABI bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false, DominatorTree *DT=nullptr)
Attempts to merge a block into its predecessor, if possible.
@ Or
Bitwise or logical OR of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I, bool IgnoreUBImplyingAttrs=true)
Don't use information from its non-constant operands.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
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.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI bool VerifyDomInfo
Enables verification of dominator trees.
constexpr unsigned BitWidth
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.
gep_type_iterator gep_type_begin(const User *GEP)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
constexpr std::enable_if_t< std::is_signed_v< T >, std::pair< T, bool > > MulOverflow(T X, T Y)
Multiply two signed integers, computing the two's complement truncated result, returning a pair {resu...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
bool pred_empty(const BasicBlock *BB)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
LLVM_ABI void setFittedBranchWeights(Instruction &I, ArrayRef< uint64_t > Weights, bool IsExpected, bool ElideAllZero=false)
Variant of setBranchWeights where the Weights will be fit first to uint32_t by shifting right.
std::pair< Value *, FPClassTest > fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, Value *RHS, bool LookThroughSrc=true)
Returns a pair of values, which if passed to llvm.is.fpclass, returns the same result as an fcmp with...
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
LLVM_ABI Value * simplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a URem, fold the result or return null.
DenseMap< const Value *, Value * > ValueToValueMap
LLVM_ABI CGPassBuilderOption getCGPassBuilderOption()
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool isRound() const
Return true if the size is a power-of-two number of bytes.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
bool isInteger() const
Return true if this is an integer or a vector integer type.
This contains information for each constraint that we are lowering.