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;
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 optimizeInlineAsmInst(CallInst *CS);
436 bool optimizeExt(Instruction *&
I);
437 bool optimizeExtUses(Instruction *
I);
438 bool optimizeLoadExt(LoadInst *Load);
439 bool optimizeShiftInst(BinaryOperator *BO);
440 bool optimizeFunnelShift(IntrinsicInst *Fsh);
441 bool optimizeSelectInst(SelectInst *SI);
442 bool optimizeShuffleVectorInst(ShuffleVectorInst *SVI);
443 bool optimizeSwitchType(SwitchInst *SI);
444 bool optimizeSwitchPhiConstants(SwitchInst *SI);
445 bool optimizeSwitchInst(SwitchInst *SI);
446 bool optimizeExtractElementInst(Instruction *Inst);
447 bool dupRetToEnableTailCallOpts(BasicBlock *BB, ModifyDT &ModifiedDT);
448 bool fixupDbgVariableRecord(DbgVariableRecord &
I);
449 bool fixupDbgVariableRecordsOnInst(Instruction &
I);
450 bool placeDbgValues(Function &
F);
451 bool placePseudoProbes(Function &
F);
452 bool canFormExtLd(
const SmallVectorImpl<Instruction *> &MovedExts,
453 LoadInst *&LI, Instruction *&Inst,
bool HasPromoted);
454 bool tryToPromoteExts(TypePromotionTransaction &TPT,
455 const SmallVectorImpl<Instruction *> &Exts,
456 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
457 unsigned CreatedInstsCost = 0);
458 bool mergeSExts(Function &
F);
459 bool splitLargeGEPOffsets();
460 bool optimizePhiType(PHINode *Inst, SmallPtrSetImpl<PHINode *> &Visited,
461 SmallPtrSetImpl<Instruction *> &DeletedInstrs);
462 bool optimizePhiTypes(Function &
F);
463 bool performAddressTypePromotion(
464 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
465 bool HasPromoted, TypePromotionTransaction &TPT,
466 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts);
467 bool splitBranchCondition(Function &
F, ModifyDT &ModifiedDT);
468 bool simplifyOffsetableRelocate(GCStatepointInst &
I);
470 bool tryToSinkFreeOperands(Instruction *
I);
471 bool replaceMathCmpWithIntrinsic(BinaryOperator *BO,
Value *Arg0,
Value *Arg1,
473 bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT);
474 bool optimizeURem(Instruction *Rem);
475 bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
476 bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
477 bool unfoldPowerOf2Test(CmpInst *Cmp);
478 void verifyBFIUpdates(Function &
F);
479 bool _run(Function &
F);
486 CodeGenPrepareLegacyPass() : FunctionPass(ID) {
492 StringRef getPassName()
const override {
return "CodeGen Prepare"; }
494 void getAnalysisUsage(AnalysisUsage &AU)
const override {
507char CodeGenPrepareLegacyPass::ID = 0;
509bool CodeGenPrepareLegacyPass::runOnFunction(
Function &
F) {
512 auto TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
513 CodeGenPrepare CGP(TM);
514 CGP.DL = &
F.getDataLayout();
515 CGP.SubtargetInfo =
TM->getSubtargetImpl(
F);
516 CGP.TLI = CGP.SubtargetInfo->getTargetLowering();
517 CGP.TRI = CGP.SubtargetInfo->getRegisterInfo();
518 CGP.TLInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
519 CGP.TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
520 CGP.LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
521 CGP.BPI.reset(
new BranchProbabilityInfo(
F, *CGP.LI));
522 CGP.BFI.reset(
new BlockFrequencyInfo(
F, *CGP.BPI, *CGP.LI));
523 CGP.PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
525 getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
526 CGP.BBSectionsProfileReader = BBSPRWP ? &BBSPRWP->getBBSPR() :
nullptr;
532 "Optimize for code generation",
false,
false)
543 return new CodeGenPrepareLegacyPass();
548 CodeGenPrepare CGP(TM);
562 DL = &
F.getDataLayout();
563 SubtargetInfo = TM->getSubtargetImpl(
F);
573 BBSectionsProfileReader =
579 bool EverMadeChange =
false;
581 OptSize =
F.hasOptSize();
586 (void)
F.setSectionPrefix(
"hot");
591 if (
F.hasFnAttribute(Attribute::Hot) ||
593 (void)
F.setSectionPrefix(
"hot");
598 F.hasFnAttribute(Attribute::Cold))
599 (void)
F.setSectionPrefix(
"unlikely");
602 (void)
F.setSectionPrefix(
"unknown");
608 const DenseMap<unsigned int, unsigned int> &BypassWidths =
611 while (BB !=
nullptr) {
624 EverMadeChange |= eliminateAssumptions(
F);
628 EverMadeChange |= eliminateMostlyEmptyBlocks(
F);
630 ModifyDT ModifiedDT = ModifyDT::NotModifyDT;
632 EverMadeChange |= splitBranchCondition(
F, ModifiedDT);
646 LI->analyze(getDT(
F));
648 bool MadeChange =
true;
649 bool FuncIterated =
false;
654 if (FuncIterated && !FreshBBs.
contains(&BB))
657 ModifyDT ModifiedDTOnIteration = ModifyDT::NotModifyDT;
660 if (ModifiedDTOnIteration == ModifyDT::ModifyBBDT)
676 else if (FuncIterated)
681 if (ModifiedDTOnIteration != ModifyDT::NotModifyDT)
686 FuncIterated = IsHugeFunc;
689 MadeChange |= mergeSExts(
F);
690 if (!LargeOffsetGEPMap.
empty())
691 MadeChange |= splitLargeGEPOffsets();
692 MadeChange |= optimizePhiTypes(
F);
695 eliminateFallThrough(
F, DT.get());
699 LI->verify(getDT(
F));
703 for (Instruction *
I : RemovedInsts)
706 EverMadeChange |= MadeChange;
707 SeenChainsForSExt.
clear();
708 ValToSExtendedUses.clear();
709 RemovedInsts.clear();
710 LargeOffsetGEPMap.
clear();
711 LargeOffsetGEPID.
clear();
722 SmallSetVector<BasicBlock *, 8> WorkList;
723 for (BasicBlock &BB :
F) {
729 for (BasicBlock *Succ : Successors)
735 MadeChange |= !WorkList.
empty();
736 while (!WorkList.
empty()) {
742 for (BasicBlock *Succ : Successors)
749 if (EverMadeChange || MadeChange)
750 MadeChange |= eliminateFallThrough(
F);
752 EverMadeChange |= MadeChange;
757 for (BasicBlock &BB :
F)
758 for (Instruction &
I : BB)
761 for (
auto &
I : Statepoints)
762 EverMadeChange |= simplifyOffsetableRelocate(*
I);
767 EverMadeChange |= placeDbgValues(
F);
768 EverMadeChange |= placePseudoProbes(
F);
775 return EverMadeChange;
778bool CodeGenPrepare::eliminateAssumptions(Function &
F) {
779 bool MadeChange =
false;
780 for (BasicBlock &BB :
F) {
781 CurInstIterator = BB.begin();
782 while (CurInstIterator != BB.end()) {
787 Assume->eraseFromParent();
789 resetIteratorIfInvalidatedWhileCalling(&BB, [&]() {
800void CodeGenPrepare::removeAllAssertingVHReferences(
Value *V) {
801 LargeOffsetGEPMap.
erase(V);
802 NewGEPBases.
erase(V);
810 auto VecI = LargeOffsetGEPMap.
find(
GEP->getPointerOperand());
811 if (VecI == LargeOffsetGEPMap.
end())
814 auto &GEPVector = VecI->second;
817 if (GEPVector.empty())
818 LargeOffsetGEPMap.
erase(VecI);
823 DominatorTree NewDT(
F);
824 LoopInfo NewLI(NewDT);
825 BranchProbabilityInfo NewBPI(
F, NewLI, TLInfo);
826 BlockFrequencyInfo NewBFI(
F, NewBPI, NewLI);
827 NewBFI.verifyMatch(*BFI);
833bool CodeGenPrepare::eliminateFallThrough(Function &
F, DominatorTree *DT) {
841 SmallSet<WeakTrackingVH, 16> Preds;
842 for (
auto &
Block : Blocks) {
848 BasicBlock *SinglePred = BB->getSinglePredecessor();
851 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
859 if (Term && !
Term->isConditional()) {
871 FreshBBs.
insert(SinglePred);
879 for (
const auto &Pred : Preds)
887BasicBlock *CodeGenPrepare::findDestBlockOfMergeableEmptyBlock(BasicBlock *BB) {
896 if (BBI != BB->
begin()) {
907 if (!canMergeBlocks(BB, DestBB))
917bool CodeGenPrepare::eliminateMostlyEmptyBlocks(Function &
F) {
918 SmallPtrSet<BasicBlock *, 16> Preheaders;
920 while (!LoopList.empty()) {
921 Loop *
L = LoopList.pop_back_val();
923 if (BasicBlock *Preheader =
L->getLoopPreheader())
924 Preheaders.
insert(Preheader);
927 bool MadeChange =
false;
939 for (
auto &
Block : Blocks) {
943 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
945 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.
count(BB)))
948 eliminateMostlyEmptyBlock(BB);
954bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB,
1005 SmallPtrSet<BasicBlock *, 16> SameIncomingValueBBs;
1010 if (DestBBPred == BB)
1014 return DestPN.getIncomingValueForBlock(BB) ==
1015 DestPN.getIncomingValueForBlock(DestBBPred);
1017 SameIncomingValueBBs.
insert(DestBBPred);
1023 if (SameIncomingValueBBs.
count(Pred))
1026 BlockFrequency PredFreq =
BFI->getBlockFreq(Pred);
1027 BlockFrequency
BBFreq =
BFI->getBlockFreq(BB);
1029 for (
auto *SameValueBB : SameIncomingValueBBs)
1030 if (SameValueBB->getUniquePredecessor() == Pred &&
1031 DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
1032 BBFreq +=
BFI->getBlockFreq(SameValueBB);
1035 return !Limit || PredFreq <= *Limit;
1041bool CodeGenPrepare::canMergeBlocks(
const BasicBlock *BB,
1042 const BasicBlock *DestBB)
const {
1046 for (
const PHINode &PN : BB->
phis()) {
1047 for (
const User *U : PN.users()) {
1056 for (
unsigned I = 0,
E = UPN->getNumIncomingValues();
I !=
E; ++
I) {
1059 Insn->
getParent() != UPN->getIncomingBlock(
I))
1074 SmallPtrSet<const BasicBlock *, 16> BBPreds;
1077 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1078 BBPreds.
insert(BBPN->getIncomingBlock(i));
1086 if (BBPreds.
count(Pred)) {
1087 for (
const PHINode &PN : DestBB->
phis()) {
1088 const Value *V1 = PN.getIncomingValueForBlock(Pred);
1089 const Value *V2 = PN.getIncomingValueForBlock(BB);
1093 if (V2PN->getParent() == BB)
1094 V2 = V2PN->getIncomingValueForBlock(Pred);
1124void CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
1134 if (SinglePred != DestBB) {
1135 assert(SinglePred == BB &&
1136 "Single predecessor not the same as predecessor");
1145 FreshBBs.
insert(SinglePred);
1146 FreshBBs.
erase(DestBB);
1154 for (PHINode &PN : DestBB->
phis()) {
1156 Value *InVal = PN.removeIncomingValue(BB,
false);
1161 if (InValPhi && InValPhi->
getParent() == BB) {
1170 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1171 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1174 PN.addIncoming(InVal, Pred);
1204 for (
auto *ThisRelocate : AllRelocateCalls) {
1205 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1206 ThisRelocate->getDerivedPtrIndex());
1207 RelocateIdxMap.
insert(std::make_pair(K, ThisRelocate));
1209 for (
auto &Item : RelocateIdxMap) {
1210 std::pair<unsigned, unsigned>
Key = Item.first;
1211 if (
Key.first ==
Key.second)
1216 auto BaseKey = std::make_pair(
Key.first,
Key.first);
1219 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1220 if (MaybeBase == RelocateIdxMap.
end())
1225 RelocateInstMap[MaybeBase->second].push_back(
I);
1233 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1236 if (!
Op ||
Op->getZExtValue() > 20)
1240 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1250 bool MadeChange =
false;
1257 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1258 &*R != RelocatedBase; ++R)
1262 RelocatedBase->
moveBefore(RI->getIterator());
1269 "Not relocating a derived object of the original base object");
1270 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1275 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1285 if (!Derived || Derived->getPointerOperand() !=
Base)
1294 "Should always have one since it's not a terminator");
1298 Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
1322 Value *ActualRelocatedBase = RelocatedBase;
1323 if (RelocatedBase->
getType() !=
Base->getType()) {
1324 ActualRelocatedBase =
1325 Builder.CreateBitCast(RelocatedBase,
Base->getType());
1327 Value *Replacement =
1328 Builder.CreateGEP(Derived->getSourceElementType(), ActualRelocatedBase,
1334 Value *ActualReplacement = Replacement;
1335 if (Replacement->
getType() != ToReplace->getType()) {
1337 Builder.CreateBitCast(Replacement, ToReplace->
getType());
1340 ToReplace->eraseFromParent();
1364bool CodeGenPrepare::simplifyOffsetableRelocate(GCStatepointInst &
I) {
1365 bool MadeChange =
false;
1367 for (
auto *U :
I.users())
1374 if (AllRelocateCalls.
size() < 2)
1379 MapVector<GCRelocateInst *, SmallVector<GCRelocateInst *, 0>> RelocateInstMap;
1381 if (RelocateInstMap.
empty())
1384 for (
auto &Item : RelocateInstMap)
1398 bool MadeChange =
false;
1401 Use &TheUse = UI.getUse();
1408 UserBB = PN->getIncomingBlock(TheUse);
1416 if (
User->isEHPad())
1426 if (UserBB == DefBB)
1430 CastInst *&InsertedCast = InsertedCasts[UserBB];
1432 if (!InsertedCast) {
1440 TheUse = InsertedCast;
1466 ASC->getDestAddressSpace()))
1521static std::optional<std::pair<Instruction *, Constant *>>
1524 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1525 return std::nullopt;
1528 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1529 return std::nullopt;
1533 return std::make_pair(IVInc, Step);
1534 return std::nullopt;
1547 return IVInc->first ==
I;
1551bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
1555 auto IsReplacableIVIncrement = [
this, &
Cmp](BinaryOperator *BO) {
1558 const Loop *
L = LI->getLoopFor(BO->
getParent());
1559 assert(L &&
"L should not be null after isIVIncrement()");
1561 if (LI->getLoopFor(
Cmp->getParent()) != L)
1567 auto &DT = getDT(*BO->
getParent()->getParent());
1576 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1599 if (BO->
getOpcode() == Instruction::Add &&
1600 IID == Intrinsic::usub_with_overflow) {
1607 for (Instruction &Iter : *
Cmp->getParent()) {
1610 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1615 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1618 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1619 if (BO->
getOpcode() != Instruction::Xor) {
1620 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1624 "Patterns with XOr should use the BO only in the compare");
1625 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1627 Cmp->eraseFromParent();
1637 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1645 B = ConstantInt::get(
B->getType(), 1);
1653 for (
User *U :
A->users()) {
1664bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp,
1665 ModifyDT &ModifiedDT) {
1666 bool EdgeCase =
false;
1668 BinaryOperator *
Add;
1673 A =
Add->getOperand(0);
1674 B =
Add->getOperand(1);
1680 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1686 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1689 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1690 Intrinsic::uadd_with_overflow))
1694 ModifiedDT = ModifyDT::ModifyInstDT;
1698bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
1699 ModifyDT &ModifiedDT) {
1706 ICmpInst::Predicate Pred =
Cmp->getPredicate();
1707 if (Pred == ICmpInst::ICMP_UGT) {
1709 Pred = ICmpInst::ICMP_ULT;
1713 B = ConstantInt::get(
B->getType(), 1);
1714 Pred = ICmpInst::ICMP_ULT;
1719 Pred = ICmpInst::ICMP_ULT;
1721 if (Pred != ICmpInst::ICMP_ULT)
1728 BinaryOperator *
Sub =
nullptr;
1729 for (User *U : CmpVariableOperand->
users()) {
1737 const APInt *CmpC, *AddC;
1749 Sub->hasNUsesOrMore(1)))
1752 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1753 Cmp, Intrinsic::usub_with_overflow))
1757 ModifiedDT = ModifyDT::ModifyInstDT;
1764bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1778 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1784 Type *OpTy =
X->getType();
1792 if (Pred == ICmpInst::ICMP_EQ) {
1793 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1794 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1796 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1802 if (IsPowerOf2OrZeroTest ||
1813 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1822 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1825 Cmp->replaceAllUsesWith(NewCmp);
1847 bool MadeChange =
false;
1850 Use &TheUse = UI.getUse();
1865 if (UserBB == DefBB)
1869 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1875 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1882 TheUse = InsertedCmp;
1888 if (Cmp->use_empty()) {
1889 Cmp->eraseFromParent();
1926 for (
User *U : Cmp->users()) {
1948 if (CmpBB != FalseBB)
1951 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
1965 for (
User *U : Cmp->users()) {
1974 SI->swapProfMetadata();
1986 Value *Op0 = Cmp->getOperand(0);
1987 Value *Op1 = Cmp->getOperand(1);
1996 unsigned NumInspected = 0;
1999 if (++NumInspected > 128)
2007 if (GoodToSwap > 0) {
2008 Cmp->swapOperands();
2028 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
2031 auto [ClassVal, ClassTest] =
2037 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2041 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
2042 Cmp->replaceAllUsesWith(IsFPClass);
2050 Value *Incr, *RemAmt;
2055 Value *AddInst, *AddOffset;
2058 if (PN !=
nullptr) {
2060 AddOffset =
nullptr;
2069 if (PN !=
nullptr) {
2082 if (PN->getNumIncomingValues() != 2)
2087 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2091 if (!L->contains(Rem))
2095 if (!L->isLoopInvariant(RemAmt))
2099 if (AddOffset && !L->isLoopInvariant(AddOffset))
2120 AddInstOut = AddInst;
2121 AddOffsetOut = AddOffset;
2140 Value *AddOffset, *RemAmt, *AddInst;
2143 AddOffset, LoopIncrPN))
2168 assert(AddOffset &&
"We found an add but missing values");
2187 Builder.SetInsertPoint(LoopIncrPN);
2188 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2193 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2198 NewRem->
addIncoming(Start, L->getLoopPreheader());
2203 FreshBBs.
insert(L->getLoopLatch());
2214bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2220bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2224 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2227 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2230 if (unfoldPowerOf2Test(Cmp))
2251 SetOfInstrs &InsertedInsts) {
2254 assert(!InsertedInsts.count(AndI) &&
2255 "Attempting to optimize already optimized and instruction");
2256 (void)InsertedInsts;
2270 for (
auto *U : AndI->
users()) {
2278 if (!CmpC || !CmpC->
isZero())
2293 Use &TheUse = UI.getUse();
2311 TheUse = InsertedAnd;
2328 if (
User->getOpcode() != Instruction::And ||
2334 if ((Cimm & (Cimm + 1)).getBoolValue())
2348 bool MadeChange =
false;
2351 TruncE = TruncI->user_end();
2352 TruncUI != TruncE;) {
2354 Use &TruncTheUse = TruncUI.getUse();
2379 if (UserBB == TruncUserBB)
2383 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2385 if (!InsertedShift && !InsertedTrunc) {
2389 if (ShiftI->
getOpcode() == Instruction::AShr)
2391 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2394 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2402 TruncInsertPt.setHeadBit(
true);
2403 assert(TruncInsertPt != TruncUserBB->
end());
2407 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2408 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2412 TruncTheUse = InsertedTrunc;
2445 bool MadeChange =
false;
2448 Use &TheUse = UI.getUse();
2462 if (UserBB == DefBB) {
2490 if (!InsertedShift) {
2494 if (ShiftI->
getOpcode() == Instruction::AShr)
2496 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2499 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2507 TheUse = InsertedShift;
2554 unsigned SizeInBits = Ty->getScalarSizeInBits();
2555 if (Ty->isVectorTy())
2567 FreshBBs.
insert(CallBlock);
2574 SplitPt.setHeadBit(
true);
2577 FreshBBs.
insert(EndBlock);
2582 L->addBasicBlockToLoop(CallBlock, LI);
2583 L->addBasicBlockToLoop(EndBlock, LI);
2589 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2596 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2597 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2598 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2603 Builder.SetInsertPoint(EndBlock, EndBlock->
begin());
2604 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2614 ModifiedDT = ModifyDT::ModifyBBDT;
2618bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2622 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2630 for (
auto &Arg : CI->
args()) {
2635 if (!Arg->getType()->isPointerTy())
2637 APInt
Offset(
DL->getIndexSizeInBits(
2640 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2641 uint64_t Offset2 =
Offset.getLimitedValue();
2663 MaybeAlign MIDestAlign =
MI->getDestAlign();
2664 if (!MIDestAlign || DestAlign > *MIDestAlign)
2665 MI->setDestAlignment(DestAlign);
2667 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2669 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2670 MTI->setSourceAlignment(SrcAlign);
2680 for (
auto &Arg : CI->
args()) {
2681 if (!Arg->getType()->isPointerTy())
2683 unsigned AS = Arg->getType()->getPointerAddressSpace();
2684 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2690 switch (
II->getIntrinsicID()) {
2693 case Intrinsic::assume:
2695 case Intrinsic::allow_runtime_check:
2696 case Intrinsic::allow_ubsan_check:
2697 case Intrinsic::experimental_widenable_condition: {
2701 if (
II->use_empty()) {
2702 II->eraseFromParent();
2706 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2711 case Intrinsic::objectsize:
2713 case Intrinsic::is_constant:
2715 case Intrinsic::aarch64_stlxr:
2716 case Intrinsic::aarch64_stxr: {
2725 InsertedInsts.insert(ExtVal);
2729 case Intrinsic::launder_invariant_group:
2730 case Intrinsic::strip_invariant_group: {
2731 Value *ArgVal =
II->getArgOperand(0);
2732 auto it = LargeOffsetGEPMap.
find(
II);
2733 if (it != LargeOffsetGEPMap.
end()) {
2737 auto GEPs = std::move(it->second);
2738 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2743 II->eraseFromParent();
2746 case Intrinsic::cttz:
2747 case Intrinsic::ctlz:
2751 case Intrinsic::fshl:
2752 case Intrinsic::fshr:
2753 return optimizeFunnelShift(
II);
2754 case Intrinsic::masked_gather:
2755 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2756 case Intrinsic::masked_scatter:
2757 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2758 case Intrinsic::masked_load:
2761 if (VT->getNumElements() == 1) {
2762 Value *PtrVal =
II->getArgOperand(0);
2764 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2769 case Intrinsic::masked_store:
2773 if (VT->getNumElements() == 1) {
2774 Value *PtrVal =
II->getArgOperand(1);
2776 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2783 SmallVector<Value *, 2> PtrOps;
2786 while (!PtrOps.
empty()) {
2789 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2803 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2805 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2815 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2816 if (!
F->getReturnType()->isPointerTy())
2819 GlobalVariable *UniformValue =
nullptr;
2820 for (
auto &BB : *
F) {
2825 else if (V != UniformValue)
2833 return UniformValue;
2836 if (
Callee->hasExactDefinition()) {
2837 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2838 bool MadeChange =
false;
2864 switch (
II->getIntrinsicID()) {
2865 case Intrinsic::memset:
2866 case Intrinsic::memcpy:
2867 case Intrinsic::memmove:
2875 if (Callee && TLInfo && TLInfo->
getLibFunc(*Callee, LF))
2877 case LibFunc_strcpy:
2878 case LibFunc_strncpy:
2879 case LibFunc_strcat:
2880 case LibFunc_strncat:
2921bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
2922 ModifyDT &ModifiedDT) {
2930 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2932 PHINode *PN =
nullptr;
2933 ExtractValueInst *EVI =
nullptr;
2934 BitCastInst *BCI =
nullptr;
2954 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
2960 return II->getIntrinsicID() == Intrinsic::lifetime_end;
2966 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
2968 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
2990 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
3040 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
3042 if (!VisitedBBs.
insert(Pred).second)
3044 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
3062 for (
auto const &TailCallBB : TailCallBBs) {
3072 BFI->getBlockFreq(BB) >=
BFI->getBlockFreq(TailCallBB));
3073 BFI->setBlockFreq(BB,
3074 (
BFI->getBlockFreq(BB) -
BFI->getBlockFreq(TailCallBB)));
3075 ModifiedDT = ModifyDT::ModifyBBDT;
3084 for (
auto *CI : CallInsts) {
3085 for (
auto const *FakeUse : FakeUses) {
3086 auto *ClonedInst = FakeUse->clone();
3104struct ExtAddrMode :
public TargetLowering::AddrMode {
3105 Value *BaseReg =
nullptr;
3106 Value *ScaledReg =
nullptr;
3107 Value *OriginalValue =
nullptr;
3108 bool InBounds =
true;
3112 BaseRegField = 0x01,
3114 BaseOffsField = 0x04,
3115 ScaledRegField = 0x08,
3117 MultipleFields = 0xff
3120 ExtAddrMode() =
default;
3122 void print(raw_ostream &OS)
const;
3129 if (ScaledReg == From)
3133 FieldName
compare(
const ExtAddrMode &other) {
3136 if (BaseReg && other.
BaseReg &&
3138 return MultipleFields;
3139 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3140 return MultipleFields;
3143 return MultipleFields;
3146 if (InBounds != other.InBounds)
3147 return MultipleFields;
3150 unsigned Result = NoField;
3153 if (BaseGV != other.BaseGV)
3155 if (BaseOffs != other.BaseOffs)
3158 Result |= ScaledRegField;
3161 if (Scale && other.
Scale && Scale != other.
Scale)
3165 return MultipleFields;
3167 return static_cast<FieldName
>(
Result);
3177 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3188 case ScaledRegField:
3191 return ConstantInt::get(IntPtrTy, BaseOffs);
3195 void SetCombinedField(FieldName
Field,
Value *V,
3196 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3201 case ExtAddrMode::BaseRegField:
3204 case ExtAddrMode::BaseGVField:
3207 assert(BaseReg ==
nullptr);
3211 case ExtAddrMode::ScaledRegField:
3216 for (
const ExtAddrMode &AM : AddrModes)
3222 case ExtAddrMode::BaseOffsField:
3225 assert(ScaledReg ==
nullptr);
3235static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3241#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3242void ExtAddrMode::print(raw_ostream &OS)
const {
3243 bool NeedPlus =
false;
3249 BaseGV->printAsOperand(OS,
false);
3254 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3259 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3260 BaseReg->printAsOperand(OS,
false);
3264 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3287class TypePromotionTransaction {
3291 class TypePromotionAction {
3299 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3301 virtual ~TypePromotionAction() =
default;
3308 virtual void undo() = 0;
3313 virtual void commit() {
3319 class InsertionHandler {
3328 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3331 bool HasPrevInstruction;
3335 InsertionHandler(Instruction *Inst) {
3343 if (HasPrevInstruction) {
3351 void insert(Instruction *Inst) {
3352 if (HasPrevInstruction) {
3364 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3369 class InstructionMoveBefore :
public TypePromotionAction {
3371 InsertionHandler Position;
3376 : TypePromotionAction(Inst), Position(Inst) {
3377 LLVM_DEBUG(
dbgs() <<
"Do: move: " << *Inst <<
"\nbefore: " << *Before
3383 void undo()
override {
3385 Position.insert(Inst);
3390 class OperandSetter :
public TypePromotionAction {
3399 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3400 : TypePromotionAction(Inst), Idx(Idx) {
3402 <<
"for:" << *Inst <<
"\n"
3403 <<
"with:" << *NewVal <<
"\n");
3409 void undo()
override {
3411 <<
"for: " << *Inst <<
"\n"
3412 <<
"with: " << *Origin <<
"\n");
3419 class OperandsHider :
public TypePromotionAction {
3425 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3428 OriginalValues.
reserve(NumOpnds);
3429 for (
unsigned It = 0; It < NumOpnds; ++It) {
3441 void undo()
override {
3443 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3449 class TruncBuilder :
public TypePromotionAction {
3456 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3458 Builder.SetCurrentDebugLocation(
DebugLoc());
3459 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3464 Value *getBuiltValue() {
return Val; }
3467 void undo()
override {
3470 IVal->eraseFromParent();
3475 class SExtBuilder :
public TypePromotionAction {
3482 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3483 : TypePromotionAction(InsertPt) {
3485 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3490 Value *getBuiltValue() {
return Val; }
3493 void undo()
override {
3496 IVal->eraseFromParent();
3501 class ZExtBuilder :
public TypePromotionAction {
3508 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3509 : TypePromotionAction(InsertPt) {
3511 Builder.SetCurrentDebugLocation(
DebugLoc());
3512 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3517 Value *getBuiltValue() {
return Val; }
3520 void undo()
override {
3523 IVal->eraseFromParent();
3528 class TypeMutator :
public TypePromotionAction {
3534 TypeMutator(Instruction *Inst,
Type *NewTy)
3535 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3536 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3542 void undo()
override {
3543 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3550 class UsesReplacer :
public TypePromotionAction {
3552 struct InstructionAndIdx {
3559 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3560 : Inst(Inst), Idx(Idx) {}
3566 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3576 UsesReplacer(Instruction *Inst,
Value *New)
3577 : TypePromotionAction(Inst),
New(
New) {
3578 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3581 for (Use &U : Inst->
uses()) {
3583 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3594 void undo()
override {
3596 for (InstructionAndIdx &Use : OriginalUses)
3597 Use.Inst->setOperand(
Use.Idx, Inst);
3602 for (DbgVariableRecord *DVR : DbgVariableRecords)
3603 DVR->replaceVariableLocationOp(New, Inst);
3608 class InstructionRemover :
public TypePromotionAction {
3610 InsertionHandler Inserter;
3614 OperandsHider Hider;
3617 UsesReplacer *Replacer =
nullptr;
3620 SetOfInstrs &RemovedInsts;
3627 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3628 Value *New =
nullptr)
3629 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3630 RemovedInsts(RemovedInsts) {
3632 Replacer =
new UsesReplacer(Inst, New);
3633 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3634 RemovedInsts.insert(Inst);
3641 ~InstructionRemover()
override {
delete Replacer; }
3643 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3644 InstructionRemover(
const InstructionRemover &other) =
delete;
3648 void undo()
override {
3649 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3650 Inserter.insert(Inst);
3654 RemovedInsts.erase(Inst);
3662 using ConstRestorationPt =
const TypePromotionAction *;
3664 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3665 : RemovedInsts(RemovedInsts) {}
3672 void rollback(ConstRestorationPt Point);
3675 ConstRestorationPt getRestorationPoint()
const;
3680 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3689 void mutateType(Instruction *Inst,
Type *NewTy);
3692 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3705 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3707 SetOfInstrs &RemovedInsts;
3712void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3714 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3715 Inst, Idx, NewVal));
3718void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3721 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3722 Inst, RemovedInsts, NewVal));
3725void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3728 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3731void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3733 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3736Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3737 std::unique_ptr<TruncBuilder>
Ptr(
new TruncBuilder(Opnd, Ty));
3739 Actions.push_back(std::move(
Ptr));
3743Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3745 std::unique_ptr<SExtBuilder>
Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3747 Actions.push_back(std::move(
Ptr));
3751Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3753 std::unique_ptr<ZExtBuilder>
Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3755 Actions.push_back(std::move(
Ptr));
3759TypePromotionTransaction::ConstRestorationPt
3760TypePromotionTransaction::getRestorationPoint()
const {
3761 return !Actions.empty() ? Actions.back().get() :
nullptr;
3764bool TypePromotionTransaction::commit() {
3765 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3772void TypePromotionTransaction::rollback(
3773 TypePromotionTransaction::ConstRestorationPt Point) {
3774 while (!Actions.empty() && Point != Actions.back().get()) {
3775 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3785class AddressingModeMatcher {
3786 SmallVectorImpl<Instruction *> &AddrModeInsts;
3787 const TargetLowering &TLI;
3788 const TargetRegisterInfo &
TRI;
3789 const DataLayout &
DL;
3791 const std::function<
const DominatorTree &()> getDTFn;
3804 const SetOfInstrs &InsertedInsts;
3807 InstrToOrigTy &PromotedInsts;
3810 TypePromotionTransaction &TPT;
3813 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3817 bool IgnoreProfitability;
3820 bool OptSize =
false;
3822 ProfileSummaryInfo *PSI;
3823 BlockFrequencyInfo *
BFI;
3825 AddressingModeMatcher(
3826 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3827 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3828 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3829 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3830 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3831 TypePromotionTransaction &TPT,
3832 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3833 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI)
3834 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3835 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3836 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3837 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3838 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI),
BFI(
BFI) {
3839 IgnoreProfitability =
false;
3851 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3852 SmallVectorImpl<Instruction *> &AddrModeInsts,
3853 const TargetLowering &TLI,
const LoopInfo &LI,
3854 const std::function<
const DominatorTree &()> getDTFn,
3855 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3856 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3857 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3858 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
3861 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3862 AccessTy, AS, MemoryInst, Result,
3863 InsertedInsts, PromotedInsts, TPT,
3864 LargeOffsetGEP, OptSize, PSI, BFI)
3872 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3874 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3875 bool *MovedAway =
nullptr);
3876 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3877 ExtAddrMode &AMBefore,
3878 ExtAddrMode &AMAfter);
3879 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3880 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3881 Value *PromotedOperand)
const;
3887class PhiNodeSetIterator {
3888 PhiNodeSet *
const Set;
3889 size_t CurrentIndex = 0;
3894 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3896 PhiNodeSetIterator &operator++();
3912 friend class PhiNodeSetIterator;
3914 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3915 using iterator = PhiNodeSetIterator;
3930 size_t FirstValidElement = 0;
3936 bool insert(PHINode *
Ptr) {
3948 if (NodeMap.erase(
Ptr)) {
3949 SkipRemovedElements(FirstValidElement);
3959 FirstValidElement = 0;
3965 if (FirstValidElement == 0)
3966 SkipRemovedElements(FirstValidElement);
3967 return PhiNodeSetIterator(
this, FirstValidElement);
3974 size_t size()
const {
return NodeMap.size(); }
3977 size_t count(PHINode *
Ptr)
const {
return NodeMap.count(
Ptr); }
3985 void SkipRemovedElements(
size_t &CurrentIndex) {
3987 auto it = NodeMap.find(NodeList[CurrentIndex]);
3990 if (it != NodeMap.end() && it->second == CurrentIndex)
3997PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
4000PHINode *PhiNodeSetIterator::operator*()
const {
4002 "PhiNodeSet access out of range");
4003 return Set->NodeList[CurrentIndex];
4006PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
4008 "PhiNodeSet access out of range");
4010 Set->SkipRemovedElements(CurrentIndex);
4014bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
4015 return CurrentIndex ==
RHS.CurrentIndex;
4018bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
4019 return !((*this) ==
RHS);
4025class SimplificationTracker {
4026 DenseMap<Value *, Value *> Storage;
4027 const SimplifyQuery &SQ;
4030 PhiNodeSet AllPhiNodes;
4032 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
4035 SimplificationTracker(
const SimplifyQuery &sq) : SQ(sq) {}
4039 auto SV = Storage.
find(V);
4040 if (SV == Storage.
end())
4048 SmallPtrSet<Value *, 32> Visited;
4050 while (!WorkList.
empty()) {
4052 if (!Visited.
insert(
P).second)
4056 for (
auto *U : PI->users())
4059 PI->replaceAllUsesWith(V);
4061 AllPhiNodes.erase(
PHI);
4064 PI->eraseFromParent();
4072 void ReplacePhi(PHINode *From, PHINode *To) {
4073 Value *OldReplacement = Get(From);
4074 while (OldReplacement != From) {
4077 OldReplacement = Get(From);
4079 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
4082 AllPhiNodes.erase(From);
4086 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
4088 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
4090 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
4092 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4094 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4096 void destroyNewNodes(
Type *CommonType) {
4099 for (
auto *
I : AllPhiNodes) {
4100 I->replaceAllUsesWith(Dummy);
4101 I->eraseFromParent();
4103 AllPhiNodes.clear();
4104 for (
auto *
I : AllSelectNodes) {
4105 I->replaceAllUsesWith(Dummy);
4106 I->eraseFromParent();
4108 AllSelectNodes.clear();
4113class AddressingModeCombiner {
4114 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4115 typedef std::pair<PHINode *, PHINode *> PHIPair;
4122 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4125 bool AllAddrModesTrivial =
true;
4128 Type *CommonType =
nullptr;
4131 const SimplifyQuery &SQ;
4137 Value *CommonValue =
nullptr;
4140 AddressingModeCombiner(
const SimplifyQuery &_SQ,
Value *OriginalValue)
4141 : SQ(_SQ), Original(OriginalValue) {}
4143 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4146 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4151 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4155 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4158 if (AddrModes.
empty()) {
4166 ExtAddrMode::FieldName ThisDifferentField =
4167 AddrModes[0].compare(NewAddrMode);
4168 if (DifferentField == ExtAddrMode::NoField)
4169 DifferentField = ThisDifferentField;
4170 else if (DifferentField != ThisDifferentField)
4171 DifferentField = ExtAddrMode::MultipleFields;
4174 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4177 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4182 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4187 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4188 !NewAddrMode.HasBaseReg);
4205 bool combineAddrModes() {
4207 if (AddrModes.
size() == 0)
4211 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4216 if (AllAddrModesTrivial)
4219 if (!addrModeCombiningAllowed())
4225 FoldAddrToValueMapping
Map;
4226 if (!initializeMap(Map))
4229 CommonValue = findCommon(Map);
4231 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4232 return CommonValue !=
nullptr;
4238 void eraseCommonValueIfDead() {
4239 if (CommonValue && CommonValue->
use_empty())
4241 CommonInst->eraseFromParent();
4249 bool initializeMap(FoldAddrToValueMapping &Map) {
4252 SmallVector<Value *, 2> NullValue;
4254 for (
auto &AM : AddrModes) {
4255 Value *DV = AM.GetFieldAsValue(DifferentField, IntPtrTy);
4258 if (CommonType && CommonType !=
Type)
4261 Map[AM.OriginalValue] = DV;
4266 assert(CommonType &&
"At least one non-null value must be!");
4267 for (
auto *V : NullValue)
4295 Value *findCommon(FoldAddrToValueMapping &Map) {
4303 SimplificationTracker
ST(SQ);
4308 InsertPlaceholders(Map, TraverseOrder, ST);
4311 FillPlaceholders(Map, TraverseOrder, ST);
4314 ST.destroyNewNodes(CommonType);
4319 unsigned PhiNotMatchedCount = 0;
4321 ST.destroyNewNodes(CommonType);
4325 auto *
Result =
ST.Get(
Map.find(Original)->second);
4327 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4328 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4335 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4336 SmallSetVector<PHIPair, 8> &Matcher,
4337 PhiNodeSet &PhiNodesToMatch) {
4340 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4343 SmallSet<PHIPair, 8> Visited;
4344 while (!WorkList.
empty()) {
4346 if (!Visited.
insert(Item).second)
4353 for (
auto *
B : Item.first->blocks()) {
4354 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4355 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4356 if (FirstValue == SecondValue)
4366 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4371 if (Matcher.
count({FirstPhi, SecondPhi}))
4376 if (MatchedPHIs.
insert(FirstPhi).second)
4377 Matcher.
insert({FirstPhi, SecondPhi});
4379 WorkList.
push_back({FirstPhi, SecondPhi});
4388 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4389 unsigned &PhiNotMatchedCount) {
4393 SmallSetVector<PHIPair, 8> Matched;
4394 SmallPtrSet<PHINode *, 8> WillNotMatch;
4395 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4396 while (PhiNodesToMatch.size()) {
4397 PHINode *
PHI = *PhiNodesToMatch.begin();
4400 WillNotMatch.
clear();
4404 bool IsMatched =
false;
4405 for (
auto &
P :
PHI->getParent()->phis()) {
4407 if (PhiNodesToMatch.count(&
P))
4409 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4419 for (
auto MV : Matched)
4420 ST.ReplacePhi(MV.first, MV.second);
4425 if (!AllowNewPhiNodes)
4428 PhiNotMatchedCount += WillNotMatch.
size();
4429 for (
auto *
P : WillNotMatch)
4430 PhiNodesToMatch.erase(
P);
4435 void FillPlaceholders(FoldAddrToValueMapping &Map,
4436 SmallVectorImpl<Value *> &TraverseOrder,
4437 SimplificationTracker &ST) {
4438 while (!TraverseOrder.
empty()) {
4440 assert(
Map.contains(Current) &&
"No node to fill!!!");
4446 auto *TrueValue = CurrentSelect->getTrueValue();
4447 assert(
Map.contains(TrueValue) &&
"No True Value!");
4448 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4449 auto *FalseValue = CurrentSelect->getFalseValue();
4450 assert(
Map.contains(FalseValue) &&
"No False Value!");
4451 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4458 assert(
Map.contains(PV) &&
"No predecessor Value!");
4459 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4462 Map[Current] =
ST.Simplify(V);
4471 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4472 SmallVectorImpl<Value *> &TraverseOrder,
4473 SimplificationTracker &ST) {
4476 "Address must be a Phi or Select node");
4479 while (!Worklist.
empty()) {
4482 if (
Map.contains(Current))
4493 CurrentSelect->getName(),
4494 CurrentSelect->getIterator(), CurrentSelect);
4498 Worklist.
push_back(CurrentSelect->getTrueValue());
4499 Worklist.
push_back(CurrentSelect->getFalseValue());
4507 ST.insertNewPhi(
PHI);
4513 bool addrModeCombiningAllowed() {
4516 switch (DifferentField) {
4519 case ExtAddrMode::BaseRegField:
4521 case ExtAddrMode::BaseGVField:
4523 case ExtAddrMode::BaseOffsField:
4525 case ExtAddrMode::ScaledRegField:
4535bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4540 return matchAddr(ScaleReg,
Depth);
4551 ExtAddrMode TestAddrMode =
AddrMode;
4555 TestAddrMode.
Scale += Scale;
4569 ConstantInt *CI =
nullptr;
4570 Value *AddLHS =
nullptr;
4574 TestAddrMode.InBounds =
false;
4591 auto GetConstantStep =
4592 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4595 return std::nullopt;
4598 return std::nullopt;
4606 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4607 return std::nullopt;
4609 return std::make_pair(IVInc->first, ConstantStep->getValue());
4610 return std::nullopt;
4625 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4632 APInt Step = IVStep->second;
4634 if (
Offset.isSignedIntN(64)) {
4635 TestAddrMode.InBounds =
false;
4637 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4642 getDTFn().
dominates(IVInc, MemoryInst)) {
4662 switch (
I->getOpcode()) {
4663 case Instruction::BitCast:
4664 case Instruction::AddrSpaceCast:
4666 if (
I->getType() ==
I->getOperand(0)->getType())
4668 return I->getType()->isIntOrPtrTy();
4669 case Instruction::PtrToInt:
4672 case Instruction::IntToPtr:
4675 case Instruction::Add:
4677 case Instruction::Mul:
4678 case Instruction::Shl:
4681 case Instruction::GetElementPtr:
4709class TypePromotionHelper {
4712 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4713 Instruction *ExtOpnd,
bool IsSExt) {
4714 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4715 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4719 if (It->second.getInt() == ExtTy)
4725 ExtTy = BothExtension;
4727 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4734 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4735 Instruction *Opnd,
bool IsSExt) {
4736 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4737 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4738 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4739 return It->second.getPointer();
4754 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4755 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4759 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4772 static Value *promoteOperandForTruncAndAnyExt(
4773 Instruction *Ext, TypePromotionTransaction &TPT,
4774 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4775 SmallVectorImpl<Instruction *> *Exts,
4776 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4787 static Value *promoteOperandForOther(Instruction *Ext,
4788 TypePromotionTransaction &TPT,
4789 InstrToOrigTy &PromotedInsts,
4790 unsigned &CreatedInstsCost,
4791 SmallVectorImpl<Instruction *> *Exts,
4792 SmallVectorImpl<Instruction *> *Truncs,
4793 const TargetLowering &TLI,
bool IsSExt);
4796 static Value *signExtendOperandForOther(
4797 Instruction *Ext, TypePromotionTransaction &TPT,
4798 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4799 SmallVectorImpl<Instruction *> *Exts,
4800 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4801 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4802 Exts, Truncs, TLI,
true);
4806 static Value *zeroExtendOperandForOther(
4807 Instruction *Ext, TypePromotionTransaction &TPT,
4808 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4809 SmallVectorImpl<Instruction *> *Exts,
4810 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4811 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4812 Exts, Truncs, TLI,
false);
4817 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4818 InstrToOrigTy &PromotedInsts,
4819 unsigned &CreatedInstsCost,
4820 SmallVectorImpl<Instruction *> *Exts,
4821 SmallVectorImpl<Instruction *> *Truncs,
4822 const TargetLowering &TLI);
4833 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4834 const TargetLowering &TLI,
4835 const InstrToOrigTy &PromotedInsts);
4840bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4841 Type *ConsideredExtType,
4842 const InstrToOrigTy &PromotedInsts,
4862 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4863 (IsSExt && BinOp->hasNoSignedWrap())))
4867 if ((Inst->
getOpcode() == Instruction::And ||
4872 if (Inst->
getOpcode() == Instruction::Xor) {
4875 if (!Cst->getValue().isAllOnes())
4884 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4894 if (ExtInst->hasOneUse()) {
4896 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4929 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4942TypePromotionHelper::Action TypePromotionHelper::getAction(
4943 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4944 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
4946 "Unexpected instruction type");
4953 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4966 return promoteOperandForTruncAndAnyExt;
4972 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4975Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4976 Instruction *SExt, TypePromotionTransaction &TPT,
4977 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4978 SmallVectorImpl<Instruction *> *Exts,
4979 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4983 Value *ExtVal = SExt;
4984 bool HasMergedNonFreeExt =
false;
4988 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
4991 TPT.replaceAllUsesWith(SExt, ZExt);
4992 TPT.eraseInstruction(SExt);
4997 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
4999 CreatedInstsCost = 0;
5003 TPT.eraseInstruction(SExtOpnd);
5011 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
5019 TPT.eraseInstruction(ExtInst, NextVal);
5023Value *TypePromotionHelper::promoteOperandForOther(
5024 Instruction *Ext, TypePromotionTransaction &TPT,
5025 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5026 SmallVectorImpl<Instruction *> *Exts,
5027 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
5032 CreatedInstsCost = 0;
5038 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
5041 ITrunc->moveAfter(ExtOpnd);
5046 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
5049 TPT.setOperand(Ext, 0, ExtOpnd);
5059 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
5061 TPT.mutateType(ExtOpnd,
Ext->getType());
5063 TPT.replaceAllUsesWith(Ext, ExtOpnd);
5070 !shouldExtOperand(ExtOpnd,
OpIdx)) {
5078 unsigned BitWidth =
Ext->getType()->getIntegerBitWidth();
5079 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
5081 TPT.setOperand(ExtOpnd,
OpIdx, ConstantInt::get(
Ext->getType(), CstVal));
5092 Value *ValForExtOpnd = IsSExt
5093 ? TPT.createSExt(ExtOpnd, Opnd,
Ext->getType())
5094 : TPT.createZExt(ExtOpnd, Opnd,
Ext->getType());
5095 TPT.setOperand(ExtOpnd,
OpIdx, ValForExtOpnd);
5097 if (!InstForExtOpnd)
5103 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5106 TPT.eraseInstruction(Ext);
5118bool AddressingModeMatcher::isPromotionProfitable(
5119 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5120 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5125 if (NewCost > OldCost)
5127 if (NewCost < OldCost)
5146bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5158 case Instruction::PtrToInt:
5161 case Instruction::IntToPtr: {
5169 case Instruction::BitCast:
5179 case Instruction::AddrSpaceCast: {
5187 case Instruction::Add: {
5190 ExtAddrMode BackupAddrMode =
AddrMode;
5191 unsigned OldSize = AddrModeInsts.
size();
5196 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5197 TPT.getRestorationPoint();
5201 int First = 0, Second = 1;
5212 AddrModeInsts.
resize(OldSize);
5213 TPT.rollback(LastKnownGood);
5223 AddrModeInsts.
resize(OldSize);
5224 TPT.rollback(LastKnownGood);
5230 case Instruction::Mul:
5231 case Instruction::Shl: {
5235 if (!
RHS ||
RHS->getBitWidth() > 64)
5237 int64_t Scale = Opcode == Instruction::Shl
5238 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5239 :
RHS->getSExtValue();
5243 case Instruction::GetElementPtr: {
5246 int VariableOperand = -1;
5247 unsigned VariableScale = 0;
5249 int64_t ConstantOffset = 0;
5251 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5253 const StructLayout *SL =
DL.getStructLayout(STy);
5264 if (ConstantInt *CI =
5266 const APInt &CVal = CI->
getValue();
5273 if (VariableOperand != -1)
5277 VariableOperand = i;
5278 VariableScale = TypeSize;
5285 if (VariableOperand == -1) {
5286 AddrMode.BaseOffs += ConstantOffset;
5292 AddrMode.BaseOffs -= ConstantOffset;
5296 ConstantOffset > 0) {
5309 BasicBlock *Parent = BaseI ? BaseI->getParent()
5310 : &
GEP->getFunction()->getEntryBlock();
5312 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5320 ExtAddrMode BackupAddrMode =
AddrMode;
5321 unsigned OldSize = AddrModeInsts.
size();
5324 AddrMode.BaseOffs += ConstantOffset;
5333 AddrModeInsts.
resize(OldSize);
5341 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5346 AddrModeInsts.
resize(OldSize);
5351 AddrMode.BaseOffs += ConstantOffset;
5352 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5353 VariableScale,
Depth)) {
5356 AddrModeInsts.
resize(OldSize);
5363 case Instruction::SExt:
5364 case Instruction::ZExt: {
5371 TypePromotionHelper::Action TPH =
5372 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5376 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5377 TPT.getRestorationPoint();
5378 unsigned CreatedInstsCost = 0;
5380 Value *PromotedOperand =
5381 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5396 assert(PromotedOperand &&
5397 "TypePromotionHelper should have filtered out those cases");
5399 ExtAddrMode BackupAddrMode =
AddrMode;
5400 unsigned OldSize = AddrModeInsts.
size();
5402 if (!matchAddr(PromotedOperand,
Depth) ||
5407 !isPromotionProfitable(CreatedInstsCost,
5408 ExtCost + (AddrModeInsts.
size() - OldSize),
5411 AddrModeInsts.
resize(OldSize);
5412 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5413 TPT.rollback(LastKnownGood);
5418 AddrMode.replaceWith(Ext, PromotedOperand);
5421 case Instruction::Call:
5423 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5439bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5442 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5443 TPT.getRestorationPoint();
5467 ExtAddrMode BackupAddrMode =
AddrMode;
5468 unsigned OldSize = AddrModeInsts.
size();
5471 bool MovedAway =
false;
5472 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5480 if (
I->hasOneUse() ||
5481 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5488 AddrModeInsts.
resize(OldSize);
5489 TPT.rollback(LastKnownGood);
5492 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5494 TPT.rollback(LastKnownGood);
5521 TPT.rollback(LastKnownGood);
5540 if (OpInfo.CallOperandVal == OpVal &&
5542 !OpInfo.isIndirect))
5558 if (!ConsideredInsts.
insert(
I).second)
5566 for (
Use &U :
I->uses()) {
5574 MemoryUses.push_back({&U, LI->getType()});
5581 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5588 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5595 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5605 if (!
find(PtrOps, U.get()))
5608 MemoryUses.push_back({&U, AccessTy});
5613 if (CI->hasFnAttr(Attribute::Cold)) {
5631 PSI, BFI, SeenInsts))
5642 unsigned SeenInsts = 0;
5645 PSI, BFI, SeenInsts);
5653bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5655 Value *KnownLive2) {
5657 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5698bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5699 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5700 if (IgnoreProfitability)
5718 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5719 ScaledReg =
nullptr;
5723 if (!BaseReg && !ScaledReg)
5744 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5747 Type *AddressAccessTy = Pair.second;
5748 unsigned AS =
Address->getType()->getPointerAddressSpace();
5754 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5756 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5757 TPT.getRestorationPoint();
5758 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5759 AddressAccessTy, AS, UserI, Result,
5760 InsertedInsts, PromotedInsts, TPT,
5761 LargeOffsetGEP, OptSize, PSI, BFI);
5762 Matcher.IgnoreProfitability =
true;
5770 TPT.rollback(LastKnownGood);
5776 MatchedAddrModeInsts.
clear();
5786 return I->getParent() != BB;
5802 return std::next(AddrInst->getIterator());
5813 Earliest = UserInst;
5838bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5839 Type *AccessTy,
unsigned AddrSpace) {
5844 SmallVector<Value *, 8> worklist;
5845 SmallPtrSet<Value *, 16> Visited;
5851 bool PhiOrSelectSeen =
false;
5852 SmallVector<Instruction *, 16> AddrModeInsts;
5853 const SimplifyQuery SQ(*
DL, TLInfo);
5854 AddressingModeCombiner AddrModes(SQ, Addr);
5855 TypePromotionTransaction TPT(RemovedInsts);
5856 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5857 TPT.getRestorationPoint();
5858 while (!worklist.
empty()) {
5870 if (!Visited.
insert(V).second)
5876 PhiOrSelectSeen =
true;
5883 PhiOrSelectSeen =
true;
5890 AddrModeInsts.
clear();
5891 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5896 auto getDTFn = [MemoryInst,
this]() ->
const DominatorTree & {
5898 return this->getDT(*
F);
5900 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5901 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5902 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5905 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5910 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5911 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5914 NewAddrMode.OriginalValue =
V;
5915 if (!AddrModes.addNewAddrMode(NewAddrMode))
5922 if (!AddrModes.combineAddrModes()) {
5923 TPT.rollback(LastKnownGood);
5929 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5935 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5949 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
5971 <<
" for " << *MemoryInst <<
"\n");
5975 !
DL->isNonIntegralPointerType(Addr->
getType())) {
5981 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
5983 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
5985 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
5992 <<
" for " << *MemoryInst <<
"\n");
5993 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
6004 if (ResultPtr ||
AddrMode.Scale != 1)
6025 GlobalValue *BaseGV =
AddrMode.BaseGV;
6026 if (BaseGV !=
nullptr) {
6031 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
6040 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
6041 if (!ResultPtr &&
AddrMode.BaseReg) {
6045 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
6046 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
6055 }
else if (!ResultPtr) {
6068 if (
V->getType() != IntPtrTy)
6069 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6077 if (
V->getType() == IntPtrTy) {
6082 "We can't transform if ScaledReg is too narrow");
6083 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6087 V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy,
AddrMode.Scale),
6090 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6101 if (ResultPtr->
getType() != I8PtrTy)
6102 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6103 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6116 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6118 SunkAddr = ResultPtr;
6120 if (ResultPtr->
getType() != I8PtrTy)
6121 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6122 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6129 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6135 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
6137 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6139 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6149 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6150 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6151 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6153 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6157 <<
" for " << *MemoryInst <<
"\n");
6168 if (
V->getType()->isPointerTy())
6169 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6170 if (
V->getType() != IntPtrTy)
6171 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6178 if (
V->getType() == IntPtrTy) {
6180 }
else if (
V->getType()->isPointerTy()) {
6181 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6184 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6193 I->eraseFromParent();
6197 V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy,
AddrMode.Scale),
6200 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6206 GlobalValue *BaseGV =
AddrMode.BaseGV;
6207 if (BaseGV !=
nullptr) {
6210 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6214 Value *
V = Builder.CreatePtrToInt(BaseGVPtr, IntPtrTy,
"sunkaddr");
6216 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6225 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6233 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6239 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6244 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6245 RecursivelyDeleteTriviallyDeadInstructions(
6246 Repl, TLInfo, nullptr,
6247 [&](Value *V) { removeAllAssertingVHReferences(V); });
6271bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6277 if (!
GEP->hasIndices())
6285 SmallVector<Value *, 2>
Ops(
GEP->operands());
6287 bool RewriteGEP =
false;
6296 unsigned FinalIndex =
Ops.size() - 1;
6301 for (
unsigned i = 1; i < FinalIndex; ++i) {
6306 C =
C->getSplatValue();
6308 if (!CI || !CI->
isZero())
6315 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6319 if (!
C || !
C->isZero()) {
6320 Ops[FinalIndex] =
V;
6328 if (!RewriteGEP &&
Ops.size() == 2)
6335 Type *SourceTy =
GEP->getSourceElementType();
6336 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6340 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6341 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6342 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6352 if (
Ops.size() != 2) {
6362 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6376 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6377 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6380 Intrinsic::masked_gather) {
6384 Intrinsic::masked_scatter);
6397 if (
Ptr->use_empty())
6399 Ptr, TLInfo,
nullptr,
6400 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6407bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6408 bool MadeChange =
false;
6410 const TargetRegisterInfo *
TRI =
6411 TM->getSubtargetImpl(*CS->
getFunction())->getRegisterInfo();
6415 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6421 OpInfo.isIndirect) {
6423 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6486bool CodeGenPrepare::tryToPromoteExts(
6487 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6488 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6489 unsigned CreatedInstsCost) {
6490 bool Promoted =
false;
6493 for (
auto *
I : Exts) {
6508 TypePromotionHelper::Action TPH =
6509 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6518 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6519 TPT.getRestorationPoint();
6520 SmallVector<Instruction *, 4> NewExts;
6521 unsigned NewCreatedInstsCost = 0;
6524 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6525 &NewExts,
nullptr, *TLI);
6527 "TypePromotionHelper should have filtered out those cases");
6537 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6540 TotalCreatedInstsCost =
6541 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6543 (TotalCreatedInstsCost > 1 ||
6545 (ExtCost == 0 && NewExts.
size() > 1))) {
6549 TPT.rollback(LastKnownGood);
6554 SmallVector<Instruction *, 2> NewlyMovedExts;
6555 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6556 bool NewPromoted =
false;
6557 for (
auto *ExtInst : NewlyMovedExts) {
6567 ProfitablyMovedExts.
push_back(MovedExt);
6574 TPT.rollback(LastKnownGood);
6585bool CodeGenPrepare::mergeSExts(Function &
F) {
6587 for (
auto &Entry : ValToSExtendedUses) {
6588 SExts &Insts =
Entry.second;
6590 for (Instruction *Inst : Insts) {
6594 bool inserted =
false;
6595 for (
auto &Pt : CurPts) {
6598 RemovedInsts.insert(Pt);
6599 Pt->removeFromParent();
6610 RemovedInsts.insert(Inst);
6617 CurPts.push_back(Inst);
6659bool CodeGenPrepare::splitLargeGEPOffsets() {
6661 for (
auto &Entry : LargeOffsetGEPMap) {
6663 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6664 &LargeOffsetGEPs =
Entry.second;
6665 auto compareGEPOffset =
6666 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6667 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6668 if (
LHS.first ==
RHS.first)
6670 if (
LHS.second !=
RHS.second)
6671 return LHS.second <
RHS.second;
6672 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6675 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6678 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6680 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6681 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6682 Value *NewBaseGEP =
nullptr;
6684 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6685 GetElementPtrInst *
GEP) {
6686 LLVMContext &Ctx =
GEP->getContext();
6687 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6689 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6701 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), DT.get(), LI);
6704 NewBaseInsertPt = std::next(BaseI->getIterator());
6711 IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
6713 Value *BaseIndex = ConstantInt::get(PtrIdxTy, BaseOffset);
6714 NewBaseGEP = OldBase;
6715 if (NewBaseGEP->
getType() != I8PtrTy)
6716 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6718 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6719 NewGEPBases.
insert(NewBaseGEP);
6725 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6726 BaseOffset = PreferBase;
6729 createNewBase(BaseOffset, OldBase, BaseGEP);
6732 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6733 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6734 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6735 int64_t
Offset = LargeOffsetGEP->second;
6736 if (
Offset != BaseOffset) {
6743 GEP->getResultElementType(),
6744 GEP->getAddressSpace())) {
6750 NewBaseGEP =
nullptr;
6755 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6760 createNewBase(BaseOffset, OldBase,
GEP);
6764 Value *NewGEP = NewBaseGEP;
6765 if (
Offset != BaseOffset) {
6768 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6772 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6773 GEP->eraseFromParent();
6780bool CodeGenPrepare::optimizePhiType(
6781 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
6782 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
6787 Type *PhiTy =
I->getType();
6788 Type *ConvertTy =
nullptr;
6790 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6793 SmallVector<Instruction *, 4> Worklist;
6795 SmallPtrSet<PHINode *, 4> PhiNodes;
6796 SmallPtrSet<ConstantData *, 4>
Constants;
6799 SmallPtrSet<Instruction *, 4> Defs;
6800 SmallPtrSet<Instruction *, 4>
Uses;
6806 bool AnyAnchored =
false;
6808 while (!Worklist.
empty()) {
6813 for (
Value *V :
Phi->incoming_values()) {
6815 if (!PhiNodes.
count(OpPhi)) {
6816 if (!Visited.
insert(OpPhi).second)
6822 if (!OpLoad->isSimple())
6824 if (Defs.
insert(OpLoad).second)
6827 if (Defs.
insert(OpEx).second)
6831 ConvertTy = OpBC->getOperand(0)->getType();
6832 if (OpBC->getOperand(0)->getType() != ConvertTy)
6834 if (Defs.
insert(OpBC).second) {
6847 for (User *V :
II->users()) {
6849 if (!PhiNodes.
count(OpPhi)) {
6850 if (Visited.
count(OpPhi))
6857 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
6859 Uses.insert(OpStore);
6862 ConvertTy = OpBC->getType();
6863 if (OpBC->getType() != ConvertTy)
6867 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
6874 if (!ConvertTy || !AnyAnchored ||
6878 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
6879 << *ConvertTy <<
"\n");
6884 for (ConstantData *
C : Constants)
6886 for (Instruction *
D : Defs) {
6888 ValMap[
D] =
D->getOperand(0);
6892 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
6895 for (PHINode *Phi : PhiNodes)
6897 Phi->getName() +
".tc",
Phi->getIterator());
6899 for (PHINode *Phi : PhiNodes) {
6901 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
6903 Phi->getIncomingBlock(i));
6907 for (Instruction *U :
Uses) {
6912 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
6922bool CodeGenPrepare::optimizePhiTypes(Function &
F) {
6927 SmallPtrSet<PHINode *, 4> Visited;
6928 SmallPtrSet<Instruction *, 4> DeletedInstrs;
6932 for (
auto &Phi : BB.
phis())
6933 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
6936 for (
auto *
I : DeletedInstrs) {
6938 I->eraseFromParent();
6946bool CodeGenPrepare::canFormExtLd(
6947 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
6948 Instruction *&Inst,
bool HasPromoted) {
6949 for (
auto *MovedExtInst : MovedExts) {
6952 Inst = MovedExtInst;
7004bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7005 bool AllowPromotionWithoutCommonHeader =
false;
7010 *Inst, AllowPromotionWithoutCommonHeader);
7011 TypePromotionTransaction TPT(RemovedInsts);
7012 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7013 TPT.getRestorationPoint();
7015 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7018 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7021 LoadInst *LI =
nullptr;
7026 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7027 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7032 Inst = ExtFedByLoad;
7037 if (ATPConsiderable &&
7038 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7039 HasPromoted, TPT, SpeculativelyMovedExts))
7042 TPT.rollback(LastKnownGood);
7051bool CodeGenPrepare::performAddressTypePromotion(
7052 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7053 bool HasPromoted, TypePromotionTransaction &TPT,
7054 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7055 bool Promoted =
false;
7056 SmallPtrSet<Instruction *, 1> UnhandledExts;
7057 bool AllSeenFirst =
true;
7058 for (
auto *
I : SpeculativelyMovedExts) {
7059 Value *HeadOfChain =
I->getOperand(0);
7060 DenseMap<Value *, Instruction *>::iterator AlreadySeen =
7061 SeenChainsForSExt.
find(HeadOfChain);
7064 if (AlreadySeen != SeenChainsForSExt.
end()) {
7065 if (AlreadySeen->second !=
nullptr)
7066 UnhandledExts.
insert(AlreadySeen->second);
7067 AllSeenFirst =
false;
7071 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7072 SpeculativelyMovedExts.size() == 1)) {
7076 for (
auto *
I : SpeculativelyMovedExts) {
7077 Value *HeadOfChain =
I->getOperand(0);
7078 SeenChainsForSExt[HeadOfChain] =
nullptr;
7079 ValToSExtendedUses[HeadOfChain].push_back(
I);
7082 Inst = SpeculativelyMovedExts.pop_back_val();
7087 for (
auto *
I : SpeculativelyMovedExts) {
7088 Value *HeadOfChain =
I->getOperand(0);
7089 SeenChainsForSExt[HeadOfChain] = Inst;
7094 if (!AllSeenFirst && !UnhandledExts.
empty())
7095 for (
auto *VisitedSExt : UnhandledExts) {
7096 if (RemovedInsts.count(VisitedSExt))
7098 TypePromotionTransaction TPT(RemovedInsts);
7100 SmallVector<Instruction *, 2> Chains;
7102 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7106 for (
auto *
I : Chains) {
7107 Value *HeadOfChain =
I->getOperand(0);
7109 SeenChainsForSExt[HeadOfChain] =
nullptr;
7110 ValToSExtendedUses[HeadOfChain].push_back(
I);
7116bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7121 Value *Src =
I->getOperand(0);
7122 if (Src->hasOneUse())
7134 bool DefIsLiveOut =
false;
7135 for (User *U :
I->users()) {
7140 if (UserBB == DefBB)
7142 DefIsLiveOut =
true;
7149 for (User *U : Src->users()) {
7152 if (UserBB == DefBB)
7161 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7163 bool MadeChange =
false;
7164 for (Use &U : Src->uses()) {
7169 if (UserBB == DefBB)
7173 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7175 if (!InsertedTrunc) {
7178 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7180 InsertedInsts.insert(InsertedTrunc);
7243bool CodeGenPrepare::optimizeLoadExt(LoadInst *Load) {
7244 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7248 if (
Load->hasOneUse() &&
7254 SmallVector<Instruction *, 8> WorkList;
7255 SmallPtrSet<Instruction *, 16> Visited;
7256 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7257 SmallVector<Instruction *, 8> DropFlags;
7258 for (
auto *U :
Load->users())
7270 while (!WorkList.
empty()) {
7274 if (!Visited.
insert(
I).second)
7279 for (
auto *U :
Phi->users())
7284 switch (
I->getOpcode()) {
7285 case Instruction::And: {
7289 APInt AndBits = AndC->getValue();
7290 DemandBits |= AndBits;
7292 if (AndBits.
ugt(WidestAndBits))
7293 WidestAndBits = AndBits;
7294 if (AndBits == WidestAndBits &&
I->getOperand(0) == Load)
7299 case Instruction::Shl: {
7303 uint64_t ShiftAmt = ShlC->getLimitedValue(
BitWidth - 1);
7304 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7309 case Instruction::Trunc: {
7312 DemandBits.setLowBits(TruncBitWidth);
7322 uint32_t ActiveBits = DemandBits.getActiveBits();
7334 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7335 WidestAndBits != DemandBits)
7338 LLVMContext &Ctx =
Load->getType()->getContext();
7339 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7349 Builder.CreateAnd(Load, ConstantInt::get(Ctx, DemandBits)));
7352 InsertedInsts.insert(NewAnd);
7357 NewAnd->setOperand(0, Load);
7360 for (
auto *
And : AndsToMaybeRemove)
7365 if (&*CurInstIterator ==
And)
7366 CurInstIterator = std::next(
And->getIterator());
7367 And->eraseFromParent();
7372 for (
auto *Inst : DropFlags)
7386 TTI->isExpensiveToSpeculativelyExecute(
I);
7404 uint64_t Max = std::max(TrueWeight, FalseWeight);
7405 uint64_t Sum = TrueWeight + FalseWeight;
7408 if (Probability >
TTI->getPredictableBranchThreshold())
7418 if (!Cmp || !Cmp->hasOneUse())
7441 assert(DefSI->getCondition() ==
SI->getCondition() &&
7442 "The condition of DefSI does not match with SI");
7443 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7446 assert(V &&
"Failed to get select true/false value");
7450bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7474 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7475 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7476 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7477 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7483bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7485 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7486 "Expected a funnel shift");
7510 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7511 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7512 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7520bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7532 It !=
SI->getParent()->
end(); ++It) {
7534 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7541 SelectInst *LastSI = ASI.
back();
7544 CurInstIterator = std::next(LastSI->
getIterator());
7548 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7549 fixupDbgVariableRecordsOnInst(*SI);
7551 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7554 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7557 TargetLowering::SelectSupportKind SelectKind;
7558 if (
SI->getType()->isVectorTy())
7559 SelectKind = TargetLowering::ScalarCondVectorVal;
7561 SelectKind = TargetLowering::ScalarValSelect;
7602 for (SelectInst *SI : ASI) {
7614 SplitPt.setHeadBit(
true);
7617 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7622 BranchInst *TrueBranch =
nullptr;
7623 BranchInst *FalseBranch =
nullptr;
7624 if (TrueInstrs.
size() == 0) {
7626 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7629 }
else if (FalseInstrs.
size() == 0) {
7631 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7638 nullptr,
nullptr, LI);
7646 EndBlock->
setName(
"select.end");
7648 TrueBlock->
setName(
"select.true.sink");
7650 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7651 :
"select.false.sink");
7655 FreshBBs.
insert(TrueBlock);
7657 FreshBBs.
insert(FalseBlock);
7658 FreshBBs.
insert(EndBlock);
7661 BFI->setBlockFreq(EndBlock,
BFI->getBlockFreq(StartBlock));
7663 static const unsigned MD[] = {
7664 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7665 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7670 for (Instruction *
I : TrueInstrs)
7672 for (Instruction *
I : FalseInstrs)
7679 if (TrueBlock ==
nullptr)
7680 TrueBlock = StartBlock;
7681 else if (FalseBlock ==
nullptr)
7682 FalseBlock = StartBlock;
7698 SI->eraseFromParent();
7700 ++NumSelectsExpanded;
7704 CurInstIterator = StartBlock->
end();
7711bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7723 "Expected a type of the same size!");
7729 Builder.SetInsertPoint(SVI);
7730 Value *BC1 = Builder.CreateBitCast(
7732 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7733 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7737 SVI, TLInfo,
nullptr,
7738 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7745 !
Op->isTerminator() && !
Op->isEHPad())
7751bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7766 DenseMap<const Instruction *, unsigned long> InstOrdering;
7767 unsigned long InstNumber = 0;
7768 for (
const auto &
I : *TargetBB)
7769 InstOrdering[&
I] = InstNumber++;
7771 for (Use *U :
reverse(OpsToSink)) {
7776 if (InstOrdering[UI] < InstOrdering[InsertPoint])
7783 SetVector<Instruction *> MaybeDead;
7784 DenseMap<Instruction *, Instruction *> NewInstructions;
7785 for (Use *U : ToReplace) {
7794 FreshBBs.
insert(OpDef->getParent());
7797 NewInstructions[UI] = NI;
7802 InsertedInsts.insert(NI);
7808 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
7809 It->second->setOperand(
U->getOperandNo(), NI);
7816 for (
auto *
I : MaybeDead) {
7817 if (!
I->hasNUsesOrMore(1)) {
7819 I->eraseFromParent();
7826bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
7843 auto *NewType = Type::getIntNTy(
Context, RegWidth);
7852 ExtType = Instruction::SExt;
7855 if (Arg->hasSExtAttr())
7856 ExtType = Instruction::SExt;
7857 if (Arg->hasZExtAttr())
7858 ExtType = Instruction::ZExt;
7864 SI->setCondition(ExtInst);
7865 for (
auto Case :
SI->cases()) {
7866 const APInt &NarrowConst = Case.getCaseValue()->getValue();
7867 APInt WideConst = (ExtType == Instruction::ZExt)
7868 ? NarrowConst.
zext(RegWidth)
7869 : NarrowConst.
sext(RegWidth);
7870 Case.setValue(ConstantInt::get(
Context, WideConst));
7876bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
7883 Value *Condition =
SI->getCondition();
7892 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
7893 ConstantInt *CaseValue = Case.getCaseValue();
7894 BasicBlock *CaseBB = Case.getCaseSuccessor();
7897 bool CheckedForSinglePred =
false;
7898 for (PHINode &
PHI : CaseBB->
phis()) {
7899 Type *PHIType =
PHI.getType();
7907 if (PHIType == ConditionType || TryZExt) {
7909 bool SkipCase =
false;
7910 Value *Replacement =
nullptr;
7911 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
7912 Value *PHIValue =
PHI.getIncomingValue(
I);
7913 if (PHIValue != CaseValue) {
7922 if (
PHI.getIncomingBlock(
I) != SwitchBB)
7927 if (!CheckedForSinglePred) {
7928 CheckedForSinglePred =
true;
7929 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
7935 if (Replacement ==
nullptr) {
7936 if (PHIValue == CaseValue) {
7937 Replacement = Condition;
7940 Replacement = Builder.CreateZExt(Condition, PHIType);
7943 PHI.setIncomingValue(
I, Replacement);
7954bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
7955 bool Changed = optimizeSwitchType(SI);
7956 Changed |= optimizeSwitchPhiConstants(SI);
7977class VectorPromoteHelper {
7979 const DataLayout &
DL;
7982 const TargetLowering &TLI;
7985 const TargetTransformInfo &
TTI;
7991 SmallVector<Instruction *, 4> InstsToBePromoted;
7994 unsigned StoreExtractCombineCost;
8003 if (InstsToBePromoted.
empty())
8005 return InstsToBePromoted.
back();
8011 unsigned getTransitionOriginalValueIdx()
const {
8013 "Other kind of transitions are not supported yet");
8020 unsigned getTransitionIdx()
const {
8022 "Other kind of transitions are not supported yet");
8030 Type *getTransitionType()
const {
8041 void promoteImpl(Instruction *ToBePromoted);
8045 bool isProfitableToPromote() {
8046 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8050 Type *PromotedType = getTransitionType();
8053 unsigned AS =
ST->getPointerAddressSpace();
8071 for (
const auto &Inst : InstsToBePromoted) {
8079 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8091 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8092 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8093 return ScalarCost > VectorCost;
8105 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8120 if (!
EC.isScalable()) {
8123 for (
unsigned Idx = 0; Idx !=
EC.getKnownMinValue(); ++Idx) {
8124 if (Idx == ExtractIdx)
8132 "Generate scalable vector for non-splat is unimplemented");
8137 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8138 unsigned OperandIdx) {
8141 if (OperandIdx != 1)
8143 switch (
Use->getOpcode()) {
8146 case Instruction::SDiv:
8147 case Instruction::UDiv:
8148 case Instruction::SRem:
8149 case Instruction::URem:
8151 case Instruction::FDiv:
8152 case Instruction::FRem:
8153 return !
Use->hasNoNaNs();
8159 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8160 const TargetTransformInfo &
TTI, Instruction *Transition,
8161 unsigned CombineCost)
8162 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8163 StoreExtractCombineCost(CombineCost) {
8164 assert(Transition &&
"Do not know how to promote null");
8168 bool canPromote(
const Instruction *ToBePromoted)
const {
8175 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8178 for (
const Use &U : ToBePromoted->
operands()) {
8179 const Value *Val =
U.get();
8180 if (Val == getEndOfTransition()) {
8184 if (canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()))
8207 void enqueueForPromotion(Instruction *ToBePromoted) {
8208 InstsToBePromoted.push_back(ToBePromoted);
8212 void recordCombineInstruction(Instruction *ToBeCombined) {
8214 CombineInst = ToBeCombined;
8224 if (InstsToBePromoted.empty() || !CombineInst)
8232 for (
auto &ToBePromoted : InstsToBePromoted)
8233 promoteImpl(ToBePromoted);
8234 InstsToBePromoted.clear();
8241void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8251 "The type of the result of the transition does not match "
8256 Type *TransitionTy = getTransitionType();
8261 for (Use &U : ToBePromoted->
operands()) {
8263 Value *NewVal =
nullptr;
8264 if (Val == Transition)
8265 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8272 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8276 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8279 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8285bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8286 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8301 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8302 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost);
8309 if (ToBePromoted->
getParent() != Parent) {
8310 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8312 <<
") than the transition (" << Parent->
getName()
8317 if (VPH.canCombine(ToBePromoted)) {
8319 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8320 VPH.recordCombineInstruction(ToBePromoted);
8322 NumStoreExtractExposed +=
Changed;
8327 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8330 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8332 VPH.enqueueForPromotion(ToBePromoted);
8333 Inst = ToBePromoted;
8373 Type *StoreType =
SI.getValueOperand()->getType();
8382 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8383 DL.getTypeSizeInBits(StoreType) == 0)
8386 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8388 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8392 if (
SI.isVolatile())
8404 if (!
match(
SI.getValueOperand(),
8411 if (!
LValue->getType()->isIntegerTy() ||
8412 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8414 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8430 Builder.SetInsertPoint(&
SI);
8434 if (LBC && LBC->getParent() !=
SI.getParent())
8435 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8436 if (HBC && HBC->getParent() !=
SI.getParent())
8437 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8439 bool IsLE =
SI.getDataLayout().isLittleEndian();
8440 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8441 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8442 Value *Addr =
SI.getPointerOperand();
8443 Align Alignment =
SI.getAlign();
8444 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8445 if (IsOffsetStore) {
8446 Addr = Builder.CreateGEP(
8447 SplitStoreType, Addr,
8455 Builder.CreateAlignedStore(V, Addr, Alignment);
8458 CreateSplitStore(
LValue,
false);
8459 CreateSplitStore(HValue,
true);
8462 SI.eraseFromParent();
8470 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8552 if (GEPIOpI->getParent() != SrcBlock)
8557 if (auto *I = dyn_cast<Instruction>(Usr)) {
8558 if (I->getParent() != SrcBlock) {
8566 std::vector<GetElementPtrInst *> UGEPIs;
8569 for (User *Usr : GEPIOp->
users()) {
8588 if (UGEPI->getOperand(0) != GEPIOp)
8590 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8592 if (GEPIIdx->getType() !=
8600 UGEPIs.push_back(UGEPI);
8602 if (UGEPIs.size() == 0)
8605 for (GetElementPtrInst *UGEPI : UGEPIs) {
8607 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8614 for (GetElementPtrInst *UGEPI : UGEPIs) {
8615 UGEPI->setOperand(0, GEPI);
8617 Constant *NewUGEPIIdx = ConstantInt::get(
8618 GEPIIdx->getType(), UGEPIIdx->
getValue() - GEPIIdx->getValue());
8619 UGEPI->setOperand(1, NewUGEPIIdx);
8622 if (!GEPI->isInBounds()) {
8623 UGEPI->setIsInBounds(
false);
8630 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8632 "GEPIOp is used outside SrcBlock");
8656 Value *
X = Cmp->getOperand(0);
8657 if (!
X->hasUseList())
8662 for (
auto *U :
X->users()) {
8666 (UI->
getParent() != Branch->getParent() &&
8667 UI->
getParent() != Branch->getSuccessor(0) &&
8668 UI->
getParent() != Branch->getSuccessor(1)) ||
8669 (UI->
getParent() != Branch->getParent() &&
8670 !UI->
getParent()->getSinglePredecessor()))
8676 if (UI->
getParent() != Branch->getParent())
8680 ConstantInt::get(UI->
getType(), 0));
8682 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8686 if (Cmp->isEquality() &&
8691 if (UI->
getParent() != Branch->getParent())
8694 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8695 ConstantInt::get(UI->
getType(), 0));
8697 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8705bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8706 bool AnyChange =
false;
8707 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8711 if (InsertedInsts.count(
I))
8720 LargeOffsetGEPMap.erase(
P);
8722 P->eraseFromParent();
8745 I, LI->getLoopFor(
I->getParent()), *
TTI))
8753 TargetLowering::TypeExpandInteger) {
8757 I, LI->getLoopFor(
I->getParent()), *
TTI))
8760 bool MadeChange = optimizeExt(
I);
8761 return MadeChange | optimizeExtUses(
I);
8768 if (optimizeCmp(Cmp, ModifiedDT))
8772 if (optimizeURem(
I))
8776 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8777 bool Modified = optimizeLoadExt(LI);
8786 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8787 unsigned AS =
SI->getPointerAddressSpace();
8788 return optimizeMemoryInst(
I,
SI->getOperand(1),
8789 SI->getOperand(0)->getType(), AS);
8793 unsigned AS = RMW->getPointerAddressSpace();
8794 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
8798 unsigned AS = CmpX->getPointerAddressSpace();
8799 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
8800 CmpX->getCompareOperand()->getType(), AS);
8810 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
8811 BinOp->
getOpcode() == Instruction::LShr)) {
8819 if (GEPI->hasAllZeroIndices()) {
8821 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
8822 GEPI->getName(), GEPI->getIterator());
8823 NC->setDebugLoc(GEPI->getDebugLoc());
8826 GEPI, TLInfo,
nullptr,
8827 [&](
Value *V) { removeAllAssertingVHReferences(V); });
8829 optimizeInst(
NC, ModifiedDT);
8852 if (Const0 || Const1) {
8853 if (!Const0 || !Const1) {
8854 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
8859 FI->eraseFromParent();
8866 if (tryToSinkFreeOperands(
I))
8869 switch (
I->getOpcode()) {
8870 case Instruction::Shl:
8871 case Instruction::LShr:
8872 case Instruction::AShr:
8874 case Instruction::Call:
8876 case Instruction::Select:
8878 case Instruction::ShuffleVector:
8880 case Instruction::Switch:
8882 case Instruction::ExtractElement:
8884 case Instruction::Br:
8893bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
8894 if (!
I.getType()->isIntegerTy() ||
8899 SmallVector<Instruction *, 4> Insts;
8905 &
I, TLInfo,
nullptr,
8906 [&](
Value *V) { removeAllAssertingVHReferences(V); });
8913bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
8915 bool MadeChange =
false;
8918 CurInstIterator = BB.
begin();
8919 ModifiedDT = ModifyDT::NotModifyDT;
8920 while (CurInstIterator != BB.
end()) {
8921 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
8922 if (ModifiedDT != ModifyDT::NotModifyDT) {
8935 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
8937 bool MadeBitReverse =
true;
8938 while (MadeBitReverse) {
8939 MadeBitReverse =
false;
8941 if (makeBitReverse(
I)) {
8942 MadeBitReverse = MadeChange =
true;
8947 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
8952bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
8953 bool AnyChange =
false;
8954 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
8955 AnyChange |= fixupDbgVariableRecord(DVR);
8961bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
8962 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
8963 DVR.
Type != DbgVariableRecord::LocationType::Assign)
8967 bool AnyChange =
false;
8968 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
8970 for (
Value *Location : LocationOps) {
8971 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9000bool CodeGenPrepare::placeDbgValues(Function &
F) {
9001 bool MadeChange =
false;
9002 DominatorTree DT(
F);
9004 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9005 SmallVector<Instruction *, 4> VIs;
9006 for (
Value *V : DbgItem->location_ops())
9014 for (Instruction *VI : VIs) {
9015 if (
VI->isTerminator())
9020 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9031 if (VIs.size() > 1) {
9034 <<
"Unable to find valid location for Debug Value, undefing:\n"
9036 DbgItem->setKillLocation();
9041 << *DbgItem <<
' ' << *VI);
9048 for (BasicBlock &BB :
F) {
9054 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9056 DbgProcessor(&DVR, &Insn);
9067bool CodeGenPrepare::placePseudoProbes(Function &
F) {
9068 bool MadeChange =
false;
9071 auto FirstInst =
Block.getFirstInsertionPt();
9072 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9076 while (
I !=
Block.end()) {
9078 II->moveBefore(FirstInst);
9088 uint64_t NewMax = (NewTrue > NewFalse) ? NewTrue : NewFalse;
9089 uint32_t Scale = (NewMax / std::numeric_limits<uint32_t>::max()) + 1;
9090 NewTrue = NewTrue / Scale;
9091 NewFalse = NewFalse / Scale;
9116bool CodeGenPrepare::splitBranchCondition(Function &
F, ModifyDT &ModifiedDT) {
9120 bool MadeChange =
false;
9121 for (
auto &BB :
F) {
9134 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9142 Value *Cond1, *Cond2;
9145 Opc = Instruction::And;
9148 Opc = Instruction::Or;
9158 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9172 Br1->setCondition(Cond1);
9177 if (
Opc == Instruction::And)
9178 Br1->setSuccessor(0, TmpBB);
9180 Br1->setSuccessor(1, TmpBB);
9185 I->removeFromParent();
9186 I->insertBefore(Br2->getIterator());
9198 if (
Opc == Instruction::Or)
9205 for (PHINode &PN : FBB->
phis()) {
9212 if (
Opc == Instruction::Or) {
9232 uint64_t TrueWeight, FalseWeight;
9234 uint64_t NewTrueWeight = TrueWeight;
9235 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9237 Br1->setMetadata(LLVMContext::MD_prof,
9238 MDBuilder(Br1->getContext())
9239 .createBranchWeights(TrueWeight, FalseWeight,
9242 NewTrueWeight = TrueWeight;
9243 NewFalseWeight = 2 * FalseWeight;
9245 Br2->setMetadata(LLVMContext::MD_prof,
9246 MDBuilder(Br2->getContext())
9247 .createBranchWeights(TrueWeight, FalseWeight));
9268 uint64_t TrueWeight, FalseWeight;
9270 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9271 uint64_t NewFalseWeight = FalseWeight;
9273 Br1->setMetadata(LLVMContext::MD_prof,
9274 MDBuilder(Br1->getContext())
9275 .createBranchWeights(TrueWeight, FalseWeight));
9277 NewTrueWeight = 2 * TrueWeight;
9278 NewFalseWeight = FalseWeight;
9280 Br2->setMetadata(LLVMContext::MD_prof,
9281 MDBuilder(Br2->getContext())
9282 .createBranchWeights(TrueWeight, FalseWeight));
9286 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 bool sinkCmpExpression(CmpInst *Cmp, const TargetLowering &TLI)
Sink the given CmpInst into user blocks to reduce the number of virtual registers that must be create...
static void scaleWeights(uint64_t &NewTrue, uint64_t &NewFalse)
Scale down both weights to fit into uint32_t.
static cl::opt< bool > ProfileUnknownInSpecialSection("profile-unknown-in-special-section", cl::Hidden, cl::desc("In profiling mode like sampleFDO, if a function doesn't have " "profile, we cannot tell the function is cold for sure because " "it may be a function newly added without ever being sampled. " "With the flag enabled, compiler can put such profile unknown " "functions into a special section, so runtime system can choose " "to handle it in a different way than .text section, to save " "RAM for example. "))
static bool OptimizeExtractBits(BinaryOperator *ShiftI, ConstantInt *CI, const TargetLowering &TLI, const DataLayout &DL)
Sink the shift right instruction into user blocks if the uses could potentially be combined with this...
static cl::opt< bool > DisableExtLdPromotion("disable-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), cl::desc("Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in " "CodeGenPrepare"))
static cl::opt< bool > DisablePreheaderProtect("disable-preheader-prot", cl::Hidden, cl::init(false), cl::desc("Disable protection against removing loop preheaders"))
static cl::opt< bool > AddrSinkCombineBaseOffs("addr-sink-combine-base-offs", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseOffs field in Address sinking."))
static bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI, const DataLayout &DL)
If the specified cast instruction is a noop copy (e.g.
static bool splitMergedValStore(StoreInst &SI, const DataLayout &DL, const TargetLowering &TLI)
For the instruction sequence of store below, F and I values are bundled together as an i64 value befo...
static bool SinkCast(CastInst *CI)
Sink the specified cast instruction into its user blocks.
static bool swapICmpOperandsToExposeCSEOpportunities(CmpInst *Cmp)
Many architectures use the same instruction for both subtract and cmp.
static cl::opt< bool > AddrSinkCombineBaseReg("addr-sink-combine-base-reg", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseReg field in Address sinking."))
static bool FindAllMemoryUses(Instruction *I, SmallVectorImpl< std::pair< Use *, Type * > > &MemoryUses, SmallPtrSetImpl< Instruction * > &ConsideredInsts, const TargetLowering &TLI, const TargetRegisterInfo &TRI, bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI, unsigned &SeenInsts)
Recursively walk all the uses of I until we find a memory use.
static cl::opt< bool > StressStoreExtract("stress-cgp-store-extract", cl::Hidden, cl::init(false), cl::desc("Stress test store(extract) optimizations in CodeGenPrepare"))
static bool isFormingBranchFromSelectProfitable(const TargetTransformInfo *TTI, const TargetLowering *TLI, SelectInst *SI)
Returns true if a SelectInst should be turned into an explicit branch.
static std::optional< std::pair< Instruction *, Constant * > > getIVIncrement(const PHINode *PN, const LoopInfo *LI)
If given PN is an inductive variable with value IVInc coming from the backedge, and on each iteration...
static cl::opt< bool > AddrSinkCombineBaseGV("addr-sink-combine-base-gv", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseGV field in Address sinking."))
static cl::opt< bool > AddrSinkUsingGEPs("addr-sink-using-gep", cl::Hidden, cl::init(true), cl::desc("Address sinking in CGP using GEPs."))
static Value * getTrueOrFalseValue(SelectInst *SI, bool isTrue, const SmallPtrSet< const Instruction *, 2 > &Selects)
If isTrue is true, return the true value of SI, otherwise return false value of SI.
static cl::opt< bool > DisableBranchOpts("disable-cgp-branch-opts", cl::Hidden, cl::init(false), cl::desc("Disable branch optimizations in CodeGenPrepare"))
static cl::opt< bool > EnableTypePromotionMerge("cgp-type-promotion-merge", cl::Hidden, cl::desc("Enable merging of redundant sexts when one is dominating" " the other."), cl::init(true))
static cl::opt< bool > ProfileGuidedSectionPrefix("profile-guided-section-prefix", cl::Hidden, cl::init(true), cl::desc("Use profile info to add section prefix for hot/cold functions"))
static cl::opt< unsigned > HugeFuncThresholdInCGPP("cgpp-huge-func", cl::init(10000), cl::Hidden, cl::desc("Least BB number of huge function."))
static cl::opt< bool > AddrSinkNewSelects("addr-sink-new-select", cl::Hidden, cl::init(true), cl::desc("Allow creation of selects in Address sinking."))
static bool foldURemOfLoopIncrement(Instruction *Rem, const DataLayout *DL, const LoopInfo *LI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
static bool optimizeBranch(BranchInst *Branch, const TargetLowering &TLI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
static bool tryUnmergingGEPsAcrossIndirectBr(GetElementPtrInst *GEPI, const TargetTransformInfo *TTI)
static bool IsOperandAMemoryOperand(CallInst *CI, InlineAsm *IA, Value *OpVal, const TargetLowering &TLI, const TargetRegisterInfo &TRI)
Check to see if all uses of OpVal by the specified inline asm call are due to memory operands.
static bool isIntrinsicOrLFToBeTailCalled(const TargetLibraryInfo *TLInfo, const CallInst *CI)
static void replaceAllUsesWith(Value *Old, Value *New, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
Replace all old uses with new ones, and push the updated BBs into FreshBBs.
static cl::opt< bool > ForceSplitStore("force-split-store", cl::Hidden, cl::init(false), cl::desc("Force store splitting no matter what the target query says."))
static void computeBaseDerivedRelocateMap(const SmallVectorImpl< GCRelocateInst * > &AllRelocateCalls, MapVector< GCRelocateInst *, SmallVector< GCRelocateInst *, 0 > > &RelocateInstMap)
static bool simplifyRelocatesOffABase(GCRelocateInst *RelocatedBase, const SmallVectorImpl< GCRelocateInst * > &Targets)
static cl::opt< bool > AddrSinkCombineScaledReg("addr-sink-combine-scaled-reg", cl::Hidden, cl::init(true), cl::desc("Allow combining of ScaledReg field in Address sinking."))
static bool foldICmpWithDominatingICmp(CmpInst *Cmp, const TargetLowering &TLI)
For pattern like:
static bool MightBeFoldableInst(Instruction *I)
This is a little filter, which returns true if an addressing computation involving I might be folded ...
static bool matchIncrement(const Instruction *IVInc, Instruction *&LHS, Constant *&Step)
static cl::opt< bool > EnableGEPOffsetSplit("cgp-split-large-offset-gep", cl::Hidden, cl::init(true), cl::desc("Enable splitting large offset of GEP."))
static cl::opt< bool > DisableComplexAddrModes("disable-complex-addr-modes", cl::Hidden, cl::init(false), cl::desc("Disables combining addressing modes with different parts " "in optimizeMemoryInst."))
static cl::opt< bool > EnableICMP_EQToICMP_ST("cgp-icmp-eq2icmp-st", cl::Hidden, cl::init(false), cl::desc("Enable ICMP_EQ to ICMP_S(L|G)T conversion."))
static cl::opt< bool > VerifyBFIUpdates("cgp-verify-bfi-updates", cl::Hidden, cl::init(false), cl::desc("Enable BFI update verification for " "CodeGenPrepare."))
static cl::opt< bool > BBSectionsGuidedSectionPrefix("bbsections-guided-section-prefix", cl::Hidden, cl::init(true), cl::desc("Use the basic-block-sections profile to determine the text " "section prefix for hot functions. Functions with " "basic-block-sections profile will be placed in `.text.hot` " "regardless of their FDO profile info. Other functions won't be " "impacted, i.e., their prefixes will be decided by FDO/sampleFDO " "profiles."))
static bool isRemOfLoopIncrementWithLoopInvariant(Instruction *Rem, const LoopInfo *LI, Value *&RemAmtOut, Value *&AddInstOut, Value *&AddOffsetOut, PHINode *&LoopIncrPNOut)
static bool isIVIncrement(const Value *V, const LoopInfo *LI)
static cl::opt< bool > DisableGCOpts("disable-cgp-gc-opts", cl::Hidden, cl::init(false), cl::desc("Disable GC optimizations in CodeGenPrepare"))
static bool GEPSequentialConstIndexed(GetElementPtrInst *GEP)
static void DbgInserterHelper(DbgVariableRecord *DVR, BasicBlock::iterator VI)
static bool isPromotedInstructionLegal(const TargetLowering &TLI, const DataLayout &DL, Value *Val)
Check whether or not Val is a legal instruction for TLI.
static cl::opt< uint64_t > FreqRatioToSkipMerge("cgp-freq-ratio-to-skip-merge", cl::Hidden, cl::init(2), cl::desc("Skip merging empty blocks if (frequency of empty block) / " "(frequency of destination block) is greater than this ratio"))
static BasicBlock::iterator findInsertPos(Value *Addr, Instruction *MemoryInst, Value *SunkAddr)
static bool IsNonLocalValue(Value *V, BasicBlock *BB)
Return true if the specified values are defined in a different basic block than BB.
static cl::opt< bool > EnableAndCmpSinking("enable-andcmp-sinking", cl::Hidden, cl::init(true), cl::desc("Enable sinking and/cmp into branches."))
static bool hasSameExtUse(Value *Val, const TargetLowering &TLI)
Check if all the uses of Val are equivalent (or free) zero or sign extensions.
static bool despeculateCountZeros(IntrinsicInst *CountZeros, LoopInfo &LI, const TargetLowering *TLI, const DataLayout *DL, ModifyDT &ModifiedDT, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
If counting leading or trailing zeros is an expensive operation and a zero input is defined,...
static cl::opt< bool > StressExtLdPromotion("stress-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), cl::desc("Stress test ext(promotable(ld)) -> promoted(ext(ld)) " "optimization in CodeGenPrepare"))
static bool matchUAddWithOverflowConstantEdgeCases(CmpInst *Cmp, BinaryOperator *&Add)
Match special-case patterns that check for unsigned add overflow.
static cl::opt< bool > DisableSelectToBranch("disable-cgp-select2branch", cl::Hidden, cl::init(false), cl::desc("Disable select to branch conversion."))
static cl::opt< bool > DisableDeletePHIs("disable-cgp-delete-phis", cl::Hidden, cl::init(false), cl::desc("Disable elimination of dead PHI nodes."))
static cl::opt< bool > AddrSinkNewPhis("addr-sink-new-phis", cl::Hidden, cl::init(false), cl::desc("Allow creation of Phis in Address sinking."))
Defines an IR pass for CodeGen Prepare.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
#define LLVM_ATTRIBUTE_UNUSED
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
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 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...
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.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
LLVM_ABI void removeFromParent()
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LocationType Type
Classification of the debug-info record that this DbgVariableRecord represents.
LLVM_ABI void replaceVariableLocationOp(Value *OldValue, Value *NewValue, bool AllowEmpty=false)
LLVM_ABI iterator_range< location_op_iterator > location_ops() const
Get the locations corresponding to the variable referenced by the debug info intrinsic.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
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, Instruction *MDFrom=nullptr)
void clear()
Completely clear the SetVector.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
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:
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.
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 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.
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
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.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap, true > m_c_NUWAdd(const LHS &L, const RHS &R)
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
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.
apint_match m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
UAddWithOverflow_match< LHS_t, RHS_t, Sum_t > m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S)
Match an icmp instruction checking for unsigned overflow on addition.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
auto m_Undef()
Match an arbitrary undef constant.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale)
Compare two scaled numbers.
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ Assume
Do not drop type tests (default).
@ 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
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)
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.
@ 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.
int popcount(T Value) noexcept
Count the number of set bits in a value.
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.