aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-02-22 10:31:41 +0000
committerTom de Vries <vries@gcc.gnu.org>2016-02-22 10:31:41 +0000
commitbddb7adb4411ec4c9653e61accb3db25e3b2c405 (patch)
tree0325e4200547ba999678e700113902517c36175c
parentb6e5b400c3253134d0c7dd71c7976bdd0be55391 (diff)
downloadgcc-bddb7adb4411ec4c9653e61accb3db25e3b2c405.zip
gcc-bddb7adb4411ec4c9653e61accb3db25e3b2c405.tar.gz
gcc-bddb7adb4411ec4c9653e61accb3db25e3b2c405.tar.bz2
Add dot-fn to gdbhooks.py
2016-02-22 Richard Biener <rguenther@suse.de> Tom de Vries <tom@codesourcery.com> * graph.c: Include dumpfile.h. (print_graph_cfg): Split into three overloads. * gdbhooks.py (class DotFn): Add and instantiate, adding command dot-fn. Co-Authored-By: Tom de Vries <tom@codesourcery.com> From-SVN: r233600
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/gdbhooks.py70
-rw-r--r--gcc/graph.c32
3 files changed, 105 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c2646f6..3e4273b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2016-02-22 Richard Biener <rguenther@suse.de>
+ Tom de Vries <tom@codesourcery.com>
+
+ * graph.c: Include dumpfile.h.
+ (print_graph_cfg): Split into three overloads.
+ * gdbhooks.py (class DotFn): Add and instantiate, adding command dot-fn.
+
2016-02-22 Tom de Vries <tom@codesourcery.com>
* gdbhooks.py (class DumpFn): Add and instantiate, adding command
diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py
index ed72016..1212312 100644
--- a/gcc/gdbhooks.py
+++ b/gcc/gdbhooks.py
@@ -680,4 +680,74 @@ class DumpFn(gdb.Command):
DumpFn()
+class DotFn(gdb.Command):
+ """
+ A custom command to show a gimple/rtl function control flow graph.
+ By default, it show the current function, but the function can also be
+ specified.
+
+ Examples of use:
+ (gdb) dot-fn
+ (gdb) dot-fn cfun
+ (gdb) dot-fn cfun 0
+ (gdb) dot-fn cfun dump_flags
+ """
+ def __init__(self):
+ gdb.Command.__init__(self, 'dot-fn', gdb.COMMAND_USER)
+
+ def invoke(self, arg, from_tty):
+ # Parse args, check number of args
+ args = gdb.string_to_argv(arg)
+ if len(args) > 2:
+ print("Too many arguments")
+ return
+
+ # Set func
+ if len(args) >= 1:
+ funcname = args[0]
+ printfuncname = "function %s" % funcname
+ else:
+ funcname = "cfun"
+ printfuncname = "current function"
+ func = gdb.parse_and_eval(funcname)
+ if func == 0:
+ print("Could not find %s" % printfuncname)
+ return
+ func = "(struct function *)%s" % func
+
+ # Set flags
+ if len(args) >= 2:
+ flags = gdb.parse_and_eval(args[1])
+ else:
+ flags = 0
+
+ # Get temp file
+ f = tempfile.NamedTemporaryFile(delete=False)
+ filename = f.name
+
+ # Close and reopen temp file to get C FILE*
+ f.close()
+ fp = gdb.parse_and_eval("fopen (\"%s\", \"w\")" % filename)
+ if fp == 0:
+ print("Cannot open temp file")
+ return
+ fp = "(FILE *)%u" % fp
+
+ # Write graph to temp file
+ _ = gdb.parse_and_eval("start_graph_dump (%s, \"<debug>\")" % fp)
+ _ = gdb.parse_and_eval("print_graph_cfg (%s, %s, %u)"
+ % (fp, func, flags))
+ _ = gdb.parse_and_eval("end_graph_dump (%s)" % fp)
+
+ # Close temp file
+ ret = gdb.parse_and_eval("fclose (%s)" % fp)
+ if ret != 0:
+ print("Could not close temp file: %s" % filename)
+ return
+
+ # Show graph in temp file
+ os.system("( dot -Tx11 \"%s\"; rm \"%s\" ) &" % (filename, filename))
+
+DotFn()
+
print('Successfully loaded GDB hooks for GCC')
diff --git a/gcc/graph.c b/gcc/graph.c
index 1b28c67..dd5bc4e 100644
--- a/gcc/graph.c
+++ b/gcc/graph.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfganal.h"
#include "cfgloop.h"
#include "graph.h"
+#include "dumpfile.h"
/* DOT files with the .dot extension are recognized as document templates
by a well-known piece of word processing software out of Redmond, WA.
@@ -272,14 +273,13 @@ draw_cfg_edges (pretty_printer *pp, struct function *fun)
subgraphs right for GraphViz, which requires nodes to be defined
before edges to cluster nodes properly. */
-void
-print_graph_cfg (const char *base, struct function *fun)
+void DEBUG_FUNCTION
+print_graph_cfg (FILE *fp, struct function *fun)
{
- const char *funcname = function_name (fun);
- FILE *fp = open_graph_file (base, "a");
pretty_printer graph_slim_pp;
graph_slim_pp.buffer->stream = fp;
pretty_printer *const pp = &graph_slim_pp;
+ const char *funcname = function_name (fun);
pp_printf (pp, "subgraph \"cluster_%s\" {\n"
"\tstyle=\"dashed\";\n"
"\tcolor=\"black\";\n"
@@ -289,6 +289,30 @@ print_graph_cfg (const char *base, struct function *fun)
draw_cfg_edges (pp, fun);
pp_printf (pp, "}\n");
pp_flush (pp);
+}
+
+/* Overload with additional flag argument. */
+
+void DEBUG_FUNCTION
+print_graph_cfg (FILE *fp, struct function *fun, int flags)
+{
+ int saved_dump_flags = dump_flags;
+ dump_flags = flags;
+ print_graph_cfg (fp, fun);
+ dump_flags = saved_dump_flags;
+}
+
+
+/* Print a graphical representation of the CFG of function FUN.
+ First print all basic blocks. Draw all edges at the end to get
+ subgraphs right for GraphViz, which requires nodes to be defined
+ before edges to cluster nodes properly. */
+
+void
+print_graph_cfg (const char *base, struct function *fun)
+{
+ FILE *fp = open_graph_file (base, "a");
+ print_graph_cfg (fp, fun);
fclose (fp);
}