mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-26 05:00:39 +00:00
fix an overly conservative caching issue that caused memdep to
cache a pointer as being unavailable due to phi trans in the wrong place. This would cause later queries to fail even when they didn't involve phi trans. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91787 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b310839aed
commit
f648125be9
@ -894,36 +894,12 @@ getNonLocalPointerDepFromBB(const PHITransAddr &Pointer, uint64_t PointeeSize,
|
||||
PredPtrVal);
|
||||
Result.push_back(Entry);
|
||||
|
||||
// Add it to the cache for this CacheKey so that subsequent queries get
|
||||
// this result.
|
||||
Cache = &NonLocalPointerDeps[CacheKey].second;
|
||||
MemoryDependenceAnalysis::NonLocalDepInfo::iterator It =
|
||||
std::upper_bound(Cache->begin(), Cache->end(), Entry);
|
||||
|
||||
if (It != Cache->begin() && (It-1)->getBB() == Pred)
|
||||
--It;
|
||||
|
||||
if (It == Cache->end() || It->getBB() != Pred) {
|
||||
Cache->insert(It, Entry);
|
||||
// Add it to the reverse map.
|
||||
ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey);
|
||||
} else if (!It->getResult().isDirty()) {
|
||||
// noop
|
||||
} else if (It->getResult().getInst() == Pred->getTerminator()) {
|
||||
// Same instruction, clear the dirty marker.
|
||||
It->setResult(Entry.getResult(), PredPtrVal);
|
||||
} else if (It->getResult().getInst() == 0) {
|
||||
// Dirty, with no instruction, just add this.
|
||||
It->setResult(Entry.getResult(), PredPtrVal);
|
||||
ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey);
|
||||
} else {
|
||||
// Otherwise, dirty with a different instruction.
|
||||
RemoveFromReverseMap(ReverseNonLocalPtrDeps,
|
||||
It->getResult().getInst(), CacheKey);
|
||||
It->setResult(Entry.getResult(),PredPtrVal);
|
||||
ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey);
|
||||
}
|
||||
Cache = 0;
|
||||
// Since we had a phi translation failure, the cache for CacheKey won't
|
||||
// include all of the entries that we need to immediately satisfy future
|
||||
// queries. Mark this in NonLocalPointerDeps by setting the
|
||||
// BBSkipFirstBlockPair pointer to null. This requires reuse of the
|
||||
// cached value to do more work but not miss the phi trans failure.
|
||||
NonLocalPointerDeps[CacheKey].first = BBSkipFirstBlockPair();
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -961,10 +937,10 @@ getNonLocalPointerDepFromBB(const PHITransAddr &Pointer, uint64_t PointeeSize,
|
||||
NumSortedEntries = Cache->size();
|
||||
}
|
||||
|
||||
// Since we did phi translation, the "Cache" set won't contain all of the
|
||||
// Since we failed phi translation, the "Cache" set won't contain all of the
|
||||
// results for the query. This is ok (we can still use it to accelerate
|
||||
// specific block queries) but we can't do the fastpath "return all
|
||||
// results from the set" Clear out the indicator for this.
|
||||
// results from the set". Clear out the indicator for this.
|
||||
CacheInfo->first = BBSkipFirstBlockPair();
|
||||
|
||||
// If *nothing* works, mark the pointer as being clobbered by the first
|
||||
|
@ -112,3 +112,35 @@ bb2:
|
||||
ret i32 %dv
|
||||
}
|
||||
|
||||
|
||||
|
||||
; void test5(int N, double* G) {
|
||||
; for (long j = 1; j < 1000; j++)
|
||||
; G[j] = G[j] + G[j-1];
|
||||
; }
|
||||
;
|
||||
; Should compile into one load in the loop.
|
||||
define void @test5(i32 %N, double* nocapture %G) nounwind ssp {
|
||||
; CHECK: @test5
|
||||
bb.nph:
|
||||
br label %for.body
|
||||
|
||||
for.body:
|
||||
%indvar = phi i64 [ 0, %bb.nph ], [ %tmp, %for.body ]
|
||||
%arrayidx6 = getelementptr double* %G, i64 %indvar
|
||||
%tmp = add i64 %indvar, 1
|
||||
%arrayidx = getelementptr double* %G, i64 %tmp
|
||||
%tmp3 = load double* %arrayidx
|
||||
%tmp7 = load double* %arrayidx6
|
||||
%add = fadd double %tmp3, %tmp7
|
||||
store double %add, double* %arrayidx
|
||||
%exitcond = icmp eq i64 %tmp, 999
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
; CHECK: for.body:
|
||||
; CHECK: phi double
|
||||
; CHECK: load double
|
||||
; CHECK-NOT: load double
|
||||
; CHECK: br i1
|
||||
for.end:
|
||||
ret void
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user