Hi, This is a simple refactoring patch which can help long compile time issue reported as PR72855. Basically, it moves cheaper checks before expensive ones. By doing this, doloop -optimization fails on cheap checks, thus following expensive data-flow analysis is skipped. Bill helped bootstrap/test on powerpc64le-unknown-linux-gnu. Is it OK?
Thanks, bin 2016-08-12 Bin Cheng <bin.ch...@arm.com> PR rtl-optimization/72855 * loop-doloop.c (doloop_insn_valid_p): New function. (doloop_valid_p): Rename to... (doloop_niter_valid_p): ...this. Factor out insn check to function doloop_insn_valid_p. (doloop_optimize): Update uses.
diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c index c311516..9fb04cf 100644 --- a/gcc/loop-doloop.c +++ b/gcc/loop-doloop.c @@ -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;