@@ -254,18 +254,51 @@ doloop_condition_get (rtx doloop_pat)
return 0;
}
-/* Return nonzero if the loop specified by LOOP is suitable for
- the use of special low-overhead looping instructions. DESC
- describes the number of iterations of the loop. */
+/* Check all insns of LOOP to see if the loop is suitable for the use of
+ special low-overhead looping instructions. Return TRUE if yes, false
+ otherwise. */
static bool
-doloop_valid_p (struct loop *loop, struct niter_desc *desc)
+doloop_insn_valid_p (struct loop *loop)
{
- basic_block *body = get_loop_body (loop), bb;
- rtx_insn *insn;
unsigned i;
- bool result = true;
+ rtx_insn *insn;
+ basic_block *body = get_loop_body (loop), bb;
+ for (i = 0; i < loop->num_nodes; i++)
+ {
+ bb = body[i];
+
+ for (insn = BB_HEAD (bb);
+ insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
+ {
+ /* Different targets have different necessities for low-overhead
+ looping. Call the back end for each instruction within the loop
+ to let it decide whether the insn prohibits a low-overhead loop.
+ It will then return the cause for it to emit to the dump file. */
+ const char * invalid = targetm.invalid_within_doloop (insn);
+ if (invalid)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Doloop: %s\n", invalid);
+
+ free (body);
+ return false;
+ }
+ }
+ }
+ free (body);
+ return true;
+}
+
+/* Check the number of iterations described by DESC of a loop to see if
+ the loop is suitable for the use of special low-overhead looping
+ instructions. Return true if yes, false otherwise. */
+
+static bool
+doloop_niter_valid_p (struct loop *, struct niter_desc *desc)
+{
/* Check for loops that may not terminate under special conditions. */
if (!desc->simple_p
|| desc->assumptions
@@ -295,38 +328,10 @@ doloop_valid_p (struct loop *loop, struct niter_desc *desc)
enable count-register loops in this case. */
if (dump_file)
fprintf (dump_file, "Doloop: Possible infinite iteration case.\n");
- result = false;
- goto cleanup;
- }
-
- for (i = 0; i < loop->num_nodes; i++)
- {
- bb = body[i];
-
- for (insn = BB_HEAD (bb);
- insn != NEXT_INSN (BB_END (bb));
- insn = NEXT_INSN (insn))
- {
- /* Different targets have different necessities for low-overhead
- looping. Call the back end for each instruction within the loop
- to let it decide whether the insn prohibits a low-overhead loop.
- It will then return the cause for it to emit to the dump file. */
- const char * invalid = targetm.invalid_within_doloop (insn);
- if (invalid)
- {
- if (dump_file)
- fprintf (dump_file, "Doloop: %s\n", invalid);
- result = false;
- goto cleanup;
- }
- }
+ return false;
}
- result = true;
-
-cleanup:
- free (body);
- return result;
+ return true;
}
/* Adds test of COND jumping to DEST on edge *E and set *E to the new fallthru
@@ -621,17 +626,25 @@ doloop_optimize (struct loop *loop)
if (dump_file)
fprintf (dump_file, "Doloop: Processing loop %d.\n", loop->num);
+ if (!doloop_insn_valid_p (loop))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Doloop: The loop is not suitable.\n");
+
+ return false;
+ }
+
iv_analysis_loop_init (loop);
/* Find the simple exit of a LOOP. */
desc = get_simple_loop_desc (loop);
/* Check that loop is a candidate for a low-overhead looping insn. */
- if (!doloop_valid_p (loop, desc))
+ if (!doloop_niter_valid_p (loop, desc))
{
if (dump_file)
- fprintf (dump_file,
- "Doloop: The loop is not suitable.\n");
+ fprintf (dump_file, "Doloop: The loop is not suitable.\n");
+
return false;
}
mode = desc->mode;