Commit 532aafad by Steven Bosscher

basic-block.h: Re-group most prototypes per file.

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.

From-SVN: r189359
parent 79bdca32
2012-07-08 Steven Bosscher <steven@gcc.gnu.org>
* 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.
2012-07-08 Steven Bosscher <steven@gcc.gnu.org>
* alias.h: Do not include coretypes.h in header files.
* cppbuiltin.h: Likewise.
* double-int.h: Likewise.
......
......@@ -859,7 +859,7 @@ RTL_BASE_H = coretypes.h rtl.h rtl.def $(MACHMODE_H) reg-notes.def \
insn-notes.def $(INPUT_H) $(REAL_H) statistics.h $(VEC_H) \
$(FIXED_VALUE_H) alias.h $(HASHTAB_H)
FIXED_VALUE_H = fixed-value.h $(MACHMODE_H) double-int.h
RTL_H = $(RTL_BASE_H) genrtl.h vecir.h
RTL_H = $(RTL_BASE_H) $(FLAGS_H) genrtl.h vecir.h
RTL_ERROR_H = rtl-error.h $(RTL_H) $(DIAGNOSTIC_CORE_H)
READ_MD_H = $(OBSTACK_H) $(HASHTAB_H) read-md.h
PARAMS_H = params.h params.def
......@@ -875,7 +875,7 @@ TREE_H = coretypes.h tree.h all-tree.def tree.def c-family/c-common.def \
REGSET_H = regset.h $(BITMAP_H) hard-reg-set.h
BASIC_BLOCK_H = basic-block.h $(PREDICT_H) $(VEC_H) $(FUNCTION_H) cfghooks.h
GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h $(VEC_H) \
vecir.h $(GGC_H) $(BASIC_BLOCK_H) tree-ssa-operands.h \
vecir.h $(GGC_H) $(BASIC_BLOCK_H) $(TREE_H) tree-ssa-operands.h \
tree-ssa-alias.h $(INTERNAL_FN_H)
TRANS_MEM_H = trans-mem.h
GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h
......@@ -886,7 +886,8 @@ ALIAS_H = alias.h
EMIT_RTL_H = emit-rtl.h
FLAGS_H = flags.h flag-types.h $(OPTIONS_H)
OPTIONS_H = options.h flag-types.h $(OPTIONS_H_EXTRA)
FUNCTION_H = function.h $(TREE_H) $(HASHTAB_H) vecprim.h $(TM_H) hard-reg-set.h
FUNCTION_H = function.h $(HASHTAB_H) vecprim.h $(TM_H) hard-reg-set.h \
$(VEC_H) vecir.h $(INPUT_H) $(MACHMODE_H)
EXPR_H = expr.h insn-config.h $(FUNCTION_H) $(RTL_H) $(FLAGS_H) $(TREE_H) $(MACHMODE_H) $(EMIT_RTL_H)
OPTABS_H = optabs.h insn-codes.h
REGS_H = regs.h $(MACHMODE_H) hard-reg-set.h
......@@ -911,7 +912,7 @@ GGC_INTERNAL_H = ggc-internal.h $(GGC_H)
TIMEVAR_H = timevar.h timevar.def
INSN_ATTR_H = insn-attr.h insn-attr-common.h $(INSN_ADDR_H)
INSN_ADDR_H = $(srcdir)/insn-addr.h vecprim.h
C_COMMON_H = c-family/c-common.h c-family/c-common.def \
C_COMMON_H = c-family/c-common.h c-family/c-common.def $(TREE_H) \
$(SPLAY_TREE_H) $(CPPLIB_H) $(GGC_H) $(DIAGNOSTIC_CORE_H)
C_PRAGMA_H = c-family/c-pragma.h $(CPPLIB_H)
C_TREE_H = c-tree.h $(C_COMMON_H) $(DIAGNOSTIC_H)
......@@ -2937,7 +2938,7 @@ cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(RECOG_H) \
$(EMIT_RTL_H) $(DIAGNOSTIC_CORE_H) $(FUNCTION_H) $(TREE_PASS_H) \
cselib.h gt-cselib.h $(GGC_H) $(TM_P_H) $(PARAMS_H) alloc-pool.h \
$(HASHTAB_H) $(TARGET_H) $(BITMAP_H)
$(HASHTAB_H) $(TARGET_H) $(BITMAP_H) $(TREE_H)
cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
hard-reg-set.h $(FLAGS_H) insn-config.h $(RECOG_H) $(EXPR_H) toplev.h $(DIAGNOSTIC_CORE_H) \
$(FUNCTION_H) $(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H) $(TIMEVAR_H) \
......@@ -3076,10 +3077,8 @@ auto-inc-dec.o : auto-inc-dec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(RTL_H) $(TM_P_H) hard-reg-set.h $(BASIC_BLOCK_H) insn-config.h \
$(REGS_H) $(FLAGS_H) $(FUNCTION_H) $(EXCEPT_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) \
$(EXPR_H) $(TIMEVAR_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H)
cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \
$(REGS_H) hard-reg-set.h $(DIAGNOSTIC_CORE_H) $(FUNCTION_H) $(EXCEPT_H) $(GGC_H) \
$(TM_P_H) $(TIMEVAR_H) $(OBSTACK_H) $(TREE_H) alloc-pool.h \
$(HASHTAB_H) $(DF_H) $(CFGLOOP_H) $(TREE_FLOW_H) $(TREE_PASS_H)
cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DIAGNOSTIC_CORE_H) $(GGC_H) \
$(OBSTACK_H) alloc-pool.h $(HASHTAB_H) $(CFGLOOP_H) $(BASIC_BLOCK_H)
cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TIMEVAR_H) toplev.h $(DIAGNOSTIC_CORE_H) $(CFGLOOP_H)
cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
......@@ -3095,10 +3094,8 @@ cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_H) \
insn-config.h $(EXPR_H) \
$(CFGLOOP_H) $(OBSTACK_H) $(TARGET_H) $(TREE_H) \
$(TREE_PASS_H) $(DF_H) $(GGC_H) $(COMMON_TARGET_H) gt-cfgrtl.h
cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h insn-config.h $(RECOG_H) $(TM_P_H) \
$(TIMEVAR_H) $(OBSTACK_H) $(DIAGNOSTIC_CORE_H) vecprim.h sbitmap.h \
$(BITMAP_H) $(CFGLOOP_H)
cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(BASIC_BLOCK_H) \
$(TIMEVAR_H) vecprim.h sbitmap.h $(BITMAP_H)
cfgbuild.o : cfgbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h $(DIAGNOSTIC_CORE_H) \
$(FUNCTION_H) $(EXCEPT_H) $(TIMEVAR_H) $(TREE_H) $(EXPR_H) sbitmap.h
......@@ -3129,7 +3126,7 @@ cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(GGC_H) \
$(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) \
coretypes.h $(TM_H) $(OBSTACK_H) $(TREE_PASS_H) $(TIMEVAR_H) $(FLAGS_H) \
$(DF_H)
$(REGS_H) $(DF_H)
loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
$(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(PARAMS_H) \
$(EXPR_H) coretypes.h $(TM_H) $(OBSTACK_H)
......@@ -3212,7 +3209,7 @@ ira-costs.o: ira-costs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(REGS_H) addresses.h insn-config.h $(RECOG_H) $(DIAGNOSTIC_CORE_H) $(TARGET_H) \
$(PARAMS_H) $(IRA_INT_H) reload.h
ira-conflicts.o: ira-conflicts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
$(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(TREE_H) $(FLAGS_H) \
insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_CORE_H) $(TM_P_H) $(PARAMS_H) \
$(DF_H) sparseset.h addresses.h $(IRA_INT_H)
ira-color.o: ira-color.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
......@@ -3263,7 +3260,7 @@ haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_
sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(FUNCTION_H) $(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) cselib.h \
ira.h $(PARAMS_H) $(TM_P_H) ira.h $(TARGET_H)
ira.h $(PARAMS_H) $(TM_P_H) ira.h $(TARGET_H) $(TREE_H)
sched-rgn.o : sched-rgn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(FUNCTION_H) $(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
......@@ -3275,7 +3272,7 @@ sched-ebb.o : sched-ebb.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(PARAMS_H) $(TARGET_H)
sched-vis.o : sched-vis.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) hard-reg-set.h $(BASIC_BLOCK_H) $(OBSTACK_H) \
$(TREE_PASS_H) $(INSN_ATTR_H)
$(TREE_PASS_H) $(INSN_ATTR_H) $(TREE_H)
sel-sched.o : sel-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_ERROR_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(FUNCTION_H) $(INSN_ATTR_H) $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
......
......@@ -448,10 +448,6 @@ basic_block split_edge_and_insert (edge, rtx);
extern void commit_one_edge_insertion (edge e);
extern void commit_edge_insertions (void);
extern void remove_fake_edges (void);
extern void remove_fake_exit_edges (void);
extern void add_noreturn_fake_exit_edges (void);
extern void connect_infinite_loops_to_exit (void);
extern edge unchecked_make_edge (basic_block, basic_block, int);
extern edge cached_make_edge (sbitmap, basic_block, basic_block, int);
extern edge make_edge (basic_block, basic_block, int);
......@@ -462,15 +458,7 @@ extern edge redirect_edge_succ_nodup (edge, basic_block);
extern void redirect_edge_pred (edge, basic_block);
extern basic_block create_basic_block_structure (rtx, rtx, rtx, basic_block);
extern void clear_bb_flags (void);
extern int post_order_compute (int *, bool, bool);
extern int inverted_post_order_compute (int *);
extern int pre_and_rev_post_order_compute (int *, int *, bool);
extern int dfs_enumerate_from (basic_block, int,
bool (*)(const_basic_block, const void *),
basic_block *, int, const void *);
extern void compute_dominance_frontiers (struct bitmap_head_def *);
extern bitmap compute_idf (bitmap, struct bitmap_head_def *);
extern void dump_bb_info (basic_block, bool, bool, int, const char *, FILE *);
extern void dump_bb_info (basic_block, bool, bool, bool, const char *, FILE *);
extern void dump_edge_info (FILE *, edge, int);
extern void brief_dump_cfg (FILE *);
extern void clear_edges (void);
......@@ -501,9 +489,9 @@ typedef struct ce_if_block
} ce_if_block_t;
/* This structure maintains an edge list vector. */
/* FIXME: Make this a VEC(edge). */
struct edge_list
{
int num_blocks;
int num_edges;
edge *index_to_edge;
};
......@@ -734,13 +722,6 @@ ei_cond (edge_iterator ei, edge *p)
ei_cond ((ITER), &(EDGE)); \
ei_next (&(ITER)))
struct edge_list * create_edge_list (void);
void free_edge_list (struct edge_list *);
void print_edge_list (FILE *, struct edge_list *);
void verify_edge_list (FILE *, struct edge_list *);
int find_edge_index (struct edge_list *, basic_block, basic_block);
edge find_edge (basic_block, basic_block);
#define CLEANUP_EXPENSIVE 1 /* Do relatively expensive optimizations
except for edge forwarding */
#define CLEANUP_CROSSJUMP 2 /* Do crossjumping. */
......@@ -789,6 +770,7 @@ extern bool predictable_edge_p (edge);
extern void init_flow (struct function *);
extern void debug_bb (basic_block);
extern basic_block debug_bb_n (int);
extern void dump_flow_info (FILE *, int);
extern void expunge_block (basic_block);
extern void link_block (basic_block, basic_block);
extern void unlink_block (basic_block);
......@@ -804,11 +786,25 @@ extern void free_aux_for_edges (void);
/* In cfganal.c */
extern void find_unreachable_blocks (void);
extern bool forwarder_block_p (const_basic_block);
extern bool can_fallthru (basic_block, basic_block);
extern bool could_fall_through (basic_block, basic_block);
extern void flow_nodes_print (const char *, const_sbitmap, FILE *);
extern void flow_edge_list_print (const char *, const edge *, int, FILE *);
extern bool mark_dfs_back_edges (void);
struct edge_list * create_edge_list (void);
void free_edge_list (struct edge_list *);
void print_edge_list (FILE *, struct edge_list *);
void verify_edge_list (FILE *, struct edge_list *);
int find_edge_index (struct edge_list *, basic_block, basic_block);
edge find_edge (basic_block, basic_block);
extern void remove_fake_edges (void);
extern void remove_fake_exit_edges (void);
extern void add_noreturn_fake_exit_edges (void);
extern void connect_infinite_loops_to_exit (void);
extern int post_order_compute (int *, bool, bool);
extern int inverted_post_order_compute (int *);
extern int pre_and_rev_post_order_compute (int *, int *, bool);
extern int dfs_enumerate_from (basic_block, int,
bool (*)(const_basic_block, const void *),
basic_block *, int, const void *);
extern void compute_dominance_frontiers (struct bitmap_head_def *);
extern bitmap compute_idf (bitmap, struct bitmap_head_def *);
/* In cfgrtl.c */
extern rtx block_label (basic_block);
......@@ -817,6 +813,8 @@ extern bool purge_all_dead_edges (void);
extern bool purge_dead_edges (basic_block);
extern bool fixup_abnormal_edges (void);
extern basic_block force_nonfallthru_and_redirect (edge, basic_block, rtx);
extern bool forwarder_block_p (const_basic_block);
extern bool can_fallthru (basic_block, basic_block);
/* In cfgbuild.c. */
extern void find_many_sub_basic_blocks (sbitmap);
......@@ -833,8 +831,6 @@ extern int flow_find_head_matching_sequence (basic_block, basic_block,
extern bool delete_unreachable_blocks (void);
extern bool mark_dfs_back_edges (void);
extern void set_edge_can_fallthru_flag (void);
extern void update_br_prob_note (basic_block);
extern bool inside_basic_block_p (const_rtx);
extern bool control_flow_insn_p (const_rtx);
......
......@@ -1384,6 +1384,41 @@ find_rarely_executed_basic_blocks_and_crossing_edges (void)
return crossing_edges;
}
/* Set the flag EDGE_CAN_FALLTHRU for edges that can be fallthru. */
static void
set_edge_can_fallthru_flag (void)
{
basic_block bb;
FOR_EACH_BB (bb)
{
edge e;
edge_iterator ei;
FOR_EACH_EDGE (e, ei, bb->succs)
{
e->flags &= ~EDGE_CAN_FALLTHRU;
/* The FALLTHRU edge is also CAN_FALLTHRU edge. */
if (e->flags & EDGE_FALLTHRU)
e->flags |= EDGE_CAN_FALLTHRU;
}
/* If the BB ends with an invertible condjump all (2) edges are
CAN_FALLTHRU edges. */
if (EDGE_COUNT (bb->succs) != 2)
continue;
if (!any_condjump_p (BB_END (bb)))
continue;
if (!invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0))
continue;
invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0);
EDGE_SUCC (bb, 0)->flags |= EDGE_CAN_FALLTHRU;
EDGE_SUCC (bb, 1)->flags |= EDGE_CAN_FALLTHRU;
}
}
/* If any destination of a crossing edge does not have a label, add label;
Convert any easy fall-through crossing edges to unconditional jumps. */
......@@ -1959,7 +1994,11 @@ reorder_basic_blocks (void)
relink_block_chain (/*stay_in_cfglayout_mode=*/true);
if (dump_file)
dump_flow_info (dump_file, dump_flags);
{
if (dump_flags & TDF_DETAILS)
dump_reg_info (dump_file);
dump_flow_info (dump_file, dump_flags);
}
if (flag_reorder_blocks_and_partition)
verify_hot_cold_block_grouping ();
......
2012-07-08 Steven Bosscher <steven@gcc.gnu.org>
* c-common.h: Include tree.h.
2012-07-02 Jason Merrill <jason@redhat.com>
PR c++/53524
......
......@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "splay-tree.h"
#include "cpplib.h"
#include "ggc.h"
#include "tree.h"
/* In order for the format checking to accept the C frontend
diagnostic framework extensions, you must include this file before
......
......@@ -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);
......
/* Control flow graph analysis code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2010
Free Software Foundation, Inc.
Copyright (C) 1987-2012 Free Software Foundation, Inc.
This file is part of GCC.
......@@ -20,24 +18,16 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* This file contains various simple utilities to analyze the CFG. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "obstack.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "insn-config.h"
#include "recog.h"
#include "diagnostic-core.h"
#include "tm_p.h"
#include "vec.h"
#include "vecprim.h"
#include "bitmap.h"
#include "sbitmap.h"
#include "timevar.h"
#include "cfgloop.h"
/* Store the data structures necessary for depth-first search. */
struct depth_first_search_dsS {
......@@ -59,106 +49,6 @@ static void flow_dfs_compute_reverse_add_bb (depth_first_search_ds,
static basic_block flow_dfs_compute_reverse_execute (depth_first_search_ds,
basic_block);
static void flow_dfs_compute_reverse_finish (depth_first_search_ds);
static bool flow_active_insn_p (const_rtx);
/* Like active_insn_p, except keep the return value clobber around
even after reload. */
static bool
flow_active_insn_p (const_rtx insn)
{
if (active_insn_p (insn))
return true;
/* A clobber of the function return value exists for buggy
programs that fail to return a value. Its effect is to
keep the return value from being live across the entire
function. If we allow it to be skipped, we introduce the
possibility for register lifetime confusion. */
if (GET_CODE (PATTERN (insn)) == CLOBBER
&& REG_P (XEXP (PATTERN (insn), 0))
&& REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))
return true;
return false;
}
/* Return true if the block has no effect and only forwards control flow to
its single destination. */
bool
forwarder_block_p (const_basic_block bb)
{
rtx insn;
if (bb == EXIT_BLOCK_PTR || bb == ENTRY_BLOCK_PTR
|| !single_succ_p (bb))
return false;
/* Protect loop latches, headers and preheaders. */
if (current_loops)
{
basic_block dest;
if (bb->loop_father->header == bb)
return false;
dest = EDGE_SUCC (bb, 0)->dest;
if (dest->loop_father->header == dest)
return false;
}
for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
if (INSN_P (insn) && flow_active_insn_p (insn))
return false;
return (!INSN_P (insn)
|| (JUMP_P (insn) && simplejump_p (insn))
|| !flow_active_insn_p (insn));
}
/* Return nonzero if we can reach target from src by falling through. */
bool
can_fallthru (basic_block src, basic_block target)
{
rtx insn = BB_END (src);
rtx insn2;
edge e;
edge_iterator ei;
if (target == EXIT_BLOCK_PTR)
return true;
if (src->next_bb != target)
return 0;
FOR_EACH_EDGE (e, ei, src->succs)
if (e->dest == EXIT_BLOCK_PTR
&& e->flags & EDGE_FALLTHRU)
return 0;
insn2 = BB_HEAD (target);
if (insn2 && !active_insn_p (insn2))
insn2 = next_active_insn (insn2);
/* ??? Later we may add code to move jump tables offline. */
return next_active_insn (insn) == insn2;
}
/* Return nonzero if we could reach target from src by falling through,
if the target was made adjacent. If we already have a fall-through
edge to the exit block, we can't do that. */
bool
could_fall_through (basic_block src, basic_block target)
{
edge e;
edge_iterator ei;
if (target == EXIT_BLOCK_PTR)
return true;
FOR_EACH_EDGE (e, ei, src->succs)
if (e->dest == EXIT_BLOCK_PTR
&& e->flags & EDGE_FALLTHRU)
return 0;
return true;
}
/* Mark the back edges in DFS traversal.
Return nonzero if a loop (natural or otherwise) is present.
......@@ -252,41 +142,6 @@ mark_dfs_back_edges (void)
return found;
}
/* Set the flag EDGE_CAN_FALLTHRU for edges that can be fallthru. */
void
set_edge_can_fallthru_flag (void)
{
basic_block bb;
FOR_EACH_BB (bb)
{
edge e;
edge_iterator ei;
FOR_EACH_EDGE (e, ei, bb->succs)
{
e->flags &= ~EDGE_CAN_FALLTHRU;
/* The FALLTHRU edge is also CAN_FALLTHRU edge. */
if (e->flags & EDGE_FALLTHRU)
e->flags |= EDGE_CAN_FALLTHRU;
}
/* If the BB ends with an invertible condjump all (2) edges are
CAN_FALLTHRU edges. */
if (EDGE_COUNT (bb->succs) != 2)
continue;
if (!any_condjump_p (BB_END (bb)))
continue;
if (!invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0))
continue;
invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0);
EDGE_SUCC (bb, 0)->flags |= EDGE_CAN_FALLTHRU;
EDGE_SUCC (bb, 1)->flags |= EDGE_CAN_FALLTHRU;
}
}
/* Find unreachable blocks. An unreachable block will have 0 in
the reachable bit in block->flags. A nonzero value indicates the
block is reachable. */
......@@ -357,23 +212,18 @@ create_edge_list (void)
struct edge_list *elist;
edge e;
int num_edges;
int block_count;
basic_block bb;
edge_iterator ei;
block_count = n_basic_blocks; /* Include the entry and exit blocks. */
num_edges = 0;
/* Determine the number of edges in the flow graph by counting successor
edges on each basic block. */
num_edges = 0;
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
{
num_edges += EDGE_COUNT (bb->succs);
}
elist = XNEW (struct edge_list);
elist->num_blocks = block_count;
elist->num_edges = num_edges;
elist->index_to_edge = XNEWVEC (edge, num_edges);
......@@ -407,7 +257,7 @@ print_edge_list (FILE *f, struct edge_list *elist)
int x;
fprintf (f, "Compressed edge list, %d BBs + entry & exit, and %d edges\n",
elist->num_blocks, elist->num_edges);
n_basic_blocks, elist->num_edges);
for (x = 0; x < elist->num_edges; x++)
{
......@@ -459,7 +309,7 @@ verify_edge_list (FILE *f, struct edge_list *elist)
}
/* We've verified that all the edges are in the list, now lets make sure
there are no spurious edges in the list. */
there are no spurious edges in the list. This is an expensive check! */
FOR_BB_BETWEEN (p, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
FOR_BB_BETWEEN (s, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
......@@ -531,42 +381,6 @@ find_edge_index (struct edge_list *edge_list, basic_block pred, basic_block succ
return (EDGE_INDEX_NO_EDGE);
}
/* Dump the list of basic blocks in the bitmap NODES. */
void
flow_nodes_print (const char *str, const_sbitmap nodes, FILE *file)
{
unsigned int node = 0;
sbitmap_iterator sbi;
if (! nodes)
return;
fprintf (file, "%s { ", str);
EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, node, sbi)
fprintf (file, "%d ", node);
fputs ("}\n", file);
}
/* Dump the list of edges in the array EDGE_LIST. */
void
flow_edge_list_print (const char *str, const edge *edge_list, int num_edges, FILE *file)
{
int i;
if (! edge_list)
return;
fprintf (file, "%s { ", str);
for (i = 0; i < num_edges; i++)
fprintf (file, "%d->%d ", edge_list[i]->src->index,
edge_list[i]->dest->index);
fputs ("}\n", file);
}
/* This routine will remove any fake predecessor edges for a basic block.
When the edge is removed, it is also removed from whatever successor
......@@ -843,7 +657,7 @@ inverted_post_order_compute (int *post_order)
sbitmap_zero (visited);
/* Put all blocks that have no successor into the initial work list. */
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
FOR_ALL_BB (bb)
if (EDGE_COUNT (bb->succs) == 0)
{
/* Push the initial edge on to the stack. */
......
......@@ -2797,7 +2797,7 @@ delete_unreachable_blocks (void)
have dominators information, walking blocks backward gets us a
better chance of retaining most debug information than
otherwise. */
if (MAY_HAVE_DEBUG_STMTS && current_ir_type () == IR_GIMPLE
if (MAY_HAVE_DEBUG_INSNS && current_ir_type () == IR_GIMPLE
&& dom_info_available_p (CDI_DOMINATORS))
{
for (b = EXIT_BLOCK_PTR->prev_bb; b != ENTRY_BLOCK_PTR; b = prev_bb)
......
......@@ -377,9 +377,40 @@ remove_edge (edge e)
if (current_loops != NULL)
rescan_loop_exit (e, false, true);
/* This is probably not needed, but it doesn't hurt. */
/* FIXME: This should be called via a remove_edge hook. */
if (current_ir_type () == IR_GIMPLE)
redirect_edge_var_map_clear (e);
remove_edge_raw (e);
}
/* Like redirect_edge_succ 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;
/* FIXME: This should be called via a hook and only for IR_GIMPLE. */
redirect_edge_var_map_dup (s, e);
remove_edge (e);
e = s;
}
else
redirect_edge_succ (e, new_succ);
return e;
}
/* Redirect the edge E to basic block DEST even if it requires creating
of a new basic block; then it returns the newly created basic block.
Aborts when redirection is impossible. */
......
......@@ -517,6 +517,107 @@ update_bb_for_insn (basic_block bb)
}
/* Like active_insn_p, except keep the return value clobber around
even after reload. */
static bool
flow_active_insn_p (const_rtx insn)
{
if (active_insn_p (insn))
return true;
/* A clobber of the function return value exists for buggy
programs that fail to return a value. Its effect is to
keep the return value from being live across the entire
function. If we allow it to be skipped, we introduce the
possibility for register lifetime confusion. */
if (GET_CODE (PATTERN (insn)) == CLOBBER
&& REG_P (XEXP (PATTERN (insn), 0))
&& REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))
return true;
return false;
}
/* Return true if the block has no effect and only forwards control flow to
its single destination. */
/* FIXME: Make this a cfg hook. */
bool
forwarder_block_p (const_basic_block bb)
{
rtx insn;
if (bb == EXIT_BLOCK_PTR || bb == ENTRY_BLOCK_PTR
|| !single_succ_p (bb))
return false;
/* Protect loop latches, headers and preheaders. */
if (current_loops)
{
basic_block dest;
if (bb->loop_father->header == bb)
return false;
dest = EDGE_SUCC (bb, 0)->dest;
if (dest->loop_father->header == dest)
return false;
}
for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
if (INSN_P (insn) && flow_active_insn_p (insn))
return false;
return (!INSN_P (insn)
|| (JUMP_P (insn) && simplejump_p (insn))
|| !flow_active_insn_p (insn));
}
/* Return nonzero if we can reach target from src by falling through. */
/* FIXME: Make this a cfg hook. */
bool
can_fallthru (basic_block src, basic_block target)
{
rtx insn = BB_END (src);
rtx insn2;
edge e;
edge_iterator ei;
if (target == EXIT_BLOCK_PTR)
return true;
if (src->next_bb != target)
return 0;
FOR_EACH_EDGE (e, ei, src->succs)
if (e->dest == EXIT_BLOCK_PTR
&& e->flags & EDGE_FALLTHRU)
return 0;
insn2 = BB_HEAD (target);
if (insn2 && !active_insn_p (insn2))
insn2 = next_active_insn (insn2);
/* ??? Later we may add code to move jump tables offline. */
return next_active_insn (insn) == insn2;
}
/* Return nonzero if we could reach target from src by falling through,
if the target was made adjacent. If we already have a fall-through
edge to the exit block, we can't do that. */
static bool
could_fall_through (basic_block src, basic_block target)
{
edge e;
edge_iterator ei;
if (target == EXIT_BLOCK_PTR)
return true;
FOR_EACH_EDGE (e, ei, src->succs)
if (e->dest == EXIT_BLOCK_PTR
&& e->flags & EDGE_FALLTHRU)
return 0;
return true;
}
/* Return the NOTE_INSN_BASIC_BLOCK of BB. */
rtx
bb_note (basic_block bb)
......@@ -1811,10 +1912,11 @@ print_rtl_with_bb (FILE *outf, const_rtx rtx_first)
for (tmp_rtx = rtx_first; NULL != tmp_rtx; tmp_rtx = NEXT_INSN (tmp_rtx))
{
int did_output;
bool verbose = ((dump_flags & TDF_DETAILS) != 0);
bb = start[INSN_UID (tmp_rtx)];
if (bb != NULL)
dump_bb_info (bb, true, false, dump_flags, ";; ", outf);
dump_bb_info (bb, true, false, verbose, ";; ", outf);
if (in_bb_p[INSN_UID (tmp_rtx)] == NOT_IN_BB
&& !NOTE_P (tmp_rtx)
......@@ -1827,7 +1929,7 @@ print_rtl_with_bb (FILE *outf, const_rtx rtx_first)
bb = end[INSN_UID (tmp_rtx)];
if (bb != NULL)
dump_bb_info (bb, false, true, dump_flags, ";; ", outf);
dump_bb_info (bb, false, true, verbose, ";; ", outf);
if (did_output)
putc ('\n', outf);
}
......@@ -1846,6 +1948,115 @@ print_rtl_with_bb (FILE *outf, const_rtx rtx_first)
}
}
/* 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. If VERBOSE is true, emit global register liveness
information. PREFIX is put in front of every line. The output is emitted
to FILE. This function should only be called by RTL CFG users. */
/* FIXME: Dumping of the basic block shared info (index, prev, next, etc.)
is done here and also in dump_bb_header (but to a pretty-printer buffer).
This should be re-factored to give similar dumps for RTL and GIMPLE. */
void
dump_bb_info (basic_block bb, bool header, bool footer, bool verbose,
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);
if (maybe_hot_bb_p (bb))
fputs (", maybe hot", file);
if (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 (verbose
&& (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 (verbose
&& (bb->flags & BB_RTL)
&& df)
{
putc ('\n', file);
df_dump_bottom (bb, file);
}
}
putc ('\n', file);
}
void
dump_flow_info (FILE *file, int flags)
{
basic_block bb;
bool verbose = ((flags & TDF_DETAILS) != 0);
fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
FOR_ALL_BB (bb)
{
dump_bb_info (bb, true, true, verbose, "", file);
check_bb_profile (bb, file);
}
putc ('\n', file);
}
void debug_flow_info (void);
DEBUG_FUNCTION void
debug_flow_info (void)
{
dump_flow_info (stderr, TDF_DETAILS);
}
/* Update the branch probability of BB if a REG_BR_PROB is present. */
void
update_br_prob_note (basic_block bb)
{
......@@ -2893,7 +3104,13 @@ struct rtl_opt_pass pass_outof_cfg_layout_mode =
some transformations while in cfglayout mode. The required sequence
of the basic blocks is in a linked list along the bb->aux field.
This functions re-links the basic block prev_bb and next_bb pointers
accordingly, and it compacts and renumbers the blocks. */
accordingly, and it compacts and renumbers the blocks.
FIXME: This currently works only for RTL, but the only RTL-specific
bits are the STAY_IN_CFGLAYOUT_MODE bits. The tracer pass was moved
to GIMPLE a long time ago, but it doesn't relink the basic block
chain. It could do that (to give better initial RTL) if this function
is made IR-agnostic (and moved to cfganal.c or cfg.c while at it). */
void
relink_block_chain (bool stay_in_cfglayout_mode)
......
2012-07-08 Steven Bosscher <steven@gcc.gnu.org>
* decl.c (cp_finish_decl): Add FIXME at add_local_decl call site.
2012-07-06 Jason Merrill <jason@redhat.com>
PR c++/53862
......
......@@ -6190,7 +6190,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
/* Normally local_decls is populated during GIMPLE lowering,
but [cd]tors are never actually compiled directly. We need
to put statics on the list so we can deal with the label
address extension. */
address extension. FIXME. */
add_local_decl (cfun, decl);
}
......
......@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "rtl.h"
#include "tree.h"/* FIXME: For hashing DEBUG_EXPR & friends. */
#include "tm_p.h"
#include "regs.h"
#include "hard-reg-set.h"
......
......@@ -403,6 +403,9 @@ static void df_clear_bb_info (struct dataflow *, unsigned int);
static void df_set_clean_cfg (void);
#endif
/* The obstack on which regsets are allocated. */
struct bitmap_obstack reg_obstack;
/* An obstack for bitmap not related to specific dataflow problems.
This obstack should e.g. be used for bitmaps with a short life time
such as temporary bitmaps. */
......@@ -1860,6 +1863,40 @@ df_reg_used (rtx insn, rtx reg)
Debugging and printing functions.
----------------------------------------------------------------------------*/
/* 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. */
extern void debug_regset (regset);
DEBUG_FUNCTION void
debug_regset (regset r)
{
dump_regset (r, stderr);
putc ('\n', stderr);
}
/* Write information about registers and basic blocks into FILE.
This is part of making a debugging dump. */
......
......@@ -716,6 +716,7 @@ compute_alignments (void)
if (dump_file)
{
dump_reg_info (dump_file);
dump_flow_info (dump_file, TDF_DETAILS);
flow_loops_dump (dump_file, NULL, 1);
}
......
......@@ -6738,13 +6738,20 @@ reposition_prologue_and_epilogue_notes (void)
#endif /* HAVE_prologue or HAVE_epilogue */
}
/* Returns the name of function FN. */
const char *
function_name (struct function *fn)
{
if (fn == NULL)
return "(nofn)";
return lang_hooks.decl_printable_name (fn->decl, 2);
}
/* Returns the name of the current function. */
const char *
current_function_name (void)
{
if (cfun == NULL)
return "<none>";
return lang_hooks.decl_printable_name (cfun->decl, 2);
return function_name (cfun);
}
......
......@@ -22,11 +22,14 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_FUNCTION_H
#define GCC_FUNCTION_H
#include "tree.h"
#include "hashtab.h"
#include "vec.h"
#include "vecprim.h"
#include "tm.h" /* For CUMULATIVE_ARGS. */
#include "hard-reg-set.h"
#include "vecir.h"
#include "machmode.h"
#include "tm.h" /* For CUMULATIVE_ARGS. */
#include "hard-reg-set.h" /* For HARD_REG_SET in struct rtl_data. */
#include "input.h" /* For location_t. */
/* Stack of pending (incomplete) sequences saved by `start_sequence'.
Each element describes one pending sequence.
......@@ -760,6 +763,7 @@ extern void clobber_return_register (void);
extern rtx get_arg_pointer_save_area (void);
/* Returns the name of the current function. */
extern const char *function_name (struct function *);
extern const char *current_function_name (void);
extern void do_warn_unused_parameter (tree);
......
......@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "vecir.h"
#include "ggc.h"
#include "basic-block.h"
#include "tree.h"
#include "tree-ssa-operands.h"
#include "tree-ssa-alias.h"
#include "internal-fn.h"
......
......@@ -4454,7 +4454,10 @@ rest_of_handle_if_conversion (void)
if (flag_if_conversion)
{
if (dump_file)
dump_flow_info (dump_file, dump_flags);
{
dump_reg_info (dump_file);
dump_flow_info (dump_file, dump_flags);
}
cleanup_cfg (CLEANUP_EXPENSIVE);
if_convert ();
}
......
......@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "regs.h"
#include "rtl.h"
#include "tree.h" /* For DECL_ARTIFICIAL and friends. */
#include "tm_p.h"
#include "target.h"
#include "flags.h"
......
......@@ -21,7 +21,7 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_LANG_HOOKS_H
#define GCC_LANG_HOOKS_H
/* This file should be #include-d after tree.h. */
/* FIXME: This file should be #include-d after tree.h (for enum tree_code). */
struct diagnostic_info;
......
......@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "hard-reg-set.h"
#include "regs.h"
#include "obstack.h"
#include "basic-block.h"
#include "cfgloop.h"
......@@ -204,7 +204,10 @@ rtl_loop_init (void)
gcc_assert (current_ir_type () == IR_RTL_CFGLAYOUT);
if (dump_file)
dump_flow_info (dump_file, dump_flags);
{
dump_reg_info (dump_file);
dump_flow_info (dump_file, dump_flags);
}
loop_optimizer_init (LOOPS_NORMAL);
return 0;
......@@ -242,7 +245,10 @@ rtl_loop_done (void)
cleanup_cfg (0);
if (dump_file)
dump_flow_info (dump_file, dump_flags);
{
dump_reg_info (dump_file);
dump_flow_info (dump_file, dump_flags);
}
return 0;
}
......
......@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tm.h"
#include "basic-block.h"
#include "tree.h" /* FIXME: Only for langhooks.h. */
#include "langhooks.h"
#include "tree.h"
#include "gcov-io.h"
......
......@@ -150,6 +150,8 @@ maybe_hot_count_p (gcov_type count)
bool
maybe_hot_bb_p (const_basic_block bb)
{
/* Make sure CFUN exists, for dump_bb_info. */
gcc_assert (cfun);
if (profile_status == PROFILE_READ)
return maybe_hot_count_p (bb->count);
return maybe_hot_frequency_p (bb->frequency);
......@@ -201,6 +203,8 @@ maybe_hot_edge_p (edge e)
bool
probably_never_executed_bb_p (const_basic_block bb)
{
/* Make sure CFUN exists, for dump_bb_info. */
gcc_assert (cfun);
if (profile_info && flag_branch_probabilities)
return ((bb->count + profile_info->runs / 2) / profile_info->runs) == 0;
if ((!profile_info || !flag_branch_probabilities)
......
......@@ -640,7 +640,7 @@ compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum)
if (dump_file)
{
int overlap = compute_frequency_overlap ();
dump_flow_info (dump_file, dump_flags);
gimple_dump_cfg (dump_file, dump_flags);
fprintf (dump_file, "Static profile overlap: %d.%d%%\n",
overlap / (OVERLAP_BASE / 100),
overlap % (OVERLAP_BASE / 100));
......
......@@ -936,7 +936,7 @@ reginfo_init (void)
if (df)
df_compute_regs_ever_live (true);
/* This prevents dump_flow_info from losing if called
/* This prevents dump_reg_info from losing if called
before reginfo is run. */
reg_pref = NULL;
/* No more global register variables may be declared. */
......
......@@ -92,7 +92,7 @@ REG_N_SETS (int regno)
#define INC_REG_N_SETS(N,V) (regstat_n_sets_and_refs[N].sets += V)
/* Functions defined in reg-stat.c. */
/* Functions defined in regstat.c. */
extern void regstat_init_n_sets_and_refs (void);
extern void regstat_free_n_sets_and_refs (void);
extern void regstat_compute_ri (void);
......@@ -100,7 +100,7 @@ extern void regstat_free_ri (void);
extern bitmap regstat_get_setjmp_crosses (void);
extern void regstat_compute_calls_crossed (void);
extern void regstat_free_calls_crossed (void);
extern void dump_reg_info (FILE *);
/* Register information indexed by register number. This structure is
initialized by calling regstat_compute_ri and is destroyed by
......
......@@ -121,8 +121,7 @@ extern regset fixed_reg_set_regset;
/* An obstack for regsets. */
extern bitmap_obstack reg_obstack;
/* In cfg.c */
/* In df-core.c (which should use regset consistently instead of bitmap...) */
extern void dump_regset (regset, FILE *);
extern void debug_regset (regset);
#endif /* GCC_REGSET_H */
......@@ -544,3 +544,69 @@ regstat_free_calls_crossed (void)
reg_info_p = NULL;
}
/* 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);
}
}
......@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "fixed-value.h"
#include "alias.h"
#include "hashtab.h"
#include "flags.h"
#undef FFS /* Some systems predefine this symbol; don't let it interfere. */
#undef FLOAT /* Likewise. */
......@@ -423,7 +424,7 @@ struct GTY((variable_size)) rtvec_def {
#define NONDEBUG_INSN_P(X) (INSN_P (X) && !DEBUG_INSN_P (X))
/* Nonzero if DEBUG_INSN_P may possibly hold. */
#define MAY_HAVE_DEBUG_INSNS MAY_HAVE_DEBUG_STMTS
#define MAY_HAVE_DEBUG_INSNS (flag_var_tracking_assignments)
/* Predicate yielding nonzero iff X is a real insn. */
#define INSN_P(X) \
......@@ -2512,10 +2513,6 @@ extern int fixup_args_size_notes (rtx, rtx, int);
extern void print_rtl_with_bb (FILE *, const_rtx);
extern rtx duplicate_insn_chain (rtx, rtx);
/* In cfg.c. */
extern void dump_reg_info (FILE *);
extern void dump_flow_info (FILE *, int);
/* In expmed.c */
extern void init_expmed (void);
extern void expand_inc (rtx, rtx);
......
......@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "diagnostic-core.h"
#include "rtl.h"
#include "tree.h" /* FIXME: Used by call_may_noreturn_p. */
#include "tm_p.h"
#include "hard-reg-set.h"
#include "regs.h"
......@@ -3374,6 +3375,8 @@ sched_analyze_insn (struct deps_desc *deps, rtx x, rtx insn)
/* Return TRUE if INSN might not always return normally (e.g. call exit,
longjmp, loop forever, ...). */
/* FIXME: Why can't this function just use flags_from_decl_or_type and
test for ECF_NORETURN? */
static bool
call_may_noreturn_p (rtx insn)
{
......
......@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "tree.h" /* FIXME: To dump INSN_VAR_LOCATION_DECL. */
#include "obstack.h"
#include "hard-reg-set.h"
#include "basic-block.h"
......@@ -806,13 +807,15 @@ print_rtl_slim (FILE *f, rtx first, rtx last, int count, int flags)
(insn != NULL) && (insn != tail) && (count != 0);
insn = NEXT_INSN (insn))
{
bool verbose = ((flags & TDF_DETAILS) != 0);
if ((flags & TDF_BLOCKS)
&& (INSN_P (insn) || NOTE_P (insn))
&& BLOCK_FOR_INSN (insn)
&& !current_bb)
{
current_bb = BLOCK_FOR_INSN (insn);
dump_bb_info (current_bb, true, false, flags, ";; ", f);
dump_bb_info (current_bb, true, false, verbose, ";; ", f);
}
dump_insn_slim (f, insn);
......@@ -821,7 +824,7 @@ print_rtl_slim (FILE *f, rtx first, rtx last, int count, int flags)
&& current_bb
&& insn == BB_END (current_bb))
{
dump_bb_info (current_bb, false, true, flags, ";; ", f);
dump_bb_info (current_bb, false, true, verbose, ";; ", f);
current_bb = NULL;
}
if (count > 0)
......
......@@ -142,7 +142,7 @@ statistics_fini_pass_2 (void **slot, void *data ATTRIBUTE_UNUSED)
current_pass->static_pass_number,
current_pass->name,
counter->id, counter->val,
cfun ? IDENTIFIER_POINTER (DECL_NAME (cfun->decl)) : "(nofn)",
current_function_name (),
count);
else
fprintf (statistics_dump_file,
......@@ -150,7 +150,7 @@ statistics_fini_pass_2 (void **slot, void *data ATTRIBUTE_UNUSED)
current_pass->static_pass_number,
current_pass->name,
counter->id,
cfun ? IDENTIFIER_POINTER (DECL_NAME (cfun->decl)) : "(nofn)",
current_function_name (),
count);
counter->prev_dumped_count = counter->count;
return 1;
......@@ -312,7 +312,7 @@ statistics_counter_event (struct function *fn, const char *id, int incr)
current_pass->static_pass_number,
current_pass->name,
id,
fn ? IDENTIFIER_POINTER (DECL_NAME (fn->decl)) : "(nofn)",
function_name (fn),
incr);
}
......@@ -342,5 +342,5 @@ statistics_histogram_event (struct function *fn, const char *id, int val)
current_pass->static_pass_number,
current_pass->name,
id, val,
fn ? IDENTIFIER_POINTER (DECL_NAME (fn->decl)) : "(nofn)");
function_name (fn));
}
......@@ -370,14 +370,12 @@ tracer (void)
{
bool changed;
gcc_assert (current_ir_type () == IR_GIMPLE);
if (n_basic_blocks <= NUM_FIXED_BLOCKS + 1)
return 0;
mark_dfs_back_edges ();
if (dump_file)
dump_flow_info (dump_file, dump_flags);
brief_dump_cfg (dump_file);
/* Trace formation is done on the fly inside tail_duplicate */
changed = tail_duplicate ();
......@@ -385,7 +383,7 @@ tracer (void)
free_dominance_info (CDI_DOMINATORS);
if (dump_file)
dump_flow_info (dump_file, dump_flags);
brief_dump_cfg (dump_file);
return changed ? TODO_cleanup_cfg : 0;
}
......
......@@ -3833,6 +3833,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
/* Set input_location here so we get the right instantiation context
if we call instantiate_decl from inlinable_function_p. */
/* FIXME: instantiate_decl isn't called by inlinable_function_p. */
saved_location = input_location;
input_location = gimple_location (stmt);
......
......@@ -10041,6 +10041,7 @@ variable_tracking_main_1 (void)
if (dump_file && (dump_flags & TDF_DETAILS))
{
dump_dataflow_sets ();
dump_reg_info (dump_file);
dump_flow_info (dump_file, dump_flags);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment