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");
2278 Builder.SetInsertPoint(LoopIncrPN);
2279 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2284 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2289 NewRem->
addIncoming(Start, L->getLoopPreheader());
2294 FreshBBs.
insert(L->getLoopLatch());
2305bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2311bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2315 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2318 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2321 if (unfoldPowerOf2Test(Cmp))
2342 SetOfInstrs &InsertedInsts) {
2345 assert(!InsertedInsts.count(AndI) &&
2346 "Attempting to optimize already optimized and instruction");
2347 (void)InsertedInsts;
2361 for (
auto *U : AndI->
users()) {
2369 if (!CmpC || !CmpC->
isZero())
2384 Use &TheUse = UI.getUse();
2402 TheUse = InsertedAnd;
2419 if (
User->getOpcode() != Instruction::And ||
2425 if ((Cimm & (Cimm + 1)).getBoolValue())
2439 bool MadeChange =
false;
2442 TruncE = TruncI->user_end();
2443 TruncUI != TruncE;) {
2445 Use &TruncTheUse = TruncUI.getUse();
2470 if (UserBB == TruncUserBB)
2474 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2476 if (!InsertedShift && !InsertedTrunc) {
2480 if (ShiftI->
getOpcode() == Instruction::AShr)
2482 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2485 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2493 TruncInsertPt.setHeadBit(
true);
2494 assert(TruncInsertPt != TruncUserBB->
end());
2498 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2499 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2503 TruncTheUse = InsertedTrunc;
2536 bool MadeChange =
false;
2540 Use &TheUse = UI.getUse();
2554 if (UserBB == DefBB) {
2582 if (!InsertedShift) {
2586 if (ShiftI->
getOpcode() == Instruction::AShr)
2588 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2591 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2599 TheUse = InsertedShift;
2647 unsigned SizeInBits = Ty->getScalarSizeInBits();
2648 if (Ty->isVectorTy())
2659 nullptr,
"cond.false");
2661 FreshBBs.
insert(CallBlock);
2668 SplitPt.setHeadBit(
true);
2670 nullptr,
"cond.end");
2672 FreshBBs.
insert(EndBlock);
2677 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2684 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2685 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2686 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2692 Builder.SetInsertPoint(EndBlock, EndBlock->
begin());
2693 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2703 ModifiedDT = ModifyDT::ModifyBBDT;
2707bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2711 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2719 for (
auto &Arg : CI->
args()) {
2724 if (!Arg->getType()->isPointerTy())
2726 APInt
Offset(
DL->getIndexSizeInBits(
2729 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2736 if (AllocaSize && AllocaSize->getKnownMinValue() >= MinSize + Offset2)
2754 MaybeAlign MIDestAlign =
MI->getDestAlign();
2755 if (!MIDestAlign || DestAlign > *MIDestAlign)
2756 MI->setDestAlignment(DestAlign);
2758 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2760 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2761 MTI->setSourceAlignment(SrcAlign);
2771 for (
auto &Arg : CI->
args()) {
2772 if (!Arg->getType()->isPointerTy())
2774 unsigned AS = Arg->getType()->getPointerAddressSpace();
2775 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2781 switch (
II->getIntrinsicID()) {
2784 case Intrinsic::assume:
2786 case Intrinsic::allow_runtime_check:
2787 case Intrinsic::allow_ubsan_check:
2788 case Intrinsic::experimental_widenable_condition: {
2792 if (
II->use_empty()) {
2793 II->eraseFromParent();
2797 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2802 case Intrinsic::objectsize:
2804 case Intrinsic::is_constant:
2806 case Intrinsic::aarch64_stlxr:
2807 case Intrinsic::aarch64_stxr: {
2816 InsertedInsts.insert(ExtVal);
2820 case Intrinsic::launder_invariant_group: {
2821 Value *ArgVal =
II->getArgOperand(0);
2822 auto it = LargeOffsetGEPMap.
find(
II);
2823 if (it != LargeOffsetGEPMap.
end()) {
2827 auto GEPs = std::move(it->second);
2828 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2833 II->eraseFromParent();
2836 case Intrinsic::cttz:
2837 case Intrinsic::ctlz:
2841 case Intrinsic::fshl:
2842 case Intrinsic::fshr:
2843 return optimizeFunnelShift(
II);
2844 case Intrinsic::masked_gather:
2845 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2846 case Intrinsic::masked_scatter:
2847 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2848 case Intrinsic::masked_load:
2851 if (VT->getNumElements() == 1) {
2852 Value *PtrVal =
II->getArgOperand(0);
2854 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2859 case Intrinsic::masked_store:
2863 if (VT->getNumElements() == 1) {
2864 Value *PtrVal =
II->getArgOperand(1);
2866 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2871 case Intrinsic::umul_with_overflow:
2872 return optimizeMulWithOverflow(
II,
false, ModifiedDT);
2873 case Intrinsic::smul_with_overflow:
2874 return optimizeMulWithOverflow(
II,
true, ModifiedDT);
2877 SmallVector<Value *, 2> PtrOps;
2880 while (!PtrOps.
empty()) {
2883 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2897 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2899 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2909 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2910 if (!
F->getReturnType()->isPointerTy())
2913 GlobalVariable *UniformValue =
nullptr;
2914 for (
auto &BB : *
F) {
2919 else if (V != UniformValue)
2927 return UniformValue;
2930 if (
Callee->hasExactDefinition()) {
2931 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2932 bool MadeChange =
false;
2958 switch (
II->getIntrinsicID()) {
2959 case Intrinsic::memset:
2960 case Intrinsic::memcpy:
2961 case Intrinsic::memmove:
2968 if (Callee && TLInfo)
2970 case LibFunc_strcpy:
2971 case LibFunc_strncpy:
2972 case LibFunc_strcat:
2973 case LibFunc_strncat:
3014bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
3015 ModifyDT &ModifiedDT) {
3023 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
3025 PHINode *PN =
nullptr;
3026 ExtractValueInst *EVI =
nullptr;
3027 BitCastInst *BCI =
nullptr;
3047 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
3053 return II->getIntrinsicID() == Intrinsic::lifetime_end;
3059 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
3061 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
3083 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
3090 auto MayBePermittedAsTailCall = [&](
const auto *CI) {
3107 MayBePermittedAsTailCall(CI)) {
3128 MayBePermittedAsTailCall(CI)) {
3135 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
3137 if (!VisitedBBs.
insert(Pred).second)
3139 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
3141 if (CI && CI->
use_empty() && MayBePermittedAsTailCall(CI)) {
3156 for (
auto const &TailCallBB : TailCallBBs) {
3166 BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB));
3167 BFI->setBlockFreq(BB,
3168 (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB)));
3169 ModifiedDT = ModifyDT::ModifyBBDT;
3178 for (
auto *CI : CallInsts) {
3179 for (
auto const *FakeUse : FakeUses) {
3180 auto *ClonedInst = FakeUse->clone();
3198struct ExtAddrMode :
public TargetLowering::AddrMode {
3199 Value *BaseReg =
nullptr;
3200 Value *ScaledReg =
nullptr;
3201 Value *OriginalValue =
nullptr;
3202 bool InBounds =
true;
3206 BaseRegField = 0x01,
3208 BaseOffsField = 0x04,
3209 ScaledRegField = 0x08,
3211 MultipleFields = 0xff
3214 ExtAddrMode() =
default;
3216 void print(raw_ostream &OS)
const;
3223 if (ScaledReg == From)
3227 FieldName
compare(
const ExtAddrMode &other) {
3230 if (BaseReg && other.
BaseReg &&
3232 return MultipleFields;
3233 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3234 return MultipleFields;
3237 return MultipleFields;
3240 if (InBounds != other.InBounds)
3241 return MultipleFields;
3244 unsigned Result = NoField;
3247 if (BaseGV != other.BaseGV)
3249 if (BaseOffs != other.BaseOffs)
3252 Result |= ScaledRegField;
3255 if (Scale && other.
Scale && Scale != other.
Scale)
3259 return MultipleFields;
3261 return static_cast<FieldName
>(
Result);
3271 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3282 case ScaledRegField:
3289 void SetCombinedField(FieldName
Field,
Value *V,
3290 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3295 case ExtAddrMode::BaseRegField:
3298 case ExtAddrMode::BaseGVField:
3301 assert(BaseReg ==
nullptr);
3305 case ExtAddrMode::ScaledRegField:
3310 for (
const ExtAddrMode &AM : AddrModes)
3316 case ExtAddrMode::BaseOffsField:
3319 assert(ScaledReg ==
nullptr);
3329static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3335#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3336void ExtAddrMode::print(raw_ostream &OS)
const {
3337 bool NeedPlus =
false;
3343 BaseGV->printAsOperand(OS,
false);
3348 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3353 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3354 BaseReg->printAsOperand(OS,
false);
3358 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3381class TypePromotionTransaction {
3385 class TypePromotionAction {
3393 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3395 virtual ~TypePromotionAction() =
default;
3402 virtual void undo() = 0;
3407 virtual void commit() {
3413 class InsertionHandler {
3422 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3425 bool HasPrevInstruction;
3429 InsertionHandler(Instruction *Inst) {
3437 if (HasPrevInstruction) {
3445 void insert(Instruction *Inst) {
3446 if (HasPrevInstruction) {
3458 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3463 class InstructionMoveBefore :
public TypePromotionAction {
3465 InsertionHandler Position;
3470 : TypePromotionAction(Inst), Position(Inst) {
3471 LLVM_DEBUG(
dbgs() <<
"Do: move: " << *Inst <<
"\nbefore: " << *Before
3477 void undo()
override {
3479 Position.insert(Inst);
3484 class OperandSetter :
public TypePromotionAction {
3493 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3494 : TypePromotionAction(Inst), Idx(Idx) {
3496 <<
"for:" << *Inst <<
"\n"
3497 <<
"with:" << *NewVal <<
"\n");
3503 void undo()
override {
3505 <<
"for: " << *Inst <<
"\n"
3506 <<
"with: " << *Origin <<
"\n");
3513 class OperandsHider :
public TypePromotionAction {
3515 SmallVector<Value *, 4> OriginalValues;
3519 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3522 OriginalValues.
reserve(NumOpnds);
3523 for (
unsigned It = 0; It < NumOpnds; ++It) {
3535 void undo()
override {
3537 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3543 class TruncBuilder :
public TypePromotionAction {
3550 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3552 Builder.SetCurrentDebugLocation(
DebugLoc());
3553 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3558 Value *getBuiltValue() {
return Val; }
3561 void undo()
override {
3564 IVal->eraseFromParent();
3569 class SExtBuilder :
public TypePromotionAction {
3576 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3577 : TypePromotionAction(InsertPt) {
3579 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3584 Value *getBuiltValue() {
return Val; }
3587 void undo()
override {
3590 IVal->eraseFromParent();
3595 class ZExtBuilder :
public TypePromotionAction {
3602 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3603 : TypePromotionAction(InsertPt) {
3605 Builder.SetCurrentDebugLocation(
DebugLoc());
3606 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3611 Value *getBuiltValue() {
return Val; }
3614 void undo()
override {
3617 IVal->eraseFromParent();
3622 class TypeMutator :
public TypePromotionAction {
3628 TypeMutator(Instruction *Inst,
Type *NewTy)
3629 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3630 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3636 void undo()
override {
3637 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3644 class UsesReplacer :
public TypePromotionAction {
3646 struct InstructionAndIdx {
3653 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3654 : Inst(Inst), Idx(Idx) {}
3660 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3670 UsesReplacer(Instruction *Inst,
Value *New)
3671 : TypePromotionAction(Inst),
New(
New) {
3672 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3675 for (Use &U : Inst->
uses()) {
3677 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3688 void undo()
override {
3690 for (InstructionAndIdx &Use : OriginalUses)
3691 Use.Inst->setOperand(
Use.Idx, Inst);
3696 for (DbgVariableRecord *DVR : DbgVariableRecords)
3697 DVR->replaceVariableLocationOp(New, Inst);
3702 class InstructionRemover :
public TypePromotionAction {
3704 InsertionHandler Inserter;
3708 OperandsHider Hider;
3711 UsesReplacer *Replacer =
nullptr;
3714 SetOfInstrs &RemovedInsts;
3721 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3722 Value *New =
nullptr)
3723 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3724 RemovedInsts(RemovedInsts) {
3726 Replacer =
new UsesReplacer(Inst, New);
3727 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3728 RemovedInsts.insert(Inst);
3735 ~InstructionRemover()
override {
delete Replacer; }
3737 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3738 InstructionRemover(
const InstructionRemover &other) =
delete;
3742 void undo()
override {
3743 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3744 Inserter.insert(Inst);
3748 RemovedInsts.erase(Inst);
3756 using ConstRestorationPt =
const TypePromotionAction *;
3758 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3759 : RemovedInsts(RemovedInsts) {}
3766 void rollback(ConstRestorationPt Point);
3769 ConstRestorationPt getRestorationPoint()
const;
3774 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3783 void mutateType(Instruction *Inst,
Type *NewTy);
3786 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3799 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3801 SetOfInstrs &RemovedInsts;
3806void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3808 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3809 Inst, Idx, NewVal));
3812void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3815 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3816 Inst, RemovedInsts, NewVal));
3819void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3822 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3825void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3827 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3830Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3831 std::unique_ptr<TruncBuilder> Ptr(
new TruncBuilder(Opnd, Ty));
3832 Value *Val = Ptr->getBuiltValue();
3833 Actions.push_back(std::move(Ptr));
3837Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3839 std::unique_ptr<SExtBuilder> Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3840 Value *Val = Ptr->getBuiltValue();
3841 Actions.push_back(std::move(Ptr));
3845Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3847 std::unique_ptr<ZExtBuilder> Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3848 Value *Val = Ptr->getBuiltValue();
3849 Actions.push_back(std::move(Ptr));
3853TypePromotionTransaction::ConstRestorationPt
3854TypePromotionTransaction::getRestorationPoint()
const {
3855 return !Actions.empty() ? Actions.back().get() :
nullptr;
3858bool TypePromotionTransaction::commit() {
3859 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3866void TypePromotionTransaction::rollback(
3867 TypePromotionTransaction::ConstRestorationPt Point) {
3868 while (!Actions.empty() && Point != Actions.back().get()) {
3869 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3879class AddressingModeMatcher {
3880 SmallVectorImpl<Instruction *> &AddrModeInsts;
3881 const TargetLowering &TLI;
3882 const TargetRegisterInfo &
TRI;
3883 const DataLayout &
DL;
3885 const std::function<
const DominatorTree &()> getDTFn;
3898 const SetOfInstrs &InsertedInsts;
3901 InstrToOrigTy &PromotedInsts;
3904 TypePromotionTransaction &TPT;
3907 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3911 bool IgnoreProfitability;
3914 bool OptSize =
false;
3916 ProfileSummaryInfo *PSI;
3917 BlockFrequencyInfo *BFI;
3919 AddressingModeMatcher(
3920 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3921 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3922 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3923 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3924 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3925 TypePromotionTransaction &TPT,
3926 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3927 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI)
3928 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3929 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3930 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3931 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3932 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI), BFI(BFI) {
3933 IgnoreProfitability =
false;
3945 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3946 SmallVectorImpl<Instruction *> &AddrModeInsts,
3947 const TargetLowering &TLI,
const LoopInfo &LI,
3948 const std::function<
const DominatorTree &()> getDTFn,
3949 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3950 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3951 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3952 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
3955 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3956 AccessTy, AS, MemoryInst, Result,
3957 InsertedInsts, PromotedInsts, TPT,
3958 LargeOffsetGEP, OptSize, PSI, BFI)
3966 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3968 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3969 bool *MovedAway =
nullptr);
3970 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3971 ExtAddrMode &AMBefore,
3972 ExtAddrMode &AMAfter);
3973 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3974 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3975 Value *PromotedOperand)
const;
3981class PhiNodeSetIterator {
3982 PhiNodeSet *
const Set;
3983 size_t CurrentIndex = 0;
3988 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3990 PhiNodeSetIterator &operator++();
4006 friend class PhiNodeSetIterator;
4008 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
4009 using iterator = PhiNodeSetIterator;
4024 size_t FirstValidElement = 0;
4030 bool insert(PHINode *Ptr) {
4031 if (NodeMap.insert(std::make_pair(Ptr,
NodeList.
size())).second) {
4041 bool erase(PHINode *Ptr) {
4042 if (NodeMap.erase(Ptr)) {
4043 SkipRemovedElements(FirstValidElement);
4053 FirstValidElement = 0;
4059 if (FirstValidElement == 0)
4060 SkipRemovedElements(FirstValidElement);
4061 return PhiNodeSetIterator(
this, FirstValidElement);
4068 size_t size()
const {
return NodeMap.size(); }
4071 size_t count(PHINode *Ptr)
const {
return NodeMap.count(Ptr); }
4079 void SkipRemovedElements(
size_t &CurrentIndex) {
4081 auto it = NodeMap.find(NodeList[CurrentIndex]);
4084 if (it != NodeMap.end() && it->second == CurrentIndex)
4091PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
4094PHINode *PhiNodeSetIterator::operator*()
const {
4096 "PhiNodeSet access out of range");
4097 return Set->NodeList[CurrentIndex];
4100PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
4102 "PhiNodeSet access out of range");
4104 Set->SkipRemovedElements(CurrentIndex);
4108bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
4109 return CurrentIndex ==
RHS.CurrentIndex;
4112bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
4113 return !((*this) ==
RHS);
4119class SimplificationTracker {
4120 DenseMap<Value *, Value *> Storage;
4123 PhiNodeSet AllPhiNodes;
4125 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
4130 auto SV = Storage.
find(V);
4131 if (SV == Storage.
end())
4139 void ReplacePhi(PHINode *From, PHINode *To) {
4140 Value *OldReplacement = Get(From);
4141 while (OldReplacement != From) {
4144 OldReplacement = Get(From);
4146 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
4149 AllPhiNodes.erase(From);
4153 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
4155 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
4157 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
4159 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4161 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4163 void destroyNewNodes(
Type *CommonType) {
4166 for (
auto *
I : AllPhiNodes) {
4167 I->replaceAllUsesWith(Dummy);
4168 I->eraseFromParent();
4170 AllPhiNodes.clear();
4171 for (
auto *
I : AllSelectNodes) {
4172 I->replaceAllUsesWith(Dummy);
4173 I->eraseFromParent();
4175 AllSelectNodes.clear();
4180class AddressingModeCombiner {
4181 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4182 typedef std::pair<PHINode *, PHINode *> PHIPair;
4189 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4192 bool AllAddrModesTrivial =
true;
4195 Type *CommonType =
nullptr;
4197 const DataLayout &
DL;
4203 Value *CommonValue =
nullptr;
4206 AddressingModeCombiner(
const DataLayout &
DL,
Value *OriginalValue)
4207 :
DL(
DL), Original(OriginalValue) {}
4209 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4212 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4217 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4221 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4224 if (AddrModes.
empty()) {
4232 ExtAddrMode::FieldName ThisDifferentField =
4233 AddrModes[0].compare(NewAddrMode);
4234 if (DifferentField == ExtAddrMode::NoField)
4235 DifferentField = ThisDifferentField;
4236 else if (DifferentField != ThisDifferentField)
4237 DifferentField = ExtAddrMode::MultipleFields;
4240 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4243 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4248 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4253 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4254 !NewAddrMode.HasBaseReg);
4271 bool combineAddrModes() {
4273 if (AddrModes.
size() == 0)
4277 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4282 if (AllAddrModesTrivial)
4285 if (!addrModeCombiningAllowed())
4291 FoldAddrToValueMapping
Map;
4292 if (!initializeMap(Map))
4295 CommonValue = findCommon(Map);
4297 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4298 return CommonValue !=
nullptr;
4304 void eraseCommonValueIfDead() {
4305 if (CommonValue && CommonValue->
use_empty())
4307 CommonInst->eraseFromParent();
4315 bool initializeMap(FoldAddrToValueMapping &Map) {
4318 SmallVector<Value *, 2> NullValue;
4320 for (
auto &AM : AddrModes) {
4324 if (CommonType && CommonType !=
Type)
4327 Map[AM.OriginalValue] = DV;
4332 assert(CommonType &&
"At least one non-null value must be!");
4333 for (
auto *V : NullValue)
4361 Value *findCommon(FoldAddrToValueMapping &Map) {
4369 SimplificationTracker
ST;
4374 InsertPlaceholders(Map, TraverseOrder, ST);
4377 FillPlaceholders(Map, TraverseOrder, ST);
4380 ST.destroyNewNodes(CommonType);
4385 unsigned PhiNotMatchedCount = 0;
4387 ST.destroyNewNodes(CommonType);
4391 auto *
Result =
ST.Get(
Map.find(Original)->second);
4393 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4394 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4401 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4402 SmallSetVector<PHIPair, 8> &Matcher,
4403 PhiNodeSet &PhiNodesToMatch) {
4406 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4409 SmallSet<PHIPair, 8> Visited;
4410 while (!WorkList.
empty()) {
4412 if (!Visited.
insert(Item).second)
4419 for (
auto *
B : Item.first->blocks()) {
4420 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4421 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4422 if (FirstValue == SecondValue)
4432 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4437 if (Matcher.
count({FirstPhi, SecondPhi}))
4442 if (MatchedPHIs.
insert(FirstPhi).second)
4443 Matcher.
insert({FirstPhi, SecondPhi});
4445 WorkList.
push_back({FirstPhi, SecondPhi});
4454 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4455 unsigned &PhiNotMatchedCount) {
4459 SmallSetVector<PHIPair, 8> Matched;
4460 SmallPtrSet<PHINode *, 8> WillNotMatch;
4461 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4462 while (PhiNodesToMatch.size()) {
4463 PHINode *
PHI = *PhiNodesToMatch.begin();
4466 WillNotMatch.
clear();
4470 bool IsMatched =
false;
4471 for (
auto &
P :
PHI->getParent()->phis()) {
4473 if (PhiNodesToMatch.count(&
P))
4475 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4485 for (
auto MV : Matched)
4486 ST.ReplacePhi(MV.first, MV.second);
4491 if (!AllowNewPhiNodes)
4494 PhiNotMatchedCount += WillNotMatch.
size();
4495 for (
auto *
P : WillNotMatch)
4496 PhiNodesToMatch.erase(
P);
4501 void FillPlaceholders(FoldAddrToValueMapping &Map,
4502 SmallVectorImpl<Value *> &TraverseOrder,
4503 SimplificationTracker &ST) {
4504 while (!TraverseOrder.
empty()) {
4506 assert(
Map.contains(Current) &&
"No node to fill!!!");
4512 auto *TrueValue = CurrentSelect->getTrueValue();
4513 assert(
Map.contains(TrueValue) &&
"No True Value!");
4514 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4515 auto *FalseValue = CurrentSelect->getFalseValue();
4516 assert(
Map.contains(FalseValue) &&
"No False Value!");
4517 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4524 assert(
Map.contains(PV) &&
"No predecessor Value!");
4525 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4536 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4537 SmallVectorImpl<Value *> &TraverseOrder,
4538 SimplificationTracker &ST) {
4541 "Address must be a Phi or Select node");
4544 while (!Worklist.
empty()) {
4547 if (
Map.contains(Current))
4558 CurrentSelect->getName(),
4559 CurrentSelect->getIterator(), CurrentSelect);
4563 Worklist.
push_back(CurrentSelect->getTrueValue());
4564 Worklist.
push_back(CurrentSelect->getFalseValue());
4572 ST.insertNewPhi(
PHI);
4578 bool addrModeCombiningAllowed() {
4581 switch (DifferentField) {
4584 case ExtAddrMode::BaseRegField:
4586 case ExtAddrMode::BaseGVField:
4588 case ExtAddrMode::BaseOffsField:
4590 case ExtAddrMode::ScaledRegField:
4600bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4605 return matchAddr(ScaleReg,
Depth);
4616 ExtAddrMode TestAddrMode =
AddrMode;
4620 TestAddrMode.
Scale += Scale;
4634 ConstantInt *CI =
nullptr;
4635 Value *AddLHS =
nullptr;
4639 TestAddrMode.InBounds =
false;
4656 auto GetConstantStep =
4657 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4660 return std::nullopt;
4663 return std::nullopt;
4671 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4672 return std::nullopt;
4674 return std::make_pair(IVInc->first, ConstantStep->getValue());
4675 return std::nullopt;
4690 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4697 APInt Step = IVStep->second;
4699 if (
Offset.isSignedIntN(64)) {
4700 TestAddrMode.InBounds =
false;
4702 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4707 getDTFn().
dominates(IVInc, MemoryInst)) {
4727 switch (
I->getOpcode()) {
4728 case Instruction::BitCast:
4729 case Instruction::AddrSpaceCast:
4731 if (
I->getType() ==
I->getOperand(0)->getType())
4733 return I->getType()->isIntOrPtrTy();
4734 case Instruction::PtrToInt:
4737 case Instruction::IntToPtr:
4740 case Instruction::Add:
4742 case Instruction::Mul:
4743 case Instruction::Shl:
4746 case Instruction::GetElementPtr:
4774class TypePromotionHelper {
4777 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4778 Instruction *ExtOpnd,
bool IsSExt) {
4779 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4780 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4784 if (It->second.getInt() == ExtTy)
4790 ExtTy = BothExtension;
4792 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4799 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4800 Instruction *Opnd,
bool IsSExt) {
4801 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4802 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4803 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4804 return It->second.getPointer();
4819 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4820 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4824 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4837 static Value *promoteOperandForTruncAndAnyExt(
4838 Instruction *Ext, TypePromotionTransaction &TPT,
4839 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4840 SmallVectorImpl<Instruction *> *Exts,
4841 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4852 static Value *promoteOperandForOther(Instruction *Ext,
4853 TypePromotionTransaction &TPT,
4854 InstrToOrigTy &PromotedInsts,
4855 unsigned &CreatedInstsCost,
4856 SmallVectorImpl<Instruction *> *Exts,
4857 SmallVectorImpl<Instruction *> *Truncs,
4858 const TargetLowering &TLI,
bool IsSExt);
4861 static Value *signExtendOperandForOther(
4862 Instruction *Ext, TypePromotionTransaction &TPT,
4863 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4864 SmallVectorImpl<Instruction *> *Exts,
4865 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4866 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4867 Exts, Truncs, TLI,
true);
4871 static Value *zeroExtendOperandForOther(
4872 Instruction *Ext, TypePromotionTransaction &TPT,
4873 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4874 SmallVectorImpl<Instruction *> *Exts,
4875 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4876 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4877 Exts, Truncs, TLI,
false);
4882 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4883 InstrToOrigTy &PromotedInsts,
4884 unsigned &CreatedInstsCost,
4885 SmallVectorImpl<Instruction *> *Exts,
4886 SmallVectorImpl<Instruction *> *Truncs,
4887 const TargetLowering &TLI);
4898 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4899 const TargetLowering &TLI,
4900 const InstrToOrigTy &PromotedInsts);
4905bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4906 Type *ConsideredExtType,
4907 const InstrToOrigTy &PromotedInsts,
4927 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4928 (IsSExt && BinOp->hasNoSignedWrap())))
4932 if ((Inst->
getOpcode() == Instruction::And ||
4937 if (Inst->
getOpcode() == Instruction::Xor) {
4940 if (!Cst->getValue().isAllOnes())
4949 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4959 if (ExtInst->hasOneUse()) {
4961 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4994 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
5007TypePromotionHelper::Action TypePromotionHelper::getAction(
5008 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
5009 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
5011 "Unexpected instruction type");
5018 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
5031 return promoteOperandForTruncAndAnyExt;
5037 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
5040Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
5041 Instruction *SExt, TypePromotionTransaction &TPT,
5042 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5043 SmallVectorImpl<Instruction *> *Exts,
5044 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
5048 Value *ExtVal = SExt;
5049 bool HasMergedNonFreeExt =
false;
5053 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
5056 TPT.replaceAllUsesWith(SExt, ZExt);
5057 TPT.eraseInstruction(SExt);
5062 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
5064 CreatedInstsCost = 0;
5068 TPT.eraseInstruction(SExtOpnd);
5076 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
5084 TPT.eraseInstruction(ExtInst, NextVal);
5088Value *TypePromotionHelper::promoteOperandForOther(
5089 Instruction *Ext, TypePromotionTransaction &TPT,
5090 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5091 SmallVectorImpl<Instruction *> *Exts,
5092 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
5097 CreatedInstsCost = 0;
5103 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
5106 ITrunc->moveAfter(ExtOpnd);
5111 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
5114 TPT.setOperand(Ext, 0, ExtOpnd);
5124 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
5126 TPT.mutateType(ExtOpnd, Ext->
getType());
5128 TPT.replaceAllUsesWith(Ext, ExtOpnd);
5131 for (
int OpIdx = 0, EndOpIdx = ExtOpnd->
getNumOperands(); OpIdx != EndOpIdx;
5135 !shouldExtOperand(ExtOpnd, OpIdx)) {
5144 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
5146 TPT.setOperand(ExtOpnd, OpIdx, ConstantInt::get(Ext->
getType(), CstVal));
5157 Value *ValForExtOpnd = IsSExt
5158 ? TPT.createSExt(ExtOpnd, Opnd, Ext->
getType())
5159 : TPT.createZExt(ExtOpnd, Opnd, Ext->
getType());
5160 TPT.setOperand(ExtOpnd, OpIdx, ValForExtOpnd);
5162 if (!InstForExtOpnd)
5168 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5171 TPT.eraseInstruction(Ext);
5183bool AddressingModeMatcher::isPromotionProfitable(
5184 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5185 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5190 if (NewCost > OldCost)
5192 if (NewCost < OldCost)
5211bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5223 case Instruction::PtrToInt:
5226 case Instruction::IntToPtr: {
5234 case Instruction::BitCast:
5244 case Instruction::AddrSpaceCast: {
5252 case Instruction::Add: {
5255 ExtAddrMode BackupAddrMode =
AddrMode;
5256 unsigned OldSize = AddrModeInsts.
size();
5261 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5262 TPT.getRestorationPoint();
5266 int First = 0, Second = 1;
5277 AddrModeInsts.
resize(OldSize);
5278 TPT.rollback(LastKnownGood);
5288 AddrModeInsts.
resize(OldSize);
5289 TPT.rollback(LastKnownGood);
5295 case Instruction::Mul:
5296 case Instruction::Shl: {
5300 if (!
RHS ||
RHS->getBitWidth() > 64)
5302 int64_t Scale = Opcode == Instruction::Shl
5303 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5304 :
RHS->getSExtValue();
5308 case Instruction::GetElementPtr: {
5311 int VariableOperand = -1;
5312 unsigned VariableScale = 0;
5314 int64_t ConstantOffset = 0;
5316 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5318 const StructLayout *SL =
DL.getStructLayout(STy);
5329 if (ConstantInt *CI =
5331 const APInt &CVal = CI->
getValue();
5338 if (VariableOperand != -1)
5342 VariableOperand = i;
5343 VariableScale = TypeSize;
5350 if (VariableOperand == -1) {
5351 AddrMode.BaseOffs += ConstantOffset;
5357 AddrMode.BaseOffs -= ConstantOffset;
5361 ConstantOffset > 0) {
5374 BasicBlock *Parent = BaseI ? BaseI->getParent()
5375 : &
GEP->getFunction()->getEntryBlock();
5377 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5385 ExtAddrMode BackupAddrMode =
AddrMode;
5386 unsigned OldSize = AddrModeInsts.
size();
5389 AddrMode.BaseOffs += ConstantOffset;
5398 AddrModeInsts.
resize(OldSize);
5406 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5411 AddrModeInsts.
resize(OldSize);
5416 AddrMode.BaseOffs += ConstantOffset;
5417 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5418 VariableScale,
Depth)) {
5421 AddrModeInsts.
resize(OldSize);
5428 case Instruction::SExt:
5429 case Instruction::ZExt: {
5436 TypePromotionHelper::Action TPH =
5437 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5441 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5442 TPT.getRestorationPoint();
5443 unsigned CreatedInstsCost = 0;
5445 Value *PromotedOperand =
5446 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5461 assert(PromotedOperand &&
5462 "TypePromotionHelper should have filtered out those cases");
5464 ExtAddrMode BackupAddrMode =
AddrMode;
5465 unsigned OldSize = AddrModeInsts.
size();
5467 if (!matchAddr(PromotedOperand,
Depth) ||
5472 !isPromotionProfitable(CreatedInstsCost,
5473 ExtCost + (AddrModeInsts.
size() - OldSize),
5476 AddrModeInsts.
resize(OldSize);
5477 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5478 TPT.rollback(LastKnownGood);
5483 AddrMode.replaceWith(Ext, PromotedOperand);
5486 case Instruction::Call:
5488 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5504bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5507 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5508 TPT.getRestorationPoint();
5532 ExtAddrMode BackupAddrMode =
AddrMode;
5533 unsigned OldSize = AddrModeInsts.
size();
5536 bool MovedAway =
false;
5537 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5545 if (
I->hasOneUse() ||
5546 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5553 AddrModeInsts.
resize(OldSize);
5554 TPT.rollback(LastKnownGood);
5557 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5559 TPT.rollback(LastKnownGood);
5586 TPT.rollback(LastKnownGood);
5605 if (OpInfo.CallOperandVal == OpVal &&
5607 !OpInfo.isIndirect))
5623 if (!ConsideredInsts.
insert(
I).second)
5631 for (
Use &U :
I->uses()) {
5639 MemoryUses.push_back({&U, LI->getType()});
5646 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5653 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5660 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5670 if (!
find(PtrOps, U.get()))
5673 MemoryUses.push_back({&U, AccessTy});
5678 if (CI->hasFnAttr(Attribute::Cold)) {
5696 PSI, BFI, SeenInsts))
5707 unsigned SeenInsts = 0;
5710 PSI, BFI, SeenInsts);
5718bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5720 Value *KnownLive2) {
5722 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5763bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5764 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5765 if (IgnoreProfitability)
5783 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5784 ScaledReg =
nullptr;
5788 if (!BaseReg && !ScaledReg)
5809 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5812 Type *AddressAccessTy = Pair.second;
5813 unsigned AS =
Address->getType()->getPointerAddressSpace();
5819 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5821 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5822 TPT.getRestorationPoint();
5823 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5824 AddressAccessTy, AS, UserI, Result,
5825 InsertedInsts, PromotedInsts, TPT,
5826 LargeOffsetGEP, OptSize, PSI, BFI);
5827 Matcher.IgnoreProfitability =
true;
5835 TPT.rollback(LastKnownGood);
5841 MatchedAddrModeInsts.
clear();
5851 return I->getParent() != BB;
5867 return std::next(AddrInst->getIterator());
5878 Earliest = UserInst;
5903bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5904 Type *AccessTy,
unsigned AddrSpace) {
5909 SmallVector<Value *, 8> worklist;
5910 SmallPtrSet<Value *, 16> Visited;
5916 bool PhiOrSelectSeen =
false;
5917 SmallVector<Instruction *, 16> AddrModeInsts;
5918 AddressingModeCombiner AddrModes(*
DL, Addr);
5919 TypePromotionTransaction TPT(RemovedInsts);
5920 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5921 TPT.getRestorationPoint();
5922 while (!worklist.
empty()) {
5934 if (!Visited.
insert(V).second)
5940 PhiOrSelectSeen =
true;
5947 PhiOrSelectSeen =
true;
5954 AddrModeInsts.
clear();
5955 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5960 auto getDTFn = [
this]() ->
const DominatorTree & {
return getDT(); };
5961 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5962 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5963 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5966 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5971 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5972 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5975 NewAddrMode.OriginalValue =
V;
5976 if (!AddrModes.addNewAddrMode(NewAddrMode))
5983 if (!AddrModes.combineAddrModes()) {
5984 TPT.rollback(LastKnownGood);
5990 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5996 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
6010 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
6032 <<
" for " << *MemoryInst <<
"\n");
6036 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6042 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
6044 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6046 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6053 <<
" for " << *MemoryInst <<
"\n");
6054 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
6065 if (ResultPtr ||
AddrMode.Scale != 1)
6086 GlobalValue *BaseGV =
AddrMode.BaseGV;
6087 if (BaseGV !=
nullptr) {
6092 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
6101 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
6102 if (!ResultPtr &&
AddrMode.BaseReg) {
6106 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
6107 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
6116 }
else if (!ResultPtr) {
6130 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
6143 "We can't transform if ScaledReg is too narrow");
6144 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
6148 V = Builder.CreateMul(
6151 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6162 if (ResultPtr->
getType() != I8PtrTy)
6163 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6164 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6177 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6179 SunkAddr = ResultPtr;
6181 if (ResultPtr->
getType() != I8PtrTy)
6182 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6183 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6190 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6196 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
6198 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6200 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6210 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6211 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6212 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6214 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6218 <<
" for " << *MemoryInst <<
"\n");
6229 if (
V->getType()->isPointerTy())
6230 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6232 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
6241 }
else if (
V->getType()->isPointerTy()) {
6242 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6245 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
6254 I->eraseFromParent();
6258 V = Builder.CreateMul(
6261 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6267 GlobalValue *BaseGV =
AddrMode.BaseGV;
6268 if (BaseGV !=
nullptr) {
6271 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6275 Value *
V = Builder.CreatePtrToInt(BaseGVPtr,
IntPtrTy,
"sunkaddr");
6277 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6286 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6294 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6300 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6305 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6306 RecursivelyDeleteTriviallyDeadInstructions(
6307 Repl, TLInfo, nullptr,
6308 [&](Value *V) { removeAllAssertingVHReferences(V); });
6332bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6338 if (!
GEP->hasIndices())
6346 SmallVector<Value *, 2>
Ops(
GEP->operands());
6348 bool RewriteGEP =
false;
6357 unsigned FinalIndex =
Ops.size() - 1;
6362 for (
unsigned i = 1; i < FinalIndex; ++i) {
6367 C =
C->getSplatValue();
6369 if (!CI || !CI->
isZero())
6376 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6380 if (!
C || !
C->isZero()) {
6381 Ops[FinalIndex] =
V;
6389 if (!RewriteGEP &&
Ops.size() == 2)
6396 Type *SourceTy =
GEP->getSourceElementType();
6397 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6401 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6402 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6403 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6413 if (
Ops.size() != 2) {
6423 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6437 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6438 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6441 Intrinsic::masked_gather) {
6445 Intrinsic::masked_scatter);
6460 Ptr, TLInfo,
nullptr,
6461 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6472 if (
I->hasNUsesOrMore(3))
6475 for (
User *U :
I->users()) {
6477 if (!Extract || Extract->getNumIndices() != 1)
6480 unsigned Index = Extract->getIndices()[0];
6482 MulExtract = Extract;
6483 else if (Index == 1)
6484 OverflowExtract = Extract;
6511bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
6512 ModifyDT &ModifiedDT) {
6519 ExtractValueInst *MulExtract =
nullptr, *OverflowExtract =
nullptr;
6524 InsertedInsts.insert(
I);
6535 OverflowEntryBB->
takeName(
I->getParent());
6541 NoOverflowBB->
moveAfter(OverflowEntryBB);
6549 Value *LoLHS = Builder.CreateTrunc(
LHS, LegalTy,
"lo.lhs");
6550 Value *HiLHS = Builder.CreateLShr(
LHS, VTHalfBitWidth,
"lhs.lsr");
6551 HiLHS = Builder.CreateTrunc(HiLHS, LegalTy,
"hi.lhs");
6554 Value *LoRHS = Builder.CreateTrunc(
RHS, LegalTy,
"lo.rhs");
6555 Value *HiRHS = Builder.CreateLShr(
RHS, VTHalfBitWidth,
"rhs.lsr");
6556 HiRHS = Builder.CreateTrunc(HiRHS, LegalTy,
"hi.rhs");
6558 Value *IsAnyBitTrue;
6561 Builder.CreateAShr(LoLHS, VTHalfBitWidth - 1,
"sign.lo.lhs");
6563 Builder.CreateAShr(LoRHS, VTHalfBitWidth - 1,
"sign.lo.rhs");
6564 Value *XorLHS = Builder.CreateXor(HiLHS, SignLoLHS);
6565 Value *XorRHS = Builder.CreateXor(HiRHS, SignLoRHS);
6566 Value *
Or = Builder.CreateOr(XorLHS, XorRHS,
"or.lhs.rhs");
6567 IsAnyBitTrue = Builder.CreateCmp(ICmpInst::ICMP_NE,
Or,
6568 ConstantInt::getNullValue(
Or->getType()));
6570 Value *CmpLHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiLHS,
6571 ConstantInt::getNullValue(LegalTy));
6572 Value *CmpRHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiRHS,
6573 ConstantInt::getNullValue(LegalTy));
6574 IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS,
"or.lhs.rhs");
6576 Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
6579 Builder.SetInsertPoint(NoOverflowBB);
6580 Value *ExtLoLHS, *ExtLoRHS;
6582 ExtLoLHS = Builder.CreateSExt(LoLHS, Ty,
"lo.lhs.ext");
6583 ExtLoRHS = Builder.CreateSExt(LoRHS, Ty,
"lo.rhs.ext");
6585 ExtLoLHS = Builder.CreateZExt(LoLHS, Ty,
"lo.lhs.ext");
6586 ExtLoRHS = Builder.CreateZExt(LoRHS, Ty,
"lo.rhs.ext");
6589 Value *
Mul = Builder.CreateMul(ExtLoLHS, ExtLoRHS,
"mul.overflow.no");
6594 OverflowResBB->
setName(
"overflow.res");
6597 Builder.CreateBr(OverflowResBB);
6605 PHINode *OverflowResPHI = Builder.CreatePHI(Ty, 2),
6607 Builder.CreatePHI(IntegerType::getInt1Ty(
I->getContext()), 2);
6619 if (OverflowExtract) {
6620 OverflowExtract->replaceAllUsesWith(OverflowFlagPHI);
6621 OverflowExtract->eraseFromParent();
6626 I->removeFromParent();
6628 I->insertInto(OverflowBB, OverflowBB->
end());
6629 Builder.SetInsertPoint(OverflowBB, OverflowBB->
end());
6631 Value *OverflowFlag = Builder.CreateExtractValue(
I, {1},
"overflow.flag");
6632 Builder.CreateBr(OverflowResBB);
6636 OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
6638 DTU->
applyUpdates({{DominatorTree::Insert, OverflowEntryBB, OverflowBB},
6639 {DominatorTree::Insert, OverflowEntryBB, NoOverflowBB},
6640 {DominatorTree::Insert, NoOverflowBB, OverflowResBB},
6641 {DominatorTree::Delete, OverflowEntryBB, OverflowResBB},
6642 {DominatorTree::Insert, OverflowBB, OverflowResBB}});
6644 ModifiedDT = ModifyDT::ModifyBBDT;
6650bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6651 bool MadeChange =
false;
6653 const TargetRegisterInfo *
TRI =
6658 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6664 OpInfo.isIndirect) {
6666 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6729bool CodeGenPrepare::tryToPromoteExts(
6730 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6731 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6732 unsigned CreatedInstsCost) {
6733 bool Promoted =
false;
6736 for (
auto *
I : Exts) {
6751 TypePromotionHelper::Action TPH =
6752 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6761 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6762 TPT.getRestorationPoint();
6763 SmallVector<Instruction *, 4> NewExts;
6764 unsigned NewCreatedInstsCost = 0;
6767 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6768 &NewExts,
nullptr, *TLI);
6770 "TypePromotionHelper should have filtered out those cases");
6780 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6783 TotalCreatedInstsCost =
6784 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6786 (TotalCreatedInstsCost > 1 ||
6788 (ExtCost == 0 && NewExts.
size() > 1))) {
6792 TPT.rollback(LastKnownGood);
6797 SmallVector<Instruction *, 2> NewlyMovedExts;
6798 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6799 bool NewPromoted =
false;
6800 for (
auto *ExtInst : NewlyMovedExts) {
6810 ProfitablyMovedExts.
push_back(MovedExt);
6817 TPT.rollback(LastKnownGood);
6828bool CodeGenPrepare::mergeSExts(
Function &
F) {
6830 for (
auto &Entry : ValToSExtendedUses) {
6831 SExts &Insts =
Entry.second;
6833 for (Instruction *Inst : Insts) {
6837 bool inserted =
false;
6838 for (
auto &Pt : CurPts) {
6841 RemovedInsts.insert(Pt);
6842 Pt->removeFromParent();
6853 RemovedInsts.insert(Inst);
6860 CurPts.push_back(Inst);
6902bool CodeGenPrepare::splitLargeGEPOffsets() {
6904 for (
auto &Entry : LargeOffsetGEPMap) {
6906 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6907 &LargeOffsetGEPs =
Entry.second;
6908 auto compareGEPOffset =
6909 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6910 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6911 if (
LHS.first ==
RHS.first)
6913 if (
LHS.second !=
RHS.second)
6914 return LHS.second <
RHS.second;
6915 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6918 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6921 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6923 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6924 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6925 Value *NewBaseGEP =
nullptr;
6927 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6928 GetElementPtrInst *
GEP) {
6929 LLVMContext &Ctx =
GEP->getContext();
6930 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6932 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6944 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), &getDT(), LI);
6947 NewBaseInsertPt = std::next(BaseI->getIterator());
6954 IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
6960 NewBaseGEP = OldBase;
6961 if (NewBaseGEP->
getType() != I8PtrTy)
6962 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6964 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6965 NewGEPBases.
insert(NewBaseGEP);
6971 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6972 BaseOffset = PreferBase;
6975 createNewBase(BaseOffset, OldBase, BaseGEP);
6978 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6979 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6980 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6981 int64_t
Offset = LargeOffsetGEP->second;
6982 if (
Offset != BaseOffset) {
6989 GEP->getResultElementType(),
6990 GEP->getAddressSpace())) {
6996 NewBaseGEP =
nullptr;
7001 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
7006 createNewBase(BaseOffset, OldBase,
GEP);
7010 Value *NewGEP = NewBaseGEP;
7011 if (
Offset != BaseOffset) {
7014 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
7018 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
7019 GEP->eraseFromParent();
7026bool CodeGenPrepare::optimizePhiType(
7027 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
7028 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
7033 Type *PhiTy =
I->getType();
7034 Type *ConvertTy =
nullptr;
7036 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
7039 SmallVector<Instruction *, 4> Worklist;
7041 SmallPtrSet<PHINode *, 4> PhiNodes;
7042 SmallPtrSet<ConstantData *, 4>
Constants;
7045 SmallPtrSet<Instruction *, 4> Defs;
7046 SmallPtrSet<Instruction *, 4>
Uses;
7052 bool AnyAnchored =
false;
7054 while (!Worklist.
empty()) {
7059 for (
Value *V :
Phi->incoming_values()) {
7061 if (!PhiNodes.
count(OpPhi)) {
7062 if (!Visited.
insert(OpPhi).second)
7068 if (!OpLoad->isSimple())
7070 if (Defs.
insert(OpLoad).second)
7073 if (Defs.
insert(OpEx).second)
7077 ConvertTy = OpBC->getOperand(0)->getType();
7078 if (OpBC->getOperand(0)->getType() != ConvertTy)
7080 if (Defs.
insert(OpBC).second) {
7093 for (User *V :
II->users()) {
7095 if (!PhiNodes.
count(OpPhi)) {
7096 if (Visited.
count(OpPhi))
7103 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
7105 Uses.insert(OpStore);
7108 ConvertTy = OpBC->getType();
7109 if (OpBC->getType() != ConvertTy)
7113 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
7120 if (!ConvertTy || !AnyAnchored || PhiTy == ConvertTy ||
7124 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
7125 << *ConvertTy <<
"\n");
7130 for (ConstantData *
C : Constants)
7132 for (Instruction *
D : Defs) {
7134 ValMap[
D] =
D->getOperand(0);
7138 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
7141 for (PHINode *Phi : PhiNodes)
7143 Phi->getName() +
".tc",
Phi->getIterator());
7145 for (PHINode *Phi : PhiNodes) {
7147 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
7149 Phi->getIncomingBlock(i));
7153 for (Instruction *U :
Uses) {
7158 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
7168bool CodeGenPrepare::optimizePhiTypes(
Function &
F) {
7173 SmallPtrSet<PHINode *, 4> Visited;
7174 SmallPtrSet<Instruction *, 4> DeletedInstrs;
7178 for (
auto &Phi : BB.
phis())
7179 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
7182 for (
auto *
I : DeletedInstrs) {
7184 I->eraseFromParent();
7192bool CodeGenPrepare::canFormExtLd(
7193 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
7194 Instruction *&Inst,
bool HasPromoted) {
7195 for (
auto *MovedExtInst : MovedExts) {
7198 Inst = MovedExtInst;
7250bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7251 bool AllowPromotionWithoutCommonHeader =
false;
7256 *Inst, AllowPromotionWithoutCommonHeader);
7257 TypePromotionTransaction TPT(RemovedInsts);
7258 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7259 TPT.getRestorationPoint();
7261 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7264 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7267 LoadInst *LI =
nullptr;
7272 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7273 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7278 Inst = ExtFedByLoad;
7283 if (ATPConsiderable &&
7284 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7285 HasPromoted, TPT, SpeculativelyMovedExts))
7288 TPT.rollback(LastKnownGood);
7297bool CodeGenPrepare::performAddressTypePromotion(
7298 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7299 bool HasPromoted, TypePromotionTransaction &TPT,
7300 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7301 bool Promoted =
false;
7302 SmallPtrSet<Instruction *, 1> UnhandledExts;
7303 bool AllSeenFirst =
true;
7304 for (
auto *
I : SpeculativelyMovedExts) {
7305 Value *HeadOfChain =
I->getOperand(0);
7306 auto AlreadySeen = SeenChainsForSExt.
find(HeadOfChain);
7309 if (AlreadySeen != SeenChainsForSExt.
end()) {
7310 if (AlreadySeen->second !=
nullptr)
7311 UnhandledExts.
insert(AlreadySeen->second);
7312 AllSeenFirst =
false;
7316 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7317 SpeculativelyMovedExts.size() == 1)) {
7321 for (
auto *
I : SpeculativelyMovedExts) {
7322 Value *HeadOfChain =
I->getOperand(0);
7323 SeenChainsForSExt[HeadOfChain] =
nullptr;
7324 ValToSExtendedUses[HeadOfChain].push_back(
I);
7327 Inst = SpeculativelyMovedExts.pop_back_val();
7332 for (
auto *
I : SpeculativelyMovedExts) {
7333 Value *HeadOfChain =
I->getOperand(0);
7334 SeenChainsForSExt[HeadOfChain] = Inst;
7339 if (!AllSeenFirst && !UnhandledExts.
empty())
7340 for (
auto *VisitedSExt : UnhandledExts) {
7341 if (RemovedInsts.count(VisitedSExt))
7343 TypePromotionTransaction TPT(RemovedInsts);
7345 SmallVector<Instruction *, 2> Chains;
7347 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7351 for (
auto *
I : Chains) {
7352 Value *HeadOfChain =
I->getOperand(0);
7354 SeenChainsForSExt[HeadOfChain] =
nullptr;
7355 ValToSExtendedUses[HeadOfChain].push_back(
I);
7361bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7366 Value *Src =
I->getOperand(0);
7367 if (Src->hasOneUse())
7379 bool DefIsLiveOut =
false;
7380 for (User *U :
I->users()) {
7385 if (UserBB == DefBB)
7387 DefIsLiveOut =
true;
7394 for (User *U : Src->users()) {
7397 if (UserBB == DefBB)
7406 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7408 bool MadeChange =
false;
7414 if (UserBB == DefBB)
7418 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7420 if (!InsertedTrunc) {
7423 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7425 InsertedInsts.insert(InsertedTrunc);
7488bool CodeGenPrepare::optimizeLoadExt(LoadInst *
Load) {
7489 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7493 if (
Load->hasOneUse() &&
7499 SmallVector<Instruction *, 8> WorkList;
7500 SmallPtrSet<Instruction *, 16> Visited;
7501 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7502 SmallVector<Instruction *, 8> DropFlags;
7503 for (
auto *U :
Load->users())
7515 while (!WorkList.
empty()) {
7519 if (!Visited.
insert(
I).second)
7524 for (
auto *U :
Phi->users())
7529 switch (
I->getOpcode()) {
7530 case Instruction::And: {
7534 APInt AndBits = AndC->getValue();
7535 DemandBits |= AndBits;
7537 if (AndBits.
ugt(WidestAndBits))
7538 WidestAndBits = AndBits;
7539 if (AndBits == WidestAndBits &&
I->getOperand(0) ==
Load)
7544 case Instruction::Shl: {
7549 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7554 case Instruction::Trunc: {
7557 DemandBits.setLowBits(TruncBitWidth);
7567 uint32_t ActiveBits = DemandBits.getActiveBits();
7579 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7580 WidestAndBits != DemandBits)
7583 LLVMContext &Ctx =
Load->getType()->getContext();
7584 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7595 Builder.CreateAnd(
Load, ConstantInt::get(Ctx, DemandBits)));
7598 InsertedInsts.insert(NewAnd);
7603 NewAnd->setOperand(0,
Load);
7606 for (
auto *
And : AndsToMaybeRemove)
7611 if (&*CurInstIterator ==
And)
7612 CurInstIterator = std::next(
And->getIterator());
7613 And->eraseFromParent();
7618 for (
auto *Inst : DropFlags)
7632 TTI->isExpensiveToSpeculativelyExecute(
I);
7650 uint64_t Max = std::max(TrueWeight, FalseWeight);
7651 uint64_t Sum = TrueWeight + FalseWeight;
7654 if (Probability >
TTI->getPredictableBranchThreshold())
7664 if (!Cmp || !Cmp->hasOneUse())
7687 assert(DefSI->getCondition() ==
SI->getCondition() &&
7688 "The condition of DefSI does not match with SI");
7689 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7692 assert(V &&
"Failed to get select true/false value");
7696bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7720 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7721 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7722 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7723 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7729bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7731 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7732 "Expected a funnel shift");
7756 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7757 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7758 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7766bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7778 It !=
SI->getParent()->
end(); ++It) {
7780 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7787 SelectInst *LastSI = ASI.
back();
7790 CurInstIterator = std::next(LastSI->
getIterator());
7794 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7795 fixupDbgVariableRecordsOnInst(*SI);
7797 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7800 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7803 TargetLowering::SelectSupportKind SelectKind;
7804 if (
SI->getType()->isVectorTy())
7805 SelectKind = TargetLowering::ScalarCondVectorVal;
7807 SelectKind = TargetLowering::ScalarValSelect;
7844 SmallVector<Instruction *> TrueInstrs, FalseInstrs;
7845 for (SelectInst *SI : ASI) {
7857 SplitPt.setHeadBit(
true);
7860 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7865 UncondBrInst *TrueBranch =
nullptr;
7866 UncondBrInst *FalseBranch =
nullptr;
7867 if (TrueInstrs.
size() == 0) {
7872 }
else if (FalseInstrs.
size() == 0) {
7889 EndBlock->
setName(
"select.end");
7891 TrueBlock->
setName(
"select.true.sink");
7893 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7894 :
"select.false.sink");
7898 FreshBBs.
insert(TrueBlock);
7900 FreshBBs.
insert(FalseBlock);
7901 FreshBBs.
insert(EndBlock);
7906 static const unsigned MD[] = {
7907 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7908 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7913 for (Instruction *
I : TrueInstrs)
7915 for (Instruction *
I : FalseInstrs)
7922 if (TrueBlock ==
nullptr)
7923 TrueBlock = StartBlock;
7924 else if (FalseBlock ==
nullptr)
7925 FalseBlock = StartBlock;
7941 SI->eraseFromParent();
7943 ++NumSelectsExpanded;
7947 CurInstIterator = StartBlock->
end();
7954bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7966 "Expected a type of the same size!");
7972 Builder.SetInsertPoint(SVI);
7973 Value *BC1 = Builder.CreateBitCast(
7975 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7976 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7980 SVI, TLInfo,
nullptr,
7981 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7988 !
Op->isTerminator() && !
Op->isEHPad())
7994bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
8009 for (Use *U :
reverse(OpsToSink)) {
8021 SetVector<Instruction *> MaybeDead;
8022 DenseMap<Instruction *, Instruction *> NewInstructions;
8023 for (Use *U : ToReplace) {
8032 FreshBBs.
insert(OpDef->getParent());
8035 NewInstructions[UI] = NI;
8040 InsertedInsts.insert(NI);
8046 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
8047 It->second->setOperand(
U->getOperandNo(), NI);
8054 for (
auto *
I : MaybeDead) {
8055 if (!
I->hasNUsesOrMore(1)) {
8057 I->eraseFromParent();
8064bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
8070 unsigned RegWidth =
RegType.getSizeInBits();
8081 auto *NewType = Type::getIntNTy(
Context, RegWidth);
8090 ExtType = Instruction::SExt;
8093 if (Arg->hasSExtAttr())
8094 ExtType = Instruction::SExt;
8095 if (Arg->hasZExtAttr())
8096 ExtType = Instruction::ZExt;
8102 SI->setCondition(ExtInst);
8103 for (
auto Case :
SI->cases()) {
8104 const APInt &NarrowConst = Case.getCaseValue()->getValue();
8105 APInt WideConst = (ExtType == Instruction::ZExt)
8106 ? NarrowConst.
zext(RegWidth)
8107 : NarrowConst.
sext(RegWidth);
8108 Case.setValue(ConstantInt::get(
Context, WideConst));
8114bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
8121 Value *Condition =
SI->getCondition();
8130 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
8131 ConstantInt *CaseValue = Case.getCaseValue();
8132 BasicBlock *CaseBB = Case.getCaseSuccessor();
8135 bool CheckedForSinglePred =
false;
8136 for (PHINode &
PHI : CaseBB->
phis()) {
8137 Type *PHIType =
PHI.getType();
8145 if (PHIType == ConditionType || TryZExt) {
8147 bool SkipCase =
false;
8148 Value *Replacement =
nullptr;
8149 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
8150 Value *PHIValue =
PHI.getIncomingValue(
I);
8151 if (PHIValue != CaseValue) {
8160 if (
PHI.getIncomingBlock(
I) != SwitchBB)
8165 if (!CheckedForSinglePred) {
8166 CheckedForSinglePred =
true;
8167 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
8173 if (Replacement ==
nullptr) {
8174 if (PHIValue == CaseValue) {
8175 Replacement = Condition;
8178 Replacement = Builder.CreateZExt(Condition, PHIType);
8181 PHI.setIncomingValue(
I, Replacement);
8192bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
8193 bool Changed = optimizeSwitchType(SI);
8194 Changed |= optimizeSwitchPhiConstants(SI);
8215class VectorPromoteHelper {
8217 const DataLayout &
DL;
8220 const TargetLowering &TLI;
8223 const TargetTransformInfo &
TTI;
8229 SmallVector<Instruction *, 4> InstsToBePromoted;
8232 unsigned StoreExtractCombineCost;
8241 if (InstsToBePromoted.
empty())
8243 return InstsToBePromoted.
back();
8249 unsigned getTransitionOriginalValueIdx()
const {
8251 "Other kind of transitions are not supported yet");
8258 unsigned getTransitionIdx()
const {
8260 "Other kind of transitions are not supported yet");
8268 Type *getTransitionType()
const {
8279 void promoteImpl(Instruction *ToBePromoted);
8283 bool isProfitableToPromote() {
8284 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8288 Type *PromotedType = getTransitionType();
8291 unsigned AS =
ST->getPointerAddressSpace();
8309 for (
const auto &Inst : InstsToBePromoted) {
8317 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8329 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8330 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8331 return ScalarCost > VectorCost;
8343 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8358 if (!
EC.isScalable()) {
8359 SmallVector<Constant *, 4> ConstVec;
8361 for (
unsigned Idx = 0; Idx !=
EC.getKnownMinValue(); ++Idx) {
8362 if (Idx == ExtractIdx)
8370 "Generate scalable vector for non-splat is unimplemented");
8375 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8376 unsigned OperandIdx) {
8379 if (OperandIdx != 1)
8381 switch (
Use->getOpcode()) {
8384 case Instruction::SDiv:
8385 case Instruction::UDiv:
8386 case Instruction::SRem:
8387 case Instruction::URem:
8389 case Instruction::FDiv:
8390 case Instruction::FRem:
8391 return !
Use->hasNoNaNs();
8397 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8398 const TargetTransformInfo &
TTI, Instruction *Transition,
8399 unsigned CombineCost)
8400 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8401 StoreExtractCombineCost(CombineCost) {
8402 assert(Transition &&
"Do not know how to promote null");
8406 bool canPromote(
const Instruction *ToBePromoted)
const {
8413 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8416 for (
const Use &U : ToBePromoted->
operands()) {
8417 const Value *Val =
U.get();
8418 if (Val == getEndOfTransition()) {
8422 if (canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()))
8445 void enqueueForPromotion(Instruction *ToBePromoted) {
8446 InstsToBePromoted.push_back(ToBePromoted);
8450 void recordCombineInstruction(Instruction *ToBeCombined) {
8452 CombineInst = ToBeCombined;
8462 if (InstsToBePromoted.empty() || !CombineInst)
8470 for (
auto &ToBePromoted : InstsToBePromoted)
8471 promoteImpl(ToBePromoted);
8472 InstsToBePromoted.clear();
8479void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8489 "The type of the result of the transition does not match "
8494 Type *TransitionTy = getTransitionType();
8499 for (Use &U : ToBePromoted->
operands()) {
8501 Value *NewVal =
nullptr;
8502 if (Val == Transition)
8503 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8510 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8514 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8517 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8523bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8524 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8539 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8540 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost);
8547 if (ToBePromoted->
getParent() != Parent) {
8548 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8550 <<
") than the transition (" << Parent->
getName()
8555 if (VPH.canCombine(ToBePromoted)) {
8557 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8558 VPH.recordCombineInstruction(ToBePromoted);
8560 NumStoreExtractExposed +=
Changed;
8565 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8568 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8570 VPH.enqueueForPromotion(ToBePromoted);
8571 Inst = ToBePromoted;
8611 Type *StoreType =
SI.getValueOperand()->getType();
8620 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8621 DL.getTypeSizeInBits(StoreType) == 0)
8624 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8626 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8642 if (!
match(
SI.getValueOperand(),
8649 if (!
LValue->getType()->isIntegerTy() ||
8650 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8652 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8668 Builder.SetInsertPoint(&
SI);
8672 if (LBC && LBC->getParent() !=
SI.getParent())
8673 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8674 if (HBC && HBC->getParent() !=
SI.getParent())
8675 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8677 bool IsLE =
SI.getDataLayout().isLittleEndian();
8678 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8679 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8680 Value *Addr =
SI.getPointerOperand();
8681 Align Alignment =
SI.getAlign();
8682 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8683 if (IsOffsetStore) {
8684 Addr = Builder.CreateGEP(
8685 SplitStoreType, Addr,
8693 Builder.CreateAlignedStore(V, Addr, Alignment);
8696 CreateSplitStore(
LValue,
false);
8697 CreateSplitStore(HValue,
true);
8700 SI.eraseFromParent();
8708 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8790 if (GEPIOpI->getParent() != SrcBlock)
8795 if (auto *I = dyn_cast<Instruction>(Usr)) {
8796 if (I->getParent() != SrcBlock) {
8804 std::vector<GetElementPtrInst *> UGEPIs;
8807 for (User *Usr : GEPIOp->
users()) {
8826 if (UGEPI->getOperand(0) != GEPIOp)
8828 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8830 if (GEPIIdx->getType() !=
8838 UGEPIs.push_back(UGEPI);
8840 if (UGEPIs.size() == 0)
8843 for (GetElementPtrInst *UGEPI : UGEPIs) {
8845 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8852 for (GetElementPtrInst *UGEPI : UGEPIs) {
8853 UGEPI->setOperand(0, GEPI);
8855 auto NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8856 Constant *NewUGEPIIdx = ConstantInt::get(GEPIIdx->getType(), NewIdx);
8857 UGEPI->setOperand(1, NewUGEPIIdx);
8859 auto SourceFlags = GEPI->getNoWrapFlags();
8862 UGEPI->getNoWrapFlags().intersectForOffsetAdd(SourceFlags);
8864 if (NewIdx.
isNegative() && TargetFlags.hasNoUnsignedWrap())
8865 TargetFlags = TargetFlags.withoutNoUnsignedWrap();
8866 UGEPI->setNoWrapFlags(TargetFlags);
8872 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8874 "GEPIOp is used outside SrcBlock");
8898 Value *
X = Cmp->getOperand(0);
8899 if (!
X->hasUseList())
8904 for (
auto *U :
X->users()) {
8908 (UI->
getParent() != Branch->getParent() &&
8909 UI->
getParent() != Branch->getSuccessor(0) &&
8910 UI->
getParent() != Branch->getSuccessor(1)) ||
8911 (UI->
getParent() != Branch->getParent() &&
8912 !UI->
getParent()->getSinglePredecessor()))
8918 if (UI->
getParent() != Branch->getParent())
8922 ConstantInt::get(UI->
getType(), 0));
8924 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8928 if (Cmp->isEquality() &&
8933 if (UI->
getParent() != Branch->getParent())
8936 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8937 ConstantInt::get(UI->
getType(), 0));
8939 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8947bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8948 bool AnyChange =
false;
8949 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8953 if (InsertedInsts.count(
I))
8962 LargeOffsetGEPMap.erase(
P);
8964 P->eraseFromParent();
8995 I, LI->getLoopFor(
I->getParent()), *
TTI))
9003 TargetLowering::TypeExpandInteger) {
9007 I, LI->getLoopFor(
I->getParent()), *
TTI))
9010 bool MadeChange = optimizeExt(
I);
9011 return MadeChange | optimizeExtUses(
I);
9018 if (optimizeCmp(Cmp, ModifiedDT))
9022 if (optimizeURem(
I))
9026 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
9027 bool Modified = optimizeLoadExt(LI);
9036 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
9037 unsigned AS =
SI->getPointerAddressSpace();
9038 return optimizeMemoryInst(
I,
SI->getOperand(1),
9039 SI->getOperand(0)->getType(), AS);
9043 unsigned AS = RMW->getPointerAddressSpace();
9044 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
9048 unsigned AS = CmpX->getPointerAddressSpace();
9049 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
9050 CmpX->getCompareOperand()->getType(), AS);
9060 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
9061 BinOp->
getOpcode() == Instruction::LShr)) {
9069 if (GEPI->hasAllZeroIndices()) {
9071 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
9072 GEPI->getName(), GEPI->getIterator());
9073 NC->setDebugLoc(GEPI->getDebugLoc());
9076 GEPI, TLInfo,
nullptr,
9077 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9079 optimizeInst(
NC, ModifiedDT);
9097 if (Const0 || Const1) {
9098 if (!Const0 || !Const1) {
9099 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
9105 FI->eraseFromParent();
9112 if (tryToSinkFreeOperands(
I))
9115 switch (
I->getOpcode()) {
9116 case Instruction::Shl:
9117 case Instruction::LShr:
9118 case Instruction::AShr:
9120 case Instruction::Call:
9122 case Instruction::Select:
9124 case Instruction::ShuffleVector:
9126 case Instruction::Switch:
9128 case Instruction::ExtractElement:
9130 case Instruction::CondBr:
9139bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
9140 if (!
I.getType()->isIntegerTy() ||
9145 SmallVector<Instruction *, 4> Insts;
9151 &
I, TLInfo,
nullptr,
9152 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9159bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
9161 bool MadeChange =
false;
9164 CurInstIterator = BB.
begin();
9165 ModifiedDT = ModifyDT::NotModifyDT;
9166 while (CurInstIterator != BB.
end()) {
9167 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
9168 if (ModifiedDT != ModifyDT::NotModifyDT) {
9177 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
9179 bool MadeBitReverse =
true;
9180 while (MadeBitReverse) {
9181 MadeBitReverse =
false;
9183 if (makeBitReverse(
I)) {
9184 MadeBitReverse = MadeChange =
true;
9189 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
9194bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
9195 bool AnyChange =
false;
9196 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
9197 AnyChange |= fixupDbgVariableRecord(DVR);
9203bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
9204 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
9205 DVR.
Type != DbgVariableRecord::LocationType::Assign)
9209 bool AnyChange =
false;
9210 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
9212 for (
Value *Location : LocationOps) {
9213 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9242bool CodeGenPrepare::placeDbgValues(
Function &
F) {
9243 bool MadeChange =
false;
9244 DominatorTree &DT = getDT();
9246 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9247 SmallVector<Instruction *, 4> VIs;
9248 for (
Value *V : DbgItem->location_ops())
9256 for (Instruction *VI : VIs) {
9257 if (
VI->isTerminator())
9262 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9273 if (VIs.size() > 1) {
9276 <<
"Unable to find valid location for Debug Value, undefing:\n"
9278 DbgItem->setKillLocation();
9283 << *DbgItem <<
' ' << *VI);
9290 for (BasicBlock &BB :
F) {
9296 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9298 DbgProcessor(&DVR, &Insn);
9309bool CodeGenPrepare::placePseudoProbes(
Function &
F) {
9310 bool MadeChange =
false;
9313 auto FirstInst =
Block.getFirstInsertionPt();
9314 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9318 while (
I !=
Block.end()) {
9320 II->moveBefore(FirstInst);
9350bool CodeGenPrepare::splitBranchCondition(
Function &
F) {
9354 bool MadeChange =
false;
9355 for (
auto &BB :
F) {
9368 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9376 Value *Cond1, *Cond2;
9379 Opc = Instruction::And;
9382 Opc = Instruction::Or;
9392 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9406 Br1->setCondition(Cond1);
9411 if (
Opc == Instruction::And)
9412 Br1->setSuccessor(0, TmpBB);
9414 Br1->setSuccessor(1, TmpBB);
9419 I->removeFromParent();
9420 I->insertBefore(Br2->getIterator());
9432 if (
Opc == Instruction::Or)
9436 TBB->replacePhiUsesWith(&BB, TmpBB);
9439 for (PHINode &PN : FBB->
phis()) {
9444 if (
Loop *L = LI->getLoopFor(&BB))
9445 L->addBasicBlockToLoop(TmpBB, *LI);
9449 DTU->
applyUpdates({{DominatorTree::Insert, &BB, TmpBB},
9450 {DominatorTree::Insert, TmpBB,
TBB},
9451 {DominatorTree::Insert, TmpBB, FBB},
9452 {DominatorTree::Delete, &BB,
TBB}});
9456 if (
Opc == Instruction::Or) {
9478 uint64_t NewTrueWeight = TrueWeight;
9479 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9483 NewTrueWeight = TrueWeight;
9484 NewFalseWeight = 2 * FalseWeight;
9509 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9510 uint64_t NewFalseWeight = FalseWeight;
9514 NewTrueWeight = 2 * TrueWeight;
9515 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 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 isFreeAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const
Returns true if a cast from SrcAS to DestAS is "cheap", such that e.g.
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(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)
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
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.
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...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
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
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.
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.