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 BlockFrequencyInfo *BFI;
317 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();
392 template <
typename F>
393 void resetIteratorIfInvalidatedWhileCalling(BasicBlock *BB,
F f) {
397 Value *CurValue = &*CurInstIterator;
398 WeakTrackingVH IterHandle(CurValue);
404 if (IterHandle != CurValue) {
405 CurInstIterator = BB->
begin();
411 DominatorTree &getDT(Function &
F) {
413 DT = std::make_unique<DominatorTree>(
F);
417 void removeAllAssertingVHReferences(
Value *V);
418 bool eliminateAssumptions(Function &
F);
419 bool eliminateFallThrough(Function &
F, DominatorTree *DT =
nullptr);
420 bool eliminateMostlyEmptyBlocks(Function &
F);
421 BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB);
422 bool canMergeBlocks(
const BasicBlock *BB,
const BasicBlock *DestBB)
const;
423 void eliminateMostlyEmptyBlock(BasicBlock *BB);
424 bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB,
426 bool makeBitReverse(Instruction &
I);
428 bool optimizeInst(Instruction *
I, ModifyDT &ModifiedDT);
429 bool optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
Type *AccessTy,
431 bool optimizeGatherScatterInst(Instruction *MemoryInst,
Value *Ptr);
432 bool optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
433 ModifyDT &ModifiedDT);
434 bool optimizeInlineAsmInst(CallInst *CS);
436 bool optimizeExt(Instruction *&
I);
437 bool optimizeExtUses(Instruction *
I);
438 bool optimizeLoadExt(LoadInst *Load);
439 bool optimizeShiftInst(BinaryOperator *BO);
440 bool optimizeFunnelShift(IntrinsicInst *Fsh);
441 bool optimizeSelectInst(SelectInst *SI);
442 bool optimizeShuffleVectorInst(ShuffleVectorInst *SVI);
443 bool optimizeSwitchType(SwitchInst *SI);
444 bool optimizeSwitchPhiConstants(SwitchInst *SI);
445 bool optimizeSwitchInst(SwitchInst *SI);
446 bool optimizeExtractElementInst(Instruction *Inst);
447 bool dupRetToEnableTailCallOpts(BasicBlock *BB, ModifyDT &ModifiedDT);
448 bool fixupDbgVariableRecord(DbgVariableRecord &
I);
449 bool fixupDbgVariableRecordsOnInst(Instruction &
I);
450 bool placeDbgValues(Function &
F);
451 bool placePseudoProbes(Function &
F);
452 bool canFormExtLd(
const SmallVectorImpl<Instruction *> &MovedExts,
453 LoadInst *&LI, Instruction *&Inst,
bool HasPromoted);
454 bool tryToPromoteExts(TypePromotionTransaction &TPT,
455 const SmallVectorImpl<Instruction *> &Exts,
456 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
457 unsigned CreatedInstsCost = 0);
458 bool mergeSExts(Function &
F);
459 bool splitLargeGEPOffsets();
460 bool optimizePhiType(PHINode *Inst, SmallPtrSetImpl<PHINode *> &Visited,
461 SmallPtrSetImpl<Instruction *> &DeletedInstrs);
462 bool optimizePhiTypes(Function &
F);
463 bool performAddressTypePromotion(
464 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
465 bool HasPromoted, TypePromotionTransaction &TPT,
466 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts);
467 bool splitBranchCondition(Function &
F, ModifyDT &ModifiedDT);
468 bool simplifyOffsetableRelocate(GCStatepointInst &
I);
470 bool tryToSinkFreeOperands(Instruction *
I);
471 bool replaceMathCmpWithIntrinsic(BinaryOperator *BO,
Value *Arg0,
Value *Arg1,
473 bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT);
474 bool optimizeURem(Instruction *Rem);
475 bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
476 bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
477 bool unfoldPowerOf2Test(CmpInst *Cmp);
478 void verifyBFIUpdates(Function &
F);
479 bool _run(Function &
F);
486 CodeGenPrepareLegacyPass() : FunctionPass(ID) {}
490 StringRef getPassName()
const override {
return "CodeGen Prepare"; }
492 void getAnalysisUsage(AnalysisUsage &AU)
const override {
499 AU.
addRequired<BranchProbabilityInfoWrapperPass>();
507char CodeGenPrepareLegacyPass::ID = 0;
509bool CodeGenPrepareLegacyPass::runOnFunction(
Function &
F) {
512 auto TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
513 CodeGenPrepare CGP(TM);
514 CGP.DL = &
F.getDataLayout();
517 CGP.TRI = CGP.SubtargetInfo->getRegisterInfo();
518 CGP.TLInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
519 CGP.TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
520 CGP.LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
521 CGP.BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
522 CGP.BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
523 CGP.PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
525 getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
526 CGP.BBSectionsProfileReader = BBSPRWP ? &BBSPRWP->getBBSPR() :
nullptr;
532 "Optimize for code generation",
false,
false)
543 return new CodeGenPrepareLegacyPass();
548 CodeGenPrepare CGP(TM);
561 DL = &
F.getDataLayout();
572 BBSectionsProfileReader =
578 bool EverMadeChange =
false;
580 OptSize =
F.hasOptSize();
585 (void)
F.setSectionPrefix(
"hot");
590 if (
F.hasFnAttribute(Attribute::Hot) ||
592 (void)
F.setSectionPrefix(
"hot");
597 F.hasFnAttribute(Attribute::Cold))
598 (void)
F.setSectionPrefix(
"unlikely");
601 (void)
F.setSectionPrefix(
"unknown");
607 const DenseMap<unsigned int, unsigned int> &BypassWidths =
610 while (BB !=
nullptr) {
623 EverMadeChange |= eliminateAssumptions(
F);
627 EverMadeChange |= eliminateMostlyEmptyBlocks(
F);
629 ModifyDT ModifiedDT = ModifyDT::NotModifyDT;
631 EverMadeChange |= splitBranchCondition(
F, ModifiedDT);
647 bool MadeChange =
true;
648 bool FuncIterated =
false;
653 if (FuncIterated && !FreshBBs.
contains(&BB))
656 ModifyDT ModifiedDTOnIteration = ModifyDT::NotModifyDT;
659 if (ModifiedDTOnIteration == ModifyDT::ModifyBBDT)
675 else if (FuncIterated)
680 if (ModifiedDTOnIteration != ModifyDT::NotModifyDT)
685 FuncIterated = IsHugeFunc;
688 MadeChange |= mergeSExts(
F);
689 if (!LargeOffsetGEPMap.
empty())
690 MadeChange |= splitLargeGEPOffsets();
691 MadeChange |= optimizePhiTypes(
F);
694 eliminateFallThrough(
F, DT.get());
702 for (Instruction *
I : RemovedInsts)
705 EverMadeChange |= MadeChange;
706 SeenChainsForSExt.
clear();
707 ValToSExtendedUses.clear();
708 RemovedInsts.clear();
709 LargeOffsetGEPMap.
clear();
710 LargeOffsetGEPID.
clear();
721 SmallSetVector<BasicBlock *, 8> WorkList;
722 for (BasicBlock &BB :
F) {
728 for (BasicBlock *Succ : Successors)
734 MadeChange |= !WorkList.
empty();
735 while (!WorkList.
empty()) {
741 for (BasicBlock *Succ : Successors)
748 if (EverMadeChange || MadeChange)
749 MadeChange |= eliminateFallThrough(
F);
751 EverMadeChange |= MadeChange;
756 for (BasicBlock &BB :
F)
757 for (Instruction &
I : BB)
760 for (
auto &
I : Statepoints)
761 EverMadeChange |= simplifyOffsetableRelocate(*
I);
766 EverMadeChange |= placeDbgValues(
F);
767 EverMadeChange |= placePseudoProbes(
F);
774 return EverMadeChange;
777bool CodeGenPrepare::eliminateAssumptions(Function &
F) {
778 bool MadeChange =
false;
779 for (BasicBlock &BB :
F) {
780 CurInstIterator = BB.begin();
781 while (CurInstIterator != BB.end()) {
786 Assume->eraseFromParent();
788 resetIteratorIfInvalidatedWhileCalling(&BB, [&]() {
799void CodeGenPrepare::removeAllAssertingVHReferences(
Value *V) {
800 LargeOffsetGEPMap.
erase(V);
801 NewGEPBases.
erase(V);
809 auto VecI = LargeOffsetGEPMap.
find(
GEP->getPointerOperand());
810 if (VecI == LargeOffsetGEPMap.
end())
813 auto &GEPVector = VecI->second;
816 if (GEPVector.empty())
817 LargeOffsetGEPMap.
erase(VecI);
821[[maybe_unused]]
void CodeGenPrepare::verifyBFIUpdates(Function &
F) {
822 DominatorTree NewDT(
F);
823 LoopInfo NewLI(NewDT);
824 BranchProbabilityInfo NewBPI(
F, NewLI, TLInfo);
825 BlockFrequencyInfo NewBFI(
F, NewBPI, NewLI);
826 NewBFI.verifyMatch(*BFI);
832bool CodeGenPrepare::eliminateFallThrough(Function &
F, DominatorTree *DT) {
840 SmallSet<WeakTrackingVH, 16> Preds;
841 for (
auto &
Block : Blocks) {
847 BasicBlock *SinglePred = BB->getSinglePredecessor();
850 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
869 FreshBBs.
insert(SinglePred);
877 for (
const auto &Pred : Preds)
885BasicBlock *CodeGenPrepare::findDestBlockOfMergeableEmptyBlock(BasicBlock *BB) {
894 if (BBI != BB->
begin()) {
905 if (!canMergeBlocks(BB, DestBB))
915bool CodeGenPrepare::eliminateMostlyEmptyBlocks(Function &
F) {
916 SmallPtrSet<BasicBlock *, 16> Preheaders;
918 while (!LoopList.empty()) {
919 Loop *
L = LoopList.pop_back_val();
921 if (BasicBlock *Preheader =
L->getLoopPreheader())
922 Preheaders.
insert(Preheader);
925 bool MadeChange =
false;
937 for (
auto &
Block : Blocks) {
941 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
943 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.
count(BB)))
946 eliminateMostlyEmptyBlock(BB);
952bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB,
1003 SmallPtrSet<BasicBlock *, 16> SameIncomingValueBBs;
1008 if (DestBBPred == BB)
1012 return DestPN.getIncomingValueForBlock(BB) ==
1013 DestPN.getIncomingValueForBlock(DestBBPred);
1015 SameIncomingValueBBs.
insert(DestBBPred);
1021 if (SameIncomingValueBBs.
count(Pred))
1027 for (
auto *SameValueBB : SameIncomingValueBBs)
1028 if (SameValueBB->getUniquePredecessor() == Pred &&
1029 DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
1033 return !Limit || PredFreq <= *Limit;
1039bool CodeGenPrepare::canMergeBlocks(
const BasicBlock *BB,
1040 const BasicBlock *DestBB)
const {
1044 for (
const PHINode &PN : BB->
phis()) {
1045 for (
const User *U : PN.users()) {
1054 for (
unsigned I = 0,
E = UPN->getNumIncomingValues();
I !=
E; ++
I) {
1057 Insn->
getParent() != UPN->getIncomingBlock(
I))
1072 SmallPtrSet<const BasicBlock *, 16> BBPreds;
1075 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1076 BBPreds.
insert(BBPN->getIncomingBlock(i));
1084 if (BBPreds.
count(Pred)) {
1085 for (
const PHINode &PN : DestBB->
phis()) {
1086 const Value *V1 = PN.getIncomingValueForBlock(Pred);
1087 const Value *V2 = PN.getIncomingValueForBlock(BB);
1091 if (V2PN->getParent() == BB)
1092 V2 = V2PN->getIncomingValueForBlock(Pred);
1122void CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
1132 if (SinglePred != DestBB) {
1133 assert(SinglePred == BB &&
1134 "Single predecessor not the same as predecessor");
1143 FreshBBs.
insert(SinglePred);
1144 FreshBBs.
erase(DestBB);
1152 for (PHINode &PN : DestBB->
phis()) {
1154 Value *InVal = PN.removeIncomingValue(BB,
false);
1159 if (InValPhi && InValPhi->
getParent() == BB) {
1168 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1169 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1172 PN.addIncoming(InVal, Pred);
1202 for (
auto *ThisRelocate : AllRelocateCalls) {
1203 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1204 ThisRelocate->getDerivedPtrIndex());
1205 RelocateIdxMap.
insert(std::make_pair(K, ThisRelocate));
1207 for (
auto &Item : RelocateIdxMap) {
1208 std::pair<unsigned, unsigned>
Key = Item.first;
1209 if (
Key.first ==
Key.second)
1214 auto BaseKey = std::make_pair(
Key.first,
Key.first);
1217 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1218 if (MaybeBase == RelocateIdxMap.
end())
1223 RelocateInstMap[MaybeBase->second].push_back(
I);
1231 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1234 if (!
Op ||
Op->getZExtValue() > 20)
1238 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1248 bool MadeChange =
false;
1255 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1256 &*R != RelocatedBase; ++R)
1260 RelocatedBase->
moveBefore(RI->getIterator());
1267 "Not relocating a derived object of the original base object");
1268 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1273 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1283 if (!Derived || Derived->getPointerOperand() !=
Base)
1292 "Should always have one since it's not a terminator");
1296 Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
1320 Value *ActualRelocatedBase = RelocatedBase;
1321 if (RelocatedBase->
getType() !=
Base->getType()) {
1322 ActualRelocatedBase =
1323 Builder.CreateBitCast(RelocatedBase,
Base->getType());
1325 Value *Replacement =
1326 Builder.CreateGEP(Derived->getSourceElementType(), ActualRelocatedBase,
1332 Value *ActualReplacement = Replacement;
1333 if (Replacement->
getType() != ToReplace->getType()) {
1335 Builder.CreateBitCast(Replacement, ToReplace->
getType());
1338 ToReplace->eraseFromParent();
1362bool CodeGenPrepare::simplifyOffsetableRelocate(GCStatepointInst &
I) {
1363 bool MadeChange =
false;
1365 for (
auto *U :
I.users())
1372 if (AllRelocateCalls.
size() < 2)
1377 MapVector<GCRelocateInst *, SmallVector<GCRelocateInst *, 0>> RelocateInstMap;
1379 if (RelocateInstMap.
empty())
1382 for (
auto &Item : RelocateInstMap)
1396 bool MadeChange =
false;
1399 Use &TheUse = UI.getUse();
1406 UserBB = PN->getIncomingBlock(TheUse);
1414 if (
User->isEHPad())
1424 if (UserBB == DefBB)
1428 CastInst *&InsertedCast = InsertedCasts[UserBB];
1430 if (!InsertedCast) {
1438 TheUse = InsertedCast;
1464 ASC->getDestAddressSpace()))
1519static std::optional<std::pair<Instruction *, Constant *>>
1522 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1523 return std::nullopt;
1526 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1527 return std::nullopt;
1531 return std::make_pair(IVInc, Step);
1532 return std::nullopt;
1545 return IVInc->first ==
I;
1549bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
1553 auto IsReplacableIVIncrement = [
this, &
Cmp](BinaryOperator *BO) {
1557 assert(L &&
"L should not be null after isIVIncrement()");
1565 auto &DT = getDT(*BO->
getParent()->getParent());
1574 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1597 if (BO->
getOpcode() == Instruction::Add &&
1598 IID == Intrinsic::usub_with_overflow) {
1605 for (Instruction &Iter : *
Cmp->getParent()) {
1608 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1613 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1616 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1617 if (BO->
getOpcode() != Instruction::Xor) {
1618 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1622 "Patterns with XOr should use the BO only in the compare");
1623 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1625 Cmp->eraseFromParent();
1635 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1643 B = ConstantInt::get(
B->getType(), 1);
1651 for (
User *U :
A->users()) {
1662bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp,
1663 ModifyDT &ModifiedDT) {
1664 bool EdgeCase =
false;
1666 BinaryOperator *
Add;
1671 A =
Add->getOperand(0);
1672 B =
Add->getOperand(1);
1678 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1684 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1687 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1688 Intrinsic::uadd_with_overflow))
1692 ModifiedDT = ModifyDT::ModifyInstDT;
1696bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
1697 ModifyDT &ModifiedDT) {
1704 ICmpInst::Predicate Pred =
Cmp->getPredicate();
1705 if (Pred == ICmpInst::ICMP_UGT) {
1707 Pred = ICmpInst::ICMP_ULT;
1711 B = ConstantInt::get(
B->getType(), 1);
1712 Pred = ICmpInst::ICMP_ULT;
1717 Pred = ICmpInst::ICMP_ULT;
1719 if (Pred != ICmpInst::ICMP_ULT)
1726 BinaryOperator *
Sub =
nullptr;
1727 for (User *U : CmpVariableOperand->
users()) {
1735 const APInt *CmpC, *AddC;
1747 Sub->hasNUsesOrMore(1)))
1753 if (
Sub->getParent() !=
Cmp->getParent() && !
Sub->hasOneUse())
1756 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1757 Cmp, Intrinsic::usub_with_overflow))
1761 ModifiedDT = ModifyDT::ModifyInstDT;
1768bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1782 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1788 Type *OpTy =
X->getType();
1796 if (Pred == ICmpInst::ICMP_EQ) {
1797 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1798 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1800 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1806 if (IsPowerOf2OrZeroTest ||
1817 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1826 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1829 Cmp->replaceAllUsesWith(NewCmp);
1849 bool UsedInPhiOrCurrentBlock =
any_of(Cmp->users(), [Cmp](
User *U) {
1850 return isa<PHINode>(U) ||
1851 cast<Instruction>(U)->getParent() == Cmp->getParent();
1856 if (UsedInPhiOrCurrentBlock && Cmp->getOperand(0)->getType()->isIntegerTy() &&
1857 Cmp->getOperand(0)->getType()->getScalarSizeInBits() >
1858 DL.getLargestLegalIntTypeSizeInBits())
1864 bool MadeChange =
false;
1867 Use &TheUse = UI.getUse();
1882 if (UserBB == DefBB)
1886 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1892 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1899 TheUse = InsertedCmp;
1905 if (Cmp->use_empty()) {
1906 Cmp->eraseFromParent();
1943 for (
User *U : Cmp->users()) {
1965 if (CmpBB != FalseBB)
1968 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
1982 for (
User *U : Cmp->users()) {
1984 BI->swapSuccessors();
1990 SI->swapProfMetadata();
2002 Value *Op0 = Cmp->getOperand(0);
2003 Value *Op1 = Cmp->getOperand(1);
2012 unsigned NumInspected = 0;
2015 if (++NumInspected > 128)
2023 if (GoodToSwap > 0) {
2024 Cmp->swapOperands();
2044 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
2047 auto [ClassVal, ClassTest] =
2053 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2057 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
2058 Cmp->replaceAllUsesWith(IsFPClass);
2066 Value *Incr, *RemAmt;
2071 Value *AddInst, *AddOffset;
2074 if (PN !=
nullptr) {
2076 AddOffset =
nullptr;
2085 if (PN !=
nullptr) {
2098 if (PN->getNumIncomingValues() != 2)
2103 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2107 if (!L->contains(Rem))
2111 if (!L->isLoopInvariant(RemAmt))
2115 if (AddOffset && !L->isLoopInvariant(AddOffset))
2136 AddInstOut = AddInst;
2137 AddOffsetOut = AddOffset;
2156 Value *AddOffset, *RemAmt, *AddInst;
2159 AddOffset, LoopIncrPN))
2184 assert(AddOffset &&
"We found an add but missing values");
2203 Builder.SetInsertPoint(LoopIncrPN);
2204 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2209 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2214 NewRem->
addIncoming(Start, L->getLoopPreheader());
2219 FreshBBs.
insert(L->getLoopLatch());
2230bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2236bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2240 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2243 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2246 if (unfoldPowerOf2Test(Cmp))
2267 SetOfInstrs &InsertedInsts) {
2270 assert(!InsertedInsts.count(AndI) &&
2271 "Attempting to optimize already optimized and instruction");
2272 (void)InsertedInsts;
2286 for (
auto *U : AndI->
users()) {
2294 if (!CmpC || !CmpC->
isZero())
2309 Use &TheUse = UI.getUse();
2327 TheUse = InsertedAnd;
2344 if (
User->getOpcode() != Instruction::And ||
2350 if ((Cimm & (Cimm + 1)).getBoolValue())
2364 bool MadeChange =
false;
2367 TruncE = TruncI->user_end();
2368 TruncUI != TruncE;) {
2370 Use &TruncTheUse = TruncUI.getUse();
2395 if (UserBB == TruncUserBB)
2399 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2401 if (!InsertedShift && !InsertedTrunc) {
2405 if (ShiftI->
getOpcode() == Instruction::AShr)
2407 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2410 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2418 TruncInsertPt.setHeadBit(
true);
2419 assert(TruncInsertPt != TruncUserBB->
end());
2423 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2424 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2428 TruncTheUse = InsertedTrunc;
2461 bool MadeChange =
false;
2464 Use &TheUse = UI.getUse();
2478 if (UserBB == DefBB) {
2506 if (!InsertedShift) {
2510 if (ShiftI->
getOpcode() == Instruction::AShr)
2512 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2515 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2523 TheUse = InsertedShift;
2570 unsigned SizeInBits = Ty->getScalarSizeInBits();
2571 if (Ty->isVectorTy())
2583 FreshBBs.
insert(CallBlock);
2590 SplitPt.setHeadBit(
true);
2593 FreshBBs.
insert(EndBlock);
2598 L->addBasicBlockToLoop(CallBlock, LI);
2599 L->addBasicBlockToLoop(EndBlock, LI);
2605 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2612 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2613 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2614 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2619 Builder.SetInsertPoint(EndBlock, EndBlock->
begin());
2620 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2630 ModifiedDT = ModifyDT::ModifyBBDT;
2634bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2638 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2646 for (
auto &Arg : CI->
args()) {
2651 if (!Arg->getType()->isPointerTy())
2653 APInt
Offset(
DL->getIndexSizeInBits(
2656 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2657 uint64_t Offset2 =
Offset.getLimitedValue();
2663 if (AllocaSize && AllocaSize->getKnownMinValue() >= MinSize + Offset2)
2681 MaybeAlign MIDestAlign =
MI->getDestAlign();
2682 if (!MIDestAlign || DestAlign > *MIDestAlign)
2683 MI->setDestAlignment(DestAlign);
2685 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2687 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2688 MTI->setSourceAlignment(SrcAlign);
2698 for (
auto &Arg : CI->
args()) {
2699 if (!Arg->getType()->isPointerTy())
2701 unsigned AS = Arg->getType()->getPointerAddressSpace();
2702 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2708 switch (
II->getIntrinsicID()) {
2711 case Intrinsic::assume:
2713 case Intrinsic::allow_runtime_check:
2714 case Intrinsic::allow_ubsan_check:
2715 case Intrinsic::experimental_widenable_condition: {
2719 if (
II->use_empty()) {
2720 II->eraseFromParent();
2724 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2729 case Intrinsic::objectsize:
2731 case Intrinsic::is_constant:
2733 case Intrinsic::aarch64_stlxr:
2734 case Intrinsic::aarch64_stxr: {
2743 InsertedInsts.insert(ExtVal);
2747 case Intrinsic::launder_invariant_group:
2748 case Intrinsic::strip_invariant_group: {
2749 Value *ArgVal =
II->getArgOperand(0);
2750 auto it = LargeOffsetGEPMap.
find(
II);
2751 if (it != LargeOffsetGEPMap.
end()) {
2755 auto GEPs = std::move(it->second);
2756 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2761 II->eraseFromParent();
2764 case Intrinsic::cttz:
2765 case Intrinsic::ctlz:
2769 case Intrinsic::fshl:
2770 case Intrinsic::fshr:
2771 return optimizeFunnelShift(
II);
2772 case Intrinsic::masked_gather:
2773 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2774 case Intrinsic::masked_scatter:
2775 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2776 case Intrinsic::masked_load:
2779 if (VT->getNumElements() == 1) {
2780 Value *PtrVal =
II->getArgOperand(0);
2782 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2787 case Intrinsic::masked_store:
2791 if (VT->getNumElements() == 1) {
2792 Value *PtrVal =
II->getArgOperand(1);
2794 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2799 case Intrinsic::umul_with_overflow:
2800 return optimizeMulWithOverflow(
II,
false, ModifiedDT);
2801 case Intrinsic::smul_with_overflow:
2802 return optimizeMulWithOverflow(
II,
true, ModifiedDT);
2805 SmallVector<Value *, 2> PtrOps;
2808 while (!PtrOps.
empty()) {
2811 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2825 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2827 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2837 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2838 if (!
F->getReturnType()->isPointerTy())
2841 GlobalVariable *UniformValue =
nullptr;
2842 for (
auto &BB : *
F) {
2847 else if (V != UniformValue)
2855 return UniformValue;
2858 if (
Callee->hasExactDefinition()) {
2859 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2860 bool MadeChange =
false;
2886 switch (
II->getIntrinsicID()) {
2887 case Intrinsic::memset:
2888 case Intrinsic::memcpy:
2889 case Intrinsic::memmove:
2897 if (Callee && TLInfo && TLInfo->
getLibFunc(*Callee, LF))
2899 case LibFunc_strcpy:
2900 case LibFunc_strncpy:
2901 case LibFunc_strcat:
2902 case LibFunc_strncat:
2943bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
2944 ModifyDT &ModifiedDT) {
2952 assert(LI->
getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2954 PHINode *PN =
nullptr;
2955 ExtractValueInst *EVI =
nullptr;
2956 BitCastInst *BCI =
nullptr;
2976 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
2982 return II->getIntrinsicID() == Intrinsic::lifetime_end;
2988 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
2990 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
3012 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
3019 auto MayBePermittedAsTailCall = [&](
const auto *CI) {
3036 MayBePermittedAsTailCall(CI)) {
3057 MayBePermittedAsTailCall(CI)) {
3064 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
3066 if (!VisitedBBs.
insert(Pred).second)
3068 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
3070 if (CI && CI->
use_empty() && MayBePermittedAsTailCall(CI)) {
3085 for (
auto const &TailCallBB : TailCallBBs) {
3098 ModifiedDT = ModifyDT::ModifyBBDT;
3107 for (
auto *CI : CallInsts) {
3108 for (
auto const *FakeUse : FakeUses) {
3109 auto *ClonedInst = FakeUse->clone();
3127struct ExtAddrMode :
public TargetLowering::AddrMode {
3128 Value *BaseReg =
nullptr;
3129 Value *ScaledReg =
nullptr;
3130 Value *OriginalValue =
nullptr;
3131 bool InBounds =
true;
3135 BaseRegField = 0x01,
3137 BaseOffsField = 0x04,
3138 ScaledRegField = 0x08,
3140 MultipleFields = 0xff
3143 ExtAddrMode() =
default;
3145 void print(raw_ostream &OS)
const;
3152 if (ScaledReg == From)
3156 FieldName
compare(
const ExtAddrMode &other) {
3159 if (BaseReg && other.
BaseReg &&
3161 return MultipleFields;
3162 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3163 return MultipleFields;
3166 return MultipleFields;
3169 if (InBounds != other.InBounds)
3170 return MultipleFields;
3173 unsigned Result = NoField;
3176 if (BaseGV != other.BaseGV)
3178 if (BaseOffs != other.BaseOffs)
3181 Result |= ScaledRegField;
3184 if (Scale && other.
Scale && Scale != other.
Scale)
3188 return MultipleFields;
3190 return static_cast<FieldName
>(
Result);
3200 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3211 case ScaledRegField:
3218 void SetCombinedField(FieldName
Field,
Value *V,
3219 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3224 case ExtAddrMode::BaseRegField:
3227 case ExtAddrMode::BaseGVField:
3230 assert(BaseReg ==
nullptr);
3234 case ExtAddrMode::ScaledRegField:
3239 for (
const ExtAddrMode &AM : AddrModes)
3245 case ExtAddrMode::BaseOffsField:
3248 assert(ScaledReg ==
nullptr);
3258static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3264#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3265void ExtAddrMode::print(raw_ostream &OS)
const {
3266 bool NeedPlus =
false;
3272 BaseGV->printAsOperand(OS,
false);
3277 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3282 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3283 BaseReg->printAsOperand(OS,
false);
3287 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3310class TypePromotionTransaction {
3314 class TypePromotionAction {
3322 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3324 virtual ~TypePromotionAction() =
default;
3331 virtual void undo() = 0;
3336 virtual void commit() {
3342 class InsertionHandler {
3351 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3354 bool HasPrevInstruction;
3358 InsertionHandler(Instruction *Inst) {
3366 if (HasPrevInstruction) {
3374 void insert(Instruction *Inst) {
3375 if (HasPrevInstruction) {
3387 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3392 class InstructionMoveBefore :
public TypePromotionAction {
3394 InsertionHandler Position;
3399 : TypePromotionAction(Inst), Position(Inst) {
3400 LLVM_DEBUG(
dbgs() <<
"Do: move: " << *Inst <<
"\nbefore: " << *Before
3406 void undo()
override {
3408 Position.insert(Inst);
3413 class OperandSetter :
public TypePromotionAction {
3422 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3423 : TypePromotionAction(Inst), Idx(Idx) {
3425 <<
"for:" << *Inst <<
"\n"
3426 <<
"with:" << *NewVal <<
"\n");
3432 void undo()
override {
3434 <<
"for: " << *Inst <<
"\n"
3435 <<
"with: " << *Origin <<
"\n");
3442 class OperandsHider :
public TypePromotionAction {
3444 SmallVector<Value *, 4> OriginalValues;
3448 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3451 OriginalValues.
reserve(NumOpnds);
3452 for (
unsigned It = 0; It < NumOpnds; ++It) {
3464 void undo()
override {
3466 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3472 class TruncBuilder :
public TypePromotionAction {
3479 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3481 Builder.SetCurrentDebugLocation(
DebugLoc());
3482 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3487 Value *getBuiltValue() {
return Val; }
3490 void undo()
override {
3493 IVal->eraseFromParent();
3498 class SExtBuilder :
public TypePromotionAction {
3505 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3506 : TypePromotionAction(InsertPt) {
3508 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3513 Value *getBuiltValue() {
return Val; }
3516 void undo()
override {
3519 IVal->eraseFromParent();
3524 class ZExtBuilder :
public TypePromotionAction {
3531 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3532 : TypePromotionAction(InsertPt) {
3534 Builder.SetCurrentDebugLocation(
DebugLoc());
3535 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3540 Value *getBuiltValue() {
return Val; }
3543 void undo()
override {
3546 IVal->eraseFromParent();
3551 class TypeMutator :
public TypePromotionAction {
3557 TypeMutator(Instruction *Inst,
Type *NewTy)
3558 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3559 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3565 void undo()
override {
3566 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3573 class UsesReplacer :
public TypePromotionAction {
3575 struct InstructionAndIdx {
3582 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3583 : Inst(Inst), Idx(Idx) {}
3589 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3599 UsesReplacer(Instruction *Inst,
Value *New)
3600 : TypePromotionAction(Inst),
New(
New) {
3601 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3604 for (Use &U : Inst->
uses()) {
3606 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3617 void undo()
override {
3619 for (InstructionAndIdx &Use : OriginalUses)
3620 Use.Inst->setOperand(
Use.Idx, Inst);
3625 for (DbgVariableRecord *DVR : DbgVariableRecords)
3626 DVR->replaceVariableLocationOp(New, Inst);
3631 class InstructionRemover :
public TypePromotionAction {
3633 InsertionHandler Inserter;
3637 OperandsHider Hider;
3640 UsesReplacer *Replacer =
nullptr;
3643 SetOfInstrs &RemovedInsts;
3650 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3651 Value *New =
nullptr)
3652 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3653 RemovedInsts(RemovedInsts) {
3655 Replacer =
new UsesReplacer(Inst, New);
3656 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3657 RemovedInsts.insert(Inst);
3664 ~InstructionRemover()
override {
delete Replacer; }
3666 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3667 InstructionRemover(
const InstructionRemover &other) =
delete;
3671 void undo()
override {
3672 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3673 Inserter.insert(Inst);
3677 RemovedInsts.erase(Inst);
3685 using ConstRestorationPt =
const TypePromotionAction *;
3687 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3688 : RemovedInsts(RemovedInsts) {}
3695 void rollback(ConstRestorationPt Point);
3698 ConstRestorationPt getRestorationPoint()
const;
3703 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3712 void mutateType(Instruction *Inst,
Type *NewTy);
3715 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3728 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3730 SetOfInstrs &RemovedInsts;
3735void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3737 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3738 Inst, Idx, NewVal));
3741void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3744 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3745 Inst, RemovedInsts, NewVal));
3748void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3751 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3754void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3756 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3759Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3760 std::unique_ptr<TruncBuilder> Ptr(
new TruncBuilder(Opnd, Ty));
3761 Value *Val = Ptr->getBuiltValue();
3762 Actions.push_back(std::move(Ptr));
3766Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3768 std::unique_ptr<SExtBuilder> Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3769 Value *Val = Ptr->getBuiltValue();
3770 Actions.push_back(std::move(Ptr));
3774Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3776 std::unique_ptr<ZExtBuilder> Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3777 Value *Val = Ptr->getBuiltValue();
3778 Actions.push_back(std::move(Ptr));
3782TypePromotionTransaction::ConstRestorationPt
3783TypePromotionTransaction::getRestorationPoint()
const {
3784 return !Actions.empty() ? Actions.back().get() :
nullptr;
3787bool TypePromotionTransaction::commit() {
3788 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3795void TypePromotionTransaction::rollback(
3796 TypePromotionTransaction::ConstRestorationPt Point) {
3797 while (!Actions.empty() && Point != Actions.back().get()) {
3798 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3808class AddressingModeMatcher {
3809 SmallVectorImpl<Instruction *> &AddrModeInsts;
3810 const TargetLowering &TLI;
3811 const TargetRegisterInfo &
TRI;
3812 const DataLayout &
DL;
3814 const std::function<
const DominatorTree &()> getDTFn;
3827 const SetOfInstrs &InsertedInsts;
3830 InstrToOrigTy &PromotedInsts;
3833 TypePromotionTransaction &TPT;
3836 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3840 bool IgnoreProfitability;
3843 bool OptSize =
false;
3845 ProfileSummaryInfo *PSI;
3846 BlockFrequencyInfo *BFI;
3848 AddressingModeMatcher(
3849 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3850 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3851 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3852 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3853 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3854 TypePromotionTransaction &TPT,
3855 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3856 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI)
3857 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3858 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3859 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3860 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3861 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI), BFI(BFI) {
3862 IgnoreProfitability =
false;
3874 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3875 SmallVectorImpl<Instruction *> &AddrModeInsts,
3876 const TargetLowering &TLI,
const LoopInfo &LI,
3877 const std::function<
const DominatorTree &()> getDTFn,
3878 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3879 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3880 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3881 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
3884 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3885 AccessTy, AS, MemoryInst, Result,
3886 InsertedInsts, PromotedInsts, TPT,
3887 LargeOffsetGEP, OptSize, PSI, BFI)
3895 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3897 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3898 bool *MovedAway =
nullptr);
3899 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3900 ExtAddrMode &AMBefore,
3901 ExtAddrMode &AMAfter);
3902 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3903 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3904 Value *PromotedOperand)
const;
3910class PhiNodeSetIterator {
3911 PhiNodeSet *
const Set;
3912 size_t CurrentIndex = 0;
3917 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3919 PhiNodeSetIterator &operator++();
3935 friend class PhiNodeSetIterator;
3937 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3938 using iterator = PhiNodeSetIterator;
3953 size_t FirstValidElement = 0;
3959 bool insert(PHINode *Ptr) {
3960 if (NodeMap.insert(std::make_pair(Ptr,
NodeList.
size())).second) {
3970 bool erase(PHINode *Ptr) {
3971 if (NodeMap.erase(Ptr)) {
3972 SkipRemovedElements(FirstValidElement);
3982 FirstValidElement = 0;
3988 if (FirstValidElement == 0)
3989 SkipRemovedElements(FirstValidElement);
3990 return PhiNodeSetIterator(
this, FirstValidElement);
3997 size_t size()
const {
return NodeMap.size(); }
4000 size_t count(PHINode *Ptr)
const {
return NodeMap.count(Ptr); }
4008 void SkipRemovedElements(
size_t &CurrentIndex) {
4010 auto it = NodeMap.find(NodeList[CurrentIndex]);
4013 if (it != NodeMap.end() && it->second == CurrentIndex)
4020PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
4023PHINode *PhiNodeSetIterator::operator*()
const {
4025 "PhiNodeSet access out of range");
4026 return Set->NodeList[CurrentIndex];
4029PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
4031 "PhiNodeSet access out of range");
4033 Set->SkipRemovedElements(CurrentIndex);
4037bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
4038 return CurrentIndex ==
RHS.CurrentIndex;
4041bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
4042 return !((*this) ==
RHS);
4048class SimplificationTracker {
4049 DenseMap<Value *, Value *> Storage;
4052 PhiNodeSet AllPhiNodes;
4054 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
4059 auto SV = Storage.
find(V);
4060 if (SV == Storage.
end())
4068 void ReplacePhi(PHINode *From, PHINode *To) {
4069 Value *OldReplacement = Get(From);
4070 while (OldReplacement != From) {
4073 OldReplacement = Get(From);
4075 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
4078 AllPhiNodes.erase(From);
4082 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
4084 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
4086 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
4088 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4090 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4092 void destroyNewNodes(
Type *CommonType) {
4095 for (
auto *
I : AllPhiNodes) {
4096 I->replaceAllUsesWith(Dummy);
4097 I->eraseFromParent();
4099 AllPhiNodes.clear();
4100 for (
auto *
I : AllSelectNodes) {
4101 I->replaceAllUsesWith(Dummy);
4102 I->eraseFromParent();
4104 AllSelectNodes.clear();
4109class AddressingModeCombiner {
4110 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4111 typedef std::pair<PHINode *, PHINode *> PHIPair;
4118 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4121 bool AllAddrModesTrivial =
true;
4124 Type *CommonType =
nullptr;
4126 const DataLayout &
DL;
4132 Value *CommonValue =
nullptr;
4135 AddressingModeCombiner(
const DataLayout &
DL,
Value *OriginalValue)
4136 :
DL(
DL), Original(OriginalValue) {}
4138 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4141 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4146 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4150 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4153 if (AddrModes.
empty()) {
4161 ExtAddrMode::FieldName ThisDifferentField =
4162 AddrModes[0].compare(NewAddrMode);
4163 if (DifferentField == ExtAddrMode::NoField)
4164 DifferentField = ThisDifferentField;
4165 else if (DifferentField != ThisDifferentField)
4166 DifferentField = ExtAddrMode::MultipleFields;
4169 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4172 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4177 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4182 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4183 !NewAddrMode.HasBaseReg);
4200 bool combineAddrModes() {
4202 if (AddrModes.
size() == 0)
4206 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4211 if (AllAddrModesTrivial)
4214 if (!addrModeCombiningAllowed())
4220 FoldAddrToValueMapping
Map;
4221 if (!initializeMap(Map))
4224 CommonValue = findCommon(Map);
4226 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4227 return CommonValue !=
nullptr;
4233 void eraseCommonValueIfDead() {
4234 if (CommonValue && CommonValue->
use_empty())
4236 CommonInst->eraseFromParent();
4244 bool initializeMap(FoldAddrToValueMapping &Map) {
4247 SmallVector<Value *, 2> NullValue;
4248 Type *IntPtrTy =
DL.getIntPtrType(AddrModes[0].OriginalValue->
getType());
4249 for (
auto &AM : AddrModes) {
4250 Value *DV = AM.GetFieldAsValue(DifferentField, IntPtrTy);
4253 if (CommonType && CommonType !=
Type)
4256 Map[AM.OriginalValue] = DV;
4261 assert(CommonType &&
"At least one non-null value must be!");
4262 for (
auto *V : NullValue)
4290 Value *findCommon(FoldAddrToValueMapping &Map) {
4298 SimplificationTracker
ST;
4303 InsertPlaceholders(Map, TraverseOrder, ST);
4306 FillPlaceholders(Map, TraverseOrder, ST);
4309 ST.destroyNewNodes(CommonType);
4314 unsigned PhiNotMatchedCount = 0;
4316 ST.destroyNewNodes(CommonType);
4320 auto *
Result =
ST.Get(
Map.find(Original)->second);
4322 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4323 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4330 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4331 SmallSetVector<PHIPair, 8> &Matcher,
4332 PhiNodeSet &PhiNodesToMatch) {
4335 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4338 SmallSet<PHIPair, 8> Visited;
4339 while (!WorkList.
empty()) {
4341 if (!Visited.
insert(Item).second)
4348 for (
auto *
B : Item.first->blocks()) {
4349 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4350 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4351 if (FirstValue == SecondValue)
4361 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4366 if (Matcher.
count({FirstPhi, SecondPhi}))
4371 if (MatchedPHIs.
insert(FirstPhi).second)
4372 Matcher.
insert({FirstPhi, SecondPhi});
4374 WorkList.
push_back({FirstPhi, SecondPhi});
4383 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4384 unsigned &PhiNotMatchedCount) {
4388 SmallSetVector<PHIPair, 8> Matched;
4389 SmallPtrSet<PHINode *, 8> WillNotMatch;
4390 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4391 while (PhiNodesToMatch.size()) {
4392 PHINode *
PHI = *PhiNodesToMatch.begin();
4395 WillNotMatch.
clear();
4399 bool IsMatched =
false;
4400 for (
auto &
P :
PHI->getParent()->phis()) {
4402 if (PhiNodesToMatch.count(&
P))
4404 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4414 for (
auto MV : Matched)
4415 ST.ReplacePhi(MV.first, MV.second);
4420 if (!AllowNewPhiNodes)
4423 PhiNotMatchedCount += WillNotMatch.
size();
4424 for (
auto *
P : WillNotMatch)
4425 PhiNodesToMatch.erase(
P);
4430 void FillPlaceholders(FoldAddrToValueMapping &Map,
4431 SmallVectorImpl<Value *> &TraverseOrder,
4432 SimplificationTracker &ST) {
4433 while (!TraverseOrder.
empty()) {
4435 assert(
Map.contains(Current) &&
"No node to fill!!!");
4441 auto *TrueValue = CurrentSelect->getTrueValue();
4442 assert(
Map.contains(TrueValue) &&
"No True Value!");
4443 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4444 auto *FalseValue = CurrentSelect->getFalseValue();
4445 assert(
Map.contains(FalseValue) &&
"No False Value!");
4446 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4453 assert(
Map.contains(PV) &&
"No predecessor Value!");
4454 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4465 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4466 SmallVectorImpl<Value *> &TraverseOrder,
4467 SimplificationTracker &ST) {
4470 "Address must be a Phi or Select node");
4473 while (!Worklist.
empty()) {
4476 if (
Map.contains(Current))
4487 CurrentSelect->getName(),
4488 CurrentSelect->getIterator(), CurrentSelect);
4492 Worklist.
push_back(CurrentSelect->getTrueValue());
4493 Worklist.
push_back(CurrentSelect->getFalseValue());
4501 ST.insertNewPhi(
PHI);
4507 bool addrModeCombiningAllowed() {
4510 switch (DifferentField) {
4513 case ExtAddrMode::BaseRegField:
4515 case ExtAddrMode::BaseGVField:
4517 case ExtAddrMode::BaseOffsField:
4519 case ExtAddrMode::ScaledRegField:
4529bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4534 return matchAddr(ScaleReg,
Depth);
4545 ExtAddrMode TestAddrMode =
AddrMode;
4549 TestAddrMode.
Scale += Scale;
4563 ConstantInt *CI =
nullptr;
4564 Value *AddLHS =
nullptr;
4568 TestAddrMode.InBounds =
false;
4585 auto GetConstantStep =
4586 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4589 return std::nullopt;
4592 return std::nullopt;
4600 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4601 return std::nullopt;
4603 return std::make_pair(IVInc->first, ConstantStep->getValue());
4604 return std::nullopt;
4619 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4626 APInt Step = IVStep->second;
4628 if (
Offset.isSignedIntN(64)) {
4629 TestAddrMode.InBounds =
false;
4631 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4636 getDTFn().
dominates(IVInc, MemoryInst)) {
4656 switch (
I->getOpcode()) {
4657 case Instruction::BitCast:
4658 case Instruction::AddrSpaceCast:
4660 if (
I->getType() ==
I->getOperand(0)->getType())
4662 return I->getType()->isIntOrPtrTy();
4663 case Instruction::PtrToInt:
4666 case Instruction::IntToPtr:
4669 case Instruction::Add:
4671 case Instruction::Mul:
4672 case Instruction::Shl:
4675 case Instruction::GetElementPtr:
4703class TypePromotionHelper {
4706 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4707 Instruction *ExtOpnd,
bool IsSExt) {
4708 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4709 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4713 if (It->second.getInt() == ExtTy)
4719 ExtTy = BothExtension;
4721 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4728 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4729 Instruction *Opnd,
bool IsSExt) {
4730 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4731 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4732 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4733 return It->second.getPointer();
4748 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4749 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4753 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4766 static Value *promoteOperandForTruncAndAnyExt(
4767 Instruction *Ext, TypePromotionTransaction &TPT,
4768 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4769 SmallVectorImpl<Instruction *> *Exts,
4770 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4781 static Value *promoteOperandForOther(Instruction *Ext,
4782 TypePromotionTransaction &TPT,
4783 InstrToOrigTy &PromotedInsts,
4784 unsigned &CreatedInstsCost,
4785 SmallVectorImpl<Instruction *> *Exts,
4786 SmallVectorImpl<Instruction *> *Truncs,
4787 const TargetLowering &TLI,
bool IsSExt);
4790 static Value *signExtendOperandForOther(
4791 Instruction *Ext, TypePromotionTransaction &TPT,
4792 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4793 SmallVectorImpl<Instruction *> *Exts,
4794 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4795 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4796 Exts, Truncs, TLI,
true);
4800 static Value *zeroExtendOperandForOther(
4801 Instruction *Ext, TypePromotionTransaction &TPT,
4802 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4803 SmallVectorImpl<Instruction *> *Exts,
4804 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4805 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4806 Exts, Truncs, TLI,
false);
4811 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4812 InstrToOrigTy &PromotedInsts,
4813 unsigned &CreatedInstsCost,
4814 SmallVectorImpl<Instruction *> *Exts,
4815 SmallVectorImpl<Instruction *> *Truncs,
4816 const TargetLowering &TLI);
4827 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4828 const TargetLowering &TLI,
4829 const InstrToOrigTy &PromotedInsts);
4834bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4835 Type *ConsideredExtType,
4836 const InstrToOrigTy &PromotedInsts,
4856 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4857 (IsSExt && BinOp->hasNoSignedWrap())))
4861 if ((Inst->
getOpcode() == Instruction::And ||
4866 if (Inst->
getOpcode() == Instruction::Xor) {
4869 if (!Cst->getValue().isAllOnes())
4878 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4888 if (ExtInst->hasOneUse()) {
4890 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4923 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4936TypePromotionHelper::Action TypePromotionHelper::getAction(
4937 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4938 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
4940 "Unexpected instruction type");
4947 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4960 return promoteOperandForTruncAndAnyExt;
4966 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4969Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4970 Instruction *SExt, TypePromotionTransaction &TPT,
4971 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4972 SmallVectorImpl<Instruction *> *Exts,
4973 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4977 Value *ExtVal = SExt;
4978 bool HasMergedNonFreeExt =
false;
4982 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
4985 TPT.replaceAllUsesWith(SExt, ZExt);
4986 TPT.eraseInstruction(SExt);
4991 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
4993 CreatedInstsCost = 0;
4997 TPT.eraseInstruction(SExtOpnd);
5005 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
5013 TPT.eraseInstruction(ExtInst, NextVal);
5017Value *TypePromotionHelper::promoteOperandForOther(
5018 Instruction *Ext, TypePromotionTransaction &TPT,
5019 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5020 SmallVectorImpl<Instruction *> *Exts,
5021 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
5026 CreatedInstsCost = 0;
5032 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
5035 ITrunc->moveAfter(ExtOpnd);
5040 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
5043 TPT.setOperand(Ext, 0, ExtOpnd);
5053 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
5055 TPT.mutateType(ExtOpnd, Ext->
getType());
5057 TPT.replaceAllUsesWith(Ext, ExtOpnd);
5064 !shouldExtOperand(ExtOpnd,
OpIdx)) {
5073 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
5075 TPT.setOperand(ExtOpnd,
OpIdx, ConstantInt::get(Ext->
getType(), CstVal));
5086 Value *ValForExtOpnd = IsSExt
5087 ? TPT.createSExt(ExtOpnd, Opnd, Ext->
getType())
5088 : TPT.createZExt(ExtOpnd, Opnd, Ext->
getType());
5089 TPT.setOperand(ExtOpnd,
OpIdx, ValForExtOpnd);
5091 if (!InstForExtOpnd)
5097 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5100 TPT.eraseInstruction(Ext);
5112bool AddressingModeMatcher::isPromotionProfitable(
5113 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5114 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5119 if (NewCost > OldCost)
5121 if (NewCost < OldCost)
5140bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5152 case Instruction::PtrToInt:
5155 case Instruction::IntToPtr: {
5163 case Instruction::BitCast:
5173 case Instruction::AddrSpaceCast: {
5181 case Instruction::Add: {
5184 ExtAddrMode BackupAddrMode =
AddrMode;
5185 unsigned OldSize = AddrModeInsts.
size();
5190 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5191 TPT.getRestorationPoint();
5195 int First = 0, Second = 1;
5206 AddrModeInsts.
resize(OldSize);
5207 TPT.rollback(LastKnownGood);
5217 AddrModeInsts.
resize(OldSize);
5218 TPT.rollback(LastKnownGood);
5224 case Instruction::Mul:
5225 case Instruction::Shl: {
5229 if (!
RHS ||
RHS->getBitWidth() > 64)
5231 int64_t Scale = Opcode == Instruction::Shl
5232 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5233 :
RHS->getSExtValue();
5237 case Instruction::GetElementPtr: {
5240 int VariableOperand = -1;
5241 unsigned VariableScale = 0;
5243 int64_t ConstantOffset = 0;
5245 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5247 const StructLayout *SL =
DL.getStructLayout(STy);
5258 if (ConstantInt *CI =
5260 const APInt &CVal = CI->
getValue();
5267 if (VariableOperand != -1)
5271 VariableOperand = i;
5272 VariableScale = TypeSize;
5279 if (VariableOperand == -1) {
5280 AddrMode.BaseOffs += ConstantOffset;
5286 AddrMode.BaseOffs -= ConstantOffset;
5290 ConstantOffset > 0) {
5303 BasicBlock *Parent = BaseI ? BaseI->getParent()
5304 : &
GEP->getFunction()->getEntryBlock();
5306 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5314 ExtAddrMode BackupAddrMode =
AddrMode;
5315 unsigned OldSize = AddrModeInsts.
size();
5318 AddrMode.BaseOffs += ConstantOffset;
5327 AddrModeInsts.
resize(OldSize);
5335 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5340 AddrModeInsts.
resize(OldSize);
5345 AddrMode.BaseOffs += ConstantOffset;
5346 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5347 VariableScale,
Depth)) {
5350 AddrModeInsts.
resize(OldSize);
5357 case Instruction::SExt:
5358 case Instruction::ZExt: {
5365 TypePromotionHelper::Action TPH =
5366 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5370 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5371 TPT.getRestorationPoint();
5372 unsigned CreatedInstsCost = 0;
5374 Value *PromotedOperand =
5375 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5390 assert(PromotedOperand &&
5391 "TypePromotionHelper should have filtered out those cases");
5393 ExtAddrMode BackupAddrMode =
AddrMode;
5394 unsigned OldSize = AddrModeInsts.
size();
5396 if (!matchAddr(PromotedOperand,
Depth) ||
5401 !isPromotionProfitable(CreatedInstsCost,
5402 ExtCost + (AddrModeInsts.
size() - OldSize),
5405 AddrModeInsts.
resize(OldSize);
5406 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5407 TPT.rollback(LastKnownGood);
5412 AddrMode.replaceWith(Ext, PromotedOperand);
5415 case Instruction::Call:
5417 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5433bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5436 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5437 TPT.getRestorationPoint();
5461 ExtAddrMode BackupAddrMode =
AddrMode;
5462 unsigned OldSize = AddrModeInsts.
size();
5465 bool MovedAway =
false;
5466 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5474 if (
I->hasOneUse() ||
5475 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5482 AddrModeInsts.
resize(OldSize);
5483 TPT.rollback(LastKnownGood);
5486 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5488 TPT.rollback(LastKnownGood);
5515 TPT.rollback(LastKnownGood);
5534 if (OpInfo.CallOperandVal == OpVal &&
5536 !OpInfo.isIndirect))
5552 if (!ConsideredInsts.
insert(
I).second)
5560 for (
Use &U :
I->uses()) {
5568 MemoryUses.push_back({&U, LI->getType()});
5575 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5582 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5589 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5599 if (!
find(PtrOps, U.get()))
5602 MemoryUses.push_back({&U, AccessTy});
5607 if (CI->hasFnAttr(Attribute::Cold)) {
5625 PSI, BFI, SeenInsts))
5636 unsigned SeenInsts = 0;
5639 PSI, BFI, SeenInsts);
5647bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5649 Value *KnownLive2) {
5651 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5692bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5693 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5694 if (IgnoreProfitability)
5712 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5713 ScaledReg =
nullptr;
5717 if (!BaseReg && !ScaledReg)
5738 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5741 Type *AddressAccessTy = Pair.second;
5742 unsigned AS =
Address->getType()->getPointerAddressSpace();
5748 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5750 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5751 TPT.getRestorationPoint();
5752 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5753 AddressAccessTy, AS, UserI, Result,
5754 InsertedInsts, PromotedInsts, TPT,
5755 LargeOffsetGEP, OptSize, PSI, BFI);
5756 Matcher.IgnoreProfitability =
true;
5764 TPT.rollback(LastKnownGood);
5770 MatchedAddrModeInsts.
clear();
5780 return I->getParent() != BB;
5796 return std::next(AddrInst->getIterator());
5807 Earliest = UserInst;
5832bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5833 Type *AccessTy,
unsigned AddrSpace) {
5838 SmallVector<Value *, 8> worklist;
5839 SmallPtrSet<Value *, 16> Visited;
5845 bool PhiOrSelectSeen =
false;
5846 SmallVector<Instruction *, 16> AddrModeInsts;
5847 AddressingModeCombiner AddrModes(*
DL, Addr);
5848 TypePromotionTransaction TPT(RemovedInsts);
5849 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5850 TPT.getRestorationPoint();
5851 while (!worklist.
empty()) {
5863 if (!Visited.
insert(V).second)
5869 PhiOrSelectSeen =
true;
5876 PhiOrSelectSeen =
true;
5883 AddrModeInsts.
clear();
5884 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5889 auto getDTFn = [MemoryInst,
this]() ->
const DominatorTree & {
5891 return this->getDT(*
F);
5893 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5894 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5895 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5898 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5903 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5904 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5907 NewAddrMode.OriginalValue =
V;
5908 if (!AddrModes.addNewAddrMode(NewAddrMode))
5915 if (!AddrModes.combineAddrModes()) {
5916 TPT.rollback(LastKnownGood);
5922 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5928 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5942 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
5964 <<
" for " << *MemoryInst <<
"\n");
5968 !
DL->isNonIntegralPointerType(Addr->
getType())) {
5974 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
5976 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
5978 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
5985 <<
" for " << *MemoryInst <<
"\n");
5986 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
5997 if (ResultPtr ||
AddrMode.Scale != 1)
6018 GlobalValue *BaseGV =
AddrMode.BaseGV;
6019 if (BaseGV !=
nullptr) {
6024 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
6033 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
6034 if (!ResultPtr &&
AddrMode.BaseReg) {
6038 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
6039 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
6048 }
else if (!ResultPtr) {
6061 if (
V->getType() != IntPtrTy)
6062 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6070 if (
V->getType() == IntPtrTy) {
6075 "We can't transform if ScaledReg is too narrow");
6076 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6080 V = Builder.CreateMul(
6083 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6094 if (ResultPtr->
getType() != I8PtrTy)
6095 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6096 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6109 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6111 SunkAddr = ResultPtr;
6113 if (ResultPtr->
getType() != I8PtrTy)
6114 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6115 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6122 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6128 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
6130 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6132 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6142 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6143 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6144 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6146 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6150 <<
" for " << *MemoryInst <<
"\n");
6161 if (
V->getType()->isPointerTy())
6162 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6163 if (
V->getType() != IntPtrTy)
6164 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6171 if (
V->getType() == IntPtrTy) {
6173 }
else if (
V->getType()->isPointerTy()) {
6174 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6177 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6186 I->eraseFromParent();
6190 V = Builder.CreateMul(
6193 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6199 GlobalValue *BaseGV =
AddrMode.BaseGV;
6200 if (BaseGV !=
nullptr) {
6203 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6207 Value *
V = Builder.CreatePtrToInt(BaseGVPtr, IntPtrTy,
"sunkaddr");
6209 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6218 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6226 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6232 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6237 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6238 RecursivelyDeleteTriviallyDeadInstructions(
6239 Repl, TLInfo, nullptr,
6240 [&](Value *V) { removeAllAssertingVHReferences(V); });
6264bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6270 if (!
GEP->hasIndices())
6278 SmallVector<Value *, 2>
Ops(
GEP->operands());
6280 bool RewriteGEP =
false;
6289 unsigned FinalIndex =
Ops.size() - 1;
6294 for (
unsigned i = 1; i < FinalIndex; ++i) {
6299 C =
C->getSplatValue();
6301 if (!CI || !CI->
isZero())
6308 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6312 if (!
C || !
C->isZero()) {
6313 Ops[FinalIndex] =
V;
6321 if (!RewriteGEP &&
Ops.size() == 2)
6328 Type *SourceTy =
GEP->getSourceElementType();
6329 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6333 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6334 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6335 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6345 if (
Ops.size() != 2) {
6355 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6369 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6370 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6373 Intrinsic::masked_gather) {
6377 Intrinsic::masked_scatter);
6392 Ptr, TLInfo,
nullptr,
6393 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6404 if (
I->hasNUsesOrMore(3))
6407 for (
User *U :
I->users()) {
6409 if (!Extract || Extract->getNumIndices() != 1)
6412 unsigned Index = Extract->getIndices()[0];
6414 MulExtract = Extract;
6415 else if (Index == 1)
6416 OverflowExtract = Extract;
6443bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
6444 ModifyDT &ModifiedDT) {
6451 ExtractValueInst *MulExtract =
nullptr, *OverflowExtract =
nullptr;
6456 InsertedInsts.insert(
I);
6465 BasicBlock *OverflowEntryBB =
I->getParent()->splitBasicBlockBefore(
I,
"");
6466 OverflowEntryBB->
takeName(
I->getParent());
6472 NoOverflowBB->
moveAfter(OverflowEntryBB);
6480 Value *LoLHS = Builder.CreateTrunc(
LHS, LegalTy,
"lo.lhs");
6481 Value *HiLHS = Builder.CreateLShr(
LHS, VTHalfBitWidth,
"lhs.lsr");
6482 HiLHS = Builder.CreateTrunc(HiLHS, LegalTy,
"hi.lhs");
6485 Value *LoRHS = Builder.CreateTrunc(
RHS, LegalTy,
"lo.rhs");
6486 Value *HiRHS = Builder.CreateLShr(
RHS, VTHalfBitWidth,
"rhs.lsr");
6487 HiRHS = Builder.CreateTrunc(HiRHS, LegalTy,
"hi.rhs");
6489 Value *IsAnyBitTrue;
6492 Builder.CreateAShr(LoLHS, VTHalfBitWidth - 1,
"sign.lo.lhs");
6494 Builder.CreateAShr(LoRHS, VTHalfBitWidth - 1,
"sign.lo.rhs");
6495 Value *XorLHS = Builder.CreateXor(HiLHS, SignLoLHS);
6496 Value *XorRHS = Builder.CreateXor(HiRHS, SignLoRHS);
6497 Value *
Or = Builder.CreateOr(XorLHS, XorRHS,
"or.lhs.rhs");
6498 IsAnyBitTrue = Builder.CreateCmp(ICmpInst::ICMP_NE,
Or,
6499 ConstantInt::getNullValue(
Or->getType()));
6501 Value *CmpLHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiLHS,
6502 ConstantInt::getNullValue(LegalTy));
6503 Value *CmpRHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiRHS,
6504 ConstantInt::getNullValue(LegalTy));
6505 IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS,
"or.lhs.rhs");
6507 Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
6510 Builder.SetInsertPoint(NoOverflowBB);
6511 Value *ExtLoLHS, *ExtLoRHS;
6513 ExtLoLHS = Builder.CreateSExt(LoLHS, Ty,
"lo.lhs.ext");
6514 ExtLoRHS = Builder.CreateSExt(LoRHS, Ty,
"lo.rhs.ext");
6516 ExtLoLHS = Builder.CreateZExt(LoLHS, Ty,
"lo.lhs.ext");
6517 ExtLoRHS = Builder.CreateZExt(LoRHS, Ty,
"lo.rhs.ext");
6520 Value *
Mul = Builder.CreateMul(ExtLoLHS, ExtLoRHS,
"mul.overflow.no");
6525 OverflowResBB->
setName(
"overflow.res");
6528 Builder.CreateBr(OverflowResBB);
6536 PHINode *OverflowResPHI = Builder.CreatePHI(Ty, 2),
6538 Builder.CreatePHI(IntegerType::getInt1Ty(
I->getContext()), 2);
6550 if (OverflowExtract) {
6551 OverflowExtract->replaceAllUsesWith(OverflowFlagPHI);
6552 OverflowExtract->eraseFromParent();
6557 I->removeFromParent();
6559 I->insertInto(OverflowBB, OverflowBB->
end());
6560 Builder.SetInsertPoint(OverflowBB, OverflowBB->
end());
6562 Value *OverflowFlag = Builder.CreateExtractValue(
I, {1},
"overflow.flag");
6563 Builder.CreateBr(OverflowResBB);
6567 OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
6569 ModifiedDT = ModifyDT::ModifyBBDT;
6575bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6576 bool MadeChange =
false;
6578 const TargetRegisterInfo *
TRI =
6583 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6589 OpInfo.isIndirect) {
6591 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6654bool CodeGenPrepare::tryToPromoteExts(
6655 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6656 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6657 unsigned CreatedInstsCost) {
6658 bool Promoted =
false;
6661 for (
auto *
I : Exts) {
6676 TypePromotionHelper::Action TPH =
6677 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6686 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6687 TPT.getRestorationPoint();
6688 SmallVector<Instruction *, 4> NewExts;
6689 unsigned NewCreatedInstsCost = 0;
6692 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6693 &NewExts,
nullptr, *TLI);
6695 "TypePromotionHelper should have filtered out those cases");
6705 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6708 TotalCreatedInstsCost =
6709 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6711 (TotalCreatedInstsCost > 1 ||
6713 (ExtCost == 0 && NewExts.
size() > 1))) {
6717 TPT.rollback(LastKnownGood);
6722 SmallVector<Instruction *, 2> NewlyMovedExts;
6723 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6724 bool NewPromoted =
false;
6725 for (
auto *ExtInst : NewlyMovedExts) {
6735 ProfitablyMovedExts.
push_back(MovedExt);
6742 TPT.rollback(LastKnownGood);
6753bool CodeGenPrepare::mergeSExts(Function &
F) {
6755 for (
auto &Entry : ValToSExtendedUses) {
6756 SExts &Insts =
Entry.second;
6758 for (Instruction *Inst : Insts) {
6762 bool inserted =
false;
6763 for (
auto &Pt : CurPts) {
6766 RemovedInsts.insert(Pt);
6767 Pt->removeFromParent();
6778 RemovedInsts.insert(Inst);
6785 CurPts.push_back(Inst);
6827bool CodeGenPrepare::splitLargeGEPOffsets() {
6829 for (
auto &Entry : LargeOffsetGEPMap) {
6831 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6832 &LargeOffsetGEPs =
Entry.second;
6833 auto compareGEPOffset =
6834 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6835 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6836 if (
LHS.first ==
RHS.first)
6838 if (
LHS.second !=
RHS.second)
6839 return LHS.second <
RHS.second;
6840 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6843 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6846 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6848 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6849 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6850 Value *NewBaseGEP =
nullptr;
6852 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6853 GetElementPtrInst *
GEP) {
6854 LLVMContext &Ctx =
GEP->getContext();
6855 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6857 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6869 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(),
6870 &getDT(*NewBaseInsertBB->
getParent()), LI);
6873 NewBaseInsertPt = std::next(BaseI->getIterator());
6880 IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
6886 NewBaseGEP = OldBase;
6887 if (NewBaseGEP->
getType() != I8PtrTy)
6888 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6890 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6891 NewGEPBases.
insert(NewBaseGEP);
6897 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6898 BaseOffset = PreferBase;
6901 createNewBase(BaseOffset, OldBase, BaseGEP);
6904 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6905 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6906 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6907 int64_t
Offset = LargeOffsetGEP->second;
6908 if (
Offset != BaseOffset) {
6915 GEP->getResultElementType(),
6916 GEP->getAddressSpace())) {
6922 NewBaseGEP =
nullptr;
6927 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6932 createNewBase(BaseOffset, OldBase,
GEP);
6936 Value *NewGEP = NewBaseGEP;
6937 if (
Offset != BaseOffset) {
6940 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6944 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6945 GEP->eraseFromParent();
6952bool CodeGenPrepare::optimizePhiType(
6953 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
6954 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
6959 Type *PhiTy =
I->getType();
6960 Type *ConvertTy =
nullptr;
6962 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6965 SmallVector<Instruction *, 4> Worklist;
6967 SmallPtrSet<PHINode *, 4> PhiNodes;
6968 SmallPtrSet<ConstantData *, 4>
Constants;
6971 SmallPtrSet<Instruction *, 4> Defs;
6972 SmallPtrSet<Instruction *, 4>
Uses;
6978 bool AnyAnchored =
false;
6980 while (!Worklist.
empty()) {
6985 for (
Value *V :
Phi->incoming_values()) {
6987 if (!PhiNodes.
count(OpPhi)) {
6988 if (!Visited.
insert(OpPhi).second)
6994 if (!OpLoad->isSimple())
6996 if (Defs.
insert(OpLoad).second)
6999 if (Defs.
insert(OpEx).second)
7003 ConvertTy = OpBC->getOperand(0)->getType();
7004 if (OpBC->getOperand(0)->getType() != ConvertTy)
7006 if (Defs.
insert(OpBC).second) {
7019 for (User *V :
II->users()) {
7021 if (!PhiNodes.
count(OpPhi)) {
7022 if (Visited.
count(OpPhi))
7029 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
7031 Uses.insert(OpStore);
7034 ConvertTy = OpBC->getType();
7035 if (OpBC->getType() != ConvertTy)
7039 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
7046 if (!ConvertTy || !AnyAnchored || PhiTy == ConvertTy ||
7050 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
7051 << *ConvertTy <<
"\n");
7056 for (ConstantData *
C : Constants)
7058 for (Instruction *
D : Defs) {
7060 ValMap[
D] =
D->getOperand(0);
7064 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
7067 for (PHINode *Phi : PhiNodes)
7069 Phi->getName() +
".tc",
Phi->getIterator());
7071 for (PHINode *Phi : PhiNodes) {
7073 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
7075 Phi->getIncomingBlock(i));
7079 for (Instruction *U :
Uses) {
7084 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
7094bool CodeGenPrepare::optimizePhiTypes(Function &
F) {
7099 SmallPtrSet<PHINode *, 4> Visited;
7100 SmallPtrSet<Instruction *, 4> DeletedInstrs;
7104 for (
auto &Phi : BB.
phis())
7105 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
7108 for (
auto *
I : DeletedInstrs) {
7110 I->eraseFromParent();
7118bool CodeGenPrepare::canFormExtLd(
7119 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
7120 Instruction *&Inst,
bool HasPromoted) {
7121 for (
auto *MovedExtInst : MovedExts) {
7124 Inst = MovedExtInst;
7176bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7177 bool AllowPromotionWithoutCommonHeader =
false;
7182 *Inst, AllowPromotionWithoutCommonHeader);
7183 TypePromotionTransaction TPT(RemovedInsts);
7184 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7185 TPT.getRestorationPoint();
7187 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7190 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7193 LoadInst *LI =
nullptr;
7198 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7199 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7204 Inst = ExtFedByLoad;
7209 if (ATPConsiderable &&
7210 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7211 HasPromoted, TPT, SpeculativelyMovedExts))
7214 TPT.rollback(LastKnownGood);
7223bool CodeGenPrepare::performAddressTypePromotion(
7224 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7225 bool HasPromoted, TypePromotionTransaction &TPT,
7226 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7227 bool Promoted =
false;
7228 SmallPtrSet<Instruction *, 1> UnhandledExts;
7229 bool AllSeenFirst =
true;
7230 for (
auto *
I : SpeculativelyMovedExts) {
7231 Value *HeadOfChain =
I->getOperand(0);
7232 DenseMap<Value *, Instruction *>::iterator AlreadySeen =
7233 SeenChainsForSExt.
find(HeadOfChain);
7236 if (AlreadySeen != SeenChainsForSExt.
end()) {
7237 if (AlreadySeen->second !=
nullptr)
7238 UnhandledExts.
insert(AlreadySeen->second);
7239 AllSeenFirst =
false;
7243 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7244 SpeculativelyMovedExts.size() == 1)) {
7248 for (
auto *
I : SpeculativelyMovedExts) {
7249 Value *HeadOfChain =
I->getOperand(0);
7250 SeenChainsForSExt[HeadOfChain] =
nullptr;
7251 ValToSExtendedUses[HeadOfChain].push_back(
I);
7254 Inst = SpeculativelyMovedExts.pop_back_val();
7259 for (
auto *
I : SpeculativelyMovedExts) {
7260 Value *HeadOfChain =
I->getOperand(0);
7261 SeenChainsForSExt[HeadOfChain] = Inst;
7266 if (!AllSeenFirst && !UnhandledExts.
empty())
7267 for (
auto *VisitedSExt : UnhandledExts) {
7268 if (RemovedInsts.count(VisitedSExt))
7270 TypePromotionTransaction TPT(RemovedInsts);
7272 SmallVector<Instruction *, 2> Chains;
7274 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7278 for (
auto *
I : Chains) {
7279 Value *HeadOfChain =
I->getOperand(0);
7281 SeenChainsForSExt[HeadOfChain] =
nullptr;
7282 ValToSExtendedUses[HeadOfChain].push_back(
I);
7288bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7293 Value *Src =
I->getOperand(0);
7294 if (Src->hasOneUse())
7306 bool DefIsLiveOut =
false;
7307 for (User *U :
I->users()) {
7312 if (UserBB == DefBB)
7314 DefIsLiveOut =
true;
7321 for (User *U : Src->users()) {
7324 if (UserBB == DefBB)
7333 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7335 bool MadeChange =
false;
7336 for (Use &U : Src->uses()) {
7341 if (UserBB == DefBB)
7345 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7347 if (!InsertedTrunc) {
7350 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7352 InsertedInsts.insert(InsertedTrunc);
7415bool CodeGenPrepare::optimizeLoadExt(LoadInst *Load) {
7416 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7420 if (
Load->hasOneUse() &&
7426 SmallVector<Instruction *, 8> WorkList;
7427 SmallPtrSet<Instruction *, 16> Visited;
7428 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7429 SmallVector<Instruction *, 8> DropFlags;
7430 for (
auto *U :
Load->users())
7442 while (!WorkList.
empty()) {
7446 if (!Visited.
insert(
I).second)
7451 for (
auto *U :
Phi->users())
7456 switch (
I->getOpcode()) {
7457 case Instruction::And: {
7461 APInt AndBits = AndC->getValue();
7462 DemandBits |= AndBits;
7464 if (AndBits.
ugt(WidestAndBits))
7465 WidestAndBits = AndBits;
7466 if (AndBits == WidestAndBits &&
I->getOperand(0) == Load)
7471 case Instruction::Shl: {
7475 uint64_t ShiftAmt = ShlC->getLimitedValue(
BitWidth - 1);
7476 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7481 case Instruction::Trunc: {
7484 DemandBits.setLowBits(TruncBitWidth);
7494 uint32_t ActiveBits = DemandBits.getActiveBits();
7506 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7507 WidestAndBits != DemandBits)
7510 LLVMContext &Ctx =
Load->getType()->getContext();
7511 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7522 Builder.CreateAnd(Load, ConstantInt::get(Ctx, DemandBits)));
7525 InsertedInsts.insert(NewAnd);
7530 NewAnd->setOperand(0, Load);
7533 for (
auto *
And : AndsToMaybeRemove)
7538 if (&*CurInstIterator ==
And)
7539 CurInstIterator = std::next(
And->getIterator());
7540 And->eraseFromParent();
7545 for (
auto *Inst : DropFlags)
7559 TTI->isExpensiveToSpeculativelyExecute(
I);
7577 uint64_t Max = std::max(TrueWeight, FalseWeight);
7578 uint64_t Sum = TrueWeight + FalseWeight;
7581 if (Probability >
TTI->getPredictableBranchThreshold())
7591 if (!Cmp || !Cmp->hasOneUse())
7614 assert(DefSI->getCondition() ==
SI->getCondition() &&
7615 "The condition of DefSI does not match with SI");
7616 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7619 assert(V &&
"Failed to get select true/false value");
7623bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7647 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7648 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7649 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7650 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7656bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7658 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7659 "Expected a funnel shift");
7683 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7684 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7685 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7693bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7705 It !=
SI->getParent()->
end(); ++It) {
7707 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7714 SelectInst *LastSI = ASI.
back();
7717 CurInstIterator = std::next(LastSI->
getIterator());
7721 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7722 fixupDbgVariableRecordsOnInst(*SI);
7724 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7727 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7730 TargetLowering::SelectSupportKind SelectKind;
7731 if (
SI->getType()->isVectorTy())
7732 SelectKind = TargetLowering::ScalarCondVectorVal;
7734 SelectKind = TargetLowering::ScalarValSelect;
7775 for (SelectInst *SI : ASI) {
7787 SplitPt.setHeadBit(
true);
7790 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7795 UncondBrInst *TrueBranch =
nullptr;
7796 UncondBrInst *FalseBranch =
nullptr;
7797 if (TrueInstrs.
size() == 0) {
7799 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7802 }
else if (FalseInstrs.
size() == 0) {
7804 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7811 nullptr,
nullptr, LI);
7819 EndBlock->
setName(
"select.end");
7821 TrueBlock->
setName(
"select.true.sink");
7823 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7824 :
"select.false.sink");
7828 FreshBBs.
insert(TrueBlock);
7830 FreshBBs.
insert(FalseBlock);
7831 FreshBBs.
insert(EndBlock);
7836 static const unsigned MD[] = {
7837 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7838 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7843 for (Instruction *
I : TrueInstrs)
7845 for (Instruction *
I : FalseInstrs)
7852 if (TrueBlock ==
nullptr)
7853 TrueBlock = StartBlock;
7854 else if (FalseBlock ==
nullptr)
7855 FalseBlock = StartBlock;
7871 SI->eraseFromParent();
7873 ++NumSelectsExpanded;
7877 CurInstIterator = StartBlock->
end();
7884bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7896 "Expected a type of the same size!");
7902 Builder.SetInsertPoint(SVI);
7903 Value *BC1 = Builder.CreateBitCast(
7905 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7906 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7910 SVI, TLInfo,
nullptr,
7911 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7918 !
Op->isTerminator() && !
Op->isEHPad())
7924bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7939 DenseMap<const Instruction *, unsigned long> InstOrdering;
7940 unsigned long InstNumber = 0;
7941 for (
const auto &
I : *TargetBB)
7942 InstOrdering[&
I] = InstNumber++;
7944 for (Use *U :
reverse(OpsToSink)) {
7949 if (InstOrdering[UI] < InstOrdering[InsertPoint])
7956 SetVector<Instruction *> MaybeDead;
7957 DenseMap<Instruction *, Instruction *> NewInstructions;
7958 for (Use *U : ToReplace) {
7967 FreshBBs.
insert(OpDef->getParent());
7970 NewInstructions[UI] = NI;
7975 InsertedInsts.insert(NI);
7981 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
7982 It->second->setOperand(
U->getOperandNo(), NI);
7989 for (
auto *
I : MaybeDead) {
7990 if (!
I->hasNUsesOrMore(1)) {
7992 I->eraseFromParent();
7999bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
8005 unsigned RegWidth =
RegType.getSizeInBits();
8016 auto *NewType = Type::getIntNTy(
Context, RegWidth);
8025 ExtType = Instruction::SExt;
8028 if (Arg->hasSExtAttr())
8029 ExtType = Instruction::SExt;
8030 if (Arg->hasZExtAttr())
8031 ExtType = Instruction::ZExt;
8037 SI->setCondition(ExtInst);
8038 for (
auto Case :
SI->cases()) {
8039 const APInt &NarrowConst = Case.getCaseValue()->getValue();
8040 APInt WideConst = (ExtType == Instruction::ZExt)
8041 ? NarrowConst.
zext(RegWidth)
8042 : NarrowConst.
sext(RegWidth);
8043 Case.setValue(ConstantInt::get(
Context, WideConst));
8049bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
8056 Value *Condition =
SI->getCondition();
8065 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
8066 ConstantInt *CaseValue = Case.getCaseValue();
8067 BasicBlock *CaseBB = Case.getCaseSuccessor();
8070 bool CheckedForSinglePred =
false;
8071 for (PHINode &
PHI : CaseBB->
phis()) {
8072 Type *PHIType =
PHI.getType();
8080 if (PHIType == ConditionType || TryZExt) {
8082 bool SkipCase =
false;
8083 Value *Replacement =
nullptr;
8084 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
8085 Value *PHIValue =
PHI.getIncomingValue(
I);
8086 if (PHIValue != CaseValue) {
8095 if (
PHI.getIncomingBlock(
I) != SwitchBB)
8100 if (!CheckedForSinglePred) {
8101 CheckedForSinglePred =
true;
8102 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
8108 if (Replacement ==
nullptr) {
8109 if (PHIValue == CaseValue) {
8110 Replacement = Condition;
8113 Replacement = Builder.CreateZExt(Condition, PHIType);
8116 PHI.setIncomingValue(
I, Replacement);
8127bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
8128 bool Changed = optimizeSwitchType(SI);
8129 Changed |= optimizeSwitchPhiConstants(SI);
8150class VectorPromoteHelper {
8152 const DataLayout &
DL;
8155 const TargetLowering &TLI;
8158 const TargetTransformInfo &
TTI;
8164 SmallVector<Instruction *, 4> InstsToBePromoted;
8167 unsigned StoreExtractCombineCost;
8176 if (InstsToBePromoted.
empty())
8178 return InstsToBePromoted.
back();
8184 unsigned getTransitionOriginalValueIdx()
const {
8186 "Other kind of transitions are not supported yet");
8193 unsigned getTransitionIdx()
const {
8195 "Other kind of transitions are not supported yet");
8203 Type *getTransitionType()
const {
8214 void promoteImpl(Instruction *ToBePromoted);
8218 bool isProfitableToPromote() {
8219 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8223 Type *PromotedType = getTransitionType();
8226 unsigned AS =
ST->getPointerAddressSpace();
8244 for (
const auto &Inst : InstsToBePromoted) {
8252 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8264 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8265 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8266 return ScalarCost > VectorCost;
8278 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8293 if (!
EC.isScalable()) {
8294 SmallVector<Constant *, 4> ConstVec;
8296 for (
unsigned Idx = 0; Idx !=
EC.getKnownMinValue(); ++Idx) {
8297 if (Idx == ExtractIdx)
8305 "Generate scalable vector for non-splat is unimplemented");
8310 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8311 unsigned OperandIdx) {
8314 if (OperandIdx != 1)
8316 switch (
Use->getOpcode()) {
8319 case Instruction::SDiv:
8320 case Instruction::UDiv:
8321 case Instruction::SRem:
8322 case Instruction::URem:
8324 case Instruction::FDiv:
8325 case Instruction::FRem:
8326 return !
Use->hasNoNaNs();
8332 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8333 const TargetTransformInfo &
TTI, Instruction *Transition,
8334 unsigned CombineCost)
8335 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8336 StoreExtractCombineCost(CombineCost) {
8337 assert(Transition &&
"Do not know how to promote null");
8341 bool canPromote(
const Instruction *ToBePromoted)
const {
8348 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8351 for (
const Use &U : ToBePromoted->
operands()) {
8352 const Value *Val =
U.get();
8353 if (Val == getEndOfTransition()) {
8357 if (canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()))
8380 void enqueueForPromotion(Instruction *ToBePromoted) {
8381 InstsToBePromoted.push_back(ToBePromoted);
8385 void recordCombineInstruction(Instruction *ToBeCombined) {
8387 CombineInst = ToBeCombined;
8397 if (InstsToBePromoted.empty() || !CombineInst)
8405 for (
auto &ToBePromoted : InstsToBePromoted)
8406 promoteImpl(ToBePromoted);
8407 InstsToBePromoted.clear();
8414void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8424 "The type of the result of the transition does not match "
8429 Type *TransitionTy = getTransitionType();
8434 for (Use &U : ToBePromoted->
operands()) {
8436 Value *NewVal =
nullptr;
8437 if (Val == Transition)
8438 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8445 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8449 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8452 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8458bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8459 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8474 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8475 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost);
8482 if (ToBePromoted->
getParent() != Parent) {
8483 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8485 <<
") than the transition (" << Parent->
getName()
8490 if (VPH.canCombine(ToBePromoted)) {
8492 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8493 VPH.recordCombineInstruction(ToBePromoted);
8495 NumStoreExtractExposed +=
Changed;
8500 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8503 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8505 VPH.enqueueForPromotion(ToBePromoted);
8506 Inst = ToBePromoted;
8546 Type *StoreType =
SI.getValueOperand()->getType();
8555 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8556 DL.getTypeSizeInBits(StoreType) == 0)
8559 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8561 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8565 if (
SI.isVolatile())
8577 if (!
match(
SI.getValueOperand(),
8584 if (!
LValue->getType()->isIntegerTy() ||
8585 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8587 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8603 Builder.SetInsertPoint(&
SI);
8607 if (LBC && LBC->getParent() !=
SI.getParent())
8608 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8609 if (HBC && HBC->getParent() !=
SI.getParent())
8610 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8612 bool IsLE =
SI.getDataLayout().isLittleEndian();
8613 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8614 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8615 Value *Addr =
SI.getPointerOperand();
8616 Align Alignment =
SI.getAlign();
8617 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8618 if (IsOffsetStore) {
8619 Addr = Builder.CreateGEP(
8620 SplitStoreType, Addr,
8628 Builder.CreateAlignedStore(V, Addr, Alignment);
8631 CreateSplitStore(
LValue,
false);
8632 CreateSplitStore(HValue,
true);
8635 SI.eraseFromParent();
8643 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8725 if (GEPIOpI->getParent() != SrcBlock)
8730 if (auto *I = dyn_cast<Instruction>(Usr)) {
8731 if (I->getParent() != SrcBlock) {
8739 std::vector<GetElementPtrInst *> UGEPIs;
8742 for (User *Usr : GEPIOp->
users()) {
8761 if (UGEPI->getOperand(0) != GEPIOp)
8763 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8765 if (GEPIIdx->getType() !=
8773 UGEPIs.push_back(UGEPI);
8775 if (UGEPIs.size() == 0)
8778 for (GetElementPtrInst *UGEPI : UGEPIs) {
8780 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8787 for (GetElementPtrInst *UGEPI : UGEPIs) {
8788 UGEPI->setOperand(0, GEPI);
8790 Constant *NewUGEPIIdx = ConstantInt::get(
8791 GEPIIdx->getType(), UGEPIIdx->
getValue() - GEPIIdx->getValue());
8792 UGEPI->setOperand(1, NewUGEPIIdx);
8795 if (!GEPI->isInBounds()) {
8796 UGEPI->setIsInBounds(
false);
8803 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8805 "GEPIOp is used outside SrcBlock");
8829 Value *
X = Cmp->getOperand(0);
8830 if (!
X->hasUseList())
8835 for (
auto *U :
X->users()) {
8839 (UI->
getParent() != Branch->getParent() &&
8840 UI->
getParent() != Branch->getSuccessor(0) &&
8841 UI->
getParent() != Branch->getSuccessor(1)) ||
8842 (UI->
getParent() != Branch->getParent() &&
8843 !UI->
getParent()->getSinglePredecessor()))
8849 if (UI->
getParent() != Branch->getParent())
8853 ConstantInt::get(UI->
getType(), 0));
8855 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8859 if (Cmp->isEquality() &&
8864 if (UI->
getParent() != Branch->getParent())
8867 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8868 ConstantInt::get(UI->
getType(), 0));
8870 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8878bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8879 bool AnyChange =
false;
8880 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8884 if (InsertedInsts.count(
I))
8893 LargeOffsetGEPMap.erase(
P);
8895 P->eraseFromParent();
8918 I, LI->getLoopFor(
I->getParent()), *
TTI))
8926 TargetLowering::TypeExpandInteger) {
8930 I, LI->getLoopFor(
I->getParent()), *
TTI))
8933 bool MadeChange = optimizeExt(
I);
8934 return MadeChange | optimizeExtUses(
I);
8941 if (optimizeCmp(Cmp, ModifiedDT))
8945 if (optimizeURem(
I))
8949 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8950 bool Modified = optimizeLoadExt(LI);
8959 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8960 unsigned AS =
SI->getPointerAddressSpace();
8961 return optimizeMemoryInst(
I,
SI->getOperand(1),
8962 SI->getOperand(0)->getType(), AS);
8966 unsigned AS = RMW->getPointerAddressSpace();
8967 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
8971 unsigned AS = CmpX->getPointerAddressSpace();
8972 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
8973 CmpX->getCompareOperand()->getType(), AS);
8983 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
8984 BinOp->
getOpcode() == Instruction::LShr)) {
8992 if (GEPI->hasAllZeroIndices()) {
8994 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
8995 GEPI->getName(), GEPI->getIterator());
8996 NC->setDebugLoc(GEPI->getDebugLoc());
8999 GEPI, TLInfo,
nullptr,
9000 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9002 optimizeInst(
NC, ModifiedDT);
9025 if (Const0 || Const1) {
9026 if (!Const0 || !Const1) {
9027 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
9032 FI->eraseFromParent();
9039 if (tryToSinkFreeOperands(
I))
9042 switch (
I->getOpcode()) {
9043 case Instruction::Shl:
9044 case Instruction::LShr:
9045 case Instruction::AShr:
9047 case Instruction::Call:
9049 case Instruction::Select:
9051 case Instruction::ShuffleVector:
9053 case Instruction::Switch:
9055 case Instruction::ExtractElement:
9057 case Instruction::CondBr:
9066bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
9067 if (!
I.getType()->isIntegerTy() ||
9072 SmallVector<Instruction *, 4> Insts;
9078 &
I, TLInfo,
nullptr,
9079 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9086bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
9088 bool MadeChange =
false;
9091 CurInstIterator = BB.
begin();
9092 ModifiedDT = ModifyDT::NotModifyDT;
9093 while (CurInstIterator != BB.
end()) {
9094 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
9095 if (ModifiedDT != ModifyDT::NotModifyDT) {
9108 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
9110 bool MadeBitReverse =
true;
9111 while (MadeBitReverse) {
9112 MadeBitReverse =
false;
9114 if (makeBitReverse(
I)) {
9115 MadeBitReverse = MadeChange =
true;
9120 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
9125bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
9126 bool AnyChange =
false;
9127 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
9128 AnyChange |= fixupDbgVariableRecord(DVR);
9134bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
9135 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
9136 DVR.
Type != DbgVariableRecord::LocationType::Assign)
9140 bool AnyChange =
false;
9141 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
9143 for (
Value *Location : LocationOps) {
9144 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9173bool CodeGenPrepare::placeDbgValues(Function &
F) {
9174 bool MadeChange =
false;
9175 DominatorTree DT(
F);
9177 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9178 SmallVector<Instruction *, 4> VIs;
9179 for (
Value *V : DbgItem->location_ops())
9187 for (Instruction *VI : VIs) {
9188 if (
VI->isTerminator())
9193 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9204 if (VIs.size() > 1) {
9207 <<
"Unable to find valid location for Debug Value, undefing:\n"
9209 DbgItem->setKillLocation();
9214 << *DbgItem <<
' ' << *VI);
9221 for (BasicBlock &BB :
F) {
9227 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9229 DbgProcessor(&DVR, &Insn);
9240bool CodeGenPrepare::placePseudoProbes(Function &
F) {
9241 bool MadeChange =
false;
9244 auto FirstInst =
Block.getFirstInsertionPt();
9245 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9249 while (
I !=
Block.end()) {
9251 II->moveBefore(FirstInst);
9261 uint64_t NewMax = (NewTrue > NewFalse) ? NewTrue : NewFalse;
9262 uint32_t Scale = (NewMax / std::numeric_limits<uint32_t>::max()) + 1;
9263 NewTrue = NewTrue / Scale;
9264 NewFalse = NewFalse / Scale;
9289bool CodeGenPrepare::splitBranchCondition(Function &
F, ModifyDT &ModifiedDT) {
9293 bool MadeChange =
false;
9294 for (
auto &BB :
F) {
9307 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9315 Value *Cond1, *Cond2;
9318 Opc = Instruction::And;
9321 Opc = Instruction::Or;
9331 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9345 Br1->setCondition(Cond1);
9350 if (
Opc == Instruction::And)
9351 Br1->setSuccessor(0, TmpBB);
9353 Br1->setSuccessor(1, TmpBB);
9358 I->removeFromParent();
9359 I->insertBefore(Br2->getIterator());
9371 if (
Opc == Instruction::Or)
9378 for (PHINode &PN : FBB->
phis()) {
9385 if (
Opc == Instruction::Or) {
9405 uint64_t TrueWeight, FalseWeight;
9407 uint64_t NewTrueWeight = TrueWeight;
9408 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9410 Br1->setMetadata(LLVMContext::MD_prof,
9411 MDBuilder(Br1->getContext())
9412 .createBranchWeights(TrueWeight, FalseWeight,
9415 NewTrueWeight = TrueWeight;
9416 NewFalseWeight = 2 * FalseWeight;
9418 Br2->setMetadata(LLVMContext::MD_prof,
9419 MDBuilder(Br2->getContext())
9420 .createBranchWeights(TrueWeight, FalseWeight));
9441 uint64_t TrueWeight, FalseWeight;
9443 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9444 uint64_t NewFalseWeight = FalseWeight;
9446 Br1->setMetadata(LLVMContext::MD_prof,
9447 MDBuilder(Br1->getContext())
9448 .createBranchWeights(TrueWeight, FalseWeight));
9450 NewTrueWeight = 2 * TrueWeight;
9451 NewFalseWeight = FalseWeight;
9453 Br2->setMetadata(LLVMContext::MD_prof,
9454 MDBuilder(Br2->getContext())
9455 .createBranchWeights(TrueWeight, FalseWeight));
9459 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(CondBrInst *Branch, const TargetLowering &TLI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
static bool tryUnmergingGEPsAcrossIndirectBr(GetElementPtrInst *GEPI, const TargetTransformInfo *TTI)
static bool IsOperandAMemoryOperand(CallInst *CI, InlineAsm *IA, Value *OpVal, const TargetLowering &TLI, const TargetRegisterInfo &TRI)
Check to see if all uses of OpVal by the specified inline asm call are due to memory operands.
static bool isIntrinsicOrLFToBeTailCalled(const TargetLibraryInfo *TLInfo, const CallInst *CI)
static void replaceAllUsesWith(Value *Old, Value *New, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
Replace all old uses with new ones, and push the updated BBs into FreshBBs.
static cl::opt< bool > ForceSplitStore("force-split-store", cl::Hidden, cl::init(false), cl::desc("Force store splitting no matter what the target query says."))
static bool matchOverflowPattern(Instruction *&I, ExtractValueInst *&MulExtract, ExtractValueInst *&OverflowExtract)
static void computeBaseDerivedRelocateMap(const SmallVectorImpl< GCRelocateInst * > &AllRelocateCalls, MapVector< GCRelocateInst *, SmallVector< GCRelocateInst *, 0 > > &RelocateInstMap)
static bool simplifyRelocatesOffABase(GCRelocateInst *RelocatedBase, const SmallVectorImpl< GCRelocateInst * > &Targets)
static cl::opt< bool > AddrSinkCombineScaledReg("addr-sink-combine-scaled-reg", cl::Hidden, cl::init(true), cl::desc("Allow combining of ScaledReg field in Address sinking."))
static bool foldICmpWithDominatingICmp(CmpInst *Cmp, const TargetLowering &TLI)
For pattern like:
static bool MightBeFoldableInst(Instruction *I)
This is a little filter, which returns true if an addressing computation involving I might be folded ...
static bool matchIncrement(const Instruction *IVInc, Instruction *&LHS, Constant *&Step)
static cl::opt< bool > EnableGEPOffsetSplit("cgp-split-large-offset-gep", cl::Hidden, cl::init(true), cl::desc("Enable splitting large offset of GEP."))
static cl::opt< bool > DisableComplexAddrModes("disable-complex-addr-modes", cl::Hidden, cl::init(false), cl::desc("Disables combining addressing modes with different parts " "in optimizeMemoryInst."))
static cl::opt< bool > EnableICMP_EQToICMP_ST("cgp-icmp-eq2icmp-st", cl::Hidden, cl::init(false), cl::desc("Enable ICMP_EQ to ICMP_S(L|G)T conversion."))
static cl::opt< bool > VerifyBFIUpdates("cgp-verify-bfi-updates", cl::Hidden, cl::init(false), cl::desc("Enable BFI update verification for " "CodeGenPrepare."))
static cl::opt< bool > BBSectionsGuidedSectionPrefix("bbsections-guided-section-prefix", cl::Hidden, cl::init(true), cl::desc("Use the basic-block-sections profile to determine the text " "section prefix for hot functions. Functions with " "basic-block-sections profile will be placed in `.text.hot` " "regardless of their FDO profile info. Other functions won't be " "impacted, i.e., their prefixes will be decided by FDO/sampleFDO " "profiles."))
static bool isRemOfLoopIncrementWithLoopInvariant(Instruction *Rem, const LoopInfo *LI, Value *&RemAmtOut, Value *&AddInstOut, Value *&AddOffsetOut, PHINode *&LoopIncrPNOut)
static bool isIVIncrement(const Value *V, const LoopInfo *LI)
static cl::opt< bool > DisableGCOpts("disable-cgp-gc-opts", cl::Hidden, cl::init(false), cl::desc("Disable GC optimizations in CodeGenPrepare"))
static bool GEPSequentialConstIndexed(GetElementPtrInst *GEP)
static void DbgInserterHelper(DbgVariableRecord *DVR, BasicBlock::iterator VI)
static bool isPromotedInstructionLegal(const TargetLowering &TLI, const DataLayout &DL, Value *Val)
Check whether or not Val is a legal instruction for TLI.
static cl::opt< uint64_t > FreqRatioToSkipMerge("cgp-freq-ratio-to-skip-merge", cl::Hidden, cl::init(2), cl::desc("Skip merging empty blocks if (frequency of empty block) / " "(frequency of destination block) is greater than this ratio"))
static BasicBlock::iterator findInsertPos(Value *Addr, Instruction *MemoryInst, Value *SunkAddr)
static bool IsNonLocalValue(Value *V, BasicBlock *BB)
Return true if the specified values are defined in a different basic block than BB.
static cl::opt< bool > EnableAndCmpSinking("enable-andcmp-sinking", cl::Hidden, cl::init(true), cl::desc("Enable sinking and/cmp into branches."))
static bool 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 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.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
void setAlignment(Align Align)
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addRequired()
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...
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
const Function * getParent() const
Return the enclosing method, or null if none.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI void insertDbgRecordBefore(DbgRecord *DR, InstListType::iterator Here)
Insert a DbgRecord into a block at the position given by Here.
InstListType::const_iterator const_iterator
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
LLVM_ABI InstListType::const_iterator getFirstNonPHIOrDbg(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic,...
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
LLVM_ABI 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.
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI void setBlockFreq(const BasicBlock *BB, BlockFrequency Freq)
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
LLVM_ABI std::optional< BlockFrequency > mul(uint64_t Factor) const
Multiplies frequency with Factor. Returns nullopt in case of overflow.
Analysis pass which computes BranchProbabilityInfo.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
Predicate getPredicate() const
Return the predicate for this instruction.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Conditional Branch instruction.
static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI void removeFromParent()
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LocationType Type
Classification of the debug-info record that this DbgVariableRecord represents.
LLVM_ABI void replaceVariableLocationOp(Value *OldValue, Value *NewValue, bool AllowEmpty=false)
LLVM_ABI iterator_range< location_op_iterator > location_ops() const
Get the locations corresponding to the variable referenced by the debug info intrinsic.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
LLVM_ABI 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.
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This instruction compares its operands according to the predicate given to the constructor.
bool isEquality() const
Return true if this predicate is either EQ or NE.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
LLVM_ABI bool isDebugOrPseudoInst() const LLVM_READONLY
Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void moveAfter(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
LLVM_ABI std::optional< simple_ilist< DbgRecord >::iterator > getDbgReinsertionPosition()
Return an iterator to the position of the "Next" DbgRecord after this instruction,...
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
LLVM_ABI void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
An instruction for reading from memory.
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
Analysis pass that exposes the LoopInfo for a function.
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
void analyze(const DominatorTreeBase< BlockT, false > &DomTree)
Create the loop forest using a stable algorithm.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
The legacy pass manager's analysis pass to compute loop information.
Represents a single loop in the control flow graph.
static MVT getIntegerVT(unsigned BitWidth)
LLVM_ABI void replacePhiUsesWith(MachineBasicBlock *Old, MachineBasicBlock *New)
Update all phi nodes in this basic block to refer to basic block New instead of basic block Old.
This class implements a map that also provides access to all stored values in a deterministic order.
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...
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)
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
void clear()
Completely clear the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
VectorType * getType() const
Overload to return most specific vector type.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator erase(const_iterator CI)
typename SuperClass::iterator iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
static unsigned getPointerOperandIndex()
TypeSize getElementOffset(unsigned Idx) const
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
int InstructionOpcodeToISD(unsigned Opcode) const
Get the ISD node that corresponds to the Instruction class opcode.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool isSelectSupported(SelectSupportKind) const
virtual bool isEqualityCmpFoldedWithSignedCmp() const
Return true if instruction generated for equality comparison is folded with instruction generated for...
virtual bool shouldFormOverflowOp(unsigned Opcode, EVT VT, bool MathUsed) const
Try to convert math with an overflow comparison into the corresponding DAG node operation.
virtual bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const
Return if the target supports combining a chain like:
virtual bool shouldOptimizeMulOverflowWithZeroHighBits(LLVMContext &Context, EVT VT) const
bool isExtLoad(const LoadInst *Load, const Instruction *Ext, const DataLayout &DL) const
Return true if Load and Ext can form an ExtLoad.
virtual bool isSExtCheaperThanZExt(EVT FromTy, EVT ToTy) const
Return true if sign-extension from FromTy to ToTy is cheaper than zero-extension.
const TargetMachine & getTargetMachine() const
virtual bool isCtpopFast(EVT VT) const
Return true if ctpop instruction is fast.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
bool enableExtLdPromotion() const
Return true if the target wants to use the optimization that turns ext(promotableInst1(....
virtual bool isCheapToSpeculateCttz(Type *Ty) const
Return true if it is cheap to speculate a call to intrinsic cttz.
bool isJumpExpensive() const
Return true if Flow Control is an expensive operation that should be avoided.
bool hasExtractBitsInsn() const
Return true if the target has BitExtract instructions.
virtual bool allowsMisalignedMemoryAccesses(EVT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *=nullptr) const
Determine if the target supports unaligned memory accesses.
bool isSlowDivBypassed() const
Returns true if target has indicated at least one type should be bypassed.
virtual bool isTruncateFree(Type *FromTy, Type *ToTy) const
Return true if it's free to truncate a value of type FromTy to type ToTy.
virtual bool hasMultipleConditionRegisters(EVT VT) const
Does the target have multiple (allocatable) condition registers that can be used to store the results...
virtual EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
virtual MVT getPreferredSwitchConditionType(LLVMContext &Context, EVT ConditionVT) const
Returns preferred type for switch condition.
bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const
Return true if the specified condition code is legal for a comparison of the specified types on this ...
virtual bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx, unsigned &Cost) const
Return true if the target can combine store(extractelement VectorTy,Idx).
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual bool isFreeAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const
Returns true if a cast from SrcAS to DestAS is "cheap", such that e.g.
virtual bool shouldConsiderGEPOffsetSplit() const
bool isExtFree(const Instruction *I) const
Return true if the extension represented by I is free.
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
bool isPredictableSelectExpensive() const
Return true if selects are only cheaper than branches if the branch is unlikely to be predicted right...
virtual bool isMultiStoresCheaperThanBitsMerge(EVT LTy, EVT HTy) const
Return true if it is cheaper to split the store of a merged int val from a pair of smaller values int...
virtual bool getAddrModeArguments(const IntrinsicInst *, SmallVectorImpl< Value * > &, Type *&) const
CodeGenPrepare sinks address calculations into the same BB as Load/Store instructions reading the add...
const DenseMap< unsigned int, unsigned int > & getBypassSlowDivWidths() const
Returns map of slow types for division or remainder with corresponding fast types.
virtual bool isCheapToSpeculateCtlz(Type *Ty) const
Return true if it is cheap to speculate a call to intrinsic ctlz.
virtual bool useSoftFloat() const
virtual int64_t getPreferredLargeGEPBaseOffset(int64_t MinOffset, int64_t MaxOffset) const
Return the prefered common base offset.
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
virtual bool shouldAlignPointerArgs(CallInst *, unsigned &, Align &) const
Return true if the pointer arguments to CI should be aligned by aligning the object whose address is ...
virtual Type * shouldConvertSplatType(ShuffleVectorInst *SVI) const
Given a shuffle vector SVI representing a vector splat, return a new scalar type of size equal to SVI...
bool isLoadLegal(EVT ValVT, EVT MemVT, Align Alignment, unsigned AddrSpace, unsigned ExtType, bool Atomic) const
Return true if the specified load with extension is legal on this target.
virtual bool addressingModeSupportsTLS(const GlobalValue &) const
Returns true if the targets addressing mode can target thread local storage (TLS).
virtual bool shouldConvertPhiType(Type *From, Type *To) const
Given a set in interconnected phis of type 'From' that are loaded/stored or bitcast to type 'To',...
virtual bool isFAbsFree(EVT VT) const
Return true if an fabs operation is free to the point where it is never worthwhile to replace it with...
virtual bool preferZeroCompareBranch() const
Return true if the heuristic to prefer icmp eq zero should be used in code gen prepare.
virtual bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AddrSpace, Instruction *I=nullptr) const
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
virtual bool optimizeExtendOrTruncateConversion(Instruction *I, Loop *L, const TargetTransformInfo &TTI) const
Try to optimize extending or truncating conversion instructions (like zext, trunc,...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
std::vector< AsmOperandInfo > AsmOperandInfoVector
virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL, const TargetRegisterInfo *TRI, const CallBase &Call) const
Split up the constraint string from the inline assembly value into the specific constraints and their...
virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op, SelectionDAG *DAG=nullptr) const
Determines the constraint code and constraint type to use for the specific AsmOperandInfo,...
virtual bool mayBeEmittedAsTailCall(const CallInst *) const
Return true if the target may be able emit the call instruction as a tail call.
virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const
Returns true if a cast between SrcAS and DestAS is a noop.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
unsigned EnableFastISel
EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...
Target-Independent Code Generator Pass Configuration Options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
virtual bool addrSinkUsingGEPs() const
Sink addresses into blocks using GEP instructions rather than pointer casts and arithmetic.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
BasicBlock * getSuccessor(unsigned i=0) const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
LLVM_ABI bool isUsedInBasicBlock(const BasicBlock *BB) const
Check if this value is used in the specified basic block.
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
iterator_range< use_iterator > uses()
void mutateType(Type *Ty)
Mutate the type of this Value to be of the specified type.
user_iterator_impl< User > user_iterator
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
bool pointsToAliveValue() const
int getNumOccurrences() const
constexpr ScalarTy getFixedValue() const
constexpr bool isNonZero() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ C
The default llvm calling convention, compatible with C.
unsigned getAddrMode(MCInstrInfo const &MCII, MCInst const &MCI)
@ BasicBlock
Various leaf nodes.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
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 bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
auto unique(Range &&R, Predicate P)
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
LLVM_ABI bool hasBranchWeightOrigin(const Instruction &I)
Check if Branch Weight Metadata has an "expected" field from an llvm.expect* intrinsic.
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
LLVM_ABI bool 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.