44#include "llvm/Config/llvm-config.h"
65#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 sinkinig 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;
316 std::unique_ptr<BlockFrequencyInfo>
BFI;
317 std::unique_ptr<BranchProbabilityInfo> BPI;
332 SetOfInstrs InsertedInsts;
336 InstrToOrigTy PromotedInsts;
339 SetOfInstrs RemovedInsts;
358 ValueToSExts ValToSExtendedUses;
368 std::unique_ptr<DominatorTree> DT;
374 bool IsHugeFunc =
false;
382 void releaseMemory() {
384 InsertedInsts.
clear();
385 PromotedInsts.clear();
394 template <
typename F>
395 void resetIteratorIfInvalidatedWhileCalling(
BasicBlock *BB,
F f) {
399 Value *CurValue = &*CurInstIterator;
406 if (IterHandle != CurValue) {
407 CurInstIterator = BB->
begin();
415 DT = std::make_unique<DominatorTree>(
F);
419 void removeAllAssertingVHReferences(
Value *V);
422 bool eliminateMostlyEmptyBlocks(
Function &
F);
425 void eliminateMostlyEmptyBlock(
BasicBlock *BB);
430 bool optimizeInst(
Instruction *
I, ModifyDT &ModifiedDT);
434 bool optimizeInlineAsmInst(
CallInst *CS);
438 bool optimizeLoadExt(
LoadInst *Load);
444 bool optimizeSwitchPhiConstants(
SwitchInst *SI);
446 bool optimizeExtractElementInst(
Instruction *Inst);
447 bool dupRetToEnableTailCallOpts(
BasicBlock *BB, ModifyDT &ModifiedDT);
455 bool tryToPromoteExts(TypePromotionTransaction &TPT,
458 unsigned CreatedInstsCost = 0);
460 bool splitLargeGEPOffsets();
464 bool performAddressTypePromotion(
465 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
466 bool HasPromoted, TypePromotionTransaction &TPT,
468 bool splitBranchCondition(
Function &
F, ModifyDT &ModifiedDT);
474 bool optimizeCmp(
CmpInst *Cmp, ModifyDT &ModifiedDT);
476 bool combineToUSubWithOverflow(
CmpInst *Cmp, ModifyDT &ModifiedDT);
477 bool combineToUAddWithOverflow(
CmpInst *Cmp, ModifyDT &ModifiedDT);
507char CodeGenPrepareLegacyPass::ID = 0;
509bool CodeGenPrepareLegacyPass::runOnFunction(
Function &
F) {
513 CodeGenPrepare CGP(TM);
514 CGP.DL = &
F.getDataLayout();
515 CGP.SubtargetInfo =
TM->getSubtargetImpl(
F);
516 CGP.TLI = CGP.SubtargetInfo->getTargetLowering();
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();
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);
550 bool Changed = CGP.run(
F, AM);
562 DL = &
F.getDataLayout();
563 SubtargetInfo = TM->getSubtargetImpl(
F);
573 BBSectionsProfileReader =
579 bool EverMadeChange =
false;
581 OptSize =
F.hasOptSize();
586 F.setSectionPrefix(
"hot");
591 if (
F.hasFnAttribute(Attribute::Hot) ||
592 PSI->isFunctionHotInCallGraph(&
F, *BFI))
593 F.setSectionPrefix(
"hot");
597 else if (PSI->isFunctionColdInCallGraph(&
F, *BFI) ||
598 F.hasFnAttribute(Attribute::Cold))
599 F.setSectionPrefix(
"unlikely");
601 PSI->isFunctionHotnessUnknown(
F))
602 F.setSectionPrefix(
"unknown");
611 while (BB !=
nullptr) {
625 EverMadeChange |= eliminateAssumptions(
F);
629 EverMadeChange |= eliminateMostlyEmptyBlocks(
F);
631 ModifyDT ModifiedDT = ModifyDT::NotModifyDT;
633 EverMadeChange |= splitBranchCondition(
F, ModifiedDT);
647 LI->analyze(getDT(
F));
649 bool MadeChange =
true;
650 bool FuncIterated =
false;
655 if (FuncIterated && !FreshBBs.
contains(&BB))
658 ModifyDT ModifiedDTOnIteration = ModifyDT::NotModifyDT;
661 if (ModifiedDTOnIteration == ModifyDT::ModifyBBDT)
664 MadeChange |= Changed;
677 else if (FuncIterated)
682 if (ModifiedDTOnIteration != ModifyDT::NotModifyDT)
687 FuncIterated = IsHugeFunc;
690 MadeChange |= mergeSExts(
F);
691 if (!LargeOffsetGEPMap.
empty())
692 MadeChange |= splitLargeGEPOffsets();
693 MadeChange |= optimizePhiTypes(
F);
696 eliminateFallThrough(
F, DT.get());
700 LI->verify(getDT(
F));
707 EverMadeChange |= MadeChange;
708 SeenChainsForSExt.
clear();
709 ValToSExtendedUses.clear();
710 RemovedInsts.clear();
711 LargeOffsetGEPMap.
clear();
712 LargeOffsetGEPID.
clear();
736 MadeChange |= !WorkList.
empty();
737 while (!WorkList.
empty()) {
750 if (EverMadeChange || MadeChange)
751 MadeChange |= eliminateFallThrough(
F);
753 EverMadeChange |= MadeChange;
760 if (
auto *SP = dyn_cast<GCStatepointInst>(&
I))
762 for (
auto &
I : Statepoints)
763 EverMadeChange |= simplifyOffsetableRelocate(*
I);
768 EverMadeChange |= placeDbgValues(
F);
769 EverMadeChange |= placePseudoProbes(
F);
776 return EverMadeChange;
779bool CodeGenPrepare::eliminateAssumptions(
Function &
F) {
780 bool MadeChange =
false;
782 CurInstIterator = BB.begin();
783 while (CurInstIterator != BB.end()) {
785 if (
auto *Assume = dyn_cast<AssumeInst>(
I)) {
787 Value *Operand = Assume->getOperand(0);
788 Assume->eraseFromParent();
790 resetIteratorIfInvalidatedWhileCalling(&BB, [&]() {
801void CodeGenPrepare::removeAllAssertingVHReferences(
Value *V) {
802 LargeOffsetGEPMap.
erase(V);
803 NewGEPBases.
erase(V);
805 auto GEP = dyn_cast<GetElementPtrInst>(V);
811 auto VecI = LargeOffsetGEPMap.
find(
GEP->getPointerOperand());
812 if (VecI == LargeOffsetGEPMap.
end())
815 auto &GEPVector = VecI->second;
818 if (GEPVector.empty())
819 LargeOffsetGEPMap.
erase(VecI);
828 NewBFI.verifyMatch(*BFI);
835 bool Changed =
false;
845 auto *BB = cast_or_null<BasicBlock>(
Block);
853 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
861 if (Term && !
Term->isConditional()) {
873 FreshBBs.
insert(SinglePred);
881 for (
const auto &Pred : Preds)
882 if (
auto *BB = cast_or_null<BasicBlock>(Pred))
898 if (BBI != BB->
begin()) {
900 while (isa<DbgInfoIntrinsic>(BBI)) {
901 if (BBI == BB->
begin())
905 if (!isa<DbgInfoIntrinsic>(BBI) && !isa<PHINode>(BBI))
914 if (!canMergeBlocks(BB, DestBB))
924bool CodeGenPrepare::eliminateMostlyEmptyBlocks(
Function &
F) {
927 while (!LoopList.empty()) {
928 Loop *
L = LoopList.pop_back_val();
931 Preheaders.
insert(Preheader);
934 bool MadeChange =
false;
950 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
952 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.
count(BB)))
955 eliminateMostlyEmptyBlock(BB);
961bool CodeGenPrepare::isMergingEmptyBlockProfitable(
BasicBlock *BB,
977 if (isa<CallBrInst>(Pred->getTerminator()) &&
1009 if (!isa<PHINode>(DestBB->
begin()))
1017 if (DestBBPred == BB)
1021 return DestPN.getIncomingValueForBlock(BB) ==
1022 DestPN.getIncomingValueForBlock(DestBBPred);
1024 SameIncomingValueBBs.
insert(DestBBPred);
1030 if (SameIncomingValueBBs.
count(Pred))
1036 for (
auto *SameValueBB : SameIncomingValueBBs)
1037 if (SameValueBB->getUniquePredecessor() == Pred &&
1038 DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
1039 BBFreq +=
BFI->getBlockFreq(SameValueBB);
1042 return !Limit || PredFreq <= *Limit;
1048bool CodeGenPrepare::canMergeBlocks(
const BasicBlock *BB,
1056 if (UI->
getParent() != DestBB || !isa<PHINode>(UI))
1062 if (
const PHINode *UPN = dyn_cast<PHINode>(UI))
1063 for (
unsigned I = 0, E = UPN->getNumIncomingValues();
I != E; ++
I) {
1065 if (
Insn &&
Insn->getParent() == BB &&
1066 Insn->getParent() != UPN->getIncomingBlock(
I))
1076 const PHINode *DestBBPN = dyn_cast<PHINode>(DestBB->
begin());
1082 if (
const PHINode *BBPN = dyn_cast<PHINode>(BB->
begin())) {
1084 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1085 BBPreds.
insert(BBPN->getIncomingBlock(i));
1093 if (BBPreds.
count(Pred)) {
1095 const Value *V1 = PN.getIncomingValueForBlock(Pred);
1096 const Value *
V2 = PN.getIncomingValueForBlock(BB);
1099 if (
const PHINode *V2PN = dyn_cast<PHINode>(V2))
1100 if (V2PN->getParent() == BB)
1101 V2 = V2PN->getIncomingValueForBlock(Pred);
1117 auto *OldI = dyn_cast<Instruction>(Old);
1131void CodeGenPrepare::eliminateMostlyEmptyBlock(
BasicBlock *BB) {
1141 if (SinglePred != DestBB) {
1142 assert(SinglePred == BB &&
1143 "Single predecessor not the same as predecessor");
1152 FreshBBs.
insert(SinglePred);
1153 FreshBBs.
erase(DestBB);
1163 Value *InVal = PN.removeIncomingValue(BB,
false);
1167 PHINode *InValPhi = dyn_cast<PHINode>(InVal);
1168 if (InValPhi && InValPhi->
getParent() == BB) {
1177 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1178 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1181 PN.addIncoming(InVal, Pred);
1205 for (
auto *ThisRelocate : AllRelocateCalls) {
1206 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1207 ThisRelocate->getDerivedPtrIndex());
1208 RelocateIdxMap.
insert(std::make_pair(K, ThisRelocate));
1210 for (
auto &Item : RelocateIdxMap) {
1211 std::pair<unsigned, unsigned> Key = Item.first;
1212 if (Key.first == Key.second)
1217 auto BaseKey = std::make_pair(Key.first, Key.first);
1220 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1221 if (MaybeBase == RelocateIdxMap.
end())
1226 RelocateInstMap[MaybeBase->second].push_back(
I);
1234 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1236 auto *
Op = dyn_cast<ConstantInt>(
GEP->getOperand(i));
1237 if (!
Op ||
Op->getZExtValue() > 20)
1241 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1251 bool MadeChange =
false;
1258 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1259 &*R != RelocatedBase; ++R)
1260 if (
auto *RI = dyn_cast<GCRelocateInst>(R))
1270 "Not relocating a derived object of the original base object");
1271 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1276 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1285 auto *Derived = dyn_cast<GetElementPtrInst>(ToReplace->getDerivedPtr());
1286 if (!Derived || Derived->getPointerOperand() !=
Base)
1295 "Should always have one since it's not a terminator");
1323 Value *ActualRelocatedBase = RelocatedBase;
1324 if (RelocatedBase->
getType() !=
Base->getType()) {
1325 ActualRelocatedBase =
1328 Value *Replacement =
1329 Builder.
CreateGEP(Derived->getSourceElementType(), ActualRelocatedBase,
1335 Value *ActualReplacement = Replacement;
1336 if (Replacement->
getType() != ToReplace->getType()) {
1341 ToReplace->eraseFromParent();
1366 bool MadeChange =
false;
1368 for (
auto *U :
I.users())
1375 if (AllRelocateCalls.
size() < 2)
1382 if (RelocateInstMap.
empty())
1385 for (
auto &Item : RelocateInstMap)
1399 bool MadeChange =
false;
1402 Use &TheUse = UI.getUse();
1409 UserBB = PN->getIncomingBlock(TheUse);
1417 if (
User->isEHPad())
1427 if (UserBB == DefBB)
1431 CastInst *&InsertedCast = InsertedCasts[UserBB];
1433 if (!InsertedCast) {
1436 InsertedCast = cast<CastInst>(CI->
clone());
1441 TheUse = InsertedCast;
1465 if (
auto *ASC = dyn_cast<AddrSpaceCastInst>(CI)) {
1467 ASC->getDestAddressSpace()))
1507 match(IVInc, m_ExtractValue<0>(m_Intrinsic<Intrinsic::uadd_with_overflow>(
1511 match(IVInc, m_ExtractValue<0>(m_Intrinsic<Intrinsic::usub_with_overflow>(
1522static std::optional<std::pair<Instruction *, Constant *>>
1525 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1526 return std::nullopt;
1529 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1530 return std::nullopt;
1534 return std::make_pair(IVInc, Step);
1535 return std::nullopt;
1539 auto *
I = dyn_cast<Instruction>(V);
1546 if (
auto *PN = dyn_cast<PHINode>(
LHS))
1548 return IVInc->first ==
I;
1552bool CodeGenPrepare::replaceMathCmpWithIntrinsic(
BinaryOperator *BO,
1560 assert(L &&
"L should not be null after isIVIncrement()");
1562 if (LI->getLoopFor(
Cmp->getParent()) != L)
1568 auto &DT = getDT(*BO->
getParent()->getParent());
1577 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1600 if (BO->
getOpcode() == Instruction::Add &&
1601 IID == Intrinsic::usub_with_overflow) {
1602 assert(isa<Constant>(Arg1) &&
"Unexpected input for usubo");
1611 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1616 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1619 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1620 if (BO->
getOpcode() != Instruction::Xor) {
1621 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1625 "Patterns with XOr should use the BO only in the compare");
1626 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1628 Cmp->eraseFromParent();
1638 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1641 if (isa<Constant>(
A))
1646 B = ConstantInt::get(
B->getType(), 1);
1654 for (
User *U :
A->users()) {
1656 Add = cast<BinaryOperator>(U);
1665bool CodeGenPrepare::combineToUAddWithOverflow(
CmpInst *Cmp,
1666 ModifyDT &ModifiedDT) {
1667 bool EdgeCase =
false;
1674 A =
Add->getOperand(0);
1675 B =
Add->getOperand(1);
1681 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1687 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1690 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1691 Intrinsic::uadd_with_overflow))
1695 ModifiedDT = ModifyDT::ModifyInstDT;
1699bool CodeGenPrepare::combineToUSubWithOverflow(
CmpInst *Cmp,
1700 ModifyDT &ModifiedDT) {
1703 if (isa<Constant>(
A) && isa<Constant>(
B))
1714 B = ConstantInt::get(
B->getType(), 1);
1728 Value *CmpVariableOperand = isa<Constant>(
A) ?
B :
A;
1730 for (
User *U : CmpVariableOperand->
users()) {
1733 Sub = cast<BinaryOperator>(U);
1738 const APInt *CmpC, *AddC;
1741 Sub = cast<BinaryOperator>(U);
1754 Cmp, Intrinsic::usub_with_overflow))
1758 ModifiedDT = ModifyDT::ModifyInstDT;
1779 bool MadeChange =
false;
1782 Use &TheUse = UI.getUse();
1789 if (isa<PHINode>(
User))
1797 if (UserBB == DefBB)
1801 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1807 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1814 TheUse = InsertedCmp;
1820 if (Cmp->use_empty()) {
1821 Cmp->eraseFromParent();
1858 for (
User *U : Cmp->users()) {
1859 if (isa<BranchInst>(U))
1861 if (isa<SelectInst>(U) && cast<SelectInst>(U)->getCondition() == Cmp)
1880 if (CmpBB != FalseBB)
1883 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
1897 for (
User *U : Cmp->users()) {
1898 if (
auto *BI = dyn_cast<BranchInst>(U)) {
1903 if (
auto *SI = dyn_cast<SelectInst>(U)) {
1906 SI->swapProfMetadata();
1918 Value *Op0 = Cmp->getOperand(0);
1919 Value *Op1 = Cmp->getOperand(1);
1921 isa<Constant>(Op1) || Op0 == Op1)
1928 unsigned NumInspected = 0;
1931 if (++NumInspected > 128)
1939 if (GoodToSwap > 0) {
1940 Cmp->swapOperands();
1948 FCmpInst *FCmp = dyn_cast<FCmpInst>(Cmp);
1960 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
1963 auto [ClassVal, ClassTest] =
1969 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
1974 Cmp->replaceAllUsesWith(IsFPClass);
1983 Value *Incr, *RemAmt;
1989 auto *PN = dyn_cast<PHINode>(Incr);
1995 if (PN->getNumIncomingValues() != 2)
2000 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2004 if (!L->contains(Rem))
2008 if (!L->isLoopInvariant(RemAmt))
2089 NewRem->
addIncoming(Start, L->getLoopPreheader());
2094 FreshBBs.
insert(L->getLoopLatch());
2102bool CodeGenPrepare::optimizeURem(
Instruction *Rem) {
2108bool CodeGenPrepare::optimizeCmp(
CmpInst *Cmp, ModifyDT &ModifiedDT) {
2112 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2115 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2136 SetOfInstrs &InsertedInsts) {
2139 assert(!InsertedInsts.count(AndI) &&
2140 "Attempting to optimize already optimized and instruction");
2141 (void)InsertedInsts;
2150 if (!isa<ConstantInt>(AndI->
getOperand(0)) &&
2155 for (
auto *U : AndI->
users()) {
2159 if (!isa<ICmpInst>(
User))
2163 if (!CmpC || !CmpC->
isZero())
2178 Use &TheUse = UI.getUse();
2196 TheUse = InsertedAnd;
2212 if (!isa<TruncInst>(
User)) {
2213 if (
User->getOpcode() != Instruction::And ||
2219 if ((Cimm & (Cimm + 1)).getBoolValue())
2232 auto *TruncI = cast<TruncInst>(
User);
2233 bool MadeChange =
false;
2236 TruncE = TruncI->user_end();
2237 TruncUI != TruncE;) {
2239 Use &TruncTheUse = TruncUI.getUse();
2240 Instruction *TruncUser = cast<Instruction>(*TruncUI);
2259 if (isa<PHINode>(TruncUser))
2264 if (UserBB == TruncUserBB)
2268 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2270 if (!InsertedShift && !InsertedTrunc) {
2274 if (ShiftI->
getOpcode() == Instruction::AShr)
2276 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2279 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2287 TruncInsertPt.setHeadBit(
true);
2288 assert(TruncInsertPt != TruncUserBB->
end());
2292 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2293 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2297 TruncTheUse = InsertedTrunc;
2330 bool MadeChange =
false;
2333 Use &TheUse = UI.getUse();
2339 if (isa<PHINode>(
User))
2347 if (UserBB == DefBB) {
2362 if (isa<TruncInst>(
User) &&
2375 if (!InsertedShift) {
2379 if (ShiftI->
getOpcode() == Instruction::AShr)
2381 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2384 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2392 TheUse = InsertedShift;
2441 if (Ty->
isVectorTy() || SizeInBits >
DL->getLargestLegalIntTypeSizeInBits())
2453 FreshBBs.
insert(CallBlock);
2460 SplitPt.setHeadBit(
true);
2463 FreshBBs.
insert(EndBlock);
2468 L->addBasicBlockToLoop(CallBlock, LI);
2469 L->addBasicBlockToLoop(EndBlock, LI);
2500 ModifiedDT = ModifyDT::ModifyBBDT;
2504bool CodeGenPrepare::optimizeCallInst(
CallInst *CI, ModifyDT &ModifiedDT) {
2513 CurInstIterator = BB->
begin();
2520 if (optimizeInlineAsmInst(CI))
2529 for (
auto &Arg : CI->
args()) {
2534 if (!Arg->getType()->isPointerTy())
2537 cast<PointerType>(Arg->getType())->getAddressSpace()),
2544 if ((AI = dyn_cast<AllocaInst>(Val)) && AI->
getAlign() < PrefAlign &&
2563 if (!MIDestAlign || DestAlign > *MIDestAlign)
2564 MI->setDestAlignment(DestAlign);
2566 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2568 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2569 MTI->setSourceAlignment(SrcAlign);
2577 if (CI->
hasFnAttr(Attribute::Cold) && !OptSize &&
2579 for (
auto &Arg : CI->
args()) {
2580 if (!Arg->getType()->isPointerTy())
2582 unsigned AS = Arg->getType()->getPointerAddressSpace();
2583 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2589 switch (
II->getIntrinsicID()) {
2592 case Intrinsic::assume:
2594 case Intrinsic::allow_runtime_check:
2595 case Intrinsic::allow_ubsan_check:
2596 case Intrinsic::experimental_widenable_condition: {
2600 if (
II->use_empty()) {
2601 II->eraseFromParent();
2605 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2610 case Intrinsic::objectsize:
2612 case Intrinsic::is_constant:
2614 case Intrinsic::aarch64_stlxr:
2615 case Intrinsic::aarch64_stxr: {
2624 InsertedInsts.insert(ExtVal);
2628 case Intrinsic::launder_invariant_group:
2629 case Intrinsic::strip_invariant_group: {
2630 Value *ArgVal =
II->getArgOperand(0);
2631 auto it = LargeOffsetGEPMap.
find(
II);
2632 if (it != LargeOffsetGEPMap.
end()) {
2636 auto GEPs = std::move(it->second);
2637 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2642 II->eraseFromParent();
2645 case Intrinsic::cttz:
2646 case Intrinsic::ctlz:
2650 case Intrinsic::fshl:
2651 case Intrinsic::fshr:
2652 return optimizeFunnelShift(
II);
2653 case Intrinsic::dbg_assign:
2654 case Intrinsic::dbg_value:
2655 return fixupDbgValue(
II);
2656 case Intrinsic::masked_gather:
2657 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2658 case Intrinsic::masked_scatter:
2659 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2665 while (!PtrOps.
empty()) {
2668 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2683 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2696 if (
const auto *
II = dyn_cast<IntrinsicInst>(CI))
2697 switch (
II->getIntrinsicID()) {
2698 case Intrinsic::memset:
2699 case Intrinsic::memcpy:
2700 case Intrinsic::memmove:
2708 if (Callee && TLInfo && TLInfo->
getLibFunc(*Callee, LF))
2710 case LibFunc_strcpy:
2711 case LibFunc_strncpy:
2712 case LibFunc_strcat:
2713 case LibFunc_strncat:
2754bool CodeGenPrepare::dupRetToEnableTailCallOpts(
BasicBlock *BB,
2755 ModifyDT &ModifiedDT) {
2763 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2770 BCI = dyn_cast<BitCastInst>(V);
2774 EVI = dyn_cast<ExtractValueInst>(V);
2781 PN = dyn_cast<PHINode>(V);
2787 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
2788 const BitCastInst *BC = dyn_cast<BitCastInst>(Inst);
2793 return II->getIntrinsicID() == Intrinsic::lifetime_end;
2801 while (isa<DbgInfoIntrinsic>(BI) || BI == BCI || BI == EVI ||
2802 isa<PseudoProbeInst>(BI) || isLifetimeEndOrBitCastFor(BI))
2815 CallInst *CI = dyn_cast<CallInst>(IncomingVal);
2834 CI = dyn_cast_or_null<CallInst>(
2848 if (!VisitedBBs.
insert(Pred).second)
2850 if (
Instruction *
I = Pred->rbegin()->getPrevNonDebugInstruction(
true)) {
2856 if (!V || isa<UndefValue>(V) ||
2866 bool Changed =
false;
2867 for (
auto const &TailCallBB : TailCallBBs) {
2870 BranchInst *BI = dyn_cast<BranchInst>(TailCallBB->getTerminator());
2877 BFI->getBlockFreq(BB) >=
BFI->getBlockFreq(TailCallBB));
2878 BFI->setBlockFreq(BB,
2879 (
BFI->getBlockFreq(BB) -
BFI->getBlockFreq(TailCallBB)));
2880 ModifiedDT = ModifyDT::ModifyBBDT;
2903 Value *OriginalValue =
nullptr;
2904 bool InBounds =
true;
2908 BaseRegField = 0x01,
2910 BaseOffsField = 0x04,
2911 ScaledRegField = 0x08,
2913 MultipleFields = 0xff
2926 return MultipleFields;
2927 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
2928 return MultipleFields;
2931 return MultipleFields;
2934 if (InBounds != other.InBounds)
2935 return MultipleFields;
2938 unsigned Result = NoField;
2941 if (BaseGV != other.BaseGV)
2943 if (BaseOffs != other.BaseOffs)
2946 Result |= ScaledRegField;
2953 return MultipleFields;
2955 return static_cast<FieldName
>(
Result);
2976 case ScaledRegField:
2979 return ConstantInt::get(IntPtrTy, BaseOffs);
2983 void SetCombinedField(FieldName
Field,
Value *V,
2989 case ExtAddrMode::BaseRegField:
2992 case ExtAddrMode::BaseGVField:
2999 case ExtAddrMode::ScaledRegField:
3010 case ExtAddrMode::BaseOffsField:
3029#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3031 bool NeedPlus =
false;
3037 BaseGV->printAsOperand(
OS,
false);
3042 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3047 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3052 OS << (NeedPlus ?
" + " :
"") <<
Scale <<
"*";
3075class TypePromotionTransaction {
3079 class TypePromotionAction {
3087 TypePromotionAction(
Instruction *Inst) : Inst(Inst) {}
3089 virtual ~TypePromotionAction() =
default;
3096 virtual void undo() = 0;
3101 virtual void commit() {
3107 class InsertionHandler {
3116 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3119 bool HasPrevInstruction;
3124 HasPrevInstruction = (Inst != &*(Inst->
getParent()->begin()));
3132 if (HasPrevInstruction) {
3133 Point.PrevInst = &*std::prev(Inst->
getIterator());
3141 if (HasPrevInstruction) {
3153 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3158 class InstructionMoveBefore :
public TypePromotionAction {
3160 InsertionHandler Position;
3165 : TypePromotionAction(Inst), Position(Inst) {
3172 void undo()
override {
3174 Position.insert(Inst);
3179 class OperandSetter :
public TypePromotionAction {
3189 : TypePromotionAction(Inst),
Idx(
Idx) {
3191 <<
"for:" << *Inst <<
"\n"
3192 <<
"with:" << *NewVal <<
"\n");
3198 void undo()
override {
3200 <<
"for: " << *Inst <<
"\n"
3201 <<
"with: " << *Origin <<
"\n");
3208 class OperandsHider :
public TypePromotionAction {
3214 OperandsHider(
Instruction *Inst) : TypePromotionAction(Inst) {
3217 OriginalValues.
reserve(NumOpnds);
3218 for (
unsigned It = 0; It < NumOpnds; ++It) {
3230 void undo()
override {
3232 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3238 class TruncBuilder :
public TypePromotionAction {
3245 TruncBuilder(
Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3247 Builder.SetCurrentDebugLocation(
DebugLoc());
3248 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3253 Value *getBuiltValue() {
return Val; }
3256 void undo()
override {
3258 if (
Instruction *IVal = dyn_cast<Instruction>(Val))
3259 IVal->eraseFromParent();
3264 class SExtBuilder :
public TypePromotionAction {
3272 : TypePromotionAction(InsertPt) {
3274 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3279 Value *getBuiltValue() {
return Val; }
3282 void undo()
override {
3284 if (
Instruction *IVal = dyn_cast<Instruction>(Val))
3285 IVal->eraseFromParent();
3290 class ZExtBuilder :
public TypePromotionAction {
3298 : TypePromotionAction(InsertPt) {
3300 Builder.SetCurrentDebugLocation(
DebugLoc());
3301 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3306 Value *getBuiltValue() {
return Val; }
3309 void undo()
override {
3311 if (
Instruction *IVal = dyn_cast<Instruction>(Val))
3312 IVal->eraseFromParent();
3317 class TypeMutator :
public TypePromotionAction {
3324 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3325 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3331 void undo()
override {
3332 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3339 class UsesReplacer :
public TypePromotionAction {
3341 struct InstructionAndIdx {
3349 : Inst(Inst),
Idx(
Idx) {}
3368 : TypePromotionAction(Inst),
New(
New) {
3369 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3374 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3385 void undo()
override {
3387 for (InstructionAndIdx &
Use : OriginalUses)
3388 Use.Inst->setOperand(
Use.Idx, Inst);
3393 for (
auto *DVI : DbgValues)
3394 DVI->replaceVariableLocationOp(New, Inst);
3398 DVR->replaceVariableLocationOp(New, Inst);
3403 class InstructionRemover :
public TypePromotionAction {
3405 InsertionHandler Inserter;
3409 OperandsHider Hider;
3412 UsesReplacer *Replacer =
nullptr;
3415 SetOfInstrs &RemovedInsts;
3422 InstructionRemover(
Instruction *Inst, SetOfInstrs &RemovedInsts,
3423 Value *New =
nullptr)
3424 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3425 RemovedInsts(RemovedInsts) {
3427 Replacer =
new UsesReplacer(Inst, New);
3428 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3429 RemovedInsts.insert(Inst);
3436 ~InstructionRemover()
override {
delete Replacer; }
3438 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3439 InstructionRemover(
const InstructionRemover &other) =
delete;
3443 void undo()
override {
3444 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3445 Inserter.insert(Inst);
3449 RemovedInsts.erase(Inst);
3457 using ConstRestorationPt =
const TypePromotionAction *;
3459 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3460 : RemovedInsts(RemovedInsts) {}
3467 void rollback(ConstRestorationPt Point);
3470 ConstRestorationPt getRestorationPoint()
const;
3502 SetOfInstrs &RemovedInsts;
3507void TypePromotionTransaction::setOperand(
Instruction *Inst,
unsigned Idx,
3509 Actions.
push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3510 Inst,
Idx, NewVal));
3513void TypePromotionTransaction::eraseInstruction(
Instruction *Inst,
3516 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3517 Inst, RemovedInsts, NewVal));
3520void TypePromotionTransaction::replaceAllUsesWith(
Instruction *Inst,
3523 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3526void TypePromotionTransaction::mutateType(
Instruction *Inst,
Type *NewTy) {
3528 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3532 std::unique_ptr<TruncBuilder>
Ptr(
new TruncBuilder(Opnd, Ty));
3534 Actions.push_back(std::move(
Ptr));
3540 std::unique_ptr<SExtBuilder>
Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3542 Actions.push_back(std::move(
Ptr));
3548 std::unique_ptr<ZExtBuilder>
Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3550 Actions.push_back(std::move(
Ptr));
3554TypePromotionTransaction::ConstRestorationPt
3555TypePromotionTransaction::getRestorationPoint()
const {
3556 return !Actions.empty() ? Actions.back().get() :
nullptr;
3559bool TypePromotionTransaction::commit() {
3560 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3567void TypePromotionTransaction::rollback(
3568 TypePromotionTransaction::ConstRestorationPt Point) {
3569 while (!Actions.empty() && Point != Actions.back().get()) {
3570 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3580class AddressingModeMatcher {
3599 const SetOfInstrs &InsertedInsts;
3602 InstrToOrigTy &PromotedInsts;
3605 TypePromotionTransaction &TPT;
3608 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3612 bool IgnoreProfitability;
3615 bool OptSize =
false;
3620 AddressingModeMatcher(
3625 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3626 TypePromotionTransaction &TPT,
3629 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3630 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3631 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3632 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3633 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI),
BFI(
BFI) {
3634 IgnoreProfitability =
false;
3651 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3656 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3657 AccessTy, AS, MemoryInst, Result,
3658 InsertedInsts, PromotedInsts, TPT,
3659 LargeOffsetGEP, OptSize, PSI, BFI)
3667 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3669 bool matchOperationAddr(
User *AddrInst,
unsigned Opcode,
unsigned Depth,
3670 bool *MovedAway =
nullptr);
3671 bool isProfitableToFoldIntoAddressingMode(
Instruction *
I,
3674 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3675 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3676 Value *PromotedOperand)
const;
3682class PhiNodeSetIterator {
3683 PhiNodeSet *
const Set;
3684 size_t CurrentIndex = 0;
3689 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3691 PhiNodeSetIterator &operator++();
3707 friend class PhiNodeSetIterator;
3710 using iterator = PhiNodeSetIterator;
3725 size_t FirstValidElement = 0;
3732 if (NodeMap.insert(std::make_pair(
Ptr,
NodeList.size())).second) {
3743 if (NodeMap.erase(
Ptr)) {
3744 SkipRemovedElements(FirstValidElement);
3754 FirstValidElement = 0;
3760 if (FirstValidElement == 0)
3761 SkipRemovedElements(FirstValidElement);
3762 return PhiNodeSetIterator(
this, FirstValidElement);
3766 iterator
end() {
return PhiNodeSetIterator(
this,
NodeList.size()); }
3769 size_t size()
const {
return NodeMap.size(); }
3780 void SkipRemovedElements(
size_t &CurrentIndex) {
3781 while (CurrentIndex <
NodeList.size()) {
3782 auto it = NodeMap.find(
NodeList[CurrentIndex]);
3785 if (it != NodeMap.end() && it->second == CurrentIndex)
3792PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
3793 :
Set(
Set), CurrentIndex(Start) {}
3795PHINode *PhiNodeSetIterator::operator*()
const {
3797 "PhiNodeSet access out of range");
3798 return Set->NodeList[CurrentIndex];
3801PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
3803 "PhiNodeSet access out of range");
3805 Set->SkipRemovedElements(CurrentIndex);
3809bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &RHS)
const {
3810 return CurrentIndex ==
RHS.CurrentIndex;
3813bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &RHS)
const {
3814 return !((*this) ==
RHS);
3820class SimplificationTracker {
3825 PhiNodeSet AllPhiNodes;
3834 auto SV = Storage.
find(V);
3835 if (SV == Storage.
end())
3845 while (!WorkList.
empty()) {
3847 if (!Visited.
insert(
P).second)
3849 if (
auto *PI = dyn_cast<Instruction>(
P))
3851 for (
auto *U : PI->users())
3854 PI->replaceAllUsesWith(V);
3855 if (
auto *
PHI = dyn_cast<PHINode>(PI))
3856 AllPhiNodes.erase(
PHI);
3857 if (
auto *
Select = dyn_cast<SelectInst>(PI))
3859 PI->eraseFromParent();
3869 while (OldReplacement !=
From) {
3871 To = dyn_cast<PHINode>(OldReplacement);
3872 OldReplacement = Get(
From);
3874 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
3876 From->replaceAllUsesWith(To);
3877 AllPhiNodes.erase(
From);
3878 From->eraseFromParent();
3881 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
3883 void insertNewPhi(
PHINode *PN) { AllPhiNodes.insert(PN); }
3887 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
3889 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
3891 void destroyNewNodes(
Type *CommonType) {
3894 for (
auto *
I : AllPhiNodes) {
3895 I->replaceAllUsesWith(Dummy);
3896 I->eraseFromParent();
3898 AllPhiNodes.clear();
3899 for (
auto *
I : AllSelectNodes) {
3900 I->replaceAllUsesWith(Dummy);
3901 I->eraseFromParent();
3903 AllSelectNodes.clear();
3908class AddressingModeCombiner {
3910 typedef std::pair<PHINode *, PHINode *> PHIPair;
3917 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
3920 bool AllAddrModesTrivial =
true;
3923 Type *CommonType =
nullptr;
3932 Value *CommonValue =
nullptr;
3936 : SQ(_SQ), Original(OriginalValue) {}
3938 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
3950 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
3953 if (AddrModes.
empty()) {
3961 ExtAddrMode::FieldName ThisDifferentField =
3962 AddrModes[0].compare(NewAddrMode);
3963 if (DifferentField == ExtAddrMode::NoField)
3964 DifferentField = ThisDifferentField;
3965 else if (DifferentField != ThisDifferentField)
3966 DifferentField = ExtAddrMode::MultipleFields;
3969 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
3972 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
3977 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
3982 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
3983 !NewAddrMode.HasBaseReg);
4000 bool combineAddrModes() {
4002 if (AddrModes.
size() == 0)
4006 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4011 if (AllAddrModesTrivial)
4014 if (!addrModeCombiningAllowed())
4020 FoldAddrToValueMapping
Map;
4021 if (!initializeMap(Map))
4024 CommonValue = findCommon(Map);
4026 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4027 return CommonValue !=
nullptr;
4033 void eraseCommonValueIfDead() {
4034 if (CommonValue && CommonValue->
getNumUses() == 0)
4035 if (
Instruction *CommonInst = dyn_cast<Instruction>(CommonValue))
4036 CommonInst->eraseFromParent();
4044 bool initializeMap(FoldAddrToValueMapping &Map) {
4049 for (
auto &AM : AddrModes) {
4050 Value *DV = AM.GetFieldAsValue(DifferentField, IntPtrTy);
4053 if (CommonType && CommonType !=
Type)
4056 Map[AM.OriginalValue] = DV;
4061 assert(CommonType &&
"At least one non-null value must be!");
4062 for (
auto *V : NullValue)
4090 Value *findCommon(FoldAddrToValueMapping &Map) {
4098 SimplificationTracker
ST(SQ);
4103 InsertPlaceholders(Map, TraverseOrder, ST);
4106 FillPlaceholders(Map, TraverseOrder, ST);
4109 ST.destroyNewNodes(CommonType);
4114 unsigned PhiNotMatchedCount = 0;
4116 ST.destroyNewNodes(CommonType);
4120 auto *
Result =
ST.Get(
Map.find(Original)->second);
4122 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4123 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4132 PhiNodeSet &PhiNodesToMatch) {
4139 while (!WorkList.
empty()) {
4141 if (!Visited.
insert(Item).second)
4148 for (
auto *
B : Item.first->blocks()) {
4149 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4150 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4151 if (FirstValue == SecondValue)
4154 PHINode *FirstPhi = dyn_cast<PHINode>(FirstValue);
4155 PHINode *SecondPhi = dyn_cast<PHINode>(SecondValue);
4161 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4166 if (Matcher.
count({FirstPhi, SecondPhi}))
4171 if (MatchedPHIs.
insert(FirstPhi).second)
4172 Matcher.
insert({FirstPhi, SecondPhi});
4174 WorkList.
push_back({FirstPhi, SecondPhi});
4183 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4184 unsigned &PhiNotMatchedCount) {
4190 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4191 while (PhiNodesToMatch.size()) {
4195 WillNotMatch.
clear();
4199 bool IsMatched =
false;
4200 for (
auto &
P :
PHI->getParent()->phis()) {
4202 if (PhiNodesToMatch.count(&
P))
4204 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4209 for (
auto M : Matched)
4215 for (
auto MV : Matched)
4216 ST.ReplacePhi(MV.first, MV.second);
4221 if (!AllowNewPhiNodes)
4224 PhiNotMatchedCount += WillNotMatch.
size();
4225 for (
auto *
P : WillNotMatch)
4226 PhiNodesToMatch.erase(
P);
4231 void FillPlaceholders(FoldAddrToValueMapping &Map,
4233 SimplificationTracker &ST) {
4234 while (!TraverseOrder.
empty()) {
4236 assert(
Map.contains(Current) &&
"No node to fill!!!");
4241 auto *CurrentSelect = cast<SelectInst>(Current);
4242 auto *TrueValue = CurrentSelect->getTrueValue();
4243 assert(
Map.contains(TrueValue) &&
"No True Value!");
4244 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4245 auto *FalseValue = CurrentSelect->getFalseValue();
4246 assert(
Map.contains(FalseValue) &&
"No False Value!");
4247 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4250 auto *
PHI = cast<PHINode>(V);
4253 Value *PV = cast<PHINode>(Current)->getIncomingValueForBlock(
B);
4254 assert(
Map.contains(PV) &&
"No predecessor Value!");
4255 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4258 Map[Current] =
ST.Simplify(V);
4267 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4269 SimplificationTracker &ST) {
4271 assert((isa<PHINode>(Original) || isa<SelectInst>(Original)) &&
4272 "Address must be a Phi or Select node");
4275 while (!Worklist.
empty()) {
4278 if (
Map.contains(Current))
4284 if (
SelectInst *CurrentSelect = dyn_cast<SelectInst>(Current)) {
4289 CurrentSelect->getName(),
4290 CurrentSelect->getIterator(), CurrentSelect);
4294 Worklist.
push_back(CurrentSelect->getTrueValue());
4295 Worklist.
push_back(CurrentSelect->getFalseValue());
4298 PHINode *CurrentPhi = cast<PHINode>(Current);
4303 ST.insertNewPhi(
PHI);
4309 bool addrModeCombiningAllowed() {
4312 switch (DifferentField) {
4315 case ExtAddrMode::BaseRegField:
4317 case ExtAddrMode::BaseGVField:
4319 case ExtAddrMode::BaseOffsField:
4321 case ExtAddrMode::ScaledRegField:
4331bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4336 return matchAddr(ScaleReg,
Depth);
4351 TestAddrMode.
Scale += Scale;
4366 Value *AddLHS =
nullptr;
4367 if (isa<Instruction>(ScaleReg) &&
4370 TestAddrMode.InBounds =
false;
4377 AddrModeInsts.
push_back(cast<Instruction>(ScaleReg));
4387 auto GetConstantStep =
4388 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4389 auto *PN = dyn_cast<PHINode>(V);
4391 return std::nullopt;
4394 return std::nullopt;
4401 if (
auto *OIVInc = dyn_cast<OverflowingBinaryOperator>(IVInc->first))
4402 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4403 return std::nullopt;
4404 if (
auto *ConstantStep = dyn_cast<ConstantInt>(IVInc->second))
4405 return std::make_pair(IVInc->first, ConstantStep->getValue());
4406 return std::nullopt;
4421 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4428 APInt Step = IVStep->second;
4430 if (
Offset.isSignedIntN(64)) {
4431 TestAddrMode.InBounds =
false;
4433 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4438 getDTFn().
dominates(IVInc, MemoryInst)) {
4439 AddrModeInsts.
push_back(cast<Instruction>(IVInc));
4458 switch (
I->getOpcode()) {
4459 case Instruction::BitCast:
4460 case Instruction::AddrSpaceCast:
4462 if (
I->getType() ==
I->getOperand(0)->getType())
4464 return I->getType()->isIntOrPtrTy();
4465 case Instruction::PtrToInt:
4468 case Instruction::IntToPtr:
4471 case Instruction::Add:
4473 case Instruction::Mul:
4474 case Instruction::Shl:
4476 return isa<ConstantInt>(
I->getOperand(1));
4477 case Instruction::GetElementPtr:
4490 Instruction *PromotedInst = dyn_cast<Instruction>(Val);
4505class TypePromotionHelper {
4508 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4510 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4511 InstrToOrigTy::iterator It = PromotedInsts.find(ExtOpnd);
4512 if (It != PromotedInsts.end()) {
4515 if (It->second.getInt() == ExtTy)
4521 ExtTy = BothExtension;
4523 PromotedInsts[ExtOpnd] = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4530 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4532 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4533 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4534 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4535 return It->second.getPointer();
4550 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4551 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4555 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4556 return !(isa<SelectInst>(Inst) && OpIdx == 0);
4568 static Value *promoteOperandForTruncAndAnyExt(
4570 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4584 TypePromotionTransaction &TPT,
4585 InstrToOrigTy &PromotedInsts,
4586 unsigned &CreatedInstsCost,
4592 static Value *signExtendOperandForOther(
4594 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4597 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4598 Exts, Truncs, TLI,
true);
4602 static Value *zeroExtendOperandForOther(
4604 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4607 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4608 Exts, Truncs, TLI,
false);
4614 InstrToOrigTy &PromotedInsts,
4615 unsigned &CreatedInstsCost,
4631 const InstrToOrigTy &PromotedInsts);
4636bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4637 Type *ConsideredExtType,
4638 const InstrToOrigTy &PromotedInsts,
4647 if (isa<ZExtInst>(Inst))
4651 if (IsSExt && isa<SExtInst>(Inst))
4656 if (
const auto *BinOp = dyn_cast<BinaryOperator>(Inst))
4657 if (isa<OverflowingBinaryOperator>(BinOp) &&
4658 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4659 (IsSExt && BinOp->hasNoSignedWrap())))
4663 if ((Inst->
getOpcode() == Instruction::And ||
4668 if (Inst->
getOpcode() == Instruction::Xor) {
4670 if (
const auto *Cst = dyn_cast<ConstantInt>(Inst->
getOperand(1)))
4671 if (!Cst->getValue().isAllOnes())
4680 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4689 const auto *ExtInst = cast<const Instruction>(*Inst->
user_begin());
4690 if (ExtInst->hasOneUse()) {
4691 const auto *AndInst = dyn_cast<const Instruction>(*ExtInst->user_begin());
4692 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4693 const auto *Cst = dyn_cast<ConstantInt>(AndInst->getOperand(1));
4703 if (!isa<TruncInst>(Inst))
4717 Instruction *Opnd = dyn_cast<Instruction>(OpndVal);
4725 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4728 else if ((IsSExt && isa<SExtInst>(Opnd)) || (!IsSExt && isa<ZExtInst>(Opnd)))
4738TypePromotionHelper::Action TypePromotionHelper::getAction(
4739 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4741 assert((isa<SExtInst>(Ext) || isa<ZExtInst>(Ext)) &&
4742 "Unexpected instruction type");
4743 Instruction *ExtOpnd = dyn_cast<Instruction>(
Ext->getOperand(0));
4745 bool IsSExt = isa<SExtInst>(Ext);
4749 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4755 if (isa<TruncInst>(ExtOpnd) && InsertedInsts.count(ExtOpnd))
4760 if (isa<SExtInst>(ExtOpnd) || isa<TruncInst>(ExtOpnd) ||
4761 isa<ZExtInst>(ExtOpnd))
4762 return promoteOperandForTruncAndAnyExt;
4768 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4771Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4773 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4779 Value *ExtVal = SExt;
4780 bool HasMergedNonFreeExt =
false;
4781 if (isa<ZExtInst>(SExtOpnd)) {
4784 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
4788 TPT.eraseInstruction(SExt);
4793 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
4795 CreatedInstsCost = 0;
4799 TPT.eraseInstruction(SExtOpnd);
4802 Instruction *ExtInst = dyn_cast<Instruction>(ExtVal);
4807 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
4815 TPT.eraseInstruction(ExtInst, NextVal);
4819Value *TypePromotionHelper::promoteOperandForOther(
4821 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4828 CreatedInstsCost = 0;
4834 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
4835 if (
Instruction *ITrunc = dyn_cast<Instruction>(Trunc)) {
4837 ITrunc->moveAfter(ExtOpnd);
4842 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
4845 TPT.setOperand(Ext, 0, ExtOpnd);
4855 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
4857 TPT.mutateType(ExtOpnd,
Ext->getType());
4859 TPT.replaceAllUsesWith(Ext, ExtOpnd);
4862 for (
int OpIdx = 0, EndOpIdx = ExtOpnd->
getNumOperands(); OpIdx != EndOpIdx;
4866 !shouldExtOperand(ExtOpnd, OpIdx)) {
4872 if (
const ConstantInt *Cst = dyn_cast<ConstantInt>(Opnd)) {
4874 unsigned BitWidth =
Ext->getType()->getIntegerBitWidth();
4877 TPT.setOperand(ExtOpnd, OpIdx, ConstantInt::get(
Ext->getType(), CstVal));
4881 if (isa<UndefValue>(Opnd)) {
4888 Value *ValForExtOpnd = IsSExt
4889 ? TPT.createSExt(ExtOpnd, Opnd,
Ext->getType())
4890 : TPT.createZExt(ExtOpnd, Opnd,
Ext->getType());
4891 TPT.setOperand(ExtOpnd, OpIdx, ValForExtOpnd);
4892 Instruction *InstForExtOpnd = dyn_cast<Instruction>(ValForExtOpnd);
4893 if (!InstForExtOpnd)
4899 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
4902 TPT.eraseInstruction(Ext);
4914bool AddressingModeMatcher::isPromotionProfitable(
4915 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
4916 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
4921 if (NewCost > OldCost)
4923 if (NewCost < OldCost)
4942bool AddressingModeMatcher::matchOperationAddr(
User *AddrInst,
unsigned Opcode,
4954 case Instruction::PtrToInt:
4957 case Instruction::IntToPtr: {
4965 case Instruction::BitCast:
4975 case Instruction::AddrSpaceCast: {
4983 case Instruction::Add: {
4987 unsigned OldSize = AddrModeInsts.
size();
4992 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
4993 TPT.getRestorationPoint();
4997 int First = 0, Second = 1;
4999 && !isa<ConstantInt>(AddrInst->
getOperand(Second)))
5008 AddrModeInsts.
resize(OldSize);
5009 TPT.rollback(LastKnownGood);
5019 AddrModeInsts.
resize(OldSize);
5020 TPT.rollback(LastKnownGood);
5026 case Instruction::Mul:
5027 case Instruction::Shl: {
5031 if (!RHS ||
RHS->getBitWidth() > 64)
5033 int64_t Scale = Opcode == Instruction::Shl
5034 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5035 :
RHS->getSExtValue();
5039 case Instruction::GetElementPtr: {
5042 int VariableOperand = -1;
5043 unsigned VariableScale = 0;
5045 int64_t ConstantOffset = 0;
5047 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5051 cast<ConstantInt>(AddrInst->
getOperand(i))->getZExtValue();
5061 dyn_cast<ConstantInt>(AddrInst->
getOperand(i))) {
5069 if (VariableOperand != -1)
5073 VariableOperand = i;
5081 if (VariableOperand == -1) {
5082 AddrMode.BaseOffs += ConstantOffset;
5084 if (!cast<GEPOperator>(AddrInst)->isInBounds())
5088 AddrMode.BaseOffs -= ConstantOffset;
5092 ConstantOffset > 0) {
5098 auto *BaseI = dyn_cast<Instruction>(
Base);
5099 auto *
GEP = cast<GetElementPtrInst>(AddrInst);
5100 if (isa<Argument>(
Base) || isa<GlobalValue>(
Base) ||
5101 (BaseI && !isa<CastInst>(BaseI) &&
5102 !isa<GetElementPtrInst>(BaseI))) {
5106 : &
GEP->getFunction()->getEntryBlock();
5108 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5117 unsigned OldSize = AddrModeInsts.
size();
5120 AddrMode.BaseOffs += ConstantOffset;
5121 if (!cast<GEPOperator>(AddrInst)->isInBounds())
5129 AddrModeInsts.
resize(OldSize);
5137 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5142 AddrModeInsts.
resize(OldSize);