[PM] Teach LVI to correctly invalidate itself when its dependencies

become unavailable.

The AssumptionCache is now immutable but it still needs to respond to
DomTree invalidation if it ended up caching one.

This lets us remove one of the explicit invalidates of LVI but the
other one continues to avoid hitting a latent bug.

llvm-svn: 292769
This commit is contained in:
Chandler Carruth 2017-01-23 06:35:12 +00:00
parent b06bcde1ab
commit a504f2b8e8
5 changed files with 80 additions and 7 deletions

View File

@ -100,6 +100,10 @@ public:
// For old PM pass. Delete once LazyValueInfoWrapperPass is gone.
void releaseMemory();
/// Handle invalidation events in the new pass manager.
bool invalidate(Function &F, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &Inv);
};
/// \brief Analysis to compute lazy value information.

View File

@ -1503,6 +1503,18 @@ void LazyValueInfo::releaseMemory() {
}
}
bool LazyValueInfo::invalidate(Function &F, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &Inv) {
// We need to invalidate if we have either failed to preserve this analyses
// result directly or if any of its dependencies have been invalidated.
auto PAC = PA.getChecker<LazyValueAnalysis>();
if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>()) ||
(DT && Inv.invalidate<DominatorTreeAnalysis>(F, PA)))
return true;
return false;
}
void LazyValueInfoWrapperPass::releaseMemory() { Info.releaseMemory(); }
LazyValueInfo LazyValueAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {

View File

@ -565,10 +565,6 @@ CorrelatedValuePropagationPass::run(Function &F, FunctionAnalysisManager &AM) {
LazyValueInfo *LVI = &AM.getResult<LazyValueAnalysis>(F);
bool Changed = runImpl(F, LVI);
// FIXME: We need to invalidate LVI to avoid PR28400. Is there a better
// solution?
AM.invalidate<LazyValueAnalysis>(F);
if (!Changed)
return PreservedAnalyses::all();
PreservedAnalyses PA;

View File

@ -0,0 +1,64 @@
; Test that the lazy value analysis gets invalidated when its dependencies go
; away. Sadly, you can neither print nor verify LVI so we just have to require
; it and check that the pass manager does the right thing.
;
; Check basic invalidation.
; RUN: opt -disable-output -disable-verify -debug-pass-manager %s 2>&1 \
; RUN: -passes='require<lazy-value-info>,invalidate<lazy-value-info>,require<lazy-value-info>' \
; RUN: | FileCheck %s --check-prefix=CHECK-INVALIDATE
; CHECK-INVALIDATE: Running pass: RequireAnalysisPass
; CHECK-INVALIDATE: Running analysis: LazyValueAnalysis
; CHECK-INVALIDATE: Running pass: InvalidateAnalysisPass
; CHECK-INVALIDATE: Invalidating analysis: LazyValueAnalysis
; CHECK-INVALIDATE: Running pass: RequireAnalysisPass
; CHECK-INVALIDATE: Running analysis: LazyValueAnalysis
;
; Check DomTree specifically.
; RUN: opt -disable-output -disable-verify -debug-pass-manager %s 2>&1 \
; RUN: -passes='require<domtree>,require<lazy-value-info>,invalidate<domtree>,require<lazy-value-info>' \
; RUN: | FileCheck %s --check-prefix=CHECK-DT-INVALIDATE
; CHECK-DT-INVALIDATE: Running pass: RequireAnalysisPass
; CHECK-DT-INVALIDATE: Running analysis: LazyValueAnalysis
; CHECK-DT-INVALIDATE: Running pass: InvalidateAnalysisPass
; CHECK-DT-INVALIDATE: Invalidating analysis: DominatorTreeAnalysis
; CHECK-DT-INVALIDATE: Invalidating analysis: LazyValueAnalysis
; CHECK-AC-INVALIDATE: Running pass: RequireAnalysisPass
; CHECK-DT-INVALIDATE: Running analysis: LazyValueAnalysis
target triple = "x86_64-unknown-linux-gnu"
@.str = private unnamed_addr constant [8 x i8] c"a = %l\0A\00", align 1
declare void @llvm.lifetime.start(i64, i8* nocapture)
declare void @hoo(i64*)
declare i32 @printf(i8* nocapture readonly, ...)
declare void @llvm.lifetime.end(i64, i8* nocapture)
define void @goo(i32 %N, i64* %b) {
entry:
%a.i = alloca i64, align 8
%tmp = bitcast i64* %a.i to i8*
%c = getelementptr inbounds i64, i64* %b, i64 0
br label %for.cond
for.cond: ; preds = %for.body, %entry
%i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
%cmp = icmp slt i32 %i.0, %N
br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
call void @llvm.lifetime.start(i64 8, i8* %tmp)
call void @hoo(i64* %a.i)
call void @hoo(i64* %c)
%tmp1 = load volatile i64, i64* %a.i, align 8
%call.i = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i64 %tmp1)
call void @llvm.lifetime.end(i64 8, i8* %tmp)
%inc = add nsw i32 %i.0, 1
br label %for.cond
for.end: ; preds = %for.cond
ret void
}

View File

@ -76,7 +76,6 @@
; CHECK-O-NEXT: Invalidating analysis: LazyValueAnalysis
; CHECK-O-NEXT: Running pass: CorrelatedValuePropagationPass
; CHECK-O-NEXT: Running analysis: LazyValueAnalysis
; CHECK-O-NEXT: Invalidating analysis: LazyValueAnalysis
; CHECK-O-NEXT: Running pass: SimplifyCFGPass
; CHECK-O-NEXT: Running pass: InstCombinePass
; CHECK-O1-NEXT: Running pass: LibCallsShrinkWrapPass
@ -112,11 +111,9 @@
; CHECK-O-NEXT: Running analysis: DemandedBitsAnalysis
; CHECK-O-NEXT: Running pass: InstCombinePass
; CHECK-O-NEXT: Running pass: JumpThreadingPass
; CHECK-O-NEXT: Running analysis: LazyValueAnalysis
; CHECK-O-NEXT: Invalidating analysis: LazyValueAnalysis
; CHECK-O-NEXT: Running pass: CorrelatedValuePropagationPass
; CHECK-O-NEXT: Running analysis: LazyValueAnalysis
; CHECK-O-NEXT: Invalidating analysis: LazyValueAnalysis
; CHECK-O-NEXT: Running pass: DSEPass
; CHECK-O-NEXT: Running pass: ADCEPass
; CHECK-O-NEXT: Running analysis: PostDominatorTreeAnalysis