Commit da9a21f4 by Sebastian Pop Committed by Sebastian Pop

re PR tree-optimization/32075 (can't determine dependence between p->a[x+i] and…

re PR tree-optimization/32075 (can't determine dependence between p->a[x+i] and p->a[x+i+1] where x is invariant but defined in the function)

	PR tree-optimization/32075
	* tree-data-ref.c (subscript_dependence_tester_1, 
	analyze_miv_subscript, analyze_overlapping_iterations,
	add_distance_for_zero_overlaps, build_classic_dist_vector,
	subscript_dependence_tester_1, analyze_overlapping_iterations,
	subscript_dependence_tester, access_functions_are_affine_or_constant_p,
	compute_affine_dependence, compute_all_dependences): Pass loop_nest 
	to evolution_function_is_affine_multivariate_p.

From-SVN: r125900
parent 14d4217b
...@@ -128,7 +128,7 @@ ...@@ -128,7 +128,7 @@
offsets->locals_base to avoid negative stack size. offsets->locals_base to avoid negative stack size.
(thumb1_expand_prologue): Assert on negative stack size. (thumb1_expand_prologue): Assert on negative stack size.
2007-04-11 Sebastian Pop <sebpop@gmail.com> 2007-04-19 Sebastian Pop <sebpop@gmail.com>
PR tree-optimization/32367 PR tree-optimization/32367
* tree-chrec.h (build_polynomial_chrec): Verify that the left hand side * tree-chrec.h (build_polynomial_chrec): Verify that the left hand side
......
...@@ -124,7 +124,8 @@ static struct datadep_stats ...@@ -124,7 +124,8 @@ static struct datadep_stats
static bool subscript_dependence_tester_1 (struct data_dependence_relation *, static bool subscript_dependence_tester_1 (struct data_dependence_relation *,
struct data_reference *, struct data_reference *,
struct data_reference *); struct data_reference *,
struct loop *);
/* Returns true iff A divides B. */ /* Returns true iff A divides B. */
static inline bool static inline bool
...@@ -2417,10 +2418,11 @@ gcd_of_steps_may_divide_p (tree chrec, tree cst) ...@@ -2417,10 +2418,11 @@ gcd_of_steps_may_divide_p (tree chrec, tree cst)
return val % cd == 0; return val % cd == 0;
} }
/* Analyze a MIV (Multiple Index Variable) subscript. *OVERLAPS_A and /* Analyze a MIV (Multiple Index Variable) subscript with respect to
*OVERLAPS_B are initialized to the functions that describe the LOOP_NEST. *OVERLAPS_A and *OVERLAPS_B are initialized to the
relation between the elements accessed twice by CHREC_A and functions that describe the relation between the elements accessed
CHREC_B. For k >= 0, the following property is verified: twice by CHREC_A and CHREC_B. For k >= 0, the following property
is verified:
CHREC_A (*OVERLAPS_A (k)) = CHREC_B (*OVERLAPS_B (k)). */ CHREC_A (*OVERLAPS_A (k)) = CHREC_B (*OVERLAPS_B (k)). */
...@@ -2429,7 +2431,8 @@ analyze_miv_subscript (tree chrec_a, ...@@ -2429,7 +2431,8 @@ analyze_miv_subscript (tree chrec_a,
tree chrec_b, tree chrec_b,
conflict_function **overlaps_a, conflict_function **overlaps_a,
conflict_function **overlaps_b, conflict_function **overlaps_b,
tree *last_conflicts) tree *last_conflicts,
struct loop *loop_nest)
{ {
/* FIXME: This is a MIV subscript, not yet handled. /* FIXME: This is a MIV subscript, not yet handled.
Example: (A[{1, +, 1}_1] vs. A[{1, +, 1}_2]) that comes from Example: (A[{1, +, 1}_1] vs. A[{1, +, 1}_2]) that comes from
...@@ -2461,7 +2464,8 @@ analyze_miv_subscript (tree chrec_a, ...@@ -2461,7 +2464,8 @@ analyze_miv_subscript (tree chrec_a,
else if (evolution_function_is_constant_p (difference) else if (evolution_function_is_constant_p (difference)
/* For the moment, the following is verified: /* For the moment, the following is verified:
evolution_function_is_affine_multivariate_p (chrec_a, 0) */ evolution_function_is_affine_multivariate_p (chrec_a,
loop_nest->num) */
&& !gcd_of_steps_may_divide_p (chrec_a, difference)) && !gcd_of_steps_may_divide_p (chrec_a, difference))
{ {
/* testsuite/.../ssa-chrec-33.c /* testsuite/.../ssa-chrec-33.c
...@@ -2475,9 +2479,9 @@ analyze_miv_subscript (tree chrec_a, ...@@ -2475,9 +2479,9 @@ analyze_miv_subscript (tree chrec_a,
dependence_stats.num_miv_independent++; dependence_stats.num_miv_independent++;
} }
else if (evolution_function_is_affine_multivariate_p (chrec_a, 0) else if (evolution_function_is_affine_multivariate_p (chrec_a, loop_nest->num)
&& !chrec_contains_symbols (chrec_a) && !chrec_contains_symbols (chrec_a)
&& evolution_function_is_affine_multivariate_p (chrec_b, 0) && evolution_function_is_affine_multivariate_p (chrec_b, loop_nest->num)
&& !chrec_contains_symbols (chrec_b)) && !chrec_contains_symbols (chrec_b))
{ {
/* testsuite/.../ssa-chrec-35.c /* testsuite/.../ssa-chrec-35.c
...@@ -2523,10 +2527,10 @@ analyze_miv_subscript (tree chrec_a, ...@@ -2523,10 +2527,10 @@ analyze_miv_subscript (tree chrec_a,
fprintf (dump_file, ")\n"); fprintf (dump_file, ")\n");
} }
/* Determines the iterations for which CHREC_A is equal to CHREC_B. /* Determines the iterations for which CHREC_A is equal to CHREC_B in
OVERLAP_ITERATIONS_A and OVERLAP_ITERATIONS_B are initialized with with respect to LOOP_NEST. OVERLAP_ITERATIONS_A and
two functions that describe the iterations that contain conflicting OVERLAP_ITERATIONS_B are initialized with two functions that
elements. describe the iterations that contain conflicting elements.
Remark: For an integer k >= 0, the following equality is true: Remark: For an integer k >= 0, the following equality is true:
...@@ -2538,8 +2542,10 @@ analyze_overlapping_iterations (tree chrec_a, ...@@ -2538,8 +2542,10 @@ analyze_overlapping_iterations (tree chrec_a,
tree chrec_b, tree chrec_b,
conflict_function **overlap_iterations_a, conflict_function **overlap_iterations_a,
conflict_function **overlap_iterations_b, conflict_function **overlap_iterations_b,
tree *last_conflicts) tree *last_conflicts, struct loop *loop_nest)
{ {
unsigned int lnn = loop_nest->num;
dependence_stats.num_subscript_tests++; dependence_stats.num_subscript_tests++;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
...@@ -2566,7 +2572,7 @@ analyze_overlapping_iterations (tree chrec_a, ...@@ -2566,7 +2572,7 @@ analyze_overlapping_iterations (tree chrec_a,
/* If they are the same chrec, and are affine, they overlap /* If they are the same chrec, and are affine, they overlap
on every iteration. */ on every iteration. */
else if (eq_evolutions_p (chrec_a, chrec_b) else if (eq_evolutions_p (chrec_a, chrec_b)
&& evolution_function_is_affine_multivariate_p (chrec_a, 0)) && evolution_function_is_affine_multivariate_p (chrec_a, lnn))
{ {
dependence_stats.num_same_subscript_function++; dependence_stats.num_same_subscript_function++;
*overlap_iterations_a = conflict_fn (1, affine_fn_cst (integer_zero_node)); *overlap_iterations_a = conflict_fn (1, affine_fn_cst (integer_zero_node));
...@@ -2578,8 +2584,8 @@ analyze_overlapping_iterations (tree chrec_a, ...@@ -2578,8 +2584,8 @@ analyze_overlapping_iterations (tree chrec_a,
yet. */ yet. */
else if ((chrec_contains_symbols (chrec_a) else if ((chrec_contains_symbols (chrec_a)
|| chrec_contains_symbols (chrec_b)) || chrec_contains_symbols (chrec_b))
&& (!evolution_function_is_affine_multivariate_p (chrec_a, 0) && (!evolution_function_is_affine_multivariate_p (chrec_a, lnn)
|| !evolution_function_is_affine_multivariate_p (chrec_b, 0))) || !evolution_function_is_affine_multivariate_p (chrec_b, lnn)))
{ {
dependence_stats.num_subscript_undetermined++; dependence_stats.num_subscript_undetermined++;
*overlap_iterations_a = conflict_fn_not_known (); *overlap_iterations_a = conflict_fn_not_known ();
...@@ -2599,7 +2605,7 @@ analyze_overlapping_iterations (tree chrec_a, ...@@ -2599,7 +2605,7 @@ analyze_overlapping_iterations (tree chrec_a,
else else
analyze_miv_subscript (chrec_a, chrec_b, analyze_miv_subscript (chrec_a, chrec_b,
overlap_iterations_a, overlap_iterations_b, overlap_iterations_a, overlap_iterations_b,
last_conflicts); last_conflicts, loop_nest);
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
...@@ -2926,7 +2932,8 @@ add_distance_for_zero_overlaps (struct data_dependence_relation *ddr) ...@@ -2926,7 +2932,8 @@ add_distance_for_zero_overlaps (struct data_dependence_relation *ddr)
to represent the data dependence as a distance vector. */ to represent the data dependence as a distance vector. */
static bool static bool
build_classic_dist_vector (struct data_dependence_relation *ddr) build_classic_dist_vector (struct data_dependence_relation *ddr,
struct loop *loop_nest)
{ {
bool init_b = false; bool init_b = false;
int index_carry = DDR_NB_LOOPS (ddr); int index_carry = DDR_NB_LOOPS (ddr);
...@@ -2985,7 +2992,8 @@ build_classic_dist_vector (struct data_dependence_relation *ddr) ...@@ -2985,7 +2992,8 @@ build_classic_dist_vector (struct data_dependence_relation *ddr)
if (!lambda_vector_lexico_pos (dist_v, DDR_NB_LOOPS (ddr))) if (!lambda_vector_lexico_pos (dist_v, DDR_NB_LOOPS (ddr)))
{ {
lambda_vector save_v = lambda_vector_new (DDR_NB_LOOPS (ddr)); lambda_vector save_v = lambda_vector_new (DDR_NB_LOOPS (ddr));
subscript_dependence_tester_1 (ddr, DDR_B (ddr), DDR_A (ddr)); subscript_dependence_tester_1 (ddr, DDR_B (ddr), DDR_A (ddr),
loop_nest);
compute_subscript_distance (ddr); compute_subscript_distance (ddr);
build_classic_dist_vector_1 (ddr, DDR_B (ddr), DDR_A (ddr), build_classic_dist_vector_1 (ddr, DDR_B (ddr), DDR_A (ddr),
save_v, &init_b, &index_carry); save_v, &init_b, &index_carry);
...@@ -3023,7 +3031,8 @@ build_classic_dist_vector (struct data_dependence_relation *ddr) ...@@ -3023,7 +3031,8 @@ build_classic_dist_vector (struct data_dependence_relation *ddr)
{ {
lambda_vector opposite_v = lambda_vector_new (DDR_NB_LOOPS (ddr)); lambda_vector opposite_v = lambda_vector_new (DDR_NB_LOOPS (ddr));
subscript_dependence_tester_1 (ddr, DDR_B (ddr), DDR_A (ddr)); subscript_dependence_tester_1 (ddr, DDR_B (ddr), DDR_A (ddr),
loop_nest);
compute_subscript_distance (ddr); compute_subscript_distance (ddr);
build_classic_dist_vector_1 (ddr, DDR_B (ddr), DDR_A (ddr), build_classic_dist_vector_1 (ddr, DDR_B (ddr), DDR_A (ddr),
opposite_v, &init_b, &index_carry); opposite_v, &init_b, &index_carry);
...@@ -3106,7 +3115,8 @@ build_classic_dir_vector (struct data_dependence_relation *ddr) ...@@ -3106,7 +3115,8 @@ build_classic_dir_vector (struct data_dependence_relation *ddr)
static bool static bool
subscript_dependence_tester_1 (struct data_dependence_relation *ddr, subscript_dependence_tester_1 (struct data_dependence_relation *ddr,
struct data_reference *dra, struct data_reference *dra,
struct data_reference *drb) struct data_reference *drb,
struct loop *loop_nest)
{ {
unsigned int i; unsigned int i;
tree last_conflicts; tree last_conflicts;
...@@ -3120,7 +3130,7 @@ subscript_dependence_tester_1 (struct data_dependence_relation *ddr, ...@@ -3120,7 +3130,7 @@ subscript_dependence_tester_1 (struct data_dependence_relation *ddr,
analyze_overlapping_iterations (DR_ACCESS_FN (dra, i), analyze_overlapping_iterations (DR_ACCESS_FN (dra, i),
DR_ACCESS_FN (drb, i), DR_ACCESS_FN (drb, i),
&overlaps_a, &overlaps_b, &overlaps_a, &overlaps_b,
&last_conflicts); &last_conflicts, loop_nest);
if (CF_NOT_KNOWN_P (overlaps_a) if (CF_NOT_KNOWN_P (overlaps_a)
|| CF_NOT_KNOWN_P (overlaps_b)) || CF_NOT_KNOWN_P (overlaps_b))
...@@ -3153,20 +3163,21 @@ subscript_dependence_tester_1 (struct data_dependence_relation *ddr, ...@@ -3153,20 +3163,21 @@ subscript_dependence_tester_1 (struct data_dependence_relation *ddr,
return true; return true;
} }
/* Computes the conflicting iterations, and initialize DDR. */ /* Computes the conflicting iterations in LOOP_NEST, and initialize DDR. */
static void static void
subscript_dependence_tester (struct data_dependence_relation *ddr) subscript_dependence_tester (struct data_dependence_relation *ddr,
struct loop *loop_nest)
{ {
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "(subscript_dependence_tester \n"); fprintf (dump_file, "(subscript_dependence_tester \n");
if (subscript_dependence_tester_1 (ddr, DDR_A (ddr), DDR_B (ddr))) if (subscript_dependence_tester_1 (ddr, DDR_A (ddr), DDR_B (ddr), loop_nest))
dependence_stats.num_dependence_dependent++; dependence_stats.num_dependence_dependent++;
compute_subscript_distance (ddr); compute_subscript_distance (ddr);
if (build_classic_dist_vector (ddr)) if (build_classic_dist_vector (ddr, loop_nest))
build_classic_dir_vector (ddr); build_classic_dir_vector (ddr);
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
...@@ -3174,18 +3185,19 @@ subscript_dependence_tester (struct data_dependence_relation *ddr) ...@@ -3174,18 +3185,19 @@ subscript_dependence_tester (struct data_dependence_relation *ddr)
} }
/* Returns true when all the access functions of A are affine or /* Returns true when all the access functions of A are affine or
constant. */ constant with respect to LOOP_NEST. */
static bool static bool
access_functions_are_affine_or_constant_p (struct data_reference *a) access_functions_are_affine_or_constant_p (struct data_reference *a,
struct loop *loop_nest)
{ {
unsigned int i; unsigned int i;
VEC(tree,heap) *fns = DR_ACCESS_FNS (a); VEC(tree,heap) *fns = DR_ACCESS_FNS (a);
tree t; tree t;
for (i = 0; VEC_iterate (tree, fns, i, t); i++) for (i = 0; VEC_iterate (tree, fns, i, t); i++)
if (!evolution_function_is_constant_p (t) if (!evolution_function_is_invariant_p (t, loop_nest->num)
&& !evolution_function_is_affine_multivariate_p (t, 0)) && !evolution_function_is_affine_multivariate_p (t, loop_nest->num))
return false; return false;
return true; return true;
...@@ -3715,17 +3727,18 @@ ddr_consistent_p (FILE *file, ...@@ -3715,17 +3727,18 @@ ddr_consistent_p (FILE *file,
return true; return true;
} }
/* This computes the affine dependence relation between A and B. /* This computes the affine dependence relation between A and B with
CHREC_KNOWN is used for representing the independence between two respect to LOOP_NEST. CHREC_KNOWN is used for representing the
accesses, while CHREC_DONT_KNOW is used for representing the unknown independence between two accesses, while CHREC_DONT_KNOW is used
relation. for representing the unknown relation.
Note that it is possible to stop the computation of the dependence Note that it is possible to stop the computation of the dependence
relation the first time we detect a CHREC_KNOWN element for a given relation the first time we detect a CHREC_KNOWN element for a given
subscript. */ subscript. */
static void static void
compute_affine_dependence (struct data_dependence_relation *ddr) compute_affine_dependence (struct data_dependence_relation *ddr,
struct loop *loop_nest)
{ {
struct data_reference *dra = DDR_A (ddr); struct data_reference *dra = DDR_A (ddr);
struct data_reference *drb = DDR_B (ddr); struct data_reference *drb = DDR_B (ddr);
...@@ -3745,13 +3758,13 @@ compute_affine_dependence (struct data_dependence_relation *ddr) ...@@ -3745,13 +3758,13 @@ compute_affine_dependence (struct data_dependence_relation *ddr)
{ {
dependence_stats.num_dependence_tests++; dependence_stats.num_dependence_tests++;
if (access_functions_are_affine_or_constant_p (dra) if (access_functions_are_affine_or_constant_p (dra, loop_nest)
&& access_functions_are_affine_or_constant_p (drb)) && access_functions_are_affine_or_constant_p (drb, loop_nest))
{ {
if (flag_check_data_deps) if (flag_check_data_deps)
{ {
/* Compute the dependences using the first algorithm. */ /* Compute the dependences using the first algorithm. */
subscript_dependence_tester (ddr); subscript_dependence_tester (ddr, loop_nest);
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
...@@ -3789,7 +3802,7 @@ compute_affine_dependence (struct data_dependence_relation *ddr) ...@@ -3789,7 +3802,7 @@ compute_affine_dependence (struct data_dependence_relation *ddr)
} }
} }
else else
subscript_dependence_tester (ddr); subscript_dependence_tester (ddr, loop_nest);
} }
/* As a last case, if the dependence cannot be determined, or if /* As a last case, if the dependence cannot be determined, or if
...@@ -3865,7 +3878,7 @@ compute_all_dependences (VEC (data_reference_p, heap) *datarefs, ...@@ -3865,7 +3878,7 @@ compute_all_dependences (VEC (data_reference_p, heap) *datarefs,
{ {
ddr = initialize_data_dependence_relation (a, b, loop_nest); ddr = initialize_data_dependence_relation (a, b, loop_nest);
VEC_safe_push (ddr_p, heap, *dependence_relations, ddr); VEC_safe_push (ddr_p, heap, *dependence_relations, ddr);
compute_affine_dependence (ddr); compute_affine_dependence (ddr, VEC_index (loop_p, loop_nest, 0));
} }
if (compute_self_and_rr) if (compute_self_and_rr)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment