mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 09:53:36 +00:00
The motivation for this diff is something I saw when I fixed the bug in
equiv_type_hlds.m on aug 13. During the bootcheck to verify the bug fix,
I enabled the end-of-front-end HLDS dump, and I saw that one module,
deep_profiler/display_report.m, had some references to MISSING_INSTs
in its HLDS dump. Since these could be signs of a bug in mode analysis,
I tracked them down. It turns out that the cause was an incompatibility
between the code that existed in error_msg_inst.m before that fix,
and the new code there added by that fix. But ironically, to find that
incompatibility, I first had to extend error_msg_inst.m's functionality
still further, specifically to make it possible to use it to write out insts
in HLDS dumps.
The reason for this need is that that the old code for dumping out insts
left a lot to be desired. It ignored (as in, it never wrote out) some parts
of specific kinds insts, such as the types in typed insts, without which
some parts of HLDS dumps did not make sense. For example, the ground inst
table in the HLDS dump of display_report.m contained several keys whose
printed versions were identical, seemingly indicating a bug in the code
that added new entries to that table (since it is supposed to add a new entry
to the table if the relevant key does not yet exist in the table). It turns
out that there was no bug; the keys differed, but only in the types.
compiler/error_msg_inst.m:
Fix the incompatibility, and document both it, and its solution.
Besides error_msg_inst, export a new function error_msg_inst_name,
which does the same thing for inst_names as error_msg_inst does for insts.
Add a flag to both functions that specifies whether the intended use
of the return value is in an error message (whose audience is usually
an ordinary Mercury user) or a HLDS dump (whose audience is always
a Mercury developer). Include details such as the types in typed insts,
and the structure of the compiler-generated inst names generally,
which involve concepts that users do not know about, in the output
only if the flag says the audience is Mercury developers.
When printing out type or inst variables, use their actual names
if these are available. To make this possible, require the callers
of error_msg_{inst,inst_name} to provide tvarsets and inst_varsets,
instead of always using empty varsets. The caller may still pass
empty varsets if cannot do better than that, but most callers can,
and now do pass valid varsets.
compiler/hlds_out_goal.m:
Since we now want to pass a valid tvarset to error_msg_inst.m
when printing the insts in goals' instmap_deltas, we need to pass around
the tvarset, as well as the inst_varset, of the procedure that the goal
was taken from. Instead of adding yet another parameter to all the affected
predicates, replace all the existing parameters that have the same role
(of which there were already about half a dozen) with a parameter
of a new type named hlds_out_info_goal, which contains the values of
all these old parameters, and the new one.
compiler/hlds_out_inst_table.m:
Use the same setting to govern whether we use error_msg_inst.m's
facilities for writing out insts and inst names in both the keys
and the values of the various inst tables.
compiler/simplify_info.m:
Include tvarsets in simplify_infos, since dumping out goals during
simplification pass can now use this information.
compiler/add_clause.m:
compiler/add_mutable_aux_preds.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/direct_arg_in_out.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/hlds_out_pred.m:
compiler/inst_abstract_unify.m:
compiler/inst_lookup.m:
compiler/intermod.m:
compiler/lco.m:
compiler/liveness.m:
compiler/make_hlds_warn.m:
compiler/mode_errors.m:
compiler/pd_debug.m:
compiler/prog_mode.m:
compiler/push_goals_together.m:
compiler/saved_vars.m:
compiler/simplify_goal.m:
compiler/simplify_goal_conj.m:
compiler/simplify_proc.m:
compiler/stack_opt.m:
compiler/superhomogeneous.m:
compiler/unneeded_code.m:
Conform to the changes above.
282 lines
10 KiB
Mathematica
282 lines
10 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 1998-2007, 2009-2011 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: pd_debug_m
|
|
% Main author: stayl.
|
|
%
|
|
% Debugging routines for partial deduction.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module transform_hlds.pd_debug.
|
|
:- interface.
|
|
|
|
:- import_module hlds.
|
|
:- import_module hlds.hlds_goal.
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.prog_data.
|
|
:- import_module transform_hlds.pd_info.
|
|
|
|
:- import_module io.
|
|
:- import_module list.
|
|
:- import_module string.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred pd_debug_message(pd_info::in,
|
|
string::in, list(string.poly_type)::in, io::di, io::uo) is det.
|
|
|
|
:- pred pd_debug_message_context(pd_info::in, prog_context::in,
|
|
string::in, list(string.poly_type)::in, io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred pd_debug_search_version_result(pd_info::in, maybe_version::in,
|
|
io::di, io::uo) is det.
|
|
|
|
:- pred pd_debug_register_version(pd_info::in, pred_proc_id::in,
|
|
version_info::in, io::di, io::uo) is det.
|
|
|
|
:- pred pd_debug_write_instmap(pd_info::in, io::di, io::uo) is det.
|
|
|
|
:- pred pd_debug_write_pred_proc_id_list(pd_info::in, list(pred_proc_id)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
:- pred pd_debug_output_goal(pd_info::in, string::in, hlds_goal::in,
|
|
io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module hlds.goal_util.
|
|
:- import_module hlds.hlds_module.
|
|
:- import_module hlds.hlds_out.
|
|
:- import_module hlds.hlds_out.hlds_out_goal.
|
|
:- import_module hlds.hlds_out.hlds_out_mode.
|
|
:- import_module hlds.hlds_out.hlds_out_util.
|
|
:- import_module hlds.instmap.
|
|
:- import_module libs.
|
|
:- import_module libs.globals.
|
|
:- import_module libs.options.
|
|
:- import_module parse_tree.parse_tree_out_info.
|
|
:- import_module parse_tree.parse_tree_out_misc.
|
|
:- import_module parse_tree.parse_tree_out_term.
|
|
:- import_module parse_tree.var_db.
|
|
:- import_module parse_tree.var_table.
|
|
|
|
:- import_module bool.
|
|
:- import_module set.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
pd_debug_message(PDInfo, Fmt, Args, !IO) :-
|
|
pd_info_get_module_info(PDInfo, ModuleInfo),
|
|
module_info_get_globals(ModuleInfo, Globals),
|
|
globals.lookup_bool_option(Globals, debug_pd, DebugPD),
|
|
(
|
|
DebugPD = no
|
|
;
|
|
DebugPD = yes,
|
|
module_info_get_name(ModuleInfo, ModuleName),
|
|
get_debug_output_stream(Globals, ModuleName, Stream, !IO),
|
|
disable_warning [unknown_format_calls] (
|
|
io.format(Stream, Fmt, Args, !IO)
|
|
),
|
|
io.flush_output(Stream, !IO)
|
|
).
|
|
|
|
pd_debug_message_context(PDInfo, Context, Fmt, Args, !IO) :-
|
|
pd_info_get_module_info(PDInfo, ModuleInfo),
|
|
module_info_get_globals(ModuleInfo, Globals),
|
|
globals.lookup_bool_option(Globals, debug_pd, DebugPD),
|
|
(
|
|
DebugPD = no
|
|
;
|
|
DebugPD = yes,
|
|
module_info_get_name(ModuleInfo, ModuleName),
|
|
get_debug_output_stream(Globals, ModuleName, Stream, !IO),
|
|
parse_tree_out_misc.write_context(Stream, Context, !IO),
|
|
disable_warning [unknown_format_calls] (
|
|
io.format(Stream, Fmt, Args, !IO)
|
|
),
|
|
io.flush_output(Stream, !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
pd_debug_search_version_result(PDInfo, MaybeVersion, !IO) :-
|
|
pd_info_get_module_info(PDInfo, ModuleInfo),
|
|
module_info_get_globals(ModuleInfo, Globals),
|
|
globals.lookup_bool_option(Globals, debug_pd, DebugPD),
|
|
(
|
|
DebugPD = no
|
|
;
|
|
DebugPD = yes,
|
|
module_info_get_name(ModuleInfo, ModuleName),
|
|
get_debug_output_stream(Globals, ModuleName, Stream, !IO),
|
|
(
|
|
MaybeVersion = no_version,
|
|
io.write_string(Stream, "Specialised version not found.\n", !IO)
|
|
;
|
|
MaybeVersion = version(exact, _, _, _, _),
|
|
io.write_string(Stream, "Exact match found.\n", !IO)
|
|
;
|
|
MaybeVersion = version(more_general, PredProcId, Version, _, _),
|
|
io.write_string(Stream, "More general version.\n", !IO),
|
|
pd_debug_output_version(Stream, ModuleInfo, PredProcId, Version,
|
|
no, !IO)
|
|
)
|
|
).
|
|
|
|
%------------%
|
|
|
|
pd_debug_register_version(PDInfo, PredProcId, Version, !IO) :-
|
|
pd_info_get_module_info(PDInfo, ModuleInfo),
|
|
module_info_get_globals(ModuleInfo, Globals),
|
|
globals.lookup_bool_option(Globals, debug_pd, DebugPD),
|
|
(
|
|
DebugPD = no
|
|
;
|
|
DebugPD = yes,
|
|
module_info_get_name(ModuleInfo, ModuleName),
|
|
get_debug_output_stream(Globals, ModuleName, Stream, !IO),
|
|
|
|
io.write_string(Stream, "Registering version:\n", !IO),
|
|
pd_debug_output_version(Stream, ModuleInfo, PredProcId, Version,
|
|
no, !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred pd_debug_output_version(io.text_output_stream::in, module_info::in,
|
|
pred_proc_id::in, version_info::in, bool::in, io::di, io::uo) is det.
|
|
|
|
pd_debug_output_version(Stream, ModuleInfo, PredProcId, Version,
|
|
WriteUnfoldedGoal, !IO) :-
|
|
Version = version_info(Goal, _, Args, _, InstMap,
|
|
InitialCost, CostDelta, Parents, _),
|
|
Goal = hlds_goal(_GoalExpr, GoalInfo),
|
|
PredName = predicate_name(ModuleInfo, PredId),
|
|
PredProcId = proc(PredId, ProcId),
|
|
pred_id_to_int(PredId, PredInt),
|
|
proc_id_to_int(ProcId, ProcInt),
|
|
|
|
io.format(Stream, "%s: (PredProcId :%d-%d)\n",
|
|
[s(PredName), i(PredInt), i(ProcInt)], !IO),
|
|
io.format(Stream, " initial cost: %d\n", [i(InitialCost)], !IO),
|
|
io.format(Stream, " cost delta: %d\n", [i(CostDelta)], !IO),
|
|
NonLocals = goal_info_get_nonlocals(GoalInfo),
|
|
module_info_pred_proc_info(ModuleInfo, PredId, ProcId, PredInfo, ProcInfo),
|
|
proc_info_get_var_table(ProcInfo, VarTable),
|
|
instmap_restrict(NonLocals, InstMap, InstMap1),
|
|
ArgsStr = mercury_vars_to_string(VarTable, print_name_and_num, Args),
|
|
InstMap1Str = instmap_to_string(VarTable, print_name_and_num, 1, InstMap1),
|
|
io.format(Stream, " args: %s\n%s\n", [s(ArgsStr), s(InstMap1Str)], !IO),
|
|
module_info_get_globals(ModuleInfo, Globals),
|
|
OutInfo = init_hlds_out_info(Globals, output_debug),
|
|
VarNameSrc = vns_var_table(VarTable),
|
|
pred_info_get_typevarset(PredInfo, TVarSet),
|
|
proc_info_get_inst_varset(ProcInfo, InstVarSet),
|
|
write_goal_nl(OutInfo, Stream, ModuleInfo, VarNameSrc, print_name_and_num,
|
|
TVarSet, InstVarSet, 1, "\n", Goal, !IO),
|
|
set.to_sorted_list(Parents, ParentsList),
|
|
ParentStrs = list.map(pred_proc_id_to_dev_string(ModuleInfo), ParentsList),
|
|
ParentsStr = string.join_list(", ", ParentStrs),
|
|
io.format(Stream, "Parents: %s\n", [s(ParentsStr)], !IO),
|
|
% XXX Neither of our callers specify WriteUnfoldedGoal = yes.
|
|
(
|
|
WriteUnfoldedGoal = yes,
|
|
proc_info_get_goal(ProcInfo, ProcGoal),
|
|
io.write_string(Stream, "Unfolded goal\n", !IO),
|
|
write_goal_nl(OutInfo, Stream, ModuleInfo, VarNameSrc,
|
|
print_name_and_num, TVarSet, InstVarSet, 1, "\n", ProcGoal, !IO)
|
|
;
|
|
WriteUnfoldedGoal = no
|
|
).
|
|
|
|
%------------%
|
|
|
|
pd_debug_write_instmap(PDInfo, !IO) :-
|
|
pd_info_get_module_info(PDInfo, ModuleInfo),
|
|
module_info_get_globals(ModuleInfo, Globals),
|
|
globals.lookup_bool_option(Globals, debug_pd, DebugPD),
|
|
(
|
|
DebugPD = no
|
|
;
|
|
DebugPD = yes,
|
|
module_info_get_name(ModuleInfo, ModuleName),
|
|
get_debug_output_stream(Globals, ModuleName, Stream, !IO),
|
|
|
|
pd_info_get_proc_info(PDInfo, ProcInfo),
|
|
proc_info_get_var_table(ProcInfo, VarTable),
|
|
pd_info_get_instmap(PDInfo, InstMap),
|
|
InstMapStr = instmap_to_string(VarTable, print_name_and_num,
|
|
1, InstMap),
|
|
io.write_string(Stream, InstMapStr, !IO),
|
|
io.flush_output(Stream, !IO)
|
|
).
|
|
|
|
%------------%
|
|
|
|
pd_debug_write_pred_proc_id_list(PDInfo, PredProcIds, !IO) :-
|
|
pd_info_get_module_info(PDInfo, ModuleInfo),
|
|
module_info_get_globals(ModuleInfo, Globals),
|
|
globals.lookup_bool_option(Globals, debug_pd, DebugPD),
|
|
(
|
|
DebugPD = no
|
|
;
|
|
DebugPD = yes,
|
|
module_info_get_name(ModuleInfo, ModuleName),
|
|
get_debug_output_stream(Globals, ModuleName, Stream, !IO),
|
|
|
|
ProcStrs =
|
|
list.map(pred_proc_id_to_dev_string(ModuleInfo), PredProcIds),
|
|
ProcsStr = string.join_list(", ", ProcStrs),
|
|
io.write_string(Stream, ProcsStr, !IO),
|
|
io.flush_output(Stream, !IO)
|
|
).
|
|
|
|
%------------%
|
|
|
|
pd_debug_output_goal(PDInfo, Msg, Goal, !IO) :-
|
|
pd_info_get_module_info(PDInfo, ModuleInfo),
|
|
module_info_get_globals(ModuleInfo, Globals),
|
|
globals.lookup_bool_option(Globals, debug_pd, DebugPD),
|
|
(
|
|
DebugPD = no
|
|
;
|
|
DebugPD = yes,
|
|
module_info_get_name(ModuleInfo, ModuleName),
|
|
get_debug_output_stream(Globals, ModuleName, Stream, !IO),
|
|
|
|
Goal = hlds_goal(GoalExpr, GoalInfo),
|
|
pd_info_get_pred_info(PDInfo, PredInfo),
|
|
pd_info_get_proc_info(PDInfo, ProcInfo),
|
|
proc_info_get_var_table(ProcInfo, VarTable),
|
|
pd_info_get_instmap(PDInfo, InstMap),
|
|
goal_util.goal_vars(hlds_goal(GoalExpr, GoalInfo), Vars),
|
|
instmap_restrict(Vars, InstMap, VarsInstMap),
|
|
|
|
OutInfo = init_hlds_out_info(Globals, output_debug),
|
|
InstmapStr = instmap_to_string(VarTable, print_name_and_num,
|
|
1, VarsInstMap),
|
|
io.format(Stream, "%s%s\n", [s(InstmapStr), s(Msg)], !IO),
|
|
pred_info_get_typevarset(PredInfo, TVarSet),
|
|
proc_info_get_inst_varset(ProcInfo, InstVarSet),
|
|
write_goal_nl(OutInfo, Stream, ModuleInfo, vns_var_table(VarTable),
|
|
print_name_and_num, TVarSet, InstVarSet, 1, "\n", Goal, !IO),
|
|
io.flush_output(Stream, !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module transform_hlds.pd_debug.
|
|
%---------------------------------------------------------------------------%
|