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)))
1755 if (
Sub->getParent() !=
Cmp->getParent() && !
Sub->hasOneUse())
1758 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1759 Cmp, Intrinsic::usub_with_overflow))
1763 ModifiedDT = ModifyDT::ModifyInstDT;
1770bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1784 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1790 Type *OpTy =
X->getType();
1798 if (Pred == ICmpInst::ICMP_EQ) {
1799 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1800 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1802 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1808 if (IsPowerOf2OrZeroTest ||
1819 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1828 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1831 Cmp->replaceAllUsesWith(NewCmp);
1853 bool MadeChange =
false;
1856 Use &TheUse = UI.getUse();
1871 if (UserBB == DefBB)
1875 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1881 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1888 TheUse = InsertedCmp;
1894 if (Cmp->use_empty()) {
1895 Cmp->eraseFromParent();
1932 for (
User *U : Cmp->users()) {
1954 if (CmpBB != FalseBB)
1957 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
1971 for (
User *U : Cmp->users()) {
1980 SI->swapProfMetadata();
1992 Value *Op0 = Cmp->getOperand(0);
1993 Value *Op1 = Cmp->getOperand(1);
2002 unsigned NumInspected = 0;
2005 if (++NumInspected > 128)
2013 if (GoodToSwap > 0) {
2014 Cmp->swapOperands();
2034 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
2037 auto [ClassVal, ClassTest] =
2043 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2047 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
2048 Cmp->replaceAllUsesWith(IsFPClass);
2056 Value *Incr, *RemAmt;
2061 Value *AddInst, *AddOffset;
2064 if (PN !=
nullptr) {
2066 AddOffset =
nullptr;
2075 if (PN !=
nullptr) {
2088 if (PN->getNumIncomingValues() != 2)
2093 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2097 if (!L->contains(Rem))
2101 if (!L->isLoopInvariant(RemAmt))
2105 if (AddOffset && !L->isLoopInvariant(AddOffset))
2126 AddInstOut = AddInst;
2127 AddOffsetOut = AddOffset;
2146 Value *AddOffset, *RemAmt, *AddInst;
2149 AddOffset, LoopIncrPN))
2174 assert(AddOffset &&
"We found an add but missing values");
2193 Builder.SetInsertPoint(LoopIncrPN);
2194 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2199 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2204 NewRem->
addIncoming(Start, L->getLoopPreheader());
2209 FreshBBs.
insert(L->getLoopLatch());
2220bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2226bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2230 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2233 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2236 if (unfoldPowerOf2Test(Cmp))
2257 SetOfInstrs &InsertedInsts) {
2260 assert(!InsertedInsts.count(AndI) &&
2261 "Attempting to optimize already optimized and instruction");
2262 (void)InsertedInsts;
2276 for (
auto *U : AndI->
users()) {
2284 if (!CmpC || !CmpC->
isZero())
2299 Use &TheUse = UI.getUse();
2317 TheUse = InsertedAnd;
2334 if (
User->getOpcode() != Instruction::And ||
2340 if ((Cimm & (Cimm + 1)).getBoolValue())
2354 bool MadeChange =
false;
2357 TruncE = TruncI->user_end();
2358 TruncUI != TruncE;) {
2360 Use &TruncTheUse = TruncUI.getUse();
2385 if (UserBB == TruncUserBB)
2389 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2391 if (!InsertedShift && !InsertedTrunc) {
2395 if (ShiftI->
getOpcode() == Instruction::AShr)
2397 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2400 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2408 TruncInsertPt.setHeadBit(
true);
2409 assert(TruncInsertPt != TruncUserBB->
end());
2413 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2414 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2418 TruncTheUse = InsertedTrunc;
2451 bool MadeChange =
false;
2454 Use &TheUse = UI.getUse();
2468 if (UserBB == DefBB) {
2496 if (!InsertedShift) {
2500 if (ShiftI->
getOpcode() == Instruction::AShr)
2502 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2505 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2513 TheUse = InsertedShift;
2560 unsigned SizeInBits = Ty->getScalarSizeInBits();
2561 if (Ty->isVectorTy())
2573 FreshBBs.
insert(CallBlock);
2580 SplitPt.setHeadBit(
true);
2583 FreshBBs.
insert(EndBlock);
2588 L->addBasicBlockToLoop(CallBlock, LI);
2589 L->addBasicBlockToLoop(EndBlock, LI);
2595 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2602 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2603 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2604 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2609 Builder.SetInsertPoint(EndBlock, EndBlock->
begin());
2610 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2620 ModifiedDT = ModifyDT::ModifyBBDT;
2624bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2628 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2636 for (
auto &Arg : CI->
args()) {
2641 if (!Arg->getType()->isPointerTy())
2643 APInt
Offset(
DL->getIndexSizeInBits(
2646 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2647 uint64_t Offset2 =
Offset.getLimitedValue();
2669 MaybeAlign MIDestAlign =
MI->getDestAlign();
2670 if (!MIDestAlign || DestAlign > *MIDestAlign)
2671 MI->setDestAlignment(DestAlign);
2673 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2675 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2676 MTI->setSourceAlignment(SrcAlign);
2686 for (
auto &Arg : CI->
args()) {
2687 if (!Arg->getType()->isPointerTy())
2689 unsigned AS = Arg->getType()->getPointerAddressSpace();
2690 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2696 switch (
II->getIntrinsicID()) {
2699 case Intrinsic::assume:
2701 case Intrinsic::allow_runtime_check:
2702 case Intrinsic::allow_ubsan_check:
2703 case Intrinsic::experimental_widenable_condition: {
2707 if (
II->use_empty()) {
2708 II->eraseFromParent();
2712 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2717 case Intrinsic::objectsize:
2719 case Intrinsic::is_constant:
2721 case Intrinsic::aarch64_stlxr:
2722 case Intrinsic::aarch64_stxr: {
2731 InsertedInsts.insert(ExtVal);
2735 case Intrinsic::launder_invariant_group:
2736 case Intrinsic::strip_invariant_group: {
2737 Value *ArgVal =
II->getArgOperand(0);
2738 auto it = LargeOffsetGEPMap.
find(
II);
2739 if (it != LargeOffsetGEPMap.
end()) {
2743 auto GEPs = std::move(it->second);
2744 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2749 II->eraseFromParent();
2752 case Intrinsic::cttz:
2753 case Intrinsic::ctlz:
2757 case Intrinsic::fshl:
2758 case Intrinsic::fshr:
2759 return optimizeFunnelShift(
II);
2760 case Intrinsic::masked_gather:
2761 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2762 case Intrinsic::masked_scatter:
2763 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2764 case Intrinsic::masked_load:
2767 if (VT->getNumElements() == 1) {
2768 Value *PtrVal =
II->getArgOperand(0);
2770 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2775 case Intrinsic::masked_store:
2779 if (VT->getNumElements() == 1) {
2780 Value *PtrVal =
II->getArgOperand(1);
2782 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2789 SmallVector<Value *, 2> PtrOps;
2792 while (!PtrOps.
empty()) {
2795 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2809 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2811 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2821 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2822 if (!
F->getReturnType()->isPointerTy())
2825 GlobalVariable *UniformValue =
nullptr;
2826 for (
auto &BB : *
F) {
2831 else if (V != UniformValue)
2839 return UniformValue;
2842 if (
Callee->hasExactDefinition()) {
2843 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2844 bool MadeChange =
false;
2870 switch (
II->getIntrinsicID()) {
2871 case Intrinsic::memset:
2872 case Intrinsic::memcpy:
2873 case Intrinsic::memmove:
2881 if (Callee && TLInfo && TLInfo->
getLibFunc(*Callee, LF))
2883 case LibFunc_strcpy:
2884 case LibFunc_strncpy:
2885 case LibFunc_strcat:
2886 case LibFunc_strncat:
2927bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
2928 ModifyDT &ModifiedDT) {
2936 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2938 PHINode *PN =
nullptr;
2939 ExtractValueInst *EVI =
nullptr;
2940 BitCastInst *BCI =
nullptr;
2960 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
2966 return II->getIntrinsicID() == Intrinsic::lifetime_end;
2972 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
2974 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
2996 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
3046 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
3048 if (!VisitedBBs.
insert(Pred).second)
3050 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
3068 for (
auto const &TailCallBB : TailCallBBs) {
3078 BFI->getBlockFreq(BB) >=
BFI->getBlockFreq(TailCallBB));
3079 BFI->setBlockFreq(BB,
3080 (
BFI->getBlockFreq(BB) -
BFI->getBlockFreq(TailCallBB)));
3081 ModifiedDT = ModifyDT::ModifyBBDT;
3090 for (
auto *CI : CallInsts) {
3091 for (
auto const *FakeUse : FakeUses) {
3092 auto *ClonedInst = FakeUse->clone();
3110struct ExtAddrMode :
public TargetLowering::AddrMode {
3111 Value *BaseReg =
nullptr;
3112 Value *ScaledReg =
nullptr;
3113 Value *OriginalValue =
nullptr;
3114 bool InBounds =
true;
3118 BaseRegField = 0x01,
3120 BaseOffsField = 0x04,
3121 ScaledRegField = 0x08,
3123 MultipleFields = 0xff
3126 ExtAddrMode() =
default;
3128 void print(raw_ostream &OS)
const;
3135 if (ScaledReg == From)
3139 FieldName
compare(
const ExtAddrMode &other) {
3142 if (BaseReg && other.
BaseReg &&
3144 return MultipleFields;
3145 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3146 return MultipleFields;
3149 return MultipleFields;
3152 if (InBounds != other.InBounds)
3153 return MultipleFields;
3156 unsigned Result = NoField;
3159 if (BaseGV != other.BaseGV)
3161 if (BaseOffs != other.BaseOffs)
3164 Result |= ScaledRegField;
3167 if (Scale && other.
Scale && Scale != other.
Scale)
3171 return MultipleFields;
3173 return static_cast<FieldName
>(
Result);
3183 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3194 case ScaledRegField:
3197 return ConstantInt::get(IntPtrTy, BaseOffs);
3201 void SetCombinedField(FieldName
Field,
Value *V,
3202 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3207 case ExtAddrMode::BaseRegField:
3210 case ExtAddrMode::BaseGVField:
3213 assert(BaseReg ==
nullptr);
3217 case ExtAddrMode::ScaledRegField:
3222 for (
const ExtAddrMode &AM : AddrModes)
3228 case ExtAddrMode::BaseOffsField:
3231 assert(ScaledReg ==
nullptr);
3241static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3247#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3248void ExtAddrMode::print(raw_ostream &OS)
const {
3249 bool NeedPlus =
false;
3255 BaseGV->printAsOperand(OS,
false);
3260 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3265 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3266 BaseReg->printAsOperand(OS,
false);
3270 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3293class TypePromotionTransaction {
3297 class TypePromotionAction {
3305 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3307 virtual ~TypePromotionAction() =
default;
3314 virtual void undo() = 0;
3319 virtual void commit() {
3325 class InsertionHandler {
3334 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3337 bool HasPrevInstruction;
3341 InsertionHandler(Instruction *Inst) {
3349 if (HasPrevInstruction) {
3357 void insert(Instruction *Inst) {
3358 if (HasPrevInstruction) {
3370 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3375 class InstructionMoveBefore :
public TypePromotionAction {
3377 InsertionHandler Position;
3382 : TypePromotionAction(Inst), Position(Inst) {
3383 LLVM_DEBUG(
dbgs() <<
"Do: move: " << *Inst <<
"\nbefore: " << *Before
3389 void undo()
override {
3391 Position.insert(Inst);
3396 class OperandSetter :
public TypePromotionAction {
3405 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3406 : TypePromotionAction(Inst), Idx(Idx) {
3408 <<
"for:" << *Inst <<
"\n"
3409 <<
"with:" << *NewVal <<
"\n");
3415 void undo()
override {
3417 <<
"for: " << *Inst <<
"\n"
3418 <<
"with: " << *Origin <<
"\n");
3425 class OperandsHider :
public TypePromotionAction {
3431 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3434 OriginalValues.
reserve(NumOpnds);
3435 for (
unsigned It = 0; It < NumOpnds; ++It) {
3447 void undo()
override {
3449 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3455 class TruncBuilder :
public TypePromotionAction {
3462 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3464 Builder.SetCurrentDebugLocation(
DebugLoc());
3465 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3470 Value *getBuiltValue() {
return Val; }
3473 void undo()
override {
3476 IVal->eraseFromParent();
3481 class SExtBuilder :
public TypePromotionAction {
3488 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3489 : TypePromotionAction(InsertPt) {
3491 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3496 Value *getBuiltValue() {
return Val; }
3499 void undo()
override {
3502 IVal->eraseFromParent();
3507 class ZExtBuilder :
public TypePromotionAction {
3514 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3515 : TypePromotionAction(InsertPt) {
3517 Builder.SetCurrentDebugLocation(
DebugLoc());
3518 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3523 Value *getBuiltValue() {
return Val; }
3526 void undo()
override {
3529 IVal->eraseFromParent();
3534 class TypeMutator :
public TypePromotionAction {
3540 TypeMutator(Instruction *Inst,
Type *NewTy)
3541 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3542 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3548 void undo()
override {
3549 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3556 class UsesReplacer :
public TypePromotionAction {
3558 struct InstructionAndIdx {
3565 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3566 : Inst(Inst), Idx(Idx) {}
3572 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3582 UsesReplacer(Instruction *Inst,
Value *New)
3583 : TypePromotionAction(Inst),
New(
New) {
3584 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3587 for (Use &U : Inst->
uses()) {
3589 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3600 void undo()
override {
3602 for (InstructionAndIdx &Use : OriginalUses)
3603 Use.Inst->setOperand(
Use.Idx, Inst);
3608 for (DbgVariableRecord *DVR : DbgVariableRecords)
3609 DVR->replaceVariableLocationOp(New, Inst);
3614 class InstructionRemover :
public TypePromotionAction {
3616 InsertionHandler Inserter;
3620 OperandsHider Hider;
3623 UsesReplacer *Replacer =
nullptr;
3626 SetOfInstrs &RemovedInsts;
3633 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3634 Value *New =
nullptr)
3635 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3636 RemovedInsts(RemovedInsts) {
3638 Replacer =
new UsesReplacer(Inst, New);
3639 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3640 RemovedInsts.insert(Inst);
3647 ~InstructionRemover()
override {
delete Replacer; }
3649 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3650 InstructionRemover(
const InstructionRemover &other) =
delete;
3654 void undo()
override {
3655 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3656 Inserter.insert(Inst);
3660 RemovedInsts.erase(Inst);
3668 using ConstRestorationPt =
const TypePromotionAction *;
3670 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3671 : RemovedInsts(RemovedInsts) {}
3678 void rollback(ConstRestorationPt Point);
3681 ConstRestorationPt getRestorationPoint()
const;
3686 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3695 void mutateType(Instruction *Inst,
Type *NewTy);
3698 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3711 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3713 SetOfInstrs &RemovedInsts;
3718void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3720 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3721 Inst, Idx, NewVal));
3724void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3727 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3728 Inst, RemovedInsts, NewVal));
3731void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3734 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3737void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3739 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3742Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3743 std::unique_ptr<TruncBuilder>
Ptr(
new TruncBuilder(Opnd, Ty));
3745 Actions.push_back(std::move(
Ptr));
3749Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3751 std::unique_ptr<SExtBuilder>
Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3753 Actions.push_back(std::move(
Ptr));
3757Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3759 std::unique_ptr<ZExtBuilder>
Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3761 Actions.push_back(std::move(
Ptr));
3765TypePromotionTransaction::ConstRestorationPt
3766TypePromotionTransaction::getRestorationPoint()
const {
3767 return !Actions.empty() ? Actions.back().get() :
nullptr;
3770bool TypePromotionTransaction::commit() {
3771 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3778void TypePromotionTransaction::rollback(
3779 TypePromotionTransaction::ConstRestorationPt Point) {
3780 while (!Actions.empty() && Point != Actions.back().get()) {
3781 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3791class AddressingModeMatcher {
3792 SmallVectorImpl<Instruction *> &AddrModeInsts;
3793 const TargetLowering &TLI;
3794 const TargetRegisterInfo &
TRI;
3795 const DataLayout &
DL;
3797 const std::function<
const DominatorTree &()> getDTFn;
3810 const SetOfInstrs &InsertedInsts;
3813 InstrToOrigTy &PromotedInsts;
3816 TypePromotionTransaction &TPT;
3819 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3823 bool IgnoreProfitability;
3826 bool OptSize =
false;
3828 ProfileSummaryInfo *PSI;
3829 BlockFrequencyInfo *
BFI;
3831 AddressingModeMatcher(
3832 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3833 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3834 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3835 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3836 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3837 TypePromotionTransaction &TPT,
3838 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3839 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI)
3840 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3841 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3842 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3843 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3844 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI),
BFI(
BFI) {
3845 IgnoreProfitability =
false;
3857 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3858 SmallVectorImpl<Instruction *> &AddrModeInsts,
3859 const TargetLowering &TLI,
const LoopInfo &LI,
3860 const std::function<
const DominatorTree &()> getDTFn,
3861 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3862 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3863 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3864 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
3867 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3868 AccessTy, AS, MemoryInst, Result,
3869 InsertedInsts, PromotedInsts, TPT,
3870 LargeOffsetGEP, OptSize, PSI, BFI)
3878 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3880 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3881 bool *MovedAway =
nullptr);
3882 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3883 ExtAddrMode &AMBefore,
3884 ExtAddrMode &AMAfter);
3885 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3886 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3887 Value *PromotedOperand)
const;
3893class PhiNodeSetIterator {
3894 PhiNodeSet *
const Set;
3895 size_t CurrentIndex = 0;
3900 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3902 PhiNodeSetIterator &operator++();
3918 friend class PhiNodeSetIterator;
3920 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3921 using iterator = PhiNodeSetIterator;
3936 size_t FirstValidElement = 0;
3942 bool insert(PHINode *
Ptr) {
3954 if (NodeMap.erase(
Ptr)) {
3955 SkipRemovedElements(FirstValidElement);
3965 FirstValidElement = 0;
3971 if (FirstValidElement == 0)
3972 SkipRemovedElements(FirstValidElement);
3973 return PhiNodeSetIterator(
this, FirstValidElement);
3980 size_t size()
const {
return NodeMap.size(); }
3983 size_t count(PHINode *
Ptr)
const {
return NodeMap.count(
Ptr); }
3991 void SkipRemovedElements(
size_t &CurrentIndex) {
3993 auto it = NodeMap.find(NodeList[CurrentIndex]);
3996 if (it != NodeMap.end() && it->second == CurrentIndex)
4003PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
4006PHINode *PhiNodeSetIterator::operator*()
const {
4008 "PhiNodeSet access out of range");
4009 return Set->NodeList[CurrentIndex];
4012PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
4014 "PhiNodeSet access out of range");
4016 Set->SkipRemovedElements(CurrentIndex);
4020bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
4021 return CurrentIndex ==
RHS.CurrentIndex;
4024bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
4025 return !((*this) ==
RHS);
4031class SimplificationTracker {
4032 DenseMap<Value *, Value *> Storage;
4033 const SimplifyQuery &SQ;
4036 PhiNodeSet AllPhiNodes;
4038 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
4041 SimplificationTracker(
const SimplifyQuery &sq) : SQ(sq) {}
4045 auto SV = Storage.
find(V);
4046 if (SV == Storage.
end())
4054 SmallPtrSet<Value *, 32> Visited;
4056 while (!WorkList.
empty()) {
4058 if (!Visited.
insert(
P).second)
4062 for (
auto *U : PI->users())
4065 PI->replaceAllUsesWith(V);
4067 AllPhiNodes.erase(
PHI);
4070 PI->eraseFromParent();
4078 void ReplacePhi(PHINode *From, PHINode *To) {
4079 Value *OldReplacement = Get(From);
4080 while (OldReplacement != From) {
4083 OldReplacement = Get(From);
4085 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
4088 AllPhiNodes.erase(From);
4092 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
4094 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
4096 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
4098 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4100 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4102 void destroyNewNodes(
Type *CommonType) {
4105 for (
auto *
I : AllPhiNodes) {
4106 I->replaceAllUsesWith(Dummy);
4107 I->eraseFromParent();
4109 AllPhiNodes.clear();
4110 for (
auto *
I : AllSelectNodes) {
4111 I->replaceAllUsesWith(Dummy);
4112 I->eraseFromParent();
4114 AllSelectNodes.clear();
4119class AddressingModeCombiner {
4120 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4121 typedef std::pair<PHINode *, PHINode *> PHIPair;
4128 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4131 bool AllAddrModesTrivial =
true;
4134 Type *CommonType =
nullptr;
4137 const SimplifyQuery &SQ;
4143 Value *CommonValue =
nullptr;
4146 AddressingModeCombiner(
const SimplifyQuery &_SQ,
Value *OriginalValue)
4147 : SQ(_SQ), Original(OriginalValue) {}
4149 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4152 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4157 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4161 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4164 if (AddrModes.
empty()) {
4172 ExtAddrMode::FieldName ThisDifferentField =
4173 AddrModes[0].compare(NewAddrMode);
4174 if (DifferentField == ExtAddrMode::NoField)
4175 DifferentField = ThisDifferentField;
4176 else if (DifferentField != ThisDifferentField)
4177 DifferentField = ExtAddrMode::MultipleFields;
4180 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4183 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4188 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4193 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4194 !NewAddrMode.HasBaseReg);
4211 bool combineAddrModes() {
4213 if (AddrModes.
size() == 0)
4217 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4222 if (AllAddrModesTrivial)
4225 if (!addrModeCombiningAllowed())
4231 FoldAddrToValueMapping
Map;
4232 if (!initializeMap(Map))
4235 CommonValue = findCommon(Map);
4237 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4238 return CommonValue !=
nullptr;
4244 void eraseCommonValueIfDead() {
4245 if (CommonValue && CommonValue->
use_empty())
4247 CommonInst->eraseFromParent();
4255 bool initializeMap(FoldAddrToValueMapping &Map) {
4258 SmallVector<Value *, 2> NullValue;
4260 for (
auto &AM : AddrModes) {
4261 Value *DV = AM.GetFieldAsValue(DifferentField, IntPtrTy);
4264 if (CommonType && CommonType !=
Type)
4267 Map[AM.OriginalValue] = DV;
4272 assert(CommonType &&
"At least one non-null value must be!");
4273 for (
auto *V : NullValue)
4301 Value *findCommon(FoldAddrToValueMapping &Map) {
4309 SimplificationTracker
ST(SQ);
4314 InsertPlaceholders(Map, TraverseOrder, ST);
4317 FillPlaceholders(Map, TraverseOrder, ST);
4320 ST.destroyNewNodes(CommonType);
4325 unsigned PhiNotMatchedCount = 0;
4327 ST.destroyNewNodes(CommonType);
4331 auto *
Result =
ST.Get(
Map.find(Original)->second);
4333 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4334 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4341 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4342 SmallSetVector<PHIPair, 8> &Matcher,
4343 PhiNodeSet &PhiNodesToMatch) {
4346 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4349 SmallSet<PHIPair, 8> Visited;
4350 while (!WorkList.
empty()) {
4352 if (!Visited.
insert(Item).second)
4359 for (
auto *
B : Item.first->blocks()) {
4360 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4361 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4362 if (FirstValue == SecondValue)
4372 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4377 if (Matcher.
count({FirstPhi, SecondPhi}))
4382 if (MatchedPHIs.
insert(FirstPhi).second)
4383 Matcher.
insert({FirstPhi, SecondPhi});
4385 WorkList.
push_back({FirstPhi, SecondPhi});
4394 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4395 unsigned &PhiNotMatchedCount) {
4399 SmallSetVector<PHIPair, 8> Matched;
4400 SmallPtrSet<PHINode *, 8> WillNotMatch;
4401 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4402 while (PhiNodesToMatch.size()) {
4403 PHINode *
PHI = *PhiNodesToMatch.begin();
4406 WillNotMatch.
clear();
4410 bool IsMatched =
false;
4411 for (
auto &
P :
PHI->getParent()->phis()) {
4413 if (PhiNodesToMatch.count(&
P))
4415 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4425 for (
auto MV : Matched)
4426 ST.ReplacePhi(MV.first, MV.second);
4431 if (!AllowNewPhiNodes)
4434 PhiNotMatchedCount += WillNotMatch.
size();
4435 for (
auto *
P : WillNotMatch)
4436 PhiNodesToMatch.erase(
P);
4441 void FillPlaceholders(FoldAddrToValueMapping &Map,
4442 SmallVectorImpl<Value *> &TraverseOrder,
4443 SimplificationTracker &ST) {
4444 while (!TraverseOrder.
empty()) {
4446 assert(
Map.contains(Current) &&
"No node to fill!!!");
4452 auto *TrueValue = CurrentSelect->getTrueValue();
4453 assert(
Map.contains(TrueValue) &&
"No True Value!");
4454 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4455 auto *FalseValue = CurrentSelect->getFalseValue();
4456 assert(
Map.contains(FalseValue) &&
"No False Value!");
4457 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4464 assert(
Map.contains(PV) &&
"No predecessor Value!");
4465 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4468 Map[Current] =
ST.Simplify(V);
4477 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4478 SmallVectorImpl<Value *> &TraverseOrder,
4479 SimplificationTracker &ST) {
4482 "Address must be a Phi or Select node");
4485 while (!Worklist.
empty()) {
4488 if (
Map.contains(Current))
4499 CurrentSelect->getName(),
4500 CurrentSelect->getIterator(), CurrentSelect);
4504 Worklist.
push_back(CurrentSelect->getTrueValue());
4505 Worklist.
push_back(CurrentSelect->getFalseValue());
4513 ST.insertNewPhi(
PHI);
4519 bool addrModeCombiningAllowed() {
4522 switch (DifferentField) {
4525 case ExtAddrMode::BaseRegField:
4527 case ExtAddrMode::BaseGVField:
4529 case ExtAddrMode::BaseOffsField:
4531 case ExtAddrMode::ScaledRegField:
4541bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4546 return matchAddr(ScaleReg,
Depth);
4557 ExtAddrMode TestAddrMode =
AddrMode;
4561 TestAddrMode.
Scale += Scale;
4575 ConstantInt *CI =
nullptr;
4576 Value *AddLHS =
nullptr;
4580 TestAddrMode.InBounds =
false;
4597 auto GetConstantStep =
4598 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4601 return std::nullopt;
4604 return std::nullopt;
4612 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4613 return std::nullopt;
4615 return std::make_pair(IVInc->first, ConstantStep->getValue());
4616 return std::nullopt;
4631 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4638 APInt Step = IVStep->second;
4640 if (
Offset.isSignedIntN(64)) {
4641 TestAddrMode.InBounds =
false;
4643 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4648 getDTFn().
dominates(IVInc, MemoryInst)) {
4668 switch (
I->getOpcode()) {
4669 case Instruction::BitCast:
4670 case Instruction::AddrSpaceCast:
4672 if (
I->getType() ==
I->getOperand(0)->getType())
4674 return I->getType()->isIntOrPtrTy();
4675 case Instruction::PtrToInt:
4678 case Instruction::IntToPtr:
4681 case Instruction::Add:
4683 case Instruction::Mul:
4684 case Instruction::Shl:
4687 case Instruction::GetElementPtr:
4715class TypePromotionHelper {
4718 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4719 Instruction *ExtOpnd,
bool IsSExt) {
4720 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4721 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4725 if (It->second.getInt() == ExtTy)
4731 ExtTy = BothExtension;
4733 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4740 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4741 Instruction *Opnd,
bool IsSExt) {
4742 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4743 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4744 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4745 return It->second.getPointer();
4760 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4761 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4765 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4778 static Value *promoteOperandForTruncAndAnyExt(
4779 Instruction *Ext, TypePromotionTransaction &TPT,
4780 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4781 SmallVectorImpl<Instruction *> *Exts,
4782 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4793 static Value *promoteOperandForOther(Instruction *Ext,
4794 TypePromotionTransaction &TPT,
4795 InstrToOrigTy &PromotedInsts,
4796 unsigned &CreatedInstsCost,
4797 SmallVectorImpl<Instruction *> *Exts,
4798 SmallVectorImpl<Instruction *> *Truncs,
4799 const TargetLowering &TLI,
bool IsSExt);
4802 static Value *signExtendOperandForOther(
4803 Instruction *Ext, TypePromotionTransaction &TPT,
4804 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4805 SmallVectorImpl<Instruction *> *Exts,
4806 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4807 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4808 Exts, Truncs, TLI,
true);
4812 static Value *zeroExtendOperandForOther(
4813 Instruction *Ext, TypePromotionTransaction &TPT,
4814 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4815 SmallVectorImpl<Instruction *> *Exts,
4816 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4817 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4818 Exts, Truncs, TLI,
false);
4823 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4824 InstrToOrigTy &PromotedInsts,
4825 unsigned &CreatedInstsCost,
4826 SmallVectorImpl<Instruction *> *Exts,
4827 SmallVectorImpl<Instruction *> *Truncs,
4828 const TargetLowering &TLI);
4839 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4840 const TargetLowering &TLI,
4841 const InstrToOrigTy &PromotedInsts);
4846bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4847 Type *ConsideredExtType,
4848 const InstrToOrigTy &PromotedInsts,
4868 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4869 (IsSExt && BinOp->hasNoSignedWrap())))
4873 if ((Inst->
getOpcode() == Instruction::And ||
4878 if (Inst->
getOpcode() == Instruction::Xor) {
4881 if (!Cst->getValue().isAllOnes())
4890 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4900 if (ExtInst->hasOneUse()) {
4902 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4935 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4948TypePromotionHelper::Action TypePromotionHelper::getAction(
4949 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4950 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
4952 "Unexpected instruction type");
4959 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4972 return promoteOperandForTruncAndAnyExt;
4978 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4981Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4982 Instruction *SExt, TypePromotionTransaction &TPT,
4983 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4984 SmallVectorImpl<Instruction *> *Exts,
4985 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4989 Value *ExtVal = SExt;
4990 bool HasMergedNonFreeExt =
false;
4994 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
4997 TPT.replaceAllUsesWith(SExt, ZExt);
4998 TPT.eraseInstruction(SExt);
5003 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
5005 CreatedInstsCost = 0;
5009 TPT.eraseInstruction(SExtOpnd);
5017 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
5025 TPT.eraseInstruction(ExtInst, NextVal);
5029Value *TypePromotionHelper::promoteOperandForOther(
5030 Instruction *Ext, TypePromotionTransaction &TPT,
5031 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5032 SmallVectorImpl<Instruction *> *Exts,
5033 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
5038 CreatedInstsCost = 0;
5044 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
5047 ITrunc->moveAfter(ExtOpnd);
5052 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
5055 TPT.setOperand(Ext, 0, ExtOpnd);
5065 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
5067 TPT.mutateType(ExtOpnd,
Ext->getType());
5069 TPT.replaceAllUsesWith(Ext, ExtOpnd);
5076 !shouldExtOperand(ExtOpnd,
OpIdx)) {
5084 unsigned BitWidth =
Ext->getType()->getIntegerBitWidth();
5085 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
5087 TPT.setOperand(ExtOpnd,
OpIdx, ConstantInt::get(
Ext->getType(), CstVal));
5098 Value *ValForExtOpnd = IsSExt
5099 ? TPT.createSExt(ExtOpnd, Opnd,
Ext->getType())
5100 : TPT.createZExt(ExtOpnd, Opnd,
Ext->getType());
5101 TPT.setOperand(ExtOpnd,
OpIdx, ValForExtOpnd);
5103 if (!InstForExtOpnd)
5109 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5112 TPT.eraseInstruction(Ext);
5124bool AddressingModeMatcher::isPromotionProfitable(
5125 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5126 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5131 if (NewCost > OldCost)
5133 if (NewCost < OldCost)
5152bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5164 case Instruction::PtrToInt:
5167 case Instruction::IntToPtr: {
5175 case Instruction::BitCast:
5185 case Instruction::AddrSpaceCast: {
5193 case Instruction::Add: {
5196 ExtAddrMode BackupAddrMode =
AddrMode;
5197 unsigned OldSize = AddrModeInsts.
size();
5202 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5203 TPT.getRestorationPoint();
5207 int First = 0, Second = 1;
5218 AddrModeInsts.
resize(OldSize);
5219 TPT.rollback(LastKnownGood);
5229 AddrModeInsts.
resize(OldSize);
5230 TPT.rollback(LastKnownGood);
5236 case Instruction::Mul:
5237 case Instruction::Shl: {
5241 if (!
RHS ||
RHS->getBitWidth() > 64)
5243 int64_t Scale = Opcode == Instruction::Shl
5244 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5245 :
RHS->getSExtValue();
5249 case Instruction::GetElementPtr: {
5252 int VariableOperand = -1;
5253 unsigned VariableScale = 0;
5255 int64_t ConstantOffset = 0;
5257 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5259 const StructLayout *SL =
DL.getStructLayout(STy);
5270 if (ConstantInt *CI =
5272 const APInt &CVal = CI->
getValue();
5279 if (VariableOperand != -1)
5283 VariableOperand = i;
5284 VariableScale = TypeSize;
5291 if (VariableOperand == -1) {
5292 AddrMode.BaseOffs += ConstantOffset;
5298 AddrMode.BaseOffs -= ConstantOffset;
5302 ConstantOffset > 0) {
5315 BasicBlock *Parent = BaseI ? BaseI->getParent()
5316 : &
GEP->getFunction()->getEntryBlock();
5318 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5326 ExtAddrMode BackupAddrMode =
AddrMode;
5327 unsigned OldSize = AddrModeInsts.
size();
5330 AddrMode.BaseOffs += ConstantOffset;
5339 AddrModeInsts.
resize(OldSize);
5347 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5352 AddrModeInsts.
resize(OldSize);
5357 AddrMode.BaseOffs += ConstantOffset;
5358 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5359 VariableScale,
Depth)) {
5362 AddrModeInsts.
resize(OldSize);
5369 case Instruction::SExt:
5370 case Instruction::ZExt: {
5377 TypePromotionHelper::Action TPH =
5378 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5382 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5383 TPT.getRestorationPoint();
5384 unsigned CreatedInstsCost = 0;
5386 Value *PromotedOperand =
5387 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5402 assert(PromotedOperand &&
5403 "TypePromotionHelper should have filtered out those cases");
5405 ExtAddrMode BackupAddrMode =
AddrMode;
5406 unsigned OldSize = AddrModeInsts.
size();
5408 if (!matchAddr(PromotedOperand,
Depth) ||
5413 !isPromotionProfitable(CreatedInstsCost,
5414 ExtCost + (AddrModeInsts.
size() - OldSize),
5417 AddrModeInsts.
resize(OldSize);
5418 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5419 TPT.rollback(LastKnownGood);
5424 AddrMode.replaceWith(Ext, PromotedOperand);
5427 case Instruction::Call:
5429 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5445bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5448 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5449 TPT.getRestorationPoint();
5473 ExtAddrMode BackupAddrMode =
AddrMode;
5474 unsigned OldSize = AddrModeInsts.
size();
5477 bool MovedAway =
false;
5478 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5486 if (
I->hasOneUse() ||
5487 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5494 AddrModeInsts.
resize(OldSize);
5495 TPT.rollback(LastKnownGood);
5498 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5500 TPT.rollback(LastKnownGood);
5527 TPT.rollback(LastKnownGood);
5546 if (OpInfo.CallOperandVal == OpVal &&
5548 !OpInfo.isIndirect))
5564 if (!ConsideredInsts.
insert(
I).second)
5572 for (
Use &U :
I->uses()) {
5580 MemoryUses.push_back({&U, LI->getType()});
5587 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5594 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5601 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5611 if (!
find(PtrOps, U.get()))
5614 MemoryUses.push_back({&U, AccessTy});
5619 if (CI->hasFnAttr(Attribute::Cold)) {
5637 PSI, BFI, SeenInsts))
5648 unsigned SeenInsts = 0;
5651 PSI, BFI, SeenInsts);
5659bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5661 Value *KnownLive2) {
5663 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5704bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5705 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5706 if (IgnoreProfitability)
5724 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5725 ScaledReg =
nullptr;
5729 if (!BaseReg && !ScaledReg)
5750 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5753 Type *AddressAccessTy = Pair.second;
5754 unsigned AS =
Address->getType()->getPointerAddressSpace();
5760 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5762 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5763 TPT.getRestorationPoint();
5764 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5765 AddressAccessTy, AS, UserI, Result,
5766 InsertedInsts, PromotedInsts, TPT,
5767 LargeOffsetGEP, OptSize, PSI, BFI);
5768 Matcher.IgnoreProfitability =
true;
5776 TPT.rollback(LastKnownGood);
5782 MatchedAddrModeInsts.
clear();
5792 return I->getParent() != BB;
5808 return std::next(AddrInst->getIterator());
5819 Earliest = UserInst;
5844bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5845 Type *AccessTy,
unsigned AddrSpace) {
5850 SmallVector<Value *, 8> worklist;
5851 SmallPtrSet<Value *, 16> Visited;
5857 bool PhiOrSelectSeen =
false;
5858 SmallVector<Instruction *, 16> AddrModeInsts;
5859 const SimplifyQuery SQ(*
DL, TLInfo);
5860 AddressingModeCombiner AddrModes(SQ, Addr);
5861 TypePromotionTransaction TPT(RemovedInsts);
5862 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5863 TPT.getRestorationPoint();
5864 while (!worklist.
empty()) {
5876 if (!Visited.
insert(V).second)
5882 PhiOrSelectSeen =
true;
5889 PhiOrSelectSeen =
true;
5896 AddrModeInsts.
clear();
5897 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5902 auto getDTFn = [MemoryInst,
this]() ->
const DominatorTree & {
5904 return this->getDT(*
F);
5906 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5907 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5908 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5911 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5916 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5917 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5920 NewAddrMode.OriginalValue =
V;
5921 if (!AddrModes.addNewAddrMode(NewAddrMode))
5928 if (!AddrModes.combineAddrModes()) {
5929 TPT.rollback(LastKnownGood);
5935 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5941 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5955 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
5977 <<
" for " << *MemoryInst <<
"\n");
5981 !
DL->isNonIntegralPointerType(Addr->
getType())) {
5987 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
5989 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
5991 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
5998 <<
" for " << *MemoryInst <<
"\n");
5999 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
6010 if (ResultPtr ||
AddrMode.Scale != 1)
6031 GlobalValue *BaseGV =
AddrMode.BaseGV;
6032 if (BaseGV !=
nullptr) {
6037 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
6046 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
6047 if (!ResultPtr &&
AddrMode.BaseReg) {
6051 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
6052 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
6061 }
else if (!ResultPtr) {
6074 if (
V->getType() != IntPtrTy)
6075 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6083 if (
V->getType() == IntPtrTy) {
6088 "We can't transform if ScaledReg is too narrow");
6089 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6093 V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy,
AddrMode.Scale),
6096 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6107 if (ResultPtr->
getType() != I8PtrTy)
6108 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6109 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6122 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6124 SunkAddr = ResultPtr;
6126 if (ResultPtr->
getType() != I8PtrTy)
6127 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6128 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6135 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6141 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
6143 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6145 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6155 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6156 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6157 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6159 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6163 <<
" for " << *MemoryInst <<
"\n");
6174 if (
V->getType()->isPointerTy())
6175 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6176 if (
V->getType() != IntPtrTy)
6177 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6184 if (
V->getType() == IntPtrTy) {
6186 }
else if (
V->getType()->isPointerTy()) {
6187 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6190 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6199 I->eraseFromParent();
6203 V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy,
AddrMode.Scale),
6206 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6212 GlobalValue *BaseGV =
AddrMode.BaseGV;
6213 if (BaseGV !=
nullptr) {
6216 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6220 Value *
V = Builder.CreatePtrToInt(BaseGVPtr, IntPtrTy,
"sunkaddr");
6222 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6231 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6239 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6245 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6250 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6251 RecursivelyDeleteTriviallyDeadInstructions(
6252 Repl, TLInfo, nullptr,
6253 [&](Value *V) { removeAllAssertingVHReferences(V); });
6277bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6283 if (!
GEP->hasIndices())
6291 SmallVector<Value *, 2>
Ops(
GEP->operands());
6293 bool RewriteGEP =
false;
6302 unsigned FinalIndex =
Ops.size() - 1;
6307 for (
unsigned i = 1; i < FinalIndex; ++i) {
6312 C =
C->getSplatValue();
6314 if (!CI || !CI->
isZero())
6321 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6325 if (!
C || !
C->isZero()) {
6326 Ops[FinalIndex] =
V;
6334 if (!RewriteGEP &&
Ops.size() == 2)
6341 Type *SourceTy =
GEP->getSourceElementType();
6342 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6346 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6347 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6348 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6358 if (
Ops.size() != 2) {
6368 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6382 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6383 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6386 Intrinsic::masked_gather) {
6390 Intrinsic::masked_scatter);
6403 if (
Ptr->use_empty())
6405 Ptr, TLInfo,
nullptr,
6406 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6413bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6414 bool MadeChange =
false;
6416 const TargetRegisterInfo *
TRI =
6417 TM->getSubtargetImpl(*CS->
getFunction())->getRegisterInfo();
6421 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6427 OpInfo.isIndirect) {
6429 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6492bool CodeGenPrepare::tryToPromoteExts(
6493 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6494 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6495 unsigned CreatedInstsCost) {
6496 bool Promoted =
false;
6499 for (
auto *
I : Exts) {
6514 TypePromotionHelper::Action TPH =
6515 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6524 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6525 TPT.getRestorationPoint();
6526 SmallVector<Instruction *, 4> NewExts;
6527 unsigned NewCreatedInstsCost = 0;
6530 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6531 &NewExts,
nullptr, *TLI);
6533 "TypePromotionHelper should have filtered out those cases");
6543 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6546 TotalCreatedInstsCost =
6547 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6549 (TotalCreatedInstsCost > 1 ||
6551 (ExtCost == 0 && NewExts.
size() > 1))) {
6555 TPT.rollback(LastKnownGood);
6560 SmallVector<Instruction *, 2> NewlyMovedExts;
6561 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6562 bool NewPromoted =
false;
6563 for (
auto *ExtInst : NewlyMovedExts) {
6573 ProfitablyMovedExts.
push_back(MovedExt);
6580 TPT.rollback(LastKnownGood);
6591bool CodeGenPrepare::mergeSExts(Function &
F) {
6593 for (
auto &Entry : ValToSExtendedUses) {
6594 SExts &Insts =
Entry.second;
6596 for (Instruction *Inst : Insts) {
6600 bool inserted =
false;
6601 for (
auto &Pt : CurPts) {
6604 RemovedInsts.insert(Pt);
6605 Pt->removeFromParent();
6616 RemovedInsts.insert(Inst);
6623 CurPts.push_back(Inst);
6665bool CodeGenPrepare::splitLargeGEPOffsets() {
6667 for (
auto &Entry : LargeOffsetGEPMap) {
6669 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6670 &LargeOffsetGEPs =
Entry.second;
6671 auto compareGEPOffset =
6672 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6673 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6674 if (
LHS.first ==
RHS.first)
6676 if (
LHS.second !=
RHS.second)
6677 return LHS.second <
RHS.second;
6678 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6681 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6684 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6686 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6687 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6688 Value *NewBaseGEP =
nullptr;
6690 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6691 GetElementPtrInst *
GEP) {
6692 LLVMContext &Ctx =
GEP->getContext();
6693 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6695 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6707 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), DT.get(), LI);
6710 NewBaseInsertPt = std::next(BaseI->getIterator());
6717 IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
6719 Value *BaseIndex = ConstantInt::get(PtrIdxTy, BaseOffset);
6720 NewBaseGEP = OldBase;
6721 if (NewBaseGEP->
getType() != I8PtrTy)
6722 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6724 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6725 NewGEPBases.
insert(NewBaseGEP);
6731 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6732 BaseOffset = PreferBase;
6735 createNewBase(BaseOffset, OldBase, BaseGEP);
6738 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6739 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6740 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6741 int64_t
Offset = LargeOffsetGEP->second;
6742 if (
Offset != BaseOffset) {
6749 GEP->getResultElementType(),
6750 GEP->getAddressSpace())) {
6756 NewBaseGEP =
nullptr;
6761 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6766 createNewBase(BaseOffset, OldBase,
GEP);
6770 Value *NewGEP = NewBaseGEP;
6771 if (
Offset != BaseOffset) {
6774 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6778 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6779 GEP->eraseFromParent();
6786bool CodeGenPrepare::optimizePhiType(
6787 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
6788 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
6793 Type *PhiTy =
I->getType();
6794 Type *ConvertTy =
nullptr;
6796 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6799 SmallVector<Instruction *, 4> Worklist;
6801 SmallPtrSet<PHINode *, 4> PhiNodes;
6802 SmallPtrSet<ConstantData *, 4>
Constants;
6805 SmallPtrSet<Instruction *, 4> Defs;
6806 SmallPtrSet<Instruction *, 4>
Uses;
6812 bool AnyAnchored =
false;
6814 while (!Worklist.
empty()) {
6819 for (
Value *V :
Phi->incoming_values()) {
6821 if (!PhiNodes.
count(OpPhi)) {
6822 if (!Visited.
insert(OpPhi).second)
6828 if (!OpLoad->isSimple())
6830 if (Defs.
insert(OpLoad).second)
6833 if (Defs.
insert(OpEx).second)
6837 ConvertTy = OpBC->getOperand(0)->getType();
6838 if (OpBC->getOperand(0)->getType() != ConvertTy)
6840 if (Defs.
insert(OpBC).second) {
6853 for (User *V :
II->users()) {
6855 if (!PhiNodes.
count(OpPhi)) {
6856 if (Visited.
count(OpPhi))
6863 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
6865 Uses.insert(OpStore);
6868 ConvertTy = OpBC->getType();
6869 if (OpBC->getType() != ConvertTy)
6873 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
6880 if (!ConvertTy || !AnyAnchored ||
6884 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
6885 << *ConvertTy <<
"\n");
6890 for (ConstantData *
C : Constants)
6892 for (Instruction *
D : Defs) {
6894 ValMap[
D] =
D->getOperand(0);
6898 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
6901 for (PHINode *Phi : PhiNodes)
6903 Phi->getName() +
".tc",
Phi->getIterator());
6905 for (PHINode *Phi : PhiNodes) {
6907 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
6909 Phi->getIncomingBlock(i));
6913 for (Instruction *U :
Uses) {
6918 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
6928bool CodeGenPrepare::optimizePhiTypes(Function &
F) {
6933 SmallPtrSet<PHINode *, 4> Visited;
6934 SmallPtrSet<Instruction *, 4> DeletedInstrs;
6938 for (
auto &Phi : BB.
phis())
6939 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
6942 for (
auto *
I : DeletedInstrs) {
6944 I->eraseFromParent();
6952bool CodeGenPrepare::canFormExtLd(
6953 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
6954 Instruction *&Inst,
bool HasPromoted) {
6955 for (
auto *MovedExtInst : MovedExts) {
6958 Inst = MovedExtInst;
7010bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7011 bool AllowPromotionWithoutCommonHeader =
false;
7016 *Inst, AllowPromotionWithoutCommonHeader);
7017 TypePromotionTransaction TPT(RemovedInsts);
7018 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7019 TPT.getRestorationPoint();
7021 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7024 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7027 LoadInst *LI =
nullptr;
7032 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7033 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7038 Inst = ExtFedByLoad;
7043 if (ATPConsiderable &&
7044 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7045 HasPromoted, TPT, SpeculativelyMovedExts))
7048 TPT.rollback(LastKnownGood);
7057bool CodeGenPrepare::performAddressTypePromotion(
7058 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7059 bool HasPromoted, TypePromotionTransaction &TPT,
7060 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7061 bool Promoted =
false;
7062 SmallPtrSet<Instruction *, 1> UnhandledExts;
7063 bool AllSeenFirst =
true;
7064 for (
auto *
I : SpeculativelyMovedExts) {
7065 Value *HeadOfChain =
I->getOperand(0);
7066 DenseMap<Value *, Instruction *>::iterator AlreadySeen =
7067 SeenChainsForSExt.
find(HeadOfChain);
7070 if (AlreadySeen != SeenChainsForSExt.
end()) {
7071 if (AlreadySeen->second !=
nullptr)
7072 UnhandledExts.
insert(AlreadySeen->second);
7073 AllSeenFirst =
false;
7077 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7078 SpeculativelyMovedExts.size() == 1)) {
7082 for (
auto *
I : SpeculativelyMovedExts) {
7083 Value *HeadOfChain =
I->getOperand(0);
7084 SeenChainsForSExt[HeadOfChain] =
nullptr;
7085 ValToSExtendedUses[HeadOfChain].push_back(
I);
7088 Inst = SpeculativelyMovedExts.pop_back_val();
7093 for (
auto *
I : SpeculativelyMovedExts) {
7094 Value *HeadOfChain =
I->getOperand(0);
7095 SeenChainsForSExt[HeadOfChain] = Inst;
7100 if (!AllSeenFirst && !UnhandledExts.
empty())
7101 for (
auto *VisitedSExt : UnhandledExts) {
7102 if (RemovedInsts.count(VisitedSExt))
7104 TypePromotionTransaction TPT(RemovedInsts);
7106 SmallVector<Instruction *, 2> Chains;
7108 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7112 for (
auto *
I : Chains) {
7113 Value *HeadOfChain =
I->getOperand(0);
7115 SeenChainsForSExt[HeadOfChain] =
nullptr;
7116 ValToSExtendedUses[HeadOfChain].push_back(
I);
7122bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7127 Value *Src =
I->getOperand(0);
7128 if (Src->hasOneUse())
7140 bool DefIsLiveOut =
false;
7141 for (User *U :
I->users()) {
7146 if (UserBB == DefBB)
7148 DefIsLiveOut =
true;
7155 for (User *U : Src->users()) {
7158 if (UserBB == DefBB)
7167 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7169 bool MadeChange =
false;
7170 for (Use &U : Src->uses()) {
7175 if (UserBB == DefBB)
7179 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7181 if (!InsertedTrunc) {
7184 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7186 InsertedInsts.insert(InsertedTrunc);
7249bool CodeGenPrepare::optimizeLoadExt(LoadInst *Load) {
7250 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7254 if (
Load->hasOneUse() &&
7260 SmallVector<Instruction *, 8> WorkList;
7261 SmallPtrSet<Instruction *, 16> Visited;
7262 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7263 SmallVector<Instruction *, 8> DropFlags;
7264 for (
auto *U :
Load->users())
7276 while (!WorkList.
empty()) {
7280 if (!Visited.
insert(
I).second)
7285 for (
auto *U :
Phi->users())
7290 switch (
I->getOpcode()) {
7291 case Instruction::And: {
7295 APInt AndBits = AndC->getValue();
7296 DemandBits |= AndBits;
7298 if (AndBits.
ugt(WidestAndBits))
7299 WidestAndBits = AndBits;
7300 if (AndBits == WidestAndBits &&
I->getOperand(0) == Load)
7305 case Instruction::Shl: {
7309 uint64_t ShiftAmt = ShlC->getLimitedValue(
BitWidth - 1);
7310 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7315 case Instruction::Trunc: {
7318 DemandBits.setLowBits(TruncBitWidth);
7328 uint32_t ActiveBits = DemandBits.getActiveBits();
7340 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7341 WidestAndBits != DemandBits)
7344 LLVMContext &Ctx =
Load->getType()->getContext();
7345 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7355 Builder.CreateAnd(Load, ConstantInt::get(Ctx, DemandBits)));
7358 InsertedInsts.insert(NewAnd);
7363 NewAnd->setOperand(0, Load);
7366 for (
auto *
And : AndsToMaybeRemove)
7371 if (&*CurInstIterator ==
And)
7372 CurInstIterator = std::next(
And->getIterator());
7373 And->eraseFromParent();
7378 for (
auto *Inst : DropFlags)
7392 TTI->isExpensiveToSpeculativelyExecute(
I);
7410 uint64_t Max = std::max(TrueWeight, FalseWeight);
7411 uint64_t Sum = TrueWeight + FalseWeight;
7414 if (Probability >
TTI->getPredictableBranchThreshold())
7424 if (!Cmp || !Cmp->hasOneUse())
7447 assert(DefSI->getCondition() ==
SI->getCondition() &&
7448 "The condition of DefSI does not match with SI");
7449 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7452 assert(V &&
"Failed to get select true/false value");
7456bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7480 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7481 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7482 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7483 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7489bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7491 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7492 "Expected a funnel shift");
7516 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7517 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7518 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7526bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7538 It !=
SI->getParent()->
end(); ++It) {
7540 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7547 SelectInst *LastSI = ASI.
back();
7550 CurInstIterator = std::next(LastSI->
getIterator());
7554 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7555 fixupDbgVariableRecordsOnInst(*SI);
7557 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7560 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7563 TargetLowering::SelectSupportKind SelectKind;
7564 if (
SI->getType()->isVectorTy())
7565 SelectKind = TargetLowering::ScalarCondVectorVal;
7567 SelectKind = TargetLowering::ScalarValSelect;
7608 for (SelectInst *SI : ASI) {
7620 SplitPt.setHeadBit(
true);
7623 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7628 BranchInst *TrueBranch =
nullptr;
7629 BranchInst *FalseBranch =
nullptr;
7630 if (TrueInstrs.
size() == 0) {
7632 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7635 }
else if (FalseInstrs.
size() == 0) {
7637 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7644 nullptr,
nullptr, LI);
7652 EndBlock->
setName(
"select.end");
7654 TrueBlock->
setName(
"select.true.sink");
7656 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7657 :
"select.false.sink");
7661 FreshBBs.
insert(TrueBlock);
7663 FreshBBs.
insert(FalseBlock);
7664 FreshBBs.
insert(EndBlock);
7667 BFI->setBlockFreq(EndBlock,
BFI->getBlockFreq(StartBlock));
7669 static const unsigned MD[] = {
7670 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7671 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7676 for (Instruction *
I : TrueInstrs)
7678 for (Instruction *
I : FalseInstrs)
7685 if (TrueBlock ==
nullptr)
7686 TrueBlock = StartBlock;
7687 else if (FalseBlock ==
nullptr)
7688 FalseBlock = StartBlock;
7704 SI->eraseFromParent();
7706 ++NumSelectsExpanded;
7710 CurInstIterator = StartBlock->
end();
7717bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7729 "Expected a type of the same size!");
7735 Builder.SetInsertPoint(SVI);
7736 Value *BC1 = Builder.CreateBitCast(
7738 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7739 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7743 SVI, TLInfo,
nullptr,
7744 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7751 !
Op->isTerminator() && !
Op->isEHPad())
7757bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7772 DenseMap<const Instruction *, unsigned long> InstOrdering;
7773 unsigned long InstNumber = 0;
7774 for (
const auto &
I : *TargetBB)
7775 InstOrdering[&
I] = InstNumber++;
7777 for (Use *U :
reverse(OpsToSink)) {
7782 if (InstOrdering[UI] < InstOrdering[InsertPoint])
7789 SetVector<Instruction *> MaybeDead;
7790 DenseMap<Instruction *, Instruction *> NewInstructions;
7791 for (Use *U : ToReplace) {
7800 FreshBBs.
insert(OpDef->getParent());
7803 NewInstructions[UI] = NI;
7808 InsertedInsts.insert(NI);
7814 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
7815 It->second->setOperand(
U->getOperandNo(), NI);
7822 for (
auto *
I : MaybeDead) {
7823 if (!
I->hasNUsesOrMore(1)) {
7825 I->eraseFromParent();
7832bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
7849 auto *NewType = Type::getIntNTy(
Context, RegWidth);
7858 ExtType = Instruction::SExt;
7861 if (Arg->hasSExtAttr())
7862 ExtType = Instruction::SExt;
7863 if (Arg->hasZExtAttr())
7864 ExtType = Instruction::ZExt;
7870 SI->setCondition(ExtInst);
7871 for (
auto Case :
SI->cases()) {
7872 const APInt &NarrowConst = Case.getCaseValue()->getValue();
7873 APInt WideConst = (ExtType == Instruction::ZExt)
7874 ? NarrowConst.
zext(RegWidth)
7875 : NarrowConst.
sext(RegWidth);
7876 Case.setValue(ConstantInt::get(
Context, WideConst));
7882bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
7889 Value *Condition =
SI->getCondition();
7898 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
7899 ConstantInt *CaseValue = Case.getCaseValue();
7900 BasicBlock *CaseBB = Case.getCaseSuccessor();
7903 bool CheckedForSinglePred =
false;
7904 for (PHINode &
PHI : CaseBB->
phis()) {
7905 Type *PHIType =
PHI.getType();
7913 if (PHIType == ConditionType || TryZExt) {
7915 bool SkipCase =
false;
7916 Value *Replacement =
nullptr;
7917 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
7918 Value *PHIValue =
PHI.getIncomingValue(
I);
7919 if (PHIValue != CaseValue) {
7928 if (
PHI.getIncomingBlock(
I) != SwitchBB)
7933 if (!CheckedForSinglePred) {
7934 CheckedForSinglePred =
true;
7935 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
7941 if (Replacement ==
nullptr) {
7942 if (PHIValue == CaseValue) {
7943 Replacement = Condition;
7946 Replacement = Builder.CreateZExt(Condition, PHIType);
7949 PHI.setIncomingValue(
I, Replacement);
7960bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
7961 bool Changed = optimizeSwitchType(SI);
7962 Changed |= optimizeSwitchPhiConstants(SI);
7983class VectorPromoteHelper {
7985 const DataLayout &
DL;
7988 const TargetLowering &TLI;
7991 const TargetTransformInfo &
TTI;
7997 SmallVector<Instruction *, 4> InstsToBePromoted;
8000 unsigned StoreExtractCombineCost;
8009 if (InstsToBePromoted.
empty())
8011 return InstsToBePromoted.
back();
8017 unsigned getTransitionOriginalValueIdx()
const {
8019 "Other kind of transitions are not supported yet");
8026 unsigned getTransitionIdx()
const {
8028 "Other kind of transitions are not supported yet");
8036 Type *getTransitionType()
const {
8047 void promoteImpl(Instruction *ToBePromoted);
8051 bool isProfitableToPromote() {
8052 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8056 Type *PromotedType = getTransitionType();
8059 unsigned AS =
ST->getPointerAddressSpace();
8077 for (
const auto &Inst : InstsToBePromoted) {
8085 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8097 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8098 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8099 return ScalarCost > VectorCost;
8111 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8126 if (!
EC.isScalable()) {
8129 for (
unsigned Idx = 0; Idx !=
EC.getKnownMinValue(); ++Idx) {
8130 if (Idx == ExtractIdx)
8138 "Generate scalable vector for non-splat is unimplemented");
8143 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8144 unsigned OperandIdx) {
8147 if (OperandIdx != 1)
8149 switch (
Use->getOpcode()) {
8152 case Instruction::SDiv:
8153 case Instruction::UDiv:
8154 case Instruction::SRem:
8155 case Instruction::URem:
8157 case Instruction::FDiv:
8158 case Instruction::FRem:
8159 return !
Use->hasNoNaNs();
8165 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8166 const TargetTransformInfo &
TTI, Instruction *Transition,
8167 unsigned CombineCost)
8168 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8169 StoreExtractCombineCost(CombineCost) {
8170 assert(Transition &&
"Do not know how to promote null");
8174 bool canPromote(
const Instruction *ToBePromoted)
const {
8181 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8184 for (
const Use &U : ToBePromoted->
operands()) {
8185 const Value *Val =
U.get();
8186 if (Val == getEndOfTransition()) {
8190 if (canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()))
8213 void enqueueForPromotion(Instruction *ToBePromoted) {
8214 InstsToBePromoted.push_back(ToBePromoted);
8218 void recordCombineInstruction(Instruction *ToBeCombined) {
8220 CombineInst = ToBeCombined;
8230 if (InstsToBePromoted.empty() || !CombineInst)
8238 for (
auto &ToBePromoted : InstsToBePromoted)
8239 promoteImpl(ToBePromoted);
8240 InstsToBePromoted.clear();
8247void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8257 "The type of the result of the transition does not match "
8262 Type *TransitionTy = getTransitionType();
8267 for (Use &U : ToBePromoted->
operands()) {
8269 Value *NewVal =
nullptr;
8270 if (Val == Transition)
8271 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8278 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8282 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8285 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8291bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8292 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8307 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8308 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost);
8315 if (ToBePromoted->
getParent() != Parent) {
8316 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8318 <<
") than the transition (" << Parent->
getName()
8323 if (VPH.canCombine(ToBePromoted)) {
8325 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8326 VPH.recordCombineInstruction(ToBePromoted);
8328 NumStoreExtractExposed +=
Changed;
8333 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8336 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8338 VPH.enqueueForPromotion(ToBePromoted);
8339 Inst = ToBePromoted;
8379 Type *StoreType =
SI.getValueOperand()->getType();
8388 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8389 DL.getTypeSizeInBits(StoreType) == 0)
8392 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8394 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8398 if (
SI.isVolatile())
8410 if (!
match(
SI.getValueOperand(),
8417 if (!
LValue->getType()->isIntegerTy() ||
8418 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8420 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8436 Builder.SetInsertPoint(&
SI);
8440 if (LBC && LBC->getParent() !=
SI.getParent())
8441 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8442 if (HBC && HBC->getParent() !=
SI.getParent())
8443 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8445 bool IsLE =
SI.getDataLayout().isLittleEndian();
8446 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8447 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8448 Value *Addr =
SI.getPointerOperand();
8449 Align Alignment =
SI.getAlign();
8450 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8451 if (IsOffsetStore) {
8452 Addr = Builder.CreateGEP(
8453 SplitStoreType, Addr,
8461 Builder.CreateAlignedStore(V, Addr, Alignment);
8464 CreateSplitStore(
LValue,
false);
8465 CreateSplitStore(HValue,
true);
8468 SI.eraseFromParent();
8476 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8558 if (GEPIOpI->getParent() != SrcBlock)
8563 if (auto *I = dyn_cast<Instruction>(Usr)) {
8564 if (I->getParent() != SrcBlock) {
8572 std::vector<GetElementPtrInst *> UGEPIs;
8575 for (User *Usr : GEPIOp->
users()) {
8594 if (UGEPI->getOperand(0) != GEPIOp)
8596 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8598 if (GEPIIdx->getType() !=
8606 UGEPIs.push_back(UGEPI);
8608 if (UGEPIs.size() == 0)
8611 for (GetElementPtrInst *UGEPI : UGEPIs) {
8613 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8620 for (GetElementPtrInst *UGEPI : UGEPIs) {
8621 UGEPI->setOperand(0, GEPI);
8623 Constant *NewUGEPIIdx = ConstantInt::get(
8624 GEPIIdx->getType(), UGEPIIdx->
getValue() - GEPIIdx->getValue());
8625 UGEPI->setOperand(1, NewUGEPIIdx);
8628 if (!GEPI->isInBounds()) {
8629 UGEPI->setIsInBounds(
false);
8636 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8638 "GEPIOp is used outside SrcBlock");
8662 Value *
X = Cmp->getOperand(0);
8663 if (!
X->hasUseList())
8668 for (
auto *U :
X->users()) {
8672 (UI->
getParent() != Branch->getParent() &&
8673 UI->
getParent() != Branch->getSuccessor(0) &&
8674 UI->
getParent() != Branch->getSuccessor(1)) ||
8675 (UI->
getParent() != Branch->getParent() &&
8676 !UI->
getParent()->getSinglePredecessor()))
8682 if (UI->
getParent() != Branch->getParent())
8686 ConstantInt::get(UI->
getType(), 0));
8688 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8692 if (Cmp->isEquality() &&
8697 if (UI->
getParent() != Branch->getParent())
8700 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8701 ConstantInt::get(UI->
getType(), 0));
8703 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8711bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8712 bool AnyChange =
false;
8713 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8717 if (InsertedInsts.count(
I))
8726 LargeOffsetGEPMap.erase(
P);
8728 P->eraseFromParent();
8751 I, LI->getLoopFor(
I->getParent()), *
TTI))
8759 TargetLowering::TypeExpandInteger) {
8763 I, LI->getLoopFor(
I->getParent()), *
TTI))
8766 bool MadeChange = optimizeExt(
I);
8767 return MadeChange | optimizeExtUses(
I);
8774 if (optimizeCmp(Cmp, ModifiedDT))
8778 if (optimizeURem(
I))
8782 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8783 bool Modified = optimizeLoadExt(LI);
8792 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8793 unsigned AS =
SI->getPointerAddressSpace();
8794 return optimizeMemoryInst(
I,
SI->getOperand(1),
8795 SI->getOperand(0)->getType(), AS);
8799 unsigned AS = RMW->getPointerAddressSpace();
8800 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
8804 unsigned AS = CmpX->getPointerAddressSpace();
8805 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
8806 CmpX->getCompareOperand()->getType(), AS);
8816 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
8817 BinOp->
getOpcode() == Instruction::LShr)) {
8825 if (GEPI->hasAllZeroIndices()) {
8827 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
8828 GEPI->getName(), GEPI->getIterator());
8829 NC->setDebugLoc(GEPI->getDebugLoc());
8832 GEPI, TLInfo,
nullptr,
8833 [&](
Value *V) { removeAllAssertingVHReferences(V); });
8835 optimizeInst(
NC, ModifiedDT);
8858 if (Const0 || Const1) {
8859 if (!Const0 || !Const1) {
8860 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
8865 FI->eraseFromParent();
8872 if (tryToSinkFreeOperands(
I))
8875 switch (
I->getOpcode()) {
8876 case Instruction::Shl:
8877 case Instruction::LShr:
8878 case Instruction::AShr:
8880 case Instruction::Call:
8882 case Instruction::Select:
8884 case Instruction::ShuffleVector:
8886 case Instruction::Switch:
8888 case Instruction::ExtractElement:
8890 case Instruction::Br:
8899bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
8900 if (!
I.getType()->isIntegerTy() ||
8905 SmallVector<Instruction *, 4> Insts;
8911 &
I, TLInfo,
nullptr,
8912 [&](
Value *V) { removeAllAssertingVHReferences(V); });
8919bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
8921 bool MadeChange =
false;
8924 CurInstIterator = BB.
begin();
8925 ModifiedDT = ModifyDT::NotModifyDT;
8926 while (CurInstIterator != BB.
end()) {
8927 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
8928 if (ModifiedDT != ModifyDT::NotModifyDT) {
8941 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
8943 bool MadeBitReverse =
true;
8944 while (MadeBitReverse) {
8945 MadeBitReverse =
false;
8947 if (makeBitReverse(
I)) {
8948 MadeBitReverse = MadeChange =
true;
8953 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
8958bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
8959 bool AnyChange =
false;
8960 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
8961 AnyChange |= fixupDbgVariableRecord(DVR);
8967bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
8968 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
8969 DVR.
Type != DbgVariableRecord::LocationType::Assign)
8973 bool AnyChange =
false;
8974 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
8976 for (
Value *Location : LocationOps) {
8977 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9006bool CodeGenPrepare::placeDbgValues(Function &
F) {
9007 bool MadeChange =
false;
9008 DominatorTree DT(
F);
9010 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9011 SmallVector<Instruction *, 4> VIs;
9012 for (
Value *V : DbgItem->location_ops())
9020 for (Instruction *VI : VIs) {
9021 if (
VI->isTerminator())
9026 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9037 if (VIs.size() > 1) {
9040 <<
"Unable to find valid location for Debug Value, undefing:\n"
9042 DbgItem->setKillLocation();
9047 << *DbgItem <<
' ' << *VI);
9054 for (BasicBlock &BB :
F) {
9060 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9062 DbgProcessor(&DVR, &Insn);
9073bool CodeGenPrepare::placePseudoProbes(Function &
F) {
9074 bool MadeChange =
false;
9077 auto FirstInst =
Block.getFirstInsertionPt();
9078 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9082 while (
I !=
Block.end()) {
9084 II->moveBefore(FirstInst);
9094 uint64_t NewMax = (NewTrue > NewFalse) ? NewTrue : NewFalse;
9095 uint32_t Scale = (NewMax / std::numeric_limits<uint32_t>::max()) + 1;
9096 NewTrue = NewTrue / Scale;
9097 NewFalse = NewFalse / Scale;
9122bool CodeGenPrepare::splitBranchCondition(Function &
F, ModifyDT &ModifiedDT) {
9126 bool MadeChange =
false;
9127 for (
auto &BB :
F) {
9140 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9148 Value *Cond1, *Cond2;
9151 Opc = Instruction::And;
9154 Opc = Instruction::Or;
9164 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9178 Br1->setCondition(Cond1);
9183 if (
Opc == Instruction::And)
9184 Br1->setSuccessor(0, TmpBB);
9186 Br1->setSuccessor(1, TmpBB);
9191 I->removeFromParent();
9192 I->insertBefore(Br2->getIterator());
9204 if (
Opc == Instruction::Or)
9211 for (PHINode &PN : FBB->
phis()) {
9218 if (
Opc == Instruction::Or) {
9238 uint64_t TrueWeight, FalseWeight;
9240 uint64_t NewTrueWeight = TrueWeight;
9241 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9243 Br1->setMetadata(LLVMContext::MD_prof,
9244 MDBuilder(Br1->getContext())
9245 .createBranchWeights(TrueWeight, FalseWeight,
9248 NewTrueWeight = TrueWeight;
9249 NewFalseWeight = 2 * FalseWeight;
9251 Br2->setMetadata(LLVMContext::MD_prof,
9252 MDBuilder(Br2->getContext())
9253 .createBranchWeights(TrueWeight, FalseWeight));
9274 uint64_t TrueWeight, FalseWeight;
9276 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9277 uint64_t NewFalseWeight = FalseWeight;
9279 Br1->setMetadata(LLVMContext::MD_prof,
9280 MDBuilder(Br1->getContext())
9281 .createBranchWeights(TrueWeight, FalseWeight));
9283 NewTrueWeight = 2 * TrueWeight;
9284 NewFalseWeight = FalseWeight;
9286 Br2->setMetadata(LLVMContext::MD_prof,
9287 MDBuilder(Br2->getContext())
9288 .createBranchWeights(TrueWeight, FalseWeight));
9292 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.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap, true > m_c_NUWAdd(const LHS &L, const RHS &R)
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
UAddWithOverflow_match< LHS_t, RHS_t, Sum_t > m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S)
Match an icmp instruction checking for unsigned overflow on addition.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
auto m_Undef()
Match an arbitrary undef constant.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale)
Compare two scaled numbers.
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ Assume
Do not drop type tests (default).
@ User
could "use" a pointer
NodeAddr< PhiNode * > Phi
NodeAddr< UseNode * > Use
SmallVector< Node, 4 > NodeList
friend class Instruction
Iterator for Instructions in a `BasicBlock.
LLVM_ABI iterator begin() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
FunctionAddr VTableAddr Value
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.