Introduce RegionInfoAnalysis, which compute Region Tree in the new PassManager. NFC
authorHongbin Zheng <etherzhhb@gmail.com>
Thu, 25 Feb 2016 16:33:26 +0000 (16:33 +0000)
committerHongbin Zheng <etherzhhb@gmail.com>
Thu, 25 Feb 2016 16:33:26 +0000 (16:33 +0000)
Differential Revision: http://reviews.llvm.org/D17571

llvm-svn: 261884

22 files changed:
llvm/include/llvm/Analysis/RegionInfo.h
llvm/lib/Analysis/RegionInfo.cpp
llvm/lib/Passes/PassBuilder.cpp
llvm/lib/Passes/PassRegistry.def
llvm/test/Analysis/RegionInfo/20100809_bb_not_in_domtree.ll
llvm/test/Analysis/RegionInfo/block_sort.ll
llvm/test/Analysis/RegionInfo/cond_loop.ll
llvm/test/Analysis/RegionInfo/condition_complicated.ll
llvm/test/Analysis/RegionInfo/condition_complicated_2.ll
llvm/test/Analysis/RegionInfo/condition_forward_edge.ll
llvm/test/Analysis/RegionInfo/condition_same_exit.ll
llvm/test/Analysis/RegionInfo/condition_simple.ll
llvm/test/Analysis/RegionInfo/exit_in_condition.ll
llvm/test/Analysis/RegionInfo/loop_with_condition.ll
llvm/test/Analysis/RegionInfo/loops_1.ll
llvm/test/Analysis/RegionInfo/loops_2.ll
llvm/test/Analysis/RegionInfo/mix_1.ll
llvm/test/Analysis/RegionInfo/nested_loops.ll
llvm/test/Analysis/RegionInfo/next.ll
llvm/test/Analysis/RegionInfo/paper.ll
llvm/test/Analysis/RegionInfo/two_loops_same_header.ll
llvm/test/Analysis/RegionInfo/unreachable_bb.ll

index 4988386..394a503 100644 (file)
 
 namespace llvm {
 
+// FIXME: Replace this brittle forward declaration with the include of the new
+// PassManager.h when doing so doesn't break the PassManagerBuilder.
+template <typename IRUnitT> class AnalysisManager;
+class PreservedAnalyses;
+
 // Class to be specialized for different users of RegionInfo
 // (i.e. BasicBlocks or MachineBasicBlocks). This is only to avoid needing to
 // pass around an unreasonable number of template parameters.
@@ -676,6 +681,22 @@ class RegionInfoBase {
   RegionInfoBase(const RegionInfoBase &) = delete;
   const RegionInfoBase &operator=(const RegionInfoBase &) = delete;
 
+  RegionInfoBase(RegionInfoBase &&Arg)
+    : DT(std::move(Arg.DT)), PDT(std::move(Arg.PDT)), DF(std::move(Arg.DF)),
+      TopLevelRegion(std::move(Arg.TopLevelRegion)),
+      BBtoRegion(std::move(Arg.BBtoRegion)) {
+    Arg.wipe();
+  }
+  RegionInfoBase &operator=(RegionInfoBase &&RHS) {
+    DT = std::move(RHS.DT);
+    PDT = std::move(RHS.PDT);
+    DF = std::move(RHS.DF);
+    TopLevelRegion = std::move(RHS.TopLevelRegion);
+    BBtoRegion = std::move(RHS.BBtoRegion);
+    RHS.wipe();
+    return *this;
+  }
+
   DomTreeT *DT;
   PostDomTreeT *PDT;
   DomFrontierT *DF;
@@ -687,6 +708,18 @@ private:
   /// Map every BB to the smallest region, that contains BB.
   BBtoRegionMap BBtoRegion;
 
+  /// \brief Wipe this region tree's state without releasing any resources.
+  ///
+  /// This is essentially a post-move helper only. It leaves the object in an
+  /// assignable and destroyable state, but otherwise invalid.
+  void wipe() {
+    DT = nullptr;
+    PDT = nullptr;
+    DF = nullptr;
+    TopLevelRegion = nullptr;
+    BBtoRegion.clear();
+  }
+
   // Check whether the entries of BBtoRegion for the BBs of region
   // SR are correct. Triggers an assertion if not. Calls itself recursively for
   // subregions.
@@ -836,10 +869,19 @@ public:
 
 class RegionInfo : public RegionInfoBase<RegionTraits<Function>> {
 public:
+  typedef RegionInfoBase<RegionTraits<Function>> Base;
+
   explicit RegionInfo();
 
   ~RegionInfo() override;
 
+  RegionInfo(RegionInfo &&Arg)
+    : Base(std::move(static_cast<Base &>(Arg))) {}
+  RegionInfo &operator=(RegionInfo &&RHS) {
+    Base::operator=(std::move(static_cast<Base &>(RHS)));
+    return *this;
+  }
+
   // updateStatistics - Update statistic about created regions.
   void updateStatistics(Region *R) final;
 
@@ -884,6 +926,40 @@ public:
   //@}
 };
 
+/// \brief Analysis pass that exposes the \c RegionInfo for a function.
+class RegionInfoAnalysis {
+  static char PassID;
+
+public:
+  typedef RegionInfo Result;
+
+  /// \brief Opaque, unique identifier for this analysis pass.
+  static void *ID() { return (void *)&PassID; }
+
+  /// \brief Provide a name for the analysis for debugging and logging.
+  static StringRef name() { return "RegionInfoAnalysis"; }
+
+  RegionInfo run(Function &F, AnalysisManager<Function> *AM);
+};
+
+/// \brief Printer pass for the \c RegionInfo.
+class RegionInfoPrinterPass {
+  raw_ostream &OS;
+
+public:
+  explicit RegionInfoPrinterPass(raw_ostream &OS);
+  PreservedAnalyses run(Function &F, AnalysisManager<Function> *AM);
+
+  static StringRef name() { return "RegionInfoPrinterPass"; }
+};
+
+/// \brief Verifier pass for the \c RegionInfo.
+struct RegionInfoVerifierPass {
+  PreservedAnalyses run(Function &F, AnalysisManager<Function> *AM);
+
+  static StringRef name() { return "RegionInfoVerifierPass"; }
+};
+
 template <>
 template <>
 inline BasicBlock *
index b4ba5af..72b3217 100644 (file)
@@ -15,6 +15,7 @@
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/RegionInfoImpl.h"
 #include "llvm/Analysis/RegionIterator.h"
+#include "llvm/IR/PassManager.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -180,3 +181,36 @@ namespace llvm {
   }
 }
 
