summaryrefslogtreecommitdiff
path: root/gcc/cfg.c
diff options
context:
space:
mode:
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-08 10:06:14 +0000
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-08 10:06:14 +0000
commit4a020a8c3dfec7d26c2e1f9c55286390c5fad76d (patch)
tree6449db5e8557f01213c64b681cc559f5835d3636 /gcc/cfg.c
parent50a8e74cf0f8c34ef9e6023e6114d044b20a588b (diff)
downloadgcc-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.c272
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);