///
/// 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.
BasicBlock::iterator ScanIt,
BasicBlock *BB,
Instruction *QueryInst = nullptr,
- unsigned *Limit = nullptr);
-
- MemDepResult getSimplePointerDependencyFrom(const MemoryLocation &MemLoc,
- bool isLoad,
- BasicBlock::iterator ScanIt,
- BasicBlock *BB,
- Instruction *QueryInst,
- 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,
+ 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
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)) {
}
}
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
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
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.
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.
return MemDepResult::getNonFuncLocal();
}
-MemDepResult MemoryDependenceResults::getDependency(Instruction *QueryInst) {
+MemDepResult MemoryDependenceResults::getDependency(Instruction *QueryInst,
+ OrderedBasicBlock *OBB) {
Instruction *ScanPos = QueryInst;
// Check for a cached result
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,