88using namespace PatternMatch;
90#define DEBUG_TYPE "dse"
92STATISTIC(NumRemainingStores,
"Number of stores remaining after DSE");
93STATISTIC(NumRedundantStores,
"Number of redundant stores deleted");
94STATISTIC(NumFastStores,
"Number of stores deleted");
95STATISTIC(NumFastOther,
"Number of other instrs removed");
96STATISTIC(NumCompletePartials,
"Number of stores dead by later partials");
97STATISTIC(NumModifiedStores,
"Number of stores modified");
98STATISTIC(NumCFGChecks,
"Number of stores modified");
102 "Number of times a valid candidate is returned from getDomMemoryDef");
104 "Number iterations check for reads in getDomMemoryDef");
107 "Controls which MemoryDefs are eliminated.");
112 cl::desc(
"Enable partial-overwrite tracking in DSE"));
117 cl::desc(
"Enable partial store merging in DSE"));
121 cl::desc(
"The number of memory instructions to scan for "
122 "dead store elimination (default = 150)"));
125 cl::desc(
"The maximum number of steps while walking upwards to find "
126 "MemoryDefs that may be killed (default = 90)"));
130 cl::desc(
"The maximum number candidates that only partially overwrite the "
131 "killing MemoryDef to consider"
136 cl::desc(
"The number of MemoryDefs we consider as candidates to eliminated "
137 "other stores per basic block (default = 5000)"));
142 "The cost of a step in the same basic block as the killing MemoryDef"
148 cl::desc(
"The cost of a step in a different basic "
149 "block than the killing MemoryDef"
154 cl::desc(
"The maximum number of blocks to check when trying to prove that "
155 "all paths to an exit go through a killing block (default = 50)"));
165 cl::desc(
"Allow DSE to optimize memory accesses."));
177 if (isa<StoreInst>(
I))
181 switch (
II->getIntrinsicID()) {
182 default:
return false;
183 case Intrinsic::memset:
184 case Intrinsic::memcpy:
185 case Intrinsic::memcpy_element_unordered_atomic:
186 case Intrinsic::memset_element_unordered_atomic:
203 return isa<AnyMemSetInst>(
I);
221enum OverwriteResult {
225 OW_PartialEarlierWithFullLater,
239 const auto *KillingII = dyn_cast<IntrinsicInst>(KillingI);
240 const auto *DeadII = dyn_cast<IntrinsicInst>(DeadI);
241 if (KillingII ==
nullptr || DeadII ==
nullptr)
243 if (KillingII->getIntrinsicID() != DeadII->getIntrinsicID())
245 if (KillingII->getIntrinsicID() == Intrinsic::masked_store) {
248 cast<VectorType>(KillingII->getArgOperand(0)->getType());
249 VectorType *DeadTy = cast<VectorType>(DeadII->getArgOperand(0)->getType());
250 if (KillingTy->getScalarSizeInBits() != DeadTy->getScalarSizeInBits())
253 if (KillingTy->getElementCount() != DeadTy->getElementCount())
258 if (KillingPtr != DeadPtr && !AA.
isMustAlias(KillingPtr, DeadPtr))
262 if (KillingII->getArgOperand(3) != DeadII->getArgOperand(3))
281 int64_t KillingOff, int64_t DeadOff,
292 KillingOff < int64_t(DeadOff + DeadSize) &&
293 int64_t(KillingOff + KillingSize) >= DeadOff) {
296 auto &IM = IOL[DeadI];
297 LLVM_DEBUG(
dbgs() <<
"DSE: Partial overwrite: DeadLoc [" << DeadOff <<
", "
298 << int64_t(DeadOff + DeadSize) <<
") KillingLoc ["
299 << KillingOff <<
", " << int64_t(KillingOff + KillingSize)
306 int64_t KillingIntStart = KillingOff;
307 int64_t KillingIntEnd = KillingOff + KillingSize;
311 auto ILI = IM.lower_bound(KillingIntStart);
312 if (ILI != IM.end() && ILI->second <= KillingIntEnd) {
316 KillingIntStart = std::min(KillingIntStart, ILI->second);
317 KillingIntEnd = std::max(KillingIntEnd, ILI->first);
326 while (ILI != IM.end() && ILI->second <= KillingIntEnd) {
327 assert(ILI->second > KillingIntStart &&
"Unexpected interval");
328 KillingIntEnd = std::max(KillingIntEnd, ILI->first);
333 IM[KillingIntEnd] = KillingIntStart;
336 if (ILI->second <= DeadOff && ILI->first >= int64_t(DeadOff + DeadSize)) {
337 LLVM_DEBUG(
dbgs() <<
"DSE: Full overwrite from partials: DeadLoc ["
338 << DeadOff <<
", " << int64_t(DeadOff + DeadSize)
339 <<
") Composite KillingLoc [" << ILI->second <<
", "
340 << ILI->first <<
")\n");
341 ++NumCompletePartials;
349 int64_t(DeadOff + DeadSize) > KillingOff &&
350 uint64_t(KillingOff - DeadOff) + KillingSize <= DeadSize) {
351 LLVM_DEBUG(
dbgs() <<
"DSE: Partial overwrite a dead load [" << DeadOff
352 <<
", " << int64_t(DeadOff + DeadSize)
353 <<
") by a killing store [" << KillingOff <<
", "
354 << int64_t(KillingOff + KillingSize) <<
")\n");
356 return OW_PartialEarlierWithFullLater;
369 (KillingOff > DeadOff && KillingOff < int64_t(DeadOff + DeadSize) &&
370 int64_t(KillingOff + KillingSize) >= int64_t(DeadOff + DeadSize)))
383 (KillingOff <= DeadOff && int64_t(KillingOff + KillingSize) > DeadOff)) {
384 assert(int64_t(KillingOff + KillingSize) < int64_t(DeadOff + DeadSize) &&
385 "Expect to be handled as OW_Complete");
405 using BlockAddressPair = std::pair<BasicBlock *, PHITransAddr>;
417 if (
auto *MemSet = dyn_cast<MemSetInst>(SecondI))
422 auto *MemLocPtr =
const_cast<Value *
>(MemLoc.
Ptr);
427 bool isFirstBlock =
true;
430 while (!WorkList.
empty()) {
442 assert(
B == SecondBB &&
"first block is not the store block");
444 isFirstBlock =
false;
450 for (; BI != EI; ++BI) {
452 if (
I->mayWriteToMemory() &&
I != SecondI)
458 "Should not hit the entry block because SI must be dominated by LI");
468 auto Inserted = Visited.
insert(std::make_pair(Pred, TranslatedPtr));
469 if (!Inserted.second) {
472 if (TranslatedPtr != Inserted.first->second)
477 WorkList.
push_back(std::make_pair(Pred, PredAddr));
486 uint64_t NewSizeInBits,
bool IsOverwriteEnd) {
488 uint64_t DeadSliceSizeInBits = OldSizeInBits - NewSizeInBits;
490 OldOffsetInBits + (IsOverwriteEnd ? NewSizeInBits : 0);
491 auto SetDeadFragExpr = [](
auto *Assign,
495 uint64_t RelativeOffset = DeadFragment.OffsetInBits -
496 Assign->getExpression()
501 Assign->getExpression(), RelativeOffset, DeadFragment.SizeInBits)) {
502 Assign->setExpression(*
NewExpr);
508 DIExpression::get(Assign->getContext(), std::nullopt),
509 DeadFragment.OffsetInBits, DeadFragment.SizeInBits);
510 Assign->setExpression(Expr);
511 Assign->setKillLocation();
518 auto GetDeadLink = [&Ctx, &LinkToNothing]() {
521 return LinkToNothing;
533 auto InsertAssignForOverlap = [&](
auto *Assign) {
534 std::optional<DIExpression::FragmentInfo> NewFragment;
536 DeadSliceSizeInBits, Assign,
541 Assign->setKillAddress();
542 Assign->setAssignId(GetDeadLink());
546 if (NewFragment->SizeInBits == 0)
550 auto *NewAssign =
static_cast<decltype(Assign)
>(Assign->clone());
551 NewAssign->insertAfter(Assign);
552 NewAssign->setAssignId(GetDeadLink());
554 SetDeadFragExpr(NewAssign, *NewFragment);
555 NewAssign->setKillAddress();
557 for_each(Linked, InsertAssignForOverlap);
558 for_each(LinkedDVRAssigns, InsertAssignForOverlap);
562 uint64_t &DeadSize, int64_t KillingStart,
563 uint64_t KillingSize,
bool IsOverwriteEnd) {
564 auto *DeadIntrinsic = cast<AnyMemIntrinsic>(DeadI);
565 Align PrefAlign = DeadIntrinsic->getDestAlign().valueOrOne();
581 int64_t ToRemoveStart = 0;
585 if (IsOverwriteEnd) {
590 ToRemoveStart = KillingStart + Off;
591 if (DeadSize <=
uint64_t(ToRemoveStart - DeadStart))
593 ToRemoveSize = DeadSize -
uint64_t(ToRemoveStart - DeadStart);
595 ToRemoveStart = DeadStart;
597 "Not overlapping accesses?");
598 ToRemoveSize = KillingSize -
uint64_t(DeadStart - KillingStart);
603 if (ToRemoveSize <= (PrefAlign.
value() - Off))
605 ToRemoveSize -= PrefAlign.
value() - Off;
608 "Should preserve selected alignment");
611 assert(ToRemoveSize > 0 &&
"Shouldn't reach here if nothing to remove");
612 assert(DeadSize > ToRemoveSize &&
"Can't remove more than original size");
614 uint64_t NewSize = DeadSize - ToRemoveSize;
615 if (
auto *AMI = dyn_cast<AtomicMemIntrinsic>(DeadI)) {
618 const uint32_t ElementSize = AMI->getElementSizeInBytes();
619 if (0 != NewSize % ElementSize)
624 << (IsOverwriteEnd ?
"END" :
"BEGIN") <<
": " << *DeadI
625 <<
"\n KILLER [" << ToRemoveStart <<
", "
626 << int64_t(ToRemoveStart + ToRemoveSize) <<
")\n");
628 Value *DeadWriteLength = DeadIntrinsic->getLength();
629 Value *TrimmedLength = ConstantInt::get(DeadWriteLength->
getType(), NewSize);
630 DeadIntrinsic->setLength(TrimmedLength);
631 DeadIntrinsic->setDestAlignment(PrefAlign);
633 Value *OrigDest = DeadIntrinsic->getRawDest();
634 if (!IsOverwriteEnd) {
635 Value *Indices[1] = {
636 ConstantInt::get(DeadWriteLength->
getType(), ToRemoveSize)};
640 NewDestGEP->
setDebugLoc(DeadIntrinsic->getDebugLoc());
641 DeadIntrinsic->setDest(NewDestGEP);
650 DeadStart += ToRemoveSize;
657 int64_t &DeadStart,
uint64_t &DeadSize) {
662 int64_t KillingStart = OII->second;
663 uint64_t KillingSize = OII->first - KillingStart;
665 assert(OII->first - KillingStart >= 0 &&
"Size expected to be positive");
667 if (KillingStart > DeadStart &&
670 (
uint64_t)(KillingStart - DeadStart) < DeadSize &&
673 KillingSize >= DeadSize - (
uint64_t)(KillingStart - DeadStart)) {
674 if (
tryToShorten(DeadI, DeadStart, DeadSize, KillingStart, KillingSize,
685 int64_t &DeadStart,
uint64_t &DeadSize) {
690 int64_t KillingStart = OII->second;
691 uint64_t KillingSize = OII->first - KillingStart;
693 assert(OII->first - KillingStart >= 0 &&
"Size expected to be positive");
695 if (KillingStart <= DeadStart &&
698 KillingSize > (
uint64_t)(DeadStart - KillingStart)) {
701 assert(KillingSize - (
uint64_t)(DeadStart - KillingStart) < DeadSize &&
702 "Should have been handled as OW_Complete");
703 if (
tryToShorten(DeadI, DeadStart, DeadSize, KillingStart, KillingSize,
714 int64_t KillingOffset, int64_t DeadOffset,
741 unsigned BitOffsetDiff = (KillingOffset - DeadOffset) * 8;
742 unsigned LShiftAmount =
743 DL.isBigEndian() ? DeadValue.
getBitWidth() - BitOffsetDiff - KillingBits
746 LShiftAmount + KillingBits);
749 APInt Merged = (DeadValue & ~Mask) | (KillingValue << LShiftAmount);
751 <<
"\n Killing: " << *KillingI
752 <<
"\n Merged Value: " << Merged <<
'\n');
762 switch (
II->getIntrinsicID()) {
763 case Intrinsic::lifetime_start:
764 case Intrinsic::lifetime_end:
765 case Intrinsic::invariant_end:
766 case Intrinsic::launder_invariant_group:
767 case Intrinsic::assume:
769 case Intrinsic::dbg_declare:
770 case Intrinsic::dbg_label:
771 case Intrinsic::dbg_value:
781bool canSkipDef(
MemoryDef *
D,
bool DefVisibleToCaller) {
785 if (
auto *CB = dyn_cast<CallBase>(DI))
786 if (CB->onlyAccessesInaccessibleMemory())
791 if (DI->
mayThrow() && !DefVisibleToCaller)
799 if (isa<FenceInst>(DI))
803 if (isNoopIntrinsic(DI))
832 bool ContainsIrreducibleLoops;
855 bool AnyUnreachableExit;
860 bool ShouldIterateEndOfFunctionDSE;
866 DSEState(
const DSEState &) =
delete;
867 DSEState &operator=(
const DSEState &) =
delete;
872 :
F(
F), AA(AA), EI(DT, &LI), BatchAA(AA, &EI), MSSA(MSSA), DT(DT),
873 PDT(PDT), TLI(TLI),
DL(
F.getDataLayout()), LI(LI) {
878 PostOrderNumbers[BB] = PO++;
881 if (
I.mayThrow() && !MA)
882 ThrowingBlocks.
insert(
I.getParent());
884 auto *MD = dyn_cast_or_null<MemoryDef>(MA);
886 (getLocForWrite(&
I) || isMemTerminatorInst(&
I)))
894 if (AI.hasPassPointeeByValueCopyAttr())
895 InvisibleToCallerAfterRet.
insert({&AI,
true});
901 return isa<UnreachableInst>(E->getTerminator());
909 auto *MA = cast<MemoryAccess>(
U.getUser());
910 if (Visited.
insert(MA).second)
917 if (
auto *CB = dyn_cast<CallBase>(
I)) {
920 (F == LibFunc_memset_chk || F == LibFunc_memcpy_chk)) {
929 if (
const auto *Len = dyn_cast<ConstantInt>(CB->getArgOperand(2)))
944 OverwriteResult isOverwrite(
const Instruction *KillingI,
948 int64_t &KillingOff, int64_t &DeadOff) {
952 if (!isGuaranteedLoopIndependent(DeadI, KillingI, DeadLoc))
956 strengthenLocationSize(KillingI, KillingLoc.
Size);
964 if (DeadUndObj == KillingUndObj && KillingLocSize.
isPrecise() &&
966 std::optional<TypeSize> KillingUndObjSize =
968 if (KillingUndObjSize && *KillingUndObjSize == KillingLocSize.
getValue())
977 const auto *KillingMemI = dyn_cast<MemIntrinsic>(KillingI);
978 const auto *DeadMemI = dyn_cast<MemIntrinsic>(DeadI);
979 if (KillingMemI && DeadMemI) {
980 const Value *KillingV = KillingMemI->getLength();
981 const Value *DeadV = DeadMemI->getLength();
982 if (KillingV == DeadV && BatchAA.
isMustAlias(DeadLoc, KillingLoc))
995 const bool AnyScalable =
1007 if (KillingSize >= DeadSize)
1014 if (Off >= 0 && (
uint64_t)Off + DeadSize <= KillingSize)
1020 if (DeadUndObj != KillingUndObj) {
1036 const Value *DeadBasePtr =
1038 const Value *KillingBasePtr =
1043 if (DeadBasePtr != KillingBasePtr)
1061 if (DeadOff >= KillingOff) {
1064 if (
uint64_t(DeadOff - KillingOff) + DeadSize <= KillingSize)
1068 else if ((
uint64_t)(DeadOff - KillingOff) < KillingSize)
1069 return OW_MaybePartial;
1073 else if ((
uint64_t)(KillingOff - DeadOff) < DeadSize) {
1074 return OW_MaybePartial;
1081 bool isInvisibleToCallerAfterRet(
const Value *V) {
1082 if (isa<AllocaInst>(V))
1084 auto I = InvisibleToCallerAfterRet.
insert({
V,
false});
1086 if (!isInvisibleToCallerOnUnwind(V)) {
1087 I.first->second =
false;
1092 return I.first->second;
1095 bool isInvisibleToCallerOnUnwind(
const Value *V) {
1096 bool RequiresNoCaptureBeforeUnwind;
1099 if (!RequiresNoCaptureBeforeUnwind)
1102 auto I = CapturedBeforeReturn.
insert({
V,
true});
1109 return !
I.first->second;
1112 std::optional<MemoryLocation> getLocForWrite(
Instruction *
I)
const {
1113 if (!
I->mayWriteToMemory())
1114 return std::nullopt;
1116 if (
auto *CB = dyn_cast<CallBase>(
I))
1125 assert(getLocForWrite(
I) &&
"Must have analyzable write");
1129 return SI->isUnordered();
1131 if (
auto *CB = dyn_cast<CallBase>(
I)) {
1133 if (
auto *
MI = dyn_cast<MemIntrinsic>(CB))
1134 return !
MI->isVolatile();
1138 if (CB->isLifetimeStartOrEnd())
1141 return CB->use_empty() && CB->willReturn() && CB->doesNotThrow() &&
1142 !CB->isTerminator();
1158 if (
auto *CB = dyn_cast<CallBase>(UseInst))
1159 if (CB->onlyAccessesInaccessibleMemory())
1162 int64_t InstWriteOffset, DepWriteOffset;
1163 if (
auto CC = getLocForWrite(UseInst))
1164 return isOverwrite(UseInst, DefInst, *
CC, DefLoc, InstWriteOffset,
1165 DepWriteOffset) == OW_Complete;
1172 << *
Def->getMemoryInst()
1173 <<
") is at the end the function \n");
1177 pushMemUses(Def, WorkList, Visited);
1178 for (
unsigned I = 0;
I < WorkList.
size();
I++) {
1185 if (isa<MemoryPhi>(UseAccess)) {
1189 if (!isGuaranteedLoopInvariant(DefLoc.
Ptr))
1192 pushMemUses(cast<MemoryPhi>(UseAccess), WorkList, Visited);
1197 Instruction *UseInst = cast<MemoryUseOrDef>(UseAccess)->getMemoryInst();
1198 if (isReadClobber(DefLoc, UseInst)) {
1199 LLVM_DEBUG(
dbgs() <<
" ... hit read clobber " << *UseInst <<
".\n");
1203 if (
MemoryDef *UseDef = dyn_cast<MemoryDef>(UseAccess))
1204 pushMemUses(UseDef, WorkList, Visited);
1212 std::optional<std::pair<MemoryLocation, bool>>
1220 if (
auto *CB = dyn_cast<CallBase>(
I)) {
1225 return std::nullopt;
1231 auto *CB = dyn_cast<CallBase>(
I);
1232 return CB && (CB->getIntrinsicID() == Intrinsic::lifetime_end ||
1240 std::optional<std::pair<MemoryLocation, bool>> MaybeTermLoc =
1241 getLocForTerminator(MaybeTerm);
1252 auto TermLoc = MaybeTermLoc->first;
1253 if (MaybeTermLoc->second) {
1257 int64_t InstWriteOffset = 0;
1258 int64_t DepWriteOffset = 0;
1259 return isOverwrite(MaybeTerm, AccessI, TermLoc, Loc, InstWriteOffset,
1260 DepWriteOffset) == OW_Complete;
1265 if (isNoopIntrinsic(UseInst))
1270 if (
auto SI = dyn_cast<StoreInst>(UseInst))
1276 if (
auto *CB = dyn_cast<CallBase>(UseInst))
1277 if (CB->onlyAccessesInaccessibleMemory())
1288 bool isGuaranteedLoopIndependent(
const Instruction *Current,
1298 if (!ContainsIrreducibleLoops && CurrentLI &&
1302 return isGuaranteedLoopInvariant(CurrentLoc.
Ptr);
1308 bool isGuaranteedLoopInvariant(
const Value *
Ptr) {
1309 Ptr =
Ptr->stripPointerCasts();
1310 if (
auto *
GEP = dyn_cast<GEPOperator>(
Ptr))
1311 if (
GEP->hasAllConstantIndices())
1312 Ptr =
GEP->getPointerOperand()->stripPointerCasts();
1314 if (
auto *
I = dyn_cast<Instruction>(
Ptr)) {
1315 return I->getParent()->isEntryBlock() ||
1316 (!ContainsIrreducibleLoops && !LI.
getLoopFor(
I->getParent()));
1327 std::optional<MemoryAccess *>
1330 unsigned &ScanLimit,
unsigned &WalkerStepLimit,
1331 bool IsMemTerm,
unsigned &PartialLimit) {
1332 if (ScanLimit == 0 || WalkerStepLimit == 0) {
1334 return std::nullopt;
1351 std::optional<MemoryLocation> CurrentLoc;
1352 for (;; Current = cast<MemoryDef>(Current)->getDefiningAccess()) {
1354 dbgs() <<
" visiting " << *Current;
1356 dbgs() <<
" (" << *cast<MemoryUseOrDef>(Current)->getMemoryInst()
1367 return std::nullopt;
1375 if (WalkerStepLimit <= StepCost) {
1377 return std::nullopt;
1379 WalkerStepLimit -= StepCost;
1383 if (isa<MemoryPhi>(Current)) {
1390 MemoryDef *CurrentDef = cast<MemoryDef>(Current);
1393 if (canSkipDef(CurrentDef, !isInvisibleToCallerOnUnwind(KillingUndObj))) {
1394 CanOptimize =
false;
1400 if (mayThrowBetween(KillingI, CurrentI, KillingUndObj)) {
1402 return std::nullopt;
1407 if (isDSEBarrier(KillingUndObj, CurrentI)) {
1409 return std::nullopt;
1416 if (!isa<IntrinsicInst>(CurrentI) && isReadClobber(KillingLoc, CurrentI))
1417 return std::nullopt;
1420 if (
any_of(Current->
uses(), [
this, &KillingLoc, StartAccess](
Use &U) {
1421 if (auto *UseOrDef = dyn_cast<MemoryUseOrDef>(U.getUser()))
1422 return !MSSA.dominates(StartAccess, UseOrDef) &&
1423 isReadClobber(KillingLoc, UseOrDef->getMemoryInst());
1427 return std::nullopt;
1432 CurrentLoc = getLocForWrite(CurrentI);
1433 if (!CurrentLoc || !isRemovable(CurrentI)) {
1434 CanOptimize =
false;
1441 if (!isGuaranteedLoopIndependent(CurrentI, KillingI, *CurrentLoc)) {
1443 CanOptimize =
false;
1451 if (!isMemTerminator(*CurrentLoc, CurrentI, KillingI)) {
1452 CanOptimize =
false;
1456 int64_t KillingOffset = 0;
1457 int64_t DeadOffset = 0;
1458 auto OR = isOverwrite(KillingI, CurrentI, KillingLoc, *CurrentLoc,
1459 KillingOffset, DeadOffset);
1465 (OR == OW_Complete || OR == OW_MaybePartial))
1471 CanOptimize =
false;
1476 if (OR == OW_Unknown || OR == OW_None)
1478 else if (OR == OW_MaybePartial) {
1483 if (PartialLimit <= 1) {
1484 WalkerStepLimit -= 1;
1485 LLVM_DEBUG(
dbgs() <<
" ... reached partial limit ... continue with next access\n");
1502 Instruction *MaybeDeadI = cast<MemoryDef>(MaybeDeadAccess)->getMemoryInst();
1503 LLVM_DEBUG(
dbgs() <<
" Checking for reads of " << *MaybeDeadAccess <<
" ("
1504 << *MaybeDeadI <<
")\n");
1508 pushMemUses(MaybeDeadAccess, WorkList, Visited);
1511 for (
unsigned I = 0;
I < WorkList.
size();
I++) {
1516 if (ScanLimit < (WorkList.
size() -
I)) {
1518 return std::nullopt;
1521 NumDomMemDefChecks++;
1523 if (isa<MemoryPhi>(UseAccess)) {
1528 LLVM_DEBUG(
dbgs() <<
" ... skipping, dominated by killing block\n");
1532 pushMemUses(UseAccess, WorkList, Visited);
1536 Instruction *UseInst = cast<MemoryUseOrDef>(UseAccess)->getMemoryInst();
1542 LLVM_DEBUG(
dbgs() <<
" ... skipping, dominated by killing def\n");
1548 if (isMemTerminator(MaybeDeadLoc, MaybeDeadI, UseInst)) {
1551 <<
" ... skipping, memterminator invalidates following accesses\n");
1555 if (isNoopIntrinsic(cast<MemoryUseOrDef>(UseAccess)->getMemoryInst())) {
1557 pushMemUses(UseAccess, WorkList, Visited);
1561 if (UseInst->
mayThrow() && !isInvisibleToCallerOnUnwind(KillingUndObj)) {
1563 return std::nullopt;
1568 if (isReadClobber(MaybeDeadLoc, UseInst)) {
1570 return std::nullopt;
1576 if (MaybeDeadAccess == UseAccess &&
1577 !isGuaranteedLoopInvariant(MaybeDeadLoc.
Ptr)) {
1578 LLVM_DEBUG(
dbgs() <<
" ... found not loop invariant self access\n");
1579 return std::nullopt;
1585 if (KillingDef == UseAccess || MaybeDeadAccess == UseAccess) {
1600 if (
MemoryDef *UseDef = dyn_cast<MemoryDef>(UseAccess)) {
1601 if (isCompleteOverwrite(MaybeDeadLoc, MaybeDeadI, UseInst)) {
1603 if (PostOrderNumbers.
find(MaybeKillingBlock)->second <
1604 PostOrderNumbers.
find(MaybeDeadAccess->
getBlock())->second) {
1605 if (!isInvisibleToCallerAfterRet(KillingUndObj)) {
1607 <<
" ... found killing def " << *UseInst <<
"\n");
1608 KillingDefs.
insert(UseInst);
1612 <<
" ... found preceeding def " << *UseInst <<
"\n");
1613 return std::nullopt;
1616 pushMemUses(UseDef, WorkList, Visited);
1623 if (!isInvisibleToCallerAfterRet(KillingUndObj)) {
1626 KillingBlocks.
insert(KD->getParent());
1628 "Expected at least a single killing block");
1642 if (!AnyUnreachableExit)
1643 return std::nullopt;
1647 CommonPred =
nullptr;
1651 if (KillingBlocks.
count(CommonPred))
1652 return {MaybeDeadAccess};
1658 WorkList.
insert(CommonPred);
1661 if (!isa<UnreachableInst>(
R->getTerminator()))
1668 for (
unsigned I = 0;
I < WorkList.
size();
I++) {
1671 if (KillingBlocks.
count(Current))
1673 if (Current == MaybeDeadAccess->
getBlock())
1674 return std::nullopt;
1685 return std::nullopt;
1692 return {MaybeDeadAccess};
1705 while (!NowDeadInsts.
empty()) {
1715 bool IsMemDef = MA && isa<MemoryDef>(MA);
1718 auto *MD = cast<MemoryDef>(MA);
1722 if (
auto *SI = dyn_cast<StoreInst>(MD->getMemoryInst())) {
1723 if (
SI->getValueOperand()->getType()->isPointerTy()) {
1725 if (CapturedBeforeReturn.
erase(UO))
1726 ShouldIterateEndOfFunctionDSE =
true;
1727 InvisibleToCallerAfterRet.
erase(UO);
1732 Updater.removeMemoryAccess(MA);
1736 if (
I != IOLs.
end())
1737 I->second.erase(DeadInst);
1740 if (
Instruction *OpI = dyn_cast<Instruction>(O)) {
1764 const Value *KillingUndObj) {
1768 if (KillingUndObj && isInvisibleToCallerOnUnwind(KillingUndObj))
1773 return !ThrowingBlocks.
empty();
1784 if (DeadI->
mayThrow() && !isInvisibleToCallerOnUnwind(KillingUndObj))
1790 if (
auto *LI = dyn_cast<LoadInst>(DeadI))
1792 if (
auto *SI = dyn_cast<StoreInst>(DeadI))
1794 if (
auto *ARMW = dyn_cast<AtomicRMWInst>(DeadI))
1796 if (
auto *CmpXchg = dyn_cast<AtomicCmpXchgInst>(DeadI))
1806 bool eliminateDeadWritesAtEndOfFunction() {
1807 bool MadeChange =
false;
1810 <<
"Trying to eliminate MemoryDefs at the end of the function\n");
1812 ShouldIterateEndOfFunctionDSE =
false;
1818 auto DefLoc = getLocForWrite(DefI);
1819 if (!DefLoc || !isRemovable(DefI)) {
1821 "instruction not removable.\n");
1831 if (!isInvisibleToCallerAfterRet(UO))
1834 if (isWriteAtEndOfFunction(Def, *DefLoc)) {
1836 LLVM_DEBUG(
dbgs() <<
" ... MemoryDef is not accessed until the end "
1837 "of the function\n");
1843 }
while (ShouldIterateEndOfFunctionDSE);
1851 MemSetInst *MemSet = dyn_cast<MemSetInst>(DefI);
1856 if (!StoredConstant || !StoredConstant->
isNullValue())
1859 if (!isRemovable(DefI))
1863 if (
F.hasFnAttribute(Attribute::SanitizeMemory) ||
1864 F.hasFnAttribute(Attribute::SanitizeAddress) ||
1865 F.hasFnAttribute(Attribute::SanitizeHWAddress) ||
1866 F.getName() ==
"calloc")
1868 auto *
Malloc =
const_cast<CallInst *
>(dyn_cast<CallInst>(DefUO));
1871 auto *InnerCallee =
Malloc->getCalledFunction();
1875 if (!TLI.
getLibFunc(*InnerCallee, Func) || !TLI.
has(Func) ||
1876 Func != LibFunc_malloc)
1886 auto *MallocBB =
Malloc->getParent(),
1887 *MemsetBB = Memset->getParent();
1888 if (MallocBB == MemsetBB)
1890 auto *
Ptr = Memset->getArgOperand(0);
1891 auto *TI = MallocBB->getTerminator();
1897 if (MemsetBB != FalseBB)
1904 if (!shouldCreateCalloc(
Malloc, MemSet) ||
1909 Type *SizeTTy =
Malloc->getArgOperand(0)->getType();
1910 auto *Calloc =
emitCalloc(ConstantInt::get(SizeTTy, 1),
1911 Malloc->getArgOperand(0), IRB, TLI);
1917 Updater.createMemoryAccessAfter(cast<Instruction>(Calloc),
nullptr,
1919 auto *NewAccessMD = cast<MemoryDef>(NewAccess);
1920 Updater.insertDef(NewAccessMD,
true);
1921 Malloc->replaceAllUsesWith(Calloc);
1928 bool dominatingConditionImpliesValue(
MemoryDef *Def) {
1929 auto *StoreI = cast<StoreInst>(
Def->getMemoryInst());
1931 Value *StorePtr = StoreI->getPointerOperand();
1932 Value *StoreVal = StoreI->getValueOperand();
1939 if (!BI || !BI->isConditional())
1945 if (BI->getSuccessor(0) == BI->getSuccessor(1))
1950 if (!
match(BI->getCondition(),
1960 if (Pred == ICmpInst::ICMP_EQ &&
1965 if (Pred == ICmpInst::ICMP_NE &&
1974 return MSSA.
dominates(ClobAcc, LoadAcc);
1982 MemSetInst *MemSet = dyn_cast<MemSetInst>(DefI);
1983 Constant *StoredConstant =
nullptr;
1985 StoredConstant = dyn_cast<Constant>(
Store->getOperand(0));
1987 StoredConstant = dyn_cast<Constant>(MemSet->
getValue());
1991 if (!isRemovable(DefI))
1994 if (StoredConstant) {
1999 if (InitC && InitC == StoredConstant)
2007 if (dominatingConditionImpliesValue(Def))
2010 if (
auto *LoadI = dyn_cast<LoadInst>(
Store->getOperand(0))) {
2011 if (LoadI->getPointerOperand() ==
Store->getOperand(1)) {
2015 if (LoadAccess ==
Def->getDefiningAccess())
2030 for (
unsigned I = 1;
I < ToCheck.
size(); ++
I) {
2031 Current = ToCheck[
I];
2032 if (
auto PhiAccess = dyn_cast<MemoryPhi>(Current)) {
2034 for (
auto &
Use : PhiAccess->incoming_values())
2035 ToCheck.
insert(cast<MemoryAccess>(&
Use));
2041 assert(isa<MemoryDef>(Current) &&
2042 "Only MemoryDefs should reach here.");
2047 if (LoadAccess != Current)
2058 bool Changed =
false;
2059 for (
auto OI : IOL) {
2062 assert(isRemovable(DeadI) &&
"Expect only removable instruction");
2065 int64_t DeadStart = 0;
2079 bool eliminateRedundantStoresOfExistingValues() {
2080 bool MadeChange =
false;
2081 LLVM_DEBUG(
dbgs() <<
"Trying to eliminate MemoryDefs that write the "
2082 "already existing value\n");
2083 for (
auto *Def : MemDefs) {
2088 auto MaybeDefLoc = getLocForWrite(DefInst);
2089 if (!MaybeDefLoc || !isRemovable(DefInst))
2096 if (
Def->isOptimized())
2097 UpperDef = dyn_cast<MemoryDef>(
Def->getOptimized());
2099 UpperDef = dyn_cast<MemoryDef>(
Def->getDefiningAccess());
2104 auto IsRedundantStore = [&]() {
2107 if (
auto *MemSetI = dyn_cast<MemSetInst>(UpperInst)) {
2108 if (
auto *SI = dyn_cast<StoreInst>(DefInst)) {
2110 auto UpperLoc = getLocForWrite(UpperInst);
2113 int64_t InstWriteOffset = 0;
2114 int64_t DepWriteOffset = 0;
2115 auto OR = isOverwrite(UpperInst, DefInst, *UpperLoc, *MaybeDefLoc,
2116 InstWriteOffset, DepWriteOffset);
2118 return StoredByte && StoredByte == MemSetI->getOperand(1) &&
2125 if (!IsRedundantStore() || isReadClobber(*MaybeDefLoc, DefInst))
2127 LLVM_DEBUG(
dbgs() <<
"DSE: Remove No-Op Store:\n DEAD: " << *DefInst
2130 NumRedundantStores++;
2141 bool MadeChange =
false;
2143 DSEState State(
F, AA, MSSA, DT, PDT, TLI, LI);
2145 for (
unsigned I = 0;
I < State.MemDefs.size();
I++) {
2147 if (State.SkipStores.count(KillingDef))
2151 std::optional<MemoryLocation> MaybeKillingLoc;
2152 if (State.isMemTerminatorInst(KillingI)) {
2153 if (
auto KillingLoc = State.getLocForTerminator(KillingI))
2154 MaybeKillingLoc = KillingLoc->first;
2156 MaybeKillingLoc = State.getLocForWrite(KillingI);
2159 if (!MaybeKillingLoc) {
2160 LLVM_DEBUG(
dbgs() <<
"Failed to find analyzable write location for "
2161 << *KillingI <<
"\n");
2165 assert(KillingLoc.
Ptr &&
"KillingLoc should not be null");
2168 << *KillingDef <<
" (" << *KillingI <<
")\n");
2179 [[maybe_unused]]
unsigned OrigNumSkipStores = State.SkipStores.size();
2182 bool Shortend =
false;
2183 bool IsMemTerm = State.isMemTerminatorInst(KillingI);
2185 for (
unsigned I = 0;
I < ToCheck.
size();
I++) {
2187 if (
Deleted.contains(Current))
2190 std::optional<MemoryAccess *> MaybeDeadAccess = State.getDomMemoryDef(
2191 KillingDef, Current, KillingLoc, KillingUndObj, ScanLimit,
2192 WalkerStepLimit, IsMemTerm, PartialLimit);
2194 if (!MaybeDeadAccess) {
2200 LLVM_DEBUG(
dbgs() <<
" Checking if we can kill " << *DeadAccess);
2201 if (isa<MemoryPhi>(DeadAccess)) {
2202 LLVM_DEBUG(
dbgs() <<
"\n ... adding incoming values to worklist\n");
2203 for (
Value *V : cast<MemoryPhi>(DeadAccess)->incoming_values()) {
2211 if (State.PostOrderNumbers[IncomingBlock] >
2212 State.PostOrderNumbers[PhiBlock])
2213 ToCheck.
insert(IncomingAccess);
2217 auto *DeadDefAccess = cast<MemoryDef>(DeadAccess);
2218 Instruction *DeadI = DeadDefAccess->getMemoryInst();
2220 ToCheck.
insert(DeadDefAccess->getDefiningAccess());
2221 NumGetDomMemoryDefPassed++;
2230 if (KillingUndObj != DeadUndObj)
2232 LLVM_DEBUG(
dbgs() <<
"DSE: Remove Dead Store:\n DEAD: " << *DeadI
2233 <<
"\n KILLER: " << *KillingI <<
'\n');
2234 State.deleteDeadInstruction(DeadI, &
Deleted);
2239 int64_t KillingOffset = 0;
2240 int64_t DeadOffset = 0;
2241 OverwriteResult
OR = State.isOverwrite(
2242 KillingI, DeadI, KillingLoc, DeadLoc, KillingOffset, DeadOffset);
2243 if (OR == OW_MaybePartial) {
2244 auto Iter = State.IOLs.insert(
2245 std::make_pair<BasicBlock *, InstOverlapIntervalsTy>(
2247 auto &IOL = Iter.first->second;
2249 DeadOffset, DeadI, IOL);
2253 auto *DeadSI = dyn_cast<StoreInst>(DeadI);
2254 auto *KillingSI = dyn_cast<StoreInst>(KillingI);
2258 if (DeadSI && KillingSI && DT.
dominates(DeadSI, KillingSI)) {
2260 KillingSI, DeadSI, KillingOffset, DeadOffset, State.DL,
2261 State.BatchAA, &DT)) {
2264 DeadSI->setOperand(0, Merged);
2265 ++NumModifiedStores;
2271 State.deleteDeadInstruction(KillingSI, &
Deleted);
2272 auto I = State.IOLs.find(DeadSI->getParent());
2273 if (
I != State.IOLs.end())
2274 I->second.erase(DeadSI);
2280 if (OR == OW_Complete) {
2281 LLVM_DEBUG(
dbgs() <<
"DSE: Remove Dead Store:\n DEAD: " << *DeadI
2282 <<
"\n KILLER: " << *KillingI <<
'\n');
2283 State.deleteDeadInstruction(DeadI, &
Deleted);
2290 assert(State.SkipStores.size() - OrigNumSkipStores ==
Deleted.size() &&
2291 "SkipStores and Deleted out of sync?");
2294 if (!Shortend && State.storeIsNoop(KillingDef, KillingUndObj)) {
2295 LLVM_DEBUG(
dbgs() <<
"DSE: Remove No-Op Store:\n DEAD: " << *KillingI
2297 State.deleteDeadInstruction(KillingI);
2298 NumRedundantStores++;
2304 if (!Shortend && State.tryFoldIntoCalloc(KillingDef, KillingUndObj)) {
2305 LLVM_DEBUG(
dbgs() <<
"DSE: Remove memset after forming calloc:\n"
2306 <<
" DEAD: " << *KillingI <<
'\n');
2307 State.deleteDeadInstruction(KillingI);
2314 for (
auto &KV : State.IOLs)
2315 MadeChange |= State.removePartiallyOverlappedStores(KV.second);
2317 MadeChange |= State.eliminateRedundantStoresOfExistingValues();
2318 MadeChange |= State.eliminateDeadWritesAtEndOfFunction();
2320 while (!State.ToRemove.empty()) {
2321 Instruction *DeadInst = State.ToRemove.pop_back_val();
2340 bool Changed = eliminateDeadStores(
F, AA, MSSA, DT, PDT, TLI, LI);
2342#ifdef LLVM_ENABLE_STATS
2345 NumRemainingStores += isa<StoreInst>(&
I);
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefAnalysis InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static void shortenAssignment(Instruction *Inst, Value *OriginalDest, uint64_t OldOffsetInBits, uint64_t OldSizeInBits, uint64_t NewSizeInBits, bool IsOverwriteEnd)
static bool isShortenableAtTheEnd(Instruction *I)
Returns true if the end of this instruction can be safely shortened in length.
static cl::opt< bool > EnablePartialStoreMerging("enable-dse-partial-store-merging", cl::init(true), cl::Hidden, cl::desc("Enable partial store merging in DSE"))
static bool tryToShortenBegin(Instruction *DeadI, OverlapIntervalsTy &IntervalMap, int64_t &DeadStart, uint64_t &DeadSize)
std::map< int64_t, int64_t > OverlapIntervalsTy
static bool isShortenableAtTheBeginning(Instruction *I)
Returns true if the beginning of this instruction can be safely shortened in length.
static cl::opt< unsigned > MemorySSADefsPerBlockLimit("dse-memoryssa-defs-per-block-limit", cl::init(5000), cl::Hidden, cl::desc("The number of MemoryDefs we consider as candidates to eliminated " "other stores per basic block (default = 5000)"))
static Constant * tryToMergePartialOverlappingStores(StoreInst *KillingI, StoreInst *DeadI, int64_t KillingOffset, int64_t DeadOffset, const DataLayout &DL, BatchAAResults &AA, DominatorTree *DT)
static bool memoryIsNotModifiedBetween(Instruction *FirstI, Instruction *SecondI, BatchAAResults &AA, const DataLayout &DL, DominatorTree *DT)
Returns true if the memory which is accessed by the second instruction is not modified between the fi...
static OverwriteResult isMaskedStoreOverwrite(const Instruction *KillingI, const Instruction *DeadI, BatchAAResults &AA)
Check if two instruction are masked stores that completely overwrite one another.
static cl::opt< unsigned > MemorySSAOtherBBStepCost("dse-memoryssa-otherbb-cost", cl::init(5), cl::Hidden, cl::desc("The cost of a step in a different basic " "block than the killing MemoryDef" "(default = 5)"))
static bool tryToShorten(Instruction *DeadI, int64_t &DeadStart, uint64_t &DeadSize, int64_t KillingStart, uint64_t KillingSize, bool IsOverwriteEnd)
static cl::opt< unsigned > MemorySSAScanLimit("dse-memoryssa-scanlimit", cl::init(150), cl::Hidden, cl::desc("The number of memory instructions to scan for " "dead store elimination (default = 150)"))
static cl::opt< unsigned > MemorySSASameBBStepCost("dse-memoryssa-samebb-cost", cl::init(1), cl::Hidden, cl::desc("The cost of a step in the same basic block as the killing MemoryDef" "(default = 1)"))
static cl::opt< bool > EnablePartialOverwriteTracking("enable-dse-partial-overwrite-tracking", cl::init(true), cl::Hidden, cl::desc("Enable partial-overwrite tracking in DSE"))
static OverwriteResult isPartialOverwrite(const MemoryLocation &KillingLoc, const MemoryLocation &DeadLoc, int64_t KillingOff, int64_t DeadOff, Instruction *DeadI, InstOverlapIntervalsTy &IOL)
Return 'OW_Complete' if a store to the 'KillingLoc' location completely overwrites a store to the 'De...
static cl::opt< unsigned > MemorySSAPartialStoreLimit("dse-memoryssa-partial-store-limit", cl::init(5), cl::Hidden, cl::desc("The maximum number candidates that only partially overwrite the " "killing MemoryDef to consider" " (default = 5)"))
static std::optional< TypeSize > getPointerSize(const Value *V, const DataLayout &DL, const TargetLibraryInfo &TLI, const Function *F)
static bool tryToShortenEnd(Instruction *DeadI, OverlapIntervalsTy &IntervalMap, int64_t &DeadStart, uint64_t &DeadSize)
static cl::opt< unsigned > MemorySSAUpwardsStepLimit("dse-memoryssa-walklimit", cl::init(90), cl::Hidden, cl::desc("The maximum number of steps while walking upwards to find " "MemoryDefs that may be killed (default = 90)"))
static cl::opt< bool > OptimizeMemorySSA("dse-optimize-memoryssa", cl::init(true), cl::Hidden, cl::desc("Allow DSE to optimize memory accesses."))
static cl::opt< unsigned > MemorySSAPathCheckLimit("dse-memoryssa-path-check-limit", cl::init(50), cl::Hidden, cl::desc("The maximum number of blocks to check when trying to prove that " "all paths to an exit go through a killing block (default = 50)"))
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines the DenseMap class.
This is the interface for a simple mod/ref and alias analysis over globals.
static void deleteDeadInstruction(Instruction *I)
This file implements a map that provides insertion order iteration.
This file provides utility analysis objects describing memory locations.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
Module.h This file contains the declarations for the Module class.
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
uint64_t IntrinsicInst * II
This header defines various interfaces for pass management in LLVM.
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
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)
A manager for alias analyses.
Class for arbitrary precision integers.
APInt zext(unsigned width) const
Zero extend to a new width.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
The possible results of an alias query.
@ NoAlias
The two locations do not alias at all.
@ PartialAlias
The two locations alias, but only due to a partial overlap.
@ MustAlias
The two locations precisely alias each other.
constexpr int32_t getOffset() const
constexpr bool hasOffset() const
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents an incoming formal argument to a Function.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
Represents analyses that only rely on functions' control flow.
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
This is an important base class in LLVM.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static DIAssignID * getDistinct(LLVMContext &Context)
static std::optional< DIExpression * > createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits)
Create a DIExpression to describe one part of an aggregate variable that is fragmented across multipl...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
A parsed version of the target data layout string in and methods for querying it.
static bool shouldExecute(unsigned CounterName)
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
DomTreeNodeBase * getIDom() const
Analysis pass which computes a DominatorTree.
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
iterator_range< root_iterator > roots()
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Context-sensitive CaptureInfo provider, which computes and caches the earliest common dominator closu...
void removeInstruction(Instruction *I)
const BasicBlock & getEntryBlock() const
static GetElementPtrInst * CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Create an "inbounds" getelementptr.
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...
bool mayThrow(bool IncludePhaseOneUnwind=false) const LLVM_READONLY
Return true if this instruction may throw an exception.
bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
bool isIdenticalTo(const Instruction *I) const LLVM_READONLY
Return true if the specified instruction is exactly identical to the current one.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
const_iterator begin() const
bool empty() const
empty - Return true when no intervals are mapped.
const_iterator end() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
static LocationSize precise(uint64_t Value)
TypeSize getValue() const
Analysis pass that exposes the LoopInfo for a function.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
This class implements a map that also provides access to all stored values in a deterministic order.
iterator find(const KeyT &Key)
Value * getLength() const
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
BasicBlock * getBlock() const
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
void setOptimized(MemoryAccess *MA)
Representation for a specific memory location.
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
LocationSize Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known.
static MemoryLocation getAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location after Ptr, while remaining within the underlying objec...
MemoryLocation getWithNewPtr(const Value *NewPtr) const
const Value * Ptr
The address of the start of the location.
static MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
static std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
An analysis that produces MemorySSA for a function.
MemoryAccess * getClobberingMemoryAccess(const Instruction *I, BatchAAResults &AA)
Given a memory Mod/Ref/ModRef'ing instruction, calling this will give you the nearest dominating Memo...
Encapsulates MemorySSA, including all data associated with memory accesses.
MemorySSAWalker * getSkipSelfWalker()
bool dominates(const MemoryAccess *A, const MemoryAccess *B) const
Given two memory accesses in potentially different blocks, determine whether MemoryAccess A dominates...
MemorySSAWalker * getWalker()
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
MemoryAccess * getDefiningAccess() const
Get the access that produces the memory state used by this Use.
Instruction * getMemoryInst() const
Get the instruction that this MemoryUse represents.
PHITransAddr - An address value which tracks and handles phi translation.
Value * translateValue(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree *DT, bool MustDominate)
translateValue - PHI translate the current address up the CFG from CurBB to Pred, updating our state ...
bool isPotentiallyPHITranslatable() const
isPotentiallyPHITranslatable - If this needs PHI translation, return true if we have some hope of doi...
bool needsPHITranslationFromBlock(BasicBlock *BB) const
needsPHITranslationFromBlock - Return true if moving from the specified BasicBlock to its predecessor...
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Analysis pass which computes a PostDominatorTree.
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
bool dominates(const Instruction *I1, const Instruction *I2) const
Return true if I1 dominates I2.
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.
void preserveSet()
Mark an analysis set as preserved.
void preserve()
Mark an analysis as preserved.
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
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.
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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.
Value * getValueOperand()
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool has(LibFunc F) const
Tests whether a library function is available.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt8Ty(LLVMContext &C)
bool isVoidTy() const
Return true if this is 'void'.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool match(Val *V, const Pattern &P)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate, true > m_c_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
SpecificCmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_SpecificICmp(ICmpInst::Predicate MatchPred, const LHS &L, const RHS &R)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
AssignmentMarkerRange getAssignmentMarkers(DIAssignID *ID)
Return a range of dbg.assign intrinsics which use \ID as an operand.
SmallVector< DbgVariableRecord * > getDVRAssignmentMarkers(const Instruction *Inst)
bool calculateFragmentIntersect(const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits, uint64_t SliceSizeInBits, const DbgAssignIntrinsic *DbgAssign, std::optional< DIExpression::FragmentInfo > &Result)
Calculate the fragment of the variable in DAI covered from (Dest + SliceOffsetInBits) to to (Dest + S...
initializer< Ty > init(const Ty &Val)
NodeAddr< DefNode * > Def
NodeAddr< FuncNode * > Func
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.
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
bool isStrongerThanMonotonic(AtomicOrdering AO)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
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...
Value * emitCalloc(Value *Num, Value *Size, IRBuilderBase &B, const TargetLibraryInfo &TLI)
Emit a call to the calloc function.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
iterator_range< po_iterator< T > > post_order(const T &G)
bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Compute the size of the object pointed by Ptr.
auto reverse(ContainerTy &&C)
bool isModSet(const ModRefInfo MRI)
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool AreStatisticsEnabled()
Check if statistics are enabled.
bool isNotVisibleOnUnwind(const Value *Object, bool &RequiresNoCaptureBeforeUnwind)
Return true if Object memory is not visible after an unwind, in the sense that program semantics cann...
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
bool salvageKnowledge(Instruction *I, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr)
Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert if before I.
Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
Value * isBytewiseValue(Value *V, const DataLayout &DL)
If the specified value can be set by repeating the same byte in memory, return the i8 value that it i...
auto predecessors(const MachineBasicBlock *BB)
bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
bool isStrongerThan(AtomicOrdering AO, AtomicOrdering Other)
Returns true if ao is stronger than other as defined by the AtomicOrdering lattice,...
bool isRefSet(const ModRefInfo MRI)
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Various options to control the behavior of getObjectSize.
bool NullIsUnknownSize
If this is true, null pointers in address space 0 will be treated as though they can't be evaluated.