[autovect] [patch] vectorize in cases when number of iterations may be zero
Victor Kaplansky
VICTORK@il.ibm.com
Mon Jun 19 11:13:00 GMT 2006
Sebastian,
your patch worked for my original example, but gcc still fails to
calculate niter when counters are signed integers:
1 int
2 foo (short *in, short *out)
3 {
4 int i;
5 int N;
6 int M;
7 int acc;
8
9 for (N = 0; N < 16; N++)
10 {
11 M = 500 - N;
12 acc = 0;
13
14 for (i = 0; i < M; i++)
15 {
16 acc += in[i];
17 }
18
19 out[N] = (short) acc;
20 }
21
22 return acc;
23 }
Can your patch to be modified to work with autovect branch as well?
-- Victor
Sebastian Pop <sebastian.pop@cri.ensmp.fr> wrote on 19.06.2006 11:42:33:
> Sebastian Pop wrote:
> > I have started on such a patch but didn't finished it last weekend.
> > I'll try to get it done for Monday.
> >
>
> Here is a possible patch for trunk. While bootstrapping, there were
> no "proved_one_more" outputs, but using this patch, the compiler
> correctly proves the may_be_zero condition is false for your example.
>
> Sebastian
>
> * tree-ssa-loop-niter.c (expand_simple_operations): Symetrically
> also check is_gimple_min_invariant for operand 0.
> (simplify_using_initial_conditions): Call may_contain_eq_values.
> * tree-chrec.c (may_contain_eq_values_aff_cst,
> may_contain_eq_values): New.
> * tree-chrec.h (may_contain_eq_values): Declared.
>
> Index: tree-ssa-loop-niter.c
> ===================================================================
> --- tree-ssa-loop-niter.c (revision 114678)
> +++ tree-ssa-loop-niter.c (working copy)
> @@ -758,7 +758,8 @@ expand_simple_operations (tree expr)
> /* And increments and decrements by a constant are simple. */
> && !((TREE_CODE (e) == PLUS_EXPR
> || TREE_CODE (e) == MINUS_EXPR)
> - && is_gimple_min_invariant (TREE_OPERAND (e, 1))))
> + && (is_gimple_min_invariant (TREE_OPERAND (e, 0))
> + || is_gimple_min_invariant (TREE_OPERAND (e, 1)))))
> return expr;
>
> return expand_simple_operations (e);
> @@ -890,7 +891,7 @@ tree_simplify_using_condition (tree cond
> /* Tries to simplify EXPR using the conditions on entry to LOOP.
> Record the conditions used for simplification to CONDS_USED.
> Returns the simplified expression (or EXPR unchanged, if no
> - simplification was possible).*/
> + simplification was possible). */
>
> static tree
> simplify_using_initial_conditions (struct loop *loop, tree expr,
> @@ -928,6 +929,26 @@ simplify_using_initial_conditions (struc
> expr = exp;
> }
>
> + /* The test above can fail as the condition before the loop can have
> + been removed by VRP. It is thus possible to prove more precise
> + informations by using the SCEV algorithm. */
> + if (TREE_CODE (expr) == EQ_EXPR)
> + {
> + tree op0 = analyze_scalar_evolution (loop, TREE_OPERAND (expr,
0));
> + tree op1 = analyze_scalar_evolution (loop, TREE_OPERAND (expr,
1));
> +
> + op0 = instantiate_parameters (loop, op0);
> + op1 = instantiate_parameters (loop, op1);
> +
> + if (may_contain_eq_values (op0, op1))
> + return expr;
> + else
> + {
> + fprintf (stderr, "\n proved_one_more \n");
> + return boolean_false_node;
> + }
> + }
> +
> return expr;
> }
>
> Index: tree-chrec.c
> ===================================================================
> --- tree-chrec.c (revision 114678)
> +++ tree-chrec.c (working copy)
> @@ -1386,3 +1386,80 @@ scev_direction (tree chrec)
> else
> return EV_DIR_GROWS;
> }
> +
> +/* Helper function. CHREC0 is supposed to be an affine function,
> + CHREC1 a constant. */
> +
> +static bool
> +may_contain_eq_values_aff_cst (tree chrec0, tree chrec1)
> +{
> + struct loop *loop = current_loops->parray[CHREC_VARIABLE (chrec0)];
> + tree niter = number_of_iterations_in_loop (loop);
> +
> + gcc_assert (evolution_function_is_affine_p (chrec0));
> + gcc_assert (evolution_function_is_constant_p (chrec1));
> +
> + if (niter && TREE_CODE (niter) == INTEGER_CST)
> + {
> + tree lb, ub;
> +
> + switch (scev_direction (chrec0))
> + {
> + case EV_DIR_GROWS:
> + lb = initial_condition (chrec0);
> + ub = chrec_apply (CHREC_VARIABLE (chrec0), chrec0, niter);
> + break;
> +
> + case EV_DIR_DECREASES:
> + ub = initial_condition (chrec0);
> + lb = chrec_apply (CHREC_VARIABLE (chrec0), chrec0, niter);
> + break;
> +
> + default:
> + return true;
> + }
> +
> + if (zero_p (fold_build2 (GE_EXPR, boolean_type_node, lb, chrec1))
> + && zero_p (fold_build2 (GE_EXPR, boolean_type_node, chrec1, ub)))
> + return true;
> + else
> + return false;
> + }
> +
> + /* Conservative answer. */
> + return true;
> +}
> +
> +/* Returns true when at least one of the values of CHREC0 and CHREC1
> + is equal, or when it is impossible to determine this property. */
> +
> +bool
> +may_contain_eq_values (tree chrec0, tree chrec1)
> +{
> + bool cst0, cst1;
> +
> + if (automatically_generated_chrec_p (chrec0)
> + || automatically_generated_chrec_p (chrec1))
> + return true;
> +
> + cst0 = evolution_function_is_constant_p (chrec0);
> + cst1 = evolution_function_is_constant_p (chrec1);
> +
> + if (cst0 && cst1)
> + {
> + if (zero_p (fold_build2 (EQ_EXPR, boolean_type_node, chrec0,
chrec1)))
> + return true;
> + else
> + return false;
> + }
> +
> + if (cst1 && evolution_function_is_affine_p (chrec0))
> + return may_contain_eq_values_aff_cst (chrec0, chrec1);
> +
> + if (cst0 && evolution_function_is_affine_p (chrec1))
> + return may_contain_eq_values_aff_cst (chrec1, chrec0);
> +
> + /* Conservative answer. */
> + return true;
> +}
> +
> Index: tree-chrec.h
> ===================================================================
> --- tree-chrec.h (revision 114678)
> +++ tree-chrec.h (working copy)
> @@ -91,6 +91,7 @@ extern bool tree_contains_chrecs (tree,
> extern bool evolution_function_is_affine_multivariate_p (tree);
> extern bool evolution_function_is_univariate_p (tree);
> extern unsigned nb_vars_in_chrec (tree);
> +extern bool may_contain_eq_values (tree, tree);
>
>
>
More information about the Gcc-patches
mailing list