invoke.texi: Remove -dv documentation.
authorSteven Bosscher <steven@gcc.gnu.org>
Mon, 26 Nov 2012 16:47:58 +0000 (16:47 +0000)
committerSteven Bosscher <steven@gcc.gnu.org>
Mon, 26 Nov 2012 16:47:58 +0000 (16:47 +0000)
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

19 files changed:
gcc/ChangeLog
gcc/common.opt
gcc/ddg.c
gcc/doc/invoke.texi
gcc/flag-types.h
gcc/flags.h
gcc/graph.c
gcc/graph.h
gcc/opts.c
gcc/passes.c
gcc/print-rtl.c
gcc/rtl.h
gcc/sched-int.h
gcc/sched-vis.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20050811-1.c
gcc/testsuite/gcc.dg/pr37858.c
gcc/toplev.c
gcc/tree-optimize.c

index 55c7df6ee4f61719d39cd23c23f6bc080aa1028a..80f9b03d45f2f23e6c77b0b5313120464d4397a3 100644 (file)
@@ -1,3 +1,33 @@
+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>
 
        * cprop.c (hash_set): Remove variable.  Use regno
index 5cf16b6b42a2c3cb1db940947708786d8d87078d..4c8bd118b289d4d83d6a9ea6a2d5996931e1b711 100644 (file)
@@ -174,9 +174,6 @@ int rtl_dump_and_exit
 Variable
 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).
 ; 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.
index 9d44ac893011edf8c2bf23dd22c5e63a3f2a6364..28402e67c5ca74db048332a2c70236934bf9e292 100644 (file)
--- a/gcc/ddg.c
+++ b/gcc/ddg.c
@@ -753,7 +753,7 @@ print_ddg (FILE *file, ddg_ptr g)
 }
 
 /* Print the given DDG in VCG format.  */
-void
+DEBUG_FUNCTION void
 vcg_print_ddg (FILE *file, ddg_ptr g)
 {
   int src_cuid;
index 8e999cba159f70f7d1f86f5b57fe5636e9f07f0e..51b6e851568c71924a43ef3c5dceda79fa27df4d 100644 (file)
@@ -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
 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
-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
 function header of a dump file, and the pass names can be dumped by using
 option @option{-fdump-passes}.
@@ -5727,12 +5727,6 @@ also printed.
 Dump the RTL in the assembler output as a comment before each instruction.
 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
 @opindex dx
 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
 in the dump instead of @code{DECL_NAME}.  Its primary use is ease of
 use working backward from mangled names in the assembly file.
 @item slim
-Inhibit dumping of members of a scope or body of a function merely
-because that scope has been reached.  Only dump such items when they
-are directly reachable by some other path.  When dumping pretty-printed
-trees, this option inhibits dumping the bodies of control structures.
+When dumping front-end intermediate representations, inhibit dumping
+of members of a scope or body of a function merely because that scope
+has been reached.  Only dump such items when they are directly reachable
+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
 Print a raw representation of the tree.  By default, trees are
 pretty-printed into a C-like representation.
@@ -5856,6 +5856,16 @@ Enable dumping various statistics about the pass (not honored by every dump
 option).
 @item blocks
 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
 Enable showing virtual operands for every statement.
 @item lineno
index d6c2610072d28c0094888b0f1dd429baa4ca7e77..f5693506f15b5605c51bda6d35a98bd559c47879 100644 (file)
@@ -141,13 +141,6 @@ enum excess_precision
   EXCESS_PRECISION_STANDARD
 };
 
