]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR116778][LRA]: Check pseudos assigned to FP after rematerialization to build live...
authorVladimir N. Makarov <vmakarov@redhat.com>
Wed, 11 Dec 2024 20:36:21 +0000 (15:36 -0500)
committerVladimir N. Makarov <vmakarov@redhat.com>
Wed, 11 Dec 2024 20:36:38 +0000 (15:36 -0500)
This is a better fix of the PR permitting to avoid building live
ranges after rematerialization.  It checks that FP can not be
eliminated now and that pseudos assigned to FP will be spilled.  In
this case we need to build live ranges after rematerialization for
correct assignments of stack slots to spilled pseudos involved in
rematerialization.

gcc/ChangeLog:

PR rtl-optimization/116778
* ira-int.h (x_ira_class_hard_reg_index): Fix comment typo.
* lra-eliminations.cc (lra_fp_pseudo_p): New function.
* lra-int.h (lra_fp_pseudo_p): External declaration.
* lra-spills.cc (lra_need_for_spills_p): Fix formatting.
* lra.cc (lra): Use lra_fp_pseudo_p in lra_create_live_range after
lra_remat.

gcc/ira-int.h
gcc/lra-eliminations.cc
gcc/lra-int.h
gcc/lra-spills.cc
gcc/lra.cc

index 8c3c5941de54a18187589c998bdb0565cdefddc2..5ce930b6d22a8caf24e077699f6a46aebdf39a53 100644 (file)
@@ -868,7 +868,7 @@ public:
 
   /* Index (in ira_class_hard_regs; for given register class and hard
      register (in general case a hard register can belong to several
-     register classes;.  The index is negative for hard registers
+     register classes).  The index is negative for hard registers
      unavailable for the allocation.  */
   short x_ira_class_hard_reg_index[N_REG_CLASSES][FIRST_PSEUDO_REGISTER];
 
index 96772f2904a683d5ca0e05a95f760c58d6715441..5343d8c5102df193bf8919e389c1811f7fdcc222 100644 (file)
@@ -1428,6 +1428,25 @@ lra_update_fp2sp_elimination (int *spilled_pseudos)
   return n;
 }
 
+/* Return true if we have a pseudo assigned to hard frame pointer.  */
+bool
+lra_fp_pseudo_p (void)
+{
+  HARD_REG_SET set;
+
+  if (frame_pointer_needed)
+    /* At this stage it means we have no pseudos assigned to FP:  */
+    return false;
+  CLEAR_HARD_REG_SET (set);
+  add_to_hard_reg_set (&set, Pmode, HARD_FRAME_POINTER_REGNUM);
+  for (int i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
+    if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0
+       && overlaps_hard_reg_set_p (set, PSEUDO_REGNO_MODE (i),
+                                   reg_renumber[i]))
+      return true;
+  return false;
+}
+
 /* Entry function to do final elimination if FINAL_P or to update
    elimination register offsets (FIRST_P if we are doing it the first
    time).  */
index 5f605c3ae410a2d06465a0eb48375d7bd0c063ca..abee008e6423512f50ad23685b4d19045a5f097e 100644 (file)
@@ -419,6 +419,7 @@ extern rtx lra_eliminate_regs_1 (rtx_insn *, rtx, machine_mode,
                                 bool, bool, poly_int64, bool);
 extern void eliminate_regs_in_insn (rtx_insn *insn, bool, bool, poly_int64);
 extern int lra_update_fp2sp_elimination (int *spilled_pseudos);
+extern bool lra_fp_pseudo_p (void);
 extern void lra_eliminate (bool, bool);
 
 extern poly_int64 lra_update_sp_offset (rtx, poly_int64);
index 3f5c8d2bcb00d502671e82a7c863447359356958..6e9a8c3e34e3771552f7ef610652ab0317569837 100644 (file)
@@ -594,8 +594,9 @@ lra_need_for_scratch_reg_p (void)
 bool
 lra_need_for_spills_p (void)
 {
-  int i; max_regno = max_reg_num ();
+  int i;
 
+  max_regno = max_reg_num ();
   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
     if (lra_reg_info[i].nrefs != 0 && lra_get_regno_hard_regno (i) < 0
        && ! ira_former_scratch_p (i))
index 6b740ed23252c9586fb2ef6b48bdcfca865cd0cd..55737deba3f158f550d57c28aa1e7ca3698a9845 100644 (file)
@@ -2555,8 +2555,11 @@ lra (FILE *f, int verbose)
         rematerialize them first.  */
       if (lra_remat ())
        {
-         /* We need full live info -- see the comment above.  */
-         lra_create_live_ranges (true, true);
+         /* We need full live info -- see the comment above.  We also might
+            need live info if we have a pseudo assigned to hard frame pointer
+            reg and will need FP for usual purposes.  */
+         lra_create_live_ranges (lra_reg_spill_p || lra_fp_pseudo_p (),
+                                 true);
          live_p = true;
          if (! lra_need_for_spills_p ())
            {