[RFC/RFA?] Per call memory garbage statistics

Jan Hubicka jh@suse.cz
Wed Jan 21 19:47:00 GMT 2004


Hi,
this is the per-call memory statistics patch I was playing around last two
days.  It looks like it is quite usefull as it shown quite many problems
already.  The output looks (in my current tree) like this:
source location                                                   Times  Allocated   Overhead
-------------------------------------------------------

[snip]

stmt.c:2389 (expand_end_stmt_expr)                                33128     662560          0:0.218%
cp/lex.c:818 (cxx_make_type)                                       5236     565488     104720:0.221%
tree.c:2540 (build_nt)                                            31785     688472          0:0.227%
cp/decl.c:540 (poplevel)                                          18230     729200          0:0.240%
cgraph.c:157 (create_edge)                                        37900     758000          0:0.250%
rtl.c:158 (rtvec_alloc)                                           61915     769988       1288:0.254%
tree.c:391 (copy_list)                                             7837     832844          0:0.274%
cgraph.c:113 (cgraph_node)                                         6155     664740     172340:0.276%
cp/decl.c:10519 (save_function_data)                               7036     759888     112576:0.287%
tree.c:387 (copy_list)                                             8219     880964          0:0.290%
emit-rtl.c:316 (get_mem_attrs)                                    44805     896100          0:0.295%
cp/name-lookup.c:4699 (maybe_push_to_top_level)                    7726     834408      61808:0.295%
convert.c:371 (convert_to_integer)                                45763     915260          0:0.301%
tree.c:3645 (build_pointer_type_for_mode)                          7241     782028     144820:0.305%
stringpool.c:70 (alloc_node)                                      14308     915712      57232:0.320%
cp/tree.c:252 (build_local_temp)                                   9059     978372          0:0.322%
cp/decl.c:10239 (start_function)                                   9156     988848          0:0.326%
genrtl.c:688 (gen_rtx_fmt_u00)                                    62462     999392          0:0.329%
cp/call.c:2505 (build_user_type_conversion_1)                     51146    1022920          0:0.337%
cp/call.c:2499 (build_user_type_conversion_1)                     51146    1022920          0:0.337%
genrtl.c:236 (gen_rtx_fmt_e)                                     131307    1050456          0:0.346%
tree.c:2943 (build_type_copy)                                      8368     903744     167360:0.353%
tree-inline.c:1367 (expand_call_inline)                           54498    1089960          0:0.359%
emit-rtl.c:367 (get_reg_attrs)                                    91169    1094028          0:0.360%
cp/lex.c:810 (copy_type)                                           8629     931932     172580:0.364%
stmt.c:3451 (expand_start_bindings_and_block)                     56531    1130620          0:0.372%
cp/decl.c:11188 (cxx_push_function_context)                        9158     989064     146528:0.374%
cp/lex.c:756 (cxx_dup_lang_specific_decl)                         29291    1168644          0:0.385%
stmt.c:2344 (expand_start_stmt_expr)                              33128    1060096     132512:0.393%
cp/pt.c:9288 (try_class_unification)                              52677    1212648      18352:0.405%
except.c:463 (init_eh_for_function)                                9158     989064     256424:0.410%
cp/name-lookup.c:4178 (arg_assoc_class)                           64671    1293420          0:0.426%
cp/tree.c:912 (ovl_cons)                                          85443    1367088          0:0.450%
cp/call.c:2527 (build_user_type_conversion_1)                     68972    1379440          0:0.454%
tree.c:2606 (build_expr_wfl)                                      41763    1336416     167052:0.495%
cp/parser.c:356 (cp_lexer_new_from_tokens)                         2401    1205708     364476:0.517%
cp/parser.c:145 (cp_token_cache_push_token)                        3193    1634816      12772:0.543%
tree.c:408 (build_int_2_wide)                                     83583    1671660          0:0.551%
cp/lex.c:700 (build_lang_decl)                                    15711    1696788          0:0.559%
cp/call.c:1103 (reference_binding)                                85698    1713960          0:0.565%
cp/decl2.c:186 (cp_build_parm_decl)                               16118    1740744          0:0.573%
cp/call.c:2161 (add_template_candidate_real)                      95347    2324284      63336:0.786%
tree-inline.c:349 (remap_block)                                   66483    2659320          0:0.876%
tree.c:2317 (build)                                              113068    2784040      18836:0.923%
tree-inline.c:1443 (expand_call_inline)                           27249    2942892          0:0.969%
ggc-common.c:188 (ggc_calloc)                                      1512    2946444      13692:0.975%
cp/name-lookup.c:1709 (set_identifier_type_value_with_scope)     151575    3031500          0:0.998%
varray.c:128 (varray_init)                                        27212    2344308     707908:1.005%
tree.c:3923 (build_method_type_directly)                          24117    2604636     482340:1.017%
genrtl.c:478 (gen_rtx_fmt_iuuB00is)                               72608    2904320     290432:1.052%
cp/lex.c:773 (copy_decl)                                          31555    3407940          0:1.122%
cp/name-lookup.c:2786 (push_class_level_binding)                 170972    3419440          0:1.126%
combine.c:9886 (recog_for_combine)                                73864    3313984     299520:1.190%
genrtl.c:635 (gen_rtx_fmt_i00)                                   233298    3732768          0:1.229%
cp/search.c:1200 (build_baselink)                                167695    4024680          0:1.326%
cp/pt.c:6158 (tsubst_decl)                                        38660    4175280          0:1.375%
cselib.c:831 (cselib_subst_to_values)                            357657    4258224          0:1.403%
cp/name-lookup.c:4675 (store_bindings)                           221612    4432240          0:1.460%
genrtl.c:51 (gen_rtx_fmt_ue)                                     374279    4491348          0:1.479%
cp/call.c:1312 (add_function_candidate)                          206354    4591208       9876:1.515%
cp/call.c:610 (standard_conversion)                              244350    4887000          0:1.610%
genrtl.c:671 (gen_rtx_fmt_e0)                                    429635    5155620          0:1.698%
c-semantics.c:200 (build_stmt)                                   263496    5325244      12588:1.758%
genrtl.c:619 (gen_rtx_fmt_0)                                     703683    5629464          0:1.854%
integrate.c:373 (copy_decl_for_inlining)                          52222    5639976          0:1.858%
integrate.c:357 (copy_decl_for_inlining)                          54463    5882004          0:1.937%
cp/call.c:543 (build_conv)                                       295266    5922884          0:1.951%
cp/pt.c:5647 (tsubst_template_args)                              244762    5883460      73716:1.962%
varray.c:161 (varray_grow)                                        22435    4472692    1830136:2.076%
cp/pt.c:3755 (coerce_template_parms)                             279266    6572008      64732:2.186%
function.c:6384 (allocate_struct_function)                         9158    4688896    1978128:2.196%
rtl.c:246 (copy_rtx)                                             580407    6967440          0:2.295%
tree.c:3869 (build_function_type)                                 57823    6244884    1156460:2.438%
cp/call.c:1261 (add_candidate)                                   206686    8267440          0:2.723%
stmt.c:3406 (expand_start_bindings_and_block)                    129461    8285504          0:2.729%
genrtl.c:33 (gen_rtx_fmt_ee)                                    1095450   13145400          0:4.330%
emit-rtl.c:3474 (get_new_any_insn)                               432335   14514808     188000:4.843%
tree-inline.c:1986 (copy_tree_r)                                2099693   43079168     117801:14.228%
Total                                                          12229041  293366904   10246871
-------------------------------------------------------

