]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
basic-block.h: Re-group most prototypes per file.
authorSteven Bosscher <steven@gcc.gnu.org>
Sun, 8 Jul 2012 10:06:14 +0000 (10:06 +0000)
committerSteven Bosscher <steven@gcc.gnu.org>
Sun, 8 Jul 2012 10:06:14 +0000 (10:06 +0000)
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

38 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/basic-block.h
gcc/bb-reorder.c
gcc/c-family/ChangeLog
gcc/c-family/c-common.h
gcc/cfg.c
gcc/cfganal.c
gcc/cfgcleanup.c
gcc/cfghooks.c
gcc/cfgrtl.c
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cselib.c
gcc/df-core.c
gcc/doc/cfg.texi
gcc/final.c
gcc/function.c
gcc/function.h
gcc/gimple.h
gcc/ifcvt.c
gcc/ira-conflicts.c
gcc/langhooks.h
gcc/loop-init.c
gcc/mcf.c
gcc/predict.c
gcc/profile.c
gcc/reginfo.c
gcc/regs.h
gcc/regset.h
gcc/regstat.c
gcc/rtl.h
gcc/sched-deps.c
gcc/sched-vis.c
gcc/statistics.c
gcc/tracer.c
gcc/tree-inline.c
gcc/var-tracking.c

index e6bbdc3353cadf73aed514fbd626ef00ec60a4dd..f0f0bfaa3c2e2dc6994783f30d5bb8c322390754 100644 (file)
@@ -1,3 +1,101 @@
+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.
index deb76282fc7fb5bad236f2c09e572162610ef906..e92ad945527dc0b2ed071b6512ee257b621168d6 100644 (file)
@@ -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) \
index 348f150ab6dc8969e57c7a9369b2f638ea4041f3..5a4540579d4229ff48137b2beb3d64b233fa5f0d 100644 (file)
@@ -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);
index 143bdd0c16870fa9687fb6f05c316b8060193823..dd41dee6006ec380293a2b151a4ca792e6d257e1 100644 (file)
@@ -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 ();
index 8b7c4b789b12317939134ac80353a6c9954e9138..dde9c936957e775fda4c63f21f9be9d701ac3183 100644 (file)
@@ -1,3 +1,7 @@
+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
index 11f58e98bbaea1202b671a9dcde8b7d248fd33a5..050112e5372f6c1e69eb75025c6fd83f0fbcc261 100644 (file)
@@ -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
index 667e0977b4f74bd8d938dd309d9d73b78af3b27b..08b34dbb5675dc2556d439f49e6a3f5fd9bdec18 100644 (file)
--- 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.
  */
 \f
 #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);
 \f
 #define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
 
@@ -98,10 +83,10 @@ init_flow (struct function *the_fun)
 }
 \f
 /* 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)
     }
 }
 \f
-/* 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);
index d361ff08f98d3a27066a50e319615a8b7498c1f5..c906e17e358dd6672c99dff3427c3266581a4229 100644 (file)
@@ -1,7 +1,5 @@
 /* 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);
-\f
-/* 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;
-}
 \f
 /* 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);
-}
-
 \f
 /* 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.  */
index 909d3462d7454b1d941986f0ae3fc5cf1c65cadb..a7f8546d51f46bb9de8bf61a6b0d90e3ee797de6 100644 (file)
@@ -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)
index 5b49d64f0905eca3ab6828dc2d1e68a21878cf34..07cbad6462f663608021cd98e92f3dcf1eac55f8 100644 (file)
@@ -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.  */
index 69cf86dc9540fea3e6280b6cf2d1512002ab39f0..595975194ddf72380ae15e8b23218adb8169e857 100644 (file)
@@ -516,6 +516,107 @@ update_bb_for_insn (basic_block bb)
   update_bb_for_insn_chain (BB_HEAD (bb), BB_END (bb), bb);
 }
 
+\f
+/* 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;
+}
 \f
 /* Return the NOTE_INSN_BASIC_BLOCK of BB.  */
 rtx
@@ -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)
     }
 }
 \f
