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:
Chris Lattner 2009-12-19 21:29:22 +00:00
parent b310839aed
commit f648125be9
2 changed files with 40 additions and 32 deletions

View File

@ -894,36 +894,12 @@ getNonLocalPointerDepFromBB(const PHITransAddr &Pointer, uint64_t PointeeSize,
PredPtrVal); PredPtrVal);
Result.push_back(Entry); Result.push_back(Entry);
// Add it to the cache for this CacheKey so that subsequent queries get // Since we had a phi translation failure, the cache for CacheKey won't
// this result. // include all of the entries that we need to immediately satisfy future
Cache = &NonLocalPointerDeps[CacheKey].second; // queries. Mark this in NonLocalPointerDeps by setting the
MemoryDependenceAnalysis::NonLocalDepInfo::iterator It = // BBSkipFirstBlockPair pointer to null. This requires reuse of the
std::upper_bound(Cache->begin(), Cache->end(), Entry); // cached value to do more work but not miss the phi trans failure.
NonLocalPointerDeps[CacheKey].first = BBSkipFirstBlockPair();
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;
continue; continue;
} }
@ -961,10 +937,10 @@ getNonLocalPointerDepFromBB(const PHITransAddr &Pointer, uint64_t PointeeSize,
NumSortedEntries = Cache->size(); 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 // 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 // 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(); CacheInfo->first = BBSkipFirstBlockPair();
// If *nothing* works, mark the pointer as being clobbered by the first // If *nothing* works, mark the pointer as being clobbered by the first

View File

@ -112,3 +112,35 @@ bb2:
ret i32 %dv 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
}