]> granicus.if.org Git - llvm/commitdiff
[PM] Teach LVI to correctly invalidate itself when its dependencies
authorChandler Carruth <chandlerc@gmail.com>
Mon, 23 Jan 2017 06:35:12 +0000 (06:35 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Mon, 23 Jan 2017 06:35:12 +0000 (06:35 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292769 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/LazyValueInfo.h
lib/Analysis/LazyValueInfo.cpp
lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
test/Analysis/LazyValueAnalysis/invalidation.ll [new file with mode: 0644]
test/Other/new-pm-defaults.ll

index 610791023a7dd7093db9ad48ff66cd78a67b6af8..ef0762079d924b62aac99c9e9c46df1734f84aab 100644 (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.
index d442310476cfbe3a2ebc1b201888925679b622b5..dc22b8173a85ddda1c99b51befba5a1809f3c4a8 100644 (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) {
index 141e99b92cdc1a1dbabe4908127429129d035cf6..60786a3373feb4683c055983c68d04cee40978de 100644 (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;
diff --git a/test/Analysis/LazyValueAnalysis/invalidation.ll b/test/Analysis/LazyValueAnalysis/invalidation.ll
new file mode 100644 (file)
index 0000000..21bfd2c
--- /dev/null
@@ -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
+}
index 0cbc18d01abd2b357b43dcd1b7003cce656df570..713cc022974a40a2605404489438f04354a822a5 100644 (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
 ; 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