+//===----------------------------------------------------------------------===//
+// RegionInfoAnalysis implementation
+//
+
+char RegionInfoAnalysis::PassID;
+
+RegionInfo RegionInfoAnalysis::run(Function &F, AnalysisManager<Function> *AM) {
+  RegionInfo RI;
+  auto *DT = &AM->getResult<DominatorTreeAnalysis>(F);
+  auto *PDT = &AM->getResult<PostDominatorTreeAnalysis>(F);
+  auto *DF = &AM->getResult<DominanceFrontierAnalysis>(F);
+
+  RI.recalculate(F, DT, PDT, DF);
+  return RI;
+}
+
+RegionInfoPrinterPass::RegionInfoPrinterPass(raw_ostream &OS)
+  : OS(OS) {}
+
+PreservedAnalyses
+RegionInfoPrinterPass::run(Function &F, FunctionAnalysisManager *AM) {
+  OS << "Region Tree for function: " << F.getName() << "\n";
+  AM->getResult<RegionInfoAnalysis>(F).print(OS);
+
+  return PreservedAnalyses::all();
+}
+
+PreservedAnalyses RegionInfoVerifierPass::run(Function &F,
+                                              AnalysisManager<Function> *AM) {
+  AM->getResult<RegionInfoAnalysis>(F).verifyAnalysis();
+
+  return PreservedAnalyses::all();
+}
index 7d0fe7e..93daad7 100644 (file)
@@ -26,6 +26,7 @@
 #include "llvm/Analysis/LazyCallGraph.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/PostDominators.h"
+#include "llvm/Analysis/RegionInfo.h"
 #include "llvm/Analysis/ScalarEvolution.h"
 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
 #include "llvm/Analysis/ScopedNoAliasAA.h"
index 51d9310..a7e2b90 100644 (file)
@@ -60,6 +60,7 @@ FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis())
 FUNCTION_ANALYSIS("postdomtree", PostDominatorTreeAnalysis())
 FUNCTION_ANALYSIS("domfrontier", DominanceFrontierAnalysis())
 FUNCTION_ANALYSIS("loops", LoopAnalysis())
+FUNCTION_ANALYSIS("regions", RegionInfoAnalysis())
 FUNCTION_ANALYSIS("no-op-function", NoOpFunctionAnalysis())
 FUNCTION_ANALYSIS("scalar-evolution", ScalarEvolutionAnalysis())
 FUNCTION_ANALYSIS("targetlibinfo", TargetLibraryAnalysis())
