diff options
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/tree-chrec.c | 37 | ||||
-rw-r--r-- | gcc/tree-scalar-evolution.c | 56 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-niter.c | 12 |
5 files changed, 110 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7ec894c86cc..e9295e65252 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2005-09-09 Sebastian Pop <pop@cri.ensmp.fr> + + * Makefile.in (tree-chrec.o): Depends on SCEV_H. + * tree-chrec.c: Include tree-scalar-evolution.h. + (chrec_convert): Instantiate the base and step before calling + scev_probably_wraps_p that would fail on parametric evolutions. + Collect all the fails into a single section failed_to_convert, + print a diagnostic, and return chrec_dont_know instead of calling + fold_convert. + * tree-scalar-evolution.c (loop_closed_phi_def): New. + (instantiate_parameters_1): Avoid instantiation of loop closed ssa + phi nodes. + (scev_const_prop): Don't replace the definition of a loop closed ssa + phi node by itself, or by another loop closed ssa phi node. + * tree-ssa-loop-niter.c (scev_probably_wraps_p, convert_step): Check + that base and step are defined. + 2005-09-09 Richard Guenther <rguenther@suse.de> PR c++/23624 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 69e482dd509..3ed71862980 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1944,7 +1944,7 @@ tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) tree-inline.h $(DIAGNOSTIC_H) $(HASHTAB_H) \ $(TM_H) coretypes.h tree-chrec.o: tree-chrec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ - $(GGC_H) $(TREE_H) real.h tree-chrec.h tree-pass.h $(PARAMS_H) \ + $(GGC_H) $(TREE_H) real.h $(SCEV_H) tree-pass.h $(PARAMS_H) \ $(DIAGNOSTIC_H) $(VARRAY_H) $(CFGLOOP_H) $(TREE_FLOW_H) tree-scalar-evolution.o: tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(GGC_H) $(TREE_H) real.h $(RTL_H) \ diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c index 8dae9167ef6..3324c8bc2b7 100644 --- a/gcc/tree-chrec.c +++ b/gcc/tree-chrec.c @@ -38,6 +38,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "tree-chrec.h" #include "tree-pass.h" #include "params.h" +#include "tree-scalar-evolution.h" @@ -1120,8 +1121,12 @@ chrec_convert (tree type, tree chrec, tree at_stmt) if (evolution_function_is_affine_p (chrec)) { - tree step; + tree base, step; bool dummy; + struct loop *loop = current_loops->parray[CHREC_VARIABLE (chrec)]; + + base = instantiate_parameters (loop, CHREC_LEFT (chrec)); + step = instantiate_parameters (loop, CHREC_RIGHT (chrec)); /* Avoid conversion of (signed char) {(uchar)1, +, (uchar)1}_x when it is not possible to prove that the scev does not wrap. @@ -1130,16 +1135,32 @@ chrec_convert (tree type, tree chrec, tree at_stmt) 1, 2, ..., 127, -128, ... The result should not be {(schar)1, +, (schar)1}_x, but instead, we should keep the conversion: (schar) {(uchar)1, +, (uchar)1}_x. */ - if (scev_probably_wraps_p (type, CHREC_LEFT (chrec), CHREC_RIGHT (chrec), - at_stmt, - current_loops->parray[CHREC_VARIABLE (chrec)], + if (scev_probably_wraps_p (type, base, step, at_stmt, loop, &dummy, &dummy)) - return fold_convert (type, chrec); + goto failed_to_convert; - step = convert_step (current_loops->parray[CHREC_VARIABLE (chrec)], type, - CHREC_LEFT (chrec), CHREC_RIGHT (chrec), at_stmt); + step = convert_step (loop, type, base, step, at_stmt); if (!step) - return fold_convert (type, chrec); + { + failed_to_convert:; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "(failed conversion:"); + fprintf (dump_file, "\n type: "); + print_generic_expr (dump_file, type, 0); + fprintf (dump_file, "\n base: "); + print_generic_expr (dump_file, base, 0); + fprintf (dump_file, "\n step: "); + print_generic_expr (dump_file, step, 0); + fprintf (dump_file, "\n estimated_nb_iterations: "); + print_generic_expr (dump_file, loop->estimated_nb_iterations, 0); + fprintf (dump_file, "\n)\n"); + } + + /* Directly convert to "don't know": no worth dealing with + difficult cases. */ + return chrec_dont_know; + } return build_polynomial_chrec (CHREC_VARIABLE (chrec), chrec_convert (type, CHREC_LEFT (chrec), diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index e7490479777..235edcdcf35 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -1928,6 +1928,32 @@ set_instantiated_value (htab_t cache, tree version, tree val) info->chrec = val; } +/* Return the closed_loop_phi node for VAR. If there is none, return + NULL_TREE. */ + +static tree +loop_closed_phi_def (tree var) +{ + struct loop *loop; + edge exit; + tree phi; + + if (var == NULL_TREE + || TREE_CODE (var) != SSA_NAME) + return NULL_TREE; + + loop = loop_containing_stmt (SSA_NAME_DEF_STMT (var)); + exit = loop->single_exit; + if (!exit) + return NULL_TREE; + + for (phi = phi_nodes (exit->dest); phi; phi = PHI_CHAIN (phi)) + if (PHI_ARG_DEF_FROM_EDGE (phi, exit) == var) + return PHI_RESULT (phi); + + return NULL_TREE; +} + /* 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 @@ -1993,9 +2019,26 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, result again. */ bitmap_set_bit (already_instantiated, SSA_NAME_VERSION (chrec)); res = analyze_scalar_evolution (def_loop, chrec); - if (res != chrec_dont_know) + + /* Don't instantiate loop-closed-ssa phi nodes. */ + if (TREE_CODE (res) == SSA_NAME + && (loop_containing_stmt (SSA_NAME_DEF_STMT (res)) == NULL + || (loop_containing_stmt (SSA_NAME_DEF_STMT (res))->depth + > def_loop->depth))) + { + if (res == chrec) + res = loop_closed_phi_def (chrec); + else + res = chrec; + + if (res == NULL_TREE) + res = chrec_dont_know; + } + + else if (res != chrec_dont_know) res = instantiate_parameters_1 (loop, res, allow_superloop_chrecs, cache); + bitmap_clear_bit (already_instantiated, SSA_NAME_VERSION (chrec)); /* Store the correct value to the cache. */ @@ -2652,7 +2695,8 @@ scev_const_prop (void) continue; /* Replace the uses of the name. */ - replace_uses_by (name, ev); + if (name != ev) + replace_uses_by (name, ev); if (!ssa_names_to_remove) ssa_names_to_remove = BITMAP_ALLOC (NULL); @@ -2712,7 +2756,13 @@ scev_const_prop (void) def = analyze_scalar_evolution_in_loop (ex_loop, ex_loop, def); if (!tree_does_not_contain_chrecs (def) - || chrec_contains_symbols_defined_in_loop (def, loop->num)) + || chrec_contains_symbols_defined_in_loop (def, loop->num) + || def == PHI_RESULT (phi) + || (TREE_CODE (def) == SSA_NAME + && loop_containing_stmt (SSA_NAME_DEF_STMT (def)) + && loop_containing_stmt (phi) + && loop_containing_stmt (SSA_NAME_DEF_STMT (def)) + == loop_containing_stmt (phi))) continue; /* If computing the expression is expensive, let it remain in diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 3ee27f4d5cc..b86641871e5 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -1857,7 +1857,9 @@ scev_probably_wraps_p (tree type, tree base, tree step, } } - if (TREE_CODE (base) == REAL_CST + if (chrec_contains_undetermined (base) + || chrec_contains_undetermined (step) + || TREE_CODE (base) == REAL_CST || TREE_CODE (step) == REAL_CST) { *unknown_max = true; @@ -1978,7 +1980,13 @@ tree convert_step (struct loop *loop, tree new_type, tree base, tree step, tree at_stmt) { - tree base_type = TREE_TYPE (base); + tree base_type; + + if (chrec_contains_undetermined (base) + || chrec_contains_undetermined (step)) + return NULL_TREE; + + base_type = TREE_TYPE (base); /* When not using wrapping arithmetic, signed types don't wrap. */ if (!flag_wrapv && !TYPE_UNSIGNED (base_type)) |