diff options
author | Zdenek Dvorak <dvorakz@suse.cz> | 2005-05-06 22:24:00 +0200 |
---|---|---|
committer | Zdenek Dvorak <rakdver@gcc.gnu.org> | 2005-05-06 20:24:00 +0000 |
commit | 4fbe4f91ff05cb6f4f9507fde1b63102a117e40f (patch) | |
tree | d915060a51b36c45e01302a15b2e5cc3e27f761c /gcc | |
parent | 6245372caaee11600cf7aab808ff30bfaccaf4e8 (diff) | |
download | gcc-4fbe4f91ff05cb6f4f9507fde1b63102a117e40f.zip gcc-4fbe4f91ff05cb6f4f9507fde1b63102a117e40f.tar.gz gcc-4fbe4f91ff05cb6f4f9507fde1b63102a117e40f.tar.bz2 |
re PR rtl-optimization/21254 (Incorrect code with -funroll-loops for multiple targets with same code)
PR rtl-optimization/21254
* loop-iv.c (iv_number_of_iterations): Simplify infiniteness
assumptions for loops that otherwise do not roll.
(find_simple_exit): Prefer # of iterations that is guaranteed
not to be infinite.
* loop-unroll.c (decide_peel_once_rolling,
decide_peel_completely): Check whether the loop is infinite.
From-SVN: r99332
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/loop-iv.c | 47 | ||||
-rw-r--r-- | gcc/loop-unroll.c | 4 |
3 files changed, 47 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e98ebef..e579c1d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2005-05-06 Zdenek Dvorak <dvorakz@suse.cz> + + PR rtl-optimization/21254 + * loop-iv.c (iv_number_of_iterations): Simplify infiniteness + assumptions for loops that otherwise do not roll. + (find_simple_exit): Prefer # of iterations that is guaranteed + not to be infinite. + * loop-unroll.c (decide_peel_once_rolling, + decide_peel_completely): Check whether the loop is infinite. + 2005-05-06 Pat Haugen <pthaugen@us.ibm.com> * config/rs6000/sysv4.opt: Fix typo. diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index 09ed73c..bacf838 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -2148,7 +2148,7 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition, assumption = simplify_gen_relational (EQ, SImode, mode, tmp, mode_mmax); if (assumption == const_true_rtx) - goto zero_iter; + goto zero_iter_simplify; iv0.base = simplify_gen_binary (PLUS, comp_mode, iv0.base, const1_rtx); } @@ -2158,7 +2158,7 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition, assumption = simplify_gen_relational (EQ, SImode, mode, tmp, mode_mmin); if (assumption == const_true_rtx) - goto zero_iter; + goto zero_iter_simplify; iv1.base = simplify_gen_binary (PLUS, comp_mode, iv1.base, constm1_rtx); } @@ -2185,7 +2185,8 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition, { desc->infinite = alloc_EXPR_LIST (0, const_true_rtx, NULL_RTX); - return; + /* Fill in the remaining fields somehow. */ + goto zero_iter_simplify; } } else @@ -2195,7 +2196,8 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition, { desc->infinite = alloc_EXPR_LIST (0, const_true_rtx, NULL_RTX); - return; + /* Fill in the remaining fields somehow. */ + goto zero_iter_simplify; } } } @@ -2306,7 +2308,7 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition, assumption = simplify_gen_relational (reverse_condition (cond), SImode, mode, tmp0, tmp1); if (assumption == const_true_rtx) - goto zero_iter; + goto zero_iter_simplify; else if (assumption != const0_rtx) desc->noloop_assumptions = alloc_EXPR_LIST (0, assumption, desc->noloop_assumptions); @@ -2449,7 +2451,7 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition, delta = simplify_gen_binary (MINUS, mode, tmp1, delta); } if (assumption == const_true_rtx) - goto zero_iter; + goto zero_iter_simplify; else if (assumption != const0_rtx) desc->noloop_assumptions = alloc_EXPR_LIST (0, assumption, desc->noloop_assumptions); @@ -2517,16 +2519,26 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition, return; -fail: - desc->simple_p = false; - return; +zero_iter_simplify: + /* Simplify the assumptions. */ + simplify_using_initial_values (loop, AND, &desc->assumptions); + if (desc->assumptions + && XEXP (desc->assumptions, 0) == const0_rtx) + goto fail; + simplify_using_initial_values (loop, IOR, &desc->infinite); + /* Fallthru. */ zero_iter: desc->const_iter = true; desc->niter = 0; desc->niter_max = 0; + desc->noloop_assumptions = NULL_RTX; desc->niter_expr = const0_rtx; return; + +fail: + desc->simple_p = false; + return; } /* Checks whether E is a simple exit from LOOP and stores its description @@ -2603,12 +2615,21 @@ find_simple_exit (struct loop *loop, struct niter_desc *desc) if (!act.simple_p) continue; - /* Prefer constant iterations; the less the better. */ if (!any) any = true; - else if (!act.const_iter - || (desc->const_iter && act.niter >= desc->niter)) - continue; + else + { + /* Prefer constant iterations; the less the better. */ + if (!act.const_iter + || (desc->const_iter && act.niter >= desc->niter)) + continue; + + /* Also if the actual exit may be infinite, while the old one + not, prefer the old one. */ + if (act.infinite && !desc->infinite) + continue; + } + *desc = act; } } diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c index 409df0c..68512d0 100644 --- a/gcc/loop-unroll.c +++ b/gcc/loop-unroll.c @@ -375,6 +375,7 @@ decide_peel_once_rolling (struct loop *loop, int flags ATTRIBUTE_UNUSED) /* Check number of iterations. */ if (!desc->simple_p || desc->assumptions + || desc->infinite || !desc->const_iter || desc->niter != 0) { @@ -444,7 +445,8 @@ decide_peel_completely (struct loop *loop, int flags ATTRIBUTE_UNUSED) /* Check number of iterations. */ if (!desc->simple_p || desc->assumptions - || !desc->const_iter) + || !desc->const_iter + || desc->infinite) { if (dump_file) fprintf (dump_file, |