mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
compiler/inst_lookup.m:
compiler/inst_mode_type_prop.m:
compiler/inst_test.m:
compiler/inst_util.m:
compiler/mode_util.m:
compiler/type_util.m:
Move these modules from the check_hlds package to the hlds package.
The reason is that all the content of five of these modules, and
most of the content of one module (inst_util.m) is not used
exclusively during semantic checking passes. (A later diff
should deal with the exception.) Some are used by the pass that
builds the initial HLDS, and all are used by middle-end and backend
passes. The move therefore reduces the number of inappropriate imports
of the check_hlds package.
compiler/check_hlds.m:
compiler/hlds.m:
Effect the transfer.
compiler/*.m:
Conform to the changes above.
183 lines
6.6 KiB
Mathematica
183 lines
6.6 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2005-2008, 2010-2011 The University of Melbourne.
|
|
% Copyright (C) 2014-2016, 2020-2025 The Mercury team.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% File smm_common.m.
|
|
% Main author: Quan Phan.
|
|
%
|
|
% This module contains defines types and procedures that are common to
|
|
% various static memory management analyses, e.g. CTGC, RBMM.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module transform_hlds.smm_common.
|
|
:- interface.
|
|
|
|
:- import_module hlds.
|
|
:- import_module hlds.hlds_goal.
|
|
:- import_module hlds.hlds_module.
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.goal_path.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.prog_data.
|
|
:- import_module parse_tree.prog_data_pragma.
|
|
|
|
:- import_module io.
|
|
:- import_module list.
|
|
:- import_module term.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% Succeeds if the selector selects the type node of the input type.
|
|
%
|
|
:- pred check_type_of_node(module_info::in, mer_type::in, selector::in)
|
|
is semidet.
|
|
|
|
% Succeeds if some (or all) of the procedures in the list are either
|
|
%
|
|
% - compiler generated unify, index, compare or init predicates, or
|
|
% - not defined in this module.
|
|
%
|
|
:- pred some_are_special_preds(list(pred_proc_id)::in, module_info::in)
|
|
is semidet.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Definition of a program point.
|
|
%
|
|
|
|
% A program point identifies a place at which a data structure possibly
|
|
% becomes garbage.
|
|
%
|
|
:- type program_point
|
|
---> pp(
|
|
pp_context :: term.context,
|
|
pp_id :: reverse_goal_path
|
|
).
|
|
|
|
% Compute the program point from the given goal_info.
|
|
%
|
|
% Note: for a meaningful use of this predicate, the goal's goal_id slot
|
|
% needs to be filled in (e.g. by a call to fill_goal_id_slots_in_proc).
|
|
%
|
|
% XXX This comment, this function, and the program point type have
|
|
% all suffered bit rot. They were written when fill_goal_id_slots_in_proc
|
|
% recorded a reverse_goal_path in each goal_info. However, it now records
|
|
% just a goal_id, which *can* be turned into a reverse_goal_path, but
|
|
% *only* with the help of a containing_goal_map, which this function
|
|
% has no access to. And the right solution to this problem would NOT be
|
|
% to add a containing_goal_map argument to this function, but to
|
|
% change the program_point type to use goal_ids instead. I (zs) have no
|
|
% idea how much modification this would require to the code operating on
|
|
% values of that type.
|
|
%
|
|
:- func program_point_init(hlds_goal_info) = program_point.
|
|
|
|
% Dump the information contained in a program point.
|
|
%
|
|
:- pred dump_program_point(io.text_output_stream::in, program_point::in,
|
|
io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module hlds.special_pred.
|
|
:- import_module hlds.status.
|
|
:- import_module hlds.type_util.
|
|
:- import_module parse_tree.parse_tree_out_misc.
|
|
|
|
:- import_module bool.
|
|
:- import_module map.
|
|
:- import_module string.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% Check if the selector is valid w.r.t the type.
|
|
%
|
|
check_type_of_node(ModuleInfo, StartType, Selector) :-
|
|
(
|
|
Selector = [Sel | Sels],
|
|
(
|
|
Sel = termsel(Cons_id, Choice),
|
|
select_subtype(ModuleInfo, StartType, Cons_id, Choice, SubType)
|
|
;
|
|
Sel = typesel(SubType)
|
|
),
|
|
check_type_of_node(ModuleInfo, SubType, Sels)
|
|
;
|
|
Selector = []
|
|
).
|
|
|
|
% Select the subtype of a type Type, selecting ConsId's position Position.
|
|
% Position counts starting from 1 (instead of 0).
|
|
% The predicate aborts if the subtype cannot be determined.
|
|
%
|
|
:- pred select_subtype(module_info::in, mer_type::in, cons_id::in, int::in,
|
|
mer_type::out) is semidet.
|
|
|
|
select_subtype(ModuleInfo, Type, ConsId, Choice, SubType) :-
|
|
get_cons_id_non_existential_arg_types(ModuleInfo, Type, ConsId, ArgTypes),
|
|
list.index1(ArgTypes, Choice, SubType).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
some_are_special_preds(PPIds, ModuleInfo) :-
|
|
(
|
|
module_info_get_special_pred_maps(ModuleInfo, SpecialPredMaps),
|
|
SpecialPredMaps = special_pred_maps(UnifyMap, IndexMap, CompareMap),
|
|
( some_special_preds_are_in_list(UnifyMap, PPIds)
|
|
; some_special_preds_are_in_list(IndexMap, PPIds)
|
|
; some_special_preds_are_in_list(CompareMap, PPIds)
|
|
)
|
|
;
|
|
list.filter(proc_not_defined_in_module(ModuleInfo), PPIds,
|
|
FilteredPPIds),
|
|
FilteredPPIds = [_ | _]
|
|
).
|
|
|
|
:- pred some_special_preds_are_in_list(map(type_ctor, pred_id)::in,
|
|
list(pred_proc_id)::in) is semidet.
|
|
|
|
some_special_preds_are_in_list(SpecMap, PPIds) :-
|
|
map.values(SpecMap, SpecialPredIds),
|
|
list.filter(
|
|
( pred(PPId::in) is semidet :-
|
|
PPId = proc(PredId, _),
|
|
list.member(PredId, SpecialPredIds)
|
|
),
|
|
PPIds, SpecialPPIds),
|
|
SpecialPPIds = [_ | _].
|
|
|
|
:- pred proc_not_defined_in_module(module_info::in, pred_proc_id::in)
|
|
is semidet.
|
|
|
|
proc_not_defined_in_module(ModuleInfo, proc(PredId, _)):-
|
|
module_info_pred_info(ModuleInfo, PredId, PredInfo),
|
|
pred_info_get_status(PredInfo, PredStatus),
|
|
pred_status_defined_in_this_module(PredStatus) = no.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
program_point_init(GoalInfo) = ProgPoint :-
|
|
Context = goal_info_get_context(GoalInfo),
|
|
RevGoalPath = goal_info_get_reverse_goal_path(GoalInfo),
|
|
ProgPoint = pp(Context, RevGoalPath).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
dump_program_point(Stream, pp(Context, RevGoalPath), !IO):-
|
|
parse_tree_out_misc.write_context(Stream, Context, !IO),
|
|
io.format(Stream, "--%s", [s(rev_goal_path_to_string(RevGoalPath))], !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module transform_hlds.smm_common.
|
|
%---------------------------------------------------------------------------%
|