2012-08-18 Dimitrios Apostolou * gcc/tree-ssa-sccvn.c (struct vn_tables_s): Add obstack_start to mark the first allocated object on the obstack. (process_scc, allocate_vn_table): Use it. (init_scc_vn): Don't truncate shared_lookup_references vector. (prealloc_ref_ops_vec): New static vector. (create_reference_ops_from_ref, create_reference_ops_from_call): Use it instead of locally allocated one. (free_scc_vn): Truncate vectors to 0, but keep them most 16 slots long. === 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 @@ -105,6 +105,7 @@ typedef struct vn_tables_s htab_t phis; htab_t references; struct obstack nary_obstack; + long *obstack_start; alloc_pool phis_pool; alloc_pool references_pool; } *vn_tables_t; @@ -973,16 +974,21 @@ copy_reference_ops_from_call (gimple cal } } +/* Preallocated vector with sufficient space - see free_scc_vn(). Helps to + avoid reallocations and space, since when we VEC_copy() it, only its exact + length is duplicated. */ + +static VEC(vn_reference_op_s, heap) *prealloc_ref_ops_vec; + /* Create a vector of vn_reference_op_s structures from REF, a - REFERENCE_CLASS_P tree. The vector is not shared. */ + REFERENCE_CLASS_P tree. The vector is not shared. */ static VEC(vn_reference_op_s, heap) * create_reference_ops_from_ref (tree ref) { - VEC (vn_reference_op_s, heap) *result = NULL; - - copy_reference_ops_from_ref (ref, &result); - return result; + VEC_truncate (vn_reference_op_s, prealloc_ref_ops_vec, 0); + copy_reference_ops_from_ref (ref, &prealloc_ref_ops_vec); + return VEC_copy (vn_reference_op_s, heap, prealloc_ref_ops_vec); } /* Create a vector of vn_reference_op_s structures from CALL, a @@ -991,10 +997,9 @@ create_reference_ops_from_ref (tree ref) static VEC(vn_reference_op_s, heap) * create_reference_ops_from_call (gimple call) { - VEC (vn_reference_op_s, heap) *result = NULL; - - copy_reference_ops_from_call (call, &result); - return result; + VEC_truncate (vn_reference_op_s, prealloc_ref_ops_vec, 0); + copy_reference_ops_from_call (call, &prealloc_ref_ops_vec); + return VEC_copy (vn_reference_op_s, heap, prealloc_ref_ops_vec); } /* Fold *& at position *I_P in a vn_reference_op_s vector *OPS. Updates @@ -3610,8 +3615,9 @@ process_scc (VEC (tree, heap) *scc) htab_empty (optimistic_info->nary); htab_empty (optimistic_info->phis); htab_empty (optimistic_info->references); - obstack_free (&optimistic_info->nary_obstack, NULL); - gcc_obstack_init (&optimistic_info->nary_obstack); + /* Quick way to empty the obstack but keep it ready for reuse. */ + obstack_free (&optimistic_info->nary_obstack, + optimistic_info->obstack_start); empty_alloc_pool (optimistic_info->phis_pool); empty_alloc_pool (optimistic_info->references_pool); FOR_EACH_VEC_ELT (tree, scc, i, var) @@ -3796,6 +3802,7 @@ allocate_vn_table (vn_tables_t table) free_reference); gcc_obstack_init (&table->nary_obstack); + table->obstack_start = XOBNEW (&table->nary_obstack, long); table->phis_pool = create_alloc_pool ("VN phis", sizeof (struct vn_phi_s), 30); @@ -3842,7 +3849,6 @@ init_scc_vn (void) gcc_obstack_init (&vn_ssa_aux_obstack); shared_lookup_phiargs = NULL; - shared_lookup_references = NULL; rpo_numbers = XNEWVEC (int, last_basic_block); rpo_numbers_temp = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS); pre_and_rev_post_order_compute (NULL, rpo_numbers_temp, false); @@ -3887,9 +3893,19 @@ free_scc_vn (void) htab_delete (constant_to_value_id); BITMAP_FREE (constant_value_ids); VEC_free (tree, heap, shared_lookup_phiargs); - VEC_free (vn_reference_op_s, heap, shared_lookup_references); XDELETEVEC (rpo_numbers); + /* Keep the shared_lookup_references and prealloc_ref_ops_vec vectors with + at most 16 slots. */ + VEC_truncate (vn_reference_op_s, shared_lookup_references, 0); + if (VEC_space (vn_reference_op_s, shared_lookup_references, 17)) + VEC_reserve_exact (vn_reference_op_s, heap, + shared_lookup_references, 16); + VEC_truncate (vn_reference_op_s, prealloc_ref_ops_vec, 0); + if (VEC_space (vn_reference_op_s, prealloc_ref_ops_vec, 17)) + VEC_reserve_exact (vn_reference_op_s, heap, + prealloc_ref_ops_vec, 16); + for (i = 0; i < num_ssa_names; i++) { tree name = ssa_name (i);