45#include "llvm/Config/llvm-config.h"
66#include "llvm/IR/IntrinsicsAArch64.h"
110#define DEBUG_TYPE "codegenprepare"
113STATISTIC(NumPHIsElim,
"Number of trivial PHIs eliminated");
114STATISTIC(NumGEPsElim,
"Number of GEPs converted to casts");
115STATISTIC(NumCmpUses,
"Number of uses of Cmp expressions replaced with uses of "
117STATISTIC(NumCastUses,
"Number of uses of Cast expressions replaced with uses "
119STATISTIC(NumMemoryInsts,
"Number of memory instructions whose address "
120 "computations were sunk");
122 "Number of phis created when address "
123 "computations were sunk to memory instructions");
125 "Number of select created when address "
126 "computations were sunk to memory instructions");
127STATISTIC(NumExtsMoved,
"Number of [s|z]ext instructions combined with loads");
128STATISTIC(NumExtUses,
"Number of uses of [s|z]ext instructions optimized");
130 "Number of and mask instructions added to form ext loads");
131STATISTIC(NumAndUses,
"Number of uses of and mask instructions optimized");
132STATISTIC(NumRetsDup,
"Number of return instructions duplicated");
133STATISTIC(NumDbgValueMoved,
"Number of debug value instructions moved");
134STATISTIC(NumSelectsExpanded,
"Number of selects turned into branches");
135STATISTIC(NumStoreExtractExposed,
"Number of store(extractelement) exposed");
139 cl::desc(
"Disable branch optimizations in CodeGenPrepare"));
143 cl::desc(
"Disable GC optimizations in CodeGenPrepare"));
148 cl::desc(
"Disable select to branch conversion."));
152 cl::desc(
"Address sinking in CGP using GEPs."));
156 cl::desc(
"Enable sinking and/cmp into branches."));
160 cl::desc(
"Disable store(extract) optimizations in CodeGenPrepare"));
164 cl::desc(
"Stress test store(extract) optimizations in CodeGenPrepare"));
168 cl::desc(
"Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in "
173 cl::desc(
"Stress test ext(promotable(ld)) -> promoted(ext(ld)) "
174 "optimization in CodeGenPrepare"));
178 cl::desc(
"Disable protection against removing loop preheaders"));
182 cl::desc(
"Use profile info to add section prefix for hot/cold functions"));
185 "profile-unknown-in-special-section",
cl::Hidden,
186 cl::desc(
"In profiling mode like sampleFDO, if a function doesn't have "
187 "profile, we cannot tell the function is cold for sure because "
188 "it may be a function newly added without ever being sampled. "
189 "With the flag enabled, compiler can put such profile unknown "
190 "functions into a special section, so runtime system can choose "
191 "to handle it in a different way than .text section, to save "
192 "RAM for example. "));
196 cl::desc(
"Use the basic-block-sections profile to determine the text "
197 "section prefix for hot functions. Functions with "
198 "basic-block-sections profile will be placed in `.text.hot` "
199 "regardless of their FDO profile info. Other functions won't be "
200 "impacted, i.e., their prefixes will be decided by FDO/sampleFDO "
205 cl::desc(
"Skip merging empty blocks if (frequency of empty block) / "
206 "(frequency of destination block) is greater than this ratio"));
210 cl::desc(
"Force store splitting no matter what the target query says."));
214 cl::desc(
"Enable merging of redundant sexts when one is dominating"
220 cl::desc(
"Disables combining addressing modes with different parts "
221 "in optimizeMemoryInst."));
225 cl::desc(
"Allow creation of Phis in Address sinking."));
229 cl::desc(
"Allow creation of selects in Address sinking."));
233 cl::desc(
"Allow combining of BaseReg field in Address sinking."));
237 cl::desc(
"Allow combining of BaseGV field in Address sinking."));
241 cl::desc(
"Allow combining of BaseOffs field in Address sinking."));
245 cl::desc(
"Allow combining of ScaledReg field in Address sinking."));
250 cl::desc(
"Enable splitting large offset of GEP."));
254 cl::desc(
"Enable ICMP_EQ to ICMP_S(L|G)T conversion."));
258 cl::desc(
"Enable BFI update verification for "
263 cl::desc(
"Enable converting phi types in CodeGenPrepare"));
267 cl::desc(
"Least BB number of huge function."));
272 cl::desc(
"Max number of address users to look at"));
276 cl::desc(
"Disable elimination of dead PHI nodes."));
304class TypePromotionTransaction;
306class CodeGenPrepare {
307 friend class CodeGenPrepareLegacyPass;
308 const TargetMachine *TM =
nullptr;
309 const TargetSubtargetInfo *SubtargetInfo =
nullptr;
310 const TargetLowering *TLI =
nullptr;
311 const TargetRegisterInfo *TRI =
nullptr;
312 const TargetTransformInfo *TTI =
nullptr;
313 const BasicBlockSectionsProfileReader *BBSectionsProfileReader =
nullptr;
314 const TargetLibraryInfo *TLInfo =
nullptr;
315 LoopInfo *LI =
nullptr;
316 std::unique_ptr<BlockFrequencyInfo> BFI;
317 std::unique_ptr<BranchProbabilityInfo> BPI;
318 ProfileSummaryInfo *PSI =
nullptr;
329 ValueMap<Value *, WeakTrackingVH> SunkAddrs;
332 SetOfInstrs InsertedInsts;
336 InstrToOrigTy PromotedInsts;
339 SetOfInstrs RemovedInsts;
342 DenseMap<Value *, Instruction *> SeenChainsForSExt;
347 MapVector<AssertingVH<Value>,
352 SmallSet<AssertingVH<Value>, 2> NewGEPBases;
355 DenseMap<AssertingVH<GetElementPtrInst>,
int> LargeOffsetGEPID;
358 ValueToSExts ValToSExtendedUses;
364 const DataLayout *DL =
nullptr;
368 std::unique_ptr<DominatorTree> DT;
371 CodeGenPrepare() =
default;
372 CodeGenPrepare(
const TargetMachine *TM) : TM(TM){};
374 bool IsHugeFunc =
false;
380 SmallPtrSet<BasicBlock *, 32> FreshBBs;
382 void releaseMemory() {
384 InsertedInsts.clear();
385 PromotedInsts.clear();
394 template <
typename F>
395 void resetIteratorIfInvalidatedWhileCalling(BasicBlock *BB,
F f) {
399 Value *CurValue = &*CurInstIterator;
400 WeakTrackingVH IterHandle(CurValue);
406 if (IterHandle != CurValue) {
407 CurInstIterator = BB->
begin();
413 DominatorTree &getDT(Function &
F) {
415 DT = std::make_unique<DominatorTree>(
F);
419 void removeAllAssertingVHReferences(
Value *V);
420 bool eliminateAssumptions(Function &
F);
421 bool eliminateFallThrough(Function &
F, DominatorTree *DT =
nullptr);
422 bool eliminateMostlyEmptyBlocks(Function &
F);
423 BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB);
424 bool canMergeBlocks(
const BasicBlock *BB,
const BasicBlock *DestBB)
const;
425 void eliminateMostlyEmptyBlock(BasicBlock *BB);
426 bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB,
428 bool makeBitReverse(Instruction &
I);
430 bool optimizeInst(Instruction *
I, ModifyDT &ModifiedDT);
431 bool optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
Type *AccessTy,
433 bool optimizeGatherScatterInst(Instruction *MemoryInst,
Value *
Ptr);
434 bool 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);
822[[maybe_unused]]
void CodeGenPrepare::verifyBFIUpdates(Function &
F) {
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);
1851 bool UsedInPhiOrCurrentBlock =
any_of(Cmp->users(), [Cmp](
User *U) {
1852 return isa<PHINode>(U) ||
1853 cast<Instruction>(U)->getParent() == Cmp->getParent();
1858 if (UsedInPhiOrCurrentBlock && Cmp->getOperand(0)->getType()->isIntegerTy() &&
1859 Cmp->getOperand(0)->getType()->getScalarSizeInBits() >
1860 DL.getLargestLegalIntTypeSizeInBits())
1866 bool MadeChange =
false;
1869 Use &TheUse = UI.getUse();
1884 if (UserBB == DefBB)
1888 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1894 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1901 TheUse = InsertedCmp;
1907 if (Cmp->use_empty()) {
1908 Cmp->eraseFromParent();
1945 for (
User *U : Cmp->users()) {
1967 if (CmpBB != FalseBB)
1970 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
1984 for (
User *U : Cmp->users()) {
1993 SI->swapProfMetadata();
2005 Value *Op0 = Cmp->getOperand(0);
2006 Value *Op1 = Cmp->getOperand(1);
2015 unsigned NumInspected = 0;
2018 if (++NumInspected > 128)
2026 if (GoodToSwap > 0) {
2027 Cmp->swapOperands();
2047 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
2050 auto [ClassVal, ClassTest] =
2056 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2060 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
2061 Cmp->replaceAllUsesWith(IsFPClass);
2069 Value *Incr, *RemAmt;
2074 Value *AddInst, *AddOffset;
2077 if (PN !=
nullptr) {
2079 AddOffset =
nullptr;
2088 if (PN !=
nullptr) {
2101 if (PN->getNumIncomingValues() != 2)
2106 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2110 if (!L->contains(Rem))
2114 if (!L->isLoopInvariant(RemAmt))
2118 if (AddOffset && !L->isLoopInvariant(AddOffset))
2139 AddInstOut = AddInst;
2140 AddOffsetOut = AddOffset;
2159 Value *AddOffset, *RemAmt, *AddInst;
2162 AddOffset, LoopIncrPN))
2187 assert(AddOffset &&
"We found an add but missing values");
2206 Builder.SetInsertPoint(LoopIncrPN);
2207 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2212 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2217 NewRem->
addIncoming(Start, L->getLoopPreheader());
2222 FreshBBs.
insert(L->getLoopLatch());
2233bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2239bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2243 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2246 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2249 if (unfoldPowerOf2Test(Cmp))
2270 SetOfInstrs &InsertedInsts) {
2273 assert(!InsertedInsts.count(AndI) &&
2274 "Attempting to optimize already optimized and instruction");
2275 (void)InsertedInsts;
2289 for (
auto *U : AndI->
users()) {
2297 if (!CmpC || !CmpC->
isZero())
2312 Use &TheUse = UI.getUse();
2330 TheUse = InsertedAnd;
2347 if (
User->getOpcode() != Instruction::And ||
2353 if ((Cimm & (Cimm + 1)).getBoolValue())
2367 bool MadeChange =
false;
2370 TruncE = TruncI->user_end();
2371 TruncUI != TruncE;) {
2373 Use &TruncTheUse = TruncUI.getUse();
2398 if (UserBB == TruncUserBB)
2402 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2404 if (!InsertedShift && !InsertedTrunc) {
2408 if (ShiftI->
getOpcode() == Instruction::AShr)
2410 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2413 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2421 TruncInsertPt.setHeadBit(
true);
2422 assert(TruncInsertPt != TruncUserBB->
end());
2426 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2427 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2431 TruncTheUse = InsertedTrunc;
2464 bool MadeChange =
false;
2467 Use &TheUse = UI.getUse();
2481 if (UserBB == DefBB) {
2509 if (!InsertedShift) {
2513 if (ShiftI->
getOpcode() == Instruction::AShr)
2515 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2518 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2526 TheUse = InsertedShift;
2573 unsigned SizeInBits = Ty->getScalarSizeInBits();
2574 if (Ty->isVectorTy())
2586 FreshBBs.
insert(CallBlock);
2593 SplitPt.setHeadBit(
true);
2596 FreshBBs.
insert(EndBlock);
2601 L->addBasicBlockToLoop(CallBlock, LI);
2602 L->addBasicBlockToLoop(EndBlock, LI);
2608 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2615 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2616 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2617 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2622 Builder.SetInsertPoint(EndBlock, EndBlock->
begin());
2623 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2633 ModifiedDT = ModifyDT::ModifyBBDT;
2637bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2641 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2649 for (
auto &Arg : CI->
args()) {
2654 if (!Arg->getType()->isPointerTy())
2656 APInt
Offset(
DL->getIndexSizeInBits(
2659 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2660 uint64_t Offset2 =
Offset.getLimitedValue();
2682 MaybeAlign MIDestAlign =
MI->getDestAlign();
2683 if (!MIDestAlign || DestAlign > *MIDestAlign)
2684 MI->setDestAlignment(DestAlign);
2686 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2688 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2689 MTI->setSourceAlignment(SrcAlign);
2699 for (
auto &Arg : CI->
args()) {
2700 if (!Arg->getType()->isPointerTy())
2702 unsigned AS = Arg->getType()->getPointerAddressSpace();
2703 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2709 switch (
II->getIntrinsicID()) {
2712 case Intrinsic::assume:
2714 case Intrinsic::allow_runtime_check:
2715 case Intrinsic::allow_ubsan_check:
2716 case Intrinsic::experimental_widenable_condition: {
2720 if (
II->use_empty()) {
2721 II->eraseFromParent();
2725 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2730 case Intrinsic::objectsize:
2732 case Intrinsic::is_constant:
2734 case Intrinsic::aarch64_stlxr:
2735 case Intrinsic::aarch64_stxr: {
2744 InsertedInsts.insert(ExtVal);
2748 case Intrinsic::launder_invariant_group:
2749 case Intrinsic::strip_invariant_group: {
2750 Value *ArgVal =
II->getArgOperand(0);
2751 auto it = LargeOffsetGEPMap.
find(
II);
2752 if (it != LargeOffsetGEPMap.
end()) {
2756 auto GEPs = std::move(it->second);
2757 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2762 II->eraseFromParent();
2765 case Intrinsic::cttz:
2766 case Intrinsic::ctlz:
2770 case Intrinsic::fshl:
2771 case Intrinsic::fshr:
2772 return optimizeFunnelShift(
II);
2773 case Intrinsic::masked_gather:
2774 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2775 case Intrinsic::masked_scatter:
2776 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2777 case Intrinsic::masked_load:
2780 if (VT->getNumElements() == 1) {
2781 Value *PtrVal =
II->getArgOperand(0);
2783 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2788 case Intrinsic::masked_store:
2792 if (VT->getNumElements() == 1) {
2793 Value *PtrVal =
II->getArgOperand(1);
2795 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2802 SmallVector<Value *, 2> PtrOps;
2805 while (!PtrOps.
empty()) {
2808 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2822 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2824 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2834 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2835 if (!
F->getReturnType()->isPointerTy())
2838 GlobalVariable *UniformValue =
nullptr;
2839 for (
auto &BB : *
F) {
2844 else if (V != UniformValue)
2852 return UniformValue;
2855 if (
Callee->hasExactDefinition()) {
2856 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2857 bool MadeChange =
false;
2883 switch (
II->getIntrinsicID()) {
2884 case Intrinsic::memset:
2885 case Intrinsic::memcpy:
2886 case Intrinsic::memmove:
2894 if (Callee && TLInfo && TLInfo->
getLibFunc(*Callee, LF))
2896 case LibFunc_strcpy:
2897 case LibFunc_strncpy:
2898 case LibFunc_strcat:
2899 case LibFunc_strncat:
2940bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
2941 ModifyDT &ModifiedDT) {
2949 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2951 PHINode *PN =
nullptr;
2952 ExtractValueInst *EVI =
nullptr;
2953 BitCastInst *BCI =
nullptr;
2973 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
2979 return II->getIntrinsicID() == Intrinsic::lifetime_end;
2985 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
2987 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
3009 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
3059 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
3061 if (!VisitedBBs.
insert(Pred).second)
3063 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
3081 for (
auto const &TailCallBB : TailCallBBs) {
3091 BFI->getBlockFreq(BB) >=
BFI->getBlockFreq(TailCallBB));
3092 BFI->setBlockFreq(BB,
3093 (
BFI->getBlockFreq(BB) -
BFI->getBlockFreq(TailCallBB)));
3094 ModifiedDT = ModifyDT::ModifyBBDT;
3103 for (
auto *CI : CallInsts) {
3104 for (
auto const *FakeUse : FakeUses) {
3105 auto *ClonedInst = FakeUse->clone();
3123struct ExtAddrMode :
public TargetLowering::AddrMode {
3124 Value *BaseReg =
nullptr;
3125 Value *ScaledReg =
nullptr;
3126 Value *OriginalValue =
nullptr;
3127 bool InBounds =
true;
3131 BaseRegField = 0x01,
3133 BaseOffsField = 0x04,
3134 ScaledRegField = 0x08,
3136 MultipleFields = 0xff
3139 ExtAddrMode() =
default;
3141 void print(raw_ostream &OS)
const;
3148 if (ScaledReg == From)
3152 FieldName
compare(
const ExtAddrMode &other) {
3155 if (BaseReg && other.
BaseReg &&
3157 return MultipleFields;
3158 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3159 return MultipleFields;
3162 return MultipleFields;
3165 if (InBounds != other.InBounds)
3166 return MultipleFields;
3169 unsigned Result = NoField;
3172 if (BaseGV != other.BaseGV)
3174 if (BaseOffs != other.BaseOffs)
3177 Result |= ScaledRegField;
3180 if (Scale && other.
Scale && Scale != other.
Scale)
3184 return MultipleFields;
3186 return static_cast<FieldName
>(
Result);
3196 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3207 case ScaledRegField:
3214 void SetCombinedField(FieldName
Field,
Value *V,
3215 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3220 case ExtAddrMode::BaseRegField:
3223 case ExtAddrMode::BaseGVField:
3226 assert(BaseReg ==
nullptr);
3230 case ExtAddrMode::ScaledRegField:
3235 for (
const ExtAddrMode &AM : AddrModes)
3241 case ExtAddrMode::BaseOffsField:
3244 assert(ScaledReg ==
nullptr);
3254static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3260#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3261void ExtAddrMode::print(raw_ostream &OS)
const {
3262 bool NeedPlus =
false;
3268 BaseGV->printAsOperand(OS,
false);
3273 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3278 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3279 BaseReg->printAsOperand(OS,
false);
3283 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3306class TypePromotionTransaction {
3310 class TypePromotionAction {
3318 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3320 virtual ~TypePromotionAction() =
default;
3327 virtual void undo() = 0;
3332 virtual void commit() {
3338 class InsertionHandler {
3347 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3350 bool HasPrevInstruction;
3354 InsertionHandler(Instruction *Inst) {
3362 if (HasPrevInstruction) {
3370 void insert(Instruction *Inst) {
3371 if (HasPrevInstruction) {
3383 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3388 class InstructionMoveBefore :
public TypePromotionAction {
3390 InsertionHandler Position;
3395 : TypePromotionAction(Inst), Position(Inst) {
3396 LLVM_DEBUG(
dbgs() <<
"Do: move: " << *Inst <<
"\nbefore: " << *Before
3402 void undo()
override {
3404 Position.insert(Inst);
3409 class OperandSetter :
public TypePromotionAction {
3418 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3419 : TypePromotionAction(Inst), Idx(Idx) {
3421 <<
"for:" << *Inst <<
"\n"
3422 <<
"with:" << *NewVal <<
"\n");
3428 void undo()
override {
3430 <<
"for: " << *Inst <<
"\n"
3431 <<
"with: " << *Origin <<
"\n");
3438 class OperandsHider :
public TypePromotionAction {
3444 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3447 OriginalValues.
reserve(NumOpnds);
3448 for (
unsigned It = 0; It < NumOpnds; ++It) {
3460 void undo()
override {
3462 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3468 class TruncBuilder :
public TypePromotionAction {
3475 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3477 Builder.SetCurrentDebugLocation(
DebugLoc());
3478 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3483 Value *getBuiltValue() {
return Val; }
3486 void undo()
override {
3489 IVal->eraseFromParent();
3494 class SExtBuilder :
public TypePromotionAction {
3501 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3502 : TypePromotionAction(InsertPt) {
3504 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3509 Value *getBuiltValue() {
return Val; }
3512 void undo()
override {
3515 IVal->eraseFromParent();
3520 class ZExtBuilder :
public TypePromotionAction {
3527 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3528 : TypePromotionAction(InsertPt) {
3530 Builder.SetCurrentDebugLocation(
DebugLoc());
3531 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3536 Value *getBuiltValue() {
return Val; }
3539 void undo()
override {
3542 IVal->eraseFromParent();
3547 class TypeMutator :
public TypePromotionAction {
3553 TypeMutator(Instruction *Inst,
Type *NewTy)
3554 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3555 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3561 void undo()
override {
3562 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3569 class UsesReplacer :
public TypePromotionAction {
3571 struct InstructionAndIdx {
3578 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3579 : Inst(Inst), Idx(Idx) {}
3585 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3595 UsesReplacer(Instruction *Inst,
Value *New)
3596 : TypePromotionAction(Inst),
New(
New) {
3597 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3600 for (Use &U : Inst->
uses()) {
3602 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3613 void undo()
override {
3615 for (InstructionAndIdx &Use : OriginalUses)
3616 Use.Inst->setOperand(
Use.Idx, Inst);
3621 for (DbgVariableRecord *DVR : DbgVariableRecords)
3622 DVR->replaceVariableLocationOp(New, Inst);
3627 class InstructionRemover :
public TypePromotionAction {
3629 InsertionHandler Inserter;
3633 OperandsHider Hider;
3636 UsesReplacer *Replacer =
nullptr;
3639 SetOfInstrs &RemovedInsts;
3646 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3647 Value *New =
nullptr)
3648 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3649 RemovedInsts(RemovedInsts) {
3651 Replacer =
new UsesReplacer(Inst, New);
3652 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3653 RemovedInsts.insert(Inst);
3660 ~InstructionRemover()
override {
delete Replacer; }
3662 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3663 InstructionRemover(
const InstructionRemover &other) =
delete;
3667 void undo()
override {
3668 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3669 Inserter.insert(Inst);
3673 RemovedInsts.erase(Inst);
3681 using ConstRestorationPt =
const TypePromotionAction *;
3683 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3684 : RemovedInsts(RemovedInsts) {}
3691 void rollback(ConstRestorationPt Point);
3694 ConstRestorationPt getRestorationPoint()
const;
3699 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3708 void mutateType(Instruction *Inst,
Type *NewTy);
3711 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3724 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3726 SetOfInstrs &RemovedInsts;
3731void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3733 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3734 Inst, Idx, NewVal));
3737void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3740 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3741 Inst, RemovedInsts, NewVal));
3744void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3747 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3750void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3752 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3755Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3756 std::unique_ptr<TruncBuilder>
Ptr(
new TruncBuilder(Opnd, Ty));
3758 Actions.push_back(std::move(
Ptr));
3762Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3764 std::unique_ptr<SExtBuilder>
Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3766 Actions.push_back(std::move(
Ptr));
3770Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3772 std::unique_ptr<ZExtBuilder>
Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3774 Actions.push_back(std::move(
Ptr));
3778TypePromotionTransaction::ConstRestorationPt
3779TypePromotionTransaction::getRestorationPoint()
const {
3780 return !Actions.empty() ? Actions.back().get() :
nullptr;
3783bool TypePromotionTransaction::commit() {
3784 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3791void TypePromotionTransaction::rollback(
3792 TypePromotionTransaction::ConstRestorationPt Point) {
3793 while (!Actions.empty() && Point != Actions.back().get()) {
3794 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3804class AddressingModeMatcher {
3805 SmallVectorImpl<Instruction *> &AddrModeInsts;
3806 const TargetLowering &TLI;
3807 const TargetRegisterInfo &
TRI;
3808 const DataLayout &
DL;
3810 const std::function<
const DominatorTree &()> getDTFn;
3823 const SetOfInstrs &InsertedInsts;
3826 InstrToOrigTy &PromotedInsts;
3829 TypePromotionTransaction &TPT;
3832 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3836 bool IgnoreProfitability;
3839 bool OptSize =
false;
3841 ProfileSummaryInfo *PSI;
3842 BlockFrequencyInfo *
BFI;
3844 AddressingModeMatcher(
3845 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3846 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3847 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3848 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3849 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3850 TypePromotionTransaction &TPT,
3851 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3852 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI)
3853 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
3854 DL(
MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
3855 AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
AddrMode(AM),
3856 InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
3857 LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI),
BFI(
BFI) {
3858 IgnoreProfitability =
false;
3870 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3871 SmallVectorImpl<Instruction *> &AddrModeInsts,
3872 const TargetLowering &TLI,
const LoopInfo &LI,
3873 const std::function<
const DominatorTree &()> getDTFn,
3874 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3875 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3876 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3877 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
3880 bool Success = AddressingModeMatcher(AddrModeInsts, TLI,
TRI, LI, getDTFn,
3881 AccessTy, AS, MemoryInst, Result,
3882 InsertedInsts, PromotedInsts, TPT,
3883 LargeOffsetGEP, OptSize, PSI, BFI)
3891 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3893 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3894 bool *MovedAway =
nullptr);
3895 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3896 ExtAddrMode &AMBefore,
3897 ExtAddrMode &AMAfter);
3898 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3899 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3900 Value *PromotedOperand)
const;
3906class PhiNodeSetIterator {
3907 PhiNodeSet *
const Set;
3908 size_t CurrentIndex = 0;
3913 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3915 PhiNodeSetIterator &operator++();
3931 friend class PhiNodeSetIterator;
3933 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3934 using iterator = PhiNodeSetIterator;
3949 size_t FirstValidElement = 0;
3955 bool insert(PHINode *
Ptr) {
3967 if (NodeMap.erase(
Ptr)) {
3968 SkipRemovedElements(FirstValidElement);
3978 FirstValidElement = 0;
3984 if (FirstValidElement == 0)
3985 SkipRemovedElements(FirstValidElement);
3986 return PhiNodeSetIterator(
this, FirstValidElement);
3993 size_t size()
const {
return NodeMap.size(); }
3996 size_t count(PHINode *
Ptr)
const {
return NodeMap.count(
Ptr); }
4004 void SkipRemovedElements(
size_t &CurrentIndex) {
4006 auto it = NodeMap.find(NodeList[CurrentIndex]);
4009 if (it != NodeMap.end() && it->second == CurrentIndex)
4016PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
4019PHINode *PhiNodeSetIterator::operator*()
const {
4021 "PhiNodeSet access out of range");
4022 return Set->NodeList[CurrentIndex];
4025PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
4027 "PhiNodeSet access out of range");
4029 Set->SkipRemovedElements(CurrentIndex);
4033bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
4034 return CurrentIndex ==
RHS.CurrentIndex;
4037bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
4038 return !((*this) ==
RHS);
4044class SimplificationTracker {
4045 DenseMap<Value *, Value *> Storage;
4048 PhiNodeSet AllPhiNodes;
4050 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
4055 auto SV = Storage.
find(V);
4056 if (SV == Storage.
end())
4064 void ReplacePhi(PHINode *From, PHINode *To) {
4065 Value *OldReplacement = Get(From);
4066 while (OldReplacement != From) {
4069 OldReplacement = Get(From);
4071 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
4074 AllPhiNodes.erase(From);
4078 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
4080 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
4082 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
4084 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4086 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4088 void destroyNewNodes(
Type *CommonType) {
4091 for (
auto *
I : AllPhiNodes) {
4092 I->replaceAllUsesWith(Dummy);
4093 I->eraseFromParent();
4095 AllPhiNodes.clear();
4096 for (
auto *
I : AllSelectNodes) {
4097 I->replaceAllUsesWith(Dummy);
4098 I->eraseFromParent();
4100 AllSelectNodes.clear();
4105class AddressingModeCombiner {
4106 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4107 typedef std::pair<PHINode *, PHINode *> PHIPair;
4114 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4117 bool AllAddrModesTrivial =
true;
4120 Type *CommonType =
nullptr;
4122 const DataLayout &
DL;
4128 Value *CommonValue =
nullptr;
4131 AddressingModeCombiner(
const DataLayout &
DL,
Value *OriginalValue)
4132 :
DL(
DL), Original(OriginalValue) {}
4134 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4137 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4142 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4146 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4149 if (AddrModes.
empty()) {
4157 ExtAddrMode::FieldName ThisDifferentField =
4158 AddrModes[0].compare(NewAddrMode);
4159 if (DifferentField == ExtAddrMode::NoField)
4160 DifferentField = ThisDifferentField;
4161 else if (DifferentField != ThisDifferentField)
4162 DifferentField = ExtAddrMode::MultipleFields;
4165 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4168 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4173 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4178 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4179 !NewAddrMode.HasBaseReg);
4196 bool combineAddrModes() {
4198 if (AddrModes.
size() == 0)
4202 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4207 if (AllAddrModesTrivial)
4210 if (!addrModeCombiningAllowed())
4216 FoldAddrToValueMapping
Map;
4217 if (!initializeMap(Map))
4220 CommonValue = findCommon(Map);
4222 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4223 return CommonValue !=
nullptr;
4229 void eraseCommonValueIfDead() {
4230 if (CommonValue && CommonValue->
use_empty())
4232 CommonInst->eraseFromParent();
4240 bool initializeMap(FoldAddrToValueMapping &Map) {
4243 SmallVector<Value *, 2> NullValue;
4244 Type *IntPtrTy =
DL.getIntPtrType(AddrModes[0].OriginalValue->
getType());
4245 for (
auto &AM : AddrModes) {
4246 Value *DV = AM.GetFieldAsValue(DifferentField, IntPtrTy);
4249 if (CommonType && CommonType !=
Type)
4252 Map[AM.OriginalValue] = DV;
4257 assert(CommonType &&
"At least one non-null value must be!");
4258 for (
auto *V : NullValue)
4286 Value *findCommon(FoldAddrToValueMapping &Map) {
4294 SimplificationTracker
ST;
4299 InsertPlaceholders(Map, TraverseOrder, ST);
4302 FillPlaceholders(Map, TraverseOrder, ST);
4305 ST.destroyNewNodes(CommonType);
4310 unsigned PhiNotMatchedCount = 0;
4312 ST.destroyNewNodes(CommonType);
4316 auto *
Result =
ST.Get(
Map.find(Original)->second);
4318 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4319 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4326 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4327 SmallSetVector<PHIPair, 8> &Matcher,
4328 PhiNodeSet &PhiNodesToMatch) {
4331 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4334 SmallSet<PHIPair, 8> Visited;
4335 while (!WorkList.
empty()) {
4337 if (!Visited.
insert(Item).second)
4344 for (
auto *
B : Item.first->blocks()) {
4345 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4346 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4347 if (FirstValue == SecondValue)
4357 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4362 if (Matcher.
count({FirstPhi, SecondPhi}))
4367 if (MatchedPHIs.
insert(FirstPhi).second)
4368 Matcher.
insert({FirstPhi, SecondPhi});
4370 WorkList.
push_back({FirstPhi, SecondPhi});
4379 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4380 unsigned &PhiNotMatchedCount) {
4384 SmallSetVector<PHIPair, 8> Matched;
4385 SmallPtrSet<PHINode *, 8> WillNotMatch;
4386 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4387 while (PhiNodesToMatch.size()) {
4388 PHINode *
PHI = *PhiNodesToMatch.begin();
4391 WillNotMatch.
clear();
4395 bool IsMatched =
false;
4396 for (
auto &
P :
PHI->getParent()->phis()) {
4398 if (PhiNodesToMatch.count(&
P))
4400 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4410 for (
auto MV : Matched)
4411 ST.ReplacePhi(MV.first, MV.second);
4416 if (!AllowNewPhiNodes)
4419 PhiNotMatchedCount += WillNotMatch.
size();
4420 for (
auto *
P : WillNotMatch)
4421 PhiNodesToMatch.erase(
P);
4426 void FillPlaceholders(FoldAddrToValueMapping &Map,
4427 SmallVectorImpl<Value *> &TraverseOrder,
4428 SimplificationTracker &ST) {
4429 while (!TraverseOrder.
empty()) {
4431 assert(
Map.contains(Current) &&
"No node to fill!!!");
4437 auto *TrueValue = CurrentSelect->getTrueValue();
4438 assert(
Map.contains(TrueValue) &&
"No True Value!");
4439 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4440 auto *FalseValue = CurrentSelect->getFalseValue();
4441 assert(
Map.contains(FalseValue) &&
"No False Value!");
4442 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4449 assert(
Map.contains(PV) &&
"No predecessor Value!");
4450 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4461 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4462 SmallVectorImpl<Value *> &TraverseOrder,
4463 SimplificationTracker &ST) {
4466 "Address must be a Phi or Select node");
4469 while (!Worklist.
empty()) {
4472 if (
Map.contains(Current))
4483 CurrentSelect->getName(),
4484 CurrentSelect->getIterator(), CurrentSelect);
4488 Worklist.
push_back(CurrentSelect->getTrueValue());
4489 Worklist.
push_back(CurrentSelect->getFalseValue());
4497 ST.insertNewPhi(
PHI);
4503 bool addrModeCombiningAllowed() {
4506 switch (DifferentField) {
4509 case ExtAddrMode::BaseRegField:
4511 case ExtAddrMode::BaseGVField:
4513 case ExtAddrMode::BaseOffsField:
4515 case ExtAddrMode::ScaledRegField:
4525bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4530 return matchAddr(ScaleReg,
Depth);
4541 ExtAddrMode TestAddrMode =
AddrMode;
4545 TestAddrMode.
Scale += Scale;
4559 ConstantInt *CI =
nullptr;
4560 Value *AddLHS =
nullptr;
4564 TestAddrMode.InBounds =
false;
4581 auto GetConstantStep =
4582 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4585 return std::nullopt;
4588 return std::nullopt;
4596 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4597 return std::nullopt;
4599 return std::make_pair(IVInc->first, ConstantStep->getValue());
4600 return std::nullopt;
4615 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4622 APInt Step = IVStep->second;
4624 if (
Offset.isSignedIntN(64)) {
4625 TestAddrMode.InBounds =
false;
4627 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4632 getDTFn().
dominates(IVInc, MemoryInst)) {
4652 switch (
I->getOpcode()) {
4653 case Instruction::BitCast:
4654 case Instruction::AddrSpaceCast:
4656 if (
I->getType() ==
I->getOperand(0)->getType())
4658 return I->getType()->isIntOrPtrTy();
4659 case Instruction::PtrToInt:
4662 case Instruction::IntToPtr:
4665 case Instruction::Add:
4667 case Instruction::Mul:
4668 case Instruction::Shl:
4671 case Instruction::GetElementPtr:
4699class TypePromotionHelper {
4702 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4703 Instruction *ExtOpnd,
bool IsSExt) {
4704 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4705 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4709 if (It->second.getInt() == ExtTy)
4715 ExtTy = BothExtension;
4717 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4724 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4725 Instruction *Opnd,
bool IsSExt) {
4726 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4727 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4728 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4729 return It->second.getPointer();
4744 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4745 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4749 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4762 static Value *promoteOperandForTruncAndAnyExt(
4763 Instruction *Ext, TypePromotionTransaction &TPT,
4764 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4765 SmallVectorImpl<Instruction *> *Exts,
4766 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4777 static Value *promoteOperandForOther(Instruction *Ext,
4778 TypePromotionTransaction &TPT,
4779 InstrToOrigTy &PromotedInsts,
4780 unsigned &CreatedInstsCost,
4781 SmallVectorImpl<Instruction *> *Exts,
4782 SmallVectorImpl<Instruction *> *Truncs,
4783 const TargetLowering &TLI,
bool IsSExt);
4786 static Value *signExtendOperandForOther(
4787 Instruction *Ext, TypePromotionTransaction &TPT,
4788 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4789 SmallVectorImpl<Instruction *> *Exts,
4790 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4791 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4792 Exts, Truncs, TLI,
true);
4796 static Value *zeroExtendOperandForOther(
4797 Instruction *Ext, TypePromotionTransaction &TPT,
4798 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4799 SmallVectorImpl<Instruction *> *Exts,
4800 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4801 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4802 Exts, Truncs, TLI,
false);
4807 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4808 InstrToOrigTy &PromotedInsts,
4809 unsigned &CreatedInstsCost,
4810 SmallVectorImpl<Instruction *> *Exts,
4811 SmallVectorImpl<Instruction *> *Truncs,
4812 const TargetLowering &TLI);
4823 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4824 const TargetLowering &TLI,
4825 const InstrToOrigTy &PromotedInsts);
4830bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4831 Type *ConsideredExtType,
4832 const InstrToOrigTy &PromotedInsts,
4852 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4853 (IsSExt && BinOp->hasNoSignedWrap())))
4857 if ((Inst->
getOpcode() == Instruction::And ||
4862 if (Inst->
getOpcode() == Instruction::Xor) {
4865 if (!Cst->getValue().isAllOnes())
4874 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4884 if (ExtInst->hasOneUse()) {
4886 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4919 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4932TypePromotionHelper::Action TypePromotionHelper::getAction(
4933 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4934 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
4936 "Unexpected instruction type");
4943 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4956 return promoteOperandForTruncAndAnyExt;
4962 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4965Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4966 Instruction *SExt, TypePromotionTransaction &TPT,
4967 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4968 SmallVectorImpl<Instruction *> *Exts,
4969 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4973 Value *ExtVal = SExt;
4974 bool HasMergedNonFreeExt =
false;
4978 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
4981 TPT.replaceAllUsesWith(SExt, ZExt);
4982 TPT.eraseInstruction(SExt);
4987 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
4989 CreatedInstsCost = 0;
4993 TPT.eraseInstruction(SExtOpnd);
5001 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
5009 TPT.eraseInstruction(ExtInst, NextVal);
5013Value *TypePromotionHelper::promoteOperandForOther(
5014 Instruction *Ext, TypePromotionTransaction &TPT,
5015 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
5016 SmallVectorImpl<Instruction *> *Exts,
5017 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
5022 CreatedInstsCost = 0;
5028 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
5031 ITrunc->moveAfter(ExtOpnd);
5036 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
5039 TPT.setOperand(Ext, 0, ExtOpnd);
5049 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
5051 TPT.mutateType(ExtOpnd,
Ext->getType());
5053 TPT.replaceAllUsesWith(Ext, ExtOpnd);
5060 !shouldExtOperand(ExtOpnd,
OpIdx)) {
5068 unsigned BitWidth =
Ext->getType()->getIntegerBitWidth();
5069 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
5071 TPT.setOperand(ExtOpnd,
OpIdx, ConstantInt::get(
Ext->getType(), CstVal));
5082 Value *ValForExtOpnd = IsSExt
5083 ? TPT.createSExt(ExtOpnd, Opnd,
Ext->getType())
5084 : TPT.createZExt(ExtOpnd, Opnd,
Ext->getType());
5085 TPT.setOperand(ExtOpnd,
OpIdx, ValForExtOpnd);
5087 if (!InstForExtOpnd)
5093 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5096 TPT.eraseInstruction(Ext);
5108bool AddressingModeMatcher::isPromotionProfitable(
5109 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5110 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5115 if (NewCost > OldCost)
5117 if (NewCost < OldCost)
5136bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5148 case Instruction::PtrToInt:
5151 case Instruction::IntToPtr: {
5159 case Instruction::BitCast:
5169 case Instruction::AddrSpaceCast: {
5177 case Instruction::Add: {
5180 ExtAddrMode BackupAddrMode =
AddrMode;
5181 unsigned OldSize = AddrModeInsts.
size();
5186 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5187 TPT.getRestorationPoint();
5191 int First = 0, Second = 1;
5202 AddrModeInsts.
resize(OldSize);
5203 TPT.rollback(LastKnownGood);
5213 AddrModeInsts.
resize(OldSize);
5214 TPT.rollback(LastKnownGood);
5220 case Instruction::Mul:
5221 case Instruction::Shl: {
5225 if (!
RHS ||
RHS->getBitWidth() > 64)
5227 int64_t Scale = Opcode == Instruction::Shl
5228 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5229 :
RHS->getSExtValue();
5233 case Instruction::GetElementPtr: {
5236 int VariableOperand = -1;
5237 unsigned VariableScale = 0;
5239 int64_t ConstantOffset = 0;
5241 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5243 const StructLayout *SL =
DL.getStructLayout(STy);
5254 if (ConstantInt *CI =
5256 const APInt &CVal = CI->
getValue();
5263 if (VariableOperand != -1)
5267 VariableOperand = i;
5268 VariableScale = TypeSize;
5275 if (VariableOperand == -1) {
5276 AddrMode.BaseOffs += ConstantOffset;
5282 AddrMode.BaseOffs -= ConstantOffset;
5286 ConstantOffset > 0) {
5299 BasicBlock *Parent = BaseI ? BaseI->getParent()
5300 : &
GEP->getFunction()->getEntryBlock();
5302 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5310 ExtAddrMode BackupAddrMode =
AddrMode;
5311 unsigned OldSize = AddrModeInsts.
size();
5314 AddrMode.BaseOffs += ConstantOffset;
5323 AddrModeInsts.
resize(OldSize);
5331 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5336 AddrModeInsts.
resize(OldSize);
5341 AddrMode.BaseOffs += ConstantOffset;
5342 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5343 VariableScale,
Depth)) {
5346 AddrModeInsts.
resize(OldSize);
5353 case Instruction::SExt:
5354 case Instruction::ZExt: {
5361 TypePromotionHelper::Action TPH =
5362 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5366 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5367 TPT.getRestorationPoint();
5368 unsigned CreatedInstsCost = 0;
5370 Value *PromotedOperand =
5371 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5386 assert(PromotedOperand &&
5387 "TypePromotionHelper should have filtered out those cases");
5389 ExtAddrMode BackupAddrMode =
AddrMode;
5390 unsigned OldSize = AddrModeInsts.
size();
5392 if (!matchAddr(PromotedOperand,
Depth) ||
5397 !isPromotionProfitable(CreatedInstsCost,
5398 ExtCost + (AddrModeInsts.
size() - OldSize),
5401 AddrModeInsts.
resize(OldSize);
5402 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5403 TPT.rollback(LastKnownGood);
5408 AddrMode.replaceWith(Ext, PromotedOperand);
5411 case Instruction::Call:
5413 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5429bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5432 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5433 TPT.getRestorationPoint();
5457 ExtAddrMode BackupAddrMode =
AddrMode;
5458 unsigned OldSize = AddrModeInsts.
size();
5461 bool MovedAway =
false;
5462 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5470 if (
I->hasOneUse() ||
5471 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5478 AddrModeInsts.
resize(OldSize);
5479 TPT.rollback(LastKnownGood);
5482 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5484 TPT.rollback(LastKnownGood);
5511 TPT.rollback(LastKnownGood);
5530 if (OpInfo.CallOperandVal == OpVal &&
5532 !OpInfo.isIndirect))
5548 if (!ConsideredInsts.
insert(
I).second)
5556 for (
Use &U :
I->uses()) {
5564 MemoryUses.push_back({&U, LI->getType()});
5571 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5578 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5585 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5595 if (!
find(PtrOps, U.get()))
5598 MemoryUses.push_back({&U, AccessTy});
5603 if (CI->hasFnAttr(Attribute::Cold)) {
5621 PSI, BFI, SeenInsts))
5632 unsigned SeenInsts = 0;
5635 PSI, BFI, SeenInsts);
5643bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5645 Value *KnownLive2) {
5647 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5688bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5689 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5690 if (IgnoreProfitability)
5708 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5709 ScaledReg =
nullptr;
5713 if (!BaseReg && !ScaledReg)
5734 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5737 Type *AddressAccessTy = Pair.second;
5738 unsigned AS =
Address->getType()->getPointerAddressSpace();
5744 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5746 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5747 TPT.getRestorationPoint();
5748 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5749 AddressAccessTy, AS, UserI, Result,
5750 InsertedInsts, PromotedInsts, TPT,
5751 LargeOffsetGEP, OptSize, PSI, BFI);
5752 Matcher.IgnoreProfitability =
true;
5760 TPT.rollback(LastKnownGood);
5766 MatchedAddrModeInsts.
clear();
5776 return I->getParent() != BB;
5792 return std::next(AddrInst->getIterator());
5803 Earliest = UserInst;
5828bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5829 Type *AccessTy,
unsigned AddrSpace) {
5834 SmallVector<Value *, 8> worklist;
5835 SmallPtrSet<Value *, 16> Visited;
5841 bool PhiOrSelectSeen =
false;
5842 SmallVector<Instruction *, 16> AddrModeInsts;
5843 AddressingModeCombiner AddrModes(*
DL, Addr);
5844 TypePromotionTransaction TPT(RemovedInsts);
5845 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5846 TPT.getRestorationPoint();
5847 while (!worklist.
empty()) {
5859 if (!Visited.
insert(V).second)
5865 PhiOrSelectSeen =
true;
5872 PhiOrSelectSeen =
true;
5879 AddrModeInsts.
clear();
5880 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5885 auto getDTFn = [MemoryInst,
this]() ->
const DominatorTree & {
5887 return this->getDT(*
F);
5889 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5890 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5891 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5894 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5899 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5900 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5903 NewAddrMode.OriginalValue =
V;
5904 if (!AddrModes.addNewAddrMode(NewAddrMode))
5911 if (!AddrModes.combineAddrModes()) {
5912 TPT.rollback(LastKnownGood);
5918 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5924 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5938 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
5960 <<
" for " << *MemoryInst <<
"\n");
5964 !
DL->isNonIntegralPointerType(Addr->
getType())) {
5970 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
5972 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
5974 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
5981 <<
" for " << *MemoryInst <<
"\n");
5982 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
5993 if (ResultPtr ||
AddrMode.Scale != 1)
6014 GlobalValue *BaseGV =
AddrMode.BaseGV;
6015 if (BaseGV !=
nullptr) {
6020 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
6029 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
6030 if (!ResultPtr &&
AddrMode.BaseReg) {
6034 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
6035 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
6044 }
else if (!ResultPtr) {
6057 if (
V->getType() != IntPtrTy)
6058 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6066 if (
V->getType() == IntPtrTy) {
6071 "We can't transform if ScaledReg is too narrow");
6072 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6076 V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy,
AddrMode.Scale),
6079 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6090 if (ResultPtr->
getType() != I8PtrTy)
6091 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6092 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6105 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6107 SunkAddr = ResultPtr;
6109 if (ResultPtr->
getType() != I8PtrTy)
6110 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6111 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6118 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6124 SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy,
"sunkaddr");
6126 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6128 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6138 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6139 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6140 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6142 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6146 <<
" for " << *MemoryInst <<
"\n");
6157 if (
V->getType()->isPointerTy())
6158 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6159 if (
V->getType() != IntPtrTy)
6160 V = Builder.CreateIntCast(V, IntPtrTy,
true,
"sunkaddr");
6167 if (
V->getType() == IntPtrTy) {
6169 }
else if (
V->getType()->isPointerTy()) {
6170 V = Builder.CreatePtrToInt(V, IntPtrTy,
"sunkaddr");
6173 V = Builder.CreateTrunc(V, IntPtrTy,
"sunkaddr");
6182 I->eraseFromParent();
6186 V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy,
AddrMode.Scale),
6189 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6195 GlobalValue *BaseGV =
AddrMode.BaseGV;
6196 if (BaseGV !=
nullptr) {
6199 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6203 Value *
V = Builder.CreatePtrToInt(BaseGVPtr, IntPtrTy,
"sunkaddr");
6205 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6214 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6222 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6228 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6233 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6234 RecursivelyDeleteTriviallyDeadInstructions(
6235 Repl, TLInfo, nullptr,
6236 [&](Value *V) { removeAllAssertingVHReferences(V); });
6260bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6266 if (!
GEP->hasIndices())
6274 SmallVector<Value *, 2>
Ops(
GEP->operands());
6276 bool RewriteGEP =
false;
6285 unsigned FinalIndex =
Ops.size() - 1;
6290 for (
unsigned i = 1; i < FinalIndex; ++i) {
6295 C =
C->getSplatValue();
6297 if (!CI || !CI->
isZero())
6304 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6308 if (!
C || !
C->isZero()) {
6309 Ops[FinalIndex] =
V;
6317 if (!RewriteGEP &&
Ops.size() == 2)
6324 Type *SourceTy =
GEP->getSourceElementType();
6325 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6329 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6330 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6331 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6341 if (
Ops.size() != 2) {
6351 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6365 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6366 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6369 Intrinsic::masked_gather) {
6373 Intrinsic::masked_scatter);
6386 if (
Ptr->use_empty())
6388 Ptr, TLInfo,
nullptr,
6389 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6396bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6397 bool MadeChange =
false;
6399 const TargetRegisterInfo *
TRI =
6400 TM->getSubtargetImpl(*CS->
getFunction())->getRegisterInfo();
6404 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6410 OpInfo.isIndirect) {
6412 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6475bool CodeGenPrepare::tryToPromoteExts(
6476 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6477 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6478 unsigned CreatedInstsCost) {
6479 bool Promoted =
false;
6482 for (
auto *
I : Exts) {
6497 TypePromotionHelper::Action TPH =
6498 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6507 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6508 TPT.getRestorationPoint();
6509 SmallVector<Instruction *, 4> NewExts;
6510 unsigned NewCreatedInstsCost = 0;
6513 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6514 &NewExts,
nullptr, *TLI);
6516 "TypePromotionHelper should have filtered out those cases");
6526 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6529 TotalCreatedInstsCost =
6530 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6532 (TotalCreatedInstsCost > 1 ||
6534 (ExtCost == 0 && NewExts.
size() > 1))) {
6538 TPT.rollback(LastKnownGood);
6543 SmallVector<Instruction *, 2> NewlyMovedExts;
6544 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6545 bool NewPromoted =
false;
6546 for (
auto *ExtInst : NewlyMovedExts) {
6556 ProfitablyMovedExts.
push_back(MovedExt);
6563 TPT.rollback(LastKnownGood);
6574bool CodeGenPrepare::mergeSExts(Function &
F) {
6576 for (
auto &Entry : ValToSExtendedUses) {
6577 SExts &Insts =
Entry.second;
6579 for (Instruction *Inst : Insts) {
6583 bool inserted =
false;
6584 for (
auto &Pt : CurPts) {
6587 RemovedInsts.insert(Pt);
6588 Pt->removeFromParent();
6599 RemovedInsts.insert(Inst);
6606 CurPts.push_back(Inst);
6648bool CodeGenPrepare::splitLargeGEPOffsets() {
6650 for (
auto &Entry : LargeOffsetGEPMap) {
6652 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6653 &LargeOffsetGEPs =
Entry.second;
6654 auto compareGEPOffset =
6655 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6656 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6657 if (
LHS.first ==
RHS.first)
6659 if (
LHS.second !=
RHS.second)
6660 return LHS.second <
RHS.second;
6661 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6664 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6667 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6669 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6670 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6671 Value *NewBaseGEP =
nullptr;
6673 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6674 GetElementPtrInst *
GEP) {
6675 LLVMContext &Ctx =
GEP->getContext();
6676 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6678 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6690 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), DT.get(), LI);
6693 NewBaseInsertPt = std::next(BaseI->getIterator());
6700 IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
6702 Value *BaseIndex = ConstantInt::get(PtrIdxTy, BaseOffset);
6703 NewBaseGEP = OldBase;
6704 if (NewBaseGEP->
getType() != I8PtrTy)
6705 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6707 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6708 NewGEPBases.
insert(NewBaseGEP);
6714 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6715 BaseOffset = PreferBase;
6718 createNewBase(BaseOffset, OldBase, BaseGEP);
6721 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6722 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6723 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6724 int64_t
Offset = LargeOffsetGEP->second;
6725 if (
Offset != BaseOffset) {
6732 GEP->getResultElementType(),
6733 GEP->getAddressSpace())) {
6739 NewBaseGEP =
nullptr;
6744 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6749 createNewBase(BaseOffset, OldBase,
GEP);
6753 Value *NewGEP = NewBaseGEP;
6754 if (
Offset != BaseOffset) {
6757 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6761 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6762 GEP->eraseFromParent();
6769bool CodeGenPrepare::optimizePhiType(
6770 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
6771 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
6776 Type *PhiTy =
I->getType();
6777 Type *ConvertTy =
nullptr;
6779 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6782 SmallVector<Instruction *, 4> Worklist;
6784 SmallPtrSet<PHINode *, 4> PhiNodes;
6785 SmallPtrSet<ConstantData *, 4>
Constants;
6788 SmallPtrSet<Instruction *, 4> Defs;
6789 SmallPtrSet<Instruction *, 4>
Uses;
6795 bool AnyAnchored =
false;
6797 while (!Worklist.
empty()) {
6802 for (
Value *V :
Phi->incoming_values()) {
6804 if (!PhiNodes.
count(OpPhi)) {
6805 if (!Visited.
insert(OpPhi).second)
6811 if (!OpLoad->isSimple())
6813 if (Defs.
insert(OpLoad).second)
6816 if (Defs.
insert(OpEx).second)
6820 ConvertTy = OpBC->getOperand(0)->getType();
6821 if (OpBC->getOperand(0)->getType() != ConvertTy)
6823 if (Defs.
insert(OpBC).second) {
6836 for (User *V :
II->users()) {
6838 if (!PhiNodes.
count(OpPhi)) {
6839 if (Visited.
count(OpPhi))
6846 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
6848 Uses.insert(OpStore);
6851 ConvertTy = OpBC->getType();
6852 if (OpBC->getType() != ConvertTy)
6856 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
6863 if (!ConvertTy || !AnyAnchored ||
6867 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
6868 << *ConvertTy <<
"\n");
6873 for (ConstantData *
C : Constants)
6875 for (Instruction *
D : Defs) {
6877 ValMap[
D] =
D->getOperand(0);
6881 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
6884 for (PHINode *Phi : PhiNodes)
6886 Phi->getName() +
".tc",
Phi->getIterator());
6888 for (PHINode *Phi : PhiNodes) {
6890 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
6892 Phi->getIncomingBlock(i));
6896 for (Instruction *U :
Uses) {
6901 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
6911bool CodeGenPrepare::optimizePhiTypes(Function &
F) {
6916 SmallPtrSet<PHINode *, 4> Visited;
6917 SmallPtrSet<Instruction *, 4> DeletedInstrs;
6921 for (
auto &Phi : BB.
phis())
6922 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
6925 for (
auto *
I : DeletedInstrs) {
6927 I->eraseFromParent();
6935bool CodeGenPrepare::canFormExtLd(
6936 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
6937 Instruction *&Inst,
bool HasPromoted) {
6938 for (
auto *MovedExtInst : MovedExts) {
6941 Inst = MovedExtInst;
6993bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
6994 bool AllowPromotionWithoutCommonHeader =
false;
6999 *Inst, AllowPromotionWithoutCommonHeader);
7000 TypePromotionTransaction TPT(RemovedInsts);
7001 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7002 TPT.getRestorationPoint();
7004 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7007 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7010 LoadInst *LI =
nullptr;
7015 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7016 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7021 Inst = ExtFedByLoad;
7026 if (ATPConsiderable &&
7027 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7028 HasPromoted, TPT, SpeculativelyMovedExts))
7031 TPT.rollback(LastKnownGood);
7040bool CodeGenPrepare::performAddressTypePromotion(
7041 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7042 bool HasPromoted, TypePromotionTransaction &TPT,
7043 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7044 bool Promoted =
false;
7045 SmallPtrSet<Instruction *, 1> UnhandledExts;
7046 bool AllSeenFirst =
true;
7047 for (
auto *
I : SpeculativelyMovedExts) {
7048 Value *HeadOfChain =
I->getOperand(0);
7049 DenseMap<Value *, Instruction *>::iterator AlreadySeen =
7050 SeenChainsForSExt.
find(HeadOfChain);
7053 if (AlreadySeen != SeenChainsForSExt.
end()) {
7054 if (AlreadySeen->second !=
nullptr)
7055 UnhandledExts.
insert(AlreadySeen->second);
7056 AllSeenFirst =
false;
7060 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7061 SpeculativelyMovedExts.size() == 1)) {
7065 for (
auto *
I : SpeculativelyMovedExts) {
7066 Value *HeadOfChain =
I->getOperand(0);
7067 SeenChainsForSExt[HeadOfChain] =
nullptr;
7068 ValToSExtendedUses[HeadOfChain].push_back(
I);
7071 Inst = SpeculativelyMovedExts.pop_back_val();
7076 for (
auto *
I : SpeculativelyMovedExts) {
7077 Value *HeadOfChain =
I->getOperand(0);
7078 SeenChainsForSExt[HeadOfChain] = Inst;
7083 if (!AllSeenFirst && !UnhandledExts.
empty())
7084 for (
auto *VisitedSExt : UnhandledExts) {
7085 if (RemovedInsts.count(VisitedSExt))
7087 TypePromotionTransaction TPT(RemovedInsts);
7089 SmallVector<Instruction *, 2> Chains;
7091 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7095 for (
auto *
I : Chains) {
7096 Value *HeadOfChain =
I->getOperand(0);
7098 SeenChainsForSExt[HeadOfChain] =
nullptr;
7099 ValToSExtendedUses[HeadOfChain].push_back(
I);
7105bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7110 Value *Src =
I->getOperand(0);
7111 if (Src->hasOneUse())
7123 bool DefIsLiveOut =
false;
7124 for (User *U :
I->users()) {
7129 if (UserBB == DefBB)
7131 DefIsLiveOut =
true;
7138 for (User *U : Src->users()) {
7141 if (UserBB == DefBB)
7150 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7152 bool MadeChange =
false;
7153 for (Use &U : Src->uses()) {
7158 if (UserBB == DefBB)
7162 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7164 if (!InsertedTrunc) {
7167 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7169 InsertedInsts.insert(InsertedTrunc);
7232bool CodeGenPrepare::optimizeLoadExt(LoadInst *Load) {
7233 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7237 if (
Load->hasOneUse() &&
7243 SmallVector<Instruction *, 8> WorkList;
7244 SmallPtrSet<Instruction *, 16> Visited;
7245 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7246 SmallVector<Instruction *, 8> DropFlags;
7247 for (
auto *U :
Load->users())
7259 while (!WorkList.
empty()) {
7263 if (!Visited.
insert(
I).second)
7268 for (
auto *U :
Phi->users())
7273 switch (
I->getOpcode()) {
7274 case Instruction::And: {
7278 APInt AndBits = AndC->getValue();
7279 DemandBits |= AndBits;
7281 if (AndBits.
ugt(WidestAndBits))
7282 WidestAndBits = AndBits;
7283 if (AndBits == WidestAndBits &&
I->getOperand(0) == Load)
7288 case Instruction::Shl: {
7292 uint64_t ShiftAmt = ShlC->getLimitedValue(
BitWidth - 1);
7293 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7298 case Instruction::Trunc: {
7301 DemandBits.setLowBits(TruncBitWidth);
7311 uint32_t ActiveBits = DemandBits.getActiveBits();
7323 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7324 WidestAndBits != DemandBits)
7327 LLVMContext &Ctx =
Load->getType()->getContext();
7328 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7338 Builder.CreateAnd(Load, ConstantInt::get(Ctx, DemandBits)));
7341 InsertedInsts.insert(NewAnd);
7346 NewAnd->setOperand(0, Load);
7349 for (
auto *
And : AndsToMaybeRemove)
7354 if (&*CurInstIterator ==
And)
7355 CurInstIterator = std::next(
And->getIterator());
7356 And->eraseFromParent();
7361 for (
auto *Inst : DropFlags)
7375 TTI->isExpensiveToSpeculativelyExecute(
I);
7393 uint64_t Max = std::max(TrueWeight, FalseWeight);
7394 uint64_t Sum = TrueWeight + FalseWeight;
7397 if (Probability >
TTI->getPredictableBranchThreshold())
7407 if (!Cmp || !Cmp->hasOneUse())
7430 assert(DefSI->getCondition() ==
SI->getCondition() &&
7431 "The condition of DefSI does not match with SI");
7432 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7435 assert(V &&
"Failed to get select true/false value");
7439bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7463 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7464 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7465 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7466 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7472bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7474 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7475 "Expected a funnel shift");
7499 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7500 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7501 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7509bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7521 It !=
SI->getParent()->
end(); ++It) {
7523 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7530 SelectInst *LastSI = ASI.
back();
7533 CurInstIterator = std::next(LastSI->
getIterator());
7537 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7538 fixupDbgVariableRecordsOnInst(*SI);
7540 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7543 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7546 TargetLowering::SelectSupportKind SelectKind;
7547 if (
SI->getType()->isVectorTy())
7548 SelectKind = TargetLowering::ScalarCondVectorVal;
7550 SelectKind = TargetLowering::ScalarValSelect;
7591 for (SelectInst *SI : ASI) {
7603 SplitPt.setHeadBit(
true);
7606 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7611 BranchInst *TrueBranch =
nullptr;
7612 BranchInst *FalseBranch =
nullptr;
7613 if (TrueInstrs.
size() == 0) {
7615 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7618 }
else if (FalseInstrs.
size() == 0) {
7620 CondFr, SplitPt,
false,
nullptr,
nullptr, LI));
7627 nullptr,
nullptr, LI);
7635 EndBlock->
setName(
"select.end");
7637 TrueBlock->
setName(
"select.true.sink");
7639 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7640 :
"select.false.sink");
7644 FreshBBs.
insert(TrueBlock);
7646 FreshBBs.
insert(FalseBlock);
7647 FreshBBs.
insert(EndBlock);
7650 BFI->setBlockFreq(EndBlock,
BFI->getBlockFreq(StartBlock));
7652 static const unsigned MD[] = {
7653 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7654 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7659 for (Instruction *
I : TrueInstrs)
7661 for (Instruction *
I : FalseInstrs)
7668 if (TrueBlock ==
nullptr)
7669 TrueBlock = StartBlock;
7670 else if (FalseBlock ==
nullptr)
7671 FalseBlock = StartBlock;
7687 SI->eraseFromParent();
7689 ++NumSelectsExpanded;
7693 CurInstIterator = StartBlock->
end();
7700bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7712 "Expected a type of the same size!");
7718 Builder.SetInsertPoint(SVI);
7719 Value *BC1 = Builder.CreateBitCast(
7721 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7722 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7726 SVI, TLInfo,
nullptr,
7727 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7734 !
Op->isTerminator() && !
Op->isEHPad())
7740bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7755 DenseMap<const Instruction *, unsigned long> InstOrdering;
7756 unsigned long InstNumber = 0;
7757 for (
const auto &
I : *TargetBB)
7758 InstOrdering[&
I] = InstNumber++;
7760 for (Use *U :
reverse(OpsToSink)) {
7765 if (InstOrdering[UI] < InstOrdering[InsertPoint])
7772 SetVector<Instruction *> MaybeDead;
7773 DenseMap<Instruction *, Instruction *> NewInstructions;
7774 for (Use *U : ToReplace) {
7783 FreshBBs.
insert(OpDef->getParent());
7786 NewInstructions[UI] = NI;
7791 InsertedInsts.insert(NI);
7797 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
7798 It->second->setOperand(
U->getOperandNo(), NI);
7805 for (
auto *
I : MaybeDead) {
7806 if (!
I->hasNUsesOrMore(1)) {
7808 I->eraseFromParent();
7815bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
7832 auto *NewType = Type::getIntNTy(
Context, RegWidth);
7841 ExtType = Instruction::SExt;
7844 if (Arg->hasSExtAttr())
7845 ExtType = Instruction::SExt;
7846 if (Arg->hasZExtAttr())
7847 ExtType = Instruction::ZExt;
7853 SI->setCondition(ExtInst);
7854 for (
auto Case :
SI->cases()) {
7855 const APInt &NarrowConst = Case.getCaseValue()->getValue();
7856 APInt WideConst = (ExtType == Instruction::ZExt)
7857 ? NarrowConst.
zext(RegWidth)
7858 : NarrowConst.
sext(RegWidth);
7859 Case.setValue(ConstantInt::get(
Context, WideConst));
7865bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
7872 Value *Condition =
SI->getCondition();
7881 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
7882 ConstantInt *CaseValue = Case.getCaseValue();
7883 BasicBlock *CaseBB = Case.getCaseSuccessor();
7886 bool CheckedForSinglePred =
false;
7887 for (PHINode &
PHI : CaseBB->
phis()) {
7888 Type *PHIType =
PHI.getType();
7896 if (PHIType == ConditionType || TryZExt) {
7898 bool SkipCase =
false;
7899 Value *Replacement =
nullptr;
7900 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
7901 Value *PHIValue =
PHI.getIncomingValue(
I);
7902 if (PHIValue != CaseValue) {
7911 if (
PHI.getIncomingBlock(
I) != SwitchBB)
7916 if (!CheckedForSinglePred) {
7917 CheckedForSinglePred =
true;
7918 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
7924 if (Replacement ==
nullptr) {
7925 if (PHIValue == CaseValue) {
7926 Replacement = Condition;
7929 Replacement = Builder.CreateZExt(Condition, PHIType);
7932 PHI.setIncomingValue(
I, Replacement);
7943bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
7944 bool Changed = optimizeSwitchType(SI);
7945 Changed |= optimizeSwitchPhiConstants(SI);
7966class VectorPromoteHelper {
7968 const DataLayout &
DL;
7971 const TargetLowering &TLI;
7974 const TargetTransformInfo &
TTI;
7980 SmallVector<Instruction *, 4> InstsToBePromoted;
7983 unsigned StoreExtractCombineCost;
7992 if (InstsToBePromoted.
empty())
7994 return InstsToBePromoted.
back();
8000 unsigned getTransitionOriginalValueIdx()
const {
8002 "Other kind of transitions are not supported yet");
8009 unsigned getTransitionIdx()
const {
8011 "Other kind of transitions are not supported yet");
8019 Type *getTransitionType()
const {
8030 void promoteImpl(Instruction *ToBePromoted);
8034 bool isProfitableToPromote() {
8035 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8039 Type *PromotedType = getTransitionType();
8042 unsigned AS =
ST->getPointerAddressSpace();
8060 for (
const auto &Inst : InstsToBePromoted) {
8068 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8080 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8081 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8082 return ScalarCost > VectorCost;
8094 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8109 if (!
EC.isScalable()) {
8112 for (
unsigned Idx = 0; Idx !=
EC.getKnownMinValue(); ++Idx) {
8113 if (Idx == ExtractIdx)
8121 "Generate scalable vector for non-splat is unimplemented");
8126 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8127 unsigned OperandIdx) {
8130 if (OperandIdx != 1)
8132 switch (
Use->getOpcode()) {
8135 case Instruction::SDiv:
8136 case Instruction::UDiv:
8137 case Instruction::SRem:
8138 case Instruction::URem:
8140 case Instruction::FDiv:
8141 case Instruction::FRem:
8142 return !
Use->hasNoNaNs();
8148 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8149 const TargetTransformInfo &
TTI, Instruction *Transition,
8150 unsigned CombineCost)
8151 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8152 StoreExtractCombineCost(CombineCost) {
8153 assert(Transition &&
"Do not know how to promote null");
8157 bool canPromote(
const Instruction *ToBePromoted)
const {
8164 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8167 for (
const Use &U : ToBePromoted->
operands()) {
8168 const Value *Val =
U.get();
8169 if (Val == getEndOfTransition()) {
8173 if (canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()))
8196 void enqueueForPromotion(Instruction *ToBePromoted) {
8197 InstsToBePromoted.push_back(ToBePromoted);
8201 void recordCombineInstruction(Instruction *ToBeCombined) {
8203 CombineInst = ToBeCombined;
8213 if (InstsToBePromoted.empty() || !CombineInst)
8221 for (
auto &ToBePromoted : InstsToBePromoted)
8222 promoteImpl(ToBePromoted);
8223 InstsToBePromoted.clear();
8230void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8240 "The type of the result of the transition does not match "
8245 Type *TransitionTy = getTransitionType();
8250 for (Use &U : ToBePromoted->
operands()) {
8252 Value *NewVal =
nullptr;
8253 if (Val == Transition)
8254 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8261 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8265 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8268 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8274bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8275 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8290 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8291 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost);
8298 if (ToBePromoted->
getParent() != Parent) {
8299 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8301 <<
") than the transition (" << Parent->
getName()
8306 if (VPH.canCombine(ToBePromoted)) {
8308 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8309 VPH.recordCombineInstruction(ToBePromoted);
8311 NumStoreExtractExposed +=
Changed;
8316 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8319 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8321 VPH.enqueueForPromotion(ToBePromoted);
8322 Inst = ToBePromoted;
8362 Type *StoreType =
SI.getValueOperand()->getType();
8371 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8372 DL.getTypeSizeInBits(StoreType) == 0)
8375 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8377 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8381 if (
SI.isVolatile())
8393 if (!
match(
SI.getValueOperand(),
8400 if (!
LValue->getType()->isIntegerTy() ||
8401 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8403 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8419 Builder.SetInsertPoint(&
SI);
8423 if (LBC && LBC->getParent() !=
SI.getParent())
8424 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8425 if (HBC && HBC->getParent() !=
SI.getParent())
8426 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8428 bool IsLE =
SI.getDataLayout().isLittleEndian();
8429 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8430 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8431 Value *Addr =
SI.getPointerOperand();
8432 Align Alignment =
SI.getAlign();
8433 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8434 if (IsOffsetStore) {
8435 Addr = Builder.CreateGEP(
8436 SplitStoreType, Addr,
8444 Builder.CreateAlignedStore(V, Addr, Alignment);
8447 CreateSplitStore(
LValue,
false);
8448 CreateSplitStore(HValue,
true);
8451 SI.eraseFromParent();
8459 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8541 if (GEPIOpI->getParent() != SrcBlock)
8546 if (auto *I = dyn_cast<Instruction>(Usr)) {
8547 if (I->getParent() != SrcBlock) {
8555 std::vector<GetElementPtrInst *> UGEPIs;
8558 for (User *Usr : GEPIOp->
users()) {
8577 if (UGEPI->getOperand(0) != GEPIOp)
8579 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8581 if (GEPIIdx->getType() !=
8589 UGEPIs.push_back(UGEPI);
8591 if (UGEPIs.size() == 0)
8594 for (GetElementPtrInst *UGEPI : UGEPIs) {
8596 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8603 for (GetElementPtrInst *UGEPI : UGEPIs) {
8604 UGEPI->setOperand(0, GEPI);
8606 Constant *NewUGEPIIdx = ConstantInt::get(
8607 GEPIIdx->getType(), UGEPIIdx->
getValue() - GEPIIdx->getValue());
8608 UGEPI->setOperand(1, NewUGEPIIdx);
8611 if (!GEPI->isInBounds()) {
8612 UGEPI->setIsInBounds(
false);
8619 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8621 "GEPIOp is used outside SrcBlock");
8645 Value *
X = Cmp->getOperand(0);
8646 if (!
X->hasUseList())
8651 for (
auto *U :
X->users()) {
8655 (UI->
getParent() != Branch->getParent() &&
8656 UI->
getParent() != Branch->getSuccessor(0) &&
8657 UI->
getParent() != Branch->getSuccessor(1)) ||
8658 (UI->
getParent() != Branch->getParent() &&
8659 !UI->
getParent()->getSinglePredecessor()))
8665 if (UI->
getParent() != Branch->getParent())
8669 ConstantInt::get(UI->
getType(), 0));
8671 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8675 if (Cmp->isEquality() &&
8680 if (UI->
getParent() != Branch->getParent())
8683 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8684 ConstantInt::get(UI->
getType(), 0));
8686 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8694bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8695 bool AnyChange =
false;
8696 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8700 if (InsertedInsts.count(
I))
8709 LargeOffsetGEPMap.erase(
P);
8711 P->eraseFromParent();
8734 I, LI->getLoopFor(
I->getParent()), *
TTI))
8742 TargetLowering::TypeExpandInteger) {
8746 I, LI->getLoopFor(
I->getParent()), *
TTI))
8749 bool MadeChange = optimizeExt(
I);
8750 return MadeChange | optimizeExtUses(
I);
8757 if (optimizeCmp(Cmp, ModifiedDT))
8761 if (optimizeURem(
I))
8765 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8766 bool Modified = optimizeLoadExt(LI);
8775 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8776 unsigned AS =
SI->getPointerAddressSpace();
8777 return optimizeMemoryInst(
I,
SI->getOperand(1),
8778 SI->getOperand(0)->getType(), AS);
8782 unsigned AS = RMW->getPointerAddressSpace();
8783 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
8787 unsigned AS = CmpX->getPointerAddressSpace();
8788 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
8789 CmpX->getCompareOperand()->getType(), AS);
8799 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
8800 BinOp->
getOpcode() == Instruction::LShr)) {
8808 if (GEPI->hasAllZeroIndices()) {
8810 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
8811 GEPI->getName(), GEPI->getIterator());
8812 NC->setDebugLoc(GEPI->getDebugLoc());
8815 GEPI, TLInfo,
nullptr,
8816 [&](
Value *V) { removeAllAssertingVHReferences(V); });
8818 optimizeInst(
NC, ModifiedDT);
8841 if (Const0 || Const1) {
8842 if (!Const0 || !Const1) {
8843 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
8848 FI->eraseFromParent();
8855 if (tryToSinkFreeOperands(
I))
8858 switch (
I->getOpcode()) {
8859 case Instruction::Shl:
8860 case Instruction::LShr:
8861 case Instruction::AShr:
8863 case Instruction::Call:
8865 case Instruction::Select:
8867 case Instruction::ShuffleVector:
8869 case Instruction::Switch:
8871 case Instruction::ExtractElement:
8873 case Instruction::Br:
8882bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
8883 if (!
I.getType()->isIntegerTy() ||
8888 SmallVector<Instruction *, 4> Insts;
8894 &
I, TLInfo,
nullptr,
8895 [&](
Value *V) { removeAllAssertingVHReferences(V); });
8902bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
8904 bool MadeChange =
false;
8907 CurInstIterator = BB.
begin();
8908 ModifiedDT = ModifyDT::NotModifyDT;
8909 while (CurInstIterator != BB.
end()) {
8910 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
8911 if (ModifiedDT != ModifyDT::NotModifyDT) {
8924 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
8926 bool MadeBitReverse =
true;
8927 while (MadeBitReverse) {
8928 MadeBitReverse =
false;
8930 if (makeBitReverse(
I)) {
8931 MadeBitReverse = MadeChange =
true;
8936 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
8941bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
8942 bool AnyChange =
false;
8943 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
8944 AnyChange |= fixupDbgVariableRecord(DVR);
8950bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
8951 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
8952 DVR.
Type != DbgVariableRecord::LocationType::Assign)
8956 bool AnyChange =
false;
8957 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
8959 for (
Value *Location : LocationOps) {
8960 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
8989bool CodeGenPrepare::placeDbgValues(Function &
F) {
8990 bool MadeChange =
false;
8991 DominatorTree DT(
F);
8993 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
8994 SmallVector<Instruction *, 4> VIs;
8995 for (
Value *V : DbgItem->location_ops())
9003 for (Instruction *VI : VIs) {
9004 if (
VI->isTerminator())
9009 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9020 if (VIs.size() > 1) {
9023 <<
"Unable to find valid location for Debug Value, undefing:\n"
9025 DbgItem->setKillLocation();
9030 << *DbgItem <<
' ' << *VI);
9037 for (BasicBlock &BB :
F) {
9043 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9045 DbgProcessor(&DVR, &Insn);
9056bool CodeGenPrepare::placePseudoProbes(Function &
F) {
9057 bool MadeChange =
false;
9060 auto FirstInst =
Block.getFirstInsertionPt();
9061 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9065 while (
I !=
Block.end()) {
9067 II->moveBefore(FirstInst);
9077 uint64_t NewMax = (NewTrue > NewFalse) ? NewTrue : NewFalse;
9078 uint32_t Scale = (NewMax / std::numeric_limits<uint32_t>::max()) + 1;
9079 NewTrue = NewTrue / Scale;
9080 NewFalse = NewFalse / Scale;
9105bool CodeGenPrepare::splitBranchCondition(Function &
F, ModifyDT &ModifiedDT) {
9109 bool MadeChange =
false;
9110 for (
auto &BB :
F) {
9123 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9131 Value *Cond1, *Cond2;
9134 Opc = Instruction::And;
9137 Opc = Instruction::Or;
9147 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9161 Br1->setCondition(Cond1);
9166 if (
Opc == Instruction::And)
9167 Br1->setSuccessor(0, TmpBB);
9169 Br1->setSuccessor(1, TmpBB);
9174 I->removeFromParent();
9175 I->insertBefore(Br2->getIterator());
9187 if (
Opc == Instruction::Or)
9194 for (PHINode &PN : FBB->
phis()) {
9201 if (
Opc == Instruction::Or) {
9221 uint64_t TrueWeight, FalseWeight;
9223 uint64_t NewTrueWeight = TrueWeight;
9224 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9226 Br1->setMetadata(LLVMContext::MD_prof,
9227 MDBuilder(Br1->getContext())
9228 .createBranchWeights(TrueWeight, FalseWeight,
9231 NewTrueWeight = TrueWeight;
9232 NewFalseWeight = 2 * FalseWeight;
9234 Br2->setMetadata(LLVMContext::MD_prof,
9235 MDBuilder(Br2->getContext())
9236 .createBranchWeights(TrueWeight, FalseWeight));
9257 uint64_t TrueWeight, FalseWeight;
9259 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9260 uint64_t NewFalseWeight = FalseWeight;
9262 Br1->setMetadata(LLVMContext::MD_prof,
9263 MDBuilder(Br1->getContext())
9264 .createBranchWeights(TrueWeight, FalseWeight));
9266 NewTrueWeight = 2 * TrueWeight;
9267 NewFalseWeight = FalseWeight;
9269 Br2->setMetadata(LLVMContext::MD_prof,
9270 MDBuilder(Br2->getContext())
9271 .createBranchWeights(TrueWeight, FalseWeight));
9275 ModifiedDT = ModifyDT::ModifyBBDT;
static unsigned getIntrinsicID(const SDNode *N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
This file contains the simple types necessary to represent the attributes associated with functions a...
static const Function * getParent(const Value *V)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool sinkAndCmp0Expression(Instruction *AndI, const TargetLowering &TLI, SetOfInstrs &InsertedInsts)
Duplicate and sink the given 'and' instruction into user blocks where it is used in a compare to allo...
static bool SinkShiftAndTruncate(BinaryOperator *ShiftI, Instruction *User, ConstantInt *CI, DenseMap< BasicBlock *, BinaryOperator * > &InsertedShifts, const TargetLowering &TLI, const DataLayout &DL)
Sink both shift and truncate instruction to the use of truncate's BB.
static bool getGEPSmallConstantIntOffsetV(GetElementPtrInst *GEP, SmallVectorImpl< Value * > &OffsetV)
static bool sinkSelectOperand(const TargetTransformInfo *TTI, Value *V)
Check if V (an operand of a select instruction) is an expensive instruction that is only used once.
static bool isExtractBitsCandidateUse(Instruction *User)
Check if the candidates could be combined with a shift instruction, which includes:
static cl::opt< unsigned > MaxAddressUsersToScan("cgp-max-address-users-to-scan", cl::init(100), cl::Hidden, cl::desc("Max number of address users to look at"))
static cl::opt< bool > OptimizePhiTypes("cgp-optimize-phi-types", cl::Hidden, cl::init(true), cl::desc("Enable converting phi types in CodeGenPrepare"))
static cl::opt< bool > DisableStoreExtract("disable-cgp-store-extract", cl::Hidden, cl::init(false), cl::desc("Disable store(extract) optimizations in CodeGenPrepare"))
static bool foldFCmpToFPClassTest(CmpInst *Cmp, const TargetLowering &TLI, const DataLayout &DL)
static void scaleWeights(uint64_t &NewTrue, uint64_t &NewFalse)
Scale down both weights to fit into uint32_t.
static cl::opt< bool > ProfileUnknownInSpecialSection("profile-unknown-in-special-section", cl::Hidden, cl::desc("In profiling mode like sampleFDO, if a function doesn't have " "profile, we cannot tell the function is cold for sure because " "it may be a function newly added without ever being sampled. " "With the flag enabled, compiler can put such profile unknown " "functions into a special section, so runtime system can choose " "to handle it in a different way than .text section, to save " "RAM for example. "))
static bool OptimizeExtractBits(BinaryOperator *ShiftI, ConstantInt *CI, const TargetLowering &TLI, const DataLayout &DL)
Sink the shift right instruction into user blocks if the uses could potentially be combined with this...
static cl::opt< bool > DisableExtLdPromotion("disable-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), cl::desc("Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in " "CodeGenPrepare"))
static cl::opt< bool > DisablePreheaderProtect("disable-preheader-prot", cl::Hidden, cl::init(false), cl::desc("Disable protection against removing loop preheaders"))
static cl::opt< bool > AddrSinkCombineBaseOffs("addr-sink-combine-base-offs", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseOffs field in Address sinking."))
static bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI, const DataLayout &DL)
If the specified cast instruction is a noop copy (e.g.
static bool splitMergedValStore(StoreInst &SI, const DataLayout &DL, const TargetLowering &TLI)
For the instruction sequence of store below, F and I values are bundled together as an i64 value befo...
static bool SinkCast(CastInst *CI)
Sink the specified cast instruction into its user blocks.
static bool swapICmpOperandsToExposeCSEOpportunities(CmpInst *Cmp)
Many architectures use the same instruction for both subtract and cmp.
static cl::opt< bool > AddrSinkCombineBaseReg("addr-sink-combine-base-reg", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseReg field in Address sinking."))
static bool FindAllMemoryUses(Instruction *I, SmallVectorImpl< std::pair< Use *, Type * > > &MemoryUses, SmallPtrSetImpl< Instruction * > &ConsideredInsts, const TargetLowering &TLI, const TargetRegisterInfo &TRI, bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI, unsigned &SeenInsts)
Recursively walk all the uses of I until we find a memory use.
static cl::opt< bool > StressStoreExtract("stress-cgp-store-extract", cl::Hidden, cl::init(false), cl::desc("Stress test store(extract) optimizations in CodeGenPrepare"))
static bool isFormingBranchFromSelectProfitable(const TargetTransformInfo *TTI, const TargetLowering *TLI, SelectInst *SI)
Returns true if a SelectInst should be turned into an explicit branch.
static std::optional< std::pair< Instruction *, Constant * > > getIVIncrement(const PHINode *PN, const LoopInfo *LI)
If given PN is an inductive variable with value IVInc coming from the backedge, and on each iteration...
static cl::opt< bool > AddrSinkCombineBaseGV("addr-sink-combine-base-gv", cl::Hidden, cl::init(true), cl::desc("Allow combining of BaseGV field in Address sinking."))
static cl::opt< bool > AddrSinkUsingGEPs("addr-sink-using-gep", cl::Hidden, cl::init(true), cl::desc("Address sinking in CGP using GEPs."))
static Value * getTrueOrFalseValue(SelectInst *SI, bool isTrue, const SmallPtrSet< const Instruction *, 2 > &Selects)
If isTrue is true, return the true value of SI, otherwise return false value of SI.
static cl::opt< bool > DisableBranchOpts("disable-cgp-branch-opts", cl::Hidden, cl::init(false), cl::desc("Disable branch optimizations in CodeGenPrepare"))
static cl::opt< bool > EnableTypePromotionMerge("cgp-type-promotion-merge", cl::Hidden, cl::desc("Enable merging of redundant sexts when one is dominating" " the other."), cl::init(true))
static cl::opt< bool > ProfileGuidedSectionPrefix("profile-guided-section-prefix", cl::Hidden, cl::init(true), cl::desc("Use profile info to add section prefix for hot/cold functions"))
static cl::opt< unsigned > HugeFuncThresholdInCGPP("cgpp-huge-func", cl::init(10000), cl::Hidden, cl::desc("Least BB number of huge function."))
static cl::opt< bool > AddrSinkNewSelects("addr-sink-new-select", cl::Hidden, cl::init(true), cl::desc("Allow creation of selects in Address sinking."))
static bool foldURemOfLoopIncrement(Instruction *Rem, const DataLayout *DL, const LoopInfo *LI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
static bool optimizeBranch(BranchInst *Branch, const TargetLowering &TLI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
static bool tryUnmergingGEPsAcrossIndirectBr(GetElementPtrInst *GEPI, const TargetTransformInfo *TTI)
static bool IsOperandAMemoryOperand(CallInst *CI, InlineAsm *IA, Value *OpVal, const TargetLowering &TLI, const TargetRegisterInfo &TRI)
Check to see if all uses of OpVal by the specified inline asm call are due to memory operands.
static bool isIntrinsicOrLFToBeTailCalled(const TargetLibraryInfo *TLInfo, const CallInst *CI)
static void replaceAllUsesWith(Value *Old, Value *New, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
Replace all old uses with new ones, and push the updated BBs into FreshBBs.
static cl::opt< bool > ForceSplitStore("force-split-store", cl::Hidden, cl::init(false), cl::desc("Force store splitting no matter what the target query says."))
static void computeBaseDerivedRelocateMap(const SmallVectorImpl< GCRelocateInst * > &AllRelocateCalls, MapVector< GCRelocateInst *, SmallVector< GCRelocateInst *, 0 > > &RelocateInstMap)
static bool simplifyRelocatesOffABase(GCRelocateInst *RelocatedBase, const SmallVectorImpl< GCRelocateInst * > &Targets)
static cl::opt< bool > AddrSinkCombineScaledReg("addr-sink-combine-scaled-reg", cl::Hidden, cl::init(true), cl::desc("Allow combining of ScaledReg field in Address sinking."))
static bool foldICmpWithDominatingICmp(CmpInst *Cmp, const TargetLowering &TLI)
For pattern like:
static bool MightBeFoldableInst(Instruction *I)
This is a little filter, which returns true if an addressing computation involving I might be folded ...
static bool matchIncrement(const Instruction *IVInc, Instruction *&LHS, Constant *&Step)
static cl::opt< bool > EnableGEPOffsetSplit("cgp-split-large-offset-gep", cl::Hidden, cl::init(true), cl::desc("Enable splitting large offset of GEP."))
static cl::opt< bool > DisableComplexAddrModes("disable-complex-addr-modes", cl::Hidden, cl::init(false), cl::desc("Disables combining addressing modes with different parts " "in optimizeMemoryInst."))
static cl::opt< bool > EnableICMP_EQToICMP_ST("cgp-icmp-eq2icmp-st", cl::Hidden, cl::init(false), cl::desc("Enable ICMP_EQ to ICMP_S(L|G)T conversion."))
static cl::opt< bool > VerifyBFIUpdates("cgp-verify-bfi-updates", cl::Hidden, cl::init(false), cl::desc("Enable BFI update verification for " "CodeGenPrepare."))
static cl::opt< bool > BBSectionsGuidedSectionPrefix("bbsections-guided-section-prefix", cl::Hidden, cl::init(true), cl::desc("Use the basic-block-sections profile to determine the text " "section prefix for hot functions. Functions with " "basic-block-sections profile will be placed in `.text.hot` " "regardless of their FDO profile info. Other functions won't be " "impacted, i.e., their prefixes will be decided by FDO/sampleFDO " "profiles."))
static bool isRemOfLoopIncrementWithLoopInvariant(Instruction *Rem, const LoopInfo *LI, Value *&RemAmtOut, Value *&AddInstOut, Value *&AddOffsetOut, PHINode *&LoopIncrPNOut)
static bool isIVIncrement(const Value *V, const LoopInfo *LI)
static cl::opt< bool > DisableGCOpts("disable-cgp-gc-opts", cl::Hidden, cl::init(false), cl::desc("Disable GC optimizations in CodeGenPrepare"))
static bool GEPSequentialConstIndexed(GetElementPtrInst *GEP)
static void DbgInserterHelper(DbgVariableRecord *DVR, BasicBlock::iterator VI)
static bool isPromotedInstructionLegal(const TargetLowering &TLI, const DataLayout &DL, Value *Val)
Check whether or not Val is a legal instruction for TLI.
static cl::opt< uint64_t > FreqRatioToSkipMerge("cgp-freq-ratio-to-skip-merge", cl::Hidden, cl::init(2), cl::desc("Skip merging empty blocks if (frequency of empty block) / " "(frequency of destination block) is greater than this ratio"))
static BasicBlock::iterator findInsertPos(Value *Addr, Instruction *MemoryInst, Value *SunkAddr)
static bool IsNonLocalValue(Value *V, BasicBlock *BB)
Return true if the specified values are defined in a different basic block than BB.
static cl::opt< bool > EnableAndCmpSinking("enable-andcmp-sinking", cl::Hidden, cl::init(true), cl::desc("Enable sinking and/cmp into branches."))
static bool sinkCmpExpression(CmpInst *Cmp, const TargetLowering &TLI, const DataLayout &DL)
Sink the given CmpInst into user blocks to reduce the number of virtual registers that must be create...
static bool hasSameExtUse(Value *Val, const TargetLowering &TLI)
Check if all the uses of Val are equivalent (or free) zero or sign extensions.
static bool despeculateCountZeros(IntrinsicInst *CountZeros, LoopInfo &LI, const TargetLowering *TLI, const DataLayout *DL, ModifyDT &ModifiedDT, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
If counting leading or trailing zeros is an expensive operation and a zero input is defined,...
static cl::opt< bool > StressExtLdPromotion("stress-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), cl::desc("Stress test ext(promotable(ld)) -> promoted(ext(ld)) " "optimization in CodeGenPrepare"))
static bool matchUAddWithOverflowConstantEdgeCases(CmpInst *Cmp, BinaryOperator *&Add)
Match special-case patterns that check for unsigned add overflow.
static cl::opt< bool > DisableSelectToBranch("disable-cgp-select2branch", cl::Hidden, cl::init(false), cl::desc("Disable select to branch conversion."))
static cl::opt< bool > DisableDeletePHIs("disable-cgp-delete-phis", cl::Hidden, cl::init(false), cl::desc("Disable elimination of dead PHI nodes."))
static cl::opt< bool > AddrSinkNewPhis("addr-sink-new-phis", cl::Hidden, cl::init(false), cl::desc("Allow creation of Phis in Address sinking."))
Defines an IR pass for CodeGen Prepare.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
static Value * getCondition(Instruction *I)
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU)
Register const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the PointerIntPair class.
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, const MachineInstr &B)
Remove Loads Into Fake Uses
static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static SymbolRef::Type getType(const Symbol *Sym)
static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, unsigned CombineOpc=0)
This file describes how to lower LLVM code to machine code.
static cl::opt< bool > DisableSelectOptimize("disable-select-optimize", cl::init(true), cl::Hidden, cl::desc("Disable the select-optimization pass from running"))
Disable the select optimization pass.
Target-Independent Code Generator Pass Configuration Options pass.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
static Constant * getConstantVector(MVT VT, ArrayRef< APInt > Bits, const APInt &Undefs, LLVMContext &C)
Class for arbitrary precision integers.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
unsigned getSignificantBits() const
Get the minimum bit size for this signed APInt.
unsigned logBase2() const
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
int64_t getSExtValue() const
Get sign extended value.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
void setAlignment(Align Align)
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addRequired()
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
An instruction that atomically checks whether a specified value is in a memory location,...
static unsigned getPointerOperandIndex()
an instruction that atomically reads a memory location, combines it with another value,...
static unsigned getPointerOperandIndex()
Analysis pass providing the BasicBlockSectionsProfileReader.
bool isFunctionHot(StringRef FuncName) const
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI void insertDbgRecordBefore(DbgRecord *DR, InstListType::iterator Here)
Insert a DbgRecord into a block at the position given by Here.
InstListType::const_iterator const_iterator
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI 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.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI void removeFromParent()
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LocationType Type
Classification of the debug-info record that this DbgVariableRecord represents.
LLVM_ABI void replaceVariableLocationOp(Value *OldValue, Value *NewValue, bool AllowEmpty=false)
LLVM_ABI iterator_range< location_op_iterator > location_ops() const
Get the locations corresponding to the variable referenced by the debug info intrinsic.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This instruction compares its operands according to the predicate given to the constructor.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionPass class - This class is used to implement most global optimizations.
const BasicBlock & getEntryBlock() const
LLVM_ABI const Value * getStatepoint() const
The statepoint with which this gc.relocate is associated.
Represents calls to the gc.relocate intrinsic.
unsigned getBasePtrIndex() const
The index into the associate statepoint's argument list which contains the base pointer of the pointe...
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static LLVM_ABI Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)
Returns the result type of a getelementptr with the given source element type and indexes.
LLVM_ABI bool canIncreaseAlignment() const
Returns true if the alignment of the value can be unilaterally increased.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
Type * getValueType() const
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This instruction compares its operands according to the predicate given to the constructor.
bool isEquality() const
Return true if this predicate is either EQ or NE.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
LLVM_ABI bool isDebugOrPseudoInst() const LLVM_READONLY
Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void moveAfter(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
LLVM_ABI std::optional< simple_ilist< DbgRecord >::iterator > getDbgReinsertionPosition()
Return an iterator to the position of the "Next" DbgRecord after this instruction,...
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
LLVM_ABI void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
An instruction for reading from memory.
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
Analysis pass that exposes the LoopInfo for a function.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
The legacy pass manager's analysis pass to compute loop information.
Represents a single loop in the control flow graph.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static MVT getIntegerVT(unsigned BitWidth)
LLVM_ABI void replacePhiUsesWith(MachineBasicBlock *Old, MachineBasicBlock *New)
Update all phi nodes in this basic block to refer to basic block New instead of basic block Old.
This class implements a map that also provides access to all stored values in a deterministic order.
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
iterator find(const KeyT &Key)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
op_range incoming_values()
Value * getIncomingValueForBlock(const BasicBlock *BB) const
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
PointerIntPair - This class implements a pair of a pointer and small integer.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
bool isFunctionColdInCallGraph(const FuncT *F, BFIT &BFI) const
Returns true if F contains only cold code.
LLVM_ABI bool isFunctionHotnessUnknown(const Function &F) const
Returns true if the hotness of F is unknown.
bool isFunctionHotInCallGraph(const FuncT *F, BFIT &BFI) const
Returns true if F contains hot code.
LLVM_ABI bool hasPartialSampleProfile() const
Returns true if module M has partial-profile sample profile.
LLVM_ABI bool hasHugeWorkingSetSize() const
Returns true if the working set size of the code is considered huge.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
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.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
LLVM_ABI bool isUsedInBasicBlock(const BasicBlock *BB) const
Check if this value is used in the specified basic block.
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
void mutateType(Type *Ty)
Mutate the type of this Value to be of the specified type.
user_iterator_impl< User > user_iterator
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
bool pointsToAliveValue() const
int getNumOccurrences() const
constexpr ScalarTy getFixedValue() const
constexpr bool isNonZero() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ C
The default llvm calling convention, compatible with C.
unsigned getAddrMode(MCInstrInfo const &MCII, MCInst const &MCI)
@ BasicBlock
Various leaf nodes.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap, true > m_c_NUWAdd(const LHS &L, const RHS &R)
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
UAddWithOverflow_match< LHS_t, RHS_t, Sum_t > m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S)
Match an icmp instruction checking for unsigned overflow on addition.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
auto m_Undef()
Match an arbitrary undef constant.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale)
Compare two scaled numbers.
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ Assume
Do not drop type tests (default).
@ User
could "use" a pointer
NodeAddr< PhiNode * > Phi
NodeAddr< UseNode * > Use
SmallVector< Node, 4 > NodeList
friend class Instruction
Iterator for Instructions in a `BasicBlock.
LLVM_ABI iterator begin() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
FunctionAddr VTableAddr Value
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool RemoveRedundantDbgInstrs(BasicBlock *BB)
Try to remove redundant dbg.value instructions from given basic block.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
LLVM_ABI bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions=false, const TargetLibraryInfo *TLI=nullptr, DomTreeUpdater *DTU=nullptr)
If a terminator instruction is predicated on a constant value, convert it into an unconditional branc...
LLVM_ABI void findDbgValues(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)
Finds the dbg.values describing a value.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
APInt operator*(APInt a, uint64_t RHS)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
auto successors(const MachineBasicBlock *BB)
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI ReturnInst * FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, BasicBlock *Pred, DomTreeUpdater *DTU=nullptr)
This method duplicates the specified return instruction into a predecessor which ends in an unconditi...
bool operator!=(uint64_t V1, const APInt &V2)
constexpr from_range_t from_range
LLVM_ABI Instruction * SplitBlockAndInsertIfElse(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ElseBlock=nullptr)
Similar to SplitBlockAndInsertIfThen, but the inserted block is on the false path of the branch.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
auto cast_or_null(const Y &Val)
LLVM_ABI void DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, bool KeepOneInputPHIs=false)
Delete the specified block, which must have no predecessors.
LLVM_ABI void initializeCodeGenPrepareLegacyPassPass(PassRegistry &)
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
auto unique(Range &&R, Predicate P)
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
LLVM_ABI bool hasBranchWeightOrigin(const Instruction &I)
Check if Branch Weight Metadata has an "expected" field from an llvm.expect* intrinsic.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
LLVM_ABI bool SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr)
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
auto dyn_cast_or_null(const Y &Val)
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
LLVM_ABI bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Examine each PHI in the given block and delete it if it is dead.
LLVM_ABI bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, SmallSetVector< Instruction *, 8 > *UnsimplifiedUsers=nullptr)
Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively.
auto reverse(ContainerTy &&C)
LLVM_ABI bool recognizeBSwapOrBitReverseIdiom(Instruction *I, bool MatchBSwaps, bool MatchBitReversals, SmallVectorImpl< Instruction * > &InsertedInsts)
Try to match a bswap or bitreverse idiom.
void sort(IteratorTy Start, IteratorTy End)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI void SplitBlockAndInsertIfThenElse(Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
generic_gep_type_iterator<> gep_type_iterator
LLVM_ABI FunctionPass * createCodeGenPrepareLegacyPass()
createCodeGenPrepareLegacyPass - Transform the code to expose more pattern matching during instructio...
ISD::CondCode getFCmpCondCode(FCmpInst::Predicate Pred)
getFCmpCondCode - Return the ISD condition code corresponding to the given LLVM IR floating-point con...
LLVM_ABI bool VerifyLoopInfo
Enable verification of loop info.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
bool attributesPermitTailCall(const Function *F, const Instruction *I, const ReturnInst *Ret, const TargetLoweringBase &TLI, bool *AllowDifferingSizes=nullptr)
Test if given that the input instruction is in the tail call position, if there is an attribute misma...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false, DominatorTree *DT=nullptr)
Attempts to merge a block into its predecessor, if possible.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
FunctionAddr VTableAddr Next
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool bypassSlowDivision(BasicBlock *BB, const DenseMap< unsigned int, unsigned int > &BypassWidth)
This optimization identifies DIV instructions in a BB that can be profitably bypassed and carried out...
gep_type_iterator gep_type_begin(const User *GEP)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
auto predecessors(const MachineBasicBlock *BB)
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
bool pred_empty(const BasicBlock *BB)
std::enable_if_t< std::is_signed_v< T >, T > AddOverflow(T X, T Y, T &Result)
Add two signed integers, computing the two's complement truncated result, returning true if overflow ...
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
std::pair< Value *, FPClassTest > fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, Value *RHS, bool LookThroughSrc=true)
Returns a pair of values, which if passed to llvm.is.fpclass, returns the same result as an fcmp with...
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
LLVM_ABI Value * simplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a URem, fold the result or return null.
DenseMap< const Value *, Value * > ValueToValueMap
LLVM_ABI CGPassBuilderOption getCGPassBuilderOption()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool isRound() const
Return true if the size is a power-of-two number of bytes.
bool isInteger() const
Return true if this is an integer or a vector integer type.
This contains information for each constraint that we are lowering.