patch to fix PR91333

Message ID 7a796507-b078-4298-d2f6-501613eca984@redhat.com
State New
Headers show
Series
  • patch to fix PR91333
Related show

Commit Message

Vladimir Makarov Jan. 31, 2020, 8:17 p.m.
The following patch fixes

   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91333

The patch was successfully bootstrapped and tested on x86-64.

The patch changes order of putting colorable allocnos on the stack and 
consequently changes order of assigning hard registers to the allocnos 
(they all will get a hard register).  This can change the assignment and 
eliminate some moves involving hard registers.

I tried many different heuristics of ordering colorable allocnos based 
on different allocno (and corresponding thread) features like living 
only in BB, live range, the allocno preferences etc. But surprisingly 
this simplest patch worked the best.   The patch results in the same 
SPEC2000 rates.

Patch

commit 9ba4fc60a8d4c06130dedb7a6df1c72d972c4eb6
Author: Vladimir N. Makarov <vmakarov@redhat.com>
Date:   Fri Jan 31 14:26:26 2020 -0500

        Fix for PR 91333 - suboptimal register allocation for inline asm
    
        2020-01-31  Vladimir Makarov  <vmakarov@redhat.com>
    
                PR rtl-optimization/91333
                * ira-color.c (bucket_allocno_compare_func): Move conflict hard
                reg preferences comparison up.
    
        2020-01-31  Vladimir Makarov  <vmakarov@redhat.com>
    
                PR rtl-optimization/91333
                * gcc.target/i386/pr91333.c: New.

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 022865d005d..f4141157e97 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@ 
+2020-01-31  Vladimir Makarov  <vmakarov@redhat.com>
+
+	PR rtl-optimization/91333
+	* ira-color.c (bucket_allocno_compare_func): Move conflict hard
+	reg preferences comparison up.
+
 2020-01-31  Andrew Stubbs  <ams@codesourcery.com>
 
 	* config/gcn/gcn-valu.md (addv64di3_exec): Allow one '0' in each
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index 4a726dc7c1b..51c4afd6391 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -2251,6 +2251,11 @@  bucket_allocno_compare_func (const void *v1p, const void *v2p)
   ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno;
   int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
 
+  /* Push allocnos with minimal conflict_allocno_hard_prefs first.  */
+  pref1 = ALLOCNO_COLOR_DATA (a1)->conflict_allocno_hard_prefs;
+  pref2 = ALLOCNO_COLOR_DATA (a2)->conflict_allocno_hard_prefs;
+  if ((diff = pref1 - pref2) != 0)
+    return diff;
   freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq;
   freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq;
   if ((diff = freq1 - freq2) != 0)
@@ -2276,11 +2281,6 @@  bucket_allocno_compare_func (const void *v1p, const void *v2p)
   a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
   if ((diff = a2_num - a1_num) != 0)
     return diff;
-  /* Push allocnos with minimal conflict_allocno_hard_prefs first.  */
-  pref1 = ALLOCNO_COLOR_DATA (a1)->conflict_allocno_hard_prefs;
-  pref2 = ALLOCNO_COLOR_DATA (a2)->conflict_allocno_hard_prefs;
-  if ((diff = pref1 - pref2) != 0)
-    return diff;
   return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
 }
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f95d2d4e069..edc250d8b40 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@ 
+2020-01-31  Vladimir Makarov  <vmakarov@redhat.com>
+
+	PR rtl-optimization/91333
+	* gcc.target/i386/pr91333.c: New.
+
 2020-01-31  Tobias Burnus  <tobias@codesourcery.com>
 
 	PR fortran/93462
diff --git a/gcc/testsuite/gcc.target/i386/pr91333.c b/gcc/testsuite/gcc.target/i386/pr91333.c
new file mode 100644
index 00000000000..41fc328698e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91333.c
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target x86_64-*-* } } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-final { scan-assembler-times "vmovapd" 2 } } */
+
+static inline double g (double x){
+  asm volatile ("" : "+x" (x));
+  return x;
+}
+static inline double f (double a, double b){
+  return g (g (a) + g (b));
+}
+double h (double a, double b){
+  return f (f (a, a), f (b, b));
+}