[polly] r262039 - Introduce fine-grain dependence analysis by tagging access functions and schedules tree with either the id of memory access or memory references.

Hongbin Zheng via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 26 09:05:25 PST 2016


Author: ether
Date: Fri Feb 26 11:05:24 2016
New Revision: 262039

URL: http://llvm.org/viewvc/llvm-project?rev=262039&view=rev
Log:
Introduce fine-grain dependence analysis by tagging access functions and schedules tree with either the id of memory access or memory references.

Differential Revision: http://reviews.llvm.org/D17381

Added:
    polly/trunk/test/DependenceInfo/fine_grain_dep_0.ll
Modified:
    polly/trunk/lib/Analysis/DependenceInfo.cpp
    polly/trunk/test/DependenceInfo/reduction_complex_location.ll
    polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum.ll
    polly/trunk/test/DependenceInfo/sequential_loops.ll

Modified: polly/trunk/lib/Analysis/DependenceInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/DependenceInfo.cpp?rev=262039&r1=262038&r2=262039&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/DependenceInfo.cpp (original)
+++ polly/trunk/lib/Analysis/DependenceInfo.cpp Fri Feb 26 11:05:24 2016
@@ -70,8 +70,53 @@ static cl::opt<enum AnalysisType> OptAna
     cl::Hidden, cl::init(VALUE_BASED_ANALYSIS), cl::ZeroOrMore,
     cl::cat(PollyCategory));
 
+enum AnalyisLevel {
+  STATEMENT_LEVEL_ANALYSIS = 0,
+  REFERENCE_LEVEL_ANALYSIS,
+  ACCESS_LEVEL_ANALYSIS
+};
+static cl::opt<enum AnalyisLevel> OptAnalysisLevel(
+    "polly-dependences-analysis-level",
+    cl::desc("The level of dependence analysis"),
+    cl::values(clEnumValN(STATEMENT_LEVEL_ANALYSIS, "statement-level",
+                          "Statement-level analysis"),
+               clEnumValN(REFERENCE_LEVEL_ANALYSIS, "reference-level",
+                          "Memory reference level analysis that distinguish"
+                          " accessed references in the same statement"),
+               clEnumValN(ACCESS_LEVEL_ANALYSIS, "access-level",
+                          "Memory reference level analysis that distinguish"
+                          " access instructions in the same statement"),
+               clEnumValEnd),
+    cl::Hidden, cl::init(STATEMENT_LEVEL_ANALYSIS), cl::ZeroOrMore,
+    cl::cat(PollyCategory));
+
 //===----------------------------------------------------------------------===//
 
+/// @brief Tag the @p Relation domain with @p TagId
+static __isl_give isl_map *tag(__isl_take isl_map *Relation,
+                               __isl_take isl_id *TagId) {
+  isl_space *Space = isl_map_get_space(Relation);
+  Space = isl_space_drop_dims(Space, isl_dim_out, 0, isl_map_n_out(Relation));
+  Space = isl_space_set_tuple_id(Space, isl_dim_out, TagId);
+  isl_multi_aff *Tag = isl_multi_aff_domain_map(Space);
+  Relation = isl_map_preimage_domain_multi_aff(Relation, Tag);
+  return Relation;
+}
+
+/// @brief Tag the @p Relation domain with either MA->getArrayId() or
+///        MA->getId() based on @p TagLevel
+static __isl_give isl_map *tag(__isl_take isl_map *Relation, MemoryAccess *MA,
+                               AnalyisLevel TagLevel) {
+  if (TagLevel == REFERENCE_LEVEL_ANALYSIS)
+    return tag(Relation, MA->getArrayId());
+
+  if (TagLevel == ACCESS_LEVEL_ANALYSIS)
+    return tag(Relation, MA->getId());
+
+  // No need to tag at the statement level.
+  return Relation;
+}
+
 /// @brief Collect information about the SCoP @p S.
 static void collectInfo(Scop &S, isl_union_map **Read, isl_union_map **Write,
                         isl_union_map **MayWrite,
@@ -116,7 +161,14 @@ static void collectInfo(Scop &S, isl_uni
             Schedule,
             isl_map_reverse(isl_map_domain_map(isl_map_copy(accdom))));
         accdom = isl_map_range_map(accdom);
+
         *AccessSchedule = isl_union_map_add_map(*AccessSchedule, Schedule);
+      } else {
+        accdom = tag(accdom, MA, OptAnalysisLevel);
+        if (OptAnalysisLevel > STATEMENT_LEVEL_ANALYSIS) {
+          isl_map *Schedule = tag(Stmt.getSchedule(), MA, OptAnalysisLevel);
+          *StmtSchedule = isl_union_map_add_map(*StmtSchedule, Schedule);
+        }
       }
 
       if (MA->isRead())
