[m-rev.] For review: Filling in rbmm_goal_info field in goal_info
Quan Phan
quan.phan at cs.kuleuven.be
Thu Sep 6 09:20:12 AEST 2007
Hi Julien,
I post everything again with the new diff.
Estimated hours taken: 15h.
Branch: main.
Implement a pass to fill in the rbmm_goal_info field in the goal_info
data structure. (Zoltan added this field several days ago.) This piece of
information will be used by the code generator to optimize the runtime support
needed for region-based memory management. It would be too much to describe
how the information will be used here. I am writing up the runtime support
needed for RBMM as the whole, which should include the explanation for this.
compiler/rbmm.add_rbmm_goal_infos.m:
New file that contains the implementation of the pass.
compiler/hlds_goal.m:
Add a function that initialize the rbmm_goal_info.
compiler/hlds_out.m:
Add an option, 'e' to --dump-hlds-options to print out rbmm_goal_info.
compiler/rbmm.m:
Include the new module and call the analysis.
compiler/rbmm.actual_region_arguments.m:
Change the data structure that represents actual region arguments to
have there separate lists for constant (carried), input (removed), and
output (created) regions.
compiler/type_util.m:
Add a predicate that check whether the terms of a type will be stored
in regions or not. This predicate must be consistent with the process
of generating allocations in unify_gen.m.
compiler/rbmm.interproc_region_lifetime.m:
Change to use the new predicate in type_util.m.
compiler/rbmm.region_transformation.m:
Change to conform to the change in actual_region_arguments.m.
Change to use the new predicate in type_util.m
doc/user_guide.texi:
Document the new option for --dump-hlds-options.
Provide the missing description for the existing option 'R'.
Regards,
Quan.
-------------- next part --------------
cvs diff: Diffing .
Index: hlds_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.180
diff -u -r1.180 hlds_goal.m
--- hlds_goal.m 7 Aug 2007 07:09:54 -0000 1.180
+++ hlds_goal.m 5 Sep 2007 18:46:00 -0000
@@ -882,6 +882,8 @@
used_regions :: set(prog_var)
).
+:- func rbmm_info_init = rbmm_goal_info.
+
:- type mode_constr_goal_info
---> mode_constr_goal_info(
% Inst_graph nodes that are reachable from variables
@@ -1684,6 +1686,9 @@
ctgc_goal_info_init = ctgc_goal_info(set.init, set.init, no_reuse_info).
+rbmm_info_init = rbmm_goal_info(set.init, set.init, set.init, set.init,
+ set.init).
+
goal_info_get_determinism(GoalInfo) = GoalInfo ^ gi_determinism.
goal_info_get_instmap_delta(GoalInfo) = GoalInfo ^ gi_instmap_delta.
goal_info_get_nonlocals(GoalInfo) = GoalInfo ^ gi_nonlocals.
Index: hlds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.432
diff -u -r1.432 hlds_out.m
--- hlds_out.m 20 Aug 2007 03:35:55 -0000 1.432
+++ hlds_out.m 5 Sep 2007 18:46:02 -0000
@@ -1354,6 +1354,37 @@
;
true
),
+ ( string.contains_char(Verbose, 'e') ->
+ MaybeRbmmInfo = goal_info_get_maybe_rbmm(GoalInfo),
+ (
+ MaybeRbmmInfo = yes(RbmmInfo),
+ RbmmInfo = rbmm_goal_info(Created, Removed, Carried, Alloc, Used),
+ write_indent(Indent, !IO),
+ io.write_string("% Created regions: ", !IO),
+ io.write_list(set.to_sorted_list(Created), ", ", io.write, !IO),
+ io.nl(!IO),
+ write_indent(Indent, !IO),
+ io.write_string("% Removed regions: ", !IO),
+ io.write_list(set.to_sorted_list(Removed), ", ", io.write, !IO),
+ io.nl(!IO),
+ write_indent(Indent, !IO),
+ io.write_string("% Carried regions: ", !IO),
+ io.write_list(set.to_sorted_list(Carried), ", ", io.write, !IO),
+ io.nl(!IO),
+ write_indent(Indent, !IO),
+ io.write_string("% Allocated into regions: ", !IO),
+ io.write_list(set.to_sorted_list(Alloc), ", ", io.write, !IO),
+ io.nl(!IO),
+ write_indent(Indent, !IO),
+ io.write_string("% Used regions: ", !IO),
+ io.write_list(set.to_sorted_list(Used), ", ", io.write, !IO),
+ io.nl(!IO)
+ ;
+ MaybeRbmmInfo = no
+ )
+ ;
+ true
+ ),
( string.contains_char(Verbose, 'z') ->
Purity = goal_info_get_purity(GoalInfo),
(
Index: rbmm.actual_region_arguments.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.actual_region_arguments.m,v
retrieving revision 1.3
diff -u -r1.3 rbmm.actual_region_arguments.m
--- rbmm.actual_region_arguments.m 23 Jul 2007 05:06:13 -0000 1.3
+++ rbmm.actual_region_arguments.m 5 Sep 2007 18:46:02 -0000
@@ -31,24 +31,28 @@
:- import_module list.
:- import_module map.
-:- import_module pair.
-:- type proc_pp_pair_region_list_table
+:- type proc_pp_actual_region_args_table
== map(
pred_proc_id,
- pp_pair_region_list_table
+ pp_actual_region_args_table
).
-:- type pp_pair_region_list_table
+:- type pp_actual_region_args_table
== map(
program_point,
- pair(list(rptg_node), list(rptg_node))
- % The first element is inputs, the second is outputs.
+ actual_region_args
).
+:- type actual_region_args
+ ---> actual_region_args(
+ list(rptg_node), % constant (carried) region arguments.
+ list(rptg_node), % inputs (removed).
+ list(rptg_node) % outputs (created).
+ ).
:- pred record_actual_region_arguments(module_info::in, rpta_info_table::in,
proc_region_set_table::in, proc_region_set_table::in,
- proc_region_set_table::in, proc_pp_pair_region_list_table::out) is det.
+ proc_region_set_table::in, proc_pp_actual_region_args_table::out) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -75,8 +79,8 @@
:- pred record_actual_region_arguments_pred(module_info::in,
rpta_info_table::in, proc_region_set_table::in,
proc_region_set_table::in, proc_region_set_table::in, pred_id::in,
- proc_pp_pair_region_list_table::in, proc_pp_pair_region_list_table::out)
- is det.
+ proc_pp_actual_region_args_table::in,
+ proc_pp_actual_region_args_table::out) is det.
record_actual_region_arguments_pred(ModuleInfo, RptaInfoTable,
ConstantRTable, DeadRTable, BornRTable, PredId,
@@ -90,8 +94,8 @@
:- pred record_actual_region_arguments_proc(module_info::in, pred_id::in,
rpta_info_table::in, proc_region_set_table::in,
proc_region_set_table::in, proc_region_set_table::in, proc_id::in,
- proc_pp_pair_region_list_table::in, proc_pp_pair_region_list_table::out)
- is det.
+ proc_pp_actual_region_args_table::in,
+ proc_pp_actual_region_args_table::out) is det.
record_actual_region_arguments_proc(ModuleInfo, PredId, RptaInfoTable,
ConstantRTable, DeadRTable, BornRTable, ProcId,
@@ -112,7 +116,7 @@
:- pred record_actual_region_arguments_goal(module_info::in,
pred_proc_id::in, rpta_info_table::in, proc_region_set_table::in,
proc_region_set_table::in, proc_region_set_table::in, hlds_goal::in,
- pp_pair_region_list_table::in, pp_pair_region_list_table::out) is det.
+ pp_actual_region_args_table::in, pp_actual_region_args_table::out) is det.
record_actual_region_arguments_goal(ModuleInfo, PPId, RptaInfoTable,
ConstantRTable, DeadRTable, BornRTable, Goal,
@@ -126,7 +130,7 @@
hlds_goal_info::in, module_info::in, pred_proc_id::in,
rpta_info_table::in, proc_region_set_table::in,
proc_region_set_table::in, proc_region_set_table::in,
- pp_pair_region_list_table::in, pp_pair_region_list_table::out) is det.
+ pp_actual_region_args_table::in, pp_actual_region_args_table::out) is det.
record_actual_region_arguments_expr(conj(_, Conjs), _, ModuleInfo, PPId,
RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
@@ -192,7 +196,7 @@
:- pred record_actual_region_arguments_case(module_info::in,
pred_proc_id::in, rpta_info_table::in, proc_region_set_table::in,
proc_region_set_table::in, proc_region_set_table::in, case::in,
- pp_pair_region_list_table::in, pp_pair_region_list_table::out) is det.
+ pp_actual_region_args_table::in, pp_actual_region_args_table::out) is det.
record_actual_region_arguments_case(ModuleInfo, PPId, RptaInfoTable,
ConstantRTable, DeadRTable, BornRTable, Case, !ActualRegionArgProc) :-
@@ -218,7 +222,7 @@
program_point::in, pred_proc_id::in,
rpta_info_table::in, proc_region_set_table::in,
proc_region_set_table::in, proc_region_set_table::in,
- pp_pair_region_list_table::in, pp_pair_region_list_table::out) is det.
+ pp_actual_region_args_table::in, pp_actual_region_args_table::out) is det.
record_actual_region_arguments_call_site(CallerPPId, CallSite,
CalleePPId, RptaInfoTable, ConstantRTable, DeadRTable,
@@ -249,10 +253,9 @@
LActualBornR0),
list.reverse(LActualBornR0, LActualBornR),
- % Record in two groups: input region arguments composed of constants and
- % deads, and output ones which are borns.
- Ins = LActualConstantR ++ LActualDeadR,
- svmap.det_insert(CallSite, Ins - LActualBornR, !ActualRegionArgProc).
+ svmap.det_insert(CallSite,
+ actual_region_args(LActualConstantR, LActualDeadR, LActualBornR),
+ !ActualRegionArgProc).
:- pred find_actual_param(map(rptg_node, rptg_node)::in, rptg_node::in,
list(rptg_node)::in, list(rptg_node)::out) is det.
Index: rbmm.add_rbmm_goal_infos.m
===================================================================
RCS file: rbmm.add_rbmm_goal_infos.m
diff -N rbmm.add_rbmm_goal_infos.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ rbmm.add_rbmm_goal_infos.m 5 Sep 2007 18:46:03 -0000
@@ -0,0 +1,504 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2007 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.add_rbmm_goal_infos.m.
+% Main author: Quan Phan.
+%
+% This module fills in rbmm_goal_info field in hlds_goal_extra_info data
+% structure. The details of this information can be read in hlds_goal.m.
+%
+% This information is used by the code generator to optimize the runtime
+% region support for backtracking in region-based memory management.
+%
+% To support programs with backtracking in region-based memory management we
+% have to deal with region resurrection (i.e., a region is dead during forward
+% execution but is still needed when the program backtracks) and we may also
+% want to do instant reclaiming when backtracking happens. In Mercury, the
+% support is needed for if-then-else, nondet disjunction and commit context.
+% This runtime support certainly incurs runtime overhead to programs therefore
+% we would like to pay for it only when we actually need it. For example, if
+% we know that the condition of an if-then-else does not allocate memory into
+% any existing regions, does not create any regions nor destroy any regions,
+% then we do not need to provide support for the if-then-else. This situation
+% is very often the case with if-then-elses therefore if we can exploit it we
+% will hopefully boost the performance of region-based memory management. The
+% rbmm_goal_info gives the code generator the information which is needed to
+% fulfill this optimization.
+%
+% XXX More information about the advanced runtime support for backtracking
+% should be documented or found somewhere but it is not available yet because
+% it is still in experimental state. We should fix this when it is more
+% stable.
+%-----------------------------------------------------------------------------%
+
+:- module transform_hlds.rbmm.add_rbmm_goal_infos.
+:- interface.
+
+:- import_module hlds.
+:- import_module hlds.hlds_module.
+:- import_module transform_hlds.rbmm.actual_region_arguments.
+:- import_module transform_hlds.rbmm.points_to_info.
+:- import_module transform_hlds.rbmm.region_resurrection_renaming.
+:- import_module transform_hlds.rbmm.region_transformation.
+
+:- pred collect_rbmm_goal_info(rpta_info_table::in,
+ proc_pp_actual_region_args_table::in, renaming_table::in,
+ renaming_table::in, name_to_prog_var_table::in,
+ module_info::in, module_info::out) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module check_hlds.
+:- import_module check_hlds.goal_path.
+:- import_module check_hlds.type_util.
+:- import_module hlds.hlds_goal.
+:- import_module hlds.hlds_pred.
+:- import_module libs.
+:- import_module libs.compiler_util.
+:- import_module mdbcomp.
+:- import_module mdbcomp.prim_data.
+:- import_module parse_tree.
+:- import_module parse_tree.prog_data.
+:- import_module parse_tree.prog_type.
+:- import_module transform_hlds.rbmm.points_to_graph.
+:- import_module transform_hlds.smm_common.
+
+:- import_module string.
+:- import_module list.
+:- import_module map.
+:- import_module maybe.
+:- import_module set.
+
+%-----------------------------------------------------------------------------%
+%
+% Collect rbmm_goal_info.
+%
+
+ % It only makes sense to collect rbmm_goal_info for the procedures
+ % which have been region-analyzed. To find such procedures we can use one
+ % of the result tables of any previous region analyses.
+ % Note: The use of ActualRegionArgumentTable here is convenient because
+ % apart from the procedure id, we also need the information about actual
+ % region arguments in this pass.
+ %
+collect_rbmm_goal_info(RptaInfoTable, ActualRegionArgumentTable,
+ ResurRenamingTable, IteRenamingTable, NameToRegionVarTable,
+ !ModuleInfo) :-
+ map.foldl(collect_rbmm_goal_info_proc(RptaInfoTable, ResurRenamingTable,
+ IteRenamingTable, NameToRegionVarTable), ActualRegionArgumentTable,
+ !ModuleInfo).
+
+:- pred collect_rbmm_goal_info_proc(rpta_info_table::in,
+ renaming_table::in, renaming_table::in, name_to_prog_var_table::in,
+ pred_proc_id::in, pp_actual_region_args_table::in,
+ module_info::in, module_info::out) is det.
+
+collect_rbmm_goal_info_proc(RptaInfoTable, ResurRenamingTable,
+ IteRenamingTable, NameToRegionVarTable, PPId, ActualRegionsArgsProc,
+ !ModuleInfo) :-
+ module_info_pred_proc_info(!.ModuleInfo, PPId, PredInfo, ProcInfo0),
+ proc_info_get_goal(ProcInfo0, Body0),
+ map.lookup(RptaInfoTable, PPId, RptaInfo),
+ RptaInfo = rpta_info(Graph, _),
+ ( map.search(ResurRenamingTable, PPId, ResurRenamingProc0) ->
+ ResurRenamingProc = ResurRenamingProc0
+ ;
+ ResurRenamingProc = map.init
+ ),
+ ( map.search(IteRenamingTable, PPId, IteRenamingProc0) ->
+ IteRenamingProc = IteRenamingProc0
+ ;
+ IteRenamingProc = map.init
+ ),
+ map.lookup(NameToRegionVarTable, PPId, NameToRegionVarProc),
+ collect_rbmm_goal_info_goal(!.ModuleInfo, ProcInfo0, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, Body0, Body),
+ proc_info_set_goal(Body, ProcInfo0, ProcInfo),
+ module_info_set_pred_proc_info(PPId, PredInfo, ProcInfo, !ModuleInfo).
+
+:- pred collect_rbmm_goal_info_goal(module_info::in, proc_info::in,
+ rpt_graph::in, pp_actual_region_args_table::in, renaming_proc::in,
+ renaming_proc::in, name_to_prog_var::in,
+ hlds_goal::in, hlds_goal::out) is det.
+
+collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, !Goal) :-
+ !.Goal = hlds_goal(Expr0, Info0),
+ collect_rbmm_goal_info_goal_expr(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, Expr0, Expr, Info0, Info),
+ !:Goal = hlds_goal(Expr, Info).
+
+:- pred collect_rbmm_goal_info_goal_expr(module_info::in, proc_info::in,
+ rpt_graph::in, pp_actual_region_args_table::in, renaming_proc::in,
+ renaming_proc::in, name_to_prog_var::in,
+ hlds_goal_expr::in, hlds_goal_expr::out,
+ hlds_goal_info::in, hlds_goal_info::out) is det.
+
+collect_rbmm_goal_info_goal_expr(ModuleInfo, _, Graph, _, ResurRenamingProc,
+ IteRenamingProc, NameToRegionVar, !Expr, !Info) :-
+ !.Expr = unify(_, _, _, Unification, _),
+ ProgPoint = program_point_init(!.Info),
+ ( map.search(ResurRenamingProc, ProgPoint, ResurRenaming0) ->
+ ResurRenaming = ResurRenaming0
+ ;
+ ResurRenaming = map.init
+ ),
+ ( map.search(IteRenamingProc, ProgPoint, IteRenaming0) ->
+ IteRenaming = IteRenaming0
+ ;
+ IteRenaming = map.init
+ ),
+ collect_rbmm_goal_info_unification(Unification, ModuleInfo, Graph,
+ ResurRenaming, IteRenaming, NameToRegionVar, !Info).
+
+collect_rbmm_goal_info_goal_expr(ModuleInfo, ProcInfo, _,
+ ActualRegionArgumentProc, _, _, _, !Expr, !Info) :-
+ !.Expr = plain_call(PredId, ProcId, Args, _, _, _),
+ CalleePPId = proc(PredId, ProcId),
+ (
+ is_create_region_call(!.Expr, ModuleInfo, CreatedRegion)
+ ->
+ RbmmGoalInfo = rbmm_goal_info(set.make_singleton_set(CreatedRegion),
+ set.init, set.init, set.init, set.init),
+ goal_info_set_maybe_rbmm(yes(RbmmGoalInfo), !Info)
+ ;
+ is_remove_region_call(!.Expr, ModuleInfo, RemovedRegion)
+ ->
+ RbmmGoalInfo = rbmm_goal_info(set.init,
+ set.make_singleton_set(RemovedRegion), set.init, set.init,
+ set.init),
+ goal_info_set_maybe_rbmm(yes(RbmmGoalInfo), !Info)
+ ;
+ some_are_special_preds([CalleePPId], ModuleInfo)
+ ->
+ goal_info_set_maybe_rbmm(yes(rbmm_info_init), !Info)
+ ;
+ CallSite = program_point_init(!.Info),
+ proc_info_get_vartypes(ProcInfo, VarTypes),
+ RegionArgs = list.filter(is_region_var(VarTypes), Args),
+ map.lookup(ActualRegionArgumentProc, CallSite, ActualRegionArgs),
+ ActualRegionArgs = actual_region_args(Constants, Inputs, _Outputs),
+ list.det_split_list(list.length(Constants), RegionArgs,
+ CarriedRegions, RemovedAndCreated),
+ list.det_split_list(list.length(Inputs), RemovedAndCreated,
+ RemovedRegions, CreatedRegions),
+ % XXX We safely approximate that RemovedRegions and CarriedRegions
+ % are allocated into and read from in this call.
+ AllocatedIntoAndReadFrom =
+ set.from_list(RemovedRegions ++ CarriedRegions),
+ RbmmGoalInfo = rbmm_goal_info(set.from_list(CreatedRegions),
+ set.from_list(RemovedRegions), set.from_list(CarriedRegions),
+ AllocatedIntoAndReadFrom, AllocatedIntoAndReadFrom),
+ goal_info_set_maybe_rbmm(yes(RbmmGoalInfo), !Info)
+ ).
+
+ % We do not handle generic calls and calls to foreign procs in RBMM yet,
+ % so if a program has any of them the RBMM compilation will fail before
+ % reaching here. We just call sorry now so that they are not
+ % forgotten when we deal with these explicitly in the future.
+ %
+collect_rbmm_goal_info_goal_expr(_, _, _, _, _, _, _, !Expr, !Info) :-
+ !.Expr = generic_call(_, _, _, _),
+ sorry(this_file,
+ "collect_rbmm_goal_info_goal_expr: generic call not handled").
+collect_rbmm_goal_info_goal_expr(_, _, _, _, _, _, _, !Expr, !Info) :-
+ !.Expr = call_foreign_proc(_, _, _, _, _, _, _),
+ sorry(this_file,
+ "collect_rbmm_goal_info_goal_expr: call to foreign proc not handled").
+
+collect_rbmm_goal_info_goal_expr(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, !Expr, !Info) :-
+ !.Expr = conj(ConjType, Conjs0),
+ list.map(collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc), Conjs0, Conjs),
+ !:Expr = conj(ConjType, Conjs),
+
+ % Calculate created, removed, allocated into, used regions.
+ compute_rbmm_info_conjunction(Conjs, rbmm_info_init, RbmmInfo0),
+
+ % Calculate carried regions.
+ % The carried regions are those that are NOT removed, NOT created by all
+ % the conjuncts.
+ RbmmInfo0 = rbmm_goal_info(Created, Removed, _, AllocatedInto, Used),
+ NonLocals = goal_info_get_nonlocals(!.Info),
+ proc_info_get_vartypes(ProcInfo, VarTypes),
+ NonLocalRegions = set.filter(is_region_var(VarTypes), NonLocals),
+ set.difference(NonLocalRegions, set.union(Created, Removed), Carried),
+ RbmmInfo = rbmm_goal_info(Created, Removed, Carried, AllocatedInto, Used),
+ goal_info_set_maybe_rbmm(yes(RbmmInfo), !Info).
+
+collect_rbmm_goal_info_goal_expr(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, !Expr, !Info) :-
+ !.Expr = disj(Disjs0),
+ list.map(collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc), Disjs0, Disjs),
+ !:Expr = disj(Disjs),
+
+ (
+ Disjs = [],
+ goal_info_set_maybe_rbmm(yes(rbmm_info_init), !Info)
+ ;
+ % Well-modedness requires that each disjunct creates, removes and
+ % carries the same regions, which are also created, removed, carried
+ % by the disjunction.
+ Disjs = [hlds_goal(_, DInfo) | _],
+ DRbmmInfo = goal_info_get_rbmm(DInfo),
+ DRbmmInfo = rbmm_goal_info(Created, Removed, Carried, _, _),
+ RbmmInfo0 = rbmm_goal_info(Created, Removed, Carried, set.init,
+ set.init),
+
+ % Calculate allocated-into and used regions.
+ compute_rbmm_info_goals(Disjs, RbmmInfo0, RbmmInfo),
+ goal_info_set_maybe_rbmm(yes(RbmmInfo), !Info)
+ ).
+
+collect_rbmm_goal_info_goal_expr(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, !Expr, !Info) :-
+ !.Expr = switch(A, B, Cases0),
+ list.map(collect_rbmm_goal_info_case(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc), Cases0, Cases),
+ !:Expr = switch(A, B, Cases),
+ (
+ Cases = [],
+ unexpected(this_file, "collect_rbmm_goal_info_goal_expr: "
+ ++ "empty switch unexpected")
+ ;
+ % The process here is similar to the above code for disjunctions.
+ Cases = [Case | _],
+ Case = case(_, Goal),
+ Goal = hlds_goal(_, CaseInfo),
+ CaseRbmmInfo = goal_info_get_rbmm(CaseInfo),
+ CaseRbmmInfo = rbmm_goal_info(Created, Removed, Carried, _, _),
+ SwitchRbmmInfo0 = rbmm_goal_info(Created, Removed, Carried, set.init,
+ set.init),
+ list.foldl(
+ (pred(C::in, Gs0::in, Gs::out) is det :-
+ C = case(_, G),
+ Gs = [G | Gs0]
+ ), Cases, [], Goals),
+ compute_rbmm_info_goals(Goals, SwitchRbmmInfo0, SwitchRbmmInfo),
+ goal_info_set_maybe_rbmm(yes(SwitchRbmmInfo), !Info)
+ ).
+
+collect_rbmm_goal_info_goal_expr(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, !Expr, !Info) :-
+ !.Expr = negation(Goal0),
+ collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, Goal0, Goal),
+ !:Expr = negation(Goal),
+ Goal = hlds_goal(_, Info),
+ RbmmInfo = goal_info_get_rbmm(Info),
+ goal_info_set_maybe_rbmm(yes(RbmmInfo), !Info).
+
+collect_rbmm_goal_info_goal_expr(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, !Expr, !Info) :-
+ !.Expr = scope(Reason, Goal0),
+ collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, Goal0, Goal),
+ !:Expr = scope(Reason, Goal),
+ Goal = hlds_goal(_, Info),
+ RbmmInfo = goal_info_get_rbmm(Info),
+ goal_info_set_maybe_rbmm(yes(RbmmInfo), !Info).
+
+collect_rbmm_goal_info_goal_expr(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, !Expr, !Info) :-
+ !.Expr = if_then_else(A, Cond0, Then0, Else0),
+ collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, Cond0, Cond),
+ collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, Then0, Then),
+ collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, Else0, Else),
+ !:Expr = if_then_else(A, Cond, Then, Else),
+
+ % Well-modedness requires that the (cond, then) and the else parts create,
+ % remove and carry the same regions, which are also created, removed,
+ % carried by the if-then-else.
+ Else = hlds_goal(_, ElseInfo),
+ ElseRbmmInfo = goal_info_get_rbmm(ElseInfo),
+ ElseRbmmInfo = rbmm_goal_info(Created, Removed, Carried, _, _),
+ IteRbmmInfo0 = rbmm_goal_info(Created, Removed, Carried, set.init,
+ set.init),
+ compute_rbmm_info_goals([Cond, Then, Else], IteRbmmInfo0, IteRbmmInfo),
+ goal_info_set_maybe_rbmm(yes(IteRbmmInfo), !Info).
+
+collect_rbmm_goal_info_goal_expr(_, _, _, _, _, _, _, !Expr, !Info) :-
+ !.Expr = shorthand(_),
+ unexpected(this_file,
+ "collect_rbmm_goal_info_goal_expr: shorthand unexpected").
+
+ % The regions that are created inside this conjunction are all that are
+ % created inside each conjunct.
+ % The regions that are removed inside this conjunction are all that are
+ % removed inside each conjunct AND EXIST before the conjunction, i.e.,
+ % not being created in the condition.
+ % The regions that are allocated into inside this conjunction are those
+ % allocated into by any conjuncts AND EXIST ...
+ % The regions that are read from inside this conjunction are those that
+ % are read from by any conjuncts AND EXIST ...
+ %
+:- pred compute_rbmm_info_conjunction(list(hlds_goal)::in,
+ rbmm_goal_info::in, rbmm_goal_info::out) is det.
+
+compute_rbmm_info_conjunction([], !RbmmInfo).
+compute_rbmm_info_conjunction([Conj | Conjs], !RbmmInfo) :-
+ Conj = hlds_goal(_, CInfo),
+ CRbmmInfo = goal_info_get_rbmm(CInfo),
+ CRbmmInfo = rbmm_goal_info(CCreated, CRemoved, _, CAllocatedInto, CUsed),
+ !.RbmmInfo = rbmm_goal_info(Created0, Removed0, Carried, AllocatedInto0,
+ Used0),
+ set.union(CCreated, Created0, Created),
+ set.difference(set.union(CRemoved, Removed0), Created, Removed),
+ set.difference(set.union(CAllocatedInto, AllocatedInto0), Created,
+ AllocatedInto),
+ set.difference(set.union(CUsed, Used0), Created, Used),
+
+ !:RbmmInfo = rbmm_goal_info(Created, Removed, Carried, AllocatedInto,
+ Used),
+ compute_rbmm_info_conjunction(Conjs, !RbmmInfo).
+
+ % The regions that are allocated into inside this list of goals are those
+ % allocated into by any goals AND EXIST ...
+ % The regions that are read from inside this list of goals are those that
+ % are read from by any goals AND EXIST ...
+ %
+ % This predicate are used to compute the above information for the goals
+ % in disjunction, cases, and if-then-else.
+ %
+:- pred compute_rbmm_info_goals(list(hlds_goal)::in,
+ rbmm_goal_info::in, rbmm_goal_info::out) is det.
+
+compute_rbmm_info_goals([], !RbmmInfo).
+compute_rbmm_info_goals([Goal | Goals], !RbmmInfo) :-
+ Goal = hlds_goal(_, Info),
+ GoalRbmmInfo = goal_info_get_rbmm(Info),
+ GoalRbmmInfo = rbmm_goal_info(_, _, _, GoalAllocatedInto, GoalUsed),
+ !.RbmmInfo = rbmm_goal_info(Created, Removed, Carried, AllocatedInto0,
+ Used0),
+ set.difference(set.union(GoalAllocatedInto, AllocatedInto0), Created,
+ AllocatedInto),
+ set.difference(set.union(GoalUsed, Used0), Created, Used),
+ !:RbmmInfo = rbmm_goal_info(Created, Removed, Carried, AllocatedInto,
+ Used),
+ compute_rbmm_info_goals(Goals, !RbmmInfo).
+
+:- pred collect_rbmm_goal_info_unification(unification::in, module_info::in,
+ rpt_graph::in, renaming::in, renaming::in, name_to_prog_var::in,
+ hlds_goal_info::in, hlds_goal_info::out) is det.
+
+collect_rbmm_goal_info_unification(Unification, ModuleInfo, Graph,
+ ResurRenaming, IteRenaming, RegionNameToVar, !Info) :-
+ (
+ Unification = construct(_, _, _, _, HowToConstruct, _, _),
+ (
+ HowToConstruct = construct_in_region(AllocatedIntoRegion),
+ RbmmInfo = rbmm_goal_info(set.init, set.init,
+ set.make_singleton_set(AllocatedIntoRegion),
+ set.make_singleton_set(AllocatedIntoRegion), set.init),
+ goal_info_set_maybe_rbmm(yes(RbmmInfo), !Info)
+ ;
+ ( HowToConstruct = construct_statically(_)
+ ; HowToConstruct = construct_dynamically
+ ; HowToConstruct = reuse_cell(_)
+ ),
+ goal_info_set_maybe_rbmm(yes(rbmm_info_init), !Info)
+ )
+ ;
+ Unification = deconstruct(DeconsCellVar, _, _, _, _, _),
+ get_node_by_variable(Graph, DeconsCellVar, Node),
+ NodeType = rptg_lookup_node_type(Graph, Node),
+ ( if type_not_stored_in_region(NodeType, ModuleInfo)
+ then
+ goal_info_set_maybe_rbmm(yes(rbmm_info_init), !Info)
+ else
+ OriginalName = rptg_lookup_region_name(Graph, Node),
+ ( map.search(ResurRenaming, OriginalName, ResurName) ->
+ Name = ResurName
+ ; map.search(IteRenaming, OriginalName, IteName) ->
+ Name = IteName
+ ;
+ Name = OriginalName
+ ),
+ map.lookup(RegionNameToVar, Name, RegionVar),
+ RbmmInfo = rbmm_goal_info(set.init, set.init,
+ set.make_singleton_set(RegionVar),
+ set.init, set.make_singleton_set(RegionVar)),
+ goal_info_set_maybe_rbmm(yes(RbmmInfo), !Info)
+ )
+ ;
+ ( Unification = assign(_, _)
+ ; Unification = simple_test(_, _)
+ ),
+ goal_info_set_maybe_rbmm(yes(rbmm_goal_info(set.init, set.init,
+ set.init, set.init, set.init)), !Info)
+ ;
+ Unification = complicated_unify(_, _, _),
+ unexpected(this_file, "collect_rbmm_goal_info_unification:"
+ ++ " encountered complicated unification")
+ ).
+
+:- pred is_remove_region_call(hlds_goal_expr::in, module_info::in,
+ prog_var::out) is semidet.
+
+is_remove_region_call(plain_call(PredId, _ProcId, Args, _, _, _),
+ ModuleInfo, RemovedRegion) :-
+ module_info_pred_info(ModuleInfo, PredId, PredInfo),
+ pred_info_module(PredInfo) = mercury_region_builtin_module,
+ pred_info_name(PredInfo) = remove_region_pred_name,
+ Args = [RemovedRegion].
+
+:- pred is_create_region_call(hlds_goal_expr::in, module_info::in,
+ prog_var::out) is semidet.
+
+is_create_region_call(plain_call(PredId, _ProcId, Args, _, _, _),
+ ModuleInfo, CreatedRegion) :-
+ module_info_pred_info(ModuleInfo, PredId, PredInfo),
+ pred_info_module(PredInfo) = mercury_region_builtin_module,
+ pred_info_name(PredInfo) = create_region_pred_name,
+ Args = [CreatedRegion].
+
+:- pred collect_rbmm_goal_info_case(module_info::in, proc_info::in,
+ rpt_graph::in, pp_actual_region_args_table::in, renaming_proc::in,
+ renaming_proc::in, name_to_prog_var::in, case::in, case::out) is det.
+
+collect_rbmm_goal_info_case(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, !Case) :-
+ !.Case = case(Functor, Goal0),
+ collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
+ ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
+ NameToRegionVarProc, Goal0, Goal),
+ !:Case = case(Functor, Goal).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "rbmm.add_rbmm_goal_infos.m".
+
+%-----------------------------------------------------------------------------%
Index: rbmm.interproc_region_lifetime.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.interproc_region_lifetime.m,v
retrieving revision 1.3
diff -u -r1.3 rbmm.interproc_region_lifetime.m
--- rbmm.interproc_region_lifetime.m 23 Jul 2007 05:06:13 -0000 1.3
+++ rbmm.interproc_region_lifetime.m 5 Sep 2007 18:46:03 -0000
@@ -69,6 +69,7 @@
:- import_module parse_tree.
:- import_module parse_tree.mercury_to_mercury.
:- import_module parse_tree.prog_data.
+:- import_module parse_tree.prog_type.
:- import_module transform_hlds.dependency_graph.
:- import_module transform_hlds.rbmm.points_to_graph.
:- import_module transform_hlds.smm_common.
@@ -590,11 +591,7 @@
retain_non_primitive_regions(ModuleInfo, Graph, Region, !RegionSet) :-
NodeType = rptg_lookup_node_type(Graph, Region),
- (
- ( type_is_atomic(ModuleInfo, NodeType)
- ; is_dummy_argument_type(ModuleInfo, NodeType)
- )
- ->
+ ( type_not_stored_in_region(NodeType, ModuleInfo) ->
true
;
svset.insert(Region, !RegionSet)
Index: rbmm.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.m,v
retrieving revision 1.6
diff -u -r1.6 rbmm.m
--- rbmm.m 20 Jul 2007 08:09:53 -0000 1.6
+++ rbmm.m 5 Sep 2007 18:46:03 -0000
@@ -25,6 +25,7 @@
:- include_module points_to_analysis.
:- include_module points_to_graph.
:- include_module points_to_info.
+:- include_module add_rbmm_goal_infos.
:- include_module region_instruction.
:- include_module region_liveness_info.
:- include_module region_resurrection_renaming.
@@ -51,6 +52,7 @@
:- import_module transform_hlds.rbmm.live_region_analysis.
:- import_module transform_hlds.rbmm.live_variable_analysis.
:- import_module transform_hlds.rbmm.points_to_analysis.
+:- import_module transform_hlds.rbmm.add_rbmm_goal_infos.
:- import_module transform_hlds.rbmm.region_instruction.
:- import_module transform_hlds.rbmm.region_resurrection_renaming.
:- import_module transform_hlds.rbmm.region_transformation.
@@ -115,8 +117,12 @@
region_transform(RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
ActualRegionArgumentTable, ResurRenamingTable, IteRenamingTable,
RegionInstructionTable, ResurRenamingAnnoTable,
- IteRenamingAnnoTable, map.init, _NameToVarTable, !ModuleInfo).
+ IteRenamingAnnoTable, map.init, NameToVarTable, !ModuleInfo),
+
+ collect_rbmm_goal_info(RptaInfoTable, ActualRegionArgumentTable,
+ ResurRenamingTable, IteRenamingTable, NameToVarTable, !ModuleInfo).
%-----------------------------------------------------------------------------%
:- end_module transform_hlds.rbmm.
%-----------------------------------------------------------------------------%
Index: user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.542
diff -u -r1.542 user_guide.texi
--- user_guide.texi 29 Aug 2007 01:27:05 -0000 1.542
+++ user_guide.texi 5 Sep 2007 18:46:08 -0000
@@ -6771,6 +6771,7 @@
b - builtin flags on calls,
c - contexts of goals and types,
d - determinism of goals,
+e - created, removed, carried, allocated into, and used regions,
f - follow_vars sets of goals,
g - goal feature lists,
i - variables whose instantiation changes,
@@ -6792,7 +6793,8 @@
I - imported predicates,
M - mode and inst information,
P - path information,
-S - information about structure sharing
+R - live forward use, live backward use and reuse possibilities,
+S - information about structure sharing,
T - type and typeclass information,
U - unify and compare predicates,
Z - information about globals structs representing call and answer tables.
cvs diff: Diffing notes
More information about the reviews
mailing list