mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-14 13:23:53 +00:00
Estimated hours taken: 10 Branches: main Make the mode analysis pass return errors as a single list of error specifications, instead of printing those error specifications out in bits and pieces as it goes along. Since the mode analysis code now does not need the I/O state to print out error messages, don't pass the I/O state around in it. Use trace goals when we need to print progress messages or debugging output. compiler/modes.m: compiler/unique_modes.m: compiler/modecheck_unify.m: compiler/modecheck_call.m: Implement the change described above. Rationalize the argument orders of some predicates. compiler/modes.m: compiler/unify_proc.m: Move the code for modechecking the procedures in the requested unify procedure queue from unify_proc.m to modes.m, since that is where all the related code is. Export a small, abstract part of the representation of the request queue from unify_proc.m to make this possible. compiler/mode_debug.m: Delete the checkpoint predicate's I/O state arguments. compiler/mode_errors.m: Replace predicates that print some error messages with functions that just return their error specifications. Delete some unused predicates. Replace a boolean with a purpose-specific type. Rationalize the argument orders of some predicates. compiler/cse_detection.m: compiler/delay_partial_inst.m: Don't pass around the I/O state, since it is now not needed. Rename a predicate to avoid ambiguity. compiler/mercury_compile.m: Conform to the changes above. Amongst other things, this means printing the error specifications returned by mode analysis. compiler/pd_util.m: compiler/try_expand.m: Conform to the changes above. compiler/error_util.m: Fix a typo. tests/invalid/bigtest.err_exp: tests/invalid/constrained_poly_insts.err_exp: Update these expected outputs for the new order of the error messages. (Before the error specifications are printed, they are sorted by context; this sorting did not occur in the old version.)
183 lines
5.8 KiB
Mathematica
183 lines
5.8 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 1996-1997, 2003-2009 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.
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% File: mode_debug.m.
|
|
% Main author: fjh.
|
|
%
|
|
% This module contains code for tracing the actions of the mode checker.
|
|
%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module check_hlds.mode_debug.
|
|
:- interface.
|
|
|
|
:- import_module check_hlds.mode_info.
|
|
|
|
% Print a debugging message which includes the port, message string,
|
|
% and the current instmap (but only if `--debug-modes' was enabled).
|
|
%
|
|
:- pred mode_checkpoint(port::in, string::in, mode_info::in, mode_info::out)
|
|
is det.
|
|
|
|
:- type port
|
|
---> enter
|
|
; exit
|
|
; wakeup.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module libs.
|
|
:- import_module libs.file_util.
|
|
:- import_module hlds.
|
|
:- import_module hlds.instmap.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.mercury_to_mercury.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
:- import_module assoc_list.
|
|
:- import_module bool.
|
|
:- import_module io.
|
|
:- import_module list.
|
|
:- import_module maybe.
|
|
:- import_module pair.
|
|
:- import_module term.
|
|
:- import_module varset.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
mode_checkpoint(Port, Msg, !ModeInfo) :-
|
|
mode_info_get_debug_modes(!.ModeInfo, DebugModes),
|
|
(
|
|
DebugModes = no
|
|
;
|
|
DebugModes = yes(debug_flags(Verbose, Minimal, Statistics)),
|
|
mode_info_get_errors(!.ModeInfo, Errors),
|
|
(
|
|
Port = enter,
|
|
PortStr = "Enter ",
|
|
Detail = yes
|
|
;
|
|
Port = wakeup,
|
|
PortStr = "Wake ",
|
|
Detail = no
|
|
;
|
|
Port = exit,
|
|
(
|
|
Errors = [],
|
|
PortStr = "Exit ",
|
|
Detail = yes
|
|
;
|
|
Errors = [_ | _],
|
|
PortStr = "Delay ",
|
|
Detail = no
|
|
)
|
|
),
|
|
mode_info_get_instmap(!.ModeInfo, InstMap),
|
|
trace [io(!IO)] (
|
|
io.write_string(PortStr, !IO),
|
|
io.write_string(Msg, !IO),
|
|
(
|
|
Detail = yes,
|
|
io.write_string(":\n", !IO),
|
|
maybe_report_stats(Statistics, !IO),
|
|
maybe_flush_output(Statistics, !IO),
|
|
( instmap_is_reachable(InstMap) ->
|
|
instmap_to_assoc_list(InstMap, NewInsts),
|
|
mode_info_get_last_checkpoint_insts(!.ModeInfo, OldInstMap),
|
|
mode_info_get_varset(!.ModeInfo, VarSet),
|
|
mode_info_get_instvarset(!.ModeInfo, InstVarSet),
|
|
write_var_insts(NewInsts, OldInstMap, VarSet, InstVarSet,
|
|
Verbose, Minimal, !IO)
|
|
;
|
|
io.write_string("\tUnreachable\n", !IO)
|
|
)
|
|
;
|
|
Detail = no
|
|
),
|
|
io.write_string("\n", !IO),
|
|
io.flush_output(!IO)
|
|
),
|
|
(
|
|
Detail = yes,
|
|
mode_info_set_last_checkpoint_insts(InstMap, !ModeInfo)
|
|
;
|
|
Detail = no
|
|
)
|
|
).
|
|
|
|
:- pred write_var_insts(assoc_list(prog_var, mer_inst)::in, instmap::in,
|
|
prog_varset::in, inst_varset::in, bool::in, bool::in,
|
|
io::di, io::uo) is det.
|
|
|
|
write_var_insts([], _, _, _, _, _, !IO).
|
|
write_var_insts([Var - Inst | VarInsts], OldInstMap, VarSet, InstVarSet,
|
|
Verbose, Minimal, !IO) :-
|
|
instmap_lookup_var(OldInstMap, Var, OldInst),
|
|
(
|
|
(
|
|
identical_insts(Inst, OldInst)
|
|
;
|
|
Inst = OldInst
|
|
)
|
|
->
|
|
(
|
|
Verbose = yes,
|
|
io.write_string("\t", !IO),
|
|
mercury_output_var(VarSet, no, Var, !IO),
|
|
io.write_string(" ::", !IO),
|
|
io.write_string(" unchanged\n", !IO)
|
|
;
|
|
Verbose = no
|
|
)
|
|
;
|
|
io.write_string("\t", !IO),
|
|
mercury_output_var(VarSet, no, Var, !IO),
|
|
io.write_string(" ::", !IO),
|
|
(
|
|
Minimal = yes,
|
|
io.write_string(" changed\n", !IO)
|
|
;
|
|
Minimal = no,
|
|
io.write_string("\n", !IO),
|
|
mercury_output_structured_inst(Inst, 2, InstVarSet, !IO)
|
|
)
|
|
),
|
|
write_var_insts(VarInsts, OldInstMap, VarSet, InstVarSet,
|
|
Verbose, Minimal, !IO).
|
|
|
|
% In the usual case of a C backend, this predicate allows us to
|
|
% conclude that two insts are identical without traversing them.
|
|
% Since the terms can be very large, this is a big gain; it can
|
|
% turn the complexity of printing a checkpoint from quadratic in the
|
|
% number of variables live at the checkpoint (when the variables
|
|
% are e.g. all part of a single long list) to linear. The minor
|
|
% increase in the constant factor in cases where identical_insts fails
|
|
% is much easier to live with.
|
|
%
|
|
:- pred identical_insts(mer_inst::in, mer_inst::in) is semidet.
|
|
|
|
identical_insts(_, _) :-
|
|
semidet_fail.
|
|
|
|
:- pragma foreign_proc("C",
|
|
identical_insts(InstA::in, InstB::in),
|
|
[will_not_call_mercury, promise_pure],
|
|
"
|
|
if (InstA == InstB) {
|
|
SUCCESS_INDICATOR = MR_TRUE;
|
|
} else {
|
|
SUCCESS_INDICATOR = MR_FALSE;
|
|
}
|
|
").
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|