@@ -124,7 +176,9 @@ static void collectInfo(Scop &S, isl_uni
       else
         *Write = isl_union_map_add_map(*Write, accdom);
     }
-    *StmtSchedule = isl_union_map_add_map(*StmtSchedule, Stmt.getSchedule());
+
+    if (OptAnalysisLevel == STATEMENT_LEVEL_ANALYSIS)
+      *StmtSchedule = isl_union_map_add_map(*StmtSchedule, Stmt.getSchedule());
   }
 
   *StmtSchedule =
@@ -269,7 +323,11 @@ static __isl_give isl_union_flow *buildF
   if (Src)
     AI = isl_union_access_info_set_must_source(AI, isl_union_map_copy(Src));
   AI = isl_union_access_info_set_schedule(AI, isl_schedule_copy(Schedule));
-  return isl_union_access_info_compute_flow(AI);
+  auto Flow = isl_union_access_info_compute_flow(AI);
+  DEBUG(if (!Flow) dbgs() << "last error: "
+                          << isl_ctx_last_error(isl_schedule_get_ctx(Schedule))
+                          << '\n';);
+  return Flow;
 }
 
 void Dependences::calculateDependences(Scop &S) {
@@ -280,9 +338,22 @@ void Dependences::calculateDependences(S
 
   collectInfo(S, &Read, &Write, &MayWrite, &AccessSchedule, &StmtSchedule);
 
+  DEBUG(dbgs() << "Read: " << Read << '\n';
+        dbgs() << "Write: " << Write << '\n';
+        dbgs() << "MayWrite: " << MayWrite << '\n';
+        dbgs() << "AccessSchedule: " << AccessSchedule << '\n';
+        dbgs() << "StmtSchedule: " << StmtSchedule << '\n';);
+
   if (isl_union_map_is_empty(AccessSchedule)) {
     isl_union_map_free(AccessSchedule);
     Schedule = S.getScheduleTree();
+    // Tag the schedule tree if we want fine-grain dependence info
+    if (OptAnalysisLevel > STATEMENT_LEVEL_ANALYSIS) {
+      auto TaggedDom = isl_union_map_domain((isl_union_map_copy(StmtSchedule)));
+      auto TaggedMap = isl_union_set_unwrap(TaggedDom);
+      auto Tags = isl_union_map_domain_map_union_pw_multi_aff(TaggedMap);
+      Schedule = isl_schedule_pullback_union_pw_multi_aff(Schedule, Tags);
+    }
   } else {
     auto *ScheduleMap =
         isl_union_map_union(AccessSchedule, isl_union_map_copy(StmtSchedule));
@@ -304,7 +375,8 @@ void Dependences::calculateDependences(S
 
   DEBUG(dbgs() << "Read: " << Read << "\n";
         dbgs() << "Write: " << Write << "\n";
-        dbgs() << "MayWrite: " << MayWrite << "\n");
+        dbgs() << "MayWrite: " << MayWrite << "\n";
+        dbgs() << "Schedule: " << Schedule << "\n");
 
   RAW = WAW = WAR = RED = nullptr;
 

Added: polly/trunk/test/DependenceInfo/fine_grain_dep_0.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/fine_grain_dep_0.ll?rev=262039&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/fine_grain_dep_0.ll (added)
+++ polly/trunk/test/DependenceInfo/fine_grain_dep_0.ll Fri Feb 26 11:05:24 2016
@@ -0,0 +1,63 @@
+; RUN: opt %loadPolly -polly-dependences -polly-dependences-analysis-type=value-based -polly-dependences-analysis-level=reference-level -analyze < %s | FileCheck %s
+;
+; CHECK:      RAW dependences:
+; CHECK-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 }
+; CHECK-NEXT: WAR dependences:
+; CHECK-NEXT:     {  }
+; CHECK-NEXT: WAW dependences:
+; CHECK-NEXT:     {  }
+; CHECK-NEXT: Reduction dependences:
+; CHECK-NEXT:     {  }
+;
+; void test(char a[], char b[], long N) {
+;   for (long i = 6; i < N; ++i) {
+;     a[i] = a[i - 4] + i;
+;     b[i] = b[i - 6] + i;
+;   }
+; }
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define void @test(i8* %a, i8* %b, i64 %N) #0 {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i64 [ 6, %entry ], [ %inc, %for.inc ]
+  %cmp = icmp slt i64 %i.0, %N
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %sub = sub nsw i64 %i.0, 4
+  %arrayidx = getelementptr inbounds i8, i8* %a, i64 %sub
+  %0 = load i8, i8* %arrayidx, align 1
+  %conv = sext i8 %0 to i64
+  %add = add nsw i64 %conv, %i.0
+  %conv1 = trunc i64 %add to i8
+  %arrayidx2 = getelementptr inbounds i8, i8* %a, i64 %i.0
+  store i8 %conv1, i8* %arrayidx2, align 1
+  %sub3 = sub nsw i64 %i.0, 6
+  %arrayidx4 = getelementptr inbounds i8, i8* %b, i64 %sub3
+  %1 = load i8, i8* %arrayidx4, align 1
+  %conv5 = sext i8 %1 to i64
+  %add6 = add nsw i64 %conv5, %i.0
+  %conv7 = trunc i64 %add6 to i8
+  %arrayidx8 = getelementptr inbounds i8, i8* %b, i64 %i.0
+  store i8 %conv7, i8* %arrayidx8, align 1
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %inc = add nsw i64 %i.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
+
+attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.ident = !{!0}
+
+!0 = !{!"clang version 3.9.0 (http://llvm.org/git/clang.git 3d5d4c39659f11dfbe8e11c857cadf5c449b559b) (http://llvm.org/git/llvm.git 801561e2bba12f2aa0285feb1105e110df443761)"}

Modified: polly/trunk/test/DependenceInfo/reduction_complex_location.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_complex_location.ll?rev=262039&r1=262038&r2=262039&view=diff
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_complex_location.ll (original)
+++ polly/trunk/test/DependenceInfo/reduction_complex_location.ll Fri Feb 26 11:05:24 2016
@@ -1,4 +1,6 @@
 ; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-dependences -polly-dependences-analysis-level=reference-level -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-dependences -polly-dependences-analysis-level=access-level -analyze < %s | FileCheck %s
 ;
 ; CHECK:      RAW dependences:
 ; CHECK-NEXT:     {  }

Modified: polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum.ll?rev=262039&r1=262038&r2=262039&view=diff
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum.ll (original)
+++ polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum.ll Fri Feb 26 11:05:24 2016
@@ -1,4 +1,6 @@
 ; RUN: opt -basicaa %loadPolly -polly-dependences -analyze < %s | FileCheck %s
+; RUN: opt -basicaa %loadPolly -polly-dependences -polly-dependences-analysis-level=reference-level -analyze < %s | FileCheck %s
+; RUN: opt -basicaa %loadPolly -polly-dependences -polly-dependences-analysis-level=access-level -analyze < %s | FileCheck %s
 ;
 ; Verify that only the inner reduction like accesses cause reduction dependences
 ;

Modified: polly/trunk/test/DependenceInfo/sequential_loops.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/sequential_loops.ll?rev=262039&r1=262038&r2=262039&view=diff
==============================================================================
--- polly/trunk/test/DependenceInfo/sequential_loops.ll (original)
+++ polly/trunk/test/DependenceInfo/sequential_loops.ll Fri Feb 26 11:05:24 2016
@@ -1,5 +1,6 @@
 ; RUN: opt -S %loadPolly -basicaa -polly-dependences -analyze -polly-dependences-analysis-type=value-based < %s | FileCheck %s -check-prefix=VALUE
 ; RUN: opt -S %loadPolly -basicaa -polly-dependences -analyze -polly-dependences-analysis-type=memory-based < %s | FileCheck %s -check-prefix=MEMORY
+; RUN: opt -S %loadPolly -basicaa -polly-dependences -analyze -polly-dependences-analysis-type=value-based -polly-dependences-analysis-level=access-level < %s | FileCheck %s -check-prefix=VALUE_ACCESS
 
 ; VALUE-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.3' in function 'sequential_writes':
 ; VALUE-NEXT:      RAW dependences:
@@ -9,6 +10,14 @@
 ; 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 }
 ;
+;VALUE_ACCESS-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.3' in function 'sequential_writes':
+;VALUE_ACCESS-NEXT:        RAW dependences:
+;VALUE_ACCESS-NEXT:                {  }
+;VALUE_ACCESS-NEXT:        WAR dependences:
+;VALUE_ACCESS-NEXT:                {  }
+;VALUE_ACCESS-NEXT:        WAW dependences:
+;VALUE_ACCESS-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 }
+;
 ; VALUE-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.3' in function 'read_after_writes':
 ; VALUE-NEXT:      RAW dependences:
 ; VALUE-NEXT:          { Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9; Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99 }
