coretypes.h (struct pretty_print_info): Make a coretype.

* coretypes.h (struct pretty_print_info): Make a coretype.
	(typedef pretty_printer): Likewise.
	* pretty-print.h (typedef pretty_printer): Not needed here anymore.
	* pretty-print.c (pp_write_text_as_dot_label_to_stream): New function.
	* rtl.h (str_pattern_slim): New prototype.
	(print_value, print_pattern, print_insn): Adjust prototypes to take
	a pretty-printer rather than a char buffer.
	* sched-vis.c (safe_concat): Remove.
	(print_exp): Print into a pretty-printer.
	(print_value): Likewise.
	(print_pattern): Likewise.
	(print_insn): Likewise.
	(print_insn_with_notes): New static function.
	(init_rtl_slim_pretty_print): New function.
	(dump_value_slim): Simplify.  Print into and flush a pretty-printer.
	(dump_insn_slim): Likewise.
	(dump_rtl_slim): Likewise.
	(str_pattern_slim): New function.
	* haifa-sched.c (model_recompute): Use str_pattern_slim instead of
	static buffers.
	(model_record_pressures): Likewise.
	(schedule_insn): Likewise.
	* sel-sched-dump.c (dump_insn_rtx_1): Likewise.
	(sel_prepare_string_for_dot_label): Refer to graph.c CFG dumper code.
	* graph.c: Include pretty-print.h.
	(init_graph_slim_pretty_print): New function.
	(print_escaped_line): Removed here, and reincarnated as
	pp_write_text_as_dot_label_to_stream.
	(draw_cfg_node): Print into a pretty printer.
	(draw_cfg_node_succ_edges): Likewise.
	(print_rtl_graph_with_bb): Likewise.
	* Makefile.in (graph.o): Fix dependencies.
	(tree-optimize.o, toplev.o, sched-vis.o): Likewise.

From-SVN: r193990
This commit is contained in:
Steven Bosscher 2012-11-30 09:46:02 +00:00
parent 7a36dc06de
commit 7eba871a24
10 changed files with 371 additions and 316 deletions

View file

@ -1,3 +1,39 @@
2012-11-30 Steven Bosscher <steven@gcc.gnu.org>
* coretypes.h (struct pretty_print_info): Make a coretype.
(typedef pretty_printer): Likewise.
* pretty-print.h (typedef pretty_printer): Not needed here anymore.
* pretty-print.c (pp_write_text_as_dot_label_to_stream): New function.
* rtl.h (str_pattern_slim): New prototype.
(print_value, print_pattern, print_insn): Adjust prototypes to take
a pretty-printer rather than a char buffer.
* sched-vis.c (safe_concat): Remove.
(print_exp): Print into a pretty-printer.
(print_value): Likewise.
(print_pattern): Likewise.
(print_insn): Likewise.
(print_insn_with_notes): New static function.
(init_rtl_slim_pretty_print): New function.
(dump_value_slim): Simplify. Print into and flush a pretty-printer.
(dump_insn_slim): Likewise.
(dump_rtl_slim): Likewise.
(str_pattern_slim): New function.
* haifa-sched.c (model_recompute): Use str_pattern_slim instead of
static buffers.
(model_record_pressures): Likewise.
(schedule_insn): Likewise.
* sel-sched-dump.c (dump_insn_rtx_1): Likewise.
(sel_prepare_string_for_dot_label): Refer to graph.c CFG dumper code.
* graph.c: Include pretty-print.h.
(init_graph_slim_pretty_print): New function.
(print_escaped_line): Removed here, and reincarnated as
pp_write_text_as_dot_label_to_stream.
(draw_cfg_node): Print into a pretty printer.
(draw_cfg_node_succ_edges): Likewise.
(print_rtl_graph_with_bb): Likewise.
* Makefile.in (graph.o): Fix dependencies.
(tree-optimize.o, toplev.o, sched-vis.o): Likewise.
2012-11-30 Jakub Jelinek <jakub@redhat.com> 2012-11-30 Jakub Jelinek <jakub@redhat.com>
* tsan.c (is_load_of_const_p): Removed. * tsan.c (is_load_of_const_p): Removed.

View file

@ -1845,9 +1845,8 @@ srcextra: gcc.srcextra lang.srcextra
gcc.srcextra: gengtype-lex.c gcc.srcextra: gengtype-lex.c
-cp -p $^ $(srcdir) -cp -p $^ $(srcdir)
graph.o: graph.c $(SYSTEM_H) coretypes.h $(TM_H) toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) \ graph.o: graph.c graph.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(RTL_H) $(FUNCTION_H) hard-reg-set.h $(BASIC_BLOCK_H) graph.h $(OBSTACK_H) \ $(DIAGNOSTIC_CORE_H) $(TM_H) $(RTL_H) $(BASIC_BLOCK_H) $(PRETTY_PRINT_H)
$(CONFIG_H) $(EMIT_RTL_H)
sbitmap.o: sbitmap.c sbitmap.h $(CONFIG_H) $(SYSTEM_H) coretypes.h sbitmap.o: sbitmap.c sbitmap.h $(CONFIG_H) $(SYSTEM_H) coretypes.h
sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H) sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H)
@ -2509,7 +2508,7 @@ tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(DIAGNOSTIC_H) $(BASIC_BLOCK_H) $(FLAGS_H) $(TM_H) \ $(DIAGNOSTIC_H) $(BASIC_BLOCK_H) $(FLAGS_H) $(TM_H) \
coretypes.h toplev.h $(DIAGNOSTIC_CORE_H) $(FUNCTION_H) langhooks.h \ coretypes.h toplev.h $(DIAGNOSTIC_CORE_H) $(FUNCTION_H) langhooks.h \
$(FLAGS_H) $(CGRAPH_H) $(PLUGIN_H) \ $(FLAGS_H) $(CGRAPH_H) $(PLUGIN_H) \
$(TREE_INLINE_H) $(GGC_H) graph.h $(CGRAPH_H) \ $(TREE_INLINE_H) $(GGC_H) $(CGRAPH_H) \
$(TREE_PASS_H) $(CFGLOOP_H) $(EXCEPT_H) $(TREE_PASS_H) $(CFGLOOP_H) $(EXCEPT_H)
gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GIMPLE_H) \ gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GIMPLE_H) \
@ -2691,7 +2690,7 @@ toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
version.h $(RTL_H) $(FUNCTION_H) $(FLAGS_H) xcoffout.h $(INPUT_H) \ version.h $(RTL_H) $(FUNCTION_H) $(FLAGS_H) xcoffout.h $(INPUT_H) \
$(INSN_ATTR_H) output.h $(DIAGNOSTIC_H) debug.h insn-config.h intl.h \ $(INSN_ATTR_H) output.h $(DIAGNOSTIC_H) debug.h insn-config.h intl.h \
$(RECOG_H) Makefile toplev.h sdbout.h dbxout.h $(EXPR_H) \ $(RECOG_H) Makefile toplev.h sdbout.h dbxout.h $(EXPR_H) \
hard-reg-set.h $(BASIC_BLOCK_H) graph.h $(EXCEPT_H) $(REGS_H) $(TIMEVAR_H) \ hard-reg-set.h $(BASIC_BLOCK_H) $(EXCEPT_H) $(REGS_H) $(TIMEVAR_H) \
value-prof.h $(PARAMS_H) $(TM_P_H) reload.h ira.h dwarf2asm.h $(TARGET_H) \ value-prof.h $(PARAMS_H) $(TM_P_H) reload.h ira.h dwarf2asm.h $(TARGET_H) \
langhooks.h insn-flags.h $(CFGLOOP_H) hosthooks.h \ langhooks.h insn-flags.h $(CFGLOOP_H) hosthooks.h \
$(CGRAPH_H) $(COVERAGE_H) alloc-pool.h $(GGC_H) \ $(CGRAPH_H) $(COVERAGE_H) alloc-pool.h $(GGC_H) \
@ -3333,8 +3332,7 @@ sched-ebb.o : sched-ebb.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(FUNCTION_H) $(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) $(TM_P_H) \ $(FUNCTION_H) $(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) $(TM_P_H) \
$(PARAMS_H) $(TARGET_H) $(PARAMS_H) $(TARGET_H)
sched-vis.o : sched-vis.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h $(TM_H) \ sched-vis.o : sched-vis.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) hard-reg-set.h $(BASIC_BLOCK_H) $(OBSTACK_H) \ $(INSN_ATTR_H) $(RTL_H) $(TREE_H) $(BASIC_BLOCK_H) $(PRETTY_PRINT_H)
$(INSN_ATTR_H) $(TREE_H)
sel-sched.o : sel-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_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 \ $(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) \ $(FUNCTION_H) $(INSN_ATTR_H) $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \

