LLVM  4.0.0
Macros | Typedefs | Enumerations | Functions | Variables
DeadStoreElimination.cpp File Reference
#include "llvm/Transforms/Scalar/DeadStoreElimination.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include <map>
Include dependency graph for DeadStoreElimination.cpp:

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "dse"
 

Typedefs

typedef std::map< int64_t,
int64_t > 
OverlapIntervalsTy
 
typedef DenseMap< Instruction
*, OverlapIntervalsTy
InstOverlapIntervalsTy
 

Enumerations

enum  OverwriteResult
 

Functions

 STATISTIC (NumRedundantStores,"Number of redundant stores deleted")
 
 STATISTIC (NumFastStores,"Number of stores deleted")
 
 STATISTIC (NumFastOther,"Number of other instrs removed")
 
 STATISTIC (NumCompletePartials,"Number of stores dead by later partials")
 
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. More...
 
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 other helpers below. More...
 
static MemoryLocation getLocForWrite (Instruction *Inst, AliasAnalysis &AA)
 Return a Location stored to by the specified instruction. More...
 
static MemoryLocation getLocForRead (Instruction *Inst, const TargetLibraryInfo &TLI)
 Return the location read by the specified "hasMemoryWrite" instruction if any. More...
 
static bool isRemovable (Instruction *I)
 If the value of this instruction and the memory it writes to is unused, may we delete this instruction? More...
 
static bool isShortenableAtTheEnd (Instruction *I)
 Returns true if the end of this instruction can be safely shortened in length. More...
 
static bool isShortenableAtTheBeginning (Instruction *I)
 Returns true if the beginning of this instruction can be safely shortened in length. More...
 
static ValuegetStoredPointerOperand (Instruction *I)
 Return the pointer that is being written to. More...
 
static uint64_t getPointerSize (const Value *V, const DataLayout &DL, const TargetLibraryInfo &TLI)
 
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 'Earlier' location, 'OverwriteEnd' if the end of the 'Earlier' location is completely overwritten by 'Later', 'OverwriteBegin' if the beginning of the 'Earlier' location is overwritten by 'Later', or 'OverwriteUnknown' if nothing can be determined. More...
 
static bool isPossibleSelfRead (Instruction *Inst, const MemoryLocation &InstStoreLoc, Instruction *DepWrite, const TargetLibraryInfo &TLI, AliasAnalysis &AA)
 If 'Inst' might be a self read (i.e. More...
 
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 first and the second instruction. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
static bool tryToShorten (Instruction *EarlierWrite, int64_t &EarlierOffset, int64_t &EarlierSize, int64_t LaterOffset, int64_t LaterSize, bool IsOverwriteEnd)
 
static bool tryToShortenEnd (Instruction *EarlierWrite, OverlapIntervalsTy &IntervalMap, int64_t &EarlierStart, int64_t &EarlierSize)
 
static bool tryToShortenBegin (Instruction *EarlierWrite, OverlapIntervalsTy &IntervalMap, int64_t &EarlierStart, int64_t &EarlierSize)
 
static bool removePartiallyOverlappedStores (AliasAnalysis *AA, const DataLayout &DL, InstOverlapIntervalsTy &IOL)
 
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)
 
static bool eliminateDeadStores (BasicBlock &BB, AliasAnalysis *AA, MemoryDependenceResults *MD, DominatorTree *DT, const TargetLibraryInfo *TLI)
 
