mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-08 18:34:00 +00:00
Estimated hours taken: 60 Branches: main Implement coverage testing. The output format is a bit crude, but people have been asking for this capability. The main problem tackled in this diff is that coverage testing requires gathering information from a lot of program executions, and the execution count files for all these executions require a huge amount of disk space. We now therefore put a limit on the number of files we keep; when this limit is exceeded, the program execution that reaches the limit will automatically summarize all these files back into a single file before it exits. This diff also tackles the same problem along a different axis by changing the format of execution count files to make them smaller. One way is to factor out and represent just once some information that is common to many procedures: the file name and the module name. Another is to abbreviate some keywords, e.g. "fproc" instead of "proc function". The third is not to write out the defining module's name unless it differs from the declaring module's name, which it almost never does. (The two differ only when the compiler is invoked with intermodule optimization, and creates a specialized version of a predicate in a module other than its home module.) Since we are changing the trace count file format anyway, make another change useful for coverage testing: record the entire provenance of the trace counts in the file, including the name of the program and what files went into unions and diffs of trace count files. When doing coverage testing of the compiler, the compiler *must* be in a debug grade. However, the tools for summarizing trace files, invoked from the compiler executable when the compiler is being coverage tested, *cannot* be in debug grade, because debug grade disables tail recursion, and without tail recursion the summarization program runs out of stack space. This diff therefore arranges for the slice directory to not be affected by the parameters applying to the rest of the workspace (including the top level Mmake.params). Mmakefile: Don't apply the top level mmake's parameters to recursive mmakes in the slice directory. Factor out some common code. configure.in: Require that the installed compiler contain the renamed standard library function names installed by my diff on Sep 20, since the slice directory needs them, and cannot get them from the workspace. mdbcomp/trace_counts.m: Update the parsing code to parse the new format for trace count files, and update the code for writing out trace counts to generate the new format. Replace the proc_label_and_filename type with the proc_label_in_context type, which makes it easier to keep track of the current module as well as the current file (this is required by the new, more compact format for trace count files). When considering the union of multiple trace counts files, keep track of whether they contained all counts or just the nonzero counts. This requires keeping track of this info for single files as well. Provide ways to represent and to compute differences between trace count files, to support the new program in slice/mtc_diff.m. mdbcomp/slice_and_dice.m: Reformat to conform to our Mercury style guide. Conform to the change to trace_counts.m. compiler/tupling.m: Conform to the change to mdbcomp. runtime/mercury_wrapper.c: Implement the new option values used to implement coverage testing. These allow control of the limit on the number of execution count files, and collecting execution counts only from a specified executable. Add MR_ prefixes. runtime/mercury_trace_base.[ch]: Provide the mechanism for summarizing execution counts when we reach the limit on the number of execution counts files. Update the code that writes out trace counts files to generate the new format for trace counts files. Make this code take the boolean that says whether to include labels with zero counts in the output as an explicit parameter, not as a global variable. Break up an excessively large function. scripts/mtc: Add the options needed to control the process of automatic summarization of trace counts files. slice/.mgnuc_copts: slice/.mgnuc_opts: slice/SLICE_FLAGS.in: Make these files empty, since we don't want to refer to the rest of the workspace. (We could delete them as well, but CVS doesn't handle resurrection of deleted files very well, and we don't want to burn any bridges.) slice/Mmakefile: Add the new executables, and make the code in this directory independent of the other directories in the workspace. Since we need the code of the modules in the mdbcomp directory but don't want to link to the object files in that directory (since the grades may differ), make copies of those modules in this directory. slice/mcov.m: Add this module, the code for the Mercury coverage test tool. slice/mtc_diff.m: Add this module, the code for computing the diff between two trace counts files. The intended use is to compare two trace counts files dumped at different stages of execution. (Since foreign_procs can be used to invoke the C functions in the runtime that write out the trace counts files in the middle of a program's execution, not just the end.) slice/mdice.m: slice/mslice.m: slice/mtc_union.m: Convert to four space indentation. tools/bootcheck: Since the slice directory's grade is independent of the grade of the other directories, don't copy it to the stage2 and stage3 by default. If it is copied, then still compile it (and otherwise handle it) separate from the other directories. Add an option for gathering coverage test data during bootchecking.
181 lines
4.5 KiB
Bash
Executable File
181 lines
4.5 KiB
Bash
Executable File
#!/bin/sh
|
|
#-----------------------------------------------------------------------------#
|
|
# Copyright (C) 2005-2006 The University of Melbourne.
|
|
# This file may only be copied under the terms of the GNU General
|
|
# Public License - see the file COPYING in the Mercury distribution.
|
|
#-----------------------------------------------------------------------------#
|
|
#
|
|
# IMPORTANT: the manpage is produced automatically from this help
|
|
# message, so if you change the help message, don't forget to check
|
|
# that the manpage still looks OK.
|
|
Help="\
|
|
Name: mtc - gathering trace counts from Mercury programs
|
|
Usage: mtc [options] <executable> [<args>]...
|
|
Description:
|
|
\`mtc' invokes the specified command \`<executable> <args>...'.
|
|
If that command is a Mercury program that was compiled with debugging
|
|
enabled (e.g. using the \`--debug' option), or if that command invokes
|
|
such a program, then mtc will cause the program to count the
|
|
number of times each event is executed, and to write out that data
|
|
to a file. Otherwise, mtc will execute the command line as if the
|
|
mtc prefix weren't there.
|
|
|
|
Options:
|
|
-c, --coverage-test
|
|
Ordinarily, the generated trace count file contains only
|
|
nonzero trace counts. This option causes even zero counts
|
|
to be written out, since coverage testing needs to know
|
|
which parts of the code are not executed.
|
|
|
|
-o <filename>, --output-file <filename>
|
|
Save the generated trace counts to <filename>.
|
|
|
|
-s <basename>, --summary-file=<basename>
|
|
If this option is given, the trace counts are put into a new
|
|
file whose name is <basename>.N for a small integer N, choosing
|
|
N to be the smallest integer for which <basename>.N doesn't yet
|
|
exist. If this is not initially possible for a small enough N
|
|
(due probably to previous runs), then the program will replace
|
|
all of the <basename>.N files with a summary named just
|
|
<basename>; if <basename> existed already, it will be included
|
|
in the summary as well. This way, at the end of a sequence of
|
|
runs of the program, the command \"mtc_union <basename>*\"
|
|
will compute a summary of all the trace counts files.
|
|
|
|
--summary-count=<maxN>
|
|
Gives the maximum value of N to use with --summary-file.
|
|
|
|
--help
|
|
Display this message.
|
|
|
|
If neither the -o nor the -s option is given, then the trace counts are put
|
|
into a file whose name is automatically generated. This name will start with
|
|
the prefix ".mercury_trace_counts", followed by a mangled version of the
|
|
name of the executable, and then the process id.
|
|
|
|
The -o and -s options are mutually exclusive.
|
|
|
|
Environment variables:
|
|
MERCURY_OPTIONS.
|
|
"
|
|
|
|
#-----------------------------------------------------------------------------#
|
|
#
|
|
# process the command line options
|
|
#
|
|
|
|
coverage_test=false
|
|
output_file=""
|
|
summary_file=""
|
|
summary_limit=""
|
|
|
|
while test "$#" -gt 0
|
|
do
|
|
case "$1" in
|
|
-c|--coverage-test)
|
|
coverage_test=true
|
|
;;
|
|
|
|
--help)
|
|
echo "$Help"
|
|
exit 0
|
|
;;
|
|
|
|
-o|--output-file)
|
|
output_file="$2";
|
|
shift
|
|
;;
|
|
|
|
-o*)
|
|
output_file="`expr $1 : '-o\(.*\)'`"
|
|
;;
|
|
|
|
--output-file=*)
|
|
output_file="`expr $1 : '--output-file=\(.*\)'`"
|
|
;;
|
|
|
|
-s|--summary-file)
|
|
summary_file="$2"
|
|
shift
|
|
;;
|
|
|
|
-s*)
|
|
summary_file="`expr $1 : '-s\(.*\)'`"
|
|
;;
|
|
|
|
--summary-file=*)
|
|
summary_file="`expr $1 : '--summary-file=\(.*\)'`"
|
|
;;
|
|
|
|
--summary-limit)
|
|
summary_limit="$2"
|
|
shift
|
|
;;
|
|
|
|
--summary-limit=*)
|
|
summary_limit="`expr $1 : '--summary-limit=\(.*\)'`"
|
|
;;
|
|
|
|
--)
|
|
shift
|
|
break
|
|
;;
|
|
|
|
-*)
|
|
echo "$0: unknown option \`$1'" 1>&2
|
|
exit 1
|
|
;;
|
|
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
case $# in
|
|
0) echo "Usage: mtc [options] <executable> [<arg> ...]" 1>&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if test "$output_file" != "" -a "$summary_file" != ""
|
|
then
|
|
echo "The options --output-file and --summary-file are incompatible."
|
|
exit 1
|
|
fi
|
|
|
|
#-----------------------------------------------------------------------------#
|
|
#
|
|
# Set the environment variables used by the Mercury runtime to the appropriate
|
|
# values to enable the gathering of trace counts, and then finally use
|
|
# $invoke_cmd to invoke the command.
|
|
#
|
|
|
|
MERCURY_OPTIONS="$MERCURY_OPTIONS --trace-count"
|
|
|
|
if "$coverage_test"
|
|
then
|
|
MERCURY_OPTIONS="$MERCURY_OPTIONS --coverage-test"
|
|
fi
|
|
|
|
if test "$summary_file" != ""
|
|
then
|
|
MERCURY_OPTIONS="$MERCURY_OPTIONS --trace-count-summary-file=$summary_file"
|
|
fi
|
|
|
|
if test "$summary_limit" != ""
|
|
then
|
|
MERCURY_OPTIONS="$MERCURY_OPTIONS --trace-count-summary-limit=$summary_limit"
|
|
fi
|
|
|
|
if test "$output_file" != ""
|
|
then
|
|
MERCURY_OPTIONS="$MERCURY_OPTIONS --tc-output-file $output_file"
|
|
fi
|
|
|
|
export MERCURY_OPTIONS
|
|
exec "$@"
|
|
|
|
#-----------------------------------------------------------------------------#
|