View file

@ -58,10 +58,11 @@ typedef struct rtvec_def *rtvec;
typedef const struct rtvec_def *const_rtvec; typedef const struct rtvec_def *const_rtvec;
union tree_node; union tree_node;
typedef union tree_node *tree; typedef union tree_node *tree;
typedef const union tree_node *const_tree;
union gimple_statement_d; union gimple_statement_d;
typedef union gimple_statement_d *gimple; typedef union gimple_statement_d *gimple;
typedef const union tree_node *const_tree;
typedef const union gimple_statement_d *const_gimple; typedef const union gimple_statement_d *const_gimple;
typedef gimple gimple_seq;
union section; union section;
typedef union section section; typedef union section section;
struct gcc_options; struct gcc_options;
@ -72,7 +73,8 @@ struct cl_decoded_option;
struct cl_option_handlers; struct cl_option_handlers;
struct diagnostic_context; struct diagnostic_context;
typedef struct diagnostic_context diagnostic_context; typedef struct diagnostic_context diagnostic_context;
typedef gimple gimple_seq; struct pretty_print_info;
typedef struct pretty_print_info pretty_printer;
/* Address space number for named address space support. */ /* Address space number for named address space support. */
typedef unsigned char addr_space_t; typedef unsigned char addr_space_t;

View file