+/* 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);
+}
+\f
+/* 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)
index f40753924450175f4d8fecaa42f483a8973ade93..44ea7865c9e15186711b7fffa392b0260f9ca036 100644 (file)
@@ -1,3 +1,7 @@
+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
index 6c0990c00f723d82f23bf13d69e94d3b27bb19ac..842c2d8c545cd4100c7adafd07a9ff1f060d0c85 100644 (file)
@@ -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);
        }
 
index d338c31be1aae163a2f3c3ea79fd6ab21c227f08..6383a8753e3ffd56c17dca08eb818f0ab9ad2957 100644 (file)
@@ -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"
index 0ca33037450cb08dc0762c688640a6b7fe009fc8..5c631f3a56858aaf1207f36bc2522ce8e6554931 100644 (file)
@@ -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.  */
index d9867fb56f045c93d22444a4acbdf16921cbf11c..4e77cd1029968d03f7ea57d0a34e909e5c6cf26c 100644 (file)
@@ -1,6 +1,5 @@
 @c -*-texinfo-*-
-@c Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007, 2008 Free Software
-@c Foundation, Inc.
+@c Copyright (C) 2001-2012 Free Software Foundation, Inc.
 @c This is part of the GCC manual.
 @c For copying conditions, see the file gcc.texi.
 
@@ -14,7 +13,7 @@
 @findex basic-block.h
 
 A control flow graph (CFG) is a data structure built on top of the