The RTL expanders and build function needs ot be transparentized, but otherwise
I think it makes it quite easy to see where the memory is going (I've cut it
down from 480MB total to 293MB you can see in my log in two days quite easilly)

Would be something liket this acceptable for mainlnie?

Honza
	* ggc-common.c (ggc_alloc_cleared_stat, ggc_realloc_stat):
	Rename from ...; make statistics transparent.
	(ggc_alloc_cleared, ggc_realloc_stat): ... these.
	(loc_descriptor): New structure.
	(hash_descriptor, eq_descriptor, loc_descriptor, cmp_statistics,
	add_statistics):
	New static function.
	(ggc_record_overhead, dump_statistics): New global function.
	* ggc-none.c (ggc_alloc_types_stat, ggc_alloc_stat, ggc_alloc_zone_stat,
	ggc_alloc_cleared_stat, ggc_realloc_stat, ggc_alloc_typed_stat): Rename
	from ...; accept locations
	(ggc_alloc_types, ggc_alloc, ggc_alloc_zone, ggc_alloc_cleared,
	ggc_realloc, ggc_alloc_typed):  ... this one.
	from ...; accept locations
	* ggc-page.c (ggc_alloc_typed_stat, ggc_alloc_zone_stat,
	ggc_alloc_stat): Rename from ... ; pass locations
	* ggc-page.c (ggc_alloc_typed, ggc_alloc_zone, ggc_alloc):
	... this one.
	(ggc_alloc_stat): Record overehead.
	* ggc.h (ggc_alloc_types, ggc_alloc, ggc_alloc_zone, ggc_alloc_cleared,
	ggc_realloc, ggc_alloc_typed):  Turn to macros
	(ggc_alloc_types_stat, ggc_alloc_stat, ggc_alloc_zone_stat,
	ggc_alloc_cleared_stat, ggc_realloc_stat, ggc_alloc_typed_stat): Declare.
	(dump_ggc_loc_satistics, ggc_record_overehead): Declare.
	* langhooks.h (lhd_make_node): Declare.
	(LANG_HOOKS_MAKE_TYPE): Default to new function,
	* langhooks.c (lhd_make_node): New.
	* rtl.c (rtx_alloc_stat, swallow_copy_rtx_stat): Rename from ... ; pass
	locations.
	(rtx_alloc, swallow_copy_rtx): ... this one.
	* rtl.h (rtx_alloc, swallow_copy_rtx): Turn to macros.
	* rtl.c (rtx_alloc_stat, swallow_copy_rtx_stat): Declare.
	* toplpev.c (finalize): Dump stats.
	* tree.c (make_node_stat, copy_node_stat, make_tree_vec_stat,
	build_tree_list_stat, tree_cons_stat, build1_stat,  build_decl_stat):
	Rename from ... ; pass locators.
	(make_node, copy_node, make_tree_vec, build_tree_list, tree_cons,
	build1,  build_decl): Declare.
	* tree.h (make_node_stat, copy_node_stat, make_tree_vec_stat,
	build_tree_list_stat, tree_cons_stat, build1_stat,  build_decl_stat):
	Declare.
	(make_node, copy_node, make_tree_vec, build_tree_list, tree_cons,
	build1,  build_decl): New macros.
	* Makefile.in (RTL_H, TREE_H): Add statistics.h dependency.
	* statistics.h: New file.
Index: ggc-none.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-none.c,v
retrieving revision 1.15
diff -c -3 -p -r1.15 ggc-none.c
*** ggc-none.c	27 Oct 2003 00:26:52 -0000	1.15
--- ggc-none.c	21 Jan 2004 18:24:29 -0000
*************** struct alloc_zone *rtl_zone = NULL;
*** 32,62 ****
  struct alloc_zone *garbage_zone = NULL;
  
  void *
! ggc_alloc_typed (enum gt_types_enum gte ATTRIBUTE_UNUSED, size_t size)
  {
    return xmalloc (size);
  }
  
  void *
! ggc_alloc (size_t size)
  {
    return xmalloc (size);
  }
  
  void *
! ggc_alloc_zone (size_t size, struct alloc_zone *zone ATTRIBUTE_UNUSED)
  {
    return xmalloc (size);
  }
  
  void *
