2012-08-19 Dimitrios Apostolou <ji...@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 <ji...@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. === 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;