45#include "llvm/Config/llvm-config.h"
66#include "llvm/IR/IntrinsicsAArch64.h"
110#define DEBUG_TYPE "codegenprepare"
113STATISTIC(NumPHIsElim,
"Number of trivial PHIs eliminated");
114STATISTIC(NumGEPsElim,
"Number of GEPs converted to casts");
115STATISTIC(NumCmpUses,
"Number of uses of Cmp expressions replaced with uses of "
117STATISTIC(NumCastUses,
"Number of uses of Cast expressions replaced with uses "
119STATISTIC(NumMemoryInsts,
"Number of memory instructions whose address "
120 "computations were sunk");
122 "Number of phis created when address "
123 "computations were sunk to memory instructions");
125 "Number of select created when address "
126 "computations were sunk to memory instructions");
127STATISTIC(NumExtsMoved,
"Number of [s|z]ext instructions combined with loads");
128STATISTIC(NumExtUses,
"Number of uses of [s|z]ext instructions optimized");
130 "Number of and mask instructions added to form ext loads");
131STATISTIC(NumAndUses,
"Number of uses of and mask instructions optimized");
132STATISTIC(NumRetsDup,
"Number of return instructions duplicated");
133STATISTIC(NumDbgValueMoved,
"Number of debug value instructions moved");
134STATISTIC(NumSelectsExpanded,
"Number of selects turned into branches");
135STATISTIC(NumStoreExtractExposed,
"Number of store(extractelement) exposed");
139 cl::desc(
"Disable branch optimizations in CodeGenPrepare"));
143 cl::desc(
"Disable GC optimizations in CodeGenPrepare"));
148 cl::desc(
"Disable select to branch conversion."));
152 cl::desc(
"Address sinking in CGP using GEPs."));
156 cl::desc(
"Enable sinking and/cmp into branches."));
160 cl::desc(
"Disable store(extract) optimizations in CodeGenPrepare"));
164 cl::desc(
"Stress test store(extract) optimizations in CodeGenPrepare"));
168 cl::desc(
"Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in "
173 cl::desc(
"Stress test ext(promotable(ld)) -> promoted(ext(ld)) "
174 "optimization in CodeGenPrepare"));
178 cl::desc(
"Disable protection against removing loop preheaders"));
182 cl::desc(
"Use profile info to add section prefix for hot/cold functions"));
185 "profile-unknown-in-special-section",
cl::Hidden,
186 cl::desc(
"In profiling mode like sampleFDO, if a function doesn't have "
187 "profile, we cannot tell the function is cold for sure because "
188 "it may be a function newly added without ever being sampled. "
189 "With the flag enabled, compiler can put such profile unknown "
190 "functions into a special section, so runtime system can choose "
191 "to handle it in a different way than .text section, to save "
192 "RAM for example. "));
196 cl::desc(
"Use the basic-block-sections profile to determine the text "
197 "section prefix for hot functions. Functions with "
198 "basic-block-sections profile will be placed in `.text.hot` "
199 "regardless of their FDO profile info. Other functions won't be "
200 "impacted, i.e., their prefixes will be decided by FDO/sampleFDO "
205 cl::desc(
"Skip merging empty blocks if (frequency of empty block) / "
206 "(frequency of destination block) is greater than this ratio"));
210 cl::desc(
"Force store splitting no matter what the target query says."));
214 cl::desc(
"Enable merging of redundant sexts when one is dominating"
220 cl::desc(
"Disables combining addressing modes with different parts "
221 "in optimizeMemoryInst."));
225 cl::desc(
"Allow creation of Phis in Address sinking."));
229 cl::desc(
"Allow creation of selects in Address sinking."));
233 cl::desc(
"Allow combining of BaseReg field in Address sinking."));
237 cl::desc(
"Allow combining of BaseGV field in Address sinking."));
241 cl::desc(
"Allow combining of BaseOffs field in Address sinking."));
245 cl::desc(
"Allow combining of ScaledReg field in Address sinking."));
250 cl::desc(
"Enable splitting large offset of GEP."));
254 cl::desc(
"Enable ICMP_EQ to ICMP_S(L|G)T conversion."));
258 cl::desc(
"Enable BFI update verification for "
263 cl::desc(
"Enable converting phi types in CodeGenPrepare"));
267 cl::desc(
"Least BB number of huge function."));
272 cl::desc(
"Max number of address users to look at"));
276 cl::desc(
"Disable elimination of dead PHI nodes."));
304class TypePromotionTransaction;
306class CodeGenPrepare {
307 friend class CodeGenPrepareLegacyPass;
308 const TargetMachine *TM =
nullptr;
309 const TargetSubtargetInfo *SubtargetInfo =
nullptr;
310 const TargetLowering *TLI =
nullptr;
311 const TargetRegisterInfo *TRI =
nullptr;
312 const TargetTransformInfo *TTI =
nullptr;
313 const BasicBlockSectionsProfileReader *BBSectionsProfileReader =
nullptr;
314 const TargetLibraryInfo *TLInfo =
nullptr;
315 LoopInfo *LI =
nullptr;
316 std::unique_ptr<BlockFrequencyInfo> BFI;
317 std::unique_ptr<BranchProbabilityInfo> BPI;
318 ProfileSummaryInfo *PSI =
nullptr;
329 ValueMap<Value *, WeakTrackingVH> SunkAddrs;
332 SetOfInstrs InsertedInsts;
336 InstrToOrigTy PromotedInsts;
339 SetOfInstrs RemovedInsts;
342 DenseMap<Value *, Instruction *> SeenChainsForSExt;
347 MapVector<AssertingVH<Value>,
352 SmallSet<AssertingVH<Value>, 2> NewGEPBases;
355 DenseMap<AssertingVH<GetElementPtrInst>,
int> LargeOffsetGEPID;
358 ValueToSExts ValToSExtendedUses;
364 const DataLayout *DL =
nullptr;
368 std::unique_ptr<DominatorTree> DT;
371 CodeGenPrepare() =
default;
372 CodeGenPrepare(
const TargetMachine *TM) : TM(TM){};
374 bool IsHugeFunc =
false;
380 SmallPtrSet<BasicBlock *, 32> FreshBBs;
382 void releaseMemory() {
384 InsertedInsts.clear();
385 PromotedInsts.clear();
394 template <
typename F>
395 void resetIteratorIfInvalidatedWhileCalling(BasicBlock *BB,
F f) {
399 Value *CurValue = &*CurInstIterator;
400 WeakTrackingVH IterHandle(CurValue);
406 if (IterHandle != CurValue) {
407 CurInstIterator = BB->
begin();
413 DominatorTree &getDT(Function &
F) {
415 DT = std::make_unique<DominatorTree>(
F);
419 void removeAllAssertingVHReferences(
Value *V);
420 bool eliminateAssumptions(Function &
F);
421 bool eliminateFallThrough(Function &
F, DominatorTree *DT =
nullptr);
422 bool eliminateMostlyEmptyBlocks(Function &
F);
423 BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB);
424 bool canMergeBlocks(
const BasicBlock *BB,
const BasicBlock *DestBB)
const;
425 void eliminateMostlyEmptyBlock(BasicBlock *BB);
426 bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB,
428 bool makeBitReverse(Instruction &
I);
430 bool optimizeInst(Instruction *
I, ModifyDT &ModifiedDT);
431 bool optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
Type *AccessTy,
433 bool optimizeGatherScatterInst(Instruction *MemoryInst,
Value *Ptr);
434 bool optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
435 ModifyDT &ModifiedDT);
436 bool optimizeInlineAsmInst(CallInst *CS);
438 bool optimizeExt(Instruction *&
I);
439 bool optimizeExtUses(Instruction *
I);
440 bool optimizeLoadExt(LoadInst *Load);
441 bool optimizeShiftInst(BinaryOperator *BO);
442 bool optimizeFunnelShift(IntrinsicInst *Fsh);
443 bool optimizeSelectInst(SelectInst *SI);
444 bool optimizeShuffleVectorInst(ShuffleVectorInst *SVI);
445 bool optimizeSwitchType(SwitchInst *SI);
446 bool optimizeSwitchPhiConstants(SwitchInst *SI);
447 bool optimizeSwitchInst(SwitchInst *SI);
448 bool optimizeExtractElementInst(Instruction *Inst);
449 bool dupRetToEnableTailCallOpts(BasicBlock *BB, ModifyDT &ModifiedDT);
450 bool fixupDbgVariableRecord(DbgVariableRecord &
I);
451 bool fixupDbgVariableRecordsOnInst(Instruction &
I);
452 bool placeDbgValues(Function &
F);
453 bool placePseudoProbes(Function &
F);
454 bool canFormExtLd(
const SmallVectorImpl<Instruction *> &MovedExts,
455 LoadInst *&LI, Instruction *&Inst,
bool HasPromoted);
456 bool tryToPromoteExts(TypePromotionTransaction &TPT,
457 const SmallVectorImpl<Instruction *> &Exts,
458 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
459 unsigned CreatedInstsCost = 0);
460 bool mergeSExts(Function &
F);
461 bool splitLargeGEPOffsets();
462 bool optimizePhiType(PHINode *Inst, SmallPtrSetImpl<PHINode *> &Visited,
463 SmallPtrSetImpl<Instruction *> &DeletedInstrs);
464 bool optimizePhiTypes(Function &
F);
465 bool performAddressTypePromotion(
466 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
467 bool HasPromoted, TypePromotionTransaction &TPT,
468 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts);
469 bool splitBranchCondition(Function &
F, ModifyDT &ModifiedDT);
470 bool simplifyOffsetableRelocate(GCStatepointInst &
I);
472 bool tryToSinkFreeOperands(Instruction *
I);
473 bool replaceMathCmpWithIntrinsic(BinaryOperator *BO,
Value *Arg0,
Value *Arg1,
475 bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT);
476 bool optimizeURem(Instruction *Rem);
477 bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
478 bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
479 bool unfoldPowerOf2Test(CmpInst *Cmp);
480 void verifyBFIUpdates(Function &
F);
481 bool _run(Function &
F);
488 CodeGenPrepareLegacyPass() : FunctionPass(ID) {
494 StringRef getPassName()
const override {
return "CodeGen Prepare"; }
496 void getAnalysisUsage(AnalysisUsage &AU)
const override {
509char CodeGenPrepareLegacyPass::ID = 0;
511bool CodeGenPrepareLegacyPass::runOnFunction(
Function &
F) {
514 auto TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
515 CodeGenPrepare CGP(TM);
516 CGP.DL = &
F.getDataLayout();
519 CGP.TRI = CGP.SubtargetInfo->getRegisterInfo();
520 CGP.TLInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
521 CGP.TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
522 CGP.LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
523 CGP.BPI.reset(
new BranchProbabilityInfo(
F, *CGP.LI));
524 CGP.BFI.reset(
new BlockFrequencyInfo(
F, *CGP.BPI, *CGP.LI));
525 CGP.PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
527 getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
528 CGP.BBSectionsProfileReader = BBSPRWP ? &BBSPRWP->getBBSPR() :
nullptr;
534 "Optimize for code generation",
false,
false)
545 return new CodeGenPrepareLegacyPass();
550 CodeGenPrepare CGP(TM);
563 DL = &
F.getDataLayout();
574 BBSectionsProfileReader =
580 bool EverMadeChange =
false;
582 OptSize =
F.hasOptSize();
587 (void)
F.setSectionPrefix(
"hot");
592 if (
F.hasFnAttribute(Attribute::Hot) ||
594 (void)
F.setSectionPrefix(
"hot");
599 F.hasFnAttribute(Attribute::Cold))
600 (void)
F.setSectionPrefix(
"unlikely");
603 (void)
F.setSectionPrefix(
"unknown");
609 const DenseMap<unsigned int, unsigned int> &BypassWidths =
612 while (BB !=
nullptr) {
625 EverMadeChange |= eliminateAssumptions(
F);
629 EverMadeChange |= eliminateMostlyEmptyBlocks(
F);
631 ModifyDT ModifiedDT = ModifyDT::NotModifyDT;
633 EverMadeChange |= splitBranchCondition(
F, ModifiedDT);
647 LI->analyze(getDT(
F));
649 bool MadeChange =
true;
650 bool FuncIterated =
false;
655 if (FuncIterated && !FreshBBs.
contains(&BB))
658 ModifyDT ModifiedDTOnIteration = ModifyDT::NotModifyDT;
661 if (ModifiedDTOnIteration == ModifyDT::ModifyBBDT)
677 else if (FuncIterated)
682 if (ModifiedDTOnIteration != ModifyDT::NotModifyDT)
687 FuncIterated = IsHugeFunc;
690 MadeChange |= mergeSExts(
F);
691 if (!LargeOffsetGEPMap.
empty())
692 MadeChange |= splitLargeGEPOffsets();
693 MadeChange |= optimizePhiTypes(
F);
696 eliminateFallThrough(
F, DT.get());
700 LI->verify(getDT(
F));
704 for (Instruction *
I : RemovedInsts)
707 EverMadeChange |= MadeChange;
708 SeenChainsForSExt.
clear();
709 ValToSExtendedUses.clear();
710 RemovedInsts.clear();
711 LargeOffsetGEPMap.
clear();
712 LargeOffsetGEPID.
clear();
723 SmallSetVector<BasicBlock *, 8> WorkList;
724 for (BasicBlock &BB :
F) {
730 for (BasicBlock *Succ : Successors)
736 MadeChange |= !WorkList.
empty();
737 while (!WorkList.
empty()) {
743 for (BasicBlock *Succ : Successors)
750 if (EverMadeChange || MadeChange)
751 MadeChange |= eliminateFallThrough(
F);
753 EverMadeChange |= MadeChange;
758 for (BasicBlock &BB :
F)
759 for (Instruction &
I : BB)
762 for (
auto &
I : Statepoints)
763 EverMadeChange |= simplifyOffsetableRelocate(*
I);
768 EverMadeChange |= placeDbgValues(
F);
769 EverMadeChange |= placePseudoProbes(
F);
776 return EverMadeChange;
779bool CodeGenPrepare::eliminateAssumptions(Function &
F) {
780 bool MadeChange =
false;
781 for (BasicBlock &BB :
F) {
782 CurInstIterator = BB.begin();
783 while (CurInstIterator != BB.end()) {
788 Assume->eraseFromParent();
790 resetIteratorIfInvalidatedWhileCalling(&BB, [&]() {
801void CodeGenPrepare::removeAllAssertingVHReferences(
Value *V) {
802 LargeOffsetGEPMap.
erase(V);
803 NewGEPBases.
erase(V);
811 auto VecI = LargeOffsetGEPMap.
find(
GEP->getPointerOperand());
812 if (VecI == LargeOffsetGEPMap.
end())
815 auto &GEPVector = VecI->second;
818 if (GEPVector.empty())
819 LargeOffsetGEPMap.
erase(VecI);
823[[maybe_unused]]
void CodeGenPrepare::verifyBFIUpdates(Function &
F) {
824 DominatorTree NewDT(
F);
825 LoopInfo NewLI(NewDT);
826 BranchProbabilityInfo NewBPI(
F, NewLI, TLInfo);
827 BlockFrequencyInfo NewBFI(
F, NewBPI, NewLI);
828 NewBFI.verifyMatch(*BFI);
834bool CodeGenPrepare::eliminateFallThrough(Function &
F, DominatorTree *DT) {
842 SmallSet<WeakTrackingVH, 16> Preds;
843 for (
auto &
Block : Blocks) {
849 BasicBlock *SinglePred = BB->getSinglePredecessor();
852 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
860 if (Term && !
Term->isConditional()) {
872 FreshBBs.
insert(SinglePred);
880 for (
const auto &Pred : Preds)
888BasicBlock *CodeGenPrepare::findDestBlockOfMergeableEmptyBlock(BasicBlock *BB) {
897 if (BBI != BB->
begin()) {
908 if (!canMergeBlocks(BB, DestBB))
918bool CodeGenPrepare::eliminateMostlyEmptyBlocks(Function &
F) {
919 SmallPtrSet<BasicBlock *, 16> Preheaders;
921 while (!LoopList.empty()) {
922 Loop *
L = LoopList.pop_back_val();
924 if (BasicBlock *Preheader =
L->getLoopPreheader())
925 Preheaders.
insert(Preheader);
928 bool MadeChange =
false;
940 for (
auto &
Block : Blocks) {
944 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
946 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.
count(BB)))
949 eliminateMostlyEmptyBlock(BB);
955bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB,
1006 SmallPtrSet<BasicBlock *, 16> SameIncomingValueBBs;
1011 if (DestBBPred == BB)
1015 return DestPN.getIncomingValueForBlock(BB) ==
1016 DestPN.getIncomingValueForBlock(DestBBPred);
1018 SameIncomingValueBBs.
insert(DestBBPred);
1024 if (SameIncomingValueBBs.
count(Pred))
1027 BlockFrequency PredFreq = BFI->getBlockFreq(Pred);
1028 BlockFrequency
BBFreq = BFI->getBlockFreq(BB);
1030 for (
auto *SameValueBB : SameIncomingValueBBs)
1031 if (SameValueBB->getUniquePredecessor() == Pred &&
1032 DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
1033 BBFreq += BFI->getBlockFreq(SameValueBB);
1036 return !Limit || PredFreq <= *Limit;
1042bool CodeGenPrepare::canMergeBlocks(
const BasicBlock *BB,
1043 const BasicBlock *DestBB)
const {
1047 for (
const PHINode &PN : BB->
phis()) {
1048 for (
const User *U : PN.users()) {
1057 for (
unsigned I = 0,
E = UPN->getNumIncomingValues();
I !=
E; ++
I) {
1060 Insn->
getParent() != UPN->getIncomingBlock(
I))
1075 SmallPtrSet<const BasicBlock *, 16> BBPreds;
1078 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1079 BBPreds.
insert(BBPN->getIncomingBlock(i));
1087 if (BBPreds.
count(Pred)) {
1088 for (
const PHINode &PN : DestBB->
phis()) {
1089 const Value *V1 = PN.getIncomingValueForBlock(Pred);
1090 const Value *V2 = PN.getIncomingValueForBlock(BB);
1094 if (V2PN->getParent() == BB)
1095 V2 = V2PN->getIncomingValueForBlock(Pred);
1125void CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
1135 if (SinglePred != DestBB) {
1136 assert(SinglePred == BB &&
1137 "Single predecessor not the same as predecessor");
1146 FreshBBs.
insert(SinglePred);
1147 FreshBBs.
erase(DestBB);
1155 for (PHINode &PN : DestBB->
phis()) {
1157 Value *InVal = PN.removeIncomingValue(BB,
false);
1162 if (InValPhi && InValPhi->
getParent() == BB) {
1171 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1172 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1175 PN.addIncoming(InVal, Pred);
1205 for (
auto *ThisRelocate : AllRelocateCalls) {
1206 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1207 ThisRelocate->getDerivedPtrIndex());
1208 RelocateIdxMap.
insert(std::make_pair(K, ThisRelocate));
1210 for (
auto &Item : RelocateIdxMap) {
1211 std::pair<unsigned, unsigned>
Key = Item.first;
1212 if (
Key.first ==
Key.second)
1217 auto BaseKey = std::make_pair(
Key.first,
Key.first);
1220 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1221 if (MaybeBase == RelocateIdxMap.
end())
1226 RelocateInstMap[MaybeBase->second].push_back(
I);
1234 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1237 if (!
Op ||
Op->getZExtValue() > 20)
1241 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1251 bool MadeChange =
false;
1258 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1259 &*R != RelocatedBase; ++R)
1263 RelocatedBase->
moveBefore(RI->getIterator());
1270 "Not relocating a derived object of the original base object");
1271 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1276 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1286 if (!Derived || Derived->getPointerOperand() !=
Base)
1295 "Should always have one since it's not a terminator");
1299 Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
1323 Value *ActualRelocatedBase = RelocatedBase;
1324 if (RelocatedBase->
getType() !=
Base->getType()) {
1325 ActualRelocatedBase =
1326 Builder.CreateBitCast(RelocatedBase,
Base->getType());
1328 Value *Replacement =
1329 Builder.CreateGEP(Derived->getSourceElementType(), ActualRelocatedBase,
1335 Value *ActualReplacement = Replacement;
1336 if (Replacement->
getType() != ToReplace->getType()) {
1338 Builder.CreateBitCast(Replacement, ToReplace->
getType());
1341 ToReplace->eraseFromParent();
1365bool CodeGenPrepare::simplifyOffsetableRelocate(GCStatepointInst &
I) {
1366 bool MadeChange =
false;
1368 for (
auto *U :
I.users())
1375 if (AllRelocateCalls.
size() < 2)
1380 MapVector<GCRelocateInst *, SmallVector<GCRelocateInst *, 0>> RelocateInstMap;
1382 if (RelocateInstMap.
empty())
1385 for (
auto &Item : RelocateInstMap)
1399 bool MadeChange =
false;
1402 Use &TheUse = UI.getUse();
1409 UserBB = PN->getIncomingBlock(TheUse);
1417 if (
User->isEHPad())
1427 if (UserBB == DefBB)
1431 CastInst *&InsertedCast = InsertedCasts[UserBB];
1433 if (!InsertedCast) {
1441 TheUse = InsertedCast;
1467 ASC->getDestAddressSpace()))
1522static std::optional<std::pair<Instruction *, Constant *>>
1525 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1526 return std::nullopt;
1529 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1530 return std::nullopt;
1534 return std::make_pair(IVInc, Step);
1535 return std::nullopt;
1548 return IVInc->first ==
I;
1552bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
1556 auto IsReplacableIVIncrement = [
this, &
Cmp](BinaryOperator *BO) {
1559 const Loop *
L = LI->getLoopFor(BO->
getParent());
1560 assert(L &&
"L should not be null after isIVIncrement()");
1562 if (LI->getLoopFor(
Cmp->getParent()) != L)
1568 auto &DT = getDT(*BO->
getParent()->getParent());
1577 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1600 if (BO->
getOpcode() == Instruction::Add &&
1601 IID == Intrinsic::usub_with_overflow) {
1608 for (Instruction &Iter : *
Cmp->getParent()) {
1611 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1616 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1619 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1620 if (BO->
getOpcode() != Instruction::Xor) {
1621 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1625 "Patterns with XOr should use the BO only in the compare");
1626 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1628 Cmp->eraseFromParent();
1638 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1646 B = ConstantInt::get(
B->getType(), 1);
1654 for (
User *U :
A->users()) {
1665bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp,
1666 ModifyDT &ModifiedDT) {
1667 bool EdgeCase =
false;
1669 BinaryOperator *
Add;
1674 A =
Add->getOperand(0);
1675 B =
Add->getOperand(1);
1681 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1687 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1690 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1691 Intrinsic::uadd_with_overflow))
1695 ModifiedDT = ModifyDT::ModifyInstDT;
1699bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
1700 ModifyDT &ModifiedDT) {
1707 ICmpInst::Predicate Pred =
Cmp->getPredicate();
1708 if (Pred == ICmpInst::ICMP_UGT) {
1710 Pred = ICmpInst::ICMP_ULT;
1714 B = ConstantInt::get(
B->getType(), 1);
1715 Pred = ICmpInst::ICMP_ULT;
1720 Pred = ICmpInst::ICMP_ULT;
1722 if (Pred != ICmpInst::ICMP_ULT)
1729 BinaryOperator *
Sub =
nullptr;
1730 for (User *U : CmpVariableOperand->
users()) {
1738 const APInt *CmpC, *AddC;
1750 Sub->hasNUsesOrMore(1)))
1756 if (
Sub->getParent() !=
Cmp->getParent() && !
Sub->hasOneUse())
1759 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1760 Cmp, Intrinsic::usub_with_overflow))
1764 ModifiedDT = ModifyDT::ModifyInstDT;
1771bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1785 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1791 Type *OpTy =
X->getType();
1799 if (Pred == ICmpInst::ICMP_EQ) {
1800 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1801 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1803 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1809 if (IsPowerOf2OrZeroTest ||
1820 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1829 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1832 Cmp->replaceAllUsesWith(NewCmp);
1852 bool UsedInPhiOrCurrentBlock =
any_of(Cmp->users(), [Cmp](
User *U) {
1853 return isa<PHINode>(U) ||
1854 cast<Instruction>(U)->getParent() == Cmp->getParent();
1859 if (UsedInPhiOrCurrentBlock && Cmp->getOperand(0)->getType()->isIntegerTy() &&
1860 Cmp->getOperand(0)->getType()->getScalarSizeInBits() >
1861 DL.getLargestLegalIntTypeSizeInBits())
1867 bool MadeChange =
false;
1870 Use &TheUse = UI.getUse();
1885 if (UserBB == DefBB)
1889 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1895 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1902 TheUse = InsertedCmp;
1908 if (Cmp->use_empty()) {
1909 Cmp->eraseFromParent();
1946 for (
User *U : Cmp->users()) {
1968 if (CmpBB != FalseBB)
1971 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
1985 for (
User *U : Cmp->users()) {
1994 SI->swapProfMetadata();
2006 Value *Op0 = Cmp->getOperand(0);
2007 Value *Op1 = Cmp->getOperand(1);
2016 unsigned NumInspected = 0;
2019 if (++NumInspected > 128)
2027 if (GoodToSwap > 0) {
2028 Cmp->swapOperands();
2048 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
2051 auto [ClassVal, ClassTest] =
2057 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2061 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
2062 Cmp->replaceAllUsesWith(IsFPClass);
2070 Value *Incr, *RemAmt;
2075 Value *AddInst, *AddOffset;
2078 if (PN !=
nullptr) {
2080 AddOffset =
nullptr;
2089 if (PN !=
nullptr) {
2102 if (PN->getNumIncomingValues() != 2)
2107 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2111 if (!L->contains(Rem))
2115 if (!L->isLoopInvariant(RemAmt))
2119 if (AddOffset && !L->isLoopInvariant(AddOffset))
2140 AddInstOut = AddInst;
2141 AddOffsetOut = AddOffset;
2160 Value *AddOffset, *RemAmt, *AddInst;
2163 AddOffset, LoopIncrPN))
2188 assert(AddOffset &&
"We found an add but missing values");
2207 Builder.SetInsertPoint(LoopIncrPN);
2208 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2213 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2218 NewRem->
addIncoming(Start, L->getLoopPreheader());
2223 FreshBBs.
insert(L->getLoopLatch());
2234bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2240bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2244 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2247 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2250 if (unfoldPowerOf2Test(Cmp))
2271 SetOfInstrs &InsertedInsts) {
2274 assert(!InsertedInsts.count(AndI) &&
2275 "Attempting to optimize already optimized and instruction");
2276 (void)InsertedInsts;
2290 for (
auto *U : AndI->
users()) {
2298 if (!CmpC || !CmpC->
isZero())
2313 Use &TheUse = UI.getUse();
2331 TheUse = InsertedAnd;
2348 if (
User->getOpcode() != Instruction::And ||
2354 if ((Cimm & (Cimm + 1)).getBoolValue())
2368 bool MadeChange =
false;
2371 TruncE = TruncI->user_end();
2372 TruncUI != TruncE;) {
2374 Use &TruncTheUse = TruncUI.getUse();
2399 if (UserBB == TruncUserBB)
2403 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2405 if (!InsertedShift && !InsertedTrunc) {
2409 if (ShiftI->
getOpcode() == Instruction::AShr)
2411 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2414 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2422 TruncInsertPt.setHeadBit(
true);
2423 assert(TruncInsertPt != TruncUserBB->
end());
2427 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2428 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2432 TruncTheUse = InsertedTrunc;
2465 bool MadeChange =
false;
2468 Use &TheUse = UI.getUse();
2482 if (UserBB == DefBB) {
2510 if (!InsertedShift) {
2514 if (ShiftI->
getOpcode() == Instruction::AShr)
2516 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2519 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2527 TheUse = InsertedShift;
2574 unsigned SizeInBits = Ty->getScalarSizeInBits();
2575 if (Ty->isVectorTy())
2587 FreshBBs.
insert(CallBlock);
2594 SplitPt.setHeadBit(
true);
2597 FreshBBs.
insert(EndBlock);
2602 L->addBasicBlockToLoop(CallBlock, LI);
2603 L->addBasicBlockToLoop(EndBlock, LI);
2609 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2616 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2617 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2618 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2623 Builder.SetInsertPoint(EndBlock, EndBlock->
begin());
2624 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2634 ModifiedDT = ModifyDT::ModifyBBDT;
2638bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2642 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2650 for (
auto &Arg : CI->
args()) {
2655 if (!Arg->getType()->isPointerTy())
2657 APInt
Offset(
DL->getIndexSizeInBits(
2660 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2661 uint64_t Offset2 =
Offset.getLimitedValue();
2683 MaybeAlign MIDestAlign =
MI->getDestAlign();
2684 if (!MIDestAlign || DestAlign > *MIDestAlign)
2685 MI->setDestAlignment(DestAlign);
2687 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2689 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2690 MTI->setSourceAlignment(SrcAlign);
2700 for (
auto &Arg : CI->
args()) {
2701 if (!Arg->getType()->isPointerTy())
2703 unsigned AS = Arg->getType()->getPointerAddressSpace();
2704 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2710 switch (
II->getIntrinsicID()) {
2713 case Intrinsic::assume:
2715 case Intrinsic::allow_runtime_check:
2716 case Intrinsic::allow_ubsan_check:
2717 case Intrinsic::experimental_widenable_condition: {
2721 if (
II->use_empty()) {
2722 II->eraseFromParent();
2726 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2731 case Intrinsic::objectsize:
2733 case Intrinsic::is_constant:
2735 case Intrinsic::aarch64_stlxr:
2736 case Intrinsic::aarch64_stxr: {
2745 InsertedInsts.insert(ExtVal);
2749 case Intrinsic::launder_invariant_group:
2750 case Intrinsic::strip_invariant_group: {
2751 Value *ArgVal =
II->getArgOperand(0);
2752 auto it = LargeOffsetGEPMap.
find(
II);
2753 if (it != LargeOffsetGEPMap.
end()) {
2757 auto GEPs = std::move(it->second);
2758 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2763 II->eraseFromParent();
2766 case Intrinsic::cttz:
2767 case Intrinsic::ctlz:
2771 case Intrinsic::fshl:
2772 case Intrinsic::fshr:
2773 return optimizeFunnelShift(
II);
2774 case Intrinsic::masked_gather:
2775 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2776 case Intrinsic::masked_scatter:
2777 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2778 case Intrinsic::masked_load:
2781 if (VT->getNumElements() == 1) {
2782 Value *PtrVal =
II->getArgOperand(0);
2784 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2789 case Intrinsic::masked_store:
2793 if (VT->getNumElements() == 1) {
2794 Value *PtrVal =
II->getArgOperand(1);
2796 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2801 case Intrinsic::umul_with_overflow:
2802 return optimizeMulWithOverflow(
II,
false, ModifiedDT);
2803 case Intrinsic::smul_with_overflow:
2804 return optimizeMulWithOverflow(
II,
true, ModifiedDT);
2807 SmallVector<Value *, 2> PtrOps;
2810 while (!PtrOps.
empty()) {
2813 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2827 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2829 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2839 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2840 if (!
F->getReturnType()->isPointerTy())
2843 GlobalVariable *UniformValue =
nullptr;
2844 for (
auto &BB : *
F) {
2849 else if (V != UniformValue)
2857 return UniformValue;
2860 if (
Callee->hasExactDefinition()) {
2861 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2862 bool MadeChange =
false;
2888 switch (
II->getIntrinsicID()) {
2889 case Intrinsic::memset:
2890 case Intrinsic::memcpy:
2891 case Intrinsic::memmove:
2899 if (Callee && TLInfo && TLInfo->
getLibFunc(*Callee, LF))
2901 case LibFunc_strcpy:
2902 case LibFunc_strncpy:
2903 case LibFunc_strcat:
2904 case LibFunc_strncat:
2945bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
2946 ModifyDT &ModifiedDT) {
2954 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2956 PHINode *PN =
nullptr;
2957 ExtractValueInst *EVI =
nullptr;
2958 BitCastInst *BCI =
nullptr;
2978 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
2984 return II->getIntrinsicID() == Intrinsic::lifetime_end;
2990 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
2992 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
3014 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
3064 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
3066 if (!VisitedBBs.
insert(Pred).second)
3068 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
3086 for (
auto const &TailCallBB : TailCallBBs) {
3096 BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB));
3097 BFI->setBlockFreq(BB,
3098 (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB)));
3099 ModifiedDT = ModifyDT::ModifyBBDT;
3108 for (
auto *CI : CallInsts) {
3109 for (
auto const *FakeUse : FakeUses) {
3110 auto *ClonedInst = FakeUse->clone();
3128struct ExtAddrMode :
public TargetLowering::AddrMode {
3129 Value *BaseReg =
nullptr;
3130 Value *ScaledReg =
nullptr;
3131 Value *OriginalValue =
nullptr;
3132 bool InBounds =
true;
3136 BaseRegField = 0x01,
3138 BaseOffsField = 0x04,
3139 ScaledRegField = 0x08,
3141 MultipleFields = 0xff
3144 ExtAddrMode() =
default;
3146 void print(raw_ostream &OS)
const;
3153 if (ScaledReg == From)
3157 FieldName
compare(
const ExtAddrMode &other) {
3160 if (BaseReg && other.
BaseReg &&
3162 return MultipleFields;
3163 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3164 return MultipleFields;
3167 return MultipleFields;
3170 if (InBounds != other.InBounds)
3171 return MultipleFields;
3174 unsigned Result = NoField;
3177 if (BaseGV != other.BaseGV)
3179 if (BaseOffs != other.BaseOffs)
3182 Result |= ScaledRegField;
3185 if (Scale && other.
Scale && Scale != other.
Scale)
3189 return MultipleFields;
3191 return static_cast<FieldName
>(
Result);
3201 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3212 case ScaledRegField:
3219 void SetCombinedField(FieldName
Field,
Value *V,
3220 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3225 case ExtAddrMode::BaseRegField:
3228 case ExtAddrMode::BaseGVField:
3231 assert(BaseReg ==
nullptr);
3235 case ExtAddrMode::ScaledRegField:
3240 for (
const ExtAddrMode &AM : AddrModes)
3246 case ExtAddrMode::BaseOffsField:
3249 assert(ScaledReg ==
nullptr);
3259static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3265#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3266void ExtAddrMode::print(raw_ostream &OS)
const {
3267 bool NeedPlus =
false;
3273 BaseGV->printAsOperand(OS,
false);
3278 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3283 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3284 BaseReg->printAsOperand(OS,
false);
3288 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3311class TypePromotionTransaction {
3315 class TypePromotionAction {
3323 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3325 virtual ~TypePromotionAction() =
default;
3332 virtual void undo() = 0;
3337 virtual void commit() {
3343 class InsertionHandler {
3352 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3355 bool HasPrevInstruction;
3359 InsertionHandler(Instruction *Inst) {
3367 if (HasPrevInstruction) {
3375 void insert(Instruction *Inst) {
3376 if (HasPrevInstruction) {
3388 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3393 class InstructionMoveBefore :
public TypePromotionAction {
3395 InsertionHandler Position;
3400 : TypePromotionAction(Inst), Position(Inst) {
3401 LLVM_DEBUG(
dbgs() <<
"Do: move: " << *Inst <<
"\nbefore: " << *Before
3407 void undo()
override {
3409 Position.insert(Inst);
3414 class OperandSetter :
public TypePromotionAction {
3423 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3424 : TypePromotionAction(Inst), Idx(Idx) {
3426 <<
"for:" << *Inst <<
"\n"
3427 <<
"with:" << *NewVal <<
"\n");
3433 void undo()
override {
3435 <<
"for: " << *Inst <<
"\n"
3436 <<
"with: " << *Origin <<
"\n");
3443 class OperandsHider :
public TypePromotionAction {
3449 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3452 OriginalValues.
reserve(NumOpnds);
3453 for (
unsigned It = 0; It < NumOpnds; ++It) {
3465 void undo()
override {
3467 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3473 class TruncBuilder :
public TypePromotionAction {
3480 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3482 Builder.SetCurrentDebugLocation(
DebugLoc());
3483 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3488 Value *getBuiltValue() {
return Val; }
3491 void undo()
override {
3494 IVal->eraseFromParent();
3499 class SExtBuilder :
public TypePromotionAction {
3506 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3507 : TypePromotionAction(InsertPt) {
3509 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3514 Value *getBuiltValue() {
return Val; }
3517 void undo()
override {
3520 IVal->eraseFromParent();
3525 class ZExtBuilder :
public TypePromotionAction {
3532 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3533 : TypePromotionAction(InsertPt) {
3535 Builder.SetCurrentDebugLocation(
DebugLoc());
3536 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3541 Value *getBuiltValue() {
return Val; }
3544 void undo()
override {
3547 IVal->eraseFromParent();
3552 class TypeMutator :
public TypePromotionAction {
3558 TypeMutator(Instruction *Inst,
Type *NewTy)
3559 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3560 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3566 void undo()
override {
3567 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3574 class UsesReplacer :
public TypePromotionAction {
3576 struct InstructionAndIdx {
3583 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3584 : Inst(Inst), Idx(Idx) {}
3590 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3600 UsesReplacer(Instruction *Inst,
Value *New)
3601 : TypePromotionAction(Inst),
New(
New) {
3602 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3605 for (Use &U : Inst->
uses()) {
3607 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3618 void undo()
override {
3620 for (InstructionAndIdx &Use : OriginalUses)
3621 Use.Inst->setOperand(
Use.Idx, Inst);
3626 for (DbgVariableRecord *DVR : DbgVariableRecords)
3627 DVR->replaceVariableLocationOp(New, Inst);
3632 class InstructionRemover :
public TypePromotionAction {
3634 InsertionHandler Inserter;
3638 OperandsHider Hider;
3641 UsesReplacer *Replacer =
nullptr;
3644 SetOfInstrs &RemovedInsts;
3651 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3652 Value *New =
nullptr)
3653 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3654 RemovedInsts(RemovedInsts) {
3656 Replacer =
new UsesReplacer(Inst, New);
3657 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3658 RemovedInsts.insert(Inst);
3665 ~InstructionRemover()
override {
delete Replacer; }
3667 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3668 InstructionRemover(
const InstructionRemover &other) =
delete;
3672 void undo()
override {
3673 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3674 Inserter.insert(Inst);
3678 RemovedInsts.erase(Inst);
3686 using ConstRestorationPt =
const TypePromotionAction *;
3688 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3689 : RemovedInsts(RemovedInsts) {}
3696 void rollback(ConstRestorationPt Point);
3699 ConstRestorationPt getRestorationPoint()
const;
3704 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3713 void mutateType(Instruction *Inst,
Type *NewTy);
3716 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3729 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3731 SetOfInstrs &RemovedInsts;
3736void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3738 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3739 Inst, Idx, NewVal));
3742void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3745 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3746 Inst, RemovedInsts, NewVal));
3749void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3752 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3755void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3757 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3760Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3761 std::unique_ptr<TruncBuilder> Ptr(
new TruncBuilder(Opnd, Ty));
3762 Value *Val = Ptr->getBuiltValue();
3763 Actions.push_back(std::move(Ptr));
3767Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3769 std::unique_ptr<SExtBuilder> Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3770 Value *Val = Ptr->getBuiltValue();
3771 Actions.push_back(std::move(Ptr));
3775Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3777 std::unique_ptr<ZExtBuilder> Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3778 Value *Val = Ptr->getBuiltValue();
3779 Actions.push_back(std::move(Ptr));
3783TypePromotionTransaction::ConstRestorationPt
3784TypePromotionTransaction::getRestorationPoint()
const {
3785 return !Actions.empty() ? Actions.back().get() :
nullptr;
3788bool TypePromotionTransaction::commit() {
3789 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3796void TypePromotionTransaction::rollback(
3797 TypePromotionTransaction::ConstRestorationPt Point) {
3798 while (!Actions.empty() && Point != Actions.back().get()) {
3799 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3809class AddressingModeMatcher {
3810 SmallVectorImpl<Instruction *> &AddrModeInsts;
3811 const TargetLowering &TLI;
3812 const TargetRegisterInfo &
TRI;
3813 const DataLayout &
DL;
3815 const std::function<
const DominatorTree &()> getDTFn;
3828 const SetOfInstrs &InsertedInsts;
3831 InstrToOrigTy &PromotedInsts;
3834 TypePromotionTransaction &TPT;
3837 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3841 bool IgnoreProfitability;
3844 bool OptSize =
false;
3846 ProfileSummaryInfo *PSI;
3847 BlockFrequencyInfo *BFI;
3849 AddressingModeMatcher(
3850 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3851 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3852 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3853 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3854 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3855 TypePromotionTransaction &TPT,
3856 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3857 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI)
3858 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3859 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3860 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3861 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3862 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI), BFI(BFI) {
3863 IgnoreProfitability =
false;
3875 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3876 SmallVectorImpl<Instruction *> &AddrModeInsts,
3877 const TargetLowering &TLI,
const LoopInfo &LI,
3878 const std::function<
const DominatorTree &()> getDTFn,
3879 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3880 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3881 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3882 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
3885 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3886 AccessTy, AS, MemoryInst, Result,
3887 InsertedInsts, PromotedInsts, TPT,
3888 LargeOffsetGEP, OptSize, PSI, BFI)
3896 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3898 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3899 bool *MovedAway =
nullptr);
3900 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3901 ExtAddrMode &AMBefore,
3902 ExtAddrMode &AMAfter);
3903 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3904 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3905 Value *PromotedOperand)
const;
3911class PhiNodeSetIterator {
3912 PhiNodeSet *
const Set;
3913 size_t CurrentIndex = 0;
3918 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3920 PhiNodeSetIterator &operator++();
3936 friend class PhiNodeSetIterator;
3938 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3939 using iterator = PhiNodeSetIterator;
3954 size_t FirstValidElement = 0;
3960 bool insert(PHINode *Ptr) {
3961 if (NodeMap.insert(std::make_pair(Ptr,
NodeList.
size())).second) {
3971 bool erase(PHINode *Ptr) {
3972 if (NodeMap.erase(Ptr)) {
3973 SkipRemovedElements(FirstValidElement);
3983 FirstValidElement = 0;
3989 if (FirstValidElement == 0)
3990 SkipRemovedElements(FirstValidElement);
3991 return PhiNodeSetIterator(
this, FirstValidElement);
3998 size_t size()
const {
return NodeMap.size(); }
4001 size_t count(PHINode *Ptr)
const {
return NodeMap.count(Ptr); }
4009 void SkipRemovedElements(
size_t &CurrentIndex) {
4011 auto it = NodeMap.find(NodeList[CurrentIndex]);
4014 if (it != NodeMap.end() && it->second == CurrentIndex)
4021PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
4024PHINode *PhiNodeSetIterator::operator*()
const {
4026 "PhiNodeSet access out of range");
4027 return Set->NodeList[CurrentIndex];
4030PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
4032 "PhiNodeSet access out of range");
4034 Set->SkipRemovedElements(CurrentIndex);
4038bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
4039 return CurrentIndex ==
RHS.CurrentIndex;
4042bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
4043 return !((*this) ==
RHS);
4049class SimplificationTracker {
4050 DenseMap<Value *, Value *> Storage;
4053 PhiNodeSet AllPhiNodes;
4055 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
4060 auto SV = Storage.
find(V);
4061 if (SV == Storage.
end())
4069 void ReplacePhi(PHINode *From, PHINode *To) {
4070 Value *OldReplacement = Get(From);
4071 while (OldReplacement != From) {
4074 OldReplacement = Get(From);
4076 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
4079 AllPhiNodes.erase(From);
4083 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
4085 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
4087 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
4089 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4091 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4093 void destroyNewNodes(
Type *CommonType) {
4096 for (
auto *
I : AllPhiNodes) {
4097 I->replaceAllUsesWith(Dummy);
4098 I->eraseFromParent();
4100 AllPhiNodes.clear();
4101 for (
auto *
I : AllSelectNodes) {
4102 I->replaceAllUsesWith(Dummy);
4103 I->eraseFromParent();
4105 AllSelectNodes.clear();
4110class AddressingModeCombiner {
4111 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4112 typedef std::pair<PHINode *, PHINode *> PHIPair;
4119 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4122 bool AllAddrModesTrivial =
true;
4125 Type *CommonType =
nullptr;
4127 const DataLayout &
DL;
4133 Value *CommonValue =
nullptr;
4136 AddressingModeCombiner(
const DataLayout &
DL,
Value *OriginalValue)
4137 :
DL(
DL), Original(OriginalValue) {}
4139 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4142 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4147 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4151 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4154 if (AddrModes.
empty()) {
4162 ExtAddrMode::FieldName ThisDifferentField =
4163 AddrModes[0].compare(NewAddrMode);
4164 if (DifferentField == ExtAddrMode::NoField)
4165 DifferentField = ThisDifferentField;
4166 else if (DifferentField != ThisDifferentField)
4167 DifferentField = ExtAddrMode::MultipleFields;
4170 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4173 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4178 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4183 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4184 !NewAddrMode.HasBaseReg);
4201 bool combineAddrModes() {
4203 if (AddrModes.
size() == 0)
4207 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4212 if (AllAddrModesTrivial)
4215 if (!addrModeCombiningAllowed())
4221 FoldAddrToValueMapping
Map;
4222 if (!initializeMap(Map))
4225 CommonValue = findCommon(Map);
4227 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4228 return CommonValue !=
nullptr;
4234 void eraseCommonValueIfDead() {
4235 if (CommonValue && CommonValue->
use_empty())
4237 CommonInst->eraseFromParent();
4245 bool initializeMap(FoldAddrToValueMapping &Map) {
4248 SmallVector<Value *, 2> NullValue;
4249 Type *IntPtrTy =
DL.getIntPtrType(AddrModes[0].OriginalValue->
getType());
4250 for (
auto &AM : AddrModes) {
4251 Value *DV = AM.GetFieldAsValue(DifferentField, IntPtrTy);
4254 if (CommonType && CommonType !=
Type)
4257 Map[AM.OriginalValue] = DV;
4262 assert(CommonType &&
"At least one non-null value must be!");
4263 for (
auto *V : NullValue)
4291 Value *findCommon(FoldAddrToValueMapping &Map) {
4299 SimplificationTracker
ST;
4304 InsertPlaceholders(Map, TraverseOrder, ST);
4307 FillPlaceholders(Map, TraverseOrder, ST);
4310 ST.destroyNewNodes(CommonType);
4315 unsigned PhiNotMatchedCount = 0;
4317 ST.destroyNewNodes(CommonType);
4321 auto *
Result =
ST.Get(
Map.find(Original)->second);
4323 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4324 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4331 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4332 SmallSetVector<PHIPair, 8> &Matcher,
4333 PhiNodeSet &PhiNodesToMatch) {
4336 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4339 SmallSet<PHIPair, 8> Visited;
4340 while (!WorkList.
empty()) {
4342 if (!Visited.
insert(Item).second)
4349 for (
auto *
B : Item.first->blocks()) {
4350 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4351 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4352 if (FirstValue == SecondValue)
4362 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4367 if (Matcher.
count({FirstPhi, SecondPhi}))
4372 if (MatchedPHIs.
insert(FirstPhi).second)
4373 Matcher.
insert({FirstPhi, SecondPhi});
4375 WorkList.
push_back({FirstPhi, SecondPhi});
4384 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4385 unsigned &PhiNotMatchedCount) {
4389 SmallSetVector<PHIPair, 8> Matched;
4390 SmallPtrSet<PHINode *, 8> WillNotMatch;
4391 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4392 while (PhiNodesToMatch.size()) {
4393 PHINode *
PHI = *PhiNodesToMatch.begin();
4396 WillNotMatch.
clear();
4400 bool IsMatched =
false;
4401 for (
auto &
P :
PHI->getParent()->phis()) {
4403 if (PhiNodesToMatch.count(&
P))
4405 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4415 for (
auto MV : Matched)
4416 ST.ReplacePhi(MV.first, MV.second);
4421 if (!AllowNewPhiNodes)
4424 PhiNotMatchedCount += WillNotMatch.
size();
4425 for (
auto *
P : WillNotMatch)
4426 PhiNodesToMatch.erase(
P);
4431 void FillPlaceholders(FoldAddrToValueMapping &Map,
4432 SmallVectorImpl<Value *> &TraverseOrder,
4433 SimplificationTracker &ST) {
4434 while (!TraverseOrder.
empty()) {
4436 assert(
Map.contains(Current) &&
"No node to fill!!!");
4442 auto *TrueValue = CurrentSelect->getTrueValue();
4443 assert(
Map.contains(TrueValue) &&
"No True Value!");
4444 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4445 auto *FalseValue = CurrentSelect->getFalseValue();
4446 assert(
Map.contains(FalseValue) &&
"No False Value!");
4447 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4454 assert(
Map.contains(PV) &&
"No predecessor Value!");
4455 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4466 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4467 SmallVectorImpl<Value *> &TraverseOrder,
4468 SimplificationTracker &ST) {
4471 "Address must be a Phi or Select node");
4474 while (!Worklist.
empty()) {
4477 if (
Map.contains(Current))
4488 CurrentSelect->getName(),
4489 CurrentSelect->getIterator(), CurrentSelect);
4493 Worklist.
push_back(CurrentSelect->getTrueValue());
4494 Worklist.
push_back(CurrentSelect->getFalseValue());
4502 ST.insertNewPhi(
PHI);
4508 bool addrModeCombiningAllowed() {
4511 switch (DifferentField) {
4514 case ExtAddrMode::BaseRegField:
4516 case ExtAddrMode::BaseGVField:
4518 case ExtAddrMode::BaseOffsField:
4520 case ExtAddrMode::ScaledRegField:
4530bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4535 return matchAddr(ScaleReg,
Depth);
4546 ExtAddrMode TestAddrMode =
AddrMode;
4550 TestAddrMode.
Scale += Scale;
4564 ConstantInt *CI =
nullptr;
4565 Value *AddLHS =
nullptr;
4569 TestAddrMode.InBounds =
false;
4586 auto GetConstantStep =
4587 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4590 return std::nullopt;
4593 return std::nullopt;
4601 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4602 return std::nullopt;
4604 return std::make_pair(IVInc->first, ConstantStep->getValue());
4605 return std::nullopt;
4620 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4627 APInt Step = IVStep->second;
4629 if (
Offset.isSignedIntN(64)) {
4630 TestAddrMode.InBounds =
false;
4632 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4637 getDTFn().
dominates(IVInc, MemoryInst)) {
4657 switch (
I->getOpcode()) {
4658 case Instruction::BitCast:
4659 case Instruction::AddrSpaceCast:
4661 if (
I->getType() ==
I->getOperand(0)->getType())
4663 return I->getType()->isIntOrPtrTy();
4664 case Instruction::PtrToInt:
4667 case Instruction::IntToPtr:
4670 case Instruction::Add:
4672 case Instruction::Mul:
4673 case Instruction::Shl:
4676 case Instruction::GetElementPtr:
4704class TypePromotionHelper {
4707 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4708 Instruction *ExtOpnd,
bool IsSExt) {
4709 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4710 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4714 if (It->second.getInt() == ExtTy)
4720 ExtTy = BothExtension;
4722 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4729 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4730 Instruction *Opnd,
bool IsSExt) {
4731 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4732 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4733 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4734 return It->second.getPointer();
4749 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4750 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4754 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4767 static Value *promoteOperandForTruncAndAnyExt(
4768 Instruction *Ext, TypePromotionTransaction &TPT,
4769 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4770 SmallVectorImpl<Instruction *> *Exts,
4771 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4782 static Value *promoteOperandForOther(Instruction *Ext,
4783 TypePromotionTransaction &TPT,
4784 InstrToOrigTy &PromotedInsts,
4785 unsigned &CreatedInstsCost,
4786 SmallVectorImpl<Instruction *> *Exts,
4787 SmallVectorImpl<Instruction *> *Truncs,
4788 const TargetLowering &TLI,
bool IsSExt);
4791 static Value *signExtendOperandForOther(
4792 Instruction *Ext, TypePromotionTransaction &TPT,
4793 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4794 SmallVectorImpl<Instruction *> *Exts,
4795 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4796 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4797 Exts, Truncs, TLI,
true);
4801 static Value *zeroExtendOperandForOther(
4802 Instruction *Ext, TypePromotionTransaction &TPT,
4803 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4804 SmallVectorImpl<Instruction *> *Exts,
4805 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4806 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4807 Exts, Truncs, TLI,
false);
4812 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4813 InstrToOrigTy &PromotedInsts,
4814 unsigned &CreatedInstsCost,
4815 SmallVectorImpl<Instruction *> *Exts,
4816 SmallVectorImpl<Instruction *> *Truncs,
4817 const TargetLowering &TLI);
4828 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4829 const TargetLowering &TLI,
4830 const InstrToOrigTy &PromotedInsts);
4835bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4836 Type *ConsideredExtType,
4837 const InstrToOrigTy &PromotedInsts,
4857 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4858 (IsSExt && BinOp->hasNoSignedWrap())))
4862 if ((Inst->
getOpcode() == Instruction::And ||
4867 if (Inst->
getOpcode() == Instruction::Xor) {
4870 if (!Cst->getValue().isAllOnes())
4879 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4889 if (ExtInst->hasOneUse()) {
4891 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4924 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4937TypePromotionHelper::Action TypePromotionHelper::getAction(
4938 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4939 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
4941 "Unexpected instruction type");
4948 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4961 return promoteOperandForTruncAndAnyExt;
4967 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4970Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4971 Instruction *SExt, TypePromotionTransaction &TPT,
4972 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4973 SmallVectorImpl<Instruction *> *Exts,
4974 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4978 Value *ExtVal = SExt;
4979 bool HasMergedNonFreeExt =
false;
4983 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
4986 TPT.replaceAllUsesWith(SExt, ZExt);
4987 TPT.eraseInstruction(SExt);
4992 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
4994 CreatedInstsCost = 0;
4998 TPT.eraseInstruction(SExtOpnd);
5006 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
5014 TPT.eraseInstruction(ExtInst, NextVal);
5018Value *TypePromotionHelper::promoteOperandForOther(
5019 Instruction *Ext, TypePromotionTransaction &TPT,
5020 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5021 SmallVectorImpl<Instruction *> *Exts,
5022 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
5027 CreatedInstsCost = 0;
5033 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
5036 ITrunc->moveAfter(ExtOpnd);
5041 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
5044 TPT.setOperand(Ext, 0, ExtOpnd);
5054 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
5056 TPT.mutateType(ExtOpnd, Ext->
getType());
5058 TPT.replaceAllUsesWith(Ext, ExtOpnd);
5065 !shouldExtOperand(ExtOpnd,
OpIdx)) {
5074 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
5076 TPT.setOperand(ExtOpnd,
OpIdx, ConstantInt::get(Ext->
getType(), CstVal));
5087 Value *ValForExtOpnd = IsSExt
5088 ? TPT.createSExt(ExtOpnd, Opnd, Ext->
getType())
5089 : TPT.createZExt(ExtOpnd, Opnd, Ext->
getType());
5090 TPT.setOperand(ExtOpnd,
OpIdx, ValForExtOpnd);
5092 if (!InstForExtOpnd)
5098 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5101 TPT.eraseInstruction(Ext);
5113bool AddressingModeMatcher::isPromotionProfitable(
5114 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5115 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5120 if (NewCost > OldCost)
5122 if (NewCost < OldCost)
5141bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5153 case Instruction::PtrToInt:
5156 case Instruction::IntToPtr: {
5164 case Instruction::BitCast:
5174 case Instruction::AddrSpaceCast: {
5182 case Instruction::Add: {
5185 ExtAddrMode BackupAddrMode =
AddrMode;
5186 unsigned OldSize = AddrModeInsts.
size();
5191 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5192 TPT.getRestorationPoint();
5196 int First = 0, Second = 1;
5207 AddrModeInsts.
resize(OldSize);
5208 TPT.rollback(LastKnownGood);
5218 AddrModeInsts.
resize(OldSize);
5219 TPT.rollback(LastKnownGood);
5225 case Instruction::Mul:
5226 case Instruction::Shl: {
5230 if (!
RHS ||
RHS->getBitWidth() > 64)
5232 int64_t Scale = Opcode == Instruction::Shl
5233 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5234 :
RHS->getSExtValue();
5238 case Instruction::GetElementPtr: {
5241 int VariableOperand = -1;
5242 unsigned VariableScale = 0;
5244 int64_t ConstantOffset = 0;
5246 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5248 const StructLayout *SL =
DL.getStructLayout(STy);
5259 if (ConstantInt *CI =
5261 const APInt &CVal = CI->
getValue();
5268 if (VariableOperand != -1)
5272 VariableOperand = i;
5273 VariableScale = TypeSize;
5280 if (VariableOperand == -1) {
5281 AddrMode.BaseOffs += ConstantOffset;
5287 AddrMode.BaseOffs -= ConstantOffset;
5291 ConstantOffset > 0) {
5304 BasicBlock *Parent = BaseI ? BaseI->getParent()
5305 : &
GEP->getFunction()->getEntryBlock();
5307 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5315 ExtAddrMode BackupAddrMode =
AddrMode;
5316 unsigned OldSize = AddrModeInsts.
size();
5319 AddrMode.BaseOffs += ConstantOffset;
5328 AddrModeInsts.
resize(OldSize);
5336 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5341 AddrModeInsts.
resize(OldSize);
5346 AddrMode.BaseOffs += ConstantOffset;
5347 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5348 VariableScale,
Depth)) {
5351 AddrModeInsts.
resize(OldSize);
5358 case Instruction::SExt:
5359 case Instruction::ZExt: {
5366 TypePromotionHelper::Action TPH =
5367 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5371 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5372 TPT.getRestorationPoint();
5373 unsigned CreatedInstsCost = 0;
5375 Value *PromotedOperand =
5376 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5391 assert(PromotedOperand &&
5392 "TypePromotionHelper should have filtered out those cases");
5394 ExtAddrMode BackupAddrMode =
AddrMode;
5395 unsigned OldSize = AddrModeInsts.
size();
5397 if (!matchAddr(PromotedOperand,
Depth) ||
5402 !isPromotionProfitable(CreatedInstsCost,
5403 ExtCost + (AddrModeInsts.
size() - OldSize),
5406 AddrModeInsts.
resize(OldSize);
5407 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5408 TPT.rollback(LastKnownGood);
5413 AddrMode.replaceWith(Ext, PromotedOperand);
5416 case Instruction::Call:
5418 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5434bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5437 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5438 TPT.getRestorationPoint();
5462 ExtAddrMode BackupAddrMode =
AddrMode;
5463 unsigned OldSize = AddrModeInsts.
size();
5466 bool MovedAway =
false;
5467 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5475 if (
I->hasOneUse() ||
5476 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5483 AddrModeInsts.
resize(OldSize);
5484 TPT.rollback(LastKnownGood);
5487 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5489 TPT.rollback(LastKnownGood);
5516 TPT.rollback(LastKnownGood);
5535 if (OpInfo.CallOperandVal == OpVal &&
5537 !OpInfo.isIndirect))
5553 if (!ConsideredInsts.
insert(
I).second)
5561 for (
Use &U :
I->uses()) {
5569 MemoryUses.push_back({&U, LI->getType()});
5576 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5583 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5590 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5600 if (!
find(PtrOps, U.get()))
5603 MemoryUses.push_back({&U, AccessTy});
5608 if (CI->hasFnAttr(Attribute::Cold)) {
5626 PSI, BFI, SeenInsts))
5637 unsigned SeenInsts = 0;
5640 PSI, BFI, SeenInsts);
5648bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5650 Value *KnownLive2) {
5652 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5693bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5694 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5695 if (IgnoreProfitability)
5713 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5714 ScaledReg =
nullptr;
5718 if (!BaseReg && !ScaledReg)
5739 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5742 Type *AddressAccessTy = Pair.second;
5743 unsigned AS =
Address->getType()->getPointerAddressSpace();
5749 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5751 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5752 TPT.getRestorationPoint();
5753 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5754 AddressAccessTy, AS, UserI, Result,
5755 InsertedInsts, PromotedInsts, TPT,
5756 LargeOffsetGEP, OptSize, PSI, BFI);
5757 Matcher.IgnoreProfitability =
true;
5765 TPT.rollback(LastKnownGood);
5771 MatchedAddrModeInsts.
clear();
5781 return I->getParent() != BB;
5797 return std::next(AddrInst->getIterator());
5808 Earliest = UserInst;
5833bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5834 Type *AccessTy,
unsigned AddrSpace) {
5839 SmallVector<Value *, 8> worklist;
5840 SmallPtrSet<Value *, 16> Visited;
5846 bool PhiOrSelectSeen =
false;
5847 SmallVector<Instruction *, 16> AddrModeInsts;
5848 AddressingModeCombiner AddrModes(*
DL, Addr);
5849 TypePromotionTransaction TPT(RemovedInsts);
5850 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5851 TPT.getRestorationPoint();
5852 while (!worklist.
empty()) {
5864 if (!Visited.
insert(V).second)
5870 PhiOrSelectSeen =
true;
5877 PhiOrSelectSeen =
true;
5884 AddrModeInsts.
clear();
5885 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5890 auto getDTFn = [MemoryInst,
this]() ->
const DominatorTree & {
5892 return this->getDT(*
F);
5894 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5895 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5896 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5899 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5904 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5905 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5908 NewAddrMode.OriginalValue =
V;
5909 if (!AddrModes.addNewAddrMode(NewAddrMode))
5916 if (!AddrModes.combineAddrModes()) {
5917 TPT.rollback(LastKnownGood);
5923 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5929 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5943 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
5965 <<
" for " << *MemoryInst <<
"\n");
5969 !
DL->isNonIntegralPointerType(Addr->
getType())) {
5975 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
5977 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
5979 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
5986 <<
" for " << *MemoryInst <<
"\n");
5987 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
5998 if (ResultPtr ||
AddrMode.Scale != 1)
6019 GlobalValue *BaseGV =
AddrMode.BaseGV;
6020 if (BaseGV !=
nullptr) {
6025 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
6034 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
6035 if (!ResultPtr &&
AddrMode.BaseReg) {
6039 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
6040 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
6049 }
else if (!ResultPtr) {
6062 if (
V->getType() != IntPtrTy)
6063 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6071 if (
V->getType() == IntPtrTy) {
6076 "We can't transform if ScaledReg is too narrow");
6077 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6081 V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy,
AddrMode.Scale),
6084 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6095 if (ResultPtr->
getType() != I8PtrTy)
6096 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6097 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6110 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6112 SunkAddr = ResultPtr;
6114 if (ResultPtr->
getType() != I8PtrTy)
6115 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6116 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6123 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6129 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
6131 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6133 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6143 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6144 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6145 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6147 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6151 <<
" for " << *MemoryInst <<
"\n");
6162 if (
V->getType()->isPointerTy())
6163 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6164 if (
V->getType() != IntPtrTy)
6165 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6172 if (
V->getType() == IntPtrTy) {
6174 }
else if (
V->getType()->isPointerTy()) {
6175 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6178 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6187 I->eraseFromParent();
6191 V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy,
AddrMode.Scale),
6194 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6200 GlobalValue *BaseGV =
AddrMode.BaseGV;
6201 if (BaseGV !=
nullptr) {
6204 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6208 Value *
V = Builder.CreatePtrToInt(BaseGVPtr, IntPtrTy,
"sunkaddr");
6210 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6219 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6227 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6233 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6238 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6239 RecursivelyDeleteTriviallyDeadInstructions(
6240 Repl, TLInfo, nullptr,
6241 [&](Value *V) { removeAllAssertingVHReferences(V); });
6265bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6271 if (!
GEP->hasIndices())
6279 SmallVector<Value *, 2>
Ops(
GEP->operands());
6281 bool RewriteGEP =
false;
6290 unsigned FinalIndex =
Ops.size() - 1;
6295 for (
unsigned i = 1; i < FinalIndex; ++i) {
6300 C =
C->getSplatValue();
6302 if (!CI || !CI->
isZero())
6309 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6313 if (!
C || !
C->isZero()) {
6314 Ops[FinalIndex] =
V;
6322 if (!RewriteGEP &&
Ops.size() == 2)
6329 Type *SourceTy =
GEP->getSourceElementType();
6330 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6334 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6335 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6336 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6346 if (
Ops.size() != 2) {
6356 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6370 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6371 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6374 Intrinsic::masked_gather) {
6378 Intrinsic::masked_scatter);
6393 Ptr, TLInfo,
nullptr,
6394 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6405 if (
I->hasNUsesOrMore(3))
6408 for (
User *U :
I->users()) {
6410 if (!Extract || Extract->getNumIndices() != 1)
6413 unsigned Index = Extract->getIndices()[0];
6415 MulExtract = Extract;
6416 else if (Index == 1)
6417 OverflowExtract = Extract;
6444bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
6445 ModifyDT &ModifiedDT) {
6452 ExtractValueInst *MulExtract =
nullptr, *OverflowExtract =
nullptr;
6457 InsertedInsts.insert(
I);
6467 I->getParent()->splitBasicBlock(
I,
"",
true);
6468 OverflowEntryBB->
takeName(
I->getParent());
6474 NoOverflowBB->
moveAfter(OverflowEntryBB);
6482 Value *LoLHS = Builder.CreateTrunc(
LHS, LegalTy,
"lo.lhs");
6483 Value *HiLHS = Builder.CreateLShr(
LHS, VTHalfBitWidth,
"lhs.lsr");
6484 HiLHS = Builder.CreateTrunc(HiLHS, LegalTy,
"hi.lhs");
6487 Value *LoRHS = Builder.CreateTrunc(
RHS, LegalTy,
"lo.rhs");
6488 Value *HiRHS = Builder.CreateLShr(
RHS, VTHalfBitWidth,
"rhs.lsr");
6489 HiRHS = Builder.CreateTrunc(HiRHS, LegalTy,
"hi.rhs");
6491 Value *IsAnyBitTrue;
6494 Builder.CreateAShr(LoLHS, VTHalfBitWidth - 1,
"sign.lo.lhs");
6496 Builder.CreateAShr(LoRHS, VTHalfBitWidth - 1,
"sign.lo.rhs");
6497 Value *XorLHS = Builder.CreateXor(HiLHS, SignLoLHS);
6498 Value *XorRHS = Builder.CreateXor(HiRHS, SignLoRHS);
6499 Value *
Or = Builder.CreateOr(XorLHS, XorRHS,
"or.lhs.rhs");
6500 IsAnyBitTrue = Builder.CreateCmp(ICmpInst::ICMP_NE,
Or,
6501 ConstantInt::getNullValue(
Or->getType()));
6503 Value *CmpLHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiLHS,
6504 ConstantInt::getNullValue(LegalTy));
6505 Value *CmpRHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiRHS,
6506 ConstantInt::getNullValue(LegalTy));
6507 IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS,
"or.lhs.rhs");
6509 Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
6512 Builder.SetInsertPoint(NoOverflowBB);
6513 Value *ExtLoLHS, *ExtLoRHS;
6515 ExtLoLHS = Builder.CreateSExt(LoLHS, Ty,
"lo.lhs.ext");
6516 ExtLoRHS = Builder.CreateSExt(LoRHS, Ty,
"lo.rhs.ext");
6518 ExtLoLHS = Builder.CreateZExt(LoLHS, Ty,
"lo.lhs.ext");
6519 ExtLoRHS = Builder.CreateZExt(LoRHS, Ty,
"lo.rhs.ext");
6522 Value *
Mul = Builder.CreateMul(ExtLoLHS, ExtLoRHS,
"mul.overflow.no");
6527 OverflowResBB->
setName(
"overflow.res");
6530 Builder.CreateBr(OverflowResBB);
6538 PHINode *OverflowResPHI = Builder.CreatePHI(Ty, 2),
6540 Builder.CreatePHI(IntegerType::getInt1Ty(
I->getContext()), 2);
6552 if (OverflowExtract) {
6553 OverflowExtract->replaceAllUsesWith(OverflowFlagPHI);
6554 OverflowExtract->eraseFromParent();
6559 I->removeFromParent();
6561 I->insertInto(OverflowBB, OverflowBB->
end());
6562 Builder.SetInsertPoint(OverflowBB, OverflowBB->
end());
6564 Value *OverflowFlag = Builder.CreateExtractValue(
I, {1},
"overflow.flag");
6565 Builder.CreateBr(OverflowResBB);
6569 OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
6571 ModifiedDT = ModifyDT::ModifyBBDT;
6577bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6578 bool MadeChange =
false;
6580 const TargetRegisterInfo *
TRI =
6585 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6591 OpInfo.isIndirect) {
6593 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6656bool CodeGenPrepare::tryToPromoteExts(
6657 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6658 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6659 unsigned CreatedInstsCost) {
6660 bool Promoted =
false;
6663 for (
auto *
I : Exts) {
6678 TypePromotionHelper::Action TPH =
6679 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6688 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6689 TPT.getRestorationPoint();
6690 SmallVector<Instruction *, 4> NewExts;
6691 unsigned NewCreatedInstsCost = 0;
6694 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6695 &NewExts,
nullptr, *TLI);
6697 "TypePromotionHelper should have filtered out those cases");
6707 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6710 TotalCreatedInstsCost =
6711 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6713 (TotalCreatedInstsCost > 1 ||
6715 (ExtCost == 0 && NewExts.
size() > 1))) {
6719 TPT.rollback(LastKnownGood);
6724 SmallVector<Instruction *, 2> NewlyMovedExts;
6725 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6726 bool NewPromoted =
false;
6727 for (
auto *ExtInst : NewlyMovedExts) {
6737 ProfitablyMovedExts.
push_back(MovedExt);
6744 TPT.rollback(LastKnownGood);
6755bool CodeGenPrepare::mergeSExts(Function &
F) {
6757 for (
auto &Entry : ValToSExtendedUses) {
6758 SExts &Insts =
Entry.second;
6760 for (Instruction *Inst : Insts) {
6764 bool inserted =
false;
6765 for (
auto &Pt : CurPts) {
6768 RemovedInsts.insert(Pt);
6769 Pt->removeFromParent();
6780 RemovedInsts.insert(Inst);
6787 CurPts.push_back(Inst);
6829bool CodeGenPrepare::splitLargeGEPOffsets() {
6831 for (
auto &Entry : LargeOffsetGEPMap) {
6833 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6834 &LargeOffsetGEPs =
Entry.second;
6835 auto compareGEPOffset =
6836 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6837 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6838 if (
LHS.first ==
RHS.first)
6840 if (
LHS.second !=
RHS.second)
6841 return LHS.second <
RHS.second;
6842 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6845 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6848 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6850 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6851 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6852 Value *NewBaseGEP =
nullptr;
6854 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6855 GetElementPtrInst *
GEP) {
6856 LLVMContext &Ctx =
GEP->getContext();
6857 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6859 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6871 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), DT.get(), LI);
6874 NewBaseInsertPt = std::next(BaseI->getIterator());
6881 IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
6883 Value *BaseIndex = ConstantInt::get(PtrIdxTy, BaseOffset);
6884 NewBaseGEP = OldBase;
6885 if (NewBaseGEP->
getType() != I8PtrTy)
6886 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6888 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6889 NewGEPBases.
insert(NewBaseGEP);
6895 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6896 BaseOffset = PreferBase;
6899 createNewBase(BaseOffset, OldBase, BaseGEP);
6902 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6903 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6904 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6905 int64_t
Offset = LargeOffsetGEP->second;
6906 if (
Offset != BaseOffset) {
6913 GEP->getResultElementType(),
6914 GEP->getAddressSpace())) {
6920 NewBaseGEP =
nullptr;
6925 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6930 createNewBase(BaseOffset, OldBase,
GEP);
6934 Value *NewGEP = NewBaseGEP;
6935 if (
Offset != BaseOffset) {
6938 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6942 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6943 GEP->eraseFromParent();
6950bool CodeGenPrepare::optimizePhiType(
6951 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
6952 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
6957 Type *PhiTy =
I->getType();
6958 Type *ConvertTy =
nullptr;
6960 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6963 SmallVector<Instruction *, 4> Worklist;
6965 SmallPtrSet<PHINode *, 4> PhiNodes;
6966 SmallPtrSet<ConstantData *, 4>
Constants;
6969 SmallPtrSet<Instruction *, 4> Defs;
6970 SmallPtrSet<Instruction *, 4>
Uses;
6976 bool AnyAnchored =
false;
6978 while (!Worklist.
empty()) {
6983 for (
Value *V :
Phi->incoming_values()) {
6985 if (!PhiNodes.
count(OpPhi)) {
6986 if (!Visited.
insert(OpPhi).second)
6992 if (!OpLoad->isSimple())
6994 if (Defs.
insert(OpLoad).second)
6997 if (Defs.
insert(OpEx).second)
7001 ConvertTy = OpBC->getOperand(0)->getType();
7002 if (OpBC->getOperand(0)->getType() != ConvertTy)
7004 if (Defs.
insert(OpBC).second) {
7017 for (User *V :
II->users()) {
7019 if (!PhiNodes.
count(OpPhi)) {
7020 if (Visited.
count(OpPhi))
7027 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
7029 Uses.insert(OpStore);
7032 ConvertTy = OpBC->getType();
7033 if (OpBC->getType() != ConvertTy)
7037 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
7044 if (!ConvertTy || !AnyAnchored ||
7048 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
7049 << *ConvertTy <<
"\n");
7054 for (ConstantData *
C : Constants)
7056 for (Instruction *
D : Defs) {
7058 ValMap[
D] =
D->getOperand(0);
7062 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
7065 for (PHINode *Phi : PhiNodes)
7067 Phi->getName() +
".tc",
Phi->getIterator());
7069 for (PHINode *Phi : PhiNodes) {
7071 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
7073 Phi->getIncomingBlock(i));
7077 for (Instruction *U :
Uses) {
7082 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
7092bool CodeGenPrepare::optimizePhiTypes(Function &
F) {
7097 SmallPtrSet<PHINode *, 4> Visited;
7098 SmallPtrSet<Instruction *, 4> DeletedInstrs;
7102 for (
auto &Phi : BB.
phis())
7103 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
7106 for (
auto *
I : DeletedInstrs) {
7108 I->eraseFromParent();
7116bool CodeGenPrepare::canFormExtLd(
7117 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
7118 Instruction *&Inst,
bool HasPromoted) {
7119 for (
auto *MovedExtInst : MovedExts) {
7122 Inst = MovedExtInst;
7174bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7175 bool AllowPromotionWithoutCommonHeader =
false;
7180 *Inst, AllowPromotionWithoutCommonHeader);
7181 TypePromotionTransaction TPT(RemovedInsts);
7182 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7183 TPT.getRestorationPoint();
7185 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7188 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7191 LoadInst *LI =
nullptr;
7196 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7197 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7202 Inst = ExtFedByLoad;
7207 if (ATPConsiderable &&
7208 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7209 HasPromoted, TPT, SpeculativelyMovedExts))
7212 TPT.rollback(LastKnownGood);
7221bool CodeGenPrepare::performAddressTypePromotion(
7222 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7223 bool HasPromoted, TypePromotionTransaction &TPT,
7224 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7225 bool Promoted =
false;
7226 SmallPtrSet<Instruction *, 1> UnhandledExts;
7227 bool AllSeenFirst =
true;
7228 for (
auto *
I : SpeculativelyMovedExts) {
7229 Value *HeadOfChain =
I->getOperand(0);
7230 DenseMap<Value *, Instruction *>::iterator AlreadySeen =
7231 SeenChainsForSExt.
find(HeadOfChain);
7234 if (AlreadySeen != SeenChainsForSExt.
end()) {
7235 if (AlreadySeen->second !=
nullptr)
7236 UnhandledExts.
insert(AlreadySeen->second);
7237 AllSeenFirst =
false;
7241 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7242 SpeculativelyMovedExts.size() == 1)) {
7246 for (
auto *
I : SpeculativelyMovedExts) {
7247 Value *HeadOfChain =
I->getOperand(0);
7248 SeenChainsForSExt[HeadOfChain] =
nullptr;
7249 ValToSExtendedUses[HeadOfChain].push_back(
I);
7252 Inst = SpeculativelyMovedExts.pop_back_val();
7257 for (
auto *
I : SpeculativelyMovedExts) {
7258 Value *HeadOfChain =
I->getOperand(0);
7259 SeenChainsForSExt[HeadOfChain] = Inst;
7264 if (!AllSeenFirst && !UnhandledExts.
empty())
7265 for (
auto *VisitedSExt : UnhandledExts) {
7266 if (RemovedInsts.count(VisitedSExt))
7268 TypePromotionTransaction TPT(RemovedInsts);
7270 SmallVector<Instruction *, 2> Chains;
7272 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7276 for (
auto *
I : Chains) {
7277 Value *HeadOfChain =
I->getOperand(0);
7279 SeenChainsForSExt[HeadOfChain] =
nullptr;
7280 ValToSExtendedUses[HeadOfChain].push_back(
I);
7286bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7291 Value *Src =
I->getOperand(0);
7292 if (Src->hasOneUse())
7304 bool DefIsLiveOut =
false;
7305 for (User *U :
I->users()) {
7310 if (UserBB == DefBB)
7312 DefIsLiveOut =
true;
7319 for (User *U : Src->users()) {
7322 if (UserBB == DefBB)
7331 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7333 bool MadeChange =
false;
7334 for (Use &U : Src->uses()) {
7339 if (UserBB == DefBB)
7343 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7345 if (!InsertedTrunc) {
7348 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7350 InsertedInsts.insert(InsertedTrunc);
7413bool CodeGenPrepare::optimizeLoadExt(LoadInst *Load) {
7414 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7418 if (
Load->hasOneUse() &&
7424 SmallVector<Instruction *, 8> WorkList;
7425 SmallPtrSet<Instruction *, 16> Visited;
7426 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7427 SmallVector<Instruction *, 8> DropFlags;
7428 for (
auto *U :
Load->users())
7440 while (!WorkList.
empty()) {
7444 if (!Visited.
insert(
I).second)
7449 for (
auto *U :
Phi->users())
7454 switch (
I->getOpcode()) {
7455 case Instruction::And: {
7459 APInt AndBits = AndC->getValue();
7460 DemandBits |= AndBits;
7462 if (AndBits.
ugt(WidestAndBits))
7463 WidestAndBits = AndBits;
7464 if (AndBits == WidestAndBits &&
I->getOperand(0) == Load)
7469 case Instruction::Shl: {
7473 uint64_t ShiftAmt = ShlC->getLimitedValue(
BitWidth - 1);
7474 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7479 case Instruction::Trunc: {
7482 DemandBits.setLowBits(TruncBitWidth);
7492 uint32_t ActiveBits = DemandBits.getActiveBits();
7504 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7505 WidestAndBits != DemandBits)
7508 LLVMContext &Ctx =
Load->getType()->getContext();
7509 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7519 Builder.CreateAnd(Load, ConstantInt::get(Ctx, DemandBits)));
7522 InsertedInsts.insert(NewAnd);
7527 NewAnd->setOperand(0, Load);
7530 for (
auto *
And : AndsToMaybeRemove)
7535 if (&*CurInstIterator ==
And)
7536 CurInstIterator = std::next(
And->getIterator());
7537 And->eraseFromParent();
7542 for (
auto *Inst : DropFlags)
7556 TTI->isExpensiveToSpeculativelyExecute(
I);
7574 uint64_t Max = std::max(TrueWeight, FalseWeight);
7575 uint64_t Sum = TrueWeight + FalseWeight;
7578 if (Probability >
TTI->getPredictableBranchThreshold())
7588 if (!Cmp || !Cmp->hasOneUse())
7611 assert(DefSI->getCondition() ==
SI->getCondition() &&
7612 "The condition of DefSI does not match with SI");
7613 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7616 assert(V &&
"Failed to get select true/false value");
7620bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7644 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7645 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7646 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7647 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7653bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7655 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7656 "Expected a funnel shift");
7680 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7681 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7682 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7690bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7702 It !=
SI->getParent()->
end(); ++It) {
7704 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7711 SelectInst *LastSI = ASI.
back();
7714 CurInstIterator = std::next(LastSI->
getIterator());
7718 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7719 fixupDbgVariableRecordsOnInst(*SI);
7721 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7724 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7727 TargetLowering::SelectSupportKind SelectKind;
7728 if (
SI->getType()->isVectorTy())
7729 SelectKind = TargetLowering::ScalarCondVectorVal;
7731 SelectKind = TargetLowering::ScalarValSelect;
7772 for (SelectInst *SI : ASI) {
7784 SplitPt.setHeadBit(
true);
7787 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7792 BranchInst *TrueBranch =
nullptr;
7793 BranchInst *FalseBranch =
nullptr;
7794 if (TrueInstrs.
size() == 0) {
7796 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7799 }
else if (FalseInstrs.
size() == 0) {
7801 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7808 nullptr,
nullptr, LI);
7816 EndBlock->
setName(
"select.end");
7818 TrueBlock->
setName(
"select.true.sink");
7820 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7821 :
"select.false.sink");
7825 FreshBBs.
insert(TrueBlock);
7827 FreshBBs.
insert(FalseBlock);
7828 FreshBBs.
insert(EndBlock);
7833 static const unsigned MD[] = {
7834 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7835 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7840 for (Instruction *
I : TrueInstrs)
7842 for (Instruction *
I : FalseInstrs)
7849 if (TrueBlock ==
nullptr)
7850 TrueBlock = StartBlock;
7851 else if (FalseBlock ==
nullptr)
7852 FalseBlock = StartBlock;
7868 SI->eraseFromParent();
7870 ++NumSelectsExpanded;
7874 CurInstIterator = StartBlock->
end();
7881bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7893 "Expected a type of the same size!");
7899 Builder.SetInsertPoint(SVI);
7900 Value *BC1 = Builder.CreateBitCast(
7902 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7903 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7907 SVI, TLInfo,
nullptr,
7908 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7915 !
Op->isTerminator() && !
Op->isEHPad())
7921bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7936 DenseMap<const Instruction *, unsigned long> InstOrdering;
7937 unsigned long InstNumber = 0;
7938 for (
const auto &
I : *TargetBB)
7939 InstOrdering[&
I] = InstNumber++;
7941 for (Use *U :
reverse(OpsToSink)) {
7946 if (InstOrdering[UI] < InstOrdering[InsertPoint])
7953 SetVector<Instruction *> MaybeDead;
7954 DenseMap<Instruction *, Instruction *> NewInstructions;
7955 for (Use *U : ToReplace) {
7964 FreshBBs.
insert(OpDef->getParent());
7967 NewInstructions[UI] = NI;
7972 InsertedInsts.insert(NI);
7978 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
7979 It->second->setOperand(
U->getOperandNo(), NI);
7986 for (
auto *
I : MaybeDead) {
7987 if (!
I->hasNUsesOrMore(1)) {
7989 I->eraseFromParent();
7996bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
8013 auto *NewType = Type::getIntNTy(
Context, RegWidth);
8022 ExtType = Instruction::SExt;
8025 if (Arg->hasSExtAttr())
8026 ExtType = Instruction::SExt;
8027 if (Arg->hasZExtAttr())
8028 ExtType = Instruction::ZExt;
8034 SI->setCondition(ExtInst);
8035 for (
auto Case :
SI->cases()) {
8036 const APInt &NarrowConst = Case.getCaseValue()->getValue();
8037 APInt WideConst = (ExtType == Instruction::ZExt)
8038 ? NarrowConst.
zext(RegWidth)
8039 : NarrowConst.
sext(RegWidth);
8040 Case.setValue(ConstantInt::get(
Context, WideConst));
8046bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
8053 Value *Condition =
SI->getCondition();
8062 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
8063 ConstantInt *CaseValue = Case.getCaseValue();
8064 BasicBlock *CaseBB = Case.getCaseSuccessor();
8067 bool CheckedForSinglePred =
false;
8068 for (PHINode &
PHI : CaseBB->
phis()) {
8069 Type *PHIType =
PHI.getType();
8077 if (PHIType == ConditionType || TryZExt) {
8079 bool SkipCase =
false;
8080 Value *Replacement =
nullptr;
8081 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
8082 Value *PHIValue =
PHI.getIncomingValue(
I);
8083 if (PHIValue != CaseValue) {
8092 if (
PHI.getIncomingBlock(
I) != SwitchBB)
8097 if (!CheckedForSinglePred) {
8098 CheckedForSinglePred =
true;
8099 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
8105 if (Replacement ==
nullptr) {
8106 if (PHIValue == CaseValue) {
8107 Replacement = Condition;
8110 Replacement = Builder.CreateZExt(Condition, PHIType);
8113 PHI.setIncomingValue(
I, Replacement);
8124bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
8125 bool Changed = optimizeSwitchType(SI);
8126 Changed |= optimizeSwitchPhiConstants(SI);
8147class VectorPromoteHelper {
8149 const DataLayout &
DL;
8152 const TargetLowering &TLI;
8155 const TargetTransformInfo &
TTI;
8161 SmallVector<Instruction *, 4> InstsToBePromoted;
8164 unsigned StoreExtractCombineCost;
8173 if (InstsToBePromoted.
empty())
8175 return InstsToBePromoted.
back();
8181 unsigned getTransitionOriginalValueIdx()
const {
8183 "Other kind of transitions are not supported yet");
8190 unsigned getTransitionIdx()
const {
8192 "Other kind of transitions are not supported yet");
8200 Type *getTransitionType()
const {
8211 void promoteImpl(Instruction *ToBePromoted);
8215 bool isProfitableToPromote() {
8216 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8220 Type *PromotedType = getTransitionType();
8223 unsigned AS =
ST->getPointerAddressSpace();
8241 for (
const auto &Inst : InstsToBePromoted) {
8249 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8261 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8262 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8263 return ScalarCost > VectorCost;
8275 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8290 if (!
EC.isScalable()) {
8293 for (
unsigned Idx = 0; Idx !=
EC.getKnownMinValue(); ++Idx) {
8294 if (Idx == ExtractIdx)
8302 "Generate scalable vector for non-splat is unimplemented");
8307 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8308 unsigned OperandIdx) {
8311 if (OperandIdx != 1)
8313 switch (
Use->getOpcode()) {
8316 case Instruction::SDiv:
8317 case Instruction::UDiv:
8318 case Instruction::SRem:
8319 case Instruction::URem:
8321 case Instruction::FDiv:
8322 case Instruction::FRem:
8323 return !
Use->hasNoNaNs();
8329 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8330 const TargetTransformInfo &
TTI, Instruction *Transition,
8331 unsigned CombineCost)
8332 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8333 StoreExtractCombineCost(CombineCost) {
8334 assert(Transition &&
"Do not know how to promote null");
8338 bool canPromote(
const Instruction *ToBePromoted)
const {
8345 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8348 for (
const Use &U : ToBePromoted->
operands()) {
8349 const Value *Val =
U.get();
8350 if (Val == getEndOfTransition()) {
8354 if (canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()))
8377 void enqueueForPromotion(Instruction *ToBePromoted) {
8378 InstsToBePromoted.push_back(ToBePromoted);
8382 void recordCombineInstruction(Instruction *ToBeCombined) {
8384 CombineInst = ToBeCombined;
8394 if (InstsToBePromoted.empty() || !CombineInst)
8402 for (
auto &ToBePromoted : InstsToBePromoted)
8403 promoteImpl(ToBePromoted);
8404 InstsToBePromoted.clear();
8411void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8421 "The type of the result of the transition does not match "
8426 Type *TransitionTy = getTransitionType();
8431 for (Use &U : ToBePromoted->
operands()) {
8433 Value *NewVal =
nullptr;
8434 if (Val == Transition)
8435 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8442 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8446 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8449 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8455bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8456 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8471 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8472 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost);
8479 if (ToBePromoted->
getParent() != Parent) {
8480 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8482 <<
") than the transition (" << Parent->
getName()
8487 if (VPH.canCombine(ToBePromoted)) {
8489 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8490 VPH.recordCombineInstruction(ToBePromoted);
8492 NumStoreExtractExposed +=
Changed;
8497 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8500 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8502 VPH.enqueueForPromotion(ToBePromoted);
8503 Inst = ToBePromoted;
8543 Type *StoreType =
SI.getValueOperand()->getType();
8552 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8553 DL.getTypeSizeInBits(StoreType) == 0)
8556 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8558 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8562 if (
SI.isVolatile())
8574 if (!
match(
SI.getValueOperand(),
8581 if (!
LValue->getType()->isIntegerTy() ||
8582 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8584 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8600 Builder.SetInsertPoint(&
SI);
8604 if (LBC && LBC->getParent() !=
SI.getParent())
8605 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8606 if (HBC && HBC->getParent() !=
SI.getParent())
8607 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8609 bool IsLE =
SI.getDataLayout().isLittleEndian();
8610 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8611 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8612 Value *Addr =
SI.getPointerOperand();
8613 Align Alignment =
SI.getAlign();
8614 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8615 if (IsOffsetStore) {
8616 Addr = Builder.CreateGEP(
8617 SplitStoreType, Addr,
8625 Builder.CreateAlignedStore(V, Addr, Alignment);
8628 CreateSplitStore(
LValue,
false);
8629 CreateSplitStore(HValue,
true);
8632 SI.eraseFromParent();
8640 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8722 if (GEPIOpI->getParent() != SrcBlock)
8727 if (auto *I = dyn_cast<Instruction>(Usr)) {
8728 if (I->getParent() != SrcBlock) {
8736 std::vector<GetElementPtrInst *> UGEPIs;
8739 for (User *Usr : GEPIOp->
users()) {
8758 if (UGEPI->getOperand(0) != GEPIOp)
8760 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8762 if (GEPIIdx->getType() !=
8770 UGEPIs.push_back(UGEPI);
8772 if (UGEPIs.size() == 0)
8775 for (GetElementPtrInst *UGEPI : UGEPIs) {
8777 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8784 for (GetElementPtrInst *UGEPI : UGEPIs) {
8785 UGEPI->setOperand(0, GEPI);
8787 Constant *NewUGEPIIdx = ConstantInt::get(
8788 GEPIIdx->getType(), UGEPIIdx->
getValue() - GEPIIdx->getValue());
8789 UGEPI->setOperand(1, NewUGEPIIdx);
8792 if (!GEPI->isInBounds()) {
8793 UGEPI->setIsInBounds(
false);
8800 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8802 "GEPIOp is used outside SrcBlock");
8826 Value *
X = Cmp->getOperand(0);
8827 if (!
X->hasUseList())
8832 for (
auto *U :
X->users()) {
8836 (UI->
getParent() != Branch->getParent() &&
8837 UI->
getParent() != Branch->getSuccessor(0) &&
8838 UI->
getParent() != Branch->getSuccessor(1)) ||
8839 (UI->
getParent() != Branch->getParent() &&
8840 !UI->
getParent()->getSinglePredecessor()))
8846 if (UI->
getParent() != Branch->getParent())
8850 ConstantInt::get(UI->
getType(), 0));
8852 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8856 if (Cmp->isEquality() &&
8861 if (UI->
getParent() != Branch->getParent())
8864 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8865 ConstantInt::get(UI->
getType(), 0));
8867 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8875bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8876 bool AnyChange =
false;
8877 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8881 if (InsertedInsts.count(
I))
8890 LargeOffsetGEPMap.erase(
P);
8892 P->eraseFromParent();
8915 I, LI->getLoopFor(
I->getParent()), *
TTI))
8923 TargetLowering::TypeExpandInteger) {
8927 I, LI->getLoopFor(
I->getParent()), *
TTI))
8930 bool MadeChange = optimizeExt(
I);
8931 return MadeChange | optimizeExtUses(
I);
8938 if (optimizeCmp(Cmp, ModifiedDT))
8942 if (optimizeURem(
I))
8946 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8947 bool Modified = optimizeLoadExt(LI);
8956 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8957 unsigned AS =
SI->getPointerAddressSpace();
8958 return optimizeMemoryInst(
I,
SI->getOperand(1),
8959 SI->getOperand(0)->getType(), AS);
8963 unsigned AS = RMW->getPointerAddressSpace();
8964 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
8968 unsigned AS = CmpX->getPointerAddressSpace();
8969 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
8970 CmpX->getCompareOperand()->getType(), AS);
8980 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
8981 BinOp->
getOpcode() == Instruction::LShr)) {
8989 if (GEPI->hasAllZeroIndices()) {
8991 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
8992 GEPI->getName(), GEPI->getIterator());
8993 NC->setDebugLoc(GEPI->getDebugLoc());
8996 GEPI, TLInfo,
nullptr,
8997 [&](
Value *V) { removeAllAssertingVHReferences(V); });
8999 optimizeInst(
NC, ModifiedDT);
9022 if (Const0 || Const1) {
9023 if (!Const0 || !Const1) {
9024 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
9029 FI->eraseFromParent();
9036 if (tryToSinkFreeOperands(
I))
9039 switch (
I->getOpcode()) {
9040 case Instruction::Shl:
9041 case Instruction::LShr:
9042 case Instruction::AShr:
9044 case Instruction::Call:
9046 case Instruction::Select:
9048 case Instruction::ShuffleVector:
9050 case Instruction::Switch:
9052 case Instruction::ExtractElement:
9054 case Instruction::Br:
9063bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
9064 if (!
I.getType()->isIntegerTy() ||
9069 SmallVector<Instruction *, 4> Insts;
9075 &
I, TLInfo,
nullptr,
9076 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9083bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
9085 bool MadeChange =
false;
9088 CurInstIterator = BB.
begin();
9089 ModifiedDT = ModifyDT::NotModifyDT;
9090 while (CurInstIterator != BB.
end()) {
9091 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
9092 if (ModifiedDT != ModifyDT::NotModifyDT) {
9105 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
9107 bool MadeBitReverse =
true;
9108 while (MadeBitReverse) {
9109 MadeBitReverse =
false;
9111 if (makeBitReverse(
I)) {
9112 MadeBitReverse = MadeChange =
true;
9117 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
9122bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
9123 bool AnyChange =
false;
9124 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
9125 AnyChange |= fixupDbgVariableRecord(DVR);
9131bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
9132 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
9133 DVR.
Type != DbgVariableRecord::LocationType::Assign)
9137 bool AnyChange =
false;
9138 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
9140 for (
Value *Location : LocationOps) {
9141 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9170bool CodeGenPrepare::placeDbgValues(Function &
F) {
9171 bool MadeChange =
false;
9172 DominatorTree DT(
F);
9174 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9175 SmallVector<Instruction *, 4> VIs;
9176 for (
Value *V : DbgItem->location_ops())
9184 for (Instruction *VI : VIs) {
9185 if (
VI->isTerminator())
9190 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9201 if (VIs.size() > 1) {
9204 <<
"Unable to find valid location for Debug Value, undefing:\n"
9206 DbgItem->setKillLocation();
9211 << *DbgItem <<
' ' << *VI);
9218 for (BasicBlock &BB :
F) {
9224 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9226 DbgProcessor(&DVR, &Insn);
9237bool CodeGenPrepare::placePseudoProbes(Function &
F) {
9238 bool MadeChange =
false;
9241 auto FirstInst =
Block.getFirstInsertionPt();
9242 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9246 while (
I !=
Block.end()) {
9248 II->moveBefore(FirstInst);
9258 uint64_t NewMax = (NewTrue > NewFalse) ? NewTrue : NewFalse;
9259 uint32_t Scale = (NewMax / std::numeric_limits<uint32_t>::max()) + 1;
9260 NewTrue = NewTrue / Scale;
9261 NewFalse = NewFalse / Scale;
9286bool CodeGenPrepare::splitBranchCondition(Function &
F, ModifyDT &ModifiedDT) {
9290 bool MadeChange =
false;
9291 for (
auto &BB :
F) {
9304 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9312 Value *Cond1, *Cond2;
9315 Opc = Instruction::And;
9318 Opc = Instruction::Or;
9328 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9342 Br1->setCondition(Cond1);
9347 if (
Opc == Instruction::And)
9348 Br1->setSuccessor(0, TmpBB);
9350 Br1->setSuccessor(1, TmpBB);
9355 I->removeFromParent();
9356 I->insertBefore(Br2->getIterator());
9368 if (
Opc == Instruction::Or)
9375 for (PHINode &PN : FBB->
phis()) {
9382 if (
Opc == Instruction::Or) {
9402 uint64_t TrueWeight, FalseWeight;
9404 uint64_t NewTrueWeight = TrueWeight;
9405 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9407 Br1->setMetadata(LLVMContext::MD_prof,
9408 MDBuilder(Br1->getContext())
9409 .createBranchWeights(TrueWeight, FalseWeight,
9412 NewTrueWeight = TrueWeight;
9413 NewFalseWeight = 2 * FalseWeight;
9415 Br2->setMetadata(LLVMContext::MD_prof,
9416 MDBuilder(Br2->getContext())
9417 .createBranchWeights(TrueWeight, FalseWeight));
9438 uint64_t TrueWeight, FalseWeight;
9440 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9441 uint64_t NewFalseWeight = FalseWeight;
9443 Br1->setMetadata(LLVMContext::MD_prof,
9444 MDBuilder(Br1->getContext())
9445 .createBranchWeights(TrueWeight, FalseWeight));
9447 NewTrueWeight = 2 * TrueWeight;
9448 NewFalseWeight = FalseWeight;
9450 Br2->setMetadata(LLVMContext::MD_prof,
9451 MDBuilder(Br2->getContext())
9452 .createBranchWeights(TrueWeight, FalseWeight));
9456 ModifiedDT = ModifyDT::ModifyBBDT;
static unsigned getIntrinsicID(const SDNode *N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
This file contains the simple types necessary to represent the attributes associated with functions a...
static const Function * getParent(const Value *V)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool sinkAndCmp0Expression(Instruction *AndI, const TargetLowering &TLI, SetOfInstrs &InsertedInsts)
Duplicate and sink the given 'and' instruction into user blocks where it is used in a compare to allo...
static bool SinkShiftAndTruncate(BinaryOperator *ShiftI, Instruction *User, ConstantInt *CI, DenseMap< BasicBlock *, BinaryOperator * > &InsertedShifts, const TargetLowering &TLI, const DataLayout &DL)
Sink both shift and truncate instruction to the use of truncate's BB.
static bool getGEPSmallConstantIntOffsetV(GetElementPtrInst *GEP, SmallVectorImpl< Value * > &OffsetV)
static bool sinkSelectOperand(const TargetTransformInfo *TTI, Value *V)
Check if V (an operand of a select instruction) is an expensive instruction that is only used once.
static bool isExtractBitsCandidateUse(Instruction *User)
Check if the candidates could be combined with a shift instruction, which includes:
static cl::opt< unsigned > MaxAddressUsersToScan("cgp-max-address-users-to-scan", cl::init(100), cl::Hidden, cl::desc("Max number of address users to look at"))
static cl::opt< bool > OptimizePhiTypes("cgp-optimize-phi-types", cl::Hidden, cl::init(true), cl::desc("Enable converting phi types in CodeGenPrepare"))
static cl::opt< bool > DisableStoreExtract("disable-cgp-store-extract", cl::Hidden, cl::init(false), cl::desc("Disable store(extract) optimizations in CodeGenPrepare"))
static bool foldFCmpToFPClassTest(CmpInst *Cmp, const TargetLowering &TLI, const DataLayout &DL)
static void scaleWeights(uint64_t &NewTrue, uint64_t &NewFalse)
Scale down both weights to fit into uint32_t.
static cl::opt< bool > ProfileUnknownInSpecialSection("profile-unknown-in-special-section", cl::Hidden, cl::desc("In profiling mode like sampleFDO, if a function doesn't have " "profile, we cannot tell the function is cold for sure because " "it may be a function newly added without ever being sampled. " "With the flag enabled, compiler can put such profile unknown " "functions into a special section, so runtime system can choose " "to handle it in a different way than .text section, to save " "RAM for example. "))
static bool OptimizeExtractBits(BinaryOperator *ShiftI, ConstantInt *CI, const TargetLowering &TLI, const DataLayout &DL)
Sink the shift right instruction into user blocks if the uses could potentially be combined with this...
static cl::opt< bool > DisableExtLdPromotion("disable-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), cl::desc("Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in " "CodeGenPrepare"))
static cl::opt< bool > DisablePreheaderProtect("disable-preheader-prot", cl::Hidden, cl::init(false), cl::desc("Disable protection against removing loop preheaders"))
static cl::opt< bool > AddrSinkCombineBaseOffs("addr-sink-combine-base-offs", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseOffs field in Address sinking."))
static bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI, const DataLayout &DL)
If the specified cast instruction is a noop copy (e.g.
static bool splitMergedValStore(StoreInst &SI, const DataLayout &DL, const TargetLowering &TLI)
For the instruction sequence of store below, F and I values are bundled together as an i64 value befo...
static bool SinkCast(CastInst *CI)
Sink the specified cast instruction into its user blocks.
static bool swapICmpOperandsToExposeCSEOpportunities(CmpInst *Cmp)
Many architectures use the same instruction for both subtract and cmp.
static cl::opt< bool > AddrSinkCombineBaseReg("addr-sink-combine-base-reg", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseReg field in Address sinking."))
static bool FindAllMemoryUses(Instruction *I, SmallVectorImpl< std::pair< Use *, Type * > > &MemoryUses, SmallPtrSetImpl< Instruction * > &ConsideredInsts, const TargetLowering &TLI, const TargetRegisterInfo &TRI, bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI, unsigned &SeenInsts)
Recursively walk all the uses of I until we find a memory use.
static cl::opt< bool > StressStoreExtract("stress-cgp-store-extract", cl::Hidden, cl::init(false), cl::desc("Stress test store(extract) optimizations in CodeGenPrepare"))
static bool isFormingBranchFromSelectProfitable(const TargetTransformInfo *TTI, const TargetLowering *TLI, SelectInst *SI)
Returns true if a SelectInst should be turned into an explicit branch.
static std::optional< std::pair< Instruction *, Constant * > > getIVIncrement(const PHINode *PN, const LoopInfo *LI)
If given PN is an inductive variable with value IVInc coming from the backedge, and on each iteration...
static cl::opt< bool > AddrSinkCombineBaseGV("addr-sink-combine-base-gv", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseGV field in Address sinking."))
static cl::opt< bool > AddrSinkUsingGEPs("addr-sink-using-gep", cl::Hidden, cl::init(true), cl::desc("Address sinking in CGP using GEPs."))
static Value * getTrueOrFalseValue(SelectInst *SI, bool isTrue, const SmallPtrSet< const Instruction *, 2 > &Selects)
If isTrue is true, return the true value of SI, otherwise return false value of SI.
static cl::opt< bool > DisableBranchOpts("disable-cgp-branch-opts", cl::Hidden, cl::init(false), cl::desc("Disable branch optimizations in CodeGenPrepare"))
static cl::opt< bool > EnableTypePromotionMerge("cgp-type-promotion-merge", cl::Hidden, cl::desc("Enable merging of redundant sexts when one is dominating" " the other."), cl::init(true))
static cl::opt< bool > ProfileGuidedSectionPrefix("profile-guided-section-prefix", cl::Hidden, cl::init(true), cl::desc("Use profile info to add section prefix for hot/cold functions"))
static cl::opt< unsigned > HugeFuncThresholdInCGPP("cgpp-huge-func", cl::init(10000), cl::Hidden, cl::desc("Least BB number of huge function."))
static cl::opt< bool > AddrSinkNewSelects("addr-sink-new-select", cl::Hidden, cl::init(true), cl::desc("Allow creation of selects in Address sinking."))
static bool foldURemOfLoopIncrement(Instruction *Rem, const DataLayout *DL, const LoopInfo *LI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
static bool optimizeBranch(BranchInst *Branch, const TargetLowering &TLI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
static bool tryUnmergingGEPsAcrossIndirectBr(GetElementPtrInst *GEPI, const TargetTransformInfo *TTI)
static bool IsOperandAMemoryOperand(CallInst *CI, InlineAsm *IA, Value *OpVal, const TargetLowering &TLI, const TargetRegisterInfo &TRI)
Check to see if all uses of OpVal by the specified inline asm call are due to memory operands.
static bool isIntrinsicOrLFToBeTailCalled(const TargetLibraryInfo *TLInfo, const CallInst *CI)
static void replaceAllUsesWith(Value *Old, Value *New, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
Replace all old uses with new ones, and push the updated BBs into FreshBBs.
static cl::opt< bool > ForceSplitStore("force-split-store", cl::Hidden, cl::init(false), cl::desc("Force store splitting no matter what the target query says."))
static bool matchOverflowPattern(Instruction *&I, ExtractValueInst *&MulExtract, ExtractValueInst *&OverflowExtract)
static void computeBaseDerivedRelocateMap(const SmallVectorImpl< GCRelocateInst * > &AllRelocateCalls, MapVector< GCRelocateInst *, SmallVector< GCRelocateInst *, 0 > > &RelocateInstMap)
static bool simplifyRelocatesOffABase(GCRelocateInst *RelocatedBase, const SmallVectorImpl< GCRelocateInst * > &Targets)
static cl::opt< bool > AddrSinkCombineScaledReg("addr-sink-combine-scaled-reg", cl::Hidden, cl::init(true), cl::desc("Allow combining of ScaledReg field in Address sinking."))
static bool foldICmpWithDominatingICmp(CmpInst *Cmp, const TargetLowering &TLI)
For pattern like:
static bool MightBeFoldableInst(Instruction *I)
This is a little filter, which returns true if an addressing computation involving I might be folded ...
static bool matchIncrement(const Instruction *IVInc, Instruction *&LHS, Constant *&Step)
static cl::opt< bool > EnableGEPOffsetSplit("cgp-split-large-offset-gep", cl::Hidden, cl::init(true), cl::desc("Enable splitting large offset of GEP."))
static cl::opt< bool > DisableComplexAddrModes("disable-complex-addr-modes", cl::Hidden, cl::init(false), cl::desc("Disables combining addressing modes with different parts " "in optimizeMemoryInst."))
static cl::opt< bool > EnableICMP_EQToICMP_ST("cgp-icmp-eq2icmp-st", cl::Hidden, cl::init(false), cl::desc("Enable ICMP_EQ to ICMP_S(L|G)T conversion."))
static cl::opt< bool > VerifyBFIUpdates("cgp-verify-bfi-updates", cl::Hidden, cl::init(false), cl::desc("Enable BFI update verification for " "CodeGenPrepare."))
static cl::opt< bool > BBSectionsGuidedSectionPrefix("bbsections-guided-section-prefix", cl::Hidden, cl::init(true), cl::desc("Use the basic-block-sections profile to determine the text " "section prefix for hot functions. Functions with " "basic-block-sections profile will be placed in `.text.hot` " "regardless of their FDO profile info. Other functions won't be " "impacted, i.e., their prefixes will be decided by FDO/sampleFDO " "profiles."))
static bool isRemOfLoopIncrementWithLoopInvariant(Instruction *Rem, const LoopInfo *LI, Value *&RemAmtOut, Value *&AddInstOut, Value *&AddOffsetOut, PHINode *&LoopIncrPNOut)
static bool isIVIncrement(const Value *V, const LoopInfo *LI)
static cl::opt< bool > DisableGCOpts("disable-cgp-gc-opts", cl::Hidden, cl::init(false), cl::desc("Disable GC optimizations in CodeGenPrepare"))
static bool GEPSequentialConstIndexed(GetElementPtrInst *GEP)
static void DbgInserterHelper(DbgVariableRecord *DVR, BasicBlock::iterator VI)
static bool isPromotedInstructionLegal(const TargetLowering &TLI, const DataLayout &DL, Value *Val)
Check whether or not Val is a legal instruction for TLI.
static cl::opt< uint64_t > FreqRatioToSkipMerge("cgp-freq-ratio-to-skip-merge", cl::Hidden, cl::init(2), cl::desc("Skip merging empty blocks if (frequency of empty block) / " "(frequency of destination block) is greater than this ratio"))
static BasicBlock::iterator findInsertPos(Value *Addr, Instruction *MemoryInst, Value *SunkAddr)
static bool IsNonLocalValue(Value *V, BasicBlock *BB)
Return true if the specified values are defined in a different basic block than BB.
static cl::opt< bool > EnableAndCmpSinking("enable-andcmp-sinking", cl::Hidden, cl::init(true), cl::desc("Enable sinking and/cmp into branches."))
static bool sinkCmpExpression(CmpInst *Cmp, const TargetLowering &TLI, const DataLayout &DL)
Sink the given CmpInst into user blocks to reduce the number of virtual registers that must be create...
static bool hasSameExtUse(Value *Val, const TargetLowering &TLI)
Check if all the uses of Val are equivalent (or free) zero or sign extensions.
static bool despeculateCountZeros(IntrinsicInst *CountZeros, LoopInfo &LI, const TargetLowering *TLI, const DataLayout *DL, ModifyDT &ModifiedDT, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
If counting leading or trailing zeros is an expensive operation and a zero input is defined,...
static cl::opt< bool > StressExtLdPromotion("stress-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), cl::desc("Stress test ext(promotable(ld)) -> promoted(ext(ld)) " "optimization in CodeGenPrepare"))
static bool matchUAddWithOverflowConstantEdgeCases(CmpInst *Cmp, BinaryOperator *&Add)
Match special-case patterns that check for unsigned add overflow.
static cl::opt< bool > DisableSelectToBranch("disable-cgp-select2branch", cl::Hidden, cl::init(false), cl::desc("Disable select to branch conversion."))
static cl::opt< bool > DisableDeletePHIs("disable-cgp-delete-phis", cl::Hidden, cl::init(false), cl::desc("Disable elimination of dead PHI nodes."))
static cl::opt< bool > AddrSinkNewPhis("addr-sink-new-phis", cl::Hidden, cl::init(false), cl::desc("Allow creation of Phis in Address sinking."))
Defines an IR pass for CodeGen Prepare.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
static Value * getCondition(Instruction *I)
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU)
Register const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the PointerIntPair class.
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, const MachineInstr &B)
Remove Loads Into Fake Uses
static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static SymbolRef::Type getType(const Symbol *Sym)
static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, unsigned CombineOpc=0)
This file describes how to lower LLVM code to machine code.
static cl::opt< bool > DisableSelectOptimize("disable-select-optimize", cl::init(true), cl::Hidden, cl::desc("Disable the select-optimization pass from running"))
Disable the select optimization pass.
Target-Independent Code Generator Pass Configuration Options pass.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
static Constant * getConstantVector(MVT VT, ArrayRef< APInt > Bits, const APInt &Undefs, LLVMContext &C)
Class for arbitrary precision integers.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
unsigned getSignificantBits() const
Get the minimum bit size for this signed APInt.
unsigned logBase2() const
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
int64_t getSExtValue() const
Get sign extended value.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
void setAlignment(Align Align)
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addRequired()
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
An instruction that atomically checks whether a specified value is in a memory location,...
static unsigned getPointerOperandIndex()
an instruction that atomically reads a memory location, combines it with another value,...
static unsigned getPointerOperandIndex()
Analysis pass providing the BasicBlockSectionsProfileReader.
bool isFunctionHot(StringRef FuncName) const
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI void insertDbgRecordBefore(DbgRecord *DR, InstListType::iterator Here)
Insert a DbgRecord into a block at the position given by Here.
InstListType::const_iterator const_iterator
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
LLVM_ABI InstListType::const_iterator getFirstNonPHIOrDbg(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic,...
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
LLVM_ABI SymbolTableList< BasicBlock >::iterator eraseFromParent()
Unlink 'this' from the containing function and delete it.
LLVM_ABI void insertDbgRecordAfter(DbgRecord *DR, Instruction *I)
Insert a DbgRecord into a block at the position given by I.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI void setBlockFreq(const BasicBlock *BB, BlockFrequency Freq)
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
Conditional or Unconditional Branch instruction.
LLVM_ABI void swapSuccessors()
Swap the successors of this branch instruction.
bool isConditional() const
BasicBlock * getSuccessor(unsigned i) const
bool isUnconditional() const
Analysis providing branch probability information.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
Predicate getPredicate() const
Return the predicate for this instruction.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
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 ...
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=true)
Return a ConstantInt with the specified value for the specified type.
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI void removeFromParent()
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LocationType Type
Classification of the debug-info record that this DbgVariableRecord represents.
LLVM_ABI void replaceVariableLocationOp(Value *OldValue, Value *NewValue, bool AllowEmpty=false)
LLVM_ABI iterator_range< location_op_iterator > location_ops() const
Get the locations corresponding to the variable referenced by the debug info intrinsic.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This instruction compares its operands according to the predicate given to the constructor.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionPass class - This class is used to implement most global optimizations.
const BasicBlock & getEntryBlock() const
LLVM_ABI const Value * getStatepoint() const
The statepoint with which this gc.relocate is associated.
Represents calls to the gc.relocate intrinsic.
unsigned getBasePtrIndex() const
The index into the associate statepoint's argument list which contains the base pointer of the pointe...
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static LLVM_ABI Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)
Returns the result type of a getelementptr with the given source element type and indexes.
LLVM_ABI bool canIncreaseAlignment() const
Returns true if the alignment of the value can be unilaterally increased.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
Type * getValueType() const
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This instruction compares its operands according to the predicate given to the constructor.
bool isEquality() const
Return true if this predicate is either EQ or NE.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
LLVM_ABI bool isDebugOrPseudoInst() const LLVM_READONLY
Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void moveAfter(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
LLVM_ABI std::optional< simple_ilist< DbgRecord >::iterator > getDbgReinsertionPosition()
Return an iterator to the position of the "Next" DbgRecord after this instruction,...
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
LLVM_ABI void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
An instruction for reading from memory.
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
Analysis pass that exposes the LoopInfo for a function.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
The legacy pass manager's analysis pass to compute loop information.
Represents a single loop in the control flow graph.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static MVT getIntegerVT(unsigned BitWidth)
LLVM_ABI void replacePhiUsesWith(MachineBasicBlock *Old, MachineBasicBlock *New)
Update all phi nodes in this basic block to refer to basic block New instead of basic block Old.
This class implements a map that also provides access to all stored values in a deterministic order.
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
iterator find(const KeyT &Key)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
op_range incoming_values()
Value * getIncomingValueForBlock(const BasicBlock *BB) const
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
PointerIntPair - This class implements a pair of a pointer and small integer.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
bool isFunctionColdInCallGraph(const FuncT *F, BFIT &BFI) const
Returns true if F contains only cold code.
LLVM_ABI bool isFunctionHotnessUnknown(const Function &F) const
Returns true if the hotness of F is unknown.
bool isFunctionHotInCallGraph(const FuncT *F, BFIT &BFI) const
Returns true if F contains hot code.
LLVM_ABI bool hasPartialSampleProfile() const
Returns true if module M has partial-profile sample profile.
LLVM_ABI bool hasHugeWorkingSetSize() const
Returns true if the working set size of the code is considered huge.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
void clear()
Completely clear the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
VectorType * getType() const
Overload to return most specific vector type.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator erase(const_iterator CI)
typename SuperClass::iterator iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
static unsigned getPointerOperandIndex()
TypeSize getElementOffset(unsigned Idx) const
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
int InstructionOpcodeToISD(unsigned Opcode) const
Get the ISD node that corresponds to the Instruction class opcode.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool isSelectSupported(SelectSupportKind) const
virtual bool isEqualityCmpFoldedWithSignedCmp() const
Return true if instruction generated for equality comparison is folded with instruction generated for...
virtual bool shouldFormOverflowOp(unsigned Opcode, EVT VT, bool MathUsed) const
Try to convert math with an overflow comparison into the corresponding DAG node operation.
virtual bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const
Return if the target supports combining a chain like:
virtual bool shouldOptimizeMulOverflowWithZeroHighBits(LLVMContext &Context, EVT VT) const
bool isExtLoad(const LoadInst *Load, const Instruction *Ext, const DataLayout &DL) const
Return true if Load and Ext can form an ExtLoad.
virtual bool isSExtCheaperThanZExt(EVT FromTy, EVT ToTy) const
Return true if sign-extension from FromTy to ToTy is cheaper than zero-extension.
const TargetMachine & getTargetMachine() const
virtual bool isCtpopFast(EVT VT) const
Return true if ctpop instruction is fast.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
bool enableExtLdPromotion() const
Return true if the target wants to use the optimization that turns ext(promotableInst1(....
virtual bool isCheapToSpeculateCttz(Type *Ty) const
Return true if it is cheap to speculate a call to intrinsic cttz.
bool isJumpExpensive() const
Return true if Flow Control is an expensive operation that should be avoided.
bool hasExtractBitsInsn() const
Return true if the target has BitExtract instructions.
virtual bool allowsMisalignedMemoryAccesses(EVT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *=nullptr) const
Determine if the target supports unaligned memory accesses.
bool isSlowDivBypassed() const
Returns true if target has indicated at least one type should be bypassed.
virtual bool isTruncateFree(Type *FromTy, Type *ToTy) const
Return true if it's free to truncate a value of type FromTy to type ToTy.
virtual bool hasMultipleConditionRegisters(EVT VT) const
Does the target have multiple (allocatable) condition registers that can be used to store the results...
virtual EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
virtual MVT getPreferredSwitchConditionType(LLVMContext &Context, EVT ConditionVT) const
Returns preferred type for switch condition.
bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const
Return true if the specified condition code is legal for a comparison of the specified types on this ...
virtual bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx, unsigned &Cost) const
Return true if the target can combine store(extractelement VectorTy,Idx).
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual bool isFreeAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const
Returns true if a cast from SrcAS to DestAS is "cheap", such that e.g.
virtual bool shouldConsiderGEPOffsetSplit() const
bool isExtFree(const Instruction *I) const
Return true if the extension represented by I is free.
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
bool isPredictableSelectExpensive() const
Return true if selects are only cheaper than branches if the branch is unlikely to be predicted right...
virtual bool isMultiStoresCheaperThanBitsMerge(EVT LTy, EVT HTy) const
Return true if it is cheaper to split the store of a merged int val from a pair of smaller values int...
virtual bool getAddrModeArguments(const IntrinsicInst *, SmallVectorImpl< Value * > &, Type *&) const
CodeGenPrepare sinks address calculations into the same BB as Load/Store instructions reading the add...
bool isLoadExtLegal(unsigned ExtType, EVT ValVT, EVT MemVT) const
Return true if the specified load with extension is legal on this target.
const DenseMap< unsigned int, unsigned int > & getBypassSlowDivWidths() const
Returns map of slow types for division or remainder with corresponding fast types.
virtual bool isCheapToSpeculateCtlz(Type *Ty) const
Return true if it is cheap to speculate a call to intrinsic ctlz.
virtual bool useSoftFloat() const
virtual int64_t getPreferredLargeGEPBaseOffset(int64_t MinOffset, int64_t MaxOffset) const
Return the prefered common base offset.
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
virtual bool shouldAlignPointerArgs(CallInst *, unsigned &, Align &) const
Return true if the pointer arguments to CI should be aligned by aligning the object whose address is ...
virtual Type * shouldConvertSplatType(ShuffleVectorInst *SVI) const
Given a shuffle vector SVI representing a vector splat, return a new scalar type of size equal to SVI...
virtual bool addressingModeSupportsTLS(const GlobalValue &) const
Returns true if the targets addressing mode can target thread local storage (TLS).
virtual bool shouldConvertPhiType(Type *From, Type *To) const
Given a set in interconnected phis of type 'From' that are loaded/stored or bitcast to type 'To',...
virtual bool isFAbsFree(EVT VT) const
Return true if an fabs operation is free to the point where it is never worthwhile to replace it with...
virtual bool preferZeroCompareBranch() const
Return true if the heuristic to prefer icmp eq zero should be used in code gen prepare.
virtual bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AddrSpace, Instruction *I=nullptr) const
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
virtual bool optimizeExtendOrTruncateConversion(Instruction *I, Loop *L, const TargetTransformInfo &TTI) const
Try to optimize extending or truncating conversion instructions (like zext, trunc,...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
std::vector< AsmOperandInfo > AsmOperandInfoVector
virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL, const TargetRegisterInfo *TRI, const CallBase &Call) const
Split up the constraint string from the inline assembly value into the specific constraints and their...
virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op, SelectionDAG *DAG=nullptr) const
Determines the constraint code and constraint type to use for the specific AsmOperandInfo,...
virtual bool mayBeEmittedAsTailCall(const CallInst *) const
Return true if the target may be able emit the call instruction as a tail call.
virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const
Returns true if a cast between SrcAS and DestAS is a noop.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
unsigned EnableFastISel
EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...
Target-Independent Code Generator Pass Configuration Options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
virtual bool addrSinkUsingGEPs() const
Sink addresses into blocks using GEP instructions rather than pointer casts and arithmetic.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
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.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
void mutateType(Type *Ty)
Mutate the type of this Value to be of the specified type.
user_iterator_impl< User > user_iterator
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
bool pointsToAliveValue() const
int getNumOccurrences() const
constexpr ScalarTy getFixedValue() const
constexpr bool isNonZero() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ C
The default llvm calling convention, compatible with C.
unsigned getAddrMode(MCInstrInfo const &MCII, MCInst const &MCI)
@ BasicBlock
Various leaf nodes.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap, true > m_c_NUWAdd(const LHS &L, const RHS &R)
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
UAddWithOverflow_match< LHS_t, RHS_t, Sum_t > m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S)
Match an icmp instruction checking for unsigned overflow on addition.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
auto m_Undef()
Match an arbitrary undef constant.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale)
Compare two scaled numbers.
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ Assume
Do not drop type tests (default).
@ User
could "use" a pointer
NodeAddr< PhiNode * > Phi
NodeAddr< UseNode * > Use
SmallVector< Node, 4 > NodeList
friend class Instruction
Iterator for Instructions in a `BasicBlock.
LLVM_ABI iterator begin() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
FunctionAddr VTableAddr Value
std::enable_if_t< std::is_signed_v< T >, T > MulOverflow(T X, T Y, T &Result)
Multiply two signed integers, computing the two's complement truncated result, returning true if an o...
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool RemoveRedundantDbgInstrs(BasicBlock *BB)
Try to remove redundant dbg.value instructions from given basic block.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
LLVM_ABI bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions=false, const TargetLibraryInfo *TLI=nullptr, DomTreeUpdater *DTU=nullptr)
If a terminator instruction is predicated on a constant value, convert it into an unconditional branc...
LLVM_ABI void findDbgValues(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)
Finds the dbg.values describing a value.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
APInt operator*(APInt a, uint64_t RHS)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
auto successors(const MachineBasicBlock *BB)
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI ReturnInst * FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, BasicBlock *Pred, DomTreeUpdater *DTU=nullptr)
This method duplicates the specified return instruction into a predecessor which ends in an unconditi...
bool operator!=(uint64_t V1, const APInt &V2)
constexpr from_range_t from_range
LLVM_ABI Instruction * SplitBlockAndInsertIfElse(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ElseBlock=nullptr)
Similar to SplitBlockAndInsertIfThen, but the inserted block is on the false path of the branch.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
auto cast_or_null(const Y &Val)
LLVM_ABI void DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, bool KeepOneInputPHIs=false)
Delete the specified block, which must have no predecessors.
LLVM_ABI void initializeCodeGenPrepareLegacyPassPass(PassRegistry &)
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
auto unique(Range &&R, Predicate P)
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
LLVM_ABI bool hasBranchWeightOrigin(const Instruction &I)
Check if Branch Weight Metadata has an "expected" field from an llvm.expect* intrinsic.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
LLVM_ABI bool SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr)
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
auto dyn_cast_or_null(const Y &Val)
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
LLVM_ABI bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Examine each PHI in the given block and delete it if it is dead.
LLVM_ABI bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, SmallSetVector< Instruction *, 8 > *UnsimplifiedUsers=nullptr)
Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively.
auto reverse(ContainerTy &&C)
LLVM_ABI bool recognizeBSwapOrBitReverseIdiom(Instruction *I, bool MatchBSwaps, bool MatchBitReversals, SmallVectorImpl< Instruction * > &InsertedInsts)
Try to match a bswap or bitreverse idiom.
void sort(IteratorTy Start, IteratorTy End)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI void SplitBlockAndInsertIfThenElse(Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
generic_gep_type_iterator<> gep_type_iterator
LLVM_ABI FunctionPass * createCodeGenPrepareLegacyPass()
createCodeGenPrepareLegacyPass - Transform the code to expose more pattern matching during instructio...
ISD::CondCode getFCmpCondCode(FCmpInst::Predicate Pred)
getFCmpCondCode - Return the ISD condition code corresponding to the given LLVM IR floating-point con...
LLVM_ABI bool VerifyLoopInfo
Enable verification of loop info.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
bool attributesPermitTailCall(const Function *F, const Instruction *I, const ReturnInst *Ret, const TargetLoweringBase &TLI, bool *AllowDifferingSizes=nullptr)
Test if given that the input instruction is in the tail call position, if there is an attribute misma...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false, DominatorTree *DT=nullptr)
Attempts to merge a block into its predecessor, if possible.
@ Or
Bitwise or logical OR of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
FunctionAddr VTableAddr Next
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool bypassSlowDivision(BasicBlock *BB, const DenseMap< unsigned int, unsigned int > &BypassWidth)
This optimization identifies DIV instructions in a BB that can be profitably bypassed and carried out...
gep_type_iterator gep_type_begin(const User *GEP)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
auto predecessors(const MachineBasicBlock *BB)
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
bool pred_empty(const BasicBlock *BB)
std::enable_if_t< std::is_signed_v< T >, T > AddOverflow(T X, T Y, T &Result)
Add two signed integers, computing the two's complement truncated result, returning true if overflow ...
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
std::pair< Value *, FPClassTest > fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, Value *RHS, bool LookThroughSrc=true)
Returns a pair of values, which if passed to llvm.is.fpclass, returns the same result as an fcmp with...
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
LLVM_ABI Value * simplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a URem, fold the result or return null.
DenseMap< const Value *, Value * > ValueToValueMap
LLVM_ABI CGPassBuilderOption getCGPassBuilderOption()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool isRound() const
Return true if the size is a power-of-two number of bytes.
bool isInteger() const
Return true if this is an integer or a vector integer type.
This contains information for each constraint that we are lowering.