diff options
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/basic-block.h | 8 | ||||
-rw-r--r-- | gcc/flow.c | 74 | ||||
-rw-r--r-- | gcc/loop.c | 89 | ||||
-rw-r--r-- | gcc/toplev.c | 2 |
5 files changed, 155 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ac38c70..a48284e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,20 @@ 2000-08-26 Michael Hayes <mhayes@cygnus.com> + * loop.c (loop_dump_aux, debug_loop): New functions. + (LOOP_BLOCK_NUM_1, LOOP_BLOCK_NUM, LOOP_INSN_UID): New macros. + + * flow.c (flow_loops_dump): Add callback parameter. + (flow_loop_dump): Add callback parameter and call it. Move + loop note debugging code to loop_dump_aux. + + * basic-block.h (flow_loop_dump): Add callback parameter + (flow_loops_dump): Likewise. + + * toplev.c (rest_of_compilation): Add NULL callback function pointer + to call to flow_loops_dump. + +2000-08-26 Michael Hayes <mhayes@cygnus.com> + * loop.c (count_loop_regs_set): Replace start and end arguments with loop argument. All callers udated. diff --git a/gcc/basic-block.h b/gcc/basic-block.h index a018f23..a653324 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -398,8 +398,12 @@ struct loops extern int flow_loops_find PARAMS ((struct loops *)); extern void flow_loops_free PARAMS ((struct loops *)); -extern void flow_loops_dump PARAMS ((const struct loops *, FILE *, int)); - +extern void flow_loops_dump PARAMS ((const struct loops *, FILE *, + void (*)(const struct loop *, + FILE *, int), int)); +extern void flow_loop_dump PARAMS ((const struct loop *, FILE *, + void (*)(const struct loop *, + FILE *, int), int)); /* This structure maintains an edge list vector. */ struct edge_list @@ -7199,12 +7199,49 @@ flow_loop_nested_p (outer, loop) return sbitmap_a_subset_b_p (loop->nodes, outer->nodes); } -/* Dump the loop information specified by LOOPS to the stream FILE. */ +/* Dump the loop information specified by LOOP to the stream FILE + using auxiliary dump callback function LOOP_DUMP_AUX if non null. */ void -flow_loops_dump (loops, file, verbose) +flow_loop_dump (loop, file, loop_dump_aux, verbose) + const struct loop *loop; + FILE *file; + void (*loop_dump_aux)(const struct loop *, FILE *, int); + int verbose; +{ + if (! loop || ! loop->header) + return; + + fprintf (file, ";;\n;; Loop %d (%d to %d):%s%s\n", + loop->num, INSN_UID (loop->first->head), + INSN_UID (loop->last->end), + loop->shared ? " shared" : "", + loop->invalid ? " invalid" : ""); + fprintf (file, ";; header %d, latch %d, pre-header %d, first %d, last %d\n", + loop->header->index, loop->latch->index, + loop->pre_header ? loop->pre_header->index : -1, + loop->first->index, loop->last->index); + fprintf (file, ";; depth %d, level %d, outer %ld\n", + loop->depth, loop->level, + (long) (loop->outer ? loop->outer->num : -1)); + + fprintf (file, ";; %d", loop->num_nodes); + flow_nodes_print (" nodes", loop->nodes, file); + fprintf (file, ";; %d", loop->num_exits); + flow_exits_print (" exits", loop->exits, loop->num_exits, file); + + if (loop_dump_aux) + loop_dump_aux (loop, file, verbose); +} + + +/* Dump the loop information specified by LOOPS to the stream FILE, + using auxiliary dump callback function LOOP_DUMP_AUX if non null. */ +void +flow_loops_dump (loops, file, loop_dump_aux, verbose) const struct loops *loops; FILE *file; + void (*loop_dump_aux)(const struct loop *, FILE *, int); int verbose; { int i; @@ -7214,23 +7251,14 @@ flow_loops_dump (loops, file, verbose) if (! num_loops || ! file) return; - fprintf (file, ";; %d loops found, %d levels\n", + fprintf (file, ";; %d loops found, %d levels\n", num_loops, loops->levels); for (i = 0; i < num_loops; i++) { struct loop *loop = &loops->array[i]; - fprintf (file, ";; loop %d (%d to %d):\n;; header %d, latch %d, pre-header %d, depth %d, level %d, outer %ld\n", - i, INSN_UID (loop->header->head), INSN_UID (loop->latch->end), - loop->header->index, loop->latch->index, - loop->pre_header ? loop->pre_header->index : -1, - loop->depth, loop->level, - (long) (loop->outer ? (loop->outer - loops->array) : -1)); - fprintf (file, ";; %d", loop->num_nodes); - flow_nodes_print (" nodes", loop->nodes, file); - fprintf (file, ";; %d", loop->num_exits); - flow_exits_print (" exits", loop->exits, loop->num_exits, file); + flow_loop_dump (loop, file, loop_dump_aux, verbose); if (loop->shared) { @@ -7252,35 +7280,20 @@ flow_loops_dump (loops, file, verbose) must be disjoint. */ disjoint = ! flow_loop_nested_p (smaller ? loop : oloop, smaller ? oloop : loop); - fprintf (file, + fprintf (file, ";; loop header %d shared by loops %d, %d %s\n", loop->header->index, i, j, disjoint ? "disjoint" : "nested"); } } } - - if (verbose) - { - /* Print diagnostics to compare our concept of a loop with - what the loop notes say. */ - if (GET_CODE (PREV_INSN (loop->first->head)) != NOTE - || NOTE_LINE_NUMBER (PREV_INSN (loop->first->head)) - != NOTE_INSN_LOOP_BEG) - fprintf (file, ";; No NOTE_INSN_LOOP_BEG at %d\n", - INSN_UID (PREV_INSN (loop->first->head))); - if (GET_CODE (NEXT_INSN (loop->last->end)) != NOTE - || NOTE_LINE_NUMBER (NEXT_INSN (loop->last->end)) - != NOTE_INSN_LOOP_END) - fprintf (file, ";; No NOTE_INSN_LOOP_END at %d\n", - INSN_UID (NEXT_INSN (loop->last->end))); - } } if (verbose) flow_loops_cfg_dump (loops, file); } + /* Free all the memory allocated for LOOPS. */ void @@ -7316,6 +7329,7 @@ flow_loops_free (loops) } } + /* Find the exits from the loop using the bitmap of loop nodes NODES and store in EXITS array. Return the number of exits from the loop. */ @@ -313,6 +313,9 @@ static int replace_label PARAMS ((rtx *, void *)); static rtx check_insn_for_givs PARAMS((struct loop *, rtx, int, int)); static rtx check_insn_for_bivs PARAMS((struct loop *, rtx, int, int)); +static void loop_dump_aux PARAMS ((const struct loop *, FILE *, int)); +void debug_loop PARAMS ((const struct loop *)); + typedef struct rtx_and_int { rtx r; int i; @@ -9953,3 +9956,89 @@ replace_label (x, data) return 0; } + +#define LOOP_BLOCK_NUM_1(INSN) \ +((INSN) ? (BLOCK_FOR_INSN (INSN) ? BLOCK_NUM (INSN) : - 1) : -1) + +/* The notes do not have an assigned block, so look at the next insn. */ +#define LOOP_BLOCK_NUM(INSN) \ +((INSN) ? (GET_CODE (INSN) == NOTE \ + ? LOOP_BLOCK_NUM_1 (next_nonnote_insn (INSN)) \ + : LOOP_BLOCK_NUM_1 (INSN)) \ + : -1) + +#define LOOP_INSN_UID(INSN) ((INSN) ? INSN_UID (INSN) : -1) + +static void loop_dump_aux (loop, file, verbose) + const struct loop *loop; + FILE *file; + int verbose; +{ + rtx label; + + if (! loop || ! file) + return; + + /* Print diagnostics to compare our concept of a loop with + what the loop notes say. */ + if (! PREV_INSN (loop->first->head) + || GET_CODE (PREV_INSN (loop->first->head)) != NOTE + || NOTE_LINE_NUMBER (PREV_INSN (loop->first->head)) + != NOTE_INSN_LOOP_BEG) + fprintf (file, ";; No NOTE_INSN_LOOP_BEG at %d\n", + INSN_UID (PREV_INSN (loop->first->head))); + if (! NEXT_INSN (loop->last->end) + || GET_CODE (NEXT_INSN (loop->last->end)) != NOTE + || NOTE_LINE_NUMBER (NEXT_INSN (loop->last->end)) + != NOTE_INSN_LOOP_END) + fprintf (file, ";; No NOTE_INSN_LOOP_END at %d\n", + INSN_UID (NEXT_INSN (loop->last->end))); + + if (loop->start) + { + fprintf (file, + ";; start %d (%d), cont dom %d (%d), cont %d (%d), vtop %d (%d), end %d (%d)\n", + LOOP_BLOCK_NUM (loop->start), + LOOP_INSN_UID (loop->start), + LOOP_BLOCK_NUM (loop->cont), + LOOP_INSN_UID (loop->cont), + LOOP_BLOCK_NUM (loop->cont), + LOOP_INSN_UID (loop->cont), + LOOP_BLOCK_NUM (loop->vtop), + LOOP_INSN_UID (loop->vtop), + LOOP_BLOCK_NUM (loop->end), + LOOP_INSN_UID (loop->end)); + fprintf (file, ";; top %d (%d), scan start %d (%d)\n", + LOOP_BLOCK_NUM (loop->top), + LOOP_INSN_UID (loop->top) , + LOOP_BLOCK_NUM (loop->scan_start), + LOOP_INSN_UID (loop->scan_start)); + fprintf (file, ";; exit_count %d", loop->exit_count); + if (loop->exit_count) + { + fputs (", labels:", file); + for (label = loop->exit_labels; label; label = LABEL_NEXTREF (label)) + { + fprintf (file, " %d ", + LOOP_INSN_UID (XEXP (label, 0))); + } + } + fputs ("\n", file); + + /* This can happen when a marked loop appears as two nested loops, + say from while (a || b) {}. The inner loop won't match + the loop markers but the outer one will. */ + if (LOOP_BLOCK_NUM (loop->cont) != loop->latch->index) + fprintf (file, ";; NOTE_INSN_LOOP_CONT not in loop latch\n"); + } +} + + +/* Call this function from the debugger to dump LOOP. */ + +void +debug_loop (loop) + const struct loop *loop; +{ + flow_loop_dump (loop, stderr, loop_dump_aux, 1); +} diff --git a/gcc/toplev.c b/gcc/toplev.c index 64afd04..e0f606f 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -3165,7 +3165,7 @@ rest_of_compilation (decl) estimate_probability (&loops); if (rtl_dump_file) - flow_loops_dump (&loops, rtl_dump_file, 0); + flow_loops_dump (&loops, rtl_dump_file, NULL, 0); flow_loops_free (&loops); } |