! ggc_alloc_cleared (size_t size)
  {
    return xcalloc (size, 1);
  }
  
  void *
! ggc_realloc (void *x, size_t size)
  {
    return xrealloc (x, size);
  }
--- 32,64 ----
  struct alloc_zone *garbage_zone = NULL;
  
  void *
! ggc_alloc_typed_stat (enum gt_types_enum gte ATTRIBUTE_UNUSED, size_t size
! 		      MEM_STAT_DECL)
  {
    return xmalloc (size);
  }
  
  void *
! ggc_alloc_stat (size_t size MEM_STAT_DECL)
  {
    return xmalloc (size);
  }
  
  void *
! ggc_alloc_zone_stat (size_t size, struct alloc_zone *zone ATTRIBUTE_UNUSED
! 		     MEM_STAT_DECL)
  {
    return xmalloc (size);
  }
  
  void *
! ggc_alloc_cleared_stat (size_t size MEM_STAT_DECL)
  {
    return xcalloc (size, 1);
  }
  
  void *
! ggc_realloc_stat (void *x, size_t size MEM_STAT_DECL)
  {
    return xrealloc (x, size);
  }
Index: ggc-page.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-page.c,v
retrieving revision 1.84
diff -c -3 -p -r1.84 ggc-page.c
*** ggc-page.c	22 Dec 2003 07:42:37 -0000	1.84
--- ggc-page.c	21 Jan 2004 18:24:35 -0000
*************** static unsigned char size_lookup[257] =
*** 1031,1053 ****
  /* Typed allocation function.  Does nothing special in this collector.  */
  
  void *
! ggc_alloc_typed (enum gt_types_enum type ATTRIBUTE_UNUSED, size_t size)
  {
!   return ggc_alloc (size);
  }
  
  /* Zone allocation function.  Does nothing special in this collector.  */
  
  void *
! ggc_alloc_zone (size_t size, struct alloc_zone *zone ATTRIBUTE_UNUSED)
  {
!   return ggc_alloc (size);
  }
  
  /* Allocate a chunk of memory of SIZE bytes.  Its contents are undefined.  */
  
  void *
! ggc_alloc (size_t size)
  {
    unsigned order, word, bit, object_offset;
    struct page_entry *entry;
--- 1031,1055 ----
  /* Typed allocation function.  Does nothing special in this collector.  */
  
  void *
! ggc_alloc_typed_stat (enum gt_types_enum type ATTRIBUTE_UNUSED, size_t size
! 		      MEM_STAT_DECL)
  {
!   return ggc_alloc_stat (size PASS_MEM_STAT);
  }
  
  /* Zone allocation function.  Does nothing special in this collector.  */
  
  void *
! ggc_alloc_zone_stat (size_t size, struct alloc_zone *zone ATTRIBUTE_UNUSED
! 		     MEM_STAT_DECL)
  {
!   return ggc_alloc_stat (size PASS_MEM_STAT);
  }
  
  /* Allocate a chunk of memory of SIZE bytes.  Its contents are undefined.  */
  
  void *
! ggc_alloc_stat (size_t size MEM_STAT_DECL)
  {
    unsigned order, word, bit, object_offset;
    struct page_entry *entry;
*************** ggc_alloc (size_t size)
*** 1191,1196 ****
--- 1193,1199 ----
        G.stats.total_overhead_under128 += OBJECT_SIZE (order) - size;
        G.stats.total_allocated_under128 += OBJECT_SIZE(order);
      }
+   ggc_record_overhead (OBJECT_SIZE (order), OBJECT_SIZE (order) - size PASS_MEM_STAT);
  
    }
  #endif
Index: ggc.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc.h,v
retrieving revision 1.61
diff -c -3 -p -r1.61 ggc.h
*** ggc.h	21 Dec 2003 14:08:33 -0000	1.61
--- ggc.h	21 Jan 2004 18:24:36 -0000
*************** Software Foundation, 59 Temple Place - S
*** 21,26 ****
--- 21,27 ----
  
  #ifndef GCC_GGC_H
  #define GCC_GGC_H
+ #include "statistics.h"
  
  /* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with
     an external gc library that might be linked in.  */
*************** extern struct alloc_zone *rtl_zone;
*** 210,228 ****
  extern struct alloc_zone *tree_zone;
  
  /* The internal primitive.  */
! extern void *ggc_alloc (size_t);
  /* Allocate an object into the specified allocation zone.  */
! extern void *ggc_alloc_zone (size_t, struct alloc_zone *);
  /* Allocate an object of the specified type and size.  */
! extern void *ggc_alloc_typed (enum gt_types_enum, size_t);
  /* Like ggc_alloc, but allocates cleared memory.  */
! extern void *ggc_alloc_cleared (size_t);
  /* Like ggc_alloc_zone, but allocates cleared memory.  */
! extern void *ggc_alloc_cleared_zone (size_t, struct alloc_zone *);
  /* Resize a block.  */
! extern void *ggc_realloc (void *, size_t);
  /* Like ggc_alloc_cleared, but performs a multiplication.  */
  extern void *ggc_calloc (size_t, size_t);
  
  #define ggc_alloc_rtx(CODE)                    \
    ((rtx) ggc_alloc_typed (gt_ggc_e_7rtx_def, RTX_SIZE (CODE)))
--- 211,239 ----
  extern struct alloc_zone *tree_zone;
  
  /* The internal primitive.  */
! extern void *ggc_alloc_stat (size_t MEM_STAT_DECL);
! #define ggc_alloc(s) ggc_alloc_stat (s MEM_STAT_INFO)
  /* Allocate an object into the specified allocation zone.  */
! extern void *ggc_alloc_zone_stat (size_t, struct alloc_zone * MEM_STAT_DECL);
! #define ggc_alloc_zone(s,z) ggc_alloc_zone_stat (s,z MEM_STAT_INFO)
  /* Allocate an object of the specified type and size.  */
