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 OldOffsetInBits, uint64_t OldSizeInBits,
517 uint64_t NewSizeInBits, bool IsOverwriteEnd) {
518 const DataLayout &DL = Inst->getDataLayout();
519 uint64_t DeadSliceSizeInBits = OldSizeInBits - NewSizeInBits;
520 uint64_t DeadSliceOffsetInBits =
521 OldOffsetInBits + (IsOverwriteEnd ? NewSizeInBits : 0);
522 auto SetDeadFragExpr = [](auto *Assign,
523 DIExpression::FragmentInfo DeadFragment) {
524 // createFragmentExpression expects an offset relative to the existing
525 // fragment offset if there is one.
526 uint64_t RelativeOffset = DeadFragment.OffsetInBits -
527 Assign->getExpression()
528 ->getFragmentInfo()
529 .value_or(DIExpression::FragmentInfo(0, 0))
530 .OffsetInBits;
532 Assign->getExpression(), RelativeOffset, DeadFragment.SizeInBits)) {
533 Assign->setExpression(*NewExpr);
534 return;
535 }
536 // Failed to create a fragment expression for this so discard the value,
537 // making this a kill location.
539 DIExpression::get(Assign->getContext(), {}), DeadFragment.OffsetInBits,
540 DeadFragment.SizeInBits);
541 Assign->setExpression(Expr);
542 Assign->setKillLocation();
543 };
544
545 // A DIAssignID to use so that the inserted dbg.assign intrinsics do not
546 // link to any instructions. Created in the loop below (once).
547 DIAssignID *LinkToNothing = nullptr;
548 LLVMContext &Ctx = Inst->getContext();
549 auto GetDeadLink = [&Ctx, &LinkToNothing]() {
550 if (!LinkToNothing)
551 LinkToNothing = DIAssignID::getDistinct(Ctx);
552 return LinkToNothing;
553 };
554
555 // Insert an unlinked dbg.assign intrinsic for the dead fragment after each
556 // overlapping dbg.assign intrinsic.
557 for (DbgVariableRecord *Assign : at::getDVRAssignmentMarkers(Inst)) {
558 std::optional<DIExpression::FragmentInfo> NewFragment;
559 if (!at::calculateFragmentIntersect(DL, OriginalDest, DeadSliceOffsetInBits,
560 DeadSliceSizeInBits, Assign,
561 NewFragment) ||
562 !NewFragment) {
563 // Either the intersection couldn't be worked out, or it covers the
564 // entire variable region described by the record. Full coverage leaves
565 // NewFragment empty rather than making calculateFragmentIntersect fail,
566 // so unlink the whole assignment from the store in both cases.
567 Assign->setKillAddress();
568 Assign->setAssignId(GetDeadLink());
569 continue;
570 }
571 // No intersect.
572 if (NewFragment->SizeInBits == 0)
573 continue;
574
575 // Fragments overlap: insert a new dbg.assign for this dead part.
576 auto *NewAssign = static_cast<decltype(Assign)>(Assign->clone());
577 NewAssign->insertAfter(Assign->getIterator());
578 NewAssign->setAssignId(GetDeadLink());
579 if (NewFragment)
580 SetDeadFragExpr(NewAssign, *NewFragment);
581 NewAssign->setKillAddress();
582 }
583}
584
585/// Update the attributes given that a memory access is updated (the
586/// dereferenced pointer could be moved forward when shortening a
587/// mem intrinsic).
588static void adjustArgAttributes(AnyMemIntrinsic *Intrinsic, unsigned ArgNo,
589 uint64_t PtrOffset) {
590 // Remember old attributes.
591 AttributeSet OldAttrs = Intrinsic->getParamAttributes(ArgNo);
592
593 // Find attributes that should be kept, and remove the rest.
594 AttributeMask AttrsToRemove;
595 for (auto &Attr : OldAttrs) {
596 if (Attr.hasKindAsEnum()) {
597 switch (Attr.getKindAsEnum()) {
598 default:
599 break;
600 case Attribute::Alignment:
601 // Only keep alignment if PtrOffset satisfy the alignment.
602 if (isAligned(Attr.getAlignment().valueOrOne(), PtrOffset))
603 continue;
604 break;
605 case Attribute::Dereferenceable:
606 case Attribute::DereferenceableOrNull:
607 // We could reduce the size of these attributes according to
608 // PtrOffset. But we simply drop these for now.
609 break;
610 case Attribute::NonNull:
611 case Attribute::NoUndef:
612 continue;
613 }
614 }
615 AttrsToRemove.addAttribute(Attr);
616 }
617
618 // Remove the attributes that should be dropped.
619 Intrinsic->removeParamAttrs(ArgNo, AttrsToRemove);
620}
621
622static bool tryToShorten(Instruction *DeadI, int64_t &DeadStart,
623 uint64_t &DeadSize, int64_t KillingStart,
624 uint64_t KillingSize, bool IsOverwriteEnd) {
625 auto *DeadIntrinsic = cast<AnyMemIntrinsic>(DeadI);
626 Align PrefAlign = DeadIntrinsic->getDestAlign().valueOrOne();
627
628 // We assume that memet/memcpy operates in chunks of the "largest" native
629 // type size and aligned on the same value. That means optimal start and size
630 // of memset/memcpy should be modulo of preferred alignment of that type. That
631 // is it there is no any sense in trying to reduce store size any further
632 // since any "extra" stores comes for free anyway.
633 // On the other hand, maximum alignment we can achieve is limited by alignment
634 // of initial store.
635
636 // TODO: Limit maximum alignment by preferred (or abi?) alignment of the
637 // "largest" native type.
638 // Note: What is the proper way to get that value?
639 // Should TargetTransformInfo::getRegisterBitWidth be used or anything else?
640 // PrefAlign = std::min(DL.getPrefTypeAlign(LargestType), PrefAlign);
641
642 int64_t ToRemoveStart = 0;
643 uint64_t ToRemoveSize = 0;
644 // Compute start and size of the region to remove. Make sure 'PrefAlign' is
645 // maintained on the remaining store.
646 if (IsOverwriteEnd) {
647 // Calculate required adjustment for 'KillingStart' in order to keep
648 // remaining store size aligned on 'PerfAlign'.
649 uint64_t Off =
650 offsetToAlignment(uint64_t(KillingStart - DeadStart), PrefAlign);
651 ToRemoveStart = KillingStart + Off;
652 if (DeadSize <= uint64_t(ToRemoveStart - DeadStart))
653 return false;
654 ToRemoveSize = DeadSize - uint64_t(ToRemoveStart - DeadStart);
655 } else {
656 ToRemoveStart = DeadStart;
657 assert(KillingSize >= uint64_t(DeadStart - KillingStart) &&
658 "Not overlapping accesses?");
659 ToRemoveSize = KillingSize - uint64_t(DeadStart - KillingStart);
660 // Calculate required adjustment for 'ToRemoveSize'in order to keep
661 // start of the remaining store aligned on 'PerfAlign'.
662 uint64_t Off = offsetToAlignment(ToRemoveSize, PrefAlign);
663 if (Off != 0) {
664 if (ToRemoveSize <= (PrefAlign.value() - Off))
665 return false;
666 ToRemoveSize -= PrefAlign.value() - Off;
667 }
668 assert(isAligned(PrefAlign, ToRemoveSize) &&
669 "Should preserve selected alignment");
670 }
671
672 assert(ToRemoveSize > 0 && "Shouldn't reach here if nothing to remove");
673 assert(DeadSize > ToRemoveSize && "Can't remove more than original size");
674
675 uint64_t NewSize = DeadSize - ToRemoveSize;
676 if (DeadIntrinsic->isAtomic()) {
677 // When shortening an atomic memory intrinsic, the newly shortened
678 // length must remain an integer multiple of the element size.
679 const uint32_t ElementSize = DeadIntrinsic->getElementSizeInBytes();
680 if (0 != NewSize % ElementSize)
681 return false;
682 }
683
684 LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n OW "
685 << (IsOverwriteEnd ? "END" : "BEGIN") << ": " << *DeadI
686 << "\n KILLER [" << ToRemoveStart << ", "
687 << int64_t(ToRemoveStart + ToRemoveSize) << ")\n");
688
689 DeadIntrinsic->setLength(NewSize);
690 DeadIntrinsic->setDestAlignment(PrefAlign);
691
692 Value *OrigDest = DeadIntrinsic->getRawDest();
693 if (!IsOverwriteEnd) {
694 Value *Indices[1] = {
695 ConstantInt::get(DeadIntrinsic->getLength()->getType(), ToRemoveSize)};
697 Type::getInt8Ty(DeadIntrinsic->getContext()), OrigDest, Indices, "",
698 DeadI->getIterator());
699 NewDestGEP->setDebugLoc(DeadIntrinsic->getDebugLoc());
700 DeadIntrinsic->setDest(NewDestGEP);
701 adjustArgAttributes(DeadIntrinsic, 0, ToRemoveSize);
702 }
703
704 // Update attached dbg.assign intrinsics. Assume 8-bit byte.
705 shortenAssignment(DeadI, OrigDest, DeadStart * 8, DeadSize * 8, NewSize * 8,
706 IsOverwriteEnd);
707
708 // Finally update start and size of dead access.
709 if (!IsOverwriteEnd)
710 DeadStart += ToRemoveSize;
711 DeadSize = NewSize;
712
713 return true;
714}
715
717 int64_t &DeadStart, uint64_t &DeadSize) {
718 if (IntervalMap.empty() || !isShortenableAtTheEnd(DeadI))
719 return false;
720
721 OverlapIntervalsTy::iterator OII = --IntervalMap.end();
722 int64_t KillingStart = OII->second;
723 uint64_t KillingSize = OII->first - KillingStart;
724
725 assert(OII->first - KillingStart >= 0 && "Size expected to be positive");
726
727 if (KillingStart > DeadStart &&
728 // Note: "KillingStart - KillingStart" is known to be positive due to
729 // preceding check.
730 (uint64_t)(KillingStart - DeadStart) < DeadSize &&
731 // Note: "DeadSize - (uint64_t)(KillingStart - DeadStart)" is known to
732 // be non negative due to preceding checks.
733 KillingSize >= DeadSize - (uint64_t)(KillingStart - DeadStart)) {
734 if (tryToShorten(DeadI, DeadStart, DeadSize, KillingStart, KillingSize,
735 true)) {
736 IntervalMap.erase(OII);
737 return true;
738 }
739 }
740 return false;
741}
742
745 int64_t &DeadStart, uint64_t &DeadSize) {
747 return false;
748
749 OverlapIntervalsTy::iterator OII = IntervalMap.begin();
750 int64_t KillingStart = OII->second;
751 uint64_t KillingSize = OII->first - KillingStart;
752
753 assert(OII->first - KillingStart >= 0 && "Size expected to be positive");
754
755 if (KillingStart <= DeadStart &&
756 // Note: "DeadStart - KillingStart" is known to be non negative due to
757 // preceding check.
758 KillingSize > (uint64_t)(DeadStart - KillingStart)) {
759 // Note: "KillingSize - (uint64_t)(DeadStart - DeadStart)" is known to
760 // be positive due to preceding checks.
761 assert(KillingSize - (uint64_t)(DeadStart - KillingStart) < DeadSize &&
762 "Should have been handled as OW_Complete");
763 if (tryToShorten(DeadI, DeadStart, DeadSize, KillingStart, KillingSize,
764 false)) {
765 IntervalMap.erase(OII);
766 return true;
767 }
768 }
769 return false;
770}
771
772static Constant *
774 int64_t KillingOffset, int64_t DeadOffset,
776 DominatorTree *DT) {
777 assert(KillingI);
778 assert(DeadI);
779
780 // If the store we find is:
781 // a) partially overwritten by the store to 'Loc'
782 // b) the killing store is fully contained in the dead one and
783 // c) they both have a constant value
784 // d) none of the two stores need padding
785 // Merge the two stores, replacing the dead store's value with a
786 // merge of both values.
787 //
788 // TODO: Deal with other constant types (vectors, etc), and probably
789 // some mem intrinsics (if needed)
790 if (!isa<ConstantInt>(DeadI->getValueOperand()) ||
791 !DL.typeSizeEqualsStoreSize(DeadI->getValueOperand()->getType()) ||
792 !isa<ConstantInt>(KillingI->getValueOperand()) ||
793 !DL.typeSizeEqualsStoreSize(KillingI->getValueOperand()->getType()) ||
794 !memoryIsNotModifiedBetween(DeadI, KillingI, AA, DL, DT))
795 return nullptr;
796
797 // The merge erases KillingI and writes its bytes via DeadI. For that to be
798 // safe:
799 // - KillingI must be deletable (not volatile, ordering at most unordered),
800 // - DeadI must be safe to rewrite, and
801 // - their orderings must match, so the bytes originally written by
802 // KillingI keep the same atomicity after they are folded into DeadI.
803 // This allows merging two simple stores or two unordered-atomic stores with
804 // matching ordering, while leaving volatile and ordered-atomic stores in
805 // place.
806 if (!KillingI->isUnordered() || !DeadI->isUnordered() ||
807 KillingI->getOrdering() != DeadI->getOrdering())
808 return nullptr;
809
810 APInt DeadValue = cast<ConstantInt>(DeadI->getValueOperand())->getValue();
811 APInt KillingValue =
812 cast<ConstantInt>(KillingI->getValueOperand())->getValue();
813 unsigned KillingBits = KillingValue.getBitWidth();
814 assert(DeadValue.getBitWidth() > KillingValue.getBitWidth());
815 KillingValue = KillingValue.zext(DeadValue.getBitWidth());
816
817 // Offset of the smaller store inside the larger store
818 unsigned BitOffsetDiff = (KillingOffset - DeadOffset) * 8;
819 unsigned LShiftAmount =
820 DL.isBigEndian() ? DeadValue.getBitWidth() - BitOffsetDiff - KillingBits
821 : BitOffsetDiff;
822 APInt Mask = APInt::getBitsSet(DeadValue.getBitWidth(), LShiftAmount,
823 LShiftAmount + KillingBits);
824 // Clear the bits we'll be replacing, then OR with the smaller
825 // store, shifted appropriately.
826 APInt Merged = (DeadValue & ~Mask) | (KillingValue << LShiftAmount);
827 LLVM_DEBUG(dbgs() << "DSE: Merge Stores:\n Dead: " << *DeadI
828 << "\n Killing: " << *KillingI
829 << "\n Merged Value: " << Merged << '\n');
830 return ConstantInt::get(DeadI->getValueOperand()->getType(), Merged);
831}
832
833// Returns true if \p I is an intrinsic that does not read or write memory.
836 switch (II->getIntrinsicID()) {
837 case Intrinsic::lifetime_start:
838 case Intrinsic::lifetime_end:
839 case Intrinsic::invariant_end:
840 case Intrinsic::launder_invariant_group:
841 case Intrinsic::assume:
842 return true;
843 case Intrinsic::dbg_declare:
844 case Intrinsic::dbg_label:
845 case Intrinsic::dbg_value:
846 llvm_unreachable("Intrinsic should not be modeled in MemorySSA");
847 default:
848 return false;
849 }
850 }
851 return false;
852}
853
854// Check if we can ignore \p D for DSE.
855static bool canSkipDef(MemoryDef *D, bool DefVisibleToCaller) {
856 Instruction *DI = D->getMemoryInst();
857 // Calls that only access inaccessible memory cannot read or write any memory
858 // locations we consider for elimination.
859 if (auto *CB = dyn_cast<CallBase>(DI))
860 if (CB->onlyAccessesInaccessibleMemory())
861 return true;
862
863 // We can eliminate stores to locations not visible to the caller across
864 // throwing instructions.
865 if (DI->mayThrow() && !DefVisibleToCaller)
866 return true;
867
868 // We can remove the dead stores, irrespective of the fence and its ordering
869 // (release/acquire/seq_cst). Fences only constraints the ordering of
870 // already visible stores, it does not make a store visible to other
871 // threads. So, skipping over a fence does not change a store from being
872 // dead.
873 if (isa<FenceInst>(DI))
874 return true;
875
876 // Skip intrinsics that do not really read or modify memory.
877 if (isNoopIntrinsic(DI))
878 return true;
879
880 return false;
881}
882
883namespace {
884
885// A memory location wrapper that represents a MemoryLocation, `MemLoc`,
886// defined by `MemDef`.
887struct MemoryLocationWrapper {
888 MemoryLocationWrapper(MemoryLocation MemLoc, MemoryDef *MemDef,
889 bool DefByInitializesAttr)
890 : MemLoc(MemLoc), MemDef(MemDef),
891 DefByInitializesAttr(DefByInitializesAttr) {
892 assert(MemLoc.Ptr && "MemLoc should be not null");
893 UnderlyingObject = getUnderlyingObject(MemLoc.Ptr);
894 DefInst = MemDef->getMemoryInst();
895 }
896
897 MemoryLocation MemLoc;
898 const Value *UnderlyingObject;
899 MemoryDef *MemDef;
900 Instruction *DefInst;
901 bool DefByInitializesAttr = false;
902};
903
904// A memory def wrapper that represents a MemoryDef and the MemoryLocation(s)
905// defined by this MemoryDef.
906struct MemoryDefWrapper {
907 MemoryDefWrapper(MemoryDef *MemDef,
908 ArrayRef<std::pair<MemoryLocation, bool>> MemLocations) {
909 DefInst = MemDef->getMemoryInst();
910 for (auto &[MemLoc, DefByInitializesAttr] : MemLocations)
911 DefinedLocations.push_back(
912 MemoryLocationWrapper(MemLoc, MemDef, DefByInitializesAttr));
913 }
914 Instruction *DefInst;
916};
917
918struct ArgumentInitInfo {
919 unsigned Idx;
920 bool IsDeadOrInvisibleOnUnwind;
921 ConstantRangeList Inits;
922};
923} // namespace
924
927 return CB && CB->getArgOperandWithAttribute(Attribute::Initializes);
928}
929
930// Return the intersected range list of the initializes attributes of "Args".
931// "Args" are call arguments that alias to each other.
932// If any argument in "Args" doesn't have dead_on_unwind attr and
933// "CallHasNoUnwindAttr" is false, return empty.
936 bool CallHasNoUnwindAttr) {
937 if (Args.empty())
938 return {};
939
940 // To address unwind, the function should have nounwind attribute or the
941 // arguments have dead or invisible on unwind. Otherwise, return empty.
942 for (const auto &Arg : Args) {
943 if (!CallHasNoUnwindAttr && !Arg.IsDeadOrInvisibleOnUnwind)
944 return {};
945 if (Arg.Inits.empty())
946 return {};
947 }
948
949 ConstantRangeList IntersectedIntervals = Args.front().Inits;
950 for (auto &Arg : Args.drop_front())
951 IntersectedIntervals = IntersectedIntervals.intersectWith(Arg.Inits);
952
953 return IntersectedIntervals;
954}
955
956namespace {
957
958struct DSEState {
959 Function &F;
960 AliasAnalysis &AA;
961 EarliestEscapeAnalysis EA;
962
963 /// The single BatchAA instance that is used to cache AA queries. It will
964 /// not be invalidated over the whole run. This is safe, because:
965 /// 1. Only memory writes are removed, so the alias cache for memory
966 /// locations remains valid.
967 /// 2. No new instructions are added (only instructions removed), so cached
968 /// information for a deleted value cannot be accessed by a re-used new
969 /// value pointer.
970 BatchAAResults BatchAA;
971
972 MemorySSA &MSSA;
973 DominatorTree &DT;
974 PostDominatorTree &PDT;
975 const TargetLibraryInfo &TLI;
976 const DataLayout &DL;
977 const CycleInfo &CI;
978
979 // All MemoryDefs that potentially could kill other MemDefs.
981 // Any that should be skipped as they are already deleted
982 SmallPtrSet<MemoryAccess *, 4> SkipStores;
983 // Keep track whether a given object is captured before return or not.
984 DenseMap<const Value *, bool> CapturedBeforeReturn;
985 // Keep track of all of the objects that are invisible to the caller after
986 // the function returns.
987 DenseMap<const Value *, bool> InvisibleToCallerAfterRet;
988 DenseMap<const Value *, uint64_t> InvisibleToCallerAfterRetBounded;
989 // Keep track of blocks with throwing instructions not modeled in MemorySSA.
990 SmallPtrSet<BasicBlock *, 16> ThrowingBlocks;
991 // Post-order numbers for each basic block. Used to figure out if memory
992 // accesses are executed before another access.
993 DenseMap<BasicBlock *, unsigned> PostOrderNumbers;
994
995 /// Keep track of instructions (partly) overlapping with killing MemoryDefs per
996 /// basic block.
997 MapVector<BasicBlock *, InstOverlapIntervalsTy> IOLs;
998 // Check if there are root nodes that are terminated by UnreachableInst.
999 // Those roots pessimize post-dominance queries. If there are such roots,
1000 // fall back to CFG scan starting from all non-unreachable roots.
1001 bool AnyUnreachableExit;
1002
1003 // Whether or not we should iterate on removing dead stores at the end of the
1004 // function due to removing a store causing a previously captured pointer to
1005 // no longer be captured.
1006 bool ShouldIterateEndOfFunctionDSE;
1007
1008 /// Dead instructions to be removed at the end of DSE.
1009 SmallVector<Instruction *> ToRemove;
1010
1011 // Class contains self-reference, make sure it's not copied/moved.
1012 DSEState(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, DominatorTree &DT,
1013 PostDominatorTree &PDT, const TargetLibraryInfo &TLI,
1014 const CycleInfo &CI);
1015 DSEState(const DSEState &) = delete;
1016 DSEState &operator=(const DSEState &) = delete;
1017
1018 LocationSize strengthenLocationSize(const Instruction *I,
1019 LocationSize Size) const;
1020
1021 /// Return 'OW_Complete' if a store to the 'KillingLoc' location (by \p
1022 /// KillingI instruction) completely overwrites a store to the 'DeadLoc'
1023 /// location (by \p DeadI instruction).
1024 /// Return OW_MaybePartial if \p KillingI does not completely overwrite
1025 /// \p DeadI, but they both write to the same underlying object. In that
1026 /// case, use isPartialOverwrite to check if \p KillingI partially overwrites
1027 /// \p DeadI. Returns 'OR_None' if \p KillingI is known to not overwrite the
1028 /// \p DeadI. Returns 'OW_Unknown' if nothing can be determined.
1029 OverwriteResult isOverwrite(const Instruction *KillingI,
1030 const Instruction *DeadI,
1031 const MemoryLocation &KillingLoc,
1032 const MemoryLocation &DeadLoc,
1033 int64_t &KillingOff, int64_t &DeadOff);
1034
1035 bool isInvisibleToCallerAfterRet(const Value *V, const Value *Ptr,
1036 const LocationSize StoreSize);
1037
1038 bool isInvisibleToCallerOnUnwind(const Value *V);
1039
1040 std::optional<MemoryLocation> getLocForWrite(Instruction *I) const;
1041
1042 // Returns a list of <MemoryLocation, bool> pairs written by I.
1043 // The bool means whether the write is from Initializes attr.
1045 getLocForInst(Instruction *I, bool ConsiderInitializesAttr);
1046
1047 /// Assuming this instruction has a dead analyzable write, can we delete
1048 /// this instruction?
1049 bool isRemovable(Instruction *I);
1050
1051 /// Returns true if \p UseInst completely overwrites \p DefLoc
1052 /// (stored by \p DefInst).
1053 bool isCompleteOverwrite(const MemoryLocation &DefLoc, Instruction *DefInst,
1054 Instruction *UseInst);
1055
1056 /// Returns true if \p Def is not read before returning from the function.
1057 bool isWriteAtEndOfFunction(MemoryDef *Def, const MemoryLocation &DefLoc);
1058
1059 /// If \p I is a memory terminator like llvm.lifetime.end or free, return a
1060 /// pair with the MemoryLocation terminated by \p I and a boolean flag
1061 /// indicating whether \p I is a free-like call.
1062 std::optional<std::pair<MemoryLocation, bool>>
1063 getLocForTerminator(Instruction *I) const;
1064
1065 /// Returns true if \p I is a memory terminator instruction like
1066 /// llvm.lifetime.end or free.
1067 bool isMemTerminatorInst(Instruction *I) const;
1068
1069 /// Returns true if \p MaybeTerm is a memory terminator for \p Loc from
1070 /// instruction \p AccessI.
1071 bool isMemTerminator(const MemoryLocation &Loc, Instruction *AccessI,
1072 Instruction *MaybeTerm);
1073
1074 // Returns true if \p Use may read from \p DefLoc.
1075 bool isReadClobber(const MemoryLocation &DefLoc, Instruction *UseInst);
1076
1077 /// Returns true if a dependency between \p Current and \p KillingDef is
1078 /// guaranteed to be loop invariant for the loops that they are in. Either
1079 /// because they are known to be in the same block, in the same loop level or
1080 /// by guaranteeing that \p CurrentLoc only references a single MemoryLocation
1081 /// during execution of the containing function.
1082 bool isGuaranteedLoopIndependent(const Instruction *Current,
1083 const Instruction *KillingDef,
1084 const MemoryLocation &CurrentLoc);
1085
1086 /// Returns true if \p Ptr is guaranteed to be loop invariant for any possible
1087 /// loop. In particular, this guarantees that it only references a single
1088 /// MemoryLocation during execution of the containing function.
1089 bool isGuaranteedLoopInvariant(const Value *Ptr);
1090
1091 // Find a MemoryDef writing to \p KillingLoc and dominating \p StartAccess,
1092 // with no read access between them or on any other path to a function exit
1093 // block if \p KillingLoc is not accessible after the function returns. If
1094 // there is no such MemoryDef, return std::nullopt. The returned value may not
1095 // (completely) overwrite \p KillingLoc. Currently we bail out when we
1096 // encounter an aliasing MemoryUse (read).
1097 std::optional<MemoryAccess *>
1098 getDomMemoryDef(MemoryDef *KillingDef, MemoryAccess *StartAccess,
1099 const MemoryLocation &KillingLoc, const Value *KillingUndObj,
1100 unsigned &ScanLimit, unsigned &WalkerStepLimit,
1101 bool IsMemTerm, unsigned &PartialLimit,
1102 bool IsInitializesAttrMemLoc);
1103
1104 /// Delete dead memory defs and recursively add their operands to ToRemove if
1105 /// they became dead.
1106 void
1107 deleteDeadInstruction(Instruction *SI,
1108 SmallPtrSetImpl<MemoryAccess *> *Deleted = nullptr);
1109
1110 // Check for any extra throws between \p KillingI and \p DeadI that block
1111 // DSE. This only checks extra maythrows (those that aren't MemoryDef's).
1112 // MemoryDef that may throw are handled during the walk from one def to the
1113 // next.
1114 bool mayThrowBetween(Instruction *KillingI, Instruction *DeadI,
1115 const Value *KillingUndObj);
1116
1117 // Check if \p DeadI acts as a DSE barrier for \p KillingI. The following
1118 // instructions act as barriers:
1119 // * A memory instruction that may throw and \p KillingI accesses a non-stack
1120 // object.
1121 // * Atomic stores stronger that monotonic.
1122 bool isDSEBarrier(const Value *KillingUndObj, Instruction *DeadI);
1123
1124 /// Eliminate writes to objects that are not visible in the caller and are not
1125 /// accessed before returning from the function.
1126 bool eliminateDeadWritesAtEndOfFunction();
1127
1128 /// If we have a zero initializing memset following a call to malloc,
1129 /// try folding it into a call to calloc.
1130 bool tryFoldIntoCalloc(MemoryDef *Def, const Value *DefUO);
1131
1132 /// \returns true if \p Def is a no-op store, either because it
1133 /// directly stores back a loaded value or stores zero to a calloced object.
1134 bool storeIsNoop(MemoryDef *Def, const Value *DefUO);
1135
1136 bool removePartiallyOverlappedStores(InstOverlapIntervalsTy &IOL);
1137
1138 /// Eliminates writes to locations where the value that is being written
1139 /// is already stored at the same location.
1140 bool eliminateRedundantStoresOfExistingValues();
1141
1142 /// If there is a dominating condition that implies the value being stored in
1143 /// a pointer, and such a condition appears in a node that dominates the
1144 /// store, then the store may be redundant if no write occurs in between.
1145 bool eliminateRedundantStoresViaDominatingConditions();
1146
1147 // Return the locations written by the initializes attribute.
1148 // Note that this function considers:
1149 // 1. Unwind edge: use "initializes" attribute only if the callee has
1150 // "nounwind" attribute, or the argument has "dead_on_unwind" attribute,
1151 // or the argument is invisible to caller on unwind. That is, we don't
1152 // perform incorrect DSE on unwind edges in the current function.
1153 // 2. Argument alias: for aliasing arguments, the "initializes" attribute is
1154 // the intersected range list of their "initializes" attributes.
1155 SmallVector<MemoryLocation, 1> getInitializesArgMemLoc(const Instruction *I);
1156
1157 // Try to eliminate dead defs that access `KillingLocWrapper.MemLoc` and are
1158 // killed by `KillingLocWrapper.MemDef`. Return whether
1159 // any changes were made, and whether `KillingLocWrapper.DefInst` was deleted.
1160 std::pair<bool, bool>
1161 eliminateDeadDefs(const MemoryLocationWrapper &KillingLocWrapper);
1162
1163 // Try to eliminate dead defs killed by `KillingDefWrapper` and return the
1164 // change state: whether make any change.
1165 bool eliminateDeadDefs(const MemoryDefWrapper &KillingDefWrapper);
1166};
1167
1168} // end anonymous namespace
1169
1170static void pushMemUses(MemoryAccess *Acc,
1173 for (Use &U : Acc->uses()) {
1174 auto *MA = cast<MemoryAccess>(U.getUser());
1175 if (Visited.insert(MA).second)
1176 WorkList.push_back(MA);
1177 }
1178}
1179
1180// Return true if "Arg" is function local and isn't captured before "CB".
1181static bool isFuncLocalAndNotCaptured(Value *Arg, const CallBase *CB,
1183 const Value *UnderlyingObj = getUnderlyingObject(Arg);
1184 return isIdentifiedFunctionLocal(UnderlyingObj) &&
1185 capturesNothing(EA.getCapturesBefore(UnderlyingObj, CB, /*OrAt=*/true,
1186 /*ReturnCaptures=*/false));
1187}
1188
1189DSEState::DSEState(Function &F, AliasAnalysis &AA, MemorySSA &MSSA,
1191 const TargetLibraryInfo &TLI, const CycleInfo &CI)
1192 : F(F), AA(AA), EA(DT, nullptr, &CI), BatchAA(AA, &EA), MSSA(MSSA), DT(DT),
1193 PDT(PDT), TLI(TLI), DL(F.getDataLayout()), CI(CI) {
1194 // Collect blocks with throwing instructions not modeled in MemorySSA and
1195 // alloc-like objects.
1196 unsigned PO = 0;
1197 for (BasicBlock *BB : post_order(&F)) {
1198 PostOrderNumbers[BB] = PO++;
1199 for (Instruction &I : *BB) {
1200 MemoryAccess *MA = MSSA.getMemoryAccess(&I);
1201 if (I.mayThrow() && !MA)
1202 ThrowingBlocks.insert(I.getParent());
1203
1204 auto *MD = dyn_cast_or_null<MemoryDef>(MA);
1205 if (MD && MemDefs.size() < MemorySSADefsPerBlockLimit &&
1206 (getLocForWrite(&I) || isMemTerminatorInst(&I) ||
1208 MemDefs.push_back(MD);
1209 }
1210 }
1211
1212 // Treat byval, inalloca or dead on return arguments the same as Allocas,
1213 // stores to them are dead at the end of the function.
1214 for (Argument &AI : F.args()) {
1215 if (AI.hasPassPointeeByValueCopyAttr()) {
1216 InvisibleToCallerAfterRet.insert({&AI, true});
1217 continue;
1218 }
1219
1220 if (!AI.getType()->isPointerTy())
1221 continue;
1222
1223 const DeadOnReturnInfo &Info = AI.getDeadOnReturnInfo();
1224 if (Info.coversAllReachableMemory())
1225 InvisibleToCallerAfterRet.insert({&AI, true});
1226 else if (uint64_t DeadBytes = Info.getNumberOfDeadBytes())
1227 InvisibleToCallerAfterRetBounded.insert({&AI, DeadBytes});
1228 }
1229
1230 AnyUnreachableExit = any_of(PDT.roots(), [](const BasicBlock *E) {
1231 return isa<UnreachableInst>(E->getTerminator());
1232 });
1233}
1234
1235LocationSize DSEState::strengthenLocationSize(const Instruction *I,
1236 LocationSize Size) const {
1237 if (auto *CB = dyn_cast<CallBase>(I)) {
1238 LibFunc F;
1239 if (TLI.getLibFunc(*CB, F) && TLI.has(F) &&
1240 (F == LibFunc_memset_chk || F == LibFunc_memcpy_chk)) {
1241 // Use the precise location size specified by the 3rd argument
1242 // for determining KillingI overwrites DeadLoc if it is a memset_chk
1243 // instruction. memset_chk will write either the amount specified as 3rd
1244 // argument or the function will immediately abort and exit the program.
1245 // NOTE: AA may determine NoAlias if it can prove that the access size
1246 // is larger than the allocation size due to that being UB. To avoid
1247 // returning potentially invalid NoAlias results by AA, limit the use of
1248 // the precise location size to isOverwrite.
1249 if (const auto *Len = dyn_cast<ConstantInt>(CB->getArgOperand(2)))
1250 return LocationSize::precise(Len->getZExtValue());
1251 }
1252 }
1253 return Size;
1254}
1255
1256OverwriteResult DSEState::isOverwrite(const Instruction *KillingI,
1257 const Instruction *DeadI,
1258 const MemoryLocation &KillingLoc,
1259 const MemoryLocation &DeadLoc,
1260 int64_t &KillingOff, int64_t &DeadOff) {
1261 // AliasAnalysis does not always account for loops. Limit overwrite checks
1262 // to dependencies for which we can guarantee they are independent of any
1263 // loops they are in.
1264 if (!isGuaranteedLoopIndependent(DeadI, KillingI, DeadLoc))
1265 return OW_Unknown;
1266
1267 LocationSize KillingLocSize =
1268 strengthenLocationSize(KillingI, KillingLoc.Size);
1269 const Value *DeadPtr = DeadLoc.Ptr->stripPointerCasts();
1270 const Value *KillingPtr = KillingLoc.Ptr->stripPointerCasts();
1271 const Value *DeadUndObj = getUnderlyingObject(DeadPtr);
1272 const Value *KillingUndObj = getUnderlyingObject(KillingPtr);
1273
1274 // Check whether the killing store overwrites the whole object, in which
1275 // case the size/offset of the dead store does not matter.
1276 if (DeadUndObj == KillingUndObj && KillingLocSize.isPrecise() &&
1277 isIdentifiedObject(KillingUndObj)) {
1278 std::optional<TypeSize> KillingUndObjSize =
1279 getPointerSize(KillingUndObj, DL, TLI, &F);
1280 if (KillingUndObjSize && *KillingUndObjSize == KillingLocSize.getValue())
1281 return OW_Complete;
1282 }
1283
1284 // FIXME: Vet that this works for size upper-bounds. Seems unlikely that we'll
1285 // get imprecise values here, though (except for unknown sizes).
1286 if (!KillingLocSize.isPrecise() || !DeadLoc.Size.isPrecise()) {
1287 // In case no constant size is known, try to an IR values for the number
1288 // of bytes written and check if they match.
1289 const auto *KillingMemI = dyn_cast<MemIntrinsic>(KillingI);
1290 const auto *DeadMemI = dyn_cast<MemIntrinsic>(DeadI);
1291 if (KillingMemI && DeadMemI) {
1292 const Value *KillingV = KillingMemI->getLength();
1293 const Value *DeadV = DeadMemI->getLength();
1294 if (KillingV == DeadV && BatchAA.isMustAlias(DeadLoc, KillingLoc))
1295 return OW_Complete;
1296 }
1297
1298 // Masked stores have imprecise locations, but we can reason about them
1299 // to some extent.
1300 return isMaskedStoreOverwrite(KillingI, DeadI, BatchAA);
1301 }
1302
1303 const TypeSize KillingSize = KillingLocSize.getValue();
1304 const TypeSize DeadSize = DeadLoc.Size.getValue();
1305 // Bail on doing Size comparison which depends on AA for now
1306 // TODO: Remove AnyScalable once Alias Analysis deal with scalable vectors
1307 const bool AnyScalable = DeadSize.isScalable() || KillingLocSize.isScalable();
1308
1309 if (AnyScalable)
1310 return OW_Unknown;
1311 // Query the alias information
1312 AliasResult AAR = BatchAA.alias(KillingLoc, DeadLoc);
1313
1314 // If the start pointers are the same, we just have to compare sizes to see if
1315 // the killing store was larger than the dead store.
1316 if (AAR == AliasResult::MustAlias) {
1317 // Make sure that the KillingSize size is >= the DeadSize size.
1318 if (KillingSize >= DeadSize)
1319 return OW_Complete;
1320 }
1321
1322 // If we hit a partial alias we may have a full overwrite
1323 if (AAR == AliasResult::PartialAlias && AAR.hasOffset()) {
1324 int32_t Off = AAR.getOffset();
1325 if (Off >= 0 && (uint64_t)Off + DeadSize <= KillingSize)
1326 return OW_Complete;
1327 }
1328
1329 // If we can't resolve the same pointers to the same object, then we can't
1330 // analyze them at all.
1331 if (DeadUndObj != KillingUndObj) {
1332 // Non aliasing stores to different objects don't overlap. Note that
1333 // if the killing store is known to overwrite whole object (out of
1334 // bounds access overwrites whole object as well) then it is assumed to
1335 // completely overwrite any store to the same object even if they don't
1336 // actually alias (see next check).
1337 if (AAR == AliasResult::NoAlias)
1338 return OW_None;
1339 return OW_Unknown;
1340 }
1341
1342 // Okay, we have stores to two completely different pointers. Try to
1343 // decompose the pointer into a "base + constant_offset" form. If the base
1344 // pointers are equal, then we can reason about the two stores.
1345 DeadOff = 0;
1346 KillingOff = 0;
1347 const Value *DeadBasePtr =
1348 GetPointerBaseWithConstantOffset(DeadPtr, DeadOff, DL);
1349 const Value *KillingBasePtr =
1350 GetPointerBaseWithConstantOffset(KillingPtr, KillingOff, DL);
1351
1352 // If the base pointers still differ, we have two completely different
1353 // stores.
1354 if (DeadBasePtr != KillingBasePtr)
1355 return OW_Unknown;
1356
1357 // The killing access completely overlaps the dead store if and only if
1358 // both start and end of the dead one is "inside" the killing one:
1359 // |<->|--dead--|<->|
1360 // |-----killing------|
1361 // Accesses may overlap if and only if start of one of them is "inside"
1362 // another one:
1363 // |<->|--dead--|<-------->|
1364 // |-------killing--------|
1365 // OR
1366 // |-------dead-------|
1367 // |<->|---killing---|<----->|
1368 //
1369 // We have to be careful here as *Off is signed while *.Size is unsigned.
1370
1371 // Check if the dead access starts "not before" the killing one.
1372 if (DeadOff >= KillingOff) {
1373 // If the dead access ends "not after" the killing access then the
1374 // dead one is completely overwritten by the killing one.
1375 if (uint64_t(DeadOff - KillingOff) + DeadSize <= KillingSize)
1376 return OW_Complete;
1377 // If start of the dead access is "before" end of the killing access
1378 // then accesses overlap.
1379 else if ((uint64_t)(DeadOff - KillingOff) < KillingSize)
1380 return OW_MaybePartial;
1381 }
1382 // If start of the killing access is "before" end of the dead access then
1383 // accesses overlap.
1384 else if ((uint64_t)(KillingOff - DeadOff) < DeadSize) {
1385 return OW_MaybePartial;
1386 }
1387
1388 // Can reach here only if accesses are known not to overlap.
1389 return OW_None;
1390}
1391
1392bool DSEState::isInvisibleToCallerAfterRet(const Value *V, const Value *Ptr,
1393 const LocationSize StoreSize) {
1394 if (isa<AllocaInst>(V))
1395 return true;
1396
1397 auto IBounded = InvisibleToCallerAfterRetBounded.find(V);
1398 if (IBounded != InvisibleToCallerAfterRetBounded.end()) {
1399 int64_t ValueOffset;
1400 [[maybe_unused]] const Value *BaseValue =
1401 GetPointerBaseWithConstantOffset(Ptr, ValueOffset, DL);
1402 // If we are not able to find a constant offset from the UO, we have to
1403 // pessimistically assume that the store writes to memory out of the
1404 // dead_on_return bounds.
1405 if (BaseValue != V)
1406 return false;
1407 // This store is only invisible after return if we are in bounds of the
1408 // range marked dead.
1409 if (StoreSize.hasValue() &&
1410 ValueOffset + StoreSize.getValue() <= IBounded->second &&
1411 ValueOffset >= 0)
1412 return true;
1413 }
1414 auto I = InvisibleToCallerAfterRet.insert({V, false});
1415 if (I.second && isInvisibleToCallerOnUnwind(V) && isNoAliasCall(V))
1416 I.first->second = capturesNothing(
1417 PointerMayBeCaptured(V, CaptureComponents::Provenance).WithRet);
1418 return I.first->second;
1419}
1420
1421bool DSEState::isInvisibleToCallerOnUnwind(const Value *V) {
1422 bool RequiresNoCaptureBeforeUnwind;
1423 if (!isNotVisibleOnUnwind(V, RequiresNoCaptureBeforeUnwind))
1424 return false;
1425 if (!RequiresNoCaptureBeforeUnwind)
1426 return true;
1427
1428 auto I = CapturedBeforeReturn.insert({V, true});
1429 if (I.second)
1430 // NOTE: This could be made more precise by PointerMayBeCapturedBefore
1431 // with the killing MemoryDef. But we refrain from doing so for now to
1432 // limit compile-time and this does not cause any changes to the number
1433 // of stores removed on a large test set in practice.
1434 I.first->second = capturesAnything(
1435 PointerMayBeCaptured(V, CaptureComponents::Provenance).WithoutRet);
1436 return !I.first->second;
1437}
1438
1439std::optional<MemoryLocation> DSEState::getLocForWrite(Instruction *I) const {
1440 if (!I->mayWriteToMemory())
1441 return std::nullopt;
1442
1443 if (auto *CB = dyn_cast<CallBase>(I))
1444 return MemoryLocation::getForDest(CB, TLI);
1445
1447}
1448
1450DSEState::getLocForInst(Instruction *I, bool ConsiderInitializesAttr) {
1452 if (isMemTerminatorInst(I)) {
1453 if (auto Loc = getLocForTerminator(I))
1454 Locations.push_back(std::make_pair(Loc->first, false));
1455 return Locations;
1456 }
1457
1458 if (auto Loc = getLocForWrite(I))
1459 Locations.push_back(std::make_pair(*Loc, false));
1460
1461 if (ConsiderInitializesAttr) {
1462 for (auto &MemLoc : getInitializesArgMemLoc(I)) {
1463 Locations.push_back(std::make_pair(MemLoc, true));
1464 }
1465 }
1466 return Locations;
1467}
1468
1469bool DSEState::isRemovable(Instruction *I) {
1470 assert(getLocForWrite(I) && "Must have analyzable write");
1471
1472 // Don't remove volatile/atomic stores.
1473 if (StoreInst *SI = dyn_cast<StoreInst>(I))
1474 return SI->isUnordered();
1475
1476 if (auto *CB = dyn_cast<CallBase>(I)) {
1477 // Don't remove volatile memory intrinsics.
1478 if (auto *MI = dyn_cast<MemIntrinsic>(CB))
1479 return !MI->isVolatile();
1480
1481 // Never remove dead lifetime intrinsics, e.g. because they are followed
1482 // by a free.
1483 if (CB->isLifetimeStartOrEnd())
1484 return false;
1485
1486 return CB->use_empty() && CB->willReturn() && CB->doesNotThrow() &&
1487 !CB->isTerminator();
1488 }
1489
1490 return false;
1491}
1492
1493bool DSEState::isCompleteOverwrite(const MemoryLocation &DefLoc,
1494 Instruction *DefInst, Instruction *UseInst) {
1495 // UseInst has a MemoryDef associated in MemorySSA. It's possible for a
1496 // MemoryDef to not write to memory, e.g. a volatile load is modeled as a
1497 // MemoryDef.
1498 if (!UseInst->mayWriteToMemory())
1499 return false;
1500
1501 if (auto *CB = dyn_cast<CallBase>(UseInst))
1502 if (CB->onlyAccessesInaccessibleMemory())
1503 return false;
1504
1505 int64_t InstWriteOffset, DepWriteOffset;
1506 if (auto CC = getLocForWrite(UseInst))
1507 return isOverwrite(UseInst, DefInst, *CC, DefLoc, InstWriteOffset,
1508 DepWriteOffset) == OW_Complete;
1509 return false;
1510}
1511
1512bool DSEState::isWriteAtEndOfFunction(MemoryDef *Def,
1513 const MemoryLocation &DefLoc) {
1514 LLVM_DEBUG(dbgs() << " Check if def " << *Def << " ("
1515 << *Def->getMemoryInst()
1516 << ") is at the end the function \n");
1518 SmallPtrSet<MemoryAccess *, 8> Visited;
1519
1520 pushMemUses(Def, WorkList, Visited);
1521 for (unsigned I = 0; I < WorkList.size(); I++) {
1522 if (WorkList.size() >= MemorySSAScanLimit) {
1523 LLVM_DEBUG(dbgs() << " ... hit exploration limit.\n");
1524 return false;
1525 }
1526
1527 MemoryAccess *UseAccess = WorkList[I];
1528 if (isa<MemoryPhi>(UseAccess)) {
1529 // AliasAnalysis does not account for loops. Limit elimination to
1530 // candidates for which we can guarantee they always store to the same
1531 // memory location.
1532 if (!isGuaranteedLoopInvariant(DefLoc.Ptr))
1533 return false;
1534
1535 pushMemUses(cast<MemoryPhi>(UseAccess), WorkList, Visited);
1536 continue;
1537 }
1538 // TODO: Checking for aliasing is expensive. Consider reducing the amount
1539 // of times this is called and/or caching it.
1540 Instruction *UseInst = cast<MemoryUseOrDef>(UseAccess)->getMemoryInst();
1541 if (isReadClobber(DefLoc, UseInst)) {
1542 LLVM_DEBUG(dbgs() << " ... hit read clobber " << *UseInst << ".\n");
1543 return false;
1544 }
1545
1546 if (MemoryDef *UseDef = dyn_cast<MemoryDef>(UseAccess))
1547 pushMemUses(UseDef, WorkList, Visited);
1548 }
1549 return true;
1550}
1551
1552std::optional<std::pair<MemoryLocation, bool>>
1553DSEState::getLocForTerminator(Instruction *I) const {
1554 if (auto *CB = dyn_cast<CallBase>(I)) {
1555 if (CB->getIntrinsicID() == Intrinsic::lifetime_end)
1556 return {
1557 std::make_pair(MemoryLocation::getForArgument(CB, 0, &TLI), false)};
1558 if (Value *FreedOp = getFreedOperand(CB, &TLI))
1559 return {std::make_pair(MemoryLocation::getAfter(FreedOp), true)};
1560 }
1561
1562 return std::nullopt;
1563}
1564
1565bool DSEState::isMemTerminatorInst(Instruction *I) const {
1566 auto *CB = dyn_cast<CallBase>(I);
1567 return CB && (CB->getIntrinsicID() == Intrinsic::lifetime_end ||
1568 getFreedOperand(CB, &TLI) != nullptr);
1569}
1570
1571bool DSEState::isMemTerminator(const MemoryLocation &Loc, Instruction *AccessI,
1572 Instruction *MaybeTerm) {
1573 std::optional<std::pair<MemoryLocation, bool>> MaybeTermLoc =
1574 getLocForTerminator(MaybeTerm);
1575
1576 if (!MaybeTermLoc)
1577 return false;
1578
1579 // If the terminator is a free-like call, all accesses to the underlying
1580 // object can be considered terminated.
1581 if (getUnderlyingObject(Loc.Ptr) !=
1582 getUnderlyingObject(MaybeTermLoc->first.Ptr))
1583 return false;
1584
1585 auto TermLoc = MaybeTermLoc->first;
1586 if (MaybeTermLoc->second) {
1587 const Value *LocUO = getUnderlyingObject(Loc.Ptr);
1588 return BatchAA.isMustAlias(TermLoc.Ptr, LocUO);
1589 }
1590 int64_t InstWriteOffset = 0;
1591 int64_t DepWriteOffset = 0;
1592 return isOverwrite(MaybeTerm, AccessI, TermLoc, Loc, InstWriteOffset,
1593 DepWriteOffset) == OW_Complete;
1594}
1595
1596bool DSEState::isReadClobber(const MemoryLocation &DefLoc,
1597 Instruction *UseInst) {
1598 if (isNoopIntrinsic(UseInst))
1599 return false;
1600
1601 // Monotonic or weaker atomic stores can be re-ordered and do not need to be
1602 // treated as read clobber.
1603 if (auto SI = dyn_cast<StoreInst>(UseInst))
1604 return isStrongerThan(SI->getOrdering(), AtomicOrdering::Monotonic);
1605
1606 if (!UseInst->mayReadFromMemory())
1607 return false;
1608
1609 if (auto *CB = dyn_cast<CallBase>(UseInst))
1610 if (CB->onlyAccessesInaccessibleMemory())
1611 return false;
1612
1613 return isRefSet(BatchAA.getModRefInfo(UseInst, DefLoc));
1614}
1615
1616bool DSEState::isGuaranteedLoopIndependent(const Instruction *Current,
1617 const Instruction *KillingDef,
1618 const MemoryLocation &CurrentLoc) {
1619 // If the dependency is within the same block or loop level (being careful
1620 // of irreducible loops), we know that AA will return a valid result for the
1621 // memory dependency. (Both at the function level, outside of any loop,
1622 // would also be valid but we currently disable that to limit compile time).
1623 if (Current->getParent() == KillingDef->getParent())
1624 return true;
1625 CycleRef CurrentC = CI.getCycle(Current->getParent());
1626 if (CurrentC && CurrentC == CI.getCycle(KillingDef->getParent()))
1627 return true;
1628 // Otherwise check the memory location is invariant to any loops.
1629 return isGuaranteedLoopInvariant(CurrentLoc.Ptr);
1630}
1631
1632bool DSEState::isGuaranteedLoopInvariant(const Value *Ptr) {
1633 Ptr = Ptr->stripPointerCasts();
1634 if (auto *GEP = dyn_cast<GEPOperator>(Ptr))
1635 if (GEP->hasAllConstantIndices())
1636 Ptr = GEP->getPointerOperand()->stripPointerCasts();
1637
1638 if (auto *I = dyn_cast<Instruction>(Ptr)) {
1639 return I->getParent()->isEntryBlock() || !CI.getCycle(I->getParent());
1640 }
1641 return true;
1642}
1643
1644std::optional<MemoryAccess *> DSEState::getDomMemoryDef(
1645 MemoryDef *KillingDef, MemoryAccess *StartAccess,
1646 const MemoryLocation &KillingLoc, const Value *KillingUndObj,
1647 unsigned &ScanLimit, unsigned &WalkerStepLimit, bool IsMemTerm,
1648 unsigned &PartialLimit, bool IsInitializesAttrMemLoc) {
1649 if (ScanLimit == 0 || WalkerStepLimit == 0) {
1650 LLVM_DEBUG(dbgs() << "\n ... hit scan limit\n");
1651 return std::nullopt;
1652 }
1653
1654 MemoryAccess *Current = StartAccess;
1655 Instruction *KillingI = KillingDef->getMemoryInst();
1656 LLVM_DEBUG(dbgs() << " trying to get dominating access\n");
1657
1658 // Only optimize defining access of KillingDef when directly starting at its
1659 // defining access. The defining access also must only access KillingLoc. At
1660 // the moment we only support instructions with a single write location, so
1661 // it should be sufficient to disable optimizations for instructions that
1662 // also read from memory.
1663 bool CanOptimize = OptimizeMemorySSA &&
1664 KillingDef->getDefiningAccess() == StartAccess &&
1665 !KillingI->mayReadFromMemory();
1666
1667 // Find the next clobbering Mod access for DefLoc, starting at StartAccess.
1668 std::optional<MemoryLocation> CurrentLoc;
1669 for (;; Current = cast<MemoryDef>(Current)->getDefiningAccess()) {
1670 LLVM_DEBUG({
1671 dbgs() << " visiting " << *Current;
1672 if (!MSSA.isLiveOnEntryDef(Current) && isa<MemoryUseOrDef>(Current))
1673 dbgs() << " (" << *cast<MemoryUseOrDef>(Current)->getMemoryInst()
1674 << ")";
1675 dbgs() << "\n";
1676 });
1677
1678 // Reached TOP.
1679 if (MSSA.isLiveOnEntryDef(Current)) {
1680 LLVM_DEBUG(dbgs() << " ... found LiveOnEntryDef\n");
1681 if (CanOptimize && Current != KillingDef->getDefiningAccess())
1682 // The first clobbering def is... none.
1683 KillingDef->setOptimized(Current);
1684 return std::nullopt;
1685 }
1686
1687 // Cost of a step. Accesses in the same block are more likely to be valid
1688 // candidates for elimination, hence consider them cheaper.
1689 unsigned StepCost = KillingDef->getBlock() == Current->getBlock()
1692 if (WalkerStepLimit <= StepCost) {
1693 LLVM_DEBUG(dbgs() << " ... hit walker step limit\n");
1694 return std::nullopt;
1695 }
1696 WalkerStepLimit -= StepCost;
1697
1698 // Return for MemoryPhis. They cannot be eliminated directly and the
1699 // caller is responsible for traversing them.
1700 if (isa<MemoryPhi>(Current)) {
1701 LLVM_DEBUG(dbgs() << " ... found MemoryPhi\n");
1702 return Current;
1703 }
1704
1705 // Below, check if CurrentDef is a valid candidate to be eliminated by
1706 // KillingDef. If it is not, check the next candidate.
1707 MemoryDef *CurrentDef = cast<MemoryDef>(Current);
1708 Instruction *CurrentI = CurrentDef->getMemoryInst();
1709
1710 if (canSkipDef(CurrentDef, !isInvisibleToCallerOnUnwind(KillingUndObj))) {
1711 CanOptimize = false;
1712 continue;
1713 }
1714
1715 // Before we try to remove anything, check for any extra throwing
1716 // instructions that block us from DSEing
1717 if (mayThrowBetween(KillingI, CurrentI, KillingUndObj)) {
1718 LLVM_DEBUG(dbgs() << " ... skip, may throw!\n");
1719 return std::nullopt;
1720 }
1721
1722 // Check for anything that looks like it will be a barrier to further
1723 // removal
1724 if (isDSEBarrier(KillingUndObj, CurrentI)) {
1725 LLVM_DEBUG(dbgs() << " ... skip, barrier\n");
1726 return std::nullopt;
1727 }
1728
1729 // If Current is known to be on path that reads DefLoc or is a read
1730 // clobber, bail out, as the path is not profitable. We skip this check
1731 // for intrinsic calls, because the code knows how to handle memcpy
1732 // intrinsics.
1733 if (!isa<IntrinsicInst>(CurrentI) && isReadClobber(KillingLoc, CurrentI))
1734 return std::nullopt;
1735
1736 // Quick check if there are direct uses that are read-clobbers.
1737 if (any_of(Current->uses(), [this, &KillingLoc, StartAccess](Use &U) {
1738 if (auto *UseOrDef = dyn_cast<MemoryUseOrDef>(U.getUser()))
1739 return !MSSA.dominates(StartAccess, UseOrDef) &&
1740 isReadClobber(KillingLoc, UseOrDef->getMemoryInst());
1741 return false;
1742 })) {
1743 LLVM_DEBUG(dbgs() << " ... found a read clobber\n");
1744 return std::nullopt;
1745 }
1746
1747 // If Current does not have an analyzable write location or is not
1748 // removable, skip it.
1749 CurrentLoc = getLocForWrite(CurrentI);
1750 if (!CurrentLoc || !isRemovable(CurrentI)) {
1751 CanOptimize = false;
1752 continue;
1753 }
1754
1755 // AliasAnalysis does not account for loops. Limit elimination to
1756 // candidates for which we can guarantee they always store to the same
1757 // memory location and not located in different loops.
1758 if (!isGuaranteedLoopIndependent(CurrentI, KillingI, *CurrentLoc)) {
1759 LLVM_DEBUG(dbgs() << " ... not guaranteed loop independent\n");
1760 CanOptimize = false;
1761 continue;
1762 }
1763
1764 if (IsMemTerm) {
1765 // If the killing def is a memory terminator (e.g. lifetime.end), check
1766 // the next candidate if the current Current does not write the same
1767 // underlying object as the terminator.
1768 if (!isMemTerminator(*CurrentLoc, CurrentI, KillingI)) {
1769 CanOptimize = false;
1770 continue;
1771 }
1772 } else {
1773 int64_t KillingOffset = 0;
1774 int64_t DeadOffset = 0;
1775 auto OR = isOverwrite(KillingI, CurrentI, KillingLoc, *CurrentLoc,
1776 KillingOffset, DeadOffset);
1777 if (CanOptimize) {
1778 // CurrentDef is the earliest write clobber of KillingDef. Use it as
1779 // optimized access. Do not optimize if CurrentDef is already the
1780 // defining access of KillingDef.
1781 if (CurrentDef != KillingDef->getDefiningAccess() &&
1782 (OR == OW_Complete || OR == OW_MaybePartial))
1783 KillingDef->setOptimized(CurrentDef);
1784
1785 // Once a may-aliasing def is encountered do not set an optimized
1786 // access.
1787 if (OR != OW_None)
1788 CanOptimize = false;
1789 }
1790
1791 // If Current does not write to the same object as KillingDef, check
1792 // the next candidate.
1793 if (OR == OW_Unknown || OR == OW_None)
1794 continue;
1795 else if (OR == OW_MaybePartial) {
1796 // If KillingDef only partially overwrites Current, check the next
1797 // candidate if the partial step limit is exceeded. This aggressively
1798 // limits the number of candidates for partial store elimination,
1799 // which are less likely to be removable in the end.
1800 if (PartialLimit <= 1) {
1801 WalkerStepLimit -= 1;
1802 LLVM_DEBUG(dbgs() << " ... reached partial limit ... continue with "
1803 "next access\n");
1804 continue;
1805 }
1806 PartialLimit -= 1;
1807 }
1808 }
1809 break;
1810 };
1811
1812 // Accesses to objects accessible after the function returns can only be
1813 // eliminated if the access is dead along all paths to the exit. Collect
1814 // the blocks with killing (=completely overwriting MemoryDefs) and check if
1815 // they cover all paths from MaybeDeadAccess to any function exit.
1816 SmallPtrSet<Instruction *, 16> KillingDefs;
1817 KillingDefs.insert(KillingDef->getMemoryInst());
1818 MemoryAccess *MaybeDeadAccess = Current;
1819 MemoryLocation MaybeDeadLoc = *CurrentLoc;
1820 Instruction *MaybeDeadI = cast<MemoryDef>(MaybeDeadAccess)->getMemoryInst();
1821 LLVM_DEBUG(dbgs() << " Checking for reads of " << *MaybeDeadAccess << " ("
1822 << *MaybeDeadI << ")\n");
1823
1825 SmallPtrSet<MemoryAccess *, 32> Visited;
1826 pushMemUses(MaybeDeadAccess, WorkList, Visited);
1827
1828 // Check if DeadDef may be read.
1829 for (unsigned I = 0; I < WorkList.size(); I++) {
1830 MemoryAccess *UseAccess = WorkList[I];
1831
1832 LLVM_DEBUG(dbgs() << " " << *UseAccess);
1833 // Bail out if the number of accesses to check exceeds the scan limit.
1834 if (ScanLimit < (WorkList.size() - I)) {
1835 LLVM_DEBUG(dbgs() << "\n ... hit scan limit\n");
1836 return std::nullopt;
1837 }
1838 --ScanLimit;
1839 NumDomMemDefChecks++;
1840
1841 if (isa<MemoryPhi>(UseAccess)) {
1842 if (any_of(KillingDefs, [this, UseAccess](Instruction *KI) {
1843 return DT.properlyDominates(KI->getParent(), UseAccess->getBlock());
1844 })) {
1845 LLVM_DEBUG(dbgs() << " ... skipping, dominated by killing block\n");
1846 continue;
1847 }
1848 LLVM_DEBUG(dbgs() << "\n ... adding PHI uses\n");
1849 pushMemUses(UseAccess, WorkList, Visited);
1850 continue;
1851 }
1852
1853 Instruction *UseInst = cast<MemoryUseOrDef>(UseAccess)->getMemoryInst();
1854 LLVM_DEBUG(dbgs() << " (" << *UseInst << ")\n");
1855
1856 if (any_of(KillingDefs, [this, UseInst](Instruction *KI) {
1857 return DT.dominates(KI, UseInst);
1858 })) {
1859 LLVM_DEBUG(dbgs() << " ... skipping, dominated by killing def\n");
1860 continue;
1861 }
1862
1863 // A memory terminator kills all preceeding MemoryDefs and all succeeding
1864 // MemoryAccesses. We do not have to check it's users.
1865 if (isMemTerminator(MaybeDeadLoc, MaybeDeadI, UseInst)) {
1866 LLVM_DEBUG(
1867 dbgs()
1868 << " ... skipping, memterminator invalidates following accesses\n");
1869 continue;
1870 }
1871
1872 if (isNoopIntrinsic(cast<MemoryUseOrDef>(UseAccess)->getMemoryInst())) {
1873 LLVM_DEBUG(dbgs() << " ... adding uses of intrinsic\n");
1874 pushMemUses(UseAccess, WorkList, Visited);
1875 continue;
1876 }
1877
1878 if (UseInst->mayThrow() && !isInvisibleToCallerOnUnwind(KillingUndObj)) {
1879 LLVM_DEBUG(dbgs() << " ... found throwing instruction\n");
1880 return std::nullopt;
1881 }
1882
1883 // Uses which may read the original MemoryDef mean we cannot eliminate the
1884 // original MD. Stop walk.
1885 // If KillingDef is a CallInst with "initializes" attribute, the reads in
1886 // the callee would be dominated by initializations, so it should be safe.
1887 bool IsKillingDefFromInitAttr = false;
1888 if (IsInitializesAttrMemLoc) {
1889 if (KillingI == UseInst &&
1890 KillingUndObj == getUnderlyingObject(MaybeDeadLoc.Ptr))
1891 IsKillingDefFromInitAttr = true;
1892 }
1893
1894 if (isReadClobber(MaybeDeadLoc, UseInst) && !IsKillingDefFromInitAttr) {
1895 LLVM_DEBUG(dbgs() << " ... found read clobber\n");
1896 return std::nullopt;
1897 }
1898
1899 // If this worklist walks back to the original memory access (and the
1900 // pointer is not guarenteed loop invariant) then we cannot assume that a
1901 // store kills itself.
1902 if (MaybeDeadAccess == UseAccess &&
1903 !isGuaranteedLoopInvariant(MaybeDeadLoc.Ptr)) {
1904 LLVM_DEBUG(dbgs() << " ... found not loop invariant self access\n");
1905 return std::nullopt;
1906 }
1907 // Otherwise, for the KillingDef and MaybeDeadAccess we only have to check
1908 // if it reads the memory location.
1909 // TODO: It would probably be better to check for self-reads before
1910 // calling the function.
1911 if (KillingDef == UseAccess || MaybeDeadAccess == UseAccess) {
1912 LLVM_DEBUG(dbgs() << " ... skipping killing def/dom access\n");
1913 continue;
1914 }
1915
1916 // Check all uses for MemoryDefs, except for defs completely overwriting
1917 // the original location. Otherwise we have to check uses of *all*
1918 // MemoryDefs we discover, including non-aliasing ones. Otherwise we might
1919 // miss cases like the following
1920 // 1 = Def(LoE) ; <----- DeadDef stores [0,1]
1921 // 2 = Def(1) ; (2, 1) = NoAlias, stores [2,3]
1922 // Use(2) ; MayAlias 2 *and* 1, loads [0, 3].
1923 // (The Use points to the *first* Def it may alias)
1924 // 3 = Def(1) ; <---- Current (3, 2) = NoAlias, (3,1) = MayAlias,
1925 // stores [0,1]
1926 if (MemoryDef *UseDef = dyn_cast<MemoryDef>(UseAccess)) {
1927 if (isCompleteOverwrite(MaybeDeadLoc, MaybeDeadI, UseInst)) {
1928 BasicBlock *MaybeKillingBlock = UseInst->getParent();
1929 if (PostOrderNumbers.find(MaybeKillingBlock)->second <
1930 PostOrderNumbers.find(MaybeDeadAccess->getBlock())->second) {
1931 if (!isInvisibleToCallerAfterRet(KillingUndObj, KillingLoc.Ptr,
1932 KillingLoc.Size)) {
1934 << " ... found killing def " << *UseInst << "\n");
1935 KillingDefs.insert(UseInst);
1936 }
1937 } else {
1939 << " ... found preceeding def " << *UseInst << "\n");
1940 return std::nullopt;
1941 }
1942 } else
1943 pushMemUses(UseDef, WorkList, Visited);
1944 }
1945 }
1946
1947 // For accesses to locations visible after the function returns, make sure
1948 // that the location is dead (=overwritten) along all paths from
1949 // MaybeDeadAccess to the exit.
1950 if (!isInvisibleToCallerAfterRet(KillingUndObj, KillingLoc.Ptr,
1951 KillingLoc.Size)) {
1952 SmallPtrSet<BasicBlock *, 16> KillingBlocks;
1953 for (Instruction *KD : KillingDefs)
1954 KillingBlocks.insert(KD->getParent());
1955 assert(!KillingBlocks.empty() &&
1956 "Expected at least a single killing block");
1957
1958 // Find the common post-dominator of all killing blocks.
1959 BasicBlock *CommonPred = *KillingBlocks.begin();
1960 for (BasicBlock *BB : llvm::drop_begin(KillingBlocks)) {
1961 if (!CommonPred)
1962 break;
1963 CommonPred = PDT.findNearestCommonDominator(CommonPred, BB);
1964 }
1965
1966 // If the common post-dominator does not post-dominate MaybeDeadAccess,
1967 // there is a path from MaybeDeadAccess to an exit not going through a
1968 // killing block.
1969 if (!PDT.dominates(CommonPred, MaybeDeadAccess->getBlock())) {
1970 if (!AnyUnreachableExit)
1971 return std::nullopt;
1972
1973 // Fall back to CFG scan starting at all non-unreachable roots if not
1974 // all paths to the exit go through CommonPred.
1975 CommonPred = nullptr;
1976 }
1977
1978 // If CommonPred itself is in the set of killing blocks, we're done.
1979 if (KillingBlocks.count(CommonPred))
1980 return {MaybeDeadAccess};
1981
1982 SetVector<BasicBlock *> WorkList;
1983 // If CommonPred is null, there are multiple exits from the function.
1984 // They all have to be added to the worklist.
1985 if (CommonPred)
1986 WorkList.insert(CommonPred);
1987 else
1988 for (BasicBlock *R : PDT.roots()) {
1989 if (!isa<UnreachableInst>(R->getTerminator()))
1990 WorkList.insert(R);
1991 }
1992
1993 NumCFGTries++;
1994 // Check if all paths starting from an exit node go through one of the
1995 // killing blocks before reaching MaybeDeadAccess.
1996 for (unsigned I = 0; I < WorkList.size(); I++) {
1997 NumCFGChecks++;
1998 BasicBlock *Current = WorkList[I];
1999 if (KillingBlocks.count(Current))
2000 continue;
2001 if (Current == MaybeDeadAccess->getBlock())
2002 return std::nullopt;
2003
2004 // MaybeDeadAccess is reachable from the entry, so we don't have to
2005 // explore unreachable blocks further.
2006 if (!DT.isReachableFromEntry(Current))
2007 continue;
2008
2009 WorkList.insert_range(predecessors(Current));
2010
2011 if (WorkList.size() >= MemorySSAPathCheckLimit)
2012 return std::nullopt;
2013 }
2014 NumCFGSuccess++;
2015 }
2016
2017 // No aliasing MemoryUses of MaybeDeadAccess found, MaybeDeadAccess is
2018 // potentially dead.
2019 return {MaybeDeadAccess};
2020}
2021
2022void DSEState::deleteDeadInstruction(Instruction *SI,
2023 SmallPtrSetImpl<MemoryAccess *> *Deleted) {
2024 MemorySSAUpdater Updater(&MSSA);
2025 SmallVector<Instruction *, 32> NowDeadInsts;
2026 NowDeadInsts.push_back(SI);
2027 --NumFastOther;
2028
2029 while (!NowDeadInsts.empty()) {
2030 Instruction *DeadInst = NowDeadInsts.pop_back_val();
2031 ++NumFastOther;
2032
2033 // Try to preserve debug information attached to the dead instruction.
2034 salvageDebugInfo(*DeadInst);
2035 salvageKnowledge(DeadInst);
2036
2037 // Remove the Instruction from MSSA.
2038 MemoryAccess *MA = MSSA.getMemoryAccess(DeadInst);
2039 bool IsMemDef = MA && isa<MemoryDef>(MA);
2040 if (MA) {
2041 if (IsMemDef) {
2042 auto *MD = cast<MemoryDef>(MA);
2043 SkipStores.insert(MD);
2044 if (Deleted)
2045 Deleted->insert(MD);
2046 if (auto *SI = dyn_cast<StoreInst>(MD->getMemoryInst())) {
2047 if (SI->getValueOperand()->getType()->isPointerTy()) {
2048 const Value *UO = getUnderlyingObject(SI->getValueOperand());
2049 if (CapturedBeforeReturn.erase(UO))
2050 ShouldIterateEndOfFunctionDSE = true;
2051 InvisibleToCallerAfterRet.erase(UO);
2052 InvisibleToCallerAfterRetBounded.erase(UO);
2053 }
2054 }
2055 }
2056
2057 Updater.removeMemoryAccess(MA);
2058 }
2059
2060 auto I = IOLs.find(DeadInst->getParent());
2061 if (I != IOLs.end())
2062 I->second.erase(DeadInst);
2063 // Remove its operands
2064 for (Use &O : DeadInst->operands())
2065 if (Instruction *OpI = dyn_cast<Instruction>(O)) {
2066 O.set(PoisonValue::get(O->getType()));
2067 if (isInstructionTriviallyDead(OpI, &TLI))
2068 NowDeadInsts.push_back(OpI);
2069 }
2070
2071 EA.removeInstruction(DeadInst);
2072 // Remove memory defs directly if they don't produce results, but only
2073 // queue other dead instructions for later removal. They may have been
2074 // used as memory locations that have been cached by BatchAA. Removing
2075 // them here may lead to newly created instructions to be allocated at the
2076 // same address, yielding stale cache entries.
2077 if (IsMemDef && DeadInst->getType()->isVoidTy())
2078 DeadInst->eraseFromParent();
2079 else
2080 ToRemove.push_back(DeadInst);
2081 }
2082}
2083
2084bool DSEState::mayThrowBetween(Instruction *KillingI, Instruction *DeadI,
2085 const Value *KillingUndObj) {
2086 // First see if we can ignore it by using the fact that KillingI is an
2087 // alloca/alloca like object that is not visible to the caller during
2088 // execution of the function.
2089 if (KillingUndObj && isInvisibleToCallerOnUnwind(KillingUndObj))
2090 return false;
2091
2092 if (KillingI->getParent() == DeadI->getParent())
2093 return ThrowingBlocks.count(KillingI->getParent());
2094 return !ThrowingBlocks.empty();
2095}
2096
2097bool DSEState::isDSEBarrier(const Value *KillingUndObj, Instruction *DeadI) {
2098 // If DeadI may throw it acts as a barrier, unless we are to an
2099 // alloca/alloca like object that does not escape.
2100 if (DeadI->mayThrow() && !isInvisibleToCallerOnUnwind(KillingUndObj))
2101 return true;
2102
2103 // If DeadI is an atomic load/store stronger than monotonic, do not try to
2104 // eliminate/reorder it.
2105 if (DeadI->isAtomic()) {
2106 if (auto *LI = dyn_cast<LoadInst>(DeadI))
2107 return isStrongerThanMonotonic(LI->getOrdering());
2108 if (auto *SI = dyn_cast<StoreInst>(DeadI))
2109 return isStrongerThanMonotonic(SI->getOrdering());
2110 if (auto *ARMW = dyn_cast<AtomicRMWInst>(DeadI))
2111 return isStrongerThanMonotonic(ARMW->getOrdering());
2112 if (auto *CmpXchg = dyn_cast<AtomicCmpXchgInst>(DeadI))
2113 return isStrongerThanMonotonic(CmpXchg->getSuccessOrdering()) ||
2114 isStrongerThanMonotonic(CmpXchg->getFailureOrdering());
2115 llvm_unreachable("other instructions should be skipped in MemorySSA");
2116 }
2117 return false;
2118}
2119
2120bool DSEState::eliminateDeadWritesAtEndOfFunction() {
2121 bool MadeChange = false;
2122 LLVM_DEBUG(
2123 dbgs() << "Trying to eliminate MemoryDefs at the end of the function\n");
2124 do {
2125 ShouldIterateEndOfFunctionDSE = false;
2126 for (MemoryDef *Def : llvm::reverse(MemDefs)) {
2127 if (SkipStores.contains(Def))
2128 continue;
2129
2130 Instruction *DefI = Def->getMemoryInst();
2131 auto DefLoc = getLocForWrite(DefI);
2132 if (!DefLoc || !isRemovable(DefI)) {
2133 LLVM_DEBUG(dbgs() << " ... could not get location for write or "
2134 "instruction not removable.\n");
2135 continue;
2136 }
2137
2138 // NOTE: Currently eliminating writes at the end of a function is
2139 // limited to MemoryDefs with a single underlying object, to save
2140 // compile-time. In practice it appears the case with multiple
2141 // underlying objects is very uncommon. If it turns out to be important,
2142 // we can use getUnderlyingObjects here instead.
2143 const Value *UO = getUnderlyingObject(DefLoc->Ptr);
2144 if (!isInvisibleToCallerAfterRet(UO, DefLoc->Ptr, DefLoc->Size))
2145 continue;
2146
2147 if (isWriteAtEndOfFunction(Def, *DefLoc)) {
2148 // See through pointer-to-pointer bitcasts
2149 LLVM_DEBUG(dbgs() << " ... MemoryDef is not accessed until the end "
2150 "of the function\n");
2152 ++NumFastStores;
2153 MadeChange = true;
2154 }
2155 }
2156 } while (ShouldIterateEndOfFunctionDSE);
2157 return MadeChange;
2158}
2159
2160bool DSEState::eliminateRedundantStoresViaDominatingConditions() {
2161 bool MadeChange = false;
2162 LLVM_DEBUG(dbgs() << "Trying to eliminate MemoryDefs whose value being "
2163 "written is implied by a dominating condition\n");
2164
2165 using ConditionInfo = std::pair<Value *, Value *>;
2166 using ScopedHTType = ScopedHashTable<ConditionInfo, Instruction *>;
2167
2168 // We maintain a scoped hash table of the active dominating conditions for a
2169 // given node.
2170 ScopedHTType ActiveConditions;
2171 auto GetDominatingCondition = [&](BasicBlock *BB)
2172 -> std::optional<std::tuple<ConditionInfo, Instruction *, BasicBlock *>> {
2173 auto *BI = dyn_cast<CondBrInst>(BB->getTerminator());
2174 if (!BI)
2175 return std::nullopt;
2176
2177 // In case both blocks are the same, it is not possible to determine
2178 // if optimization is possible. (We would not want to optimize a store
2179 // in the FalseBB if condition is true and vice versa.)
2180 if (BI->getSuccessor(0) == BI->getSuccessor(1))
2181 return std::nullopt;
2182
2183 Instruction *ICmpL;
2184 CmpPredicate Pred;
2185 Value *StorePtr, *StoreVal;
2186 if (!match(BI->getCondition(),
2187 m_c_ICmp(Pred, m_Instruction(ICmpL, m_Load(m_Value(StorePtr))),
2188 m_Value(StoreVal))) ||
2189 !ICmpInst::isEquality(Pred))
2190 return std::nullopt;
2191
2192 // Ensure the replacement is allowed when comparing pointers, as
2193 // the equality compares addresses only, not pointers' provenance.
2194 if (StoreVal->getType()->isPointerTy() &&
2195 !canReplacePointersIfEqual(StoreVal, ICmpL, DL))
2196 return std::nullopt;
2197
2198 unsigned ImpliedSuccIdx = Pred == ICmpInst::ICMP_EQ ? 0 : 1;
2199 BasicBlock *ImpliedSucc = BI->getSuccessor(ImpliedSuccIdx);
2200 return {{ConditionInfo(StorePtr, StoreVal), ICmpL, ImpliedSucc}};
2201 };
2202
2203 auto VisitNode = [&](DomTreeNode *Node, unsigned Depth, auto &Self) -> void {
2205 return;
2206
2207 BasicBlock *BB = Node->getBlock();
2208 // Check for redundant stores against active known conditions.
2209 if (auto *Accesses = MSSA.getBlockDefs(BB)) {
2210 for (auto &Access : make_early_inc_range(*Accesses)) {
2211 auto *Def = dyn_cast<MemoryDef>(&Access);
2212 if (!Def)
2213 continue;
2214
2215 auto *SI = dyn_cast<StoreInst>(Def->getMemoryInst());
2216 if (!SI || !SI->isUnordered())
2217 continue;
2218
2219 Instruction *LI = ActiveConditions.lookup(
2220 {SI->getPointerOperand(), SI->getValueOperand()});
2221 if (!LI)
2222 continue;
2223
2224 // Found a dominating condition that may imply the value being stored.
2225 // Make sure there does not exist any clobbering access between the
2226 // load and the potential redundant store.
2227 MemoryAccess *LoadAccess = MSSA.getMemoryAccess(LI);
2228 MemoryAccess *ClobberingAccess =
2229 MSSA.getSkipSelfWalker()->getClobberingMemoryAccess(Def, BatchAA);
2230 if (MSSA.dominates(ClobberingAccess, LoadAccess)) {
2232 << "Removing No-Op Store:\n DEAD: " << *SI << '\n');
2234 NumRedundantStores++;
2235 MadeChange = true;
2236 }
2237 }
2238 }
2239
2240 // See whether this basic block establishes a dominating condition.
2241 auto MaybeCondition = GetDominatingCondition(BB);
2242
2243 for (DomTreeNode *Child : Node->children()) {
2244 // RAII scope for the active conditions.
2245 ScopedHTType::ScopeTy Scope(ActiveConditions);
2246 if (MaybeCondition) {
2247 const auto &[Cond, LI, ImpliedSucc] = *MaybeCondition;
2248 if (DT.dominates(BasicBlockEdge(BB, ImpliedSucc), Child->getBlock())) {
2249 // Found a condition that holds for this child, dominated by the
2250 // current node via the equality edge. Propagate the condition to
2251 // the children by pushing it onto the table.
2252 ActiveConditions.insert(Cond, LI);
2253 }
2254 }
2255
2256 // Recursively visit the children of this node. Upon destruction, the no
2257 // longer active condition before visiting any sibling nodes is popped
2258 // from the active scope.
2259 Self(Child, Depth + 1, Self);
2260 }
2261 };
2262
2263 // Do a DFS walk of the dom-tree.
2265
2266 return MadeChange;
2267}
2268
2269bool DSEState::tryFoldIntoCalloc(MemoryDef *Def, const Value *DefUO) {
2270 Instruction *DefI = Def->getMemoryInst();
2271 MemSetInst *MemSet = dyn_cast<MemSetInst>(DefI);
2272 if (!MemSet)
2273 // TODO: Could handle zero store to small allocation as well.
2274 return false;
2275 Constant *StoredConstant = dyn_cast<Constant>(MemSet->getValue());
2276 if (!StoredConstant || !StoredConstant->isNullValue())
2277 return false;
2278
2279 if (!isRemovable(DefI))
2280 // The memset might be volatile..
2281 return false;
2282
2283 if (F.hasFnAttribute(Attribute::SanitizeMemory) ||
2284 F.hasFnAttribute(Attribute::SanitizeAddress) ||
2285 F.hasFnAttribute(Attribute::SanitizeHWAddress) || F.getName() == "calloc")
2286 return false;
2287 auto *Malloc = const_cast<CallInst *>(dyn_cast<CallInst>(DefUO));
2288 if (!Malloc)
2289 return false;
2290 auto *InnerCallee = Malloc->getCalledFunction();
2291 if (!InnerCallee)
2292 return false;
2293 LibFunc Func = NotLibFunc;
2294 StringRef ZeroedVariantName;
2295 if (!TLI.getLibFunc(*InnerCallee, Func) || !TLI.has(Func) ||
2296 Func != LibFunc_malloc) {
2297 Attribute Attr = Malloc->getFnAttr("alloc-variant-zeroed");
2298 if (!Attr.isValid())
2299 return false;
2300 ZeroedVariantName = Attr.getValueAsString();
2301 if (ZeroedVariantName.empty())
2302 return false;
2303 }
2304
2305 // Gracefully handle malloc with unexpected memory attributes.
2306 auto *MallocDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(Malloc));
2307 if (!MallocDef)
2308 return false;
2309
2310 auto shouldCreateCalloc = [](CallInst *Malloc, CallInst *Memset) {
2311 // Check for br(icmp ptr, null), truebb, falsebb) pattern at the end
2312 // of malloc block
2313 auto *MallocBB = Malloc->getParent(), *MemsetBB = Memset->getParent();
2314 if (MallocBB == MemsetBB)
2315 return true;
2316 auto *Ptr = Memset->getArgOperand(0);
2317 auto *TI = MallocBB->getTerminator();
2318 BasicBlock *TrueBB, *FalseBB;
2319 if (!match(TI, m_Br(m_SpecificICmp(ICmpInst::ICMP_EQ, m_Specific(Ptr),
2320 m_Zero()),
2321 TrueBB, FalseBB)))
2322 return false;
2323 if (MemsetBB != FalseBB)
2324 return false;
2325 return true;
2326 };
2327
2328 if (Malloc->getOperand(0) != MemSet->getLength())
2329 return false;
2330 if (!shouldCreateCalloc(Malloc, MemSet) || !DT.dominates(Malloc, MemSet) ||
2331 !memoryIsNotModifiedBetween(Malloc, MemSet, BatchAA, DL, &DT))
2332 return false;
2333 IRBuilder<> IRB(Malloc);
2334 assert(Func == LibFunc_malloc || !ZeroedVariantName.empty());
2335 Value *Calloc = nullptr;
2336 if (!ZeroedVariantName.empty()) {
2337 LLVMContext &Ctx = Malloc->getContext();
2338 AttributeList Attrs = InnerCallee->getAttributes();
2339 AllocFnKind AllocKind =
2340 Attrs.getFnAttr(Attribute::AllocKind).getAllocKind() |
2341 AllocFnKind::Zeroed;
2342 AllocKind &= ~AllocFnKind::Uninitialized;
2343 Attrs =
2344 Attrs.addFnAttribute(Ctx, Attribute::getWithAllocKind(Ctx, AllocKind))
2345 .removeFnAttribute(Ctx, "alloc-variant-zeroed");
2346 FunctionCallee ZeroedVariant = Malloc->getModule()->getOrInsertFunction(
2347 ZeroedVariantName, InnerCallee->getFunctionType(), Attrs);
2348 cast<Function>(ZeroedVariant.getCallee())
2349 ->setCallingConv(Malloc->getCallingConv());
2351 Args.append(Malloc->arg_begin(), Malloc->arg_end());
2352 CallInst *CI = IRB.CreateCall(ZeroedVariant, Args, ZeroedVariantName);
2353 CI->setCallingConv(Malloc->getCallingConv());
2354 Calloc = CI;
2355 } else {
2356 Type *SizeTTy = Malloc->getArgOperand(0)->getType();
2357 Calloc = emitCalloc(ConstantInt::get(SizeTTy, 1), Malloc->getArgOperand(0),
2358 IRB, TLI, Malloc->getType()->getPointerAddressSpace());
2359 }
2360 if (!Calloc)
2361 return false;
2362
2363 if (MDNode *MD = Malloc->getMetadata(LLVMContext::MD_alloc_token))
2364 cast<Instruction>(Calloc)->setMetadata(LLVMContext::MD_alloc_token, MD);
2365
2366 MemorySSAUpdater Updater(&MSSA);
2367 auto *NewAccess = Updater.createMemoryAccessAfter(cast<Instruction>(Calloc),
2368 nullptr, MallocDef);
2369 auto *NewAccessMD = cast<MemoryDef>(NewAccess);
2370 Updater.insertDef(NewAccessMD, /*RenameUses=*/true);
2371 Malloc->replaceAllUsesWith(Calloc);
2373 return true;
2374}
2375
2376bool DSEState::storeIsNoop(MemoryDef *Def, const Value *DefUO) {
2377 Instruction *DefI = Def->getMemoryInst();
2378 StoreInst *Store = dyn_cast<StoreInst>(DefI);
2379 MemSetInst *MemSet = dyn_cast<MemSetInst>(DefI);
2380 Constant *StoredConstant = nullptr;
2381 if (Store)
2382 StoredConstant = dyn_cast<Constant>(Store->getOperand(0));
2383 else if (MemSet)
2384 StoredConstant = dyn_cast<Constant>(MemSet->getValue());
2385 else
2386 return false;
2387
2388 if (!isRemovable(DefI))
2389 return false;
2390
2391 if (StoredConstant) {
2392 Constant *InitC =
2393 getInitialValueOfAllocation(DefUO, &TLI, StoredConstant->getType());
2394 // If the clobbering access is LiveOnEntry, no instructions between them
2395 // can modify the memory location.
2396 if (InitC && InitC == StoredConstant)
2397 return MSSA.isLiveOnEntryDef(
2398 MSSA.getSkipSelfWalker()->getClobberingMemoryAccess(Def, BatchAA));
2399 }
2400
2401 if (!Store)
2402 return false;
2403
2404 if (auto *LoadI = dyn_cast<LoadInst>(Store->getOperand(0))) {
2405 if (LoadI->getPointerOperand() == Store->getOperand(1)) {
2406 // Get the defining access for the load.
2407 auto *LoadAccess = MSSA.getMemoryAccess(LoadI)->getDefiningAccess();
2408 // Fast path: the defining accesses are the same.
2409 if (LoadAccess == Def->getDefiningAccess())
2410 return true;
2411
2412 // Look through phi accesses. Recursively scan all phi accesses by
2413 // adding them to a worklist. Bail when we run into a memory def that
2414 // does not match LoadAccess.
2415 SetVector<MemoryAccess *> ToCheck;
2416 MemoryAccess *Current =
2417 MSSA.getWalker()->getClobberingMemoryAccess(Def, BatchAA);
2418 // We don't want to bail when we run into the store memory def. But,
2419 // the phi access may point to it. So, pretend like we've already
2420 // checked it.
2421 ToCheck.insert(Def);
2422 ToCheck.insert(Current);
2423 // Start at current (1) to simulate already having checked Def.
2424 for (unsigned I = 1; I < ToCheck.size(); ++I) {
2425 Current = ToCheck[I];
2426 if (auto PhiAccess = dyn_cast<MemoryPhi>(Current)) {
2427 // Check all the operands.
2428 for (auto &Use : PhiAccess->incoming_values())
2429 ToCheck.insert(cast<MemoryAccess>(&Use));
2430 continue;
2431 }
2432
2433 // If we found a memory def, bail. This happens when we have an
2434 // unrelated write in between an otherwise noop store.
2435 assert(isa<MemoryDef>(Current) && "Only MemoryDefs should reach here.");
2436 // TODO: Skip no alias MemoryDefs that have no aliasing reads.
2437 // We are searching for the definition of the store's destination.
2438 // So, if that is the same definition as the load, then this is a
2439 // noop. Otherwise, fail.
2440 if (LoadAccess != Current)
2441 return false;
2442 }
2443 return true;
2444 }
2445 }
2446
2447 return false;
2448}
2449
2450bool DSEState::removePartiallyOverlappedStores(InstOverlapIntervalsTy &IOL) {
2451 bool Changed = false;
2452 for (auto OI : IOL) {
2453 Instruction *DeadI = OI.first;
2454 MemoryLocation Loc = *getLocForWrite(DeadI);
2455 assert(isRemovable(DeadI) && "Expect only removable instruction");
2456
2457 const Value *Ptr = Loc.Ptr->stripPointerCasts();
2458 int64_t DeadStart = 0;
2459 uint64_t DeadSize = Loc.Size.getValue();
2460 GetPointerBaseWithConstantOffset(Ptr, DeadStart, DL);
2461 OverlapIntervalsTy &IntervalMap = OI.second;
2462 Changed |= tryToShortenEnd(DeadI, IntervalMap, DeadStart, DeadSize);
2463 if (IntervalMap.empty())
2464 continue;
2465 Changed |= tryToShortenBegin(DeadI, IntervalMap, DeadStart, DeadSize);
2466 }
2467 return Changed;
2468}
2469
2470bool DSEState::eliminateRedundantStoresOfExistingValues() {
2471 bool MadeChange = false;
2472 LLVM_DEBUG(dbgs() << "Trying to eliminate MemoryDefs that write the "
2473 "already existing value\n");
2474 for (auto *Def : MemDefs) {
2475 if (SkipStores.contains(Def) || MSSA.isLiveOnEntryDef(Def))
2476 continue;
2477
2478 Instruction *DefInst = Def->getMemoryInst();
2479 auto MaybeDefLoc = getLocForWrite(DefInst);
2480 if (!MaybeDefLoc || !isRemovable(DefInst))
2481 continue;
2482
2483 MemoryDef *UpperDef;
2484 // To conserve compile-time, we avoid walking to the next clobbering def.
2485 // Instead, we just try to get the optimized access, if it exists. DSE
2486 // will try to optimize defs during the earlier traversal.
2487 if (Def->isOptimized())
2488 UpperDef = dyn_cast<MemoryDef>(Def->getOptimized());
2489 else
2490 UpperDef = dyn_cast<MemoryDef>(Def->getDefiningAccess());
2491 if (!UpperDef || MSSA.isLiveOnEntryDef(UpperDef))
2492 continue;
2493
2494 Instruction *UpperInst = UpperDef->getMemoryInst();
2495 auto IsRedundantStore = [&]() {
2496 // We don't care about differences in call attributes here.
2497 if (DefInst->isIdenticalToWhenDefined(UpperInst,
2498 /*IntersectAttrs=*/true))
2499 return true;
2500 if (auto *MemSetI = dyn_cast<MemSetInst>(UpperInst)) {
2501 if (auto *SI = dyn_cast<StoreInst>(DefInst)) {
2502 // MemSetInst must have a write location.
2503 auto UpperLoc = getLocForWrite(UpperInst);
2504 if (!UpperLoc)
2505 return false;
2506 int64_t InstWriteOffset = 0;
2507 int64_t DepWriteOffset = 0;
2508 auto OR = isOverwrite(UpperInst, DefInst, *UpperLoc, *MaybeDefLoc,
2509 InstWriteOffset, DepWriteOffset);
2510 Value *StoredByte = isBytewiseValue(SI->getValueOperand(), DL);
2511 return StoredByte && StoredByte == MemSetI->getOperand(1) &&
2512 OR == OW_Complete;
2513 }
2514 }
2515 return false;
2516 };
2517
2518 if (!IsRedundantStore() || isReadClobber(*MaybeDefLoc, DefInst))
2519 continue;
2520 LLVM_DEBUG(dbgs() << "DSE: Remove No-Op Store:\n DEAD: " << *DefInst
2521 << '\n');
2522 deleteDeadInstruction(DefInst);
2523 NumRedundantStores++;
2524 MadeChange = true;
2525 }
2526 return MadeChange;
2527}
2528
2530DSEState::getInitializesArgMemLoc(const Instruction *I) {
2531 const CallBase *CB = dyn_cast<CallBase>(I);
2532 if (!CB)
2533 return {};
2534
2535 // Collect aliasing arguments and their initializes ranges.
2536 SmallMapVector<Value *, SmallVector<ArgumentInitInfo, 2>, 2> Arguments;
2537 for (unsigned Idx = 0, Count = CB->arg_size(); Idx < Count; ++Idx) {
2538 Value *CurArg = CB->getArgOperand(Idx);
2539 if (!CurArg->getType()->isPointerTy())
2540 continue;
2541
2542 ConstantRangeList Inits;
2543 Attribute InitializesAttr = CB->getParamAttr(Idx, Attribute::Initializes);
2544 // initializes on byval arguments refers to the callee copy, not the
2545 // original memory the caller passed in.
2546 if (InitializesAttr.isValid() && !CB->isByValArgument(Idx))
2547 Inits = InitializesAttr.getValueAsConstantRangeList();
2548
2549 // Check whether "CurArg" could alias with global variables. We require
2550 // either it's function local and isn't captured before or the "CB" only
2551 // accesses arg or inaccessible mem.
2552 if (!Inits.empty() && !CB->onlyAccessesInaccessibleMemOrArgMem() &&
2553 !isFuncLocalAndNotCaptured(CurArg, CB, EA))
2554 Inits = ConstantRangeList();
2555
2556 // We don't perform incorrect DSE on unwind edges in the current function,
2557 // and use the "initializes" attribute to kill dead stores if:
2558 // - The call does not throw exceptions, "CB->doesNotThrow()".
2559 // - Or the callee parameter has "dead_on_unwind" attribute.
2560 // - Or the argument is invisible to caller on unwind, and there are no
2561 // unwind edges from this call in the current function (e.g. `CallInst`).
2562 bool IsDeadOrInvisibleOnUnwind =
2563 CB->paramHasAttr(Idx, Attribute::DeadOnUnwind) ||
2564 (isa<CallInst>(CB) && isInvisibleToCallerOnUnwind(CurArg));
2565 ArgumentInitInfo InitInfo{Idx, IsDeadOrInvisibleOnUnwind, Inits};
2566 bool FoundAliasing = false;
2567 for (auto &[Arg, AliasList] : Arguments) {
2568 auto AAR = BatchAA.alias(MemoryLocation::getBeforeOrAfter(Arg),
2570 if (AAR == AliasResult::NoAlias) {
2571 continue;
2572 } else if (AAR == AliasResult::MustAlias) {
2573 FoundAliasing = true;
2574 AliasList.push_back(InitInfo);
2575 } else {
2576 // For PartialAlias and MayAlias, there is an offset or may be an
2577 // unknown offset between the arguments and we insert an empty init
2578 // range to discard the entire initializes info while intersecting.
2579 FoundAliasing = true;
2580 AliasList.push_back(ArgumentInitInfo{Idx, IsDeadOrInvisibleOnUnwind,
2581 ConstantRangeList()});
2582 }
2583 }
2584 if (!FoundAliasing)
2585 Arguments[CurArg] = {InitInfo};
2586 }
2587
2589 for (const auto &[_, Args] : Arguments) {
2590 auto IntersectedRanges =
2592 if (IntersectedRanges.empty())
2593 continue;
2594
2595 for (const auto &Arg : Args) {
2596 for (const auto &Range : IntersectedRanges) {
2597 int64_t Start = Range.getLower().getSExtValue();
2598 int64_t End = Range.getUpper().getSExtValue();
2599 // For now, we only handle locations starting at offset 0.
2600 if (Start == 0)
2601 Locations.push_back(MemoryLocation(CB->getArgOperand(Arg.Idx),
2602 LocationSize::precise(End - Start),
2603 CB->getAAMetadata()));
2604 }
2605 }
2606 }
2607 return Locations;
2608}
2609
2610std::pair<bool, bool>
2611DSEState::eliminateDeadDefs(const MemoryLocationWrapper &KillingLocWrapper) {
2612 bool Changed = false;
2613 bool DeletedKillingLoc = false;
2614 unsigned ScanLimit = MemorySSAScanLimit;
2615 unsigned WalkerStepLimit = MemorySSAUpwardsStepLimit;
2616 unsigned PartialLimit = MemorySSAPartialStoreLimit;
2617 // Worklist of MemoryAccesses that may be killed by
2618 // "KillingLocWrapper.MemDef".
2619 SmallSetVector<MemoryAccess *, 8> ToCheck;
2620 // Track MemoryAccesses that have been deleted in the loop below, so we can
2621 // skip them. Don't use SkipStores for this, which may contain reused
2622 // MemoryAccess addresses.
2623 SmallPtrSet<MemoryAccess *, 8> Deleted;
2624 [[maybe_unused]] unsigned OrigNumSkipStores = SkipStores.size();
2625 ToCheck.insert(KillingLocWrapper.MemDef->getDefiningAccess());
2626
2627 // Check if MemoryAccesses in the worklist are killed by
2628 // "KillingLocWrapper.MemDef".
2629 for (unsigned I = 0; I < ToCheck.size(); I++) {
2630 MemoryAccess *Current = ToCheck[I];
2631 if (Deleted.contains(Current))
2632 continue;
2633 std::optional<MemoryAccess *> MaybeDeadAccess = getDomMemoryDef(
2634 KillingLocWrapper.MemDef, Current, KillingLocWrapper.MemLoc,
2635 KillingLocWrapper.UnderlyingObject, ScanLimit, WalkerStepLimit,
2636 isMemTerminatorInst(KillingLocWrapper.DefInst), PartialLimit,
2637 KillingLocWrapper.DefByInitializesAttr);
2638
2639 if (!MaybeDeadAccess) {
2640 LLVM_DEBUG(dbgs() << " finished walk\n");
2641 continue;
2642 }
2643 MemoryAccess *DeadAccess = *MaybeDeadAccess;
2644 LLVM_DEBUG(dbgs() << " Checking if we can kill " << *DeadAccess);
2645 if (isa<MemoryPhi>(DeadAccess)) {
2646 LLVM_DEBUG(dbgs() << "\n ... adding incoming values to worklist\n");
2647 for (Value *V : cast<MemoryPhi>(DeadAccess)->incoming_values()) {
2648 MemoryAccess *IncomingAccess = cast<MemoryAccess>(V);
2649 BasicBlock *IncomingBlock = IncomingAccess->getBlock();
2650 BasicBlock *PhiBlock = DeadAccess->getBlock();
2651
2652 // We only consider incoming MemoryAccesses that come before the
2653 // MemoryPhi. Otherwise we could discover candidates that do not
2654 // strictly dominate our starting def.
2655 if (PostOrderNumbers[IncomingBlock] > PostOrderNumbers[PhiBlock])
2656 ToCheck.insert(IncomingAccess);
2657 }
2658 continue;
2659 }
2660 // We cannot apply the initializes attribute to DeadAccess/DeadDef.
2661 // It would incorrectly consider a call instruction as redundant store
2662 // and remove this call instruction.
2663 // TODO: this conflates the existence of a MemoryLocation with being able
2664 // to delete the instruction. Fix isRemovable() to consider calls with
2665 // side effects that cannot be removed, e.g. calls with the initializes
2666 // attribute, and remove getLocForInst(ConsiderInitializesAttr = false).
2667 MemoryDefWrapper DeadDefWrapper(
2668 cast<MemoryDef>(DeadAccess),
2669 getLocForInst(cast<MemoryDef>(DeadAccess)->getMemoryInst(),
2670 /*ConsiderInitializesAttr=*/false));
2671 assert(DeadDefWrapper.DefinedLocations.size() == 1);
2672 MemoryLocationWrapper &DeadLocWrapper =
2673 DeadDefWrapper.DefinedLocations.front();
2674 LLVM_DEBUG(dbgs() << " (" << *DeadLocWrapper.DefInst << ")\n");
2675 ToCheck.insert(DeadLocWrapper.MemDef->getDefiningAccess());
2676 NumGetDomMemoryDefPassed++;
2677
2678 if (!DebugCounter::shouldExecute(MemorySSACounter))
2679 continue;
2680 if (isMemTerminatorInst(KillingLocWrapper.DefInst)) {
2681 if (KillingLocWrapper.UnderlyingObject != DeadLocWrapper.UnderlyingObject)
2682 continue;
2683 LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: "
2684 << *DeadLocWrapper.DefInst << "\n KILLER: "
2685 << *KillingLocWrapper.DefInst << '\n');
2686 deleteDeadInstruction(DeadLocWrapper.DefInst, &Deleted);
2687 ++NumFastStores;
2688 Changed = true;
2689 } else {
2690 // Check if DeadI overwrites KillingI.
2691 int64_t KillingOffset = 0;
2692 int64_t DeadOffset = 0;
2693 OverwriteResult OR =
2694 isOverwrite(KillingLocWrapper.DefInst, DeadLocWrapper.DefInst,
2695 KillingLocWrapper.MemLoc, DeadLocWrapper.MemLoc,
2696 KillingOffset, DeadOffset);
2697 if (OR == OW_MaybePartial) {
2698 auto &IOL = IOLs[DeadLocWrapper.DefInst->getParent()];
2699 OR = isPartialOverwrite(KillingLocWrapper.MemLoc, DeadLocWrapper.MemLoc,
2700 KillingOffset, DeadOffset,
2701 DeadLocWrapper.DefInst, IOL);
2702 }
2703 if (EnablePartialStoreMerging && OR == OW_PartialEarlierWithFullLater) {
2704 auto *DeadSI = dyn_cast<StoreInst>(DeadLocWrapper.DefInst);
2705 auto *KillingSI = dyn_cast<StoreInst>(KillingLocWrapper.DefInst);
2706 // We are re-using tryToMergePartialOverlappingStores, which requires
2707 // DeadSI to dominate KillingSI.
2708 // TODO: implement tryToMergeParialOverlappingStores using MemorySSA.
2709 if (DeadSI && KillingSI && DT.dominates(DeadSI, KillingSI)) {
2710 if (Constant *Merged = tryToMergePartialOverlappingStores(
2711 KillingSI, DeadSI, KillingOffset, DeadOffset, DL, BatchAA,
2712 &DT)) {
2713
2714 // Update stored value of earlier store to merged constant.
2715 DeadSI->setOperand(0, Merged);
2716 ++NumModifiedStores;
2717 Changed = true;
2718 DeletedKillingLoc = true;
2719
2720 // Remove killing store and remove any outstanding overlap
2721 // intervals for the updated store.
2722 deleteDeadInstruction(KillingSI, &Deleted);
2723 auto I = IOLs.find(DeadSI->getParent());
2724 if (I != IOLs.end())
2725 I->second.erase(DeadSI);
2726 break;
2727 }
2728 }
2729 }
2730 if (OR == OW_Complete) {
2731 LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: "
2732 << *DeadLocWrapper.DefInst << "\n KILLER: "
2733 << *KillingLocWrapper.DefInst << '\n');
2734 deleteDeadInstruction(DeadLocWrapper.DefInst, &Deleted);
2735 ++NumFastStores;
2736 Changed = true;
2737 }
2738 }
2739 }
2740
2741 assert(SkipStores.size() - OrigNumSkipStores == Deleted.size() &&
2742 "SkipStores and Deleted out of sync?");
2743
2744 return {Changed, DeletedKillingLoc};
2745}
2746
2747bool DSEState::eliminateDeadDefs(const MemoryDefWrapper &KillingDefWrapper) {
2748 if (KillingDefWrapper.DefinedLocations.empty()) {
2749 LLVM_DEBUG(dbgs() << "Failed to find analyzable write location for "
2750 << *KillingDefWrapper.DefInst << "\n");
2751 return false;
2752 }
2753
2754 bool MadeChange = false;
2755 for (auto &KillingLocWrapper : KillingDefWrapper.DefinedLocations) {
2756 LLVM_DEBUG(dbgs() << "Trying to eliminate MemoryDefs killed by "
2757 << *KillingLocWrapper.MemDef << " ("
2758 << *KillingLocWrapper.DefInst << ")\n");
2759 auto [Changed, DeletedKillingLoc] = eliminateDeadDefs(KillingLocWrapper);
2760 MadeChange |= Changed;
2761
2762 // Check if the store is a no-op.
2763 if (!DeletedKillingLoc && storeIsNoop(KillingLocWrapper.MemDef,
2764 KillingLocWrapper.UnderlyingObject)) {
2765 LLVM_DEBUG(dbgs() << "DSE: Remove No-Op Store:\n DEAD: "
2766 << *KillingLocWrapper.DefInst << '\n');
2767 deleteDeadInstruction(KillingLocWrapper.DefInst);
2768 NumRedundantStores++;
2769 MadeChange = true;
2770 continue;
2771 }
2772 // Can we form a calloc from a memset/malloc pair?
2773 if (!DeletedKillingLoc &&
2774 tryFoldIntoCalloc(KillingLocWrapper.MemDef,
2775 KillingLocWrapper.UnderlyingObject)) {
2776 LLVM_DEBUG(dbgs() << "DSE: Remove memset after forming calloc:\n"
2777 << " DEAD: " << *KillingLocWrapper.DefInst << '\n');
2778 deleteDeadInstruction(KillingLocWrapper.DefInst);
2779 MadeChange = true;
2780 continue;
2781 }
2782 }
2783 return MadeChange;
2784}
2785
2788 const TargetLibraryInfo &TLI,
2789 const CycleInfo &CI) {
2790 bool MadeChange = false;
2791 DSEState State(F, AA, MSSA, DT, PDT, TLI, CI);
2792 // For each store:
2793 for (unsigned I = 0; I < State.MemDefs.size(); I++) {
2794 MemoryDef *KillingDef = State.MemDefs[I];
2795 if (State.SkipStores.count(KillingDef))
2796 continue;
2797
2798 MemoryDefWrapper KillingDefWrapper(
2799 KillingDef, State.getLocForInst(KillingDef->getMemoryInst(),
2801 MadeChange |= State.eliminateDeadDefs(KillingDefWrapper);
2802 }
2803
2805 for (auto &KV : State.IOLs)
2806 MadeChange |= State.removePartiallyOverlappedStores(KV.second);
2807
2808 MadeChange |= State.eliminateRedundantStoresOfExistingValues();
2809 MadeChange |= State.eliminateDeadWritesAtEndOfFunction();
2810 MadeChange |= State.eliminateRedundantStoresViaDominatingConditions();
2811
2812 while (!State.ToRemove.empty()) {
2813 Instruction *DeadInst = State.ToRemove.pop_back_val();
2814 DeadInst->eraseFromParent();
2815 }
2816
2817 return MadeChange;
2818}
2819
2820//===----------------------------------------------------------------------===//
2821// DSE Pass
2822//===----------------------------------------------------------------------===//
2827 MemorySSA &MSSA = AM.getResult<MemorySSAAnalysis>(F).getMSSA();
2830
2831 bool Changed = eliminateDeadStores(F, AA, MSSA, DT, PDT, TLI, CI);
2832
2833#ifdef LLVM_ENABLE_STATS
2835 for (auto &I : instructions(F))
2836 NumRemainingStores += isa<StoreInst>(&I);
2837#endif
2838
2839 if (!Changed)
2840 return PreservedAnalyses::all();
2841
2845 return PA;
2846}
2847
2848namespace {
2849
2850/// A legacy pass for the legacy pass manager that wraps \c DSEPass.
2851class DSELegacyPass : public FunctionPass {
2852public:
2853 static char ID; // Pass identification, replacement for typeid
2854
2855 DSELegacyPass() : FunctionPass(ID) {
2857 }
2858
2859 bool runOnFunction(Function &F) override {
2860 if (skipFunction(F))
2861 return false;
2862
2863 AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
2864 DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
2865 const TargetLibraryInfo &TLI =
2866 getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
2867 MemorySSA &MSSA = getAnalysis<MemorySSAWrapperPass>().getMSSA();
2868 PostDominatorTree &PDT =
2869 getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
2870 CycleInfo &CI = getAnalysis<CycleInfoWrapperPass>().getResult();
2871
2872 bool Changed = eliminateDeadStores(F, AA, MSSA, DT, PDT, TLI, CI);
2873
2874#ifdef LLVM_ENABLE_STATS
2876 for (auto &I : instructions(F))
2877 NumRemainingStores += isa<StoreInst>(&I);
2878#endif
2879
2880 return Changed;
2881 }
2882
2883 void getAnalysisUsage(AnalysisUsage &AU) const override {
2884 AU.setPreservesCFG();
2885 AU.addRequired<AAResultsWrapperPass>();
2886 AU.addRequired<TargetLibraryInfoWrapperPass>();
2887 AU.addPreserved<GlobalsAAWrapperPass>();
2888 AU.addRequired<DominatorTreeWrapperPass>();
2889 AU.addRequired<PostDominatorTreeWrapperPass>();
2890 AU.addRequired<MemorySSAWrapperPass>();
2891 AU.addPreserved<MemorySSAWrapperPass>();
2892 AU.addRequired<CycleInfoWrapperPass>();
2893 AU.addRequired<AssumptionCacheTracker>();
2894 }
2895};
2896
2897} // end anonymous namespace
2898
2899char DSELegacyPass::ID = 0;
2900
2901INITIALIZE_PASS_BEGIN(DSELegacyPass, "dse", "Dead Store Elimination", false,
2902 false)
2912INITIALIZE_PASS_END(DSELegacyPass, "dse", "Dead Store Elimination", false,
2913 false)
2914
2916 return new DSELegacyPass();
2917}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 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 void shortenAssignment(Instruction *Inst, Value *OriginalDest, uint64_t OldOffsetInBits, uint64_t OldSizeInBits, uint64_t NewSizeInBits, bool IsOverwriteEnd)
static bool isShortenableAtTheEnd(Instruction *I)
Returns true if the end of this instruction can be safely shortened in length.
static 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.
bool getLibFunc(StringRef funcName, LibFunc &F) 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:882
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.