46 #define DEBUG_TYPE "dse"
48 STATISTIC(NumRedundantStores,
"Number of redundant stores deleted");
49 STATISTIC(NumFastStores,
"Number of stores deleted");
50 STATISTIC(NumFastOther ,
"Number of other instrs removed");
51 STATISTIC(NumCompletePartials,
"Number of stores dead by later partials");
56 cl::desc(
"Enable partial-overwrite tracking in DSE"));
106 if (ValueSet) ValueSet->remove(DeadInst);
107 InstrOrdering->
erase(DeadInst);
114 }
while (!NowDeadInsts.
empty());
121 if (isa<StoreInst>(I))
124 switch (II->getIntrinsicID()) {
127 case Intrinsic::memset:
128 case Intrinsic::memmove:
129 case Intrinsic::memcpy:
130 case Intrinsic::init_trampoline:
131 case Intrinsic::lifetime_end:
136 if (
Function *
F = CS.getCalledFunction()) {
138 if (TLI.
has(LibFunc::strcpy) && FnName == TLI.
getName(LibFunc::strcpy))
140 if (TLI.
has(LibFunc::strncpy) && FnName == TLI.
getName(LibFunc::strncpy))
142 if (TLI.
has(LibFunc::strcat) && FnName == TLI.
getName(LibFunc::strcat))
144 if (TLI.
has(LibFunc::strncat) && FnName == TLI.
getName(LibFunc::strncat))
171 case Intrinsic::init_trampoline:
175 case Intrinsic::lifetime_end: {
176 uint64_t Len = cast<ConstantInt>(II->
getArgOperand(0))->getZExtValue();
200 return SI->isUnordered();
203 switch (II->getIntrinsicID()) {
205 case Intrinsic::lifetime_end:
209 case Intrinsic::init_trampoline:
213 case Intrinsic::memset:
214 case Intrinsic::memmove:
215 case Intrinsic::memcpy:
222 return CS.getInstruction()->use_empty();
232 if (isa<StoreInst>(I))
236 switch (II->getIntrinsicID()) {
237 default:
return false;
238 case Intrinsic::memset:
239 case Intrinsic::memcpy:
263 return SI->getPointerOperand();
265 return MI->getDest();
268 switch (II->getIntrinsicID()) {
270 case Intrinsic::init_trampoline:
271 return II->getArgOperand(0);
307 int64_t &EarlierOff, int64_t &LaterOff,
313 return OverwriteUnknown;
323 return OverwriteComplete;
335 return OverwriteUnknown;
340 if (ObjectSize == Later.
Size && ObjectSize >= Earlier.
Size)
341 return OverwriteComplete;
353 return OverwriteUnknown;
370 if (EarlierOff >= LaterOff &&
372 uint64_t(EarlierOff - LaterOff) + Earlier.
Size <= Later.
Size)
373 return OverwriteComplete;
381 LaterOff < int64_t(EarlierOff + Earlier.
Size) &&
382 int64_t(LaterOff + Later.
Size) >= EarlierOff) {
385 auto &IM = IOL[DepWrite];
386 DEBUG(
dbgs() <<
"DSE: Partial overwrite: Earlier [" << EarlierOff <<
", " <<
387 int64_t(EarlierOff + Earlier.
Size) <<
") Later [" <<
388 LaterOff <<
", " << int64_t(LaterOff + Later.
Size) <<
")\n");
394 int64_t LaterIntStart = LaterOff, LaterIntEnd = LaterOff + Later.
Size;
398 auto ILI = IM.lower_bound(LaterIntStart);
399 if (ILI != IM.end() && ILI->second <= LaterIntEnd) {
403 LaterIntStart =
std::min(LaterIntStart, ILI->second);
404 LaterIntEnd = std::max(LaterIntEnd, ILI->first);
413 while (ILI != IM.end() && ILI->second <= LaterIntEnd) {
414 assert(ILI->second > LaterIntStart &&
"Unexpected interval");
415 LaterIntEnd = std::max(LaterIntEnd, ILI->first);
420 IM[LaterIntEnd] = LaterIntStart;
423 if (ILI->second <= EarlierOff &&
424 ILI->first >= int64_t(EarlierOff + Earlier.
Size)) {
425 DEBUG(
dbgs() <<
"DSE: Full overwrite from partials: Earlier [" <<
426 EarlierOff <<
", " <<
427 int64_t(EarlierOff + Earlier.
Size) <<
428 ") Composite Later [" <<
429 ILI->second <<
", " << ILI->first <<
")\n");
430 ++NumCompletePartials;
431 return OverwriteComplete;
444 (LaterOff > EarlierOff && LaterOff < int64_t(EarlierOff + Earlier.
Size) &&
445 int64_t(LaterOff + Later.
Size) >= int64_t(EarlierOff + Earlier.
Size)))
458 (LaterOff <= EarlierOff && int64_t(LaterOff + Later.
Size) > EarlierOff)) {
460 int64_t(EarlierOff + Earlier.
Size) &&
461 "Expect to be handled as OverwriteComplete");
462 return OverwriteBegin;
465 return OverwriteUnknown;
489 if (!InstReadLoc.
Ptr)
return false;
492 if (AA.
isNoAlias(InstReadLoc, InstStoreLoc))
return false;
530 bool isFirstBlock =
true;
533 while (!WorkList.
empty()) {
542 assert(B == SecondBB &&
"first block is not the store block");
544 isFirstBlock =
false;
550 for (; BI != EI; ++BI) {
560 "Should not hit the entry block because SI must be dominated by LI");
562 if (!Visited.
insert(*PredI).second)
577 if (Pred == BB)
continue;
594 bool MadeChange =
false;
601 while (!Blocks.empty()) {
620 DEBUG(
dbgs() <<
"DSE: Dead Store to soon to be freed memory:\n DEAD: "
621 << *Dependency <<
'\n');
654 if (isa<Constant>(UnderlyingPointer))
659 if (isa<AllocaInst>(UnderlyingPointer) || isa<Argument>(UnderlyingPointer)) {
660 DeadStackObjects.
remove(const_cast<Value*>(UnderlyingPointer));
668 return !AA->
isNoAlias(StackLoc, LoadedLoc);
683 bool MadeChange =
false;
692 if (isa<AllocaInst>(&
I))
704 if (AI.hasByValOrInAllocaAttr())
705 DeadStackObjects.
insert(&AI);
721 for (
Value *Pointer : Pointers)
722 if (!DeadStackObjects.
count(Pointer)) {
730 DEBUG(
dbgs() <<
"DSE: Dead Store at End of Block:\n DEAD: "
731 << *Dead <<
"\n Objects: ";
733 E = Pointers.end();
I !=
E; ++
I) {
735 if (std::next(
I) !=
E)
750 DEBUG(
dbgs() <<
"DSE: Removing trivially dead instruction:\n DEAD: "
758 if (isa<AllocaInst>(BBI)) {
761 DeadStackObjects.
remove(&*BBI);
769 DeadStackObjects.
remove(&*BBI);
787 if (DeadStackObjects.
empty())
798 if (isa<FenceInst>(*BBI))
804 if (
LoadInst *
L = dyn_cast<LoadInst>(BBI)) {
805 if (!
L->isUnordered())
808 }
else if (
VAArgInst *V = dyn_cast<VAArgInst>(BBI)) {
812 }
else if (!BBI->mayReadFromMemory()) {
827 if (DeadStackObjects.
empty())
835 int64_t &EarlierSize, int64_t LaterOffset,
836 int64_t LaterSize,
bool IsOverwriteEnd) {
843 MemIntrinsic *EarlierIntrinsic = cast<MemIntrinsic>(EarlierWrite);
844 unsigned EarlierWriteAlign = EarlierIntrinsic->
getAlignment();
846 LaterOffset = int64_t(LaterOffset + LaterSize);
849 !((EarlierWriteAlign != 0) && LaterOffset % EarlierWriteAlign == 0))
852 DEBUG(
dbgs() <<
"DSE: Remove Dead Store:\n OW "
853 << (IsOverwriteEnd ?
"END" :
"BEGIN") <<
": " << *EarlierWrite
854 <<
"\n KILLER (offset " << LaterOffset <<
", " << EarlierSize
857 int64_t NewLength = IsOverwriteEnd
858 ? LaterOffset - EarlierOffset
859 : EarlierSize - (LaterOffset - EarlierOffset);
862 Value *TrimmedLength =
864 EarlierIntrinsic->
setLength(TrimmedLength);
866 EarlierSize = NewLength;
867 if (!IsOverwriteEnd) {
868 int64_t OffsetMoved = (LaterOffset - EarlierOffset);
869 Value *Indices[1] = {
872 EarlierIntrinsic->
getRawDest(), Indices,
"", EarlierWrite);
873 EarlierIntrinsic->
setDest(NewDestGEP);
874 EarlierOffset = EarlierOffset + OffsetMoved;
881 int64_t &EarlierStart, int64_t &EarlierSize) {
885 OverlapIntervalsTy::iterator OII = --IntervalMap.end();
886 int64_t LaterStart = OII->second;
887 int64_t LaterSize = OII->first - LaterStart;
889 if (LaterStart > EarlierStart && LaterStart < EarlierStart + EarlierSize &&
890 LaterStart + LaterSize >= EarlierStart + EarlierSize) {
891 if (
tryToShorten(EarlierWrite, EarlierStart, EarlierSize, LaterStart,
893 IntervalMap.erase(OII);
902 int64_t &EarlierStart, int64_t &EarlierSize) {
906 OverlapIntervalsTy::iterator OII = IntervalMap.begin();
907 int64_t LaterStart = OII->second;
908 int64_t LaterSize = OII->first - LaterStart;
910 if (LaterStart <= EarlierStart && LaterStart + LaterSize > EarlierStart) {
911 assert(LaterStart + LaterSize < EarlierStart + EarlierSize &&
912 "Should have been handled as OverwriteComplete");
913 if (
tryToShorten(EarlierWrite, EarlierStart, EarlierSize, LaterStart,
915 IntervalMap.erase(OII);
925 bool Changed =
false;
926 for (
auto OI : IOL) {
933 int64_t EarlierStart = 0;
934 int64_t EarlierSize = int64_t(Loc.
Size);
939 if (IntervalMap.empty())
964 DEBUG(
dbgs() <<
"DSE: Remove Store Of Load from same pointer:\n LOAD: "
965 << *DepLoad <<
"\n STORE: " << *SI <<
'\n');
968 ++NumRedundantStores;
979 if (UnderlyingPointer &&
isCallocLikeFn(UnderlyingPointer, TLI) &&
982 dbgs() <<
"DSE: Remove null store to the calloc'ed object:\n DEAD: "
983 << *Inst <<
"\n OBJECT: " << *UnderlyingPointer <<
'\n');
986 ++NumRedundantStores;
997 bool MadeChange =
false;
1001 size_t LastThrowingInstIndex = 0;
1003 size_t InstrIndex = 1;
1012 MadeChange |=
handleFree(
F, AA, MD, DT, TLI, IOL, &InstrOrdering);
1021 size_t CurInstNumber = InstrIndex++;
1022 InstrOrdering.
insert(std::make_pair(Inst, CurInstNumber));
1024 LastThrowingInstIndex = CurInstNumber;
1082 size_t DepIndex = InstrOrdering.
lookup(DepWrite);
1083 assert(DepIndex &&
"Unexpected instruction");
1084 if (DepIndex <= LastThrowingInstIndex) {
1086 bool IsStoreDeadOnUnwind = isa<AllocaInst>(
Underlying);
1087 if (!IsStoreDeadOnUnwind) {
1095 if (!IsStoreDeadOnUnwind)
1104 int64_t InstWriteOffset, DepWriteOffset;
1106 isOverwrite(Loc, DepLoc, DL, *TLI, DepWriteOffset, InstWriteOffset,
1108 if (OR == OverwriteComplete) {
1109 DEBUG(
dbgs() <<
"DSE: Remove Dead Store:\n DEAD: "
1110 << *DepWrite <<
"\n KILLER: " << *Inst <<
'\n');
1121 ((OR == OverwriteBegin &&
1124 "when partial-overwrite "
1125 "tracking is enabled");
1126 int64_t EarlierSize = DepLoc.
Size;
1127 int64_t LaterSize = Loc.
Size;
1128 bool IsOverwriteEnd = (OR == OverwriteEnd);
1129 MadeChange |=
tryToShorten(DepWrite, DepWriteOffset, EarlierSize,
1130 InstWriteOffset, LaterSize, IsOverwriteEnd);
1142 if (DepWrite == &BB.
front())
break;
1160 MadeChange |=
handleEndBlock(BB, AA, MD, TLI, IOL, &InstrOrdering);
1168 bool MadeChange =
false;
1204 bool runOnFunction(
Function &
F)
override {
1205 if (skipFunction(F))
1208 DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1209 AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
1211 &getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
1213 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
1245 return new DSELegacyPass();
unsigned getAlignment() const
Legacy wrapper pass to provide the GlobalsAAResult object.
Value * getValueOperand()
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Provides a lazy, caching interface for making common memory aliasing information queries, backed by LLVM's alias analysis passes.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static MemoryLocation getLocForWrite(Instruction *Inst, AliasAnalysis &AA)
Return a Location stored to by the specified instruction.
LLVM Argument representation.
bool isDef() const
Tests if this MemDepResult represents a query that is an instruction definition dependency.
STATISTIC(NumFunctions,"Total number of functions")
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
This is the interface for a simple mod/ref and alias analysis over globals.
std::map< int64_t, int64_t > OverlapIntervalsTy
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
void initializeDSELegacyPassPass(PassRegistry &)
unsigned getNumOperands() const
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias. ...
This class represents a function call, abstracting a target machine's calling convention.
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction & front() const
Analysis pass which computes a DominatorTree.
static bool handleFree(CallInst *F, AliasAnalysis *AA, MemoryDependenceResults *MD, DominatorTree *DT, const TargetLibraryInfo *TLI, InstOverlapIntervalsTy &IOL, DenseMap< Instruction *, size_t > *InstrOrdering)
Handle frees of entire structures whose dependency is a store to a field of that structure.
An instruction for reading from memory.
void GetUnderlyingObjects(Value *V, SmallVectorImpl< Value * > &Objects, const DataLayout &DL, LoopInfo *LI=nullptr, unsigned MaxLookup=6)
This method is similar to GetUnderlyingObject except that it can look through phi and select instruct...
static bool isPossibleSelfRead(Instruction *Inst, const MemoryLocation &InstStoreLoc, Instruction *DepWrite, const TargetLibraryInfo &TLI, AliasAnalysis &AA)
If 'Inst' might be a self read (i.e.
void setDest(Value *Ptr)
Set the specified arguments of the instruction.
bool isClobber() const
Tests if this MemDepResult represents a query that is an instruction clobber dependency.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
const CallInst * isFreeCall(const Value *I, const TargetLibraryInfo *TLI)
isFreeCall - Returns non-null if the value is a call to the builtin free()
INITIALIZE_PASS_BEGIN(DSELegacyPass,"dse","Dead Store Elimination", false, false) INITIALIZE_PASS_END(DSELegacyPass
iterator begin()
Instruction iterator methods.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
static void findUnconditionalPreds(SmallVectorImpl< BasicBlock * > &Blocks, BasicBlock *BB, DominatorTree *DT)
Find all blocks that will unconditionally lead to the block BB and append them to F...
static OverwriteResult isOverwrite(const MemoryLocation &Later, const MemoryLocation &Earlier, const DataLayout &DL, const TargetLibraryInfo &TLI, int64_t &EarlierOff, int64_t &LaterOff, Instruction *DepWrite, InstOverlapIntervalsTy &IOL)
Return 'OverwriteComplete' if a store to the 'Later' location completely overwrites a store to the 'E...
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
bool has(LibFunc::Func F) const
Tests whether a library function is available.
const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr it the function does no...
static bool handleEndBlock(BasicBlock &BB, AliasAnalysis *AA, MemoryDependenceResults *MD, const TargetLibraryInfo *TLI, InstOverlapIntervalsTy &IOL, DenseMap< Instruction *, size_t > *InstrOrdering)
Remove dead stores to stack-allocated locations in the function end block.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
An analysis that produces MemoryDependenceResults for a function.
The access references the value stored in memory.
bool remove(const value_type &X)
Remove an item from the set vector.
LLVM_NODISCARD bool empty() const
static void removeAccessedObjects(const MemoryLocation &LoadedLoc, SmallSetVector< Value *, 16 > &DeadStackObjects, const DataLayout &DL, AliasAnalysis *AA, const TargetLibraryInfo *TLI)
Check to see if the specified location may alias any of the stack objects in the DeadStackObjects set...
static GetElementPtrInst * CreateInBounds(Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Create an "inbounds" getelementptr.
bool insert(const value_type &X)
Insert a new element into the SetVector.
static Value * getStoredPointerOperand(Instruction *I)
Return the pointer that is being written to.
static MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset...
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
bool empty() const
Determine if the SetVector is empty or not.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, bool RoundToAlign=false, ObjSizeMode Mode=ObjSizeMode::Exact)
Compute the size of the object pointed by Ptr.
An instruction for storing to memory.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
unsigned getNumSuccessors() const
Return the number of successors that this terminator has.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
The access neither references nor modifies the value stored in memory.
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
initializer< Ty > init(const Ty &Val)
bool erase(const KeyT &Val)
static bool isShortenableAtTheBeginning(Instruction *I)
Returns true if the beginning of this instruction can be safely shortened in length.
Subclasses of this class are all able to terminate a basic block.
A set of analyses that are preserved following a run of a transformation pass.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs...ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
static bool removePartiallyOverlappedStores(AliasAnalysis *AA, const DataLayout &DL, InstOverlapIntervalsTy &IOL)
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DenseMap< Instruction *, OverlapIntervalsTy > InstOverlapIntervalsTy
A manager for alias analyses.
static ManagedStatic< OptionRegistry > OR
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
static bool hasMemoryWrite(Instruction *I, const TargetLibraryInfo &TLI)
Does this instruction write some memory? This only returns true for things that we can analyze with o...
Value * getRawDest() const
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
static bool isShortenableAtTheEnd(Instruction *I)
Returns true if the end of this instruction can be safely shortened in length.
Represent the analysis usage information of a pass.
constexpr bool isPowerOf2_64(uint64_t Value)
isPowerOf2_64 - This function returns true if the argument is a power of two 0 (64 bit edition...
FunctionPass * createDeadStoreEliminationPass()
static bool memoryIsNotModifiedBetween(Instruction *FirstI, Instruction *SecondI, AliasAnalysis *AA)
Returns true if the memory which is accessed by the second instruction is not modified between the fi...
std::underlying_type< E >::type Underlying(E Val)
Check that Val is in range for E, and return Val cast to E's underlying type.
Analysis pass providing a never-invalidated alias analysis result.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
Interval::pred_iterator pred_end(Interval *I)
self_iterator getIterator()
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
A wrapper analysis pass for the legacy pass manager that exposes a MemoryDepnedenceResults instance...
Value * GetUnderlyingObject(Value *V, const DataLayout &DL, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
A memory dependence query can return one of three different answers.
unsigned getDefaultBlockScanLimit() const
Some methods limit the number of instructions they will examine.
const Value * Ptr
The address of the start of the location.
Representation for a specific memory location.
static cl::opt< bool > EnablePartialOverwriteTracking("enable-dse-partial-overwrite-tracking", cl::init(true), cl::Hidden, cl::desc("Enable partial-overwrite tracking in DSE"))
MemDepResult getPointerDependencyFrom(const MemoryLocation &Loc, bool isLoad, BasicBlock::iterator ScanIt, BasicBlock *BB, Instruction *QueryInst=nullptr, unsigned *Limit=nullptr)
Returns the instruction on which a memory location depends.
static void deleteDeadInstruction(Instruction *I, BasicBlock::iterator *BBI, MemoryDependenceResults &MD, const TargetLibraryInfo &TLI, InstOverlapIntervalsTy &IOL, DenseMap< Instruction *, size_t > *InstrOrdering, SmallSetVector< Value *, 16 > *ValueSet=nullptr)
Delete this instruction.
A SetVector that performs no allocations if smaller than a certain size.
bool doesNotAccessMemory(ImmutableCallSite CS)
Checks if the specified call is known to never read or write memory.
This is the common base class for memset/memcpy/memmove.
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
ValTy * getArgument(unsigned ArgNo) const
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Provides information about what library functions are available for the current target.
Value * getLength() const
LLVM_NODISCARD T pop_back_val()
bool isNonLocal() const
Tests if this MemDepResult represents a query that is transparent to the start of the block...
Value * stripPointerCasts()
Strip off pointer casts, all-zero GEPs, and aliases.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
const BasicBlock & getEntryBlock() const
static bool eliminateNoopStore(Instruction *Inst, BasicBlock::iterator &BBI, AliasAnalysis *AA, MemoryDependenceResults *MD, const DataLayout &DL, const TargetLibraryInfo *TLI, InstOverlapIntervalsTy &IOL, DenseMap< Instruction *, size_t > *InstrOrdering)
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th call argument.
ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc)
getModRefInfo (for call sites) - Return information about whether a particular call site modifies or ...
bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are must-alias.
bool mayThrow() const
Return true if this instruction may throw an exception.
This class wraps the llvm.memcpy/memmove intrinsics.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Instruction * getInst() const
If this is a normal dependency, returns the instruction that is depended on.
static bool tryToShortenBegin(Instruction *EarlierWrite, OverlapIntervalsTy &IntervalMap, int64_t &EarlierStart, int64_t &EarlierSize)
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
static MemoryLocation getLocForRead(Instruction *Inst, const TargetLibraryInfo &TLI)
Return the location read by the specified "hasMemoryWrite" instruction if any.
StringRef getName(LibFunc::Func F) const
bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a library function that allocates zero-filled memory (such as...
The access both references and modifies the value stored in memory.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a library function that allocates memory (either malloc...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void preserve()
Mark an analysis as preserved.
Analysis pass providing the TargetLibraryInfo.
static bool eliminateDeadStores(BasicBlock &BB, AliasAnalysis *AA, MemoryDependenceResults *MD, DominatorTree *DT, const TargetLibraryInfo *TLI)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const BasicBlock & front() const
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction has no side ef...
LLVM Value Representation.
void removeInstruction(Instruction *InstToRemove)
Removes an instruction from the dependence analysis, updating the dependence of instructions that pre...
bool remove_if(UnaryPredicate P)
Remove items from the set vector based on a predicate function.
static bool isRemovable(Instruction *I)
If the value of this instruction and the memory it writes to is unused, may we delete this instructio...
StringRef - Represent a constant reference to a string, i.e.
A container for analyses that lazily runs them and caches their results.
Legacy analysis pass which computes a DominatorTree.
static bool isVolatile(Instruction *Inst)
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
static uint64_t getPointerSize(const Value *V, const DataLayout &DL, const TargetLibraryInfo &TLI)
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
Value * getPointerOperand()
const BasicBlock * getParent() const
static bool tryToShorten(Instruction *EarlierWrite, int64_t &EarlierOffset, int64_t &EarlierSize, int64_t LaterOffset, int64_t LaterSize, bool IsOverwriteEnd)
iterator_range< arg_iterator > args()
A wrapper class for inspecting calls to intrinsic functions.
static bool tryToShortenEnd(Instruction *EarlierWrite, OverlapIntervalsTy &IntervalMap, int64_t &EarlierStart, int64_t &EarlierSize)
uint64_t Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known...
MemDepResult getDependency(Instruction *QueryInst)
Returns the instruction on which a memory operation depends.
static MemoryLocation getForSource(const MemTransferInst *MTI)
Return a location representing the source of a memory transfer.