mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-17 06:47:17 +00:00
Estimated hours taken: 25 Branches: main Provide the direct reuse analysis part of the structure reuse analysis (which itself is part of the CTGC system). compiler/ctgc.datastruct.m: compiler/ctgc.util.m: Additional predicates. compiler/ctgc.m: Add structure reuse module. compiler/handle_options.m: compiler/options.m: Add new options "structure_reuse_analysis" and related ones. compiler/handle_options.m: compiler/hlds_out.m: Add dump option "R" to dump structure reuse related information in the hlds_dump files. compiler/hlds_goal.m: Types to record structure reuse information at the level of each goal. Additional "case_get_goal" function to extract the goal from an case. compiler/mercury_compile.m: Add structure reuse analysis as a new compiler stage. compiler/structure_reuse.analysis.m: The top level analysis predicates. compiler/structure_reuse.direct.m: compiler/structure_reuse.direct.choose_reuse.m: compiler/structure_reuse.direct.detect_garbage.m: Direct reuse analysis is split into 2 steps: determining when and how data structures become garbage, and then choosing how these dead data structures might best be reused. compiler/structure_reuse.domain.m: The abstract domain for keeping track of reuse conditions, the main domain in the structure reuse analysis. compiler/structure_reuse.lbu.m: compiler/structure_reuse.lfu.m: To determine whether data structures become dead or not, one needs to know which variables in a goal are needed with respect to forward execution (lfu = local forward use), and backward execution, i.e. backtracking (lbu = local backward use). These two modules provide the necessary functionality to pre-annotate the goals with lfu and lbu information. compiler/structure_sharing.analysis.m: compiler/structure_sharing.domain.m: Remove the structure sharing table from the interface of the analysis predicate in structure_sharing.analysis.m; Move predicates to structure_sharing.domain.m so that they become more easily accessible for the structure_reuse modules. compiler/prog_data.m: New types "dead_var", "live_var" and alike.
138 lines
5.1 KiB
Mathematica
138 lines
5.1 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 2006 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.analysis.m
|
|
% Main authors: nancy
|
|
%
|
|
% Implementation of the structure reuse analysis (compile-time garbage
|
|
% collection system): each procedure is analysed to see whether some
|
|
% of the terms it manipulates become garbage thus making it possible
|
|
% to reuse that garbage straight away for creating new terms.
|
|
%
|
|
% Structure reuse is broken up into three phases:
|
|
% * the direct reuse analysis (structure_reuse.direct.m)
|
|
% * the indirect analysis (structure_reuse.indirect.m)
|
|
% * and the generation of the optimised procedures.
|
|
%
|
|
% The following example shows instances of direct and indirect reuse:
|
|
%
|
|
% list__append(H1, H2, H3) :-
|
|
% (
|
|
% H1 => [],
|
|
% H3 := H2
|
|
% ;
|
|
% % Cell H1 dies provided some condition about the
|
|
% % structure sharing of H1 is true. A deconstruction
|
|
% % generating a dead cell, followed by a
|
|
% % construction reusing that cell, is called a direct
|
|
% % reuse.
|
|
% H1 => [X | Xs],
|
|
%
|
|
% % If the condition about the structure sharing of H1
|
|
% % is true then we can call the version of list__append
|
|
% % which does reuse. Calling the optimised version here leads
|
|
% % to a new condition to be met by the headvars of any
|
|
% % call to the resulting optimised version of append.
|
|
% % This is an indirect reuse.
|
|
% list__append(Xs, H2, Zs),
|
|
%
|
|
% % Reuse the dead cell H1. This is a direct reuse.
|
|
% H3 <= [X | Zs]
|
|
% ).
|
|
%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module transform_hlds.ctgc.structure_reuse.analysis.
|
|
|
|
:- interface.
|
|
|
|
:- import_module hlds.hlds_module.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred structure_reuse_analysis(module_info::in, module_info::out,
|
|
io::di, io::uo) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module check_hlds.goal_path.
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module hlds.passes_aux.
|
|
:- import_module libs.globals.
|
|
:- import_module libs.options.
|
|
:- import_module parse_tree.prog_out.
|
|
:- import_module transform_hlds.ctgc.structure_reuse.direct.
|
|
:- import_module transform_hlds.ctgc.structure_reuse.domain.
|
|
:- import_module transform_hlds.ctgc.structure_reuse.lbu.
|
|
:- import_module transform_hlds.ctgc.structure_reuse.lfu.
|
|
:- import_module transform_hlds.ctgc.structure_sharing.domain.
|
|
|
|
:- import_module string.
|
|
|
|
|
|
structure_reuse_analysis(!ModuleInfo, !IO):-
|
|
globals.io_lookup_bool_option(very_verbose, VeryVerbose, !IO),
|
|
|
|
% Load all available structure sharing information into a sharing table.
|
|
SharingTable = load_structure_sharing_table(!.ModuleInfo),
|
|
|
|
% Load all the available reuse information into a reuse table.
|
|
% XXX TO DO!
|
|
% ReuseTable0 = load_structure_reuse_table(!.ModuleInfo),
|
|
|
|
% Pre-annotate each of the goals with "Local Forward Use" and
|
|
% "Local Backward Use" information, and fill in all the goal_path slots
|
|
% as well.
|
|
|
|
maybe_write_string(VeryVerbose, "% Annotating in use information...", !IO),
|
|
process_all_nonimported_procs(update_proc_io(annotate_in_use_information),
|
|
!ModuleInfo, !IO),
|
|
maybe_write_string(VeryVerbose, "done.\n", !IO),
|
|
|
|
% Determine information about possible direct reuses.
|
|
maybe_write_string(VeryVerbose, "% Direct reuse...\n", !IO),
|
|
DummyReuseTable = reuse_as_table_init,
|
|
direct_reuse_pass(SharingTable, !ModuleInfo,
|
|
DummyReuseTable, _ReuseTable, !IO),
|
|
maybe_write_string(VeryVerbose, "% Direct reuse: done.\n", !IO).
|
|
|
|
% Determine information about possible indirect reuses.
|
|
% XXX TO DO!
|
|
% indirect_reuse_pass(SharingTable, ReuseTable1, ReuseTable2,
|
|
% !ModuleInfo, !IO),
|
|
|
|
% For every procedure that has some potential (conditional) reuse (either
|
|
% direct or indirect), create a new procedure that actually implements
|
|
% that reuse.
|
|
% XXX TO DO!
|
|
% split_reuse_procedures(ReuseTable2, ReuseTable3, !ModuleInfo, !IO),
|
|
|
|
% Record the results of the reuse table into the HLDS.
|
|
% XXX TO DO!
|
|
% map.foldl(save_reuse_in_module_info, ReuseTable3, !ModuleInfo).
|
|
%
|
|
% Output some profiling information.
|
|
% XXX TO DO!
|
|
% profiling(!.ModuleInfo, ReuseTable3).
|
|
|
|
:- pred annotate_in_use_information(pred_id::in, proc_id::in,
|
|
module_info::in, proc_info::in, proc_info::out, io::di, io::uo) is det.
|
|
|
|
annotate_in_use_information(_PredId, _ProcId, ModuleInfo, !ProcInfo, !IO) :-
|
|
forward_use_information(!ProcInfo),
|
|
backward_use_information(ModuleInfo, !ProcInfo),
|
|
goal_path.fill_goal_path_slots(ModuleInfo, !ProcInfo).
|
|
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- func this_file = string.
|
|
this_file = "structure_reuse.analysis.m".
|
|
|
|
:- end_module transform_hlds.ctgc.structure_reuse.analysis.
|