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