This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]