mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-17 10:23:46 +00:00
compiler/op_mode.m:
Add a field that specifies whether the compiler was invoked by
"mmc --make" to the opm_top_args top-level op_mode. This is the
class of op_modes for which we need that info.
Fill in this new field from the value of the --invoked-by-mmc-make
option.
compiler/options.m:
Add an "only_opmode_" prefix to the internal name of the
--invoked-by-mmc-make option. Move this option next to the --make option.
Improve the wording of some options' usage messages.
doc/user_guide.texi:
Make the same changes in wording here as well.
compiler/add_pragma.m:
compiler/add_type.m:
compiler/exception_analysis.m:
compiler/handle_options.m:
compiler/headvar_names.m:
compiler/hlds_module.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_make_hlds.m:
compiler/mode_errors.m:
compiler/op_mode.m:
compiler/options.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.analysis.m:
compiler/tabling_analysis.m:
compiler/term_util.m:
compiler/trailing_analysis.m:
compiler/unused_args.m:
Conform to the changes above, either by finding out whether
the compiler was invoked by mmc --make using the op_mode instead
of the option, or by ignoring that info where not needed.
1880 lines
80 KiB
Mathematica
1880 lines
80 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 1996-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: hlds_module.m.
|
|
% Main authors: fjh, conway.
|
|
%
|
|
% This module defines the main part of the High Level Data Structure or HLDS
|
|
% that deals with issues that concern the module as a whole.
|
|
%
|
|
% The main data structures defined here are the types
|
|
%
|
|
% module_info
|
|
%
|
|
% There is a separate interface section for each of these.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module hlds.hlds_module.
|
|
:- interface.
|
|
|
|
:- import_module analysis.
|
|
:- import_module check_hlds.
|
|
:- import_module check_hlds.proc_requests.
|
|
:- import_module hlds.const_struct.
|
|
:- import_module hlds.hlds_class.
|
|
:- import_module hlds.hlds_cons.
|
|
:- import_module hlds.hlds_data.
|
|
:- import_module hlds.hlds_dependency_graph.
|
|
:- import_module hlds.hlds_inst_mode.
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module hlds.hlds_promise.
|
|
:- import_module hlds.pred_table.
|
|
:- import_module hlds.special_pred.
|
|
:- import_module hlds.status.
|
|
:- import_module libs.
|
|
:- import_module libs.globals.
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.module_qual.
|
|
:- import_module parse_tree.prog_data.
|
|
:- import_module parse_tree.prog_data_event.
|
|
:- import_module parse_tree.prog_data_foreign.
|
|
:- import_module parse_tree.prog_data_pragma.
|
|
:- import_module parse_tree.prog_data_used_modules.
|
|
:- import_module parse_tree.prog_foreign.
|
|
:- import_module parse_tree.prog_item.
|
|
:- import_module recompilation.
|
|
|
|
:- import_module cord.
|
|
:- import_module list.
|
|
:- import_module map.
|
|
:- import_module maybe.
|
|
:- import_module multi_map.
|
|
:- import_module one_or_more.
|
|
:- import_module pair.
|
|
:- import_module set.
|
|
:- import_module set_tree234.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% The module_info contains many fields of many types. These are the types
|
|
% that are not defined elsewhere.
|
|
%
|
|
|
|
:- type module_info.
|
|
|
|
:- type pragma_exported_proc
|
|
---> pragma_exported_proc(
|
|
foreign_language, % The language we are exporting to.
|
|
pred_id,
|
|
proc_id,
|
|
string, % The exported name of the procedure.
|
|
% i.e. the function name in C, method
|
|
% name in Java etc.
|
|
prog_context
|
|
).
|
|
|
|
% This structure contains the information we need to generate
|
|
% a type_ctor_info structure for a type defined in this module.
|
|
|
|
:- type type_ctor_gen_info
|
|
---> type_ctor_gen_info(
|
|
type_ctor,
|
|
module_name, % module name
|
|
string, % type name
|
|
int, % type arity
|
|
type_status, % status of the type
|
|
hlds_type_defn, % defn of type
|
|
pred_proc_id, % unify procedure
|
|
pred_proc_id % compare procedure
|
|
% maybe(pred_proc_id) % prettyprinter, if relevant
|
|
).
|
|
|
|
% Map from proc to a list of unused argument numbers.
|
|
%
|
|
:- type unused_arg_info == map(pred_proc_id, list(int)).
|
|
|
|
% For every procedure that requires its own tabling structure,
|
|
% this field records the information needed to define that structure.
|
|
:- type table_struct_map == map(pred_proc_id, table_struct_info).
|
|
|
|
:- type table_struct_info
|
|
---> table_struct_info(
|
|
table_struct_proc :: proc_table_struct_info,
|
|
table_struct_attrs :: table_attributes
|
|
).
|
|
|
|
% List of procedures for which there are user-requested type
|
|
% specializations, and a list of predicates which should be processed
|
|
% by higher_order.m to ensure the production of those versions.
|
|
:- type type_spec_info
|
|
---> type_spec_info(
|
|
% Procedures for which there are user-requested type
|
|
% specializations.
|
|
user_req_procs :: set(pred_proc_id),
|
|
|
|
% Set of predicates which need to be processed by
|
|
% higher_order.m to produce those specialized versions.
|
|
must_process_preds :: set(pred_id),
|
|
|
|
% Map from predicates for which the user requested a type
|
|
% specialization to the list of predicates which must be
|
|
% processed by higher_order.m to force the production of those
|
|
% versions. This is used by dead_proc_elim.m to avoid creating
|
|
% versions unnecessarily for versions in imported modules.
|
|
user_to_process_map :: multi_map(pred_id, pred_id),
|
|
|
|
% Type spec pragmas to be placed in the `.opt' file if a
|
|
% predicate becomes exported.
|
|
pragma_map :: multi_map(pred_id,
|
|
pragma_info_type_spec)
|
|
).
|
|
|
|
% Once filled in by simplify_proc.m (for all non-lambda procedures)
|
|
% and by lambda.m (for procedures created to implement lambda expressions),
|
|
% this map should have an entry for every procedure that is of interest to
|
|
% direct_arg_in_out.m. A procedure may be of interest to that module
|
|
% because it has one or more arguments that it needs to clone,
|
|
% or because it has one or more arguments whose modes do not specify
|
|
% whether they need to be cloned, and for which therefore it should
|
|
% generate a "sorry, not implemented" message. In both cases, the
|
|
% one_or_more(int) specify the argument positions involved; in the latter
|
|
% case, we also record the list of arguments for which we *could* tell
|
|
% they need to be cloned.
|
|
%
|
|
:- type direct_arg_proc_map == map(pred_proc_id, direct_arg_proc).
|
|
:- type direct_arg_proc
|
|
---> direct_arg_clone_proc(
|
|
clone_daio_args :: one_or_more(int)
|
|
)
|
|
; direct_arg_problem_proc(
|
|
problem_args :: one_or_more(int),
|
|
no_problem_args :: list(int)
|
|
).
|
|
|
|
% Maps the full names of procedures (in the sense of complexity_proc_name
|
|
% in complexity.m) to the number of their slot in MR_complexity_proc_table.
|
|
:- type complexity_proc_map == map(string, int).
|
|
|
|
:- type complexity_proc_info
|
|
---> complexity_proc_info(
|
|
% The index of the procedure in the runtime system's
|
|
% MR_complexity_procs array.
|
|
complexity_proc_num :: int,
|
|
|
|
% The full name of the procedure, in the form
|
|
% fqn/arity-modenum, where fqn is the predicate or function's
|
|
% fully qualified name.
|
|
complexity_proc_name :: string,
|
|
|
|
complexity_proc_args :: list(complexity_arg_info)
|
|
).
|
|
|
|
:- type complexity_arg_info
|
|
---> complexity_arg_info(
|
|
complexity_arg_name :: maybe(string),
|
|
complexity_arg_kind :: complexity_arg_kind
|
|
).
|
|
|
|
:- type complexity_arg_kind
|
|
---> complexity_input_variable_size
|
|
; complexity_input_fixed_size
|
|
; complexity_output.
|
|
|
|
:- type exported_enum_info
|
|
---> exported_enum_info(
|
|
% The type whose constants we are exporting to a foreign
|
|
% language.
|
|
eei_type_ctor :: type_ctor,
|
|
|
|
% The constants we are exporting.
|
|
eei_constants :: list(constructor_repn),
|
|
|
|
% The language we are exporting to.
|
|
eei_language :: foreign_language,
|
|
|
|
% This maps the names of the constructors in the Mercury type
|
|
% to their names in the foreign language.
|
|
eei_name_map :: map(string, string),
|
|
|
|
% The context of the foreign_export_enum pragma
|
|
% that asked for all this.
|
|
eei_context :: prog_context
|
|
).
|
|
|
|
:- type proc_analysis_kind
|
|
---> pak_exception
|
|
; pak_trailing
|
|
; pak_mm_tabling
|
|
; pak_termination
|
|
; pak_termination2
|
|
; pak_structure_sharing
|
|
; pak_structure_reuse.
|
|
|
|
% Types for order-independent state update (oisu).
|
|
%
|
|
:- type oisu_map == map(type_ctor, oisu_preds).
|
|
:- type oisu_preds
|
|
---> oisu_preds(
|
|
op_creators :: list(pred_id),
|
|
op_mutators :: list(pred_id),
|
|
op_destructors :: list(pred_id)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% The initialization predicate for the module_info data structure,
|
|
% and its raw getter and setter predicates.
|
|
%
|
|
|
|
% Create an empty module_info for the module named in the given
|
|
% compilation unit.
|
|
%
|
|
:- pred module_info_init(globals::in, module_name::in, prog_context::in,
|
|
string::in, include_module_map::in, used_modules::in, set(module_name)::in,
|
|
partial_qualifier_info::in, maybe(recompilation_info)::in,
|
|
type_repn_decision_data::in, module_info::out) is det.
|
|
|
|
% Once the module_info has been built, we call module_info_optimize
|
|
% to attempt to optimize the data structures for lots of accesses
|
|
% and relatively few insertion/deletions. This was useful when
|
|
% we stored maps using not-necessarily-balanced binary trees;
|
|
% this was when we balanced them. Now that we store maps in 234-trees,
|
|
% it is a no-op. However, we keep this predicate around, since we may
|
|
% yet switch to newer data structures that could also benefit from
|
|
% knowing when their access patterns change from mostly-write to
|
|
% mostly read. For example, we could switch some tables from
|
|
% 234-trees to arrays.
|
|
%
|
|
:- pred module_info_optimize(module_info::in, module_info::out) is det.
|
|
|
|
:- type avail_module_map == map(module_name, avail_module_entry).
|
|
:- type avail_module_entry
|
|
---> avail_module_entry(
|
|
% ms_interface iff any avail_module has ms_interface.
|
|
module_section,
|
|
|
|
% import_decl iff any avail_module has import_decl.
|
|
% XXX CLEANUP This is wrong. A module may have
|
|
% a ":- use_module" declaration in the interface and
|
|
% an ":- import_module" declaration in the implementation,
|
|
% and this design cannot express that.
|
|
import_or_use,
|
|
|
|
% The locations of the *explicit* import_module and
|
|
% use_import declarations, in the *source* of the module.
|
|
% The implicit ones aren't in the list, and neither
|
|
% are the imports and uses read in from interface
|
|
% and optimization files, so it is possible for the list
|
|
% to be empty.
|
|
list(avail_module)
|
|
).
|
|
|
|
:- type avail_module
|
|
---> avail_module(
|
|
module_section,
|
|
import_or_use,
|
|
prog_context
|
|
).
|
|
|
|
% The getter predicates. Please keep the order of declarations here
|
|
% and the order of the clauses below in sync with the order of the
|
|
% fields in the module_info and module_sub_info types.
|
|
|
|
:- pred module_info_get_globals(module_info::in, globals::out) is det.
|
|
:- pred module_info_get_predicate_table(module_info::in,
|
|
predicate_table::out) is det.
|
|
:- pred module_info_get_type_table(module_info::in, type_table::out) is det.
|
|
:- pred module_info_get_no_tag_types(module_info::in,
|
|
no_tag_type_table::out) is det.
|
|
:- pred module_info_get_inst_table(module_info::in, inst_table::out) is det.
|
|
:- pred module_info_get_mode_table(module_info::in, mode_table::out) is det.
|
|
:- pred module_info_get_cons_table(module_info::in, cons_table::out) is det.
|
|
:- pred module_info_get_ctor_field_table(module_info::in,
|
|
ctor_field_table::out) is det.
|
|
|
|
:- pred module_info_get_special_pred_maps(module_info::in,
|
|
special_pred_maps::out) is det.
|
|
:- pred module_info_get_class_table(module_info::in, class_table::out) is det.
|
|
:- pred module_info_get_instance_table(module_info::in,
|
|
instance_table::out) is det.
|
|
:- pred module_info_get_type_spec_info(module_info::in,
|
|
type_spec_info::out) is det.
|
|
:- pred module_info_get_const_struct_db(module_info::in,
|
|
const_struct_db::out) is det.
|
|
:- pred module_info_get_c_j_cs_fims(module_info::in,
|
|
c_j_cs_fims::out) is det.
|
|
:- pred module_info_get_pragma_exported_procs(module_info::in,
|
|
cord(pragma_exported_proc)::out) is det.
|
|
|
|
:- pred module_info_get_name(module_info::in, module_name::out) is det.
|
|
:- pred module_info_get_name_context(module_info::in,
|
|
prog_context::out) is det.
|
|
:- pred module_info_get_dump_hlds_base_file_name(module_info::in,
|
|
string::out) is det.
|
|
:- pred module_info_get_include_module_map(module_info::in,
|
|
include_module_map::out) is det.
|
|
:- pred module_info_get_partial_qualifier_info(module_info::in,
|
|
partial_qualifier_info::out) is det.
|
|
:- pred module_info_get_maybe_recompilation_info(module_info::in,
|
|
maybe(recompilation_info)::out) is det.
|
|
:- pred module_info_get_proc_requests(module_info::in,
|
|
proc_requests::out) is det.
|
|
:- pred module_info_get_assertion_table(module_info::in,
|
|
assertion_table::out) is det.
|
|
:- pred module_info_get_exclusive_table(module_info::in,
|
|
exclusive_table::out) is det.
|
|
:- pred module_info_get_has_parallel_conj(module_info::in,
|
|
has_parallel_conj::out) is det.
|
|
:- pred module_info_get_has_user_event(module_info::in,
|
|
has_user_event::out) is det.
|
|
:- pred module_info_get_direct_arg_proc_map(module_info::in,
|
|
direct_arg_proc_map::out) is det.
|
|
:- pred module_info_get_foreign_decl_codes_user(module_info::in,
|
|
cord(foreign_decl_code)::out) is det.
|
|
:- pred module_info_get_foreign_decl_codes_aux(module_info::in,
|
|
cord(foreign_decl_code)::out) is det.
|
|
:- pred module_info_get_foreign_body_codes(module_info::in,
|
|
cord(foreign_body_code)::out) is det.
|
|
:- pred module_info_get_fact_table_file_names(module_info::in,
|
|
list(string)::out) is det.
|
|
:- pred module_info_get_int_bad_clauses(module_info::in,
|
|
set(pred_pf_name_arity)::out) is det.
|
|
:- pred module_info_get_maybe_dependency_info(module_info::in,
|
|
maybe(hlds_dependency_info)::out) is det.
|
|
:- pred module_info_get_type_ctor_gen_infos(module_info::in,
|
|
list(type_ctor_gen_info)::out) is det.
|
|
:- pred module_info_get_must_be_stratified_preds(module_info::in,
|
|
set(pred_id)::out) is det.
|
|
:- pred module_info_get_unused_arg_info(module_info::in,
|
|
unused_arg_info::out) is det.
|
|
:- pred module_info_get_table_struct_map(module_info::in,
|
|
table_struct_map::out) is det.
|
|
:- pred module_info_get_avail_module_map(module_info::in,
|
|
avail_module_map::out) is det.
|
|
:- pred module_info_get_used_modules(module_info::in,
|
|
used_modules::out) is det.
|
|
:- pred module_info_get_ancestor_avail_modules(module_info::in,
|
|
set(module_name)::out) is det.
|
|
:- pred module_info_get_maybe_complexity_proc_map(module_info::in,
|
|
maybe(pair(int, complexity_proc_map))::out) is det.
|
|
:- pred module_info_get_complexity_proc_infos(module_info::in,
|
|
list(complexity_proc_info)::out) is det.
|
|
:- pred module_info_get_proc_analysis_kinds(module_info::in,
|
|
set(proc_analysis_kind)::out) is det.
|
|
:- pred module_info_get_analysis_info(module_info::in,
|
|
analysis_info::out) is det.
|
|
:- pred module_info_get_user_init_pred_target_names(module_info::in,
|
|
pred_target_names::out) is det.
|
|
:- pred module_info_get_user_final_pred_target_names(module_info::in,
|
|
pred_target_names::out) is det.
|
|
:- pred module_info_get_structure_reuse_preds(module_info::in,
|
|
set(pred_id)::out) is det.
|
|
:- pred module_info_get_format_call_pragma_preds(module_info::in,
|
|
set(pred_id)::out) is det.
|
|
:- pred module_info_get_exported_enums(module_info::in,
|
|
list(exported_enum_info)::out) is det.
|
|
:- pred module_info_get_event_set(module_info::in, event_set::out) is det.
|
|
:- pred module_info_get_oisu_map(module_info::in, oisu_map::out) is det.
|
|
:- pred module_info_get_oisu_procs(module_info::in,
|
|
set(pred_proc_id)::out) is det.
|
|
:- pred module_info_get_ts_rev_string_table(module_info::in, int::out,
|
|
list(string)::out) is det.
|
|
:- pred module_info_get_type_repn_dec(module_info::in,
|
|
type_repn_decision_data::out) is det.
|
|
|
|
% The setter predicates. Please keep the order of declarations here
|
|
% and the order of the clauses below in sync with the order of the
|
|
% fields in the module_info and module_sub_info types.
|
|
|
|
:- pred module_info_set_globals(globals::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_predicate_table(predicate_table::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_type_table(type_table::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_no_tag_types(no_tag_type_table::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_inst_table(inst_table::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_mode_table(mode_table::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_cons_table(cons_table::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_ctor_field_table(ctor_field_table::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
:- pred module_info_set_special_pred_maps(special_pred_maps::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_class_table(class_table::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_instance_table(instance_table::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_type_spec_info(type_spec_info::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_const_struct_db(const_struct_db::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_c_j_cs_fims(c_j_cs_fims::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_pragma_exported_procs(cord(pragma_exported_proc)::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
:- pred module_info_set_maybe_recompilation_info(maybe(recompilation_info)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_proc_requests(proc_requests::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_assertion_table(assertion_table::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_exclusive_table(exclusive_table::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_has_parallel_conj(
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_has_user_event(
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_direct_arg_proc_map(direct_arg_proc_map::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_foreign_decl_codes_user(cord(foreign_decl_code)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_foreign_decl_codes_aux(cord(foreign_decl_code)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_foreign_body_codes(cord(foreign_body_code)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_int_bad_clauses(set(pred_pf_name_arity)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_type_ctor_gen_infos(list(type_ctor_gen_info)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_must_be_stratified_preds(set(pred_id)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_unused_arg_info(unused_arg_info::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_table_struct_map(table_struct_map::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_used_modules(used_modules::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_ancestor_avail_modules(set(module_name)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_maybe_complexity_proc_map(
|
|
maybe(pair(int, complexity_proc_map))::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_complexity_proc_infos(list(complexity_proc_info)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_proc_analysis_kinds(set(proc_analysis_kind)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_analysis_info(analysis_info::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_user_init_pred_target_names(pred_target_names::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_user_final_pred_target_names(pred_target_names::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_structure_reuse_preds(set(pred_id)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_format_call_pragma_preds(set(pred_id)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_exported_enums(list(exported_enum_info)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_event_set(event_set::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_oisu_map(oisu_map::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_oisu_procs(set(pred_proc_id)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_ts_rev_string_table(int::in, list(string)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_type_repn_dec(type_repn_decision_data::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Utility predicates that are a bit more complicated than
|
|
% a simple getter or setter predicates.
|
|
%
|
|
|
|
:- pred module_info_get_pred_id_table(module_info::in,
|
|
pred_id_table::out) is det.
|
|
:- pred module_info_set_pred_id_table(pred_id_table::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
% Given a pred_id, return the pred_info of the specified pred.
|
|
%
|
|
:- pred module_info_pred_info(module_info::in, pred_id::in, pred_info::out)
|
|
is det.
|
|
|
|
% Given a pred_proc_id, return the proc_info of the specified procedure.
|
|
%
|
|
:- pred module_info_proc_info(module_info::in, pred_proc_id::in,
|
|
proc_info::out) is det.
|
|
:- pred module_info_proc_info(module_info::in, pred_id::in, proc_id::in,
|
|
proc_info::out) is det.
|
|
|
|
% Given a pred_id and a proc_id, get the pred_info of that predicate
|
|
% and the proc_info for that mode of that predicate.
|
|
%
|
|
:- pred module_info_pred_proc_info(module_info::in, pred_id::in, proc_id::in,
|
|
pred_info::out, proc_info::out) is det.
|
|
:- pred module_info_pred_proc_info(module_info::in, pred_proc_id::in,
|
|
pred_info::out, proc_info::out) is det.
|
|
|
|
% Return a set of the pred_ids of all the valid predicates.
|
|
% Predicates whose definition contains a type error, etc.
|
|
% get removed from this set, so that later passes can rely
|
|
% on the predicates in this set being type-correct, etc.
|
|
%
|
|
:- pred module_info_get_valid_pred_id_set(module_info::in,
|
|
set_tree234(pred_id)::out) is det.
|
|
|
|
% Return the same pred_ids as module_info_get_valid_pred_id_set,
|
|
% but in the form of a sorted list.
|
|
%
|
|
:- pred module_info_get_valid_pred_ids(module_info::in,
|
|
list(pred_id)::out) is det.
|
|
|
|
% Remove one or more predicates from the set of valid pred_ids,
|
|
% to prevent further processing of those predicates after errors
|
|
% have been encountered in them.
|
|
%
|
|
:- pred module_info_make_pred_id_invalid(pred_id::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_make_pred_ids_invalid(list(pred_id)::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
% Completely remove a predicate from a module.
|
|
%
|
|
:- pred module_info_remove_predicate(pred_id::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
:- pred module_info_set_pred_info(pred_id::in, pred_info::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
:- pred module_info_set_pred_proc_info(pred_proc_id::in,
|
|
pred_info::in, proc_info::in, module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_pred_proc_info(pred_id::in, proc_id::in,
|
|
pred_info::in, proc_info::in, module_info::in, module_info::out) is det.
|
|
|
|
%---------------------%
|
|
|
|
:- pred predicate_id(module_info::in, pred_id::in, module_name::out,
|
|
string::out, arity::out) is det.
|
|
|
|
:- func predicate_module(module_info, pred_id) = module_name.
|
|
:- func predicate_name(module_info, pred_id) = string.
|
|
:- func predicate_arity(module_info, pred_id) = arity.
|
|
|
|
%---------------------%
|
|
|
|
:- pred module_add_foreign_decl_code_user(foreign_decl_code::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_add_foreign_decl_code_aux(foreign_decl_code::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
:- pred module_add_foreign_body_code(foreign_body_code::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
:- pred module_add_item_fim(item_fim::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
:- pred module_add_fact_table_file(string::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
%---------------------%
|
|
|
|
% Please see module_info_ensure_dependency_info for the constraints
|
|
% on the returned dependency_info.
|
|
%
|
|
:- pred module_info_dependency_info(module_info::in,
|
|
hlds_dependency_info::out) is det.
|
|
|
|
:- pred module_info_set_dependency_info(hlds_dependency_info::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
:- pred module_info_clobber_dependency_info(
|
|
module_info::in, module_info::out) is det.
|
|
|
|
%---------------------%
|
|
|
|
% The module_info stores a counter which is used to distinguish
|
|
% lambda predicates which appear on the same line in the same file.
|
|
% This predicate returns the next number for the given context
|
|
% and increments the counter for that context.
|
|
%
|
|
:- pred module_info_next_lambda_count(prog_context::in, int::out,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
:- pred module_info_next_atomic_count(prog_context::in, int::out,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
:- pred module_info_next_loop_inv_count(prog_context::in, int::out,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
%---------------------%
|
|
|
|
:- pred module_add_avail_module_name(module_name::in,
|
|
module_section::in, import_or_use::in, maybe(prog_context)::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
:- pred module_add_indirectly_imported_module_name(module_name::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
% Return the set of the visible modules. These are
|
|
%
|
|
% (1) the current module,
|
|
% (2) any imported modules,
|
|
% (3) any ancestor modules, and
|
|
% (4) any modules imported by ancestor modules.
|
|
%
|
|
% It excludes transitively imported modules (those for which we read
|
|
% `.int2' files).
|
|
%
|
|
:- pred module_info_get_visible_modules(module_info::in,
|
|
set(module_name)::out) is det.
|
|
|
|
% This returns all the modules that this module's code depends on,
|
|
% i.e. all modules that have been used or imported by this module,
|
|
% directly or indirectly, including parent modules.
|
|
%
|
|
:- pred module_info_get_all_deps(module_info::in,
|
|
set(module_name)::out) is det.
|
|
|
|
:- pred module_info_add_module_to_public_used_modules(module_name::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
%---------------------%
|
|
|
|
:- pred module_info_user_init_pred_target_names(module_info::in,
|
|
list(string)::out) is det.
|
|
:- pred module_info_user_final_pred_target_names(module_info::in,
|
|
list(string)::out) is det.
|
|
|
|
:- pred module_info_user_init_pred_procs(module_info::in,
|
|
list(pred_proc_id)::out) is det.
|
|
:- pred module_info_user_final_pred_procs(module_info::in,
|
|
list(pred_proc_id)::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% The information needed by the pass that decides type representations.
|
|
% The first three fields contain information that it uses make its
|
|
% decisions; the fourth contains information that says what it should *do*
|
|
% with the results of its decisions.
|
|
%
|
|
:- type type_repn_decision_data
|
|
---> type_repn_decision_data(
|
|
% The contents of type_repn items read in from the interface
|
|
% files of other modules, containing information about the
|
|
% representations of the types defined in those modules.
|
|
trdd_type_repns :: type_ctor_repn_map,
|
|
|
|
% The contents of direct_arg clauses in type definitions
|
|
% read in from the interface files of other modules,
|
|
% containing information about the direct_arg part of the
|
|
% representations of those types.
|
|
%
|
|
% XXX TYPE_REPN In the future, this information should *also*
|
|
% be stored in type_repn items.
|
|
trdd_direct_arg_map :: direct_arg_map,
|
|
|
|
% The contents of foreign_enum pragmas read in either
|
|
% from interface files of other modules, or the source file
|
|
% of the module being compiled, giving the foreign language
|
|
% definition of a type.
|
|
trdd_foreign_enums :: list({item_mercury_status,
|
|
item_foreign_enum_info}),
|
|
|
|
% The contents of foreign_export_enum pragmas read in
|
|
% from the source file of the module being compiled,
|
|
% asking the compiler to generate definitions
|
|
% of the named types in the named foreign languages.
|
|
trdd_foreign_exports :: list(item_foreign_export_enum_info)
|
|
).
|
|
|
|
:- type direct_arg_map == map(type_ctor, list(sym_name_arity)).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module libs.op_mode.
|
|
:- import_module mdbcomp.builtin_modules.
|
|
:- import_module transform_hlds.
|
|
:- import_module transform_hlds.mmc_analysis.
|
|
|
|
:- import_module assoc_list.
|
|
:- import_module bool.
|
|
:- import_module counter.
|
|
:- import_module require.
|
|
:- import_module string.
|
|
|
|
% The module_info, module_sub_info and module_rare_info types
|
|
% constitute a single logical data structure split into three parts
|
|
% for efficiency purposes.
|
|
%
|
|
% The module_info type contains the most frequently accessed and updated
|
|
% pieces of information about the module.
|
|
%
|
|
% We keep the other pieces of information we need about the module
|
|
% in the module_sub_info or the module_rare_info types. Those that are
|
|
% reasonably frequently updated are in the module_sub_info; those that
|
|
% are rarely or never updated are in the module_rare_info.
|
|
%
|
|
% This arrangement minimizes the amount of memory that needs to be
|
|
% allocated, and filled in, when a field is updated.
|
|
%
|
|
% Note that a field may be rarely read or written for two main reasons.
|
|
%
|
|
% - One reason is that the compiler simply does not need to read or write
|
|
% the field very often. This may be e.g. because it is used only
|
|
% when processing a language construct that is rare, or because
|
|
% its uses are concentrated in a few pieces of code that read it
|
|
% only when they start and write it only when they finish.
|
|
%
|
|
% - Another reason is that it is used only when a compiler option
|
|
% is given, and it is rarely given.
|
|
|
|
% Please keep the order of the fields in module_info, module_sub_info
|
|
% and module_rare_info in sync with the order of the both the
|
|
% declarations and definitions of both the getter and setter predicates.
|
|
|
|
:- type module_info
|
|
---> module_info(
|
|
% The Boehm collector allocates blocks whose sizes are
|
|
% multiples of 2. Please keep the number of fields here
|
|
% to a multiple of 2 as well.
|
|
|
|
% Note that the no_tag_type_table contains information
|
|
% about notag types that is also available in the type_table,
|
|
% but in a format that allows faster access.
|
|
|
|
/* 01 */ mi_sub_info :: module_sub_info,
|
|
/* 02 */ mi_rare_info :: module_rare_info,
|
|
/* 03 */ mi_globals :: globals,
|
|
/* 04 */ mi_predicate_table :: predicate_table,
|
|
/* 05 */ mi_type_table :: type_table,
|
|
/* 06 */ mi_no_tag_type_table :: no_tag_type_table,
|
|
/* 07 */ mi_inst_table :: inst_table,
|
|
/* 08 */ mi_mode_table :: mode_table,
|
|
/* 09 */ mi_cons_table :: cons_table,
|
|
/* 10 */ mi_ctor_field_table :: ctor_field_table
|
|
).
|
|
|
|
:- type module_sub_info
|
|
---> module_sub_info(
|
|
msi_special_pred_maps :: special_pred_maps,
|
|
msi_class_table :: class_table,
|
|
msi_instance_table :: instance_table,
|
|
|
|
% Data used for user-guided type specialization.
|
|
msi_type_spec_info :: type_spec_info,
|
|
|
|
% The database of constant structures the code generator
|
|
% will generate independently, outside all the procedures
|
|
% of the program.
|
|
msi_const_struct_db :: const_struct_db,
|
|
|
|
msi_c_j_cs_fims :: c_j_cs_fims,
|
|
|
|
% List of the procs for which there is a
|
|
% pragma foreign_export(...) declaration.
|
|
msi_pragma_exported_procs :: cord(pragma_exported_proc)
|
|
).
|
|
|
|
:- type module_rare_info
|
|
---> module_rare_info(
|
|
mri_module_name :: module_name,
|
|
mri_module_name_context :: prog_context,
|
|
mri_dump_base_file_name :: string,
|
|
|
|
mri_include_module_map :: include_module_map,
|
|
|
|
mri_partial_qualifier_info :: partial_qualifier_info,
|
|
mri_maybe_recompilation_info :: maybe(recompilation_info),
|
|
|
|
mri_proc_requests :: proc_requests,
|
|
mri_assertion_table :: assertion_table,
|
|
mri_exclusive_table :: exclusive_table,
|
|
|
|
mri_direct_arg_proc_map :: direct_arg_proc_map,
|
|
|
|
mri_has_parallel_conj :: has_parallel_conj,
|
|
mri_has_user_event :: has_user_event,
|
|
|
|
% We classify foreign code fragments bodily included in the
|
|
% generated target language file into three categories,
|
|
% based on two criteria.
|
|
%
|
|
% The first criterion is declarations (decl_codes) vs
|
|
% non-declarations (body codes). We separate these because
|
|
% we have to put declarations before code that may use those
|
|
% declarations.
|
|
%
|
|
% We would prefer the second criterion to be declarations
|
|
% that define types vs declarations that define other entities
|
|
% that may refer to those types, such as global variables
|
|
% or function, again so that we can emit the former before
|
|
% the latter, Unfortunately, foreign_decl pragmas do not
|
|
% specify what they define. Instead, our second criterion is
|
|
% user-provided declarations vs aux declarations added
|
|
% by the Mercury compiler itself to implement either
|
|
% (a) mutables, or (b) fact tables. Neither of the latter
|
|
% define types, so putting these after user-provided
|
|
% declarations will work, as long as in the user-provided
|
|
% declarations, definitions of types precede definitions
|
|
% of other entities that refer to those types. Ensuring that
|
|
% is the programmer's responsibility.
|
|
mri_foreign_decl_codes_user :: cord(foreign_decl_code),
|
|
mri_foreign_decl_codes_aux :: cord(foreign_decl_code),
|
|
mri_foreign_body_codes :: cord(foreign_body_code),
|
|
|
|
% The names of the files containing fact tables implementing
|
|
% predicates defined in this module.
|
|
mri_fact_table_file_names :: list(string),
|
|
|
|
% The set of predicates and functions for which there was
|
|
% an attempt to define them in the interface (by clause,
|
|
% foreign_proc, or external_proc pragma), which means that
|
|
% if we find no definition for them in the implementation
|
|
% section either, we should NOT generate an error message
|
|
% complaining about the definition being missing. Such a
|
|
% message would be misleading, since the definition is not
|
|
% missing, it was just misplaced, and we have already
|
|
% generated an error message about that misplaced attempt
|
|
% at definition.
|
|
mri_int_bad_clauses :: set(pred_pf_name_arity),
|
|
|
|
% Please see module_info_ensure_dependency_info for the
|
|
% meaning of this dependency_info, and the constraints on it.
|
|
mri_maybe_dependency_info :: maybe(hlds_dependency_info),
|
|
|
|
mri_type_ctor_gen_infos :: list(type_ctor_gen_info),
|
|
mri_must_be_stratified_preds :: set(pred_id),
|
|
|
|
% Unused argument info about predicates in the current module
|
|
% which has been exported in .opt files.
|
|
mri_unused_arg_info :: unused_arg_info,
|
|
|
|
% For every procedure that requires its own tabling structure,
|
|
% this field records the information needed to define that
|
|
% structure.
|
|
mri_table_struct_map :: table_struct_map,
|
|
|
|
% How many lambda expressions there are at different contexts
|
|
% in the module. This is used to uniquely identify lambda
|
|
% expressions that appear on the same line of the same file.
|
|
mri_lambdas_per_context :: map(prog_context, counter),
|
|
|
|
% How many STM atomic expressions there are at different
|
|
% contexts in the module. This is used to uniquely identify
|
|
% STM atomic expressions that appear on the same line of
|
|
% the same file.
|
|
mri_atomics_per_context :: map(prog_context, counter),
|
|
|
|
% How many loop invariant optimizations we have done at
|
|
% different contexts in the module. This is used to provide
|
|
% a uniquely identify the predicates that we create
|
|
% using the loop invariant optimization, in the rare case
|
|
% that one line contains the definition of more than one
|
|
% predicate.
|
|
mri_loop_invs_per_context :: map(prog_context, counter),
|
|
|
|
% The add_item_avails predicate in make_hlds_passes.m fills
|
|
% this field with information about all the import- and
|
|
% use_module declarations both in the module being compiled,
|
|
% and in the .int0 interface files of its ancestors.
|
|
%
|
|
% Each entry in the avail_module_map will specify
|
|
%
|
|
% - whether the module is imported or used in the interface
|
|
% of either the module or its ancestors, and
|
|
%
|
|
% - whether the module is imported (as opposed to used)
|
|
% in either the module or its ancestors.
|
|
%
|
|
% Each entry will also contain a list of avail_modules
|
|
% *for import/use_module declarations in this module only*;
|
|
% there won't be any entries for imports/uses in ancestors.
|
|
%
|
|
% This field is used by:
|
|
%
|
|
% - intermod.m to (over-)estimate the set of use_module decls
|
|
% needed by the code put into a .opt file;
|
|
%
|
|
% - try_expand.m to see whether exception is imported
|
|
% and hence whether it has anything to do at all
|
|
% (since we import exception.m implicitly if some code
|
|
% contains a try goal);
|
|
%
|
|
% - by unused_imports.m to decide what import_module and/or
|
|
% use_module declarations to warn about;
|
|
%
|
|
% - by xml_documentation to prettyprint a module as XML;
|
|
%
|
|
% and possibly more.
|
|
mri_avail_module_map :: avail_module_map,
|
|
|
|
% The names of all the indirectly imported modules
|
|
% (used by the MLDS back-end).
|
|
%
|
|
% XXX CLEANUP The above is misleading.
|
|
% When added to the info in the previous field, the value
|
|
% in this field is used to for two purposes, both of which
|
|
% need the full set of modules imported and/or used both
|
|
% directly and indirectly, and both explicitly or implicitly.
|
|
% The purposes are:
|
|
%
|
|
% - #including those the .mh and .mih files of those modules;
|
|
% - reading and writing the .analysis files of those modules.
|
|
mri_indirectly_imported_module_names
|
|
:: set(module_name),
|
|
|
|
% The modules which have already been calculated as being used.
|
|
% This slot is initialized to the set of modules that have
|
|
% been seen to be used during the expansion of equivalence
|
|
% types and insts.
|
|
mri_used_modules :: used_modules,
|
|
|
|
% The set of modules imported by ancestor modules.
|
|
%
|
|
% We used to add these to mri_used_modules, but that prevented
|
|
% the compiler from generating useful warnings about unused
|
|
% local imports/uses of those modules. We now keep this info
|
|
% on a "may be useful later" basis; it is current unused.
|
|
mri_ancestor_avail_modules :: set(module_name),
|
|
|
|
% Information about the procedures we are performing
|
|
% complexity experiments on.
|
|
mri_maybe_complexity_proc_map :: maybe(pair(int,
|
|
complexity_proc_map)),
|
|
mri_complexity_proc_infos :: list(complexity_proc_info),
|
|
|
|
% Records the set of analyses whose results are now available
|
|
% in the proc_infos. As each analysis puts its results
|
|
% in the proc_infos, it should add its id to this set.
|
|
mri_proc_analysis_kinds :: set(proc_analysis_kind),
|
|
|
|
% Information for the inter-module analysis framework.
|
|
mri_analysis_info :: analysis_info,
|
|
|
|
% Exported target language names for preds appearing in
|
|
% `:- initialise' directives, and implicitly in
|
|
% `:- mutable' directives, in this module.
|
|
mri_user_init_pred_target_names :: pred_target_names,
|
|
|
|
% Exported target names for preds appearing in
|
|
% `:- finalise' directives in this module.
|
|
mri_user_final_pred_target_names :: pred_target_names,
|
|
|
|
% Predicates which were created as reuse versions of other
|
|
% procedures. Its only use is to avoid writing out pragmas
|
|
% for structure reuse predicates to `.trans_opt' files.
|
|
mri_structure_reuse_preds :: set(pred_id),
|
|
|
|
% The set of predicates in the HLDS that have
|
|
% a format_call pragma.
|
|
%
|
|
% This set is filled in by add_pragma.m when the HLDS
|
|
% is first constructed. Usually, this set will be empty,
|
|
% but if it is not, the check_pragma_format_call_preds pass
|
|
% will check all these pragmas for errors.
|
|
%
|
|
% This pass must be after type and mode analysis (since it
|
|
% needs to know the types and modes of procedure arguments),
|
|
% and must be before the simplification pass at the end of
|
|
% semantic analysis (since that is when format_call.m's code
|
|
% uses this info, relying on it having being checked).
|
|
mri_format_call_pragma_preds :: set(pred_id),
|
|
|
|
% Enumeration types that have been exported to a foreign
|
|
% language.
|
|
mri_exported_enums :: list(exported_enum_info),
|
|
|
|
mri_event_set :: event_set,
|
|
|
|
% The set of visible declarations about order-independent
|
|
% state update.
|
|
mri_oisu_map :: oisu_map,
|
|
|
|
% The set of procedures defined in this module that
|
|
% have OISU arguments.
|
|
mri_oisu_procs :: set(pred_proc_id),
|
|
|
|
% A table of strings used by some threadscope events.
|
|
% Currently threadscope events are introduced for each future
|
|
% in dep_par_conj.m which is why we need to record the table
|
|
% within the HLDS. The LLDS also uses threadscope string
|
|
% tables, see global_data.m, the LLDS introduces strings during
|
|
% the HLDS->LLDS transformation of parallel conjunctions.
|
|
mri_ts_string_table_size :: int,
|
|
mri_ts_rev_string_table :: list(string),
|
|
|
|
% Information needed to decide type representations.
|
|
mri_type_repn_dec :: type_repn_decision_data
|
|
).
|
|
|
|
% Access stats for the module_info structure on 30 december 2014.
|
|
%
|
|
% i read same diff same%
|
|
% 0 188233540 17 38369323 0.00% predicate_table
|
|
% 1 7933 0 480 0.00% proc_requests
|
|
% 2 261171 0 103230 0.00% special_pred_maps
|
|
% 3 4576898 0 0 partial_qualifier_info
|
|
% 4 21758620 2908 1589788 0.18% type_table
|
|
% 5 22754063 0 2360725 0.00% inst_table
|
|
% 6 145877431 10501 149637 6.56% mode_table
|
|
% 7 16110150 3767 803152 0.47% cons_table
|
|
% 8 7125765 353 65777 0.53% class_table
|
|
% 9 2543131 353 206012 0.17% instance_table
|
|
% 10 7935 0 3798 0.00% assertion_table
|
|
% 11 0 0 0 exclusive_table
|
|
% 12 4552293 620283 180042 77.50% ctor_field_table
|
|
% 13 2256146 2219707 235 99.99% maybe_recompilation_info
|
|
% 14 14893776 0 0 name
|
|
% 15 0 0 0 dump_hlds_base_file_name
|
|
% 16 39144524 0 16950 0.00% globals
|
|
% 17 8481 17 64 20.99% has_parallel_conj
|
|
% 18 253 4 5 44.44% has_user_event
|
|
% 19 0 223574 3371 98.51% contains_foreign_type
|
|
% 20 9180 0 710 0.00% foreign_decl_codes
|
|
% 21 3683 0 856 0.00% foreign_body_codes
|
|
% 22 966008 0 963108 0.00% foreign_import_modules
|
|
% 23 331870 281405 35898 88.69% pragma_exported_procs
|
|
% 24 1 0 0 fact_table_file_names
|
|
% 25 10630 11345 8490 57.20% maybe_dependency_info
|
|
% 26 11342 4885 128 97.45% num_errors
|
|
% 27 35292 2442 3209 43.21% type_ctor_gen_infos
|
|
% 28 3506 0 2 0.00% must_be_stratified_preds
|
|
% 29 1 0 1 0.00% unused_arg_info
|
|
% 30 3972001 0 3445467 0.00% exception_info
|
|
% 31 296 0 0 trailing_info
|
|
% 32 4071 0 75 0.00% table_struct_map
|
|
% 33 296 0 0 mm_tabling_info
|
|
% 34 4019 0 4019 0.00% lambdas_per_context
|
|
% 35 0 0 0 atomics_per_context
|
|
% 36 7053 0 0 imported_module_names
|
|
% 37 3135 0 0 indirectly_imported_mod_specs
|
|
% 38 1 0 0 interface_module_names
|
|
% 39 6568 0 3767 0.00% used_modules
|
|
% 40 1656135 0 126058 0.00% type_spec_info
|
|
% 41 22588003 0 87106 0.00% no_tag_types
|
|
% 42 171993 0 0 complexity_proc_map
|
|
% 43 2821 0 0 complexity_proc_infos
|
|
% 44 763 336 2 99.41% analysis_info
|
|
% 45 316 0 20 0.00% structure_reuse_preds
|
|
% 46 5703 0 55 0.00% exported_enums
|
|
% 47 48 0 3767 0.00% event_set
|
|
% 48 3510 0 6 0.00% oisu_map
|
|
% 49 0 0 2 0.00% oisu_procs
|
|
% 50 2684695 2592456 10222 99.61% const_struct_db
|
|
% 51 2821 0 0 threadscope_string_table
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
module_info_init(Globals, ModuleName, ModuleNameContext, DumpBaseFileName,
|
|
InclMap, UsedModules, ImplicitlyUsedModules,
|
|
QualifierInfo, MaybeRecompInfo, TypeRepnDec, ModuleInfo) :-
|
|
SpecialPredMaps = special_pred_maps(map.init, map.init, map.init),
|
|
map.init(ClassTable),
|
|
map.init(InstanceTable),
|
|
|
|
set.init(TypeSpecPreds),
|
|
set.init(TypeSpecForcePreds),
|
|
map.init(SpecMap),
|
|
map.init(PragmaMap),
|
|
TypeSpecInfo = type_spec_info(TypeSpecPreds, TypeSpecForcePreds,
|
|
SpecMap, PragmaMap),
|
|
|
|
const_struct_db_init(Globals, ConstStructDb),
|
|
ForeignImportModules = init_foreign_import_modules,
|
|
PragmaExportedProcs = cord.init,
|
|
|
|
ModuleSubInfo = module_sub_info(
|
|
SpecialPredMaps,
|
|
ClassTable,
|
|
InstanceTable,
|
|
TypeSpecInfo,
|
|
ConstStructDb,
|
|
ForeignImportModules,
|
|
PragmaExportedProcs),
|
|
|
|
init_requests(ProcRequests),
|
|
assertion_table_init(AssertionTable),
|
|
exclusive_table_init(ExclusiveTable),
|
|
map.init(DirectArgInOutMap),
|
|
HasParallelConj = has_no_parallel_conj,
|
|
HasUserEvent = has_no_user_event,
|
|
ForeignDeclsUser = cord.init,
|
|
ForeignDeclsAux = cord.init,
|
|
ForeignBodies = cord.init,
|
|
FactTableFiles = [],
|
|
set.init(IntBadPreds),
|
|
MaybeDependencyInfo = maybe.no,
|
|
MustBeStratifiedPreds = [],
|
|
set.init(StratPreds),
|
|
map.init(UnusedArgInfo),
|
|
map.init(TablingStructMap),
|
|
map.init(LambdasPerContext),
|
|
map.init(AtomicsPerContext),
|
|
map.init(LoopInvsPerContext),
|
|
|
|
% XXX ITEM_LIST Given that we start with an aug_compilation_unit,
|
|
% shouldn't the work of finding implicit dependencies have already
|
|
% been done?
|
|
% XXX ITEM_LIST Should a tabled predicate declared in a .int* or .*opt
|
|
% file generate an implicit dependency?
|
|
|
|
% XXX ITEM_LIST We should record ImportDeps and UseDeps separately.
|
|
% XXX ITEM_LIST Should we record implicitly and explicitly imported
|
|
% separately, or at least record for each import (and use) whether
|
|
% it was explicit or implicit, and one (or more) context where either
|
|
% the explicit imported was requested, or the implicit import was required.
|
|
|
|
map.init(AvailModuleMap0),
|
|
add_implicit_avail_module(import_decl, mercury_public_builtin_module,
|
|
AvailModuleMap0, AvailModuleMap1),
|
|
set.fold(add_implicit_avail_module(use_decl), ImplicitlyUsedModules,
|
|
AvailModuleMap1, AvailModuleMap),
|
|
|
|
set.init(IndirectlyImportedModules),
|
|
|
|
set.init(AncestorAvailModules),
|
|
MaybeComplexityMap = no,
|
|
ComplexityProcInfos = [],
|
|
set.init(ProcAnalysisKinds),
|
|
|
|
globals.get_op_mode(Globals, OpMode),
|
|
( if
|
|
OpMode = opm_top_args(opma_augment(opmau_make_analysis_registry), _)
|
|
then
|
|
MakeAnalysisReg = yes
|
|
else
|
|
MakeAnalysisReg = no
|
|
),
|
|
AnalysisInfo = init_analysis_info(mmc, ModuleName, MakeAnalysisReg),
|
|
|
|
UserInitPredTargetNames = pred_target_names(map.init),
|
|
UserFinalPredTargetNames = pred_target_names(map.init),
|
|
set.init(StructureReusePredIds),
|
|
set.init(FormatCallPragmaPredIds),
|
|
ExportedEnums = [],
|
|
EventSet = event_set("", map.init),
|
|
map.init(OISUMap),
|
|
set.init(OISUProcs),
|
|
TSStringTableSize = 0,
|
|
TSRevStringTable = [],
|
|
|
|
ModuleRareInfo = module_rare_info(
|
|
ModuleName,
|
|
ModuleNameContext,
|
|
DumpBaseFileName,
|
|
InclMap,
|
|
QualifierInfo,
|
|
MaybeRecompInfo,
|
|
ProcRequests,
|
|
AssertionTable,
|
|
ExclusiveTable,
|
|
DirectArgInOutMap,
|
|
HasParallelConj,
|
|
HasUserEvent,
|
|
ForeignDeclsUser,
|
|
ForeignDeclsAux,
|
|
ForeignBodies,
|
|
FactTableFiles,
|
|
IntBadPreds,
|
|
MaybeDependencyInfo,
|
|
MustBeStratifiedPreds,
|
|
StratPreds,
|
|
UnusedArgInfo,
|
|
TablingStructMap,
|
|
LambdasPerContext,
|
|
AtomicsPerContext,
|
|
LoopInvsPerContext,
|
|
AvailModuleMap,
|
|
IndirectlyImportedModules,
|
|
UsedModules,
|
|
AncestorAvailModules,
|
|
MaybeComplexityMap,
|
|
ComplexityProcInfos,
|
|
ProcAnalysisKinds,
|
|
AnalysisInfo,
|
|
UserInitPredTargetNames,
|
|
UserFinalPredTargetNames,
|
|
StructureReusePredIds,
|
|
FormatCallPragmaPredIds,
|
|
ExportedEnums,
|
|
EventSet,
|
|
OISUMap,
|
|
OISUProcs,
|
|
TSStringTableSize,
|
|
TSRevStringTable,
|
|
TypeRepnDec),
|
|
|
|
predicate_table_init(PredicateTable),
|
|
TypeTable = init_type_table,
|
|
map.init(NoTagTypes),
|
|
inst_table_init(InstTable),
|
|
mode_table_init(ModeTable),
|
|
CtorTable = init_cons_table,
|
|
map.init(FieldNameTable),
|
|
|
|
ModuleInfo = module_info(
|
|
ModuleSubInfo,
|
|
ModuleRareInfo,
|
|
Globals,
|
|
PredicateTable,
|
|
TypeTable,
|
|
NoTagTypes,
|
|
InstTable,
|
|
ModeTable,
|
|
CtorTable,
|
|
FieldNameTable).
|
|
|
|
:- pred add_implicit_avail_module(import_or_use::in, module_name::in,
|
|
avail_module_map::in, avail_module_map::out) is det.
|
|
|
|
add_implicit_avail_module(ImportOrUse, ModuleName, !AvailModuleMap) :-
|
|
Entry = avail_module_entry(ms_implementation, ImportOrUse, []),
|
|
map.det_insert(ModuleName, Entry, !AvailModuleMap).
|
|
|
|
module_info_optimize(!ModuleInfo) :-
|
|
% Currently, all the calls to *_table_optimize are no-ops.
|
|
% We keep them, and this predicate, in case that changes in the future.
|
|
|
|
module_info_get_predicate_table(!.ModuleInfo, Preds0),
|
|
predicate_table_optimize(Preds0, Preds),
|
|
module_info_set_predicate_table(Preds, !ModuleInfo),
|
|
|
|
module_info_get_inst_table(!.ModuleInfo, InstTable0),
|
|
inst_table_get_user_insts(InstTable0, UserInstTable0),
|
|
map.optimize(UserInstTable0, UserInstTable),
|
|
inst_table_set_user_insts(UserInstTable, InstTable0, InstTable),
|
|
module_info_set_inst_table(InstTable, !ModuleInfo),
|
|
|
|
module_info_get_mode_table(!.ModuleInfo, Modes0),
|
|
mode_table_optimize(Modes0, Modes),
|
|
module_info_set_mode_table(Modes, !ModuleInfo),
|
|
|
|
module_info_get_cons_table(!.ModuleInfo, Ctors0),
|
|
cons_table_optimize(Ctors0, Ctors),
|
|
module_info_set_cons_table(Ctors, !ModuleInfo).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Getter and setter predicates on the module_info that are local to this
|
|
% module.
|
|
%
|
|
|
|
:- pred module_info_get_lambdas_per_context(module_info::in,
|
|
map(prog_context, counter)::out) is det.
|
|
:- pred module_info_get_atomics_per_context(module_info::in,
|
|
map(prog_context, counter)::out) is det.
|
|
:- pred module_info_get_loop_invs_per_context(module_info::in,
|
|
map(prog_context, counter)::out) is det.
|
|
:- pred module_info_get_indirectly_imported_module_names(module_info::in,
|
|
set(module_name)::out) is det.
|
|
|
|
:- pred module_info_set_maybe_dependency_info(maybe(hlds_dependency_info)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_lambdas_per_context(map(prog_context, counter)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_atomics_per_context(map(prog_context, counter)::in,
|
|
module_info::in, module_info::out) is det.
|
|
:- pred module_info_set_loop_invs_per_context(map(prog_context, counter)::in,
|
|
module_info::in, module_info::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Getter predicates for the module_info.
|
|
%
|
|
|
|
module_info_get_globals(MI, X) :-
|
|
X = MI ^ mi_globals.
|
|
module_info_get_predicate_table(MI, X) :-
|
|
X = MI ^ mi_predicate_table.
|
|
module_info_get_type_table(MI, X) :-
|
|
X = MI ^ mi_type_table.
|
|
module_info_get_no_tag_types(MI, X) :-
|
|
X = MI ^ mi_no_tag_type_table.
|
|
module_info_get_inst_table(MI, X) :-
|
|
X = MI ^ mi_inst_table.
|
|
module_info_get_mode_table(MI, X) :-
|
|
X = MI ^ mi_mode_table.
|
|
module_info_get_cons_table(MI, X) :-
|
|
X = MI ^ mi_cons_table.
|
|
module_info_get_ctor_field_table(MI, X) :-
|
|
X = MI ^ mi_ctor_field_table.
|
|
|
|
module_info_get_special_pred_maps(MI, X) :-
|
|
X = MI ^ mi_sub_info ^ msi_special_pred_maps.
|
|
module_info_get_class_table(MI, X) :-
|
|
X = MI ^ mi_sub_info ^ msi_class_table.
|
|
module_info_get_instance_table(MI, X) :-
|
|
X = MI ^ mi_sub_info ^ msi_instance_table.
|
|
module_info_get_type_spec_info(MI, X) :-
|
|
X = MI ^ mi_sub_info ^ msi_type_spec_info.
|
|
module_info_get_const_struct_db(MI, X) :-
|
|
X = MI ^ mi_sub_info ^ msi_const_struct_db.
|
|
module_info_get_c_j_cs_fims(MI, X) :-
|
|
X = MI ^ mi_sub_info ^ msi_c_j_cs_fims.
|
|
module_info_get_pragma_exported_procs(MI, X) :-
|
|
X = MI ^ mi_sub_info ^ msi_pragma_exported_procs.
|
|
|
|
module_info_get_name(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_module_name.
|
|
module_info_get_name_context(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_module_name_context.
|
|
module_info_get_dump_hlds_base_file_name(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_dump_base_file_name.
|
|
module_info_get_include_module_map(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_include_module_map.
|
|
module_info_get_partial_qualifier_info(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_partial_qualifier_info.
|
|
module_info_get_maybe_recompilation_info(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_maybe_recompilation_info.
|
|
module_info_get_proc_requests(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_proc_requests.
|
|
module_info_get_assertion_table(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_assertion_table.
|
|
module_info_get_exclusive_table(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_exclusive_table.
|
|
module_info_get_has_parallel_conj(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_has_parallel_conj.
|
|
module_info_get_has_user_event(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_has_user_event.
|
|
module_info_get_direct_arg_proc_map(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_direct_arg_proc_map.
|
|
module_info_get_foreign_decl_codes_user(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_foreign_decl_codes_user.
|
|
module_info_get_foreign_decl_codes_aux(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_foreign_decl_codes_aux.
|
|
module_info_get_foreign_body_codes(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_foreign_body_codes.
|
|
module_info_get_fact_table_file_names(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_fact_table_file_names.
|
|
module_info_get_int_bad_clauses(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_int_bad_clauses.
|
|
module_info_get_maybe_dependency_info(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_maybe_dependency_info.
|
|
module_info_get_type_ctor_gen_infos(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_type_ctor_gen_infos.
|
|
module_info_get_must_be_stratified_preds(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_must_be_stratified_preds.
|
|
module_info_get_unused_arg_info(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_unused_arg_info.
|
|
module_info_get_table_struct_map(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_table_struct_map.
|
|
module_info_get_lambdas_per_context(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_lambdas_per_context.
|
|
module_info_get_atomics_per_context(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_atomics_per_context.
|
|
module_info_get_loop_invs_per_context(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_loop_invs_per_context.
|
|
module_info_get_avail_module_map(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_avail_module_map.
|
|
module_info_get_indirectly_imported_module_names(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_indirectly_imported_module_names.
|
|
module_info_get_used_modules(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_used_modules.
|
|
module_info_get_ancestor_avail_modules(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_ancestor_avail_modules.
|
|
module_info_get_maybe_complexity_proc_map(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_maybe_complexity_proc_map.
|
|
module_info_get_complexity_proc_infos(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_complexity_proc_infos.
|
|
module_info_get_proc_analysis_kinds(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_proc_analysis_kinds.
|
|
module_info_get_analysis_info(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_analysis_info.
|
|
module_info_get_user_init_pred_target_names(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_user_init_pred_target_names.
|
|
module_info_get_user_final_pred_target_names(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_user_final_pred_target_names.
|
|
module_info_get_structure_reuse_preds(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_structure_reuse_preds.
|
|
module_info_get_format_call_pragma_preds(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_format_call_pragma_preds.
|
|
module_info_get_exported_enums(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_exported_enums.
|
|
module_info_get_event_set(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_event_set.
|
|
module_info_get_oisu_map(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_oisu_map.
|
|
module_info_get_oisu_procs(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_oisu_procs.
|
|
module_info_get_ts_rev_string_table(MI, X, Y) :-
|
|
X = MI ^ mi_rare_info ^ mri_ts_string_table_size,
|
|
Y = MI ^ mi_rare_info ^ mri_ts_rev_string_table.
|
|
module_info_get_type_repn_dec(MI, X) :-
|
|
X = MI ^ mi_rare_info ^ mri_type_repn_dec.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Setter predicates for the module_info.
|
|
%
|
|
|
|
module_info_set_globals(X, !MI) :-
|
|
!MI ^ mi_globals := X.
|
|
module_info_set_predicate_table(X, !MI) :-
|
|
!MI ^ mi_predicate_table := X.
|
|
module_info_set_type_table(X, !MI) :-
|
|
!MI ^ mi_type_table := X.
|
|
module_info_set_no_tag_types(X, !MI) :-
|
|
!MI ^ mi_no_tag_type_table := X.
|
|
module_info_set_inst_table(X, !MI) :-
|
|
!MI ^ mi_inst_table := X.
|
|
module_info_set_mode_table(X, !MI) :-
|
|
!MI ^ mi_mode_table := X.
|
|
module_info_set_cons_table(X, !MI) :-
|
|
!MI ^ mi_cons_table := X.
|
|
module_info_set_ctor_field_table(X, !MI) :-
|
|
!MI ^ mi_ctor_field_table := X.
|
|
|
|
module_info_set_special_pred_maps(X, !MI) :-
|
|
!MI ^ mi_sub_info ^ msi_special_pred_maps := X.
|
|
module_info_set_class_table(X, !MI) :-
|
|
!MI ^ mi_sub_info ^ msi_class_table := X.
|
|
module_info_set_instance_table(X, !MI) :-
|
|
!MI ^ mi_sub_info ^ msi_instance_table := X.
|
|
module_info_set_type_spec_info(X, !MI) :-
|
|
!MI ^ mi_sub_info ^ msi_type_spec_info := X.
|
|
module_info_set_const_struct_db(X, !MI) :-
|
|
( if
|
|
private_builtin.pointer_equal(X,
|
|
!.MI ^ mi_sub_info ^ msi_const_struct_db)
|
|
then
|
|
true
|
|
else
|
|
!MI ^ mi_sub_info ^ msi_const_struct_db := X
|
|
).
|
|
module_info_set_c_j_cs_fims(X, !MI) :-
|
|
!MI ^ mi_sub_info ^ msi_c_j_cs_fims := X.
|
|
module_info_set_pragma_exported_procs(X, !MI) :-
|
|
( if
|
|
private_builtin.pointer_equal(X,
|
|
!.MI ^ mi_sub_info ^ msi_pragma_exported_procs)
|
|
then
|
|
true
|
|
else
|
|
!MI ^ mi_sub_info ^ msi_pragma_exported_procs := X
|
|
).
|
|
|
|
module_info_set_maybe_recompilation_info(X, !MI) :-
|
|
( if
|
|
private_builtin.pointer_equal(X,
|
|
!.MI ^ mi_rare_info ^ mri_maybe_recompilation_info)
|
|
then
|
|
true
|
|
else
|
|
!MI ^ mi_rare_info ^ mri_maybe_recompilation_info := X
|
|
).
|
|
module_info_set_proc_requests(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_proc_requests := X.
|
|
module_info_set_assertion_table(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_assertion_table := X.
|
|
module_info_set_exclusive_table(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_exclusive_table := X.
|
|
module_info_set_has_parallel_conj(!MI) :-
|
|
X = has_parallel_conj,
|
|
!MI ^ mi_rare_info ^ mri_has_parallel_conj := X.
|
|
module_info_set_has_user_event(!MI) :-
|
|
X = has_user_event,
|
|
!MI ^ mi_rare_info ^ mri_has_user_event := X.
|
|
module_info_set_direct_arg_proc_map(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_direct_arg_proc_map := X.
|
|
module_info_set_foreign_decl_codes_user(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_foreign_decl_codes_user := X.
|
|
module_info_set_foreign_decl_codes_aux(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_foreign_decl_codes_aux := X.
|
|
module_info_set_foreign_body_codes(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_foreign_body_codes := X.
|
|
module_info_set_int_bad_clauses(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_int_bad_clauses := X.
|
|
module_info_set_maybe_dependency_info(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_maybe_dependency_info := X.
|
|
module_info_set_type_ctor_gen_infos(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_type_ctor_gen_infos := X.
|
|
module_info_set_must_be_stratified_preds(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_must_be_stratified_preds := X.
|
|
module_info_set_unused_arg_info(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_unused_arg_info := X.
|
|
module_info_set_table_struct_map(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_table_struct_map := X.
|
|
module_info_set_lambdas_per_context(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_lambdas_per_context := X.
|
|
module_info_set_atomics_per_context(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_atomics_per_context := X.
|
|
module_info_set_loop_invs_per_context(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_loop_invs_per_context := X.
|
|
module_info_set_used_modules(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_used_modules := X.
|
|
module_info_set_ancestor_avail_modules(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_ancestor_avail_modules := X.
|
|
module_info_set_maybe_complexity_proc_map(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_maybe_complexity_proc_map := X.
|
|
module_info_set_complexity_proc_infos(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_complexity_proc_infos := X.
|
|
module_info_set_proc_analysis_kinds(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_proc_analysis_kinds := X.
|
|
module_info_set_analysis_info(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_analysis_info := X.
|
|
module_info_set_user_init_pred_target_names(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_user_init_pred_target_names := X.
|
|
module_info_set_user_final_pred_target_names(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_user_final_pred_target_names := X.
|
|
module_info_set_structure_reuse_preds(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_structure_reuse_preds := X.
|
|
module_info_set_format_call_pragma_preds(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_format_call_pragma_preds := X.
|
|
module_info_set_exported_enums(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_exported_enums := X.
|
|
module_info_set_event_set(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_event_set := X.
|
|
module_info_set_oisu_map(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_oisu_map := X.
|
|
module_info_set_oisu_procs(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_oisu_procs := X.
|
|
module_info_set_ts_rev_string_table(X, Y, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_ts_string_table_size := X,
|
|
!MI ^ mi_rare_info ^ mri_ts_rev_string_table := Y.
|
|
module_info_set_type_repn_dec(X, !MI) :-
|
|
!MI ^ mi_rare_info ^ mri_type_repn_dec := X.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Utility predicates that are a bit more complicated than
|
|
% a simple getter or setter predicates.
|
|
%
|
|
|
|
module_info_get_pred_id_table(MI, PredIdTable) :-
|
|
module_info_get_predicate_table(MI, PredTable),
|
|
predicate_table_get_pred_id_table(PredTable, PredIdTable).
|
|
|
|
module_info_set_pred_id_table(PredIdTable, !MI) :-
|
|
module_info_get_predicate_table(!.MI, PredTable0),
|
|
predicate_table_set_pred_id_table(PredIdTable, PredTable0, PredTable),
|
|
module_info_set_predicate_table(PredTable, !MI).
|
|
|
|
module_info_pred_info(MI, PredId, PredInfo) :-
|
|
module_info_get_pred_id_table(MI, PredIdTable),
|
|
( if map.search(PredIdTable, PredId, PredInfoPrime) then
|
|
PredInfo = PredInfoPrime
|
|
else
|
|
pred_id_to_int(PredId, PredInt),
|
|
string.int_to_string(PredInt, PredStr),
|
|
unexpected($pred, "cannot find predicate number " ++ PredStr)
|
|
).
|
|
|
|
module_info_proc_info(MI, PPId, ProcInfo) :-
|
|
module_info_pred_proc_info(MI, PPId, _, ProcInfo).
|
|
|
|
module_info_proc_info(MI, PredId, ProcId, ProcInfo) :-
|
|
module_info_pred_proc_info(MI, PredId, ProcId, _, ProcInfo).
|
|
|
|
module_info_pred_proc_info(MI, PredId, ProcId, PredInfo, ProcInfo) :-
|
|
module_info_pred_info(MI, PredId, PredInfo),
|
|
pred_info_get_proc_table(PredInfo, Procs),
|
|
map.lookup(Procs, ProcId, ProcInfo).
|
|
|
|
module_info_pred_proc_info(MI, proc(PredId, ProcId), PredInfo, ProcInfo) :-
|
|
module_info_pred_proc_info(MI, PredId, ProcId, PredInfo, ProcInfo).
|
|
|
|
module_info_get_valid_pred_id_set(MI, PredIdSet) :-
|
|
module_info_get_predicate_table(MI, PredTable),
|
|
predicate_table_get_valid_pred_id_set(PredTable, PredIdSet).
|
|
|
|
module_info_get_valid_pred_ids(MI, PredIds) :-
|
|
module_info_get_predicate_table(MI, PredTable),
|
|
predicate_table_get_valid_pred_id_set(PredTable, PredIdSet),
|
|
set_tree234.to_sorted_list(PredIdSet, PredIds).
|
|
|
|
module_info_make_pred_id_invalid(PredId, !MI) :-
|
|
module_info_get_predicate_table(!.MI, PredTable0),
|
|
predicate_table_make_pred_id_invalid(PredId, PredTable0, PredTable),
|
|
module_info_set_predicate_table(PredTable, !MI).
|
|
|
|
module_info_make_pred_ids_invalid(PredIds, !MI) :-
|
|
module_info_get_predicate_table(!.MI, PredTable0),
|
|
predicate_table_make_pred_ids_invalid(PredIds, PredTable0, PredTable),
|
|
module_info_set_predicate_table(PredTable, !MI).
|
|
|
|
module_info_remove_predicate(PredId, !MI) :-
|
|
module_info_get_predicate_table(!.MI, PredTable0),
|
|
predicate_table_remove_predicate(PredId, PredTable0, PredTable),
|
|
module_info_set_predicate_table(PredTable, !MI).
|
|
|
|
module_info_set_pred_info(PredId, PredInfo, !MI) :-
|
|
module_info_get_pred_id_table(!.MI, PredIdTable0),
|
|
% XXX Should be map.det_update.
|
|
map.set(PredId, PredInfo, PredIdTable0, PredIdTable),
|
|
module_info_set_pred_id_table(PredIdTable, !MI).
|
|
|
|
module_info_set_pred_proc_info(proc(PredId, ProcId), PredInfo, ProcInfo,
|
|
!MI) :-
|
|
module_info_set_pred_proc_info(PredId, ProcId,
|
|
PredInfo, ProcInfo, !MI).
|
|
|
|
module_info_set_pred_proc_info(PredId, ProcId, PredInfo0, ProcInfo, !MI) :-
|
|
% XXX Should be pred_info_set_proc_info, which calls map.det_update.
|
|
pred_info_get_proc_table(PredInfo0, Procs0),
|
|
map.set(ProcId, ProcInfo, Procs0, Procs),
|
|
pred_info_set_proc_table(Procs, PredInfo0, PredInfo),
|
|
module_info_set_pred_info(PredId, PredInfo, !MI).
|
|
|
|
%---------------------%
|
|
|
|
predicate_id(ModuleInfo, PredId, ModuleName, PredName, Arity) :-
|
|
module_info_pred_info(ModuleInfo, PredId, PredInfo),
|
|
ModuleName = pred_info_module(PredInfo),
|
|
PredName = pred_info_name(PredInfo),
|
|
Arity = pred_info_orig_arity(PredInfo).
|
|
|
|
predicate_module(ModuleInfo, PredId) = ModuleName :-
|
|
module_info_pred_info(ModuleInfo, PredId, PredInfo),
|
|
ModuleName = pred_info_module(PredInfo).
|
|
|
|
predicate_name(ModuleInfo, PredId) = PredName :-
|
|
module_info_pred_info(ModuleInfo, PredId, PredInfo),
|
|
PredName = pred_info_name(PredInfo).
|
|
|
|
predicate_arity(ModuleInfo, PredId) = Arity :-
|
|
module_info_pred_info(ModuleInfo, PredId, PredInfo),
|
|
Arity = pred_info_orig_arity(PredInfo).
|
|
|
|
%---------------------%
|
|
|
|
module_add_foreign_decl_code_user(ForeignDeclCode, !Module) :-
|
|
module_info_get_foreign_decl_codes_user(!.Module, ForeignDeclCodes0),
|
|
ForeignDeclCodes = cord.snoc(ForeignDeclCodes0, ForeignDeclCode),
|
|
module_info_set_foreign_decl_codes_user(ForeignDeclCodes, !Module).
|
|
|
|
module_add_foreign_decl_code_aux(ForeignDeclCode, !Module) :-
|
|
module_info_get_foreign_decl_codes_aux(!.Module, ForeignDeclCodes0),
|
|
ForeignDeclCodes = cord.snoc(ForeignDeclCodes0, ForeignDeclCode),
|
|
module_info_set_foreign_decl_codes_aux(ForeignDeclCodes, !Module).
|
|
|
|
module_add_foreign_body_code(ForeignBodyCode, !Module) :-
|
|
module_info_get_foreign_body_codes(!.Module, ForeignBodyCodes0),
|
|
ForeignBodyCodes = cord.snoc(ForeignBodyCodes0, ForeignBodyCode),
|
|
module_info_set_foreign_body_codes(ForeignBodyCodes, !Module).
|
|
|
|
module_add_item_fim(ItemFIM, !Module) :-
|
|
module_info_get_c_j_cs_fims(!.Module, FIMs0),
|
|
ItemFIM = item_fim(Lang, ModuleName, _Context, _SeqNum),
|
|
add_fim(Lang, ModuleName, FIMs0, FIMs),
|
|
module_info_set_c_j_cs_fims(FIMs, !Module).
|
|
|
|
module_add_fact_table_file(FileName, !Module) :-
|
|
FileNames0 = !.Module ^ mi_rare_info ^ mri_fact_table_file_names,
|
|
FileNames = [FileName | FileNames0],
|
|
!Module ^ mi_rare_info ^ mri_fact_table_file_names := FileNames.
|
|
|
|
%---------------------%
|
|
|
|
module_info_dependency_info(MI, DepInfo) :-
|
|
module_info_get_maybe_dependency_info(MI, MaybeDepInfo),
|
|
(
|
|
MaybeDepInfo = yes(DepInfoPrime),
|
|
DepInfo = DepInfoPrime
|
|
;
|
|
MaybeDepInfo = no,
|
|
unexpected($pred, "attempted to access invalid dependency_info")
|
|
).
|
|
|
|
module_info_set_dependency_info(DependencyInfo, !MI) :-
|
|
module_info_set_maybe_dependency_info(yes(DependencyInfo), !MI).
|
|
|
|
module_info_clobber_dependency_info(!MI) :-
|
|
module_info_set_maybe_dependency_info(no, !MI).
|
|
|
|
%---------------------%
|
|
|
|
module_info_next_lambda_count(Context, Count, !MI) :-
|
|
module_info_get_lambdas_per_context(!.MI, ContextCounter0),
|
|
( if
|
|
map.insert(Context, counter.init(2),
|
|
ContextCounter0, FoundContextCounter)
|
|
then
|
|
Count = 1,
|
|
ContextCounter = FoundContextCounter
|
|
else
|
|
map.lookup(ContextCounter0, Context, Counter0),
|
|
counter.allocate(Count, Counter0, Counter),
|
|
map.det_update(Context, Counter, ContextCounter0, ContextCounter)
|
|
),
|
|
module_info_set_lambdas_per_context(ContextCounter, !MI).
|
|
|
|
module_info_next_atomic_count(Context, Count, !MI) :-
|
|
module_info_get_atomics_per_context(!.MI, ContextCounter0),
|
|
( if
|
|
map.insert(Context, counter.init(2),
|
|
ContextCounter0, FoundContextCounter)
|
|
then
|
|
Count = 1,
|
|
ContextCounter = FoundContextCounter
|
|
else
|
|
map.lookup(ContextCounter0, Context, Counter0),
|
|
counter.allocate(Count, Counter0, Counter),
|
|
map.det_update(Context, Counter, ContextCounter0, ContextCounter)
|
|
),
|
|
module_info_set_atomics_per_context(ContextCounter, !MI).
|
|
|
|
module_info_next_loop_inv_count(Context, Count, !MI) :-
|
|
module_info_get_loop_invs_per_context(!.MI, ContextCounter0),
|
|
( if
|
|
map.insert(Context, counter.init(2),
|
|
ContextCounter0, FoundContextCounter)
|
|
then
|
|
Count = 1,
|
|
ContextCounter = FoundContextCounter
|
|
else
|
|
map.lookup(ContextCounter0, Context, Counter0),
|
|
counter.allocate(Count, Counter0, Counter),
|
|
map.det_update(Context, Counter, ContextCounter0, ContextCounter)
|
|
),
|
|
module_info_set_loop_invs_per_context(ContextCounter, !MI).
|
|
|
|
%---------------------%
|
|
|
|
module_add_avail_module_name(ModuleName, NewSection, NewImportOrUse,
|
|
MaybeContext, !MI) :-
|
|
(
|
|
MaybeContext = no,
|
|
NewAvails = []
|
|
;
|
|
MaybeContext = yes(Context),
|
|
NewAvails = [avail_module(NewSection, NewImportOrUse, Context)]
|
|
),
|
|
AvailMap0 = !.MI ^ mi_rare_info ^ mri_avail_module_map,
|
|
( if map.search(AvailMap0, ModuleName, OldEntry) then
|
|
OldEntry = avail_module_entry(OldSection, OldImportOrUse, OldAvails),
|
|
% XXX: If one of the entries (new or old) is a use_module in the
|
|
% interface section, while the other is an import_module in the
|
|
% implementation section, the result *ought* to be something like
|
|
% the int_use_imp_import alternative of the section_import_or_use type,
|
|
% BUT the design of avail_module_entry has no way to express that.
|
|
% The code of combine_old_new_avail_attrs returns "import_module in the
|
|
% interface section" in such cases, which is almost certainly a bug.
|
|
combine_old_new_avail_attrs(OldSection, NewSection,
|
|
OldImportOrUse, NewImportOrUse, Section, ImportOrUse),
|
|
Avails = NewAvails ++ OldAvails,
|
|
NewEntry = avail_module_entry(Section, ImportOrUse, Avails),
|
|
map.det_update(ModuleName, NewEntry, AvailMap0, AvailMap)
|
|
else
|
|
NewEntry = avail_module_entry(NewSection, NewImportOrUse, NewAvails),
|
|
map.det_insert(ModuleName, NewEntry, AvailMap0, AvailMap)
|
|
),
|
|
!MI ^ mi_rare_info ^ mri_avail_module_map := AvailMap.
|
|
|
|
:- pred combine_old_new_avail_attrs(module_section::in, module_section::in,
|
|
import_or_use::in, import_or_use::in,
|
|
module_section::out, import_or_use::out) is det.
|
|
|
|
combine_old_new_avail_attrs(OldSection, NewSection,
|
|
OldImportOrUse, NewImportOrUse, Section, ImportOrUse) :-
|
|
( if
|
|
( OldSection = ms_interface
|
|
; NewSection = ms_interface
|
|
)
|
|
then
|
|
Section = ms_interface
|
|
else
|
|
Section = ms_implementation
|
|
),
|
|
( if
|
|
( OldImportOrUse = import_decl
|
|
; NewImportOrUse = import_decl
|
|
)
|
|
then
|
|
ImportOrUse = import_decl
|
|
else
|
|
ImportOrUse = use_decl
|
|
).
|
|
|
|
module_add_indirectly_imported_module_name(AddedModuleSpecifier, !MI) :-
|
|
Modules0 = !.MI ^ mi_rare_info ^ mri_indirectly_imported_module_names,
|
|
set.insert(AddedModuleSpecifier, Modules0, Modules),
|
|
!MI ^ mi_rare_info ^ mri_indirectly_imported_module_names := Modules.
|
|
|
|
module_info_get_visible_modules(ModuleInfo, !:VisibleModules) :-
|
|
module_info_get_name(ModuleInfo, ThisModule),
|
|
module_info_get_avail_module_map(ModuleInfo, AvailModuleMap),
|
|
|
|
map.keys(AvailModuleMap, AvailModules),
|
|
set.list_to_set(AvailModules, !:VisibleModules),
|
|
set.insert(ThisModule, !VisibleModules),
|
|
set.insert_list(get_ancestors(ThisModule), !VisibleModules).
|
|
|
|
module_info_get_all_deps(ModuleInfo, AllImports) :-
|
|
module_info_get_name(ModuleInfo, ModuleName),
|
|
Parents = get_ancestors(ModuleName),
|
|
module_info_get_avail_module_map(ModuleInfo, AvailModuleMap),
|
|
map.keys(AvailModuleMap, DirectImports),
|
|
module_info_get_indirectly_imported_module_names(ModuleInfo,
|
|
IndirectImports),
|
|
AllImports = set.union_list([IndirectImports,
|
|
set.list_to_set(DirectImports), set.list_to_set(Parents)]).
|
|
|
|
module_info_add_module_to_public_used_modules(ModuleName, !MI) :-
|
|
module_info_get_used_modules(!.MI, UsedModules0),
|
|
record_module_and_ancestors_as_used(visibility_public, ModuleName,
|
|
UsedModules0, UsedModules),
|
|
module_info_set_used_modules(UsedModules, !MI).
|
|
|
|
%---------------------%
|
|
|
|
module_info_user_init_pred_target_names(MI, CNames) :-
|
|
module_info_get_user_init_pred_target_names(MI, InitPredTargetNames),
|
|
InitPredTargetNames = pred_target_names(SeqNumToPredTargetNamesMap),
|
|
map.values(SeqNumToPredTargetNamesMap, PredTargetNamesLists),
|
|
list.condense(PredTargetNamesLists, PredTargetNames),
|
|
CNames = assoc_list.values(PredTargetNames).
|
|
|
|
module_info_user_final_pred_target_names(MI, CNames) :-
|
|
module_info_get_user_final_pred_target_names(MI, FinalPredTargetNames),
|
|
FinalPredTargetNames = pred_target_names(SeqNumToPredTargetNamesMap),
|
|
map.values(SeqNumToPredTargetNamesMap, PredTargetNamesLists),
|
|
list.condense(PredTargetNamesLists, PredTargetNames),
|
|
CNames = assoc_list.values(PredTargetNames).
|
|
|
|
module_info_user_init_pred_procs(MI, PredProcIds) :-
|
|
module_info_get_user_init_pred_target_names(MI, InitPredTargetNames),
|
|
InitPredTargetNames = pred_target_names(SeqNumToPredTargetNamesMap),
|
|
map.values(SeqNumToPredTargetNamesMap, PredTargetNamesLists),
|
|
list.condense(PredTargetNamesLists, PredTargetNames),
|
|
SymNamesArities = assoc_list.keys(PredTargetNames),
|
|
list.map(get_unique_pred_proc_id_for_pred_sym_name_arity(MI),
|
|
SymNamesArities, PredProcIds).
|
|
|
|
module_info_user_final_pred_procs(MI, PredProcIds) :-
|
|
module_info_get_user_final_pred_target_names(MI, FinalPredTargetNames),
|
|
FinalPredTargetNames = pred_target_names(SeqNumToPredTargetNamesMap),
|
|
map.values(SeqNumToPredTargetNamesMap, PredTargetNamesLists),
|
|
list.condense(PredTargetNamesLists, PredTargetNames),
|
|
SymNamesArities = assoc_list.keys(PredTargetNames),
|
|
list.map(get_unique_pred_proc_id_for_pred_sym_name_arity(MI),
|
|
SymNamesArities, PredProcIds).
|
|
|
|
:- pred get_unique_pred_proc_id_for_pred_sym_name_arity(module_info::in,
|
|
sym_name_arity::in, pred_proc_id::out) is det.
|
|
|
|
get_unique_pred_proc_id_for_pred_sym_name_arity(MI, SNA, PredProcId) :-
|
|
module_info_get_predicate_table(MI, PredTable),
|
|
SNA = sym_name_arity(SymName, Arity),
|
|
UserArity = user_arity(Arity),
|
|
predicate_table_lookup_pred_sym_arity(PredTable,
|
|
may_be_partially_qualified, SymName, UserArity, PredIds),
|
|
( if PredIds = [PredId] then
|
|
pred_table.get_single_proc_id(MI, PredId, ProcId),
|
|
PredProcId = proc(PredId, ProcId)
|
|
else
|
|
unexpected($pred, "lookup failed")
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module hlds.hlds_module.
|
|
%---------------------------------------------------------------------------%
|