-intermediate code representation (the RTL or @code{tree} instruction
+intermediate code representation (the RTL or @code{GIMPLE} instruction
 stream) abstracting the control flow behavior of a function that is
 being compiled.  The CFG is a directed graph where the vertices
 represent basic blocks and edges represent possible transfer of
@@ -22,6 +21,20 @@ control flow from one basic block to another.  The data structures
 used to represent the control flow graph are defined in
 @file{basic-block.h}.
 
+In GCC, the representation of control flow is maintained throughout
+the compilation process, from constructing the CFG early in 
+@code{pass_build_cfg} to @code{pass_free_cfg} (see @file{passes.c}).
+The CFG takes various different modes and may undergo extensive
+manipulations, but the graph is always valid between its construction
+and its release.  This way, transfer of information such as data flow,
+a measured profile, or the loop tree, can be propagated through the
+passes pipeline, and even from @code{GIMPLE} to @code{RTL}.
+
+Often the CFG may be better viewed as integral part of instruction
+chain, than structure built on the top of it.  Updating the compiler's
+intermediate representation for instructions can not be easily done
+without proper maintenance of the CFG simultaneously.
+
 @menu
 * Basic Blocks::           The definition and representation of basic blocks.
 * Edges::                  Types of edges and their representation.
@@ -40,16 +53,10 @@ A basic block is a straight-line sequence of code with only one entry
 point and only one exit.  In GCC, basic blocks are represented using
 the @code{basic_block} data type.
 
-@findex next_bb, prev_bb, FOR_EACH_BB
-Two pointer members of the @code{basic_block} structure are the
-pointers @code{next_bb} and @code{prev_bb}.  These are used to keep
-doubly linked chain of basic blocks in the same order as the
-underlying instruction stream.  The chain of basic blocks is updated
-transparently by the provided API for manipulating the CFG@.  The macro
-@code{FOR_EACH_BB} can be used to visit all the basic blocks in
-lexicographical order.  Dominator traversals are also possible using
-@code{walk_dominator_tree}.  Given two basic blocks A and B, block A
-dominates block B if A is @emph{always} executed before B@.
+@findex ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR
+Special basic blocks represent possible entry and exit points of a
+function.  These blocks are called @code{ENTRY_BLOCK_PTR} and
+@code{EXIT_BLOCK_PTR}.  These blocks do not contain any code.
 
 @findex BASIC_BLOCK
 The @code{BASIC_BLOCK} array contains all basic blocks in an
@@ -61,39 +68,61 @@ The total number of basic blocks in the function is
 the total number of basic blocks may vary during the compilation
 process, as passes reorder, create, duplicate, and destroy basic
 blocks.  The index for any block should never be greater than
-@code{last_basic_block}.
+@code{last_basic_block}.  The indices 0 and 1 are special codes
+reserved for @code{ENTRY_BLOCK} and @code{EXIT_BLOCK}, the
+indices of @code{ENTRY_BLOCK_PTR} and @code{EXIT_BLOCK_PTR}.
 
-@findex ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR
-Special basic blocks represent possible entry and exit points of a
-function.  These blocks are called @code{ENTRY_BLOCK_PTR} and
-@code{EXIT_BLOCK_PTR}.  These blocks do not contain any code, and are
-not elements of the @code{BASIC_BLOCK} array.  Therefore they have
-been assigned unique, negative index numbers.
+@findex next_bb, prev_bb, FOR_EACH_BB, FOR_ALL_BB
+Two pointer members of the @code{basic_block} structure are the
+pointers @code{next_bb} and @code{prev_bb}.  These are used to keep
+doubly linked chain of basic blocks in the same order as the
+underlying instruction stream.  The chain of basic blocks is updated
+transparently by the provided API for manipulating the CFG@.  The macro
+@code{FOR_EACH_BB} can be used to visit all the basic blocks in
+lexicographical order, except @code{ENTRY_BLOCK} and @code{EXIT_BLOCK}.
+The macro @code{FOR_ALL_BB} also visits all basic blocks in
+lexicographical order, including @code{ENTRY_BLOCK} and @code{EXIT_BLOCK}.
+
+@findex post_order_compute, inverted_post_order_compute, walk_dominator_tree
+The functions @code{post_order_compute} and @code{inverted_post_order_compute}
+can be used to compute topological orders of the CFG.  The orders are
+stored as vectors of basic block indices.  The @code{BASIC_BLOCK} array
+can be used to iterate each basic block by index.
+Dominator traversals are also possible using
+@code{walk_dominator_tree}.  Given two basic blocks A and B, block A
+dominates block B if A is @emph{always} executed before B@.
 
 Each @code{basic_block} also contains pointers to the first
 instruction (the @dfn{head}) and the last instruction (the @dfn{tail})
 or @dfn{end} of the instruction stream contained in a basic block.  In
 fact, since the @code{basic_block} data type is used to represent
-blocks in both major intermediate representations of GCC (@code{tree}
+blocks in both major intermediate representations of GCC (@code{GIMPLE}
 and RTL), there are pointers to the head and end of a basic block for
-both representations.
+both representations, stored in intermediate representation specific
+data in the @code{il} field of @code{struct basic_block_def}.
+
+@findex CODE_LABEL
+@findex NOTE_INSN_BASIC_BLOCK
+For RTL, these pointers are @code{BB_HEAD} and @code{BB_END}.
 
-@findex NOTE_INSN_BASIC_BLOCK, CODE_LABEL, notes
-For RTL, these pointers are @code{rtx head, end}.  In the RTL function
-representation, the head pointer always points either to a
-@code{NOTE_INSN_BASIC_BLOCK} or to a @code{CODE_LABEL}, if present.
+@cindex insn notes, notes
+@findex NOTE_INSN_BASIC_BLOCK
 In the RTL representation of a function, the instruction stream
-contains not only the ``real'' instructions, but also @dfn{notes}.
+contains not only the ``real'' instructions, but also @dfn{notes}
+or @dfn{insn notes} (to distinguish them from @dfn{reg notes}).
 Any function that moves or duplicates the basic blocks needs
 to take care of updating of these notes.  Many of these notes expect
-that the instruction stream consists of linear regions, making such
-updates difficult.   The @code{NOTE_INSN_BASIC_BLOCK} note is the only
-kind of note that may appear in the instruction stream contained in a
-basic block.  The instruction stream of a basic block always follows a
-@code{NOTE_INSN_BASIC_BLOCK},  but zero or more @code{CODE_LABEL}
-nodes can precede the block note.   A basic block ends by control flow
-instruction or last instruction before following @code{CODE_LABEL} or
-@code{NOTE_INSN_BASIC_BLOCK}.  A @code{CODE_LABEL} cannot appear in
+that the instruction stream consists of linear regions, so updating
+can sometimes be tedious.  All types of insn notes are defined
+in @file{insn-notes.def}.
+
+In the RTL function representation, the instructions contained in a
+basic block always follow a @code{NOTE_INSN_BASIC_BLOCK}, but zero
+or more @code{CODE_LABEL} nodes can precede the block note.
+A basic block ends with a control flow instruction or with the last
+instruction before the next @code{CODE_LABEL} or
+@code{NOTE_INSN_BASIC_BLOCK}.
+By definition, a @code{CODE_LABEL} cannot appear in the middle of
 the instruction stream of a basic block.
 
 @findex can_fallthru
@@ -110,27 +139,34 @@ Before any edge is made @dfn{fall-thru}, the existence of such
 construct in the way needs to be checked by calling
 @code{can_fallthru} function.
 
-@cindex block statement iterators
-For the @code{tree} representation, the head and end of the basic block
-are being pointed to by the @code{stmt_list} field, but this special
-@code{tree} should never be referenced directly.  Instead, at the tree
-level abstract containers and iterators are used to access statements
-and expressions in basic blocks.  These iterators are called
-@dfn{block statement iterators} (BSIs).  Grep for @code{^bsi}
-in the various @file{tree-*} files.
-The following snippet will pretty-print all the statements of the
-program in the GIMPLE representation.
+@cindex GIMPLE statement iterators
+For the @code{GIMPLE} representation, the PHI nodes and statements
+contained in a basic block are in a @code{gimple_seq} pointed to by
+the basic block intermediate language specific pointers.
+Abstract containers and iterators are used to access the PHI nodes
+and statements in a basic blocks.  These iterators are called
+@dfn{GIMPLE statement iterators} (GSIs).  Grep for @code{^gsi}
+in the various @file{gimple-*} and @file{tree-*} files.
+The following snippet will pretty-print all PHI nodes the statements
+of the current function in the GIMPLE representation.
 
 @smallexample
+basic_block bb;
+
 FOR_EACH_BB (bb)
   @{
-     block_stmt_iterator si;
-
-     for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
-       @{
-          tree stmt = bsi_stmt (si);
-          print_generic_stmt (stderr, stmt, 0);
-       @}
+   gimple_stmt_iterator si;
+
+   for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
+     @{
+       gimple phi = gsi_stmt (si);
+       print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
+     @}
+   for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
+     @{
+       gimple stmt = gsi_stmt (si);
+       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
+     @}
   @}
 @end smallexample
 
@@ -144,7 +180,7 @@ Edges represent possible control flow transfers from the end of some
 basic block A to the head of another basic block B@.  We say that A is
 a predecessor of B, and B is a successor of A@.  Edges are represented
 in GCC with the @code{edge} data type.  Each @code{edge} acts as a
-link between two basic blocks: the @code{src} member of an edge
+link between two basic blocks: The @code{src} member of an edge
 points to the predecessor basic block of the @code{dest} basic block.
 The members @code{preds} and @code{succs} of the @code{basic_block} data
 type point to type-safe vectors of edges to the predecessors and
@@ -245,7 +281,7 @@ is needed.  Note that this may require creation of a new basic block.
 Exception handling edges represent possible control transfers from a
 trapping instruction to an exception handler.  The definition of
 ``trapping'' varies.  In C++, only function calls can throw, but for
-Java, exceptions like division by zero or segmentation fault are
+Java and Ada, exceptions like division by zero or segmentation fault are
 defined and thus each instruction possibly throwing this kind of
 exception needs to be handled as control flow instruction.  Exception
 edges have the @code{EDGE_ABNORMAL} and @code{EDGE_EH} flags set.
@@ -260,7 +296,7 @@ anyway.  The edges can be eliminated via @code{purge_dead_edges} call.
 In the RTL representation, the destination of an exception edge is
 specified by @code{REG_EH_REGION} note attached to the insn.
 In case of a trapping call the @code{EDGE_ABNORMAL_CALL} flag is set
-too.  In the @code{tree} representation, this extra flag is not set.
+too.  In the @code{GIMPLE} representation, this extra flag is not set.
 
 @findex may_trap_p, tree_could_trap_p
 In the RTL representation, the predicate @code{may_trap_p} may be used
@@ -320,9 +356,11 @@ y:
   goto *x;
 @end smallexample
 
+@findex pass_duplicate_computed_gotos
 However, the classic problem with this transformation is that it has a
 runtime cost in there resulting code: An extra jump.  Therefore, the
-computed jumps are un-factored in the later passes of the compiler.
+computed jumps are un-factored in the later passes of the compiler
+(in the pass called @code{pass_duplicate_computed_gotos}).
 Be aware of that when you work on passes in that area.  There have
 been numerous examples already where the compile time for code with
 unfactored computed jumps caused some serious headaches.
@@ -343,7 +381,7 @@ edge from the call to the label is created with the
 @findex LABEL_ALTERNATE_NAME
 By definition, execution of function starts at basic block 0, so there
 is always an edge from the @code{ENTRY_BLOCK_PTR} to basic block 0.
-There is no @code{tree} representation for alternate entry points at
+There is no @code{GIMPLE} representation for alternate entry points at
 this moment.  In RTL, alternate entry points are specified by
 @code{CODE_LABEL} with @code{LABEL_ALTERNATE_NAME} defined.  This
 feature is currently used for multiple entry point prologues and is
@@ -372,7 +410,7 @@ speed.  In such cases it is useful to know information about how often
 some given block will be executed.  That is the purpose for
 maintaining profile within the flow graph.
 GCC can handle profile information obtained through @dfn{profile
-feedback}, but it can also  estimate branch probabilities based on
+feedback}, but it can also estimate branch probabilities based on
 statics and heuristics.
 
 @cindex profile feedback
@@ -425,7 +463,7 @@ Each edge also contains a branch probability field: an integer in the
 range from 0 to @code{REG_BR_PROB_BASE}.  It represents probability of
 passing control from the end of the @code{src} basic block to the
 @code{dest} basic block, i.e.@: the probability that control will flow
-along this edge.   The @code{EDGE_FREQUENCY} macro is available to
+along this edge.  The @code{EDGE_FREQUENCY} macro is available to
 compute how frequently a given edge is taken.  There is a @code{count}
 field for each edge as well, representing same information as for a
 basic block.
@@ -482,76 +520,63 @@ manipulation routines when necessary.  These hooks are defined in
 manipulations, including block splitting and merging, edge redirection
 and creating and deleting basic blocks.  These hooks should provide
 everything you need to maintain and manipulate the CFG in both the RTL
-and @code{tree} representation.
+and @code{GIMPLE} representation.
 
 At the moment, the basic block boundaries are maintained transparently
 when modifying instructions, so there rarely is a need to move them
 manually (such as in case someone wants to output instruction outside
 basic block explicitly).
-Often the CFG may be better viewed as integral part of instruction
-chain, than structure built on the top of it.  However, in principle
-the control flow graph for the @code{tree} representation is
-@emph{not} an integral part of the representation, in that a function
-tree may be expanded without first building a  flow graph for the
-@code{tree} representation at all.  This happens when compiling
-without any @code{tree} optimization enabled.  When the @code{tree}
-optimizations are enabled and the instruction stream is rewritten in
-SSA form, the CFG is very tightly coupled with the instruction stream.
-In particular, statement insertion and removal has to be done with
-care.  In fact, the whole @code{tree} representation can not be easily
-used or maintained without proper maintenance of the CFG
-simultaneously.
-
-@findex BLOCK_FOR_INSN, bb_for_stmt
+
+@findex BLOCK_FOR_INSN, gimple_bb
 In the RTL representation, each instruction has a
 @code{BLOCK_FOR_INSN} value that represents pointer to the basic block
-that contains the instruction.  In the @code{tree} representation, the
-function @code{bb_for_stmt} returns a pointer to the basic block
+that contains the instruction.  In the @code{GIMPLE} representation, the
+function @code{gimple_bb} returns a pointer to the basic block
 containing the queried statement.
 
-@cindex block statement iterators
-When changes need to be applied to a function in its @code{tree}
-representation, @dfn{block statement iterators} should be used.  These
+@cindex GIMPLE statement iterators
+When changes need to be applied to a function in its @code{GIMPLE}
+representation, @dfn{GIMPLE statement iterators} should be used.  These
 iterators provide an integrated abstraction of the flow graph and the
 instruction stream.  Block statement iterators are constructed using
-the @code{block_stmt_iterator} data structure and several modifier are
+the @code{gimple_stmt_iterator} data structure and several modifier are
 available, including the following:
 
 @ftable @code
-@item bsi_start
-This function initializes a @code{block_stmt_iterator} that points to
+@item gsi_start
+This function initializes a @code{gimple_stmt_iterator} that points to
 the first non-empty statement in a basic block.
 
-@item bsi_last
-This function initializes a @code{block_stmt_iterator} that points to
+@item gsi_last
+This function initializes a @code{gimple_stmt_iterator} that points to
 the last statement in a basic block.
 
-@item bsi_end_p
-This predicate is @code{true} if a @code{block_stmt_iterator}
+@item gsi_end_p
+This predicate is @code{true} if a @code{gimple_stmt_iterator}
 represents the end of a basic block.
 
-@item bsi_next
-This function takes a @code{block_stmt_iterator} and makes it point to
+@item gsi_next
+This function takes a @code{gimple_stmt_iterator} and makes it point to
 its successor.
 
-@item bsi_prev
-This function takes a @code{block_stmt_iterator} and makes it point to
+@item gsi_prev
+This function takes a @code{gimple_stmt_iterator} and makes it point to
 its predecessor.
 
-@item bsi_insert_after
-This function inserts a statement after the @code{block_stmt_iterator}
+@item gsi_insert_after
+This function inserts a statement after the @code{gimple_stmt_iterator}
 passed in.  The final parameter determines whether the statement
 iterator is updated to point to the newly inserted statement, or left
 pointing to the original statement.
 
-@item bsi_insert_before
-This function inserts a statement before the @code{block_stmt_iterator}
+@item gsi_insert_before
+This function inserts a statement before the @code{gimple_stmt_iterator}
 passed in.  The final parameter determines whether the statement
 iterator is updated to point to the newly inserted statement, or left
 pointing to the original  statement.
 
-@item bsi_remove
-This function removes the @code{block_stmt_iterator} passed in and
+@item gsi_remove
+This function removes the @code{gimple_stmt_iterator} passed in and
 rechains the remaining statements in a basic block, if any.
 @end ftable
 
@@ -591,8 +616,8 @@ target of a jump or branch instruction.
 
 @findex insert_insn_on_edge
 @findex commit_edge_insertions
-@findex bsi_insert_on_edge
-@findex bsi_commit_edge_inserts
+@findex gsi_insert_on_edge
+@findex gsi_commit_edge_inserts
 @cindex edge splitting
 For a global optimizer, a common operation is to split edges in the
 flow graph and insert instructions on them.  In the RTL
@@ -602,20 +627,17 @@ representation, this can be easily done using the
 call that will take care of moving the inserted instructions off the
 edge into the instruction stream contained in a basic block.  This
 includes the creation of new basic blocks where needed.  In the
-@code{tree} representation, the equivalent functions are
-@code{bsi_insert_on_edge} which inserts a block statement
-iterator on an edge, and @code{bsi_commit_edge_inserts} which flushes
+@code{GIMPLE} representation, the equivalent functions are
+@code{gsi_insert_on_edge} which inserts a block statement
+iterator on an edge, and @code{gsi_commit_edge_inserts} which flushes
 the instruction to actual instruction stream.
 
-While debugging the optimization pass, a @code{verify_flow_info}
+@findex verify_flow_info
+@cindex CFG verification
+While debugging the optimization pass, the @code{verify_flow_info}
 function may be useful to find bugs in the control flow graph updating
 code.
 
-Note that at present, the representation of control flow in the
-@code{tree} representation is discarded before expanding to RTL@.
-Long term the CFG should be maintained and ``expanded'' to the
-RTL representation along with the function @code{tree} itself.
-
 
 @node Liveness information
 @section Liveness information
index 5326018d0bff2739b904a34b1fab9d307d47cc75..668aacb309eebfb3913c1410bcf907af18a659aa 100644 (file)
@@ -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);
     }