-/* Selection of the graph form.  */
-enum graph_dump_types
-{
-  no_graph = 0,
-  vcg
-};
-
 /* Type of stack check.  */
 enum stack_check_type
 {
index d56d5411e7bb34f0e46c26c0195a11921cc08989..010e8ff933753f8d7370590aa724281fc965b756 100644 (file)
@@ -89,9 +89,6 @@ extern struct target_flag_state *this_target_flag_state;
 #define 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
    greater is in use.  */
 
index 847aac2dc1a5af430748de1629338126ab0db513..bb1bb7b6d939e49a8984ede0cabb731650f920f0 100644 (file)
@@ -1,7 +1,8 @@
 /* Output routines for graphical representation.
-   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2007, 2008, 2010
+   Copyright (C) 1998-2012
    Free Software Foundation, Inc.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+   Rewritten for DOT output by Steven Bosscher, 2012.
 
 This file is part of GCC.
 
@@ -22,396 +23,244 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "rtl.h"
-#include "flags.h"
-#include "function.h"
-#include "hard-reg-set.h"
-#include "obstack.h"
+#include "diagnostic-core.h" /* for fatal_error */
+#include "sbitmap.h"
 #include "basic-block.h"
-#include "diagnostic-core.h"
+#include "rtl.h"
+#include "tree.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.  */
-static int inbb = 0;
+/* DOT files with the .dot extension are recognized as document templates
+   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 *);
-static void start_bb (FILE *, int);
-static void node_data (FILE *, rtx);
-static void draw_edge (FILE *, int, int, int, int);
-static void end_fct (FILE *);
-static void end_bb (FILE *);
-
-/* Output text for new basic block.  */
-static void
-start_fct (FILE *fp)
+/* Open a file with MODE for dumping our graph to.
+   Return the file pointer.  */
+static FILE *
+open_graph_file (const char *base, const char *mode)
 {
-  switch (graph_dump_format)
-    {
-    case vcg:
-      fprintf (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;
-    }
+  size_t namelen = strlen (base);
+  size_t extlen = strlen (graph_ext) + 1;
+  char *buf = XALLOCAVEC (char, namelen + extlen);
+  FILE *fp;
 
-#if 0
-  /* FIXME Should this be printed?  It makes the graph significantly larger.  */
+  memcpy (buf, base, namelen);
+  memcpy (buf + namelen, graph_ext, extlen);
 
-  /* Print the live-at-start register list.  */
-  fputc ('\n', fp);
-  EXECUTE_IF_SET_IN_REG_SET (basic_block_live_at_start[bb], 0, i, rsi)
-    {
-      fprintf (fp, " %d", i);
-      if (i < FIRST_PSEUDO_REGISTER)
-       fprintf (fp, " [%s]", reg_names[i]);
-    }
-#endif
+  fp = fopen (buf, mode);
+  if (fp == NULL)
+    fatal_error ("can%'t open %s: %m", buf);
 
-  switch (graph_dump_format)
-    {
-    case vcg:
-      fputs ("\"\n\n", fp);
-      break;
-    case no_graph:
-      break;
-    }
+  return fp;
 }
 
-static void
-node_data (FILE *fp, rtx tmp_rtx)
+/* Print the output from print_insn or print_pattern with GraphViz-special
+   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
-        block.  */
-      switch (graph_dump_format)
+      switch (*p)
        {
-       case vcg:
-         fprintf (fp, "\
-edge: { sourcename: \"%s.0\" targetname: \"%s.%d\" }\n",
-                  current_function_name (),
-                  current_function_name (), XINT (tmp_rtx, 0));
+       case '\n':
+         /* Print newlines as a left-aligned newline.  */
+         fputs ("\\l\\\n", fp);
          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;
        }
+      p++;
     }
+  fputs ("\\l\\\n", fp);
+}
 
-  switch (graph_dump_format)
-    {
-    case vcg:
-      fprintf (fp, "node: {\n  title: \"%s.%d\"\n  color: %s\n  \
-label: \"%s %d\n",
-              current_function_name (), XINT (tmp_rtx, 0),
-              NOTE_P (tmp_rtx) ? "lightgrey"
-              : NONJUMP_INSN_P (tmp_rtx) ? "green"
-              : JUMP_P (tmp_rtx) ? "darkgreen"
-              : 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;
-    }
+/* Draw a basic block BB belonging to the function with FNDECL_UID
+   as its unique number.  */
+static void
+draw_cfg_node (FILE *fp, int fndecl_uid, basic_block bb)
+{
+  rtx insn;
+  bool first = true;
+  const char *shape;
+  const char *fillcolor;
 
-  /* Print the RTL.  */
-  if (NOTE_P (tmp_rtx))
+  if (bb->index == ENTRY_BLOCK || bb->index == EXIT_BLOCK)
     {
-      const char *name;
-      name =  GET_NOTE_INSN_NAME (NOTE_KIND (tmp_rtx));
-      fprintf (fp, " %s", name);
+      shape = "Mdiamond";
+      fillcolor = "white";
     }
-  else if (INSN_P (tmp_rtx))
-    print_rtl_single (fp, PATTERN (tmp_rtx));
   else
-    print_rtl_single (fp, tmp_rtx);
-
-  switch (graph_dump_format)
     {
-    case vcg:
-      fputs ("\"\n}\n", fp);
-      break;
-    case no_graph:
-      break;
+      shape = "record";
+      fillcolor =
+       BB_PARTITION (bb) == BB_HOT_PARTITION ? "lightpink"
+       : BB_PARTITION (bb) == BB_COLD_PARTITION ? "lightblue"
+       : "lightgrey";
     }
-}
 
-static void
-draw_edge (FILE *fp, int from, int to, int bb_edge, int color_class)
-{
-  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;
-    }
-}
+  fprintf (fp,
+          "\tfn_%d_basic_block_%d [shape=%s,style=filled,fillcolor=%s,label=\"",
+          fndecl_uid, bb->index, shape, fillcolor);
 
