47#include "llvm/Config/llvm-config.h"
70#include "llvm/IR/IntrinsicsAArch64.h"
114#define DEBUG_TYPE "codegenprepare"
117STATISTIC(NumPHIsElim,
"Number of trivial PHIs eliminated");
118STATISTIC(NumGEPsElim,
"Number of GEPs converted to casts");
119STATISTIC(NumCmpUses,
"Number of uses of Cmp expressions replaced with uses of "
121STATISTIC(NumCastUses,
"Number of uses of Cast expressions replaced with uses "
123STATISTIC(NumMemoryInsts,
"Number of memory instructions whose address "
124 "computations were sunk");
126 "Number of phis created when address "
127 "computations were sunk to memory instructions");
129 "Number of select created when address "
130 "computations were sunk to memory instructions");
131STATISTIC(NumExtsMoved,
"Number of [s|z]ext instructions combined with loads");
132STATISTIC(NumExtUses,
"Number of uses of [s|z]ext instructions optimized");
134 "Number of and mask instructions added to form ext loads");
135STATISTIC(NumAndUses,
"Number of uses of and mask instructions optimized");
136STATISTIC(NumRetsDup,
"Number of return instructions duplicated");
137STATISTIC(NumDbgValueMoved,
"Number of debug value instructions moved");
138STATISTIC(NumSelectsExpanded,
"Number of selects turned into branches");
139STATISTIC(NumStoreExtractExposed,
"Number of store(extractelement) exposed");
167class TypePromotionTransaction;
169class CodeGenPrepare {
170 friend class CodeGenPrepareLegacyPass;
171 const CodeGenOptions &Opts;
172 const TargetMachine *TM =
nullptr;
173 const TargetSubtargetInfo *SubtargetInfo =
nullptr;
174 const TargetLowering *TLI =
nullptr;
175 const TargetRegisterInfo *TRI =
nullptr;
176 const TargetTransformInfo *TTI =
nullptr;
177 const BasicBlockSectionsProfileReader *BBSectionsProfileReader =
nullptr;
178 const TargetLibraryInfo *TLInfo =
nullptr;
179 DomTreeUpdater *DTU =
nullptr;
180 LoopInfo *LI =
nullptr;
181 BlockFrequencyInfo *BFI;
182 BranchProbabilityInfo *BPI;
183 ProfileSummaryInfo *PSI =
nullptr;
194 ValueMap<Value *, WeakTrackingVH> SunkAddrs;
197 SetOfInstrs InsertedInsts;
201 InstrToOrigTy PromotedInsts;
204 SetOfInstrs RemovedInsts;
207 DenseMap<Value *, Instruction *> SeenChainsForSExt;
212 MapVector<AssertingVH<Value>,
217 SmallSet<AssertingVH<Value>, 2> NewGEPBases;
220 DenseMap<AssertingVH<GetElementPtrInst>,
int> LargeOffsetGEPID;
223 ValueToSExts ValToSExtendedUses;
229 const DataLayout *DL =
nullptr;
232 CodeGenPrepare(
const TargetMachine *TM)
233 : Opts(cl::LibraryOptionsContext::
get<CodeGenOptions>(
234 TM->
Options.MCOptions.LibraryOptions)),
237 bool IsHugeFunc =
false;
243 SmallPtrSet<BasicBlock *, 32> FreshBBs;
245 void releaseMemory() {
247 InsertedInsts.clear();
248 PromotedInsts.clear();
255 template <
typename F>
256 void resetIteratorIfInvalidatedWhileCalling(BasicBlock *BB,
F f) {
260 Value *CurValue = &*CurInstIterator;
261 WeakTrackingVH IterHandle(CurValue);
267 if (IterHandle != CurValue) {
268 CurInstIterator = BB->
begin();
274 DominatorTree &getDT() {
return DTU->getDomTree(); }
276 void removeAllAssertingVHReferences(
Value *
V);
279 bool eliminateMostlyEmptyBlocks(
Function &
F,
bool &ResetLI);
280 BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB);
281 bool canMergeBlocks(
const BasicBlock *BB,
const BasicBlock *DestBB)
const;
282 bool eliminateMostlyEmptyBlock(BasicBlock *BB);
283 bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB,
285 bool makeBitReverse(Instruction &
I);
287 bool optimizeInst(Instruction *
I, ModifyDT &ModifiedDT);
288 bool optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
Type *AccessTy,
290 bool optimizeGatherScatterInst(Instruction *MemoryInst,
Value *Ptr);
291 bool optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
292 ModifyDT &ModifiedDT);
293 bool optimizeInlineAsmInst(CallInst *CS);
295 bool optimizeExt(Instruction *&
I);
296 bool optimizeExtUses(Instruction *
I);
297 bool optimizeLoadExt(LoadInst *
Load);
298 bool optimizeShiftInst(BinaryOperator *BO);
299 bool optimizeFunnelShift(IntrinsicInst *Fsh);
300 bool optimizeSelectInst(SelectInst *SI);
301 bool optimizeShuffleVectorInst(ShuffleVectorInst *SVI);
302 bool optimizeSwitchType(SwitchInst *SI);
303 bool optimizeSwitchPhiConstants(SwitchInst *SI);
304 bool optimizeSwitchInst(SwitchInst *SI);
305 bool optimizeExtractElementInst(Instruction *Inst);
306 bool dupRetToEnableTailCallOpts(BasicBlock *BB, ModifyDT &ModifiedDT);
307 bool fixupDbgVariableRecord(DbgVariableRecord &
I);
308 bool fixupDbgVariableRecordsOnInst(Instruction &
I);
311 bool canFormExtLd(
const SmallVectorImpl<Instruction *> &MovedExts,
312 LoadInst *&LI, Instruction *&Inst,
bool HasPromoted);
313 bool tryToPromoteExts(TypePromotionTransaction &TPT,
314 const SmallVectorImpl<Instruction *> &Exts,
315 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
316 unsigned CreatedInstsCost = 0);
318 bool splitLargeGEPOffsets();
319 bool optimizePhiType(PHINode *Inst, SmallPtrSetImpl<PHINode *> &Visited,
320 SmallPtrSetImpl<Instruction *> &DeletedInstrs);
322 bool performAddressTypePromotion(
323 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
324 bool HasPromoted, TypePromotionTransaction &TPT,
325 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts);
327 bool simplifyOffsetableRelocate(GCStatepointInst &
I);
329 bool tryToSinkFreeOperands(Instruction *
I);
330 bool replaceMathCmpWithIntrinsic(BinaryOperator *BO,
Value *Arg0,
Value *Arg1,
332 bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT);
333 bool optimizeURem(Instruction *Rem);
334 bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
335 bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
336 bool unfoldPowerOf2Test(CmpInst *Cmp);
345 CodeGenPrepareLegacyPass() : FunctionPass(ID) {}
349 StringRef getPassName()
const override {
return "CodeGen Prepare"; }
351 void getAnalysisUsage(AnalysisUsage &AU)
const override {
359 AU.
addRequired<BranchProbabilityInfoWrapperPass>();
367char CodeGenPrepareLegacyPass::ID = 0;
369bool CodeGenPrepareLegacyPass::runOnFunction(
Function &
F) {
372 auto TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
373 CodeGenPrepare CGP(TM);
374 CGP.DL = &
F.getDataLayout();
377 CGP.TRI = CGP.SubtargetInfo->getRegisterInfo();
378 CGP.TLInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
379 CGP.TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
380 CGP.LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
381 CGP.BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
382 CGP.BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
383 CGP.PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
385 getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
386 CGP.BBSectionsProfileReader = BBSPRWP ? &BBSPRWP->getBBSPR() :
nullptr;
387 DomTreeUpdater DTUpdater(
388 &getAnalysis<DominatorTreeWrapperPass>().
getDomTree(),
389 DomTreeUpdater::UpdateStrategy::Lazy);
390 CGP.DTU = &DTUpdater;
396 "Optimize for code generation",
false,
false)
408 return new CodeGenPrepareLegacyPass();
413 CodeGenPrepare CGP(TM);
426 DL = &
F.getDataLayout();
439 "analysis to be available");
440 BBSectionsProfileReader =
443 DomTreeUpdater::UpdateStrategy::Lazy);
449 bool EverMadeChange =
false;
451 OptSize =
F.hasOptSize();
454 if (Opts.bbsections_guided_section_prefix && BBSectionsProfileReader &&
456 (void)
F.setSectionPrefix(
"hot");
457 }
else if (Opts.profile_guided_section_prefix) {
461 if (
F.hasFnAttribute(Attribute::Hot) ||
462 PSI->isFunctionHotInCallGraph(&
F, *BFI))
463 (void)
F.setSectionPrefix(
"hot");
467 else if (PSI->isFunctionColdInCallGraph(&
F, *BFI) ||
468 F.hasFnAttribute(Attribute::Cold))
469 (void)
F.setSectionPrefix(
"unlikely");
470 else if (Opts.profile_unknown_in_special_section &&
471 PSI->hasPartialSampleProfile() && PSI->isFunctionHotnessUnknown(
F))
472 (void)
F.setSectionPrefix(
"unknown");
478 const DenseMap<unsigned int, unsigned int> &BypassWidths =
481 while (BB !=
nullptr) {
494 EverMadeChange |= eliminateAssumptions(
F);
496 auto resetLoopInfo = [
this]() {
503 bool ResetLI =
false;
504 EverMadeChange |= eliminateMostlyEmptyBlocks(
F, ResetLI);
508 if (Opts.cgp_branch_opts)
509 EverMadeChange |= splitBranchCondition(
F);
515 EverMadeChange |=
Split;
521 assert(getDT().
verify(DominatorTree::VerificationLevel::Fast) &&
522 "Incorrect DominatorTree updates in CGP");
530 IsHugeFunc =
F.size() > Opts.cgp_huge_func;
532 bool MadeChange =
true;
533 bool FuncIterated =
false;
543 if (FuncIterated && !FreshBBs.
contains(&BB))
546 ModifyDT ModifiedDTOnIteration = ModifyDT::NotModifyDT;
562 else if (FuncIterated)
567 if (ModifiedDTOnIteration != ModifyDT::NotModifyDT)
572 FuncIterated = IsHugeFunc;
574 if (Opts.cgp_type_promotion_merge && !ValToSExtendedUses.empty())
575 MadeChange |= mergeSExts(
F);
576 if (!LargeOffsetGEPMap.
empty())
577 MadeChange |= splitLargeGEPOffsets();
578 MadeChange |= optimizePhiTypes(
F);
581 eliminateFallThrough(
F);
585 assert(getDT().
verify(DominatorTree::VerificationLevel::Fast) &&
586 "Incorrect DominatorTree updates in CGP");
593 for (Instruction *
I : RemovedInsts)
596 EverMadeChange |= MadeChange;
597 SeenChainsForSExt.
clear();
598 ValToSExtendedUses.clear();
599 RemovedInsts.clear();
600 LargeOffsetGEPMap.
clear();
601 LargeOffsetGEPID.
clear();
610 if (Opts.cgp_branch_opts) {
615 SmallSetVector<BasicBlock *, 8> WorkList;
616 for (BasicBlock &BB :
F) {
622 for (BasicBlock *Succ : Successors)
628 MadeChange |= !WorkList.
empty();
629 while (!WorkList.
empty()) {
635 for (BasicBlock *Succ : Successors)
645 if (EverMadeChange || MadeChange)
646 MadeChange |= eliminateFallThrough(
F);
648 EverMadeChange |= MadeChange;
651 if (Opts.cgp_gc_opts) {
653 for (BasicBlock &BB :
F)
654 for (Instruction &
I : BB)
657 for (
auto &
I : Statepoints)
658 EverMadeChange |= simplifyOffsetableRelocate(*
I);
663 EverMadeChange |= placeDbgValues(
F);
664 EverMadeChange |= placePseudoProbes(
F);
667 if (Opts.cgp_verify_bfi_updates)
671 return EverMadeChange;
674bool CodeGenPrepare::eliminateAssumptions(
Function &
F) {
675 bool MadeChange =
false;
676 for (BasicBlock &BB :
F) {
677 CurInstIterator = BB.begin();
678 while (CurInstIterator != BB.end()) {
683 Assume->eraseFromParent();
685 resetIteratorIfInvalidatedWhileCalling(&BB, [&]() {
696void CodeGenPrepare::removeAllAssertingVHReferences(
Value *
V) {
697 LargeOffsetGEPMap.
erase(
V);
706 auto VecI = LargeOffsetGEPMap.
find(
GEP->getPointerOperand());
707 if (VecI == LargeOffsetGEPMap.
end())
710 auto &GEPVector = VecI->second;
713 if (GEPVector.empty())
714 LargeOffsetGEPMap.
erase(VecI);
718[[maybe_unused]]
void CodeGenPrepare::verifyBFIUpdates(
Function &
F) {
721 BranchProbabilityInfo NewBPI(
F, NewCI, TLInfo);
722 BlockFrequencyInfo NewBFI(
F, NewBPI, NewCI);
723 NewBFI.verifyMatch(*BFI);
729bool CodeGenPrepare::eliminateFallThrough(
Function &
F) {
731 SmallPtrSet<BasicBlock *, 8> Preds;
739 BasicBlock *SinglePred = BB->getSinglePredecessor();
742 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
755 FreshBBs.
insert(SinglePred);
763 for (
auto *
Pred : Preds)
771BasicBlock *CodeGenPrepare::findDestBlockOfMergeableEmptyBlock(BasicBlock *BB) {
780 if (BBI != BB->
begin()) {
791 if (!canMergeBlocks(BB, DestBB))
801bool CodeGenPrepare::eliminateMostlyEmptyBlocks(
Function &
F,
bool &ResetLI) {
802 SmallPtrSet<BasicBlock *, 16> Preheaders;
804 while (!LoopList.empty()) {
805 Loop *
L = LoopList.pop_back_val();
807 if (BasicBlock *Preheader =
L->getLoopPreheader())
808 Preheaders.
insert(Preheader);
812 bool MadeChange =
false;
813 SmallPtrSet<PHINode *, 32> KnownNonDeadPHIs;
817 if (Opts.cgp_delete_phis)
825 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
827 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.
count(BB)))
830 ResetLI |= eliminateMostlyEmptyBlock(BB);
836bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB,
843 if (Opts.cgp_preheader_prot && isPreheader &&
887 SmallPtrSet<BasicBlock *, 16> SameIncomingValueBBs;
892 if (DestBBPred == BB)
896 return DestPN.getIncomingValueForBlock(BB) ==
897 DestPN.getIncomingValueForBlock(DestBBPred);
899 SameIncomingValueBBs.
insert(DestBBPred);
908 BlockFrequency PredFreq = BFI->getBlockFreq(
Pred);
909 BlockFrequency
BBFreq = BFI->getBlockFreq(BB);
911 for (
auto *SameValueBB : SameIncomingValueBBs)
912 if (SameValueBB->getUniquePredecessor() ==
Pred &&
913 DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
914 BBFreq += BFI->getBlockFreq(SameValueBB);
916 std::optional<BlockFrequency> Limit =
917 BBFreq.mul(Opts.cgp_freq_ratio_to_skip_merge);
918 return !Limit || PredFreq <= *Limit;
924bool CodeGenPrepare::canMergeBlocks(
const BasicBlock *BB,
925 const BasicBlock *DestBB)
const {
929 for (
const PHINode &PN : BB->
phis()) {
930 for (
const User *U : PN.users()) {
939 for (
unsigned I = 0,
E = UPN->getNumIncomingValues();
I !=
E; ++
I) {
942 Insn->
getParent() != UPN->getIncomingBlock(
I))
957 SmallPtrSet<const BasicBlock *, 16> BBPreds;
960 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
961 BBPreds.
insert(BBPN->getIncomingBlock(i));
970 for (
const PHINode &PN : DestBB->
phis()) {
971 const Value *
V1 = PN.getIncomingValueForBlock(
Pred);
972 const Value *V2 = PN.getIncomingValueForBlock(BB);
976 if (V2PN->getParent() == BB)
977 V2 = V2PN->getIncomingValueForBlock(
Pred);
996 E = OldI->user_end();
1009bool CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
1019 if (SinglePred != DestBB) {
1020 assert(SinglePred == BB &&
1021 "Single predecessor not the same as predecessor");
1030 FreshBBs.
insert(SinglePred);
1031 FreshBBs.
erase(DestBB);
1039 for (PHINode &PN : DestBB->
phis()) {
1041 Value *InVal = PN.removeIncomingValue(BB,
false);
1046 if (InValPhi && InValPhi->
getParent() == BB) {
1055 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1056 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1059 PN.addIncoming(InVal,
Pred);
1067 Pred->getTerminator()->copyMetadata(*BI, LLVMContext::MD_loop);
1073 SmallPtrSet<BasicBlock *, 8> SeenPreds;
1077 if (!PredOfDestBB.contains(
Pred)) {
1087 DTUpdates.
push_back({DominatorTree::Delete, BB, DestBB});
1107 for (
auto *ThisRelocate : AllRelocateCalls) {
1108 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1109 ThisRelocate->getDerivedPtrIndex());
1110 RelocateIdxMap.
insert(std::make_pair(
K, ThisRelocate));
1112 for (
auto &Item : RelocateIdxMap) {
1113 std::pair<unsigned, unsigned>
Key = Item.first;
1114 if (
Key.first ==
Key.second)
1119 auto BaseKey = std::make_pair(
Key.first,
Key.first);
1122 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1123 if (MaybeBase == RelocateIdxMap.
end())
1128 RelocateInstMap[MaybeBase->second].push_back(
I);
1136 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1139 if (!
Op ||
Op->getZExtValue() > 20)
1143 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1153 bool MadeChange =
false;
1160 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1161 &*R != RelocatedBase; ++R)
1165 RelocatedBase->
moveBefore(RI->getIterator());
1172 "Not relocating a derived object of the original base object");
1173 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1178 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1188 if (!Derived || Derived->getPointerOperand() !=
Base)
1197 "Should always have one since it's not a terminator");
1201 Builder.disableGEPCanonicalization();
1202 Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
1204 Value *Replacement = Builder.CreateGEP(Derived->getSourceElementType(),
1207 ToReplace->replaceAllUsesWith(Replacement);
1208 ToReplace->eraseFromParent();
1232bool CodeGenPrepare::simplifyOffsetableRelocate(GCStatepointInst &
I) {
1233 bool MadeChange =
false;
1235 for (
auto *U :
I.users())
1242 if (AllRelocateCalls.
size() < 2)
1247 MapVector<GCRelocateInst *, SmallVector<GCRelocateInst *, 0>> RelocateInstMap;
1249 if (RelocateInstMap.
empty())
1252 for (
auto &Item : RelocateInstMap)
1266 bool MadeChange =
false;
1269 Use &TheUse = UI.getUse();
1276 UserBB = PN->getIncomingBlock(TheUse);
1284 if (
User->isEHPad())
1294 if (UserBB == DefBB)
1298 CastInst *&InsertedCast = InsertedCasts[UserBB];
1300 if (!InsertedCast) {
1308 TheUse = InsertedCast;
1327 if (!SrcInst || SrcInst->getParent() == BCI->
getParent() ||
1328 SrcInst->isTerminator())
1332 Type *SrcTy = SrcInst->getType();
1333 EVT SrcVT =
TLI.getValueType(
DL, SrcTy);
1334 EVT DestVT =
TLI.getValueType(
DL, DestTy);
1346 bool IsCrossDomain = DestTy->
isFPOrFPVectorTy() != SrcTy->isFPOrFPVectorTy();
1349 unsigned NativeWidth =
DL.getPointerSizeInBits();
1350 bool IsLargeScalar =
1352 DL.getTypeSizeInBits(DestTy).getFixedValue() > NativeWidth;
1354 if (IsCrossDomain || IsLargeScalar)
1360 : std::next(SrcInst->getIterator());
1376 if (!
TLI.isFreeAddrSpaceCast(
DL, ASC->getSrcAddressSpace(),
1377 ASC->getDestAddressSpace()))
1432static std::optional<std::pair<Instruction *, Constant *>>
1435 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1436 return std::nullopt;
1439 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1440 return std::nullopt;
1444 return std::make_pair(IVInc, Step);
1445 return std::nullopt;
1458 return IVInc->first ==
I;
1462bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
1466 auto IsReplacableIVIncrement = [
this, &
Cmp](BinaryOperator *BO) {
1470 assert(L &&
"L should not be null after isIVIncrement()");
1472 if (LI->getLoopFor(
Cmp->getParent()) != L)
1485 return BO->
hasOneUse() && DT.dominates(
Cmp->getParent(),
L->getLoopLatch());
1487 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1510 if (BO->
getOpcode() == Instruction::Add &&
1511 IID == Intrinsic::usub_with_overflow) {
1518 for (Instruction &Iter : *
Cmp->getParent()) {
1521 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1526 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1529 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1530 if (BO->
getOpcode() != Instruction::Xor) {
1531 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1535 "Patterns with XOr should use the BO only in the compare");
1536 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1538 Cmp->eraseFromParent();
1548 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1556 B = ConstantInt::get(
B->getType(), 1);
1564 for (
User *U :
A->users()) {
1575bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp,
1576 ModifyDT &ModifiedDT) {
1577 bool EdgeCase =
false;
1579 BinaryOperator *
Add;
1584 A =
Add->getOperand(0);
1585 B =
Add->getOperand(1);
1591 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1597 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1600 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1601 Intrinsic::uadd_with_overflow))
1605 ModifiedDT = ModifyDT::ModifyInstDT;
1609bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
1610 ModifyDT &ModifiedDT) {
1617 ICmpInst::Predicate
Pred =
Cmp->getPredicate();
1618 if (
Pred == ICmpInst::ICMP_UGT) {
1620 Pred = ICmpInst::ICMP_ULT;
1624 B = ConstantInt::get(
B->getType(), 1);
1625 Pred = ICmpInst::ICMP_ULT;
1630 Pred = ICmpInst::ICMP_ULT;
1632 if (
Pred != ICmpInst::ICMP_ULT)
1639 BinaryOperator *
Sub =
nullptr;
1640 for (User *U : CmpVariableOperand->
users()) {
1648 const APInt *CmpC, *AddC;
1660 Sub->hasNUsesOrMore(1)))
1666 if (
Sub->getParent() !=
Cmp->getParent() && !
Sub->hasOneUse())
1669 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1670 Cmp, Intrinsic::usub_with_overflow))
1674 ModifiedDT = ModifyDT::ModifyInstDT;
1681bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1694 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1700 Type *OpTy =
X->getType();
1708 if (
Pred == ICmpInst::ICMP_EQ) {
1709 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1710 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1712 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1718 if (IsPowerOf2OrZeroTest ||
1729 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1738 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1741 Cmp->replaceAllUsesWith(NewCmp);
1754 if (
TLI.hasMultipleConditionRegisters(
EVT::getEVT(Cmp->getType())))
1761 bool UsedInPhiOrCurrentBlock =
any_of(Cmp->users(), [Cmp](
User *U) {
1762 return isa<PHINode>(U) ||
1763 cast<Instruction>(U)->getParent() == Cmp->getParent();
1768 if (UsedInPhiOrCurrentBlock && Cmp->getOperand(0)->getType()->isIntegerTy() &&
1769 Cmp->getOperand(0)->getType()->getScalarSizeInBits() >
1770 DL.getLargestLegalIntTypeSizeInBits())
1776 bool MadeChange =
false;
1779 Use &TheUse = UI.getUse();
1794 if (UserBB == DefBB)
1798 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1804 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1811 TheUse = InsertedCmp;
1817 if (Cmp->use_empty()) {
1818 Cmp->eraseFromParent();
1845 bool EnableICmpEqToICmpSt) {
1846 if (!EnableICmpEqToICmpSt &&
TLI.isEqualityCmpFoldedWithSignedCmp())
1855 for (
User *U : Cmp->users()) {
1877 if (CmpBB != FalseBB)
1880 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
1894 for (
User *U : Cmp->users()) {
1896 BI->swapSuccessors();
1902 SI->swapProfMetadata();
1914 Value *Op0 = Cmp->getOperand(0);
1915 Value *Op1 = Cmp->getOperand(1);
1924 unsigned NumInspected = 0;
1927 if (++NumInspected > 128)
1935 if (GoodToSwap > 0) {
1936 Cmp->swapOperands();
1949 EVT VT =
TLI.getValueType(
DL, Cmp->getOperand(0)->getType());
1950 if (
TLI.isFAbsFree(VT) &&
1956 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
1959 auto [ClassVal, ClassTest] =
1965 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
1969 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
1970 Cmp->replaceAllUsesWith(IsFPClass);
1978 Value *Incr, *RemAmt;
1983 Value *AddInst, *AddOffset;
1986 if (PN !=
nullptr) {
1988 AddOffset =
nullptr;
2006 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2010 if (!L->contains(Rem))
2014 if (!L->isLoopInvariant(RemAmt))
2018 if (AddOffset && !L->isLoopInvariant(AddOffset))
2039 AddInstOut = AddInst;
2040 AddOffsetOut = AddOffset;
2059 Value *AddOffset, *RemAmt, *AddInst;
2062 AddOffset, LoopIncrPN))
2087 assert(AddOffset &&
"We found an add but missing values");
2105 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2110 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2117 NewRem->
addIncoming(Start, L->getLoopPreheader());
2122 FreshBBs.
insert(L->getLoopLatch());
2133bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2139bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2143 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2146 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2149 if (unfoldPowerOf2Test(Cmp))
2170 SetOfInstrs &InsertedInsts) {
2173 assert(!InsertedInsts.count(AndI) &&
2174 "Attempting to optimize already optimized and instruction");
2175 (void)InsertedInsts;
2189 for (
auto *U : AndI->
users()) {
2197 if (!CmpC || !CmpC->
isZero())
2201 if (!
TLI.isMaskAndCmp0FoldingBeneficial(*AndI))
2212 Use &TheUse = UI.getUse();
2230 TheUse = InsertedAnd;
2247 if (
User->getOpcode() != Instruction::And ||
2253 if ((Cimm & (Cimm + 1)).getBoolValue())
2267 bool MadeChange =
false;
2270 TruncE = TruncI->user_end();
2271 TruncUI != TruncE;) {
2273 Use &TruncTheUse = TruncUI.getUse();
2279 int ISDOpcode =
TLI.InstructionOpcodeToISD(TruncUser->
getOpcode());
2288 if (
TLI.isOperationLegalOrCustom(
2289 ISDOpcode,
TLI.getValueType(
DL, TruncUser->
getType(),
true)))
2298 if (UserBB == TruncUserBB)
2302 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2304 if (!InsertedShift && !InsertedTrunc) {
2308 if (ShiftI->
getOpcode() == Instruction::AShr)
2310 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2313 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2321 TruncInsertPt.setHeadBit(
true);
2322 assert(TruncInsertPt != TruncUserBB->
end());
2326 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2327 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2331 TruncTheUse = InsertedTrunc;
2362 bool shiftIsLegal =
TLI.isTypeLegal(
TLI.getValueType(
DL, ShiftI->
getType()));
2364 bool MadeChange =
false;
2368 Use &TheUse = UI.getUse();
2382 if (UserBB == DefBB) {
2410 if (!InsertedShift) {
2414 if (ShiftI->
getOpcode() == Instruction::AShr)
2416 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2419 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2427 TheUse = InsertedShift;
2470 if ((IntrinsicID == Intrinsic::cttz &&
TLI->isCheapToSpeculateCttz(Ty)) ||
2471 (IntrinsicID == Intrinsic::ctlz &&
TLI->isCheapToSpeculateCtlz(Ty)))
2475 unsigned SizeInBits = Ty->getScalarSizeInBits();
2476 if (Ty->isVectorTy())
2487 nullptr,
"cond.false");
2489 FreshBBs.
insert(CallBlock);
2496 SplitPt.setHeadBit(
true);
2498 nullptr,
"cond.end");
2500 FreshBBs.
insert(EndBlock);
2504 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2511 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2512 Value *Cmp = Builder.CreateICmpEQ(
Op,
Zero,
"cmpz");
2513 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2519 Builder.SetInsertPoint(EndBlock->
begin());
2520 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2530 ModifiedDT = ModifyDT::ModifyBBDT;
2534bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2538 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2546 for (
auto &Arg : CI->
args()) {
2551 if (!Arg->getType()->isPointerTy())
2553 APInt
Offset(
DL->getIndexSizeInBits(
2556 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2563 if (AllocaSize && AllocaSize->getKnownMinValue() >= MinSize + Offset2)
2581 MaybeAlign MIDestAlign =
MI->getDestAlign();
2582 if (!MIDestAlign || DestAlign > *MIDestAlign)
2583 MI->setDestAlignment(DestAlign);
2585 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2587 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2588 MTI->setSourceAlignment(SrcAlign);
2598 for (
auto &Arg : CI->
args()) {
2599 if (!Arg->getType()->isPointerTy())
2601 unsigned AS = Arg->getType()->getPointerAddressSpace();
2602 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2608 switch (
II->getIntrinsicID()) {
2611 case Intrinsic::assume:
2613 case Intrinsic::allow_runtime_check:
2614 case Intrinsic::allow_ubsan_check:
2615 case Intrinsic::experimental_widenable_condition: {
2619 if (
II->use_empty()) {
2620 II->eraseFromParent();
2624 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2629 case Intrinsic::objectsize:
2631 case Intrinsic::is_constant:
2633 case Intrinsic::aarch64_stlxr:
2634 case Intrinsic::aarch64_stxr: {
2643 InsertedInsts.insert(ExtVal);
2647 case Intrinsic::launder_invariant_group: {
2648 Value *ArgVal =
II->getArgOperand(0);
2649 auto it = LargeOffsetGEPMap.
find(
II);
2650 if (it != LargeOffsetGEPMap.
end()) {
2654 auto GEPs = std::move(it->second);
2655 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2660 II->eraseFromParent();
2663 case Intrinsic::cttz:
2664 case Intrinsic::ctlz:
2668 case Intrinsic::fshl:
2669 case Intrinsic::fshr:
2670 return optimizeFunnelShift(
II);
2671 case Intrinsic::masked_gather:
2672 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2673 case Intrinsic::masked_scatter:
2674 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2675 case Intrinsic::masked_load:
2678 if (VT->getNumElements() == 1) {
2679 Value *PtrVal =
II->getArgOperand(0);
2681 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2686 case Intrinsic::masked_store:
2690 if (VT->getNumElements() == 1) {
2691 Value *PtrVal =
II->getArgOperand(1);
2693 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2698 case Intrinsic::umul_with_overflow:
2699 return optimizeMulWithOverflow(
II,
false, ModifiedDT);
2700 case Intrinsic::smul_with_overflow:
2701 return optimizeMulWithOverflow(
II,
true, ModifiedDT);
2704 SmallVector<Value *, 2> PtrOps;
2707 while (!PtrOps.
empty()) {
2710 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2724 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2726 if (
Value *
V = Simplifier.optimizeCall(CI, Builder)) {
2736 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2737 if (!
F->getReturnType()->isPointerTy())
2740 GlobalVariable *UniformValue =
nullptr;
2741 for (
auto &BB : *
F) {
2746 else if (
V != UniformValue)
2754 return UniformValue;
2757 if (
Callee->hasExactDefinition()) {
2758 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2759 bool MadeChange =
false;
2785 switch (
II->getIntrinsicID()) {
2786 case Intrinsic::memset:
2787 case Intrinsic::memcpy:
2788 case Intrinsic::memmove:
2795 if (Callee && TLInfo)
2797 case LibFunc_strcpy:
2798 case LibFunc_strncpy:
2799 case LibFunc_strcat:
2800 case LibFunc_strncat:
2841bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
2842 ModifyDT &ModifiedDT) {
2847 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2849 PHINode *PN =
nullptr;
2850 ExtractValueInst *EVI =
nullptr;
2851 BitCastInst *BCI =
nullptr;
2873 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
2875 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
2904 auto MayBePermittedAsTailCall = [&](
const auto *CI) {
2921 MayBePermittedAsTailCall(CI)) {
2942 MayBePermittedAsTailCall(CI)) {
2949 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
2953 if (Instruction *
I =
Pred->rbegin()->getPrevNode()) {
2955 if (CI && CI->
use_empty() && MayBePermittedAsTailCall(CI)) {
2970 for (
auto const &TailCallBB : TailCallBBs) {
2979 assert(!Opts.cgp_verify_bfi_updates ||
2980 BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB));
2981 BFI->setBlockFreq(BB,
2982 (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB)));
2983 ModifiedDT = ModifyDT::ModifyBBDT;
2992 for (
auto *CI : CallInsts) {
2993 for (
auto const *FakeUse : FakeUses) {
2994 auto *ClonedInst = FakeUse->clone();
3012struct ExtAddrMode :
public TargetLowering::AddrMode {
3013 Value *BaseReg =
nullptr;
3014 Value *ScaledReg =
nullptr;
3015 Value *OriginalValue =
nullptr;
3016 bool InBounds =
true;
3020 BaseRegField = 0x01,
3022 BaseOffsField = 0x04,
3023 ScaledRegField = 0x08,
3025 MultipleFields = 0xff
3028 ExtAddrMode() =
default;
3030 void print(raw_ostream &OS)
const;
3037 if (ScaledReg == From)
3041 FieldName
compare(
const ExtAddrMode &other) {
3044 if (BaseReg && other.
BaseReg &&
3046 return MultipleFields;
3047 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3048 return MultipleFields;
3051 return MultipleFields;
3054 if (InBounds != other.InBounds)
3055 return MultipleFields;
3058 unsigned Result = NoField;
3061 if (BaseGV != other.BaseGV)
3063 if (BaseOffs != other.BaseOffs)
3066 Result |= ScaledRegField;
3069 if (Scale && other.
Scale && Scale != other.
Scale)
3073 return MultipleFields;
3075 return static_cast<FieldName
>(
Result);
3085 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3096 case ScaledRegField:
3104 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3109 case ExtAddrMode::BaseRegField:
3112 case ExtAddrMode::BaseGVField:
3115 assert(BaseReg ==
nullptr);
3119 case ExtAddrMode::ScaledRegField:
3124 for (
const ExtAddrMode &AM : AddrModes)
3130 case ExtAddrMode::BaseOffsField:
3133 assert(ScaledReg ==
nullptr);
3143static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3149#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3150void ExtAddrMode::print(raw_ostream &OS)
const {
3151 bool NeedPlus =
false;
3157 BaseGV->printAsOperand(OS,
false);
3162 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3167 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3168 BaseReg->printAsOperand(OS,
false);
3172 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3195class TypePromotionTransaction {
3199 class TypePromotionAction {
3207 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3209 virtual ~TypePromotionAction() =
default;
3216 virtual void undo() = 0;
3221 virtual void commit() {
3227 class InsertionHandler {
3236 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3239 bool HasPrevInstruction;
3243 InsertionHandler(Instruction *Inst) {
3251 if (HasPrevInstruction) {
3259 void insert(Instruction *Inst) {
3260 if (HasPrevInstruction) {
3272 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3277 class OperandSetter :
public TypePromotionAction {
3286 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3287 : TypePromotionAction(Inst),
Idx(
Idx) {
3289 <<
"for:" << *Inst <<
"\n"
3290 <<
"with:" << *NewVal <<
"\n");
3296 void undo()
override {
3298 <<
"for: " << *Inst <<
"\n"
3299 <<
"with: " << *Origin <<
"\n");
3306 class OperandsHider :
public TypePromotionAction {
3308 SmallVector<Value *, 4> OriginalValues;
3312 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3315 OriginalValues.
reserve(NumOpnds);
3316 for (
unsigned It = 0; It < NumOpnds; ++It) {
3328 void undo()
override {
3330 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3336 class TruncBuilder :
public TypePromotionAction {
3343 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3345 Builder.SetCurrentDebugLocation(
DebugLoc());
3346 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3351 Value *getBuiltValue() {
return Val; }
3354 void undo()
override {
3357 IVal->eraseFromParent();
3362 class SExtBuilder :
public TypePromotionAction {
3369 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3370 : TypePromotionAction(InsertPt) {
3372 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3377 Value *getBuiltValue() {
return Val; }
3380 void undo()
override {
3383 IVal->eraseFromParent();
3388 class ZExtBuilder :
public TypePromotionAction {
3395 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3396 : TypePromotionAction(InsertPt) {
3398 Builder.SetCurrentDebugLocation(
DebugLoc());
3399 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3404 Value *getBuiltValue() {
return Val; }
3407 void undo()
override {
3410 IVal->eraseFromParent();
3415 class TypeMutator :
public TypePromotionAction {
3421 TypeMutator(Instruction *Inst,
Type *NewTy)
3422 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3423 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3429 void undo()
override {
3430 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3437 class UsesReplacer :
public TypePromotionAction {
3439 struct InstructionAndIdx {
3446 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3447 : Inst(Inst),
Idx(
Idx) {}
3453 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3461 UsesReplacer(Instruction *Inst,
Value *New)
3462 : TypePromotionAction(Inst),
New(
New) {
3463 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3466 for (Use &U : Inst->
uses()) {
3468 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3479 void undo()
override {
3481 for (InstructionAndIdx &Use : OriginalUses)
3482 Use.Inst->setOperand(
Use.Idx, Inst);
3487 for (DbgVariableRecord *DVR : DbgVariableRecords)
3488 DVR->replaceVariableLocationOp(New, Inst);
3493 class InstructionRemover :
public TypePromotionAction {
3495 InsertionHandler Inserter;
3499 OperandsHider Hider;
3502 UsesReplacer *Replacer =
nullptr;
3505 SetOfInstrs &RemovedInsts;
3512 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3513 Value *New =
nullptr)
3514 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3515 RemovedInsts(RemovedInsts) {
3517 Replacer =
new UsesReplacer(Inst, New);
3518 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3519 RemovedInsts.insert(Inst);
3526 ~InstructionRemover()
override {
delete Replacer; }
3528 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3529 InstructionRemover(
const InstructionRemover &other) =
delete;
3533 void undo()
override {
3534 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3535 Inserter.insert(Inst);
3539 RemovedInsts.erase(Inst);
3547 using ConstRestorationPt =
const TypePromotionAction *;
3549 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3550 : RemovedInsts(RemovedInsts) {}
3557 void rollback(ConstRestorationPt Point);
3560 ConstRestorationPt getRestorationPoint()
const;
3565 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3574 void mutateType(Instruction *Inst,
Type *NewTy);
3577 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3589 SetOfInstrs &RemovedInsts;
3594void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3596 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3597 Inst, Idx, NewVal));
3600void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3603 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3604 Inst, RemovedInsts, NewVal));
3607void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3610 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3613void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3615 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3618Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3619 std::unique_ptr<TruncBuilder> Ptr(
new TruncBuilder(Opnd, Ty));
3620 Value *Val = Ptr->getBuiltValue();
3621 Actions.push_back(std::move(Ptr));
3625Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3627 std::unique_ptr<SExtBuilder> Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3628 Value *Val = Ptr->getBuiltValue();
3629 Actions.push_back(std::move(Ptr));
3633Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3635 std::unique_ptr<ZExtBuilder> Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3636 Value *Val = Ptr->getBuiltValue();
3637 Actions.push_back(std::move(Ptr));
3641TypePromotionTransaction::ConstRestorationPt
3642TypePromotionTransaction::getRestorationPoint()
const {
3643 return !Actions.empty() ? Actions.back().get() :
nullptr;
3646bool TypePromotionTransaction::commit() {
3647 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3654void TypePromotionTransaction::rollback(
3655 TypePromotionTransaction::ConstRestorationPt Point) {
3656 while (!Actions.empty() && Point != Actions.back().get()) {
3657 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3667class AddressingModeMatcher {
3668 SmallVectorImpl<Instruction *> &AddrModeInsts;
3669 const TargetLowering &
TLI;
3670 const TargetRegisterInfo &
TRI;
3671 const DataLayout &
DL;
3673 const std::function<
const DominatorTree &()> getDTFn;
3686 const SetOfInstrs &InsertedInsts;
3689 InstrToOrigTy &PromotedInsts;
3692 TypePromotionTransaction &TPT;
3695 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3699 bool IgnoreProfitability;
3702 bool OptSize =
false;
3704 ProfileSummaryInfo *PSI;
3705 BlockFrequencyInfo *BFI;
3706 const CodeGenOptions &Opts;
3708 AddressingModeMatcher(
3709 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &
TLI,
3710 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3711 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3712 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3713 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3714 TypePromotionTransaction &TPT,
3715 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3716 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
3717 const CodeGenOptions &Opts)
3719 getDTFn(getDTFn), AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
3720 AddrMode(AM), InsertedInsts(InsertedInsts),
3721 PromotedInsts(PromotedInsts), TPT(TPT), LargeOffsetGEP(LargeOffsetGEP),
3722 OptSize(OptSize), PSI(PSI), BFI(BFI), Opts(Opts) {
3723 IgnoreProfitability =
false;
3735 Match(
Value *
V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3736 SmallVectorImpl<Instruction *> &AddrModeInsts,
3737 const TargetLowering &
TLI,
const LoopInfo &LI,
3738 const std::function<
const DominatorTree &()> getDTFn,
3739 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3740 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3741 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3742 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
3743 const CodeGenOptions &Opts) {
3746 bool Success = AddressingModeMatcher(
3747 AddrModeInsts,
TLI,
TRI, LI, getDTFn, AccessTy, AS,
3748 MemoryInst, Result, InsertedInsts, PromotedInsts, TPT,
3749 LargeOffsetGEP, OptSize, PSI, BFI, Opts)
3757 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3759 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3760 bool *MovedAway =
nullptr);
3761 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3762 ExtAddrMode &AMBefore,
3763 ExtAddrMode &AMAfter);
3764 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3765 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3766 Value *PromotedOperand)
const;
3772class PhiNodeSetIterator {
3773 PhiNodeSet *
const Set;
3774 size_t CurrentIndex = 0;
3779 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3781 PhiNodeSetIterator &operator++();
3797 friend class PhiNodeSetIterator;
3799 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3800 using iterator = PhiNodeSetIterator;
3815 size_t FirstValidElement = 0;
3821 bool insert(PHINode *Ptr) {
3822 if (NodeMap.insert(std::make_pair(Ptr,
NodeList.
size())).second) {
3832 bool erase(PHINode *Ptr) {
3833 if (NodeMap.erase(Ptr)) {
3834 SkipRemovedElements(FirstValidElement);
3844 FirstValidElement = 0;
3850 if (FirstValidElement == 0)
3851 SkipRemovedElements(FirstValidElement);
3852 return PhiNodeSetIterator(
this, FirstValidElement);
3859 size_t size()
const {
return NodeMap.size(); }
3862 size_t count(PHINode *Ptr)
const {
return NodeMap.count(Ptr); }
3870 void SkipRemovedElements(
size_t &CurrentIndex) {
3872 auto it = NodeMap.find(NodeList[CurrentIndex]);
3875 if (it != NodeMap.end() && it->second == CurrentIndex)
3882PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
3885PHINode *PhiNodeSetIterator::operator*()
const {
3887 "PhiNodeSet access out of range");
3888 return Set->NodeList[CurrentIndex];
3891PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
3893 "PhiNodeSet access out of range");
3895 Set->SkipRemovedElements(CurrentIndex);
3899bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
3900 return CurrentIndex ==
RHS.CurrentIndex;
3903bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
3904 return !((*this) ==
RHS);
3910class SimplificationTracker {
3911 DenseMap<Value *, Value *> Storage;
3914 PhiNodeSet AllPhiNodes;
3916 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
3922 if (SV == Storage.
end())
3930 void ReplacePhi(PHINode *From, PHINode *To) {
3931 Value *OldReplacement = Get(From);
3932 while (OldReplacement != From) {
3935 OldReplacement = Get(From);
3937 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
3940 AllPhiNodes.erase(From);
3944 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
3946 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
3948 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
3950 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
3952 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
3954 void destroyNewNodes(
Type *CommonType) {
3957 for (
auto *
I : AllPhiNodes) {
3958 I->replaceAllUsesWith(Dummy);
3959 I->eraseFromParent();
3961 AllPhiNodes.clear();
3962 for (
auto *
I : AllSelectNodes) {
3963 I->replaceAllUsesWith(Dummy);
3964 I->eraseFromParent();
3966 AllSelectNodes.clear();
3971class AddressingModeCombiner {
3972 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
3973 typedef std::pair<PHINode *, PHINode *> PHIPair;
3980 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
3983 bool AllAddrModesTrivial =
true;
3986 Type *CommonType =
nullptr;
3988 const DataLayout &
DL;
3989 const CodeGenOptions &Opts;
3995 Value *CommonValue =
nullptr;
3998 AddressingModeCombiner(
const DataLayout &
DL,
const CodeGenOptions &Opts,
3999 Value *OriginalValue)
4000 :
DL(
DL), Opts(Opts), Original(OriginalValue) {}
4002 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4005 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4010 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4014 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4017 if (AddrModes.
empty()) {
4025 ExtAddrMode::FieldName ThisDifferentField =
4026 AddrModes[0].compare(NewAddrMode);
4027 if (DifferentField == ExtAddrMode::NoField)
4028 DifferentField = ThisDifferentField;
4029 else if (DifferentField != ThisDifferentField)
4030 DifferentField = ExtAddrMode::MultipleFields;
4033 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4036 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4041 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4046 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4047 !NewAddrMode.HasBaseReg);
4064 bool combineAddrModes() {
4066 if (AddrModes.
size() == 0)
4070 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4075 if (AllAddrModesTrivial)
4078 if (!addrModeCombiningAllowed())
4084 FoldAddrToValueMapping
Map;
4085 if (!initializeMap(Map))
4088 CommonValue = findCommon(Map);
4090 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4091 return CommonValue !=
nullptr;
4097 void eraseCommonValueIfDead() {
4098 if (CommonValue && CommonValue->
use_empty())
4100 CommonInst->eraseFromParent();
4108 bool initializeMap(FoldAddrToValueMapping &Map) {
4111 SmallVector<Value *, 2> NullValue;
4113 for (
auto &AM : AddrModes) {
4117 if (CommonType && CommonType !=
Type)
4120 Map[AM.OriginalValue] = DV;
4125 assert(CommonType &&
"At least one non-null value must be!");
4126 for (
auto *
V : NullValue)
4154 Value *findCommon(FoldAddrToValueMapping &Map) {
4162 SimplificationTracker
ST;
4167 InsertPlaceholders(Map, TraverseOrder, ST);
4170 FillPlaceholders(Map, TraverseOrder, ST);
4172 if (!Opts.cgp_addr_sink_new_select &&
ST.countNewSelectNodes() > 0) {
4173 ST.destroyNewNodes(CommonType);
4178 unsigned PhiNotMatchedCount = 0;
4179 if (!MatchPhiSet(ST, Opts.cgp_addr_sink_new_phis, PhiNotMatchedCount)) {
4180 ST.destroyNewNodes(CommonType);
4184 auto *
Result =
ST.Get(
Map.find(Original)->second);
4186 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4187 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4194 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4195 SmallSetVector<PHIPair, 8> &Matcher,
4196 PhiNodeSet &PhiNodesToMatch) {
4199 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4202 SmallSet<PHIPair, 8> Visited;
4203 while (!WorkList.
empty()) {
4205 if (!Visited.
insert(Item).second)
4212 for (
auto *
B : Item.first->blocks()) {
4213 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4214 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4215 if (FirstValue == SecondValue)
4225 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4230 if (Matcher.
count({FirstPhi, SecondPhi}))
4235 if (MatchedPHIs.
insert(FirstPhi).second)
4236 Matcher.
insert({FirstPhi, SecondPhi});
4238 WorkList.
push_back({FirstPhi, SecondPhi});
4247 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4248 unsigned &PhiNotMatchedCount) {
4252 SmallSetVector<PHIPair, 8> Matched;
4253 SmallPtrSet<PHINode *, 8> WillNotMatch;
4254 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4255 while (PhiNodesToMatch.size()) {
4256 PHINode *
PHI = *PhiNodesToMatch.begin();
4259 WillNotMatch.
clear();
4263 bool IsMatched =
false;
4264 for (
auto &
P :
PHI->getParent()->phis()) {
4266 if (PhiNodesToMatch.count(&
P))
4268 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4278 for (
auto MV : Matched)
4279 ST.ReplacePhi(MV.first, MV.second);
4284 if (!AllowNewPhiNodes)
4287 PhiNotMatchedCount += WillNotMatch.
size();
4288 for (
auto *
P : WillNotMatch)
4289 PhiNodesToMatch.erase(
P);
4294 void FillPlaceholders(FoldAddrToValueMapping &Map,
4295 SmallVectorImpl<Value *> &TraverseOrder,
4296 SimplificationTracker &ST) {
4297 while (!TraverseOrder.
empty()) {
4299 assert(
Map.contains(Current) &&
"No node to fill!!!");
4305 auto *TrueValue = CurrentSelect->getTrueValue();
4306 assert(
Map.contains(TrueValue) &&
"No True Value!");
4307 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4308 auto *FalseValue = CurrentSelect->getFalseValue();
4309 assert(
Map.contains(FalseValue) &&
"No False Value!");
4310 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4317 assert(
Map.contains(PV) &&
"No predecessor Value!");
4318 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4329 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4330 SmallVectorImpl<Value *> &TraverseOrder,
4331 SimplificationTracker &ST) {
4334 "Address must be a Phi or Select node");
4337 while (!Worklist.
empty()) {
4340 if (
Map.contains(Current))
4351 CurrentSelect->getName(),
4352 CurrentSelect->getIterator(), CurrentSelect);
4356 Worklist.
push_back(CurrentSelect->getTrueValue());
4357 Worklist.
push_back(CurrentSelect->getFalseValue());
4365 ST.insertNewPhi(
PHI);
4371 bool addrModeCombiningAllowed() {
4372 if (!Opts.cgp_complex_addr_modes)
4374 switch (DifferentField) {
4377 case ExtAddrMode::BaseRegField:
4378 return Opts.cgp_addr_sink_combine_base_reg;
4379 case ExtAddrMode::BaseGVField:
4380 return Opts.cgp_addr_sink_combine_base_gv;
4381 case ExtAddrMode::BaseOffsField:
4382 return Opts.cgp_addr_sink_combine_base_offs;
4383 case ExtAddrMode::ScaledRegField:
4384 return Opts.cgp_addr_sink_combine_scaled_reg;
4393bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4398 return matchAddr(ScaleReg,
Depth);
4409 ExtAddrMode TestAddrMode =
AddrMode;
4413 TestAddrMode.
Scale += Scale;
4427 ConstantInt *CI =
nullptr;
4428 Value *AddLHS =
nullptr;
4432 TestAddrMode.InBounds =
false;
4449 auto GetConstantStep =
4450 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4453 return std::nullopt;
4456 return std::nullopt;
4464 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4465 return std::nullopt;
4467 return std::make_pair(IVInc->first, ConstantStep->getValue());
4468 return std::nullopt;
4483 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4490 APInt Step = IVStep->second;
4492 if (
Offset.isSignedIntN(64)) {
4493 TestAddrMode.InBounds =
false;
4495 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4500 getDTFn().
dominates(IVInc, MemoryInst)) {
4520 switch (
I->getOpcode()) {
4521 case Instruction::BitCast:
4522 case Instruction::AddrSpaceCast:
4524 if (
I->getType() ==
I->getOperand(0)->getType())
4526 return I->getType()->isIntOrPtrTy();
4527 case Instruction::PtrToInt:
4530 case Instruction::IntToPtr:
4533 case Instruction::Add:
4535 case Instruction::Or:
4537 case Instruction::Mul:
4538 case Instruction::Shl:
4541 case Instruction::GetElementPtr:
4557 int ISDOpcode =
TLI.InstructionOpcodeToISD(PromotedInst->
getOpcode());
4562 return TLI.isOperationLegalOrCustom(
4563 ISDOpcode,
TLI.getValueType(
DL, PromotedInst->
getType()));
4569class TypePromotionHelper {
4572 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4573 Instruction *ExtOpnd,
bool IsSExt) {
4574 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4575 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4579 if (It->second.getInt() == ExtTy)
4585 ExtTy = BothExtension;
4587 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4594 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4595 Instruction *Opnd,
bool IsSExt) {
4596 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4597 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4598 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4599 return It->second.getPointer();
4614 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4615 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4619 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4632 static Value *promoteOperandForTruncAndAnyExt(
4633 Instruction *Ext, TypePromotionTransaction &TPT,
4634 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4635 SmallVectorImpl<Instruction *> *Exts,
4636 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &
TLI);
4647 static Value *promoteOperandForOther(Instruction *Ext,
4648 TypePromotionTransaction &TPT,
4649 InstrToOrigTy &PromotedInsts,
4650 unsigned &CreatedInstsCost,
4651 SmallVectorImpl<Instruction *> *Exts,
4652 SmallVectorImpl<Instruction *> *Truncs,
4653 const TargetLowering &
TLI,
bool IsSExt);
4656 static Value *signExtendOperandForOther(
4657 Instruction *Ext, TypePromotionTransaction &TPT,
4658 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4659 SmallVectorImpl<Instruction *> *Exts,
4660 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &
TLI) {
4661 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4662 Exts, Truncs,
TLI,
true);
4666 static Value *zeroExtendOperandForOther(
4667 Instruction *Ext, TypePromotionTransaction &TPT,
4668 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4669 SmallVectorImpl<Instruction *> *Exts,
4670 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &
TLI) {
4671 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4672 Exts, Truncs,
TLI,
false);
4677 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4678 InstrToOrigTy &PromotedInsts,
4679 unsigned &CreatedInstsCost,
4680 SmallVectorImpl<Instruction *> *Exts,
4681 SmallVectorImpl<Instruction *> *Truncs,
4682 const TargetLowering &
TLI);
4693 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4694 const TargetLowering &
TLI,
4695 const InstrToOrigTy &PromotedInsts);
4700bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4701 Type *ConsideredExtType,
4702 const InstrToOrigTy &PromotedInsts,
4722 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4723 (IsSExt && BinOp->hasNoSignedWrap())))
4727 if ((Inst->
getOpcode() == Instruction::And ||
4732 if (Inst->
getOpcode() == Instruction::Xor) {
4735 if (!Cst->getValue().isAllOnes())
4744 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4754 if (ExtInst->hasOneUse()) {
4756 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4789 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4802TypePromotionHelper::Action TypePromotionHelper::getAction(
4803 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4804 const TargetLowering &
TLI,
const InstrToOrigTy &PromotedInsts) {
4806 "Unexpected instruction type");
4813 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4826 return promoteOperandForTruncAndAnyExt;
4832 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4835Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4836 Instruction *SExt, TypePromotionTransaction &TPT,
4837 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4838 SmallVectorImpl<Instruction *> *Exts,
4839 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &
TLI) {
4843 Value *ExtVal = SExt;
4844 bool HasMergedNonFreeExt =
false;
4851 TPT.replaceAllUsesWith(SExt, ZExt);
4852 TPT.eraseInstruction(SExt);
4857 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
4859 CreatedInstsCost = 0;
4863 TPT.eraseInstruction(SExtOpnd);
4871 CreatedInstsCost = !
TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
4879 TPT.eraseInstruction(ExtInst, NextVal);
4883Value *TypePromotionHelper::promoteOperandForOther(
4884 Instruction *Ext, TypePromotionTransaction &TPT,
4885 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4886 SmallVectorImpl<Instruction *> *Exts,
4887 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &
TLI,
4892 CreatedInstsCost = 0;
4898 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
4901 ITrunc->moveAfter(ExtOpnd);
4906 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
4909 TPT.setOperand(Ext, 0, ExtOpnd);
4919 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
4921 TPT.mutateType(ExtOpnd, Ext->
getType());
4923 TPT.replaceAllUsesWith(Ext, ExtOpnd);
4926 for (
int OpIdx = 0, EndOpIdx = ExtOpnd->
getNumOperands(); OpIdx != EndOpIdx;
4930 !shouldExtOperand(ExtOpnd, OpIdx)) {
4939 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
4941 TPT.setOperand(ExtOpnd, OpIdx, ConstantInt::get(Ext->
getType(), CstVal));
4952 Value *ValForExtOpnd = IsSExt
4953 ? TPT.createSExt(ExtOpnd, Opnd, Ext->
getType())
4954 : TPT.createZExt(ExtOpnd, Opnd, Ext->
getType());
4955 TPT.setOperand(ExtOpnd, OpIdx, ValForExtOpnd);
4957 if (!InstForExtOpnd)
4966 TPT.eraseInstruction(Ext);
4978bool AddressingModeMatcher::isPromotionProfitable(
4979 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
4980 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
4985 if (NewCost > OldCost)
4987 if (NewCost < OldCost)
5006bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5018 case Instruction::PtrToInt:
5021 case Instruction::IntToPtr: {
5029 case Instruction::BitCast:
5039 case Instruction::AddrSpaceCast: {
5047 case Instruction::Or:
5051 case Instruction::Add: {
5054 ExtAddrMode BackupAddrMode =
AddrMode;
5055 unsigned OldSize = AddrModeInsts.
size();
5060 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5061 TPT.getRestorationPoint();
5065 int First = 0, Second = 1;
5076 AddrModeInsts.
resize(OldSize);
5077 TPT.rollback(LastKnownGood);
5087 AddrModeInsts.
resize(OldSize);
5088 TPT.rollback(LastKnownGood);
5091 case Instruction::Mul:
5092 case Instruction::Shl: {
5096 if (!
RHS ||
RHS->getBitWidth() > 64)
5098 int64_t Scale = Opcode == Instruction::Shl
5099 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5100 :
RHS->getSExtValue();
5104 case Instruction::GetElementPtr: {
5107 int VariableOperand = -1;
5108 unsigned VariableScale = 0;
5110 int64_t ConstantOffset = 0;
5112 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5114 const StructLayout *SL =
DL.getStructLayout(STy);
5125 if (ConstantInt *CI =
5127 const APInt &CVal = CI->
getValue();
5134 if (VariableOperand != -1)
5138 VariableOperand = i;
5139 VariableScale = TypeSize;
5146 if (VariableOperand == -1) {
5147 AddrMode.BaseOffs += ConstantOffset;
5153 AddrMode.BaseOffs -= ConstantOffset;
5157 ConstantOffset != 0) {
5171 BaseI ? BaseI->getParent() : &
GEP->getFunction()->getEntryBlock();
5173 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5181 ExtAddrMode BackupAddrMode =
AddrMode;
5182 unsigned OldSize = AddrModeInsts.
size();
5185 AddrMode.BaseOffs += ConstantOffset;
5194 AddrModeInsts.
resize(OldSize);
5202 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5207 AddrModeInsts.
resize(OldSize);
5212 AddrMode.BaseOffs += ConstantOffset;
5213 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5214 VariableScale,
Depth)) {
5217 AddrModeInsts.
resize(OldSize);
5224 case Instruction::SExt:
5225 case Instruction::ZExt: {
5232 TypePromotionHelper::Action TPH =
5233 TypePromotionHelper::getAction(Ext, InsertedInsts,
TLI, PromotedInsts);
5237 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5238 TPT.getRestorationPoint();
5239 unsigned CreatedInstsCost = 0;
5241 Value *PromotedOperand =
5242 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr,
TLI);
5257 assert(PromotedOperand &&
5258 "TypePromotionHelper should have filtered out those cases");
5260 ExtAddrMode BackupAddrMode =
AddrMode;
5261 unsigned OldSize = AddrModeInsts.
size();
5263 if (!matchAddr(PromotedOperand,
Depth) ||
5268 !isPromotionProfitable(CreatedInstsCost,
5269 ExtCost + (AddrModeInsts.
size() - OldSize),
5272 AddrModeInsts.
resize(OldSize);
5273 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5274 TPT.rollback(LastKnownGood);
5279 AddrMode.replaceWith(Ext, PromotedOperand);
5282 case Instruction::Call:
5284 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5300bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5303 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5304 TPT.getRestorationPoint();
5328 ExtAddrMode BackupAddrMode =
AddrMode;
5329 unsigned OldSize = AddrModeInsts.
size();
5332 bool MovedAway =
false;
5333 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5341 if (
I->hasOneUse() ||
5342 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5349 AddrModeInsts.
resize(OldSize);
5350 TPT.rollback(LastKnownGood);
5353 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5355 TPT.rollback(LastKnownGood);
5382 TPT.rollback(LastKnownGood);
5393 TLI.ParseConstraints(
F->getDataLayout(), &
TRI, *CI);
5397 TLI.ComputeConstraintToUse(OpInfo,
SDValue());
5401 if (OpInfo.CallOperandVal == OpVal &&
5403 !OpInfo.isIndirect))
5419 if (!ConsideredInsts.
insert(
I).second)
5427 for (
Use &U :
I->uses()) {
5430 if (SeenInsts++ >= MaxUsersToScan)
5435 MemoryUses.push_back({&U, LI->getType()});
5442 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5449 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5456 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5463 if (!
TLI.getAddrModeArguments(
II, PtrOps, AccessTy))
5466 if (!
find(PtrOps, U.get()))
5469 MemoryUses.push_back({&U, AccessTy});
5474 if (CI->hasFnAttr(Attribute::Cold)) {
5492 PSI, BFI, SeenInsts, MaxUsersToScan))
5503 unsigned SeenInsts = 0;
5506 PSI, BFI, SeenInsts, MaxUsersToScan);
5513bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5515 Value *KnownLive2) {
5517 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5558bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5559 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5560 if (IgnoreProfitability)
5578 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5579 ScaledReg =
nullptr;
5583 if (!BaseReg && !ScaledReg)
5592 Opts.cgp_max_address_users_to_scan))
5605 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5608 Type *AddressAccessTy = Pair.second;
5609 unsigned AS =
Address->getType()->getPointerAddressSpace();
5615 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5617 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5618 TPT.getRestorationPoint();
5619 AddressingModeMatcher Matcher(MatchedAddrModeInsts,
TLI,
TRI, LI, getDTFn,
5620 AddressAccessTy, AS, UserI, Result,
5621 InsertedInsts, PromotedInsts, TPT,
5622 LargeOffsetGEP, OptSize, PSI, BFI, Opts);
5623 Matcher.IgnoreProfitability =
true;
5631 TPT.rollback(LastKnownGood);
5637 MatchedAddrModeInsts.
clear();
5647 return I->getParent() != BB;
5663 return std::next(AddrInst->getIterator());
5674 Earliest = UserInst;
5699bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5700 Type *AccessTy,
unsigned AddrSpace) {
5705 SmallVector<Value *, 8> worklist;
5706 SmallPtrSet<Value *, 16> Visited;
5712 bool PhiOrSelectSeen =
false;
5713 SmallVector<Instruction *, 16> AddrModeInsts;
5714 AddressingModeCombiner AddrModes(*
DL, Opts, Addr);
5715 TypePromotionTransaction TPT(RemovedInsts);
5716 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5717 TPT.getRestorationPoint();
5718 while (!worklist.
empty()) {
5730 if (!Visited.
insert(
V).second)
5736 PhiOrSelectSeen =
true;
5743 PhiOrSelectSeen =
true;
5750 AddrModeInsts.
clear();
5751 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5756 auto getDTFn = [
this]() ->
const DominatorTree & {
return getDT(); };
5757 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5758 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *
TLI, *LI, getDTFn,
5759 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5762 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5767 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5768 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5771 NewAddrMode.OriginalValue =
V;
5772 if (!AddrModes.addNewAddrMode(NewAddrMode))
5779 if (!AddrModes.combineAddrModes()) {
5780 TPT.rollback(LastKnownGood);
5786 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5792 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *
V) {
5806 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
5829 <<
" for " << *MemoryInst <<
"\n");
5833 !
DL->isNonIntegralPointerType(Addr->
getType())) {
5839 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
5841 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
5843 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
5845 }
else if (
valueOr(Opts.cgp_addr_sink_using_gep,
true) ||
5846 (Opts.cgp_addr_sink_using_gep == BoolOrDefault::Default &&
5851 <<
" for " << *MemoryInst <<
"\n");
5852 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
5863 if (ResultPtr ||
AddrMode.Scale != 1)
5884 GlobalValue *BaseGV =
AddrMode.BaseGV;
5885 if (BaseGV !=
nullptr) {
5890 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
5899 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
5900 if (!ResultPtr &&
AddrMode.BaseReg) {
5904 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
5905 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
5914 }
else if (!ResultPtr) {
5927 if (
V->getType() != IdxTy)
5928 V = Builder.CreateIntCast(
V, IdxTy,
true,
"sunkaddr");
5936 if (
V->getType() == IdxTy) {
5941 "We can't transform if ScaledReg is too narrow");
5942 V = Builder.CreateTrunc(
V, IdxTy,
"sunkaddr");
5946 V = Builder.CreateMul(
5949 ResultIndex = Builder.CreateAdd(ResultIndex,
V,
"sunkaddr");
5960 if (ResultPtr->
getType() != I8PtrTy)
5961 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
5962 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
5975 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
5977 SunkAddr = ResultPtr;
5979 if (ResultPtr->
getType() != I8PtrTy)
5980 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
5981 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
5988 !
DL->isNonIntegralPointerType(Addr->
getType())) {
5994 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
5996 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
5998 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6008 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6009 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6010 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6012 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6016 <<
" for " << *MemoryInst <<
"\n");
6027 if (
V->getType()->isPointerTy())
6028 V = Builder.CreatePtrToInt(
V,
IntPtrTy,
"sunkaddr");
6030 V = Builder.CreateIntCast(
V,
IntPtrTy,
true,
"sunkaddr");
6039 }
else if (
V->getType()->isPointerTy()) {
6040 V = Builder.CreatePtrToInt(
V,
IntPtrTy,
"sunkaddr");
6043 V = Builder.CreateTrunc(
V,
IntPtrTy,
"sunkaddr");
6052 I->eraseFromParent();
6056 V = Builder.CreateMul(
6059 Result = Builder.CreateAdd(Result,
V,
"sunkaddr");
6065 GlobalValue *BaseGV =
AddrMode.BaseGV;
6066 if (BaseGV !=
nullptr) {
6069 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6073 Value *
V = Builder.CreatePtrToInt(BaseGVPtr,
IntPtrTy,
"sunkaddr");
6075 Result = Builder.CreateAdd(Result,
V,
"sunkaddr");
6084 Result = Builder.CreateAdd(Result,
V,
"sunkaddr");
6092 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6098 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6103 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6104 RecursivelyDeleteTriviallyDeadInstructions(
6105 Repl, TLInfo, nullptr,
6106 [&](Value *V) { removeAllAssertingVHReferences(V); });
6130bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6136 if (!
GEP->hasIndices())
6144 SmallVector<Value *, 2>
Ops(
GEP->operands());
6146 bool RewriteGEP =
false;
6155 unsigned FinalIndex =
Ops.size() - 1;
6160 for (
unsigned i = 1; i < FinalIndex; ++i) {
6165 C =
C->getSplatValue();
6167 if (!CI || !CI->
isZero())
6174 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6178 if (!
C || !
C->isZero()) {
6179 Ops[FinalIndex] =
V;
6187 if (!RewriteGEP &&
Ops.size() == 2)
6193 Builder.disableGEPCanonicalization();
6195 Type *SourceTy =
GEP->getSourceElementType();
6196 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6200 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6201 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6202 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6212 if (
Ops.size() != 2) {
6222 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6234 Builder.disableGEPCanonicalization();
6237 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6238 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6241 Intrinsic::masked_gather) {
6245 Intrinsic::masked_scatter);
6260 Ptr, TLInfo,
nullptr,
6261 [&](
Value *
V) { removeAllAssertingVHReferences(
V); });
6272 if (
I->hasNUsesOrMore(3))
6275 for (
User *U :
I->users()) {
6277 if (!Extract || Extract->getNumIndices() != 1)
6280 unsigned Index = Extract->getIndices()[0];
6282 MulExtract = Extract;
6283 else if (Index == 1)
6284 OverflowExtract = Extract;
6311bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
6312 ModifyDT &ModifiedDT) {
6319 ExtractValueInst *MulExtract =
nullptr, *OverflowExtract =
nullptr;
6324 InsertedInsts.insert(
I);
6335 OverflowEntryBB->
takeName(
I->getParent());
6341 NoOverflowBB->
moveAfter(OverflowEntryBB);
6349 Value *LoLHS = Builder.CreateTrunc(
LHS, LegalTy,
"lo.lhs");
6350 Value *HiLHS = Builder.CreateLShr(
LHS, VTHalfBitWidth,
"lhs.lsr");
6351 HiLHS = Builder.CreateTrunc(HiLHS, LegalTy,
"hi.lhs");
6354 Value *LoRHS = Builder.CreateTrunc(
RHS, LegalTy,
"lo.rhs");
6355 Value *HiRHS = Builder.CreateLShr(
RHS, VTHalfBitWidth,
"rhs.lsr");
6356 HiRHS = Builder.CreateTrunc(HiRHS, LegalTy,
"hi.rhs");
6358 Value *IsAnyBitTrue;
6361 Builder.CreateAShr(LoLHS, VTHalfBitWidth - 1,
"sign.lo.lhs");
6363 Builder.CreateAShr(LoRHS, VTHalfBitWidth - 1,
"sign.lo.rhs");
6364 Value *XorLHS = Builder.CreateXor(HiLHS, SignLoLHS);
6365 Value *XorRHS = Builder.CreateXor(HiRHS, SignLoRHS);
6366 Value *
Or = Builder.CreateOr(XorLHS, XorRHS,
"or.lhs.rhs");
6367 IsAnyBitTrue = Builder.CreateCmp(ICmpInst::ICMP_NE,
Or,
6368 ConstantInt::getNullValue(
Or->getType()));
6370 Value *CmpLHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiLHS,
6371 ConstantInt::getNullValue(LegalTy));
6372 Value *CmpRHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiRHS,
6373 ConstantInt::getNullValue(LegalTy));
6374 IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS,
"or.lhs.rhs");
6376 Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
6379 Builder.SetInsertPoint(NoOverflowBB);
6380 Value *ExtLoLHS, *ExtLoRHS;
6382 ExtLoLHS = Builder.CreateSExt(LoLHS, Ty,
"lo.lhs.ext");
6383 ExtLoRHS = Builder.CreateSExt(LoRHS, Ty,
"lo.rhs.ext");
6385 ExtLoLHS = Builder.CreateZExt(LoLHS, Ty,
"lo.lhs.ext");
6386 ExtLoRHS = Builder.CreateZExt(LoRHS, Ty,
"lo.rhs.ext");
6389 Value *
Mul = Builder.CreateMul(ExtLoLHS, ExtLoRHS,
"mul.overflow.no");
6394 OverflowResBB->
setName(
"overflow.res");
6397 Builder.CreateBr(OverflowResBB);
6405 PHINode *OverflowResPHI = Builder.CreatePHI(Ty, 2),
6407 Builder.CreatePHI(IntegerType::getInt1Ty(
I->getContext()), 2);
6419 if (OverflowExtract) {
6420 OverflowExtract->replaceAllUsesWith(OverflowFlagPHI);
6421 OverflowExtract->eraseFromParent();
6426 I->removeFromParent();
6428 I->insertInto(OverflowBB, OverflowBB->
end());
6429 Builder.SetInsertPoint(OverflowBB->
end());
6431 Value *OverflowFlag = Builder.CreateExtractValue(
I, {1},
"overflow.flag");
6432 Builder.CreateBr(OverflowResBB);
6436 OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
6438 DTU->
applyUpdates({{DominatorTree::Insert, OverflowEntryBB, OverflowBB},
6439 {DominatorTree::Insert, OverflowEntryBB, NoOverflowBB},
6440 {DominatorTree::Insert, NoOverflowBB, OverflowResBB},
6441 {DominatorTree::Delete, OverflowEntryBB, OverflowResBB},
6442 {DominatorTree::Insert, OverflowBB, OverflowResBB}});
6444 ModifiedDT = ModifyDT::ModifyBBDT;
6450bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6451 bool MadeChange =
false;
6453 const TargetRegisterInfo *
TRI =
6458 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6464 OpInfo.isIndirect) {
6466 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6515 if (!
TLI.isZExtFree(NarrowTy, LargeTy))
6529bool CodeGenPrepare::tryToPromoteExts(
6530 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6531 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6532 unsigned CreatedInstsCost) {
6533 bool Promoted =
false;
6536 for (
auto *
I : Exts) {
6551 TypePromotionHelper::Action TPH =
6552 TypePromotionHelper::getAction(
I, InsertedInsts, *
TLI, PromotedInsts);
6561 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6562 TPT.getRestorationPoint();
6563 SmallVector<Instruction *, 4> NewExts;
6564 unsigned NewCreatedInstsCost = 0;
6567 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6568 &NewExts,
nullptr, *
TLI);
6570 "TypePromotionHelper should have filtered out those cases");
6580 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6583 TotalCreatedInstsCost =
6584 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6585 if (!Opts.cgp_stress_ext_ld_promotion &&
6586 (TotalCreatedInstsCost > 1 ||
6588 (ExtCost == 0 && NewExts.
size() > 1))) {
6592 TPT.rollback(LastKnownGood);
6597 SmallVector<Instruction *, 2> NewlyMovedExts;
6598 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6599 bool NewPromoted =
false;
6600 for (
auto *ExtInst : NewlyMovedExts) {
6606 !(Opts.cgp_stress_ext_ld_promotion ||
6607 NewCreatedInstsCost <= ExtCost ||
6611 ProfitablyMovedExts.
push_back(MovedExt);
6618 TPT.rollback(LastKnownGood);
6629bool CodeGenPrepare::mergeSExts(
Function &
F) {
6631 for (
auto &Entry : ValToSExtendedUses) {
6632 SExts &Insts =
Entry.second;
6634 for (Instruction *Inst : Insts) {
6638 bool inserted =
false;
6639 for (
auto &Pt : CurPts) {
6642 RemovedInsts.insert(Pt);
6643 Pt->removeFromParent();
6654 RemovedInsts.insert(Inst);
6661 CurPts.push_back(Inst);
6703bool CodeGenPrepare::splitLargeGEPOffsets() {
6705 for (
auto &Entry : LargeOffsetGEPMap) {
6707 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6708 &LargeOffsetGEPs =
Entry.second;
6709 auto compareGEPOffset =
6710 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6711 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6712 if (
LHS.first ==
RHS.first)
6714 if (
LHS.second !=
RHS.second)
6715 return LHS.second <
RHS.second;
6716 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6719 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6722 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6724 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6725 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6726 Value *NewBaseGEP =
nullptr;
6728 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6729 GetElementPtrInst *
GEP) {
6730 LLVMContext &Ctx =
GEP->getContext();
6731 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6733 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6745 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), &getDT(), LI);
6748 NewBaseInsertPt = std::next(BaseI->getIterator());
6761 NewBaseGEP = OldBase;
6762 if (NewBaseGEP->
getType() != I8PtrTy)
6763 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6765 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6766 NewGEPBases.
insert(NewBaseGEP);
6772 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6773 BaseOffset = PreferBase;
6776 createNewBase(BaseOffset, OldBase, BaseGEP);
6779 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6780 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6781 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6782 int64_t
Offset = LargeOffsetGEP->second;
6783 if (
Offset != BaseOffset) {
6790 GEP->getResultElementType(),
6791 GEP->getAddressSpace())) {
6797 NewBaseGEP =
nullptr;
6802 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6807 createNewBase(BaseOffset, OldBase,
GEP);
6811 Value *NewGEP = NewBaseGEP;
6812 if (
Offset != BaseOffset) {
6815 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6819 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6820 GEP->eraseFromParent();
6827bool CodeGenPrepare::optimizePhiType(
6828 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
6829 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
6834 Type *PhiTy =
I->getType();
6835 Type *ConvertTy =
nullptr;
6837 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6840 SmallVector<Instruction *, 4> Worklist;
6842 SmallPtrSet<PHINode *, 4> PhiNodes;
6843 SmallPtrSet<ConstantData *, 4>
Constants;
6846 SmallPtrSet<Instruction *, 4> Defs;
6847 SmallPtrSet<Instruction *, 4>
Uses;
6853 bool AnyAnchored =
false;
6855 while (!Worklist.
empty()) {
6860 for (
Value *
V :
Phi->incoming_values()) {
6862 if (!PhiNodes.
count(OpPhi)) {
6863 if (!Visited.
insert(OpPhi).second)
6869 if (!OpLoad->isSimple())
6871 if (Defs.
insert(OpLoad).second)
6874 if (Defs.
insert(OpEx).second)
6878 ConvertTy = OpBC->getOperand(0)->getType();
6879 if (OpBC->getOperand(0)->getType() != ConvertTy)
6881 if (Defs.
insert(OpBC).second) {
6894 for (User *
V :
II->users()) {
6896 if (!PhiNodes.
count(OpPhi)) {
6897 if (Visited.
count(OpPhi))
6904 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
6906 Uses.insert(OpStore);
6909 ConvertTy = OpBC->getType();
6910 if (OpBC->getType() != ConvertTy)
6914 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
6921 if (!ConvertTy || !AnyAnchored || PhiTy == ConvertTy ||
6925 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
6926 << *ConvertTy <<
"\n");
6931 for (ConstantData *
C : Constants)
6933 for (Instruction *
D : Defs) {
6935 ValMap[
D] =
D->getOperand(0);
6939 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
6942 for (PHINode *Phi : PhiNodes)
6944 Phi->getName() +
".tc",
Phi->getIterator());
6946 for (PHINode *Phi : PhiNodes) {
6948 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
6950 Phi->getIncomingBlock(i));
6954 for (Instruction *U :
Uses) {
6959 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
6969bool CodeGenPrepare::optimizePhiTypes(
Function &
F) {
6970 if (!Opts.cgp_optimize_phi_types)
6974 SmallPtrSet<PHINode *, 4> Visited;
6975 SmallPtrSet<Instruction *, 4> DeletedInstrs;
6979 for (
auto &Phi : BB.
phis())
6980 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
6983 for (
auto *
I : DeletedInstrs) {
6985 I->eraseFromParent();
6993bool CodeGenPrepare::canFormExtLd(
6994 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
6995 Instruction *&Inst,
bool HasPromoted) {
6996 for (
auto *MovedExtInst : MovedExts) {
6999 Inst = MovedExtInst;
7051bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7052 bool AllowPromotionWithoutCommonHeader =
false;
7057 *Inst, AllowPromotionWithoutCommonHeader);
7058 TypePromotionTransaction TPT(RemovedInsts);
7059 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7060 TPT.getRestorationPoint();
7062 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7065 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7068 LoadInst *LI =
nullptr;
7073 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7074 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7079 Inst = ExtFedByLoad;
7084 if (ATPConsiderable &&
7085 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7086 HasPromoted, TPT, SpeculativelyMovedExts))
7089 TPT.rollback(LastKnownGood);
7098bool CodeGenPrepare::performAddressTypePromotion(
7099 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7100 bool HasPromoted, TypePromotionTransaction &TPT,
7101 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7102 bool Promoted =
false;
7103 SmallPtrSet<Instruction *, 1> UnhandledExts;
7104 bool AllSeenFirst =
true;
7105 for (
auto *
I : SpeculativelyMovedExts) {
7106 Value *HeadOfChain =
I->getOperand(0);
7107 auto AlreadySeen = SeenChainsForSExt.
find(HeadOfChain);
7110 if (AlreadySeen != SeenChainsForSExt.
end()) {
7111 if (AlreadySeen->second !=
nullptr)
7112 UnhandledExts.
insert(AlreadySeen->second);
7113 AllSeenFirst =
false;
7117 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7118 SpeculativelyMovedExts.size() == 1)) {
7122 for (
auto *
I : SpeculativelyMovedExts) {
7123 Value *HeadOfChain =
I->getOperand(0);
7124 SeenChainsForSExt[HeadOfChain] =
nullptr;
7125 ValToSExtendedUses[HeadOfChain].push_back(
I);
7128 Inst = SpeculativelyMovedExts.pop_back_val();
7133 for (
auto *
I : SpeculativelyMovedExts) {
7134 Value *HeadOfChain =
I->getOperand(0);
7135 SeenChainsForSExt[HeadOfChain] = Inst;
7140 if (!AllSeenFirst && !UnhandledExts.
empty())
7141 for (
auto *VisitedSExt : UnhandledExts) {
7142 if (RemovedInsts.count(VisitedSExt))
7144 TypePromotionTransaction TPT(RemovedInsts);
7146 SmallVector<Instruction *, 2> Chains;
7148 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7152 for (
auto *
I : Chains) {
7153 Value *HeadOfChain =
I->getOperand(0);
7155 SeenChainsForSExt[HeadOfChain] =
nullptr;
7156 ValToSExtendedUses[HeadOfChain].push_back(
I);
7162bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7167 Value *Src =
I->getOperand(0);
7168 if (Src->hasOneUse())
7180 bool DefIsLiveOut =
false;
7181 for (User *U :
I->users()) {
7186 if (UserBB == DefBB)
7188 DefIsLiveOut =
true;
7195 for (User *U : Src->users()) {
7198 if (UserBB == DefBB)
7207 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7209 bool MadeChange =
false;
7215 if (UserBB == DefBB)
7219 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7221 if (!InsertedTrunc) {
7224 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7226 InsertedInsts.insert(InsertedTrunc);
7239 I->dropPoisonGeneratingFlags();
7295bool CodeGenPrepare::optimizeLoadExt(LoadInst *
Load) {
7296 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7300 if (
Load->hasOneUse() &&
7306 SmallVector<Instruction *, 8> WorkList;
7307 SmallPtrSet<Instruction *, 16> Visited;
7308 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7309 SmallVector<Instruction *, 8> DropFlags;
7310 for (
auto *U :
Load->users())
7322 while (!WorkList.
empty()) {
7326 if (!Visited.
insert(
I).second)
7331 for (
auto *U :
Phi->users())
7336 switch (
I->getOpcode()) {
7337 case Instruction::And: {
7341 APInt AndBits = AndC->getValue();
7342 DemandBits |= AndBits;
7344 if (AndBits.
ugt(WidestAndBits))
7345 WidestAndBits = AndBits;
7346 if (AndBits == WidestAndBits &&
I->getOperand(0) ==
Load)
7351 case Instruction::Shl: {
7356 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7361 case Instruction::Trunc: {
7364 DemandBits.setLowBits(TruncBitWidth);
7374 uint32_t ActiveBits = DemandBits.getActiveBits();
7386 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7387 WidestAndBits != DemandBits)
7390 LLVMContext &Ctx =
Load->getType()->getContext();
7391 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7402 Builder.CreateAnd(
Load, ConstantInt::get(Ctx, DemandBits)));
7405 InsertedInsts.insert(NewAnd);
7410 NewAnd->setOperand(0,
Load);
7413 for (
auto *
And : AndsToMaybeRemove)
7418 if (&*CurInstIterator ==
And)
7419 CurInstIterator = std::next(
And->getIterator());
7420 And->eraseFromParent();
7425 for (
auto *Inst : DropFlags)
7439 TTI->isExpensiveToSpeculativelyExecute(
I);
7447 if (!
TLI->isPredictableSelectExpensive())
7457 uint64_t Max = std::max(TrueWeight, FalseWeight);
7458 uint64_t Sum = TrueWeight + FalseWeight;
7461 if (Probability >
TTI->getPredictableBranchThreshold())
7471 if (!Cmp || !Cmp->hasOneUse())
7494 assert(DefSI->getCondition() ==
SI->getCondition() &&
7495 "The condition of DefSI does not match with SI");
7496 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7499 assert(
V &&
"Failed to get select true/false value");
7503bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7527 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7528 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7529 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7530 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7536bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7538 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7539 "Expected a funnel shift");
7563 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7564 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7565 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7573bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7574 if (!Opts.cgp_select2branch)
7578 if (!Opts.disable_select_optimize)
7585 It !=
SI->getParent()->
end(); ++It) {
7587 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7594 SelectInst *LastSI = ASI.
back();
7597 CurInstIterator = std::next(LastSI->
getIterator());
7601 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7602 fixupDbgVariableRecordsOnInst(*SI);
7604 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7607 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7610 TargetLowering::SelectSupportKind SelectKind;
7611 if (
SI->getType()->isVectorTy())
7612 SelectKind = TargetLowering::ScalarCondVectorVal;
7614 SelectKind = TargetLowering::ScalarValSelect;
7651 SmallVector<Instruction *> TrueInstrs, FalseInstrs;
7652 for (SelectInst *SI : ASI) {
7664 SplitPt.setHeadBit(
true);
7667 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7672 UncondBrInst *TrueBranch =
nullptr;
7673 UncondBrInst *FalseBranch =
nullptr;
7674 if (TrueInstrs.
size() == 0) {
7679 }
else if (FalseInstrs.
size() == 0) {
7696 EndBlock->
setName(
"select.end");
7698 TrueBlock->
setName(
"select.true.sink");
7700 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7701 :
"select.false.sink");
7705 FreshBBs.
insert(TrueBlock);
7707 FreshBBs.
insert(FalseBlock);
7708 FreshBBs.
insert(EndBlock);
7713 static const unsigned MD[] = {
7714 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7715 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7720 for (Instruction *
I : TrueInstrs)
7722 for (Instruction *
I : FalseInstrs)
7729 if (TrueBlock ==
nullptr)
7730 TrueBlock = StartBlock;
7731 else if (FalseBlock ==
nullptr)
7732 FalseBlock = StartBlock;
7748 SI->eraseFromParent();
7750 ++NumSelectsExpanded;
7754 CurInstIterator = StartBlock->
end();
7761bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7773 "Expected a type of the same size!");
7779 Value *BC1 = Builder.CreateBitCast(
7781 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7782 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7786 SVI, TLInfo,
nullptr,
7787 [&](
Value *
V) { removeAllAssertingVHReferences(
V); });
7794 !
Op->isTerminator() && !
Op->isEHPad())
7800bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7815 for (Use *U :
reverse(OpsToSink)) {
7827 SetVector<Instruction *> MaybeDead;
7828 DenseMap<Instruction *, Instruction *> NewInstructions;
7829 for (Use *U : ToReplace) {
7838 FreshBBs.
insert(OpDef->getParent());
7841 NewInstructions[UI] = NI;
7846 InsertedInsts.insert(NI);
7852 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
7853 It->second->setOperand(
U->getOperandNo(), NI);
7860 for (
auto *
I : MaybeDead) {
7861 if (!
I->hasNUsesOrMore(1)) {
7863 I->eraseFromParent();
7870bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
7876 unsigned RegWidth =
RegType.getSizeInBits();
7887 auto *NewType = Type::getIntNTy(
Context, RegWidth);
7896 ExtType = Instruction::SExt;
7899 if (Arg->hasSExtAttr())
7900 ExtType = Instruction::SExt;
7901 if (Arg->hasZExtAttr())
7902 ExtType = Instruction::ZExt;
7908 SI->setCondition(ExtInst);
7909 for (
auto Case :
SI->cases()) {
7910 const APInt &NarrowConst = Case.getCaseValue()->getValue();
7911 APInt WideConst = (ExtType == Instruction::ZExt)
7912 ? NarrowConst.
zext(RegWidth)
7913 : NarrowConst.
sext(RegWidth);
7914 Case.setValue(ConstantInt::get(
Context, WideConst));
7920bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
7927 Value *Condition =
SI->getCondition();
7936 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
7937 ConstantInt *CaseValue = Case.getCaseValue();
7938 BasicBlock *CaseBB = Case.getCaseSuccessor();
7941 bool CheckedForSinglePred =
false;
7942 for (PHINode &
PHI : CaseBB->
phis()) {
7943 Type *PHIType =
PHI.getType();
7951 if (PHIType == ConditionType || TryZExt) {
7953 bool SkipCase =
false;
7954 Value *Replacement =
nullptr;
7955 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
7956 Value *PHIValue =
PHI.getIncomingValue(
I);
7957 if (PHIValue != CaseValue) {
7966 if (
PHI.getIncomingBlock(
I) != SwitchBB)
7971 if (!CheckedForSinglePred) {
7972 CheckedForSinglePred =
true;
7973 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
7979 if (Replacement ==
nullptr) {
7980 if (PHIValue == CaseValue) {
7981 Replacement = Condition;
7984 Replacement = Builder.CreateZExt(Condition, PHIType);
7987 PHI.setIncomingValue(
I, Replacement);
7998bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
7999 bool Changed = optimizeSwitchType(SI);
8000 Changed |= optimizeSwitchPhiConstants(SI);
8021class VectorPromoteHelper {
8023 const DataLayout &
DL;
8026 const TargetLowering &
TLI;
8029 const TargetTransformInfo &
TTI;
8035 SmallVector<Instruction *, 4> InstsToBePromoted;
8038 unsigned StoreExtractCombineCost;
8040 bool StressStoreExtract;
8049 if (InstsToBePromoted.
empty())
8051 return InstsToBePromoted.
back();
8057 unsigned getTransitionOriginalValueIdx()
const {
8059 "Other kind of transitions are not supported yet");
8066 unsigned getTransitionIdx()
const {
8068 "Other kind of transitions are not supported yet");
8076 Type *getTransitionType()
const {
8087 void promoteImpl(Instruction *ToBePromoted);
8091 bool isProfitableToPromote() {
8092 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8096 Type *PromotedType = getTransitionType();
8099 unsigned AS =
ST->getPointerAddressSpace();
8117 for (
const auto &Inst : InstsToBePromoted) {
8125 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8134 CostKind, Arg0Info, Arg1Info);
8137 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8138 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8139 return ScalarCost > VectorCost;
8151 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8166 if (!
EC.isScalable()) {
8167 SmallVector<Constant *, 4> ConstVec;
8169 for (
unsigned Idx = 0;
Idx !=
EC.getKnownMinValue(); ++
Idx) {
8170 if (Idx == ExtractIdx)
8178 "Generate scalable vector for non-splat is unimplemented");
8183 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8184 unsigned OperandIdx) {
8187 if (OperandIdx != 1)
8189 switch (
Use->getOpcode()) {
8192 case Instruction::SDiv:
8193 case Instruction::UDiv:
8194 case Instruction::SRem:
8195 case Instruction::URem:
8197 case Instruction::FDiv:
8198 case Instruction::FRem:
8199 return !
Use->hasNoNaNs();
8205 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &
TLI,
8206 const TargetTransformInfo &
TTI, Instruction *Transition,
8207 unsigned CombineCost,
bool StressStoreExtract)
8209 StoreExtractCombineCost(CombineCost),
8210 StressStoreExtract(StressStoreExtract) {
8211 assert(Transition &&
"Do not know how to promote null");
8215 bool canPromote(
const Instruction *ToBePromoted)
const {
8222 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8227 for (
const Use &U : ToBePromoted->
operands()) {
8228 const Value *Val =
U.get();
8229 if (Val == getEndOfTransition()) {
8240 return StressStoreExtract ||
8251 void enqueueForPromotion(Instruction *ToBePromoted) {
8252 InstsToBePromoted.push_back(ToBePromoted);
8256 void recordCombineInstruction(Instruction *ToBeCombined) {
8258 CombineInst = ToBeCombined;
8268 if (InstsToBePromoted.empty() || !CombineInst)
8272 if (!StressStoreExtract && !isProfitableToPromote())
8276 for (
auto &ToBePromoted : InstsToBePromoted)
8277 promoteImpl(ToBePromoted);
8278 InstsToBePromoted.clear();
8285void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8295 "The type of the result of the transition does not match "
8300 Type *TransitionTy = getTransitionType();
8305 for (Use &U : ToBePromoted->
operands()) {
8307 Value *NewVal =
nullptr;
8308 if (Val == Transition)
8309 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8316 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8320 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8323 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8329bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8330 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8331 if (!Opts.cgp_store_extract ||
8332 (!Opts.cgp_stress_store_extract &&
8345 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8346 VectorPromoteHelper VPH(*
DL, *
TLI, *
TTI, Inst, CombineCost,
8347 Opts.cgp_stress_store_extract);
8354 if (ToBePromoted->
getParent() != Parent) {
8355 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8357 <<
") than the transition (" << Parent->
getName()
8362 if (VPH.canCombine(ToBePromoted)) {
8364 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8365 VPH.recordCombineInstruction(ToBePromoted);
8367 NumStoreExtractExposed +=
Changed;
8372 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8375 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8377 VPH.enqueueForPromotion(ToBePromoted);
8378 Inst = ToBePromoted;
8417 bool ForceSplitStore) {
8419 Type *StoreType =
SI.getValueOperand()->getType();
8428 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8429 DL.getTypeSizeInBits(StoreType) == 0)
8432 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8434 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8450 if (!
match(
SI.getValueOperand(),
8457 if (!
LValue->getType()->isIntegerTy() ||
8458 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8460 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8471 if (!ForceSplitStore && !
TLI.isMultiStoresCheaperThanBitsMerge(LowTy, HighTy))
8476 Builder.disableGEPCanonicalization();
8480 if (LBC && LBC->getParent() !=
SI.getParent())
8481 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8482 if (HBC && HBC->getParent() !=
SI.getParent())
8483 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8485 bool IsLE =
SI.getDataLayout().isLittleEndian();
8486 auto CreateSplitStore = [&](
Value *
V,
bool Upper) {
8487 V = Builder.CreateZExtOrBitCast(
V, SplitStoreType);
8488 Value *Addr =
SI.getPointerOperand();
8489 Align Alignment =
SI.getAlign();
8490 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8491 if (IsOffsetStore) {
8492 Addr = Builder.CreateGEP(
8493 SplitStoreType, Addr,
8501 Builder.CreateAlignedStore(
V, Addr, Alignment);
8504 CreateSplitStore(
LValue,
false);
8505 CreateSplitStore(HValue,
true);
8508 SI.eraseFromParent();
8593 if (auto *I = dyn_cast<Instruction>(Usr)) {
8594 if (I->getParent() != SrcBlock) {
8602 std::vector<GetElementPtrInst *> UGEPIs;
8605 for (User *Usr : GEPIOp->
users()) {
8617 ConstantInt *UGEPIIdx;
8620 if (GEPIIdx->getType() != UGEPIIdx->
getType())
8628 if (UGEPIs.size() == 0)
8631 for (GetElementPtrInst *UGEPI : UGEPIs) {
8633 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8640 for (GetElementPtrInst *UGEPI : UGEPIs) {
8641 UGEPI->setOperand(0, GEPI);
8643 auto NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8644 Constant *NewUGEPIIdx = ConstantInt::get(GEPIIdx->getType(), NewIdx);
8645 UGEPI->setOperand(1, NewUGEPIIdx);
8647 auto SourceFlags = GEPI->getNoWrapFlags();
8650 UGEPI->getNoWrapFlags().intersectForOffsetAdd(SourceFlags);
8652 if (NewIdx.
isNegative() && TargetFlags.hasNoUnsignedWrap())
8653 TargetFlags = TargetFlags.withoutNoUnsignedWrap();
8654 UGEPI->setNoWrapFlags(TargetFlags);
8660 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8662 "GEPIOp is used outside SrcBlock");
8679 if (!
TLI.preferZeroCompareBranch())
8686 Value *
X = Cmp->getOperand(0);
8687 if (!
X->hasUseList())
8692 for (
auto *U :
X->users()) {
8696 (UI->
getParent() != Branch->getParent() &&
8697 UI->
getParent() != Branch->getSuccessor(0) &&
8698 UI->
getParent() != Branch->getSuccessor(1)) ||
8699 (UI->
getParent() != Branch->getParent() &&
8700 !UI->
getParent()->getSinglePredecessor()))
8706 if (UI->
getParent() != Branch->getParent())
8710 ConstantInt::get(UI->
getType(), 0));
8712 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8716 if (Cmp->isEquality() &&
8721 if (UI->
getParent() != Branch->getParent())
8724 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8725 ConstantInt::get(UI->
getType(), 0));
8727 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8767 if (!L || !L->isInnermost())
8771 BasicBlock *PreHeader = L->getLoopPreheader();
8773 if (!PreHeader || !Latch || Phi->getParent() != Header ||
8774 Phi->getNumIncomingValues() != 2)
8778 Value *Start = Phi->getIncomingValueForBlock(PreHeader);
8779 Value *Step = Phi->getIncomingValueForBlock(Latch);
8786 Type *ITy = VTy->getElementType();
8787 if (
DL.getTypeStoreSize(ITy) !=
DL.getPointerSize())
8794 Value *LoopStride =
nullptr;
8800 const APInt *ShiftAmt =
nullptr;
8801 Value *PtrStride =
nullptr;
8805 (1ULL << ShiftAmt->
getZExtValue()) != EltCnt.getKnownMinValue())
8817 for (
User *U : Phi->users()) {
8829 if (!
GEP ||
GEP->getNumOperands() != 2)
8834 if (!L->isLoopInvariant(
Base))
8843 unsigned Size =
DL.getTypeStoreSize(
GEP->getResultElementType());
8848 Value *StructSize = ConstantInt::get(ITy,
Size);
8850 Builder.CreateVectorSplat(VTy->getElementCount(), StructSize);
8851 Value *NewStart = Builder.CreateMul(Start, SizeSplat);
8852 NewStart = Builder.CreateGEP(Int8Ty,
Base, NewStart);
8856 Value *StructStride = Builder.CreateMul(PtrStride, StructSize);
8858 Builder.CreateVectorSplat(VTy->getElementCount(), StructStride);
8860 Builder.SetInsertPoint(Phi);
8861 PHINode *NewPhi = Builder.CreatePHI(
GEP->getType(), 2,
"vec.lsr.phi");
8863 StructStride = Builder.CreateGEP(Int8Ty, NewPhi, StructStride);
8870 Builder.SetInsertPoint(
GEP);
8871 GEP->replaceAllUsesWith(NewPhi);
8880bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8881 bool AnyChange =
false;
8882 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8886 if (InsertedInsts.count(
I))
8895 LargeOffsetGEPMap.erase(
P);
8897 P->eraseFromParent();
8905 if (
P->getType()->isScalableTy())
8934 I, LI->getLoopFor(
I->getParent()), *
TTI))
8942 TargetLowering::TypeExpandInteger) {
8946 I, LI->getLoopFor(
I->getParent()), *
TTI))
8949 bool MadeChange = optimizeExt(
I);
8950 return MadeChange | optimizeExtUses(
I);
8957 if (optimizeCmp(Cmp, ModifiedDT))
8961 if (optimizeURem(
I))
8965 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8966 bool Modified = optimizeLoadExt(LI);
8975 bool Modified = tryToSinkFreeOperands(
I);
8976 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8977 unsigned AS =
SI->getPointerAddressSpace();
8978 Modified |= optimizeMemoryInst(
I,
SI->getOperand(1),
8979 SI->getOperand(0)->getType(), AS);
8984 unsigned AS = RMW->getPointerAddressSpace();
8985 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
8989 unsigned AS = CmpX->getPointerAddressSpace();
8990 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
8991 CmpX->getCompareOperand()->getType(), AS);
8996 if (BinOp && BinOp->
getOpcode() == Instruction::And &&
8997 Opts.cgp_andcmp_sinking &&
9002 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
9003 BinOp->
getOpcode() == Instruction::LShr)) {
9011 if (GEPI->hasAllZeroIndices()) {
9013 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
9014 GEPI->getName(), GEPI->getIterator());
9015 NC->setDebugLoc(GEPI->getDebugLoc());
9018 GEPI, TLInfo,
nullptr,
9019 [&](
Value *
V) { removeAllAssertingVHReferences(
V); });
9021 optimizeInst(
NC, ModifiedDT);
9039 if (Const0 || Const1) {
9040 if (!Const0 || !Const1) {
9041 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
9047 FI->eraseFromParent();
9055 if (
I->getType()->isVectorTy() &&
9059 if (tryToSinkFreeOperands(
I))
9062 switch (
I->getOpcode()) {
9063 case Instruction::Shl:
9064 case Instruction::LShr:
9065 case Instruction::AShr:
9067 case Instruction::Call:
9069 case Instruction::Select:
9071 case Instruction::ShuffleVector:
9073 case Instruction::Switch:
9075 case Instruction::ExtractElement:
9077 case Instruction::CondBr:
9086bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
9087 if (!
I.getType()->isIntegerTy() ||
9092 SmallVector<Instruction *, 4> Insts;
9098 &
I, TLInfo,
nullptr,
9099 [&](
Value *
V) { removeAllAssertingVHReferences(
V); });
9106bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
9108 bool MadeChange =
false;
9111 CurInstIterator = BB.
begin();
9112 ModifiedDT = ModifyDT::NotModifyDT;
9113 while (CurInstIterator != BB.
end()) {
9114 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
9115 if (ModifiedDT != ModifyDT::NotModifyDT) {
9124 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
9126 bool MadeBitReverse =
true;
9127 while (MadeBitReverse) {
9128 MadeBitReverse =
false;
9130 if (makeBitReverse(
I)) {
9131 MadeBitReverse = MadeChange =
true;
9136 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
9141bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
9142 bool AnyChange =
false;
9143 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
9144 AnyChange |= fixupDbgVariableRecord(DVR);
9150bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
9151 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
9152 DVR.
Type != DbgVariableRecord::LocationType::Assign)
9156 bool AnyChange =
false;
9157 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
9159 for (
Value *Location : LocationOps) {
9160 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9189bool CodeGenPrepare::placeDbgValues(
Function &
F) {
9190 bool MadeChange =
false;
9191 DominatorTree &DT = getDT();
9193 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9194 SmallVector<Instruction *, 4> VIs;
9195 for (
Value *
V : DbgItem->location_ops())
9203 for (Instruction *VI : VIs) {
9204 if (
VI->isTerminator())
9209 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9220 if (VIs.size() > 1) {
9223 <<
"Unable to find valid location for Debug Value, undefing:\n"
9225 DbgItem->setKillLocation();
9230 << *DbgItem <<
' ' << *VI);
9237 for (BasicBlock &BB :
F) {
9243 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9245 DbgProcessor(&DVR, &Insn);
9256bool CodeGenPrepare::placePseudoProbes(
Function &
F) {
9257 bool MadeChange =
false;
9260 auto FirstInst =
Block.getFirstInsertionPt();
9265 while (
I !=
Block.end()) {
9267 II->moveBefore(FirstInst);
9297bool CodeGenPrepare::splitBranchCondition(
Function &
F) {
9301 bool MadeChange =
false;
9302 for (
auto &BB :
F) {
9315 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9323 Value *Cond1, *Cond2;
9326 Opc = Instruction::And;
9329 Opc = Instruction::Or;
9339 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9353 Br1->setCondition(Cond1);
9358 if (
Opc == Instruction::And)
9359 Br1->setSuccessor(0, TmpBB);
9361 Br1->setSuccessor(1, TmpBB);
9366 I->removeFromParent();
9367 I->insertBefore(Br2->getIterator());
9379 if (
Opc == Instruction::Or)
9383 TBB->replacePhiUsesWith(&BB, TmpBB);
9386 for (PHINode &PN : FBB->
phis()) {
9391 if (
Loop *L = LI->getLoopFor(&BB))
9392 L->addBasicBlockToLoop(TmpBB, *LI);
9396 DTU->
applyUpdates({{DominatorTree::Insert, &BB, TmpBB},
9397 {DominatorTree::Insert, TmpBB,
TBB},
9398 {DominatorTree::Insert, TmpBB, FBB},
9399 {DominatorTree::Delete, &BB,
TBB}});
9403 if (
Opc == Instruction::Or) {
9425 uint64_t NewTrueWeight = TrueWeight;
9426 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9430 NewTrueWeight = TrueWeight;
9431 NewFalseWeight = 2 * FalseWeight;
9456 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9457 uint64_t NewFalseWeight = FalseWeight;
9461 NewTrueWeight = 2 * TrueWeight;
9462 NewFalseWeight = FalseWeight;
static unsigned getIntrinsicID(const SDNode *N)
const TargetLowering & TLI
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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 bool optimizeBitCast(BitCastInst *BCI, const TargetLowering &TLI, const DataLayout &DL)
Hoists bitcasts to the source block to reduce register pressure.
static bool foldFCmpToFPClassTest(CmpInst *Cmp, const TargetLowering &TLI, const DataLayout &DL)
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 bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI, const DataLayout &DL)
If the specified cast instruction is a noop copy (e.g.
static bool SinkCast(CastInst *CI)
Sink the specified cast instruction into its user blocks.
static bool splitMergedValStore(StoreInst &SI, const DataLayout &DL, const TargetLowering &TLI, bool ForceSplitStore)
For the instruction sequence of store below, F and I values are bundled together as an i64 value befo...
static bool swapICmpOperandsToExposeCSEOpportunities(CmpInst *Cmp)
Many architectures use the same instruction for both subtract and cmp.
static bool isFormingBranchFromSelectProfitable(const TargetTransformInfo *TTI, const TargetLowering *TLI, SelectInst *SI)
Returns true if a SelectInst should be turned into an explicit branch.
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, unsigned MaxUsersToScan)
Recursively walk all the uses of I until we find a memory use.
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 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 bool foldICmpWithDominatingICmp(CmpInst *Cmp, const TargetLowering &TLI, bool EnableICmpEqToICmpSt)
For pattern like:
static bool strengthReduceVectorPhiUsers(PHINode *Phi, LoopInfo *LI)
static bool foldURemOfLoopIncrement(Instruction *Rem, const DataLayout *DL, const LoopInfo *LI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
static bool optimizeBranch(CondBrInst *Branch, const TargetLowering &TLI, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
static bool tryUnmergingGEPsAcrossIndirectBr(GetElementPtrInst *GEPI, const TargetTransformInfo *TTI)
static bool IsOperandAMemoryOperand(CallInst *CI, InlineAsm *IA, Value *OpVal, const TargetLowering &TLI, const TargetRegisterInfo &TRI)
Check to see if all uses of OpVal by the specified inline asm call are due to memory operands.
static bool isIntrinsicOrLFToBeTailCalled(const TargetLibraryInfo *TLInfo, const CallInst *CI)
static void replaceAllUsesWith(Value *Old, Value *New, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHuge)
Replace all old uses with new ones, and push the updated BBs into FreshBBs.
static bool matchOverflowPattern(Instruction *&I, ExtractValueInst *&MulExtract, ExtractValueInst *&OverflowExtract)
static void computeBaseDerivedRelocateMap(const SmallVectorImpl< GCRelocateInst * > &AllRelocateCalls, MapVector< GCRelocateInst *, SmallVector< GCRelocateInst *, 0 > > &RelocateInstMap)
static bool simplifyRelocatesOffABase(GCRelocateInst *RelocatedBase, const SmallVectorImpl< GCRelocateInst * > &Targets)
static 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 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 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 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 bool despeculateCountZeros(IntrinsicInst *CountZeros, DomTreeUpdater *DTU, LoopInfo *LI, const TargetLowering *TLI, const DataLayout *DL, ModifyDT &ModifiedDT, SmallPtrSet< BasicBlock *, 32 > &FreshBBs, bool IsHugeFunc)
If counting leading or trailing zeros is an expensive operation and a zero input is defined,...
static bool sinkCmpExpression(CmpInst *Cmp, const TargetLowering &TLI, const DataLayout &DL)
Sink the given CmpInst into user blocks to reduce the number of virtual registers that must be create...
static bool hasSameExtUse(Value *Val, const TargetLowering &TLI)
Check if all the uses of Val are equivalent (or free) zero or sign extensions.
static bool matchUAddWithOverflowConstantEdgeCases(CmpInst *Cmp, BinaryOperator *&Add)
Match special-case patterns that check for unsigned add overflow.
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...
This file declares the LLVM IR specialization of the GenericCycle templates.
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
static Value * getCondition(Instruction *I)
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static void eraseInstruction(Instruction &I, const LICMDependencies &Deps)
Register const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
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.
SmallVector< MachineOperand, 4 > Cond
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
static DominatorTree getDomTree(Function &F)
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, const MachineInstr &B)
Remove Loads Into Fake Uses
static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, unsigned CombineOpc=0)
This file describes how to lower LLVM code to machine code.
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.
uint64_t getZExtValue() const
Get zero extended value.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isNegative() const
Determine sign of this APInt.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
unsigned getSignificantBits() const
Get the minimum bit size for this signed APInt.
unsigned logBase2() const
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
int64_t getSExtValue() const
Get sign extended value.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
void setAlignment(Align Align)
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addRequired()
Represent a constant reference to an array (0 or more elements consecutively in memory),...
An instruction that atomically checks whether a specified value is in a memory location,...
static unsigned getPointerOperandIndex()
an instruction that atomically reads a memory location, combines it with another value,...
static unsigned getPointerOperandIndex()
Analysis pass providing the BasicBlockSectionsProfileReader.
LLVM_ABI bool isFunctionHot(StringRef FuncName) const
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI void insertDbgRecordBefore(DbgRecord *DR, InstListType::iterator Here)
Insert a DbgRecord into a block at the position given by Here.
InstListType::const_iterator const_iterator
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
LLVM_ABI 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 InstListType::const_iterator getFirstNonPHIOrPseudoProbe() const
Returns an iterator to the first instruction in this block that is not a PHINode or a pseudo operatio...
LLVM_ABI void insertDbgRecordAfter(DbgRecord *DR, Instruction *I)
Insert a DbgRecord into a block at the position given by I.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
This class represents a no-op cast from one type to another.
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI void setBlockFreq(const BasicBlock *BB, BlockFrequency Freq)
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
Analysis pass which computes BranchProbabilityInfo.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
Predicate getPredicate() const
Return the predicate for this instruction.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Conditional Branch instruction.
static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI void removeFromParent()
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LocationType Type
Classification of the debug-info record that this DbgVariableRecord represents.
LLVM_ABI void replaceVariableLocationOp(Value *OldValue, Value *NewValue, bool AllowEmpty=false)
LLVM_ABI iterator_range< location_op_iterator > location_ops() const
Get the locations corresponding to the variable referenced by the debug info intrinsic.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
LLVM_ABI void deleteBB(BasicBlock *DelBB)
Delete DelBB.
Analysis pass which computes a DominatorTree.
static constexpr UpdateKind Insert
Legacy analysis pass which computes a DominatorTree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This instruction compares its operands according to the predicate given to the constructor.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionPass class - This class is used to implement most global optimizations.
const BasicBlock & getEntryBlock() const
LLVM_ABI const Value * getStatepoint() const
The statepoint with which this gc.relocate is associated.
Represents calls to the gc.relocate intrinsic.
unsigned getBasePtrIndex() const
The index into the associate statepoint's argument list which contains the base pointer of the pointe...
void compute(FunctionT &F)
Compute the cycle info for a function.
DomTreeT & getDomTree()
Flush DomTree updates and return DomTree.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
void flush()
Apply all pending updates to available trees and flush all BasicBlocks awaiting deletion.
bool isBBPendingDeletion(BasicBlockT *DelBB) const
Returns true if DelBB is awaiting deletion.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static LLVM_ABI Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)
Returns the result type of a getelementptr with the given source element type and indexes.
LLVM_ABI bool canIncreaseAlignment() const
Returns true if the alignment of the value can be unilaterally increased.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This instruction compares its operands according to the predicate given to the constructor.
bool isEquality() const
Return true if this predicate is either EQ or NE.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
LLVM_ABI 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.
user_iterator_impl< Instruction > user_iterator
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
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.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
iterator_range< user_iterator > users()
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
user_iterator user_begin()
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.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
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.
static MVT getIntegerVT(unsigned BitWidth)
This class implements a map that also provides access to all stored values in a deterministic order.
iterator find(const KeyT &Key)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
op_range incoming_values()
Value * getIncomingValueForBlock(const BasicBlock *BB) const
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
PointerIntPair - This class implements a pair of a pointer and small integer.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
void clear()
Completely clear the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
VectorType * getType() const
Overload to return most specific vector type.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator erase(const_iterator CI)
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.
LibFunc getLibFunc(StringRef funcName) 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 shouldFormOverflowOp(unsigned Opcode, EVT VT, bool MathUsed) const
Try to convert math with an overflow comparison into the corresponding DAG node operation.
virtual bool shouldOptimizeMulOverflowWithZeroHighBits(LLVMContext &Context, EVT VT) const
bool isExtLoad(const LoadInst *Load, const Instruction *Ext, const DataLayout &DL) const
Return true if Load and Ext can form an ExtLoad.
virtual bool isSExtCheaperThanZExt(EVT FromTy, EVT ToTy) const
Return true if sign-extension from FromTy to ToTy is cheaper than zero-extension.
const TargetMachine & getTargetMachine() const
virtual bool isCtpopFast(EVT VT) const
Return true if ctpop instruction is fast.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
bool enableExtLdPromotion() const
Return true if the target wants to use the optimization that turns ext(promotableInst1(....
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 MVT getPreferredSwitchConditionType(LLVMContext &Context, EVT ConditionVT) const
Returns preferred type for switch condition.
virtual bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx, unsigned &Cost) const
Return true if the target can combine store(extractelement VectorTy,Idx).
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...
virtual bool getAddrModeArguments(const IntrinsicInst *, SmallVectorImpl< Value * > &, Type *&) const
CodeGenPrepare sinks address calculations into the same BB as Load/Store instructions reading the add...
const DenseMap< unsigned int, unsigned int > & getBypassSlowDivWidths() const
Returns map of slow types for division or remainder with corresponding fast types.
virtual 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 optimizeVectorCrossLaneOperation(Instruction *I, Loop *L) const
virtual bool shouldAlignPointerArgs(CallInst *, unsigned &, Align &) const
Return true if the pointer arguments to CI should be aligned by aligning the object whose address is ...
virtual Type * shouldConvertSplatType(ShuffleVectorInst *SVI) const
Given a shuffle vector SVI representing a vector splat, return a new scalar type of size equal to SVI...
bool isLoadLegal(EVT ValVT, EVT MemVT, Align Alignment, unsigned AddrSpace, unsigned ExtType, bool Atomic) const
Return true if the specified load with extension is legal on this target.
virtual bool addressingModeSupportsTLS(const GlobalValue &) const
Returns true if the targets addressing mode can target thread local storage (TLS).
virtual bool shouldConvertPhiType(Type *From, Type *To) const
Given a set in interconnected phis of type 'From' that are loaded/stored or bitcast to type 'To',...
virtual bool 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(const DataLayout &DL, unsigned SrcAS, unsigned DestAS) const
Returns true if a cast between SrcAS and DestAS is a noop.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
unsigned EnableFastISel
EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...
Target-Independent Code Generator Pass Configuration Options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
virtual bool addrSinkUsingGEPs() const
Sink addresses into blocks using GEP instructions rather than pointer casts and arithmetic.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
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)
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
BasicBlock * getSuccessor(unsigned i=0) const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
LLVM_ABI bool isUsedInBasicBlock(const BasicBlock *BB) const
Check if this value is used in the specified basic block.
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
iterator_range< use_iterator > uses()
void mutateType(Type *Ty)
Mutate the type of this Value to be of the specified type.
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
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.
unsigned getAddrMode(MCInstrInfo const &MCII, MCInst const &MCI)
@ BasicBlock
Various leaf nodes.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
AllOnesConstantMatch m_AllOnes()
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
match_bind< PHINode > m_Phi(PHINode *&PN)
Match a PHI node, capturing it if we match.
auto m_Cmp()
Matches any compare instruction and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap, true > m_c_NUWAdd(const LHS &L, const RHS &R)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_Ctpop(const Opnd0 &Op0)
auto m_Constant()
Match an arbitrary Constant and ignore it.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
auto m_VScale()
Matches a call to llvm.vscale().
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
Splat_match< T > m_Splat(const T &SubPattern)
Match a vector splat.
PtrAdd_match< PointerOpTy, OffsetOpTy > m_PtrAdd(const DataLayout &DL, const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp)
Matches GEP with i8 source element type and canonical index type.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
UAddWithOverflow_match< LHS_t, RHS_t, Sum_t > m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S)
Match an icmp instruction checking for unsigned overflow on addition.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
auto m_Undef()
Match an arbitrary undef constant.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale)
Compare two scaled numbers.
@ CE
Windows NT (Windows on ARM)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ User
could "use" a pointer
NodeAddr< PhiNode * > Phi
NodeAddr< UseNode * > Use
SmallVector< Node, 4 > NodeList
friend class Instruction
Iterator for Instructions in a `BasicBlock.
LLVM_ABI iterator begin() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
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 bool bypassSlowDivision(BasicBlock *BB, const DenseMap< unsigned int, unsigned int > &BypassWidth, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BranchProbabilityInfo *BPI=nullptr)
This optimization identifies DIV instructions in a BB that can be profitably bypassed and carried out...
LLVM_ABI void findDbgValues(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)
Finds the dbg.values describing a value.
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
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)
@ Load
The value being inserted comes from a load (InsertElement only).
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI ReturnInst * FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, BasicBlock *Pred, DomTreeUpdater *DTU=nullptr)
This method duplicates the specified return instruction into a predecessor which ends in an unconditi...
bool operator!=(uint64_t V1, const APInt &V2)
constexpr from_range_t from_range
LLVM_ABI BasicBlock * splitBlockBefore(BasicBlock *Old, BasicBlock::iterator SplitPt, DomTreeUpdater *DTU, LoopInfo *LI, MemorySSAUpdater *MSSAU, const Twine &BBName="")
Split the specified block at the specified instruction SplitPt.
LLVM_ABI Instruction * SplitBlockAndInsertIfElse(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ElseBlock=nullptr)
Similar to SplitBlockAndInsertIfThen, but the inserted block is on the false path of the branch.
LLVM_ABI bool SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr, DomTreeUpdater *DTU=nullptr)
LLVM_ABI bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, SmallPtrSetImpl< PHINode * > *KnownNonDeadPHIs=nullptr)
Examine each PHI in the given block and delete it if it is dead.
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...
constexpr std::enable_if_t< std::is_signed_v< T >, std::pair< T, bool > > AddOverflow(T X, T Y)
Add two signed integers, computing the two's complement truncated result, returning a pair {result,...
LLVM_ABI void DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, bool KeepOneInputPHIs=false)
Delete the specified block, which must have no predecessors.
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
auto unique(Range &&R, Predicate P)
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
LLVM_ABI bool hasBranchWeightOrigin(const Instruction &I)
Check if Branch Weight Metadata has an "expected" field from an llvm.expect* intrinsic.
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
auto dyn_cast_or_null(const Y &Val)
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 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.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
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.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
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...
LLVM_ABI 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.
LLVM_ABI 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...
LLVM_ABI bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false, DominatorTree *DT=nullptr)
Attempts to merge a block into its predecessor, if possible.
@ Or
Bitwise or logical OR of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I, bool IgnoreUBImplyingAttrs=true)
Don't use information from its non-constant operands.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI bool VerifyDomInfo
Enables verification of dominator trees.
constexpr unsigned BitWidth
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
constexpr bool valueOr(BoolOrDefault X, bool Default)
constexpr std::enable_if_t< std::is_signed_v< T >, std::pair< T, bool > > MulOverflow(T X, T Y)
Multiply two signed integers, computing the two's complement truncated result, returning a pair {resu...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
bool pred_empty(const BasicBlock *BB)
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...
LLVM_ABI void setFittedBranchWeights(Instruction &I, ArrayRef< uint64_t > Weights, bool IsExpected, bool ElideAllZero=false)
Variant of setBranchWeights where the Weights will be fit first to uint32_t by shifting right.
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 void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
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 isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
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.