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);
1145bool CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
1155 if (SinglePred != DestBB) {
1156 assert(SinglePred == BB &&
1157 "Single predecessor not the same as predecessor");
1166 FreshBBs.
insert(SinglePred);
1167 FreshBBs.
erase(DestBB);
1175 for (PHINode &PN : DestBB->
phis()) {
1177 Value *InVal = PN.removeIncomingValue(BB,
false);
1182 if (InValPhi && InValPhi->
getParent() == BB) {
1191 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1192 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1195 PN.addIncoming(InVal, Pred);
1209 SmallPtrSet<BasicBlock *, 8> SeenPreds;
1213 if (!PredOfDestBB.contains(Pred)) {
1214 if (SeenPreds.
insert(Pred).second)
1215 DTUpdates.
push_back({DominatorTree::Insert, Pred, DestBB});
1220 if (SeenPreds.
insert(Pred).second)
1221 DTUpdates.
push_back({DominatorTree::Delete, Pred, BB});
1223 DTUpdates.
push_back({DominatorTree::Delete, BB, DestBB});
1243 for (
auto *ThisRelocate : AllRelocateCalls) {
1244 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1245 ThisRelocate->getDerivedPtrIndex());
1246 RelocateIdxMap.
insert(std::make_pair(K, ThisRelocate));
1248 for (
auto &Item : RelocateIdxMap) {
1249 std::pair<unsigned, unsigned>
Key = Item.first;
1250 if (
Key.first ==
Key.second)
1255 auto BaseKey = std::make_pair(
Key.first,
Key.first);
1258 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1259 if (MaybeBase == RelocateIdxMap.
end())
1264 RelocateInstMap[MaybeBase->second].push_back(
I);
1272 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1275 if (!
Op ||
Op->getZExtValue() > 20)
1279 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1289 bool MadeChange =
false;
1296 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1297 &*R != RelocatedBase; ++R)
1301 RelocatedBase->
moveBefore(RI->getIterator());
1308 "Not relocating a derived object of the original base object");
1309 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1314 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1324 if (!Derived || Derived->getPointerOperand() !=
Base)
1333 "Should always have one since it's not a terminator");
1337 Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
1361 Value *ActualRelocatedBase = RelocatedBase;
1362 if (RelocatedBase->
getType() !=
Base->getType()) {
1363 ActualRelocatedBase =
1364 Builder.CreateBitCast(RelocatedBase,
Base->getType());
1366 Value *Replacement =
1367 Builder.CreateGEP(Derived->getSourceElementType(), ActualRelocatedBase,
1373 Value *ActualReplacement = Replacement;
1374 if (Replacement->
getType() != ToReplace->getType()) {
1376 Builder.CreateBitCast(Replacement, ToReplace->
getType());
1379 ToReplace->eraseFromParent();
1403bool CodeGenPrepare::simplifyOffsetableRelocate(GCStatepointInst &
I) {
1404 bool MadeChange =
false;
1406 for (
auto *U :
I.users())
1413 if (AllRelocateCalls.
size() < 2)
1418 MapVector<GCRelocateInst *, SmallVector<GCRelocateInst *, 0>> RelocateInstMap;
1420 if (RelocateInstMap.
empty())
1423 for (
auto &Item : RelocateInstMap)
1437 bool MadeChange =
false;
1440 Use &TheUse = UI.getUse();
1447 UserBB = PN->getIncomingBlock(TheUse);
1455 if (
User->isEHPad())
1465 if (UserBB == DefBB)
1469 CastInst *&InsertedCast = InsertedCasts[UserBB];
1471 if (!InsertedCast) {
1479 TheUse = InsertedCast;
1498 if (!SrcInst || SrcInst->getParent() == BCI->
getParent() ||
1499 SrcInst->isTerminator())
1503 Type *SrcTy = SrcInst->getType();
1517 bool IsCrossDomain = DestTy->
isFPOrFPVectorTy() != SrcTy->isFPOrFPVectorTy();
1520 unsigned NativeWidth =
DL.getPointerSizeInBits();
1521 bool IsLargeScalar =
1523 DL.getTypeSizeInBits(DestTy).getFixedValue() > NativeWidth;
1525 if (IsCrossDomain || IsLargeScalar)
1531 : std::next(SrcInst->getIterator());
1548 ASC->getDestAddressSpace()))
1603static std::optional<std::pair<Instruction *, Constant *>>
1606 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1607 return std::nullopt;
1610 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1611 return std::nullopt;
1615 return std::make_pair(IVInc, Step);
1616 return std::nullopt;
1629 return IVInc->first ==
I;
1633bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
1637 auto IsReplacableIVIncrement = [
this, &
Cmp](BinaryOperator *BO) {
1641 assert(L &&
"L should not be null after isIVIncrement()");
1643 if (LI->getLoopFor(
Cmp->getParent()) != L)
1656 return BO->
hasOneUse() && DT.dominates(
Cmp->getParent(),
L->getLoopLatch());
1658 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1681 if (BO->
getOpcode() == Instruction::Add &&
1682 IID == Intrinsic::usub_with_overflow) {
1689 for (Instruction &Iter : *
Cmp->getParent()) {
1692 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1697 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1700 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1701 if (BO->
getOpcode() != Instruction::Xor) {
1702 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1706 "Patterns with XOr should use the BO only in the compare");
1707 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1709 Cmp->eraseFromParent();
1719 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1727 B = ConstantInt::get(
B->getType(), 1);
1735 for (
User *U :
A->users()) {
1746bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp,
1747 ModifyDT &ModifiedDT) {
1748 bool EdgeCase =
false;
1750 BinaryOperator *
Add;
1755 A =
Add->getOperand(0);
1756 B =
Add->getOperand(1);
1762 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1768 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1771 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1772 Intrinsic::uadd_with_overflow))
1776 ModifiedDT = ModifyDT::ModifyInstDT;
1780bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
1781 ModifyDT &ModifiedDT) {
1788 ICmpInst::Predicate Pred =
Cmp->getPredicate();
1789 if (Pred == ICmpInst::ICMP_UGT) {
1791 Pred = ICmpInst::ICMP_ULT;
1795 B = ConstantInt::get(
B->getType(), 1);
1796 Pred = ICmpInst::ICMP_ULT;
1801 Pred = ICmpInst::ICMP_ULT;
1803 if (Pred != ICmpInst::ICMP_ULT)
1810 BinaryOperator *
Sub =
nullptr;
1811 for (User *U : CmpVariableOperand->
users()) {
1819 const APInt *CmpC, *AddC;
1831 Sub->hasNUsesOrMore(1)))
1837 if (
Sub->getParent() !=
Cmp->getParent() && !
Sub->hasOneUse())
1840 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1841 Cmp, Intrinsic::usub_with_overflow))
1845 ModifiedDT = ModifyDT::ModifyInstDT;
1852bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1865 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1871 Type *OpTy =
X->getType();
1879 if (Pred == ICmpInst::ICMP_EQ) {
1880 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1881 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1883 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1889 if (IsPowerOf2OrZeroTest ||
1900 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1909 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1912 Cmp->replaceAllUsesWith(NewCmp);
1932 bool UsedInPhiOrCurrentBlock =
any_of(Cmp->users(), [Cmp](
User *U) {
1933 return isa<PHINode>(U) ||
1934 cast<Instruction>(U)->getParent() == Cmp->getParent();
1939 if (UsedInPhiOrCurrentBlock && Cmp->getOperand(0)->getType()->isIntegerTy() &&
1940 Cmp->getOperand(0)->getType()->getScalarSizeInBits() >
1941 DL.getLargestLegalIntTypeSizeInBits())
1947 bool MadeChange =
false;
1950 Use &TheUse = UI.getUse();
1965 if (UserBB == DefBB)
1969 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1975 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1982 TheUse = InsertedCmp;
1988 if (Cmp->use_empty()) {
1989 Cmp->eraseFromParent();
2026 for (
User *U : Cmp->users()) {
2048 if (CmpBB != FalseBB)
2051 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
2065 for (
User *U : Cmp->users()) {
2067 BI->swapSuccessors();
2073 SI->swapProfMetadata();
2085 Value *Op0 = Cmp->getOperand(0);
2086 Value *Op1 = Cmp->getOperand(1);
2095 unsigned NumInspected = 0;
2098 if (++NumInspected > 128)
2106 if (GoodToSwap > 0) {
2107 Cmp->swapOperands();
2127 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
2130 auto [ClassVal, ClassTest] =
2136 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2140 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
2141 Cmp->replaceAllUsesWith(IsFPClass);
2149 Value *Incr, *RemAmt;
2154 Value *AddInst, *AddOffset;
2157 if (PN !=
nullptr) {
2159 AddOffset =
nullptr;
2177 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2181 if (!L->contains(Rem))
2185 if (!L->isLoopInvariant(RemAmt))
2189 if (AddOffset && !L->isLoopInvariant(AddOffset))
2210 AddInstOut = AddInst;
2211 AddOffsetOut = AddOffset;
2230 Value *AddOffset, *RemAmt, *AddInst;
2233 AddOffset, LoopIncrPN))
2258 assert(AddOffset &&
"We found an add but missing values");
2277 Builder.SetInsertPoint(LoopIncrPN);
2278 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2283 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2288 NewRem->
addIncoming(Start, L->getLoopPreheader());
2293 FreshBBs.
insert(L->getLoopLatch());
2304bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2310bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2314 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2317 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2320 if (unfoldPowerOf2Test(Cmp))
2341 SetOfInstrs &InsertedInsts) {
2344 assert(!InsertedInsts.count(AndI) &&
2345 "Attempting to optimize already optimized and instruction");
2346 (void)InsertedInsts;
2360 for (
auto *U : AndI->
users()) {
2368 if (!CmpC || !CmpC->
isZero())
2383 Use &TheUse = UI.getUse();
2401 TheUse = InsertedAnd;
2418 if (
User->getOpcode() != Instruction::And ||
2424 if ((Cimm & (Cimm + 1)).getBoolValue())
2438 bool MadeChange =
false;
2441 TruncE = TruncI->user_end();
2442 TruncUI != TruncE;) {
2444 Use &TruncTheUse = TruncUI.getUse();
2469 if (UserBB == TruncUserBB)
2473 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2475 if (!InsertedShift && !InsertedTrunc) {
2479 if (ShiftI->
getOpcode() == Instruction::AShr)
2481 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2484 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2492 TruncInsertPt.setHeadBit(
true);
2493 assert(TruncInsertPt != TruncUserBB->
end());
2497 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2498 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2502 TruncTheUse = InsertedTrunc;
2535 bool MadeChange =
false;
2538 Use &TheUse = UI.getUse();
2552 if (UserBB == DefBB) {
2580 if (!InsertedShift) {
2584 if (ShiftI->
getOpcode() == Instruction::AShr)
2586 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2589 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2597 TheUse = InsertedShift;
2645 unsigned SizeInBits = Ty->getScalarSizeInBits();
2646 if (Ty->isVectorTy())
2657 nullptr,
"cond.false");
2659 FreshBBs.
insert(CallBlock);
2666 SplitPt.setHeadBit(
true);
2668 nullptr,
"cond.end");
2670 FreshBBs.
insert(EndBlock);
2675 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2682 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2683 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2684 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2690 Builder.SetInsertPoint(EndBlock, EndBlock->
begin());
2691 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2701 ModifiedDT = ModifyDT::ModifyBBDT;
2705bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2709 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2717 for (
auto &Arg : CI->
args()) {
2722 if (!Arg->getType()->isPointerTy())
2724 APInt
Offset(
DL->getIndexSizeInBits(
2727 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2734 if (AllocaSize && AllocaSize->getKnownMinValue() >= MinSize + Offset2)
2752 MaybeAlign MIDestAlign =
MI->getDestAlign();
2753 if (!MIDestAlign || DestAlign > *MIDestAlign)
2754 MI->setDestAlignment(DestAlign);
2756 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2758 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2759 MTI->setSourceAlignment(SrcAlign);
2769 for (
auto &Arg : CI->
args()) {
2770 if (!Arg->getType()->isPointerTy())
2772 unsigned AS = Arg->getType()->getPointerAddressSpace();
2773 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2779 switch (
II->getIntrinsicID()) {
2782 case Intrinsic::assume:
2784 case Intrinsic::allow_runtime_check:
2785 case Intrinsic::allow_ubsan_check:
2786 case Intrinsic::experimental_widenable_condition: {
2790 if (
II->use_empty()) {
2791 II->eraseFromParent();
2795 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2800 case Intrinsic::objectsize:
2802 case Intrinsic::is_constant:
2804 case Intrinsic::aarch64_stlxr:
2805 case Intrinsic::aarch64_stxr: {
2814 InsertedInsts.insert(ExtVal);
2818 case Intrinsic::launder_invariant_group:
2819 case Intrinsic::strip_invariant_group: {
2820 Value *ArgVal =
II->getArgOperand(0);
2821 auto it = LargeOffsetGEPMap.
find(
II);
2822 if (it != LargeOffsetGEPMap.
end()) {
2826 auto GEPs = std::move(it->second);
2827 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2832 II->eraseFromParent();
2835 case Intrinsic::cttz:
2836 case Intrinsic::ctlz:
2840 case Intrinsic::fshl:
2841 case Intrinsic::fshr:
2842 return optimizeFunnelShift(
II);
2843 case Intrinsic::masked_gather:
2844 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2845 case Intrinsic::masked_scatter:
2846 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2847 case Intrinsic::masked_load:
2850 if (VT->getNumElements() == 1) {
2851 Value *PtrVal =
II->getArgOperand(0);
2853 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2858 case Intrinsic::masked_store:
2862 if (VT->getNumElements() == 1) {
2863 Value *PtrVal =
II->getArgOperand(1);
2865 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2870 case Intrinsic::umul_with_overflow:
2871 return optimizeMulWithOverflow(
II,
false, ModifiedDT);
2872 case Intrinsic::smul_with_overflow:
2873 return optimizeMulWithOverflow(
II,
true, ModifiedDT);
2876 SmallVector<Value *, 2> PtrOps;
2879 while (!PtrOps.
empty()) {
2882 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2896 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2898 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2908 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2909 if (!
F->getReturnType()->isPointerTy())
2912 GlobalVariable *UniformValue =
nullptr;
2913 for (
auto &BB : *
F) {
2918 else if (V != UniformValue)
2926 return UniformValue;
2929 if (
Callee->hasExactDefinition()) {
2930 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2931 bool MadeChange =
false;
2957 switch (
II->getIntrinsicID()) {
2958 case Intrinsic::memset:
2959 case Intrinsic::memcpy:
2960 case Intrinsic::memmove:
2967 if (Callee && TLInfo)
2969 case LibFunc_strcpy:
2970 case LibFunc_strncpy:
2971 case LibFunc_strcat:
2972 case LibFunc_strncat:
3013bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
3014 ModifyDT &ModifiedDT) {
3022 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
3024 PHINode *PN =
nullptr;
3025 ExtractValueInst *EVI =
nullptr;
3026 BitCastInst *BCI =
nullptr;
3046 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
3052 return II->getIntrinsicID() == Intrinsic::lifetime_end;
3058 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
3060 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
3082 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
3089 auto MayBePermittedAsTailCall = [&](
const auto *CI) {
3106 MayBePermittedAsTailCall(CI)) {
3127 MayBePermittedAsTailCall(CI)) {
3134 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
3136 if (!VisitedBBs.
insert(Pred).second)
3138 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
3140 if (CI && CI->
use_empty() && MayBePermittedAsTailCall(CI)) {
3155 for (
auto const &TailCallBB : TailCallBBs) {
3165 BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB));
3166 BFI->setBlockFreq(BB,
3167 (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB)));
3168 ModifiedDT = ModifyDT::ModifyBBDT;
3177 for (
auto *CI : CallInsts) {
3178 for (
auto const *FakeUse : FakeUses) {
3179 auto *ClonedInst = FakeUse->clone();
3197struct ExtAddrMode :
public TargetLowering::AddrMode {
3198 Value *BaseReg =
nullptr;
3199 Value *ScaledReg =
nullptr;
3200 Value *OriginalValue =
nullptr;
3201 bool InBounds =
true;
3205 BaseRegField = 0x01,
3207 BaseOffsField = 0x04,
3208 ScaledRegField = 0x08,
3210 MultipleFields = 0xff
3213 ExtAddrMode() =
default;
3215 void print(raw_ostream &OS)
const;
3222 if (ScaledReg == From)
3226 FieldName
compare(
const ExtAddrMode &other) {
3229 if (BaseReg && other.
BaseReg &&
3231 return MultipleFields;
3232 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3233 return MultipleFields;
3236 return MultipleFields;
3239 if (InBounds != other.InBounds)
3240 return MultipleFields;
3243 unsigned Result = NoField;
3246 if (BaseGV != other.BaseGV)
3248 if (BaseOffs != other.BaseOffs)
3251 Result |= ScaledRegField;
3254 if (Scale && other.
Scale && Scale != other.
Scale)
3258 return MultipleFields;
3260 return static_cast<FieldName
>(
Result);
3270 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3281 case ScaledRegField:
3288 void SetCombinedField(FieldName
Field,
Value *V,
3289 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3294 case ExtAddrMode::BaseRegField:
3297 case ExtAddrMode::BaseGVField:
3300 assert(BaseReg ==
nullptr);
3304 case ExtAddrMode::ScaledRegField:
3309 for (
const ExtAddrMode &AM : AddrModes)
3315 case ExtAddrMode::BaseOffsField:
3318 assert(ScaledReg ==
nullptr);
3328static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3334#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3335void ExtAddrMode::print(raw_ostream &OS)
const {
3336 bool NeedPlus =
false;
3342 BaseGV->printAsOperand(OS,
false);
3347 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3352 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3353 BaseReg->printAsOperand(OS,
false);
3357 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3380class TypePromotionTransaction {
3384 class TypePromotionAction {
3392 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3394 virtual ~TypePromotionAction() =
default;
3401 virtual void undo() = 0;
3406 virtual void commit() {
3412 class InsertionHandler {
3421 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3424 bool HasPrevInstruction;
3428 InsertionHandler(Instruction *Inst) {
3436 if (HasPrevInstruction) {
3444 void insert(Instruction *Inst) {
3445 if (HasPrevInstruction) {
3457 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3462 class InstructionMoveBefore :
public TypePromotionAction {
3464 InsertionHandler Position;
3469 : TypePromotionAction(Inst), Position(Inst) {
3470 LLVM_DEBUG(
dbgs() <<
"Do: move: " << *Inst <<
"\nbefore: " << *Before
3476 void undo()
override {
3478 Position.insert(Inst);
3483 class OperandSetter :
public TypePromotionAction {
3492 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3493 : TypePromotionAction(Inst), Idx(Idx) {
3495 <<
"for:" << *Inst <<
"\n"
3496 <<
"with:" << *NewVal <<
"\n");
3502 void undo()
override {
3504 <<
"for: " << *Inst <<
"\n"
3505 <<
"with: " << *Origin <<
"\n");
3512 class OperandsHider :
public TypePromotionAction {
3514 SmallVector<Value *, 4> OriginalValues;
3518 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3521 OriginalValues.
reserve(NumOpnds);
3522 for (
unsigned It = 0; It < NumOpnds; ++It) {
3534 void undo()
override {
3536 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3542 class TruncBuilder :
public TypePromotionAction {
3549 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3551 Builder.SetCurrentDebugLocation(
DebugLoc());
3552 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3557 Value *getBuiltValue() {
return Val; }
3560 void undo()
override {
3563 IVal->eraseFromParent();
3568 class SExtBuilder :
public TypePromotionAction {
3575 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3576 : TypePromotionAction(InsertPt) {
3578 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3583 Value *getBuiltValue() {
return Val; }
3586 void undo()
override {
3589 IVal->eraseFromParent();
3594 class ZExtBuilder :
public TypePromotionAction {
3601 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3602 : TypePromotionAction(InsertPt) {
3604 Builder.SetCurrentDebugLocation(
DebugLoc());
3605 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3610 Value *getBuiltValue() {
return Val; }
3613 void undo()
override {
3616 IVal->eraseFromParent();
3621 class TypeMutator :
public TypePromotionAction {
3627 TypeMutator(Instruction *Inst,
Type *NewTy)
3628 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3629 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3635 void undo()
override {
3636 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3643 class UsesReplacer :
public TypePromotionAction {
3645 struct InstructionAndIdx {
3652 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3653 : Inst(Inst), Idx(Idx) {}
3659 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3669 UsesReplacer(Instruction *Inst,
Value *New)
3670 : TypePromotionAction(Inst),
New(
New) {
3671 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3674 for (Use &U : Inst->
uses()) {
3676 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3687 void undo()
override {
3689 for (InstructionAndIdx &Use : OriginalUses)
3690 Use.Inst->setOperand(
Use.Idx, Inst);
3695 for (DbgVariableRecord *DVR : DbgVariableRecords)
3696 DVR->replaceVariableLocationOp(New, Inst);
3701 class InstructionRemover :
public TypePromotionAction {
3703 InsertionHandler Inserter;
3707 OperandsHider Hider;
3710 UsesReplacer *Replacer =
nullptr;
3713 SetOfInstrs &RemovedInsts;
3720 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3721 Value *New =
nullptr)
3722 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3723 RemovedInsts(RemovedInsts) {
3725 Replacer =
new UsesReplacer(Inst, New);
3726 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3727 RemovedInsts.insert(Inst);
3734 ~InstructionRemover()
override {
delete Replacer; }
3736 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3737 InstructionRemover(
const InstructionRemover &other) =
delete;
3741 void undo()
override {
3742 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3743 Inserter.insert(Inst);
3747 RemovedInsts.erase(Inst);
3755 using ConstRestorationPt =
const TypePromotionAction *;
3757 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3758 : RemovedInsts(RemovedInsts) {}
3765 void rollback(ConstRestorationPt Point);
3768 ConstRestorationPt getRestorationPoint()
const;
3773 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3782 void mutateType(Instruction *Inst,
Type *NewTy);
3785 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3798 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3800 SetOfInstrs &RemovedInsts;
3805void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3807 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3808 Inst, Idx, NewVal));
3811void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3814 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3815 Inst, RemovedInsts, NewVal));
3818void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3821 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3824void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3826 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3829Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3830 std::unique_ptr<TruncBuilder> Ptr(
new TruncBuilder(Opnd, Ty));
3831 Value *Val = Ptr->getBuiltValue();
3832 Actions.push_back(std::move(Ptr));
3836Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3838 std::unique_ptr<SExtBuilder> Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3839 Value *Val = Ptr->getBuiltValue();
3840 Actions.push_back(std::move(Ptr));
3844Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3846 std::unique_ptr<ZExtBuilder> Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3847 Value *Val = Ptr->getBuiltValue();
3848 Actions.push_back(std::move(Ptr));
3852TypePromotionTransaction::ConstRestorationPt
3853TypePromotionTransaction::getRestorationPoint()
const {
3854 return !Actions.empty() ? Actions.back().get() :
nullptr;
3857bool TypePromotionTransaction::commit() {
3858 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3865void TypePromotionTransaction::rollback(
3866 TypePromotionTransaction::ConstRestorationPt Point) {
3867 while (!Actions.empty() && Point != Actions.back().get()) {
3868 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3878class AddressingModeMatcher {
3879 SmallVectorImpl<Instruction *> &AddrModeInsts;
3880 const TargetLowering &TLI;
3881 const TargetRegisterInfo &
TRI;
3882 const DataLayout &
DL;
3884 const std::function<
const DominatorTree &()> getDTFn;
3897 const SetOfInstrs &InsertedInsts;
3900 InstrToOrigTy &PromotedInsts;
3903 TypePromotionTransaction &TPT;
3906 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3910 bool IgnoreProfitability;
3913 bool OptSize =
false;
3915 ProfileSummaryInfo *PSI;
3916 BlockFrequencyInfo *BFI;
3918 AddressingModeMatcher(
3919 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3920 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3921 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3922 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3923 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3924 TypePromotionTransaction &TPT,
3925 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3926 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI)
3927 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3928 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3929 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3930 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3931 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI), BFI(BFI) {
3932 IgnoreProfitability =
false;
3944 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3945 SmallVectorImpl<Instruction *> &AddrModeInsts,
3946 const TargetLowering &TLI,
const LoopInfo &LI,
3947 const std::function<
const DominatorTree &()> getDTFn,
3948 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3949 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3950 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3951 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
3954 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3955 AccessTy, AS, MemoryInst, Result,
3956 InsertedInsts, PromotedInsts, TPT,
3957 LargeOffsetGEP, OptSize, PSI, BFI)
3965 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3967 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3968 bool *MovedAway =
nullptr);
3969 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3970 ExtAddrMode &AMBefore,
3971 ExtAddrMode &AMAfter);
3972 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3973 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3974 Value *PromotedOperand)
const;
3980class PhiNodeSetIterator {
3981 PhiNodeSet *
const Set;
3982 size_t CurrentIndex = 0;
3987 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3989 PhiNodeSetIterator &operator++();
4005 friend class PhiNodeSetIterator;
4007 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
4008 using iterator = PhiNodeSetIterator;
4023 size_t FirstValidElement = 0;
4029 bool insert(PHINode *Ptr) {
4030 if (NodeMap.insert(std::make_pair(Ptr,
NodeList.
size())).second) {
4040 bool erase(PHINode *Ptr) {
4041 if (NodeMap.erase(Ptr)) {
4042 SkipRemovedElements(FirstValidElement);
4052 FirstValidElement = 0;
4058 if (FirstValidElement == 0)
4059 SkipRemovedElements(FirstValidElement);
4060 return PhiNodeSetIterator(
this, FirstValidElement);
4067 size_t size()
const {
return NodeMap.size(); }
4070 size_t count(PHINode *Ptr)
const {
return NodeMap.count(Ptr); }
4078 void SkipRemovedElements(
size_t &CurrentIndex) {
4080 auto it = NodeMap.find(NodeList[CurrentIndex]);
4083 if (it != NodeMap.end() && it->second == CurrentIndex)
4090PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
4093PHINode *PhiNodeSetIterator::operator*()
const {
4095 "PhiNodeSet access out of range");
4096 return Set->NodeList[CurrentIndex];
4099PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
4101 "PhiNodeSet access out of range");
4103 Set->SkipRemovedElements(CurrentIndex);
4107bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
4108 return CurrentIndex ==
RHS.CurrentIndex;
4111bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
4112 return !((*this) ==
RHS);
4118class SimplificationTracker {
4119 DenseMap<Value *, Value *> Storage;
4122 PhiNodeSet AllPhiNodes;
4124 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
4129 auto SV = Storage.
find(V);
4130 if (SV == Storage.
end())
4138 void ReplacePhi(PHINode *From, PHINode *To) {
4139 Value *OldReplacement = Get(From);
4140 while (OldReplacement != From) {
4143 OldReplacement = Get(From);
4145 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
4148 AllPhiNodes.erase(From);
4152 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
4154 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
4156 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
4158 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4160 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4162 void destroyNewNodes(
Type *CommonType) {
4165 for (
auto *
I : AllPhiNodes) {
4166 I->replaceAllUsesWith(Dummy);
4167 I->eraseFromParent();
4169 AllPhiNodes.clear();
4170 for (
auto *
I : AllSelectNodes) {
4171 I->replaceAllUsesWith(Dummy);
4172 I->eraseFromParent();
4174 AllSelectNodes.clear();
4179class AddressingModeCombiner {
4180 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4181 typedef std::pair<PHINode *, PHINode *> PHIPair;
4188 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4191 bool AllAddrModesTrivial =
true;
4194 Type *CommonType =
nullptr;
4196 const DataLayout &
DL;
4202 Value *CommonValue =
nullptr;
4205 AddressingModeCombiner(
const DataLayout &
DL,
Value *OriginalValue)
4206 :
DL(
DL), Original(OriginalValue) {}
4208 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4211 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4216 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4220 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4223 if (AddrModes.
empty()) {
4231 ExtAddrMode::FieldName ThisDifferentField =
4232 AddrModes[0].compare(NewAddrMode);
4233 if (DifferentField == ExtAddrMode::NoField)
4234 DifferentField = ThisDifferentField;
4235 else if (DifferentField != ThisDifferentField)
4236 DifferentField = ExtAddrMode::MultipleFields;
4239 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4242 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4247 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4252 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4253 !NewAddrMode.HasBaseReg);
4270 bool combineAddrModes() {
4272 if (AddrModes.
size() == 0)
4276 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4281 if (AllAddrModesTrivial)
4284 if (!addrModeCombiningAllowed())
4290 FoldAddrToValueMapping
Map;
4291 if (!initializeMap(Map))
4294 CommonValue = findCommon(Map);
4296 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4297 return CommonValue !=
nullptr;
4303 void eraseCommonValueIfDead() {
4304 if (CommonValue && CommonValue->
use_empty())
4306 CommonInst->eraseFromParent();
4314 bool initializeMap(FoldAddrToValueMapping &Map) {
4317 SmallVector<Value *, 2> NullValue;
4319 for (
auto &AM : AddrModes) {
4323 if (CommonType && CommonType !=
Type)
4326 Map[AM.OriginalValue] = DV;
4331 assert(CommonType &&
"At least one non-null value must be!");
4332 for (
auto *V : NullValue)
4360 Value *findCommon(FoldAddrToValueMapping &Map) {
4368 SimplificationTracker
ST;
4373 InsertPlaceholders(Map, TraverseOrder, ST);
4376 FillPlaceholders(Map, TraverseOrder, ST);
4379 ST.destroyNewNodes(CommonType);
4384 unsigned PhiNotMatchedCount = 0;
4386 ST.destroyNewNodes(CommonType);
4390 auto *
Result =
ST.Get(
Map.find(Original)->second);
4392 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4393 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4400 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4401 SmallSetVector<PHIPair, 8> &Matcher,
4402 PhiNodeSet &PhiNodesToMatch) {
4405 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4408 SmallSet<PHIPair, 8> Visited;
4409 while (!WorkList.
empty()) {
4411 if (!Visited.
insert(Item).second)
4418 for (
auto *
B : Item.first->blocks()) {
4419 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4420 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4421 if (FirstValue == SecondValue)
4431 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4436 if (Matcher.
count({FirstPhi, SecondPhi}))
4441 if (MatchedPHIs.
insert(FirstPhi).second)
4442 Matcher.
insert({FirstPhi, SecondPhi});
4444 WorkList.
push_back({FirstPhi, SecondPhi});
4453 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4454 unsigned &PhiNotMatchedCount) {
4458 SmallSetVector<PHIPair, 8> Matched;
4459 SmallPtrSet<PHINode *, 8> WillNotMatch;
4460 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4461 while (PhiNodesToMatch.size()) {
4462 PHINode *
PHI = *PhiNodesToMatch.begin();
4465 WillNotMatch.
clear();
4469 bool IsMatched =
false;
4470 for (
auto &
P :
PHI->getParent()->phis()) {
4472 if (PhiNodesToMatch.count(&
P))
4474 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4484 for (
auto MV : Matched)
4485 ST.ReplacePhi(MV.first, MV.second);
4490 if (!AllowNewPhiNodes)
4493 PhiNotMatchedCount += WillNotMatch.
size();
4494 for (
auto *
P : WillNotMatch)
4495 PhiNodesToMatch.erase(
P);
4500 void FillPlaceholders(FoldAddrToValueMapping &Map,
4501 SmallVectorImpl<Value *> &TraverseOrder,
4502 SimplificationTracker &ST) {
4503 while (!TraverseOrder.
empty()) {
4505 assert(
Map.contains(Current) &&
"No node to fill!!!");
4511 auto *TrueValue = CurrentSelect->getTrueValue();
4512 assert(
Map.contains(TrueValue) &&
"No True Value!");
4513 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4514 auto *FalseValue = CurrentSelect->getFalseValue();
4515 assert(
Map.contains(FalseValue) &&
"No False Value!");
4516 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4523 assert(
Map.contains(PV) &&
"No predecessor Value!");
4524 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4535 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4536 SmallVectorImpl<Value *> &TraverseOrder,
4537 SimplificationTracker &ST) {
4540 "Address must be a Phi or Select node");
4543 while (!Worklist.
empty()) {
4546 if (
Map.contains(Current))
4557 CurrentSelect->getName(),
4558 CurrentSelect->getIterator(), CurrentSelect);
4562 Worklist.
push_back(CurrentSelect->getTrueValue());
4563 Worklist.
push_back(CurrentSelect->getFalseValue());
4571 ST.insertNewPhi(
PHI);
4577 bool addrModeCombiningAllowed() {
4580 switch (DifferentField) {
4583 case ExtAddrMode::BaseRegField:
4585 case ExtAddrMode::BaseGVField:
4587 case ExtAddrMode::BaseOffsField:
4589 case ExtAddrMode::ScaledRegField:
4599bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4604 return matchAddr(ScaleReg,
Depth);
4615 ExtAddrMode TestAddrMode =
AddrMode;
4619 TestAddrMode.
Scale += Scale;
4633 ConstantInt *CI =
nullptr;
4634 Value *AddLHS =
nullptr;
4638 TestAddrMode.InBounds =
false;
4655 auto GetConstantStep =
4656 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4659 return std::nullopt;
4662 return std::nullopt;
4670 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4671 return std::nullopt;
4673 return std::make_pair(IVInc->first, ConstantStep->getValue());
4674 return std::nullopt;
4689 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4696 APInt Step = IVStep->second;
4698 if (
Offset.isSignedIntN(64)) {
4699 TestAddrMode.InBounds =
false;
4701 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4706 getDTFn().
dominates(IVInc, MemoryInst)) {
4726 switch (
I->getOpcode()) {
4727 case Instruction::BitCast:
4728 case Instruction::AddrSpaceCast:
4730 if (
I->getType() ==
I->getOperand(0)->getType())
4732 return I->getType()->isIntOrPtrTy();
4733 case Instruction::PtrToInt:
4736 case Instruction::IntToPtr:
4739 case Instruction::Add:
4741 case Instruction::Mul:
4742 case Instruction::Shl:
4745 case Instruction::GetElementPtr:
4773class TypePromotionHelper {
4776 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4777 Instruction *ExtOpnd,
bool IsSExt) {
4778 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4779 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4783 if (It->second.getInt() == ExtTy)
4789 ExtTy = BothExtension;
4791 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4798 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4799 Instruction *Opnd,
bool IsSExt) {
4800 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4801 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4802 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4803 return It->second.getPointer();
4818 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4819 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4823 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4836 static Value *promoteOperandForTruncAndAnyExt(
4837 Instruction *Ext, TypePromotionTransaction &TPT,
4838 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4839 SmallVectorImpl<Instruction *> *Exts,
4840 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4851 static Value *promoteOperandForOther(Instruction *Ext,
4852 TypePromotionTransaction &TPT,
4853 InstrToOrigTy &PromotedInsts,
4854 unsigned &CreatedInstsCost,
4855 SmallVectorImpl<Instruction *> *Exts,
4856 SmallVectorImpl<Instruction *> *Truncs,
4857 const TargetLowering &TLI,
bool IsSExt);
4860 static Value *signExtendOperandForOther(
4861 Instruction *Ext, TypePromotionTransaction &TPT,
4862 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4863 SmallVectorImpl<Instruction *> *Exts,
4864 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4865 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4866 Exts, Truncs, TLI,
true);
4870 static Value *zeroExtendOperandForOther(
4871 Instruction *Ext, TypePromotionTransaction &TPT,
4872 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4873 SmallVectorImpl<Instruction *> *Exts,
4874 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4875 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4876 Exts, Truncs, TLI,
false);
4881 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4882 InstrToOrigTy &PromotedInsts,
4883 unsigned &CreatedInstsCost,
4884 SmallVectorImpl<Instruction *> *Exts,
4885 SmallVectorImpl<Instruction *> *Truncs,
4886 const TargetLowering &TLI);
4897 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4898 const TargetLowering &TLI,
4899 const InstrToOrigTy &PromotedInsts);
4904bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4905 Type *ConsideredExtType,
4906 const InstrToOrigTy &PromotedInsts,
4926 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4927 (IsSExt && BinOp->hasNoSignedWrap())))
4931 if ((Inst->
getOpcode() == Instruction::And ||
4936 if (Inst->
getOpcode() == Instruction::Xor) {
4939 if (!Cst->getValue().isAllOnes())
4948 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4958 if (ExtInst->hasOneUse()) {
4960 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4993 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
5006TypePromotionHelper::Action TypePromotionHelper::getAction(
5007 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
5008 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
5010 "Unexpected instruction type");
5017 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
5030 return promoteOperandForTruncAndAnyExt;
5036 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
5039Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
5040 Instruction *SExt, TypePromotionTransaction &TPT,
5041 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5042 SmallVectorImpl<Instruction *> *Exts,
5043 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
5047 Value *ExtVal = SExt;
5048 bool HasMergedNonFreeExt =
false;
5052 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
5055 TPT.replaceAllUsesWith(SExt, ZExt);
5056 TPT.eraseInstruction(SExt);
5061 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
5063 CreatedInstsCost = 0;
5067 TPT.eraseInstruction(SExtOpnd);
5075 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
5083 TPT.eraseInstruction(ExtInst, NextVal);
5087Value *TypePromotionHelper::promoteOperandForOther(
5088 Instruction *Ext, TypePromotionTransaction &TPT,
5089 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5090 SmallVectorImpl<Instruction *> *Exts,
5091 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
5096 CreatedInstsCost = 0;
5102 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
5105 ITrunc->moveAfter(ExtOpnd);
5110 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
5113 TPT.setOperand(Ext, 0, ExtOpnd);
5123 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
5125 TPT.mutateType(ExtOpnd, Ext->
getType());
5127 TPT.replaceAllUsesWith(Ext, ExtOpnd);
5130 for (
int OpIdx = 0, EndOpIdx = ExtOpnd->
getNumOperands(); OpIdx != EndOpIdx;
5134 !shouldExtOperand(ExtOpnd, OpIdx)) {
5143 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
5145 TPT.setOperand(ExtOpnd, OpIdx, ConstantInt::get(Ext->
getType(), CstVal));
5156 Value *ValForExtOpnd = IsSExt
5157 ? TPT.createSExt(ExtOpnd, Opnd, Ext->
getType())
5158 : TPT.createZExt(ExtOpnd, Opnd, Ext->
getType());
5159 TPT.setOperand(ExtOpnd, OpIdx, ValForExtOpnd);
5161 if (!InstForExtOpnd)
5167 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5170 TPT.eraseInstruction(Ext);
5182bool AddressingModeMatcher::isPromotionProfitable(
5183 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5184 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5189 if (NewCost > OldCost)
5191 if (NewCost < OldCost)
5210bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5222 case Instruction::PtrToInt:
5225 case Instruction::IntToPtr: {
5233 case Instruction::BitCast:
5243 case Instruction::AddrSpaceCast: {
5251 case Instruction::Add: {
5254 ExtAddrMode BackupAddrMode =
AddrMode;
5255 unsigned OldSize = AddrModeInsts.
size();
5260 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5261 TPT.getRestorationPoint();
5265 int First = 0, Second = 1;
5276 AddrModeInsts.
resize(OldSize);
5277 TPT.rollback(LastKnownGood);
5287 AddrModeInsts.
resize(OldSize);
5288 TPT.rollback(LastKnownGood);
5294 case Instruction::Mul:
5295 case Instruction::Shl: {
5299 if (!
RHS ||
RHS->getBitWidth() > 64)
5301 int64_t Scale = Opcode == Instruction::Shl
5302 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5303 :
RHS->getSExtValue();
5307 case Instruction::GetElementPtr: {
5310 int VariableOperand = -1;
5311 unsigned VariableScale = 0;
5313 int64_t ConstantOffset = 0;
5315 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5317 const StructLayout *SL =
DL.getStructLayout(STy);
5328 if (ConstantInt *CI =
5330 const APInt &CVal = CI->
getValue();
5337 if (VariableOperand != -1)
5341 VariableOperand = i;
5342 VariableScale = TypeSize;
5349 if (VariableOperand == -1) {
5350 AddrMode.BaseOffs += ConstantOffset;
5356 AddrMode.BaseOffs -= ConstantOffset;
5360 ConstantOffset > 0) {
5373 BasicBlock *Parent = BaseI ? BaseI->getParent()
5374 : &
GEP->getFunction()->getEntryBlock();
5376 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5384 ExtAddrMode BackupAddrMode =
AddrMode;
5385 unsigned OldSize = AddrModeInsts.
size();
5388 AddrMode.BaseOffs += ConstantOffset;
5397 AddrModeInsts.
resize(OldSize);
5405 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5410 AddrModeInsts.
resize(OldSize);
5415 AddrMode.BaseOffs += ConstantOffset;
5416 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5417 VariableScale,
Depth)) {
5420 AddrModeInsts.
resize(OldSize);
5427 case Instruction::SExt:
5428 case Instruction::ZExt: {
5435 TypePromotionHelper::Action TPH =
5436 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5440 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5441 TPT.getRestorationPoint();
5442 unsigned CreatedInstsCost = 0;
5444 Value *PromotedOperand =
5445 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5460 assert(PromotedOperand &&
5461 "TypePromotionHelper should have filtered out those cases");
5463 ExtAddrMode BackupAddrMode =
AddrMode;
5464 unsigned OldSize = AddrModeInsts.
size();
5466 if (!matchAddr(PromotedOperand,
Depth) ||
5471 !isPromotionProfitable(CreatedInstsCost,
5472 ExtCost + (AddrModeInsts.
size() - OldSize),
5475 AddrModeInsts.
resize(OldSize);
5476 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5477 TPT.rollback(LastKnownGood);
5482 AddrMode.replaceWith(Ext, PromotedOperand);
5485 case Instruction::Call:
5487 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5503bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5506 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5507 TPT.getRestorationPoint();
5531 ExtAddrMode BackupAddrMode =
AddrMode;
5532 unsigned OldSize = AddrModeInsts.
size();
5535 bool MovedAway =
false;
5536 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5544 if (
I->hasOneUse() ||
5545 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5552 AddrModeInsts.
resize(OldSize);
5553 TPT.rollback(LastKnownGood);
5556 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5558 TPT.rollback(LastKnownGood);
5585 TPT.rollback(LastKnownGood);
5604 if (OpInfo.CallOperandVal == OpVal &&
5606 !OpInfo.isIndirect))
5622 if (!ConsideredInsts.
insert(
I).second)
5630 for (
Use &U :
I->uses()) {
5638 MemoryUses.push_back({&U, LI->getType()});
5645 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5652 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5659 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5669 if (!
find(PtrOps, U.get()))
5672 MemoryUses.push_back({&U, AccessTy});
5677 if (CI->hasFnAttr(Attribute::Cold)) {
5695 PSI, BFI, SeenInsts))
5706 unsigned SeenInsts = 0;
5709 PSI, BFI, SeenInsts);
5717bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5719 Value *KnownLive2) {
5721 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5762bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5763 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5764 if (IgnoreProfitability)
5782 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5783 ScaledReg =
nullptr;
5787 if (!BaseReg && !ScaledReg)
5808 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5811 Type *AddressAccessTy = Pair.second;
5812 unsigned AS =
Address->getType()->getPointerAddressSpace();
5818 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5820 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5821 TPT.getRestorationPoint();
5822 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5823 AddressAccessTy, AS, UserI, Result,
5824 InsertedInsts, PromotedInsts, TPT,
5825 LargeOffsetGEP, OptSize, PSI, BFI);
5826 Matcher.IgnoreProfitability =
true;
5834 TPT.rollback(LastKnownGood);
5840 MatchedAddrModeInsts.
clear();
5850 return I->getParent() != BB;
5866 return std::next(AddrInst->getIterator());
5877 Earliest = UserInst;
5902bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5903 Type *AccessTy,
unsigned AddrSpace) {
5908 SmallVector<Value *, 8> worklist;
5909 SmallPtrSet<Value *, 16> Visited;
5915 bool PhiOrSelectSeen =
false;
5916 SmallVector<Instruction *, 16> AddrModeInsts;
5917 AddressingModeCombiner AddrModes(*
DL, Addr);
5918 TypePromotionTransaction TPT(RemovedInsts);
5919 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5920 TPT.getRestorationPoint();
5921 while (!worklist.
empty()) {
5933 if (!Visited.
insert(V).second)
5939 PhiOrSelectSeen =
true;
5946 PhiOrSelectSeen =
true;
5953 AddrModeInsts.
clear();
5954 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5959 auto getDTFn = [
this]() ->
const DominatorTree & {
return getDT(); };
5960 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5961 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5962 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5965 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5970 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5971 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5974 NewAddrMode.OriginalValue =
V;
5975 if (!AddrModes.addNewAddrMode(NewAddrMode))
5982 if (!AddrModes.combineAddrModes()) {
5983 TPT.rollback(LastKnownGood);
5989 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5995 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
6009 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
6031 <<
" for " << *MemoryInst <<
"\n");
6035 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6041 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
6043 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6045 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6052 <<
" for " << *MemoryInst <<
"\n");
6053 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
6064 if (ResultPtr ||
AddrMode.Scale != 1)
6085 GlobalValue *BaseGV =
AddrMode.BaseGV;
6086 if (BaseGV !=
nullptr) {
6091 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
6100 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
6101 if (!ResultPtr &&
AddrMode.BaseReg) {
6105 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
6106 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
6115 }
else if (!ResultPtr) {
6129 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
6142 "We can't transform if ScaledReg is too narrow");
6143 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
6147 V = Builder.CreateMul(
6150 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6161 if (ResultPtr->
getType() != I8PtrTy)
6162 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6163 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6176 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6178 SunkAddr = ResultPtr;
6180 if (ResultPtr->
getType() != I8PtrTy)
6181 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6182 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6189 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6195 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
6197 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6199 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6209 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6210 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6211 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6213 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6217 <<
" for " << *MemoryInst <<
"\n");
6228 if (
V->getType()->isPointerTy())
6229 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6231 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
6240 }
else if (
V->getType()->isPointerTy()) {
6241 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6244 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
6253 I->eraseFromParent();
6257 V = Builder.CreateMul(
6260 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6266 GlobalValue *BaseGV =
AddrMode.BaseGV;
6267 if (BaseGV !=
nullptr) {
6270 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6274 Value *
V = Builder.CreatePtrToInt(BaseGVPtr,
IntPtrTy,
"sunkaddr");
6276 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6285 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6293 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6299 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6304 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6305 RecursivelyDeleteTriviallyDeadInstructions(
6306 Repl, TLInfo, nullptr,
6307 [&](Value *V) { removeAllAssertingVHReferences(V); });
6331bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6337 if (!
GEP->hasIndices())
6345 SmallVector<Value *, 2>
Ops(
GEP->operands());
6347 bool RewriteGEP =
false;
6356 unsigned FinalIndex =
Ops.size() - 1;
6361 for (
unsigned i = 1; i < FinalIndex; ++i) {
6366 C =
C->getSplatValue();
6368 if (!CI || !CI->
isZero())
6375 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6379 if (!
C || !
C->isZero()) {
6380 Ops[FinalIndex] =
V;
6388 if (!RewriteGEP &&
Ops.size() == 2)
6395 Type *SourceTy =
GEP->getSourceElementType();
6396 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6400 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6401 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6402 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6412 if (
Ops.size() != 2) {
6422 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6436 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6437 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6440 Intrinsic::masked_gather) {
6444 Intrinsic::masked_scatter);
6459 Ptr, TLInfo,
nullptr,
6460 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6471 if (
I->hasNUsesOrMore(3))
6474 for (
User *U :
I->users()) {
6476 if (!Extract || Extract->getNumIndices() != 1)
6479 unsigned Index = Extract->getIndices()[0];
6481 MulExtract = Extract;
6482 else if (Index == 1)
6483 OverflowExtract = Extract;
6510bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
6511 ModifyDT &ModifiedDT) {
6518 ExtractValueInst *MulExtract =
nullptr, *OverflowExtract =
nullptr;
6523 InsertedInsts.insert(
I);
6534 OverflowEntryBB->
takeName(
I->getParent());
6540 NoOverflowBB->
moveAfter(OverflowEntryBB);
6548 Value *LoLHS = Builder.CreateTrunc(
LHS, LegalTy,
"lo.lhs");
6549 Value *HiLHS = Builder.CreateLShr(
LHS, VTHalfBitWidth,
"lhs.lsr");
6550 HiLHS = Builder.CreateTrunc(HiLHS, LegalTy,
"hi.lhs");
6553 Value *LoRHS = Builder.CreateTrunc(
RHS, LegalTy,
"lo.rhs");
6554 Value *HiRHS = Builder.CreateLShr(
RHS, VTHalfBitWidth,
"rhs.lsr");
6555 HiRHS = Builder.CreateTrunc(HiRHS, LegalTy,
"hi.rhs");
6557 Value *IsAnyBitTrue;
6560 Builder.CreateAShr(LoLHS, VTHalfBitWidth - 1,
"sign.lo.lhs");
6562 Builder.CreateAShr(LoRHS, VTHalfBitWidth - 1,
"sign.lo.rhs");
6563 Value *XorLHS = Builder.CreateXor(HiLHS, SignLoLHS);
6564 Value *XorRHS = Builder.CreateXor(HiRHS, SignLoRHS);
6565 Value *
Or = Builder.CreateOr(XorLHS, XorRHS,
"or.lhs.rhs");
6566 IsAnyBitTrue = Builder.CreateCmp(ICmpInst::ICMP_NE,
Or,
6567 ConstantInt::getNullValue(
Or->getType()));
6569 Value *CmpLHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiLHS,
6570 ConstantInt::getNullValue(LegalTy));
6571 Value *CmpRHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiRHS,
6572 ConstantInt::getNullValue(LegalTy));
6573 IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS,
"or.lhs.rhs");
6575 Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
6578 Builder.SetInsertPoint(NoOverflowBB);
6579 Value *ExtLoLHS, *ExtLoRHS;
6581 ExtLoLHS = Builder.CreateSExt(LoLHS, Ty,
"lo.lhs.ext");
6582 ExtLoRHS = Builder.CreateSExt(LoRHS, Ty,
"lo.rhs.ext");
6584 ExtLoLHS = Builder.CreateZExt(LoLHS, Ty,
"lo.lhs.ext");
6585 ExtLoRHS = Builder.CreateZExt(LoRHS, Ty,
"lo.rhs.ext");
6588 Value *
Mul = Builder.CreateMul(ExtLoLHS, ExtLoRHS,
"mul.overflow.no");
6593 OverflowResBB->
setName(
"overflow.res");
6596 Builder.CreateBr(OverflowResBB);
6604 PHINode *OverflowResPHI = Builder.CreatePHI(Ty, 2),
6606 Builder.CreatePHI(IntegerType::getInt1Ty(
I->getContext()), 2);
6618 if (OverflowExtract) {
6619 OverflowExtract->replaceAllUsesWith(OverflowFlagPHI);
6620 OverflowExtract->eraseFromParent();
6625 I->removeFromParent();
6627 I->insertInto(OverflowBB, OverflowBB->
end());
6628 Builder.SetInsertPoint(OverflowBB, OverflowBB->
end());
6630 Value *OverflowFlag = Builder.CreateExtractValue(
I, {1},
"overflow.flag");
6631 Builder.CreateBr(OverflowResBB);
6635 OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
6637 DTU->
applyUpdates({{DominatorTree::Insert, OverflowEntryBB, OverflowBB},
6638 {DominatorTree::Insert, OverflowEntryBB, NoOverflowBB},
6639 {DominatorTree::Insert, NoOverflowBB, OverflowResBB},
6640 {DominatorTree::Delete, OverflowEntryBB, OverflowResBB},
6641 {DominatorTree::Insert, OverflowBB, OverflowResBB}});
6643 ModifiedDT = ModifyDT::ModifyBBDT;
6649bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6650 bool MadeChange =
false;
6652 const TargetRegisterInfo *
TRI =
6657 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6663 OpInfo.isIndirect) {
6665 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6728bool CodeGenPrepare::tryToPromoteExts(
6729 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6730 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6731 unsigned CreatedInstsCost) {
6732 bool Promoted =
false;
6735 for (
auto *
I : Exts) {
6750 TypePromotionHelper::Action TPH =
6751 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6760 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6761 TPT.getRestorationPoint();
6762 SmallVector<Instruction *, 4> NewExts;
6763 unsigned NewCreatedInstsCost = 0;
6766 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6767 &NewExts,
nullptr, *TLI);
6769 "TypePromotionHelper should have filtered out those cases");
6779 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6782 TotalCreatedInstsCost =
6783 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6785 (TotalCreatedInstsCost > 1 ||
6787 (ExtCost == 0 && NewExts.
size() > 1))) {
6791 TPT.rollback(LastKnownGood);
6796 SmallVector<Instruction *, 2> NewlyMovedExts;
6797 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6798 bool NewPromoted =
false;
6799 for (
auto *ExtInst : NewlyMovedExts) {
6809 ProfitablyMovedExts.
push_back(MovedExt);
6816 TPT.rollback(LastKnownGood);
6827bool CodeGenPrepare::mergeSExts(
Function &
F) {
6829 for (
auto &Entry : ValToSExtendedUses) {
6830 SExts &Insts =
Entry.second;
6832 for (Instruction *Inst : Insts) {
6836 bool inserted =
false;
6837 for (
auto &Pt : CurPts) {
6840 RemovedInsts.insert(Pt);
6841 Pt->removeFromParent();
6852 RemovedInsts.insert(Inst);
6859 CurPts.push_back(Inst);
6901bool CodeGenPrepare::splitLargeGEPOffsets() {
6903 for (
auto &Entry : LargeOffsetGEPMap) {
6905 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6906 &LargeOffsetGEPs =
Entry.second;
6907 auto compareGEPOffset =
6908 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6909 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6910 if (
LHS.first ==
RHS.first)
6912 if (
LHS.second !=
RHS.second)
6913 return LHS.second <
RHS.second;
6914 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6917 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6920 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6922 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6923 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6924 Value *NewBaseGEP =
nullptr;
6926 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6927 GetElementPtrInst *
GEP) {
6928 LLVMContext &Ctx =
GEP->getContext();
6929 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6931 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6943 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), &getDT(), LI);
6946 NewBaseInsertPt = std::next(BaseI->getIterator());
6953 IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
6959 NewBaseGEP = OldBase;
6960 if (NewBaseGEP->
getType() != I8PtrTy)
6961 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6963 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6964 NewGEPBases.
insert(NewBaseGEP);
6970 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6971 BaseOffset = PreferBase;
6974 createNewBase(BaseOffset, OldBase, BaseGEP);
6977 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6978 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6979 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6980 int64_t
Offset = LargeOffsetGEP->second;
6981 if (
Offset != BaseOffset) {
6988 GEP->getResultElementType(),
6989 GEP->getAddressSpace())) {
6995 NewBaseGEP =
nullptr;
7000 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
7005 createNewBase(BaseOffset, OldBase,
GEP);
7009 Value *NewGEP = NewBaseGEP;
7010 if (
Offset != BaseOffset) {
7013 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
7017 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
7018 GEP->eraseFromParent();
7025bool CodeGenPrepare::optimizePhiType(
7026 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
7027 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
7032 Type *PhiTy =
I->getType();
7033 Type *ConvertTy =
nullptr;
7035 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
7038 SmallVector<Instruction *, 4> Worklist;
7040 SmallPtrSet<PHINode *, 4> PhiNodes;
7041 SmallPtrSet<ConstantData *, 4>
Constants;
7044 SmallPtrSet<Instruction *, 4> Defs;
7045 SmallPtrSet<Instruction *, 4>
Uses;
7051 bool AnyAnchored =
false;
7053 while (!Worklist.
empty()) {
7058 for (
Value *V :
Phi->incoming_values()) {
7060 if (!PhiNodes.
count(OpPhi)) {
7061 if (!Visited.
insert(OpPhi).second)
7067 if (!OpLoad->isSimple())
7069 if (Defs.
insert(OpLoad).second)
7072 if (Defs.
insert(OpEx).second)
7076 ConvertTy = OpBC->getOperand(0)->getType();
7077 if (OpBC->getOperand(0)->getType() != ConvertTy)
7079 if (Defs.
insert(OpBC).second) {
7092 for (User *V :
II->users()) {
7094 if (!PhiNodes.
count(OpPhi)) {
7095 if (Visited.
count(OpPhi))
7102 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
7104 Uses.insert(OpStore);
7107 ConvertTy = OpBC->getType();
7108 if (OpBC->getType() != ConvertTy)
7112 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
7119 if (!ConvertTy || !AnyAnchored || PhiTy == ConvertTy ||
7123 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
7124 << *ConvertTy <<
"\n");
7129 for (ConstantData *
C : Constants)
7131 for (Instruction *
D : Defs) {
7133 ValMap[
D] =
D->getOperand(0);
7137 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
7140 for (PHINode *Phi : PhiNodes)
7142 Phi->getName() +
".tc",
Phi->getIterator());
7144 for (PHINode *Phi : PhiNodes) {
7146 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
7148 Phi->getIncomingBlock(i));
7152 for (Instruction *U :
Uses) {
7157 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
7167bool CodeGenPrepare::optimizePhiTypes(
Function &
F) {
7172 SmallPtrSet<PHINode *, 4> Visited;
7173 SmallPtrSet<Instruction *, 4> DeletedInstrs;
7177 for (
auto &Phi : BB.
phis())
7178 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
7181 for (
auto *
I : DeletedInstrs) {
7183 I->eraseFromParent();
7191bool CodeGenPrepare::canFormExtLd(
7192 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
7193 Instruction *&Inst,
bool HasPromoted) {
7194 for (
auto *MovedExtInst : MovedExts) {
7197 Inst = MovedExtInst;
7249bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7250 bool AllowPromotionWithoutCommonHeader =
false;
7255 *Inst, AllowPromotionWithoutCommonHeader);
7256 TypePromotionTransaction TPT(RemovedInsts);
7257 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7258 TPT.getRestorationPoint();
7260 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7263 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7266 LoadInst *LI =
nullptr;
7271 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7272 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7277 Inst = ExtFedByLoad;
7282 if (ATPConsiderable &&
7283 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7284 HasPromoted, TPT, SpeculativelyMovedExts))
7287 TPT.rollback(LastKnownGood);
7296bool CodeGenPrepare::performAddressTypePromotion(
7297 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7298 bool HasPromoted, TypePromotionTransaction &TPT,
7299 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7300 bool Promoted =
false;
7301 SmallPtrSet<Instruction *, 1> UnhandledExts;
7302 bool AllSeenFirst =
true;
7303 for (
auto *
I : SpeculativelyMovedExts) {
7304 Value *HeadOfChain =
I->getOperand(0);
7305 auto AlreadySeen = SeenChainsForSExt.
find(HeadOfChain);
7308 if (AlreadySeen != SeenChainsForSExt.
end()) {
7309 if (AlreadySeen->second !=
nullptr)
7310 UnhandledExts.
insert(AlreadySeen->second);
7311 AllSeenFirst =
false;
7315 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7316 SpeculativelyMovedExts.size() == 1)) {
7320 for (
auto *
I : SpeculativelyMovedExts) {
7321 Value *HeadOfChain =
I->getOperand(0);
7322 SeenChainsForSExt[HeadOfChain] =
nullptr;
7323 ValToSExtendedUses[HeadOfChain].push_back(
I);
7326 Inst = SpeculativelyMovedExts.pop_back_val();
7331 for (
auto *
I : SpeculativelyMovedExts) {
7332 Value *HeadOfChain =
I->getOperand(0);
7333 SeenChainsForSExt[HeadOfChain] = Inst;
7338 if (!AllSeenFirst && !UnhandledExts.
empty())
7339 for (
auto *VisitedSExt : UnhandledExts) {
7340 if (RemovedInsts.count(VisitedSExt))
7342 TypePromotionTransaction TPT(RemovedInsts);
7344 SmallVector<Instruction *, 2> Chains;
7346 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7350 for (
auto *
I : Chains) {
7351 Value *HeadOfChain =
I->getOperand(0);
7353 SeenChainsForSExt[HeadOfChain] =
nullptr;
7354 ValToSExtendedUses[HeadOfChain].push_back(
I);
7360bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7365 Value *Src =
I->getOperand(0);
7366 if (Src->hasOneUse())
7378 bool DefIsLiveOut =
false;
7379 for (User *U :
I->users()) {
7384 if (UserBB == DefBB)
7386 DefIsLiveOut =
true;
7393 for (User *U : Src->users()) {
7396 if (UserBB == DefBB)
7405 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7407 bool MadeChange =
false;
7413 if (UserBB == DefBB)
7417 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7419 if (!InsertedTrunc) {
7422 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7424 InsertedInsts.insert(InsertedTrunc);
7487bool CodeGenPrepare::optimizeLoadExt(LoadInst *
Load) {
7488 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7492 if (
Load->hasOneUse() &&
7498 SmallVector<Instruction *, 8> WorkList;
7499 SmallPtrSet<Instruction *, 16> Visited;
7500 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7501 SmallVector<Instruction *, 8> DropFlags;
7502 for (
auto *U :
Load->users())
7514 while (!WorkList.
empty()) {
7518 if (!Visited.
insert(
I).second)
7523 for (
auto *U :
Phi->users())
7528 switch (
I->getOpcode()) {
7529 case Instruction::And: {
7533 APInt AndBits = AndC->getValue();
7534 DemandBits |= AndBits;
7536 if (AndBits.
ugt(WidestAndBits))
7537 WidestAndBits = AndBits;
7538 if (AndBits == WidestAndBits &&
I->getOperand(0) ==
Load)
7543 case Instruction::Shl: {
7548 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7553 case Instruction::Trunc: {
7556 DemandBits.setLowBits(TruncBitWidth);
7566 uint32_t ActiveBits = DemandBits.getActiveBits();
7578 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7579 WidestAndBits != DemandBits)
7582 LLVMContext &Ctx =
Load->getType()->getContext();
7583 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7594 Builder.CreateAnd(
Load, ConstantInt::get(Ctx, DemandBits)));
7597 InsertedInsts.insert(NewAnd);
7602 NewAnd->setOperand(0,
Load);
7605 for (
auto *
And : AndsToMaybeRemove)
7610 if (&*CurInstIterator ==
And)
7611 CurInstIterator = std::next(
And->getIterator());
7612 And->eraseFromParent();
7617 for (
auto *Inst : DropFlags)
7631 TTI->isExpensiveToSpeculativelyExecute(
I);
7649 uint64_t Max = std::max(TrueWeight, FalseWeight);
7650 uint64_t Sum = TrueWeight + FalseWeight;
7653 if (Probability >
TTI->getPredictableBranchThreshold())
7663 if (!Cmp || !Cmp->hasOneUse())
7686 assert(DefSI->getCondition() ==
SI->getCondition() &&
7687 "The condition of DefSI does not match with SI");
7688 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7691 assert(V &&
"Failed to get select true/false value");
7695bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7719 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7720 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7721 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7722 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7728bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7730 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7731 "Expected a funnel shift");
7755 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7756 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7757 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7765bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7777 It !=
SI->getParent()->
end(); ++It) {
7779 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7786 SelectInst *LastSI = ASI.
back();
7789 CurInstIterator = std::next(LastSI->
getIterator());
7793 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7794 fixupDbgVariableRecordsOnInst(*SI);
7796 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7799 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7802 TargetLowering::SelectSupportKind SelectKind;
7803 if (
SI->getType()->isVectorTy())
7804 SelectKind = TargetLowering::ScalarCondVectorVal;
7806 SelectKind = TargetLowering::ScalarValSelect;
7843 SmallVector<Instruction *> TrueInstrs, FalseInstrs;
7844 for (SelectInst *SI : ASI) {
7856 SplitPt.setHeadBit(
true);
7859 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7864 UncondBrInst *TrueBranch =
nullptr;
7865 UncondBrInst *FalseBranch =
nullptr;
7866 if (TrueInstrs.
size() == 0) {
7871 }
else if (FalseInstrs.
size() == 0) {
7888 EndBlock->
setName(
"select.end");
7890 TrueBlock->
setName(
"select.true.sink");
7892 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7893 :
"select.false.sink");
7897 FreshBBs.
insert(TrueBlock);
7899 FreshBBs.
insert(FalseBlock);
7900 FreshBBs.
insert(EndBlock);
7905 static const unsigned MD[] = {
7906 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7907 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7912 for (Instruction *
I : TrueInstrs)
7914 for (Instruction *
I : FalseInstrs)
7921 if (TrueBlock ==
nullptr)
7922 TrueBlock = StartBlock;
7923 else if (FalseBlock ==
nullptr)
7924 FalseBlock = StartBlock;
7940 SI->eraseFromParent();
7942 ++NumSelectsExpanded;
7946 CurInstIterator = StartBlock->
end();
7953bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7965 "Expected a type of the same size!");
7971 Builder.SetInsertPoint(SVI);
7972 Value *BC1 = Builder.CreateBitCast(
7974 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7975 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7979 SVI, TLInfo,
nullptr,
7980 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7987 !
Op->isTerminator() && !
Op->isEHPad())
7993bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
8008 for (Use *U :
reverse(OpsToSink)) {
8020 SetVector<Instruction *> MaybeDead;
8021 DenseMap<Instruction *, Instruction *> NewInstructions;
8022 for (Use *U : ToReplace) {
8031 FreshBBs.
insert(OpDef->getParent());
8034 NewInstructions[UI] = NI;
8039 InsertedInsts.insert(NI);
8045 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
8046 It->second->setOperand(
U->getOperandNo(), NI);
8053 for (
auto *
I : MaybeDead) {
8054 if (!
I->hasNUsesOrMore(1)) {
8056 I->eraseFromParent();
8063bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
8069 unsigned RegWidth =
RegType.getSizeInBits();
8080 auto *NewType = Type::getIntNTy(
Context, RegWidth);
8089 ExtType = Instruction::SExt;
8092 if (Arg->hasSExtAttr())
8093 ExtType = Instruction::SExt;
8094 if (Arg->hasZExtAttr())
8095 ExtType = Instruction::ZExt;
8101 SI->setCondition(ExtInst);
8102 for (
auto Case :
SI->cases()) {
8103 const APInt &NarrowConst = Case.getCaseValue()->getValue();
8104 APInt WideConst = (ExtType == Instruction::ZExt)
8105 ? NarrowConst.
zext(RegWidth)
8106 : NarrowConst.
sext(RegWidth);
8107 Case.setValue(ConstantInt::get(
Context, WideConst));
8113bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
8120 Value *Condition =
SI->getCondition();
8129 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
8130 ConstantInt *CaseValue = Case.getCaseValue();
8131 BasicBlock *CaseBB = Case.getCaseSuccessor();
8134 bool CheckedForSinglePred =
false;
8135 for (PHINode &
PHI : CaseBB->
phis()) {
8136 Type *PHIType =
PHI.getType();
8144 if (PHIType == ConditionType || TryZExt) {
8146 bool SkipCase =
false;
8147 Value *Replacement =
nullptr;
8148 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
8149 Value *PHIValue =
PHI.getIncomingValue(
I);
8150 if (PHIValue != CaseValue) {
8159 if (
PHI.getIncomingBlock(
I) != SwitchBB)
8164 if (!CheckedForSinglePred) {
8165 CheckedForSinglePred =
true;
8166 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
8172 if (Replacement ==
nullptr) {
8173 if (PHIValue == CaseValue) {
8174 Replacement = Condition;
8177 Replacement = Builder.CreateZExt(Condition, PHIType);
8180 PHI.setIncomingValue(
I, Replacement);
8191bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
8192 bool Changed = optimizeSwitchType(SI);
8193 Changed |= optimizeSwitchPhiConstants(SI);
8214class VectorPromoteHelper {
8216 const DataLayout &
DL;
8219 const TargetLowering &TLI;
8222 const TargetTransformInfo &
TTI;
8228 SmallVector<Instruction *, 4> InstsToBePromoted;
8231 unsigned StoreExtractCombineCost;
8240 if (InstsToBePromoted.
empty())
8242 return InstsToBePromoted.
back();
8248 unsigned getTransitionOriginalValueIdx()
const {
8250 "Other kind of transitions are not supported yet");
8257 unsigned getTransitionIdx()
const {
8259 "Other kind of transitions are not supported yet");
8267 Type *getTransitionType()
const {
8278 void promoteImpl(Instruction *ToBePromoted);
8282 bool isProfitableToPromote() {
8283 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8287 Type *PromotedType = getTransitionType();
8290 unsigned AS =
ST->getPointerAddressSpace();
8308 for (
const auto &Inst : InstsToBePromoted) {
8316 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8328 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8329 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8330 return ScalarCost > VectorCost;
8342 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8357 if (!
EC.isScalable()) {
8358 SmallVector<Constant *, 4> ConstVec;
8360 for (
unsigned Idx = 0; Idx !=
EC.getKnownMinValue(); ++Idx) {
8361 if (Idx == ExtractIdx)
8369 "Generate scalable vector for non-splat is unimplemented");
8374 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8375 unsigned OperandIdx) {
8378 if (OperandIdx != 1)
8380 switch (
Use->getOpcode()) {
8383 case Instruction::SDiv:
8384 case Instruction::UDiv:
8385 case Instruction::SRem:
8386 case Instruction::URem:
8388 case Instruction::FDiv:
8389 case Instruction::FRem:
8390 return !
Use->hasNoNaNs();
8396 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8397 const TargetTransformInfo &
TTI, Instruction *Transition,
8398 unsigned CombineCost)
8399 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8400 StoreExtractCombineCost(CombineCost) {
8401 assert(Transition &&
"Do not know how to promote null");
8405 bool canPromote(
const Instruction *ToBePromoted)
const {
8412 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8415 for (
const Use &U : ToBePromoted->
operands()) {
8416 const Value *Val =
U.get();
8417 if (Val == getEndOfTransition()) {
8421 if (canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()))
8444 void enqueueForPromotion(Instruction *ToBePromoted) {
8445 InstsToBePromoted.push_back(ToBePromoted);
8449 void recordCombineInstruction(Instruction *ToBeCombined) {
8451 CombineInst = ToBeCombined;
8461 if (InstsToBePromoted.empty() || !CombineInst)
8469 for (
auto &ToBePromoted : InstsToBePromoted)
8470 promoteImpl(ToBePromoted);
8471 InstsToBePromoted.clear();
8478void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8488 "The type of the result of the transition does not match "
8493 Type *TransitionTy = getTransitionType();
8498 for (Use &U : ToBePromoted->
operands()) {
8500 Value *NewVal =
nullptr;
8501 if (Val == Transition)
8502 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8509 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8513 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8516 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8522bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8523 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8538 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8539 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost);
8546 if (ToBePromoted->
getParent() != Parent) {
8547 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8549 <<
") than the transition (" << Parent->
getName()
8554 if (VPH.canCombine(ToBePromoted)) {
8556 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8557 VPH.recordCombineInstruction(ToBePromoted);
8559 NumStoreExtractExposed +=
Changed;
8564 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8567 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8569 VPH.enqueueForPromotion(ToBePromoted);
8570 Inst = ToBePromoted;
8610 Type *StoreType =
SI.getValueOperand()->getType();
8619 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8620 DL.getTypeSizeInBits(StoreType) == 0)
8623 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8625 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8641 if (!
match(
SI.getValueOperand(),
8648 if (!
LValue->getType()->isIntegerTy() ||
8649 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8651 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8667 Builder.SetInsertPoint(&
SI);
8671 if (LBC && LBC->getParent() !=
SI.getParent())
8672 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8673 if (HBC && HBC->getParent() !=
SI.getParent())
8674 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8676 bool IsLE =
SI.getDataLayout().isLittleEndian();
8677 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8678 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8679 Value *Addr =
SI.getPointerOperand();
8680 Align Alignment =
SI.getAlign();
8681 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8682 if (IsOffsetStore) {
8683 Addr = Builder.CreateGEP(
8684 SplitStoreType, Addr,
8692 Builder.CreateAlignedStore(V, Addr, Alignment);
8695 CreateSplitStore(
LValue,
false);
8696 CreateSplitStore(HValue,
true);
8699 SI.eraseFromParent();
8707 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8789 if (GEPIOpI->getParent() != SrcBlock)
8794 if (auto *I = dyn_cast<Instruction>(Usr)) {
8795 if (I->getParent() != SrcBlock) {
8803 std::vector<GetElementPtrInst *> UGEPIs;
8806 for (User *Usr : GEPIOp->
users()) {
8825 if (UGEPI->getOperand(0) != GEPIOp)
8827 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8829 if (GEPIIdx->getType() !=
8837 UGEPIs.push_back(UGEPI);
8839 if (UGEPIs.size() == 0)
8842 for (GetElementPtrInst *UGEPI : UGEPIs) {
8844 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8851 for (GetElementPtrInst *UGEPI : UGEPIs) {
8852 UGEPI->setOperand(0, GEPI);
8854 auto NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8855 Constant *NewUGEPIIdx = ConstantInt::get(GEPIIdx->getType(), NewIdx);
8856 UGEPI->setOperand(1, NewUGEPIIdx);
8858 auto SourceFlags = GEPI->getNoWrapFlags();
8861 UGEPI->getNoWrapFlags().intersectForOffsetAdd(SourceFlags);
8863 if (NewIdx.
isNegative() && TargetFlags.hasNoUnsignedWrap())
8864 TargetFlags = TargetFlags.withoutNoUnsignedWrap();
8865 UGEPI->setNoWrapFlags(TargetFlags);
8871 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8873 "GEPIOp is used outside SrcBlock");
8897 Value *
X = Cmp->getOperand(0);
8898 if (!
X->hasUseList())
8903 for (
auto *U :
X->users()) {
8907 (UI->
getParent() != Branch->getParent() &&
8908 UI->
getParent() != Branch->getSuccessor(0) &&
8909 UI->
getParent() != Branch->getSuccessor(1)) ||
8910 (UI->
getParent() != Branch->getParent() &&
8911 !UI->
getParent()->getSinglePredecessor()))
8917 if (UI->
getParent() != Branch->getParent())
8921 ConstantInt::get(UI->
getType(), 0));
8923 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8927 if (Cmp->isEquality() &&
8932 if (UI->
getParent() != Branch->getParent())
8935 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8936 ConstantInt::get(UI->
getType(), 0));
8938 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8946bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8947 bool AnyChange =
false;
8948 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8952 if (InsertedInsts.count(
I))
8961 LargeOffsetGEPMap.erase(
P);
8963 P->eraseFromParent();
8994 I, LI->getLoopFor(
I->getParent()), *
TTI))
9002 TargetLowering::TypeExpandInteger) {
9006 I, LI->getLoopFor(
I->getParent()), *
TTI))
9009 bool MadeChange = optimizeExt(
I);
9010 return MadeChange | optimizeExtUses(
I);
9017 if (optimizeCmp(Cmp, ModifiedDT))
9021 if (optimizeURem(
I))
9025 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
9026 bool Modified = optimizeLoadExt(LI);
9035 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
9036 unsigned AS =
SI->getPointerAddressSpace();
9037 return optimizeMemoryInst(
I,
SI->getOperand(1),
9038 SI->getOperand(0)->getType(), AS);
9042 unsigned AS = RMW->getPointerAddressSpace();
9043 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
9047 unsigned AS = CmpX->getPointerAddressSpace();
9048 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
9049 CmpX->getCompareOperand()->getType(), AS);
9059 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
9060 BinOp->
getOpcode() == Instruction::LShr)) {
9068 if (GEPI->hasAllZeroIndices()) {
9070 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
9071 GEPI->getName(), GEPI->getIterator());
9072 NC->setDebugLoc(GEPI->getDebugLoc());
9075 GEPI, TLInfo,
nullptr,
9076 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9078 optimizeInst(
NC, ModifiedDT);
9101 if (Const0 || Const1) {
9102 if (!Const0 || !Const1) {
9103 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
9108 FI->eraseFromParent();
9115 if (tryToSinkFreeOperands(
I))
9118 switch (
I->getOpcode()) {
9119 case Instruction::Shl:
9120 case Instruction::LShr:
9121 case Instruction::AShr:
9123 case Instruction::Call:
9125 case Instruction::Select:
9127 case Instruction::ShuffleVector:
9129 case Instruction::Switch:
9131 case Instruction::ExtractElement:
9133 case Instruction::CondBr:
9142bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
9143 if (!
I.getType()->isIntegerTy() ||
9148 SmallVector<Instruction *, 4> Insts;
9154 &
I, TLInfo,
nullptr,
9155 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9162bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
9164 bool MadeChange =
false;
9167 CurInstIterator = BB.
begin();
9168 ModifiedDT = ModifyDT::NotModifyDT;
9169 while (CurInstIterator != BB.
end()) {
9170 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
9171 if (ModifiedDT != ModifyDT::NotModifyDT) {
9180 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
9182 bool MadeBitReverse =
true;
9183 while (MadeBitReverse) {
9184 MadeBitReverse =
false;
9186 if (makeBitReverse(
I)) {
9187 MadeBitReverse = MadeChange =
true;
9192 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
9197bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
9198 bool AnyChange =
false;
9199 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
9200 AnyChange |= fixupDbgVariableRecord(DVR);
9206bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
9207 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
9208 DVR.
Type != DbgVariableRecord::LocationType::Assign)
9212 bool AnyChange =
false;
9213 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
9215 for (
Value *Location : LocationOps) {
9216 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9245bool CodeGenPrepare::placeDbgValues(
Function &
F) {
9246 bool MadeChange =
false;
9247 DominatorTree &DT = getDT();
9249 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9250 SmallVector<Instruction *, 4> VIs;
9251 for (
Value *V : DbgItem->location_ops())
9259 for (Instruction *VI : VIs) {
9260 if (
VI->isTerminator())
9265 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9276 if (VIs.size() > 1) {
9279 <<
"Unable to find valid location for Debug Value, undefing:\n"
9281 DbgItem->setKillLocation();
9286 << *DbgItem <<
' ' << *VI);
9293 for (BasicBlock &BB :
F) {
9299 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9301 DbgProcessor(&DVR, &Insn);
9312bool CodeGenPrepare::placePseudoProbes(
Function &
F) {
9313 bool MadeChange =
false;
9316 auto FirstInst =
Block.getFirstInsertionPt();
9317 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9321 while (
I !=
Block.end()) {
9323 II->moveBefore(FirstInst);
9353bool CodeGenPrepare::splitBranchCondition(
Function &
F) {
9357 bool MadeChange =
false;
9358 for (
auto &BB :
F) {
9371 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9379 Value *Cond1, *Cond2;
9382 Opc = Instruction::And;
9385 Opc = Instruction::Or;
9395 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9409 Br1->setCondition(Cond1);
9414 if (
Opc == Instruction::And)
9415 Br1->setSuccessor(0, TmpBB);
9417 Br1->setSuccessor(1, TmpBB);
9422 I->removeFromParent();
9423 I->insertBefore(Br2->getIterator());
9435 if (
Opc == Instruction::Or)
9442 for (PHINode &PN : FBB->
phis()) {
9447 if (
Loop *L = LI->getLoopFor(&BB))
9448 L->addBasicBlockToLoop(TmpBB, *LI);
9452 DTU->
applyUpdates({{DominatorTree::Insert, &BB, TmpBB},
9453 {DominatorTree::Insert, TmpBB,
TBB},
9454 {DominatorTree::Insert, TmpBB, FBB},
9455 {DominatorTree::Delete, &BB,
TBB}});
9459 if (
Opc == Instruction::Or) {
9481 uint64_t NewTrueWeight = TrueWeight;
9482 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9486 NewTrueWeight = TrueWeight;
9487 NewFalseWeight = 2 * FalseWeight;
9512 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9513 uint64_t NewFalseWeight = FalseWeight;
9517 NewTrueWeight = 2 * TrueWeight;
9518 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.
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()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
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.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
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)
LLVM_ABI void replacePhiUsesWith(MachineBasicBlock *Old, MachineBasicBlock *New)
Update all phi nodes in this basic block to refer to basic block New instead of basic block Old.
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.
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.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
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.
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.
user_iterator_impl< User > user_iterator
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)
DXILDebugInfoMap run(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.