@@ -17,6 +26,14 @@
 ; VALUE-NEXT:      WAW dependences:
 ; VALUE-NEXT:          { Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9 }
 ;
+;VALUE_ACCESS-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.3' in function 'read_after_writes':
+;VALUE_ACCESS-NEXT:        RAW dependences:
+;VALUE_ACCESS-NEXT:                { [Stmt_S1[i0] -> Stmt_S1_Write0_MemRef_A[]] -> [Stmt_S3[i0] -> Stmt_S3_Read0_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_Read0_MemRef_A[]] : 0 <= i0 <= 9; Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99 }
+;VALUE_ACCESS-NEXT:        WAR dependences:
+;VALUE_ACCESS-NEXT:                {  }
+;VALUE_ACCESS-NEXT:        WAW dependences:
+;VALUE_ACCESS-NEXT:                { Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Write0_MemRef_A[]] -> [Stmt_S2[i0] -> Stmt_S2_Write0_MemRef_A[]] : 0 <= i0 <= 9 }
+;
 ; VALUE-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.3' in function 'write_after_read':
 ; VALUE-NEXT:      RAW dependences:
 ; VALUE-NEXT:          {  }
@@ -25,6 +42,14 @@
 ; VALUE-NEXT:      WAW dependences:
 ; VALUE-NEXT:          { Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9 }
 ;
