Index: llvm/trunk/include/llvm/Analysis/AliasAnalysis.h =================================================================== --- llvm/trunk/include/llvm/Analysis/AliasAnalysis.h +++ llvm/trunk/include/llvm/Analysis/AliasAnalysis.h @@ -197,6 +197,20 @@ AAs.emplace_back(new Model(AAResult, *this)); } + /// Register a function analysis ID that the results aggregation depends on. + /// + /// This is used in the new pass manager to implement the invalidation logic + /// where we must invalidate the results aggregation if any of our component + /// analyses become invalid. + void addAADependencyID(AnalysisKey *ID) { AADeps.push_back(ID); } + + /// Handle invalidation events in the new pass manager. + /// + /// The aggregation is invalidated if any of the underlying analyses is + /// invalidated. + bool invalidate(Function &F, const PreservedAnalyses &PA, + FunctionAnalysisManager::Invalidator &Inv); + //===--------------------------------------------------------------------===// /// \name Alias Queries /// @{ @@ -609,6 +623,8 @@ const TargetLibraryInfo &TLI; std::vector> AAs; + + std::vector AADeps; }; /// Temporary typedef for legacy code that uses a generic \c AliasAnalysis @@ -922,15 +938,19 @@ FunctionAnalysisManager &AM, AAResults &AAResults) { AAResults.addAAResult(AM.template getResult(F)); + AAResults.addAADependencyID(AnalysisT::ID()); } template static void getModuleAAResultImpl(Function &F, FunctionAnalysisManager &AM, AAResults &AAResults) { - auto &MAM = - AM.getResult(F).getManager(); - if (auto *R = MAM.template getCachedResult(*F.getParent())) + auto &MAMProxy = AM.getResult(F); + auto &MAM = MAMProxy.getManager(); + if (auto *R = MAM.template getCachedResult(*F.getParent())) { AAResults.addAAResult(*R); + MAMProxy + .template registerOuterAnalysisInvalidation(); + } } }; Index: llvm/trunk/include/llvm/IR/PassManager.h =================================================================== --- llvm/trunk/include/llvm/IR/PassManager.h +++ llvm/trunk/include/llvm/IR/PassManager.h @@ -1218,11 +1218,9 @@ /// context requires. template PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM, ExtraArgTs &&...) { - // We have to directly invalidate the analysis result as we can't - // enumerate all other analyses and use the preserved set to control it. - AM.template invalidate(Arg); - - return PreservedAnalyses::all(); + auto PA = PreservedAnalyses::all(); + PA.abandon(); + return PA; } }; Index: llvm/trunk/lib/Analysis/AliasAnalysis.cpp =================================================================== --- llvm/trunk/lib/Analysis/AliasAnalysis.cpp +++ llvm/trunk/lib/Analysis/AliasAnalysis.cpp @@ -53,7 +53,8 @@ static cl::opt DisableBasicAA("disable-basicaa", cl::Hidden, cl::init(false)); -AAResults::AAResults(AAResults &&Arg) : TLI(Arg.TLI), AAs(std::move(Arg.AAs)) { +AAResults::AAResults(AAResults &&Arg) + : TLI(Arg.TLI), AAs(std::move(Arg.AAs)), AADeps(std::move(Arg.AADeps)) { for (auto &AA : AAs) AA->setAAResults(this); } @@ -69,6 +70,25 @@ #endif } +bool AAResults::invalidate(Function &F, const PreservedAnalyses &PA, + FunctionAnalysisManager::Invalidator &Inv) { + if (PA.areAllPreserved()) + return false; // Nothing to do, everything is still valid. + + // Check if the AA manager itself has been invalidated. + auto PAC = PA.getChecker(); + if (!PAC.preserved() && !PAC.preservedSet>()) + return true; // The manager needs to be blown away, clear everything. + + // Check all of the dependencies registered. + for (AnalysisKey *ID : AADeps) + if (Inv.invalidate(ID, F, PA)) + return true; + + // Everything we depend on is still fine, so are we. Nothing to invalidate. + return false; +} + //===----------------------------------------------------------------------===// // Default chaining methods //===----------------------------------------------------------------------===// Index: llvm/trunk/test/Other/new-pass-manager.ll =================================================================== --- llvm/trunk/test/Other/new-pass-manager.ll +++ llvm/trunk/test/Other/new-pass-manager.ll @@ -49,7 +49,7 @@ ; CHECK-MODULE-PRINT: Running pass: VerifierPass ; CHECK-MODULE-PRINT: Running pass: PrintModulePass ; CHECK-MODULE-PRINT: ModuleID -; CHECK-MODULE-PRINT: define void @foo(i1 %x) +; CHECK-MODULE-PRINT: define void @foo(i1 %x, i8* %p1, i8* %p2) ; CHECK-MODULE-PRINT: Running pass: VerifierPass ; CHECK-MODULE-PRINT: Finished llvm::Module pass manager run @@ -58,7 +58,7 @@ ; CHECK-MODULE-VERIFY: Starting llvm::Module pass manager run ; CHECK-MODULE-VERIFY: Running pass: PrintModulePass ; CHECK-MODULE-VERIFY: ModuleID -; CHECK-MODULE-VERIFY: define void @foo(i1 %x) +; CHECK-MODULE-VERIFY: define void @foo(i1 %x, i8* %p1, i8* %p2) ; CHECK-MODULE-VERIFY: Running pass: VerifierPass ; CHECK-MODULE-VERIFY: Finished llvm::Module pass manager run @@ -71,7 +71,7 @@ ; CHECK-FUNCTION-PRINT: Starting llvm::Function pass manager run ; CHECK-FUNCTION-PRINT: Running pass: PrintFunctionPass ; CHECK-FUNCTION-PRINT-NOT: ModuleID -; CHECK-FUNCTION-PRINT: define void @foo(i1 %x) +; CHECK-FUNCTION-PRINT: define void @foo(i1 %x, i8* %p1, i8* %p2) ; CHECK-FUNCTION-PRINT: Finished llvm::Function pass manager run ; CHECK-FUNCTION-PRINT: Running pass: VerifierPass ; CHECK-FUNCTION-PRINT: Finished llvm::Module pass manager run @@ -82,17 +82,19 @@ ; CHECK-FUNCTION-VERIFY: Starting llvm::Function pass manager run ; CHECK-FUNCTION-VERIFY: Running pass: PrintFunctionPass ; CHECK-FUNCTION-VERIFY-NOT: ModuleID -; CHECK-FUNCTION-VERIFY: define void @foo(i1 %x) +; CHECK-FUNCTION-VERIFY: define void @foo(i1 %x, i8* %p1, i8* %p2) ; CHECK-FUNCTION-VERIFY: Running pass: VerifierPass ; CHECK-FUNCTION-VERIFY: Finished llvm::Function pass manager run ; CHECK-FUNCTION-VERIFY: Finished llvm::Module pass manager run ; RUN: opt -S -o - -passes='no-op-module,no-op-module' %s \ ; RUN: | FileCheck %s --check-prefix=CHECK-NOOP -; CHECK-NOOP: define void @foo(i1 %x) { +; CHECK-NOOP: define void @foo(i1 %x, i8* %p1, i8* %p2) { ; CHECK-NOOP: entry: +; CHECK-NOOP: store i8 42, i8* %p1 ; CHECK-NOOP: br i1 %x, label %loop, label %exit ; CHECK-NOOP: loop: +; CHECK-NOOP: %tmp1 = load i8, i8* %p2 ; CHECK-NOOP: br label %loop ; CHECK-NOOP: exit: ; CHECK-NOOP: ret void @@ -323,6 +325,42 @@ ; CHECK-AA-DEFAULT: Finished llvm::Module pass manager run ; RUN: opt -disable-output -disable-verify -debug-pass-manager %s 2>&1 \ +; RUN: -passes='require,invalidate,aa-eval' -aa-pipeline='basic-aa' \ +; RUN: | FileCheck %s --check-prefix=CHECK-AA-FUNCTION-INVALIDATE +; CHECK-AA-FUNCTION-INVALIDATE: Starting llvm::Function pass manager run +; CHECK-AA-FUNCTION-INVALIDATE: Running pass: RequireAnalysisPass +; CHECK-AA-FUNCTION-INVALIDATE: Running analysis: AAManager +; CHECK-AA-FUNCTION-INVALIDATE: Running analysis: BasicAA +; CHECK-AA-FUNCTION-INVALIDATE: Running pass: InvalidateAnalysisPass +; CHECK-AA-FUNCTION-INVALIDATE: Invalidating analysis: BasicAA +; CHECK-AA-FUNCTION-INVALIDATE: Invalidating analysis: AAManager +; CHECK-AA-FUNCTION-INVALIDATE: Running pass: AAEvaluator +; CHECK-AA-FUNCTION-INVALIDATE: Running analysis: AAManager +; CHECK-AA-FUNCTION-INVALIDATE: Running analysis: BasicAA +; CHECK-AA-FUNCTION-INVALIDATE: Finished llvm::Function pass manager run + +; RUN: opt -disable-output -disable-verify -debug-pass-manager %s 2>&1 \ +; RUN: -passes='require,function(require),invalidate,require,function(aa-eval)' -aa-pipeline='globals-aa' \ +; RUN: | FileCheck %s --check-prefix=CHECK-AA-MODULE-INVALIDATE +; CHECK-AA-MODULE-INVALIDATE: Starting llvm::Module pass manager run +; CHECK-AA-MODULE-INVALIDATE: Running pass: RequireAnalysisPass +; CHECK-AA-MODULE-INVALIDATE: Running analysis: GlobalsAA +; CHECK-AA-MODULE-INVALIDATE: Starting llvm::Function pass manager run +; CHECK-AA-MODULE-INVALIDATE: Running pass: RequireAnalysisPass +; CHECK-AA-MODULE-INVALIDATE: Running analysis: AAManager +; CHECK-AA-MODULE-INVALIDATE: Finished llvm::Function pass manager run +; CHECK-AA-MODULE-INVALIDATE: Running pass: InvalidateAnalysisPass +; CHECK-AA-MODULE-INVALIDATE: Invalidating analysis: AAManager +; CHECK-AA-MODULE-INVALIDATE: Invalidating analysis: GlobalsAA +; CHECK-AA-MODULE-INVALIDATE: Running pass: RequireAnalysisPass +; CHECK-AA-MODULE-INVALIDATE: Running analysis: GlobalsAA +; CHECK-AA-MODULE-INVALIDATE: Starting llvm::Function pass manager run +; CHECK-AA-MODULE-INVALIDATE: Running pass: AAEvaluator +; CHECK-AA-MODULE-INVALIDATE: Running analysis: AAManager +; CHECK-AA-MODULE-INVALIDATE: Finished llvm::Function pass manager run +; CHECK-AA-MODULE-INVALIDATE: Finished llvm::Module pass manager run + +; RUN: opt -disable-output -disable-verify -debug-pass-manager %s 2>&1 \ ; RUN: -passes='require' \ ; RUN: | FileCheck %s --check-prefix=CHECK-MEMDEP ; CHECK-MEMDEP: Starting llvm::Module pass manager run @@ -526,11 +564,13 @@ ; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Function pass manager run ; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Module pass manager run -define void @foo(i1 %x) { +define void @foo(i1 %x, i8* %p1, i8* %p2) { entry: + store i8 42, i8* %p1 br i1 %x, label %loop, label %exit loop: + %tmp1 = load i8, i8* %p2 br label %loop exit: