[m-rev.] A diff of adding a new option for RBMM
Quan Phan
quan.phan at cs.kuleuven.be
Sat Nov 28 02:50:09 AEDT 2009
Hi,
This diff has been reviewed by Zoltan.
Regards,
Quan.
compiler/options.m:
Add a new option that allows us to distinguish between the rbmm2 and rbmm3
versions of the system in the paper.
compiler/rbmm.add_rbmm_goal_infos.m:
Use the new option to decide whether to apply the optimization
that distinguishes rbmm3.
compiler/rbmm.points_to_graph.m:
Add a utility predicate needed by the new code in
rbmm.add_rbmm_goal_infos.m.
compiler/rbmm.region_arguments.m:
A new module that replaces rbmm.actual_region_arguments.m. It computes
the regions in one place, not in several.
compiler/rbmm.actual_region_arguments.m:
Remove this replaced module.
compiler/rbmm.m:
Replace the old module with the new one.
compiler/rbmm.points_to_analysis.m:
Apply rule T6 from my thesis.
compiler/rbmm.points_to_info.m:
Add meaningful names to some types.
compiler/rbmm.interproc_region_lifetime.m:
Use the new type name.
compiler/rbmm.region_transformation.m:
Use the new type name, and use the new data structure representing
procedure arguments.
cvs diff: Diffing .
Index: options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.660
diff -u -r1.660 options.m
--- options.m 30 Oct 2009 03:33:17 -0000 1.660
+++ options.m 28 Nov 2009 01:52:05 -0000
@@ -372,6 +372,7 @@
; extend_stacks_when_needed
; stack_segments
; use_regions
+ ; use_alloc_regions
; use_regions_debug
; use_regions_profiling
; source_to_source_debug
@@ -1247,6 +1248,7 @@
extend_stacks_when_needed - bool(no),
stack_segments - bool(no),
use_regions - bool(no),
+ use_alloc_regions - bool(yes),
use_regions_debug - bool(no),
use_regions_profiling - bool(no),
use_minimal_model_stack_copy - bool(no),
@@ -2112,6 +2114,7 @@
long_option("extend-stacks-when-needed", extend_stacks_when_needed).
long_option("stack-segments", stack_segments).
long_option("use-regions", use_regions).
+long_option("use-alloc-regions", use_alloc_regions).
long_option("use-regions-debug", use_regions_debug).
long_option("use-regions-profiling",use_regions_profiling).
% Data representation options
@@ -4201,6 +4204,9 @@
% should also document rbmmd rbmmp rbmmdp
%"--use-regions\t\t(grade modifier: `.rbmm')",
%"\tEnable support for region-based memory managment."
+ %"--use-alloc-regions",
+ %"\tCompute and use the exact set of regions",
+ %"\t that may be allocated into by a call."
]),
io.write_string("\n LLDS back-end compilation model options:\n"),
Index: rbmm.actual_region_arguments.m
===================================================================
RCS file: rbmm.actual_region_arguments.m
diff -N rbmm.actual_region_arguments.m
--- rbmm.actual_region_arguments.m 23 Dec 2008 01:37:40 -0000 1.4
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,268 +0,0 @@
-% -----------------------------------------------------------------------------%
-% vim: ft=mercury ts=4 sw=4 et
-%-----------------------------------------------------------------------------%
-% Copyright (C) 2007-2008 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.actual_region_arguments.m.
-% Main author: Quan Phan.
-%
-% We will pass regions as extra arguments in procedure calls. The extra formal
-% region arguments are already known from live region analysis.
-% This module derives the corresponding actual region arguments at call sites
-% in each procedure. This information will be used to extend the argument
-% lists of calls in the HLDS.
-
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-:- module transform_hlds.rbmm.actual_region_arguments.
-:- interface.
-
-:- import_module hlds.
-:- import_module hlds.hlds_module.
-:- import_module hlds.hlds_pred.
-:- import_module transform_hlds.rbmm.points_to_graph.
-:- import_module transform_hlds.rbmm.points_to_info.
-:- import_module transform_hlds.rbmm.region_liveness_info.
-:- import_module transform_hlds.smm_common.
-
-:- import_module list.
-:- import_module map.
-
-:- type proc_pp_actual_region_args_table
- == map(
- pred_proc_id,
- pp_actual_region_args_table
- ).
-
-:- type pp_actual_region_args_table
- == map(
- program_point,
- 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_actual_region_args_table::out) is det.
-
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-:- implementation.
-
-:- import_module check_hlds.
-:- import_module check_hlds.goal_path.
-:- import_module hlds.hlds_goal.
-:- import_module libs.
-:- import_module libs.compiler_util.
-
-:- import_module set.
-:- import_module string.
-:- import_module svmap.
-
-record_actual_region_arguments(ModuleInfo, RptaInfoTable, ConstantRTable,
- DeadRTable, BornRTable, ActualRegionArgTable) :-
- module_info_predids(PredIds, ModuleInfo, _),
- list.foldl(record_actual_region_arguments_pred(ModuleInfo,
- RptaInfoTable, ConstantRTable, DeadRTable, BornRTable),
- PredIds, map.init, ActualRegionArgTable).
-
-:- 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_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,
- !ActualRegionArgTable) :-
- module_info_pred_info(ModuleInfo, PredId, PredInfo),
- ProcIds = pred_info_non_imported_procids(PredInfo),
- list.foldl(record_actual_region_arguments_proc(ModuleInfo, PredId,
- RptaInfoTable, ConstantRTable, DeadRTable, BornRTable), ProcIds,
- !ActualRegionArgTable).
-
-:- 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_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,
- !ActualRegionArgTable) :-
- PPId = proc(PredId, ProcId),
- ( if some_are_special_preds([PPId], ModuleInfo)
- then true
- else
- module_info_proc_info(ModuleInfo, PPId, ProcInfo0),
- fill_goal_path_slots(ModuleInfo, ProcInfo0, ProcInfo),
- proc_info_get_goal(ProcInfo, Body),
- record_actual_region_arguments_goal(ModuleInfo, PPId,
- RptaInfoTable, ConstantRTable, DeadRTable, BornRTable, Body,
- map.init, ActualRegionArgProc),
- svmap.set(PPId, ActualRegionArgProc, !ActualRegionArgTable)
- ).
-
-:- 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_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, !ActualRegionArgProc) :-
- Goal = hlds_goal(Expr, Info),
- record_actual_region_arguments_expr(Expr, Info, ModuleInfo, PPId,
- RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
- !ActualRegionArgProc).
-
-:- pred record_actual_region_arguments_expr(hlds_goal_expr::in,
- 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_actual_region_args_table::in, pp_actual_region_args_table::out) is det.
-
-record_actual_region_arguments_expr(GoalExpr, GoalInfo, ModuleInfo, CallerPPId,
- RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
- !ActualRegionArgProc) :-
- (
- GoalExpr = plain_call(PredId, ProcId, _, _, _, _),
- CalleePPId = proc(PredId, ProcId),
- ( some_are_special_preds([CalleePPId], ModuleInfo) ->
- true
- ;
- CallSite = program_point_init(GoalInfo),
- record_actual_region_arguments_call_site(CallerPPId, CallSite,
- CalleePPId, RptaInfoTable, ConstantRTable, DeadRTable,
- BornRTable, !ActualRegionArgProc)
- )
- ;
- GoalExpr = conj(_, Conjuncts),
- list.foldl(
- record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
- RptaInfoTable, ConstantRTable, DeadRTable, BornRTable),
- Conjuncts, !ActualRegionArgProc)
- ;
- GoalExpr = disj(Disjuncts),
- list.foldl(
- record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
- RptaInfoTable, ConstantRTable, DeadRTable, BornRTable),
- Disjuncts, !ActualRegionArgProc)
- ;
- GoalExpr = if_then_else(_, Cond, Then, Else),
- record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
- RptaInfoTable, ConstantRTable, DeadRTable, BornRTable, Cond,
- !ActualRegionArgProc),
- record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
- RptaInfoTable, ConstantRTable, DeadRTable, BornRTable, Then,
- !ActualRegionArgProc),
- record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
- RptaInfoTable, ConstantRTable, DeadRTable, BornRTable, Else,
- !ActualRegionArgProc)
- ;
- GoalExpr = switch(_, _, Cases),
- list.foldl(
- record_actual_region_arguments_case(ModuleInfo, CallerPPId,
- RptaInfoTable, ConstantRTable, DeadRTable, BornRTable),
- Cases, !ActualRegionArgProc)
- ;
- GoalExpr = generic_call(_, _, _, _),
- sorry(this_file,
- "record_actual_region_arguments_expr: generic_call NYI")
- ;
- GoalExpr = call_foreign_proc(_, _, _, _, _, _, _),
- sorry(this_file,
- "record_actual_region_arguments_expr: call_foreign_proc NYI")
- ;
- GoalExpr = negation(SubGoal),
- record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
- RptaInfoTable, ConstantRTable, DeadRTable, BornRTable, SubGoal,
- !ActualRegionArgProc)
- ;
- GoalExpr = unify(_, _, _, _, _)
- ;
- GoalExpr = scope(_, SubGoal),
- % XXX We should special-case the handling of from_ground_term_construct
- % scopes.
- record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
- RptaInfoTable, ConstantRTable, DeadRTable, BornRTable, SubGoal,
- !ActualRegionArgProc)
- ;
- GoalExpr = shorthand(_),
- unexpected(this_file,
- "record_actual_region_arguments_expr: shorthand")
- ).
-
-:- 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_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) :-
- Case = case(_, _, Goal),
- record_actual_region_arguments_goal(ModuleInfo, PPId, RptaInfoTable,
- ConstantRTable, DeadRTable, BornRTable, Goal, !ActualRegionArgProc).
-
-:- pred record_actual_region_arguments_call_site(pred_proc_id::in,
- 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_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,
- BornRTable, !ActualRegionArgProc) :-
- map.lookup(ConstantRTable, CalleePPId, CalleeConstantR),
- map.lookup(DeadRTable, CalleePPId, CalleeDeadR),
- map.lookup(BornRTable, CalleePPId, CalleeBornR),
-
- map.lookup(RptaInfoTable, CallerPPId, CallerRptaInfo),
- CallerRptaInfo = rpta_info(_, CallerAlpha),
- map.lookup(CallerAlpha, CallSite, AlphaAtCallSite),
-
- % Actual constant region arguments.
- set.to_sorted_list(CalleeConstantR, LCalleeConstantR),
- list.foldl(find_actual_param(AlphaAtCallSite), LCalleeConstantR, [],
- LActualConstantR0),
- list.reverse(LActualConstantR0, LActualConstantR),
-
- % Actual dead region arguments.
- set.to_sorted_list(CalleeDeadR, LCalleeDeadR),
- list.foldl(find_actual_param(AlphaAtCallSite), LCalleeDeadR, [],
- LActualDeadR0),
- list.reverse(LActualDeadR0, LActualDeadR),
-
- % Actual born region arguments.
- set.to_sorted_list(CalleeBornR, LCalleeBornR),
- list.foldl(find_actual_param(AlphaAtCallSite), LCalleeBornR, [],
- LActualBornR0),
- list.reverse(LActualBornR0, LActualBornR),
-
- 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.
-
-find_actual_param(Alpha_PP, Formal, Actuals0, Actuals) :-
- map.lookup(Alpha_PP, Formal, Actual),
- Actuals = [Actual | Actuals0].
-
-%-----------------------------------------------------------------------------%
-
-:- func this_file = string.
-
-this_file = "rbmm.actual_region_arguments.m".
-
-%-----------------------------------------------------------------------------%
Index: rbmm.add_rbmm_goal_infos.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.add_rbmm_goal_infos.m,v
retrieving revision 1.8
diff -u -r1.8 rbmm.add_rbmm_goal_infos.m
--- rbmm.add_rbmm_goal_infos.m 2 Sep 2009 00:30:23 -0000 1.8
+++ rbmm.add_rbmm_goal_infos.m 28 Nov 2009 01:52:05 -0000
@@ -41,8 +41,8 @@
:- 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_arguments.
:- import_module transform_hlds.rbmm.region_resurrection_renaming.
:- import_module transform_hlds.rbmm.region_transformation.
@@ -63,6 +63,8 @@
:- import_module hlds.hlds_pred.
:- import_module libs.
:- import_module libs.compiler_util.
+:- import_module libs.globals.
+:- import_module libs.options.
:- import_module mdbcomp.
:- import_module mdbcomp.prim_data.
:- import_module parse_tree.
@@ -72,11 +74,12 @@
:- import_module transform_hlds.rbmm.points_to_graph.
:- import_module transform_hlds.smm_common.
-:- import_module string.
+:- import_module bool.
:- import_module list.
:- import_module map.
:- import_module maybe.
:- import_module set.
+:- import_module string.
%-----------------------------------------------------------------------------%
%
@@ -163,7 +166,7 @@
collect_rbmm_goal_info_unification(Unification, ModuleInfo, Graph,
ResurRenaming, IteRenaming, NameToRegionVar, !Info).
-collect_rbmm_goal_info_goal_expr(ModuleInfo, ProcInfo, _,
+collect_rbmm_goal_info_goal_expr(ModuleInfo, ProcInfo, Graph,
ActualRegionArgumentProc, _, _, _, !Expr, !Info) :-
!.Expr = plain_call(PredId, ProcId, Args, _, _, _),
CalleePPId = proc(PredId, ProcId),
@@ -189,7 +192,7 @@
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),
+ ActualRegionArgs = region_args(Constants, Inputs, _Outputs),
list.det_split_list(list.length(Constants), RegionArgs,
CarriedRegions, RemovedAndCreated),
list.det_split_list(list.length(Inputs), RemovedAndCreated,
@@ -198,12 +201,55 @@
% are allocated into and read from in this call.
AllocatedIntoAndReadFrom =
set.from_list(RemovedRegions ++ CarriedRegions),
+
+ module_info_get_globals(ModuleInfo, Globals),
+ globals.lookup_bool_option(Globals, use_alloc_regions,
+ UseAllocRegions),
+ (
+ UseAllocRegions = yes,
+ % Keep only the regions that are removed but also allocated into.
+ keep_allocated_regions(Inputs, RemovedRegions, Graph,
+ RemovedAndAllocRegions),
+ % Allocated regions are the above plus the carried ones.
+ % The carried here are those that are also allocated into.
+ AllocatedIntoRegions =
+ set.from_list(RemovedAndAllocRegions ++ CarriedRegions)
+ ;
+ UseAllocRegions = no,
+ AllocatedIntoRegions = AllocatedIntoAndReadFrom
+ ),
+
+ % The read-from set is not very important so we are not precise
+ % in estimating it.
RbmmGoalInfo = rbmm_goal_info(set.from_list(CreatedRegions),
set.from_list(RemovedRegions), set.from_list(CarriedRegions),
- AllocatedIntoAndReadFrom, AllocatedIntoAndReadFrom),
+ AllocatedIntoRegions, AllocatedIntoAndReadFrom),
goal_info_set_maybe_rbmm(yes(RbmmGoalInfo), !Info)
).
+ % The elements in the first and second lists are corresponding.
+ % Ones in the first list are the nodes in rpt graph therefore we can
+ % check their allocated property, ones in the second list are prog_vars
+ % (after renaming) that represent those in the first.
+ %
+:- pred keep_allocated_regions(list(rptg_node)::in, list(prog_var)::in,
+ rpt_graph::in, list(prog_var)::out) is det.
+
+keep_allocated_regions([], [], _, []).
+keep_allocated_regions([], [_ | _], _, []) :-
+ unexpected(this_file, "keep_allocated_regions: length mismatch").
+keep_allocated_regions([_ | _], [], _, []) :-
+ unexpected(this_file, "keep_allocated_regions: length mismatch").
+keep_allocated_regions([Input | Inputs], [RemovedRegion | RemovedRegions],
+ Graph, RemovedAndAllocRegions) :-
+ keep_allocated_regions(Inputs, RemovedRegions, Graph,
+ RemovedAndAllocRegions0),
+ ( rptg_is_allocated_node(Graph, Input) ->
+ RemovedAndAllocRegions = [RemovedRegion | RemovedAndAllocRegions0]
+ ;
+ RemovedAndAllocRegions = RemovedAndAllocRegions0
+ ).
+
% 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
@@ -440,6 +486,8 @@
then
goal_info_set_maybe_rbmm(yes(rbmm_info_init), !Info)
else
+ % We need to try to apply renaming here because the
+ % region name in the Graph may need to be changed.
OriginalName = rptg_lookup_region_name(Graph, Node),
( map.search(ResurRenaming, OriginalName, ResurNameList) ->
Name = list.det_last(ResurNameList)
@@ -448,18 +496,29 @@
;
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)),
+
+ % This region may only be read from in the procedure containing
+ % this deconstruction therefore there might be no entry for it
+ % in RegionNameToVar.
+ ( map.search(RegionNameToVar, Name, RegionVar) ->
+ RbmmInfo = rbmm_goal_info(set.init, set.init,
+ set.make_singleton_set(RegionVar),
+ set.init, set.make_singleton_set(RegionVar))
+ ;
+ RbmmInfo = rbmm_info_init
+ ),
goal_info_set_maybe_rbmm(yes(RbmmInfo), !Info)
)
;
- ( Unification = assign(_, _)
+ (
+ % XXX We do have assignments between two region variables. But
+ % we do not consider either of them created or removed because
+ % the region they are bound to is still there, i.e., it has been
+ % created and will not be removed.
+ 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)
+ goal_info_set_maybe_rbmm(yes(rbmm_info_init), !Info)
;
Unification = complicated_unify(_, _, _),
unexpected(this_file, "collect_rbmm_goal_info_unification:"
Index: rbmm.interproc_region_lifetime.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.interproc_region_lifetime.m,v
retrieving revision 1.4
diff -u -r1.4 rbmm.interproc_region_lifetime.m
--- rbmm.interproc_region_lifetime.m 6 Sep 2007 12:45:24 -0000 1.4
+++ rbmm.interproc_region_lifetime.m 28 Nov 2009 01:52:05 -0000
@@ -144,7 +144,7 @@
:- type rule_pred == (
pred(pred_proc_id, region_set, region_set, proc_region_set_table,
- map(rptg_node, rptg_node), region_set)
+ rpt_call_alpha_mapping, region_set)
).
:- inst rule_pred == ( pred(in, in, in, in, in, out) is det ).
@@ -347,8 +347,8 @@
% Rules for eliminating regions from deadR set.
%
:- pred dead_removal_rules(pred_proc_id::in, region_set::in, region_set::in,
- proc_region_set_table::in, map(rptg_node, rptg_node)::in,
- region_set::out) is det.
+ proc_region_set_table::in, rpt_call_alpha_mapping::in, region_set::out)
+ is det.
dead_removal_rules(Q_Id, LRBefore, LRAfter, DeadRTable, AlphaAtPP, DeadR_q) :-
% The current deadR of q.
@@ -364,7 +364,7 @@
targets_with_more_than_one_source(AlphaAtPP, Targets),
set.fold(dead_removal_rule_2(AlphaAtPP), Targets, DeadR_q1, DeadR_q).
-:- pred dead_removal_rule_1(map(rptg_node, rptg_node)::in, rptg_node::in,
+:- pred dead_removal_rule_1(rpt_call_alpha_mapping::in, rptg_node::in,
region_set::in, region_set::out) is det.
dead_removal_rule_1(AlphaAtCallSite, Region, !DeadR_q) :-
@@ -375,7 +375,7 @@
% Remove any r' that is in deadR(q).
set.difference(!.DeadR_q, RPrimes, !:DeadR_q).
-:- pred dead_removal_rule_2(map(rptg_node, rptg_node)::in, rptg_node::in,
+:- pred dead_removal_rule_2(rpt_call_alpha_mapping::in, rptg_node::in,
set(rptg_node)::in, set(rptg_node)::out) is det.
dead_removal_rule_2(AlphaAtCallSite, Region, !DeadR_q) :-
@@ -386,7 +386,7 @@
% rules for eliminating regions from bornR set.
%
:- pred born_removal_rules(pred_proc_id::in, region_set::in, region_set::in,
- proc_region_set_table::in, map(rptg_node, rptg_node)::in,
+ proc_region_set_table::in, rpt_call_alpha_mapping::in,
region_set::out) is det.
born_removal_rules(Q_Id, LRBefore, _, BornRTable, AlphaAtCallSite, BornR_q) :-
@@ -403,7 +403,7 @@
set.fold(born_removal_rule_2(AlphaAtCallSite), Targets,
BornR_q1, BornR_q).
-:- pred born_removal_rule_1(map(rptg_node, rptg_node)::in, rptg_node::in,
+:- pred born_removal_rule_1(rpt_call_alpha_mapping::in, rptg_node::in,
set(rptg_node)::in, set(rptg_node)::out) is det.
born_removal_rule_1(AlphaAtCallSite, Region, !BornR_q) :-
@@ -414,7 +414,7 @@
% alpha(r') = r, alpha(r'') = r, r', r'' in bornR(q) imply remove r',
% r'' from bornR(q).
%
-:- pred born_removal_rule_2(map(rptg_node, rptg_node)::in, rptg_node::in,
+:- pred born_removal_rule_2(rpt_call_alpha_mapping::in, rptg_node::in,
set(rptg_node)::in, set(rptg_node)::out) is det.
born_removal_rule_2(AlphaAtCallSite, Region, !BornR_q) :-
@@ -425,7 +425,7 @@
% Find targets of alpha mapping that are mapped to by more than one
% source.
%
-:- pred targets_with_more_than_one_source(map(rptg_node, rptg_node)::in,
+:- pred targets_with_more_than_one_source(rpt_call_alpha_mapping::in,
region_set::out) is det.
targets_with_more_than_one_source(AlphaAtCallSite, Targets) :-
Index: rbmm.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.m,v
retrieving revision 1.9
diff -u -r1.9 rbmm.m
--- rbmm.m 23 Apr 2009 10:00:24 -0000 1.9
+++ rbmm.m 28 Nov 2009 01:52:05 -0000
@@ -16,7 +16,7 @@
:- module transform_hlds.rbmm.
:- interface.
-:- include_module actual_region_arguments.
+:- include_module add_rbmm_goal_infos.
:- include_module condition_renaming.
:- include_module execution_path.
:- include_module interproc_region_lifetime.
@@ -25,7 +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_arguments.
:- include_module region_instruction.
:- include_module region_liveness_info.
:- include_module region_resurrection_renaming.
@@ -45,7 +45,6 @@
:- implementation.
-:- import_module transform_hlds.rbmm.actual_region_arguments.
:- import_module transform_hlds.rbmm.condition_renaming.
:- import_module transform_hlds.rbmm.execution_path.
:- import_module transform_hlds.rbmm.interproc_region_lifetime.
@@ -53,6 +52,7 @@
:- 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_arguments.
:- import_module transform_hlds.rbmm.region_instruction.
:- import_module transform_hlds.rbmm.region_resurrection_renaming.
:- import_module transform_hlds.rbmm.region_transformation.
@@ -84,9 +84,9 @@
BecomeLiveTable, BecomeDeadBeforeTable, BecomeDeadAfterTable,
RegionInstructionTable),
- record_actual_region_arguments(!.ModuleInfo, RptaInfoTable,
- ConstantRTable, DeadRTable, BornRTable,
- ActualRegionArgumentTable),
+ record_region_arguments(!.ModuleInfo, RptaInfoTable,
+ ConstantRTable, DeadRTable, BornRTable, FormalRegionArgTable,
+ ActualRegionArgTable),
% The region analysis treats region variables as if they are
% imperative-style updatable variables. They may also have scopes
@@ -119,12 +119,12 @@
RptaInfoTable, IteRenamingTable0, IteRenamingTable,
IteRenamingAnnoTable),
- region_transform(RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
- ActualRegionArgumentTable, ResurRenamingTable, IteRenamingTable,
- RegionInstructionTable, ResurRenamingAnnoTable,
+ region_transform(RptaInfoTable, FormalRegionArgTable,
+ ActualRegionArgTable, ResurRenamingTable,
+ IteRenamingTable, RegionInstructionTable, ResurRenamingAnnoTable,
IteRenamingAnnoTable, map.init, NameToVarTable, !ModuleInfo),
- collect_rbmm_goal_info(RptaInfoTable, ActualRegionArgumentTable,
+ collect_rbmm_goal_info(RptaInfoTable, ActualRegionArgTable,
ResurRenamingTable, IteRenamingTable, NameToVarTable, !ModuleInfo).
%-----------------------------------------------------------------------------%
Index: rbmm.points_to_analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.points_to_analysis.m,v
retrieving revision 1.12
diff -u -r1.12 rbmm.points_to_analysis.m
--- rbmm.points_to_analysis.m 19 Aug 2009 07:44:57 -0000 1.12
+++ rbmm.points_to_analysis.m 28 Nov 2009 01:52:05 -0000
@@ -772,7 +772,7 @@
%
:- pred alpha_mapping_at_call_site(list(prog_var)::in, list(prog_var)::in,
rpt_graph::in, rpt_graph::in, rpt_graph::out,
- map(rptg_node, rptg_node)::in, map(rptg_node, rptg_node)::out) is det.
+ rpt_call_alpha_mapping::in, rpt_call_alpha_mapping::out) is det.
alpha_mapping_at_call_site([], [], _, !CallerGraph, !AlphaMap).
alpha_mapping_at_call_site([], [_ | _], _, _, _, _, _) :-
@@ -781,30 +781,33 @@
alpha_mapping_at_call_site([_ | _], [], _, _, _, _, _) :-
unexpected(this_file,
"alpha_mapping_at_call_site: actuals and formals do not match.").
- % Xi's are formal arguments, Yi's are actual arguments at the call site
- %
alpha_mapping_at_call_site([Xi | Xs], [Yi | Ys], CalleeGraph,
!CallerGraph, !AlphaMap) :-
+ % Xi's are formal arguments, Yi's are actual arguments at the call site.
rptg_get_node_by_variable(CalleeGraph, Xi, N_Xi),
rptg_get_node_by_variable(!.CallerGraph, Yi, N_Yi),
( map.search(!.AlphaMap, N_Xi, N_Y) ->
% alpha(N_Xi) = N_Y, alpha(N_Xi) = N_Yi, N_Y != N_Yi.
%
- ( N_Y \= N_Yi ->
+ ( N_Y = N_Yi ->
+ true
+ ;
% Apply rule P4.
unify_operator(N_Y, N_Yi, !CallerGraph),
% Apply rule P1 after some nodes are unified.
rule_1(N_Y, !CallerGraph)
- ;
- true
)
;
svmap.set(N_Xi, N_Yi, !AlphaMap),
- % N_Yi inherits N_Xi's is_allocated.
- IsAlloc = rptg_lookup_node_is_allocated(CalleeGraph, N_Xi),
- rptg_set_node_is_allocated(N_Yi, IsAlloc, !CallerGraph)
+ % If N_Xi's is_allocated then N_Yi is also allocated.
+ % Otherwise leave N_Yi alone.
+ ( rptg_is_allocated_node(CalleeGraph, N_Xi) ->
+ rptg_set_node_is_allocated(N_Yi, bool.yes, !CallerGraph)
+ ;
+ true
+ )
),
alpha_mapping_at_call_site(Xs, Ys, CalleeGraph, !CallerGraph, !AlphaMap).
@@ -930,9 +933,12 @@
svmap.set(CalleeM, CallerM, AlphaAtCallSite0, AlphaAtCallSite1),
svmap.set(CallSite, AlphaAtCallSite1, !CallerAlphaMapping),
- % CallerM inherits CalleeM's is_allocated.
- IsAlloc = rptg_lookup_node_is_allocated(CalleeGraph, CalleeM),
- rptg_set_node_is_allocated(CallerM, IsAlloc, !CallerGraph)
+ % If CalleeM's is_allocated then CallerM is also allocated.
+ % Otherwise leave CallerM alone.
+ ( rptg_is_allocated_node(CalleeGraph, CalleeM) ->
+ rptg_set_node_is_allocated(CallerM, bool.yes, !CallerGraph)
+ ; true
+ )
)
else
true
Index: rbmm.points_to_graph.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.points_to_graph.m,v
retrieving revision 1.4
diff -u -r1.4 rbmm.points_to_graph.m
--- rbmm.points_to_graph.m 21 Apr 2009 14:05:55 -0000 1.4
+++ rbmm.points_to_graph.m 28 Nov 2009 01:52:05 -0000
@@ -179,6 +179,8 @@
:- func rptg_lookup_node_vars(rpt_graph, rptg_node) = set(prog_var).
:- func rptg_lookup_node_is_allocated(rpt_graph, rptg_node) = bool.
+:- pred rptg_is_allocated_node(rpt_graph::in, rptg_node::in) is semidet.
+
% Return the list of edges (edge id's).
%
:- func rptg_lookup_list_outedges(rpt_graph, rptg_node) = list(rptg_edge).
@@ -589,6 +591,10 @@
NodeContent = rptg_get_node_content(Graph, Node),
IsAllocated = rptg_node_content_get_is_allocated(NodeContent).
+rptg_is_allocated_node(Graph, Region) :-
+ IsAlloc = rptg_lookup_node_is_allocated(Graph, Region),
+ IsAlloc = bool.yes.
+
rptg_lookup_list_outedges(Graph, Node) = EdgeList :-
OutEdgesOfNode = rptg_lookup_map_outedges(Graph, Node),
map.keys(OutEdgesOfNode, EdgeList).
@@ -987,9 +993,6 @@
Processed = [Node | Processed0],
% Take out-edges of the Node and update the remembered list.
- %OutEdges = rptg_get_outedges(Graph),
- %map.lookup(OutEdges, Node, OutEdgesOfNode),
- %map.keys(OutEdgesOfNode, EdgeList),
EdgeList = rptg_lookup_list_outedges(Graph, Node),
list.foldl(
update_remembered_list(Selector, HLDS, TypeX, Graph, Processed),
Index: rbmm.points_to_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.points_to_info.m,v
retrieving revision 1.4
diff -u -r1.4 rbmm.points_to_info.m
--- rbmm.points_to_info.m 21 Apr 2009 14:05:55 -0000 1.4
+++ rbmm.points_to_info.m 28 Nov 2009 01:52:05 -0000
@@ -37,8 +37,6 @@
:- pred rpta_info_table_set_rpta_info(pred_proc_id::in, rpta_info::in,
rpta_info_table::in, rpta_info_table::out) is det.
- % type rpta_info and operations
- %
:- type rpta_info
---> rpta_info(rpt_graph, rpt_alpha_mapping).
@@ -52,7 +50,16 @@
%-----------------------------------------------------------------------------%
-:- type rpt_alpha_mapping == map(program_point, map(rptg_node, rptg_node)).
+ % This type represents the alpha mapping of all call sites in a procedure.
+ % For documentation of alpha mappings, see Chapter 4 in Quan's thesis;
+ % basically, they map the nodes in the region points-to graph of the callee
+ % to the corresponding nodes in the caller.
+ %
+:- type rpt_alpha_mapping == map(program_point, rpt_call_alpha_mapping).
+
+ % This type represents the alpha mapping at one call site.
+ %
+:- type rpt_call_alpha_mapping == map(rptg_node, rptg_node).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -77,15 +84,13 @@
%-----------------------------------------------------------------------------%
rpta_info_table_init = map.init.
+
rpta_info_table_search_rpta_info(PredProcId, Table) = RptaInfo :-
Table ^ elem(PredProcId) = RptaInfo.
-rpta_info_table_set_rpta_info(PredProcId, RptaInfo, Table0, Table) :-
- Table = Table0 ^ elem(PredProcId) := RptaInfo.
- % The rpta_info will be for a specific procedure, so at the beginning
- % the alpha mapping is empty and the rpt graph contains all the nodes
- % corresponding to all the variables appear in the procedure.
- %
+rpta_info_table_set_rpta_info(PredProcId, RptaInfo, !Table) :-
+ !Table ^ elem(PredProcId) := RptaInfo.
+
rpta_info_init(ProcInfo) = RptaInfo :-
proc_info_get_vartypes(ProcInfo, VarTypes),
map.keys(VarTypes, Vars),
@@ -139,8 +144,8 @@
AlphaMappingAtCallSiteA,AlphaMappingAtCallSiteB),
rpt_alpha_mapping_equal_2(CallSiteAs, AlphaMappingA, AlphaMappingB).
-:- pred rpt_alpha_mapping_at_call_site_equal(map(rptg_node, rptg_node)::in,
- map(rptg_node, rptg_node)::in) is semidet.
+:- pred rpt_alpha_mapping_at_call_site_equal(rpt_call_alpha_mapping::in,
+ rpt_call_alpha_mapping::in) is semidet.
rpt_alpha_mapping_at_call_site_equal(AMAtCallSiteA, AMAtCallSiteB) :-
map.count(AMAtCallSiteA, CA),
@@ -151,7 +156,7 @@
AMAtCallSiteB).
:- pred rpt_alpha_mapping_at_call_site_equal_2(list(rptg_node)::in,
- map(rptg_node, rptg_node)::in, map(rptg_node, rptg_node)::in) is semidet.
+ rpt_call_alpha_mapping::in, rpt_call_alpha_mapping::in) is semidet.
rpt_alpha_mapping_at_call_site_equal_2([], _, _).
rpt_alpha_mapping_at_call_site_equal_2([N | Ns], AMAtCallSiteA,
Index: rbmm.region_arguments.m
===================================================================
RCS file: rbmm.region_arguments.m
diff -N rbmm.region_arguments.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ rbmm.region_arguments.m 28 Nov 2009 01:52:06 -0000
@@ -0,0 +1,334 @@
+% -----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2009 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.region_arguments.m.
+% Main author: qph.
+%
+% We will pass regions as extra arguments in procedure calls.
+% After the region liveness analysis we can decide on what region variables
+% need to be region arguments (for procedures and calls).
+% This module derives the formal region arguments for procedures and
+% the actual region arguments at call sites in each procedure.
+% This information will be used to extend the argument lists of procedures
+% and calls in the HLDS.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- module transform_hlds.rbmm.region_arguments.
+:- interface.
+
+:- import_module hlds.
+:- import_module hlds.hlds_module.
+:- import_module hlds.hlds_pred.
+:- import_module transform_hlds.rbmm.points_to_graph.
+:- import_module transform_hlds.rbmm.points_to_info.
+:- import_module transform_hlds.rbmm.region_liveness_info.
+:- import_module transform_hlds.smm_common.
+
+:- import_module list.
+:- import_module map.
+
+:- type proc_formal_region_args_table
+ == map(
+ pred_proc_id,
+ region_args
+ ).
+
+:- type proc_pp_actual_region_args_table
+ == map(
+ pred_proc_id,
+ pp_actual_region_args_table
+ ).
+
+:- type pp_actual_region_args_table
+ == map(
+ program_point,
+ region_args
+ ).
+
+:- type region_args
+ ---> region_args(
+ list(rptg_node), % constant (carried) region arguments.
+ list(rptg_node), % inputs (removed).
+ list(rptg_node) % outputs (created).
+ ).
+
+:- pred record_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_formal_region_args_table::out,
+ proc_pp_actual_region_args_table::out) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module check_hlds.
+:- import_module check_hlds.goal_path.
+:- import_module hlds.hlds_goal.
+:- import_module libs.
+:- import_module libs.compiler_util.
+
+:- import_module set.
+:- import_module string.
+:- import_module svmap.
+
+record_region_arguments(ModuleInfo, RptaInfoTable, ConstantRTable,
+ DeadRTable, BornRTable, FormalRegionArgTable, ActualRegionArgTable) :-
+ module_info_predids(PredIds, ModuleInfo, _),
+ list.foldl2(record_actual_region_arguments_pred(ModuleInfo,
+ RptaInfoTable, ConstantRTable, DeadRTable, BornRTable),
+ PredIds, map.init, FormalRegionArgTable,
+ map.init, ActualRegionArgTable).
+
+:- 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_formal_region_args_table::in,
+ proc_formal_region_args_table::out,
+ 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,
+ !FormalRegionArgTable, !ActualRegionArgTable) :-
+ module_info_pred_info(ModuleInfo, PredId, PredInfo),
+ ProcIds = pred_info_non_imported_procids(PredInfo),
+ list.foldl2(record_region_arguments_proc(ModuleInfo, PredId,
+ RptaInfoTable, ConstantRTable, DeadRTable, BornRTable), ProcIds,
+ !FormalRegionArgTable, !ActualRegionArgTable).
+
+:- pred record_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_formal_region_args_table::in,
+ proc_formal_region_args_table::out,
+ proc_pp_actual_region_args_table::in,
+ proc_pp_actual_region_args_table::out) is det.
+
+record_region_arguments_proc(ModuleInfo, PredId, RptaInfoTable,
+ ConstantRTable, DeadRTable, BornRTable, ProcId,
+ !FormalRegionArgTable, !ActualRegionArgTable) :-
+ PPId = proc(PredId, ProcId),
+ ( if some_are_special_preds([PPId], ModuleInfo)
+ then true
+ else
+ record_formal_region_arguments_proc(PPId, RptaInfoTable,
+ ConstantRTable, DeadRTable, BornRTable, !FormalRegionArgTable),
+
+ module_info_proc_info(ModuleInfo, PPId, ProcInfo0),
+ fill_goal_path_slots(ModuleInfo, ProcInfo0, ProcInfo),
+ proc_info_get_goal(ProcInfo, Body),
+ record_actual_region_arguments_goal(ModuleInfo, PPId,
+ RptaInfoTable, ConstantRTable, DeadRTable, BornRTable, Body,
+ !FormalRegionArgTable, map.init, ActualRegionArgProc),
+ svmap.set(PPId, ActualRegionArgProc, !ActualRegionArgTable)
+ ).
+
+:- pred record_formal_region_arguments_proc(pred_proc_id::in,
+ rpta_info_table::in, proc_region_set_table::in,
+ proc_region_set_table::in, proc_region_set_table::in,
+ proc_formal_region_args_table::in, proc_formal_region_args_table::out)
+ is det.
+
+record_formal_region_arguments_proc(PPId, RptaInfoTable,
+ ConstantRTable, DeadRTable, BornRTable, !FormalRegionArgTable) :-
+ ( map.search(!.FormalRegionArgTable, PPId, _) ->
+ true
+ ;
+ map.lookup(ConstantRTable, PPId, ConstantR),
+ map.lookup(DeadRTable, PPId, DeadR),
+ map.lookup(BornRTable, PPId, BornR),
+
+ map.lookup(RptaInfoTable, PPId, RptaInfo),
+ RptaInfo = rpta_info(Graph, _),
+
+ % Formal constant, allocated-into region arguments.
+ set.to_sorted_list(ConstantR, LConstantR),
+ list.filter(rptg_is_allocated_node(Graph),
+ LConstantR, LFormalConstantAllocR),
+
+ % Formal dead region arguments.
+ set.to_sorted_list(DeadR, FormalDeadR),
+
+ % Formal born region arguments.
+ set.to_sorted_list(BornR, FormalBornR),
+
+ svmap.det_insert(PPId,
+ region_args(LFormalConstantAllocR, FormalDeadR, FormalBornR),
+ !FormalRegionArgTable)
+ ).
+
+:- 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,
+ proc_formal_region_args_table::in, proc_formal_region_args_table::out,
+ 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,
+ !FormalRegionArgTable, !ActualRegionArgProc) :-
+ Goal = hlds_goal(Expr, Info),
+ record_actual_region_arguments_expr(Expr, Info, ModuleInfo, PPId,
+ RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
+ !FormalRegionArgTable, !ActualRegionArgProc).
+
+:- pred record_actual_region_arguments_expr(hlds_goal_expr::in,
+ 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,
+ proc_formal_region_args_table::in, proc_formal_region_args_table::out,
+ pp_actual_region_args_table::in, pp_actual_region_args_table::out) is det.
+
+record_actual_region_arguments_expr(GoalExpr, GoalInfo, ModuleInfo, CallerPPId,
+ RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
+ !FormalRegionArgTable, !ActualRegionArgProc) :-
+ (
+ GoalExpr = plain_call(PredId, ProcId, _, _, _, _),
+ CalleePPId = proc(PredId, ProcId),
+ ( some_are_special_preds([CalleePPId], ModuleInfo) ->
+ true
+ ;
+ CallSite = program_point_init(GoalInfo),
+ record_actual_region_arguments_call_site(CallerPPId, CallSite,
+ CalleePPId, RptaInfoTable, ConstantRTable, DeadRTable,
+ BornRTable, !FormalRegionArgTable, !ActualRegionArgProc)
+ )
+ ;
+ GoalExpr = conj(_, Conjuncts),
+ list.foldl2(
+ record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
+ RptaInfoTable, ConstantRTable, DeadRTable, BornRTable),
+ Conjuncts, !FormalRegionArgTable, !ActualRegionArgProc)
+ ;
+ GoalExpr = disj(Disjuncts),
+ list.foldl2(
+ record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
+ RptaInfoTable, ConstantRTable, DeadRTable, BornRTable),
+ Disjuncts, !FormalRegionArgTable, !ActualRegionArgProc)
+ ;
+ GoalExpr = if_then_else(_, Cond, Then, Else),
+ record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
+ RptaInfoTable, ConstantRTable, DeadRTable, BornRTable, Cond,
+ !FormalRegionArgTable, !ActualRegionArgProc),
+ record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
+ RptaInfoTable, ConstantRTable, DeadRTable, BornRTable, Then,
+ !FormalRegionArgTable, !ActualRegionArgProc),
+ record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
+ RptaInfoTable, ConstantRTable, DeadRTable, BornRTable, Else,
+ !FormalRegionArgTable, !ActualRegionArgProc)
+ ;
+ GoalExpr = switch(_, _, Cases),
+ list.foldl2(
+ record_actual_region_arguments_case(ModuleInfo, CallerPPId,
+ RptaInfoTable, ConstantRTable, DeadRTable, BornRTable),
+ Cases, !FormalRegionArgTable, !ActualRegionArgProc)
+ ;
+ GoalExpr = generic_call(_, _, _, _),
+ sorry(this_file,
+ "record_actual_region_arguments_expr: generic_call NYI")
+ ;
+ GoalExpr = call_foreign_proc(_, _, _, _, _, _, _),
+ sorry(this_file,
+ "record_actual_region_arguments_expr: call_foreign_proc NYI")
+ ;
+ GoalExpr = negation(SubGoal),
+ record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
+ RptaInfoTable, ConstantRTable, DeadRTable, BornRTable, SubGoal,
+ !FormalRegionArgTable, !ActualRegionArgProc)
+ ;
+ GoalExpr = unify(_, _, _, _, _)
+ ;
+ GoalExpr = scope(_, SubGoal),
+ % XXX We should special-case the handling of from_ground_term_construct
+ % scopes.
+ record_actual_region_arguments_goal(ModuleInfo, CallerPPId,
+ RptaInfoTable, ConstantRTable, DeadRTable, BornRTable, SubGoal,
+ !FormalRegionArgTable, !ActualRegionArgProc)
+ ;
+ GoalExpr = shorthand(_),
+ unexpected(this_file,
+ "record_actual_region_arguments_expr: shorthand")
+ ).
+
+:- 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,
+ proc_formal_region_args_table::in, proc_formal_region_args_table::out,
+ 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,
+ !FormalRegionArgTable, !ActualRegionArgProc) :-
+ Case = case(_, _, Goal),
+ record_actual_region_arguments_goal(ModuleInfo, PPId, RptaInfoTable,
+ ConstantRTable, DeadRTable, BornRTable, Goal,
+ !FormalRegionArgTable, !ActualRegionArgProc).
+
+ % Region variables in deadR and in bornR are passed as arguments.
+ % Out of the region variables in constantR (constant in the sense that
+ % their bindings will not change during the call) we only pass ones that
+ % may be allocated into as arguments. The actual region arguments are
+ % computed according to these lines.
+ %
+:- pred record_actual_region_arguments_call_site(pred_proc_id::in,
+ 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,
+ proc_formal_region_args_table::in, proc_formal_region_args_table::out,
+ 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,
+ BornRTable, !FormalRegionArgTable, !ActualRegionArgProc) :-
+ ( map.search(!.FormalRegionArgTable, CalleePPId, FormalRegionArgCallee) ->
+ % If the formal region arguments of the called procedure have been
+ % computed, the corresponding actual ones can be straightforwardly
+ % derived using the call site's alpha mapping.
+ FormalRegionArgCallee =
+ region_args(FormalConstants, FormalDeads, FormalBorns),
+ map.lookup(RptaInfoTable, CallerPPId, CallerRptaInfo),
+ CallerRptaInfo = rpta_info(_CallerGraph, CallerAlpha),
+ map.lookup(CallerAlpha, CallSite, AlphaAtCallSite),
+ list.foldr(find_actual_param(AlphaAtCallSite), FormalConstants,
+ [], ActualConstants),
+ list.foldr(find_actual_param(AlphaAtCallSite), FormalDeads,
+ [], ActualDeads),
+ list.foldr(find_actual_param(AlphaAtCallSite), FormalBorns,
+ [], ActualBorns),
+ svmap.det_insert(CallSite,
+ region_args(ActualConstants, ActualDeads, ActualBorns),
+ !ActualRegionArgProc)
+ ;
+ % The formal region arguments of the called procedure haven't been
+ % recorded, so do it now.
+ record_formal_region_arguments_proc(CalleePPId, RptaInfoTable,
+ ConstantRTable, DeadRTable, BornRTable, !FormalRegionArgTable),
+
+ % We try again at this call site after the formal region arguments
+ % are recorded.
+ record_actual_region_arguments_call_site(CallerPPId, CallSite,
+ CalleePPId, RptaInfoTable, ConstantRTable, DeadRTable,
+ BornRTable, !FormalRegionArgTable, !ActualRegionArgProc)
+ ).
+
+:- pred find_actual_param(rpt_call_alpha_mapping::in, rptg_node::in,
+ list(rptg_node)::in, list(rptg_node)::out) is det.
+
+find_actual_param(Alpha_PP, Formal, Actuals0, Actuals) :-
+ map.lookup(Alpha_PP, Formal, Actual),
+ Actuals = [Actual | Actuals0].
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "rbmm.region_arguments.m".
+
+%-----------------------------------------------------------------------------%
Index: rbmm.region_transformation.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.region_transformation.m,v
retrieving revision 1.12
diff -u -r1.12 rbmm.region_transformation.m
--- rbmm.region_transformation.m 8 Sep 2009 02:43:38 -0000 1.12
+++ rbmm.region_transformation.m 28 Nov 2009 01:52:06 -0000
@@ -27,10 +27,9 @@
:- import_module hlds.hlds_pred.
:- import_module parse_tree.
:- import_module parse_tree.prog_data.
-:- import_module transform_hlds.rbmm.actual_region_arguments.
:- import_module transform_hlds.rbmm.points_to_info.
+:- import_module transform_hlds.rbmm.region_arguments.
:- import_module transform_hlds.rbmm.region_instruction.
-:- import_module transform_hlds.rbmm.region_liveness_info.
:- import_module transform_hlds.rbmm.region_resurrection_renaming.
:- import_module map.
@@ -45,21 +44,24 @@
:- type name_to_prog_var == map(string, prog_var).
% The names of the predicates for creating and removing regions.
- % The predicates are in mercury_region_builtin_module.
+ % The predicates are in region_builtin library module.
%
:- func create_region_pred_name = string.
:- func remove_region_pred_name = string.
- % XXX Besides changing the HLDS, this predicate also returns a mapping
- % from a region name to a program variable which represents the
- % region. We will only create a new program variable for a region
- % name which is not yet in the map. Currently this map is only used
- % in this transformation. If we do not need the map later on we should
- % not return it.
+ % Besides changing the HLDS with region information, this predicate also
+ % returns a mapping from a region name to a program variable which
+ % represents the region. We will only create a new program variable for a
+ % region name which is not yet in the map. This information is needed when
+ % computing rbmm_goal_info. Note that because we only pass as argument to
+ % a procedure a region that will be allocated into, be removed, or be
+ % created in the procedure, some regions in the rpt graph of the procedure
+ % may not need to be presented by program variables. They are the regions
+ % that only be read from in the procedure. Therefore there are NO entries
+ % for them in the region_name-to-prog_var map.
%
-:- pred region_transform(rpta_info_table::in, proc_region_set_table::in,
- proc_region_set_table::in, proc_region_set_table::in,
- proc_pp_actual_region_args_table::in,
+:- pred region_transform(rpta_info_table::in,
+ proc_formal_region_args_table::in, proc_pp_actual_region_args_table::in,
renaming_table::in, renaming_table::in, region_instr_table::in,
renaming_annotation_table::in, renaming_annotation_table::in,
name_to_prog_var_table::in, name_to_prog_var_table::out,
@@ -105,15 +107,13 @@
create_region_pred_name = "create_region".
remove_region_pred_name = "remove_region".
-region_transform(RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
+region_transform(RptaInfoTable, FormalRegionArgTable, ActualRegionArgTable,
+ ResurRenamingTable, IteRenamingTable, RegionInstructionTable,
+ ResurRenamingAnnoTable, IteRenamingAnnoTable, !NameToVarTable,
+ !ModuleInfo) :-
+ map.foldl2(annotate_pred, FormalRegionArgTable, [], PredIds, !ModuleInfo),
+ list.foldl2(region_transform_pred(RptaInfoTable, FormalRegionArgTable,
ActualRegionArgTable, ResurRenamingTable, IteRenamingTable,
- RegionInstructionTable, ResurRenamingAnnoTable, IteRenamingAnnoTable,
- !NameToVarTable, !ModuleInfo) :-
- map.foldl2(annotate_pred(DeadRTable, BornRTable), ConstantRTable, [],
- PredIds, !ModuleInfo),
- list.foldl2(region_transform_pred(RptaInfoTable,
- ConstantRTable, DeadRTable, BornRTable, ActualRegionArgTable,
- ResurRenamingTable, IteRenamingTable,
RegionInstructionTable, ResurRenamingAnnoTable, IteRenamingAnnoTable),
PredIds, !NameToVarTable, !ModuleInfo),
@@ -121,7 +121,6 @@
% annotated with region information and recorded. This is necessary
% because recompute_instmap_delta_proc and repuritycheck_proc need to
% look up information about the (annotated) called procedures.
-
list.foldl(update_instmap_delta_pred, PredIds, !ModuleInfo),
list.foldl(recheck_purity_pred, PredIds, !ModuleInfo).
@@ -133,22 +132,20 @@
% 2. Argument types: arg_types, updated with region type for region
% arguments.
%
-:- pred annotate_pred(proc_region_set_table::in, proc_region_set_table::in,
- pred_proc_id::in, region_set::in, list(pred_id)::in, list(pred_id)::out,
+:- pred annotate_pred(pred_proc_id::in, region_args::in,
+ list(pred_id)::in, list(pred_id)::out,
module_info::in, module_info::out) is det.
-annotate_pred(DeadRTable, BornRTable, PPId, ConstantR, !Processed,
- !ModuleInfo) :-
+annotate_pred(PPId, FormalRegionArgs, !Processed, !ModuleInfo) :-
PPId = proc(PredId, _),
( list.member(PredId, !.Processed) ->
true
;
some [!PredInfo] (
module_info_pred_info(!.ModuleInfo, PredId, !:PredInfo),
- map.lookup(DeadRTable, PPId, DeadR),
- map.lookup(BornRTable, PPId, BornR),
- NumberOfRegArgs = set.count(DeadR) + set.count(BornR) +
- set.count(ConstantR),
+ FormalRegionArgs = region_args(Constants, Deads, Borns),
+ NumberOfRegArgs = list.length(Constants) + list.length(Deads) +
+ list.length(Borns),
Arity = pred_info_orig_arity(!.PredInfo),
pred_info_set_orig_arity(Arity + NumberOfRegArgs, !PredInfo),
@@ -174,22 +171,22 @@
% This predicate transforms the procedures of a predicate.
%
-:- pred region_transform_pred(rpta_info_table::in, proc_region_set_table::in,
- proc_region_set_table::in, proc_region_set_table::in,
+:- pred region_transform_pred(rpta_info_table::in,
+ proc_formal_region_args_table::in,
proc_pp_actual_region_args_table::in,
renaming_table::in, renaming_table::in, region_instr_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,
module_info::in, module_info::out) is det.
-region_transform_pred(RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
+region_transform_pred(RptaInfoTable, FormalRegionArgTable,
ActualRegionArgTable, ResurRenamingTable, IteRenamingTable,
RegionInstructionTable, ResurRenamingAnnoTable, IteRenamingAnnoTable,
PredId, !NameToVarTable, !ModuleInfo) :-
module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
ProcIds = pred_info_non_imported_procids(PredInfo),
list.foldl2(region_transform_proc(RptaInfoTable,
- ConstantRTable, DeadRTable, BornRTable, ActualRegionArgTable,
+ FormalRegionArgTable, ActualRegionArgTable,
ResurRenamingTable, IteRenamingTable,
RegionInstructionTable, ResurRenamingAnnoTable, IteRenamingAnnoTable,
PredId), ProcIds, !NameToVarTable, !ModuleInfo).
@@ -208,15 +205,14 @@
% As said above, we will recompute instmap delta, recheck purity for
% this annotated procedure after all the procedures have been transformed.
%
-:- 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_actual_region_args_table::in,
+:- pred region_transform_proc(rpta_info_table::in,
+ proc_formal_region_args_table::in, proc_pp_actual_region_args_table::in,
renaming_table::in, renaming_table::in, region_instr_table::in,
renaming_annotation_table::in, renaming_annotation_table::in,
pred_id::in, proc_id::in, name_to_prog_var_table::in,
name_to_prog_var_table::out, module_info::in, module_info::out) is det.
-region_transform_proc(RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
+region_transform_proc(RptaInfoTable, FormalRegionArgTable,
ActualRegionArgTable, ResurRenamingTable, IteRenamingTable,
RegionInstructionTable, ResurRenamingAnnoTable, IteRenamingAnnoTable,
PredId, ProcId, !NameToVarTable, !ModuleInfo) :-
@@ -229,9 +225,7 @@
proc_info_get_argmodes(ProcInfo1, ActualArgModes0),
proc_info_get_goal(ProcInfo1, Goal0),
map.lookup(RptaInfoTable, PPId, rpta_info(Graph, _)),
- map.lookup(ConstantRTable, PPId, ConstantR),
- map.lookup(DeadRTable, PPId, DeadR),
- map.lookup(BornRTable, PPId, BornR),
+ map.lookup(FormalRegionArgTable, PPId, FormalRegionArgProc),
map.lookup(ActualRegionArgTable, PPId, ActualRegionArgProc),
( map.search(ResurRenamingTable, PPId, ResurRenamingProc0) ->
ResurRenamingProc = ResurRenamingProc0,
@@ -249,7 +243,7 @@
),
map.lookup(RegionInstructionTable, PPId, RegionInstructionProc),
NameToVar0 = map.init,
- annotate_proc(!.ModuleInfo, PredInfo0, Graph, ConstantR, DeadR, BornR,
+ annotate_proc(!.ModuleInfo, PredInfo0, Graph, FormalRegionArgProc,
ActualRegionArgProc, ResurRenamingProc, IteRenamingProc,
RegionInstructionProc, ResurRenamingAnnoProc, IteRenamingAnnoProc,
VarSet0, _, VarTypes0, _, HeadVars0, _, ActualArgModes0, _,
@@ -269,16 +263,15 @@
% + new calls to region instructions
%
:- pred annotate_proc(module_info::in, pred_info::in, rpt_graph::in,
- region_set::in, region_set::in, region_set::in,
- pp_actual_region_args_table::in, renaming_proc::in, renaming_proc::in,
- region_instr_proc::in, renaming_annotation_proc::in,
+ region_args::in, pp_actual_region_args_table::in, renaming_proc::in,
+ renaming_proc::in, region_instr_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,
list(mer_mode)::in, list(mer_mode)::out, hlds_goal::in, hlds_goal::out,
name_to_prog_var::in, name_to_prog_var::out, proc_info::in,
proc_info::out) is det.
-annotate_proc(ModuleInfo, PredInfo, Graph, ConstantR, DeadR, BornR,
+annotate_proc(ModuleInfo, PredInfo, Graph, FormalRegionArgProc,
ActualRegionArgProc, ResurRenamingProc, IteRenamingProc,
RegionInstructionProc, ResurRenamingAnnoProc, IteRenamingAnnoProc,
!VarSet, !VarTypes, !HeadVars, !ActualArgModes, !Goal,
@@ -302,18 +295,17 @@
% Note that formal region arguments are not subjected to renaming.
%
% Along with the extra arguments we also add extra modes for them.
- set.to_sorted_list(ConstantR, LConstantR),
- set.to_sorted_list(DeadR, LDeadR),
- set.to_sorted_list(BornR, LBornR),
- FormalInputNodes = LConstantR ++ LDeadR,
- FormalNodes = FormalInputNodes ++ LBornR,
+
+ FormalRegionArgProc = region_args(Constants, Deads, Borns),
+ FormalInputNodes = Constants ++ Deads,
+ FormalNodes = FormalInputNodes ++ Borns,
list.map_foldl3(node_to_var(Graph), FormalNodes, FormalRegionArgs,
!NameToVar, !VarSet, !VarTypes),
InMode = in_mode,
OutMode = out_mode,
list.duplicate(list.length(FormalInputNodes), InMode, InModes),
- list.duplicate(list.length(LBornR), OutMode, OutModes),
+ list.duplicate(list.length(Borns), OutMode, OutModes),
% Notice that the output of a function needs to be the last argument.
PredOrFunc = pred_info_is_pred_or_func(PredInfo),
@@ -438,9 +430,9 @@
( map.search(ActualRegionArgProc, ProgPoint, ActualNodes0) ->
ActualNodes = ActualNodes0
;
- ActualNodes = actual_region_args([], [], [])
+ ActualNodes = region_args([], [], [])
),
- ActualNodes = actual_region_args(Constants, Ins, Outs),
+ ActualNodes = region_args(Constants, Ins, Outs),
AllNodes = Constants ++ Ins ++ Outs,
list.map_foldl3(
node_to_var_with_both_renamings(Graph, ResurRenaming, IteRenaming),
cvs diff: Diffing notes
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list