Files
mercury/tools/binary_step
Zoltan Somogyi 4fe703c7b9 Implement a more cache-friendly translation of lookup switches.
Estimated hours taken: 8
Branches: main

Implement a more cache-friendly translation of lookup switches. Previously,
for a switch such as the one in

	:- pred p(foo::in, string::out, bar::out, float::out) is semidet.

	p(d, "four", f1, 4.4).
	p(e, "five", f2, 5.5).
	p(f, "six", f4("hex"), 6.6).
	p(g, "seven", f5(77.7), 7.7).

we generated three static cells, one for each argument, and then indexed
into each one in turn to get the values of HeadVar__2, HeadVar__3 and
HeadVar__4. The different static cells each represent a column here.
Each of the loads accessing the columns will access a different cache block,
so with this technique we expect to get as many cache misses as there are
output variables.

This diff changes the code we generate to use a vector of static cells
where each cell represents a row. The assignments to the output variables
will now access the different fields of a row, which will be next to each
other. We thus expect only one cache miss irrespective of the number of output
variables, at least up to the number of variables that actually fit into one
cache block.

compiler/global_data.m:
	Provide a mechanism for creating not just single (scalar) static cells,
	but arrays (vectors) of them.

compiler/lookup_switch.m:
	Use the new mechanism to generate code along the lines described above.

	Put the information passed between the two halves of the lookup switch
	implementation (detection and code generation) into an opaque data
	structure.

compiler/switch_gen.m:
	Conform to the new interface of lookup_switch.m.

compiler/ll_pseudo_type_info.m:
compiler/stack_layout.m:
compiler/string_switch.m:
compiler/unify_gen.m:
compiler/var_locn.m:
	Conform to the change to global_data.m.

compiler/llds.m:
	Define the data structures for holding vectors of static cells. Rename
	the function symbols we used to use to refer to static cells to make
	clear that they apply to scalar cells only. Provide similar mechanisms
	for representing static cell vectors and references to them.

	Generalize heap_ref heap references to allow the index to be computed
	at runtime, not compile time. For symmetry's sake, do likewise
	for stack references.

compiler/llds_out.m:
	Add the code required to write out static cell vectors.

	Rename decl_ids to increase clarity and avoid ambiguity.

compiler/code_util.m:
compiler/exprn_aux.m:
	Modify code that traverses rvals to now also traverse the new rvals
	inside memory references.

compiler/name_mangle.m:
	Provide the prefix for static cell vectors.

compiler/layout_out.m:
compiler/rtti_out.m:
compiler/opt_debug.m:
	Conform to the change to data_addrs and decl_ids.

compiler/code_info.m:
	Provide access to the new functionality in global_data.m, and conform
	to the change to llds.m.

	Provide a utility predicate needed by lookup_switch.m.

compiler/hlds_llds.m:
	Fix the formatting of some comments.

tools/binary:
tools/binary_step:
	Fix the bit rot that has set in since they were last used (the rest
	of the system has changed quite a lot since then). I had to do so
	to debug one part of this change.

tests/hard_coded/dense_lookup_switch2.{m,exp}:
tests/hard_coded/dense_lookup_switch3.{m,exp}:
	New test cases to exercise the new algorithm.

tests/hard_coded/Mmakefile:
	Enable the new test cases, as well as an old one (from 1997!)
	that seems never to have been enabled.
2006-03-30 02:46:08 +00:00

387 lines
9.6 KiB
Bash
Executable File

