Hi! On larger testcases, we leak megabytes of memory since the vec.h changes, where edge_var_map_vector has been changed from a VEC(edge_var_map, heap) * into the space efficient vector, but is missing freeing of the pointed memory (i.e. release ()), and additionally it isn't very space and compile time efficient to malloc (well, new) vec<edge_var_map> objects, because those are just pointer sized objects which we can put directly into the pointer map slot.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2013-02-26 Jakub Jelinek <ja...@redhat.com> PR middle-end/56461 * tree-flow.h (edge_var_map_vector): Change into va_heap, vl_embed vector. * tree-ssa.c (redirect_edge_var_map_add): Use vec_safe_reserve and vec_safe_push, always update *slot. (redirect_edge_var_map_clear): Use vec_free. (redirect_edge_var_map_dup): Use vec_safe_copy and vec_safe_reserve. (free_var_map_entry): Use vec_free. * tree-cfgcleanup.c (remove_forwarder_block_with_phi): Use FOR_EACH_VEC_SAFE_ELT instead of FOR_EACH_VEC_ELT. --- gcc/tree-flow.h.jj 2013-02-13 21:47:17.000000000 +0100 +++ gcc/tree-flow.h 2013-02-26 16:19:29.567822673 +0100 @@ -481,7 +481,7 @@ typedef struct _edge_var_map edge_var_ma /* A vector of var maps. */ -typedef vec<edge_var_map> edge_var_map_vector; +typedef vec<edge_var_map, va_heap, vl_embed> edge_var_map_vector; extern void init_tree_ssa (struct function *); extern void redirect_edge_var_map_add (edge, tree, tree, source_location); --- gcc/tree-ssa.c.jj 2013-02-12 17:27:48.000000000 +0100 +++ gcc/tree-ssa.c 2013-02-26 16:33:19.345295876 +0100 @@ -59,16 +59,13 @@ redirect_edge_var_map_add (edge e, tree slot = pointer_map_insert (edge_var_maps, e); head = (edge_var_map_vector *) *slot; if (!head) - { - head = new edge_var_map_vector; - head->create (5); - *slot = head; - } + vec_safe_reserve (head, 5); new_node.def = def; new_node.result = result; new_node.locus = locus; - head->safe_push (new_node); + vec_safe_push (head, new_node); + *slot = head; } @@ -88,7 +85,7 @@ redirect_edge_var_map_clear (edge e) if (slot) { head = (edge_var_map_vector *) *slot; - delete head; + vec_free (head); *slot = NULL; } } @@ -115,11 +112,11 @@ redirect_edge_var_map_dup (edge newe, ed return; head = (edge_var_map_vector *) *old_slot; - edge_var_map_vector *new_head = new edge_var_map_vector; + edge_var_map_vector *new_head = NULL; if (head) - *new_head = head->copy (); + new_head = vec_safe_copy (head); else - new_head->create (5); + vec_safe_reserve (new_head, 5); *new_slot = new_head; } @@ -151,7 +148,7 @@ free_var_map_entry (const void *key ATTR void *data ATTRIBUTE_UNUSED) { edge_var_map_vector *head = (edge_var_map_vector *) *value; - delete head; + vec_free (head); return true; } --- gcc/tree-cfgcleanup.c.jj 2013-02-12 11:23:37.000000000 +0100 +++ gcc/tree-cfgcleanup.c 2013-02-26 16:36:17.671315288 +0100 @@ -822,7 +822,7 @@ remove_forwarder_block_with_phi (basic_b redirection, replace it with the PHI argument that used to be on E. */ head = redirect_edge_var_map_vector (e); - FOR_EACH_VEC_ELT (*head, i, vm) + FOR_EACH_VEC_SAFE_ELT (head, i, vm) { tree old_arg = redirect_edge_var_map_result (vm); tree new_arg = redirect_edge_var_map_def (vm); Jakub