Index: lib/Analysis/DependenceInfo.cpp =================================================================== --- lib/Analysis/DependenceInfo.cpp +++ lib/Analysis/DependenceInfo.cpp @@ -70,8 +70,32 @@ cl::Hidden, cl::init(VALUE_BASED_ANALYSIS), cl::ZeroOrMore, cl::cat(PollyCategory)); +enum AnalyisLevel { STATEMENT_LEVEL_ANALYSIS, REFERENCE_LEVEL_ANALYSIS }; +static cl::opt 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 references in the same statement"), + clEnumValEnd), + cl::Hidden, cl::init(STATEMENT_LEVEL_ANALYSIS), cl::ZeroOrMore, + cl::cat(PollyCategory)); + //===----------------------------------------------------------------------===// +/// @brief +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 Collect information about the SCoP @p S. static void collectInfo(Scop &S, isl_union_map **Read, isl_union_map **Write, isl_union_map **MayWrite, @@ -98,6 +122,9 @@ accdom = isl_map_intersect_domain(accdom, domcp); + if (OptAnalysisLevel == REFERENCE_LEVEL_ANALYSIS) + accdom = tag(accdom, MA->getArrayId()); + if (ReductionBaseValues.count(MA->getBaseAddr())) { // Wrap the access domain and adjust the schedule accordingly. // @@ -123,8 +150,15 @@ *Read = isl_union_map_add_map(*Read, accdom); else *Write = isl_union_map_add_map(*Write, accdom); + + if (OptAnalysisLevel == REFERENCE_LEVEL_ANALYSIS) { + isl_map *Schedule = tag(Stmt.getSchedule(), MA->getArrayId()); + *StmtSchedule = isl_union_map_add_map(*StmtSchedule, Schedule); + } } - *StmtSchedule = isl_union_map_add_map(*StmtSchedule, Stmt.getSchedule()); + + if (OptAnalysisLevel == STATEMENT_LEVEL_ANALYSIS) + *StmtSchedule = isl_union_map_add_map(*StmtSchedule, Stmt.getSchedule()); } *StmtSchedule = @@ -262,7 +296,14 @@ collectInfo(S, &Read, &Write, &MayWrite, &AccessSchedule, &StmtSchedule); - if (isl_union_map_is_empty(AccessSchedule)) { + 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) && + OptAnalysisLevel == STATEMENT_LEVEL_ANALYSIS) { isl_union_map_free(AccessSchedule); Schedule = S.getScheduleTree(); } else { @@ -290,7 +331,8 @@ 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; @@ -302,7 +344,10 @@ AI = isl_union_access_info_set_must_source(AI, isl_union_map_copy(Write)); AI = isl_union_access_info_set_may_source(AI, isl_union_map_copy(MayWrite)); AI = isl_union_access_info_set_schedule(AI, isl_schedule_copy(Schedule)); + Flow = isl_union_access_info_compute_flow(AI); + DEBUG(if (!Flow) dbgs() + << "last error: " << isl_ctx_last_error(IslCtx.get()) << '\n';); RAW = isl_union_flow_get_must_dependence(Flow); isl_union_flow_free(Flow); @@ -333,6 +378,8 @@ AI = isl_union_access_info_set_may_source(AI, isl_union_map_copy(Write)); AI = isl_union_access_info_set_schedule(AI, isl_schedule_copy(Schedule)); Flow = isl_union_access_info_compute_flow(AI); + DEBUG(if (!Flow) dbgs() + << "last error: " << isl_ctx_last_error(IslCtx.get()) << '\n';); RAW = isl_union_flow_get_may_dependence(Flow); isl_union_flow_free(Flow); Index: test/DependenceInfo/access_level_dep_simple_0.ll =================================================================== --- /dev/null +++ test/DependenceInfo/access_level_dep_simple_0.ll @@ -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)"}