#!/bin/sh
#
# vim: ts=4 sw=4 et
#
# Test the stage2 directory to see whether it passes
# a bootstrap check and/or a check using the tests directory.
# If stage2 passes, binary_step returns an exit status of 0 (true);
# if it fails, binary_step returns an exit status of 1 (false).
#
# binary_step remakes the archive in stage2/library and the executable
# in stage2/compiler. In the intended use, the binary script sets up
# these directories so that these actions cause no recompilations,
# either Mercury to C or C to object, only linking. Other uses probably
# won't work.
usage="\
Usage: $0 [options]
Options:
-b-, --no-bootcheck
Do not perform a bootcheck; check only the tests directory.
-c, --compile-only
Check the successful creation of the stage3 .c files,
but do not compare stage2.ok and stage3.
-C, --compare-to-bad
Compile stage3 using the parameter settings in the stage2.bad
directory, and compare stage3 to stage2.bad, not stage2.ok.
-d, --dependency-only
Check only that the dependencies can be made in stage3.
-h, --help
Display this usage message.
-j <num-jobs>, --jobs <num-jobs>
Run using <num-jobs> different parallel processes.
-l, --library-only
Check the successful creation of the stage3 .c files in the
library, but do not compile the compiler directory.
-m <mmake-args>, --mmake-args <mmake-args>
Pass <mmake-args> as options to \`mmake'.
-o <filename>, --output-file <filename>
Output results to <filename>.
-s <command>, --single-command <command>
Execute the given command using the constructed compiler.
-t <testdir>, --test-dir <testdir>
Execute runtests from the named subdirectory of tests.
"
# If you change this, you will also need to change the files indicated
# in scripts/c2init.in.
STD_LIB_NAME=mer_std
set -x
alltestdirs="benchmarks general hard_coded invalid valid warnings"
bootcheck="true"
compile_only="false"
dependency_only="false"
library_only="false"
jfactor=""
mmake_opts=""
outfile="DIFF.BINARY"
single_command=""
testdirs=""
basis="ok"
while [ $# -gt 0 ]; do
case "$1" in
-b-|--no-bootcheck)
bootcheck="false" ;;
-c|--compile-only)
compile_only="true" ;;
-C|--compare-to-bad)
basis="bad" ;;
-d|--dependency-only)
dependency_only="true" ;;
-h|--help)
echo "$usage"
exit 0 ;;
-j|--jobs)
jfactor="-j$2"; shift ;;
-j*)
jfactor="-j` expr $1 : '-j\(.*\)' `" ;;
--jobs*)
jfactor="--jobs` expr $1 : '--jobs\(.*\)' `" ;;
-l|--library-only)
library_only="true" ;;
-m|--mmake)
mmake_opts="$mmake_opts $2"; shift ;;
-o|--output-file)
outfile="$2"; shift ;;
-o*)
outfile="` expr $1 : '-o\(.*\)' `"; ;;
-s|--single-command)
single_command="$2"; shift ;;
-s*)
single_command="` expr $1 : '-s\(.*\)' `" ;;
--single-command*)
single_command="` expr $1 : '--single-command\(.*\)' `" ;;
-t|--test-dir)
testdir="$2"; shift
if test -d tests/$testdir
then
testdirs="$testdirs $testdir"
else
if test "$testdir" = "all"
then
testdirs="$alltestdirs"
else
echo "tests has no subdirectory named $testdir"
fi
fi ;;
-t*)
testdir="` expr $1 : '-t\(.*\)' `"
if test -d tests/$testdir
then
testdirs="$testdirs $testdir"
else
if test "$testdir" = "all"
then
testdirs="$alltestdirs"
else
echo "tests has no subdirectory named $testdir"
fi
fi ;;
-*)
echo "$0: unknown option \`$1'" 1>&2
echo "$usage" 1>&2
exit 1 ;;
*)
echo "$usage" 1>&2
exit 1 ;;
esac
shift
done
root=`/bin/pwd`
MERCURY_COMPILER=$root/compiler/mercury_compile
export MERCURY_COMPILER
MERCURY_CONFIG_FILE=$root/scripts/Mercury.config
export MERCURY_CONFIG_FILE
MMAKE_VPATH=.
export MMAKE_VPATH
MMAKE_DIR=../scripts
export MMAKE_DIR
# Ensure that mmake will not disturb the .o and .c files placed there by binary
set +x
touch stage2/library/*.c
touch stage2/mdbcomp/*.c
touch stage2/analysis/*.c
touch stage2/compiler/*.c
sleep 2
touch stage2/library/*.int3
touch stage2/mdbcomp/*.int3
touch stage2/analysis/*.int3
touch stage2/compiler/*.int3
sleep 2
touch stage2/library/*.date3
touch stage2/mdbcomp/*.date3
touch stage2/analysis/*.date3
touch stage2/compiler/*.date3
touch stage2/library/*.int2
touch stage2/library/*.int
touch stage2/mdbcomp/*.int2
touch stage2/mdbcomp/*.int
touch stage2/analysis/*.int2
touch stage2/analysis/*.int
touch stage2/compiler/*.int2
touch stage2/compiler/*.int
sleep 2
touch stage2/library/*.date
touch stage2/mdbcomp/*.date
touch stage2/analysis/*.date
touch stage2/compiler/*.date
touch stage2/library/*.opt
sleep 2
touch stage2/library/*.optdate
touch stage2/library/*.trans_opt
sleep 2
touch stage2/library/*.trans_opt_date
touch stage2/library/*.o
touch stage2/library/*.pic_o
touch stage2/mdbcomp/*.o
touch stage2/analysis/*.o
touch stage2/compiler/*.o
# Rebuild the stage2 library and compiler from the components already there.
/bin/rm -f stage2/library/lib$STD_LIB_NAME.a stage2/library/lib$STD_LIB_NAME.so
/bin/rm -f stage2/mdbcomp/lib$STD_LIB_NAME.a stage2/library/lib$STD_LIB_NAME.so
/bin/rm -f stage2/compiler/mercury_compile
set -x
if (cd stage2/library ; mmake $mmake_opts $jfactor)
then
echo "building of stage 2 library successful"
else
echo "building of stage 2 library not successful"
touch .stage2_problem
exit 1
fi
if (cd stage2/mdbcomp ; mmake $mmake_opts $jfactor library)
then
echo "building of stage 2 mdbcomp successful"
else
echo "building of stage 2 mdbcomp not successful"
touch .stage2_problem
exit 1
fi
if (cd stage2/analysis ; mmake $mmake_opts $jfactor library)
then
echo "building of stage 2 analysis successful"
else
echo "building of stage 2 analysis not successful"
touch .stage2_problem
exit 1
fi
if (cd stage2/compiler ; mmake $mmake_opts $jfactor mercury_compile)
then
echo "building of stage 2 compiler successful"
else
echo "building of stage 2 compiler not successful"
touch .stage2_problem
exit 1
fi
unset MMAKE_VPATH
unset MMAKE_DIR
MERCURY_COMPILER=$root/stage2/compiler/mercury_compile
export MERCURY_COMPILER
ulimit -t 200
if test "$single_command" != ""
then
echo "executing $single_command"
arg $single_command
if $single_command
then
echo "command successful"
else
echo "command not successful"
exit 1
fi
fi
if "$bootcheck"
then
# Rebuild the stage3 library and compiler from scratch
/bin/rm -f stage3/library/*.c
/bin/rm -f stage3/library/*.c_date
/bin/rm -f stage3/library/*.d
/bin/rm -f stage3/library/*.optdate
/bin/rm -f stage3/library/*.trans_opt_date
/bin/rm -f stage3/library/*.date3
/bin/rm -f stage3/library/*.date
/bin/rm -f stage3/library/*.opt
/bin/rm -f stage3/library/*.trans_opt
/bin/rm -f stage3/library/*.int3
/bin/rm -f stage3/library/*.int2
/bin/rm -f stage3/library/*.int
/bin/rm -f stage3/compiler/*.c
/bin/rm -f stage3/compiler/*.c_date
/bin/rm -f stage3/compiler/*.d
/bin/rm -f stage3/compiler/*.optdate
/bin/rm -f stage3/compiler/*.trans_opt_date
/bin/rm -f stage3/compiler/*.date3
/bin/rm -f stage3/compiler/*.date
/bin/rm -f stage3/compiler/*.opt
/bin/rm -f stage3/compiler/*.trans_opt
/bin/rm -f stage3/compiler/*.int3
/bin/rm -f stage3/compiler/*.int2
/bin/rm -f stage3/compiler/*.int
if (cd stage3 ; mmake $mmake_opts depend_library depend_compiler)
then
echo "building of stage 3 dependencies successful"
if $dependency_only
then
exit 0
fi
else
echo "building of stage 3 dependencies not successful"
exit 1
fi
MMAKE_VPATH=.
export MMAKE_VPATH
MMAKE_DIR=../scripts
export MMAKE_DIR
if (cd stage3/library ; mmake -S $mmake_opts $jfactor ints ; mmake -S $mmake_opts $jfactor cs)
then
echo "building of stage 3 library successful"
if $library_only
then
exit 0
fi
else
echo "building of stage 3 library not successful"
exit 1
fi
if (cd stage3/compiler ; mmake -S $mmake_opts $jfactor ints ; mmake -S $mmake_opts $jfactor cs)
then
echo "building of stage 3 compiler successful"
else
echo "building of stage 3 compiler not successful"
exit 1
fi
if test "$compile_only" = false
then
founddiff=false
cat /dev/null > $outfile
for dir in library compiler
do
# `mmake cs' in the compiler directory doesn't build
# `top_level_init.c', so we only compare the `.c'
# files present in the stage3 directory.
for stage3file in stage3/$dir/*.c
do
stage2file="stage2.$basis/$dir/`basename $file`"
diff -u $stage2file $stage3file >> $outfile ||
founddiff=true
done
done
if "$founddiff" = true
then
echo "error - stage2.$basis and stage3 differ!"
exit 1
else
echo "stage2.$basis and stage3 compare ok"
fi
fi
fi
for testdir in $testdirs
do
if (cd tests/$testdir; runtests)
then
echo "tests in the $testdir directory successful"
else
echo "tests in the $testdir directory not successful"
exit 1
fi
done
exit 0