index 518d52401c5ade0bf7893978723960d49410164a..b37646922a457cdaf5a6e5523529d7c27510eec5 100644 (file)
@@ -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);
 }
 \f
 
index 58f38bd1c2bbbe5ddf2ca04d3244b1ba44be5acd..a7d8b44a5d0a1d6576c126fa4d20044004f5077e 100644 (file)
@@ -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);
index 193590dbe74c3250c1290fbf9d5d8d15ecd93df5..6bb6d93064092bd78597d26020a69cb0e453408a 100644 (file)
@@ -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"
index c1d4c9eb1e17d753bc6faa66b54a007d4bbccb97..68b50a1a3381afb8500cebb40b5eac71dbb0c6d1 100644 (file)
@@ -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 ();
     }
index a0d36094ed568405c471e7ffae3385b932087253..1d740797ecfe9882e3606e5a8389722c48e527cc 100644 (file)
@@ -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"
index 76b1fe260137480daaa5c8133be215fd83976ce4..a91906729204cc0033c0f2c8adcfb6197c78989a 100644 (file)
@@ -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;
 
index ee3d80c94795c5a04d104a31fb274245995ac840..45d49f22cad8559556d185a240f8bc65050f377d 100644 (file)
@@ -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;
 }
index 81949ab5bc503dd01a5047c3de5d17d327fffe7a..b6112100a31d1dd00bb5cf50184f3026e4dedcb6 100644 (file)
--- a/gcc/mcf.c
+++ b/gcc/mcf.c
@@ -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"
index 776ea7e9a79d9d4cba0d5902e372f10dea140fd5..78f15e388e32f70fa07da6ba965614afd770068b 100644 (file)
@@ -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)
index ad3a2c317464235f04fc46c5fa28530ed59c2f06..bf48cffdf2ca477641a7b2372ed6f76efbbdc1df 100644 (file)
@@ -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));
index 4fa0d04ce9c80707d3fb51471cc3600f4fcb335f..99d1a94078d9e0c0af7528b80f21450ac3a7ab1c 100644 (file)
@@ -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.  */
index 24f410c6b07e6d7e368aff472733d3c937e3384c..4c9d7a6ce4218201b3f3ff880161f9c8ba85077d 100644 (file)
@@ -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
index af807b03597382fac3fd955ede348e6222f66bca..c4981c720355e186fece0f5201325d2ec29f5a51 100644 (file)
@@ -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 */
index cecc7278999688c75abdc7e63e3cefcd3fefec01..ddfb404fbf2a2df10ccc3e16e5509a10277b4743 100644 (file)
@@ -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);
+    }
+}
+
index cbed2005e32e1fcf131529437dc662262cccc1f9..4bef6f84003f5eeb28fbc0c94418e3a3634178fb 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -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);
index b92ba9b9334d728c09473a07c648bf0ae4c4b4a8..1469818a1829e6a4d8288bc20b56e7c77d468701 100644 (file)
@@ -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)
 {
index 5b6ea9ed88a317c22aadfcca3015b6ffefa8e7e5..2b4d6240cb801bc1794ce96c46d5f20c599d7772 100644 (file)
@@ -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)
index 4883859f7a3aeaa38d79a957b0b83842143a329e..55ec981f3bb504294fa08d44fcc7c8abe93ec20c 100644 (file)
@@ -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));
 }
index 7ea67fa0c5e2133448cdf8009ec76933250c15db..e005702eef158af4b8612cebf6d40785a1a585bc 100644 (file)
@@ -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;
 }
index c3d3fb6648600c4aac7fe4d096c6f5f86bd28da4..31773dddb17dea091f393fa70d942210c4e4f4e1 100644 (file)
@@ -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);
 
index 5288c284227bb27f7b1c8351c1de5984552b680b..4570b97c0a4e6d0c8da5c07ab323aa62e15d4a5f 100644 (file)
@@ -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);
     }