mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-16 14:25:56 +00:00
Branches: main Mark procedures whose names use the suffix "_det" to indicate that the procedure is a det version of a semidet procedure of the same name (modulo the suffix) as obsolete. The versions that use "det_" as a prefix should be used instead. (The latter naming scheme is the one in general use throughout the standard library.) library/dir.m: library/list.m: library/stack.m: As above. Add versions with the "det_" suffix where they were not already present. Group function definitions together with the corresponding predicate definition. library/cord.m: library/erlang_rtti_implementation.m: library/io.m: library/string.m: compiler/*.m: browser/declarative_execution.m: browser/declarative_tree.m: ssdb/ssdb.m: Conform to the above changes. library/Mercury.options: Delete a setting for a deleted module. NEWS: Announce this change.
606 lines
25 KiB
Mathematica
606 lines
25 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 2009, 2011 The University of Melbourne.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% File: ml_code_util.m.
|
|
% Main author: fjh.
|
|
%
|
|
% This module is part of the MLDS code generator.
|
|
% It defines the ml_gen_info type and its access routines.
|
|
%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module ml_backend.ml_gen_info.
|
|
:- interface.
|
|
|
|
:- import_module hlds.hlds_module.
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module libs.globals.
|
|
:- import_module ml_backend.mlds.
|
|
:- import_module ml_backend.ml_global_data.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
:- import_module bool.
|
|
:- import_module list.
|
|
:- import_module map.
|
|
:- import_module set.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% The `ml_gen_info' ADT.
|
|
%
|
|
|
|
% The `ml_gen_info' type holds information used during
|
|
% MLDS code generation for a given procedure.
|
|
%
|
|
:- type ml_gen_info.
|
|
|
|
% Initialize the ml_gen_info, so that it is ready for generating code
|
|
% for the given procedure. The last argument records the persistent
|
|
% information accumulated by the code generator so far during the
|
|
% processing of previous procedures.
|
|
%
|
|
:- func ml_gen_info_init(module_info, pred_id, proc_id, proc_info,
|
|
ml_global_data) = ml_gen_info.
|
|
|
|
:- pred ml_gen_info_get_module_info(ml_gen_info::in, module_info::out) is det.
|
|
:- pred ml_gen_info_get_high_level_data(ml_gen_info::in, bool::out) is det.
|
|
:- pred ml_gen_info_get_target(ml_gen_info::in, compilation_target::out)
|
|
is det.
|
|
:- pred ml_gen_info_get_pred_id(ml_gen_info::in, pred_id::out) is det.
|
|
:- pred ml_gen_info_get_proc_id(ml_gen_info::in, proc_id::out) is det.
|
|
:- pred ml_gen_info_get_varset(ml_gen_info::in, prog_varset::out) is det.
|
|
:- pred ml_gen_info_get_var_types(ml_gen_info::in, vartypes::out) is det.
|
|
:- pred ml_gen_info_get_byref_output_vars(ml_gen_info::in, list(prog_var)::out)
|
|
is det.
|
|
:- pred ml_gen_info_get_value_output_vars(ml_gen_info::in, list(prog_var)::out)
|
|
is det.
|
|
:- pred ml_gen_info_get_global_data(ml_gen_info::in, ml_global_data::out)
|
|
is det.
|
|
|
|
:- pred ml_gen_info_set_module_info(module_info::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
:- pred ml_gen_info_set_varset(prog_varset::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
:- pred ml_gen_info_set_var_types(vartypes::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
:- pred ml_gen_info_set_byref_output_vars(list(prog_var)::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
:- pred ml_gen_info_set_value_output_vars(list(prog_var)::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
:- pred ml_gen_info_set_global_data(ml_global_data::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
:- pred ml_gen_info_get_globals(ml_gen_info::in, globals::out) is det.
|
|
:- pred ml_gen_info_get_module_name(ml_gen_info::in, mercury_module_name::out)
|
|
is det.
|
|
|
|
% Lookup the --gcc-nested-functions option.
|
|
%
|
|
:- pred ml_gen_info_use_gcc_nested_functions(ml_gen_info::in, bool::out)
|
|
is det.
|
|
|
|
% Lookup the --put-commit-in-nested-func option.
|
|
%
|
|
:- pred ml_gen_info_put_commit_in_own_func(ml_gen_info::in, bool::out) is det.
|
|
|
|
% Generate a new label number for use in label statements.
|
|
% This is used to give unique names to the case labels generated
|
|
% for dense switch statements.
|
|
%
|
|
:- type label_num == int.
|
|
:- pred ml_gen_info_new_label(label_num::out,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
% A number corresponding to an MLDS nested function which serves as a
|
|
% label (i.e. a continuation function).
|
|
%
|
|
:- type ml_label_func == mlds_func_sequence_num.
|
|
|
|
% Generate a new function label number. This is used to give unique names
|
|
% to the nested functions used when generating code for nondet procedures.
|
|
%
|
|
:- pred ml_gen_info_new_func_label(ml_label_func::out,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
% Increase the function label and const sequence number counters by some
|
|
% amount which is presumed to be sufficient to ensure that if we start
|
|
% again with a fresh ml_gen_info and then call this function, we won't
|
|
% encounter any already-used function labels or constants. (This is used
|
|
% when generating wrapper functions for type class methods.)
|
|
%
|
|
:- pred ml_gen_info_bump_counters(ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
% Generate a new auxiliary variable name. The name of the variable
|
|
% will start with the given prefix and end with a sequence number
|
|
% that differentiates this aux var from all others.
|
|
%
|
|
% Auxiliary variables are used for purposes such as commit label numbers
|
|
% and holding table indexes in switches.
|
|
%
|
|
:- pred ml_gen_info_new_aux_var_name(string::in, mlds_var_name::out,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
% Generate a new `cond' variable number.
|
|
%
|
|
:- type cond_seq ---> cond_seq(int).
|
|
:- pred ml_gen_info_new_cond_var(cond_seq::out,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
% Generate a new `conv' variable number. This is used to give unique names
|
|
% to the local variables generated by ml_gen_box_or_unbox_lval, which are
|
|
% used to handle boxing/unboxing argument conversions.
|
|
%
|
|
:- type conv_seq ---> conv_seq(int).
|
|
:- pred ml_gen_info_new_conv_var(conv_seq::out,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
:- type ml_ground_term
|
|
---> ml_ground_term(
|
|
% The value of the ground term.
|
|
mlds_rval,
|
|
|
|
% The type of the ground term (actually, the type of the
|
|
% variable the ground term was constructed for).
|
|
mer_type,
|
|
|
|
% The corresponding MLDS type. It could be computed from the
|
|
% Mercury type, but there is no point in doing so when using
|
|
% the ground term as well when constructing it.
|
|
mlds_type
|
|
).
|
|
|
|
:- type ml_ground_term_map == map(prog_var, ml_ground_term).
|
|
|
|
% Set the `const' variable name corresponding to the given HLDS variable.
|
|
%
|
|
:- pred ml_gen_info_set_const_var(prog_var::in, ml_ground_term::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
% Lookup the `const' sequence number corresponding to a given HLDS
|
|
% variable.
|
|
%
|
|
:- pred ml_gen_info_lookup_const_var(ml_gen_info::in, prog_var::in,
|
|
ml_ground_term::out) is det.
|
|
:- pred ml_gen_info_search_const_var(ml_gen_info::in, prog_var::in,
|
|
ml_ground_term::out) is semidet.
|
|
|
|
% A success continuation specifies the (rval for the variable holding
|
|
% the address of the) function that a nondet procedure should call
|
|
% if it succeeds, and possibly also the (rval for the variable holding)
|
|
% the environment pointer for that function, and possibly also the
|
|
% (list of rvals for the) arguments to the continuation.
|
|
|
|
:- type success_cont
|
|
---> success_cont(
|
|
mlds_rval, % function pointer
|
|
mlds_rval, % environment pointer
|
|
% note that if we're using nested
|
|
% functions then the environment
|
|
% pointer will not be used
|
|
list(mlds_type), % argument types, if any
|
|
list(mlds_lval) % arguments, if any
|
|
% The arguments will only be non-empty
|
|
% if the --nondet-copy-out option is
|
|
% enabled. They do not include the
|
|
% environment pointer.
|
|
).
|
|
|
|
% The ml_gen_info contains a stack of success continuations.
|
|
% The following routines provide access to that stack.
|
|
|
|
:- pred ml_gen_info_push_success_cont(success_cont::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
:- pred ml_gen_info_pop_success_cont(ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
:- pred ml_gen_info_current_success_cont(ml_gen_info::in, success_cont::out)
|
|
is det.
|
|
|
|
% We keep a partial mapping from vars to lvals. This is used in special
|
|
% cases to override the normal lval for a variable. ml_gen_var will check
|
|
% this map first, and if the variable is not in this map, then it will go
|
|
% ahead and generate an lval for it as usual.
|
|
|
|
% Set the lval for a variable.
|
|
%
|
|
:- pred ml_gen_info_set_var_lval(prog_var::in, mlds_lval::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
% Get the partial mapping from variables to lvals.
|
|
%
|
|
:- pred ml_gen_info_get_var_lvals(ml_gen_info::in,
|
|
map(prog_var, mlds_lval)::out) is det.
|
|
|
|
% Set the partial mapping from variables to lvals.
|
|
%
|
|
:- pred ml_gen_info_set_var_lvals(map(prog_var, mlds_lval)::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
% A variable can be bound to a constant in one branch of a control
|
|
% structure and to a non-constant term in another branch. We remember
|
|
% information about variables bound to constants in the map these two
|
|
% predicates are the getter and setter of. Branched control structures
|
|
% should reset the map to its original value at the start of every branch
|
|
% after the first (to prevent a later branch from using information that is
|
|
% applicable only in a previous branch), and at the end of the branched
|
|
% control structure (to prevent the code after it using information whose
|
|
% correctness depends on the exact route execution took to there).
|
|
%
|
|
:- pred ml_gen_info_get_const_var_map(ml_gen_info::in,
|
|
map(prog_var, ml_ground_term)::out) is det.
|
|
:- pred ml_gen_info_set_const_var_map(map(prog_var, ml_ground_term)::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
% The ml_gen_info contains a list of extra definitions of functions or
|
|
% global constants which should be inserted before the definition of the
|
|
% function for the current procedure. This is used for the definitions
|
|
% of the wrapper functions needed for closures. When generating code
|
|
% for a procedure that creates a closure, we insert the definition of
|
|
% the wrapper function used for that closure into this list.
|
|
|
|
% Insert an extra definition at the start of the list of extra
|
|
% definitions.
|
|
%
|
|
:- pred ml_gen_info_add_closure_wrapper_defn(mlds_defn::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
% Get the list of extra definitions.
|
|
%
|
|
:- pred ml_gen_info_get_closure_wrapper_defns(ml_gen_info::in,
|
|
list(mlds_defn)::out) is det.
|
|
|
|
% Add the given string as the name of an environment variable used by
|
|
% the function being generated.
|
|
%
|
|
:- pred ml_gen_info_add_env_var_name(string::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
% Get the names of the used environment variables.
|
|
%
|
|
:- pred ml_gen_info_get_env_var_names(ml_gen_info::in, set(string)::out)
|
|
is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module check_hlds.mode_util.
|
|
:- import_module libs.options.
|
|
|
|
:- import_module counter.
|
|
:- import_module int.
|
|
:- import_module maybe.
|
|
:- import_module stack.
|
|
:- import_module string.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% The definition of the `ml_gen_info' ADT.
|
|
%
|
|
|
|
:- type ml_gen_info
|
|
---> ml_gen_info(
|
|
/* 1 */ mgi_module_info :: module_info,
|
|
|
|
% These fields remain constant for each procedure unless
|
|
% accurate GC is enabled, in which case they may get updated
|
|
% if we create fresh variables for the type_info variables
|
|
% needed for calls to private_builtin.gc_trace.
|
|
/* 2 */ mgi_varset :: prog_varset,
|
|
/* 3 */ mgi_var_types :: vartypes,
|
|
|
|
% Output arguments that are passed by reference.
|
|
/* 4 */ mgi_byref_output_vars :: list(prog_var),
|
|
|
|
% Output arguments that are returned as values.
|
|
/* 5 */ mgi_value_output_vars :: list(prog_var),
|
|
|
|
% Definitions of functions or global constants which should be
|
|
% inserted before the definition of the function for the
|
|
% current procedure.
|
|
/* 6 */ mgi_var_lvals :: map(prog_var, mlds_lval),
|
|
|
|
/* 7 */ mgi_global_data :: ml_global_data,
|
|
|
|
% All of the other pieces of information that are not among
|
|
% the most frequently read and/or written fields. Limiting
|
|
% ml_gen_info to eight fields make updating the structure
|
|
% quicker and less wasteful of memory.
|
|
/* 8 */ mgi_sub_info :: ml_gen_sub_info
|
|
).
|
|
|
|
:- type ml_gen_sub_info
|
|
---> ml_gen_sub_info(
|
|
% Quick-access read-only copies of parts of the globals
|
|
% structure taken from the module_info.
|
|
/* 1 */ mgsi_high_level_data :: bool,
|
|
/* 2 */ mgsi_target :: compilation_target,
|
|
|
|
% The identity of the procedure we are generating code for.
|
|
/* 3 */ mgsi_pred_id :: pred_id,
|
|
/* 4 */ mgsi_proc_id :: proc_id,
|
|
|
|
/* 5 */ mgsi_func_counter :: counter,
|
|
/* 6 */ mgsi_label_counter :: counter,
|
|
/* 7 */ mgsi_aux_var_counter :: counter,
|
|
/* 8 */ mgsi_cond_var_counter :: counter,
|
|
/* 9 */ mgsi_conv_var_counter :: counter,
|
|
|
|
/* 10 */ mgsi_const_var_map :: map(prog_var, ml_ground_term),
|
|
|
|
/* 11 */ mgsi_closure_wrapper_defns :: list(mlds_defn),
|
|
|
|
% A partial mapping from vars to lvals, used to override
|
|
% the normal lval that we use for a variable.
|
|
/* 12 */ mgsi_success_cont_stack :: stack(success_cont),
|
|
|
|
/* 13 */ mgsi_env_var_names :: set(string)
|
|
).
|
|
|
|
ml_gen_info_init(ModuleInfo, PredId, ProcId, ProcInfo, GlobalData) = Info :-
|
|
module_info_get_globals(ModuleInfo, Globals),
|
|
globals.lookup_bool_option(Globals, highlevel_data, HighLevelData),
|
|
globals.get_target(Globals, CompilationTarget),
|
|
|
|
proc_info_get_headvars(ProcInfo, HeadVars),
|
|
proc_info_get_varset(ProcInfo, VarSet),
|
|
proc_info_get_vartypes(ProcInfo, VarTypes),
|
|
proc_info_get_argmodes(ProcInfo, HeadModes),
|
|
ByRefOutputVars = select_output_vars(ModuleInfo, HeadVars, HeadModes,
|
|
VarTypes),
|
|
ValueOutputVars = [],
|
|
|
|
% XXX This needs to start at 1 rather than 0 otherwise the transformation
|
|
% for adding the shadow stack for accurate garbage collection does not work
|
|
% properly and we will end up generating two C functions with the same
|
|
% name (see ml_elim_nested.gen_gc_trace_func/8 for details).
|
|
%
|
|
counter.init(1, FuncLabelCounter),
|
|
counter.init(0, LabelCounter),
|
|
counter.init(0, AuxVarCounter),
|
|
counter.init(0, CondVarCounter),
|
|
counter.init(0, ConvVarCounter),
|
|
map.init(ConstVarMap),
|
|
stack.init(SuccContStack),
|
|
map.init(VarLvals),
|
|
ClosureWrapperDefns = [],
|
|
EnvVarNames = set.init,
|
|
|
|
SubInfo = ml_gen_sub_info(
|
|
HighLevelData,
|
|
CompilationTarget,
|
|
PredId,
|
|
ProcId,
|
|
FuncLabelCounter,
|
|
LabelCounter,
|
|
AuxVarCounter,
|
|
CondVarCounter,
|
|
ConvVarCounter,
|
|
ConstVarMap,
|
|
ClosureWrapperDefns,
|
|
SuccContStack,
|
|
EnvVarNames
|
|
),
|
|
Info = ml_gen_info(
|
|
ModuleInfo,
|
|
VarSet,
|
|
VarTypes,
|
|
ByRefOutputVars,
|
|
ValueOutputVars,
|
|
VarLvals,
|
|
GlobalData,
|
|
SubInfo
|
|
).
|
|
|
|
:- pred ml_gen_info_get_func_counter(ml_gen_info::in, counter::out) is det.
|
|
:- pred ml_gen_info_get_label_counter(ml_gen_info::in, counter::out) is det.
|
|
:- pred ml_gen_info_get_aux_var_counter(ml_gen_info::in, counter::out) is det.
|
|
:- pred ml_gen_info_get_cond_var_counter(ml_gen_info::in, counter::out) is det.
|
|
:- pred ml_gen_info_get_conv_var_counter(ml_gen_info::in, counter::out) is det.
|
|
:- pred ml_gen_info_get_success_cont_stack(ml_gen_info::in,
|
|
stack(success_cont)::out) is det.
|
|
|
|
ml_gen_info_get_module_info(Info, Info ^ mgi_module_info).
|
|
ml_gen_info_get_high_level_data(Info,
|
|
Info ^ mgi_sub_info ^ mgsi_high_level_data).
|
|
ml_gen_info_get_target(Info, Info ^ mgi_sub_info ^ mgsi_target).
|
|
ml_gen_info_get_pred_id(Info, Info ^ mgi_sub_info ^ mgsi_pred_id).
|
|
ml_gen_info_get_proc_id(Info, Info ^ mgi_sub_info ^ mgsi_proc_id).
|
|
ml_gen_info_get_varset(Info, Info ^ mgi_varset).
|
|
ml_gen_info_get_var_types(Info, Info ^ mgi_var_types).
|
|
ml_gen_info_get_byref_output_vars(Info, Info ^ mgi_byref_output_vars).
|
|
ml_gen_info_get_value_output_vars(Info, Info ^ mgi_value_output_vars).
|
|
ml_gen_info_get_var_lvals(Info, Info ^ mgi_var_lvals).
|
|
ml_gen_info_get_global_data(Info, Info ^ mgi_global_data).
|
|
|
|
ml_gen_info_get_func_counter(Info, Info ^ mgi_sub_info ^ mgsi_func_counter).
|
|
ml_gen_info_get_label_counter(Info, Info ^ mgi_sub_info ^ mgsi_label_counter).
|
|
ml_gen_info_get_aux_var_counter(Info,
|
|
Info ^ mgi_sub_info ^ mgsi_aux_var_counter).
|
|
ml_gen_info_get_cond_var_counter(Info,
|
|
Info ^ mgi_sub_info ^ mgsi_cond_var_counter).
|
|
ml_gen_info_get_conv_var_counter(Info,
|
|
Info ^ mgi_sub_info ^ mgsi_conv_var_counter).
|
|
ml_gen_info_get_const_var_map(Info,
|
|
Info ^ mgi_sub_info ^ mgsi_const_var_map).
|
|
ml_gen_info_get_success_cont_stack(Info,
|
|
Info ^ mgi_sub_info ^ mgsi_success_cont_stack).
|
|
ml_gen_info_get_closure_wrapper_defns(Info,
|
|
Info ^ mgi_sub_info ^ mgsi_closure_wrapper_defns).
|
|
ml_gen_info_get_env_var_names(Info, Info ^ mgi_sub_info ^ mgsi_env_var_names).
|
|
|
|
:- pred ml_gen_info_set_func_counter(counter::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
:- pred ml_gen_info_set_label_counter(counter::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
:- pred ml_gen_info_set_aux_var_counter(counter::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
:- pred ml_gen_info_set_cond_var_counter(counter::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
:- pred ml_gen_info_set_conv_var_counter(counter::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
:- pred ml_gen_info_set_success_cont_stack(stack(success_cont)::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
:- pred ml_gen_info_set_closure_wrapper_defns(list(mlds_defn)::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
:- pred ml_gen_info_set_env_var_names(set(string)::in,
|
|
ml_gen_info::in, ml_gen_info::out) is det.
|
|
|
|
ml_gen_info_set_module_info(ModuleInfo, !Info) :-
|
|
!Info ^ mgi_module_info := ModuleInfo.
|
|
ml_gen_info_set_varset(VarSet, !Info) :-
|
|
!Info ^ mgi_varset := VarSet.
|
|
ml_gen_info_set_var_types(VarTypes, !Info) :-
|
|
!Info ^ mgi_var_types := VarTypes.
|
|
ml_gen_info_set_byref_output_vars(OutputVars, !Info) :-
|
|
!Info ^ mgi_byref_output_vars := OutputVars.
|
|
ml_gen_info_set_value_output_vars(OutputVars, !Info) :-
|
|
!Info ^ mgi_value_output_vars := OutputVars.
|
|
ml_gen_info_set_var_lvals(VarLvals, !Info) :-
|
|
!Info ^ mgi_var_lvals := VarLvals.
|
|
ml_gen_info_set_global_data(GlobalData, !Info) :-
|
|
!Info ^ mgi_global_data := GlobalData.
|
|
|
|
ml_gen_info_set_func_counter(FuncCounter, !Info) :-
|
|
SubInfo0 = !.Info ^ mgi_sub_info,
|
|
SubInfo = SubInfo0 ^ mgsi_func_counter := FuncCounter,
|
|
!Info ^ mgi_sub_info := SubInfo.
|
|
ml_gen_info_set_label_counter(LabelCounter, !Info) :-
|
|
SubInfo0 = !.Info ^ mgi_sub_info,
|
|
SubInfo = SubInfo0 ^ mgsi_label_counter := LabelCounter,
|
|
!Info ^ mgi_sub_info := SubInfo.
|
|
ml_gen_info_set_aux_var_counter(AuxVarCounter, !Info) :-
|
|
SubInfo0 = !.Info ^ mgi_sub_info,
|
|
SubInfo = SubInfo0 ^ mgsi_aux_var_counter := AuxVarCounter,
|
|
!Info ^ mgi_sub_info := SubInfo.
|
|
ml_gen_info_set_cond_var_counter(CondVarCounter, !Info) :-
|
|
SubInfo0 = !.Info ^ mgi_sub_info,
|
|
SubInfo = SubInfo0 ^ mgsi_cond_var_counter := CondVarCounter,
|
|
!Info ^ mgi_sub_info := SubInfo.
|
|
ml_gen_info_set_conv_var_counter(ConvVarCounter, !Info) :-
|
|
SubInfo0 = !.Info ^ mgi_sub_info,
|
|
SubInfo = SubInfo0 ^ mgsi_conv_var_counter := ConvVarCounter,
|
|
!Info ^ mgi_sub_info := SubInfo.
|
|
ml_gen_info_set_const_var_map(ConstVarMap, !Info) :-
|
|
SubInfo0 = !.Info ^ mgi_sub_info,
|
|
SubInfo = SubInfo0 ^ mgsi_const_var_map := ConstVarMap,
|
|
!Info ^ mgi_sub_info := SubInfo.
|
|
ml_gen_info_set_success_cont_stack(SuccessContStack, !Info) :-
|
|
SubInfo0 = !.Info ^ mgi_sub_info,
|
|
SubInfo = SubInfo0 ^ mgsi_success_cont_stack := SuccessContStack,
|
|
!Info ^ mgi_sub_info := SubInfo.
|
|
ml_gen_info_set_closure_wrapper_defns(ClosureWrapperDefns, !Info) :-
|
|
SubInfo0 = !.Info ^ mgi_sub_info,
|
|
SubInfo = SubInfo0 ^ mgsi_closure_wrapper_defns := ClosureWrapperDefns,
|
|
!Info ^ mgi_sub_info := SubInfo.
|
|
ml_gen_info_set_env_var_names(EnvVarNames, !Info) :-
|
|
SubInfo0 = !.Info ^ mgi_sub_info,
|
|
SubInfo = SubInfo0 ^ mgsi_env_var_names := EnvVarNames,
|
|
!Info ^ mgi_sub_info := SubInfo.
|
|
|
|
ml_gen_info_get_module_name(Info, ModuleName) :-
|
|
ml_gen_info_get_module_info(Info, ModuleInfo),
|
|
module_info_get_name(ModuleInfo, ModuleName).
|
|
|
|
ml_gen_info_use_gcc_nested_functions(Info, UseNestedFuncs) :-
|
|
ml_gen_info_get_globals(Info, Globals),
|
|
globals.lookup_bool_option(Globals, gcc_nested_functions,
|
|
UseNestedFuncs).
|
|
|
|
ml_gen_info_put_commit_in_own_func(Info, PutCommitInNestedFunc) :-
|
|
ml_gen_info_get_globals(Info, Globals),
|
|
globals.lookup_bool_option(Globals, put_commit_in_own_func,
|
|
PutCommitInNestedFunc).
|
|
|
|
ml_gen_info_get_globals(Info, Globals) :-
|
|
ml_gen_info_get_module_info(Info, ModuleInfo),
|
|
module_info_get_globals(ModuleInfo, Globals).
|
|
|
|
ml_gen_info_new_func_label(Label, !Info) :-
|
|
ml_gen_info_get_func_counter(!.Info, Counter0),
|
|
counter.allocate(Label, Counter0, Counter),
|
|
ml_gen_info_set_func_counter(Counter, !Info).
|
|
|
|
ml_gen_info_new_label(Label, !Info) :-
|
|
ml_gen_info_get_label_counter(!.Info, Counter0),
|
|
counter.allocate(Label, Counter0, Counter),
|
|
ml_gen_info_set_label_counter(Counter, !Info).
|
|
|
|
ml_gen_info_bump_counters(!Info) :-
|
|
ml_gen_info_get_func_counter(!.Info, FuncLabelCounter0),
|
|
counter.allocate(FuncLabel, FuncLabelCounter0, _),
|
|
FuncLabelCounter = counter.init(FuncLabel + 10000),
|
|
ml_gen_info_set_func_counter(FuncLabelCounter, !Info).
|
|
|
|
ml_gen_info_new_aux_var_name(Prefix, VarName, !Info) :-
|
|
ml_gen_info_get_aux_var_counter(!.Info, AuxVarCounter0),
|
|
counter.allocate(AuxVarNum, AuxVarCounter0, AuxVarCounter),
|
|
ml_gen_info_set_aux_var_counter(AuxVarCounter, !Info),
|
|
|
|
Name = Prefix ++ "_" ++ string.int_to_string(AuxVarNum),
|
|
VarName = mlds_var_name(Name, no).
|
|
|
|
ml_gen_info_new_cond_var(cond_seq(CondNum), !Info) :-
|
|
ml_gen_info_get_cond_var_counter(!.Info, CondCounter0),
|
|
counter.allocate(CondNum, CondCounter0, CondCounter),
|
|
ml_gen_info_set_cond_var_counter(CondCounter, !Info).
|
|
|
|
ml_gen_info_new_conv_var(conv_seq(ConvNum), !Info) :-
|
|
ml_gen_info_get_conv_var_counter(!.Info, ConvCounter0),
|
|
counter.allocate(ConvNum, ConvCounter0, ConvCounter),
|
|
ml_gen_info_set_conv_var_counter(ConvCounter, !Info).
|
|
|
|
ml_gen_info_set_const_var(Var, GroundTerm, !Info) :-
|
|
ml_gen_info_get_const_var_map(!.Info, ConstVarMap0),
|
|
% We cannot call map.det_insert, because we do not (yet) clean up the
|
|
% const_var_map at the start of later branches of a branched goal,
|
|
% and thus when generating code for a later branch, we may come across
|
|
% an entry left by an earlier branch. Using map.set instead throws away
|
|
% such obsolete entries.
|
|
map.set(Var, GroundTerm, ConstVarMap0, ConstVarMap),
|
|
ml_gen_info_set_const_var_map(ConstVarMap, !Info).
|
|
|
|
ml_gen_info_lookup_const_var(Info, Var, GroundTerm) :-
|
|
ml_gen_info_get_const_var_map(Info, ConstVarMap),
|
|
map.lookup(ConstVarMap, Var, GroundTerm).
|
|
|
|
ml_gen_info_search_const_var(Info, Var, GroundTerm) :-
|
|
ml_gen_info_get_const_var_map(Info, ConstVarMap),
|
|
map.search(ConstVarMap, Var, GroundTerm).
|
|
|
|
ml_gen_info_push_success_cont(SuccCont, !Info) :-
|
|
ml_gen_info_get_success_cont_stack(!.Info, Stack0),
|
|
stack.push(Stack0, SuccCont, Stack),
|
|
ml_gen_info_set_success_cont_stack(Stack, !Info).
|
|
|
|
ml_gen_info_pop_success_cont(!Info) :-
|
|
ml_gen_info_get_success_cont_stack(!.Info, Stack0),
|
|
stack.det_pop(Stack0, _SuccCont, Stack),
|
|
ml_gen_info_set_success_cont_stack(Stack, !Info).
|
|
|
|
ml_gen_info_current_success_cont(Info, SuccCont) :-
|
|
ml_gen_info_get_success_cont_stack(Info, Stack),
|
|
stack.det_top(Stack, SuccCont).
|
|
|
|
ml_gen_info_set_var_lval(Var, Lval, !Info) :-
|
|
ml_gen_info_get_var_lvals(!.Info, VarLvals0),
|
|
map.set(Var, Lval, VarLvals0, VarLvals),
|
|
ml_gen_info_set_var_lvals(VarLvals, !Info).
|
|
|
|
ml_gen_info_add_closure_wrapper_defn(ClosureWrapperDefn, !Info) :-
|
|
ml_gen_info_get_closure_wrapper_defns(!.Info, ClosureWrapperDefns0),
|
|
ClosureWrapperDefns = [ClosureWrapperDefn | ClosureWrapperDefns0],
|
|
ml_gen_info_set_closure_wrapper_defns(ClosureWrapperDefns, !Info).
|
|
|
|
ml_gen_info_add_env_var_name(Name, !Info) :-
|
|
ml_gen_info_get_env_var_names(!.Info, EnvVarNames0),
|
|
set.insert(Name, EnvVarNames0, EnvVarNames),
|
|
ml_gen_info_set_env_var_names(EnvVarNames, !Info).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
:- end_module ml_gen_info.
|
|
%-----------------------------------------------------------------------------%
|