diff options
-rw-r--r-- | llvm/include/llvm/Analysis/AliasAnalysis.h | 26 | ||||
-rw-r--r-- | llvm/include/llvm/IR/PassManager.h | 8 | ||||
-rw-r--r-- | llvm/lib/Analysis/AliasAnalysis.cpp | 22 | ||||
-rw-r--r-- | llvm/test/Other/new-pass-manager.ll | 52 |
4 files changed, 93 insertions, 15 deletions
diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h index ff483f911ba..d8e50438e72 100644 --- a/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/llvm/include/llvm/Analysis/AliasAnalysis.h @@ -197,6 +197,20 @@ public: AAs.emplace_back(new Model<AAResultT>(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 @@ private: const TargetLibraryInfo &TLI; std::vector<std::unique_ptr<Concept>> AAs; + + std::vector<AnalysisKey *> AADeps; }; /// Temporary typedef for legacy code that uses a generic \c AliasAnalysis @@ -922,15 +938,19 @@ private: FunctionAnalysisManager &AM, AAResults &AAResults) { AAResults.addAAResult(AM.template getResult<AnalysisT>(F)); + AAResults.addAADependencyID(AnalysisT::ID()); } template <typename AnalysisT> static void getModuleAAResultImpl(Function &F, FunctionAnalysisManager &AM, AAResults &AAResults) { - auto &MAM = - AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager(); - if (auto *R = MAM.template getCachedResult<AnalysisT>(*F.getParent())) + auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F); + auto &MAM = MAMProxy.getManager(); + if (auto *R = MAM.template getCachedResult<AnalysisT>(*F.getParent())) { AAResults.addAAResult(*R); + MAMProxy + .template registerOuterAnalysisInvalidation<AnalysisT, AAManager>(); + } } }; diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h index c064e4b51be..3e4edd893d3 100644 --- a/llvm/include/llvm/IR/PassManager.h +++ b/llvm/include/llvm/IR/PassManager.h @@ -1218,11 +1218,9 @@ struct InvalidateAnalysisPass /// context requires. template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs> 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<AnalysisT>(Arg); - - return PreservedAnalyses::all(); + auto PA = PreservedAnalyses::all(); + PA.abandon<AnalysisT>(); + return PA; } }; diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp index d5676455d1e..f88e40adb90 100644 --- a/llvm/lib/Analysis/AliasAnalysis.cpp +++ b/llvm/lib/Analysis/AliasAnalysis.cpp @@ -53,7 +53,8 @@ using namespace llvm; static cl::opt<bool> 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 @@ AAResults::~AAResults() { #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<AAManager>(); + if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>()) + 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 //===----------------------------------------------------------------------===// diff --git a/llvm/test/Other/new-pass-manager.ll b/llvm/test/Other/new-pass-manager.ll index c50d4169760..6338dd012ce 100644 --- a/llvm/test/Other/new-pass-manager.ll +++ b/llvm/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<aa>,invalidate<basic-aa>,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<globals-aa>,function(require<aa>),invalidate<globals-aa>,require<globals-aa>,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<memdep>' \ ; 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: |