Commit 2282a0e6 by Zdenek Dvorak Committed by Zdenek Dvorak

re PR tree-optimization/18463 (suboptimal use of fancy x86 addressing modes)

	PR tree-optimization/18463
	* tree-chrec.c (chrec_convert): Return fold_converted chrec if
	converting it directly is not possible.
	(chrec_convert_aggressive): New function.
	* tree-chrec.h (chrec_convert_aggressive): Declare.
	* tree-scalar-evolution.c (instantiate_parameters_1, resolve_mixers):
	Fold chrec conversions aggressively if asked to.
	(instantiate_parameters): Modified because of changes in
	instantiate_parameters_1.

From-SVN: r104443
parent 3a3c28db
2005-09-20 Zdenek Dvorak <dvorakz@suse.cz>
PR tree-optimization/18463
* tree-chrec.c (chrec_convert): Return fold_converted chrec if
converting it directly is not possible.
(chrec_convert_aggressive): New function.
* tree-chrec.h (chrec_convert_aggressive): Declare.
* tree-scalar-evolution.c (instantiate_parameters_1, resolve_mixers):
Fold chrec conversions aggressively if asked to.
(instantiate_parameters): Modified because of changes in
instantiate_parameters_1.
2005-09-19 Richard Henderson <rth@redhat.com> 2005-09-19 Richard Henderson <rth@redhat.com>
* config/i386/sse.md (reduc_splus_v4sf): Rename from reduc_plus_v4sf. * config/i386/sse.md (reduc_splus_v4sf): Rename from reduc_plus_v4sf.
......
...@@ -1164,9 +1164,7 @@ chrec_convert (tree type, tree chrec, tree at_stmt) ...@@ -1164,9 +1164,7 @@ chrec_convert (tree type, tree chrec, tree at_stmt)
fprintf (dump_file, "\n)\n"); fprintf (dump_file, "\n)\n");
} }
/* Directly convert to "don't know": no worth dealing with return fold_convert (type, chrec);
difficult cases. */
return chrec_dont_know;
} }
return build_polynomial_chrec (CHREC_VARIABLE (chrec), return build_polynomial_chrec (CHREC_VARIABLE (chrec),
...@@ -1201,6 +1199,35 @@ chrec_convert (tree type, tree chrec, tree at_stmt) ...@@ -1201,6 +1199,35 @@ chrec_convert (tree type, tree chrec, tree at_stmt)
return res; return res;
} }
/* Convert CHREC to TYPE, without regard to signed overflows. Returns the new
chrec if something else than what chrec_convert would do happens, NULL_TREE
otherwise. */
tree
chrec_convert_aggressive (tree type, tree chrec)
{
tree inner_type, left, right, lc, rc;
if (automatically_generated_chrec_p (chrec)
|| TREE_CODE (chrec) != POLYNOMIAL_CHREC)
return NULL_TREE;
inner_type = TREE_TYPE (chrec);
if (TYPE_PRECISION (type) > TYPE_PRECISION (inner_type))
return NULL_TREE;
left = CHREC_LEFT (chrec);
right = CHREC_RIGHT (chrec);
lc = chrec_convert_aggressive (type, left);
if (!lc)
lc = chrec_convert (type, left, NULL_TREE);
rc = chrec_convert_aggressive (type, right);
if (!rc)
rc = chrec_convert (type, right, NULL_TREE);
return build_polynomial_chrec (CHREC_VARIABLE (chrec), lc, rc);
}
/* Returns the type of the chrec. */ /* Returns the type of the chrec. */
tree tree
......
...@@ -68,6 +68,7 @@ extern tree chrec_fold_plus (tree, tree, tree); ...@@ -68,6 +68,7 @@ extern tree chrec_fold_plus (tree, tree, tree);
extern tree chrec_fold_minus (tree, tree, tree); extern tree chrec_fold_minus (tree, tree, tree);
extern tree chrec_fold_multiply (tree, tree, tree); extern tree chrec_fold_multiply (tree, tree, tree);
extern tree chrec_convert (tree, tree, tree); extern tree chrec_convert (tree, tree, tree);
extern tree chrec_convert_aggressive (tree, tree);
extern tree chrec_type (tree); extern tree chrec_type (tree);
/* Operations. */ /* Operations. */
......
...@@ -1955,20 +1955,27 @@ loop_closed_phi_def (tree var) ...@@ -1955,20 +1955,27 @@ loop_closed_phi_def (tree var)
} }
/* Analyze all the parameters of the chrec that were left under a symbolic form, /* Analyze all the parameters of the chrec that were left under a symbolic form,
with respect to LOOP. CHREC is the chrec to instantiate. If with respect to LOOP. CHREC is the chrec to instantiate. CACHE is the cache
ALLOW_SUPERLOOP_CHRECS is true, replacing loop invariants with of already instantiated values. FLAGS modify the way chrecs are
outer loop chrecs is done. CACHE is the cache of already instantiated instantiated. */
values. */
/* Values for FLAGS. */
enum
{
INSERT_SUPERLOOP_CHRECS = 1, /* Loop invariants are replaced with chrecs
in outer loops. */
FOLD_CONVERSIONS = 2 /* The conversions that may wrap in
signed/pointer type are folded, as long as the
value of the chrec is preserved. */
};
static tree static tree
instantiate_parameters_1 (struct loop *loop, tree chrec, instantiate_parameters_1 (struct loop *loop, tree chrec, int flags, htab_t cache)
bool allow_superloop_chrecs,
htab_t cache)
{ {
tree res, op0, op1, op2; tree res, op0, op1, op2;
basic_block def_bb; basic_block def_bb;
struct loop *def_loop; struct loop *def_loop;
if (automatically_generated_chrec_p (chrec) if (automatically_generated_chrec_p (chrec)
|| is_gimple_min_invariant (chrec)) || is_gimple_min_invariant (chrec))
return chrec; return chrec;
...@@ -1981,7 +1988,7 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, ...@@ -1981,7 +1988,7 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
/* A parameter (or loop invariant and we do not want to include /* A parameter (or loop invariant and we do not want to include
evolutions in outer loops), nothing to do. */ evolutions in outer loops), nothing to do. */
if (!def_bb if (!def_bb
|| (!allow_superloop_chrecs || (!(flags & INSERT_SUPERLOOP_CHRECS)
&& !flow_bb_inside_loop_p (loop, def_bb))) && !flow_bb_inside_loop_p (loop, def_bb)))
return chrec; return chrec;
...@@ -2036,8 +2043,7 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, ...@@ -2036,8 +2043,7 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
} }
else if (res != chrec_dont_know) else if (res != chrec_dont_know)
res = instantiate_parameters_1 (loop, res, allow_superloop_chrecs, res = instantiate_parameters_1 (loop, res, flags, cache);
cache);
bitmap_clear_bit (already_instantiated, SSA_NAME_VERSION (chrec)); bitmap_clear_bit (already_instantiated, SSA_NAME_VERSION (chrec));
...@@ -2047,12 +2053,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, ...@@ -2047,12 +2053,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
case POLYNOMIAL_CHREC: case POLYNOMIAL_CHREC:
op0 = instantiate_parameters_1 (loop, CHREC_LEFT (chrec), op0 = instantiate_parameters_1 (loop, CHREC_LEFT (chrec),
allow_superloop_chrecs, cache); flags, cache);
if (op0 == chrec_dont_know) if (op0 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
op1 = instantiate_parameters_1 (loop, CHREC_RIGHT (chrec), op1 = instantiate_parameters_1 (loop, CHREC_RIGHT (chrec),
allow_superloop_chrecs, cache); flags, cache);
if (op1 == chrec_dont_know) if (op1 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
...@@ -2063,12 +2069,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, ...@@ -2063,12 +2069,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
case PLUS_EXPR: case PLUS_EXPR:
op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
allow_superloop_chrecs, cache); flags, cache);
if (op0 == chrec_dont_know) if (op0 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1), op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
allow_superloop_chrecs, cache); flags, cache);
if (op1 == chrec_dont_know) if (op1 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
...@@ -2079,12 +2085,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, ...@@ -2079,12 +2085,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
case MINUS_EXPR: case MINUS_EXPR:
op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
allow_superloop_chrecs, cache); flags, cache);
if (op0 == chrec_dont_know) if (op0 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1), op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
allow_superloop_chrecs, cache); flags, cache);
if (op1 == chrec_dont_know) if (op1 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
...@@ -2095,12 +2101,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, ...@@ -2095,12 +2101,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
case MULT_EXPR: case MULT_EXPR:
op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
allow_superloop_chrecs, cache); flags, cache);
if (op0 == chrec_dont_know) if (op0 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1), op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
allow_superloop_chrecs, cache); flags, cache);
if (op1 == chrec_dont_know) if (op1 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
...@@ -2113,10 +2119,17 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, ...@@ -2113,10 +2119,17 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
case CONVERT_EXPR: case CONVERT_EXPR:
case NON_LVALUE_EXPR: case NON_LVALUE_EXPR:
op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
allow_superloop_chrecs, cache); flags, cache);
if (op0 == chrec_dont_know) if (op0 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
if (flags & FOLD_CONVERSIONS)
{
tree tmp = chrec_convert_aggressive (TREE_TYPE (chrec), op0);
if (tmp)
return tmp;
}
if (op0 == TREE_OPERAND (chrec, 0)) if (op0 == TREE_OPERAND (chrec, 0))
return chrec; return chrec;
...@@ -2136,17 +2149,17 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, ...@@ -2136,17 +2149,17 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
{ {
case 3: case 3:
op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
allow_superloop_chrecs, cache); flags, cache);
if (op0 == chrec_dont_know) if (op0 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1), op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
allow_superloop_chrecs, cache); flags, cache);
if (op1 == chrec_dont_know) if (op1 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
op2 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 2), op2 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 2),
allow_superloop_chrecs, cache); flags, cache);
if (op2 == chrec_dont_know) if (op2 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
...@@ -2160,12 +2173,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, ...@@ -2160,12 +2173,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
case 2: case 2:
op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
allow_superloop_chrecs, cache); flags, cache);
if (op0 == chrec_dont_know) if (op0 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1), op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
allow_superloop_chrecs, cache); flags, cache);
if (op1 == chrec_dont_know) if (op1 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
...@@ -2176,7 +2189,7 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, ...@@ -2176,7 +2189,7 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
case 1: case 1:
op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
allow_superloop_chrecs, cache); flags, cache);
if (op0 == chrec_dont_know) if (op0 == chrec_dont_know)
return chrec_dont_know; return chrec_dont_know;
if (op0 == TREE_OPERAND (chrec, 0)) if (op0 == TREE_OPERAND (chrec, 0))
...@@ -2214,7 +2227,7 @@ instantiate_parameters (struct loop *loop, ...@@ -2214,7 +2227,7 @@ instantiate_parameters (struct loop *loop,
fprintf (dump_file, ")\n"); fprintf (dump_file, ")\n");
} }
res = instantiate_parameters_1 (loop, chrec, true, cache); res = instantiate_parameters_1 (loop, chrec, INSERT_SUPERLOOP_CHRECS, cache);
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
...@@ -2229,13 +2242,15 @@ instantiate_parameters (struct loop *loop, ...@@ -2229,13 +2242,15 @@ instantiate_parameters (struct loop *loop,
} }
/* Similar to instantiate_parameters, but does not introduce the /* Similar to instantiate_parameters, but does not introduce the
evolutions in outer loops for LOOP invariants in CHREC. */ evolutions in outer loops for LOOP invariants in CHREC, and does not
care about causing overflows, as long as they do not affect value
of an expression. */
static tree static tree
resolve_mixers (struct loop *loop, tree chrec) resolve_mixers (struct loop *loop, tree chrec)
{ {
htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info); htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info);
tree ret = instantiate_parameters_1 (loop, chrec, false, cache); tree ret = instantiate_parameters_1 (loop, chrec, FOLD_CONVERSIONS, cache);
htab_delete (cache); htab_delete (cache);
return ret; return ret;
} }
......
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