18 #define DEBUG_TYPE "dse"
41 STATISTIC(NumFastStores,
"Number of stores deleted");
42 STATISTIC(NumFastOther ,
"Number of other instrs removed");
57 AA = &getAnalysis<AliasAnalysis>();
58 MD = &getAnalysis<MemoryDependenceAnalysis>();
59 DT = &getAnalysis<DominatorTree>();
60 TLI = AA->getTargetLibraryInfo();
66 if (DT->isReachableFromEntry(
I))
67 Changed |= runOnBasicBlock(*
I);
69 AA = 0; MD = 0; DT = 0;
129 for (
unsigned op = 0, e = DeadInst->
getNumOperands(); op != e; ++op) {
143 if (ValueSet) ValueSet->remove(DeadInst);
144 }
while (!NowDeadInsts.
empty());
151 if (isa<StoreInst>(I))
154 switch (II->getIntrinsicID()) {
166 if (
Function *F = CS.getCalledFunction()) {
193 if (
StoreInst *SI = dyn_cast<StoreInst>(Inst))
222 uint64_t Len = cast<ConstantInt>(II->
getArgOperand(0))->getZExtValue();
233 "Unknown instruction case");
247 if (
StoreInst *SI = dyn_cast<StoreInst>(I))
248 return SI->isUnordered();
251 switch (II->getIntrinsicID()) {
265 return !cast<MemIntrinsic>(II)->isVolatile();
270 return CS.getInstruction()->use_empty();
280 if (isa<StoreInst>(I))
284 switch (II->getIntrinsicID()) {
285 default:
return false;
300 if (
StoreInst *SI = dyn_cast<StoreInst>(I))
301 return SI->getPointerOperand();
303 return MI->getDest();
306 switch (II->getIntrinsicID()) {
309 return II->getArgOperand(0);
359 return OverwriteComplete;
361 return OverwriteUnknown;
366 return OverwriteComplete;
374 return OverwriteUnknown;
387 return OverwriteUnknown;
392 if (ObjectSize == Later.
Size && ObjectSize >= Earlier.
Size)
393 return OverwriteComplete;
405 return OverwriteUnknown;
422 if (EarlierOff >= LaterOff &&
424 uint64_t(EarlierOff - LaterOff) + Earlier.
Size <= Later.
Size)
425 return OverwriteComplete;
435 if (LaterOff > EarlierOff &&
436 LaterOff < int64_t(EarlierOff + Earlier.
Size) &&
437 int64_t(LaterOff + Later.
Size) >= int64_t(EarlierOff + Earlier.
Size))
441 return OverwriteUnknown;
463 if (InstReadLoc.
Ptr == 0)
return false;
466 if (AA.
isNoAlias(InstReadLoc, InstStoreLoc))
return false;
492 bool MadeChange =
false;
500 MadeChange |= HandleFree(F);
517 if (
StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
519 if (SI->getPointerOperand() == DepLoad->getPointerOperand() &&
521 DEBUG(
dbgs() <<
"DSE: Remove Store Of Load from same pointer:\n "
522 <<
"LOAD: " << *DepLoad <<
"\n STORE: " << *SI <<
'\n');
532 else if (BBI != BB.
begin())
567 int64_t InstWriteOffset, DepWriteOffset;
569 DepWriteOffset, InstWriteOffset);
570 if (OR == OverwriteComplete) {
571 DEBUG(
dbgs() <<
"DSE: Remove Dead Store:\n DEAD: "
572 << *DepWrite <<
"\n KILLER: " << *Inst <<
'\n');
582 if (BBI != BB.
begin())
592 MemIntrinsic* DepIntrinsic = cast<MemIntrinsic>(DepWrite);
595 ((DepWriteAlign != 0) && InstWriteOffset % DepWriteAlign == 0)) {
597 DEBUG(
dbgs() <<
"DSE: Remove Dead Store:\n OW END: "
598 << *DepWrite <<
"\n KILLER (offset "
599 << InstWriteOffset <<
", "
600 << DepLoc.
Size <<
")"
621 if (DepWrite == &BB.
front())
break;
627 InstDep = MD->getPointerDependencyFrom(Loc,
false, DepWrite, &BB);
634 MadeChange |= handleEndBlock(BB);
645 if (Pred == BB)
continue;
658 bool MadeChange =
false;
664 while (!Blocks.empty()) {
669 MemDepResult Dep = MD->getPointerDependencyFrom(Loc,
false, InstPt, BB);
694 Dep = MD->getPointerDependencyFrom(Loc,
false, Next, BB);
706 typedef Value *argument_type;
710 bool operator()(
Value *
I) {
727 bool MadeChange =
false;
736 if (isa<AllocaInst>(
I))
749 if (AI->hasByValAttr())
750 DeadStackObjects.
insert(AI);
765 E = Pointers.
end();
I != E; ++
I)
766 if (!DeadStackObjects.
count(*
I)) {
774 DEBUG(
dbgs() <<
"DSE: Dead Store at End of Block:\n DEAD: "
775 << *Dead <<
"\n Objects: ";
777 E = Pointers.
end();
I != E; ++
I) {
801 if (isa<AllocaInst>(BBI)) {
804 DeadStackObjects.
remove(BBI);
808 if (
CallSite CS = cast<Value>(BBI)) {
812 DeadStackObjects.
remove(BBI);
816 if (AA->doesNotAccessMemory(CS))
821 CouldRef Pred = { CS, AA };
826 if (DeadStackObjects.
empty())
835 if (
LoadInst *L = dyn_cast<LoadInst>(BBI)) {
836 if (!L->isUnordered())
838 LoadedLoc = AA->getLocation(L);
839 }
else if (
VAArgInst *V = dyn_cast<VAArgInst>(BBI)) {
840 LoadedLoc = AA->getLocation(V);
842 LoadedLoc = AA->getLocationForSource(MTI);
843 }
else if (!BBI->mayReadFromMemory()) {
854 RemoveAccessedObjects(LoadedLoc, DeadStackObjects);
858 if (DeadStackObjects.
empty())
867 typedef Value *argument_type;
871 bool operator()(
Value *
I) {
874 return !AA->isNoAlias(StackLoc, LoadedLoc);
887 if (isa<Constant>(UnderlyingPointer))
892 if (isa<AllocaInst>(UnderlyingPointer) || isa<Argument>(UnderlyingPointer)) {
893 DeadStackObjects.
remove(const_cast<Value*>(UnderlyingPointer));
898 CouldAlias Pred = { LoadedLoc, AA };
unsigned getAlignment() const
const DataLayout * getDataLayout() const
void push_back(const T &Elt)
AnalysisUsage & addPreserved()
static PassRegistry * getPassRegistry()
void GetUnderlyingObjects(Value *V, SmallVectorImpl< Value * > &Objects, const DataLayout *TD=0, unsigned MaxLookup=6)
bool isReachableFromEntry(const BasicBlock *A) const
Intrinsic::ID getIntrinsicID() const
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned getNumOperands() const
static Location getLocationForSource(const MemTransferInst *MTI)
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout *TD)
const Function * getParent() const
Return the enclosing method, or null if none.
char *strcat(char *s1, const char *s2);
const Instruction & front() const
static uint64_t getPointerSize(const Value *V, AliasAnalysis &AA)
void initializeDSEPass(PassRegistry &)
static bool isShortenable(Instruction *I)
static OverwriteResult isOverwrite(const AliasAnalysis::Location &Later, const AliasAnalysis::Location &Earlier, AliasAnalysis &AA, int64_t &EarlierOff, int64_t &LaterOff)
ValTy * getArgument(unsigned ArgNo) const
const CallInst * isFreeCall(const Value *I, const TargetLibraryInfo *TLI)
isFreeCall - Returns non-null if the value is a call to the builtin free()
StringRef getName() const
Value * GetUnderlyingObject(Value *V, const DataLayout *TD=0, unsigned MaxLookup=6)
AnalysisUsage & addRequired()
bool isNoAlias(const Location &LocA, const Location &LocB)
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool has(LibFunc::Func F) const
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
#define llvm_unreachable(msg)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
ID
LLVM Calling Convention Representation.
bool remove(const value_type &X)
Remove an item from the set vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
static Value * getStoredPointerOperand(Instruction *I)
getStoredPointerOperand - Return the pointer that is being written to.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
static void DeleteDeadInstruction(Instruction *I, MemoryDependenceAnalysis &MD, const TargetLibraryInfo *TLI, SmallSetVector< Value *, 16 > *ValueSet=0)
bool empty() const
Determine if the SetVector is empty or not.
static bool hasMemoryWrite(Instruction *I, const TargetLibraryInfo *TLI)
static bool isPossibleSelfRead(Instruction *Inst, const AliasAnalysis::Location &InstStoreLoc, Instruction *DepWrite, AliasAnalysis &AA)
unsigned getNumSuccessors() const
static AliasAnalysis::Location getLocForRead(Instruction *Inst, AliasAnalysis &AA)
LLVM Basic Block Representation.
machine Machine Common Subexpression Elimination
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=0)
Interval::pred_iterator pred_begin(Interval *I)
ItTy next(ItTy it, Dist n)
static Location getLocationForDest(const MemIntrinsic *MI)
Value * getOperand(unsigned i) const
Interval::pred_iterator pred_end(Interval *I)
Location - A description of a memory location.
#define INITIALIZE_AG_DEPENDENCY(depName)
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures)
bool isMustAlias(const Location &LocA, const Location &LocB)
isMustAlias - A convenience wrapper.
A SetVector that performs no allocations if smaller than a certain size.
char *strncat(char *s1, const char *s2, size_t n);
FunctionPass * createDeadStoreEliminationPass()
STATISTIC(NumFastStores,"Number of stores deleted")
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Value * getLength() const
Value * stripPointerCasts()
Strips off any unneeded pointer casts, all-zero GEPs and aliases from the specified value...
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
static void FindUnconditionalPreds(SmallVectorImpl< BasicBlock * > &Blocks, BasicBlock *BB, DominatorTree *DT)
Value * getArgOperand(unsigned i) const
bool isPowerOf2_64(uint64_t Value)
Location getLocation(const LoadInst *LI)
Instruction * getInst() const
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
StringRef getName(LibFunc::Func F) const
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
const Value * Ptr
Ptr - The address of the start of the location.
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...
static uint64_t const UnknownSize
LLVM Value Representation.
bool remove_if(UnaryPredicate P)
Remove items from the set vector based on a predicate function.
static bool isRemovable(Instruction *I)
char *strcpy(char *s1, const char *s2);
const TargetLibraryInfo * getTargetLibraryInfo() const
static AliasAnalysis::Location getLocForWrite(Instruction *Inst, AliasAnalysis &AA)
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *DL, const TargetLibraryInfo *TLI, bool RoundToAlign=false)
Compute the size of the object pointed by Ptr. Returns true and the object size in Size if successful...
const BasicBlock * getParent() const
INITIALIZE_PASS(GlobalMerge,"global-merge","Global Merge", false, false) bool GlobalMerge const DataLayout * TD
void removeInstruction(Instruction *InstToRemove)
char *strncpy(char *s1, const char *s2, size_t n);