]> gcc.gnu.org Git - gcc.git/commitdiff
RA: Ignore conflicts for some pseudos from insns throwing a final exception
authorVladimir N. Makarov <vmakarov@redhat.com>
Fri, 16 Jun 2023 15:12:32 +0000 (11:12 -0400)
committerVladimir N. Makarov <vmakarov@redhat.com>
Fri, 16 Jun 2023 15:16:35 +0000 (11:16 -0400)
IRA adds conflicts to the pseudos from insns can throw exceptions
internally even if the exception code is final for the function and
the pseudo value is not used in the exception code.  This results in
spilling a pseudo in a loop (see
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110215).

The following patch fixes the problem.

        PR rtl-optimization/110215

gcc/ChangeLog:

* ira-lives.cc: Include except.h.
(process_bb_node_lives): Ignore conflicts from cleanup exceptions
when the pseudo does not live at the exception landing pad.

gcc/ira-lives.cc

index 6a3901ee234f1264f5e1cebae5d61709a397c37e..bc8493856a4eae92955471baea324df743532dd3 100644 (file)
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ira-int.h"
 #include "sparseset.h"
 #include "function-abi.h"
+#include "except.h"
 
 /* The code in this file is similar to one in global but the code
    works on the allocno basis and creates live ranges instead of
@@ -1383,14 +1384,24 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
                      SET_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj));
                      SET_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
                    }
-                 if (can_throw_internal (insn))
+                 eh_region r;
+                 eh_landing_pad lp;
+                 rtx_code_label *landing_label;
+                 basic_block landing_bb;
+                 if (can_throw_internal (insn)
+                     && (r = get_eh_region_from_rtx (insn)) != NULL
+                     && (lp = gen_eh_landing_pad (r)) != NULL
+                     && (landing_label = lp->landing_pad) != NULL
+                     && (landing_bb = BLOCK_FOR_INSN (landing_label)) != NULL
+                     && (r->type != ERT_CLEANUP
+                         || bitmap_bit_p (df_get_live_in (landing_bb),
+                                          ALLOCNO_REGNO (a))))
                    {
-                     OBJECT_CONFLICT_HARD_REGS (obj)
-                       |= callee_abi.mode_clobbers (ALLOCNO_MODE (a));
-                     OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)
-                       |= callee_abi.mode_clobbers (ALLOCNO_MODE (a));
+                     HARD_REG_SET new_conflict_regs
+                       = callee_abi.mode_clobbers (ALLOCNO_MODE (a));
+                     OBJECT_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
+                     OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
                    }
-
                  if (sparseset_bit_p (allocnos_processed, num))
                    continue;
                  sparseset_set_bit (allocnos_processed, num);
This page took 0.062909 seconds and 5 git commands to generate.