! extern void *ggc_alloc_typed_stat (enum gt_types_enum, size_t MEM_STAT_DECL);
! #define ggc_alloc_typed(s,z) ggc_alloc_typed_stat (s,z MEM_STAT_INFO)
  /* Like ggc_alloc, but allocates cleared memory.  */
! extern void *ggc_alloc_cleared_stat (size_t MEM_STAT_DECL);
! #define ggc_alloc_cleared(s) ggc_alloc_cleared_stat (s MEM_STAT_INFO)
  /* Like ggc_alloc_zone, but allocates cleared memory.  */
! extern void *ggc_alloc_cleared_zone (size_t, struct alloc_zone * MEM_STAT_DECL);
! #define ggc_alloc_cleared_zone(s,z) ggc_alloc_cleared_stat (s,z MEM_STAT_INFO)
  /* Resize a block.  */
! extern void *ggc_realloc_stat (void *, size_t MEM_STAT_DECL);
! #define ggc_realloc(s,z) ggc_realloc_stat (s,z MEM_STAT_INFO)
  /* Like ggc_alloc_cleared, but performs a multiplication.  */
  extern void *ggc_calloc (size_t, size_t);
+ 
+ extern void ggc_record_overhead (size_t, size_t MEM_STAT_DECL);
+ 
+ extern void dump_ggc_loc_statistics (void);
  
  #define ggc_alloc_rtx(CODE)                    \
    ((rtx) ggc_alloc_typed (gt_ggc_e_7rtx_def, RTX_SIZE (CODE)))
