diff mbox

more malloc mitigation

Message ID alpine.LNX.2.02.1208182201510.20463@localhost.localdomain
State New
Headers show

Commit Message

Dimitrios Apostolou Aug. 18, 2012, 7:10 p.m. UTC
Hi,

2012-08-18  Dimitrios Apostolou  <jimis@gmx.net>

 	* 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.


I'd have used a stack vector for create_reference_ops_from_{ref,call} 
instead of a static one on the heap, but the functions return heap 
vectors. Can I just cast a stack vector to a heap one?

Also is it acceptable to leak 4K  because of never freeing the whole 
obstack?

Tested on x86 with old snapshot, will post update soon after testing with 
more recent one.


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

	* 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.
diff mbox

Patch

=== 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);