46#include "llvm/Config/llvm-config.h"
68#include "llvm/IR/IntrinsicsAArch64.h"
112#define DEBUG_TYPE "codegenprepare"
115STATISTIC(NumPHIsElim,
"Number of trivial PHIs eliminated");
116STATISTIC(NumGEPsElim,
"Number of GEPs converted to casts");
117STATISTIC(NumCmpUses,
"Number of uses of Cmp expressions replaced with uses of "
119STATISTIC(NumCastUses,
"Number of uses of Cast expressions replaced with uses "
121STATISTIC(NumMemoryInsts,
"Number of memory instructions whose address "
122 "computations were sunk");
124 "Number of phis created when address "
125 "computations were sunk to memory instructions");
127 "Number of select created when address "
128 "computations were sunk to memory instructions");
129STATISTIC(NumExtsMoved,
"Number of [s|z]ext instructions combined with loads");
130STATISTIC(NumExtUses,
"Number of uses of [s|z]ext instructions optimized");
132 "Number of and mask instructions added to form ext loads");
133STATISTIC(NumAndUses,
"Number of uses of and mask instructions optimized");
134STATISTIC(NumRetsDup,
"Number of return instructions duplicated");
135STATISTIC(NumDbgValueMoved,
"Number of debug value instructions moved");
136STATISTIC(NumSelectsExpanded,
"Number of selects turned into branches");
137STATISTIC(NumStoreExtractExposed,
"Number of store(extractelement) exposed");
141 cl::desc(
"Disable branch optimizations in CodeGenPrepare"));
145 cl::desc(
"Disable GC optimizations in CodeGenPrepare"));
150 cl::desc(
"Disable select to branch conversion."));
154 cl::desc(
"Address sinking in CGP using GEPs."));
158 cl::desc(
"Enable sinking and/cmp into branches."));
162 cl::desc(
"Disable store(extract) optimizations in CodeGenPrepare"));
166 cl::desc(
"Stress test store(extract) optimizations in CodeGenPrepare"));
170 cl::desc(
"Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in "
175 cl::desc(
"Stress test ext(promotable(ld)) -> promoted(ext(ld)) "
176 "optimization in CodeGenPrepare"));
180 cl::desc(
"Disable protection against removing loop preheaders"));
184 cl::desc(
"Use profile info to add section prefix for hot/cold functions"));
187 "profile-unknown-in-special-section",
cl::Hidden,
188 cl::desc(
"In profiling mode like sampleFDO, if a function doesn't have "
189 "profile, we cannot tell the function is cold for sure because "
190 "it may be a function newly added without ever being sampled. "
191 "With the flag enabled, compiler can put such profile unknown "
192 "functions into a special section, so runtime system can choose "
193 "to handle it in a different way than .text section, to save "
194 "RAM for example. "));
198 cl::desc(
"Use the basic-block-sections profile to determine the text "
199 "section prefix for hot functions. Functions with "
200 "basic-block-sections profile will be placed in `.text.hot` "
201 "regardless of their FDO profile info. Other functions won't be "
202 "impacted, i.e., their prefixes will be decided by FDO/sampleFDO "
207 cl::desc(
"Skip merging empty blocks if (frequency of empty block) / "
208 "(frequency of destination block) is greater than this ratio"));
212 cl::desc(
"Force store splitting no matter what the target query says."));
216 cl::desc(
"Enable merging of redundant sexts when one is dominating"
222 cl::desc(
"Disables combining addressing modes with different parts "
223 "in optimizeMemoryInst."));
227 cl::desc(
"Allow creation of Phis in Address sinking."));
231 cl::desc(
"Allow creation of selects in Address sinking."));
235 cl::desc(
"Allow combining of BaseReg field in Address sinking."));
239 cl::desc(
"Allow combining of BaseGV field in Address sinking."));
243 cl::desc(
"Allow combining of BaseOffs field in Address sinking."));
247 cl::desc(
"Allow combining of ScaledReg field in Address sinking."));
252 cl::desc(
"Enable splitting large offset of GEP."));
256 cl::desc(
"Enable ICMP_EQ to ICMP_S(L|G)T conversion."));
260 cl::desc(
"Enable BFI update verification for "
265 cl::desc(
"Enable converting phi types in CodeGenPrepare"));
269 cl::desc(
"Least BB number of huge function."));
274 cl::desc(
"Max number of address users to look at"));
278 cl::desc(
"Disable elimination of dead PHI nodes."));
306class TypePromotionTransaction;
308class CodeGenPrepare {
309 friend class CodeGenPrepareLegacyPass;
310 const TargetMachine *TM =
nullptr;
311 const TargetSubtargetInfo *SubtargetInfo =
nullptr;
312 const TargetLowering *TLI =
nullptr;
313 const TargetRegisterInfo *TRI =
nullptr;
314 const TargetTransformInfo *TTI =
nullptr;
315 const BasicBlockSectionsProfileReader *BBSectionsProfileReader =
nullptr;
316 const TargetLibraryInfo *TLInfo =
nullptr;
317 DomTreeUpdater *DTU =
nullptr;
318 LoopInfo *LI =
nullptr;
319 BlockFrequencyInfo *BFI;
320 BranchProbabilityInfo *BPI;
321 ProfileSummaryInfo *PSI =
nullptr;
332 ValueMap<Value *, WeakTrackingVH> SunkAddrs;
335 SetOfInstrs InsertedInsts;
339 InstrToOrigTy PromotedInsts;
342 SetOfInstrs RemovedInsts;
345 DenseMap<Value *, Instruction *> SeenChainsForSExt;
350 MapVector<AssertingVH<Value>,
355 SmallSet<AssertingVH<Value>, 2> NewGEPBases;
358 DenseMap<AssertingVH<GetElementPtrInst>,
int> LargeOffsetGEPID;
361 ValueToSExts ValToSExtendedUses;
367 const DataLayout *DL =
nullptr;
370 CodeGenPrepare() =
default;
371 CodeGenPrepare(
const TargetMachine *TM) : TM(TM){};
373 bool IsHugeFunc =
false;
379 SmallPtrSet<BasicBlock *, 32> FreshBBs;
381 void releaseMemory() {
383 InsertedInsts.clear();
384 PromotedInsts.clear();
391 template <
typename F>
392 void resetIteratorIfInvalidatedWhileCalling(BasicBlock *BB,
F f) {
396 Value *CurValue = &*CurInstIterator;
397 WeakTrackingVH IterHandle(CurValue);
403 if (IterHandle != CurValue) {
404 CurInstIterator = BB->
begin();
410 DominatorTree &getDT() {
return DTU->getDomTree(); }
412 void removeAllAssertingVHReferences(
Value *V);
413 bool eliminateAssumptions(Function &
F);
414 bool eliminateFallThrough(Function &
F);
415 bool eliminateMostlyEmptyBlocks(Function &
F,
bool &ResetLI);
416 BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB);
417 bool canMergeBlocks(
const BasicBlock *BB,
const BasicBlock *DestBB)
const;
418 bool eliminateMostlyEmptyBlock(BasicBlock *BB);
419 bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB,
421 bool makeBitReverse(Instruction &
I);
423 bool optimizeInst(Instruction *
I, ModifyDT &ModifiedDT);
424 bool optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
Type *AccessTy,
426 bool optimizeGatherScatterInst(Instruction *MemoryInst,
Value *Ptr);
427 bool optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
428 ModifyDT &ModifiedDT);
429 bool optimizeInlineAsmInst(CallInst *CS);
431 bool optimizeExt(Instruction *&
I);
432 bool optimizeExtUses(Instruction *
I);
433 bool optimizeLoadExt(LoadInst *Load);
434 bool optimizeShiftInst(BinaryOperator *BO);
435 bool optimizeFunnelShift(IntrinsicInst *Fsh);
436 bool optimizeSelectInst(SelectInst *SI);
437 bool optimizeShuffleVectorInst(ShuffleVectorInst *SVI);
438 bool optimizeSwitchType(SwitchInst *SI);
439 bool optimizeSwitchPhiConstants(SwitchInst *SI);
440 bool optimizeSwitchInst(SwitchInst *SI);
441 bool optimizeExtractElementInst(Instruction *Inst);
442 bool dupRetToEnableTailCallOpts(BasicBlock *BB, ModifyDT &ModifiedDT);
443 bool fixupDbgVariableRecord(DbgVariableRecord &
I);
444 bool fixupDbgVariableRecordsOnInst(Instruction &
I);
445 bool placeDbgValues(Function &
F);
446 bool placePseudoProbes(Function &
F);
447 bool canFormExtLd(
const SmallVectorImpl<Instruction *> &MovedExts,
448 LoadInst *&LI, Instruction *&Inst,
bool HasPromoted);
449 bool tryToPromoteExts(TypePromotionTransaction &TPT,
450 const SmallVectorImpl<Instruction *> &Exts,
451 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
452 unsigned CreatedInstsCost = 0);
453 bool mergeSExts(Function &
F);
454 bool splitLargeGEPOffsets();
455 bool optimizePhiType(PHINode *Inst, SmallPtrSetImpl<PHINode *> &Visited,
456 SmallPtrSetImpl<Instruction *> &DeletedInstrs);
457 bool optimizePhiTypes(Function &
F);
458 bool performAddressTypePromotion(
459 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
460 bool HasPromoted, TypePromotionTransaction &TPT,
461 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts);
462 bool splitBranchCondition(Function &
F);
463 bool simplifyOffsetableRelocate(GCStatepointInst &
I);
465 bool tryToSinkFreeOperands(Instruction *
I);
466 bool replaceMathCmpWithIntrinsic(BinaryOperator *BO,
Value *Arg0,
Value *Arg1,
468 bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT);
469 bool optimizeURem(Instruction *Rem);
470 bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
471 bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
472 bool unfoldPowerOf2Test(CmpInst *Cmp);
473 void verifyBFIUpdates(Function &
F);
474 bool _run(Function &
F);
481 CodeGenPrepareLegacyPass() : FunctionPass(ID) {}
485 StringRef getPassName()
const override {
return "CodeGen Prepare"; }
487 void getAnalysisUsage(AnalysisUsage &AU)
const override {
495 AU.
addRequired<BranchProbabilityInfoWrapperPass>();
503char CodeGenPrepareLegacyPass::ID = 0;
505bool CodeGenPrepareLegacyPass::runOnFunction(
Function &
F) {
508 auto TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
509 CodeGenPrepare CGP(TM);
510 CGP.DL = &
F.getDataLayout();
513 CGP.TRI = CGP.SubtargetInfo->getRegisterInfo();
514 CGP.TLInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
515 CGP.TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
516 CGP.LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
517 CGP.BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
518 CGP.BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
519 CGP.PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
521 getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
522 CGP.BBSectionsProfileReader = BBSPRWP ? &BBSPRWP->getBBSPR() :
nullptr;
523 DomTreeUpdater DTUpdater(
524 &getAnalysis<DominatorTreeWrapperPass>().
getDomTree(),
525 DomTreeUpdater::UpdateStrategy::Lazy);
526 CGP.DTU = &DTUpdater;
532 "Optimize for code generation",
false,
false)
544 return new CodeGenPrepareLegacyPass();
549 CodeGenPrepare CGP(TM);
562 DL = &
F.getDataLayout();
573 BBSectionsProfileReader =
576 DomTreeUpdater::UpdateStrategy::Lazy);
582 bool EverMadeChange =
false;
584 OptSize =
F.hasOptSize();
589 (void)
F.setSectionPrefix(
"hot");
594 if (
F.hasFnAttribute(Attribute::Hot) ||
596 (void)
F.setSectionPrefix(
"hot");
601 F.hasFnAttribute(Attribute::Cold))
602 (void)
F.setSectionPrefix(
"unlikely");
605 (void)
F.setSectionPrefix(
"unknown");
611 const DenseMap<unsigned int, unsigned int> &BypassWidths =
614 while (BB !=
nullptr) {
627 EverMadeChange |= eliminateAssumptions(
F);
629 auto resetLoopInfo = [
this]() {
636 bool ResetLI =
false;
637 EverMadeChange |= eliminateMostlyEmptyBlocks(
F, ResetLI);
642 EverMadeChange |= splitBranchCondition(
F);
648 EverMadeChange |=
Split;
654 assert(getDT().
verify(DominatorTree::VerificationLevel::Fast) &&
655 "Incorrect DominatorTree updates in CGP");
665 bool MadeChange =
true;
666 bool FuncIterated =
false;
676 if (FuncIterated && !FreshBBs.
contains(&BB))
679 ModifyDT ModifiedDTOnIteration = ModifyDT::NotModifyDT;
695 else if (FuncIterated)
700 if (ModifiedDTOnIteration != ModifyDT::NotModifyDT)
705 FuncIterated = IsHugeFunc;
708 MadeChange |= mergeSExts(
F);
709 if (!LargeOffsetGEPMap.
empty())
710 MadeChange |= splitLargeGEPOffsets();
711 MadeChange |= optimizePhiTypes(
F);
714 eliminateFallThrough(
F);
718 assert(getDT().
verify(DominatorTree::VerificationLevel::Fast) &&
719 "Incorrect DominatorTree updates in CGP");
726 for (Instruction *
I : RemovedInsts)
729 EverMadeChange |= MadeChange;
730 SeenChainsForSExt.
clear();
731 ValToSExtendedUses.clear();
732 RemovedInsts.clear();
733 LargeOffsetGEPMap.
clear();
734 LargeOffsetGEPID.
clear();
748 SmallSetVector<BasicBlock *, 8> WorkList;
749 for (BasicBlock &BB :
F) {
755 for (BasicBlock *Succ : Successors)
761 MadeChange |= !WorkList.
empty();
762 while (!WorkList.
empty()) {
768 for (BasicBlock *Succ : Successors)
778 if (EverMadeChange || MadeChange)
779 MadeChange |= eliminateFallThrough(
F);
781 EverMadeChange |= MadeChange;
786 for (BasicBlock &BB :
F)
787 for (Instruction &
I : BB)
790 for (
auto &
I : Statepoints)
791 EverMadeChange |= simplifyOffsetableRelocate(*
I);
796 EverMadeChange |= placeDbgValues(
F);
797 EverMadeChange |= placePseudoProbes(
F);
804 return EverMadeChange;
807bool CodeGenPrepare::eliminateAssumptions(Function &
F) {
808 bool MadeChange =
false;
809 for (BasicBlock &BB :
F) {
810 CurInstIterator = BB.begin();
811 while (CurInstIterator != BB.end()) {
816 Assume->eraseFromParent();
818 resetIteratorIfInvalidatedWhileCalling(&BB, [&]() {
829void CodeGenPrepare::removeAllAssertingVHReferences(
Value *V) {
830 LargeOffsetGEPMap.
erase(V);
831 NewGEPBases.
erase(V);
839 auto VecI = LargeOffsetGEPMap.
find(
GEP->getPointerOperand());
840 if (VecI == LargeOffsetGEPMap.
end())
843 auto &GEPVector = VecI->second;
846 if (GEPVector.empty())
847 LargeOffsetGEPMap.
erase(VecI);
851[[maybe_unused]]
void CodeGenPrepare::verifyBFIUpdates(Function &
F) {
852 DominatorTree NewDT(
F);
853 LoopInfo NewLI(NewDT);
854 BranchProbabilityInfo NewBPI(
F, NewLI, TLInfo);
855 BlockFrequencyInfo NewBFI(
F, NewBPI, NewLI);
856 NewBFI.verifyMatch(*BFI);
862bool CodeGenPrepare::eliminateFallThrough(Function &
F) {
864 SmallPtrSet<BasicBlock *, 8> Preds;
872 BasicBlock *SinglePred = BB->getSinglePredecessor();
875 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
888 FreshBBs.
insert(SinglePred);
896 for (
auto *Pred : Preds)
904BasicBlock *CodeGenPrepare::findDestBlockOfMergeableEmptyBlock(BasicBlock *BB) {
913 if (BBI != BB->
begin()) {
924 if (!canMergeBlocks(BB, DestBB))
934bool CodeGenPrepare::eliminateMostlyEmptyBlocks(Function &
F,
bool &ResetLI) {
935 SmallPtrSet<BasicBlock *, 16> Preheaders;
937 while (!LoopList.empty()) {
938 Loop *
L = LoopList.pop_back_val();
940 if (BasicBlock *Preheader =
L->getLoopPreheader())
941 Preheaders.
insert(Preheader);
945 bool MadeChange =
false;
957 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
959 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.
count(BB)))
962 ResetLI |= eliminateMostlyEmptyBlock(BB);
968bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB,
1019 SmallPtrSet<BasicBlock *, 16> SameIncomingValueBBs;
1024 if (DestBBPred == BB)
1028 return DestPN.getIncomingValueForBlock(BB) ==
1029 DestPN.getIncomingValueForBlock(DestBBPred);
1031 SameIncomingValueBBs.
insert(DestBBPred);
1037 if (SameIncomingValueBBs.
count(Pred))
1043 for (
auto *SameValueBB : SameIncomingValueBBs)
1044 if (SameValueBB->getUniquePredecessor() == Pred &&
1045 DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
1049 return !Limit || PredFreq <= *Limit;
1055bool CodeGenPrepare::canMergeBlocks(
const BasicBlock *BB,
1056 const BasicBlock *DestBB)
const {
1060 for (
const PHINode &PN : BB->
phis()) {
1061 for (
const User *U : PN.users()) {
1070 for (
unsigned I = 0,
E = UPN->getNumIncomingValues();
I !=
E; ++
I) {
1073 Insn->
getParent() != UPN->getIncomingBlock(
I))
1088 SmallPtrSet<const BasicBlock *, 16> BBPreds;
1091 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1092 BBPreds.
insert(BBPN->getIncomingBlock(i));
1100 if (BBPreds.
count(Pred)) {
1101 for (
const PHINode &PN : DestBB->
phis()) {
1102 const Value *V1 = PN.getIncomingValueForBlock(Pred);
1103 const Value *V2 = PN.getIncomingValueForBlock(BB);
1107 if (V2PN->getParent() == BB)
1108 V2 = V2PN->getIncomingValueForBlock(Pred);
1139bool CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
1149 if (SinglePred != DestBB) {
1150 assert(SinglePred == BB &&
1151 "Single predecessor not the same as predecessor");
1160 FreshBBs.
insert(SinglePred);
1161 FreshBBs.
erase(DestBB);
1169 for (PHINode &PN : DestBB->
phis()) {
1171 Value *InVal = PN.removeIncomingValue(BB,
false);
1176 if (InValPhi && InValPhi->
getParent() == BB) {
1185 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1186 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1189 PN.addIncoming(InVal, Pred);
1195 if (BI->hasMetadata(LLVMContext::MD_loop)) {
1203 SmallPtrSet<BasicBlock *, 8> SeenPreds;
1207 if (!PredOfDestBB.contains(Pred)) {
1208 if (SeenPreds.
insert(Pred).second)
1209 DTUpdates.
push_back({DominatorTree::Insert, Pred, DestBB});
1214 if (SeenPreds.
insert(Pred).second)
1215 DTUpdates.
push_back({DominatorTree::Delete, Pred, BB});
1217 DTUpdates.
push_back({DominatorTree::Delete, BB, DestBB});
1237 for (
auto *ThisRelocate : AllRelocateCalls) {
1238 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1239 ThisRelocate->getDerivedPtrIndex());
1240 RelocateIdxMap.
insert(std::make_pair(K, ThisRelocate));
1242 for (
auto &Item : RelocateIdxMap) {
1243 std::pair<unsigned, unsigned>
Key = Item.first;
1244 if (
Key.first ==
Key.second)
1249 auto BaseKey = std::make_pair(
Key.first,
Key.first);
1252 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1253 if (MaybeBase == RelocateIdxMap.
end())
1258 RelocateInstMap[MaybeBase->second].push_back(
I);
1266 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1269 if (!
Op ||
Op->getZExtValue() > 20)
1273 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1283 bool MadeChange =
false;
1290 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1291 &*R != RelocatedBase; ++R)
1295 RelocatedBase->
moveBefore(RI->getIterator());
1302 "Not relocating a derived object of the original base object");
1303 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1308 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1318 if (!Derived || Derived->getPointerOperand() !=
Base)
1327 "Should always have one since it's not a terminator");
1331 Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
1355 Value *ActualRelocatedBase = RelocatedBase;
1356 if (RelocatedBase->
getType() !=
Base->getType()) {
1357 ActualRelocatedBase =
1358 Builder.CreateBitCast(RelocatedBase,
Base->getType());
1360 Value *Replacement =
1361 Builder.CreateGEP(Derived->getSourceElementType(), ActualRelocatedBase,
1367 Value *ActualReplacement = Replacement;
1368 if (Replacement->
getType() != ToReplace->getType()) {
1370 Builder.CreateBitCast(Replacement, ToReplace->
getType());
1373 ToReplace->eraseFromParent();
1397bool CodeGenPrepare::simplifyOffsetableRelocate(GCStatepointInst &
I) {
1398 bool MadeChange =
false;
1400 for (
auto *U :
I.users())
1407 if (AllRelocateCalls.
size() < 2)
1412 MapVector<GCRelocateInst *, SmallVector<GCRelocateInst *, 0>> RelocateInstMap;
1414 if (RelocateInstMap.
empty())
1417 for (
auto &Item : RelocateInstMap)
1431 bool MadeChange =
false;
1434 Use &TheUse = UI.getUse();
1441 UserBB = PN->getIncomingBlock(TheUse);
1449 if (
User->isEHPad())
1459 if (UserBB == DefBB)
1463 CastInst *&InsertedCast = InsertedCasts[UserBB];
1465 if (!InsertedCast) {
1473 TheUse = InsertedCast;
1499 ASC->getDestAddressSpace()))
1554static std::optional<std::pair<Instruction *, Constant *>>
1557 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1558 return std::nullopt;
1561 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1562 return std::nullopt;
1566 return std::make_pair(IVInc, Step);
1567 return std::nullopt;
1580 return IVInc->first ==
I;
1584bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
1588 auto IsReplacableIVIncrement = [
this, &
Cmp](BinaryOperator *BO) {
1592 assert(L &&
"L should not be null after isIVIncrement()");
1607 return BO->
hasOneUse() && DT.dominates(
Cmp->getParent(),
L->getLoopLatch());
1609 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1632 if (BO->
getOpcode() == Instruction::Add &&
1633 IID == Intrinsic::usub_with_overflow) {
1640 for (Instruction &Iter : *
Cmp->getParent()) {
1643 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1648 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1651 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1652 if (BO->
getOpcode() != Instruction::Xor) {
1653 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1657 "Patterns with XOr should use the BO only in the compare");
1658 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1660 Cmp->eraseFromParent();
1670 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1678 B = ConstantInt::get(
B->getType(), 1);
1686 for (
User *U :
A->users()) {
1697bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp,
1698 ModifyDT &ModifiedDT) {
1699 bool EdgeCase =
false;
1701 BinaryOperator *
Add;
1706 A =
Add->getOperand(0);
1707 B =
Add->getOperand(1);
1713 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1719 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1722 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1723 Intrinsic::uadd_with_overflow))
1727 ModifiedDT = ModifyDT::ModifyInstDT;
1731bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
1732 ModifyDT &ModifiedDT) {
1739 ICmpInst::Predicate Pred =
Cmp->getPredicate();
1740 if (Pred == ICmpInst::ICMP_UGT) {
1742 Pred = ICmpInst::ICMP_ULT;
1746 B = ConstantInt::get(
B->getType(), 1);
1747 Pred = ICmpInst::ICMP_ULT;
1752 Pred = ICmpInst::ICMP_ULT;
1754 if (Pred != ICmpInst::ICMP_ULT)
1761 BinaryOperator *
Sub =
nullptr;
1762 for (User *U : CmpVariableOperand->
users()) {
1770 const APInt *CmpC, *AddC;
1782 Sub->hasNUsesOrMore(1)))
1788 if (
Sub->getParent() !=
Cmp->getParent() && !
Sub->hasOneUse())
1791 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1792 Cmp, Intrinsic::usub_with_overflow))
1796 ModifiedDT = ModifyDT::ModifyInstDT;
1803bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1816 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1822 Type *OpTy =
X->getType();
1830 if (Pred == ICmpInst::ICMP_EQ) {
1831 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1832 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1834 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1840 if (IsPowerOf2OrZeroTest ||
1851 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1860 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1863 Cmp->replaceAllUsesWith(NewCmp);
1883 bool UsedInPhiOrCurrentBlock =
any_of(Cmp->users(), [Cmp](
User *U) {
1884 return isa<PHINode>(U) ||
1885 cast<Instruction>(U)->getParent() == Cmp->getParent();
1890 if (UsedInPhiOrCurrentBlock && Cmp->getOperand(0)->getType()->isIntegerTy() &&
1891 Cmp->getOperand(0)->getType()->getScalarSizeInBits() >
1892 DL.getLargestLegalIntTypeSizeInBits())
1898 bool MadeChange =
false;
1901 Use &TheUse = UI.getUse();
1916 if (UserBB == DefBB)
1920 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1926 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1933 TheUse = InsertedCmp;
1939 if (Cmp->use_empty()) {
1940 Cmp->eraseFromParent();
1977 for (
User *U : Cmp->users()) {
1999 if (CmpBB != FalseBB)
2002 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
2016 for (
User *U : Cmp->users()) {
2018 BI->swapSuccessors();
2024 SI->swapProfMetadata();
2036 Value *Op0 = Cmp->getOperand(0);
2037 Value *Op1 = Cmp->getOperand(1);
2046 unsigned NumInspected = 0;
2049 if (++NumInspected > 128)
2057 if (GoodToSwap > 0) {
2058 Cmp->swapOperands();
2078 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
2081 auto [ClassVal, ClassTest] =
2087 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2091 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
2092 Cmp->replaceAllUsesWith(IsFPClass);
2100 Value *Incr, *RemAmt;
2105 Value *AddInst, *AddOffset;
2108 if (PN !=
nullptr) {
2110 AddOffset =
nullptr;
2119 if (PN !=
nullptr) {
2132 if (PN->getNumIncomingValues() != 2)
2137 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2141 if (!L->contains(Rem))
2145 if (!L->isLoopInvariant(RemAmt))
2149 if (AddOffset && !L->isLoopInvariant(AddOffset))
2170 AddInstOut = AddInst;
2171 AddOffsetOut = AddOffset;
2190 Value *AddOffset, *RemAmt, *AddInst;
2193 AddOffset, LoopIncrPN))
2218 assert(AddOffset &&
"We found an add but missing values");
2237 Builder.SetInsertPoint(LoopIncrPN);
2238 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2243 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2248 NewRem->
addIncoming(Start, L->getLoopPreheader());
2253 FreshBBs.
insert(L->getLoopLatch());
2264bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2270bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2274 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2277 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2280 if (unfoldPowerOf2Test(Cmp))
2301 SetOfInstrs &InsertedInsts) {
2304 assert(!InsertedInsts.count(AndI) &&
2305 "Attempting to optimize already optimized and instruction");
2306 (void)InsertedInsts;
2320 for (
auto *U : AndI->
users()) {
2328 if (!CmpC || !CmpC->
isZero())
2343 Use &TheUse = UI.getUse();
2361 TheUse = InsertedAnd;
2378 if (
User->getOpcode() != Instruction::And ||
2384 if ((Cimm & (Cimm + 1)).getBoolValue())
2398 bool MadeChange =
false;
2401 TruncE = TruncI->user_end();
2402 TruncUI != TruncE;) {
2404 Use &TruncTheUse = TruncUI.getUse();
2429 if (UserBB == TruncUserBB)
2433 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2435 if (!InsertedShift && !InsertedTrunc) {
2439 if (ShiftI->
getOpcode() == Instruction::AShr)
2441 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2444 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2452 TruncInsertPt.setHeadBit(
true);
2453 assert(TruncInsertPt != TruncUserBB->
end());
2457 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2458 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2462 TruncTheUse = InsertedTrunc;
2495 bool MadeChange =
false;
2498 Use &TheUse = UI.getUse();
2512 if (UserBB == DefBB) {
2540 if (!InsertedShift) {
2544 if (ShiftI->
getOpcode() == Instruction::AShr)
2546 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2549 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2557 TheUse = InsertedShift;
2605 unsigned SizeInBits = Ty->getScalarSizeInBits();
2606 if (Ty->isVectorTy())
2617 nullptr,
"cond.false");
2619 FreshBBs.
insert(CallBlock);
2626 SplitPt.setHeadBit(
true);
2628 nullptr,
"cond.end");
2630 FreshBBs.
insert(EndBlock);
2635 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2642 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2643 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2644 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2650 Builder.SetInsertPoint(EndBlock, EndBlock->
begin());
2651 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2661 ModifiedDT = ModifyDT::ModifyBBDT;
2665bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2669 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2677 for (
auto &Arg : CI->
args()) {
2682 if (!Arg->getType()->isPointerTy())
2684 APInt
Offset(
DL->getIndexSizeInBits(
2687 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2688 uint64_t Offset2 =
Offset.getLimitedValue();
2694 if (AllocaSize && AllocaSize->getKnownMinValue() >= MinSize + Offset2)
2712 MaybeAlign MIDestAlign =
MI->getDestAlign();
2713 if (!MIDestAlign || DestAlign > *MIDestAlign)
2714 MI->setDestAlignment(DestAlign);
2716 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2718 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2719 MTI->setSourceAlignment(SrcAlign);
2729 for (
auto &Arg : CI->
args()) {
2730 if (!Arg->getType()->isPointerTy())
2732 unsigned AS = Arg->getType()->getPointerAddressSpace();
2733 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2739 switch (
II->getIntrinsicID()) {
2742 case Intrinsic::assume:
2744 case Intrinsic::allow_runtime_check:
2745 case Intrinsic::allow_ubsan_check:
2746 case Intrinsic::experimental_widenable_condition: {
2750 if (
II->use_empty()) {
2751 II->eraseFromParent();
2755 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2760 case Intrinsic::objectsize:
2762 case Intrinsic::is_constant:
2764 case Intrinsic::aarch64_stlxr:
2765 case Intrinsic::aarch64_stxr: {
2774 InsertedInsts.insert(ExtVal);
2778 case Intrinsic::launder_invariant_group:
2779 case Intrinsic::strip_invariant_group: {
2780 Value *ArgVal =
II->getArgOperand(0);
2781 auto it = LargeOffsetGEPMap.
find(
II);
2782 if (it != LargeOffsetGEPMap.
end()) {
2786 auto GEPs = std::move(it->second);
2787 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2792 II->eraseFromParent();
2795 case Intrinsic::cttz:
2796 case Intrinsic::ctlz:
2800 case Intrinsic::fshl:
2801 case Intrinsic::fshr:
2802 return optimizeFunnelShift(
II);
2803 case Intrinsic::masked_gather:
2804 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2805 case Intrinsic::masked_scatter:
2806 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2807 case Intrinsic::masked_load:
2810 if (VT->getNumElements() == 1) {
2811 Value *PtrVal =
II->getArgOperand(0);
2813 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2818 case Intrinsic::masked_store:
2822 if (VT->getNumElements() == 1) {
2823 Value *PtrVal =
II->getArgOperand(1);
2825 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2830 case Intrinsic::umul_with_overflow:
2831 return optimizeMulWithOverflow(
II,
false, ModifiedDT);
2832 case Intrinsic::smul_with_overflow:
2833 return optimizeMulWithOverflow(
II,
true, ModifiedDT);
2836 SmallVector<Value *, 2> PtrOps;
2839 while (!PtrOps.
empty()) {
2842 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2856 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2858 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2868 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2869 if (!
F->getReturnType()->isPointerTy())
2872 GlobalVariable *UniformValue =
nullptr;
2873 for (
auto &BB : *
F) {
2878 else if (V != UniformValue)
2886 return UniformValue;
2889 if (
Callee->hasExactDefinition()) {
2890 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2891 bool MadeChange =
false;
2917 switch (
II->getIntrinsicID()) {
2918 case Intrinsic::memset:
2919 case Intrinsic::memcpy:
2920 case Intrinsic::memmove:
2928 if (Callee && TLInfo && TLInfo->
getLibFunc(*Callee, LF))
2930 case LibFunc_strcpy:
2931 case LibFunc_strncpy:
2932 case LibFunc_strcat:
2933 case LibFunc_strncat:
2974bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
2975 ModifyDT &ModifiedDT) {
2983 assert(LI->
getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2985 PHINode *PN =
nullptr;
2986 ExtractValueInst *EVI =
nullptr;
2987 BitCastInst *BCI =
nullptr;
3007 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
3013 return II->getIntrinsicID() == Intrinsic::lifetime_end;
3019 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
3021 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
3043 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
3050 auto MayBePermittedAsTailCall = [&](
const auto *CI) {
3067 MayBePermittedAsTailCall(CI)) {
3088 MayBePermittedAsTailCall(CI)) {
3095 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
3097 if (!VisitedBBs.
insert(Pred).second)
3099 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
3101 if (CI && CI->
use_empty() && MayBePermittedAsTailCall(CI)) {
3116 for (
auto const &TailCallBB : TailCallBBs) {
3129 ModifiedDT = ModifyDT::ModifyBBDT;
3138 for (
auto *CI : CallInsts) {
3139 for (
auto const *FakeUse : FakeUses) {
3140 auto *ClonedInst = FakeUse->clone();
3158struct ExtAddrMode :
public TargetLowering::AddrMode {
3159 Value *BaseReg =
nullptr;
3160 Value *ScaledReg =
nullptr;
3161 Value *OriginalValue =
nullptr;
3162 bool InBounds =
true;
3166 BaseRegField = 0x01,
3168 BaseOffsField = 0x04,
3169 ScaledRegField = 0x08,
3171 MultipleFields = 0xff
3174 ExtAddrMode() =
default;
3176 void print(raw_ostream &OS)
const;
3183 if (ScaledReg == From)
3187 FieldName
compare(
const ExtAddrMode &other) {
3190 if (BaseReg && other.
BaseReg &&
3192 return MultipleFields;
3193 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3194 return MultipleFields;
3197 return MultipleFields;
3200 if (InBounds != other.InBounds)
3201 return MultipleFields;
3204 unsigned Result = NoField;
3207 if (BaseGV != other.BaseGV)
3209 if (BaseOffs != other.BaseOffs)
3212 Result |= ScaledRegField;
3215 if (Scale && other.
Scale && Scale != other.
Scale)
3219 return MultipleFields;
3221 return static_cast<FieldName
>(
Result);
3231 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3242 case ScaledRegField:
3249 void SetCombinedField(FieldName
Field,
Value *V,
3250 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3255 case ExtAddrMode::BaseRegField:
3258 case ExtAddrMode::BaseGVField:
3261 assert(BaseReg ==
nullptr);
3265 case ExtAddrMode::ScaledRegField:
3270 for (
const ExtAddrMode &AM : AddrModes)
3276 case ExtAddrMode::BaseOffsField:
3279 assert(ScaledReg ==
nullptr);
3289static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3295#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3296void ExtAddrMode::print(raw_ostream &OS)
const {
3297 bool NeedPlus =
false;
3303 BaseGV->printAsOperand(OS,
false);
3308 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3313 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3314 BaseReg->printAsOperand(OS,
false);
3318 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3341class TypePromotionTransaction {
3345 class TypePromotionAction {
3353 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3355 virtual ~TypePromotionAction() =
default;
3362 virtual void undo() = 0;
3367 virtual void commit() {
3373 class InsertionHandler {
3382 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3385 bool HasPrevInstruction;
3389 InsertionHandler(Instruction *Inst) {
3397 if (HasPrevInstruction) {
3405 void insert(Instruction *Inst) {
3406 if (HasPrevInstruction) {
3418 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3423 class InstructionMoveBefore :
public TypePromotionAction {
3425 InsertionHandler Position;
3430 : TypePromotionAction(Inst), Position(Inst) {
3431 LLVM_DEBUG(
dbgs() <<
"Do: move: " << *Inst <<
"\nbefore: " << *Before
3437 void undo()
override {
3439 Position.insert(Inst);
3444 class OperandSetter :
public TypePromotionAction {
3453 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3454 : TypePromotionAction(Inst), Idx(Idx) {
3456 <<
"for:" << *Inst <<
"\n"
3457 <<
"with:" << *NewVal <<
"\n");
3463 void undo()
override {
3465 <<
"for: " << *Inst <<
"\n"
3466 <<
"with: " << *Origin <<
"\n");
3473 class OperandsHider :
public TypePromotionAction {
3475 SmallVector<Value *, 4> OriginalValues;
3479 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3482 OriginalValues.
reserve(NumOpnds);
3483 for (
unsigned It = 0; It < NumOpnds; ++It) {
3495 void undo()
override {
3497 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3503 class TruncBuilder :
public TypePromotionAction {
3510 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3512 Builder.SetCurrentDebugLocation(
DebugLoc());
3513 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3518 Value *getBuiltValue() {
return Val; }
3521 void undo()
override {
3524 IVal->eraseFromParent();
3529 class SExtBuilder :
public TypePromotionAction {
3536 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3537 : TypePromotionAction(InsertPt) {
3539 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3544 Value *getBuiltValue() {
return Val; }
3547 void undo()
override {
3550 IVal->eraseFromParent();
3555 class ZExtBuilder :
public TypePromotionAction {
3562 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3563 : TypePromotionAction(InsertPt) {
3565 Builder.SetCurrentDebugLocation(
DebugLoc());
3566 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3571 Value *getBuiltValue() {
return Val; }
3574 void undo()
override {
3577 IVal->eraseFromParent();
3582 class TypeMutator :
public TypePromotionAction {
3588 TypeMutator(Instruction *Inst,
Type *NewTy)
3589 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3590 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3596 void undo()
override {
3597 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3604 class UsesReplacer :
public TypePromotionAction {
3606 struct InstructionAndIdx {
3613 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3614 : Inst(Inst), Idx(Idx) {}
3620 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3630 UsesReplacer(Instruction *Inst,
Value *New)
3631 : TypePromotionAction(Inst),
New(
New) {
3632 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3635 for (Use &U : Inst->
uses()) {
3637 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3648 void undo()
override {
3650 for (InstructionAndIdx &Use : OriginalUses)
3651 Use.Inst->setOperand(
Use.Idx, Inst);
3656 for (DbgVariableRecord *DVR : DbgVariableRecords)
3657 DVR->replaceVariableLocationOp(New, Inst);
3662 class InstructionRemover :
public TypePromotionAction {
3664 InsertionHandler Inserter;
3668 OperandsHider Hider;
3671 UsesReplacer *Replacer =
nullptr;
3674 SetOfInstrs &RemovedInsts;
3681 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3682 Value *New =
nullptr)
3683 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3684 RemovedInsts(RemovedInsts) {
3686 Replacer =
new UsesReplacer(Inst, New);
3687 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3688 RemovedInsts.insert(Inst);
3695 ~InstructionRemover()
override {
delete Replacer; }
3697 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3698 InstructionRemover(
const InstructionRemover &other) =
delete;
3702 void undo()
override {
3703 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3704 Inserter.insert(Inst);
3708 RemovedInsts.erase(Inst);
3716 using ConstRestorationPt =
const TypePromotionAction *;
3718 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3719 : RemovedInsts(RemovedInsts) {}
3726 void rollback(ConstRestorationPt Point);
3729 ConstRestorationPt getRestorationPoint()
const;
3734 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3743 void mutateType(Instruction *Inst,
Type *NewTy);
3746 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3759 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3761 SetOfInstrs &RemovedInsts;
3766void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3768 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3769 Inst, Idx, NewVal));
3772void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3775 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3776 Inst, RemovedInsts, NewVal));
3779void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3782 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3785void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3787 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3790Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3791 std::unique_ptr<TruncBuilder> Ptr(
new TruncBuilder(Opnd, Ty));
3792 Value *Val = Ptr->getBuiltValue();
3793 Actions.push_back(std::move(Ptr));
3797Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3799 std::unique_ptr<SExtBuilder> Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3800 Value *Val = Ptr->getBuiltValue();
3801 Actions.push_back(std::move(Ptr));
3805Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3807 std::unique_ptr<ZExtBuilder> Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3808 Value *Val = Ptr->getBuiltValue();
3809 Actions.push_back(std::move(Ptr));
3813TypePromotionTransaction::ConstRestorationPt
3814TypePromotionTransaction::getRestorationPoint()
const {
3815 return !Actions.empty() ? Actions.back().get() :
nullptr;
3818bool TypePromotionTransaction::commit() {
3819 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3826void TypePromotionTransaction::rollback(
3827 TypePromotionTransaction::ConstRestorationPt Point) {
3828 while (!Actions.empty() && Point != Actions.back().get()) {
3829 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3839class AddressingModeMatcher {
3840 SmallVectorImpl<Instruction *> &AddrModeInsts;
3841 const TargetLowering &TLI;
3842 const TargetRegisterInfo &
TRI;
3843 const DataLayout &
DL;
3845 const std::function<
const DominatorTree &()> getDTFn;
3858 const SetOfInstrs &InsertedInsts;
3861 InstrToOrigTy &PromotedInsts;
3864 TypePromotionTransaction &TPT;
3867 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3871 bool IgnoreProfitability;
3874 bool OptSize =
false;
3876 ProfileSummaryInfo *PSI;
3877 BlockFrequencyInfo *BFI;
3879 AddressingModeMatcher(
3880 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3881 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3882 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3883 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3884 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3885 TypePromotionTransaction &TPT,
3886 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3887 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI)
3888 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3889 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3890 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3891 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3892 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI), BFI(BFI) {
3893 IgnoreProfitability =
false;
3905 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3906 SmallVectorImpl<Instruction *> &AddrModeInsts,
3907 const TargetLowering &TLI,
const LoopInfo &LI,
3908 const std::function<
const DominatorTree &()> getDTFn,
3909 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3910 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3911 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3912 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
3915 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3916 AccessTy, AS, MemoryInst, Result,
3917 InsertedInsts, PromotedInsts, TPT,
3918 LargeOffsetGEP, OptSize, PSI, BFI)
3926 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3928 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3929 bool *MovedAway =
nullptr);
3930 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3931 ExtAddrMode &AMBefore,
3932 ExtAddrMode &AMAfter);
3933 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3934 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3935 Value *PromotedOperand)
const;
3941class PhiNodeSetIterator {
3942 PhiNodeSet *
const Set;
3943 size_t CurrentIndex = 0;
3948 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3950 PhiNodeSetIterator &operator++();
3966 friend class PhiNodeSetIterator;
3968 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3969 using iterator = PhiNodeSetIterator;
3984 size_t FirstValidElement = 0;
3990 bool insert(PHINode *Ptr) {
3991 if (NodeMap.insert(std::make_pair(Ptr,
NodeList.
size())).second) {
4001 bool erase(PHINode *Ptr) {
4002 if (NodeMap.erase(Ptr)) {
4003 SkipRemovedElements(FirstValidElement);
4013 FirstValidElement = 0;
4019 if (FirstValidElement == 0)
4020 SkipRemovedElements(FirstValidElement);
4021 return PhiNodeSetIterator(
this, FirstValidElement);
4028 size_t size()
const {
return NodeMap.size(); }
4031 size_t count(PHINode *Ptr)
const {
return NodeMap.count(Ptr); }
4039 void SkipRemovedElements(
size_t &CurrentIndex) {
4041 auto it = NodeMap.find(NodeList[CurrentIndex]);
4044 if (it != NodeMap.end() && it->second == CurrentIndex)
4051PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
4054PHINode *PhiNodeSetIterator::operator*()
const {
4056 "PhiNodeSet access out of range");
4057 return Set->NodeList[CurrentIndex];
4060PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
4062 "PhiNodeSet access out of range");
4064 Set->SkipRemovedElements(CurrentIndex);
4068bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
4069 return CurrentIndex ==
RHS.CurrentIndex;
4072bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
4073 return !((*this) ==
RHS);
4079class SimplificationTracker {
4080 DenseMap<Value *, Value *> Storage;
4083 PhiNodeSet AllPhiNodes;
4085 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
4090 auto SV = Storage.
find(V);
4091 if (SV == Storage.
end())
4099 void ReplacePhi(PHINode *From, PHINode *To) {
4100 Value *OldReplacement = Get(From);
4101 while (OldReplacement != From) {
4104 OldReplacement = Get(From);
4106 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
4109 AllPhiNodes.erase(From);
4113 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
4115 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
4117 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
4119 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4121 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4123 void destroyNewNodes(
Type *CommonType) {
4126 for (
auto *
I : AllPhiNodes) {
4127 I->replaceAllUsesWith(Dummy);
4128 I->eraseFromParent();
4130 AllPhiNodes.clear();
4131 for (
auto *
I : AllSelectNodes) {
4132 I->replaceAllUsesWith(Dummy);
4133 I->eraseFromParent();
4135 AllSelectNodes.clear();
4140class AddressingModeCombiner {
4141 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4142 typedef std::pair<PHINode *, PHINode *> PHIPair;
4149 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4152 bool AllAddrModesTrivial =
true;
4155 Type *CommonType =
nullptr;
4157 const DataLayout &
DL;
4163 Value *CommonValue =
nullptr;
4166 AddressingModeCombiner(
const DataLayout &
DL,
Value *OriginalValue)
4167 :
DL(
DL), Original(OriginalValue) {}
4169 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4172 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4177 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4181 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4184 if (AddrModes.
empty()) {
4192 ExtAddrMode::FieldName ThisDifferentField =
4193 AddrModes[0].compare(NewAddrMode);
4194 if (DifferentField == ExtAddrMode::NoField)
4195 DifferentField = ThisDifferentField;
4196 else if (DifferentField != ThisDifferentField)
4197 DifferentField = ExtAddrMode::MultipleFields;
4200 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4203 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4208 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4213 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4214 !NewAddrMode.HasBaseReg);
4231 bool combineAddrModes() {
4233 if (AddrModes.
size() == 0)
4237 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4242 if (AllAddrModesTrivial)
4245 if (!addrModeCombiningAllowed())
4251 FoldAddrToValueMapping
Map;
4252 if (!initializeMap(Map))
4255 CommonValue = findCommon(Map);
4257 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4258 return CommonValue !=
nullptr;
4264 void eraseCommonValueIfDead() {
4265 if (CommonValue && CommonValue->
use_empty())
4267 CommonInst->eraseFromParent();
4275 bool initializeMap(FoldAddrToValueMapping &Map) {
4278 SmallVector<Value *, 2> NullValue;
4279 Type *IntPtrTy =
DL.getIntPtrType(AddrModes[0].OriginalValue->
getType());
4280 for (
auto &AM : AddrModes) {
4281 Value *DV = AM.GetFieldAsValue(DifferentField, IntPtrTy);
4284 if (CommonType && CommonType !=
Type)
4287 Map[AM.OriginalValue] = DV;
4292 assert(CommonType &&
"At least one non-null value must be!");
4293 for (
auto *V : NullValue)
4321 Value *findCommon(FoldAddrToValueMapping &Map) {
4329 SimplificationTracker
ST;
4334 InsertPlaceholders(Map, TraverseOrder, ST);
4337 FillPlaceholders(Map, TraverseOrder, ST);
4340 ST.destroyNewNodes(CommonType);
4345 unsigned PhiNotMatchedCount = 0;
4347 ST.destroyNewNodes(CommonType);
4351 auto *
Result =
ST.Get(
Map.find(Original)->second);
4353 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4354 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4361 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4362 SmallSetVector<PHIPair, 8> &Matcher,
4363 PhiNodeSet &PhiNodesToMatch) {
4366 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4369 SmallSet<PHIPair, 8> Visited;
4370 while (!WorkList.
empty()) {
4372 if (!Visited.
insert(Item).second)
4379 for (
auto *
B : Item.first->blocks()) {
4380 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4381 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4382 if (FirstValue == SecondValue)
4392 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4397 if (Matcher.
count({FirstPhi, SecondPhi}))
4402 if (MatchedPHIs.
insert(FirstPhi).second)
4403 Matcher.
insert({FirstPhi, SecondPhi});
4405 WorkList.
push_back({FirstPhi, SecondPhi});
4414 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4415 unsigned &PhiNotMatchedCount) {
4419 SmallSetVector<PHIPair, 8> Matched;
4420 SmallPtrSet<PHINode *, 8> WillNotMatch;
4421 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4422 while (PhiNodesToMatch.size()) {
4423 PHINode *
PHI = *PhiNodesToMatch.begin();
4426 WillNotMatch.
clear();
4430 bool IsMatched =
false;
4431 for (
auto &
P :
PHI->getParent()->phis()) {
4433 if (PhiNodesToMatch.count(&
P))
4435 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4445 for (
auto MV : Matched)
4446 ST.ReplacePhi(MV.first, MV.second);
4451 if (!AllowNewPhiNodes)
4454 PhiNotMatchedCount += WillNotMatch.
size();
4455 for (
auto *
P : WillNotMatch)
4456 PhiNodesToMatch.erase(
P);
4461 void FillPlaceholders(FoldAddrToValueMapping &Map,
4462 SmallVectorImpl<Value *> &TraverseOrder,
4463 SimplificationTracker &ST) {
4464 while (!TraverseOrder.
empty()) {
4466 assert(
Map.contains(Current) &&
"No node to fill!!!");
4472 auto *TrueValue = CurrentSelect->getTrueValue();
4473 assert(
Map.contains(TrueValue) &&
"No True Value!");
4474 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4475 auto *FalseValue = CurrentSelect->getFalseValue();
4476 assert(
Map.contains(FalseValue) &&
"No False Value!");
4477 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4484 assert(
Map.contains(PV) &&
"No predecessor Value!");
4485 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4496 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4497 SmallVectorImpl<Value *> &TraverseOrder,
4498 SimplificationTracker &ST) {
4501 "Address must be a Phi or Select node");
4504 while (!Worklist.
empty()) {
4507 if (
Map.contains(Current))
4518 CurrentSelect->getName(),
4519 CurrentSelect->getIterator(), CurrentSelect);
4523 Worklist.
push_back(CurrentSelect->getTrueValue());
4524 Worklist.
push_back(CurrentSelect->getFalseValue());
4532 ST.insertNewPhi(
PHI);
4538 bool addrModeCombiningAllowed() {
4541 switch (DifferentField) {
4544 case ExtAddrMode::BaseRegField:
4546 case ExtAddrMode::BaseGVField:
4548 case ExtAddrMode::BaseOffsField:
4550 case ExtAddrMode::ScaledRegField:
4560bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4565 return matchAddr(ScaleReg,
Depth);
4576 ExtAddrMode TestAddrMode =
AddrMode;
4580 TestAddrMode.
Scale += Scale;
4594 ConstantInt *CI =
nullptr;
4595 Value *AddLHS =
nullptr;
4599 TestAddrMode.InBounds =
false;
4616 auto GetConstantStep =
4617 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4620 return std::nullopt;
4623 return std::nullopt;
4631 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4632 return std::nullopt;
4634 return std::make_pair(IVInc->first, ConstantStep->getValue());
4635 return std::nullopt;
4650 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4657 APInt Step = IVStep->second;
4659 if (
Offset.isSignedIntN(64)) {
4660 TestAddrMode.InBounds =
false;
4662 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4667 getDTFn().
dominates(IVInc, MemoryInst)) {
4687 switch (
I->getOpcode()) {
4688 case Instruction::BitCast:
4689 case Instruction::AddrSpaceCast:
4691 if (
I->getType() ==
I->getOperand(0)->getType())
4693 return I->getType()->isIntOrPtrTy();
4694 case Instruction::PtrToInt:
4697 case Instruction::IntToPtr:
4700 case Instruction::Add:
4702 case Instruction::Mul:
4703 case Instruction::Shl:
4706 case Instruction::GetElementPtr:
4734class TypePromotionHelper {
4737 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4738 Instruction *ExtOpnd,
bool IsSExt) {
4739 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4740 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4744 if (It->second.getInt() == ExtTy)
4750 ExtTy = BothExtension;
4752 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4759 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4760 Instruction *Opnd,
bool IsSExt) {
4761 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4762 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4763 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4764 return It->second.getPointer();
4779 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4780 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4784 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4797 static Value *promoteOperandForTruncAndAnyExt(
4798 Instruction *Ext, TypePromotionTransaction &TPT,
4799 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4800 SmallVectorImpl<Instruction *> *Exts,
4801 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4812 static Value *promoteOperandForOther(Instruction *Ext,
4813 TypePromotionTransaction &TPT,
4814 InstrToOrigTy &PromotedInsts,
4815 unsigned &CreatedInstsCost,
4816 SmallVectorImpl<Instruction *> *Exts,
4817 SmallVectorImpl<Instruction *> *Truncs,
4818 const TargetLowering &TLI,
bool IsSExt);
4821 static Value *signExtendOperandForOther(
4822 Instruction *Ext, TypePromotionTransaction &TPT,
4823 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4824 SmallVectorImpl<Instruction *> *Exts,
4825 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4826 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4827 Exts, Truncs, TLI,
true);
4831 static Value *zeroExtendOperandForOther(
4832 Instruction *Ext, TypePromotionTransaction &TPT,
4833 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4834 SmallVectorImpl<Instruction *> *Exts,
4835 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4836 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4837 Exts, Truncs, TLI,
false);
4842 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4843 InstrToOrigTy &PromotedInsts,
4844 unsigned &CreatedInstsCost,
4845 SmallVectorImpl<Instruction *> *Exts,
4846 SmallVectorImpl<Instruction *> *Truncs,
4847 const TargetLowering &TLI);
4858 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4859 const TargetLowering &TLI,
4860 const InstrToOrigTy &PromotedInsts);
4865bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4866 Type *ConsideredExtType,
4867 const InstrToOrigTy &PromotedInsts,
4887 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4888 (IsSExt && BinOp->hasNoSignedWrap())))
4892 if ((Inst->
getOpcode() == Instruction::And ||
4897 if (Inst->
getOpcode() == Instruction::Xor) {
4900 if (!Cst->getValue().isAllOnes())
4909 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4919 if (ExtInst->hasOneUse()) {
4921 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4954 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4967TypePromotionHelper::Action TypePromotionHelper::getAction(
4968 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4969 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
4971 "Unexpected instruction type");
4978 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4991 return promoteOperandForTruncAndAnyExt;
4997 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
5000Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
5001 Instruction *SExt, TypePromotionTransaction &TPT,
5002 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5003 SmallVectorImpl<Instruction *> *Exts,
5004 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
5008 Value *ExtVal = SExt;
5009 bool HasMergedNonFreeExt =
false;
5013 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
5016 TPT.replaceAllUsesWith(SExt, ZExt);
5017 TPT.eraseInstruction(SExt);
5022 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
5024 CreatedInstsCost = 0;
5028 TPT.eraseInstruction(SExtOpnd);
5036 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
5044 TPT.eraseInstruction(ExtInst, NextVal);
5048Value *TypePromotionHelper::promoteOperandForOther(
5049 Instruction *Ext, TypePromotionTransaction &TPT,
5050 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5051 SmallVectorImpl<Instruction *> *Exts,
5052 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
5057 CreatedInstsCost = 0;
5063 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
5066 ITrunc->moveAfter(ExtOpnd);
5071 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
5074 TPT.setOperand(Ext, 0, ExtOpnd);
5084 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
5086 TPT.mutateType(ExtOpnd, Ext->
getType());
5088 TPT.replaceAllUsesWith(Ext, ExtOpnd);
5095 !shouldExtOperand(ExtOpnd,
OpIdx)) {
5104 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
5106 TPT.setOperand(ExtOpnd,
OpIdx, ConstantInt::get(Ext->
getType(), CstVal));
5117 Value *ValForExtOpnd = IsSExt
5118 ? TPT.createSExt(ExtOpnd, Opnd, Ext->
getType())
5119 : TPT.createZExt(ExtOpnd, Opnd, Ext->
getType());
5120 TPT.setOperand(ExtOpnd,
OpIdx, ValForExtOpnd);
5122 if (!InstForExtOpnd)
5128 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5131 TPT.eraseInstruction(Ext);
5143bool AddressingModeMatcher::isPromotionProfitable(
5144 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5145 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5150 if (NewCost > OldCost)
5152 if (NewCost < OldCost)
5171bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5183 case Instruction::PtrToInt:
5186 case Instruction::IntToPtr: {
5194 case Instruction::BitCast:
5204 case Instruction::AddrSpaceCast: {
5212 case Instruction::Add: {
5215 ExtAddrMode BackupAddrMode =
AddrMode;
5216 unsigned OldSize = AddrModeInsts.
size();
5221 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5222 TPT.getRestorationPoint();
5226 int First = 0, Second = 1;
5237 AddrModeInsts.
resize(OldSize);
5238 TPT.rollback(LastKnownGood);
5248 AddrModeInsts.
resize(OldSize);
5249 TPT.rollback(LastKnownGood);
5255 case Instruction::Mul:
5256 case Instruction::Shl: {
5260 if (!
RHS ||
RHS->getBitWidth() > 64)
5262 int64_t Scale = Opcode == Instruction::Shl
5263 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5264 :
RHS->getSExtValue();
5268 case Instruction::GetElementPtr: {
5271 int VariableOperand = -1;
5272 unsigned VariableScale = 0;
5274 int64_t ConstantOffset = 0;
5276 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5278 const StructLayout *SL =
DL.getStructLayout(STy);
5289 if (ConstantInt *CI =
5291 const APInt &CVal = CI->
getValue();
5298 if (VariableOperand != -1)
5302 VariableOperand = i;
5303 VariableScale = TypeSize;
5310 if (VariableOperand == -1) {
5311 AddrMode.BaseOffs += ConstantOffset;
5317 AddrMode.BaseOffs -= ConstantOffset;
5321 ConstantOffset > 0) {
5334 BasicBlock *Parent = BaseI ? BaseI->getParent()
5335 : &
GEP->getFunction()->getEntryBlock();
5337 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5345 ExtAddrMode BackupAddrMode =
AddrMode;
5346 unsigned OldSize = AddrModeInsts.
size();
5349 AddrMode.BaseOffs += ConstantOffset;
5358 AddrModeInsts.
resize(OldSize);
5366 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5371 AddrModeInsts.
resize(OldSize);
5376 AddrMode.BaseOffs += ConstantOffset;
5377 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5378 VariableScale,
Depth)) {
5381 AddrModeInsts.
resize(OldSize);
5388 case Instruction::SExt:
5389 case Instruction::ZExt: {
5396 TypePromotionHelper::Action TPH =
5397 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5401 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5402 TPT.getRestorationPoint();
5403 unsigned CreatedInstsCost = 0;
5405 Value *PromotedOperand =
5406 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5421 assert(PromotedOperand &&
5422 "TypePromotionHelper should have filtered out those cases");
5424 ExtAddrMode BackupAddrMode =
AddrMode;
5425 unsigned OldSize = AddrModeInsts.
size();
5427 if (!matchAddr(PromotedOperand,
Depth) ||
5432 !isPromotionProfitable(CreatedInstsCost,
5433 ExtCost + (AddrModeInsts.
size() - OldSize),
5436 AddrModeInsts.
resize(OldSize);
5437 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5438 TPT.rollback(LastKnownGood);
5443 AddrMode.replaceWith(Ext, PromotedOperand);
5446 case Instruction::Call:
5448 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5464bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5467 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5468 TPT.getRestorationPoint();
5492 ExtAddrMode BackupAddrMode =
AddrMode;
5493 unsigned OldSize = AddrModeInsts.
size();
5496 bool MovedAway =
false;
5497 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5505 if (
I->hasOneUse() ||
5506 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5513 AddrModeInsts.
resize(OldSize);
5514 TPT.rollback(LastKnownGood);
5517 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5519 TPT.rollback(LastKnownGood);
5546 TPT.rollback(LastKnownGood);
5565 if (OpInfo.CallOperandVal == OpVal &&
5567 !OpInfo.isIndirect))
5583 if (!ConsideredInsts.
insert(
I).second)
5591 for (
Use &U :
I->uses()) {
5599 MemoryUses.push_back({&U, LI->getType()});
5606 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5613 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5620 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5630 if (!
find(PtrOps, U.get()))
5633 MemoryUses.push_back({&U, AccessTy});
5638 if (CI->hasFnAttr(Attribute::Cold)) {
5656 PSI, BFI, SeenInsts))
5667 unsigned SeenInsts = 0;
5670 PSI, BFI, SeenInsts);
5678bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5680 Value *KnownLive2) {
5682 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5723bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5724 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5725 if (IgnoreProfitability)
5743 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5744 ScaledReg =
nullptr;
5748 if (!BaseReg && !ScaledReg)
5769 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5772 Type *AddressAccessTy = Pair.second;
5773 unsigned AS =
Address->getType()->getPointerAddressSpace();
5779 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5781 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5782 TPT.getRestorationPoint();
5783 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5784 AddressAccessTy, AS, UserI, Result,
5785 InsertedInsts, PromotedInsts, TPT,
5786 LargeOffsetGEP, OptSize, PSI, BFI);
5787 Matcher.IgnoreProfitability =
true;
5795 TPT.rollback(LastKnownGood);
5801 MatchedAddrModeInsts.
clear();
5811 return I->getParent() != BB;
5827 return std::next(AddrInst->getIterator());
5838 Earliest = UserInst;
5863bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5864 Type *AccessTy,
unsigned AddrSpace) {
5869 SmallVector<Value *, 8> worklist;
5870 SmallPtrSet<Value *, 16> Visited;
5876 bool PhiOrSelectSeen =
false;
5877 SmallVector<Instruction *, 16> AddrModeInsts;
5878 AddressingModeCombiner AddrModes(*
DL, Addr);
5879 TypePromotionTransaction TPT(RemovedInsts);
5880 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5881 TPT.getRestorationPoint();
5882 while (!worklist.
empty()) {
5894 if (!Visited.
insert(V).second)
5900 PhiOrSelectSeen =
true;
5907 PhiOrSelectSeen =
true;
5914 AddrModeInsts.
clear();
5915 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5920 auto getDTFn = [
this]() ->
const DominatorTree & {
return getDT(); };
5921 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5922 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5923 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5926 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5931 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5932 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5935 NewAddrMode.OriginalValue =
V;
5936 if (!AddrModes.addNewAddrMode(NewAddrMode))
5943 if (!AddrModes.combineAddrModes()) {
5944 TPT.rollback(LastKnownGood);
5950 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5956 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5970 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
5992 <<
" for " << *MemoryInst <<
"\n");
5996 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6002 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
6004 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6006 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6013 <<
" for " << *MemoryInst <<
"\n");
6014 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
6025 if (ResultPtr ||
AddrMode.Scale != 1)
6046 GlobalValue *BaseGV =
AddrMode.BaseGV;
6047 if (BaseGV !=
nullptr) {
6052 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
6061 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
6062 if (!ResultPtr &&
AddrMode.BaseReg) {
6066 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
6067 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
6076 }
else if (!ResultPtr) {
6089 if (
V->getType() != IntPtrTy)
6090 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6098 if (
V->getType() == IntPtrTy) {
6103 "We can't transform if ScaledReg is too narrow");
6104 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6108 V = Builder.CreateMul(
6111 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6122 if (ResultPtr->
getType() != I8PtrTy)
6123 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6124 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6137 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6139 SunkAddr = ResultPtr;
6141 if (ResultPtr->
getType() != I8PtrTy)
6142 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6143 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6150 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6156 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
6158 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6160 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6170 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6171 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6172 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6174 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6178 <<
" for " << *MemoryInst <<
"\n");
6189 if (
V->getType()->isPointerTy())
6190 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6191 if (
V->getType() != IntPtrTy)
6192 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6199 if (
V->getType() == IntPtrTy) {
6201 }
else if (
V->getType()->isPointerTy()) {
6202 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6205 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6214 I->eraseFromParent();
6218 V = Builder.CreateMul(
6221 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6227 GlobalValue *BaseGV =
AddrMode.BaseGV;
6228 if (BaseGV !=
nullptr) {
6231 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6235 Value *
V = Builder.CreatePtrToInt(BaseGVPtr, IntPtrTy,
"sunkaddr");
6237 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6246 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6254 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6260 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6265 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6266 RecursivelyDeleteTriviallyDeadInstructions(
6267 Repl, TLInfo, nullptr,
6268 [&](Value *V) { removeAllAssertingVHReferences(V); });
6292bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6298 if (!
GEP->hasIndices())
6306 SmallVector<Value *, 2>
Ops(
GEP->operands());
6308 bool RewriteGEP =
false;
6317 unsigned FinalIndex =
Ops.size() - 1;
6322 for (
unsigned i = 1; i < FinalIndex; ++i) {
6327 C =
C->getSplatValue();
6329 if (!CI || !CI->
isZero())
6336 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6340 if (!
C || !
C->isZero()) {
6341 Ops[FinalIndex] =
V;
6349 if (!RewriteGEP &&
Ops.size() == 2)
6356 Type *SourceTy =
GEP->getSourceElementType();
6357 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6361 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6362 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6363 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6373 if (
Ops.size() != 2) {
6383 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6397 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6398 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6401 Intrinsic::masked_gather) {
6405 Intrinsic::masked_scatter);
6420 Ptr, TLInfo,
nullptr,
6421 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6432 if (
I->hasNUsesOrMore(3))
6435 for (
User *U :
I->users()) {
6437 if (!Extract || Extract->getNumIndices() != 1)
6440 unsigned Index = Extract->getIndices()[0];
6442 MulExtract = Extract;
6443 else if (Index == 1)
6444 OverflowExtract = Extract;
6471bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
6472 ModifyDT &ModifiedDT) {
6479 ExtractValueInst *MulExtract =
nullptr, *OverflowExtract =
nullptr;
6484 InsertedInsts.insert(
I);
6495 OverflowEntryBB->
takeName(
I->getParent());
6501 NoOverflowBB->
moveAfter(OverflowEntryBB);
6509 Value *LoLHS = Builder.CreateTrunc(
LHS, LegalTy,
"lo.lhs");
6510 Value *HiLHS = Builder.CreateLShr(
LHS, VTHalfBitWidth,
"lhs.lsr");
6511 HiLHS = Builder.CreateTrunc(HiLHS, LegalTy,
"hi.lhs");
6514 Value *LoRHS = Builder.CreateTrunc(
RHS, LegalTy,
"lo.rhs");
6515 Value *HiRHS = Builder.CreateLShr(
RHS, VTHalfBitWidth,
"rhs.lsr");
6516 HiRHS = Builder.CreateTrunc(HiRHS, LegalTy,
"hi.rhs");
6518 Value *IsAnyBitTrue;
6521 Builder.CreateAShr(LoLHS, VTHalfBitWidth - 1,
"sign.lo.lhs");
6523 Builder.CreateAShr(LoRHS, VTHalfBitWidth - 1,
"sign.lo.rhs");
6524 Value *XorLHS = Builder.CreateXor(HiLHS, SignLoLHS);
6525 Value *XorRHS = Builder.CreateXor(HiRHS, SignLoRHS);
6526 Value *
Or = Builder.CreateOr(XorLHS, XorRHS,
"or.lhs.rhs");
6527 IsAnyBitTrue = Builder.CreateCmp(ICmpInst::ICMP_NE,
Or,
6528 ConstantInt::getNullValue(
Or->getType()));
6530 Value *CmpLHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiLHS,
6531 ConstantInt::getNullValue(LegalTy));
6532 Value *CmpRHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiRHS,
6533 ConstantInt::getNullValue(LegalTy));
6534 IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS,
"or.lhs.rhs");
6536 Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
6539 Builder.SetInsertPoint(NoOverflowBB);
6540 Value *ExtLoLHS, *ExtLoRHS;
6542 ExtLoLHS = Builder.CreateSExt(LoLHS, Ty,
"lo.lhs.ext");
6543 ExtLoRHS = Builder.CreateSExt(LoRHS, Ty,
"lo.rhs.ext");
6545 ExtLoLHS = Builder.CreateZExt(LoLHS, Ty,
"lo.lhs.ext");
6546 ExtLoRHS = Builder.CreateZExt(LoRHS, Ty,
"lo.rhs.ext");
6549 Value *
Mul = Builder.CreateMul(ExtLoLHS, ExtLoRHS,
"mul.overflow.no");
6554 OverflowResBB->
setName(
"overflow.res");
6557 Builder.CreateBr(OverflowResBB);
6565 PHINode *OverflowResPHI = Builder.CreatePHI(Ty, 2),
6567 Builder.CreatePHI(IntegerType::getInt1Ty(
I->getContext()), 2);
6579 if (OverflowExtract) {
6580 OverflowExtract->replaceAllUsesWith(OverflowFlagPHI);
6581 OverflowExtract->eraseFromParent();
6586 I->removeFromParent();
6588 I->insertInto(OverflowBB, OverflowBB->
end());
6589 Builder.SetInsertPoint(OverflowBB, OverflowBB->
end());
6591 Value *OverflowFlag = Builder.CreateExtractValue(
I, {1},
"overflow.flag");
6592 Builder.CreateBr(OverflowResBB);
6596 OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
6598 DTU->
applyUpdates({{DominatorTree::Insert, OverflowEntryBB, OverflowBB},
6599 {DominatorTree::Insert, OverflowEntryBB, NoOverflowBB},
6600 {DominatorTree::Insert, NoOverflowBB, OverflowResBB},
6601 {DominatorTree::Delete, OverflowEntryBB, OverflowResBB},
6602 {DominatorTree::Insert, OverflowBB, OverflowResBB}});
6604 ModifiedDT = ModifyDT::ModifyBBDT;
6610bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6611 bool MadeChange =
false;
6613 const TargetRegisterInfo *
TRI =
6618 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6624 OpInfo.isIndirect) {
6626 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6689bool CodeGenPrepare::tryToPromoteExts(
6690 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6691 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6692 unsigned CreatedInstsCost) {
6693 bool Promoted =
false;
6696 for (
auto *
I : Exts) {
6711 TypePromotionHelper::Action TPH =
6712 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6721 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6722 TPT.getRestorationPoint();
6723 SmallVector<Instruction *, 4> NewExts;
6724 unsigned NewCreatedInstsCost = 0;
6727 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6728 &NewExts,
nullptr, *TLI);
6730 "TypePromotionHelper should have filtered out those cases");
6740 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6743 TotalCreatedInstsCost =
6744 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6746 (TotalCreatedInstsCost > 1 ||
6748 (ExtCost == 0 && NewExts.
size() > 1))) {
6752 TPT.rollback(LastKnownGood);
6757 SmallVector<Instruction *, 2> NewlyMovedExts;
6758 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6759 bool NewPromoted =
false;
6760 for (
auto *ExtInst : NewlyMovedExts) {
6770 ProfitablyMovedExts.
push_back(MovedExt);
6777 TPT.rollback(LastKnownGood);
6788bool CodeGenPrepare::mergeSExts(Function &
F) {
6790 for (
auto &Entry : ValToSExtendedUses) {
6791 SExts &Insts =
Entry.second;
6793 for (Instruction *Inst : Insts) {
6797 bool inserted =
false;
6798 for (
auto &Pt : CurPts) {
6801 RemovedInsts.insert(Pt);
6802 Pt->removeFromParent();
6813 RemovedInsts.insert(Inst);
6820 CurPts.push_back(Inst);
6862bool CodeGenPrepare::splitLargeGEPOffsets() {
6864 for (
auto &Entry : LargeOffsetGEPMap) {
6866 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6867 &LargeOffsetGEPs =
Entry.second;
6868 auto compareGEPOffset =
6869 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6870 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6871 if (
LHS.first ==
RHS.first)
6873 if (
LHS.second !=
RHS.second)
6874 return LHS.second <
RHS.second;
6875 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6878 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6881 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6883 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6884 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6885 Value *NewBaseGEP =
nullptr;
6887 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6888 GetElementPtrInst *
GEP) {
6889 LLVMContext &Ctx =
GEP->getContext();
6890 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6892 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6904 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), &getDT(), LI);
6907 NewBaseInsertPt = std::next(BaseI->getIterator());
6914 IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
6920 NewBaseGEP = OldBase;
6921 if (NewBaseGEP->
getType() != I8PtrTy)
6922 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6924 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6925 NewGEPBases.
insert(NewBaseGEP);
6931 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6932 BaseOffset = PreferBase;
6935 createNewBase(BaseOffset, OldBase, BaseGEP);
6938 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6939 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6940 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6941 int64_t
Offset = LargeOffsetGEP->second;
6942 if (
Offset != BaseOffset) {
6949 GEP->getResultElementType(),
6950 GEP->getAddressSpace())) {
6956 NewBaseGEP =
nullptr;
6961 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6966 createNewBase(BaseOffset, OldBase,
GEP);
6970 Value *NewGEP = NewBaseGEP;
6971 if (
Offset != BaseOffset) {
6974 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6978 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6979 GEP->eraseFromParent();
6986bool CodeGenPrepare::optimizePhiType(
6987 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
6988 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
6993 Type *PhiTy =
I->getType();
6994 Type *ConvertTy =
nullptr;
6996 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6999 SmallVector<Instruction *, 4> Worklist;
7001 SmallPtrSet<PHINode *, 4> PhiNodes;
7002 SmallPtrSet<ConstantData *, 4>
Constants;
7005 SmallPtrSet<Instruction *, 4> Defs;
7006 SmallPtrSet<Instruction *, 4>
Uses;
7012 bool AnyAnchored =
false;
7014 while (!Worklist.
empty()) {
7019 for (
Value *V :
Phi->incoming_values()) {
7021 if (!PhiNodes.
count(OpPhi)) {
7022 if (!Visited.
insert(OpPhi).second)
7028 if (!OpLoad->isSimple())
7030 if (Defs.
insert(OpLoad).second)
7033 if (Defs.
insert(OpEx).second)
7037 ConvertTy = OpBC->getOperand(0)->getType();
7038 if (OpBC->getOperand(0)->getType() != ConvertTy)
7040 if (Defs.
insert(OpBC).second) {
7053 for (User *V :
II->users()) {
7055 if (!PhiNodes.
count(OpPhi)) {
7056 if (Visited.
count(OpPhi))
7063 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
7065 Uses.insert(OpStore);
7068 ConvertTy = OpBC->getType();
7069 if (OpBC->getType() != ConvertTy)
7073 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
7080 if (!ConvertTy || !AnyAnchored || PhiTy == ConvertTy ||
7084 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
7085 << *ConvertTy <<
"\n");
7090 for (ConstantData *
C : Constants)
7092 for (Instruction *
D : Defs) {
7094 ValMap[
D] =
D->getOperand(0);
7098 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
7101 for (PHINode *Phi : PhiNodes)
7103 Phi->getName() +
".tc",
Phi->getIterator());
7105 for (PHINode *Phi : PhiNodes) {
7107 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
7109 Phi->getIncomingBlock(i));
7113 for (Instruction *U :
Uses) {
7118 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
7128bool CodeGenPrepare::optimizePhiTypes(Function &
F) {
7133 SmallPtrSet<PHINode *, 4> Visited;
7134 SmallPtrSet<Instruction *, 4> DeletedInstrs;
7138 for (
auto &Phi : BB.
phis())
7139 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
7142 for (
auto *
I : DeletedInstrs) {
7144 I->eraseFromParent();
7152bool CodeGenPrepare::canFormExtLd(
7153 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
7154 Instruction *&Inst,
bool HasPromoted) {
7155 for (
auto *MovedExtInst : MovedExts) {
7158 Inst = MovedExtInst;
7210bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7211 bool AllowPromotionWithoutCommonHeader =
false;
7216 *Inst, AllowPromotionWithoutCommonHeader);
7217 TypePromotionTransaction TPT(RemovedInsts);
7218 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7219 TPT.getRestorationPoint();
7221 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7224 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7227 LoadInst *LI =
nullptr;
7232 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7233 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7238 Inst = ExtFedByLoad;
7243 if (ATPConsiderable &&
7244 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7245 HasPromoted, TPT, SpeculativelyMovedExts))
7248 TPT.rollback(LastKnownGood);
7257bool CodeGenPrepare::performAddressTypePromotion(
7258 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7259 bool HasPromoted, TypePromotionTransaction &TPT,
7260 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7261 bool Promoted =
false;
7262 SmallPtrSet<Instruction *, 1> UnhandledExts;
7263 bool AllSeenFirst =
true;
7264 for (
auto *
I : SpeculativelyMovedExts) {
7265 Value *HeadOfChain =
I->getOperand(0);
7266 auto AlreadySeen = SeenChainsForSExt.
find(HeadOfChain);
7269 if (AlreadySeen != SeenChainsForSExt.
end()) {
7270 if (AlreadySeen->second !=
nullptr)
7271 UnhandledExts.
insert(AlreadySeen->second);
7272 AllSeenFirst =
false;
7276 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7277 SpeculativelyMovedExts.size() == 1)) {
7281 for (
auto *
I : SpeculativelyMovedExts) {
7282 Value *HeadOfChain =
I->getOperand(0);
7283 SeenChainsForSExt[HeadOfChain] =
nullptr;
7284 ValToSExtendedUses[HeadOfChain].push_back(
I);
7287 Inst = SpeculativelyMovedExts.pop_back_val();
7292 for (
auto *
I : SpeculativelyMovedExts) {
7293 Value *HeadOfChain =
I->getOperand(0);
7294 SeenChainsForSExt[HeadOfChain] = Inst;
7299 if (!AllSeenFirst && !UnhandledExts.
empty())
7300 for (
auto *VisitedSExt : UnhandledExts) {
7301 if (RemovedInsts.count(VisitedSExt))
7303 TypePromotionTransaction TPT(RemovedInsts);
7305 SmallVector<Instruction *, 2> Chains;
7307 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7311 for (
auto *
I : Chains) {
7312 Value *HeadOfChain =
I->getOperand(0);
7314 SeenChainsForSExt[HeadOfChain] =
nullptr;
7315 ValToSExtendedUses[HeadOfChain].push_back(
I);
7321bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7326 Value *Src =
I->getOperand(0);
7327 if (Src->hasOneUse())
7339 bool DefIsLiveOut =
false;
7340 for (User *U :
I->users()) {
7345 if (UserBB == DefBB)
7347 DefIsLiveOut =
true;
7354 for (User *U : Src->users()) {
7357 if (UserBB == DefBB)
7366 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7368 bool MadeChange =
false;
7369 for (Use &U : Src->uses()) {
7374 if (UserBB == DefBB)
7378 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7380 if (!InsertedTrunc) {
7383 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7385 InsertedInsts.insert(InsertedTrunc);
7448bool CodeGenPrepare::optimizeLoadExt(LoadInst *Load) {
7449 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7453 if (
Load->hasOneUse() &&
7459 SmallVector<Instruction *, 8> WorkList;
7460 SmallPtrSet<Instruction *, 16> Visited;
7461 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7462 SmallVector<Instruction *, 8> DropFlags;
7463 for (
auto *U :
Load->users())
7475 while (!WorkList.
empty()) {
7479 if (!Visited.
insert(
I).second)
7484 for (
auto *U :
Phi->users())
7489 switch (
I->getOpcode()) {
7490 case Instruction::And: {
7494 APInt AndBits = AndC->getValue();
7495 DemandBits |= AndBits;
7497 if (AndBits.
ugt(WidestAndBits))
7498 WidestAndBits = AndBits;
7499 if (AndBits == WidestAndBits &&
I->getOperand(0) == Load)
7504 case Instruction::Shl: {
7508 uint64_t ShiftAmt = ShlC->getLimitedValue(
BitWidth - 1);
7509 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7514 case Instruction::Trunc: {
7517 DemandBits.setLowBits(TruncBitWidth);
7527 uint32_t ActiveBits = DemandBits.getActiveBits();
7539 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7540 WidestAndBits != DemandBits)
7543 LLVMContext &Ctx =
Load->getType()->getContext();
7544 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7555 Builder.CreateAnd(Load, ConstantInt::get(Ctx, DemandBits)));
7558 InsertedInsts.insert(NewAnd);
7563 NewAnd->setOperand(0, Load);
7566 for (
auto *
And : AndsToMaybeRemove)
7571 if (&*CurInstIterator ==
And)
7572 CurInstIterator = std::next(
And->getIterator());
7573 And->eraseFromParent();
7578 for (
auto *Inst : DropFlags)
7592 TTI->isExpensiveToSpeculativelyExecute(
I);
7610 uint64_t Max = std::max(TrueWeight, FalseWeight);
7611 uint64_t Sum = TrueWeight + FalseWeight;
7614 if (Probability >
TTI->getPredictableBranchThreshold())
7624 if (!Cmp || !Cmp->hasOneUse())
7647 assert(DefSI->getCondition() ==
SI->getCondition() &&
7648 "The condition of DefSI does not match with SI");
7649 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7652 assert(V &&
"Failed to get select true/false value");
7656bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7680 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7681 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7682 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7683 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7689bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7691 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7692 "Expected a funnel shift");
7716 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7717 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7718 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7726bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7738 It !=
SI->getParent()->
end(); ++It) {
7740 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7747 SelectInst *LastSI = ASI.
back();
7750 CurInstIterator = std::next(LastSI->
getIterator());
7754 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7755 fixupDbgVariableRecordsOnInst(*SI);
7757 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7760 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7763 TargetLowering::SelectSupportKind SelectKind;
7764 if (
SI->getType()->isVectorTy())
7765 SelectKind = TargetLowering::ScalarCondVectorVal;
7767 SelectKind = TargetLowering::ScalarValSelect;
7805 for (SelectInst *SI : ASI) {
7817 SplitPt.setHeadBit(
true);
7820 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7825 UncondBrInst *TrueBranch =
nullptr;
7826 UncondBrInst *FalseBranch =
nullptr;
7827 if (TrueInstrs.
size() == 0) {
7830 FalseBlock = FalseBranch->getParent();
7832 }
else if (FalseInstrs.
size() == 0) {
7835 TrueBlock = TrueBranch->getParent();
7844 TrueBlock = TrueBranch->getParent();
7845 FalseBlock = FalseBranch->getParent();
7849 EndBlock->
setName(
"select.end");
7851 TrueBlock->
setName(
"select.true.sink");
7853 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7854 :
"select.false.sink");
7858 FreshBBs.
insert(TrueBlock);
7860 FreshBBs.
insert(FalseBlock);
7861 FreshBBs.
insert(EndBlock);
7866 static const unsigned MD[] = {
7867 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7868 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7873 for (Instruction *
I : TrueInstrs)
7874 I->moveBefore(TrueBranch->getIterator());
7875 for (Instruction *
I : FalseInstrs)
7876 I->moveBefore(FalseBranch->getIterator());
7882 if (TrueBlock ==
nullptr)
7883 TrueBlock = StartBlock;
7884 else if (FalseBlock ==
nullptr)
7885 FalseBlock = StartBlock;
7901 SI->eraseFromParent();
7903 ++NumSelectsExpanded;
7907 CurInstIterator = StartBlock->
end();
7914bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7926 "Expected a type of the same size!");
7932 Builder.SetInsertPoint(SVI);
7933 Value *BC1 = Builder.CreateBitCast(
7935 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7936 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7940 SVI, TLInfo,
nullptr,
7941 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7948 !
Op->isTerminator() && !
Op->isEHPad())
7954bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7969 for (Use *U :
reverse(OpsToSink)) {
7981 SetVector<Instruction *> MaybeDead;
7982 DenseMap<Instruction *, Instruction *> NewInstructions;
7983 for (Use *U : ToReplace) {
7992 FreshBBs.
insert(OpDef->getParent());
7995 NewInstructions[UI] = NI;
8000 InsertedInsts.insert(NI);
8006 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
8007 It->second->setOperand(
U->getOperandNo(), NI);
8014 for (
auto *
I : MaybeDead) {
8015 if (!
I->hasNUsesOrMore(1)) {
8017 I->eraseFromParent();
8024bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
8030 unsigned RegWidth =
RegType.getSizeInBits();
8041 auto *NewType = Type::getIntNTy(
Context, RegWidth);
8050 ExtType = Instruction::SExt;
8053 if (Arg->hasSExtAttr())
8054 ExtType = Instruction::SExt;
8055 if (Arg->hasZExtAttr())
8056 ExtType = Instruction::ZExt;
8062 SI->setCondition(ExtInst);
8063 for (
auto Case :
SI->cases()) {
8064 const APInt &NarrowConst = Case.getCaseValue()->getValue();
8065 APInt WideConst = (ExtType == Instruction::ZExt)
8066 ? NarrowConst.
zext(RegWidth)
8067 : NarrowConst.
sext(RegWidth);
8068 Case.setValue(ConstantInt::get(
Context, WideConst));
8074bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
8081 Value *Condition =
SI->getCondition();
8090 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
8091 ConstantInt *CaseValue = Case.getCaseValue();
8092 BasicBlock *CaseBB = Case.getCaseSuccessor();
8095 bool CheckedForSinglePred =
false;
8096 for (PHINode &
PHI : CaseBB->
phis()) {
8097 Type *PHIType =
PHI.getType();
8105 if (PHIType == ConditionType || TryZExt) {
8107 bool SkipCase =
false;
8108 Value *Replacement =
nullptr;
8109 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
8110 Value *PHIValue =
PHI.getIncomingValue(
I);
8111 if (PHIValue != CaseValue) {
8120 if (
PHI.getIncomingBlock(
I) != SwitchBB)
8125 if (!CheckedForSinglePred) {
8126 CheckedForSinglePred =
true;
8127 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
8133 if (Replacement ==
nullptr) {
8134 if (PHIValue == CaseValue) {
8135 Replacement = Condition;
8138 Replacement = Builder.CreateZExt(Condition, PHIType);
8141 PHI.setIncomingValue(
I, Replacement);
8152bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
8153 bool Changed = optimizeSwitchType(SI);
8154 Changed |= optimizeSwitchPhiConstants(SI);
8175class VectorPromoteHelper {
8177 const DataLayout &
DL;
8180 const TargetLowering &TLI;
8183 const TargetTransformInfo &
TTI;
8189 SmallVector<Instruction *, 4> InstsToBePromoted;
8192 unsigned StoreExtractCombineCost;
8201 if (InstsToBePromoted.
empty())
8203 return InstsToBePromoted.
back();
8209 unsigned getTransitionOriginalValueIdx()
const {
8211 "Other kind of transitions are not supported yet");
8218 unsigned getTransitionIdx()
const {
8220 "Other kind of transitions are not supported yet");
8228 Type *getTransitionType()
const {
8239 void promoteImpl(Instruction *ToBePromoted);
8243 bool isProfitableToPromote() {
8244 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8248 Type *PromotedType = getTransitionType();
8251 unsigned AS =
ST->getPointerAddressSpace();
8269 for (
const auto &Inst : InstsToBePromoted) {
8277 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8289 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8290 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8291 return ScalarCost > VectorCost;
8303 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8318 if (!
EC.isScalable()) {
8319 SmallVector<Constant *, 4> ConstVec;
8321 for (
unsigned Idx = 0; Idx !=
EC.getKnownMinValue(); ++Idx) {
8322 if (Idx == ExtractIdx)
8330 "Generate scalable vector for non-splat is unimplemented");
8335 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8336 unsigned OperandIdx) {
8339 if (OperandIdx != 1)
8341 switch (
Use->getOpcode()) {
8344 case Instruction::SDiv:
8345 case Instruction::UDiv:
8346 case Instruction::SRem:
8347 case Instruction::URem:
8349 case Instruction::FDiv:
8350 case Instruction::FRem:
8351 return !
Use->hasNoNaNs();
8357 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8358 const TargetTransformInfo &
TTI, Instruction *Transition,
8359 unsigned CombineCost)
8360 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8361 StoreExtractCombineCost(CombineCost) {
8362 assert(Transition &&
"Do not know how to promote null");
8366 bool canPromote(
const Instruction *ToBePromoted)
const {
8373 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8376 for (
const Use &U : ToBePromoted->
operands()) {
8377 const Value *Val =
U.get();
8378 if (Val == getEndOfTransition()) {
8382 if (canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()))
8405 void enqueueForPromotion(Instruction *ToBePromoted) {
8406 InstsToBePromoted.push_back(ToBePromoted);
8410 void recordCombineInstruction(Instruction *ToBeCombined) {
8412 CombineInst = ToBeCombined;
8422 if (InstsToBePromoted.empty() || !CombineInst)
8430 for (
auto &ToBePromoted : InstsToBePromoted)
8431 promoteImpl(ToBePromoted);
8432 InstsToBePromoted.clear();
8439void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8449 "The type of the result of the transition does not match "
8454 Type *TransitionTy = getTransitionType();
8459 for (Use &U : ToBePromoted->
operands()) {
8461 Value *NewVal =
nullptr;
8462 if (Val == Transition)
8463 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8470 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8474 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8477 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8483bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8484 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8499 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8500 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost);
8507 if (ToBePromoted->
getParent() != Parent) {
8508 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8510 <<
") than the transition (" << Parent->
getName()
8515 if (VPH.canCombine(ToBePromoted)) {
8517 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8518 VPH.recordCombineInstruction(ToBePromoted);
8520 NumStoreExtractExposed +=
Changed;
8525 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8528 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8530 VPH.enqueueForPromotion(ToBePromoted);
8531 Inst = ToBePromoted;
8571 Type *StoreType =
SI.getValueOperand()->getType();
8580 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8581 DL.getTypeSizeInBits(StoreType) == 0)
8584 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8586 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8590 if (
SI.isVolatile())
8602 if (!
match(
SI.getValueOperand(),
8609 if (!
LValue->getType()->isIntegerTy() ||
8610 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8612 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8628 Builder.SetInsertPoint(&
SI);
8632 if (LBC && LBC->getParent() !=
SI.getParent())
8633 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8634 if (HBC && HBC->getParent() !=
SI.getParent())
8635 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8637 bool IsLE =
SI.getDataLayout().isLittleEndian();
8638 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8639 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8640 Value *Addr =
SI.getPointerOperand();
8641 Align Alignment =
SI.getAlign();
8642 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8643 if (IsOffsetStore) {
8644 Addr = Builder.CreateGEP(
8645 SplitStoreType, Addr,
8653 Builder.CreateAlignedStore(V, Addr, Alignment);
8656 CreateSplitStore(
LValue,
false);
8657 CreateSplitStore(HValue,
true);
8660 SI.eraseFromParent();
8668 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8750 if (GEPIOpI->getParent() != SrcBlock)
8755 if (auto *I = dyn_cast<Instruction>(Usr)) {
8756 if (I->getParent() != SrcBlock) {
8764 std::vector<GetElementPtrInst *> UGEPIs;
8767 for (User *Usr : GEPIOp->
users()) {
8786 if (UGEPI->getOperand(0) != GEPIOp)
8788 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8790 if (GEPIIdx->getType() !=
8798 UGEPIs.push_back(UGEPI);
8800 if (UGEPIs.size() == 0)
8803 for (GetElementPtrInst *UGEPI : UGEPIs) {
8805 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8812 for (GetElementPtrInst *UGEPI : UGEPIs) {
8813 UGEPI->setOperand(0, GEPI);
8815 auto NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8816 Constant *NewUGEPIIdx = ConstantInt::get(GEPIIdx->getType(), NewIdx);
8817 UGEPI->setOperand(1, NewUGEPIIdx);
8819 auto SourceFlags = GEPI->getNoWrapFlags();
8822 UGEPI->getNoWrapFlags().intersectForOffsetAdd(SourceFlags);
8824 if (NewIdx.
isNegative() && TargetFlags.hasNoUnsignedWrap())
8825 TargetFlags = TargetFlags.withoutNoUnsignedWrap();
8826 UGEPI->setNoWrapFlags(TargetFlags);
8832 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8834 "GEPIOp is used outside SrcBlock");
8858 Value *
X = Cmp->getOperand(0);
8859 if (!
X->hasUseList())
8864 for (
auto *U :
X->users()) {
8868 (UI->
getParent() != Branch->getParent() &&
8869 UI->
getParent() != Branch->getSuccessor(0) &&
8870 UI->
getParent() != Branch->getSuccessor(1)) ||
8871 (UI->
getParent() != Branch->getParent() &&
8872 !UI->
getParent()->getSinglePredecessor()))
8878 if (UI->
getParent() != Branch->getParent())
8882 ConstantInt::get(UI->
getType(), 0));
8884 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8888 if (Cmp->isEquality() &&
8893 if (UI->
getParent() != Branch->getParent())
8896 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8897 ConstantInt::get(UI->
getType(), 0));
8899 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8907bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8908 bool AnyChange =
false;
8909 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8913 if (InsertedInsts.count(
I))
8922 LargeOffsetGEPMap.erase(
P);
8924 P->eraseFromParent();
8947 I, LI->getLoopFor(
I->getParent()), *
TTI))
8955 TargetLowering::TypeExpandInteger) {
8959 I, LI->getLoopFor(
I->getParent()), *
TTI))
8962 bool MadeChange = optimizeExt(
I);
8963 return MadeChange | optimizeExtUses(
I);
8970 if (optimizeCmp(Cmp, ModifiedDT))
8974 if (optimizeURem(
I))
8978 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8979 bool Modified = optimizeLoadExt(LI);
8988 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8989 unsigned AS =
SI->getPointerAddressSpace();
8990 return optimizeMemoryInst(
I,
SI->getOperand(1),
8991 SI->getOperand(0)->getType(), AS);
8995 unsigned AS = RMW->getPointerAddressSpace();
8996 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
9000 unsigned AS = CmpX->getPointerAddressSpace();
9001 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
9002 CmpX->getCompareOperand()->getType(), AS);
9012 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
9013 BinOp->
getOpcode() == Instruction::LShr)) {
9021 if (GEPI->hasAllZeroIndices()) {
9023 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
9024 GEPI->getName(), GEPI->getIterator());
9025 NC->setDebugLoc(GEPI->getDebugLoc());
9028 GEPI, TLInfo,
nullptr,
9029 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9031 optimizeInst(
NC, ModifiedDT);
9054 if (Const0 || Const1) {
9055 if (!Const0 || !Const1) {
9056 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
9061 FI->eraseFromParent();
9068 if (tryToSinkFreeOperands(
I))
9071 switch (
I->getOpcode()) {
9072 case Instruction::Shl:
9073 case Instruction::LShr:
9074 case Instruction::AShr:
9076 case Instruction::Call:
9078 case Instruction::Select:
9080 case Instruction::ShuffleVector:
9082 case Instruction::Switch:
9084 case Instruction::ExtractElement:
9086 case Instruction::CondBr:
9095bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
9096 if (!
I.getType()->isIntegerTy() ||
9101 SmallVector<Instruction *, 4> Insts;
9107 &
I, TLInfo,
nullptr,
9108 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9115bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
9117 bool MadeChange =
false;
9120 CurInstIterator = BB.
begin();
9121 ModifiedDT = ModifyDT::NotModifyDT;
9122 while (CurInstIterator != BB.
end()) {
9123 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
9124 if (ModifiedDT != ModifyDT::NotModifyDT) {
9133 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
9135 bool MadeBitReverse =
true;
9136 while (MadeBitReverse) {
9137 MadeBitReverse =
false;
9139 if (makeBitReverse(
I)) {
9140 MadeBitReverse = MadeChange =
true;
9145 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
9150bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
9151 bool AnyChange =
false;
9152 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
9153 AnyChange |= fixupDbgVariableRecord(DVR);
9159bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
9160 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
9161 DVR.
Type != DbgVariableRecord::LocationType::Assign)
9165 bool AnyChange =
false;
9166 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
9168 for (
Value *Location : LocationOps) {
9169 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9198bool CodeGenPrepare::placeDbgValues(Function &
F) {
9199 bool MadeChange =
false;
9200 DominatorTree &DT = getDT();
9202 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9203 SmallVector<Instruction *, 4> VIs;
9204 for (
Value *V : DbgItem->location_ops())
9212 for (Instruction *VI : VIs) {
9213 if (
VI->isTerminator())
9218 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9229 if (VIs.size() > 1) {
9232 <<
"Unable to find valid location for Debug Value, undefing:\n"
9234 DbgItem->setKillLocation();
9239 << *DbgItem <<
' ' << *VI);
9246 for (BasicBlock &BB :
F) {
9252 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9254 DbgProcessor(&DVR, &Insn);
9265bool CodeGenPrepare::placePseudoProbes(Function &
F) {
9266 bool MadeChange =
false;
9269 auto FirstInst =
Block.getFirstInsertionPt();
9270 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9274 while (
I !=
Block.end()) {
9276 II->moveBefore(FirstInst);
9286 uint64_t NewMax = (NewTrue > NewFalse) ? NewTrue : NewFalse;
9287 uint32_t Scale = (NewMax / std::numeric_limits<uint32_t>::max()) + 1;
9288 NewTrue = NewTrue / Scale;
9289 NewFalse = NewFalse / Scale;
9314bool CodeGenPrepare::splitBranchCondition(Function &
F) {
9318 bool MadeChange =
false;
9319 for (
auto &BB :
F) {
9332 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9340 Value *Cond1, *Cond2;
9343 Opc = Instruction::And;
9346 Opc = Instruction::Or;
9356 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9370 Br1->setCondition(Cond1);
9375 if (
Opc == Instruction::And)
9376 Br1->setSuccessor(0, TmpBB);
9378 Br1->setSuccessor(1, TmpBB);
9383 I->removeFromParent();
9384 I->insertBefore(Br2->getIterator());
9396 if (
Opc == Instruction::Or)
9403 for (PHINode &PN : FBB->
phis()) {
9408 if (Loop *L = LI->getLoopFor(&BB))
9409 L->addBasicBlockToLoop(TmpBB, *LI);
9413 DTU->
applyUpdates({{DominatorTree::Insert, &BB, TmpBB},
9414 {DominatorTree::Insert, TmpBB,
TBB},
9415 {DominatorTree::Insert, TmpBB, FBB},
9416 {DominatorTree::Delete, &BB,
TBB}});
9420 if (
Opc == Instruction::Or) {
9440 uint64_t TrueWeight, FalseWeight;
9442 uint64_t NewTrueWeight = TrueWeight;
9443 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9445 Br1->setMetadata(LLVMContext::MD_prof,
9446 MDBuilder(Br1->getContext())
9447 .createBranchWeights(TrueWeight, FalseWeight,
9450 NewTrueWeight = TrueWeight;
9451 NewFalseWeight = 2 * FalseWeight;
9453 Br2->setMetadata(LLVMContext::MD_prof,
9454 MDBuilder(Br2->getContext())
9455 .createBranchWeights(TrueWeight, FalseWeight));
9476 uint64_t TrueWeight, FalseWeight;
9478 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9479 uint64_t NewFalseWeight = FalseWeight;
9481 Br1->setMetadata(LLVMContext::MD_prof,
9482 MDBuilder(Br1->getContext())
9483 .createBranchWeights(TrueWeight, FalseWeight));
9485 NewTrueWeight = 2 * TrueWeight;
9486 NewFalseWeight = FalseWeight;
9488 Br2->setMetadata(LLVMContext::MD_prof,
9489 MDBuilder(Br2->getContext())
9490 .createBranchWeights(TrueWeight, FalseWeight));
static unsigned getIntrinsicID(const SDNode *N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
This file contains the simple types necessary to represent the attributes associated with functions a...
static const Function * getParent(const Value *V)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool sinkAndCmp0Expression(Instruction *AndI, const TargetLowering &TLI, SetOfInstrs &InsertedInsts)
Duplicate and sink the given 'and' instruction into user blocks where it is used in a compare to allo...
static bool SinkShiftAndTruncate(BinaryOperator *ShiftI, Instruction *User, ConstantInt *CI, DenseMap< BasicBlock *, BinaryOperator * > &InsertedShifts, const TargetLowering &TLI, const DataLayout &DL)
Sink both shift and truncate instruction to the use of truncate's BB.
static bool getGEPSmallConstantIntOffsetV(GetElementPtrInst *GEP, SmallVectorImpl< Value * > &OffsetV)
static bool sinkSelectOperand(const TargetTransformInfo *TTI, Value *V)
Check if V (an operand of a select instruction) is an expensive instruction that is only used once.
static bool isExtractBitsCandidateUse(Instruction *User)
Check if the candidates could be combined with a shift instruction, which includes:
static cl::opt< unsigned > MaxAddressUsersToScan("cgp-max-address-users-to-scan", cl::init(100), cl::Hidden, cl::desc("Max number of address users to look at"))
static cl::opt< bool > OptimizePhiTypes("cgp-optimize-phi-types", cl::Hidden, cl::init(true), cl::desc("Enable converting phi types in CodeGenPrepare"))
static cl::opt< bool > DisableStoreExtract("disable-cgp-store-extract", cl::Hidden, cl::init(false), cl::desc("Disable store(extract) optimizations in CodeGenPrepare"))
static bool foldFCmpToFPClassTest(CmpInst *Cmp, const TargetLowering &TLI, const DataLayout &DL)
static void scaleWeights(uint64_t &NewTrue, uint64_t &NewFalse)
Scale down both weights to fit into uint32_t.
static cl::opt< bool > ProfileUnknownInSpecialSection("profile-unknown-in-special-section", cl::Hidden, cl::desc("In profiling mode like sampleFDO, if a function doesn't have " "profile, we cannot tell the function is cold for sure because " "it may be a function newly added without ever being sampled. " "With the flag enabled, compiler can put such profile unknown " "functions into a special section, so runtime system can choose " "to handle it in a different way than .text section, to save " "RAM for example. "))
static bool OptimizeExtractBits(BinaryOperator *ShiftI, ConstantInt *CI, const TargetLowering &TLI, const DataLayout &DL)
Sink the shift right instruction into user blocks if the uses could potentially be combined with this...
static cl::opt< bool > DisableExtLdPromotion("disable-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), cl::desc("Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in " "CodeGenPrepare"))
static cl::opt< bool > DisablePreheaderProtect("disable-preheader-prot", cl::Hidden, cl::init(false), cl::desc("Disable protection against removing loop preheaders"))
static cl::opt< bool > AddrSinkCombineBaseOffs("addr-sink-combine-base-offs", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseOffs field in Address sinking."))
static bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI, const DataLayout &DL)
If the specified cast instruction is a noop copy (e.g.
static bool splitMergedValStore(StoreInst &SI, const DataLayout &DL, const TargetLowering &TLI)
For the instruction sequence of store below, F and I values are bundled together as an i64 value befo...
static bool SinkCast(CastInst *CI)
Sink the specified cast instruction into its user blocks.
static bool swapICmpOperandsToExposeCSEOpportunities(CmpInst *Cmp)
Many architectures use the same instruction for both subtract and cmp.
static cl::opt< bool > AddrSinkCombineBaseReg("addr-sink-combine-base-reg", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseReg field in Address sinking."))
static bool FindAllMemoryUses(Instruction *I, SmallVectorImpl< std::pair< Use *, Type * > > &MemoryUses, SmallPtrSetImpl< Instruction * > &ConsideredInsts, const TargetLowering &TLI, const TargetRegisterInfo &TRI, bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI, unsigned &SeenInsts)
Recursively walk all the uses of I until we find a memory use.
static cl::opt< bool > StressStoreExtract("stress-cgp-store-extract", cl::Hidden, cl::init(false), cl::desc("Stress test store(extract) optimizations in CodeGenPrepare"))
static bool isFormingBranchFromSelectProfitable(const TargetTransformInfo *TTI, const TargetLowering *TLI, SelectInst *SI)
Returns true if a SelectInst should be turned into an explicit branch.
static std::optional< std::pair< Instruction *, Constant * > > getIVIncrement(const PHINode *PN, const LoopInfo *LI)
If given PN is an inductive variable with value IVInc coming from the backedge, and on each iteration...
static cl::opt< bool > AddrSinkCombineBaseGV("addr-sink-combine-base-gv", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseGV field in Address sinking."))
static cl::opt< bool > AddrSinkUsingGEPs("addr-sink-using-gep", cl::Hidden, cl::init(true), cl::desc("Address sinking in CGP using GEPs."))
static Value * getTrueOrFalseValue(SelectInst *SI, bool isTrue, const SmallPtrSet< const Instruction *, 2 > &Selects)
If isTrue is true, return the true value of SI, otherwise return false value of SI.
static cl::opt< bool > DisableBranchOpts("disable-cgp-branch-opts", cl::Hidden, cl::init(false), cl::desc("Disable branch optimizations in CodeGenPrepare"))
static cl::opt< bool > EnableTypePromotionMerge("cgp-type-promotion-merge", cl::Hidden, cl::desc("Enable merging of redundant sexts when one is dominating" " the other."), cl::init(true))
static cl::opt< bool > ProfileGuidedSectionPrefix("profile-guided-section-prefix", cl::Hidden, cl::init(true), cl::desc("Use profile info to add section prefix for hot/cold functions"))
static cl::opt< unsigned > HugeFuncThresholdInCGPP("cgpp-huge-func", cl::init(10000), cl::Hidden, cl::desc("Least BB number of huge function."))
static cl::opt< bool > AddrSinkNewSelects("addr-sink-new-select", cl::Hidden, cl::init(true), cl::desc("Allow creation of selects in Address sinking."))
static bool foldURemOfLoopIncrement(Instruction *Rem, const DataLayout *DL, const LoopInfo *LI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
static bool optimizeBranch(CondBrInst *Branch, const TargetLowering &TLI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
static bool tryUnmergingGEPsAcrossIndirectBr(GetElementPtrInst *GEPI, const TargetTransformInfo *TTI)
static bool IsOperandAMemoryOperand(CallInst *CI, InlineAsm *IA, Value *OpVal, const TargetLowering &TLI, const TargetRegisterInfo &TRI)
Check to see if all uses of OpVal by the specified inline asm call are due to memory operands.
static bool isIntrinsicOrLFToBeTailCalled(const TargetLibraryInfo *TLInfo, const CallInst *CI)
static void replaceAllUsesWith(Value *Old, Value *New, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
Replace all old uses with new ones, and push the updated BBs into FreshBBs.
static cl::opt< bool > ForceSplitStore("force-split-store", cl::Hidden, cl::init(false), cl::desc("Force store splitting no matter what the target query says."))
static bool matchOverflowPattern(Instruction *&I, ExtractValueInst *&MulExtract, ExtractValueInst *&OverflowExtract)
static void computeBaseDerivedRelocateMap(const SmallVectorImpl< GCRelocateInst * > &AllRelocateCalls, MapVector< GCRelocateInst *, SmallVector< GCRelocateInst *, 0 > > &RelocateInstMap)
static bool simplifyRelocatesOffABase(GCRelocateInst *RelocatedBase, const SmallVectorImpl< GCRelocateInst * > &Targets)
static cl::opt< bool > AddrSinkCombineScaledReg("addr-sink-combine-scaled-reg", cl::Hidden, cl::init(true), cl::desc("Allow combining of ScaledReg field in Address sinking."))
static bool foldICmpWithDominatingICmp(CmpInst *Cmp, const TargetLowering &TLI)
For pattern like:
static bool MightBeFoldableInst(Instruction *I)
This is a little filter, which returns true if an addressing computation involving I might be folded ...
static bool matchIncrement(const Instruction *IVInc, Instruction *&LHS, Constant *&Step)
static cl::opt< bool > EnableGEPOffsetSplit("cgp-split-large-offset-gep", cl::Hidden, cl::init(true), cl::desc("Enable splitting large offset of GEP."))
static cl::opt< bool > DisableComplexAddrModes("disable-complex-addr-modes", cl::Hidden, cl::init(false), cl::desc("Disables combining addressing modes with different parts " "in optimizeMemoryInst."))
static cl::opt< bool > EnableICMP_EQToICMP_ST("cgp-icmp-eq2icmp-st", cl::Hidden, cl::init(false), cl::desc("Enable ICMP_EQ to ICMP_S(L|G)T conversion."))
static cl::opt< bool > VerifyBFIUpdates("cgp-verify-bfi-updates", cl::Hidden, cl::init(false), cl::desc("Enable BFI update verification for " "CodeGenPrepare."))
static cl::opt< bool > BBSectionsGuidedSectionPrefix("bbsections-guided-section-prefix", cl::Hidden, cl::init(true), cl::desc("Use the basic-block-sections profile to determine the text " "section prefix for hot functions. Functions with " "basic-block-sections profile will be placed in `.text.hot` " "regardless of their FDO profile info. Other functions won't be " "impacted, i.e., their prefixes will be decided by FDO/sampleFDO " "profiles."))
static bool isRemOfLoopIncrementWithLoopInvariant(Instruction *Rem, const LoopInfo *LI, Value *&RemAmtOut, Value *&AddInstOut, Value *&AddOffsetOut, PHINode *&LoopIncrPNOut)
static bool isIVIncrement(const Value *V, const LoopInfo *LI)
static cl::opt< bool > DisableGCOpts("disable-cgp-gc-opts", cl::Hidden, cl::init(false), cl::desc("Disable GC optimizations in CodeGenPrepare"))
static bool GEPSequentialConstIndexed(GetElementPtrInst *GEP)
static void DbgInserterHelper(DbgVariableRecord *DVR, BasicBlock::iterator VI)
static bool isPromotedInstructionLegal(const TargetLowering &TLI, const DataLayout &DL, Value *Val)
Check whether or not Val is a legal instruction for TLI.
static cl::opt< uint64_t > FreqRatioToSkipMerge("cgp-freq-ratio-to-skip-merge", cl::Hidden, cl::init(2), cl::desc("Skip merging empty blocks if (frequency of empty block) / " "(frequency of destination block) is greater than this ratio"))
static BasicBlock::iterator findInsertPos(Value *Addr, Instruction *MemoryInst, Value *SunkAddr)
static bool IsNonLocalValue(Value *V, BasicBlock *BB)
Return true if the specified values are defined in a different basic block than BB.
static cl::opt< bool > EnableAndCmpSinking("enable-andcmp-sinking", cl::Hidden, cl::init(true), cl::desc("Enable sinking and/cmp into branches."))
static bool despeculateCountZeros(IntrinsicInst *CountZeros, DomTreeUpdater *DTU, 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 bool sinkCmpExpression(CmpInst *Cmp, const TargetLowering &TLI, const DataLayout &DL)
Sink the given CmpInst into user blocks to reduce the number of virtual registers that must be create...
static bool hasSameExtUse(Value *Val, const TargetLowering &TLI)
Check if all the uses of Val are equivalent (or free) zero or sign extensions.
static cl::opt< bool > StressExtLdPromotion("stress-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), cl::desc("Stress test ext(promotable(ld)) -> promoted(ext(ld)) " "optimization in CodeGenPrepare"))
static bool matchUAddWithOverflowConstantEdgeCases(CmpInst *Cmp, BinaryOperator *&Add)
Match special-case patterns that check for unsigned add overflow.
static cl::opt< bool > DisableSelectToBranch("disable-cgp-select2branch", cl::Hidden, cl::init(false), cl::desc("Disable select to branch conversion."))
static cl::opt< bool > DisableDeletePHIs("disable-cgp-delete-phis", cl::Hidden, cl::init(false), cl::desc("Disable elimination of dead PHI nodes."))
static cl::opt< bool > AddrSinkNewPhis("addr-sink-new-phis", cl::Hidden, cl::init(false), cl::desc("Allow creation of Phis in Address sinking."))
Defines an IR pass for CodeGen Prepare.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
static Value * getCondition(Instruction *I)
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU)
Register const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the PointerIntPair class.
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static DominatorTree getDomTree(Function &F)
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, const MachineInstr &B)
Remove Loads Into Fake Uses
static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, unsigned CombineOpc=0)
This file describes how to lower LLVM code to machine code.
static cl::opt< bool > DisableSelectOptimize("disable-select-optimize", cl::init(true), cl::Hidden, cl::desc("Disable the select-optimization pass from running"))
Disable the select optimization pass.
Target-Independent Code Generator Pass Configuration Options pass.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
static Constant * getConstantVector(MVT VT, ArrayRef< APInt > Bits, const APInt &Undefs, LLVMContext &C)
Class for arbitrary precision integers.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isNegative() const
Determine sign of this APInt.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
unsigned getSignificantBits() const
Get the minimum bit size for this signed APInt.
unsigned logBase2() const
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
int64_t getSExtValue() const
Get sign extended value.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
void setAlignment(Align Align)
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addRequired()
Represent a constant reference to an array (0 or more elements consecutively in memory),...
An instruction that atomically checks whether a specified value is in a memory location,...
static unsigned getPointerOperandIndex()
an instruction that atomically reads a memory location, combines it with another value,...
static unsigned getPointerOperandIndex()
Analysis pass providing the BasicBlockSectionsProfileReader.
bool isFunctionHot(StringRef FuncName) const
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI void insertDbgRecordBefore(DbgRecord *DR, InstListType::iterator Here)
Insert a DbgRecord into a block at the position given by Here.
InstListType::const_iterator const_iterator
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
LLVM_ABI InstListType::const_iterator getFirstNonPHIOrDbg(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic,...
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
LLVM_ABI 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; assumes that the block is well-formed.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI void setBlockFreq(const BasicBlock *BB, BlockFrequency Freq)
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
LLVM_ABI std::optional< BlockFrequency > mul(uint64_t Factor) const
Multiplies frequency with Factor. Returns nullopt in case of overflow.
Analysis pass which computes BranchProbabilityInfo.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
Predicate getPredicate() const
Return the predicate for this instruction.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Conditional Branch instruction.
static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI void removeFromParent()
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LocationType Type
Classification of the debug-info record that this DbgVariableRecord represents.
LLVM_ABI void replaceVariableLocationOp(Value *OldValue, Value *NewValue, bool AllowEmpty=false)
LLVM_ABI iterator_range< location_op_iterator > location_ops() const
Get the locations corresponding to the variable referenced by the debug info intrinsic.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
LLVM_ABI void deleteBB(BasicBlock *DelBB)
Delete DelBB.
Analysis pass which computes a DominatorTree.
static constexpr UpdateKind Insert
Legacy analysis pass which computes a DominatorTree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This instruction compares its operands according to the predicate given to the constructor.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionPass class - This class is used to implement most global optimizations.
const BasicBlock & getEntryBlock() const
LLVM_ABI const Value * getStatepoint() const
The statepoint with which this gc.relocate is associated.
Represents calls to the gc.relocate intrinsic.
unsigned getBasePtrIndex() const
The index into the associate statepoint's argument list which contains the base pointer of the pointe...
DomTreeT & getDomTree()
Flush DomTree updates and return DomTree.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
void flush()
Apply all pending updates to available trees and flush all BasicBlocks awaiting deletion.
bool isBBPendingDeletion(BasicBlockT *DelBB) const
Returns true if DelBB is awaiting deletion.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static LLVM_ABI Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)
Returns the result type of a getelementptr with the given source element type and indexes.
LLVM_ABI bool canIncreaseAlignment() const
Returns true if the alignment of the value can be unilaterally increased.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This instruction compares its operands according to the predicate given to the constructor.
bool isEquality() const
Return true if this predicate is either EQ or NE.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
LLVM_ABI bool isDebugOrPseudoInst() const LLVM_READONLY
Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void moveAfter(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
LLVM_ABI std::optional< simple_ilist< DbgRecord >::iterator > getDbgReinsertionPosition()
Return an iterator to the position of the "Next" DbgRecord after this instruction,...
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
LLVM_ABI void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
An instruction for reading from memory.
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
Analysis pass that exposes the LoopInfo for a function.
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
void analyze(const DominatorTreeBase< BlockT, false > &DomTree)
Create the loop forest using a stable algorithm.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
The legacy pass manager's analysis pass to compute loop information.
Represents a single loop in the control flow graph.
static MVT getIntegerVT(unsigned BitWidth)
LLVM_ABI void replacePhiUsesWith(MachineBasicBlock *Old, MachineBasicBlock *New)
Update all phi nodes in this basic block to refer to basic block New instead of basic block Old.
This class implements a map that also provides access to all stored values in a deterministic order.
iterator find(const KeyT &Key)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
op_range incoming_values()
Value * getIncomingValueForBlock(const BasicBlock *BB) const
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
PointerIntPair - This class implements a pair of a pointer and small integer.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
bool isFunctionColdInCallGraph(const FuncT *F, BFIT &BFI) const
Returns true if F contains only cold code.
LLVM_ABI bool isFunctionHotnessUnknown(const Function &F) const
Returns true if the hotness of F is unknown.
bool isFunctionHotInCallGraph(const FuncT *F, BFIT &BFI) const
Returns true if F contains hot code.
LLVM_ABI bool hasPartialSampleProfile() const
Returns true if module M has partial-profile sample profile.
LLVM_ABI bool hasHugeWorkingSetSize() const
Returns true if the working set size of the code is considered huge.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
void clear()
Completely clear the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
VectorType * getType() const
Overload to return most specific vector type.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator erase(const_iterator CI)
typename SuperClass::iterator iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
static unsigned getPointerOperandIndex()
TypeSize getElementOffset(unsigned Idx) const
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
int InstructionOpcodeToISD(unsigned Opcode) const
Get the ISD node that corresponds to the Instruction class opcode.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool isSelectSupported(SelectSupportKind) const
virtual bool isEqualityCmpFoldedWithSignedCmp() const
Return true if instruction generated for equality comparison is folded with instruction generated for...
virtual bool shouldFormOverflowOp(unsigned Opcode, EVT VT, bool MathUsed) const
Try to convert math with an overflow comparison into the corresponding DAG node operation.
virtual bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const
Return if the target supports combining a chain like:
virtual bool shouldOptimizeMulOverflowWithZeroHighBits(LLVMContext &Context, EVT VT) const
bool isExtLoad(const LoadInst *Load, const Instruction *Ext, const DataLayout &DL) const
Return true if Load and Ext can form an ExtLoad.
virtual bool isSExtCheaperThanZExt(EVT FromTy, EVT ToTy) const
Return true if sign-extension from FromTy to ToTy is cheaper than zero-extension.
const TargetMachine & getTargetMachine() const
virtual bool isCtpopFast(EVT VT) const
Return true if ctpop instruction is fast.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
bool enableExtLdPromotion() const
Return true if the target wants to use the optimization that turns ext(promotableInst1(....
virtual bool isCheapToSpeculateCttz(Type *Ty) const
Return true if it is cheap to speculate a call to intrinsic cttz.
bool isJumpExpensive() const
Return true if Flow Control is an expensive operation that should be avoided.
bool hasExtractBitsInsn() const
Return true if the target has BitExtract instructions.
virtual bool allowsMisalignedMemoryAccesses(EVT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *=nullptr) const
Determine if the target supports unaligned memory accesses.
bool isSlowDivBypassed() const
Returns true if target has indicated at least one type should be bypassed.
virtual bool isTruncateFree(Type *FromTy, Type *ToTy) const
Return true if it's free to truncate a value of type FromTy to type ToTy.
virtual bool hasMultipleConditionRegisters(EVT VT) const
Does the target have multiple (allocatable) condition registers that can be used to store the results...
virtual EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
virtual MVT getPreferredSwitchConditionType(LLVMContext &Context, EVT ConditionVT) const
Returns preferred type for switch condition.
bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const
Return true if the specified condition code is legal for a comparison of the specified types on this ...
virtual bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx, unsigned &Cost) const
Return true if the target can combine store(extractelement VectorTy,Idx).
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual bool isFreeAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const
Returns true if a cast from SrcAS to DestAS is "cheap", such that e.g.
virtual bool shouldConsiderGEPOffsetSplit() const
bool isExtFree(const Instruction *I) const
Return true if the extension represented by I is free.
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
bool isPredictableSelectExpensive() const
Return true if selects are only cheaper than branches if the branch is unlikely to be predicted right...
virtual bool isMultiStoresCheaperThanBitsMerge(EVT LTy, EVT HTy) const
Return true if it is cheaper to split the store of a merged int val from a pair of smaller values int...
virtual bool getAddrModeArguments(const IntrinsicInst *, SmallVectorImpl< Value * > &, Type *&) const
CodeGenPrepare sinks address calculations into the same BB as Load/Store instructions reading the add...
const DenseMap< unsigned int, unsigned int > & getBypassSlowDivWidths() const
Returns map of slow types for division or remainder with corresponding fast types.
virtual bool isCheapToSpeculateCtlz(Type *Ty) const
Return true if it is cheap to speculate a call to intrinsic ctlz.
virtual bool useSoftFloat() const
virtual int64_t getPreferredLargeGEPBaseOffset(int64_t MinOffset, int64_t MaxOffset) const
Return the prefered common base offset.
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
virtual bool shouldAlignPointerArgs(CallInst *, unsigned &, Align &) const
Return true if the pointer arguments to CI should be aligned by aligning the object whose address is ...
virtual Type * shouldConvertSplatType(ShuffleVectorInst *SVI) const
Given a shuffle vector SVI representing a vector splat, return a new scalar type of size equal to SVI...
bool isLoadLegal(EVT ValVT, EVT MemVT, Align Alignment, unsigned AddrSpace, unsigned ExtType, bool Atomic) const
Return true if the specified load with extension is legal on this target.
virtual bool addressingModeSupportsTLS(const GlobalValue &) const
Returns true if the targets addressing mode can target thread local storage (TLS).
virtual bool shouldConvertPhiType(Type *From, Type *To) const
Given a set in interconnected phis of type 'From' that are loaded/stored or bitcast to type 'To',...
virtual bool isFAbsFree(EVT VT) const
Return true if an fabs operation is free to the point where it is never worthwhile to replace it with...
virtual bool preferZeroCompareBranch() const
Return true if the heuristic to prefer icmp eq zero should be used in code gen prepare.
virtual bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AddrSpace, Instruction *I=nullptr) const
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
virtual bool optimizeExtendOrTruncateConversion(Instruction *I, Loop *L, const TargetTransformInfo &TTI) const
Try to optimize extending or truncating conversion instructions (like zext, trunc,...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
std::vector< AsmOperandInfo > AsmOperandInfoVector
virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL, const TargetRegisterInfo *TRI, const CallBase &Call) const
Split up the constraint string from the inline assembly value into the specific constraints and their...
virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op, SelectionDAG *DAG=nullptr) const
Determines the constraint code and constraint type to use for the specific AsmOperandInfo,...
virtual bool mayBeEmittedAsTailCall(const CallInst *) const
Return true if the target may be able emit the call instruction as a tail call.
virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const
Returns true if a cast between SrcAS and DestAS is a noop.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
unsigned EnableFastISel
EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...
Target-Independent Code Generator Pass Configuration Options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
virtual bool addrSinkUsingGEPs() const
Sink addresses into blocks using GEP instructions rather than pointer casts and arithmetic.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
BasicBlock * getSuccessor(unsigned i=0) const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
LLVM_ABI bool isUsedInBasicBlock(const BasicBlock *BB) const
Check if this value is used in the specified basic block.
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
iterator_range< use_iterator > uses()
void mutateType(Type *Ty)
Mutate the type of this Value to be of the specified type.
user_iterator_impl< User > user_iterator
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
bool pointsToAliveValue() const
int getNumOccurrences() const
constexpr ScalarTy getFixedValue() const
constexpr bool isNonZero() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ C
The default llvm calling convention, compatible with C.
unsigned getAddrMode(MCInstrInfo const &MCII, MCInst const &MCI)
@ BasicBlock
Various leaf nodes.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
auto m_Cmp()
Matches any compare instruction and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
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)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
match_bind< 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)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_Constant()
Match an arbitrary Constant and ignore it.
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.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
m_Intrinsic_Ty< Opnd0 >::Ty m_Ctpop(const Opnd0 &Op0)
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.
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
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)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
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)
DXILDebugInfoMap run(Module &M)
@ User
could "use" a pointer
NodeAddr< PhiNode * > Phi
NodeAddr< UseNode * > Use
SmallVector< Node, 4 > NodeList
friend class Instruction
Iterator for Instructions in a `BasicBlock.
LLVM_ABI iterator begin() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
FunctionAddr VTableAddr Value
std::enable_if_t< std::is_signed_v< T >, T > MulOverflow(T X, T Y, T &Result)
Multiply two signed integers, computing the two's complement truncated result, returning true if an o...
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool RemoveRedundantDbgInstrs(BasicBlock *BB)
Try to remove redundant dbg.value instructions from given basic block.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
LLVM_ABI bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions=false, const TargetLibraryInfo *TLI=nullptr, DomTreeUpdater *DTU=nullptr)
If a terminator instruction is predicated on a constant value, convert it into an unconditional branc...
LLVM_ABI void findDbgValues(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)
Finds the dbg.values describing a value.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
APInt operator*(APInt a, uint64_t RHS)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
auto successors(const MachineBasicBlock *BB)
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI ReturnInst * FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, BasicBlock *Pred, DomTreeUpdater *DTU=nullptr)
This method duplicates the specified return instruction into a predecessor which ends in an unconditi...
bool operator!=(uint64_t V1, const APInt &V2)
constexpr from_range_t from_range
LLVM_ABI BasicBlock * splitBlockBefore(BasicBlock *Old, BasicBlock::iterator SplitPt, DomTreeUpdater *DTU, LoopInfo *LI, MemorySSAUpdater *MSSAU, const Twine &BBName="")
Split the specified block at the specified instruction SplitPt.
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.
LLVM_ABI bool SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr, DomTreeUpdater *DTU=nullptr)
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 bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
auto unique(Range &&R, Predicate P)
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
LLVM_ABI bool hasBranchWeightOrigin(const Instruction &I)
Check if Branch Weight Metadata has an "expected" field from an llvm.expect* intrinsic.
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
auto dyn_cast_or_null(const Y &Val)
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
LLVM_ABI bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Examine each PHI in the given block and delete it if it is dead.
LLVM_ABI bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, SmallSetVector< Instruction *, 8 > *UnsimplifiedUsers=nullptr)
Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively.
auto reverse(ContainerTy &&C)
LLVM_ABI bool recognizeBSwapOrBitReverseIdiom(Instruction *I, bool MatchBSwaps, bool MatchBitReversals, SmallVectorImpl< Instruction * > &InsertedInsts)
Try to match a bswap or bitreverse idiom.
void sort(IteratorTy Start, IteratorTy End)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI void SplitBlockAndInsertIfThenElse(Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
generic_gep_type_iterator<> gep_type_iterator
LLVM_ABI FunctionPass * createCodeGenPrepareLegacyPass()
createCodeGenPrepareLegacyPass - Transform the code to expose more pattern matching during instructio...
ISD::CondCode getFCmpCondCode(FCmpInst::Predicate Pred)
getFCmpCondCode - Return the ISD condition code corresponding to the given LLVM IR floating-point con...
LLVM_ABI bool VerifyLoopInfo
Enable verification of loop info.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
bool attributesPermitTailCall(const Function *F, const Instruction *I, const ReturnInst *Ret, const TargetLoweringBase &TLI, bool *AllowDifferingSizes=nullptr)
Test if given that the input instruction is in the tail call position, if there is an attribute misma...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false, DominatorTree *DT=nullptr)
Attempts to merge a block into its predecessor, if possible.
@ Or
Bitwise or logical OR of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction.
FunctionAddr VTableAddr Next
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
bool bypassSlowDivision(BasicBlock *BB, const DenseMap< unsigned int, unsigned int > &BypassWidth, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
This optimization identifies DIV instructions in a BB that can be profitably bypassed and carried out...
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI bool VerifyDomInfo
Enables verification of dominator trees.
constexpr unsigned BitWidth
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
bool pred_empty(const BasicBlock *BB)
std::enable_if_t< std::is_signed_v< T >, T > AddOverflow(T X, T Y, T &Result)
Add two signed integers, computing the two's complement truncated result, returning true if overflow ...
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
std::pair< Value *, FPClassTest > fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, Value *RHS, bool LookThroughSrc=true)
Returns a pair of values, which if passed to llvm.is.fpclass, returns the same result as an fcmp with...
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
LLVM_ABI Value * simplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a URem, fold the result or return null.
DenseMap< const Value *, Value * > ValueToValueMap
LLVM_ABI CGPassBuilderOption getCGPassBuilderOption()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool isRound() const
Return true if the size is a power-of-two number of bytes.
bool isInteger() const
Return true if this is an integer or a vector integer type.
This contains information for each constraint that we are lowering.