summaryrefslogtreecommitdiff
path: root/gcc/loop-iv.c
diff options
context:
space:
mode:
authorZdenek Dvorak <dvorakz@suse.cz>2005-05-06 22:24:00 +0200
committerZdenek Dvorak <rakdver@gcc.gnu.org>2005-05-06 20:24:00 +0000
commit4fbe4f91ff05cb6f4f9507fde1b63102a117e40f (patch)
treed915060a51b36c45e01302a15b2e5cc3e27f761c /gcc/loop-iv.c
parent6245372caaee11600cf7aab808ff30bfaccaf4e8 (diff)
downloadgcc-4fbe4f91ff05cb6f4f9507fde1b63102a117e40f.tar.gz
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/loop-iv.c')
-rw-r--r--gcc/loop-iv.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index 09ed73c6324..bacf8382b7f 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;
}
}