mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-17 14:57:03 +00:00
Estimated hours taken: 3 Branches: main Auto-generate the code for performing higher order calls and method calls. This way, we can vary the number of explicit arguments we specialize for independently of the number of hidden arguments we specialize for. (Previously, we did not specialize on the number of hidden arguments at all.) tools/make_spec_ho_call: A new script to auto-generate the code for performing higher order calls. tools/make_spec_method_call: A new script to auto-generate the code for performing method calls. runtime/mercury_ho_call.c: Replace the old handwritten code for performing higher order and method calls with #includes of the auto-generated files. runtime/Mmakefile: Make the object files of mercury_ho_call.c depend on the auto-generated files, and through them, on the scripts. compiler/options.m: Conform to the new parameters in the scripts.
139 lines
4.5 KiB
Bash
Executable File
139 lines
4.5 KiB
Bash
Executable File
#!/bin/sh
|
|
# vim: ts=4 sw=4 et
|
|
|
|
# If you change max_spec_explicit_arg, you should consider changing
|
|
# the value of the max_specialized_do_call_class_method option in
|
|
# compiler/options.m.
|
|
max_spec_explicit_arg=6
|
|
max_spec_hidden_arg=1
|
|
|
|
> mercury_method_call_declares.i
|
|
> mercury_method_call_inits.i
|
|
|
|
spec_explicit_arg=-1
|
|
while test $spec_explicit_arg -le $max_spec_explicit_arg
|
|
do
|
|
if test $spec_explicit_arg -lt 0
|
|
then
|
|
variant="compact"
|
|
else
|
|
variant="$spec_explicit_arg"
|
|
fi
|
|
|
|
echo "MR_define_entry(mercury__do_call_class_method_$variant);"
|
|
echo "{"
|
|
echo " MR_Word type_class_info;"
|
|
echo " MR_Integer method_index;"
|
|
echo " MR_Code *dest;"
|
|
echo " int num_explicit_args;"
|
|
echo " int num_hidden_args;"
|
|
echo " int i;"
|
|
|
|
i=1;
|
|
while test $i -le $spec_explicit_arg
|
|
do
|
|
echo " MR_Word arg$i;"
|
|
i=`expr $i + 1`
|
|
done
|
|
|
|
echo
|
|
echo " type_class_info = MR_r1;"
|
|
echo " method_index = MR_r2;"
|
|
echo " dest = MR_typeclass_info_class_method(type_class_info, method_index);"
|
|
echo " num_hidden_args ="
|
|
echo " MR_typeclass_info_num_extra_instance_args(type_class_info);"
|
|
|
|
if test $spec_explicit_arg -lt 0
|
|
then
|
|
echo " num_explicit_args = MR_r3;"
|
|
num_explicit_args="num_explicit_args"
|
|
else
|
|
i=1;
|
|
while test $i -le $spec_explicit_arg
|
|
do
|
|
j=`expr $i + 2`
|
|
echo " arg$i = MR_r$j;"
|
|
i=`expr $i + 1`
|
|
done
|
|
num_explicit_args="$spec_explicit_arg"
|
|
fi
|
|
echo
|
|
echo " MR_maybe_record_method_histogram($num_explicit_args, num_hidden_args);"
|
|
echo
|
|
|
|
if test $max_spec_hidden_arg -ge 0 -a $spec_explicit_arg -ge 0
|
|
then
|
|
echo " switch (num_hidden_args) {"
|
|
spec_hidden_arg=0
|
|
while test $spec_hidden_arg -le $max_spec_hidden_arg
|
|
do
|
|
echo " case $spec_hidden_arg:"
|
|
i=1;
|
|
while test $i -le $spec_hidden_arg
|
|
do
|
|
echo " MR_r$i = MR_typeclass_info_extra_instance_arg(type_class_info, $i);"
|
|
i=`expr $i + 1`
|
|
done
|
|
j=1
|
|
while test $j -le $spec_explicit_arg
|
|
do
|
|
echo " MR_r$i = arg$j;"
|
|
i=`expr $i + 1`
|
|
j=`expr $j + 1`
|
|
done
|
|
|
|
echo " MR_tailcall(dest, MR_prof_ho_caller_proc);"
|
|
echo " break;"
|
|
echo
|
|
spec_hidden_arg=`expr $spec_hidden_arg + 1`
|
|
done
|
|
echo " default:"
|
|
echo " /* fall through to the general case below */"
|
|
echo " break;"
|
|
echo " }"
|
|
echo
|
|
fi
|
|
|
|
echo " MR_save_registers();"
|
|
if test $spec_explicit_arg -lt 0
|
|
then
|
|
echo " if (num_hidden_args < MR_CLASS_METHOD_CALL_INPUTS_COMPACT) {"
|
|
echo " /* copy the explicit args to the left, from the left */"
|
|
echo " for (i = 1; i <= num_explicit_args; i++) {"
|
|
echo " MR_virtual_reg_assign(i + num_hidden_args,"
|
|
echo " MR_virtual_reg_value(i + MR_CLASS_METHOD_CALL_INPUTS_COMPACT));"
|
|
echo " }"
|
|
echo " } else if (num_hidden_args > MR_CLASS_METHOD_CALL_INPUTS_COMPACT) {"
|
|
echo " /* copy the explicit args to the right, from the right */"
|
|
echo " for (i = num_explicit_args; i > 0 ; i--) {"
|
|
echo " MR_virtual_reg_assign(i + num_hidden_args,"
|
|
echo " MR_virtual_reg_value(i + MR_CLASS_METHOD_CALL_INPUTS_COMPACT));"
|
|
echo " }"
|
|
echo " } /* else the explicit args are in the right place */"
|
|
else
|
|
i=1
|
|
while test $i -le $spec_explicit_arg
|
|
do
|
|
echo " MR_virtual_reg_assign(num_hidden_args + $i, arg$i);"
|
|
i=`expr $i + 1`
|
|
done
|
|
|
|
fi
|
|
echo
|
|
|
|
echo " for (i = 1; i <= num_hidden_args; i++) {"
|
|
echo " MR_virtual_reg_assign(i,"
|
|
echo " MR_typeclass_info_extra_instance_arg(type_class_info, i));"
|
|
echo " }"
|
|
echo " MR_restore_registers();"
|
|
echo
|
|
echo " MR_tailcall(dest, MR_prof_ho_caller_proc);"
|
|
echo "}"
|
|
echo
|
|
|
|
echo "MR_define_extern_entry(mercury__do_call_class_method_$variant);" >> mercury_method_call_declares.i
|
|
echo " MR_init_entry_an(mercury__do_call_class_method_$variant);" >> mercury_method_call_inits.i
|
|
|
|
spec_explicit_arg=`expr $spec_explicit_arg + 1`
|
|
done
|