mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 09:23:44 +00:00
compiler/inst_lookup.m:
compiler/inst_mode_type_prop.m:
compiler/inst_test.m:
compiler/inst_util.m:
compiler/mode_util.m:
compiler/type_util.m:
Move these modules from the check_hlds package to the hlds package.
The reason is that all the content of five of these modules, and
most of the content of one module (inst_util.m) is not used
exclusively during semantic checking passes. (A later diff
should deal with the exception.) Some are used by the pass that
builds the initial HLDS, and all are used by middle-end and backend
passes. The move therefore reduces the number of inappropriate imports
of the check_hlds package.
compiler/check_hlds.m:
compiler/hlds.m:
Effect the transfer.
compiler/*.m:
Conform to the changes above.
803 lines
33 KiB
Mathematica
803 lines
33 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2014-2025 The Mercury team.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% File: simplify_info.m.
|
|
%
|
|
% This module defines the simplify_info type and its access predicates.
|
|
% This type contains information for use by the other submodules of simplify.m:
|
|
% both static information (such as identity of the procedure whose body is
|
|
% being simplified), and information specific to the current point in the
|
|
% simplification process (such as whether we have seen a parallel conjunction).
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module check_hlds.simplify.simplify_info.
|
|
:- interface.
|
|
|
|
:- import_module check_hlds.simplify.simplify_tasks.
|
|
:- import_module hlds.
|
|
:- import_module hlds.const_struct.
|
|
:- import_module hlds.hlds_module.
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module hlds.hlds_rtti.
|
|
:- import_module libs.
|
|
:- import_module libs.optimization_options.
|
|
:- import_module libs.trace_params.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.error_spec.
|
|
:- import_module parse_tree.prog_data.
|
|
:- import_module parse_tree.var_table.
|
|
|
|
:- import_module bool.
|
|
:- import_module io.
|
|
:- import_module list.
|
|
:- import_module maybe.
|
|
:- import_module set.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type innermost_proc
|
|
---> imp_whole_proc
|
|
% The innermost proc is the whole original procedure.
|
|
; imp_lambda(prog_context).
|
|
% The innermost proc is a lambda expression
|
|
% at the given source location, which a later compiler pass
|
|
% will transform into a separate procedure.
|
|
|
|
% A switch arm context records the fact that we are inside
|
|
% a switch on the given variable, and specifically, we are
|
|
% inside the arm of that switch that is for the given cons_ids.
|
|
:- type switch_arm
|
|
---> switch_arm(
|
|
prog_var,
|
|
set(cons_id)
|
|
).
|
|
|
|
:- type simplify_nested_context
|
|
---> simplify_nested_context(
|
|
% Are we currently inside a goal that was duplicated
|
|
% for a switch?
|
|
snc_inside_dupl_for_switch :: bool,
|
|
|
|
% Can the procedure we are inside be invoked from an
|
|
% all-solutions predicate?
|
|
% If we are inside one or more lambda expressions,
|
|
% the relevant procedure is the innermost lambda,
|
|
% which will later be transformed into a separate procedure.
|
|
% If yes, identify the procedure.
|
|
snc_proc_is_model_non :: maybe(innermost_proc),
|
|
|
|
% Count of the number of lambda goals that
|
|
%
|
|
% - we are inside,
|
|
% - that were not created to implement a try goal.
|
|
%
|
|
% The code of lambda expressions that are created
|
|
% to implement try goals are always executed in the
|
|
% call tree of the procedure in which they appear,
|
|
% but this is not true for lambda expressions in general;
|
|
% they are often returned to ancestors, which then
|
|
% execute them (or not) outside that call tree.
|
|
%
|
|
% If this field is zero, a call that has identical input
|
|
% arguments to the clause head *will* yield an infinite loop;
|
|
% if this field is greater than zero; it only *may* yield
|
|
% an infinite loop.
|
|
snc_num_enclosing_barriers :: uint,
|
|
|
|
% The list of switch arms we are inside. The outermost
|
|
% (and therefore largest, in terms of the amount of code
|
|
% inside it) switch arm will be at the tail end of the list,
|
|
% while the innermost switch arm will be at the head
|
|
% of the list.
|
|
snc_switch_arms :: list(switch_arm)
|
|
).
|
|
|
|
:- type maybe_allow_messages
|
|
---> do_not_allow_messages
|
|
; allow_messages.
|
|
|
|
:- type maybe_rerun_quant_instmap_deltas
|
|
---> do_not_rerun_quant_instmap_deltas
|
|
; rerun_quant_instmap_deltas.
|
|
|
|
:- type maybe_rerun_det
|
|
---> do_not_rerun_det
|
|
; rerun_det.
|
|
|
|
:- type maybe_rerun_simplify_no_warn_simple
|
|
---> do_not_rerun_simplify_no_warn_simple
|
|
; rerun_simplify_no_warn_simple.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type simplify_info.
|
|
|
|
% Initialise the simplify_info.
|
|
%
|
|
:- pred simplify_info_init(io.text_output_stream::in, module_info::in,
|
|
pred_id::in, proc_id::in, proc_info::in, simplify_tasks::in,
|
|
simplify_info::out) is det.
|
|
|
|
% Reinitialise the simplify_info before reprocessing a goal.
|
|
%
|
|
:- pred simplify_info_reinit(simplify_tasks::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Operations on simplify_infos.
|
|
%
|
|
|
|
:- pred simplify_info_get_pred_proc_info(simplify_info::in, pred_info::out,
|
|
proc_info::out) is det.
|
|
|
|
:- pred simplify_info_add_elim_vars(list(prog_var)::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
|
|
:- pred simplify_info_add_message(error_spec::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
|
|
:- pred simplify_info_incr_cost_delta(int::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
|
|
:- pred simplify_info_apply_substitutions_and_duplicate(prog_var::in,
|
|
prog_var::in, tsubst::in, simplify_info::in, simplify_info::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Getters and setters of fields of simplify_info.
|
|
%
|
|
|
|
:- type maybe_fully_strict
|
|
---> not_fully_strict
|
|
; fully_strict.
|
|
|
|
:- type maybe_trace_optimized
|
|
---> not_trace_optimized
|
|
; trace_optimized.
|
|
|
|
:- type maybe_ignore_marked_static
|
|
---> do_not_ignore_marked_static
|
|
; ignore_marked_static.
|
|
|
|
:- pred simplify_info_get_simplify_tasks(simplify_info::in,
|
|
simplify_tasks::out) is det.
|
|
:- pred simplify_info_get_module_info(simplify_info::in, module_info::out)
|
|
is det.
|
|
:- pred simplify_info_get_var_table(simplify_info::in, var_table::out) is det.
|
|
:- pred simplify_info_get_rerun_quant_instmap_delta(simplify_info::in,
|
|
maybe_rerun_quant_instmap_deltas::out) is det.
|
|
:- pred simplify_info_get_rerun_det(simplify_info::in,
|
|
maybe_rerun_det::out) is det.
|
|
|
|
:- pred simplify_info_get_progress_stream(simplify_info::in,
|
|
io.text_output_stream::out) is det.
|
|
:- pred simplify_info_get_pred_proc_id(simplify_info::in,
|
|
pred_proc_id::out) is det.
|
|
:- pred simplify_info_get_tvarset(simplify_info::in,
|
|
tvarset::out) is det.
|
|
:- pred simplify_info_get_inst_varset(simplify_info::in,
|
|
inst_varset::out) is det.
|
|
:- pred simplify_info_get_fully_strict(simplify_info::in,
|
|
maybe_fully_strict::out) is det.
|
|
:- pred simplify_info_get_eff_trace_level_optimized(simplify_info::in,
|
|
eff_trace_level::out, maybe_trace_optimized::out) is det.
|
|
:- pred simplify_info_get_ignore_marked_static(simplify_info::in,
|
|
maybe_ignore_marked_static::out) is det.
|
|
|
|
:- pred simplify_info_get_rtti_varmaps(simplify_info::in, rtti_varmaps::out)
|
|
is det.
|
|
:- pred simplify_info_get_elim_vars(simplify_info::in,
|
|
list(list(prog_var))::out) is det.
|
|
:- pred simplify_info_get_allow_messages(simplify_info::in,
|
|
maybe_allow_messages::out) is det.
|
|
:- pred simplify_info_get_error_specs(simplify_info::in, list(error_spec)::out)
|
|
is det.
|
|
:- pred simplify_info_get_cost_delta(simplify_info::in, int::out) is det.
|
|
:- pred simplify_info_get_has_parallel_conj(simplify_info::in,
|
|
has_parallel_conj::out) is det.
|
|
:- pred simplify_info_get_found_contains_trace(simplify_info::in, bool::out)
|
|
is det.
|
|
:- pred simplify_info_get_has_user_event(simplify_info::in,
|
|
has_user_event::out) is det.
|
|
:- pred simplify_info_get_deleted_call_callees(simplify_info::in,
|
|
set(pred_proc_id)::out) is det.
|
|
:- pred simplify_info_get_switch_arms_to_split(simplify_info::in,
|
|
set(switch_arm)::out) is det.
|
|
:- pred simplify_info_get_defined_where(simplify_info::in,
|
|
defined_where::out) is det.
|
|
:- pred simplify_info_get_rerun_simplify_no_warn_simple(simplify_info::in,
|
|
maybe_rerun_simplify_no_warn_simple::out) is det.
|
|
|
|
:- pred simplify_info_set_simplify_tasks(simplify_tasks::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_module_info(module_info::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_var_table(var_table::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_rerun_quant_instmap_delta(
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_rerun_det(
|
|
simplify_info::in, simplify_info::out) is det.
|
|
|
|
:- pred simplify_info_set_rtti_varmaps(rtti_varmaps::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_elim_vars(list(list(prog_var))::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_allow_messages(maybe_allow_messages::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_error_specs(list(error_spec)::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_cost_delta(int::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_has_parallel_conj(has_parallel_conj::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_found_contains_trace(bool::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_has_user_event(has_user_event::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_deleted_call_callees(set(pred_proc_id)::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_switch_arms_to_split(set(switch_arm)::in,
|
|
simplify_info::in, simplify_info::out) is det.
|
|
:- pred simplify_info_set_rerun_simplify_no_warn_simple(
|
|
simplify_info::in, simplify_info::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred simplify_do_warn_dodgy_simple_code(simplify_info::in) is semidet.
|
|
:- pred simplify_do_warn_duplicate_calls(simplify_info::in) is semidet.
|
|
:- pred simplify_do_warn_implicit_stream_calls(simplify_info::in) is semidet.
|
|
:- pred simplify_do_format_calls(simplify_info::in) is semidet.
|
|
:- pred simplify_do_warn_obsolete(simplify_info::in) is semidet.
|
|
:- pred simplify_do_mark_code_model_changes(simplify_info::in) is semidet.
|
|
:- pred simplify_do_after_front_end(simplify_info::in) is semidet.
|
|
:- pred simplify_do_excess_assign(simplify_info::in) is semidet.
|
|
:- pred simplify_do_merge_code_after_switch(simplify_info::in) is semidet.
|
|
:- pred simplify_do_elim_removable_scopes(simplify_info::in) is semidet.
|
|
:- pred simplify_do_opt_duplicate_calls(simplify_info::in) is semidet.
|
|
:- pred simplify_do_const_prop(simplify_info::in) is semidet.
|
|
:- pred simplify_do_ignore_par_conjunctions(simplify_info::in) is semidet.
|
|
:- pred simplify_do_warn_suspicious_recursion(simplify_info::in) is semidet.
|
|
:- pred simplify_do_warn_no_solution_disjunct(simplify_info::in) is semidet.
|
|
|
|
% Succeed if either warn_duplicate_calls or opt_duplicate_calls is set,
|
|
% and return whether opt_duplicate_calls is set.
|
|
%
|
|
:- pred simplify_do_warn_or_opt_duplicate_calls(simplify_info::in,
|
|
maybe_opt_dup_calls::out) is semidet.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module hlds.status.
|
|
:- import_module hlds.type_util.
|
|
:- import_module libs.globals.
|
|
:- import_module libs.options.
|
|
|
|
:- import_module int.
|
|
:- import_module map.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% The information we need while we traverse the body of a procedure,
|
|
% simplifying it.
|
|
%
|
|
% The simplify_info, simplify_sub_info and simplify_info_params types
|
|
% constitute a single logical data structure split into three parts
|
|
% for efficiency purposes.
|
|
%
|
|
% The simplify_info type contains the most frequently used writeable
|
|
% fields. The other writeable fields are in the simplify_sub_info,
|
|
% while all the readonly fields are in the simplify_info_params.
|
|
|
|
:- type simplify_info
|
|
---> simplify_info(
|
|
% The Boehm collector allocates blocks whose sizes are
|
|
% multiples of 2, so we should keep the number of fields
|
|
% in a simplify_info to be a multiple of 2 as well.
|
|
|
|
% The tasks we do in this invocation of simplification.
|
|
/* 1 */ simp_simplify_tasks :: simplify_tasks,
|
|
|
|
% The whole module. Those parts of it that are also contained
|
|
% in other fields of simplify_info and simplify_sub_info
|
|
% may be out of date in the module_info.
|
|
/* 2 */ simp_module_info :: module_info,
|
|
|
|
% The variables of the procedure being simplified.
|
|
/* 3 */ simp_var_table :: var_table,
|
|
|
|
% Does the goal need requantification, and the recomputation
|
|
% of instmap_deltas?
|
|
/* 4 */ simp_rerun_quant_instmap_delta
|
|
:: maybe_rerun_quant_instmap_deltas,
|
|
|
|
% Does determinism analysis need to be rerun?
|
|
/* 5 */ simp_rerun_det :: maybe_rerun_det,
|
|
|
|
/* 6 */ simp_params :: simplify_info_params,
|
|
/* 7 */ simp_sub_info :: simplify_sub_info
|
|
).
|
|
|
|
:- type simplify_info_params
|
|
---> simplify_info_params(
|
|
% The id of the stream to which any trace goals should write.
|
|
sip_progress_stream :: io.text_output_stream,
|
|
|
|
% The id of the procedure we are simplifying, and two
|
|
% fields of its pred_info and proc_info that we need
|
|
% but never change.
|
|
sip_pred_proc_id :: pred_proc_id,
|
|
sip_tvarset :: tvarset,
|
|
sip_inst_varset :: inst_varset,
|
|
|
|
% The value of the --fully-strict option.
|
|
sip_fully_strict :: maybe_fully_strict,
|
|
|
|
sip_eff_trace_level :: eff_trace_level,
|
|
|
|
% The value of the --trace-optimized option.
|
|
sip_trace_optimized :: maybe_trace_optimized,
|
|
|
|
sip_ignore_marked_static :: maybe_ignore_marked_static
|
|
).
|
|
|
|
:- type simplify_sub_info
|
|
---> simplify_sub_info(
|
|
% Information about the typeinfo and typeclass info vars
|
|
% for the type variables of the procedure being simplified.
|
|
% Logically, this field belongs next to simp_var_table,
|
|
% but it is not used frequently enough to store at the
|
|
% top level of simplify_info.
|
|
ssimp_rtti_varmaps :: rtti_varmaps,
|
|
|
|
% The variables we have eliminated. Each list of vars consists
|
|
% of a list of consecutive variable numbers in ascending order.
|
|
% The relative order of the lists is unknown.
|
|
ssimp_elim_vars :: list(list(prog_var)),
|
|
|
|
ssimp_error_specs :: list(error_spec),
|
|
|
|
% Measure of the improvement in the goal from simplification.
|
|
ssimp_cost_delta :: int,
|
|
|
|
% Are we allowed to generate error, warning and/or
|
|
% informational message for the user?
|
|
%
|
|
% The default value of this field is allow_messages,
|
|
% but it is set to do_not_allow_messages during the second pass
|
|
% of simplification. See the comment in simplify_proc.m
|
|
% next to the call to simplify_info_set_allow_messages
|
|
% for the reason why.
|
|
ssimp_allow_messages :: maybe_allow_messages,
|
|
|
|
% Have we seen a parallel conjunction?
|
|
ssimp_has_parallel_conj :: has_parallel_conj,
|
|
|
|
% Have we seen a goal with a feature that says it contains
|
|
% a trace goal?
|
|
ssimp_found_contains_trace :: bool,
|
|
|
|
% Have we seen an event call?
|
|
ssimp_has_user_event :: has_user_event,
|
|
|
|
% The set of predicates that we deleted calls to while
|
|
% simplifying the procedure body.
|
|
ssimp_deleted_call_callees :: set(pred_proc_id),
|
|
|
|
% The set of outermost switch arm contexts within which
|
|
% there is at least one *other* switch on the same variable.
|
|
% (We collect only the *outermost* switch arms, because when
|
|
% the transformation in split_switch_arms.m processes a switch
|
|
% arm, it also implicitly processes all switches on that
|
|
% same variable inside the code of that arm.)
|
|
ssimp_switch_arms_to_split :: set(switch_arm),
|
|
|
|
% Is the predicate we are simplifying defined in this module?
|
|
ssimp_defined_where :: defined_where,
|
|
|
|
ssimp_rerun_simplify ::
|
|
maybe_rerun_simplify_no_warn_simple
|
|
).
|
|
|
|
simplify_info_init(ProgressStream, ModuleInfo, PredId, ProcId, ProcInfo,
|
|
SimplifyTasks, Info) :-
|
|
PredProcId = proc(PredId, ProcId),
|
|
proc_info_get_inst_varset(ProcInfo, InstVarSet),
|
|
module_info_get_globals(ModuleInfo, Globals),
|
|
globals.lookup_bool_option(Globals, fully_strict, FullyStrict0),
|
|
( FullyStrict0 = no, FullyStrict = not_fully_strict
|
|
; FullyStrict0 = yes, FullyStrict = fully_strict
|
|
),
|
|
globals.get_trace_level(Globals, TraceLevel),
|
|
module_info_pred_info(ModuleInfo, PredId, PredInfo),
|
|
pred_info_get_typevarset(PredInfo, TVarSet),
|
|
EffTraceLevel =
|
|
eff_trace_level_for_proc(ModuleInfo, PredInfo, ProcInfo, TraceLevel),
|
|
globals.lookup_bool_option(Globals, trace_optimized, TraceOptimized0),
|
|
( TraceOptimized0 = no, TraceOptimized = not_trace_optimized
|
|
; TraceOptimized0 = yes, TraceOptimized = trace_optimized
|
|
),
|
|
Backend = lookup_current_backend(Globals),
|
|
(
|
|
Backend = low_level_backend,
|
|
IgnoreMarkedStatic = ignore_marked_static
|
|
;
|
|
Backend = high_level_backend,
|
|
IgnoreMarkedStatic = do_not_ignore_marked_static
|
|
),
|
|
|
|
Params = simplify_info_params(ProgressStream, PredProcId,
|
|
TVarSet, InstVarSet, FullyStrict, EffTraceLevel,
|
|
TraceOptimized, IgnoreMarkedStatic),
|
|
|
|
proc_info_get_rtti_varmaps(ProcInfo, RttiVarMaps),
|
|
ElimVars = [],
|
|
AllowMsgs = allow_messages,
|
|
Specs = [],
|
|
CostDelta = 0,
|
|
HasParallelConj = has_no_parallel_conj,
|
|
FoundContainsTrace = no,
|
|
HasUserEvent = has_no_user_event,
|
|
set.init(TraceGoalProcs),
|
|
set.init(SwitchArmsToSplit),
|
|
pred_info_get_status(PredInfo, PredStatus),
|
|
pred_status_defined_in_this_module(PredStatus) = InThisModule,
|
|
( InThisModule = yes, DefinedWhere = defined_in_this_module
|
|
; InThisModule = no, DefinedWhere = defined_in_other_module
|
|
),
|
|
RerunSimplify = do_not_rerun_simplify_no_warn_simple,
|
|
|
|
SubInfo = simplify_sub_info(RttiVarMaps, ElimVars, Specs, CostDelta,
|
|
AllowMsgs, HasParallelConj, FoundContainsTrace, HasUserEvent,
|
|
TraceGoalProcs, SwitchArmsToSplit, DefinedWhere, RerunSimplify),
|
|
|
|
% SimplifyTasks
|
|
% ModuleInfo
|
|
proc_info_get_var_table(ProcInfo, VarTable),
|
|
RerunQuant = do_not_rerun_quant_instmap_deltas,
|
|
RerunDet = do_not_rerun_det,
|
|
|
|
Info = simplify_info(SimplifyTasks, ModuleInfo, VarTable,
|
|
RerunQuant, RerunDet, Params, SubInfo).
|
|
|
|
simplify_info_reinit(SimplifyTasks, !Info) :-
|
|
!Info ^ simp_simplify_tasks := SimplifyTasks,
|
|
!Info ^ simp_rerun_quant_instmap_delta
|
|
:= do_not_rerun_quant_instmap_deltas,
|
|
!Info ^ simp_rerun_det := do_not_rerun_det,
|
|
!Info ^ simp_sub_info ^ ssimp_has_parallel_conj := has_no_parallel_conj,
|
|
!Info ^ simp_sub_info ^ ssimp_has_user_event := has_no_user_event.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
simplify_info_get_pred_proc_info(Info, PredInfo, ProcInfo) :-
|
|
simplify_info_get_module_info(Info, ModuleInfo),
|
|
simplify_info_get_pred_proc_id(Info, PredProcId),
|
|
module_info_pred_proc_info(ModuleInfo, PredProcId, PredInfo, ProcInfo).
|
|
|
|
simplify_info_add_elim_vars(ElimVars, !Info) :-
|
|
simplify_info_get_elim_vars(!.Info, ElimVarsLists0),
|
|
ElimVarsLists = [ElimVars | ElimVarsLists0],
|
|
simplify_info_set_elim_vars(ElimVarsLists, !Info).
|
|
|
|
simplify_info_add_message(Spec, !Info) :-
|
|
simplify_info_get_allow_messages(!.Info, AllowMsgs),
|
|
(
|
|
AllowMsgs = do_not_allow_messages
|
|
;
|
|
AllowMsgs = allow_messages,
|
|
simplify_info_get_error_specs(!.Info, Specs0),
|
|
Specs = [Spec | Specs0],
|
|
simplify_info_set_error_specs(Specs, !Info)
|
|
).
|
|
|
|
simplify_info_incr_cost_delta(Incr, !Info) :-
|
|
simplify_info_get_cost_delta(!.Info, CostDelta0),
|
|
CostDelta = CostDelta0 + Incr,
|
|
simplify_info_set_cost_delta(CostDelta, !Info).
|
|
|
|
simplify_info_apply_substitutions_and_duplicate(ToVar, FromVar, TSubst,
|
|
!Info) :-
|
|
simplify_info_get_module_info(!.Info, ModuleInfo),
|
|
simplify_info_get_var_table(!.Info, VarTable0),
|
|
simplify_info_get_rtti_varmaps(!.Info, RttiVarMaps0),
|
|
apply_rec_subst_to_var_table(is_type_a_dummy(ModuleInfo), TSubst,
|
|
VarTable0, VarTable),
|
|
Renaming = map.singleton(ToVar, FromVar),
|
|
apply_substitutions_to_rtti_varmaps(map.init, TSubst, Renaming,
|
|
RttiVarMaps0, RttiVarMaps1),
|
|
rtti_var_info_duplicate(FromVar, ToVar, RttiVarMaps1, RttiVarMaps),
|
|
simplify_info_set_var_table(VarTable, !Info),
|
|
simplify_info_set_rtti_varmaps(RttiVarMaps, !Info).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
simplify_info_get_simplify_tasks(Info, X) :-
|
|
X = Info ^ simp_simplify_tasks.
|
|
simplify_info_get_module_info(Info, X) :-
|
|
X = Info ^ simp_module_info.
|
|
simplify_info_get_var_table(Info, X) :-
|
|
X = Info ^ simp_var_table.
|
|
simplify_info_get_rerun_quant_instmap_delta(Info, X) :-
|
|
X = Info ^ simp_rerun_quant_instmap_delta.
|
|
simplify_info_get_rerun_det(Info, X) :-
|
|
X = Info ^ simp_rerun_det.
|
|
|
|
simplify_info_get_progress_stream(Info, X) :-
|
|
X = Info ^ simp_params ^ sip_progress_stream.
|
|
simplify_info_get_pred_proc_id(Info, X) :-
|
|
X = Info ^ simp_params ^ sip_pred_proc_id.
|
|
simplify_info_get_tvarset(Info, X) :-
|
|
X = Info ^ simp_params ^ sip_tvarset.
|
|
simplify_info_get_inst_varset(Info, X) :-
|
|
X = Info ^ simp_params ^ sip_inst_varset.
|
|
simplify_info_get_fully_strict(Info, X) :-
|
|
X = Info ^ simp_params ^ sip_fully_strict.
|
|
simplify_info_get_eff_trace_level_optimized(Info, X, Y) :-
|
|
X = Info ^ simp_params ^ sip_eff_trace_level,
|
|
Y = Info ^ simp_params ^ sip_trace_optimized.
|
|
simplify_info_get_ignore_marked_static(Info, X) :-
|
|
X = Info ^ simp_params ^ sip_ignore_marked_static.
|
|
|
|
simplify_info_get_rtti_varmaps(Info, X) :-
|
|
X = Info ^ simp_sub_info ^ ssimp_rtti_varmaps.
|
|
simplify_info_get_elim_vars(Info, X) :-
|
|
X = Info ^ simp_sub_info ^ ssimp_elim_vars.
|
|
simplify_info_get_allow_messages(Info, X) :-
|
|
X = Info ^ simp_sub_info ^ ssimp_allow_messages.
|
|
simplify_info_get_error_specs(Info, X) :-
|
|
X = Info ^ simp_sub_info ^ ssimp_error_specs.
|
|
simplify_info_get_cost_delta(Info, X) :-
|
|
X = Info ^ simp_sub_info ^ ssimp_cost_delta.
|
|
simplify_info_get_has_parallel_conj(Info, X) :-
|
|
X = Info ^ simp_sub_info ^ ssimp_has_parallel_conj.
|
|
simplify_info_get_found_contains_trace(Info, X) :-
|
|
X = Info ^ simp_sub_info ^ ssimp_found_contains_trace.
|
|
simplify_info_get_has_user_event(Info, X) :-
|
|
X = Info ^ simp_sub_info ^ ssimp_has_user_event.
|
|
simplify_info_get_deleted_call_callees(Info, X) :-
|
|
X = Info ^ simp_sub_info ^ ssimp_deleted_call_callees.
|
|
simplify_info_get_switch_arms_to_split(Info, X) :-
|
|
X = Info ^ simp_sub_info ^ ssimp_switch_arms_to_split.
|
|
simplify_info_get_defined_where(Info, X) :-
|
|
X = Info ^ simp_sub_info ^ ssimp_defined_where.
|
|
simplify_info_get_rerun_simplify_no_warn_simple(Info, X) :-
|
|
X = Info ^ simp_sub_info ^ ssimp_rerun_simplify.
|
|
|
|
%---------------------%
|
|
|
|
simplify_info_set_simplify_tasks(X, !Info) :-
|
|
!Info ^ simp_simplify_tasks := X.
|
|
simplify_info_set_module_info(X, !Info) :-
|
|
( if private_builtin.pointer_equal(X, !.Info ^ simp_module_info) then
|
|
true
|
|
else
|
|
!Info ^ simp_module_info := X
|
|
).
|
|
simplify_info_set_var_table(X, !Info) :-
|
|
( if private_builtin.pointer_equal(X, !.Info ^ simp_var_table) then
|
|
true
|
|
else
|
|
!Info ^ simp_var_table := X
|
|
).
|
|
simplify_info_set_rerun_quant_instmap_delta(!Info) :-
|
|
X = rerun_quant_instmap_deltas,
|
|
( if X = !.Info ^ simp_rerun_quant_instmap_delta then
|
|
true
|
|
else
|
|
!Info ^ simp_rerun_quant_instmap_delta := X
|
|
).
|
|
simplify_info_set_rerun_det(!Info) :-
|
|
X = rerun_det,
|
|
( if X = !.Info ^ simp_rerun_det then
|
|
true
|
|
else
|
|
!Info ^ simp_rerun_det := X
|
|
).
|
|
|
|
simplify_info_set_rtti_varmaps(X, !Info) :-
|
|
( if
|
|
private_builtin.pointer_equal(X,
|
|
!.Info ^ simp_sub_info ^ ssimp_rtti_varmaps)
|
|
then
|
|
true
|
|
else
|
|
!Info ^ simp_sub_info ^ ssimp_rtti_varmaps := X
|
|
).
|
|
simplify_info_set_elim_vars(X, !Info) :-
|
|
!Info ^ simp_sub_info ^ ssimp_elim_vars := X.
|
|
simplify_info_set_allow_messages(X, !Info) :-
|
|
!Info ^ simp_sub_info ^ ssimp_allow_messages := X.
|
|
simplify_info_set_error_specs(X, !Info) :-
|
|
!Info ^ simp_sub_info ^ ssimp_error_specs := X.
|
|
simplify_info_set_cost_delta(X, !Info) :-
|
|
( if X = !.Info ^ simp_sub_info ^ ssimp_cost_delta then
|
|
true
|
|
else
|
|
!Info ^ simp_sub_info ^ ssimp_cost_delta := X
|
|
).
|
|
simplify_info_set_has_parallel_conj(X, !Info) :-
|
|
( if X = !.Info ^ simp_sub_info ^ ssimp_has_parallel_conj then
|
|
true
|
|
else
|
|
!Info ^ simp_sub_info ^ ssimp_has_parallel_conj := X
|
|
).
|
|
simplify_info_set_found_contains_trace(X, !Info) :-
|
|
( if X = !.Info ^ simp_sub_info ^ ssimp_found_contains_trace then
|
|
true
|
|
else
|
|
!Info ^ simp_sub_info ^ ssimp_found_contains_trace := X
|
|
).
|
|
simplify_info_set_has_user_event(X, !Info) :-
|
|
( if X = !.Info ^ simp_sub_info ^ ssimp_has_user_event then
|
|
true
|
|
else
|
|
!Info ^ simp_sub_info ^ ssimp_has_user_event := X
|
|
).
|
|
simplify_info_set_deleted_call_callees(X, !Info) :-
|
|
( if
|
|
private_builtin.pointer_equal(X,
|
|
!.Info ^ simp_sub_info ^ ssimp_deleted_call_callees)
|
|
then
|
|
true
|
|
else
|
|
!Info ^ simp_sub_info ^ ssimp_deleted_call_callees := X
|
|
).
|
|
simplify_info_set_switch_arms_to_split(X, !Info) :-
|
|
!Info ^ simp_sub_info ^ ssimp_switch_arms_to_split := X.
|
|
simplify_info_set_rerun_simplify_no_warn_simple(!Info) :-
|
|
X = rerun_simplify_no_warn_simple,
|
|
!Info ^ simp_sub_info ^ ssimp_rerun_simplify := X.
|
|
|
|
% Access stats for the det_info structure, derived on 2017 march 8
|
|
% using the commented-out code below:
|
|
%
|
|
% i read same diff same%
|
|
% 0 54320730 0 428653 0.00% simplify_tasks
|
|
% 1 22537405 10190586 39961 99.61% module_info
|
|
% 2 1164463 29082 87284 24.99% varset
|
|
% 3 11655215 103357 14630 87.60% vartypes
|
|
% 4 593952 34444 81741 29.65% rtti_varmaps
|
|
% 5 144530 0 0 fully_strict
|
|
% 6 1268871 0 0 pred_id, proc_id
|
|
% 7 25167 0 0 inst_varset
|
|
% 8 431612 0 4700 0.00% elim_vars
|
|
% 9 8132 0 428653 0.00% allow_messages
|
|
% 10 431084 0 4172 0.00% error_specs
|
|
% 11 858622 41608 25167 62.31% requantify
|
|
% 12 858622 531 1606 24.85% rerun_det
|
|
% 13 148274 83477 61740 57.48% cost_delta
|
|
% 14 426912 52 170 23.42% has_parallel_conj
|
|
% 15 429969 8066 887 90.09% found_contains_trace
|
|
% 16 426912 16 36 30.77% has_user_event
|
|
% 17 484085 56008 1165 97.96% deleted_call_callees
|
|
%
|
|
% :- pragma foreign_decl("C", local,
|
|
% "
|
|
% #define MR_NUM_INFO_STATS 18
|
|
% unsigned long MR_stats_read[MR_NUM_INFO_STATS];
|
|
% unsigned long MR_stats_same[MR_NUM_INFO_STATS];
|
|
% unsigned long MR_stats_diff[MR_NUM_INFO_STATS];
|
|
% ").
|
|
%
|
|
% :- pred gather_info_read_stats(int::in,
|
|
% T::in, T::out) is det.
|
|
%
|
|
% :- pragma foreign_proc("C",
|
|
% gather_info_read_stats(N::in, X0::in, X::out),
|
|
% [will_not_call_mercury, promise_pure],
|
|
% "
|
|
% ++MR_stats_read[N];
|
|
% X = X0;
|
|
% ").
|
|
%
|
|
% :- pred gather_info_write_stats(int::in, T::in, T::in,
|
|
% simplify_info::in, simplify_info::out) is det.
|
|
%
|
|
% :- pragma foreign_proc("C",
|
|
% gather_info_write_stats(N::in, Old::in, New::in, Info0::in, Info::out),
|
|
% [will_not_call_mercury, promise_pure],
|
|
% "
|
|
% if (((MR_Unsigned) Old) == ((MR_Unsigned) New)) {
|
|
% ++MR_stats_same[N];
|
|
% } else {
|
|
% ++MR_stats_diff[N];
|
|
% }
|
|
%
|
|
% Info = Info0;
|
|
% ").
|
|
%
|
|
% :- interface.
|
|
% :- import_module io.
|
|
% :- pred write_simplify_info_stats(io::di, io::uo) is det.
|
|
% :- implementation.
|
|
%
|
|
% :- pragma foreign_proc("C",
|
|
% write_simplify_info_stats(IO0::di, IO::uo),
|
|
% [will_not_call_mercury, promise_pure],
|
|
% "
|
|
% FILE *fp;
|
|
%
|
|
% fp = fopen(""/tmp/SIMPLIFY_INFO_STATS"", ""a"");
|
|
% if (fp != NULL) {
|
|
% int i;
|
|
% for (i = 0; i < MR_NUM_INFO_STATS; i++) {
|
|
% fprintf(fp, ""stat_rsd %d %lu %lu %lu\\n"",
|
|
% i, MR_stats_read[i], MR_stats_same[i], MR_stats_diff[i]);
|
|
% }
|
|
% }
|
|
%
|
|
% IO = IO0;
|
|
% ").
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
simplify_do_warn_dodgy_simple_code(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_warn_dodgy_simple_code = warn_dodgy_simple_code.
|
|
simplify_do_warn_duplicate_calls(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_warn_duplicate_calls = warn_duplicate_calls.
|
|
simplify_do_warn_implicit_stream_calls(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_warn_implicit_streams = warn_implicit_streams.
|
|
simplify_do_format_calls(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_invoke_format_call = invoke_format_call.
|
|
simplify_do_warn_obsolete(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_warn_obsolete = warn_obsolete.
|
|
simplify_do_mark_code_model_changes(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_mark_code_model_changes = mark_code_model_changes.
|
|
simplify_do_after_front_end(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_after_front_end = after_front_end.
|
|
simplify_do_excess_assign(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_excess_assign = elim_excess_assigns.
|
|
simplify_do_merge_code_after_switch(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_merge_code_after_switch = merge_code_after_switch.
|
|
simplify_do_elim_removable_scopes(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_elim_removable_scopes = elim_removable_scopes.
|
|
simplify_do_opt_duplicate_calls(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_opt_duplicate_calls = opt_dup_calls.
|
|
simplify_do_const_prop(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_constant_prop = prop_constants.
|
|
simplify_do_ignore_par_conjunctions(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_ignore_par_conjunctions = ignore_par_conjs.
|
|
simplify_do_warn_suspicious_recursion(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_warn_suspicious_recursion = warn_suspicious_rec.
|
|
simplify_do_warn_no_solution_disjunct(Info) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
SimplifyTasks ^ do_warn_no_solution_disjunct = warn_no_soln_disjunct.
|
|
|
|
simplify_do_warn_or_opt_duplicate_calls(Info, OptDuplicateCalls) :-
|
|
simplify_info_get_simplify_tasks(Info, SimplifyTasks),
|
|
WarnDuplicateCalls = SimplifyTasks ^ do_warn_duplicate_calls,
|
|
OptDuplicateCalls = SimplifyTasks ^ do_opt_duplicate_calls,
|
|
( WarnDuplicateCalls = warn_duplicate_calls
|
|
; OptDuplicateCalls = opt_dup_calls
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module check_hlds.simplify.simplify_info.
|
|
%---------------------------------------------------------------------------%
|