-static void
-end_bb (FILE *fp)
-{
-  switch (graph_dump_format)
+  if (bb->index == ENTRY_BLOCK)
+    fputs ("ENTRY", fp);
+  else if (bb->index == EXIT_BLOCK)
+    fputs ("EXIT", fp);
+  else
     {
-    case vcg:
-      /* Check if we are inside of a building block.  */
-      if (inbb != 0)
-        {
-          fputs ("}\n", fp);
-          inbb = 0; /* Now we are outside of a building block.  */
-        }
-      break;
-    case no_graph:
-      break;
+      fputc ('{', fp);
+      /* TODO: inter-bb stuff.  */
+      FOR_BB_INSNS (bb, insn)
+       {
+         char buf[2048];
+
+         if (! first)
+           fputc ('|', fp);
+
+         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
-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:
-      fprintf (fp, "node: { title: \"%s.999999\" label: \"END\" }\n}\n",
-              current_function_name ());
-      break;
-    case no_graph:
-      break;
-    }
-}
-\f
-/* 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;
+      const char *style = "\"solid,bold\"";
+      const char *color = "black";
+      int weight = 10;
 
-  memcpy (buf, base, namelen);
-  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)
+      if (e->flags & EDGE_FAKE)
        {
-         start[i] = end[i] = -1;
-         in_bb_p[i] = NOT_IN_BB;
+         style = "dotted";
+         color = "green";
+         weight = 0;
        }
-
-      FOR_EACH_BB_REVERSE (bb)
+      else if (e->flags & EDGE_DFS_BACK)
        {
-         rtx x;
-         start[INSN_UID (BB_HEAD (bb))] = bb->index;
-         end[INSN_UID (BB_END (bb))] = bb->index;
-         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;
-           }
+         style = "\"dotted,bold\"";
+         color = "blue";
+         weight = 10;
        }
-
-      /* 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))
+      else if (e->flags & EDGE_FALLTHRU)
        {
-         int edge_printed = 0;
-         rtx next_insn;
-
-         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);
-               }
-           }
+         color = "blue";
+         weight = 100;
        }
 
-      dump_for_graph = 0;
+      if (e->flags & EDGE_ABNORMAL)
+       color = "red";
 
-      end_fct (fp);
-
-      /* Clean up.  */
-      free (start);
-      free (end);
-      free (in_bb_p);
+      fprintf (fp,
+              "\tfn_%d_basic_block_%d:s -> fn_%d_basic_block_%d:n "
+              "[style=%s,color=%s,weight=%d,constraint=%s];\n",
+              fndecl_uid, e->src->index,
+              fndecl_uid, e->dest->index,
+              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);
 }
 
+/* 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.  */
-
 void
 clean_graph_dump_file (const char *base)
 {
-  size_t namelen = strlen (base);
-  size_t extlen = strlen (graph_ext[graph_dump_format]) + 1;
-  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);
-
+  FILE *fp = open_graph_file (base, "w");
+  start_graph_dump (fp);
   fclose (fp);
 }
 
