* cfgexpand (n_stack_vars_conflict): New static variable.
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 Nov 2009 21:46:45 +0000 (21:46 +0000)
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 Nov 2009 21:46:45 +0000 (21:46 +0000)
(triangular_index): Reduce likelyhood of overflow by performing
the division before the multiplication.
(resize_stack_vars_conflict): Call fatal_error if overflow
occurred in triangular_index.  Update n_stack_vars_conflict.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154689 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cfgexpand.c

index 850e31f..845f268 100644 (file)
@@ -1,5 +1,11 @@
 2009-11-26  Bernd Schmidt  <bernd.schmidt@analog.com>
 
+       * cfgexpand (n_stack_vars_conflict): New static variable.
+       (triangular_index): Reduce likelyhood of overflow by performing
+       the division before the multiplication.
+       (resize_stack_vars_conflict): Call fatal_error if overflow
+       occurred in triangular_index.  Update n_stack_vars_conflict.
+
        PR rtl-opt/38582
        * regrename.c (struct du_chain): Remove member earlyclobber.
        (scan_rtx_reg): Don't set it.  Remove argument earlyclobber,
index 087b624..d3637a0 100644 (file)
@@ -217,6 +217,7 @@ static size_t *stack_vars_sorted;
    is lower triangular.  */
 static bool *stack_vars_conflict;
 static size_t stack_vars_conflict_alloc;
+static size_t n_stack_vars_conflict;
 
 /* The phase of the stack frame.  This is the known misalignment of
    virtual_stack_vars_rtx from PREFERRED_STACK_BOUNDARY.  That is,
@@ -335,7 +336,11 @@ triangular_index (size_t i, size_t j)
       size_t t;
       t = i, i = j, j = t;
     }
-  return (i * (i + 1)) / 2 + j;
+
+  if (i & 1)
+    return ((i + 1) / 2) * i + j;
+  else
+    return (i / 2) * (i + 1) + j;
 }
 
 /* Ensure that STACK_VARS_CONFLICT is large enough for N objects.  */
@@ -346,12 +351,17 @@ resize_stack_vars_conflict (size_t n)
   size_t size = triangular_index (n-1, n-1) + 1;
 
   if (size <= stack_vars_conflict_alloc)
-    return;
+    {
+      if (n > n_stack_vars_conflict)
+       fatal_error ("program is too large to be compiled on this machine");
+      return;
+    }
 
   stack_vars_conflict = XRESIZEVEC (bool, stack_vars_conflict, size);
   memset (stack_vars_conflict + stack_vars_conflict_alloc, 0,
          (size - stack_vars_conflict_alloc) * sizeof (bool));
   stack_vars_conflict_alloc = size;
+  n_stack_vars_conflict = n;
 }
 
 /* Make the decls associated with luid's X and Y conflict.  */