* config/tc-rx.c (rx_bytesT): Add grown/shrank counters for
authorDJ Delorie <dj@redhat.com>
Fri, 2 Jul 2010 20:24:23 +0000 (20:24 +0000)
committerDJ Delorie <dj@redhat.com>
Fri, 2 Jul 2010 20:24:23 +0000 (20:24 +0000)
relaxation.
(rx_relax_frag): Prevent infinite loops of grow/shrink/grow/etc.

gas/ChangeLog
gas/config/tc-rx.c

index ef3ac8b..47708c7 100644 (file)
@@ -1,3 +1,9 @@
+2010-07-02  DJ Delorie  <dj@redhat.com>
+
+       * config/tc-rx.c (rx_bytesT): Add grown/shrank counters for
+       relaxation.
+       (rx_relax_frag): Prevent infinite loops of grow/shrink/grow/etc.
+
 2010-07-01  H.J. Lu  <hongjiu.lu@intel.com>
 
        AVX Programming Reference (June, 2010)
index 3bb9a5a..00101e0 100644 (file)
@@ -624,6 +624,8 @@ typedef struct rx_bytesT
   int n_relax;
   int link_relax;
   fixS *link_relax_fixP;
+  char times_grown;
+  char times_shrank;
 } rx_bytesT;
 
 static rx_bytesT rx_bytes;
@@ -1485,6 +1487,21 @@ rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
        break;
       }
 
+  /* This prevents infinite loops in align-heavy sources.  */
+  if (newsize < oldsize)
+    {
+      if (fragP->tc_frag_data->times_shrank > 10
+         && fragP->tc_frag_data->times_grown > 10)
+       newsize = oldsize;
+      if (fragP->tc_frag_data->times_shrank < 20)
+       fragP->tc_frag_data->times_shrank ++;
+    }
+  else if (newsize > oldsize)
+    {
+      if (fragP->tc_frag_data->times_grown < 20)
+       fragP->tc_frag_data->times_grown ++;
+    }
+
   fragP->fr_subtype = newsize;
   tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
   return newsize - oldsize;