diff options
author | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-08 10:06:14 +0000 |
---|---|---|
committer | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-08 10:06:14 +0000 |
commit | 4a020a8c3dfec7d26c2e1f9c55286390c5fad76d (patch) | |
tree | 6449db5e8557f01213c64b681cc559f5835d3636 /gcc/cfg.c | |
parent | 50a8e74cf0f8c34ef9e6023e6114d044b20a588b (diff) | |
download | gcc-4a020a8c3dfec7d26c2e1f9c55286390c5fad76d.tar.gz |
gcc/
* basic-block.h: Re-group most prototypes per file.
(struct edge_list): Remove num_blocks field.
(dump_bb_info): Adjust prototypes.
(dump_reg_info): Move prototype to regs.h.
* function.h: Do not include tree.h.
Include vec.h, vecir.h, input.h and machmode.h to compensate.
(function_name): New prototype.
* gimple.h: Include tree.h to compensate for basic-block.h change.
* langhooks.h: Note that tree.h is only necessary for enum tree_code.
* regs.h (dump_reg_info): Prototype here.
* regset.h: Adjust file reference in comment.
(debug_regset): Remove prototype.
* rtl.h: Include flags.h for flag_var_tracking_assignments.
(MAY_HAVE_DEBUG_INSNS): Define as flag_var_tracking_assignments
instead of no-longer-available tree.h's MAY_HAVE_DEBUG_STMTS.
(dump_reg_info, dump_flow_info): Remove prototypes.
* bb-reorder.c (set_edge_can_fallthru_flag): Move from cfganal.c
to here, the only user. Make static.
(reorder_basic_blocks): Call dump_reg_info before dump_flow_info.
* cfg.c: Do not include tm.h, tree.h, rtl.h, hard-reg-set.h, regs.h,
flags.h, function.h, except.h, diagnostic-core.h, tm_p.h, timevar.h,
tree-pass.h, cfgloop.h, and tree-flow.h.
Include basic-block.h, the first header I'd expect to be included.
(reg_obstack): Move to df-core.c.
(free_edge): Remove bogus ATTRIBUTE_UNUSED.
(remove_edge_raw): Do not call tree-ssa's redirect_edge_var_map_clear.
(redirect_edge_succ_nodup): Move to cfghooks.c.
(dump_regset, debug_regset): Move to df-core.c.
(dump_bb_info): Move to cfgrtl.c.
(dump_reg_info): Move to regstat.c.
(dump_flow_info): Move to cfgrtl.c.
(debug_flow_info): Likewise.
(dump_edge_info): Do not look at cfun, a CFG without cfun is nonsense.
* cfganal.c: Do not include tm.h, rtl.h, obstack.h, hard-reg-set.h,
insn-config.h, recog.h, diagnostic-core.h, tm_p.h, and cfgloop.h.
(flow_active_insn_p, forwarder_block_p, can_fallthru,
could_fall_through): Move to cfgrtl.c.
(set_edge_can_fallthru_flag): Moved to bb-reorder.c.
(create_edge_list): Do not set edge_list's removed num_blocks.
(print_edge_list): Look at n_basic_blocks instead of num_blocks.
(flow_nodes_print): Remove.
(flow_edge_list_print): Remove.
(inverted_post_order_compute): Use FOR_ALL_BB.
*cfgrtl.c (dump_flow_info): Moved from cfg.c.
Do not call dump_reg_info.
(debug_flow_info): Moved from cfg.c
(dump_bb_info): Moved from cfg.c. Take 'verbose' argument
to avoid looking at TDF_* flags from tree-pass.h.
(flow_active_insn_p, forwarder_block_p, can_fallthru,
could_fall_through): Moved from cfganal.c.
(print_rtl_with_bb): Adjust dump_bb_info calls.
* cfghooks.c (redirect_edge_succ_nodup): Moved from cfg.c.
(remove_edge): Call redirect_edge_var_map_clear if IR_GIMPLE.
(cfgcleanup.c): Look at MAY_HAVE_DEBUG_INSNS, not MAY_HAVE_DEBUG_STMTS.
* cselib.c: Include tree.h with a FIXME.
* df-core.c (reg_obstack): Moved from cfg.c.
(dump_regset): Likewise.
(debug_regset): Likewise. Make a DEBUG_FUNCTION.
* final.c (compute_alignments): Call dump_reg_info before
dump_flow_info.
* function.c (function_name): New function.
(current_function_name): Use it.
* ifcvt.c (rest_of_handle_if_conversion): Call dump_reg_info before
dump_flow_info.
* ira-conflicts.c: Include tree.h with a note.
* regstat.c (dump_reg_info): Moved here from cfg.c.
* loop-init.c: Include regs.h instead of hard-reg-set.h.
(rtl_loop_init): Call dump_reg_info before dump_flow_info.
(rtl_loop_done): Likewise.
* mcf.c: Include tree.h before langhooks.h.
* predict.c (maybe_hot_count_p): Assert we have cfun.
(probably_never_executed_bb_p): Likewise.
* profile.c (compute_branch_probabilities): Use gimple_dump_cfg
instead of dump_flow_info.
* sched-deps.c: Include tree.h with a FIXME.
(call_may_noreturn_p): Add FIXME note why this function has to
look at function decls instead of function decl flags.
* sched-vis.c: Include tree.h with a FIXME.
(print_rtl_slim): Adjust dump_bb_info uses.
* statistics.c (statistics_fini_pass_2): Use current_function_name
to avoid including tree.h.
(statistics_counter_event): Use function_name for the same reason.
(statistics_histogram_event): Likewise.
* tracer.c (tracer): Remove bogus gcc_assert. Use brief_dump_cfg
instead of dump_flow_info.
* var-tracking.c (variable_tracking_main_1): Call dump_reg_info
before dump_flow_info.
* doc/cfg.texi: Update CFG documentation.
* Makefile.in (RTL_H): Depend on FLAGS_H.
(GIMPLE_H): Depend on TREE_H.
(FUNCTION_H): Depend on VEC_H, vecir.h, INPUT_H and MACHMODE_H,
but no longer on TREE_H.
(C_COMMON_H): Depend on TREE_H.
(cselib.o, cse.o, cfganal.o, loop-init.o, ira-conflicts.o,
sched-deps.o, sched-vis.o): Fixup dependencies.
c-family/
* c-common.h: Include tree.h.
cp/
* decl.c (cp_finish_decl): Add FIXME at add_local_decl call site.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189359 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfg.c')
-rw-r--r-- | gcc/cfg.c | 272 |
1 files changed, 11 insertions, 261 deletions
diff --git a/gcc/cfg.c b/gcc/cfg.c index 667e0977b4f..08b34dbb567 100644 --- a/gcc/cfg.c +++ b/gcc/cfg.c @@ -43,37 +43,22 @@ along with GCC; see the file COPYING3. If not see verify_flow_info - Dumping and debugging print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n + + TODO: Document these "Available functionality" functions in the files + that implement them. */ #include "config.h" #include "system.h" #include "coretypes.h" -#include "tm.h" -#include "tree.h" -#include "rtl.h" -#include "hard-reg-set.h" -#include "regs.h" -#include "flags.h" -#include "function.h" -#include "except.h" -#include "diagnostic-core.h" -#include "tm_p.h" #include "obstack.h" -#include "timevar.h" -#include "tree-pass.h" #include "ggc.h" #include "hashtab.h" #include "alloc-pool.h" +#include "basic-block.h" #include "df.h" -#include "cfgloop.h" -#include "tree-flow.h" - -/* The obstack on which the flow graph components are allocated. */ - -struct bitmap_obstack reg_obstack; +#include "cfgloop.h" /* FIXME: For struct loop. */ -void debug_flow_info (void); -static void free_edge (edge); #define RDIV(X,Y) (((X) + (Y) / 2) / (Y)) @@ -98,10 +83,10 @@ init_flow (struct function *the_fun) } /* Helper function for remove_edge and clear_edges. Frees edge structure - without actually unlinking it from the pred/succ lists. */ + without actually removing it from the pred/succ arrays. */ static void -free_edge (edge e ATTRIBUTE_UNUSED) +free_edge (edge e) { n_edges--; ggc_free (e); @@ -363,9 +348,6 @@ remove_edge_raw (edge e) disconnect_src (e); disconnect_dest (e); - /* This is probably not needed, but it doesn't hurt. */ - redirect_edge_var_map_clear (e); - free_edge (e); } @@ -386,31 +368,6 @@ redirect_edge_succ (edge e, basic_block new_succ) execute_on_growing_pred (e); } -/* Like previous but avoid possible duplicate edge. */ - -edge -redirect_edge_succ_nodup (edge e, basic_block new_succ) -{ - edge s; - - s = find_edge (e->src, new_succ); - if (s && s != e) - { - s->flags |= e->flags; - s->probability += e->probability; - if (s->probability > REG_BR_PROB_BASE) - s->probability = REG_BR_PROB_BASE; - s->count += e->count; - redirect_edge_var_map_dup (s, e); - remove_edge (e); - e = s; - } - else - redirect_edge_succ (e, new_succ); - - return e; -} - /* Redirect an edge's predecessor from one block to another. */ void @@ -485,222 +442,15 @@ check_bb_profile (basic_block bb, FILE * file) } } -/* Write information about registers and basic blocks into FILE. - This is part of making a debugging dump. */ - -void -dump_regset (regset r, FILE *outf) -{ - unsigned i; - reg_set_iterator rsi; - - if (r == NULL) - { - fputs (" (nil)", outf); - return; - } - - EXECUTE_IF_SET_IN_REG_SET (r, 0, i, rsi) - { - fprintf (outf, " %d", i); - if (i < FIRST_PSEUDO_REGISTER) - fprintf (outf, " [%s]", - reg_names[i]); - } -} - -/* Print a human-readable representation of R on the standard error - stream. This function is designed to be used from within the - debugger. */ - -DEBUG_FUNCTION void -debug_regset (regset r) -{ - dump_regset (r, stderr); - putc ('\n', stderr); -} - -/* Emit basic block information for BB. HEADER is true if the user wants - the generic information and the predecessors, FOOTER is true if they want - the successors. FLAGS is the dump flags of interest; TDF_DETAILS emit - global register liveness information. PREFIX is put in front of every - line. The output is emitted to FILE. */ -void -dump_bb_info (basic_block bb, bool header, bool footer, int flags, - const char *prefix, FILE *file) -{ - edge e; - edge_iterator ei; - - if (header) - { - fprintf (file, "\n%sBasic block %d ", prefix, bb->index); - if (bb->prev_bb) - fprintf (file, ", prev %d", bb->prev_bb->index); - if (bb->next_bb) - fprintf (file, ", next %d", bb->next_bb->index); - fprintf (file, ", loop_depth %d, count ", bb->loop_depth); - fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count); - fprintf (file, ", freq %i", bb->frequency); - /* Both maybe_hot_bb_p & probably_never_executed_bb_p functions - crash without cfun. */ - if (cfun && maybe_hot_bb_p (bb)) - fputs (", maybe hot", file); - if (cfun && probably_never_executed_bb_p (bb)) - fputs (", probably never executed", file); - if (bb->flags) - { - static const char * const bits[] = { - "new", "reachable", "irr_loop", "superblock", "disable_sched", - "hot_partition", "cold_partition", "duplicated", - "non_local_goto_target", "rtl", "forwarder", "nonthreadable", - "modified" - }; - unsigned int flags; - - fputs (", flags:", file); - for (flags = bb->flags; flags ; flags &= flags - 1) - { - unsigned i = ctz_hwi (flags); - if (i < ARRAY_SIZE (bits)) - fprintf (file, " %s", bits[i]); - else - fprintf (file, " <%d>", i); - } - } - fputs (".\n", file); - - fprintf (file, "%sPredecessors: ", prefix); - FOR_EACH_EDGE (e, ei, bb->preds) - dump_edge_info (file, e, 0); - - if ((flags & TDF_DETAILS) - && (bb->flags & BB_RTL) - && df) - { - putc ('\n', file); - df_dump_top (bb, file); - } - } - - if (footer) - { - fprintf (file, "\n%sSuccessors: ", prefix); - FOR_EACH_EDGE (e, ei, bb->succs) - dump_edge_info (file, e, 1); - - if ((flags & TDF_DETAILS) - && (bb->flags & BB_RTL) - && df) - { - putc ('\n', file); - df_dump_bottom (bb, file); - } - } - - putc ('\n', file); -} - -/* Dump the register info to FILE. */ - -void -dump_reg_info (FILE *file) -{ - unsigned int i, max = max_reg_num (); - if (reload_completed) - return; - - if (reg_info_p_size < max) - max = reg_info_p_size; - - fprintf (file, "%d registers.\n", max); - for (i = FIRST_PSEUDO_REGISTER; i < max; i++) - { - enum reg_class rclass, altclass; - - if (regstat_n_sets_and_refs) - fprintf (file, "\nRegister %d used %d times across %d insns", - i, REG_N_REFS (i), REG_LIVE_LENGTH (i)); - else if (df) - fprintf (file, "\nRegister %d used %d times across %d insns", - i, DF_REG_USE_COUNT (i) + DF_REG_DEF_COUNT (i), REG_LIVE_LENGTH (i)); - - if (REG_BASIC_BLOCK (i) >= NUM_FIXED_BLOCKS) - fprintf (file, " in block %d", REG_BASIC_BLOCK (i)); - if (regstat_n_sets_and_refs) - fprintf (file, "; set %d time%s", REG_N_SETS (i), - (REG_N_SETS (i) == 1) ? "" : "s"); - else if (df) - fprintf (file, "; set %d time%s", DF_REG_DEF_COUNT (i), - (DF_REG_DEF_COUNT (i) == 1) ? "" : "s"); - if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i])) - fputs ("; user var", file); - if (REG_N_DEATHS (i) != 1) - fprintf (file, "; dies in %d places", REG_N_DEATHS (i)); - if (REG_N_CALLS_CROSSED (i) == 1) - fputs ("; crosses 1 call", file); - else if (REG_N_CALLS_CROSSED (i)) - fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i)); - if (REG_FREQ_CALLS_CROSSED (i)) - fprintf (file, "; crosses call with %d frequency", REG_FREQ_CALLS_CROSSED (i)); - if (regno_reg_rtx[i] != NULL - && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD) - fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i)); - - rclass = reg_preferred_class (i); - altclass = reg_alternate_class (i); - if (rclass != GENERAL_REGS || altclass != ALL_REGS) - { - if (altclass == ALL_REGS || rclass == ALL_REGS) - fprintf (file, "; pref %s", reg_class_names[(int) rclass]); - else if (altclass == NO_REGS) - fprintf (file, "; %s or none", reg_class_names[(int) rclass]); - else - fprintf (file, "; pref %s, else %s", - reg_class_names[(int) rclass], - reg_class_names[(int) altclass]); - } - - if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i])) - fputs ("; pointer", file); - fputs (".\n", file); - } -} - - -void -dump_flow_info (FILE *file, int flags) -{ - basic_block bb; - - /* There are no pseudo registers after reload. Don't dump them. */ - if (reg_info_p_size && (flags & TDF_DETAILS) != 0) - dump_reg_info (file); - - fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges); - FOR_ALL_BB (bb) - { - dump_bb_info (bb, true, true, flags, "", file); - check_bb_profile (bb, file); - } - - putc ('\n', file); -} - -DEBUG_FUNCTION void -debug_flow_info (void) -{ - dump_flow_info (stderr, TDF_DETAILS); -} - void dump_edge_info (FILE *file, edge e, int do_succ) { basic_block side = (do_succ ? e->dest : e->src); - /* both ENTRY_BLOCK_PTR & EXIT_BLOCK_PTR depend upon cfun. */ - if (cfun && side == ENTRY_BLOCK_PTR) + /* ENTRY_BLOCK_PTR/EXIT_BLOCK_PTR depend on cfun. + Compare against ENTRY_BLOCK/EXIT_BLOCK to avoid that dependency. */ + if (side->index == ENTRY_BLOCK) fputs (" ENTRY", file); - else if (cfun && side == EXIT_BLOCK_PTR) + else if (side->index == EXIT_BLOCK) fputs (" EXIT", file); else fprintf (file, " %d", side->index); |