Index: langhooks-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks-def.h,v
retrieving revision 1.71
diff -c -3 -p -r1.71 langhooks-def.h
*** langhooks-def.h	9 Jan 2004 19:54:59 -0000	1.71
--- langhooks-def.h	21 Jan 2004 18:24:48 -0000
*************** extern tree lhd_callgraph_analyze_expr (
*** 206,211 ****
--- 206,212 ----
  /* Tree dump hooks.  */
  extern bool lhd_tree_dump_dump_tree (void *, tree);
  extern int lhd_tree_dump_type_quals (tree);
+ extern tree lhd_make_node (enum tree_code);
  
  #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN lhd_tree_dump_dump_tree
  #define LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN lhd_tree_dump_type_quals
*************** extern int lhd_tree_dump_type_quals (tre
*** 217,223 ****
  
  /* Types hooks.  There are no reasonable defaults for most of them,
     so we create a compile-time error instead.  */
! #define LANG_HOOKS_MAKE_TYPE make_node
  #define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error
  #define LANG_HOOKS_TYPE_PROMOTES_TO lhd_type_promotes_to
  #define LANG_HOOKS_REGISTER_BUILTIN_TYPE lhd_register_builtin_type
--- 218,224 ----
  
  /* Types hooks.  There are no reasonable defaults for most of them,
     so we create a compile-time error instead.  */
! #define LANG_HOOKS_MAKE_TYPE lhd_make_node
  #define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error
  #define LANG_HOOKS_TYPE_PROMOTES_TO lhd_type_promotes_to
  #define LANG_HOOKS_REGISTER_BUILTIN_TYPE lhd_register_builtin_type
Index: langhooks.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks.c,v
retrieving revision 1.57
diff -c -3 -p -r1.57 langhooks.c
*** langhooks.c	9 Jan 2004 19:55:00 -0000	1.57
--- langhooks.c	21 Jan 2004 18:24:49 -0000
*************** lhd_callgraph_analyze_expr (tree *tp ATT
*** 562,565 ****
--- 562,571 ----
    return NULL;
  }
  
+ tree
+ lhd_make_node (enum tree_code code)
+ {
+   return make_node (code);
+ }
+ 
  #include "gt-langhooks.h"
Index: rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.c,v
retrieving revision 1.130
diff -c -3 -p -r1.130 rtl.c
*** rtl.c	22 Dec 2003 07:42:37 -0000	1.130
--- rtl.c	21 Jan 2004 18:26:19 -0000
*************** rtvec_alloc (int n)
*** 173,183 ****
     all the rest is initialized to zero.  */
  
  rtx
! rtx_alloc (RTX_CODE code)
  {
    rtx rt;
  
!   rt = ggc_alloc_rtx (code);
  
    /* We want to clear everything up to the FLD array.  Normally, this
       is one int, but we don't want to assume that and it isn't very
--- 173,183 ----
     all the rest is initialized to zero.  */
  
  rtx
! rtx_alloc_stat (RTX_CODE code MEM_STAT_DECL)
  {
    rtx rt;
  
!   rt = ggc_alloc_typed_stat (gt_ggc_e_7rtx_def, RTX_SIZE (code) PASS_MEM_STAT);
  
    /* We want to clear everything up to the FLD array.  Normally, this
       is one int, but we don't want to assume that and it isn't very
*************** copy_rtx (rtx orig)
*** 305,315 ****
  /* Create a new copy of an rtx.  Only copy just one level.  */
  
  rtx
! shallow_copy_rtx (rtx orig)
  {
    rtx copy;
  
!   copy = ggc_alloc_rtx (GET_CODE (orig));
    memcpy (copy, orig, RTX_SIZE (GET_CODE (orig)));
    return copy;
  }
--- 305,316 ----
  /* Create a new copy of an rtx.  Only copy just one level.  */
  
  rtx
! shallow_copy_rtx_stat (rtx orig MEM_STAT_DECL)
  {
    rtx copy;
  
!   copy = ggc_alloc_typed_stat (gt_ggc_e_7rtx_def, RTX_SIZE (GET_CODE (orig))
! 			       PASS_MEM_STAT);
    memcpy (copy, orig, RTX_SIZE (GET_CODE (orig)));
    return copy;
  }
index: rtl.h
===================================================================
rcs file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.449
diff -c -3 -p -r1.449 rtl.h
*** rtl.h	17 jan 2004 22:14:17 -0000	1.449
--- rtl.h	21 jan 2004 18:26:26 -0000
*************** Software Foundation, 59 Temple Place - S
*** 21,26 ****
--- 21,27 ----
  
  #ifndef GCC_RTL_H
  #define GCC_RTL_H
+ #include "statistics.h"
  
  struct function;
  
*************** extern rtx emit_copy_of_insn_after (rtx,
*** 1452,1460 ****
  extern void set_reg_attrs_from_mem (rtx, rtx);
  extern void set_mem_attrs_from_reg (rtx, rtx);
  extern void set_reg_attrs_for_parm (rtx, rtx);
  
  /* In rtl.c */
! extern rtx rtx_alloc (RTX_CODE);
  extern rtvec rtvec_alloc (int);
  extern rtx copy_rtx (rtx);
  extern void dump_rtx_statistics (void);
--- 1458,1469 ----
  extern void set_reg_attrs_from_mem (rtx, rtx);
  extern void set_mem_attrs_from_reg (rtx, rtx);
  extern void set_reg_attrs_for_parm (rtx, rtx);
+ extern void set_reg_pointer_align (rtx, unsigned int);
  
  /* In rtl.c */
! extern rtx rtx_alloc_stat (RTX_CODE MEM_STAT_DECL);
! #define rtx_alloc(c) rtx_alloc_stat (c MEM_STAT_INFO)
! 
  extern rtvec rtvec_alloc (int);
  extern rtx copy_rtx (rtx);
  extern void dump_rtx_statistics (void);
*************** extern rtx copy_rtx_if_shared (rtx);
*** 1464,1470 ****
  
  /* In rtl.c */
  extern rtx copy_most_rtx (rtx, rtx);
! extern rtx shallow_copy_rtx (rtx);
  extern int rtx_equal_p (rtx, rtx);
  
  /* In emit-rtl.c */
--- 1473,1480 ----
  
  /* In rtl.c */
  extern rtx copy_most_rtx (rtx, rtx);
! extern rtx shallow_copy_rtx_stat (rtx MEM_STAT_DECL);
! #define shallow_copy_rtx(a) shallow_copy_rtx_stat (a MEM_STAT_INFO)
  extern int rtx_equal_p (rtx, rtx);
  
  /* In emit-rtl.c */
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.865
diff -c -3 -p -r1.865 toplev.c
*** toplev.c	17 Jan 2004 12:28:57 -0000	1.865
--- toplev.c	21 Jan 2004 18:26:43 -0000
*************** finalize (void)
*** 4583,4588 ****
--- 4585,4592 ----
        stringpool_statistics ();
        dump_tree_statistics ();
        dump_rtx_statistics ();
+       dump_varray_statistics ();
+       dump_ggc_loc_statistics ();
      }
  
    /* Free up memory for the benefit of leak detectors.  */
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.342
diff -c -3 -p -r1.342 tree.c
*** tree.c	16 Jan 2004 07:20:28 -0000	1.342
--- tree.c	21 Jan 2004 18:26:56 -0000
*************** tree_size (tree node)
*** 202,208 ****
     Achoo!  I got a code in the node.  */
  
  tree
! make_node (enum tree_code code)
  {
    tree t;
    int type = TREE_CODE_CLASS (code);
--- 202,208 ----
     Achoo!  I got a code in the node.  */
  
  tree
! make_node_stat (enum tree_code code MEM_STAT_DECL)
  {
    tree t;
    int type = TREE_CODE_CLASS (code);
*************** make_node (enum tree_code code)
*** 271,277 ****
    tree_node_sizes[(int) kind] += length;
  #endif
  
!   t = ggc_alloc_tree (length);
  
    memset (t, 0, length);
  
--- 271,277 ----
    tree_node_sizes[(int) kind] += length;
  #endif
  
!   t = ggc_alloc_zone_stat (length, tree_zone PASS_MEM_STAT);
  
    memset (t, 0, length);
  
*************** make_node (enum tree_code code)
*** 342,355 ****
     TREE_CHAIN is zero and it has a fresh uid.  */
  
  tree
! copy_node (tree node)
  {
    tree t;
    enum tree_code code = TREE_CODE (node);
    size_t length;
  
    length = tree_size (node);
!   t = ggc_alloc_tree (length);
    memcpy (t, node, length);
  
    TREE_CHAIN (t) = 0;
--- 342,355 ----
     TREE_CHAIN is zero and it has a fresh uid.  */
  
  tree
! copy_node_stat (tree node MEM_STAT_DECL)
  {
    tree t;
    enum tree_code code = TREE_CODE (node);
    size_t length;
  
    length = tree_size (node);
!   t = ggc_alloc_zone_stat (length, tree_zone PASS_MEM_STAT);
    memcpy (t, node, length);
  
    TREE_CHAIN (t) = 0;
*************** build_complex (tree type, tree real, tre
*** 569,575 ****
  /* Build a newly constructed TREE_VEC node of length LEN.  */
  
  tree
! make_tree_vec (int len)
  {
    tree t;
    int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec);
--- 569,575 ----
  /* Build a newly constructed TREE_VEC node of length LEN.  */
  
  tree
! make_tree_vec_stat (int len MEM_STAT_DECL)
  {
    tree t;
    int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec);
*************** make_tree_vec (int len)
*** 579,587 ****
    tree_node_sizes[(int) vec_kind] += length;
  #endif
  
!   t = ggc_alloc_tree (length);
  
    memset (t, 0, length);
    TREE_SET_CODE (t, TREE_VEC);
    TREE_VEC_LENGTH (t) = len;
  
--- 579,588 ----
    tree_node_sizes[(int) vec_kind] += length;
  #endif
  
!   t = ggc_alloc_zone_stat (length, tree_zone PASS_MEM_STAT);
  
    memset (t, 0, length);
+ 
    TREE_SET_CODE (t, TREE_VEC);
    TREE_VEC_LENGTH (t) = len;
  
*************** nreverse (tree t)
*** 1039,1047 ****
     purpose and value fields are PARM and VALUE.  */
  
  tree
! build_tree_list (tree parm, tree value)
  {
!   tree t = make_node (TREE_LIST);
    TREE_PURPOSE (t) = parm;
    TREE_VALUE (t) = value;
    return t;
--- 1040,1048 ----
     purpose and value fields are PARM and VALUE.  */
  
  tree
! build_tree_list_stat (tree parm, tree value MEM_STAT_DECL)
  {
!   tree t = make_node_stat (TREE_LIST PASS_MEM_STAT);
    TREE_PURPOSE (t) = parm;
    TREE_VALUE (t) = value;
    return t;
*************** build_tree_list (tree parm, tree value)
*** 1052,1062 ****
     and whose TREE_CHAIN is CHAIN.  */
  
  tree
! tree_cons (tree purpose, tree value, tree chain)
  {
    tree node;
  
!   node = ggc_alloc_tree (sizeof (struct tree_list));
  
    memset (node, 0, sizeof (struct tree_common));
  
--- 1053,1064 ----
     and whose TREE_CHAIN is CHAIN.  */
  
  tree
! tree_cons_stat (tree purpose, tree value, tree chain MEM_STAT_DECL)
  {
    tree node;
  
!   node = ggc_alloc_zone_stat (sizeof (struct tree_list),
! 			      tree_zone PASS_MEM_STAT);
  
    memset (node, 0, sizeof (struct tree_common));
  
*************** build (enum tree_code code, tree tt, ...
*** 2416,2422 ****
     of varargs, which is expensive for RISC machines.  */
  
  tree
! build1 (enum tree_code code, tree type, tree node)
  {
    int length = sizeof (struct tree_exp);
  #ifdef GATHER_STATISTICS
--- 2418,2424 ----
     of varargs, which is expensive for RISC machines.  */
  
  tree
! build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
  {
    int length = sizeof (struct tree_exp);
  #ifdef GATHER_STATISTICS
*************** build1 (enum tree_code code, tree type, 
*** 2449,2455 ****
      abort ();
  #endif /* ENABLE_CHECKING */
  
!   t = ggc_alloc_tree (length);
  
    memset (t, 0, sizeof (struct tree_common));
  
--- 2451,2457 ----
      abort ();
  #endif /* ENABLE_CHECKING */
  
!   t = ggc_alloc_zone_stat (length, tree_zone PASS_MEM_STAT);
  
    memset (t, 0, sizeof (struct tree_common));
  
*************** build_nt (enum tree_code code, ...)
*** 2552,2562 ****
     Other slots are initialized to 0 or null pointers.  */
  
  tree
! build_decl (enum tree_code code, tree name, tree type)
  {
    tree t;
  
!   t = make_node (code);
  
  /*  if (type == error_mark_node)
      type = integer_type_node; */
--- 2554,2564 ----
     Other slots are initialized to 0 or null pointers.  */
  
  tree
! build_decl_stat (enum tree_code code, tree name, tree type MEM_STAT_DECL)
  {
    tree t;
  
!   t = make_node_stat (code PASS_MEM_STAT);
  
  /*  if (type == error_mark_node)
      type = integer_type_node; */
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.458
diff -c -3 -p -r1.458 tree.h
*** tree.h	16 Jan 2004 07:20:29 -0000	1.458
--- tree.h	21 Jan 2004 18:27:08 -0000
*************** Software Foundation, 59 Temple Place - S
*** 25,30 ****
--- 25,31 ----
  #include "machmode.h"
  #include "version.h"
  #include "input.h"
+ #include "statistics.h"
  
  /* Codes of tree nodes */
  
*************** extern size_t tree_size (tree);
*** 2060,2070 ****
     The TREE_CODE is the only argument.  Contents are initialized
     to zero except for a few of the common fields.  */
  
! extern tree make_node (enum tree_code);
  
  /* Make a copy of a node, with all the same contents.  */
  
! extern tree copy_node (tree);
  
  /* Make a copy of a chain of TREE_LIST nodes.  */
  
--- 2061,2073 ----
     The TREE_CODE is the only argument.  Contents are initialized
     to zero except for a few of the common fields.  */
  
! extern tree make_node_stat (enum tree_code MEM_STAT_DECL);
! #define make_node(t) make_node_stat (t MEM_STAT_INFO)
  
  /* Make a copy of a node, with all the same contents.  */
  
! extern tree copy_node_stat (tree MEM_STAT_DECL);
! #define copy_node(t) copy_node_stat (t MEM_STAT_INFO)
  
  /* Make a copy of a chain of TREE_LIST nodes.  */
  
*************** extern tree copy_list (tree);
*** 2072,2078 ****
  
  /* Make a TREE_VEC.  */
  
! extern tree make_tree_vec (int);
  
  /* Return the (unique) IDENTIFIER_NODE node for a given name.
     The name is supplied as a char *.  */
--- 2075,2082 ----
  
  /* Make a TREE_VEC.  */
  
! extern tree make_tree_vec_stat (int MEM_STAT_DECL);
! #define make_tree_vec(t) make_tree_vec_stat (t MEM_STAT_INFO)
  
  /* Return the (unique) IDENTIFIER_NODE node for a given name.
     The name is supplied as a char *.  */
*************** extern tree build_constructor (tree, tre
*** 2112,2120 ****
  extern tree build_real_from_int_cst (tree, tree);
  extern tree build_complex (tree, tree, tree);
  extern tree build_string (int, const char *);
! extern tree build1 (enum tree_code, tree, tree);
! extern tree build_tree_list (tree, tree);
! extern tree build_decl (enum tree_code, tree, tree);
  extern tree build_block (tree, tree, tree, tree, tree);
  extern tree build_expr_wfl (tree, const char *, int, int);
  
--- 2116,2127 ----
  extern tree build_real_from_int_cst (tree, tree);
  extern tree build_complex (tree, tree, tree);
  extern tree build_string (int, const char *);
! extern tree build1_stat (enum tree_code, tree, tree MEM_STAT_DECL);
! #define build1(c,t,q) build1_stat (c,t,q MEM_STAT_INFO)
! extern tree build_tree_list_stat (tree, tree MEM_STAT_DECL);
! #define build_tree_list(t,q) build_tree_list_stat(t,q MEM_STAT_INFO)
! extern tree build_decl_stat (enum tree_code, tree, tree MEM_STAT_DECL);
! #define build_decl(c,t,q) build_decl_stat (c,t,q MEM_STAT_INFO)
  extern tree build_block (tree, tree, tree, tree, tree);
  extern tree build_expr_wfl (tree, const char *, int, int);
  
*************** extern tree chainon (tree, tree);
*** 2468,2474 ****
  
  /* Make a new TREE_LIST node from specified PURPOSE, VALUE and CHAIN.  */
  
! extern tree tree_cons (tree, tree, tree);
  
  /* Return the last tree node in a chain.  */
  
--- 2475,2482 ----
  
  /* Make a new TREE_LIST node from specified PURPOSE, VALUE and CHAIN.  */
  
! extern tree tree_cons_stat (tree, tree, tree MEM_STAT_DECL);
! #define tree_cons(t,q,w) tree_cons_stat (t,q,w MEM_STAT_INFO)
  
  /* Return the last tree node in a chain.  */
  
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1229
diff -c -3 -p -r1.1229 Makefile.in
*** Makefile.in	20 Jan 2004 20:36:18 -0000	1.1229
--- Makefile.in	21 Jan 2004 18:55:46 -0000
*************** LANGHOOKS_DEF_H = langhooks-def.h $(HOOK
*** 655,664 ****
  TARGET_DEF_H = target-def.h $(HOOKS_H)
  MACHMODE_H = machmode.h mode-classes.def insn-modes.h
  RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H)
! RTL_H = $(RTL_BASE_H) genrtl.h input.h
  PARAMS_H = params.h params.def
  TREE_H = tree.h tree.def $(MACHMODE_H) tree-check.h version.h builtins.def \
!           input.h
  BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h varray.h $(PARTITION_H) \
            hard-reg-set.h cfghooks.h
  COVERAGE_H = coverage.h gcov-io.h gcov-iov.h
--- 655,664 ----
  TARGET_DEF_H = target-def.h $(HOOKS_H)
  MACHMODE_H = machmode.h mode-classes.def insn-modes.h
  RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H)
! RTL_H = $(RTL_BASE_H) genrtl.h input.h statistics.h
  PARAMS_H = params.h params.def
  TREE_H = tree.h tree.def $(MACHMODE_H) tree-check.h version.h builtins.def \
!           input.h statistics.h
  BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h varray.h $(PARTITION_H) \
            hard-reg-set.h cfghooks.h
  COVERAGE_H = coverage.h gcov-io.h gcov-iov.h
*************** bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM
*** 1731,1737 ****
  global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
     reload.h function.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h output.h \
     toplev.h $(TM_P_H)
! varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) varray.h $(GGC_H) errors.h
  ra.o : ra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TM_P_H) insn-config.h \
     $(RECOG_H) $(INTEGRATE_H) function.h $(REGS_H) $(OBSTACK_H) hard-reg-set.h \
     $(BASIC_BLOCK_H) df.h $(EXPR_H) output.h toplev.h flags.h reload.h ra.h
--- 1731,1738 ----
  global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
     reload.h function.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h output.h \
     toplev.h $(TM_P_H)
! varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) varray.h $(GGC_H) errors.h \
!    $(HASHTAB_H)
  ra.o : ra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TM_P_H) insn-config.h \
     $(RECOG_H) $(INTEGRATE_H) function.h $(REGS_H) $(OBSTACK_H) hard-reg-set.h \
     $(BASIC_BLOCK_H) df.h $(EXPR_H) output.h toplev.h flags.h reload.h ra.h
Index: ggc-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-common.c,v
retrieving revision 1.78
diff -c -3 -p -r1.78 ggc-common.c
*** ggc-common.c	29 Oct 2003 22:13:59 -0000	1.78
--- ggc-common.c	21 Jan 2004 19:01:02 -0000
*************** ggc_mark_roots (void)
*** 129,150 ****
  
  /* Allocate a block of memory, then clear it.  */
  void *
! ggc_alloc_cleared (size_t size)
  {
!   void *buf = ggc_alloc (size);
    memset (buf, 0, size);
    return buf;
  }
  
  /* Resize a block of memory, possibly re-allocating it.  */
  void *
! ggc_realloc (void *x, size_t size)
  {
    void *r;
    size_t old_size;
  
    if (x == NULL)
!     return ggc_alloc (size);
  
    old_size = ggc_get_size (x);
    if (size <= old_size)
--- 129,150 ----
  
  /* Allocate a block of memory, then clear it.  */
  void *
! ggc_alloc_cleared_stat (size_t size MEM_STAT_DECL)
  {
!   void *buf = ggc_alloc_stat (size PASS_MEM_STAT);
    memset (buf, 0, size);
    return buf;
  }
  
  /* Resize a block of memory, possibly re-allocating it.  */
  void *
! ggc_realloc_stat (void *x, size_t size MEM_STAT_DECL)
  {
    void *r;
    size_t old_size;
  
    if (x == NULL)
!     return ggc_alloc_stat (size PASS_MEM_STAT);
  
    old_size = ggc_get_size (x);
    if (size <= old_size)
*************** ggc_realloc (void *x, size_t size)
*** 165,171 ****
        return x;
      }
  
!   r = ggc_alloc (size);
  
    /* Since ggc_get_size returns the size of the pool, not the size of the
       individually allocated object, we'd access parts of the old object
--- 165,171 ----
        return x;
      }
  
!   r = ggc_alloc_stat (size PASS_MEM_STAT);
  
    /* Since ggc_get_size returns the size of the pool, not the size of the
       individually allocated object, we'd access parts of the old object
*************** init_ggc_heuristics (void)
*** 758,762 ****
--- 758,899 ----
  #if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT
    set_param_value ("ggc-min-expand", ggc_min_expand_heuristic());
    set_param_value ("ggc-min-heapsize", ggc_min_heapsize_heuristic());
+ #endif
+ }
+ 
+ #ifdef GATHER_STATISTICS
+ 
+ /* Datastructure used to store per-call-site statistics.  */
+ struct loc_descriptor
+ {
+   const char *file;
+   int line;
+   const char *function;
+   int times;
+   size_t allocated;
+   size_t overhead;
+ };
+ 
+ /* Hashtable used for statistics.  */
+ static htab_t loc_hash;
+ 
+ /* Hash table helpers functions.  */
+ static hashval_t
+ hash_descriptor (const void *p)
+ {
+   const struct loc_descriptor *d = p;
+ 
+   return htab_hash_pointer (d->function) | d->line;
+ }
+ 
+ static int
+ eq_descriptor (const void *p1, const void *p2)
+ {
+   const struct loc_descriptor *d = p1;
+   const struct loc_descriptor *d2 = p2;
+ 
+   return (d->file == d2->file && d->line == d2->line
+ 	  && d->function == d2->function);
+ }
+ 
+ /* Return descriptor for given call site, create new one if needed.  */
+ static struct loc_descriptor *
+ loc_descriptor (const char *name, int line, const char *function)
+ {
+   struct loc_descriptor loc;
+   struct loc_descriptor **slot;
+ 
+   loc.file = name;
+   loc.line = line;
+   loc.function = function;
+   if (!loc_hash)
+     loc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
+ 
+   slot = (struct loc_descriptor **) htab_find_slot (loc_hash, &loc, 1);
+   if (*slot)
+     return *slot;
+   *slot = xcalloc (sizeof (**slot), 1);
+   (*slot)->file = name;
+   (*slot)->line = line;
+   (*slot)->function = function;
+   return *slot;
+ }
+ 
+ /* Record ALLOCATED and OVERHEAD bytes to descritor NAME:LINE (FUNCTION).  */
+ void ggc_record_overhead (size_t allocated, size_t overhead,
+ 			  const char *name, int line, const char *function)
+ {
+   struct loc_descriptor *loc = loc_descriptor (name, line, function);
+ 
+   loc->times++;
+   loc->allocated+=allocated;
+   loc->overhead+=overhead;
+ }
+ 
+ /* 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) - (l2->allocated + l2->overhead);
+ }
+ 
+ /* Collect array of the descriptors from hashtable.  */
+ struct loc_descriptor **loc_array;
+ static int
+ add_statistics (void **slot, void *b)
+ {
+   int *n = (int *)b;
+   loc_array[*n] = (struct loc_descriptor *) *slot;
+   (*n)++;
+   return 1;
+ }
+ 
+ /* Dump per-site memory statistics.  */
+ #endif
+ void dump_ggc_loc_statistics (void)
+ {
+ #ifdef GATHER_STATISTICS
+   int nentries = 0;
+   char s[4096];
+   size_t count, size, overhead;
+   int i;
+ 
+   loc_array = xcalloc (sizeof (*loc_array), loc_hash->n_elements);
+   fprintf (stderr, "-------------------------------------------------------\n");
+   fprintf (stderr, "\n%-60s %10s %10s %10s\n",
+ 	   "source location", "Times", "Allocated", "Overhead");
+   fprintf (stderr, "-------------------------------------------------------\n");
+   count = 0;
+   size = 0;
+   overhead = 0;
+   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];
+       size += d->allocated;
+       count += d->times;
+       overhead += d->overhead;
+     }
+   for (i = 0; i < nentries; i++)
+     {
+       struct loc_descriptor *d = loc_array[i];
+       if (d->allocated)
+ 	{
+ 	  const char *s1 = d->file;
+ 	  const char *s2;
+ 	  while ((s2 = strstr (s1, "gcc/")))
+ 	    s1 = s2 + 4;
+ 	  sprintf (s, "%s:%i (%s)", s1, d->line, d->function);
+ 	  fprintf (stderr, "%-60s %10i %10li %10li:%.3f%%\n", s,
+ 		   d->times, (long)d->allocated, (long)d->overhead,
+ 		   (d->allocated + d->overhead) *100.0 / (size + overhead));
+ 	}
+     }
+   fprintf (stderr, "%-60s %10ld %10ld %10ld\n",
+ 	   "Total", (long)count, (long)size, (long)overhead);
+   fprintf (stderr, "-------------------------------------------------------\n");
  #endif
  }

/* Memory statistics helpers.
   Copyright (C) 2004
   Free Software Foundation, Inc.
   Contributed by Cygnus Solutions.

   This file is part of GCC.

   GCC is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   GCC is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   License for more details.

   You should have received a copy of the GNU General Public License
   along with GCC; see the file COPYING.  If not, write to the Free
   the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
   MA 02111-1307, USA.  */

#ifndef GCC_STATISTICS
#define GCC_STATISTICS
#ifdef GATHER_STATISTICS
#define MEM_STAT_DECL , const char *_loc_name ATTRIBUTE_UNUSED, int _loc_line ATTRIBUTE_UNUSED, const char *_loc_function ATTRIBUTE_UNUSED
#define PASS_MEM_STAT , _loc_name, _loc_line,  _loc_function
#define MEM_STAT_INFO , __FILE__, __LINE__, __FUNCTION__
#else
#define MEM_STAT_DECL
#define PASS_MEM_STAT
#define MEM_STAT_INFO
#endif
#endif



More information about the Gcc-patches mailing list