Whilst working on the RTL frontend, I ran into various crashes
relating to missing RTL information for params, for DECL_RTL, and
DECL_RTL_INCOMING.

These are normally set up for a PARM_DECL by "expand", but are
currently NULL when reading dumps from print_rtx_function.

Attempting to access DECL_RTL without initialization leads to an
attempt to lazily set the RTL, which fails here in make_decl_rtl:

1302      /* Check that we are not being given an automatic variable.  */
1303      gcc_assert (TREE_CODE (decl) != PARM_DECL
1304                  && TREE_CODE (decl) != RESULT_DECL);

Similarly, DECL_RTL_INCOMING is sometimes accessed by some passes, and
is currently NULL when reading RTL dumps.

I don't think we can re-run parts of expand, so I think we need to
store the values of DECL_RTL and DECL_RTL_INCOMING for PARM_DECLs in
the dump format.

The following patch implements this for print_rtx_function.

For example, a function on aarch64 taking one int:

int __RTL("rtl-combine") f1 (int n)
{
(function "f1"
  (param "n"
    (DECL_RTL
      (reg/v:SI %1 [ n ])
    ) ;; DECL_RTL
    (DECL_RTL_INCOMING
      (reg:SI x0 [ n ])
    ) ;; DECL_RTL_INCOMING
  ) ;; param "n"
  (insn-chain
    ;; etc

and a function on x86_64 taking three ints:

int __RTL("rtl-vregs") test_1 (int i, int j, int k)
{
(function "test_1"
  (param "i"
    (DECL_RTL
      (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
                    (const_int -4)) [1 i+0 S4 A32])
    ) ;; DECL_RTL
    (DECL_RTL_INCOMING
      (reg:SI di [ i ])
    ) ;; DECL_RTL_INCOMING
  ) ;; param "i"
  (param "j"
    (DECL_RTL
      (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
                    (const_int -8)) [1 j+0 S4 A32])
    ) ;; DECL_RTL
    (DECL_RTL_INCOMING
      (reg:SI si [ j ])
    ) ;; DECL_RTL_INCOMING
  ) ;; param "j"
  (param "k"
    (DECL_RTL
      (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
                    (const_int -12)) [1 k+0 S4 A32])
    ) ;; DECL_RTL
    (DECL_RTL_INCOMING
      (reg:SI dx [ k ])
    ) ;; DECL_RTL_INCOMING
  ) ;; param "k"
  (insn-chain
    ;; etc

I don't like how verbose the output is, but I think it's needed.
Or we could move it to after the "insn-chain" directive.

I have working code for the RTL frontend to read this format, and
it fixes the various bugs I ran into.

Only lightly tested so far.

OK for trunk if it passes bootstrap and regrtest?

gcc/ChangeLog:
        * print-rtl-function.c (print_any_param_name): New function.
        (print_param): New function.
        (print_rtx_function): Call print_param for each argument.
---
 gcc/print-rtl-function.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/gcc/print-rtl-function.c b/gcc/print-rtl-function.c
index b62f1b3..9b1155d 100644
--- a/gcc/print-rtl-function.c
+++ b/gcc/print-rtl-function.c
@@ -127,6 +127,40 @@ can_have_basic_block_p (const rtx_insn *insn)
   return true;
 }
 
+/* Subroutine of print_param.  Write the name of ARG, if any, to OUTFILE.  */
+
+static void
+print_any_param_name (FILE *outfile, tree arg)
+{
+  if (DECL_NAME (arg))
+    fprintf (outfile, " \"%s\"", IDENTIFIER_POINTER (DECL_NAME (arg)));
+}
+
+/* Print a "(param)" directive for ARG to OUTFILE.  */
+
+static void
+print_param (FILE *outfile, rtx_writer &w, tree arg)
+{
+  fprintf (outfile, "  (param");
+  print_any_param_name (outfile, arg);
+  fprintf (outfile, "\n");
+
+  /* Print the value of DECL_RTL (without lazy-evaluation).  */
+  fprintf (outfile, "    (DECL_RTL\n");
+  rtx decl_rtl = DECL_WRTL_CHECK (arg)->decl_with_rtl.rtl;
+  w.print_rtl_single_with_indent (decl_rtl, 6);
+  fprintf (outfile, "    ) ;; DECL_RTL\n");
+
+  /* Print DECL_INCOMING_RTL.  */
+  fprintf (outfile, "    (DECL_RTL_INCOMING\n");
+  w.print_rtl_single_with_indent (DECL_INCOMING_RTL (arg), 6);
+  fprintf (outfile, "    ) ;; DECL_RTL_INCOMING\n");
+
+  fprintf (outfile, "  ) ;; param");
+  print_any_param_name (outfile, arg);
+  fprintf (outfile, "\n");
+}
+
 /* Write FN to OUTFILE in a form suitable for parsing, with indentation
    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
@@ -202,6 +236,10 @@ print_rtx_function (FILE *outfile, function *fn, bool 
compact)
 
   fprintf (outfile, "(function \"%s\"\n", dname);
 
+  /* Params.  */
+  for (tree arg = DECL_ARGUMENTS (fdecl); arg; arg = DECL_CHAIN (arg))
+    print_param (outfile, w, arg);
+
   /* The instruction chain.  */
   fprintf (outfile, "  (insn-chain\n");
   basic_block curr_bb = NULL;
-- 
1.8.5.3

Reply via email to