@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "rtl.h" #include "rtl.h"
#include "tree.h" #include "tree.h"
#include "graph.h" #include "graph.h"
#include "pretty-print.h"
/* DOT files with the .dot extension are recognized as document templates /* DOT files with the .dot extension are recognized as document templates
by a well-known piece of word processing software out of Redmond, WA. by a well-known piece of word processing software out of Redmond, WA.
@ -56,45 +57,30 @@ open_graph_file (const char *base, const char *mode)
return fp; return fp;
} }
/* Print the output from print_insn or print_pattern with GraphViz-special /* Return a pretty-print buffer for output to file FP. */
characters escaped as necessary. */
void static pretty_printer *
print_escaped_line (FILE *fp, const char *buf) init_graph_slim_pretty_print (FILE *fp)
{ {
const char *p = buf; static bool initialized = false;
static pretty_printer graph_slim_pp;
while (*p) if (! initialized)
{ {
switch (*p) pp_construct (&graph_slim_pp, /*prefix=*/NULL, /*linewidth=*/0);
{ initialized = true;
case '\n':
/* Print newlines as a left-aligned newline. */
fputs ("\\l\\\n", fp);
break;
case '{':
case '}':
case '<':
case '>':
case '|':
case '"':
case ' ':
/* These characters have to be escaped to work with record-shape nodes. */
fputc ('\\', fp);
/* fall through */
default:
fputc (*p, fp);
break;
}
p++;
} }
fputs ("\\l\\\n", fp); else
gcc_assert (! pp_last_position_in_text (&graph_slim_pp));
graph_slim_pp.buffer->stream = fp;
return &graph_slim_pp;
} }
/* Draw a basic block BB belonging to the function with FNDECL_UID /* Draw a basic block BB belonging to the function with FNDECL_UID
as its unique number. */ as its unique number. */
static void static void
draw_cfg_node (FILE *fp, int fndecl_uid, basic_block bb) draw_cfg_node (pretty_printer *pp, int fndecl_uid, basic_block bb)
{ {
rtx insn; rtx insn;
bool first = true; bool first = true;
@ -115,48 +101,53 @@ draw_cfg_node (FILE *fp, int fndecl_uid, basic_block bb)
: "lightgrey"; : "lightgrey";
} }
fprintf (fp, pp_printf (pp,
"\tfn_%d_basic_block_%d [shape=%s,style=filled,fillcolor=%s,label=\"", "\tfn_%d_basic_block_%d "
fndecl_uid, bb->index, shape, fillcolor); "[shape=%s,style=filled,fillcolor=%s,label=\"",
fndecl_uid, bb->index, shape, fillcolor);
if (bb->index == ENTRY_BLOCK) if (bb->index == ENTRY_BLOCK)
fputs ("ENTRY", fp); pp_string (pp, "ENTRY");
else if (bb->index == EXIT_BLOCK) else if (bb->index == EXIT_BLOCK)
fputs ("EXIT", fp); pp_string (pp, "EXIT");
else else
{ {
fputc ('{', fp); pp_character (pp, '{');
pp_write_text_to_stream (pp);
/* TODO: inter-bb stuff. */ /* TODO: inter-bb stuff. */
FOR_BB_INSNS (bb, insn) FOR_BB_INSNS (bb, insn)
{ {
char buf[2048];
if (! first) if (! first)
fputc ('|', fp); {
pp_character (pp, '|');
pp_write_text_to_stream (pp);
}
first = false;
print_insn (buf, insn, 1); print_insn (pp, insn, 1);
print_escaped_line (fp, buf); pp_newline (pp);
if (INSN_P (insn) && REG_NOTES (insn)) if (INSN_P (insn) && REG_NOTES (insn))
for (rtx note = REG_NOTES (insn); note; note = XEXP (note, 1)) for (rtx note = REG_NOTES (insn); note; note = XEXP (note, 1))
{ {
fprintf (fp, " %s: ", pp_printf (pp, " %s: ",
GET_REG_NOTE_NAME (REG_NOTE_KIND (note))); GET_REG_NOTE_NAME (REG_NOTE_KIND (note)));
print_pattern (buf, XEXP (note, 0), 1); print_pattern (pp, XEXP (note, 0), 1);
print_escaped_line (fp, buf); pp_newline (pp);
} }
pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true);
first = false;
} }
fputc ('}', fp); pp_character (pp, '}');
} }
fputs ("\"];\n\n", fp); pp_string (pp, "\"];\n\n");
pp_flush (pp);
} }
/* Draw all successor edges of a basic block BB belonging to the function /* Draw all successor edges of a basic block BB belonging to the function
with FNDECL_UID as its unique number. */ with FNDECL_UID as its unique number. */
static void static void
draw_cfg_node_succ_edges (FILE *fp, int fndecl_uid, basic_block bb) draw_cfg_node_succ_edges (pretty_printer *pp, int fndecl_uid, basic_block bb)
{ {
edge e; edge e;
edge_iterator ei; edge_iterator ei;
@ -187,14 +178,15 @@ draw_cfg_node_succ_edges (FILE *fp, int fndecl_uid, basic_block bb)
if (e->flags & EDGE_ABNORMAL) if (e->flags & EDGE_ABNORMAL)
color = "red"; color = "red";
fprintf (fp, pp_printf (pp,
"\tfn_%d_basic_block_%d:s -> fn_%d_basic_block_%d:n " "\tfn_%d_basic_block_%d:s -> fn_%d_basic_block_%d:n "
"[style=%s,color=%s,weight=%d,constraint=%s];\n", "[style=%s,color=%s,weight=%d,constraint=%s];\n",
fndecl_uid, e->src->index, fndecl_uid, e->src->index,
fndecl_uid, e->dest->index, fndecl_uid, e->dest->index,
style, color, weight, style, color, weight,
(e->flags & (EDGE_FAKE | EDGE_DFS_BACK)) ? "false" : "true"); (e->flags & (EDGE_FAKE | EDGE_DFS_BACK)) ? "false" : "true");
} }
pp_flush (pp);
} }
/* Print a graphical representation of the CFG of function FUN. /* Print a graphical representation of the CFG of function FUN.
@ -208,19 +200,19 @@ print_rtl_graph_with_bb (const char *base, tree fndecl)
int *rpo = XNEWVEC (int, n_basic_blocks); int *rpo = XNEWVEC (int, n_basic_blocks);
basic_block bb; basic_block bb;
int i, n; int i, n;
pretty_printer *pp = init_graph_slim_pretty_print (fp);
fprintf (fp, pp_printf (pp, "subgraph \"%s\" {\n"
"subgraph \"%s\" {\n" "\tcolor=\"black\";\n"
"\tcolor=\"black\";\n" "\tlabel=\"%s\";\n",
"\tlabel=\"%s\";\n", funcname, funcname);
funcname, funcname);
/* First print all basic blocks. /* First print all basic blocks.
Visit the blocks in reverse post order to get a good ranking Visit the blocks in reverse post order to get a good ranking
of the nodes. */ of the nodes. */
n = pre_and_rev_post_order_compute (NULL, rpo, true); n = pre_and_rev_post_order_compute (NULL, rpo, true);
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
draw_cfg_node (fp, fndecl_uid, BASIC_BLOCK (rpo[i])); draw_cfg_node (pp, fndecl_uid, BASIC_BLOCK (rpo[i]));
/* Draw all edges at the end to get subgraphs right for GraphViz, /* Draw all edges at the end to get subgraphs right for GraphViz,
which requires nodes to be defined before edges to cluster which requires nodes to be defined before edges to cluster
@ -232,10 +224,10 @@ print_rtl_graph_with_bb (const char *base, tree fndecl)
for ourselves is also not desirable.) */ for ourselves is also not desirable.) */
mark_dfs_back_edges (); mark_dfs_back_edges ();
FOR_ALL_BB (bb) FOR_ALL_BB (bb)
draw_cfg_node_succ_edges (fp, fndecl_uid, bb); draw_cfg_node_succ_edges (pp, fndecl_uid, bb);
fputs ("\t}\n", fp);
pp_printf (pp, "\t}\n");
pp_flush (pp);
fclose (fp); fclose (fp);
} }

View file

