]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
reload1.c (reload): Only spill eliminable register with multiple adjacent elimination...
authorJ"orn Rennecke <joern.rennecke@superh.com>
Wed, 25 Feb 2004 12:42:26 +0000 (12:42 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Wed, 25 Feb 2004 12:42:26 +0000 (12:42 +0000)
* reload1.c (reload): Only spill eliminable register with multiple
adjacent elimination alternatives if all alternatives fail.

From-SVN: r78430

gcc/ChangeLog
gcc/reload1.c

index ec2d741ac59f16f8ef6c34d3aba1fef3b5baad5b..4405cd971408ef5dc5be86bb9e6403273da18ed1 100644 (file)
@@ -1,3 +1,8 @@
+2004-02-25  J"orn Rennecke <joern.rennecke@superh.com>
+
+       * reload1.c (reload): Only spill eliminable register with multiple
+       adjacent elimination alternatives if all alternatives fail.
+
 2004-02-25  Richard Earnshaw  <rearnsha@arm.com>
 
        * arm.c (arm_legitimate_index_p): For QImode the range of an offset
index 1f21e4800a6eb0832116fc909bd8b51b7298edba..12451db1318e8fb85db1f5a8bd4751177e899d46 100644 (file)
@@ -849,9 +849,22 @@ reload (rtx first, int global)
 
   /* Spill any hard regs that we know we can't eliminate.  */
   CLEAR_HARD_REG_SET (used_spill_regs);
-  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
-    if (! ep->can_eliminate)
-      spill_hard_reg (ep->from, 1);
+  /* There can be multiple ways to eliminate a register;
+     they should be listed adjacently.
+     Elimination for any register fails only if all possible ways fail.  */
+  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; )
+    {
+      int from = ep->from;
+      int can_eliminate = 0;
+      do
+       {
+          can_eliminate |= ep->can_eliminate;
+          ep++;
+       }
+      while (ep < &reg_eliminate[NUM_ELIMINABLE_REGS] && ep->from == from);
+      if (! can_eliminate)
+       spill_hard_reg (from, 1);
+    }
 
 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
   if (frame_pointer_needed)