print_rtx_function: integrate dumping of the CFG into the insn chain
authorDavid Malcolm <dmalcolm@redhat.com>
Wed, 12 Oct 2016 14:59:56 +0000 (14:59 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Wed, 12 Oct 2016 14:59:56 +0000 (14:59 +0000)
gcc/ChangeLog:
* function-tests.c: Include "print-rtl.h".
(selftest::test_expansion_to_rtl): Call print_rtx_function on the
function, and verify what is dumped.
* print-rtl-function.c (print_edge): New function.
(begin_any_block): New function.
(end_any_block): New function.
(can_have_basic_block_p): New function.
(print_rtx_function): Track the basic blocks of insns in the
chain, wrapping those that are within blocks within "(block)"
directives.  Remove the "(cfg)" directive.

From-SVN: r241057

gcc/ChangeLog
gcc/function-tests.c
gcc/print-rtl-function.c

index ff670802ce5bd522160fa11c37cbbca4725b9b58..35f38fff13ac9de0ad7632efd687e4c55f1826db 100644 (file)
@@ -1,3 +1,16 @@
+2016-10-12  David Malcolm  <dmalcolm@redhat.com>
+
+       * function-tests.c: Include "print-rtl.h".
+       (selftest::test_expansion_to_rtl): Call print_rtx_function on the
+       function, and verify what is dumped.
+       * print-rtl-function.c (print_edge): New function.
+       (begin_any_block): New function.
+       (end_any_block): New function.
+       (can_have_basic_block_p): New function.
+       (print_rtx_function): Track the basic blocks of insns in the
+       chain, wrapping those that are within blocks within "(block)"
+       directives.  Remove the "(cfg)" directive.
+
 2016-10-12  David Malcolm  <dmalcolm@redhat.com>
 
        * selftest.c (selftest::read_file): New function.
index 4152cd386d5aed5c59ec4f4c5ec430bc689566c7..049a07f9a86f3fc0b941d451d29a794c22230e6c 100644 (file)
@@ -78,6 +78,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "selftest.h"
+#include "print-rtl.h"
 
 #if CHECKING_P
 
@@ -643,6 +644,27 @@ test_expansion_to_rtl ()
 
   /* ...etc; any further checks are likely to over-specify things
      and run us into target dependencies.  */
+
+  /* Verify that print_rtl_function is sane.  */
+  named_temp_file tmp_out (".rtl");
+  FILE *outfile = fopen (tmp_out.get_filename (), "w");
+  print_rtx_function (outfile, fun);
+  fclose (outfile);
+
+  char *dump = read_file (SELFTEST_LOCATION, tmp_out.get_filename ());
+  ASSERT_STR_CONTAINS (dump, "(function \"test_fn\"\n");
+  ASSERT_STR_CONTAINS (dump, "  (insn-chain\n");
+  ASSERT_STR_CONTAINS (dump, "    (block 2\n");
+  ASSERT_STR_CONTAINS (dump, "      (edge-from entry (flags \"FALLTHRU\"))\n");
+  ASSERT_STR_CONTAINS (dump, "      (insn "); /* ...etc.  */
+  ASSERT_STR_CONTAINS (dump, "      (edge-to exit (flags \"FALLTHRU\"))\n");
+  ASSERT_STR_CONTAINS (dump, "    ) ;; block 2\n");
+  ASSERT_STR_CONTAINS (dump, "  ) ;; insn-chain\n");
+  ASSERT_STR_CONTAINS (dump, "  (crtl\n");
+  ASSERT_STR_CONTAINS (dump, "  ) ;; crtl\n");
+  ASSERT_STR_CONTAINS (dump, ") ;; function \"test_fn\"\n");
+
+  free (dump);
 }
 
 /* Run all of the selftests within this file.  */
index c4b99c03a37f82f2a0243dd667bede1627ede420..4f9b4efdb2e3cd0a25f82799aa657210e15a8081 100644 (file)
@@ -33,14 +33,106 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "emit-rtl.h"
 
