https://gcc.gnu.org/g:c4dae80357ccf2e035d8e9ec0a3bb319344c5b41

commit r15-7185-gc4dae80357ccf2e035d8e9ec0a3bb319344c5b41
Author: Vladimir N. Makarov <vmaka...@redhat.com>
Date:   Fri Jan 24 13:16:53 2025 -0500

    [PR118497][IRA]: Fix calculation of cost of assigning callee-saved hard reg
    
      Assembler code generated by GCC for PR118497 contains unnecessary
    move insn.  This happened as IRA assigns AX reg to a pseudo which
    should be in BX reg later for a call.  The pseudo did not get BX as
    LRA decided that it requires to save BX although BX will be saved
    anyway.  The patch fixes the cost calculation.  Usage of hard reg
    nrefs from regstat or DF will result in numerous failures as such
    nrefs include artificial reg refs.  Therefore we add a calculation of
    hard reg nrefs in IRA.  Also we change regexp used for scanning the
    assembler in test vartrack-1.c as with the patch LRA assigns
    callee-saved hard reg BP instead of another callee-saved hard reg BX
    expected by the test.
    
    gcc/ChangeLog:
    
            PR target/118497
            * ira-int.h (target_ira_int): Add x_ira_hard_regno_nrefs.
            (ira_hard_regno_nrefs): New macro.
            * ira.cc (setup_hard_regno_aclass): Remove unused code.  Modify
            the comment.
            (setup_hard_regno_nrefs): New function.
            (ira): Call it.
            * ira-color.cc (calculate_saved_nregs): Check
            ira_hard_regno_nrefs.
    
    gcc/testsuite/ChangeLog:
    
            PR target/118497
            * gcc.target/i386/pr118497.c: New.
            * gcc.target/i386/vartrack-1.c: Modify the regexp.

Diff:
---
 gcc/ira-color.cc                           |  1 +
 gcc/ira-int.h                              |  5 ++++
 gcc/ira.cc                                 | 42 ++++++++++++++++++------------
 gcc/testsuite/gcc.target/i386/pr118497.c   | 16 ++++++++++++
 gcc/testsuite/gcc.target/i386/vartrack-1.c | 12 ++++-----
 5 files changed, 54 insertions(+), 22 deletions(-)

diff --git a/gcc/ira-color.cc b/gcc/ira-color.cc
index 23f68c007573..0699b349a1af 100644
--- a/gcc/ira-color.cc
+++ b/gcc/ira-color.cc
@@ -1752,6 +1752,7 @@ calculate_saved_nregs (int hard_regno, machine_mode mode)
   ira_assert (hard_regno >= 0);
   for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--)
     if (!allocated_hardreg_p[hard_regno + i]
+       && ira_hard_regno_nrefs[hard_regno + i] == 0
        && !crtl->abi->clobbers_full_reg_p (hard_regno + i)
        && !LOCAL_REGNO (hard_regno + i))
       nregs++;
diff --git a/gcc/ira-int.h b/gcc/ira-int.h
index aa8432416fce..49e086e4d4b1 100644
--- a/gcc/ira-int.h
+++ b/gcc/ira-int.h
@@ -936,6 +936,9 @@ public:
 
   /* Flag of that the above array has been initialized.  */
   bool x_ira_prohibited_mode_move_regs_initialized_p;
+
+  /* Number of real occurences of hard regs before IRA.  */
+  size_t x_ira_hard_regno_nrefs[FIRST_PSEUDO_REGISTER];
 };
 
 extern class target_ira_int default_target_ira_int;
@@ -983,6 +986,8 @@ extern class target_ira_int *this_target_ira_int;
   (this_target_ira_int->x_ira_reg_class_superunion)
 #define ira_prohibited_mode_move_regs \
   (this_target_ira_int->x_ira_prohibited_mode_move_regs)
+#define ira_hard_regno_nrefs \
+  (this_target_ira_int->x_ira_hard_regno_nrefs)
 
 /* ira.cc: */
 
diff --git a/gcc/ira.cc b/gcc/ira.cc
index ad522b00f8b5..885239d1b43c 100644
--- a/gcc/ira.cc
+++ b/gcc/ira.cc
@@ -1416,7 +1416,7 @@ find_reg_classes (void)
 
 
 
-/* Set up the array above.  */
+/* Set up array ira_hard_regno_allocno_class.  */
 static void
 setup_hard_regno_aclass (void)
 {
@@ -1424,25 +1424,10 @@ setup_hard_regno_aclass (void)
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     {
-#if 1
       ira_hard_regno_allocno_class[i]
        = (TEST_HARD_REG_BIT (no_unit_alloc_regs, i)
           ? NO_REGS
           : ira_allocno_class_translate[REGNO_REG_CLASS (i)]);
-#else
-      int j;
-      enum reg_class cl;
-      ira_hard_regno_allocno_class[i] = NO_REGS;
-      for (j = 0; j < ira_allocno_classes_num; j++)
-       {
-         cl = ira_allocno_classes[j];
-         if (ira_class_hard_reg_index[cl][i] >= 0)
-           {
-             ira_hard_regno_allocno_class[i] = cl;
-             break;
-           }
-       }
-#endif
     }
 }
 
