#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/PHITransAddr.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PredIteratorCache.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/Value.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include <algorithm>
#include <cassert>
#include <iterator>
#include <utility>
usingnamespacellvm;
#define DEBUG_TYPE …
STATISTIC(NumCacheNonLocal, "Number of fully cached non-local responses");
STATISTIC(NumCacheDirtyNonLocal, "Number of dirty cached non-local responses");
STATISTIC(NumUncacheNonLocal, "Number of uncached non-local responses");
STATISTIC(NumCacheNonLocalPtr,
"Number of fully cached non-local ptr responses");
STATISTIC(NumCacheDirtyNonLocalPtr,
"Number of cached, but dirty, non-local ptr responses");
STATISTIC(NumUncacheNonLocalPtr, "Number of uncached non-local ptr responses");
STATISTIC(NumCacheCompleteNonLocalPtr,
"Number of block queries that were completely cached");
static cl::opt<unsigned> BlockScanLimit(
"memdep-block-scan-limit", cl::Hidden, cl::init(100),
cl::desc("The number of instructions to scan in a block in memory "
"dependency analysis (default = 100)"));
static cl::opt<unsigned>
BlockNumberLimit("memdep-block-number-limit", cl::Hidden, cl::init(200),
cl::desc("The number of blocks to scan during memory "
"dependency analysis (default = 200)"));
static const unsigned int NumResultsLimit = …;
template <typename KeyTy>
static void
RemoveFromReverseMap(DenseMap<Instruction *, SmallPtrSet<KeyTy, 4>> &ReverseMap,
Instruction *Inst, KeyTy Val) { … }
static ModRefInfo GetLocation(const Instruction *Inst, MemoryLocation &Loc,
const TargetLibraryInfo &TLI) { … }
MemDepResult MemoryDependenceResults::getCallDependencyFrom(
CallBase *Call, bool isReadOnlyCall, BasicBlock::iterator ScanIt,
BasicBlock *BB) { … }
MemDepResult MemoryDependenceResults::getPointerDependencyFrom(
const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt,
BasicBlock *BB, Instruction *QueryInst, unsigned *Limit,
BatchAAResults &BatchAA) { … }
MemDepResult MemoryDependenceResults::getPointerDependencyFrom(
const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt,
BasicBlock *BB, Instruction *QueryInst, unsigned *Limit) { … }
MemDepResult
MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,
BasicBlock *BB) { … }
static bool canSkipClobberingStore(const StoreInst *SI,
const MemoryLocation &MemLoc,
Align MemLocAlign, BatchAAResults &BatchAA,
unsigned ScanLimit) { … }
MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt,
BasicBlock *BB, Instruction *QueryInst, unsigned *Limit,
BatchAAResults &BatchAA) { … }
MemDepResult MemoryDependenceResults::getDependency(Instruction *QueryInst) { … }
#ifndef NDEBUG
static void AssertSorted(MemoryDependenceResults::NonLocalDepInfo &Cache,
int Count = -1) {
if (Count == -1)
Count = Cache.size();
assert(std::is_sorted(Cache.begin(), Cache.begin() + Count) &&
"Cache isn't sorted!");
}
#endif
const MemoryDependenceResults::NonLocalDepInfo &
MemoryDependenceResults::getNonLocalCallDependency(CallBase *QueryCall) { … }
void MemoryDependenceResults::getNonLocalPointerDependency(
Instruction *QueryInst, SmallVectorImpl<NonLocalDepResult> &Result) { … }
MemDepResult MemoryDependenceResults::getNonLocalInfoForBlock(
Instruction *QueryInst, const MemoryLocation &Loc, bool isLoad,
BasicBlock *BB, NonLocalDepInfo *Cache, unsigned NumSortedEntries,
BatchAAResults &BatchAA) { … }
static void
SortNonLocalDepInfoCache(MemoryDependenceResults::NonLocalDepInfo &Cache,
unsigned NumSortedEntries) { … }
bool MemoryDependenceResults::getNonLocalPointerDepFromBB(
Instruction *QueryInst, const PHITransAddr &Pointer,
const MemoryLocation &Loc, bool isLoad, BasicBlock *StartBB,
SmallVectorImpl<NonLocalDepResult> &Result,
DenseMap<BasicBlock *, Value *> &Visited, bool SkipFirstBlock,
bool IsIncomplete) { … }
void MemoryDependenceResults::removeCachedNonLocalPointerDependencies(
ValueIsLoadPair P) { … }
void MemoryDependenceResults::invalidateCachedPointerInfo(Value *Ptr) { … }
void MemoryDependenceResults::invalidateCachedPredecessors() { … }
void MemoryDependenceResults::removeInstruction(Instruction *RemInst) { … }
void MemoryDependenceResults::verifyRemoved(Instruction *D) const { … }
AnalysisKey MemoryDependenceAnalysis::Key;
MemoryDependenceAnalysis::MemoryDependenceAnalysis()
: … { … }
MemoryDependenceResults
MemoryDependenceAnalysis::run(Function &F, FunctionAnalysisManager &AM) { … }
char MemoryDependenceWrapperPass::ID = …;
INITIALIZE_PASS_BEGIN(MemoryDependenceWrapperPass, "memdep",
"Memory Dependence Analysis", false, true)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_END(MemoryDependenceWrapperPass, "memdep",
"Memory Dependence Analysis", false, true)
MemoryDependenceWrapperPass::MemoryDependenceWrapperPass() : … { … }
MemoryDependenceWrapperPass::~MemoryDependenceWrapperPass() = default;
void MemoryDependenceWrapperPass::releaseMemory() { … }
void MemoryDependenceWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { … }
bool MemoryDependenceResults::invalidate(Function &F, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &Inv) { … }
unsigned MemoryDependenceResults::getDefaultBlockScanLimit() const { … }
bool MemoryDependenceWrapperPass::runOnFunction(Function &F) { … }