[m-rev.] for review: [CTGC] indirect reuse analysis.
Julien Fischer
juliensf at cs.mu.OZ.AU
Wed May 24 13:29:32 AEST 2006
On Thu, 18 May 2006, Nancy Mazur wrote:
> Estimated hours taken: 10
> Branches: main
>
> Provide the indirect reuse analysis part of the CTGC system. Using a fixpoint
> computation, this propagates the reuse conditions determined by the direct
> reuse analysis step through procedure calls.
>
> compiler/ctgc.datastruct.m:
> Minor additions.
>
> compiler/ctgc.livedata.m:
> (new file) Types and operations needed for defining the lattice of
> possibly live datastructures.
>
> compiler/ctgc.m:
> Add livedata submodule.
>
> compiler/ctgc.util.m:
> Provide the operations for determining variable and type renamings,
> used both by the structure sharing analysis as well as the reuse
> analysis.
>
> compiler/hlds_module.m:
> Add structure reuse information to collect the mapping between
> procedures, and their reuse versions.
>
> compiler/prog_data.m:
> New types "dead_vars", "live_vars".
>
> compiler/structure_reuse.analysis.m:
> Add the indirect reuse analysis step.
>
> compiler/structure_reuse.direct.detect_garbage.m:
> compiler/structure_sharing.domain.m:
> Mainly moving the operation of looking up sharing information and
> combining it with existing sharing to a more appropriate place, namely
> structure_sharing.domain.m
>
> compiler/structure_reuse.domain.m:
> Add a renaming operation but especially two predicates needed to
> verify whether a given procedure call satisfies the derived reuse
> conditions, and to translate these reuse conditions to the
> head variables of the procedure in which the procedure call occurs.
>
> compiler/structure_reuse.indirect.m:
> The actual indirect reuse analysis.
>
> compiler/structure_reuse.m:
> Add "structure_reuse.indirect" as a submodule.
>
> compiler/structure_sharing.analysis.m:
> small changes.
>
> Index: compiler/ctgc.datastruct.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/ctgc.datastruct.m,v
> retrieving revision 1.6
> diff -u -d -r1.6 ctgc.datastruct.m
> --- compiler/ctgc.datastruct.m 10 May 2006 10:56:49 -0000 1.6
> +++ compiler/ctgc.datastruct.m 18 May 2006 12:01:04 -0000
> @@ -35,6 +35,11 @@
> %
> :- pred datastruct_equal(datastruct::in, datastruct::in) is semidet.
>
> + % Verify whether the datastructure represents a top cell, ie. where
s/ie./i.e./
> + % the selector path is an empty path.
> + %
> +:- pred datastruct_refers_to_topcell(datastruct::in) is semidet.
> +
> % Select a subterm of the given datastructure using the specified selector.
> % It is assumed that the selector is a valid selector for that
> % datastructure.
...
> Index: compiler/ctgc.livedata.m
> ===================================================================
> RCS file: compiler/ctgc.livedata.m
> diff -N compiler/ctgc.livedata.m
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ compiler/ctgc.livedata.m 18 May 2006 12:01:05 -0000
> @@ -0,0 +1,292 @@
> +%-----------------------------------------------------------------------------%
> +% 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: ctgc.livedata.m.
> +% Main author: nancy.
> +%
> +% Definition of the live_data type used to represent the set of datastructures
> +% that are probably (not definitely!) live at a given program point (goal).
> +% A data structure is said to be "live" if the memory used to represent
> +% that data structure may possibly be accessed during the further execution
> +% of the program w.r.t. the program point (goal) looked at.
> +%
> +%-----------------------------------------------------------------------------%
> +
> +:- module transform_hlds.ctgc.livedata.
> +:- interface.
> +
> +:- import_module parse_tree.prog_data.
> +:- import_module hlds.hlds_module.
> +:- import_module hlds.hlds_pred.
> +:- import_module transform_hlds.ctgc.structure_sharing.
> +:- import_module transform_hlds.ctgc.structure_sharing.domain.
> +:- import_module hlds.hlds_goal.
> +
> +:- import_module list.
> +
> +%-----------------------------------------------------------------------------%
> +
> +:- type livedata.
> +
> + % Create an initial set of live data structure, possibly given a list
> + % of live variables or data structures.
> + %
> +:- func livedata_init = livedata. % Which assumes that nothing is live.
> +:- func livedata_init_from_vars(live_vars) = livedata.
> +:- func livedata_init_from_datastructs(live_datastructs) = livedata.
> +:- func livedata_init_as_top = livedata.
> +
> + % Verify whether the liveness set is bottom resp. top.
> +:- pred livedata_is_bottom(livedata::in) is semidet.
> +:- pred livedata_is_top(livedata::in) is semidet.
> +
> + % Return the list of live data structures represented by livedata.
> + % Returns a software error when the livedata set is top.
> + %
> +:- func livedata_get_datastructs(livedata) = list(datastruct).
> +
> + % Least upper bound of all the livedata.
> + %
> +:- func livedata_least_upper_bound(module_info, proc_info, livedata,
> + livedata) = livedata.
> +:- func livedata_least_upper_bound_list(module_info, proc_info,
> + list(livedata)) = livedata.
> +
> + % Subsumption predicates.
> + %
> +:- pred livedata_subsumes_prog_var(livedata::in, prog_var::in) is semidet.
> +:- pred livedata_subsumes_datastruct(module_info::in, proc_info::in,
> + livedata::in, datastruct::in) is semidet.
> +
> + % Projection operation.
> + %
> +:- func livedata_project(list(prog_var), livedata) = livedata.
> +
> +%-----------------------------------------------------------------------------%
> +
> +:- func livedata_init_at_goal(module_info, proc_info, hlds_goal_info,
> + sharing_as) = livedata.
> +:- func livedata_add_liveness(module_info, proc_info, live_datastructs,
> + sharing_as, livedata) = livedata.
> +
> +:- pred nodes_are_not_live(module_info::in, proc_info::in,
> + list(datastruct)::in, livedata::in) is semidet.
> +%-----------------------------------------------------------------------------%
> +
> +:- implementation.
> +
> +:- import_module libs.compiler_util.
> +:- import_module transform_hlds.ctgc.datastruct.
> +
> +:- import_module set.
> +
> +
> +:- type livedata
> + ---> bottom % There are no live data structures.
> + ; top % All data structures may be live.
> + ; live(list(datastruct)).
> + % Only the listed datastructures can possibly
> + % be live.
There are already types with constructors called bottom and top in several parts
of the compiler. It would probably a good idea to use more distinct names,
e.g.
:- type livedata
---> livedata_bottom
; livedata_top
; livedata_live(list(datastruct)).
(It's probably worth doing a bit of renaming along similar lines in
other parts of the CTGC system as well).
...
> +livedata_project(ProgVars, LiveData) = ProjectedLiveData :-
> + (
> + LiveData = bottom,
> + ProjectedLiveData = bottom
> + ;
> + LiveData = top,
> + ProjectedLiveData = top
> + ;
> + LiveData = live(Data),
> + list.filter(list_contains_datastruct_var(ProgVars),
> + Data, FilteredData),
> + ( FilteredData = [] -> ProjectedLiveData = bottom
> + ; ProjectedLiveData = live(FilteredData)
> + )
That if-then-else can be a switch.
...
> Index: compiler/ctgc.util.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/ctgc.util.m,v
> retrieving revision 1.5
> diff -u -d -r1.5 ctgc.util.m
> --- compiler/ctgc.util.m 10 May 2006 10:56:49 -0000 1.5
> +++ compiler/ctgc.util.m 18 May 2006 12:01:05 -0000
> @@ -18,8 +18,10 @@
>
> :- import_module hlds.hlds_module.
> :- import_module hlds.hlds_pred.
> +:- import_module parse_tree.prog_data.
>
> :- import_module list.
> +:- import_module map.
>
> %-----------------------------------------------------------------------------%
>
> @@ -34,16 +36,32 @@
> :- pred pred_requires_no_analysis(module_info::in, pred_id::in) is semidet.
> :- pred pred_requires_analysis(module_info::in, pred_id::in) is semidet.
>
> + % Given the pred_proc_id of a procedure call and its actual arguments,
> + % determine the variable renaming to rename anything which is defined
> + % in terms of the formal arguments of the called procedure to the context
> + % of the actual arguments.
> + %
> +:- func get_variable_renaming(module_info, pred_proc_id, prog_vars) =
> + map(prog_var, prog_var).
> +
The module goal_util defines the type prog_var_renaming (==map(prog_var,
prog_var)).
...
> Index: compiler/hlds_module.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/hlds_module.m,v
> retrieving revision 1.134
> diff -u -d -r1.134 hlds_module.m
> --- compiler/hlds_module.m 29 Mar 2006 08:06:48 -0000 1.134
> +++ compiler/hlds_module.m 18 May 2006 12:01:07 -0000
> @@ -185,6 +185,14 @@
> ; complexity_input_fixed_size
> ; complexity_output.
>
> + % This type is used to record the mapping between original
> + % procedures, and their optimised versions with respect to
> + % structure reuse (CTGC).
> + %
> +:- type structure_reuse_info
> + ---> structure_reuse_info(
> + map(pred_proc_id, pair(pred_proc_id, sym_name))
> + ).
...
> Index: compiler/structure_reuse.direct.detect_garbage.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/structure_reuse.direct.detect_garbage.m,v
> retrieving revision 1.1
> diff -u -d -r1.1 structure_reuse.direct.detect_garbage.m
> --- compiler/structure_reuse.direct.detect_garbage.m 10 May 2006 10:56:56 -0000 1.1
> +++ compiler/structure_reuse.direct.detect_garbage.m 18 May 2006 12:01:12 -0000
> @@ -90,6 +90,7 @@
> func(C) = G :- (G = C ^ case_goal), Cases), !SharingAs,
> !DeadCellTable)
> ;
> + % XXX
Why has that XXX comment been added there?
> GoalExpr = not(_Goal)
> ;
> GoalExpr = scope(_, SubGoal),
> @@ -208,28 +209,6 @@
>
> var_is_live(Var, LiveData) :-
> list.member(datastruct_init(Var), LiveData).
...
> + % reuse_as_rename_using_module_info(ModuleInfo, PPId,
> + % ActualVars, ActualTypes, ActualTVarset, FormalReuse, ActualReuse):
> + %
> + % Renaming of the formal description of structure reuse conditions to the
> + % actual description of these conditions. The information about the formal
> + % variables needs to be extracted from the module information.
> + % A list of variables and types is used as the actual variables and types.
> + % The type variables set in the actual context must also be specified.
> + %
I don't understand the last part of that description.
> +:- pred reuse_as_rename_using_module_info(module_info::in,
> + pred_proc_id::in, prog_vars::in, list(mer_type)::in, tvarset::in,
> + reuse_as::in, reuse_as::out) is det.
> +
> % Given a variable and type variable mapping, rename the reuses
> % conditions accordingly.
...
> +:- func reuse_condition_from_called_proc_to_local_condition(module_info,
> + proc_info, prog_vars, live_datastructs, sharing_as, reuse_condition) =
> + reuse_condition.
> +
> +reuse_condition_from_called_proc_to_local_condition(ModuleInfo, ProcInfo,
> + HeadVars, LuData, SharingAs, CalledCondition) = LocalCondition :-
> + (
> + CalledCondition = always, % should not occur though...
> + LocalCondition = always
If it shouldn't occur then why not call unexpected/2 here?
> + ;
> + CalledCondition = condition(CalledDeadNodes,
> + CalledInUseNodes, CalledSharingAs),
> +
> + % Translate the dead nodes:
> + AllDeadNodes = extend_datastructs(ModuleInfo, ProcInfo,
> + SharingAs, CalledDeadNodes),
> + AllDeadHeadVarNodes = datastructs_project(HeadVars, AllDeadNodes),
> +
> + (
> + AllDeadHeadVarNodes = []
> + ->
> + LocalCondition = always
> + ;
> + % Translate the in use nodes:
> + AllInUseNodes = extend_datastructs(ModuleInfo, ProcInfo,
> + SharingAs, list.append(LuData, CalledInUseNodes)),
> + AllInUseHeadVarNodes = datastructs_project(HeadVars,
> + AllInUseNodes),
> +
> + % Translate the sharing information:
> + AllLocalSharing = sharing_as_comb(ModuleInfo, ProcInfo,
> + CalledSharingAs, SharingAs),
> + AllHeadVarLocalSharing = sharing_as_project(HeadVars,
> + AllLocalSharing),
> +
> + LocalCondition = condition(AllDeadHeadVarNodes,
> + AllInUseHeadVarNodes, AllHeadVarLocalSharing)
> + )
You can turn that if-then-else into a switch.
...
> Index: compiler/structure_reuse.indirect.m
> ===================================================================
> RCS file: compiler/structure_reuse.indirect.m
> diff -N compiler/structure_reuse.indirect.m
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ compiler/structure_reuse.indirect.m 18 May 2006 12:01:14 -0000
> @@ -0,0 +1,676 @@
> +%------------------------------------------------------------------------------%
> +% vim: ft=mercury ff=unix 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.indirect.m
> +% Main authors: nancy
> +%
> +% Determine the indirect reuse. This requires a fixpoint computation.
> +%------------------------------------------------------------------------------%
> +
> +:- module structure_reuse.indirect.
> +
> +:- interface.
> +
> +:- import_module hlds.hlds_module.
> +:- import_module transform_hlds.ctgc.structure_reuse.domain.
> +:- import_module transform_hlds.ctgc.structure_sharing.domain.
> +
> +:- import_module io.
> +
> + % Direct reuse analysis derives information about deconstructions that
> + % under certain circumstances (formalised as "reuse conditions") form
> + % the last ever (memory) access to the deconstructed term.
> + %
> + % Indirect reuse analysis is about verifying procedure calls to see
> + % whether these procedure calls satisfy these reuse conditions for
> + % direct reuse, and under what circumstances (again expressed as
> + % reuse conditions). Using a fixpoint computation, we determine the
> + % overall reuse conditions for a procedure call to be replaced by a
> + % call to an optimised version of that procedure w.r.t. its memory usage.
> + %
> + % The results of the analysis are primarely stored in the reuse table, yet
s/primarely/primarily/
> + % also involves annotations at the level of the individual procedure calls,
> + % which explains the need for updating the HLDS as well.
> + %
> +:- pred indirect_reuse_pass(sharing_as_table::in, module_info::in,
> + module_info::out, reuse_as_table::in, reuse_as_table::out,
> + io::di, io::uo) is det.
> +
...
> +indirect_reuse_pass(SharingTable, !ModuleInfo, !ReuseTable, !IO):-
> + %
> + % Perform a bottom-up traversal of the SCCs in the program,
s/program/module/
> + % analysing indirect structure reuse in each one as we go.
> + %
> + module_info_ensure_dependency_info(!ModuleInfo),
> + module_info_get_maybe_dependency_info(!.ModuleInfo, MaybeDepInfo),
> + (
> + MaybeDepInfo = yes(DepInfo),
> + hlds_dependency_info_get_dependency_ordering(DepInfo, SCCs),
> + list.foldl3(indirect_reuse_analyse_scc(SharingTable),
> + SCCs, !ModuleInfo, !ReuseTable, !IO)
> + ;
> + MaybeDepInfo = no,
> + unexpected(this_file, "No dependency information.")
> + ).
> +
> +:- pred indirect_reuse_analyse_scc(sharing_as_table::in,
> + list(pred_proc_id)::in, module_info::in, module_info::out,
> + reuse_as_table::in, reuse_as_table::out, io::di, io::uo) is det.
> +
> +indirect_reuse_analyse_scc(SharingTable, SCC, !ModuleInfo, !ReuseTable, !IO) :-
> + ( preds_requiring_no_analysis(!.ModuleInfo, SCC) ->
> + true
> + ;
> + indirect_reuse_analyse_scc_until_fixpoint(SharingTable,
> + SCC, !.ReuseTable, !ModuleInfo,
> + sr_fixpoint_table_init(SCC, !.ReuseTable), FixpointTable, !IO),
> + list.foldl(update_reuse_in_table(FixpointTable), SCC, !ReuseTable)
> + ).
> +
> +:- pred indirect_reuse_analyse_scc_until_fixpoint(sharing_as_table::in,
> + list(pred_proc_id)::in, reuse_as_table::in,
> + module_info::in, module_info::out, sr_fixpoint_table::in,
> + sr_fixpoint_table::out, io::di, io::uo) is det.
> +
> +indirect_reuse_analyse_scc_until_fixpoint(SharingTable, SCC,
> + ReuseTable, !ModuleInfo, !FixpointTable, !IO):-
> + list.foldl3(indirect_reuse_analyse_pred_proc(SharingTable, ReuseTable),
> + SCC, !ModuleInfo, !FixpointTable, !IO),
> + ( sr_fixpoint_table_stable(!.FixpointTable) ->
> + true
> + ;
> + sr_fixpoint_table_new_run(!FixpointTable),
> + indirect_reuse_analyse_scc_until_fixpoint(SharingTable,
> + SCC, ReuseTable, !ModuleInfo, !FixpointTable, !IO)
> + ).
> +
...
> +
> + % The type ir_background_info has the purpose to collect all the necessary
> + % background information needed to be able to perform the indirect reuse
> + % (ir) analysis of a specific procedure.
> + %
> +:- type ir_background_info
> + ---> ir_background_info(
> + module_info :: module_info,
> + pred_info :: pred_info,
> + proc_info :: proc_info,
> + sharing_table :: sharing_as_table,
> + reuse_table :: reuse_as_table,
> + headvars :: list(prog_var)
> + ).
> +
> + % The type analysis_info gathers the analysis information that may change
> + % from goal to goal.
> + %
> +:- type analysis_info
> + ---> analysis_info(
> + sharing_as :: sharing_as,
> + reuse_as :: reuse_as,
> + static_vars :: set(prog_var),
> + fptable :: sr_fixpoint_table
> + ).
> +
analysis_info is not a good name for this as it's also the name of one of
the principle data structures used by the intermodule-analysis framework
(which we will eventually be using here.)
...
> +%-----------------------------------------------------------------------------%
> +
> +:- pred indirect_reuse_analyse_goal(ir_background_info::in, hlds_goal::in,
> + hlds_goal::out, analysis_info::in, analysis_info::out,
> + io::di, io::uo) is det.
> +
> +indirect_reuse_analyse_goal(BaseInfo, !Goal, !AnalysisInfo, !IO) :-
> + !.Goal = GoalExpr0 - GoalInfo0,
> + (
> + GoalExpr0 = conj(ConjType, Goals0),
> + list.map_foldl2(indirect_reuse_analyse_goal(BaseInfo), Goals0,
> + Goals, !AnalysisInfo, !IO),
> + GoalExpr = conj(ConjType, Goals),
> + !:Goal = GoalExpr - GoalInfo0
> + ;
> + GoalExpr0 = call(CalleePredId, CalleeProcId, CalleeArgs, _, _, _),
> + verify_indirect_reuse(BaseInfo, CalleePredId, CalleeProcId,
> + CalleeArgs, GoalInfo0, GoalInfo, !AnalysisInfo, !IO),
> + lookup_sharing_and_comb(BaseInfo ^ module_info, BaseInfo ^ proc_info,
> + BaseInfo ^ sharing_table, CalleePredId, CalleeProcId,
> + CalleeArgs, !.AnalysisInfo ^ sharing_as, NewSharing),
> + !:AnalysisInfo = !.AnalysisInfo ^ sharing_as := NewSharing,
> + GoalExpr = GoalExpr0,
> + !:Goal = GoalExpr - GoalInfo
> + ;
> + GoalExpr0 = generic_call(_GenDetails, _, _, _),
> + goal_info_get_context(GoalInfo0, Context),
> + context_to_string(Context, ContextString),
> + !:AnalysisInfo = !.AnalysisInfo ^ sharing_as :=
> + sharing_as_top_sharing_accumulate("generic call ("
> + ++ ContextString ++ ")",
> + !.AnalysisInfo ^ sharing_as)
> + ;
> + GoalExpr0 = unify(_, _, _, Unification, _),
> + % Record the statically constructed variables:
> + ( Unification = construct(Var, _, _, _,
> + construct_statically(_), _, _) ->
> + !:AnalysisInfo = !.AnalysisInfo ^ static_vars :=
> + set.insert(!.AnalysisInfo ^ static_vars, Var)
> + ;
> + true
> + ),
> + !:AnalysisInfo = !.AnalysisInfo ^ sharing_as :=
> + add_unify_sharing(BaseInfo ^ module_info, BaseInfo ^ proc_info,
> + Unification, GoalInfo0, !.AnalysisInfo ^ sharing_as)
> + ;
> + GoalExpr0 = disj(Goals0),
> + list.map2_foldl2(
> + indirect_reuse_analyse_disj(BaseInfo, !.AnalysisInfo),
> + Goals0, Goals, AnalysisInfoList, !.AnalysisInfo ^ fptable,
> + NewFixpointTable, !IO),
> + analysis_info_combine(BaseInfo, AnalysisInfoList, NewFixpointTable,
> + !AnalysisInfo),
> + GoalExpr = disj(Goals),
> + !:Goal = GoalExpr - GoalInfo0
> + ;
> + GoalExpr0 = switch(A, B, Cases0),
> + list.map2_foldl2(
> + indirect_reuse_analyse_case(BaseInfo, !.AnalysisInfo),
> + Cases0, Cases, AnalysisInfoList, !.AnalysisInfo ^ fptable,
> + NewFixpointTable, !IO),
> + analysis_info_combine(BaseInfo, AnalysisInfoList, NewFixpointTable,
> + !AnalysisInfo),
> + GoalExpr = switch(A, B, Cases),
> + !:Goal = GoalExpr - GoalInfo0
> + ;
> + % XXX
A little more information please.
...
> + % Verify whether the caller's environment satisfies the reuse conditions
> + % stated in the reuse description of the called procedure. If this
> + % succeeds, then translate those reuse conditions to this caller's
> + % environment.
> + %
> + % Pre-conditions: The sharing is not top, and reuse_as contains at least
> + % one conditional reuse condition.
> + %
> +:- pred verify_indirect_reuse_2(ir_background_info::in, analysis_info::in,
> + hlds_goal_info::in, pred_proc_id::in, list(prog_var)::in, reuse_as::in,
> + reuse_as::out) is det.
> +
> +verify_indirect_reuse_2(BaseInfo, AnalysisInfo, GoalInfo, CalleePPId,
> + CalleeArgs, FormalReuseAs, NewReuseAs):-
> + ModuleInfo = BaseInfo ^ module_info,
> + PredInfo = BaseInfo ^ pred_info,
> + ProcInfo = BaseInfo ^ proc_info,
> + SharingAs = AnalysisInfo ^ sharing_as,
> + proc_info_get_vartypes(ProcInfo, ActualVarTypes),
> + pred_info_get_typevarset(PredInfo, ActualTVarset),
> + list.map(map.lookup(ActualVarTypes), CalleeArgs, CalleeTypes),
> + reuse_as_rename_using_module_info(ModuleInfo, CalleePPId,
> + CalleeArgs, CalleeTypes, ActualTVarset, FormalReuseAs, ActualReuseAs),
> + LiveData = livedata_init_at_goal(ModuleInfo, ProcInfo, GoalInfo,
> + SharingAs),
> + ProjectedLiveData = livedata_project(CalleeArgs, LiveData),
> + (
> + % Given the preconditions, livedata wil not be empty, and
s/wil/will/
I suggest adding a sanity checking that verifys those preconditions.
> + % reuse_as contains at least one reuse condition.
> + reuse_as_satisfied(ModuleInfo, ProcInfo, ProjectedLiveData,
> + SharingAs, set.to_sorted_list(AnalysisInfo ^ static_vars),
> + ActualReuseAs)
> + ->
> + LuData = list.map(datastruct_init,
> + set.to_sorted_list(set.union(goal_info_get_lfu(GoalInfo),
> + goal_info_get_lbu(GoalInfo)))),
> + NewReuseAs = reuse_as_from_called_procedure_to_local_reuse_as(
> + ModuleInfo, ProcInfo, BaseInfo ^ headvars, LuData, SharingAs,
> + ActualReuseAs)
> + ;
> + NewReuseAs = reuse_as_init % no reuse
> + ).
> +
...
> Index: compiler/structure_sharing.domain.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/structure_sharing.domain.m,v
> retrieving revision 1.8
> diff -u -d -r1.8 structure_sharing.domain.m
> --- compiler/structure_sharing.domain.m 10 May 2006 10:56:57 -0000 1.8
> +++ compiler/structure_sharing.domain.m 18 May 2006 12:01:17 -0000
> @@ -87,7 +87,7 @@
>
> % Return a short description of the sharing information.
> %
> -:- func short_description(sharing_as) = string.
> +:- func sharing_as_short_description(sharing_as) = string.
>
> % Projection operation.
> % This operation reduces the sharing information to information
> @@ -98,6 +98,7 @@
> %
> :- pred sharing_as_project(prog_vars::in,
> sharing_as::in, sharing_as::out) is det.
> +:- func sharing_as_project(prog_vars, sharing_as) = sharing_as.
> :- pred sharing_as_project_set(set(prog_var)::in,
> sharing_as::in, sharing_as::out) is det.
>
> @@ -113,10 +114,11 @@
> % ActualVars, ActualTypes, ActualTVarset, FormalSharing, ActualSharing):
> %
> % Renaming of the formal description of data structure sharing to the
> - % actual description of the sharing. The formal information is given
> - % using the module information. A list of variables and types is used as
> - % the actual variables and types.
> - % recorded in the module info.
> + % actual description of the sharing. The information about the formal
> + % variables needs to be extracted from the module information.
> + % A list of variables and types is used as the actual variables and types.
> + % The type variables set in the actual context must also be specified.
> + %
> %
> :- pred sharing_as_rename_using_module_info(module_info::in,
> pred_proc_id::in, prog_vars::in, list(mer_type)::in, tvarset::in,
> @@ -175,6 +177,8 @@
> %
> :- func extend_datastruct(module_info, proc_info, sharing_as, datastruct)
> = list(datastruct).
> +:- func extend_datastructs(module_info, proc_info, sharing_as,
> + list(datastruct)) = list(datastruct).
>
> % apply_widening(ModuleInfo, ProcInfo, WideningLimit, WideningDone,
> % SharingIn, SharingOut):
> @@ -230,6 +234,15 @@
>
> %-----------------------------------------------------------------------------%
>
> + % Lookup the sharing information of a called procedure (given its
> + % pred_id and proc_id), and combine it with the already existing
s/already/any/?
> + % sharing information.
> + %
> +:- pred lookup_sharing_and_comb(module_info::in, proc_info::in,
> + sharing_as_table::in, pred_id::in, proc_id::in, prog_vars::in,
> + sharing_as::in, sharing_as::out) is det.
Julien.
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list