Files
mercury/compiler/ctgc.datastruct.m
Zoltan Somogyi 22c831ffe7 Convert the ctgc modules to use var_tables.
compiler/ctgc.datastruct.m:
compiler/ctgc.livedata.m:
compiler/ctgc.util.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
    Convert these modules to use var_tables.

    In cases where predicates took a proc_info argument that they used
    only to get access to type information, replace that argument
    with a var_table.

    In cases where predicates took a proc_info argument that they used
    both to get access to type information and for some other purpose,
    and their parent had the var_table already available, add the
    var_table as an additional argument.

compiler/type_util.m:
    Add var_table versions of some utility predicates for use
    by the modules above.

compiler/type_util.m:
2022-05-01 08:38:17 +10:00

202 lines
7.1 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 2006, 2009, 2012 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: ctgc.datastruct.m.
% Main author: nancy.
%
% Definition of predicates and functions for the manipulation of
% datastructures.
%
%---------------------------------------------------------------------------%
:- module transform_hlds.ctgc.datastruct.
:- interface.
:- import_module hlds.
:- import_module hlds.hlds_module.
:- import_module parse_tree.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_pragma.
:- import_module parse_tree.var_table.
:- import_module list.
%---------------------------------------------------------------------------%
% Create an initial top-datastruct of the given variable.
%
:- func datastruct_init(prog_var) = datastruct.
:- func datastruct_init_with_selector(prog_var, selector) = datastruct.
:- func datastruct_init_with_pos(prog_var, cons_id, int) = datastruct.
% Verify whether the given datastructs are identical.
%
:- pred datastruct_equal(datastruct::in, datastruct::in) is semidet.
% Check whether the two given datastructs are related to the
% same variable or not.
%
:- pred datastruct_same_vars(datastruct::in, datastruct::in) is semidet.
% Verify whether the datastructure represents a top cell, i.e. where
% the selector path is an empty path.
%
:- pred datastruct_refers_to_topcell(datastruct::in) is semidet.
% Select a subterm of the given datastructure using the specified selector.
% It is assumed that the selector is a valid selector for that
% datastructure.
%
:- func datastruct_termshift(module_info, var_table, selector, datastruct)
= datastruct.
% Normalize the representation of the datastructure.
% (proc_info is needed to obtain the type of the variable of the
% datastructure).
% The selector of a datastruct is normalized
% iff none of the term nodes met on the path to the actual selected
% term by the selector has the same type as the selected node.
%
:- func normalize_datastruct(module_info, var_table, datastruct) = datastruct.
:- pred datastruct_subsumed_by_return_selector(module_info::in, var_table::in,
datastruct::in, datastruct::in, selector::out) is semidet.
:- pred datastruct_subsumed_by(module_info::in, var_table::in,
datastruct::in, datastruct::in) is semidet.
:- pred datastruct_subsumed_by_list(module_info::in, var_table::in,
datastruct::in, list(datastruct)::in) is semidet.
:- pred datastructs_subsumed_by_list(module_info::in, var_table::in,
list(datastruct)::in, list(datastruct)::in) is semidet.
:- pred datastructs_that_are_subsumed_by_list(module_info::in, var_table::in,
list(datastruct)::in, list(datastruct)::in, list(datastruct)::out) is det.
:- func datastruct_lists_least_upper_bound(module_info, var_table,
list(datastruct), list(datastruct)) = list(datastruct).
:- pred datastruct_apply_widening(module_info::in, var_table::in,
datastruct::in, datastruct::out) is det.
:- func datastructs_project(list(prog_var),
list(datastruct)) = list(datastruct).
:- func datastructs_vars(list(datastruct)) = list(prog_var).
%---------------------------------------------------------------------------%
:- implementation.
:- import_module transform_hlds.ctgc.selector.
%---------------------------------------------------------------------------%
datastruct_init(V) = datastruct_init_with_selector(V, []).
datastruct_init_with_selector(V, Sel) = selected_cel(V, Sel).
datastruct_init_with_pos(V, ConsId, Int)
= datastruct_init_with_selector(V, selector_init(ConsId, Int)).
datastruct_equal(D1, D2) :- D1 = D2.
datastruct_same_vars(D1, D2) :-
D1 ^ sc_var = D2 ^ sc_var.
datastruct_refers_to_topcell(Data):-
DSel = Data ^ sc_selector,
DSel = [].
datastruct_termshift(ModuleInfo, VarTable, Sel, Data0) = Data :-
(
Sel = [],
Data = Data0
;
Sel = [_ | _],
Data0 = selected_cel(Var, DSel),
selector_termshift(DSel, Sel, NewSel0),
% Keep datastruct seletors normalized.
lookup_var_type(VarTable, Var, Type),
normalize_selector_with_type_information(ModuleInfo, Type,
NewSel0, NewSel),
Data = selected_cel(Var, NewSel)
).
normalize_datastruct(ModuleInfo, VarTable, Data0) = Data :-
Data0 = selected_cel(Var, DSel0),
lookup_var_type(VarTable, Var, Type),
normalize_selector_with_type_information(ModuleInfo, Type, DSel0, DSel),
Data = selected_cel(Var, DSel).
datastruct_subsumed_by_return_selector(ModuleInfo, VarTable, Data1, Data2,
Extension) :-
Data1 = selected_cel(Var, Sel1),
Data2 = selected_cel(Var, Sel2),
lookup_var_type(VarTable, Var, Type),
selector_subsumed_by(ModuleInfo, already_normalized,
Sel1, Sel2, Type, Extension).
datastruct_subsumed_by(ModuleInfo, VarTable, Data1, Data2) :-
datastruct_subsumed_by_return_selector(ModuleInfo, VarTable, Data1, Data2,
_).
datastruct_subsumed_by_list(ModuleInfo, VarTable, Data0, [Data | Rest]):-
(
datastruct_subsumed_by(ModuleInfo, VarTable, Data0, Data)
;
datastruct_subsumed_by_list(ModuleInfo, VarTable, Data0, Rest)
).
datastructs_subsumed_by_list(ModuleInfo, VarTable, PerhapsSubsumedData,
Data) :-
all [X] (
list.member(X, PerhapsSubsumedData)
=>
datastructs_subsume_datastruct(ModuleInfo, VarTable, Data, X)
).
datastructs_that_are_subsumed_by_list(ModuleInfo, VarTable,
PerhapsSubsumedData, Datastructs, SubsumedData) :-
list.filter(
datastructs_subsume_datastruct(ModuleInfo, VarTable, Datastructs),
PerhapsSubsumedData, SubsumedData).
:- pred datastructs_subsume_datastruct(module_info::in, var_table::in,
list(datastruct)::in, datastruct::in) is semidet.
datastructs_subsume_datastruct(ModuleInfo, VarTable, Datastructs, Data):-
datastruct_subsumed_by_list(ModuleInfo, VarTable, Data, Datastructs).
datastruct_lists_least_upper_bound(ModuleInfo, VarTable, Data1, Data2)
= Data :-
list.filter(
datastructs_subsume_datastruct(ModuleInfo, VarTable, Data1),
Data2, _SubsumedData, NotSubsumedData),
Data = list.append(NotSubsumedData, Data1).
datastruct_apply_widening(ModuleInfo, VarTable, Data0, Data) :-
Data0 = selected_cel(Var, Sel0),
lookup_var_type(VarTable, Var, Type),
selector_apply_widening(ModuleInfo, Type, Sel0, Sel),
Data = selected_cel(Var, Sel).
datastructs_project(Vars, DataIn) =
list.filter(
(pred(Data::in) is semidet :- list.member(Data ^ sc_var, Vars)),
DataIn).
datastructs_vars(Data) = list.map(func(X) = X ^ sc_var, Data).
%---------------------------------------------------------------------------%
:- end_module transform_hlds.ctgc.datastruct.
%---------------------------------------------------------------------------%