From c2f151084d3ae3d9c04d0d7125c863612f8c34f5 Mon Sep 17 00:00:00 2001 From: Tobias Grosser Date: Wed, 1 Mar 2017 21:11:27 +0000 Subject: [PATCH] [ScopInfo] Disable memory folding in case it results in multi-disjunct relations Multi-disjunct access maps can easily result in inbound assumptions which explode in case of many memory accesses and many parameters. This change reduces compilation time of some larger kernel from over 15 minutes to less than 16 seconds. Interesting is the test case test/ScopInfo/multidim_param_in_subscript.ll which has a memory access [n] -> { Stmt_for_body3[i0, i1] -> MemRef_A[i0, -1 + n - i1] } which requires folding, but where only a single disjunct remains. We can still model this test case even when only using limited memory folding. For people only reading commit messages, here the comment that explains what memory folding is: To recover memory accesses with array size parameters in the subscript expression we post-process the delinearization results. We would normally recover from an access A[exp0(i) * N + exp1(i)] into an array A[][N] the 2D access A[exp0(i)][exp1(i)]. However, another valid delinearization is A[exp0(i) - 1][exp1(i) + N] which - depending on the range of exp1(i) - may be preferrable. Specifically, for cases where we know exp1(i) is negative, we want to choose the latter expression. As we commonly do not have any information about the range of exp1(i), we do not choose one of the two options, but instead create a piecewise access function that adds the (-1, N) offsets as soon as exp1(i) becomes negative. For a 2D array such an access function is created by applying the piecewise map: [i,j] -> [i, j] : j >= 0 [i,j] -> [i-1, j+N] : j < 0 After this patch we generate only the first case, except for situations where we can proove the first case to be invalid and can consequently select the second without introducing disjuncts. llvm-svn: 296679 --- polly/lib/Analysis/ScopInfo.cpp | 19 +++++++++++++++++++ .../test/Isl/Ast/simple-run-time-condition.ll | 1 + .../ScopInfo/multidim_fortran_2d_params.ll | 1 + ...multidim_ivs_and_parameteric_offsets_3d.ll | 3 ++- .../ScopInfo/multidim_param_in_subscript-2.ll | 3 ++- 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index 5cc84e096838..5930380cc0bc 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -142,6 +142,11 @@ static cl::opt PollyPreciseInbounds( cl::desc("Take more precise inbounds assumptions (do not scale well)"), cl::Hidden, cl::init(false), cl::cat(PollyCategory)); +static cl::opt PollyPreciseFoldAccesses( + "polly-precise-fold-accesses", + cl::desc("Fold memory accesses to modele more possible delinearizations " + "(do not scale well)"), + cl::Hidden, cl::init(false), cl::cat(PollyCategory)); //===----------------------------------------------------------------------===// // Create a sequence of two schedules. Either argument may be null and is @@ -790,6 +795,8 @@ void MemoryAccess::foldAccessRelation() { int Size = Subscripts.size(); + isl_map *OldAccessRelation = isl_map_copy(AccessRelation); + for (int i = Size - 2; i >= 0; --i) { isl_space *Space; isl_map *MapOne, *MapTwo; @@ -841,6 +848,18 @@ void MemoryAccess::foldAccessRelation() { AccessRelation = isl_map_set_tuple_id(AccessRelation, isl_dim_out, BaseAddrId); AccessRelation = isl_map_gist_domain(AccessRelation, Statement->getDomain()); + + // Access dimension folding might in certain cases increase the number of + // disjuncts in the memory access, which can possibly complicate the generated + // run-time checks and can lead to costly compilation. + if (!PollyPreciseFoldAccesses && isl_map_n_basic_map(AccessRelation) > + isl_map_n_basic_map(OldAccessRelation)) { + isl_map_free(AccessRelation); + AccessRelation = OldAccessRelation; + } else { + isl_map_free(OldAccessRelation); + } + isl_space_free(Space); } diff --git a/polly/test/Isl/Ast/simple-run-time-condition.ll b/polly/test/Isl/Ast/simple-run-time-condition.ll index b02db7b1d3ac..aba5d9e34f50 100644 --- a/polly/test/Isl/Ast/simple-run-time-condition.ll +++ b/polly/test/Isl/Ast/simple-run-time-condition.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-ast -analyze -polly-precise-inbounds < %s \ +; RUN: -polly-precise-fold-accesses \ ; RUN: | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/polly/test/ScopInfo/multidim_fortran_2d_params.ll b/polly/test/ScopInfo/multidim_fortran_2d_params.ll index cc3082ce3302..d4fa53d8ca40 100644 --- a/polly/test/ScopInfo/multidim_fortran_2d_params.ll +++ b/polly/test/ScopInfo/multidim_fortran_2d_params.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -analyze \ +; RUN: -polly-precise-fold-accesses \ ; RUN: -polly-invariant-load-hoisting=true < %s | FileCheck %s ; subroutine init_array(ni, nj, pi, pj, a) diff --git a/polly/test/ScopInfo/multidim_ivs_and_parameteric_offsets_3d.ll b/polly/test/ScopInfo/multidim_ivs_and_parameteric_offsets_3d.ll index 8ce6bad1b1f7..22bfbab4e58d 100644 --- a/polly/test/ScopInfo/multidim_ivs_and_parameteric_offsets_3d.ll +++ b/polly/test/ScopInfo/multidim_ivs_and_parameteric_offsets_3d.ll @@ -1,4 +1,5 @@ -; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-scops -analyze < %s \ +; RUN: -polly-precise-fold-accesses | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" ; void foo(long n, long m, long o, double A[n][m][o], long p, long q, long r) { diff --git a/polly/test/ScopInfo/multidim_param_in_subscript-2.ll b/polly/test/ScopInfo/multidim_param_in_subscript-2.ll index 303d9130ac7a..b6c43e9b9776 100644 --- a/polly/test/ScopInfo/multidim_param_in_subscript-2.ll +++ b/polly/test/ScopInfo/multidim_param_in_subscript-2.ll @@ -1,4 +1,5 @@ -; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-scops -analyze \ +; RUN: -polly-precise-fold-accesses < %s | FileCheck %s ; ; void foo(long n, long m, float A[][n][m]) { ; for (long i = 0; i < 100; i++)