diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h --- a/llvm/include/llvm/IR/PassManager.h +++ b/llvm/include/llvm/IR/PassManager.h @@ -186,9 +186,22 @@ PreservedIDs.insert(ID); } - /// Mark an analysis set as preserved. + /// Mark an analysis set as preserved. This is only called by inner pass + /// manager to tell outer pass manager that inner analyses are up-to-date. + /// Regular passes should not call this. + /// FIXME: rename this to `preserveSetAndClearAbandonedAnalyses`? template void preserveSet() { preserveSet(AnalysisSetT::ID()); + NotPreservedAnalysisIDs.clear(); + } + + // TODO: Using `preserve` instead so we could add comment to + // preserveSet saying that it is restricted to usage introduced in D23691. + // `preserveSet` is semantically correct but + // `preserve` helps reason about the code which IMHO is more + // important. + template <> void preserveSet() { + preserveSet(CFGAnalyses::ID()); } /// Mark an analysis set as preserved using its ID. diff --git a/llvm/unittests/IR/PassManagerTest.cpp b/llvm/unittests/IR/PassManagerTest.cpp --- a/llvm/unittests/IR/PassManagerTest.cpp +++ b/llvm/unittests/IR/PassManagerTest.cpp @@ -396,10 +396,19 @@ PA.abandon(); EXPECT_FALSE(PA.getChecker().preserved()); - // Even if the sets are preserved, the abandoned analyses' checker won't - // return true for those sets. + // If the sets are preserved after the analyses are abandoned, the abandoned + // analyses' checker will return true for those sets. PA.preserveSet>(); PA.preserveSet>(); + EXPECT_TRUE(PA.getChecker() + .preservedSet>()); + EXPECT_TRUE(PA.getChecker() + .preservedSet>()); + + // If the sets are preserved before the analyses are abandoned, the abandoned + // analyses' checker will return false for those sets. + PA.abandon(); + PA.abandon(); EXPECT_FALSE(PA.getChecker() .preservedSet>()); EXPECT_FALSE(PA.getChecker()