Commit 2a8997e8 authored by zack's avatar zack
Browse files

* 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
parent 14da2a08
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
......
......@@ -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;
......
......@@ -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;
......
......@@ -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));
}
......@@ -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));
}
......@@ -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));
......@@ -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. */
......
......@@ -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 ();
......
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