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 = CodeGenOptions::Global;
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() =
default;
233 CodeGenPrepare(
const TargetMachine *TM) : TM(TM){};
235 bool IsHugeFunc =
false;
241 SmallPtrSet<BasicBlock *, 32> FreshBBs;
243 void releaseMemory() {
245 InsertedInsts.clear();
246 PromotedInsts.clear();
253 template <
typename F>
254 void resetIteratorIfInvalidatedWhileCalling(BasicBlock *BB,
F f) {
258 Value *CurValue = &*CurInstIterator;
259 WeakTrackingVH IterHandle(CurValue);
265 if (IterHandle != CurValue) {
266 CurInstIterator = BB->
begin();
272 DominatorTree &getDT() {
return DTU->getDomTree(); }
274 void removeAllAssertingVHReferences(
Value *V);
277 bool eliminateMostlyEmptyBlocks(
Function &
F,
bool &ResetLI);
278 BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB);
279 bool canMergeBlocks(
const BasicBlock *BB,
const BasicBlock *DestBB)
const;
280 bool eliminateMostlyEmptyBlock(BasicBlock *BB);
281 bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB,
283 bool makeBitReverse(Instruction &
I);
285 bool optimizeInst(Instruction *
I, ModifyDT &ModifiedDT);
286 bool optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
Type *AccessTy,
288 bool optimizeGatherScatterInst(Instruction *MemoryInst,
Value *Ptr);
289 bool optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
290 ModifyDT &ModifiedDT);
291 bool optimizeInlineAsmInst(CallInst *CS);
293 bool optimizeExt(Instruction *&
I);
294 bool optimizeExtUses(Instruction *
I);
295 bool optimizeLoadExt(LoadInst *
Load);
296 bool optimizeShiftInst(BinaryOperator *BO);
297 bool optimizeFunnelShift(IntrinsicInst *Fsh);
298 bool optimizeSelectInst(SelectInst *SI);
299 bool optimizeShuffleVectorInst(ShuffleVectorInst *SVI);
300 bool optimizeSwitchType(SwitchInst *SI);
301 bool optimizeSwitchPhiConstants(SwitchInst *SI);
302 bool optimizeSwitchInst(SwitchInst *SI);
303 bool optimizeExtractElementInst(Instruction *Inst);
304 bool dupRetToEnableTailCallOpts(BasicBlock *BB, ModifyDT &ModifiedDT);
305 bool fixupDbgVariableRecord(DbgVariableRecord &
I);
306 bool fixupDbgVariableRecordsOnInst(Instruction &
I);
309 bool canFormExtLd(
const SmallVectorImpl<Instruction *> &MovedExts,
310 LoadInst *&LI, Instruction *&Inst,
bool HasPromoted);
311 bool tryToPromoteExts(TypePromotionTransaction &TPT,
312 const SmallVectorImpl<Instruction *> &Exts,
313 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
314 unsigned CreatedInstsCost = 0);
316 bool splitLargeGEPOffsets();
317 bool optimizePhiType(PHINode *Inst, SmallPtrSetImpl<PHINode *> &Visited,
318 SmallPtrSetImpl<Instruction *> &DeletedInstrs);
320 bool performAddressTypePromotion(
321 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
322 bool HasPromoted, TypePromotionTransaction &TPT,
323 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts);
325 bool simplifyOffsetableRelocate(GCStatepointInst &
I);
327 bool tryToSinkFreeOperands(Instruction *
I);
328 bool replaceMathCmpWithIntrinsic(BinaryOperator *BO,
Value *Arg0,
Value *Arg1,
330 bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT);
331 bool optimizeURem(Instruction *Rem);
332 bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
333 bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
334 bool unfoldPowerOf2Test(CmpInst *Cmp);
343 CodeGenPrepareLegacyPass() : FunctionPass(ID) {}
347 StringRef getPassName()
const override {
return "CodeGen Prepare"; }
349 void getAnalysisUsage(AnalysisUsage &AU)
const override {
357 AU.
addRequired<BranchProbabilityInfoWrapperPass>();
365char CodeGenPrepareLegacyPass::ID = 0;
367bool CodeGenPrepareLegacyPass::runOnFunction(
Function &
F) {
370 auto TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
371 CodeGenPrepare CGP(TM);
372 CGP.DL = &
F.getDataLayout();
375 CGP.TRI = CGP.SubtargetInfo->getRegisterInfo();
376 CGP.TLInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
377 CGP.TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
378 CGP.LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
379 CGP.BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
380 CGP.BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
381 CGP.PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
383 getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
384 CGP.BBSectionsProfileReader = BBSPRWP ? &BBSPRWP->getBBSPR() :
nullptr;
385 DomTreeUpdater DTUpdater(
386 &getAnalysis<DominatorTreeWrapperPass>().
getDomTree(),
387 DomTreeUpdater::UpdateStrategy::Lazy);
388 CGP.DTU = &DTUpdater;
394 "Optimize for code generation",
false,
false)
406 return new CodeGenPrepareLegacyPass();
411 CodeGenPrepare CGP(TM);
424 DL = &
F.getDataLayout();
437 "analysis to be available");
438 BBSectionsProfileReader =
441 DomTreeUpdater::UpdateStrategy::Lazy);
447 bool EverMadeChange =
false;
449 OptSize =
F.hasOptSize();
452 if (Opts.bbsections_guided_section_prefix && BBSectionsProfileReader &&
454 (void)
F.setSectionPrefix(
"hot");
455 }
else if (Opts.profile_guided_section_prefix) {
459 if (
F.hasFnAttribute(Attribute::Hot) ||
460 PSI->isFunctionHotInCallGraph(&
F, *BFI))
461 (void)
F.setSectionPrefix(
"hot");
465 else if (PSI->isFunctionColdInCallGraph(&
F, *BFI) ||
466 F.hasFnAttribute(Attribute::Cold))
467 (void)
F.setSectionPrefix(
"unlikely");
468 else if (Opts.profile_unknown_in_special_section &&
469 PSI->hasPartialSampleProfile() && PSI->isFunctionHotnessUnknown(
F))
470 (void)
F.setSectionPrefix(
"unknown");
476 const DenseMap<unsigned int, unsigned int> &BypassWidths =
479 while (BB !=
nullptr) {
492 EverMadeChange |= eliminateAssumptions(
F);
494 auto resetLoopInfo = [
this]() {
501 bool ResetLI =
false;
502 EverMadeChange |= eliminateMostlyEmptyBlocks(
F, ResetLI);
506 if (Opts.cgp_branch_opts)
507 EverMadeChange |= splitBranchCondition(
F);
513 EverMadeChange |=
Split;
519 assert(getDT().
verify(DominatorTree::VerificationLevel::Fast) &&
520 "Incorrect DominatorTree updates in CGP");
528 IsHugeFunc =
F.size() > Opts.cgp_huge_func;
530 bool MadeChange =
true;
531 bool FuncIterated =
false;
541 if (FuncIterated && !FreshBBs.
contains(&BB))
544 ModifyDT ModifiedDTOnIteration = ModifyDT::NotModifyDT;
560 else if (FuncIterated)
565 if (ModifiedDTOnIteration != ModifyDT::NotModifyDT)
570 FuncIterated = IsHugeFunc;
572 if (Opts.cgp_type_promotion_merge && !ValToSExtendedUses.empty())
573 MadeChange |= mergeSExts(
F);
574 if (!LargeOffsetGEPMap.
empty())
575 MadeChange |= splitLargeGEPOffsets();
576 MadeChange |= optimizePhiTypes(
F);
579 eliminateFallThrough(
F);
583 assert(getDT().
verify(DominatorTree::VerificationLevel::Fast) &&
584 "Incorrect DominatorTree updates in CGP");
591 for (Instruction *
I : RemovedInsts)
594 EverMadeChange |= MadeChange;
595 SeenChainsForSExt.
clear();
596 ValToSExtendedUses.clear();
597 RemovedInsts.clear();
598 LargeOffsetGEPMap.
clear();
599 LargeOffsetGEPID.
clear();
608 if (Opts.cgp_branch_opts) {
613 SmallSetVector<BasicBlock *, 8> WorkList;
614 for (BasicBlock &BB :
F) {
620 for (BasicBlock *Succ : Successors)
626 MadeChange |= !WorkList.
empty();
627 while (!WorkList.
empty()) {
633 for (BasicBlock *Succ : Successors)
643 if (EverMadeChange || MadeChange)
644 MadeChange |= eliminateFallThrough(
F);
646 EverMadeChange |= MadeChange;
649 if (Opts.cgp_gc_opts) {
651 for (BasicBlock &BB :
F)
652 for (Instruction &
I : BB)
655 for (
auto &
I : Statepoints)
656 EverMadeChange |= simplifyOffsetableRelocate(*
I);
661 EverMadeChange |= placeDbgValues(
F);
662 EverMadeChange |= placePseudoProbes(
F);
665 if (Opts.cgp_verify_bfi_updates)
669 return EverMadeChange;
672bool CodeGenPrepare::eliminateAssumptions(
Function &
F) {
673 bool MadeChange =
false;
674 for (BasicBlock &BB :
F) {
675 CurInstIterator = BB.begin();
676 while (CurInstIterator != BB.end()) {
681 Assume->eraseFromParent();
683 resetIteratorIfInvalidatedWhileCalling(&BB, [&]() {
694void CodeGenPrepare::removeAllAssertingVHReferences(
Value *V) {
695 LargeOffsetGEPMap.
erase(V);
696 NewGEPBases.
erase(V);
704 auto VecI = LargeOffsetGEPMap.
find(
GEP->getPointerOperand());
705 if (VecI == LargeOffsetGEPMap.
end())
708 auto &GEPVector = VecI->second;
711 if (GEPVector.empty())
712 LargeOffsetGEPMap.
erase(VecI);
716[[maybe_unused]]
void CodeGenPrepare::verifyBFIUpdates(
Function &
F) {
717 DominatorTree NewDT(
F);
720 BranchProbabilityInfo NewBPI(
F, NewCI, TLInfo);
721 BlockFrequencyInfo NewBFI(
F, NewBPI, NewCI);
722 NewBFI.verifyMatch(*BFI);
728bool CodeGenPrepare::eliminateFallThrough(
Function &
F) {
730 SmallPtrSet<BasicBlock *, 8> Preds;
738 BasicBlock *SinglePred = BB->getSinglePredecessor();
741 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
754 FreshBBs.
insert(SinglePred);
762 for (
auto *Pred : Preds)
770BasicBlock *CodeGenPrepare::findDestBlockOfMergeableEmptyBlock(BasicBlock *BB) {
779 if (BBI != BB->
begin()) {
790 if (!canMergeBlocks(BB, DestBB))
800bool CodeGenPrepare::eliminateMostlyEmptyBlocks(
Function &
F,
bool &ResetLI) {
801 SmallPtrSet<BasicBlock *, 16> Preheaders;
803 while (!LoopList.empty()) {
804 Loop *
L = LoopList.pop_back_val();
806 if (BasicBlock *Preheader =
L->getLoopPreheader())
807 Preheaders.
insert(Preheader);
811 bool MadeChange =
false;
812 SmallPtrSet<PHINode *, 32> KnownNonDeadPHIs;
816 if (Opts.cgp_delete_phis)
824 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
826 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.
count(BB)))
829 ResetLI |= eliminateMostlyEmptyBlock(BB);
835bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB,
842 if (Opts.cgp_preheader_prot && isPreheader &&
886 SmallPtrSet<BasicBlock *, 16> SameIncomingValueBBs;
891 if (DestBBPred == BB)
895 return DestPN.getIncomingValueForBlock(BB) ==
896 DestPN.getIncomingValueForBlock(DestBBPred);
898 SameIncomingValueBBs.
insert(DestBBPred);
904 if (SameIncomingValueBBs.
count(Pred))
907 BlockFrequency PredFreq = BFI->getBlockFreq(Pred);
908 BlockFrequency
BBFreq = BFI->getBlockFreq(BB);
910 for (
auto *SameValueBB : SameIncomingValueBBs)
911 if (SameValueBB->getUniquePredecessor() == Pred &&
912 DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
913 BBFreq += BFI->getBlockFreq(SameValueBB);
915 std::optional<BlockFrequency> Limit =
916 BBFreq.mul(Opts.cgp_freq_ratio_to_skip_merge);
917 return !Limit || PredFreq <= *Limit;
923bool CodeGenPrepare::canMergeBlocks(
const BasicBlock *BB,
924 const BasicBlock *DestBB)
const {
928 for (
const PHINode &PN : BB->
phis()) {
929 for (
const User *U : PN.users()) {
938 for (
unsigned I = 0,
E = UPN->getNumIncomingValues();
I !=
E; ++
I) {
941 Insn->
getParent() != UPN->getIncomingBlock(
I))
956 SmallPtrSet<const BasicBlock *, 16> BBPreds;
959 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
960 BBPreds.
insert(BBPN->getIncomingBlock(i));
968 if (BBPreds.
count(Pred)) {
969 for (
const PHINode &PN : DestBB->
phis()) {
970 const Value *
V1 = PN.getIncomingValueForBlock(Pred);
971 const Value *V2 = PN.getIncomingValueForBlock(BB);
975 if (V2PN->getParent() == BB)
976 V2 = V2PN->getIncomingValueForBlock(Pred);
995 E = OldI->user_end();
1008bool CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
1018 if (SinglePred != DestBB) {
1019 assert(SinglePred == BB &&
1020 "Single predecessor not the same as predecessor");
1029 FreshBBs.
insert(SinglePred);
1030 FreshBBs.
erase(DestBB);
1038 for (PHINode &PN : DestBB->
phis()) {
1040 Value *InVal = PN.removeIncomingValue(BB,
false);
1045 if (InValPhi && InValPhi->
getParent() == BB) {
1054 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1055 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1058 PN.addIncoming(InVal, Pred);
1072 SmallPtrSet<BasicBlock *, 8> SeenPreds;
1076 if (!PredOfDestBB.contains(Pred)) {
1077 if (SeenPreds.
insert(Pred).second)
1078 DTUpdates.
push_back({DominatorTree::Insert, Pred, DestBB});
1083 if (SeenPreds.
insert(Pred).second)
1084 DTUpdates.
push_back({DominatorTree::Delete, Pred, BB});
1086 DTUpdates.
push_back({DominatorTree::Delete, BB, DestBB});
1106 for (
auto *ThisRelocate : AllRelocateCalls) {
1107 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1108 ThisRelocate->getDerivedPtrIndex());
1109 RelocateIdxMap.
insert(std::make_pair(
K, ThisRelocate));
1111 for (
auto &Item : RelocateIdxMap) {
1112 std::pair<unsigned, unsigned>
Key = Item.first;
1113 if (
Key.first ==
Key.second)
1118 auto BaseKey = std::make_pair(
Key.first,
Key.first);
1121 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1122 if (MaybeBase == RelocateIdxMap.
end())
1127 RelocateInstMap[MaybeBase->second].push_back(
I);
1135 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1138 if (!
Op ||
Op->getZExtValue() > 20)
1142 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1152 bool MadeChange =
false;
1159 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1160 &*R != RelocatedBase; ++R)
1164 RelocatedBase->
moveBefore(RI->getIterator());
1171 "Not relocating a derived object of the original base object");
1172 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1177 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1187 if (!Derived || Derived->getPointerOperand() !=
Base)
1196 "Should always have one since it's not a terminator");
1200 Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
1224 Value *ActualRelocatedBase = RelocatedBase;
1225 if (RelocatedBase->
getType() !=
Base->getType()) {
1226 ActualRelocatedBase =
1227 Builder.CreateBitCast(RelocatedBase,
Base->getType());
1229 Value *Replacement =
1230 Builder.CreateGEP(Derived->getSourceElementType(), ActualRelocatedBase,
1236 Value *ActualReplacement = Replacement;
1237 if (Replacement->
getType() != ToReplace->getType()) {
1239 Builder.CreateBitCast(Replacement, ToReplace->
getType());
1242 ToReplace->eraseFromParent();
1266bool CodeGenPrepare::simplifyOffsetableRelocate(GCStatepointInst &
I) {
1267 bool MadeChange =
false;
1269 for (
auto *U :
I.users())
1276 if (AllRelocateCalls.
size() < 2)
1281 MapVector<GCRelocateInst *, SmallVector<GCRelocateInst *, 0>> RelocateInstMap;
1283 if (RelocateInstMap.
empty())
1286 for (
auto &Item : RelocateInstMap)
1300 bool MadeChange =
false;
1303 Use &TheUse = UI.getUse();
1310 UserBB = PN->getIncomingBlock(TheUse);
1318 if (
User->isEHPad())
1328 if (UserBB == DefBB)
1332 CastInst *&InsertedCast = InsertedCasts[UserBB];
1334 if (!InsertedCast) {
1342 TheUse = InsertedCast;
1361 if (!SrcInst || SrcInst->getParent() == BCI->
getParent() ||
1362 SrcInst->isTerminator())
1366 Type *SrcTy = SrcInst->getType();
1380 bool IsCrossDomain = DestTy->
isFPOrFPVectorTy() != SrcTy->isFPOrFPVectorTy();
1383 unsigned NativeWidth =
DL.getPointerSizeInBits();
1384 bool IsLargeScalar =
1386 DL.getTypeSizeInBits(DestTy).getFixedValue() > NativeWidth;
1388 if (IsCrossDomain || IsLargeScalar)
1394 : std::next(SrcInst->getIterator());
1411 ASC->getDestAddressSpace()))
1466static std::optional<std::pair<Instruction *, Constant *>>
1469 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1470 return std::nullopt;
1473 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1474 return std::nullopt;
1478 return std::make_pair(IVInc, Step);
1479 return std::nullopt;
1492 return IVInc->first ==
I;
1496bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
1500 auto IsReplacableIVIncrement = [
this, &
Cmp](BinaryOperator *BO) {
1504 assert(L &&
"L should not be null after isIVIncrement()");
1506 if (LI->getLoopFor(
Cmp->getParent()) != L)
1519 return BO->
hasOneUse() && DT.dominates(
Cmp->getParent(),
L->getLoopLatch());
1521 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1544 if (BO->
getOpcode() == Instruction::Add &&
1545 IID == Intrinsic::usub_with_overflow) {
1552 for (Instruction &Iter : *
Cmp->getParent()) {
1555 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1560 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1563 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1564 if (BO->
getOpcode() != Instruction::Xor) {
1565 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1569 "Patterns with XOr should use the BO only in the compare");
1570 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1572 Cmp->eraseFromParent();
1582 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1590 B = ConstantInt::get(
B->getType(), 1);
1598 for (
User *U :
A->users()) {
1609bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp,
1610 ModifyDT &ModifiedDT) {
1611 bool EdgeCase =
false;
1613 BinaryOperator *
Add;
1618 A =
Add->getOperand(0);
1619 B =
Add->getOperand(1);
1625 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1631 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1634 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1635 Intrinsic::uadd_with_overflow))
1639 ModifiedDT = ModifyDT::ModifyInstDT;
1643bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
1644 ModifyDT &ModifiedDT) {
1651 ICmpInst::Predicate Pred =
Cmp->getPredicate();
1652 if (Pred == ICmpInst::ICMP_UGT) {
1654 Pred = ICmpInst::ICMP_ULT;
1658 B = ConstantInt::get(
B->getType(), 1);
1659 Pred = ICmpInst::ICMP_ULT;
1664 Pred = ICmpInst::ICMP_ULT;
1666 if (Pred != ICmpInst::ICMP_ULT)
1673 BinaryOperator *
Sub =
nullptr;
1674 for (User *U : CmpVariableOperand->
users()) {
1682 const APInt *CmpC, *AddC;
1694 Sub->hasNUsesOrMore(1)))
1700 if (
Sub->getParent() !=
Cmp->getParent() && !
Sub->hasOneUse())
1703 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1704 Cmp, Intrinsic::usub_with_overflow))
1708 ModifiedDT = ModifyDT::ModifyInstDT;
1715bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1728 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1734 Type *OpTy =
X->getType();
1742 if (Pred == ICmpInst::ICMP_EQ) {
1743 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1744 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1746 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1752 if (IsPowerOf2OrZeroTest ||
1763 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1772 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1775 Cmp->replaceAllUsesWith(NewCmp);
1795 bool UsedInPhiOrCurrentBlock =
any_of(Cmp->users(), [Cmp](
User *U) {
1796 return isa<PHINode>(U) ||
1797 cast<Instruction>(U)->getParent() == Cmp->getParent();
1802 if (UsedInPhiOrCurrentBlock && Cmp->getOperand(0)->getType()->isIntegerTy() &&
1803 Cmp->getOperand(0)->getType()->getScalarSizeInBits() >
1804 DL.getLargestLegalIntTypeSizeInBits())
1810 bool MadeChange =
false;
1813 Use &TheUse = UI.getUse();
1828 if (UserBB == DefBB)
1832 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1838 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1845 TheUse = InsertedCmp;
1851 if (Cmp->use_empty()) {
1852 Cmp->eraseFromParent();
1879 bool EnableICmpEqToICmpSt) {
1889 for (
User *U : Cmp->users()) {
1911 if (CmpBB != FalseBB)
1914 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
1928 for (
User *U : Cmp->users()) {
1930 BI->swapSuccessors();
1936 SI->swapProfMetadata();
1948 Value *Op0 = Cmp->getOperand(0);
1949 Value *Op1 = Cmp->getOperand(1);
1958 unsigned NumInspected = 0;
1961 if (++NumInspected > 128)
1969 if (GoodToSwap > 0) {
1970 Cmp->swapOperands();
1990 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
1993 auto [ClassVal, ClassTest] =
1999 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2003 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
2004 Cmp->replaceAllUsesWith(IsFPClass);
2012 Value *Incr, *RemAmt;
2017 Value *AddInst, *AddOffset;
2020 if (PN !=
nullptr) {
2022 AddOffset =
nullptr;
2040 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2044 if (!L->contains(Rem))
2048 if (!L->isLoopInvariant(RemAmt))
2052 if (AddOffset && !L->isLoopInvariant(AddOffset))
2073 AddInstOut = AddInst;
2074 AddOffsetOut = AddOffset;
2093 Value *AddOffset, *RemAmt, *AddInst;
2096 AddOffset, LoopIncrPN))
2121 assert(AddOffset &&
"We found an add but missing values");
2139 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2144 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2149 NewRem->
addIncoming(Start, L->getLoopPreheader());
2154 FreshBBs.
insert(L->getLoopLatch());
2165bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2171bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2175 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2178 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2181 if (unfoldPowerOf2Test(Cmp))
2202 SetOfInstrs &InsertedInsts) {
2205 assert(!InsertedInsts.count(AndI) &&
2206 "Attempting to optimize already optimized and instruction");
2207 (void)InsertedInsts;
2221 for (
auto *U : AndI->
users()) {
2229 if (!CmpC || !CmpC->
isZero())
2244 Use &TheUse = UI.getUse();
2262 TheUse = InsertedAnd;
2279 if (
User->getOpcode() != Instruction::And ||
2285 if ((Cimm & (Cimm + 1)).getBoolValue())
2299 bool MadeChange =
false;
2302 TruncE = TruncI->user_end();
2303 TruncUI != TruncE;) {
2305 Use &TruncTheUse = TruncUI.getUse();
2330 if (UserBB == TruncUserBB)
2334 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2336 if (!InsertedShift && !InsertedTrunc) {
2340 if (ShiftI->
getOpcode() == Instruction::AShr)
2342 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2345 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2353 TruncInsertPt.setHeadBit(
true);
2354 assert(TruncInsertPt != TruncUserBB->
end());
2358 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2359 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2363 TruncTheUse = InsertedTrunc;
2396 bool MadeChange =
false;
2400 Use &TheUse = UI.getUse();
2414 if (UserBB == DefBB) {
2442 if (!InsertedShift) {
2446 if (ShiftI->
getOpcode() == Instruction::AShr)
2448 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2451 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2459 TheUse = InsertedShift;
2507 unsigned SizeInBits = Ty->getScalarSizeInBits();
2508 if (Ty->isVectorTy())
2519 nullptr,
"cond.false");
2521 FreshBBs.
insert(CallBlock);
2528 SplitPt.setHeadBit(
true);
2530 nullptr,
"cond.end");
2532 FreshBBs.
insert(EndBlock);
2536 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2543 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2544 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2545 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2551 Builder.SetInsertPoint(EndBlock->
begin());
2552 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2562 ModifiedDT = ModifyDT::ModifyBBDT;
2566bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2570 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2578 for (
auto &Arg : CI->
args()) {
2583 if (!Arg->getType()->isPointerTy())
2585 APInt
Offset(
DL->getIndexSizeInBits(
2588 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2595 if (AllocaSize && AllocaSize->getKnownMinValue() >= MinSize + Offset2)
2613 MaybeAlign MIDestAlign =
MI->getDestAlign();
2614 if (!MIDestAlign || DestAlign > *MIDestAlign)
2615 MI->setDestAlignment(DestAlign);
2617 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2619 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2620 MTI->setSourceAlignment(SrcAlign);
2630 for (
auto &Arg : CI->
args()) {
2631 if (!Arg->getType()->isPointerTy())
2633 unsigned AS = Arg->getType()->getPointerAddressSpace();
2634 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2640 switch (
II->getIntrinsicID()) {
2643 case Intrinsic::assume:
2645 case Intrinsic::allow_runtime_check:
2646 case Intrinsic::allow_ubsan_check:
2647 case Intrinsic::experimental_widenable_condition: {
2651 if (
II->use_empty()) {
2652 II->eraseFromParent();
2656 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2661 case Intrinsic::objectsize:
2663 case Intrinsic::is_constant:
2665 case Intrinsic::aarch64_stlxr:
2666 case Intrinsic::aarch64_stxr: {
2675 InsertedInsts.insert(ExtVal);
2679 case Intrinsic::launder_invariant_group: {
2680 Value *ArgVal =
II->getArgOperand(0);
2681 auto it = LargeOffsetGEPMap.
find(
II);
2682 if (it != LargeOffsetGEPMap.
end()) {
2686 auto GEPs = std::move(it->second);
2687 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2692 II->eraseFromParent();
2695 case Intrinsic::cttz:
2696 case Intrinsic::ctlz:
2700 case Intrinsic::fshl:
2701 case Intrinsic::fshr:
2702 return optimizeFunnelShift(
II);
2703 case Intrinsic::masked_gather:
2704 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2705 case Intrinsic::masked_scatter:
2706 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2707 case Intrinsic::masked_load:
2710 if (VT->getNumElements() == 1) {
2711 Value *PtrVal =
II->getArgOperand(0);
2713 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2718 case Intrinsic::masked_store:
2722 if (VT->getNumElements() == 1) {
2723 Value *PtrVal =
II->getArgOperand(1);
2725 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2730 case Intrinsic::umul_with_overflow:
2731 return optimizeMulWithOverflow(
II,
false, ModifiedDT);
2732 case Intrinsic::smul_with_overflow:
2733 return optimizeMulWithOverflow(
II,
true, ModifiedDT);
2736 SmallVector<Value *, 2> PtrOps;
2739 while (!PtrOps.
empty()) {
2742 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2756 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2758 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2768 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2769 if (!
F->getReturnType()->isPointerTy())
2772 GlobalVariable *UniformValue =
nullptr;
2773 for (
auto &BB : *
F) {
2778 else if (V != UniformValue)
2786 return UniformValue;
2789 if (
Callee->hasExactDefinition()) {
2790 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2791 bool MadeChange =
false;
2817 switch (
II->getIntrinsicID()) {
2818 case Intrinsic::memset:
2819 case Intrinsic::memcpy:
2820 case Intrinsic::memmove:
2827 if (Callee && TLInfo)
2829 case LibFunc_strcpy:
2830 case LibFunc_strncpy:
2831 case LibFunc_strcat:
2832 case LibFunc_strncat:
2873bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
2874 ModifyDT &ModifiedDT) {
2882 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2884 PHINode *PN =
nullptr;
2885 ExtractValueInst *EVI =
nullptr;
2886 BitCastInst *BCI =
nullptr;
2906 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
2912 return II->getIntrinsicID() == Intrinsic::lifetime_end;
2918 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
2920 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
2942 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
2949 auto MayBePermittedAsTailCall = [&](
const auto *CI) {
2966 MayBePermittedAsTailCall(CI)) {
2987 MayBePermittedAsTailCall(CI)) {
2994 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
2996 if (!VisitedBBs.
insert(Pred).second)
2998 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
3000 if (CI && CI->
use_empty() && MayBePermittedAsTailCall(CI)) {
3015 for (
auto const &TailCallBB : TailCallBBs) {
3024 assert(!Opts.cgp_verify_bfi_updates ||
3025 BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB));
3026 BFI->setBlockFreq(BB,
3027 (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB)));
3028 ModifiedDT = ModifyDT::ModifyBBDT;
3037 for (
auto *CI : CallInsts) {
3038 for (
auto const *FakeUse : FakeUses) {
3039 auto *ClonedInst = FakeUse->clone();
3057struct ExtAddrMode :
public TargetLowering::AddrMode {
3058 Value *BaseReg =
nullptr;
3059 Value *ScaledReg =
nullptr;
3060 Value *OriginalValue =
nullptr;
3061 bool InBounds =
true;
3065 BaseRegField = 0x01,
3067 BaseOffsField = 0x04,
3068 ScaledRegField = 0x08,
3070 MultipleFields = 0xff
3073 ExtAddrMode() =
default;
3075 void print(raw_ostream &OS)
const;
3082 if (ScaledReg == From)
3086 FieldName
compare(
const ExtAddrMode &other) {
3089 if (BaseReg && other.
BaseReg &&
3091 return MultipleFields;
3092 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3093 return MultipleFields;
3096 return MultipleFields;
3099 if (InBounds != other.InBounds)
3100 return MultipleFields;
3103 unsigned Result = NoField;
3106 if (BaseGV != other.BaseGV)
3108 if (BaseOffs != other.BaseOffs)
3111 Result |= ScaledRegField;
3114 if (Scale && other.
Scale && Scale != other.
Scale)
3118 return MultipleFields;
3120 return static_cast<FieldName
>(
Result);
3130 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3141 case ScaledRegField:
3148 void SetCombinedField(FieldName
Field,
Value *V,
3149 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3154 case ExtAddrMode::BaseRegField:
3157 case ExtAddrMode::BaseGVField:
3160 assert(BaseReg ==
nullptr);
3164 case ExtAddrMode::ScaledRegField:
3169 for (
const ExtAddrMode &AM : AddrModes)
3175 case ExtAddrMode::BaseOffsField:
3178 assert(ScaledReg ==
nullptr);
3188static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3194#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3195void ExtAddrMode::print(raw_ostream &OS)
const {
3196 bool NeedPlus =
false;
3202 BaseGV->printAsOperand(OS,
false);
3207 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3212 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3213 BaseReg->printAsOperand(OS,
false);
3217 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3240class TypePromotionTransaction {
3244 class TypePromotionAction {
3252 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3254 virtual ~TypePromotionAction() =
default;
3261 virtual void undo() = 0;
3266 virtual void commit() {
3272 class InsertionHandler {
3281 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3284 bool HasPrevInstruction;
3288 InsertionHandler(Instruction *Inst) {
3296 if (HasPrevInstruction) {
3304 void insert(Instruction *Inst) {
3305 if (HasPrevInstruction) {
3317 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3322 class OperandSetter :
public TypePromotionAction {
3331 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3332 : TypePromotionAction(Inst),
Idx(
Idx) {
3334 <<
"for:" << *Inst <<
"\n"
3335 <<
"with:" << *NewVal <<
"\n");
3341 void undo()
override {
3343 <<
"for: " << *Inst <<
"\n"
3344 <<
"with: " << *Origin <<
"\n");
3351 class OperandsHider :
public TypePromotionAction {
3353 SmallVector<Value *, 4> OriginalValues;
3357 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3360 OriginalValues.
reserve(NumOpnds);
3361 for (
unsigned It = 0; It < NumOpnds; ++It) {
3373 void undo()
override {
3375 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3381 class TruncBuilder :
public TypePromotionAction {
3388 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3390 Builder.SetCurrentDebugLocation(
DebugLoc());
3391 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3396 Value *getBuiltValue() {
return Val; }
3399 void undo()
override {
3402 IVal->eraseFromParent();
3407 class SExtBuilder :
public TypePromotionAction {
3414 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3415 : TypePromotionAction(InsertPt) {
3417 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3422 Value *getBuiltValue() {
return Val; }
3425 void undo()
override {
3428 IVal->eraseFromParent();
3433 class ZExtBuilder :
public TypePromotionAction {
3440 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3441 : TypePromotionAction(InsertPt) {
3443 Builder.SetCurrentDebugLocation(
DebugLoc());
3444 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3449 Value *getBuiltValue() {
return Val; }
3452 void undo()
override {
3455 IVal->eraseFromParent();
3460 class TypeMutator :
public TypePromotionAction {
3466 TypeMutator(Instruction *Inst,
Type *NewTy)
3467 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3468 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3474 void undo()
override {
3475 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3482 class UsesReplacer :
public TypePromotionAction {
3484 struct InstructionAndIdx {
3491 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3492 : Inst(Inst),
Idx(
Idx) {}
3498 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3508 UsesReplacer(Instruction *Inst,
Value *New)
3509 : TypePromotionAction(Inst),
New(
New) {
3510 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3513 for (Use &U : Inst->
uses()) {
3515 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3526 void undo()
override {
3528 for (InstructionAndIdx &Use : OriginalUses)
3529 Use.Inst->setOperand(
Use.Idx, Inst);
3534 for (DbgVariableRecord *DVR : DbgVariableRecords)
3535 DVR->replaceVariableLocationOp(New, Inst);
3540 class InstructionRemover :
public TypePromotionAction {
3542 InsertionHandler Inserter;
3546 OperandsHider Hider;
3549 UsesReplacer *Replacer =
nullptr;
3552 SetOfInstrs &RemovedInsts;
3559 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3560 Value *New =
nullptr)
3561 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3562 RemovedInsts(RemovedInsts) {
3564 Replacer =
new UsesReplacer(Inst, New);
3565 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3566 RemovedInsts.insert(Inst);
3573 ~InstructionRemover()
override {
delete Replacer; }
3575 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3576 InstructionRemover(
const InstructionRemover &other) =
delete;
3580 void undo()
override {
3581 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3582 Inserter.insert(Inst);
3586 RemovedInsts.erase(Inst);
3594 using ConstRestorationPt =
const TypePromotionAction *;
3596 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3597 : RemovedInsts(RemovedInsts) {}
3604 void rollback(ConstRestorationPt Point);
3607 ConstRestorationPt getRestorationPoint()
const;
3612 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3621 void mutateType(Instruction *Inst,
Type *NewTy);
3624 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3637 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3639 SetOfInstrs &RemovedInsts;
3644void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3646 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3647 Inst, Idx, NewVal));
3650void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3653 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3654 Inst, RemovedInsts, NewVal));
3657void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3660 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3663void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3665 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3668Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3669 std::unique_ptr<TruncBuilder> Ptr(
new TruncBuilder(Opnd, Ty));
3670 Value *Val = Ptr->getBuiltValue();
3671 Actions.push_back(std::move(Ptr));
3675Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3677 std::unique_ptr<SExtBuilder> Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3678 Value *Val = Ptr->getBuiltValue();
3679 Actions.push_back(std::move(Ptr));
3683Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3685 std::unique_ptr<ZExtBuilder> Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3686 Value *Val = Ptr->getBuiltValue();
3687 Actions.push_back(std::move(Ptr));
3691TypePromotionTransaction::ConstRestorationPt
3692TypePromotionTransaction::getRestorationPoint()
const {
3693 return !Actions.empty() ? Actions.back().get() :
nullptr;
3696bool TypePromotionTransaction::commit() {
3697 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3704void TypePromotionTransaction::rollback(
3705 TypePromotionTransaction::ConstRestorationPt Point) {
3706 while (!Actions.empty() && Point != Actions.back().get()) {
3707 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3717class AddressingModeMatcher {
3718 SmallVectorImpl<Instruction *> &AddrModeInsts;
3719 const TargetLowering &TLI;
3720 const TargetRegisterInfo &
TRI;
3721 const DataLayout &
DL;
3723 const std::function<
const DominatorTree &()> getDTFn;
3736 const SetOfInstrs &InsertedInsts;
3739 InstrToOrigTy &PromotedInsts;
3742 TypePromotionTransaction &TPT;
3745 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3749 bool IgnoreProfitability;
3752 bool OptSize =
false;
3754 ProfileSummaryInfo *PSI;
3755 BlockFrequencyInfo *BFI;
3756 const CodeGenOptions &Opts;
3758 AddressingModeMatcher(
3759 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3760 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3761 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3762 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3763 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3764 TypePromotionTransaction &TPT,
3765 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3766 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
3767 const CodeGenOptions &Opts)
3768 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
DL(
MI->getDataLayout()), LI(LI),
3769 getDTFn(getDTFn), AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
3770 AddrMode(AM), InsertedInsts(InsertedInsts),
3771 PromotedInsts(PromotedInsts), TPT(TPT), LargeOffsetGEP(LargeOffsetGEP),
3772 OptSize(OptSize), PSI(PSI), BFI(BFI), Opts(Opts) {
3773 IgnoreProfitability =
false;
3785 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3786 SmallVectorImpl<Instruction *> &AddrModeInsts,
3787 const TargetLowering &TLI,
const LoopInfo &LI,
3788 const std::function<
const DominatorTree &()> getDTFn,
3789 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3790 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3791 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3792 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
3793 const CodeGenOptions &Opts) {
3796 bool Success = AddressingModeMatcher(
3797 AddrModeInsts, TLI,
TRI, LI, getDTFn, AccessTy, AS,
3798 MemoryInst, Result, InsertedInsts, PromotedInsts, TPT,
3799 LargeOffsetGEP, OptSize, PSI, BFI, Opts)
3807 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3809 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3810 bool *MovedAway =
nullptr);
3811 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3812 ExtAddrMode &AMBefore,
3813 ExtAddrMode &AMAfter);
3814 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3815 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3816 Value *PromotedOperand)
const;
3822class PhiNodeSetIterator {
3823 PhiNodeSet *
const Set;
3824 size_t CurrentIndex = 0;
3829 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3831 PhiNodeSetIterator &operator++();
3847 friend class PhiNodeSetIterator;
3849 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3850 using iterator = PhiNodeSetIterator;
3865 size_t FirstValidElement = 0;
3871 bool insert(PHINode *Ptr) {
3872 if (NodeMap.insert(std::make_pair(Ptr,
NodeList.
size())).second) {
3882 bool erase(PHINode *Ptr) {
3883 if (NodeMap.erase(Ptr)) {
3884 SkipRemovedElements(FirstValidElement);
3894 FirstValidElement = 0;
3900 if (FirstValidElement == 0)
3901 SkipRemovedElements(FirstValidElement);
3902 return PhiNodeSetIterator(
this, FirstValidElement);
3909 size_t size()
const {
return NodeMap.size(); }
3912 size_t count(PHINode *Ptr)
const {
return NodeMap.count(Ptr); }
3920 void SkipRemovedElements(
size_t &CurrentIndex) {
3922 auto it = NodeMap.find(NodeList[CurrentIndex]);
3925 if (it != NodeMap.end() && it->second == CurrentIndex)
3932PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
3935PHINode *PhiNodeSetIterator::operator*()
const {
3937 "PhiNodeSet access out of range");
3938 return Set->NodeList[CurrentIndex];
3941PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
3943 "PhiNodeSet access out of range");
3945 Set->SkipRemovedElements(CurrentIndex);
3949bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
3950 return CurrentIndex ==
RHS.CurrentIndex;
3953bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
3954 return !((*this) ==
RHS);
3960class SimplificationTracker {
3961 DenseMap<Value *, Value *> Storage;
3964 PhiNodeSet AllPhiNodes;
3966 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
3971 auto SV = Storage.
find(V);
3972 if (SV == Storage.
end())
3980 void ReplacePhi(PHINode *From, PHINode *To) {
3981 Value *OldReplacement = Get(From);
3982 while (OldReplacement != From) {
3985 OldReplacement = Get(From);
3987 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
3990 AllPhiNodes.erase(From);
3994 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
3996 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
3998 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
4000 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4002 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4004 void destroyNewNodes(
Type *CommonType) {
4007 for (
auto *
I : AllPhiNodes) {
4008 I->replaceAllUsesWith(Dummy);
4009 I->eraseFromParent();
4011 AllPhiNodes.clear();
4012 for (
auto *
I : AllSelectNodes) {
4013 I->replaceAllUsesWith(Dummy);
4014 I->eraseFromParent();
4016 AllSelectNodes.clear();
4021class AddressingModeCombiner {
4022 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4023 typedef std::pair<PHINode *, PHINode *> PHIPair;
4030 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4033 bool AllAddrModesTrivial =
true;
4036 Type *CommonType =
nullptr;
4038 const DataLayout &
DL;
4039 const CodeGenOptions &Opts;
4045 Value *CommonValue =
nullptr;
4048 AddressingModeCombiner(
const DataLayout &
DL,
const CodeGenOptions &Opts,
4049 Value *OriginalValue)
4050 :
DL(
DL), Opts(Opts), Original(OriginalValue) {}
4052 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4055 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4060 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4064 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4067 if (AddrModes.
empty()) {
4075 ExtAddrMode::FieldName ThisDifferentField =
4076 AddrModes[0].compare(NewAddrMode);
4077 if (DifferentField == ExtAddrMode::NoField)
4078 DifferentField = ThisDifferentField;
4079 else if (DifferentField != ThisDifferentField)
4080 DifferentField = ExtAddrMode::MultipleFields;
4083 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4086 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4091 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4096 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4097 !NewAddrMode.HasBaseReg);
4114 bool combineAddrModes() {
4116 if (AddrModes.
size() == 0)
4120 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4125 if (AllAddrModesTrivial)
4128 if (!addrModeCombiningAllowed())
4134 FoldAddrToValueMapping
Map;
4135 if (!initializeMap(Map))
4138 CommonValue = findCommon(Map);
4140 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4141 return CommonValue !=
nullptr;
4147 void eraseCommonValueIfDead() {
4148 if (CommonValue && CommonValue->
use_empty())
4150 CommonInst->eraseFromParent();
4158 bool initializeMap(FoldAddrToValueMapping &Map) {
4161 SmallVector<Value *, 2> NullValue;
4163 for (
auto &AM : AddrModes) {
4167 if (CommonType && CommonType !=
Type)
4170 Map[AM.OriginalValue] = DV;
4175 assert(CommonType &&
"At least one non-null value must be!");
4176 for (
auto *V : NullValue)
4204 Value *findCommon(FoldAddrToValueMapping &Map) {
4212 SimplificationTracker
ST;
4217 InsertPlaceholders(Map, TraverseOrder, ST);
4220 FillPlaceholders(Map, TraverseOrder, ST);
4222 if (!Opts.cgp_addr_sink_new_select &&
ST.countNewSelectNodes() > 0) {
4223 ST.destroyNewNodes(CommonType);
4228 unsigned PhiNotMatchedCount = 0;
4229 if (!MatchPhiSet(ST, Opts.cgp_addr_sink_new_phis, PhiNotMatchedCount)) {
4230 ST.destroyNewNodes(CommonType);
4234 auto *
Result =
ST.Get(
Map.find(Original)->second);
4236 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4237 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4244 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4245 SmallSetVector<PHIPair, 8> &Matcher,
4246 PhiNodeSet &PhiNodesToMatch) {
4249 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4252 SmallSet<PHIPair, 8> Visited;
4253 while (!WorkList.
empty()) {
4255 if (!Visited.
insert(Item).second)
4262 for (
auto *
B : Item.first->blocks()) {
4263 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4264 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4265 if (FirstValue == SecondValue)
4275 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4280 if (Matcher.
count({FirstPhi, SecondPhi}))
4285 if (MatchedPHIs.
insert(FirstPhi).second)
4286 Matcher.
insert({FirstPhi, SecondPhi});
4288 WorkList.
push_back({FirstPhi, SecondPhi});
4297 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4298 unsigned &PhiNotMatchedCount) {
4302 SmallSetVector<PHIPair, 8> Matched;
4303 SmallPtrSet<PHINode *, 8> WillNotMatch;
4304 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4305 while (PhiNodesToMatch.size()) {
4306 PHINode *
PHI = *PhiNodesToMatch.begin();
4309 WillNotMatch.
clear();
4313 bool IsMatched =
false;
4314 for (
auto &
P :
PHI->getParent()->phis()) {
4316 if (PhiNodesToMatch.count(&
P))
4318 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4328 for (
auto MV : Matched)
4329 ST.ReplacePhi(MV.first, MV.second);
4334 if (!AllowNewPhiNodes)
4337 PhiNotMatchedCount += WillNotMatch.
size();
4338 for (
auto *
P : WillNotMatch)
4339 PhiNodesToMatch.erase(
P);
4344 void FillPlaceholders(FoldAddrToValueMapping &Map,
4345 SmallVectorImpl<Value *> &TraverseOrder,
4346 SimplificationTracker &ST) {
4347 while (!TraverseOrder.
empty()) {
4349 assert(
Map.contains(Current) &&
"No node to fill!!!");
4355 auto *TrueValue = CurrentSelect->getTrueValue();
4356 assert(
Map.contains(TrueValue) &&
"No True Value!");
4357 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4358 auto *FalseValue = CurrentSelect->getFalseValue();
4359 assert(
Map.contains(FalseValue) &&
"No False Value!");
4360 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4367 assert(
Map.contains(PV) &&
"No predecessor Value!");
4368 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4379 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4380 SmallVectorImpl<Value *> &TraverseOrder,
4381 SimplificationTracker &ST) {
4384 "Address must be a Phi or Select node");
4387 while (!Worklist.
empty()) {
4390 if (
Map.contains(Current))
4401 CurrentSelect->getName(),
4402 CurrentSelect->getIterator(), CurrentSelect);
4406 Worklist.
push_back(CurrentSelect->getTrueValue());
4407 Worklist.
push_back(CurrentSelect->getFalseValue());
4415 ST.insertNewPhi(
PHI);
4421 bool addrModeCombiningAllowed() {
4422 if (!Opts.cgp_complex_addr_modes)
4424 switch (DifferentField) {
4427 case ExtAddrMode::BaseRegField:
4428 return Opts.cgp_addr_sink_combine_base_reg;
4429 case ExtAddrMode::BaseGVField:
4430 return Opts.cgp_addr_sink_combine_base_gv;
4431 case ExtAddrMode::BaseOffsField:
4432 return Opts.cgp_addr_sink_combine_base_offs;
4433 case ExtAddrMode::ScaledRegField:
4434 return Opts.cgp_addr_sink_combine_scaled_reg;
4443bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4448 return matchAddr(ScaleReg,
Depth);
4459 ExtAddrMode TestAddrMode =
AddrMode;
4463 TestAddrMode.
Scale += Scale;
4477 ConstantInt *CI =
nullptr;
4478 Value *AddLHS =
nullptr;
4482 TestAddrMode.InBounds =
false;
4499 auto GetConstantStep =
4500 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4503 return std::nullopt;
4506 return std::nullopt;
4514 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4515 return std::nullopt;
4517 return std::make_pair(IVInc->first, ConstantStep->getValue());
4518 return std::nullopt;
4533 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4540 APInt Step = IVStep->second;
4542 if (
Offset.isSignedIntN(64)) {
4543 TestAddrMode.InBounds =
false;
4545 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4550 getDTFn().
dominates(IVInc, MemoryInst)) {
4570 switch (
I->getOpcode()) {
4571 case Instruction::BitCast:
4572 case Instruction::AddrSpaceCast:
4574 if (
I->getType() ==
I->getOperand(0)->getType())
4576 return I->getType()->isIntOrPtrTy();
4577 case Instruction::PtrToInt:
4580 case Instruction::IntToPtr:
4583 case Instruction::Add:
4585 case Instruction::Mul:
4586 case Instruction::Shl:
4589 case Instruction::GetElementPtr:
4617class TypePromotionHelper {
4620 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4621 Instruction *ExtOpnd,
bool IsSExt) {
4622 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4623 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4627 if (It->second.getInt() == ExtTy)
4633 ExtTy = BothExtension;
4635 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4642 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4643 Instruction *Opnd,
bool IsSExt) {
4644 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4645 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4646 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4647 return It->second.getPointer();
4662 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4663 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4667 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4680 static Value *promoteOperandForTruncAndAnyExt(
4681 Instruction *Ext, TypePromotionTransaction &TPT,
4682 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4683 SmallVectorImpl<Instruction *> *Exts,
4684 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4695 static Value *promoteOperandForOther(Instruction *Ext,
4696 TypePromotionTransaction &TPT,
4697 InstrToOrigTy &PromotedInsts,
4698 unsigned &CreatedInstsCost,
4699 SmallVectorImpl<Instruction *> *Exts,
4700 SmallVectorImpl<Instruction *> *Truncs,
4701 const TargetLowering &TLI,
bool IsSExt);
4704 static Value *signExtendOperandForOther(
4705 Instruction *Ext, TypePromotionTransaction &TPT,
4706 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4707 SmallVectorImpl<Instruction *> *Exts,
4708 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4709 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4710 Exts, Truncs, TLI,
true);
4714 static Value *zeroExtendOperandForOther(
4715 Instruction *Ext, TypePromotionTransaction &TPT,
4716 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4717 SmallVectorImpl<Instruction *> *Exts,
4718 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4719 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4720 Exts, Truncs, TLI,
false);
4725 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4726 InstrToOrigTy &PromotedInsts,
4727 unsigned &CreatedInstsCost,
4728 SmallVectorImpl<Instruction *> *Exts,
4729 SmallVectorImpl<Instruction *> *Truncs,
4730 const TargetLowering &TLI);
4741 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4742 const TargetLowering &TLI,
4743 const InstrToOrigTy &PromotedInsts);
4748bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4749 Type *ConsideredExtType,
4750 const InstrToOrigTy &PromotedInsts,
4770 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4771 (IsSExt && BinOp->hasNoSignedWrap())))
4775 if ((Inst->
getOpcode() == Instruction::And ||
4780 if (Inst->
getOpcode() == Instruction::Xor) {
4783 if (!Cst->getValue().isAllOnes())
4792 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4802 if (ExtInst->hasOneUse()) {
4804 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4837 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4850TypePromotionHelper::Action TypePromotionHelper::getAction(
4851 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4852 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
4854 "Unexpected instruction type");
4861 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4874 return promoteOperandForTruncAndAnyExt;
4880 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4883Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4884 Instruction *SExt, TypePromotionTransaction &TPT,
4885 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4886 SmallVectorImpl<Instruction *> *Exts,
4887 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4891 Value *ExtVal = SExt;
4892 bool HasMergedNonFreeExt =
false;
4896 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
4899 TPT.replaceAllUsesWith(SExt, ZExt);
4900 TPT.eraseInstruction(SExt);
4905 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
4907 CreatedInstsCost = 0;
4911 TPT.eraseInstruction(SExtOpnd);
4919 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
4927 TPT.eraseInstruction(ExtInst, NextVal);
4931Value *TypePromotionHelper::promoteOperandForOther(
4932 Instruction *Ext, TypePromotionTransaction &TPT,
4933 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4934 SmallVectorImpl<Instruction *> *Exts,
4935 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
4940 CreatedInstsCost = 0;
4946 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
4949 ITrunc->moveAfter(ExtOpnd);
4954 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
4957 TPT.setOperand(Ext, 0, ExtOpnd);
4967 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
4969 TPT.mutateType(ExtOpnd, Ext->
getType());
4971 TPT.replaceAllUsesWith(Ext, ExtOpnd);
4974 for (
int OpIdx = 0, EndOpIdx = ExtOpnd->
getNumOperands(); OpIdx != EndOpIdx;
4978 !shouldExtOperand(ExtOpnd, OpIdx)) {
4987 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
4989 TPT.setOperand(ExtOpnd, OpIdx, ConstantInt::get(Ext->
getType(), CstVal));
5000 Value *ValForExtOpnd = IsSExt
5001 ? TPT.createSExt(ExtOpnd, Opnd, Ext->
getType())
5002 : TPT.createZExt(ExtOpnd, Opnd, Ext->
getType());
5003 TPT.setOperand(ExtOpnd, OpIdx, ValForExtOpnd);
5005 if (!InstForExtOpnd)
5011 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5014 TPT.eraseInstruction(Ext);
5026bool AddressingModeMatcher::isPromotionProfitable(
5027 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5028 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5033 if (NewCost > OldCost)
5035 if (NewCost < OldCost)
5054bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5066 case Instruction::PtrToInt:
5069 case Instruction::IntToPtr: {
5077 case Instruction::BitCast:
5087 case Instruction::AddrSpaceCast: {
5095 case Instruction::Add: {
5098 ExtAddrMode BackupAddrMode =
AddrMode;
5099 unsigned OldSize = AddrModeInsts.
size();
5104 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5105 TPT.getRestorationPoint();
5109 int First = 0, Second = 1;
5120 AddrModeInsts.
resize(OldSize);
5121 TPT.rollback(LastKnownGood);
5131 AddrModeInsts.
resize(OldSize);
5132 TPT.rollback(LastKnownGood);
5138 case Instruction::Mul:
5139 case Instruction::Shl: {
5143 if (!
RHS ||
RHS->getBitWidth() > 64)
5145 int64_t Scale = Opcode == Instruction::Shl
5146 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5147 :
RHS->getSExtValue();
5151 case Instruction::GetElementPtr: {
5154 int VariableOperand = -1;
5155 unsigned VariableScale = 0;
5157 int64_t ConstantOffset = 0;
5159 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5161 const StructLayout *SL =
DL.getStructLayout(STy);
5172 if (ConstantInt *CI =
5174 const APInt &CVal = CI->
getValue();
5181 if (VariableOperand != -1)
5185 VariableOperand = i;
5186 VariableScale = TypeSize;
5193 if (VariableOperand == -1) {
5194 AddrMode.BaseOffs += ConstantOffset;
5200 AddrMode.BaseOffs -= ConstantOffset;
5204 ConstantOffset > 0) {
5218 BaseI ? BaseI->getParent() : &
GEP->getFunction()->getEntryBlock();
5220 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5228 ExtAddrMode BackupAddrMode =
AddrMode;
5229 unsigned OldSize = AddrModeInsts.
size();
5232 AddrMode.BaseOffs += ConstantOffset;
5241 AddrModeInsts.
resize(OldSize);
5249 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5254 AddrModeInsts.
resize(OldSize);
5259 AddrMode.BaseOffs += ConstantOffset;
5260 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5261 VariableScale,
Depth)) {
5264 AddrModeInsts.
resize(OldSize);
5271 case Instruction::SExt:
5272 case Instruction::ZExt: {
5279 TypePromotionHelper::Action TPH =
5280 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5284 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5285 TPT.getRestorationPoint();
5286 unsigned CreatedInstsCost = 0;
5288 Value *PromotedOperand =
5289 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5304 assert(PromotedOperand &&
5305 "TypePromotionHelper should have filtered out those cases");
5307 ExtAddrMode BackupAddrMode =
AddrMode;
5308 unsigned OldSize = AddrModeInsts.
size();
5310 if (!matchAddr(PromotedOperand,
Depth) ||
5315 !isPromotionProfitable(CreatedInstsCost,
5316 ExtCost + (AddrModeInsts.
size() - OldSize),
5319 AddrModeInsts.
resize(OldSize);
5320 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5321 TPT.rollback(LastKnownGood);
5326 AddrMode.replaceWith(Ext, PromotedOperand);
5329 case Instruction::Call:
5331 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5347bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5350 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5351 TPT.getRestorationPoint();
5375 ExtAddrMode BackupAddrMode =
AddrMode;
5376 unsigned OldSize = AddrModeInsts.
size();
5379 bool MovedAway =
false;
5380 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5388 if (
I->hasOneUse() ||
5389 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5396 AddrModeInsts.
resize(OldSize);
5397 TPT.rollback(LastKnownGood);
5400 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5402 TPT.rollback(LastKnownGood);
5429 TPT.rollback(LastKnownGood);
5448 if (OpInfo.CallOperandVal == OpVal &&
5450 !OpInfo.isIndirect))
5466 if (!ConsideredInsts.
insert(
I).second)
5474 for (
Use &U :
I->uses()) {
5477 if (SeenInsts++ >= MaxUsersToScan)
5482 MemoryUses.push_back({&U, LI->getType()});
5489 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5496 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5503 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5513 if (!
find(PtrOps, U.get()))
5516 MemoryUses.push_back({&U, AccessTy});
5521 if (CI->hasFnAttr(Attribute::Cold)) {
5539 PSI, BFI, SeenInsts, MaxUsersToScan))
5550 unsigned SeenInsts = 0;
5553 PSI, BFI, SeenInsts, MaxUsersToScan);
5560bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5562 Value *KnownLive2) {
5564 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5605bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5606 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5607 if (IgnoreProfitability)
5625 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5626 ScaledReg =
nullptr;
5630 if (!BaseReg && !ScaledReg)
5639 Opts.cgp_max_address_users_to_scan))
5652 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5655 Type *AddressAccessTy = Pair.second;
5656 unsigned AS =
Address->getType()->getPointerAddressSpace();
5662 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5664 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5665 TPT.getRestorationPoint();
5666 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5667 AddressAccessTy, AS, UserI, Result,
5668 InsertedInsts, PromotedInsts, TPT,
5669 LargeOffsetGEP, OptSize, PSI, BFI, Opts);
5670 Matcher.IgnoreProfitability =
true;
5678 TPT.rollback(LastKnownGood);
5684 MatchedAddrModeInsts.
clear();
5694 return I->getParent() != BB;
5710 return std::next(AddrInst->getIterator());
5721 Earliest = UserInst;
5746bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5747 Type *AccessTy,
unsigned AddrSpace) {
5752 SmallVector<Value *, 8> worklist;
5753 SmallPtrSet<Value *, 16> Visited;
5759 bool PhiOrSelectSeen =
false;
5760 SmallVector<Instruction *, 16> AddrModeInsts;
5761 AddressingModeCombiner AddrModes(*
DL, Opts, Addr);
5762 TypePromotionTransaction TPT(RemovedInsts);
5763 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5764 TPT.getRestorationPoint();
5765 while (!worklist.
empty()) {
5777 if (!Visited.
insert(V).second)
5783 PhiOrSelectSeen =
true;
5790 PhiOrSelectSeen =
true;
5797 AddrModeInsts.
clear();
5798 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5803 auto getDTFn = [
this]() ->
const DominatorTree & {
return getDT(); };
5804 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5805 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5806 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5809 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5814 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5815 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5818 NewAddrMode.OriginalValue =
V;
5819 if (!AddrModes.addNewAddrMode(NewAddrMode))
5826 if (!AddrModes.combineAddrModes()) {
5827 TPT.rollback(LastKnownGood);
5833 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5839 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5853 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
5875 <<
" for " << *MemoryInst <<
"\n");
5879 !
DL->isNonIntegralPointerType(Addr->
getType())) {
5885 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
5887 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
5889 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
5891 }
else if (
valueOr(Opts.cgp_addr_sink_using_gep,
true) ||
5892 (Opts.cgp_addr_sink_using_gep == BoolOrDefault::Default &&
5897 <<
" for " << *MemoryInst <<
"\n");
5898 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
5909 if (ResultPtr ||
AddrMode.Scale != 1)
5930 GlobalValue *BaseGV =
AddrMode.BaseGV;
5931 if (BaseGV !=
nullptr) {
5936 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
5945 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
5946 if (!ResultPtr &&
AddrMode.BaseReg) {
5950 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
5951 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
5960 }
else if (!ResultPtr) {
5974 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
5987 "We can't transform if ScaledReg is too narrow");
5988 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
5992 V = Builder.CreateMul(
5995 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6006 if (ResultPtr->
getType() != I8PtrTy)
6007 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6008 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6021 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6023 SunkAddr = ResultPtr;
6025 if (ResultPtr->
getType() != I8PtrTy)
6026 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6027 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6034 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6040 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
6042 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6044 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6054 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6055 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6056 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6058 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6062 <<
" for " << *MemoryInst <<
"\n");
6073 if (
V->getType()->isPointerTy())
6074 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6076 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
6085 }
else if (
V->getType()->isPointerTy()) {
6086 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6089 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
6098 I->eraseFromParent();
6102 V = Builder.CreateMul(
6105 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6111 GlobalValue *BaseGV =
AddrMode.BaseGV;
6112 if (BaseGV !=
nullptr) {
6115 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6119 Value *
V = Builder.CreatePtrToInt(BaseGVPtr,
IntPtrTy,
"sunkaddr");
6121 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6130 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6138 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6144 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6149 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6150 RecursivelyDeleteTriviallyDeadInstructions(
6151 Repl, TLInfo, nullptr,
6152 [&](Value *V) { removeAllAssertingVHReferences(V); });
6176bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6182 if (!
GEP->hasIndices())
6190 SmallVector<Value *, 2>
Ops(
GEP->operands());
6192 bool RewriteGEP =
false;
6201 unsigned FinalIndex =
Ops.size() - 1;
6206 for (
unsigned i = 1; i < FinalIndex; ++i) {
6211 C =
C->getSplatValue();
6213 if (!CI || !CI->
isZero())
6220 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6224 if (!
C || !
C->isZero()) {
6225 Ops[FinalIndex] =
V;
6233 if (!RewriteGEP &&
Ops.size() == 2)
6240 Type *SourceTy =
GEP->getSourceElementType();
6241 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6245 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6246 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6247 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6257 if (
Ops.size() != 2) {
6267 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6281 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6282 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6285 Intrinsic::masked_gather) {
6289 Intrinsic::masked_scatter);
6304 Ptr, TLInfo,
nullptr,
6305 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6316 if (
I->hasNUsesOrMore(3))
6319 for (
User *U :
I->users()) {
6321 if (!Extract || Extract->getNumIndices() != 1)
6324 unsigned Index = Extract->getIndices()[0];
6326 MulExtract = Extract;
6327 else if (Index == 1)
6328 OverflowExtract = Extract;
6355bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
6356 ModifyDT &ModifiedDT) {
6363 ExtractValueInst *MulExtract =
nullptr, *OverflowExtract =
nullptr;
6368 InsertedInsts.insert(
I);
6379 OverflowEntryBB->
takeName(
I->getParent());
6385 NoOverflowBB->
moveAfter(OverflowEntryBB);
6393 Value *LoLHS = Builder.CreateTrunc(
LHS, LegalTy,
"lo.lhs");
6394 Value *HiLHS = Builder.CreateLShr(
LHS, VTHalfBitWidth,
"lhs.lsr");
6395 HiLHS = Builder.CreateTrunc(HiLHS, LegalTy,
"hi.lhs");
6398 Value *LoRHS = Builder.CreateTrunc(
RHS, LegalTy,
"lo.rhs");
6399 Value *HiRHS = Builder.CreateLShr(
RHS, VTHalfBitWidth,
"rhs.lsr");
6400 HiRHS = Builder.CreateTrunc(HiRHS, LegalTy,
"hi.rhs");
6402 Value *IsAnyBitTrue;
6405 Builder.CreateAShr(LoLHS, VTHalfBitWidth - 1,
"sign.lo.lhs");
6407 Builder.CreateAShr(LoRHS, VTHalfBitWidth - 1,
"sign.lo.rhs");
6408 Value *XorLHS = Builder.CreateXor(HiLHS, SignLoLHS);
6409 Value *XorRHS = Builder.CreateXor(HiRHS, SignLoRHS);
6410 Value *
Or = Builder.CreateOr(XorLHS, XorRHS,
"or.lhs.rhs");
6411 IsAnyBitTrue = Builder.CreateCmp(ICmpInst::ICMP_NE,
Or,
6412 ConstantInt::getNullValue(
Or->getType()));
6414 Value *CmpLHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiLHS,
6415 ConstantInt::getNullValue(LegalTy));
6416 Value *CmpRHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiRHS,
6417 ConstantInt::getNullValue(LegalTy));
6418 IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS,
"or.lhs.rhs");
6420 Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
6423 Builder.SetInsertPoint(NoOverflowBB);
6424 Value *ExtLoLHS, *ExtLoRHS;
6426 ExtLoLHS = Builder.CreateSExt(LoLHS, Ty,
"lo.lhs.ext");
6427 ExtLoRHS = Builder.CreateSExt(LoRHS, Ty,
"lo.rhs.ext");
6429 ExtLoLHS = Builder.CreateZExt(LoLHS, Ty,
"lo.lhs.ext");
6430 ExtLoRHS = Builder.CreateZExt(LoRHS, Ty,
"lo.rhs.ext");
6433 Value *
Mul = Builder.CreateMul(ExtLoLHS, ExtLoRHS,
"mul.overflow.no");
6438 OverflowResBB->
setName(
"overflow.res");
6441 Builder.CreateBr(OverflowResBB);
6449 PHINode *OverflowResPHI = Builder.CreatePHI(Ty, 2),
6451 Builder.CreatePHI(IntegerType::getInt1Ty(
I->getContext()), 2);
6463 if (OverflowExtract) {
6464 OverflowExtract->replaceAllUsesWith(OverflowFlagPHI);
6465 OverflowExtract->eraseFromParent();
6470 I->removeFromParent();
6472 I->insertInto(OverflowBB, OverflowBB->
end());
6473 Builder.SetInsertPoint(OverflowBB->
end());
6475 Value *OverflowFlag = Builder.CreateExtractValue(
I, {1},
"overflow.flag");
6476 Builder.CreateBr(OverflowResBB);
6480 OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
6482 DTU->
applyUpdates({{DominatorTree::Insert, OverflowEntryBB, OverflowBB},
6483 {DominatorTree::Insert, OverflowEntryBB, NoOverflowBB},
6484 {DominatorTree::Insert, NoOverflowBB, OverflowResBB},
6485 {DominatorTree::Delete, OverflowEntryBB, OverflowResBB},
6486 {DominatorTree::Insert, OverflowBB, OverflowResBB}});
6488 ModifiedDT = ModifyDT::ModifyBBDT;
6494bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6495 bool MadeChange =
false;
6497 const TargetRegisterInfo *
TRI =
6502 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6508 OpInfo.isIndirect) {
6510 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6573bool CodeGenPrepare::tryToPromoteExts(
6574 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6575 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6576 unsigned CreatedInstsCost) {
6577 bool Promoted =
false;
6580 for (
auto *
I : Exts) {
6595 TypePromotionHelper::Action TPH =
6596 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6605 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6606 TPT.getRestorationPoint();
6607 SmallVector<Instruction *, 4> NewExts;
6608 unsigned NewCreatedInstsCost = 0;
6611 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6612 &NewExts,
nullptr, *TLI);
6614 "TypePromotionHelper should have filtered out those cases");
6624 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6627 TotalCreatedInstsCost =
6628 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6629 if (!Opts.cgp_stress_ext_ld_promotion &&
6630 (TotalCreatedInstsCost > 1 ||
6632 (ExtCost == 0 && NewExts.
size() > 1))) {
6636 TPT.rollback(LastKnownGood);
6641 SmallVector<Instruction *, 2> NewlyMovedExts;
6642 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6643 bool NewPromoted =
false;
6644 for (
auto *ExtInst : NewlyMovedExts) {
6650 !(Opts.cgp_stress_ext_ld_promotion ||
6651 NewCreatedInstsCost <= ExtCost ||
6655 ProfitablyMovedExts.
push_back(MovedExt);
6662 TPT.rollback(LastKnownGood);
6673bool CodeGenPrepare::mergeSExts(
Function &
F) {
6675 for (
auto &Entry : ValToSExtendedUses) {
6676 SExts &Insts =
Entry.second;
6678 for (Instruction *Inst : Insts) {
6682 bool inserted =
false;
6683 for (
auto &Pt : CurPts) {
6686 RemovedInsts.insert(Pt);
6687 Pt->removeFromParent();
6698 RemovedInsts.insert(Inst);
6705 CurPts.push_back(Inst);
6747bool CodeGenPrepare::splitLargeGEPOffsets() {
6749 for (
auto &Entry : LargeOffsetGEPMap) {
6751 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6752 &LargeOffsetGEPs =
Entry.second;
6753 auto compareGEPOffset =
6754 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6755 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6756 if (
LHS.first ==
RHS.first)
6758 if (
LHS.second !=
RHS.second)
6759 return LHS.second <
RHS.second;
6760 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6763 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6766 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6768 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6769 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6770 Value *NewBaseGEP =
nullptr;
6772 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6773 GetElementPtrInst *
GEP) {
6774 LLVMContext &Ctx =
GEP->getContext();
6775 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6777 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6789 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), &getDT(), LI);
6792 NewBaseInsertPt = std::next(BaseI->getIterator());
6805 NewBaseGEP = OldBase;
6806 if (NewBaseGEP->
getType() != I8PtrTy)
6807 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6809 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6810 NewGEPBases.
insert(NewBaseGEP);
6816 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6817 BaseOffset = PreferBase;
6820 createNewBase(BaseOffset, OldBase, BaseGEP);
6823 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6824 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6825 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6826 int64_t
Offset = LargeOffsetGEP->second;
6827 if (
Offset != BaseOffset) {
6834 GEP->getResultElementType(),
6835 GEP->getAddressSpace())) {
6841 NewBaseGEP =
nullptr;
6846 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6851 createNewBase(BaseOffset, OldBase,
GEP);
6855 Value *NewGEP = NewBaseGEP;
6856 if (
Offset != BaseOffset) {
6859 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6863 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6864 GEP->eraseFromParent();
6871bool CodeGenPrepare::optimizePhiType(
6872 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
6873 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
6878 Type *PhiTy =
I->getType();
6879 Type *ConvertTy =
nullptr;
6881 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6884 SmallVector<Instruction *, 4> Worklist;
6886 SmallPtrSet<PHINode *, 4> PhiNodes;
6887 SmallPtrSet<ConstantData *, 4>
Constants;
6890 SmallPtrSet<Instruction *, 4> Defs;
6891 SmallPtrSet<Instruction *, 4>
Uses;
6897 bool AnyAnchored =
false;
6899 while (!Worklist.
empty()) {
6904 for (
Value *V :
Phi->incoming_values()) {
6906 if (!PhiNodes.
count(OpPhi)) {
6907 if (!Visited.
insert(OpPhi).second)
6913 if (!OpLoad->isSimple())
6915 if (Defs.
insert(OpLoad).second)
6918 if (Defs.
insert(OpEx).second)
6922 ConvertTy = OpBC->getOperand(0)->getType();
6923 if (OpBC->getOperand(0)->getType() != ConvertTy)
6925 if (Defs.
insert(OpBC).second) {
6938 for (User *V :
II->users()) {
6940 if (!PhiNodes.
count(OpPhi)) {
6941 if (Visited.
count(OpPhi))
6948 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
6950 Uses.insert(OpStore);
6953 ConvertTy = OpBC->getType();
6954 if (OpBC->getType() != ConvertTy)
6958 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
6965 if (!ConvertTy || !AnyAnchored || PhiTy == ConvertTy ||
6969 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
6970 << *ConvertTy <<
"\n");
6975 for (ConstantData *
C : Constants)
6977 for (Instruction *
D : Defs) {
6979 ValMap[
D] =
D->getOperand(0);
6983 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
6986 for (PHINode *Phi : PhiNodes)
6988 Phi->getName() +
".tc",
Phi->getIterator());
6990 for (PHINode *Phi : PhiNodes) {
6992 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
6994 Phi->getIncomingBlock(i));
6998 for (Instruction *U :
Uses) {
7003 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
7013bool CodeGenPrepare::optimizePhiTypes(
Function &
F) {
7014 if (!Opts.cgp_optimize_phi_types)
7018 SmallPtrSet<PHINode *, 4> Visited;
7019 SmallPtrSet<Instruction *, 4> DeletedInstrs;
7023 for (
auto &Phi : BB.
phis())
7024 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
7027 for (
auto *
I : DeletedInstrs) {
7029 I->eraseFromParent();
7037bool CodeGenPrepare::canFormExtLd(
7038 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
7039 Instruction *&Inst,
bool HasPromoted) {
7040 for (
auto *MovedExtInst : MovedExts) {
7043 Inst = MovedExtInst;
7095bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7096 bool AllowPromotionWithoutCommonHeader =
false;
7101 *Inst, AllowPromotionWithoutCommonHeader);
7102 TypePromotionTransaction TPT(RemovedInsts);
7103 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7104 TPT.getRestorationPoint();
7106 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7109 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7112 LoadInst *LI =
nullptr;
7117 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7118 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7123 Inst = ExtFedByLoad;
7128 if (ATPConsiderable &&
7129 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7130 HasPromoted, TPT, SpeculativelyMovedExts))
7133 TPT.rollback(LastKnownGood);
7142bool CodeGenPrepare::performAddressTypePromotion(
7143 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7144 bool HasPromoted, TypePromotionTransaction &TPT,
7145 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7146 bool Promoted =
false;
7147 SmallPtrSet<Instruction *, 1> UnhandledExts;
7148 bool AllSeenFirst =
true;
7149 for (
auto *
I : SpeculativelyMovedExts) {
7150 Value *HeadOfChain =
I->getOperand(0);
7151 auto AlreadySeen = SeenChainsForSExt.
find(HeadOfChain);
7154 if (AlreadySeen != SeenChainsForSExt.
end()) {
7155 if (AlreadySeen->second !=
nullptr)
7156 UnhandledExts.
insert(AlreadySeen->second);
7157 AllSeenFirst =
false;
7161 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7162 SpeculativelyMovedExts.size() == 1)) {
7166 for (
auto *
I : SpeculativelyMovedExts) {
7167 Value *HeadOfChain =
I->getOperand(0);
7168 SeenChainsForSExt[HeadOfChain] =
nullptr;
7169 ValToSExtendedUses[HeadOfChain].push_back(
I);
7172 Inst = SpeculativelyMovedExts.pop_back_val();
7177 for (
auto *
I : SpeculativelyMovedExts) {
7178 Value *HeadOfChain =
I->getOperand(0);
7179 SeenChainsForSExt[HeadOfChain] = Inst;
7184 if (!AllSeenFirst && !UnhandledExts.
empty())
7185 for (
auto *VisitedSExt : UnhandledExts) {
7186 if (RemovedInsts.count(VisitedSExt))
7188 TypePromotionTransaction TPT(RemovedInsts);
7190 SmallVector<Instruction *, 2> Chains;
7192 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7196 for (
auto *
I : Chains) {
7197 Value *HeadOfChain =
I->getOperand(0);
7199 SeenChainsForSExt[HeadOfChain] =
nullptr;
7200 ValToSExtendedUses[HeadOfChain].push_back(
I);
7206bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7211 Value *Src =
I->getOperand(0);
7212 if (Src->hasOneUse())
7224 bool DefIsLiveOut =
false;
7225 for (User *U :
I->users()) {
7230 if (UserBB == DefBB)
7232 DefIsLiveOut =
true;
7239 for (User *U : Src->users()) {
7242 if (UserBB == DefBB)
7251 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7253 bool MadeChange =
false;
7259 if (UserBB == DefBB)
7263 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7265 if (!InsertedTrunc) {
7268 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7270 InsertedInsts.insert(InsertedTrunc);
7333bool CodeGenPrepare::optimizeLoadExt(LoadInst *
Load) {
7334 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7338 if (
Load->hasOneUse() &&
7344 SmallVector<Instruction *, 8> WorkList;
7345 SmallPtrSet<Instruction *, 16> Visited;
7346 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7347 SmallVector<Instruction *, 8> DropFlags;
7348 for (
auto *U :
Load->users())
7360 while (!WorkList.
empty()) {
7364 if (!Visited.
insert(
I).second)
7369 for (
auto *U :
Phi->users())
7374 switch (
I->getOpcode()) {
7375 case Instruction::And: {
7379 APInt AndBits = AndC->getValue();
7380 DemandBits |= AndBits;
7382 if (AndBits.
ugt(WidestAndBits))
7383 WidestAndBits = AndBits;
7384 if (AndBits == WidestAndBits &&
I->getOperand(0) ==
Load)
7389 case Instruction::Shl: {
7394 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7399 case Instruction::Trunc: {
7402 DemandBits.setLowBits(TruncBitWidth);
7412 uint32_t ActiveBits = DemandBits.getActiveBits();
7424 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7425 WidestAndBits != DemandBits)
7428 LLVMContext &Ctx =
Load->getType()->getContext();
7429 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7440 Builder.CreateAnd(
Load, ConstantInt::get(Ctx, DemandBits)));
7443 InsertedInsts.insert(NewAnd);
7448 NewAnd->setOperand(0,
Load);
7451 for (
auto *
And : AndsToMaybeRemove)
7456 if (&*CurInstIterator ==
And)
7457 CurInstIterator = std::next(
And->getIterator());
7458 And->eraseFromParent();
7463 for (
auto *Inst : DropFlags)
7477 TTI->isExpensiveToSpeculativelyExecute(
I);
7495 uint64_t Max = std::max(TrueWeight, FalseWeight);
7496 uint64_t Sum = TrueWeight + FalseWeight;
7499 if (Probability >
TTI->getPredictableBranchThreshold())
7509 if (!Cmp || !Cmp->hasOneUse())
7532 assert(DefSI->getCondition() ==
SI->getCondition() &&
7533 "The condition of DefSI does not match with SI");
7534 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7537 assert(V &&
"Failed to get select true/false value");
7541bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7565 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7566 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7567 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7568 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7574bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7576 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7577 "Expected a funnel shift");
7601 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7602 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7603 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7611bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7612 if (!Opts.cgp_select2branch)
7623 It !=
SI->getParent()->
end(); ++It) {
7625 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7632 SelectInst *LastSI = ASI.
back();
7635 CurInstIterator = std::next(LastSI->
getIterator());
7639 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7640 fixupDbgVariableRecordsOnInst(*SI);
7642 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7645 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7648 TargetLowering::SelectSupportKind SelectKind;
7649 if (
SI->getType()->isVectorTy())
7650 SelectKind = TargetLowering::ScalarCondVectorVal;
7652 SelectKind = TargetLowering::ScalarValSelect;
7689 SmallVector<Instruction *> TrueInstrs, FalseInstrs;
7690 for (SelectInst *SI : ASI) {
7702 SplitPt.setHeadBit(
true);
7705 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7710 UncondBrInst *TrueBranch =
nullptr;
7711 UncondBrInst *FalseBranch =
nullptr;
7712 if (TrueInstrs.
size() == 0) {
7717 }
else if (FalseInstrs.
size() == 0) {
7734 EndBlock->
setName(
"select.end");
7736 TrueBlock->
setName(
"select.true.sink");
7738 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7739 :
"select.false.sink");
7743 FreshBBs.
insert(TrueBlock);
7745 FreshBBs.
insert(FalseBlock);
7746 FreshBBs.
insert(EndBlock);
7751 static const unsigned MD[] = {
7752 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7753 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7758 for (Instruction *
I : TrueInstrs)
7760 for (Instruction *
I : FalseInstrs)
7767 if (TrueBlock ==
nullptr)
7768 TrueBlock = StartBlock;
7769 else if (FalseBlock ==
nullptr)
7770 FalseBlock = StartBlock;
7786 SI->eraseFromParent();
7788 ++NumSelectsExpanded;
7792 CurInstIterator = StartBlock->
end();
7799bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7811 "Expected a type of the same size!");
7817 Value *BC1 = Builder.CreateBitCast(
7819 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7820 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7824 SVI, TLInfo,
nullptr,
7825 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7832 !
Op->isTerminator() && !
Op->isEHPad())
7838bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7853 for (Use *U :
reverse(OpsToSink)) {
7865 SetVector<Instruction *> MaybeDead;
7866 DenseMap<Instruction *, Instruction *> NewInstructions;
7867 for (Use *U : ToReplace) {
7876 FreshBBs.
insert(OpDef->getParent());
7879 NewInstructions[UI] = NI;
7884 InsertedInsts.insert(NI);
7890 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
7891 It->second->setOperand(
U->getOperandNo(), NI);
7898 for (
auto *
I : MaybeDead) {
7899 if (!
I->hasNUsesOrMore(1)) {
7901 I->eraseFromParent();
7908bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
7914 unsigned RegWidth =
RegType.getSizeInBits();
7925 auto *NewType = Type::getIntNTy(
Context, RegWidth);
7934 ExtType = Instruction::SExt;
7937 if (Arg->hasSExtAttr())
7938 ExtType = Instruction::SExt;
7939 if (Arg->hasZExtAttr())
7940 ExtType = Instruction::ZExt;
7946 SI->setCondition(ExtInst);
7947 for (
auto Case :
SI->cases()) {
7948 const APInt &NarrowConst = Case.getCaseValue()->getValue();
7949 APInt WideConst = (ExtType == Instruction::ZExt)
7950 ? NarrowConst.
zext(RegWidth)
7951 : NarrowConst.
sext(RegWidth);
7952 Case.setValue(ConstantInt::get(
Context, WideConst));
7958bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
7965 Value *Condition =
SI->getCondition();
7974 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
7975 ConstantInt *CaseValue = Case.getCaseValue();
7976 BasicBlock *CaseBB = Case.getCaseSuccessor();
7979 bool CheckedForSinglePred =
false;
7980 for (PHINode &
PHI : CaseBB->
phis()) {
7981 Type *PHIType =
PHI.getType();
7989 if (PHIType == ConditionType || TryZExt) {
7991 bool SkipCase =
false;
7992 Value *Replacement =
nullptr;
7993 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
7994 Value *PHIValue =
PHI.getIncomingValue(
I);
7995 if (PHIValue != CaseValue) {
8004 if (
PHI.getIncomingBlock(
I) != SwitchBB)
8009 if (!CheckedForSinglePred) {
8010 CheckedForSinglePred =
true;
8011 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
8017 if (Replacement ==
nullptr) {
8018 if (PHIValue == CaseValue) {
8019 Replacement = Condition;
8022 Replacement = Builder.CreateZExt(Condition, PHIType);
8025 PHI.setIncomingValue(
I, Replacement);
8036bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
8037 bool Changed = optimizeSwitchType(SI);
8038 Changed |= optimizeSwitchPhiConstants(SI);
8059class VectorPromoteHelper {
8061 const DataLayout &
DL;
8064 const TargetLowering &TLI;
8067 const TargetTransformInfo &
TTI;
8073 SmallVector<Instruction *, 4> InstsToBePromoted;
8076 unsigned StoreExtractCombineCost;
8078 bool StressStoreExtract;
8087 if (InstsToBePromoted.
empty())
8089 return InstsToBePromoted.
back();
8095 unsigned getTransitionOriginalValueIdx()
const {
8097 "Other kind of transitions are not supported yet");
8104 unsigned getTransitionIdx()
const {
8106 "Other kind of transitions are not supported yet");
8114 Type *getTransitionType()
const {
8125 void promoteImpl(Instruction *ToBePromoted);
8129 bool isProfitableToPromote() {
8130 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8134 Type *PromotedType = getTransitionType();
8137 unsigned AS =
ST->getPointerAddressSpace();
8155 for (
const auto &Inst : InstsToBePromoted) {
8163 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8175 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8176 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8177 return ScalarCost > VectorCost;
8189 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8204 if (!
EC.isScalable()) {
8205 SmallVector<Constant *, 4> ConstVec;
8207 for (
unsigned Idx = 0;
Idx !=
EC.getKnownMinValue(); ++
Idx) {
8208 if (Idx == ExtractIdx)
8216 "Generate scalable vector for non-splat is unimplemented");
8221 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8222 unsigned OperandIdx) {
8225 if (OperandIdx != 1)
8227 switch (
Use->getOpcode()) {
8230 case Instruction::SDiv:
8231 case Instruction::UDiv:
8232 case Instruction::SRem:
8233 case Instruction::URem:
8235 case Instruction::FDiv:
8236 case Instruction::FRem:
8237 return !
Use->hasNoNaNs();
8243 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8244 const TargetTransformInfo &
TTI, Instruction *Transition,
8245 unsigned CombineCost,
bool StressStoreExtract)
8246 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8247 StoreExtractCombineCost(CombineCost),
8248 StressStoreExtract(StressStoreExtract) {
8249 assert(Transition &&
"Do not know how to promote null");
8253 bool canPromote(
const Instruction *ToBePromoted)
const {
8260 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8265 for (
const Use &U : ToBePromoted->
operands()) {
8266 const Value *Val =
U.get();
8267 if (Val == getEndOfTransition()) {
8278 return StressStoreExtract ||
8289 void enqueueForPromotion(Instruction *ToBePromoted) {
8290 InstsToBePromoted.push_back(ToBePromoted);
8294 void recordCombineInstruction(Instruction *ToBeCombined) {
8296 CombineInst = ToBeCombined;
8306 if (InstsToBePromoted.empty() || !CombineInst)
8310 if (!StressStoreExtract && !isProfitableToPromote())
8314 for (
auto &ToBePromoted : InstsToBePromoted)
8315 promoteImpl(ToBePromoted);
8316 InstsToBePromoted.clear();
8323void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8333 "The type of the result of the transition does not match "
8338 Type *TransitionTy = getTransitionType();
8343 for (Use &U : ToBePromoted->
operands()) {
8345 Value *NewVal =
nullptr;
8346 if (Val == Transition)
8347 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8354 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8358 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8361 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8367bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8368 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8369 if (!Opts.cgp_store_extract ||
8370 (!Opts.cgp_stress_store_extract &&
8383 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8384 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost,
8385 Opts.cgp_stress_store_extract);
8392 if (ToBePromoted->
getParent() != Parent) {
8393 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8395 <<
") than the transition (" << Parent->
getName()
8400 if (VPH.canCombine(ToBePromoted)) {
8402 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8403 VPH.recordCombineInstruction(ToBePromoted);
8405 NumStoreExtractExposed +=
Changed;
8410 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8413 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8415 VPH.enqueueForPromotion(ToBePromoted);
8416 Inst = ToBePromoted;
8455 bool ForceSplitStore) {
8457 Type *StoreType =
SI.getValueOperand()->getType();
8466 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8467 DL.getTypeSizeInBits(StoreType) == 0)
8470 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8472 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8488 if (!
match(
SI.getValueOperand(),
8495 if (!
LValue->getType()->isIntegerTy() ||
8496 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8498 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8517 if (LBC && LBC->getParent() !=
SI.getParent())
8518 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8519 if (HBC && HBC->getParent() !=
SI.getParent())
8520 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8522 bool IsLE =
SI.getDataLayout().isLittleEndian();
8523 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8524 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8525 Value *Addr =
SI.getPointerOperand();
8526 Align Alignment =
SI.getAlign();
8527 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8528 if (IsOffsetStore) {
8529 Addr = Builder.CreateGEP(
8530 SplitStoreType, Addr,
8538 Builder.CreateAlignedStore(V, Addr, Alignment);
8541 CreateSplitStore(
LValue,
false);
8542 CreateSplitStore(HValue,
true);
8545 SI.eraseFromParent();
8553 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8635 if (GEPIOpI->getParent() != SrcBlock)
8640 if (auto *I = dyn_cast<Instruction>(Usr)) {
8641 if (I->getParent() != SrcBlock) {
8649 std::vector<GetElementPtrInst *> UGEPIs;
8652 for (User *Usr : GEPIOp->
users()) {
8671 if (UGEPI->getOperand(0) != GEPIOp)
8673 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8675 if (GEPIIdx->getType() !=
8683 UGEPIs.push_back(UGEPI);
8685 if (UGEPIs.size() == 0)
8688 for (GetElementPtrInst *UGEPI : UGEPIs) {
8690 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8697 for (GetElementPtrInst *UGEPI : UGEPIs) {
8698 UGEPI->setOperand(0, GEPI);
8700 auto NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8701 Constant *NewUGEPIIdx = ConstantInt::get(GEPIIdx->getType(), NewIdx);
8702 UGEPI->setOperand(1, NewUGEPIIdx);
8704 auto SourceFlags = GEPI->getNoWrapFlags();
8707 UGEPI->getNoWrapFlags().intersectForOffsetAdd(SourceFlags);
8709 if (NewIdx.
isNegative() && TargetFlags.hasNoUnsignedWrap())
8710 TargetFlags = TargetFlags.withoutNoUnsignedWrap();
8711 UGEPI->setNoWrapFlags(TargetFlags);
8717 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8719 "GEPIOp is used outside SrcBlock");
8743 Value *
X = Cmp->getOperand(0);
8744 if (!
X->hasUseList())
8749 for (
auto *U :
X->users()) {
8753 (UI->
getParent() != Branch->getParent() &&
8754 UI->
getParent() != Branch->getSuccessor(0) &&
8755 UI->
getParent() != Branch->getSuccessor(1)) ||
8756 (UI->
getParent() != Branch->getParent() &&
8757 !UI->
getParent()->getSinglePredecessor()))
8763 if (UI->
getParent() != Branch->getParent())
8767 ConstantInt::get(UI->
getType(), 0));
8769 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8773 if (Cmp->isEquality() &&
8778 if (UI->
getParent() != Branch->getParent())
8781 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8782 ConstantInt::get(UI->
getType(), 0));
8784 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8792bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8793 bool AnyChange =
false;
8794 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8798 if (InsertedInsts.count(
I))
8807 LargeOffsetGEPMap.erase(
P);
8809 P->eraseFromParent();
8840 I, LI->getLoopFor(
I->getParent()), *
TTI))
8848 TargetLowering::TypeExpandInteger) {
8852 I, LI->getLoopFor(
I->getParent()), *
TTI))
8855 bool MadeChange = optimizeExt(
I);
8856 return MadeChange | optimizeExtUses(
I);
8863 if (optimizeCmp(Cmp, ModifiedDT))
8867 if (optimizeURem(
I))
8871 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8872 bool Modified = optimizeLoadExt(LI);
8881 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8882 unsigned AS =
SI->getPointerAddressSpace();
8883 return optimizeMemoryInst(
I,
SI->getOperand(1),
8884 SI->getOperand(0)->getType(), AS);
8888 unsigned AS = RMW->getPointerAddressSpace();
8889 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
8893 unsigned AS = CmpX->getPointerAddressSpace();
8894 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
8895 CmpX->getCompareOperand()->getType(), AS);
8900 if (BinOp && BinOp->
getOpcode() == Instruction::And &&
8901 Opts.cgp_andcmp_sinking &&
8906 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
8907 BinOp->
getOpcode() == Instruction::LShr)) {
8915 if (GEPI->hasAllZeroIndices()) {
8917 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
8918 GEPI->getName(), GEPI->getIterator());
8919 NC->setDebugLoc(GEPI->getDebugLoc());
8922 GEPI, TLInfo,
nullptr,
8923 [&](
Value *V) { removeAllAssertingVHReferences(V); });
8925 optimizeInst(
NC, ModifiedDT);
8943 if (Const0 || Const1) {
8944 if (!Const0 || !Const1) {
8945 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
8951 FI->eraseFromParent();
8958 if (tryToSinkFreeOperands(
I))
8961 switch (
I->getOpcode()) {
8962 case Instruction::Shl:
8963 case Instruction::LShr:
8964 case Instruction::AShr:
8966 case Instruction::Call:
8968 case Instruction::Select:
8970 case Instruction::ShuffleVector:
8972 case Instruction::Switch:
8974 case Instruction::ExtractElement:
8976 case Instruction::CondBr:
8985bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
8986 if (!
I.getType()->isIntegerTy() ||
8991 SmallVector<Instruction *, 4> Insts;
8997 &
I, TLInfo,
nullptr,
8998 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9005bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
9007 bool MadeChange =
false;
9010 CurInstIterator = BB.
begin();
9011 ModifiedDT = ModifyDT::NotModifyDT;
9012 while (CurInstIterator != BB.
end()) {
9013 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
9014 if (ModifiedDT != ModifyDT::NotModifyDT) {
9023 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
9025 bool MadeBitReverse =
true;
9026 while (MadeBitReverse) {
9027 MadeBitReverse =
false;
9029 if (makeBitReverse(
I)) {
9030 MadeBitReverse = MadeChange =
true;
9035 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
9040bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
9041 bool AnyChange =
false;
9042 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
9043 AnyChange |= fixupDbgVariableRecord(DVR);
9049bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
9050 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
9051 DVR.
Type != DbgVariableRecord::LocationType::Assign)
9055 bool AnyChange =
false;
9056 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
9058 for (
Value *Location : LocationOps) {
9059 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9088bool CodeGenPrepare::placeDbgValues(
Function &
F) {
9089 bool MadeChange =
false;
9090 DominatorTree &DT = getDT();
9092 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9093 SmallVector<Instruction *, 4> VIs;
9094 for (
Value *V : DbgItem->location_ops())
9102 for (Instruction *VI : VIs) {
9103 if (
VI->isTerminator())
9108 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9119 if (VIs.size() > 1) {
9122 <<
"Unable to find valid location for Debug Value, undefing:\n"
9124 DbgItem->setKillLocation();
9129 << *DbgItem <<
' ' << *VI);
9136 for (BasicBlock &BB :
F) {
9142 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9144 DbgProcessor(&DVR, &Insn);
9155bool CodeGenPrepare::placePseudoProbes(
Function &
F) {
9156 bool MadeChange =
false;
9159 auto FirstInst =
Block.getFirstInsertionPt();
9160 while (FirstInst !=
Block.end() && FirstInst->isDebugOrPseudoInst())
9164 while (
I !=
Block.end()) {
9166 II->moveBefore(FirstInst);
9196bool CodeGenPrepare::splitBranchCondition(
Function &
F) {
9200 bool MadeChange =
false;
9201 for (
auto &BB :
F) {
9214 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9222 Value *Cond1, *Cond2;
9225 Opc = Instruction::And;
9228 Opc = Instruction::Or;
9238 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9252 Br1->setCondition(Cond1);
9257 if (
Opc == Instruction::And)
9258 Br1->setSuccessor(0, TmpBB);
9260 Br1->setSuccessor(1, TmpBB);
9265 I->removeFromParent();
9266 I->insertBefore(Br2->getIterator());
9278 if (
Opc == Instruction::Or)
9282 TBB->replacePhiUsesWith(&BB, TmpBB);
9285 for (PHINode &PN : FBB->
phis()) {
9290 if (
Loop *L = LI->getLoopFor(&BB))
9291 L->addBasicBlockToLoop(TmpBB, *LI);
9295 DTU->
applyUpdates({{DominatorTree::Insert, &BB, TmpBB},
9296 {DominatorTree::Insert, TmpBB,
TBB},
9297 {DominatorTree::Insert, TmpBB, FBB},
9298 {DominatorTree::Delete, &BB,
TBB}});
9302 if (
Opc == Instruction::Or) {
9324 uint64_t NewTrueWeight = TrueWeight;
9325 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9329 NewTrueWeight = TrueWeight;
9330 NewFalseWeight = 2 * FalseWeight;
9355 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9356 uint64_t NewFalseWeight = FalseWeight;
9360 NewTrueWeight = 2 * TrueWeight;
9361 NewFalseWeight = FalseWeight;
static unsigned getIntrinsicID(const SDNode *N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
This file contains the simple types necessary to represent the attributes associated with functions a...
static const Function * getParent(const Value *V)
static GCRegistry::Add< 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 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 bool GEPSequentialConstIndexed(GetElementPtrInst *GEP)
static void DbgInserterHelper(DbgVariableRecord *DVR, BasicBlock::iterator VI)
static bool isPromotedInstructionLegal(const TargetLowering &TLI, const DataLayout &DL, Value *Val)
Check whether or not Val is a legal instruction for TLI.
static 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...
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
This file 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, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU)
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.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
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.
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 InstListType::const_iterator getFirstNonPHIOrDbg(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic,...
LLVM_ABI 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 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 bool isDebugOrPseudoInst() const LLVM_READONLY
Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
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.
Instruction * user_back()
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.
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.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
void clear()
Completely clear the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
VectorType * getType() const
Overload to return most specific vector type.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator erase(const_iterator CI)
typename SuperClass::iterator iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
static unsigned getPointerOperandIndex()
TypeSize getElementOffset(unsigned Idx) const
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
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 isEqualityCmpFoldedWithSignedCmp() const
Return true if instruction generated for equality comparison is folded with instruction generated for...
virtual bool shouldFormOverflowOp(unsigned Opcode, EVT VT, bool MathUsed) const
Try to convert math with an overflow comparison into the corresponding DAG node operation.
virtual bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const
Return if the target supports combining a chain like:
virtual bool shouldOptimizeMulOverflowWithZeroHighBits(LLVMContext &Context, EVT VT) const
bool isExtLoad(const LoadInst *Load, const Instruction *Ext, const DataLayout &DL) const
Return true if Load and Ext can form an ExtLoad.
virtual bool isSExtCheaperThanZExt(EVT FromTy, EVT ToTy) const
Return true if sign-extension from FromTy to ToTy is cheaper than zero-extension.
const TargetMachine & getTargetMachine() const
virtual bool isCtpopFast(EVT VT) const
Return true if ctpop instruction is fast.
virtual bool isFreeAddrSpaceCast(const DataLayout &DL, unsigned SrcAS, unsigned DestAS) const
Returns true if a cast from SrcAS to DestAS is "cheap", such that e.g.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
bool enableExtLdPromotion() const
Return true if the target wants to use the optimization that turns ext(promotableInst1(....
virtual unsigned getNumRegisters(LLVMContext &Context, EVT VT, std::optional< MVT > RegisterVT=std::nullopt) const
Return the number of registers that this ValueType will eventually require.
virtual bool isCheapToSpeculateCttz(Type *Ty) const
Return true if it is cheap to speculate a call to intrinsic cttz.
bool isJumpExpensive() const
Return true if Flow Control is an expensive operation that should be avoided.
bool hasExtractBitsInsn() const
Return true if the target has BitExtract instructions.
virtual bool allowsMisalignedMemoryAccesses(EVT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *=nullptr) const
Determine if the target supports unaligned memory accesses.
bool isSlowDivBypassed() const
Returns true if target has indicated at least one type should be bypassed.
virtual bool isTruncateFree(Type *FromTy, Type *ToTy) const
Return true if it's free to truncate a value of type FromTy to type ToTy.
virtual bool hasMultipleConditionRegisters(EVT VT) const
Does the target have multiple (allocatable) condition registers that can be used to store the results...
virtual EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
virtual MVT getPreferredSwitchConditionType(LLVMContext &Context, EVT ConditionVT) const
Returns preferred type for switch condition.
bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const
Return true if the specified condition code is legal for a comparison of the specified types on this ...
virtual bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx, unsigned &Cost) const
Return true if the target can combine store(extractelement VectorTy,Idx).
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual bool shouldConsiderGEPOffsetSplit() const
bool isExtFree(const Instruction *I) const
Return true if the extension represented by I is free.
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
bool isPredictableSelectExpensive() const
Return true if selects are only cheaper than branches if the branch is unlikely to be predicted right...
virtual bool isMultiStoresCheaperThanBitsMerge(EVT LTy, EVT HTy) const
Return true if it is cheaper to split the store of a merged int val from a pair of smaller values int...
virtual bool getAddrModeArguments(const IntrinsicInst *, SmallVectorImpl< Value * > &, Type *&) const
CodeGenPrepare sinks address calculations into the same BB as Load/Store instructions reading the add...
const DenseMap< unsigned int, unsigned int > & getBypassSlowDivWidths() const
Returns map of slow types for division or remainder with corresponding fast types.
virtual bool isCheapToSpeculateCtlz(Type *Ty) const
Return true if it is cheap to speculate a call to intrinsic ctlz.
virtual bool useSoftFloat() const
virtual int64_t getPreferredLargeGEPBaseOffset(int64_t MinOffset, int64_t MaxOffset) const
Return the prefered common base offset.
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
virtual bool shouldAlignPointerArgs(CallInst *, unsigned &, Align &) const
Return true if the pointer arguments to CI should be aligned by aligning the object whose address is ...
virtual Type * shouldConvertSplatType(ShuffleVectorInst *SVI) const
Given a shuffle vector SVI representing a vector splat, return a new scalar type of size equal to SVI...
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 isFAbsFree(EVT VT) const
Return true if an fabs operation is free to the point where it is never worthwhile to replace it with...
virtual bool preferZeroCompareBranch() const
Return true if the heuristic to prefer icmp eq zero should be used in code gen prepare.
virtual bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AddrSpace, Instruction *I=nullptr) const
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
virtual bool optimizeExtendOrTruncateConversion(Instruction *I, Loop *L, const TargetTransformInfo &TTI) const
Try to optimize extending or truncating conversion instructions (like zext, trunc,...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
std::vector< AsmOperandInfo > AsmOperandInfoVector
virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL, const TargetRegisterInfo *TRI, const CallBase &Call) const
Split up the constraint string from the inline assembly value into the specific constraints and their...
virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op, SelectionDAG *DAG=nullptr) const
Determines the constraint code and constraint type to use for the specific AsmOperandInfo,...
virtual bool mayBeEmittedAsTailCall(const CallInst *) const
Return true if the target may be able emit the call instruction as a tail call.
virtual bool isNoopAddrSpaceCast(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.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
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.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
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.
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.
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 CGPassBuilderOption getCGPassBuilderOption()
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.