Patchwork obstack for equiv_class_label, more vectors on stack

login
register
mail settings
Submitter Dimitrios Apostolou
Date Aug. 19, 2012, 6:29 p.m.
Message ID <alpine.LNX.2.02.1208191206310.20463@localhost.localdomain>
Download mbox | patch
Permalink /patch/178579/
State New
Headers show

Comments

Dimitrios Apostolou - Aug. 19, 2012, 6:29 p.m.
2012-08-19  Dimitrios Apostolou  <jimis@gmx.net>

 	* gcc/tree-ssa-structalias.c: Change declaration of ce_s type
 	vector from heap to stack. Update all relevant functions to
 	VEC_alloc() such vector upfront with enough (32) slots so that
 	malloc() calls are mostly avoided.
 	(equiv_class_obstack) New global static obstack for allocating
 	struct equiv_class_label.
 	(equiv_class_add): Use the above instead of malloc().
 	(perform_var_substitution): Don't allow entries of
 	location_equiv_class_table to be freed, because they are free'd...
 	(free_var_substitution_info): ...here by freeing the obstack.
 	* gcc/vecir.h: Add declaration of stack allocated tree type vector.
 	* gcc/tree-ssa-sccvn.c (vn_phi_insert, print_scc, compare_ops)
 	(sort_scc, copy_reference, extract_and_process_scc_for_name): Use
 	it, instead of heap allocated vector.



Not all of these places are hot on the profiler, but since I changed a few 
I had to change them all to remove complete the heap ce_s vector. Passes 
tests and offers small gains (couple of ms), but expect a more thorough 
report and testing against a new snapshot by next week.


Thanks,
Dimitris
2012-08-19  Dimitrios Apostolou  <jimis@gmx.net>

	* gcc/tree-ssa-structalias.c: Change declaration of ce_s type
	vector from heap to stack. Update all relevant functions to
	VEC_alloc() such vector upfront with enough (32) slots so that
	malloc() calls are mostly avoided.
	(equiv_class_obstack) New global static obstack for allocating
	struct equiv_class_label.
	(equiv_class_add): Use the above instead of malloc().
	(perform_var_substitution): Don't allow entries of
	location_equiv_class_table to be freed, because they are free'd...
	(free_var_substitution_info): ...here by freeing the obstack.
	* gcc/vecir.h: Add declaration of stack allocated tree type vector.
	* gcc/tree-ssa-sccvn.c (vn_phi_insert, print_scc, compare_ops)
	(sort_scc, copy_reference, extract_and_process_scc_for_name): Use
	it, instead of heap allocated vector.

Patch

=== modified file 'gcc/tree-ssa-structalias.c'
--- gcc/tree-ssa-structalias.c	2012-08-16 14:27:51 +0000

+++ gcc/tree-ssa-structalias.c	2012-08-18 16:43:02 +0000

@@ -472,11 +472,14 @@  struct constraint_expr

 
 typedef struct constraint_expr ce_s;
 DEF_VEC_O(ce_s);
-DEF_VEC_ALLOC_O(ce_s, heap);

-static void get_constraint_for_1 (tree, VEC(ce_s, heap) **, bool, bool);

-static void get_constraint_for (tree, VEC(ce_s, heap) **);

-static void get_constraint_for_rhs (tree, VEC(ce_s, heap) **);

-static void do_deref (VEC (ce_s, heap) **);

+DEF_VEC_ALLOC_O_STACK(ce_s);

+#define VEC_ce_s_stack_alloc(alloc) \

+  VEC_stack_alloc (ce_s, alloc)

+

+static void get_constraint_for_1 (tree, VEC(ce_s, stack) **, bool, bool);

+static void get_constraint_for (tree, VEC(ce_s, stack) **);

+static void get_constraint_for_rhs (tree, VEC(ce_s, stack) **);

+static void do_deref (VEC (ce_s, stack) **);

 
 /* Our set constraints are made up of two constraint expressions, one
    LHS, and one RHS.
@@ -1893,6 +1896,9 @@  static htab_t pointer_equiv_class_table;

    classes.  */
 static htab_t location_equiv_class_table;
 
+/* Pool of memory for storing the above */

+static struct obstack equiv_class_obstack;

+

 /* Hash function for a equiv_class_label_t */
 
 static hashval_t
@@ -1942,7 +1948,7 @@  equiv_class_add (htab_t table, unsigned

 		 bitmap labels)
 {
   void **slot;
-  equiv_class_label_t ecl = XNEW (struct equiv_class_label);

+  equiv_class_label_t ecl = XOBNEW (&equiv_class_obstack, struct equiv_class_label);

 
   ecl->labels = labels;
   ecl->equivalence_class = equivalence_class;
@@ -2153,10 +2159,12 @@  perform_var_substitution (constraint_gra

   struct scc_info *si = init_scc_info (size);
 
   bitmap_obstack_initialize (&iteration_obstack);
+  gcc_obstack_init (&equiv_class_obstack);

+  /* NULL free function, we'll free the whole pool at the end of the pass. */

   pointer_equiv_class_table = htab_create (511, equiv_class_label_hash,
-					   equiv_class_label_eq, free);

+					   equiv_class_label_eq, NULL);

   location_equiv_class_table = htab_create (511, equiv_class_label_hash,
-					    equiv_class_label_eq, free);

+					    equiv_class_label_eq, NULL);

   pointer_equiv_class = 1;
   location_equiv_class = 1;
 
@@ -2263,6 +2271,7 @@  free_var_substitution_info (struct scc_i

   sbitmap_free (graph->direct_nodes);
   htab_delete (pointer_equiv_class_table);
   htab_delete (location_equiv_class_table);
+  obstack_free (&equiv_class_obstack, NULL);

   bitmap_obstack_release (&iteration_obstack);
 }
 
