47#include "llvm/Config/llvm-config.h"
70#include "llvm/IR/IntrinsicsAArch64.h"
114#define DEBUG_TYPE "codegenprepare"
117STATISTIC(NumPHIsElim,
"Number of trivial PHIs eliminated");
118STATISTIC(NumGEPsElim,
"Number of GEPs converted to casts");
119STATISTIC(NumCmpUses,
"Number of uses of Cmp expressions replaced with uses of "
121STATISTIC(NumCastUses,
"Number of uses of Cast expressions replaced with uses "
123STATISTIC(NumMemoryInsts,
"Number of memory instructions whose address "
124 "computations were sunk");
126 "Number of phis created when address "
127 "computations were sunk to memory instructions");
129 "Number of select created when address "
130 "computations were sunk to memory instructions");
131STATISTIC(NumExtsMoved,
"Number of [s|z]ext instructions combined with loads");
132STATISTIC(NumExtUses,
"Number of uses of [s|z]ext instructions optimized");
134 "Number of and mask instructions added to form ext loads");
135STATISTIC(NumAndUses,
"Number of uses of and mask instructions optimized");
136STATISTIC(NumRetsDup,
"Number of return instructions duplicated");
137STATISTIC(NumDbgValueMoved,
"Number of debug value instructions moved");
138STATISTIC(NumSelectsExpanded,
"Number of selects turned into branches");
139STATISTIC(NumStoreExtractExposed,
"Number of store(extractelement) exposed");
167class TypePromotionTransaction;
169class CodeGenPrepare {
170 friend class CodeGenPrepareLegacyPass;
171 const CodeGenOptions &Opts;
172 const TargetMachine *TM =
nullptr;
173 const TargetSubtargetInfo *SubtargetInfo =
nullptr;
174 const TargetLowering *TLI =
nullptr;
175 const TargetRegisterInfo *TRI =
nullptr;
176 const TargetTransformInfo *TTI =
nullptr;
177 const BasicBlockSectionsProfileReader *BBSectionsProfileReader =
nullptr;
178 const TargetLibraryInfo *TLInfo =
nullptr;
179 DomTreeUpdater *DTU =
nullptr;
180 LoopInfo *LI =
nullptr;
181 BlockFrequencyInfo *BFI;
182 BranchProbabilityInfo *BPI;
183 ProfileSummaryInfo *PSI =
nullptr;
194 ValueMap<Value *, WeakTrackingVH> SunkAddrs;
197 SetOfInstrs InsertedInsts;
201 InstrToOrigTy PromotedInsts;
204 SetOfInstrs RemovedInsts;
207 DenseMap<Value *, Instruction *> SeenChainsForSExt;
212 MapVector<AssertingVH<Value>,
217 SmallSet<AssertingVH<Value>, 2> NewGEPBases;
220 DenseMap<AssertingVH<GetElementPtrInst>,
int> LargeOffsetGEPID;
223 ValueToSExts ValToSExtendedUses;
229 const DataLayout *DL =
nullptr;
232 CodeGenPrepare(
const TargetMachine *TM)
233 : Opts(cl::LibraryOptionsContext::
get<CodeGenOptions>(
234 TM->
Options.MCOptions.LibraryOptions)),
237 bool IsHugeFunc =
false;
243 SmallPtrSet<BasicBlock *, 32> FreshBBs;
245 void releaseMemory() {
247 InsertedInsts.clear();
248 PromotedInsts.clear();
255 template <
typename F>
256 void resetIteratorIfInvalidatedWhileCalling(BasicBlock *BB,
F f) {
260 Value *CurValue = &*CurInstIterator;
261 WeakTrackingVH IterHandle(CurValue);
267 if (IterHandle != CurValue) {
268 CurInstIterator = BB->
begin();
274 DominatorTree &getDT() {
return DTU->getDomTree(); }
276 void removeAllAssertingVHReferences(
Value *V);
279 bool eliminateMostlyEmptyBlocks(
Function &
F,
bool &ResetLI);
280 BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB);
281 bool canMergeBlocks(
const BasicBlock *BB,
const BasicBlock *DestBB)
const;
282 bool eliminateMostlyEmptyBlock(BasicBlock *BB);
283 bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB,
285 bool makeBitReverse(Instruction &
I);
287 bool optimizeInst(Instruction *
I, ModifyDT &ModifiedDT);
288 bool optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
Type *AccessTy,
290 bool optimizeGatherScatterInst(Instruction *MemoryInst,
Value *Ptr);
291 bool optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
292 ModifyDT &ModifiedDT);
293 bool optimizeInlineAsmInst(CallInst *CS);
295 bool optimizeExt(Instruction *&
I);
296 bool optimizeExtUses(Instruction *
I);
297 bool optimizeLoadExt(LoadInst *
Load);
298 bool optimizeShiftInst(BinaryOperator *BO);
299 bool optimizeFunnelShift(IntrinsicInst *Fsh);
300 bool optimizeSelectInst(SelectInst *SI);
301 bool optimizeShuffleVectorInst(ShuffleVectorInst *SVI);
302 bool optimizeSwitchType(SwitchInst *SI);
303 bool optimizeSwitchPhiConstants(SwitchInst *SI);
304 bool optimizeSwitchInst(SwitchInst *SI);
305 bool optimizeExtractElementInst(Instruction *Inst);
306 bool dupRetToEnableTailCallOpts(BasicBlock *BB, ModifyDT &ModifiedDT);
307 bool fixupDbgVariableRecord(DbgVariableRecord &
I);
308 bool fixupDbgVariableRecordsOnInst(Instruction &
I);
311 bool canFormExtLd(
const SmallVectorImpl<Instruction *> &MovedExts,
312 LoadInst *&LI, Instruction *&Inst,
bool HasPromoted);
313 bool tryToPromoteExts(TypePromotionTransaction &TPT,
314 const SmallVectorImpl<Instruction *> &Exts,
315 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
316 unsigned CreatedInstsCost = 0);
318 bool splitLargeGEPOffsets();
319 bool optimizePhiType(PHINode *Inst, SmallPtrSetImpl<PHINode *> &Visited,
320 SmallPtrSetImpl<Instruction *> &DeletedInstrs);
322 bool performAddressTypePromotion(
323 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
324 bool HasPromoted, TypePromotionTransaction &TPT,
325 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts);
327 bool simplifyOffsetableRelocate(GCStatepointInst &
I);
329 bool tryToSinkFreeOperands(Instruction *
I);
330 bool replaceMathCmpWithIntrinsic(BinaryOperator *BO,
Value *Arg0,
Value *Arg1,
332 bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT);
333 bool optimizeURem(Instruction *Rem);
334 bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
335 bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
336 bool unfoldPowerOf2Test(CmpInst *Cmp);
345 CodeGenPrepareLegacyPass() : FunctionPass(ID) {}
349 StringRef getPassName()
const override {
return "CodeGen Prepare"; }
351 void getAnalysisUsage(AnalysisUsage &AU)
const override {
359 AU.
addRequired<BranchProbabilityInfoWrapperPass>();
367char CodeGenPrepareLegacyPass::ID = 0;
369bool CodeGenPrepareLegacyPass::runOnFunction(
Function &
F) {
372 auto TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
373 CodeGenPrepare CGP(TM);
374 CGP.DL = &
F.getDataLayout();
377 CGP.TRI = CGP.SubtargetInfo->getRegisterInfo();
378 CGP.TLInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
379 CGP.TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
380 CGP.LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
381 CGP.BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
382 CGP.BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
383 CGP.PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
385 getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
386 CGP.BBSectionsProfileReader = BBSPRWP ? &BBSPRWP->getBBSPR() :
nullptr;
387 DomTreeUpdater DTUpdater(
388 &getAnalysis<DominatorTreeWrapperPass>().
getDomTree(),
389 DomTreeUpdater::UpdateStrategy::Lazy);
390 CGP.DTU = &DTUpdater;
396 "Optimize for code generation",
false,
false)
408 return new CodeGenPrepareLegacyPass();
413 CodeGenPrepare CGP(TM);
426 DL = &
F.getDataLayout();
439 "analysis to be available");
440 BBSectionsProfileReader =
443 DomTreeUpdater::UpdateStrategy::Lazy);
449 bool EverMadeChange =
false;
451 OptSize =
F.hasOptSize();
454 if (Opts.bbsections_guided_section_prefix && BBSectionsProfileReader &&
456 (void)
F.setSectionPrefix(
"hot");
457 }
else if (Opts.profile_guided_section_prefix) {
461 if (
F.hasFnAttribute(Attribute::Hot) ||
462 PSI->isFunctionHotInCallGraph(&
F, *BFI))
463 (void)
F.setSectionPrefix(
"hot");
467 else if (PSI->isFunctionColdInCallGraph(&
F, *BFI) ||
468 F.hasFnAttribute(Attribute::Cold))
469 (void)
F.setSectionPrefix(
"unlikely");
470 else if (Opts.profile_unknown_in_special_section &&
471 PSI->hasPartialSampleProfile() && PSI->isFunctionHotnessUnknown(
F))
472 (void)
F.setSectionPrefix(
"unknown");
478 const DenseMap<unsigned int, unsigned int> &BypassWidths =
481 while (BB !=
nullptr) {
494 EverMadeChange |= eliminateAssumptions(
F);
496 auto resetLoopInfo = [
this]() {
503 bool ResetLI =
false;
504 EverMadeChange |= eliminateMostlyEmptyBlocks(
F, ResetLI);
508 if (Opts.cgp_branch_opts)
509 EverMadeChange |= splitBranchCondition(
F);
515 EverMadeChange |=
Split;
521 assert(getDT().
verify(DominatorTree::VerificationLevel::Fast) &&
522 "Incorrect DominatorTree updates in CGP");
530 IsHugeFunc =
F.size() > Opts.cgp_huge_func;
532 bool MadeChange =
true;
533 bool FuncIterated =
false;
543 if (FuncIterated && !FreshBBs.
contains(&BB))
546 ModifyDT ModifiedDTOnIteration = ModifyDT::NotModifyDT;
562 else if (FuncIterated)
567 if (ModifiedDTOnIteration != ModifyDT::NotModifyDT)
572 FuncIterated = IsHugeFunc;
574 if (Opts.cgp_type_promotion_merge && !ValToSExtendedUses.empty())
575 MadeChange |= mergeSExts(
F);
576 if (!LargeOffsetGEPMap.
empty())
577 MadeChange |= splitLargeGEPOffsets();
578 MadeChange |= optimizePhiTypes(
F);
581 eliminateFallThrough(
F);
585 assert(getDT().
verify(DominatorTree::VerificationLevel::Fast) &&
586 "Incorrect DominatorTree updates in CGP");
593 for (Instruction *
I : RemovedInsts)
596 EverMadeChange |= MadeChange;
597 SeenChainsForSExt.
clear();
598 ValToSExtendedUses.clear();
599 RemovedInsts.clear();
600 LargeOffsetGEPMap.
clear();
601 LargeOffsetGEPID.
clear();
610 if (Opts.cgp_branch_opts) {
615 SmallSetVector<BasicBlock *, 8> WorkList;
616 for (BasicBlock &BB :
F) {
622 for (BasicBlock *Succ : Successors)
628 MadeChange |= !WorkList.
empty();
629 while (!WorkList.
empty()) {
635 for (BasicBlock *Succ : Successors)
645 if (EverMadeChange || MadeChange)
646 MadeChange |= eliminateFallThrough(
F);
648 EverMadeChange |= MadeChange;
651 if (Opts.cgp_gc_opts) {
653 for (BasicBlock &BB :
F)
654 for (Instruction &
I : BB)
657 for (
auto &
I : Statepoints)
658 EverMadeChange |= simplifyOffsetableRelocate(*
I);
663 EverMadeChange |= placeDbgValues(
F);
664 EverMadeChange |= placePseudoProbes(
F);
667 if (Opts.cgp_verify_bfi_updates)
671 return EverMadeChange;
674bool CodeGenPrepare::eliminateAssumptions(
Function &
F) {
675 bool MadeChange =
false;
676 for (BasicBlock &BB :
F) {
677 CurInstIterator = BB.begin();
678 while (CurInstIterator != BB.end()) {
683 Assume->eraseFromParent();
685 resetIteratorIfInvalidatedWhileCalling(&BB, [&]() {
696void CodeGenPrepare::removeAllAssertingVHReferences(
Value *V) {
697 LargeOffsetGEPMap.
erase(V);
698 NewGEPBases.
erase(V);
706 auto VecI = LargeOffsetGEPMap.
find(
GEP->getPointerOperand());
707 if (VecI == LargeOffsetGEPMap.
end())
710 auto &GEPVector = VecI->second;
713 if (GEPVector.empty())
714 LargeOffsetGEPMap.
erase(VecI);
718[[maybe_unused]]
void CodeGenPrepare::verifyBFIUpdates(
Function &
F) {
719 DominatorTree NewDT(
F);
722 BranchProbabilityInfo NewBPI(
F, NewCI, TLInfo);
723 BlockFrequencyInfo NewBFI(
F, NewBPI, NewCI);
724 NewBFI.verifyMatch(*BFI);
730bool CodeGenPrepare::eliminateFallThrough(
Function &
F) {
732 SmallPtrSet<BasicBlock *, 8> Preds;
740 BasicBlock *SinglePred = BB->getSinglePredecessor();
743 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
756 FreshBBs.
insert(SinglePred);
764 for (
auto *Pred : Preds)
772BasicBlock *CodeGenPrepare::findDestBlockOfMergeableEmptyBlock(BasicBlock *BB) {
781 if (BBI != BB->
begin()) {
792 if (!canMergeBlocks(BB, DestBB))
802bool CodeGenPrepare::eliminateMostlyEmptyBlocks(
Function &
F,
bool &ResetLI) {
803 SmallPtrSet<BasicBlock *, 16> Preheaders;
805 while (!LoopList.empty()) {
806 Loop *
L = LoopList.pop_back_val();
808 if (BasicBlock *Preheader =
L->getLoopPreheader())
809 Preheaders.
insert(Preheader);
813 bool MadeChange =
false;
814 SmallPtrSet<PHINode *, 32> KnownNonDeadPHIs;
818 if (Opts.cgp_delete_phis)
826 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
828 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.
count(BB)))
831 ResetLI |= eliminateMostlyEmptyBlock(BB);
837bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB,
844 if (Opts.cgp_preheader_prot && isPreheader &&
888 SmallPtrSet<BasicBlock *, 16> SameIncomingValueBBs;
893 if (DestBBPred == BB)
897 return DestPN.getIncomingValueForBlock(BB) ==
898 DestPN.getIncomingValueForBlock(DestBBPred);
900 SameIncomingValueBBs.
insert(DestBBPred);
906 if (SameIncomingValueBBs.
count(Pred))
909 BlockFrequency PredFreq = BFI->getBlockFreq(Pred);
910 BlockFrequency
BBFreq = BFI->getBlockFreq(BB);
912 for (
auto *SameValueBB : SameIncomingValueBBs)
913 if (SameValueBB->getUniquePredecessor() == Pred &&
914 DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
915 BBFreq += BFI->getBlockFreq(SameValueBB);
917 std::optional<BlockFrequency> Limit =
918 BBFreq.mul(Opts.cgp_freq_ratio_to_skip_merge);
919 return !Limit || PredFreq <= *Limit;
925bool CodeGenPrepare::canMergeBlocks(
const BasicBlock *BB,
926 const BasicBlock *DestBB)
const {
930 for (
const PHINode &PN : BB->
phis()) {
931 for (
const User *U : PN.users()) {
940 for (
unsigned I = 0,
E = UPN->getNumIncomingValues();
I !=
E; ++
I) {
943 Insn->
getParent() != UPN->getIncomingBlock(
I))
958 SmallPtrSet<const BasicBlock *, 16> BBPreds;
961 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
962 BBPreds.
insert(BBPN->getIncomingBlock(i));
970 if (BBPreds.
count(Pred)) {
971 for (
const PHINode &PN : DestBB->
phis()) {
972 const Value *
V1 = PN.getIncomingValueForBlock(Pred);
973 const Value *V2 = PN.getIncomingValueForBlock(BB);
977 if (V2PN->getParent() == BB)
978 V2 = V2PN->getIncomingValueForBlock(Pred);
997 E = OldI->user_end();
1010bool CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
1020 if (SinglePred != DestBB) {
1021 assert(SinglePred == BB &&
1022 "Single predecessor not the same as predecessor");
1031 FreshBBs.
insert(SinglePred);
1032 FreshBBs.
erase(DestBB);
1040 for (PHINode &PN : DestBB->
phis()) {
1042 Value *InVal = PN.removeIncomingValue(BB,
false);
1047 if (InValPhi && InValPhi->
getParent() == BB) {
1056 for (
unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i)
1057 PN.addIncoming(InVal, BBPN->getIncomingBlock(i));
1060 PN.addIncoming(InVal, Pred);
1074 SmallPtrSet<BasicBlock *, 8> SeenPreds;
1078 if (!PredOfDestBB.contains(Pred)) {
1079 if (SeenPreds.
insert(Pred).second)
1080 DTUpdates.
push_back({DominatorTree::Insert, Pred, DestBB});
1085 if (SeenPreds.
insert(Pred).second)
1086 DTUpdates.
push_back({DominatorTree::Delete, Pred, BB});
1088 DTUpdates.
push_back({DominatorTree::Delete, BB, DestBB});
1108 for (
auto *ThisRelocate : AllRelocateCalls) {
1109 auto K = std::make_pair(ThisRelocate->getBasePtrIndex(),
1110 ThisRelocate->getDerivedPtrIndex());
1111 RelocateIdxMap.
insert(std::make_pair(
K, ThisRelocate));
1113 for (
auto &Item : RelocateIdxMap) {
1114 std::pair<unsigned, unsigned>
Key = Item.first;
1115 if (
Key.first ==
Key.second)
1120 auto BaseKey = std::make_pair(
Key.first,
Key.first);
1123 auto MaybeBase = RelocateIdxMap.
find(BaseKey);
1124 if (MaybeBase == RelocateIdxMap.
end())
1129 RelocateInstMap[MaybeBase->second].push_back(
I);
1137 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++) {
1140 if (!
Op ||
Op->getZExtValue() > 20)
1144 for (
unsigned i = 1; i <
GEP->getNumOperands(); i++)
1154 bool MadeChange =
false;
1161 for (
auto R = RelocatedBase->
getParent()->getFirstInsertionPt();
1162 &*R != RelocatedBase; ++R)
1166 RelocatedBase->
moveBefore(RI->getIterator());
1173 "Not relocating a derived object of the original base object");
1174 if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) {
1179 if (RelocatedBase->
getParent() != ToReplace->getParent()) {
1189 if (!Derived || Derived->getPointerOperand() !=
Base)
1198 "Should always have one since it's not a terminator");
1202 Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
1226 Value *ActualRelocatedBase = RelocatedBase;
1227 if (RelocatedBase->
getType() !=
Base->getType()) {
1228 ActualRelocatedBase =
1229 Builder.CreateBitCast(RelocatedBase,
Base->getType());
1231 Value *Replacement =
1232 Builder.CreateGEP(Derived->getSourceElementType(), ActualRelocatedBase,
1238 Value *ActualReplacement = Replacement;
1239 if (Replacement->
getType() != ToReplace->getType()) {
1241 Builder.CreateBitCast(Replacement, ToReplace->
getType());
1244 ToReplace->eraseFromParent();
1268bool CodeGenPrepare::simplifyOffsetableRelocate(GCStatepointInst &
I) {
1269 bool MadeChange =
false;
1271 for (
auto *U :
I.users())
1278 if (AllRelocateCalls.
size() < 2)
1283 MapVector<GCRelocateInst *, SmallVector<GCRelocateInst *, 0>> RelocateInstMap;
1285 if (RelocateInstMap.
empty())
1288 for (
auto &Item : RelocateInstMap)
1302 bool MadeChange =
false;
1305 Use &TheUse = UI.getUse();
1312 UserBB = PN->getIncomingBlock(TheUse);
1320 if (
User->isEHPad())
1330 if (UserBB == DefBB)
1334 CastInst *&InsertedCast = InsertedCasts[UserBB];
1336 if (!InsertedCast) {
1344 TheUse = InsertedCast;
1363 if (!SrcInst || SrcInst->getParent() == BCI->
getParent() ||
1364 SrcInst->isTerminator())
1368 Type *SrcTy = SrcInst->getType();
1382 bool IsCrossDomain = DestTy->
isFPOrFPVectorTy() != SrcTy->isFPOrFPVectorTy();
1385 unsigned NativeWidth =
DL.getPointerSizeInBits();
1386 bool IsLargeScalar =
1388 DL.getTypeSizeInBits(DestTy).getFixedValue() > NativeWidth;
1390 if (IsCrossDomain || IsLargeScalar)
1396 : std::next(SrcInst->getIterator());
1413 ASC->getDestAddressSpace()))
1468static std::optional<std::pair<Instruction *, Constant *>>
1471 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1472 return std::nullopt;
1475 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1476 return std::nullopt;
1480 return std::make_pair(IVInc, Step);
1481 return std::nullopt;
1494 return IVInc->first ==
I;
1498bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
1502 auto IsReplacableIVIncrement = [
this, &
Cmp](BinaryOperator *BO) {
1506 assert(L &&
"L should not be null after isIVIncrement()");
1508 if (LI->getLoopFor(
Cmp->getParent()) != L)
1521 return BO->
hasOneUse() && DT.dominates(
Cmp->getParent(),
L->getLoopLatch());
1523 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1546 if (BO->
getOpcode() == Instruction::Add &&
1547 IID == Intrinsic::usub_with_overflow) {
1554 for (Instruction &Iter : *
Cmp->getParent()) {
1557 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1562 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1565 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1566 if (BO->
getOpcode() != Instruction::Xor) {
1567 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1571 "Patterns with XOr should use the BO only in the compare");
1572 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1574 Cmp->eraseFromParent();
1584 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1592 B = ConstantInt::get(
B->getType(), 1);
1600 for (
User *U :
A->users()) {
1611bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp,
1612 ModifyDT &ModifiedDT) {
1613 bool EdgeCase =
false;
1615 BinaryOperator *
Add;
1620 A =
Add->getOperand(0);
1621 B =
Add->getOperand(1);
1627 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1633 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1636 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1637 Intrinsic::uadd_with_overflow))
1641 ModifiedDT = ModifyDT::ModifyInstDT;
1645bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
1646 ModifyDT &ModifiedDT) {
1653 ICmpInst::Predicate Pred =
Cmp->getPredicate();
1654 if (Pred == ICmpInst::ICMP_UGT) {
1656 Pred = ICmpInst::ICMP_ULT;
1660 B = ConstantInt::get(
B->getType(), 1);
1661 Pred = ICmpInst::ICMP_ULT;
1666 Pred = ICmpInst::ICMP_ULT;
1668 if (Pred != ICmpInst::ICMP_ULT)
1675 BinaryOperator *
Sub =
nullptr;
1676 for (User *U : CmpVariableOperand->
users()) {
1684 const APInt *CmpC, *AddC;
1696 Sub->hasNUsesOrMore(1)))
1702 if (
Sub->getParent() !=
Cmp->getParent() && !
Sub->hasOneUse())
1705 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1706 Cmp, Intrinsic::usub_with_overflow))
1710 ModifiedDT = ModifyDT::ModifyInstDT;
1717bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1730 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1736 Type *OpTy =
X->getType();
1744 if (Pred == ICmpInst::ICMP_EQ) {
1745 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1746 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1748 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1754 if (IsPowerOf2OrZeroTest ||
1765 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1774 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1777 Cmp->replaceAllUsesWith(NewCmp);
1797 bool UsedInPhiOrCurrentBlock =
any_of(Cmp->users(), [Cmp](
User *U) {
1798 return isa<PHINode>(U) ||
1799 cast<Instruction>(U)->getParent() == Cmp->getParent();
1804 if (UsedInPhiOrCurrentBlock && Cmp->getOperand(0)->getType()->isIntegerTy() &&
1805 Cmp->getOperand(0)->getType()->getScalarSizeInBits() >
1806 DL.getLargestLegalIntTypeSizeInBits())
1812 bool MadeChange =
false;
1815 Use &TheUse = UI.getUse();
1830 if (UserBB == DefBB)
1834 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1840 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1847 TheUse = InsertedCmp;
1853 if (Cmp->use_empty()) {
1854 Cmp->eraseFromParent();
1881 bool EnableICmpEqToICmpSt) {
1891 for (
User *U : Cmp->users()) {
1913 if (CmpBB != FalseBB)
1916 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
1930 for (
User *U : Cmp->users()) {
1932 BI->swapSuccessors();
1938 SI->swapProfMetadata();
1950 Value *Op0 = Cmp->getOperand(0);
1951 Value *Op1 = Cmp->getOperand(1);
1960 unsigned NumInspected = 0;
1963 if (++NumInspected > 128)
1971 if (GoodToSwap > 0) {
1972 Cmp->swapOperands();
1992 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
1995 auto [ClassVal, ClassTest] =
2001 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
2005 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
2006 Cmp->replaceAllUsesWith(IsFPClass);
2014 Value *Incr, *RemAmt;
2019 Value *AddInst, *AddOffset;
2022 if (PN !=
nullptr) {
2024 AddOffset =
nullptr;
2042 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2046 if (!L->contains(Rem))
2050 if (!L->isLoopInvariant(RemAmt))
2054 if (AddOffset && !L->isLoopInvariant(AddOffset))
2075 AddInstOut = AddInst;
2076 AddOffsetOut = AddOffset;
2095 Value *AddOffset, *RemAmt, *AddInst;
2098 AddOffset, LoopIncrPN))
2123 assert(AddOffset &&
"We found an add but missing values");
2141 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2146 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2151 NewRem->
addIncoming(Start, L->getLoopPreheader());
2156 FreshBBs.
insert(L->getLoopLatch());
2167bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2173bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2177 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2180 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2183 if (unfoldPowerOf2Test(Cmp))
2204 SetOfInstrs &InsertedInsts) {
2207 assert(!InsertedInsts.count(AndI) &&
2208 "Attempting to optimize already optimized and instruction");
2209 (void)InsertedInsts;
2223 for (
auto *U : AndI->
users()) {
2231 if (!CmpC || !CmpC->
isZero())
2246 Use &TheUse = UI.getUse();
2264 TheUse = InsertedAnd;
2281 if (
User->getOpcode() != Instruction::And ||
2287 if ((Cimm & (Cimm + 1)).getBoolValue())
2301 bool MadeChange =
false;
2304 TruncE = TruncI->user_end();
2305 TruncUI != TruncE;) {
2307 Use &TruncTheUse = TruncUI.getUse();
2332 if (UserBB == TruncUserBB)
2336 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2338 if (!InsertedShift && !InsertedTrunc) {
2342 if (ShiftI->
getOpcode() == Instruction::AShr)
2344 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2347 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2355 TruncInsertPt.setHeadBit(
true);
2356 assert(TruncInsertPt != TruncUserBB->
end());
2360 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2361 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2365 TruncTheUse = InsertedTrunc;
2398 bool MadeChange =
false;
2402 Use &TheUse = UI.getUse();
2416 if (UserBB == DefBB) {
2444 if (!InsertedShift) {
2448 if (ShiftI->
getOpcode() == Instruction::AShr)
2450 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2453 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2461 TheUse = InsertedShift;
2509 unsigned SizeInBits = Ty->getScalarSizeInBits();
2510 if (Ty->isVectorTy())
2521 nullptr,
"cond.false");
2523 FreshBBs.
insert(CallBlock);
2530 SplitPt.setHeadBit(
true);
2532 nullptr,
"cond.end");
2534 FreshBBs.
insert(EndBlock);
2538 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2545 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2546 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2547 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2553 Builder.SetInsertPoint(EndBlock->
begin());
2554 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2564 ModifiedDT = ModifyDT::ModifyBBDT;
2568bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2572 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2580 for (
auto &Arg : CI->
args()) {
2585 if (!Arg->getType()->isPointerTy())
2587 APInt
Offset(
DL->getIndexSizeInBits(
2590 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2597 if (AllocaSize && AllocaSize->getKnownMinValue() >= MinSize + Offset2)
2615 MaybeAlign MIDestAlign =
MI->getDestAlign();
2616 if (!MIDestAlign || DestAlign > *MIDestAlign)
2617 MI->setDestAlignment(DestAlign);
2619 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2621 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2622 MTI->setSourceAlignment(SrcAlign);
2632 for (
auto &Arg : CI->
args()) {
2633 if (!Arg->getType()->isPointerTy())
2635 unsigned AS = Arg->getType()->getPointerAddressSpace();
2636 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2642 switch (
II->getIntrinsicID()) {
2645 case Intrinsic::assume:
2647 case Intrinsic::allow_runtime_check:
2648 case Intrinsic::allow_ubsan_check:
2649 case Intrinsic::experimental_widenable_condition: {
2653 if (
II->use_empty()) {
2654 II->eraseFromParent();
2658 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2663 case Intrinsic::objectsize:
2665 case Intrinsic::is_constant:
2667 case Intrinsic::aarch64_stlxr:
2668 case Intrinsic::aarch64_stxr: {
2677 InsertedInsts.insert(ExtVal);
2681 case Intrinsic::launder_invariant_group: {
2682 Value *ArgVal =
II->getArgOperand(0);
2683 auto it = LargeOffsetGEPMap.
find(
II);
2684 if (it != LargeOffsetGEPMap.
end()) {
2688 auto GEPs = std::move(it->second);
2689 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2694 II->eraseFromParent();
2697 case Intrinsic::cttz:
2698 case Intrinsic::ctlz:
2702 case Intrinsic::fshl:
2703 case Intrinsic::fshr:
2704 return optimizeFunnelShift(
II);
2705 case Intrinsic::masked_gather:
2706 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2707 case Intrinsic::masked_scatter:
2708 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2709 case Intrinsic::masked_load:
2712 if (VT->getNumElements() == 1) {
2713 Value *PtrVal =
II->getArgOperand(0);
2715 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2720 case Intrinsic::masked_store:
2724 if (VT->getNumElements() == 1) {
2725 Value *PtrVal =
II->getArgOperand(1);
2727 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2732 case Intrinsic::umul_with_overflow:
2733 return optimizeMulWithOverflow(
II,
false, ModifiedDT);
2734 case Intrinsic::smul_with_overflow:
2735 return optimizeMulWithOverflow(
II,
true, ModifiedDT);
2738 SmallVector<Value *, 2> PtrOps;
2741 while (!PtrOps.
empty()) {
2744 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2758 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2760 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2770 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2771 if (!
F->getReturnType()->isPointerTy())
2774 GlobalVariable *UniformValue =
nullptr;
2775 for (
auto &BB : *
F) {
2780 else if (V != UniformValue)
2788 return UniformValue;
2791 if (
Callee->hasExactDefinition()) {
2792 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2793 bool MadeChange =
false;
2819 switch (
II->getIntrinsicID()) {
2820 case Intrinsic::memset:
2821 case Intrinsic::memcpy:
2822 case Intrinsic::memmove:
2829 if (Callee && TLInfo)
2831 case LibFunc_strcpy:
2832 case LibFunc_strncpy:
2833 case LibFunc_strcat:
2834 case LibFunc_strncat:
2875bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
2876 ModifyDT &ModifiedDT) {
2881 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2883 PHINode *PN =
nullptr;
2884 ExtractValueInst *EVI =
nullptr;
2885 BitCastInst *BCI =
nullptr;
2905 auto isLifetimeEndOrBitCastFor = [](
const Instruction *Inst) {
2911 return II->getIntrinsicID() == Intrinsic::lifetime_end;
2917 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
2919 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
2941 isLifetimeEndOrBitCastFor(&*BI) || isFakeUse(&*BI))
2948 auto MayBePermittedAsTailCall = [&](
const auto *CI) {
2965 MayBePermittedAsTailCall(CI)) {
2986 MayBePermittedAsTailCall(CI)) {
2993 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
2995 if (!VisitedBBs.
insert(Pred).second)
2997 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
2999 if (CI && CI->
use_empty() && MayBePermittedAsTailCall(CI)) {
3014 for (
auto const &TailCallBB : TailCallBBs) {
3023 assert(!Opts.cgp_verify_bfi_updates ||
3024 BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB));
3025 BFI->setBlockFreq(BB,
3026 (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB)));
3027 ModifiedDT = ModifyDT::ModifyBBDT;
3036 for (
auto *CI : CallInsts) {
3037 for (
auto const *FakeUse : FakeUses) {
3038 auto *ClonedInst = FakeUse->clone();
3056struct ExtAddrMode :
public TargetLowering::AddrMode {
3057 Value *BaseReg =
nullptr;
3058 Value *ScaledReg =
nullptr;
3059 Value *OriginalValue =
nullptr;
3060 bool InBounds =
true;
3064 BaseRegField = 0x01,
3066 BaseOffsField = 0x04,
3067 ScaledRegField = 0x08,
3069 MultipleFields = 0xff
3072 ExtAddrMode() =
default;
3074 void print(raw_ostream &OS)
const;
3081 if (ScaledReg == From)
3085 FieldName
compare(
const ExtAddrMode &other) {
3088 if (BaseReg && other.
BaseReg &&
3090 return MultipleFields;
3091 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3092 return MultipleFields;
3095 return MultipleFields;
3098 if (InBounds != other.InBounds)
3099 return MultipleFields;
3102 unsigned Result = NoField;
3105 if (BaseGV != other.BaseGV)
3107 if (BaseOffs != other.BaseOffs)
3110 Result |= ScaledRegField;
3113 if (Scale && other.
Scale && Scale != other.
Scale)
3117 return MultipleFields;
3119 return static_cast<FieldName
>(
Result);
3129 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3140 case ScaledRegField:
3147 void SetCombinedField(FieldName
Field,
Value *V,
3148 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3153 case ExtAddrMode::BaseRegField:
3156 case ExtAddrMode::BaseGVField:
3159 assert(BaseReg ==
nullptr);
3163 case ExtAddrMode::ScaledRegField:
3168 for (
const ExtAddrMode &AM : AddrModes)
3174 case ExtAddrMode::BaseOffsField:
3177 assert(ScaledReg ==
nullptr);
3187static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3193#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3194void ExtAddrMode::print(raw_ostream &OS)
const {
3195 bool NeedPlus =
false;
3201 BaseGV->printAsOperand(OS,
false);
3206 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3211 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3212 BaseReg->printAsOperand(OS,
false);
3216 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3239class TypePromotionTransaction {
3243 class TypePromotionAction {
3251 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3253 virtual ~TypePromotionAction() =
default;
3260 virtual void undo() = 0;
3265 virtual void commit() {
3271 class InsertionHandler {
3280 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3283 bool HasPrevInstruction;
3287 InsertionHandler(Instruction *Inst) {
3295 if (HasPrevInstruction) {
3303 void insert(Instruction *Inst) {
3304 if (HasPrevInstruction) {
3316 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3321 class OperandSetter :
public TypePromotionAction {
3330 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3331 : TypePromotionAction(Inst),
Idx(
Idx) {
3333 <<
"for:" << *Inst <<
"\n"
3334 <<
"with:" << *NewVal <<
"\n");
3340 void undo()
override {
3342 <<
"for: " << *Inst <<
"\n"
3343 <<
"with: " << *Origin <<
"\n");
3350 class OperandsHider :
public TypePromotionAction {
3352 SmallVector<Value *, 4> OriginalValues;
3356 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3359 OriginalValues.
reserve(NumOpnds);
3360 for (
unsigned It = 0; It < NumOpnds; ++It) {
3372 void undo()
override {
3374 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3380 class TruncBuilder :
public TypePromotionAction {
3387 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3389 Builder.SetCurrentDebugLocation(
DebugLoc());
3390 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3395 Value *getBuiltValue() {
return Val; }
3398 void undo()
override {
3401 IVal->eraseFromParent();
3406 class SExtBuilder :
public TypePromotionAction {
3413 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3414 : TypePromotionAction(InsertPt) {
3416 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3421 Value *getBuiltValue() {
return Val; }
3424 void undo()
override {
3427 IVal->eraseFromParent();
3432 class ZExtBuilder :
public TypePromotionAction {
3439 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3440 : TypePromotionAction(InsertPt) {
3442 Builder.SetCurrentDebugLocation(
DebugLoc());
3443 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3448 Value *getBuiltValue() {
return Val; }
3451 void undo()
override {
3454 IVal->eraseFromParent();
3459 class TypeMutator :
public TypePromotionAction {
3465 TypeMutator(Instruction *Inst,
Type *NewTy)
3466 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3467 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3473 void undo()
override {
3474 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3481 class UsesReplacer :
public TypePromotionAction {
3483 struct InstructionAndIdx {
3490 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3491 : Inst(Inst),
Idx(
Idx) {}
3497 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3507 UsesReplacer(Instruction *Inst,
Value *New)
3508 : TypePromotionAction(Inst),
New(
New) {
3509 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3512 for (Use &U : Inst->
uses()) {
3514 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3525 void undo()
override {
3527 for (InstructionAndIdx &Use : OriginalUses)
3528 Use.Inst->setOperand(
Use.Idx, Inst);
3533 for (DbgVariableRecord *DVR : DbgVariableRecords)
3534 DVR->replaceVariableLocationOp(New, Inst);
3539 class InstructionRemover :
public TypePromotionAction {
3541 InsertionHandler Inserter;
3545 OperandsHider Hider;
3548 UsesReplacer *Replacer =
nullptr;
3551 SetOfInstrs &RemovedInsts;
3558 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3559 Value *New =
nullptr)
3560 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3561 RemovedInsts(RemovedInsts) {
3563 Replacer =
new UsesReplacer(Inst, New);
3564 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3565 RemovedInsts.insert(Inst);
3572 ~InstructionRemover()
override {
delete Replacer; }
3574 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3575 InstructionRemover(
const InstructionRemover &other) =
delete;
3579 void undo()
override {
3580 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3581 Inserter.insert(Inst);
3585 RemovedInsts.erase(Inst);
3593 using ConstRestorationPt =
const TypePromotionAction *;
3595 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3596 : RemovedInsts(RemovedInsts) {}
3603 void rollback(ConstRestorationPt Point);
3606 ConstRestorationPt getRestorationPoint()
const;
3611 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3620 void mutateType(Instruction *Inst,
Type *NewTy);
3623 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3636 SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
3638 SetOfInstrs &RemovedInsts;
3643void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3645 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3646 Inst, Idx, NewVal));
3649void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3652 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3653 Inst, RemovedInsts, NewVal));
3656void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3659 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3662void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3664 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3667Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3668 std::unique_ptr<TruncBuilder> Ptr(
new TruncBuilder(Opnd, Ty));
3669 Value *Val = Ptr->getBuiltValue();
3670 Actions.push_back(std::move(Ptr));
3674Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3676 std::unique_ptr<SExtBuilder> Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3677 Value *Val = Ptr->getBuiltValue();
3678 Actions.push_back(std::move(Ptr));
3682Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3684 std::unique_ptr<ZExtBuilder> Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3685 Value *Val = Ptr->getBuiltValue();
3686 Actions.push_back(std::move(Ptr));
3690TypePromotionTransaction::ConstRestorationPt
3691TypePromotionTransaction::getRestorationPoint()
const {
3692 return !Actions.empty() ? Actions.back().get() :
nullptr;
3695bool TypePromotionTransaction::commit() {
3696 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3703void TypePromotionTransaction::rollback(
3704 TypePromotionTransaction::ConstRestorationPt Point) {
3705 while (!Actions.empty() && Point != Actions.back().get()) {
3706 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3716class AddressingModeMatcher {
3717 SmallVectorImpl<Instruction *> &AddrModeInsts;
3718 const TargetLowering &TLI;
3719 const TargetRegisterInfo &
TRI;
3720 const DataLayout &
DL;
3722 const std::function<
const DominatorTree &()> getDTFn;
3735 const SetOfInstrs &InsertedInsts;
3738 InstrToOrigTy &PromotedInsts;
3741 TypePromotionTransaction &TPT;
3744 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3748 bool IgnoreProfitability;
3751 bool OptSize =
false;
3753 ProfileSummaryInfo *PSI;
3754 BlockFrequencyInfo *BFI;
3755 const CodeGenOptions &Opts;
3757 AddressingModeMatcher(
3758 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3759 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3760 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3761 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3762 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3763 TypePromotionTransaction &TPT,
3764 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3765 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
3766 const CodeGenOptions &Opts)
3767 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
DL(
MI->getDataLayout()), LI(LI),
3768 getDTFn(getDTFn), AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
3769 AddrMode(AM), InsertedInsts(InsertedInsts),
3770 PromotedInsts(PromotedInsts), TPT(TPT), LargeOffsetGEP(LargeOffsetGEP),
3771 OptSize(OptSize), PSI(PSI), BFI(BFI), Opts(Opts) {
3772 IgnoreProfitability =
false;
3784 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3785 SmallVectorImpl<Instruction *> &AddrModeInsts,
3786 const TargetLowering &TLI,
const LoopInfo &LI,
3787 const std::function<
const DominatorTree &()> getDTFn,
3788 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3789 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3790 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3791 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
3792 const CodeGenOptions &Opts) {
3795 bool Success = AddressingModeMatcher(
3796 AddrModeInsts, TLI,
TRI, LI, getDTFn, AccessTy, AS,
3797 MemoryInst, Result, InsertedInsts, PromotedInsts, TPT,
3798 LargeOffsetGEP, OptSize, PSI, BFI, Opts)
3806 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3808 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3809 bool *MovedAway =
nullptr);
3810 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3811 ExtAddrMode &AMBefore,
3812 ExtAddrMode &AMAfter);
3813 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3814 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3815 Value *PromotedOperand)
const;
3821class PhiNodeSetIterator {
3822 PhiNodeSet *
const Set;
3823 size_t CurrentIndex = 0;
3828 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3830 PhiNodeSetIterator &operator++();
3846 friend class PhiNodeSetIterator;
3848 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3849 using iterator = PhiNodeSetIterator;
3864 size_t FirstValidElement = 0;
3870 bool insert(PHINode *Ptr) {
3871 if (NodeMap.insert(std::make_pair(Ptr,
NodeList.
size())).second) {
3881 bool erase(PHINode *Ptr) {
3882 if (NodeMap.erase(Ptr)) {
3883 SkipRemovedElements(FirstValidElement);
3893 FirstValidElement = 0;
3899 if (FirstValidElement == 0)
3900 SkipRemovedElements(FirstValidElement);
3901 return PhiNodeSetIterator(
this, FirstValidElement);
3908 size_t size()
const {
return NodeMap.size(); }
3911 size_t count(PHINode *Ptr)
const {
return NodeMap.count(Ptr); }
3919 void SkipRemovedElements(
size_t &CurrentIndex) {
3921 auto it = NodeMap.find(NodeList[CurrentIndex]);
3924 if (it != NodeMap.end() && it->second == CurrentIndex)
3931PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
3934PHINode *PhiNodeSetIterator::operator*()
const {
3936 "PhiNodeSet access out of range");
3937 return Set->NodeList[CurrentIndex];
3940PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
3942 "PhiNodeSet access out of range");
3944 Set->SkipRemovedElements(CurrentIndex);
3948bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
3949 return CurrentIndex ==
RHS.CurrentIndex;
3952bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
3953 return !((*this) ==
RHS);
3959class SimplificationTracker {
3960 DenseMap<Value *, Value *> Storage;
3963 PhiNodeSet AllPhiNodes;
3965 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
3970 auto SV = Storage.
find(V);
3971 if (SV == Storage.
end())
3979 void ReplacePhi(PHINode *From, PHINode *To) {
3980 Value *OldReplacement = Get(From);
3981 while (OldReplacement != From) {
3984 OldReplacement = Get(From);
3986 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
3989 AllPhiNodes.erase(From);
3993 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
3995 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
3997 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
3999 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
4001 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
4003 void destroyNewNodes(
Type *CommonType) {
4006 for (
auto *
I : AllPhiNodes) {
4007 I->replaceAllUsesWith(Dummy);
4008 I->eraseFromParent();
4010 AllPhiNodes.clear();
4011 for (
auto *
I : AllSelectNodes) {
4012 I->replaceAllUsesWith(Dummy);
4013 I->eraseFromParent();
4015 AllSelectNodes.clear();
4020class AddressingModeCombiner {
4021 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
4022 typedef std::pair<PHINode *, PHINode *> PHIPair;
4029 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
4032 bool AllAddrModesTrivial =
true;
4035 Type *CommonType =
nullptr;
4037 const DataLayout &
DL;
4038 const CodeGenOptions &Opts;
4044 Value *CommonValue =
nullptr;
4047 AddressingModeCombiner(
const DataLayout &
DL,
const CodeGenOptions &Opts,
4048 Value *OriginalValue)
4049 :
DL(
DL), Opts(Opts), Original(OriginalValue) {}
4051 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4054 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4059 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4063 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4066 if (AddrModes.
empty()) {
4074 ExtAddrMode::FieldName ThisDifferentField =
4075 AddrModes[0].compare(NewAddrMode);
4076 if (DifferentField == ExtAddrMode::NoField)
4077 DifferentField = ThisDifferentField;
4078 else if (DifferentField != ThisDifferentField)
4079 DifferentField = ExtAddrMode::MultipleFields;
4082 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4085 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4090 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4095 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4096 !NewAddrMode.HasBaseReg);
4113 bool combineAddrModes() {
4115 if (AddrModes.
size() == 0)
4119 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4124 if (AllAddrModesTrivial)
4127 if (!addrModeCombiningAllowed())
4133 FoldAddrToValueMapping
Map;
4134 if (!initializeMap(Map))
4137 CommonValue = findCommon(Map);
4139 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4140 return CommonValue !=
nullptr;
4146 void eraseCommonValueIfDead() {
4147 if (CommonValue && CommonValue->
use_empty())
4149 CommonInst->eraseFromParent();
4157 bool initializeMap(FoldAddrToValueMapping &Map) {
4160 SmallVector<Value *, 2> NullValue;
4162 for (
auto &AM : AddrModes) {
4166 if (CommonType && CommonType !=
Type)
4169 Map[AM.OriginalValue] = DV;
4174 assert(CommonType &&
"At least one non-null value must be!");
4175 for (
auto *V : NullValue)
4203 Value *findCommon(FoldAddrToValueMapping &Map) {
4211 SimplificationTracker
ST;
4216 InsertPlaceholders(Map, TraverseOrder, ST);
4219 FillPlaceholders(Map, TraverseOrder, ST);
4221 if (!Opts.cgp_addr_sink_new_select &&
ST.countNewSelectNodes() > 0) {
4222 ST.destroyNewNodes(CommonType);
4227 unsigned PhiNotMatchedCount = 0;
4228 if (!MatchPhiSet(ST, Opts.cgp_addr_sink_new_phis, PhiNotMatchedCount)) {
4229 ST.destroyNewNodes(CommonType);
4233 auto *
Result =
ST.Get(
Map.find(Original)->second);
4235 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4236 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4243 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4244 SmallSetVector<PHIPair, 8> &Matcher,
4245 PhiNodeSet &PhiNodesToMatch) {
4248 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4251 SmallSet<PHIPair, 8> Visited;
4252 while (!WorkList.
empty()) {
4254 if (!Visited.
insert(Item).second)
4261 for (
auto *
B : Item.first->blocks()) {
4262 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4263 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4264 if (FirstValue == SecondValue)
4274 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4279 if (Matcher.
count({FirstPhi, SecondPhi}))
4284 if (MatchedPHIs.
insert(FirstPhi).second)
4285 Matcher.
insert({FirstPhi, SecondPhi});
4287 WorkList.
push_back({FirstPhi, SecondPhi});
4296 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4297 unsigned &PhiNotMatchedCount) {
4301 SmallSetVector<PHIPair, 8> Matched;
4302 SmallPtrSet<PHINode *, 8> WillNotMatch;
4303 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4304 while (PhiNodesToMatch.size()) {
4305 PHINode *
PHI = *PhiNodesToMatch.begin();
4308 WillNotMatch.
clear();
4312 bool IsMatched =
false;
4313 for (
auto &
P :
PHI->getParent()->phis()) {
4315 if (PhiNodesToMatch.count(&
P))
4317 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4327 for (
auto MV : Matched)
4328 ST.ReplacePhi(MV.first, MV.second);
4333 if (!AllowNewPhiNodes)
4336 PhiNotMatchedCount += WillNotMatch.
size();
4337 for (
auto *
P : WillNotMatch)
4338 PhiNodesToMatch.erase(
P);
4343 void FillPlaceholders(FoldAddrToValueMapping &Map,
4344 SmallVectorImpl<Value *> &TraverseOrder,
4345 SimplificationTracker &ST) {
4346 while (!TraverseOrder.
empty()) {
4348 assert(
Map.contains(Current) &&
"No node to fill!!!");
4354 auto *TrueValue = CurrentSelect->getTrueValue();
4355 assert(
Map.contains(TrueValue) &&
"No True Value!");
4356 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4357 auto *FalseValue = CurrentSelect->getFalseValue();
4358 assert(
Map.contains(FalseValue) &&
"No False Value!");
4359 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4366 assert(
Map.contains(PV) &&
"No predecessor Value!");
4367 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4378 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4379 SmallVectorImpl<Value *> &TraverseOrder,
4380 SimplificationTracker &ST) {
4383 "Address must be a Phi or Select node");
4386 while (!Worklist.
empty()) {
4389 if (
Map.contains(Current))
4400 CurrentSelect->getName(),
4401 CurrentSelect->getIterator(), CurrentSelect);
4405 Worklist.
push_back(CurrentSelect->getTrueValue());
4406 Worklist.
push_back(CurrentSelect->getFalseValue());
4414 ST.insertNewPhi(
PHI);
4420 bool addrModeCombiningAllowed() {
4421 if (!Opts.cgp_complex_addr_modes)
4423 switch (DifferentField) {
4426 case ExtAddrMode::BaseRegField:
4427 return Opts.cgp_addr_sink_combine_base_reg;
4428 case ExtAddrMode::BaseGVField:
4429 return Opts.cgp_addr_sink_combine_base_gv;
4430 case ExtAddrMode::BaseOffsField:
4431 return Opts.cgp_addr_sink_combine_base_offs;
4432 case ExtAddrMode::ScaledRegField:
4433 return Opts.cgp_addr_sink_combine_scaled_reg;
4442bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4447 return matchAddr(ScaleReg,
Depth);
4458 ExtAddrMode TestAddrMode =
AddrMode;
4462 TestAddrMode.
Scale += Scale;
4476 ConstantInt *CI =
nullptr;
4477 Value *AddLHS =
nullptr;
4481 TestAddrMode.InBounds =
false;
4498 auto GetConstantStep =
4499 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4502 return std::nullopt;
4505 return std::nullopt;
4513 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4514 return std::nullopt;
4516 return std::make_pair(IVInc->first, ConstantStep->getValue());
4517 return std::nullopt;
4532 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4539 APInt Step = IVStep->second;
4541 if (
Offset.isSignedIntN(64)) {
4542 TestAddrMode.InBounds =
false;
4544 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4549 getDTFn().
dominates(IVInc, MemoryInst)) {
4569 switch (
I->getOpcode()) {
4570 case Instruction::BitCast:
4571 case Instruction::AddrSpaceCast:
4573 if (
I->getType() ==
I->getOperand(0)->getType())
4575 return I->getType()->isIntOrPtrTy();
4576 case Instruction::PtrToInt:
4579 case Instruction::IntToPtr:
4582 case Instruction::Add:
4584 case Instruction::Or:
4586 case Instruction::Mul:
4587 case Instruction::Shl:
4590 case Instruction::GetElementPtr:
4618class TypePromotionHelper {
4621 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4622 Instruction *ExtOpnd,
bool IsSExt) {
4623 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4624 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4628 if (It->second.getInt() == ExtTy)
4634 ExtTy = BothExtension;
4636 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4643 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4644 Instruction *Opnd,
bool IsSExt) {
4645 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4646 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4647 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4648 return It->second.getPointer();
4663 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4664 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4668 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4681 static Value *promoteOperandForTruncAndAnyExt(
4682 Instruction *Ext, TypePromotionTransaction &TPT,
4683 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4684 SmallVectorImpl<Instruction *> *Exts,
4685 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4696 static Value *promoteOperandForOther(Instruction *Ext,
4697 TypePromotionTransaction &TPT,
4698 InstrToOrigTy &PromotedInsts,
4699 unsigned &CreatedInstsCost,
4700 SmallVectorImpl<Instruction *> *Exts,
4701 SmallVectorImpl<Instruction *> *Truncs,
4702 const TargetLowering &TLI,
bool IsSExt);
4705 static Value *signExtendOperandForOther(
4706 Instruction *Ext, TypePromotionTransaction &TPT,
4707 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4708 SmallVectorImpl<Instruction *> *Exts,
4709 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4710 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4711 Exts, Truncs, TLI,
true);
4715 static Value *zeroExtendOperandForOther(
4716 Instruction *Ext, TypePromotionTransaction &TPT,
4717 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4718 SmallVectorImpl<Instruction *> *Exts,
4719 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4720 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4721 Exts, Truncs, TLI,
false);
4726 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4727 InstrToOrigTy &PromotedInsts,
4728 unsigned &CreatedInstsCost,
4729 SmallVectorImpl<Instruction *> *Exts,
4730 SmallVectorImpl<Instruction *> *Truncs,
4731 const TargetLowering &TLI);
4742 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4743 const TargetLowering &TLI,
4744 const InstrToOrigTy &PromotedInsts);
4749bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4750 Type *ConsideredExtType,
4751 const InstrToOrigTy &PromotedInsts,
4771 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4772 (IsSExt && BinOp->hasNoSignedWrap())))
4776 if ((Inst->
getOpcode() == Instruction::And ||
4781 if (Inst->
getOpcode() == Instruction::Xor) {
4784 if (!Cst->getValue().isAllOnes())
4793 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4803 if (ExtInst->hasOneUse()) {
4805 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4838 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4851TypePromotionHelper::Action TypePromotionHelper::getAction(
4852 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4853 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
4855 "Unexpected instruction type");
4862 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4875 return promoteOperandForTruncAndAnyExt;
4881 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4884Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4885 Instruction *SExt, TypePromotionTransaction &TPT,
4886 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4887 SmallVectorImpl<Instruction *> *Exts,
4888 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4892 Value *ExtVal = SExt;
4893 bool HasMergedNonFreeExt =
false;
4897 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
4900 TPT.replaceAllUsesWith(SExt, ZExt);
4901 TPT.eraseInstruction(SExt);
4906 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
4908 CreatedInstsCost = 0;
4912 TPT.eraseInstruction(SExtOpnd);
4920 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
4928 TPT.eraseInstruction(ExtInst, NextVal);
4932Value *TypePromotionHelper::promoteOperandForOther(
4933 Instruction *Ext, TypePromotionTransaction &TPT,
4934 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4935 SmallVectorImpl<Instruction *> *Exts,
4936 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
4941 CreatedInstsCost = 0;
4947 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
4950 ITrunc->moveAfter(ExtOpnd);
4955 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
4958 TPT.setOperand(Ext, 0, ExtOpnd);
4968 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
4970 TPT.mutateType(ExtOpnd, Ext->
getType());
4972 TPT.replaceAllUsesWith(Ext, ExtOpnd);
4975 for (
int OpIdx = 0, EndOpIdx = ExtOpnd->
getNumOperands(); OpIdx != EndOpIdx;
4979 !shouldExtOperand(ExtOpnd, OpIdx)) {
4988 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
4990 TPT.setOperand(ExtOpnd, OpIdx, ConstantInt::get(Ext->
getType(), CstVal));
5001 Value *ValForExtOpnd = IsSExt
5002 ? TPT.createSExt(ExtOpnd, Opnd, Ext->
getType())
5003 : TPT.createZExt(ExtOpnd, Opnd, Ext->
getType());
5004 TPT.setOperand(ExtOpnd, OpIdx, ValForExtOpnd);
5006 if (!InstForExtOpnd)
5012 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
5015 TPT.eraseInstruction(Ext);
5027bool AddressingModeMatcher::isPromotionProfitable(
5028 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
5029 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
5034 if (NewCost > OldCost)
5036 if (NewCost < OldCost)
5055bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5067 case Instruction::PtrToInt:
5070 case Instruction::IntToPtr: {
5078 case Instruction::BitCast:
5088 case Instruction::AddrSpaceCast: {
5096 case Instruction::Or:
5100 case Instruction::Add: {
5103 ExtAddrMode BackupAddrMode =
AddrMode;
5104 unsigned OldSize = AddrModeInsts.
size();
5109 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5110 TPT.getRestorationPoint();
5114 int First = 0, Second = 1;
5125 AddrModeInsts.
resize(OldSize);
5126 TPT.rollback(LastKnownGood);
5136 AddrModeInsts.
resize(OldSize);
5137 TPT.rollback(LastKnownGood);
5140 case Instruction::Mul:
5141 case Instruction::Shl: {
5145 if (!
RHS ||
RHS->getBitWidth() > 64)
5147 int64_t Scale = Opcode == Instruction::Shl
5148 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5149 :
RHS->getSExtValue();
5153 case Instruction::GetElementPtr: {
5156 int VariableOperand = -1;
5157 unsigned VariableScale = 0;
5159 int64_t ConstantOffset = 0;
5161 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5163 const StructLayout *SL =
DL.getStructLayout(STy);
5174 if (ConstantInt *CI =
5176 const APInt &CVal = CI->
getValue();
5183 if (VariableOperand != -1)
5187 VariableOperand = i;
5188 VariableScale = TypeSize;
5195 if (VariableOperand == -1) {
5196 AddrMode.BaseOffs += ConstantOffset;
5202 AddrMode.BaseOffs -= ConstantOffset;
5206 ConstantOffset != 0) {
5220 BaseI ? BaseI->getParent() : &
GEP->getFunction()->getEntryBlock();
5222 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5230 ExtAddrMode BackupAddrMode =
AddrMode;
5231 unsigned OldSize = AddrModeInsts.
size();
5234 AddrMode.BaseOffs += ConstantOffset;
5243 AddrModeInsts.
resize(OldSize);
5251 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5256 AddrModeInsts.
resize(OldSize);
5261 AddrMode.BaseOffs += ConstantOffset;
5262 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5263 VariableScale,
Depth)) {
5266 AddrModeInsts.
resize(OldSize);
5273 case Instruction::SExt:
5274 case Instruction::ZExt: {
5281 TypePromotionHelper::Action TPH =
5282 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5286 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5287 TPT.getRestorationPoint();
5288 unsigned CreatedInstsCost = 0;
5290 Value *PromotedOperand =
5291 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5306 assert(PromotedOperand &&
5307 "TypePromotionHelper should have filtered out those cases");
5309 ExtAddrMode BackupAddrMode =
AddrMode;
5310 unsigned OldSize = AddrModeInsts.
size();
5312 if (!matchAddr(PromotedOperand,
Depth) ||
5317 !isPromotionProfitable(CreatedInstsCost,
5318 ExtCost + (AddrModeInsts.
size() - OldSize),
5321 AddrModeInsts.
resize(OldSize);
5322 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5323 TPT.rollback(LastKnownGood);
5328 AddrMode.replaceWith(Ext, PromotedOperand);
5331 case Instruction::Call:
5333 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5349bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5352 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5353 TPT.getRestorationPoint();
5377 ExtAddrMode BackupAddrMode =
AddrMode;
5378 unsigned OldSize = AddrModeInsts.
size();
5381 bool MovedAway =
false;
5382 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5390 if (
I->hasOneUse() ||
5391 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5398 AddrModeInsts.
resize(OldSize);
5399 TPT.rollback(LastKnownGood);
5402 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5404 TPT.rollback(LastKnownGood);
5431 TPT.rollback(LastKnownGood);
5450 if (OpInfo.CallOperandVal == OpVal &&
5452 !OpInfo.isIndirect))
5468 if (!ConsideredInsts.
insert(
I).second)
5476 for (
Use &U :
I->uses()) {
5479 if (SeenInsts++ >= MaxUsersToScan)
5484 MemoryUses.push_back({&U, LI->getType()});
5491 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5498 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5505 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5515 if (!
find(PtrOps, U.get()))
5518 MemoryUses.push_back({&U, AccessTy});
5523 if (CI->hasFnAttr(Attribute::Cold)) {
5541 PSI, BFI, SeenInsts, MaxUsersToScan))
5552 unsigned SeenInsts = 0;
5555 PSI, BFI, SeenInsts, MaxUsersToScan);
5562bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5564 Value *KnownLive2) {
5566 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5607bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5608 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5609 if (IgnoreProfitability)
5627 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5628 ScaledReg =
nullptr;
5632 if (!BaseReg && !ScaledReg)
5641 Opts.cgp_max_address_users_to_scan))
5654 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5657 Type *AddressAccessTy = Pair.second;
5658 unsigned AS =
Address->getType()->getPointerAddressSpace();
5664 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5666 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5667 TPT.getRestorationPoint();
5668 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5669 AddressAccessTy, AS, UserI, Result,
5670 InsertedInsts, PromotedInsts, TPT,
5671 LargeOffsetGEP, OptSize, PSI, BFI, Opts);
5672 Matcher.IgnoreProfitability =
true;
5680 TPT.rollback(LastKnownGood);
5686 MatchedAddrModeInsts.
clear();
5696 return I->getParent() != BB;
5712 return std::next(AddrInst->getIterator());
5723 Earliest = UserInst;
5748bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5749 Type *AccessTy,
unsigned AddrSpace) {
5754 SmallVector<Value *, 8> worklist;
5755 SmallPtrSet<Value *, 16> Visited;
5761 bool PhiOrSelectSeen =
false;
5762 SmallVector<Instruction *, 16> AddrModeInsts;
5763 AddressingModeCombiner AddrModes(*
DL, Opts, Addr);
5764 TypePromotionTransaction TPT(RemovedInsts);
5765 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5766 TPT.getRestorationPoint();
5767 while (!worklist.
empty()) {
5779 if (!Visited.
insert(V).second)
5785 PhiOrSelectSeen =
true;
5792 PhiOrSelectSeen =
true;
5799 AddrModeInsts.
clear();
5800 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5805 auto getDTFn = [
this]() ->
const DominatorTree & {
return getDT(); };
5806 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5807 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5808 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5811 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5816 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5817 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5820 NewAddrMode.OriginalValue =
V;
5821 if (!AddrModes.addNewAddrMode(NewAddrMode))
5828 if (!AddrModes.combineAddrModes()) {
5829 TPT.rollback(LastKnownGood);
5835 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5841 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5855 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
5877 <<
" for " << *MemoryInst <<
"\n");
5881 !
DL->isNonIntegralPointerType(Addr->
getType())) {
5887 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
5889 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
5891 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
5893 }
else if (
valueOr(Opts.cgp_addr_sink_using_gep,
true) ||
5894 (Opts.cgp_addr_sink_using_gep == BoolOrDefault::Default &&
5899 <<
" for " << *MemoryInst <<
"\n");
5900 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
5911 if (ResultPtr ||
AddrMode.Scale != 1)
5932 GlobalValue *BaseGV =
AddrMode.BaseGV;
5933 if (BaseGV !=
nullptr) {
5938 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
5947 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
5948 if (!ResultPtr &&
AddrMode.BaseReg) {
5952 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
5953 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
5962 }
else if (!ResultPtr) {
5976 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
5989 "We can't transform if ScaledReg is too narrow");
5990 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
5994 V = Builder.CreateMul(
5997 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
6008 if (ResultPtr->
getType() != I8PtrTy)
6009 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6010 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6023 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
6025 SunkAddr = ResultPtr;
6027 if (ResultPtr->
getType() != I8PtrTy)
6028 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
6029 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
6036 !
DL->isNonIntegralPointerType(Addr->
getType())) {
6042 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
6044 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
6046 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6056 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6057 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6058 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6060 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6064 <<
" for " << *MemoryInst <<
"\n");
6075 if (
V->getType()->isPointerTy())
6076 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6078 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
6087 }
else if (
V->getType()->isPointerTy()) {
6088 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6091 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
6100 I->eraseFromParent();
6104 V = Builder.CreateMul(
6107 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6113 GlobalValue *BaseGV =
AddrMode.BaseGV;
6114 if (BaseGV !=
nullptr) {
6117 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6121 Value *
V = Builder.CreatePtrToInt(BaseGVPtr,
IntPtrTy,
"sunkaddr");
6123 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6132 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6140 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6146 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6151 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6152 RecursivelyDeleteTriviallyDeadInstructions(
6153 Repl, TLInfo, nullptr,
6154 [&](Value *V) { removeAllAssertingVHReferences(V); });
6178bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6184 if (!
GEP->hasIndices())
6192 SmallVector<Value *, 2>
Ops(
GEP->operands());
6194 bool RewriteGEP =
false;
6203 unsigned FinalIndex =
Ops.size() - 1;
6208 for (
unsigned i = 1; i < FinalIndex; ++i) {
6213 C =
C->getSplatValue();
6215 if (!CI || !CI->
isZero())
6222 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6226 if (!
C || !
C->isZero()) {
6227 Ops[FinalIndex] =
V;
6235 if (!RewriteGEP &&
Ops.size() == 2)
6242 Type *SourceTy =
GEP->getSourceElementType();
6243 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6247 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6248 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6249 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6259 if (
Ops.size() != 2) {
6269 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6283 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6284 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6287 Intrinsic::masked_gather) {
6291 Intrinsic::masked_scatter);
6306 Ptr, TLInfo,
nullptr,
6307 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6318 if (
I->hasNUsesOrMore(3))
6321 for (
User *U :
I->users()) {
6323 if (!Extract || Extract->getNumIndices() != 1)
6326 unsigned Index = Extract->getIndices()[0];
6328 MulExtract = Extract;
6329 else if (Index == 1)
6330 OverflowExtract = Extract;
6357bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
6358 ModifyDT &ModifiedDT) {
6365 ExtractValueInst *MulExtract =
nullptr, *OverflowExtract =
nullptr;
6370 InsertedInsts.insert(
I);
6381 OverflowEntryBB->
takeName(
I->getParent());
6387 NoOverflowBB->
moveAfter(OverflowEntryBB);
6395 Value *LoLHS = Builder.CreateTrunc(
LHS, LegalTy,
"lo.lhs");
6396 Value *HiLHS = Builder.CreateLShr(
LHS, VTHalfBitWidth,
"lhs.lsr");
6397 HiLHS = Builder.CreateTrunc(HiLHS, LegalTy,
"hi.lhs");
6400 Value *LoRHS = Builder.CreateTrunc(
RHS, LegalTy,
"lo.rhs");
6401 Value *HiRHS = Builder.CreateLShr(
RHS, VTHalfBitWidth,
"rhs.lsr");
6402 HiRHS = Builder.CreateTrunc(HiRHS, LegalTy,
"hi.rhs");
6404 Value *IsAnyBitTrue;
6407 Builder.CreateAShr(LoLHS, VTHalfBitWidth - 1,
"sign.lo.lhs");
6409 Builder.CreateAShr(LoRHS, VTHalfBitWidth - 1,
"sign.lo.rhs");
6410 Value *XorLHS = Builder.CreateXor(HiLHS, SignLoLHS);
6411 Value *XorRHS = Builder.CreateXor(HiRHS, SignLoRHS);
6412 Value *
Or = Builder.CreateOr(XorLHS, XorRHS,
"or.lhs.rhs");
6413 IsAnyBitTrue = Builder.CreateCmp(ICmpInst::ICMP_NE,
Or,
6414 ConstantInt::getNullValue(
Or->getType()));
6416 Value *CmpLHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiLHS,
6417 ConstantInt::getNullValue(LegalTy));
6418 Value *CmpRHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiRHS,
6419 ConstantInt::getNullValue(LegalTy));
6420 IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS,
"or.lhs.rhs");
6422 Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
6425 Builder.SetInsertPoint(NoOverflowBB);
6426 Value *ExtLoLHS, *ExtLoRHS;
6428 ExtLoLHS = Builder.CreateSExt(LoLHS, Ty,
"lo.lhs.ext");
6429 ExtLoRHS = Builder.CreateSExt(LoRHS, Ty,
"lo.rhs.ext");
6431 ExtLoLHS = Builder.CreateZExt(LoLHS, Ty,
"lo.lhs.ext");
6432 ExtLoRHS = Builder.CreateZExt(LoRHS, Ty,
"lo.rhs.ext");
6435 Value *
Mul = Builder.CreateMul(ExtLoLHS, ExtLoRHS,
"mul.overflow.no");
6440 OverflowResBB->
setName(
"overflow.res");
6443 Builder.CreateBr(OverflowResBB);
6451 PHINode *OverflowResPHI = Builder.CreatePHI(Ty, 2),
6453 Builder.CreatePHI(IntegerType::getInt1Ty(
I->getContext()), 2);
6465 if (OverflowExtract) {
6466 OverflowExtract->replaceAllUsesWith(OverflowFlagPHI);
6467 OverflowExtract->eraseFromParent();
6472 I->removeFromParent();
6474 I->insertInto(OverflowBB, OverflowBB->
end());
6475 Builder.SetInsertPoint(OverflowBB->
end());
6477 Value *OverflowFlag = Builder.CreateExtractValue(
I, {1},
"overflow.flag");
6478 Builder.CreateBr(OverflowResBB);
6482 OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
6484 DTU->
applyUpdates({{DominatorTree::Insert, OverflowEntryBB, OverflowBB},
6485 {DominatorTree::Insert, OverflowEntryBB, NoOverflowBB},
6486 {DominatorTree::Insert, NoOverflowBB, OverflowResBB},
6487 {DominatorTree::Delete, OverflowEntryBB, OverflowResBB},
6488 {DominatorTree::Insert, OverflowBB, OverflowResBB}});
6490 ModifiedDT = ModifyDT::ModifyBBDT;
6496bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6497 bool MadeChange =
false;
6499 const TargetRegisterInfo *
TRI =
6504 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6510 OpInfo.isIndirect) {
6512 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6575bool CodeGenPrepare::tryToPromoteExts(
6576 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6577 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6578 unsigned CreatedInstsCost) {
6579 bool Promoted =
false;
6582 for (
auto *
I : Exts) {
6597 TypePromotionHelper::Action TPH =
6598 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6607 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6608 TPT.getRestorationPoint();
6609 SmallVector<Instruction *, 4> NewExts;
6610 unsigned NewCreatedInstsCost = 0;
6613 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6614 &NewExts,
nullptr, *TLI);
6616 "TypePromotionHelper should have filtered out those cases");
6626 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6629 TotalCreatedInstsCost =
6630 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6631 if (!Opts.cgp_stress_ext_ld_promotion &&
6632 (TotalCreatedInstsCost > 1 ||
6634 (ExtCost == 0 && NewExts.
size() > 1))) {
6638 TPT.rollback(LastKnownGood);
6643 SmallVector<Instruction *, 2> NewlyMovedExts;
6644 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6645 bool NewPromoted =
false;
6646 for (
auto *ExtInst : NewlyMovedExts) {
6652 !(Opts.cgp_stress_ext_ld_promotion ||
6653 NewCreatedInstsCost <= ExtCost ||
6657 ProfitablyMovedExts.
push_back(MovedExt);
6664 TPT.rollback(LastKnownGood);
6675bool CodeGenPrepare::mergeSExts(
Function &
F) {
6677 for (
auto &Entry : ValToSExtendedUses) {
6678 SExts &Insts =
Entry.second;
6680 for (Instruction *Inst : Insts) {
6684 bool inserted =
false;
6685 for (
auto &Pt : CurPts) {
6688 RemovedInsts.insert(Pt);
6689 Pt->removeFromParent();
6700 RemovedInsts.insert(Inst);
6707 CurPts.push_back(Inst);
6749bool CodeGenPrepare::splitLargeGEPOffsets() {
6751 for (
auto &Entry : LargeOffsetGEPMap) {
6753 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6754 &LargeOffsetGEPs =
Entry.second;
6755 auto compareGEPOffset =
6756 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6757 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6758 if (
LHS.first ==
RHS.first)
6760 if (
LHS.second !=
RHS.second)
6761 return LHS.second <
RHS.second;
6762 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6765 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6768 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6770 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6771 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6772 Value *NewBaseGEP =
nullptr;
6774 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6775 GetElementPtrInst *
GEP) {
6776 LLVMContext &Ctx =
GEP->getContext();
6777 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6779 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6791 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), &getDT(), LI);
6794 NewBaseInsertPt = std::next(BaseI->getIterator());
6807 NewBaseGEP = OldBase;
6808 if (NewBaseGEP->
getType() != I8PtrTy)
6809 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6811 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6812 NewGEPBases.
insert(NewBaseGEP);
6818 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6819 BaseOffset = PreferBase;
6822 createNewBase(BaseOffset, OldBase, BaseGEP);
6825 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6826 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6827 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6828 int64_t
Offset = LargeOffsetGEP->second;
6829 if (
Offset != BaseOffset) {
6836 GEP->getResultElementType(),
6837 GEP->getAddressSpace())) {
6843 NewBaseGEP =
nullptr;
6848 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6853 createNewBase(BaseOffset, OldBase,
GEP);
6857 Value *NewGEP = NewBaseGEP;
6858 if (
Offset != BaseOffset) {
6861 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6865 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6866 GEP->eraseFromParent();
6873bool CodeGenPrepare::optimizePhiType(
6874 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
6875 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
6880 Type *PhiTy =
I->getType();
6881 Type *ConvertTy =
nullptr;
6883 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6886 SmallVector<Instruction *, 4> Worklist;
6888 SmallPtrSet<PHINode *, 4> PhiNodes;
6889 SmallPtrSet<ConstantData *, 4>
Constants;
6892 SmallPtrSet<Instruction *, 4> Defs;
6893 SmallPtrSet<Instruction *, 4>
Uses;
6899 bool AnyAnchored =
false;
6901 while (!Worklist.
empty()) {
6906 for (
Value *V :
Phi->incoming_values()) {
6908 if (!PhiNodes.
count(OpPhi)) {
6909 if (!Visited.
insert(OpPhi).second)
6915 if (!OpLoad->isSimple())
6917 if (Defs.
insert(OpLoad).second)
6920 if (Defs.
insert(OpEx).second)
6924 ConvertTy = OpBC->getOperand(0)->getType();
6925 if (OpBC->getOperand(0)->getType() != ConvertTy)
6927 if (Defs.
insert(OpBC).second) {
6940 for (User *V :
II->users()) {
6942 if (!PhiNodes.
count(OpPhi)) {
6943 if (Visited.
count(OpPhi))
6950 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
6952 Uses.insert(OpStore);
6955 ConvertTy = OpBC->getType();
6956 if (OpBC->getType() != ConvertTy)
6960 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
6967 if (!ConvertTy || !AnyAnchored || PhiTy == ConvertTy ||
6971 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
6972 << *ConvertTy <<
"\n");
6977 for (ConstantData *
C : Constants)
6979 for (Instruction *
D : Defs) {
6981 ValMap[
D] =
D->getOperand(0);
6985 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
6988 for (PHINode *Phi : PhiNodes)
6990 Phi->getName() +
".tc",
Phi->getIterator());
6992 for (PHINode *Phi : PhiNodes) {
6994 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
6996 Phi->getIncomingBlock(i));
7000 for (Instruction *U :
Uses) {
7005 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
7015bool CodeGenPrepare::optimizePhiTypes(
Function &
F) {
7016 if (!Opts.cgp_optimize_phi_types)
7020 SmallPtrSet<PHINode *, 4> Visited;
7021 SmallPtrSet<Instruction *, 4> DeletedInstrs;
7025 for (
auto &Phi : BB.
phis())
7026 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
7029 for (
auto *
I : DeletedInstrs) {
7031 I->eraseFromParent();
7039bool CodeGenPrepare::canFormExtLd(
7040 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
7041 Instruction *&Inst,
bool HasPromoted) {
7042 for (
auto *MovedExtInst : MovedExts) {
7045 Inst = MovedExtInst;
7097bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7098 bool AllowPromotionWithoutCommonHeader =
false;
7103 *Inst, AllowPromotionWithoutCommonHeader);
7104 TypePromotionTransaction TPT(RemovedInsts);
7105 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7106 TPT.getRestorationPoint();
7108 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7111 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7114 LoadInst *LI =
nullptr;
7119 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7120 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7125 Inst = ExtFedByLoad;
7130 if (ATPConsiderable &&
7131 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7132 HasPromoted, TPT, SpeculativelyMovedExts))
7135 TPT.rollback(LastKnownGood);
7144bool CodeGenPrepare::performAddressTypePromotion(
7145 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7146 bool HasPromoted, TypePromotionTransaction &TPT,
7147 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7148 bool Promoted =
false;
7149 SmallPtrSet<Instruction *, 1> UnhandledExts;
7150 bool AllSeenFirst =
true;
7151 for (
auto *
I : SpeculativelyMovedExts) {
7152 Value *HeadOfChain =
I->getOperand(0);
7153 auto AlreadySeen = SeenChainsForSExt.
find(HeadOfChain);
7156 if (AlreadySeen != SeenChainsForSExt.
end()) {
7157 if (AlreadySeen->second !=
nullptr)
7158 UnhandledExts.
insert(AlreadySeen->second);
7159 AllSeenFirst =
false;
7163 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7164 SpeculativelyMovedExts.size() == 1)) {
7168 for (
auto *
I : SpeculativelyMovedExts) {
7169 Value *HeadOfChain =
I->getOperand(0);
7170 SeenChainsForSExt[HeadOfChain] =
nullptr;
7171 ValToSExtendedUses[HeadOfChain].push_back(
I);
7174 Inst = SpeculativelyMovedExts.pop_back_val();
7179 for (
auto *
I : SpeculativelyMovedExts) {
7180 Value *HeadOfChain =
I->getOperand(0);
7181 SeenChainsForSExt[HeadOfChain] = Inst;
7186 if (!AllSeenFirst && !UnhandledExts.
empty())
7187 for (
auto *VisitedSExt : UnhandledExts) {
7188 if (RemovedInsts.count(VisitedSExt))
7190 TypePromotionTransaction TPT(RemovedInsts);
7192 SmallVector<Instruction *, 2> Chains;
7194 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7198 for (
auto *
I : Chains) {
7199 Value *HeadOfChain =
I->getOperand(0);
7201 SeenChainsForSExt[HeadOfChain] =
nullptr;
7202 ValToSExtendedUses[HeadOfChain].push_back(
I);
7208bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7213 Value *Src =
I->getOperand(0);
7214 if (Src->hasOneUse())
7226 bool DefIsLiveOut =
false;
7227 for (User *U :
I->users()) {
7232 if (UserBB == DefBB)
7234 DefIsLiveOut =
true;
7241 for (User *U : Src->users()) {
7244 if (UserBB == DefBB)
7253 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7255 bool MadeChange =
false;
7261 if (UserBB == DefBB)
7265 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7267 if (!InsertedTrunc) {
7270 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7272 InsertedInsts.insert(InsertedTrunc);
7285 I->dropPoisonGeneratingFlags();
7341bool CodeGenPrepare::optimizeLoadExt(LoadInst *
Load) {
7342 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7346 if (
Load->hasOneUse() &&
7352 SmallVector<Instruction *, 8> WorkList;
7353 SmallPtrSet<Instruction *, 16> Visited;
7354 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7355 SmallVector<Instruction *, 8> DropFlags;
7356 for (
auto *U :
Load->users())
7368 while (!WorkList.
empty()) {
7372 if (!Visited.
insert(
I).second)
7377 for (
auto *U :
Phi->users())
7382 switch (
I->getOpcode()) {
7383 case Instruction::And: {
7387 APInt AndBits = AndC->getValue();
7388 DemandBits |= AndBits;
7390 if (AndBits.
ugt(WidestAndBits))
7391 WidestAndBits = AndBits;
7392 if (AndBits == WidestAndBits &&
I->getOperand(0) ==
Load)
7397 case Instruction::Shl: {
7402 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7407 case Instruction::Trunc: {
7410 DemandBits.setLowBits(TruncBitWidth);
7420 uint32_t ActiveBits = DemandBits.getActiveBits();
7432 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7433 WidestAndBits != DemandBits)
7436 LLVMContext &Ctx =
Load->getType()->getContext();
7437 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7448 Builder.CreateAnd(
Load, ConstantInt::get(Ctx, DemandBits)));
7451 InsertedInsts.insert(NewAnd);
7456 NewAnd->setOperand(0,
Load);
7459 for (
auto *
And : AndsToMaybeRemove)
7464 if (&*CurInstIterator ==
And)
7465 CurInstIterator = std::next(
And->getIterator());
7466 And->eraseFromParent();
7471 for (
auto *Inst : DropFlags)
7485 TTI->isExpensiveToSpeculativelyExecute(
I);
7503 uint64_t Max = std::max(TrueWeight, FalseWeight);
7504 uint64_t Sum = TrueWeight + FalseWeight;
7507 if (Probability >
TTI->getPredictableBranchThreshold())
7517 if (!Cmp || !Cmp->hasOneUse())
7540 assert(DefSI->getCondition() ==
SI->getCondition() &&
7541 "The condition of DefSI does not match with SI");
7542 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7545 assert(V &&
"Failed to get select true/false value");
7549bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7573 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7574 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7575 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7576 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7582bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7584 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7585 "Expected a funnel shift");
7609 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7610 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7611 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7619bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7620 if (!Opts.cgp_select2branch)
7624 if (!Opts.disable_select_optimize)
7631 It !=
SI->getParent()->
end(); ++It) {
7633 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7640 SelectInst *LastSI = ASI.
back();
7643 CurInstIterator = std::next(LastSI->
getIterator());
7647 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7648 fixupDbgVariableRecordsOnInst(*SI);
7650 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7653 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7656 TargetLowering::SelectSupportKind SelectKind;
7657 if (
SI->getType()->isVectorTy())
7658 SelectKind = TargetLowering::ScalarCondVectorVal;
7660 SelectKind = TargetLowering::ScalarValSelect;
7697 SmallVector<Instruction *> TrueInstrs, FalseInstrs;
7698 for (SelectInst *SI : ASI) {
7710 SplitPt.setHeadBit(
true);
7713 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7718 UncondBrInst *TrueBranch =
nullptr;
7719 UncondBrInst *FalseBranch =
nullptr;
7720 if (TrueInstrs.
size() == 0) {
7725 }
else if (FalseInstrs.
size() == 0) {
7742 EndBlock->
setName(
"select.end");
7744 TrueBlock->
setName(
"select.true.sink");
7746 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7747 :
"select.false.sink");
7751 FreshBBs.
insert(TrueBlock);
7753 FreshBBs.
insert(FalseBlock);
7754 FreshBBs.
insert(EndBlock);
7759 static const unsigned MD[] = {
7760 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7761 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7766 for (Instruction *
I : TrueInstrs)
7768 for (Instruction *
I : FalseInstrs)
7775 if (TrueBlock ==
nullptr)
7776 TrueBlock = StartBlock;
7777 else if (FalseBlock ==
nullptr)
7778 FalseBlock = StartBlock;
7794 SI->eraseFromParent();
7796 ++NumSelectsExpanded;
7800 CurInstIterator = StartBlock->
end();
7807bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7819 "Expected a type of the same size!");
7825 Value *BC1 = Builder.CreateBitCast(
7827 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7828 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7832 SVI, TLInfo,
nullptr,
7833 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7840 !
Op->isTerminator() && !
Op->isEHPad())
7846bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7861 for (Use *U :
reverse(OpsToSink)) {
7873 SetVector<Instruction *> MaybeDead;
7874 DenseMap<Instruction *, Instruction *> NewInstructions;
7875 for (Use *U : ToReplace) {
7884 FreshBBs.
insert(OpDef->getParent());
7887 NewInstructions[UI] = NI;
7892 InsertedInsts.insert(NI);
7898 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
7899 It->second->setOperand(
U->getOperandNo(), NI);
7906 for (
auto *
I : MaybeDead) {
7907 if (!
I->hasNUsesOrMore(1)) {
7909 I->eraseFromParent();
7916bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
7922 unsigned RegWidth =
RegType.getSizeInBits();
7933 auto *NewType = Type::getIntNTy(
Context, RegWidth);
7942 ExtType = Instruction::SExt;
7945 if (Arg->hasSExtAttr())
7946 ExtType = Instruction::SExt;
7947 if (Arg->hasZExtAttr())
7948 ExtType = Instruction::ZExt;
7954 SI->setCondition(ExtInst);
7955 for (
auto Case :
SI->cases()) {
7956 const APInt &NarrowConst = Case.getCaseValue()->getValue();
7957 APInt WideConst = (ExtType == Instruction::ZExt)
7958 ? NarrowConst.
zext(RegWidth)
7959 : NarrowConst.
sext(RegWidth);
7960 Case.setValue(ConstantInt::get(
Context, WideConst));
7966bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
7973 Value *Condition =
SI->getCondition();
7982 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
7983 ConstantInt *CaseValue = Case.getCaseValue();
7984 BasicBlock *CaseBB = Case.getCaseSuccessor();
7987 bool CheckedForSinglePred =
false;
7988 for (PHINode &
PHI : CaseBB->
phis()) {
7989 Type *PHIType =
PHI.getType();
7997 if (PHIType == ConditionType || TryZExt) {
7999 bool SkipCase =
false;
8000 Value *Replacement =
nullptr;
8001 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
8002 Value *PHIValue =
PHI.getIncomingValue(
I);
8003 if (PHIValue != CaseValue) {
8012 if (
PHI.getIncomingBlock(
I) != SwitchBB)
8017 if (!CheckedForSinglePred) {
8018 CheckedForSinglePred =
true;
8019 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
8025 if (Replacement ==
nullptr) {
8026 if (PHIValue == CaseValue) {
8027 Replacement = Condition;
8030 Replacement = Builder.CreateZExt(Condition, PHIType);
8033 PHI.setIncomingValue(
I, Replacement);
8044bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
8045 bool Changed = optimizeSwitchType(SI);
8046 Changed |= optimizeSwitchPhiConstants(SI);
8067class VectorPromoteHelper {
8069 const DataLayout &
DL;
8072 const TargetLowering &TLI;
8075 const TargetTransformInfo &
TTI;
8081 SmallVector<Instruction *, 4> InstsToBePromoted;
8084 unsigned StoreExtractCombineCost;
8086 bool StressStoreExtract;
8095 if (InstsToBePromoted.
empty())
8097 return InstsToBePromoted.
back();
8103 unsigned getTransitionOriginalValueIdx()
const {
8105 "Other kind of transitions are not supported yet");
8112 unsigned getTransitionIdx()
const {
8114 "Other kind of transitions are not supported yet");
8122 Type *getTransitionType()
const {
8133 void promoteImpl(Instruction *ToBePromoted);
8137 bool isProfitableToPromote() {
8138 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8142 Type *PromotedType = getTransitionType();
8145 unsigned AS =
ST->getPointerAddressSpace();
8163 for (
const auto &Inst : InstsToBePromoted) {
8171 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8183 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8184 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8185 return ScalarCost > VectorCost;
8197 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8212 if (!
EC.isScalable()) {
8213 SmallVector<Constant *, 4> ConstVec;
8215 for (
unsigned Idx = 0;
Idx !=
EC.getKnownMinValue(); ++
Idx) {
8216 if (Idx == ExtractIdx)
8224 "Generate scalable vector for non-splat is unimplemented");
8229 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8230 unsigned OperandIdx) {
8233 if (OperandIdx != 1)
8235 switch (
Use->getOpcode()) {
8238 case Instruction::SDiv:
8239 case Instruction::UDiv:
8240 case Instruction::SRem:
8241 case Instruction::URem:
8243 case Instruction::FDiv:
8244 case Instruction::FRem:
8245 return !
Use->hasNoNaNs();
8251 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8252 const TargetTransformInfo &
TTI, Instruction *Transition,
8253 unsigned CombineCost,
bool StressStoreExtract)
8254 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8255 StoreExtractCombineCost(CombineCost),
8256 StressStoreExtract(StressStoreExtract) {
8257 assert(Transition &&
"Do not know how to promote null");
8261 bool canPromote(
const Instruction *ToBePromoted)
const {
8268 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8273 for (
const Use &U : ToBePromoted->
operands()) {
8274 const Value *Val =
U.get();
8275 if (Val == getEndOfTransition()) {
8286 return StressStoreExtract ||
8297 void enqueueForPromotion(Instruction *ToBePromoted) {
8298 InstsToBePromoted.push_back(ToBePromoted);
8302 void recordCombineInstruction(Instruction *ToBeCombined) {
8304 CombineInst = ToBeCombined;
8314 if (InstsToBePromoted.empty() || !CombineInst)
8318 if (!StressStoreExtract && !isProfitableToPromote())
8322 for (
auto &ToBePromoted : InstsToBePromoted)
8323 promoteImpl(ToBePromoted);
8324 InstsToBePromoted.clear();
8331void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8341 "The type of the result of the transition does not match "
8346 Type *TransitionTy = getTransitionType();
8351 for (Use &U : ToBePromoted->
operands()) {
8353 Value *NewVal =
nullptr;
8354 if (Val == Transition)
8355 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8362 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8366 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8369 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8375bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8376 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8377 if (!Opts.cgp_store_extract ||
8378 (!Opts.cgp_stress_store_extract &&
8391 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8392 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost,
8393 Opts.cgp_stress_store_extract);
8400 if (ToBePromoted->
getParent() != Parent) {
8401 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8403 <<
") than the transition (" << Parent->
getName()
8408 if (VPH.canCombine(ToBePromoted)) {
8410 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8411 VPH.recordCombineInstruction(ToBePromoted);
8413 NumStoreExtractExposed +=
Changed;
8418 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8421 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8423 VPH.enqueueForPromotion(ToBePromoted);
8424 Inst = ToBePromoted;
8463 bool ForceSplitStore) {
8465 Type *StoreType =
SI.getValueOperand()->getType();
8474 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8475 DL.getTypeSizeInBits(StoreType) == 0)
8478 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8480 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8496 if (!
match(
SI.getValueOperand(),
8503 if (!
LValue->getType()->isIntegerTy() ||
8504 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8506 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8525 if (LBC && LBC->getParent() !=
SI.getParent())
8526 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8527 if (HBC && HBC->getParent() !=
SI.getParent())
8528 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8530 bool IsLE =
SI.getDataLayout().isLittleEndian();
8531 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8532 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8533 Value *Addr =
SI.getPointerOperand();
8534 Align Alignment =
SI.getAlign();
8535 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8536 if (IsOffsetStore) {
8537 Addr = Builder.CreateGEP(
8538 SplitStoreType, Addr,
8546 Builder.CreateAlignedStore(V, Addr, Alignment);
8549 CreateSplitStore(
LValue,
false);
8550 CreateSplitStore(HValue,
true);
8553 SI.eraseFromParent();
8561 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8643 if (GEPIOpI->getParent() != SrcBlock)
8648 if (auto *I = dyn_cast<Instruction>(Usr)) {
8649 if (I->getParent() != SrcBlock) {
8657 std::vector<GetElementPtrInst *> UGEPIs;
8660 for (User *Usr : GEPIOp->
users()) {
8679 if (UGEPI->getOperand(0) != GEPIOp)
8681 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8683 if (GEPIIdx->getType() !=
8691 UGEPIs.push_back(UGEPI);
8693 if (UGEPIs.size() == 0)
8696 for (GetElementPtrInst *UGEPI : UGEPIs) {
8698 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8705 for (GetElementPtrInst *UGEPI : UGEPIs) {
8706 UGEPI->setOperand(0, GEPI);
8708 auto NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8709 Constant *NewUGEPIIdx = ConstantInt::get(GEPIIdx->getType(), NewIdx);
8710 UGEPI->setOperand(1, NewUGEPIIdx);
8712 auto SourceFlags = GEPI->getNoWrapFlags();
8715 UGEPI->getNoWrapFlags().intersectForOffsetAdd(SourceFlags);
8717 if (NewIdx.
isNegative() && TargetFlags.hasNoUnsignedWrap())
8718 TargetFlags = TargetFlags.withoutNoUnsignedWrap();
8719 UGEPI->setNoWrapFlags(TargetFlags);
8725 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8727 "GEPIOp is used outside SrcBlock");
8751 Value *
X = Cmp->getOperand(0);
8752 if (!
X->hasUseList())
8757 for (
auto *U :
X->users()) {
8761 (UI->
getParent() != Branch->getParent() &&
8762 UI->
getParent() != Branch->getSuccessor(0) &&
8763 UI->
getParent() != Branch->getSuccessor(1)) ||
8764 (UI->
getParent() != Branch->getParent() &&
8765 !UI->
getParent()->getSinglePredecessor()))
8771 if (UI->
getParent() != Branch->getParent())
8775 ConstantInt::get(UI->
getType(), 0));
8777 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8781 if (Cmp->isEquality() &&
8786 if (UI->
getParent() != Branch->getParent())
8789 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8790 ConstantInt::get(UI->
getType(), 0));
8792 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8800bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8801 bool AnyChange =
false;
8802 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8806 if (InsertedInsts.count(
I))
8815 LargeOffsetGEPMap.erase(
P);
8817 P->eraseFromParent();
8848 I, LI->getLoopFor(
I->getParent()), *
TTI))
8856 TargetLowering::TypeExpandInteger) {
8860 I, LI->getLoopFor(
I->getParent()), *
TTI))
8863 bool MadeChange = optimizeExt(
I);
8864 return MadeChange | optimizeExtUses(
I);
8871 if (optimizeCmp(Cmp, ModifiedDT))
8875 if (optimizeURem(
I))
8879 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8880 bool Modified = optimizeLoadExt(LI);
8889 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8890 unsigned AS =
SI->getPointerAddressSpace();
8891 return optimizeMemoryInst(
I,
SI->getOperand(1),
8892 SI->getOperand(0)->getType(), AS);
8896 unsigned AS = RMW->getPointerAddressSpace();
8897 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
8901 unsigned AS = CmpX->getPointerAddressSpace();
8902 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
8903 CmpX->getCompareOperand()->getType(), AS);
8908 if (BinOp && BinOp->
getOpcode() == Instruction::And &&
8909 Opts.cgp_andcmp_sinking &&
8914 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
8915 BinOp->
getOpcode() == Instruction::LShr)) {
8923 if (GEPI->hasAllZeroIndices()) {
8925 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
8926 GEPI->getName(), GEPI->getIterator());
8927 NC->setDebugLoc(GEPI->getDebugLoc());
8930 GEPI, TLInfo,
nullptr,
8931 [&](
Value *V) { removeAllAssertingVHReferences(V); });
8933 optimizeInst(
NC, ModifiedDT);
8951 if (Const0 || Const1) {
8952 if (!Const0 || !Const1) {
8953 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
8959 FI->eraseFromParent();
8967 if (
I->getType()->isVectorTy() &&
8971 if (tryToSinkFreeOperands(
I))
8974 switch (
I->getOpcode()) {
8975 case Instruction::Shl:
8976 case Instruction::LShr:
8977 case Instruction::AShr:
8979 case Instruction::Call:
8981 case Instruction::Select:
8983 case Instruction::ShuffleVector:
8985 case Instruction::Switch:
8987 case Instruction::ExtractElement:
8989 case Instruction::CondBr:
8998bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
8999 if (!
I.getType()->isIntegerTy() ||
9004 SmallVector<Instruction *, 4> Insts;
9010 &
I, TLInfo,
nullptr,
9011 [&](
Value *V) { removeAllAssertingVHReferences(V); });
9018bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
9020 bool MadeChange =
false;
9023 CurInstIterator = BB.
begin();
9024 ModifiedDT = ModifyDT::NotModifyDT;
9025 while (CurInstIterator != BB.
end()) {
9026 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
9027 if (ModifiedDT != ModifyDT::NotModifyDT) {
9036 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
9038 bool MadeBitReverse =
true;
9039 while (MadeBitReverse) {
9040 MadeBitReverse =
false;
9042 if (makeBitReverse(
I)) {
9043 MadeBitReverse = MadeChange =
true;
9048 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
9053bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
9054 bool AnyChange =
false;
9055 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
9056 AnyChange |= fixupDbgVariableRecord(DVR);
9062bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
9063 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
9064 DVR.
Type != DbgVariableRecord::LocationType::Assign)
9068 bool AnyChange =
false;
9069 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
9071 for (
Value *Location : LocationOps) {
9072 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9101bool CodeGenPrepare::placeDbgValues(
Function &
F) {
9102 bool MadeChange =
false;
9103 DominatorTree &DT = getDT();
9105 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9106 SmallVector<Instruction *, 4> VIs;
9107 for (
Value *V : DbgItem->location_ops())
9115 for (Instruction *VI : VIs) {
9116 if (
VI->isTerminator())
9121 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9132 if (VIs.size() > 1) {
9135 <<
"Unable to find valid location for Debug Value, undefing:\n"
9137 DbgItem->setKillLocation();
9142 << *DbgItem <<
' ' << *VI);
9149 for (BasicBlock &BB :
F) {
9155 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9157 DbgProcessor(&DVR, &Insn);
9168bool CodeGenPrepare::placePseudoProbes(
Function &
F) {
9169 bool MadeChange =
false;
9172 auto FirstInst =
Block.getFirstInsertionPt();
9177 while (
I !=
Block.end()) {
9179 II->moveBefore(FirstInst);
9209bool CodeGenPrepare::splitBranchCondition(
Function &
F) {
9213 bool MadeChange =
false;
9214 for (
auto &BB :
F) {
9227 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9235 Value *Cond1, *Cond2;
9238 Opc = Instruction::And;
9241 Opc = Instruction::Or;
9251 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9265 Br1->setCondition(Cond1);
9270 if (
Opc == Instruction::And)
9271 Br1->setSuccessor(0, TmpBB);
9273 Br1->setSuccessor(1, TmpBB);
9278 I->removeFromParent();
9279 I->insertBefore(Br2->getIterator());
9291 if (
Opc == Instruction::Or)
9295 TBB->replacePhiUsesWith(&BB, TmpBB);
9298 for (PHINode &PN : FBB->
phis()) {
9303 if (
Loop *L = LI->getLoopFor(&BB))
9304 L->addBasicBlockToLoop(TmpBB, *LI);
9308 DTU->
applyUpdates({{DominatorTree::Insert, &BB, TmpBB},
9309 {DominatorTree::Insert, TmpBB,
TBB},
9310 {DominatorTree::Insert, TmpBB, FBB},
9311 {DominatorTree::Delete, &BB,
TBB}});
9315 if (
Opc == Instruction::Or) {
9337 uint64_t NewTrueWeight = TrueWeight;
9338 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9342 NewTrueWeight = TrueWeight;
9343 NewFalseWeight = 2 * FalseWeight;
9368 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9369 uint64_t NewFalseWeight = FalseWeight;
9373 NewTrueWeight = 2 * TrueWeight;
9374 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 const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
LLVM_ABI InstListType::const_iterator getFirstNonPHIOrPseudoProbe() const
Returns an iterator to the first instruction in this block that is not a PHINode or a pseudo operatio...
LLVM_ABI void insertDbgRecordAfter(DbgRecord *DR, Instruction *I)
Insert a DbgRecord into a block at the position given by I.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
This class represents a no-op cast from one type to another.
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI void setBlockFreq(const BasicBlock *BB, BlockFrequency Freq)
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
Analysis pass which computes BranchProbabilityInfo.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
Predicate getPredicate() const
Return the predicate for this instruction.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Conditional Branch instruction.
static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI void removeFromParent()
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LocationType Type
Classification of the debug-info record that this DbgVariableRecord represents.
LLVM_ABI void replaceVariableLocationOp(Value *OldValue, Value *NewValue, bool AllowEmpty=false)
LLVM_ABI iterator_range< location_op_iterator > location_ops() const
Get the locations corresponding to the variable referenced by the debug info intrinsic.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
LLVM_ABI void deleteBB(BasicBlock *DelBB)
Delete DelBB.
Analysis pass which computes a DominatorTree.
static constexpr UpdateKind Insert
Legacy analysis pass which computes a DominatorTree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This instruction compares its operands according to the predicate given to the constructor.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionPass class - This class is used to implement most global optimizations.
const BasicBlock & getEntryBlock() const
LLVM_ABI const Value * getStatepoint() const
The statepoint with which this gc.relocate is associated.
Represents calls to the gc.relocate intrinsic.
unsigned getBasePtrIndex() const
The index into the associate statepoint's argument list which contains the base pointer of the pointe...
void compute(FunctionT &F)
Compute the cycle info for a function.
DomTreeT & getDomTree()
Flush DomTree updates and return DomTree.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
void flush()
Apply all pending updates to available trees and flush all BasicBlocks awaiting deletion.
bool isBBPendingDeletion(BasicBlockT *DelBB) const
Returns true if DelBB is awaiting deletion.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static LLVM_ABI Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)
Returns the result type of a getelementptr with the given source element type and indexes.
LLVM_ABI bool canIncreaseAlignment() const
Returns true if the alignment of the value can be unilaterally increased.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This instruction compares its operands according to the predicate given to the constructor.
bool isEquality() const
Return true if this predicate is either EQ or NE.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
user_iterator_impl< Instruction > user_iterator
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
LLVM_ABI void moveAfter(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
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 optimizeVectorCrossLaneOperation(Instruction *I, Loop *L) const
virtual bool shouldAlignPointerArgs(CallInst *, unsigned &, Align &) const
Return true if the pointer arguments to CI should be aligned by aligning the object whose address is ...
virtual Type * shouldConvertSplatType(ShuffleVectorInst *SVI) const
Given a shuffle vector SVI representing a vector splat, return a new scalar type of size equal to SVI...
bool isLoadLegal(EVT ValVT, EVT MemVT, Align Alignment, unsigned AddrSpace, unsigned ExtType, bool Atomic) const
Return true if the specified load with extension is legal on this target.
virtual bool addressingModeSupportsTLS(const GlobalValue &) const
Returns true if the targets addressing mode can target thread local storage (TLS).
virtual bool shouldConvertPhiType(Type *From, Type *To) const
Given a set in interconnected phis of type 'From' that are loaded/stored or bitcast to type 'To',...
virtual bool 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.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI void SplitBlockAndInsertIfThenElse(Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
generic_gep_type_iterator<> gep_type_iterator
LLVM_ABI FunctionPass * createCodeGenPrepareLegacyPass()
createCodeGenPrepareLegacyPass - Transform the code to expose more pattern matching during instructio...
LLVM_ABI ISD::CondCode getFCmpCondCode(FCmpInst::Predicate Pred)
getFCmpCondCode - Return the ISD condition code corresponding to the given LLVM IR floating-point con...
LLVM_ABI bool VerifyLoopInfo
Enable verification of loop info.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI bool attributesPermitTailCall(const Function *F, const Instruction *I, const ReturnInst *Ret, const TargetLoweringBase &TLI, bool *AllowDifferingSizes=nullptr)
Test if given that the input instruction is in the tail call position, if there is an attribute misma...
LLVM_ABI bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false, DominatorTree *DT=nullptr)
Attempts to merge a block into its predecessor, if possible.
@ Or
Bitwise or logical OR of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I, bool IgnoreUBImplyingAttrs=true)
Don't use information from its non-constant operands.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI bool VerifyDomInfo
Enables verification of dominator trees.
constexpr unsigned BitWidth
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
constexpr bool valueOr(BoolOrDefault X, bool Default)
constexpr std::enable_if_t< std::is_signed_v< T >, std::pair< T, bool > > MulOverflow(T X, T Y)
Multiply two signed integers, computing the two's complement truncated result, returning a pair {resu...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
bool pred_empty(const BasicBlock *BB)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
LLVM_ABI void setFittedBranchWeights(Instruction &I, ArrayRef< uint64_t > Weights, bool IsExpected, bool ElideAllZero=false)
Variant of setBranchWeights where the Weights will be fit first to uint32_t by shifting right.
std::pair< Value *, FPClassTest > fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, Value *RHS, bool LookThroughSrc=true)
Returns a pair of values, which if passed to llvm.is.fpclass, returns the same result as an fcmp with...
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
LLVM_ABI Value * simplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a URem, fold the result or return null.
DenseMap< const Value *, Value * > ValueToValueMap
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool isRound() const
Return true if the size is a power-of-two number of bytes.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
bool isInteger() const
Return true if this is an integer or a vector integer type.
This contains information for each constraint that we are lowering.