Targets with vitual registers would like to use virtual registers as arguments
same way usual targets use hard registers. This patch relaxes assertions that
prevent that from happening. It also introduces a new hook,
TARGET_MARK_ARG_REGNOS, which is supposed to tell df which pseudos are args.

gcc/ChangeLog:

        * df-problems.cc (df_word_lr_bb_local_compute): Patch assert to accept
        pseudo registers as args.
        * expr.cc (use_regs): Likewise.
        * df-scan.cc (df_get_entry_block_def_set): Inboke the hook to mark arg
        pseudos.
        * target.def: Introduce a hook to mark vreg args.
        * doc/tm.texi.in: Document the new hook.
        * doc/tm.texi: Likewise.
---
 gcc/df-problems.cc | 6 ++++--
 gcc/df-scan.cc     | 4 ++++
 gcc/doc/tm.texi    | 5 +++++
 gcc/doc/tm.texi.in | 2 ++
 gcc/expr.cc        | 3 ++-
 gcc/target.def     | 7 +++++++
 6 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/gcc/df-problems.cc b/gcc/df-problems.cc
index 710f3c12032..70b44c546d4 100644
--- a/gcc/df-problems.cc
+++ b/gcc/df-problems.cc
@@ -2954,9 +2954,11 @@ df_word_lr_bb_local_compute (unsigned int bb_index)
   rtx_insn *insn;
   df_ref def, use;
 
-  /* Ensure that artificial refs don't contain references to pseudos.  */
+  /* Ensure that artificial refs don't contain references to pseudos.
+     Do allow pseudos as args, though. */
   FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
-    gcc_assert (DF_REF_REGNO (def) < FIRST_PSEUDO_REGISTER);
+    gcc_assert (DF_REF_REGNO (def) < FIRST_PSEUDO_REGISTER
+                || bitmap_bit_p (df->entry_block_defs, DF_REF_REGNO (def)));
 
   FOR_EACH_ARTIFICIAL_USE (use, bb_index)
     gcc_assert (DF_REF_REGNO (use) < FIRST_PSEUDO_REGISTER);
diff --git a/gcc/df-scan.cc b/gcc/df-scan.cc
index c6a5053ddbb..5cc8f2e1a46 100644
--- a/gcc/df-scan.cc
+++ b/gcc/df-scan.cc
@@ -3500,6 +3500,10 @@ df_get_entry_block_def_set (bitmap entry_block_defs)
        bitmap_set_bit (entry_block_defs, INCOMING_REGNO (i));
     }
 
+  /* Whatever the target considers to be an argument */
+  if (targetm.calls.mark_arg_regnos)
+    targetm.calls.mark_arg_regnos (entry_block_defs);
+
   /* The always important stack pointer.  */
   bitmap_set_bit (entry_block_defs, STACK_POINTER_REGNUM);
 
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 2832a447e3e..692794087dd 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -4507,6 +4507,11 @@ return a different value if an argument size must be 
rounded to a larger
 value.
 @end deftypefn
 
+@deftypefn {Target Hook} void TARGET_MARK_ARG_REGNOS (bitmap @var{regs})
+Useful for TARGET_NO_REGISTER_ALLOCATION targets, define this to mark all
+ the pseudos that hold the current function arguments.
+@end deftypefn
+
 @defmac FUNCTION_ARG_REGNO_P (@var{regno})
 A C expression that is nonzero if @var{regno} is the number of a hard
 register in which function arguments are sometimes passed.  This does
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 274bb899d0c..afdd9f2bf8d 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3465,6 +3465,8 @@ required.
 
 @hook TARGET_FUNCTION_ARG_ROUND_BOUNDARY
 
+@hook TARGET_MARK_ARG_REGNOS
+
 @defmac FUNCTION_ARG_REGNO_P (@var{regno})
 A C expression that is nonzero if @var{regno} is the number of a hard
 register in which function arguments are sometimes passed.  This does
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 7ca5dd84ce9..78a3f68440d 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -3789,7 +3789,8 @@ use_regs (rtx *call_fusage, int regno, int nregs)
 {
   int i;
 
-  gcc_assert (regno + nregs <= FIRST_PSEUDO_REGISTER);
+  gcc_assert (regno + nregs <= FIRST_PSEUDO_REGISTER
+              || targetm.no_register_allocation);
 
   for (i = 0; i < nregs; i++)
     use_reg (call_fusage, regno_reg_rtx[regno + i]);
diff --git a/gcc/target.def b/gcc/target.def
index 11b358f4160..71e45c6c3a2 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -5378,6 +5378,13 @@ value.",
  unsigned int, (machine_mode mode, const_tree type),
  default_function_arg_round_boundary)
 
+DEFHOOK
+(mark_arg_regnos,
+ "Useful for TARGET_NO_REGISTER_ALLOCATION targets, define this to mark all\n\
+ the pseudos that hold the current function arguments.",
+ void, (bitmap regs),
+ NULL)
+
 /* Return the diagnostic message string if function without a prototype
    is not allowed for this 'val' argument; NULL otherwise. */
 DEFHOOK
-- 
2.54.0

Reply via email to