LLVM 24.0.0git
DeadStoreElimination.cpp
Go to the documentation of this file.
1//===- DeadStoreElimination.cpp - MemorySSA Backed Dead Store Elimination -===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// The code below implements dead store elimination using MemorySSA. It uses
10// the following general approach: given a MemoryDef, walk upwards to find
11// clobbering MemoryDefs that may be killed by the starting def. Then check
12// that there are no uses that may read the location of the original MemoryDef
13// in between both MemoryDefs. A bit more concretely:
14//
15// For all MemoryDefs StartDef:
16// 1. Get the next dominating clobbering MemoryDef (MaybeDeadAccess) by walking
17// upwards.
18// 2. Check that there are no reads between MaybeDeadAccess and the StartDef by
19// checking all uses starting at MaybeDeadAccess and walking until we see
20// StartDef.
21// 3. For each found CurrentDef, check that:
22// 1. There are no barrier instructions between CurrentDef and StartDef (like
23// throws or stores with ordering constraints).
24// 2. StartDef is executed whenever CurrentDef is executed.
25// 3. StartDef completely overwrites CurrentDef.
26// 4. Erase CurrentDef from the function and MemorySSA.
27//
28//===----------------------------------------------------------------------===//
29
31#include "llvm/ADT/APInt.h"
32#include "llvm/ADT/DenseMap.h"
33#include "llvm/ADT/MapVector.h"
36#include "llvm/ADT/SetVector.h"
39#include "llvm/ADT/Statistic.h"
40#include "llvm/ADT/StringRef.h"
46#include "llvm/Analysis/Loads.h"
55#include "llvm/IR/Argument.h"
57#include "llvm/IR/BasicBlock.h"
58#include "llvm/IR/Constant.h"
60#include "llvm/IR/Constants.h"
61#include "llvm/IR/DataLayout.h"
62#include "llvm/IR/DebugInfo.h"
63#include "llvm/IR/Dominators.h"
64#include "llvm/IR/Function.h"
65#include "llvm/IR/IRBuilder.h"
67#include "llvm/IR/InstrTypes.h"
68#include "llvm/IR/Instruction.h"
71#include "llvm/IR/Module.h"
72#include "llvm/IR/PassManager.h"
74#include "llvm/IR/Value.h"
78#include "llvm/Support/Debug.h"
86#include <algorithm>
87#include <cassert>
88#include <cstdint>
89#include <map>
90#include <optional>
91#include <utility>
92
93using namespace llvm;
94using namespace PatternMatch;
95
96#define DEBUG_TYPE "dse"
97
98STATISTIC(NumRemainingStores, "Number of stores remaining after DSE");
99STATISTIC(NumRedundantStores, "Number of redundant stores deleted");
100STATISTIC(NumFastStores, "Number of stores deleted");
101STATISTIC(NumFastOther, "Number of other instrs removed");
102STATISTIC(NumCompletePartials, "Number of stores dead by later partials");
103STATISTIC(NumModifiedStores, "Number of stores modified");
104STATISTIC(NumCFGChecks, "Number of stores modified");
105STATISTIC(NumCFGTries, "Number of stores modified");
106STATISTIC(NumCFGSuccess, "Number of stores modified");
107STATISTIC(NumGetDomMemoryDefPassed,
108 "Number of times a valid candidate is returned from getDomMemoryDef");
109STATISTIC(NumDomMemDefChecks,
110 "Number iterations check for reads in getDomMemoryDef");
111
112DEBUG_COUNTER(MemorySSACounter, "dse-memoryssa",
113 "Controls which MemoryDefs are eliminated.");
114
115static cl::opt<bool>
116EnablePartialOverwriteTracking("enable-dse-partial-overwrite-tracking",
117 cl::init(true), cl::Hidden,
118 cl::desc("Enable partial-overwrite tracking in DSE"));
119
120static cl::opt<bool>
121EnablePartialStoreMerging("enable-dse-partial-store-merging",
122 cl::init(true), cl::Hidden,
123 cl::desc("Enable partial store merging in DSE"));
124
126 MemorySSAScanLimit("dse-memoryssa-scanlimit", cl::init(150), cl::Hidden,
127 cl::desc("The number of memory instructions to scan for "
128 "dead store elimination (default = 150)"));
130 "dse-memoryssa-walklimit", cl::init(90), cl::Hidden,
131 cl::desc("The maximum number of steps while walking upwards to find "
132 "MemoryDefs that may be killed (default = 90)"));
133
135 "dse-memoryssa-partial-store-limit", cl::init(5), cl::Hidden,
136 cl::desc("The maximum number candidates that only partially overwrite the "
137 "killing MemoryDef to consider"
138 " (default = 5)"));
139
141 "dse-memoryssa-defs-per-block-limit", cl::init(5000), cl::Hidden,
142 cl::desc("The number of MemoryDefs we consider as candidates to eliminated "
143 "other stores per basic block (default = 5000)"));
144
146 "dse-memoryssa-samebb-cost", cl::init(1), cl::Hidden,
147 cl::desc(
148 "The cost of a step in the same basic block as the killing MemoryDef"
149 "(default = 1)"));
150
152 MemorySSAOtherBBStepCost("dse-memoryssa-otherbb-cost", cl::init(5),
154 cl::desc("The cost of a step in a different basic "
155 "block than the killing MemoryDef"
156 "(default = 5)"));
157
159 "dse-memoryssa-path-check-limit", cl::init(50), cl::Hidden,
160 cl::desc("The maximum number of blocks to check when trying to prove that "
161 "all paths to an exit go through a killing block (default = 50)"));
162
163// This flags allows or disallows DSE to optimize MemorySSA during its
164// traversal. Note that DSE optimizing MemorySSA may impact other passes
165// downstream of the DSE invocation and can lead to issues not being
166// reproducible in isolation (i.e. when MemorySSA is built from scratch). In
167// those cases, the flag can be used to check if DSE's MemorySSA optimizations
168// impact follow-up passes.
169static cl::opt<bool>
170 OptimizeMemorySSA("dse-optimize-memoryssa", cl::init(true), cl::Hidden,
171 cl::desc("Allow DSE to optimize memory accesses."));
172
173// TODO: remove this flag.
175 "enable-dse-initializes-attr-improvement", cl::init(true), cl::Hidden,
176 cl::desc("Enable the initializes attr improvement in DSE"));
177
179 "dse-max-dom-cond-depth", cl::init(1024), cl::Hidden,
180 cl::desc("Max dominator tree recursion depth for eliminating redundant "
181 "stores via dominating conditions"));
182
183//===----------------------------------------------------------------------===//
184// Helper functions
185//===----------------------------------------------------------------------===//
186using OverlapIntervalsTy = std::map<int64_t, int64_t>;
188
189/// Returns true if the end of this instruction can be safely shortened in
190/// length.
192 // Don't shorten stores for now
193 if (isa<StoreInst>(I))
194 return false;
195
197 switch (II->getIntrinsicID()) {
198 default: return false;
199 case Intrinsic::memset:
200 case Intrinsic::memcpy:
201 case Intrinsic::memcpy_element_unordered_atomic:
202 case Intrinsic::memset_element_unordered_atomic:
203 // Do shorten memory intrinsics.
204 // FIXME: Add memmove if it's also safe to transform.
205 return true;
206 }
207 }
208
209 // Don't shorten libcalls calls for now.
210
211 return false;
212}
213
214/// Returns true if the beginning of this instruction can be safely shortened
215/// in length.
217 // FIXME: Handle only memset for now. Supporting memcpy/memmove should be
218 // easily done by offsetting the source address.
219 return isa<AnyMemSetInst>(I);
220}
221
222static std::optional<TypeSize> getPointerSize(const Value *V,
223 const DataLayout &DL,
224 const TargetLibraryInfo &TLI,
225 const Function *F) {
227 ObjectSizeOpts Opts;
229
230 if (getObjectSize(V, Size, DL, &TLI, Opts))
231 return TypeSize::getFixed(Size);
232 return std::nullopt;
233}
234
235namespace {
236
237enum OverwriteResult {
238 OW_Begin,
239 OW_Complete,
240 OW_End,
241 OW_PartialEarlierWithFullLater,
242 OW_MaybePartial,
243 OW_None,
244 OW_Unknown
245};
246
247} // end anonymous namespace
248
249/// Check if two instruction are masked stores that completely
250/// overwrite one another. More specifically, \p KillingI has to
251/// overwrite \p DeadI.
252static OverwriteResult isMaskedStoreOverwrite(const Instruction *KillingI,
253 const Instruction *DeadI,
255 const auto *KillingII = dyn_cast<IntrinsicInst>(KillingI);
256 const auto *DeadII = dyn_cast<IntrinsicInst>(DeadI);
257 if (KillingII == nullptr || DeadII == nullptr)
258 return OW_Unknown;
259 if (KillingII->getIntrinsicID() != DeadII->getIntrinsicID())
260 return OW_Unknown;
261
262 switch (KillingII->getIntrinsicID()) {
263 case Intrinsic::masked_store:
264 case Intrinsic::vp_store: {
265 const DataLayout &DL = KillingII->getDataLayout();
266 auto *KillingTy = KillingII->getArgOperand(0)->getType();
267 auto *DeadTy = DeadII->getArgOperand(0)->getType();
268 if (DL.getTypeSizeInBits(KillingTy) != DL.getTypeSizeInBits(DeadTy))
269 return OW_Unknown;
270 // Element count.
271 if (cast<VectorType>(KillingTy)->getElementCount() !=
272 cast<VectorType>(DeadTy)->getElementCount())
273 return OW_Unknown;
274 // Pointers.
275 Value *KillingPtr = KillingII->getArgOperand(1);
276 Value *DeadPtr = DeadII->getArgOperand(1);
277 if (KillingPtr != DeadPtr && !AA.isMustAlias(KillingPtr, DeadPtr))
278 return OW_Unknown;
279 if (KillingII->getIntrinsicID() == Intrinsic::masked_store) {
280 // Masks.
281 // TODO: check that KillingII's mask is a superset of the DeadII's mask.
282 if (KillingII->getArgOperand(2) != DeadII->getArgOperand(2))
283 return OW_Unknown;
284 } else if (KillingII->getIntrinsicID() == Intrinsic::vp_store) {
285 // Masks.
286 // TODO: check that KillingII's mask is a superset of the DeadII's mask.
287 if (KillingII->getArgOperand(2) != DeadII->getArgOperand(2))
288 return OW_Unknown;
289 // Lengths.
290 if (KillingII->getArgOperand(3) != DeadII->getArgOperand(3))
291 return OW_Unknown;
292 }
293 return OW_Complete;
294 }
295 default:
296 return OW_Unknown;
297 }
298}
299
300/// Return 'OW_Complete' if a store to the 'KillingLoc' location completely
301/// overwrites a store to the 'DeadLoc' location, 'OW_End' if the end of the
302/// 'DeadLoc' location is completely overwritten by 'KillingLoc', 'OW_Begin'
303/// if the beginning of the 'DeadLoc' location is overwritten by 'KillingLoc'.
304/// 'OW_PartialEarlierWithFullLater' means that a dead (big) store was
305/// overwritten by a killing (smaller) store which doesn't write outside the big
306/// store's memory locations. Returns 'OW_Unknown' if nothing can be determined.
307/// NOTE: This function must only be called if both \p KillingLoc and \p
308/// DeadLoc belong to the same underlying object with valid \p KillingOff and
309/// \p DeadOff.
310static OverwriteResult isPartialOverwrite(const MemoryLocation &KillingLoc,
311 const MemoryLocation &DeadLoc,
312 int64_t KillingOff, int64_t DeadOff,
313 Instruction *DeadI,
315 const uint64_t KillingSize = KillingLoc.Size.getValue();
316 const uint64_t DeadSize = DeadLoc.Size.getValue();
317 // We may now overlap, although the overlap is not complete. There might also
318 // be other incomplete overlaps, and together, they might cover the complete
319 // dead store.
320 // Note: The correctness of this logic depends on the fact that this function
321 // is not even called providing DepWrite when there are any intervening reads.
323 KillingOff < int64_t(DeadOff + DeadSize) &&
324 int64_t(KillingOff + KillingSize) >= DeadOff) {
325
326 // Insert our part of the overlap into the map.
327 auto &IM = IOL[DeadI];
328 LLVM_DEBUG(dbgs() << "DSE: Partial overwrite: DeadLoc [" << DeadOff << ", "
329 << int64_t(DeadOff + DeadSize) << ") KillingLoc ["
330 << KillingOff << ", " << int64_t(KillingOff + KillingSize)
331 << ")\n");
332
333 // Make sure that we only insert non-overlapping intervals and combine
334 // adjacent intervals. The intervals are stored in the map with the ending
335 // offset as the key (in the half-open sense) and the starting offset as
336 // the value.
337 int64_t KillingIntStart = KillingOff;
338 int64_t KillingIntEnd = KillingOff + KillingSize;
339
340 // Find any intervals ending at, or after, KillingIntStart which start
341 // before KillingIntEnd.
342 auto ILI = IM.lower_bound(KillingIntStart);
343 if (ILI != IM.end() && ILI->second <= KillingIntEnd) {
344 // This existing interval is overlapped with the current store somewhere
345 // in [KillingIntStart, KillingIntEnd]. Merge them by erasing the existing
346 // intervals and adjusting our start and end.
347 KillingIntStart = std::min(KillingIntStart, ILI->second);
348 KillingIntEnd = std::max(KillingIntEnd, ILI->first);
349 ILI = IM.erase(ILI);
350
351 // Continue erasing and adjusting our end in case other previous
352 // intervals are also overlapped with the current store.
353 //
354 // |--- dead 1 ---| |--- dead 2 ---|
355 // |------- killing---------|
356 //
357 while (ILI != IM.end() && ILI->second <= KillingIntEnd) {
358 assert(ILI->second > KillingIntStart && "Unexpected interval");
359 KillingIntEnd = std::max(KillingIntEnd, ILI->first);
360 ILI = IM.erase(ILI);
361 }
362 }
363
364 IM[KillingIntEnd] = KillingIntStart;
365
366 ILI = IM.begin();
367 if (ILI->second <= DeadOff && ILI->first >= int64_t(DeadOff + DeadSize)) {
368 LLVM_DEBUG(dbgs() << "DSE: Full overwrite from partials: DeadLoc ["
369 << DeadOff << ", " << int64_t(DeadOff + DeadSize)
370 << ") Composite KillingLoc [" << ILI->second << ", "
371 << ILI->first << ")\n");
372 ++NumCompletePartials;
373 return OW_Complete;
374 }
375 }
376
377 // Check for a dead store which writes to all the memory locations that
378 // the killing store writes to.
379 if (EnablePartialStoreMerging && KillingOff >= DeadOff &&
380 int64_t(DeadOff + DeadSize) > KillingOff &&
381 uint64_t(KillingOff - DeadOff) + KillingSize <= DeadSize) {
382 LLVM_DEBUG(dbgs() << "DSE: Partial overwrite a dead load [" << DeadOff
383 << ", " << int64_t(DeadOff + DeadSize)
384 << ") by a killing store [" << KillingOff << ", "
385 << int64_t(KillingOff + KillingSize) << ")\n");
386 // TODO: Maybe come up with a better name?
387 return OW_PartialEarlierWithFullLater;
388 }
389
390 // Another interesting case is if the killing store overwrites the end of the
391 // dead store.
392 //
393 // |--dead--|
394 // |-- killing --|
395 //
396 // In this case we may want to trim the size of dead store to avoid
397 // generating stores to addresses which will definitely be overwritten killing
398 // store.
400 (KillingOff > DeadOff && KillingOff < int64_t(DeadOff + DeadSize) &&
401 int64_t(KillingOff + KillingSize) >= int64_t(DeadOff + DeadSize)))
402 return OW_End;
403
404 // Finally, we also need to check if the killing store overwrites the
405 // beginning of the dead store.
406 //
407 // |--dead--|
408 // |-- killing --|
409 //
410 // In this case we may want to move the destination address and trim the size
411 // of dead store to avoid generating stores to addresses which will definitely
412 // be overwritten killing store.
414 (KillingOff <= DeadOff && int64_t(KillingOff + KillingSize) > DeadOff)) {
415 assert(int64_t(KillingOff + KillingSize) < int64_t(DeadOff + DeadSize) &&
416 "Expect to be handled as OW_Complete");
417 return OW_Begin;
418 }
419 // Otherwise, they don't completely overlap.
420 return OW_Unknown;
421}
422
423/// Returns true if the memory which is accessed by the second instruction is not
424/// modified between the first and the second instruction.
425/// Precondition: Second instruction must be dominated by the first
426/// instruction.
427static bool
430 DominatorTree *DT) {
431 // Do a backwards scan through the CFG from SecondI to FirstI. Look for
432 // instructions which can modify the memory location accessed by SecondI.
433 //
434 // While doing the walk keep track of the address to check. It might be
435 // different in different basic blocks due to PHI translation.
436 using BlockAddressPair = std::pair<BasicBlock *, PHITransAddr>;
438 // Keep track of the address we visited each block with. Bail out if we
439 // visit a block with different addresses.
441
442 BasicBlock::iterator FirstBBI(FirstI);
443 ++FirstBBI;
444 BasicBlock::iterator SecondBBI(SecondI);
445 BasicBlock *FirstBB = FirstI->getParent();
446 BasicBlock *SecondBB = SecondI->getParent();
447 MemoryLocation MemLoc;
448 if (auto *MemSet = dyn_cast<MemSetInst>(SecondI))
449 MemLoc = MemoryLocation::getForDest(MemSet);
450 else
451 MemLoc = MemoryLocation::get(SecondI);
452
453 auto *MemLocPtr = const_cast<Value *>(MemLoc.Ptr);
454
455 // Start checking the SecondBB.
456 WorkList.push_back(
457 std::make_pair(SecondBB, PHITransAddr(MemLocPtr, DL, nullptr)));
458 bool isFirstBlock = true;
459
460 // Check all blocks going backward until we reach the FirstBB.
461 while (!WorkList.empty()) {
462 BlockAddressPair Current = WorkList.pop_back_val();
463 BasicBlock *B = Current.first;
464 PHITransAddr &Addr = Current.second;
465 Value *Ptr = Addr.getAddr();
466
467 // Ignore instructions before FirstI if this is the FirstBB.
468 BasicBlock::iterator BI = (B == FirstBB ? FirstBBI : B->begin());
469
471 if (isFirstBlock) {
472 // Ignore instructions after SecondI if this is the first visit of SecondBB.
473 assert(B == SecondBB && "first block is not the store block");
474 EI = SecondBBI;
475 isFirstBlock = false;
476 } else {
477 // It's not SecondBB or (in case of a loop) the second visit of SecondBB.
478 // In this case we also have to look at instructions after SecondI.
479 EI = B->end();
480 }
481 for (; BI != EI; ++BI) {
482 Instruction *I = &*BI;
483 if (I->mayWriteToMemory() && I != SecondI)
484 if (isModSet(AA.getModRefInfo(I, MemLoc.getWithNewPtr(Ptr))))
485 return false;
486 }
487 if (B != FirstBB) {
488 assert(B != &FirstBB->getParent()->getEntryBlock() &&
489 "Should not hit the entry block because SI must be dominated by LI");
490 for (BasicBlock *Pred : predecessors(B)) {
491 PHITransAddr PredAddr = Addr;
492 if (PredAddr.needsPHITranslationFromBlock(B)) {
493 if (!PredAddr.isPotentiallyPHITranslatable())
494 return false;
495 if (!PredAddr.translateValue(B, Pred, DT, false))
496 return false;
497 }
498 Value *TranslatedPtr = PredAddr.getAddr();
499 auto Inserted = Visited.insert(std::make_pair(Pred, TranslatedPtr));
500 if (!Inserted.second) {
501 // We already visited this block before. If it was with a different
502 // address - bail out!
503 if (TranslatedPtr != Inserted.first->second)
504 return false;
505 // ... otherwise just skip it.
506 continue;
507 }
508 WorkList.push_back(std::make_pair(Pred, PredAddr));
509 }
510 }
511 }
512 return true;
513}
514
515static void shortenAssignment(Instruction *Inst, Value *OriginalDest,
516 uint64_t OldSizeInBits, uint64_t NewSizeInBits,
517 bool IsOverwriteEnd) {
518 const DataLayout &DL = Inst->getDataLayout();
519 uint64_t DeadSliceSizeInBits = OldSizeInBits - NewSizeInBits;
520 // The dead slice offset is relative to OriginalDest, the slice start we hand
521 // calculateFragmentIntersect. Shortening the end keeps the front of the
522 // store, so the dead bits start where the new store ends; shortening the
523 // beginning kills the bits at OriginalDest itself. Don't add OriginalDest's
524 // offset from its base object here. calculateFragmentIntersect already
525 // measures that pointer against the marker's address.
526 uint64_t DeadSliceOffsetInBits = IsOverwriteEnd ? NewSizeInBits : 0;
527 auto SetDeadFragExpr = [](auto *Assign,
528 DIExpression::FragmentInfo DeadFragment) {
529 // createFragmentExpression expects an offset relative to the existing
530 // fragment offset if there is one.
531 uint64_t RelativeOffset = DeadFragment.OffsetInBits -
532 Assign->getExpression()
533 ->getFragmentInfo()
534 .value_or(DIExpression::FragmentInfo(0, 0))
535 .OffsetInBits;
537 Assign->getExpression(), RelativeOffset, DeadFragment.SizeInBits)) {
538 Assign->setExpression(*NewExpr);
539 return;
540 }
541 // Failed to create a fragment expression for this so discard the value,
542 // making this a kill location.
544 DIExpression::get(Assign->getContext(), {}), DeadFragment.OffsetInBits,
545 DeadFragment.SizeInBits);
546 Assign->setExpression(Expr);
547 Assign->setKillLocation();
548 };
549
550 // A DIAssignID to use so that the inserted dbg.assign intrinsics do not
551 // link to any instructions. Created in the loop below (once).
552 DIAssignID *LinkToNothing = nullptr;
553 LLVMContext &Ctx = Inst->getContext();
554 auto GetDeadLink = [&Ctx, &LinkToNothing]() {
555 if (!LinkToNothing)
556 LinkToNothing = DIAssignID::getDistinct(Ctx);
557 return LinkToNothing;
558 };
559
560 // Insert an unlinked dbg.assign intrinsic for the dead fragment after each
561 // overlapping dbg.assign intrinsic.
562 for (DbgVariableRecord *Assign : at::getDVRAssignmentMarkers(Inst)) {
563 std::optional<DIExpression::FragmentInfo> NewFragment;
564 if (!at::calculateFragmentIntersect(DL, OriginalDest, DeadSliceOffsetInBits,
565 DeadSliceSizeInBits, Assign,
566 NewFragment) ||
567 !NewFragment) {
568 // Either the intersection couldn't be worked out, or it covers the
569 // entire variable region described by the record. Full coverage leaves
570 // NewFragment empty rather than making calculateFragmentIntersect fail,
571 // so unlink the whole assignment from the store in both cases.
572 Assign->setKillAddress();
573 Assign->setAssignId(GetDeadLink());
574 continue;
575 }
576 // No intersect.
577 if (NewFragment->SizeInBits == 0)
578 continue;
579
580 // Fragments overlap: insert a new dbg.assign for this dead part.
581 auto *NewAssign = static_cast<decltype(Assign)>(Assign->clone());
582 NewAssign->insertAfter(Assign->getIterator());
583 NewAssign->setAssignId(GetDeadLink());
584 if (NewFragment)
585 SetDeadFragExpr(NewAssign, *NewFragment);
586 NewAssign->setKillAddress();
587 }
588}
589
590/// Update the attributes given that a memory access is updated (the
591/// dereferenced pointer could be moved forward when shortening a
592/// mem intrinsic).
593static void adjustArgAttributes(AnyMemIntrinsic *Intrinsic, unsigned ArgNo,
594 uint64_t PtrOffset) {
595 // Remember old attributes.
596 AttributeSet OldAttrs = Intrinsic->getParamAttributes(ArgNo);
597
598 // Find attributes that should be kept, and remove the rest.
599 AttributeMask AttrsToRemove;
600 for (auto &Attr : OldAttrs) {
601 if (Attr.hasKindAsEnum()) {
602 switch (Attr.getKindAsEnum()) {
603 default:
604 break;
605 case Attribute::Alignment:
606 // Only keep alignment if PtrOffset satisfy the alignment.
607 if (isAligned(Attr.getAlignment().valueOrOne(), PtrOffset))
608 continue;
609 break;
610 case Attribute::Dereferenceable:
611 case Attribute::DereferenceableOrNull:
612 // We could reduce the size of these attributes according to
613 // PtrOffset. But we simply drop these for now.
614 break;
615 case Attribute::NonNull:
616 case Attribute::NoUndef:
617 continue;
618 }
619 }
620 AttrsToRemove.addAttribute(Attr);
621 }
622
623 // Remove the attributes that should be dropped.
624 Intrinsic->removeParamAttrs(ArgNo, AttrsToRemove);
625}
626
627static bool tryToShorten(Instruction *DeadI, int64_t &DeadStart,
628 uint64_t &DeadSize, int64_t KillingStart,
629 uint64_t KillingSize, bool IsOverwriteEnd) {
630 auto *DeadIntrinsic = cast<AnyMemIntrinsic>(DeadI);
631 Align PrefAlign = DeadIntrinsic->getDestAlign().valueOrOne();
632
633 // We assume that memet/memcpy operates in chunks of the "largest" native
634 // type size and aligned on the same value. That means optimal start and size
635 // of memset/memcpy should be modulo of preferred alignment of that type. That
636 // is it there is no any sense in trying to reduce store size any further
637 // since any "extra" stores comes for free anyway.
638 // On the other hand, maximum alignment we can achieve is limited by alignment
639 // of initial store.
640
641 // TODO: Limit maximum alignment by preferred (or abi?) alignment of the
642 // "largest" native type.
643 // Note: What is the proper way to get that value?
644 // Should TargetTransformInfo::getRegisterBitWidth be used or anything else?
645 // PrefAlign = std::min(DL.getPrefTypeAlign(LargestType), PrefAlign);
646
647 int64_t ToRemoveStart = 0;
648 uint64_t ToRemoveSize = 0;
649 // Compute start and size of the region to remove. Make sure 'PrefAlign' is
650 // maintained on the remaining store.
651 if (IsOverwriteEnd) {
652 // Calculate required adjustment for 'KillingStart' in order to keep
653 // remaining store size aligned on 'PerfAlign'.
654 uint64_t Off =
655 offsetToAlignment(uint64_t(KillingStart - DeadStart), PrefAlign);
656 ToRemoveStart = KillingStart + Off;
657 if (DeadSize <= uint64_t(ToRemoveStart - DeadStart))
658 return false;
659 ToRemoveSize = DeadSize - uint64_t(ToRemoveStart - DeadStart);
660 } else {
661 ToRemoveStart = DeadStart;
662 assert(KillingSize >= uint64_t(DeadStart - KillingStart) &&
663 "Not overlapping accesses?");
664 ToRemoveSize = KillingSize - uint64_t(DeadStart - KillingStart);
665 // Calculate required adjustment for 'ToRemoveSize'in order to keep
666 // start of the remaining store aligned on 'PerfAlign'.
667 uint64_t Off = offsetToAlignment(ToRemoveSize, PrefAlign);
668 if (Off != 0) {
669 if (ToRemoveSize <= (PrefAlign.value() - Off))
670 return false;
671 ToRemoveSize -= PrefAlign.value() - Off;
672 }
673 assert(isAligned(PrefAlign, ToRemoveSize) &&
674 "Should preserve selected alignment");
675 }
676
677 assert(ToRemoveSize > 0 && "Shouldn't reach here if nothing to remove");
678 assert(DeadSize > ToRemoveSize && "Can't remove more than original size");
679
680 uint64_t NewSize = DeadSize - ToRemoveSize;
681 if (DeadIntrinsic->isAtomic()) {
682 // When shortening an atomic memory intrinsic, the newly shortened
683 // length must remain an integer multiple of the element size.
684 const uint32_t ElementSize = DeadIntrinsic->getElementSizeInBytes();
685 if (0 != NewSize % ElementSize)
686 return false;
687 }
688
689 LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n OW "
690 << (IsOverwriteEnd ? "END" : "BEGIN") << ": " << *DeadI
691 << "\n KILLER [" << ToRemoveStart << ", "
692 << int64_t(ToRemoveStart + ToRemoveSize) << ")\n");
693
694 DeadIntrinsic->setLength(NewSize);
695 DeadIntrinsic->setDestAlignment(PrefAlign);
696
697 Value *OrigDest = DeadIntrinsic->getRawDest();
698 if (!IsOverwriteEnd) {
699 Value *Indices[1] = {
700 ConstantInt::get(DeadIntrinsic->getLength()->getType(), ToRemoveSize)};
702 Type::getInt8Ty(DeadIntrinsic->getContext()), OrigDest, Indices, "",
703 DeadI->getIterator());
704 NewDestGEP->setDebugLoc(DeadIntrinsic->getDebugLoc());
705 DeadIntrinsic->setDest(NewDestGEP);
706 adjustArgAttributes(DeadIntrinsic, 0, ToRemoveSize);
707 }
708
709 // Update attached dbg.assign intrinsics. Assume 8-bit byte.
710 shortenAssignment(DeadI, OrigDest, DeadSize * 8, NewSize * 8, IsOverwriteEnd);
711
712 // Finally update start and size of dead access.
713 if (!IsOverwriteEnd)
714 DeadStart += ToRemoveSize;
715 DeadSize = NewSize;
716
717 return true;
718}
719
721 int64_t &DeadStart, uint64_t &DeadSize) {
722 if (IntervalMap.empty() || !isShortenableAtTheEnd(DeadI))
723 return false;
724
725 OverlapIntervalsTy::iterator OII = --IntervalMap.end();
726 int64_t KillingStart = OII->second;
727 uint64_t KillingSize = OII->first - KillingStart;
728
729 assert(OII->first - KillingStart >= 0 && "Size expected to be positive");
730
731 if (KillingStart > DeadStart &&
732 // Note: "KillingStart - KillingStart" is known to be positive due to
733 // preceding check.
734 (uint64_t)(KillingStart - DeadStart) < DeadSize &&
735 // Note: "DeadSize - (uint64_t)(KillingStart - DeadStart)" is known to
736 // be non negative due to preceding checks.
737 KillingSize >= DeadSize - (uint64_t)(KillingStart - DeadStart)) {
738 if (tryToShorten(DeadI, DeadStart, DeadSize, KillingStart, KillingSize,
739 true)) {
740 IntervalMap.erase(OII);
741 return true;
742 }
743 }
744 return false;
745}
746
749 int64_t &DeadStart, uint64_t &DeadSize) {
751 return false;
752
753 OverlapIntervalsTy::iterator OII = IntervalMap.begin();
754 int64_t KillingStart = OII->second;
755 uint64_t KillingSize = OII->first - KillingStart;
756
757 assert(OII->first - KillingStart >= 0 && "Size expected to be positive");
758
759 if (KillingStart <= DeadStart &&
760 // Note: "DeadStart - KillingStart" is known to be non negative due to
761 // preceding check.
762 KillingSize > (uint64_t)(DeadStart - KillingStart)) {
763 // Note: "KillingSize - (uint64_t)(DeadStart - DeadStart)" is known to
764 // be positive due to preceding checks.
765 assert(KillingSize - (uint64_t)(DeadStart - KillingStart) < DeadSize &&
766 "Should have been handled as OW_Complete");
767 if (tryToShorten(DeadI, DeadStart, DeadSize, KillingStart, KillingSize,
768 false)) {
769 IntervalMap.erase(OII);
770 return true;
771 }
772 }
773 return false;
774}
775
776static Constant *
778 int64_t KillingOffset, int64_t DeadOffset,
780 DominatorTree *DT) {
781 assert(KillingI);
782 assert(DeadI);
783
784 // If the store we find is:
785 // a) partially overwritten by the store to 'Loc'
786 // b) the killing store is fully contained in the dead one and
787 // c) they both have a constant value
788 // d) none of the two stores need padding
789 // Merge the two stores, replacing the dead store's value with a
790 // merge of both values.
791 //
792 // TODO: Deal with other constant types (vectors, etc), and probably
793 // some mem intrinsics (if needed)
794 if (!isa<ConstantInt>(DeadI->getValueOperand()) ||
795 !DL.typeSizeEqualsStoreSize(DeadI->getValueOperand()->getType()) ||
796 !isa<ConstantInt>(KillingI->getValueOperand()) ||
797 !DL.typeSizeEqualsStoreSize(KillingI->getValueOperand()->getType()) ||
798 !memoryIsNotModifiedBetween(DeadI, KillingI, AA, DL, DT))
799 return nullptr;
800
801 // The merge erases KillingI and writes its bytes via DeadI. For that to be
802 // safe:
803 // - KillingI must be deletable (not volatile, ordering at most unordered),
804 // - DeadI must be safe to rewrite, and
805 // - their orderings must match, so the bytes originally written by
806 // KillingI keep the same atomicity after they are folded into DeadI.
807 // This allows merging two simple stores or two unordered-atomic stores with
808 // matching ordering, while leaving volatile and ordered-atomic stores in
809 // place.
810 if (!KillingI->isUnordered() || !DeadI->isUnordered() ||
811 KillingI->getOrdering() != DeadI->getOrdering())
812 return nullptr;
813
814 APInt DeadValue = cast<ConstantInt>(DeadI->getValueOperand())->getValue();
815 APInt KillingValue =
816 cast<ConstantInt>(KillingI->getValueOperand())->getValue();
817 unsigned KillingBits = KillingValue.getBitWidth();
818 assert(DeadValue.getBitWidth() > KillingValue.getBitWidth());
819 KillingValue = KillingValue.zext(DeadValue.getBitWidth());
820
821 // Offset of the smaller store inside the larger store
822 unsigned BitOffsetDiff = (KillingOffset - DeadOffset) * 8;
823 unsigned LShiftAmount =
824 DL.isBigEndian() ? DeadValue.getBitWidth() - BitOffsetDiff - KillingBits
825 : BitOffsetDiff;
826 APInt Mask = APInt::getBitsSet(DeadValue.getBitWidth(), LShiftAmount,
827 LShiftAmount + KillingBits);
828 // Clear the bits we'll be replacing, then OR with the smaller
829 // store, shifted appropriately.
830 APInt Merged = (DeadValue & ~Mask) | (KillingValue << LShiftAmount);
831 LLVM_DEBUG(dbgs() << "DSE: Merge Stores:\n Dead: " << *DeadI
832 << "\n Killing: " << *KillingI
833 << "\n Merged Value: " << Merged << '\n');
834 return ConstantInt::get(DeadI->getValueOperand()->getType(), Merged);
835}
836
837// Returns true if \p I is an intrinsic that does not read or write memory.
840 switch (II->getIntrinsicID()) {
841 case Intrinsic::lifetime_start:
842 case Intrinsic::lifetime_end:
843 case Intrinsic::invariant_end:
844 case Intrinsic::launder_invariant_group:
845 case Intrinsic::assume:
846 return true;
847 case Intrinsic::dbg_declare:
848 case Intrinsic::dbg_label:
849 case Intrinsic::dbg_value:
850 llvm_unreachable("Intrinsic should not be modeled in MemorySSA");
851 default:
852 return false;
853 }
854 }
855 return false;
856}
857
858// Check if we can ignore \p D for DSE.
859static bool canSkipDef(MemoryDef *D, bool DefVisibleToCaller) {
860 Instruction *DI = D->getMemoryInst();
861 // Calls that only access inaccessible memory cannot read or write any memory
862 // locations we consider for elimination.
863 if (auto *CB = dyn_cast<CallBase>(DI))
864 if (CB->onlyAccessesInaccessibleMemory())
865 return true;
866
867 // We can eliminate stores to locations not visible to the caller across
868 // throwing instructions.
869 if (DI->mayThrow() && !DefVisibleToCaller)
870 return true;
871
872 // We can remove the dead stores, irrespective of the fence and its ordering
873 // (release/acquire/seq_cst). Fences only constraints the ordering of
874 // already visible stores, it does not make a store visible to other
875 // threads. So, skipping over a fence does not change a store from being
876 // dead.
877 if (isa<FenceInst>(DI))
878 return true;
879
880 // Skip intrinsics that do not really read or modify memory.
881 if (isNoopIntrinsic(DI))
882 return true;
883
884 return false;
885}
886
887namespace {
888
889// A memory location wrapper that represents a MemoryLocation, `MemLoc`,
890// defined by `MemDef`.
891struct MemoryLocationWrapper {
892 MemoryLocationWrapper(MemoryLocation MemLoc, MemoryDef *MemDef,
893 bool DefByInitializesAttr)
894 : MemLoc(MemLoc), MemDef(MemDef),
895 DefByInitializesAttr(DefByInitializesAttr) {
896 assert(MemLoc.Ptr && "MemLoc should be not null");
897 UnderlyingObject = getUnderlyingObject(MemLoc.Ptr);
898 DefInst = MemDef->getMemoryInst();
899 }
900
901 MemoryLocation MemLoc;
902 const Value *UnderlyingObject;
903 MemoryDef *MemDef;
904 Instruction *DefInst;
905 bool DefByInitializesAttr = false;
906};
907
908// A memory def wrapper that represents a MemoryDef and the MemoryLocation(s)
909// defined by this MemoryDef.
910struct MemoryDefWrapper {
911 MemoryDefWrapper(MemoryDef *MemDef,
912 ArrayRef<std::pair<MemoryLocation, bool>> MemLocations) {
913 DefInst = MemDef->getMemoryInst();
914 for (auto &[MemLoc, DefByInitializesAttr] : MemLocations)
915 DefinedLocations.push_back(
916 MemoryLocationWrapper(MemLoc, MemDef, DefByInitializesAttr));
917 }
918 Instruction *DefInst;
920};
921
922struct ArgumentInitInfo {
923 unsigned Idx;
924 bool IsDeadOrInvisibleOnUnwind;
925 ConstantRangeList Inits;
926};
927} // namespace
928
931 return CB && CB->getArgOperandWithAttribute(Attribute::Initializes);
932}
933
934// Return the intersected range list of the initializes attributes of "Args".
935// "Args" are call arguments that alias to each other.
936// If any argument in "Args" doesn't have dead_on_unwind attr and
937// "CallHasNoUnwindAttr" is false, return empty.
940 bool CallHasNoUnwindAttr) {
941 if (Args.empty())
942 return {};
943
944 // To address unwind, the function should have nounwind attribute or the
945 // arguments have dead or invisible on unwind. Otherwise, return empty.
946 for (const auto &Arg : Args) {
947 if (!CallHasNoUnwindAttr && !Arg.IsDeadOrInvisibleOnUnwind)
948 return {};
949 if (Arg.Inits.empty())
950 return {};
951 }
952
953 ConstantRangeList IntersectedIntervals = Args.front().Inits;
954 for (auto &Arg : Args.drop_front())
955 IntersectedIntervals = IntersectedIntervals.intersectWith(Arg.Inits);
956
957 return IntersectedIntervals;
958}
959
960namespace {
961
962struct DSEState {
963 Function &F;
964 AliasAnalysis &AA;
965 EarliestEscapeAnalysis EA;
966
967 /// The single BatchAA instance that is used to cache AA queries. It will
968 /// not be invalidated over the whole run. This is safe, because:
969 /// 1. Only memory writes are removed, so the alias cache for memory
970 /// locations remains valid.
971 /// 2. No new instructions are added (only instructions removed), so cached
972 /// information for a deleted value cannot be accessed by a re-used new
973 /// value pointer.
974 BatchAAResults BatchAA;
975
976 MemorySSA &MSSA;
977 DominatorTree &DT;
978 PostDominatorTree &PDT;
979 const TargetLibraryInfo &TLI;
980 const DataLayout &DL;
981 const CycleInfo &CI;
982
983 // All MemoryDefs that potentially could kill other MemDefs.
985 // Any that should be skipped as they are already deleted
986 SmallPtrSet<MemoryAccess *, 4> SkipStores;
987 // Keep track whether a given object is captured before return or not.
988 DenseMap<const Value *, bool> CapturedBeforeReturn;
989 // Keep track of all of the objects that are invisible to the caller after
990 // the function returns.
991 DenseMap<const Value *, bool> InvisibleToCallerAfterRet;
992 DenseMap<const Value *, uint64_t> InvisibleToCallerAfterRetBounded;
993 // Keep track of blocks with throwing instructions not modeled in MemorySSA.
994 SmallPtrSet<BasicBlock *, 16> ThrowingBlocks;
995 // Post-order numbers for each basic block. Used to figure out if memory
996 // accesses are executed before another access.
997 DenseMap<BasicBlock *, unsigned> PostOrderNumbers;
998
999 /// Keep track of instructions (partly) overlapping with killing MemoryDefs per
1000 /// basic block.
1001 MapVector<BasicBlock *, InstOverlapIntervalsTy> IOLs;
1002 // Check if there are root nodes that are terminated by UnreachableInst.
1003 // Those roots pessimize post-dominance queries. If there are such roots,
1004 // fall back to CFG scan starting from all non-unreachable roots.
1005 bool AnyUnreachableExit;
1006
1007 // Whether or not we should iterate on removing dead stores at the end of the
1008 // function due to removing a store causing a previously captured pointer to
1009 // no longer be captured.
1010 bool ShouldIterateEndOfFunctionDSE;
1011
1012 /// Dead instructions to be removed at the end of DSE.
1013 SmallVector<Instruction *> ToRemove;
1014
1015 // Class contains self-reference, make sure it's not copied/moved.
1016 DSEState(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, DominatorTree &DT,
1017 PostDominatorTree &PDT, const TargetLibraryInfo &TLI,
1018 const CycleInfo &CI);
1019 DSEState(const DSEState &) = delete;
1020 DSEState &operator=(const DSEState &) = delete;
1021
1022 LocationSize strengthenLocationSize(const Instruction *I,
1023 LocationSize Size) const;
1024
1025 /// Return 'OW_Complete' if a store to the 'KillingLoc' location (by \p
1026 /// KillingI instruction) completely overwrites a store to the 'DeadLoc'
1027 /// location (by \p DeadI instruction).
1028 /// Return OW_MaybePartial if \p KillingI does not completely overwrite
1029 /// \p DeadI, but they both write to the same underlying object. In that
1030 /// case, use isPartialOverwrite to check if \p KillingI partially overwrites
1031 /// \p DeadI. Returns 'OR_None' if \p KillingI is known to not overwrite the
1032 /// \p DeadI. Returns 'OW_Unknown' if nothing can be determined.
1033 OverwriteResult isOverwrite(const Instruction *KillingI,
1034 const Instruction *DeadI,
1035 const MemoryLocation &KillingLoc,
1036 const MemoryLocation &DeadLoc,
1037 int64_t &KillingOff, int64_t &DeadOff);
1038
1039 bool isInvisibleToCallerAfterRet(const Value *V, const Value *Ptr,
1040 const LocationSize StoreSize);
1041
1042 bool isInvisibleToCallerOnUnwind(const Value *V);
1043
1044 std::optional<MemoryLocation> getLocForWrite(Instruction *I) const;
1045
1046 // Returns a list of <MemoryLocation, bool> pairs written by I.
1047 // The bool means whether the write is from Initializes attr.
1049 getLocForInst(Instruction *I, bool ConsiderInitializesAttr);
1050
1051 /// Assuming this instruction has a dead analyzable write, can we delete
1052 /// this instruction?
1053 bool isRemovable(Instruction *I);
1054
1055 /// Returns true if \p UseInst completely overwrites \p DefLoc
1056 /// (stored by \p DefInst).
1057 bool isCompleteOverwrite(const MemoryLocation &DefLoc, Instruction *DefInst,
1058 Instruction *UseInst);
1059
1060 /// Returns true if \p Def is not read before returning from the function.
1061 bool isWriteAtEndOfFunction(MemoryDef *Def, const MemoryLocation &DefLoc);
1062
1063 /// If \p I is a memory terminator like llvm.lifetime.end or free, return a
1064 /// pair with the MemoryLocation terminated by \p I and a boolean flag
1065 /// indicating whether \p I is a free-like call.
1066 std::optional<std::pair<MemoryLocation, bool>>
1067 getLocForTerminator(Instruction *I) const;
1068
1069 /// Returns true if \p I is a memory terminator instruction like
1070 /// llvm.lifetime.end or free.
1071 bool isMemTerminatorInst(Instruction *I) const;
1072
1073 /// Returns true if \p MaybeTerm is a memory terminator for \p Loc from
1074 /// instruction \p AccessI.
1075 bool isMemTerminator(const MemoryLocation &Loc, Instruction *AccessI,
1076 Instruction *MaybeTerm);
1077
1078 // Returns true if \p Use may read from \p DefLoc.
1079 bool isReadClobber(const MemoryLocation &DefLoc, Instruction *UseInst);
1080
1081 /// Returns true if a dependency between \p Current and \p KillingDef is
1082 /// guaranteed to be loop invariant for the loops that they are in. Either
1083 /// because they are known to be in the same block, in the same loop level or
1084 /// by guaranteeing that \p CurrentLoc only references a single MemoryLocation
1085 /// during execution of the containing function.
1086 bool isGuaranteedLoopIndependent(const Instruction *Current,
1087 const Instruction *KillingDef,
1088 const MemoryLocation &CurrentLoc);
1089
1090 /// Returns true if \p Ptr is guaranteed to be loop invariant for any possible
1091 /// loop. In particular, this guarantees that it only references a single
1092 /// MemoryLocation during execution of the containing function.
1093 bool isGuaranteedLoopInvariant(const Value *Ptr);
1094
1095 // Find a MemoryDef writing to \p KillingLoc and dominating \p StartAccess,
1096 // with no read access between them or on any other path to a function exit
1097 // block if \p KillingLoc is not accessible after the function returns. If
1098 // there is no such MemoryDef, return std::nullopt. The returned value may not
1099 // (completely) overwrite \p KillingLoc. Currently we bail out when we
1100 // encounter an aliasing MemoryUse (read).
1101 std::optional<MemoryAccess *>
1102 getDomMemoryDef(MemoryDef *KillingDef, MemoryAccess *StartAccess,
1103 const MemoryLocation &KillingLoc, const Value *KillingUndObj,
1104 unsigned &ScanLimit, unsigned &WalkerStepLimit,
1105 bool IsMemTerm, unsigned &PartialLimit,
1106 bool IsInitializesAttrMemLoc);
1107
1108 /// Delete dead memory defs and recursively add their operands to ToRemove if
1109 /// they became dead.
1110 void
1111 deleteDeadInstruction(Instruction *SI,
1112 SmallPtrSetImpl<MemoryAccess *> *Deleted = nullptr);
1113
1114 // Check for any extra throws between \p KillingI and \p DeadI that block
1115 // DSE. This only checks extra maythrows (those that aren't MemoryDef's).
1116 // MemoryDef that may throw are handled during the walk from one def to the
1117 // next.
1118 bool mayThrowBetween(Instruction *KillingI, Instruction *DeadI,
1119 const Value *KillingUndObj);
1120
1121 // Check if \p DeadI acts as a DSE barrier for \p KillingI. The following
1122 // instructions act as barriers:
1123 // * A memory instruction that may throw and \p KillingI accesses a non-stack
1124 // object.
1125 // * Atomic stores stronger that monotonic.
1126 bool isDSEBarrier(const Value *KillingUndObj, Instruction *DeadI);
1127
1128 /// Eliminate writes to objects that are not visible in the caller and are not
1129 /// accessed before returning from the function.
1130 bool eliminateDeadWritesAtEndOfFunction();
1131
1132 /// If we have a zero initializing memset following a call to malloc,
1133 /// try folding it into a call to calloc.
1134 bool tryFoldIntoCalloc(MemoryDef *Def, const Value *DefUO);
1135
1136 /// \returns true if \p Def is a no-op store, either because it
1137 /// directly stores back a loaded value or stores zero to a calloced object.
1138 bool storeIsNoop(MemoryDef *Def, const Value *DefUO);
1139
1140 bool removePartiallyOverlappedStores(InstOverlapIntervalsTy &IOL);
1141
1142 /// Eliminates writes to locations where the value that is being written
1143 /// is already stored at the same location.
1144 bool eliminateRedundantStoresOfExistingValues();
1145
1146 /// If there is a dominating condition that implies the value being stored in
1147 /// a pointer, and such a condition appears in a node that dominates the
1148 /// store, then the store may be redundant if no write occurs in between.
1149 bool eliminateRedundantStoresViaDominatingConditions();
1150
1151 // Return the locations written by the initializes attribute.
1152 // Note that this function considers:
1153 // 1. Unwind edge: use "initializes" attribute only if the callee has
1154 // "nounwind" attribute, or the argument has "dead_on_unwind" attribute,
1155 // or the argument is invisible to caller on unwind. That is, we don't
1156 // perform incorrect DSE on unwind edges in the current function.
1157 // 2. Argument alias: for aliasing arguments, the "initializes" attribute is
1158 // the intersected range list of their "initializes" attributes.
1159 SmallVector<MemoryLocation, 1> getInitializesArgMemLoc(const Instruction *I);
1160
1161 // Try to eliminate dead defs that access `KillingLocWrapper.MemLoc` and are
1162 // killed by `KillingLocWrapper.MemDef`. Return whether
1163 // any changes were made, and whether `KillingLocWrapper.DefInst` was deleted.
1164 std::pair<bool, bool>
1165 eliminateDeadDefs(const MemoryLocationWrapper &KillingLocWrapper);
1166
1167 // Try to eliminate dead defs killed by `KillingDefWrapper` and return the
1168 // change state: whether make any change.
1169 bool eliminateDeadDefs(const MemoryDefWrapper &KillingDefWrapper);
1170};
1171
1172} // end anonymous namespace
1173
1174static void pushMemUses(MemoryAccess *Acc,
1177 for (Use &U : Acc->uses()) {
1178 auto *MA = cast<MemoryAccess>(U.getUser());
1179 if (Visited.insert(MA).second)
1180 WorkList.push_back(MA);
1181 }
1182}
1183
1184// Return true if "Arg" is function local and isn't captured before "CB".
1185static bool isFuncLocalAndNotCaptured(Value *Arg, const CallBase *CB,
1187 const Value *UnderlyingObj = getUnderlyingObject(Arg);
1188 return isIdentifiedFunctionLocal(UnderlyingObj) &&
1189 capturesNothing(EA.getCapturesBefore(UnderlyingObj, CB, /*OrAt=*/true,
1190 /*ReturnCaptures=*/false));
1191}
1192
1193DSEState::DSEState(Function &F, AliasAnalysis &AA, MemorySSA &MSSA,
1195 const TargetLibraryInfo &TLI, const CycleInfo &CI)
1196 : F(F), AA(AA), EA(DT, nullptr, &CI), BatchAA(AA, &EA), MSSA(MSSA), DT(DT),
1197 PDT(PDT), TLI(TLI), DL(F.getDataLayout()), CI(CI) {
1198 // Collect blocks with throwing instructions not modeled in MemorySSA and
1199 // alloc-like objects.
1200 unsigned PO = 0;
1201 for (BasicBlock *BB : post_order(&F)) {
1202 PostOrderNumbers[BB] = PO++;
1203 for (Instruction &I : *BB) {
1204 MemoryAccess *MA = MSSA.getMemoryAccess(&I);
1205 if (I.mayThrow() && !MA)
1206 ThrowingBlocks.insert(I.getParent());
1207
1208 auto *MD = dyn_cast_or_null<MemoryDef>(MA);
1209 if (MD && MemDefs.size() < MemorySSADefsPerBlockLimit &&
1210 (getLocForWrite(&I) || isMemTerminatorInst(&I) ||
1212 MemDefs.push_back(MD);
1213 }
1214 }
1215
1216 // Treat byval, inalloca or dead on return arguments the same as Allocas,
1217 // stores to them are dead at the end of the function.
1218 for (Argument &AI : F.args()) {
1219 if (AI.hasPassPointeeByValueCopyAttr()) {
1220 InvisibleToCallerAfterRet.insert({&AI, true});
1221 continue;
1222 }
1223
1224 if (!AI.getType()->isPointerTy())
1225 continue;
1226
1227 const DeadOnReturnInfo &Info = AI.getDeadOnReturnInfo();
1228 if (Info.coversAllReachableMemory())
1229 InvisibleToCallerAfterRet.insert({&AI, true});
1230 else if (uint64_t DeadBytes = Info.getNumberOfDeadBytes())
1231 InvisibleToCallerAfterRetBounded.insert({&AI, DeadBytes});
1232 }
1233
1234 AnyUnreachableExit = any_of(PDT.roots(), [](const BasicBlock *E) {
1235 return isa<UnreachableInst>(E->getTerminator());
1236 });
1237}
1238
1239LocationSize DSEState::strengthenLocationSize(const Instruction *I,
1240 LocationSize Size) const {
1241 if (auto *CB = dyn_cast<CallBase>(I)) {
1242 LibFunc F = TLI.getLibFunc(*CB);
1243 if (TLI.has(F) && (F == LibFunc_memset_chk || F == LibFunc_memcpy_chk)) {
1244 // Use the precise location size specified by the 3rd argument
1245 // for determining KillingI overwrites DeadLoc if it is a memset_chk
1246 // instruction. memset_chk will write either the amount specified as 3rd
1247 // argument or the function will immediately abort and exit the program.
1248 // NOTE: AA may determine NoAlias if it can prove that the access size
1249 // is larger than the allocation size due to that being UB. To avoid
1250 // returning potentially invalid NoAlias results by AA, limit the use of
1251 // the precise location size to isOverwrite.
1252 if (const auto *Len = dyn_cast<ConstantInt>(CB->getArgOperand(2)))
1253 return LocationSize::precise(Len->getZExtValue());
1254 }
1255 }
1256 return Size;
1257}
1258
1259OverwriteResult DSEState::isOverwrite(const Instruction *KillingI,
1260 const Instruction *DeadI,
1261 const MemoryLocation &KillingLoc,
1262 const MemoryLocation &DeadLoc,
1263 int64_t &KillingOff, int64_t &DeadOff) {
1264 // AliasAnalysis does not always account for loops. Limit overwrite checks
1265 // to dependencies for which we can guarantee they are independent of any
1266 // loops they are in.
1267 if (!isGuaranteedLoopIndependent(DeadI, KillingI, DeadLoc))
1268 return OW_Unknown;
1269
1270 LocationSize KillingLocSize =
1271 strengthenLocationSize(KillingI, KillingLoc.Size);
1272 const Value *DeadPtr = DeadLoc.Ptr->stripPointerCasts();
1273 const Value *KillingPtr = KillingLoc.Ptr->stripPointerCasts();
1274 const Value *DeadUndObj = getUnderlyingObject(DeadPtr);
1275 const Value *KillingUndObj = getUnderlyingObject(KillingPtr);
1276
1277 // Check whether the killing store overwrites the whole object, in which
1278 // case the size/offset of the dead store does not matter.
1279 if (DeadUndObj == KillingUndObj && KillingLocSize.isPrecise() &&
1280 isIdentifiedObject(KillingUndObj)) {
1281 std::optional<TypeSize> KillingUndObjSize =
1282 getPointerSize(KillingUndObj, DL, TLI, &F);
1283 if (KillingUndObjSize && *KillingUndObjSize == KillingLocSize.getValue())
1284 return OW_Complete;
1285 }
1286
1287 // FIXME: Vet that this works for size upper-bounds. Seems unlikely that we'll
1288 // get imprecise values here, though (except for unknown sizes).
1289 if (!KillingLocSize.isPrecise() || !DeadLoc.Size.isPrecise()) {
1290 // In case no constant size is known, try to an IR values for the number
1291 // of bytes written and check if they match.
1292 const auto *KillingMemI = dyn_cast<MemIntrinsic>(KillingI);
1293 const auto *DeadMemI = dyn_cast<MemIntrinsic>(DeadI);
1294 if (KillingMemI && DeadMemI) {
1295 const Value *KillingV = KillingMemI->getLength();
1296 const Value *DeadV = DeadMemI->getLength();
1297 if (KillingV == DeadV && BatchAA.isMustAlias(DeadLoc, KillingLoc))
1298 return OW_Complete;
1299 }
1300
1301 // Masked stores have imprecise locations, but we can reason about them
1302 // to some extent.
1303 return isMaskedStoreOverwrite(KillingI, DeadI, BatchAA);
1304 }
1305
1306 const TypeSize KillingSize = KillingLocSize.getValue();
1307 const TypeSize DeadSize = DeadLoc.Size.getValue();
1308 // Bail on doing Size comparison which depends on AA for now
1309 // TODO: Remove AnyScalable once Alias Analysis deal with scalable vectors
1310 const bool AnyScalable = DeadSize.isScalable() || KillingLocSize.isScalable();
1311
1312 if (AnyScalable)
1313 return OW_Unknown;
1314 // Query the alias information
1315 AliasResult AAR = BatchAA.alias(KillingLoc, DeadLoc);
1316
1317 // If the start pointers are the same, we just have to compare sizes to see if
1318 // the killing store was larger than the dead store.
1319 if (AAR == AliasResult::MustAlias) {
1320 // Make sure that the KillingSize size is >= the DeadSize size.
1321 if (KillingSize >= DeadSize)
1322 return OW_Complete;
1323 }
1324
1325 // If we hit a partial alias we may have a full overwrite
1326 if (AAR == AliasResult::PartialAlias && AAR.hasOffset()) {
1327 int32_t Off = AAR.getOffset();
1328 if (Off >= 0 && (uint64_t)Off + DeadSize <= KillingSize)
1329 return OW_Complete;
1330 }
1331
1332 // If we can't resolve the same pointers to the same object, then we can't
1333 // analyze them at all.
1334 if (DeadUndObj != KillingUndObj) {
1335 // Non aliasing stores to different objects don't overlap. Note that
1336 // if the killing store is known to overwrite whole object (out of
1337 // bounds access overwrites whole object as well) then it is assumed to
1338 // completely overwrite any store to the same object even if they don't
1339 // actually alias (see next check).
1340 if (AAR == AliasResult::NoAlias)
1341 return OW_None;
1342 return OW_Unknown;
1343 }
1344
1345 // Okay, we have stores to two completely different pointers. Try to
1346 // decompose the pointer into a "base + constant_offset" form. If the base
1347 // pointers are equal, then we can reason about the two stores.
1348 DeadOff = 0;
1349 KillingOff = 0;
1350 const Value *DeadBasePtr =
1351 GetPointerBaseWithConstantOffset(DeadPtr, DeadOff, DL);
1352 const Value *KillingBasePtr =
1353 GetPointerBaseWithConstantOffset(KillingPtr, KillingOff, DL);
1354
1355 // If the base pointers still differ, we have two completely different
1356 // stores.
1357 if (DeadBasePtr != KillingBasePtr)
1358 return OW_Unknown;
1359
1360 // The killing access completely overlaps the dead store if and only if
1361 // both start and end of the dead one is "inside" the killing one:
1362 // |<->|--dead--|<->|
1363 // |-----killing------|
1364 // Accesses may overlap if and only if start of one of them is "inside"
1365 // another one:
1366 // |<->|--dead--|<-------->|
1367 // |-------killing--------|
1368 // OR
1369 // |-------dead-------|
1370 // |<->|---killing---|<----->|
1371 //
1372 // We have to be careful here as *Off is signed while *.Size is unsigned.
1373
1374 // Check if the dead access starts "not before" the killing one.
1375 if (DeadOff >= KillingOff) {
1376 // If the dead access ends "not after" the killing access then the
1377 // dead one is completely overwritten by the killing one.
1378 if (uint64_t(DeadOff - KillingOff) + DeadSize <= KillingSize)
1379 return OW_Complete;
1380 // If start of the dead access is "before" end of the killing access
1381 // then accesses overlap.
1382 else if ((uint64_t)(DeadOff - KillingOff) < KillingSize)
1383 return OW_MaybePartial;
1384 }
1385 // If start of the killing access is "before" end of the dead access then
1386 // accesses overlap.
1387 else if ((uint64_t)(KillingOff - DeadOff) < DeadSize) {
1388 return OW_MaybePartial;
1389 }
1390
1391 // Can reach here only if accesses are known not to overlap.
1392 return OW_None;
1393}
1394
1395bool DSEState::isInvisibleToCallerAfterRet(const Value *V, const Value *Ptr,
1396 const LocationSize StoreSize) {
1397 if (isa<AllocaInst>(V))
1398 return true;
1399
1400 auto IBounded = InvisibleToCallerAfterRetBounded.find(V);
1401 if (IBounded != InvisibleToCallerAfterRetBounded.end()) {
1402 int64_t ValueOffset;
1403 [[maybe_unused]] const Value *BaseValue =
1404 GetPointerBaseWithConstantOffset(Ptr, ValueOffset, DL);
1405 // If we are not able to find a constant offset from the UO, we have to
1406 // pessimistically assume that the store writes to memory out of the
1407 // dead_on_return bounds.
1408 if (BaseValue != V)
1409 return false;
1410 // This store is only invisible after return if we are in bounds of the
1411 // range marked dead.
1412 if (StoreSize.hasValue() &&
1413 ValueOffset + StoreSize.getValue() <= IBounded->second &&
1414 ValueOffset >= 0)
1415 return true;
1416 }
1417 auto I = InvisibleToCallerAfterRet.insert({V, false});
1418 if (I.second && isInvisibleToCallerOnUnwind(V) && isNoAliasCall(V))
1419 I.first->second = capturesNothing(
1420 PointerMayBeCaptured(V, CaptureComponents::Provenance).WithRet);
1421 return I.first->second;
1422}
1423
1424bool DSEState::isInvisibleToCallerOnUnwind(const Value *V) {
1425 bool RequiresNoCaptureBeforeUnwind;
1426 if (!isNotVisibleOnUnwind(V, RequiresNoCaptureBeforeUnwind))
1427 return false;
1428 if (!RequiresNoCaptureBeforeUnwind)
1429 return true;
1430
1431 auto I = CapturedBeforeReturn.insert({V, true});
1432 if (I.second)
1433 // NOTE: This could be made more precise by PointerMayBeCapturedBefore
1434 // with the killing MemoryDef. But we refrain from doing so for now to
1435 // limit compile-time and this does not cause any changes to the number
1436 // of stores removed on a large test set in practice.
1437 I.first->second = capturesAnything(
1438 PointerMayBeCaptured(V, CaptureComponents::Provenance).WithoutRet);
1439 return !I.first->second;
1440}
1441
1442std::optional<MemoryLocation> DSEState::getLocForWrite(Instruction *I) const {
1443 if (!I->mayWriteToMemory())
1444 return std::nullopt;
1445
1446 if (auto *CB = dyn_cast<CallBase>(I))
1447 return MemoryLocation::getForDest(CB, TLI);
1448
1450}
1451
1453DSEState::getLocForInst(Instruction *I, bool ConsiderInitializesAttr) {
1455 if (isMemTerminatorInst(I)) {
1456 if (auto Loc = getLocForTerminator(I))
1457 Locations.push_back(std::make_pair(Loc->first, false));
1458 return Locations;
1459 }
1460
1461 if (auto Loc = getLocForWrite(I))
1462 Locations.push_back(std::make_pair(*Loc, false));
1463
1464 if (ConsiderInitializesAttr) {
1465 for (auto &MemLoc : getInitializesArgMemLoc(I)) {
1466 Locations.push_back(std::make_pair(MemLoc, true));
1467 }
1468 }
1469 return Locations;
1470}
1471
1472bool DSEState::isRemovable(Instruction *I) {
1473 assert(getLocForWrite(I) && "Must have analyzable write");
1474
1475 // Don't remove volatile/atomic stores.
1476 if (StoreInst *SI = dyn_cast<StoreInst>(I))
1477 return SI->isUnordered();
1478
1479 if (auto *CB = dyn_cast<CallBase>(I)) {
1480 // Don't remove volatile memory intrinsics.
1481 if (auto *MI = dyn_cast<MemIntrinsic>(CB))
1482 return !MI->isVolatile();
1483
1484 // Never remove dead lifetime intrinsics, e.g. because they are followed
1485 // by a free.
1486 if (CB->isLifetimeStartOrEnd())
1487 return false;
1488
1489 return CB->use_empty() && CB->willReturn() && CB->doesNotThrow() &&
1490 !CB->isTerminator();
1491 }
1492
1493 return false;
1494}
1495
1496bool DSEState::isCompleteOverwrite(const MemoryLocation &DefLoc,
1497 Instruction *DefInst, Instruction *UseInst) {
1498 // UseInst has a MemoryDef associated in MemorySSA. It's possible for a
1499 // MemoryDef to not write to memory, e.g. a volatile load is modeled as a
1500 // MemoryDef.
1501 if (!UseInst->mayWriteToMemory())
1502 return false;
1503
1504 if (auto *CB = dyn_cast<CallBase>(UseInst))
1505 if (CB->onlyAccessesInaccessibleMemory())
1506 return false;
1507
1508 int64_t InstWriteOffset, DepWriteOffset;
1509 if (auto CC = getLocForWrite(UseInst))
1510 return isOverwrite(UseInst, DefInst, *CC, DefLoc, InstWriteOffset,
1511 DepWriteOffset) == OW_Complete;
1512 return false;
1513}
1514
1515bool DSEState::isWriteAtEndOfFunction(MemoryDef *Def,
1516 const MemoryLocation &DefLoc) {
1517 LLVM_DEBUG(dbgs() << " Check if def " << *Def << " ("
1518 << *Def->getMemoryInst()
1519 << ") is at the end the function \n");
1521 SmallPtrSet<MemoryAccess *, 8> Visited;
1522
1523 pushMemUses(Def, WorkList, Visited);
1524 for (unsigned I = 0; I < WorkList.size(); I++) {
1525 if (WorkList.size() >= MemorySSAScanLimit) {
1526 LLVM_DEBUG(dbgs() << " ... hit exploration limit.\n");
1527 return false;
1528 }
1529
1530 MemoryAccess *UseAccess = WorkList[I];
1531 if (isa<MemoryPhi>(UseAccess)) {
1532 // AliasAnalysis does not account for loops. Limit elimination to
1533 // candidates for which we can guarantee they always store to the same
1534 // memory location.
1535 if (!isGuaranteedLoopInvariant(DefLoc.Ptr))
1536 return false;
1537
1538 pushMemUses(cast<MemoryPhi>(UseAccess), WorkList, Visited);
1539 continue;
1540 }
1541 // TODO: Checking for aliasing is expensive. Consider reducing the amount
1542 // of times this is called and/or caching it.
1543 Instruction *UseInst = cast<MemoryUseOrDef>(UseAccess)->getMemoryInst();
1544 if (isReadClobber(DefLoc, UseInst)) {
1545 LLVM_DEBUG(dbgs() << " ... hit read clobber " << *UseInst << ".\n");
1546 return false;
1547 }
1548
1549 if (MemoryDef *UseDef = dyn_cast<MemoryDef>(UseAccess))
1550 pushMemUses(UseDef, WorkList, Visited);
1551 }
1552 return true;
1553}
1554
1555std::optional<std::pair<MemoryLocation, bool>>
1556DSEState::getLocForTerminator(Instruction *I) const {
1557 if (auto *CB = dyn_cast<CallBase>(I)) {
1558 if (CB->getIntrinsicID() == Intrinsic::lifetime_end)
1559 return {
1560 std::make_pair(MemoryLocation::getForArgument(CB, 0, &TLI), false)};
1561 if (Value *FreedOp = getFreedOperand(CB, &TLI))
1562 return {std::make_pair(MemoryLocation::getAfter(FreedOp), true)};
1563 }
1564
1565 return std::nullopt;
1566}
1567
1568bool DSEState::isMemTerminatorInst(Instruction *I) const {
1569 auto *CB = dyn_cast<CallBase>(I);
1570 return CB && (CB->getIntrinsicID() == Intrinsic::lifetime_end ||
1571 getFreedOperand(CB, &TLI) != nullptr);
1572}
1573
1574bool DSEState::isMemTerminator(const MemoryLocation &Loc, Instruction *AccessI,
1575 Instruction *MaybeTerm) {
1576 std::optional<std::pair<MemoryLocation, bool>> MaybeTermLoc =
1577 getLocForTerminator(MaybeTerm);
1578
1579 if (!MaybeTermLoc)
1580 return false;
1581
1582 // If the terminator is a free-like call, all accesses to the underlying
1583 // object can be considered terminated.
1584 if (getUnderlyingObject(Loc.Ptr) !=
1585 getUnderlyingObject(MaybeTermLoc->first.Ptr))
1586 return false;
1587
1588 auto TermLoc = MaybeTermLoc->first;
1589 if (MaybeTermLoc->second) {
1590 const Value *LocUO = getUnderlyingObject(Loc.Ptr);
1591 return BatchAA.isMustAlias(TermLoc.Ptr, LocUO);
1592 }
1593 int64_t InstWriteOffset = 0;
1594 int64_t DepWriteOffset = 0;
1595 return isOverwrite(MaybeTerm, AccessI, TermLoc, Loc, InstWriteOffset,
1596 DepWriteOffset) == OW_Complete;
1597}
1598
1599bool DSEState::isReadClobber(const MemoryLocation &DefLoc,
1600 Instruction *UseInst) {
1601 if (isNoopIntrinsic(UseInst))
1602 return false;
1603
1604 // Monotonic or weaker atomic stores can be re-ordered and do not need to be
1605 // treated as read clobber.
1606 if (auto SI = dyn_cast<StoreInst>(UseInst))
1607 return isStrongerThan(SI->getOrdering(), AtomicOrdering::Monotonic);
1608
1609 if (!UseInst->mayReadFromMemory())
1610 return false;
1611
1612 if (auto *CB = dyn_cast<CallBase>(UseInst))
1613 if (CB->onlyAccessesInaccessibleMemory())
1614 return false;
1615
1616 return isRefSet(BatchAA.getModRefInfo(UseInst, DefLoc));
1617}
1618
1619bool DSEState::isGuaranteedLoopIndependent(const Instruction *Current,
1620 const Instruction *KillingDef,
1621 const MemoryLocation &CurrentLoc) {
1622 // If the dependency is within the same block or loop level (being careful
1623 // of irreducible loops), we know that AA will return a valid result for the
1624 // memory dependency. (Both at the function level, outside of any loop,
1625 // would also be valid but we currently disable that to limit compile time).
1626 if (Current->getParent() == KillingDef->getParent())
1627 return true;
1628 CycleRef CurrentC = CI.getCycle(Current->getParent());
1629 if (CurrentC && CurrentC == CI.getCycle(KillingDef->getParent()))
1630 return true;
1631 // Otherwise check the memory location is invariant to any loops.
1632 return isGuaranteedLoopInvariant(CurrentLoc.Ptr);
1633}
1634
1635bool DSEState::isGuaranteedLoopInvariant(const Value *Ptr) {
1636 Ptr = Ptr->stripPointerCasts();
1637 if (auto *GEP = dyn_cast<GEPOperator>(Ptr))
1638 if (GEP->hasAllConstantIndices())
1639 Ptr = GEP->getPointerOperand()->stripPointerCasts();
1640
1641 if (auto *I = dyn_cast<Instruction>(Ptr)) {
1642 return I->getParent()->isEntryBlock() || !CI.getCycle(I->getParent());
1643 }
1644 return true;
1645}
1646
1647std::optional<MemoryAccess *> DSEState::getDomMemoryDef(
1648 MemoryDef *KillingDef, MemoryAccess *StartAccess,
1649 const MemoryLocation &KillingLoc, const Value *KillingUndObj,
1650 unsigned &ScanLimit, unsigned &WalkerStepLimit, bool IsMemTerm,
1651 unsigned &PartialLimit, bool IsInitializesAttrMemLoc) {
1652 if (ScanLimit == 0 || WalkerStepLimit == 0) {
1653 LLVM_DEBUG(dbgs() << "\n ... hit scan limit\n");
1654 return std::nullopt;
1655 }
1656
1657 MemoryAccess *Current = StartAccess;
1658 Instruction *KillingI = KillingDef->getMemoryInst();
1659 LLVM_DEBUG(dbgs() << " trying to get dominating access\n");
1660
1661 // Only optimize defining access of KillingDef when directly starting at its
1662 // defining access. The defining access also must only access KillingLoc. At
1663 // the moment we only support instructions with a single write location, so
1664 // it should be sufficient to disable optimizations for instructions that
1665 // also read from memory.
1666 bool CanOptimize = OptimizeMemorySSA &&
1667 KillingDef->getDefiningAccess() == StartAccess &&
1668 !KillingI->mayReadFromMemory();
1669
1670 // Find the next clobbering Mod access for DefLoc, starting at StartAccess.
1671 std::optional<MemoryLocation> CurrentLoc;
1672 for (;; Current = cast<MemoryDef>(Current)->getDefiningAccess()) {
1673 LLVM_DEBUG({
1674 dbgs() << " visiting " << *Current;
1675 if (!MSSA.isLiveOnEntryDef(Current) && isa<MemoryUseOrDef>(Current))
1676 dbgs() << " (" << *cast<MemoryUseOrDef>(Current)->getMemoryInst()
1677 << ")";
1678 dbgs() << "\n";
1679 });
1680
1681 // Reached TOP.
1682 if (MSSA.isLiveOnEntryDef(Current)) {
1683 LLVM_DEBUG(dbgs() << " ... found LiveOnEntryDef\n");
1684 if (CanOptimize && Current != KillingDef->getDefiningAccess())
1685 // The first clobbering def is... none.
1686 KillingDef->setOptimized(Current);
1687 return std::nullopt;
1688 }
1689
1690 // Cost of a step. Accesses in the same block are more likely to be valid
1691 // candidates for elimination, hence consider them cheaper.
1692 unsigned StepCost = KillingDef->getBlock() == Current->getBlock()
1695 if (WalkerStepLimit <= StepCost) {
1696 LLVM_DEBUG(dbgs() << " ... hit walker step limit\n");
1697 return std::nullopt;
1698 }
1699 WalkerStepLimit -= StepCost;
1700
1701 // Return for MemoryPhis. They cannot be eliminated directly and the
1702 // caller is responsible for traversing them.
1703 if (isa<MemoryPhi>(Current)) {
1704 LLVM_DEBUG(dbgs() << " ... found MemoryPhi\n");
1705 return Current;
1706 }
1707
1708 // Below, check if CurrentDef is a valid candidate to be eliminated by
1709 // KillingDef. If it is not, check the next candidate.
1710 MemoryDef *CurrentDef = cast<MemoryDef>(Current);
1711 Instruction *CurrentI = CurrentDef->getMemoryInst();
1712
1713 if (canSkipDef(CurrentDef, !isInvisibleToCallerOnUnwind(KillingUndObj))) {
1714 CanOptimize = false;
1715 continue;
1716 }
1717
1718 // Before we try to remove anything, check for any extra throwing
1719 // instructions that block us from DSEing
1720 if (mayThrowBetween(KillingI, CurrentI, KillingUndObj)) {
1721 LLVM_DEBUG(dbgs() << " ... skip, may throw!\n");
1722 return std::nullopt;
1723 }
1724
1725 // Check for anything that looks like it will be a barrier to further
1726 // removal
1727 if (isDSEBarrier(KillingUndObj, CurrentI)) {
1728 LLVM_DEBUG(dbgs() << " ... skip, barrier\n");
1729 return std::nullopt;
1730 }
1731
1732 // If Current is known to be on path that reads DefLoc or is a read
1733 // clobber, bail out, as the path is not profitable. We skip this check
1734 // for intrinsic calls, because the code knows how to handle memcpy
1735 // intrinsics.
1736 if (!isa<IntrinsicInst>(CurrentI) && isReadClobber(KillingLoc, CurrentI))
1737 return std::nullopt;
1738
1739 // Quick check if there are direct uses that are read-clobbers.
1740 if (any_of(Current->uses(), [this, &KillingLoc, StartAccess](Use &U) {
1741 if (auto *UseOrDef = dyn_cast<MemoryUseOrDef>(U.getUser()))
1742 return !MSSA.dominates(StartAccess, UseOrDef) &&
1743 isReadClobber(KillingLoc, UseOrDef->getMemoryInst());
1744 return false;
1745 })) {
1746 LLVM_DEBUG(dbgs() << " ... found a read clobber\n");
1747 return std::nullopt;
1748 }
1749
1750 // If Current does not have an analyzable write location or is not
1751 // removable, skip it.
1752 CurrentLoc = getLocForWrite(CurrentI);
1753 if (!CurrentLoc || !isRemovable(CurrentI)) {
1754 CanOptimize = false;
1755 continue;
1756 }
1757
1758 // AliasAnalysis does not account for loops. Limit elimination to
1759 // candidates for which we can guarantee they always store to the same
1760 // memory location and not located in different loops.
1761 if (!isGuaranteedLoopIndependent(CurrentI, KillingI, *CurrentLoc)) {
1762 LLVM_DEBUG(dbgs() << " ... not guaranteed loop independent\n");
1763 CanOptimize = false;
1764 continue;
1765 }
1766
1767 if (IsMemTerm) {
1768 // If the killing def is a memory terminator (e.g. lifetime.end), check
1769 // the next candidate if the current Current does not write the same
1770 // underlying object as the terminator.
1771 if (!isMemTerminator(*CurrentLoc, CurrentI, KillingI)) {
1772 CanOptimize = false;
1773 continue;
1774 }
1775 } else {
1776 int64_t KillingOffset = 0;
1777 int64_t DeadOffset = 0;
1778 auto OR = isOverwrite(KillingI, CurrentI, KillingLoc, *CurrentLoc,
1779 KillingOffset, DeadOffset);
1780 if (CanOptimize) {
1781 // CurrentDef is the earliest write clobber of KillingDef. Use it as
1782 // optimized access. Do not optimize if CurrentDef is already the
1783 // defining access of KillingDef.
1784 if (CurrentDef != KillingDef->getDefiningAccess() &&
1785 (OR == OW_Complete || OR == OW_MaybePartial))
1786 KillingDef->setOptimized(CurrentDef);
1787
1788 // Once a may-aliasing def is encountered do not set an optimized
1789 // access.
1790 if (OR != OW_None)
1791 CanOptimize = false;
1792 }
1793
1794 // If Current does not write to the same object as KillingDef, check
1795 // the next candidate.
1796 if (OR == OW_Unknown || OR == OW_None)
1797 continue;
1798 else if (OR == OW_MaybePartial) {
1799 // If KillingDef only partially overwrites Current, check the next
1800 // candidate if the partial step limit is exceeded. This aggressively
1801 // limits the number of candidates for partial store elimination,
1802 // which are less likely to be removable in the end.
1803 if (PartialLimit <= 1) {
1804 WalkerStepLimit -= 1;
1805 LLVM_DEBUG(dbgs() << " ... reached partial limit ... continue with "
1806 "next access\n");
1807 continue;
1808 }
1809 PartialLimit -= 1;
1810 }
1811 }
1812 break;
1813 };
1814
1815 // Accesses to objects accessible after the function returns can only be
1816 // eliminated if the access is dead along all paths to the exit. Collect
1817 // the blocks with killing (=completely overwriting MemoryDefs) and check if
1818 // they cover all paths from MaybeDeadAccess to any function exit.
1819 SmallPtrSet<Instruction *, 16> KillingDefs;
1820 KillingDefs.insert(KillingDef->getMemoryInst());
1821 MemoryAccess *MaybeDeadAccess = Current;
1822 MemoryLocation MaybeDeadLoc = *CurrentLoc;
1823 Instruction *MaybeDeadI = cast<MemoryDef>(MaybeDeadAccess)->getMemoryInst();
1824 LLVM_DEBUG(dbgs() << " Checking for reads of " << *MaybeDeadAccess << " ("
1825 << *MaybeDeadI << ")\n");
1826
1828 SmallPtrSet<MemoryAccess *, 32> Visited;
1829 pushMemUses(MaybeDeadAccess, WorkList, Visited);
1830
1831 // Check if DeadDef may be read.
1832 for (unsigned I = 0; I < WorkList.size(); I++) {
1833 MemoryAccess *UseAccess = WorkList[I];
1834
1835 LLVM_DEBUG(dbgs() << " " << *UseAccess);
1836 // Bail out if the number of accesses to check exceeds the scan limit.
1837 if (ScanLimit < (WorkList.size() - I)) {
1838 LLVM_DEBUG(dbgs() << "\n ... hit scan limit\n");
1839 return std::nullopt;
1840 }
1841 --ScanLimit;
1842 NumDomMemDefChecks++;
1843
1844 if (isa<MemoryPhi>(UseAccess)) {
1845 if (any_of(KillingDefs, [this, UseAccess](Instruction *KI) {
1846 return DT.properlyDominates(KI->getParent(), UseAccess->getBlock());
1847 })) {
1848 LLVM_DEBUG(dbgs() << " ... skipping, dominated by killing block\n");
1849 continue;
1850 }
1851 LLVM_DEBUG(dbgs() << "\n ... adding PHI uses\n");
1852 pushMemUses(UseAccess, WorkList, Visited);
1853 continue;
1854 }
1855
1856 Instruction *UseInst = cast<MemoryUseOrDef>(UseAccess)->getMemoryInst();
1857 LLVM_DEBUG(dbgs() << " (" << *UseInst << ")\n");
1858
1859 if (any_of(KillingDefs, [this, UseInst](Instruction *KI) {
1860 return DT.dominates(KI, UseInst);
1861 })) {
1862 LLVM_DEBUG(dbgs() << " ... skipping, dominated by killing def\n");
1863 continue;
1864 }
1865
1866 // A memory terminator kills all preceeding MemoryDefs and all succeeding
1867 // MemoryAccesses. We do not have to check it's users.
1868 if (isMemTerminator(MaybeDeadLoc, MaybeDeadI, UseInst)) {
1869 LLVM_DEBUG(
1870 dbgs()
1871 << " ... skipping, memterminator invalidates following accesses\n");
1872 continue;
1873 }
1874
1875 if (isNoopIntrinsic(cast<MemoryUseOrDef>(UseAccess)->getMemoryInst())) {
1876 LLVM_DEBUG(dbgs() << " ... adding uses of intrinsic\n");
1877 pushMemUses(UseAccess, WorkList, Visited);
1878 continue;
1879 }
1880
1881 if (UseInst->mayThrow() && !isInvisibleToCallerOnUnwind(KillingUndObj)) {
1882 LLVM_DEBUG(dbgs() << " ... found throwing instruction\n");
1883 return std::nullopt;
1884 }
1885
1886 // Uses which may read the original MemoryDef mean we cannot eliminate the
1887 // original MD. Stop walk.
1888 // If KillingDef is a CallInst with "initializes" attribute, the reads in
1889 // the callee would be dominated by initializations, so it should be safe.
1890 bool IsKillingDefFromInitAttr = false;
1891 if (IsInitializesAttrMemLoc) {
1892 if (KillingI == UseInst &&
1893 KillingUndObj == getUnderlyingObject(MaybeDeadLoc.Ptr))
1894 IsKillingDefFromInitAttr = true;
1895 }
1896
1897 if (isReadClobber(MaybeDeadLoc, UseInst) && !IsKillingDefFromInitAttr) {
1898 LLVM_DEBUG(dbgs() << " ... found read clobber\n");
1899 return std::nullopt;
1900 }
1901
1902 // If this worklist walks back to the original memory access (and the
1903 // pointer is not guarenteed loop invariant) then we cannot assume that a
1904 // store kills itself.
1905 if (MaybeDeadAccess == UseAccess &&
1906 !isGuaranteedLoopInvariant(MaybeDeadLoc.Ptr)) {
1907 LLVM_DEBUG(dbgs() << " ... found not loop invariant self access\n");
1908 return std::nullopt;
1909 }
1910 // Otherwise, for the KillingDef and MaybeDeadAccess we only have to check
1911 // if it reads the memory location.
1912 // TODO: It would probably be better to check for self-reads before
1913 // calling the function.
1914 if (KillingDef == UseAccess || MaybeDeadAccess == UseAccess) {
1915 LLVM_DEBUG(dbgs() << " ... skipping killing def/dom access\n");
1916 continue;
1917 }
1918
1919 // Check all uses for MemoryDefs, except for defs completely overwriting
1920 // the original location. Otherwise we have to check uses of *all*
1921 // MemoryDefs we discover, including non-aliasing ones. Otherwise we might
1922 // miss cases like the following
1923 // 1 = Def(LoE) ; <----- DeadDef stores [0,1]
1924 // 2 = Def(1) ; (2, 1) = NoAlias, stores [2,3]
1925 // Use(2) ; MayAlias 2 *and* 1, loads [0, 3].
1926 // (The Use points to the *first* Def it may alias)
1927 // 3 = Def(1) ; <---- Current (3, 2) = NoAlias, (3,1) = MayAlias,
1928 // stores [0,1]
1929 if (MemoryDef *UseDef = dyn_cast<MemoryDef>(UseAccess)) {
1930 if (isCompleteOverwrite(MaybeDeadLoc, MaybeDeadI, UseInst)) {
1931 BasicBlock *MaybeKillingBlock = UseInst->getParent();
1932 if (PostOrderNumbers.find(MaybeKillingBlock)->second <
1933 PostOrderNumbers.find(MaybeDeadAccess->getBlock())->second) {
1934 if (!isInvisibleToCallerAfterRet(KillingUndObj, KillingLoc.Ptr,
1935 KillingLoc.Size)) {
1937 << " ... found killing def " << *UseInst << "\n");
1938 KillingDefs.insert(UseInst);
1939 }
1940 } else {
1942 << " ... found preceeding def " << *UseInst << "\n");
1943 return std::nullopt;
1944 }
1945 } else
1946 pushMemUses(UseDef, WorkList, Visited);
1947 }
1948 }
1949
1950 // For accesses to locations visible after the function returns, make sure
1951 // that the location is dead (=overwritten) along all paths from
1952 // MaybeDeadAccess to the exit.
1953 if (!isInvisibleToCallerAfterRet(KillingUndObj, KillingLoc.Ptr,
1954 KillingLoc.Size)) {
1955 SmallPtrSet<BasicBlock *, 16> KillingBlocks;
1956 for (Instruction *KD : KillingDefs)
1957 KillingBlocks.insert(KD->getParent());
1958 assert(!KillingBlocks.empty() &&
1959 "Expected at least a single killing block");
1960
1961 // Find the common post-dominator of all killing blocks.
1962 BasicBlock *CommonPred = *KillingBlocks.begin();
1963 for (BasicBlock *BB : llvm::drop_begin(KillingBlocks)) {
1964 if (!CommonPred)
1965 break;
1966 CommonPred = PDT.findNearestCommonDominator(CommonPred, BB);
1967 }
1968
1969 // If the common post-dominator does not post-dominate MaybeDeadAccess,
1970 // there is a path from MaybeDeadAccess to an exit not going through a
1971 // killing block.
1972 if (!PDT.dominates(CommonPred, MaybeDeadAccess->getBlock())) {
1973 if (!AnyUnreachableExit)
1974 return std::nullopt;
1975
1976 // Fall back to CFG scan starting at all non-unreachable roots if not
1977 // all paths to the exit go through CommonPred.
1978 CommonPred = nullptr;
1979 }
1980
1981 // If CommonPred itself is in the set of killing blocks, we're done.
1982 if (KillingBlocks.count(CommonPred))
1983 return {MaybeDeadAccess};
1984
1985 SetVector<BasicBlock *> WorkList;
1986 // If CommonPred is null, there are multiple exits from the function.
1987 // They all have to be added to the worklist.
1988 if (CommonPred)
1989 WorkList.insert(CommonPred);
1990 else
1991 for (BasicBlock *R : PDT.roots()) {
1992 if (!isa<UnreachableInst>(R->getTerminator()))
1993 WorkList.insert(R);
1994 }
1995
1996 NumCFGTries++;
1997 // Check if all paths starting from an exit node go through one of the
1998 // killing blocks before reaching MaybeDeadAccess.
1999 for (unsigned I = 0; I < WorkList.size(); I++) {
2000 NumCFGChecks++;
2001 BasicBlock *Current = WorkList[I];
2002 if (KillingBlocks.count(Current))
2003 continue;
2004 if (Current == MaybeDeadAccess->getBlock())
2005 return std::nullopt;
2006
2007 // MaybeDeadAccess is reachable from the entry, so we don't have to
2008 // explore unreachable blocks further.
2009 if (!DT.isReachableFromEntry(Current))
2010 continue;
2011
2012 WorkList.insert_range(predecessors(Current));
2013
2014 if (WorkList.size() >= MemorySSAPathCheckLimit)
2015 return std::nullopt;
2016 }
2017 NumCFGSuccess++;
2018 }
2019
2020 // No aliasing MemoryUses of MaybeDeadAccess found, MaybeDeadAccess is
2021 // potentially dead.
2022 return {MaybeDeadAccess};
2023}
2024
2025void DSEState::deleteDeadInstruction(Instruction *SI,
2026 SmallPtrSetImpl<MemoryAccess *> *Deleted) {
2027 MemorySSAUpdater Updater(&MSSA);
2028 SmallVector<Instruction *, 32> NowDeadInsts;
2029 NowDeadInsts.push_back(SI);
2030 --NumFastOther;
2031
2032 while (!NowDeadInsts.empty()) {
2033 Instruction *DeadInst = NowDeadInsts.pop_back_val();
2034 ++NumFastOther;
2035
2036 // Try to preserve debug information attached to the dead instruction.
2037 salvageDebugInfo(*DeadInst);
2038 salvageKnowledge(DeadInst);
2039
2040 // Remove the Instruction from MSSA.
2041 MemoryAccess *MA = MSSA.getMemoryAccess(DeadInst);
2042 bool IsMemDef = MA && isa<MemoryDef>(MA);
2043 if (MA) {
2044 if (IsMemDef) {
2045 auto *MD = cast<MemoryDef>(MA);
2046 SkipStores.insert(MD);
2047 if (Deleted)
2048 Deleted->insert(MD);
2049 if (auto *SI = dyn_cast<StoreInst>(MD->getMemoryInst())) {
2050 if (SI->getValueOperand()->getType()->isPointerTy()) {
2051 const Value *UO = getUnderlyingObject(SI->getValueOperand());
2052 if (CapturedBeforeReturn.erase(UO))
2053 ShouldIterateEndOfFunctionDSE = true;
2054 InvisibleToCallerAfterRet.erase(UO);
2055 InvisibleToCallerAfterRetBounded.erase(UO);
2056 }
2057 }
2058 }
2059
2060 Updater.removeMemoryAccess(MA);
2061 }
2062
2063 auto I = IOLs.find(DeadInst->getParent());
2064 if (I != IOLs.end())
2065 I->second.erase(DeadInst);
2066 // Remove its operands
2067 for (Use &O : DeadInst->operands())
2068 if (Instruction *OpI = dyn_cast<Instruction>(O)) {
2069 O.set(PoisonValue::get(O->getType()));
2070 if (isInstructionTriviallyDead(OpI, &TLI))
2071 NowDeadInsts.push_back(OpI);
2072 }
2073
2074 EA.removeInstruction(DeadInst);
2075 // Remove memory defs directly if they don't produce results, but only
2076 // queue other dead instructions for later removal. They may have been
2077 // used as memory locations that have been cached by BatchAA. Removing
2078 // them here may lead to newly created instructions to be allocated at the
2079 // same address, yielding stale cache entries.
2080 if (IsMemDef && DeadInst->getType()->isVoidTy())
2081 DeadInst->eraseFromParent();
2082 else
2083 ToRemove.push_back(DeadInst);
2084 }
2085}
2086
2087bool DSEState::mayThrowBetween(Instruction *KillingI, Instruction *DeadI,
2088 const Value *KillingUndObj) {
2089 // First see if we can ignore it by using the fact that KillingI is an
2090 // alloca/alloca like object that is not visible to the caller during
2091 // execution of the function.
2092 if (KillingUndObj && isInvisibleToCallerOnUnwind(KillingUndObj))
2093 return false;
2094
2095 if (KillingI->getParent() == DeadI->getParent())
2096 return ThrowingBlocks.count(KillingI->getParent());
2097 return !ThrowingBlocks.empty();
2098}
2099
2100bool DSEState::isDSEBarrier(const Value *KillingUndObj, Instruction *DeadI) {
2101 // If DeadI may throw it acts as a barrier, unless we are to an
2102 // alloca/alloca like object that does not escape.
2103 if (DeadI->mayThrow() && !isInvisibleToCallerOnUnwind(KillingUndObj))
2104 return true;
2105
2106 // If DeadI is an atomic load/store stronger than monotonic, do not try to
2107 // eliminate/reorder it.
2108 if (DeadI->isAtomic()) {
2109 if (auto *LI = dyn_cast<LoadInst>(DeadI))
2110 return isStrongerThanMonotonic(LI->getOrdering());
2111 if (auto *SI = dyn_cast<StoreInst>(DeadI))
2112 return isStrongerThanMonotonic(SI->getOrdering());
2113 if (auto *ARMW = dyn_cast<AtomicRMWInst>(DeadI))
2114 return isStrongerThanMonotonic(ARMW->getOrdering());
2115 if (auto *CmpXchg = dyn_cast<AtomicCmpXchgInst>(DeadI))
2116 return isStrongerThanMonotonic(CmpXchg->getSuccessOrdering()) ||
2117 isStrongerThanMonotonic(CmpXchg->getFailureOrdering());
2118 llvm_unreachable("other instructions should be skipped in MemorySSA");
2119 }
2120 return false;
2121}
2122
2123bool DSEState::eliminateDeadWritesAtEndOfFunction() {
2124 bool MadeChange = false;
2125 LLVM_DEBUG(
2126 dbgs() << "Trying to eliminate MemoryDefs at the end of the function\n");
2127 do {
2128 ShouldIterateEndOfFunctionDSE = false;
2129 for (MemoryDef *Def : llvm::reverse(MemDefs)) {
2130 if (SkipStores.contains(Def))
2131 continue;
2132
2133 Instruction *DefI = Def->getMemoryInst();
2134 auto DefLoc = getLocForWrite(DefI);
2135 if (!DefLoc || !isRemovable(DefI)) {
2136 LLVM_DEBUG(dbgs() << " ... could not get location for write or "
2137 "instruction not removable.\n");
2138 continue;
2139 }
2140
2141 // NOTE: Currently eliminating writes at the end of a function is
2142 // limited to MemoryDefs with a single underlying object, to save
2143 // compile-time. In practice it appears the case with multiple
2144 // underlying objects is very uncommon. If it turns out to be important,
2145 // we can use getUnderlyingObjects here instead.
2146 const Value *UO = getUnderlyingObject(DefLoc->Ptr);
2147 if (!isInvisibleToCallerAfterRet(UO, DefLoc->Ptr, DefLoc->Size))
2148 continue;
2149
2150 if (isWriteAtEndOfFunction(Def, *DefLoc)) {
2151 // See through pointer-to-pointer bitcasts
2152 LLVM_DEBUG(dbgs() << " ... MemoryDef is not accessed until the end "
2153 "of the function\n");
2155 ++NumFastStores;
2156 MadeChange = true;
2157 }
2158 }
2159 } while (ShouldIterateEndOfFunctionDSE);
2160 return MadeChange;
2161}
2162
2163bool DSEState::eliminateRedundantStoresViaDominatingConditions() {
2164 bool MadeChange = false;
2165 LLVM_DEBUG(dbgs() << "Trying to eliminate MemoryDefs whose value being "
2166 "written is implied by a dominating condition\n");
2167
2168 using ConditionInfo = std::pair<Value *, Value *>;
2169 using ScopedHTType = ScopedHashTable<ConditionInfo, Instruction *>;
2170
2171 // We maintain a scoped hash table of the active dominating conditions for a
2172 // given node.
2173 ScopedHTType ActiveConditions;
2174 auto GetDominatingCondition = [&](BasicBlock *BB)
2175 -> std::optional<std::tuple<ConditionInfo, Instruction *, BasicBlock *>> {
2176 auto *BI = dyn_cast<CondBrInst>(BB->getTerminator());
2177 if (!BI)
2178 return std::nullopt;
2179
2180 // In case both blocks are the same, it is not possible to determine
2181 // if optimization is possible. (We would not want to optimize a store
2182 // in the FalseBB if condition is true and vice versa.)
2183 if (BI->getSuccessor(0) == BI->getSuccessor(1))
2184 return std::nullopt;
2185
2186 Instruction *ICmpL;
2187 CmpPredicate Pred;
2188 Value *StorePtr, *StoreVal;
2189 if (!match(BI->getCondition(),
2190 m_c_ICmp(Pred, m_Instruction(ICmpL, m_Load(m_Value(StorePtr))),
2191 m_Value(StoreVal))) ||
2192 !ICmpInst::isEquality(Pred))
2193 return std::nullopt;
2194
2195 // Ensure the replacement is allowed when comparing pointers, as
2196 // the equality compares addresses only, not pointers' provenance.
2197 if (StoreVal->getType()->isPointerTy() &&
2198 !canReplacePointersIfEqual(StoreVal, ICmpL, DL))
2199 return std::nullopt;
2200
2201 unsigned ImpliedSuccIdx = Pred == ICmpInst::ICMP_EQ ? 0 : 1;
2202 BasicBlock *ImpliedSucc = BI->getSuccessor(ImpliedSuccIdx);
2203 return {{ConditionInfo(StorePtr, StoreVal), ICmpL, ImpliedSucc}};
2204 };
2205
2206 auto VisitNode = [&](DomTreeNode *Node, unsigned Depth, auto &Self) -> void {
2208 return;
2209
2210 BasicBlock *BB = Node->getBlock();
2211 // Check for redundant stores against active known conditions.
2212 if (auto *Accesses = MSSA.getBlockDefs(BB)) {
2213 for (auto &Access : make_early_inc_range(*Accesses)) {
2214 auto *Def = dyn_cast<MemoryDef>(&Access);
2215 if (!Def)
2216 continue;
2217
2218 auto *SI = dyn_cast<StoreInst>(Def->getMemoryInst());
2219 if (!SI || !SI->isUnordered())
2220 continue;
2221
2222 Instruction *LI = ActiveConditions.lookup(
2223 {SI->getPointerOperand(), SI->getValueOperand()});
2224 if (!LI)
2225 continue;
2226
2227 // Found a dominating condition that may imply the value being stored.
2228 // Make sure there does not exist any clobbering access between the
2229 // load and the potential redundant store.
2230 MemoryAccess *LoadAccess = MSSA.getMemoryAccess(LI);
2231 MemoryAccess *ClobberingAccess =
2232 MSSA.getSkipSelfWalker()->getClobberingMemoryAccess(Def, BatchAA);
2233 if (MSSA.dominates(ClobberingAccess, LoadAccess)) {
2235 << "Removing No-Op Store:\n DEAD: " << *SI << '\n');
2237 NumRedundantStores++;
2238 MadeChange = true;
2239 }
2240 }
2241 }
2242
2243 // See whether this basic block establishes a dominating condition.
2244 auto MaybeCondition = GetDominatingCondition(BB);
2245
2246 for (DomTreeNode *Child : Node->children()) {
2247 // RAII scope for the active conditions.
2248 ScopedHTType::ScopeTy Scope(ActiveConditions);
2249 if (MaybeCondition) {
2250 const auto &[Cond, LI, ImpliedSucc] = *MaybeCondition;
2251 if (DT.dominates(BasicBlockEdge(BB, ImpliedSucc), Child->getBlock())) {
2252 // Found a condition that holds for this child, dominated by the
2253 // current node via the equality edge. Propagate the condition to
2254 // the children by pushing it onto the table.
2255 ActiveConditions.insert(Cond, LI);
2256 }
2257 }
2258
2259 // Recursively visit the children of this node. Upon destruction, the no
2260 // longer active condition before visiting any sibling nodes is popped
2261 // from the active scope.
2262 Self(Child, Depth + 1, Self);
2263 }
2264 };
2265
2266 // Do a DFS walk of the dom-tree.
2268
2269 return MadeChange;
2270}
2271
2272bool DSEState::tryFoldIntoCalloc(MemoryDef *Def, const Value *DefUO) {
2273 Instruction *DefI = Def->getMemoryInst();
2274 MemSetInst *MemSet = dyn_cast<MemSetInst>(DefI);
2275 if (!MemSet)
2276 // TODO: Could handle zero store to small allocation as well.
2277 return false;
2278 Constant *StoredConstant = dyn_cast<Constant>(MemSet->getValue());
2279 if (!StoredConstant || !StoredConstant->isNullValue())
2280 return false;
2281
2282 if (!isRemovable(DefI))
2283 // The memset might be volatile..
2284 return false;
2285
2286 if (F.hasFnAttribute(Attribute::SanitizeMemory) ||
2287 F.hasFnAttribute(Attribute::SanitizeAddress) ||
2288 F.hasFnAttribute(Attribute::SanitizeHWAddress) || F.getName() == "calloc")
2289 return false;
2290 auto *Malloc = const_cast<CallInst *>(dyn_cast<CallInst>(DefUO));
2291 if (!Malloc)
2292 return false;
2293 auto *InnerCallee = Malloc->getCalledFunction();
2294 if (!InnerCallee)
2295 return false;
2296 LibFunc Func = TLI.getLibFunc(*InnerCallee);
2297 StringRef ZeroedVariantName;
2298 if (Func != LibFunc_malloc || !TLI.has(Func)) {
2299 Attribute Attr = Malloc->getFnAttr("alloc-variant-zeroed");
2300 if (!Attr.isValid())
2301 return false;
2302 ZeroedVariantName = Attr.getValueAsString();
2303 if (ZeroedVariantName.empty())
2304 return false;
2305 }
2306
2307 // Gracefully handle malloc with unexpected memory attributes.
2308 auto *MallocDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(Malloc));
2309 if (!MallocDef)
2310 return false;
2311
2312 auto shouldCreateCalloc = [](CallInst *Malloc, CallInst *Memset) {
2313 // Check for br(icmp ptr, null), truebb, falsebb) pattern at the end
2314 // of malloc block
2315 auto *MallocBB = Malloc->getParent(), *MemsetBB = Memset->getParent();
2316 if (MallocBB == MemsetBB)
2317 return true;
2318 auto *Ptr = Memset->getArgOperand(0);
2319 auto *TI = MallocBB->getTerminator();
2320 BasicBlock *TrueBB, *FalseBB;
2321 if (!match(TI, m_Br(m_SpecificICmp(ICmpInst::ICMP_EQ, m_Specific(Ptr),
2322 m_Zero()),
2323 TrueBB, FalseBB)))
2324 return false;
2325 if (MemsetBB != FalseBB)
2326 return false;
2327 return true;
2328 };
2329
2330 if (Malloc->getOperand(0) != MemSet->getLength())
2331 return false;
2332 if (!shouldCreateCalloc(Malloc, MemSet) || !DT.dominates(Malloc, MemSet) ||
2333 !memoryIsNotModifiedBetween(Malloc, MemSet, BatchAA, DL, &DT))
2334 return false;
2335 IRBuilder<> IRB(Malloc);
2336 assert(Func == LibFunc_malloc || !ZeroedVariantName.empty());
2337 Value *Calloc = nullptr;
2338 if (!ZeroedVariantName.empty()) {
2339 LLVMContext &Ctx = Malloc->getContext();
2340 AttributeList Attrs = InnerCallee->getAttributes();
2341 AllocFnKind AllocKind =
2342 Attrs.getFnAttr(Attribute::AllocKind).getAllocKind() |
2343 AllocFnKind::Zeroed;
2344 AllocKind &= ~AllocFnKind::Uninitialized;
2345 Attrs =
2346 Attrs.addFnAttribute(Ctx, Attribute::getWithAllocKind(Ctx, AllocKind))
2347 .removeFnAttribute(Ctx, "alloc-variant-zeroed");
2348 FunctionCallee ZeroedVariant = Malloc->getModule()->getOrInsertFunction(
2349 ZeroedVariantName, InnerCallee->getFunctionType(), Attrs);
2350 cast<Function>(ZeroedVariant.getCallee())
2351 ->setCallingConv(Malloc->getCallingConv());
2353 Args.append(Malloc->arg_begin(), Malloc->arg_end());
2354 CallInst *CI = IRB.CreateCall(ZeroedVariant, Args, ZeroedVariantName);
2355 CI->setCallingConv(Malloc->getCallingConv());
2356 Calloc = CI;
2357 } else {
2358 Type *SizeTTy = Malloc->getArgOperand(0)->getType();
2359 Calloc = emitCalloc(ConstantInt::get(SizeTTy, 1), Malloc->getArgOperand(0),
2360 IRB, TLI, Malloc->getType()->getPointerAddressSpace());
2361 }
2362 if (!Calloc)
2363 return false;
2364
2365 if (MDNode *MD = Malloc->getMetadata(LLVMContext::MD_alloc_token))
2366 cast<Instruction>(Calloc)->setMetadata(LLVMContext::MD_alloc_token, MD);
2367
2368 MemorySSAUpdater Updater(&MSSA);
2369 auto *NewAccess = Updater.createMemoryAccessAfter(cast<Instruction>(Calloc),
2370 nullptr, MallocDef);
2371 auto *NewAccessMD = cast<MemoryDef>(NewAccess);
2372 Updater.insertDef(NewAccessMD, /*RenameUses=*/true);
2373 Malloc->replaceAllUsesWith(Calloc);
2375 return true;
2376}
2377
2378bool DSEState::storeIsNoop(MemoryDef *Def, const Value *DefUO) {
2379 Instruction *DefI = Def->getMemoryInst();
2380 StoreInst *Store = dyn_cast<StoreInst>(DefI);
2381 MemSetInst *MemSet = dyn_cast<MemSetInst>(DefI);
2382 Constant *StoredConstant = nullptr;
2383 if (Store)
2384 StoredConstant = dyn_cast<Constant>(Store->getOperand(0));
2385 else if (MemSet)
2386 StoredConstant = dyn_cast<Constant>(MemSet->getValue());
2387 else
2388 return false;
2389
2390 if (!isRemovable(DefI))
2391 return false;
2392
2393 if (StoredConstant) {
2394 Constant *InitC =
2395 getInitialValueOfAllocation(DefUO, &TLI, StoredConstant->getType());
2396 // If the clobbering access is LiveOnEntry, no instructions between them
2397 // can modify the memory location.
2398 if (InitC && InitC == StoredConstant)
2399 return MSSA.isLiveOnEntryDef(
2400 MSSA.getSkipSelfWalker()->getClobberingMemoryAccess(Def, BatchAA));
2401 }
2402
2403 if (!Store)
2404 return false;
2405
2406 if (auto *LoadI = dyn_cast<LoadInst>(Store->getOperand(0))) {
2407 if (LoadI->getPointerOperand() == Store->getOperand(1)) {
2408 // Get the defining access for the load.
2409 auto *LoadAccess = MSSA.getMemoryAccess(LoadI)->getDefiningAccess();
2410 // Fast path: the defining accesses are the same.
2411 if (LoadAccess == Def->getDefiningAccess())
2412 return true;
2413
2414 // Look through phi accesses. Recursively scan all phi accesses by
2415 // adding them to a worklist. Bail when we run into a memory def that
2416 // does not match LoadAccess.
2417 SetVector<MemoryAccess *> ToCheck;
2418 MemoryAccess *Current =
2419 MSSA.getWalker()->getClobberingMemoryAccess(Def, BatchAA);
2420 // We don't want to bail when we run into the store memory def. But,
2421 // the phi access may point to it. So, pretend like we've already
2422 // checked it.
2423 ToCheck.insert(Def);
2424 ToCheck.insert(Current);
2425 // Start at current (1) to simulate already having checked Def.
2426 for (unsigned I = 1; I < ToCheck.size(); ++I) {
2427 Current = ToCheck[I];
2428 if (auto PhiAccess = dyn_cast<MemoryPhi>(Current)) {
2429 // Check all the operands.
2430 for (auto &Use : PhiAccess->incoming_values())
2431 ToCheck.insert(cast<MemoryAccess>(&Use));
2432 continue;
2433 }
2434
2435 // If we found a memory def, bail. This happens when we have an
2436 // unrelated write in between an otherwise noop store.
2437 assert(isa<MemoryDef>(Current) && "Only MemoryDefs should reach here.");
2438 // TODO: Skip no alias MemoryDefs that have no aliasing reads.
2439 // We are searching for the definition of the store's destination.
2440 // So, if that is the same definition as the load, then this is a
2441 // noop. Otherwise, fail.
2442 if (LoadAccess != Current)
2443 return false;
2444 }
2445 return true;
2446 }
2447 }
2448
2449 return false;
2450}
2451
2452bool DSEState::removePartiallyOverlappedStores(InstOverlapIntervalsTy &IOL) {
2453 bool Changed = false;
2454 for (auto OI : IOL) {
2455 Instruction *DeadI = OI.first;
2456 MemoryLocation Loc = *getLocForWrite(DeadI);
2457 assert(isRemovable(DeadI) && "Expect only removable instruction");
2458
2459 const Value *Ptr = Loc.Ptr->stripPointerCasts();
2460 int64_t DeadStart = 0;
2461 uint64_t DeadSize = Loc.Size.getValue();
2462 GetPointerBaseWithConstantOffset(Ptr, DeadStart, DL);
2463 OverlapIntervalsTy &IntervalMap = OI.second;
2464 Changed |= tryToShortenEnd(DeadI, IntervalMap, DeadStart, DeadSize);
2465 if (IntervalMap.empty())
2466 continue;
2467 Changed |= tryToShortenBegin(DeadI, IntervalMap, DeadStart, DeadSize);
2468 }
2469 return Changed;
2470}
2471
2472bool DSEState::eliminateRedundantStoresOfExistingValues() {
2473 bool MadeChange = false;
2474 LLVM_DEBUG(dbgs() << "Trying to eliminate MemoryDefs that write the "
2475 "already existing value\n");
2476 for (auto *Def : MemDefs) {
2477 if (SkipStores.contains(Def) || MSSA.isLiveOnEntryDef(Def))
2478 continue;
2479
2480 Instruction *DefInst = Def->getMemoryInst();
2481 auto MaybeDefLoc = getLocForWrite(DefInst);
2482 if (!MaybeDefLoc || !isRemovable(DefInst))
2483 continue;
2484
2485 MemoryDef *UpperDef;
2486 // To conserve compile-time, we avoid walking to the next clobbering def.
2487 // Instead, we just try to get the optimized access, if it exists. DSE
2488 // will try to optimize defs during the earlier traversal.
2489 if (Def->isOptimized())
2490 UpperDef = dyn_cast<MemoryDef>(Def->getOptimized());
2491 else
2492 UpperDef = dyn_cast<MemoryDef>(Def->getDefiningAccess());
2493 if (!UpperDef || MSSA.isLiveOnEntryDef(UpperDef))
2494 continue;
2495
2496 Instruction *UpperInst = UpperDef->getMemoryInst();
2497 auto IsRedundantStore = [&]() {
2498 // We don't care about differences in call attributes here.
2499 if (DefInst->isIdenticalToWhenDefined(UpperInst,
2500 /*IntersectAttrs=*/true))
2501 return true;
2502 if (auto *MemSetI = dyn_cast<MemSetInst>(UpperInst)) {
2503 if (auto *SI = dyn_cast<StoreInst>(DefInst)) {
2504 // MemSetInst must have a write location.
2505 auto UpperLoc = getLocForWrite(UpperInst);
2506 if (!UpperLoc)
2507 return false;
2508 int64_t InstWriteOffset = 0;
2509 int64_t DepWriteOffset = 0;
2510 auto OR = isOverwrite(UpperInst, DefInst, *UpperLoc, *MaybeDefLoc,
2511 InstWriteOffset, DepWriteOffset);
2512 Value *StoredByte = isBytewiseValue(SI->getValueOperand(), DL);
2513 return StoredByte && StoredByte == MemSetI->getOperand(1) &&
2514 OR == OW_Complete;
2515 }
2516 }
2517 return false;
2518 };
2519
2520 if (!IsRedundantStore() || isReadClobber(*MaybeDefLoc, DefInst))
2521 continue;
2522 LLVM_DEBUG(dbgs() << "DSE: Remove No-Op Store:\n DEAD: " << *DefInst
2523 << '\n');
2524 deleteDeadInstruction(DefInst);
2525 NumRedundantStores++;
2526 MadeChange = true;
2527 }
2528 return MadeChange;
2529}
2530
2532DSEState::getInitializesArgMemLoc(const Instruction *I) {
2533 const CallBase *CB = dyn_cast<CallBase>(I);
2534 if (!CB)
2535 return {};
2536
2537 // Collect aliasing arguments and their initializes ranges.
2538 SmallMapVector<Value *, SmallVector<ArgumentInitInfo, 2>, 2> Arguments;
2539 for (unsigned Idx = 0, Count = CB->arg_size(); Idx < Count; ++Idx) {
2540 Value *CurArg = CB->getArgOperand(Idx);
2541 if (!CurArg->getType()->isPointerTy())
2542 continue;
2543
2544 ConstantRangeList Inits;
2545 Attribute InitializesAttr = CB->getParamAttr(Idx, Attribute::Initializes);
2546 // initializes on byval arguments refers to the callee copy, not the
2547 // original memory the caller passed in.
2548 if (InitializesAttr.isValid() && !CB->isByValArgument(Idx))
2549 Inits = InitializesAttr.getValueAsConstantRangeList();
2550
2551 // Check whether "CurArg" could alias with global variables. We require
2552 // either it's function local and isn't captured before or the "CB" only
2553 // accesses arg or inaccessible mem.
2554 if (!Inits.empty() && !CB->onlyAccessesInaccessibleMemOrArgMem() &&
2555 !isFuncLocalAndNotCaptured(CurArg, CB, EA))
2556 Inits = ConstantRangeList();
2557
2558 // We don't perform incorrect DSE on unwind edges in the current function,
2559 // and use the "initializes" attribute to kill dead stores if:
2560 // - The call does not throw exceptions, "CB->doesNotThrow()".
2561 // - Or the callee parameter has "dead_on_unwind" attribute.
2562 // - Or the argument is invisible to caller on unwind, and there are no
2563 // unwind edges from this call in the current function (e.g. `CallInst`).
2564 bool IsDeadOrInvisibleOnUnwind =
2565 CB->paramHasAttr(Idx, Attribute::DeadOnUnwind) ||
2566 (isa<CallInst>(CB) && isInvisibleToCallerOnUnwind(CurArg));
2567 ArgumentInitInfo InitInfo{Idx, IsDeadOrInvisibleOnUnwind, Inits};
2568 bool FoundAliasing = false;
2569 for (auto &[Arg, AliasList] : Arguments) {
2570 auto AAR = BatchAA.alias(MemoryLocation::getBeforeOrAfter(Arg),
2572 if (AAR == AliasResult::NoAlias) {
2573 continue;
2574 } else if (AAR == AliasResult::MustAlias) {
2575 FoundAliasing = true;
2576 AliasList.push_back(InitInfo);
2577 } else {
2578 // For PartialAlias and MayAlias, there is an offset or may be an
2579 // unknown offset between the arguments and we insert an empty init
2580 // range to discard the entire initializes info while intersecting.
2581 FoundAliasing = true;
2582 AliasList.push_back(ArgumentInitInfo{Idx, IsDeadOrInvisibleOnUnwind,
2583 ConstantRangeList()});
2584 }
2585 }
2586 if (!FoundAliasing)
2587 Arguments[CurArg] = {InitInfo};
2588 }
2589
2591 for (const auto &[_, Args] : Arguments) {
2592 auto IntersectedRanges =
2594 if (IntersectedRanges.empty())
2595 continue;
2596
2597 for (const auto &Arg : Args) {
2598 for (const auto &Range : IntersectedRanges) {
2599 int64_t Start = Range.getLower().getSExtValue();
2600 int64_t End = Range.getUpper().getSExtValue();
2601 // For now, we only handle locations starting at offset 0.
2602 if (Start == 0)
2603 Locations.push_back(MemoryLocation(CB->getArgOperand(Arg.Idx),
2604 LocationSize::precise(End - Start),
2605 CB->getAAMetadata()));
2606 }
2607 }
2608 }
2609 return Locations;
2610}
2611
2612std::pair<bool, bool>
2613DSEState::eliminateDeadDefs(const MemoryLocationWrapper &KillingLocWrapper) {
2614 bool Changed = false;
2615 bool DeletedKillingLoc = false;
2616 unsigned ScanLimit = MemorySSAScanLimit;
2617 unsigned WalkerStepLimit = MemorySSAUpwardsStepLimit;
2618 unsigned PartialLimit = MemorySSAPartialStoreLimit;
2619 // Worklist of MemoryAccesses that may be killed by
2620 // "KillingLocWrapper.MemDef".
2621 SmallSetVector<MemoryAccess *, 8> ToCheck;
2622 // Track MemoryAccesses that have been deleted in the loop below, so we can
2623 // skip them. Don't use SkipStores for this, which may contain reused
2624 // MemoryAccess addresses.
2625 SmallPtrSet<MemoryAccess *, 8> Deleted;
2626 [[maybe_unused]] unsigned OrigNumSkipStores = SkipStores.size();
2627 ToCheck.insert(KillingLocWrapper.MemDef->getDefiningAccess());
2628
2629 // Check if MemoryAccesses in the worklist are killed by
2630 // "KillingLocWrapper.MemDef".
2631 for (unsigned I = 0; I < ToCheck.size(); I++) {
2632 MemoryAccess *Current = ToCheck[I];
2633 if (Deleted.contains(Current))
2634 continue;
2635 std::optional<MemoryAccess *> MaybeDeadAccess = getDomMemoryDef(
2636 KillingLocWrapper.MemDef, Current, KillingLocWrapper.MemLoc,
2637 KillingLocWrapper.UnderlyingObject, ScanLimit, WalkerStepLimit,
2638 isMemTerminatorInst(KillingLocWrapper.DefInst), PartialLimit,
2639 KillingLocWrapper.DefByInitializesAttr);
2640
2641 if (!MaybeDeadAccess) {
2642 LLVM_DEBUG(dbgs() << " finished walk\n");
2643 continue;
2644 }
2645 MemoryAccess *DeadAccess = *MaybeDeadAccess;
2646 LLVM_DEBUG(dbgs() << " Checking if we can kill " << *DeadAccess);
2647 if (isa<MemoryPhi>(DeadAccess)) {
2648 LLVM_DEBUG(dbgs() << "\n ... adding incoming values to worklist\n");
2649 for (Value *V : cast<MemoryPhi>(DeadAccess)->incoming_values()) {
2650 MemoryAccess *IncomingAccess = cast<MemoryAccess>(V);
2651 BasicBlock *IncomingBlock = IncomingAccess->getBlock();
2652 BasicBlock *PhiBlock = DeadAccess->getBlock();
2653
2654 // We only consider incoming MemoryAccesses that come before the
2655 // MemoryPhi. Otherwise we could discover candidates that do not
2656 // strictly dominate our starting def.
2657 if (PostOrderNumbers[IncomingBlock] > PostOrderNumbers[PhiBlock])
2658 ToCheck.insert(IncomingAccess);
2659 }
2660 continue;
2661 }
2662 // We cannot apply the initializes attribute to DeadAccess/DeadDef.
2663 // It would incorrectly consider a call instruction as redundant store
2664 // and remove this call instruction.
2665 // TODO: this conflates the existence of a MemoryLocation with being able
2666 // to delete the instruction. Fix isRemovable() to consider calls with
2667 // side effects that cannot be removed, e.g. calls with the initializes
2668 // attribute, and remove getLocForInst(ConsiderInitializesAttr = false).
2669 MemoryDefWrapper DeadDefWrapper(
2670 cast<MemoryDef>(DeadAccess),
2671 getLocForInst(cast<MemoryDef>(DeadAccess)->getMemoryInst(),
2672 /*ConsiderInitializesAttr=*/false));
2673 assert(DeadDefWrapper.DefinedLocations.size() == 1);
2674 MemoryLocationWrapper &DeadLocWrapper =
2675 DeadDefWrapper.DefinedLocations.front();
2676 LLVM_DEBUG(dbgs() << " (" << *DeadLocWrapper.DefInst << ")\n");
2677 ToCheck.insert(DeadLocWrapper.MemDef->getDefiningAccess());
2678 NumGetDomMemoryDefPassed++;
2679
2680 if (!DebugCounter::shouldExecute(MemorySSACounter))
2681 continue;
2682 if (isMemTerminatorInst(KillingLocWrapper.DefInst)) {
2683 if (KillingLocWrapper.UnderlyingObject != DeadLocWrapper.UnderlyingObject)
2684 continue;
2685 LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: "
2686 << *DeadLocWrapper.DefInst << "\n KILLER: "
2687 << *KillingLocWrapper.DefInst << '\n');
2688 deleteDeadInstruction(DeadLocWrapper.DefInst, &Deleted);
2689 ++NumFastStores;
2690 Changed = true;
2691 } else {
2692 // Check if DeadI overwrites KillingI.
2693 int64_t KillingOffset = 0;
2694 int64_t DeadOffset = 0;
2695 OverwriteResult OR =
2696 isOverwrite(KillingLocWrapper.DefInst, DeadLocWrapper.DefInst,
2697 KillingLocWrapper.MemLoc, DeadLocWrapper.MemLoc,
2698 KillingOffset, DeadOffset);
2699 if (OR == OW_MaybePartial) {
2700 auto &IOL = IOLs[DeadLocWrapper.DefInst->getParent()];
2701 OR = isPartialOverwrite(KillingLocWrapper.MemLoc, DeadLocWrapper.MemLoc,
2702 KillingOffset, DeadOffset,
2703 DeadLocWrapper.DefInst, IOL);
2704 }
2705 if (EnablePartialStoreMerging && OR == OW_PartialEarlierWithFullLater) {
2706 auto *DeadSI = dyn_cast<StoreInst>(DeadLocWrapper.DefInst);
2707 auto *KillingSI = dyn_cast<StoreInst>(KillingLocWrapper.DefInst);
2708 // We are re-using tryToMergePartialOverlappingStores, which requires
2709 // DeadSI to dominate KillingSI.
2710 // TODO: implement tryToMergeParialOverlappingStores using MemorySSA.
2711 if (DeadSI && KillingSI && DT.dominates(DeadSI, KillingSI)) {
2712 if (Constant *Merged = tryToMergePartialOverlappingStores(
2713 KillingSI, DeadSI, KillingOffset, DeadOffset, DL, BatchAA,
2714 &DT)) {
2715
2716 // Update stored value of earlier store to merged constant.
2717 DeadSI->setOperand(0, Merged);
2718 ++NumModifiedStores;
2719 Changed = true;
2720 DeletedKillingLoc = true;
2721
2722 // Remove killing store and remove any outstanding overlap
2723 // intervals for the updated store.
2724 deleteDeadInstruction(KillingSI, &Deleted);
2725 auto I = IOLs.find(DeadSI->getParent());
2726 if (I != IOLs.end())
2727 I->second.erase(DeadSI);
2728 break;
2729 }
2730 }
2731 }
2732 if (OR == OW_Complete) {
2733 LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: "
2734 << *DeadLocWrapper.DefInst << "\n KILLER: "
2735 << *KillingLocWrapper.DefInst << '\n');
2736 deleteDeadInstruction(DeadLocWrapper.DefInst, &Deleted);
2737 ++NumFastStores;
2738 Changed = true;
2739 }
2740 }
2741 }
2742
2743 assert(SkipStores.size() - OrigNumSkipStores == Deleted.size() &&
2744 "SkipStores and Deleted out of sync?");
2745
2746 return {Changed, DeletedKillingLoc};
2747}
2748
2749bool DSEState::eliminateDeadDefs(const MemoryDefWrapper &KillingDefWrapper) {
2750 if (KillingDefWrapper.DefinedLocations.empty()) {
2751 LLVM_DEBUG(dbgs() << "Failed to find analyzable write location for "
2752 << *KillingDefWrapper.DefInst << "\n");
2753 return false;
2754 }
2755
2756 bool MadeChange = false;
2757 for (auto &KillingLocWrapper : KillingDefWrapper.DefinedLocations) {
2758 LLVM_DEBUG(dbgs() << "Trying to eliminate MemoryDefs killed by "
2759 << *KillingLocWrapper.MemDef << " ("
2760 << *KillingLocWrapper.DefInst << ")\n");
2761 auto [Changed, DeletedKillingLoc] = eliminateDeadDefs(KillingLocWrapper);
2762 MadeChange |= Changed;
2763
2764 // Check if the store is a no-op.
2765 if (!DeletedKillingLoc && storeIsNoop(KillingLocWrapper.MemDef,
2766 KillingLocWrapper.UnderlyingObject)) {
2767 LLVM_DEBUG(dbgs() << "DSE: Remove No-Op Store:\n DEAD: "
2768 << *KillingLocWrapper.DefInst << '\n');
2769 deleteDeadInstruction(KillingLocWrapper.DefInst);
2770 NumRedundantStores++;
2771 MadeChange = true;
2772 continue;
2773 }
2774 // Can we form a calloc from a memset/malloc pair?
2775 if (!DeletedKillingLoc &&
2776 tryFoldIntoCalloc(KillingLocWrapper.MemDef,
2777 KillingLocWrapper.UnderlyingObject)) {
2778 LLVM_DEBUG(dbgs() << "DSE: Remove memset after forming calloc:\n"
2779 << " DEAD: " << *KillingLocWrapper.DefInst << '\n');
2780 deleteDeadInstruction(KillingLocWrapper.DefInst);
2781 MadeChange = true;
2782 continue;
2783 }
2784 }
2785 return MadeChange;
2786}
2787
2790 const TargetLibraryInfo &TLI,
2791 const CycleInfo &CI) {
2792 bool MadeChange = false;
2793 DSEState State(F, AA, MSSA, DT, PDT, TLI, CI);
2794 // For each store:
2795 for (unsigned I = 0; I < State.MemDefs.size(); I++) {
2796 MemoryDef *KillingDef = State.MemDefs[I];
2797 if (State.SkipStores.count(KillingDef))
2798 continue;
2799
2800 MemoryDefWrapper KillingDefWrapper(
2801 KillingDef, State.getLocForInst(KillingDef->getMemoryInst(),
2803 MadeChange |= State.eliminateDeadDefs(KillingDefWrapper);
2804 }
2805
2807 for (auto &KV : State.IOLs)
2808 MadeChange |= State.removePartiallyOverlappedStores(KV.second);
2809
2810 MadeChange |= State.eliminateRedundantStoresOfExistingValues();
2811 MadeChange |= State.eliminateDeadWritesAtEndOfFunction();
2812 MadeChange |= State.eliminateRedundantStoresViaDominatingConditions();
2813
2814 while (!State.ToRemove.empty()) {
2815 Instruction *DeadInst = State.ToRemove.pop_back_val();
2816 DeadInst->eraseFromParent();
2817 }
2818
2819 return MadeChange;
2820}
2821
2822//===----------------------------------------------------------------------===//
2823// DSE Pass
2824//===----------------------------------------------------------------------===//
2829 MemorySSA &MSSA = AM.getResult<MemorySSAAnalysis>(F).getMSSA();
2832
2833 bool Changed = eliminateDeadStores(F, AA, MSSA, DT, PDT, TLI, CI);
2834
2835#ifdef LLVM_ENABLE_STATS
2837 for (auto &I : instructions(F))
2838 NumRemainingStores += isa<StoreInst>(&I);
2839#endif
2840
2841 if (!Changed)
2842 return PreservedAnalyses::all();
2843
2847 return PA;
2848}
2849
2850namespace {
2851
2852/// A legacy pass for the legacy pass manager that wraps \c DSEPass.
2853class DSELegacyPass : public FunctionPass {
2854public:
2855 static char ID; // Pass identification, replacement for typeid
2856
2857 DSELegacyPass() : FunctionPass(ID) {
2859 }
2860
2861 bool runOnFunction(Function &F) override {
2862 if (skipFunction(F))
2863 return false;
2864
2865 AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
2866 DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
2867 const TargetLibraryInfo &TLI =
2868 getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
2869 MemorySSA &MSSA = getAnalysis<MemorySSAWrapperPass>().getMSSA();
2870 PostDominatorTree &PDT =
2871 getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
2872 CycleInfo &CI = getAnalysis<CycleInfoWrapperPass>().getResult();
2873
2874 bool Changed = eliminateDeadStores(F, AA, MSSA, DT, PDT, TLI, CI);
2875
2876#ifdef LLVM_ENABLE_STATS
2878 for (auto &I : instructions(F))
2879 NumRemainingStores += isa<StoreInst>(&I);
2880#endif
2881
2882 return Changed;
2883 }
2884
2885 void getAnalysisUsage(AnalysisUsage &AU) const override {
2886 AU.setPreservesCFG();
2887 AU.addRequired<AAResultsWrapperPass>();
2888 AU.addRequired<TargetLibraryInfoWrapperPass>();
2889 AU.addPreserved<GlobalsAAWrapperPass>();
2890 AU.addRequired<DominatorTreeWrapperPass>();
2891 AU.addRequired<PostDominatorTreeWrapperPass>();
2892 AU.addRequired<MemorySSAWrapperPass>();
2893 AU.addPreserved<MemorySSAWrapperPass>();
2894 AU.addRequired<CycleInfoWrapperPass>();
2895 AU.addRequired<AssumptionCacheTracker>();
2896 }
2897};
2898
2899} // end anonymous namespace
2900
2901char DSELegacyPass::ID = 0;
2902
2903INITIALIZE_PASS_BEGIN(DSELegacyPass, "dse", "Dead Store Elimination", false,
2904 false)
2914INITIALIZE_PASS_END(DSELegacyPass, "dse", "Dead Store Elimination", false,
2915 false)
2916
2918 return new DSELegacyPass();
2919}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
AMDGPU Lower Kernel Arguments
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
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")
#define LLVM_ABI
Definition Compiler.h:215
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
DXIL Forward Handle Accesses
DXIL Resource Access
static void shortenAssignment(Instruction *Inst, Value *OriginalDest, uint64_t OldSizeInBits, uint64_t NewSizeInBits, bool IsOverwriteEnd)
static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, DominatorTree &DT, PostDominatorTree &PDT, const TargetLibraryInfo &TLI, const CycleInfo &CI)
MapVector< Instruction *, OverlapIntervalsTy > InstOverlapIntervalsTy
static bool canSkipDef(MemoryDef *D, bool DefVisibleToCaller)
static cl::opt< bool > EnableInitializesImprovement("enable-dse-initializes-attr-improvement", cl::init(true), cl::Hidden, cl::desc("Enable the initializes attr improvement in DSE"))
static bool isShortenableAtTheEnd(Instruction *I)
Returns true if the end of this instruction can be safely shortened in length.
static bool isNoopIntrinsic(Instruction *I)
static ConstantRangeList getIntersectedInitRangeList(ArrayRef< ArgumentInitInfo > Args, bool CallHasNoUnwindAttr)
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 void pushMemUses(MemoryAccess *Acc, SmallVectorImpl< MemoryAccess * > &WorkList, SmallPtrSetImpl< MemoryAccess * > &Visited)
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 bool isFuncLocalAndNotCaptured(Value *Arg, const CallBase *CB, EarliestEscapeAnalysis &EA)
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 > MaxDepthRecursion("dse-max-dom-cond-depth", cl::init(1024), cl::Hidden, cl::desc("Max dominator tree recursion depth for eliminating redundant " "stores via dominating conditions"))
static void adjustArgAttributes(AnyMemIntrinsic *Intrinsic, unsigned ArgNo, uint64_t PtrOffset)
Update the attributes given that a memory access is updated (the dereferenced pointer could be moved ...
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 bool hasInitializesAttr(Instruction *I)
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.
early cse Early CSE w MemorySSA
static bool runOnFunction(Function &F, bool PostInlining)
This is the interface for a simple mod/ref and alias analysis over globals.
Hexagon Common GEP
#define _
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
static void deleteDeadInstruction(Instruction *I)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
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...
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
if(PassOpts->AAPipeline)
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
const SmallVectorImpl< MachineOperand > & Cond
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)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
static bool VisitNode(MachineDomTreeNode *Node, Register TLSBaseAddrReg)
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Class for arbitrary precision integers.
Definition APInt.h:78
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1050
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
Definition APInt.h:255
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1509
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1583
@ 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
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:275
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
An immutable pass that tracks lazily created AssumptionCache objects.
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
This class holds the attributes for a particular argument, parameter, function, or return value.
Definition Attributes.h:407
LLVM_ABI ArrayRef< ConstantRange > getValueAsConstantRangeList() const
Return the attribute's value as a ConstantRange array.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:261
LLVM Basic Block Representation.
Definition BasicBlock.h:62
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
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.
Definition Analysis.h:73
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
void setCallingConv(CallingConv::ID CC)
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Get the attribute of a given kind from a given arg.
bool isByValArgument(unsigned ArgNo) const
Determine whether this argument is passed by value.
LLVM_ABI bool onlyAccessesInaccessibleMemOrArgMem() const
Determine if the function may only access memory that is either inaccessible from the IR or pointed t...
bool doesNotThrow() const
Determine if the call cannot unwind.
Value * getArgOperand(unsigned i) const
LLVM_ABI Value * getArgOperandWithAttribute(Attribute::AttrKind Kind) const
If one of the arguments has the specified attribute, returns its operand value.
unsigned arg_size() const
This class represents a list of constant ranges.
bool empty() const
Return true if this list contains no members.
LLVM_ABI ConstantRangeList intersectWith(const ConstantRangeList &CRL) const
Return the range list that results from the intersection of this ConstantRangeList with another Const...
const APInt & getLower() const
Return the lower value for this range.
const APInt & getUpper() const
Return the upper value for this range.
This is an important base class in LLVM.
Definition Constant.h:43
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition Constant.h:64
Analysis pass which computes a CycleInfo.
Legacy analysis pass which computes a CycleInfo.
static DIAssignID * getDistinct(LLVMContext &Context)
DbgVariableFragmentInfo FragmentInfo
static LLVM_ABI 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...
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Record of a variable value-assignment, aka a non instruction representation of the dbg....
static bool shouldExecute(CounterInfo &Counter)
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:284
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
iterator_range< root_iterator > roots()
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
Legacy analysis pass which computes a DominatorTree.
Definition Dominators.h:277
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
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.
Context-sensitive CaptureAnalysis provider, which computes and caches the earliest common dominator c...
void removeInstruction(Instruction *I)
CaptureComponents getCapturesBefore(const Value *Object, const Instruction *I, bool OrAt, bool ReturnCaptures) override
Return how Object may be captured before instruction I, considering only provenance captures.
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
const BasicBlock & getEntryBlock() const
Definition Function.h:793
CycleRef getCycle(const BlockT *Block) const
Find the innermost cycle containing Block.
static GetElementPtrInst * CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Create an "inbounds" getelementptr.
Legacy wrapper pass to provide the GlobalsAAResult object.
bool isEquality() const
Return true if this predicate is either EQ or NE.
LLVM_ABI bool mayThrow(bool IncludePhaseOneUnwind=false) const LLVM_READONLY
Return true if this instruction may throw an exception.
LLVM_ABI bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI bool isIdenticalToWhenDefined(const Instruction *I, bool IntersectAttrs=false) const LLVM_READONLY
This is like isIdenticalTo, except that it ignores the SubclassOptionalData flags,...
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI 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.
Definition LLVMContext.h:68
bool hasValue() const
static LocationSize precise(uint64_t Value)
bool isScalable() const
TypeSize getValue() const
bool isPrecise() const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1567
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:38
Value * getLength() const
Value * getValue() const
BasicBlock * getBlock() const
Definition MemorySSA.h:162
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
Definition MemorySSA.h:371
void setOptimized(MemoryAccess *MA)
Definition MemorySSA.h:392
A wrapper analysis pass for the legacy pass manager that exposes a MemoryDepnedenceResults instance.
Representation for a specific memory location.
static LLVM_ABI 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 getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location before or after Ptr, while remaining within the underl...
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 LLVM_ABI MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
static LLVM_ABI MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
An analysis that produces MemorySSA for a function.
Definition MemorySSA.h:922
MemoryAccess * getClobberingMemoryAccess(const Instruction *I, BatchAAResults &AA)
Given a memory Mod/Ref/ModRef'ing instruction, calling this will give you the nearest dominating Memo...
Definition MemorySSA.h:1035
Legacy analysis pass which computes MemorySSA.
Definition MemorySSA.h:975
Encapsulates MemorySSA, including all data associated with memory accesses.
Definition MemorySSA.h:702
DefsList * getBlockDefs(const BasicBlock *BB) const
Return the list of MemoryDef's and MemoryPhi's for a given basic block.
Definition MemorySSA.h:765
LLVM_ABI MemorySSAWalker * getSkipSelfWalker()
LLVM_ABI bool dominates(const MemoryAccess *A, const MemoryAccess *B) const
Given two memory accesses in potentially different blocks, determine whether MemoryAccess A dominates...
LLVM_ABI MemorySSAWalker * getWalker()
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
Definition MemorySSA.h:720
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
Definition MemorySSA.h:740
MemoryAccess * getDefiningAccess() const
Get the access that produces the memory state used by this Use.
Definition MemorySSA.h:260
Instruction * getMemoryInst() const
Get the instruction that this MemoryUse represents.
Definition MemorySSA.h:257
PHITransAddr - An address value which tracks and handles phi translation.
LLVM_ABI 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 ...
LLVM_ABI 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...
Value * getAddr() const
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static LLVM_ABI 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...
LLVM_ABI 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.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
void insert_range(Range &&R)
Definition SetVector.h:182
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
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.
iterator begin() const
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.
AtomicOrdering getOrdering() const
Returns the ordering constraint of this store instruction.
Value * getValueOperand()
bool isUnordered() const
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
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.
LibFunc getLibFunc(StringRef funcName) const
Searches for a particular function name.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:307
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
op_range operands()
Definition User.h:267
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:258
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:713
iterator_range< use_iterator > uses()
Definition Value.h:380
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
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.
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
auto m_Value()
Match an arbitrary value and ignore it.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
SmallVector< DbgVariableRecord * > getDVRAssignmentMarkers(const Instruction *Inst)
Return a range of dbg_assign records for which Inst performs the assignment they encode.
Definition DebugInfo.h:205
LLVM_ABI bool calculateFragmentIntersect(const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits, uint64_t SliceSizeInBits, const DbgVariableRecord *DVRAssign, 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
Definition RDFGraph.h:384
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
NodeAddr< FuncNode * > Func
Definition RDFGraph.h:393
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
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.
Definition STLExtras.h:315
LLVM_ABI void initializeDSELegacyPassPass(PassRegistry &)
LLVM_ABI 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,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool isStrongerThanMonotonic(AtomicOrdering AO)
@ Uninitialized
Definition Threading.h:60
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
Definition Alignment.h:134
AllocFnKind
Definition Attributes.h:53
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...
Definition Utils.cpp:1675
@ Store
The extracted value is stored (ExtractElement only).
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.
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...
Definition STLExtras.h:633
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
DomTreeNodeBase< BasicBlock > DomTreeNode
Definition Dominators.h:65
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
LLVM_ABI 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.
Definition Local.cpp:403
LLVM_ABI 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)
Definition STLExtras.h:407
LLVM_ABI bool canReplacePointersIfEqual(const Value *From, const Value *To, const DataLayout &DL)
Returns true if a pointer value From can be replaced with another pointer value \To if they are deeme...
Definition Loads.cpp:896
bool isModSet(const ModRefInfo MRI)
Definition ModRef.h:49
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI bool AreStatisticsEnabled()
Check if statistics are enabled.
LLVM_ABI 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...
LLVM_ABI Value * emitCalloc(Value *Num, Value *Size, IRBuilderBase &B, const TargetLibraryInfo &TLI, unsigned AddrSpace)
Emit a call to the calloc function.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
auto post_order(const T &G)
Post-order traversal of a graph.
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...
Definition Casting.h:547
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...
Definition Alignment.h:186
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI bool salvageKnowledge(Instruction *I, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr)
Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert if before I.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
LLVM_ABI bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
LLVM_ABI bool isIdentifiedFunctionLocal(const Value *V)
Return true if V is umabigously identified at the function-level.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI FunctionPass * createDeadStoreEliminationPass()
LLVM_ABI 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 capturesAnything(CaptureComponents CC)
Definition ModRef.h:379
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
bool capturesNothing(CaptureComponents CC)
Definition ModRef.h:375
LLVM_ABI 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)
Definition ModRef.h:52
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
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.