[m-rev.] For review: Filling in rbmm_goal_info field in goal_info
Quan Phan
quan.phan at cs.kuleuven.be
Wed Aug 15 10:39:01 AEST 2007
Hi,
Estimate hours taken: 15h.
Branch: main.
Implement the analysis 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.rbmm_goal_info_analysis.m:
New file that contains the implementation of the analysis.
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 seperate 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 allocation 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 --------------
? .hlds_goal.m.swp
? .rbmm.points_to_analysis.m.swp
? diff.19.35
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 14 Aug 2007 23:41:09 -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.430
diff -u -r1.430 hlds_out.m
--- hlds_out.m 13 Aug 2007 03:01:40 -0000 1.430
+++ hlds_out.m 14 Aug 2007 23:41:10 -0000
@@ -1353,6 +1353,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 14 Aug 2007 23:41:11 -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.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 14 Aug 2007 23:41:11 -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 14 Aug 2007 23:41:11 -0000
@@ -25,6 +25,7 @@
:- include_module points_to_analysis.
:- include_module points_to_graph.
:- include_module points_to_info.
+:- include_module rbmm_goal_info_analysis.
:- 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.rbmm_goal_info_analysis.
:- 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: rbmm.rbmm_goal_info_analysis.m
===================================================================
RCS file: rbmm.rbmm_goal_info_analysis.m
diff -N rbmm.rbmm_goal_info_analysis.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ rbmm.rbmm_goal_info_analysis.m 14 Aug 2007 23:41:11 -0000
@@ -0,0 +1,488 @@
+%-----------------------------------------------------------------------------%
+% 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.rbmm_goal_info_analysis.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
+% support for region-based memory management.
+%
+%-----------------------------------------------------------------------------%
+
+:- module transform_hlds.rbmm.rbmm_goal_info_analysis.
+:- 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.
+
+%-----------------------------------------------------------------------------%
+%
+% rbmm_goal_info analysis.
+%
+
+ % We need to collect this pieces of information for the procedures which
+ % have been region-analyzed. Therefore we can use one of the resulting
+ % tables from previous phases for the PPId. The use of
+ % ActualRegionArgumentTable here is convenient because we also need the
+ % information about actual region arguments in this analysis.
+ %
+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_disjunction(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 that for nondet disjunction.
+ 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),
+ compute_rbmm_info_switch(Cases, 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),
+ Else = hlds_goal(_, ElseInfo),
+ RbmmInfo = goal_info_get_rbmm(ElseInfo),
+ goal_info_set_maybe_rbmm(yes(RbmmInfo), !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 disjunction are those
+ % allocated into by any disjuncts AND EXIST ...
+ % The regions that are read from inside this disjunction are those that
+ % are read from by any disjuncts AND EXIST ...
+ %
+:- pred compute_rbmm_info_disjunction(list(hlds_goal)::in,
+ rbmm_goal_info::in, rbmm_goal_info::out) is det.
+
+compute_rbmm_info_disjunction([], !RbmmInfo).
+compute_rbmm_info_disjunction([Disj | Disjs], !RbmmInfo) :-
+ Disj = hlds_goal(_, DInfo),
+ DRbmmInfo = goal_info_get_rbmm(DInfo),
+ DRbmmInfo = rbmm_goal_info(_, _, _, DAllocatedInto, DUsed),
+ !.RbmmInfo = rbmm_goal_info(Created, Removed, Carried, AllocatedInto0,
+ Used0),
+ set.difference(set.union(DAllocatedInto, AllocatedInto0), Created,
+ AllocatedInto),
+ set.difference(set.union(DUsed, Used0), Created, Used),
+ !:RbmmInfo = rbmm_goal_info(Created, Removed, Carried, AllocatedInto,
+ Used),
+ compute_rbmm_info_disjunction(Disjs, !RbmmInfo).
+
+ % The process here is similar to that for nondet disjunction.
+ %
+:- pred compute_rbmm_info_switch(list(case)::in, rbmm_goal_info::in,
+ rbmm_goal_info::out) is det.
+
+compute_rbmm_info_switch([], !SwitchRbmmInfo).
+compute_rbmm_info_switch([Case | Cases], !SwitchRbmmInfo) :-
+ Case = case(_, Goal),
+ Goal = hlds_goal(_, Info),
+ CaseRbmmInfo = goal_info_get_rbmm(Info),
+ CaseRbmmInfo = rbmm_goal_info(_, _, _, CaseAllocatedInto, CaseUsed),
+ !.SwitchRbmmInfo = rbmm_goal_info(Created, Removed, Carried,
+ AllocatedInto0, Used0),
+ set.difference(set.union(CaseAllocatedInto, AllocatedInto0), Created,
+ AllocatedInto),
+ set.difference(set.union(CaseUsed, Used0), Created, Used),
+ !:SwitchRbmmInfo = rbmm_goal_info(Created, Removed, Carried,
+ AllocatedInto, Used),
+ compute_rbmm_info_switch(Cases, !SwitchRbmmInfo).
+
+:- 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:"
+ ++ " encounter 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.rbmm_goal_info_analysis.m".
+
+%-----------------------------------------------------------------------------%
Index: rbmm.region_transformation.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.region_transformation.m,v
retrieving revision 1.3
diff -u -r1.3 rbmm.region_transformation.m
--- rbmm.region_transformation.m 23 Jul 2007 05:06:15 -0000 1.3
+++ rbmm.region_transformation.m 14 Aug 2007 23:41:11 -0000
@@ -59,7 +59,7 @@
%
:- pred region_transform(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::in,
+ proc_pp_actual_region_args_table::in,
renaming_table::in, renaming_table::in, region_instruction_table::in,
renaming_annotation_table::in, renaming_annotation_table::in,
name_to_prog_var_table::in, name_to_prog_var_table::out,
@@ -174,7 +174,7 @@
%
:- pred region_transform_pred(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::in,
+ proc_pp_actual_region_args_table::in,
renaming_table::in, renaming_table::in, region_instruction_table::in,
renaming_annotation_table::in, renaming_annotation_table::in,
pred_id::in, name_to_prog_var_table::in, name_to_prog_var_table::out,
@@ -208,7 +208,7 @@
%
:- pred region_transform_proc(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::in,
+ proc_pp_actual_region_args_table::in,
renaming_table::in, renaming_table::in, region_instruction_table::in,
renaming_annotation_table::in, renaming_annotation_table::in,
pred_id::in, proc_id::in, name_to_prog_var_table::in,
@@ -268,7 +268,7 @@
%
:- pred annotate_proc(module_info::in, pred_info::in, rpt_graph::in,
region_set::in, region_set::in, region_set::in,
- pp_pair_region_list_table::in, renaming_proc::in, renaming_proc::in,
+ pp_actual_region_args_table::in, renaming_proc::in, renaming_proc::in,
region_instruction_proc::in, renaming_annotation_proc::in,
renaming_annotation_proc::in, prog_varset::in, prog_varset::out,
vartypes::in, vartypes::out, list(prog_var)::in, list(prog_var)::out,
@@ -348,7 +348,7 @@
% caused by renaming and annotations needed for resurrection problem.
%
:- pred region_transform_goal(module_info::in, rpt_graph::in,
- renaming_proc::in, renaming_proc::in, pp_pair_region_list_table::in,
+ renaming_proc::in, renaming_proc::in, pp_actual_region_args_table::in,
region_instruction_proc::in, renaming_annotation_proc::in,
renaming_annotation_proc::in, hlds_goal::in, hlds_goal::out,
name_to_prog_var::in, name_to_prog_var::out,
@@ -415,7 +415,7 @@
).
:- pred region_transform_goal_expr(module_info::in, rpt_graph::in,
- renaming::in, renaming::in, pp_pair_region_list_table::in,
+ renaming::in, renaming::in, pp_actual_region_args_table::in,
program_point::in, hlds_goal_expr::in, hlds_goal_expr::out,
hlds_goal_info::in, hlds_goal_info::out, name_to_prog_var::in,
name_to_prog_var::out, prog_varset::in, prog_varset::out,
@@ -433,10 +433,10 @@
( map.search(ActualRegionArgProc, ProgPoint, ActualNodes0) ->
ActualNodes = ActualNodes0
;
- ActualNodes = pair([],[])
+ ActualNodes = actual_region_args([], [], [])
),
- ActualNodes = Ins - Outs,
- AllNodes = Ins ++ Outs,
+ ActualNodes = actual_region_args(Constants, Ins, Outs),
+ AllNodes = Constants ++ Ins ++ Outs,
list.map_foldl3(
node_to_var_with_both_renamings(Graph, ResurRenaming, IteRenaming),
AllNodes, ActualRegionArgs, !NameToVar, !VarSet, !VarTypes),
@@ -488,7 +488,7 @@
% Because an atomic goal is turned into a conjunction, we need to
% flatten its compounding conjunction if it is in one.
:- pred region_transform_compound_goal(module_info::in, rpt_graph::in,
- renaming_proc::in, renaming_proc::in, pp_pair_region_list_table::in,
+ renaming_proc::in, renaming_proc::in, pp_actual_region_args_table::in,
region_instruction_proc::in, renaming_annotation_proc::in,
renaming_annotation_proc::in, hlds_goal::in, hlds_goal::out,
name_to_prog_var::in, name_to_prog_var::out,
@@ -584,11 +584,7 @@
IsUnique, SubInfo),
get_node_by_variable(Graph, Var, Node),
NodeType = rptg_lookup_node_type(Graph, Node),
- (
- ( type_is_atomic(ModuleInfo, NodeType)
- ; is_dummy_argument_type(ModuleInfo, NodeType)
- )
- ->
+ ( type_not_stored_in_region(NodeType, ModuleInfo) ->
true
;
Name = rptg_lookup_region_name(Graph, Node),
@@ -623,7 +619,7 @@
% Finally, we try to flatten this new conjunction.
%
:- pred region_transform_case(module_info::in, rpt_graph::in,
- renaming_proc::in, renaming_proc::in, pp_pair_region_list_table::in,
+ renaming_proc::in, renaming_proc::in, pp_actual_region_args_table::in,
region_instruction_proc::in, renaming_annotation_proc::in,
renaming_annotation_proc::in, hlds_goal::in, case::in, case::out,
name_to_prog_var::in, name_to_prog_var::out,
Index: type_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/type_util.m,v
retrieving revision 1.179
diff -u -r1.179 type_util.m
--- type_util.m 9 Aug 2007 05:28:26 -0000 1.179
+++ type_util.m 14 Aug 2007 23:41:12 -0000
@@ -233,6 +233,11 @@
%
:- func cons_id_adjusted_arity(module_info, mer_type, cons_id) = int.
+ % Check if (the terms of) the type is NOT allocated in a region in
+ % region-based memory management.
+ %
+:- pred type_not_stored_in_region(mer_type::in, module_info::in) is semidet.
+
%-----------------------------------------------------------------------------%
% If possible, get the argument types for the cons_id. We need to pass in
@@ -955,6 +960,16 @@
%-----------------------------------------------------------------------------%
+type_not_stored_in_region(Type, ModuleInfo) :-
+ ( type_is_atomic(ModuleInfo, Type)
+ ; is_dummy_argument_type(ModuleInfo, Type)
+ ; Type = type_info_type
+ ; Type = type_ctor_info_type
+ ; type_is_var(Type)
+ ).
+
+%-----------------------------------------------------------------------------%
+
maybe_get_cons_id_arg_types(ModuleInfo, MaybeType, ConsId0, Arity,
MaybeTypes) :-
( ConsId0 = cons(_SymName, _) ->
Index: user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.540
diff -u -r1.540 user_guide.texi
--- user_guide.texi 13 Aug 2007 03:01:55 -0000 1.540
+++ user_guide.texi 14 Aug 2007 23:42:53 -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