mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-15 22:03:26 +00:00
compiler/hlds_module.m:
Put related fields of the module_sub_info next to each other.
Some of those fields contained lists that were built reversed,
in order to avoid O(N^2) behavior when repeatedly adding new items
to the end of the list. Replace these with cords, which did not exist
when those fields were first added.
Give some fields and their getter/setter predicates more descriptive
names.
Separate out both the declarations and definitions of the getter and
setter predicates, and put them into the same order as the (updated)
order of the fields. Put the utility predicates (those that are more
complicated than just getters or setters) into an order based on
what fields they work on, following the same order.
Improve the operation of some of the utility predicates, e.g. replacing
a nondet predicate with a det predicate returning a set.
Delete an unused type.
Conform to the changes in the modules imported by hlds_module.m,
e.g. pred_table.m, prog_data.m and prog_foreign.m.
compiler/pred_table.m:
We used to store the set of valid pred ids as two lists, again to avoid
O(N^2) behavior. Replace the two lists with a set. This allows
looking up the set *without* updating the pred_table, or, when
the pred_table is within the module_info, updating the module_info.
Instead of allowing callers to replace the set of valid pred ids wholesale,
enforce the documented invariant on that set by only allowing deletions.
Conform to the changes above.
compiler/add_pragma.m:
compiler/bytecode_gen.m:
compiler/check_typeclass.m:
compiler/compile_target_code.m:
compiler/cse_detection.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/dep_par_conj.m:
compiler/dependency_graph.m:
compiler/deps_map.m:
compiler/det_analysis.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/erl_code_gen.m:
compiler/exception_analysis.m:
compiler/export.m:
compiler/float_regs.m:
compiler/foreign.m:
compiler/higher_order.m:
compiler/hlds_module.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/introduce_parallelism.m:
compiler/lambda.m:
compiler/liveness.m:
Conform to the changes above.
In many places, the change to how the valid pred ids are stored
allows us to avoid creating new module_infos.
In some places, fix style issues I noticed while working on the above.
compiler/llds.m:
compiler/mercury_compile_llds_back_end.m:
Conform to the changes above.
Move a type from llds.m to mercury_compile_llds_back_end.m, since
only the latter uses it.
compiler/prog_data.m:
compiler/prog_foreign.m:
Replace some types that used to hold reversed lists with cords.
In prog_foreign.m, represent the two kinds of foreign code that
do NOT define procedures with similarly named types.
Delete a type (user_foreign_code) that duplicated another type.
Replace an equivalence type with a notag type, for safety.
compiler/recompilation.usage.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
Now that we have direct access to the set of visible modules,
simplify the logic of some code dealing with those modules.
compiler/module_imports.m:
Put some related fields next to each other.
compiler/llds_out_file.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_passes.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_middle_passes.m:
compiler/ml_proc_gen.m:
compiler/mlds.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
compiler/mode_constraints.m:
compiler/modes.m:
compiler/modules.m:
compiler/passes_aux.m:
compiler/polymorphism.m:
compiler/post_typecheck.m:
compiler/pred_table.m:
compiler/proc_gen.m:
compiler/prog_item.m:
compiler/purity.m:
compiler/rbmm.condition_renaming.m:
compiler/rbmm.execution_path.m:
compiler/rbmm.live_region_analysis.m:
compiler/rbmm.live_variable_analysis.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.region_arguments.m:
compiler/rbmm.region_instruction.m:
compiler/ssdebug.m:
compiler/stm_expand.m:
compiler/stratify.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.m:
compiler/structure_reuse.domain.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/switch_detection.m:
compiler/tabling_analysis.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/termination.m:
compiler/trailing_analysis.m:
compiler/trans_opt.m:
compiler/try_expand.m:
compiler/type_constraints.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/write_deps_file.m:
236 lines
9.8 KiB
Mathematica
236 lines
9.8 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 2005-2007, 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 rbmm.live_region_analysis.m.
|
|
% Main author: Quan Phan.
|
|
%
|
|
% This module implements the live region analysis, which uses execution paths
|
|
% with live variables to collect live regions at each program point.
|
|
%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module transform_hlds.rbmm.live_region_analysis.
|
|
:- interface.
|
|
|
|
:- import_module hlds.
|
|
:- import_module hlds.hlds_module.
|
|
:- import_module transform_hlds.rbmm.points_to_info.
|
|
:- import_module transform_hlds.rbmm.region_liveness_info.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Collects live region sets.
|
|
%
|
|
:- pred live_region_analysis(module_info::in, rpta_info_table::in,
|
|
proc_pp_varset_table::in, proc_pp_varset_table::in,
|
|
proc_pp_varset_table::in, proc_pp_region_set_table::out,
|
|
proc_pp_region_set_table::out, proc_pp_region_set_table::out,
|
|
proc_region_set_table::out, proc_region_set_table::out,
|
|
proc_region_set_table::out, proc_region_set_table::out,
|
|
proc_region_set_table::out) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.prog_data.
|
|
:- import_module transform_hlds.rbmm.points_to_graph.
|
|
:- import_module transform_hlds.smm_common.
|
|
|
|
:- import_module list.
|
|
:- import_module map.
|
|
:- import_module require.
|
|
:- import_module set.
|
|
:- import_module term.
|
|
|
|
%----------------------------------------------------------------------------%
|
|
%
|
|
% Live region analysis
|
|
%
|
|
|
|
% Compute for each procedure live region sets before and after all program
|
|
% points. As in live variable analysis we calculated the set of void
|
|
% variables after a program point, this analysis also computes the set of
|
|
% regions of those variables.
|
|
%
|
|
% Apart from that, it is convenient to also compute the inputR, outputR,
|
|
% localR, and the initial bornR and deadR for each procedure in this
|
|
% analysis.
|
|
%
|
|
|
|
live_region_analysis(ModuleInfo, RptaInfoTable, LVBeforeTable, LVAfterTable,
|
|
VoidVarTable, LRBeforeTable, LRAfterTable, VoidVarRegionTable,
|
|
InputRTable, OutputRTable, BornRTable, DeadRTable, LocalRTable) :-
|
|
module_info_get_valid_pred_ids(ModuleInfo, PredIds),
|
|
map.init(LRBeforeTable0),
|
|
map.init(LRAfterTable0),
|
|
map.init(VoidVarRegionTable0),
|
|
map.init(InputRTable0),
|
|
map.init(OutputRTable0),
|
|
map.init(BornRTable0),
|
|
map.init(DeadRTable0),
|
|
map.init(LocalRTable0),
|
|
foldl8(
|
|
live_region_analysis_pred(ModuleInfo, RptaInfoTable,
|
|
LVBeforeTable, LVAfterTable, VoidVarTable),
|
|
PredIds,
|
|
LRBeforeTable0, LRBeforeTable,
|
|
LRAfterTable0, LRAfterTable,
|
|
VoidVarRegionTable0, VoidVarRegionTable,
|
|
InputRTable0, InputRTable,
|
|
OutputRTable0, OutputRTable,
|
|
BornRTable0, BornRTable,
|
|
DeadRTable0, DeadRTable,
|
|
LocalRTable0, LocalRTable).
|
|
|
|
:- pred live_region_analysis_pred(module_info::in, rpta_info_table::in,
|
|
proc_pp_varset_table::in, proc_pp_varset_table::in,
|
|
proc_pp_varset_table::in, pred_id::in,
|
|
proc_pp_region_set_table::in, proc_pp_region_set_table::out,
|
|
proc_pp_region_set_table::in, proc_pp_region_set_table::out,
|
|
proc_pp_region_set_table::in, proc_pp_region_set_table::out,
|
|
proc_region_set_table::in, proc_region_set_table::out,
|
|
proc_region_set_table::in, proc_region_set_table::out,
|
|
proc_region_set_table::in, proc_region_set_table::out,
|
|
proc_region_set_table::in, proc_region_set_table::out,
|
|
proc_region_set_table::in, proc_region_set_table::out) is det.
|
|
|
|
live_region_analysis_pred(ModuleInfo, RptaInfoTable, LVBeforeTable,
|
|
LVAfterTable, VoidVarTable, PredId, !LRBeforeTable, !LRAfterTable,
|
|
!VoidVarRegionTable, !InputRTable, !OutputRTable, !BornRTable,
|
|
!DeadRTable, !LocalRTable) :-
|
|
module_info_pred_info(ModuleInfo, PredId, PredInfo),
|
|
pred_info_non_imported_procids(PredInfo) = ProcIds,
|
|
|
|
foldl8(
|
|
live_region_analysis_proc(ModuleInfo, RptaInfoTable,
|
|
LVBeforeTable, LVAfterTable, VoidVarTable, PredId),
|
|
ProcIds,
|
|
!LRBeforeTable, !LRAfterTable, !VoidVarRegionTable,
|
|
!InputRTable, !OutputRTable, !BornRTable, !DeadRTable, !LocalRTable).
|
|
|
|
:- pred live_region_analysis_proc(module_info::in, rpta_info_table::in,
|
|
proc_pp_varset_table::in, proc_pp_varset_table::in,
|
|
proc_pp_varset_table::in, pred_id::in, proc_id::in,
|
|
proc_pp_region_set_table::in, proc_pp_region_set_table::out,
|
|
proc_pp_region_set_table::in, proc_pp_region_set_table::out,
|
|
proc_pp_region_set_table::in, proc_pp_region_set_table::out,
|
|
proc_region_set_table::in, proc_region_set_table::out,
|
|
proc_region_set_table::in, proc_region_set_table::out,
|
|
proc_region_set_table::in, proc_region_set_table::out,
|
|
proc_region_set_table::in, proc_region_set_table::out,
|
|
proc_region_set_table::in, proc_region_set_table::out) is det.
|
|
|
|
live_region_analysis_proc(ModuleInfo, RptaInfoTable, LVBeforeTable,
|
|
LVAfterTable, VoidVarTable, PredId, ProcId, !LRBeforeTable,
|
|
!LRAfterTable, !VoidVarRegionTable, !InputRTable, !OutputRTable,
|
|
!BornRTable, !DeadRTable, !LocalRTable) :-
|
|
PPId = proc(PredId, ProcId),
|
|
( some_are_special_preds([PPId], ModuleInfo) ->
|
|
% XXX: This action seems to be overkilled, it never goes in this
|
|
% branch.
|
|
% XXX: For the time being just ignore special predicates
|
|
% such as __Unify__ and others or non-defined-in-module ones.
|
|
% The latter ones should have been analysed when their
|
|
% modules analysed and their tables will be integrated.
|
|
% But it is not the case at the moment.
|
|
true
|
|
;
|
|
% This test is just a cautious check.
|
|
( RptaInfo = rpta_info_table_search_rpta_info(PPId, RptaInfoTable) ->
|
|
% Compute region sets.
|
|
RptaInfo = rpta_info(Graph, _ALpha),
|
|
module_info_proc_info(ModuleInfo, PPId, ProcInfo),
|
|
find_input_output_args(ModuleInfo, ProcInfo, Inputs, Outputs),
|
|
lv_to_lr(set.from_list(Inputs), Graph, ModuleInfo, ProcInfo,
|
|
InputR),
|
|
lv_to_lr(set.from_list(Outputs), Graph, ModuleInfo, ProcInfo,
|
|
OutputR),
|
|
map.set(PPId, InputR, !InputRTable),
|
|
map.set(PPId, OutputR, !OutputRTable),
|
|
% initial bornR
|
|
set.difference(OutputR, InputR, BornR),
|
|
map.set(PPId, BornR, !BornRTable),
|
|
% initial deadR
|
|
set.difference(InputR, OutputR, DeadR),
|
|
map.set(PPId, DeadR, !DeadRTable),
|
|
% localR
|
|
Nodes = rptg_get_nodes_as_list(Graph),
|
|
set.difference(
|
|
set.difference(set.from_list(Nodes), InputR),
|
|
OutputR, LocalR),
|
|
map.set(PPId, LocalR, !LocalRTable),
|
|
|
|
% Compute live region set at each program point
|
|
map.lookup(LVBeforeTable, PPId, ProcLVBefore),
|
|
map.foldl(
|
|
proc_lv_to_proc_lr(Graph, ModuleInfo, ProcInfo),
|
|
ProcLVBefore, map.init, ProcLRBefore),
|
|
map.set(PPId, ProcLRBefore, !LRBeforeTable),
|
|
|
|
map.lookup(LVAfterTable, PPId, ProcLVAfter),
|
|
map.foldl(
|
|
proc_lv_to_proc_lr(Graph, ModuleInfo, ProcInfo),
|
|
ProcLVAfter, map.init, ProcLRAfter),
|
|
map.set(PPId, ProcLRAfter, !LRAfterTable),
|
|
|
|
map.lookup(VoidVarTable, PPId, ProcVoidVar),
|
|
map.foldl(
|
|
proc_lv_to_proc_lr(Graph, ModuleInfo, ProcInfo),
|
|
ProcVoidVar, map.init, ProcVoidVarRegion),
|
|
map.set(PPId, ProcVoidVarRegion, !VoidVarRegionTable)
|
|
;
|
|
unexpected($module, $pred, "no rpta_info")
|
|
)
|
|
).
|
|
|
|
:- pred proc_lv_to_proc_lr(rpt_graph::in, module_info::in, proc_info::in,
|
|
program_point::in, variable_set::in, pp_region_set_table::in,
|
|
pp_region_set_table::out) is det.
|
|
|
|
proc_lv_to_proc_lr(Graph, ModuleInfo, ProcInfo, ProgPoint, LVs, !ProcLRMap) :-
|
|
lv_to_lr(LVs, Graph, ModuleInfo, ProcInfo, LRs),
|
|
map.set(ProgPoint, LRs, !ProcLRMap).
|
|
|
|
:- pred foldl8(pred(L, A, A, B, B, C, C, D, D, E, E, F, F, G, G, H, H),
|
|
list(L),
|
|
A, A, B, B, C, C, D, D, E, E, F, F, G, G, H, H).
|
|
:- mode foldl8(pred(in, in, out, in, out, in, out, in, out, in, out, in, out,
|
|
in, out, in, out) is det,
|
|
in, in, out, in, out, in, out, in, out, in, out, in, out, in, out, in,
|
|
out) is det.
|
|
|
|
foldl8(_, [], !A, !B, !C, !D, !E, !F, !G, !H).
|
|
foldl8(P, [H|T], !A, !B, !C, !D, !E, !F, !G, !H) :-
|
|
call(P, H, !A, !B, !C, !D, !E, !F, !G, !H),
|
|
foldl8(P, T, !A, !B, !C, !D, !E, !F, !G, !H).
|
|
|
|
% From a set of live variables, derive the set of live regions.
|
|
% A live region is defined to be reachable from a live variable
|
|
% in the corresponding region points-to graph.
|
|
%
|
|
:- pred lv_to_lr(variable_set::in, rpt_graph::in, module_info::in,
|
|
proc_info::in, region_set::out) is det.
|
|
|
|
lv_to_lr(LVSet, Graph, ModuleInfo, ProcInfo, LRSet) :-
|
|
( set.is_empty(LVSet) ->
|
|
set.init(LRSet)
|
|
;
|
|
% Collect reachable regions at this program point.
|
|
set.init(LRSet0),
|
|
set.fold(rptg_reach_from_a_variable(Graph, ModuleInfo, ProcInfo),
|
|
LVSet, LRSet0, LRSet)
|
|
).
|
|
|
|
%----------------------------------------------------------------------------%
|
|
:- end_module transform_hlds.rbmm.live_region_analysis.
|
|
%----------------------------------------------------------------------------%
|