Introduce RegionInfoAnalysis, which compute Region Tree in the new PassManager. NFC
Differential Revision: http://reviews.llvm.org/D17571
llvm-svn: 261904
diff --git a/llvm/include/llvm/Analysis/RegionInfo.h b/llvm/include/llvm/Analysis/RegionInfo.h
index 4988386..394a503 100644
--- a/llvm/include/llvm/Analysis/RegionInfo.h
+++ b/llvm/include/llvm/Analysis/RegionInfo.h
@@ -47,6 +47,11 @@
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 @@
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 @@
/// 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 @@
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 @@
//@}
};
+/// \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 *
diff --git a/llvm/lib/Analysis/RegionInfo.cpp b/llvm/lib/Analysis/RegionInfo.cpp
index b4ba5af..72b3217 100644
--- a/llvm/lib/Analysis/RegionInfo.cpp
+++ b/llvm/lib/Analysis/RegionInfo.cpp
@@ -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 @@
}
}
+//===----------------------------------------------------------------------===//
+// 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();
+}
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 7d0fe7e6..93daad7 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -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"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 51d9310..a7e2b90 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -60,6 +60,7 @@
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<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
diff --git a/llvm/test/Analysis/RegionInfo/20100809_bb_not_in_domtree.ll b/llvm/test/Analysis/RegionInfo/20100809_bb_not_in_domtree.ll
index 0dfa0bf..84e7278 100644
--- a/llvm/test/Analysis/RegionInfo/20100809_bb_not_in_domtree.ll
+++ b/llvm/test/Analysis/RegionInfo/20100809_bb_not_in_domtree.ll
@@ -1,4 +1,6 @@
; RUN: opt -regions < %s
+; RUN: opt < %s -passes='print<regions>'
+
define i32 @main() nounwind {
entry:
br label %for.cond
diff --git a/llvm/test/Analysis/RegionInfo/block_sort.ll b/llvm/test/Analysis/RegionInfo/block_sort.ll
index d7ef79c..ce1a481 100644
--- a/llvm/test/Analysis/RegionInfo/block_sort.ll
+++ b/llvm/test/Analysis/RegionInfo/block_sort.ll
@@ -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
diff --git a/llvm/test/Analysis/RegionInfo/cond_loop.ll b/llvm/test/Analysis/RegionInfo/cond_loop.ll
index 0da4e5d..333cdff 100644
--- a/llvm/test/Analysis/RegionInfo/cond_loop.ll
+++ b/llvm/test/Analysis/RegionInfo/cond_loop.ll
@@ -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"
diff --git a/llvm/test/Analysis/RegionInfo/condition_complicated.ll b/llvm/test/Analysis/RegionInfo/condition_complicated.ll
index 53f13c1..ba107bf 100644
--- a/llvm/test/Analysis/RegionInfo/condition_complicated.ll
+++ b/llvm/test/Analysis/RegionInfo/condition_complicated.ll
@@ -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
diff --git a/llvm/test/Analysis/RegionInfo/condition_complicated_2.ll b/llvm/test/Analysis/RegionInfo/condition_complicated_2.ll
index fd04afc..9071771 100644
--- a/llvm/test/Analysis/RegionInfo/condition_complicated_2.ll
+++ b/llvm/test/Analysis/RegionInfo/condition_complicated_2.ll
@@ -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
diff --git a/llvm/test/Analysis/RegionInfo/condition_forward_edge.ll b/llvm/test/Analysis/RegionInfo/condition_forward_edge.ll
index 88c45c2..9c1ac75 100644
--- a/llvm/test/Analysis/RegionInfo/condition_forward_edge.ll
+++ b/llvm/test/Analysis/RegionInfo/condition_forward_edge.ll
@@ -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"
diff --git a/llvm/test/Analysis/RegionInfo/condition_same_exit.ll b/llvm/test/Analysis/RegionInfo/condition_same_exit.ll
index bfb0df8..570c772 100644
--- a/llvm/test/Analysis/RegionInfo/condition_same_exit.ll
+++ b/llvm/test/Analysis/RegionInfo/condition_same_exit.ll
@@ -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"
diff --git a/llvm/test/Analysis/RegionInfo/condition_simple.ll b/llvm/test/Analysis/RegionInfo/condition_simple.ll
index 3f93a6e..46c1b94 100644
--- a/llvm/test/Analysis/RegionInfo/condition_simple.ll
+++ b/llvm/test/Analysis/RegionInfo/condition_simple.ll
@@ -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"
diff --git a/llvm/test/Analysis/RegionInfo/exit_in_condition.ll b/llvm/test/Analysis/RegionInfo/exit_in_condition.ll
index ac409ec..4eb3be4 100644
--- a/llvm/test/Analysis/RegionInfo/exit_in_condition.ll
+++ b/llvm/test/Analysis/RegionInfo/exit_in_condition.ll
@@ -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
diff --git a/llvm/test/Analysis/RegionInfo/loop_with_condition.ll b/llvm/test/Analysis/RegionInfo/loop_with_condition.ll
index 4c1c8654..4122b20 100644
--- a/llvm/test/Analysis/RegionInfo/loop_with_condition.ll
+++ b/llvm/test/Analysis/RegionInfo/loop_with_condition.ll
@@ -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"
diff --git a/llvm/test/Analysis/RegionInfo/loops_1.ll b/llvm/test/Analysis/RegionInfo/loops_1.ll
index 9efe619..aedb484 100644
--- a/llvm/test/Analysis/RegionInfo/loops_1.ll
+++ b/llvm/test/Analysis/RegionInfo/loops_1.ll
@@ -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
diff --git a/llvm/test/Analysis/RegionInfo/loops_2.ll b/llvm/test/Analysis/RegionInfo/loops_2.ll
index ca7eca7..3ac83b0 100644
--- a/llvm/test/Analysis/RegionInfo/loops_2.ll
+++ b/llvm/test/Analysis/RegionInfo/loops_2.ll
@@ -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
diff --git a/llvm/test/Analysis/RegionInfo/mix_1.ll b/llvm/test/Analysis/RegionInfo/mix_1.ll
index 55001c7..3ae22af 100644
--- a/llvm/test/Analysis/RegionInfo/mix_1.ll
+++ b/llvm/test/Analysis/RegionInfo/mix_1.ll
@@ -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:
diff --git a/llvm/test/Analysis/RegionInfo/nested_loops.ll b/llvm/test/Analysis/RegionInfo/nested_loops.ll
index 3e73b3a..6db3237 100644
--- a/llvm/test/Analysis/RegionInfo/nested_loops.ll
+++ b/llvm/test/Analysis/RegionInfo/nested_loops.ll
@@ -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
diff --git a/llvm/test/Analysis/RegionInfo/next.ll b/llvm/test/Analysis/RegionInfo/next.ll
index b22bbcc..617273f 100644
--- a/llvm/test/Analysis/RegionInfo/next.ll
+++ b/llvm/test/Analysis/RegionInfo/next.ll
@@ -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
diff --git a/llvm/test/Analysis/RegionInfo/paper.ll b/llvm/test/Analysis/RegionInfo/paper.ll
index 0398d2b..3e592f4 100644
--- a/llvm/test/Analysis/RegionInfo/paper.ll
+++ b/llvm/test/Analysis/RegionInfo/paper.ll
@@ -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"
diff --git a/llvm/test/Analysis/RegionInfo/two_loops_same_header.ll b/llvm/test/Analysis/RegionInfo/two_loops_same_header.ll
index 2571342..2d5fa08 100644
--- a/llvm/test/Analysis/RegionInfo/two_loops_same_header.ll
+++ b/llvm/test/Analysis/RegionInfo/two_loops_same_header.ll
@@ -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
diff --git a/llvm/test/Analysis/RegionInfo/unreachable_bb.ll b/llvm/test/Analysis/RegionInfo/unreachable_bb.ll
index 626ccbe..5dd1be9 100644
--- a/llvm/test/Analysis/RegionInfo/unreachable_bb.ll
+++ b/llvm/test/Analysis/RegionInfo/unreachable_bb.ll
@@ -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() {