diff gcc/vec.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children f6334be47118
line wrap: on
line diff
--- a/gcc/vec.c	Sun Feb 07 18:28:00 2010 +0900
+++ b/gcc/vec.c	Fri Feb 12 23:39:51 2010 +0900
@@ -33,7 +33,7 @@
 #include "toplev.h"
 #include "hashtab.h"
 
-struct vec_prefix 
+struct vec_prefix
 {
   unsigned num;
   unsigned alloc;
@@ -113,7 +113,8 @@
   if (!vec_desc_hash)
     vec_desc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
 
-  slot = (struct vec_descriptor **) htab_find_slot (vec_desc_hash, &loc, 1);
+  slot = (struct vec_descriptor **) htab_find_slot (vec_desc_hash, &loc,
+						    INSERT);
   if (*slot)
     return *slot;
   *slot = XCNEW (struct vec_descriptor);
@@ -189,10 +190,10 @@
     /* If there's no prefix, and we've not requested anything, then we
        will create a NULL vector.  */
     return 0;
-  
+
   /* We must have run out of room.  */
   gcc_assert (alloc - num < (unsigned) reserve);
-  
+
   if (exact)
     /* Exact size.  */
     alloc = num + reserve;
@@ -207,7 +208,7 @@
       else
 	/* Grow slower when large.  */
 	alloc = (alloc * 3 / 2);
-      
+
       /* If this is still too small, set it to the right size. */
       if (alloc < num + reserve)
 	alloc = num + reserve;
@@ -226,20 +227,20 @@
 		    bool exact MEM_STAT_DECL)
 {
   struct vec_prefix *pfx = (struct vec_prefix *) vec;
-  unsigned alloc = alloc = calculate_allocation (pfx, reserve, exact);
-  
+  unsigned alloc = calculate_allocation (pfx, reserve, exact);
+
   if (!alloc)
     {
       if (pfx)
         ggc_free (pfx);
       return NULL;
     }
-  
+
   vec = ggc_realloc_stat (vec, vec_offset + alloc * elt_size PASS_MEM_STAT);
   ((struct vec_prefix *)vec)->alloc = alloc;
   if (!pfx)
     ((struct vec_prefix *)vec)->num = 0;
-  
+
   return vec;
 }
 
@@ -315,7 +316,7 @@
   if (vec)
     free_overhead (pfx);
 #endif
-  
+
   vec = xrealloc (vec, vec_offset + alloc * elt_size);
   ((struct vec_prefix *)vec)->alloc = alloc;
   if (!pfx)
@@ -325,7 +326,7 @@
     register_overhead ((struct vec_prefix *)vec,
     		       vec_offset + alloc * elt_size PASS_MEM_STAT);
 #endif
-  
+
   return vec;
 }
 
@@ -371,6 +372,147 @@
 			       PASS_MEM_STAT);
 }
 
