X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcfg.c;h=ff3f367913678045160983eb988011d67bb644d7;hb=ecbfdc878159c748742c4a5e8d416e4edd90cac9;hp=ba4dd812a64b1b3d40b912c4999f8b2cc9303596;hpb=917bbcab602907861c40cfad1cc5337aaf9d0f1d;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cfg.c b/gcc/cfg.c index ba4dd812a64..ff3f3679136 100644 --- a/gcc/cfg.c +++ b/gcc/cfg.c @@ -1,6 +1,6 @@ /* Control flow graph manipulation code for GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GCC. @@ -111,6 +111,7 @@ struct basic_block_def entry_exit_blocks[2] EXIT_BLOCK_PTR, /* next_bb */ 0, /* loop_depth */ NULL, /* loop_father */ + { NULL, NULL }, /* dom */ 0, /* count */ 0, /* frequency */ 0, /* flags */ @@ -133,6 +134,7 @@ struct basic_block_def entry_exit_blocks[2] NULL, /* next_bb */ 0, /* loop_depth */ NULL, /* loop_father */ + { NULL, NULL }, /* dom */ 0, /* count */ 0, /* frequency */ 0, /* flags */ @@ -155,7 +157,7 @@ init_flow (void) if (!initialized) { gcc_obstack_init (&flow_obstack); - flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0); + flow_firstobj = obstack_alloc (&flow_obstack, 0); initialized = 1; } else @@ -163,7 +165,7 @@ init_flow (void) free_alloc_pool (bb_pool); free_alloc_pool (edge_pool); obstack_free (&flow_obstack, flow_firstobj); - flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0); + flow_firstobj = obstack_alloc (&flow_obstack, 0); } bb_pool = create_alloc_pool ("Basic block pool", sizeof (struct basic_block_def), 100); @@ -332,7 +334,7 @@ cached_make_edge (sbitmap *edge_cache, basic_block src, basic_block dst, int fla if (flags == 0) return NULL; - /* FALLTHRU */ + /* Fall through. */ case 0: for (e = src->succ; e; e = e->succ_next) if (e->dest == dst) @@ -491,48 +493,49 @@ dump_flow_info (FILE *file) static const char * const reg_class_names[] = REG_CLASS_NAMES; fprintf (file, "%d registers.\n", max_regno); - for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) - if (REG_N_REFS (i)) - { - enum reg_class class, altclass; - - fprintf (file, "\nRegister %d used %d times across %d insns", - i, REG_N_REFS (i), REG_LIVE_LENGTH (i)); - if (REG_BASIC_BLOCK (i) >= 0) - fprintf (file, " in block %d", REG_BASIC_BLOCK (i)); - if (REG_N_SETS (i)) - fprintf (file, "; set %d time%s", REG_N_SETS (i), - (REG_N_SETS (i) == 1) ? "" : "s"); - if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i])) - fprintf (file, "; user var"); - if (REG_N_DEATHS (i) != 1) - fprintf (file, "; dies in %d places", REG_N_DEATHS (i)); - if (REG_N_CALLS_CROSSED (i) == 1) - fprintf (file, "; crosses 1 call"); - else if (REG_N_CALLS_CROSSED (i)) - fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i)); - if (regno_reg_rtx[i] != NULL - && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD) - fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i)); - - class = reg_preferred_class (i); - altclass = reg_alternate_class (i); - if (class != GENERAL_REGS || altclass != ALL_REGS) - { - if (altclass == ALL_REGS || class == ALL_REGS) - fprintf (file, "; pref %s", reg_class_names[(int) class]); - else if (altclass == NO_REGS) - fprintf (file, "; %s or none", reg_class_names[(int) class]); - else - fprintf (file, "; pref %s, else %s", - reg_class_names[(int) class], - reg_class_names[(int) altclass]); - } + if (reg_n_info) + for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) + if (REG_N_REFS (i)) + { + enum reg_class class, altclass; + + fprintf (file, "\nRegister %d used %d times across %d insns", + i, REG_N_REFS (i), REG_LIVE_LENGTH (i)); + if (REG_BASIC_BLOCK (i) >= 0) + fprintf (file, " in block %d", REG_BASIC_BLOCK (i)); + if (REG_N_SETS (i)) + fprintf (file, "; set %d time%s", REG_N_SETS (i), + (REG_N_SETS (i) == 1) ? "" : "s"); + if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i])) + fprintf (file, "; user var"); + if (REG_N_DEATHS (i) != 1) + fprintf (file, "; dies in %d places", REG_N_DEATHS (i)); + if (REG_N_CALLS_CROSSED (i) == 1) + fprintf (file, "; crosses 1 call"); + else if (REG_N_CALLS_CROSSED (i)) + fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i)); + if (regno_reg_rtx[i] != NULL + && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD) + fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i)); + + class = reg_preferred_class (i); + altclass = reg_alternate_class (i); + if (class != GENERAL_REGS || altclass != ALL_REGS) + { + if (altclass == ALL_REGS || class == ALL_REGS) + fprintf (file, "; pref %s", reg_class_names[(int) class]); + else if (altclass == NO_REGS) + fprintf (file, "; %s or none", reg_class_names[(int) class]); + else + fprintf (file, "; pref %s, else %s", + reg_class_names[(int) class], + reg_class_names[(int) altclass]); + } - if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i])) - fprintf (file, "; pointer"); - fprintf (file, ".\n"); - } + if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i])) + fprintf (file, "; pointer"); + fprintf (file, ".\n"); + } fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges); FOR_EACH_BB (bb) @@ -542,7 +545,7 @@ dump_flow_info (FILE *file) gcov_type lsum; fprintf (file, "\nBasic block %d: first insn %d, last %d, ", - bb->index, INSN_UID (bb->head), INSN_UID (bb->end)); + bb->index, INSN_UID (BB_HEAD (bb)), INSN_UID (BB_END (bb))); fprintf (file, "prev %d, next %d, ", bb->prev_bb->index, bb->next_bb->index); fprintf (file, "loop_depth %d, count ", bb->loop_depth); @@ -636,7 +639,7 @@ dump_edge_info (FILE *file, edge e, int do_succ) { static const char * const bitnames[] = { "fallthru", "ab", "abcall", "eh", "fake", "dfs_back", - "can_fallthru", "irreducible", "sibcall" + "can_fallthru", "irreducible", "sibcall", "loop_exit" }; int comma = 0; int i, flags = e->flags; @@ -697,7 +700,7 @@ alloc_aux_for_blocks (int size) /* Check whether AUX data are still allocated. */ else if (first_block_aux_obj) abort (); - first_block_aux_obj = (char *) obstack_alloc (&block_aux_obstack, 0); + first_block_aux_obj = obstack_alloc (&block_aux_obstack, 0); if (size) { basic_block bb; @@ -763,7 +766,7 @@ alloc_aux_for_edges (int size) else if (first_edge_aux_obj) abort (); - first_edge_aux_obj = (char *) obstack_alloc (&edge_aux_obstack, 0); + first_edge_aux_obj = obstack_alloc (&edge_aux_obstack, 0); if (size) { basic_block bb; @@ -807,182 +810,16 @@ free_aux_for_edges (void) clear_aux_for_edges (); } -/* Verify the CFG consistency. - - Currently it does following checks edge and basic block list correctness - and calls into IL dependent checking then. */ -void -verify_flow_info (void) -{ - size_t *edge_checksum; - int num_bb_notes, err = 0; - basic_block bb, last_bb_seen; - basic_block *last_visited; - - last_visited = (basic_block *) xcalloc (last_basic_block + 2, - sizeof (basic_block)); - edge_checksum = (size_t *) xcalloc (last_basic_block + 2, sizeof (size_t)); - - /* Check bb chain & numbers. */ - last_bb_seen = ENTRY_BLOCK_PTR; - FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb) - { - if (bb != EXIT_BLOCK_PTR - && bb != BASIC_BLOCK (bb->index)) - { - error ("bb %d on wrong place", bb->index); - err = 1; - } - - if (bb->prev_bb != last_bb_seen) - { - error ("prev_bb of %d should be %d, not %d", - bb->index, last_bb_seen->index, bb->prev_bb->index); - err = 1; - } - - last_bb_seen = bb; - } - - /* Now check the basic blocks (boundaries etc.) */ - FOR_EACH_BB_REVERSE (bb) - { - int n_fallthru = 0; - edge e; - - if (bb->count < 0) - { - error ("verify_flow_info: Wrong count of block %i %i", - bb->index, (int)bb->count); - err = 1; - } - if (bb->frequency < 0) - { - error ("verify_flow_info: Wrong frequency of block %i %i", - bb->index, bb->frequency); - err = 1; - } - for (e = bb->succ; e; e = e->succ_next) - { - if (last_visited [e->dest->index + 2] == bb) - { - error ("verify_flow_info: Duplicate edge %i->%i", - e->src->index, e->dest->index); - err = 1; - } - if (e->probability < 0 || e->probability > REG_BR_PROB_BASE) - { - error ("verify_flow_info: Wrong probability of edge %i->%i %i", - e->src->index, e->dest->index, e->probability); - err = 1; - } - if (e->count < 0) - { - error ("verify_flow_info: Wrong count of edge %i->%i %i", - e->src->index, e->dest->index, (int)e->count); - err = 1; - } - - last_visited [e->dest->index + 2] = bb; - - if (e->flags & EDGE_FALLTHRU) - n_fallthru++; - - if (e->src != bb) - { - error ("verify_flow_info: Basic block %d succ edge is corrupted", - bb->index); - fprintf (stderr, "Predecessor: "); - dump_edge_info (stderr, e, 0); - fprintf (stderr, "\nSuccessor: "); - dump_edge_info (stderr, e, 1); - fprintf (stderr, "\n"); - err = 1; - } - - edge_checksum[e->dest->index + 2] += (size_t) e; - } - if (n_fallthru > 1) - { - error ("Wrong amount of branch edges after unconditional jump %i", bb->index); - err = 1; - } - - for (e = bb->pred; e; e = e->pred_next) - { - if (e->dest != bb) - { - error ("basic block %d pred edge is corrupted", bb->index); - fputs ("Predecessor: ", stderr); - dump_edge_info (stderr, e, 0); - fputs ("\nSuccessor: ", stderr); - dump_edge_info (stderr, e, 1); - fputc ('\n', stderr); - err = 1; - } - edge_checksum[e->dest->index + 2] -= (size_t) e; - } - } - - /* Complete edge checksumming for ENTRY and EXIT. */ - { - edge e; - - for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next) - edge_checksum[e->dest->index + 2] += (size_t) e; - - for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next) - edge_checksum[e->dest->index + 2] -= (size_t) e; - } - - FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb) - if (edge_checksum[bb->index + 2]) - { - error ("basic block %i edge lists are corrupted", bb->index); - err = 1; - } - - num_bb_notes = 0; - last_bb_seen = ENTRY_BLOCK_PTR; - - /* Clean up. */ - free (last_visited); - free (edge_checksum); - err |= cfg_hooks->cfgh_verify_flow_info (); - if (err) - internal_error ("verify_flow_info failed"); -} - -/* Print out one basic block with live information at start and end. */ - -void -dump_bb (basic_block bb, FILE *outf) -{ - edge e; - - fprintf (outf, ";; Basic block %d, loop depth %d, count ", - bb->index, bb->loop_depth); - fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count); - putc ('\n', outf); - - cfg_hooks->dump_bb (bb, outf); - - fputs (";; Successors: ", outf); - for (e = bb->succ; e; e = e->succ_next) - dump_edge_info (outf, e, 1); - putc ('\n', outf); -} - void debug_bb (basic_block bb) { - dump_bb (bb, stderr); + dump_bb (bb, stderr, 0); } basic_block debug_bb_n (int n) { basic_block bb = BASIC_BLOCK (n); - dump_bb (bb, stderr); + dump_bb (bb, stderr, 0); return bb; }