diff options
author | spop <spop@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-06-07 19:51:25 +0000 |
---|---|---|
committer | spop <spop@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-06-07 19:51:25 +0000 |
commit | b3786ab323f4845c9721759e9e0442bfa68eafe4 (patch) | |
tree | 4aae0809ad1fc08b9c4dad889abab72475236b7f /gcc/tree-chrec.c | |
parent | e8473153f8d7b879a3faaa173e192a0d5ba78250 (diff) | |
download | gcc-b3786ab323f4845c9721759e9e0442bfa68eafe4.tar.gz |
Fixes PR 18403 and meta PR 21861.
* Makefile.in (tree-chrec.o): Depend on CFGLOOP_H and TREE_FLOW_H.
* tree-chrec.c: Include cfgloop.h and tree-flow.h.
(evolution_function_is_invariant_rec_p,
evolution_function_is_invariant_p): New.
(chrec_convert): Use an extra parameter AT_STMT for refining the
information that is passed down to convert_step. Integrate the
code that was in count_ev_in_wider_type.
* tree-chrec.h (count_ev_in_wider_type): Removed.
(chrec_convert): Modify its declaration.
(evolution_function_is_invariant_p): Declared.
(evolution_function_is_affine_p): Use evolution_function_is_invariant_p.
* tree-flow.h (can_count_iv_in_wider_type): Renamed convert_step.
(scev_probably_wraps_p): Declared.
* tree-scalar-evolution.c (count_ev_in_wider_type): Removed.
(follow_ssa_edge_in_rhs, interpret_rhs_modify_expr):
Use an extra parameter AT_STMT for refining the information that is
passed down to convert_step.
(follow_ssa_edge_inner_loop_phi, follow_ssa_edge,
analyze_scalar_evolution_1): Initialize AT_STMT with the current
analyzed statement.
(instantiate_parameters_1): Don't know yet how to initialize AT_STMT.
* tree-ssa-loop-ivopts.c (idx_find_step): Update the use of
can_count_iv_in_wider_type to use convert_step.
* tree-ssa-loop-niter.c (can_count_iv_in_wider_type_bound): Move
code that is independent of the loop over the known iteration
bounds to convert_step_widening, the rest is moved to
proved_non_wrapping_p.
(scev_probably_wraps_p): New.
(can_count_iv_in_wider_type): Renamed convert_step.
* tree-vrp.c (adjust_range_with_scev): Take an extra AT_STMT parameter.
Use scev_probably_wraps_p for computing init_is_max.
(vrp_visit_assignment): Pass the current analyzed statement to
adjust_range_with_scev.
(execute_vrp): Call estimate_numbers_of_iterations for refining the
information provided by scev analyzer.
testsuite:
* testsuite/gcc.dg/vect/vect-77.c: Remove xfail from lp64.
* testsuite/gcc.dg/vect/vect-78.c: Same.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@100718 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-chrec.c')
-rw-r--r-- | gcc/tree-chrec.c | 139 |
1 files changed, 99 insertions, 40 deletions
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c index 1a7e8c8c631..ee171506140 100644 --- a/gcc/tree-chrec.c +++ b/gcc/tree-chrec.c @@ -32,6 +32,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "tree.h" #include "diagnostic.h" #include "varray.h" +#include "cfgloop.h" +#include "tree-flow.h" #include "tree-chrec.h" #include "tree-pass.h" #include "params.h" @@ -909,6 +911,57 @@ tree_contains_chrecs (tree expr, int *size) } } +/* Recursive helper function. */ + +static bool +evolution_function_is_invariant_rec_p (tree chrec, int loopnum) +{ + if (evolution_function_is_constant_p (chrec)) + return true; + + if (TREE_CODE (chrec) == SSA_NAME + && expr_invariant_in_loop_p (current_loops->parray[loopnum], + chrec)) + return true; + + if (TREE_CODE (chrec) == POLYNOMIAL_CHREC + && CHREC_VARIABLE (chrec) == (unsigned) loopnum) + return false; + + switch (TREE_CODE_LENGTH (TREE_CODE (chrec))) + { + case 2: + if (!evolution_function_is_invariant_rec_p (TREE_OPERAND (chrec, 1), + loopnum)) + return false; + + case 1: + if (!evolution_function_is_invariant_rec_p (TREE_OPERAND (chrec, 0), + loopnum)) + return false; + return true; + + default: + return false; + } + + return false; +} + +/* Return true if CHREC is invariant in loop LOOPNUM, false otherwise. */ + +bool +evolution_function_is_invariant_p (tree chrec, int loopnum) +{ + if (evolution_function_is_constant_p (chrec)) + return true; + + if (current_loops != NULL) + return evolution_function_is_invariant_rec_p (chrec, loopnum); + + return false; +} + /* Determine whether the given tree is an affine multivariate evolution. */ @@ -1019,11 +1072,17 @@ nb_vars_in_chrec (tree chrec) -/* Convert CHREC to TYPE. The following is rule is always true: - TREE_TYPE (chrec) == TREE_TYPE (CHREC_LEFT (chrec)) == TREE_TYPE - (CHREC_RIGHT (chrec)). An example of what could happen when adding - two chrecs and the type of the CHREC_RIGHT is different than - CHREC_LEFT is: +/* Convert CHREC to TYPE. When the analyzer knows the context in + which the CHREC is built, it sets AT_STMT to the statement that + contains the definition of the analyzed variable, otherwise the + conversion is less accurate: the information is used for + determining a more accurate estimation of the number of iterations. + By default AT_STMT could be safely set to NULL_TREE. + + The following rule is always true: TREE_TYPE (chrec) == + TREE_TYPE (CHREC_LEFT (chrec)) == TREE_TYPE (CHREC_RIGHT (chrec)). + An example of what could happen when adding two chrecs and the type + of the CHREC_RIGHT is different than CHREC_LEFT is: {(uint) 0, +, (uchar) 10} + {(uint) 0, +, (uchar) 250} @@ -1038,11 +1097,10 @@ nb_vars_in_chrec (tree chrec) */ tree -chrec_convert (tree type, - tree chrec) +chrec_convert (tree type, tree chrec, tree at_stmt) { - tree ct; - + tree ct, res; + if (automatically_generated_chrec_p (chrec)) return chrec; @@ -1050,43 +1108,44 @@ chrec_convert (tree type, if (ct == type) return chrec; - if (TYPE_PRECISION (ct) < TYPE_PRECISION (type)) - return count_ev_in_wider_type (type, chrec); - - switch (TREE_CODE (chrec)) + if (evolution_function_is_affine_p (chrec)) { - case POLYNOMIAL_CHREC: + tree step = convert_step (current_loops->parray[CHREC_VARIABLE (chrec)], + type, CHREC_LEFT (chrec), CHREC_RIGHT (chrec), + at_stmt); + if (!step) + return fold_convert (type, chrec); + return build_polynomial_chrec (CHREC_VARIABLE (chrec), - chrec_convert (type, - CHREC_LEFT (chrec)), - chrec_convert (type, - CHREC_RIGHT (chrec))); + chrec_convert (type, CHREC_LEFT (chrec), + at_stmt), + step); + } - default: - { - tree res = fold_convert (type, chrec); + if (TREE_CODE (chrec) == POLYNOMIAL_CHREC) + return chrec_dont_know; - /* Don't propagate overflows. */ - if (CONSTANT_CLASS_P (res)) - { - TREE_CONSTANT_OVERFLOW (res) = 0; - TREE_OVERFLOW (res) = 0; - } + res = fold_convert (type, chrec); - /* But reject constants that don't fit in their type after conversion. - This can happen if TYPE_MIN_VALUE or TYPE_MAX_VALUE are not the - natural values associated with TYPE_PRECISION and TYPE_UNSIGNED, - and can cause problems later when computing niters of loops. Note - that we don't do the check before converting because we don't want - to reject conversions of negative chrecs to unsigned types. */ - if (TREE_CODE (res) == INTEGER_CST - && TREE_CODE (type) == INTEGER_TYPE - && !int_fits_type_p (res, type)) - res = chrec_dont_know; - - return res; - } + /* Don't propagate overflows. */ + if (CONSTANT_CLASS_P (res)) + { + TREE_CONSTANT_OVERFLOW (res) = 0; + TREE_OVERFLOW (res) = 0; } + + /* But reject constants that don't fit in their type after conversion. + This can happen if TYPE_MIN_VALUE or TYPE_MAX_VALUE are not the + natural values associated with TYPE_PRECISION and TYPE_UNSIGNED, + and can cause problems later when computing niters of loops. Note + that we don't do the check before converting because we don't want + to reject conversions of negative chrecs to unsigned types. */ + if (TREE_CODE (res) == INTEGER_CST + && TREE_CODE (type) == INTEGER_TYPE + && !int_fits_type_p (res, type)) + res = chrec_dont_know; + + return res; } /* Returns the type of the chrec. */ |