diff options
author | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-17 23:17:20 +0000 |
---|---|---|
committer | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-17 23:17:20 +0000 |
commit | 5147ec0758d033a3f21f831c878ec8fa5dcd2a94 (patch) | |
tree | 9d5c1ea84c526379245c9986d831f4ce16757d79 /gcc | |
parent | f25dbbf707698795ff642f32c290d25d5c356975 (diff) | |
download | gcc-5147ec0758d033a3f21f831c878ec8fa5dcd2a94.tar.gz |
* dumpfile.h (TDF_COMMENT): New define.
* basic-block.h (EDGE_FALLTHRU, EDGE_ABNORMAL, EDGE_ABNORMAL_CALL,
EDGE_EH, EDGE_FAKE, EDGE_DFS_BACK, EDGE_CAN_FALLTHRU,
EDGE_IRREDUCIBLE_LOOP, EDGE_SIBCALL, EDGE_LOOP_EXIT, EDGE_TRUE_VALUE,
EDGE_FALSE_VALUE, EDGE_EXECUTABLE, EDGE_CROSSING, EDGE_PRESERVE):
Move to new file cfg-flags.h.
(enum cfg_edge_flags): New enum, using cfg-flags.h.
(EDGE_ALL_FLAGS): Compute value automatically.
(BB_NEW, BB_REACHABLE, BB_IRREDUCIBLE_LOOP, BB_SUPERBLOCK,
BB_DISABLE_SCHEDULE, BB_HOT_PARTITION, BB_COLD_PARTITION,
BB_DUPLICATED, BB_NON_LOCAL_GOTO_TARGET, BB_RTL,
BB_FORWARDER_BLOCK, BB_NONTHREADABLE_BLOCK, BB_MODIFIED, BB_VISITED,
BB_IN_TRANSACTION): Move to new file cfg-flags.h.
(enum bb_flags): Rename to cfg_bb_flags. Use cfg-flags.h.
(BB_ALL_FLAGS): New, compute value automatically.
(dump_bb_info): Update prototype.
(dump_edge_info): Update prototype.
* cfg-flags.h: New file.
* cfg.c (dump_edge_info): Take flags argument. Be verbose only if
TDF_DETAILS and not TDF_SLIM. Include cfg-flags.h for bitnames.
Check that the edge flags are within the range of EDGE_ALL_FLAGS.
(debug_bb): Update dump_bb call.
(dump_cfg_bb_info): Remove.
(dump_bb_info): New function. Use cfg-flags.h for bitnames.
Adjust verbosity using TDF_* flags. Check that the basic block flags
are within the range of BB_ALL_FLAGS.
(brief_dump_cfg): Use dump_bb_info instead of dump_cfg_bb_info.
* cfghooks.h (struct cfghooks): Update dump_bb hook, take a FILE
first for consistency with other dump functions.
(dump_bb): Update prototype accordingly.
* cfghooks.c: Include dumpfile.h.
(verify_flow_info): Update dump_edge_info calls.
(dump_bb): Take a flags argument and pass it around.
Use dump_bb_info to dump common information about a basic block.
(dump_flow_info): Moved here from cfgrtl.c. Make IL agnostic.
(debug_flow_info): Moved here from cfgrtl.c.
* profile.c (is_edge_inconsistent): Update dump_bb calls.
* loop-invariant.c (find_defs): Update print_rtl_with_bb call.
* rtl.h (debug_bb_n_slim, debug_bb_slim, print_rtl_slim,
print_rtl_slim_with_bb): Remove prototypes.
(dump_insn_slim): Adjust prototype to take a const_rtx.
(print_rtl_with_bb): Adjust prototype.
* sched-rgn.c (debug_region): Use dump_bb instead of debug_bb_n_slim.
* sched-vis.c (dump_insn_slim): Take a const_rtx.
(debug_insn_slim): Prototype here near DEBUG_FUNCTION marker.
(print_rtl_slim_with_bb): Remove.
(print_rtl_slim): Rename to debug_rtl_slim. Print only insn info,
not basic block info (print_rtl_with_bb with TDF_SLIM should be used
for that. Prototype here near DEBUG_FUNCTION marker.
(debug_bb_slim): Prototype here near DEBUG_FUNCTION marker.
Use dump_bb.
(debug_bb_n_slim): Prototype here near DEBUG_FUNCTION marker.
* tree-cfg.c (gimple_can_merge_blocks_p): Use EDGE_COMPLEX.
(remove_bb): Update dump_bb call.
(gimple_debug_bb): Use dump_bb.
(dump_function_to_file): Update gimple_dump_bb call.
(print_loops_bb): Likewise.
* tree-flow.h (gimple_dump_bb): Update prototype.
* gimple-pretty-print.c (dump_bb_header): Rename to
dump_gimple_bb_header. Write to a stream instead of a pretty
printer. Use dump_bb_info to dump basic block info.
(dump_bb_end): Rename to dump_gimple_bb_footer. Write to a
stream instead of a pretty printer. Use dump_bb_info.
(gimple_dump_bb_buff): Do not call dump_bb_header and dump_bb_end.
(gimple_dump_bb): Do it here with dump_gimple_bb_header and
dump_gimple_bb_footer.
* cfgrtl.c (rtl_dump_bb): Update prototype. Only dump DF if the
dump flags have TDF_DETAILS. Use dump_insn_slim if TDF_SLIM.
(print_rtl_with_bb): Take a flags argument and pass it around.
Use dump_insn_slim if TDF_SLIM.
(dump_bb_info): Removed and re-incarnated in cfg.c.
(dump_flow_info): Moved to cfghooks.c.
(debug_flow_info): Moved to cfghooks.c.
* passes.c (execute_function_dump): Unconditionally use
print_rtl_with_bb for RTL dumps, now that it understands TDF_SLIM.
* final.c (dump_basic_block_info): Update dump_edge_info calls.
* tree-vrp.c (dump_asserts_for): Likewise.
* ifcvt.c (if_convert): Unconditionally use print_rtl_with_bb.
* tree-if-conv.c (if_convertible_bb_p): Don't look at
EDGE_ABNORMAL_CALL, it has no meaning in the GIMPLE world.
* trans-mem.c (make_tm_edge): Don't set EDGE_ABNORMAL_CALL,
for the same reason.
* config/rl78/rl78.c (rl78_reorg): Update print_rtl_with_bb calls.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189590 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 86 | ||||
-rw-r--r-- | gcc/basic-block.h | 125 | ||||
-rw-r--r-- | gcc/cfg-flags.def | 179 | ||||
-rw-r--r-- | gcc/cfg.c | 163 | ||||
-rw-r--r-- | gcc/cfghooks.c | 80 | ||||
-rw-r--r-- | gcc/cfghooks.h | 4 | ||||
-rw-r--r-- | gcc/cfgrtl.c | 146 | ||||
-rw-r--r-- | gcc/config/rl78/rl78.c | 4 | ||||
-rw-r--r-- | gcc/dumpfile.h | 1 | ||||
-rw-r--r-- | gcc/final.c | 4 | ||||
-rw-r--r-- | gcc/gimple-pretty-print.c | 100 | ||||
-rw-r--r-- | gcc/ifcvt.c | 7 | ||||
-rw-r--r-- | gcc/loop-invariant.c | 2 | ||||
-rw-r--r-- | gcc/passes.c | 8 | ||||
-rw-r--r-- | gcc/profile.c | 10 | ||||
-rw-r--r-- | gcc/rtl.h | 9 | ||||
-rw-r--r-- | gcc/sched-rgn.c | 3 | ||||
-rw-r--r-- | gcc/sched-vis.c | 46 | ||||
-rw-r--r-- | gcc/trans-mem.c | 2 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 10 | ||||
-rw-r--r-- | gcc/tree-flow.h | 2 | ||||
-rw-r--r-- | gcc/tree-if-conv.c | 3 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 2 |
23 files changed, 534 insertions, 462 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aa7df8ec20f..f5242940351 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,89 @@ +2012-07-18 Steven Bosscher <steven@gcc.gnu.org> + + * dumpfile.h (TDF_COMMENT): New define. + * basic-block.h (EDGE_FALLTHRU, EDGE_ABNORMAL, EDGE_ABNORMAL_CALL, + EDGE_EH, EDGE_FAKE, EDGE_DFS_BACK, EDGE_CAN_FALLTHRU, + EDGE_IRREDUCIBLE_LOOP, EDGE_SIBCALL, EDGE_LOOP_EXIT, EDGE_TRUE_VALUE, + EDGE_FALSE_VALUE, EDGE_EXECUTABLE, EDGE_CROSSING, EDGE_PRESERVE): + Move to new file cfg-flags.h. + (enum cfg_edge_flags): New enum, using cfg-flags.h. + (EDGE_ALL_FLAGS): Compute value automatically. + (BB_NEW, BB_REACHABLE, BB_IRREDUCIBLE_LOOP, BB_SUPERBLOCK, + BB_DISABLE_SCHEDULE, BB_HOT_PARTITION, BB_COLD_PARTITION, + BB_DUPLICATED, BB_NON_LOCAL_GOTO_TARGET, BB_RTL, + BB_FORWARDER_BLOCK, BB_NONTHREADABLE_BLOCK, BB_MODIFIED, BB_VISITED, + BB_IN_TRANSACTION): Move to new file cfg-flags.h. + (enum bb_flags): Rename to cfg_bb_flags. Use cfg-flags.h. + (BB_ALL_FLAGS): New, compute value automatically. + (dump_bb_info): Update prototype. + (dump_edge_info): Update prototype. + * cfg-flags.h: New file. + * cfg.c (dump_edge_info): Take flags argument. Be verbose only if + TDF_DETAILS and not TDF_SLIM. Include cfg-flags.h for bitnames. + Check that the edge flags are within the range of EDGE_ALL_FLAGS. + (debug_bb): Update dump_bb call. + (dump_cfg_bb_info): Remove. + (dump_bb_info): New function. Use cfg-flags.h for bitnames. + Adjust verbosity using TDF_* flags. Check that the basic block flags + are within the range of BB_ALL_FLAGS. + (brief_dump_cfg): Use dump_bb_info instead of dump_cfg_bb_info. + * cfghooks.h (struct cfghooks): Update dump_bb hook, take a FILE + first for consistency with other dump functions. + (dump_bb): Update prototype accordingly. + * cfghooks.c: Include dumpfile.h. + (verify_flow_info): Update dump_edge_info calls. + (dump_bb): Take a flags argument and pass it around. + Use dump_bb_info to dump common information about a basic block. + (dump_flow_info): Moved here from cfgrtl.c. Make IL agnostic. + (debug_flow_info): Moved here from cfgrtl.c. + * profile.c (is_edge_inconsistent): Update dump_bb calls. + * loop-invariant.c (find_defs): Update print_rtl_with_bb call. + * rtl.h (debug_bb_n_slim, debug_bb_slim, print_rtl_slim, + print_rtl_slim_with_bb): Remove prototypes. + (dump_insn_slim): Adjust prototype to take a const_rtx. + (print_rtl_with_bb): Adjust prototype. + * sched-rgn.c (debug_region): Use dump_bb instead of debug_bb_n_slim. + * sched-vis.c (dump_insn_slim): Take a const_rtx. + (debug_insn_slim): Prototype here near DEBUG_FUNCTION marker. + (print_rtl_slim_with_bb): Remove. + (print_rtl_slim): Rename to debug_rtl_slim. Print only insn info, + not basic block info (print_rtl_with_bb with TDF_SLIM should be used + for that. Prototype here near DEBUG_FUNCTION marker. + (debug_bb_slim): Prototype here near DEBUG_FUNCTION marker. + Use dump_bb. + (debug_bb_n_slim): Prototype here near DEBUG_FUNCTION marker. + * tree-cfg.c (gimple_can_merge_blocks_p): Use EDGE_COMPLEX. + (remove_bb): Update dump_bb call. + (gimple_debug_bb): Use dump_bb. + (dump_function_to_file): Update gimple_dump_bb call. + (print_loops_bb): Likewise. + * tree-flow.h (gimple_dump_bb): Update prototype. + * gimple-pretty-print.c (dump_bb_header): Rename to + dump_gimple_bb_header. Write to a stream instead of a pretty + printer. Use dump_bb_info to dump basic block info. + (dump_bb_end): Rename to dump_gimple_bb_footer. Write to a + stream instead of a pretty printer. Use dump_bb_info. + (gimple_dump_bb_buff): Do not call dump_bb_header and dump_bb_end. + (gimple_dump_bb): Do it here with dump_gimple_bb_header and + dump_gimple_bb_footer. + * cfgrtl.c (rtl_dump_bb): Update prototype. Only dump DF if the + dump flags have TDF_DETAILS. Use dump_insn_slim if TDF_SLIM. + (print_rtl_with_bb): Take a flags argument and pass it around. + Use dump_insn_slim if TDF_SLIM. + (dump_bb_info): Removed and re-incarnated in cfg.c. + (dump_flow_info): Moved to cfghooks.c. + (debug_flow_info): Moved to cfghooks.c. + * passes.c (execute_function_dump): Unconditionally use + print_rtl_with_bb for RTL dumps, now that it understands TDF_SLIM. + * final.c (dump_basic_block_info): Update dump_edge_info calls. + * tree-vrp.c (dump_asserts_for): Likewise. + * ifcvt.c (if_convert): Unconditionally use print_rtl_with_bb. + * tree-if-conv.c (if_convertible_bb_p): Don't look at + EDGE_ABNORMAL_CALL, it has no meaning in the GIMPLE world. + * trans-mem.c (make_tm_edge): Don't set EDGE_ABNORMAL_CALL, + for the same reason. + * config/rl78/rl78.c (rl78_reorg): Update print_rtl_with_bb calls. + 2012-07-17 Richard Guenther <rguenther@suse.de> * tree-vect-data-refs.c (vect_get_new_vect_var): Add referenced diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 7a89ef5b43f..bf18baef139 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -55,7 +55,7 @@ struct GTY(()) edge_def { dest->preds. */ unsigned int dest_idx; - int flags; /* see EDGE_* below */ + int flags; /* see cfg-flags.def */ int probability; /* biased by REG_BR_PROB_BASE */ gcov_type count; /* Expected number of executions calculated in profile.c */ @@ -65,32 +65,20 @@ DEF_VEC_P(edge); DEF_VEC_ALLOC_P(edge,gc); DEF_VEC_ALLOC_P(edge,heap); -/* Always update the table in cfg.c dump_edge_info. */ -#define EDGE_FALLTHRU 0x0001 /* 'Straight line' flow */ -#define EDGE_ABNORMAL 0x0002 /* Strange flow, like computed - label, or eh */ -#define EDGE_ABNORMAL_CALL 0x0004 /* Call with abnormal exit - like an exception, or sibcall */ -#define EDGE_EH 0x0008 /* Exception throw */ -#define EDGE_FAKE 0x0010 /* Not a real edge (profile.c) */ -#define EDGE_DFS_BACK 0x0020 /* A backwards edge */ -#define EDGE_CAN_FALLTHRU 0x0040 /* Candidate for straight line - flow. */ -#define EDGE_IRREDUCIBLE_LOOP 0x0080 /* Part of irreducible loop. */ -#define EDGE_SIBCALL 0x0100 /* Edge from sibcall to exit. */ -#define EDGE_LOOP_EXIT 0x0200 /* Exit of a loop. */ -#define EDGE_TRUE_VALUE 0x0400 /* Edge taken when controlling - predicate is nonzero. */ -#define EDGE_FALSE_VALUE 0x0800 /* Edge taken when controlling - predicate is zero. */ -#define EDGE_EXECUTABLE 0x1000 /* Edge is executable. Only - valid during SSA-CCP. */ -#define EDGE_CROSSING 0x2000 /* Edge crosses between hot - and cold sections, when we - do partitioning. */ -#define EDGE_PRESERVE 0x4000 /* Never merge blocks via this edge. */ -#define EDGE_ALL_FLAGS 0x7fff +/* Masks for edge.flags. */ +#define DEF_EDGE_FLAG(NAME,IDX) EDGE_##NAME = 1 << IDX , +enum cfg_edge_flags { +#include "cfg-flags.def" + LAST_CFG_EDGE_FLAG /* this is only used for EDGE_ALL_FLAGS */ +}; +#undef DEF_EDGE_FLAG + +/* Bit mask for all edge flags. */ +#define EDGE_ALL_FLAGS ((LAST_CFG_EDGE_FLAG - 1) * 2 - 1) +/* The following four flags all indicate something special about an edge. + Test the edge flags on EDGE_COMPLEX to detect all forms of "strange" + control flow transfers. */ #define EDGE_COMPLEX \ (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_PRESERVE) @@ -184,10 +172,12 @@ struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_d /* Expected frequency. Normalized to be in range 0 to BB_FREQ_MAX. */ int frequency; - /* The discriminator for this block. */ + /* The discriminator for this block. The discriminator distinguishes + among several basic blocks that share a common locus, allowing for + more accurate sample-based profiling. */ int discriminator; - /* Various flags. See BB_* below. */ + /* Various flags. See cfg-flags.def. */ int flags; }; @@ -204,74 +194,19 @@ DEF_VEC_ALLOC_P(basic_block,heap); #define BB_FREQ_MAX 10000 -/* Masks for basic_block.flags. - - BB_HOT_PARTITION and BB_COLD_PARTITION should be preserved throughout - the compilation, so they are never cleared. - - All other flags may be cleared by clear_bb_flags(). It is generally - a bad idea to rely on any flags being up-to-date. - - Always update the table in cfg.c dump_bb_info. */ - -enum bb_flags +/* Masks for basic_block.flags. */ +#define DEF_BASIC_BLOCK_FLAG(NAME,IDX) BB_##NAME = 1 << IDX , +enum cfg_bb_flags { - /* Only set on blocks that have just been created by create_bb. */ - BB_NEW = 1 << 0, - - /* Set by find_unreachable_blocks. Do not rely on this being set in any - pass. */ - BB_REACHABLE = 1 << 1, - - /* Set for blocks in an irreducible loop by loop analysis. */ - BB_IRREDUCIBLE_LOOP = 1 << 2, - - /* Set on blocks that may actually not be single-entry single-exit block. */ - BB_SUPERBLOCK = 1 << 3, - - /* Set on basic blocks that the scheduler should not touch. This is used - by SMS to prevent other schedulers from messing with the loop schedule. */ - BB_DISABLE_SCHEDULE = 1 << 4, - - /* Set on blocks that should be put in a hot section. */ - BB_HOT_PARTITION = 1 << 5, - - /* Set on blocks that should be put in a cold section. */ - BB_COLD_PARTITION = 1 << 6, - - /* Set on block that was duplicated. */ - BB_DUPLICATED = 1 << 7, - - /* Set if the label at the top of this block is the target of a non-local goto. */ - BB_NON_LOCAL_GOTO_TARGET = 1 << 8, - - /* Set on blocks that are in RTL format. */ - BB_RTL = 1 << 9 , - - /* Set on blocks that are forwarder blocks. - Only used in cfgcleanup.c. */ - BB_FORWARDER_BLOCK = 1 << 10, - - /* Set on blocks that cannot be threaded through. - Only used in cfgcleanup.c. */ - BB_NONTHREADABLE_BLOCK = 1 << 11, - - /* Set on blocks that were modified in some way. This bit is set in - df_set_bb_dirty, but not cleared by df_analyze, so it can be used - to test whether a block has been modified prior to a df_analyze - call. */ - BB_MODIFIED = 1 << 12, - - /* A general visited flag for passes to use. */ - BB_VISITED = 1 << 13, - - /* Set on blocks that are in a transaction. This is calculated on - demand, and is available after calling - compute_transaction_bits(). */ - BB_IN_TRANSACTION = 1 << 14 +#include "cfg-flags.def" + LAST_CFG_BB_FLAG /* this is only used for BB_ALL_FLAGS */ }; +#undef DEF_BASIC_BLOCK_FLAG + +/* Bit mask for all edge flags. */ +#define BB_ALL_FLAGS ((LAST_CFG_BB_FLAG - 1) * 2 - 1) -/* Dummy flag for convenience in the hot/cold partitioning code. */ +/* Dummy bitmask for convenience in the hot/cold partitioning code. */ #define BB_UNPARTITIONED 0 /* Partitions, to be used when partitioning hot and cold basic blocks into @@ -458,8 +393,8 @@ 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 void dump_bb_info (basic_block, bool, bool, bool, const char *, FILE *); -extern void dump_edge_info (FILE *, edge, int); +extern void dump_bb_info (FILE *, basic_block, int, int, bool, bool); +extern void dump_edge_info (FILE *, edge, int, int); extern void brief_dump_cfg (FILE *); extern void clear_edges (void); extern void scale_bbs_frequencies_int (basic_block *, int, int, int); diff --git a/gcc/cfg-flags.def b/gcc/cfg-flags.def new file mode 100644 index 00000000000..a9aaf186ec1 --- /dev/null +++ b/gcc/cfg-flags.def @@ -0,0 +1,179 @@ +/* Flags on basic blocks and edges. + Copyright (C) 2012 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +/* This file defines flags that may appear on basic blocks or on + edges. Source files define DEF_BASIC_BLOCK_FLAG or DEF_EDGE_FLAG + appropriately before including this file. */ + +#if !defined(DEF_BASIC_BLOCK_FLAG) && !defined(DEF_EDGE_FLAG) +#error "You must define DEF_BASIC_BLOCK_FLAG or DEF_EDGE_FLAG" +#endif + +#ifdef DEF_BASIC_BLOCK_FLAG + +/* Masks for basic_block.flags. + + The format of this file is: DEF_BASIC_BLOCK_FLAG(NAME, IDX). + NAME is the name of the basic block flag. A flag BB_#NAME will be + created and the name is used in dump_edge_info. + IDX is a sequence number that is used to determine the value + of the flag, which is 1 << IDX). + + BB_HOT_PARTITION and BB_COLD_PARTITION should be preserved throughout + the compilation, so they are never cleared. + + All other flags may be cleared by clear_bb_flags(). It is generally + a bad idea to rely on any flags being up-to-date. */ + +/* Only set on blocks that have just been created by create_bb. */ +DEF_BASIC_BLOCK_FLAG(NEW, 0) + +/* Set by find_unreachable_blocks. Do not rely on this being set in any + pass. */ +DEF_BASIC_BLOCK_FLAG(REACHABLE, 1) + +/* Set for blocks in an irreducible loop by loop analysis. */ +DEF_BASIC_BLOCK_FLAG(IRREDUCIBLE_LOOP, 2) + +/* Set on blocks that may actually not be single-entry single-exit block. */ +DEF_BASIC_BLOCK_FLAG(SUPERBLOCK, 3) + +/* Set on basic blocks that the scheduler should not touch. This is used + by SMS to prevent other schedulers from messing with the loop schedule. */ +DEF_BASIC_BLOCK_FLAG(DISABLE_SCHEDULE, 4) + +/* Set on blocks that should be put in a hot section. */ +DEF_BASIC_BLOCK_FLAG(HOT_PARTITION, 5) + +/* Set on blocks that should be put in a cold section. */ +DEF_BASIC_BLOCK_FLAG(COLD_PARTITION, 6) + +/* Set on block that was duplicated. */ +DEF_BASIC_BLOCK_FLAG(DUPLICATED, 7) + +/* Set if the label at the top of this block is the target of a non-local goto. */ +DEF_BASIC_BLOCK_FLAG(NON_LOCAL_GOTO_TARGET, 8) + +/* Set on blocks that are in RTL format. */ +DEF_BASIC_BLOCK_FLAG(RTL, 9) + +/* Set on blocks that are forwarder blocks. + Only used in cfgcleanup.c. */ +DEF_BASIC_BLOCK_FLAG(FORWARDER_BLOCK, 10) + +/* Set on blocks that cannot be threaded through. + Only used in cfgcleanup.c. */ +DEF_BASIC_BLOCK_FLAG(NONTHREADABLE_BLOCK, 11) + +/* Set on blocks that were modified in some way. This bit is set in + df_set_bb_dirty, but not cleared by df_analyze, so it can be used + to test whether a block has been modified prior to a df_analyze call. */ +DEF_BASIC_BLOCK_FLAG(MODIFIED, 12) + +/* A general visited flag for passes to use. */ +DEF_BASIC_BLOCK_FLAG(VISITED, 13) + +/* Set on blocks that are in a transaction. This is calculated on + demand, and is available after calling + compute_transaction_bits(). */ +DEF_BASIC_BLOCK_FLAG(IN_TRANSACTION, 14) + +#endif + +#ifdef DEF_EDGE_FLAG + +/* Masks for edge.flags. + + The format of this file is: DEF_EDGE_FLAG(NAME, IDX, STRING). + NAME is the name of the edge flag. A flag EDGE_#NAME will be + created and the name is used in dump_edge_info. + IDX is a sequence number that is used to determine the value + of the flag, which is 1 << IDX). */ + +/* 'Straight line' flow. In GIMPLE and in cfglayout mode, all normal + edges are fallthru edges. In cfgrtl mode, this flag really means + that control flow falls through to the next basic block in the line. */ +DEF_EDGE_FLAG(FALLTHRU, 0) + +/* Strange flow, like a computed jump or exception handling. Usually + this means that the edge cannot be split. */ +DEF_EDGE_FLAG(ABNORMAL, 1) + +/* Edge out of a basic block that ends with a CALL_INSN with abnormal + exit, like an exception, or a sibcall. + This flag is only used for the RTL CFG. */ +DEF_EDGE_FLAG(ABNORMAL_CALL, 2) + +/* Exception edge. Exception handling edges represent possible control + transfers from a trapping instruction to an exception handler. EH + edges also have EDGE_ABNORMAL set. */ +DEF_EDGE_FLAG(EH, 3) + +/* Never merge blocks via this edge. This is used for exception handling, + to prevent merging away edges to the post-landing-pad basic block. + This flag is only used for the RTL CFG. */ +DEF_EDGE_FLAG(PRESERVE, 4) + +/* Not a real edge. This is used to connect parts of the CFG that do + not halt, such as infinite loops and noreturn functions, to the + EXIT_BLOCK, so that traversing of the reverse CFG is possible. */ +DEF_EDGE_FLAG(FAKE, 5) + +/* A back edge, marked in a depth-first search of the CFG. Back edges + are hints that this edge may be part of a loop in the CFG. */ +DEF_EDGE_FLAG(DFS_BACK, 6) + +/* Edge in a part of the CFG that is an irreducible loop. */ +DEF_EDGE_FLAG(IRREDUCIBLE_LOOP, 7) + +/* Edge taken when controlling predicate is nonzero. + This is only used for the GIMPLE CFG. */ +DEF_EDGE_FLAG(TRUE_VALUE, 8) + +/* Edge taken when controlling predicate is zero. + This is only used for the GIMPLE CFG. */ +DEF_EDGE_FLAG(FALSE_VALUE, 9) + +/* Edge is executable. This is only used in GIMPLE SSA-CCP and VRP. + This is only used for the GIMPLE CFG. */ +DEF_EDGE_FLAG(EXECUTABLE, 10) + +/* Edge crosses between hot and cold sections, when we do partitioning. + This flag is only used for the RTL CFG. */ +DEF_EDGE_FLAG(CROSSING, 11) + +/* Edge from a sibcall CALL_INSN to exit. + This flag is only used for the RTL CFG. */ +DEF_EDGE_FLAG(SIBCALL, 12) + +/* Candidate for straight line flow. Only used in bb-reorder.c. + This flag is only used for the RTL CFG. */ +DEF_EDGE_FLAG(CAN_FALLTHRU, 13) + +/* Exit of a loop. This is only used in ifcvt.c. + This flag is only used for the RTL CFG. */ +DEF_EDGE_FLAG(LOOP_EXIT, 14) + +#endif + +/* +Local variables: +mode:c +End: +*/ diff --git a/gcc/cfg.c b/gcc/cfg.c index b87318639c9..fc16ecd7f7d 100644 --- a/gcc/cfg.c +++ b/gcc/cfg.c @@ -444,9 +444,15 @@ check_bb_profile (basic_block bb, FILE * file) } void -dump_edge_info (FILE *file, edge e, int do_succ) +dump_edge_info (FILE *file, edge e, int flags, int do_succ) { basic_block side = (do_succ ? e->dest : e->src); + bool do_details = false; + + if ((flags & TDF_DETAILS) != 0 + && (flags & TDF_SLIM) == 0) + do_details = true; + /* ENTRY_BLOCK_PTR/EXIT_BLOCK_PTR depend on cfun. Compare against ENTRY_BLOCK/EXIT_BLOCK to avoid that dependency. */ if (side->index == ENTRY_BLOCK) @@ -456,25 +462,28 @@ dump_edge_info (FILE *file, edge e, int do_succ) else fprintf (file, " %d", side->index); - if (e->probability) + if (e->probability && do_details) fprintf (file, " [%.1f%%] ", e->probability * 100.0 / REG_BR_PROB_BASE); - if (e->count) + if (e->count && do_details) { fputs (" count:", file); fprintf (file, HOST_WIDEST_INT_PRINT_DEC, e->count); } - if (e->flags) + if (e->flags && do_details) { - static const char * const bitnames[] = { - "fallthru", "ab", "abcall", "eh", "fake", "dfs_back", - "can_fallthru", "irreducible", "sibcall", "loop_exit", - "true", "false", "exec", "crossing", "preserve" - }; - int comma = 0; + static const char * const bitnames[] = + { +#define DEF_EDGE_FLAG(NAME,IDX) #NAME , +#include "cfg-flags.def" + NULL +#undef DEF_EDGE_FLAG + }; + bool comma = false; int i, flags = e->flags; + gcc_assert (e->flags <= EDGE_ALL_FLAGS); fputs (" (", file); for (i = 0; flags; i++) if (flags & (1 << i)) @@ -483,11 +492,8 @@ dump_edge_info (FILE *file, edge e, int do_succ) if (comma) fputc (',', file); - if (i < (int) ARRAY_SIZE (bitnames)) - fputs (bitnames[i], file); - else - fprintf (file, "%d", i); - comma = 1; + fputs (bitnames[i], file); + comma = true; } fputc (')', file); @@ -641,57 +647,114 @@ free_aux_for_edges (void) DEBUG_FUNCTION void debug_bb (basic_block bb) { - dump_bb (bb, stderr, 0); + dump_bb (stderr, bb, 0, dump_flags | TDF_BLOCKS); } DEBUG_FUNCTION basic_block debug_bb_n (int n) { basic_block bb = BASIC_BLOCK (n); - dump_bb (bb, stderr, 0); + debug_bb (bb); return bb; } -/* Dumps cfg related information about basic block BB to FILE. */ +/* Dumps cfg related information about basic block BB to OUTF. + If HEADER is true, dump things that appear before the instructions + contained in BB. If FOOTER is true, dump things that appear after. + Flags are the TDF_* masks as documented in dumpfile.h. + NB: With TDF_DETAILS, it is assumed that cfun is available, so + that maybe_hot_bb_p and probably_never_executed_bb_p don't ICE. */ -static void -dump_cfg_bb_info (FILE *file, basic_block bb) +void +dump_bb_info (FILE *outf, basic_block bb, int indent, int flags, + bool do_header, bool do_footer) { - unsigned i; edge_iterator ei; - bool first = true; + edge e; static const char * const bb_bitnames[] = { - "new", "reachable", "irreducible_loop", "superblock", - "nosched", "hot", "cold", "dup", "xlabel", "rtl", - "fwdr", "nothrd" +#define DEF_BASIC_BLOCK_FLAG(NAME,IDX) #NAME , +#include "cfg-flags.def" + NULL +#undef DEF_BASIC_BLOCK_FLAG }; const unsigned n_bitnames = sizeof (bb_bitnames) / sizeof (char *); - edge e; + char *s_indent = (char *) alloca ((size_t) indent + 1); + memset ((void *) s_indent, ' ', (size_t) indent); + s_indent[indent] = '\0'; - fprintf (file, "Basic block %d", bb->index); - for (i = 0; i < n_bitnames; i++) - if (bb->flags & (1 << i)) - { - if (first) - fputs (" (", file); - else - fputs (", ", file); - first = false; - fputs (bb_bitnames[i], file); - } - if (!first) - putc (')', file); - putc ('\n', file); - - fputs ("Predecessors: ", file); - FOR_EACH_EDGE (e, ei, bb->preds) - dump_edge_info (file, e, 0); - - fprintf (file, "\nSuccessors: "); - FOR_EACH_EDGE (e, ei, bb->succs) - dump_edge_info (file, e, 1); - fputs ("\n\n", file); + gcc_assert (bb->flags <= BB_ALL_FLAGS); + + if (do_header) + { + unsigned i; + + if (flags & TDF_COMMENT) + fputs (";; ", outf); + fprintf (outf, "%sbasic block %d", s_indent, bb->index); + if (flags & TDF_DETAILS) + { + fprintf (outf, ", loop depth %d, count " HOST_WIDEST_INT_PRINT_DEC, + bb->loop_depth, (HOST_WIDEST_INT) bb->count); + fprintf (outf, ", freq %i", bb->frequency); + if (maybe_hot_bb_p (bb)) + fputs (", maybe hot", outf); + if (probably_never_executed_bb_p (bb)) + fputs (", probably never executed", outf); + } + fputc ('\n', outf); + + if (flags & TDF_DETAILS) + { + bool first = true; + + if (flags & TDF_COMMENT) + fputs (";; ", outf); + fprintf (outf, "%s prev block ", s_indent); + if (bb->prev_bb) + fprintf (outf, "%d", bb->prev_bb->index); + else + fprintf (outf, "(nil)"); + fprintf (outf, ", next block "); + if (bb->next_bb) + fprintf (outf, "%d", bb->next_bb->index); + else + fprintf (outf, "(nil)"); + + fputs (", flags:", outf); + for (i = 0; i < n_bitnames; i++) + if (bb->flags & (1 << i)) + { + if (first) + fputs (" (", outf); + else + fputs (", ", outf); + first = false; + fputs (bb_bitnames[i], outf); + } + if (!first) + fputc (')', outf); + } + fputc ('\n', outf); + + if (flags & TDF_COMMENT) + fputs (";; ", outf); + fprintf (outf, "%s pred: ", s_indent); + FOR_EACH_EDGE (e, ei, bb->preds) + dump_edge_info (outf, e, flags, 0); + fputc ('\n', outf); + } + + if (do_footer) + { + fputc ('\n', outf); + if (flags & TDF_COMMENT) + fputs (";; ", outf); + fprintf (outf, "%s succ: ", s_indent); + FOR_EACH_EDGE (e, ei, bb->succs) + dump_edge_info (outf, e, flags, 1); + fputs ("\n\n", outf); + } } /* Dumps a brief description of cfg to FILE. */ @@ -703,7 +766,7 @@ brief_dump_cfg (FILE *file) FOR_EACH_BB (bb) { - dump_cfg_bb_info (file, bb); + dump_bb_info (file, bb, 0, 0, true, true); } } diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index 07cbad6462f..69655390102 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "dumpfile.h" #include "tm.h" #include "tree.h" #include "rtl.h" @@ -183,9 +184,9 @@ verify_flow_info (void) error ("verify_flow_info: Basic block %d succ edge is corrupted", bb->index); fprintf (stderr, "Predecessor: "); - dump_edge_info (stderr, e, 0); + dump_edge_info (stderr, e, TDF_DETAILS, 0); fprintf (stderr, "\nSuccessor: "); - dump_edge_info (stderr, e, 1); + dump_edge_info (stderr, e, TDF_DETAILS, 1); fprintf (stderr, "\n"); err = 1; } @@ -204,9 +205,9 @@ verify_flow_info (void) { error ("basic block %d pred edge is corrupted", bb->index); fputs ("Predecessor: ", stderr); - dump_edge_info (stderr, e, 0); + dump_edge_info (stderr, e, TDF_DETAILS, 0); fputs ("\nSuccessor: ", stderr); - dump_edge_info (stderr, e, 1); + dump_edge_info (stderr, e, TDF_DETAILS, 1); fputc ('\n', stderr); err = 1; } @@ -217,9 +218,9 @@ verify_flow_info (void) error ("its dest_idx should be %d, not %d", ei.index, e->dest_idx); fputs ("Predecessor: ", stderr); - dump_edge_info (stderr, e, 0); + dump_edge_info (stderr, e, TDF_DETAILS, 0); fputs ("\nSuccessor: ", stderr); - dump_edge_info (stderr, e, 1); + dump_edge_info (stderr, e, TDF_DETAILS, 1); fputc ('\n', stderr); err = 1; } @@ -260,50 +261,43 @@ verify_flow_info (void) timevar_pop (TV_CFG_VERIFY); } -/* Print out one basic block. This function takes care of the purely - graph related information. The cfg hook for the active representation - should dump representation-specific information. */ +/* Print out one basic block BB to file OUTF. INDENT is printed at the + start of each new line. FLAGS are the TDF_* flags in dumpfile.h. + + This function takes care of the purely graph related information. + The cfg hook for the active representation should dump + representation-specific information. */ void -dump_bb (basic_block bb, FILE *outf, int indent) +dump_bb (FILE *outf, basic_block bb, int indent, int flags) { - edge e; - edge_iterator ei; - char *s_indent; - - s_indent = (char *) alloca ((size_t) indent + 1); - memset (s_indent, ' ', (size_t) indent); - s_indent[indent] = '\0'; - - fprintf (outf, ";;%s basic block %d, loop depth %d, count ", - s_indent, bb->index, bb->loop_depth); - fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count); - putc ('\n', outf); + dump_bb_info (outf, bb, indent, flags | TDF_COMMENT, true, true); + if (cfg_hooks->dump_bb) + cfg_hooks->dump_bb (outf, bb, indent, flags); +} - fprintf (outf, ";;%s prev block ", s_indent); - if (bb->prev_bb) - fprintf (outf, "%d, ", bb->prev_bb->index); - else - fprintf (outf, "(nil), "); - fprintf (outf, "next block "); - if (bb->next_bb) - fprintf (outf, "%d", bb->next_bb->index); - else - fprintf (outf, "(nil)"); - putc ('\n', outf); +/* Dump the complete CFG to FILE. FLAGS are the TDF_* flags in dumpfile.h. */ +void +dump_flow_info (FILE *file, int flags) +{ + basic_block bb; - fprintf (outf, ";;%s pred: ", s_indent); - FOR_EACH_EDGE (e, ei, bb->preds) - dump_edge_info (outf, e, 0); - putc ('\n', outf); + fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges); + FOR_ALL_BB (bb) + { + dump_bb (file, bb, 0, flags); + check_bb_profile (bb, file); + } - fprintf (outf, ";;%s succ: ", s_indent); - FOR_EACH_EDGE (e, ei, bb->succs) - dump_edge_info (outf, e, 1); - putc ('\n', outf); + putc ('\n', file); +} - if (cfg_hooks->dump_bb) - cfg_hooks->dump_bb (bb, outf, indent, 0); +/* Like above, but dump to stderr. To be called from debuggers. */ +void debug_flow_info (void); +DEBUG_FUNCTION void +debug_flow_info (void) +{ + dump_flow_info (stderr, TDF_DETAILS); } /* Redirect edge E to the given basic block DEST and update underlying program diff --git a/gcc/cfghooks.h b/gcc/cfghooks.h index adf6a893b00..cd4bd4165ec 100644 --- a/gcc/cfghooks.h +++ b/gcc/cfghooks.h @@ -28,7 +28,7 @@ struct cfg_hooks /* Debugging. */ int (*verify_flow_info) (void); - void (*dump_bb) (basic_block, FILE *, int, int); + void (*dump_bb) (FILE *, basic_block, int, int); /* Basic CFG manipulation. */ @@ -141,7 +141,7 @@ struct cfg_hooks }; extern void verify_flow_info (void); -extern void dump_bb (basic_block, FILE *, int); +extern void dump_bb (FILE *, basic_block, int, int); extern edge redirect_edge_and_branch (edge, basic_block); extern basic_block redirect_edge_and_branch_force (edge, basic_block); extern bool can_remove_branch_p (const_edge); diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 34e8bd45b81..e87f06db3a0 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -88,7 +88,7 @@ static void rtl_delete_block (basic_block); static basic_block rtl_redirect_edge_and_branch_force (edge, basic_block); static edge rtl_redirect_edge_and_branch (edge, basic_block); static basic_block rtl_split_block (basic_block, void *); -static void rtl_dump_bb (basic_block, FILE *, int, int); +static void rtl_dump_bb (FILE *, basic_block, int, int); static int rtl_verify_flow_info_1 (void); static void rtl_make_forwarder_block (edge); @@ -1836,10 +1836,11 @@ commit_edge_insertions (void) /* Print out RTL-specific basic block information (live information - at start and end). */ + at start and end with TDF_DETAILS). FLAGS are the TDF_* masks + documented in dumpfile.h. */ static void -rtl_dump_bb (basic_block bb, FILE *outf, int indent, int flags ATTRIBUTE_UNUSED) +rtl_dump_bb (FILE *outf, basic_block bb, int indent, int flags) { rtx insn; rtx last; @@ -1849,7 +1850,7 @@ rtl_dump_bb (basic_block bb, FILE *outf, int indent, int flags ATTRIBUTE_UNUSED) memset (s_indent, ' ', (size_t) indent); s_indent[indent] = '\0'; - if (df) + if (df && (flags & TDF_DETAILS)) { df_dump_top (bb, outf); putc ('\n', outf); @@ -1858,9 +1859,15 @@ rtl_dump_bb (basic_block bb, FILE *outf, int indent, int flags ATTRIBUTE_UNUSED) if (bb->index != ENTRY_BLOCK && bb->index != EXIT_BLOCK) for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb)); insn != last; insn = NEXT_INSN (insn)) - print_rtl_single (outf, insn); + { + if (! (flags & TDF_SLIM)) + print_rtl_single (outf, insn); + else + dump_insn_slim (outf, insn); + + } - if (df) + if (df && (flags & TDF_DETAILS)) { df_dump_bottom (bb, outf); putc ('\n', outf); @@ -1869,10 +1876,10 @@ rtl_dump_bb (basic_block bb, FILE *outf, int indent, int flags ATTRIBUTE_UNUSED) } /* Like print_rtl, but also print out live information for the start of each - basic block. */ + basic block. FLAGS are the flags documented in dumpfile.h. */ void -print_rtl_with_bb (FILE *outf, const_rtx rtx_first) +print_rtl_with_bb (FILE *outf, const_rtx rtx_first, int flags) { const_rtx tmp_rtx; if (rtx_first == 0) @@ -1911,12 +1918,9 @@ 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, verbose, ";; ", outf); + dump_bb_info (outf, bb, 0, dump_flags | TDF_COMMENT, true, false); if (in_bb_p[INSN_UID (tmp_rtx)] == NOT_IN_BB && !NOTE_P (tmp_rtx) @@ -1925,13 +1929,16 @@ print_rtl_with_bb (FILE *outf, const_rtx rtx_first) else if (in_bb_p[INSN_UID (tmp_rtx)] == IN_MULTIPLE_BB) fprintf (outf, ";; Insn is in multiple basic blocks\n"); - did_output = print_rtl_single (outf, tmp_rtx); + if (! (flags & TDF_SLIM)) + print_rtl_single (outf, tmp_rtx); + else + dump_insn_slim (outf, tmp_rtx); bb = end[INSN_UID (tmp_rtx)]; if (bb != NULL) - dump_bb_info (bb, false, true, verbose, ";; ", outf); - if (did_output) - putc ('\n', outf); + dump_bb_info (outf, bb, 0, dump_flags | TDF_COMMENT, false, true); + + putc ('\n', outf); } free (start); @@ -1948,113 +1955,6 @@ print_rtl_with_bb (FILE *outf, const_rtx rtx_first) } } -/* Emit basic block information for BB. HEADER is true if the user wants - the generic information and the predecessors, FOOTER is true if they want - the successors. If VERBOSE is true, emit global register liveness - information. PREFIX is put in front of every line. The output is emitted - to FILE. This function should only be called by RTL CFG users. */ -/* FIXME: Dumping of the basic block shared info (index, prev, next, etc.) - is done here and also in dump_bb_header (but to a pretty-printer buffer). - This should be re-factored to give similar dumps for RTL and GIMPLE. */ - -void -dump_bb_info (basic_block bb, bool header, bool footer, bool verbose, - const char *prefix, FILE *file) -{ - edge e; - edge_iterator ei; - - if (header) - { - fprintf (file, "\n%sBasic block %d ", prefix, bb->index); - if (bb->prev_bb) - fprintf (file, ", prev %d", bb->prev_bb->index); - if (bb->next_bb) - fprintf (file, ", next %d", bb->next_bb->index); - fprintf (file, ", loop_depth %d, count ", bb->loop_depth); - fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count); - fprintf (file, ", freq %i", bb->frequency); - if (maybe_hot_bb_p (bb)) - fputs (", maybe hot", file); - if (probably_never_executed_bb_p (bb)) - fputs (", probably never executed", file); - if (bb->flags) - { - static const char * const bits[] = { - "new", "reachable", "irr_loop", "superblock", "disable_sched", - "hot_partition", "cold_partition", "duplicated", - "non_local_goto_target", "rtl", "forwarder", "nonthreadable", - "modified" - }; - unsigned int flags; - - fputs (", flags:", file); - for (flags = bb->flags; flags ; flags &= flags - 1) - { - unsigned i = ctz_hwi (flags); - if (i < ARRAY_SIZE (bits)) - fprintf (file, " %s", bits[i]); - else - fprintf (file, " <%d>", i); - } - } - fputs (".\n", file); - - fprintf (file, "%sPredecessors: ", prefix); - FOR_EACH_EDGE (e, ei, bb->preds) - dump_edge_info (file, e, 0); - - if (verbose - && (bb->flags & BB_RTL) - && df) - { - putc ('\n', file); - df_dump_top (bb, file); - } - } - - if (footer) - { - fprintf (file, "\n%sSuccessors: ", prefix); - FOR_EACH_EDGE (e, ei, bb->succs) - dump_edge_info (file, e, 1); - - if (verbose - && (bb->flags & BB_RTL) - && df) - { - putc ('\n', file); - df_dump_bottom (bb, file); - } - } - - putc ('\n', file); -} - - -void -dump_flow_info (FILE *file, int flags) -{ - basic_block bb; - bool verbose = ((flags & TDF_DETAILS) != 0); - - fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges); - FOR_ALL_BB (bb) - { - dump_bb_info (bb, true, true, verbose, "", file); - check_bb_profile (bb, file); - } - - putc ('\n', file); -} - -void debug_flow_info (void); -DEBUG_FUNCTION void -debug_flow_info (void) -{ - dump_flow_info (stderr, TDF_DETAILS); -} - /* Update the branch probability of BB if a REG_BR_PROB is present. */ void diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c index f1193528adc..df41a85278a 100644 --- a/gcc/config/rl78/rl78.c +++ b/gcc/config/rl78/rl78.c @@ -2663,7 +2663,7 @@ rl78_reorg (void) if (dump_file) { fprintf (dump_file, "\n================DEVIRT:=AFTER=ALLOC=PHYSICAL=REGISTERS================\n"); - print_rtl_with_bb (dump_file, get_insns ()); + print_rtl_with_bb (dump_file, get_insns (), 0); } rl78_propogate_register_origins (); @@ -2672,7 +2672,7 @@ rl78_reorg (void) if (dump_file) { fprintf (dump_file, "\n================DEVIRT:=AFTER=PROPOGATION=============================\n"); - print_rtl_with_bb (dump_file, get_insns ()); + print_rtl_with_bb (dump_file, get_insns (), 0); fprintf (dump_file, "\n======================================================================\n"); } diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h index 936186a8596..2ea3901b32e 100644 --- a/gcc/dumpfile.h +++ b/gcc/dumpfile.h @@ -81,6 +81,7 @@ enum tree_dump_index #define TDF_ENUMERATE_LOCALS (1 << 22) /* Enumerate locals by uid. */ #define TDF_CSELIB (1 << 23) /* Dump cselib details. */ #define TDF_SCEV (1 << 24) /* Dump SCEV details. */ +#define TDF_COMMENT (1 << 25) /* Dump lines with prefix ";;" */ /* In tree-dump.c */ diff --git a/gcc/final.c b/gcc/final.c index cd49648179a..7db047104fb 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1799,7 +1799,7 @@ dump_basic_block_info (FILE *file, rtx insn, basic_block *start_to_bb, fprintf (file, "\n%s PRED:", ASM_COMMENT_START); FOR_EACH_EDGE (e, ei, bb->preds) { - dump_edge_info (file, e, 0); + dump_edge_info (file, e, TDF_DETAILS, 0); } fprintf (file, "\n"); } @@ -1812,7 +1812,7 @@ dump_basic_block_info (FILE *file, rtx insn, basic_block *start_to_bb, fprintf (asm_out_file, "%s SUCC:", ASM_COMMENT_START); FOR_EACH_EDGE (e, ei, bb->succs) { - dump_edge_info (asm_out_file, e, 1); + dump_edge_info (asm_out_file, e, TDF_DETAILS, 1); } fprintf (file, "\n"); } diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index fc38f8f1302..febf1d98dbc 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -2059,83 +2059,52 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags) } -/* Dumps header of basic block BB to buffer BUFFER indented by INDENT +/* Dumps header of basic block BB to OUTF indented by INDENT spaces and details described by flags. */ static void -dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags) +dump_gimple_bb_header (FILE *outf, basic_block bb, int indent, int flags) { - edge e; - gimple stmt; - edge_iterator ei; - if (flags & TDF_BLOCKS) { - INDENT (indent); - pp_string (buffer, "# BLOCK "); - pp_decimal_int (buffer, bb->index); - if (bb->frequency) - { - pp_string (buffer, " freq:"); - pp_decimal_int (buffer, bb->frequency); - } - if (bb->count) - { - pp_string (buffer, " count:"); - pp_widest_integer (buffer, bb->count); - } + dump_bb_info (outf, bb, indent, flags, true, false); if (flags & TDF_LINENO) { gimple_stmt_iterator gsi; + char *s_indent = (char *) alloca ((size_t) indent + 1); + memset (s_indent, ' ', (size_t) indent); + s_indent[indent] = '\0'; + + if (flags & TDF_COMMENT) + fputs (";; ", outf); for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) if (!is_gimple_debug (gsi_stmt (gsi)) && get_lineno (gsi_stmt (gsi)) != UNKNOWN_LOCATION) { - pp_string (buffer, ", starting at line "); - pp_decimal_int (buffer, get_lineno (gsi_stmt (gsi))); + fprintf (outf, "%sstarting at line %d", + s_indent, get_lineno (gsi_stmt (gsi))); break; } - - if (bb->discriminator) - { - pp_string (buffer, ", discriminator "); - pp_decimal_int (buffer, bb->discriminator); - } + if (bb->discriminator) + fprintf (outf, ", discriminator %i", bb->discriminator); + fputc ('\n', outf); } - newline_and_indent (buffer, indent); - - pp_string (buffer, "# PRED:"); - pp_write_text_to_stream (buffer); - FOR_EACH_EDGE (e, ei, bb->preds) - if (flags & TDF_SLIM) - { - pp_character (buffer, ' '); - if (e->src == ENTRY_BLOCK_PTR) - pp_string (buffer, "ENTRY"); - else - pp_decimal_int (buffer, e->src->index); - } - else - dump_edge_info (buffer->buffer->stream, e, 0); - pp_newline (buffer); } else { - stmt = first_stmt (bb); + gimple stmt = first_stmt (bb); if (!stmt || gimple_code (stmt) != GIMPLE_LABEL) { - INDENT (indent - 2); - pp_string (buffer, "<bb "); - pp_decimal_int (buffer, bb->index); - pp_string (buffer, ">:"); - pp_newline (buffer); + char *s_indent = (char *) alloca ((size_t) indent - 2 + 1); + memset (s_indent, ' ', (size_t) indent); + s_indent[indent] = '\0'; + fprintf (outf, "%s<bb %d>:\n", s_indent, bb->index); } } - pp_write_text_to_stream (buffer); if (cfun) - check_bb_profile (bb, buffer->buffer->stream); + check_bb_profile (bb, outf); } @@ -2143,26 +2112,9 @@ dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags) spaces. */ static void -dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags) +dump_gimple_bb_footer (FILE *outf, basic_block bb, int indent, int flags) { - edge e; - edge_iterator ei; - - INDENT (indent); - pp_string (buffer, "# SUCC:"); - pp_write_text_to_stream (buffer); - FOR_EACH_EDGE (e, ei, bb->succs) - if (flags & TDF_SLIM) - { - pp_character (buffer, ' '); - if (e->dest == EXIT_BLOCK_PTR) - pp_string (buffer, "EXIT"); - else - pp_decimal_int (buffer, e->dest->index); - } - else - dump_edge_info (buffer->buffer->stream, e, 1); - pp_newline (buffer); + dump_bb_info (outf, bb, indent, flags, false, true); } @@ -2292,7 +2244,6 @@ gimple_dump_bb_buff (pretty_printer *buffer, basic_block bb, int indent, if (label_indent < 0) label_indent = 0; - dump_bb_header (buffer, bb, indent, flags); dump_phi_nodes (buffer, bb, indent, flags); for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) @@ -2310,9 +2261,6 @@ gimple_dump_bb_buff (pretty_printer *buffer, basic_block bb, int indent, } dump_implicit_edges (buffer, bb, indent, flags); - - if (flags & TDF_BLOCKS) - dump_bb_end (buffer, bb, indent, flags); } @@ -2320,9 +2268,11 @@ gimple_dump_bb_buff (pretty_printer *buffer, basic_block bb, int indent, indented by INDENT spaces. */ void -gimple_dump_bb (basic_block bb, FILE *file, int indent, int flags) +gimple_dump_bb (FILE *file, basic_block bb, int indent, int flags) { + dump_gimple_bb_header (file, bb, indent, flags); maybe_init_pretty_print (file); gimple_dump_bb_buff (&buffer, bb, indent, flags); pp_flush (&buffer); + dump_gimple_bb_footer (file, bb, indent, flags); } diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index d4718f913fa..08a9755649a 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -4391,12 +4391,7 @@ if_convert (void) #ifdef IFCVT_MULTIPLE_DUMPS if (dump_file && cond_exec_changed_p) - { - if (dump_flags & TDF_SLIM) - print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags); - else - print_rtl_with_bb (dump_file, get_insns ()); - } + print_rtl_with_bb (dump_file, get_insns (), dump_flags); #endif } while (cond_exec_changed_p); diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index 13760832c48..14d3e0a6794 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -675,7 +675,7 @@ find_defs (struct loop *loop, basic_block *body) { df_dump_region (dump_file); fprintf (dump_file, "*****starting processing of loop ******\n"); - print_rtl_with_bb (dump_file, get_insns ()); + print_rtl_with_bb (dump_file, get_insns (), dump_flags); fprintf (dump_file, "*****ending processing of loop ******\n"); } check_invariant_table_size (); diff --git a/gcc/passes.c b/gcc/passes.c index dfd797ac716..5612a35a867 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -1725,11 +1725,9 @@ execute_function_dump (void *data ATTRIBUTE_UNUSED) dump_function_to_file (current_function_decl, dump_file, dump_flags); else { - if (dump_flags & TDF_SLIM) - print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags); - else if ((cfun->curr_properties & PROP_cfg) - && (dump_flags & TDF_BLOCKS)) - print_rtl_with_bb (dump_file, get_insns ()); + if ((cfun->curr_properties & PROP_cfg) + && (dump_flags & TDF_BLOCKS)) + print_rtl_with_bb (dump_file, get_insns (), dump_flags); else print_rtl (dump_file, get_insns ()); diff --git a/gcc/profile.c b/gcc/profile.c index c5e60b66dcf..99a22f274a8 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -276,8 +276,8 @@ is_edge_inconsistent (VEC(edge,gc) *edges) fprintf (dump_file, "Edge %i->%i is inconsistent, count"HOST_WIDEST_INT_PRINT_DEC, e->src->index, e->dest->index, e->count); - dump_bb (e->src, dump_file, 0); - dump_bb (e->dest, dump_file, 0); + dump_bb (dump_file, e->src, 0, TDF_DETAILS); + dump_bb (dump_file, e->dest, 0, TDF_DETAILS); } return true; } @@ -326,7 +326,7 @@ is_inconsistent (void) HOST_WIDEST_INT_PRINT_DEC, bb->index, bb->count); - dump_bb (bb, dump_file, 0); + dump_bb (dump_file, bb, 0, TDF_DETAILS); } inconsistent = true; } @@ -339,7 +339,7 @@ is_inconsistent (void) bb->index, bb->count, sum_edge_counts (bb->preds)); - dump_bb (bb, dump_file, 0); + dump_bb (dump_file, bb, 0, TDF_DETAILS); } inconsistent = true; } @@ -353,7 +353,7 @@ is_inconsistent (void) bb->index, bb->count, sum_edge_counts (bb->succs)); - dump_bb (bb, dump_file, 0); + dump_bb (dump_file, bb, 0, TDF_DETAILS); } inconsistent = true; } diff --git a/gcc/rtl.h b/gcc/rtl.h index 425bccf3000..1b136597452 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -2460,12 +2460,7 @@ extern void dump_combine_total_stats (FILE *); extern void delete_dead_jumptables (void); /* In sched-vis.c. */ -extern void debug_bb_n_slim (int); -extern void debug_bb_slim (basic_block); -extern void print_rtl_slim (FILE *, rtx, rtx, int, int); -extern void print_rtl_slim_with_bb (FILE *, rtx, int); -extern void dump_insn_slim (FILE *f, rtx x); -extern void debug_insn_slim (rtx x); +extern void dump_insn_slim (FILE *, const_rtx x); /* In sched-rgn.c. */ extern void schedule_insns (void); @@ -2508,7 +2503,7 @@ extern HOST_WIDE_INT find_args_size_adjust (rtx); extern int fixup_args_size_notes (rtx, rtx, int); /* In cfgrtl.c */ -extern void print_rtl_with_bb (FILE *, const_rtx); +extern void print_rtl_with_bb (FILE *, const_rtx, int); extern rtx duplicate_insn_chain (rtx, rtx); /* In expmed.c */ diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c index 97edfae27d5..69645b4ff49 100644 --- a/gcc/sched-rgn.c +++ b/gcc/sched-rgn.c @@ -396,7 +396,8 @@ debug_region (int rgn) for (bb = 0; bb < rgn_table[rgn].rgn_nr_blocks; bb++) { - debug_bb_n_slim (rgn_bb_table[current_blocks + bb]); + dump_bb (stderr, BASIC_BLOCK (rgn_bb_table[current_blocks + bb]), + 0, TDF_SLIM); fprintf (stderr, "\n"); } diff --git a/gcc/sched-vis.c b/gcc/sched-vis.c index 44c7d595eaf..768aa133522 100644 --- a/gcc/sched-vis.c +++ b/gcc/sched-vis.c @@ -761,7 +761,7 @@ print_insn (char *buf, const_rtx x, int verbose) /* Emit a slim dump of X (an insn) to the file F, including any register note attached to the instruction. */ void -dump_insn_slim (FILE *f, rtx x) +dump_insn_slim (FILE *f, const_rtx x) { char t[BUF_LEN + 32]; rtx note; @@ -779,65 +779,41 @@ dump_insn_slim (FILE *f, rtx x) } /* Emit a slim dump of X (an insn) to stderr. */ +extern void debug_insn_slim (const_rtx); DEBUG_FUNCTION void -debug_insn_slim (rtx x) +debug_insn_slim (const_rtx x) { dump_insn_slim (stderr, x); } -/* Provide a slim dump the instruction chain starting at FIRST to F, honoring - the dump flags given in FLAGS. Currently, TDF_BLOCKS and TDF_DETAILS - include more information on the basic blocks. */ -void -print_rtl_slim_with_bb (FILE *f, rtx first, int flags) -{ - print_rtl_slim (f, first, NULL, -1, flags); -} - /* Same as above, but stop at LAST or when COUNT == 0. If COUNT < 0 it will stop only at LAST or NULL rtx. */ -void -print_rtl_slim (FILE *f, rtx first, rtx last, int count, int flags) +extern void debug_rtl_slim (FILE *, const_rtx, const_rtx, int, int); +DEBUG_FUNCTION void +debug_rtl_slim (FILE *f, const_rtx first, const_rtx last, + int count, int flags ATTRIBUTE_UNUSED) { - basic_block current_bb = NULL; - rtx insn, tail; + const_rtx insn, tail; tail = last ? NEXT_INSN (last) : NULL_RTX; for (insn = first; (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, verbose, ";; ", f); - } - dump_insn_slim (f, insn); - - if ((flags & TDF_BLOCKS) - && current_bb - && insn == BB_END (current_bb)) - { - dump_bb_info (current_bb, false, true, verbose, ";; ", f); - current_bb = NULL; - } if (count > 0) count--; } } +extern void debug_bb_slim (basic_block); DEBUG_FUNCTION void debug_bb_slim (basic_block bb) { - print_rtl_slim (stderr, BB_HEAD (bb), BB_END (bb), -1, 32); + dump_bb (stderr, bb, 0, TDF_SLIM); } +extern void debug_bb_n_slim (int); DEBUG_FUNCTION void debug_bb_n_slim (int n) { diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index 77a33bc7631..cdb0a8abc10 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -2576,7 +2576,7 @@ make_tm_edge (gimple stmt, basic_block bb, struct tm_region *region) n->label_or_list = tree_cons (NULL, dummy.label_or_list, old); } - make_edge (bb, region->entry_block, EDGE_ABNORMAL | EDGE_ABNORMAL_CALL); + make_edge (bb, region->entry_block, EDGE_ABNORMAL); } diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index c6ccdfe3799..e4cf076f28b 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -1448,7 +1448,7 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b) if (!single_succ_p (a)) return false; - if (single_succ_edge (a)->flags & (EDGE_ABNORMAL | EDGE_EH | EDGE_PRESERVE)) + if (single_succ_edge (a)->flags & EDGE_COMPLEX) return false; if (single_succ (a) != b) @@ -1844,7 +1844,7 @@ remove_bb (basic_block bb) fprintf (dump_file, "Removing basic block %d\n", bb->index); if (dump_flags & TDF_DETAILS) { - dump_bb (bb, dump_file, 0); + dump_bb (dump_file, bb, 0, 0); fprintf (dump_file, "\n"); } } @@ -2063,7 +2063,7 @@ find_case_label_for_value (gimple switch_stmt, tree val) void gimple_debug_bb (basic_block bb) { - gimple_dump_bb (bb, stderr, 0, TDF_VOPS|TDF_MEMSYMS); + dump_bb (stderr, bb, 0, TDF_VOPS|TDF_MEMSYMS); } @@ -6695,7 +6695,7 @@ dump_function_to_file (tree fn, FILE *file, int flags) fprintf (file, "\n"); FOR_EACH_BB (bb) - gimple_dump_bb (bb, file, 2, flags); + gimple_dump_bb (file, bb, 2, flags); fprintf (file, "}\n"); check_bb_profile (EXIT_BLOCK_PTR, file); @@ -6821,7 +6821,7 @@ print_loops_bb (FILE *file, basic_block bb, int indent, int verbosity) if (verbosity >= 3) { fprintf (file, "%s {\n", s_indent); - gimple_dump_bb (bb, file, indent + 4, TDF_VOPS|TDF_MEMSYMS); + gimple_dump_bb (file, bb, indent + 4, TDF_VOPS|TDF_MEMSYMS); fprintf (file, "%s }\n", s_indent); } } diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 61742c424db..061a3f8dab5 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -414,7 +414,7 @@ extern bool is_ctrl_altering_stmt (gimple); extern bool simple_goto_p (gimple); extern bool stmt_can_make_abnormal_goto (gimple); extern basic_block single_noncomplex_succ (basic_block bb); -extern void gimple_dump_bb (basic_block, FILE *, int, int); +extern void gimple_dump_bb (FILE *, basic_block, int, int); extern void gimple_debug_bb (basic_block); extern basic_block gimple_debug_bb_n (int); extern void gimple_dump_cfg (FILE *, int); diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 1b816fb57b2..89747b3a275 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -819,8 +819,7 @@ if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb) /* Be less adventurous and handle only normal edges. */ FOR_EACH_EDGE (e, ei, bb->succs) - if (e->flags & - (EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP)) + if (e->flags & (EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Difficult to handle edges\n"); diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index f224c6f5b39..66cc4066830 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4121,7 +4121,7 @@ dump_asserts_for (FILE *file, tree name) { fprintf (file, "\n\tEDGE %d->%d", loc->e->src->index, loc->e->dest->index); - dump_edge_info (file, loc->e, 0); + dump_edge_info (file, loc->e, dump_flags, 0); } fprintf (file, "\n\tPREDICATE: "); print_generic_expr (file, name, 0); |