[m-rev.] For review: Fix some bugs related to RBMM
Quan Phan
quan.phan at cs.kuleuven.be
Wed Apr 9 06:43:08 AEST 2008
Hi,
I committed this change today.
Regards,
Quan.
On Thu, Apr 03, 2008 at 06:57:17PM +0200, Quan Phan wrote:
> Hi,
>
> This change is limited in RBMM implementation. Will anyone take a look
> at it soon or can I commit first and will address comments, if any,
> after that?
>
> Zoltan, this includes the fix for the two bugs you detected and told me
> in one of our emails before (tests/hard_coded/{cycles.m and cycles2.m}).
>
> Thanks and regards,
> Quan.
> Estimated hours taken: 20
> Branch: main
>
> Fix some bugs in the implementation of RBMM.
> 1) Renaming of region variables:
> There are cases where at a program point two resurrection renamings of a region
> variable exist, one is to apply to the remove intruction and the other to the
> create instruction annotated at that point. Before only one of them was kept,
> now we keep both (1.1) and then apply them as said (1.2).
>
> 2) Fix some other bugs.
> 3) Improve namings and comments at various places.
>
> Implement the saving of protected regions at disj frames ONLY for semidet
> disjunctions. We need this information so as to be able to commit the regions'
> removals when a nonlast disjunct of a semidet disjunction succeeds.
>
> compiler/rbmm.region_resurrection_renaming.m:
> Implement 1.1).
>
> Use counter module instead of int to implement a counter.
> Fix a logic bug that to find resurrected, live regions before a join
> point, we also need to consider the regions live after the previous
> program point. Before we did not, which is a bug.
>
> compiler/rbmm.region_transformation.m:
> Conform to 1) and implement (1.2).
>
> Ensure that when adding region paramaters to function call, the
> variant that the function output is at the end is respected. Before it
> is not, which is a bug.
>
> compiler/rbmm.add_rbmm_goal_infos.m:
> To conform with 1).
>
> compiler/rbmm.condition_renaming.m:
> To conform with 1).
>
> (*) Fix the bug that the reverse condition renaming for an if-then-else
> may be introduced in the condition of another if-then-else in the
> first's then part.
>
> compiler/rbmm.region_instruction.m:
> Ensure that when both a remove and a create instructions are annotated
> to before a program point, the remove one will go first, then the
> create.
>
> Make them conform to the changes for 1).
>
> compiler/rbmm.m:
> To conform with 1) and (*).
> Index: compiler/rbmm.add_rbmm_goal_infos.m
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.add_rbmm_goal_infos.m,v
> retrieving revision 1.3
> diff -u -r1.3 rbmm.add_rbmm_goal_infos.m
> --- compiler/rbmm.add_rbmm_goal_infos.m 27 Feb 2008 07:23:14 -0000 1.3
> +++ compiler/rbmm.add_rbmm_goal_infos.m 3 Apr 2008 15:39:17 -0000
> @@ -438,10 +438,10 @@
> 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
> + ( map.search(ResurRenaming, OriginalName, ResurNameList) ->
> + Name = list.det_last(ResurNameList)
> + ; map.search(IteRenaming, OriginalName, IteNameList) ->
> + Name = list.det_last(IteNameList)
> ;
> Name = OriginalName
> ),
> Index: compiler/rbmm.condition_renaming.m
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.condition_renaming.m,v
> retrieving revision 1.8
> diff -u -r1.8 rbmm.condition_renaming.m
> --- compiler/rbmm.condition_renaming.m 27 Feb 2008 07:23:14 -0000 1.8
> +++ compiler/rbmm.condition_renaming.m 3 Apr 2008 15:39:18 -0000
> @@ -109,10 +109,20 @@
> % happens. For each Condition where renaming happens,
> % it finds the first program point in the corresponding Then and
> % introduces the reverse renaming annotation before that ponit.
> - %
> + % Note that that first program point must not be in the condition of
> + % an if-then-else. E.g.,
> + % if % a renaming exists here: R -> R_ite_1
> + % then
> + % if % not add reverse renaming annotation at this point.
> + % then
> + % % but at here: R := R_ite_1
> + % else
> + % $ and at here: R := R_ite_1
> + % else
> + % ...
> :- pred collect_ite_annotation(proc_goal_path_regions_table::in,
> execution_path_table::in, rpta_info_table::in, renaming_table::in,
> - renaming_annotation_table::out) is det.
> + renaming_table::out, renaming_annotation_table::out) is det.
>
> %-----------------------------------------------------------------------------%
> %-----------------------------------------------------------------------------%
> @@ -387,13 +397,14 @@
>
> apply_region_renaming(Graph, Renaming, Node, !Regions) :-
> RegionName = rptg_lookup_region_name(Graph, Node),
> - ( map.search(Renaming, RegionName, RenamedRegionName) ->
> + ( map.search(Renaming, RegionName, RenamedRegionNameList) ->
> + RenamedRegionName = list.det_last(RenamedRegionNameList),
> svset.insert(RenamedRegionName, !Regions)
> ;
> svset.insert(RegionName, !Regions)
> ).
>
> -:- pred renaming_annotation_to_regions(region_instruction::in,
> +:- pred renaming_annotation_to_regions(region_instr::in,
> set(string)::in, set(string)::out,
> set(string)::in, set(string)::out) is det.
>
> @@ -914,9 +925,9 @@
> record_ite_renaming(ProgPoint, HowMany, _Graph, RegName, !IteRenamingProc) :-
> NewName = RegName ++ "_ite_" ++ string.int_to_string(HowMany),
> ( map.search(!.IteRenamingProc, ProgPoint, IteRenaming0) ->
> - svmap.set(RegName, NewName, IteRenaming0, IteRenaming)
> + svmap.set(RegName, [NewName], IteRenaming0, IteRenaming)
> ;
> - svmap.set(RegName, NewName, map.init, IteRenaming)
> + svmap.set(RegName, [NewName], map.init, IteRenaming)
> ),
> svmap.set(ProgPoint, IteRenaming, !IteRenamingProc).
>
> @@ -1016,69 +1027,105 @@
> %
>
> collect_ite_annotation(IteRenamedRegionTable, ExecPathTable,
> - RptaInfoTable, IteRenamingTable, IteAnnotationTable) :-
> - map.foldl(
> - collect_ite_annotation_proc(ExecPathTable, RptaInfoTable,
> - IteRenamingTable),
> - IteRenamedRegionTable, map.init, IteAnnotationTable).
> + RptaInfoTable, !IteRenamingTable, IteAnnotationTable) :-
> + map.foldl2(
> + collect_ite_annotation_proc(ExecPathTable, RptaInfoTable),
> + IteRenamedRegionTable, !IteRenamingTable,
> + map.init, IteAnnotationTable).
>
> :- pred collect_ite_annotation_proc(execution_path_table::in,
> - rpta_info_table::in, renaming_table::in, pred_proc_id::in,
> - goal_path_regions_table::in,
> + rpta_info_table::in, pred_proc_id::in,
> + goal_path_regions_table::in, renaming_table::in, renaming_table::out,
> renaming_annotation_table::in, renaming_annotation_table::out) is det.
>
> -collect_ite_annotation_proc(ExecPathTable, RptaInfoTable, IteRenamingTable,
> - PPId, IteRenamedRegionProc, !IteAnnotationTable) :-
> +collect_ite_annotation_proc(ExecPathTable, RptaInfoTable, PPId,
> + IteRenamedRegionProc, !IteRenamingTable, !IteAnnotationTable) :-
> map.lookup(ExecPathTable, PPId, ExecPaths),
> map.lookup(RptaInfoTable, PPId, RptaInfo),
> - map.lookup(IteRenamingTable, PPId, IteRenamingProc),
> + map.lookup(!.IteRenamingTable, PPId, IteRenamingProc0),
> RptaInfo = rpta_info(Graph, _),
> - map.foldl(
> - collect_ite_annotation_region_names(ExecPaths, Graph, IteRenamingProc),
> - IteRenamedRegionProc, map.init, IteAnnotationProc),
> - svmap.set(PPId, IteAnnotationProc, !IteAnnotationTable).
> + map.foldl2(
> + collect_ite_annotation_region_names(ExecPaths, Graph),
> + IteRenamedRegionProc, IteRenamingProc0, IteRenamingProc,
> + map.init, IteAnnotationProc),
> + svmap.set(PPId, IteAnnotationProc, !IteAnnotationTable),
> + svmap.set(PPId, IteRenamingProc, !IteRenamingTable).
>
> :- pred collect_ite_annotation_region_names(list(execution_path)::in,
> - rpt_graph::in, renaming_proc::in, goal_path::in, set(string)::in,
> + rpt_graph::in, goal_path::in, set(string)::in,
> + renaming_proc::in, renaming_proc::out,
> renaming_annotation_proc::in, renaming_annotation_proc::out) is det.
>
> -collect_ite_annotation_region_names(ExecPaths, Graph, IteRenamingProc,
> - PathToCond, RenamedRegions, !IteAnnotationProc) :-
> +collect_ite_annotation_region_names(ExecPaths, Graph, PathToCond,
> + RenamedRegions, !IteRenamingProc, !IteAnnotationProc) :-
> ( cord.split_last(PathToCond, InitialSteps, LastStep) ->
> expect(unify(LastStep, step_ite_cond), this_file,
> "collect_ite_annotation_region_names: not step_ite_cond"),
> PathToThen = cord.snoc(InitialSteps, step_ite_then),
> get_closest_condition_in_goal_path(PathToCond, _, 0, HowMany),
> - list.foldl(
> - collect_ite_annotation_exec_path(Graph, IteRenamingProc,
> - PathToThen, RenamedRegions, HowMany),
> - ExecPaths, !IteAnnotationProc)
> + list.foldl2(
> + collect_ite_annotation_exec_path(Graph, PathToThen,
> + RenamedRegions, HowMany),
> + ExecPaths, !IteRenamingProc, !IteAnnotationProc)
> ;
> unexpected(this_file,
> "collect_ite_annotation_region_set: empty path to condition.")
> ).
>
> -:- pred collect_ite_annotation_exec_path(rpt_graph::in,
> - renaming_proc::in, goal_path::in,
> +:- pred collect_ite_annotation_exec_path(rpt_graph::in, goal_path::in,
> set(string)::in, int::in, execution_path::in,
> + renaming_proc::in, renaming_proc::out,
> + renaming_annotation_proc::in, renaming_annotation_proc::out) is det.
> +
> +collect_ite_annotation_exec_path(_, _, _, _, [], !IteRenamingProc,
> + !IteAnnotationProc).
> +collect_ite_annotation_exec_path(Graph, PathToThen, RenamedRegions,
> + HowMany, [ProgPoint - _ | ProgPoint_Goals],
> + !IteRenamingProc, !IteAnnotationProc) :-
> + % This is the first program point of this execution path.
> + % We never need to introduce reversed renaming at this point.
> + collect_ite_annotation_exec_path_2(Graph, PathToThen, RenamedRegions,
> + HowMany, ProgPoint, ProgPoint_Goals, !IteRenamingProc,
> + !IteAnnotationProc).
> +
> + % Process from the 2nd program point onwards.
> +:- pred collect_ite_annotation_exec_path_2(rpt_graph::in, goal_path::in,
> + set(string)::in, int::in, program_point::in, execution_path::in,
> + renaming_proc::in, renaming_proc::out,
> renaming_annotation_proc::in, renaming_annotation_proc::out) is det.
>
> -collect_ite_annotation_exec_path(_, _, _, _, _, [], !IteAnnotationProc).
> -collect_ite_annotation_exec_path(Graph, IteRenamingProc, PathToThen,
> - RenamedRegions, HowMany,
> - [ProgPoint - _ | ProgPoint_Goals], !IteAnnotationProc) :-
> +collect_ite_annotation_exec_path_2(_, _, _, _, _, [], !IteRenamingProc,
> + !IteAnnotationProc).
> +collect_ite_annotation_exec_path_2(Graph, PathToThen, RenamedRegions,
> + HowMany, PrevPoint, [ProgPoint - _ | ProgPoint_Goals],
> + !IteRenamingProc, !IteAnnotationProc) :-
> ProgPoint = pp(_, GoalPath),
> PathToThenSteps = cord.list(PathToThen),
> GoalPathSteps = cord.list(GoalPath),
> - ( list.append(_, PathToThenSteps, GoalPathSteps) ->
> - % This is the first goal in the corresponding then branch, we need
> - % to introduce reverse renaming at this point.
> - set.fold(
> - introduce_reverse_renaming(ProgPoint, IteRenamingProc, HowMany),
> - RenamedRegions, !IteAnnotationProc)
> + ( list.append(PathToThenSteps, FromThenSteps, GoalPathSteps) ->
> + ( list.member(step_ite_cond, FromThenSteps) ->
> + % We cannot introduce reverse renaming in the condition of
> + % an if-then-else. So we need to maintain the ite renaming
> + % from the previous point to this point.
> + ( map.search(!.IteRenamingProc, PrevPoint, PrevIteRenaming) ->
> + svmap.set(ProgPoint, PrevIteRenaming, !IteRenamingProc)
> + ; true
> + ),
> + collect_ite_annotation_exec_path_2(Graph, PathToThen,
> + RenamedRegions, HowMany, ProgPoint, ProgPoint_Goals,
> + !IteRenamingProc, !IteAnnotationProc)
> + ;
> + % This is the first point in the corresponding then branch, which
> + % is not in the condition of another if-then-else, we need
> + % to introduce reverse renaming at this point.
> + set.fold(
> + introduce_reverse_renaming(ProgPoint, !.IteRenamingProc,
> + HowMany),
> + RenamedRegions, !IteAnnotationProc)
> + )
> ;
> - collect_ite_annotation_exec_path(Graph, IteRenamingProc,
> - PathToThen, RenamedRegions, HowMany, ProgPoint_Goals,
> + collect_ite_annotation_exec_path_2(Graph, PathToThen, RenamedRegions,
> + HowMany, ProgPoint, ProgPoint_Goals, !IteRenamingProc,
> !IteAnnotationProc)
> ).
>
> @@ -1096,8 +1143,14 @@
> !IteAnnotationProc) :-
> CurrentName = RegName ++ "_ite_" ++ string.int_to_string(HowMany),
> ( map.search(IteRenamingProc, ProgPoint, Renaming) ->
> - ( map.search(Renaming, RegName, RenameTo) ->
> - make_renaming_instruction(CurrentName, RenameTo, Annotation)
> + ( map.search(Renaming, RegName, RenameToList) ->
> + ( list.length(RenameToList) = 1 ->
> + RenameTo = list.det_last(RenameToList),
> + make_renaming_instruction(CurrentName, RenameTo, Annotation)
> + ;
> + unexpected(this_file,
> + "introduce_reverse_renaming: more than one renaming exist.")
> + )
> ;
> make_renaming_instruction(CurrentName, RegName, Annotation)
> )
> Index: compiler/rbmm.m
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.m,v
> retrieving revision 1.7
> diff -u -r1.7 rbmm.m
> --- compiler/rbmm.m 6 Sep 2007 12:45:24 -0000 1.7
> +++ compiler/rbmm.m 3 Apr 2008 15:39:18 -0000
> @@ -102,17 +102,19 @@
> collect_region_resurrection_renaming(CreatedBeforeTable, LocalRTable,
> RptaInfoTable, ResurrectionPathTable, ResurrectionRenameTable),
> collect_renaming_and_annotation(ResurrectionRenameTable, JoinPointTable,
> - LRBeforeTable, BornRTable, RptaInfoTable, ResurrectionPathTable,
> - ExecPathTable, ResurRenamingAnnoTable, ResurRenamingTable),
> + LRBeforeTable, LRAfterTable, BornRTable, RptaInfoTable,
> + ResurrectionPathTable, ExecPathTable, ResurRenamingAnnoTable,
> + ResurRenamingTable),
> collect_non_local_and_in_cond_regions(!.ModuleInfo, RptaInfoTable,
> LRBeforeTable, LRAfterTable, ResurRenamingTable,
> ResurRenamingAnnoTable, LocalRegionsTable, InCondRegionsTable),
> collect_ite_renamed_regions(LocalRegionsTable, InCondRegionsTable,
> RenamedRegionsTable),
> collect_ite_renaming(!.ModuleInfo, RptaInfoTable, RenamedRegionsTable,
> - IteRenamingTable),
> + IteRenamingTable0),
> collect_ite_annotation(RenamedRegionsTable, ExecPathTable,
> - RptaInfoTable, IteRenamingTable, IteRenamingAnnoTable),
> + RptaInfoTable, IteRenamingTable0, IteRenamingTable,
> + IteRenamingAnnoTable),
>
> region_transform(RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
> ActualRegionArgumentTable, ResurRenamingTable, IteRenamingTable,
> Index: compiler/rbmm.region_instruction.m
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.region_instruction.m,v
> retrieving revision 1.4
> diff -u -r1.4 rbmm.region_instruction.m
> --- compiler/rbmm.region_instruction.m 23 Jul 2007 05:06:14 -0000 1.4
> +++ compiler/rbmm.region_instruction.m 3 Apr 2008 15:39:18 -0000
> @@ -28,25 +28,25 @@
> :- import_module map.
> :- import_module string.
>
> -:- type region_instruction_table
> - == map(pred_proc_id, region_instruction_proc).
> +:- type region_instr_table
> + == map(pred_proc_id, region_instr_proc).
>
> -:- type region_instruction_proc
> - == map(program_point, instructions_before_after).
> +:- type region_instr_proc
> + == map(program_point, instrs_before_after).
>
> % We introduce region instructions before and after a program point.
> -:- type instructions_before_after
> - ---> instructions_before_after(
> - instructions_before :: list(region_instruction),
> +:- type instrs_before_after
> + ---> instrs_before_after(
> + instrs_before :: list(region_instr),
> % Region instructions before a program
> % point.
>
> - instructions_after :: list(region_instruction)
> + instrs_after :: list(region_instr)
> % Region instructions after a program
> % point.
> ).
>
> -:- type region_instruction
> +:- type region_instr
> ---> create_region(
> % Region name.
> string
> @@ -65,16 +65,16 @@
> string
> ).
>
> -:- type region_instruction_type
> - ---> create_region_instruction
> - ; remove_region_instruction
> - ; renaming_region_instruction.
> +:- type region_instr_type
> + ---> create_region_instr
> + ; remove_region_instr
> + ; renaming_region_instr.
>
> :- pred introduce_region_instructions(module_info::in, rpta_info_table::in,
> execution_path_table::in, proc_pp_region_set_table::in,
> proc_pp_region_set_table::in, proc_pp_region_set_table::in,
> proc_region_set_table::in, proc_region_set_table::in,
> - proc_region_set_table::in, region_instruction_table::out) is det.
> + proc_region_set_table::in, region_instr_table::out) is det.
>
> %-----------------------------------------------------------------------------%
> %-----------------------------------------------------------------------------%
> @@ -113,7 +113,7 @@
> proc_pp_region_set_table::in, proc_pp_region_set_table::in,
> proc_pp_region_set_table::in, proc_region_set_table::in,
> proc_region_set_table::in, proc_region_set_table::in, pred_id::in,
> - region_instruction_table::in, region_instruction_table::out) is det.
> + region_instr_table::in, region_instr_table::out) is det.
>
> introduce_region_instructions_pred(ModuleInfo, RptaInfoTable, ExecPathTable,
> LRBeforeTable, LRAfterTable, VoidVarRegionTable, BornRTable,
> @@ -130,7 +130,7 @@
> proc_pp_region_set_table::in, proc_pp_region_set_table::in,
> proc_pp_region_set_table::in, proc_region_set_table::in,
> proc_region_set_table::in, proc_region_set_table::in, proc_id::in,
> - region_instruction_table::in, region_instruction_table::out) is det.
> + region_instr_table::in, region_instr_table::out) is det.
>
> introduce_region_instructions_proc(ModuleInfo, PredId, RptaInfoTable,
> ExecPathTable, LRBeforeTable, LRAfterTable, VoidVarRegionTable,
> @@ -164,7 +164,7 @@
> pp_region_set_table::in, pp_region_set_table::in,
> pp_region_set_table::in, proc_region_set_table::in,
> proc_region_set_table::in, module_info::in, proc_info::in,
> - region_instruction_proc::in, region_instruction_proc::out) is det.
> + region_instr_proc::in, region_instr_proc::out) is det.
>
> introduce_region_instructions_exec_paths([], _, _, _, _, _, _, _, _, _, _, _,
> !RegionInstructionProc).
> @@ -184,7 +184,7 @@
> pp_region_set_table::in, pp_region_set_table::in,
> pp_region_set_table::in, proc_region_set_table::in,
> proc_region_set_table::in, module_info::in, proc_info::in,
> - region_instruction_proc::in, region_instruction_proc::out) is det.
> + region_instr_proc::in, region_instr_proc::out) is det.
>
> introduce_region_instructions_exec_path([], _, _, _, _, _, _, _, _, _, _, _,
> !RegionInstructionProc).
> @@ -207,7 +207,7 @@
> set.intersect(Local_Born_Dead, DeadVoidVarRegions0, DeadVoidVarRegions),
> RptaInfo = rpta_info(CallerGraph, _),
> set.fold(
> - record_instruction_after_prog_point(remove_region_instruction,
> + record_instruction_after_prog_point(remove_region_instr,
> ProgPoint, CallerGraph),
> DeadVoidVarRegions, !RegionInstructionProc),
>
> @@ -242,8 +242,9 @@
> set.difference(LRAfter, LRBeforeNext, ToBeRemovedBeforeNext),
> set.intersect(Local_Born_Dead, ToBeRemovedBeforeNext,
> ToBeRemovedBeforeNextAndAllowed),
> - set.fold(record_instruction_before_prog_point(remove_region_instruction,
> - NextProgPoint, CallerGraph), ToBeRemovedBeforeNextAndAllowed,
> + set.fold(record_instruction_before_prog_point(
> + remove_region_instr, NextProgPoint, CallerGraph),
> + ToBeRemovedBeforeNextAndAllowed,
> !RegionInstructionProc),
>
> introduce_region_instructions_exec_path(ProgPoint_Goals, RptaInfo,
> @@ -270,7 +271,7 @@
> %
> :- pred transformation_rule_1(hlds_goal_expr::in, program_point::in,
> region_set::in, rpta_info::in, proc_region_set_table::in,
> - region_instruction_proc::in, region_instruction_proc::out) is det.
> + region_instr_proc::in, region_instr_proc::out) is det.
>
> transformation_rule_1(Expr, ProgPoint, ToBeCreatedAndAllowed, CallerRptaInfo,
> BornRTable, !RegionInstructionProc) :-
> @@ -297,7 +298,7 @@
> % provided that they are in BornR or LocalR, i.e., p is allowed
> % to create them.
> set.fold(
> - record_instruction_before_prog_point(create_region_instruction,
> + record_instruction_before_prog_point(create_region_instr,
> ProgPoint, CallerGraph),
> ToBeCreatedAndAllowed, !RegionInstructionProc)
> )
> @@ -314,7 +315,7 @@
>
> :- pred process_mapping_rule_1(program_point::in, region_set::in,
> region_set::in, rpt_graph::in, rptg_node::in, rptg_node::in,
> - region_instruction_proc::in, region_instruction_proc::out) is det.
> + region_instr_proc::in, region_instr_proc::out) is det.
>
> process_mapping_rule_1(ProgPoint, ToBeCreatedAndAllowed, CalleeBornR,
> CallerGraph, SourceRegion, TargetRegion, !RegionInstructionProc) :-
> @@ -322,7 +323,7 @@
> set.contains(ToBeCreatedAndAllowed, TargetRegion),
> not set.contains(CalleeBornR, SourceRegion)
> ->
> - record_instruction_before_prog_point(create_region_instruction,
> + record_instruction_before_prog_point(create_region_instr,
> ProgPoint, CallerGraph, TargetRegion, !RegionInstructionProc)
> ;
> true
> @@ -335,7 +336,7 @@
> %
> :- pred transformation_rule_2(hlds_goal_expr::in, program_point::in,
> region_set::in, rpta_info::in, module_info::in, proc_info::in,
> - region_instruction_proc::in, region_instruction_proc::out) is det.
> + region_instr_proc::in, region_instr_proc::out) is det.
>
> transformation_rule_2(Expr, ProgPoint, ToBeCreatedAndAllowed, RptaInfo,
> ModuleInfo, ProcInfo, !RegionInstructionProc) :-
> @@ -349,9 +350,10 @@
>
> set.intersect(Reach_X, ToBeCreatedAndAllowed,
> ToBeCreatedAllowedAndReached),
> - set.fold(record_instruction_before_prog_point(create_region_instruction,
> - ProgPoint, Graph), ToBeCreatedAllowedAndReached,
> - !RegionInstructionProc)
> + set.fold(
> + record_instruction_before_prog_point(create_region_instr,
> + ProgPoint, Graph),
> + ToBeCreatedAllowedAndReached, !RegionInstructionProc)
> ;
> ( Expr = unify(_, _, _, deconstruct(_, _, _, _, _, _), _)
> ; Expr = unify(_, _, _, assign(_, _), _)
> @@ -383,7 +385,7 @@
> %
> :- pred transformation_rule_3(hlds_goal_expr::in, program_point::in,
> region_set::in, rpta_info::in, proc_region_set_table::in,
> - region_instruction_proc::in, region_instruction_proc::out) is det.
> + region_instr_proc::in, region_instr_proc::out) is det.
>
> transformation_rule_3(Expr, ProgPoint, ToBeRemovedAndAllowed, CallerRptaInfo,
> DeadRTable, !RegionInstructionProc) :-
> @@ -405,7 +407,7 @@
> % become dead provided that p is allowed to remove those
> % regions.
> set.fold(
> - record_instruction_after_prog_point(remove_region_instruction,
> + record_instruction_after_prog_point(remove_region_instr,
> ProgPoint, CallerGraph),
> ToBeRemovedAndAllowed, !RegionInstructionProc)
> )
> @@ -422,7 +424,7 @@
>
> :- pred process_mapping_rule_3(program_point::in, region_set::in,
> region_set::in, rpt_graph::in, rptg_node::in, rptg_node::in,
> - region_instruction_proc::in, region_instruction_proc::out) is det.
> + region_instr_proc::in, region_instr_proc::out) is det.
>
> process_mapping_rule_3(ProgPoint, ToBeRemovedAndAllowed, CalleeDeadR,
> CallerGraph, SourceRegion, TargetRegion, !RegionInstructionProc) :-
> @@ -430,7 +432,7 @@
> set.contains(ToBeRemovedAndAllowed, TargetRegion),
> not set.contains(CalleeDeadR, SourceRegion)
> ->
> - record_instruction_after_prog_point(remove_region_instruction,
> + record_instruction_after_prog_point(remove_region_instr,
> ProgPoint, CallerGraph, TargetRegion, !RegionInstructionProc)
> ;
> true
> @@ -442,8 +444,8 @@
> % procedure is allowed to remove it.
> %
> :- pred transformation_rule_4(hlds_goal_expr::in, program_point::in,
> - region_set::in, rpta_info::in, region_instruction_proc::in,
> - region_instruction_proc::out) is det.
> + region_set::in, rpta_info::in, region_instr_proc::in,
> + region_instr_proc::out) is det.
>
> transformation_rule_4(Expr, ProgPoint, ToBeRemovedAndAllowed, RptaInfo,
> !RegionInstructionProc) :-
> @@ -451,8 +453,10 @@
> Expr = unify(_, _, _, _, _)
> ->
> RptaInfo = rpta_info(Graph, _),
> - set.fold(record_instruction_after_prog_point(remove_region_instruction,
> - ProgPoint, Graph), ToBeRemovedAndAllowed, !RegionInstructionProc)
> + set.fold(
> + record_instruction_after_prog_point(remove_region_instr,
> + ProgPoint, Graph),
> + ToBeRemovedAndAllowed, !RegionInstructionProc)
> ;
> ( Expr = plain_call(_, _, _, _, _, _)
> ; Expr = conj(_, [])
> @@ -469,20 +473,20 @@
> % We will record the annotations after the program point.
> %
> :- pred transformation_rule_4_2(program_point::in, region_set::in,
> - rpta_info::in, region_instruction_proc::in, region_instruction_proc::out)
> + rpta_info::in, region_instr_proc::in, region_instr_proc::out)
> is det.
>
> transformation_rule_4_2(ProgPoint, ToBeRemovedAndAllowed, RptaInfo,
> !RegionInstructionProc) :-
> RptaInfo = rpta_info(Graph, _),
> set.fold(
> - record_instruction_after_prog_point(remove_region_instruction,
> + record_instruction_after_prog_point(remove_region_instr,
> ProgPoint, Graph),
> ToBeRemovedAndAllowed, !RegionInstructionProc).
>
> -:- pred record_instruction_after_prog_point(region_instruction_type::in,
> +:- pred record_instruction_after_prog_point(region_instr_type::in,
> program_point::in, rpt_graph::in, rptg_node::in,
> - region_instruction_proc::in, region_instruction_proc::out) is det.
> + region_instr_proc::in, region_instr_proc::out) is det.
>
> record_instruction_after_prog_point(RegionInstType, ProgPoint, Graph, Region,
> !RegionInstructionProc) :-
> @@ -492,63 +496,74 @@
> % Attach the instruction to after the program point.
> (
> map.search(!.RegionInstructionProc, ProgPoint,
> - instructions_before_after(InstsBefore, InstsAfter))
> + instrs_before_after(InstsBefore, InstsAfter))
> ->
> ( list.member(RegionInstruction, InstsAfter) ->
> true
> ;
> svmap.set(ProgPoint,
> - instructions_before_after(InstsBefore,
> + instrs_before_after(InstsBefore,
> [RegionInstruction | InstsAfter]),
> !RegionInstructionProc)
> )
> ;
> svmap.set(ProgPoint,
> - instructions_before_after([], [RegionInstruction]),
> + instrs_before_after([], [RegionInstruction]),
> !RegionInstructionProc)
> ).
>
> -:- pred record_instruction_before_prog_point(region_instruction_type::in,
> + % When adding region annotations to before a program point, we maintain
> + % that remove instructions are added to top, create instructions are
> + % appended at the end.
> + %
> +:- pred record_instruction_before_prog_point(region_instr_type::in,
> program_point::in, rpt_graph::in, rptg_node::in,
> - region_instruction_proc::in, region_instruction_proc::out) is det.
> + region_instr_proc::in, region_instr_proc::out) is det.
>
> -record_instruction_before_prog_point(RegionInstType, ProgPoint, Graph, Region,
> +record_instruction_before_prog_point(RegionInstrType, ProgPoint, Graph, Region,
> !RegionInstructionProc) :-
> RegionName = rptg_lookup_region_name(Graph, Region),
> - make_create_or_remove_instruction(RegionInstType, RegionName,
> + make_create_or_remove_instruction(RegionInstrType, RegionName,
> RegionInstruction),
> % Attach the instruction to before the program point.
> (
> map.search(!.RegionInstructionProc, ProgPoint,
> - instructions_before_after(InstsBefore, InstsAfter))
> + instrs_before_after(InstrsBefore, InstrsAfter))
> ->
> - ( list.member(RegionInstruction, InstsBefore) ->
> + ( list.member(RegionInstruction, InstrsBefore) ->
> true
> ;
> + % It is only safe to add create intructions after remove
> + % instructions before a program point because we allow
> + % remove(R1), create(R1), p(..., R1, ...).
> + ( RegionInstrType = create_region_instr ->
> + NewInstrsBefore = InstrsBefore ++ [RegionInstruction]
> + ;
> + NewInstrsBefore = [RegionInstruction | InstrsBefore]
> + ),
> svmap.set(ProgPoint,
> - instructions_before_after([RegionInstruction | InstsBefore],
> - InstsAfter),
> + instrs_before_after(NewInstrsBefore, InstrsAfter),
> !RegionInstructionProc)
> )
> ;
> svmap.set(ProgPoint,
> - instructions_before_after([RegionInstruction], []),
> + instrs_before_after([RegionInstruction], []),
> !RegionInstructionProc)
> ).
>
> -:- pred make_create_or_remove_instruction(region_instruction_type::in,
> - string::in, region_instruction::out) is det.
> +:- pred make_create_or_remove_instruction(region_instr_type::in,
> + string::in, region_instr::out) is det.
>
> -make_create_or_remove_instruction(RegionInstType, RegionName,
> +make_create_or_remove_instruction(RegionInstrType, RegionName,
> RegionInstruction) :-
> (
> - RegionInstType = create_region_instruction,
> + RegionInstrType = create_region_instr,
> RegionInstruction = create_region(RegionName)
> ;
> - RegionInstType = remove_region_instruction,
> + RegionInstrType = remove_region_instr,
> RegionInstruction = remove_region(RegionName)
> ;
> - RegionInstType = renaming_region_instruction,
> + RegionInstrType = renaming_region_instr,
> unexpected(this_file, "make_create_or_remove_instruction: "
> ++ "unexpected region instruction type")
> ).
> Index: compiler/rbmm.region_resurrection_renaming.m
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.region_resurrection_renaming.m,v
> retrieving revision 1.5
> diff -u -r1.5 rbmm.region_resurrection_renaming.m
> --- compiler/rbmm.region_resurrection_renaming.m 23 Jul 2007 05:06:15 -0000 1.5
> +++ compiler/rbmm.region_resurrection_renaming.m 3 Apr 2008 15:39:18 -0000
> @@ -31,6 +31,7 @@
>
> :- import_module list.
> :- import_module map.
> +:- import_module multi_map.
> :- import_module string.
>
> %-----------------------------------------------------------------------------%
> @@ -41,13 +42,21 @@
> :- type renaming_proc ==
> map(program_point, renaming).
>
> -:- type renaming == map(string, string).
> + % Most of the time, at a program point there is only one renaming for a
> + % region variable. But at some resurrection points, two renamings exists
> + % for the resurrecting region. This should happen only in the following
> + % case:
> + % remove(R), % R -> R_Resur_1
> + % create(R), % R -> R_Resur_2
> + % (i) goal
> + % That's why multi_map is used.
> +:- type renaming == multi_map(string, string).
>
> :- type renaming_annotation_table ==
> map(pred_proc_id, renaming_annotation_proc).
>
> :- type renaming_annotation_proc ==
> - map(program_point, list(region_instruction)).
> + map(program_point, list(region_instr)).
>
> :- type proc_resurrection_path_table ==
> map(pred_proc_id, exec_path_region_set_table).
> @@ -73,21 +82,13 @@
> proc_region_set_table::in, proc_region_set_table::in,
> proc_pp_region_set_table::out, proc_resurrection_path_table::out) is det.
>
> - % This predicate only traverses procedures with the execution paths
> - % containing resurrection and computes *renaming* at the points
> - % where a resurrected region becomes live.
> - % The result here will also only contain procedures in which resurrection
> - % happens and for each procedure only execution paths in which
> - % resurrection happens.
> - %
> -:- pred collect_region_resurrection_renaming(proc_pp_region_set_table::in,
> - proc_region_set_table::in, rpta_info_table::in,
> - proc_resurrection_path_table::in,
> - renaming_table::out) is det.
> -
> % Collect join points in procedures.
> - % We need to find the join points in a procedure because we need to use
> - % a specific region name for each renaming at a join point.
> + % The purpose of finding join points in a procedure is because if a region
> + % is given different names in different execution paths leading to a join
> + % point, we need to unify those names at the join point.
> + % For this purpose, we will only collect join points in execution paths
> + % in which resurrection happens (i.e., the output table of by the above
> + % pass).
> %
> % A program point is a join point if it is in at least two execution
> % paths and its previous points in some two execution paths are different.
> @@ -95,16 +96,36 @@
> :- pred collect_join_points(proc_resurrection_path_table::in,
> execution_path_table::in, join_point_region_name_table::out) is det.
>
> - % XXX Need to collect the execution paths in which a resurrection of a
> - % region does not happen but they contain a join point, where the
> - % region is renamed.
> - % At the creation point of the region in such an execution path, we also
> - % need to rename the region.
> + % This predicate find the execution paths in which we need to introduce
> + % resurrection renaming. These paths include
> + % 1) those in which resurrection happens (computed by
> + % compute_resurrection_paths),
> + % 2) and those in which resurrection does not happens but contain the join
> + % points that belong to those in 1). These can be seen as they share a
> + % program point with those in 1). We need to care about those paths
> + % because in such an execution path, we also need to rename a resurrected
> + % region (in the paths in 1)) so that at the join point it can be renamed
> + % again to the unified one. If we keep the original name we will have
> + % problem if the region is an output and therefore a renaming to the
> + % original name will be introduced after the last program point.
> %
> :- pred collect_paths_containing_join_points(execution_path_table::in,
> join_point_region_name_table::in, proc_resurrection_path_table::in,
> proc_resurrection_path_table::out) is det.
>
> + % This predicate only traverses the execution paths in which resurrection
> + % renaming is needed, i.e., those in the output table of the previous
> + % pass. It computes *renaming* at the points where a resurrected region
> + % becomes live.
> + % The result here will also only contain procedures in which resurrection
> + % happens and for each procedure only execution paths in which
> + % resurrection happens.
> + %
> +:- pred collect_region_resurrection_renaming(proc_pp_region_set_table::in,
> + proc_region_set_table::in, rpta_info_table::in,
> + proc_resurrection_path_table::in,
> + renaming_table::out) is det.
> +
> % This predicate collects *renaming* along the execution paths in
> % procedures where region resurrection happens. It also computes
> % the reversed renaming *annotations* to ensure the integrity use of
> @@ -112,19 +133,20 @@
> %
> :- pred collect_renaming_and_annotation(renaming_table::in,
> join_point_region_name_table::in, proc_pp_region_set_table::in,
> - proc_region_set_table::in, rpta_info_table::in,
> - proc_resurrection_path_table::in, execution_path_table::in,
> - renaming_annotation_table::out, renaming_table::out) is det.
> + proc_pp_region_set_table::in, proc_region_set_table::in,
> + rpta_info_table::in, proc_resurrection_path_table::in,
> + execution_path_table::in, renaming_annotation_table::out,
> + renaming_table::out) is det.
>
> % Record the annotation for a procedure.
> %
> -:- pred record_annotation(program_point::in, region_instruction::in,
> +:- pred record_annotation(program_point::in, region_instr::in,
> renaming_annotation_proc::in, renaming_annotation_proc::out) is det.
>
> % Make a region renaming instruction.
> %
> :- pred make_renaming_instruction(string::in, string::in,
> - region_instruction::out) is det.
> + region_instr::out) is det.
>
> %-----------------------------------------------------------------------------%
> %-----------------------------------------------------------------------------%
> @@ -184,8 +206,8 @@
> LRAfterProc, set.union(BornRProc, LocalRProc)), ExecPaths,
> map.init, CreatedBeforeProc, map.init, PathContainsResurrectionProc),
> svmap.set(PPId, CreatedBeforeProc, !CreatedBeforeTable),
> - % We only want to include procedures in which resurrection happens
> - % in this map.
> + % We only want to include procedures in which resurrection happens in this
> + % map.
> ( map.count(PathContainsResurrectionProc) = 0 ->
> true
> ;
> @@ -204,8 +226,7 @@
> LRAfterProc, Born_Local), ExecPath,
> set.init, _, !CreatedBeforeProc,
> set.init, ResurrectedRegionsInExecPath),
> - % We want to record only execution paths in which resurrections
> - % happen.
> + % We want to record only execution paths in which resurrections happen.
> ( set.empty(ResurrectedRegionsInExecPath) ->
> true
> ;
> @@ -231,8 +252,8 @@
> CreatedBeforeProgPoint),
> svmap.set(ProgPoint, CreatedBeforeProgPoint, !CreatedBeforeProc),
>
> - % Resurrected regions become live at more than one program point
> - % in an execution path.
> + % Resurrected regions become live at more than one program point in an
> + % execution path.
> set.intersect(!.Candidates, CreatedBeforeProgPoint, ResurrectedRegions),
> set.union(ResurrectedRegions, !ResurrectedRegionsInExecPath),
>
> @@ -269,31 +290,43 @@
> assoc_list.keys(ExecPath, P),
> Ps = [P | Ps0]),
> ExecPaths, [], Paths),
> - list.foldl3(collect_join_points_path(Paths), Paths,
> + list.foldl4(collect_join_points_path(Paths), Paths, map.init, _,
> counter.init(0), _, set.init, _JoinPoints, map.init, JoinPointProc),
> svmap.set(PPId, JoinPointProc, !JoinPointTable).
>
> :- pred collect_join_points_path(list(list(program_point))::in,
> - list(program_point)::in, counter::in, counter::out,
> + list(program_point)::in,
> + map(program_point, string)::in, map(program_point, string)::out,
> + counter::in, counter::out,
> set(program_point)::in, set(program_point)::out,
> map(program_point, string)::in, map(program_point, string)::out) is det.
>
> -collect_join_points_path(Paths, Path, !Counter, !JoinPoints,
> +collect_join_points_path(Paths, Path, !JP2Name, !Counter, !JoinPoints,
> !JoinPointProc) :-
> list.delete_all(Paths, Path, TheOtherPaths),
> % We ignore the first program point in each path because
> % it cannot be a join point.
> ( Path = [PrevPoint, ProgPoint | ProgPoints] ->
> - ( is_join_point(ProgPoint, PrevPoint, TheOtherPaths) ->
> - counter.allocate(N, !Counter),
> - svmap.set(ProgPoint, "_jp_" ++ string.int_to_string(N),
> - !JoinPointProc),
> - svset.insert(ProgPoint, !JoinPoints)
> - ;
> + ( set.member(ProgPoint, !.JoinPoints) ->
> true
> + ;
> + ( is_join_point(ProgPoint, PrevPoint, TheOtherPaths) ->
> + % Try to lookup the postfix at this jp.
> + ( map.search(!.JP2Name, PrevPoint, JPName0) ->
> + JPName = JPName0
> + ;
> + counter.allocate(N, !Counter),
> + JPName = "_jp_" ++ string.int_to_string(N),
> + svmap.set(PrevPoint, JPName, !JP2Name)
> + ),
> + svmap.set(ProgPoint, JPName, !JoinPointProc),
> + svset.insert(ProgPoint, !JoinPoints)
> + ;
> + true
> + )
> ),
> collect_join_points_path(Paths, [ProgPoint | ProgPoints],
> - !Counter, !JoinPoints, !JoinPointProc)
> + !JP2Name, !Counter, !JoinPoints, !JoinPointProc)
> ;
> true
> ).
> @@ -426,11 +459,11 @@
> list.foldl2(
> collect_region_resurrection_renaming_prog_point(Graph,
> CreatedBeforeProc, ResurrectedRegions),
> - ExecPath, 1, _, !ResurrectionRenameProc).
> + ExecPath, counter.init(0), _, !ResurrectionRenameProc).
>
> :- pred collect_region_resurrection_renaming_prog_point(rpt_graph::in,
> pp_region_set_table::in, region_set::in,
> - pair(program_point, hlds_goal)::in, int::in, int::out,
> + pair(program_point, hlds_goal)::in, counter::in, counter::out,
> renaming_proc::in, renaming_proc::out) is det.
>
> collect_region_resurrection_renaming_prog_point(Graph, CreatedBeforeProc,
> @@ -443,11 +476,11 @@
> ( set.empty(ToBeRenamedRegions) ->
> true
> ;
> + counter.allocate(N, !RenamingCounter),
> set.fold(
> - record_renaming_prog_point(Graph, ProgPoint, !.RenamingCounter),
> + record_renaming_prog_point(Graph, ProgPoint, N),
> ToBeRenamedRegions, !ResurrectionRenameProc)
> - ),
> - !:RenamingCounter = !.RenamingCounter + 1.
> + ).
>
> :- pred record_renaming_prog_point(rpt_graph::in, program_point::in, int::in,
> rptg_node::in, renaming_proc::in, renaming_proc::out) is det.
> @@ -459,9 +492,9 @@
> ++ string.int_to_string(RenamingCounter),
>
> ( map.search(!.ResurrectionRenameProc, ProgPoint, RenamingProgPoint0) ->
> - svmap.set(RegionName, Renamed, RenamingProgPoint0, RenamingProgPoint)
> + svmap.set(RegionName, [Renamed], RenamingProgPoint0, RenamingProgPoint)
> ;
> - svmap.det_insert(RegionName, Renamed, map.init, RenamingProgPoint)
> + svmap.det_insert(RegionName, [Renamed], map.init, RenamingProgPoint)
> ),
> svmap.set(ProgPoint, RenamingProgPoint, !ResurrectionRenameProc).
>
> @@ -479,26 +512,29 @@
> % variable.
>
> collect_renaming_and_annotation(ResurrectionRenameTable, JoinPointTable,
> - LRBeforeTable, BornRTable, RptaInfoTable, ResurrectionPathTable,
> - ExecPathTable, AnnotationTable, RenamingTable) :-
> + LRBeforeTable, LRAfterTable, BornRTable, RptaInfoTable,
> + ResurrectionPathTable, ExecPathTable,
> + AnnotationTable, RenamingTable) :-
> map.foldl2(collect_renaming_and_annotation_proc(ExecPathTable,
> - JoinPointTable, LRBeforeTable, BornRTable, RptaInfoTable,
> + JoinPointTable, LRBeforeTable, LRAfterTable, BornRTable, RptaInfoTable,
> ResurrectionPathTable), ResurrectionRenameTable,
> map.init, AnnotationTable, map.init, RenamingTable).
>
> :- pred collect_renaming_and_annotation_proc(execution_path_table::in,
> join_point_region_name_table::in, proc_pp_region_set_table::in,
> - proc_region_set_table::in, rpta_info_table::in,
> - proc_resurrection_path_table::in, pred_proc_id::in,
> + proc_pp_region_set_table::in, proc_region_set_table::in,
> + rpta_info_table::in, proc_resurrection_path_table::in, pred_proc_id::in,
> renaming_proc::in,
> renaming_annotation_table::in, renaming_annotation_table::out,
> renaming_table::in, renaming_table::out) is det.
>
> collect_renaming_and_annotation_proc(ExecPathTable, JoinPointTable,
> - LRBeforeTable, BornRTable, RptaInfoTable, ResurrectionPathTable,
> - PPId, ResurrectionRenameProc, !AnnotationTable, !RenamingTable) :-
> + LRBeforeTable, LRAfterTable, BornRTable, RptaInfoTable,
> + ResurrectionPathTable, PPId, ResurrectionRenameProc,
> + !AnnotationTable, !RenamingTable) :-
> map.lookup(JoinPointTable, PPId, JoinPointProc),
> map.lookup(LRBeforeTable, PPId, LRBeforeProc),
> + map.lookup(LRAfterTable, PPId, LRAfterProc),
> map.lookup(BornRTable, PPId, BornR),
> map.lookup(RptaInfoTable, PPId, RptaInfo),
> RptaInfo = rpta_info(Graph, _),
> @@ -514,8 +550,8 @@
> ResurrectedRegionsInPaths, set.init, ResurrectedRegionsProc),
> map.lookup(ExecPathTable, PPId, ExecPaths),
> list.foldl2(collect_renaming_and_annotation_exec_path(
> - ResurrectionRenameProc, JoinPointProc, LRBeforeProc, BornR,
> - Graph, ResurrectedRegionsProc), ExecPaths,
> + ResurrectionRenameProc, JoinPointProc, LRBeforeProc, LRAfterProc,
> + BornR, Graph, ResurrectedRegionsProc), ExecPaths,
> map.init, AnnotationProc, map.init, RenamingProc),
> svmap.set(PPId, AnnotationProc, !AnnotationTable),
> svmap.set(PPId, RenamingProc, !RenamingTable).
> @@ -529,11 +565,12 @@
> %
> :- pred collect_renaming_and_annotation_exec_path(renaming_proc::in,
> map(program_point, string)::in, pp_region_set_table::in,
> - region_set::in, rpt_graph::in, region_set::in, execution_path::in,
> + pp_region_set_table::in, region_set::in, rpt_graph::in, region_set::in,
> + execution_path::in,
> renaming_annotation_proc::in, renaming_annotation_proc::out,
> renaming_proc::in, renaming_proc::out) is det.
>
> -collect_renaming_and_annotation_exec_path(_, _, _, _, _, _, [],
> +collect_renaming_and_annotation_exec_path(_, _, _, _, _, _, _, [],
> !AnnotationProc, !RenamingProc) :-
> unexpected(this_file, "collect_renaming_and_annotation_exec_path: "
> ++ "empty execution path encountered").
> @@ -543,19 +580,22 @@
> % when it is a resurrection point.
> %
> collect_renaming_and_annotation_exec_path(ResurrectionRenameProc,
> - JoinPointProc, LRBeforeProc, BornR, Graph, ResurrectedRegions,
> - [ProgPoint - _ | ProgPoint_Goals], !AnnotationProc, !RenamingProc) :-
> + JoinPointProc, LRBeforeProc, LRAfterProc, BornR, Graph,
> + ResurrectedRegions, [ProgPoint - _ | ProgPoint_Goals],
> + !AnnotationProc, !RenamingProc) :-
> ( map.search(ResurrectionRenameProc, ProgPoint, ResurRename) ->
> svmap.set(ProgPoint, ResurRename, !RenamingProc)
> ;
> svmap.set(ProgPoint, map.init, !RenamingProc)
> ),
> collect_renaming_and_annotation_exec_path_2(ResurrectionRenameProc,
> - JoinPointProc, LRBeforeProc, BornR, Graph, ResurrectedRegions,
> - ProgPoint, ProgPoint_Goals, !AnnotationProc, !RenamingProc).
> + JoinPointProc, LRBeforeProc, LRAfterProc, BornR, Graph,
> + ResurrectedRegions, ProgPoint, ProgPoint_Goals, !AnnotationProc,
> + !RenamingProc).
>
> :- pred collect_renaming_and_annotation_exec_path_2(renaming_proc::in,
> map(program_point, string)::in, pp_region_set_table::in,
> + pp_region_set_table::in,
> region_set::in, rpt_graph::in, region_set::in, program_point::in,
> execution_path::in,
> renaming_annotation_proc::in, renaming_annotation_proc::out,
> @@ -564,7 +604,7 @@
> % This means the first program point is also the last.
> % We do not need to do anything more.
> %
> -collect_renaming_and_annotation_exec_path_2(_, _, _, _, _, _, _, [],
> +collect_renaming_and_annotation_exec_path_2(_, _, _, _, _, _, _, _, [],
> !AnnotationProc, !RenamingProc).
>
> % This is a program point which is not the first.
> @@ -587,16 +627,16 @@
> % parameters which resurrect.
> %
> collect_renaming_and_annotation_exec_path_2(ResurrectionRenameProc,
> - JoinPointProc, LRBeforeProc, BornR, Graph, ResurrectedRegions,
> - PrevProgPoint, [ProgPoint - _ | ProgPoint_Goals],
> + JoinPointProc, LRBeforeProc, LRAfterProc, BornR, Graph,
> + ResurrectedRegions, PrevProgPoint, [ProgPoint - _ | ProgPoint_Goals],
> !AnnotationProc, !RenamingProc) :-
> map.lookup(!.RenamingProc, PrevProgPoint, PrevRenaming),
> ( map.search(ResurrectionRenameProc, ProgPoint, ResurRenaming) ->
> % This is a resurrection point of some region(s). We need to merge
> % the existing renaming at the previous point with the resurrection
> - % renaming here. When two renamings have the same key, i.e., the region
> - % resurrects, the resurrection renaming takes priority.
> - map.overlay(PrevRenaming, ResurRenaming, Renaming0),
> + % renaming here. When two renamings have the same key, i.e.,
> + % the related region resurrects, we will keep both renamings.
> + multi_map.merge(PrevRenaming, ResurRenaming, Renaming0),
> svmap.set(ProgPoint, Renaming0, !RenamingProc)
> ;
> % This is not a resurrection point (of any regions).
> @@ -607,10 +647,14 @@
> % This is a join point.
> % Add annotations to the previous point.
> map.lookup(LRBeforeProc, ProgPoint, LRBeforeProgPoint),
> - set.intersect(ResurrectedRegions, LRBeforeProgPoint,
> + map.lookup(LRAfterProc, PrevProgPoint, LRAfterPrevProgPoint),
> + % Not yet dead in the sense that the region is still needed to be
> + % removed.
> + set.union(LRBeforeProgPoint, LRAfterPrevProgPoint, NotYetDeadRegions),
> + set.intersect(ResurrectedRegions, NotYetDeadRegions,
> ResurrectedAndLiveRegions),
> set.fold2(
> - add_annotation_and_renaming(PrevProgPoint, Graph,
> + add_annotation_and_renaming_at_join_point(PrevProgPoint, Graph,
> JoinPointName, PrevRenaming),
> ResurrectedAndLiveRegions, !AnnotationProc, map.init, Renaming),
> % We will just overwrite any existing renaming information
> @@ -625,30 +669,32 @@
> % Add reversed renaming for regions in bornR.
> set.intersect(ResurrectedRegions, BornR, ResurrectedAndBornRegions),
> map.lookup(!.RenamingProc, ProgPoint, LastRenaming),
> - set.fold(add_annotation(ProgPoint, Graph, LastRenaming),
> + set.fold(add_annotation_at_last_prog_point(ProgPoint, Graph,
> + LastRenaming),
> ResurrectedAndBornRegions, !AnnotationProc)
> ;
> ProgPoint_Goals = [_ | _],
> collect_renaming_and_annotation_exec_path_2(ResurrectionRenameProc,
> - JoinPointProc, LRBeforeProc, BornR, Graph, ResurrectedRegions,
> - ProgPoint, ProgPoint_Goals, !AnnotationProc, !RenamingProc)
> + JoinPointProc, LRBeforeProc, LRAfterProc, BornR, Graph,
> + ResurrectedRegions, ProgPoint, ProgPoint_Goals, !AnnotationProc,
> + !RenamingProc)
> ).
>
> % This predicate adds renaming annotation after the previous program
> % point and records renaming from existing region name.
> %
> -:- pred add_annotation_and_renaming(program_point::in,
> +:- pred add_annotation_and_renaming_at_join_point(program_point::in,
> rpt_graph::in, string::in, renaming::in, rptg_node::in,
> renaming_annotation_proc::in, renaming_annotation_proc::out,
> renaming::in, renaming::out) is det.
>
> -add_annotation_and_renaming(PrevProgPoint, Graph, JoinPointName,
> +add_annotation_and_renaming_at_join_point(PrevProgPoint, Graph, JoinPointName,
> PrevRenaming, Region, !AnnotationProc, !Renaming) :-
> RegionName = rptg_lookup_region_name(Graph, Region),
> NewName = RegionName ++ JoinPointName,
>
> - % Add renaming.
> - svmap.det_insert(RegionName, NewName, !Renaming),
> + % Record renaming at the join point if it doesn't exist yet.
> + svmap.det_insert(RegionName, [NewName], !Renaming),
>
> % Add annotation to (after) the previous program point.
> % XXX Annotations are only added for resurrected regions that have been
> @@ -657,7 +703,8 @@
> % It seems that we have to add annotations (reverse renaming) for ones that
> % have not been renamed as implemented below too. The only difference is
> % that the reverse renaming is between the new name and the original name.
> - ( map.search(PrevRenaming, RegionName, CurrentName) ->
> + ( map.search(PrevRenaming, RegionName, RenamedNames) ->
> + list.det_last(RenamedNames, CurrentName),
> make_renaming_instruction(CurrentName, NewName, Annotation),
> record_annotation(PrevProgPoint, Annotation, !AnnotationProc)
> ;
> @@ -665,17 +712,19 @@
> record_annotation(PrevProgPoint, Annotation, !AnnotationProc)
> ).
>
> -:- pred add_annotation(program_point::in, rpt_graph::in, renaming::in,
> - rptg_node::in, renaming_annotation_proc::in,
> +:- pred add_annotation_at_last_prog_point(program_point::in, rpt_graph::in,
> + renaming::in, rptg_node::in, renaming_annotation_proc::in,
> renaming_annotation_proc::out) is det.
>
> -add_annotation(ProgPoint, Graph, Renaming, Region, !AnnotationProc) :-
> +add_annotation_at_last_prog_point(ProgPoint, Graph, Renaming, Region,
> + !AnnotationProc) :-
> RegionName = rptg_lookup_region_name(Graph, Region),
>
> % Add annotation to (after) the program point.
> % Annotations are only added for resurrected regions that have been
> % renamed in this execution path.
> - ( map.search(Renaming, RegionName, CurrentName) ->
> + ( map.search(Renaming, RegionName, CurrentNameList) ->
> + CurrentName = list.det_last(CurrentNameList),
> make_renaming_instruction(CurrentName, RegionName, Annotation),
> record_annotation(ProgPoint, Annotation, !AnnotationProc)
> ;
> Index: compiler/rbmm.region_transformation.m
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.region_transformation.m,v
> retrieving revision 1.6
> diff -u -r1.6 rbmm.region_transformation.m
> --- compiler/rbmm.region_transformation.m 27 Feb 2008 07:23:14 -0000 1.6
> +++ compiler/rbmm.region_transformation.m 3 Apr 2008 15:39:19 -0000
> @@ -60,7 +60,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_actual_region_args_table::in,
> - renaming_table::in, renaming_table::in, region_instruction_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,
> module_info::in, module_info::out) is det.
> @@ -175,7 +175,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_actual_region_args_table::in,
> - renaming_table::in, renaming_table::in, region_instruction_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.
> @@ -209,7 +209,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_actual_region_args_table::in,
> - renaming_table::in, renaming_table::in, region_instruction_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.
> @@ -269,7 +269,7 @@
> :- 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_instruction_proc::in, renaming_annotation_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,
> @@ -349,7 +349,7 @@
> %
> :- pred region_transform_goal(module_info::in, rpt_graph::in,
> renaming_proc::in, renaming_proc::in, pp_actual_region_args_table::in,
> - region_instruction_proc::in, renaming_annotation_proc::in,
> + region_instr_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,
> prog_varset::in, prog_varset::out, vartypes::in, vartypes::out) is det.
> @@ -380,10 +380,10 @@
> % Region instructions before and after this program point.
> (
> map.search(RegionInstructionProc, ProgPoint,
> - instructions_before_after(Before, After))
> + instrs_before_after(Before, After))
> ->
> % Region instructions before this program point.
> - list.foldl4(region_instruction_to_conj(ModuleInfo, Context,
> + list.foldl4(region_instruction_to_conj_before(ModuleInfo, Context,
> ResurRenaming, IteRenaming), Before, !NameToVar,
> !VarSet, !VarTypes, IteRenamingAssignments, Conjs1),
>
> @@ -426,7 +426,7 @@
>
> % Annotate procedure calls with actual region arguments.
> %
> -region_transform_goal_expr(_, Graph, ResurRenaming, IteRenaming,
> +region_transform_goal_expr(ModuleInfo, Graph, ResurRenaming, IteRenaming,
> ActualRegionArgProc, ProgPoint, !GoalExpr, !GoalInfo,
> !NameToVar, !VarSet, !VarTypes) :-
> !.GoalExpr = plain_call(CalleePredId, CalleeProcId, Args0, Builtin,
> @@ -443,7 +443,18 @@
> list.map_foldl3(
> node_to_var_with_both_renamings(Graph, ResurRenaming, IteRenaming),
> AllNodes, ActualRegionArgs, !NameToVar, !VarSet, !VarTypes),
> - Args = Args0 ++ ActualRegionArgs,
> + module_info_pred_info(ModuleInfo, CalleePredId, CalleePredInfo),
> + CalleePredOrFunc = pred_info_is_pred_or_func(CalleePredInfo),
> + (
> + CalleePredOrFunc = pf_predicate,
> + Args = Args0 ++ ActualRegionArgs
> + ;
> + CalleePredOrFunc = pf_function,
> + % The output of function is always at the last.
> + list.split_last_det(Args0, BeforeLast, Last),
> + Args = BeforeLast ++ ActualRegionArgs ++ [Last]
> + ),
> +
> !:GoalExpr = plain_call(CalleePredId, CalleeProcId, Args, Builtin,
> Context, Name).
>
> @@ -492,7 +503,7 @@
> % 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_actual_region_args_table::in,
> - region_instruction_proc::in, renaming_annotation_proc::in,
> + region_instr_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,
> prog_varset::in, prog_varset::out, vartypes::in, vartypes::out) is det.
> @@ -623,7 +634,7 @@
> %
> :- pred region_transform_case(module_info::in, rpt_graph::in,
> renaming_proc::in, renaming_proc::in, pp_actual_region_args_table::in,
> - region_instruction_proc::in, renaming_annotation_proc::in,
> + region_instr_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,
> prog_varset::in, prog_varset::out, vartypes::in, vartypes::out) is det.
> @@ -656,12 +667,12 @@
> % Region instructions before and after this program point.
> (
> map.search(RegionInstructionProc, ProgPoint,
> - instructions_before_after(Before, After))
> + instrs_before_after(Before, After))
> ->
> % Region instructions before this program point.
> list.foldl4(
> - region_instruction_to_conj(ModuleInfo, Context, ResurRenaming,
> - IteRenaming),
> + region_instruction_to_conj_before(ModuleInfo, Context,
> + ResurRenaming, IteRenaming),
> Before, !NameToVar, !VarSet, !VarTypes,
> IteRenamingAssignments, Conjs1),
>
> @@ -674,8 +685,7 @@
> Conjs2 = IteRenamingAssignments
> ),
>
> - % Assignment unifications due to region resurrection
> - % renaming.
> + % Assignment unifications due to region resurrection renaming.
> assignments_from_resur_renaming_anno(ResurRenamingAnnoProc, ProgPoint,
> IteRenaming, !NameToVar, !VarSet, !VarTypes, Conjs2, Conjs),
>
> @@ -784,7 +794,8 @@
> % Resurrection renaming will be applied first. If a renaming exists
> % for the name (i.e., the name will be changed to another name) then
> % ite renaming need not to be applied because actually it is not
> - % applicable anymore.
> + % applicable anymore. If more than one renaming exist, then we use
> + % the last one.
> %
> :- pred region_name_to_var_with_both_renamings(string::in, renaming::in,
> renaming::in, prog_var::out, name_to_prog_var::in, name_to_prog_var::out,
> @@ -792,10 +803,30 @@
>
> region_name_to_var_with_both_renamings(Name0, ResurRenaming, IteRenaming,
> RegVar, !NameToVar, !VarSet, !VarTypes) :-
> - ( map.search(ResurRenaming, Name0, ResurName) ->
> - Name = ResurName
> - ; map.search(IteRenaming, Name0, IteName) ->
> - Name = IteName
> + ( map.search(ResurRenaming, Name0, ResurNameList) ->
> + list.det_last(ResurNameList, Name)
> + ; map.search(IteRenaming, Name0, IteNameList) ->
> + list.det_last(IteNameList, Name)
> + ;
> + Name = Name0
> + ),
> + region_name_to_var(Name, RegVar, !NameToVar, !VarSet, !VarTypes).
> +
> + % This predicate is the same as the above except that if more than one
> + % renaming exist we will use the first one. This is for use *only* when
> + % renaming the region in a remove instruction added before a program
> + % point.
> + %
> +:- pred region_name_to_var_with_both_renamings_before(string::in, renaming::in,
> + renaming::in, prog_var::out, name_to_prog_var::in, name_to_prog_var::out,
> + prog_varset::in, prog_varset::out, vartypes::in, vartypes::out) is det.
> +
> +region_name_to_var_with_both_renamings_before(Name0, ResurRenaming,
> + IteRenaming, RegVar, !NameToVar, !VarSet, !VarTypes) :-
> + ( map.search(ResurRenaming, Name0, ResurNameList) ->
> + Name = list.det_index0(ResurNameList, 0)
> + ; map.search(IteRenaming, Name0, IteNameList) ->
> + Name = list.det_index0(IteNameList, 0)
> ;
> Name = Name0
> ),
> @@ -810,8 +841,8 @@
>
> region_name_to_var_with_renaming(Name0, ResurRenaming, RegVar,
> !NameToVar, !VarSet, !VarTypes) :-
> - ( map.search(ResurRenaming, Name0, ResurName) ->
> - Name = ResurName
> + ( map.search(ResurRenaming, Name0, ResurNameList) ->
> + Name = list.det_last(ResurNameList)
> ;
> Name = Name0
> ),
> @@ -820,11 +851,11 @@
> % The region name in a region instruction is subjected to renaming due
> % to if-then-else and region resurrection. This predicate turns such an
> % instruction into a call to a suitable region builtin.
> - % XXX Call to generate_simple_call here seems to overkill because we
> + % XXX Call to generate_simple_call here seems to be an overkill because we
> % will recompute nonlocals, instmap delta anyway.
> %
> :- pred region_instruction_to_conj(module_info::in, term.context::in,
> - renaming::in, renaming::in, region_instruction::in,
> + renaming::in, renaming::in, region_instr::in,
> name_to_prog_var::in, name_to_prog_var::out,
> prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
> hlds_goals::in, hlds_goals::out) is det.
> @@ -852,6 +883,40 @@
> ),
> Conjs = Conjs0 ++ [CallGoal].
>
> + % The same as the one right above except that to a region in a remove
> + % instruction we apply the first resurrection renaming.
> + %
> +:- pred region_instruction_to_conj_before(module_info::in, term.context::in,
> + renaming::in, renaming::in, region_instr::in,
> + name_to_prog_var::in, name_to_prog_var::out,
> + prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
> + hlds_goals::in, hlds_goals::out) is det.
> +
> +region_instruction_to_conj_before(ModuleInfo, Context, ResurRenaming,
> + IteRenaming, RegionInstruction, !NameToVar, !VarSet, !VarTypes,
> + Conjs0, Conjs) :-
> + (
> + RegionInstruction = create_region(RegionName),
> + region_name_to_var_with_both_renamings(RegionName, ResurRenaming,
> + IteRenaming, RegionVar, !NameToVar, !VarSet, !VarTypes),
> + generate_simple_call(mercury_region_builtin_module,
> + create_region_pred_name, pf_predicate, only_mode, detism_det,
> + purity_impure, [RegionVar], [], [], ModuleInfo, Context, CallGoal)
> + ;
> + RegionInstruction = remove_region(RegionName),
> + region_name_to_var_with_both_renamings_before(RegionName,
> + ResurRenaming, IteRenaming, RegionVar, !NameToVar, !VarSet,
> + !VarTypes),
> + generate_simple_call(mercury_region_builtin_module,
> + remove_region_pred_name, pf_predicate, only_mode, detism_det,
> + purity_impure, [RegionVar], [], [], ModuleInfo, Context, CallGoal)
> + ;
> + RegionInstruction = rename_region(_, _),
> + unexpected(this_file, "region_instruction_to_conj: " ++
> + "encounter neither create or remove instruction")
> + ),
> + Conjs = Conjs0 ++ [CallGoal].
> +
> % A resurrection renaming annotation is in the form Rx = Rx_resur_y,
> % where Rx is the original name of the region, the other is the one
> % the region is renamed to.
> @@ -860,7 +925,7 @@
> % if-then-else, if such a renaming exists at the current program point.
> %
> :- pred resur_renaming_annotation_to_assignment(renaming::in,
> - region_instruction::in, name_to_prog_var::in, name_to_prog_var::out,
> + region_instr::in, name_to_prog_var::in, name_to_prog_var::out,
> prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
> hlds_goals::in, hlds_goals::out) is det.
>
> @@ -888,7 +953,7 @@
> % an assignment. No renaming needs to be applied to the
> % if-then-else renaming annotations.
> %
> -:- pred ite_renaming_annotation_to_assignment(region_instruction::in,
> +:- pred ite_renaming_annotation_to_assignment(region_instr::in,
> name_to_prog_var::in, name_to_prog_var::out,
> prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
> hlds_goals::in, hlds_goals::out) is det.
--------------------------------------------------------------------------
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