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