mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 17:33:38 +00:00
compiler/analysis.framework.m:
compiler/analysis.operations.m:
Split the old contents of analysis.m between these two modules.
analysis.framework.m contains the general framework which may have
any number of instances; analysis.operations defines one instance.
compiler/analysis.m:
Replace this module's old contents with include_module declarations
for the two new modules above (as well as the existing include_module
for analysis.file).
compiler/analysis.file.m:
compiler/exception_analysis.m:
compiler/format_call.m:
compiler/handle_options.m:
compiler/hlds_module.m:
compiler/hlds_pred.m:
compiler/make.check_up_to_date.m:
compiler/make.program_target.m:
compiler/make.timestamp.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/mmc_analysis.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/tabling_analysis.m:
compiler/trailing_analysis.m:
compiler/unused_args.m:
Conform to the changes above.
compiler/notes/compiler_design.html:
Add the new modules to the list currently undocumented modules.
207 lines
8.2 KiB
Mathematica
207 lines
8.2 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2006-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: structure_reuse.direct.m.
|
|
% Main authors: nancy.
|
|
%
|
|
% This module defines procedures and types related to the detection of so
|
|
% called "direct reuses" within the CTGC system. A direct reuse is a
|
|
% combination of the location of a deconstruction unification (where a
|
|
% datastructure may become garbage under certain conditions) and a set of
|
|
% locations of construction unifications where the garbage datastructure can
|
|
% be reused locally.
|
|
%
|
|
% Direct reuse analysis requires two steps:
|
|
% - Detecting where datastructures may become garbage.
|
|
% - Finding where these garbage datastructures can be reused.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module transform_hlds.ctgc.structure_reuse.direct.
|
|
:- interface.
|
|
|
|
:- import_module hlds.
|
|
:- import_module hlds.hlds_module.
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module transform_hlds.ctgc.structure_reuse.domain.
|
|
:- import_module transform_hlds.ctgc.structure_sharing.
|
|
:- import_module transform_hlds.ctgc.structure_sharing.domain.
|
|
|
|
:- import_module io.
|
|
:- import_module list.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% The first pass, where we process all procedures defined in the module.
|
|
%
|
|
:- pred direct_reuse_pass(io.text_output_stream::in, sharing_as_table::in,
|
|
module_info::in, module_info::out,
|
|
reuse_as_table::in, reuse_as_table::out) is det.
|
|
|
|
% Subsequent passes, where we process only the listed procedures.
|
|
%
|
|
:- pred direct_reuse_process_specific_procs(io.text_output_stream::in,
|
|
sharing_as_table::in, list(pred_proc_id)::in,
|
|
module_info::in, module_info::out,
|
|
reuse_as_table::in, reuse_as_table::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module analysis.
|
|
:- import_module analysis.framework.
|
|
:- import_module hlds.passes_aux.
|
|
:- import_module hlds.pred_name.
|
|
:- import_module hlds.status.
|
|
:- import_module libs.
|
|
:- import_module libs.file_util.
|
|
:- import_module libs.globals.
|
|
:- import_module libs.options.
|
|
:- import_module transform_hlds.ctgc.structure_reuse.dead_cell_table.
|
|
:- import_module transform_hlds.ctgc.structure_reuse.direct_choose_reuse.
|
|
:- import_module transform_hlds.ctgc.structure_reuse.direct_detect_garbage.
|
|
:- import_module transform_hlds.ctgc.util.
|
|
:- import_module transform_hlds.smm_common.
|
|
|
|
:- import_module bool.
|
|
:- import_module map.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
direct_reuse_pass(ProgressStream, SharingTable, !ModuleInfo, !ReuseTable) :-
|
|
% Gather the pred_ids of the preds that need to be analysed.
|
|
module_info_get_valid_pred_ids(!.ModuleInfo, AllPredIds),
|
|
list.filter(pred_requires_analysis(!.ModuleInfo), AllPredIds,
|
|
ToBeAnalysedPredIds),
|
|
|
|
% Analyse and annotate each of the predicates.
|
|
list.foldl2(direct_reuse_process_pred(ProgressStream, SharingTable),
|
|
ToBeAnalysedPredIds, !ModuleInfo, !ReuseTable).
|
|
|
|
:- pred direct_reuse_process_pred(io.text_output_stream::in,
|
|
sharing_as_table::in, pred_id::in,
|
|
module_info::in, module_info::out,
|
|
reuse_as_table::in, reuse_as_table::out) is det.
|
|
|
|
direct_reuse_process_pred(ProgressStream, SharingTable, PredId,
|
|
!ModuleInfo, !ReuseTable) :-
|
|
module_info_pred_info(!.ModuleInfo, PredId, PredInfo0),
|
|
( if
|
|
pred_info_get_origin(PredInfo0, Origin),
|
|
Origin = origin_compiler(made_for_uci(_, _))
|
|
then
|
|
% We can't analyse compiler generated special predicates.
|
|
true
|
|
else if
|
|
pred_info_get_status(PredInfo0, PredStatus),
|
|
PredStatus = pred_status(status_external(_))
|
|
then
|
|
% We can't analyse `:- pragma external_{pred/func}' procedures,
|
|
% but we add an extry to the reuse table so something will be written
|
|
% out to optimisation interface files.
|
|
ProcIds = pred_info_all_procids(PredInfo0),
|
|
list.foldl(set_external_pred_reuse_as(PredId, reuse_as_init, optimal),
|
|
ProcIds, !ReuseTable)
|
|
else
|
|
ProcIds = pred_info_all_non_imported_procids(PredInfo0),
|
|
list.foldl2(
|
|
direct_reuse_process_proc(ProgressStream, SharingTable, PredId),
|
|
ProcIds, !ModuleInfo, !ReuseTable)
|
|
).
|
|
|
|
:- pred set_external_pred_reuse_as(pred_id::in, reuse_as::in,
|
|
analysis_status::in, proc_id::in, reuse_as_table::in, reuse_as_table::out)
|
|
is det.
|
|
|
|
set_external_pred_reuse_as(PredId, ReuseAs, Status, ProcId, !ReuseTable) :-
|
|
reuse_as_table_set(proc(PredId, ProcId),
|
|
reuse_as_and_status(ReuseAs, Status), !ReuseTable).
|
|
|
|
direct_reuse_process_specific_procs(ProgressStream, SharingTable, PPIds,
|
|
!ModuleInfo, !ReuseTable) :-
|
|
list.foldl2(direct_reuse_process_ppid(ProgressStream, SharingTable), PPIds,
|
|
!ModuleInfo, !ReuseTable).
|
|
|
|
:- pred direct_reuse_process_ppid(io.text_output_stream::in,
|
|
sharing_as_table::in, pred_proc_id::in,
|
|
module_info::in, module_info::out,
|
|
reuse_as_table::in, reuse_as_table::out) is det.
|
|
|
|
direct_reuse_process_ppid(ProgressStream, SharingTable, proc(PredId, ProcId),
|
|
!ModuleInfo, !ReuseTable) :-
|
|
direct_reuse_process_proc(ProgressStream, SharingTable, PredId, ProcId,
|
|
!ModuleInfo, !ReuseTable).
|
|
|
|
% Process one individual procedure.
|
|
%
|
|
:- pred direct_reuse_process_proc(io.text_output_stream::in,
|
|
sharing_as_table::in, pred_id::in, proc_id::in,
|
|
module_info::in, module_info::out,
|
|
reuse_as_table::in, reuse_as_table::out) is det.
|
|
|
|
direct_reuse_process_proc(ProgressStream, SharingTable, PredId, ProcId,
|
|
!ModuleInfo, !ReuseTable) :-
|
|
module_info_pred_info(!.ModuleInfo, PredId, PredInfo0),
|
|
pred_info_proc_info(PredInfo0, ProcId, ProcInfo0),
|
|
|
|
direct_reuse_process_proc_2(ProgressStream, !.ModuleInfo, SharingTable,
|
|
PredId, PredInfo0, ProcId, ProcInfo0, ProcInfo, ReuseAs),
|
|
% XXX is this right?
|
|
Status = optimal,
|
|
AsAndStatus = reuse_as_and_status(ReuseAs, Status),
|
|
reuse_as_table_set(proc(PredId, ProcId), AsAndStatus, !ReuseTable),
|
|
|
|
pred_info_set_proc_info(ProcId, ProcInfo, PredInfo0, PredInfo),
|
|
module_info_set_pred_info(PredId, PredInfo, !ModuleInfo).
|
|
|
|
:- pred direct_reuse_process_proc_2(io.text_output_stream::in, module_info::in,
|
|
sharing_as_table::in, pred_id::in, pred_info::in,
|
|
proc_id::in, proc_info::in, proc_info::out, reuse_as::out) is det.
|
|
|
|
direct_reuse_process_proc_2(ProgressStream, ModuleInfo, SharingTable,
|
|
PredId, PredInfo, ProcId, !ProcInfo, ReuseAs) :-
|
|
module_info_get_globals(ModuleInfo, Globals),
|
|
globals.lookup_bool_option(Globals, very_verbose, VeryVerbose),
|
|
|
|
trace [io(!IO)] (
|
|
maybe_write_proc_progress_message(ProgressStream, ModuleInfo,
|
|
"Direct reuse analysis of", proc(PredId, ProcId), !IO)
|
|
),
|
|
|
|
proc_info_get_goal(!.ProcInfo, Goal0),
|
|
|
|
% Determine the deconstructions in which data may potentially become
|
|
% garbage.
|
|
|
|
determine_dead_deconstructions(ModuleInfo, PredInfo, !.ProcInfo,
|
|
SharingTable, Goal0, DeadCellTable),
|
|
trace [io(!IO)] (
|
|
get_debug_output_stream(ModuleInfo, DebugStream, !IO),
|
|
dead_cell_table_maybe_dump(DebugStream, VeryVerbose,
|
|
DeadCellTable, !IO)
|
|
),
|
|
|
|
% Determine how the detected dead datastructures can be reused.
|
|
% This annotates the goal with potential reuses.
|
|
|
|
determine_reuse(ModuleInfo, !.ProcInfo, DeadCellTable, Goal0, Goal,
|
|
ReuseAs),
|
|
|
|
proc_info_set_goal(Goal, !ProcInfo),
|
|
|
|
trace [io(!IO)] (
|
|
maybe_write_string(ProgressStream, VeryVerbose,
|
|
"% reuse analysis done.\n", !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module transform_hlds.ctgc.structure_reuse.direct.
|
|
%---------------------------------------------------------------------------%
|