@@ -420,19 +269,7 @@ clean_graph_dump_file (const char *base)
 void
 finish_graph_dump_file (const char *base)
 {
-  size_t namelen = strlen (base);
-  size_t extlen = strlen (graph_ext[graph_dump_format]) + 1;
-  char *buf = XALLOCAVEC (char, namelen + extlen);
-  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);
-    }
+  FILE *fp = open_graph_file (base, "a");
+  end_graph_dump (fp);
+  fclose (fp);
 }
index f35aecd2f32fc0fdcbeb2780804d97a03d6283ec..892ebb7edb5af23c83c610b07d179a4a7f7545d5 100644 (file)
@@ -20,7 +20,7 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef 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 finish_graph_dump_file (const char *);
 
index 26a0bb878c53ea994a648eaccb688f6af915dacc..b3a9afe8e4d8829896d05a749f9bcfc6fa69d454 100644 (file)
@@ -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_print_asm_name = 1;
        break;
-      case 'v':
-       opts->x_graph_dump_format = vcg;
-       break;
       case 'x':
        opts->x_rtl_dump_and_exit = 1;
        break;
index ee21a9ae3be286857ca3dbb7b187ba9d59d560bf..62f8e1c1e063a34c8271dca18883c29c2341d059 100644 (file)
@@ -239,19 +239,18 @@ finish_optimization_passes (void)
     {
       dump_start (pass_profile.pass.static_pass_number, NULL);
       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.  */
-  if (graph_dump_format != no_graph)
-    for (i = TDI_end; (dfi = get_dump_file_info (i)) != NULL; ++i)
-      if (dump_initialized_p (i)
-         && (dfi->pflags & TDF_GRAPH) != 0
-         && (name = get_dump_file_name (i)) != NULL)
-       {
-         finish_graph_dump_file (name);
-         free (name);
-       }
+  for (i = TDI_end; (dfi = get_dump_file_info (i)) != NULL; ++i)
+    if (dump_initialized_p (i)
+       && (dfi->pflags & TDF_GRAPH) != 0
+       && (name = get_dump_file_name (i)) != NULL)
+      {
+       finish_graph_dump_file (name);
+       free (name);
+      }
 
   timevar_pop (TV_DUMP);
 }
@@ -1777,18 +1776,16 @@ execute_function_dump (void *data ATTRIBUTE_UNUSED)
       if (cfun->curr_properties & PROP_trees)
         dump_function_to_file (current_function_decl, dump_file, dump_flags);
       else
