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