45#include "llvm/Config/llvm-config.h"
66#include "llvm/IR/IntrinsicsAArch64.h"
110#define DEBUG_TYPE "codegenprepare"
113STATISTIC(NumPHIsElim,
"Number of trivial PHIs eliminated");
114STATISTIC(NumGEPsElim,
"Number of GEPs converted to casts");
115STATISTIC(NumCmpUses,
"Number of uses of Cmp expressions replaced with uses of "
117STATISTIC(NumCastUses,
"Number of uses of Cast expressions replaced with uses "
119STATISTIC(NumMemoryInsts,
"Number of memory instructions whose address "
120 "computations were sunk");
122 "Number of phis created when address "
123 "computations were sunk to memory instructions");
125 "Number of select created when address "
126 "computations were sunk to memory instructions");
127STATISTIC(NumExtsMoved,
"Number of [s|z]ext instructions combined with loads");
128STATISTIC(NumExtUses,
"Number of uses of [s|z]ext instructions optimized");
130 "Number of and mask instructions added to form ext loads");
131STATISTIC(NumAndUses,
"Number of uses of and mask instructions optimized");
132STATISTIC(NumRetsDup,
"Number of return instructions duplicated");
133STATISTIC(NumDbgValueMoved,
"Number of debug value instructions moved");
134STATISTIC(NumSelectsExpanded,
"Number of selects turned into branches");
135STATISTIC(NumStoreExtractExposed,
"Number of store(extractelement) exposed");
139 cl::desc(
"Disable branch optimizations in CodeGenPrepare"));
143 cl::desc(
"Disable GC optimizations in CodeGenPrepare"));
148 cl::desc(
"Disable select to branch conversion."));
152 cl::desc(
"Address sinking in CGP using GEPs."));
156 cl::desc(
"Enable sinking and/cmp into branches."));
160 cl::desc(
"Disable store(extract) optimizations in CodeGenPrepare"));
164 cl::desc(
"Stress test store(extract) optimizations in CodeGenPrepare"));
168 cl::desc(
"Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in "
173 cl::desc(
"Stress test ext(promotable(ld)) -> promoted(ext(ld)) "
174 "optimization in CodeGenPrepare"));
178 cl::desc(
"Disable protection against removing loop preheaders"));
182 cl::desc(
"Use profile info to add section prefix for hot/cold functions"));
185 "profile-unknown-in-special-section",
cl::Hidden,
186 cl::desc(
"In profiling mode like sampleFDO, if a function doesn't have "
187 "profile, we cannot tell the function is cold for sure because "
188 "it may be a function newly added without ever being sampled. "
189 "With the flag enabled, compiler can put such profile unknown "
190 "functions into a special section, so runtime system can choose "
191 "to handle it in a different way than .text section, to save "
192 "RAM for example. "));
196 cl::desc(
"Use the basic-block-sections profile to determine the text "
197 "section prefix for hot functions. Functions with "
198 "basic-block-sections profile will be placed in `.text.hot` "
199 "regardless of their FDO profile info. Other functions won't be "
200 "impacted, i.e., their prefixes will be decided by FDO/sampleFDO "
205 cl::desc(
"Skip merging empty blocks if (frequency of empty block) / "
206 "(frequency of destination block) is greater than this ratio"));
210 cl::desc(
"Force store splitting no matter what the target query says."));
214 cl::desc(
"Enable merging of redundant sexts when one is dominating"
220 cl::desc(
"Disables combining addressing modes with different parts "
221 "in optimizeMemoryInst."));
225 cl::desc(
"Allow creation of Phis in Address sinking."));
229 cl::desc(
"Allow creation of selects in Address sinking."));
233 cl::desc(
"Allow combining of BaseReg field in Address sinking."));
237 cl::desc(
"Allow combining of BaseGV field in Address sinking."));
241 cl::desc(
"Allow combining of BaseOffs field in Address sinking."));
245 cl::desc(
"Allow combining of ScaledReg field in Address sinking."));
250 cl::desc(
"Enable splitting large offset of GEP."));
254 cl::desc(
"Enable ICMP_EQ to ICMP_S(L|G)T conversion."));
258 cl::desc(
"Enable BFI update verification for "
263 cl::desc(
"Enable converting phi types in CodeGenPrepare"));
267 cl::desc(
"Least BB number of huge function."));
272 cl::desc(
"Max number of address users to look at"));
276 cl::desc(
"Disable elimination of dead PHI nodes."));
304class TypePromotionTransaction;
306class CodeGenPrepare {
307 friend class CodeGenPrepareLegacyPass;
308 const TargetMachine *TM =
nullptr;
309 const TargetSubtargetInfo *SubtargetInfo =
nullptr;
310 const TargetLowering *TLI =
nullptr;
311 const TargetRegisterInfo *TRI =
nullptr;
312 const TargetTransformInfo *TTI =
nullptr;
313 const BasicBlockSectionsProfileReader *BBSectionsProfileReader =
nullptr;
314 const TargetLibraryInfo *TLInfo =
nullptr;
315 LoopInfo *LI =
nullptr;
316 std::unique_ptr<BlockFrequencyInfo> BFI;
317 std::unique_ptr<BranchProbabilityInfo> BPI;
318 ProfileSummaryInfo *PSI =
nullptr;
329 ValueMap<Value *, WeakTrackingVH> SunkAddrs;
332 SetOfInstrs InsertedInsts;
336 InstrToOrigTy PromotedInsts;
339 SetOfInstrs RemovedInsts;
342 DenseMap<Value *, Instruction *> SeenChainsForSExt;
347 MapVector<AssertingVH<Value>,
352 SmallSet<AssertingVH<Value>, 2> NewGEPBases;
355 DenseMap<AssertingVH<GetElementPtrInst>,
int> LargeOffsetGEPID;
358 ValueToSExts ValToSExtendedUses;
364 const DataLayout *DL =
nullptr;
368 std::unique_ptr<DominatorTree> DT;
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();
394 template <
typename F>
395 void resetIteratorIfInvalidatedWhileCalling(BasicBlock *BB,
F f) {
399 Value *CurValue = &*CurInstIterator;
400 WeakTrackingVH IterHandle(CurValue);
406 if (IterHandle != CurValue) {
407 CurInstIterator = BB->
begin();
413 DominatorTree &getDT(Function &
F) {
415 DT = std::make_unique<DominatorTree>(
F);
419 void removeAllAssertingVHReferences(
Value *V);
420 bool eliminateAssumptions(Function &
F);
421 bool eliminateFallThrough(Function &
F, DominatorTree *DT =
nullptr);
422 bool eliminateMostlyEmptyBlocks(Function &
F);
423 BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB);
424 bool canMergeBlocks(
const BasicBlock *BB,
const BasicBlock *DestBB)
const;
425 void eliminateMostlyEmptyBlock(BasicBlock *BB);
426 bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB,
428 bool makeBitReverse(Instruction &
I);
430 bool optimizeInst(Instruction *
I, ModifyDT &ModifiedDT);
431 bool optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
Type *AccessTy,
433 bool optimizeGatherScatterInst(Instruction *MemoryInst,
Value *Ptr);
434 bool optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
435 ModifyDT &ModifiedDT);
436 bool optimizeInlineAsmInst(CallInst *CS);
438 bool optimizeExt(Instruction *&
I);
439 bool optimizeExtUses(Instruction *
I);
440 bool optimizeLoadExt(LoadInst *Load);
441 bool optimizeShiftInst(BinaryOperator *BO);
442 bool optimizeFunnelShift(IntrinsicInst *Fsh);
443 bool optimizeSelectInst(SelectInst *SI);
444 bool optimizeShuffleVectorInst(ShuffleVectorInst *SVI);
445 bool optimizeSwitchType(SwitchInst *SI);
446 bool optimizeSwitchPhiConstants(SwitchInst *SI);
447 bool optimizeSwitchInst(SwitchInst *SI);
448 bool optimizeExtractElementInst(Instruction *Inst);
449 bool dupRetToEnableTailCallOpts(BasicBlock *BB, ModifyDT &ModifiedDT);
450 bool fixupDbgVariableRecord(DbgVariableRecord &
I);
451 bool fixupDbgVariableRecordsOnInst(Instruction &
I);
452 bool placeDbgValues(Function &
F);
453 bool placePseudoProbes(Function &
F);
454 bool canFormExtLd(
const SmallVectorImpl<Instruction *> &MovedExts,
455 LoadInst *&LI, Instruction *&Inst,
bool HasPromoted);
456 bool tryToPromoteExts(TypePromotionTransaction &TPT,
457 const SmallVectorImpl<Instruction *> &Exts,
458 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
459 unsigned CreatedInstsCost = 0);
460 bool mergeSExts(Function &
F);
461 bool splitLargeGEPOffsets();
462 bool optimizePhiType(PHINode *Inst, SmallPtrSetImpl<PHINode *> &Visited,
463 SmallPtrSetImpl<Instruction *> &DeletedInstrs);
464 bool optimizePhiTypes(Function &
F);
465 bool performAddressTypePromotion(
466 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
467 bool HasPromoted, TypePromotionTransaction &TPT,
468 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts);
469 bool splitBranchCondition(Function &
F, ModifyDT &ModifiedDT);
470 bool simplifyOffsetableRelocate(GCStatepointInst &
I);
472 bool tryToSinkFreeOperands(Instruction *
I);
473 bool replaceMathCmpWithIntrinsic(BinaryOperator *BO,
Value *Arg0,
Value *Arg1,
475 bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT);
476 bool optimizeURem(Instruction *Rem);
477 bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
478 bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
479 bool unfoldPowerOf2Test(CmpInst *Cmp);
480 void verifyBFIUpdates(Function &
F);
481 bool _run(Function &
F);
488 CodeGenPrepareLegacyPass() : FunctionPass(ID) {
494 StringRef getPassName()
const override {
return "CodeGen Prepare"; }
496 void getAnalysisUsage(AnalysisUsage &AU)
const override {
509char CodeGenPrepareLegacyPass::ID = 0;
511bool CodeGenPrepareLegacyPass::runOnFunction(
Function &
F) {
514 auto TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
515 CodeGenPrepare CGP(TM);
516 CGP.DL = &
F.getDataLayout();
519 CGP.TRI = CGP.SubtargetInfo->getRegisterInfo();
520 CGP.TLInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
521 CGP.TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
522 CGP.LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
523 CGP.BPI.reset(
new BranchProbabilityInfo(
F, *CGP.LI));
524 CGP.BFI.reset(
new BlockFrequencyInfo(
F, *CGP.BPI, *CGP.LI));
525 CGP.PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
527 getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
528 CGP.BBSectionsProfileReader = BBSPRWP ? &BBSPRWP->getBBSPR() :
nullptr;
534 "Optimize for code generation",
false,
false)
545 return new CodeGenPrepareLegacyPass();
550 CodeGenPrepare CGP(TM);
564 DL = &
F.getDataLayout();
575 BBSectionsProfileReader =
581 bool EverMadeChange =
false;
583 OptSize =
F.hasOptSize();
588 (void)
F.setSectionPrefix(
"hot");
593 if (
F.hasFnAttribute(Attribute::Hot) ||
595 (void)
F.setSectionPrefix(
"hot");
600 F.hasFnAttribute(Attribute::Cold))
601 (void)
F.setSectionPrefix(
"unlikely");
604 (void)
F.setSectionPrefix(
"unknown");
610 const DenseMap<unsigned int, unsigned int> &BypassWidths =
613 while (BB !=
nullptr) {
626 EverMadeChange |= eliminateAssumptions(
F);
630 EverMadeChange |= eliminateMostlyEmptyBlocks(
F);
632 ModifyDT ModifiedDT = ModifyDT::NotModifyDT;
634 EverMadeChange |= splitBranchCondition(
F, ModifiedDT);
648 LI->analyze(getDT(
F));
650 bool MadeChange =
true;
651 bool FuncIterated =
false;
656 if (FuncIterated && !FreshBBs.
contains(&BB))
659 ModifyDT ModifiedDTOnIteration = ModifyDT::NotModifyDT;
662 if (ModifiedDTOnIteration == ModifyDT::ModifyBBDT)
678 else if (FuncIterated)
683 if (ModifiedDTOnIteration != ModifyDT::NotModifyDT)
688 FuncIterated = IsHugeFunc;
691 MadeChange |= mergeSExts(
F);
692 if (!LargeOffsetGEPMap.
empty())
693 MadeChange |= splitLargeGEPOffsets();
694 MadeChange |= optimizePhiTypes(
F);
697 eliminateFallThrough(
F, DT.get());
701 LI->verify(getDT(
F));
705 for (Instruction *
I : RemovedInsts)
708 EverMadeChange |= MadeChange;
709 SeenChainsForSExt.
clear();
710 ValToSExtendedUses.clear();
711 RemovedInsts.clear();
712 LargeOffsetGEPMap.
clear();
713 LargeOffsetGEPID.
clear();
724 SmallSetVector<BasicBlock *, 8> WorkList;
725 for (BasicBlock &BB :
F) {
731 for (BasicBlock *Succ : Successors)
737 MadeChange |= !WorkList.
empty();
738 while (!WorkList.
empty()) {
744 for (BasicBlock *Succ : Successors)
751 if (EverMadeChange || MadeChange)
752 MadeChange |= eliminateFallThrough(
F);
754 EverMadeChange |= MadeChange;
759 for (BasicBlock &BB :
F)
760 for (Instruction &
I : BB)
763 for (
auto &
I : Statepoints)
764 EverMadeChange |= simplifyOffsetableRelocate(*
I);
769 EverMadeChange |= placeDbgValues(
F);
770 EverMadeChange |= placePseudoProbes(
F);
777 return EverMadeChange;
780bool CodeGenPrepare::eliminateAssumptions(Function &
F) {
781 bool MadeChange =
false;
782 for (BasicBlock &BB :
F) {
783 CurInstIterator = BB.begin();
784 while (CurInstIterator != BB.end()) {
789 Assume->eraseFromParent();
791 resetIteratorIfInvalidatedWhileCalling(&BB, [&]() {
802void CodeGenPrepare::removeAllAssertingVHReferences(
Value *V) {
803 LargeOffsetGEPMap.
erase(V);
804 NewGEPBases.
erase(V);
812 auto VecI = LargeOffsetGEPMap.
find(
GEP->getPointerOperand());
813 if (VecI == LargeOffsetGEPMap.
end())
816 auto &GEPVector = VecI->second;
819 if (GEPVector.empty())
820 LargeOffsetGEPMap.
erase(VecI);
824[[maybe_unused]]
void CodeGenPrepare::verifyBFIUpdates(Function &
F) {
825 DominatorTree NewDT(
F);
826 LoopInfo NewLI(NewDT);
827 BranchProbabilityInfo NewBPI(
F, NewLI, TLInfo);
828 BlockFrequencyInfo NewBFI(
F, NewBPI, NewLI);
829 NewBFI.verifyMatch(*BFI);
835bool CodeGenPrepare::eliminateFallThrough(Function &
F, DominatorTree *DT) {
843 SmallSet<WeakTrackingVH, 16> Preds;
844 for (
auto &
Block : Blocks) {
850 BasicBlock *SinglePred = BB->getSinglePredecessor();
853 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
861 if (Term && !
Term->isConditional()) {
873 FreshBBs.
insert(SinglePred);
881 for (
const auto &Pred : Preds)
889BasicBlock *CodeGenPrepare::findDestBlockOfMergeableEmptyBlock(BasicBlock *BB) {
898 if (BBI != BB->
begin()) {
909 if (!canMergeBlocks(BB, DestBB))
919bool CodeGenPrepare::eliminateMostlyEmptyBlocks(Function &
F) {
920 SmallPtrSet<BasicBlock *, 16> Preheaders;
922 while (!LoopList.empty()) {
923 Loop *
L = LoopList.pop_back_val();
925 if (BasicBlock *Preheader =
L->getLoopPreheader())
926 Preheaders.
insert(Preheader);
929 bool MadeChange =
false;
941 for (
auto &
Block : Blocks) {
945 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
947 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.
count(BB)))
950 eliminateMostlyEmptyBlock(BB);
956bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB,
1007 SmallPtrSet<BasicBlock *, 16> SameIncomingValueBBs;
1012 if (DestBBPred == BB)
1016 return DestPN.getIncomingValueForBlock(BB) ==
1017 DestPN.getIncomingValueForBlock(DestBBPred);
1019 SameIncomingValueBBs.
insert(DestBBPred);
1025 if (SameIncomingValueBBs.
count(Pred))
1028 BlockFrequency PredFreq = BFI->getBlockFreq(Pred);
1029 BlockFrequency
BBFreq = BFI->getBlockFreq(BB);
1031 for (
auto *SameValueBB : SameIncomingValueBBs)
1032 if (SameValueBB->getUniquePredecessor() == Pred &&
1033 DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
1034 BBFreq += BFI->getBlockFreq(SameValueBB);
1037 return !Limit || PredFreq <= *Limit;
1043bool CodeGenPrepare::canMergeBlocks(
const BasicBlock *BB,
1044 const BasicBlock *DestBB)
const {
1048 for (
const PHINode &PN : BB->
phis()) {
1049 for (
const User *U : PN.users()) {
1058 for (
unsigned I = 0,
E = UPN->getNumIncomingValues();
I !=
E; ++
I) {
1061 Insn->
getParent() != UPN->getIncomingBlock(
I))
1076 SmallPtrSet<const BasicBlock *, 16> BBPreds;
1079 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1080 BBPreds.
insert(BBPN->getIncomingBlock(i));
1088 if (BBPreds.
count(Pred)) {
1089 for (
const PHINode &PN : DestBB->
phis()) {
1090 const Value *V1 = PN.getIncomingValueForBlock(Pred);
1091 const Value *V2 = PN.getIncomingValueForBlock(BB);
1095 if (V2PN->getParent() == BB)
1096 V2 = V2PN->getIncomingValueForBlock(Pred);
1126void CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
1136 if (SinglePred != DestBB) {
1137 assert(SinglePred == BB &&
1138 "Single predecessor not the same as predecessor");
1147 FreshBBs.
insert(SinglePred);
1148 FreshBBs.
erase(DestBB);
1156 for (PHINode &PN : DestBB->
phis()) {
1158 Value *InVal = PN.removeIncomingValue(BB,
false);
1163 if (InValPhi && InValPhi->
getParent() == BB) {
1172 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1173 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1176 PN.addIncoming(InVal, Pred);
1206 for (
auto *ThisRelocate : AllRelocateCalls) {
1207 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1208 ThisRelocate->getDerivedPtrIndex());
1209 RelocateIdxMap.
insert(std::make_pair(K, ThisRelocate));
1211 for (
auto &Item : RelocateIdxMap) {
1212 std::pair<unsigned, unsigned>
Key = Item.first;
1213 if (
Key.first ==
Key.second)
1218 auto BaseKey = std::make_pair(
Key.first,
Key.first);
1221 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1222 if (MaybeBase == RelocateIdxMap.
end())
1227 RelocateInstMap[MaybeBase->second].push_back(
I);
1235 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1238 if (!
Op ||
Op->getZExtValue() > 20)
1242 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1252 bool MadeChange =
false;
1259 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1260 &*R != RelocatedBase; ++R)
1264 RelocatedBase->
moveBefore(RI->getIterator());
1271 "Not relocating a derived object of the original base object");
1272 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1277 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1287 if (!Derived || Derived->getPointerOperand() !=
Base)
1296 "Should always have one since it's not a terminator");
1300 Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
1324 Value *ActualRelocatedBase = RelocatedBase;
1325 if (RelocatedBase->
getType() !=
Base->getType()) {
1326 ActualRelocatedBase =
1327 Builder.CreateBitCast(RelocatedBase,
Base->getType());
1329 Value *Replacement =
1330 Builder.CreateGEP(Derived->getSourceElementType(), ActualRelocatedBase,
1336 Value *ActualReplacement = Replacement;
1337 if (Replacement->
getType() != ToReplace->getType()) {
1339 Builder.CreateBitCast(Replacement, ToReplace->
getType());
1342 ToReplace->eraseFromParent();
1366bool CodeGenPrepare::simplifyOffsetableRelocate(GCStatepointInst &
I) {
1367 bool MadeChange =
false;
1369 for (
auto *U :
I.users())
1376 if (AllRelocateCalls.
size() < 2)
1381 MapVector<GCRelocateInst *, SmallVector<GCRelocateInst *, 0>> RelocateInstMap;
1383 if (RelocateInstMap.
empty())
1386 for (
auto &Item : RelocateInstMap)
1400 bool MadeChange =
false;
1403 Use &TheUse = UI.getUse();
1410 UserBB = PN->getIncomingBlock(TheUse);
1418 if (
User->isEHPad())
1428 if (UserBB == DefBB)
1432 CastInst *&InsertedCast = InsertedCasts[UserBB];
1434 if (!InsertedCast) {
1442 TheUse = InsertedCast;
1468 ASC->getDestAddressSpace()))
1523static std::optional<std::pair<Instruction *, Constant *>>
1526 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1527 return std::nullopt;
1530 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1531 return std::nullopt;
1535 return std::make_pair(IVInc, Step);
1536 return std::nullopt;
1549 return IVInc->first ==
I;
1553bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
1557 auto IsReplacableIVIncrement = [
this, &
Cmp](BinaryOperator *BO) {
1560 const Loop *
L = LI->getLoopFor(BO->
getParent());
1561 assert(L &&
"L should not be null after isIVIncrement()");
1563 if (LI->getLoopFor(
Cmp->getParent()) != L)
1569 auto &DT = getDT(*BO->
getParent()->getParent());
1578 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1601 if (BO->
getOpcode() == Instruction::Add &&
1602 IID == Intrinsic::usub_with_overflow) {
1609 for (Instruction &Iter : *
Cmp->getParent()) {
1612 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1617 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1620 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1621 if (BO->
getOpcode() != Instruction::Xor) {
1622 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1626 "Patterns with XOr should use the BO only in the compare");
1627 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1629 Cmp->eraseFromParent();
1639 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1647 B = ConstantInt::get(
B->getType(), 1);
1655 for (
User *U :
A->users()) {
1666bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp,
1667 ModifyDT &ModifiedDT) {
1668 bool EdgeCase =
false;
1670 BinaryOperator *
Add;
1675 A =
Add->getOperand(0);
1676 B =
Add->getOperand(1);
1682 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1688 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1691 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1692 Intrinsic::uadd_with_overflow))
1696 ModifiedDT = ModifyDT::ModifyInstDT;
1700bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
1701 ModifyDT &ModifiedDT) {
1708 ICmpInst::Predicate Pred =
Cmp->getPredicate();
1709 if (Pred == ICmpInst::ICMP_UGT) {
1711 Pred = ICmpInst::ICMP_ULT;
1715 B = ConstantInt::get(
B->getType(), 1);
1716 Pred = ICmpInst::ICMP_ULT;
1721 Pred = ICmpInst::ICMP_ULT;
1723 if (Pred != ICmpInst::ICMP_ULT)
1730 BinaryOperator *
Sub =
nullptr;
1731 for (User *U : CmpVariableOperand->
users()) {
1739 const APInt *CmpC, *AddC;
1751 Sub->hasNUsesOrMore(1)))
1757 if (
Sub->getParent() !=
Cmp->getParent() && !
Sub->hasOneUse())
1760 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1761 Cmp, Intrinsic::usub_with_overflow))
1765 ModifiedDT = ModifyDT::ModifyInstDT;
1772bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1786 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1792 Type *OpTy =
X->getType();
1800 if (Pred == ICmpInst::ICMP_EQ) {
1801 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1802 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1804 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1810 if (IsPowerOf2OrZeroTest ||
1821 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1830 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1833 Cmp->replaceAllUsesWith(NewCmp);
1853 bool UsedInPhiOrCurrentBlock =
any_of(Cmp->users(), [Cmp](
User *U) {
1854 return isa<PHINode>(U) ||
1855 cast<Instruction>(U)->getParent() == Cmp->getParent();
1860 if (UsedInPhiOrCurrentBlock && Cmp->getOperand(0)->getType()->isIntegerTy() &&
1861 Cmp->getOperand(0)->getType()->getScalarSizeInBits() >
1862 DL.getLargestLegalIntTypeSizeInBits())
1868 bool MadeChange =
false;
1871 Use &TheUse = UI.getUse();
1886 if (UserBB == DefBB)
1890 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1896 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1903 TheUse = InsertedCmp;
1909 if (Cmp->use_empty()) {
1910 Cmp->eraseFromParent();
1947 for (
User *U : Cmp->users()) {
1969 if (CmpBB != FalseBB)
1972 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
1986 for (
User *U : Cmp->users()) {
1995 SI->swapProfMetadata();
2007 Value *Op0 = Cmp->getOperand(0);
2008 Value *Op1 = Cmp->getOperand(1);
2017 unsigned NumInspected = 0;
2020 if (++NumInspected > 128)
2028 if (GoodToSwap > 0) {
2029 Cmp->swapOperands();
2049 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
2052 auto [ClassVal, ClassTest] =
2058 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2062 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
2063 Cmp->replaceAllUsesWith(IsFPClass);
2071 Value *Incr, *RemAmt;
2076 Value *AddInst, *AddOffset;
2079 if (PN !=
nullptr) {
2081 AddOffset =
nullptr;
2090 if (PN !=
nullptr) {
2103 if (PN->getNumIncomingValues() != 2)
2108 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2112 if (!L->contains(Rem))
2116 if (!L->isLoopInvariant(RemAmt))
2120 if (AddOffset && !L->isLoopInvariant(AddOffset))
2141 AddInstOut = AddInst;
2142 AddOffsetOut = AddOffset;
2161 Value *AddOffset, *RemAmt, *AddInst;
2164 AddOffset, LoopIncrPN))
2189 assert(AddOffset &&
"We found an add but missing values");
2208 Builder.SetInsertPoint(LoopIncrPN);
2209 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2214 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2219 NewRem->
addIncoming(Start, L->getLoopPreheader());
2224 FreshBBs.
insert(L->getLoopLatch());
2235bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2241bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2245 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2248 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2251 if (unfoldPowerOf2Test(Cmp))
2272 SetOfInstrs &InsertedInsts) {
2275 assert(!InsertedInsts.count(AndI) &&
2276 "Attempting to optimize already optimized and instruction");
2277 (void)InsertedInsts;
2291 for (
auto *U : AndI->
users()) {
2299 if (!CmpC || !CmpC->
isZero())
2314 Use &TheUse = UI.getUse();
2332 TheUse = InsertedAnd;
2349 if (
User->getOpcode() != Instruction::And ||
2355 if ((Cimm & (Cimm + 1)).getBoolValue())
2369 bool MadeChange =
false;
2372 TruncE = TruncI->user_end();
2373 TruncUI != TruncE;) {
2375 Use &TruncTheUse = TruncUI.getUse();
2400 if (UserBB == TruncUserBB)
2404 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2406 if (!InsertedShift && !InsertedTrunc) {
2410 if (ShiftI->
getOpcode() == Instruction::AShr)
2412 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2415 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2423 TruncInsertPt.setHeadBit(
true);
2424 assert(TruncInsertPt != TruncUserBB->
end());
2428 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2429 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2433 TruncTheUse = InsertedTrunc;
2466 bool MadeChange =
false;
2469 Use &TheUse = UI.getUse();
2483 if (UserBB == DefBB) {
2511 if (!InsertedShift) {
2515 if (ShiftI->
getOpcode() == Instruction::AShr)
2517 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2520 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2528 TheUse = InsertedShift;
2575 unsigned SizeInBits = Ty->getScalarSizeInBits();
2576 if (Ty->isVectorTy())
2588 FreshBBs.
insert(CallBlock);
2595 SplitPt.setHeadBit(
true);
2598 FreshBBs.
insert(EndBlock);
2603 L->addBasicBlockToLoop(CallBlock, LI);
2604 L->addBasicBlockToLoop(EndBlock, LI);
2610 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2617 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2618 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2619 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2624 Builder.SetInsertPoint(EndBlock, EndBlock->
begin());
2625 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2635 ModifiedDT = ModifyDT::ModifyBBDT;
2639bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2643 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2651 for (
auto &Arg : CI->
args()) {
2656 if (!Arg->getType()->isPointerTy())
2658 APInt
Offset(
DL->getIndexSizeInBits(
2661 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2662 uint64_t Offset2 =
Offset.getLimitedValue();
2684 MaybeAlign MIDestAlign =
MI->getDestAlign();
2685 if (!MIDestAlign || DestAlign > *MIDestAlign)
2686 MI->setDestAlignment(DestAlign);
2688 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2690 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2691 MTI->setSourceAlignment(SrcAlign);
2701 for (
auto &Arg : CI->
args()) {
2702 if (!Arg->getType()->isPointerTy())
2704 unsigned AS = Arg->getType()->getPointerAddressSpace();
2705 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2711 switch (
II->getIntrinsicID()) {
2714 case Intrinsic::assume:
2716 case Intrinsic::allow_runtime_check:
2717 case Intrinsic::allow_ubsan_check:
2718 case Intrinsic::experimental_widenable_condition: {
2722 if (
II->use_empty()) {
2723 II->eraseFromParent();
2727 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2732 case Intrinsic::objectsize:
2734 case Intrinsic::is_constant:
2736 case Intrinsic::aarch64_stlxr:
2737 case Intrinsic::aarch64_stxr: {
2746 InsertedInsts.insert(ExtVal);
2750 case Intrinsic::launder_invariant_group:
2751 case Intrinsic::strip_invariant_group: {
2752 Value *ArgVal =
II->getArgOperand(0);
2753 auto it = LargeOffsetGEPMap.
find(
II);
2754 if (it != LargeOffsetGEPMap.
end()) {
2758 auto GEPs = std::move(it->second);
2759 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2764 II->eraseFromParent();
2767 case Intrinsic::cttz:
2768 case Intrinsic::ctlz:
2772 case Intrinsic::fshl:
2773 case Intrinsic::fshr:
2774 return optimizeFunnelShift(
II);
2775 case Intrinsic::masked_gather:
2776 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2777 case Intrinsic::masked_scatter:
2778 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2779 case Intrinsic::masked_load:
2782 if (VT->getNumElements() == 1) {
2783 Value *PtrVal =
II->getArgOperand(0);
2785 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2790 case Intrinsic::masked_store:
2794 if (VT->getNumElements() == 1) {
2795 Value *PtrVal =
II->getArgOperand(1);
2797 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2802 case Intrinsic::umul_with_overflow:
2803 return optimizeMulWithOverflow(
II,
false, ModifiedDT);
2804 case Intrinsic::smul_with_overflow:
2805 return optimizeMulWithOverflow(
II,
true, ModifiedDT);
2808 SmallVector<Value *, 2> PtrOps;
2811 while (!PtrOps.
empty()) {
2814 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2828 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2830 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2840 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2841 if (!
F->getReturnType()->isPointerTy())
2844 GlobalVariable *UniformValue =
nullptr;
2845 for (
auto &BB : *
F) {
2850 else if (V != UniformValue)
2858 return UniformValue;
2861 if (
Callee->hasExactDefinition()) {
2862 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2863 bool MadeChange =
false;
2889 switch (
II->getIntrinsicID()) {
2890 case Intrinsic::memset:
2891 case Intrinsic::memcpy:
2892 case Intrinsic::memmove:
2900 if (Callee && TLInfo && TLInfo->
getLibFunc(*Callee, LF))
2902 case LibFunc_strcpy:
2903 case LibFunc_strncpy:
2904 case LibFunc_strcat:
2905 case LibFunc_strncat:
2946bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
2947 ModifyDT &ModifiedDT) {
2955 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2957 PHINode *PN =
nullptr;
2958 ExtractValueInst *EVI =
nullptr;
2959 BitCastInst *BCI =
nullptr;
2979 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
2985 return II->getIntrinsicID() == Intrinsic::lifetime_end;
2991 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
2993 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
3015 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
3065 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
3067 if (!VisitedBBs.
insert(Pred).second)
3069 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
3087 for (
auto const &TailCallBB : TailCallBBs) {
3097 BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB));
3098 BFI->setBlockFreq(BB,
3099 (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB)));
3100 ModifiedDT = ModifyDT::ModifyBBDT;
3109 for (
auto *CI : CallInsts) {
3110 for (
auto const *FakeUse : FakeUses) {
3111 auto *ClonedInst = FakeUse->clone();
3129struct ExtAddrMode :
public TargetLowering::AddrMode {
3130 Value *BaseReg =
nullptr;
3131 Value *ScaledReg =
nullptr;
3132 Value *OriginalValue =
nullptr;
3133 bool InBounds =
true;
3137 BaseRegField = 0x01,
3139 BaseOffsField = 0x04,
3140 ScaledRegField = 0x08,
3142 MultipleFields = 0xff
3145 ExtAddrMode() =
default;
3147 void print(raw_ostream &OS)
const;
3154 if (ScaledReg == From)
3158 FieldName
compare(
const ExtAddrMode &other) {
3161 if (BaseReg && other.
BaseReg &&
3163 return MultipleFields;
3164 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3165 return MultipleFields;
3168 return MultipleFields;
3171 if (InBounds != other.InBounds)
3172 return MultipleFields;
3175 unsigned Result = NoField;
3178 if (BaseGV != other.BaseGV)
3180 if (BaseOffs != other.BaseOffs)
3183 Result |= ScaledRegField;
3186 if (Scale && other.
Scale && Scale != other.
Scale)
3190 return MultipleFields;
3192 return static_cast<FieldName
>(
Result);
3202 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3213 case ScaledRegField:
3220 void SetCombinedField(FieldName
Field,
Value *V,
3221 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3226 case ExtAddrMode::BaseRegField:
3229 case ExtAddrMode::BaseGVField:
3232 assert(BaseReg ==
nullptr);
3236 case ExtAddrMode::ScaledRegField:
3241 for (
const ExtAddrMode &AM : AddrModes)
3247 case ExtAddrMode::BaseOffsField:
3250 assert(ScaledReg ==
nullptr);
3260static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3266#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3267void ExtAddrMode::print(raw_ostream &OS)
const {
3268 bool NeedPlus =
false;
3274 BaseGV->printAsOperand(OS,
false);
3279 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3284 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3285 BaseReg->printAsOperand(OS,
false);
3289 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3312class TypePromotionTransaction {
3316 class TypePromotionAction {
3324 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3326 virtual ~TypePromotionAction() =
default;
3333 virtual void undo() = 0;
3338 virtual void commit() {
3344 class InsertionHandler {
3353 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3356 bool HasPrevInstruction;
3360 InsertionHandler(Instruction *Inst) {
3368 if (HasPrevInstruction) {
3376 void insert(Instruction *Inst) {
3377 if (HasPrevInstruction) {
3389 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3394 class InstructionMoveBefore :
public TypePromotionAction {
3396 InsertionHandler Position;
3401 : TypePromotionAction(Inst), Position(Inst) {
3402 LLVM_DEBUG(
dbgs() <<
"Do: move: " << *Inst <<
"\nbefore: " << *Before
3408 void undo()
override {
3410 Position.insert(Inst);
3415 class OperandSetter :
public TypePromotionAction {
3424 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3425 : TypePromotionAction(Inst), Idx(Idx) {
3427 <<
"for:" << *Inst <<
"\n"
3428 <<
"with:" << *NewVal <<
"\n");
3434 void undo()
override {
3436 <<
"for: " << *Inst <<
"\n"
3437 <<
"with: " << *Origin <<
"\n");
3444 class OperandsHider :
public TypePromotionAction {
3450 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3453 OriginalValues.
reserve(NumOpnds);
3454 for (
unsigned It = 0; It < NumOpnds; ++It) {
3466 void undo()
override {
3468 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3474 class TruncBuilder :
public TypePromotionAction {
3481 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3483 Builder.SetCurrentDebugLocation(
DebugLoc());
3484 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3489 Value *getBuiltValue() {
return Val; }
3492 void undo()
override {
3495 IVal->eraseFromParent();
3500 class SExtBuilder :
public TypePromotionAction {
3507 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3508 : TypePromotionAction(InsertPt) {
3510 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3515 Value *getBuiltValue() {
return Val; }
3518 void undo()
override {
3521 IVal->eraseFromParent();
3526 class ZExtBuilder :
public TypePromotionAction {
3533 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3534 : TypePromotionAction(InsertPt) {
3536 Builder.SetCurrentDebugLocation(
DebugLoc());
3537 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3542 Value *getBuiltValue() {
return Val; }
3545 void undo()
override {
3548 IVal->eraseFromParent();
3553 class TypeMutator :
public TypePromotionAction {
3559 TypeMutator(Instruction *Inst,
Type *NewTy)
3560 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3561 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3567 void undo()
override {
3568 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3575 class UsesReplacer :
public TypePromotionAction {
3577 struct InstructionAndIdx {
3584 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3585 : Inst(Inst), Idx(Idx) {}
3591 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3601 UsesReplacer(Instruction *Inst,
Value *New)
3602 : TypePromotionAction(Inst),
New(
New) {
3603 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3606 for (Use &U : Inst->
uses()) {
3608 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3619 void undo()
override {
3621 for (InstructionAndIdx &Use : OriginalUses)
3622 Use.Inst->setOperand(
Use.Idx, Inst);
3627 for (DbgVariableRecord *DVR : DbgVariableRecords)
3628 DVR->replaceVariableLocationOp(New, Inst);
3633 class InstructionRemover :
public TypePromotionAction {
3635 InsertionHandler Inserter;
3639 OperandsHider Hider;
3642 UsesReplacer *Replacer =
nullptr;
3645 SetOfInstrs &RemovedInsts;
3652 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3653 Value *New =
nullptr)
3654 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3655 RemovedInsts(RemovedInsts) {
3657 Replacer =
new UsesReplacer(Inst, New);
3658 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3659 RemovedInsts.insert(Inst);
3666 ~InstructionRemover()
override {
delete Replacer; }
3668 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3669 InstructionRemover(
const InstructionRemover &other) =
delete;
3673 void undo()
override {
3674 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3675 Inserter.insert(Inst);
3679 RemovedInsts.erase(Inst);
3687 using ConstRestorationPt =
const TypePromotionAction *;
3689 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3690 : RemovedInsts(RemovedInsts) {}
3697 void rollback(ConstRestorationPt Point);
3700 ConstRestorationPt getRestorationPoint()
const;
3705 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3714 void mutateType(Instruction *Inst,
Type *NewTy);
3717 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3730 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3732 SetOfInstrs &RemovedInsts;
3737void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3739 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3740 Inst, Idx, NewVal));
3743void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3746 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3747 Inst, RemovedInsts, NewVal));
3750void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3753 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3756void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3758 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3761Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3762 std::unique_ptr<TruncBuilder> Ptr(
new TruncBuilder(Opnd, Ty));
3763 Value *Val = Ptr->getBuiltValue();
3764 Actions.push_back(std::move(Ptr));
3768Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3770 std::unique_ptr<SExtBuilder> Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3771 Value *Val = Ptr->getBuiltValue();
3772 Actions.push_back(std::move(Ptr));
3776Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3778 std::unique_ptr<ZExtBuilder> Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3779 Value *Val = Ptr->getBuiltValue();
3780 Actions.push_back(std::move(Ptr));
3784TypePromotionTransaction::ConstRestorationPt
3785TypePromotionTransaction::getRestorationPoint()
const {
3786 return !Actions.empty() ? Actions.back().get() :
nullptr;
3789bool TypePromotionTransaction::commit() {
3790 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3797void TypePromotionTransaction::rollback(
3798 TypePromotionTransaction::ConstRestorationPt Point) {
3799 while (!Actions.empty() && Point != Actions.back().get()) {
3800 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3810class AddressingModeMatcher {
3811 SmallVectorImpl<Instruction *> &AddrModeInsts;
3812 const TargetLowering &TLI;
3813 const TargetRegisterInfo &
TRI;
3814 const DataLayout &
DL;
3816 const std::function<
const DominatorTree &()> getDTFn;
3829 const SetOfInstrs &InsertedInsts;
3832 InstrToOrigTy &PromotedInsts;
3835 TypePromotionTransaction &TPT;
3838 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3842 bool IgnoreProfitability;
3845 bool OptSize =
false;
3847 ProfileSummaryInfo *PSI;
3848 BlockFrequencyInfo *BFI;
3850 AddressingModeMatcher(
3851 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3852 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3853 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3854 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3855 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3856 TypePromotionTransaction &TPT,
3857 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3858 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI)
3859 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3860 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3861 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3862 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3863 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI), BFI(BFI) {
3864 IgnoreProfitability =
false;
3876 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3877 SmallVectorImpl<Instruction *> &AddrModeInsts,
3878 const TargetLowering &TLI,
const LoopInfo &LI,
3879 const std::function<
const DominatorTree &()> getDTFn,
3880 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3881 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3882 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3883 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
3886 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3887 AccessTy, AS, MemoryInst, Result,
3888 InsertedInsts, PromotedInsts, TPT,
3889 LargeOffsetGEP, OptSize, PSI, BFI)
3897 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3899 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3900 bool *MovedAway =
nullptr);
3901 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3902 ExtAddrMode &AMBefore,
3903 ExtAddrMode &AMAfter);
3904 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3905 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3906 Value *PromotedOperand)
const;
3912class PhiNodeSetIterator {
3913 PhiNodeSet *
const Set;
3914 size_t CurrentIndex = 0;
3919 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3921 PhiNodeSetIterator &operator++();
3937 friend class PhiNodeSetIterator;
3939 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3940 using iterator = PhiNodeSetIterator;
3955 size_t FirstValidElement = 0;
3961 bool insert(PHINode *Ptr) {
3962 if (NodeMap.insert(std::make_pair(Ptr,
NodeList.
size())).second) {
3972 bool erase(PHINode *Ptr) {
3973 if (NodeMap.erase(Ptr)) {
3974 SkipRemovedElements(FirstValidElement);
3984 FirstValidElement = 0;
3990 if (FirstValidElement == 0)
3991 SkipRemovedElements(FirstValidElement);
3992 return PhiNodeSetIterator(
this, FirstValidElement);
3999 size_t size()
const {
return NodeMap.size(); }
4002 size_t count(PHINode *Ptr)
const {
return NodeMap.count(Ptr); }
4010 void SkipRemovedElements(
size_t &CurrentIndex) {
4012 auto it = NodeMap.find(NodeList[CurrentIndex]);
4015 if (it != NodeMap.end() && it->second == CurrentIndex)
4022PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
4025PHINode *PhiNodeSetIterator::operator*()
const {
4027 "PhiNodeSet access out of range");
4028 return Set->NodeList[CurrentIndex];
4031PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
4033 "PhiNodeSet access out of range");
4035 Set->SkipRemovedElements(CurrentIndex);
4039bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
4040 return CurrentIndex ==
RHS.CurrentIndex;
4043bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
4044 return !((*this) ==
RHS);
4050class SimplificationTracker {
4051 DenseMap<Value *, Value *> Storage;
4054 PhiNodeSet AllPhiNodes;
4056 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
4061 auto SV = Storage.
find(V);
4062 if (SV == Storage.
end())
4070 void ReplacePhi(PHINode *From, PHINode *To) {
4071 Value *OldReplacement = Get(From);
4072 while (OldReplacement != From) {
4075 OldReplacement = Get(From);
4077 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
4080 AllPhiNodes.erase(From);
4084 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
4086 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
4088 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
4090 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4092 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4094 void destroyNewNodes(
Type *CommonType) {
4097 for (
auto *
I : AllPhiNodes) {
4098 I->replaceAllUsesWith(Dummy);
4099 I->eraseFromParent();
4101 AllPhiNodes.clear();
4102 for (
auto *
I : AllSelectNodes) {
4103 I->replaceAllUsesWith(Dummy);
4104 I->eraseFromParent();
4106 AllSelectNodes.clear();
4111class AddressingModeCombiner {
4112 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4113 typedef std::pair<PHINode *, PHINode *> PHIPair;
4120 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4123 bool AllAddrModesTrivial =
true;
4126 Type *CommonType =
nullptr;
4128 const DataLayout &
DL;
4134 Value *CommonValue =
nullptr;
4137 AddressingModeCombiner(
const DataLayout &
DL,
Value *OriginalValue)
4138 :
DL(
DL), Original(OriginalValue) {}
4140 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4143 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4148 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4152 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4155 if (AddrModes.
empty()) {
4163 ExtAddrMode::FieldName ThisDifferentField =
4164 AddrModes[0].compare(NewAddrMode);
4165 if (DifferentField == ExtAddrMode::NoField)
4166 DifferentField = ThisDifferentField;
4167 else if (DifferentField != ThisDifferentField)
4168 DifferentField = ExtAddrMode::MultipleFields;
4171 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4174 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4179 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4184 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4185 !NewAddrMode.HasBaseReg);
4202 bool combineAddrModes() {
4204 if (AddrModes.
size() == 0)
4208 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4213 if (AllAddrModesTrivial)
4216 if (!addrModeCombiningAllowed())
4222 FoldAddrToValueMapping
Map;
4223 if (!initializeMap(Map))
4226 CommonValue = findCommon(Map);
4228 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4229 return CommonValue !=
nullptr;
4235 void eraseCommonValueIfDead() {
4236 if (CommonValue && CommonValue->
use_empty())
4238 CommonInst->eraseFromParent();
4246 bool initializeMap(FoldAddrToValueMapping &Map) {
4249 SmallVector<Value *, 2> NullValue;
4250 Type *IntPtrTy =
DL.getIntPtrType(AddrModes[0].OriginalValue->
getType());
4251 for (
auto &AM : AddrModes) {
4252 Value *DV = AM.GetFieldAsValue(DifferentField, IntPtrTy);
4255 if (CommonType && CommonType !=
Type)
4258 Map[AM.OriginalValue] = DV;
4263 assert(CommonType &&
"At least one non-null value must be!");
4264 for (
auto *V : NullValue)
4292 Value *findCommon(FoldAddrToValueMapping &Map) {
4300 SimplificationTracker
ST;
4305 InsertPlaceholders(Map, TraverseOrder, ST);
4308 FillPlaceholders(Map, TraverseOrder, ST);
4311 ST.destroyNewNodes(CommonType);
4316 unsigned PhiNotMatchedCount = 0;
4318 ST.destroyNewNodes(CommonType);
4322 auto *
Result =
ST.Get(
Map.find(Original)->second);
4324 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4325 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4332 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4333 SmallSetVector<PHIPair, 8> &Matcher,
4334 PhiNodeSet &PhiNodesToMatch) {
4337 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4340 SmallSet<PHIPair, 8> Visited;
4341 while (!WorkList.
empty()) {
4343 if (!Visited.
insert(Item).second)
4350 for (
auto *
B : Item.first->blocks()) {
4351 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4352 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4353 if (FirstValue == SecondValue)
4363 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4368 if (Matcher.
count({FirstPhi, SecondPhi}))
4373 if (MatchedPHIs.
insert(FirstPhi).second)
4374 Matcher.
insert({FirstPhi, SecondPhi});
4376 WorkList.
push_back({FirstPhi, SecondPhi});
4385 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4386 unsigned &PhiNotMatchedCount) {
4390 SmallSetVector<PHIPair, 8> Matched;
4391 SmallPtrSet<PHINode *, 8> WillNotMatch;
4392 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4393 while (PhiNodesToMatch.size()) {
4394 PHINode *
PHI = *PhiNodesToMatch.begin();
4397 WillNotMatch.
clear();
4401 bool IsMatched =
false;
4402 for (
auto &
P :
PHI->getParent()->phis()) {
4404 if (PhiNodesToMatch.count(&
P))
4406 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4416 for (
auto MV : Matched)
4417 ST.ReplacePhi(MV.first, MV.second);
4422 if (!AllowNewPhiNodes)
4425 PhiNotMatchedCount += WillNotMatch.
size();
4426 for (
auto *
P : WillNotMatch)
4427 PhiNodesToMatch.erase(
P);
4432 void FillPlaceholders(FoldAddrToValueMapping &Map,
4433 SmallVectorImpl<Value *> &TraverseOrder,
4434 SimplificationTracker &ST) {
4435 while (!TraverseOrder.
empty()) {
4437 assert(
Map.contains(Current) &&
"No node to fill!!!");
4443 auto *TrueValue = CurrentSelect->getTrueValue();
4444 assert(
Map.contains(TrueValue) &&
"No True Value!");
4445 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4446 auto *FalseValue = CurrentSelect->getFalseValue();
4447 assert(
Map.contains(FalseValue) &&
"No False Value!");
4448 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4455 assert(
Map.contains(PV) &&
"No predecessor Value!");
4456 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4467 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4468 SmallVectorImpl<Value *> &TraverseOrder,
4469 SimplificationTracker &ST) {
4472 "Address must be a Phi or Select node");
4475 while (!Worklist.
empty()) {
4478 if (
Map.contains(Current))
4489 CurrentSelect->getName(),
4490 CurrentSelect->getIterator(), CurrentSelect);
4494 Worklist.
push_back(CurrentSelect->getTrueValue());
4495 Worklist.
push_back(CurrentSelect->getFalseValue());
4503 ST.insertNewPhi(
PHI);
4509 bool addrModeCombiningAllowed() {
4512 switch (DifferentField) {
4515 case ExtAddrMode::BaseRegField:
4517 case ExtAddrMode::BaseGVField:
4519 case ExtAddrMode::BaseOffsField:
4521 case ExtAddrMode::ScaledRegField:
4531bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4536 return matchAddr(ScaleReg,
Depth);
4547 ExtAddrMode TestAddrMode =
AddrMode;
4551 TestAddrMode.
Scale += Scale;
4565 ConstantInt *CI =
nullptr;
4566 Value *AddLHS =
nullptr;
4570 TestAddrMode.InBounds =
false;
4587 auto GetConstantStep =
4588 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4591 return std::nullopt;
4594 return std::nullopt;
4602 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4603 return std::nullopt;
4605 return std::make_pair(IVInc->first, ConstantStep->getValue());
4606 return std::nullopt;
4621 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4628 APInt Step = IVStep->second;
4630 if (
Offset.isSignedIntN(64)) {
4631 TestAddrMode.InBounds =
false;
4633 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4638 getDTFn().
dominates(IVInc, MemoryInst)) {
4658 switch (
I->getOpcode()) {
4659 case Instruction::BitCast:
4660 case Instruction::AddrSpaceCast:
4662 if (
I->getType() ==
I->getOperand(0)->getType())
4664 return I->getType()->isIntOrPtrTy();
4665 case Instruction::PtrToInt:
4668 case Instruction::IntToPtr:
4671 case Instruction::Add:
4673 case Instruction::Mul:
4674 case Instruction::Shl:
4677 case Instruction::GetElementPtr:
4705class TypePromotionHelper {
4708 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4709 Instruction *ExtOpnd,
bool IsSExt) {
4710 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4711 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4715 if (It->second.getInt() == ExtTy)
4721 ExtTy = BothExtension;
4723 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4730 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4731 Instruction *Opnd,
bool IsSExt) {
4732 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4733 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4734 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4735 return It->second.getPointer();
4750 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4751 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4755 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4768 static Value *promoteOperandForTruncAndAnyExt(
4769 Instruction *Ext, TypePromotionTransaction &TPT,
4770 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4771 SmallVectorImpl<Instruction *> *Exts,
4772 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4783 static Value *promoteOperandForOther(Instruction *Ext,
4784 TypePromotionTransaction &TPT,
4785 InstrToOrigTy &PromotedInsts,
4786 unsigned &CreatedInstsCost,
4787 SmallVectorImpl<Instruction *> *Exts,
4788 SmallVectorImpl<Instruction *> *Truncs,
4789 const TargetLowering &TLI,
bool IsSExt);
4792 static Value *signExtendOperandForOther(
4793 Instruction *Ext, TypePromotionTransaction &TPT,
4794 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4795 SmallVectorImpl<Instruction *> *Exts,
4796 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4797 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4798 Exts, Truncs, TLI,
true);
4802 static Value *zeroExtendOperandForOther(
4803 Instruction *Ext, TypePromotionTransaction &TPT,
4804 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4805 SmallVectorImpl<Instruction *> *Exts,
4806 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4807 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4808 Exts, Truncs, TLI,
false);
4813 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4814 InstrToOrigTy &PromotedInsts,
4815 unsigned &CreatedInstsCost,
4816 SmallVectorImpl<Instruction *> *Exts,
4817 SmallVectorImpl<Instruction *> *Truncs,
4818 const TargetLowering &TLI);
4829 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4830 const TargetLowering &TLI,
4831 const InstrToOrigTy &PromotedInsts);
4836bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4837 Type *ConsideredExtType,
4838 const InstrToOrigTy &PromotedInsts,
4858 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4859 (IsSExt && BinOp->hasNoSignedWrap())))
4863 if ((Inst->
getOpcode() == Instruction::And ||
4868 if (Inst->
getOpcode() == Instruction::Xor) {
4871 if (!Cst->getValue().isAllOnes())
4880 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4890 if (ExtInst->hasOneUse()) {
4892 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4925 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4938TypePromotionHelper::Action TypePromotionHelper::getAction(
4939 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4940 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
4942 "Unexpected instruction type");
4949 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4962 return promoteOperandForTruncAndAnyExt;
4968 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4971Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4972 Instruction *SExt, TypePromotionTransaction &TPT,
4973 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4974 SmallVectorImpl<Instruction *> *Exts,
4975 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4979 Value *ExtVal = SExt;
4980 bool HasMergedNonFreeExt =
false;
4984 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
4987 TPT.replaceAllUsesWith(SExt, ZExt);
4988 TPT.eraseInstruction(SExt);
4993 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
4995 CreatedInstsCost = 0;
4999 TPT.eraseInstruction(SExtOpnd);
5007 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
5015 TPT.eraseInstruction(ExtInst, NextVal);
5019Value *TypePromotionHelper::promoteOperandForOther(
5020 Instruction *Ext, TypePromotionTransaction &TPT,
5021 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5022 SmallVectorImpl<Instruction *> *Exts,
5023 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
5028 CreatedInstsCost = 0;
5034 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
5037 ITrunc->moveAfter(ExtOpnd);
5042 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
5045 TPT.setOperand(Ext, 0, ExtOpnd);
5055 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
5057 TPT.mutateType(ExtOpnd,
Ext->getType());
5059 TPT.replaceAllUsesWith(Ext, ExtOpnd);
5066 !shouldExtOperand(ExtOpnd,
OpIdx)) {
5074 unsigned BitWidth =
Ext->getType()->getIntegerBitWidth();
5075 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
5077 TPT.setOperand(ExtOpnd,
OpIdx, ConstantInt::get(
Ext->getType(), CstVal));
5088 Value *ValForExtOpnd = IsSExt
5089 ? TPT.createSExt(ExtOpnd, Opnd,
Ext->getType())
5090 : TPT.createZExt(ExtOpnd, Opnd,
Ext->getType());
5091 TPT.setOperand(ExtOpnd,
OpIdx, ValForExtOpnd);
5093 if (!InstForExtOpnd)
5099 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5102 TPT.eraseInstruction(Ext);
5114bool AddressingModeMatcher::isPromotionProfitable(
5115 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5116 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5121 if (NewCost > OldCost)
5123 if (NewCost < OldCost)
5142bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5154 case Instruction::PtrToInt:
5157 case Instruction::IntToPtr: {
5165 case Instruction::BitCast:
5175 case Instruction::AddrSpaceCast: {
5183 case Instruction::Add: {
5186 ExtAddrMode BackupAddrMode =
AddrMode;
5187 unsigned OldSize = AddrModeInsts.
size();
5192 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5193 TPT.getRestorationPoint();
5197 int First = 0, Second = 1;
5208 AddrModeInsts.
resize(OldSize);
5209 TPT.rollback(LastKnownGood);
5219 AddrModeInsts.
resize(OldSize);
5220 TPT.rollback(LastKnownGood);
5226 case Instruction::Mul:
5227 case Instruction::Shl: {
5231 if (!
RHS ||
RHS->getBitWidth() > 64)
5233 int64_t Scale = Opcode == Instruction::Shl
5234 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5235 :
RHS->getSExtValue();
5239 case Instruction::GetElementPtr: {
5242 int VariableOperand = -1;
5243 unsigned VariableScale = 0;
5245 int64_t ConstantOffset = 0;
5247 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5249 const StructLayout *SL =
DL.getStructLayout(STy);
5260 if (ConstantInt *CI =
5262 const APInt &CVal = CI->
getValue();
5269 if (VariableOperand != -1)
5273 VariableOperand = i;
5274 VariableScale = TypeSize;
5281 if (VariableOperand == -1) {
5282 AddrMode.BaseOffs += ConstantOffset;
5288 AddrMode.BaseOffs -= ConstantOffset;
5292 ConstantOffset > 0) {
5305 BasicBlock *Parent = BaseI ? BaseI->getParent()
5306 : &
GEP->getFunction()->getEntryBlock();
5308 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5316 ExtAddrMode BackupAddrMode =
AddrMode;
5317 unsigned OldSize = AddrModeInsts.
size();
5320 AddrMode.BaseOffs += ConstantOffset;
5329 AddrModeInsts.
resize(OldSize);
5337 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5342 AddrModeInsts.
resize(OldSize);
5347 AddrMode.BaseOffs += ConstantOffset;
5348 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5349 VariableScale,
Depth)) {
5352 AddrModeInsts.
resize(OldSize);
5359 case Instruction::SExt:
5360 case Instruction::ZExt: {
5367 TypePromotionHelper::Action TPH =
5368 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5372 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5373 TPT.getRestorationPoint();
5374 unsigned CreatedInstsCost = 0;
5376 Value *PromotedOperand =
5377 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5392 assert(PromotedOperand &&
5393 "TypePromotionHelper should have filtered out those cases");
5395 ExtAddrMode BackupAddrMode =
AddrMode;
5396 unsigned OldSize = AddrModeInsts.
size();
5398 if (!matchAddr(PromotedOperand,
Depth) ||
5403 !isPromotionProfitable(CreatedInstsCost,
5404 ExtCost + (AddrModeInsts.
size() - OldSize),
5407 AddrModeInsts.
resize(OldSize);
5408 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5409 TPT.rollback(LastKnownGood);
5414 AddrMode.replaceWith(Ext, PromotedOperand);
5417 case Instruction::Call:
5419 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5435bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5438 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5439 TPT.getRestorationPoint();
5463 ExtAddrMode BackupAddrMode =
AddrMode;
5464 unsigned OldSize = AddrModeInsts.
size();
5467 bool MovedAway =
false;
5468 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5476 if (
I->hasOneUse() ||
5477 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5484 AddrModeInsts.
resize(OldSize);
5485 TPT.rollback(LastKnownGood);
5488 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5490 TPT.rollback(LastKnownGood);
5517 TPT.rollback(LastKnownGood);
5536 if (OpInfo.CallOperandVal == OpVal &&
5538 !OpInfo.isIndirect))
5554 if (!ConsideredInsts.
insert(
I).second)
5562 for (
Use &U :
I->uses()) {
5570 MemoryUses.push_back({&U, LI->getType()});
5577 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5584 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5591 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5601 if (!
find(PtrOps, U.get()))
5604 MemoryUses.push_back({&U, AccessTy});
5609 if (CI->hasFnAttr(Attribute::Cold)) {
5627 PSI, BFI, SeenInsts))
5638 unsigned SeenInsts = 0;
5641 PSI, BFI, SeenInsts);
5649bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5651 Value *KnownLive2) {
5653 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5694bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5695 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5696 if (IgnoreProfitability)
5714 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5715 ScaledReg =
nullptr;
5719 if (!BaseReg && !ScaledReg)
5740 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5743 Type *AddressAccessTy = Pair.second;
5744 unsigned AS =
Address->getType()->getPointerAddressSpace();
5750 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5752 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5753 TPT.getRestorationPoint();
5754 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5755 AddressAccessTy, AS, UserI, Result,
5756 InsertedInsts, PromotedInsts, TPT,
5757 LargeOffsetGEP, OptSize, PSI, BFI);
5758 Matcher.IgnoreProfitability =
true;
5766 TPT.rollback(LastKnownGood);
5772 MatchedAddrModeInsts.
clear();
5782 return I->getParent() != BB;
5798 return std::next(AddrInst->getIterator());
5809 Earliest = UserInst;
5834bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5835 Type *AccessTy,
unsigned AddrSpace) {
5840 SmallVector<Value *, 8> worklist;
5841 SmallPtrSet<Value *, 16> Visited;
5847 bool PhiOrSelectSeen =
false;
5848 SmallVector<Instruction *, 16> AddrModeInsts;
5849 AddressingModeCombiner AddrModes(*
DL, Addr);
5850 TypePromotionTransaction TPT(RemovedInsts);
5851 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5852 TPT.getRestorationPoint();
5853 while (!worklist.
empty()) {
5865 if (!Visited.
insert(V).second)
5871 PhiOrSelectSeen =
true;
5878 PhiOrSelectSeen =
true;
5885 AddrModeInsts.
clear();
5886 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5891 auto getDTFn = [MemoryInst,
this]() ->
const DominatorTree & {
5893 return this->getDT(*
F);
5895 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5896 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5897 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5900 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5905 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5906 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5909 NewAddrMode.OriginalValue =
V;
5910 if (!AddrModes.addNewAddrMode(NewAddrMode))
5917 if (!AddrModes.combineAddrModes()) {
5918 TPT.rollback(LastKnownGood);
5924 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5930 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5944 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
5966 <<
" for " << *MemoryInst <<
"\n");
5970 !
DL->isNonIntegralPointerType(Addr->
getType())) {
5976 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
5978 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
5980 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
5987 <<
" for " << *MemoryInst <<
"\n");
5988 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
5999 if (ResultPtr ||
AddrMode.Scale != 1)
6020 GlobalValue *BaseGV =
AddrMode.BaseGV;
6021 if (BaseGV !=
nullptr) {
6026 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
6035 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
6036 if (!ResultPtr &&
AddrMode.BaseReg) {
6040 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
6041 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
6050 }
else if (!ResultPtr) {
6063 if (
V->getType() != IntPtrTy)
6064 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6072 if (
V->getType() == IntPtrTy) {
6077 "We can't transform if ScaledReg is too narrow");
6078 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6082 V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy,
AddrMode.Scale),
6085 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6096 if (ResultPtr->
getType() != I8PtrTy)
6097 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6098 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6111 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6113 SunkAddr = ResultPtr;
6115 if (ResultPtr->
getType() != I8PtrTy)
6116 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6117 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6124 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6130 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
6132 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6134 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6144 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6145 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6146 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6148 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6152 <<
" for " << *MemoryInst <<
"\n");
6163 if (
V->getType()->isPointerTy())
6164 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6165 if (
V->getType() != IntPtrTy)
6166 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6173 if (
V->getType() == IntPtrTy) {
6175 }
else if (
V->getType()->isPointerTy()) {
6176 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6179 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6188 I->eraseFromParent();
6192 V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy,
AddrMode.Scale),
6195 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6201 GlobalValue *BaseGV =
AddrMode.BaseGV;
6202 if (BaseGV !=
nullptr) {
6205 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6209 Value *
V = Builder.CreatePtrToInt(BaseGVPtr, IntPtrTy,
"sunkaddr");
6211 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6220 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6228 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6234 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6239 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6240 RecursivelyDeleteTriviallyDeadInstructions(
6241 Repl, TLInfo, nullptr,
6242 [&](Value *V) { removeAllAssertingVHReferences(V); });
6266bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6272 if (!
GEP->hasIndices())
6280 SmallVector<Value *, 2>
Ops(
GEP->operands());
6282 bool RewriteGEP =
false;
6291 unsigned FinalIndex =
Ops.size() - 1;
6296 for (
unsigned i = 1; i < FinalIndex; ++i) {
6301 C =
C->getSplatValue();
6303 if (!CI || !CI->
isZero())
6310 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6314 if (!
C || !
C->isZero()) {
6315 Ops[FinalIndex] =
V;
6323 if (!RewriteGEP &&
Ops.size() == 2)
6330 Type *SourceTy =
GEP->getSourceElementType();
6331 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6335 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6336 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6337 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6347 if (
Ops.size() != 2) {
6357 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6371 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6372 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6375 Intrinsic::masked_gather) {
6379 Intrinsic::masked_scatter);
6394 Ptr, TLInfo,
nullptr,
6395 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6406 if (
I->hasNUsesOrMore(3))
6409 for (
User *U :
I->users()) {
6411 if (!Extract || Extract->getNumIndices() != 1)
6414 unsigned Index = Extract->getIndices()[0];
6416 MulExtract = Extract;
6417 else if (Index == 1)
6418 OverflowExtract = Extract;
6445bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
6446 ModifyDT &ModifiedDT) {
6453 ExtractValueInst *MulExtract =
nullptr, *OverflowExtract =
nullptr;
6458 InsertedInsts.insert(
I);
6468 I->getParent()->splitBasicBlock(
I,
"",
true);
6469 OverflowEntryBB->
takeName(
I->getParent());
6475 NoOverflowBB->
moveAfter(OverflowEntryBB);
6483 Value *LoLHS = Builder.CreateTrunc(
LHS, LegalTy,
"lo.lhs");
6484 Value *HiLHS = Builder.CreateLShr(
LHS, VTHalfBitWidth,
"lhs.lsr");
6485 HiLHS = Builder.CreateTrunc(HiLHS, LegalTy,
"hi.lhs");
6488 Value *LoRHS = Builder.CreateTrunc(
RHS, LegalTy,
"lo.rhs");
6489 Value *HiRHS = Builder.CreateLShr(
RHS, VTHalfBitWidth,
"rhs.lsr");
6490 HiRHS = Builder.CreateTrunc(HiRHS, LegalTy,
"hi.rhs");
6492 Value *IsAnyBitTrue;
6495 Builder.CreateAShr(LoLHS, VTHalfBitWidth - 1,
"sign.lo.lhs");
6497 Builder.CreateAShr(LoRHS, VTHalfBitWidth - 1,
"sign.lo.rhs");
6498 Value *XorLHS = Builder.CreateXor(HiLHS, SignLoLHS);
6499 Value *XorRHS = Builder.CreateXor(HiRHS, SignLoRHS);
6500 Value *
Or = Builder.CreateOr(XorLHS, XorRHS,
"or.lhs.rhs");
6501 IsAnyBitTrue = Builder.CreateCmp(ICmpInst::ICMP_NE,
Or,
6502 ConstantInt::getNullValue(
Or->getType()));
6504 Value *CmpLHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiLHS,
6505 ConstantInt::getNullValue(LegalTy));
6506 Value *CmpRHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiRHS,
6507 ConstantInt::getNullValue(LegalTy));
6508 IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS,
"or.lhs.rhs");
6510 Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
6513 Builder.SetInsertPoint(NoOverflowBB);
6514 Value *ExtLoLHS, *ExtLoRHS;
6516 ExtLoLHS = Builder.CreateSExt(LoLHS, Ty,
"lo.lhs.ext");
6517 ExtLoRHS = Builder.CreateSExt(LoRHS, Ty,
"lo.rhs.ext");
6519 ExtLoLHS = Builder.CreateZExt(LoLHS, Ty,
"lo.lhs.ext");
6520 ExtLoRHS = Builder.CreateZExt(LoRHS, Ty,
"lo.rhs.ext");
6523 Value *
Mul = Builder.CreateMul(ExtLoLHS, ExtLoRHS,
"mul.overflow.no");
6528 OverflowResBB->
setName(
"overflow.res");
6531 Builder.CreateBr(OverflowResBB);
6539 PHINode *OverflowResPHI = Builder.CreatePHI(Ty, 2),
6541 Builder.CreatePHI(IntegerType::getInt1Ty(
I->getContext()), 2);
6553 if (OverflowExtract) {
6554 OverflowExtract->replaceAllUsesWith(OverflowFlagPHI);
6555 OverflowExtract->eraseFromParent();
6560 I->removeFromParent();
6562 I->insertInto(OverflowBB, OverflowBB->
end());
6563 Builder.SetInsertPoint(OverflowBB, OverflowBB->
end());
6565 Value *OverflowFlag = Builder.CreateExtractValue(
I, {1},
"overflow.flag");
6566 Builder.CreateBr(OverflowResBB);
6570 OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
6572 ModifiedDT = ModifyDT::ModifyBBDT;
6578bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6579 bool MadeChange =
false;
6581 const TargetRegisterInfo *
TRI =
6586 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6592 OpInfo.isIndirect) {
6594 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6657bool CodeGenPrepare::tryToPromoteExts(
6658 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6659 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6660 unsigned CreatedInstsCost) {
6661 bool Promoted =
false;
6664 for (
auto *
I : Exts) {
6679 TypePromotionHelper::Action TPH =
6680 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6689 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6690 TPT.getRestorationPoint();
6691 SmallVector<Instruction *, 4> NewExts;
6692 unsigned NewCreatedInstsCost = 0;
6695 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6696 &NewExts,
nullptr, *TLI);
6698 "TypePromotionHelper should have filtered out those cases");
6708 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6711 TotalCreatedInstsCost =
6712 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6714 (TotalCreatedInstsCost > 1 ||
6716 (ExtCost == 0 && NewExts.
size() > 1))) {
6720 TPT.rollback(LastKnownGood);
6725 SmallVector<Instruction *, 2> NewlyMovedExts;
6726 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6727 bool NewPromoted =
false;
6728 for (
auto *ExtInst : NewlyMovedExts) {
6738 ProfitablyMovedExts.
push_back(MovedExt);
6745 TPT.rollback(LastKnownGood);
6756bool CodeGenPrepare::mergeSExts(Function &
F) {
6758 for (
auto &Entry : ValToSExtendedUses) {
6759 SExts &Insts =
Entry.second;
6761 for (Instruction *Inst : Insts) {
6765 bool inserted =
false;
6766 for (
auto &Pt : CurPts) {
6769 RemovedInsts.insert(Pt);
6770 Pt->removeFromParent();
6781 RemovedInsts.insert(Inst);
6788 CurPts.push_back(Inst);
6830bool CodeGenPrepare::splitLargeGEPOffsets() {
6832 for (
auto &Entry : LargeOffsetGEPMap) {
6834 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6835 &LargeOffsetGEPs =
Entry.second;
6836 auto compareGEPOffset =
6837 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6838 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6839 if (
LHS.first ==
RHS.first)
6841 if (
LHS.second !=
RHS.second)
6842 return LHS.second <
RHS.second;
6843 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6846 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6849 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6851 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6852 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6853 Value *NewBaseGEP =
nullptr;
6855 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6856 GetElementPtrInst *
GEP) {
6857 LLVMContext &Ctx =
GEP->getContext();
6858 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6860 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6872 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), DT.get(), LI);
6875 NewBaseInsertPt = std::next(BaseI->getIterator());
6882 IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
6884 Value *BaseIndex = ConstantInt::get(PtrIdxTy, BaseOffset);
6885 NewBaseGEP = OldBase;
6886 if (NewBaseGEP->
getType() != I8PtrTy)
6887 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6889 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6890 NewGEPBases.
insert(NewBaseGEP);
6896 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6897 BaseOffset = PreferBase;
6900 createNewBase(BaseOffset, OldBase, BaseGEP);
6903 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6904 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6905 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6906 int64_t
Offset = LargeOffsetGEP->second;
6907 if (
Offset != BaseOffset) {
6914 GEP->getResultElementType(),
6915 GEP->getAddressSpace())) {
6921 NewBaseGEP =
nullptr;
6926 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6931 createNewBase(BaseOffset, OldBase,
GEP);
6935 Value *NewGEP = NewBaseGEP;
6936 if (
Offset != BaseOffset) {
6939 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6943 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6944 GEP->eraseFromParent();
6951bool CodeGenPrepare::optimizePhiType(
6952 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
6953 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
6958 Type *PhiTy =
I->getType();
6959 Type *ConvertTy =
nullptr;
6961 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6964 SmallVector<Instruction *, 4> Worklist;
6966 SmallPtrSet<PHINode *, 4> PhiNodes;
6967 SmallPtrSet<ConstantData *, 4>
Constants;
6970 SmallPtrSet<Instruction *, 4> Defs;
6971 SmallPtrSet<Instruction *, 4>
Uses;
6977 bool AnyAnchored =
false;
6979 while (!Worklist.
empty()) {
6984 for (
Value *V :
Phi->incoming_values()) {
6986 if (!PhiNodes.
count(OpPhi)) {
6987 if (!Visited.
insert(OpPhi).second)
6993 if (!OpLoad->isSimple())
6995 if (Defs.
insert(OpLoad).second)
6998 if (Defs.
insert(OpEx).second)
7002 ConvertTy = OpBC->getOperand(0)->getType();
7003 if (OpBC->getOperand(0)->getType() != ConvertTy)
7005 if (Defs.
insert(OpBC).second) {
7018 for (User *V :
II->users()) {
7020 if (!PhiNodes.
count(OpPhi)) {
7021 if (Visited.
count(OpPhi))
7028 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
7030 Uses.insert(OpStore);
7033 ConvertTy = OpBC->getType();
7034 if (OpBC->getType() != ConvertTy)
7038 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
7045 if (!ConvertTy || !AnyAnchored ||
7049 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
7050 << *ConvertTy <<
"\n");
7055 for (ConstantData *
C : Constants)
7057 for (Instruction *
D : Defs) {
7059 ValMap[
D] =
D->getOperand(0);
7063 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
7066 for (PHINode *Phi : PhiNodes)
7068 Phi->getName() +
".tc",
Phi->getIterator());
7070 for (PHINode *Phi : PhiNodes) {
7072 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
7074 Phi->getIncomingBlock(i));
7078 for (Instruction *U :
Uses) {
7083 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
7093bool CodeGenPrepare::optimizePhiTypes(Function &
F) {
7098 SmallPtrSet<PHINode *, 4> Visited;
7099 SmallPtrSet<Instruction *, 4> DeletedInstrs;
7103 for (
auto &Phi : BB.
phis())
7104 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
7107 for (
auto *
I : DeletedInstrs) {
7109 I->eraseFromParent();
7117bool CodeGenPrepare::canFormExtLd(
7118 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
7119 Instruction *&Inst,
bool HasPromoted) {
7120 for (
auto *MovedExtInst : MovedExts) {
7123 Inst = MovedExtInst;
7175bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7176 bool AllowPromotionWithoutCommonHeader =
false;
7181 *Inst, AllowPromotionWithoutCommonHeader);
7182 TypePromotionTransaction TPT(RemovedInsts);
7183 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7184 TPT.getRestorationPoint();
7186 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7189 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7192 LoadInst *LI =
nullptr;
7197 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7198 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7203 Inst = ExtFedByLoad;
7208 if (ATPConsiderable &&
7209 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7210 HasPromoted, TPT, SpeculativelyMovedExts))
7213 TPT.rollback(LastKnownGood);
7222bool CodeGenPrepare::performAddressTypePromotion(
7223 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7224 bool HasPromoted, TypePromotionTransaction &TPT,
7225 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7226 bool Promoted =
false;
7227 SmallPtrSet<Instruction *, 1> UnhandledExts;
7228 bool AllSeenFirst =
true;
7229 for (
auto *
I : SpeculativelyMovedExts) {
7230 Value *HeadOfChain =
I->getOperand(0);
7231 DenseMap<Value *, Instruction *>::iterator AlreadySeen =
7232 SeenChainsForSExt.
find(HeadOfChain);
7235 if (AlreadySeen != SeenChainsForSExt.
end()) {
7236 if (AlreadySeen->second !=
nullptr)
7237 UnhandledExts.
insert(AlreadySeen->second);
7238 AllSeenFirst =
false;
7242 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7243 SpeculativelyMovedExts.size() == 1)) {
7247 for (
auto *
I : SpeculativelyMovedExts) {
7248 Value *HeadOfChain =
I->getOperand(0);
7249 SeenChainsForSExt[HeadOfChain] =
nullptr;
7250 ValToSExtendedUses[HeadOfChain].push_back(
I);
7253 Inst = SpeculativelyMovedExts.pop_back_val();
7258 for (
auto *
I : SpeculativelyMovedExts) {
7259 Value *HeadOfChain =
I->getOperand(0);
7260 SeenChainsForSExt[HeadOfChain] = Inst;
7265 if (!AllSeenFirst && !UnhandledExts.
empty())
7266 for (
auto *VisitedSExt : UnhandledExts) {
7267 if (RemovedInsts.count(VisitedSExt))
7269 TypePromotionTransaction TPT(RemovedInsts);
7271 SmallVector<Instruction *, 2> Chains;
7273 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7277 for (
auto *
I : Chains) {
7278 Value *HeadOfChain =
I->getOperand(0);
7280 SeenChainsForSExt[HeadOfChain] =
nullptr;
7281 ValToSExtendedUses[HeadOfChain].push_back(
I);
7287bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7292 Value *Src =
I->getOperand(0);
7293 if (Src->hasOneUse())
7305 bool DefIsLiveOut =
false;
7306 for (User *U :
I->users()) {
7311 if (UserBB == DefBB)
7313 DefIsLiveOut =
true;
7320 for (User *U : Src->users()) {
7323 if (UserBB == DefBB)
7332 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7334 bool MadeChange =
false;
7335 for (Use &U : Src->uses()) {
7340 if (UserBB == DefBB)
7344 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7346 if (!InsertedTrunc) {
7349 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7351 InsertedInsts.insert(InsertedTrunc);
7414bool CodeGenPrepare::optimizeLoadExt(LoadInst *Load) {
7415 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7419 if (
Load->hasOneUse() &&
7425 SmallVector<Instruction *, 8> WorkList;
7426 SmallPtrSet<Instruction *, 16> Visited;
7427 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7428 SmallVector<Instruction *, 8> DropFlags;
7429 for (
auto *U :
Load->users())
7441 while (!WorkList.
empty()) {
7445 if (!Visited.
insert(
I).second)
7450 for (
auto *U :
Phi->users())
7455 switch (
I->getOpcode()) {
7456 case Instruction::And: {
7460 APInt AndBits = AndC->getValue();
7461 DemandBits |= AndBits;
7463 if (AndBits.
ugt(WidestAndBits))
7464 WidestAndBits = AndBits;
7465 if (AndBits == WidestAndBits &&
I->getOperand(0) == Load)
7470 case Instruction::Shl: {
7474 uint64_t ShiftAmt = ShlC->getLimitedValue(
BitWidth - 1);
7475 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7480 case Instruction::Trunc: {
7483 DemandBits.setLowBits(TruncBitWidth);
7493 uint32_t ActiveBits = DemandBits.getActiveBits();
7505 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7506 WidestAndBits != DemandBits)
7509 LLVMContext &Ctx =
Load->getType()->getContext();
7510 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7520 Builder.CreateAnd(Load, ConstantInt::get(Ctx, DemandBits)));
7523 InsertedInsts.insert(NewAnd);
7528 NewAnd->setOperand(0, Load);
7531 for (
auto *
And : AndsToMaybeRemove)
7536 if (&*CurInstIterator ==
And)
7537 CurInstIterator = std::next(
And->getIterator());
7538 And->eraseFromParent();
7543 for (
auto *Inst : DropFlags)
7557 TTI->isExpensiveToSpeculativelyExecute(
I);
7575 uint64_t Max = std::max(TrueWeight, FalseWeight);
7576 uint64_t Sum = TrueWeight + FalseWeight;
7579 if (Probability >
TTI->getPredictableBranchThreshold())
7589 if (!Cmp || !Cmp->hasOneUse())
7612 assert(DefSI->getCondition() ==
SI->getCondition() &&
7613 "The condition of DefSI does not match with SI");
7614 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7617 assert(V &&
"Failed to get select true/false value");
7621bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7645 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7646 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7647 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7648 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7654bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7656 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7657 "Expected a funnel shift");
7681 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7682 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7683 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7691bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7703 It !=
SI->getParent()->
end(); ++It) {
7705 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7712 SelectInst *LastSI = ASI.
back();
7715 CurInstIterator = std::next(LastSI->
getIterator());
7719 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7720 fixupDbgVariableRecordsOnInst(*SI);
7722 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7725 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7728 TargetLowering::SelectSupportKind SelectKind;
7729 if (
SI->getType()->isVectorTy())
7730 SelectKind = TargetLowering::ScalarCondVectorVal;
7732 SelectKind = TargetLowering::ScalarValSelect;
7773 for (SelectInst *SI : ASI) {
7785 SplitPt.setHeadBit(
true);
7788 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7793 BranchInst *TrueBranch =
nullptr;
7794 BranchInst *FalseBranch =
nullptr;
7795 if (TrueInstrs.
size() == 0) {
7797 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7800 }
else if (FalseInstrs.
size() == 0) {
7802 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7809 nullptr,
nullptr, LI);
7817 EndBlock->
setName(
"select.end");
7819 TrueBlock->
setName(
"select.true.sink");
7821 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7822 :
"select.false.sink");
7826 FreshBBs.
insert(TrueBlock);
7828 FreshBBs.
insert(FalseBlock);
7829 FreshBBs.
insert(EndBlock);
7834 static const unsigned MD[] = {
7835 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7836 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7841 for (Instruction *
I : TrueInstrs)
7843 for (Instruction *
I : FalseInstrs)
7850 if (TrueBlock ==
nullptr)
7851 TrueBlock = StartBlock;
7852 else if (FalseBlock ==
nullptr)
7853 FalseBlock = StartBlock;
7869 SI->eraseFromParent();
7871 ++NumSelectsExpanded;
7875 CurInstIterator = StartBlock->
end();
7882bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7894 "Expected a type of the same size!");
7900 Builder.SetInsertPoint(SVI);
7901 Value *BC1 = Builder.CreateBitCast(
7903 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7904 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7908 SVI, TLInfo,
nullptr,
7909 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7916 !
Op->isTerminator() && !
Op->isEHPad())
7922bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7937 DenseMap<const Instruction *, unsigned long> InstOrdering;
7938 unsigned long InstNumber = 0;
7939 for (
const auto &
I : *TargetBB)
7940 InstOrdering[&
I] = InstNumber++;
7942 for (Use *U :
reverse(OpsToSink)) {
7947 if (InstOrdering[UI] < InstOrdering[InsertPoint])
7954 SetVector<Instruction *> MaybeDead;
7955 DenseMap<Instruction *, Instruction *> NewInstructions;
7956 for (Use *U : ToReplace) {
7965 FreshBBs.
insert(OpDef->getParent());
7968 NewInstructions[UI] = NI;
7973 InsertedInsts.insert(NI);
7979 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
7980 It->second->setOperand(
U->getOperandNo(), NI);
7987 for (
auto *
I : MaybeDead) {
7988 if (!
I->hasNUsesOrMore(1)) {
7990 I->eraseFromParent();
7997bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
8014 auto *NewType = Type::getIntNTy(
Context, RegWidth);
8023 ExtType = Instruction::SExt;
8026 if (Arg->hasSExtAttr())
8027 ExtType = Instruction::SExt;
8028 if (Arg->hasZExtAttr())
8029 ExtType = Instruction::ZExt;
8035 SI->setCondition(ExtInst);
8036 for (
auto Case :
SI->cases()) {
8037 const APInt &NarrowConst = Case.getCaseValue()->getValue();
8038 APInt WideConst = (ExtType == Instruction::ZExt)
8039 ? NarrowConst.
zext(RegWidth)
8040 : NarrowConst.
sext(RegWidth);
8041 Case.setValue(ConstantInt::get(
Context, WideConst));
8047bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
8054 Value *Condition =
SI->getCondition();
8063 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
8064 ConstantInt *CaseValue = Case.getCaseValue();
8065 BasicBlock *CaseBB = Case.getCaseSuccessor();
8068 bool CheckedForSinglePred =
false;
8069 for (PHINode &
PHI : CaseBB->
phis()) {
8070 Type *PHIType =
PHI.getType();
8078 if (PHIType == ConditionType || TryZExt) {
8080 bool SkipCase =
false;
8081 Value *Replacement =
nullptr;
8082 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
8083 Value *PHIValue =
PHI.getIncomingValue(
I);
8084 if (PHIValue != CaseValue) {
8093 if (
PHI.getIncomingBlock(
I) != SwitchBB)
8098 if (!CheckedForSinglePred) {
8099 CheckedForSinglePred =
true;
8100 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
8106 if (Replacement ==
nullptr) {
8107 if (PHIValue == CaseValue) {
8108 Replacement = Condition;
8111 Replacement = Builder.CreateZExt(Condition, PHIType);
8114 PHI.setIncomingValue(
I, Replacement);
8125bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
8126 bool Changed = optimizeSwitchType(SI);
8127 Changed |= optimizeSwitchPhiConstants(SI);
8148class VectorPromoteHelper {
8150 const DataLayout &
DL;
8153 const TargetLowering &TLI;
8156 const TargetTransformInfo &
TTI;
8162 SmallVector<Instruction *, 4> InstsToBePromoted;
8165 unsigned StoreExtractCombineCost;
8174 if (InstsToBePromoted.
empty())
8176 return InstsToBePromoted.
back();
8182 unsigned getTransitionOriginalValueIdx()
const {
8184 "Other kind of transitions are not supported yet");
8191 unsigned getTransitionIdx()
const {
8193 "Other kind of transitions are not supported yet");
8201 Type *getTransitionType()
const {
8212 void promoteImpl(Instruction *ToBePromoted);
8216 bool isProfitableToPromote() {
8217 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8221 Type *PromotedType = getTransitionType();
8224 unsigned AS =
ST->getPointerAddressSpace();
8242 for (
const auto &Inst : InstsToBePromoted) {
8250 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8262 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8263 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8264 return ScalarCost > VectorCost;
8276 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8291 if (!
EC.isScalable()) {
8294 for (
unsigned Idx = 0; Idx !=
EC.getKnownMinValue(); ++Idx) {
8295 if (Idx == ExtractIdx)
8303 "Generate scalable vector for non-splat is unimplemented");
8308 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8309 unsigned OperandIdx) {
8312 if (OperandIdx != 1)
8314 switch (
Use->getOpcode()) {
8317 case Instruction::SDiv:
8318 case Instruction::UDiv:
8319 case Instruction::SRem:
8320 case Instruction::URem:
8322 case Instruction::FDiv:
8323 case Instruction::FRem:
8324 return !
Use->hasNoNaNs();
8330 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8331 const TargetTransformInfo &
TTI, Instruction *Transition,
8332 unsigned CombineCost)
8333 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8334 StoreExtractCombineCost(CombineCost) {
8335 assert(Transition &&
"Do not know how to promote null");
8339 bool canPromote(
const Instruction *ToBePromoted)
const {
8346 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8349 for (
const Use &U : ToBePromoted->
operands()) {
8350 const Value *Val =
U.get();
8351 if (Val == getEndOfTransition()) {
8355 if (canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()))
8378 void enqueueForPromotion(Instruction *ToBePromoted) {
8379 InstsToBePromoted.push_back(ToBePromoted);
8383 void recordCombineInstruction(Instruction *ToBeCombined) {
8385 CombineInst = ToBeCombined;
8395 if (InstsToBePromoted.empty() || !CombineInst)
8403 for (
auto &ToBePromoted : InstsToBePromoted)
8404 promoteImpl(ToBePromoted);
8405 InstsToBePromoted.clear();
8412void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8422 "The type of the result of the transition does not match "
8427 Type *TransitionTy = getTransitionType();
8432 for (Use &U : ToBePromoted->
operands()) {
8434 Value *NewVal =
nullptr;
8435 if (Val == Transition)
8436 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8443 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8447 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8450 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8456bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8457 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8472 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8473 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost);
8480 if (ToBePromoted->
getParent() != Parent) {
8481 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8483 <<
") than the transition (" << Parent->
getName()
8488 if (VPH.canCombine(ToBePromoted)) {
8490 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8491 VPH.recordCombineInstruction(ToBePromoted);
8493 NumStoreExtractExposed +=
Changed;
8498 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8501 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8503 VPH.enqueueForPromotion(ToBePromoted);
8504 Inst = ToBePromoted;
8544 Type *StoreType =
SI.getValueOperand()->getType();
8553 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8554 DL.getTypeSizeInBits(StoreType) == 0)
8557 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8559 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8563 if (
SI.isVolatile())
8575 if (!
match(
SI.getValueOperand(),
8582 if (!
LValue->getType()->isIntegerTy() ||
8583 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8585 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8601 Builder.SetInsertPoint(&
SI);
8605 if (LBC && LBC->getParent() !=
SI.getParent())
8606 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8607 if (HBC && HBC->getParent() !=
SI.getParent())
8608 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8610 bool IsLE =
SI.getDataLayout().isLittleEndian();
8611 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8612 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8613 Value *Addr =
SI.getPointerOperand();
8614 Align Alignment =
SI.getAlign();
8615 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8616 if (IsOffsetStore) {
8617 Addr = Builder.CreateGEP(
8618 SplitStoreType, Addr,
8626 Builder.CreateAlignedStore(V, Addr, Alignment);
8629 CreateSplitStore(
LValue,
false);
8630 CreateSplitStore(HValue,
true);
8633 SI.eraseFromParent();
8641 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8723 if (GEPIOpI->getParent() != SrcBlock)
8728 if (auto *I = dyn_cast<Instruction>(Usr)) {
8729 if (I->getParent() != SrcBlock) {
8737 std::vector<GetElementPtrInst *> UGEPIs;
8740 for (User *Usr : GEPIOp->
users()) {
8759 if (UGEPI->getOperand(0) != GEPIOp)
8761 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8763 if (GEPIIdx->getType() !=
8771 UGEPIs.push_back(UGEPI);
8773 if (UGEPIs.size() == 0)
8776 for (GetElementPtrInst *UGEPI : UGEPIs) {
8778 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8785 for (GetElementPtrInst *UGEPI : UGEPIs) {
8786 UGEPI->setOperand(0, GEPI);
8788 Constant *NewUGEPIIdx = ConstantInt::get(
8789 GEPIIdx->getType(), UGEPIIdx->
getValue() - GEPIIdx->getValue());
8790 UGEPI->setOperand(1, NewUGEPIIdx);
8793 if (!GEPI->isInBounds()) {
8794 UGEPI->setIsInBounds(
false);
8801 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8803 "GEPIOp is used outside SrcBlock");
8827 Value *
X = Cmp->getOperand(0);
8828 if (!
X->hasUseList())
8833 for (
auto *U :
X->users()) {
8837 (UI->
getParent() != Branch->getParent() &&
8838 UI->
getParent() != Branch->getSuccessor(0) &&
8839 UI->
getParent() != Branch->getSuccessor(1)) ||
8840 (UI->
getParent() != Branch->getParent() &&
8841 !UI->
getParent()->getSinglePredecessor()))
8847 if (UI->
getParent() != Branch->getParent())
8851 ConstantInt::get(UI->
getType(), 0));
8853 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8857 if (Cmp->isEquality() &&
8862 if (UI->
getParent() != Branch->getParent())
8865 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8866 ConstantInt::get(UI->
getType(), 0));
8868 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8876bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8877 bool AnyChange =
false;
8878 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8882 if (InsertedInsts.count(
I))
8891 LargeOffsetGEPMap.erase(
P);
8893 P->eraseFromParent();
8916 I, LI->getLoopFor(
I->getParent()), *
TTI))
8924 TargetLowering::TypeExpandInteger) {
8928 I, LI->getLoopFor(
I->getParent()), *
TTI))
8931 bool MadeChange = optimizeExt(
I);
8932 return MadeChange | optimizeExtUses(
I);
8939 if (optimizeCmp(Cmp, ModifiedDT))
8943 if (optimizeURem(
I))
8947 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8948 bool Modified = optimizeLoadExt(LI);
8957 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8958 unsigned AS =
SI->getPointerAddressSpace();
8959 return optimizeMemoryInst(
I,
SI->getOperand(1),
8960 SI->getOperand(0)->getType(), AS);
8964 unsigned AS = RMW->getPointerAddressSpace();
8965 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
8969 unsigned AS = CmpX->getPointerAddressSpace();
8970 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
8971 CmpX->getCompareOperand()->getType(), AS);
8981 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
8982 BinOp->
getOpcode() == Instruction::LShr)) {
8990 if (GEPI->hasAllZeroIndices()) {
8992 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
8993 GEPI->getName(), GEPI->getIterator());
8994 NC->setDebugLoc(GEPI->getDebugLoc());
8997 GEPI, TLInfo,
nullptr,
8998 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9000 optimizeInst(
NC, ModifiedDT);
9023 if (Const0 || Const1) {
9024 if (!Const0 || !Const1) {
9025 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
9030 FI->eraseFromParent();
9037 if (tryToSinkFreeOperands(
I))
9040 switch (
I->getOpcode()) {
9041 case Instruction::Shl:
9042 case Instruction::LShr:
9043 case Instruction::AShr:
9045 case Instruction::Call:
9047 case Instruction::Select:
9049 case Instruction::ShuffleVector:
9051 case Instruction::Switch:
9053 case Instruction::ExtractElement:
9055 case Instruction::Br:
9064bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
9065 if (!
I.getType()->isIntegerTy() ||
9070 SmallVector<Instruction *, 4> Insts;
9076 &
I, TLInfo,
nullptr,
9077 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9084bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
9086 bool MadeChange =
false;
9089 CurInstIterator = BB.
begin();
9090 ModifiedDT = ModifyDT::NotModifyDT;
9091 while (CurInstIterator != BB.
end()) {
9092 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
9093 if (ModifiedDT != ModifyDT::NotModifyDT) {
9106 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
9108 bool MadeBitReverse =
true;
9109 while (MadeBitReverse) {
9110 MadeBitReverse =
false;
9112 if (makeBitReverse(
I)) {
9113 MadeBitReverse = MadeChange =
true;
9118 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
9123bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
9124 bool AnyChange =
false;
9125 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
9126 AnyChange |= fixupDbgVariableRecord(DVR);
9132bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
9133 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
9134 DVR.
Type != DbgVariableRecord::LocationType::Assign)
9138 bool AnyChange =
false;
9139 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
9141 for (
Value *Location : LocationOps) {
9142 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9171bool CodeGenPrepare::placeDbgValues(Function &
F) {
9172 bool MadeChange =
false;
9173 DominatorTree DT(
F);
9175 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9176 SmallVector<Instruction *, 4> VIs;
9177 for (
Value *V : DbgItem->location_ops())
9185 for (Instruction *VI : VIs) {
9186 if (
VI->isTerminator())
9191 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9202 if (VIs.size() > 1) {
9205 <<
"Unable to find valid location for Debug Value, undefing:\n"
9207 DbgItem->setKillLocation();
9212 << *DbgItem <<
' ' << *VI);
9219 for (BasicBlock &BB :
F) {
9225 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9227 DbgProcessor(&DVR, &Insn);
9238bool CodeGenPrepare::placePseudoProbes(Function &
F) {
9239 bool MadeChange =
false;
9242 auto FirstInst =
Block.getFirstInsertionPt();
9243 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9247 while (
I !=
Block.end()) {
9249 II->moveBefore(FirstInst);
9259 uint64_t NewMax = (NewTrue > NewFalse) ? NewTrue : NewFalse;
9260 uint32_t Scale = (NewMax / std::numeric_limits<uint32_t>::max()) + 1;
9261 NewTrue = NewTrue / Scale;
9262 NewFalse = NewFalse / Scale;
9287bool CodeGenPrepare::splitBranchCondition(Function &
F, ModifyDT &ModifiedDT) {
9291 bool MadeChange =
false;
9292 for (
auto &BB :
F) {
9305 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9313 Value *Cond1, *Cond2;
9316 Opc = Instruction::And;
9319 Opc = Instruction::Or;
9329 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9343 Br1->setCondition(Cond1);
9348 if (
Opc == Instruction::And)
9349 Br1->setSuccessor(0, TmpBB);
9351 Br1->setSuccessor(1, TmpBB);
9356 I->removeFromParent();
9357 I->insertBefore(Br2->getIterator());
9369 if (
Opc == Instruction::Or)
9376 for (PHINode &PN : FBB->
phis()) {
9383 if (
Opc == Instruction::Or) {
9403 uint64_t TrueWeight, FalseWeight;
9405 uint64_t NewTrueWeight = TrueWeight;
9406 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9408 Br1->setMetadata(LLVMContext::MD_prof,
9409 MDBuilder(Br1->getContext())
9410 .createBranchWeights(TrueWeight, FalseWeight,
9413 NewTrueWeight = TrueWeight;
9414 NewFalseWeight = 2 * FalseWeight;
9416 Br2->setMetadata(LLVMContext::MD_prof,
9417 MDBuilder(Br2->getContext())
9418 .createBranchWeights(TrueWeight, FalseWeight));
9439 uint64_t TrueWeight, FalseWeight;
9441 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9442 uint64_t NewFalseWeight = FalseWeight;
9444 Br1->setMetadata(LLVMContext::MD_prof,
9445 MDBuilder(Br1->getContext())
9446 .createBranchWeights(TrueWeight, FalseWeight));
9448 NewTrueWeight = 2 * TrueWeight;
9449 NewFalseWeight = FalseWeight;
9451 Br2->setMetadata(LLVMContext::MD_prof,
9452 MDBuilder(Br2->getContext())
9453 .createBranchWeights(TrueWeight, FalseWeight));
9457 ModifiedDT = ModifyDT::ModifyBBDT;
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 void scaleWeights(uint64_t &NewTrue, uint64_t &NewFalse)
Scale down both weights to fit into uint32_t.
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(BranchInst *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 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 bool despeculateCountZeros(IntrinsicInst *CountZeros, 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 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 defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
static Value * getCondition(Instruction *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 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 TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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 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.
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
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()
ArrayRef - 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.
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 BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
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 SymbolTableList< BasicBlock >::iterator eraseFromParent()
Unlink 'this' from the containing function and delete it.
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 if the block is well formed or null if the block is not well forme...
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.
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.
Conditional or Unconditional Branch instruction.
LLVM_ABI void swapSuccessors()
Swap the successors of this branch instruction.
bool isConditional() const
BasicBlock * getSuccessor(unsigned i) const
bool isUnconditional() const
Analysis providing branch probability information.
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...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
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)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
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 bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
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...
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.
Type * getValueType() const
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This instruction compares its operands according to the predicate given to the constructor.
bool isEquality() const
Return true if this predicate is either EQ or NE.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
LLVM_ABI bool isDebugOrPseudoInst() const LLVM_READONLY
Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void moveAfter(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
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.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
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.
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
iterator find(const KeyT &Key)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
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...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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.
bool isFunctionColdInCallGraph(const FuncT *F, BFIT &BFI) const
Returns true if F contains only cold code.
LLVM_ABI bool isFunctionHotnessUnknown(const Function &F) const
Returns true if the hotness of F is unknown.
bool isFunctionHotInCallGraph(const FuncT *F, BFIT &BFI) const
Returns true if F contains hot code.
LLVM_ABI bool hasPartialSampleProfile() const
Returns true if module M has partial-profile sample profile.
LLVM_ABI bool hasHugeWorkingSetSize() const
Returns true if the working set size of the code is considered huge.
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)
void clear()
Completely clear the SetVector.
size_type count(const key_type &key) const
Count the number of elements of a given key in 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...
bool isLoadExtLegal(unsigned ExtType, EVT ValVT, EVT MemVT) const
Return true if the specified load with extension is legal on this target.
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...
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)
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.
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.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
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)
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
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)
bind_ty< 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)
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
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.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
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.
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)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale)
Compare two scaled numbers.
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ Assume
Do not drop type tests (default).
@ 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)
FunctionAddr VTableAddr Value
std::enable_if_t< std::is_signed_v< T >, T > MulOverflow(T X, T Y, T &Result)
Multiply two signed integers, computing the two's complement truncated result, returning true if an o...
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)
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 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.
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...
auto cast_or_null(const Y &Val)
LLVM_ABI void DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, bool KeepOneInputPHIs=false)
Delete the specified block, which must have no predecessors.
LLVM_ABI void initializeCodeGenPrepareLegacyPassPass(PassRegistry &)
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.
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 SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr)
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 DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Examine each PHI in the given block and delete it if it is dead.
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...
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.
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.
FunctionAddr VTableAddr Next
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 >
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.
bool bypassSlowDivision(BasicBlock *BB, const DenseMap< unsigned int, unsigned int > &BypassWidth)
This optimization identifies DIV instructions in a BB that can be profitably bypassed and carried out...
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)
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
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.
bool pred_empty(const BasicBlock *BB)
std::enable_if_t< std::is_signed_v< T >, T > AddOverflow(T X, T Y, T &Result)
Add two signed integers, computing the two's complement truncated result, returning true if overflow ...
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...
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()
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.