[polly] r211794 - Hybrid dependency analysis
Johannes Doerfert
jdoerfert at codeaurora.org
Thu Jun 26 11:38:08 PDT 2014
Author: jdoerfert
Date: Thu Jun 26 13:38:08 2014
New Revision: 211794
URL: http://llvm.org/viewvc/llvm-project?rev=211794&view=rev
Log:
Hybrid dependency analysis
This dependency analysis will keep track of memory accesses if they might be
part of a reduction. If not, the dependences are tracked on a statement level.
The main reason to do this is to reduce the compile time while beeing able to
distinguish the effects of reduction and non-reduction accesses.
+ Adjusted two test cases
Added:
polly/trunk/test/Dependences/reduction_simple_iv_debug_wrapped_dependences.ll
Modified:
polly/trunk/include/polly/Dependences.h
polly/trunk/lib/Analysis/Dependences.cpp
polly/trunk/test/Dependences/reduction_simple_iv.ll
Modified: polly/trunk/include/polly/Dependences.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/Dependences.h?rev=211794&r1=211793&r2=211794&view=diff
==============================================================================
--- polly/trunk/include/polly/Dependences.h (original)
+++ polly/trunk/include/polly/Dependences.h Thu Jun 26 13:38:08 2014
@@ -119,7 +119,8 @@ private:
/// @brief Collect information about the SCoP.
void collectInfo(Scop &S, isl_union_map **Read, isl_union_map **Write,
- isl_union_map **MayWrite, isl_union_map **Schedule);
+ isl_union_map **MayWrite, isl_union_map **AccessSchedule,
+ isl_union_map **StmtSchedule);
/// @brief Calculate and add at the privatization dependences
void addPrivatizationDependences();
Modified: polly/trunk/lib/Analysis/Dependences.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/Dependences.cpp?rev=211794&r1=211793&r2=211794&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/Dependences.cpp (original)
+++ polly/trunk/lib/Analysis/Dependences.cpp Thu Jun 26 13:38:08 2014
@@ -69,12 +69,20 @@ Dependences::Dependences() : ScopPass(ID
void Dependences::collectInfo(Scop &S, isl_union_map **Read,
isl_union_map **Write, isl_union_map **MayWrite,
- isl_union_map **Schedule) {
+ isl_union_map **AccessSchedule,
+ isl_union_map **StmtSchedule) {
isl_space *Space = S.getParamSpace();
*Read = isl_union_map_empty(isl_space_copy(Space));
*Write = isl_union_map_empty(isl_space_copy(Space));
*MayWrite = isl_union_map_empty(isl_space_copy(Space));
- *Schedule = isl_union_map_empty(Space);
+ *AccessSchedule = isl_union_map_empty(isl_space_copy(Space));
+ *StmtSchedule = isl_union_map_empty(Space);
+
+ SmallPtrSet<const Value *, 8> ReductionBaseValues;
+ for (ScopStmt *Stmt : S)
+ for (MemoryAccess *MA : *Stmt)
+ if (MA->isReductionLike())
+ ReductionBaseValues.insert(MA->getBaseAddr());
for (ScopStmt *Stmt : S) {
for (MemoryAccess *MA : *Stmt) {
@@ -83,12 +91,38 @@ void Dependences::collectInfo(Scop &S, i
accdom = isl_map_intersect_domain(accdom, domcp);
+ if (ReductionBaseValues.count(MA->getBaseAddr())) {
+ // Wrap the access domain and adjust the scattering accordingly.
+ //
+ // An access domain like
+ // Stmt[i0, i1] -> MemAcc_A[i0 + i1]
+ // will be transformed into
+ // [Stmt[i0, i1] -> MemAcc_A[i0 + i1]] -> MemAcc_A[i0 + i1]
+ //
+ // The original scattering looks like
+ // Stmt[i0, i1] -> [0, i0, 2, i1, 0]
+ // but as we transformed the access domain we need the scattering
+ // to match the new access domains, thus we need
+ // [Stmt[i0, i1] -> MemAcc_A[i0 + i1]] -> [0, i0, 2, i1, 0]
+ accdom = isl_map_range_map(accdom);
+
+ isl_map *stmt_scatter = Stmt->getScattering();
+ isl_set *scatter_dom = isl_map_domain(isl_map_copy(accdom));
+ isl_set *scatter_ran = isl_map_range(stmt_scatter);
+ isl_map *scatter =
+ isl_map_from_domain_and_range(scatter_dom, scatter_ran);
+ for (unsigned u = 0, e = Stmt->getNumIterators(); u != e; u++)
+ scatter =
+ isl_map_equate(scatter, isl_dim_out, 2 * u + 1, isl_dim_in, u);
+ *AccessSchedule = isl_union_map_add_map(*AccessSchedule, scatter);
+ }
+
if (MA->isRead())
*Read = isl_union_map_add_map(*Read, accdom);
else
*Write = isl_union_map_add_map(*Write, accdom);
}
- *Schedule = isl_union_map_add_map(*Schedule, Stmt->getScattering());
+ *StmtSchedule = isl_union_map_add_map(*StmtSchedule, Stmt->getScattering());
}
}
@@ -159,11 +193,15 @@ void Dependences::addPrivatizationDepend
}
void Dependences::calculateDependences(Scop &S) {
- isl_union_map *Read, *Write, *MayWrite, *Schedule;
+ isl_union_map *Read, *Write, *MayWrite, *AccessSchedule, *StmtSchedule,
+ *Schedule;
DEBUG(dbgs() << "Scop: \n" << S << "\n");
- collectInfo(S, &Read, &Write, &MayWrite, &Schedule);
+ collectInfo(S, &Read, &Write, &MayWrite, &AccessSchedule, &StmtSchedule);
+
+ Schedule =
+ isl_union_map_union(AccessSchedule, isl_union_map_copy(StmtSchedule));
Read = isl_union_map_coalesce(Read);
Write = isl_union_map_coalesce(Write);
@@ -235,6 +273,33 @@ void Dependences::calculateDependences(S
isl_ctx_reset_operations(S.getIslCtx());
isl_ctx_set_max_operations(S.getIslCtx(), MaxOpsOld);
+ isl_union_map *STMT_RAW, *STMT_WAW, *STMT_WAR;
+ STMT_RAW = isl_union_map_intersect_domain(
+ isl_union_map_copy(RAW),
+ isl_union_map_domain(isl_union_map_copy(StmtSchedule)));
+ STMT_WAW = isl_union_map_intersect_domain(
+ isl_union_map_copy(WAW),
+ isl_union_map_domain(isl_union_map_copy(StmtSchedule)));
+ STMT_WAR = isl_union_map_intersect_domain(isl_union_map_copy(WAR),
+ isl_union_map_domain(StmtSchedule));
+ DEBUG(dbgs() << "Wrapped Dependences:\n"; printScop(dbgs()); dbgs() << "\n");
+
+ RAW = isl_union_map_zip(RAW);
+ WAW = isl_union_map_zip(WAW);
+ WAR = isl_union_map_zip(WAR);
+
+ DEBUG(dbgs() << "Zipped Dependences:\n"; printScop(dbgs()); dbgs() << "\n");
+
+ RAW = isl_union_map_union(isl_union_set_unwrap(isl_union_map_domain(RAW)),
+ STMT_RAW);
+ WAW = isl_union_map_union(isl_union_set_unwrap(isl_union_map_domain(WAW)),
+ STMT_WAW);
+ WAR = isl_union_map_union(isl_union_set_unwrap(isl_union_map_domain(WAR)),
+ STMT_WAR);
+
+ DEBUG(dbgs() << "Unwrapped Dependences:\n"; printScop(dbgs());
+ dbgs() << "\n");
+
// To handle reduction dependences we proceed as follows:
// 1) Aggregate all possible reduction dependences, namely all self
// dependences on reduction like statements.
Modified: polly/trunk/test/Dependences/reduction_simple_iv.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Dependences/reduction_simple_iv.ll?rev=211794&r1=211793&r2=211794&view=diff
==============================================================================
--- polly/trunk/test/Dependences/reduction_simple_iv.ll (original)
+++ polly/trunk/test/Dependences/reduction_simple_iv.ll Thu Jun 26 13:38:08 2014
@@ -9,7 +9,6 @@
; CHECK: Reduction dependences:
; CHECK: { Stmt_for_cond[i0] -> Stmt_for_cond[1 + i0] : i0 <= 99 and i0 >= 0 }
;
-;
; void f(int* sum) {
; for (int i = 0; i <= 100; i++)
; sum += i * 3;
Added: polly/trunk/test/Dependences/reduction_simple_iv_debug_wrapped_dependences.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Dependences/reduction_simple_iv_debug_wrapped_dependences.ll?rev=211794&view=auto
==============================================================================
--- polly/trunk/test/Dependences/reduction_simple_iv_debug_wrapped_dependences.ll (added)
+++ polly/trunk/test/Dependences/reduction_simple_iv_debug_wrapped_dependences.ll Thu Jun 26 13:38:08 2014
@@ -0,0 +1,64 @@
+; RUN: opt %loadPolly -polly-dependences -analyze -debug-only=polly-dependence 2>&1 < %s | FileCheck %s
+;
+; REQUIRES: asserts
+;
+; CHECK: Read: { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> MemRef_sum[0] : i0 >= 0 and i0 <= 100 }
+; CHECK: Write: { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> MemRef_sum[0] : i0 >= 0 and i0 <= 100 }
+; CHECK: Schedule: { Stmt_for_cond[i0] -> scattering[0, i0, 0]; [Stmt_for_cond[i0] -> MemRef_sum[0]] -> scattering[0, i0, 0] : i0 <= 100 and i0 >= 0 }
+; CHECK: Wrapped Dependences:
+; CHECK: RAW dependences:
+; CHECK: { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> [Stmt_for_cond[1 + i0] -> MemRef_sum[0]] : i0 >= 0 and i0 <= 99 }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> [Stmt_for_cond[1 + i0] -> MemRef_sum[0]] : i0 >= 0 and i0 <= 99 }
+; CHECK: Reduction dependences:
+; CHECK: n/a
+; CHECK: Zipped Dependences:
+; CHECK: RAW dependences:
+; CHECK: { [Stmt_for_cond[i0] -> Stmt_for_cond[1 + i0]] -> [MemRef_sum[0] -> MemRef_sum[0]] : i0 >= 0 and i0 <= 99 }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { [Stmt_for_cond[i0] -> Stmt_for_cond[1 + i0]] -> [MemRef_sum[0] -> MemRef_sum[0]] : i0 >= 0 and i0 <= 99 }
+; CHECK: Reduction dependences:
+; CHECK: n/a
+; CHECK: Unwrapped Dependences:
+; CHECK: RAW dependences:
+; CHECK: { Stmt_for_cond[i0] -> Stmt_for_cond[1 + i0] : i0 >= 0 and i0 <= 99 }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { Stmt_for_cond[i0] -> Stmt_for_cond[1 + i0] : i0 >= 0 and i0 <= 99 }
+; CHECK: Reduction dependences:
+; CHECK: n/a
+;
+; void f(int* sum) {
+; for (int i = 0; i <= 100; i++)
+; sum += i * 3;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+ br label %entry.split1
+
+entry.split1: ; preds = %entry
+ br label %entry.split
+
+entry.split: ; preds = %entry.split1
+ br label %for.cond
+
+for.cond: ; preds = %for.cond, %entry.split
+ %i1.0 = phi i32 [ 0, %entry.split ], [ %inc, %for.cond ]
+ %sum.reload = load i32* %sum
+ %mul = mul nsw i32 %i1.0, 3
+ %add = add nsw i32 %sum.reload, %mul
+ %inc = add nsw i32 %i1.0, 1
+ store i32 %add, i32* %sum
+ %cmp = icmp slt i32 %i1.0, 100
+ br i1 %cmp, label %for.cond, label %for.end
+
+for.end: ; preds = %for.cond
+ ret void
+}
More information about the llvm-commits
mailing list