=== modified file 'gcc/tree-ssa-sccvn.c'
@@ -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);