--- gcc/tree-chrec.h (/gcc-local/trunk) (revision 30596) +++ gcc/tree-chrec.h (/gcc-local/export-ddg) (revision 30596) @@ -82,7 +82,7 @@ extern bool tree_contains_chrecs (const_ extern bool evolution_function_is_affine_multivariate_p (const_tree, int); extern bool evolution_function_is_univariate_p (const_tree); extern unsigned nb_vars_in_chrec (tree); -extern bool evolution_function_is_invariant_p (tree, int); +extern bool evolution_function_is_invariant_p (const_tree, int); /* Determines whether CHREC is equal to zero. */ --- gcc/tree-chrec.c (/gcc-local/trunk) (revision 30596) +++ gcc/tree-chrec.c (/gcc-local/export-ddg) (revision 30596) @@ -943,7 +943,7 @@ tree_contains_chrecs (const_tree expr, i /* Recursive helper function. */ static bool -evolution_function_is_invariant_rec_p (tree chrec, int loopnum) +evolution_function_is_invariant_rec_p (const_tree chrec, int loopnum) { if (evolution_function_is_constant_p (chrec)) return true; @@ -986,7 +986,7 @@ evolution_function_is_invariant_rec_p (t /* Return true if CHREC is invariant in loop LOOPNUM, false otherwise. */ bool -evolution_function_is_invariant_p (tree chrec, int loopnum) +evolution_function_is_invariant_p (const_tree chrec, int loopnum) { return evolution_function_is_invariant_rec_p (chrec, loopnum); } --- gcc/tree-data-ref.c (/gcc-local/trunk) (revision 30596) +++ gcc/tree-data-ref.c (/gcc-local/export-ddg) (revision 30596) @@ -1355,10 +1355,10 @@ non_affine_dependence_relation (struct d variables, i.e., if the ZIV (Zero Index Variable) test is true. */ static inline bool -ziv_subscript_p (const_tree chrec_a, const_tree chrec_b) +ziv_subscript_p (const_tree chrec_a, const_tree chrec_b, int loopnum) { - return (evolution_function_is_constant_p (chrec_a) - && evolution_function_is_constant_p (chrec_b)); + return (evolution_function_is_invariant_p (chrec_a, loopnum) + && evolution_function_is_invariant_p (chrec_b, loopnum)); } /* Returns true iff CHREC_A and CHREC_B are dependent on an index @@ -1463,7 +1463,10 @@ analyze_ziv_subscript (tree chrec_a, if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "(analyze_ziv_subscript \n"); - + + if (operand_equal_p (chrec_a, chrec_b, 0)) + goto overlaps_each_iteration; + chrec_a = chrec_convert (integer_type_node, chrec_a, NULL_TREE); chrec_b = chrec_convert (integer_type_node, chrec_b, NULL_TREE); difference = chrec_fold_minus (integer_type_node, chrec_a, chrec_b); @@ -1475,6 +1478,7 @@ analyze_ziv_subscript (tree chrec_a, { /* The difference is equal to zero: the accessed index overlaps for each iteration in the loop. */ + overlaps_each_iteration: *overlaps_a = conflict_fn (1, affine_fn_cst (integer_zero_node)); *overlaps_b = conflict_fn (1, affine_fn_cst (integer_zero_node)); *last_conflicts = chrec_dont_know; @@ -2588,13 +2592,22 @@ analyze_overlapping_iterations (tree chr /* If they are the same chrec, and are affine, they overlap on every iteration. */ - else if (eq_evolutions_p (chrec_a, chrec_b) - && evolution_function_is_affine_multivariate_p (chrec_a, lnn)) + else if (eq_evolutions_p (chrec_a, chrec_b)) { - dependence_stats.num_same_subscript_function++; - *overlap_iterations_a = conflict_fn (1, affine_fn_cst (integer_zero_node)); - *overlap_iterations_b = conflict_fn (1, affine_fn_cst (integer_zero_node)); - *last_conflicts = chrec_dont_know; + if (ziv_subscript_p (chrec_a, chrec_b, lnn)) + analyze_ziv_subscript (chrec_a, chrec_b, + overlap_iterations_a, overlap_iterations_b, + last_conflicts); + + else if (evolution_function_is_affine_multivariate_p (chrec_a, lnn)) + { + dependence_stats.num_same_subscript_function++; + *overlap_iterations_a = + conflict_fn (1, affine_fn_cst (integer_zero_node)); + *overlap_iterations_b = + conflict_fn (1, affine_fn_cst (integer_zero_node)); + *last_conflicts = chrec_dont_know; + } } /* If they aren't the same, and aren't affine, we can't do anything @@ -2609,7 +2622,7 @@ analyze_overlapping_iterations (tree chr *overlap_iterations_b = conflict_fn_not_known (); } - else if (ziv_subscript_p (chrec_a, chrec_b)) + else if (ziv_subscript_p (chrec_a, chrec_b, lnn)) analyze_ziv_subscript (chrec_a, chrec_b, overlap_iterations_a, overlap_iterations_b, last_conflicts); @@ -3404,12 +3417,14 @@ omega_extract_distance_vectors (omega_pb static bool omega_setup_subscript (tree access_fun_a, tree access_fun_b, struct data_dependence_relation *ddr, - omega_pb pb, bool *maybe_dependent) + omega_pb pb, bool *maybe_dependent, + struct loop *loop_nest) { int eq; tree fun_a = chrec_convert (integer_type_node, access_fun_a, NULL_TREE); tree fun_b = chrec_convert (integer_type_node, access_fun_b, NULL_TREE); tree difference = chrec_fold_minus (integer_type_node, fun_a, fun_b); + int lnn = loop_nest->num; /* When the fun_a - fun_b is not constant, the dependence is not captured by the classic distance vector representation. */ @@ -3417,7 +3432,7 @@ omega_setup_subscript (tree access_fun_a return false; /* ZIV test. */ - if (ziv_subscript_p (fun_a, fun_b) && !integer_zerop (difference)) + if (ziv_subscript_p (fun_a, fun_b, lnn) && !integer_zerop (difference)) { /* There is no dependence. */ *maybe_dependent = false; @@ -3455,7 +3470,8 @@ omega_setup_subscript (tree access_fun_a static bool init_omega_for_ddr_1 (struct data_reference *dra, struct data_reference *drb, struct data_dependence_relation *ddr, - omega_pb pb, bool *maybe_dependent) + omega_pb pb, bool *maybe_dependent, + struct loop *loop_nest) { unsigned i; int ineq; @@ -3466,7 +3482,7 @@ init_omega_for_ddr_1 (struct data_refere for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++) { if (!omega_setup_subscript (DR_ACCESS_FN (dra, i), DR_ACCESS_FN (drb, i), - ddr, pb, maybe_dependent)) + ddr, pb, maybe_dependent, loop_nest)) return false; else if (*maybe_dependent == false) { @@ -3606,7 +3622,7 @@ init_omega_for_ddr_1 (struct data_refere static bool init_omega_for_ddr (struct data_dependence_relation *ddr, - bool *maybe_dependent) + bool *maybe_dependent, struct loop *loop_nest) { omega_pb pb; bool res = false; @@ -3628,7 +3644,7 @@ init_omega_for_ddr (struct data_dependen /* Save the dependences carried by outer loops. */ pb = omega_alloc_problem (2 * DDR_NB_LOOPS (ddr), DDR_NB_LOOPS (ddr)); res = init_omega_for_ddr_1 (DDR_A (ddr), DDR_B (ddr), ddr, pb, - maybe_dependent); + maybe_dependent, loop_nest); omega_free_problem (pb); return res; } @@ -3640,7 +3656,7 @@ init_omega_for_ddr (struct data_dependen number of variables for the constraint system is 2*NB_LOOPS. */ pb = omega_alloc_problem (2 * DDR_NB_LOOPS (ddr), DDR_NB_LOOPS (ddr)); res = init_omega_for_ddr_1 (DDR_A (ddr), DDR_B (ddr), ddr, pb, - maybe_dependent); + maybe_dependent, loop_nest); omega_free_problem (pb); /* Stop computation if not decidable, or no dependence. */ @@ -3649,7 +3665,7 @@ init_omega_for_ddr (struct data_dependen pb = omega_alloc_problem (2 * DDR_NB_LOOPS (ddr), DDR_NB_LOOPS (ddr)); res = init_omega_for_ddr_1 (DDR_B (ddr), DDR_A (ddr), ddr, pb, - maybe_dependent); + maybe_dependent, loop_nest); omega_free_problem (pb); return res; @@ -3808,7 +3824,7 @@ compute_affine_dependence (struct data_d DDR_DIR_VECTS (ddr) = NULL; /* Compute the same information using Omega. */ - if (!init_omega_for_ddr (ddr, &maybe_dependent)) + if (!init_omega_for_ddr (ddr, &maybe_dependent, loop_nest)) goto csys_dont_know; if (dump_file && (dump_flags & TDF_DETAILS))