public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix IRA register preferencing
@ 2014-12-09 19:21 Wilco Dijkstra
  2014-12-09 23:17 ` Jeff Law
  0 siblings, 1 reply; 7+ messages in thread
From: Wilco Dijkstra @ 2014-12-09 19:21 UTC (permalink / raw)
  To: gcc-patches

This fixes a bug in register preferencing. When live range splitting creates a new register from
another, it copies most fields except for the register preferences. The preference GENERAL_REGS is
used as reg_pref[i].prefclass is initialized with GENERAL_REGS in allocate_reg_info () and
resize_reg_info ().

This initialization value is not innocuous like the comment suggests - if a new register has a
non-integer mode, it is forced to prefer GENERAL_REGS. This changes the register costs in pass 2 so
that they are incorrect. As a result the liverange is either spilled or allocated to an integer
register:

void g(double);
void f(double x) 
{ 
  if (x == 0) 
    return; 
  g (x);
  g (x); 
}

f:
        fcmp    d0, #0.0
        bne     .L6
        ret
.L6:
        stp     x19, x30, [sp, -16]!
        fmov    x19, d0
        bl      g
        fmov    d0, x19
        ldp     x19, x30, [sp], 16
        b       g

With the fix it uses a floating point register as expected. Given a similar issue in
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02253.html, would it not be better to change the
initialization values of reg_pref to illegal register classes so this kind of issue can be trivially
found with an assert? Also would it not be a good idea to have a single register copy function that
ensures all data is copied?


ChangeLog: 2014-12-09  Wilco Dijkstra  wdijkstr@arm.com

	* gcc/ira-emit.c (ira_create_new_reg): Copy preference classes.

---
 gcc/ira-emit.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/gcc/ira-emit.c b/gcc/ira-emit.c
index d246b7f..d736836 100644
--- a/gcc/ira-emit.c
+++ b/gcc/ira-emit.c
@@ -348,6 +348,7 @@ rtx
 ira_create_new_reg (rtx original_reg)
 {
   rtx new_reg;
+  int original_regno = REGNO (original_reg);
 
   new_reg = gen_reg_rtx (GET_MODE (original_reg));
   ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (original_reg);
@@ -356,8 +357,16 @@ ira_create_new_reg (rtx original_reg)
   REG_ATTRS (new_reg) = REG_ATTRS (original_reg);
   if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
     fprintf (ira_dump_file, "      Creating newreg=%i from oldreg=%i\n",
-	     REGNO (new_reg), REGNO (original_reg));
+	     REGNO (new_reg), original_regno);
   ira_expand_reg_equiv ();
+
+  /* Copy the preference classes to new_reg.  */
+  resize_reg_info ();
+  setup_reg_classes (REGNO (new_reg),
+		     reg_preferred_class (original_regno),
+		     reg_alternate_class (original_regno),
+		     reg_allocno_class (original_regno));
+
   return new_reg;
 }
 
-- 
1.9.1



^ permalink raw reply	[flat|nested] 7+ messages in thread
* [PATCH] Fix IRA register preferencing
@ 2015-11-10 13:31 Wilco Dijkstra
  2015-11-12  3:44 ` Vladimir Makarov
  0 siblings, 1 reply; 7+ messages in thread
From: Wilco Dijkstra @ 2015-11-10 13:31 UTC (permalink / raw)
  To: gcc-patches

Ping of https://gcc.gnu.org/ml/gcc-patches/2014-12/msg00829.html:



This fixes a bug in register preferencing. When live range splitting creates
a new register from
another, it copies most fields except for the register preferences. The
preference GENERAL_REGS is
used as reg_pref[i].prefclass is initialized with GENERAL_REGS in
allocate_reg_info () and
resize_reg_info ().

This initialization value is not innocuous like the comment suggests - if a
new register has a
non-integer mode, it is forced to prefer GENERAL_REGS. This changes the
register costs in pass 2 so
that they are incorrect. As a result the liverange is either spilled or
allocated to an integer
register:

void g(double);
void f(double x) 
{ 
  if (x == 0) 
    return; 
  g (x);
  g (x); 
}

f:
        fcmp    d0, #0.0
        bne     .L6
        ret
.L6:
        stp     x19, x30, [sp, -16]!
        fmov    x19, d0
        bl      g
        fmov    d0, x19
        ldp     x19, x30, [sp], 16
        b       g

With the fix it uses a floating point register as expected. Given a similar
issue in
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02253.html, would it not be
better to change the
initialization values of reg_pref to illegal register classes so this kind
of issue can be trivially
found with an assert? Also would it not be a good idea to have a single
register copy function that
ensures all data is copied?


ChangeLog: 2014-12-09  Wilco Dijkstra  wdijkstr@arm.com

        * gcc/ira-emit.c (ira_create_new_reg): Copy preference classes.

---
 gcc/ira-emit.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/gcc/ira-emit.c b/gcc/ira-emit.c
index d246b7f..d736836 100644
--- a/gcc/ira-emit.c
+++ b/gcc/ira-emit.c
@@ -348,6 +348,7 @@ rtx
 ira_create_new_reg (rtx original_reg)
 {
   rtx new_reg;
+  int original_regno = REGNO (original_reg);
 
   new_reg = gen_reg_rtx (GET_MODE (original_reg));
   ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (original_reg);
@@ -356,8 +357,16 @@ ira_create_new_reg (rtx original_reg)
   REG_ATTRS (new_reg) = REG_ATTRS (original_reg);
   if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
     fprintf (ira_dump_file, "      Creating newreg=%i from oldreg=%i\n",
-            REGNO (new_reg), REGNO (original_reg));
+            REGNO (new_reg), original_regno);
   ira_expand_reg_equiv ();
+
+  /* Copy the preference classes to new_reg.  */
+  resize_reg_info ();
+  setup_reg_classes (REGNO (new_reg),
+                   reg_preferred_class (original_regno),
+                   reg_alternate_class (original_regno),
+                   reg_allocno_class (original_regno));
+
   return new_reg;
 }
 
-- 
1.9.1





^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-11-12  3:44 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-09 19:21 [PATCH] Fix IRA register preferencing Wilco Dijkstra
2014-12-09 23:17 ` Jeff Law
2014-12-10 13:26   ` Wilco Dijkstra
2014-12-10 20:47     ` Jeff Law
2015-04-27 15:01       ` Wilco Dijkstra
2015-11-10 13:31 Wilco Dijkstra
2015-11-12  3:44 ` Vladimir Makarov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).