From b9dcdee46edefdb67cbbb5aa0829fba999c2a1f0 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 3 Mar 2004 12:25:51 +0100 Subject: [PATCH] ggc-common.c (ggc_alloc_cleared_stat, [...]): Rename from ...; make statistics transparent. * 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, build?_stat, build_decl_stat): Rename from ... ; pass locators. (make_node, copy_node, make_tree_vec, build_tree_list, tree_cons, build?, build_decl): Declare. * tree.h (make_node_stat, copy_node_stat, make_tree_vec_stat, build_tree_list_stat, tree_cons_stat, build?_stat, build_decl_stat): Declare. (make_node, copy_node, make_tree_vec, build_tree_list, tree_cons, build?, build_decl): New macros. * Makefile.in (RTL_H, TREE_H): Add statistics.h dependency. * statistics.h: New file. From-SVN: r78826 --- gcc/ChangeLog | 48 +++++++++++++++ gcc/Makefile.in | 4 +- gcc/ggc-common.c | 147 ++++++++++++++++++++++++++++++++++++++++++-- gcc/ggc-none.c | 12 ++-- gcc/ggc-page.c | 15 +++-- gcc/ggc.h | 23 +++++-- gcc/langhooks-def.h | 3 +- gcc/langhooks.c | 6 ++ gcc/rtl.c | 9 +-- gcc/rtl.h | 9 ++- gcc/statistics.h | 34 ++++++++++ gcc/toplev.c | 1 + gcc/tree.c | 49 ++++++++------- gcc/tree.h | 35 +++++++---- 14 files changed, 331 insertions(+), 64 deletions(-) create mode 100644 gcc/statistics.h diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e812431d853..7ed079e6db6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,51 @@ +2004-03-03 Jan Hubicka + + * 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, build?_stat, build_decl_stat): + Rename from ... ; pass locators. + (make_node, copy_node, make_tree_vec, build_tree_list, tree_cons, + build?, build_decl): Declare. + * tree.h (make_node_stat, copy_node_stat, make_tree_vec_stat, + build_tree_list_stat, tree_cons_stat, build?_stat, build_decl_stat): + Declare. + (make_node, copy_node, make_tree_vec, build_tree_list, tree_cons, + build?, build_decl): New macros. + * Makefile.in (RTL_H, TREE_H): Add statistics.h dependency. + * statistics.h: New file. + 2004-03-03 Maciej W. Rozycki Richard Sandiford diff --git a/gcc/Makefile.in b/gcc/Makefile.in index d83c8de734a..416e2305edc 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -663,10 +663,10 @@ LANGHOOKS_DEF_H = langhooks-def.h $(HOOKS_H) 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 +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 + 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 diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index 3d096b9e133..70a0d084c81 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -129,22 +129,22 @@ ggc_mark_roots (void) /* Allocate a block of memory, then clear it. */ void * -ggc_alloc_cleared (size_t size) +ggc_alloc_cleared_stat (size_t size MEM_STAT_DECL) { - void *buf = ggc_alloc (size); + 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 (void *x, size_t size) +ggc_realloc_stat (void *x, size_t size MEM_STAT_DECL) { void *r; size_t old_size; if (x == NULL) - return ggc_alloc (size); + return ggc_alloc_stat (size PASS_MEM_STAT); old_size = ggc_get_size (x); @@ -166,7 +166,7 @@ ggc_realloc (void *x, size_t size) return x; } - r = ggc_alloc (size); + 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 @@ -761,3 +761,140 @@ init_ggc_heuristics (void) 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 +} diff --git a/gcc/ggc-none.c b/gcc/ggc-none.c index 659bf931d09..0a97d95456b 100644 --- a/gcc/ggc-none.c +++ b/gcc/ggc-none.c @@ -32,31 +32,33 @@ struct alloc_zone *rtl_zone = NULL; struct alloc_zone *garbage_zone = NULL; void * -ggc_alloc_typed (enum gt_types_enum gte ATTRIBUTE_UNUSED, size_t size) +ggc_alloc_typed_stat (enum gt_types_enum gte ATTRIBUTE_UNUSED, size_t size + MEM_STAT_DECL) { return xmalloc (size); } void * -ggc_alloc (size_t size) +ggc_alloc_stat (size_t size MEM_STAT_DECL) { return xmalloc (size); } void * -ggc_alloc_zone (size_t size, struct alloc_zone *zone ATTRIBUTE_UNUSED) +ggc_alloc_zone_stat (size_t size, struct alloc_zone *zone ATTRIBUTE_UNUSED + MEM_STAT_DECL) { return xmalloc (size); } void * -ggc_alloc_cleared (size_t size) +ggc_alloc_cleared_stat (size_t size MEM_STAT_DECL) { return xcalloc (size, 1); } void * -ggc_realloc (void *x, size_t size) +ggc_realloc_stat (void *x, size_t size MEM_STAT_DECL) { return xrealloc (x, size); } diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c index c499dd79e9d..dadc1249c89 100644 --- a/gcc/ggc-page.c +++ b/gcc/ggc-page.c @@ -1044,23 +1044,25 @@ static unsigned char size_lookup[257] = /* Typed allocation function. Does nothing special in this collector. */ void * -ggc_alloc_typed (enum gt_types_enum type ATTRIBUTE_UNUSED, size_t size) +ggc_alloc_typed_stat (enum gt_types_enum type ATTRIBUTE_UNUSED, size_t size + MEM_STAT_DECL) { - return ggc_alloc (size); + return ggc_alloc_stat (size PASS_MEM_STAT); } /* Zone allocation function. Does nothing special in this collector. */ void * -ggc_alloc_zone (size_t size, struct alloc_zone *zone ATTRIBUTE_UNUSED) +ggc_alloc_zone_stat (size_t size, struct alloc_zone *zone ATTRIBUTE_UNUSED + MEM_STAT_DECL) { - return ggc_alloc (size); + return ggc_alloc_stat (size PASS_MEM_STAT); } /* Allocate a chunk of memory of SIZE bytes. Its contents are undefined. */ void * -ggc_alloc (size_t size) +ggc_alloc_stat (size_t size MEM_STAT_DECL) { size_t order, word, bit, object_offset, object_size; struct page_entry *entry; @@ -1171,6 +1173,9 @@ ggc_alloc (size_t size) G.page_tails[order]->next = entry; G.page_tails[order] = entry; } +#ifdef GATHER_STATISTICS + ggc_record_overhead (OBJECT_SIZE (order), OBJECT_SIZE (order) - size PASS_MEM_STAT); +#endif /* Calculate the object's address. */ result = entry->page + object_offset; diff --git a/gcc/ggc.h b/gcc/ggc.h index f9d2ac21c31..4ce271a0760 100644 --- a/gcc/ggc.h +++ b/gcc/ggc.h @@ -21,6 +21,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #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. */ @@ -210,21 +211,31 @@ extern struct alloc_zone *rtl_zone; extern struct alloc_zone *tree_zone; /* The internal primitive. */ -extern void *ggc_alloc (size_t); +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 (size_t, struct alloc_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 (enum gt_types_enum, size_t); +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 (size_t); +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 *); +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 (void *, size_t); +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); /* Free a block. To be used when known for certain it's not reachable. */ extern void ggc_free (void *); + +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))) diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index 7d66437af03..f9e621f3e28 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -206,6 +206,7 @@ extern tree lhd_callgraph_analyze_expr (tree *, int *, tree); /* 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 @@ -217,7 +218,7 @@ extern int lhd_tree_dump_type_quals (tree); /* 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_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 diff --git a/gcc/langhooks.c b/gcc/langhooks.c index a965193978d..d37ba213586 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -562,4 +562,10 @@ lhd_callgraph_analyze_expr (tree *tp ATTRIBUTE_UNUSED, return NULL; } +tree +lhd_make_node (enum tree_code code) +{ + return make_node (code); +} + #include "gt-langhooks.h" diff --git a/gcc/rtl.c b/gcc/rtl.c index a14c8e1b4f0..9f545d83623 100644 --- a/gcc/rtl.c +++ b/gcc/rtl.c @@ -173,11 +173,11 @@ rtvec_alloc (int n) all the rest is initialized to zero. */ rtx -rtx_alloc (RTX_CODE code) +rtx_alloc_stat (RTX_CODE code MEM_STAT_DECL) { rtx rt; - rt = ggc_alloc_rtx (code); + 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 @@ -309,11 +309,12 @@ copy_rtx (rtx orig) /* Create a new copy of an rtx. Only copy just one level. */ rtx -shallow_copy_rtx (rtx orig) +shallow_copy_rtx_stat (rtx orig MEM_STAT_DECL) { rtx copy; - copy = ggc_alloc_rtx (GET_CODE (orig)); + 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; } diff --git a/gcc/rtl.h b/gcc/rtl.h index 3cec0c466fb..66578d08bf5 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -21,6 +21,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #ifndef GCC_RTL_H #define GCC_RTL_H +#include "statistics.h" struct function; @@ -1556,9 +1557,12 @@ extern rtx emit_copy_of_insn_after (rtx, rtx); 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 (RTX_CODE); +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); @@ -1568,7 +1572,8 @@ extern rtx copy_rtx_if_shared (rtx); /* In rtl.c */ extern rtx copy_most_rtx (rtx, rtx); -extern rtx shallow_copy_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 */ diff --git a/gcc/statistics.h b/gcc/statistics.h new file mode 100644 index 00000000000..2b0656574dd --- /dev/null +++ b/gcc/statistics.h @@ -0,0 +1,34 @@ +/* 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 diff --git a/gcc/toplev.c b/gcc/toplev.c index dd57caefc83..da9e7f90bab 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2527,6 +2527,7 @@ finalize (void) dump_rtx_statistics (); dump_varray_statistics (); dump_alloc_pool_statistics (); + dump_ggc_loc_statistics (); } /* Free up memory for the benefit of leak detectors. */ diff --git a/gcc/tree.c b/gcc/tree.c index 3913b55f33e..633dcd1fcb9 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -200,7 +200,7 @@ tree_size (tree node) Achoo! I got a code in the node. */ tree -make_node (enum tree_code code) +make_node_stat (enum tree_code code MEM_STAT_DECL) { tree t; int type = TREE_CODE_CLASS (code); @@ -269,7 +269,7 @@ make_node (enum tree_code code) tree_node_sizes[(int) kind] += length; #endif - t = ggc_alloc_tree (length); + t = ggc_alloc_zone_stat (length, tree_zone PASS_MEM_STAT); memset (t, 0, length); @@ -340,14 +340,14 @@ make_node (enum tree_code code) TREE_CHAIN is zero and it has a fresh uid. */ tree -copy_node (tree node) +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_tree (length); + t = ggc_alloc_zone_stat (length, tree_zone PASS_MEM_STAT); memcpy (t, node, length); TREE_CHAIN (t) = 0; @@ -554,7 +554,7 @@ build_complex (tree type, tree real, tree imag) /* Build a newly constructed TREE_VEC node of length LEN. */ tree -make_tree_vec (int len) +make_tree_vec_stat (int len MEM_STAT_DECL) { tree t; int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec); @@ -564,9 +564,10 @@ make_tree_vec (int len) tree_node_sizes[(int) vec_kind] += length; #endif - t = ggc_alloc_tree (length); + 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; @@ -1024,9 +1025,9 @@ nreverse (tree t) purpose and value fields are PARM and VALUE. */ tree -build_tree_list (tree parm, tree value) +build_tree_list_stat (tree parm, tree value MEM_STAT_DECL) { - tree t = make_node (TREE_LIST); + tree t = make_node_stat (TREE_LIST PASS_MEM_STAT); TREE_PURPOSE (t) = parm; TREE_VALUE (t) = value; return t; @@ -1037,11 +1038,12 @@ build_tree_list (tree parm, tree value) and whose TREE_CHAIN is CHAIN. */ tree -tree_cons (tree purpose, tree value, tree chain) +tree_cons_stat (tree purpose, tree value, tree chain MEM_STAT_DECL) { tree node; - node = ggc_alloc_tree (sizeof (struct tree_list)); + node = ggc_alloc_zone_stat (sizeof (struct tree_list), + tree_zone PASS_MEM_STAT); memset (node, 0, sizeof (struct tree_common)); @@ -2296,7 +2298,7 @@ stabilize_reference_1 (tree e) magic within the build macro. */ tree -build0 (enum tree_code code, tree tt) +build0_stat (enum tree_code code, tree tt MEM_STAT_DECL) { tree t; @@ -2305,14 +2307,14 @@ build0 (enum tree_code code, tree tt) abort (); #endif - t = make_node (code); + t = make_node_stat (code PASS_MEM_STAT); TREE_TYPE (t) = tt; return t; } tree -build1 (enum tree_code code, tree type, tree node) +build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL) { int length = sizeof (struct tree_exp); #ifdef GATHER_STATISTICS @@ -2343,7 +2345,7 @@ build1 (enum tree_code code, tree type, tree node) abort (); #endif /* ENABLE_CHECKING */ - t = ggc_alloc_tree (length); + t = ggc_alloc_zone_stat (length, tree_zone PASS_MEM_STAT); memset (t, 0, sizeof (struct tree_common)); @@ -2429,7 +2431,7 @@ build1 (enum tree_code code, tree type, tree node) } while (0) tree -build2 (enum tree_code code, tree tt, tree arg0, tree arg1) +build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL) { bool constant, read_only, side_effects; tree t; @@ -2440,7 +2442,7 @@ build2 (enum tree_code code, tree tt, tree arg0, tree arg1) abort (); #endif - t = make_node (code); + t = make_node_stat (code PASS_MEM_STAT); TREE_TYPE (t) = tt; /* Below, we automatically set TREE_SIDE_EFFECTS and TREE_READONLY for the @@ -2487,7 +2489,8 @@ build2 (enum tree_code code, tree tt, tree arg0, tree arg1) } tree -build3 (enum tree_code code, tree tt, tree arg0, tree arg1, tree arg2) +build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1, + tree arg2 MEM_STAT_DECL) { bool constant, read_only, side_effects; tree t; @@ -2508,7 +2511,7 @@ build3 (enum tree_code code, tree tt, tree arg0, tree arg1, tree arg2) abort (); #endif - t = make_node (code); + t = make_node_stat (code PASS_MEM_STAT); TREE_TYPE (t) = tt; fro = first_rtl_op (code); @@ -2525,8 +2528,8 @@ build3 (enum tree_code code, tree tt, tree arg0, tree arg1, tree arg2) } tree -build4 (enum tree_code code, tree tt, tree arg0, tree arg1, - tree arg2, tree arg3) +build4_stat (enum tree_code code, tree tt, tree arg0, tree arg1, + tree arg2, tree arg3 MEM_STAT_DECL) { bool constant, read_only, side_effects; tree t; @@ -2537,7 +2540,7 @@ build4 (enum tree_code code, tree tt, tree arg0, tree arg1, abort (); #endif - t = make_node (code); + t = make_node_stat (code PASS_MEM_STAT); TREE_TYPE (t) = tt; fro = first_rtl_op (code); @@ -2631,11 +2634,11 @@ build_nt (enum tree_code code, ...) Other slots are initialized to 0 or null pointers. */ tree -build_decl (enum tree_code code, tree name, tree type) +build_decl_stat (enum tree_code code, tree name, tree type MEM_STAT_DECL) { tree t; - t = make_node (code); + t = make_node_stat (code PASS_MEM_STAT); /* if (type == error_mark_node) type = integer_type_node; */ diff --git a/gcc/tree.h b/gcc/tree.h index 2fe847e7be7..2d14d898da9 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -25,6 +25,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "machmode.h" #include "version.h" #include "input.h" +#include "statistics.h" /* Codes of tree nodes */ @@ -2066,11 +2067,13 @@ extern size_t tree_size (tree); 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); +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 (tree); +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. */ @@ -2078,7 +2081,8 @@ extern tree copy_list (tree); /* Make a TREE_VEC. */ -extern tree make_tree_vec (int); +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 *. */ @@ -2124,11 +2128,17 @@ extern tree build_nt (enum tree_code, ...); #define _buildC2(x,a1,a2,a3,a4,a5,a6,a7,a8,a9,c,...) c #endif -extern tree build0 (enum tree_code, tree); -extern tree build1 (enum tree_code, tree, tree); -extern tree build2 (enum tree_code, tree, tree, tree); -extern tree build3 (enum tree_code, tree, tree, tree, tree); -extern tree build4 (enum tree_code, tree, tree, tree, tree, tree); +extern tree build0_stat (enum tree_code, tree MEM_STAT_DECL); +#define build0(c,t) build0_stat (c,t MEM_STAT_INFO) +extern tree build1_stat (enum tree_code, tree, tree MEM_STAT_DECL); +#define build1(c,t1,t2) build1_stat (c,t1,t2 MEM_STAT_INFO) +extern tree build2_stat (enum tree_code, tree, tree, tree MEM_STAT_DECL); +#define build2(c,t1,t2,t3) build2_stat (c,t1,t2,t3 MEM_STAT_INFO) +extern tree build3_stat (enum tree_code, tree, tree, tree, tree MEM_STAT_DECL); +#define build3(c,t1,t2,t3,t4) build3_stat (c,t1,t2,t3,t4 MEM_STAT_INFO) +extern tree build4_stat (enum tree_code, tree, tree, tree, tree, + tree MEM_STAT_DECL); +#define build4(c,t1,t2,t3,t4,t5) build4_stat (c,t1,t2,t3,t4,t5 MEM_STAT_INFO) extern tree build_int_2_wide (unsigned HOST_WIDE_INT, HOST_WIDE_INT); extern tree build_vector (tree, tree); @@ -2136,8 +2146,10 @@ extern tree build_constructor (tree, tree); 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 build_tree_list (tree, tree); -extern tree build_decl (enum tree_code, tree, tree); +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); @@ -2495,7 +2507,8 @@ extern tree chainon (tree, tree); /* Make a new TREE_LIST node from specified PURPOSE, VALUE and CHAIN. */ -extern tree tree_cons (tree, tree, tree); +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. */