static bool eliminateDeadStores (Function &F, AliasAnalysis *AA, MemoryDependenceResults *MD, DominatorTree *DT, const TargetLibraryInfo *TLI)
 
 INITIALIZE_PASS_BEGIN (DSELegacyPass,"dse","Dead Store Elimination", false, false) INITIALIZE_PASS_END(DSELegacyPass
 

Variables

static cl::opt< boolEnablePartialOverwriteTracking ("enable-dse-partial-overwrite-tracking", cl::init(true), cl::Hidden, cl::desc("Enable partial-overwrite tracking in DSE"))
 
 dse
 
Dead Store Elimination
 
Dead Store false
 

Macro Definition Documentation

#define DEBUG_TYPE   "dse"

Definition at line 46 of file DeadStoreElimination.cpp.

Typedef Documentation

Definition at line 63 of file DeadStoreElimination.cpp.

typedef std::map<int64_t, int64_t> OverlapIntervalsTy

Definition at line 62 of file DeadStoreElimination.cpp.

Enumeration Type Documentation

Definition at line 290 of file DeadStoreElimination.cpp.

Function Documentation

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 
)
static
static bool eliminateDeadStores ( BasicBlock BB,
AliasAnalysis AA,
MemoryDependenceResults MD,
DominatorTree DT,
const TargetLibraryInfo TLI 
)
static

Definition at line 993 of file DeadStoreElimination.cpp.

References assert(), llvm::BasicBlock::begin(), llvm::dbgs(), DEBUG, deleteDeadInstruction(), eliminateNoopStore(), EnablePartialOverwriteTracking, llvm::BasicBlock::end(), F, llvm::BasicBlock::front(), llvm::Module::getDataLayout(), llvm::MemoryDependenceResults::getDefaultBlockScanLimit(), llvm::MemoryDependenceResults::getDependency(), llvm::MemDepResult::getInst(), llvm::ilist_node_impl< OptionsT >::getIterator(), getLocForWrite(), llvm::AAResults::getModRefInfo(), llvm::BasicBlock::getModule(), llvm::TerminatorInst::getNumSuccessors(), llvm::MemoryDependenceResults::getPointerDependencyFrom(), llvm::BasicBlock::getTerminator(), llvm::GetUnderlyingObject(), handleEndBlock(), handleFree(), hasMemoryWrite(), llvm::DenseMapBase< DenseMap< KeyT, ValueT, KeyInfoT, BucketT >, KeyT, ValueT, KeyInfoT, BucketT >::insert(), llvm::isAllocLikeFn(), llvm::MemDepResult::isClobber(), llvm::MemDepResult::isDef(), llvm::isFreeCall(), isOverwrite(), isPossibleSelfRead(), isRemovable(), isShortenableAtTheBeginning(), isShortenableAtTheEnd(), llvm::DenseMapBase< DenseMap< KeyT, ValueT, KeyInfoT, BucketT >, KeyT, ValueT, KeyInfoT, BucketT >::lookup(), llvm::Instruction::mayThrow(), llvm::MRI_Ref, OR, llvm::PointerMayBeCaptured(), llvm::MemoryLocation::Ptr, removePartiallyOverlappedStores(), llvm::MemoryLocation::Size, tryToShorten(), and llvm::BitmaskEnumDetail::Underlying().

Referenced by eliminateDeadStores(), and llvm::DSEPass::run().

static bool eliminateDeadStores ( Function F,
AliasAnalysis AA,
MemoryDependenceResults MD,
DominatorTree DT,
const TargetLibraryInfo TLI 
)
static
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 
)
static
static void findUnconditionalPreds ( SmallVectorImpl< BasicBlock * > &  Blocks,
BasicBlock BB,
DominatorTree DT 
)
static
static MemoryLocation getLocForRead ( Instruction Inst,
const TargetLibraryInfo TLI 
)
static

Return the location read by the specified "hasMemoryWrite" instruction if any.

Definition at line 184 of file DeadStoreElimination.cpp.

References assert(), llvm::MemoryLocation::getForSource(), and hasMemoryWrite().

Referenced by isPossibleSelfRead().

static MemoryLocation getLocForWrite ( Instruction Inst,
AliasAnalysis AA 
)
static

Return a Location stored to by the specified instruction.

If isRemovable returns true, this function and getLocForRead completely describe the memory operations for this instruction.

