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());
1204 Value *Replacement = Builder.CreateGEP(Derived->getSourceElementType(),
1207 ToReplace->replaceAllUsesWith(Replacement);
1208 ToReplace->eraseFromParent();
1232bool CodeGenPrepare::simplifyOffsetableRelocate(GCStatepointInst &
I) {
1233 bool MadeChange =
false;
1235 for (
auto *U :
I.users())
1242 if (AllRelocateCalls.
size() < 2)
1247 MapVector<GCRelocateInst *, SmallVector<GCRelocateInst *, 0>> RelocateInstMap;
1249 if (RelocateInstMap.
empty())
1252 for (
auto &Item : RelocateInstMap)
1266 bool MadeChange =
false;
1269 Use &TheUse = UI.getUse();
1276 UserBB = PN->getIncomingBlock(TheUse);
1284 if (
User->isEHPad())
1294 if (UserBB == DefBB)
1298 CastInst *&InsertedCast = InsertedCasts[UserBB];
1300 if (!InsertedCast) {
1308 TheUse = InsertedCast;
1327 if (!SrcInst || SrcInst->getParent() == BCI->
getParent() ||
1328 SrcInst->isTerminator())
1332 Type *SrcTy = SrcInst->getType();
1346 bool IsCrossDomain = DestTy->
isFPOrFPVectorTy() != SrcTy->isFPOrFPVectorTy();
1349 unsigned NativeWidth =
DL.getPointerSizeInBits();
1350 bool IsLargeScalar =
1352 DL.getTypeSizeInBits(DestTy).getFixedValue() > NativeWidth;
1354 if (IsCrossDomain || IsLargeScalar)
1360 : std::next(SrcInst->getIterator());
1377 ASC->getDestAddressSpace()))
1432static std::optional<std::pair<Instruction *, Constant *>>
1435 if (!L || L->getHeader() != PN->
getParent() || !L->getLoopLatch())
1436 return std::nullopt;
1439 if (!IVInc || LI->
getLoopFor(IVInc->getParent()) != L)
1440 return std::nullopt;
1444 return std::make_pair(IVInc, Step);
1445 return std::nullopt;
1458 return IVInc->first ==
I;
1462bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
1466 auto IsReplacableIVIncrement = [
this, &
Cmp](BinaryOperator *BO) {
1470 assert(L &&
"L should not be null after isIVIncrement()");
1472 if (LI->getLoopFor(
Cmp->getParent()) != L)
1485 return BO->
hasOneUse() && DT.dominates(
Cmp->getParent(),
L->getLoopLatch());
1487 if (BO->
getParent() !=
Cmp->getParent() && !IsReplacableIVIncrement(BO)) {
1510 if (BO->
getOpcode() == Instruction::Add &&
1511 IID == Intrinsic::usub_with_overflow) {
1518 for (Instruction &Iter : *
Cmp->getParent()) {
1521 if ((BO->
getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) {
1526 assert(InsertPt !=
nullptr &&
"Parent block did not contain cmp or binop");
1529 Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);
1530 if (BO->
getOpcode() != Instruction::Xor) {
1531 Value *Math = Builder.CreateExtractValue(MathOV, 0,
"math");
1535 "Patterns with XOr should use the BO only in the compare");
1536 Value *OV = Builder.CreateExtractValue(MathOV, 1,
"ov");
1538 Cmp->eraseFromParent();
1548 Value *
A = Cmp->getOperand(0), *
B = Cmp->getOperand(1);
1556 B = ConstantInt::get(
B->getType(), 1);
1564 for (
User *U :
A->users()) {
1575bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp,
1576 ModifyDT &ModifiedDT) {
1577 bool EdgeCase =
false;
1579 BinaryOperator *
Add;
1584 A =
Add->getOperand(0);
1585 B =
Add->getOperand(1);
1591 Add->hasNUsesOrMore(EdgeCase ? 1 : 2)))
1597 if (
Add->getParent() !=
Cmp->getParent() && !
Add->hasOneUse())
1600 if (!replaceMathCmpWithIntrinsic(
Add,
A,
B, Cmp,
1601 Intrinsic::uadd_with_overflow))
1605 ModifiedDT = ModifyDT::ModifyInstDT;
1609bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
1610 ModifyDT &ModifiedDT) {
1617 ICmpInst::Predicate Pred =
Cmp->getPredicate();
1618 if (Pred == ICmpInst::ICMP_UGT) {
1620 Pred = ICmpInst::ICMP_ULT;
1624 B = ConstantInt::get(
B->getType(), 1);
1625 Pred = ICmpInst::ICMP_ULT;
1630 Pred = ICmpInst::ICMP_ULT;
1632 if (Pred != ICmpInst::ICMP_ULT)
1639 BinaryOperator *
Sub =
nullptr;
1640 for (User *U : CmpVariableOperand->
users()) {
1648 const APInt *CmpC, *AddC;
1660 Sub->hasNUsesOrMore(1)))
1666 if (
Sub->getParent() !=
Cmp->getParent() && !
Sub->hasOneUse())
1669 if (!replaceMathCmpWithIntrinsic(
Sub,
Sub->getOperand(0),
Sub->getOperand(1),
1670 Cmp, Intrinsic::usub_with_overflow))
1674 ModifiedDT = ModifyDT::ModifyInstDT;
1681bool CodeGenPrepare::unfoldPowerOf2Test(CmpInst *Cmp) {
1694 if (!IsStrictlyPowerOf2Test && !IsPowerOf2OrZeroTest)
1700 Type *OpTy =
X->getType();
1708 if (Pred == ICmpInst::ICMP_EQ) {
1709 Cmp->setOperand(1, ConstantInt::get(OpTy, 2));
1710 Cmp->setPredicate(ICmpInst::ICMP_ULT);
1712 Cmp->setPredicate(ICmpInst::ICMP_UGT);
1718 if (IsPowerOf2OrZeroTest ||
1729 NewCmp = Builder.CreateICmp(NewPred,
And, ConstantInt::getNullValue(OpTy));
1738 NewCmp = Builder.CreateICmp(NewPred,
Xor,
Sub);
1741 Cmp->replaceAllUsesWith(NewCmp);
1761 bool UsedInPhiOrCurrentBlock =
any_of(Cmp->users(), [Cmp](
User *U) {
1762 return isa<PHINode>(U) ||
1763 cast<Instruction>(U)->getParent() == Cmp->getParent();
1768 if (UsedInPhiOrCurrentBlock && Cmp->getOperand(0)->getType()->isIntegerTy() &&
1769 Cmp->getOperand(0)->getType()->getScalarSizeInBits() >
1770 DL.getLargestLegalIntTypeSizeInBits())
1776 bool MadeChange =
false;
1779 Use &TheUse = UI.getUse();
1794 if (UserBB == DefBB)
1798 CmpInst *&InsertedCmp = InsertedCmps[UserBB];
1804 Cmp->getOperand(0), Cmp->getOperand(1),
"");
1811 TheUse = InsertedCmp;
1817 if (Cmp->use_empty()) {
1818 Cmp->eraseFromParent();
1845 bool EnableICmpEqToICmpSt) {
1855 for (
User *U : Cmp->users()) {
1877 if (CmpBB != FalseBB)
1880 Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
1894 for (
User *U : Cmp->users()) {
1896 BI->swapSuccessors();
1902 SI->swapProfMetadata();
1914 Value *Op0 = Cmp->getOperand(0);
1915 Value *Op1 = Cmp->getOperand(1);
1924 unsigned NumInspected = 0;
1927 if (++NumInspected > 128)
1935 if (GoodToSwap > 0) {
1936 Cmp->swapOperands();
1956 auto ShouldReverseTransform = [](
FPClassTest ClassTest) {
1959 auto [ClassVal, ClassTest] =
1965 if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest))
1969 Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest);
1970 Cmp->replaceAllUsesWith(IsFPClass);
1978 Value *Incr, *RemAmt;
1983 Value *AddInst, *AddOffset;
1986 if (PN !=
nullptr) {
1988 AddOffset =
nullptr;
2006 if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
2010 if (!L->contains(Rem))
2014 if (!L->isLoopInvariant(RemAmt))
2018 if (AddOffset && !L->isLoopInvariant(AddOffset))
2039 AddInstOut = AddInst;
2040 AddOffsetOut = AddOffset;
2059 Value *AddOffset, *RemAmt, *AddInst;
2062 AddOffset, LoopIncrPN))
2087 assert(AddOffset &&
"We found an add but missing values");
2105 PHINode *NewRem = Builder.CreatePHI(Ty, 2);
2110 Value *RemAdd = Builder.CreateNUWAdd(NewRem, ConstantInt::get(Ty, 1));
2115 NewRem->
addIncoming(Start, L->getLoopPreheader());
2120 FreshBBs.
insert(L->getLoopLatch());
2131bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2137bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
2141 if (combineToUAddWithOverflow(Cmp, ModifiedDT))
2144 if (combineToUSubWithOverflow(Cmp, ModifiedDT))
2147 if (unfoldPowerOf2Test(Cmp))
2168 SetOfInstrs &InsertedInsts) {
2171 assert(!InsertedInsts.count(AndI) &&
2172 "Attempting to optimize already optimized and instruction");
2173 (void)InsertedInsts;
2187 for (
auto *U : AndI->
users()) {
2195 if (!CmpC || !CmpC->
isZero())
2210 Use &TheUse = UI.getUse();
2228 TheUse = InsertedAnd;
2245 if (
User->getOpcode() != Instruction::And ||
2251 if ((Cimm & (Cimm + 1)).getBoolValue())
2265 bool MadeChange =
false;
2268 TruncE = TruncI->user_end();
2269 TruncUI != TruncE;) {
2271 Use &TruncTheUse = TruncUI.getUse();
2296 if (UserBB == TruncUserBB)
2300 CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB];
2302 if (!InsertedShift && !InsertedTrunc) {
2306 if (ShiftI->
getOpcode() == Instruction::AShr)
2308 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2311 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2319 TruncInsertPt.setHeadBit(
true);
2320 assert(TruncInsertPt != TruncUserBB->
end());
2324 InsertedTrunc->
insertBefore(*TruncUserBB, TruncInsertPt);
2325 InsertedTrunc->
setDebugLoc(TruncI->getDebugLoc());
2329 TruncTheUse = InsertedTrunc;
2362 bool MadeChange =
false;
2366 Use &TheUse = UI.getUse();
2380 if (UserBB == DefBB) {
2408 if (!InsertedShift) {
2412 if (ShiftI->
getOpcode() == Instruction::AShr)
2414 BinaryOperator::CreateAShr(ShiftI->
getOperand(0), CI,
"");
2417 BinaryOperator::CreateLShr(ShiftI->
getOperand(0), CI,
"");
2425 TheUse = InsertedShift;
2473 unsigned SizeInBits = Ty->getScalarSizeInBits();
2474 if (Ty->isVectorTy())
2485 nullptr,
"cond.false");
2487 FreshBBs.
insert(CallBlock);
2494 SplitPt.setHeadBit(
true);
2496 nullptr,
"cond.end");
2498 FreshBBs.
insert(EndBlock);
2502 Builder.SetCurrentDebugLocation(CountZeros->
getDebugLoc());
2509 Op = Builder.CreateFreeze(
Op,
Op->getName() +
".fr");
2510 Value *Cmp = Builder.CreateICmpEQ(
Op, Zero,
"cmpz");
2511 Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
2517 Builder.SetInsertPoint(EndBlock->
begin());
2518 PHINode *PN = Builder.CreatePHI(Ty, 2,
"ctz");
2528 ModifiedDT = ModifyDT::ModifyBBDT;
2532bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
2536 if (CI->
isInlineAsm() && optimizeInlineAsmInst(CI))
2544 for (
auto &Arg : CI->
args()) {
2549 if (!Arg->getType()->isPointerTy())
2551 APInt
Offset(
DL->getIndexSizeInBits(
2554 Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*
DL,
Offset);
2561 if (AllocaSize && AllocaSize->getKnownMinValue() >= MinSize + Offset2)
2579 MaybeAlign MIDestAlign =
MI->getDestAlign();
2580 if (!MIDestAlign || DestAlign > *MIDestAlign)
2581 MI->setDestAlignment(DestAlign);
2583 MaybeAlign MTISrcAlign = MTI->getSourceAlign();
2585 if (!MTISrcAlign || SrcAlign > *MTISrcAlign)
2586 MTI->setSourceAlignment(SrcAlign);
2596 for (
auto &Arg : CI->
args()) {
2597 if (!Arg->getType()->isPointerTy())
2599 unsigned AS = Arg->getType()->getPointerAddressSpace();
2600 if (optimizeMemoryInst(CI, Arg, Arg->getType(), AS))
2606 switch (
II->getIntrinsicID()) {
2609 case Intrinsic::assume:
2611 case Intrinsic::allow_runtime_check:
2612 case Intrinsic::allow_ubsan_check:
2613 case Intrinsic::experimental_widenable_condition: {
2617 if (
II->use_empty()) {
2618 II->eraseFromParent();
2622 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
2627 case Intrinsic::objectsize:
2629 case Intrinsic::is_constant:
2631 case Intrinsic::aarch64_stlxr:
2632 case Intrinsic::aarch64_stxr: {
2641 InsertedInsts.insert(ExtVal);
2645 case Intrinsic::launder_invariant_group: {
2646 Value *ArgVal =
II->getArgOperand(0);
2647 auto it = LargeOffsetGEPMap.
find(
II);
2648 if (it != LargeOffsetGEPMap.
end()) {
2652 auto GEPs = std::move(it->second);
2653 LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
2658 II->eraseFromParent();
2661 case Intrinsic::cttz:
2662 case Intrinsic::ctlz:
2666 case Intrinsic::fshl:
2667 case Intrinsic::fshr:
2668 return optimizeFunnelShift(
II);
2669 case Intrinsic::masked_gather:
2670 return optimizeGatherScatterInst(
II,
II->getArgOperand(0));
2671 case Intrinsic::masked_scatter:
2672 return optimizeGatherScatterInst(
II,
II->getArgOperand(1));
2673 case Intrinsic::masked_load:
2676 if (VT->getNumElements() == 1) {
2677 Value *PtrVal =
II->getArgOperand(0);
2679 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2684 case Intrinsic::masked_store:
2688 if (VT->getNumElements() == 1) {
2689 Value *PtrVal =
II->getArgOperand(1);
2691 if (optimizeMemoryInst(
II, PtrVal, VT->getElementType(), AS))
2696 case Intrinsic::umul_with_overflow:
2697 return optimizeMulWithOverflow(
II,
false, ModifiedDT);
2698 case Intrinsic::smul_with_overflow:
2699 return optimizeMulWithOverflow(
II,
true, ModifiedDT);
2702 SmallVector<Value *, 2> PtrOps;
2705 while (!PtrOps.
empty()) {
2708 if (optimizeMemoryInst(
II, PtrVal, AccessTy, AS))
2722 FortifiedLibCallSimplifier Simplifier(TLInfo,
true);
2724 if (
Value *V = Simplifier.optimizeCall(CI, Builder)) {
2734 auto GetUniformReturnValue = [](
const Function *
F) -> GlobalVariable * {
2735 if (!
F->getReturnType()->isPointerTy())
2738 GlobalVariable *UniformValue =
nullptr;
2739 for (
auto &BB : *
F) {
2744 else if (V != UniformValue)
2752 return UniformValue;
2755 if (
Callee->hasExactDefinition()) {
2756 if (GlobalVariable *RV = GetUniformReturnValue(Callee)) {
2757 bool MadeChange =
false;
2783 switch (
II->getIntrinsicID()) {
2784 case Intrinsic::memset:
2785 case Intrinsic::memcpy:
2786 case Intrinsic::memmove:
2793 if (Callee && TLInfo)
2795 case LibFunc_strcpy:
2796 case LibFunc_strncpy:
2797 case LibFunc_strcat:
2798 case LibFunc_strncat:
2839bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
2840 ModifyDT &ModifiedDT) {
2845 assert(LI->getLoopFor(BB) ==
nullptr &&
"A return block cannot be in a loop");
2847 PHINode *PN =
nullptr;
2848 ExtractValueInst *EVI =
nullptr;
2849 BitCastInst *BCI =
nullptr;
2871 auto isFakeUse = [&FakeUses](
const Instruction *Inst) {
2873 II &&
II->getIntrinsicID() == Intrinsic::fake_use) {
2902 auto MayBePermittedAsTailCall = [&](
const auto *CI) {
2919 MayBePermittedAsTailCall(CI)) {
2940 MayBePermittedAsTailCall(CI)) {
2947 SmallPtrSet<BasicBlock *, 4> VisitedBBs;
2949 if (!VisitedBBs.
insert(Pred).second)
2951 if (Instruction *
I = Pred->rbegin()->getPrevNode()) {
2953 if (CI && CI->
use_empty() && MayBePermittedAsTailCall(CI)) {
2968 for (
auto const &TailCallBB : TailCallBBs) {
2977 assert(!Opts.cgp_verify_bfi_updates ||
2978 BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB));
2979 BFI->setBlockFreq(BB,
2980 (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB)));
2981 ModifiedDT = ModifyDT::ModifyBBDT;
2990 for (
auto *CI : CallInsts) {
2991 for (
auto const *FakeUse : FakeUses) {
2992 auto *ClonedInst = FakeUse->clone();
3010struct ExtAddrMode :
public TargetLowering::AddrMode {
3011 Value *BaseReg =
nullptr;
3012 Value *ScaledReg =
nullptr;
3013 Value *OriginalValue =
nullptr;
3014 bool InBounds =
true;
3018 BaseRegField = 0x01,
3020 BaseOffsField = 0x04,
3021 ScaledRegField = 0x08,
3023 MultipleFields = 0xff
3026 ExtAddrMode() =
default;
3028 void print(raw_ostream &OS)
const;
3035 if (ScaledReg == From)
3039 FieldName
compare(
const ExtAddrMode &other) {
3042 if (BaseReg && other.
BaseReg &&
3044 return MultipleFields;
3045 if (BaseGV && other.BaseGV && BaseGV->getType() != other.BaseGV->getType())
3046 return MultipleFields;
3049 return MultipleFields;
3052 if (InBounds != other.InBounds)
3053 return MultipleFields;
3056 unsigned Result = NoField;
3059 if (BaseGV != other.BaseGV)
3061 if (BaseOffs != other.BaseOffs)
3064 Result |= ScaledRegField;
3067 if (Scale && other.
Scale && Scale != other.
Scale)
3071 return MultipleFields;
3073 return static_cast<FieldName
>(
Result);
3083 return !BaseOffs && !Scale && !(BaseGV &&
BaseReg);
3094 case ScaledRegField:
3101 void SetCombinedField(FieldName
Field,
Value *V,
3102 const SmallVectorImpl<ExtAddrMode> &AddrModes) {
3107 case ExtAddrMode::BaseRegField:
3110 case ExtAddrMode::BaseGVField:
3113 assert(BaseReg ==
nullptr);
3117 case ExtAddrMode::ScaledRegField:
3122 for (
const ExtAddrMode &AM : AddrModes)
3128 case ExtAddrMode::BaseOffsField:
3131 assert(ScaledReg ==
nullptr);
3141static inline raw_ostream &
operator<<(raw_ostream &OS,
const ExtAddrMode &AM) {
3147#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3148void ExtAddrMode::print(raw_ostream &OS)
const {
3149 bool NeedPlus =
false;
3155 BaseGV->printAsOperand(OS,
false);
3160 OS << (NeedPlus ?
" + " :
"") << BaseOffs;
3165 OS << (NeedPlus ?
" + " :
"") <<
"Base:";
3166 BaseReg->printAsOperand(OS,
false);
3170 OS << (NeedPlus ?
" + " :
"") << Scale <<
"*";
3193class TypePromotionTransaction {
3197 class TypePromotionAction {
3205 TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
3207 virtual ~TypePromotionAction() =
default;
3214 virtual void undo() = 0;
3219 virtual void commit() {
3225 class InsertionHandler {
3234 std::optional<DbgRecord::self_iterator> BeforeDbgRecord = std::nullopt;
3237 bool HasPrevInstruction;
3241 InsertionHandler(Instruction *Inst) {
3249 if (HasPrevInstruction) {
3257 void insert(Instruction *Inst) {
3258 if (HasPrevInstruction) {
3270 Inst->
getParent()->reinsertInstInDbgRecords(Inst, BeforeDbgRecord);
3275 class OperandSetter :
public TypePromotionAction {
3284 OperandSetter(Instruction *Inst,
unsigned Idx,
Value *NewVal)
3285 : TypePromotionAction(Inst),
Idx(
Idx) {
3287 <<
"for:" << *Inst <<
"\n"
3288 <<
"with:" << *NewVal <<
"\n");
3294 void undo()
override {
3296 <<
"for: " << *Inst <<
"\n"
3297 <<
"with: " << *Origin <<
"\n");
3304 class OperandsHider :
public TypePromotionAction {
3306 SmallVector<Value *, 4> OriginalValues;
3310 OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) {
3313 OriginalValues.
reserve(NumOpnds);
3314 for (
unsigned It = 0; It < NumOpnds; ++It) {
3326 void undo()
override {
3328 for (
unsigned It = 0, EndIt = OriginalValues.
size(); It != EndIt; ++It)
3334 class TruncBuilder :
public TypePromotionAction {
3341 TruncBuilder(Instruction *Opnd,
Type *Ty) : TypePromotionAction(Opnd) {
3343 Builder.SetCurrentDebugLocation(
DebugLoc());
3344 Val = Builder.CreateTrunc(Opnd, Ty,
"promoted");
3349 Value *getBuiltValue() {
return Val; }
3352 void undo()
override {
3355 IVal->eraseFromParent();
3360 class SExtBuilder :
public TypePromotionAction {
3367 SExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3368 : TypePromotionAction(InsertPt) {
3370 Val = Builder.CreateSExt(Opnd, Ty,
"promoted");
3375 Value *getBuiltValue() {
return Val; }
3378 void undo()
override {
3381 IVal->eraseFromParent();
3386 class ZExtBuilder :
public TypePromotionAction {
3393 ZExtBuilder(Instruction *InsertPt,
Value *Opnd,
Type *Ty)
3394 : TypePromotionAction(InsertPt) {
3396 Builder.SetCurrentDebugLocation(
DebugLoc());
3397 Val = Builder.CreateZExt(Opnd, Ty,
"promoted");
3402 Value *getBuiltValue() {
return Val; }
3405 void undo()
override {
3408 IVal->eraseFromParent();
3413 class TypeMutator :
public TypePromotionAction {
3419 TypeMutator(Instruction *Inst,
Type *NewTy)
3420 : TypePromotionAction(Inst), OrigTy(Inst->
getType()) {
3421 LLVM_DEBUG(
dbgs() <<
"Do: MutateType: " << *Inst <<
" with " << *NewTy
3427 void undo()
override {
3428 LLVM_DEBUG(
dbgs() <<
"Undo: MutateType: " << *Inst <<
" with " << *OrigTy
3435 class UsesReplacer :
public TypePromotionAction {
3437 struct InstructionAndIdx {
3444 InstructionAndIdx(Instruction *Inst,
unsigned Idx)
3445 : Inst(Inst),
Idx(
Idx) {}
3451 SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;
3459 UsesReplacer(Instruction *Inst,
Value *New)
3460 : TypePromotionAction(Inst),
New(
New) {
3461 LLVM_DEBUG(
dbgs() <<
"Do: UsersReplacer: " << *Inst <<
" with " << *New
3464 for (Use &U : Inst->
uses()) {
3466 OriginalUses.
push_back(InstructionAndIdx(UserI,
U.getOperandNo()));
3477 void undo()
override {
3479 for (InstructionAndIdx &Use : OriginalUses)
3480 Use.Inst->setOperand(
Use.Idx, Inst);
3485 for (DbgVariableRecord *DVR : DbgVariableRecords)
3486 DVR->replaceVariableLocationOp(New, Inst);
3491 class InstructionRemover :
public TypePromotionAction {
3493 InsertionHandler Inserter;
3497 OperandsHider Hider;
3500 UsesReplacer *Replacer =
nullptr;
3503 SetOfInstrs &RemovedInsts;
3510 InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
3511 Value *New =
nullptr)
3512 : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
3513 RemovedInsts(RemovedInsts) {
3515 Replacer =
new UsesReplacer(Inst, New);
3516 LLVM_DEBUG(
dbgs() <<
"Do: InstructionRemover: " << *Inst <<
"\n");
3517 RemovedInsts.insert(Inst);
3524 ~InstructionRemover()
override {
delete Replacer; }
3526 InstructionRemover &operator=(
const InstructionRemover &other) =
delete;
3527 InstructionRemover(
const InstructionRemover &other) =
delete;
3531 void undo()
override {
3532 LLVM_DEBUG(
dbgs() <<
"Undo: InstructionRemover: " << *Inst <<
"\n");
3533 Inserter.insert(Inst);
3537 RemovedInsts.erase(Inst);
3545 using ConstRestorationPt =
const TypePromotionAction *;
3547 TypePromotionTransaction(SetOfInstrs &RemovedInsts)
3548 : RemovedInsts(RemovedInsts) {}
3555 void rollback(ConstRestorationPt Point);
3558 ConstRestorationPt getRestorationPoint()
const;
3563 void setOperand(Instruction *Inst,
unsigned Idx,
Value *NewVal);
3572 void mutateType(Instruction *Inst,
Type *NewTy);
3575 Value *createTrunc(Instruction *Opnd,
Type *Ty);
3587 SetOfInstrs &RemovedInsts;
3592void TypePromotionTransaction::setOperand(Instruction *Inst,
unsigned Idx,
3594 Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>(
3595 Inst, Idx, NewVal));
3598void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
3601 std::make_unique<TypePromotionTransaction::InstructionRemover>(
3602 Inst, RemovedInsts, NewVal));
3605void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
3608 std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
3611void TypePromotionTransaction::mutateType(Instruction *Inst,
Type *NewTy) {
3613 std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
3616Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
Type *Ty) {
3617 std::unique_ptr<TruncBuilder> Ptr(
new TruncBuilder(Opnd, Ty));
3618 Value *Val = Ptr->getBuiltValue();
3619 Actions.push_back(std::move(Ptr));
3623Value *TypePromotionTransaction::createSExt(Instruction *Inst,
Value *Opnd,
3625 std::unique_ptr<SExtBuilder> Ptr(
new SExtBuilder(Inst, Opnd, Ty));
3626 Value *Val = Ptr->getBuiltValue();
3627 Actions.push_back(std::move(Ptr));
3631Value *TypePromotionTransaction::createZExt(Instruction *Inst,
Value *Opnd,
3633 std::unique_ptr<ZExtBuilder> Ptr(
new ZExtBuilder(Inst, Opnd, Ty));
3634 Value *Val = Ptr->getBuiltValue();
3635 Actions.push_back(std::move(Ptr));
3639TypePromotionTransaction::ConstRestorationPt
3640TypePromotionTransaction::getRestorationPoint()
const {
3641 return !Actions.empty() ? Actions.back().get() :
nullptr;
3644bool TypePromotionTransaction::commit() {
3645 for (std::unique_ptr<TypePromotionAction> &Action : Actions)
3652void TypePromotionTransaction::rollback(
3653 TypePromotionTransaction::ConstRestorationPt Point) {
3654 while (!Actions.empty() && Point != Actions.back().get()) {
3655 std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
3665class AddressingModeMatcher {
3666 SmallVectorImpl<Instruction *> &AddrModeInsts;
3667 const TargetLowering &TLI;
3668 const TargetRegisterInfo &
TRI;
3669 const DataLayout &
DL;
3671 const std::function<
const DominatorTree &()> getDTFn;
3684 const SetOfInstrs &InsertedInsts;
3687 InstrToOrigTy &PromotedInsts;
3690 TypePromotionTransaction &TPT;
3693 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP;
3697 bool IgnoreProfitability;
3700 bool OptSize =
false;
3702 ProfileSummaryInfo *PSI;
3703 BlockFrequencyInfo *BFI;
3704 const CodeGenOptions &Opts;
3706 AddressingModeMatcher(
3707 SmallVectorImpl<Instruction *> &AMI,
const TargetLowering &TLI,
3708 const TargetRegisterInfo &
TRI,
const LoopInfo &LI,
3709 const std::function<
const DominatorTree &()> getDTFn,
Type *AT,
3710 unsigned AS, Instruction *
MI, ExtAddrMode &AM,
3711 const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
3712 TypePromotionTransaction &TPT,
3713 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3714 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
3715 const CodeGenOptions &Opts)
3716 : AddrModeInsts(AMI), TLI(TLI),
TRI(
TRI),
DL(
MI->getDataLayout()), LI(LI),
3717 getDTFn(getDTFn), AccessTy(AT), AddrSpace(AS), MemoryInst(
MI),
3718 AddrMode(AM), InsertedInsts(InsertedInsts),
3719 PromotedInsts(PromotedInsts), TPT(TPT), LargeOffsetGEP(LargeOffsetGEP),
3720 OptSize(OptSize), PSI(PSI), BFI(BFI), Opts(Opts) {
3721 IgnoreProfitability =
false;
3733 Match(
Value *V,
Type *AccessTy,
unsigned AS, Instruction *MemoryInst,
3734 SmallVectorImpl<Instruction *> &AddrModeInsts,
3735 const TargetLowering &TLI,
const LoopInfo &LI,
3736 const std::function<
const DominatorTree &()> getDTFn,
3737 const TargetRegisterInfo &
TRI,
const SetOfInstrs &InsertedInsts,
3738 InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
3739 std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
3740 bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
3741 const CodeGenOptions &Opts) {
3744 bool Success = AddressingModeMatcher(
3745 AddrModeInsts, TLI,
TRI, LI, getDTFn, AccessTy, AS,
3746 MemoryInst, Result, InsertedInsts, PromotedInsts, TPT,
3747 LargeOffsetGEP, OptSize, PSI, BFI, Opts)
3755 bool matchScaledValue(
Value *ScaleReg, int64_t Scale,
unsigned Depth);
3757 bool matchOperationAddr(User *AddrInst,
unsigned Opcode,
unsigned Depth,
3758 bool *MovedAway =
nullptr);
3759 bool isProfitableToFoldIntoAddressingMode(Instruction *
I,
3760 ExtAddrMode &AMBefore,
3761 ExtAddrMode &AMAfter);
3762 bool valueAlreadyLiveAtInst(
Value *Val,
Value *KnownLive1,
Value *KnownLive2);
3763 bool isPromotionProfitable(
unsigned NewCost,
unsigned OldCost,
3764 Value *PromotedOperand)
const;
3770class PhiNodeSetIterator {
3771 PhiNodeSet *
const Set;
3772 size_t CurrentIndex = 0;
3777 PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start);
3779 PhiNodeSetIterator &operator++();
3795 friend class PhiNodeSetIterator;
3797 using MapType = SmallDenseMap<PHINode *, size_t, 32>;
3798 using iterator = PhiNodeSetIterator;
3813 size_t FirstValidElement = 0;
3819 bool insert(PHINode *Ptr) {
3820 if (NodeMap.insert(std::make_pair(Ptr,
NodeList.
size())).second) {
3830 bool erase(PHINode *Ptr) {
3831 if (NodeMap.erase(Ptr)) {
3832 SkipRemovedElements(FirstValidElement);
3842 FirstValidElement = 0;
3848 if (FirstValidElement == 0)
3849 SkipRemovedElements(FirstValidElement);
3850 return PhiNodeSetIterator(
this, FirstValidElement);
3857 size_t size()
const {
return NodeMap.size(); }
3860 size_t count(PHINode *Ptr)
const {
return NodeMap.count(Ptr); }
3868 void SkipRemovedElements(
size_t &CurrentIndex) {
3870 auto it = NodeMap.find(NodeList[CurrentIndex]);
3873 if (it != NodeMap.end() && it->second == CurrentIndex)
3880PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *
const Set,
size_t Start)
3883PHINode *PhiNodeSetIterator::operator*()
const {
3885 "PhiNodeSet access out of range");
3886 return Set->NodeList[CurrentIndex];
3889PhiNodeSetIterator &PhiNodeSetIterator::operator++() {
3891 "PhiNodeSet access out of range");
3893 Set->SkipRemovedElements(CurrentIndex);
3897bool PhiNodeSetIterator::operator==(
const PhiNodeSetIterator &
RHS)
const {
3898 return CurrentIndex ==
RHS.CurrentIndex;
3901bool PhiNodeSetIterator::operator!=(
const PhiNodeSetIterator &
RHS)
const {
3902 return !((*this) ==
RHS);
3908class SimplificationTracker {
3909 DenseMap<Value *, Value *> Storage;
3912 PhiNodeSet AllPhiNodes;
3914 SmallPtrSet<SelectInst *, 32> AllSelectNodes;
3919 auto SV = Storage.
find(V);
3920 if (SV == Storage.
end())
3928 void ReplacePhi(PHINode *From, PHINode *To) {
3929 Value *OldReplacement = Get(From);
3930 while (OldReplacement != From) {
3933 OldReplacement = Get(From);
3935 assert(To && Get(To) == To &&
"Replacement PHI node is already replaced.");
3938 AllPhiNodes.erase(From);
3942 PhiNodeSet &newPhiNodes() {
return AllPhiNodes; }
3944 void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); }
3946 void insertNewSelect(SelectInst *SI) { AllSelectNodes.
insert(SI); }
3948 unsigned countNewPhiNodes()
const {
return AllPhiNodes.size(); }
3950 unsigned countNewSelectNodes()
const {
return AllSelectNodes.
size(); }
3952 void destroyNewNodes(
Type *CommonType) {
3955 for (
auto *
I : AllPhiNodes) {
3956 I->replaceAllUsesWith(Dummy);
3957 I->eraseFromParent();
3959 AllPhiNodes.clear();
3960 for (
auto *
I : AllSelectNodes) {
3961 I->replaceAllUsesWith(Dummy);
3962 I->eraseFromParent();
3964 AllSelectNodes.clear();
3969class AddressingModeCombiner {
3970 typedef DenseMap<Value *, Value *> FoldAddrToValueMapping;
3971 typedef std::pair<PHINode *, PHINode *> PHIPair;
3978 ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField;
3981 bool AllAddrModesTrivial =
true;
3984 Type *CommonType =
nullptr;
3986 const DataLayout &
DL;
3987 const CodeGenOptions &Opts;
3993 Value *CommonValue =
nullptr;
3996 AddressingModeCombiner(
const DataLayout &
DL,
const CodeGenOptions &Opts,
3997 Value *OriginalValue)
3998 :
DL(
DL), Opts(Opts), Original(OriginalValue) {}
4000 ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
4003 const ExtAddrMode &
getAddrMode()
const {
return AddrModes[0]; }
4008 bool addNewAddrMode(ExtAddrMode &NewAddrMode) {
4012 AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial();
4015 if (AddrModes.
empty()) {
4023 ExtAddrMode::FieldName ThisDifferentField =
4024 AddrModes[0].compare(NewAddrMode);
4025 if (DifferentField == ExtAddrMode::NoField)
4026 DifferentField = ThisDifferentField;
4027 else if (DifferentField != ThisDifferentField)
4028 DifferentField = ExtAddrMode::MultipleFields;
4031 bool CanHandle = DifferentField != ExtAddrMode::MultipleFields;
4034 CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField;
4039 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
4044 CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField ||
4045 !NewAddrMode.HasBaseReg);
4062 bool combineAddrModes() {
4064 if (AddrModes.
size() == 0)
4068 if (AddrModes.
size() == 1 || DifferentField == ExtAddrMode::NoField)
4073 if (AllAddrModesTrivial)
4076 if (!addrModeCombiningAllowed())
4082 FoldAddrToValueMapping
Map;
4083 if (!initializeMap(Map))
4086 CommonValue = findCommon(Map);
4088 AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
4089 return CommonValue !=
nullptr;
4095 void eraseCommonValueIfDead() {
4096 if (CommonValue && CommonValue->
use_empty())
4098 CommonInst->eraseFromParent();
4106 bool initializeMap(FoldAddrToValueMapping &Map) {
4109 SmallVector<Value *, 2> NullValue;
4111 for (
auto &AM : AddrModes) {
4115 if (CommonType && CommonType !=
Type)
4118 Map[AM.OriginalValue] = DV;
4123 assert(CommonType &&
"At least one non-null value must be!");
4124 for (
auto *V : NullValue)
4152 Value *findCommon(FoldAddrToValueMapping &Map) {
4160 SimplificationTracker
ST;
4165 InsertPlaceholders(Map, TraverseOrder, ST);
4168 FillPlaceholders(Map, TraverseOrder, ST);
4170 if (!Opts.cgp_addr_sink_new_select &&
ST.countNewSelectNodes() > 0) {
4171 ST.destroyNewNodes(CommonType);
4176 unsigned PhiNotMatchedCount = 0;
4177 if (!MatchPhiSet(ST, Opts.cgp_addr_sink_new_phis, PhiNotMatchedCount)) {
4178 ST.destroyNewNodes(CommonType);
4182 auto *
Result =
ST.Get(
Map.find(Original)->second);
4184 NumMemoryInstsPhiCreated +=
ST.countNewPhiNodes() + PhiNotMatchedCount;
4185 NumMemoryInstsSelectCreated +=
ST.countNewSelectNodes();
4192 bool MatchPhiNode(PHINode *
PHI, PHINode *Candidate,
4193 SmallSetVector<PHIPair, 8> &Matcher,
4194 PhiNodeSet &PhiNodesToMatch) {
4197 SmallPtrSet<PHINode *, 8> MatchedPHIs;
4200 SmallSet<PHIPair, 8> Visited;
4201 while (!WorkList.
empty()) {
4203 if (!Visited.
insert(Item).second)
4210 for (
auto *
B : Item.first->blocks()) {
4211 Value *FirstValue = Item.first->getIncomingValueForBlock(
B);
4212 Value *SecondValue = Item.second->getIncomingValueForBlock(
B);
4213 if (FirstValue == SecondValue)
4223 if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) ||
4228 if (Matcher.
count({FirstPhi, SecondPhi}))
4233 if (MatchedPHIs.
insert(FirstPhi).second)
4234 Matcher.
insert({FirstPhi, SecondPhi});
4236 WorkList.
push_back({FirstPhi, SecondPhi});
4245 bool MatchPhiSet(SimplificationTracker &ST,
bool AllowNewPhiNodes,
4246 unsigned &PhiNotMatchedCount) {
4250 SmallSetVector<PHIPair, 8> Matched;
4251 SmallPtrSet<PHINode *, 8> WillNotMatch;
4252 PhiNodeSet &PhiNodesToMatch =
ST.newPhiNodes();
4253 while (PhiNodesToMatch.size()) {
4254 PHINode *
PHI = *PhiNodesToMatch.begin();
4257 WillNotMatch.
clear();
4261 bool IsMatched =
false;
4262 for (
auto &
P :
PHI->getParent()->phis()) {
4264 if (PhiNodesToMatch.count(&
P))
4266 if ((IsMatched = MatchPhiNode(
PHI, &
P, Matched, PhiNodesToMatch)))
4276 for (
auto MV : Matched)
4277 ST.ReplacePhi(MV.first, MV.second);
4282 if (!AllowNewPhiNodes)
4285 PhiNotMatchedCount += WillNotMatch.
size();
4286 for (
auto *
P : WillNotMatch)
4287 PhiNodesToMatch.erase(
P);
4292 void FillPlaceholders(FoldAddrToValueMapping &Map,
4293 SmallVectorImpl<Value *> &TraverseOrder,
4294 SimplificationTracker &ST) {
4295 while (!TraverseOrder.
empty()) {
4297 assert(
Map.contains(Current) &&
"No node to fill!!!");
4303 auto *TrueValue = CurrentSelect->getTrueValue();
4304 assert(
Map.contains(TrueValue) &&
"No True Value!");
4305 Select->setTrueValue(
ST.Get(Map[TrueValue]));
4306 auto *FalseValue = CurrentSelect->getFalseValue();
4307 assert(
Map.contains(FalseValue) &&
"No False Value!");
4308 Select->setFalseValue(
ST.Get(Map[FalseValue]));
4315 assert(
Map.contains(PV) &&
"No predecessor Value!");
4316 PHI->addIncoming(
ST.Get(Map[PV]),
B);
4327 void InsertPlaceholders(FoldAddrToValueMapping &Map,
4328 SmallVectorImpl<Value *> &TraverseOrder,
4329 SimplificationTracker &ST) {
4332 "Address must be a Phi or Select node");
4335 while (!Worklist.
empty()) {
4338 if (
Map.contains(Current))
4349 CurrentSelect->getName(),
4350 CurrentSelect->getIterator(), CurrentSelect);
4354 Worklist.
push_back(CurrentSelect->getTrueValue());
4355 Worklist.
push_back(CurrentSelect->getFalseValue());
4363 ST.insertNewPhi(
PHI);
4369 bool addrModeCombiningAllowed() {
4370 if (!Opts.cgp_complex_addr_modes)
4372 switch (DifferentField) {
4375 case ExtAddrMode::BaseRegField:
4376 return Opts.cgp_addr_sink_combine_base_reg;
4377 case ExtAddrMode::BaseGVField:
4378 return Opts.cgp_addr_sink_combine_base_gv;
4379 case ExtAddrMode::BaseOffsField:
4380 return Opts.cgp_addr_sink_combine_base_offs;
4381 case ExtAddrMode::ScaledRegField:
4382 return Opts.cgp_addr_sink_combine_scaled_reg;
4391bool AddressingModeMatcher::matchScaledValue(
Value *ScaleReg, int64_t Scale,
4396 return matchAddr(ScaleReg,
Depth);
4407 ExtAddrMode TestAddrMode =
AddrMode;
4411 TestAddrMode.
Scale += Scale;
4425 ConstantInt *CI =
nullptr;
4426 Value *AddLHS =
nullptr;
4430 TestAddrMode.InBounds =
false;
4447 auto GetConstantStep =
4448 [
this](
const Value *
V) -> std::optional<std::pair<Instruction *, APInt>> {
4451 return std::nullopt;
4454 return std::nullopt;
4462 if (OIVInc->hasNoSignedWrap() || OIVInc->hasNoUnsignedWrap())
4463 return std::nullopt;
4465 return std::make_pair(IVInc->first, ConstantStep->getValue());
4466 return std::nullopt;
4481 if (
auto IVStep = GetConstantStep(ScaleReg)) {
4488 APInt Step = IVStep->second;
4490 if (
Offset.isSignedIntN(64)) {
4491 TestAddrMode.InBounds =
false;
4493 TestAddrMode.BaseOffs -=
Offset.getLimitedValue();
4498 getDTFn().
dominates(IVInc, MemoryInst)) {
4518 switch (
I->getOpcode()) {
4519 case Instruction::BitCast:
4520 case Instruction::AddrSpaceCast:
4522 if (
I->getType() ==
I->getOperand(0)->getType())
4524 return I->getType()->isIntOrPtrTy();
4525 case Instruction::PtrToInt:
4528 case Instruction::IntToPtr:
4531 case Instruction::Add:
4533 case Instruction::Or:
4535 case Instruction::Mul:
4536 case Instruction::Shl:
4539 case Instruction::GetElementPtr:
4567class TypePromotionHelper {
4570 static void addPromotedInst(InstrToOrigTy &PromotedInsts,
4571 Instruction *ExtOpnd,
bool IsSExt) {
4572 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4573 auto [It,
Inserted] = PromotedInsts.try_emplace(ExtOpnd);
4577 if (It->second.getInt() == ExtTy)
4583 ExtTy = BothExtension;
4585 It->second = TypeIsSExt(ExtOpnd->
getType(), ExtTy);
4592 static const Type *getOrigType(
const InstrToOrigTy &PromotedInsts,
4593 Instruction *Opnd,
bool IsSExt) {
4594 ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension;
4595 InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd);
4596 if (It != PromotedInsts.end() && It->second.getInt() == ExtTy)
4597 return It->second.getPointer();
4612 static bool canGetThrough(
const Instruction *Inst,
Type *ConsideredExtType,
4613 const InstrToOrigTy &PromotedInsts,
bool IsSExt);
4617 static bool shouldExtOperand(
const Instruction *Inst,
int OpIdx) {
4630 static Value *promoteOperandForTruncAndAnyExt(
4631 Instruction *Ext, TypePromotionTransaction &TPT,
4632 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4633 SmallVectorImpl<Instruction *> *Exts,
4634 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI);
4645 static Value *promoteOperandForOther(Instruction *Ext,
4646 TypePromotionTransaction &TPT,
4647 InstrToOrigTy &PromotedInsts,
4648 unsigned &CreatedInstsCost,
4649 SmallVectorImpl<Instruction *> *Exts,
4650 SmallVectorImpl<Instruction *> *Truncs,
4651 const TargetLowering &TLI,
bool IsSExt);
4654 static Value *signExtendOperandForOther(
4655 Instruction *Ext, TypePromotionTransaction &TPT,
4656 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4657 SmallVectorImpl<Instruction *> *Exts,
4658 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4659 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4660 Exts, Truncs, TLI,
true);
4664 static Value *zeroExtendOperandForOther(
4665 Instruction *Ext, TypePromotionTransaction &TPT,
4666 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4667 SmallVectorImpl<Instruction *> *Exts,
4668 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4669 return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost,
4670 Exts, Truncs, TLI,
false);
4675 using Action =
Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
4676 InstrToOrigTy &PromotedInsts,
4677 unsigned &CreatedInstsCost,
4678 SmallVectorImpl<Instruction *> *Exts,
4679 SmallVectorImpl<Instruction *> *Truncs,
4680 const TargetLowering &TLI);
4691 static Action getAction(Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4692 const TargetLowering &TLI,
4693 const InstrToOrigTy &PromotedInsts);
4698bool TypePromotionHelper::canGetThrough(
const Instruction *Inst,
4699 Type *ConsideredExtType,
4700 const InstrToOrigTy &PromotedInsts,
4720 ((!IsSExt && BinOp->hasNoUnsignedWrap()) ||
4721 (IsSExt && BinOp->hasNoSignedWrap())))
4725 if ((Inst->
getOpcode() == Instruction::And ||
4730 if (Inst->
getOpcode() == Instruction::Xor) {
4733 if (!Cst->getValue().isAllOnes())
4742 if (Inst->
getOpcode() == Instruction::LShr && !IsSExt)
4752 if (ExtInst->hasOneUse()) {
4754 if (AndInst && AndInst->getOpcode() == Instruction::And) {
4787 const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt);
4800TypePromotionHelper::Action TypePromotionHelper::getAction(
4801 Instruction *Ext,
const SetOfInstrs &InsertedInsts,
4802 const TargetLowering &TLI,
const InstrToOrigTy &PromotedInsts) {
4804 "Unexpected instruction type");
4811 if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt))
4824 return promoteOperandForTruncAndAnyExt;
4830 return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther;
4833Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
4834 Instruction *SExt, TypePromotionTransaction &TPT,
4835 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4836 SmallVectorImpl<Instruction *> *Exts,
4837 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI) {
4841 Value *ExtVal = SExt;
4842 bool HasMergedNonFreeExt =
false;
4846 HasMergedNonFreeExt = !TLI.
isExtFree(SExtOpnd);
4849 TPT.replaceAllUsesWith(SExt, ZExt);
4850 TPT.eraseInstruction(SExt);
4855 TPT.setOperand(SExt, 0, SExtOpnd->
getOperand(0));
4857 CreatedInstsCost = 0;
4861 TPT.eraseInstruction(SExtOpnd);
4869 CreatedInstsCost = !TLI.
isExtFree(ExtInst) && !HasMergedNonFreeExt;
4877 TPT.eraseInstruction(ExtInst, NextVal);
4881Value *TypePromotionHelper::promoteOperandForOther(
4882 Instruction *Ext, TypePromotionTransaction &TPT,
4883 InstrToOrigTy &PromotedInsts,
unsigned &CreatedInstsCost,
4884 SmallVectorImpl<Instruction *> *Exts,
4885 SmallVectorImpl<Instruction *> *Truncs,
const TargetLowering &TLI,
4890 CreatedInstsCost = 0;
4896 Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->
getType());
4899 ITrunc->moveAfter(ExtOpnd);
4904 TPT.replaceAllUsesWith(ExtOpnd, Trunc);
4907 TPT.setOperand(Ext, 0, ExtOpnd);
4917 addPromotedInst(PromotedInsts, ExtOpnd, IsSExt);
4919 TPT.mutateType(ExtOpnd, Ext->
getType());
4921 TPT.replaceAllUsesWith(Ext, ExtOpnd);
4924 for (
int OpIdx = 0, EndOpIdx = ExtOpnd->
getNumOperands(); OpIdx != EndOpIdx;
4928 !shouldExtOperand(ExtOpnd, OpIdx)) {
4937 APInt CstVal = IsSExt ? Cst->getValue().sext(
BitWidth)
4939 TPT.setOperand(ExtOpnd, OpIdx, ConstantInt::get(Ext->
getType(), CstVal));
4950 Value *ValForExtOpnd = IsSExt
4951 ? TPT.createSExt(ExtOpnd, Opnd, Ext->
getType())
4952 : TPT.createZExt(ExtOpnd, Opnd, Ext->
getType());
4953 TPT.setOperand(ExtOpnd, OpIdx, ValForExtOpnd);
4955 if (!InstForExtOpnd)
4961 CreatedInstsCost += !TLI.
isExtFree(InstForExtOpnd);
4964 TPT.eraseInstruction(Ext);
4976bool AddressingModeMatcher::isPromotionProfitable(
4977 unsigned NewCost,
unsigned OldCost,
Value *PromotedOperand)
const {
4978 LLVM_DEBUG(
dbgs() <<
"OldCost: " << OldCost <<
"\tNewCost: " << NewCost
4983 if (NewCost > OldCost)
4985 if (NewCost < OldCost)
5004bool AddressingModeMatcher::matchOperationAddr(User *AddrInst,
unsigned Opcode,
5016 case Instruction::PtrToInt:
5019 case Instruction::IntToPtr: {
5027 case Instruction::BitCast:
5037 case Instruction::AddrSpaceCast: {
5045 case Instruction::Or:
5049 case Instruction::Add: {
5052 ExtAddrMode BackupAddrMode =
AddrMode;
5053 unsigned OldSize = AddrModeInsts.
size();
5058 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5059 TPT.getRestorationPoint();
5063 int First = 0, Second = 1;
5074 AddrModeInsts.
resize(OldSize);
5075 TPT.rollback(LastKnownGood);
5085 AddrModeInsts.
resize(OldSize);
5086 TPT.rollback(LastKnownGood);
5089 case Instruction::Mul:
5090 case Instruction::Shl: {
5094 if (!
RHS ||
RHS->getBitWidth() > 64)
5096 int64_t Scale = Opcode == Instruction::Shl
5097 ? 1LL <<
RHS->getLimitedValue(
RHS->getBitWidth() - 1)
5098 :
RHS->getSExtValue();
5102 case Instruction::GetElementPtr: {
5105 int VariableOperand = -1;
5106 unsigned VariableScale = 0;
5108 int64_t ConstantOffset = 0;
5110 for (
unsigned i = 1, e = AddrInst->
getNumOperands(); i != e; ++i, ++GTI) {
5112 const StructLayout *SL =
DL.getStructLayout(STy);
5123 if (ConstantInt *CI =
5125 const APInt &CVal = CI->
getValue();
5132 if (VariableOperand != -1)
5136 VariableOperand = i;
5137 VariableScale = TypeSize;
5144 if (VariableOperand == -1) {
5145 AddrMode.BaseOffs += ConstantOffset;
5151 AddrMode.BaseOffs -= ConstantOffset;
5155 ConstantOffset != 0) {
5169 BaseI ? BaseI->getParent() : &
GEP->getFunction()->getEntryBlock();
5171 LargeOffsetGEP = std::make_pair(
GEP, ConstantOffset);
5179 ExtAddrMode BackupAddrMode =
AddrMode;
5180 unsigned OldSize = AddrModeInsts.
size();
5183 AddrMode.BaseOffs += ConstantOffset;
5192 AddrModeInsts.
resize(OldSize);
5200 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand), VariableScale,
5205 AddrModeInsts.
resize(OldSize);
5210 AddrMode.BaseOffs += ConstantOffset;
5211 if (!matchScaledValue(AddrInst->
getOperand(VariableOperand),
5212 VariableScale,
Depth)) {
5215 AddrModeInsts.
resize(OldSize);
5222 case Instruction::SExt:
5223 case Instruction::ZExt: {
5230 TypePromotionHelper::Action TPH =
5231 TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts);
5235 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5236 TPT.getRestorationPoint();
5237 unsigned CreatedInstsCost = 0;
5239 Value *PromotedOperand =
5240 TPH(Ext, TPT, PromotedInsts, CreatedInstsCost,
nullptr,
nullptr, TLI);
5255 assert(PromotedOperand &&
5256 "TypePromotionHelper should have filtered out those cases");
5258 ExtAddrMode BackupAddrMode =
AddrMode;
5259 unsigned OldSize = AddrModeInsts.
size();
5261 if (!matchAddr(PromotedOperand,
Depth) ||
5266 !isPromotionProfitable(CreatedInstsCost,
5267 ExtCost + (AddrModeInsts.
size() - OldSize),
5270 AddrModeInsts.
resize(OldSize);
5271 LLVM_DEBUG(
dbgs() <<
"Sign extension does not pay off: rollback\n");
5272 TPT.rollback(LastKnownGood);
5277 AddrMode.replaceWith(Ext, PromotedOperand);
5280 case Instruction::Call:
5282 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address) {
5298bool AddressingModeMatcher::matchAddr(
Value *Addr,
unsigned Depth) {
5301 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5302 TPT.getRestorationPoint();
5326 ExtAddrMode BackupAddrMode =
AddrMode;
5327 unsigned OldSize = AddrModeInsts.
size();
5330 bool MovedAway =
false;
5331 if (matchOperationAddr(
I,
I->getOpcode(),
Depth, &MovedAway)) {
5339 if (
I->hasOneUse() ||
5340 isProfitableToFoldIntoAddressingMode(
I, BackupAddrMode,
AddrMode)) {
5347 AddrModeInsts.
resize(OldSize);
5348 TPT.rollback(LastKnownGood);
5351 if (matchOperationAddr(CE,
CE->getOpcode(),
Depth))
5353 TPT.rollback(LastKnownGood);
5380 TPT.rollback(LastKnownGood);
5399 if (OpInfo.CallOperandVal == OpVal &&
5401 !OpInfo.isIndirect))
5417 if (!ConsideredInsts.
insert(
I).second)
5425 for (
Use &U :
I->uses()) {
5428 if (SeenInsts++ >= MaxUsersToScan)
5433 MemoryUses.push_back({&U, LI->getType()});
5440 MemoryUses.push_back({&U,
SI->getValueOperand()->getType()});
5447 MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
5454 MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
5464 if (!
find(PtrOps, U.get()))
5467 MemoryUses.push_back({&U, AccessTy});
5472 if (CI->hasFnAttr(Attribute::Cold)) {
5490 PSI, BFI, SeenInsts, MaxUsersToScan))
5501 unsigned SeenInsts = 0;
5504 PSI, BFI, SeenInsts, MaxUsersToScan);
5511bool AddressingModeMatcher::valueAlreadyLiveAtInst(
Value *Val,
5513 Value *KnownLive2) {
5515 if (Val ==
nullptr || Val == KnownLive1 || Val == KnownLive2)
5556bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
5557 Instruction *
I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) {
5558 if (IgnoreProfitability)
5576 if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.
BaseReg, AMBefore.
ScaledReg))
5577 ScaledReg =
nullptr;
5581 if (!BaseReg && !ScaledReg)
5590 Opts.cgp_max_address_users_to_scan))
5603 for (
const std::pair<Use *, Type *> &Pair : MemoryUses) {
5606 Type *AddressAccessTy = Pair.second;
5607 unsigned AS =
Address->getType()->getPointerAddressSpace();
5613 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5615 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5616 TPT.getRestorationPoint();
5617 AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI,
TRI, LI, getDTFn,
5618 AddressAccessTy, AS, UserI, Result,
5619 InsertedInsts, PromotedInsts, TPT,
5620 LargeOffsetGEP, OptSize, PSI, BFI, Opts);
5621 Matcher.IgnoreProfitability =
true;
5629 TPT.rollback(LastKnownGood);
5635 MatchedAddrModeInsts.
clear();
5645 return I->getParent() != BB;
5661 return std::next(AddrInst->getIterator());
5672 Earliest = UserInst;
5697bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst,
Value *Addr,
5698 Type *AccessTy,
unsigned AddrSpace) {
5703 SmallVector<Value *, 8> worklist;
5704 SmallPtrSet<Value *, 16> Visited;
5710 bool PhiOrSelectSeen =
false;
5711 SmallVector<Instruction *, 16> AddrModeInsts;
5712 AddressingModeCombiner AddrModes(*
DL, Opts, Addr);
5713 TypePromotionTransaction TPT(RemovedInsts);
5714 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
5715 TPT.getRestorationPoint();
5716 while (!worklist.
empty()) {
5728 if (!Visited.
insert(V).second)
5734 PhiOrSelectSeen =
true;
5741 PhiOrSelectSeen =
true;
5748 AddrModeInsts.
clear();
5749 std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(
nullptr,
5754 auto getDTFn = [
this]() ->
const DominatorTree & {
return getDT(); };
5755 ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
5756 V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
5757 *
TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
5760 GetElementPtrInst *
GEP = LargeOffsetGEP.first;
5765 LargeOffsetGEPMap[
GEP->getPointerOperand()].push_back(LargeOffsetGEP);
5766 LargeOffsetGEPID.
insert(std::make_pair(
GEP, LargeOffsetGEPID.
size()));
5769 NewAddrMode.OriginalValue =
V;
5770 if (!AddrModes.addNewAddrMode(NewAddrMode))
5777 if (!AddrModes.combineAddrModes()) {
5778 TPT.rollback(LastKnownGood);
5784 ExtAddrMode
AddrMode = AddrModes.getAddrMode();
5790 if (!PhiOrSelectSeen &&
none_of(AddrModeInsts, [&](
Value *V) {
5804 WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
5826 <<
" for " << *MemoryInst <<
"\n");
5830 !
DL->isNonIntegralPointerType(Addr->
getType())) {
5836 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
5838 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
5840 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
5842 }
else if (
valueOr(Opts.cgp_addr_sink_using_gep,
true) ||
5843 (Opts.cgp_addr_sink_using_gep == BoolOrDefault::Default &&
5848 <<
" for " << *MemoryInst <<
"\n");
5849 Value *ResultPtr =
nullptr, *ResultIndex =
nullptr;
5860 if (ResultPtr ||
AddrMode.Scale != 1)
5881 GlobalValue *BaseGV =
AddrMode.BaseGV;
5882 if (BaseGV !=
nullptr) {
5887 ResultPtr = Builder.CreateThreadLocalAddress(BaseGV);
5896 if (!
DL->isNonIntegralPointerType(Addr->
getType())) {
5897 if (!ResultPtr &&
AddrMode.BaseReg) {
5901 }
else if (!ResultPtr &&
AddrMode.Scale == 1) {
5902 ResultPtr = Builder.CreateIntToPtr(
AddrMode.ScaledReg, Addr->
getType(),
5911 }
else if (!ResultPtr) {
5925 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
5938 "We can't transform if ScaledReg is too narrow");
5939 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
5943 V = Builder.CreateMul(
5946 ResultIndex = Builder.CreateAdd(ResultIndex, V,
"sunkaddr");
5957 if (ResultPtr->
getType() != I8PtrTy)
5958 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
5959 ResultPtr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
5972 if (PtrInst && PtrInst->getParent() != MemoryInst->
getParent())
5974 SunkAddr = ResultPtr;
5976 if (ResultPtr->
getType() != I8PtrTy)
5977 ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy);
5978 SunkAddr = Builder.CreatePtrAdd(ResultPtr, ResultIndex,
"sunkaddr",
5985 !
DL->isNonIntegralPointerType(Addr->
getType())) {
5991 SunkAddr = Builder.CreatePtrToInt(SunkAddr,
IntPtrTy,
"sunkaddr");
5993 Builder.CreateIntToPtr(SunkAddr, Addr->
getType(),
"sunkaddr");
5995 SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->
getType());
6005 if (
DL->isNonIntegralPointerType(Addr->
getType()) ||
6006 (BasePtrTy &&
DL->isNonIntegralPointerType(BasePtrTy)) ||
6007 (ScalePtrTy &&
DL->isNonIntegralPointerType(ScalePtrTy)) ||
6009 DL->isNonIntegralPointerType(
AddrMode.BaseGV->getType())))
6013 <<
" for " << *MemoryInst <<
"\n");
6024 if (
V->getType()->isPointerTy())
6025 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6027 V = Builder.CreateIntCast(V,
IntPtrTy,
true,
"sunkaddr");
6036 }
else if (
V->getType()->isPointerTy()) {
6037 V = Builder.CreatePtrToInt(V,
IntPtrTy,
"sunkaddr");
6040 V = Builder.CreateTrunc(V,
IntPtrTy,
"sunkaddr");
6049 I->eraseFromParent();
6053 V = Builder.CreateMul(
6056 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6062 GlobalValue *BaseGV =
AddrMode.BaseGV;
6063 if (BaseGV !=
nullptr) {
6066 BaseGVPtr = Builder.CreateThreadLocalAddress(BaseGV);
6070 Value *
V = Builder.CreatePtrToInt(BaseGVPtr,
IntPtrTy,
"sunkaddr");
6072 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6081 Result = Builder.CreateAdd(Result, V,
"sunkaddr");
6089 SunkAddr = Builder.CreateIntToPtr(Result, Addr->
getType(),
"sunkaddr");
6095 SunkAddrs[Addr] = WeakTrackingVH(SunkAddr);
6100 resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
6101 RecursivelyDeleteTriviallyDeadInstructions(
6102 Repl, TLInfo, nullptr,
6103 [&](Value *V) { removeAllAssertingVHReferences(V); });
6127bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
6133 if (!
GEP->hasIndices())
6141 SmallVector<Value *, 2>
Ops(
GEP->operands());
6143 bool RewriteGEP =
false;
6152 unsigned FinalIndex =
Ops.size() - 1;
6157 for (
unsigned i = 1; i < FinalIndex; ++i) {
6162 C =
C->getSplatValue();
6164 if (!CI || !CI->
isZero())
6171 if (
Ops[FinalIndex]->
getType()->isVectorTy()) {
6175 if (!
C || !
C->isZero()) {
6176 Ops[FinalIndex] =
V;
6184 if (!RewriteGEP &&
Ops.size() == 2)
6191 Type *SourceTy =
GEP->getSourceElementType();
6192 Type *ScalarIndexTy =
DL->getIndexType(
Ops[0]->
getType()->getScalarType());
6196 if (!
Ops[FinalIndex]->
getType()->isVectorTy()) {
6197 NewAddr = Builder.CreateGEP(SourceTy,
Ops[0],
ArrayRef(
Ops).drop_front());
6198 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6208 if (
Ops.size() != 2) {
6218 NewAddr = Builder.CreateGEP(SourceTy,
Base, Index);
6232 Type *ScalarIndexTy =
DL->getIndexType(
V->getType()->getScalarType());
6233 auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
6236 Intrinsic::masked_gather) {
6240 Intrinsic::masked_scatter);
6255 Ptr, TLInfo,
nullptr,
6256 [&](
Value *V) { removeAllAssertingVHReferences(V); });
6267 if (
I->hasNUsesOrMore(3))
6270 for (
User *U :
I->users()) {
6272 if (!Extract || Extract->getNumIndices() != 1)
6275 unsigned Index = Extract->getIndices()[0];
6277 MulExtract = Extract;
6278 else if (Index == 1)
6279 OverflowExtract = Extract;
6306bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *
I,
bool IsSigned,
6307 ModifyDT &ModifiedDT) {
6314 ExtractValueInst *MulExtract =
nullptr, *OverflowExtract =
nullptr;
6319 InsertedInsts.insert(
I);
6330 OverflowEntryBB->
takeName(
I->getParent());
6336 NoOverflowBB->
moveAfter(OverflowEntryBB);
6344 Value *LoLHS = Builder.CreateTrunc(
LHS, LegalTy,
"lo.lhs");
6345 Value *HiLHS = Builder.CreateLShr(
LHS, VTHalfBitWidth,
"lhs.lsr");
6346 HiLHS = Builder.CreateTrunc(HiLHS, LegalTy,
"hi.lhs");
6349 Value *LoRHS = Builder.CreateTrunc(
RHS, LegalTy,
"lo.rhs");
6350 Value *HiRHS = Builder.CreateLShr(
RHS, VTHalfBitWidth,
"rhs.lsr");
6351 HiRHS = Builder.CreateTrunc(HiRHS, LegalTy,
"hi.rhs");
6353 Value *IsAnyBitTrue;
6356 Builder.CreateAShr(LoLHS, VTHalfBitWidth - 1,
"sign.lo.lhs");
6358 Builder.CreateAShr(LoRHS, VTHalfBitWidth - 1,
"sign.lo.rhs");
6359 Value *XorLHS = Builder.CreateXor(HiLHS, SignLoLHS);
6360 Value *XorRHS = Builder.CreateXor(HiRHS, SignLoRHS);
6361 Value *
Or = Builder.CreateOr(XorLHS, XorRHS,
"or.lhs.rhs");
6362 IsAnyBitTrue = Builder.CreateCmp(ICmpInst::ICMP_NE,
Or,
6363 ConstantInt::getNullValue(
Or->getType()));
6365 Value *CmpLHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiLHS,
6366 ConstantInt::getNullValue(LegalTy));
6367 Value *CmpRHS = Builder.CreateCmp(ICmpInst::ICMP_NE, HiRHS,
6368 ConstantInt::getNullValue(LegalTy));
6369 IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS,
"or.lhs.rhs");
6371 Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
6374 Builder.SetInsertPoint(NoOverflowBB);
6375 Value *ExtLoLHS, *ExtLoRHS;
6377 ExtLoLHS = Builder.CreateSExt(LoLHS, Ty,
"lo.lhs.ext");
6378 ExtLoRHS = Builder.CreateSExt(LoRHS, Ty,
"lo.rhs.ext");
6380 ExtLoLHS = Builder.CreateZExt(LoLHS, Ty,
"lo.lhs.ext");
6381 ExtLoRHS = Builder.CreateZExt(LoRHS, Ty,
"lo.rhs.ext");
6384 Value *
Mul = Builder.CreateMul(ExtLoLHS, ExtLoRHS,
"mul.overflow.no");
6389 OverflowResBB->
setName(
"overflow.res");
6392 Builder.CreateBr(OverflowResBB);
6400 PHINode *OverflowResPHI = Builder.CreatePHI(Ty, 2),
6402 Builder.CreatePHI(IntegerType::getInt1Ty(
I->getContext()), 2);
6414 if (OverflowExtract) {
6415 OverflowExtract->replaceAllUsesWith(OverflowFlagPHI);
6416 OverflowExtract->eraseFromParent();
6421 I->removeFromParent();
6423 I->insertInto(OverflowBB, OverflowBB->
end());
6424 Builder.SetInsertPoint(OverflowBB->
end());
6426 Value *OverflowFlag = Builder.CreateExtractValue(
I, {1},
"overflow.flag");
6427 Builder.CreateBr(OverflowResBB);
6431 OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
6433 DTU->
applyUpdates({{DominatorTree::Insert, OverflowEntryBB, OverflowBB},
6434 {DominatorTree::Insert, OverflowEntryBB, NoOverflowBB},
6435 {DominatorTree::Insert, NoOverflowBB, OverflowResBB},
6436 {DominatorTree::Delete, OverflowEntryBB, OverflowResBB},
6437 {DominatorTree::Insert, OverflowBB, OverflowResBB}});
6439 ModifiedDT = ModifyDT::ModifyBBDT;
6445bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) {
6446 bool MadeChange =
false;
6448 const TargetRegisterInfo *
TRI =
6453 for (TargetLowering::AsmOperandInfo &OpInfo : TargetConstraints) {
6459 OpInfo.isIndirect) {
6461 MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->
getType(), ~0u);
6524bool CodeGenPrepare::tryToPromoteExts(
6525 TypePromotionTransaction &TPT,
const SmallVectorImpl<Instruction *> &Exts,
6526 SmallVectorImpl<Instruction *> &ProfitablyMovedExts,
6527 unsigned CreatedInstsCost) {
6528 bool Promoted =
false;
6531 for (
auto *
I : Exts) {
6546 TypePromotionHelper::Action TPH =
6547 TypePromotionHelper::getAction(
I, InsertedInsts, *TLI, PromotedInsts);
6556 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
6557 TPT.getRestorationPoint();
6558 SmallVector<Instruction *, 4> NewExts;
6559 unsigned NewCreatedInstsCost = 0;
6562 Value *PromotedVal = TPH(
I, TPT, PromotedInsts, NewCreatedInstsCost,
6563 &NewExts,
nullptr, *TLI);
6565 "TypePromotionHelper should have filtered out those cases");
6575 long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost;
6578 TotalCreatedInstsCost =
6579 std::max((
long long)0, (TotalCreatedInstsCost - ExtCost));
6580 if (!Opts.cgp_stress_ext_ld_promotion &&
6581 (TotalCreatedInstsCost > 1 ||
6583 (ExtCost == 0 && NewExts.
size() > 1))) {
6587 TPT.rollback(LastKnownGood);
6592 SmallVector<Instruction *, 2> NewlyMovedExts;
6593 (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost);
6594 bool NewPromoted =
false;
6595 for (
auto *ExtInst : NewlyMovedExts) {
6601 !(Opts.cgp_stress_ext_ld_promotion ||
6602 NewCreatedInstsCost <= ExtCost ||
6606 ProfitablyMovedExts.
push_back(MovedExt);
6613 TPT.rollback(LastKnownGood);
6624bool CodeGenPrepare::mergeSExts(
Function &
F) {
6626 for (
auto &Entry : ValToSExtendedUses) {
6627 SExts &Insts =
Entry.second;
6629 for (Instruction *Inst : Insts) {
6633 bool inserted =
false;
6634 for (
auto &Pt : CurPts) {
6637 RemovedInsts.insert(Pt);
6638 Pt->removeFromParent();
6649 RemovedInsts.insert(Inst);
6656 CurPts.push_back(Inst);
6698bool CodeGenPrepare::splitLargeGEPOffsets() {
6700 for (
auto &Entry : LargeOffsetGEPMap) {
6702 SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
6703 &LargeOffsetGEPs =
Entry.second;
6704 auto compareGEPOffset =
6705 [&](
const std::pair<GetElementPtrInst *, int64_t> &
LHS,
6706 const std::pair<GetElementPtrInst *, int64_t> &
RHS) {
6707 if (
LHS.first ==
RHS.first)
6709 if (
LHS.second !=
RHS.second)
6710 return LHS.second <
RHS.second;
6711 return LargeOffsetGEPID[
LHS.first] < LargeOffsetGEPID[
RHS.first];
6714 llvm::sort(LargeOffsetGEPs, compareGEPOffset);
6717 if (LargeOffsetGEPs.
front().second == LargeOffsetGEPs.
back().second)
6719 GetElementPtrInst *BaseGEP = LargeOffsetGEPs.
begin()->first;
6720 int64_t BaseOffset = LargeOffsetGEPs.
begin()->second;
6721 Value *NewBaseGEP =
nullptr;
6723 auto createNewBase = [&](int64_t BaseOffset,
Value *OldBase,
6724 GetElementPtrInst *
GEP) {
6725 LLVMContext &Ctx =
GEP->getContext();
6726 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6728 PointerType::get(Ctx,
GEP->getType()->getPointerAddressSpace());
6740 SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), &getDT(), LI);
6743 NewBaseInsertPt = std::next(BaseI->getIterator());
6756 NewBaseGEP = OldBase;
6757 if (NewBaseGEP->
getType() != I8PtrTy)
6758 NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
6760 NewBaseBuilder.CreatePtrAdd(NewBaseGEP, BaseIndex,
"splitgep");
6761 NewGEPBases.
insert(NewBaseGEP);
6767 LargeOffsetGEPs.
front().second, LargeOffsetGEPs.
back().second)) {
6768 BaseOffset = PreferBase;
6771 createNewBase(BaseOffset, OldBase, BaseGEP);
6774 auto *LargeOffsetGEP = LargeOffsetGEPs.
begin();
6775 while (LargeOffsetGEP != LargeOffsetGEPs.
end()) {
6776 GetElementPtrInst *
GEP = LargeOffsetGEP->first;
6777 int64_t
Offset = LargeOffsetGEP->second;
6778 if (
Offset != BaseOffset) {
6785 GEP->getResultElementType(),
6786 GEP->getAddressSpace())) {
6792 NewBaseGEP =
nullptr;
6797 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
6802 createNewBase(BaseOffset, OldBase,
GEP);
6806 Value *NewGEP = NewBaseGEP;
6807 if (
Offset != BaseOffset) {
6810 NewGEP = Builder.CreatePtrAdd(NewBaseGEP, Index);
6814 LargeOffsetGEP = LargeOffsetGEPs.
erase(LargeOffsetGEP);
6815 GEP->eraseFromParent();
6822bool CodeGenPrepare::optimizePhiType(
6823 PHINode *
I, SmallPtrSetImpl<PHINode *> &Visited,
6824 SmallPtrSetImpl<Instruction *> &DeletedInstrs) {
6829 Type *PhiTy =
I->getType();
6830 Type *ConvertTy =
nullptr;
6832 (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatingPointTy()))
6835 SmallVector<Instruction *, 4> Worklist;
6837 SmallPtrSet<PHINode *, 4> PhiNodes;
6838 SmallPtrSet<ConstantData *, 4>
Constants;
6841 SmallPtrSet<Instruction *, 4> Defs;
6842 SmallPtrSet<Instruction *, 4>
Uses;
6848 bool AnyAnchored =
false;
6850 while (!Worklist.
empty()) {
6855 for (
Value *V :
Phi->incoming_values()) {
6857 if (!PhiNodes.
count(OpPhi)) {
6858 if (!Visited.
insert(OpPhi).second)
6864 if (!OpLoad->isSimple())
6866 if (Defs.
insert(OpLoad).second)
6869 if (Defs.
insert(OpEx).second)
6873 ConvertTy = OpBC->getOperand(0)->getType();
6874 if (OpBC->getOperand(0)->getType() != ConvertTy)
6876 if (Defs.
insert(OpBC).second) {
6889 for (User *V :
II->users()) {
6891 if (!PhiNodes.
count(OpPhi)) {
6892 if (Visited.
count(OpPhi))
6899 if (!OpStore->isSimple() || OpStore->getOperand(0) !=
II)
6901 Uses.insert(OpStore);
6904 ConvertTy = OpBC->getType();
6905 if (OpBC->getType() != ConvertTy)
6909 any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
6916 if (!ConvertTy || !AnyAnchored || PhiTy == ConvertTy ||
6920 LLVM_DEBUG(
dbgs() <<
"Converting " << *
I <<
"\n and connected nodes to "
6921 << *ConvertTy <<
"\n");
6926 for (ConstantData *
C : Constants)
6928 for (Instruction *
D : Defs) {
6930 ValMap[
D] =
D->getOperand(0);
6934 ValMap[
D] =
new BitCastInst(
D, ConvertTy,
D->getName() +
".bc", insertPt);
6937 for (PHINode *Phi : PhiNodes)
6939 Phi->getName() +
".tc",
Phi->getIterator());
6941 for (PHINode *Phi : PhiNodes) {
6943 for (
int i = 0, e =
Phi->getNumIncomingValues(); i < e; i++)
6945 Phi->getIncomingBlock(i));
6949 for (Instruction *U :
Uses) {
6954 U->setOperand(0,
new BitCastInst(ValMap[
U->getOperand(0)], PhiTy,
"bc",
6964bool CodeGenPrepare::optimizePhiTypes(
Function &
F) {
6965 if (!Opts.cgp_optimize_phi_types)
6969 SmallPtrSet<PHINode *, 4> Visited;
6970 SmallPtrSet<Instruction *, 4> DeletedInstrs;
6974 for (
auto &Phi : BB.
phis())
6975 Changed |= optimizePhiType(&Phi, Visited, DeletedInstrs);
6978 for (
auto *
I : DeletedInstrs) {
6980 I->eraseFromParent();
6988bool CodeGenPrepare::canFormExtLd(
6989 const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI,
6990 Instruction *&Inst,
bool HasPromoted) {
6991 for (
auto *MovedExtInst : MovedExts) {
6994 Inst = MovedExtInst;
7046bool CodeGenPrepare::optimizeExt(Instruction *&Inst) {
7047 bool AllowPromotionWithoutCommonHeader =
false;
7052 *Inst, AllowPromotionWithoutCommonHeader);
7053 TypePromotionTransaction TPT(RemovedInsts);
7054 TypePromotionTransaction::ConstRestorationPt LastKnownGood =
7055 TPT.getRestorationPoint();
7057 SmallVector<Instruction *, 2> SpeculativelyMovedExts;
7060 bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts);
7063 LoadInst *LI =
nullptr;
7068 if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) {
7069 assert(LI && ExtFedByLoad &&
"Expect a valid load and extension");
7074 Inst = ExtFedByLoad;
7079 if (ATPConsiderable &&
7080 performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader,
7081 HasPromoted, TPT, SpeculativelyMovedExts))
7084 TPT.rollback(LastKnownGood);
7093bool CodeGenPrepare::performAddressTypePromotion(
7094 Instruction *&Inst,
bool AllowPromotionWithoutCommonHeader,
7095 bool HasPromoted, TypePromotionTransaction &TPT,
7096 SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) {
7097 bool Promoted =
false;
7098 SmallPtrSet<Instruction *, 1> UnhandledExts;
7099 bool AllSeenFirst =
true;
7100 for (
auto *
I : SpeculativelyMovedExts) {
7101 Value *HeadOfChain =
I->getOperand(0);
7102 auto AlreadySeen = SeenChainsForSExt.
find(HeadOfChain);
7105 if (AlreadySeen != SeenChainsForSExt.
end()) {
7106 if (AlreadySeen->second !=
nullptr)
7107 UnhandledExts.
insert(AlreadySeen->second);
7108 AllSeenFirst =
false;
7112 if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader &&
7113 SpeculativelyMovedExts.size() == 1)) {
7117 for (
auto *
I : SpeculativelyMovedExts) {
7118 Value *HeadOfChain =
I->getOperand(0);
7119 SeenChainsForSExt[HeadOfChain] =
nullptr;
7120 ValToSExtendedUses[HeadOfChain].push_back(
I);
7123 Inst = SpeculativelyMovedExts.pop_back_val();
7128 for (
auto *
I : SpeculativelyMovedExts) {
7129 Value *HeadOfChain =
I->getOperand(0);
7130 SeenChainsForSExt[HeadOfChain] = Inst;
7135 if (!AllSeenFirst && !UnhandledExts.
empty())
7136 for (
auto *VisitedSExt : UnhandledExts) {
7137 if (RemovedInsts.count(VisitedSExt))
7139 TypePromotionTransaction TPT(RemovedInsts);
7141 SmallVector<Instruction *, 2> Chains;
7143 bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains);
7147 for (
auto *
I : Chains) {
7148 Value *HeadOfChain =
I->getOperand(0);
7150 SeenChainsForSExt[HeadOfChain] =
nullptr;
7151 ValToSExtendedUses[HeadOfChain].push_back(
I);
7157bool CodeGenPrepare::optimizeExtUses(Instruction *
I) {
7162 Value *Src =
I->getOperand(0);
7163 if (Src->hasOneUse())
7175 bool DefIsLiveOut =
false;
7176 for (User *U :
I->users()) {
7181 if (UserBB == DefBB)
7183 DefIsLiveOut =
true;
7190 for (User *U : Src->users()) {
7193 if (UserBB == DefBB)
7202 DenseMap<BasicBlock *, Instruction *> InsertedTruncs;
7204 bool MadeChange =
false;
7210 if (UserBB == DefBB)
7214 Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
7216 if (!InsertedTrunc) {
7219 InsertedTrunc =
new TruncInst(
I, Src->getType(),
"");
7221 InsertedInsts.insert(InsertedTrunc);
7234 I->dropPoisonGeneratingFlags();
7290bool CodeGenPrepare::optimizeLoadExt(LoadInst *
Load) {
7291 if (!
Load->isSimple() || !
Load->getType()->isIntOrPtrTy())
7295 if (
Load->hasOneUse() &&
7301 SmallVector<Instruction *, 8> WorkList;
7302 SmallPtrSet<Instruction *, 16> Visited;
7303 SmallVector<Instruction *, 8> AndsToMaybeRemove;
7304 SmallVector<Instruction *, 8> DropFlags;
7305 for (
auto *U :
Load->users())
7317 while (!WorkList.
empty()) {
7321 if (!Visited.
insert(
I).second)
7326 for (
auto *U :
Phi->users())
7331 switch (
I->getOpcode()) {
7332 case Instruction::And: {
7336 APInt AndBits = AndC->getValue();
7337 DemandBits |= AndBits;
7339 if (AndBits.
ugt(WidestAndBits))
7340 WidestAndBits = AndBits;
7341 if (AndBits == WidestAndBits &&
I->getOperand(0) ==
Load)
7346 case Instruction::Shl: {
7351 DemandBits.setLowBits(
BitWidth - ShiftAmt);
7356 case Instruction::Trunc: {
7359 DemandBits.setLowBits(TruncBitWidth);
7369 uint32_t ActiveBits = DemandBits.getActiveBits();
7381 if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) ||
7382 WidestAndBits != DemandBits)
7385 LLVMContext &Ctx =
Load->getType()->getContext();
7386 Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits);
7397 Builder.CreateAnd(
Load, ConstantInt::get(Ctx, DemandBits)));
7400 InsertedInsts.insert(NewAnd);
7405 NewAnd->setOperand(0,
Load);
7408 for (
auto *
And : AndsToMaybeRemove)
7413 if (&*CurInstIterator ==
And)
7414 CurInstIterator = std::next(
And->getIterator());
7415 And->eraseFromParent();
7420 for (
auto *Inst : DropFlags)
7434 TTI->isExpensiveToSpeculativelyExecute(
I);
7452 uint64_t Max = std::max(TrueWeight, FalseWeight);
7453 uint64_t Sum = TrueWeight + FalseWeight;
7456 if (Probability >
TTI->getPredictableBranchThreshold())
7466 if (!Cmp || !Cmp->hasOneUse())
7489 assert(DefSI->getCondition() ==
SI->getCondition() &&
7490 "The condition of DefSI does not match with SI");
7491 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
7494 assert(V &&
"Failed to get select true/false value");
7498bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
7522 BinaryOperator::BinaryOps Opcode = Shift->
getOpcode();
7523 Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), TVal);
7524 Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->
getOperand(0), FVal);
7525 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7531bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
7533 assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) &&
7534 "Expected a funnel shift");
7558 Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, TVal});
7559 Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, {
X,
Y, FVal});
7560 Value *NewSel = Builder.CreateSelect(
Cond, NewTVal, NewFVal);
7568bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
7569 if (!Opts.cgp_select2branch)
7573 if (!Opts.disable_select_optimize)
7580 It !=
SI->getParent()->
end(); ++It) {
7582 if (
I &&
SI->getCondition() ==
I->getCondition()) {
7589 SelectInst *LastSI = ASI.
back();
7592 CurInstIterator = std::next(LastSI->
getIterator());
7596 for (SelectInst *SI :
ArrayRef(ASI).drop_front())
7597 fixupDbgVariableRecordsOnInst(*SI);
7599 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
7602 if (VectorCond ||
SI->getMetadata(LLVMContext::MD_unpredictable))
7605 TargetLowering::SelectSupportKind SelectKind;
7606 if (
SI->getType()->isVectorTy())
7607 SelectKind = TargetLowering::ScalarCondVectorVal;
7609 SelectKind = TargetLowering::ScalarValSelect;
7646 SmallVector<Instruction *> TrueInstrs, FalseInstrs;
7647 for (SelectInst *SI : ASI) {
7659 SplitPt.setHeadBit(
true);
7662 auto *CondFr =
IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
7667 UncondBrInst *TrueBranch =
nullptr;
7668 UncondBrInst *FalseBranch =
nullptr;
7669 if (TrueInstrs.
size() == 0) {
7674 }
else if (FalseInstrs.
size() == 0) {
7691 EndBlock->
setName(
"select.end");
7693 TrueBlock->
setName(
"select.true.sink");
7695 FalseBlock->
setName(FalseInstrs.
size() == 0 ?
"select.false"
7696 :
"select.false.sink");
7700 FreshBBs.
insert(TrueBlock);
7702 FreshBBs.
insert(FalseBlock);
7703 FreshBBs.
insert(EndBlock);
7708 static const unsigned MD[] = {
7709 LLVMContext::MD_prof, LLVMContext::MD_unpredictable,
7710 LLVMContext::MD_make_implicit, LLVMContext::MD_dbg};
7715 for (Instruction *
I : TrueInstrs)
7717 for (Instruction *
I : FalseInstrs)
7724 if (TrueBlock ==
nullptr)
7725 TrueBlock = StartBlock;
7726 else if (FalseBlock ==
nullptr)
7727 FalseBlock = StartBlock;
7743 SI->eraseFromParent();
7745 ++NumSelectsExpanded;
7749 CurInstIterator = StartBlock->
end();
7756bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
7768 "Expected a type of the same size!");
7774 Value *BC1 = Builder.CreateBitCast(
7776 Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
7777 Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
7781 SVI, TLInfo,
nullptr,
7782 [&](
Value *V) { removeAllAssertingVHReferences(V); });
7789 !
Op->isTerminator() && !
Op->isEHPad())
7795bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *
I) {
7810 for (Use *U :
reverse(OpsToSink)) {
7822 SetVector<Instruction *> MaybeDead;
7823 DenseMap<Instruction *, Instruction *> NewInstructions;
7824 for (Use *U : ToReplace) {
7833 FreshBBs.
insert(OpDef->getParent());
7836 NewInstructions[UI] = NI;
7841 InsertedInsts.insert(NI);
7847 if (
auto It = NewInstructions.
find(OldI); It != NewInstructions.
end())
7848 It->second->setOperand(
U->getOperandNo(), NI);
7855 for (
auto *
I : MaybeDead) {
7856 if (!
I->hasNUsesOrMore(1)) {
7858 I->eraseFromParent();
7865bool CodeGenPrepare::optimizeSwitchType(SwitchInst *SI) {
7871 unsigned RegWidth =
RegType.getSizeInBits();
7882 auto *NewType = Type::getIntNTy(
Context, RegWidth);
7891 ExtType = Instruction::SExt;
7894 if (Arg->hasSExtAttr())
7895 ExtType = Instruction::SExt;
7896 if (Arg->hasZExtAttr())
7897 ExtType = Instruction::ZExt;
7903 SI->setCondition(ExtInst);
7904 for (
auto Case :
SI->cases()) {
7905 const APInt &NarrowConst = Case.getCaseValue()->getValue();
7906 APInt WideConst = (ExtType == Instruction::ZExt)
7907 ? NarrowConst.
zext(RegWidth)
7908 : NarrowConst.
sext(RegWidth);
7909 Case.setValue(ConstantInt::get(
Context, WideConst));
7915bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
7922 Value *Condition =
SI->getCondition();
7931 for (
const SwitchInst::CaseHandle &Case :
SI->cases()) {
7932 ConstantInt *CaseValue = Case.getCaseValue();
7933 BasicBlock *CaseBB = Case.getCaseSuccessor();
7936 bool CheckedForSinglePred =
false;
7937 for (PHINode &
PHI : CaseBB->
phis()) {
7938 Type *PHIType =
PHI.getType();
7946 if (PHIType == ConditionType || TryZExt) {
7948 bool SkipCase =
false;
7949 Value *Replacement =
nullptr;
7950 for (
unsigned I = 0,
E =
PHI.getNumIncomingValues();
I !=
E;
I++) {
7951 Value *PHIValue =
PHI.getIncomingValue(
I);
7952 if (PHIValue != CaseValue) {
7961 if (
PHI.getIncomingBlock(
I) != SwitchBB)
7966 if (!CheckedForSinglePred) {
7967 CheckedForSinglePred =
true;
7968 if (
SI->findCaseDest(CaseBB) ==
nullptr) {
7974 if (Replacement ==
nullptr) {
7975 if (PHIValue == CaseValue) {
7976 Replacement = Condition;
7979 Replacement = Builder.CreateZExt(Condition, PHIType);
7982 PHI.setIncomingValue(
I, Replacement);
7993bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
7994 bool Changed = optimizeSwitchType(SI);
7995 Changed |= optimizeSwitchPhiConstants(SI);
8016class VectorPromoteHelper {
8018 const DataLayout &
DL;
8021 const TargetLowering &TLI;
8024 const TargetTransformInfo &
TTI;
8030 SmallVector<Instruction *, 4> InstsToBePromoted;
8033 unsigned StoreExtractCombineCost;
8035 bool StressStoreExtract;
8044 if (InstsToBePromoted.
empty())
8046 return InstsToBePromoted.
back();
8052 unsigned getTransitionOriginalValueIdx()
const {
8054 "Other kind of transitions are not supported yet");
8061 unsigned getTransitionIdx()
const {
8063 "Other kind of transitions are not supported yet");
8071 Type *getTransitionType()
const {
8082 void promoteImpl(Instruction *ToBePromoted);
8086 bool isProfitableToPromote() {
8087 Value *ValIdx = Transition->
getOperand(getTransitionOriginalValueIdx());
8091 Type *PromotedType = getTransitionType();
8094 unsigned AS =
ST->getPointerAddressSpace();
8112 for (
const auto &Inst : InstsToBePromoted) {
8120 TargetTransformInfo::OperandValueInfo Arg0Info, Arg1Info;
8129 CostKind, Arg0Info, Arg1Info);
8132 dbgs() <<
"Estimated cost of computation to be promoted:\nScalar: "
8133 << ScalarCost <<
"\nVector: " << VectorCost <<
'\n');
8134 return ScalarCost > VectorCost;
8146 unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
8161 if (!
EC.isScalable()) {
8162 SmallVector<Constant *, 4> ConstVec;
8164 for (
unsigned Idx = 0;
Idx !=
EC.getKnownMinValue(); ++
Idx) {
8165 if (Idx == ExtractIdx)
8173 "Generate scalable vector for non-splat is unimplemented");
8178 static bool canCauseUndefinedBehavior(
const Instruction *Use,
8179 unsigned OperandIdx) {
8182 if (OperandIdx != 1)
8184 switch (
Use->getOpcode()) {
8187 case Instruction::SDiv:
8188 case Instruction::UDiv:
8189 case Instruction::SRem:
8190 case Instruction::URem:
8192 case Instruction::FDiv:
8193 case Instruction::FRem:
8194 return !
Use->hasNoNaNs();
8200 VectorPromoteHelper(
const DataLayout &
DL,
const TargetLowering &TLI,
8201 const TargetTransformInfo &
TTI, Instruction *Transition,
8202 unsigned CombineCost,
bool StressStoreExtract)
8203 :
DL(
DL), TLI(TLI),
TTI(
TTI), Transition(Transition),
8204 StoreExtractCombineCost(CombineCost),
8205 StressStoreExtract(StressStoreExtract) {
8206 assert(Transition &&
"Do not know how to promote null");
8210 bool canPromote(
const Instruction *ToBePromoted)
const {
8217 bool shouldPromote(
const Instruction *ToBePromoted)
const {
8222 for (
const Use &U : ToBePromoted->
operands()) {
8223 const Value *Val =
U.get();
8224 if (Val == getEndOfTransition()) {
8235 return StressStoreExtract ||
8246 void enqueueForPromotion(Instruction *ToBePromoted) {
8247 InstsToBePromoted.push_back(ToBePromoted);
8251 void recordCombineInstruction(Instruction *ToBeCombined) {
8253 CombineInst = ToBeCombined;
8263 if (InstsToBePromoted.empty() || !CombineInst)
8267 if (!StressStoreExtract && !isProfitableToPromote())
8271 for (
auto &ToBePromoted : InstsToBePromoted)
8272 promoteImpl(ToBePromoted);
8273 InstsToBePromoted.clear();
8280void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
8290 "The type of the result of the transition does not match "
8295 Type *TransitionTy = getTransitionType();
8300 for (Use &U : ToBePromoted->
operands()) {
8302 Value *NewVal =
nullptr;
8303 if (Val == Transition)
8304 NewVal = Transition->
getOperand(getTransitionOriginalValueIdx());
8311 canCauseUndefinedBehavior(ToBePromoted,
U.getOperandNo()));
8315 ToBePromoted->
setOperand(
U.getOperandNo(), NewVal);
8318 Transition->
setOperand(getTransitionOriginalValueIdx(), ToBePromoted);
8324bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
8325 unsigned CombineCost = std::numeric_limits<unsigned>::max();
8326 if (!Opts.cgp_store_extract ||
8327 (!Opts.cgp_stress_store_extract &&
8340 LLVM_DEBUG(
dbgs() <<
"Found an interesting transition: " << *Inst <<
'\n');
8341 VectorPromoteHelper VPH(*
DL, *TLI, *
TTI, Inst, CombineCost,
8342 Opts.cgp_stress_store_extract);
8349 if (ToBePromoted->
getParent() != Parent) {
8350 LLVM_DEBUG(
dbgs() <<
"Instruction to promote is in a different block ("
8352 <<
") than the transition (" << Parent->
getName()
8357 if (VPH.canCombine(ToBePromoted)) {
8359 <<
"will be combined with: " << *ToBePromoted <<
'\n');
8360 VPH.recordCombineInstruction(ToBePromoted);
8362 NumStoreExtractExposed +=
Changed;
8367 if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted))
8370 LLVM_DEBUG(
dbgs() <<
"Promoting is possible... Enqueue for promotion!\n");
8372 VPH.enqueueForPromotion(ToBePromoted);
8373 Inst = ToBePromoted;
8412 bool ForceSplitStore) {
8414 Type *StoreType =
SI.getValueOperand()->getType();
8423 if (!
DL.typeSizeEqualsStoreSize(StoreType) ||
8424 DL.getTypeSizeInBits(StoreType) == 0)
8427 unsigned HalfValBitSize =
DL.getTypeSizeInBits(StoreType) / 2;
8429 if (!
DL.typeSizeEqualsStoreSize(SplitStoreType))
8445 if (!
match(
SI.getValueOperand(),
8452 if (!
LValue->getType()->isIntegerTy() ||
8453 DL.getTypeSizeInBits(
LValue->getType()) > HalfValBitSize ||
8455 DL.getTypeSizeInBits(HValue->
getType()) > HalfValBitSize)
8474 if (LBC && LBC->getParent() !=
SI.getParent())
8475 LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType());
8476 if (HBC && HBC->getParent() !=
SI.getParent())
8477 HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType());
8479 bool IsLE =
SI.getDataLayout().isLittleEndian();
8480 auto CreateSplitStore = [&](
Value *V,
bool Upper) {
8481 V = Builder.CreateZExtOrBitCast(V, SplitStoreType);
8482 Value *Addr =
SI.getPointerOperand();
8483 Align Alignment =
SI.getAlign();
8484 const bool IsOffsetStore = (IsLE &&
Upper) || (!IsLE && !
Upper);
8485 if (IsOffsetStore) {
8486 Addr = Builder.CreateGEP(
8487 SplitStoreType, Addr,
8495 Builder.CreateAlignedStore(V, Addr, Alignment);
8498 CreateSplitStore(
LValue,
false);
8499 CreateSplitStore(HValue,
true);
8502 SI.eraseFromParent();
8510 return GEP->getNumOperands() == 2 &&
I.isSequential() &&
8592 if (GEPIOpI->getParent() != SrcBlock)
8597 if (auto *I = dyn_cast<Instruction>(Usr)) {
8598 if (I->getParent() != SrcBlock) {
8606 std::vector<GetElementPtrInst *> UGEPIs;
8609 for (User *Usr : GEPIOp->
users()) {
8628 if (UGEPI->getOperand(0) != GEPIOp)
8630 if (UGEPI->getSourceElementType() != GEPI->getSourceElementType())
8632 if (GEPIIdx->getType() !=
8640 UGEPIs.push_back(UGEPI);
8642 if (UGEPIs.size() == 0)
8645 for (GetElementPtrInst *UGEPI : UGEPIs) {
8647 APInt NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8654 for (GetElementPtrInst *UGEPI : UGEPIs) {
8655 UGEPI->setOperand(0, GEPI);
8657 auto NewIdx = UGEPIIdx->
getValue() - GEPIIdx->getValue();
8658 Constant *NewUGEPIIdx = ConstantInt::get(GEPIIdx->getType(), NewIdx);
8659 UGEPI->setOperand(1, NewUGEPIIdx);
8661 auto SourceFlags = GEPI->getNoWrapFlags();
8664 UGEPI->getNoWrapFlags().intersectForOffsetAdd(SourceFlags);
8666 if (NewIdx.
isNegative() && TargetFlags.hasNoUnsignedWrap())
8667 TargetFlags = TargetFlags.withoutNoUnsignedWrap();
8668 UGEPI->setNoWrapFlags(TargetFlags);
8674 return cast<Instruction>(Usr)->getParent() != SrcBlock;
8676 "GEPIOp is used outside SrcBlock");
8700 Value *
X = Cmp->getOperand(0);
8701 if (!
X->hasUseList())
8706 for (
auto *U :
X->users()) {
8710 (UI->
getParent() != Branch->getParent() &&
8711 UI->
getParent() != Branch->getSuccessor(0) &&
8712 UI->
getParent() != Branch->getSuccessor(1)) ||
8713 (UI->
getParent() != Branch->getParent() &&
8714 !UI->
getParent()->getSinglePredecessor()))
8720 if (UI->
getParent() != Branch->getParent())
8724 ConstantInt::get(UI->
getType(), 0));
8726 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8730 if (Cmp->isEquality() &&
8735 if (UI->
getParent() != Branch->getParent())
8738 Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
8739 ConstantInt::get(UI->
getType(), 0));
8741 LLVM_DEBUG(
dbgs() <<
" to compare on zero: " << *NewCmp <<
"\n");
8749bool CodeGenPrepare::optimizeInst(Instruction *
I, ModifyDT &ModifiedDT) {
8750 bool AnyChange =
false;
8751 AnyChange = fixupDbgVariableRecordsOnInst(*
I);
8755 if (InsertedInsts.count(
I))
8764 LargeOffsetGEPMap.erase(
P);
8766 P->eraseFromParent();
8797 I, LI->getLoopFor(
I->getParent()), *
TTI))
8805 TargetLowering::TypeExpandInteger) {
8809 I, LI->getLoopFor(
I->getParent()), *
TTI))
8812 bool MadeChange = optimizeExt(
I);
8813 return MadeChange | optimizeExtUses(
I);
8820 if (optimizeCmp(Cmp, ModifiedDT))
8824 if (optimizeURem(
I))
8828 LI->
setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8829 bool Modified = optimizeLoadExt(LI);
8838 bool Modified = tryToSinkFreeOperands(
I);
8839 SI->setMetadata(LLVMContext::MD_invariant_group,
nullptr);
8840 unsigned AS =
SI->getPointerAddressSpace();
8841 Modified |= optimizeMemoryInst(
I,
SI->getOperand(1),
8842 SI->getOperand(0)->getType(), AS);
8847 unsigned AS = RMW->getPointerAddressSpace();
8848 return optimizeMemoryInst(
I, RMW->getPointerOperand(), RMW->getType(), AS);
8852 unsigned AS = CmpX->getPointerAddressSpace();
8853 return optimizeMemoryInst(
I, CmpX->getPointerOperand(),
8854 CmpX->getCompareOperand()->getType(), AS);
8859 if (BinOp && BinOp->
getOpcode() == Instruction::And &&
8860 Opts.cgp_andcmp_sinking &&
8865 if (BinOp && (BinOp->
getOpcode() == Instruction::AShr ||
8866 BinOp->
getOpcode() == Instruction::LShr)) {
8874 if (GEPI->hasAllZeroIndices()) {
8876 Instruction *
NC =
new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
8877 GEPI->getName(), GEPI->getIterator());
8878 NC->setDebugLoc(GEPI->getDebugLoc());
8881 GEPI, TLInfo,
nullptr,
8882 [&](
Value *V) { removeAllAssertingVHReferences(V); });
8884 optimizeInst(
NC, ModifiedDT);
8902 if (Const0 || Const1) {
8903 if (!Const0 || !Const1) {
8904 auto *
F =
new FreezeInst(Const0 ? Op1 : Op0,
"", CmpI->
getIterator());
8910 FI->eraseFromParent();
8918 if (
I->getType()->isVectorTy() &&
8922 if (tryToSinkFreeOperands(
I))
8925 switch (
I->getOpcode()) {
8926 case Instruction::Shl:
8927 case Instruction::LShr:
8928 case Instruction::AShr:
8930 case Instruction::Call:
8932 case Instruction::Select:
8934 case Instruction::ShuffleVector:
8936 case Instruction::Switch:
8938 case Instruction::ExtractElement:
8940 case Instruction::CondBr:
8949bool CodeGenPrepare::makeBitReverse(Instruction &
I) {
8950 if (!
I.getType()->isIntegerTy() ||
8955 SmallVector<Instruction *, 4> Insts;
8961 &
I, TLInfo,
nullptr,
8962 [&](
Value *V) { removeAllAssertingVHReferences(V); });
8969bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
8971 bool MadeChange =
false;
8974 CurInstIterator = BB.
begin();
8975 ModifiedDT = ModifyDT::NotModifyDT;
8976 while (CurInstIterator != BB.
end()) {
8977 MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT);
8978 if (ModifiedDT != ModifyDT::NotModifyDT) {
8987 }
while (ModifiedDT == ModifyDT::ModifyInstDT);
8989 bool MadeBitReverse =
true;
8990 while (MadeBitReverse) {
8991 MadeBitReverse =
false;
8993 if (makeBitReverse(
I)) {
8994 MadeBitReverse = MadeChange =
true;
8999 MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT);
9004bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &
I) {
9005 bool AnyChange =
false;
9006 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange()))
9007 AnyChange |= fixupDbgVariableRecord(DVR);
9013bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
9014 if (DVR.
Type != DbgVariableRecord::LocationType::Value &&
9015 DVR.
Type != DbgVariableRecord::LocationType::Assign)
9019 bool AnyChange =
false;
9020 SmallDenseSet<Value *> LocationOps(DVR.
location_ops().begin(),
9022 for (
Value *Location : LocationOps) {
9023 WeakTrackingVH SunkAddrVH = SunkAddrs[
Location];
9052bool CodeGenPrepare::placeDbgValues(
Function &
F) {
9053 bool MadeChange =
false;
9054 DominatorTree &DT = getDT();
9056 auto DbgProcessor = [&](
auto *DbgItem,
Instruction *Position) {
9057 SmallVector<Instruction *, 4> VIs;
9058 for (
Value *V : DbgItem->location_ops())
9066 for (Instruction *VI : VIs) {
9067 if (
VI->isTerminator())
9072 if (
isa<PHINode>(VI) &&
VI->getParent()->getTerminator()->isEHPad())
9083 if (VIs.size() > 1) {
9086 <<
"Unable to find valid location for Debug Value, undefing:\n"
9088 DbgItem->setKillLocation();
9093 << *DbgItem <<
' ' << *VI);
9100 for (BasicBlock &BB :
F) {
9106 if (DVR.
Type != DbgVariableRecord::LocationType::Value)
9108 DbgProcessor(&DVR, &Insn);
9119bool CodeGenPrepare::placePseudoProbes(
Function &
F) {
9120 bool MadeChange =
false;
9123 auto FirstInst =
Block.getFirstInsertionPt();
9128 while (
I !=
Block.end()) {
9130 II->moveBefore(FirstInst);
9160bool CodeGenPrepare::splitBranchCondition(
Function &
F) {
9164 bool MadeChange =
false;
9165 for (
auto &BB :
F) {
9178 if (Br1->getMetadata(LLVMContext::MD_unpredictable))
9186 Value *Cond1, *Cond2;
9189 Opc = Instruction::And;
9192 Opc = Instruction::Or;
9202 if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
9216 Br1->setCondition(Cond1);
9221 if (
Opc == Instruction::And)
9222 Br1->setSuccessor(0, TmpBB);
9224 Br1->setSuccessor(1, TmpBB);
9229 I->removeFromParent();
9230 I->insertBefore(Br2->getIterator());
9242 if (
Opc == Instruction::Or)
9246 TBB->replacePhiUsesWith(&BB, TmpBB);
9249 for (PHINode &PN : FBB->
phis()) {
9254 if (
Loop *L = LI->getLoopFor(&BB))
9255 L->addBasicBlockToLoop(TmpBB, *LI);
9259 DTU->
applyUpdates({{DominatorTree::Insert, &BB, TmpBB},
9260 {DominatorTree::Insert, TmpBB,
TBB},
9261 {DominatorTree::Insert, TmpBB, FBB},
9262 {DominatorTree::Delete, &BB,
TBB}});
9266 if (
Opc == Instruction::Or) {
9288 uint64_t NewTrueWeight = TrueWeight;
9289 uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;
9293 NewTrueWeight = TrueWeight;
9294 NewFalseWeight = 2 * FalseWeight;
9319 uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight;
9320 uint64_t NewFalseWeight = FalseWeight;
9324 NewTrueWeight = 2 * TrueWeight;
9325 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...
This file declares the LLVM IR specialization of the GenericCycle templates.
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
static Value * getCondition(Instruction *I)
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static void eraseInstruction(Instruction &I, const LICMDependencies &Deps)
Register const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the PointerIntPair class.
This file contains the declarations for profiling metadata utility functions.
SmallVector< MachineOperand, 4 > Cond
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
static DominatorTree getDomTree(Function &F)
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, const MachineInstr &B)
Remove Loads Into Fake Uses
static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, unsigned CombineOpc=0)
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
static Constant * getConstantVector(MVT VT, ArrayRef< APInt > Bits, const APInt &Undefs, LLVMContext &C)
Class for arbitrary precision integers.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isNegative() const
Determine sign of this APInt.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
unsigned getSignificantBits() const
Get the minimum bit size for this signed APInt.
unsigned logBase2() const
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
int64_t getSExtValue() const
Get sign extended value.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
void setAlignment(Align Align)
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addRequired()
Represent a constant reference to an array (0 or more elements consecutively in memory),...
An instruction that atomically checks whether a specified value is in a memory location,...
static unsigned getPointerOperandIndex()
an instruction that atomically reads a memory location, combines it with another value,...
static unsigned getPointerOperandIndex()
Analysis pass providing the BasicBlockSectionsProfileReader.
LLVM_ABI bool isFunctionHot(StringRef FuncName) const
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI void insertDbgRecordBefore(DbgRecord *DR, InstListType::iterator Here)
Insert a DbgRecord into a block at the position given by Here.
InstListType::const_iterator const_iterator
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
LLVM_ABI InstListType::const_iterator getFirstNonPHIOrPseudoProbe() const
Returns an iterator to the first instruction in this block that is not a PHINode or a pseudo operatio...
LLVM_ABI void insertDbgRecordAfter(DbgRecord *DR, Instruction *I)
Insert a DbgRecord into a block at the position given by I.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
This class represents a no-op cast from one type to another.
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI void setBlockFreq(const BasicBlock *BB, BlockFrequency Freq)
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
Analysis pass which computes BranchProbabilityInfo.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
Predicate getPredicate() const
Return the predicate for this instruction.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Conditional Branch instruction.
static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI void removeFromParent()
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LocationType Type
Classification of the debug-info record that this DbgVariableRecord represents.
LLVM_ABI void replaceVariableLocationOp(Value *OldValue, Value *NewValue, bool AllowEmpty=false)
LLVM_ABI iterator_range< location_op_iterator > location_ops() const
Get the locations corresponding to the variable referenced by the debug info intrinsic.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
LLVM_ABI void deleteBB(BasicBlock *DelBB)
Delete DelBB.
Analysis pass which computes a DominatorTree.
static constexpr UpdateKind Insert
Legacy analysis pass which computes a DominatorTree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This instruction compares its operands according to the predicate given to the constructor.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionPass class - This class is used to implement most global optimizations.
const BasicBlock & getEntryBlock() const
LLVM_ABI const Value * getStatepoint() const
The statepoint with which this gc.relocate is associated.
Represents calls to the gc.relocate intrinsic.
unsigned getBasePtrIndex() const
The index into the associate statepoint's argument list which contains the base pointer of the pointe...
void compute(FunctionT &F)
Compute the cycle info for a function.
DomTreeT & getDomTree()
Flush DomTree updates and return DomTree.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
void flush()
Apply all pending updates to available trees and flush all BasicBlocks awaiting deletion.
bool isBBPendingDeletion(BasicBlockT *DelBB) const
Returns true if DelBB is awaiting deletion.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static LLVM_ABI Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)
Returns the result type of a getelementptr with the given source element type and indexes.
LLVM_ABI bool canIncreaseAlignment() const
Returns true if the alignment of the value can be unilaterally increased.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This instruction compares its operands according to the predicate given to the constructor.
bool isEquality() const
Return true if this predicate is either EQ or NE.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
user_iterator_impl< Instruction > user_iterator
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
LLVM_ABI void moveAfter(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
iterator_range< user_iterator > users()
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
user_iterator user_begin()
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
LLVM_ABI std::optional< simple_ilist< DbgRecord >::iterator > getDbgReinsertionPosition()
Return an iterator to the position of the "Next" DbgRecord after this instruction,...
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
LLVM_ABI void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction.
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)
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.