@@ -5549,6 +5534,30 @@ static int saved_flag_ira_share_spill_slots;
 /* Set to true while in IRA.  */
 bool ira_in_progress = false;
 
+/* Set up array ira_hard_regno_nrefs.  */
+static void
+setup_hard_regno_nrefs (void)
+{
+  int i;
+
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    {
+      ira_hard_regno_nrefs[i] = 0;
+      for (df_ref use = DF_REG_USE_CHAIN (i);
+          use != NULL;
+          use = DF_REF_NEXT_REG (use))
+       if (DF_REF_CLASS (use) != DF_REF_ARTIFICIAL
+           && !(DF_REF_INSN_INFO (use) && DEBUG_INSN_P (DF_REF_INSN (use))))
+         ira_hard_regno_nrefs[i]++;
+      for (df_ref def = DF_REG_DEF_CHAIN (i);
+          def != NULL;
+          def = DF_REF_NEXT_REG (def))
+       if (DF_REF_CLASS (def) != DF_REF_ARTIFICIAL
+           && !(DF_REF_INSN_INFO (def) && DEBUG_INSN_P (DF_REF_INSN (def))))
+         ira_hard_regno_nrefs[i]++;
+    }
+}
+
 /* This is the main entry of IRA.  */
 static void
 ira (FILE *f)
@@ -5562,6 +5571,7 @@ ira (FILE *f)
   edge e;
   bool output_jump_reload_p = false;
 
+  setup_hard_regno_nrefs ();
   if (ira_use_lra_p)
     {
       /* First put potential jump output reloads on the output edges
diff --git a/gcc/testsuite/gcc.target/i386/pr118497.c 
b/gcc/testsuite/gcc.target/i386/pr118497.c
new file mode 100644
index 000000000000..ef720931aa49
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr118497.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { ia32 } } } */
+/* { dg-options "-O2 -fpic" } */
+extern void crosscall2 (void (*fn) (void *, int), void *, int);
+extern void _cgo_panic (void *, int);
+extern void _cgo_allocate (void *, int);
+
+void
+callPanic (void)
+{
+  struct { const char *p; } a;
+  a.p = "panic from C";
+  crosscall2 (_cgo_panic, &a, sizeof a);
+  *(int*) 1 = 1;
+}
+
+/* { dg-final { scan-assembler "__x86.get_pc_thunk.bx" } } */
diff --git a/gcc/testsuite/gcc.target/i386/vartrack-1.c 
b/gcc/testsuite/gcc.target/i386/vartrack-1.c
index b7e7e7844d8e..14a2d6a0a8a9 100644
--- a/gcc/testsuite/gcc.target/i386/vartrack-1.c
+++ b/gcc/testsuite/gcc.target/i386/vartrack-1.c
@@ -15,14 +15,14 @@ main ()
 }
 
 /* Before adjust_insn:
-   26: [--sp:DI]=bx:DI
-   29: bx:DI=[sp:DI++]
+   26: [--sp:DI]=b[px]:DI
+   29: b[px]:DI=[sp:DI++]
 
    after adjust_insn:
-   26: {[argp:DI-0x10]=bx:DI;sp:DI=argp:DI-0x10;}
-   29: {bx:DI=[argp:DI-0x10];sp:DI=argp:DI-0x8;} */
+   26: {[argp:DI-0x10]=b[px]:DI;sp:DI=argp:DI-0x10;}
+   29: {b[px]:DI=[argp:DI-0x10];sp:DI=argp:DI-0x8;} */
 
-/* { dg-final { scan-rtl-dump-times {[0-9][0-9]*: 
\{\[argp:DI-0x10\]=bx:DI;sp:DI=argp:DI-0x10;\}} 1 "vartrack" } } */
+/* { dg-final { scan-rtl-dump-times {[0-9][0-9]*: 
\{\[argp:DI-0x10\]=b[px]:DI;sp:DI=argp:DI-0x10;\}} 1 "vartrack" } } */
 
-/* { dg-final { scan-rtl-dump-times {[0-9][0-9]*: 
\{bx:DI=\[argp:DI-0x10\];sp:DI=argp:DI-0x8;\}} 1 "vartrack" } } */
+/* { dg-final { scan-rtl-dump-times {[0-9][0-9]*: 
\{b[px]:DI=\[argp:DI-0x10\];sp:DI=argp:DI-0x8;\}} 1 "vartrack" } } */

Reply via email to