diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c8847eb8031..6f49f862c32 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2006-12-23 Jan Hubicka + + * toplev.c (dump_memory_report): Break out from... + (finalize): Here. + * toplev.h (dump_memory_report): Declare. + (cmp_statistic): Rename to ... + (final_cmp_statistic): ... this one + (cmp_statistic): New. + (dump_ggc_loc_staitsitcs): New FINAL parpameter. + * common.opt (-fpre-ipa-mem-report, -fpost-ipa-mem-report): Declare. + * varray.c (dump_varray_staitiscs): Do not segfault when no varray was + allocated so far. + * cgraphunit.c (cgraph_optimize): Dump the memory reports. + 2006-12-22 Mike Stump * config/rs6000/t-darwin (DARWIN_EXTRA_CRT_BUILD_CFLAGS): Add diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 37e1ac88995..cb2f824fb70 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1394,6 +1394,11 @@ cgraph_optimize (void) varpool_analyze_pending_decls (); timevar_push (TV_CGRAPHOPT); + if (pre_ipa_mem_report) + { + fprintf (stderr, "Memory consumption before IPA\n"); + dump_memory_report (false); + } if (!quiet_flag) fprintf (stderr, "Performing interprocedural optimizations\n"); @@ -1419,6 +1424,11 @@ cgraph_optimize (void) dump_cgraph (cgraph_dump_file); dump_varpool (cgraph_dump_file); } + if (post_ipa_mem_report) + { + fprintf (stderr, "Memory consumption before IPA\n"); + dump_memory_report (false); + } timevar_pop (TV_CGRAPHOPT); /* Output everything. */ diff --git a/gcc/common.opt b/gcc/common.opt index 7ec6f4723cd..7ad2f1dbacb 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -644,6 +644,14 @@ foptimize-sibling-calls Common Report Var(flag_optimize_sibling_calls) Optimize sibling and tail recursive calls +fpre-ipa-mem-report +Common Report Var(pre_ipa_mem_report) +Report on memory allocation before interprocedural optimization + +fpost-ipa-mem-report +Common Report Var(post_ipa_mem_report) +Report on memory allocation before interprocedural optimization + fpack-struct Common Report Var(flag_pack_struct) Pack structure members together without holes diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index b65280bfce0..63f22f2fbb6 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -290,7 +290,7 @@ Objective-C and Objective-C++ Dialects}. -fdump-tree-storeccp@r{[}-@var{n}@r{]} @gol -feliminate-dwarf2-dups -feliminate-unused-debug-types @gol -feliminate-unused-debug-symbols -femit-class-debug-always @gol --fmem-report -fprofile-arcs @gol +-fmem-report -fpre-ipa-mem-report -fpost-ipa-mem-report -fprofile-arcs @gol -frandom-seed=@var{string} -fsched-verbose=@var{n} @gol -ftest-coverage -ftime-report -fvar-tracking @gol -g -g@var{level} -gcoff -gdwarf-2 @gol @@ -3728,6 +3728,13 @@ pass when it finishes. Makes the compiler print some statistics about permanent memory allocation when it finishes. +@item -fpre-ipa-mem-report +@opindex fpre-ipa-mem-report +@item -fpost-ipa-mem-report +@opindex fpost-ipa-mem-report +Makes the compiler print some statistics about permanent memory +allocation before or after interprocedural optimization. + @item -fprofile-arcs @opindex fprofile-arcs Add code so that program flow @dfn{arcs} are instrumented. During diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index 3cafc770efd..7341e968edc 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -917,14 +917,33 @@ ggc_free_overhead (void *ptr) free (p); } +/* Helper for qsort; sort descriptors by amount of memory consumed. */ +static int +final_cmp_statistic (const void *loc1, const void *loc2) +{ + struct loc_descriptor *l1 = *(struct loc_descriptor **) loc1; + struct loc_descriptor *l2 = *(struct loc_descriptor **) loc2; + long diff; + diff = ((long)(l1->allocated + l1->overhead - l1->freed) - + (l2->allocated + l2->overhead - l2->freed)); + return diff > 0 ? 1 : diff < 0 ? -1 : 0; +} + /* Helper for qsort; sort descriptors by amount of memory consumed. */ static int cmp_statistic (const void *loc1, const void *loc2) { struct loc_descriptor *l1 = *(struct loc_descriptor **) loc1; struct loc_descriptor *l2 = *(struct loc_descriptor **) loc2; - return ((l1->allocated + l1->overhead - l1->freed) - - (l2->allocated + l2->overhead - l2->freed)); + long diff; + + diff = ((long)(l1->allocated + l1->overhead - l1->freed - l1->collected) - + (l2->allocated + l2->overhead - l2->freed - l2->collected)); + if (diff) + return diff > 0 ? 1 : diff < 0 ? -1 : 0; + diff = ((long)(l1->allocated + l1->overhead - l1->freed) - + (l2->allocated + l2->overhead - l2->freed)); + return diff > 0 ? 1 : diff < 0 ? -1 : 0; } /* Collect array of the descriptors from hashtable. */ @@ -941,7 +960,7 @@ add_statistics (void **slot, void *b) /* Dump per-site memory statistics. */ #endif void -dump_ggc_loc_statistics (void) +dump_ggc_loc_statistics (bool final ATTRIBUTE_UNUSED) { #ifdef GATHER_STATISTICS int nentries = 0; @@ -958,7 +977,8 @@ dump_ggc_loc_statistics (void) "source location", "Garbage", "Freed", "Leak", "Overhead", "Times"); fprintf (stderr, "-------------------------------------------------------\n"); htab_traverse (loc_hash, add_statistics, &nentries); - qsort (loc_array, nentries, sizeof (*loc_array), cmp_statistic); + qsort (loc_array, nentries, sizeof (*loc_array), + final ? final_cmp_statistic : cmp_statistic); for (i = 0; i < nentries; i++) { struct loc_descriptor *d = loc_array[i]; diff --git a/gcc/ggc.h b/gcc/ggc.h index d6e2303de81..3ff04567ab0 100644 --- a/gcc/ggc.h +++ b/gcc/ggc.h @@ -222,7 +222,7 @@ extern void ggc_record_overhead (size_t, size_t, void * MEM_STAT_DECL); extern void ggc_free_overhead (void *); extern void ggc_prune_overhead_list (void); -extern void dump_ggc_loc_statistics (void); +extern void dump_ggc_loc_statistics (bool); /* Type-safe, C++-friendly versions of ggc_alloc() and gcc_calloc(). */ #define GGC_NEW(T) ((T *) ggc_alloc (sizeof (T))) diff --git a/gcc/toplev.c b/gcc/toplev.c index d83da13b4a5..bcefdc091f1 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2012,6 +2012,19 @@ lang_dependent_init (const char *name) return 1; } +void +dump_memory_report (bool final) +{ + ggc_print_statistics (); + stringpool_statistics (); + dump_tree_statistics (); + dump_rtx_statistics (); + dump_varray_statistics (); + dump_alloc_pool_statistics (); + dump_bitmap_statistics (); + dump_ggc_loc_statistics (final); +} + /* Clean up: close opened files, etc. */ static void @@ -2040,16 +2053,7 @@ finalize (void) finish_optimization_passes (); if (mem_report) - { - ggc_print_statistics (); - stringpool_statistics (); - dump_tree_statistics (); - dump_rtx_statistics (); - dump_varray_statistics (); - dump_alloc_pool_statistics (); - dump_bitmap_statistics (); - dump_ggc_loc_statistics (); - } + dump_memory_report (true); /* Free up memory for the benefit of leak detectors. */ free_reg_info (); diff --git a/gcc/toplev.h b/gcc/toplev.h index c935f7ee797..a23d52c8983 100644 --- a/gcc/toplev.h +++ b/gcc/toplev.h @@ -100,6 +100,8 @@ extern void check_global_declarations (tree *, int); extern void emit_debug_global_declarations (tree *, int); extern void write_global_declarations (void); +extern void dump_memory_report (bool); + /* A unique local time stamp, might be zero if none is available. */ extern unsigned local_tick; diff --git a/gcc/varray.c b/gcc/varray.c index 9900f9e1be0..2044629eee0 100644 --- a/gcc/varray.c +++ b/gcc/varray.c @@ -246,14 +246,17 @@ dump_varray_statistics (void) #ifdef GATHER_STATISTICS struct output_info info; - fprintf (stderr, "\nVARRAY Kind Count Bytes Resized copied\n"); - fprintf (stderr, "-------------------------------------------------------\n"); - info.count = 0; - info.size = 0; - htab_traverse (varray_hash, print_statistics, &info); - fprintf (stderr, "-------------------------------------------------------\n"); - fprintf (stderr, "%-20s %7d %10d\n", - "Total", info.count, info.size); - fprintf (stderr, "-------------------------------------------------------\n"); + if (varray_hash) + { + fprintf (stderr, "\nVARRAY Kind Count Bytes Resized copied\n"); + fprintf (stderr, "-------------------------------------------------------\n"); + info.count = 0; + info.size = 0; + htab_traverse (varray_hash, print_statistics, &info); + fprintf (stderr, "-------------------------------------------------------\n"); + fprintf (stderr, "%-20s %7d %10d\n", + "Total", info.count, info.size); + fprintf (stderr, "-------------------------------------------------------\n"); + } #endif }