Files
mercury/tools/item_stats
Zoltan Somogyi ecbe12cfa6 Provide a mechanism for gathering statistics about items.
compiler/prog_item_stats.m:
    New module to gather and print out statistics about items.

compiler/make_hlds_passes.m:
    Invoke the new module if this module was compiled with a trace flag
    that calls for this. (It is of course off by default.)

compiler/parse_tree.m:
    Include the new module.

compiler/notes/compiler_design.html:
    Document the new module, and improve the formatting of the documentation
    of related modules.

tools/item_stats:
    A new script to summarize the statistics gathered by prog_item_stats.m.

tools/sum_stats:
    A much earlier version of that script, which may be useful in other
    contexts.
2015-10-24 07:01:36 +11:00

185 lines
5.2 KiB
Bash
Executable File

#!/bin/sh
# vim: ts=4 sw=4 et ft=sh
#
# This script is intended to summarize the contents of the statistics files
# generated by compiler/prog_item_stats.m. These contain a few lines
# of the form
#
# MODULE modulename
#
# for context, but by far the bulk of their content (and all of their useful
# information) consists of lines of the form
#
# section item_or_goal_category count
#
# which give number of times a given kind of item or goal occurs in the given
# section.
#
# This script computes and prints the total count for each category in each
# section.
ignore_errors=1
print_zero=0
while test "$#" -gt 0
do
case "$1" in
-e)
# By default, we ignore malformed lines, which can happen when
# two or more compiler invocations print out their statistics at the
# same time. If the user specifies -e, we will print a message for
# each malformed line.
ignore_errors=0
shift
;;
-z)
# Normally, we don't print anything for item or goal categories
# that do not occur in a section. If the user specifies -z, we will
# print categories even if their total count is zero.
print_zero=1
shift
;;
*)
break
;;
esac
done
if test "$#" -eq 1
then
filename="$1"
else
echo "usage: item_stats [-e] [-z] stats_filename"
exit 1
fi
gawk -e '
{
if (NF == 2 && $1 == "MODULE") {
cur_module = $2;
} else if (NF == 3) {
section = $1;
category = $2;
count = $3;
sections[section] = 0;
sections["any_section"] = 0;
categories[category] = 0;
stats_total[section "@" category] += count;
stats_total["any_section" "@" category] += count;
if (count + 0 > stats_cmax[section "@" category]) {
stats_cmax[section "@" category] = count + 0;
}
if (count + 0 > stats_cmax["any_section" "@" category]) {
stats_cmax["any_section" "@" category] = count + 0;
}
} else {
if (! ignore_errors) {
printf("unexpected line in module %s: <%s>\n", cur_module, $0);
}
}
}
END {
for (section in sections) {
if (section == "src_int") {
sec_num = 1;
} else if (section == "src_impl") {
sec_num = 2;
} else if (section == "src_impl_sub") {
sec_num = 3;
} else if (section == "int_imported") {
sec_num = 11;
} else if (section == "int_used") {
sec_num = 12;
} else if (section == "int_abstract_imported") {
sec_num = 13;
} else if (section == "int_for_opt_imported") {
sec_num = 14;
} else if (section == "opt_imported") {
sec_num = 21;
} else if (section == "any_section") {
sec_num = 31;
} else {
sec_num = 41;
}
for (category in categories) {
if (substr(category, 1, 5) == "item_") {
cat_kind = 1;
} else {
cat_kind = 2;
}
total = stats_total[section "@" category];
cmax = stats_cmax[section "@" category];
if (total > 0 || print_zero) {
printf("%d %d %s %s %d% d\n",
sec_num, cat_kind, section, category, total, cmax);
}
}
}
}
' print_zero="${print_zero}" ignore_errors="${ignore_errors}" < "${filename}" |
sort --key=1n,1 --key=2n,2 --key=5nr,5 |
tee .z2 |
gawk '
{
if (NF +1 > 0 && $1 == "unexpected") {
printf("%s\n", $0);
} else if (NF == 6) {
sec_num = $1;
cat_kind = $2;
section = $3;
category = $4;
count = $5;
cmax = $6;
if (! printed_header) {
printf("%-22s %-22s %15s %15s\n",
"section", "category", "total", "maximum");
printed_header = 1;
}
if (sec_num != prev_sec_num) {
printf("\n");
prev_sec_num = sec_num;
prev_cat_kind = cat_kind;
} else if (cat_kind != prev_cat_kind) {
printf("\n");
prev_cat_kind = cat_kind;
}
# We put commas between thousands, because without this,
# it is more difficult to compare counts in different sections.
count_str = thousands(count);
cmax_str = thousands(cmax);
printf("%-22s %-22s %15s %15s\n",
section, category, count_str, cmax_str);
}
}
function thousands(n)
{
str = "";
if (sprintf("%d", n) == "0") {
str = "0";
} else {
while (1) {
last = n % 1000;
prev = n / 1000;
if (sprintf("%d", prev) == "0") {
str = sprintf("%d", last) str;
break;
} else {
str = "," sprintf("%03d", last) str;
}
n = prev;
}
}
return str;
}
'