summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/include/polly/DependenceInfo.h45
-rw-r--r--polly/include/polly/LinkAllPasses.h1
-rw-r--r--polly/lib/Analysis/DependenceInfo.cpp56
-rw-r--r--polly/lib/Support/RegisterPasses.cpp1
-rw-r--r--polly/test/DependenceInfo/computeout.ll9
-rw-r--r--polly/test/DependenceInfo/different_schedule_dimensions.ll11
-rw-r--r--polly/test/DependenceInfo/do_pluto_matmult.ll16
-rw-r--r--polly/test/DependenceInfo/fine_grain_dep_0.ll1
8 files changed, 140 insertions, 0 deletions
diff --git a/polly/include/polly/DependenceInfo.h b/polly/include/polly/DependenceInfo.h
index 609e8107689..aced9b0065a 100644
--- a/polly/include/polly/DependenceInfo.h
+++ b/polly/include/polly/DependenceInfo.h
@@ -141,11 +141,15 @@ struct Dependences {
/// @brief Dump the dependence information stored to the dbgs stream.
void dump() const;
+ /// @brief Return the granularity of this dependence analysis.
+ AnalyisLevel getDependenceLevel() { return Level; }
+
/// @brief Allow the DependenceInfo access to private members and methods.
///
/// To restrict access to the internal state, only the DependenceInfo class
/// is able to call or modify a Dependences struct.
friend class DependenceInfo;
+ friend class DependenceInfoWrapperPass;
/// @brief Destructor that will free internal objects.
~Dependences() { releaseMemory(); }
@@ -232,11 +236,52 @@ private:
std::unique_ptr<Dependences> D[Dependences::NumAnalysisLevels];
};
+/// @brief Construct a new DependenceInfoWrapper pass.
+class DependenceInfoWrapperPass : public FunctionPass {
+public:
+ static char ID;
+
+ /// @brief Construct a new DependenceInfoWrapper pass.
+ DependenceInfoWrapperPass() : FunctionPass(ID) {}
+
+ /// @brief Return the dependence information for the given SCoP.
+ ///
+ /// @param S SCoP object.
+ /// @param Level The granularity of dependence analysis result.
+ ///
+ /// @return The dependence analysis result
+ ///
+ const Dependences &getDependences(Scop *S, Dependences::AnalyisLevel Level);
+
+ /// @brief Recompute dependences from schedule and memory accesses.
+ const Dependences &recomputeDependences(Scop *S,
+ Dependences::AnalyisLevel Level);
+
+ /// @brief Compute the dependence information on-the-fly for the function.
+ bool runOnFunction(Function &F) override;
+
+ /// @brief Print the dependences for the current function to @p OS.
+ void print(raw_ostream &OS, const Module *M = nullptr) const override;
+
+ /// @brief Release the internal memory.
+ void releaseMemory() override { ScopToDepsMap.clear(); }
+
+ /// @brief Register all analyses and transformation required.
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+private:
+ using ScopToDepsMapTy = DenseMap<Scop *, std::unique_ptr<Dependences>>;
+
+ /// @brief Scop to Dependence map for the current function.
+ ScopToDepsMapTy ScopToDepsMap;
+};
+
} // namespace polly
namespace llvm {
class PassRegistry;
void initializeDependenceInfoPass(llvm::PassRegistry &);
+void initializeDependenceInfoWrapperPassPass(llvm::PassRegistry &);
} // namespace llvm
#endif
diff --git a/polly/include/polly/LinkAllPasses.h b/polly/include/polly/LinkAllPasses.h
index 48d3d3a324b..b5fed125d26 100644
--- a/polly/include/polly/LinkAllPasses.h
+++ b/polly/include/polly/LinkAllPasses.h
@@ -29,6 +29,7 @@ namespace polly {
llvm::Pass *createCodePreparationPass();
llvm::Pass *createDeadCodeElimPass();
llvm::Pass *createDependenceInfoPass();
+llvm::Pass *createDependenceInfoWrapperPassPass();
llvm::Pass *createDOTOnlyPrinterPass();
llvm::Pass *createDOTOnlyViewerPass();
llvm::Pass *createDOTPrinterPass();
diff --git a/polly/lib/Analysis/DependenceInfo.cpp b/polly/lib/Analysis/DependenceInfo.cpp
index dcee885ec89..1ebc7783bc1 100644
--- a/polly/lib/Analysis/DependenceInfo.cpp
+++ b/polly/lib/Analysis/DependenceInfo.cpp
@@ -804,3 +804,59 @@ INITIALIZE_PASS_BEGIN(DependenceInfo, "polly-dependences",
INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass);
INITIALIZE_PASS_END(DependenceInfo, "polly-dependences",
"Polly - Calculate dependences", false, false)
+
+//===----------------------------------------------------------------------===//
+const Dependences &
+DependenceInfoWrapperPass::getDependences(Scop *S,
+ Dependences::AnalyisLevel Level) {
+ auto It = ScopToDepsMap.find(S);
+ if (It != ScopToDepsMap.end())
+ if (It->second) {
+ if (It->second->getDependenceLevel() == Level)
+ return *It->second.get();
+ }
+ return recomputeDependences(S, Level);
+}
+
+const Dependences &DependenceInfoWrapperPass::recomputeDependences(
+ Scop *S, Dependences::AnalyisLevel Level) {
+ std::unique_ptr<Dependences> D(new Dependences(S->getSharedIslCtx(), Level));
+ D->calculateDependences(*S);
+ auto Inserted = ScopToDepsMap.insert(std::make_pair(S, std::move(D)));
+ return *Inserted.first->second;
+}
+
+bool DependenceInfoWrapperPass::runOnFunction(Function &F) {
+ auto &SI = getAnalysis<ScopInfoWrapperPass>();
+ for (auto &It : SI)
+ recomputeDependences(It.second.get(), Dependences::AL_Access);
+ return false;
+}
+
+void DependenceInfoWrapperPass::print(raw_ostream &OS, const Module *M) const {
+ for (auto &It : ScopToDepsMap) {
+ assert((It.first && It.second) && "Invalid Scop or Dependence object!\n");
+ It.second->print(OS);
+ }
+}
+
+void DependenceInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredTransitive<ScopInfoWrapperPass>();
+ AU.setPreservesAll();
+}
+
+char DependenceInfoWrapperPass::ID = 0;
+
+Pass *polly::createDependenceInfoWrapperPassPass() {
+ return new DependenceInfoWrapperPass();
+}
+
+INITIALIZE_PASS_BEGIN(
+ DependenceInfoWrapperPass, "polly-function-dependences",
+ "Polly - Calculate dependences for all the SCoPs of a function", false,
+ false)
+INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass);
+INITIALIZE_PASS_END(
+ DependenceInfoWrapperPass, "polly-function-dependences",
+ "Polly - Calculate dependences for all the SCoPs of a function", false,
+ false)
diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp
index 9baf8de56fe..9d3dee8f7b3 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -148,6 +148,7 @@ void initializePollyPasses(PassRegistry &Registry) {
initializeCodePreparationPass(Registry);
initializeDeadCodeElimPass(Registry);
initializeDependenceInfoPass(Registry);
+ initializeDependenceInfoWrapperPassPass(Registry);
initializeJSONExporterPass(Registry);
initializeJSONImporterPass(Registry);
initializeIslAstInfoPass(Registry);
diff --git a/polly/test/DependenceInfo/computeout.ll b/polly/test/DependenceInfo/computeout.ll
index 52e8084a0a6..98af1c102f0 100644
--- a/polly/test/DependenceInfo/computeout.ll
+++ b/polly/test/DependenceInfo/computeout.ll
@@ -1,5 +1,7 @@
; RUN: opt -S %loadPolly -polly-dependences -analyze < %s | FileCheck %s -check-prefix=VALUE
+; RUN: opt -S %loadPolly -polly-function-dependences -analyze < %s | FileCheck %s -check-prefix=FUNC-VALUE
; RUN: opt -S %loadPolly -polly-dependences -analyze -polly-dependences-computeout=1 < %s | FileCheck %s -check-prefix=TIMEOUT
+; RUN: opt -S %loadPolly -polly-function-dependences -analyze -polly-dependences-computeout=1 < %s | FileCheck %s -check-prefix=TIMEOUT
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
; for(i = 0; i < 100; i++ )
@@ -57,6 +59,13 @@ exit.3:
; VALUE-NEXT: WAW dependences:
; VALUE-NEXT: { Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9; Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99 }
+; FUNC-VALUE: RAW dependences:
+; FUNC-VALUE-NEXT: { }
+; FUNC-VALUE-NEXT: WAR dependences:
+; FUNC-VALUE-NEXT: { }
+; FUNC-VALUE-NEXT: WAW dependences:
+; FUNC-VALUE-NEXT: { Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Write0_MemRef_A[]] -> [Stmt_S3[i0] -> Stmt_S3_Write0_MemRef_A[]] : 10 <= i0 <= 99; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9; [Stmt_S2[i0] -> Stmt_S2_Write0_MemRef_A[]] -> [Stmt_S3[i0] -> Stmt_S3_Write0_MemRef_A[]] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Write0_MemRef_A[]] -> [Stmt_S2[i0] -> Stmt_S2_Write0_MemRef_A[]] : 0 <= i0 <= 9; Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99 }
+
; TIMEOUT: RAW dependences:
; TIMEOUT-NEXT: n/a
; TIMEOUT-NEXT: WAR dependences:
diff --git a/polly/test/DependenceInfo/different_schedule_dimensions.ll b/polly/test/DependenceInfo/different_schedule_dimensions.ll
index 2c8a00c0eb9..9cdfbed79ab 100644
--- a/polly/test/DependenceInfo/different_schedule_dimensions.ll
+++ b/polly/test/DependenceInfo/different_schedule_dimensions.ll
@@ -1,5 +1,7 @@
; RUN: opt -S %loadPolly -polly-dependences \
; RUN: -analyze < %s | FileCheck %s
+; RUN: opt -S %loadPolly -polly-function-dependences \
+; RUN: -analyze < %s | FileCheck %s -check-prefix=FUNC
; CHECK: RAW dependences:
; CHECK: { Stmt_bb9[0] -> Stmt_bb10[0] }
@@ -10,6 +12,15 @@
; CHECK: Reduction dependences:
; CHECK: { }
+; FUNC: RAW dependences:
+; FUNC-NEXT: { Stmt_bb9[0] -> Stmt_bb10[0]; [Stmt_bb9[0] -> Stmt_bb9_Write0_MemRef_tmp11[]] -> [Stmt_bb10[0] -> Stmt_bb10_Read0_MemRef_tmp11[]] }
+; FUNC-NEXT: WAR dependences:
+; FUNC-NEXT: { }
+; FUNC-NEXT: WAW dependences:
+; FUNC-NEXT: { Stmt_bb3[0] -> Stmt_bb10[0]; [Stmt_bb3[0] -> Stmt_bb3_Write1_MemRef_arg1[]] -> [Stmt_bb10[0] -> Stmt_bb10_Write1_MemRef_arg1[]] }
+; FUNC-NEXT: Reduction dependences:
+; FUNC-NEXT: { }
+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @hoge(i32 %arg, [1024 x double]* %arg1) {
diff --git a/polly/test/DependenceInfo/do_pluto_matmult.ll b/polly/test/DependenceInfo/do_pluto_matmult.ll
index e4f10fccf55..04602fc5e4c 100644
--- a/polly/test/DependenceInfo/do_pluto_matmult.ll
+++ b/polly/test/DependenceInfo/do_pluto_matmult.ll
@@ -1,5 +1,7 @@
; RUN: opt %loadPolly -basicaa -polly-dependences -analyze -polly-dependences-analysis-type=value-based < %s | FileCheck %s -check-prefix=VALUE
; RUN: opt %loadPolly -basicaa -polly-dependences -analyze -polly-dependences-analysis-type=memory-based < %s | FileCheck %s -check-prefix=MEMORY
+; RUN: opt %loadPolly -basicaa -polly-function-dependences -analyze -polly-dependences-analysis-type=value-based < %s | FileCheck %s -check-prefix=FUNC-VALUE
+; RUN: opt %loadPolly -basicaa -polly-function-dependences -analyze -polly-dependences-analysis-type=memory-based < %s | FileCheck %s -check-prefix=FUNC-MEMORY
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
@@ -77,3 +79,17 @@ do.end45: ; preds = %do.cond42
; MEMORY-NEXT: { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, o2] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and i2 >= 0 and i2 < o2 <= 35 }
; MEMORY-NEXT: WAW dependences:
; MEMORY-NEXT: { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, o2] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and i2 >= 0 and i2 < o2 <= 35 }
+
+; FUNC-VALUE: RAW dependences:
+; FUNC-VALUE-NEXT: { [Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2_Write3_MemRef_C[]] -> [Stmt_do_body2[i0, i1, 1 + i2] -> Stmt_do_body2_Read0_MemRef_C[]] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and 0 <= i2 <= 34; Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, 1 + i2] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and 0 <= i2 <= 34 }
+; FUNC-VALUE-NEXT: WAR dependences:
+; FUNC-VALUE-NEXT: { }
+; FUNC-VALUE-NEXT: WAW dependences:
+; FUNC-VALUE-NEXT: { [Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2_Write3_MemRef_C[]] -> [Stmt_do_body2[i0, i1, 1 + i2] -> Stmt_do_body2_Write3_MemRef_C[]] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and 0 <= i2 <= 34; Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, 1 + i2] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and 0 <= i2 <= 34 }
+
+; FUNC-MEMORY: RAW dependences:
+; FUNC-MEMORY-NEXT: { [Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2_Write3_MemRef_C[]] -> [Stmt_do_body2[i0, i1, o2] -> Stmt_do_body2_Read0_MemRef_C[]] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and i2 >= 0 and i2 < o2 <= 35; Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, o2] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and i2 >= 0 and i2 < o2 <= 35 }
+; FUNC-MEMORY-NEXT: WAR dependences:
+; FUNC-MEMORY-NEXT: { [Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2_Read0_MemRef_C[]] -> [Stmt_do_body2[i0, i1, o2] -> Stmt_do_body2_Write3_MemRef_C[]] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and i2 >= 0 and i2 < o2 <= 35; Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, o2] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and i2 >= 0 and i2 < o2 <= 35 }
+; FUNC-MEMORY-NEXT: WAW dependences:
+; FUNC-MEMORY-NEXT: { [Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2_Write3_MemRef_C[]] -> [Stmt_do_body2[i0, i1, o2] -> Stmt_do_body2_Write3_MemRef_C[]] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and i2 >= 0 and i2 < o2 <= 35; Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, o2] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and i2 >= 0 and i2 < o2 <= 35 }
diff --git a/polly/test/DependenceInfo/fine_grain_dep_0.ll b/polly/test/DependenceInfo/fine_grain_dep_0.ll
index 5f384b92520..0bacbf9ab43 100644
--- a/polly/test/DependenceInfo/fine_grain_dep_0.ll
+++ b/polly/test/DependenceInfo/fine_grain_dep_0.ll
@@ -1,5 +1,6 @@
; RUN: opt %loadPolly -polly-dependences -polly-dependences-analysis-type=value-based -polly-dependences-analysis-level=reference-wise -analyze < %s | FileCheck %s --check-prefix=REF
; RUN: opt %loadPolly -polly-dependences -polly-dependences-analysis-type=value-based -polly-dependences-analysis-level=access-wise -analyze < %s | FileCheck %s --check-prefix=ACC
+; RUN: opt %loadPolly -polly-function-dependences -polly-dependences-analysis-type=value-based -polly-dependences-analysis-level=access-wise -analyze < %s | FileCheck %s --check-prefix=ACC
;
; REF: RAW dependences:
; REF-NEXT: [N] -> { [Stmt_for_body[i0] -> MemRef_a[]] -> [Stmt_for_body[4 + i0] -> MemRef_a[]] : 0 <= i0 <= -11 + N; [Stmt_for_body[i0] -> MemRef_b[]] -> [Stmt_for_body[6 + i0] -> MemRef_b[]] : 0 <= i0 <= -13 + N; Stmt_for_body[i0] -> Stmt_for_body[6 + i0] : 0 <= i0 <= -13 + N; Stmt_for_body[i0] -> Stmt_for_body[4 + i0] : 0 <= i0 <= -11 + N }
OpenPOWER on IntegriCloud