@ -2168,8 +2168,6 @@ model_recompute (rtx insn)
if (sched_verbose >= 5) if (sched_verbose >= 5)
{ {
char buf[2048];
if (!print_p) if (!print_p)
{ {
fprintf (sched_dump, MODEL_BAR); fprintf (sched_dump, MODEL_BAR);
@ -2179,9 +2177,9 @@ model_recompute (rtx insn)
print_p = true; print_p = true;
} }
print_pattern (buf, PATTERN (insn), 0);
fprintf (sched_dump, ";;\t\t| %3d %4d %-30s ", fprintf (sched_dump, ";;\t\t| %3d %4d %-30s ",
point, INSN_UID (insn), buf); point, INSN_UID (insn),
str_pattern_slim (PATTERN (insn)));
for (pci = 0; pci < ira_pressure_classes_num; pci++) for (pci = 0; pci < ira_pressure_classes_num; pci++)
{ {
cl = ira_pressure_classes[pci]; cl = ira_pressure_classes[pci];
@ -3343,18 +3341,16 @@ model_record_pressures (struct model_insn_info *insn)
point = model_index (insn->insn); point = model_index (insn->insn);
if (sched_verbose >= 2) if (sched_verbose >= 2)
{ {
char buf[2048];
if (point == 0) if (point == 0)
{ {
fprintf (sched_dump, "\n;;\tModel schedule:\n;;\n"); fprintf (sched_dump, "\n;;\tModel schedule:\n;;\n");
fprintf (sched_dump, ";;\t| idx insn | mpri hght dpth prio |\n"); fprintf (sched_dump, ";;\t| idx insn | mpri hght dpth prio |\n");
} }
print_pattern (buf, PATTERN (insn->insn), 0);
fprintf (sched_dump, ";;\t| %3d %4d | %4d %4d %4d %4d | %-30s ", fprintf (sched_dump, ";;\t| %3d %4d | %4d %4d %4d %4d | %-30s ",
point, INSN_UID (insn->insn), insn->model_priority, point, INSN_UID (insn->insn), insn->model_priority,
insn->depth + insn->alap, insn->depth, insn->depth + insn->alap, insn->depth,
INSN_PRIORITY (insn->insn), buf); INSN_PRIORITY (insn->insn),
str_pattern_slim (PATTERN (insn->insn)));
} }
calculate_reg_deaths (insn->insn, death); calculate_reg_deaths (insn->insn, death);
reg_pressure = INSN_REG_PRESSURE (insn->insn); reg_pressure = INSN_REG_PRESSURE (insn->insn);
@ -3715,12 +3711,9 @@ schedule_insn (rtx insn)
if (sched_verbose >= 1) if (sched_verbose >= 1)
{ {
struct reg_pressure_data *pressure_info; struct reg_pressure_data *pressure_info;
char buf[2048];
print_insn (buf, insn, 0);
buf[40] = 0;
fprintf (sched_dump, ";;\t%3i--> %s%-40s:", fprintf (sched_dump, ";;\t%3i--> %s%-40s:",
clock_var, (*current_sched_info->print_insn) (insn, 1), buf); clock_var, (*current_sched_info->print_insn) (insn, 1),
str_pattern_slim (PATTERN (insn)));
if (recog_memoized (insn) < 0) if (recog_memoized (insn) < 0)
fprintf (sched_dump, "nothing"); fprintf (sched_dump, "nothing");

View file

@ -99,6 +99,58 @@ pp_write_text_to_stream (pretty_printer *pp)
pp_clear_output_area (pp); pp_clear_output_area (pp);
} }
/* As pp_write_text_to_stream, but for GraphViz label output.
Flush the formatted text of pretty-printer PP onto the attached stream.
Replace characters in PPF that have special meaning in a GraphViz .dot
file.
This routine is not very fast, but it doesn't have to be as this is only
be used by routines dumping intermediate representations in graph form. */
void
pp_write_text_as_dot_label_to_stream (pretty_printer *pp, bool for_record)
{
const char *text = pp_formatted_text (pp);
const char *p = text;
FILE *fp = pp->buffer->stream;
while (*p)
{
switch (*p)
{
/* Print newlines as a left-aligned newline. */
case '\n':
fputs ("\\l\\\n", fp);
break;
/* A pipe is only special for record-shape nodes. */
case '|':
if (for_record)
fputc ('\\', fp);
fputc (*p, fp);
break;
/* The following characters always have to be escaped
for use in labels. */
case '{':
case '}':
case '<':
case '>':
case '"':
case ' ':
fputc ('\\', fp);
/* fall through */
default:
fputc (*p, fp);
break;
}
p++;
}
pp_clear_output_area (pp);
}
/* Wrap a text delimited by START and END into PRETTY-PRINTER. */ /* Wrap a text delimited by START and END into PRETTY-PRINTER. */
static void static void
pp_wrap_text (pretty_printer *pp, const char *start, const char *end) pp_wrap_text (pretty_printer *pp, const char *start, const char *end)

View file

@ -132,7 +132,6 @@ typedef struct
/* The type of a hook that formats client-specific data onto a pretty_pinter. /* The type of a hook that formats client-specific data onto a pretty_pinter.
A client-supplied formatter returns true if everything goes well, A client-supplied formatter returns true if everything goes well,
otherwise it returns false. */ otherwise it returns false. */
typedef struct pretty_print_info pretty_printer;
typedef bool (*printer_fn) (pretty_printer *, text_info *, const char *, typedef bool (*printer_fn) (pretty_printer *, text_info *, const char *,
int, bool, bool, bool); int, bool, bool, bool);
@ -343,7 +342,8 @@ extern void pp_base_indent (pretty_printer *);
extern void pp_base_newline (pretty_printer *); extern void pp_base_newline (pretty_printer *);
extern void pp_base_character (pretty_printer *, int); extern void pp_base_character (pretty_printer *, int);
extern void pp_base_string (pretty_printer *, const char *); extern void pp_base_string (pretty_printer *, const char *);
extern void pp_write_text_to_stream (pretty_printer *pp); extern void pp_write_text_to_stream (pretty_printer *);
extern void pp_write_text_as_dot_label_to_stream (pretty_printer *, bool);
extern void pp_base_maybe_space (pretty_printer *); extern void pp_base_maybe_space (pretty_printer *);
/* Switch into verbatim mode and return the old mode. */ /* Switch into verbatim mode and return the old mode. */

View file

@ -2597,16 +2597,16 @@ extern int print_rtl_single (FILE *, const_rtx);
extern int print_rtl_single_with_indent (FILE *, const_rtx, int); extern int print_rtl_single_with_indent (FILE *, const_rtx, int);
extern void print_inline_rtx (FILE *, const_rtx, int); extern void print_inline_rtx (FILE *, const_rtx, int);
/* Functions in sched-vis.c. These must be outside INSN_SCHEDULING as /* Functions in sched-vis.c. FIXME: Ideally these functions would
sched-vis.c is compiled always. FIXME: Ideally these functions would
not be in sched-vis.c but in rtl.c, because they are not only used not be in sched-vis.c but in rtl.c, because they are not only used
by the scheduler anymore but for all "slim" RTL dumping. */ by the scheduler anymore but for all "slim" RTL dumping. */
extern void dump_value_slim (FILE *, const_rtx, int); extern void dump_value_slim (FILE *, const_rtx, int);
extern void dump_insn_slim (FILE *, const_rtx); extern void dump_insn_slim (FILE *, const_rtx);
extern void dump_rtl_slim (FILE *, const_rtx, const_rtx, int, int); extern void dump_rtl_slim (FILE *, const_rtx, const_rtx, int, int);
extern void print_value (char *, const_rtx, int); extern void print_value (pretty_printer *, const_rtx, int);
extern void print_pattern (char *, const_rtx, int); extern void print_pattern (pretty_printer *, const_rtx, int);
extern void print_insn (char *, const_rtx, int); extern void print_insn (pretty_printer *, const_rtx, int);
extern const char *str_pattern_slim (const_rtx);
/* In function.c */ /* In function.c */
extern void reposition_prologue_and_epilogue_notes (void); extern void reposition_prologue_and_epilogue_notes (void);

View file

@ -30,50 +30,41 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h" #include "tm.h"
#include "rtl.h" #include "rtl.h"
#include "tree.h" /* FIXME: To dump INSN_VAR_LOCATION_DECL. */ #include "tree.h" /* FIXME: To dump INSN_VAR_LOCATION_DECL. */
#include "obstack.h"
#include "hard-reg-set.h"
#include "basic-block.h" #include "basic-block.h"
#include "insn-attr.h"
#include "dumpfile.h" /* for the TDF_* flags */ #include "dumpfile.h" /* for the TDF_* flags */
#include "pretty-print.h"
static char *safe_concat (char *, char *, const char *); /* The functions in this file try to print RTL in a form resembling assembler
mnemonics. Because this form is more concise than the "traditional" form
of RTL printing in Lisp-style, the form printed by this file is called
"slim". RTL dumps in slim format can be obtained by appending the "-slim"
option to -fdump-rtl-<pass>. Control flow graph output as a DOT file is
always printed in slim form.
#define BUF_LEN 2048 The normal interface to the functionality provided in this pretty-printer
is through the dump_*_slim functions to print to a stream, or via the
print_*_slim functions to print into a user's pretty-printer.
static char * It is also possible to obtain a string for a single pattern as a string
safe_concat (char *buf, char *cur, const char *str) pointer, via str_pattern_slim, but this usage is discouraged. */
{
char *end = buf + BUF_LEN - 2; /* Leave room for null. */
int c;
if (cur > end) /* A pretty-printer for slim rtl printing. */
{ static bool rtl_slim_pp_initialized = false;
*end = '\0'; static pretty_printer rtl_slim_pp;
return end;
}
while (cur < end && (c = *str++) != '\0') /* This recognizes rtx'en classified as expressions. These are always
*cur++ = c;
*cur = '\0';
return cur;
}
/* This recognizes rtx, I classified as expressions. These are always
represent some action on values or results of other expression, that represent some action on values or results of other expression, that
may be stored in objects representing values. */ may be stored in objects representing values. */
static void static void
print_exp (char *buf, const_rtx x, int verbose) print_exp (pretty_printer *pp, const_rtx x, int verbose)
{ {
char tmp[BUF_LEN];
const char *st[4]; const char *st[4];
char *cur = buf; const char *fun;
const char *fun = (char *) 0;
const char *sep;
rtx op[4]; rtx op[4];
int i; int i;
fun = (char *) 0;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
st[i] = (char *) 0; st[i] = (char *) 0;
@ -351,21 +342,18 @@ print_exp (char *buf, const_rtx x, int verbose)
case UNSPEC: case UNSPEC:
case UNSPEC_VOLATILE: case UNSPEC_VOLATILE:
{ {
cur = safe_concat (buf, cur, "unspec"); pp_string (pp, "unspec");
if (GET_CODE (x) == UNSPEC_VOLATILE) if (GET_CODE (x) == UNSPEC_VOLATILE)
cur = safe_concat (buf, cur, "/v"); pp_string (pp, "/v");
cur = safe_concat (buf, cur, "["); pp_character (pp, '[');
sep = "";
for (i = 0; i < XVECLEN (x, 0); i++) for (i = 0; i < XVECLEN (x, 0); i++)
{ {
print_pattern (tmp, XVECEXP (x, 0, i), verbose); if (i != 0)
cur = safe_concat (buf, cur, sep); pp_character (pp, ',');
cur = safe_concat (buf, cur, tmp); print_pattern (pp, XVECEXP (x, 0, i), verbose);
sep = ",";
} }
cur = safe_concat (buf, cur, "] "); pp_string (pp, "] ");
sprintf (tmp, "%d", XINT (x, 1)); pp_decimal_int (pp, XINT (x, 1));
cur = safe_concat (buf, cur, tmp);
} }
break; break;
default: default:
@ -402,266 +390,213 @@ print_exp (char *buf, const_rtx x, int verbose)
/* Print this as a function? */ /* Print this as a function? */
if (fun) if (fun)
{ {
cur = safe_concat (buf, cur, fun); pp_string (pp, fun);
cur = safe_concat (buf, cur, "("); pp_character (pp, '(');
} }
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
if (st[i]) if (st[i])
cur = safe_concat (buf, cur, st[i]); pp_string (pp, st[i]);
if (op[i]) if (op[i])
{ {
if (fun && i != 0) if (fun && i != 0)
cur = safe_concat (buf, cur, ","); pp_character (pp, ',');
print_value (pp, op[i], verbose);
print_value (tmp, op[i], verbose);
cur = safe_concat (buf, cur, tmp);
} }
} }
if (fun) if (fun)
cur = safe_concat (buf, cur, ")"); pp_character (pp, ')');
} /* print_exp */ } /* print_exp */
/* Prints rtxes, I customarily classified as values. They're constants, /* Prints rtxes, I customarily classified as values. They're constants,
registers, labels, symbols and memory accesses. */ registers, labels, symbols and memory accesses. */
void void
print_value (char *buf, const_rtx x, int verbose) print_value (pretty_printer *pp, const_rtx x, int verbose)
{ {
char t[BUF_LEN]; char tmp[1024];
char *cur = buf;
if (!x) if (!x)
{ {
safe_concat (buf, buf, "(nil)"); pp_string (pp, "(nil)");
return; return;
} }
switch (GET_CODE (x)) switch (GET_CODE (x))
{ {
case CONST_INT: case CONST_INT:
sprintf (t, HOST_WIDE_INT_PRINT_HEX, pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
(unsigned HOST_WIDE_INT) INTVAL (x)); (unsigned HOST_WIDE_INT) INTVAL (x));
cur = safe_concat (buf, cur, t);
break; break;
case CONST_DOUBLE: case CONST_DOUBLE:
if (FLOAT_MODE_P (GET_MODE (x))) if (FLOAT_MODE_P (GET_MODE (x)))
real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1); {
real_to_decimal (tmp, CONST_DOUBLE_REAL_VALUE (x),
sizeof (tmp), 0, 1);
pp_string (pp, tmp);
}
else else
sprintf (t, pp_printf (pp, "<%wx,%wx>",
"<" HOST_WIDE_INT_PRINT_HEX "," HOST_WIDE_INT_PRINT_HEX ">", (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
(unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x), (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
(unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
cur = safe_concat (buf, cur, t);
break; break;
case CONST_FIXED: case CONST_FIXED:
fixed_to_decimal (t, CONST_FIXED_VALUE (x), sizeof (t)); fixed_to_decimal (tmp, CONST_FIXED_VALUE (x), sizeof (tmp));
cur = safe_concat (buf, cur, t); pp_string (pp, tmp);
break; break;
case CONST_STRING: case CONST_STRING:
cur = safe_concat (buf, cur, "\""); pp_printf (pp, "\"%s\"", XSTR (x, 0));
cur = safe_concat (buf, cur, XSTR (x, 0));
cur = safe_concat (buf, cur, "\"");
break; break;
case SYMBOL_REF: case SYMBOL_REF:
cur = safe_concat (buf, cur, "`"); pp_printf (pp, "`%s'", XSTR (x, 0));
cur = safe_concat (buf, cur, XSTR (x, 0));
cur = safe_concat (buf, cur, "'");
break; break;
case LABEL_REF: case LABEL_REF:
sprintf (t, "L%d", INSN_UID (XEXP (x, 0))); pp_printf (pp, "L%d", INSN_UID (XEXP (x, 0)));
cur = safe_concat (buf, cur, t);
break; break;
case CONST: case CONST:
print_value (t, XEXP (x, 0), verbose);
cur = safe_concat (buf, cur, "const(");
cur = safe_concat (buf, cur, t);
cur = safe_concat (buf, cur, ")");
break;
case HIGH: case HIGH:
print_value (t, XEXP (x, 0), verbose); case STRICT_LOW_PART:
cur = safe_concat (buf, cur, "high("); pp_printf (pp, "%s(", GET_RTX_NAME (GET_CODE (x)));
cur = safe_concat (buf, cur, t); print_value (pp, XEXP (x, 0), verbose);
cur = safe_concat (buf, cur, ")"); pp_character (pp, ')');
break; break;
case REG: case REG:
if (REGNO (x) < FIRST_PSEUDO_REGISTER) if (REGNO (x) < FIRST_PSEUDO_REGISTER)
{ {
int c = reg_names[REGNO (x)][0]; if (ISDIGIT (reg_names[REGNO (x)][0]))
if (ISDIGIT (c)) pp_character (pp, '%');
cur = safe_concat (buf, cur, "%"); pp_string (pp, reg_names[REGNO (x)]);
cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
} }
else else
{ pp_printf (pp, "r%d", REGNO (x));
sprintf (t, "r%d", REGNO (x));
cur = safe_concat (buf, cur, t);
}
if (verbose) if (verbose)
{ pp_printf (pp, ":%s", GET_MODE_NAME (GET_MODE (x)));
sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x)));
cur = safe_concat (buf, cur, t);
}
break; break;
case SUBREG: case SUBREG:
print_value (t, SUBREG_REG (x), verbose); print_value (pp, SUBREG_REG (x), verbose);
cur = safe_concat (buf, cur, t); pp_printf (pp, "#%d", SUBREG_BYTE (x));
sprintf (t, "#%d", SUBREG_BYTE (x));
cur = safe_concat (buf, cur, t);
break;
case STRICT_LOW_PART:
print_value (t, XEXP (x, 0), verbose);
cur = safe_concat (buf, cur, "strict_low_part(");
cur = safe_concat (buf, cur, t);
cur = safe_concat (buf, cur, ")");
break; break;
case SCRATCH: case SCRATCH:
cur = safe_concat (buf, cur, "scratch");
break;
case CC0: case CC0:
cur = safe_concat (buf, cur, "cc0");
break;
case PC: case PC:
cur = safe_concat (buf, cur, "pc"); pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
break; break;
case MEM: case MEM:
print_value (t, XEXP (x, 0), verbose); pp_character (pp, '[');
cur = safe_concat (buf, cur, "["); print_value (pp, XEXP (x, 0), verbose);
cur = safe_concat (buf, cur, t); pp_character (pp, ']');
cur = safe_concat (buf, cur, "]");
break; break;
case DEBUG_EXPR: case DEBUG_EXPR:
sprintf (t, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x))); pp_printf (pp, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
cur = safe_concat (buf, cur, t);
break; break;
default: default:
print_exp (t, x, verbose); print_exp (pp, x, verbose);
cur = safe_concat (buf, cur, t);
break; break;
} }
} /* print_value */ } /* print_value */
/* Print X, an RTL value node, to file F in slim format. Include
additional information if VERBOSE is nonzero.
Value nodes are constants, registers, labels, symbols and
memory. */
void
dump_value_slim (FILE *f, const_rtx x, int verbose)
{
char buf[BUF_LEN];
print_value (buf, x, verbose);
fprintf (f, "%s", buf);
}
/* The next step in insn detalization, its pattern recognition. */ /* The next step in insn detalization, its pattern recognition. */
void void
print_pattern (char *buf, const_rtx x, int verbose) print_pattern (pretty_printer *pp, const_rtx x, int verbose)
{ {
char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
if (! x) if (! x)
{ {
sprintf (buf, "(nil)"); pp_string (pp, "(nil)");
return; return;
} }
switch (GET_CODE (x)) switch (GET_CODE (x))
{ {
case SET: case SET:
print_value (t1, SET_DEST (x), verbose); print_value (pp, SET_DEST (x), verbose);
print_value (t2, SET_SRC (x), verbose); pp_character (pp, '=');
sprintf (buf, "%s=%s", t1, t2); print_value (pp, SET_SRC (x), verbose);
break; break;
case RETURN: case RETURN:
case SIMPLE_RETURN: case SIMPLE_RETURN:
case EH_RETURN: case EH_RETURN:
sprintf (buf, GET_RTX_NAME (GET_CODE (x))); pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
break; break;
case CALL: case CALL:
print_exp (buf, x, verbose); print_exp (pp, x, verbose);
break; break;
case CLOBBER: case CLOBBER:
case USE: case USE:
print_value (t1, XEXP (x, 0), verbose); pp_printf (pp, "%s ", GET_RTX_NAME (GET_CODE (x)));
sprintf (buf, "%s %s", GET_RTX_NAME (GET_CODE (x)), t1); print_value (pp, XEXP (x, 0), verbose);
break; break;
case VAR_LOCATION: case VAR_LOCATION:
print_value (t1, PAT_VAR_LOCATION_LOC (x), verbose); pp_string (pp, "loc ");
sprintf (buf, "loc %s", t1); print_value (pp, PAT_VAR_LOCATION_LOC (x), verbose);
break; break;
case COND_EXEC: case COND_EXEC:
pp_character (pp, '(');
if (GET_CODE (COND_EXEC_TEST (x)) == NE if (GET_CODE (COND_EXEC_TEST (x)) == NE
&& XEXP (COND_EXEC_TEST (x), 1) == const0_rtx) && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose); print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
else if (GET_CODE (COND_EXEC_TEST (x)) == EQ else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
&& XEXP (COND_EXEC_TEST (x), 1) == const0_rtx) && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
{ {
t1[0] = '!'; pp_character (pp, '!');
print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose); print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
} }
else else
print_value (t1, COND_EXEC_TEST (x), verbose); print_value (pp, COND_EXEC_TEST (x), verbose);
print_pattern (t2, COND_EXEC_CODE (x), verbose); pp_string (pp, ") ");
sprintf (buf, "(%s) %s", t1, t2); print_pattern (pp, COND_EXEC_CODE (x), verbose);
break; break;
case PARALLEL: case PARALLEL:
{ {
int i; int i;
sprintf (t1, "{"); pp_character (pp, '{');
for (i = 0; i < XVECLEN (x, 0); i++) for (i = 0; i < XVECLEN (x, 0); i++)
{ {
print_pattern (t2, XVECEXP (x, 0, i), verbose); print_pattern (pp, XVECEXP (x, 0, i), verbose);
sprintf (t3, "%s%s;", t1, t2); pp_character (pp, ';');
strcpy (t1, t3);
} }
sprintf (buf, "%s}", t1); pp_character (pp, '}');
} }
break; break;
case SEQUENCE: case SEQUENCE:
{ {
int i; int i;
sprintf (t1, "sequence{"); pp_string (pp, "sequence{");
for (i = 0; i < XVECLEN (x, 0); i++) for (i = 0; i < XVECLEN (x, 0); i++)
{ {
print_pattern (t2, XVECEXP (x, 0, i), verbose); print_pattern (pp, XVECEXP (x, 0, i), verbose);
sprintf (t3, "%s%s;", t1, t2); pp_character (pp, ';');
strcpy (t1, t3);
} }
sprintf (buf, "%s}", t1); pp_character (pp, '}');
} }
break; break;
case ASM_INPUT: case ASM_INPUT:
sprintf (buf, "asm {%s}", XSTR (x, 0)); pp_printf (pp, "asm {%s}", XSTR (x, 0));
break; break;
case ADDR_VEC: case ADDR_VEC:
/* Fall through. */ /* Fall through. */
case ADDR_DIFF_VEC: case ADDR_DIFF_VEC:
print_value (buf, XEXP (x, 0), verbose); print_value (pp, XEXP (x, 0), verbose);
break; break;
case TRAP_IF: case TRAP_IF:
print_value (t1, TRAP_CONDITION (x), verbose); pp_string (pp, "trap_if ");
sprintf (buf, "trap_if %s", t1); print_value (pp, TRAP_CONDITION (x), verbose);
break; break;
case UNSPEC: case UNSPEC:
case UNSPEC_VOLATILE: case UNSPEC_VOLATILE:
/* Fallthru -- leave UNSPECs to print_exp. */ /* Fallthru -- leave UNSPECs to print_exp. */
default: default:
print_value (buf, x, verbose); print_value (pp, x, verbose);
} }
} /* print_pattern */ } /* print_pattern */
/* This is the main function in slim rtl visualization mechanism. /* This is the main function in slim rtl visualization mechanism.
X is an insn, to be printed into BUF. X is an insn, to be printed into PP.
This function tries to print it properly in human-readable form, This function tries to print it properly in human-readable form,
resembling assembler mnemonics (instead of the older Lisp-style resembling assembler mnemonics (instead of the older Lisp-style
@ -672,15 +607,20 @@ print_pattern (char *buf, const_rtx x, int verbose)
with their INSN_UIDs. */ with their INSN_UIDs. */
void void
print_insn (char *buf, const_rtx x, int verbose) print_insn (pretty_printer *pp, const_rtx x, int verbose)
{ {
/* Collect the string to output for X in t1. t2 is a scratch area. */ if (verbose)
char t1[BUF_LEN], t2[BUF_LEN]; {
/* Blech, pretty-print can't print integers with a specified width. */
char uid_prefix[32];
snprintf (uid_prefix, sizeof uid_prefix, " %4d: ", INSN_UID (x));
pp_string (pp, uid_prefix);
}
switch (GET_CODE (x)) switch (GET_CODE (x))
{ {
case INSN: case INSN:
print_pattern (t1, PATTERN (x), verbose); print_pattern (pp, PATTERN (x), verbose);
break; break;
case DEBUG_INSN: case DEBUG_INSN:
@ -707,47 +647,46 @@ print_insn (char *buf, const_rtx x, int verbose)
name = idbuf; name = idbuf;
} }
} }
pp_printf (pp, "debug %s => ", name);
if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x))) if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x)))
sprintf (t1, "debug %s optimized away", name); pp_string (pp, "optimized away");
else else
{ print_pattern (pp, INSN_VAR_LOCATION_LOC (x), verbose);
print_pattern (t2, INSN_VAR_LOCATION_LOC (x), verbose);
sprintf (t1, "debug %s => %s", name, t2);
}
} }
break; break;
case JUMP_INSN: case JUMP_INSN:
print_pattern (t1, PATTERN (x), verbose); print_pattern (pp, PATTERN (x), verbose);
break; break;
case CALL_INSN: case CALL_INSN:
if (GET_CODE (PATTERN (x)) == PARALLEL) if (GET_CODE (PATTERN (x)) == PARALLEL)
print_pattern (t1, XVECEXP (PATTERN (x), 0, 0), verbose); print_pattern (pp, XVECEXP (PATTERN (x), 0, 0), verbose);
else else
print_pattern (t1, PATTERN (x), verbose); print_pattern (pp, PATTERN (x), verbose);
break; break;
case CODE_LABEL: case CODE_LABEL:
sprintf (t1, "L%d:", INSN_UID (x)); pp_printf (pp, "L%d:", INSN_UID (x));
break; break;
case BARRIER: case BARRIER:
sprintf (t1, "barrier"); pp_string (pp, "barrier");
break; break;
case NOTE: case NOTE:
{ {
pp_string (pp, GET_NOTE_INSN_NAME (NOTE_KIND (x)));
switch (NOTE_KIND (x)) switch (NOTE_KIND (x))
{ {
case NOTE_INSN_EH_REGION_BEG: case NOTE_INSN_EH_REGION_BEG:
case NOTE_INSN_EH_REGION_END: case NOTE_INSN_EH_REGION_END:
sprintf (t2, "%d", NOTE_EH_HANDLER (x)); pp_printf (pp, " %d", NOTE_EH_HANDLER (x));
break; break;
case NOTE_INSN_BLOCK_BEG: case NOTE_INSN_BLOCK_BEG:
case NOTE_INSN_BLOCK_END: case NOTE_INSN_BLOCK_END:
sprintf (t2, "%d", BLOCK_NUMBER (NOTE_BLOCK (x))); pp_printf (pp, " %d", BLOCK_NUMBER (NOTE_BLOCK (x)));
break; break;
case NOTE_INSN_BASIC_BLOCK: case NOTE_INSN_BASIC_BLOCK:
sprintf (t2, "%d", NOTE_BASIC_BLOCK (x)->index); pp_printf (pp, " %d", NOTE_BASIC_BLOCK (x)->index);
break; break;
case NOTE_INSN_DELETED_LABEL: case NOTE_INSN_DELETED_LABEL:
@ -756,57 +695,86 @@ print_insn (char *buf, const_rtx x, int verbose)
const char *label = NOTE_DELETED_LABEL_NAME (x); const char *label = NOTE_DELETED_LABEL_NAME (x);
if (label == NULL) if (label == NULL)
label = ""; label = "";
sprintf (t2, "(\"%s\")", label); pp_printf (pp, " (\"%s\")", label);
} }
break; break;
case NOTE_INSN_VAR_LOCATION: case NOTE_INSN_VAR_LOCATION:
case NOTE_INSN_CALL_ARG_LOCATION: case NOTE_INSN_CALL_ARG_LOCATION:
/* It's safe here to use t1 for scratch because the output pp_character (pp, '{');
is printed in t2 and put back in t1 at the bottom of print_pattern (pp, NOTE_VAR_LOCATION (x), verbose);
the inner switch statement. */ pp_character (pp, '}');
print_pattern (t1, NOTE_VAR_LOCATION (x), verbose);
sprintf (t2, "{%s}", t1);
break; break;
default: default:
t2[0] = '\0';
break; break;
} }
sprintf (t1, "%s %s", GET_NOTE_INSN_NAME (NOTE_KIND (x)), t2);
break; break;
} }
default: default:
sprintf (t1, "<What %s?>", GET_RTX_NAME (GET_CODE (x))); gcc_unreachable ();
break;
} }
if (verbose)
sprintf (buf, " %4d: %s", INSN_UID (x), t1);
else
sprintf (buf, "%s", t1);
} /* print_insn */ } /* print_insn */
/* Prerry-print a slim dump of X (an insn) to PP, including any register
note attached to the instruction. */
static void
print_insn_with_notes (pretty_printer *pp, const_rtx x)
{
pp_string (pp, print_rtx_head);
print_insn (pp, x, 1);
pp_newline (pp);
if (INSN_P (x) && REG_NOTES (x))
for (rtx note = REG_NOTES (x); note; note = XEXP (note, 1))
{
pp_printf (pp, "%s %s", print_rtx_head,
GET_REG_NOTE_NAME (REG_NOTE_KIND (note)));
print_pattern (pp, XEXP (note, 0), 1);
pp_newline (pp);
}
}
/* Return a pretty-print buffer set up to print to file F. */
static pretty_printer *
init_rtl_slim_pretty_print (FILE *f)
{
if (! rtl_slim_pp_initialized)
{
pp_construct (&rtl_slim_pp, /*prefix=*/NULL, /*linewidth=*/0);
rtl_slim_pp_initialized = true;
}
else
/* Clean out any data that str_insn_slim may have left here. */
pp_clear_output_area (&rtl_slim_pp);
rtl_slim_pp.buffer->stream = f;
return &rtl_slim_pp;
}
/* Print X, an RTL value node, to file F in slim format. Include
additional information if VERBOSE is nonzero.
Value nodes are constants, registers, labels, symbols and
memory. */
void
dump_value_slim (FILE *f, const_rtx x, int verbose)
{
pretty_printer *pp = init_rtl_slim_pretty_print (f);
print_value (pp, x, verbose);
pp_flush (pp);
}
/* Emit a slim dump of X (an insn) to the file F, including any register /* Emit a slim dump of X (an insn) to the file F, including any register
note attached to the instruction. */ note attached to the instruction. */
void void
dump_insn_slim (FILE *f, const_rtx x) dump_insn_slim (FILE *f, const_rtx x)
{ {
char t[BUF_LEN + 32]; pretty_printer *pp = init_rtl_slim_pretty_print (f);
rtx note; print_insn_with_notes (pp, x);
pp_flush (pp);
print_insn (t, x, 1);
fputs (print_rtx_head, f);
fputs (t, f);
putc ('\n', f);
if (INSN_P (x) && REG_NOTES (x))
for (note = REG_NOTES (x); note; note = XEXP (note, 1))
{
fputs (print_rtx_head, f);
print_pattern (t, XEXP (note, 0), 1);
fprintf (f, " %s: %s\n",
GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
}
} }
/* Same as above, but stop at LAST or when COUNT == 0. /* Same as above, but stop at LAST or when COUNT == 0.
@ -817,16 +785,33 @@ dump_rtl_slim (FILE *f, const_rtx first, const_rtx last,
int count, int flags ATTRIBUTE_UNUSED) int count, int flags ATTRIBUTE_UNUSED)
{ {
const_rtx insn, tail; const_rtx insn, tail;
pretty_printer *pp = init_rtl_slim_pretty_print (f);
tail = last ? NEXT_INSN (last) : NULL_RTX; tail = last ? NEXT_INSN (last) : NULL_RTX;
for (insn = first; for (insn = first;
(insn != NULL) && (insn != tail) && (count != 0); (insn != NULL) && (insn != tail) && (count != 0);
insn = NEXT_INSN (insn)) insn = NEXT_INSN (insn))
{ {
dump_insn_slim (f, insn); print_insn_with_notes (pp, insn);
if (count > 0) if (count > 0)
count--; count--;
} }
pp_flush (pp);
}
/* Pretty-print pattern X of some insn in non-verbose mode.
Return a string pointer to the pretty-printer buffer.
This function is only exported exists only to accommodate some older users
of the slim RTL pretty printers. Please do not use it for new code. */
const char *
str_pattern_slim (const_rtx x)
{
pretty_printer *pp = init_rtl_slim_pretty_print (NULL);
print_pattern (pp, x, 0);
return pp_base_formatted_text (pp);
} }
/* Emit a slim dump of X (an insn) to stderr. */ /* Emit a slim dump of X (an insn) to stderr. */

