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;
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);
454 bool tryToPromoteExts(TypePromotionTransaction &TPT,
457 unsigned CreatedInstsCost = 0);
459 bool splitLargeGEPOffsets();
463 bool performAddressTypePromotion(
464 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
465 bool HasPromoted, TypePromotionTransaction &TPT,
467 bool splitBranchCondition(
Function &
F, ModifyDT &ModifiedDT);
473 bool optimizeCmp(
CmpInst *Cmp, ModifyDT &ModifiedDT);
475 bool combineToUSubWithOverflow(
CmpInst *Cmp, ModifyDT &ModifiedDT);
476 bool combineToUAddWithOverflow(
CmpInst *Cmp, ModifyDT &ModifiedDT);
477 bool unfoldPowerOf2Test(
CmpInst *Cmp);
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) {
624 EverMadeChange |= eliminateAssumptions(
F);
628 EverMadeChange |= eliminateMostlyEmptyBlocks(
F);
630 ModifyDT ModifiedDT = ModifyDT::NotModifyDT;
632 EverMadeChange |= splitBranchCondition(
F, ModifiedDT);
646 LI->analyze(getDT(
F));
648 bool MadeChange =
true;
649 bool FuncIterated =
false;
654 if (FuncIterated && !FreshBBs.
contains(&BB))
657 ModifyDT ModifiedDTOnIteration = ModifyDT::NotModifyDT;
660 if (ModifiedDTOnIteration == ModifyDT::ModifyBBDT)
663 MadeChange |= Changed;
676 else if (FuncIterated)
681 if (ModifiedDTOnIteration != ModifyDT::NotModifyDT)
686 FuncIterated = IsHugeFunc;
689 MadeChange |= mergeSExts(
F);
690 if (!LargeOffsetGEPMap.
empty())
691 MadeChange |= splitLargeGEPOffsets();
692 MadeChange |= optimizePhiTypes(
F);
695 eliminateFallThrough(
F, DT.get());
699 LI->verify(getDT(
F));
706 EverMadeChange |= MadeChange;
707 SeenChainsForSExt.
clear();
708 ValToSExtendedUses.clear();
709 RemovedInsts.clear();
710 LargeOffsetGEPMap.
clear();
711 LargeOffsetGEPID.
clear();
735 MadeChange |= !WorkList.
empty();
736 while (!WorkList.
empty()) {
749 if (EverMadeChange || MadeChange)
750 MadeChange |= eliminateFallThrough(
F);
752 EverMadeChange |= MadeChange;
759 if (
auto *SP = dyn_cast<GCStatepointInst>(&
I))
761 for (
auto &
I : Statepoints)
762 EverMadeChange |= simplifyOffsetableRelocate(*
I);
767 EverMadeChange |= placeDbgValues(
F);
768 EverMadeChange |= placePseudoProbes(
F);
775 return EverMadeChange;
778bool CodeGenPrepare::eliminateAssumptions(
Function &
F) {
779 bool MadeChange =
false;
781 CurInstIterator = BB.begin();
782 while (CurInstIterator != BB.end()) {
784 if (
auto *Assume = dyn_cast<AssumeInst>(
I)) {
787 Assume->eraseFromParent();
789 resetIteratorIfInvalidatedWhileCalling(&BB, [&]() {
800void CodeGenPrepare::removeAllAssertingVHReferences(
Value *V) {
801 LargeOffsetGEPMap.
erase(V);
802 NewGEPBases.
erase(V);
804 auto GEP = dyn_cast<GetElementPtrInst>(V);
810 auto VecI = LargeOffsetGEPMap.
find(
GEP->getPointerOperand());
811 if (VecI == LargeOffsetGEPMap.
end())
814 auto &GEPVector = VecI->second;
817 if (GEPVector.empty())
818 LargeOffsetGEPMap.
erase(VecI);
827 NewBFI.verifyMatch(*BFI);
834 bool Changed =
false;
843 auto *BB = cast_or_null<BasicBlock>(
Block);
851 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
859 if (Term && !
Term->isConditional()) {
871 FreshBBs.
insert(SinglePred);
879 for (
const auto &Pred : Preds)
880 if (
auto *BB = cast_or_null<BasicBlock>(Pred))
896 if (BBI != BB->
begin()) {
898 if (!isa<PHINode>(BBI))
907 if (!canMergeBlocks(BB, DestBB))
917bool CodeGenPrepare::eliminateMostlyEmptyBlocks(
Function &
F) {
920 while (!LoopList.empty()) {
921 Loop *
L = LoopList.pop_back_val();
924 Preheaders.
insert(Preheader);
927 bool MadeChange =
false;
943 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
945 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.
count(BB)))
948 eliminateMostlyEmptyBlock(BB);
954bool CodeGenPrepare::isMergingEmptyBlockProfitable(
BasicBlock *BB,
970 if (isa<CallBrInst>(Pred->getTerminator()) &&
1002 if (!isa<PHINode>(DestBB->
begin()))
1010 if (DestBBPred == BB)
1014 return DestPN.getIncomingValueForBlock(BB) ==
1015 DestPN.getIncomingValueForBlock(DestBBPred);
1017 SameIncomingValueBBs.
insert(DestBBPred);
1023 if (SameIncomingValueBBs.
count(Pred))
1029 for (
auto *SameValueBB : SameIncomingValueBBs)
1030 if (SameValueBB->getUniquePredecessor() == Pred &&
1031 DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
1032 BBFreq +=
BFI->getBlockFreq(SameValueBB);
1035 return !Limit || PredFreq <= *Limit;
1041bool CodeGenPrepare::canMergeBlocks(
const BasicBlock *BB,
1049 if (UI->
getParent() != DestBB || !isa<PHINode>(UI))
1055 if (
const PHINode *UPN = dyn_cast<PHINode>(UI))
1056 for (
unsigned I = 0, E = UPN->getNumIncomingValues();
I != E; ++
I) {
1057 Instruction *Insn = dyn_cast<Instruction>(UPN->getIncomingValue(
I));
1059 Insn->
getParent() != UPN->getIncomingBlock(
I))
1069 const PHINode *DestBBPN = dyn_cast<PHINode>(DestBB->
begin());
1075 if (
const PHINode *BBPN = dyn_cast<PHINode>(BB->
begin())) {
1077 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1078 BBPreds.
insert(BBPN->getIncomingBlock(i));
1086 if (BBPreds.
count(Pred)) {
1088 const Value *V1 = PN.getIncomingValueForBlock(Pred);
1089 const Value *V2 = PN.getIncomingValueForBlock(BB);
1092 if (
const PHINode *V2PN = dyn_cast<PHINode>(V2))
1093 if (V2PN->getParent() == BB)
1094 V2 = V2PN->getIncomingValueForBlock(Pred);
1110 auto *OldI = dyn_cast<Instruction>(Old);
1124void CodeGenPrepare::eliminateMostlyEmptyBlock(
BasicBlock *BB) {
1134 if (SinglePred != DestBB) {
1135 assert(SinglePred == BB &&
1136 "Single predecessor not the same as predecessor");
1145 FreshBBs.
insert(SinglePred);
1146 FreshBBs.
erase(DestBB);
1156 Value *InVal = PN.removeIncomingValue(BB,
false);
1160 PHINode *InValPhi = dyn_cast<PHINode>(InVal);
1161 if (InValPhi && InValPhi->
getParent() == BB) {
1170 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1171 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1174 PN.addIncoming(InVal, Pred);
1204 for (
auto *ThisRelocate : AllRelocateCalls) {
1205 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1206 ThisRelocate->getDerivedPtrIndex());
1207 RelocateIdxMap.
insert(std::make_pair(K, ThisRelocate));
1209 for (
auto &Item : RelocateIdxMap) {
1210 std::pair<unsigned, unsigned> Key = Item.first;
1211 if (Key.first == Key.second)
1216 auto BaseKey = std::make_pair(Key.first, Key.first);
1219 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1220 if (MaybeBase == RelocateIdxMap.
end())
1225 RelocateInstMap[MaybeBase->second].push_back(
I);
1233 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1235 auto *
Op = dyn_cast<ConstantInt>(
GEP->getOperand(i));
1236 if (!
Op ||
Op->getZExtValue() > 20)
1240 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1250 bool MadeChange =
false;
1257 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1258 &*R != RelocatedBase; ++R)
1259 if (
auto *RI = dyn_cast<GCRelocateInst>(R))
1262 RelocatedBase->
moveBefore(RI->getIterator());
1269 "Not relocating a derived object of the original base object");
1270 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1275 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1284 auto *Derived = dyn_cast<GetElementPtrInst>(ToReplace->getDerivedPtr());
1285 if (!Derived || Derived->getPointerOperand() !=
Base)
1294 "Should always have one since it's not a terminator");
1322 Value *ActualRelocatedBase = RelocatedBase;
1323 if (RelocatedBase->
getType() !=
Base->getType()) {
1324 ActualRelocatedBase =
1327 Value *Replacement =
1328 Builder.
CreateGEP(Derived->getSourceElementType(), ActualRelocatedBase,
1334 Value *ActualReplacement = Replacement;
1335 if (Replacement->
getType() != ToReplace->getType()) {
1340 ToReplace->eraseFromParent();
1365 bool MadeChange =
false;
1367 for (
auto *U :
I.users())
1374 if (AllRelocateCalls.
size() < 2)
1381 if (RelocateInstMap.
empty())
1384 for (
auto &Item : RelocateInstMap)
1398 bool MadeChange =
false;
1401 Use &TheUse = UI.getUse();
1408 UserBB = PN->getIncomingBlock(TheUse);
1416 if (
User->isEHPad())
1426 if (UserBB == DefBB)
1430 CastInst *&InsertedCast = InsertedCasts[UserBB];
1432 if (!InsertedCast) {
1435 InsertedCast = cast<CastInst>(CI->
clone());
1440 TheUse = InsertedCast;
1464 if (
auto *ASC = dyn_cast<AddrSpaceCastInst>(CI)) {
1466 ASC->getDestAddressSpace()))
1506 match(IVInc, m_ExtractValue<0>(m_Intrinsic<Intrinsic::uadd_with_overflow>(
1510 match(IVInc, m_ExtractValue<0>(m_Intrinsic<Intrinsic::usub_with_overflow>(
1521static std::optional<std::pair<Instruction *, Constant *>>
1524 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1525 return std::nullopt;
1528 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1529 return std::nullopt;
1533 return std::make_pair(IVInc, Step);
1534 return std::nullopt;
1538 auto *
I = dyn_cast<Instruction>(V);
1545 if (
auto *PN = dyn_cast<PHINode>(
LHS))
1547 return IVInc->first ==
I;
1551bool CodeGenPrepare::replaceMathCmpWithIntrinsic(
BinaryOperator *BO,
1559 assert(L &&
"L should not be null after isIVIncrement()");
1561 if (LI->getLoopFor(
Cmp->getParent()) != L)
1567 auto &DT = getDT(*BO->
getParent()->getParent());
1576 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1599 if (BO->
getOpcode() == Instruction::Add &&
1600 IID == Intrinsic::usub_with_overflow) {
1601 assert(isa<Constant>(Arg1) &&
"Unexpected input for usubo");
1610 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1615 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1618 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1619 if (BO->
getOpcode() != Instruction::Xor) {
1620 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1624 "Patterns with XOr should use the BO only in the compare");
1625 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1627 Cmp->eraseFromParent();
1637 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1640 if (isa<Constant>(
A))
1645 B = ConstantInt::get(
B->getType(), 1);
1653 for (
User *U :
A->users()) {
1655 Add = cast<BinaryOperator>(U);
1664bool CodeGenPrepare::combineToUAddWithOverflow(
CmpInst *Cmp,
1665 ModifyDT &ModifiedDT) {
1666 bool EdgeCase =
false;
1673 A =
Add->getOperand(0);
1674 B =
Add->getOperand(1);
1680 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1686 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1689 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1690 Intrinsic::uadd_with_overflow))
1694 ModifiedDT = ModifyDT::ModifyInstDT;
1698bool CodeGenPrepare::combineToUSubWithOverflow(
CmpInst *Cmp,
1699 ModifyDT &ModifiedDT) {
1702 if (isa<Constant>(
A) && isa<Constant>(
B))
1713 B = ConstantInt::get(
B->getType(), 1);
1727 Value *CmpVariableOperand = isa<Constant>(
A) ?
B :
A;
1729 for (
User *U : CmpVariableOperand->
users()) {
1732 Sub = cast<BinaryOperator>(U);
1737 const APInt *CmpC, *AddC;
1740 Sub = cast<BinaryOperator>(U);
1749 Sub->hasNUsesOrMore(1)))
1752 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1753 Cmp, Intrinsic::usub_with_overflow))
1757 ModifiedDT = ModifyDT::ModifyInstDT;
1764bool CodeGenPrepare::unfoldPowerOf2Test(
CmpInst *Cmp) {
1778 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1784 Type *OpTy =
X->getType();
1793 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1802 if (IsPowerOf2OrZeroTest ||
1822 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1825 Cmp->replaceAllUsesWith(NewCmp);
1847 bool MadeChange =
false;
1850 Use &TheUse = UI.getUse();
1857 if (isa<PHINode>(
User))
1865 if (UserBB == DefBB)
1869 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1875 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1882 TheUse = InsertedCmp;
1888 if (Cmp->use_empty()) {
1889 Cmp->eraseFromParent();
1926 for (
User *U : Cmp->users()) {
1927 if (isa<BranchInst>(U))
1929 if (isa<SelectInst>(U) && cast<SelectInst>(U)->getCondition() == Cmp)
1948 if (CmpBB != FalseBB)
1951 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
1965 for (
User *U : Cmp->users()) {
1966 if (
auto *BI = dyn_cast<BranchInst>(U)) {
1971 if (
auto *SI = dyn_cast<SelectInst>(U)) {
1974 SI->swapProfMetadata();
1986 Value *Op0 = Cmp->getOperand(0);
1987 Value *Op1 = Cmp->getOperand(1);
1989 isa<Constant>(Op1) || Op0 == Op1)
1996 unsigned NumInspected = 0;
1999 if (++NumInspected > 128)
2007 if (GoodToSwap > 0) {
2008 Cmp->swapOperands();
2016 FCmpInst *FCmp = dyn_cast<FCmpInst>(Cmp);
2028 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
2031 auto [ClassVal, ClassTest] =
2037 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2042 Cmp->replaceAllUsesWith(IsFPClass);
2050 Value *Incr, *RemAmt;
2055 Value *AddInst, *AddOffset;
2057 auto *PN = dyn_cast<PHINode>(Incr);
2058 if (PN !=
nullptr) {
2060 AddOffset =
nullptr;
2068 PN = dyn_cast<PHINode>(V0);
2069 if (PN !=
nullptr) {
2072 PN = dyn_cast<PHINode>(V1);
2082 if (PN->getNumIncomingValues() != 2)
2087 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2091 if (!L->contains(Rem))
2095 if (!L->isLoopInvariant(RemAmt))
2099 if (AddOffset && !L->isLoopInvariant(AddOffset))
2120 AddInstOut = AddInst;
2121 AddOffsetOut = AddOffset;
2140 Value *AddOffset, *RemAmt, *AddInst;
2143 AddOffset, LoopIncrPN))
2168 assert(AddOffset &&
"We found an add but missing values");
2198 NewRem->
addIncoming(Start, L->getLoopPreheader());
2203 FreshBBs.
insert(L->getLoopLatch());
2210 cast<Instruction>(AddInst)->eraseFromParent();
2214bool CodeGenPrepare::optimizeURem(
Instruction *Rem) {
2220bool CodeGenPrepare::optimizeCmp(
CmpInst *Cmp, ModifyDT &ModifiedDT) {
2224 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2227 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2230 if (unfoldPowerOf2Test(Cmp))
2251 SetOfInstrs &InsertedInsts) {
2254 assert(!InsertedInsts.count(AndI) &&
2255 "Attempting to optimize already optimized and instruction");
2256 (void)InsertedInsts;
2265 if (!isa<ConstantInt>(AndI->
getOperand(0)) &&
2270 for (
auto *U : AndI->
users()) {
2274 if (!isa<ICmpInst>(
User))
2278 if (!CmpC || !CmpC->
isZero())
2293 Use &TheUse = UI.getUse();
2311 TheUse = InsertedAnd;
2327 if (!isa<TruncInst>(
User)) {
2328 if (
User->getOpcode() != Instruction::And ||
2334 if ((Cimm & (Cimm + 1)).getBoolValue())
2347 auto *TruncI = cast<TruncInst>(
User);
2348 bool MadeChange =
false;
2351 TruncE = TruncI->user_end();
2352 TruncUI != TruncE;) {
2354 Use &TruncTheUse = TruncUI.getUse();
2355 Instruction *TruncUser = cast<Instruction>(*TruncUI);
2374 if (isa<PHINode>(TruncUser))
2379 if (UserBB == TruncUserBB)
2383 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2385 if (!InsertedShift && !InsertedTrunc) {
2389 if (ShiftI->
getOpcode() == Instruction::AShr)
2391 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2394 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2402 TruncInsertPt.setHeadBit(
true);
2403 assert(TruncInsertPt != TruncUserBB->
end());
2407 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2408 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2412 TruncTheUse = InsertedTrunc;
2445 bool MadeChange =
false;
2448 Use &TheUse = UI.getUse();
2454 if (isa<PHINode>(
User))
2462 if (UserBB == DefBB) {
2477 if (isa<TruncInst>(
User) &&
2490 if (!InsertedShift) {
2494 if (ShiftI->
getOpcode() == Instruction::AShr)
2496 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2499 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2507 TheUse = InsertedShift;
2567 FreshBBs.
insert(CallBlock);
2574 SplitPt.setHeadBit(
true);
2577 FreshBBs.
insert(EndBlock);
2582 L->addBasicBlockToLoop(CallBlock, LI);
2583 L->addBasicBlockToLoop(EndBlock, LI);
2614 ModifiedDT = ModifyDT::ModifyBBDT;
2618bool CodeGenPrepare::optimizeCallInst(
CallInst *CI, ModifyDT &ModifiedDT) {
2627 CurInstIterator = BB->
begin();
2634 if (optimizeInlineAsmInst(CI))
2643 for (
auto &Arg : CI->
args()) {
2648 if (!Arg->getType()->isPointerTy())
2651 cast<PointerType>(Arg->getType())->getAddressSpace()),
2658 if ((AI = dyn_cast<AllocaInst>(Val)) && AI->
getAlign() < PrefAlign &&
2677 if (!MIDestAlign || DestAlign > *MIDestAlign)
2678 MI->setDestAlignment(DestAlign);
2680 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2682 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2683 MTI->setSourceAlignment(SrcAlign);
2693 for (
auto &Arg : CI->
args()) {
2694 if (!Arg->getType()->isPointerTy())
2696 unsigned AS = Arg->getType()->getPointerAddressSpace();
2697 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2703 switch (
II->getIntrinsicID()) {
2706 case Intrinsic::assume:
2708 case Intrinsic::allow_runtime_check:
2709 case Intrinsic::allow_ubsan_check:
2710 case Intrinsic::experimental_widenable_condition: {
2714 if (
II->use_empty()) {
2715 II->eraseFromParent();
2719 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2724 case Intrinsic::objectsize:
2726 case Intrinsic::is_constant:
2728 case Intrinsic::aarch64_stlxr:
2729 case Intrinsic::aarch64_stxr: {
2738 InsertedInsts.insert(ExtVal);
2742 case Intrinsic::launder_invariant_group:
2743 case Intrinsic::strip_invariant_group: {
2744 Value *ArgVal =
II->getArgOperand(0);
2745 auto it = LargeOffsetGEPMap.
find(
II);
2746 if (it != LargeOffsetGEPMap.
end()) {
2750 auto GEPs = std::move(it->second);
2751 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2756 II->eraseFromParent();
2759 case Intrinsic::cttz:
2760 case Intrinsic::ctlz:
2764 case Intrinsic::fshl:
2765 case Intrinsic::fshr:
2766 return optimizeFunnelShift(
II);
2767 case Intrinsic::masked_gather:
2768 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2769 case Intrinsic::masked_scatter:
2770 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2771 case Intrinsic::masked_load:
2773 if (
auto *VT = dyn_cast<FixedVectorType>(
II->getType())) {
2774 if (VT->getNumElements() == 1) {
2775 Value *PtrVal =
II->getArgOperand(0);
2777 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2782 case Intrinsic::masked_store:
2785 dyn_cast<FixedVectorType>(
II->getArgOperand(0)->getType())) {
2786 if (VT->getNumElements() == 1) {
2787 Value *PtrVal =
II->getArgOperand(1);
2789 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2799 while (!PtrOps.
empty()) {
2802 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2818 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2829 if (!
F->getReturnType()->isPointerTy())
2833 for (
auto &BB : *
F) {
2835 if (
auto *V = dyn_cast<GlobalVariable>(RI->getReturnValue())) {
2838 else if (V != UniformValue)
2846 return UniformValue;
2849 if (
Callee->hasExactDefinition()) {
2851 bool MadeChange =
false;
2853 auto *
I = dyn_cast<Instruction>(
U.getUser());
2876 if (
const auto *
II = dyn_cast<IntrinsicInst>(CI))
2877 switch (
II->getIntrinsicID()) {
2878 case Intrinsic::memset:
2879 case Intrinsic::memcpy:
2880 case Intrinsic::memmove:
2888 if (Callee && TLInfo && TLInfo->
getLibFunc(*Callee, LF))
2890 case LibFunc_strcpy:
2891 case LibFunc_strncpy:
2892 case LibFunc_strcat:
2893 case LibFunc_strncat:
2934bool CodeGenPrepare::dupRetToEnableTailCallOpts(
BasicBlock *BB,
2935 ModifyDT &ModifiedDT) {
2943 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2950 BCI = dyn_cast<BitCastInst>(V);
2954 EVI = dyn_cast<ExtractValueInst>(V);
2961 PN = dyn_cast<PHINode>(V);
2967 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
2968 const BitCastInst *BC = dyn_cast<BitCastInst>(Inst);
2973 return II->getIntrinsicID() == Intrinsic::lifetime_end;
2979 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
2980 if (
auto *
II = dyn_cast<IntrinsicInst>(Inst);
2981 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
2989 if (!isa<PHINode>(
II->getOperand(0))) {
3002 while (&*BI == BCI || &*BI == EVI || isa<PseudoProbeInst>(BI) ||
3003 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
3019 CallInst *CI = dyn_cast<CallInst>(IncomingVal);
3039 CI = dyn_cast_or_null<CallInst>(
3055 if (!VisitedBBs.
insert(Pred).second)
3063 if (!V || isa<UndefValue>(V) ||
3074 bool Changed =
false;
3075 for (
auto const &TailCallBB : TailCallBBs) {
3078 BranchInst *BI = dyn_cast<BranchInst>(TailCallBB->getTerminator());
3085 BFI->getBlockFreq(BB) >=
BFI->getBlockFreq(TailCallBB));
3086 BFI->setBlockFreq(BB,
3087 (
BFI->getBlockFreq(BB) -
BFI->getBlockFreq(TailCallBB)));
3088 ModifiedDT = ModifyDT::ModifyBBDT;
3097 for (
auto *CI : CallInsts) {
3098 for (
auto const *FakeUse : FakeUses) {
3099 auto *ClonedInst = FakeUse->clone();
3120 Value *OriginalValue =
nullptr;
3121 bool InBounds =
true;
3125 BaseRegField = 0x01,
3127 BaseOffsField = 0x04,
3128 ScaledRegField = 0x08,
3130 MultipleFields = 0xff
3151 return MultipleFields;
3152 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3153 return MultipleFields;
3156 return MultipleFields;
3159 if (InBounds != other.InBounds)
3160 return MultipleFields;
3163 unsigned Result = NoField;
3166 if (BaseGV != other.BaseGV)
3168 if (BaseOffs != other.BaseOffs)
3171 Result |= ScaledRegField;
3178 return MultipleFields;
3180 return static_cast<FieldName
>(
Result);
3201 case ScaledRegField:
3204 return ConstantInt::get(IntPtrTy, BaseOffs);
3208 void SetCombinedField(FieldName
Field,
Value *V,
3214 case ExtAddrMode::BaseRegField:
3217 case ExtAddrMode::BaseGVField:
3224 case ExtAddrMode::ScaledRegField:
3235 case ExtAddrMode::BaseOffsField:
3254#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3256 bool NeedPlus =
false;
3262 BaseGV->printAsOperand(
OS,
false);
3267 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3272 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3277 OS << (NeedPlus ?
" + " :
"") <<
Scale <<
"*";
3300class TypePromotionTransaction {
3304 class TypePromotionAction {
3312 TypePromotionAction(
Instruction *Inst) : Inst(Inst) {}
3314 virtual ~TypePromotionAction() =
default;
3321 virtual void undo() = 0;
3326 virtual void commit() {
3332 class InsertionHandler {
3341 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3344 bool HasPrevInstruction;
3349 HasPrevInstruction = (Inst != &*(Inst->
getParent()->begin()));
3356 if (HasPrevInstruction) {
3365 if (HasPrevInstruction) {
3377 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3382 class InstructionMoveBefore :
public TypePromotionAction {
3384 InsertionHandler Position;
3389 : TypePromotionAction(Inst), Position(Inst) {
3390 LLVM_DEBUG(
dbgs() <<
"Do: move: " << *Inst <<
"\nbefore: " << *Before
3396 void undo()
override {
3398 Position.insert(Inst);
3403 class OperandSetter :
public TypePromotionAction {
3413 : TypePromotionAction(Inst),
Idx(
Idx) {
3415 <<
"for:" << *Inst <<
"\n"
3416 <<
"with:" << *NewVal <<
"\n");
3422 void undo()
override {
3424 <<
"for: " << *Inst <<
"\n"
3425 <<
"with: " << *Origin <<
"\n");
3432 class OperandsHider :
public TypePromotionAction {
3438 OperandsHider(
Instruction *Inst) : TypePromotionAction(Inst) {
3441 OriginalValues.
reserve(NumOpnds);
3442 for (
unsigned It = 0; It < NumOpnds; ++It) {
3454 void undo()
override {
3456 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3462 class TruncBuilder :
public TypePromotionAction {
3469 TruncBuilder(
Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3471 Builder.SetCurrentDebugLocation(
DebugLoc());
3472 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3477 Value *getBuiltValue() {
return Val; }
3480 void undo()
override {
3482 if (
Instruction *IVal = dyn_cast<Instruction>(Val))
3483 IVal->eraseFromParent();
3488 class SExtBuilder :
public TypePromotionAction {
3496 : TypePromotionAction(InsertPt) {
3498 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3503 Value *getBuiltValue() {
return Val; }
3506 void undo()
override {
3508 if (
Instruction *IVal = dyn_cast<Instruction>(Val))
3509 IVal->eraseFromParent();
3514 class ZExtBuilder :
public TypePromotionAction {
3522 : TypePromotionAction(InsertPt) {
3524 Builder.SetCurrentDebugLocation(
DebugLoc());
3525 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3530 Value *getBuiltValue() {
return Val; }
3533 void undo()
override {
3535 if (
Instruction *IVal = dyn_cast<Instruction>(Val))
3536 IVal->eraseFromParent();
3541 class TypeMutator :
public TypePromotionAction {
3548 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3549 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3555 void undo()
override {
3556 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3563 class UsesReplacer :
public TypePromotionAction {
3565 struct InstructionAndIdx {
3573 : Inst(Inst),
Idx(
Idx) {}
3590 : TypePromotionAction(Inst),
New(
New) {
3591 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3596 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3607 void undo()
override {
3609 for (InstructionAndIdx &
Use : OriginalUses)
3610 Use.Inst->setOperand(
Use.Idx, Inst);
3616 DVR->replaceVariableLocationOp(New, Inst);
3621 class InstructionRemover :
public TypePromotionAction {
3623 InsertionHandler Inserter;
3627 OperandsHider Hider;
3630 UsesReplacer *Replacer =
nullptr;
3633 SetOfInstrs &RemovedInsts;
3640 InstructionRemover(
Instruction *Inst, SetOfInstrs &RemovedInsts,
3641 Value *New =
nullptr)
3642 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3643 RemovedInsts(RemovedInsts) {
3645 Replacer =
new UsesReplacer(Inst, New);
3646 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3647 RemovedInsts.insert(Inst);
3654 ~InstructionRemover()
override {
delete Replacer; }
3656 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3657 InstructionRemover(
const InstructionRemover &other) =
delete;
3661 void undo()
override {
3662 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3663 Inserter.insert(Inst);
3667 RemovedInsts.erase(Inst);
3675 using ConstRestorationPt =
const TypePromotionAction *;
3677 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3678 : RemovedInsts(RemovedInsts) {}
3685 void rollback(ConstRestorationPt Point);
3688 ConstRestorationPt getRestorationPoint()
const;
3720 SetOfInstrs &RemovedInsts;
3725void TypePromotionTransaction::setOperand(
Instruction *Inst,
unsigned Idx,
3727 Actions.
push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3728 Inst,
Idx, NewVal));
3731void TypePromotionTransaction::eraseInstruction(
Instruction *Inst,
3734 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3735 Inst, RemovedInsts, NewVal));
3738void TypePromotionTransaction::replaceAllUsesWith(
Instruction *Inst,
3741 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3744void TypePromotionTransaction::mutateType(
Instruction *Inst,
Type *NewTy) {
3746 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3750 std::unique_ptr<TruncBuilder>
Ptr(
new TruncBuilder(Opnd, Ty));
3752 Actions.push_back(std::move(
Ptr));
3758 std::unique_ptr<SExtBuilder>
Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3760 Actions.push_back(std::move(
Ptr));
3766 std::unique_ptr<ZExtBuilder>
Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3768 Actions.push_back(std::move(
Ptr));
3772TypePromotionTransaction::ConstRestorationPt
3773TypePromotionTransaction::getRestorationPoint()
const {
3774 return !Actions.empty() ? Actions.back().get() :
nullptr;
3777bool TypePromotionTransaction::commit() {
3778 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3785void TypePromotionTransaction::rollback(
3786 TypePromotionTransaction::ConstRestorationPt Point) {
3787 while (!Actions.empty() && Point != Actions.back().get()) {
3788 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3798class AddressingModeMatcher {
3817 const SetOfInstrs &InsertedInsts;
3820 InstrToOrigTy &PromotedInsts;
3823 TypePromotionTransaction &TPT;
3826 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3830 bool IgnoreProfitability;
3833 bool OptSize =
false;
3838 AddressingModeMatcher(
3843 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3844 TypePromotionTransaction &TPT,
3847 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3848 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3849 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3850 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3851 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI),
BFI(
BFI) {
3852 IgnoreProfitability =
false;
3869 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3874 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3875 AccessTy, AS, MemoryInst, Result,
3876 InsertedInsts, PromotedInsts, TPT,
3877 LargeOffsetGEP, OptSize, PSI, BFI)
3885 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3887 bool matchOperationAddr(
User *AddrInst,
unsigned Opcode,
unsigned Depth,
3888 bool *MovedAway =
nullptr);
3889 bool isProfitableToFoldIntoAddressingMode(
Instruction *
I,
3892 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3893 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3894 Value *PromotedOperand)
const;
3900class PhiNodeSetIterator {
3901 PhiNodeSet *
const Set;
3902 size_t CurrentIndex = 0;
3907 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3909 PhiNodeSetIterator &operator++();
3925 friend class PhiNodeSetIterator;
3928 using iterator = PhiNodeSetIterator;
3943 size_t FirstValidElement = 0;
3950 if (NodeMap.insert(std::make_pair(
Ptr,
NodeList.size())).second) {
3961 if (NodeMap.erase(
Ptr)) {
3962 SkipRemovedElements(FirstValidElement);
3972 FirstValidElement = 0;
3978 if (FirstValidElement == 0)
3979 SkipRemovedElements(FirstValidElement);
3980 return PhiNodeSetIterator(
this, FirstValidElement);
3984 iterator
end() {
return PhiNodeSetIterator(
this,
NodeList.size()); }
3987 size_t size()
const {
return NodeMap.size(); }
3998 void SkipRemovedElements(
size_t &CurrentIndex) {
3999 while (CurrentIndex <
NodeList.size()) {
4000 auto it = NodeMap.find(
NodeList[CurrentIndex]);
4003 if (it != NodeMap.end() && it->second == CurrentIndex)
4010PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
4011 :
Set(
Set), CurrentIndex(Start) {}
4013PHINode *PhiNodeSetIterator::operator*()
const {
4015 "PhiNodeSet access out of range");
4016 return Set->NodeList[CurrentIndex];
4019PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
4021 "PhiNodeSet access out of range");
4023 Set->SkipRemovedElements(CurrentIndex);
4027bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &RHS)
const {
4028 return CurrentIndex ==
RHS.CurrentIndex;
4031bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &RHS)
const {
4032 return !((*this) ==
RHS);
4038class SimplificationTracker {
4043 PhiNodeSet AllPhiNodes;
4052 auto SV = Storage.
find(V);
4053 if (SV == Storage.
end())
4063 while (!WorkList.
empty()) {
4065 if (!Visited.
insert(
P).second)
4067 if (
auto *PI = dyn_cast<Instruction>(
P))
4069 for (
auto *U : PI->users())
4072 PI->replaceAllUsesWith(V);
4073 if (
auto *
PHI = dyn_cast<PHINode>(PI))
4074 AllPhiNodes.erase(
PHI);
4075 if (
auto *
Select = dyn_cast<SelectInst>(PI))
4077 PI->eraseFromParent();
4087 while (OldReplacement !=
From) {
4089 To = dyn_cast<PHINode>(OldReplacement);
4090 OldReplacement = Get(
From);
4092 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
4094 From->replaceAllUsesWith(To);
4095 AllPhiNodes.erase(
From);
4096 From->eraseFromParent();
4099 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
4101 void insertNewPhi(
PHINode *PN) { AllPhiNodes.insert(PN); }
4105 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4107 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4109 void destroyNewNodes(
Type *CommonType) {
4112 for (
auto *
I : AllPhiNodes) {
4113 I->replaceAllUsesWith(Dummy);
4114 I->eraseFromParent();
4116 AllPhiNodes.clear();
4117 for (
auto *
I : AllSelectNodes) {
4118 I->replaceAllUsesWith(Dummy);
4119 I->eraseFromParent();
4121 AllSelectNodes.clear();
4126class AddressingModeCombiner {
4128 typedef std::pair<PHINode *, PHINode *> PHIPair;
4135 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4138 bool AllAddrModesTrivial =
true;
4141 Type *CommonType =
nullptr;
4150 Value *CommonValue =
nullptr;
4154 : SQ(_SQ), Original(OriginalValue) {}
4156 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4168 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4171 if (AddrModes.
empty()) {
4179 ExtAddrMode::FieldName ThisDifferentField =
4180 AddrModes[0].compare(NewAddrMode);
4181 if (DifferentField == ExtAddrMode::NoField)
4182 DifferentField = ThisDifferentField;
4183 else if (DifferentField != ThisDifferentField)
4184 DifferentField = ExtAddrMode::MultipleFields;
4187 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4190 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4195 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4200 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4201 !NewAddrMode.HasBaseReg);
4218 bool combineAddrModes() {
4220 if (AddrModes.
size() == 0)
4224 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4229 if (AllAddrModesTrivial)
4232 if (!addrModeCombiningAllowed())
4238 FoldAddrToValueMapping
Map;
4239 if (!initializeMap(Map))
4242 CommonValue = findCommon(Map);
4244 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4245 return CommonValue !=
nullptr;
4251 void eraseCommonValueIfDead() {
4252 if (CommonValue && CommonValue->
use_empty())
4253 if (
Instruction *CommonInst = dyn_cast<Instruction>(CommonValue))
4254 CommonInst->eraseFromParent();
4262 bool initializeMap(FoldAddrToValueMapping &Map) {
4267 for (
auto &AM : AddrModes) {
4268 Value *DV = AM.GetFieldAsValue(DifferentField, IntPtrTy);
4271 if (CommonType && CommonType !=
Type)
4274 Map[AM.OriginalValue] = DV;
4279 assert(CommonType &&
"At least one non-null value must be!");
4280 for (
auto *V : NullValue)
4308 Value *findCommon(FoldAddrToValueMapping &Map) {
4316 SimplificationTracker
ST(SQ);
4321 InsertPlaceholders(Map, TraverseOrder, ST);
4324 FillPlaceholders(Map, TraverseOrder, ST);
4327 ST.destroyNewNodes(CommonType);
4332 unsigned PhiNotMatchedCount = 0;
4334 ST.destroyNewNodes(CommonType);
4338 auto *
Result =
ST.Get(
Map.find(Original)->second);
4340 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4341 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4350 PhiNodeSet &PhiNodesToMatch) {
4357 while (!WorkList.
empty()) {
4359 if (!Visited.
insert(Item).second)
4366 for (
auto *
B : Item.first->blocks()) {
4367 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4368 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4369 if (FirstValue == SecondValue)
4372 PHINode *FirstPhi = dyn_cast<PHINode>(FirstValue);
4373 PHINode *SecondPhi = dyn_cast<PHINode>(SecondValue);
4379 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4384 if (Matcher.
count({FirstPhi, SecondPhi}))
4389 if (MatchedPHIs.
insert(FirstPhi).second)
4390 Matcher.
insert({FirstPhi, SecondPhi});
4392 WorkList.
push_back({FirstPhi, SecondPhi});
4401 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4402 unsigned &PhiNotMatchedCount) {
4408 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4409 while (PhiNodesToMatch.size()) {
4413 WillNotMatch.
clear();
4417 bool IsMatched =
false;
4418 for (
auto &
P :
PHI->getParent()->phis()) {
4420 if (PhiNodesToMatch.count(&
P))
4422 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4432 for (
auto MV : Matched)
4433 ST.ReplacePhi(MV.first, MV.second);
4438 if (!AllowNewPhiNodes)
4441 PhiNotMatchedCount += WillNotMatch.
size();
4442 for (
auto *
P : WillNotMatch)
4443 PhiNodesToMatch.erase(
P);
4448 void FillPlaceholders(FoldAddrToValueMapping &Map,
4450 SimplificationTracker &ST) {
4451 while (!TraverseOrder.
empty()) {
4453 assert(
Map.contains(Current) &&
"No node to fill!!!");
4458 auto *CurrentSelect = cast<SelectInst>(Current);
4459 auto *TrueValue = CurrentSelect->getTrueValue();
4460 assert(
Map.contains(TrueValue) &&
"No True Value!");
4461 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4462 auto *FalseValue = CurrentSelect->getFalseValue();
4463 assert(
Map.contains(FalseValue) &&
"No False Value!");
4464 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4467 auto *
PHI = cast<PHINode>(V);
4470 Value *PV = cast<PHINode>(Current)->getIncomingValueForBlock(
B);
4471 assert(
Map.contains(PV) &&
"No predecessor Value!");
4472 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4475 Map[Current] =
ST.Simplify(V);
4484 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4486 SimplificationTracker &ST) {
4488 assert((isa<PHINode>(Original) || isa<SelectInst>(Original)) &&
4489 "Address must be a Phi or Select node");
4492 while (!Worklist.
empty()) {
4495 if (
Map.contains(Current))
4501 if (
SelectInst *CurrentSelect = dyn_cast<SelectInst>(Current)) {
4506 CurrentSelect->getName(),
4507 CurrentSelect->getIterator(), CurrentSelect);
4511 Worklist.
push_back(CurrentSelect->getTrueValue());
4512 Worklist.
push_back(CurrentSelect->getFalseValue());
4515 PHINode *CurrentPhi = cast<PHINode>(Current);
4520 ST.insertNewPhi(
PHI);
4526 bool addrModeCombiningAllowed() {
4529 switch (DifferentField) {
4532 case ExtAddrMode::BaseRegField:
4534 case ExtAddrMode::BaseGVField:
4536 case ExtAddrMode::BaseOffsField:
4538 case ExtAddrMode::ScaledRegField:
4548bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4553 return matchAddr(ScaleReg,
Depth);
4568 TestAddrMode.
Scale += Scale;
4583 Value *AddLHS =
nullptr;
4584 if (isa<Instruction>(ScaleReg) &&
4587 TestAddrMode.InBounds =
false;
4594 AddrModeInsts.
push_back(cast<Instruction>(ScaleReg));
4604 auto GetConstantStep =
4605 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4606 auto *PN = dyn_cast<PHINode>(V);
4608 return std::nullopt;
4611 return std::nullopt;
4618 if (
auto *OIVInc = dyn_cast<OverflowingBinaryOperator>(IVInc->first))
4619 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4620 return std::nullopt;
4621 if (
auto *ConstantStep = dyn_cast<ConstantInt>(IVInc->second))
4622 return std::make_pair(IVInc->first, ConstantStep->getValue());
4623 return std::nullopt;
4638 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4645 APInt Step = IVStep->second;
4647 if (
Offset.isSignedIntN(64)) {
4648 TestAddrMode.InBounds =
false;
4650 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4655 getDTFn().
dominates(IVInc, MemoryInst)) {
4656 AddrModeInsts.
push_back(cast<Instruction>(IVInc));
4675 switch (
I->getOpcode()) {
4676 case Instruction::BitCast:
4677 case Instruction::AddrSpaceCast:
4679 if (
I->getType() ==
I->getOperand(0)->getType())
4681 return I->getType()->isIntOrPtrTy();
4682 case Instruction::PtrToInt:
4685 case Instruction::IntToPtr:
4688 case Instruction::Add:
4690 case Instruction::Mul:
4691 case Instruction::Shl:
4693 return isa<ConstantInt>(
I->getOperand(1));
4694 case Instruction::GetElementPtr:
4707 Instruction *PromotedInst = dyn_cast<Instruction>(Val);
4722class TypePromotionHelper {
4725 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4727 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4728 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4732 if (It->second.getInt() == ExtTy)
4738 ExtTy = BothExtension;
4740 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4747 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4749 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4750 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4751 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4752 return It->second.getPointer();
4767 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4768 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4773 return !(isa<SelectInst>(Inst) &&
OpIdx == 0);
4785 static Value *promoteOperandForTruncAndAnyExt(
4787 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4801 TypePromotionTransaction &TPT,
4802 InstrToOrigTy &PromotedInsts,
4803 unsigned &CreatedInstsCost,
4809 static Value *signExtendOperandForOther(
4811 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4814 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4815 Exts, Truncs, TLI,
true);
4819 static Value *zeroExtendOperandForOther(
4821 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4824 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4825 Exts, Truncs, TLI,
false);
4831 InstrToOrigTy &PromotedInsts,
4832 unsigned &CreatedInstsCost,
4846 static Action getAction(
Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4848 const InstrToOrigTy &PromotedInsts);
4853bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4854 Type *ConsideredExtType,
4855 const InstrToOrigTy &PromotedInsts,
4864 if (isa<ZExtInst>(Inst))
4868 if (IsSExt && isa<SExtInst>(Inst))
4873 if (
const auto *BinOp = dyn_cast<BinaryOperator>(Inst))
4874 if (isa<OverflowingBinaryOperator>(BinOp) &&
4875 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4876 (IsSExt && BinOp->hasNoSignedWrap())))
4880 if ((Inst->
getOpcode() == Instruction::And ||
4885 if (Inst->
getOpcode() == Instruction::Xor) {
4887 if (
const auto *Cst = dyn_cast<ConstantInt>(Inst->
getOperand(1)))
4888 if (!Cst->getValue().isAllOnes())
4897 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4906 const auto *ExtInst = cast<const Instruction>(*Inst->
user_begin());
4907 if (ExtInst->hasOneUse()) {
4908 const auto *AndInst = dyn_cast<const Instruction>(*ExtInst->user_begin());
4909 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4910 const auto *Cst = dyn_cast<ConstantInt>(AndInst->getOperand(1));
4920 if (!isa<TruncInst>(Inst))
4934 Instruction *Opnd = dyn_cast<Instruction>(OpndVal);
4942 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4945 else if ((IsSExt && isa<SExtInst>(Opnd)) || (!IsSExt && isa<ZExtInst>(Opnd)))
4955TypePromotionHelper::Action TypePromotionHelper::getAction(
4956 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4958 assert((isa<SExtInst>(Ext) || isa<ZExtInst>(Ext)) &&
4959 "Unexpected instruction type");
4960 Instruction *ExtOpnd = dyn_cast<Instruction>(
Ext->getOperand(0));
4962 bool IsSExt = isa<SExtInst>(Ext);
4966 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4972 if (isa<TruncInst>(ExtOpnd) && InsertedInsts.count(ExtOpnd))
4977 if (isa<SExtInst>(ExtOpnd) || isa<TruncInst>(ExtOpnd) ||
4978 isa<ZExtInst>(ExtOpnd))
4979 return promoteOperandForTruncAndAnyExt;
4985 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4988Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4990 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4996 Value *ExtVal = SExt;
4997 bool HasMergedNonFreeExt =
false;
4998 if (isa<ZExtInst>(SExtOpnd)) {
5001 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
5005 TPT.eraseInstruction(SExt);
5010 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
5012 CreatedInstsCost = 0;
5016 TPT.eraseInstruction(SExtOpnd);
5019 Instruction *ExtInst = dyn_cast<Instruction>(ExtVal);
5024 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
5032 TPT.eraseInstruction(ExtInst, NextVal);
5036Value *TypePromotionHelper::promoteOperandForOther(
5038 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5045 CreatedInstsCost = 0;
5051 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
5052 if (
Instruction *ITrunc = dyn_cast<Instruction>(Trunc)) {
5054 ITrunc->moveAfter(ExtOpnd);
5059 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
5062 TPT.setOperand(Ext, 0, ExtOpnd);
5072 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
5074 TPT.mutateType(ExtOpnd,
Ext->getType());
5076 TPT.replaceAllUsesWith(Ext, ExtOpnd);
5083 !shouldExtOperand(ExtOpnd,
OpIdx)) {
5089 if (
const ConstantInt *Cst = dyn_cast<ConstantInt>(Opnd)) {
5091 unsigned BitWidth =
Ext->getType()->getIntegerBitWidth();
5094 TPT.setOperand(ExtOpnd,
OpIdx, ConstantInt::get(
Ext->getType(), CstVal));
5098 if (isa<UndefValue>(Opnd)) {
5105 Value *ValForExtOpnd = IsSExt
5106 ? TPT.createSExt(ExtOpnd, Opnd,
Ext->getType())
5107 : TPT.createZExt(ExtOpnd, Opnd,
Ext->getType());
5108 TPT.setOperand(ExtOpnd,
OpIdx, ValForExtOpnd);
5109 Instruction *InstForExtOpnd = dyn_cast<Instruction>(ValForExtOpnd);
5110 if (!InstForExtOpnd)
5116 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5119 TPT.eraseInstruction(Ext);
5131bool AddressingModeMatcher::isPromotionProfitable(
5132 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5133 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5138 if (NewCost > OldCost)
5140 if (NewCost < OldCost)
5159bool AddressingModeMatcher::matchOperationAddr(
User *AddrInst,
unsigned Opcode,
5171 case Instruction::PtrToInt:
5174 case Instruction::IntToPtr: {
5182 case Instruction::BitCast:
5192 case Instruction::AddrSpaceCast: {
5200 case Instruction::Add: {
5204 unsigned OldSize = AddrModeInsts.
size();
5209 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5210 TPT.getRestorationPoint();
5214 int First = 0, Second = 1;
5216 && !isa<ConstantInt>(AddrInst->
getOperand(Second)))
5225 AddrModeInsts.
resize(OldSize);
5226 TPT.rollback(LastKnownGood);
5236 AddrModeInsts.
resize(OldSize);
5237 TPT.rollback(LastKnownGood);
5243 case Instruction::Mul:
5244 case Instruction::Shl: {
5248 if (!RHS ||
RHS->getBitWidth() > 64)
5250 int64_t Scale = Opcode == Instruction::Shl
5251 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5252 :
RHS->getSExtValue();
5256 case Instruction::GetElementPtr: {
5259 int VariableOperand = -1;
5260 unsigned VariableScale = 0;
5262 int64_t ConstantOffset = 0;
5264 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5268 cast<ConstantInt>(AddrInst->
getOperand(i))->getZExtValue();
5278 dyn_cast<ConstantInt>(AddrInst->
getOperand(i))) {
5286 if (VariableOperand != -1)
5290 VariableOperand = i;
5298 if (VariableOperand == -1) {
5299 AddrMode.BaseOffs += ConstantOffset;
5301 if (!cast<GEPOperator>(AddrInst)->isInBounds())
5305 AddrMode.BaseOffs -= ConstantOffset;
5309 ConstantOffset > 0) {
5315 auto *BaseI = dyn_cast<Instruction>(
Base);
5316 auto *
GEP = cast<GetElementPtrInst>(AddrInst);
5317 if (isa<Argument>(
Base) || isa<GlobalValue>(
Base) ||
5318 (BaseI && !isa<CastInst>(BaseI) &&
5319 !isa<GetElementPtrInst>(BaseI))) {
5323 : &
GEP->getFunction()->getEntryBlock();
5325 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5334 unsigned OldSize = AddrModeInsts.
size();
5337 AddrMode.BaseOffs += ConstantOffset;
5338 if (!cast<GEPOperator>(AddrInst)->isInBounds())
5346 AddrModeInsts.
resize(OldSize);
5354 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5359 AddrModeInsts.
resize(OldSize);
5364 AddrMode.BaseOffs += ConstantOffset;
5365 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5366 VariableScale,
Depth)) {
5369 AddrModeInsts.
resize(OldSize);
5376 case Instruction::SExt:
5377 case Instruction::ZExt: {
5384 TypePromotionHelper::Action TPH =
5385 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5389 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5390 TPT.getRestorationPoint();
5391 unsigned CreatedInstsCost = 0;
5393 Value *PromotedOperand =
5394 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5409 assert(PromotedOperand &&
5410 "TypePromotionHelper should have filtered out those cases");
5413 unsigned OldSize = AddrModeInsts.
size();
5415 if (!matchAddr(PromotedOperand,
Depth) ||
5420 !isPromotionProfitable(CreatedInstsCost,
5421 ExtCost + (AddrModeInsts.
size() - OldSize),
5424 AddrModeInsts.
resize(OldSize);
5425 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5426 TPT.rollback(LastKnownGood);
5431 AddrMode.replaceWith(Ext, PromotedOperand);
5434 case Instruction::Call:
5436 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5452bool AddressingModeMatcher::matchAddr(
Value *
Addr,
unsigned Depth) {
5455 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5456 TPT.getRestorationPoint();
5481 unsigned OldSize = AddrModeInsts.
size();
5484 bool MovedAway =
false;
5485 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5493 if (
I->hasOneUse() ||
5494 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5501 AddrModeInsts.
resize(OldSize);
5502 TPT.rollback(LastKnownGood);
5505 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5507 TPT.rollback(LastKnownGood);
5508 }
else if (isa<ConstantPointerNull>(
Addr)) {
5534 TPT.rollback(LastKnownGood);
5553 if (OpInfo.CallOperandVal == OpVal &&
5555 !OpInfo.isIndirect))
5571 if (!ConsideredInsts.
insert(
I).second)
5579 for (
Use &U :
I->uses()) {
5585 Instruction *UserI = cast<Instruction>(U.getUser());
5586 if (
LoadInst *LI = dyn_cast<LoadInst>(UserI)) {
5587 MemoryUses.push_back({&U, LI->getType()});
5591 if (
StoreInst *SI = dyn_cast<StoreInst>(UserI)) {
5594 MemoryUses.push_back({&U, SI->getValueOperand()->
getType()});
5601 MemoryUses.push_back({&U, RMW->getValOperand()->
getType()});
5608 MemoryUses.push_back({&U, CmpX->getCompareOperand()->
getType()});
5612 if (
CallInst *CI = dyn_cast<CallInst>(UserI)) {
5613 if (CI->hasFnAttr(Attribute::Cold)) {
5620 InlineAsm *IA = dyn_cast<InlineAsm>(CI->getCalledOperand());
5631 PSI, BFI, SeenInsts))
5642 unsigned SeenInsts = 0;
5645 PSI, BFI, SeenInsts);
5653bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5655 Value *KnownLive2) {
5657 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5661 if (!isa<Instruction>(Val) && !isa<Argument>(Val))
5667 if (
AllocaInst *AI = dyn_cast<AllocaInst>(Val))
5698bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5700 if (IgnoreProfitability)
5718 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5719 ScaledReg =
nullptr;
5723 if (!BaseReg && !ScaledReg)
5744 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5746 Instruction *UserI = cast<Instruction>(Pair.first->getUser());
5747 Type *AddressAccessTy = Pair.second;
5748 unsigned AS =
Address->getType()->getPointerAddressSpace();
5754 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5756 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5757 TPT.getRestorationPoint();
5758 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5759 AddressAccessTy, AS, UserI, Result,
5760 InsertedInsts, PromotedInsts, TPT,
5761 LargeOffsetGEP, OptSize, PSI, BFI);
5762 Matcher.IgnoreProfitability =
true;
5763 bool Success = Matcher.matchAddr(Address, 0);
5770 TPT.rollback(LastKnownGood);
5776 MatchedAddrModeInsts.
clear();
5786 return I->getParent() != BB;
5795 if (
Addr->hasOneUse())
5801 if (
Instruction *AddrInst = dyn_cast<Instruction>(SunkAddr))
5802 return std::next(AddrInst->getIterator());
5813 Earliest = UserInst;
5839 Type *AccessTy,
unsigned AddrSpace) {
5851 bool PhiOrSelectSeen =
false;
5854 AddressingModeCombiner AddrModes(SQ,
Addr);
5855 TypePromotionTransaction TPT(RemovedInsts);
5856 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5857 TPT.getRestorationPoint();
5858 while (!worklist.
empty()) {
5870 if (!Visited.
insert(V).second)
5874 if (
PHINode *
P = dyn_cast<PHINode>(V)) {
5876 PhiOrSelectSeen =
true;
5880 if (
SelectInst *SI = dyn_cast<SelectInst>(V)) {
5883 PhiOrSelectSeen =
true;
5890 AddrModeInsts.
clear();
5891 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5896 auto getDTFn = [MemoryInst,
this]() ->
const DominatorTree & {
5898 return this->getDT(*
F);
5900 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5901 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5902 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5910 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5911 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5914 NewAddrMode.OriginalValue =
V;
5915 if (!AddrModes.addNewAddrMode(NewAddrMode))
5922 if (!AddrModes.combineAddrModes()) {
5923 TPT.rollback(LastKnownGood);
5935 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5952 Type *IntPtrTy =
DL->getIntPtrType(
Addr->getType());
5971 <<
" for " << *MemoryInst <<
"\n");
5974 Addr->getType()->getPointerAddressSpace() &&
5975 !
DL->isNonIntegralPointerType(
Addr->getType())) {
5981 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
5983 Builder.CreateIntToPtr(SunkAddr,
Addr->getType(),
"sunkaddr");
5985 SunkAddr = Builder.CreatePointerCast(SunkAddr,
Addr->getType());
5992 <<
" for " << *MemoryInst <<
"\n");
5993 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
6004 if (ResultPtr ||
AddrMode.Scale != 1)
6026 if (BaseGV !=
nullptr) {
6031 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
6040 if (!
DL->isNonIntegralPointerType(
Addr->getType())) {
6041 if (!ResultPtr &&
AddrMode.BaseReg) {
6042 ResultPtr = Builder.CreateIntToPtr(
AddrMode.BaseReg,
Addr->getType(),
6045 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
6046 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg,
Addr->getType(),
6055 }
else if (!ResultPtr) {
6059 Builder.getPtrTy(
Addr->getType()->getPointerAddressSpace());
6068 if (
V->getType() != IntPtrTy)
6069 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6077 if (
V->getType() == IntPtrTy) {
6081 cast<IntegerType>(
V->getType())->getBitWidth() &&
6082 "We can't transform if ScaledReg is too narrow");
6083 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6087 V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy,
AddrMode.Scale),
6090 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6101 if (ResultPtr->
getType() != I8PtrTy)
6102 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6103 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6111 auto PtrInst = dyn_cast<Instruction>(ResultPtr);
6116 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6118 SunkAddr = ResultPtr;
6120 if (ResultPtr->
getType() != I8PtrTy)
6121 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6122 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6128 Addr->getType()->getPointerAddressSpace() &&
6129 !
DL->isNonIntegralPointerType(
Addr->getType())) {
6135 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
6137 Builder.CreateIntToPtr(SunkAddr,
Addr->getType(),
"sunkaddr");
6139 SunkAddr = Builder.CreatePointerCast(SunkAddr,
Addr->getType());
6148 PointerType *ScalePtrTy = dyn_cast_or_null<PointerType>(ScaleTy);
6149 if (
DL->isNonIntegralPointerType(
Addr->getType()) ||
6150 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6151 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6153 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6157 <<
" for " << *MemoryInst <<
"\n");
6158 Type *IntPtrTy =
DL->getIntPtrType(
Addr->getType());
6168 if (
V->getType()->isPointerTy())
6169 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6170 if (
V->getType() != IntPtrTy)
6171 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6178 if (
V->getType() == IntPtrTy) {
6180 }
else if (
V->getType()->isPointerTy()) {
6181 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6182 }
else if (cast<IntegerType>(IntPtrTy)->
getBitWidth() <
6183 cast<IntegerType>(
V->getType())->getBitWidth()) {
6184 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6191 Instruction *
I = dyn_cast_or_null<Instruction>(Result);
6193 I->eraseFromParent();
6197 V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy,
AddrMode.Scale),
6200 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6207 if (BaseGV !=
nullptr) {
6210 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6214 Value *
V = Builder.CreatePtrToInt(BaseGVPtr, IntPtrTy,
"sunkaddr");
6216 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6225 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6233 SunkAddr = Builder.CreateIntToPtr(Result,
Addr->getType(),
"sunkaddr");
6244 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6245 RecursivelyDeleteTriviallyDeadInstructions(
6246 Repl, TLInfo, nullptr,
6247 [&](Value *V) { removeAllAssertingVHReferences(V); });
6271bool CodeGenPrepare::optimizeGatherScatterInst(
Instruction *MemoryInst,
6275 if (
const auto *
GEP = dyn_cast<GetElementPtrInst>(
Ptr)) {
6277 if (!
GEP->hasIndices())
6287 bool RewriteGEP =
false;
6289 if (Ops[0]->
getType()->isVectorTy()) {
6296 unsigned FinalIndex = Ops.size() - 1;
6301 for (
unsigned i = 1; i < FinalIndex; ++i) {
6302 auto *
C = dyn_cast<Constant>(Ops[i]);
6305 if (isa<VectorType>(
C->getType()))
6306 C =
C->getSplatValue();
6307 auto *CI = dyn_cast_or_null<ConstantInt>(
C);
6308 if (!CI || !CI->
isZero())
6315 if (Ops[FinalIndex]->
getType()->isVectorTy()) {
6317 auto *
C = dyn_cast<ConstantInt>(V);
6319 if (!
C || !
C->isZero()) {
6320 Ops[FinalIndex] =
V;
6328 if (!RewriteGEP && Ops.size() == 2)
6331 auto NumElts = cast<VectorType>(
Ptr->getType())->getElementCount();
6335 Type *SourceTy =
GEP->getSourceElementType();
6336 Type *ScalarIndexTy =
DL->getIndexType(Ops[0]->
getType()->getScalarType());
6340 if (!Ops[FinalIndex]->
getType()->isVectorTy()) {
6341 NewAddr = Builder.CreateGEP(SourceTy, Ops[0],
ArrayRef(Ops).drop_front());
6342 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6344 SourceTy,
ArrayRef(Ops).drop_front());
6352 if (Ops.size() != 2) {
6358 SourceTy,
ArrayRef(Ops).drop_front());
6362 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6364 }
else if (!isa<Constant>(
Ptr)) {
6371 auto NumElts = cast<VectorType>(
Ptr->getType())->getElementCount();
6376 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6377 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6380 Intrinsic::masked_gather) {
6384 Intrinsic::masked_scatter);
6397 if (
Ptr->use_empty())
6399 Ptr, TLInfo,
nullptr,
6400 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6407bool CodeGenPrepare::optimizeInlineAsmInst(
CallInst *CS) {
6408 bool MadeChange =
false;
6411 TM->getSubtargetImpl(*CS->
getFunction())->getRegisterInfo();
6421 OpInfo.isIndirect) {
6423 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6436 bool IsSExt = isa<SExtInst>(FirstUser);
6440 if ((IsSExt && !isa<SExtInst>(UI)) || (!IsSExt && !isa<ZExtInst>(UI)))
6486bool CodeGenPrepare::tryToPromoteExts(
6489 unsigned CreatedInstsCost) {
6490 bool Promoted =
false;
6493 for (
auto *
I : Exts) {
6495 if (isa<LoadInst>(
I->getOperand(0))) {
6508 TypePromotionHelper::Action TPH =
6509 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6518 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6519 TPT.getRestorationPoint();
6521 unsigned NewCreatedInstsCost = 0;
6524 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6525 &NewExts,
nullptr, *TLI);
6527 "TypePromotionHelper should have filtered out those cases");
6537 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6540 TotalCreatedInstsCost =
6541 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6543 (TotalCreatedInstsCost > 1 ||
6545 (ExtCost == 0 && NewExts.
size() > 1))) {
6549 TPT.rollback(LastKnownGood);
6555 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6556 bool NewPromoted =
false;
6557 for (
auto *ExtInst : NewlyMovedExts) {
6558 Instruction *MovedExt = cast<Instruction>(ExtInst);
6562 if (isa<LoadInst>(ExtOperand) &&
6567 ProfitablyMovedExts.
push_back(MovedExt);
6574 TPT.rollback(LastKnownGood);
6585bool CodeGenPrepare::mergeSExts(
Function &
F) {
6586 bool Changed =
false;
6587 for (
auto &Entry : ValToSExtendedUses) {
6588 SExts &Insts =
Entry.second;
6591 if (RemovedInsts.count(Inst) || !isa<SExtInst>(Inst) ||
6594 bool inserted =
false;
6595 for (
auto &Pt : CurPts) {
6598 RemovedInsts.insert(Pt);
6599 Pt->removeFromParent();
6610 RemovedInsts.insert(Inst);
6617 CurPts.push_back(Inst);
6659bool CodeGenPrepare::splitLargeGEPOffsets() {
6660 bool Changed =
false;
6661 for (
auto &Entry : LargeOffsetGEPMap) {
6664 &LargeOffsetGEPs =
Entry.second;
6665 auto compareGEPOffset =
6666 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6667 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6668 if (
LHS.first ==
RHS.first)
6670 if (
LHS.second !=
RHS.second)
6671 return LHS.second <
RHS.second;
6672 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6675 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6678 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6681 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6682 Value *NewBaseGEP =
nullptr;
6684 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6687 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6689 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6693 if (
auto *BaseI = dyn_cast<Instruction>(OldBase)) {
6697 if (isa<PHINode>(BaseI))
6699 else if (
InvokeInst *Invoke = dyn_cast<InvokeInst>(BaseI)) {
6701 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), DT.get(), LI);
6704 NewBaseInsertPt = std::next(BaseI->getIterator());
6711 IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
6713 Value *BaseIndex = ConstantInt::get(PtrIdxTy, BaseOffset);
6714 NewBaseGEP = OldBase;
6715 if (NewBaseGEP->
getType() != I8PtrTy)
6716 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6718 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6719 NewGEPBases.
insert(NewBaseGEP);
6725 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6726 BaseOffset = PreferBase;
6729 createNewBase(BaseOffset, OldBase, BaseGEP);
6732 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6733 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6735 int64_t
Offset = LargeOffsetGEP->second;
6736 if (
Offset != BaseOffset) {
6743 GEP->getResultElementType(),
6744 GEP->getAddressSpace())) {
6750 NewBaseGEP =
nullptr;
6755 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6760 createNewBase(BaseOffset, OldBase,
GEP);
6764 Value *NewGEP = NewBaseGEP;
6765 if (
Offset != BaseOffset) {
6768 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6772 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6773 GEP->eraseFromParent();
6780bool CodeGenPrepare::optimizePhiType(
6787 Type *PhiTy =
I->getType();
6788 Type *ConvertTy =
nullptr;
6790 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6806 bool AnyAnchored =
false;
6808 while (!Worklist.
empty()) {
6811 if (
auto *Phi = dyn_cast<PHINode>(
II)) {
6813 for (
Value *V :
Phi->incoming_values()) {
6814 if (
auto *OpPhi = dyn_cast<PHINode>(V)) {
6815 if (!PhiNodes.
count(OpPhi)) {
6816 if (!Visited.
insert(OpPhi).second)
6821 }
else if (
auto *OpLoad = dyn_cast<LoadInst>(V)) {
6822 if (!OpLoad->isSimple())
6824 if (Defs.
insert(OpLoad).second)
6826 }
else if (
auto *OpEx = dyn_cast<ExtractElementInst>(V)) {
6827 if (Defs.
insert(OpEx).second)
6829 }
else if (
auto *OpBC = dyn_cast<BitCastInst>(V)) {
6831 ConvertTy = OpBC->getOperand(0)->getType();
6832 if (OpBC->getOperand(0)->getType() != ConvertTy)
6834 if (Defs.
insert(OpBC).second) {
6836 AnyAnchored |= !isa<LoadInst>(OpBC->getOperand(0)) &&
6837 !isa<ExtractElementInst>(OpBC->getOperand(0));
6839 }
else if (
auto *OpC = dyn_cast<ConstantData>(V))
6847 for (
User *V :
II->users()) {
6848 if (
auto *OpPhi = dyn_cast<PHINode>(V)) {
6849 if (!PhiNodes.
count(OpPhi)) {
6850 if (Visited.
count(OpPhi))
6856 }
else if (
auto *OpStore = dyn_cast<StoreInst>(V)) {
6857 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
6859 Uses.insert(OpStore);
6860 }
else if (
auto *OpBC = dyn_cast<BitCastInst>(V)) {
6862 ConvertTy = OpBC->getType();
6863 if (OpBC->getType() != ConvertTy)
6867 any_of(OpBC->users(), [](
User *U) { return !isa<StoreInst>(U); });
6874 if (!ConvertTy || !AnyAnchored ||
6878 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
6879 << *ConvertTy <<
"\n");
6887 if (isa<BitCastInst>(
D)) {
6888 ValMap[
D] =
D->getOperand(0);
6892 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
6897 Phi->getName() +
".tc",
Phi->getIterator());
6899 for (
PHINode *Phi : PhiNodes) {
6900 PHINode *NewPhi = cast<PHINode>(ValMap[Phi]);
6901 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
6903 Phi->getIncomingBlock(i));
6908 if (isa<BitCastInst>(U)) {
6912 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
6922bool CodeGenPrepare::optimizePhiTypes(
Function &
F) {
6926 bool Changed =
false;
6932 for (
auto &Phi : BB.
phis())
6933 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
6936 for (
auto *
I : DeletedInstrs) {
6938 I->eraseFromParent();
6946bool CodeGenPrepare::canFormExtLd(
6949 for (
auto *MovedExtInst : MovedExts) {
6950 if (isa<LoadInst>(MovedExtInst->getOperand(0))) {
6951 LI = cast<LoadInst>(MovedExtInst->getOperand(0));
6952 Inst = MovedExtInst;
7004bool CodeGenPrepare::optimizeExt(
Instruction *&Inst) {
7005 bool AllowPromotionWithoutCommonHeader =
false;
7010 *Inst, AllowPromotionWithoutCommonHeader);
7011 TypePromotionTransaction TPT(RemovedInsts);
7012 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7013 TPT.getRestorationPoint();
7018 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7026 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7027 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7032 Inst = ExtFedByLoad;
7037 if (ATPConsiderable &&
7038 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7039 HasPromoted, TPT, SpeculativelyMovedExts))
7042 TPT.rollback(LastKnownGood);
7051bool CodeGenPrepare::performAddressTypePromotion(
7052 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7053 bool HasPromoted, TypePromotionTransaction &TPT,
7055 bool Promoted =
false;
7057 bool AllSeenFirst =
true;
7058 for (
auto *
I : SpeculativelyMovedExts) {
7059 Value *HeadOfChain =
I->getOperand(0);
7061 SeenChainsForSExt.
find(HeadOfChain);
7064 if (AlreadySeen != SeenChainsForSExt.
end()) {
7065 if (AlreadySeen->second !=
nullptr)
7066 UnhandledExts.
insert(AlreadySeen->second);
7067 AllSeenFirst =
false;
7071 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7072 SpeculativelyMovedExts.size() == 1)) {
7076 for (
auto *
I : SpeculativelyMovedExts) {
7077 Value *HeadOfChain =
I->getOperand(0);
7078 SeenChainsForSExt[HeadOfChain] =
nullptr;
7079 ValToSExtendedUses[HeadOfChain].push_back(
I);
7082 Inst = SpeculativelyMovedExts.pop_back_val();
7087 for (
auto *
I : SpeculativelyMovedExts) {
7088 Value *HeadOfChain =
I->getOperand(0);
7089 SeenChainsForSExt[HeadOfChain] = Inst;
7094 if (!AllSeenFirst && !UnhandledExts.
empty())
7095 for (
auto *VisitedSExt : UnhandledExts) {
7096 if (RemovedInsts.count(VisitedSExt))
7098 TypePromotionTransaction TPT(RemovedInsts);
7102 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7106 for (
auto *
I : Chains) {
7107 Value *HeadOfChain =
I->getOperand(0);
7109 SeenChainsForSExt[HeadOfChain] =
nullptr;
7110 ValToSExtendedUses[HeadOfChain].push_back(
I);
7121 Value *Src =
I->getOperand(0);
7122 if (Src->hasOneUse())
7131 if (!isa<Instruction>(Src) || DefBB != cast<Instruction>(Src)->
getParent())
7134 bool DefIsLiveOut =
false;
7135 for (
User *U :
I->users()) {
7140 if (UserBB == DefBB)
7142 DefIsLiveOut =
true;
7149 for (
User *U : Src->users()) {
7152 if (UserBB == DefBB)
7156 if (isa<PHINode>(UI) || isa<LoadInst>(UI) || isa<StoreInst>(UI))
7163 bool MadeChange =
false;
7164 for (
Use &U : Src->uses()) {
7169 if (UserBB == DefBB)
7173 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7175 if (!InsertedTrunc) {
7178 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7180 InsertedInsts.insert(InsertedTrunc);
7243bool CodeGenPrepare::optimizeLoadExt(
LoadInst *Load) {
7244 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7248 if (
Load->hasOneUse() &&
7249 InsertedInsts.count(cast<Instruction>(*
Load->user_begin())))
7258 for (
auto *U :
Load->users())
7259 WorkList.
push_back(cast<Instruction>(U));
7270 while (!WorkList.
empty()) {
7274 if (!Visited.
insert(
I).second)
7278 if (
auto *Phi = dyn_cast<PHINode>(
I)) {
7279 for (
auto *U :
Phi->users())
7280 WorkList.
push_back(cast<Instruction>(U));
7284 switch (
I->getOpcode()) {
7285 case Instruction::And: {
7286 auto *AndC = dyn_cast<ConstantInt>(
I->getOperand(1));
7289 APInt AndBits = AndC->getValue();
7290 DemandBits |= AndBits;
7292 if (AndBits.
ugt(WidestAndBits))
7293 WidestAndBits = AndBits;
7294 if (AndBits == WidestAndBits &&
I->getOperand(0) == Load)
7299 case Instruction::Shl: {
7300 auto *ShlC = dyn_cast<ConstantInt>(
I->getOperand(1));
7304 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7309 case Instruction::Trunc: {
7312 DemandBits.setLowBits(TruncBitWidth);
7322 uint32_t ActiveBits = DemandBits.getActiveBits();
7334 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7335 WidestAndBits != DemandBits)
7348 auto *NewAnd = cast<Instruction>(
7349 Builder.CreateAnd(Load, ConstantInt::get(Ctx, DemandBits)));
7352 InsertedInsts.insert(NewAnd);
7357 NewAnd->setOperand(0, Load);
7360 for (
auto *
And : AndsToMaybeRemove)
7363 if (cast<ConstantInt>(
And->getOperand(1))->getValue() == DemandBits) {
7365 if (&*CurInstIterator ==
And)
7366 CurInstIterator = std::next(
And->getIterator());
7367 And->eraseFromParent();
7372 for (
auto *Inst : DropFlags)
7382 auto *
I = dyn_cast<Instruction>(V);
7404 uint64_t Max = std::max(TrueWeight, FalseWeight);
7405 uint64_t Sum = TrueWeight + FalseWeight;
7413 CmpInst *Cmp = dyn_cast<CmpInst>(SI->getCondition());
7418 if (!Cmp || !Cmp->hasOneUse())
7439 for (
SelectInst *DefSI = SI; DefSI !=
nullptr && Selects.
count(DefSI);
7440 DefSI = dyn_cast<SelectInst>(V)) {
7441 assert(DefSI->getCondition() == SI->getCondition() &&
7442 "The condition of DefSI does not match with SI");
7443 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7446 assert(V &&
"Failed to get select true/false value");
7475 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7476 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7477 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7483bool CodeGenPrepare::optimizeFunnelShift(
IntrinsicInst *Fsh) {
7485 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7486 "Expected a funnel shift");
7510 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7511 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7512 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7520bool CodeGenPrepare::optimizeSelectInst(
SelectInst *SI) {
7532 It !=
SI->getParent()->
end(); ++It) {
7534 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7544 CurInstIterator = std::next(LastSI->
getIterator());
7549 fixupDbgVariableRecordsOnInst(*SI);
7551 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7554 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7558 if (
SI->getType()->isVectorTy())
7559 SelectKind = TargetLowering::ScalarCondVectorVal;
7561 SelectKind = TargetLowering::ScalarValSelect;
7604 TrueInstrs.
push_back(cast<Instruction>(V));
7606 FalseInstrs.
push_back(cast<Instruction>(V));
7614 SplitPt.setHeadBit(
true);
7617 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7624 if (TrueInstrs.
size() == 0) {
7626 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7628 EndBlock = cast<BasicBlock>(FalseBranch->
getOperand(0));
7629 }
else if (FalseInstrs.
size() == 0) {
7631 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7633 EndBlock = cast<BasicBlock>(TrueBranch->
getOperand(0));
7638 nullptr,
nullptr, LI);
7639 TrueBranch = cast<BranchInst>(ThenTerm);
7640 FalseBranch = cast<BranchInst>(ElseTerm);
7643 EndBlock = cast<BasicBlock>(TrueBranch->
getOperand(0));
7646 EndBlock->
setName(
"select.end");
7648 TrueBlock->
setName(
"select.true.sink");
7650 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7651 :
"select.false.sink");
7655 FreshBBs.
insert(TrueBlock);
7657 FreshBBs.
insert(FalseBlock);
7658 FreshBBs.
insert(EndBlock);
7661 BFI->setBlockFreq(EndBlock,
BFI->getBlockFreq(StartBlock));
7663 static const unsigned MD[] = {
7664 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7665 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7679 if (TrueBlock ==
nullptr)
7680 TrueBlock = StartBlock;
7681 else if (FalseBlock ==
nullptr)
7682 FalseBlock = StartBlock;
7698 SI->eraseFromParent();
7700 ++NumSelectsExpanded;
7704 CurInstIterator = StartBlock->
end();
7720 auto *SVIVecType = cast<FixedVectorType>(SVI->
getType());
7723 "Expected a type of the same size!");
7729 Builder.SetInsertPoint(SVI);
7730 Value *BC1 = Builder.CreateBitCast(
7731 cast<Instruction>(SVI->
getOperand(0))->getOperand(1), NewType);
7732 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7733 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7737 SVI, TLInfo,
nullptr,
7738 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7742 if (
auto *BCI = dyn_cast<Instruction>(BC1))
7743 if (
auto *
Op = dyn_cast<Instruction>(BCI->
getOperand(0)))
7744 if (BCI->
getParent() !=
Op->getParent() && !isa<PHINode>(
Op) &&
7745 !
Op->isTerminator() && !
Op->isEHPad())
7751bool CodeGenPrepare::tryToSinkFreeOperands(
Instruction *
I) {
7763 bool Changed =
false;
7767 unsigned long InstNumber = 0;
7768 for (
const auto &
I : *TargetBB)
7769 InstOrdering[&
I] = InstNumber++;
7772 auto *UI = cast<Instruction>(
U->get());
7773 if (isa<PHINode>(UI))
7776 if (InstOrdering[UI] < InstOrdering[InsertPoint])
7785 for (
Use *U : ToReplace) {
7786 auto *UI = cast<Instruction>(
U->get());
7793 if (
auto *OpDef = dyn_cast<Instruction>(
Op))
7794 FreshBBs.
insert(OpDef->getParent());
7797 NewInstructions[UI] = NI;
7802 InsertedInsts.insert(NI);
7808 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
7809 It->second->setOperand(
U->getOperandNo(), NI);
7816 for (
auto *
I : MaybeDead) {
7817 if (!
I->hasNUsesOrMore(1)) {
7819 I->eraseFromParent();
7826bool CodeGenPrepare::optimizeSwitchType(
SwitchInst *SI) {
7834 if (RegWidth <= cast<IntegerType>(OldType)->
getBitWidth())
7852 ExtType = Instruction::SExt;
7854 if (
auto *Arg = dyn_cast<Argument>(
Cond)) {
7855 if (Arg->hasSExtAttr())
7856 ExtType = Instruction::SExt;
7857 if (Arg->hasZExtAttr())
7858 ExtType = Instruction::ZExt;
7864 SI->setCondition(ExtInst);
7865 for (
auto Case :
SI->cases()) {
7866 const APInt &NarrowConst = Case.getCaseValue()->getValue();
7867 APInt WideConst = (ExtType == Instruction::ZExt)
7868 ? NarrowConst.
zext(RegWidth)
7869 : NarrowConst.
sext(RegWidth);
7870 Case.setValue(ConstantInt::get(Context, WideConst));
7876bool CodeGenPrepare::optimizeSwitchPhiConstants(
SwitchInst *SI) {
7883 Value *Condition =
SI->getCondition();
7885 if (isa<ConstantInt>(*Condition))
7888 bool Changed =
false;
7894 BasicBlock *CaseBB = Case.getCaseSuccessor();
7897 bool CheckedForSinglePred =
false;
7899 Type *PHIType =
PHI.getType();
7907 if (PHIType == ConditionType || TryZExt) {
7909 bool SkipCase =
false;
7910 Value *Replacement =
nullptr;
7911 for (
unsigned I = 0, E =
PHI.getNumIncomingValues();
I != E;
I++) {
7912 Value *PHIValue =
PHI.getIncomingValue(
I);
7913 if (PHIValue != CaseValue) {
7916 ConstantInt *PHIValueInt = dyn_cast<ConstantInt>(PHIValue);
7922 if (
PHI.getIncomingBlock(
I) != SwitchBB)
7927 if (!CheckedForSinglePred) {
7928 CheckedForSinglePred =
true;
7929 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
7935 if (Replacement ==
nullptr) {
7936 if (PHIValue == CaseValue) {
7937 Replacement = Condition;
7940 Replacement = Builder.CreateZExt(Condition, PHIType);
7943 PHI.setIncomingValue(
I, Replacement);
7954bool CodeGenPrepare::optimizeSwitchInst(
SwitchInst *SI) {
7955 bool Changed = optimizeSwitchType(SI);
7956 Changed |= optimizeSwitchPhiConstants(SI);
7977class VectorPromoteHelper {
7994 unsigned StoreExtractCombineCost;
8003 if (InstsToBePromoted.
empty())
8005 return InstsToBePromoted.
back();
8011 unsigned getTransitionOriginalValueIdx()
const {
8012 assert(isa<ExtractElementInst>(Transition) &&
8013 "Other kind of transitions are not supported yet");
8020 unsigned getTransitionIdx()
const {
8021 assert(isa<ExtractElementInst>(Transition) &&
8022 "Other kind of transitions are not supported yet");
8030 Type *getTransitionType()
const {
8045 bool isProfitableToPromote() {
8046 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8047 unsigned Index = isa<ConstantInt>(ValIdx)
8048 ? cast<ConstantInt>(ValIdx)->getZExtValue()
8050 Type *PromotedType = getTransitionType();
8053 unsigned AS =
ST->getPointerAddressSpace();
8071 for (
const auto &Inst : InstsToBePromoted) {
8077 bool IsArg0Constant = isa<UndefValue>(Arg0) || isa<ConstantInt>(Arg0) ||
8078 isa<ConstantFP>(Arg0);
8091 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8092 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8093 return ScalarCost > VectorCost;
8105 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8110 if (
ConstantInt *CstVal = dyn_cast<ConstantInt>(ValExtractIdx))
8116 ElementCount EC = cast<VectorType>(getTransitionType())->getElementCount();
8120 if (!
EC.isScalable()) {
8123 for (
unsigned Idx = 0;
Idx !=
EC.getKnownMinValue(); ++
Idx) {
8124 if (
Idx == ExtractIdx)
8132 "Generate scalable vector for non-splat is unimplemented");
8138 unsigned OperandIdx) {
8141 if (OperandIdx != 1)
8143 switch (
Use->getOpcode()) {
8146 case Instruction::SDiv:
8147 case Instruction::UDiv:
8148 case Instruction::SRem:
8149 case Instruction::URem:
8151 case Instruction::FDiv:
8152 case Instruction::FRem:
8153 return !
Use->hasNoNaNs();
8161 unsigned CombineCost)
8162 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8163 StoreExtractCombineCost(CombineCost) {
8164 assert(Transition &&
"Do not know how to promote null");
8168 bool canPromote(
const Instruction *ToBePromoted)
const {
8170 return isa<BinaryOperator>(ToBePromoted);
8175 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8179 const Value *Val =
U.get();
8180 if (Val == getEndOfTransition()) {
8184 if (canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()))
8188 if (!isa<ConstantInt>(Val) && !isa<UndefValue>(Val) &&
8189 !isa<ConstantFP>(Val))
8198 ISDOpcode, TLI.
getValueType(DL, getTransitionType(),
true));
8207 void enqueueForPromotion(
Instruction *ToBePromoted) {
8208 InstsToBePromoted.push_back(ToBePromoted);
8212 void recordCombineInstruction(
Instruction *ToBeCombined) {
8214 CombineInst = ToBeCombined;
8224 if (InstsToBePromoted.empty() || !CombineInst)
8232 for (
auto &ToBePromoted : InstsToBePromoted)
8233 promoteImpl(ToBePromoted);
8234 InstsToBePromoted.clear();
8241void VectorPromoteHelper::promoteImpl(
Instruction *ToBePromoted) {
8251 "The type of the result of the transition does not match "
8256 Type *TransitionTy = getTransitionType();
8263 Value *NewVal =
nullptr;
8264 if (Val == Transition)
8265 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8266 else if (isa<UndefValue>(Val) || isa<ConstantInt>(Val) ||
8267 isa<ConstantFP>(Val)) {
8270 cast<Constant>(Val),
8271 isa<UndefValue>(Val) ||
8272 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8276 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8279 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8285bool CodeGenPrepare::optimizeExtractElementInst(
Instruction *Inst) {
8286 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8301 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8302 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost);
8309 if (ToBePromoted->
getParent() != Parent) {
8310 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8312 <<
") than the transition (" << Parent->
getName()
8317 if (VPH.canCombine(ToBePromoted)) {
8319 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8320 VPH.recordCombineInstruction(ToBePromoted);
8321 bool Changed = VPH.promote();
8322 NumStoreExtractExposed += Changed;
8327 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8330 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8332 VPH.enqueueForPromotion(ToBePromoted);
8333 Inst = ToBePromoted;
8373 Type *StoreType = SI.getValueOperand()->getType();
8382 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8383 DL.getTypeSizeInBits(StoreType) == 0)
8386 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8388 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8392 if (SI.isVolatile())
8404 if (!
match(SI.getValueOperand(),
8411 if (!
LValue->getType()->isIntegerTy() ||
8412 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8414 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8419 auto *LBC = dyn_cast<BitCastInst>(
LValue);
8420 auto *HBC = dyn_cast<BitCastInst>(HValue);
8434 if (LBC && LBC->getParent() != SI.getParent())
8436 if (HBC && HBC->getParent() != SI.getParent())
8437 HValue = Builder.
CreateBitCast(HBC->getOperand(0), HBC->getType());
8439 bool IsLE = SI.getDataLayout().isLittleEndian();
8440 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8443 Align Alignment = SI.getAlign();
8444 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8445 if (IsOffsetStore) {
8447 SplitStoreType,
Addr,
8458 CreateSplitStore(
LValue,
false);
8459 CreateSplitStore(HValue,
true);
8462 SI.eraseFromParent();
8470 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8471 isa<ConstantInt>(
GEP->getOperand(1));
8549 if (!isa<Instruction>(GEPIOp))
8551 auto *GEPIOpI = cast<Instruction>(GEPIOp);
8552 if (GEPIOpI->getParent() != SrcBlock)
8557 if (auto *I = dyn_cast<Instruction>(Usr)) {
8558 if (I->getParent() != SrcBlock) {
8566 std::vector<GetElementPtrInst *> UGEPIs;
8573 if (!isa<Instruction>(Usr))
8575 auto *UI = cast<Instruction>(Usr);
8580 if (!isa<GetElementPtrInst>(Usr))
8582 auto *UGEPI = cast<GetElementPtrInst>(Usr);
8588 if (UGEPI->getOperand(0) != GEPIOp)
8590 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8592 if (GEPIIdx->getType() !=
8593 cast<ConstantInt>(UGEPI->getOperand(1))->getType())
8595 ConstantInt *UGEPIIdx = cast<ConstantInt>(UGEPI->getOperand(1));
8600 UGEPIs.push_back(UGEPI);
8602 if (UGEPIs.size() == 0)
8606 ConstantInt *UGEPIIdx = cast<ConstantInt>(UGEPI->getOperand(1));
8615 UGEPI->setOperand(0, GEPI);
8616 ConstantInt *UGEPIIdx = cast<ConstantInt>(UGEPI->getOperand(1));
8617 Constant *NewUGEPIIdx = ConstantInt::get(
8618 GEPIIdx->getType(), UGEPIIdx->
getValue() - GEPIIdx->getValue());
8619 UGEPI->setOperand(1, NewUGEPIIdx);
8622 if (!GEPI->isInBounds()) {
8623 UGEPI->setIsInBounds(
false);
8630 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8632 "GEPIOp is used outside SrcBlock");
8652 ICmpInst *Cmp = dyn_cast<ICmpInst>(Branch->getCondition());
8653 if (!Cmp || !isa<ConstantInt>(Cmp->getOperand(1)) || !Cmp->hasOneUse())
8656 Value *
X = Cmp->getOperand(0);
8657 if (!
X->hasUseList())
8660 APInt CmpC = cast<ConstantInt>(Cmp->getOperand(1))->getValue();
8662 for (
auto *U :
X->users()) {
8666 (UI->
getParent() != Branch->getParent() &&
8667 UI->
getParent() != Branch->getSuccessor(0) &&
8668 UI->
getParent() != Branch->getSuccessor(1)) ||
8669 (UI->
getParent() != Branch->getParent() &&
8670 !UI->
getParent()->getSinglePredecessor()))
8673 if (CmpC.
isPowerOf2() && Cmp->getPredicate() == ICmpInst::ICMP_ULT &&
8676 if (UI->
getParent() != Branch->getParent())
8680 ConstantInt::get(UI->
getType(), 0));
8682 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8686 if (Cmp->isEquality() &&
8691 if (UI->
getParent() != Branch->getParent())
8695 ConstantInt::get(UI->
getType(), 0));
8697 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8705bool CodeGenPrepare::optimizeInst(
Instruction *
I, ModifyDT &ModifiedDT) {
8706 bool AnyChange =
false;
8707 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8711 if (InsertedInsts.count(
I))
8715 if (
PHINode *
P = dyn_cast<PHINode>(
I)) {
8720 LargeOffsetGEPMap.erase(
P);
8722 P->eraseFromParent();
8729 if (
CastInst *CI = dyn_cast<CastInst>(
I)) {
8742 if ((isa<UIToFPInst>(
I) || isa<SIToFPInst>(
I) || isa<FPToUIInst>(
I) ||
8743 isa<TruncInst>(
I)) &&
8745 I, LI->getLoopFor(
I->getParent()), *
TTI))
8748 if (isa<ZExtInst>(
I) || isa<SExtInst>(
I)) {
8753 TargetLowering::TypeExpandInteger) {
8757 I, LI->getLoopFor(
I->getParent()), *
TTI))
8760 bool MadeChange = optimizeExt(
I);
8761 return MadeChange | optimizeExtUses(
I);
8767 if (
auto *Cmp = dyn_cast<CmpInst>(
I))
8768 if (optimizeCmp(Cmp, ModifiedDT))
8772 if (optimizeURem(
I))
8775 if (
LoadInst *LI = dyn_cast<LoadInst>(
I)) {
8776 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8777 bool Modified = optimizeLoadExt(LI);
8783 if (
StoreInst *SI = dyn_cast<StoreInst>(
I)) {
8786 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8787 unsigned AS =
SI->getPointerAddressSpace();
8788 return optimizeMemoryInst(
I,
SI->getOperand(1),
8789 SI->getOperand(0)->getType(), AS);
8793 unsigned AS = RMW->getPointerAddressSpace();
8794 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
8798 unsigned AS = CmpX->getPointerAddressSpace();
8799 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
8800 CmpX->getCompareOperand()->getType(), AS);
8810 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
8811 BinOp->
getOpcode() == Instruction::LShr)) {
8819 if (GEPI->hasAllZeroIndices()) {
8822 GEPI->getName(), GEPI->getIterator());
8823 NC->setDebugLoc(GEPI->getDebugLoc());
8826 GEPI, TLInfo,
nullptr,
8827 [&](
Value *V) { removeAllAssertingVHReferences(V); });
8829 optimizeInst(
NC, ModifiedDT);
8841 if (
ICmpInst *
II = dyn_cast<ICmpInst>(FI->getOperand(0)))
8843 else if (
FCmpInst *
F = dyn_cast<FCmpInst>(FI->getOperand(0)))
8844 CmpI =
F->getFastMathFlags().none() ?
F :
nullptr;
8848 bool Const0 = isa<ConstantInt>(Op0) || isa<ConstantFP>(Op0) ||
8849 isa<ConstantPointerNull>(Op0);
8850 bool Const1 = isa<ConstantInt>(Op1) || isa<ConstantFP>(Op1) ||
8851 isa<ConstantPointerNull>(Op1);
8852 if (Const0 || Const1) {
8853 if (!Const0 || !Const1) {
8859 FI->eraseFromParent();
8866 if (tryToSinkFreeOperands(
I))
8869 switch (
I->getOpcode()) {
8870 case Instruction::Shl:
8871 case Instruction::LShr:
8872 case Instruction::AShr:
8873 return optimizeShiftInst(cast<BinaryOperator>(
I));
8874 case Instruction::Call:
8876 case Instruction::Select:
8877 return optimizeSelectInst(cast<SelectInst>(
I));
8878 case Instruction::ShuffleVector:
8879 return optimizeShuffleVectorInst(cast<ShuffleVectorInst>(
I));
8880 case Instruction::Switch:
8881 return optimizeSwitchInst(cast<SwitchInst>(
I));
8882 case Instruction::ExtractElement:
8883 return optimizeExtractElementInst(cast<ExtractElementInst>(
I));
8884 case Instruction::Br:
8885 return optimizeBranch(cast<BranchInst>(
I), *TLI, FreshBBs, IsHugeFunc);
8894 if (!
I.getType()->isIntegerTy() ||
8905 &
I, TLInfo,
nullptr,
8906 [&](
Value *V) { removeAllAssertingVHReferences(V); });
8913bool CodeGenPrepare::optimizeBlock(
BasicBlock &BB, ModifyDT &ModifiedDT) {
8915 bool MadeChange =
false;
8918 CurInstIterator = BB.
begin();
8919 ModifiedDT = ModifyDT::NotModifyDT;
8920 while (CurInstIterator != BB.
end()) {
8921 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
8922 if (ModifiedDT != ModifyDT::NotModifyDT) {
8935 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
8937 bool MadeBitReverse =
true;
8938 while (MadeBitReverse) {
8939 MadeBitReverse =
false;
8941 if (makeBitReverse(
I)) {
8942 MadeBitReverse = MadeChange =
true;
8947 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
8952bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(
Instruction &
I) {
8953 bool AnyChange =
false;
8955 AnyChange |= fixupDbgVariableRecord(DVR);
8962 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
8963 DVR.
Type != DbgVariableRecord::LocationType::Assign)
8967 bool AnyChange =
false;
8970 for (
Value *Location : LocationOps) {
8989 if (isa<PHINode>(VI))
9000bool CodeGenPrepare::placeDbgValues(
Function &
F) {
9001 bool MadeChange =
false;
9004 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9006 for (
Value *V : DbgItem->location_ops())
9007 if (
Instruction *VI = dyn_cast_or_null<Instruction>(V))
9015 if (
VI->isTerminator())
9020 if (isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9031 if (VIs.size() > 1) {
9034 <<
"Unable to find valid location for Debug Value, undefing:\n"
9036 DbgItem->setKillLocation();
9041 << *DbgItem <<
' ' << *VI);
9054 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9056 DbgProcessor(&DVR, &Insn);
9067bool CodeGenPrepare::placePseudoProbes(
Function &
F) {
9068 bool MadeChange =
false;
9071 auto FirstInst =
Block.getFirstInsertionPt();
9072 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9076 while (
I !=
Block.end()) {
9077 if (
auto *
II = dyn_cast<PseudoProbeInst>(
I++)) {
9078 II->moveBefore(FirstInst);
9088 uint64_t NewMax = (NewTrue > NewFalse) ? NewTrue : NewFalse;
9089 uint32_t Scale = (NewMax / std::numeric_limits<uint32_t>::max()) + 1;
9090 NewTrue = NewTrue / Scale;
9091 NewFalse = NewFalse / Scale;
9116bool CodeGenPrepare::splitBranchCondition(
Function &
F, ModifyDT &ModifiedDT) {
9120 bool MadeChange =
false;
9121 for (
auto &BB :
F) {
9134 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9142 Value *Cond1, *Cond2;
9145 Opc = Instruction::And;
9148 Opc = Instruction::Or;
9158 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9172 Br1->setCondition(Cond1);
9177 if (
Opc == Instruction::And)
9178 Br1->setSuccessor(0, TmpBB);
9180 Br1->setSuccessor(1, TmpBB);
9184 if (
auto *
I = dyn_cast<Instruction>(Cond2)) {
9185 I->removeFromParent();
9186 I->insertBefore(Br2->getIterator());
9198 if (
Opc == Instruction::Or)
9212 if (
Opc == Instruction::Or) {
9234 uint64_t NewTrueWeight = TrueWeight;
9235 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9237 Br1->setMetadata(LLVMContext::MD_prof,
9242 NewTrueWeight = TrueWeight;
9243 NewFalseWeight = 2 * FalseWeight;
9245 Br2->setMetadata(LLVMContext::MD_prof,
9270 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9271 uint64_t NewFalseWeight = FalseWeight;
9273 Br1->setMetadata(LLVMContext::MD_prof,
9277 NewTrueWeight = 2 * TrueWeight;
9278 NewFalseWeight = FalseWeight;
9280 Br2->setMetadata(LLVMContext::MD_prof,
9286 ModifiedDT = ModifyDT::ModifyBBDT;
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
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
This file contains the simple types necessary to represent the attributes associated with functions a...
static const Function * getParent(const Value *V)
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
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)
Optimize for code generation
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 bool sinkCmpExpression(CmpInst *Cmp, const TargetLowering &TLI)
Sink the given CmpInst into user blocks to reduce the number of virtual registers that must be create...
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 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 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.
#define LLVM_ATTRIBUTE_UNUSED
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")))
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
DenseMap< Block *, BlockRelaxAux > Blocks
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Module.h This file contains the declarations for the Module class.
This defines the Use class.
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
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
#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 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.
an instruction to allocate memory on the stack
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
void setAlignment(Align Align)
A container for analyses that lazily runs them and caches their results.
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.
Represent the analysis usage information of a pass.
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),...
Value handle that asserts if the Value is deleted.
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...
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 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.
const Function * getParent() const
Return the enclosing method, or null if none.
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.
This class represents a no-op cast from one type to another.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
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)
Base class for constants with no operands.
A constant value that is initialized with an expression using other constant values.
static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
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.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
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)
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
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)
This class implements simplifications for calls to fortified library functions (__st*cpy_chk,...
This class represents a freeze function that returns random concrete value if an operand is either a ...
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
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...
Represents a gc.statepoint intrinsic call.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static LLVM_ABI Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)
Returns the result type of a getelementptr with the given source element type and indexes.
LLVM_ABI bool canIncreaseAlignment() const
Returns true if the alignment of the value can be unilaterally increased.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
Type * getValueType() const
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This instruction compares its operands according to the predicate given to the constructor.
bool isEquality() const
Return true if this predicate is either EQ or NE.
Value * CreateZExtOrBitCast(Value *V, Type *DestTy, const Twine &Name="")
ConstantInt * getTrue()
Get the constant value for i1 true.
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateFreeze(Value *V, const Twine &Name="")
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
Value * CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
LLVM_ABI Value * createIsFPClass(Value *FPNum, unsigned Test)
Value * CreateCmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
ConstantInt * getInt(const APInt &AI)
Get a constant integer value.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
LLVM_ABI bool isDebugOrPseudoInst() const LLVM_READONLY
Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void moveAfter(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
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.
This is an important class for using LLVM in a threaded context.
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.
LLVM_ABI MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
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)
This is the common base class for memset/memcpy/memmove.
This class wraps the llvm.memcpy/memmove intrinsics.
An analysis over an "inner" IR unit that provides access to an analysis manager over a "outer" IR uni...
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
op_range incoming_values()
Value * getIncomingValueForBlock(const BasicBlock *BB) const
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
PointerIntPair - This class implements a pair of a pointer and small integer.
In order to facilitate speculative execution, many instructions do not invoke immediate undefined beh...
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.
Return a value (possibly void), from a function.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, Instruction *MDFrom=nullptr)
A vector that has set insertion semantics.
void clear()
Completely clear the SetVector.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
This instruction constructs a fixed permutation of two input vectors.
VectorType * getType() const
Overload to return most specific vector type.
Implements a dense probed hash-table based set with some number of buckets stored inline.
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.
A SetVector that performs no allocations if smaller than a certain size.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
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()
StringRef - Represent a constant reference to a string, i.e.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
TypeSize getElementOffset(unsigned Idx) const
Class to represent struct types.
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:
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.
SelectSupportKind
Enum that describes what type of support for selects the target has.
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 bool ExpandInlineAsm(CallInst *) const
This hook allows the target to expand an inline asm call to be explicit llvm code if it wants to.
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.
Primary interface to the complete machine description for the target machine.
virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const
Returns true if a cast between SrcAS and DestAS is a noop.
Target-Independent Code Generator Pass Configuration Options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
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.
This class represents a truncation of integer types.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
LLVM_ABI unsigned getIntegerBitWidth() const
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
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.
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, APInt &Offset) const
This is a wrapper around stripAndAccumulateConstantOffsets with the in-bounds requirement set to fals...
user_iterator user_begin()
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
LLVM_ABI bool isUsedInBasicBlock(const BasicBlock *BB) const
Check if this value is used in the specified basic block.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
void mutateType(Type *Ty)
Mutate the type of this Value to be of the specified type.
user_iterator_impl< User > user_iterator
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
Value handle that is nullable, but tries to track the Value.
bool pointsToAliveValue() const
This class represents zero extension of integer types.
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.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
unsigned getAddrMode(MCInstrInfo const &MCII, MCInst const &MCI)
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.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
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.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
apint_match m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
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.
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
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).
NodeAddr< PhiNode * > Phi
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
LLVM_ABI const_iterator begin(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get begin iterator over path.
LLVM_ABI const_iterator end(StringRef path LLVM_LIFETIME_BOUND)
Get end iterator over path.
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)
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.
int popcount(T Value) noexcept
Count the number of set bits in a value.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
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.
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)
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...
LLVM_ABI void DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, bool KeepOneInputPHIs=false)
Delete the specified block, which must have no predecessors.
LLVM_ABI void initializeCodeGenPrepareLegacyPassPass(PassRegistry &)
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
auto unique(Range &&R, Predicate P)
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
LLVM_ABI bool hasBranchWeightOrigin(const Instruction &I)
Check if Branch Weight Metadata has an "expected" field from an llvm.expect* intrinsic.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
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.
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.
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.
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...
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.
@ Xor
Bitwise or logical XOR of integers.
@ Sub
Subtraction of integers.
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...
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.
constexpr unsigned BitWidth
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
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 ...
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.
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.
Used to describe addressing mode similar to ExtAddrMode in CodeGenPrepare.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.