Commit a27a5de9 by Steven Bosscher

invoke.texi: Remove -dv documentation.

gcc/
	* doc/invoke.texi: Remove -dv documentation.  Fix up graph dump related
	documentation.  Document the '-graph' dump option.  Complete the '-slim'
	dump option documentation.

	* common.opt (Variable graph_dump_format): Remove.
	* flag-types.h (enum graph_dump_types): Remove.
	* flags.h (dump_for_graph): Remove.
	* opts.c (decode_d_option): Remove -dv handling.
	* sched-int.h (print_insn, print_pattern, print_value): Move prototypes
	from here ...
	* rtl.h: ...to here.  Add note that these functions ought to be in
	another file.
	* sched-vis.c (print_insn): Add detailed dump for insn notes.
	* print-rtl.c (dump_for_graph): Remove.
	(print_rtx): Remove dump_for_graph related code.
	* graph.c: Almost complete re-write to dump DOT (GraphViz) dumps
	instead of VCG dumps.
	* graph.h (print_rtl_graph_with_bb): Update prototype.
	* passes.c (finish_optimization_passes): Fix profile dump finishing.
	Unconditionally loop over graph dumps to finalize.
	(execute_function_dump): Split code to dump graphs to separate block.
	(execute_one_pass): Don't set TDF_GRAPH here, let the dump option
	decoders do their job.

	* ddg.c (vcg_print_ddg): Make it a DEBUG_FUNCTION.
	* toplev.c: Don't include graph.h.
	* tree-optimize.c: Don't include graph.h.

testsuite/
	* testsuite/gcc.dg/20050811-1.c: Change -dv option to -graph option
	to -fdump-rtl-all.
	* testsuite/gcc.dg/pr37858.c: Remove -dv option.

