mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[MemDepAnalysis] Allow caller to pass in an OrderedBasicBlock.
If the caller can preserve the OBB, we can avoid recomputing the order for each getDependency call. Reviewers: efriedma, rnk, hfinkel Reviewed By: rnk Differential Revision: https://reviews.llvm.org/D59788 llvm-svn: 357206
This commit is contained in:
parent
6ff8220b91
commit
9641845c3d
@ -381,7 +381,8 @@ public:
|
||||
///
|
||||
/// See the class comment for more details. It is illegal to call this on
|
||||
/// non-memory instructions.
|
||||
MemDepResult getDependency(Instruction *QueryInst);
|
||||
MemDepResult getDependency(Instruction *QueryInst,
|
||||
OrderedBasicBlock *OBB = nullptr);
|
||||
|
||||
/// Perform a full dependency query for the specified call, returning the set
|
||||
/// of blocks that the value is potentially live across.
|
||||
@ -447,14 +448,14 @@ public:
|
||||
BasicBlock::iterator ScanIt,
|
||||
BasicBlock *BB,
|
||||
Instruction *QueryInst = nullptr,
|
||||
unsigned *Limit = nullptr);
|
||||
unsigned *Limit = nullptr,
|
||||
OrderedBasicBlock *OBB = nullptr);
|
||||
|
||||
MemDepResult getSimplePointerDependencyFrom(const MemoryLocation &MemLoc,
|
||||
bool isLoad,
|
||||
BasicBlock::iterator ScanIt,
|
||||
BasicBlock *BB,
|
||||
Instruction *QueryInst,
|
||||
unsigned *Limit = nullptr);
|
||||
MemDepResult
|
||||
getSimplePointerDependencyFrom(const MemoryLocation &MemLoc, bool isLoad,
|
||||
BasicBlock::iterator ScanIt, BasicBlock *BB,
|
||||
Instruction *QueryInst, unsigned *Limit,
|
||||
OrderedBasicBlock *OBB);
|
||||
|
||||
/// This analysis looks for other loads and stores with invariant.group
|
||||
/// metadata and the same pointer operand. Returns Unknown if it does not
|
||||
|
@ -326,7 +326,8 @@ static bool isVolatile(Instruction *Inst) {
|
||||
|
||||
MemDepResult MemoryDependenceResults::getPointerDependencyFrom(
|
||||
const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt,
|
||||
BasicBlock *BB, Instruction *QueryInst, unsigned *Limit) {
|
||||
BasicBlock *BB, Instruction *QueryInst, unsigned *Limit,
|
||||
OrderedBasicBlock *OBB) {
|
||||
MemDepResult InvariantGroupDependency = MemDepResult::getUnknown();
|
||||
if (QueryInst != nullptr) {
|
||||
if (auto *LI = dyn_cast<LoadInst>(QueryInst)) {
|
||||
@ -337,7 +338,7 @@ MemDepResult MemoryDependenceResults::getPointerDependencyFrom(
|
||||
}
|
||||
}
|
||||
MemDepResult SimpleDep = getSimplePointerDependencyFrom(
|
||||
MemLoc, isLoad, ScanIt, BB, QueryInst, Limit);
|
||||
MemLoc, isLoad, ScanIt, BB, QueryInst, Limit, OBB);
|
||||
if (SimpleDep.isDef())
|
||||
return SimpleDep;
|
||||
// Non-local invariant group dependency indicates there is non local Def
|
||||
@ -438,14 +439,13 @@ MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,
|
||||
|
||||
MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
|
||||
const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt,
|
||||
BasicBlock *BB, Instruction *QueryInst, unsigned *Limit) {
|
||||
BasicBlock *BB, Instruction *QueryInst, unsigned *Limit,
|
||||
OrderedBasicBlock *OBB) {
|
||||
bool isInvariantLoad = false;
|
||||
|
||||
if (!Limit) {
|
||||
unsigned DefaultLimit = BlockScanLimit;
|
||||
return getSimplePointerDependencyFrom(MemLoc, isLoad, ScanIt, BB, QueryInst,
|
||||
&DefaultLimit);
|
||||
}
|
||||
unsigned DefaultLimit = BlockScanLimit;
|
||||
if (!Limit)
|
||||
Limit = &DefaultLimit;
|
||||
|
||||
// We must be careful with atomic accesses, as they may allow another thread
|
||||
// to touch this location, clobbering it. We are conservative: if the
|
||||
@ -487,11 +487,14 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
|
||||
|
||||
const DataLayout &DL = BB->getModule()->getDataLayout();
|
||||
|
||||
// Create a numbered basic block to lazily compute and cache instruction
|
||||
// If the caller did not provide an ordered basic block,
|
||||
// create one to lazily compute and cache instruction
|
||||
// positions inside a BB. This is used to provide fast queries for relative
|
||||
// position between two instructions in a BB and can be used by
|
||||
// AliasAnalysis::callCapturesBefore.
|
||||
OrderedBasicBlock OBB(BB);
|
||||
OrderedBasicBlock OBBTmp(BB);
|
||||
if (!OBB)
|
||||
OBB = &OBBTmp;
|
||||
|
||||
// Return "true" if and only if the instruction I is either a non-simple
|
||||
// load or a non-simple store.
|
||||
@ -682,7 +685,7 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
|
||||
ModRefInfo MR = AA.getModRefInfo(Inst, MemLoc);
|
||||
// If necessary, perform additional analysis.
|
||||
if (isModAndRefSet(MR))
|
||||
MR = AA.callCapturesBefore(Inst, MemLoc, &DT, &OBB);
|
||||
MR = AA.callCapturesBefore(Inst, MemLoc, &DT, OBB);
|
||||
switch (clearMust(MR)) {
|
||||
case ModRefInfo::NoModRef:
|
||||
// If the call has no effect on the queried pointer, just ignore it.
|
||||
@ -708,7 +711,8 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
|
||||
return MemDepResult::getNonFuncLocal();
|
||||
}
|
||||
|
||||
MemDepResult MemoryDependenceResults::getDependency(Instruction *QueryInst) {
|
||||
MemDepResult MemoryDependenceResults::getDependency(Instruction *QueryInst,
|
||||
OrderedBasicBlock *OBB) {
|
||||
Instruction *ScanPos = QueryInst;
|
||||
|
||||
// Check for a cached result
|
||||
@ -746,8 +750,9 @@ MemDepResult MemoryDependenceResults::getDependency(Instruction *QueryInst) {
|
||||
if (auto *II = dyn_cast<IntrinsicInst>(QueryInst))
|
||||
isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_start;
|
||||
|
||||
LocalCache = getPointerDependencyFrom(
|
||||
MemLoc, isLoad, ScanPos->getIterator(), QueryParent, QueryInst);
|
||||
LocalCache =
|
||||
getPointerDependencyFrom(MemLoc, isLoad, ScanPos->getIterator(),
|
||||
QueryParent, QueryInst, nullptr, OBB);
|
||||
} else if (auto *QueryCall = dyn_cast<CallBase>(QueryInst)) {
|
||||
bool isReadOnly = AA.onlyReadsMemory(QueryCall);
|
||||
LocalCache = getCallDependencyFrom(QueryCall, isReadOnly,
|
||||
|
Loading…
Reference in New Issue
Block a user