From: Johannes Doerfert Date: Mon, 28 Jul 2014 03:46:28 +0000 (+0000) Subject: Replace the dependences parallelism check by the IslAst one X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=515f85770cbd6127185e7dc6746429b08c2ebe43;p=platform%2Fupstream%2Fllvm.git Replace the dependences parallelism check by the IslAst one llvm-svn: 214061 --- diff --git a/polly/include/polly/Dependences.h b/polly/include/polly/Dependences.h index b305660..240bb7c 100755 --- a/polly/include/polly/Dependences.h +++ b/polly/include/polly/Dependences.h @@ -85,17 +85,15 @@ public: // dependences. bool isValidScattering(StatementToIslMapTy *NewScatterings); - /// @brief Check if a dimension of the Scop can be executed in parallel. + /// @brief Check if a partial schedule is parallel wrt to @p Deps. /// - /// @param LoopDomain The subset of the scattering space that is executed in - /// parallel. - /// @param ParallelDimension The scattering dimension that is being executed - /// in parallel. + /// @param Schedule The subset of the scattering space that we want to check. + /// @param Deps The dependences @p Schedule needs to respect. /// - /// @return bool Returns true, if executing parallelDimension in parallel is - /// valid for the scattering domain subset given. - bool isParallelDimension(__isl_take isl_set *LoopDomain, - unsigned ParallelDimension); + /// @return Returns true, if executing parallel the outermost dimension of + /// @p Schedule is valid according to the dependences @p Deps. + bool isParallel(__isl_keep isl_union_map *Schedule, + __isl_take isl_union_map *Deps); /// @brief Get the dependences in this Scop. /// diff --git a/polly/lib/Analysis/Dependences.cpp b/polly/lib/Analysis/Dependences.cpp index 2a6b16d..715b88b 100644 --- a/polly/lib/Analysis/Dependences.cpp +++ b/polly/lib/Analysis/Dependences.cpp @@ -437,76 +437,43 @@ bool Dependences::isValidScattering(StatementToIslMapTy *NewScattering) { return IsValid; } -isl_union_map *getCombinedScheduleForSpace(Scop *scop, unsigned dimLevel) { - isl_space *Space = scop->getParamSpace(); - isl_union_map *schedule = isl_union_map_empty(Space); - - for (ScopStmt *Stmt : *scop) { - unsigned remainingDimensions = Stmt->getNumScattering() - dimLevel; - isl_map *Scattering = isl_map_project_out( - Stmt->getScattering(), isl_dim_out, dimLevel, remainingDimensions); - schedule = isl_union_map_add_map(schedule, Scattering); - } - - return schedule; -} - -bool Dependences::isParallelDimension(__isl_take isl_set *ScheduleSubset, - unsigned ParallelDim) { - // To check if a loop is parallel, we perform the following steps: - // - // o Move dependences from 'Domain -> Domain' to 'Schedule -> Schedule' space. - // o Limit dependences to the schedule space enumerated by the loop. - // o Calculate distances of the dependences. - // o Check if one of the distances is invalid in presence of parallelism. - - isl_union_map *Schedule, *Deps; - isl_map *ScheduleDeps; - Scop *S = &getCurScop(); - - if (!hasValidDependences()) { - isl_set_free(ScheduleSubset); - return false; - } - - // FIXME: We can remove ignore reduction dependences in case we privatize the - // memory locations the reduction statements reduce into. - Deps = getDependences(TYPE_RAW | TYPE_WAW | TYPE_WAR | TYPE_RED); - - if (isl_union_map_is_empty(Deps)) { - isl_union_map_free(Deps); - isl_set_free(ScheduleSubset); - return true; - } +// Check if the current scheduling dimension is parallel. +// +// We check for parallelism by verifying that the loop does not carry any +// dependences. +// +// Parallelism test: if the distance is zero in all outer dimensions, then it +// has to be zero in the current dimension as well. +// +// Implementation: first, translate dependences into time space, then force +// outer dimensions to be equal. If the distance is zero in the current +// dimension, then the loop is parallel. The distance is zero in the current +// dimension if it is a subset of a map with equal values for the current +// dimension. +bool Dependences::isParallel(isl_union_map *Schedule, isl_union_map *Deps) { + isl_map *ScheduleDeps, *Test; + unsigned Dimension, IsParallel; - Schedule = getCombinedScheduleForSpace(S, ParallelDim); Deps = isl_union_map_apply_range(Deps, isl_union_map_copy(Schedule)); - Deps = isl_union_map_apply_domain(Deps, Schedule); + Deps = isl_union_map_apply_domain(Deps, isl_union_map_copy(Schedule)); if (isl_union_map_is_empty(Deps)) { isl_union_map_free(Deps); - isl_set_free(ScheduleSubset); return true; } ScheduleDeps = isl_map_from_union_map(Deps); - ScheduleDeps = - isl_map_intersect_domain(ScheduleDeps, isl_set_copy(ScheduleSubset)); - ScheduleDeps = isl_map_intersect_range(ScheduleDeps, ScheduleSubset); - - isl_set *Distances = isl_map_deltas(ScheduleDeps); - isl_space *Space = isl_set_get_space(Distances); - isl_set *Invalid = isl_set_universe(Space); + Dimension = isl_map_dim(ScheduleDeps, isl_dim_out) - 1; - // [0, ..., 0, +] - All zeros and last dimension larger than zero - for (unsigned i = 0; i < ParallelDim - 1; i++) - Invalid = isl_set_fix_si(Invalid, isl_dim_set, i, 0); + for (unsigned i = 0; i < Dimension; i++) + ScheduleDeps = isl_map_equate(ScheduleDeps, isl_dim_out, i, isl_dim_in, i); - Invalid = isl_set_lower_bound_si(Invalid, isl_dim_set, ParallelDim - 1, 1); - Invalid = isl_set_intersect(Invalid, Distances); + Test = isl_map_universe(isl_map_get_space(ScheduleDeps)); + Test = isl_map_equate(Test, isl_dim_out, Dimension, isl_dim_in, Dimension); + IsParallel = isl_map_is_subset(ScheduleDeps, Test); - bool IsParallel = isl_set_is_empty(Invalid); - isl_set_free(Invalid); + isl_map_free(Test); + isl_map_free(ScheduleDeps); return IsParallel; } diff --git a/polly/lib/CodeGen/CodeGeneration.cpp b/polly/lib/CodeGen/CodeGeneration.cpp index 1f093fb..56b2ab3 100644 --- a/polly/lib/CodeGen/CodeGeneration.cpp +++ b/polly/lib/CodeGen/CodeGeneration.cpp @@ -861,13 +861,35 @@ void ClastStmtCodeGen::codegenForVector(const clast_for *F) { ClastVars.erase(F->iterator); } +static isl_union_map *getCombinedScheduleForSpace(Scop *S, unsigned dimLevel) { + isl_space *Space = S->getParamSpace(); + isl_union_map *schedule = isl_union_map_empty(Space); + + for (ScopStmt *Stmt : *S) { + unsigned remainingDimensions = Stmt->getNumScattering() - dimLevel; + isl_map *Scattering = isl_map_project_out( + Stmt->getScattering(), isl_dim_out, dimLevel, remainingDimensions); + schedule = isl_union_map_add_map(schedule, Scattering); + } + + return schedule; +} + bool ClastStmtCodeGen::isParallelFor(const clast_for *f) { isl_set *Domain = isl_set_copy(isl_set_from_cloog_domain(f->domain)); assert(Domain && "Cannot access domain of loop"); Dependences &D = P->getAnalysis(); - - return D.isParallelDimension(Domain, isl_set_n_dim(Domain)); + isl_union_map *Deps = + D.getDependences(Dependences::TYPE_RAW | Dependences::TYPE_WAW | + Dependences::TYPE_WAR | Dependences::TYPE_RAW); + isl_union_map *Schedule = + getCombinedScheduleForSpace(S, isl_set_n_dim(Domain)); + Schedule = + isl_union_map_intersect_range(Schedule, isl_union_set_from_set(Domain)); + bool IsParallel = D.isParallel(Schedule, Deps); + isl_union_map_free(Schedule); + return IsParallel; } void ClastStmtCodeGen::codegen(const clast_for *f) { diff --git a/polly/lib/CodeGen/IslAst.cpp b/polly/lib/CodeGen/IslAst.cpp index eb82a41..471cbb1 100644 --- a/polly/lib/CodeGen/IslAst.cpp +++ b/polly/lib/CodeGen/IslAst.cpp @@ -139,56 +139,6 @@ printFor(__isl_take isl_printer *Printer, return Printer; } -// Check if the current scheduling dimension is parallel. -// -// We check for parallelism by verifying that the loop does not carry any -// dependences. -// -// Parallelism test: if the distance is zero in all outer dimensions, then it -// has to be zero in the current dimension as well. -// -// Implementation: first, translate dependences into time space, then force -// outer dimensions to be equal. If the distance is zero in the current -// dimension, then the loop is parallel. The distance is zero in the current -// dimension if it is a subset of a map with equal values for the current -// dimension. -static bool astScheduleDimIsParallel(__isl_keep isl_ast_build *Build, - __isl_take isl_union_map *Deps) { - isl_union_map *Schedule; - isl_map *ScheduleDeps, *Test; - isl_space *ScheduleSpace; - unsigned Dimension, IsParallel; - - Schedule = isl_ast_build_get_schedule(Build); - ScheduleSpace = isl_ast_build_get_schedule_space(Build); - - Dimension = isl_space_dim(ScheduleSpace, isl_dim_out) - 1; - - Deps = isl_union_map_apply_range(Deps, isl_union_map_copy(Schedule)); - Deps = isl_union_map_apply_domain(Deps, Schedule); - - if (isl_union_map_is_empty(Deps)) { - isl_union_map_free(Deps); - isl_space_free(ScheduleSpace); - return true; - } - - ScheduleDeps = isl_map_from_union_map(Deps); - - for (unsigned i = 0; i < Dimension; i++) - ScheduleDeps = isl_map_equate(ScheduleDeps, isl_dim_out, i, isl_dim_in, i); - - Test = isl_map_universe(isl_map_get_space(ScheduleDeps)); - Test = isl_map_equate(Test, isl_dim_out, Dimension, isl_dim_in, Dimension); - IsParallel = isl_map_is_subset(ScheduleDeps, Test); - - isl_space_free(ScheduleSpace); - isl_map_free(Test); - isl_map_free(ScheduleDeps); - - return IsParallel; -} - /// @brief Check if the current scheduling dimension is parallel /// /// In case the dimension is parallel we also check if any reduction @@ -205,15 +155,17 @@ static bool astScheduleDimIsParallel(__isl_keep isl_ast_build *Build, if (!D->hasValidDependences()) return false; + isl_union_map *Schedule = isl_ast_build_get_schedule(Build); isl_union_map *Deps = D->getDependences( Dependences::TYPE_RAW | Dependences::TYPE_WAW | Dependences::TYPE_WAR); - if (!astScheduleDimIsParallel(Build, Deps)) + if (!D->isParallel(Schedule, Deps) && !isl_union_map_free(Schedule)) return false; isl_union_map *RedDeps = D->getDependences(Dependences::TYPE_TC_RED); - if (!astScheduleDimIsParallel(Build, RedDeps)) + if (!D->isParallel(Schedule, RedDeps)) IsReductionParallel = true; + isl_union_map_free(Schedule); return true; }