[m-rev.] for review: higher order calling convention
Zoltan Somogyi
zs at cs.mu.OZ.AU
Tue Oct 28 13:25:03 AEDT 2003
For review by Fergus.
Change the calling convention for higher order calls, to make such calls
faster.
The change to mercury_ho_call.c will be committed first. The change to the
compiler will be committed later, after people had a chance to do a "cvs
update" of the change of the runtime. This will avoid installed compilers
generating calls to labels that do not exist in the runtime directories of
workspaces.
runtime/mercury_ho_call.c:
Add versions of mercury_do_call_closure/mercury_do_call_class_method
that do not expect the argument giving the number of output arguments,
since the code does not and will not need this information.
compiler/call_gen.m:
Do not generate the argument giving the number of output arguments,
and start placing user-specified arguments into the freed-up register.
compiler/llds_out.m:
Generate code that calls the compact versions of the labels in
mercury_ho_call.c.
cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/call_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/call_gen.m,v
retrieving revision 1.157
diff -u -r1.157 call_gen.m
--- compiler/call_gen.m 27 Oct 2003 05:42:35 -0000 1.157
+++ compiler/call_gen.m 27 Oct 2003 06:35:08 -0000
@@ -264,9 +264,9 @@
).
call_gen__generic_call_info(_, higher_order(PredVar, _, _, _),
- do_call_closure, [PredVar - arg_info(1, top_in)], 4).
+ do_call_closure, [PredVar - arg_info(1, top_in)], 3).
call_gen__generic_call_info(_, class_method(TCVar, _, _, _),
- do_call_class_method, [TCVar - arg_info(1, top_in)], 5).
+ do_call_class_method, [TCVar - arg_info(1, top_in)], 4).
% Casts are generated inline.
call_gen__generic_call_info(_, unsafe_cast, do_not_reached, [], 1).
call_gen__generic_call_info(_, aditi_builtin(_, _), _, _, _) :-
@@ -291,27 +291,21 @@
call_gen__generic_call_nonvar_setup(higher_order(_, _, _, _),
InVars, OutVars, Code, !CI) :-
- code_info__clobber_regs([reg(r, 2), reg(r, 3)], !CI),
+ code_info__clobber_regs([reg(r, 2)], !CI),
list__length(InVars, NInVars),
- list__length(OutVars, NOutVars),
Code = node([
assign(reg(r, 2), const(int_const(NInVars))) -
- "Assign number of immediate input arguments",
- assign(reg(r, 3), const(int_const(NOutVars))) -
- "Assign number of output arguments"
+ "Assign number of immediate input arguments"
]).
call_gen__generic_call_nonvar_setup(class_method(_, Method, _, _),
InVars, OutVars, Code, !CI) :-
- code_info__clobber_regs([reg(r, 2), reg(r, 3), reg(r, 4)], !CI),
+ code_info__clobber_regs([reg(r, 2), reg(r, 3)], !CI),
list__length(InVars, NInVars),
- list__length(OutVars, NOutVars),
Code = node([
assign(reg(r, 2), const(int_const(Method))) -
"Index of class method in typeclass info",
assign(reg(r, 3), const(int_const(NInVars))) -
- "Assign number of immediate input arguments",
- assign(reg(r, 4), const(int_const(NOutVars))) -
- "Assign number of output arguments"
+ "Assign number of immediate input arguments"
]).
call_gen__generic_call_nonvar_setup(unsafe_cast, _, _, _, !CI) :-
error("call_gen__generic_call_nonvar_setup: unsafe_cast").
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.218
diff -u -r1.218 llds_out.m
--- compiler/llds_out.m 24 Oct 2003 06:17:40 -0000 1.218
+++ compiler/llds_out.m 24 Oct 2003 06:31:21 -0000
@@ -2637,9 +2637,11 @@
output_code_addr_decls(do_trace_redo_fail_deep) -->
io__write_string("MR_declare_entry(MR_do_trace_redo_fail_deep);\n").
output_code_addr_decls(do_call_closure) -->
- io__write_string("MR_declare_entry(mercury__do_call_closure);\n").
+ io__write_string(
+ "MR_declare_entry(mercury__do_call_closure_compact);\n").
output_code_addr_decls(do_call_class_method) -->
- io__write_string("MR_declare_entry(mercury__do_call_class_method);\n").
+ io__write_string(
+ "MR_declare_entry(mercury__do_call_class_method_compact);\n").
output_code_addr_decls(do_not_reached) -->
io__write_string("MR_declare_entry(MR_do_not_reached);\n").
@@ -2881,14 +2883,14 @@
output_label_as_code_addr(CallerLabel),
io__write_string(");\n\t\t"),
io__write_string(
- "MR_noprof_tailcall(MR_ENTRY(mercury__do_call_closure));\n").
+ "MR_noprof_tailcall(MR_ENTRY(mercury__do_call_closure_compact));\n").
output_goto(do_call_class_method, CallerLabel) -->
% see comment in output_call for why we use `noprof_' etc. here
io__write_string("MR_set_prof_ho_caller_proc("),
output_label_as_code_addr(CallerLabel),
io__write_string(");\n\t\t"),
io__write_string(
- "MR_noprof_tailcall(MR_ENTRY(mercury__do_call_class_method));\n").
+ "MR_noprof_tailcall(MR_ENTRY(mercury__do_call_class_method_compact));\n").
output_goto(do_not_reached, CallerLabel) -->
io__write_string("MR_tailcall(MR_ENTRY(MR_do_not_reached),\n\t\t"),
output_label_as_code_addr(CallerLabel),
@@ -2984,9 +2986,9 @@
output_code_addr(do_trace_redo_fail_deep) -->
io__write_string("MR_ENTRY(MR_do_trace_redo_fail_deep)").
output_code_addr(do_call_closure) -->
- io__write_string("MR_ENTRY(mercury__do_call_closure)").
+ io__write_string("MR_ENTRY(mercury__do_call_closure_compact)").
output_code_addr(do_call_class_method) -->
- io__write_string("MR_ENTRY(mercury__do_call_class_method)").
+ io__write_string("MR_ENTRY(mercury__do_call_class_method_compact)").
output_code_addr(do_not_reached) -->
io__write_string("MR_ENTRY(MR_do_not_reached)").
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing java
cvs diff: Diffing java/library
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_ho_call.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_ho_call.c,v
retrieving revision 1.66
diff -u -r1.66 mercury_ho_call.c
--- runtime/mercury_ho_call.c 20 Oct 2003 07:29:32 -0000 1.66
+++ runtime/mercury_ho_call.c 20 Oct 2003 07:38:20 -0000
@@ -343,7 +343,7 @@
** provided by the higher-order call may be input or output, and may appear
** in any order.
**
-** The input arguments to do_call_*_closure are the closure in MR_r1,
+** The input arguments to do_call_closure are the closure in MR_r1,
** the number of additional input arguments in MR_r2, the number of output
** arguments to expect in MR_r3, and the additional input arguments themselves
** in MR_r4, MR_r5, etc. The output arguments are returned in registers MR_r1,
@@ -353,6 +353,19 @@
** The placement of the extra input arguments into MR_r4, MR_r5 etc is done by
** the code generator, as is the movement of the output arguments to their
** eventual destinations.
+**
+** do_call_closure_compact is like do_call_closure, but it doesn't use MR_r3
+** for the number of output arguments. Instead, the extra input arguments start
+** in MR_r3, not MR_r4. The code generator now calls do_call_closure_compact;
+** do_call_closure is for backward compatibility.
+**
+** do_call_class_method_compact has the equivalent relationship to
+** do_call_class_method.
+**
+** After bootstrapping is complete, we should delete the existing
+** implementations of do_call_closure and do_call_class_method, and
+** rename do_call_closure_compact as do_call_closure and
+** do_call_class_method_compact as do_call_class_method.
*/
/*
@@ -362,6 +375,7 @@
** MR_r3 -> number of output arguments (unused).
*/
#define MR_HO_CALL_INPUTS 3
+#define MR_HO_CALL_INPUTS_COMPACT 2
/*
** Number of input arguments to do_call_*_class_method,
@@ -370,7 +384,8 @@
** MR_r3 -> number of immediate input arguments.
** MR_r4 -> number of output arguments (unused).
*/
-#define MR_CLASS_METHOD_CALL_INPUTS 4
+#define MR_CLASS_METHOD_CALL_INPUTS 4
+#define MR_CLASS_METHOD_CALL_INPUTS_COMPACT 3
/*
** These are the real implementations of higher order calls and method calls.
@@ -378,6 +393,8 @@
MR_define_extern_entry(mercury__do_call_closure);
MR_define_extern_entry(mercury__do_call_class_method);
+MR_define_extern_entry(mercury__do_call_closure_compact);
+MR_define_extern_entry(mercury__do_call_class_method_compact);
/*
** These are the real implementations of unify and compare.
@@ -393,7 +410,9 @@
MR_BEGIN_MODULE(call_module)
MR_init_entry_an(mercury__do_call_closure);
+ MR_init_entry_an(mercury__do_call_closure_compact);
MR_init_entry_an(mercury__do_call_class_method);
+ MR_init_entry_an(mercury__do_call_class_method_compact);
MR_init_entry_an(mercury__builtin__unify_2_0);
MR_init_entry_an(mercury__builtin__compare_3_0);
@@ -456,6 +475,59 @@
MR_tailcall(closure->MR_closure_code, MR_prof_ho_caller_proc);
}
+/*
+** Note: this routine gets ignored for profiling.
+** That means it should be called using noprof_call()
+** rather than call(). See comment in output_call in
+** compiler/llds_out for explanation.
+*/
+MR_define_entry(mercury__do_call_closure_compact);
+{
+ MR_Closure *closure;
+ int num_extra_args; /* # of args provided by our caller */
+ int num_hidden_args;/* # of args hidden in the closure */
+ int i;
+
+ /*
+ ** These assignments to local variables allow the values
+ ** of the relevant registers to be printed in gdb without
+ ** worrying about which machine registers, if any, hold them.
+ */
+
+ closure = (MR_Closure *) MR_r1;
+ num_extra_args = MR_r2;
+ num_hidden_args = closure->MR_closure_num_hidden_args;
+
+ MR_save_registers();
+
+ if (num_hidden_args < MR_HO_CALL_INPUTS_COMPACT) {
+ /* copy to the left, from the left */
+ for (i = 1; i <= num_extra_args; i++) {
+ MR_virtual_reg(i + num_hidden_args) =
+ MR_virtual_reg(i + MR_HO_CALL_INPUTS_COMPACT);
+ }
+ } else if (num_hidden_args > MR_HO_CALL_INPUTS_COMPACT) {
+ /* copy to the right, from the right */
+ for (i = num_extra_args; i > 0; i--) {
+ MR_virtual_reg(i + num_hidden_args) =
+ MR_virtual_reg(i + MR_HO_CALL_INPUTS_COMPACT);
+ }
+ } /* else the new args are in the right place */
+
+ for (i = 1; i <= num_hidden_args; i++) {
+ MR_virtual_reg(i) = closure->MR_closure_hidden_args(i);
+ }
+
+ MR_restore_registers();
+
+ /*
+ ** Note that we pass MR_prof_ho_caller_proc rather than
+ ** MR_LABEL(mercury__do_call_closure), so that the call gets recorded
+ ** as having come from our caller.
+ */
+ MR_tailcall(closure->MR_closure_code, MR_prof_ho_caller_proc);
+}
+
/*
** MR_r1: the typeclass_info
** MR_r2: index of class method
@@ -509,6 +581,79 @@
MR_virtual_reg(i + num_extra_instance_args) =
MR_virtual_reg(i +
MR_CLASS_METHOD_CALL_INPUTS);
+ }
+ } /* else the new args are in the right place */
+
+ for (i = num_extra_instance_args; i > 0; i--) {
+ MR_virtual_reg(i) =
+ MR_typeclass_info_arg_typeclass_info(MR_virtual_reg(1),
+ i);
+ }
+
+ MR_restore_registers();
+
+ /*
+ ** Note that we pass MR_prof_ho_caller_proc rather than
+ ** MR_LABEL(mercury__do_call_class_method), so that the call gets
+ ** recorded as having come from our caller.
+ */
+ MR_tailcall(destination, MR_prof_ho_caller_proc);
+}
+
+ /*
+ ** MR_r1: the typeclass_info
+ ** MR_r2: index of class method
+ ** MR_r3: number of immediate input arguments
+ ** MR_r4+:input args
+ */
+
+/*
+** Note: this routine gets ignored for profiling.
+** That means it should be called using noprof_call()
+** rather than call(). See comment in output_call in
+** compiler/llds_out for explanation.
+*/
+MR_define_entry(mercury__do_call_class_method_compact);
+{
+ MR_Word type_class_info;
+ MR_Integer method_index;
+ MR_Integer num_input_args;
+ MR_Code *destination;
+ MR_Integer num_extra_instance_args;
+ int i;
+
+ /*
+ ** These assignments to local variables allow the values
+ ** of the relevant registers to be printed in gdb without
+ ** worrying about which machine registers, if any, hold them.
+ */
+
+ type_class_info = MR_r1;
+ method_index = (MR_Integer) MR_r2;
+ num_input_args = MR_r3;
+
+ destination = MR_typeclass_info_class_method(type_class_info,
+ method_index);
+ num_extra_instance_args = (MR_Integer)
+ MR_typeclass_info_num_extra_instance_args(type_class_info);
+
+ MR_save_registers();
+
+ if (num_extra_instance_args < MR_CLASS_METHOD_CALL_INPUTS_COMPACT) {
+ /* copy to the left, from the left */
+ for (i = 1; i <= num_input_args; i++) {
+ MR_virtual_reg(i + num_extra_instance_args) =
+ MR_virtual_reg(i +
+ MR_CLASS_METHOD_CALL_INPUTS_COMPACT);
+ }
+ } else if (num_extra_instance_args >
+ MR_CLASS_METHOD_CALL_INPUTS_COMPACT)
+ {
+ /* copy to the right, from the right */
+ for (i = num_input_args; i > 0; i--) {
+ MR_virtual_reg(i + num_extra_instance_args) =
+ MR_virtual_reg(i +
+ MR_CLASS_METHOD_CALL_INPUTS_COMPACT);
}
} /* else the new args are in the right place */
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list