Commit fba0bfd4 by Zack Weinberg Committed by Zack Weinberg

flags.h (time_report, mem_report): New global flags.

	* 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.

From-SVN: r36049
parent 612105a6
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> Wed Aug 30 00:11:42 2000 Denis Chertykov <denisc@overta.ru>
* config/avr/avr.md ("*movsf","*movsi"): Pass NULL to * config/avr/avr.md ("*movsf","*movsi"): Pass NULL to
......
...@@ -63,6 +63,15 @@ extern int optimize_size; ...@@ -63,6 +63,15 @@ extern int optimize_size;
extern int quiet_flag; 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. */ /* Don't print warning messages. -w. */
extern int inhibit_warnings; extern int inhibit_warnings;
......
...@@ -599,9 +599,15 @@ ggc_alloc_cleared (size) ...@@ -599,9 +599,15 @@ ggc_alloc_cleared (size)
} }
/* Print statistics that are independent of the collector in use. */ /* 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 void
ggc_print_statistics (stream, stats) ggc_print_common_statistics (stream, stats)
FILE *stream; FILE *stream;
ggc_statistics *stats; ggc_statistics *stats;
{ {
...@@ -627,43 +633,44 @@ ggc_print_statistics (stream, stats) ...@@ -627,43 +633,44 @@ ggc_print_statistics (stream, stats)
} }
/* Print the statistics for trees. */ /* 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"); "Number", "Bytes", "% Total");
for (code = 0; code < MAX_TREE_CODES; ++code) for (code = 0; code < MAX_TREE_CODES; ++code)
if (ggc_stats->num_trees[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], tree_code_name[code],
22 - (int) strlen (tree_code_name[code]), "",
ggc_stats->num_trees[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]) (100 * ((double) ggc_stats->size_trees[code])
/ ggc_stats->total_size_trees)); / ggc_stats->total_size_trees));
} }
fprintf (stream, fprintf (stream,
"%-22s%-15u %-15lu\n", "Total", "%-17s%10u%16ld%c\n", "Total",
ggc_stats->total_num_trees, 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. */ /* 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"); "Number", "Bytes", "% Total");
for (code = 0; code < NUM_RTX_CODE; ++code) for (code = 0; code < NUM_RTX_CODE; ++code)
if (ggc_stats->num_rtxs[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], rtx_name[code],
22 - (int) strlen (rtx_name[code]), "",
ggc_stats->num_rtxs[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]) (100 * ((double) ggc_stats->size_rtxs[code])
/ ggc_stats->total_size_rtxs)); / ggc_stats->total_size_rtxs));
} }
fprintf (stream, fprintf (stream,
"%-22s%-15u %-15lu\n", "Total", "%-17s%10u%16ld%c\n", "Total",
ggc_stats->total_num_rtxs, 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. */ /* Don't gather statistics any more. */
ggc_stats = NULL; ggc_stats = NULL;
......
...@@ -1162,12 +1162,19 @@ ggc_collect () ...@@ -1162,12 +1162,19 @@ ggc_collect ()
} }
/* Print allocation statistics. */ /* 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 void
ggc_page_print_statistics () ggc_print_statistics ()
{ {
struct ggc_statistics stats; struct ggc_statistics stats;
unsigned int i; unsigned int i;
size_t total_overhead = 0;
/* Clear the statistics. */ /* Clear the statistics. */
memset (&stats, 0, sizeof (stats)); memset (&stats, 0, sizeof (stats));
...@@ -1176,7 +1183,7 @@ ggc_page_print_statistics () ...@@ -1176,7 +1183,7 @@ ggc_page_print_statistics ()
G.allocated_last_gc = 0; G.allocated_last_gc = 0;
/* Collect and print the statistics common across collectors. */ /* 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 /* Release free pages so that we will not count the bytes allocated
there as part of the total allocated memory. */ there as part of the total allocated memory. */
...@@ -1184,34 +1191,41 @@ ggc_page_print_statistics () ...@@ -1184,34 +1191,41 @@ ggc_page_print_statistics ()
/* Collect some information about the various sizes of /* Collect some information about the various sizes of
allocation. */ 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) for (i = 0; i < HOST_BITS_PER_PTR; ++i)
{ {
page_entry *p; page_entry *p;
size_t allocated; size_t allocated;
size_t in_use; size_t in_use;
size_t overhead;
/* Skip empty entries. */ /* Skip empty entries. */
if (!G.pages[i]) if (!G.pages[i])
continue; continue;
allocated = in_use = 0; overhead = allocated = in_use = 0;
/* Figure out the total number of bytes allocated for objects of /* 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) for (p = G.pages[i]; p; p = p->next)
{ {
allocated += p->bytes; allocated += p->bytes;
in_use += in_use +=
(OBJECTS_PER_PAGE (i) - p->num_free_objects) * (1 << i); (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, fprintf (stderr, "%-5d %10ld%c %10ld%c %10ld%c\n", i,
(unsigned long) allocated, (unsigned long) in_use); SCALE (allocated), LABEL (allocated),
SCALE (in_use), LABEL (in_use),
SCALE (overhead), LABEL (overhead));
total_overhead += overhead;
} }
fprintf (stderr, "%-5s %10ld%c %10ld%c %10ld%c\n", "Total",
/* Print out some global information. */ SCALE (G.bytes_mapped), LABEL (G.bytes_mapped),
fprintf (stderr, "\nTotal bytes marked: %lu\n", SCALE (G.allocated), LABEL(G.allocated),
(unsigned long) G.allocated); SCALE (total_overhead), LABEL (total_overhead));
fprintf (stderr, "Total bytes mapped: %lu\n",
(unsigned long) G.bytes_mapped);
} }
...@@ -137,10 +137,13 @@ static void clear_marks PARAMS ((struct ggc_mem *)); ...@@ -137,10 +137,13 @@ static void clear_marks PARAMS ((struct ggc_mem *));
static void sweep_objs PARAMS ((struct ggc_mem **)); static void sweep_objs PARAMS ((struct ggc_mem **));
static void ggc_pop_context_1 PARAMS ((struct ggc_mem *, int)); 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 #ifdef GGC_BALANCE
extern void debug_ggc_balance PARAMS ((void)); extern void debug_ggc_balance PARAMS ((void));
static void tally_leaves PARAMS ((struct ggc_mem *, int, size_t *, size_t *));
#endif #endif
static void tally_leaves PARAMS ((struct ggc_mem *, int, size_t *, size_t *));
/* Insert V into the search tree. */ /* Insert V into the search tree. */
...@@ -434,7 +437,7 @@ debug_ggc_tree (p, indent) ...@@ -434,7 +437,7 @@ debug_ggc_tree (p, indent)
for (i = 0; i < indent; ++i) for (i = 0; i < indent; ++i)
putc (' ', stderr); 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]) if (p->sub[1])
debug_ggc_tree (p->sub[1], indent + 1); debug_ggc_tree (p->sub[1], indent + 1);
...@@ -460,7 +463,9 @@ debug_ggc_balance () ...@@ -460,7 +463,9 @@ debug_ggc_balance ()
(float)sumdepth / (float)nleaf, (float)sumdepth / (float)nleaf,
log ((double) G.objects) / M_LN2); log ((double) G.objects) / M_LN2);
} }
#endif
/* Used by debug_ggc_balance, and also by ggc_print_statistics. */
static void static void
tally_leaves (x, depth, nleaf, sumdepth) tally_leaves (x, depth, nleaf, sumdepth)
struct ggc_mem *x; struct ggc_mem *x;
...@@ -481,4 +486,45 @@ tally_leaves (x, depth, nleaf, sumdepth) ...@@ -481,4 +486,45 @@ tally_leaves (x, depth, nleaf, sumdepth)
tally_leaves (x->sub[1], depth + 1, 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));
}
...@@ -206,7 +206,7 @@ size_t ggc_get_size PARAMS ((const void *)); ...@@ -206,7 +206,7 @@ size_t ggc_get_size PARAMS ((const void *));
/* Used by the various collectors to gather and print statistics that /* Used by the various collectors to gather and print statistics that
do not depend on the collector in use. */ 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. */ /* Print allocation statistics. */
extern void ggc_page_print_statistics PARAMS ((void)); extern void ggc_print_statistics PARAMS ((void));
...@@ -40,7 +40,7 @@ extern int getrusage PARAMS ((int, struct rusage *)); ...@@ -40,7 +40,7 @@ extern int getrusage PARAMS ((int, struct rusage *));
/* See timevar.h for an explanation of timing variables. */ /* See timevar.h for an explanation of timing variables. */
/* This macro evaluates to non-zero if timing variables are enabled. */ /* This macro evaluates to non-zero if timing variables are enabled. */
#define TIMEVAR_ENABLE (!quiet_flag) #define TIMEVAR_ENABLE (time_report)
/* A timing variable. */ /* A timing variable. */
......
...@@ -464,10 +464,19 @@ int pedantic = 0; ...@@ -464,10 +464,19 @@ int pedantic = 0;
int in_system_header = 0; int in_system_header = 0;
/* Don't print functions as they are compiled and don't print /* Don't print functions as they are compiled. -quiet. */
times taken by the various passes. -quiet. */
int quiet_flag = 0; 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. */ /* -f flags. */
...@@ -1122,7 +1131,11 @@ lang_independent_options f_options[] = ...@@ -1122,7 +1131,11 @@ lang_independent_options f_options[] =
{"bounds-check", &flag_bounds_check, 1, {"bounds-check", &flag_bounds_check, 1,
"Generate code to check bounds before dereferencing pointers and arrays" }, "Generate code to check bounds before dereferencing pointers and arrays" },
{"single-precision-constant", &flag_single_precision_constant, 1, {"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. */ /* Table of language-specific options. */
...@@ -2101,6 +2114,9 @@ compile_file (name) ...@@ -2101,6 +2114,9 @@ compile_file (name)
if (dump_base_name == 0) if (dump_base_name == 0)
dump_base_name = name ? name : "gccdump"; dump_base_name = name ? name : "gccdump";
if (! quiet_flag)
time_report = 1;
/* Start timing total execution time. */ /* Start timing total execution time. */
init_timevar (); init_timevar ();
...@@ -2464,6 +2480,9 @@ compile_file (name) ...@@ -2464,6 +2480,9 @@ compile_file (name)
} }
} }
if (mem_report)
ggc_print_statistics ();
/* Free up memory for the benefit of leak detectors. */ /* Free up memory for the benefit of leak detectors. */
free_reg_info (); free_reg_info ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment