mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-20 00:15:27 +00:00
Estimated hours taken: 51 Make closures always include layout information, not just in grades in which typeinfo liveness is turned on. This requires separating two notions, which were previously combined: - Body typeinfo liveness means that when a variable X is live, any typeinfo variables describing type variables that occur in the type of X must also be live. - Interface typeinfo liveness means that when the input arguments of a procedure include a polymorphically typed variable (e.g. X), typeinfo variables describing type variables that occur in the type of X must also be among the arguments. This change turns on interface typeinfo liveness for procedures that either have their address taken in the current module, or are exported and thus may have their address taken in some other module. compiler/hlds_pred.m: Centralize decisions wrt whether procedure interfaces and bodies use typeinfo liveness here. compiler/options.m: Rename the typeinfo_liveness option as body_typeinfo_liveness, since this reflects its new function. compiler/call_gen.m: compiler/higher_order.m: compiler/live_vars.m: compiler/liveness.m: compiler/unused_args.m: Use hlds_pred.m to make decisions about liveness. compiler/lambda.m: Always include the relevant typeinfos in the interfaces of procedures created for lambdas. compiler/continuation_info.m: compiler/stack_layout.m: compiler/unify_gen.m: Modify the predicates that record and use layout information about closures to always do so, since the necessary information is now always available about the interfaces of procedures which can be put into closures. Previously, they only did so if typeinfo_liveness was set. Also, generate information about the types of the variables in a closure from the pred_info's arg types field, not from the proc_info's var types field, because unlike the latter, it is valid even for imported predicates. compiler/hlds_out.m: Print the non-clause-related information in the clauses_info part of a pred_info (e.g. the type parameters) even if the predicate has no actual clauses. Simplify the code a bit by getting rid of a duplicate test. compiler/middle_rec.m: Require that the code generated for the base case not refer to any stack slots if this way of generating code is to be used. This is necessary because the base case is executed when the current procedure has no stack frame, and thus any references to stack slots would refer to and possibly overwrite the data in another procedure's frame. In the absence of requiring body typeinfo liveness for exported procedures, such references were not generated; in its presence, they were. However, we now require only interface liveness for exported procedures, so we can still use middle recursion for them. compiler/handle_options.m: Do not turn off middle_rec if (body) typeinfo liveness is turned on, now that the bug has been fixed. For polymorphic predicates, the base case will still contain references to stack slots, and thus the middle-rec optimization will not applied for them, but the optimization may apply to monomorphic predicates. compiler/passes_aux.m: Add the ability to call compiler passes with the procedure id as well as the predicate id of the procedure they are passed. tests/hard_coded/typeclasses/Mmakefile: Refer to --body-typeinfo-liveness instead of --typeinfo-liveness.
514 lines
16 KiB
Mathematica
514 lines
16 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 1995-1999 The University of Melbourne.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% This file contains auxiliary routines for the passes
|
|
% of the front and back ends of the compiler.
|
|
|
|
% Author: zs
|
|
|
|
:- module passes_aux.
|
|
|
|
:- interface.
|
|
|
|
:- import_module hlds_module, hlds_pred, prog_data.
|
|
:- import_module io, std_util, list, bool.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- type task ---> update_proc(pred(
|
|
proc_info, module_info, proc_info))
|
|
; update_proc_predid(pred(
|
|
proc_info, pred_id, module_info, proc_info))
|
|
; update_proc_predprocid(pred(
|
|
proc_info, pred_id, proc_id,
|
|
module_info, proc_info))
|
|
; update_proc_io(pred(
|
|
pred_id, proc_id, module_info,
|
|
proc_info, proc_info, io__state, io__state))
|
|
; update_proc_error(pred(
|
|
pred_id, proc_id, module_info, module_info,
|
|
proc_info, proc_info, int, int,
|
|
io__state, io__state))
|
|
; update_pred_error(pred_error_task)
|
|
; update_module(pred(
|
|
proc_info, proc_info,
|
|
module_info, module_info))
|
|
; update_module_io(pred(
|
|
pred_id, proc_id, proc_info, proc_info,
|
|
module_info, module_info,
|
|
io__state, io__state))
|
|
% It would be better to use an existentially-quantified type
|
|
% rather than `univ' here, but the current version of Mercury
|
|
% doesn't support existentially-quantified types.
|
|
; update_module_cookie(pred(
|
|
pred_id, proc_id, proc_info, proc_info,
|
|
univ, univ, module_info, module_info),
|
|
univ)
|
|
.
|
|
|
|
|
|
:- type pred_error_task ==
|
|
pred(pred_id, module_info, module_info, pred_info, pred_info,
|
|
int, int, io__state, io__state).
|
|
|
|
/****************
|
|
|
|
Note that update_module_cookie causes some difficulties.
|
|
Ideally, it should be implemented using existential types:
|
|
|
|
:- type task --->
|
|
...
|
|
; some [T] update_module_cookie(pred(
|
|
pred_id, proc_id, proc_info, proc_info,
|
|
T, T, module_info, module_info),
|
|
T)
|
|
|
|
That would avoid the need for messing about with type_to_univ and
|
|
univ_to_type.
|
|
|
|
Originally, it was implemented by changing `task' to `task(T)':
|
|
|
|
:- type task(T) --->
|
|
...
|
|
; update_module_cookie(pred(
|
|
pred_id, proc_id, proc_info, proc_info,
|
|
T, T, module_info, module_info),
|
|
T)
|
|
|
|
but that is not a good solution, because it causes a lot of warnings
|
|
about unbound type variables.
|
|
|
|
****************/
|
|
|
|
:- inst task = bound(( update_proc(pred(in, in, out) is det)
|
|
; update_proc_predid(pred(in, in, in, out) is det)
|
|
; update_proc_predprocid(pred(in, in, in, in, out)
|
|
is det)
|
|
; update_proc_io(pred(in, in, in, in, out, di, uo)
|
|
is det)
|
|
; update_proc_error(pred(in, in, in, out, in, out,
|
|
out, out, di, uo) is det)
|
|
; update_pred_error(pred(in, in, out, in, out,
|
|
out, out, di, uo) is det)
|
|
; update_module(pred(in, out, in, out) is det)
|
|
; update_module_io(pred(in, in, in, out,
|
|
in, out, di, uo) is det)
|
|
; update_module_cookie(pred(in, in, in, out, in, out,
|
|
in, out) is det, ground)
|
|
)).
|
|
|
|
:- inst pred_error_task =
|
|
(pred(in, in, out, in, out, out, out, di, uo) is det).
|
|
|
|
:- mode task :: task -> task.
|
|
|
|
:- pred process_all_nonimported_procs(task, module_info, module_info,
|
|
io__state, io__state).
|
|
:- mode process_all_nonimported_procs(task, in, out, di, uo) is det.
|
|
|
|
% Process procedures for which a given test succeeds.
|
|
:- pred process_matching_nonimported_procs(task, pred(pred_info),
|
|
module_info, module_info, io__state, io__state).
|
|
:- mode process_matching_nonimported_procs(task, pred(in) is semidet,
|
|
in, out, di, uo) is det.
|
|
|
|
:- pred process_matching_nonimported_procs(task, task, pred(pred_info),
|
|
module_info, module_info, io__state, io__state).
|
|
:- mode process_matching_nonimported_procs(task, out(task),
|
|
pred(in) is semidet, in, out, di, uo) is det.
|
|
|
|
:- pred process_all_nonimported_nonaditi_procs(task, module_info, module_info,
|
|
io__state, io__state).
|
|
:- mode process_all_nonimported_nonaditi_procs(task, in, out, di, uo) is det.
|
|
|
|
:- pred process_all_nonimported_nonaditi_procs(task, task,
|
|
module_info, module_info, io__state, io__state).
|
|
:- mode process_all_nonimported_nonaditi_procs(task, out(task),
|
|
in, out, di, uo) is det.
|
|
|
|
:- pred process_all_nonimported_procs(task, task,
|
|
module_info, module_info, io__state, io__state).
|
|
:- mode process_all_nonimported_procs(task, out(task), in, out, di, uo) is det.
|
|
|
|
:- pred write_pred_progress_message(string::in, pred_id::in, module_info::in,
|
|
io__state::di, io__state::uo) is det.
|
|
|
|
:- pred write_proc_progress_message(string::in, pred_id::in, proc_id::in,
|
|
module_info::in, io__state::di, io__state::uo) is det.
|
|
|
|
:- pred maybe_report_stats(bool::in, io__state::di, io__state::uo) is det.
|
|
:- pred maybe_write_string(bool::in, string::in,
|
|
io__state::di, io__state::uo) is det.
|
|
:- pred maybe_flush_output(bool::in, io__state::di, io__state::uo) is det.
|
|
|
|
:- pred report_error(string::in, io__state::di, io__state::uo) is det.
|
|
|
|
:- pred invoke_system_command(string::in, bool::out,
|
|
io__state::di, io__state::uo) is det.
|
|
|
|
:- pred maybe_report_sizes(module_info::in, io__state::di, io__state::uo)
|
|
is det.
|
|
|
|
|
|
:- pred report_pred_proc_id(module_info, pred_id, proc_id,
|
|
maybe(prog_context), prog_context, io__state, io__state).
|
|
:- mode report_pred_proc_id(in, in, in, in, out, di, uo) is det.
|
|
|
|
:- pred report_pred_name_mode(pred_or_func, string, list((mode)),
|
|
io__state, io__state).
|
|
:- mode report_pred_name_mode(in, in, in, di, uo) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module options, globals, hlds_out, prog_out, mode_util.
|
|
:- import_module mercury_to_mercury.
|
|
:- import_module varset.
|
|
:- import_module int, map, tree234, require.
|
|
|
|
process_all_nonimported_procs(Task, ModuleInfo0, ModuleInfo) -->
|
|
{ True = lambda([_PredInfo::in] is semidet, true) },
|
|
process_matching_nonimported_procs(Task, True,
|
|
ModuleInfo0, ModuleInfo).
|
|
|
|
process_all_nonimported_nonaditi_procs(Task, ModuleInfo0, ModuleInfo) -->
|
|
{ NotAditi = lambda([PredInfo::in] is semidet, (
|
|
\+ hlds_pred__pred_info_is_aditi_relation(PredInfo)
|
|
)) },
|
|
process_matching_nonimported_procs(Task, NotAditi,
|
|
ModuleInfo0, ModuleInfo).
|
|
|
|
process_all_nonimported_nonaditi_procs(Task0, Task,
|
|
ModuleInfo0, ModuleInfo) -->
|
|
{ NotAditi = lambda([PredInfo::in] is semidet, (
|
|
\+ hlds_pred__pred_info_is_aditi_relation(PredInfo)
|
|
)) },
|
|
process_matching_nonimported_procs(Task0, Task, NotAditi,
|
|
ModuleInfo0, ModuleInfo).
|
|
|
|
process_all_nonimported_procs(Task0, Task, ModuleInfo0, ModuleInfo) -->
|
|
{ True = lambda([_PredInfo::in] is semidet, true) },
|
|
process_matching_nonimported_procs(Task0, Task, True,
|
|
ModuleInfo0, ModuleInfo).
|
|
|
|
process_matching_nonimported_procs(Task, Filter, ModuleInfo0, ModuleInfo) -->
|
|
{ module_info_predids(ModuleInfo0, PredIds) },
|
|
( { Task = update_pred_error(Pred) } ->
|
|
list__foldl2(process_nonimported_pred(Pred, Filter), PredIds,
|
|
ModuleInfo0, ModuleInfo)
|
|
;
|
|
process_nonimported_procs_in_preds(PredIds, Task, _, Filter,
|
|
ModuleInfo0, ModuleInfo)
|
|
).
|
|
|
|
process_matching_nonimported_procs(Task0, Task, Filter,
|
|
ModuleInfo0, ModuleInfo) -->
|
|
{ module_info_predids(ModuleInfo0, PredIds) },
|
|
process_nonimported_procs_in_preds(PredIds, Task0, Task, Filter,
|
|
ModuleInfo0, ModuleInfo).
|
|
|
|
:- pred process_nonimported_pred(pred_error_task, pred(pred_info), pred_id,
|
|
module_info, module_info, io__state, io__state).
|
|
:- mode process_nonimported_pred(in(pred_error_task), pred(in) is semidet, in,
|
|
in, out, di, uo) is det.
|
|
|
|
process_nonimported_pred(Task, Filter, PredId, ModuleInfo0, ModuleInfo,
|
|
IO0, IO) :-
|
|
module_info_pred_info(ModuleInfo0, PredId, PredInfo0),
|
|
(
|
|
( pred_info_is_imported(PredInfo0)
|
|
; \+ call(Filter, PredInfo0)
|
|
)
|
|
->
|
|
ModuleInfo = ModuleInfo0,
|
|
IO = IO0
|
|
;
|
|
call(Task, PredId, ModuleInfo0, ModuleInfo1,
|
|
PredInfo0, PredInfo, WarnCnt, ErrCnt, IO0, IO1),
|
|
module_info_set_pred_info(ModuleInfo1,
|
|
PredId, PredInfo, ModuleInfo2),
|
|
passes_aux__handle_errors(WarnCnt, ErrCnt,
|
|
ModuleInfo2, ModuleInfo, IO1, IO)
|
|
).
|
|
|
|
:- pred process_nonimported_procs_in_preds(list(pred_id), task, task,
|
|
pred(pred_info), module_info, module_info, io__state, io__state).
|
|
:- mode process_nonimported_procs_in_preds(in, task, out(task),
|
|
pred(in) is semidet, in, out, di, uo) is det.
|
|
|
|
process_nonimported_procs_in_preds([], Task, Task, _, ModuleInfo, ModuleInfo)
|
|
--> [].
|
|
process_nonimported_procs_in_preds([PredId | PredIds], Task0, Task, Filter,
|
|
ModuleInfo0, ModuleInfo) -->
|
|
{ module_info_preds(ModuleInfo0, PredTable) },
|
|
{ map__lookup(PredTable, PredId, PredInfo) },
|
|
( { call(Filter, PredInfo) } ->
|
|
{ pred_info_non_imported_procids(PredInfo, ProcIds) },
|
|
process_nonimported_procs(ProcIds, PredId, Task0, Task1,
|
|
ModuleInfo0, ModuleInfo1)
|
|
;
|
|
{ ModuleInfo1 = ModuleInfo0 },
|
|
{ Task1 = Task0 }
|
|
),
|
|
process_nonimported_procs_in_preds(PredIds, Task1, Task, Filter,
|
|
ModuleInfo1, ModuleInfo).
|
|
|
|
:- pred process_nonimported_procs(list(proc_id), pred_id, task, task,
|
|
module_info, module_info, io__state, io__state).
|
|
:- mode process_nonimported_procs(in, in, task, out(task), in, out, di, uo)
|
|
is det.
|
|
|
|
process_nonimported_procs([], _PredId, Task, Task,
|
|
ModuleInfo, ModuleInfo, State, State).
|
|
process_nonimported_procs([ProcId | ProcIds], PredId, Task0, Task,
|
|
ModuleInfo0, ModuleInfo, State0, State) :-
|
|
|
|
module_info_preds(ModuleInfo0, Preds0),
|
|
map__lookup(Preds0, PredId, Pred0),
|
|
pred_info_procedures(Pred0, Procs0),
|
|
map__lookup(Procs0, ProcId, Proc0),
|
|
|
|
(
|
|
Task0 = update_module(Closure),
|
|
call(Closure, Proc0, Proc, ModuleInfo0, ModuleInfo8),
|
|
Task1 = Task0,
|
|
State9 = State0
|
|
;
|
|
Task0 = update_module_io(Closure),
|
|
call(Closure, PredId, ProcId, Proc0, Proc,
|
|
ModuleInfo0, ModuleInfo8, State0, State9),
|
|
Task1 = Task0
|
|
;
|
|
Task0 = update_proc(Closure),
|
|
call(Closure, Proc0, ModuleInfo0, Proc),
|
|
ModuleInfo8 = ModuleInfo0,
|
|
Task1 = Task0,
|
|
State9 = State0
|
|
;
|
|
Task0 = update_proc_predid(Closure),
|
|
call(Closure, Proc0, PredId, ModuleInfo0, Proc),
|
|
ModuleInfo8 = ModuleInfo0,
|
|
Task1 = Task0,
|
|
State9 = State0
|
|
;
|
|
Task0 = update_proc_predprocid(Closure),
|
|
call(Closure, Proc0, PredId, ProcId, ModuleInfo0, Proc),
|
|
ModuleInfo8 = ModuleInfo0,
|
|
Task1 = Task0,
|
|
State9 = State0
|
|
;
|
|
Task0 = update_proc_io(Closure),
|
|
call(Closure, PredId, ProcId, ModuleInfo0,
|
|
Proc0, Proc, State0, State9),
|
|
ModuleInfo8 = ModuleInfo0,
|
|
Task1 = Task0
|
|
;
|
|
Task0 = update_proc_error(Closure),
|
|
call(Closure, PredId, ProcId, ModuleInfo0, ModuleInfo1,
|
|
Proc0, Proc, WarnCnt, ErrCnt, State0, State1),
|
|
Task1 = Task0,
|
|
passes_aux__handle_errors(WarnCnt, ErrCnt,
|
|
ModuleInfo1, ModuleInfo8, State1, State9)
|
|
;
|
|
Task0 = update_pred_error(_),
|
|
error("passes_aux:process_non_imported_procs")
|
|
;
|
|
Task0 = update_module_cookie(Closure, Cookie0),
|
|
call(Closure, PredId, ProcId, Proc0, Proc,
|
|
Cookie0, Cookie1, ModuleInfo0, ModuleInfo8),
|
|
Task1 = update_module_cookie(Closure, Cookie1),
|
|
State9 = State0
|
|
),
|
|
|
|
% If the pass changed the module_info, it may have changed
|
|
% the pred table or the proc table for this pred_id. Don't
|
|
% take any chances.
|
|
|
|
module_info_preds(ModuleInfo8, Preds8),
|
|
map__lookup(Preds8, PredId, Pred8),
|
|
pred_info_procedures(Pred8, Procs8),
|
|
|
|
map__det_update(Procs8, ProcId, Proc, Procs),
|
|
pred_info_set_procedures(Pred8, Procs, Pred),
|
|
map__det_update(Preds8, PredId, Pred, Preds),
|
|
module_info_set_preds(ModuleInfo8, Preds, ModuleInfo9),
|
|
|
|
process_nonimported_procs(ProcIds, PredId, Task1, Task,
|
|
ModuleInfo9, ModuleInfo, State9, State).
|
|
|
|
write_pred_progress_message(Message, PredId, ModuleInfo) -->
|
|
globals__io_lookup_bool_option(very_verbose, VeryVerbose),
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string(Message),
|
|
hlds_out__write_pred_id(ModuleInfo, PredId),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
).
|
|
|
|
write_proc_progress_message(Message, PredId, ProcId, ModuleInfo) -->
|
|
globals__io_lookup_bool_option(very_verbose, VeryVerbose),
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string(Message),
|
|
hlds_out__write_pred_proc_id(ModuleInfo, PredId, ProcId),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
).
|
|
|
|
maybe_report_stats(yes) --> io__report_stats.
|
|
maybe_report_stats(no) --> [].
|
|
|
|
maybe_write_string(yes, String) --> io__write_string(String).
|
|
maybe_write_string(no, _) --> [].
|
|
|
|
maybe_flush_output(yes) --> io__flush_output.
|
|
maybe_flush_output(no) --> [].
|
|
|
|
report_error(ErrorMessage) -->
|
|
io__write_string("Error: "),
|
|
io__write_string(ErrorMessage),
|
|
io__write_string("\n"),
|
|
io__set_exit_status(1).
|
|
|
|
:- pred passes_aux__handle_errors(int, int, module_info, module_info,
|
|
io__state, io__state).
|
|
:- mode passes_aux__handle_errors(in, in, in, out, di, uo) is det.
|
|
|
|
passes_aux__handle_errors(WarnCnt, ErrCnt, ModuleInfo1, ModuleInfo8,
|
|
State1, State9) :-
|
|
globals__io_lookup_bool_option(halt_at_warn, HaltAtWarn,
|
|
State1, State2),
|
|
(
|
|
(
|
|
ErrCnt > 0
|
|
;
|
|
WarnCnt > 0,
|
|
HaltAtWarn = yes
|
|
)
|
|
->
|
|
io__set_exit_status(1, State2, State9),
|
|
module_info_incr_errors(ModuleInfo1, ModuleInfo8)
|
|
;
|
|
ModuleInfo8 = ModuleInfo1,
|
|
State9 = State2
|
|
).
|
|
|
|
invoke_system_command(Command, Succeeded) -->
|
|
globals__io_lookup_bool_option(verbose, Verbose),
|
|
( { Verbose = yes } ->
|
|
io__write_string("% Invoking system command `"),
|
|
io__write_string(Command),
|
|
io__write_string("'...\n"),
|
|
io__flush_output
|
|
;
|
|
[]
|
|
),
|
|
io__call_system(Command, Result),
|
|
( { Result = ok(0) } ->
|
|
maybe_write_string(Verbose, "% done.\n"),
|
|
{ Succeeded = yes }
|
|
; { Result = ok(_) } ->
|
|
report_error("system command returned non-zero exit status."),
|
|
{ Succeeded = no }
|
|
;
|
|
report_error("unable to invoke system command."),
|
|
{ Succeeded = no }
|
|
).
|
|
|
|
maybe_report_sizes(HLDS) -->
|
|
globals__io_lookup_bool_option(statistics, Statistics),
|
|
( { Statistics = yes } ->
|
|
report_sizes(HLDS)
|
|
;
|
|
[]
|
|
).
|
|
|
|
:- pred report_sizes(module_info, io__state, io__state).
|
|
:- mode report_sizes(in, di, uo) is det.
|
|
|
|
report_sizes(ModuleInfo) -->
|
|
{ module_info_preds(ModuleInfo, Preds) },
|
|
tree_stats("Pred table", Preds),
|
|
{ module_info_types(ModuleInfo, Types) },
|
|
tree_stats("Type table", Types),
|
|
{ module_info_ctors(ModuleInfo, Ctors) },
|
|
tree_stats("Constructor table", Ctors).
|
|
|
|
:- pred tree_stats(string, map(_K, _V), io__state, io__state).
|
|
:- mode tree_stats(in, in, di, uo) is det.
|
|
|
|
tree_stats(Description, Tree) -->
|
|
{ map__count(Tree, Count) },
|
|
io__write_string(Description),
|
|
io__write_string(": count = "),
|
|
io__write_int(Count),
|
|
io__write_string("\n").
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
report_pred_proc_id(ModuleInfo, PredId, ProcId, MaybeContext, Context) -->
|
|
{ module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
|
|
PredInfo, ProcInfo) },
|
|
{ pred_info_name(PredInfo, PredName) },
|
|
{ pred_info_arity(PredInfo, Arity) },
|
|
{ pred_info_get_is_pred_or_func(PredInfo, PredOrFunc) },
|
|
{ proc_info_context(ProcInfo, Context) },
|
|
{ proc_info_argmodes(ProcInfo, ArgModes0) },
|
|
|
|
% We need to strip off the extra type_info arguments inserted at the
|
|
% front by polymorphism.m - we only want the last `PredArity' of them.
|
|
%
|
|
{ list__length(ArgModes0, NumArgModes) },
|
|
{ NumToDrop is NumArgModes - Arity },
|
|
( { list__drop(NumToDrop, ArgModes0, ArgModes1) } ->
|
|
{ ArgModes = ArgModes1 }
|
|
;
|
|
{ error("report_pred_proc_id: list__drop failed") }
|
|
),
|
|
(
|
|
{ MaybeContext = yes(OutContext) }
|
|
;
|
|
{ MaybeContext = no },
|
|
{ OutContext = Context }
|
|
),
|
|
prog_out__write_context(OutContext),
|
|
io__write_string("In `"),
|
|
report_pred_name_mode(PredOrFunc, PredName, ArgModes),
|
|
io__write_string("':\n").
|
|
|
|
|
|
report_pred_name_mode(predicate, PredName, ArgModes) -->
|
|
io__write_string(PredName),
|
|
( { ArgModes \= [] } ->
|
|
{ varset__init(InstVarSet) }, % XXX inst var names
|
|
io__write_string("("),
|
|
{ strip_builtin_qualifiers_from_mode_list(ArgModes,
|
|
ArgModes1) },
|
|
mercury_output_mode_list(ArgModes1, InstVarSet),
|
|
io__write_string(")")
|
|
;
|
|
[]
|
|
).
|
|
|
|
report_pred_name_mode(function, FuncName, ArgModes) -->
|
|
{ varset__init(InstVarSet) }, % XXX inst var names
|
|
{ strip_builtin_qualifiers_from_mode_list(ArgModes, ArgModes1) },
|
|
{ pred_args_to_func_args(ArgModes1, FuncArgModes, FuncRetMode) },
|
|
io__write_string(FuncName),
|
|
( { FuncArgModes \= [] } ->
|
|
io__write_string("("),
|
|
mercury_output_mode_list(FuncArgModes, InstVarSet),
|
|
io__write_string(")")
|
|
;
|
|
[]
|
|
),
|
|
io__write_string(" = "),
|
|
mercury_output_mode(FuncRetMode, InstVarSet).
|
|
|
|
%-----------------------------------------------------------------------------%
|