Definition at line 154 of file DeadStoreElimination.cpp.

References llvm::dyn_cast(), llvm::MemoryLocation::get(), llvm::CallInst::getArgOperand(), llvm::MemoryLocation::getForDest(), llvm::IntrinsicInst::getIntrinsicID(), MI, and SI.

Referenced by eliminateDeadStores(), and removePartiallyOverlappedStores().

static uint64_t getPointerSize ( const Value V,
const DataLayout DL,
const TargetLibraryInfo TLI 
)
static
static Value* getStoredPointerOperand ( Instruction I)
static

Return the pointer that is being written to.

Definition at line 261 of file DeadStoreElimination.cpp.

References llvm::CallSiteBase< FunTy, BBTy, ValTy, UserTy, UseTy, InstrTy, CallTy, InvokeTy, IterTy >::getArgument(), llvm_unreachable, MI, and SI.

Referenced by handleEndBlock(), and handleFree().

static bool handleEndBlock ( BasicBlock BB,
AliasAnalysis AA,
MemoryDependenceResults MD,
const TargetLibraryInfo TLI,
InstOverlapIntervalsTy IOL,
DenseMap< Instruction *, size_t > *  InstrOrdering 
)
static
static bool handleFree ( CallInst F,
AliasAnalysis AA,
MemoryDependenceResults MD,
DominatorTree DT,
const TargetLibraryInfo TLI,
InstOverlapIntervalsTy IOL,
DenseMap< Instruction *, size_t > *  InstrOrdering 
)
static
static bool hasMemoryWrite ( Instruction I,
const TargetLibraryInfo TLI 
)
static

Does this instruction write some memory? This only returns true for things that we can analyze with other helpers below.

Definition at line 120 of file DeadStoreElimination.cpp.

References F, llvm::TargetLibraryInfo::getName(), and llvm::TargetLibraryInfo::has().

Referenced by eliminateDeadStores(), getLocForRead(), handleEndBlock(), and handleFree().

INITIALIZE_PASS_BEGIN ( DSELegacyPass  ,
"dse"  ,
"Dead Store Elimination ,
false  ,
false   
)
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 
)
static

Return 'OverwriteComplete' if a store to the 'Later' location completely overwrites a store to the 'Earlier' location, 'OverwriteEnd' if the end of the 'Earlier' location is completely overwritten by 'Later', 'OverwriteBegin' if the beginning of the 'Earlier' location is overwritten by 'Later', or 'OverwriteUnknown' if nothing can be determined.

Definition at line 303 of file DeadStoreElimination.cpp.

References assert(), llvm::dbgs(), DEBUG, EnablePartialOverwriteTracking, llvm::GetPointerBaseWithConstantOffset(), getPointerSize(), llvm::GetUnderlyingObject(), fuzzer::min(), llvm::MemoryLocation::Ptr, llvm::MemoryLocation::Size, llvm::Value::stripPointerCasts(), and llvm::MemoryLocation::UnknownSize.

Referenced by eliminateDeadStores().

static bool isPossibleSelfRead ( Instruction Inst,
const MemoryLocation InstStoreLoc,
Instruction DepWrite,
const TargetLibraryInfo TLI,
AliasAnalysis AA 
)
static

If 'Inst' might be a self read (i.e.

a noop copy of a memory region into an identical pointer) then it doesn't actually make its input dead in the traditional sense. Consider this case:

memcpy(A <- B) memcpy(A <- A)

In this case, the second store to A does not make the first store to A dead. The usual situation isn't an explicit A<-A store like this (which can be trivially removed) but a case where two pointers may alias.

This function detects when it is unsafe to remove a dependent instruction because the DSE inducing instruction may be a self-read.

Definition at line 481 of file DeadStoreElimination.cpp.

References getLocForRead(), llvm::AAResults::isMustAlias(), llvm::AAResults::isNoAlias(), and llvm::MemoryLocation::Ptr.

