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);
414 bool eliminateAssumptions(Function &
F);
415 bool eliminateFallThrough(Function &
F);
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);
446 bool placeDbgValues(Function &
F);
447 bool placePseudoProbes(Function &
F);
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);
454 bool mergeSExts(Function &
F);
455 bool splitLargeGEPOffsets();
456 bool optimizePhiType(PHINode *Inst, SmallPtrSetImpl<PHINode *> &Visited,
457 SmallPtrSetImpl<Instruction *> &DeletedInstrs);
458 bool optimizePhiTypes(Function &
F);
459 bool performAddressTypePromotion(
460 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
461 bool HasPromoted, TypePromotionTransaction &TPT,
462 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts);
463 bool splitBranchCondition(Function &
F);
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);
474 void verifyBFIUpdates(Function &
F);
475 bool _run(Function &
F);
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 LoopInfo NewLI(NewDT);
860 BranchProbabilityInfo NewBPI(
F, NewCI, TLInfo);
861 BlockFrequencyInfo NewBFI(
F, NewBPI, NewLI);
862 NewBFI.verifyMatch(*BFI);
868bool CodeGenPrepare::eliminateFallThrough(Function &
F) {
870 SmallPtrSet<BasicBlock *, 8> Preds;
878 BasicBlock *SinglePred = BB->getSinglePredecessor();
881 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
894 FreshBBs.
insert(SinglePred);
902 for (
auto *Pred : Preds)
910BasicBlock *CodeGenPrepare::findDestBlockOfMergeableEmptyBlock(BasicBlock *BB) {
919 if (BBI != BB->
begin()) {
930 if (!canMergeBlocks(BB, DestBB))
940bool CodeGenPrepare::eliminateMostlyEmptyBlocks(Function &
F,
bool &ResetLI) {
941 SmallPtrSet<BasicBlock *, 16> Preheaders;
943 while (!LoopList.empty()) {
944 Loop *
L = LoopList.pop_back_val();
946 if (BasicBlock *Preheader =
L->getLoopPreheader())
947 Preheaders.
insert(Preheader);
951 bool MadeChange =
false;
952 SmallPtrSet<PHINode *, 32> KnownNonDeadPHIs;
964 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
966 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.
count(BB)))
969 ResetLI |= eliminateMostlyEmptyBlock(BB);
975bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB,
1026 SmallPtrSet<BasicBlock *, 16> SameIncomingValueBBs;
1031 if (DestBBPred == BB)
1035 return DestPN.getIncomingValueForBlock(BB) ==
1036 DestPN.getIncomingValueForBlock(DestBBPred);
1038 SameIncomingValueBBs.
insert(DestBBPred);
1044 if (SameIncomingValueBBs.
count(Pred))
1047 BlockFrequency PredFreq = BFI->getBlockFreq(Pred);
1048 BlockFrequency
BBFreq = BFI->getBlockFreq(BB);
1050 for (
auto *SameValueBB : SameIncomingValueBBs)
1051 if (SameValueBB->getUniquePredecessor() == Pred &&
1052 DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
1053 BBFreq += BFI->getBlockFreq(SameValueBB);
1056 return !Limit || PredFreq <= *Limit;
1062bool CodeGenPrepare::canMergeBlocks(
const BasicBlock *BB,
1063 const BasicBlock *DestBB)
const {
1067 for (
const PHINode &PN : BB->
phis()) {
1068 for (
const User *U : PN.users()) {
1077 for (
unsigned I = 0,
E = UPN->getNumIncomingValues();
I !=
E; ++
I) {
1080 Insn->
getParent() != UPN->getIncomingBlock(
I))
1095 SmallPtrSet<const BasicBlock *, 16> BBPreds;
1098 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1099 BBPreds.
insert(BBPN->getIncomingBlock(i));
1107 if (BBPreds.
count(Pred)) {
1108 for (
const PHINode &PN : DestBB->
phis()) {
1109 const Value *
V1 = PN.getIncomingValueForBlock(Pred);
1110 const Value *V2 = PN.getIncomingValueForBlock(BB);
1114 if (V2PN->getParent() == BB)
1115 V2 = V2PN->getIncomingValueForBlock(Pred);
1146bool CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
1156 if (SinglePred != DestBB) {
1157 assert(SinglePred == BB &&
1158 "Single predecessor not the same as predecessor");
1167 FreshBBs.
insert(SinglePred);
1168 FreshBBs.
erase(DestBB);
1176 for (PHINode &PN : DestBB->
phis()) {
1178 Value *InVal = PN.removeIncomingValue(BB,
false);
1183 if (InValPhi && InValPhi->
getParent() == BB) {
1192 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1193 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1196 PN.addIncoming(InVal, Pred);
1202 if (BI->hasMetadata(LLVMContext::MD_loop)) {
1210 SmallPtrSet<BasicBlock *, 8> SeenPreds;
1214 if (!PredOfDestBB.contains(Pred)) {
1215 if (SeenPreds.
insert(Pred).second)
1216 DTUpdates.
push_back({DominatorTree::Insert, Pred, DestBB});
1221 if (SeenPreds.
insert(Pred).second)
1222 DTUpdates.
push_back({DominatorTree::Delete, Pred, BB});
1224 DTUpdates.
push_back({DominatorTree::Delete, BB, DestBB});
1244 for (
auto *ThisRelocate : AllRelocateCalls) {
1245 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1246 ThisRelocate->getDerivedPtrIndex());
1247 RelocateIdxMap.
insert(std::make_pair(K, ThisRelocate));
1249 for (
auto &Item : RelocateIdxMap) {
1250 std::pair<unsigned, unsigned>
Key = Item.first;
1251 if (
Key.first ==
Key.second)
1256 auto BaseKey = std::make_pair(
Key.first,
Key.first);
1259 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1260 if (MaybeBase == RelocateIdxMap.
end())
1265 RelocateInstMap[MaybeBase->second].push_back(
I);
1273 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1276 if (!
Op ||
Op->getZExtValue() > 20)
1280 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1290 bool MadeChange =
false;
1297 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1298 &*R != RelocatedBase; ++R)
1302 RelocatedBase->
moveBefore(RI->getIterator());
1309 "Not relocating a derived object of the original base object");
1310 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1315 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1325 if (!Derived || Derived->getPointerOperand() !=
Base)
1334 "Should always have one since it's not a terminator");
1338 Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
1362 Value *ActualRelocatedBase = RelocatedBase;
1363 if (RelocatedBase->
getType() !=
Base->getType()) {
1364 ActualRelocatedBase =
1365 Builder.CreateBitCast(RelocatedBase,
Base->getType());
1367 Value *Replacement =
1368 Builder.CreateGEP(Derived->getSourceElementType(), ActualRelocatedBase,
1374 Value *ActualReplacement = Replacement;
1375 if (Replacement->
getType() != ToReplace->getType()) {
1377 Builder.CreateBitCast(Replacement, ToReplace->
getType());
1380 ToReplace->eraseFromParent();
1404bool CodeGenPrepare::simplifyOffsetableRelocate(GCStatepointInst &
I) {
1405 bool MadeChange =
false;
1407 for (
auto *U :
I.users())
1414 if (AllRelocateCalls.
size() < 2)
1419 MapVector<GCRelocateInst *, SmallVector<GCRelocateInst *, 0>> RelocateInstMap;
1421 if (RelocateInstMap.
empty())
1424 for (
auto &Item : RelocateInstMap)
1438 bool MadeChange =
false;
1441 Use &TheUse = UI.getUse();
1448 UserBB = PN->getIncomingBlock(TheUse);
1456 if (
User->isEHPad())
1466 if (UserBB == DefBB)
1470 CastInst *&InsertedCast = InsertedCasts[UserBB];
1472 if (!InsertedCast) {
1480 TheUse = InsertedCast;
1506 ASC->getDestAddressSpace()))
1561static std::optional<std::pair<Instruction *, Constant *>>
1564 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1565 return std::nullopt;
1568 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1569 return std::nullopt;
1573 return std::make_pair(IVInc, Step);
1574 return std::nullopt;
1587 return IVInc->first ==
I;
1591bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
1595 auto IsReplacableIVIncrement = [
this, &
Cmp](BinaryOperator *BO) {
1598 const Loop *
L = LI->getLoopFor(BO->
getParent());
1599 assert(L &&
"L should not be null after isIVIncrement()");
1601 if (LI->getLoopFor(
Cmp->getParent()) != L)
1614 return BO->
hasOneUse() && DT.dominates(
Cmp->getParent(),
L->getLoopLatch());
1616 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1639 if (BO->
getOpcode() == Instruction::Add &&
1640 IID == Intrinsic::usub_with_overflow) {
1647 for (Instruction &Iter : *
Cmp->getParent()) {
1650 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1655 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1658 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1659 if (BO->
getOpcode() != Instruction::Xor) {
1660 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1664 "Patterns with XOr should use the BO only in the compare");
1665 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1667 Cmp->eraseFromParent();
1677 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1685 B = ConstantInt::get(
B->getType(), 1);
1693 for (
User *U :
A->users()) {
1704bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp,
1705 ModifyDT &ModifiedDT) {
1706 bool EdgeCase =
false;
1708 BinaryOperator *
Add;
1713 A =
Add->getOperand(0);
1714 B =
Add->getOperand(1);
1720 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1726 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1729 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1730 Intrinsic::uadd_with_overflow))
1734 ModifiedDT = ModifyDT::ModifyInstDT;
1738bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
1739 ModifyDT &ModifiedDT) {
1746 ICmpInst::Predicate Pred =
Cmp->getPredicate();
1747 if (Pred == ICmpInst::ICMP_UGT) {
1749 Pred = ICmpInst::ICMP_ULT;
1753 B = ConstantInt::get(
B->getType(), 1);
1754 Pred = ICmpInst::ICMP_ULT;
1759 Pred = ICmpInst::ICMP_ULT;
1761 if (Pred != ICmpInst::ICMP_ULT)
1768 BinaryOperator *
Sub =
nullptr;
1769 for (User *U : CmpVariableOperand->
users()) {
1777 const APInt *CmpC, *AddC;
1789 Sub->hasNUsesOrMore(1)))
1795 if (
Sub->getParent() !=
Cmp->getParent() && !
Sub->hasOneUse())
1798 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1799 Cmp, Intrinsic::usub_with_overflow))
1803 ModifiedDT = ModifyDT::ModifyInstDT;
1810bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1823 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1829 Type *OpTy =
X->getType();
1837 if (Pred == ICmpInst::ICMP_EQ) {
1838 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1839 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1841 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1847 if (IsPowerOf2OrZeroTest ||
1858 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1867 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1870 Cmp->replaceAllUsesWith(NewCmp);
1890 bool UsedInPhiOrCurrentBlock =
any_of(Cmp->users(), [Cmp](
User *U) {
1891 return isa<PHINode>(U) ||
1892 cast<Instruction>(U)->getParent() == Cmp->getParent();
1897 if (UsedInPhiOrCurrentBlock && Cmp->getOperand(0)->getType()->isIntegerTy() &&
1898 Cmp->getOperand(0)->getType()->getScalarSizeInBits() >
1899 DL.getLargestLegalIntTypeSizeInBits())
1905 bool MadeChange =
false;
1908 Use &TheUse = UI.getUse();
1923 if (UserBB == DefBB)
1927 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1933 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1940 TheUse = InsertedCmp;
1946 if (Cmp->use_empty()) {
1947 Cmp->eraseFromParent();
1984 for (
User *U : Cmp->users()) {
2006 if (CmpBB != FalseBB)
2009 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
2023 for (
User *U : Cmp->users()) {
2025 BI->swapSuccessors();
2031 SI->swapProfMetadata();
2043 Value *Op0 = Cmp->getOperand(0);
2044 Value *Op1 = Cmp->getOperand(1);
2053 unsigned NumInspected = 0;
2056 if (++NumInspected > 128)
2064 if (GoodToSwap > 0) {
2065 Cmp->swapOperands();
2085 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
2088 auto [ClassVal, ClassTest] =
2094 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2098 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
2099 Cmp->replaceAllUsesWith(IsFPClass);
2107 Value *Incr, *RemAmt;
2112 Value *AddInst, *AddOffset;
2115 if (PN !=
nullptr) {
2117 AddOffset =
nullptr;
2135 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2139 if (!L->contains(Rem))
2143 if (!L->isLoopInvariant(RemAmt))
2147 if (AddOffset && !L->isLoopInvariant(AddOffset))
2168 AddInstOut = AddInst;
2169 AddOffsetOut = AddOffset;
2188 Value *AddOffset, *RemAmt, *AddInst;
2191 AddOffset, LoopIncrPN))
2216 assert(AddOffset &&
"We found an add but missing values");
2235 Builder.SetInsertPoint(LoopIncrPN);
2236 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2241 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2246 NewRem->
addIncoming(Start, L->getLoopPreheader());
2251 FreshBBs.
insert(L->getLoopLatch());
2262bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2268bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2272 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2275 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2278 if (unfoldPowerOf2Test(Cmp))
2299 SetOfInstrs &InsertedInsts) {
2302 assert(!InsertedInsts.count(AndI) &&
2303 "Attempting to optimize already optimized and instruction");
2304 (void)InsertedInsts;
2318 for (
auto *U : AndI->
users()) {
2326 if (!CmpC || !CmpC->
isZero())
2341 Use &TheUse = UI.getUse();
2359 TheUse = InsertedAnd;
2376 if (
User->getOpcode() != Instruction::And ||
2382 if ((Cimm & (Cimm + 1)).getBoolValue())
2396 bool MadeChange =
false;
2399 TruncE = TruncI->user_end();
2400 TruncUI != TruncE;) {
2402 Use &TruncTheUse = TruncUI.getUse();
2427 if (UserBB == TruncUserBB)
2431 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2433 if (!InsertedShift && !InsertedTrunc) {
2437 if (ShiftI->
getOpcode() == Instruction::AShr)
2439 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2442 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2450 TruncInsertPt.setHeadBit(
true);
2451 assert(TruncInsertPt != TruncUserBB->
end());
2455 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2456 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2460 TruncTheUse = InsertedTrunc;
2493 bool MadeChange =
false;
2496 Use &TheUse = UI.getUse();
2510 if (UserBB == DefBB) {
2538 if (!InsertedShift) {
2542 if (ShiftI->
getOpcode() == Instruction::AShr)
2544 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2547 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2555 TheUse = InsertedShift;
2603 unsigned SizeInBits = Ty->getScalarSizeInBits();
2604 if (Ty->isVectorTy())
2615 nullptr,
"cond.false");
2617 FreshBBs.
insert(CallBlock);
2624 SplitPt.setHeadBit(
true);
2626 nullptr,
"cond.end");
2628 FreshBBs.
insert(EndBlock);
2633 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2640 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2641 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2642 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2648 Builder.SetInsertPoint(EndBlock, EndBlock->
begin());
2649 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2659 ModifiedDT = ModifyDT::ModifyBBDT;
2663bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2667 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2675 for (
auto &Arg : CI->
args()) {
2680 if (!Arg->getType()->isPointerTy())
2682 APInt
Offset(
DL->getIndexSizeInBits(
2685 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2686 uint64_t Offset2 =
Offset.getLimitedValue();
2692 if (AllocaSize && AllocaSize->getKnownMinValue() >= MinSize + Offset2)
2710 MaybeAlign MIDestAlign =
MI->getDestAlign();
2711 if (!MIDestAlign || DestAlign > *MIDestAlign)
2712 MI->setDestAlignment(DestAlign);
2714 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2716 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2717 MTI->setSourceAlignment(SrcAlign);
2727 for (
auto &Arg : CI->
args()) {
2728 if (!Arg->getType()->isPointerTy())
2730 unsigned AS = Arg->getType()->getPointerAddressSpace();
2731 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2737 switch (
II->getIntrinsicID()) {
2740 case Intrinsic::assume:
2742 case Intrinsic::allow_runtime_check:
2743 case Intrinsic::allow_ubsan_check:
2744 case Intrinsic::experimental_widenable_condition: {
2748 if (
II->use_empty()) {
2749 II->eraseFromParent();
2753 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2758 case Intrinsic::objectsize:
2760 case Intrinsic::is_constant:
2762 case Intrinsic::aarch64_stlxr:
2763 case Intrinsic::aarch64_stxr: {
2772 InsertedInsts.insert(ExtVal);
2776 case Intrinsic::launder_invariant_group:
2777 case Intrinsic::strip_invariant_group: {
2778 Value *ArgVal =
II->getArgOperand(0);
2779 auto it = LargeOffsetGEPMap.
find(
II);
2780 if (it != LargeOffsetGEPMap.
end()) {
2784 auto GEPs = std::move(it->second);
2785 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2790 II->eraseFromParent();
2793 case Intrinsic::cttz:
2794 case Intrinsic::ctlz:
2798 case Intrinsic::fshl:
2799 case Intrinsic::fshr:
2800 return optimizeFunnelShift(
II);
2801 case Intrinsic::masked_gather:
2802 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2803 case Intrinsic::masked_scatter:
2804 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2805 case Intrinsic::masked_load:
2808 if (VT->getNumElements() == 1) {
2809 Value *PtrVal =
II->getArgOperand(0);
2811 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2816 case Intrinsic::masked_store:
2820 if (VT->getNumElements() == 1) {
2821 Value *PtrVal =
II->getArgOperand(1);
2823 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2828 case Intrinsic::umul_with_overflow:
2829 return optimizeMulWithOverflow(
II,
false, ModifiedDT);
2830 case Intrinsic::smul_with_overflow:
2831 return optimizeMulWithOverflow(
II,
true, ModifiedDT);
2834 SmallVector<Value *, 2> PtrOps;
2837 while (!PtrOps.
empty()) {
2840 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2854 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2856 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2866 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2867 if (!
F->getReturnType()->isPointerTy())
2870 GlobalVariable *UniformValue =
nullptr;
2871 for (
auto &BB : *
F) {
2876 else if (V != UniformValue)
2884 return UniformValue;
2887 if (
Callee->hasExactDefinition()) {
2888 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2889 bool MadeChange =
false;
2915 switch (
II->getIntrinsicID()) {
2916 case Intrinsic::memset:
2917 case Intrinsic::memcpy:
2918 case Intrinsic::memmove:
2926 if (Callee && TLInfo && TLInfo->
getLibFunc(*Callee, LF))
2928 case LibFunc_strcpy:
2929 case LibFunc_strncpy:
2930 case LibFunc_strcat:
2931 case LibFunc_strncat:
2972bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
2973 ModifyDT &ModifiedDT) {
2981 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2983 PHINode *PN =
nullptr;
2984 ExtractValueInst *EVI =
nullptr;
2985 BitCastInst *BCI =
nullptr;
3005 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
3011 return II->getIntrinsicID() == Intrinsic::lifetime_end;
3017 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
3019 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
3041 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
3048 auto MayBePermittedAsTailCall = [&](
const auto *CI) {
3065 MayBePermittedAsTailCall(CI)) {
3086 MayBePermittedAsTailCall(CI)) {
3093 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
3095 if (!VisitedBBs.
insert(Pred).second)
3097 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
3099 if (CI && CI->
use_empty() && MayBePermittedAsTailCall(CI)) {
3114 for (
auto const &TailCallBB : TailCallBBs) {
3124 BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB));
3125 BFI->setBlockFreq(BB,
3126 (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB)));
3127 ModifiedDT = ModifyDT::ModifyBBDT;
3136 for (
auto *CI : CallInsts) {
3137 for (
auto const *FakeUse : FakeUses) {
3138 auto *ClonedInst = FakeUse->clone();
3156struct ExtAddrMode :
public TargetLowering::AddrMode {
3157 Value *BaseReg =
nullptr;
3158 Value *ScaledReg =
nullptr;
3159 Value *OriginalValue =
nullptr;
3160 bool InBounds =
true;
3164 BaseRegField = 0x01,
3166 BaseOffsField = 0x04,
3167 ScaledRegField = 0x08,
3169 MultipleFields = 0xff
3172 ExtAddrMode() =
default;
3174 void print(raw_ostream &OS)
const;
3181 if (ScaledReg == From)
3185 FieldName
compare(
const ExtAddrMode &other) {
3188 if (BaseReg && other.
BaseReg &&
3190 return MultipleFields;
3191 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3192 return MultipleFields;
3195 return MultipleFields;
3198 if (InBounds != other.InBounds)
3199 return MultipleFields;
3202 unsigned Result = NoField;
3205 if (BaseGV != other.BaseGV)
3207 if (BaseOffs != other.BaseOffs)
3210 Result |= ScaledRegField;
3213 if (Scale && other.
Scale && Scale != other.
Scale)
3217 return MultipleFields;
3219 return static_cast<FieldName
>(
Result);
3229 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3240 case ScaledRegField:
3247 void SetCombinedField(FieldName
Field,
Value *V,
3248 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3253 case ExtAddrMode::BaseRegField:
3256 case ExtAddrMode::BaseGVField:
3259 assert(BaseReg ==
nullptr);
3263 case ExtAddrMode::ScaledRegField:
3268 for (
const ExtAddrMode &AM : AddrModes)
3274 case ExtAddrMode::BaseOffsField:
3277 assert(ScaledReg ==
nullptr);
3287static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3293#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3294void ExtAddrMode::print(raw_ostream &OS)
const {
3295 bool NeedPlus =
false;
3301 BaseGV->printAsOperand(OS,
false);
3306 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3311 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3312 BaseReg->printAsOperand(OS,
false);
3316 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3339class TypePromotionTransaction {
3343 class TypePromotionAction {
3351 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3353 virtual ~TypePromotionAction() =
default;
3360 virtual void undo() = 0;
3365 virtual void commit() {
3371 class InsertionHandler {
3380 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3383 bool HasPrevInstruction;
3387 InsertionHandler(Instruction *Inst) {
3395 if (HasPrevInstruction) {
3403 void insert(Instruction *Inst) {
3404 if (HasPrevInstruction) {
3416 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3421 class InstructionMoveBefore :
public TypePromotionAction {
3423 InsertionHandler Position;
3428 : TypePromotionAction(Inst), Position(Inst) {
3429 LLVM_DEBUG(
dbgs() <<
"Do: move: " << *Inst <<
"\nbefore: " << *Before
3435 void undo()
override {
3437 Position.insert(Inst);
3442 class OperandSetter :
public TypePromotionAction {
3451 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3452 : TypePromotionAction(Inst), Idx(Idx) {
3454 <<
"for:" << *Inst <<
"\n"
3455 <<
"with:" << *NewVal <<
"\n");
3461 void undo()
override {
3463 <<
"for: " << *Inst <<
"\n"
3464 <<
"with: " << *Origin <<
"\n");
3471 class OperandsHider :
public TypePromotionAction {
3473 SmallVector<Value *, 4> OriginalValues;
3477 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3480 OriginalValues.
reserve(NumOpnds);
3481 for (
unsigned It = 0; It < NumOpnds; ++It) {
3493 void undo()
override {
3495 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3501 class TruncBuilder :
public TypePromotionAction {
3508 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3510 Builder.SetCurrentDebugLocation(
DebugLoc());
3511 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3516 Value *getBuiltValue() {
return Val; }
3519 void undo()
override {
3522 IVal->eraseFromParent();
3527 class SExtBuilder :
public TypePromotionAction {
3534 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3535 : TypePromotionAction(InsertPt) {
3537 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3542 Value *getBuiltValue() {
return Val; }
3545 void undo()
override {
3548 IVal->eraseFromParent();
3553 class ZExtBuilder :
public TypePromotionAction {
3560 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3561 : TypePromotionAction(InsertPt) {
3563 Builder.SetCurrentDebugLocation(
DebugLoc());
3564 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3569 Value *getBuiltValue() {
return Val; }
3572 void undo()
override {
3575 IVal->eraseFromParent();
3580 class TypeMutator :
public TypePromotionAction {
3586 TypeMutator(Instruction *Inst,
Type *NewTy)
3587 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3588 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3594 void undo()
override {
3595 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3602 class UsesReplacer :
public TypePromotionAction {
3604 struct InstructionAndIdx {
3611 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3612 : Inst(Inst), Idx(Idx) {}
3618 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3628 UsesReplacer(Instruction *Inst,
Value *New)
3629 : TypePromotionAction(Inst),
New(
New) {
3630 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3633 for (Use &U : Inst->
uses()) {
3635 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3646 void undo()
override {
3648 for (InstructionAndIdx &Use : OriginalUses)
3649 Use.Inst->setOperand(
Use.Idx, Inst);
3654 for (DbgVariableRecord *DVR : DbgVariableRecords)
3655 DVR->replaceVariableLocationOp(New, Inst);
3660 class InstructionRemover :
public TypePromotionAction {
3662 InsertionHandler Inserter;
3666 OperandsHider Hider;
3669 UsesReplacer *Replacer =
nullptr;
3672 SetOfInstrs &RemovedInsts;
3679 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3680 Value *New =
nullptr)
3681 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3682 RemovedInsts(RemovedInsts) {
3684 Replacer =
new UsesReplacer(Inst, New);
3685 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3686 RemovedInsts.insert(Inst);
3693 ~InstructionRemover()
override {
delete Replacer; }
3695 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3696 InstructionRemover(
const InstructionRemover &other) =
delete;
3700 void undo()
override {
3701 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3702 Inserter.insert(Inst);
3706 RemovedInsts.erase(Inst);
3714 using ConstRestorationPt =
const TypePromotionAction *;
3716 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3717 : RemovedInsts(RemovedInsts) {}
3724 void rollback(ConstRestorationPt Point);
3727 ConstRestorationPt getRestorationPoint()
const;
3732 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3741 void mutateType(Instruction *Inst,
Type *NewTy);
3744 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3757 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3759 SetOfInstrs &RemovedInsts;
3764void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3766 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3767 Inst, Idx, NewVal));
3770void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3773 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3774 Inst, RemovedInsts, NewVal));
3777void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3780 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3783void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3785 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3788Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3789 std::unique_ptr<TruncBuilder> Ptr(
new TruncBuilder(Opnd, Ty));
3790 Value *Val = Ptr->getBuiltValue();
3791 Actions.push_back(std::move(Ptr));
3795Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3797 std::unique_ptr<SExtBuilder> Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3798 Value *Val = Ptr->getBuiltValue();
3799 Actions.push_back(std::move(Ptr));
3803Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3805 std::unique_ptr<ZExtBuilder> Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3806 Value *Val = Ptr->getBuiltValue();
3807 Actions.push_back(std::move(Ptr));
3811TypePromotionTransaction::ConstRestorationPt
3812TypePromotionTransaction::getRestorationPoint()
const {
3813 return !Actions.empty() ? Actions.back().get() :
nullptr;
3816bool TypePromotionTransaction::commit() {
3817 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3824void TypePromotionTransaction::rollback(
3825 TypePromotionTransaction::ConstRestorationPt Point) {
3826 while (!Actions.empty() && Point != Actions.back().get()) {
3827 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3837class AddressingModeMatcher {
3838 SmallVectorImpl<Instruction *> &AddrModeInsts;
3839 const TargetLowering &TLI;
3840 const TargetRegisterInfo &
TRI;
3841 const DataLayout &
DL;
3843 const std::function<
const DominatorTree &()> getDTFn;
3856 const SetOfInstrs &InsertedInsts;
3859 InstrToOrigTy &PromotedInsts;
3862 TypePromotionTransaction &TPT;
3865 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3869 bool IgnoreProfitability;
3872 bool OptSize =
false;
3874 ProfileSummaryInfo *PSI;
3875 BlockFrequencyInfo *BFI;
3877 AddressingModeMatcher(
3878 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3879 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3880 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3881 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3882 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3883 TypePromotionTransaction &TPT,
3884 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3885 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI)
3886 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3887 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3888 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3889 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3890 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI), BFI(BFI) {
3891 IgnoreProfitability =
false;
3903 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3904 SmallVectorImpl<Instruction *> &AddrModeInsts,
3905 const TargetLowering &TLI,
const LoopInfo &LI,
3906 const std::function<
const DominatorTree &()> getDTFn,
3907 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3908 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3909 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3910 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
3913 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3914 AccessTy, AS, MemoryInst, Result,
3915 InsertedInsts, PromotedInsts, TPT,
3916 LargeOffsetGEP, OptSize, PSI, BFI)
3924 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3926 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3927 bool *MovedAway =
nullptr);
3928 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3929 ExtAddrMode &AMBefore,
3930 ExtAddrMode &AMAfter);
3931 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3932 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3933 Value *PromotedOperand)
const;
3939class PhiNodeSetIterator {
3940 PhiNodeSet *
const Set;
3941 size_t CurrentIndex = 0;
3946 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3948 PhiNodeSetIterator &operator++();
3964 friend class PhiNodeSetIterator;
3966 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3967 using iterator = PhiNodeSetIterator;
3982 size_t FirstValidElement = 0;
3988 bool insert(PHINode *Ptr) {
3989 if (NodeMap.insert(std::make_pair(Ptr,
NodeList.
size())).second) {
3999 bool erase(PHINode *Ptr) {
4000 if (NodeMap.erase(Ptr)) {
4001 SkipRemovedElements(FirstValidElement);
4011 FirstValidElement = 0;
4017 if (FirstValidElement == 0)
4018 SkipRemovedElements(FirstValidElement);
4019 return PhiNodeSetIterator(
this, FirstValidElement);
4026 size_t size()
const {
return NodeMap.size(); }
4029 size_t count(PHINode *Ptr)
const {
return NodeMap.count(Ptr); }
4037 void SkipRemovedElements(
size_t &CurrentIndex) {
4039 auto it = NodeMap.find(NodeList[CurrentIndex]);
4042 if (it != NodeMap.end() && it->second == CurrentIndex)
4049PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
4052PHINode *PhiNodeSetIterator::operator*()
const {
4054 "PhiNodeSet access out of range");
4055 return Set->NodeList[CurrentIndex];
4058PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
4060 "PhiNodeSet access out of range");
4062 Set->SkipRemovedElements(CurrentIndex);
4066bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
4067 return CurrentIndex ==
RHS.CurrentIndex;
4070bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
4071 return !((*this) ==
RHS);
4077class SimplificationTracker {
4078 DenseMap<Value *, Value *> Storage;
4081 PhiNodeSet AllPhiNodes;
4083 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
4088 auto SV = Storage.
find(V);
4089 if (SV == Storage.
end())
4097 void ReplacePhi(PHINode *From, PHINode *To) {
4098 Value *OldReplacement = Get(From);
4099 while (OldReplacement != From) {
4102 OldReplacement = Get(From);
4104 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
4107 AllPhiNodes.erase(From);
4111 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
4113 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
4115 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
4117 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4119 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4121 void destroyNewNodes(
Type *CommonType) {
4124 for (
auto *
I : AllPhiNodes) {
4125 I->replaceAllUsesWith(Dummy);
4126 I->eraseFromParent();
4128 AllPhiNodes.clear();
4129 for (
auto *
I : AllSelectNodes) {
4130 I->replaceAllUsesWith(Dummy);
4131 I->eraseFromParent();
4133 AllSelectNodes.clear();
4138class AddressingModeCombiner {
4139 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4140 typedef std::pair<PHINode *, PHINode *> PHIPair;
4147 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4150 bool AllAddrModesTrivial =
true;
4153 Type *CommonType =
nullptr;
4155 const DataLayout &
DL;
4161 Value *CommonValue =
nullptr;
4164 AddressingModeCombiner(
const DataLayout &
DL,
Value *OriginalValue)
4165 :
DL(
DL), Original(OriginalValue) {}
4167 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4170 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4175 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4179 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4182 if (AddrModes.
empty()) {
4190 ExtAddrMode::FieldName ThisDifferentField =
4191 AddrModes[0].compare(NewAddrMode);
4192 if (DifferentField == ExtAddrMode::NoField)
4193 DifferentField = ThisDifferentField;
4194 else if (DifferentField != ThisDifferentField)
4195 DifferentField = ExtAddrMode::MultipleFields;
4198 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4201 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4206 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4211 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4212 !NewAddrMode.HasBaseReg);
4229 bool combineAddrModes() {
4231 if (AddrModes.
size() == 0)
4235 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4240 if (AllAddrModesTrivial)
4243 if (!addrModeCombiningAllowed())
4249 FoldAddrToValueMapping
Map;
4250 if (!initializeMap(Map))
4253 CommonValue = findCommon(Map);
4255 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4256 return CommonValue !=
nullptr;
4262 void eraseCommonValueIfDead() {
4263 if (CommonValue && CommonValue->
use_empty())
4265 CommonInst->eraseFromParent();
4273 bool initializeMap(FoldAddrToValueMapping &Map) {
4276 SmallVector<Value *, 2> NullValue;
4278 for (
auto &AM : AddrModes) {
4282 if (CommonType && CommonType !=
Type)
4285 Map[AM.OriginalValue] = DV;
4290 assert(CommonType &&
"At least one non-null value must be!");
4291 for (
auto *V : NullValue)
4319 Value *findCommon(FoldAddrToValueMapping &Map) {
4327 SimplificationTracker
ST;
4332 InsertPlaceholders(Map, TraverseOrder, ST);
4335 FillPlaceholders(Map, TraverseOrder, ST);
4338 ST.destroyNewNodes(CommonType);
4343 unsigned PhiNotMatchedCount = 0;
4345 ST.destroyNewNodes(CommonType);
4349 auto *
Result =
ST.Get(
Map.find(Original)->second);
4351 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4352 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4359 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4360 SmallSetVector<PHIPair, 8> &Matcher,
4361 PhiNodeSet &PhiNodesToMatch) {
4364 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4367 SmallSet<PHIPair, 8> Visited;
4368 while (!WorkList.
empty()) {
4370 if (!Visited.
insert(Item).second)
4377 for (
auto *
B : Item.first->blocks()) {
4378 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4379 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4380 if (FirstValue == SecondValue)
4390 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4395 if (Matcher.
count({FirstPhi, SecondPhi}))
4400 if (MatchedPHIs.
insert(FirstPhi).second)
4401 Matcher.
insert({FirstPhi, SecondPhi});
4403 WorkList.
push_back({FirstPhi, SecondPhi});
4412 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4413 unsigned &PhiNotMatchedCount) {
4417 SmallSetVector<PHIPair, 8> Matched;
4418 SmallPtrSet<PHINode *, 8> WillNotMatch;
4419 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4420 while (PhiNodesToMatch.size()) {
4421 PHINode *
PHI = *PhiNodesToMatch.begin();
4424 WillNotMatch.
clear();
4428 bool IsMatched =
false;
4429 for (
auto &
P :
PHI->getParent()->phis()) {
4431 if (PhiNodesToMatch.count(&
P))
4433 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4443 for (
auto MV : Matched)
4444 ST.ReplacePhi(MV.first, MV.second);
4449 if (!AllowNewPhiNodes)
4452 PhiNotMatchedCount += WillNotMatch.
size();
4453 for (
auto *
P : WillNotMatch)
4454 PhiNodesToMatch.erase(
P);
4459 void FillPlaceholders(FoldAddrToValueMapping &Map,
4460 SmallVectorImpl<Value *> &TraverseOrder,
4461 SimplificationTracker &ST) {
4462 while (!TraverseOrder.
empty()) {
4464 assert(
Map.contains(Current) &&
"No node to fill!!!");
4470 auto *TrueValue = CurrentSelect->getTrueValue();
4471 assert(
Map.contains(TrueValue) &&
"No True Value!");
4472 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4473 auto *FalseValue = CurrentSelect->getFalseValue();
4474 assert(
Map.contains(FalseValue) &&
"No False Value!");
4475 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4482 assert(
Map.contains(PV) &&
"No predecessor Value!");
4483 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4494 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4495 SmallVectorImpl<Value *> &TraverseOrder,
4496 SimplificationTracker &ST) {
4499 "Address must be a Phi or Select node");
4502 while (!Worklist.
empty()) {
4505 if (
Map.contains(Current))
4516 CurrentSelect->getName(),
4517 CurrentSelect->getIterator(), CurrentSelect);
4521 Worklist.
push_back(CurrentSelect->getTrueValue());
4522 Worklist.
push_back(CurrentSelect->getFalseValue());
4530 ST.insertNewPhi(
PHI);
4536 bool addrModeCombiningAllowed() {
4539 switch (DifferentField) {
4542 case ExtAddrMode::BaseRegField:
4544 case ExtAddrMode::BaseGVField:
4546 case ExtAddrMode::BaseOffsField:
4548 case ExtAddrMode::ScaledRegField:
4558bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4563 return matchAddr(ScaleReg,
Depth);
4574 ExtAddrMode TestAddrMode =
AddrMode;
4578 TestAddrMode.
Scale += Scale;
4592 ConstantInt *CI =
nullptr;
4593 Value *AddLHS =
nullptr;
4597 TestAddrMode.InBounds =
false;
4614 auto GetConstantStep =
4615 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4618 return std::nullopt;
4621 return std::nullopt;
4629 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4630 return std::nullopt;
4632 return std::make_pair(IVInc->first, ConstantStep->getValue());
4633 return std::nullopt;
4648 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4655 APInt Step = IVStep->second;
4657 if (
Offset.isSignedIntN(64)) {
4658 TestAddrMode.InBounds =
false;
4660 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4665 getDTFn().
dominates(IVInc, MemoryInst)) {
4685 switch (
I->getOpcode()) {
4686 case Instruction::BitCast:
4687 case Instruction::AddrSpaceCast:
4689 if (
I->getType() ==
I->getOperand(0)->getType())
4691 return I->getType()->isIntOrPtrTy();
4692 case Instruction::PtrToInt:
4695 case Instruction::IntToPtr:
4698 case Instruction::Add:
4700 case Instruction::Mul:
4701 case Instruction::Shl:
4704 case Instruction::GetElementPtr:
4732class TypePromotionHelper {
4735 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4736 Instruction *ExtOpnd,
bool IsSExt) {
4737 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4738 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4742 if (It->second.getInt() == ExtTy)
4748 ExtTy = BothExtension;
4750 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4757 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4758 Instruction *Opnd,
bool IsSExt) {
4759 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4760 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4761 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4762 return It->second.getPointer();
4777 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4778 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4782 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4795 static Value *promoteOperandForTruncAndAnyExt(
4796 Instruction *Ext, TypePromotionTransaction &TPT,
4797 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4798 SmallVectorImpl<Instruction *> *Exts,
4799 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4810 static Value *promoteOperandForOther(Instruction *Ext,
4811 TypePromotionTransaction &TPT,
4812 InstrToOrigTy &PromotedInsts,
4813 unsigned &CreatedInstsCost,
4814 SmallVectorImpl<Instruction *> *Exts,
4815 SmallVectorImpl<Instruction *> *Truncs,
4816 const TargetLowering &TLI,
bool IsSExt);
4819 static Value *signExtendOperandForOther(
4820 Instruction *Ext, TypePromotionTransaction &TPT,
4821 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4822 SmallVectorImpl<Instruction *> *Exts,
4823 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4824 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4825 Exts, Truncs, TLI,
true);
4829 static Value *zeroExtendOperandForOther(
4830 Instruction *Ext, TypePromotionTransaction &TPT,
4831 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4832 SmallVectorImpl<Instruction *> *Exts,
4833 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4834 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4835 Exts, Truncs, TLI,
false);
4840 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4841 InstrToOrigTy &PromotedInsts,
4842 unsigned &CreatedInstsCost,
4843 SmallVectorImpl<Instruction *> *Exts,
4844 SmallVectorImpl<Instruction *> *Truncs,
4845 const TargetLowering &TLI);
4856 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4857 const TargetLowering &TLI,
4858 const InstrToOrigTy &PromotedInsts);
4863bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4864 Type *ConsideredExtType,
4865 const InstrToOrigTy &PromotedInsts,
4885 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4886 (IsSExt && BinOp->hasNoSignedWrap())))
4890 if ((Inst->
getOpcode() == Instruction::And ||
4895 if (Inst->
getOpcode() == Instruction::Xor) {
4898 if (!Cst->getValue().isAllOnes())
4907 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4917 if (ExtInst->hasOneUse()) {
4919 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4952 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4965TypePromotionHelper::Action TypePromotionHelper::getAction(
4966 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4967 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
4969 "Unexpected instruction type");
4976 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4989 return promoteOperandForTruncAndAnyExt;
4995 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4998Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4999 Instruction *SExt, TypePromotionTransaction &TPT,
5000 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5001 SmallVectorImpl<Instruction *> *Exts,
5002 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
5006 Value *ExtVal = SExt;
5007 bool HasMergedNonFreeExt =
false;
5011 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
5014 TPT.replaceAllUsesWith(SExt, ZExt);
5015 TPT.eraseInstruction(SExt);
5020 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
5022 CreatedInstsCost = 0;
5026 TPT.eraseInstruction(SExtOpnd);
5034 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
5042 TPT.eraseInstruction(ExtInst, NextVal);
5046Value *TypePromotionHelper::promoteOperandForOther(
5047 Instruction *Ext, TypePromotionTransaction &TPT,
5048 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5049 SmallVectorImpl<Instruction *> *Exts,
5050 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
5055 CreatedInstsCost = 0;
5061 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
5064 ITrunc->moveAfter(ExtOpnd);
5069 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
5072 TPT.setOperand(Ext, 0, ExtOpnd);
5082 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
5084 TPT.mutateType(ExtOpnd, Ext->
getType());
5086 TPT.replaceAllUsesWith(Ext, ExtOpnd);
5093 !shouldExtOperand(ExtOpnd,
OpIdx)) {
5102 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
5104 TPT.setOperand(ExtOpnd,
OpIdx, ConstantInt::get(Ext->
getType(), CstVal));
5115 Value *ValForExtOpnd = IsSExt
5116 ? TPT.createSExt(ExtOpnd, Opnd, Ext->
getType())
5117 : TPT.createZExt(ExtOpnd, Opnd, Ext->
getType());
5118 TPT.setOperand(ExtOpnd,
OpIdx, ValForExtOpnd);
5120 if (!InstForExtOpnd)
5126 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5129 TPT.eraseInstruction(Ext);
5141bool AddressingModeMatcher::isPromotionProfitable(
5142 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5143 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5148 if (NewCost > OldCost)
5150 if (NewCost < OldCost)
5169bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5181 case Instruction::PtrToInt:
5184 case Instruction::IntToPtr: {
5192 case Instruction::BitCast:
5202 case Instruction::AddrSpaceCast: {
5210 case Instruction::Add: {
5213 ExtAddrMode BackupAddrMode =
AddrMode;
5214 unsigned OldSize = AddrModeInsts.
size();
5219 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5220 TPT.getRestorationPoint();
5224 int First = 0, Second = 1;
5235 AddrModeInsts.
resize(OldSize);
5236 TPT.rollback(LastKnownGood);
5246 AddrModeInsts.
resize(OldSize);
5247 TPT.rollback(LastKnownGood);
5253 case Instruction::Mul:
5254 case Instruction::Shl: {
5258 if (!
RHS ||
RHS->getBitWidth() > 64)
5260 int64_t Scale = Opcode == Instruction::Shl
5261 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5262 :
RHS->getSExtValue();
5266 case Instruction::GetElementPtr: {
5269 int VariableOperand = -1;
5270 unsigned VariableScale = 0;
5272 int64_t ConstantOffset = 0;
5274 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5276 const StructLayout *SL =
DL.getStructLayout(STy);
5287 if (ConstantInt *CI =
5289 const APInt &CVal = CI->
getValue();
5296 if (VariableOperand != -1)
5300 VariableOperand = i;
5301 VariableScale = TypeSize;
5308 if (VariableOperand == -1) {
5309 AddrMode.BaseOffs += ConstantOffset;
5315 AddrMode.BaseOffs -= ConstantOffset;
5319 ConstantOffset > 0) {
5332 BasicBlock *Parent = BaseI ? BaseI->getParent()
5333 : &
GEP->getFunction()->getEntryBlock();
5335 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5343 ExtAddrMode BackupAddrMode =
AddrMode;
5344 unsigned OldSize = AddrModeInsts.
size();
5347 AddrMode.BaseOffs += ConstantOffset;
5356 AddrModeInsts.
resize(OldSize);
5364 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5369 AddrModeInsts.
resize(OldSize);
5374 AddrMode.BaseOffs += ConstantOffset;
5375 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5376 VariableScale,
Depth)) {
5379 AddrModeInsts.
resize(OldSize);
5386 case Instruction::SExt:
5387 case Instruction::ZExt: {
5394 TypePromotionHelper::Action TPH =
5395 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5399 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5400 TPT.getRestorationPoint();
5401 unsigned CreatedInstsCost = 0;
5403 Value *PromotedOperand =
5404 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5419 assert(PromotedOperand &&
5420 "TypePromotionHelper should have filtered out those cases");
5422 ExtAddrMode BackupAddrMode =
AddrMode;
5423 unsigned OldSize = AddrModeInsts.
size();
5425 if (!matchAddr(PromotedOperand,
Depth) ||
5430 !isPromotionProfitable(CreatedInstsCost,
5431 ExtCost + (AddrModeInsts.
size() - OldSize),
5434 AddrModeInsts.
resize(OldSize);
5435 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5436 TPT.rollback(LastKnownGood);
5441 AddrMode.replaceWith(Ext, PromotedOperand);
5444 case Instruction::Call:
5446 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5462bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5465 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5466 TPT.getRestorationPoint();
5490 ExtAddrMode BackupAddrMode =
AddrMode;
5491 unsigned OldSize = AddrModeInsts.
size();
5494 bool MovedAway =
false;
5495 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5503 if (
I->hasOneUse() ||
5504 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5511 AddrModeInsts.
resize(OldSize);
5512 TPT.rollback(LastKnownGood);
5515 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5517 TPT.rollback(LastKnownGood);
5544 TPT.rollback(LastKnownGood);
5563 if (OpInfo.CallOperandVal == OpVal &&
5565 !OpInfo.isIndirect))
5581 if (!ConsideredInsts.
insert(
I).second)
5589 for (
Use &U :
I->uses()) {
5597 MemoryUses.push_back({&U, LI->getType()});
5604 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5611 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5618 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5628 if (!
find(PtrOps, U.get()))
5631 MemoryUses.push_back({&U, AccessTy});
5636 if (CI->hasFnAttr(Attribute::Cold)) {
5654 PSI, BFI, SeenInsts))
5665 unsigned SeenInsts = 0;
5668 PSI, BFI, SeenInsts);
5676bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5678 Value *KnownLive2) {
5680 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5721bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5722 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5723 if (IgnoreProfitability)
5741 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5742 ScaledReg =
nullptr;
5746 if (!BaseReg && !ScaledReg)
5767 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5770 Type *AddressAccessTy = Pair.second;
5771 unsigned AS =
Address->getType()->getPointerAddressSpace();
5777 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5779 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5780 TPT.getRestorationPoint();
5781 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5782 AddressAccessTy, AS, UserI, Result,
5783 InsertedInsts, PromotedInsts, TPT,
5784 LargeOffsetGEP, OptSize, PSI, BFI);
5785 Matcher.IgnoreProfitability =
true;
5793 TPT.rollback(LastKnownGood);
5799 MatchedAddrModeInsts.
clear();
5809 return I->getParent() != BB;
5825 return std::next(AddrInst->getIterator());
5836 Earliest = UserInst;
5861bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5862 Type *AccessTy,
unsigned AddrSpace) {
5867 SmallVector<Value *, 8> worklist;
5868 SmallPtrSet<Value *, 16> Visited;
5874 bool PhiOrSelectSeen =
false;
5875 SmallVector<Instruction *, 16> AddrModeInsts;
5876 AddressingModeCombiner AddrModes(*
DL, Addr);
5877 TypePromotionTransaction TPT(RemovedInsts);
5878 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5879 TPT.getRestorationPoint();
5880 while (!worklist.
empty()) {
5892 if (!Visited.
insert(V).second)
5898 PhiOrSelectSeen =
true;
5905 PhiOrSelectSeen =
true;
5912 AddrModeInsts.
clear();
5913 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5918 auto getDTFn = [
this]() ->
const DominatorTree & {
return getDT(); };
5919 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5920 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5921 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5924 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5929 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5930 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5933 NewAddrMode.OriginalValue =
V;
5934 if (!AddrModes.addNewAddrMode(NewAddrMode))
5941 if (!AddrModes.combineAddrModes()) {
5942 TPT.rollback(LastKnownGood);
5948 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5954 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5968 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
5990 <<
" for " << *MemoryInst <<
"\n");
5994 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6000 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
6002 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6004 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6011 <<
" for " << *MemoryInst <<
"\n");
6012 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
6023 if (ResultPtr ||
AddrMode.Scale != 1)
6044 GlobalValue *BaseGV =
AddrMode.BaseGV;
6045 if (BaseGV !=
nullptr) {
6050 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
6059 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
6060 if (!ResultPtr &&
AddrMode.BaseReg) {
6064 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
6065 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
6074 }
else if (!ResultPtr) {
6088 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
6101 "We can't transform if ScaledReg is too narrow");
6102 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
6106 V = Builder.CreateMul(
6109 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6120 if (ResultPtr->
getType() != I8PtrTy)
6121 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6122 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6135 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6137 SunkAddr = ResultPtr;
6139 if (ResultPtr->
getType() != I8PtrTy)
6140 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6141 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6148 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6154 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
6156 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6158 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6168 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6169 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6170 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6172 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6176 <<
" for " << *MemoryInst <<
"\n");
6187 if (
V->getType()->isPointerTy())
6188 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6190 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
6199 }
else if (
V->getType()->isPointerTy()) {
6200 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6203 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
6212 I->eraseFromParent();
6216 V = Builder.CreateMul(
6219 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6225 GlobalValue *BaseGV =
AddrMode.BaseGV;
6226 if (BaseGV !=
nullptr) {
6229 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6233 Value *
V = Builder.CreatePtrToInt(BaseGVPtr,
IntPtrTy,
"sunkaddr");
6235 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6244 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6252 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6258 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6263 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6264 RecursivelyDeleteTriviallyDeadInstructions(
6265 Repl, TLInfo, nullptr,
6266 [&](Value *V) { removeAllAssertingVHReferences(V); });
6290bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6296 if (!
GEP->hasIndices())
6304 SmallVector<Value *, 2>
Ops(
GEP->operands());
6306 bool RewriteGEP =
false;
6315 unsigned FinalIndex =
Ops.size() - 1;
6320 for (
unsigned i = 1; i < FinalIndex; ++i) {
6325 C =
C->getSplatValue();
6327 if (!CI || !CI->
isZero())
6334 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6338 if (!
C || !
C->isZero()) {
6339 Ops[FinalIndex] =
V;
6347 if (!RewriteGEP &&
Ops.size() == 2)
6354 Type *SourceTy =
GEP->getSourceElementType();
6355 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6359 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6360 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6361 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6371 if (
Ops.size() != 2) {
6381 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6395 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6396 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6399 Intrinsic::masked_gather) {
6403 Intrinsic::masked_scatter);
6418 Ptr, TLInfo,
nullptr,
6419 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6430 if (
I->hasNUsesOrMore(3))
6433 for (
User *U :
I->users()) {
6435 if (!Extract || Extract->getNumIndices() != 1)
6438 unsigned Index = Extract->getIndices()[0];
6440 MulExtract = Extract;
6441 else if (Index == 1)
6442 OverflowExtract = Extract;
6469bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
6470 ModifyDT &ModifiedDT) {
6477 ExtractValueInst *MulExtract =
nullptr, *OverflowExtract =
nullptr;
6482 InsertedInsts.insert(
I);
6493 OverflowEntryBB->
takeName(
I->getParent());
6499 NoOverflowBB->
moveAfter(OverflowEntryBB);
6507 Value *LoLHS = Builder.CreateTrunc(
LHS, LegalTy,
"lo.lhs");
6508 Value *HiLHS = Builder.CreateLShr(
LHS, VTHalfBitWidth,
"lhs.lsr");
6509 HiLHS = Builder.CreateTrunc(HiLHS, LegalTy,
"hi.lhs");
6512 Value *LoRHS = Builder.CreateTrunc(
RHS, LegalTy,
"lo.rhs");
6513 Value *HiRHS = Builder.CreateLShr(
RHS, VTHalfBitWidth,
"rhs.lsr");
6514 HiRHS = Builder.CreateTrunc(HiRHS, LegalTy,
"hi.rhs");
6516 Value *IsAnyBitTrue;
6519 Builder.CreateAShr(LoLHS, VTHalfBitWidth - 1,
"sign.lo.lhs");
6521 Builder.CreateAShr(LoRHS, VTHalfBitWidth - 1,
"sign.lo.rhs");
6522 Value *XorLHS = Builder.CreateXor(HiLHS, SignLoLHS);
6523 Value *XorRHS = Builder.CreateXor(HiRHS, SignLoRHS);
6524 Value *
Or = Builder.CreateOr(XorLHS, XorRHS,
"or.lhs.rhs");
6525 IsAnyBitTrue = Builder.CreateCmp(ICmpInst::ICMP_NE,
Or,
6526 ConstantInt::getNullValue(
Or->getType()));
6528 Value *CmpLHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiLHS,
6529 ConstantInt::getNullValue(LegalTy));
6530 Value *CmpRHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiRHS,
6531 ConstantInt::getNullValue(LegalTy));
6532 IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS,
"or.lhs.rhs");
6534 Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
6537 Builder.SetInsertPoint(NoOverflowBB);
6538 Value *ExtLoLHS, *ExtLoRHS;
6540 ExtLoLHS = Builder.CreateSExt(LoLHS, Ty,
"lo.lhs.ext");
6541 ExtLoRHS = Builder.CreateSExt(LoRHS, Ty,
"lo.rhs.ext");
6543 ExtLoLHS = Builder.CreateZExt(LoLHS, Ty,
"lo.lhs.ext");
6544 ExtLoRHS = Builder.CreateZExt(LoRHS, Ty,
"lo.rhs.ext");
6547 Value *
Mul = Builder.CreateMul(ExtLoLHS, ExtLoRHS,
"mul.overflow.no");
6552 OverflowResBB->
setName(
"overflow.res");
6555 Builder.CreateBr(OverflowResBB);
6563 PHINode *OverflowResPHI = Builder.CreatePHI(Ty, 2),
6565 Builder.CreatePHI(IntegerType::getInt1Ty(
I->getContext()), 2);
6577 if (OverflowExtract) {
6578 OverflowExtract->replaceAllUsesWith(OverflowFlagPHI);
6579 OverflowExtract->eraseFromParent();
6584 I->removeFromParent();
6586 I->insertInto(OverflowBB, OverflowBB->
end());
6587 Builder.SetInsertPoint(OverflowBB, OverflowBB->
end());
6589 Value *OverflowFlag = Builder.CreateExtractValue(
I, {1},
"overflow.flag");
6590 Builder.CreateBr(OverflowResBB);
6594 OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
6596 DTU->
applyUpdates({{DominatorTree::Insert, OverflowEntryBB, OverflowBB},
6597 {DominatorTree::Insert, OverflowEntryBB, NoOverflowBB},
6598 {DominatorTree::Insert, NoOverflowBB, OverflowResBB},
6599 {DominatorTree::Delete, OverflowEntryBB, OverflowResBB},
6600 {DominatorTree::Insert, OverflowBB, OverflowResBB}});
6602 ModifiedDT = ModifyDT::ModifyBBDT;
6608bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6609 bool MadeChange =
false;
6611 const TargetRegisterInfo *
TRI =
6616 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6622 OpInfo.isIndirect) {
6624 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6687bool CodeGenPrepare::tryToPromoteExts(
6688 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6689 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6690 unsigned CreatedInstsCost) {
6691 bool Promoted =
false;
6694 for (
auto *
I : Exts) {
6709 TypePromotionHelper::Action TPH =
6710 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6719 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6720 TPT.getRestorationPoint();
6721 SmallVector<Instruction *, 4> NewExts;
6722 unsigned NewCreatedInstsCost = 0;
6725 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6726 &NewExts,
nullptr, *TLI);
6728 "TypePromotionHelper should have filtered out those cases");
6738 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6741 TotalCreatedInstsCost =
6742 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6744 (TotalCreatedInstsCost > 1 ||
6746 (ExtCost == 0 && NewExts.
size() > 1))) {
6750 TPT.rollback(LastKnownGood);
6755 SmallVector<Instruction *, 2> NewlyMovedExts;
6756 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6757 bool NewPromoted =
false;
6758 for (
auto *ExtInst : NewlyMovedExts) {
6768 ProfitablyMovedExts.
push_back(MovedExt);
6775 TPT.rollback(LastKnownGood);
6786bool CodeGenPrepare::mergeSExts(Function &
F) {
6788 for (
auto &Entry : ValToSExtendedUses) {
6789 SExts &Insts =
Entry.second;
6791 for (Instruction *Inst : Insts) {
6795 bool inserted =
false;
6796 for (
auto &Pt : CurPts) {
6799 RemovedInsts.insert(Pt);
6800 Pt->removeFromParent();
6811 RemovedInsts.insert(Inst);
6818 CurPts.push_back(Inst);
6860bool CodeGenPrepare::splitLargeGEPOffsets() {
6862 for (
auto &Entry : LargeOffsetGEPMap) {
6864 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6865 &LargeOffsetGEPs =
Entry.second;
6866 auto compareGEPOffset =
6867 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6868 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6869 if (
LHS.first ==
RHS.first)
6871 if (
LHS.second !=
RHS.second)
6872 return LHS.second <
RHS.second;
6873 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6876 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6879 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6881 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6882 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6883 Value *NewBaseGEP =
nullptr;
6885 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6886 GetElementPtrInst *
GEP) {
6887 LLVMContext &Ctx =
GEP->getContext();
6888 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6890 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6902 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), &getDT(), LI);
6905 NewBaseInsertPt = std::next(BaseI->getIterator());
6912 IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
6918 NewBaseGEP = OldBase;
6919 if (NewBaseGEP->
getType() != I8PtrTy)
6920 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6922 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6923 NewGEPBases.
insert(NewBaseGEP);
6929 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6930 BaseOffset = PreferBase;
6933 createNewBase(BaseOffset, OldBase, BaseGEP);
6936 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6937 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6938 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6939 int64_t
Offset = LargeOffsetGEP->second;
6940 if (
Offset != BaseOffset) {
6947 GEP->getResultElementType(),
6948 GEP->getAddressSpace())) {
6954 NewBaseGEP =
nullptr;
6959 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6964 createNewBase(BaseOffset, OldBase,
GEP);
6968 Value *NewGEP = NewBaseGEP;
6969 if (
Offset != BaseOffset) {
6972 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6976 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6977 GEP->eraseFromParent();
6984bool CodeGenPrepare::optimizePhiType(
6985 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
6986 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
6991 Type *PhiTy =
I->getType();
6992 Type *ConvertTy =
nullptr;
6994 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6997 SmallVector<Instruction *, 4> Worklist;
6999 SmallPtrSet<PHINode *, 4> PhiNodes;
7000 SmallPtrSet<ConstantData *, 4>
Constants;
7003 SmallPtrSet<Instruction *, 4> Defs;
7004 SmallPtrSet<Instruction *, 4>
Uses;
7010 bool AnyAnchored =
false;
7012 while (!Worklist.
empty()) {
7017 for (
Value *V :
Phi->incoming_values()) {
7019 if (!PhiNodes.
count(OpPhi)) {
7020 if (!Visited.
insert(OpPhi).second)
7026 if (!OpLoad->isSimple())
7028 if (Defs.
insert(OpLoad).second)
7031 if (Defs.
insert(OpEx).second)
7035 ConvertTy = OpBC->getOperand(0)->getType();
7036 if (OpBC->getOperand(0)->getType() != ConvertTy)
7038 if (Defs.
insert(OpBC).second) {
7051 for (User *V :
II->users()) {
7053 if (!PhiNodes.
count(OpPhi)) {
7054 if (Visited.
count(OpPhi))
7061 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
7063 Uses.insert(OpStore);
7066 ConvertTy = OpBC->getType();
7067 if (OpBC->getType() != ConvertTy)
7071 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
7078 if (!ConvertTy || !AnyAnchored || PhiTy == ConvertTy ||
7082 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
7083 << *ConvertTy <<
"\n");
7088 for (ConstantData *
C : Constants)
7090 for (Instruction *
D : Defs) {
7092 ValMap[
D] =
D->getOperand(0);
7096 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
7099 for (PHINode *Phi : PhiNodes)
7101 Phi->getName() +
".tc",
Phi->getIterator());
7103 for (PHINode *Phi : PhiNodes) {
7105 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
7107 Phi->getIncomingBlock(i));
7111 for (Instruction *U :
Uses) {
7116 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
7126bool CodeGenPrepare::optimizePhiTypes(Function &
F) {
7131 SmallPtrSet<PHINode *, 4> Visited;
7132 SmallPtrSet<Instruction *, 4> DeletedInstrs;
7136 for (
auto &Phi : BB.
phis())
7137 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
7140 for (
auto *
I : DeletedInstrs) {
7142 I->eraseFromParent();
7150bool CodeGenPrepare::canFormExtLd(
7151 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
7152 Instruction *&Inst,
bool HasPromoted) {
7153 for (
auto *MovedExtInst : MovedExts) {
7156 Inst = MovedExtInst;
7208bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7209 bool AllowPromotionWithoutCommonHeader =
false;
7214 *Inst, AllowPromotionWithoutCommonHeader);
7215 TypePromotionTransaction TPT(RemovedInsts);
7216 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7217 TPT.getRestorationPoint();
7219 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7222 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7225 LoadInst *LI =
nullptr;
7230 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7231 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7236 Inst = ExtFedByLoad;
7241 if (ATPConsiderable &&
7242 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7243 HasPromoted, TPT, SpeculativelyMovedExts))
7246 TPT.rollback(LastKnownGood);
7255bool CodeGenPrepare::performAddressTypePromotion(
7256 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7257 bool HasPromoted, TypePromotionTransaction &TPT,
7258 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7259 bool Promoted =
false;
7260 SmallPtrSet<Instruction *, 1> UnhandledExts;
7261 bool AllSeenFirst =
true;
7262 for (
auto *
I : SpeculativelyMovedExts) {
7263 Value *HeadOfChain =
I->getOperand(0);
7264 auto AlreadySeen = SeenChainsForSExt.
find(HeadOfChain);
7267 if (AlreadySeen != SeenChainsForSExt.
end()) {
7268 if (AlreadySeen->second !=
nullptr)
7269 UnhandledExts.
insert(AlreadySeen->second);
7270 AllSeenFirst =
false;
7274 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7275 SpeculativelyMovedExts.size() == 1)) {
7279 for (
auto *
I : SpeculativelyMovedExts) {
7280 Value *HeadOfChain =
I->getOperand(0);
7281 SeenChainsForSExt[HeadOfChain] =
nullptr;
7282 ValToSExtendedUses[HeadOfChain].push_back(
I);
7285 Inst = SpeculativelyMovedExts.pop_back_val();
7290 for (
auto *
I : SpeculativelyMovedExts) {
7291 Value *HeadOfChain =
I->getOperand(0);
7292 SeenChainsForSExt[HeadOfChain] = Inst;
7297 if (!AllSeenFirst && !UnhandledExts.
empty())
7298 for (
auto *VisitedSExt : UnhandledExts) {
7299 if (RemovedInsts.count(VisitedSExt))
7301 TypePromotionTransaction TPT(RemovedInsts);
7303 SmallVector<Instruction *, 2> Chains;
7305 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7309 for (
auto *
I : Chains) {
7310 Value *HeadOfChain =
I->getOperand(0);
7312 SeenChainsForSExt[HeadOfChain] =
nullptr;
7313 ValToSExtendedUses[HeadOfChain].push_back(
I);
7319bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7324 Value *Src =
I->getOperand(0);
7325 if (Src->hasOneUse())
7337 bool DefIsLiveOut =
false;
7338 for (User *U :
I->users()) {
7343 if (UserBB == DefBB)
7345 DefIsLiveOut =
true;
7352 for (User *U : Src->users()) {
7355 if (UserBB == DefBB)
7364 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7366 bool MadeChange =
false;
7367 for (Use &U : Src->uses()) {
7372 if (UserBB == DefBB)
7376 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7378 if (!InsertedTrunc) {
7381 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7383 InsertedInsts.insert(InsertedTrunc);
7446bool CodeGenPrepare::optimizeLoadExt(LoadInst *
Load) {
7447 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7451 if (
Load->hasOneUse() &&
7457 SmallVector<Instruction *, 8> WorkList;
7458 SmallPtrSet<Instruction *, 16> Visited;
7459 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7460 SmallVector<Instruction *, 8> DropFlags;
7461 for (
auto *U :
Load->users())
7473 while (!WorkList.
empty()) {
7477 if (!Visited.
insert(
I).second)
7482 for (
auto *U :
Phi->users())
7487 switch (
I->getOpcode()) {
7488 case Instruction::And: {
7492 APInt AndBits = AndC->getValue();
7493 DemandBits |= AndBits;
7495 if (AndBits.
ugt(WidestAndBits))
7496 WidestAndBits = AndBits;
7497 if (AndBits == WidestAndBits &&
I->getOperand(0) ==
Load)
7502 case Instruction::Shl: {
7506 uint64_t ShiftAmt = ShlC->getLimitedValue(
BitWidth - 1);
7507 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7512 case Instruction::Trunc: {
7515 DemandBits.setLowBits(TruncBitWidth);
7525 uint32_t ActiveBits = DemandBits.getActiveBits();
7537 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7538 WidestAndBits != DemandBits)
7541 LLVMContext &Ctx =
Load->getType()->getContext();
7542 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7553 Builder.CreateAnd(
Load, ConstantInt::get(Ctx, DemandBits)));
7556 InsertedInsts.insert(NewAnd);
7561 NewAnd->setOperand(0,
Load);
7564 for (
auto *
And : AndsToMaybeRemove)
7569 if (&*CurInstIterator ==
And)
7570 CurInstIterator = std::next(
And->getIterator());
7571 And->eraseFromParent();
7576 for (
auto *Inst : DropFlags)
7590 TTI->isExpensiveToSpeculativelyExecute(
I);
7608 uint64_t Max = std::max(TrueWeight, FalseWeight);
7609 uint64_t Sum = TrueWeight + FalseWeight;
7612 if (Probability >
TTI->getPredictableBranchThreshold())
7622 if (!Cmp || !Cmp->hasOneUse())
7645 assert(DefSI->getCondition() ==
SI->getCondition() &&
7646 "The condition of DefSI does not match with SI");
7647 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7650 assert(V &&
"Failed to get select true/false value");
7654bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7678 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7679 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7680 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7681 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7687bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7689 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7690 "Expected a funnel shift");
7714 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7715 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7716 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7724bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7736 It !=
SI->getParent()->
end(); ++It) {
7738 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7745 SelectInst *LastSI = ASI.
back();
7748 CurInstIterator = std::next(LastSI->
getIterator());
7752 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7753 fixupDbgVariableRecordsOnInst(*SI);
7755 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7758 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7761 TargetLowering::SelectSupportKind SelectKind;
7762 if (
SI->getType()->isVectorTy())
7763 SelectKind = TargetLowering::ScalarCondVectorVal;
7765 SelectKind = TargetLowering::ScalarValSelect;
7802 SmallVector<Instruction *> TrueInstrs, FalseInstrs;
7803 for (SelectInst *SI : ASI) {
7815 SplitPt.setHeadBit(
true);
7818 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7823 UncondBrInst *TrueBranch =
nullptr;
7824 UncondBrInst *FalseBranch =
nullptr;
7825 if (TrueInstrs.
size() == 0) {
7828 FalseBlock = FalseBranch->getParent();
7830 }
else if (FalseInstrs.
size() == 0) {
7833 TrueBlock = TrueBranch->getParent();
7842 TrueBlock = TrueBranch->getParent();
7843 FalseBlock = FalseBranch->getParent();
7847 EndBlock->
setName(
"select.end");
7849 TrueBlock->
setName(
"select.true.sink");
7851 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7852 :
"select.false.sink");
7856 FreshBBs.
insert(TrueBlock);
7858 FreshBBs.
insert(FalseBlock);
7859 FreshBBs.
insert(EndBlock);
7864 static const unsigned MD[] = {
7865 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7866 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7871 for (Instruction *
I : TrueInstrs)
7872 I->moveBefore(TrueBranch->getIterator());
7873 for (Instruction *
I : FalseInstrs)
7874 I->moveBefore(FalseBranch->getIterator());
7880 if (TrueBlock ==
nullptr)
7881 TrueBlock = StartBlock;
7882 else if (FalseBlock ==
nullptr)
7883 FalseBlock = StartBlock;
7899 SI->eraseFromParent();
7901 ++NumSelectsExpanded;
7905 CurInstIterator = StartBlock->
end();
7912bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7924 "Expected a type of the same size!");
7930 Builder.SetInsertPoint(SVI);
7931 Value *BC1 = Builder.CreateBitCast(
7933 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7934 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7938 SVI, TLInfo,
nullptr,
7939 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7946 !
Op->isTerminator() && !
Op->isEHPad())
7952bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7967 for (Use *U :
reverse(OpsToSink)) {
7979 SetVector<Instruction *> MaybeDead;
7980 DenseMap<Instruction *, Instruction *> NewInstructions;
7981 for (Use *U : ToReplace) {
7990 FreshBBs.
insert(OpDef->getParent());
7993 NewInstructions[UI] = NI;
7998 InsertedInsts.insert(NI);
8004 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
8005 It->second->setOperand(
U->getOperandNo(), NI);
8012 for (
auto *
I : MaybeDead) {
8013 if (!
I->hasNUsesOrMore(1)) {
8015 I->eraseFromParent();
8022bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
8028 unsigned RegWidth =
RegType.getSizeInBits();
8039 auto *NewType = Type::getIntNTy(
Context, RegWidth);
8048 ExtType = Instruction::SExt;
8051 if (Arg->hasSExtAttr())
8052 ExtType = Instruction::SExt;
8053 if (Arg->hasZExtAttr())
8054 ExtType = Instruction::ZExt;
8060 SI->setCondition(ExtInst);
8061 for (
auto Case :
SI->cases()) {
8062 const APInt &NarrowConst = Case.getCaseValue()->getValue();
8063 APInt WideConst = (ExtType == Instruction::ZExt)
8064 ? NarrowConst.
zext(RegWidth)
8065 : NarrowConst.
sext(RegWidth);
8066 Case.setValue(ConstantInt::get(
Context, WideConst));
8072bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
8079 Value *Condition =
SI->getCondition();
8088 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
8089 ConstantInt *CaseValue = Case.getCaseValue();
8090 BasicBlock *CaseBB = Case.getCaseSuccessor();
8093 bool CheckedForSinglePred =
false;
8094 for (PHINode &
PHI : CaseBB->
phis()) {
8095 Type *PHIType =
PHI.getType();
8103 if (PHIType == ConditionType || TryZExt) {
8105 bool SkipCase =
false;
8106 Value *Replacement =
nullptr;
8107 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
8108 Value *PHIValue =
PHI.getIncomingValue(
I);
8109 if (PHIValue != CaseValue) {
8118 if (
PHI.getIncomingBlock(
I) != SwitchBB)
8123 if (!CheckedForSinglePred) {
8124 CheckedForSinglePred =
true;
8125 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
8131 if (Replacement ==
nullptr) {
8132 if (PHIValue == CaseValue) {
8133 Replacement = Condition;
8136 Replacement = Builder.CreateZExt(Condition, PHIType);
8139 PHI.setIncomingValue(
I, Replacement);
8150bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
8151 bool Changed = optimizeSwitchType(SI);
8152 Changed |= optimizeSwitchPhiConstants(SI);
8173class VectorPromoteHelper {
8175 const DataLayout &
DL;
8178 const TargetLowering &TLI;
8181 const TargetTransformInfo &
TTI;
8187 SmallVector<Instruction *, 4> InstsToBePromoted;
8190 unsigned StoreExtractCombineCost;
8199 if (InstsToBePromoted.
empty())
8201 return InstsToBePromoted.
back();
8207 unsigned getTransitionOriginalValueIdx()
const {
8209 "Other kind of transitions are not supported yet");
8216 unsigned getTransitionIdx()
const {
8218 "Other kind of transitions are not supported yet");
8226 Type *getTransitionType()
const {
8237 void promoteImpl(Instruction *ToBePromoted);
8241 bool isProfitableToPromote() {
8242 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8246 Type *PromotedType = getTransitionType();
8249 unsigned AS =
ST->getPointerAddressSpace();
8267 for (
const auto &Inst : InstsToBePromoted) {
8275 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8287 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8288 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8289 return ScalarCost > VectorCost;
8301 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8316 if (!
EC.isScalable()) {
8317 SmallVector<Constant *, 4> ConstVec;
8319 for (
unsigned Idx = 0; Idx !=
EC.getKnownMinValue(); ++Idx) {
8320 if (Idx == ExtractIdx)
8328 "Generate scalable vector for non-splat is unimplemented");
8333 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8334 unsigned OperandIdx) {
8337 if (OperandIdx != 1)
8339 switch (
Use->getOpcode()) {
8342 case Instruction::SDiv:
8343 case Instruction::UDiv:
8344 case Instruction::SRem:
8345 case Instruction::URem:
8347 case Instruction::FDiv:
8348 case Instruction::FRem:
8349 return !
Use->hasNoNaNs();
8355 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8356 const TargetTransformInfo &
TTI, Instruction *Transition,
8357 unsigned CombineCost)
8358 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8359 StoreExtractCombineCost(CombineCost) {
8360 assert(Transition &&
"Do not know how to promote null");
8364 bool canPromote(
const Instruction *ToBePromoted)
const {
8371 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8374 for (
const Use &U : ToBePromoted->
operands()) {
8375 const Value *Val =
U.get();
8376 if (Val == getEndOfTransition()) {
8380 if (canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()))
8403 void enqueueForPromotion(Instruction *ToBePromoted) {
8404 InstsToBePromoted.push_back(ToBePromoted);
8408 void recordCombineInstruction(Instruction *ToBeCombined) {
8410 CombineInst = ToBeCombined;
8420 if (InstsToBePromoted.empty() || !CombineInst)
8428 for (
auto &ToBePromoted : InstsToBePromoted)
8429 promoteImpl(ToBePromoted);
8430 InstsToBePromoted.clear();
8437void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8447 "The type of the result of the transition does not match "
8452 Type *TransitionTy = getTransitionType();
8457 for (Use &U : ToBePromoted->
operands()) {
8459 Value *NewVal =
nullptr;
8460 if (Val == Transition)
8461 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8468 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8472 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8475 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8481bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8482 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8497 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8498 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost);
8505 if (ToBePromoted->
getParent() != Parent) {
8506 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8508 <<
") than the transition (" << Parent->
getName()
8513 if (VPH.canCombine(ToBePromoted)) {
8515 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8516 VPH.recordCombineInstruction(ToBePromoted);
8518 NumStoreExtractExposed +=
Changed;
8523 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8526 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8528 VPH.enqueueForPromotion(ToBePromoted);
8529 Inst = ToBePromoted;
8569 Type *StoreType =
SI.getValueOperand()->getType();
8578 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8579 DL.getTypeSizeInBits(StoreType) == 0)
8582 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8584 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8600 if (!
match(
SI.getValueOperand(),
8607 if (!
LValue->getType()->isIntegerTy() ||
8608 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8610 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8626 Builder.SetInsertPoint(&
SI);
8630 if (LBC && LBC->getParent() !=
SI.getParent())
8631 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8632 if (HBC && HBC->getParent() !=
SI.getParent())
8633 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8635 bool IsLE =
SI.getDataLayout().isLittleEndian();
8636 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8637 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8638 Value *Addr =
SI.getPointerOperand();
8639 Align Alignment =
SI.getAlign();
8640 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8641 if (IsOffsetStore) {
8642 Addr = Builder.CreateGEP(
8643 SplitStoreType, Addr,
8651 Builder.CreateAlignedStore(V, Addr, Alignment);
8654 CreateSplitStore(
LValue,
false);
8655 CreateSplitStore(HValue,
true);
8658 SI.eraseFromParent();
8666 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8748 if (GEPIOpI->getParent() != SrcBlock)
8753 if (auto *I = dyn_cast<Instruction>(Usr)) {
8754 if (I->getParent() != SrcBlock) {
8762 std::vector<GetElementPtrInst *> UGEPIs;
8765 for (User *Usr : GEPIOp->
users()) {
8784 if (UGEPI->getOperand(0) != GEPIOp)
8786 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8788 if (GEPIIdx->getType() !=
8796 UGEPIs.push_back(UGEPI);
8798 if (UGEPIs.size() == 0)
8801 for (GetElementPtrInst *UGEPI : UGEPIs) {
8803 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8810 for (GetElementPtrInst *UGEPI : UGEPIs) {
8811 UGEPI->setOperand(0, GEPI);
8813 auto NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8814 Constant *NewUGEPIIdx = ConstantInt::get(GEPIIdx->getType(), NewIdx);
8815 UGEPI->setOperand(1, NewUGEPIIdx);
8817 auto SourceFlags = GEPI->getNoWrapFlags();
8820 UGEPI->getNoWrapFlags().intersectForOffsetAdd(SourceFlags);
8822 if (NewIdx.
isNegative() && TargetFlags.hasNoUnsignedWrap())
8823 TargetFlags = TargetFlags.withoutNoUnsignedWrap();
8824 UGEPI->setNoWrapFlags(TargetFlags);
8830 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8832 "GEPIOp is used outside SrcBlock");
8856 Value *
X = Cmp->getOperand(0);
8857 if (!
X->hasUseList())
8862 for (
auto *U :
X->users()) {
8866 (UI->
getParent() != Branch->getParent() &&
8867 UI->
getParent() != Branch->getSuccessor(0) &&
8868 UI->
getParent() != Branch->getSuccessor(1)) ||
8869 (UI->
getParent() != Branch->getParent() &&
8870 !UI->
getParent()->getSinglePredecessor()))
8876 if (UI->
getParent() != Branch->getParent())
8880 ConstantInt::get(UI->
getType(), 0));
8882 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8886 if (Cmp->isEquality() &&
8891 if (UI->
getParent() != Branch->getParent())
8894 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8895 ConstantInt::get(UI->
getType(), 0));
8897 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8905bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8906 bool AnyChange =
false;
8907 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8911 if (InsertedInsts.count(
I))
8920 LargeOffsetGEPMap.erase(
P);
8922 P->eraseFromParent();
8945 I, LI->getLoopFor(
I->getParent()), *
TTI))
8953 TargetLowering::TypeExpandInteger) {
8957 I, LI->getLoopFor(
I->getParent()), *
TTI))
8960 bool MadeChange = optimizeExt(
I);
8961 return MadeChange | optimizeExtUses(
I);
8968 if (optimizeCmp(Cmp, ModifiedDT))
8972 if (optimizeURem(
I))
8976 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8977 bool Modified = optimizeLoadExt(LI);
8986 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8987 unsigned AS =
SI->getPointerAddressSpace();
8988 return optimizeMemoryInst(
I,
SI->getOperand(1),
8989 SI->getOperand(0)->getType(), AS);
8993 unsigned AS = RMW->getPointerAddressSpace();
8994 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
8998 unsigned AS = CmpX->getPointerAddressSpace();
8999 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
9000 CmpX->getCompareOperand()->getType(), AS);
9010 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
9011 BinOp->
getOpcode() == Instruction::LShr)) {
9019 if (GEPI->hasAllZeroIndices()) {
9021 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
9022 GEPI->getName(), GEPI->getIterator());
9023 NC->setDebugLoc(GEPI->getDebugLoc());
9026 GEPI, TLInfo,
nullptr,
9027 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9029 optimizeInst(
NC, ModifiedDT);
9052 if (Const0 || Const1) {
9053 if (!Const0 || !Const1) {
9054 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
9059 FI->eraseFromParent();
9066 if (tryToSinkFreeOperands(
I))
9069 switch (
I->getOpcode()) {
9070 case Instruction::Shl:
9071 case Instruction::LShr:
9072 case Instruction::AShr:
9074 case Instruction::Call:
9076 case Instruction::Select:
9078 case Instruction::ShuffleVector:
9080 case Instruction::Switch:
9082 case Instruction::ExtractElement:
9084 case Instruction::CondBr:
9093bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
9094 if (!
I.getType()->isIntegerTy() ||
9099 SmallVector<Instruction *, 4> Insts;
9105 &
I, TLInfo,
nullptr,
9106 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9113bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
9115 bool MadeChange =
false;
9118 CurInstIterator = BB.
begin();
9119 ModifiedDT = ModifyDT::NotModifyDT;
9120 while (CurInstIterator != BB.
end()) {
9121 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
9122 if (ModifiedDT != ModifyDT::NotModifyDT) {
9131 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
9133 bool MadeBitReverse =
true;
9134 while (MadeBitReverse) {
9135 MadeBitReverse =
false;
9137 if (makeBitReverse(
I)) {
9138 MadeBitReverse = MadeChange =
true;
9143 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
9148bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
9149 bool AnyChange =
false;
9150 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
9151 AnyChange |= fixupDbgVariableRecord(DVR);
9157bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
9158 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
9159 DVR.
Type != DbgVariableRecord::LocationType::Assign)
9163 bool AnyChange =
false;
9164 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
9166 for (
Value *Location : LocationOps) {
9167 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9196bool CodeGenPrepare::placeDbgValues(Function &
F) {
9197 bool MadeChange =
false;
9198 DominatorTree &DT = getDT();
9200 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9201 SmallVector<Instruction *, 4> VIs;
9202 for (
Value *V : DbgItem->location_ops())
9210 for (Instruction *VI : VIs) {
9211 if (
VI->isTerminator())
9216 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9227 if (VIs.size() > 1) {
9230 <<
"Unable to find valid location for Debug Value, undefing:\n"
9232 DbgItem->setKillLocation();
9237 << *DbgItem <<
' ' << *VI);
9244 for (BasicBlock &BB :
F) {
9250 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9252 DbgProcessor(&DVR, &Insn);
9263bool CodeGenPrepare::placePseudoProbes(Function &
F) {
9264 bool MadeChange =
false;
9267 auto FirstInst =
Block.getFirstInsertionPt();
9268 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9272 while (
I !=
Block.end()) {
9274 II->moveBefore(FirstInst);
9304bool CodeGenPrepare::splitBranchCondition(Function &
F) {
9308 bool MadeChange =
false;
9309 for (
auto &BB :
F) {
9322 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9330 Value *Cond1, *Cond2;
9333 Opc = Instruction::And;
9336 Opc = Instruction::Or;
9346 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9360 Br1->setCondition(Cond1);
9365 if (
Opc == Instruction::And)
9366 Br1->setSuccessor(0, TmpBB);
9368 Br1->setSuccessor(1, TmpBB);
9373 I->removeFromParent();
9374 I->insertBefore(Br2->getIterator());
9386 if (
Opc == Instruction::Or)
9393 for (PHINode &PN : FBB->
phis()) {
9398 if (Loop *L = LI->getLoopFor(&BB))
9399 L->addBasicBlockToLoop(TmpBB, *LI);
9403 DTU->
applyUpdates({{DominatorTree::Insert, &BB, TmpBB},
9404 {DominatorTree::Insert, TmpBB,
TBB},
9405 {DominatorTree::Insert, TmpBB, FBB},
9406 {DominatorTree::Delete, &BB,
TBB}});
9410 if (
Opc == Instruction::Or) {
9430 uint64_t TrueWeight, FalseWeight;
9432 uint64_t NewTrueWeight = TrueWeight;
9433 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9437 NewTrueWeight = TrueWeight;
9438 NewFalseWeight = 2 * FalseWeight;
9461 uint64_t TrueWeight, FalseWeight;
9463 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9464 uint64_t NewFalseWeight = FalseWeight;
9468 NewTrueWeight = 2 * TrueWeight;
9469 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< 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 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.
MachineInstr unsigned OpIdx
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.
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 ...
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.
bool getLibFunc(StringRef funcName, LibFunc &F) 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 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)
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.
@ C
The default llvm calling convention, compatible with C.
unsigned getAddrMode(MCInstrInfo const &MCII, MCInst const &MCI)
@ BasicBlock
Various leaf nodes.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
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.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
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 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.
LLVM_ABI bool bypassSlowDivision(BasicBlock *BB, const DenseMap< unsigned int, unsigned int > &BypassWidth, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
This optimization identifies DIV instructions in a BB that can be profitably bypassed and carried out...
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 isInteger() const
Return true if this is an integer or a vector integer type.
This contains information for each constraint that we are lowering.