+/* Print an "(edge-from)" or "(edge-to)" directive describing E
+   to OUTFILE.  */
+
+static void
+print_edge (FILE *outfile, edge e, bool from)
+{
+  fprintf (outfile, "      (%s ", from ? "edge-from" : "edge-to");
+  basic_block bb = from ? e->src : e->dest;
+  gcc_assert (bb);
+  switch (bb->index)
+    {
+    case ENTRY_BLOCK:
+      fprintf (outfile, "entry");
+      break;
+    case EXIT_BLOCK:
+      fprintf (outfile, "exit");
+      break;
+    default:
+      fprintf (outfile, "%i", bb->index);
+      break;
+    }
+
+  /* Express edge flags as a string with " | " separator.
+     e.g. (flags "FALLTHRU | DFS_BACK").  */
+  fprintf (outfile, " (flags \"");
+  bool seen_flag = false;
+#define DEF_EDGE_FLAG(NAME,IDX) \
+  do {                                         \
+    if (e->flags & EDGE_##NAME)                        \
+      {                                                \
+       if (seen_flag)                          \
+         fprintf (outfile, " | ");             \
+       fprintf (outfile, "%s", (#NAME));       \
+       seen_flag = true;                       \
+      }                                                \
+  } while (0);
+#include "cfg-flags.def"
+#undef DEF_EDGE_FLAG
+
+  fprintf (outfile, "\"))\n");
+}
+
+/* If BB is non-NULL, print the start of a "(block)" directive for it
+   to OUTFILE, otherwise do nothing.  */
+
+static void
+begin_any_block (FILE *outfile, basic_block bb)
+{
+  if (!bb)
+    return;
+
+  edge e;
+  edge_iterator ei;
+
+  fprintf (outfile, "    (block %i\n", bb->index);
+  FOR_EACH_EDGE (e, ei, bb->preds)
+    print_edge (outfile, e, true);
+}
+
+/* If BB is non-NULL, print the end of a "(block)" directive for it
+   to OUTFILE, otherwise do nothing.  */
+
+static void
+end_any_block (FILE *outfile, basic_block bb)
+{
+  if (!bb)
+    return;
+
+  edge e;
+  edge_iterator ei;
+
+  FOR_EACH_EDGE (e, ei, bb->succs)
+    print_edge (outfile, e, false);
+  fprintf (outfile, "    ) ;; block %i\n", bb->index);
+}
+
+/* Determine if INSN is of a kind that can have a basic block.  */
+
+static bool
+can_have_basic_block_p (const rtx_insn *insn)
+{
+  rtx_code code = GET_CODE (insn);
+  if (code == BARRIER)
+    return false;
+  gcc_assert (GET_RTX_FORMAT (code)[2] == 'B');
+  return true;
+}
+
 /* Write FN to OUTFILE in a form suitable for parsing, with indentation
-   and comments to make the structure easy for a human to grok.
+   and comments to make the structure easy for a human to grok.  Track
+   the basic blocks of insns in the chain, wrapping those that are within
+   blocks within "(block)" directives.
 
    Example output:
 
-     (function "times_two"
-       (insn-chain
-        (note 1 0 4 (nil) NOTE_INSN_DELETED)
+   (function "times_two"
+     (insn-chain
+       (note 1 0 4 (nil) NOTE_INSN_DELETED)
+       (block 2
+        (edge-from entry (flags "FALLTHRU"))
         (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])
@@ -69,23 +161,15 @@ along with GCC; see the file COPYING3.  If not see
                  (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"
+        (edge-to exit (flags "FALLTHRU"))
+       ) ;; block 2
+     ) ;; insn-chain
+     (crtl
+       (return_rtx
+         (reg/i:SI 0 ax)
+       ) ;; return_rtx
+     ) ;; crtl
+   ) ;; function "times_two"
 */
 
 DEBUG_FUNCTION void
@@ -99,27 +183,25 @@ print_rtx_function (FILE *outfile, function *fn)
 
   /* The instruction chain.  */
   fprintf (outfile, "  (insn-chain\n");
+  basic_block curr_bb = NULL;
   for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
-    print_rtl_single_with_indent (outfile, insn, 4);
+    {
+      basic_block insn_bb;
+      if (can_have_basic_block_p (insn))
+       insn_bb = BLOCK_FOR_INSN (insn);
+      else
+       insn_bb = NULL;
+      if (curr_bb != insn_bb)
+       {
+         end_any_block (outfile, curr_bb);
+         curr_bb = insn_bb;
+         begin_any_block (outfile, curr_bb);
+       }
+      print_rtl_single_with_indent (outfile, insn, curr_bb ? 6 : 4);
+    }
+  end_any_block (outfile, curr_bb);
   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");