@@ -2741,7 +2750,7 @@  new_scalar_tmp_constraint_exp (const cha

    If address_p is true, the result will be taken its address of.  */
 
 static void
-get_constraint_for_ssa_var (tree t, VEC(ce_s, heap) **results, bool address_p)

+get_constraint_for_ssa_var (tree t, VEC(ce_s, stack) **results, bool address_p)

 {
   struct constraint_expr cexpr;
   varinfo_t vi;
@@ -2793,12 +2802,12 @@  get_constraint_for_ssa_var (tree t, VEC(

       for (; vi; vi = vi->next)
 	{
 	  cexpr.var = vi->id;
-	  VEC_safe_push (ce_s, heap, *results, &cexpr);

+	  VEC_safe_push (ce_s, stack, *results, &cexpr);

 	}
       return;
     }
 
-  VEC_safe_push (ce_s, heap, *results, &cexpr);

+  VEC_safe_push (ce_s, stack, *results, &cexpr);

 }
 
 /* Process constraint T, performing various simplifications and then
@@ -2878,7 +2887,7 @@  bitpos_of_field (const tree fdecl)

 
 static void
 get_constraint_for_ptr_offset (tree ptr, tree offset,
-			       VEC (ce_s, heap) **results)

+			       VEC (ce_s, stack) **results)

 {
   struct constraint_expr c;
   unsigned int j, n;
@@ -2946,7 +2955,7 @@  get_constraint_for_ptr_offset (tree ptr,

 	      c2.type = ADDRESSOF;
 	      c2.offset = 0;
 	      if (c2.var != c.var)
-		VEC_safe_push (ce_s, heap, *results, &c2);

+		VEC_safe_push (ce_s, stack, *results, &c2);

 	      temp = temp->next;
 	    }
 	  while (temp);
@@ -2981,7 +2990,7 @@  get_constraint_for_ptr_offset (tree ptr,

 	      c2.var = temp->next->id;
 	      c2.type = ADDRESSOF;
 	      c2.offset = 0;
-	      VEC_safe_push (ce_s, heap, *results, &c2);

+	      VEC_safe_push (ce_s, stack, *results, &c2);

 	    }
 	  c.var = temp->id;
 	  c.offset = 0;
@@ -3000,7 +3009,7 @@  get_constraint_for_ptr_offset (tree ptr,

    as the lhs.  */
 
 static void
-get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results,

+get_constraint_for_component_ref (tree t, VEC(ce_s, stack) **results,

 				  bool address_p, bool lhs_p)
 {
   tree orig_t = t;
@@ -3025,7 +3034,7 @@  get_constraint_for_component_ref (tree t

       temp.offset = 0;
       temp.var = integer_id;
       temp.type = SCALAR;
-      VEC_safe_push (ce_s, heap, *results, &temp);

+      VEC_safe_push (ce_s, stack, *results, &temp);

       return;
     }
 
@@ -3047,7 +3056,7 @@  get_constraint_for_component_ref (tree t

 	    temp.offset = 0;
 	    temp.var = anything_id;
 	    temp.type = ADDRESSOF;
-	    VEC_safe_push (ce_s, heap, *results, &temp);

+	    VEC_safe_push (ce_s, stack, *results, &temp);

 	    return;
 	  }
     }
@@ -3088,7 +3097,7 @@  get_constraint_for_component_ref (tree t

 				    bitpos, bitmaxsize))
 		{
 		  cexpr.var = curr->id;
-		  VEC_safe_push (ce_s, heap, *results, &cexpr);

+		  VEC_safe_push (ce_s, stack, *results, &cexpr);

 		  if (address_p)
 		    break;
 		}
@@ -3103,7 +3112,7 @@  get_constraint_for_component_ref (tree t

 	      while (curr->next != NULL)
 		curr = curr->next;
 	      cexpr.var = curr->id;
-	      VEC_safe_push (ce_s, heap, *results, &cexpr);

+	      VEC_safe_push (ce_s, stack, *results, &cexpr);

 	    }
 	  else if (VEC_length (ce_s, *results) == 0)
 	    /* Assert that we found *some* field there. The user couldn't be
@@ -3116,7 +3125,7 @@  get_constraint_for_component_ref (tree t

 	      cexpr.type = SCALAR;
 	      cexpr.var = anything_id;
 	      cexpr.offset = 0;
-	      VEC_safe_push (ce_s, heap, *results, &cexpr);

+	      VEC_safe_push (ce_s, stack, *results, &cexpr);

 	    }
 	}
       else if (bitmaxsize == 0)
@@ -3162,7 +3171,7 @@  get_constraint_for_component_ref (tree t

    This is needed so that we can handle dereferencing DEREF constraints.  */
 
 static void
-do_deref (VEC (ce_s, heap) **constraints)

+do_deref (VEC (ce_s, stack) **constraints)

 {
   struct constraint_expr *c;
   unsigned int i = 0;
@@ -3189,7 +3198,7 @@  do_deref (VEC (ce_s, heap) **constraints

    address of it.  */
 
 static void
-get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results)

+get_constraint_for_address_of (tree t, VEC (ce_s, stack) **results)

 {
   struct constraint_expr *c;
   unsigned int i;
@@ -3208,7 +3217,7 @@  get_constraint_for_address_of (tree t, V

 /* Given a tree T, return the constraint expression for it.  */
 
 static void
-get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p,

+get_constraint_for_1 (tree t, VEC (ce_s, stack) **results, bool address_p,

 		      bool lhs_p)
 {
   struct constraint_expr temp;
@@ -3240,7 +3249,7 @@  get_constraint_for_1 (tree t, VEC (ce_s,

 	temp.var = nonlocal_id;
       temp.type = ADDRESSOF;
       temp.offset = 0;
-      VEC_safe_push (ce_s, heap, *results, &temp);

+      VEC_safe_push (ce_s, stack, *results, &temp);

       return;
     }
 
@@ -3250,7 +3259,7 @@  get_constraint_for_1 (tree t, VEC (ce_s,

       temp.var = readonly_id;
       temp.type = SCALAR;
       temp.offset = 0;
-      VEC_safe_push (ce_s, heap, *results, &temp);

+      VEC_safe_push (ce_s, stack, *results, &temp);

       return;
     }
 
@@ -3311,7 +3320,7 @@  get_constraint_for_1 (tree t, VEC (ce_s,

 		      if (curr->offset - vi->offset < size)
 			{
 			  cs.var = curr->id;
-			  VEC_safe_push (ce_s, heap, *results, &cs);

+			  VEC_safe_push (ce_s, stack, *results, &cs);

 			}
 		      else
 			break;
@@ -3346,17 +3355,17 @@  get_constraint_for_1 (tree t, VEC (ce_s,

 	    {
 	      unsigned int i;
 	      tree val;
-	      VEC (ce_s, heap) *tmp = NULL;

+	      VEC (ce_s, stack) *tmp = VEC_alloc (ce_s, stack, 32);

 	      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
 		{
 		  struct constraint_expr *rhsp;
 		  unsigned j;
 		  get_constraint_for_1 (val, &tmp, address_p, lhs_p);
 		  FOR_EACH_VEC_ELT (ce_s, tmp, j, rhsp)
-		    VEC_safe_push (ce_s, heap, *results, rhsp);

+		    VEC_safe_push (ce_s, stack, *results, rhsp);

 		  VEC_truncate (ce_s, tmp, 0);
 		}
-	      VEC_free (ce_s, heap, tmp);

+	      VEC_free (ce_s, stack, tmp);

 	      /* We do not know whether the constructor was complete,
 	         so technically we have to add &NOTHING or &ANYTHING
 		 like we do for an empty constructor as well.  */
@@ -3377,7 +3386,7 @@  get_constraint_for_1 (tree t, VEC (ce_s,

 	temp.type = ADDRESSOF;
 	temp.var = nonlocal_id;
 	temp.offset = 0;
-	VEC_safe_push (ce_s, heap, *results, &temp);

+	VEC_safe_push (ce_s, stack, *results, &temp);

 	return;
       }
     default:;
@@ -3387,13 +3396,13 @@  get_constraint_for_1 (tree t, VEC (ce_s,

   temp.type = ADDRESSOF;
   temp.var = anything_id;
   temp.offset = 0;
-  VEC_safe_push (ce_s, heap, *results, &temp);

+  VEC_safe_push (ce_s, stack, *results, &temp);

 }
 
 /* Given a gimple tree T, return the constraint expression vector for it.  */
 
 static void
-get_constraint_for (tree t, VEC (ce_s, heap) **results)

+get_constraint_for (tree t, VEC (ce_s, stack) **results)

 {
   gcc_assert (VEC_length (ce_s, *results) == 0);
 
@@ -3404,7 +3413,7 @@  get_constraint_for (tree t, VEC (ce_s, h

    to be used as the rhs of a constraint.  */
 
 static void
-get_constraint_for_rhs (tree t, VEC (ce_s, heap) **results)

+get_constraint_for_rhs (tree t, VEC (ce_s, stack) **results)

 {
   gcc_assert (VEC_length (ce_s, *results) == 0);
 
@@ -3416,7 +3425,7 @@  get_constraint_for_rhs (tree t, VEC (ce_

    entries in *LHSC.  */
 
 static void
-process_all_all_constraints (VEC (ce_s, heap) *lhsc, VEC (ce_s, heap) *rhsc)

+process_all_all_constraints (VEC (ce_s, stack) *lhsc, VEC (ce_s, stack) *rhsc)

 {
   struct constraint_expr *lhsp, *rhsp;
   unsigned i, j;
@@ -3446,8 +3455,9 @@  static void

 do_structure_copy (tree lhsop, tree rhsop)
 {
   struct constraint_expr *lhsp, *rhsp;
-  VEC (ce_s, heap) *lhsc = NULL, *rhsc = NULL;

   unsigned j;
+  VEC (ce_s, stack) *lhsc = VEC_alloc (ce_s, stack, 32);

+  VEC (ce_s, stack) *rhsc = VEC_alloc (ce_s, stack, 32);

 
   get_constraint_for (lhsop, &lhsc);
   get_constraint_for_rhs (rhsop, &rhsc);
@@ -3506,14 +3516,14 @@  do_structure_copy (tree lhsop, tree rhso

   else
     gcc_unreachable ();
 
-  VEC_free (ce_s, heap, lhsc);

-  VEC_free (ce_s, heap, rhsc);

+  VEC_free (ce_s, stack, lhsc);

+  VEC_free (ce_s, stack, rhsc);

 }
 
 /* Create constraints ID = { rhsc }.  */
 
 static void
-make_constraints_to (unsigned id, VEC(ce_s, heap) *rhsc)

+make_constraints_to (unsigned id, VEC(ce_s, stack) *rhsc)

 {
   struct constraint_expr *c;
   struct constraint_expr includes;
@@ -3532,10 +3542,10 @@  make_constraints_to (unsigned id, VEC(ce

 static void
 make_constraint_to (unsigned id, tree op)
 {
-  VEC(ce_s, heap) *rhsc = NULL;

+  VEC(ce_s, stack) *rhsc = VEC_alloc (ce_s, stack, 32);

   get_constraint_for_rhs (op, &rhsc);
   make_constraints_to (id, rhsc);
-  VEC_free (ce_s, heap, rhsc);

+  VEC_free (ce_s, stack, rhsc);

 }
 
 /* Create a constraint ID = &FROM.  */
@@ -3726,7 +3736,7 @@  get_function_part_constraint (varinfo_t

    RHS.  */
 
 static void
-handle_rhs_call (gimple stmt, VEC(ce_s, heap) **results)

+handle_rhs_call (gimple stmt, VEC(ce_s, stack) **results)

 {
   struct constraint_expr rhsc;
   unsigned i;
@@ -3780,7 +3790,7 @@  handle_rhs_call (gimple stmt, VEC(ce_s,

       rhsc.var = get_call_use_vi (stmt)->id;
       rhsc.offset = 0;
       rhsc.type = SCALAR;
-      VEC_safe_push (ce_s, heap, *results, &rhsc);

+      VEC_safe_push (ce_s, stack, *results, &rhsc);

     }
 
   /* The static chain escapes as well.  */
@@ -3792,22 +3802,23 @@  handle_rhs_call (gimple stmt, VEC(ce_s,

       && gimple_call_lhs (stmt) != NULL_TREE
       && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
     {
-      VEC(ce_s, heap) *tmpc = NULL;

       struct constraint_expr lhsc, *c;
+      VEC(ce_s, stack) *tmpc = VEC_alloc (ce_s, stack, 32);

+

       get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
       lhsc.var = escaped_id;
       lhsc.offset = 0;
       lhsc.type = SCALAR;
       FOR_EACH_VEC_ELT (ce_s, tmpc, i, c)
 	process_constraint (new_constraint (lhsc, *c));
-      VEC_free(ce_s, heap, tmpc);

+      VEC_free(ce_s, stack, tmpc);

     }
 
   /* Regular functions return nonlocal memory.  */
   rhsc.var = nonlocal_id;
   rhsc.offset = 0;
   rhsc.type = SCALAR;
-  VEC_safe_push (ce_s, heap, *results, &rhsc);

+  VEC_safe_push (ce_s, stack, *results, &rhsc);

 }
 
 /* For non-IPA mode, generate constraints necessary for a call
@@ -3815,10 +3826,10 @@  handle_rhs_call (gimple stmt, VEC(ce_s,

    the LHS point to global and escaped variables.  */
 
 static void
-handle_lhs_call (gimple stmt, tree lhs, int flags, VEC(ce_s, heap) *rhsc,

+handle_lhs_call (gimple stmt, tree lhs, int flags, VEC(ce_s, stack) *rhsc,

 		 tree fndecl)
 {
-  VEC(ce_s, heap) *lhsc = NULL;

+  VEC(ce_s, stack) *lhsc = VEC_alloc (ce_s, stack, 32);

 
   get_constraint_for (lhs, &lhsc);
   /* If the store is to a global decl make sure to
@@ -3828,11 +3839,11 @@  handle_lhs_call (gimple stmt, tree lhs,

       && DECL_P (lhs)
       && is_global_var (lhs))
     {
-      struct constraint_expr tmpc;

+      ce_s tmpc;

       tmpc.var = escaped_id;
       tmpc.offset = 0;
       tmpc.type = SCALAR;
-      VEC_safe_push (ce_s, heap, lhsc, &tmpc);

+      VEC_safe_push (ce_s, stack, lhsc, &tmpc);

     }
 
   /* If the call returns an argument unmodified override the rhs
@@ -3842,17 +3853,17 @@  handle_lhs_call (gimple stmt, tree lhs,

       && (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt))
     {
       tree arg;
-      rhsc = NULL;

+      VEC(ce_s, stack) *rhsc2 = VEC_alloc (ce_s, stack, 32);

       arg = gimple_call_arg (stmt, flags & ERF_RETURN_ARG_MASK);
-      get_constraint_for (arg, &rhsc);

-      process_all_all_constraints (lhsc, rhsc);

-      VEC_free (ce_s, heap, rhsc);

+      get_constraint_for (arg, &rhsc2);

+      process_all_all_constraints (lhsc, rhsc2);

+      VEC_free (ce_s, stack, rhsc2);

     }
   else if (flags & ERF_NOALIAS)
     {
       varinfo_t vi;
-      struct constraint_expr tmpc;

-      rhsc = NULL;

+      ce_s tmpc;

+      VEC(ce_s, stack) *rhsc2 = VEC_alloc (ce_s, stack, 32);

       vi = make_heapvar ("HEAP");
       /* We delay marking allocated storage global until we know if
          it escapes.  */
@@ -3867,21 +3878,21 @@  handle_lhs_call (gimple stmt, tree lhs,

       tmpc.var = vi->id;
       tmpc.offset = 0;
       tmpc.type = ADDRESSOF;
-      VEC_safe_push (ce_s, heap, rhsc, &tmpc);

-      process_all_all_constraints (lhsc, rhsc);

-      VEC_free (ce_s, heap, rhsc);

+      VEC_safe_push (ce_s, stack, rhsc2, &tmpc);

+      process_all_all_constraints (lhsc, rhsc2);

+      VEC_free (ce_s, stack, rhsc2);

     }
   else
     process_all_all_constraints (lhsc, rhsc);
 
-  VEC_free (ce_s, heap, lhsc);

+  VEC_free (ce_s, stack, lhsc);

 }
 
 /* For non-IPA mode, generate constraints necessary for a call of a
    const function that returns a pointer in the statement STMT.  */
 
 static void
-handle_const_call (gimple stmt, VEC(ce_s, heap) **results)

+handle_const_call (gimple stmt, VEC(ce_s, stack) **results)

 {
   struct constraint_expr rhsc;
   unsigned int k;
@@ -3896,34 +3907,35 @@  handle_const_call (gimple stmt, VEC(ce_s

       rhsc.var = uses->id;
       rhsc.offset = 0;
       rhsc.type = SCALAR;
-      VEC_safe_push (ce_s, heap, *results, &rhsc);

+      VEC_safe_push (ce_s, stack, *results, &rhsc);

     }
 
   /* May return arguments.  */
   for (k = 0; k < gimple_call_num_args (stmt); ++k)
     {
       tree arg = gimple_call_arg (stmt, k);
-      VEC(ce_s, heap) *argc = NULL;

       unsigned i;
       struct constraint_expr *argp;
+      VEC(ce_s, stack) *argc = VEC_alloc (ce_s, stack, 32);

+

       get_constraint_for_rhs (arg, &argc);
       FOR_EACH_VEC_ELT (ce_s, argc, i, argp)
-	VEC_safe_push (ce_s, heap, *results, argp);

-      VEC_free(ce_s, heap, argc);

+	VEC_safe_push (ce_s, stack, *results, argp);

+      VEC_free(ce_s, stack, argc);

     }
 
   /* May return addresses of globals.  */
   rhsc.var = nonlocal_id;
   rhsc.offset = 0;
   rhsc.type = ADDRESSOF;
-  VEC_safe_push (ce_s, heap, *results, &rhsc);

+  VEC_safe_push (ce_s, stack, *results, &rhsc);

 }
 
 /* For non-IPA mode, generate constraints necessary for a call to a
    pure function in statement STMT.  */
 
 static void
-handle_pure_call (gimple stmt, VEC(ce_s, heap) **results)

+handle_pure_call (gimple stmt, VEC(ce_s, stack) **results)

 {
   struct constraint_expr rhsc;
   unsigned i;
@@ -3958,12 +3970,12 @@  handle_pure_call (gimple stmt, VEC(ce_s,

       rhsc.var = uses->id;
       rhsc.offset = 0;
       rhsc.type = SCALAR;
-      VEC_safe_push (ce_s, heap, *results, &rhsc);

+      VEC_safe_push (ce_s, stack, *results, &rhsc);

     }
   rhsc.var = nonlocal_id;
   rhsc.offset = 0;
   rhsc.type = SCALAR;
-  VEC_safe_push (ce_s, heap, *results, &rhsc);

+  VEC_safe_push (ce_s, stack, *results, &rhsc);

 }
 
 
@@ -4004,9 +4016,9 @@  static bool

 find_func_aliases_for_builtin_call (gimple t)
 {
   tree fndecl = gimple_call_fndecl (t);
-  VEC(ce_s, heap) *lhsc = NULL;

-  VEC(ce_s, heap) *rhsc = NULL;

   varinfo_t fi;
+  VEC(ce_s, stack) *lhsc = VEC_alloc (ce_s, stack, 32);

+  VEC(ce_s, stack) *rhsc = VEC_alloc (ce_s, stack, 32);

 
   if (fndecl != NULL_TREE
       && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
@@ -4059,16 +4071,17 @@  find_func_aliases_for_builtin_call (gimp

 	      else
 		get_constraint_for (dest, &rhsc);
 	      process_all_all_constraints (lhsc, rhsc);
-	      VEC_free (ce_s, heap, lhsc);

-	      VEC_free (ce_s, heap, rhsc);

+	      VEC_truncate (ce_s, lhsc, 0);

+	      VEC_truncate (ce_s, rhsc, 0);

 	    }
 	  get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
 	  get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
 	  do_deref (&lhsc);
 	  do_deref (&rhsc);
 	  process_all_all_constraints (lhsc, rhsc);
-	  VEC_free (ce_s, heap, lhsc);

-	  VEC_free (ce_s, heap, rhsc);

+

+	  VEC_free (ce_s, stack, lhsc);

+	  VEC_free (ce_s, stack, rhsc);

 	  return true;
 	}
       case BUILT_IN_MEMSET:
@@ -4085,8 +4098,8 @@  find_func_aliases_for_builtin_call (gimp

 	      get_constraint_for (res, &lhsc);
 	      get_constraint_for (dest, &rhsc);
 	      process_all_all_constraints (lhsc, rhsc);
-	      VEC_free (ce_s, heap, lhsc);

-	      VEC_free (ce_s, heap, rhsc);

+	      VEC_truncate (ce_s, lhsc, 0);

+	      VEC_truncate (ce_s, rhsc, 0);

 	    }
 	  get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
 	  do_deref (&lhsc);
@@ -4104,7 +4117,9 @@  find_func_aliases_for_builtin_call (gimp

 	  ac.offset = 0;
 	  FOR_EACH_VEC_ELT (ce_s, lhsc, i, lhsp)
 	      process_constraint (new_constraint (*lhsp, ac));
-	  VEC_free (ce_s, heap, lhsc);

+

+	  VEC_free (ce_s, stack, lhsc);

+	  VEC_free (ce_s, stack, rhsc);

 	  return true;
 	}
       case BUILT_IN_ASSUME_ALIGNED:
@@ -4116,8 +4131,8 @@  find_func_aliases_for_builtin_call (gimp

 	      get_constraint_for (res, &lhsc);
 	      get_constraint_for (dest, &rhsc);
 	      process_all_all_constraints (lhsc, rhsc);
-	      VEC_free (ce_s, heap, lhsc);

-	      VEC_free (ce_s, heap, rhsc);

+	      VEC_free (ce_s, stack, lhsc);

+	      VEC_free (ce_s, stack, rhsc);

 	    }
 	  return true;
 	}
@@ -4157,8 +4172,9 @@  find_func_aliases_for_builtin_call (gimp

 	    do_deref (&lhsc);
 	    do_deref (&rhsc);
 	    process_all_all_constraints (lhsc, rhsc);
-	    VEC_free (ce_s, heap, lhsc);

-	    VEC_free (ce_s, heap, rhsc);

+

+	    VEC_free (ce_s, stack, lhsc);

+	    VEC_free (ce_s, stack, rhsc);

 	    return true;
 	  }
 	break;
@@ -4182,7 +4198,7 @@  find_func_aliases_for_builtin_call (gimp

 		  get_constraint_for (frame, &rhsc);
 		  FOR_EACH_VEC_ELT (ce_s, rhsc, i, rhsp)
 		      process_constraint (new_constraint (lhs, *rhsp));
-		  VEC_free (ce_s, heap, rhsc);

+		  VEC_truncate (ce_s, rhsc, 0);

 
 		  /* Make the frame point to the function for
 		     the trampoline adjustment call.  */
@@ -4190,9 +4206,9 @@  find_func_aliases_for_builtin_call (gimp

 		  do_deref (&lhsc);
 		  get_constraint_for (nfunc, &rhsc);
 		  process_all_all_constraints (lhsc, rhsc);
-		  VEC_free (ce_s, heap, rhsc);

-		  VEC_free (ce_s, heap, lhsc);

 
+		  VEC_free (ce_s, stack, rhsc);

+		  VEC_free (ce_s, stack, lhsc);

 		  return true;
 		}
 	    }
@@ -4210,8 +4226,8 @@  find_func_aliases_for_builtin_call (gimp

 	      get_constraint_for (tramp, &rhsc);
 	      do_deref (&rhsc);
 	      process_all_all_constraints (lhsc, rhsc);
-	      VEC_free (ce_s, heap, rhsc);

-	      VEC_free (ce_s, heap, lhsc);

+	      VEC_free (ce_s, stack, rhsc);

+	      VEC_free (ce_s, stack, lhsc);

 	    }
 	  return true;
 	}
@@ -4233,8 +4249,8 @@  find_func_aliases_for_builtin_call (gimp

 	  do_deref (&lhsc);
 	  get_constraint_for (src, &rhsc);
 	  process_all_all_constraints (lhsc, rhsc);
-	  VEC_free (ce_s, heap, lhsc);

-	  VEC_free (ce_s, heap, rhsc);

+	  VEC_free (ce_s, stack, lhsc);

+	  VEC_free (ce_s, stack, rhsc);

 	  return true;
 	}
       CASE_BUILT_IN_TM_LOAD (1):
@@ -4255,8 +4271,8 @@  find_func_aliases_for_builtin_call (gimp

 	  get_constraint_for (addr, &rhsc);
 	  do_deref (&rhsc);
 	  process_all_all_constraints (lhsc, rhsc);
-	  VEC_free (ce_s, heap, lhsc);

-	  VEC_free (ce_s, heap, rhsc);

+	  VEC_free (ce_s, stack, lhsc);

+	  VEC_free (ce_s, stack, rhsc);

 	  return true;
 	}
       /* Variadic argument handling needs to be handled in IPA
@@ -4285,7 +4301,7 @@  find_func_aliases_for_builtin_call (gimp

 	    }
 	  FOR_EACH_VEC_ELT (ce_s, lhsc, i, lhsp)
 	    process_constraint (new_constraint (*lhsp, rhs));
-	  VEC_free (ce_s, heap, lhsc);

+	  VEC_free (ce_s, stack, lhsc);

 	  /* va_list is clobbered.  */
 	  make_constraint_to (get_call_clobber_vi (t)->id, valist);
 	  return true;
@@ -4328,9 +4344,9 @@  static void

 find_func_aliases_for_call (gimple t)
 {
   tree fndecl = gimple_call_fndecl (t);
-  VEC(ce_s, heap) *lhsc = NULL;

-  VEC(ce_s, heap) *rhsc = NULL;

   varinfo_t fi;
+  VEC(ce_s, stack) *lhsc = VEC_alloc (ce_s, stack, 32);

+  VEC(ce_s, stack) *rhsc = VEC_alloc (ce_s, stack, 32);

 
   if (fndecl != NULL_TREE
       && DECL_BUILT_IN (fndecl)
@@ -4341,7 +4357,6 @@  find_func_aliases_for_call (gimple t)

   if (!in_ipa_mode
       || (fndecl && !fi->is_fn_info))
     {
-      VEC(ce_s, heap) *rhsc = NULL;

       int flags = gimple_call_flags (t);
 
       /* Const functions can return their arguments and addresses
@@ -4360,7 +4375,6 @@  find_func_aliases_for_call (gimple t)

 	handle_rhs_call (t, &rhsc);
       if (gimple_call_lhs (t))
 	handle_lhs_call (t, gimple_call_lhs (t), flags, rhsc, fndecl);
-      VEC_free (ce_s, heap, rhsc);

     }
   else
     {
@@ -4398,11 +4412,11 @@  find_func_aliases_for_call (gimple t)

 	      && DECL_RESULT (fndecl)
 	      && DECL_BY_REFERENCE (DECL_RESULT (fndecl)))
 	    {
-	      VEC(ce_s, heap) *tem = NULL;

-	      VEC_safe_push (ce_s, heap, tem, &rhs);

+	      VEC(ce_s, stack) *tem = VEC_alloc (ce_s, stack, 32);

+	      VEC_safe_push (ce_s, stack, tem, &rhs);

 	      do_deref (&tem);
 	      rhs = VEC_index (ce_s, tem, 0);
-	      VEC_free(ce_s, heap, tem);

+	      VEC_free(ce_s, stack, tem);

 	    }
 	  FOR_EACH_VEC_ELT (ce_s, lhsc, j, lhsp)
 	    process_constraint (new_constraint (*lhsp, rhs));
@@ -4421,7 +4435,7 @@  find_func_aliases_for_call (gimple t)

 	  lhs = get_function_part_constraint (fi, fi_result);
 	  FOR_EACH_VEC_ELT (ce_s, rhsc, j, rhsp)
 	    process_constraint (new_constraint (lhs, *rhsp));
-	  VEC_free (ce_s, heap, rhsc);

+	  VEC_free (ce_s, stack, rhsc);

 	}
 
       /* If we use a static chain, pass it along.  */
@@ -4436,6 +4450,8 @@  find_func_aliases_for_call (gimple t)

 	    process_constraint (new_constraint (lhs, *rhsp));
 	}
     }
+  VEC_free (ce_s, stack, lhsc);

+  VEC_free (ce_s, stack, rhsc);

 }
 
 /* Walk statement T setting up aliasing constraints according to the
@@ -4447,10 +4463,10 @@  static void

 find_func_aliases (gimple origt)
 {
   gimple t = origt;
-  VEC(ce_s, heap) *lhsc = NULL;

-  VEC(ce_s, heap) *rhsc = NULL;

   struct constraint_expr *c;
   varinfo_t fi;
+  VEC(ce_s, stack) *lhsc = VEC_alloc (ce_s, stack, 32);

+  VEC(ce_s, stack) *rhsc = VEC_alloc (ce_s, stack, 32);

 
   /* Now build constraints expressions.  */
   if (gimple_code (t) == GIMPLE_PHI)
@@ -4534,18 +4550,19 @@  find_func_aliases (gimple origt)

 	  else
 	    {
 	      /* All other operations are merges.  */
-	      VEC (ce_s, heap) *tmp = NULL;

 	      struct constraint_expr *rhsp;
 	      unsigned i, j;
+	      VEC (ce_s, stack) *tmp = VEC_alloc (ce_s, stack, 32);

+

 	      get_constraint_for_rhs (gimple_assign_rhs1 (t), &rhsc);
 	      for (i = 2; i < gimple_num_ops (t); ++i)
 		{
 		  get_constraint_for_rhs (gimple_op (t, i), &tmp);
 		  FOR_EACH_VEC_ELT (ce_s, tmp, j, rhsp)
-		    VEC_safe_push (ce_s, heap, rhsc, rhsp);

+		    VEC_safe_push (ce_s, stack, rhsc, rhsp);

 		  VEC_truncate (ce_s, tmp, 0);
 		}
-	      VEC_free (ce_s, heap, tmp);

+	      VEC_free (ce_s, stack, tmp);

 	    }
 	  process_all_all_constraints (lhsc, rhsc);
 	}
@@ -4607,16 +4624,16 @@  find_func_aliases (gimple origt)

 	     any global memory.  */
 	  if (op)
 	    {
-	      VEC(ce_s, heap) *lhsc = NULL;

 	      struct constraint_expr rhsc, *lhsp;
 	      unsigned j;
+

 	      get_constraint_for (op, &lhsc);
 	      rhsc.var = nonlocal_id;
 	      rhsc.offset = 0;
 	      rhsc.type = SCALAR;
 	      FOR_EACH_VEC_ELT (ce_s, lhsc, j, lhsp)
 		process_constraint (new_constraint (*lhsp, rhsc));
-	      VEC_free (ce_s, heap, lhsc);

+	      VEC_truncate (ce_s, lhsc, 0);

 	    }
 	}
       for (i = 0; i < gimple_asm_ninputs (t); ++i)
@@ -4640,8 +4657,8 @@  find_func_aliases (gimple origt)

 	}
     }
 
-  VEC_free (ce_s, heap, rhsc);

-  VEC_free (ce_s, heap, lhsc);

+  VEC_free (ce_s, stack, rhsc);

+  VEC_free (ce_s, stack, lhsc);

 }
 
 
@@ -4651,14 +4668,15 @@  find_func_aliases (gimple origt)

 static void
 process_ipa_clobber (varinfo_t fi, tree ptr)
 {
-  VEC(ce_s, heap) *ptrc = NULL;

   struct constraint_expr *c, lhs;
   unsigned i;
+  VEC(ce_s, stack) *ptrc = VEC_alloc (ce_s, stack, 32);

+

   get_constraint_for_rhs (ptr, &ptrc);
   lhs = get_function_part_constraint (fi, fi_clobbers);
   FOR_EACH_VEC_ELT (ce_s, ptrc, i, c)
     process_constraint (new_constraint (lhs, *c));
-  VEC_free (ce_s, heap, ptrc);

+  VEC_free (ce_s, stack, ptrc);

 }
 
 /* Walk statement T setting up clobber and use constraints according to the
@@ -4669,9 +4687,9 @@  static void

 find_func_clobbers (gimple origt)
 {
   gimple t = origt;
-  VEC(ce_s, heap) *lhsc = NULL;

-  VEC(ce_s, heap) *rhsc = NULL;

   varinfo_t fi;
+  VEC(ce_s, stack) *lhsc = VEC_alloc (ce_s, stack, 32);

+  VEC(ce_s, stack) *rhsc = VEC_alloc (ce_s, stack, 32);

 
   /* Add constraints for clobbered/used in IPA mode.
      We are not interested in what automatic variables are clobbered
@@ -4703,13 +4721,15 @@  find_func_clobbers (gimple origt)

 		   && auto_var_in_fn_p
 		        (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), cfun->decl))))
 	{
-	  struct constraint_expr lhsc, *rhsp;

+	  struct constraint_expr lhsc_expr, *rhsp;

 	  unsigned i;
-	  lhsc = get_function_part_constraint (fi, fi_clobbers);

-	  get_constraint_for_address_of (lhs, &rhsc);

-	  FOR_EACH_VEC_ELT (ce_s, rhsc, i, rhsp)

-	    process_constraint (new_constraint (lhsc, *rhsp));

-	  VEC_free (ce_s, heap, rhsc);

+	  VEC(ce_s, stack) *rhsc2 = VEC_alloc (ce_s, stack, 32);

+

+	  lhsc_expr = get_function_part_constraint (fi, fi_clobbers);

+	  get_constraint_for_address_of (lhs, &rhsc2);

+	  FOR_EACH_VEC_ELT (ce_s, rhsc2, i, rhsp)

+	    process_constraint (new_constraint (lhsc_expr, *rhsp));

+	  VEC_free (ce_s, stack, rhsc2);

 	}
     }
 
@@ -4733,15 +4753,16 @@  find_func_clobbers (gimple origt)

 	{
 	  struct constraint_expr lhs, *rhsp;
 	  unsigned i;
+	  VEC(ce_s, stack) *rhsc2 = VEC_alloc (ce_s, stack, 32);

+

 	  lhs = get_function_part_constraint (fi, fi_uses);
-	  get_constraint_for_address_of (rhs, &rhsc);

-	  FOR_EACH_VEC_ELT (ce_s, rhsc, i, rhsp)

+	  get_constraint_for_address_of (rhs, &rhsc2);

+	  FOR_EACH_VEC_ELT (ce_s, rhsc2, i, rhsp)

 	    process_constraint (new_constraint (lhs, *rhsp));
-	  VEC_free (ce_s, heap, rhsc);

+	  VEC_free (ce_s, stack, rhsc2);

 	}
     }
-

-  if (is_gimple_call (t))

+  else if (is_gimple_call (t))

     {
       varinfo_t cfi = NULL;
       tree decl = gimple_call_fndecl (t);
@@ -4786,12 +4807,13 @@  find_func_clobbers (gimple origt)

 	      lhs = get_function_part_constraint (fi, fi_clobbers);
 	      FOR_EACH_VEC_ELT (ce_s, lhsc, i, lhsp)
 		process_constraint (new_constraint (lhs, *lhsp));
-	      VEC_free (ce_s, heap, lhsc);

 	      get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
 	      lhs = get_function_part_constraint (fi, fi_uses);
 	      FOR_EACH_VEC_ELT (ce_s, rhsc, i, rhsp)
 		process_constraint (new_constraint (lhs, *rhsp));
-	      VEC_free (ce_s, heap, rhsc);

+

+	      VEC_free (ce_s, stack, lhsc);

+	      VEC_free (ce_s, stack, rhsc);

 	      return;
 	    }
 	  /* The following function clobbers memory pointed to by
@@ -4806,7 +4828,7 @@  find_func_clobbers (gimple origt)

 	      lhs = get_function_part_constraint (fi, fi_clobbers);
 	      FOR_EACH_VEC_ELT (ce_s, lhsc, i, lhsp)
 		process_constraint (new_constraint (lhs, *lhsp));
-	      VEC_free (ce_s, heap, lhsc);

+	      VEC_free (ce_s, stack, lhsc);

 	      return;
 	    }
 	  /* The following functions clobber their second and third
@@ -4876,7 +4898,6 @@  find_func_clobbers (gimple origt)

 	  get_constraint_for_address_of (arg, &rhsc);
 	  FOR_EACH_VEC_ELT (ce_s, rhsc, j, rhsp)
 	    process_constraint (new_constraint (lhs, *rhsp));
-	  VEC_free (ce_s, heap, rhsc);

 	}
 
       /* Build constraints for propagating clobbers/uses along the
@@ -4889,6 +4910,7 @@  find_func_clobbers (gimple origt)

 				  anything_id);
 	  make_constraint_from (first_vi_for_offset (fi, fi_uses),
 				anything_id);
+	  VEC_free (ce_s, stack, rhsc);

 	  return;
 	}
 
@@ -4911,6 +4933,7 @@  find_func_clobbers (gimple origt)

 	  if ((vi = lookup_call_use_vi (t)) != NULL)
 	    make_copy_constraint (first_vi_for_offset (fi, fi_uses),
 				  vi->id);
+	  VEC_free (ce_s, stack, rhsc);

 	  return;
 	}
 
@@ -4937,7 +4960,7 @@  find_func_clobbers (gimple origt)

 			    anything_id);
     }
 
-  VEC_free (ce_s, heap, rhsc);

+  VEC_free (ce_s, stack, rhsc);

 }
 
 
@@ -5597,7 +5620,7 @@  create_variable_info_for (tree decl, con

 	  if (DECL_INITIAL (decl)
 	      && vnode->analyzed)
 	    {
-	      VEC (ce_s, heap) *rhsc = NULL;

+	      VEC (ce_s, stack) *rhsc = VEC_alloc (ce_s, stack, 32);

 	      struct constraint_expr lhs, *rhsp;
 	      unsigned i;
 	      get_constraint_for_rhs (DECL_INITIAL (decl), &rhsc);
@@ -5616,7 +5639,7 @@  create_variable_info_for (tree decl, con

 		  FOR_EACH_VEC_ELT (ce_s, rhsc, i, rhsp)
 		    process_constraint (new_constraint (lhs, *rhsp));
 		}
-	      VEC_free (ce_s, heap, rhsc);

+	      VEC_free (ce_s, stack, rhsc);

 	    }
 	}
     }

=== modified file 'gcc/vecir.h'
--- gcc/vecir.h	2010-05-15 19:02:11 +0000

+++ gcc/vecir.h	2012-08-18 16:43:02 +0000

@@ -28,6 +28,9 @@  along with GCC; see the file COPYING3.

 DEF_VEC_P(tree);
 DEF_VEC_ALLOC_P(tree,gc);
 DEF_VEC_ALLOC_P(tree,heap);
+DEF_VEC_ALLOC_P_STACK(tree);

+#define VEC_tree_stack_alloc(alloc) \

+  VEC_stack_alloc (tree, alloc)

 
 /* A varray of gimple statements.  */
 DEF_VEC_P(gimple);

=== modified file 'gcc/tree-ssa-sccvn.c'
--- gcc/tree-ssa-sccvn.c	2012-08-16 14:27:51 +0000

+++ gcc/tree-ssa-sccvn.c	2012-08-18 16:43:02 +0000

@@ -3644,8 +3650,8 @@  DEF_VEC_ALLOC_O(ssa_op_iter,heap);

 static bool
 extract_and_process_scc_for_name (tree name)
 {
-  VEC (tree, heap) *scc = NULL;

   tree x;
+  VEC (tree, stack) *scc = VEC_alloc (tree, stack, 16);

 
   /* Found an SCC, pop the components off the SCC stack and
      process them.  */
@@ -3654,7 +3660,7 @@  extract_and_process_scc_for_name (tree n

       x = VEC_pop (tree, sccstack);
 
       VN_INFO (x)->on_sccstack = false;
-      VEC_safe_push (tree, heap, scc, x);

+      VEC_safe_push (tree, stack, scc, x);

     } while (x != name);
 
   /* Bail out of SCCVN in case a SCC turns out to be incredibly large.  */
@@ -3678,7 +3684,7 @@  extract_and_process_scc_for_name (tree n

 
   process_scc (scc);
 
-  VEC_free (tree, heap, scc);

+  VEC_free (tree, stack, scc);

 
   return true;
 }
@@ -2474,7 +2479,7 @@  vn_phi_insert (gimple phi, tree result)

 /* Print set of components in strongly connected component SCC to OUT. */
 
 static void
-print_scc (FILE *out, VEC (tree, heap) *scc)

+print_scc (FILE *out, VEC (tree, stack) *scc)

 {
   tree var;
   unsigned int i;
@@ -3513,7 +3518,7 @@  compare_ops (const void *pa, const void

    array will give you the members in RPO order.  */
 
 static void
-sort_scc (VEC (tree, heap) *scc)

+sort_scc (VEC (tree, stack) *scc)

 {
   VEC_qsort (tree, scc, compare_ops);
 }
@@ -3564,7 +3569,7 @@  copy_reference (vn_reference_t oref, vn_

 /* Process a strongly connected component in the SSA graph.  */
 
 static void
-process_scc (VEC (tree, heap) *scc)

+process_scc (VEC (tree, stack) *scc)

 {
   tree var;
   unsigned int i;