Files
mercury/compiler/higher_order.higher_order_info.m
2024-06-09 08:34:36 +10:00

161 lines
5.6 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1996-2012 The University of Melbourne.
% Copyright (C) 2014-2024 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.
%---------------------------------------------------------------------------%
:- module transform_hlds.higher_order.higher_order_info.
:- interface.
:- import_module hlds.
:- import_module hlds.hlds_pred.
:- import_module transform_hlds.higher_order.higher_order_global_info.
:- import_module set.
%---------------------------------------------------------------------------%
% Returned by ho_traverse_proc_body.
%
:- type ho_changed
---> hoc_changed % Need to requantify goal + check other procs.
; hoc_request % Need to check other procs.
; hoc_unchanged. % Do nothing more for this predicate.
% Used while traversing goals.
%
:- type higher_order_info.
:- func hoi_init(higher_order_global_info, pred_id, proc_id)
= higher_order_info.
:- pred hoi_results(higher_order_info::in, higher_order_global_info::out,
pred_info::out, proc_info::out, set(ho_request)::out) is det.
:- func hoi_get_global_info(higher_order_info) = higher_order_global_info.
:- func hoi_get_pred_proc_id(higher_order_info) = pred_proc_id.
:- func hoi_get_pred_info(higher_order_info) = pred_info.
:- func hoi_get_proc_info(higher_order_info) = proc_info.
:- func hoi_get_known_var_map(higher_order_info) = known_var_map.
:- func hoi_get_changed(higher_order_info) = ho_changed.
:- pred hoi_set_global_info(higher_order_global_info::in,
higher_order_info::in, higher_order_info::out) is det.
:- pred hoi_set_pred_info(pred_info::in,
higher_order_info::in, higher_order_info::out) is det.
:- pred hoi_set_proc_info(proc_info::in,
higher_order_info::in, higher_order_info::out) is det.
:- pred hoi_set_known_var_map(known_var_map::in,
higher_order_info::in, higher_order_info::out) is det.
:- pred hoi_set_changed(ho_changed::in,
higher_order_info::in, higher_order_info::out) is det.
:- pred hoi_add_request(ho_request::in,
higher_order_info::in, higher_order_info::out) is det.
%---------------------------------------------------------------------------%
:- implementation.
:- import_module hlds.hlds_module.
:- import_module parse_tree.
:- import_module parse_tree.prog_data.
:- import_module map.
%---------------------------------------------------------------------------%
% Used while traversing goals.
%
:- type higher_order_info
---> higher_order_info(
% The hoi_pred_proc_id field is read-only. All the others
% are read-write.
hoi_global_info :: higher_order_global_info,
% The pred_proc_id, pred_info and proc_info of the procedure
% whose body is being traversed.
hoi_pred_proc_id :: pred_proc_id,
hoi_pred_info :: pred_info,
hoi_proc_info :: proc_info,
% Higher order variables with unique known values.
hoi_known_var_map :: known_var_map,
hoi_requests :: set(ho_request),
hoi_changed :: ho_changed
).
hoi_init(GlobalInfo0, PredId, ProcId) = Info :-
ModuleInfo0 = hogi_get_module_info(GlobalInfo0),
module_info_pred_proc_info(ModuleInfo0, PredId, ProcId,
PredInfo0, ProcInfo0),
PredProcId = proc(PredId, ProcId),
map.init(KnownVarMap0),
set.init(Requests0),
Info = higher_order_info(GlobalInfo0, PredProcId, PredInfo0, ProcInfo0,
KnownVarMap0, Requests0, hoc_unchanged).
hoi_results(Info, GlobalInfo, PredInfo, ProcInfo, Requests) :-
Info = higher_order_info(GlobalInfo, _, PredInfo, ProcInfo, _,
Requests, _).
%---------------------------------------------------------------------------%
:- func hoi_get_requests(higher_order_info) = set(ho_request).
hoi_get_global_info(Info) = X :-
X = Info ^ hoi_global_info.
hoi_get_pred_proc_id(Info) = X :-
X = Info ^ hoi_pred_proc_id.
hoi_get_pred_info(Info) = X :-
X = Info ^ hoi_pred_info.
hoi_get_proc_info(Info) = X :-
X = Info ^ hoi_proc_info.
hoi_get_known_var_map(Info) = X :-
X = Info ^ hoi_known_var_map.
hoi_get_requests(Info) = X :-
X = Info ^ hoi_requests.
hoi_get_changed(Info) = X :-
X = Info ^ hoi_changed.
:- pred hoi_set_requests(set(ho_request)::in,
higher_order_info::in, higher_order_info::out) is det.
hoi_set_global_info(X, !Info) :-
!Info ^ hoi_global_info := X.
hoi_set_pred_info(X, !Info) :-
!Info ^ hoi_pred_info := X.
hoi_set_proc_info(X, !Info) :-
!Info ^ hoi_proc_info := X.
hoi_set_known_var_map(X, !Info) :-
!Info ^ hoi_known_var_map := X.
hoi_set_requests(X, !Info) :-
!Info ^ hoi_requests := X.
hoi_set_changed(X, !Info) :-
!Info ^ hoi_changed := X.
hoi_add_request(Request, !Info) :-
Requests0 = hoi_get_requests(!.Info),
set.insert(Request, Requests0, Requests),
hoi_set_requests(Requests, !Info),
Changed0 = hoi_get_changed(!.Info),
(
( Changed0 = hoc_changed
; Changed0 = hoc_request
)
% The existing status is still correct.
;
Changed0 = hoc_unchanged,
hoi_set_changed(hoc_request, !Info)
).
%---------------------------------------------------------------------------%
:- end_module transform_hlds.higher_order.higher_order_info.
%---------------------------------------------------------------------------%