45#include "llvm/Config/llvm-config.h"
66#include "llvm/IR/IntrinsicsAArch64.h"
110#define DEBUG_TYPE "codegenprepare"
113STATISTIC(NumPHIsElim,
"Number of trivial PHIs eliminated");
114STATISTIC(NumGEPsElim,
"Number of GEPs converted to casts");
115STATISTIC(NumCmpUses,
"Number of uses of Cmp expressions replaced with uses of "
117STATISTIC(NumCastUses,
"Number of uses of Cast expressions replaced with uses "
119STATISTIC(NumMemoryInsts,
"Number of memory instructions whose address "
120 "computations were sunk");
122 "Number of phis created when address "
123 "computations were sunk to memory instructions");
125 "Number of select created when address "
126 "computations were sunk to memory instructions");
127STATISTIC(NumExtsMoved,
"Number of [s|z]ext instructions combined with loads");
128STATISTIC(NumExtUses,
"Number of uses of [s|z]ext instructions optimized");
130 "Number of and mask instructions added to form ext loads");
131STATISTIC(NumAndUses,
"Number of uses of and mask instructions optimized");
132STATISTIC(NumRetsDup,
"Number of return instructions duplicated");
133STATISTIC(NumDbgValueMoved,
"Number of debug value instructions moved");
134STATISTIC(NumSelectsExpanded,
"Number of selects turned into branches");
135STATISTIC(NumStoreExtractExposed,
"Number of store(extractelement) exposed");
139 cl::desc(
"Disable branch optimizations in CodeGenPrepare"));
143 cl::desc(
"Disable GC optimizations in CodeGenPrepare"));
148 cl::desc(
"Disable select to branch conversion."));
152 cl::desc(
"Address sinking in CGP using GEPs."));
156 cl::desc(
"Enable sinking and/cmp into branches."));
160 cl::desc(
"Disable store(extract) optimizations in CodeGenPrepare"));
164 cl::desc(
"Stress test store(extract) optimizations in CodeGenPrepare"));
168 cl::desc(
"Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in "
173 cl::desc(
"Stress test ext(promotable(ld)) -> promoted(ext(ld)) "
174 "optimization in CodeGenPrepare"));
178 cl::desc(
"Disable protection against removing loop preheaders"));
182 cl::desc(
"Use profile info to add section prefix for hot/cold functions"));
185 "profile-unknown-in-special-section",
cl::Hidden,
186 cl::desc(
"In profiling mode like sampleFDO, if a function doesn't have "
187 "profile, we cannot tell the function is cold for sure because "
188 "it may be a function newly added without ever being sampled. "
189 "With the flag enabled, compiler can put such profile unknown "
190 "functions into a special section, so runtime system can choose "
191 "to handle it in a different way than .text section, to save "
192 "RAM for example. "));
196 cl::desc(
"Use the basic-block-sections profile to determine the text "
197 "section prefix for hot functions. Functions with "
198 "basic-block-sections profile will be placed in `.text.hot` "
199 "regardless of their FDO profile info. Other functions won't be "
200 "impacted, i.e., their prefixes will be decided by FDO/sampleFDO "
205 cl::desc(
"Skip merging empty blocks if (frequency of empty block) / "
206 "(frequency of destination block) is greater than this ratio"));
210 cl::desc(
"Force store splitting no matter what the target query says."));
214 cl::desc(
"Enable merging of redundant sexts when one is dominating"
220 cl::desc(
"Disables combining addressing modes with different parts "
221 "in optimizeMemoryInst."));
225 cl::desc(
"Allow creation of Phis in Address sinking."));
229 cl::desc(
"Allow creation of selects in Address sinking."));
233 cl::desc(
"Allow combining of BaseReg field in Address sinking."));
237 cl::desc(
"Allow combining of BaseGV field in Address sinking."));
241 cl::desc(
"Allow combining of BaseOffs field in Address sinking."));
245 cl::desc(
"Allow combining of ScaledReg field in Address sinking."));
250 cl::desc(
"Enable splitting large offset of GEP."));
254 cl::desc(
"Enable ICMP_EQ to ICMP_S(L|G)T conversion."));
258 cl::desc(
"Enable BFI update verification for "
263 cl::desc(
"Enable converting phi types in CodeGenPrepare"));
267 cl::desc(
"Least BB number of huge function."));
272 cl::desc(
"Max number of address users to look at"));
276 cl::desc(
"Disable elimination of dead PHI nodes."));
304class TypePromotionTransaction;
306class CodeGenPrepare {
307 friend class CodeGenPrepareLegacyPass;
308 const TargetMachine *TM =
nullptr;
309 const TargetSubtargetInfo *SubtargetInfo =
nullptr;
310 const TargetLowering *TLI =
nullptr;
311 const TargetRegisterInfo *TRI =
nullptr;
312 const TargetTransformInfo *TTI =
nullptr;
313 const BasicBlockSectionsProfileReader *BBSectionsProfileReader =
nullptr;
314 const TargetLibraryInfo *TLInfo =
nullptr;
315 LoopInfo *LI =
nullptr;
316 std::unique_ptr<BlockFrequencyInfo> BFI;
317 std::unique_ptr<BranchProbabilityInfo> BPI;
318 ProfileSummaryInfo *PSI =
nullptr;
329 ValueMap<Value *, WeakTrackingVH> SunkAddrs;
332 SetOfInstrs InsertedInsts;
336 InstrToOrigTy PromotedInsts;
339 SetOfInstrs RemovedInsts;
342 DenseMap<Value *, Instruction *> SeenChainsForSExt;
347 MapVector<AssertingVH<Value>,
352 SmallSet<AssertingVH<Value>, 2> NewGEPBases;
355 DenseMap<AssertingVH<GetElementPtrInst>,
int> LargeOffsetGEPID;
358 ValueToSExts ValToSExtendedUses;
364 const DataLayout *DL =
nullptr;
368 std::unique_ptr<DominatorTree> DT;
371 CodeGenPrepare() =
default;
372 CodeGenPrepare(
const TargetMachine *TM) : TM(TM){};
374 bool IsHugeFunc =
false;
380 SmallPtrSet<BasicBlock *, 32> FreshBBs;
382 void releaseMemory() {
384 InsertedInsts.clear();
385 PromotedInsts.clear();
394 template <
typename F>
395 void resetIteratorIfInvalidatedWhileCalling(BasicBlock *BB,
F f) {
399 Value *CurValue = &*CurInstIterator;
400 WeakTrackingVH IterHandle(CurValue);
406 if (IterHandle != CurValue) {
407 CurInstIterator = BB->
begin();
413 DominatorTree &getDT(Function &
F) {
415 DT = std::make_unique<DominatorTree>(
F);
419 void removeAllAssertingVHReferences(
Value *V);
420 bool eliminateAssumptions(Function &
F);
421 bool eliminateFallThrough(Function &
F, DominatorTree *DT =
nullptr);
422 bool eliminateMostlyEmptyBlocks(Function &
F);
423 BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB);
424 bool canMergeBlocks(
const BasicBlock *BB,
const BasicBlock *DestBB)
const;
425 void eliminateMostlyEmptyBlock(BasicBlock *BB);
426 bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB,
428 bool makeBitReverse(Instruction &
I);
430 bool optimizeInst(Instruction *
I, ModifyDT &ModifiedDT);
431 bool optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
Type *AccessTy,
433 bool optimizeGatherScatterInst(Instruction *MemoryInst,
Value *Ptr);
434 bool optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
435 ModifyDT &ModifiedDT);
436 bool optimizeInlineAsmInst(CallInst *CS);
438 bool optimizeExt(Instruction *&
I);
439 bool optimizeExtUses(Instruction *
I);
440 bool optimizeLoadExt(LoadInst *Load);
441 bool optimizeShiftInst(BinaryOperator *BO);
442 bool optimizeFunnelShift(IntrinsicInst *Fsh);
443 bool optimizeSelectInst(SelectInst *SI);
444 bool optimizeShuffleVectorInst(ShuffleVectorInst *SVI);
445 bool optimizeSwitchType(SwitchInst *SI);
446 bool optimizeSwitchPhiConstants(SwitchInst *SI);
447 bool optimizeSwitchInst(SwitchInst *SI);
448 bool optimizeExtractElementInst(Instruction *Inst);
449 bool dupRetToEnableTailCallOpts(BasicBlock *BB, ModifyDT &ModifiedDT);
450 bool fixupDbgVariableRecord(DbgVariableRecord &
I);
451 bool fixupDbgVariableRecordsOnInst(Instruction &
I);
452 bool placeDbgValues(Function &
F);
453 bool placePseudoProbes(Function &
F);
454 bool canFormExtLd(
const SmallVectorImpl<Instruction *> &MovedExts,
455 LoadInst *&LI, Instruction *&Inst,
bool HasPromoted);
456 bool tryToPromoteExts(TypePromotionTransaction &TPT,
457 const SmallVectorImpl<Instruction *> &Exts,
458 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
459 unsigned CreatedInstsCost = 0);
460 bool mergeSExts(Function &
F);
461 bool splitLargeGEPOffsets();
462 bool optimizePhiType(PHINode *Inst, SmallPtrSetImpl<PHINode *> &Visited,
463 SmallPtrSetImpl<Instruction *> &DeletedInstrs);
464 bool optimizePhiTypes(Function &
F);
465 bool performAddressTypePromotion(
466 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
467 bool HasPromoted, TypePromotionTransaction &TPT,
468 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts);
469 bool splitBranchCondition(Function &
F, ModifyDT &ModifiedDT);
470 bool simplifyOffsetableRelocate(GCStatepointInst &
I);
472 bool tryToSinkFreeOperands(Instruction *
I);
473 bool replaceMathCmpWithIntrinsic(BinaryOperator *BO,
Value *Arg0,
Value *Arg1,
475 bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT);
476 bool optimizeURem(Instruction *Rem);
477 bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
478 bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
479 bool unfoldPowerOf2Test(CmpInst *Cmp);
480 void verifyBFIUpdates(Function &
F);
481 bool _run(Function &
F);
488 CodeGenPrepareLegacyPass() : FunctionPass(ID) {}
492 StringRef getPassName()
const override {
return "CodeGen Prepare"; }
494 void getAnalysisUsage(AnalysisUsage &AU)
const override {
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.reset(
new BranchProbabilityInfo(
F, *CGP.LI));
522 CGP.BFI.reset(
new BlockFrequencyInfo(
F, *CGP.BPI, *CGP.LI));
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);
645 LI->analyze(getDT(
F));
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());
698 LI->verify(getDT(
F));
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())
858 if (Term && !
Term->isConditional()) {
870 FreshBBs.
insert(SinglePred);
878 for (
const auto &Pred : Preds)
886BasicBlock *CodeGenPrepare::findDestBlockOfMergeableEmptyBlock(BasicBlock *BB) {
895 if (BBI != BB->
begin()) {
906 if (!canMergeBlocks(BB, DestBB))
916bool CodeGenPrepare::eliminateMostlyEmptyBlocks(Function &
F) {
917 SmallPtrSet<BasicBlock *, 16> Preheaders;
919 while (!LoopList.empty()) {
920 Loop *
L = LoopList.pop_back_val();
922 if (BasicBlock *Preheader =
L->getLoopPreheader())
923 Preheaders.
insert(Preheader);
926 bool MadeChange =
false;
938 for (
auto &
Block : Blocks) {
942 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
944 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.
count(BB)))
947 eliminateMostlyEmptyBlock(BB);
953bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB,
1004 SmallPtrSet<BasicBlock *, 16> SameIncomingValueBBs;
1009 if (DestBBPred == BB)
1013 return DestPN.getIncomingValueForBlock(BB) ==
1014 DestPN.getIncomingValueForBlock(DestBBPred);
1016 SameIncomingValueBBs.
insert(DestBBPred);
1022 if (SameIncomingValueBBs.
count(Pred))
1025 BlockFrequency PredFreq = BFI->getBlockFreq(Pred);
1026 BlockFrequency
BBFreq = BFI->getBlockFreq(BB);
1028 for (
auto *SameValueBB : SameIncomingValueBBs)
1029 if (SameValueBB->getUniquePredecessor() == Pred &&
1030 DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
1031 BBFreq += BFI->getBlockFreq(SameValueBB);
1034 return !Limit || PredFreq <= *Limit;
1040bool CodeGenPrepare::canMergeBlocks(
const BasicBlock *BB,
1041 const BasicBlock *DestBB)
const {
1045 for (
const PHINode &PN : BB->
phis()) {
1046 for (
const User *U : PN.users()) {
1055 for (
unsigned I = 0,
E = UPN->getNumIncomingValues();
I !=
E; ++
I) {
1058 Insn->
getParent() != UPN->getIncomingBlock(
I))
1073 SmallPtrSet<const BasicBlock *, 16> BBPreds;
1076 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1077 BBPreds.
insert(BBPN->getIncomingBlock(i));
1085 if (BBPreds.
count(Pred)) {
1086 for (
const PHINode &PN : DestBB->
phis()) {
1087 const Value *V1 = PN.getIncomingValueForBlock(Pred);
1088 const Value *V2 = PN.getIncomingValueForBlock(BB);
1092 if (V2PN->getParent() == BB)
1093 V2 = V2PN->getIncomingValueForBlock(Pred);
1123void CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
1133 if (SinglePred != DestBB) {
1134 assert(SinglePred == BB &&
1135 "Single predecessor not the same as predecessor");
1144 FreshBBs.
insert(SinglePred);
1145 FreshBBs.
erase(DestBB);
1153 for (PHINode &PN : DestBB->
phis()) {
1155 Value *InVal = PN.removeIncomingValue(BB,
false);
1160 if (InValPhi && InValPhi->
getParent() == BB) {
1169 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1170 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1173 PN.addIncoming(InVal, Pred);
1203 for (
auto *ThisRelocate : AllRelocateCalls) {
1204 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1205 ThisRelocate->getDerivedPtrIndex());
1206 RelocateIdxMap.
insert(std::make_pair(K, ThisRelocate));
1208 for (
auto &Item : RelocateIdxMap) {
1209 std::pair<unsigned, unsigned>
Key = Item.first;
1210 if (
Key.first ==
Key.second)
1215 auto BaseKey = std::make_pair(
Key.first,
Key.first);
1218 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1219 if (MaybeBase == RelocateIdxMap.
end())
1224 RelocateInstMap[MaybeBase->second].push_back(
I);
1232 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1235 if (!
Op ||
Op->getZExtValue() > 20)
1239 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1249 bool MadeChange =
false;
1256 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1257 &*R != RelocatedBase; ++R)
1261 RelocatedBase->
moveBefore(RI->getIterator());
1268 "Not relocating a derived object of the original base object");
1269 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1274 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1284 if (!Derived || Derived->getPointerOperand() !=
Base)
1293 "Should always have one since it's not a terminator");
1297 Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
1321 Value *ActualRelocatedBase = RelocatedBase;
1322 if (RelocatedBase->
getType() !=
Base->getType()) {
1323 ActualRelocatedBase =
1324 Builder.CreateBitCast(RelocatedBase,
Base->getType());
1326 Value *Replacement =
1327 Builder.CreateGEP(Derived->getSourceElementType(), ActualRelocatedBase,
1333 Value *ActualReplacement = Replacement;
1334 if (Replacement->
getType() != ToReplace->getType()) {
1336 Builder.CreateBitCast(Replacement, ToReplace->
getType());
1339 ToReplace->eraseFromParent();
1363bool CodeGenPrepare::simplifyOffsetableRelocate(GCStatepointInst &
I) {
1364 bool MadeChange =
false;
1366 for (
auto *U :
I.users())
1373 if (AllRelocateCalls.
size() < 2)
1378 MapVector<GCRelocateInst *, SmallVector<GCRelocateInst *, 0>> RelocateInstMap;
1380 if (RelocateInstMap.
empty())
1383 for (
auto &Item : RelocateInstMap)
1397 bool MadeChange =
false;
1400 Use &TheUse = UI.getUse();
1407 UserBB = PN->getIncomingBlock(TheUse);
1415 if (
User->isEHPad())
1425 if (UserBB == DefBB)
1429 CastInst *&InsertedCast = InsertedCasts[UserBB];
1431 if (!InsertedCast) {
1439 TheUse = InsertedCast;
1465 ASC->getDestAddressSpace()))
1520static std::optional<std::pair<Instruction *, Constant *>>
1523 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1524 return std::nullopt;
1527 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1528 return std::nullopt;
1532 return std::make_pair(IVInc, Step);
1533 return std::nullopt;
1546 return IVInc->first ==
I;
1550bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
1554 auto IsReplacableIVIncrement = [
this, &
Cmp](BinaryOperator *BO) {
1557 const Loop *
L = LI->getLoopFor(BO->
getParent());
1558 assert(L &&
"L should not be null after isIVIncrement()");
1560 if (LI->getLoopFor(
Cmp->getParent()) != L)
1566 auto &DT = getDT(*BO->
getParent()->getParent());
1575 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1598 if (BO->
getOpcode() == Instruction::Add &&
1599 IID == Intrinsic::usub_with_overflow) {
1606 for (Instruction &Iter : *
Cmp->getParent()) {
1609 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1614 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1617 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1618 if (BO->
getOpcode() != Instruction::Xor) {
1619 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1623 "Patterns with XOr should use the BO only in the compare");
1624 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1626 Cmp->eraseFromParent();
1636 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1644 B = ConstantInt::get(
B->getType(), 1);
1652 for (
User *U :
A->users()) {
1663bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp,
1664 ModifyDT &ModifiedDT) {
1665 bool EdgeCase =
false;
1667 BinaryOperator *
Add;
1672 A =
Add->getOperand(0);
1673 B =
Add->getOperand(1);
1679 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1685 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1688 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1689 Intrinsic::uadd_with_overflow))
1693 ModifiedDT = ModifyDT::ModifyInstDT;
1697bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
1698 ModifyDT &ModifiedDT) {
1705 ICmpInst::Predicate Pred =
Cmp->getPredicate();
1706 if (Pred == ICmpInst::ICMP_UGT) {
1708 Pred = ICmpInst::ICMP_ULT;
1712 B = ConstantInt::get(
B->getType(), 1);
1713 Pred = ICmpInst::ICMP_ULT;
1718 Pred = ICmpInst::ICMP_ULT;
1720 if (Pred != ICmpInst::ICMP_ULT)
1727 BinaryOperator *
Sub =
nullptr;
1728 for (User *U : CmpVariableOperand->
users()) {
1736 const APInt *CmpC, *AddC;
1748 Sub->hasNUsesOrMore(1)))
1754 if (
Sub->getParent() !=
Cmp->getParent() && !
Sub->hasOneUse())
1757 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1758 Cmp, Intrinsic::usub_with_overflow))
1762 ModifiedDT = ModifyDT::ModifyInstDT;
1769bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1783 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1789 Type *OpTy =
X->getType();
1797 if (Pred == ICmpInst::ICMP_EQ) {
1798 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1799 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1801 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1807 if (IsPowerOf2OrZeroTest ||
1818 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1827 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1830 Cmp->replaceAllUsesWith(NewCmp);
1850 bool UsedInPhiOrCurrentBlock =
any_of(Cmp->users(), [Cmp](
User *U) {
1851 return isa<PHINode>(U) ||
1852 cast<Instruction>(U)->getParent() == Cmp->getParent();
1857 if (UsedInPhiOrCurrentBlock && Cmp->getOperand(0)->getType()->isIntegerTy() &&
1858 Cmp->getOperand(0)->getType()->getScalarSizeInBits() >
1859 DL.getLargestLegalIntTypeSizeInBits())
1865 bool MadeChange =
false;
1868 Use &TheUse = UI.getUse();
1883 if (UserBB == DefBB)
1887 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1893 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1900 TheUse = InsertedCmp;
1906 if (Cmp->use_empty()) {
1907 Cmp->eraseFromParent();
1944 for (
User *U : Cmp->users()) {
1966 if (CmpBB != FalseBB)
1969 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
1983 for (
User *U : Cmp->users()) {
1992 SI->swapProfMetadata();
2004 Value *Op0 = Cmp->getOperand(0);
2005 Value *Op1 = Cmp->getOperand(1);
2014 unsigned NumInspected = 0;
2017 if (++NumInspected > 128)
2025 if (GoodToSwap > 0) {
2026 Cmp->swapOperands();
2046 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
2049 auto [ClassVal, ClassTest] =
2055 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2059 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
2060 Cmp->replaceAllUsesWith(IsFPClass);
2068 Value *Incr, *RemAmt;
2073 Value *AddInst, *AddOffset;
2076 if (PN !=
nullptr) {
2078 AddOffset =
nullptr;
2087 if (PN !=
nullptr) {
2100 if (PN->getNumIncomingValues() != 2)
2105 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2109 if (!L->contains(Rem))
2113 if (!L->isLoopInvariant(RemAmt))
2117 if (AddOffset && !L->isLoopInvariant(AddOffset))
2138 AddInstOut = AddInst;
2139 AddOffsetOut = AddOffset;
2158 Value *AddOffset, *RemAmt, *AddInst;
2161 AddOffset, LoopIncrPN))
2186 assert(AddOffset &&
"We found an add but missing values");
2205 Builder.SetInsertPoint(LoopIncrPN);
2206 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2211 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2216 NewRem->
addIncoming(Start, L->getLoopPreheader());
2221 FreshBBs.
insert(L->getLoopLatch());
2232bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2238bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2242 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2245 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2248 if (unfoldPowerOf2Test(Cmp))
2269 SetOfInstrs &InsertedInsts) {
2272 assert(!InsertedInsts.count(AndI) &&
2273 "Attempting to optimize already optimized and instruction");
2274 (void)InsertedInsts;
2288 for (
auto *U : AndI->
users()) {
2296 if (!CmpC || !CmpC->
isZero())
2311 Use &TheUse = UI.getUse();
2329 TheUse = InsertedAnd;
2346 if (
User->getOpcode() != Instruction::And ||
2352 if ((Cimm & (Cimm + 1)).getBoolValue())
2366 bool MadeChange =
false;
2369 TruncE = TruncI->user_end();
2370 TruncUI != TruncE;) {
2372 Use &TruncTheUse = TruncUI.getUse();
2397 if (UserBB == TruncUserBB)
2401 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2403 if (!InsertedShift && !InsertedTrunc) {
2407 if (ShiftI->
getOpcode() == Instruction::AShr)
2409 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2412 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2420 TruncInsertPt.setHeadBit(
true);
2421 assert(TruncInsertPt != TruncUserBB->
end());
2425 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2426 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2430 TruncTheUse = InsertedTrunc;
2463 bool MadeChange =
false;
2466 Use &TheUse = UI.getUse();
2480 if (UserBB == DefBB) {
2508 if (!InsertedShift) {
2512 if (ShiftI->
getOpcode() == Instruction::AShr)
2514 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2517 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2525 TheUse = InsertedShift;
2572 unsigned SizeInBits = Ty->getScalarSizeInBits();
2573 if (Ty->isVectorTy())
2585 FreshBBs.
insert(CallBlock);
2592 SplitPt.setHeadBit(
true);
2595 FreshBBs.
insert(EndBlock);
2600 L->addBasicBlockToLoop(CallBlock, LI);
2601 L->addBasicBlockToLoop(EndBlock, LI);
2607 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2614 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2615 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2616 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2621 Builder.SetInsertPoint(EndBlock, EndBlock->
begin());
2622 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2632 ModifiedDT = ModifyDT::ModifyBBDT;
2636bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2640 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2648 for (
auto &Arg : CI->
args()) {
2653 if (!Arg->getType()->isPointerTy())
2655 APInt
Offset(
DL->getIndexSizeInBits(
2658 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2659 uint64_t Offset2 =
Offset.getLimitedValue();
2665 if (AllocaSize && AllocaSize->getKnownMinValue() >= MinSize + Offset2)
2683 MaybeAlign MIDestAlign =
MI->getDestAlign();
2684 if (!MIDestAlign || DestAlign > *MIDestAlign)
2685 MI->setDestAlignment(DestAlign);
2687 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2689 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2690 MTI->setSourceAlignment(SrcAlign);
2700 for (
auto &Arg : CI->
args()) {
2701 if (!Arg->getType()->isPointerTy())
2703 unsigned AS = Arg->getType()->getPointerAddressSpace();
2704 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2710 switch (
II->getIntrinsicID()) {
2713 case Intrinsic::assume:
2715 case Intrinsic::allow_runtime_check:
2716 case Intrinsic::allow_ubsan_check:
2717 case Intrinsic::experimental_widenable_condition: {
2721 if (
II->use_empty()) {
2722 II->eraseFromParent();
2726 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2731 case Intrinsic::objectsize:
2733 case Intrinsic::is_constant:
2735 case Intrinsic::aarch64_stlxr:
2736 case Intrinsic::aarch64_stxr: {
2745 InsertedInsts.insert(ExtVal);
2749 case Intrinsic::launder_invariant_group:
2750 case Intrinsic::strip_invariant_group: {
2751 Value *ArgVal =
II->getArgOperand(0);
2752 auto it = LargeOffsetGEPMap.
find(
II);
2753 if (it != LargeOffsetGEPMap.
end()) {
2757 auto GEPs = std::move(it->second);
2758 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2763 II->eraseFromParent();
2766 case Intrinsic::cttz:
2767 case Intrinsic::ctlz:
2771 case Intrinsic::fshl:
2772 case Intrinsic::fshr:
2773 return optimizeFunnelShift(
II);
2774 case Intrinsic::masked_gather:
2775 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2776 case Intrinsic::masked_scatter:
2777 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2778 case Intrinsic::masked_load:
2781 if (VT->getNumElements() == 1) {
2782 Value *PtrVal =
II->getArgOperand(0);
2784 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2789 case Intrinsic::masked_store:
2793 if (VT->getNumElements() == 1) {
2794 Value *PtrVal =
II->getArgOperand(1);
2796 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2801 case Intrinsic::umul_with_overflow:
2802 return optimizeMulWithOverflow(
II,
false, ModifiedDT);
2803 case Intrinsic::smul_with_overflow:
2804 return optimizeMulWithOverflow(
II,
true, ModifiedDT);
2807 SmallVector<Value *, 2> PtrOps;
2810 while (!PtrOps.
empty()) {
2813 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2827 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2829 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2839 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2840 if (!
F->getReturnType()->isPointerTy())
2843 GlobalVariable *UniformValue =
nullptr;
2844 for (
auto &BB : *
F) {
2849 else if (V != UniformValue)
2857 return UniformValue;
2860 if (
Callee->hasExactDefinition()) {
2861 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2862 bool MadeChange =
false;
2888 switch (
II->getIntrinsicID()) {
2889 case Intrinsic::memset:
2890 case Intrinsic::memcpy:
2891 case Intrinsic::memmove:
2899 if (Callee && TLInfo && TLInfo->
getLibFunc(*Callee, LF))
2901 case LibFunc_strcpy:
2902 case LibFunc_strncpy:
2903 case LibFunc_strcat:
2904 case LibFunc_strncat:
2945bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
2946 ModifyDT &ModifiedDT) {
2954 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2956 PHINode *PN =
nullptr;
2957 ExtractValueInst *EVI =
nullptr;
2958 BitCastInst *BCI =
nullptr;
2978 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
2984 return II->getIntrinsicID() == Intrinsic::lifetime_end;
2990 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
2992 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
3014 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
3021 auto MayBePermittedAsTailCall = [&](
const auto *CI) {
3038 MayBePermittedAsTailCall(CI)) {
3059 MayBePermittedAsTailCall(CI)) {
3066 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
3068 if (!VisitedBBs.
insert(Pred).second)
3070 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
3072 if (CI && CI->
use_empty() && MayBePermittedAsTailCall(CI)) {
3087 for (
auto const &TailCallBB : TailCallBBs) {
3097 BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB));
3098 BFI->setBlockFreq(BB,
3099 (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB)));
3100 ModifiedDT = ModifyDT::ModifyBBDT;
3109 for (
auto *CI : CallInsts) {
3110 for (
auto const *FakeUse : FakeUses) {
3111 auto *ClonedInst = FakeUse->clone();
3129struct ExtAddrMode :
public TargetLowering::AddrMode {
3130 Value *BaseReg =
nullptr;
3131 Value *ScaledReg =
nullptr;
3132 Value *OriginalValue =
nullptr;
3133 bool InBounds =
true;
3137 BaseRegField = 0x01,
3139 BaseOffsField = 0x04,
3140 ScaledRegField = 0x08,
3142 MultipleFields = 0xff
3145 ExtAddrMode() =
default;
3147 void print(raw_ostream &OS)
const;
3154 if (ScaledReg == From)
3158 FieldName
compare(
const ExtAddrMode &other) {
3161 if (BaseReg && other.
BaseReg &&
3163 return MultipleFields;
3164 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3165 return MultipleFields;
3168 return MultipleFields;
3171 if (InBounds != other.InBounds)
3172 return MultipleFields;
3175 unsigned Result = NoField;
3178 if (BaseGV != other.BaseGV)
3180 if (BaseOffs != other.BaseOffs)
3183 Result |= ScaledRegField;
3186 if (Scale && other.
Scale && Scale != other.
Scale)
3190 return MultipleFields;
3192 return static_cast<FieldName
>(
Result);
3202 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3213 case ScaledRegField:
3220 void SetCombinedField(FieldName
Field,
Value *V,
3221 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3226 case ExtAddrMode::BaseRegField:
3229 case ExtAddrMode::BaseGVField:
3232 assert(BaseReg ==
nullptr);
3236 case ExtAddrMode::ScaledRegField:
3241 for (
const ExtAddrMode &AM : AddrModes)
3247 case ExtAddrMode::BaseOffsField:
3250 assert(ScaledReg ==
nullptr);
3260static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3266#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3267void ExtAddrMode::print(raw_ostream &OS)
const {
3268 bool NeedPlus =
false;
3274 BaseGV->printAsOperand(OS,
false);
3279 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3284 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3285 BaseReg->printAsOperand(OS,
false);
3289 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3312class TypePromotionTransaction {
3316 class TypePromotionAction {
3324 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3326 virtual ~TypePromotionAction() =
default;
3333 virtual void undo() = 0;
3338 virtual void commit() {
3344 class InsertionHandler {
3353 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3356 bool HasPrevInstruction;
3360 InsertionHandler(Instruction *Inst) {
3368 if (HasPrevInstruction) {
3376 void insert(Instruction *Inst) {
3377 if (HasPrevInstruction) {
3389 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3394 class InstructionMoveBefore :
public TypePromotionAction {
3396 InsertionHandler Position;
3401 : TypePromotionAction(Inst), Position(Inst) {
3402 LLVM_DEBUG(
dbgs() <<
"Do: move: " << *Inst <<
"\nbefore: " << *Before
3408 void undo()
override {
3410 Position.insert(Inst);
3415 class OperandSetter :
public TypePromotionAction {
3424 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3425 : TypePromotionAction(Inst), Idx(Idx) {
3427 <<
"for:" << *Inst <<
"\n"
3428 <<
"with:" << *NewVal <<
"\n");
3434 void undo()
override {
3436 <<
"for: " << *Inst <<
"\n"
3437 <<
"with: " << *Origin <<
"\n");
3444 class OperandsHider :
public TypePromotionAction {
3446 SmallVector<Value *, 4> OriginalValues;
3450 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3453 OriginalValues.
reserve(NumOpnds);
3454 for (
unsigned It = 0; It < NumOpnds; ++It) {
3466 void undo()
override {
3468 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3474 class TruncBuilder :
public TypePromotionAction {
3481 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3483 Builder.SetCurrentDebugLocation(
DebugLoc());
3484 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3489 Value *getBuiltValue() {
return Val; }
3492 void undo()
override {
3495 IVal->eraseFromParent();
3500 class SExtBuilder :
public TypePromotionAction {
3507 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3508 : TypePromotionAction(InsertPt) {
3510 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3515 Value *getBuiltValue() {
return Val; }
3518 void undo()
override {
3521 IVal->eraseFromParent();
3526 class ZExtBuilder :
public TypePromotionAction {
3533 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3534 : TypePromotionAction(InsertPt) {
3536 Builder.SetCurrentDebugLocation(
DebugLoc());
3537 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3542 Value *getBuiltValue() {
return Val; }
3545 void undo()
override {
3548 IVal->eraseFromParent();
3553 class TypeMutator :
public TypePromotionAction {
3559 TypeMutator(Instruction *Inst,
Type *NewTy)
3560 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3561 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3567 void undo()
override {
3568 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3575 class UsesReplacer :
public TypePromotionAction {
3577 struct InstructionAndIdx {
3584 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3585 : Inst(Inst), Idx(Idx) {}
3591 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3601 UsesReplacer(Instruction *Inst,
Value *New)
3602 : TypePromotionAction(Inst),
New(
New) {
3603 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3606 for (Use &U : Inst->
uses()) {
3608 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3619 void undo()
override {
3621 for (InstructionAndIdx &Use : OriginalUses)
3622 Use.Inst->setOperand(
Use.Idx, Inst);
3627 for (DbgVariableRecord *DVR : DbgVariableRecords)
3628 DVR->replaceVariableLocationOp(New, Inst);
3633 class InstructionRemover :
public TypePromotionAction {
3635 InsertionHandler Inserter;
3639 OperandsHider Hider;
3642 UsesReplacer *Replacer =
nullptr;
3645 SetOfInstrs &RemovedInsts;
3652 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3653 Value *New =
nullptr)
3654 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3655 RemovedInsts(RemovedInsts) {
3657 Replacer =
new UsesReplacer(Inst, New);
3658 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3659 RemovedInsts.insert(Inst);
3666 ~InstructionRemover()
override {
delete Replacer; }
3668 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3669 InstructionRemover(
const InstructionRemover &other) =
delete;
3673 void undo()
override {
3674 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3675 Inserter.insert(Inst);
3679 RemovedInsts.erase(Inst);
3687 using ConstRestorationPt =
const TypePromotionAction *;
3689 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3690 : RemovedInsts(RemovedInsts) {}
3697 void rollback(ConstRestorationPt Point);
3700 ConstRestorationPt getRestorationPoint()
const;
3705 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3714 void mutateType(Instruction *Inst,
Type *NewTy);
3717 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3730 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3732 SetOfInstrs &RemovedInsts;
3737void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3739 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3740 Inst, Idx, NewVal));
3743void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3746 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3747 Inst, RemovedInsts, NewVal));
3750void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3753 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3756void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3758 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3761Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3762 std::unique_ptr<TruncBuilder> Ptr(
new TruncBuilder(Opnd, Ty));
3763 Value *Val = Ptr->getBuiltValue();
3764 Actions.push_back(std::move(Ptr));
3768Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3770 std::unique_ptr<SExtBuilder> Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3771 Value *Val = Ptr->getBuiltValue();
3772 Actions.push_back(std::move(Ptr));
3776Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3778 std::unique_ptr<ZExtBuilder> Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3779 Value *Val = Ptr->getBuiltValue();
3780 Actions.push_back(std::move(Ptr));
3784TypePromotionTransaction::ConstRestorationPt
3785TypePromotionTransaction::getRestorationPoint()
const {
3786 return !Actions.empty() ? Actions.back().get() :
nullptr;
3789bool TypePromotionTransaction::commit() {
3790 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3797void TypePromotionTransaction::rollback(
3798 TypePromotionTransaction::ConstRestorationPt Point) {
3799 while (!Actions.empty() && Point != Actions.back().get()) {
3800 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3810class AddressingModeMatcher {
3811 SmallVectorImpl<Instruction *> &AddrModeInsts;
3812 const TargetLowering &TLI;
3813 const TargetRegisterInfo &
TRI;
3814 const DataLayout &
DL;
3816 const std::function<
const DominatorTree &()> getDTFn;
3829 const SetOfInstrs &InsertedInsts;
3832 InstrToOrigTy &PromotedInsts;
3835 TypePromotionTransaction &TPT;
3838 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3842 bool IgnoreProfitability;
3845 bool OptSize =
false;
3847 ProfileSummaryInfo *PSI;
3848 BlockFrequencyInfo *BFI;
3850 AddressingModeMatcher(
3851 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3852 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3853 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3854 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3855 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3856 TypePromotionTransaction &TPT,
3857 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3858 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI)
3859 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3860 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3861 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3862 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3863 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI), BFI(BFI) {
3864 IgnoreProfitability =
false;
3876 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3877 SmallVectorImpl<Instruction *> &AddrModeInsts,
3878 const TargetLowering &TLI,
const LoopInfo &LI,
3879 const std::function<
const DominatorTree &()> getDTFn,
3880 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3881 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3882 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3883 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
3886 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3887 AccessTy, AS, MemoryInst, Result,
3888 InsertedInsts, PromotedInsts, TPT,
3889 LargeOffsetGEP, OptSize, PSI, BFI)
3897 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3899 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3900 bool *MovedAway =
nullptr);
3901 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3902 ExtAddrMode &AMBefore,
3903 ExtAddrMode &AMAfter);
3904 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3905 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3906 Value *PromotedOperand)
const;
3912class PhiNodeSetIterator {
3913 PhiNodeSet *
const Set;
3914 size_t CurrentIndex = 0;
3919 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3921 PhiNodeSetIterator &operator++();
3937 friend class PhiNodeSetIterator;
3939 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3940 using iterator = PhiNodeSetIterator;
3955 size_t FirstValidElement = 0;
3961 bool insert(PHINode *Ptr) {
3962 if (NodeMap.insert(std::make_pair(Ptr,
NodeList.
size())).second) {
3972 bool erase(PHINode *Ptr) {
3973 if (NodeMap.erase(Ptr)) {
3974 SkipRemovedElements(FirstValidElement);
3984 FirstValidElement = 0;
3990 if (FirstValidElement == 0)
3991 SkipRemovedElements(FirstValidElement);
3992 return PhiNodeSetIterator(
this, FirstValidElement);
3999 size_t size()
const {
return NodeMap.size(); }
4002 size_t count(PHINode *Ptr)
const {
return NodeMap.count(Ptr); }
4010 void SkipRemovedElements(
size_t &CurrentIndex) {
4012 auto it = NodeMap.find(NodeList[CurrentIndex]);
4015 if (it != NodeMap.end() && it->second == CurrentIndex)
4022PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
4025PHINode *PhiNodeSetIterator::operator*()
const {
4027 "PhiNodeSet access out of range");
4028 return Set->NodeList[CurrentIndex];
4031PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
4033 "PhiNodeSet access out of range");
4035 Set->SkipRemovedElements(CurrentIndex);
4039bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
4040 return CurrentIndex ==
RHS.CurrentIndex;
4043bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
4044 return !((*this) ==
RHS);
4050class SimplificationTracker {
4051 DenseMap<Value *, Value *> Storage;
4054 PhiNodeSet AllPhiNodes;
4056 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
4061 auto SV = Storage.
find(V);
4062 if (SV == Storage.
end())
4070 void ReplacePhi(PHINode *From, PHINode *To) {
4071 Value *OldReplacement = Get(From);
4072 while (OldReplacement != From) {
4075 OldReplacement = Get(From);
4077 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
4080 AllPhiNodes.erase(From);
4084 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
4086 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
4088 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
4090 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4092 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4094 void destroyNewNodes(
Type *CommonType) {
4097 for (
auto *
I : AllPhiNodes) {
4098 I->replaceAllUsesWith(Dummy);
4099 I->eraseFromParent();
4101 AllPhiNodes.clear();
4102 for (
auto *
I : AllSelectNodes) {
4103 I->replaceAllUsesWith(Dummy);
4104 I->eraseFromParent();
4106 AllSelectNodes.clear();
4111class AddressingModeCombiner {
4112 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4113 typedef std::pair<PHINode *, PHINode *> PHIPair;
4120 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4123 bool AllAddrModesTrivial =
true;
4126 Type *CommonType =
nullptr;
4128 const DataLayout &
DL;
4134 Value *CommonValue =
nullptr;
4137 AddressingModeCombiner(
const DataLayout &
DL,
Value *OriginalValue)
4138 :
DL(
DL), Original(OriginalValue) {}
4140 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4143 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4148 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4152 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4155 if (AddrModes.
empty()) {
4163 ExtAddrMode::FieldName ThisDifferentField =
4164 AddrModes[0].compare(NewAddrMode);
4165 if (DifferentField == ExtAddrMode::NoField)
4166 DifferentField = ThisDifferentField;
4167 else if (DifferentField != ThisDifferentField)
4168 DifferentField = ExtAddrMode::MultipleFields;
4171 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4174 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4179 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4184 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4185 !NewAddrMode.HasBaseReg);
4202 bool combineAddrModes() {
4204 if (AddrModes.
size() == 0)
4208 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4213 if (AllAddrModesTrivial)
4216 if (!addrModeCombiningAllowed())
4222 FoldAddrToValueMapping
Map;
4223 if (!initializeMap(Map))
4226 CommonValue = findCommon(Map);
4228 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4229 return CommonValue !=
nullptr;
4235 void eraseCommonValueIfDead() {
4236 if (CommonValue && CommonValue->
use_empty())
4238 CommonInst->eraseFromParent();
4246 bool initializeMap(FoldAddrToValueMapping &Map) {
4249 SmallVector<Value *, 2> NullValue;
4250 Type *IntPtrTy =
DL.getIntPtrType(AddrModes[0].OriginalValue->
getType());
4251 for (
auto &AM : AddrModes) {
4252 Value *DV = AM.GetFieldAsValue(DifferentField, IntPtrTy);
4255 if (CommonType && CommonType !=
Type)
4258 Map[AM.OriginalValue] = DV;
4263 assert(CommonType &&
"At least one non-null value must be!");
4264 for (
auto *V : NullValue)
4292 Value *findCommon(FoldAddrToValueMapping &Map) {
4300 SimplificationTracker
ST;
4305 InsertPlaceholders(Map, TraverseOrder, ST);
4308 FillPlaceholders(Map, TraverseOrder, ST);
4311 ST.destroyNewNodes(CommonType);
4316 unsigned PhiNotMatchedCount = 0;
4318 ST.destroyNewNodes(CommonType);
4322 auto *
Result =
ST.Get(
Map.find(Original)->second);
4324 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4325 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4332 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4333 SmallSetVector<PHIPair, 8> &Matcher,
4334 PhiNodeSet &PhiNodesToMatch) {
4337 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4340 SmallSet<PHIPair, 8> Visited;
4341 while (!WorkList.
empty()) {
4343 if (!Visited.
insert(Item).second)
4350 for (
auto *
B : Item.first->blocks()) {
4351 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4352 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4353 if (FirstValue == SecondValue)
4363 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4368 if (Matcher.
count({FirstPhi, SecondPhi}))
4373 if (MatchedPHIs.
insert(FirstPhi).second)
4374 Matcher.
insert({FirstPhi, SecondPhi});
4376 WorkList.
push_back({FirstPhi, SecondPhi});
4385 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4386 unsigned &PhiNotMatchedCount) {
4390 SmallSetVector<PHIPair, 8> Matched;
4391 SmallPtrSet<PHINode *, 8> WillNotMatch;
4392 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4393 while (PhiNodesToMatch.size()) {
4394 PHINode *
PHI = *PhiNodesToMatch.begin();
4397 WillNotMatch.
clear();
4401 bool IsMatched =
false;
4402 for (
auto &
P :
PHI->getParent()->phis()) {
4404 if (PhiNodesToMatch.count(&
P))
4406 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4416 for (
auto MV : Matched)
4417 ST.ReplacePhi(MV.first, MV.second);
4422 if (!AllowNewPhiNodes)
4425 PhiNotMatchedCount += WillNotMatch.
size();
4426 for (
auto *
P : WillNotMatch)
4427 PhiNodesToMatch.erase(
P);
4432 void FillPlaceholders(FoldAddrToValueMapping &Map,
4433 SmallVectorImpl<Value *> &TraverseOrder,
4434 SimplificationTracker &ST) {
4435 while (!TraverseOrder.
empty()) {
4437 assert(
Map.contains(Current) &&
"No node to fill!!!");
4443 auto *TrueValue = CurrentSelect->getTrueValue();
4444 assert(
Map.contains(TrueValue) &&
"No True Value!");
4445 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4446 auto *FalseValue = CurrentSelect->getFalseValue();
4447 assert(
Map.contains(FalseValue) &&
"No False Value!");
4448 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4455 assert(
Map.contains(PV) &&
"No predecessor Value!");
4456 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4467 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4468 SmallVectorImpl<Value *> &TraverseOrder,
4469 SimplificationTracker &ST) {
4472 "Address must be a Phi or Select node");
4475 while (!Worklist.
empty()) {
4478 if (
Map.contains(Current))
4489 CurrentSelect->getName(),
4490 CurrentSelect->getIterator(), CurrentSelect);
4494 Worklist.
push_back(CurrentSelect->getTrueValue());
4495 Worklist.
push_back(CurrentSelect->getFalseValue());
4503 ST.insertNewPhi(
PHI);
4509 bool addrModeCombiningAllowed() {
4512 switch (DifferentField) {
4515 case ExtAddrMode::BaseRegField:
4517 case ExtAddrMode::BaseGVField:
4519 case ExtAddrMode::BaseOffsField:
4521 case ExtAddrMode::ScaledRegField:
4531bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4536 return matchAddr(ScaleReg,
Depth);
4547 ExtAddrMode TestAddrMode =
AddrMode;
4551 TestAddrMode.
Scale += Scale;
4565 ConstantInt *CI =
nullptr;
4566 Value *AddLHS =
nullptr;
4570 TestAddrMode.InBounds =
false;
4587 auto GetConstantStep =
4588 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4591 return std::nullopt;
4594 return std::nullopt;
4602 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4603 return std::nullopt;
4605 return std::make_pair(IVInc->first, ConstantStep->getValue());
4606 return std::nullopt;
4621 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4628 APInt Step = IVStep->second;
4630 if (
Offset.isSignedIntN(64)) {
4631 TestAddrMode.InBounds =
false;
4633 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4638 getDTFn().
dominates(IVInc, MemoryInst)) {
4658 switch (
I->getOpcode()) {
4659 case Instruction::BitCast:
4660 case Instruction::AddrSpaceCast:
4662 if (
I->getType() ==
I->getOperand(0)->getType())
4664 return I->getType()->isIntOrPtrTy();
4665 case Instruction::PtrToInt:
4668 case Instruction::IntToPtr:
4671 case Instruction::Add:
4673 case Instruction::Mul:
4674 case Instruction::Shl:
4677 case Instruction::GetElementPtr:
4705class TypePromotionHelper {
4708 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4709 Instruction *ExtOpnd,
bool IsSExt) {
4710 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4711 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4715 if (It->second.getInt() == ExtTy)
4721 ExtTy = BothExtension;
4723 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4730 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4731 Instruction *Opnd,
bool IsSExt) {
4732 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4733 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4734 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4735 return It->second.getPointer();
4750 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4751 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4755 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4768 static Value *promoteOperandForTruncAndAnyExt(
4769 Instruction *Ext, TypePromotionTransaction &TPT,
4770 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4771 SmallVectorImpl<Instruction *> *Exts,
4772 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4783 static Value *promoteOperandForOther(Instruction *Ext,
4784 TypePromotionTransaction &TPT,
4785 InstrToOrigTy &PromotedInsts,
4786 unsigned &CreatedInstsCost,
4787 SmallVectorImpl<Instruction *> *Exts,
4788 SmallVectorImpl<Instruction *> *Truncs,
4789 const TargetLowering &TLI,
bool IsSExt);
4792 static Value *signExtendOperandForOther(
4793 Instruction *Ext, TypePromotionTransaction &TPT,
4794 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4795 SmallVectorImpl<Instruction *> *Exts,
4796 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4797 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4798 Exts, Truncs, TLI,
true);
4802 static Value *zeroExtendOperandForOther(
4803 Instruction *Ext, TypePromotionTransaction &TPT,
4804 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4805 SmallVectorImpl<Instruction *> *Exts,
4806 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4807 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4808 Exts, Truncs, TLI,
false);
4813 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4814 InstrToOrigTy &PromotedInsts,
4815 unsigned &CreatedInstsCost,
4816 SmallVectorImpl<Instruction *> *Exts,
4817 SmallVectorImpl<Instruction *> *Truncs,
4818 const TargetLowering &TLI);
4829 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4830 const TargetLowering &TLI,
4831 const InstrToOrigTy &PromotedInsts);
4836bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4837 Type *ConsideredExtType,
4838 const InstrToOrigTy &PromotedInsts,
4858 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4859 (IsSExt && BinOp->hasNoSignedWrap())))
4863 if ((Inst->
getOpcode() == Instruction::And ||
4868 if (Inst->
getOpcode() == Instruction::Xor) {
4871 if (!Cst->getValue().isAllOnes())
4880 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4890 if (ExtInst->hasOneUse()) {
4892 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4925 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4938TypePromotionHelper::Action TypePromotionHelper::getAction(
4939 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4940 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
4942 "Unexpected instruction type");
4949 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4962 return promoteOperandForTruncAndAnyExt;
4968 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4971Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4972 Instruction *SExt, TypePromotionTransaction &TPT,
4973 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4974 SmallVectorImpl<Instruction *> *Exts,
4975 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4979 Value *ExtVal = SExt;
4980 bool HasMergedNonFreeExt =
false;
4984 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
4987 TPT.replaceAllUsesWith(SExt, ZExt);
4988 TPT.eraseInstruction(SExt);
4993 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
4995 CreatedInstsCost = 0;
4999 TPT.eraseInstruction(SExtOpnd);
5007 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
5015 TPT.eraseInstruction(ExtInst, NextVal);
5019Value *TypePromotionHelper::promoteOperandForOther(
5020 Instruction *Ext, TypePromotionTransaction &TPT,
5021 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5022 SmallVectorImpl<Instruction *> *Exts,
5023 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
5028 CreatedInstsCost = 0;
5034 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
5037 ITrunc->moveAfter(ExtOpnd);
5042 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
5045 TPT.setOperand(Ext, 0, ExtOpnd);
5055 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
5057 TPT.mutateType(ExtOpnd, Ext->
getType());
5059 TPT.replaceAllUsesWith(Ext, ExtOpnd);
5066 !shouldExtOperand(ExtOpnd,
OpIdx)) {
5075 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
5077 TPT.setOperand(ExtOpnd,
OpIdx, ConstantInt::get(Ext->
getType(), CstVal));
5088 Value *ValForExtOpnd = IsSExt
5089 ? TPT.createSExt(ExtOpnd, Opnd, Ext->
getType())
5090 : TPT.createZExt(ExtOpnd, Opnd, Ext->
getType());
5091 TPT.setOperand(ExtOpnd,
OpIdx, ValForExtOpnd);
5093 if (!InstForExtOpnd)
5099 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5102 TPT.eraseInstruction(Ext);
5114bool AddressingModeMatcher::isPromotionProfitable(
5115 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5116 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5121 if (NewCost > OldCost)
5123 if (NewCost < OldCost)
5142bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5154 case Instruction::PtrToInt:
5157 case Instruction::IntToPtr: {
5165 case Instruction::BitCast:
5175 case Instruction::AddrSpaceCast: {
5183 case Instruction::Add: {
5186 ExtAddrMode BackupAddrMode =
AddrMode;
5187 unsigned OldSize = AddrModeInsts.
size();
5192 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5193 TPT.getRestorationPoint();
5197 int First = 0, Second = 1;
5208 AddrModeInsts.
resize(OldSize);
5209 TPT.rollback(LastKnownGood);
5219 AddrModeInsts.
resize(OldSize);
5220 TPT.rollback(LastKnownGood);
5226 case Instruction::Mul:
5227 case Instruction::Shl: {
5231 if (!
RHS ||
RHS->getBitWidth() > 64)
5233 int64_t Scale = Opcode == Instruction::Shl
5234 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5235 :
RHS->getSExtValue();
5239 case Instruction::GetElementPtr: {
5242 int VariableOperand = -1;
5243 unsigned VariableScale = 0;
5245 int64_t ConstantOffset = 0;
5247 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5249 const StructLayout *SL =
DL.getStructLayout(STy);
5260 if (ConstantInt *CI =
5262 const APInt &CVal = CI->
getValue();
5269 if (VariableOperand != -1)
5273 VariableOperand = i;
5274 VariableScale = TypeSize;
5281 if (VariableOperand == -1) {
5282 AddrMode.BaseOffs += ConstantOffset;
5288 AddrMode.BaseOffs -= ConstantOffset;
5292 ConstantOffset > 0) {
5305 BasicBlock *Parent = BaseI ? BaseI->getParent()
5306 : &
GEP->getFunction()->getEntryBlock();
5308 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5316 ExtAddrMode BackupAddrMode =
AddrMode;
5317 unsigned OldSize = AddrModeInsts.
size();
5320 AddrMode.BaseOffs += ConstantOffset;
5329 AddrModeInsts.
resize(OldSize);
5337 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5342 AddrModeInsts.
resize(OldSize);
5347 AddrMode.BaseOffs += ConstantOffset;
5348 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5349 VariableScale,
Depth)) {
5352 AddrModeInsts.
resize(OldSize);
5359 case Instruction::SExt:
5360 case Instruction::ZExt: {
5367 TypePromotionHelper::Action TPH =
5368 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5372 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5373 TPT.getRestorationPoint();
5374 unsigned CreatedInstsCost = 0;
5376 Value *PromotedOperand =
5377 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5392 assert(PromotedOperand &&
5393 "TypePromotionHelper should have filtered out those cases");
5395 ExtAddrMode BackupAddrMode =
AddrMode;
5396 unsigned OldSize = AddrModeInsts.
size();
5398 if (!matchAddr(PromotedOperand,
Depth) ||
5403 !isPromotionProfitable(CreatedInstsCost,
5404 ExtCost + (AddrModeInsts.
size() - OldSize),
5407 AddrModeInsts.
resize(OldSize);
5408 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5409 TPT.rollback(LastKnownGood);
5414 AddrMode.replaceWith(Ext, PromotedOperand);
5417 case Instruction::Call:
5419 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5435bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5438 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5439 TPT.getRestorationPoint();
5463 ExtAddrMode BackupAddrMode =
AddrMode;
5464 unsigned OldSize = AddrModeInsts.
size();
5467 bool MovedAway =
false;
5468 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5476 if (
I->hasOneUse() ||
5477 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5484 AddrModeInsts.
resize(OldSize);
5485 TPT.rollback(LastKnownGood);
5488 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5490 TPT.rollback(LastKnownGood);
5517 TPT.rollback(LastKnownGood);
5536 if (OpInfo.CallOperandVal == OpVal &&
5538 !OpInfo.isIndirect))
5554 if (!ConsideredInsts.
insert(
I).second)
5562 for (
Use &U :
I->uses()) {
5570 MemoryUses.push_back({&U, LI->getType()});
5577 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5584 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5591 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5601 if (!
find(PtrOps, U.get()))
5604 MemoryUses.push_back({&U, AccessTy});
5609 if (CI->hasFnAttr(Attribute::Cold)) {
5627 PSI, BFI, SeenInsts))
5638 unsigned SeenInsts = 0;
5641 PSI, BFI, SeenInsts);
5649bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5651 Value *KnownLive2) {
5653 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5694bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5695 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5696 if (IgnoreProfitability)
5714 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5715 ScaledReg =
nullptr;
5719 if (!BaseReg && !ScaledReg)
5740 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5743 Type *AddressAccessTy = Pair.second;
5744 unsigned AS =
Address->getType()->getPointerAddressSpace();
5750 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5752 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5753 TPT.getRestorationPoint();
5754 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5755 AddressAccessTy, AS, UserI, Result,
5756 InsertedInsts, PromotedInsts, TPT,
5757 LargeOffsetGEP, OptSize, PSI, BFI);
5758 Matcher.IgnoreProfitability =
true;
5766 TPT.rollback(LastKnownGood);
5772 MatchedAddrModeInsts.
clear();
5782 return I->getParent() != BB;
5798 return std::next(AddrInst->getIterator());
5809 Earliest = UserInst;
5834bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5835 Type *AccessTy,
unsigned AddrSpace) {
5840 SmallVector<Value *, 8> worklist;
5841 SmallPtrSet<Value *, 16> Visited;
5847 bool PhiOrSelectSeen =
false;
5848 SmallVector<Instruction *, 16> AddrModeInsts;
5849 AddressingModeCombiner AddrModes(*
DL, Addr);
5850 TypePromotionTransaction TPT(RemovedInsts);
5851 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5852 TPT.getRestorationPoint();
5853 while (!worklist.
empty()) {
5865 if (!Visited.
insert(V).second)
5871 PhiOrSelectSeen =
true;
5878 PhiOrSelectSeen =
true;
5885 AddrModeInsts.
clear();
5886 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5891 auto getDTFn = [MemoryInst,
this]() ->
const DominatorTree & {
5893 return this->getDT(*
F);
5895 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5896 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5897 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5900 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5905 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5906 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5909 NewAddrMode.OriginalValue =
V;
5910 if (!AddrModes.addNewAddrMode(NewAddrMode))
5917 if (!AddrModes.combineAddrModes()) {
5918 TPT.rollback(LastKnownGood);
5924 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5930 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5944 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
5966 <<
" for " << *MemoryInst <<
"\n");
5970 !
DL->isNonIntegralPointerType(Addr->
getType())) {
5976 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
5978 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
5980 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
5987 <<
" for " << *MemoryInst <<
"\n");
5988 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
5999 if (ResultPtr ||
AddrMode.Scale != 1)
6020 GlobalValue *BaseGV =
AddrMode.BaseGV;
6021 if (BaseGV !=
nullptr) {
6026 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
6035 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
6036 if (!ResultPtr &&
AddrMode.BaseReg) {
6040 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
6041 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
6050 }
else if (!ResultPtr) {
6063 if (
V->getType() != IntPtrTy)
6064 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6072 if (
V->getType() == IntPtrTy) {
6077 "We can't transform if ScaledReg is too narrow");
6078 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6082 V = Builder.CreateMul(
6085 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6096 if (ResultPtr->
getType() != I8PtrTy)
6097 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6098 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6111 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6113 SunkAddr = ResultPtr;
6115 if (ResultPtr->
getType() != I8PtrTy)
6116 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6117 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6124 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6130 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
6132 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6134 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6144 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6145 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6146 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6148 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6152 <<
" for " << *MemoryInst <<
"\n");
6163 if (
V->getType()->isPointerTy())
6164 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6165 if (
V->getType() != IntPtrTy)
6166 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6173 if (
V->getType() == IntPtrTy) {
6175 }
else if (
V->getType()->isPointerTy()) {
6176 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6179 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6188 I->eraseFromParent();
6192 V = Builder.CreateMul(
6195 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6201 GlobalValue *BaseGV =
AddrMode.BaseGV;
6202 if (BaseGV !=
nullptr) {
6205 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6209 Value *
V = Builder.CreatePtrToInt(BaseGVPtr, IntPtrTy,
"sunkaddr");
6211 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6220 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6228 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6234 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6239 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6240 RecursivelyDeleteTriviallyDeadInstructions(
6241 Repl, TLInfo, nullptr,
6242 [&](Value *V) { removeAllAssertingVHReferences(V); });
6266bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6272 if (!
GEP->hasIndices())
6280 SmallVector<Value *, 2>
Ops(
GEP->operands());
6282 bool RewriteGEP =
false;
6291 unsigned FinalIndex =
Ops.size() - 1;
6296 for (
unsigned i = 1; i < FinalIndex; ++i) {
6301 C =
C->getSplatValue();
6303 if (!CI || !CI->
isZero())
6310 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6314 if (!
C || !
C->isZero()) {
6315 Ops[FinalIndex] =
V;
6323 if (!RewriteGEP &&
Ops.size() == 2)
6330 Type *SourceTy =
GEP->getSourceElementType();
6331 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6335 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6336 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6337 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6347 if (
Ops.size() != 2) {
6357 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6371 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6372 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6375 Intrinsic::masked_gather) {
6379 Intrinsic::masked_scatter);
6394 Ptr, TLInfo,
nullptr,
6395 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6406 if (
I->hasNUsesOrMore(3))
6409 for (
User *U :
I->users()) {
6411 if (!Extract || Extract->getNumIndices() != 1)
6414 unsigned Index = Extract->getIndices()[0];
6416 MulExtract = Extract;
6417 else if (Index == 1)
6418 OverflowExtract = Extract;
6445bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
6446 ModifyDT &ModifiedDT) {
6453 ExtractValueInst *MulExtract =
nullptr, *OverflowExtract =
nullptr;
6458 InsertedInsts.insert(
I);
6468 I->getParent()->splitBasicBlock(
I,
"",
true);
6469 OverflowEntryBB->
takeName(
I->getParent());
6475 NoOverflowBB->
moveAfter(OverflowEntryBB);
6483 Value *LoLHS = Builder.CreateTrunc(
LHS, LegalTy,
"lo.lhs");
6484 Value *HiLHS = Builder.CreateLShr(
LHS, VTHalfBitWidth,
"lhs.lsr");
6485 HiLHS = Builder.CreateTrunc(HiLHS, LegalTy,
"hi.lhs");
6488 Value *LoRHS = Builder.CreateTrunc(
RHS, LegalTy,
"lo.rhs");
6489 Value *HiRHS = Builder.CreateLShr(
RHS, VTHalfBitWidth,
"rhs.lsr");
6490 HiRHS = Builder.CreateTrunc(HiRHS, LegalTy,
"hi.rhs");
6492 Value *IsAnyBitTrue;
6495 Builder.CreateAShr(LoLHS, VTHalfBitWidth - 1,
"sign.lo.lhs");
6497 Builder.CreateAShr(LoRHS, VTHalfBitWidth - 1,
"sign.lo.rhs");
6498 Value *XorLHS = Builder.CreateXor(HiLHS, SignLoLHS);
6499 Value *XorRHS = Builder.CreateXor(HiRHS, SignLoRHS);
6500 Value *
Or = Builder.CreateOr(XorLHS, XorRHS,
"or.lhs.rhs");
6501 IsAnyBitTrue = Builder.CreateCmp(ICmpInst::ICMP_NE,
Or,
6502 ConstantInt::getNullValue(
Or->getType()));
6504 Value *CmpLHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiLHS,
6505 ConstantInt::getNullValue(LegalTy));
6506 Value *CmpRHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiRHS,
6507 ConstantInt::getNullValue(LegalTy));
6508 IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS,
"or.lhs.rhs");
6510 Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
6513 Builder.SetInsertPoint(NoOverflowBB);
6514 Value *ExtLoLHS, *ExtLoRHS;
6516 ExtLoLHS = Builder.CreateSExt(LoLHS, Ty,
"lo.lhs.ext");
6517 ExtLoRHS = Builder.CreateSExt(LoRHS, Ty,
"lo.rhs.ext");
6519 ExtLoLHS = Builder.CreateZExt(LoLHS, Ty,
"lo.lhs.ext");
6520 ExtLoRHS = Builder.CreateZExt(LoRHS, Ty,
"lo.rhs.ext");
6523 Value *
Mul = Builder.CreateMul(ExtLoLHS, ExtLoRHS,
"mul.overflow.no");
6528 OverflowResBB->
setName(
"overflow.res");
6531 Builder.CreateBr(OverflowResBB);
6539 PHINode *OverflowResPHI = Builder.CreatePHI(Ty, 2),
6541 Builder.CreatePHI(IntegerType::getInt1Ty(
I->getContext()), 2);
6553 if (OverflowExtract) {
6554 OverflowExtract->replaceAllUsesWith(OverflowFlagPHI);
6555 OverflowExtract->eraseFromParent();
6560 I->removeFromParent();
6562 I->insertInto(OverflowBB, OverflowBB->
end());
6563 Builder.SetInsertPoint(OverflowBB, OverflowBB->
end());
6565 Value *OverflowFlag = Builder.CreateExtractValue(
I, {1},
"overflow.flag");
6566 Builder.CreateBr(OverflowResBB);
6570 OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
6572 ModifiedDT = ModifyDT::ModifyBBDT;
6578bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6579 bool MadeChange =
false;
6581 const TargetRegisterInfo *
TRI =
6586 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6592 OpInfo.isIndirect) {
6594 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6657bool CodeGenPrepare::tryToPromoteExts(
6658 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6659 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6660 unsigned CreatedInstsCost) {
6661 bool Promoted =
false;
6664 for (
auto *
I : Exts) {
6679 TypePromotionHelper::Action TPH =
6680 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6689 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6690 TPT.getRestorationPoint();
6691 SmallVector<Instruction *, 4> NewExts;
6692 unsigned NewCreatedInstsCost = 0;
6695 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6696 &NewExts,
nullptr, *TLI);
6698 "TypePromotionHelper should have filtered out those cases");
6708 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6711 TotalCreatedInstsCost =
6712 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6714 (TotalCreatedInstsCost > 1 ||
6716 (ExtCost == 0 && NewExts.
size() > 1))) {
6720 TPT.rollback(LastKnownGood);
6725 SmallVector<Instruction *, 2> NewlyMovedExts;
6726 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6727 bool NewPromoted =
false;
6728 for (
auto *ExtInst : NewlyMovedExts) {
6738 ProfitablyMovedExts.
push_back(MovedExt);
6745 TPT.rollback(LastKnownGood);
6756bool CodeGenPrepare::mergeSExts(Function &
F) {
6758 for (
auto &Entry : ValToSExtendedUses) {
6759 SExts &Insts =
Entry.second;
6761 for (Instruction *Inst : Insts) {
6765 bool inserted =
false;
6766 for (
auto &Pt : CurPts) {
6769 RemovedInsts.insert(Pt);
6770 Pt->removeFromParent();
6781 RemovedInsts.insert(Inst);
6788 CurPts.push_back(Inst);
6830bool CodeGenPrepare::splitLargeGEPOffsets() {
6832 for (
auto &Entry : LargeOffsetGEPMap) {
6834 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6835 &LargeOffsetGEPs =
Entry.second;
6836 auto compareGEPOffset =
6837 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6838 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6839 if (
LHS.first ==
RHS.first)
6841 if (
LHS.second !=
RHS.second)
6842 return LHS.second <
RHS.second;
6843 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6846 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6849 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6851 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6852 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6853 Value *NewBaseGEP =
nullptr;
6855 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6856 GetElementPtrInst *
GEP) {
6857 LLVMContext &Ctx =
GEP->getContext();
6858 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6860 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6872 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), DT.get(), LI);
6875 NewBaseInsertPt = std::next(BaseI->getIterator());
6882 IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
6888 NewBaseGEP = OldBase;
6889 if (NewBaseGEP->
getType() != I8PtrTy)
6890 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6892 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6893 NewGEPBases.
insert(NewBaseGEP);
6899 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6900 BaseOffset = PreferBase;
6903 createNewBase(BaseOffset, OldBase, BaseGEP);
6906 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6907 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6908 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6909 int64_t
Offset = LargeOffsetGEP->second;
6910 if (
Offset != BaseOffset) {
6917 GEP->getResultElementType(),
6918 GEP->getAddressSpace())) {
6924 NewBaseGEP =
nullptr;
6929 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6934 createNewBase(BaseOffset, OldBase,
GEP);
6938 Value *NewGEP = NewBaseGEP;
6939 if (
Offset != BaseOffset) {
6942 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6946 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6947 GEP->eraseFromParent();
6954bool CodeGenPrepare::optimizePhiType(
6955 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
6956 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
6961 Type *PhiTy =
I->getType();
6962 Type *ConvertTy =
nullptr;
6964 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6967 SmallVector<Instruction *, 4> Worklist;
6969 SmallPtrSet<PHINode *, 4> PhiNodes;
6970 SmallPtrSet<ConstantData *, 4>
Constants;
6973 SmallPtrSet<Instruction *, 4> Defs;
6974 SmallPtrSet<Instruction *, 4>
Uses;
6980 bool AnyAnchored =
false;
6982 while (!Worklist.
empty()) {
6987 for (
Value *V :
Phi->incoming_values()) {
6989 if (!PhiNodes.
count(OpPhi)) {
6990 if (!Visited.
insert(OpPhi).second)
6996 if (!OpLoad->isSimple())
6998 if (Defs.
insert(OpLoad).second)
7001 if (Defs.
insert(OpEx).second)
7005 ConvertTy = OpBC->getOperand(0)->getType();
7006 if (OpBC->getOperand(0)->getType() != ConvertTy)
7008 if (Defs.
insert(OpBC).second) {
7021 for (User *V :
II->users()) {
7023 if (!PhiNodes.
count(OpPhi)) {
7024 if (Visited.
count(OpPhi))
7031 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
7033 Uses.insert(OpStore);
7036 ConvertTy = OpBC->getType();
7037 if (OpBC->getType() != ConvertTy)
7041 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
7048 if (!ConvertTy || !AnyAnchored || PhiTy == ConvertTy ||
7052 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
7053 << *ConvertTy <<
"\n");
7058 for (ConstantData *
C : Constants)
7060 for (Instruction *
D : Defs) {
7062 ValMap[
D] =
D->getOperand(0);
7066 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
7069 for (PHINode *Phi : PhiNodes)
7071 Phi->getName() +
".tc",
Phi->getIterator());
7073 for (PHINode *Phi : PhiNodes) {
7075 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
7077 Phi->getIncomingBlock(i));
7081 for (Instruction *U :
Uses) {
7086 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
7096bool CodeGenPrepare::optimizePhiTypes(Function &
F) {
7101 SmallPtrSet<PHINode *, 4> Visited;
7102 SmallPtrSet<Instruction *, 4> DeletedInstrs;
7106 for (
auto &Phi : BB.
phis())
7107 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
7110 for (
auto *
I : DeletedInstrs) {
7112 I->eraseFromParent();
7120bool CodeGenPrepare::canFormExtLd(
7121 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
7122 Instruction *&Inst,
bool HasPromoted) {
7123 for (
auto *MovedExtInst : MovedExts) {
7126 Inst = MovedExtInst;
7178bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7179 bool AllowPromotionWithoutCommonHeader =
false;
7184 *Inst, AllowPromotionWithoutCommonHeader);
7185 TypePromotionTransaction TPT(RemovedInsts);
7186 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7187 TPT.getRestorationPoint();
7189 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7192 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7195 LoadInst *LI =
nullptr;
7200 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7201 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7206 Inst = ExtFedByLoad;
7211 if (ATPConsiderable &&
7212 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7213 HasPromoted, TPT, SpeculativelyMovedExts))
7216 TPT.rollback(LastKnownGood);
7225bool CodeGenPrepare::performAddressTypePromotion(
7226 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7227 bool HasPromoted, TypePromotionTransaction &TPT,
7228 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7229 bool Promoted =
false;
7230 SmallPtrSet<Instruction *, 1> UnhandledExts;
7231 bool AllSeenFirst =
true;
7232 for (
auto *
I : SpeculativelyMovedExts) {
7233 Value *HeadOfChain =
I->getOperand(0);
7234 DenseMap<Value *, Instruction *>::iterator AlreadySeen =
7235 SeenChainsForSExt.
find(HeadOfChain);
7238 if (AlreadySeen != SeenChainsForSExt.
end()) {
7239 if (AlreadySeen->second !=
nullptr)
7240 UnhandledExts.
insert(AlreadySeen->second);
7241 AllSeenFirst =
false;
7245 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7246 SpeculativelyMovedExts.size() == 1)) {
7250 for (
auto *
I : SpeculativelyMovedExts) {
7251 Value *HeadOfChain =
I->getOperand(0);
7252 SeenChainsForSExt[HeadOfChain] =
nullptr;
7253 ValToSExtendedUses[HeadOfChain].push_back(
I);
7256 Inst = SpeculativelyMovedExts.pop_back_val();
7261 for (
auto *
I : SpeculativelyMovedExts) {
7262 Value *HeadOfChain =
I->getOperand(0);
7263 SeenChainsForSExt[HeadOfChain] = Inst;
7268 if (!AllSeenFirst && !UnhandledExts.
empty())
7269 for (
auto *VisitedSExt : UnhandledExts) {
7270 if (RemovedInsts.count(VisitedSExt))
7272 TypePromotionTransaction TPT(RemovedInsts);
7274 SmallVector<Instruction *, 2> Chains;
7276 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7280 for (
auto *
I : Chains) {
7281 Value *HeadOfChain =
I->getOperand(0);
7283 SeenChainsForSExt[HeadOfChain] =
nullptr;
7284 ValToSExtendedUses[HeadOfChain].push_back(
I);
7290bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7295 Value *Src =
I->getOperand(0);
7296 if (Src->hasOneUse())
7308 bool DefIsLiveOut =
false;
7309 for (User *U :
I->users()) {
7314 if (UserBB == DefBB)
7316 DefIsLiveOut =
true;
7323 for (User *U : Src->users()) {
7326 if (UserBB == DefBB)
7335 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7337 bool MadeChange =
false;
7338 for (Use &U : Src->uses()) {
7343 if (UserBB == DefBB)
7347 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7349 if (!InsertedTrunc) {
7352 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7354 InsertedInsts.insert(InsertedTrunc);
7417bool CodeGenPrepare::optimizeLoadExt(LoadInst *Load) {
7418 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7422 if (
Load->hasOneUse() &&
7428 SmallVector<Instruction *, 8> WorkList;
7429 SmallPtrSet<Instruction *, 16> Visited;
7430 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7431 SmallVector<Instruction *, 8> DropFlags;
7432 for (
auto *U :
Load->users())
7444 while (!WorkList.
empty()) {
7448 if (!Visited.
insert(
I).second)
7453 for (
auto *U :
Phi->users())
7458 switch (
I->getOpcode()) {
7459 case Instruction::And: {
7463 APInt AndBits = AndC->getValue();
7464 DemandBits |= AndBits;
7466 if (AndBits.
ugt(WidestAndBits))
7467 WidestAndBits = AndBits;
7468 if (AndBits == WidestAndBits &&
I->getOperand(0) == Load)
7473 case Instruction::Shl: {
7477 uint64_t ShiftAmt = ShlC->getLimitedValue(
BitWidth - 1);
7478 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7483 case Instruction::Trunc: {
7486 DemandBits.setLowBits(TruncBitWidth);
7496 uint32_t ActiveBits = DemandBits.getActiveBits();
7508 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7509 WidestAndBits != DemandBits)
7512 LLVMContext &Ctx =
Load->getType()->getContext();
7513 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7523 Builder.CreateAnd(Load, ConstantInt::get(Ctx, DemandBits)));
7526 InsertedInsts.insert(NewAnd);
7531 NewAnd->setOperand(0, Load);
7534 for (
auto *
And : AndsToMaybeRemove)
7539 if (&*CurInstIterator ==
And)
7540 CurInstIterator = std::next(
And->getIterator());
7541 And->eraseFromParent();
7546 for (
auto *Inst : DropFlags)
7560 TTI->isExpensiveToSpeculativelyExecute(
I);
7578 uint64_t Max = std::max(TrueWeight, FalseWeight);
7579 uint64_t Sum = TrueWeight + FalseWeight;
7582 if (Probability >
TTI->getPredictableBranchThreshold())
7592 if (!Cmp || !Cmp->hasOneUse())
7615 assert(DefSI->getCondition() ==
SI->getCondition() &&
7616 "The condition of DefSI does not match with SI");
7617 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7620 assert(V &&
"Failed to get select true/false value");
7624bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7648 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7649 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7650 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7651 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7657bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7659 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7660 "Expected a funnel shift");
7684 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7685 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7686 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7694bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7706 It !=
SI->getParent()->
end(); ++It) {
7708 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7715 SelectInst *LastSI = ASI.
back();
7718 CurInstIterator = std::next(LastSI->
getIterator());
7722 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7723 fixupDbgVariableRecordsOnInst(*SI);
7725 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7728 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7731 TargetLowering::SelectSupportKind SelectKind;
7732 if (
SI->getType()->isVectorTy())
7733 SelectKind = TargetLowering::ScalarCondVectorVal;
7735 SelectKind = TargetLowering::ScalarValSelect;
7776 for (SelectInst *SI : ASI) {
7788 SplitPt.setHeadBit(
true);
7791 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7796 BranchInst *TrueBranch =
nullptr;
7797 BranchInst *FalseBranch =
nullptr;
7798 if (TrueInstrs.
size() == 0) {
7800 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7803 }
else if (FalseInstrs.
size() == 0) {
7805 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7812 nullptr,
nullptr, LI);
7820 EndBlock->
setName(
"select.end");
7822 TrueBlock->
setName(
"select.true.sink");
7824 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7825 :
"select.false.sink");
7829 FreshBBs.
insert(TrueBlock);
7831 FreshBBs.
insert(FalseBlock);
7832 FreshBBs.
insert(EndBlock);
7837 static const unsigned MD[] = {
7838 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7839 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7844 for (Instruction *
I : TrueInstrs)
7846 for (Instruction *
I : FalseInstrs)
7853 if (TrueBlock ==
nullptr)
7854 TrueBlock = StartBlock;
7855 else if (FalseBlock ==
nullptr)
7856 FalseBlock = StartBlock;
7872 SI->eraseFromParent();
7874 ++NumSelectsExpanded;
7878 CurInstIterator = StartBlock->
end();
7885bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7897 "Expected a type of the same size!");
7903 Builder.SetInsertPoint(SVI);
7904 Value *BC1 = Builder.CreateBitCast(
7906 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7907 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7911 SVI, TLInfo,
nullptr,
7912 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7919 !
Op->isTerminator() && !
Op->isEHPad())
7925bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7940 DenseMap<const Instruction *, unsigned long> InstOrdering;
7941 unsigned long InstNumber = 0;
7942 for (
const auto &
I : *TargetBB)
7943 InstOrdering[&
I] = InstNumber++;
7945 for (Use *U :
reverse(OpsToSink)) {
7950 if (InstOrdering[UI] < InstOrdering[InsertPoint])
7957 SetVector<Instruction *> MaybeDead;
7958 DenseMap<Instruction *, Instruction *> NewInstructions;
7959 for (Use *U : ToReplace) {
7968 FreshBBs.
insert(OpDef->getParent());
7971 NewInstructions[UI] = NI;
7976 InsertedInsts.insert(NI);
7982 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
7983 It->second->setOperand(
U->getOperandNo(), NI);
7990 for (
auto *
I : MaybeDead) {
7991 if (!
I->hasNUsesOrMore(1)) {
7993 I->eraseFromParent();
8000bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
8017 auto *NewType = Type::getIntNTy(
Context, RegWidth);
8026 ExtType = Instruction::SExt;
8029 if (Arg->hasSExtAttr())
8030 ExtType = Instruction::SExt;
8031 if (Arg->hasZExtAttr())
8032 ExtType = Instruction::ZExt;
8038 SI->setCondition(ExtInst);
8039 for (
auto Case :
SI->cases()) {
8040 const APInt &NarrowConst = Case.getCaseValue()->getValue();
8041 APInt WideConst = (ExtType == Instruction::ZExt)
8042 ? NarrowConst.
zext(RegWidth)
8043 : NarrowConst.
sext(RegWidth);
8044 Case.setValue(ConstantInt::get(
Context, WideConst));
8050bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
8057 Value *Condition =
SI->getCondition();
8066 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
8067 ConstantInt *CaseValue = Case.getCaseValue();
8068 BasicBlock *CaseBB = Case.getCaseSuccessor();
8071 bool CheckedForSinglePred =
false;
8072 for (PHINode &
PHI : CaseBB->
phis()) {
8073 Type *PHIType =
PHI.getType();
8081 if (PHIType == ConditionType || TryZExt) {
8083 bool SkipCase =
false;
8084 Value *Replacement =
nullptr;
8085 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
8086 Value *PHIValue =
PHI.getIncomingValue(
I);
8087 if (PHIValue != CaseValue) {
8096 if (
PHI.getIncomingBlock(
I) != SwitchBB)
8101 if (!CheckedForSinglePred) {
8102 CheckedForSinglePred =
true;
8103 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
8109 if (Replacement ==
nullptr) {
8110 if (PHIValue == CaseValue) {
8111 Replacement = Condition;
8114 Replacement = Builder.CreateZExt(Condition, PHIType);
8117 PHI.setIncomingValue(
I, Replacement);
8128bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
8129 bool Changed = optimizeSwitchType(SI);
8130 Changed |= optimizeSwitchPhiConstants(SI);
8151class VectorPromoteHelper {
8153 const DataLayout &
DL;
8156 const TargetLowering &TLI;
8159 const TargetTransformInfo &
TTI;
8165 SmallVector<Instruction *, 4> InstsToBePromoted;
8168 unsigned StoreExtractCombineCost;
8177 if (InstsToBePromoted.
empty())
8179 return InstsToBePromoted.
back();
8185 unsigned getTransitionOriginalValueIdx()
const {
8187 "Other kind of transitions are not supported yet");
8194 unsigned getTransitionIdx()
const {
8196 "Other kind of transitions are not supported yet");
8204 Type *getTransitionType()
const {
8215 void promoteImpl(Instruction *ToBePromoted);
8219 bool isProfitableToPromote() {
8220 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8224 Type *PromotedType = getTransitionType();
8227 unsigned AS =
ST->getPointerAddressSpace();
8245 for (
const auto &Inst : InstsToBePromoted) {
8253 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8265 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8266 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8267 return ScalarCost > VectorCost;
8279 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8294 if (!
EC.isScalable()) {
8295 SmallVector<Constant *, 4> ConstVec;
8297 for (
unsigned Idx = 0; Idx !=
EC.getKnownMinValue(); ++Idx) {
8298 if (Idx == ExtractIdx)
8306 "Generate scalable vector for non-splat is unimplemented");
8311 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8312 unsigned OperandIdx) {
8315 if (OperandIdx != 1)
8317 switch (
Use->getOpcode()) {
8320 case Instruction::SDiv:
8321 case Instruction::UDiv:
8322 case Instruction::SRem:
8323 case Instruction::URem:
8325 case Instruction::FDiv:
8326 case Instruction::FRem:
8327 return !
Use->hasNoNaNs();
8333 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8334 const TargetTransformInfo &
TTI, Instruction *Transition,
8335 unsigned CombineCost)
8336 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8337 StoreExtractCombineCost(CombineCost) {
8338 assert(Transition &&
"Do not know how to promote null");
8342 bool canPromote(
const Instruction *ToBePromoted)
const {
8349 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8352 for (
const Use &U : ToBePromoted->
operands()) {
8353 const Value *Val =
U.get();
8354 if (Val == getEndOfTransition()) {
8358 if (canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()))
8381 void enqueueForPromotion(Instruction *ToBePromoted) {
8382 InstsToBePromoted.push_back(ToBePromoted);
8386 void recordCombineInstruction(Instruction *ToBeCombined) {
8388 CombineInst = ToBeCombined;
8398 if (InstsToBePromoted.empty() || !CombineInst)
8406 for (
auto &ToBePromoted : InstsToBePromoted)
8407 promoteImpl(ToBePromoted);
8408 InstsToBePromoted.clear();
8415void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8425 "The type of the result of the transition does not match "
8430 Type *TransitionTy = getTransitionType();
8435 for (Use &U : ToBePromoted->
operands()) {
8437 Value *NewVal =
nullptr;
8438 if (Val == Transition)
8439 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8446 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8450 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8453 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8459bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8460 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8475 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8476 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost);
8483 if (ToBePromoted->
getParent() != Parent) {
8484 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8486 <<
") than the transition (" << Parent->
getName()
8491 if (VPH.canCombine(ToBePromoted)) {
8493 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8494 VPH.recordCombineInstruction(ToBePromoted);
8496 NumStoreExtractExposed +=
Changed;
8501 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8504 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8506 VPH.enqueueForPromotion(ToBePromoted);
8507 Inst = ToBePromoted;
8547 Type *StoreType =
SI.getValueOperand()->getType();
8556 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8557 DL.getTypeSizeInBits(StoreType) == 0)
8560 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8562 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8566 if (
SI.isVolatile())
8578 if (!
match(
SI.getValueOperand(),
8585 if (!
LValue->getType()->isIntegerTy() ||
8586 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8588 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8604 Builder.SetInsertPoint(&
SI);
8608 if (LBC && LBC->getParent() !=
SI.getParent())
8609 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8610 if (HBC && HBC->getParent() !=
SI.getParent())
8611 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8613 bool IsLE =
SI.getDataLayout().isLittleEndian();
8614 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8615 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8616 Value *Addr =
SI.getPointerOperand();
8617 Align Alignment =
SI.getAlign();
8618 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8619 if (IsOffsetStore) {
8620 Addr = Builder.CreateGEP(
8621 SplitStoreType, Addr,
8629 Builder.CreateAlignedStore(V, Addr, Alignment);
8632 CreateSplitStore(
LValue,
false);
8633 CreateSplitStore(HValue,
true);
8636 SI.eraseFromParent();
8644 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8726 if (GEPIOpI->getParent() != SrcBlock)
8731 if (auto *I = dyn_cast<Instruction>(Usr)) {
8732 if (I->getParent() != SrcBlock) {
8740 std::vector<GetElementPtrInst *> UGEPIs;
8743 for (User *Usr : GEPIOp->
users()) {
8762 if (UGEPI->getOperand(0) != GEPIOp)
8764 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8766 if (GEPIIdx->getType() !=
8774 UGEPIs.push_back(UGEPI);
8776 if (UGEPIs.size() == 0)
8779 for (GetElementPtrInst *UGEPI : UGEPIs) {
8781 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8788 for (GetElementPtrInst *UGEPI : UGEPIs) {
8789 UGEPI->setOperand(0, GEPI);
8791 Constant *NewUGEPIIdx = ConstantInt::get(
8792 GEPIIdx->getType(), UGEPIIdx->
getValue() - GEPIIdx->getValue());
8793 UGEPI->setOperand(1, NewUGEPIIdx);
8796 if (!GEPI->isInBounds()) {
8797 UGEPI->setIsInBounds(
false);
8804 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8806 "GEPIOp is used outside SrcBlock");
8830 Value *
X = Cmp->getOperand(0);
8831 if (!
X->hasUseList())
8836 for (
auto *U :
X->users()) {
8840 (UI->
getParent() != Branch->getParent() &&
8841 UI->
getParent() != Branch->getSuccessor(0) &&
8842 UI->
getParent() != Branch->getSuccessor(1)) ||
8843 (UI->
getParent() != Branch->getParent() &&
8844 !UI->
getParent()->getSinglePredecessor()))
8850 if (UI->
getParent() != Branch->getParent())
8854 ConstantInt::get(UI->
getType(), 0));
8856 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8860 if (Cmp->isEquality() &&
8865 if (UI->
getParent() != Branch->getParent())
8868 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8869 ConstantInt::get(UI->
getType(), 0));
8871 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8879bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8880 bool AnyChange =
false;
8881 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8885 if (InsertedInsts.count(
I))
8894 LargeOffsetGEPMap.erase(
P);
8896 P->eraseFromParent();
8919 I, LI->getLoopFor(
I->getParent()), *
TTI))
8927 TargetLowering::TypeExpandInteger) {
8931 I, LI->getLoopFor(
I->getParent()), *
TTI))
8934 bool MadeChange = optimizeExt(
I);
8935 return MadeChange | optimizeExtUses(
I);
8942 if (optimizeCmp(Cmp, ModifiedDT))
8946 if (optimizeURem(
I))
8950 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8951 bool Modified = optimizeLoadExt(LI);
8960 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8961 unsigned AS =
SI->getPointerAddressSpace();
8962 return optimizeMemoryInst(
I,
SI->getOperand(1),
8963 SI->getOperand(0)->getType(), AS);
8967 unsigned AS = RMW->getPointerAddressSpace();
8968 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
8972 unsigned AS = CmpX->getPointerAddressSpace();
8973 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
8974 CmpX->getCompareOperand()->getType(), AS);
8984 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
8985 BinOp->
getOpcode() == Instruction::LShr)) {
8993 if (GEPI->hasAllZeroIndices()) {
8995 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
8996 GEPI->getName(), GEPI->getIterator());
8997 NC->setDebugLoc(GEPI->getDebugLoc());
9000 GEPI, TLInfo,
nullptr,
9001 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9003 optimizeInst(
NC, ModifiedDT);
9026 if (Const0 || Const1) {
9027 if (!Const0 || !Const1) {
9028 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
9033 FI->eraseFromParent();
9040 if (tryToSinkFreeOperands(
I))
9043 switch (
I->getOpcode()) {
9044 case Instruction::Shl:
9045 case Instruction::LShr:
9046 case Instruction::AShr:
9048 case Instruction::Call:
9050 case Instruction::Select:
9052 case Instruction::ShuffleVector:
9054 case Instruction::Switch:
9056 case Instruction::ExtractElement:
9058 case Instruction::Br:
9067bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
9068 if (!
I.getType()->isIntegerTy() ||
9073 SmallVector<Instruction *, 4> Insts;
9079 &
I, TLInfo,
nullptr,
9080 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9087bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
9089 bool MadeChange =
false;
9092 CurInstIterator = BB.
begin();
9093 ModifiedDT = ModifyDT::NotModifyDT;
9094 while (CurInstIterator != BB.
end()) {
9095 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
9096 if (ModifiedDT != ModifyDT::NotModifyDT) {
9109 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
9111 bool MadeBitReverse =
true;
9112 while (MadeBitReverse) {
9113 MadeBitReverse =
false;
9115 if (makeBitReverse(
I)) {
9116 MadeBitReverse = MadeChange =
true;
9121 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
9126bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
9127 bool AnyChange =
false;
9128 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
9129 AnyChange |= fixupDbgVariableRecord(DVR);
9135bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
9136 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
9137 DVR.
Type != DbgVariableRecord::LocationType::Assign)
9141 bool AnyChange =
false;
9142 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
9144 for (
Value *Location : LocationOps) {
9145 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9174bool CodeGenPrepare::placeDbgValues(Function &
F) {
9175 bool MadeChange =
false;
9176 DominatorTree DT(
F);
9178 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9179 SmallVector<Instruction *, 4> VIs;
9180 for (
Value *V : DbgItem->location_ops())
9188 for (Instruction *VI : VIs) {
9189 if (
VI->isTerminator())
9194 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9205 if (VIs.size() > 1) {
9208 <<
"Unable to find valid location for Debug Value, undefing:\n"
9210 DbgItem->setKillLocation();
9215 << *DbgItem <<
' ' << *VI);
9222 for (BasicBlock &BB :
F) {
9228 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9230 DbgProcessor(&DVR, &Insn);
9241bool CodeGenPrepare::placePseudoProbes(Function &
F) {
9242 bool MadeChange =
false;
9245 auto FirstInst =
Block.getFirstInsertionPt();
9246 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9250 while (
I !=
Block.end()) {
9252 II->moveBefore(FirstInst);
9262 uint64_t NewMax = (NewTrue > NewFalse) ? NewTrue : NewFalse;
9263 uint32_t Scale = (NewMax / std::numeric_limits<uint32_t>::max()) + 1;
9264 NewTrue = NewTrue / Scale;
9265 NewFalse = NewFalse / Scale;
9290bool CodeGenPrepare::splitBranchCondition(Function &
F, ModifyDT &ModifiedDT) {
9294 bool MadeChange =
false;
9295 for (
auto &BB :
F) {
9308 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9316 Value *Cond1, *Cond2;
9319 Opc = Instruction::And;
9322 Opc = Instruction::Or;
9332 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9346 Br1->setCondition(Cond1);
9351 if (
Opc == Instruction::And)
9352 Br1->setSuccessor(0, TmpBB);
9354 Br1->setSuccessor(1, TmpBB);
9359 I->removeFromParent();
9360 I->insertBefore(Br2->getIterator());
9372 if (
Opc == Instruction::Or)
9379 for (PHINode &PN : FBB->
phis()) {
9386 if (
Opc == Instruction::Or) {
9406 uint64_t TrueWeight, FalseWeight;
9408 uint64_t NewTrueWeight = TrueWeight;
9409 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9411 Br1->setMetadata(LLVMContext::MD_prof,
9412 MDBuilder(Br1->getContext())
9413 .createBranchWeights(TrueWeight, FalseWeight,
9416 NewTrueWeight = TrueWeight;
9417 NewFalseWeight = 2 * FalseWeight;
9419 Br2->setMetadata(LLVMContext::MD_prof,
9420 MDBuilder(Br2->getContext())
9421 .createBranchWeights(TrueWeight, FalseWeight));
9442 uint64_t TrueWeight, FalseWeight;
9444 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9445 uint64_t NewFalseWeight = FalseWeight;
9447 Br1->setMetadata(LLVMContext::MD_prof,
9448 MDBuilder(Br1->getContext())
9449 .createBranchWeights(TrueWeight, FalseWeight));
9451 NewTrueWeight = 2 * TrueWeight;
9452 NewFalseWeight = FalseWeight;
9454 Br2->setMetadata(LLVMContext::MD_prof,
9455 MDBuilder(Br2->getContext())
9456 .createBranchWeights(TrueWeight, FalseWeight));
9460 ModifiedDT = ModifyDT::ModifyBBDT;
static unsigned getIntrinsicID(const SDNode *N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
This file contains the simple types necessary to represent the attributes associated with functions a...
static const Function * getParent(const Value *V)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool sinkAndCmp0Expression(Instruction *AndI, const TargetLowering &TLI, SetOfInstrs &InsertedInsts)
Duplicate and sink the given 'and' instruction into user blocks where it is used in a compare to allo...
static bool SinkShiftAndTruncate(BinaryOperator *ShiftI, Instruction *User, ConstantInt *CI, DenseMap< BasicBlock *, BinaryOperator * > &InsertedShifts, const TargetLowering &TLI, const DataLayout &DL)
Sink both shift and truncate instruction to the use of truncate's BB.
static bool getGEPSmallConstantIntOffsetV(GetElementPtrInst *GEP, SmallVectorImpl< Value * > &OffsetV)
static bool sinkSelectOperand(const TargetTransformInfo *TTI, Value *V)
Check if V (an operand of a select instruction) is an expensive instruction that is only used once.
static bool isExtractBitsCandidateUse(Instruction *User)
Check if the candidates could be combined with a shift instruction, which includes:
static cl::opt< unsigned > MaxAddressUsersToScan("cgp-max-address-users-to-scan", cl::init(100), cl::Hidden, cl::desc("Max number of address users to look at"))
static cl::opt< bool > OptimizePhiTypes("cgp-optimize-phi-types", cl::Hidden, cl::init(true), cl::desc("Enable converting phi types in CodeGenPrepare"))
static cl::opt< bool > DisableStoreExtract("disable-cgp-store-extract", cl::Hidden, cl::init(false), cl::desc("Disable store(extract) optimizations in CodeGenPrepare"))
static bool foldFCmpToFPClassTest(CmpInst *Cmp, const TargetLowering &TLI, const DataLayout &DL)
static void scaleWeights(uint64_t &NewTrue, uint64_t &NewFalse)
Scale down both weights to fit into uint32_t.
static cl::opt< bool > ProfileUnknownInSpecialSection("profile-unknown-in-special-section", cl::Hidden, cl::desc("In profiling mode like sampleFDO, if a function doesn't have " "profile, we cannot tell the function is cold for sure because " "it may be a function newly added without ever being sampled. " "With the flag enabled, compiler can put such profile unknown " "functions into a special section, so runtime system can choose " "to handle it in a different way than .text section, to save " "RAM for example. "))
static bool OptimizeExtractBits(BinaryOperator *ShiftI, ConstantInt *CI, const TargetLowering &TLI, const DataLayout &DL)
Sink the shift right instruction into user blocks if the uses could potentially be combined with this...
static cl::opt< bool > DisableExtLdPromotion("disable-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), cl::desc("Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in " "CodeGenPrepare"))
static cl::opt< bool > DisablePreheaderProtect("disable-preheader-prot", cl::Hidden, cl::init(false), cl::desc("Disable protection against removing loop preheaders"))
static cl::opt< bool > AddrSinkCombineBaseOffs("addr-sink-combine-base-offs", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseOffs field in Address sinking."))
static bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI, const DataLayout &DL)
If the specified cast instruction is a noop copy (e.g.
static bool splitMergedValStore(StoreInst &SI, const DataLayout &DL, const TargetLowering &TLI)
For the instruction sequence of store below, F and I values are bundled together as an i64 value befo...
static bool SinkCast(CastInst *CI)
Sink the specified cast instruction into its user blocks.
static bool swapICmpOperandsToExposeCSEOpportunities(CmpInst *Cmp)
Many architectures use the same instruction for both subtract and cmp.
static cl::opt< bool > AddrSinkCombineBaseReg("addr-sink-combine-base-reg", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseReg field in Address sinking."))
static bool FindAllMemoryUses(Instruction *I, SmallVectorImpl< std::pair< Use *, Type * > > &MemoryUses, SmallPtrSetImpl< Instruction * > &ConsideredInsts, const TargetLowering &TLI, const TargetRegisterInfo &TRI, bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI, unsigned &SeenInsts)
Recursively walk all the uses of I until we find a memory use.
static cl::opt< bool > StressStoreExtract("stress-cgp-store-extract", cl::Hidden, cl::init(false), cl::desc("Stress test store(extract) optimizations in CodeGenPrepare"))
static bool isFormingBranchFromSelectProfitable(const TargetTransformInfo *TTI, const TargetLowering *TLI, SelectInst *SI)
Returns true if a SelectInst should be turned into an explicit branch.
static std::optional< std::pair< Instruction *, Constant * > > getIVIncrement(const PHINode *PN, const LoopInfo *LI)
If given PN is an inductive variable with value IVInc coming from the backedge, and on each iteration...
static cl::opt< bool > AddrSinkCombineBaseGV("addr-sink-combine-base-gv", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseGV field in Address sinking."))
static cl::opt< bool > AddrSinkUsingGEPs("addr-sink-using-gep", cl::Hidden, cl::init(true), cl::desc("Address sinking in CGP using GEPs."))
static Value * getTrueOrFalseValue(SelectInst *SI, bool isTrue, const SmallPtrSet< const Instruction *, 2 > &Selects)
If isTrue is true, return the true value of SI, otherwise return false value of SI.
static cl::opt< bool > DisableBranchOpts("disable-cgp-branch-opts", cl::Hidden, cl::init(false), cl::desc("Disable branch optimizations in CodeGenPrepare"))
static cl::opt< bool > EnableTypePromotionMerge("cgp-type-promotion-merge", cl::Hidden, cl::desc("Enable merging of redundant sexts when one is dominating" " the other."), cl::init(true))
static cl::opt< bool > ProfileGuidedSectionPrefix("profile-guided-section-prefix", cl::Hidden, cl::init(true), cl::desc("Use profile info to add section prefix for hot/cold functions"))
static cl::opt< unsigned > HugeFuncThresholdInCGPP("cgpp-huge-func", cl::init(10000), cl::Hidden, cl::desc("Least BB number of huge function."))
static cl::opt< bool > AddrSinkNewSelects("addr-sink-new-select", cl::Hidden, cl::init(true), cl::desc("Allow creation of selects in Address sinking."))
static bool foldURemOfLoopIncrement(Instruction *Rem, const DataLayout *DL, const LoopInfo *LI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
static bool optimizeBranch(BranchInst *Branch, const TargetLowering &TLI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
static bool tryUnmergingGEPsAcrossIndirectBr(GetElementPtrInst *GEPI, const TargetTransformInfo *TTI)
static bool IsOperandAMemoryOperand(CallInst *CI, InlineAsm *IA, Value *OpVal, const TargetLowering &TLI, const TargetRegisterInfo &TRI)
Check to see if all uses of OpVal by the specified inline asm call are due to memory operands.
static bool isIntrinsicOrLFToBeTailCalled(const TargetLibraryInfo *TLInfo, const CallInst *CI)
static void replaceAllUsesWith(Value *Old, Value *New, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
Replace all old uses with new ones, and push the updated BBs into FreshBBs.
static cl::opt< bool > ForceSplitStore("force-split-store", cl::Hidden, cl::init(false), cl::desc("Force store splitting no matter what the target query says."))
static bool matchOverflowPattern(Instruction *&I, ExtractValueInst *&MulExtract, ExtractValueInst *&OverflowExtract)
static void computeBaseDerivedRelocateMap(const SmallVectorImpl< GCRelocateInst * > &AllRelocateCalls, MapVector< GCRelocateInst *, SmallVector< GCRelocateInst *, 0 > > &RelocateInstMap)
static bool simplifyRelocatesOffABase(GCRelocateInst *RelocatedBase, const SmallVectorImpl< GCRelocateInst * > &Targets)
static cl::opt< bool > AddrSinkCombineScaledReg("addr-sink-combine-scaled-reg", cl::Hidden, cl::init(true), cl::desc("Allow combining of ScaledReg field in Address sinking."))
static bool foldICmpWithDominatingICmp(CmpInst *Cmp, const TargetLowering &TLI)
For pattern like:
static bool MightBeFoldableInst(Instruction *I)
This is a little filter, which returns true if an addressing computation involving I might be folded ...
static bool matchIncrement(const Instruction *IVInc, Instruction *&LHS, Constant *&Step)
static cl::opt< bool > EnableGEPOffsetSplit("cgp-split-large-offset-gep", cl::Hidden, cl::init(true), cl::desc("Enable splitting large offset of GEP."))
static cl::opt< bool > DisableComplexAddrModes("disable-complex-addr-modes", cl::Hidden, cl::init(false), cl::desc("Disables combining addressing modes with different parts " "in optimizeMemoryInst."))
static cl::opt< bool > EnableICMP_EQToICMP_ST("cgp-icmp-eq2icmp-st", cl::Hidden, cl::init(false), cl::desc("Enable ICMP_EQ to ICMP_S(L|G)T conversion."))
static cl::opt< bool > VerifyBFIUpdates("cgp-verify-bfi-updates", cl::Hidden, cl::init(false), cl::desc("Enable BFI update verification for " "CodeGenPrepare."))
static cl::opt< bool > BBSectionsGuidedSectionPrefix("bbsections-guided-section-prefix", cl::Hidden, cl::init(true), cl::desc("Use the basic-block-sections profile to determine the text " "section prefix for hot functions. Functions with " "basic-block-sections profile will be placed in `.text.hot` " "regardless of their FDO profile info. Other functions won't be " "impacted, i.e., their prefixes will be decided by FDO/sampleFDO " "profiles."))
static bool isRemOfLoopIncrementWithLoopInvariant(Instruction *Rem, const LoopInfo *LI, Value *&RemAmtOut, Value *&AddInstOut, Value *&AddOffsetOut, PHINode *&LoopIncrPNOut)
static bool isIVIncrement(const Value *V, const LoopInfo *LI)
static cl::opt< bool > DisableGCOpts("disable-cgp-gc-opts", cl::Hidden, cl::init(false), cl::desc("Disable GC optimizations in CodeGenPrepare"))
static bool GEPSequentialConstIndexed(GetElementPtrInst *GEP)
static void DbgInserterHelper(DbgVariableRecord *DVR, BasicBlock::iterator VI)
static bool isPromotedInstructionLegal(const TargetLowering &TLI, const DataLayout &DL, Value *Val)
Check whether or not Val is a legal instruction for TLI.
static cl::opt< uint64_t > FreqRatioToSkipMerge("cgp-freq-ratio-to-skip-merge", cl::Hidden, cl::init(2), cl::desc("Skip merging empty blocks if (frequency of empty block) / " "(frequency of destination block) is greater than this ratio"))
static BasicBlock::iterator findInsertPos(Value *Addr, Instruction *MemoryInst, Value *SunkAddr)
static bool IsNonLocalValue(Value *V, BasicBlock *BB)
Return true if the specified values are defined in a different basic block than BB.
static cl::opt< bool > EnableAndCmpSinking("enable-andcmp-sinking", cl::Hidden, cl::init(true), cl::desc("Enable sinking and/cmp into branches."))
static bool sinkCmpExpression(CmpInst *Cmp, const TargetLowering &TLI, const DataLayout &DL)
Sink the given CmpInst into user blocks to reduce the number of virtual registers that must be create...
static bool hasSameExtUse(Value *Val, const TargetLowering &TLI)
Check if all the uses of Val are equivalent (or free) zero or sign extensions.
static bool despeculateCountZeros(IntrinsicInst *CountZeros, LoopInfo &LI, const TargetLowering *TLI, const DataLayout *DL, ModifyDT &ModifiedDT, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
If counting leading or trailing zeros is an expensive operation and a zero input is defined,...
static cl::opt< bool > StressExtLdPromotion("stress-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), cl::desc("Stress test ext(promotable(ld)) -> promoted(ext(ld)) " "optimization in CodeGenPrepare"))
static bool matchUAddWithOverflowConstantEdgeCases(CmpInst *Cmp, BinaryOperator *&Add)
Match special-case patterns that check for unsigned add overflow.
static cl::opt< bool > DisableSelectToBranch("disable-cgp-select2branch", cl::Hidden, cl::init(false), cl::desc("Disable select to branch conversion."))
static cl::opt< bool > DisableDeletePHIs("disable-cgp-delete-phis", cl::Hidden, cl::init(false), cl::desc("Disable elimination of dead PHI nodes."))
static cl::opt< bool > AddrSinkNewPhis("addr-sink-new-phis", cl::Hidden, cl::init(false), cl::desc("Allow creation of Phis in Address sinking."))
Defines an IR pass for CodeGen Prepare.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
static Value * getCondition(Instruction *I)
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU)
Register const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the PointerIntPair class.
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, const MachineInstr &B)
Remove Loads Into Fake Uses
static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static SymbolRef::Type getType(const Symbol *Sym)
static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, unsigned CombineOpc=0)
This file describes how to lower LLVM code to machine code.
static cl::opt< bool > DisableSelectOptimize("disable-select-optimize", cl::init(true), cl::Hidden, cl::desc("Disable the select-optimization pass from running"))
Disable the select optimization pass.
Target-Independent Code Generator Pass Configuration Options pass.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
static Constant * getConstantVector(MVT VT, ArrayRef< APInt > Bits, const APInt &Undefs, LLVMContext &C)
Class for arbitrary precision integers.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
unsigned getSignificantBits() const
Get the minimum bit size for this signed APInt.
unsigned logBase2() const
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
int64_t getSExtValue() const
Get sign extended value.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
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...
const Function * getParent() const
Return the enclosing method, or null if none.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI void insertDbgRecordBefore(DbgRecord *DR, InstListType::iterator Here)
Insert a DbgRecord into a block at the position given by Here.
InstListType::const_iterator const_iterator
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
LLVM_ABI InstListType::const_iterator getFirstNonPHIOrDbg(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic,...
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
LLVM_ABI SymbolTableList< BasicBlock >::iterator eraseFromParent()
Unlink 'this' from the containing function and delete it.
LLVM_ABI void insertDbgRecordAfter(DbgRecord *DR, Instruction *I)
Insert a DbgRecord into a block at the position given by I.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI void setBlockFreq(const BasicBlock *BB, BlockFrequency Freq)
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
Conditional or Unconditional Branch instruction.
LLVM_ABI void swapSuccessors()
Swap the successors of this branch instruction.
bool isConditional() const
BasicBlock * getSuccessor(unsigned i) const
bool isUnconditional() const
Analysis providing branch probability information.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
Predicate getPredicate() const
Return the predicate for this instruction.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
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.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
The legacy pass manager's analysis pass to compute loop information.
Represents a single loop in the control flow graph.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static MVT getIntegerVT(unsigned BitWidth)
LLVM_ABI void replacePhiUsesWith(MachineBasicBlock *Old, MachineBasicBlock *New)
Update all phi nodes in this basic block to refer to basic block New instead of basic block Old.
This class implements a map that also provides access to all stored values in a deterministic order.
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
iterator find(const KeyT &Key)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
op_range incoming_values()
Value * getIncomingValueForBlock(const BasicBlock *BB) const
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
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...
bool isLoadExtLegal(unsigned ExtType, EVT ValVT, EVT MemVT) const
Return true if the specified load with extension is legal on this target.
const DenseMap< unsigned int, unsigned int > & getBypassSlowDivWidths() const
Returns map of slow types for division or remainder with corresponding fast types.
virtual bool isCheapToSpeculateCtlz(Type *Ty) const
Return true if it is cheap to speculate a call to intrinsic ctlz.
virtual bool useSoftFloat() const
virtual int64_t getPreferredLargeGEPBaseOffset(int64_t MinOffset, int64_t MaxOffset) const
Return the prefered common base offset.
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
virtual bool shouldAlignPointerArgs(CallInst *, unsigned &, Align &) const
Return true if the pointer arguments to CI should be aligned by aligning the object whose address is ...
virtual Type * shouldConvertSplatType(ShuffleVectorInst *SVI) const
Given a shuffle vector SVI representing a vector splat, return a new scalar type of size equal to SVI...
virtual bool addressingModeSupportsTLS(const GlobalValue &) const
Returns true if the targets addressing mode can target thread local storage (TLS).
virtual bool shouldConvertPhiType(Type *From, Type *To) const
Given a set in interconnected phis of type 'From' that are loaded/stored or bitcast to type 'To',...
virtual bool isFAbsFree(EVT VT) const
Return true if an fabs operation is free to the point where it is never worthwhile to replace it with...
virtual bool preferZeroCompareBranch() const
Return true if the heuristic to prefer icmp eq zero should be used in code gen prepare.
virtual bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AddrSpace, Instruction *I=nullptr) const
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
virtual bool optimizeExtendOrTruncateConversion(Instruction *I, Loop *L, const TargetTransformInfo &TTI) const
Try to optimize extending or truncating conversion instructions (like zext, trunc,...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
std::vector< AsmOperandInfo > AsmOperandInfoVector
virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL, const TargetRegisterInfo *TRI, const CallBase &Call) const
Split up the constraint string from the inline assembly value into the specific constraints and their...
virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op, SelectionDAG *DAG=nullptr) const
Determines the constraint code and constraint type to use for the specific AsmOperandInfo,...
virtual bool mayBeEmittedAsTailCall(const CallInst *) const
Return true if the target may be able emit the call instruction as a tail call.
virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const
Returns true if a cast between SrcAS and DestAS is a noop.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
unsigned EnableFastISel
EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...
Target-Independent Code Generator Pass Configuration Options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
virtual bool addrSinkUsingGEPs() const
Sink addresses into blocks using GEP instructions rather than pointer casts and arithmetic.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
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.