From 88d02c9e3e2d8e03745271bac7541767d9f553b5 Mon Sep 17 00:00:00 2001 From: rakdver Date: Tue, 20 Sep 2005 07:09:20 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104443 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 12 ++++++++ gcc/tree-chrec.c | 33 ++++++++++++++++++-- gcc/tree-chrec.h | 1 + gcc/tree-scalar-evolution.c | 73 +++++++++++++++++++++++++++------------------ 4 files changed, 87 insertions(+), 32 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ed36fd464e0..802e7a631df 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2005-09-20 Zdenek Dvorak + + 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 * config/i386/sse.md (reduc_splus_v4sf): Rename from reduc_plus_v4sf. diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c index 88b27d84aa6..0bf1d384592 100644 --- a/gcc/tree-chrec.c +++ b/gcc/tree-chrec.c @@ -1164,9 +1164,7 @@ chrec_convert (tree type, tree chrec, tree at_stmt) fprintf (dump_file, "\n)\n"); } - /* Directly convert to "don't know": no worth dealing with - difficult cases. */ - return chrec_dont_know; + return fold_convert (type, chrec); } return build_polynomial_chrec (CHREC_VARIABLE (chrec), @@ -1201,6 +1199,35 @@ chrec_convert (tree type, tree chrec, tree at_stmt) 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. */ tree diff --git a/gcc/tree-chrec.h b/gcc/tree-chrec.h index 6ef1b66a7f4..19719a65be8 100644 --- a/gcc/tree-chrec.h +++ b/gcc/tree-chrec.h @@ -68,6 +68,7 @@ extern tree chrec_fold_plus (tree, tree, tree); extern tree chrec_fold_minus (tree, tree, tree); extern tree chrec_fold_multiply (tree, tree, tree); extern tree chrec_convert (tree, tree, tree); +extern tree chrec_convert_aggressive (tree, tree); extern tree chrec_type (tree); /* Operations. */ diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index 235edcdcf35..82f814e40ff 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -1955,20 +1955,27 @@ loop_closed_phi_def (tree var) } /* 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 - ALLOW_SUPERLOOP_CHRECS is true, replacing loop invariants with - outer loop chrecs is done. CACHE is the cache of already instantiated - values. */ + with respect to LOOP. CHREC is the chrec to instantiate. CACHE is the cache + of already instantiated values. FLAGS modify the way chrecs are + instantiated. */ +/* 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 -instantiate_parameters_1 (struct loop *loop, tree chrec, - bool allow_superloop_chrecs, - htab_t cache) +instantiate_parameters_1 (struct loop *loop, tree chrec, int flags, htab_t cache) { tree res, op0, op1, op2; basic_block def_bb; struct loop *def_loop; - + if (automatically_generated_chrec_p (chrec) || is_gimple_min_invariant (chrec)) return 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 evolutions in outer loops), nothing to do. */ if (!def_bb - || (!allow_superloop_chrecs + || (!(flags & INSERT_SUPERLOOP_CHRECS) && !flow_bb_inside_loop_p (loop, def_bb))) return chrec; @@ -2036,8 +2043,7 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, } else if (res != chrec_dont_know) - res = instantiate_parameters_1 (loop, res, allow_superloop_chrecs, - cache); + res = instantiate_parameters_1 (loop, res, flags, cache); bitmap_clear_bit (already_instantiated, SSA_NAME_VERSION (chrec)); @@ -2047,12 +2053,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, case POLYNOMIAL_CHREC: op0 = instantiate_parameters_1 (loop, CHREC_LEFT (chrec), - allow_superloop_chrecs, cache); + flags, cache); if (op0 == chrec_dont_know) return chrec_dont_know; op1 = instantiate_parameters_1 (loop, CHREC_RIGHT (chrec), - allow_superloop_chrecs, cache); + flags, cache); if (op1 == chrec_dont_know) return chrec_dont_know; @@ -2063,12 +2069,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, case PLUS_EXPR: op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), - allow_superloop_chrecs, cache); + flags, cache); if (op0 == chrec_dont_know) return chrec_dont_know; op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1), - allow_superloop_chrecs, cache); + flags, cache); if (op1 == chrec_dont_know) return chrec_dont_know; @@ -2079,12 +2085,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, case MINUS_EXPR: op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), - allow_superloop_chrecs, cache); + flags, cache); if (op0 == chrec_dont_know) return chrec_dont_know; op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1), - allow_superloop_chrecs, cache); + flags, cache); if (op1 == chrec_dont_know) return chrec_dont_know; @@ -2095,12 +2101,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, case MULT_EXPR: op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), - allow_superloop_chrecs, cache); + flags, cache); if (op0 == chrec_dont_know) return chrec_dont_know; op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1), - allow_superloop_chrecs, cache); + flags, cache); if (op1 == chrec_dont_know) return chrec_dont_know; @@ -2113,10 +2119,17 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, case CONVERT_EXPR: case NON_LVALUE_EXPR: op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), - allow_superloop_chrecs, cache); + flags, cache); if (op0 == 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)) return chrec; @@ -2136,17 +2149,17 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, { case 3: op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), - allow_superloop_chrecs, cache); + flags, cache); if (op0 == chrec_dont_know) return chrec_dont_know; op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1), - allow_superloop_chrecs, cache); + flags, cache); if (op1 == chrec_dont_know) return chrec_dont_know; op2 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 2), - allow_superloop_chrecs, cache); + flags, cache); if (op2 == chrec_dont_know) return chrec_dont_know; @@ -2160,12 +2173,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, case 2: op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), - allow_superloop_chrecs, cache); + flags, cache); if (op0 == chrec_dont_know) return chrec_dont_know; op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1), - allow_superloop_chrecs, cache); + flags, cache); if (op1 == chrec_dont_know) return chrec_dont_know; @@ -2176,7 +2189,7 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, case 1: op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0), - allow_superloop_chrecs, cache); + flags, cache); if (op0 == chrec_dont_know) return chrec_dont_know; if (op0 == TREE_OPERAND (chrec, 0)) @@ -2214,7 +2227,7 @@ instantiate_parameters (struct loop *loop, 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)) { @@ -2229,13 +2242,15 @@ instantiate_parameters (struct loop *loop, } /* 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 resolve_mixers (struct loop *loop, tree chrec) { 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); return ret; } -- 2.11.4.GIT