mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-16 22:35:41 +00:00
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.
387 lines
9.6 KiB
Bash
Executable File
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
|