View file

@ -136,12 +136,7 @@ dump_insn_rtx_1 (rtx insn, int flags)
sel_print ("%d;", INSN_UID (insn)); sel_print ("%d;", INSN_UID (insn));
if (flags & DUMP_INSN_RTX_PATTERN) if (flags & DUMP_INSN_RTX_PATTERN)
{ sel_print ("%s;", str_pattern_slim (insn));
char buf[2048];
print_insn (buf, insn, 0);
sel_print ("%s;", buf);
}
if (flags & DUMP_INSN_RTX_BBN) if (flags & DUMP_INSN_RTX_BBN)
{ {
@ -522,6 +517,7 @@ sel_print_insn (const_rtx insn, int aligned ATTRIBUTE_UNUSED)
/* Functions for pretty printing of CFG. */ /* Functions for pretty printing of CFG. */
/* FIXME: Using pretty-print here could simplify this stuff. */
/* Replace all occurencies of STR1 to STR2 in BUF. /* Replace all occurencies of STR1 to STR2 in BUF.
The BUF must be large enough to hold the result. */ The BUF must be large enough to hold the result. */
@ -564,7 +560,8 @@ replace_str_in_buf (char *buf, const char *str1, const char *str2)
while (p); while (p);
} }
/* Replace characters in BUF that have special meaning in .dot file. */ /* Replace characters in BUF that have special meaning in .dot file.
Similar to pp_write_text_as_dot_label_to_stream. */
static void static void
sel_prepare_string_for_dot_label (char *buf) sel_prepare_string_for_dot_label (char *buf)
{ {