Index: lib/CodeGen/PPCGCodeGeneration.cpp =================================================================== --- lib/CodeGen/PPCGCodeGeneration.cpp +++ lib/CodeGen/PPCGCodeGeneration.cpp @@ -2632,6 +2632,77 @@ return Names; } + /// Remove unreferenced parameter dimensions from union_map. + isl::union_map removeUnusedParameters(isl::union_map UMap) { + auto New = isl::union_map::empty(isl::space(UMap.get_ctx(), 0, 0)); + + auto Lambda = [&New](isl::map S) -> isl::stat { + int Removed = 0; + int NumDims = S.dim(isl::dim::param); + for (long i = 0; i < NumDims; i++) { + int Dim = i - Removed; + if (!S.involves_dims(isl::dim::param, Dim, 1)) { + S = S.remove_dims(isl::dim::param, Dim, 1); + Removed++; + } + } + New = New.unite(S); + return isl::stat::ok; + }; + + UMap.foreach_map(Lambda); + return New; + } + + /// Remove unreferenced parameter dimensions from union_set. + isl::union_set removeUnusedParameters(isl::union_set USet) { + auto New = isl::union_set::empty(isl::space(USet.get_ctx(), 0, 0)); + + auto Lambda = [&New](isl::set S) -> isl::stat { + int Removed = 0; + int NumDims = S.dim(isl::dim::param); + for (long i = 0; i < NumDims; i++) { + int Dim = i - Removed; + if (!S.involves_dims(isl::dim::param, Dim, 1)) { + S = S.remove_dims(isl::dim::param, Dim, 1); + Removed++; + } + } + New = New.unite(S); + return isl::stat::ok; + }; + + USet.foreach_set(Lambda); + return New; + } + + /// Simplify PPCG scop to improve compile time. + /// + /// We drop unused parameter dimensions to reduce the size of the sets we are + /// working with. Especially the computed dependences tend to accumulate a lot + /// of parameters that are present in the input memory accesses, but often are + /// not necessary to express the actual dependences. As isl represents maps + /// and sets with dense matrices, reducing the dimensionality of isl sets + /// commonly reduces code generation performance. + void simplifyPPCGScop(ppcg_scop *PPCGScop) { + PPCGScop->domain = + removeUnusedParameters(isl::manage(PPCGScop->domain)).release(); + + PPCGScop->dep_forced = + removeUnusedParameters(isl::manage(PPCGScop->dep_forced)).release(); + PPCGScop->dep_false = + removeUnusedParameters(isl::manage(PPCGScop->dep_false)).release(); + PPCGScop->dep_flow = + removeUnusedParameters(isl::manage(PPCGScop->dep_flow)).release(); + PPCGScop->tagged_dep_flow = + removeUnusedParameters(isl::manage(PPCGScop->tagged_dep_flow)) + .release(); + + PPCGScop->tagged_dep_order = + removeUnusedParameters(isl::manage(PPCGScop->tagged_dep_order)) + .release(); + } + /// Create a new PPCG scop from the current scop. /// /// The PPCG scop is initialized with data from the current polly::Scop. From @@ -2689,6 +2760,7 @@ compute_tagger(PPCGScop); compute_dependences(PPCGScop); eliminate_dead_code(PPCGScop); + simplifyPPCGScop(PPCGScop); return PPCGScop; } @@ -3132,8 +3204,12 @@ int has_permutable = has_any_permutable_node(Schedule); - Schedule = - isl_schedule_align_params(Schedule, S->getFullParamSpace().release()); + /// Copy to and from device functions may introduce new parameters, which + /// must be present in the schedule tree root for code generation. Hence, + /// we ensure that all possible parameters are introduced from this point. + if (!PollyManagedMemory) + Schedule = + isl_schedule_align_params(Schedule, S->getFullParamSpace().release()); if (!has_permutable || has_permutable < 0) { Schedule = isl_schedule_free(Schedule);