From: Sebastian Pop Date: Wed, 11 Apr 2007 17:10:23 +0000 (+0200) Subject: tree-data-ref.c (affine_function_zero_p, [...]): New. X-Git-Tag: releases/gcc-4.3.0~5705 X-Git-Url: https://gcc.gnu.org/git/?a=commitdiff_plain;h=1baf2906ef9aa2870b7162b51f9e5b15c7251031;p=gcc.git tree-data-ref.c (affine_function_zero_p, [...]): New. * tree-data-ref.c (affine_function_zero_p, constant_access_functions, insert_innermost_unit_dist_vector, add_distance_for_zero_overlaps): New. (build_classic_dist_vector): Call add_distance_for_zero_overlaps. From-SVN: r123721 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 98d5bc758891..6f757215f29e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2007-04-11 Sebastian Pop + + * tree-data-ref.c (affine_function_zero_p, constant_access_functions, + insert_innermost_unit_dist_vector, add_distance_for_zero_overlaps): New. + (build_classic_dist_vector): Call add_distance_for_zero_overlaps. + 2007-04-10 Zdenek Dvorak * tree-data-ref.c (add_multivariate_self_dist): Force the distance diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 7d8074679ea3..0340b9e8b005 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -2124,6 +2124,15 @@ affine_function_constant_p (affine_fn fn) return true; } +/* Returns true if FN is the zero constant function. */ + +static bool +affine_function_zero_p (affine_fn fn) +{ + return (integer_zerop (affine_function_base (fn)) + && affine_function_constant_p (fn)); +} + /* Applies operation OP on affine functions FNA and FNB, and returns the result. */ @@ -3847,6 +3856,22 @@ same_access_functions (struct data_dependence_relation *ddr) return true; } +/* Return true when the DDR contains only constant access functions. */ + +static bool +constant_access_functions (struct data_dependence_relation *ddr) +{ + unsigned i; + + for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++) + if (!evolution_function_is_constant_p (DR_ACCESS_FN (DDR_A (ddr), i)) + || !evolution_function_is_constant_p (DR_ACCESS_FN (DDR_B (ddr), i))) + return false; + + return true; +} + + /* Helper function for the case where DDR_A and DDR_B are the same multivariate access function. */ @@ -3928,6 +3953,53 @@ add_other_self_distances (struct data_dependence_relation *ddr) add_outer_distances (ddr, dist_v, index_carry); } +static void +insert_innermost_unit_dist_vector (struct data_dependence_relation *ddr) +{ + lambda_vector dist_v = lambda_vector_new (DDR_NB_LOOPS (ddr)); + + dist_v[DDR_INNER_LOOP (ddr)] = 1; + save_dist_v (ddr, dist_v); +} + +/* Adds a unit distance vector to DDR when there is a 0 overlap. This + is the case for example when access functions are the same and + equal to a constant, as in: + + | loop_1 + | A[3] = ... + | ... = A[3] + | endloop_1 + + in which case the distance vectors are (0) and (1). */ + +static void +add_distance_for_zero_overlaps (struct data_dependence_relation *ddr) +{ + unsigned i, j; + + for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++) + { + subscript_p sub = DDR_SUBSCRIPT (ddr, i); + conflict_function *ca = SUB_CONFLICTS_IN_A (sub); + conflict_function *cb = SUB_CONFLICTS_IN_B (sub); + + for (j = 0; j < ca->n; j++) + if (affine_function_zero_p (ca->fns[j])) + { + insert_innermost_unit_dist_vector (ddr); + return; + } + + for (j = 0; j < cb->n; j++) + if (affine_function_zero_p (cb->fns[j])) + { + insert_innermost_unit_dist_vector (ddr); + return; + } + } +} + /* Compute the classic per loop distance vector. DDR is the data dependence relation to build a vector from. Return false when fail to represent the data dependence as a distance vector. */ @@ -3948,6 +4020,9 @@ build_classic_dist_vector (struct data_dependence_relation *ddr) dist_v = lambda_vector_new (DDR_NB_LOOPS (ddr)); save_dist_v (ddr, dist_v); + if (constant_access_functions (ddr)) + add_distance_for_zero_overlaps (ddr); + if (DDR_NB_LOOPS (ddr) > 1) add_other_self_distances (ddr);