Hi,
The following patch has been bootstrapped and regtested on powerpc64le-linux, 
aarch64-linux and x86_64-linux. This patch is a proposed fix for PR118533.
Request you to please review the patch.

Regards
Surya


lra: initialize allocated_hard_reg_p[] for hard regs referenced in RTL 
[PR118533]

When computing the costs of the hard registers in assign_hard_reg(), the
cost of saving/restoring a callee-save register in the prolog/epilog is
taken into consideration. However, if some other pseudo has already been
assigned that hard register, then any further assignments of that hard
register don't need to be charged the save/restore cost, since it has
already been accounted for. The array allocated_hardreg_p[] specifies if
a hard register has already been allocated to an allocno. This array is
updated whenever a register is assigned. This array should also be
updated if any hard register is referenced in the RTL because any such
register usage should count as the "first" usage. A hard register
reference can occur in the RTL due to inline asm specifying a register
for a local variable, or a target’s machine pattern can explicitly
reference a hard register.

2025-01-28  Surya Kumari Jangala  <jskum...@linux.ibm.com>

gcc/
        PR rtl-optimization/118533
        * ira-color.cc (initialize_allocated_hardreg): New function.
        (color): Initialize array.
---

diff --git a/gcc/ira-color.cc b/gcc/ira-color.cc
index 0699b349a1a..2ab87860ce6 100644
--- a/gcc/ira-color.cc
+++ b/gcc/ira-color.cc
@@ -5194,12 +5194,64 @@ ira_finish_assign (void)
 
 
 
+/* When computing the costs of the hard registers in assign_hard_reg(),
+   the cost of saving/restoring a callee-save register in prolog/epilog is
+   taken into consideration. However, if some other pseudo has already
+   been assigned that hard register, then any further assignments of
+   that hard register don't need to be charged that save/restore cost,
+   since it has already been accounted for. The array
+   allocated_hardreg_p[] specifies if a hard register has already been
+   allocated to an allocno. This array is updated whenever a register is
+   assigned. This array should also be updated if any hard register is
+   referenced in the RTL insns. A hard register reference can occur in
+   the RTL due to inline asm specifying a register for a local variable,
+   or a target’s machine pattern can explicitly reference a hard
+   register.  */
+static void
+initialize_allocated_hardreg (void)
+{
+  basic_block bb;
+
+  memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
+
+  FOR_ALL_BB_FN (bb, cfun) {
+    rtx_insn *insn;
+    enum rtx_code pat_code;
+
+    FOR_BB_INSNS (bb, insn) {
+      if (!NONDEBUG_INSN_P (insn))
+       continue;
+
+      pat_code = GET_CODE (PATTERN (insn));
+      if (pat_code == ASM_INPUT || pat_code == USE || pat_code == CLOBBER)
+       continue;
+
+      extract_insn (insn);
+
+      for (int i = 0; i < recog_data.n_operands; i++)
+       {
+         rtx op = recog_data.operand[i];
+         if (GET_CODE (op) == SUBREG)
+           op = SUBREG_REG (op);
+         if (REG_P (op) && REGNO (op) < FIRST_PSEUDO_REGISTER)
+           {
+             int hard_regno = REGNO (op);
+             machine_mode mode = recog_data.operand_mode[i];
+             for (int j = hard_regno_nregs (hard_regno, mode) - 1; j >= 0; j--)
+               allocated_hardreg_p[hard_regno + j] = true;
+           }
+       }
+    }
+  }
+}
+
+
 /* Entry function doing color-based register allocation.  */
 static void
 color (void)
 {
   allocno_stack_vec.create (ira_allocnos_num);
-  memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
+  initialize_allocated_hardreg ();
   ira_initiate_assign ();
   do_coloring ();
   ira_finish_assign ();
-- 
2.43.5

Reply via email to