The following fixes df-problems.c:4405 (df_md_alloc) -39759960:4741239668736.0% -40 520627: 0.6% 0 0 heap df-problems.c:225 (df_rd_alloc) -17948440:4741239668736.0% -40 284572: 0.3% 0 0 heap
you can sometimes see by properly accounting the "bitmap_move" operation it does. The patch below also fixes statistics for free_node to use tree_size properly (lto also frees STRING_CSTs) - that reduces the amount if ICEing in the testsuite when mem-stats are enabled but doesn't completely eliminate them - we've got some global destructors that appear to run out-of-order and crashing (just use valgrind on a mem-stat compiler - seems to happen with LTO only). The patch should also fix stat printing on hosts where long is only 32bits but pointers are larger (windows?). Bootstrapped on x86_64-unknown-linux-gnu, testing mightly successful. Will install soon. Richard. 2016-02-23 Richard Biener <rguent...@suse.de> * mem-stats.h (struct mem_usage): Use PRIu64 for printing size_t. * bitmap.h (struct bitmap_usage): Likewise. (bitmap_move): Declare. * bitmap.c (register_overhead): Take size_t argument. (bitmap_move): New function. * df-problems.c (df_rd_transfer_function): Use bitmap_move to properly account overhead. * tree.c (free_node): Use tree_size. Index: gcc/mem-stats.h =================================================================== *** gcc/mem-stats.h (revision 233620) --- gcc/mem-stats.h (working copy) *************** struct mem_usage *** 190,199 **** { char *location_string = loc->to_string (); ! fprintf (stderr, "%-48s %10li:%5.1f%%%10li%10li:%5.1f%%%10s\n", ! location_string, ! (long)m_allocated, get_percent (m_allocated, total.m_allocated), ! (long)m_peak, (long)m_times, get_percent (m_times, total.m_times), loc->m_ggc ? "ggc" : "heap"); free (location_string); --- 190,200 ---- { char *location_string = loc->to_string (); ! fprintf (stderr, "%-48s %10" PRIu64 ":%5.1f%%" ! "%10" PRIu64 "%10" PRIu64 ":%5.1f%%%10s\n", ! location_string, (uint64_t)m_allocated, ! get_percent (m_allocated, total.m_allocated), ! (uint64_t)m_peak, (uint64_t)m_times, get_percent (m_times, total.m_times), loc->m_ggc ? "ggc" : "heap"); free (location_string); *************** struct mem_usage *** 204,211 **** dump_footer () const { print_dash_line (); ! fprintf (stderr, "%s%54li%27li\n", "Total", (long)m_allocated, ! (long)m_times); print_dash_line (); } --- 205,212 ---- dump_footer () const { print_dash_line (); ! fprintf (stderr, "%s%54" PRIu64 "%27" PRIu64 "\n", "Total", ! (uint64_t)m_allocated, (uint64_t)m_times); print_dash_line (); } Index: gcc/bitmap.h =================================================================== *** gcc/bitmap.h (revision 233620) --- gcc/bitmap.h (working copy) *************** struct bitmap_usage: public mem_usage *** 157,168 **** { char *location_string = loc->to_string (); ! fprintf (stderr, "%-48s %10li:%5.1f%%%10li%10li:%5.1f%%%12li%12li%10s\n", ! location_string, ! (long)m_allocated, get_percent (m_allocated, total.m_allocated), ! (long)m_peak, (long)m_times, get_percent (m_times, total.m_times), ! (long)m_nsearches, (long)m_search_iter, loc->m_ggc ? "ggc" : "heap"); free (location_string); --- 157,170 ---- { char *location_string = loc->to_string (); ! fprintf (stderr, "%-48s %10" PRIu64 ":%5.1f%%" ! "%10" PRIu64 "%10" PRIu64 ":%5.1f%%" ! "%12" PRIu64 "%12" PRIu64 "%10s\n", ! location_string, (uint64_t)m_allocated, ! get_percent (m_allocated, total.m_allocated), ! (uint64_t)m_peak, (uint64_t)m_times, get_percent (m_times, total.m_times), ! m_nsearches, m_search_iter, loc->m_ggc ? "ggc" : "heap"); free (location_string); *************** extern void bitmap_clear (bitmap); *** 253,258 **** --- 255,263 ---- /* Copy a bitmap to another bitmap. */ extern void bitmap_copy (bitmap, const_bitmap); + /* Move a bitmap to another bitmap. */ + extern void bitmap_move (bitmap, bitmap); + /* True if two bitmaps are identical. */ extern bool bitmap_equal_p (const_bitmap, const_bitmap); Index: gcc/bitmap.c =================================================================== *** gcc/bitmap.c (revision 233620) --- gcc/bitmap.c (working copy) *************** bitmap_register (bitmap b MEM_STAT_DECL) *** 35,41 **** /* Account the overhead. */ static void ! register_overhead (bitmap b, int amount) { if (bitmap_mem_desc.contains_descriptor_for_instance (b)) bitmap_mem_desc.register_instance_overhead (amount, b); --- 35,41 ---- /* Account the overhead. */ static void ! register_overhead (bitmap b, size_t amount) { if (bitmap_mem_desc.contains_descriptor_for_instance (b)) bitmap_mem_desc.register_instance_overhead (amount, b); *************** bitmap_copy (bitmap to, const_bitmap fro *** 468,473 **** --- 468,494 ---- to_ptr = to_elt; } } + + /* Move a bitmap to another bitmap. */ + + void + bitmap_move (bitmap to, bitmap from) + { + gcc_assert (to->obstack == from->obstack); + + bitmap_clear (to); + + *to = *from; + + if (GATHER_STATISTICS) + { + size_t sz = 0; + for (bitmap_element *e = to->first; e; e = e->next) + sz += sizeof (bitmap_element); + register_overhead (to, sz); + register_overhead (from, -sz); + } + } /* Find a bitmap element that would hold a bitmap's bit. Update the `current' field even if we can't find an element that Index: gcc/df-problems.c =================================================================== *** gcc/df-problems.c (revision 233620) --- gcc/df-problems.c (working copy) *************** df_rd_transfer_function (int bb_index) *** 517,526 **** bitmap_ior_into (&tmp, gen); changed = !bitmap_equal_p (&tmp, out); if (changed) ! { ! bitmap_clear (out); ! bb_info->out = tmp; ! } else bitmap_clear (&tmp); } --- 517,523 ---- bitmap_ior_into (&tmp, gen); changed = !bitmap_equal_p (&tmp, out); if (changed) ! bitmap_move (out, &tmp); else bitmap_clear (&tmp); } Index: gcc/tree.c =================================================================== *** gcc/tree.c (revision 233597) --- gcc/tree.c (working copy) *************** free_node (tree node) *** 1114,1120 **** { tree_code_counts[(int) TREE_CODE (node)]--; tree_node_counts[(int) t_kind]--; ! tree_node_sizes[(int) t_kind] -= tree_code_size (TREE_CODE (node)); } if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR)) vec_free (CONSTRUCTOR_ELTS (node)); --- 1114,1120 ---- { tree_code_counts[(int) TREE_CODE (node)]--; tree_node_counts[(int) t_kind]--; ! tree_node_sizes[(int) t_kind] -= tree_size (node); } if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR)) vec_free (CONSTRUCTOR_ELTS (node));