diff mbox

Machine-readable RTL dumps: print_rtx_function

Message ID 1475171249-37489-1-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm Sept. 29, 2016, 5:47 p.m. UTC
This patch adds a new function, print_rtx_function, intended for use
for generating function dumps suitable for parsing by the RTL frontend,
but also intended to be human-readable, and human-authorable.

I put the function in its own file (rather than print-rtl.c) to avoid
having to recompile all the gen* files etc every time the format is
tweaked.

For the RTL frontend, it's not enough for a dump to simply record
the insn chain: we need to also capture the CFG and various other state.

It's possible to reconstruct the CFG based on jump instructions when we're
in "cfgrtl" mode (https://gcc.gnu.org/wiki/cfglayout_mode) but not when
in "cfglayout" mode - in the latter,  unconditional jumps are represented
purely by edges in the CFG, not via jump instructions.  So it seems best
to directly capture the CFG.  I plan to keep the CFG-reconstruction code,
so that the CFG information can be optional, to make it easier to
write interesting test cases by hand (for cfgrtl passes).

Some other state needs to be captured.  I know that we need to at least
capture crtl->return_rtx.  The reason for this is that in the normal case
of expanding gimple, this is set inside assign_parms via non-trivial
target-specific logic.  We don't want to rerun assign_parms when loading
a dump as it could insert new insns.  In theory we could rerun parts of
this logic, but it seems simplest to have the dump record the decisions
that were made by assign_parms.  (if crtl->return_rtx is not set, then
df subtly changes behavior, e.g on x86_64 "ax" is not recognized as
used at the exit block).

Nothing in the tree actually uses the new dump function; you (currently)
have to call it manually from the debugger.  We could start using this
function in various pass dumps - though that would obviously
run the risk of affecting dump-scanning in the DejaGnu test suite, so
I'm leaving that as followup work.

The new dump format looks a lot like the existing insn chain dumps:
Here's an example dump (from x86_64).  I put the insn chain at the
top, with the other data coming after it, since GCC developers are
used to seeing the insn chain.  The dump uses indentation and
comments to make it easier for humans to grok.

 (function "times_two"
   (insn-chain
     (note 1 0 4 (nil) NOTE_INSN_DELETED)
     (note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
     (insn 2 4 3 2 (set (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
                         (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])
                 (reg:SI 5 di [ i ])) t.c:2 -1
              (nil))
     (note 3 2 6 2 NOTE_INSN_FUNCTION_BEG)
     (insn 6 3 7 2 (set (reg:SI 89)
                 (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
                         (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])) t.c:3 -1
              (nil))
     (insn 7 6 10 2 (parallel [
                     (set (reg:SI 87 [ _2 ])
                         (ashift:SI (reg:SI 89)
                             (const_int 1 [0x1])))
                     (clobber (reg:CC 17 flags))
                 ]) t.c:3 -1
              (expr_list:REG_EQUAL (ashift:SI (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
                             (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])
                     (const_int 1 [0x1]))
                 (nil)))
     (insn 10 7 14 2 (set (reg:SI 88 [ <retval> ])
                 (reg:SI 87 [ _2 ])) t.c:3 -1
              (nil))
     (insn 14 10 15 2 (set (reg/i:SI 0 ax)
                 (reg:SI 88 [ <retval> ])) t.c:4 -1
              (nil))
     (insn 15 14 0 2 (use (reg/i:SI 0 ax)) t.c:4 -1
              (nil))
   ) ;; insn-chain
   (cfg
     (bb 0
       (edge 0 2 (flags 0x1))
     ) ;; bb
     (bb 2
       (edge 2 1 (flags 0x1))
     ) ;; bb
     (bb 1
     ) ;; bb
   ) ;; cfg
   (crtl
     (return_rtx
       (reg/i:SI 0 ax)
     ) ;; return_rtx
   ) ;; crtl
 ) ;; function "times_two"

I anticipate the format gaining extra fields, but I want to nail
down the basic ideas and structure a little before I rewrite the
RTL frontend to use it, hence this patch.

Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu.

OK for trunk?

gcc/ChangeLog:
	* Makefile.in (OBJS): Add print-rtl-function.o.
	* print-rtl-function.c: New file.
	* print-rtl.h (print_rtx_function): New decl.
---
 gcc/Makefile.in          |   1 +
 gcc/print-rtl-function.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++
 gcc/print-rtl.h          |   2 +
 3 files changed, 134 insertions(+)
 create mode 100644 gcc/print-rtl-function.c

Comments

Bernd Schmidt Sept. 29, 2016, 5:25 p.m. UTC | #1
On 09/29/2016 07:47 PM, David Malcolm wrote:
> This patch adds a new function, print_rtx_function, intended for use
> for generating function dumps suitable for parsing by the RTL frontend,
> but also intended to be human-readable, and human-authorable.

>      (note 1 0 4 (nil) NOTE_INSN_DELETED)
>      (note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
>      (insn 2 4 3 2 (set (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
>                          (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])
>                  (reg:SI 5 di [ i ])) t.c:2 -1
>               (nil))

I think it might be a good idea to get rid of redundant information like 
insn numbers for such a dump format. But that can be left for followup 
patches.

> OK for trunk?

OK.


Bernd
Jeff Law Sept. 29, 2016, 5:36 p.m. UTC | #2
On 09/29/2016 11:25 AM, Bernd Schmidt wrote:
> On 09/29/2016 07:47 PM, David Malcolm wrote:
>> This patch adds a new function, print_rtx_function, intended for use
>> for generating function dumps suitable for parsing by the RTL frontend,
>> but also intended to be human-readable, and human-authorable.
>
>>      (note 1 0 4 (nil) NOTE_INSN_DELETED)
>>      (note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
>>      (insn 2 4 3 2 (set (mem/c:SI (plus:DI (reg/f:DI 82
>> virtual-stack-vars)
>>                          (const_int -4 [0xfffffffffffffffc])) [1 i+0
>> S4 A32])
>>                  (reg:SI 5 di [ i ])) t.c:2 -1
>>               (nil))
>
> I think it might be a good idea to get rid of redundant information like
> insn numbers for such a dump format. But that can be left for followup
> patches.
I would make the same suggestion.  The insn # and backend pattern name 
(if any) should be omitted in machine-readable dump format.  I'm fine 
with that as a follow-up as well.

jeff
Segher Boessenkool Oct. 2, 2016, 12:04 p.m. UTC | #3
On Thu, Sep 29, 2016 at 11:36:29AM -0600, Jeff Law wrote:
> On 09/29/2016 11:25 AM, Bernd Schmidt wrote:
> >On 09/29/2016 07:47 PM, David Malcolm wrote:
> >>This patch adds a new function, print_rtx_function, intended for use
> >>for generating function dumps suitable for parsing by the RTL frontend,
> >>but also intended to be human-readable, and human-authorable.
> >
> >>     (note 1 0 4 (nil) NOTE_INSN_DELETED)
> >>     (note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
> >>     (insn 2 4 3 2 (set (mem/c:SI (plus:DI (reg/f:DI 82
> >>virtual-stack-vars)
> >>                         (const_int -4 [0xfffffffffffffffc])) [1 i+0
> >>S4 A32])
> >>                 (reg:SI 5 di [ i ])) t.c:2 -1
> >>              (nil))
> >
> >I think it might be a good idea to get rid of redundant information like
> >insn numbers for such a dump format. But that can be left for followup
> >patches.
> I would make the same suggestion.  The insn # and backend pattern name 
> (if any) should be omitted in machine-readable dump format.  I'm fine 
> with that as a follow-up as well.

You need the insn id for (at least) code_label.


Segher
David Malcolm Oct. 3, 2016, 12:46 p.m. UTC | #4
On Sun, 2016-10-02 at 07:04 -0500, Segher Boessenkool wrote:
> On Thu, Sep 29, 2016 at 11:36:29AM -0600, Jeff Law wrote:
> > On 09/29/2016 11:25 AM, Bernd Schmidt wrote:
> > > On 09/29/2016 07:47 PM, David Malcolm wrote:
> > > > This patch adds a new function, print_rtx_function, intended
> > > > for use
> > > > for generating function dumps suitable for parsing by the RTL
> > > > frontend,
> > > > but also intended to be human-readable, and human-authorable.
> > > 
> > > >     (note 1 0 4 (nil) NOTE_INSN_DELETED)
> > > >     (note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
> > > >     (insn 2 4 3 2 (set (mem/c:SI (plus:DI (reg/f:DI 82
> > > > virtual-stack-vars)
> > > >                         (const_int -4 [0xfffffffffffffffc])) [1
> > > > i+0
> > > > S4 A32])
> > > >                 (reg:SI 5 di [ i ])) t.c:2 -1
> > > >              (nil))
> > > 
> > > I think it might be a good idea to get rid of redundant
> > > information like
> > > insn numbers for such a dump format. But that can be left for
> > > followup
> > > patches.
> > I would make the same suggestion.  The insn # and backend pattern
> > name 
> > (if any) should be omitted in machine-readable dump format.  I'm
> > fine 
> > with that as a follow-up as well.
> 
> You need the insn id for (at least) code_label.

I think that Bernd is referring to the INSN_CODE, rather than than
INSN_UID.
diff mbox

Patch

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index ff12908..15c48bc 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1405,6 +1405,7 @@  OBJS = \
 	postreload.o \
 	predict.o \
 	print-rtl.o \
+	print-rtl-function.o \
 	print-tree.o \
 	profile.o \
 	real.o \
diff --git a/gcc/print-rtl-function.c b/gcc/print-rtl-function.c
new file mode 100644
index 0000000..c4b99c0
--- /dev/null
+++ b/gcc/print-rtl-function.c
@@ -0,0 +1,131 @@ 
+/* Print RTL functions for GCC.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "alias.h"
+#include "tree.h"
+#include "cfg.h"
+#include "flags.h"
+#include "predict.h"
+#include "function.h"
+#include "basic-block.h"
+#include "print-rtl.h"
+#include "langhooks.h"
+#include "emit-rtl.h"
+
+/* Write FN to OUTFILE in a form suitable for parsing, with indentation
+   and comments to make the structure easy for a human to grok.
+
+   Example output:
+
+     (function "times_two"
+       (insn-chain
+	 (note 1 0 4 (nil) NOTE_INSN_DELETED)
+	 (note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
+	 (insn 2 4 3 2 (set (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+			     (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])
+		     (reg:SI 5 di [ i ])) t.c:2 -1
+		  (nil))
+	 (note 3 2 6 2 NOTE_INSN_FUNCTION_BEG)
+	 (insn 6 3 7 2 (set (reg:SI 89)
+		     (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+			     (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])) t.c:3 -1
+		  (nil))
+	 (insn 7 6 10 2 (parallel [
+			 (set (reg:SI 87 [ _2 ])
+			     (ashift:SI (reg:SI 89)
+				 (const_int 1 [0x1])))
+			 (clobber (reg:CC 17 flags))
+		     ]) t.c:3 -1
+		  (expr_list:REG_EQUAL (ashift:SI (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+				 (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])
+			 (const_int 1 [0x1]))
+		     (nil)))
+	 (insn 10 7 14 2 (set (reg:SI 88 [ <retval> ])
+		     (reg:SI 87 [ _2 ])) t.c:3 -1
+		  (nil))
+	 (insn 14 10 15 2 (set (reg/i:SI 0 ax)
+		     (reg:SI 88 [ <retval> ])) t.c:4 -1
+		  (nil))
+	 (insn 15 14 0 2 (use (reg/i:SI 0 ax)) t.c:4 -1
+		  (nil))
+       ) ;; insn-chain
+       (cfg
+	 (bb 0
+	   (edge 0 2 (flags 0x1))
+	 ) ;; bb
+	 (bb 2
+	   (edge 2 1 (flags 0x1))
+	 ) ;; bb
+	 (bb 1
+	 ) ;; bb
+       ) ;; cfg
+       (crtl
+	 (return_rtx
+	   (reg/i:SI 0 ax)
+	 ) ;; return_rtx
+       ) ;; crtl
+     ) ;; function "times_two"
+*/
+
+DEBUG_FUNCTION void
+print_rtx_function (FILE *outfile, function *fn)
+{
+  tree fdecl = fn->decl;
+
+  const char *dname = lang_hooks.decl_printable_name (fdecl, 2);
+
+  fprintf (outfile, "(function \"%s\"\n", dname);
+
+  /* The instruction chain.  */
+  fprintf (outfile, "  (insn-chain\n");
+  for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
+    print_rtl_single_with_indent (outfile, insn, 4);
+  fprintf (outfile, "  ) ;; insn-chain\n");
+
+  /* The CFG.  */
+  fprintf (outfile, "  (cfg\n");
+  {
+    basic_block bb;
+    FOR_ALL_BB_FN (bb, fn)
+      {
+	fprintf (outfile, "    (bb %i\n", bb->index);
+	edge e;
+	edge_iterator ei;
+	FOR_EACH_EDGE (e, ei, bb->succs)
+	  fprintf (outfile, "      (edge %i %i (flags 0x%x))\n",
+		   e->src->index, e->dest->index, e->flags);
+	fprintf (outfile, "    ) ;; bb\n");
+      }
+  }
+  fprintf (outfile, "  ) ;; cfg\n");
+
+  /* Additional RTL state.  */
+  fprintf (outfile, "  (crtl\n");
+  fprintf (outfile, "    (return_rtx \n");
+  print_rtl_single_with_indent (outfile, crtl->return_rtx, 6);
+  fprintf (outfile, "    ) ;; return_rtx\n");
+  fprintf (outfile, "  ) ;; crtl\n");
+
+  fprintf (outfile, ") ;; function \"%s\"\n", dname);
+}
diff --git a/gcc/print-rtl.h b/gcc/print-rtl.h
index e585a63..9cad683 100644
--- a/gcc/print-rtl.h
+++ b/gcc/print-rtl.h
@@ -36,4 +36,6 @@  extern void print_insn (pretty_printer *pp, const rtx_insn *x, int verbose);
 extern void rtl_dump_bb_for_graph (pretty_printer *, basic_block);
 extern const char *str_pattern_slim (const_rtx);
 
+extern void print_rtx_function (FILE *file, function *fn);
+
 #endif  // GCC_PRINT_RTL_H