-       {
-         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 ());
-       }
+       print_rtl_with_bb (dump_file, get_insns (), dump_flags);
 
       /* Flush the file.  If verification fails, we won't be able to
         close the file before aborting.  */
       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)
 
   if (initializing_dump
       && dump_file
-      && graph_dump_format != no_graph
+      && (dump_flags & TDF_GRAPH)
       && cfun
       && (cfun->curr_properties & (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);
     }
 
index c2a04a8bef5acb5d42102ed14e14f1825edec5d6..75f93504c7341a2e31e7e9ed48b7ec4fba335c48 100644 (file)
@@ -77,9 +77,6 @@ int flag_dump_unnumbered_links = 0;
 /* Nonzero means use simplified format without flags, modes, etc.  */
 int flag_simple = 0;
 
-/* Nonzero if we are dumping graphical description.  */
-int dump_for_graph;
-
 #ifndef GENERATOR_FILE
 void
 print_mem_expr (FILE *outfile, const_tree expr)
@@ -124,74 +121,62 @@ print_rtx (const_rtx in_rtx)
 
   is_insn = INSN_P (in_rtx);
 
-  /* When printing in VCG format we write INSNs, NOTE, LABEL, and BARRIER
-     in separate nodes and therefore have to handle them special here.  */
-  if (dump_for_graph
-      && (is_insn || NOTE_P (in_rtx)
-         || LABEL_P (in_rtx) || BARRIER_P (in_rtx)))
-    {
-      i = 3;
-      indent = 0;
-    }
+  /* Print name of expression code.  */
+  if (flag_simple && CONST_INT_P (in_rtx))
+    fputc ('(', outfile);
   else
-    {
-      /* 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)));
+    fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
 
-      if (! flag_simple)
-       {
-         if (RTX_FLAG (in_rtx, in_struct))
-           fputs ("/s", outfile);
+  if (! flag_simple)
+    {
+      if (RTX_FLAG (in_rtx, in_struct))
+       fputs ("/s", outfile);
 
-         if (RTX_FLAG (in_rtx, volatil))
-           fputs ("/v", outfile);
+      if (RTX_FLAG (in_rtx, volatil))
+       fputs ("/v", outfile);
 
-         if (RTX_FLAG (in_rtx, unchanging))
-           fputs ("/u", outfile);
+      if (RTX_FLAG (in_rtx, unchanging))
+       fputs ("/u", outfile);
 
-         if (RTX_FLAG (in_rtx, frame_related))
-           fputs ("/f", outfile);
+      if (RTX_FLAG (in_rtx, frame_related))
+       fputs ("/f", outfile);
 
-         if (RTX_FLAG (in_rtx, jump))
-           fputs ("/j", outfile);
+      if (RTX_FLAG (in_rtx, jump))
+       fputs ("/j", outfile);
 
-         if (RTX_FLAG (in_rtx, call))
-           fputs ("/c", outfile);
+      if (RTX_FLAG (in_rtx, call))
+       fputs ("/c", outfile);
 
-         if (RTX_FLAG (in_rtx, return_val))
-           fputs ("/i", outfile);
+      if (RTX_FLAG (in_rtx, return_val))
+       fputs ("/i", outfile);
 
-         /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */
-         if ((GET_CODE (in_rtx) == EXPR_LIST
-              || GET_CODE (in_rtx) == INSN_LIST)
-             && (int)GET_MODE (in_rtx) < REG_NOTE_MAX)
-           fprintf (outfile, ":%s",
-                    GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
+      /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */
+      if ((GET_CODE (in_rtx) == EXPR_LIST
+          || GET_CODE (in_rtx) == INSN_LIST)
+         && (int)GET_MODE (in_rtx) < REG_NOTE_MAX)
+       fprintf (outfile, ":%s",
+                GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
 
-         /* For other rtl, print the mode if it's not VOID.  */
-         else if (GET_MODE (in_rtx) != VOIDmode)
-           fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
+      /* For other rtl, print the mode if it's not VOID.  */
+      else if (GET_MODE (in_rtx) != VOIDmode)
+       fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
 
 #ifndef GENERATOR_FILE
-         if (GET_CODE (in_rtx) == VAR_LOCATION)
-           {
-             if (TREE_CODE (PAT_VAR_LOCATION_DECL (in_rtx)) == STRING_CST)
-               fputs (" <debug string placeholder>", outfile);
-             else
-               print_mem_expr (outfile, PAT_VAR_LOCATION_DECL (in_rtx));
-             fputc (' ', outfile);
-             print_rtx (PAT_VAR_LOCATION_LOC (in_rtx));
-             if (PAT_VAR_LOCATION_STATUS (in_rtx)
-                 == VAR_INIT_STATUS_UNINITIALIZED)
-               fprintf (outfile, " [uninit]");
-             sawclose = 1;
-             i = GET_RTX_LENGTH (VAR_LOCATION);
-           }
-#endif
+      if (GET_CODE (in_rtx) == VAR_LOCATION)
+       {
+         if (TREE_CODE (PAT_VAR_LOCATION_DECL (in_rtx)) == STRING_CST)
+           fputs (" <debug string placeholder>", outfile);
+         else
+           print_mem_expr (outfile, PAT_VAR_LOCATION_DECL (in_rtx));
+         fputc (' ', outfile);
+         print_rtx (PAT_VAR_LOCATION_LOC (in_rtx));
+         if (PAT_VAR_LOCATION_STATUS (in_rtx)
+             == VAR_INIT_STATUS_UNINITIALIZED)
+           fprintf (outfile, " [uninit]");
+         sawclose = 1;
+         i = GET_RTX_LENGTH (VAR_LOCATION);
        }
+#endif
     }
 
 #ifndef GENERATOR_FILE
@@ -217,14 +202,9 @@ print_rtx (const_rtx in_rtx)
       string:
 
        if (str == 0)
-         fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
+         fputs (" \"\"", outfile);
        else
-         {
-           if (dump_for_graph)
-             fprintf (outfile, " (\\\"%s\\\")", str);
-           else
-             fprintf (outfile, " (\"%s\")", str);
-         }
+         fprintf (outfile, " (\"%s\")", str);
        sawclose = 1;
        break;
 
@@ -652,15 +632,8 @@ print_rtx (const_rtx in_rtx)
       break;
     }
 
-  if (dump_for_graph
-      && (is_insn || NOTE_P (in_rtx)
-         || LABEL_P (in_rtx) || BARRIER_P (in_rtx)))
-    sawclose = 0;
-  else
-    {
-      fputc (')', outfile);
-      sawclose = 1;
-    }
+  fputc (')', outfile);
+  sawclose = 1;
 }
 
 /* Print an rtx on the current line of FILE.  Initially indent IND
index 5617dc145d1347e333a91e2c21e1c5e891f3dc20..90b13429bb65cac8676b3838b43d8f9467265429 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2605,6 +2605,14 @@ extern int print_rtl_single (FILE *, const_rtx);
 extern int print_rtl_single_with_indent (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 */
 extern void reposition_prologue_and_epilogue_notes (void);
 extern int prologue_epilogue_contains (const_rtx);
index 1a80f5272f8cd1a39e03eef1c27a9903d3bfaa2c..312a56d84dd6f7c6017b5e829eb27e3f1ec81ef4 100644 (file)
@@ -1578,11 +1578,5 @@ extern void sd_debug_lists (rtx, sd_list_types_def);
 
 #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 */
 
index d4f5e95782d06dcdb75a96b7158537cc54a203d3..9572a47dc468fbb8205e66e5e061cd97dceb0df9 100644 (file)
@@ -782,12 +782,53 @@ print_insn (char *buf, const_rtx x, int verbose)
       sprintf (buf, "i%4d: barrier", INSN_UID (x));
       break;
     case NOTE:
-      sprintf (buf, " %4d %s", INSN_UID (x),
-              GET_NOTE_INSN_NAME (NOTE_KIND (x)));
-      break;
+      {
+        int uid = INSN_UID (x);
+        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:
       sprintf (buf, "i%4d  <What %s?>", INSN_UID (x),
               GET_RTX_NAME (GET_CODE (x)));
+      break;
     }
 }                              /* print_insn */
 
