]> granicus.if.org Git - llvm/commitdiff
PM: Check that loop passes preserve a basic set of analyses
authorJustin Bogner <mail@justinbogner.com>
Tue, 3 May 2016 21:35:08 +0000 (21:35 +0000)
committerJustin Bogner <mail@justinbogner.com>
Tue, 3 May 2016 21:35:08 +0000 (21:35 +0000)
A loop pass that didn't preserve this entire set of passes wouldn't
play well with other loop passes, since these are generally a basic
requirement to do any interesting transformations to a loop.

Adds a helper to get the set of analyses a loop pass should preserve,
and checks that any loop pass we run satisfies the requirement.

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

include/llvm/Analysis/LoopPassManager.h
include/llvm/IR/PassManager.h
lib/Analysis/LoopPassManager.cpp
unittests/Analysis/LoopPassManagerTest.cpp

index e7d9578c1f8f426fe9a1cf6395b6e66cf79c8993..a8955185125995360f96791cc7fde8a958da92d5 100644 (file)
@@ -48,6 +48,9 @@ extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>;
 typedef OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>
     FunctionAnalysisManagerLoopProxy;
 
+/// Returns the minimum set of Analyses that all loop passes must preserve.
+PreservedAnalyses getLoopPassPreservedAnalyses();
+
 /// \brief Adaptor that maps from a function to its loops.
 ///
 /// Designed to allow composition of a LoopPass(Manager) and a
@@ -101,6 +104,8 @@ public:
     // post-order.
     for (auto *L : reverse(Loops)) {
       PreservedAnalyses PassPA = Pass.run(*L, LAM);
+      assert(PassPA.preserved(getLoopPassPreservedAnalyses()) &&
+             "Loop passes must preserve all relevant analyses");
 
       // We know that the loop pass couldn't have invalidated any other loop's
       // analyses (that's the contract of a loop pass), so directly handle the
index 2f9a8f243e03d3a2c157464c37439bb6b61c62e2..da4b708c3359b0ff5b4d6583e2667c3ec44c50d0 100644 (file)
@@ -144,6 +144,16 @@ public:
            PreservedPassIDs.count(PassID);
   }
 
+  /// \brief Query whether all of the analyses in the set are preserved.
+  bool preserved(PreservedAnalyses Arg) {
+    if (Arg.areAllPreserved())
+      return areAllPreserved();
+    for (void *P : Arg.PreservedPassIDs)
+      if (!preserved(P))
+        return false;
+    return true;
+  }
+
   /// \brief Test whether all passes are preserved.
   ///
   /// This is used primarily to optimize for the case of no changes which will
index 76210fa89c0fd43b88ce106d0c0e17505f392e67..8bac19a58217286a9087496cc6a800ee3999eff6 100644 (file)
@@ -8,6 +8,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Analysis/LoopPassManager.h"
+#include "llvm/Analysis/BasicAliasAnalysis.h"
+#include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
+#include "llvm/IR/Dominators.h"
 
 using namespace llvm;
 
@@ -18,3 +24,16 @@ template class AnalysisManager<Loop>;
 template class InnerAnalysisManagerProxy<LoopAnalysisManager, Function>;
 template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>;
 }
+
+PreservedAnalyses llvm::getLoopPassPreservedAnalyses() {
+  PreservedAnalyses PA;
+  PA.preserve<DominatorTreeAnalysis>();
+  PA.preserve<LoopAnalysis>();
+  PA.preserve<ScalarEvolutionAnalysis>();
+  // TODO: What we really want to do here is preserve an AA category, but that
+  // concept doesn't exist yet.
+  PA.preserve<BasicAA>();
+  PA.preserve<GlobalsAA>();
+  PA.preserve<SCEVAA>();
+  return PA;
+}
index 3cbe203e14df2a1fa7536e14a41ca9f3c1901ec4..5858e174aabb6432fb10ef71030ba1f8a25d6f39 100644 (file)
@@ -92,7 +92,7 @@ public:
   TestLoopInvalidatingPass(StringRef LoopName) : Name(LoopName) {}
 
   PreservedAnalyses run(Loop &L, AnalysisManager<Loop> &AM) {
-    return L.getName() == Name ? PreservedAnalyses::none()
+    return L.getName() == Name ? getLoopPassPreservedAnalyses()
                                : PreservedAnalyses::all();
   }