+/* Stack vectors are a little different.  VEC_alloc turns into a call
+   to vec_stack_p_reserve_exact1 and passes in space allocated via a
+   call to alloca.  We record that pointer so that we know that we
+   shouldn't free it.  If the vector is resized, we resize it on the
+   heap.  We record the pointers in a vector and search it in LIFO
+   order--i.e., we look for the newest stack vectors first.  We don't
+   expect too many stack vectors at any one level, and searching from
+   the end should normally be efficient even if they are used in a
+   recursive function.  */
+
+typedef void *void_p;
+DEF_VEC_P(void_p);
+DEF_VEC_ALLOC_P(void_p,heap);
+
+static VEC(void_p,heap) *stack_vecs;
+
+/* Allocate a vector which uses alloca for the initial allocation.
+   SPACE is space allocated using alloca, ALLOC is the number of
+   entries allocated.  */
+
+void *
+vec_stack_p_reserve_exact_1 (int alloc, void *space)
+{
+  struct vec_prefix *pfx = (struct vec_prefix *) space;
+
+  VEC_safe_push (void_p, heap, stack_vecs, space);
+
+  pfx->num = 0;
+  pfx->alloc = alloc;
+
+  return space;
+}
+
+/* Grow a vector allocated using alloca.  When this happens, we switch
+   back to heap allocation.  We remove the vector from stack_vecs, if
+   it is there, since we no longer need to avoid freeing it.  */
+
+static void *
+vec_stack_o_reserve_1 (void *vec, int reserve, size_t vec_offset,
+		       size_t elt_size, bool exact MEM_STAT_DECL)
+{
+  bool found;
+  unsigned int ix;
+  void *newvec;
+
+  found = false;
+  for (ix = VEC_length (void_p, stack_vecs); ix > 0; --ix)
+    {
+      if (VEC_index (void_p, stack_vecs, ix - 1) == vec)
+	{
+	  VEC_unordered_remove (void_p, stack_vecs, ix - 1);
+	  found = true;
+	  break;
+	}
+    }
+
+  if (!found)
+    {
+      /* VEC is already on the heap.  */
+      return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size,
+				   exact PASS_MEM_STAT);
+    }
+
+  /* Move VEC to the heap.  */
+  reserve += ((struct vec_prefix *) vec)->num;
+  newvec = vec_heap_o_reserve_1 (NULL, reserve, vec_offset, elt_size,
+				 exact PASS_MEM_STAT);
+  if (newvec && vec)
+    {
+      ((struct vec_prefix *) newvec)->num = ((struct vec_prefix *) vec)->num;
+      memcpy (((struct vec_prefix *) newvec)->vec,
+	      ((struct vec_prefix *) vec)->vec,
+	      ((struct vec_prefix *) vec)->num * elt_size);
+    }
+  return newvec;
+}
+
+/* Grow a vector allocated on the stack.  */
+
+void *
+vec_stack_p_reserve (void *vec, int reserve MEM_STAT_DECL)
+{
+  return vec_stack_o_reserve_1 (vec, reserve,
+				offsetof (struct vec_prefix, vec),
+				sizeof (void *), false
+				PASS_MEM_STAT);
+}
+
+/* Exact version of vec_stack_p_reserve.  */
+
+void *
+vec_stack_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL)
+{
+  return vec_stack_o_reserve_1 (vec, reserve,
+				offsetof (struct vec_prefix, vec),
+				sizeof (void *), true
+				PASS_MEM_STAT);
+}
+
+/* Like vec_stack_p_reserve, but for objects.  */
+
+void *
+vec_stack_o_reserve (void *vec, int reserve, size_t vec_offset,
+		     size_t elt_size MEM_STAT_DECL)
+{
+  return vec_stack_o_reserve_1 (vec, reserve, vec_offset, elt_size, false
+				PASS_MEM_STAT);
+}
+
+/* Like vec_stack_p_reserve_exact, but for objects.  */
+
+void *
+vec_stack_o_reserve_exact (void *vec, int reserve, size_t vec_offset,
+			    size_t elt_size MEM_STAT_DECL)
+{
+  return vec_stack_o_reserve_1 (vec, reserve, vec_offset, elt_size, true
+				PASS_MEM_STAT);
+}
+
+/* Free a vector allocated on the stack.  Don't actually free it if we
+   find it in the hash table.  */
+
+void
+vec_stack_free (void *vec)
+{
+  unsigned int ix;
+
+  for (ix = VEC_length (void_p, stack_vecs); ix > 0; --ix)
+    {
+      if (VEC_index (void_p, stack_vecs, ix - 1) == vec)
+	{
+	  VEC_unordered_remove (void_p, stack_vecs, ix - 1);
+	  return;
+	}
+    }
+
+  /* VEC was not on the list of vecs allocated on the stack, so it
+     must be allocated on the heap.  */
+  vec_heap_free (vec);
+}
+
 #if ENABLE_CHECKING
 /* Issue a vector domain error, and then fall over.  */