index 0dec0bf3349c8e10aac6fce5b6954c783ec3b3ca..ed2bea89c63b63a53b8d8a5d71c6a2a1287ce5b6 100644 (file)
@@ -1,3 +1,9 @@
+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>
 
        * lib/target-supports.exp (check_effective_target_arm_v8_vfp_ok):
index a9f860bb8bdff48ea7843a259017b82b083a0d7e..010aa5a09ed19f73e0558e418577c8d20b6dd24b 100644 (file)
@@ -1,6 +1,6 @@
-/* Test whether -dv -fdump-rtl-all doesn't crash.  */
+/* Test whether -fdump-rtl-all-graph doesn't crash.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -dv -fdump-rtl-all" } */
+/* { dg-options "-O2 -fdump-rtl-all-graph" } */
 
 int foo (void)
 {
index 4a827eebd129187e5a0e998eb550aee7017b1854..f606d4a5d1a1f3d06a22655c52febaf6b355dfe1 100644 (file)
@@ -1,6 +1,7 @@
 /* PR middle-end/37858 */
+/* ??? With -dv removed, this test is a bit silly.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-early_local_cleanups -dv" } */
+/* { dg-options "-O2 -fdump-ipa-early_local_cleanups" } */
 
 int
 main (void)
index d9d11270d7c47b96ae8f7dc8e41a1a26374de8a1..2c2898c65c76b92f159273a6df0875bb124af6b2 100644 (file)
@@ -49,7 +49,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "basic-block.h"
 #include "intl.h"
 #include "ggc.h"
-#include "graph.h"
 #include "regs.h"
 #include "timevar.h"
 #include "diagnostic.h"
index e44756d120c505607c19f4cf74021728605419cd..48f7d450b10304232497bbb4e1adf5db931b49bf 100644 (file)
@@ -38,7 +38,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "ggc.h"
 #include "cgraph.h"
-#include "graph.h"
 #include "cfgloop.h"
 #include "except.h"
 #include "plugin.h"