mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-11 20:03:28 +00:00
Change the calling convention for higher order calls, to make such calls
Estimated hours taken: 1 Branches: main 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.
This commit is contained in:
@@ -264,9 +264,9 @@ call_gen__extra_livevals(Reg, FirstInput, ExtraLiveVals) :-
|
||||
).
|
||||
|
||||
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(_, _), _, _, _) :-
|
||||
@@ -290,28 +290,22 @@ call_gen__generic_call_info(_, aditi_builtin(_, _), _, _, _) :-
|
||||
code_info::in, code_info::out) is det.
|
||||
|
||||
call_gen__generic_call_nonvar_setup(higher_order(_, _, _, _),
|
||||
InVars, OutVars, Code, !CI) :-
|
||||
code_info__clobber_regs([reg(r, 2), reg(r, 3)], !CI),
|
||||
InVars, _OutVars, Code, !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),
|
||||
InVars, _OutVars, Code, !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").
|
||||
|
||||
@@ -2508,9 +2508,11 @@ output_code_addr_decls(do_trace_redo_fail_deep, !IO) :-
|
||||
io__write_string("MR_declare_entry(MR_do_trace_redo_fail_deep);\n",
|
||||
!IO).
|
||||
output_code_addr_decls(do_call_closure, !IO) :-
|
||||
io__write_string("MR_declare_entry(mercury__do_call_closure);\n", !IO).
|
||||
io__write_string(
|
||||
"MR_declare_entry(mercury__do_call_closure_compact);\n", !IO).
|
||||
output_code_addr_decls(do_call_class_method, !IO) :-
|
||||
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",
|
||||
!IO).
|
||||
output_code_addr_decls(do_not_reached, !IO) :-
|
||||
io__write_string("MR_declare_entry(MR_do_not_reached);\n", !IO).
|
||||
@@ -2753,16 +2755,15 @@ output_goto(do_call_closure, CallerLabel, !IO) :-
|
||||
io__write_string("MR_set_prof_ho_caller_proc(", !IO),
|
||||
output_label_as_code_addr(CallerLabel, !IO),
|
||||
io__write_string(");\n\t\t", !IO),
|
||||
io__write_string(
|
||||
"MR_noprof_tailcall(MR_ENTRY(mercury__do_call_closure));\n",
|
||||
!IO).
|
||||
io__write_string("MR_noprof_tailcall(" ++
|
||||
"MR_ENTRY(mercury__do_call_closure_compact));\n", !IO).
|
||||
output_goto(do_call_class_method, CallerLabel, !IO) :-
|
||||
% see comment in output_call for why we use `noprof_' etc. here
|
||||
io__write_string("MR_set_prof_ho_caller_proc(", !IO),
|
||||
output_label_as_code_addr(CallerLabel, !IO),
|
||||
io__write_string(");\n\t\t", !IO),
|
||||
io__write_string("MR_noprof_tailcall(" ++
|
||||
"MR_ENTRY(mercury__do_call_class_method));\n", !IO).
|
||||
"MR_ENTRY(mercury__do_call_class_method_compact));\n", !IO).
|
||||
output_goto(do_not_reached, CallerLabel, !IO) :-
|
||||
io__write_string("MR_tailcall(MR_ENTRY(MR_do_not_reached),\n\t\t",
|
||||
!IO),
|
||||
@@ -2863,9 +2864,10 @@ output_code_addr(do_trace_redo_fail_shallow, !IO) :-
|
||||
output_code_addr(do_trace_redo_fail_deep, !IO) :-
|
||||
io__write_string("MR_ENTRY(MR_do_trace_redo_fail_deep)", !IO).
|
||||
output_code_addr(do_call_closure, !IO) :-
|
||||
io__write_string("MR_ENTRY(mercury__do_call_closure)", !IO).
|
||||
io__write_string("MR_ENTRY(mercury__do_call_closure_compact)", !IO).
|
||||
output_code_addr(do_call_class_method, !IO) :-
|
||||
io__write_string("MR_ENTRY(mercury__do_call_class_method)", !IO).
|
||||
io__write_string("MR_ENTRY(mercury__do_call_class_method_compact)",
|
||||
!IO).
|
||||
output_code_addr(do_not_reached, !IO) :-
|
||||
io__write_string("MR_ENTRY(MR_do_not_reached)", !IO).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user