From-SVN: r193821
parent f460c170
2012-11-26 Steven Bosscher <steven@gcc.gnu.org>
* doc/invoke.texi: Remove -dv documentation. Fix up graph dump related
documentation. Document the '-graph' dump option. Complete the '-slim'
dump option documentation.
* common.opt (Variable graph_dump_format): Remove.
* flag-types.h (enum graph_dump_types): Remove.
* flags.h (dump_for_graph): Remove.
* opts.c (decode_d_option): Remove -dv handling.
* sched-int.h (print_insn, print_pattern, print_value): Move prototypes
from here ...
* rtl.h: ...to here. Add note that these functions ought to be in
another file.
* sched-vis.c (print_insn): Add detailed dump for insn notes.
* print-rtl.c (dump_for_graph): Remove.
(print_rtx): Remove dump_for_graph related code.
* graph.c: Almost complete re-write to dump DOT (GraphViz) dumps
instead of VCG dumps.
* graph.h (print_rtl_graph_with_bb): Update prototype.
* passes.c (finish_optimization_passes): Fix profile dump finishing.
Unconditionally loop over graph dumps to finalize.
(execute_function_dump): Split code to dump graphs to separate block.
(execute_one_pass): Don't set TDF_GRAPH here, let the dump option
decoders do their job.
* ddg.c (vcg_print_ddg): Make it a DEBUG_FUNCTION.
* toplev.c: Don't include graph.h.
* tree-optimize.c: Don't include graph.h.
2012-11-26 Marek Polacek <polacek@redhat.com> 2012-11-26 Marek Polacek <polacek@redhat.com>
* cprop.c (hash_set): Remove variable. Use regno * cprop.c (hash_set): Remove variable. Use regno
...@@ -174,9 +174,6 @@ int rtl_dump_and_exit ...@@ -174,9 +174,6 @@ int rtl_dump_and_exit
Variable Variable
int flag_print_asm_name int flag_print_asm_name
Variable
enum graph_dump_types graph_dump_format = no_graph
; Name of top-level original source file (what was input to cpp). ; Name of top-level original source file (what was input to cpp).
; This comes from the #-command at the beginning of the actual input. ; This comes from the #-command at the beginning of the actual input.
; If there isn't any there, then this is the cc1 input file name. ; If there isn't any there, then this is the cc1 input file name.
......
...@@ -753,7 +753,7 @@ print_ddg (FILE *file, ddg_ptr g) ...@@ -753,7 +753,7 @@ print_ddg (FILE *file, ddg_ptr g)
} }
/* Print the given DDG in VCG format. */ /* Print the given DDG in VCG format. */
void DEBUG_FUNCTION void
vcg_print_ddg (FILE *file, ddg_ptr g) vcg_print_ddg (FILE *file, ddg_ptr g)
{ {
int src_cuid; int src_cuid;
......
...@@ -5371,7 +5371,7 @@ appended with a sequential number starting from 1. @var{range-list} is a ...@@ -5371,7 +5371,7 @@ appended with a sequential number starting from 1. @var{range-list} is a
comma-separated list of function ranges or assembler names. Each range is a number comma-separated list of function ranges or assembler names. Each range is a number
pair separated by a colon. The range is inclusive in both ends. If the range pair separated by a colon. The range is inclusive in both ends. If the range
is trivial, the number pair can be simplified as a single number. If the is trivial, the number pair can be simplified as a single number. If the
function's cgraph node's @var{uid} falls within one of the specified ranges, function's call graph node's @var{uid} falls within one of the specified ranges,
the @var{pass} is disabled for that function. The @var{uid} is shown in the the @var{pass} is disabled for that function. The @var{uid} is shown in the
function header of a dump file, and the pass names can be dumped by using function header of a dump file, and the pass names can be dumped by using
option @option{-fdump-passes}. option @option{-fdump-passes}.
...@@ -5727,12 +5727,6 @@ also printed. ...@@ -5727,12 +5727,6 @@ also printed.
Dump the RTL in the assembler output as a comment before each instruction. Dump the RTL in the assembler output as a comment before each instruction.
Also turns on @option{-dp} annotation. Also turns on @option{-dp} annotation.
@item -dv
@opindex dv
For each of the other indicated dump files (@option{-fdump-rtl-@var{pass}}),
dump a representation of the control flow graph suitable for viewing with VCG
to @file{@var{file}.@var{pass}.vcg}.
@item -dx @item -dx
@opindex dx @opindex dx
Just generate RTL for a function instead of compiling it. Usually used Just generate RTL for a function instead of compiling it. Usually used
...@@ -5841,10 +5835,16 @@ If @code{DECL_ASSEMBLER_NAME} has been set for a given decl, use that ...@@ -5841,10 +5835,16 @@ If @code{DECL_ASSEMBLER_NAME} has been set for a given decl, use that
in the dump instead of @code{DECL_NAME}. Its primary use is ease of in the dump instead of @code{DECL_NAME}. Its primary use is ease of
use working backward from mangled names in the assembly file. use working backward from mangled names in the assembly file.
@item slim @item slim
Inhibit dumping of members of a scope or body of a function merely When dumping front-end intermediate representations, inhibit dumping
because that scope has been reached. Only dump such items when they of members of a scope or body of a function merely because that scope
are directly reachable by some other path. When dumping pretty-printed has been reached. Only dump such items when they are directly reachable
trees, this option inhibits dumping the bodies of control structures. by some other path.
When dumping pretty-printed trees, this option inhibits dumping the
bodies of control structures.
When dumping RTL, print the RTL in slim (condensed) form instead of
the default LISP-like representation.
@item raw @item raw
Print a raw representation of the tree. By default, trees are Print a raw representation of the tree. By default, trees are
pretty-printed into a C-like representation. pretty-printed into a C-like representation.
...@@ -5856,6 +5856,16 @@ Enable dumping various statistics about the pass (not honored by every dump ...@@ -5856,6 +5856,16 @@ Enable dumping various statistics about the pass (not honored by every dump
option). option).
@item blocks @item blocks
Enable showing basic block boundaries (disabled in raw dumps). Enable showing basic block boundaries (disabled in raw dumps).
@item graph
For each of the other indicated dump files (@option{-fdump-rtl-@var{pass}}),
dump a representation of the control flow graph suitable for viewing with
GraphViz to @file{@var{file}.@var{passid}.@var{pass}.dot}. Note that if
the file contains more than one function, the generated file cannot be
used directly by GraphViz@. You must cut and paste each function's
graph into its own separate file first.
This option currently only works for RTL dumps, and the RTL is always
dumped in slim form.
@item vops @item vops
Enable showing virtual operands for every statement. Enable showing virtual operands for every statement.
@item lineno @item lineno
......
...@@ -141,13 +141,6 @@ enum excess_precision ...@@ -141,13 +141,6 @@ enum excess_precision
EXCESS_PRECISION_STANDARD EXCESS_PRECISION_STANDARD
}; };
/* Selection of the graph form. */
enum graph_dump_types
{
no_graph = 0,
vcg
};
/* Type of stack check. */ /* Type of stack check. */
enum stack_check_type enum stack_check_type
{ {
......
...@@ -89,9 +89,6 @@ extern struct target_flag_state *this_target_flag_state; ...@@ -89,9 +89,6 @@ extern struct target_flag_state *this_target_flag_state;
#define flag_excess_precision \ #define flag_excess_precision \
(this_target_flag_state->x_flag_excess_precision) (this_target_flag_state->x_flag_excess_precision)
/* Nonzero if we dump in VCG format, not plain text. */
extern int dump_for_graph;
/* Returns TRUE if generated code should match ABI version N or /* Returns TRUE if generated code should match ABI version N or
greater is in use. */ greater is in use. */
......
/* Output routines for graphical representation. /* Output routines for graphical representation.
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2007, 2008, 2010 Copyright (C) 1998-2012
Free Software Foundation, Inc. Free Software Foundation, Inc.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
Rewritten for DOT output by Steven Bosscher, 2012.
This file is part of GCC. This file is part of GCC.
...@@ -22,396 +23,244 @@ along with GCC; see the file COPYING3. If not see ...@@ -22,396 +23,244 @@ along with GCC; see the file COPYING3. If not see
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
#include "coretypes.h" #include "coretypes.h"
#include "tm.h" #include "diagnostic-core.h" /* for fatal_error */
#include "rtl.h" #include "sbitmap.h"
#include "flags.h"
#include "function.h"
#include "hard-reg-set.h"
#include "obstack.h"
#include "basic-block.h" #include "basic-block.h"
#include "diagnostic-core.h" #include "rtl.h"
#include "tree.h"
#include "graph.h" #include "graph.h"
#include "emit-rtl.h"
static const char *const graph_ext[] =
{
/* no_graph */ "",
/* vcg */ ".vcg",
};
/* The flag to indicate if output is inside of a building block. */ /* DOT files with the .dot extension are recognized as document templates
static int inbb = 0; by a well-known piece of word processing software out of Redmond, WA.
Therefore some recommend using the .gv extension instead. Obstinately
ignore that recommendatition... */
static const char *const graph_ext = ".dot";
static void start_fct (FILE *); /* Open a file with MODE for dumping our graph to.
static void start_bb (FILE *, int); Return the file pointer. */
static void node_data (FILE *, rtx); static FILE *
static void draw_edge (FILE *, int, int, int, int); open_graph_file (const char *base, const char *mode)
static void end_fct (FILE *);
static void end_bb (FILE *);
/* Output text for new basic block. */
static void
start_fct (FILE *fp)
{ {
switch (graph_dump_format) size_t namelen = strlen (base);
{ size_t extlen = strlen (graph_ext) + 1;
case vcg: char *buf = XALLOCAVEC (char, namelen + extlen);
fprintf (fp, "\ FILE *fp;
graph: { title: \"%s\"\nfolding: 1\nhidden: 2\nnode: { title: \"%s.0\" }\n",
current_function_name (), current_function_name ());
break;
case no_graph:
break;
}
}
static void
start_bb (FILE *fp, int bb)
{
#if 0
reg_set_iterator rsi;
#endif
switch (graph_dump_format)
{
case vcg:
fprintf (fp, "\
graph: {\ntitle: \"%s.BB%d\"\nfolding: 1\ncolor: lightblue\n\
label: \"basic block %d",
current_function_name (), bb, bb);
inbb = 1; /* Now We are inside of a building block. */
break;
case no_graph:
break;
}
#if 0 memcpy (buf, base, namelen);
/* FIXME Should this be printed? It makes the graph significantly larger. */ memcpy (buf + namelen, graph_ext, extlen);
/* Print the live-at-start register list. */ fp = fopen (buf, mode);
fputc ('\n', fp); if (fp == NULL)
EXECUTE_IF_SET_IN_REG_SET (basic_block_live_at_start[bb], 0, i, rsi) fatal_error ("can%'t open %s: %m", buf);
{
fprintf (fp, " %d", i);
if (i < FIRST_PSEUDO_REGISTER)
fprintf (fp, " [%s]", reg_names[i]);
}
#endif
switch (graph_dump_format) return fp;
{
case vcg:
fputs ("\"\n\n", fp);
break;
case no_graph:
break;
}
} }
static void /* Print the output from print_insn or print_pattern with GraphViz-special
node_data (FILE *fp, rtx tmp_rtx) characters escaped as necessary. */
void
print_escaped_line (FILE *fp, const char *buf)
{ {
if (PREV_INSN (tmp_rtx) == 0) const char *p = buf;
while (*p)
{ {
/* This is the first instruction. Add an edge from the starting switch (*p)
block. */
switch (graph_dump_format)
{ {
case vcg: case '\n':
fprintf (fp, "\ /* Print newlines as a left-aligned newline. */
edge: { sourcename: \"%s.0\" targetname: \"%s.%d\" }\n", fputs ("\\l\\\n", fp);
current_function_name (),
current_function_name (), XINT (tmp_rtx, 0));
break; break;
case no_graph:
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; break;
} }
p++;
} }
fputs ("\\l\\\n", fp);
}
switch (graph_dump_format) /* Draw a basic block BB belonging to the function with FNDECL_UID
{ as its unique number. */
case vcg: static void
fprintf (fp, "node: {\n title: \"%s.%d\"\n color: %s\n \ draw_cfg_node (FILE *fp, int fndecl_uid, basic_block bb)
label: \"%s %d\n", {
current_function_name (), XINT (tmp_rtx, 0), rtx insn;
NOTE_P (tmp_rtx) ? "lightgrey" bool first = true;
: NONJUMP_INSN_P (tmp_rtx) ? "green" const char *shape;
: JUMP_P (tmp_rtx) ? "darkgreen" const char *fillcolor;
: CALL_P (tmp_rtx) ? "darkgreen"
: LABEL_P (tmp_rtx) ? "\
darkgrey\n shape: ellipse" : "white",
GET_RTX_NAME (GET_CODE (tmp_rtx)), XINT (tmp_rtx, 0));
break;
case no_graph:
break;
}
/* Print the RTL. */ if (bb->index == ENTRY_BLOCK || bb->index == EXIT_BLOCK)
if (NOTE_P (tmp_rtx))
{ {
const char *name; shape = "Mdiamond";
name = GET_NOTE_INSN_NAME (NOTE_KIND (tmp_rtx)); fillcolor = "white";
fprintf (fp, " %s", name);
} }
else if (INSN_P (tmp_rtx))
print_rtl_single (fp, PATTERN (tmp_rtx));
else else
print_rtl_single (fp, tmp_rtx);
switch (graph_dump_format)
{ {
case vcg: shape = "record";
fputs ("\"\n}\n", fp); fillcolor =
break; BB_PARTITION (bb) == BB_HOT_PARTITION ? "lightpink"
case no_graph: : BB_PARTITION (bb) == BB_COLD_PARTITION ? "lightblue"
break; : "lightgrey";
} }
}
static void fprintf (fp,
draw_edge (FILE *fp, int from, int to, int bb_edge, int color_class) "\tfn_%d_basic_block_%d [shape=%s,style=filled,fillcolor=%s,label=\"",
{ fndecl_uid, bb->index, shape, fillcolor);
const char * color;
switch (graph_dump_format)
{
case vcg:
color = "";
if (color_class == 2)
color = "color: red ";
else if (bb_edge)
color = "color: blue ";
else if (color_class == 3)
color = "color: green ";
fprintf (fp,
"edge: { sourcename: \"%s.%d\" targetname: \"%s.%d\" %s",
current_function_name (), from,
current_function_name (), to, color);
if (color_class)
fprintf (fp, "class: %d ", color_class);
fputs ("}\n", fp);
break;
case no_graph:
break;
}
}
static void if (bb->index == ENTRY_BLOCK)
end_bb (FILE *fp) fputs ("ENTRY", fp);
{ else if (bb->index == EXIT_BLOCK)
switch (graph_dump_format) fputs ("EXIT", fp);
else
{ {
case vcg: fputc ('{', fp);
/* Check if we are inside of a building block. */ /* TODO: inter-bb stuff. */
if (inbb != 0) FOR_BB_INSNS (bb, insn)
{ {
fputs ("}\n", fp); char buf[2048];
inbb = 0; /* Now we are outside of a building block. */
} if (! first)
break; fputc ('|', fp);
case no_graph:
break; print_insn (buf, insn, 1);
print_escaped_line (fp, buf);
if (INSN_P (insn) && REG_NOTES (insn))
for (rtx note = REG_NOTES (insn); note; note = XEXP (note, 1))
{
fprintf (fp, " %s: ",
GET_REG_NOTE_NAME (REG_NOTE_KIND (note)));
print_pattern (buf, XEXP (note, 0), 1);
print_escaped_line (fp, buf);
}
first = false;
}
fputc ('}', fp);
} }
fputs ("\"];\n\n", fp);
} }
/* Draw all successor edges of a basic block BB belonging to the function
with FNDECL_UID as its unique number. */
static void static void
end_fct (FILE *fp) draw_cfg_node_succ_edges (FILE *fp, int fndecl_uid, basic_block bb)
{ {
switch (graph_dump_format) edge e;
edge_iterator ei;
FOR_EACH_EDGE (e, ei, bb->succs)
{ {
case vcg: const char *style = "\"solid,bold\"";
fprintf (fp, "node: { title: \"%s.999999\" label: \"END\" }\n}\n", const char *color = "black";
current_function_name ()); int weight = 10;
break;
case no_graph:
break;
}
}
/* Like print_rtl, but also print out live information for the start of each
basic block. */
void
print_rtl_graph_with_bb (const char *base, rtx rtx_first)
{
rtx tmp_rtx;
size_t namelen = strlen (base);
size_t extlen = strlen (graph_ext[graph_dump_format]) + 1;
char *buf = XALLOCAVEC (char, namelen + extlen);
FILE *fp;
if (!basic_block_info)
return;
memcpy (buf, base, namelen); if (e->flags & EDGE_FAKE)
memcpy (buf + namelen, graph_ext[graph_dump_format], extlen);
fp = fopen (buf, "a");
if (fp == NULL)
return;
if (rtx_first == 0)
fprintf (fp, "(nil)\n");
else
{
enum bb_state { NOT_IN_BB, IN_ONE_BB, IN_MULTIPLE_BB };
int max_uid = get_max_uid ();
int *start = XNEWVEC (int, max_uid);
int *end = XNEWVEC (int, max_uid);
enum bb_state *in_bb_p = XNEWVEC (enum bb_state, max_uid);
basic_block bb;
int i;
for (i = 0; i < max_uid; ++i)
{ {
start[i] = end[i] = -1; style = "dotted";
in_bb_p[i] = NOT_IN_BB; color = "green";
weight = 0;
} }
else if (e->flags & EDGE_DFS_BACK)
FOR_EACH_BB_REVERSE (bb)
{ {
rtx x; style = "\"dotted,bold\"";
start[INSN_UID (BB_HEAD (bb))] = bb->index; color = "blue";
end[INSN_UID (BB_END (bb))] = bb->index; weight = 10;
for (x = BB_HEAD (bb); x != NULL_RTX; x = NEXT_INSN (x))
{
in_bb_p[INSN_UID (x)]
= (in_bb_p[INSN_UID (x)] == NOT_IN_BB)
? IN_ONE_BB : IN_MULTIPLE_BB;
if (x == BB_END (bb))
break;
}
} }
else if (e->flags & EDGE_FALLTHRU)
/* Tell print-rtl that we want graph output. */
dump_for_graph = 1;
/* Start new function. */
start_fct (fp);
for (tmp_rtx = NEXT_INSN (rtx_first); NULL != tmp_rtx;
tmp_rtx = NEXT_INSN (tmp_rtx))
{ {
int edge_printed = 0; color = "blue";
rtx next_insn; weight = 100;
if (start[INSN_UID (tmp_rtx)] < 0 && end[INSN_UID (tmp_rtx)] < 0)
{
if (BARRIER_P (tmp_rtx))
continue;
if (NOTE_P (tmp_rtx)
&& (1 || in_bb_p[INSN_UID (tmp_rtx)] == NOT_IN_BB))
continue;
}
if ((i = start[INSN_UID (tmp_rtx)]) >= 0)
{
/* We start a subgraph for each basic block. */
start_bb (fp, i);
if (i == 0)
draw_edge (fp, 0, INSN_UID (tmp_rtx), 1, 0);
}
/* Print the data for this node. */
node_data (fp, tmp_rtx);
next_insn = next_nonnote_insn (tmp_rtx);
if ((i = end[INSN_UID (tmp_rtx)]) >= 0)
{
edge e;
edge_iterator ei;
bb = BASIC_BLOCK (i);
/* End of the basic block. */
end_bb (fp);
/* Now specify the edges to all the successors of this
basic block. */
FOR_EACH_EDGE (e, ei, bb->succs)
{
if (e->dest != EXIT_BLOCK_PTR)
{
rtx block_head = BB_HEAD (e->dest);
draw_edge (fp, INSN_UID (tmp_rtx),
INSN_UID (block_head),
next_insn != block_head,
(e->flags & EDGE_ABNORMAL ? 2 : 0));
if (block_head == next_insn)
edge_printed = 1;
}
else
{
draw_edge (fp, INSN_UID (tmp_rtx), 999999,
next_insn != 0,
(e->flags & EDGE_ABNORMAL ? 2 : 0));
if (next_insn == 0)
edge_printed = 1;
}
}
}
if (!edge_printed)
{
/* Don't print edges to barriers. */
if (next_insn == 0
|| !BARRIER_P (next_insn))
draw_edge (fp, XINT (tmp_rtx, 0),
next_insn ? INSN_UID (next_insn) : 999999, 0, 0);
else
{
/* We draw the remaining edges in class 3. We have
to skip over the barrier since these nodes are
not printed at all. */
do
next_insn = NEXT_INSN (next_insn);
while (next_insn
&& (NOTE_P (next_insn)
|| BARRIER_P (next_insn)));
draw_edge (fp, XINT (tmp_rtx, 0),
next_insn ? INSN_UID (next_insn) : 999999, 0, 3);
}
}
} }
dump_for_graph = 0; if (e->flags & EDGE_ABNORMAL)
color = "red";
end_fct (fp); fprintf (fp,
"\tfn_%d_basic_block_%d:s -> fn_%d_basic_block_%d:n "
/* Clean up. */ "[style=%s,color=%s,weight=%d,constraint=%s];\n",
free (start); fndecl_uid, e->src->index,
free (end); fndecl_uid, e->dest->index,
free (in_bb_p); style, color, weight,
(e->flags & (EDGE_FAKE | EDGE_DFS_BACK)) ? "false" : "true");
} }
}
/* Print a graphical representation of the CFG of function FUN.
Currently only supports RTL in cfgrtl or cfglayout mode, GIMPLE is TODO. */
void
print_rtl_graph_with_bb (const char *base, tree fndecl)
{
const char *funcname = fndecl_name (fndecl);
int fndecl_uid = DECL_UID (fndecl);
FILE *fp = open_graph_file (base, "a");
int *rpo = XNEWVEC (int, n_basic_blocks);
basic_block bb;
int i, n;
fprintf (fp,
"subgraph \"%s\" {\n"
"\tcolor=\"black\";\n"
"\tlabel=\"%s\";\n",
funcname, funcname);
/* First print all basic blocks.
Visit the blocks in reverse post order to get a good ranking
of the nodes. */
n = pre_and_rev_post_order_compute (NULL, rpo, true);
for (i = 0; i < n; i++)
draw_cfg_node (fp, fndecl_uid, BASIC_BLOCK (rpo[i]));
/* Draw all edges at the end to get subgraphs right for GraphViz,
which requires nodes to be defined before edges to cluster
nodes properly.
Draw retreating edges as not constraining, this makes the layout
of the graph better. (??? Calling mark_dfs_back may change the
compiler's behavior when dumping, but computing back edges here
for ourselves is also not desirable.) */
mark_dfs_back_edges ();
FOR_ALL_BB (bb)
draw_cfg_node_succ_edges (fp, fndecl_uid, bb);
fputs ("\t}\n", fp);
fclose (fp); fclose (fp);
} }
/* Start the dump of a graph. */
static void
start_graph_dump (FILE *fp)
{
fputs ("digraph \"\" {\n"
"overlap=false;\n",
fp);
}
/* End the dump of a graph. */
static void
end_graph_dump (FILE *fp)
{
fputs ("}\n", fp);
}
/* Similar as clean_dump_file, but this time for graph output files. */ /* Similar as clean_dump_file, but this time for graph output files. */
void void
clean_graph_dump_file (const char *base) clean_graph_dump_file (const char *base)
{ {
size_t namelen = strlen (base); FILE *fp = open_graph_file (base, "w");
size_t extlen = strlen (graph_ext[graph_dump_format]) + 1; start_graph_dump (fp);
char *buf = XALLOCAVEC (char, namelen + extlen);
FILE *fp;
memcpy (buf, base, namelen);
memcpy (buf + namelen, graph_ext[graph_dump_format], extlen);
fp = fopen (buf, "w");
if (fp == NULL)
fatal_error ("can%'t open %s: %m", buf);
gcc_assert (graph_dump_format == vcg);
fputs ("graph: {\nport_sharing: no\n", fp);
fclose (fp); fclose (fp);
} }
...@@ -420,19 +269,7 @@ clean_graph_dump_file (const char *base) ...@@ -420,19 +269,7 @@ clean_graph_dump_file (const char *base)
void void
finish_graph_dump_file (const char *base) finish_graph_dump_file (const char *base)
{ {
size_t namelen = strlen (base); FILE *fp = open_graph_file (base, "a");
size_t extlen = strlen (graph_ext[graph_dump_format]) + 1; end_graph_dump (fp);
char *buf = XALLOCAVEC (char, namelen + extlen); fclose (fp);
FILE *fp;
memcpy (buf, base, namelen);
memcpy (buf + namelen, graph_ext[graph_dump_format], extlen);
fp = fopen (buf, "a");
if (fp != NULL)
{
gcc_assert (graph_dump_format == vcg);
fputs ("}\n", fp);
fclose (fp);
}
} }
...@@ -20,7 +20,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -20,7 +20,7 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_GRAPH_H #ifndef GCC_GRAPH_H
#define GCC_GRAPH_H #define GCC_GRAPH_H
extern void print_rtl_graph_with_bb (const char *, rtx); extern void print_rtl_graph_with_bb (const char *, tree);
extern void clean_graph_dump_file (const char *); extern void clean_graph_dump_file (const char *);
extern void finish_graph_dump_file (const char *); extern void finish_graph_dump_file (const char *);
......
...@@ -1982,9 +1982,6 @@ decode_d_option (const char *arg, struct gcc_options *opts, ...@@ -1982,9 +1982,6 @@ decode_d_option (const char *arg, struct gcc_options *opts,
opts->x_flag_dump_rtl_in_asm = 1; opts->x_flag_dump_rtl_in_asm = 1;
opts->x_flag_print_asm_name = 1; opts->x_flag_print_asm_name = 1;
break; break;
case 'v':
opts->x_graph_dump_format = vcg;
break;
case 'x': case 'x':
opts->x_rtl_dump_and_exit = 1; opts->x_rtl_dump_and_exit = 1;
break; break;
......
...@@ -239,19 +239,18 @@ finish_optimization_passes (void) ...@@ -239,19 +239,18 @@ finish_optimization_passes (void)
{ {
dump_start (pass_profile.pass.static_pass_number, NULL); dump_start (pass_profile.pass.static_pass_number, NULL);
print_combine_total_stats (); print_combine_total_stats ();
dump_finish (pass_combine.pass.static_pass_number); dump_finish (pass_profile.pass.static_pass_number);
} }
/* Do whatever is necessary to finish printing the graphs. */ /* Do whatever is necessary to finish printing the graphs. */
if (graph_dump_format != no_graph) for (i = TDI_end; (dfi = get_dump_file_info (i)) != NULL; ++i)
for (i = TDI_end; (dfi = get_dump_file_info (i)) != NULL; ++i) if (dump_initialized_p (i)
if (dump_initialized_p (i) && (dfi->pflags & TDF_GRAPH) != 0
&& (dfi->pflags & TDF_GRAPH) != 0 && (name = get_dump_file_name (i)) != NULL)
&& (name = get_dump_file_name (i)) != NULL) {
{ finish_graph_dump_file (name);
finish_graph_dump_file (name); free (name);
free (name); }
}
timevar_pop (TV_DUMP); timevar_pop (TV_DUMP);
} }
...@@ -1777,18 +1776,16 @@ execute_function_dump (void *data ATTRIBUTE_UNUSED) ...@@ -1777,18 +1776,16 @@ execute_function_dump (void *data ATTRIBUTE_UNUSED)
if (cfun->curr_properties & PROP_trees) if (cfun->curr_properties & PROP_trees)
dump_function_to_file (current_function_decl, dump_file, dump_flags); dump_function_to_file (current_function_decl, dump_file, dump_flags);
else else
{ print_rtl_with_bb (dump_file, get_insns (), dump_flags);
print_rtl_with_bb (dump_file, get_insns (), dump_flags);
if ((cfun->curr_properties & PROP_cfg)
&& graph_dump_format != no_graph
&& (dump_flags & TDF_GRAPH))
print_rtl_graph_with_bb (dump_file_name, get_insns ());
}
/* Flush the file. If verification fails, we won't be able to /* Flush the file. If verification fails, we won't be able to
close the file before aborting. */ close the file before aborting. */
fflush (dump_file); fflush (dump_file);
if ((cfun->curr_properties & PROP_cfg)
&& (cfun->curr_properties & PROP_rtl)
&& (dump_flags & TDF_GRAPH))
print_rtl_graph_with_bb (dump_file_name, cfun->decl);
} }
} }
...@@ -2338,13 +2335,11 @@ execute_one_pass (struct opt_pass *pass) ...@@ -2338,13 +2335,11 @@ execute_one_pass (struct opt_pass *pass)
if (initializing_dump if (initializing_dump
&& dump_file && dump_file
&& graph_dump_format != no_graph && (dump_flags & TDF_GRAPH)
&& cfun && cfun
&& (cfun->curr_properties & (PROP_cfg | PROP_rtl)) && (cfun->curr_properties & (PROP_cfg | PROP_rtl))
== (PROP_cfg | PROP_rtl)) == (PROP_cfg | PROP_rtl))
{ {
get_dump_file_info (pass->static_pass_number)->pflags |= TDF_GRAPH;
dump_flags |= TDF_GRAPH;
clean_graph_dump_file (dump_file_name); clean_graph_dump_file (dump_file_name);
} }
......
...@@ -77,9 +77,6 @@ int flag_dump_unnumbered_links = 0; ...@@ -77,9 +77,6 @@ int flag_dump_unnumbered_links = 0;
/* Nonzero means use simplified format without flags, modes, etc. */ /* Nonzero means use simplified format without flags, modes, etc. */
int flag_simple = 0; int flag_simple = 0;
/* Nonzero if we are dumping graphical description. */
int dump_for_graph;
#ifndef GENERATOR_FILE #ifndef GENERATOR_FILE
void void
print_mem_expr (FILE *outfile, const_tree expr) print_mem_expr (FILE *outfile, const_tree expr)
...@@ -124,74 +121,62 @@ print_rtx (const_rtx in_rtx) ...@@ -124,74 +121,62 @@ print_rtx (const_rtx in_rtx)
is_insn = INSN_P (in_rtx); is_insn = INSN_P (in_rtx);
/* When printing in VCG format we write INSNs, NOTE, LABEL, and BARRIER /* Print name of expression code. */
in separate nodes and therefore have to handle them special here. */ if (flag_simple && CONST_INT_P (in_rtx))
if (dump_for_graph fputc ('(', outfile);
&& (is_insn || NOTE_P (in_rtx)
|| LABEL_P (in_rtx) || BARRIER_P (in_rtx)))
{
i = 3;
indent = 0;
}
else else
{ fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
/* Print name of expression code. */
if (flag_simple && CONST_INT_P (in_rtx))
fputc ('(', outfile);
else
fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
if (! flag_simple) if (! flag_simple)
{ {
if (RTX_FLAG (in_rtx, in_struct)) if (RTX_FLAG (in_rtx, in_struct))
fputs ("/s", outfile); fputs ("/s", outfile);
if (RTX_FLAG (in_rtx, volatil)) if (RTX_FLAG (in_rtx, volatil))
fputs ("/v", outfile); fputs ("/v", outfile);
if (RTX_FLAG (in_rtx, unchanging)) if (RTX_FLAG (in_rtx, unchanging))
fputs ("/u", outfile); fputs ("/u", outfile);
if (RTX_FLAG (in_rtx, frame_related)) if (RTX_FLAG (in_rtx, frame_related))
fputs ("/f", outfile); fputs ("/f", outfile);
if (RTX_FLAG (in_rtx, jump)) if (RTX_FLAG (in_rtx, jump))
fputs ("/j", outfile); fputs ("/j", outfile);
if (RTX_FLAG (in_rtx, call)) if (RTX_FLAG (in_rtx, call))
fputs ("/c", outfile); fputs ("/c", outfile);
if (RTX_FLAG (in_rtx, return_val)) if (RTX_FLAG (in_rtx, return_val))
fputs ("/i", outfile); fputs ("/i", outfile);
/* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */ /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */
if ((GET_CODE (in_rtx) == EXPR_LIST if ((GET_CODE (in_rtx) == EXPR_LIST
|| GET_CODE (in_rtx) == INSN_LIST) || GET_CODE (in_rtx) == INSN_LIST)
&& (int)GET_MODE (in_rtx) < REG_NOTE_MAX) && (int)GET_MODE (in_rtx) < REG_NOTE_MAX)
fprintf (outfile, ":%s", fprintf (outfile, ":%s",
GET_REG_NOTE_NAME (GET_MODE (in_rtx))); GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
/* For other rtl, print the mode if it's not VOID. */ /* For other rtl, print the mode if it's not VOID. */
else if (GET_MODE (in_rtx) != VOIDmode) else if (GET_MODE (in_rtx) != VOIDmode)
fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx))); fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
#ifndef GENERATOR_FILE #ifndef GENERATOR_FILE
if (GET_CODE (in_rtx) == VAR_LOCATION) if (GET_CODE (in_rtx) == VAR_LOCATION)
{ {
if (TREE_CODE (PAT_VAR_LOCATION_DECL (in_rtx)) == STRING_CST) if (TREE_CODE (PAT_VAR_LOCATION_DECL (in_rtx)) == STRING_CST)
fputs (" <debug string placeholder>", outfile); fputs (" <debug string placeholder>", outfile);
else else
print_mem_expr (outfile, PAT_VAR_LOCATION_DECL (in_rtx)); print_mem_expr (outfile, PAT_VAR_LOCATION_DECL (in_rtx));
fputc (' ', outfile); fputc (' ', outfile);
print_rtx (PAT_VAR_LOCATION_LOC (in_rtx)); print_rtx (PAT_VAR_LOCATION_LOC (in_rtx));
if (PAT_VAR_LOCATION_STATUS (in_rtx) if (PAT_VAR_LOCATION_STATUS (in_rtx)
== VAR_INIT_STATUS_UNINITIALIZED) == VAR_INIT_STATUS_UNINITIALIZED)
fprintf (outfile, " [uninit]"); fprintf (outfile, " [uninit]");
sawclose = 1; sawclose = 1;
i = GET_RTX_LENGTH (VAR_LOCATION); i = GET_RTX_LENGTH (VAR_LOCATION);
}
#endif
} }
#endif
} }
#ifndef GENERATOR_FILE #ifndef GENERATOR_FILE
...@@ -217,14 +202,9 @@ print_rtx (const_rtx in_rtx) ...@@ -217,14 +202,9 @@ print_rtx (const_rtx in_rtx)
string: string:
if (str == 0) if (str == 0)
fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile); fputs (" \"\"", outfile);
else else
{ fprintf (outfile, " (\"%s\")", str);
if (dump_for_graph)
fprintf (outfile, " (\\\"%s\\\")", str);
else
fprintf (outfile, " (\"%s\")", str);
}
sawclose = 1; sawclose = 1;
break; break;
...@@ -652,15 +632,8 @@ print_rtx (const_rtx in_rtx) ...@@ -652,15 +632,8 @@ print_rtx (const_rtx in_rtx)
break; break;
} }
if (dump_for_graph fputc (')', outfile);
&& (is_insn || NOTE_P (in_rtx) sawclose = 1;
|| LABEL_P (in_rtx) || BARRIER_P (in_rtx)))
sawclose = 0;
else
{
fputc (')', outfile);
sawclose = 1;
}
} }
/* Print an rtx on the current line of FILE. Initially indent IND /* Print an rtx on the current line of FILE. Initially indent IND
......
...@@ -2605,6 +2605,14 @@ extern int print_rtl_single (FILE *, const_rtx); ...@@ -2605,6 +2605,14 @@ 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
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
by the scheduler anymore but for all "slim" RTL dumping. */
extern void print_insn (char *, const_rtx, int);
extern void print_pattern (char *, const_rtx, int);
extern void print_value (char *, const_rtx, int);
/* In function.c */ /* In function.c */
extern void reposition_prologue_and_epilogue_notes (void); extern void reposition_prologue_and_epilogue_notes (void);
extern int prologue_epilogue_contains (const_rtx); extern int prologue_epilogue_contains (const_rtx);
......
...@@ -1578,11 +1578,5 @@ extern void sd_debug_lists (rtx, sd_list_types_def); ...@@ -1578,11 +1578,5 @@ extern void sd_debug_lists (rtx, sd_list_types_def);
#endif /* INSN_SCHEDULING */ #endif /* INSN_SCHEDULING */
/* Functions in sched-vis.c. These must be outside INSN_SCHEDULING as
sched-vis.c is compiled always. */
extern void print_insn (char *, const_rtx, int);
extern void print_pattern (char *, const_rtx, int);
extern void print_value (char *, const_rtx, int);
#endif /* GCC_SCHED_INT_H */ #endif /* GCC_SCHED_INT_H */
...@@ -782,12 +782,53 @@ print_insn (char *buf, const_rtx x, int verbose) ...@@ -782,12 +782,53 @@ print_insn (char *buf, const_rtx x, int verbose)
sprintf (buf, "i%4d: barrier", INSN_UID (x)); sprintf (buf, "i%4d: barrier", INSN_UID (x));
break; break;
case NOTE: case NOTE:
sprintf (buf, " %4d %s", INSN_UID (x), {
GET_NOTE_INSN_NAME (NOTE_KIND (x))); int uid = INSN_UID (x);
break; const char *note_name = GET_NOTE_INSN_NAME (NOTE_KIND (x));
switch (NOTE_KIND (x))
{
case NOTE_INSN_EH_REGION_BEG:
case NOTE_INSN_EH_REGION_END:
sprintf (buf, " %4d %s %d", uid, note_name,
NOTE_EH_HANDLER (x));
break;
case NOTE_INSN_BLOCK_BEG:
case NOTE_INSN_BLOCK_END:
sprintf (buf, " %4d %s %d", uid, note_name,
BLOCK_NUMBER (NOTE_BLOCK (x)));
break;
case NOTE_INSN_BASIC_BLOCK:
sprintf (buf, " %4d %s %d", uid, note_name,
NOTE_BASIC_BLOCK (x)->index);
break;
case NOTE_INSN_DELETED_LABEL:
case NOTE_INSN_DELETED_DEBUG_LABEL:
{
const char *label = NOTE_DELETED_LABEL_NAME (x);
if (label == NULL)
label = "";
sprintf (buf, " %4d %s (\"%s\")", uid, note_name, label);
}
break;
case NOTE_INSN_VAR_LOCATION:
print_pattern (t, NOTE_VAR_LOCATION (x), verbose);
sprintf (buf, " %4d %s {%s}", uid, note_name, t);
break;
default:
sprintf (buf, " %4d %s", uid, note_name);
break;
}
break;
}
default: default:
sprintf (buf, "i%4d <What %s?>", INSN_UID (x), sprintf (buf, "i%4d <What %s?>", INSN_UID (x),
GET_RTX_NAME (GET_CODE (x))); GET_RTX_NAME (GET_CODE (x)));
break;
} }
} /* print_insn */ } /* print_insn */
......
2012-11-26 Steven Bosscher <steven@gcc.gnu.org>
* testsuite/gcc.dg/20050811-1.c: Change -dv option to -graph option
to -fdump-rtl-all.
* testsuite/gcc.dg/pr37858.c: Remove -dv option.
2012-11-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com> 2012-11-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* lib/target-supports.exp (check_effective_target_arm_v8_vfp_ok): * lib/target-supports.exp (check_effective_target_arm_v8_vfp_ok):
......
/* Test whether -dv -fdump-rtl-all doesn't crash. */ /* Test whether -fdump-rtl-all-graph doesn't crash. */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -dv -fdump-rtl-all" } */ /* { dg-options "-O2 -fdump-rtl-all-graph" } */
int foo (void) int foo (void)
{ {
......
/* PR middle-end/37858 */ /* PR middle-end/37858 */
/* ??? With -dv removed, this test is a bit silly. */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -fdump-ipa-early_local_cleanups -dv" } */ /* { dg-options "-O2 -fdump-ipa-early_local_cleanups" } */
int int
main (void) main (void)
......
...@@ -49,7 +49,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -49,7 +49,6 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h" #include "basic-block.h"
#include "intl.h" #include "intl.h"
#include "ggc.h" #include "ggc.h"
#include "graph.h"
#include "regs.h" #include "regs.h"
#include "timevar.h" #include "timevar.h"
#include "diagnostic.h" #include "diagnostic.h"
......
...@@ -38,7 +38,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -38,7 +38,6 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h" #include "tree-pass.h"
#include "ggc.h" #include "ggc.h"
#include "cgraph.h" #include "cgraph.h"
#include "graph.h"
#include "cfgloop.h" #include "cfgloop.h"
#include "except.h" #include "except.h"
#include "plugin.h" #include "plugin.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment