This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Use sched-vis if asked for slim RTL dumps
- From: Paolo Bonzini <paolo dot bonzini at lu dot unisi dot ch>
- To: Vladimir Makarov <vmakarov at redhat dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 19 Jan 2006 17:05:14 +0100
- Subject: Re: [PATCH] Use sched-vis if asked for slim RTL dumps
- References: <43CE3990.2040303@lu.unisi.ch> <43CFB414.6060503@redhat.com>
I like a lot the idea to have a slim dump of RTL. It is really useful
therefore it is not the 1st try to do it. As I remember the new
register allocator had it too. Saying that I have no rights to
approve the patch because most changes not in the scheduler.
I see. In fact, I CCed you mostly because I suppose you have experience
with the sched-vis output and could tell if it is "too" slim for
practical use. I just tried reusing what was there, rather than spend
time thinking of what should/should not go into the dump, and coding it
for the n-th time. For example that it's missing the original variable
names, which somebody may like to have. Also, I'd like to have more
spacing in the operators, but that's not essential for now.
The attached patch fixes the problems that Vladimir pointed out. Since
the only changes to the code are function names and comments, I only
built cc1 powerpc-apple-darwin8.4.0 for now. Of course if the patch is
approved, I will bootstrap/regtest before committing. However, note
that the sched-vis code in the patch is not exercised in the testsuite
run.
Paolo
2006-01-18 Paolo Bonzini <bonzini@gnu.org>
* Makefile.in (sched-vis.o): Update dependencies.
* haifa-sched.c (sched_finish): Clear current_sched_info.
* cfg.c (dump_bb_info): New, split from dump_flow_info.
(dump_flow_info): Call it.
* passes.c (execute_todo): Call print_rtl_slim_with_bb to make
a slim RTL dump.
* basic-block.h (dump_bb_info): Declare.
* tree-dump.c (dump_enable_all): Fix bug with -fdump-tree-all-blocks
-fdump-rtl-all-blocks.
* rtl.h: Declare new functions exported from sched-vis.c.
* sched-vis.c: Enable also if scheduling is not used.
(print_value): Print the mode of registers if not inside scheduling.
(print_insn): Make it work outside the scheduler. Beautify the output
a bit.
(dump_insn_slim, debug_insn_slim, print_rtl_slim_with_bb): New.
Index: haifa-sched.c
===================================================================
--- haifa-sched.c (revision 108713)
+++ haifa-sched.c (working copy)
@@ -2362,5 +2362,7 @@ sched_finish (void)
if (targetm.sched.md_finish_global)
targetm.sched.md_finish_global (sched_dump, sched_verbose);
+
+ current_sched_info = NULL;
}
#endif /* INSN_SCHEDULING */
Index: cfg.c
===================================================================
--- cfg.c (revision 108713)
+++ cfg.c (working copy)
@@ -62,6 +62,7 @@ Software Foundation, 51 Franklin Street,
#include "tm_p.h"
#include "obstack.h"
#include "timevar.h"
+#include "tree-pass.h"
#include "ggc.h"
#include "hashtab.h"
#include "alloc-pool.h"
@@ -465,11 +466,75 @@ check_bb_profile (basic_block bb, FILE *
}
}
+/* 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);
+ if (maybe_hot_bb_p (bb))
+ fprintf (file, ", maybe hot");
+ if (probably_never_executed_bb_p (bb))
+ fprintf (file, ", probably never executed");
+ fprintf (file, ".\n");
+
+ fprintf (file, "%sPredecessors: ", prefix);
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ dump_edge_info (file, e, 0);
+ }
+
+ 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))
+ {
+ if (bb->il.rtl->global_live_at_start && header)
+ {
+ fprintf (file, "\n%sRegisters live at start:", prefix);
+ dump_regset (bb->il.rtl->global_live_at_start, file);
+ }
+
+ if (bb->il.rtl->global_live_at_end && footer)
+ {
+ fprintf (file, "\n%sRegisters live at end:", prefix);
+ dump_regset (bb->il.rtl->global_live_at_end, file);
+ }
+ }
+
+ putc ('\n', file);
+}
+
void
dump_flow_info (FILE *file)
{
basic_block bb;
+ if (file == dump_file
+ && (dump_flags & TDF_SLIM)
+ && !(dump_flags & TDF_DETAILS))
+ return;
+
/* There are no pseudo registers after reload. Don't dump them. */
if (reg_n_info && !reload_completed)
{
@@ -521,45 +581,7 @@ dump_flow_info (FILE *file)
fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
FOR_EACH_BB (bb)
{
- edge e;
- edge_iterator ei;
-
- fprintf (file, "\nBasic block %d ", bb->index);
- fprintf (file, "prev %d, next %d, ",
- bb->prev_bb->index, 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))
- fprintf (file, ", maybe hot");
- if (probably_never_executed_bb_p (bb))
- fprintf (file, ", probably never executed");
- fprintf (file, ".\n");
-
- fprintf (file, "Predecessors: ");
- 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);
-
- if (bb->flags & BB_RTL)
- {
- if (bb->il.rtl->global_live_at_start)
- {
- fprintf (file, "\nRegisters live at start:");
- dump_regset (bb->il.rtl->global_live_at_start, file);
- }
-
- if (bb->il.rtl->global_live_at_end)
- {
- fprintf (file, "\nRegisters live at end:");
- dump_regset (bb->il.rtl->global_live_at_end, file);
- }
- }
-
- putc ('\n', file);
+ dump_bb_info (bb, true, true, TDF_DETAILS, "", file);
check_bb_profile (bb, file);
}
Index: passes.c
===================================================================
--- passes.c (revision 108713)
+++ passes.c (working copy)
@@ -753,16 +810,20 @@ execute_todo (struct tree_opt_pass *pass
if (properties & PROP_trees)
dump_function_to_file (current_function_decl,
dump_file, dump_flags);
- else if (properties & PROP_cfg)
+ else
{
- print_rtl_with_bb (dump_file, get_insns ());
+ if (dump_flags & TDF_SLIM)
+ print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags);
+ else if (properties & PROP_cfg)
+ print_rtl_with_bb (dump_file, get_insns ());
+ else
+ print_rtl (dump_file, get_insns ());
- if (graph_dump_format != no_graph
+ if (properties & PROP_cfg
+ && graph_dump_format != no_graph
&& (dump_flags & TDF_GRAPH))
print_rtl_graph_with_bb (dump_file_name, get_insns ());
}
- else
- print_rtl (dump_file, get_insns ());
/* Flush the file. If verification fails, we won't be able to
close the file before aborting. */
Index: rtl.h
===================================================================
--- rtl.h (revision 108713)
+++ rtl.h (working copy)
@@ -1980,6 +1981,11 @@ extern void dump_combine_total_stats (FI
/* In web.c */
extern void web_main (void);
+/* In sched-vis.c. */
+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);
+
/* In sched-rgn.c. */
extern void schedule_insns (FILE *);
Index: basic-block.h
===================================================================
--- basic-block.h (revision 108713)
+++ basic-block.h (working copy)
@@ -508,6 +508,7 @@ extern int dfs_enumerate_from (basic_blo
bool (*)(basic_block, void *),
basic_block *, int, void *);
extern void compute_dominance_frontiers (bitmap *);
+extern void dump_bb_info (basic_block, bool, bool, int, const char *, FILE *);
extern void dump_edge_info (FILE *, edge, int);
extern void brief_dump_cfg (FILE *);
extern void clear_edges (void);
Index: tree-dump.c
===================================================================
--- tree-dump.c (revision 108713)
+++ tree-dump.c (working copy)
@@ -920,24 +920,25 @@ dump_end (enum tree_dump_index phase ATT
static int
dump_enable_all (int flags, int letter)
{
+ int ir_type = (flags & (TDF_TREE | TDF_RTL | TDF_IPA));
int n = 0;
size_t i;
for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
- if ((dump_files[i].flags & flags)
+ if ((dump_files[i].flags & ir_type)
&& (letter == 0 || letter == dump_files[i].letter))
{
dump_files[i].state = -1;
- dump_files[i].flags = flags;
+ dump_files[i].flags |= flags;
n++;
}
for (i = 0; i < extra_dump_files_in_use; i++)
- if ((extra_dump_files[i].flags & flags)
+ if ((extra_dump_files[i].flags & ir_type)
&& (letter == 0 || letter == extra_dump_files[i].letter))
{
extra_dump_files[i].state = -1;
- extra_dump_files[i].flags = flags;
+ extra_dump_files[i].flags |= flags;
n++;
}
Index: sched-vis.c
===================================================================
--- sched-vis.c (revision 108713)
+++ sched-vis.c (working copy)
@@ -25,18 +25,13 @@ Software Foundation, 51 Franklin Street,
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "toplev.h"
#include "rtl.h"
-#include "tm_p.h"
-#include "regs.h"
+#include "obstack.h"
#include "hard-reg-set.h"
#include "basic-block.h"
-#include "insn-attr.h"
#include "real.h"
#include "sched-int.h"
-#include "target.h"
-
-#ifdef INSN_SCHEDULING
+#include "tree-pass.h"
static char *safe_concat (char *, char *, const char *);
static void print_exp (char *, rtx, int);
@@ -478,6 +473,11 @@ print_value (char *buf, rtx x, int verbo
sprintf (t, "r%d", REGNO (x));
cur = safe_concat (buf, cur, t);
}
+ if (verbose && !current_sched_info)
+ {
+ sprintf (t, ":%s", GET_MODE (x));
+ cur = safe_concat (buf, cur, t);
+ }
break;
case SUBREG:
print_value (t, SUBREG_REG (x), verbose);
@@ -629,19 +629,19 @@ print_insn (char *buf, rtx x, int verbos
{
case INSN:
print_pattern (t, PATTERN (x), verbose);
- if (verbose)
+ if (verbose && current_sched_info)
sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
t);
else
- sprintf (buf, "%-4d %s", INSN_UID (x), t);
+ sprintf (buf, " %4d %s", INSN_UID (x), t);
break;
case JUMP_INSN:
print_pattern (t, PATTERN (x), verbose);
- if (verbose)
+ if (verbose && current_sched_info)
sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
t);
else
- sprintf (buf, "%-4d %s", INSN_UID (x), t);
+ sprintf (buf, " %4d %s", INSN_UID (x), t);
break;
case CALL_INSN:
x = PATTERN (insn);
@@ -652,38 +652,92 @@ print_insn (char *buf, rtx x, int verbos
}
else
strcpy (t, "call <...>");
- if (verbose)
+ if (verbose && current_sched_info)
sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
else
- sprintf (buf, "%-4d %s", INSN_UID (insn), t);
+ sprintf (buf, " %4d %s", INSN_UID (insn), t);
break;
case CODE_LABEL:
sprintf (buf, "L%d:", INSN_UID (x));
break;
case BARRIER:
- sprintf (buf, "i% 4d: barrier", INSN_UID (x));
+ sprintf (buf, "i%4d: barrier", INSN_UID (x));
break;
case NOTE:
if (NOTE_LINE_NUMBER (x) > 0)
{
expanded_location xloc;
NOTE_EXPANDED_LOCATION (xloc, x);
- sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
+ sprintf (buf, " %4d note \"%s\" %d", INSN_UID (x),
xloc.file, xloc.line);
}
else
- sprintf (buf, "%4d %s", INSN_UID (x),
+ sprintf (buf, " %4d %s", INSN_UID (x),
GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
break;
default:
- if (verbose)
- {
- sprintf (buf, "Not an INSN at all\n");
- debug_rtx (x);
- }
- else
- sprintf (buf, "i%-4d <What?>", INSN_UID (x));
+ sprintf (buf, "i%4d <What %s?>", INSN_UID (x),
+ GET_RTX_NAME (GET_CODE (x)));
}
} /* print_insn */
-#endif
+
+/* 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)
+{
+ char t[BUF_LEN + 32];
+ rtx note;
+
+ print_insn (t, x, 1);
+ fputs (t, f);
+ putc ('\n', f);
+ if (INSN_P (x) && REG_NOTES (x))
+ for (note = REG_NOTES (x); note; note = XEXP (note, 1))
+ {
+ print_value (t, XEXP (note, 0), 1);
+ fprintf (f, " %s: %s\n",
+ GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
+ }
+}
+
+/* Emit a slim dump of X (an insn) to stderr. */
+void
+debug_insn_slim (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)
+{
+ basic_block current_bb = NULL;
+ rtx insn;
+
+ for (insn = first; NULL != insn; insn = NEXT_INSN (insn))
+ {
+ if ((flags & TDF_BLOCKS)
+ && (INSN_P (insn) || GET_CODE (insn) == NOTE)
+ && BLOCK_FOR_INSN (insn)
+ && !current_bb)
+ {
+ current_bb = BLOCK_FOR_INSN (insn);
+ dump_bb_info (current_bb, true, false, flags, ";; ", f);
+ }
+
+ dump_insn_slim (f, insn);
+
+ if ((flags & TDF_BLOCKS)
+ && current_bb
+ && insn == BB_END (current_bb))
+ {
+ dump_bb_info (current_bb, false, true, flags, ";; ", f);
+ current_bb = NULL;
+ }
+ }
+}
+
Index: Makefile.in
===================================================================
--- Makefile.in (revision 108713)
+++ Makefile.in (working copy)
@@ -2498,8 +2499,8 @@ sched-ebb.o : sched-ebb.c $(CONFIG_H) $(
function.h $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) \
$(PARAMS_H) $(CFGLAYOUT_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) $(INSN_ATTR_H) \
- $(REGS_H) $(TM_P_H) $(TARGET_H) real.h toplev.h
+ $(RTL_H) $(SCHED_INT_H) hard-reg-set.h $(BASIC_BLOCK_H) $(OBSTACK_H) \
+ $(TM_P_H) real.h toplev.h tree-pass.h
final.o : final.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) intl.h $(REGS_H) $(RECOG_H) conditions.h \
insn-config.h $(INSN_ATTR_H) function.h real.h output.h hard-reg-set.h \