@@ -94,11 +95,13 @@ FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs()))
 FUNCTION_PASS("print<postdomtree>", PostDominatorTreePrinterPass(dbgs()))
 FUNCTION_PASS("print<domfrontier>", DominanceFrontierPrinterPass(dbgs()))
 FUNCTION_PASS("print<loops>", LoopPrinterPass(dbgs()))
+FUNCTION_PASS("print<regions>", RegionInfoPrinterPass(dbgs()))
 FUNCTION_PASS("print<scalar-evolution>", ScalarEvolutionPrinterPass(dbgs()))
 FUNCTION_PASS("simplify-cfg", SimplifyCFGPass())
 FUNCTION_PASS("sroa", SROA())
 FUNCTION_PASS("verify", VerifierPass())
 FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass())
+FUNCTION_PASS("verify<regions>", RegionInfoVerifierPass())
 #undef FUNCTION_PASS
 
 #ifndef LOOP_ANALYSIS
index 0dfa0bf..84e7278 100644 (file)
@@ -1,4 +1,6 @@
 ; RUN: opt -regions < %s
+; RUN: opt < %s -passes='print<regions>'
+
 define i32 @main() nounwind {
 entry:
   br label %for.cond
index d7ef79c..ce1a481 100644 (file)
@@ -4,6 +4,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define void @BZ2_blockSort() nounwind {
 start:
   br label %while
index 0da4e5d..333cdff 100644 (file)
@@ -4,6 +4,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define void @normal_condition() nounwind {
 5:
         br label %"0"
index 53f13c1..ba107bf 100644 (file)
@@ -4,6 +4,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define internal fastcc zeroext i8 @handle_compress() nounwind {
 end165:
   br i1 1, label %false239, label %true181
index fd04afc..9071771 100644 (file)
@@ -4,6 +4,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define internal fastcc void @compress() nounwind {
 end33:
   br i1 1, label %end124, label %lor.lhs.false95
index 88c45c2..9c1ac75 100644 (file)
@@ -4,6 +4,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define void @normal_condition() nounwind {
 0:
        br label %"1"
index bfb0df8..570c772 100644 (file)
@@ -4,6 +4,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define void @normal_condition() nounwind {
 0:
        br i1 1, label %"1", label %"4"
index 3f93a6e..46c1b94 100644 (file)
@@ -4,6 +4,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define void @normal_condition() nounwind {
 0:
        br label %"1"
index ac409ec..4eb3be4 100644 (file)
@@ -4,6 +4,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define internal fastcc zeroext i8 @handle_compress() nounwind {
 entry:
   br label %outer
index 4c1c865..4122b20 100644 (file)
@@ -5,6 +5,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define void @normal_condition() nounwind {
 0:
         br label %"1"
index 9efe619..aedb484 100644 (file)
@@ -4,6 +4,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define internal fastcc zeroext i8 @loops_1() nounwind {
 entry:
   br i1 1, label %outer , label %a
index ca7eca7..3ac83b0 100644 (file)
@@ -4,6 +4,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define void @meread_() nounwind {
 entry:
   br label %bb23
index 55001c7..3ae22af 100644 (file)
@@ -5,6 +5,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define void @a_linear_impl_fig_1() nounwind {
 0:
 
index 3e73b3a..6db3237 100644 (file)
@@ -5,6 +5,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define internal fastcc zeroext i8 @handle_compress() nounwind {
 entry:
   br label %outer
index b22bbcc..617273f 100644 (file)
@@ -4,6 +4,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define void @MAIN__() nounwind {
 entry:
   br label %__label_002001.outer
index 0398d2b..3e592f4 100644 (file)
@@ -4,6 +4,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define void @a_linear_impl_fig_1() nounwind {
 0:
         br label %"1"
index 2571342..2d5fa08 100644 (file)
@@ -4,6 +4,8 @@
 ; RUN: opt -regions -print-region-style=bb  -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
 ; RUN: opt -regions -print-region-style=rn  -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
 
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
 define internal fastcc zeroext i8 @handle_compress() nounwind {
 entry:
   br label %outer
index 626ccbe..5dd1be9 100644 (file)
@@ -1,4 +1,5 @@
 ; RUN: opt -regions -analyze < %s | FileCheck %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
 
 ; We should not crash if there are some bbs that are not reachable.
 define void @f() {