+;VALUE_ACCESS-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.3' in function 'write_after_read':
+;VALUE_ACCESS-NEXT:         RAW dependences:
+;VALUE_ACCESS-NEXT:                 {  }
+;VALUE_ACCESS-NEXT:         WAR dependences:
+;VALUE_ACCESS-NEXT:                { Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Read0_MemRef_A[]] -> [Stmt_S2[i0] -> Stmt_S2_Write0_MemRef_A[]] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Read0_MemRef_A[]] -> [Stmt_S3[i0] -> Stmt_S3_Write0_MemRef_A[]] : 10 <= i0 <= 99; Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99 }
+;VALUE_ACCESS-NEXT:         WAW dependences:
+;VALUE_ACCESS-NEXT:                { 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 }
+;
 ; VALUE-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.2' in function 'parametric_offset':
 ; VALUE-NEXT:      RAW dependences:
 ; VALUE-NEXT:          [p] -> { Stmt_S1[i0] -> Stmt_S2[-p + i0] : i0 >= p and 0 <= i0 <= 99 and i0 <= 9 + p }
@@ -32,6 +57,14 @@
 ; VALUE-NEXT:          [p] -> {  }
 ; VALUE-NEXT:      WAW dependences:
 ; VALUE-NEXT:          [p] -> {  }
+;
+;VALUE_ACCESS-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.2' in function 'parametric_offset':
+;VALUE_ACCESS-NEXT:        RAW dependences:
+;VALUE_ACCESS-NEXT:                [p] -> { [Stmt_S1[i0] -> Stmt_S1_Write0_MemRef_A[]] -> [Stmt_S2[-p + i0] -> Stmt_S2_Read0_MemRef_A[]] : i0 >= p and 0 <= i0 <= 99 and i0 <= 9 + p; Stmt_S1[i0] -> Stmt_S2[-p + i0] : i0 >= p and 0 <= i0 <= 99 and i0 <= 9 + p }
+;VALUE_ACCESS-NEXT:        WAR dependences:
+;VALUE_ACCESS-NEXT:                [p] -> {  }
+;VALUE_ACCESS-NEXT:        WAW dependences:
+;VALUE_ACCESS-NEXT:                [p] -> {  }
 
 ; MEMORY-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.3' in function 'sequential_writes':
 ; MEMORY-NEXT:      RAW dependences:




More information about the llvm-commits mailing list