[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