summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2000-08-29 20:57:11 +0000
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2000-08-29 20:57:11 +0000
commit2a8997e85cd4ad92644cad6932aa2b5e2115d610 (patch)
tree467a74cb03ab3a07329d87c25f28745ba9ed5e7f
parent14da2a08382098d9b235ebe6ab1d02e5c3cb24d0 (diff)
downloadgcc-2a8997e85cd4ad92644cad6932aa2b5e2115d610.tar.gz
* flags.h (time_report, mem_report): New global flags.
* toplev.c: Define time_report and mem_report. (f_options): Add -ftime-report and -fmem-report. (compile_file): Turn on time_report if quiet_flag is off. Call ggc_print_statistics at very end if mem_report is on. * timevar.c (TIMEVAR_ENABLE): Examine time_report, not quiet_flag. * ggc-common.c (ggc_print_statistics): Rename to ggc_print_common_statistics; all callers changed. Scale quantities above 10K to kilobytes and above 10M to megabytes. * ggc-page.c (ggc_page_print_statistics): Rename to ggc_print_statistics. Report memory consumed by internal data structures for each allocation bucket. Scale quantities above 10K to kilobytes and above 10M to megabytes. * ggc-simple.c: Prototype debug_ggc_tree to avoid warning. Cast PTR_KEY(p) to unsigned long in fprintf call to avoid warning. Define tally_leaves always. (ggc_print_statistics): New function. * ggc.h: Adjust for renamed functions. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36049 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/flags.h9
-rw-r--r--gcc/ggc-common.c35
-rw-r--r--gcc/ggc-page.c40
-rw-r--r--gcc/ggc-simple.c52
-rw-r--r--gcc/ggc.h4
-rw-r--r--gcc/timevar.c2
-rw-r--r--gcc/toplev.c25
8 files changed, 153 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ee5b233ab43..de89784b7a1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,25 @@
+2000-08-29 Zack Weinberg <zack@wolery.cumb.org>
+
+ * flags.h (time_report, mem_report): New global flags.
+ * toplev.c: Define time_report and mem_report.
+ (f_options): Add -ftime-report and -fmem-report.
+ (compile_file): Turn on time_report if quiet_flag is off.
+ Call ggc_print_statistics at very end if mem_report is on.
+ * timevar.c (TIMEVAR_ENABLE): Examine time_report, not quiet_flag.
+
+ * ggc-common.c (ggc_print_statistics): Rename to
+ ggc_print_common_statistics; all callers changed. Scale
+ quantities above 10K to kilobytes and above 10M to megabytes.
+ * ggc-page.c (ggc_page_print_statistics): Rename to
+ ggc_print_statistics. Report memory consumed by internal data
+ structures for each allocation bucket. Scale quantities above
+ 10K to kilobytes and above 10M to megabytes.
+ * ggc-simple.c: Prototype debug_ggc_tree to avoid warning.
+ Cast PTR_KEY(p) to unsigned long in fprintf call to avoid warning.
+ Define tally_leaves always.
+ (ggc_print_statistics): New function.
+ * ggc.h: Adjust for renamed functions.
+
Wed Aug 30 00:11:42 2000 Denis Chertykov <denisc@overta.ru>
* config/avr/avr.md ("*movsf","*movsi"): Pass NULL to
diff --git a/gcc/flags.h b/gcc/flags.h
index a294c37de20..21f9237c629 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -63,6 +63,15 @@ extern int optimize_size;
extern int quiet_flag;
+/* Print times taken by the various passes. -ftime-report. */
+
+extern int time_report;
+
+/* Print memory still in use at end of compilation (which may have little
+ to do with peak memory consumption). -fmem-report. */
+
+extern int mem_report;
+
/* Don't print warning messages. -w. */
extern int inhibit_warnings;
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index 2fa3d101493..5f6f0c01fc5 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -599,9 +599,15 @@ ggc_alloc_cleared (size)
}
/* Print statistics that are independent of the collector in use. */
+#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
+ ? (x) \
+ : ((x) < 1024*1024*10 \
+ ? (x) / 1024 \
+ : (x) / (1024*1024))))
+#define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
void
-ggc_print_statistics (stream, stats)
+ggc_print_common_statistics (stream, stats)
FILE *stream;
ggc_statistics *stats;
{
@@ -627,43 +633,44 @@ ggc_print_statistics (stream, stats)
}
/* Print the statistics for trees. */
- fprintf (stream, "%-22s%-16s%-16s%-7s\n", "Code",
+ fprintf (stream, "\n%-17s%10s %16s %10s\n", "Tree",
"Number", "Bytes", "% Total");
for (code = 0; code < MAX_TREE_CODES; ++code)
if (ggc_stats->num_trees[code])
{
- fprintf (stream, "%s%*s%-15u %-15lu %7.3f\n",
+ fprintf (stream, "%-17s%10u%16ld%c %10.3f\n",
tree_code_name[code],
- 22 - (int) strlen (tree_code_name[code]), "",
ggc_stats->num_trees[code],
- (unsigned long) ggc_stats->size_trees[code],
+ SCALE (ggc_stats->size_trees[code]),
+ LABEL (ggc_stats->size_trees[code]),
(100 * ((double) ggc_stats->size_trees[code])
/ ggc_stats->total_size_trees));
}
fprintf (stream,
- "%-22s%-15u %-15lu\n", "Total",
+ "%-17s%10u%16ld%c\n", "Total",
ggc_stats->total_num_trees,
- (unsigned long) ggc_stats->total_size_trees);
+ SCALE (ggc_stats->total_size_trees),
+ LABEL (ggc_stats->total_size_trees));
/* Print the statistics for RTL. */
- fprintf (stream, "\n%-22s%-16s%-16s%-7s\n", "Code",
+ fprintf (stream, "\n%-17s%10s %16s %10s\n", "RTX",
"Number", "Bytes", "% Total");
for (code = 0; code < NUM_RTX_CODE; ++code)
if (ggc_stats->num_rtxs[code])
{
- fprintf (stream, "%s%*s%-15u %-15lu %7.3f\n",
+ fprintf (stream, "%-17s%10u%16ld%c %10.3f\n",
rtx_name[code],
- 22 - (int) strlen (rtx_name[code]), "",
ggc_stats->num_rtxs[code],
- (unsigned long) ggc_stats->size_rtxs[code],
+ SCALE (ggc_stats->size_rtxs[code]),
+ LABEL (ggc_stats->size_rtxs[code]),
(100 * ((double) ggc_stats->size_rtxs[code])
/ ggc_stats->total_size_rtxs));
}
fprintf (stream,
- "%-22s%-15u %-15lu\n", "Total",
+ "%-17s%10u%16ld%c\n", "Total",
ggc_stats->total_num_rtxs,
- (unsigned long) ggc_stats->total_size_rtxs);
-
+ SCALE (ggc_stats->total_size_rtxs),
+ LABEL (ggc_stats->total_size_rtxs));
/* Don't gather statistics any more. */
ggc_stats = NULL;
diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c
index b395aaaf92e..8744129aaaf 100644
--- a/gcc/ggc-page.c
+++ b/gcc/ggc-page.c
@@ -1162,12 +1162,19 @@ ggc_collect ()
}
/* Print allocation statistics. */
+#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
+ ? (x) \
+ : ((x) < 1024*1024*10 \
+ ? (x) / 1024 \
+ : (x) / (1024*1024))))
+#define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
void
-ggc_page_print_statistics ()
+ggc_print_statistics ()
{
struct ggc_statistics stats;
unsigned int i;
+ size_t total_overhead = 0;
/* Clear the statistics. */
memset (&stats, 0, sizeof (stats));
@@ -1176,7 +1183,7 @@ ggc_page_print_statistics ()
G.allocated_last_gc = 0;
/* Collect and print the statistics common across collectors. */
- ggc_print_statistics (stderr, &stats);
+ ggc_print_common_statistics (stderr, &stats);
/* Release free pages so that we will not count the bytes allocated
there as part of the total allocated memory. */
@@ -1184,34 +1191,41 @@ ggc_page_print_statistics ()
/* Collect some information about the various sizes of
allocation. */
- fprintf (stderr, "\n%-4s%-16s%-16s\n", "Log", "Allocated", "Used");
+ fprintf (stderr, "\n%-5s %10s %10s %10s\n",
+ "Log", "Allocated", "Used", "Overhead");
for (i = 0; i < HOST_BITS_PER_PTR; ++i)
{
page_entry *p;
size_t allocated;
size_t in_use;
+ size_t overhead;
/* Skip empty entries. */
if (!G.pages[i])
continue;
- allocated = in_use = 0;
+ overhead = allocated = in_use = 0;
/* Figure out the total number of bytes allocated for objects of
- this size, and how many of them are actually in use. */
+ this size, and how many of them are actually in use. Also figure
+ out how much memory the page table is using. */
for (p = G.pages[i]; p; p = p->next)
{
allocated += p->bytes;
in_use +=
(OBJECTS_PER_PAGE (i) - p->num_free_objects) * (1 << i);
+
+ overhead += (sizeof (page_entry) - sizeof (long)
+ + BITMAP_SIZE (OBJECTS_PER_PAGE (i) + 1));
}
- fprintf (stderr, "%-3d %-15lu %-15lu\n", i,
- (unsigned long) allocated, (unsigned long) in_use);
+ fprintf (stderr, "%-5d %10ld%c %10ld%c %10ld%c\n", i,
+ SCALE (allocated), LABEL (allocated),
+ SCALE (in_use), LABEL (in_use),
+ SCALE (overhead), LABEL (overhead));
+ total_overhead += overhead;
}
-
- /* Print out some global information. */
- fprintf (stderr, "\nTotal bytes marked: %lu\n",
- (unsigned long) G.allocated);
- fprintf (stderr, "Total bytes mapped: %lu\n",
- (unsigned long) G.bytes_mapped);
+ fprintf (stderr, "%-5s %10ld%c %10ld%c %10ld%c\n", "Total",
+ SCALE (G.bytes_mapped), LABEL (G.bytes_mapped),
+ SCALE (G.allocated), LABEL(G.allocated),
+ SCALE (total_overhead), LABEL (total_overhead));
}
diff --git a/gcc/ggc-simple.c b/gcc/ggc-simple.c
index 86afaf17e12..7822bb916f3 100644
--- a/gcc/ggc-simple.c
+++ b/gcc/ggc-simple.c
@@ -137,10 +137,13 @@ static void clear_marks PARAMS ((struct ggc_mem *));
static void sweep_objs PARAMS ((struct ggc_mem **));
static void ggc_pop_context_1 PARAMS ((struct ggc_mem *, int));
+/* For use from debugger. */
+extern void debug_ggc_tree PARAMS ((struct ggc_mem *, int));
+
#ifdef GGC_BALANCE
extern void debug_ggc_balance PARAMS ((void));
-static void tally_leaves PARAMS ((struct ggc_mem *, int, size_t *, size_t *));
#endif
+static void tally_leaves PARAMS ((struct ggc_mem *, int, size_t *, size_t *));
/* Insert V into the search tree. */
@@ -434,7 +437,7 @@ debug_ggc_tree (p, indent)
for (i = 0; i < indent; ++i)
putc (' ', stderr);
- fprintf (stderr, "%lx %p\n", PTR_KEY (p), p);
+ fprintf (stderr, "%lx %p\n", (unsigned long)PTR_KEY (p), p);
if (p->sub[1])
debug_ggc_tree (p->sub[1], indent + 1);
@@ -460,7 +463,9 @@ debug_ggc_balance ()
(float)sumdepth / (float)nleaf,
log ((double) G.objects) / M_LN2);
}
+#endif
+/* Used by debug_ggc_balance, and also by ggc_print_statistics. */
static void
tally_leaves (x, depth, nleaf, sumdepth)
struct ggc_mem *x;
@@ -481,4 +486,45 @@ tally_leaves (x, depth, nleaf, sumdepth)
tally_leaves (x->sub[1], depth + 1, nleaf, sumdepth);
}
}
-#endif
+
+#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
+ ? (x) \
+ : ((x) < 1024*1024*10 \
+ ? (x) / 1024 \
+ : (x) / (1024*1024))))
+#define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
+
+/* Report on GC memory usage. */
+void
+ggc_print_statistics ()
+{
+ struct ggc_statistics stats;
+ size_t nleaf = 0, sumdepth = 0;
+
+ /* Clear the statistics. */
+ memset (&stats, 0, sizeof (stats));
+
+ /* Make sure collection will really occur. */
+ G.allocated_last_gc = 0;
+
+ /* Collect and print the statistics common across collectors. */
+ ggc_print_common_statistics (stderr, &stats);
+
+ /* Report on tree balancing. */
+ tally_leaves (G.root, 0, &nleaf, &sumdepth);
+
+ fprintf (stderr, "\n\
+Total internal data (bytes)\t%ld%c\n\
+Number of leaves in tree\t%d\n\
+Average leaf depth\t\t%.1f\n",
+ SCALE(G.objects * offsetof (struct ggc_mem, u)),
+ LABEL(G.objects * offsetof (struct ggc_mem, u)),
+ nleaf, (double)sumdepth / (double)nleaf);
+
+ /* Report overall memory usage. */
+ fprintf (stderr, "\n\
+Total objects allocated\t\t%d\n\
+Total memory in GC arena\t%ld%c\n",
+ G.objects,
+ SCALE(G.allocated), LABEL(G.allocated));
+}
diff --git a/gcc/ggc.h b/gcc/ggc.h
index 81e7012dcd6..8796fd1a830 100644
--- a/gcc/ggc.h
+++ b/gcc/ggc.h
@@ -206,7 +206,7 @@ size_t ggc_get_size PARAMS ((const void *));
/* Used by the various collectors to gather and print statistics that
do not depend on the collector in use. */
-void ggc_print_statistics PARAMS ((FILE *, ggc_statistics *));
+void ggc_print_common_statistics PARAMS ((FILE *, ggc_statistics *));
/* Print allocation statistics. */
-extern void ggc_page_print_statistics PARAMS ((void));
+extern void ggc_print_statistics PARAMS ((void));
diff --git a/gcc/timevar.c b/gcc/timevar.c
index 6635c1d13dc..5a79fa7ccab 100644
--- a/gcc/timevar.c
+++ b/gcc/timevar.c
@@ -40,7 +40,7 @@ extern int getrusage PARAMS ((int, struct rusage *));
/* See timevar.h for an explanation of timing variables. */
/* This macro evaluates to non-zero if timing variables are enabled. */
-#define TIMEVAR_ENABLE (!quiet_flag)
+#define TIMEVAR_ENABLE (time_report)
/* A timing variable. */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 8fac38b1ca0..b14a1ee42a9 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -464,10 +464,19 @@ int pedantic = 0;
int in_system_header = 0;
-/* Don't print functions as they are compiled and don't print
- times taken by the various passes. -quiet. */
+/* Don't print functions as they are compiled. -quiet. */
int quiet_flag = 0;
+
+/* Print times taken by the various passes. -ftime-report. */
+
+int time_report = 0;
+
+/* Print memory still in use at end of compilation (which may have little
+ to do with peak memory consumption). -fmem-report. */
+
+int mem_report = 0;
+
/* -f flags. */
@@ -1122,7 +1131,11 @@ lang_independent_options f_options[] =
{"bounds-check", &flag_bounds_check, 1,
"Generate code to check bounds before dereferencing pointers and arrays" },
{"single-precision-constant", &flag_single_precision_constant, 1,
- "Convert floating point constant to single precision constant"}
+ "Convert floating point constant to single precision constant"},
+ {"time-report", &time_report,
+ "Report time taken by each compiler pass at end of run"},
+ {"mem-report", &mem_report,
+ "Report on permanent memory allocation at end of run"},
};
/* Table of language-specific options. */
@@ -2101,6 +2114,9 @@ compile_file (name)
if (dump_base_name == 0)
dump_base_name = name ? name : "gccdump";
+ if (! quiet_flag)
+ time_report = 1;
+
/* Start timing total execution time. */
init_timevar ();
@@ -2464,6 +2480,9 @@ compile_file (name)
}
}
+ if (mem_report)
+ ggc_print_statistics ();
+
/* Free up memory for the benefit of leak detectors. */
free_reg_info ();