This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Memory statistics before and after IPA
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 10 Dec 2006 14:20:01 +0100
- Subject: Memory statistics before and after IPA
HI,
the IPA merge (I hope to proceed this week ;) will definitly considerably
change GCC memory behaviour just after parsing and lowering all the functions
(we will have all functions in SSA instead of high gimple). In some tests I did
for GCC summit paper this effect was from large part undoable by performing
early optimizations that makes the function bodies smaller again, but still I
guess we will run into some interesting testcases especially if we decide to
represent aliasing somehow.
This patch adds two options: -fpre-ipa-mem-report and -fpost-ipa-mem-report
that dumps the memory statistics before and after IPA passes. The statistics
are also changed to be sorted by still reachable memory rather than overall
garbage productions so the major offenders in our memory report can be identified
easilly.
I hope to get those scores down by some cleanups, ale process of tupleification
can be a lot better seen here.
Bootstrapped/regtested i686-linux.
OK?
:ADDPATCH middle-end:
* 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.
Index: toplev.c
===================================================================
*** toplev.c (revision 119660)
--- toplev.c (working copy)
*************** lang_dependent_init (const char *name)
*** 2014,2019 ****
--- 2014,2032 ----
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
*************** finalize (void)
*** 2042,2057 ****
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 ();
! }
/* Free up memory for the benefit of leak detectors. */
free_reg_info ();
--- 2055,2061 ----
finish_optimization_passes ();
if (mem_report)
! dump_memory_report (true);
/* Free up memory for the benefit of leak detectors. */
free_reg_info ();
Index: toplev.h
===================================================================
*** toplev.h (revision 119660)
--- toplev.h (working copy)
*************** extern void check_global_declarations (t
*** 100,105 ****
--- 100,107 ----
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;
Index: ggc.h
===================================================================
*** ggc.h (revision 119660)
--- ggc.h (working copy)
*************** extern void ggc_record_overhead (size_t,
*** 222,228 ****
extern void ggc_free_overhead (void *);
extern void ggc_prune_overhead_list (void);
! extern void dump_ggc_loc_statistics (void);
/* Type-safe, C++-friendly versions of ggc_alloc() and gcc_calloc(). */
#define GGC_NEW(T) ((T *) ggc_alloc (sizeof (T)))
--- 222,228 ----
extern void ggc_free_overhead (void *);
extern void ggc_prune_overhead_list (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)))
Index: ggc-common.c
===================================================================
*** ggc-common.c (revision 119660)
--- ggc-common.c (working copy)
*************** ggc_free_overhead (void *ptr)
*** 919,930 ****
/* 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));
}
/* Collect array of the descriptors from hashtable. */
--- 919,949 ----
/* 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;
+ 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. */
*************** add_statistics (void **slot, void *b)
*** 941,947 ****
/* Dump per-site memory statistics. */
#endif
void
! dump_ggc_loc_statistics (void)
{
#ifdef GATHER_STATISTICS
int nentries = 0;
--- 960,966 ----
/* Dump per-site memory statistics. */
#endif
void
! dump_ggc_loc_statistics (bool final ATTRIBUTE_UNUSED)
{
#ifdef GATHER_STATISTICS
int nentries = 0;
*************** dump_ggc_loc_statistics (void)
*** 958,964 ****
"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);
for (i = 0; i < nentries; i++)
{
struct loc_descriptor *d = loc_array[i];
--- 977,984 ----
"source location", "Garbage", "Freed", "Leak", "Overhead", "Times");
fprintf (stderr, "-------------------------------------------------------\n");
htab_traverse (loc_hash, add_statistics, &nentries);
! 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];
Index: common.opt
===================================================================
*** common.opt (revision 119660)
--- common.opt (working copy)
*************** foptimize-sibling-calls
*** 644,649 ****
--- 644,657 ----
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
Index: varray.c
===================================================================
*** varray.c (revision 119660)
--- varray.c (working copy)
*************** dump_varray_statistics (void)
*** 246,259 ****
#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");
#endif
}
--- 246,262 ----
#ifdef GATHER_STATISTICS
struct output_info info;
! 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
}
Index: doc/invoke.texi
===================================================================
*** doc/invoke.texi (revision 119660)
--- doc/invoke.texi (working copy)
*************** Objective-C and Objective-C++ Dialects}.
*** 288,294 ****
-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
-frandom-seed=@var{string} -fsched-verbose=@var{n} @gol
-ftest-coverage -ftime-report -fvar-tracking @gol
-g -g@var{level} -gcoff -gdwarf-2 @gol
--- 288,294 ----
-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 -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
*************** pass when it finishes.
*** 3710,3715 ****
--- 3710,3722 ----
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