Referenced by eliminateDeadStores().

static bool isRemovable ( Instruction I)
static

If the value of this instruction and the memory it writes to is unused, may we delete this instruction?

Definition at line 197 of file DeadStoreElimination.cpp.

References isVolatile(), llvm_unreachable, and SI.

Referenced by eliminateDeadStores(), eliminateNoopStore(), handleEndBlock(), handleFree(), and removePartiallyOverlappedStores().

static bool isShortenableAtTheBeginning ( Instruction I)
static

Returns true if the beginning of this instruction can be safely shortened in length.

Definition at line 253 of file DeadStoreElimination.cpp.

References llvm::dyn_cast(), llvm::IntrinsicInst::getIntrinsicID(), and I.

Referenced by eliminateDeadStores(), and tryToShortenBegin().

static bool isShortenableAtTheEnd ( Instruction I)
static

Returns true if the end of this instruction can be safely shortened in length.

Definition at line 230 of file DeadStoreElimination.cpp.

Referenced by eliminateDeadStores(), and tryToShortenEnd().

static bool memoryIsNotModifiedBetween ( Instruction FirstI,
Instruction SecondI,
AliasAnalysis AA 
)
static
static void removeAccessedObjects ( const MemoryLocation LoadedLoc,
SmallSetVector< Value *, 16 > &  DeadStackObjects,
const DataLayout DL,
AliasAnalysis AA,
const TargetLibraryInfo TLI 
)
static

Check to see if the specified location may alias any of the stack objects in the DeadStackObjects set.

If so, they become live because the location is being loaded.

Definition at line 647 of file DeadStoreElimination.cpp.

References getPointerSize(), llvm::GetUnderlyingObject(), I, llvm::AAResults::isNoAlias(), llvm::MemoryLocation::Ptr, llvm::SetVector< T, SmallVector< T, N >, SmallDenseSet< T, N > >::remove(), and llvm::SetVector< T, SmallVector< T, N >, SmallDenseSet< T, N > >::remove_if().

Referenced by handleEndBlock().

static bool removePartiallyOverlappedStores ( AliasAnalysis AA,
const DataLayout DL,
InstOverlapIntervalsTy IOL 
)
static
STATISTIC ( NumRedundantStores  ,
"Number of redundant stores deleted"   
)
STATISTIC ( NumFastStores  ,
"Number of stores deleted"   
)
STATISTIC ( NumFastOther  ,
"Number of other instrs removed"   
)
STATISTIC ( NumCompletePartials  ,
"Number of stores dead by later partials"   
)
static bool tryToShorten ( Instruction EarlierWrite,
int64_t &  EarlierOffset,
int64_t &  EarlierSize,
int64_t  LaterOffset,
int64_t  LaterSize,
bool  IsOverwriteEnd 
)
static
static bool tryToShortenBegin ( Instruction EarlierWrite,
OverlapIntervalsTy IntervalMap,
int64_t &  EarlierStart,
int64_t &  EarlierSize 
)
static
static bool tryToShortenEnd ( Instruction EarlierWrite,
OverlapIntervalsTy IntervalMap,
int64_t &  EarlierStart,
int64_t &  EarlierSize 
)
static

Definition at line 879 of file DeadStoreElimination.cpp.

References isShortenableAtTheEnd(), and tryToShorten().

Referenced by removePartiallyOverlappedStores().

Variable Documentation

dse

Definition at line 1241 of file DeadStoreElimination.cpp.

Dead Store Elimination

Definition at line 1241 of file DeadStoreElimination.cpp.

cl::opt<bool> EnablePartialOverwriteTracking("enable-dse-partial-overwrite-tracking", cl::init(true), cl::Hidden, cl::desc("Enable partial-overwrite tracking in DSE"))
static

Referenced by eliminateDeadStores(), and isOverwrite().

Dead Store false

Definition at line 1241 of file DeadStoreElimination.cpp.