[m-rev.] For review: Annotate the HLDS with regions

Quan Phan Quan.Phan at cs.kuleuven.be
Fri Jun 29 14:40:17 AEST 2007


Hi,

Estimated hours taken: 48.
Branch: main.

Annotate the HLDS with information about region information. This includes:
- Adding calls to region builtins, which are defined in
library/region_builtin.m, currently they are methods for creating and 
removing regions.
- Adding extra region arguments for procedures and calls, so that regions can
be passed between procedure calls. The extra region arguments are appended at
the end of the argument list for predicates. For functions, we make sure that
the output argument is always at the last so they are added before the last.
- Annotating construction unifications with regions so that terms can be
constructed in regions. The changes here must be consistent with the changes
necessary in unify_gen.m (which will be posted in another email). This means
that we will only update constructions of terms which are actually stored on
the heap.

After the region transformation each procedure needs to be requantified. After
ALL the procedures have been transformed and requantified, instmap delta is
recomputed and purity is rechecked. That is necessary because requantification
and repurity check lookup information about the transformed procedures.

The annotated HLDS can be viewed by compiling with --dump-hlds=240.

compiler/hlds_goal.m:
        Add another type constructor for how_to_construct to allow
	constructing terms in regions.

compiler/goal_util.m
compiler/hlds_out.m
compiler/ml_unify_gen.m
compiler/interval.m
compiler/structure_reuse.indirect.m
	Simple change to suit with the above additional type constructor.

compiler/quantification.m
	Change to suit with the additional type constructor. The (region)
	variable in construct_in_region is considered nonlocal to the 
	construction.

compiler/rbmm.condition_renaming.m:
	Change the algorithm so that the transformation needed to solve the
	problem with if-then-else is derived after the region annotated
	program has been transformed for solving the region resurrection
	problem. This is needed because the solution to region resurrection
	problem may introduce bindings of non-local region variables inside
	condition goal of an if-then-else.

compiler/rbmm.execution_path.m:
	Correct a typo.  
									
compiler/rbmm.m:
	Add a new submodule region_transformation.
	Call to region_transform to actually update the HLDS with region
	information.

compiler/rbmm.region_resurrection_renaming.m:
	Provide better comments. Reordering some predicates to suit with
	the flow of computation.

compiler/rbmm.region_transformation.m:
	New file.
	Annotate the HLDS with region information to prepare for code
	generation.

compiler/rbmm.actual_region_arguments.m:
	Change the data structure so that the actual region arguments are 
	separated into "in" and "out" groups.


Index: hlds_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.177
diff -u -u -r1.177 hlds_goal.m
--- hlds_goal.m	13 Apr 2007 04:56:39 -0000	1.177
+++ hlds_goal.m	22 Jun 2007 11:39:51 -0000
@@ -521,7 +521,7 @@
     % This type contains the fields of a construct unification that are needed
     % only rarely. If a value of this type is bound to no_construct_sub_info,
     % this means the same as construct_sub_info(no, no), but takes less space.
-    % This matters because a modules have lots of construct unifications.
+    % This matters because a module has lots of construct unifications.
 :- type construct_sub_info
     --->    construct_sub_info(
                 take_address_fields     :: maybe(list(int)),
@@ -764,11 +764,15 @@
 :- type how_to_construct
     --->    construct_statically(
                 % Use a statically initialized constant.
-
                 args :: list(static_cons)
             )
+
     ;       construct_dynamically
-            % Allocate a new term on the heap
+            % Allocate a new term on the heap.
+
+    ;
+            construct_in_region(prog_var)
+            % Allocate a new term in a region.
 
     ;       reuse_cell(cell_to_reuse).
             % Reuse an existing heap cell.
Index: goal_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.147
diff -u -u -r1.147 goal_util.m
--- goal_util.m	13 Apr 2007 04:56:38 -0000	1.147
+++ goal_util.m	12 Jun 2007 00:53:08 -0000
@@ -709,6 +709,10 @@
     ;
         How0 = construct_statically(_),
         How = How0
+    ;
+        How0 = construct_in_region(RegVar0),
+        rename_var(Must, Subn, RegVar0, RegVar),
+        How = construct_in_region(RegVar)
     ),
     (
         SubInfo0 = construct_sub_info(MTA, MaybeSize0),
Index: hlds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.426
diff -u -u -r1.426 hlds_out.m
--- hlds_out.m	17 May 2007 03:52:43 -0000	1.426
+++ hlds_out.m	12 Jun 2007 01:02:13 -0000
@@ -2367,6 +2367,12 @@
         io.write_string("% reuse cell: ", !IO),
         mercury_output_var(ProgVarSet, AppendVarNums, ReuseVar, !IO),
         io.write_string("\n", !IO)
+    ;
+        ConstructHow = construct_in_region(RegVar),
+        write_indent(Indent, !IO),
+        io.write_string(" construct in region: ", !IO),
+        mercury_output_var(ProgVarSet, AppendVarNums, RegVar, !IO),
+        io.write_string("\n", !IO)
     ).
 
 write_unification(deconstruct(Var, ConsId, ArgVars, ArgModes, CanFail, CanCGC),
Index: ml_unify_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_unify_gen.m,v
retrieving revision 1.112
diff -u -u -r1.112 ml_unify_gen.m
--- ml_unify_gen.m	17 May 2007 01:09:58 -0000	1.112
+++ ml_unify_gen.m	12 Jun 2007 01:43:18 -0000
@@ -787,6 +787,10 @@
 
         Decls = [],
         Statements = [Statement | Statements0]
+    ;
+        HowToConstruct = construct_in_region(_RegVar),
+        sorry(this_file, "ml_gen_new_object: " ++
+            "implementation for construct_in_region is not available")
     ).
 
 :- pred ml_gen_field_take_address_assigns(list(take_addr_info)::in,
Index: interval.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/interval.m,v
retrieving revision 1.29
diff -u -u -r1.29 interval.m
--- interval.m	12 Jun 2007 07:21:25 -0000	1.29
+++ interval.m	27 Jun 2007 06:04:14 -0000
@@ -353,6 +353,11 @@
                 HowToConstruct = reuse_cell(_),
                 unexpected(this_file, "build_interval_info_in_goal: reuse")
             ;
+                % XXX Temporary for the time being.
+                HowToConstruct = construct_in_region(_),
+                unexpected(this_file,
+                    "build_interval_info_in_goal: construct in region")
+            ;
                 ( HowToConstruct = construct_statically(_)
                 ; HowToConstruct = construct_dynamically
                 )
Index: quantification.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/quantification.m,v
retrieving revision 1.116
diff -u -u -r1.116 quantification.m
--- quantification.m	12 Jun 2007 07:21:25 -0000	1.116
+++ quantification.m	22 Jun 2007 11:46:17 -0000
@@ -513,13 +513,20 @@
         (
             How = reuse_cell(cell_to_reuse(ReuseVar0, _, SetArgs)),
             MaybeSetArgs = yes(SetArgs),
-            MaybeReuseVar = yes(ReuseVar0)
+            MaybeReuseVar = yes(ReuseVar0),
+            MaybeRegionVar = no
+        ;
+            How = construct_in_region(RegionVar0),
+            MaybeSetArgs = no,
+            MaybeReuseVar = no,
+            MaybeRegionVar = yes(RegionVar0)
         ;
             ( How = construct_statically(_)
             ; How = construct_dynamically
             ),
             MaybeSetArgs = no,
-            MaybeReuseVar = no
+            MaybeReuseVar = no,
+            MaybeRegionVar = no
         ),
         (
             SubInfo = construct_sub_info(_, MaybeSize),
@@ -532,7 +539,8 @@
     ;
         MaybeSetArgs = no,
         MaybeReuseVar = no,
-        MaybeSizeVar = no
+        MaybeSizeVar = no,
+        MaybeRegionVar = no
     ),
     implicitly_quantify_unify_rhs(MaybeSetArgs, Context, UnifyRHS0, UnifyRHS,
         Unification0, Unification, !Info),
@@ -549,10 +557,17 @@
     ),
     (
         MaybeSizeVar = yes(SizeVar),
-        insert(GoalVars2, SizeVar, GoalVars)
+        insert(GoalVars2, SizeVar, GoalVars3)
     ;
         MaybeSizeVar = no,
-        GoalVars = GoalVars2
+        GoalVars3 = GoalVars2
+    ),
+    (
+        MaybeRegionVar = yes(RegionVar),
+        insert(GoalVars3, RegionVar, GoalVars)
+    ;
+        MaybeRegionVar = no,
+        GoalVars = GoalVars3
     ),
     update_seen_vars(GoalVars, !Info),
     intersect(GoalVars, OutsideVars, NonLocalVars1),
@@ -1127,6 +1142,10 @@
             MaybeSetArgs = yes(SetArgs),
             insert(!.Set, ReuseVar, !:Set)
         ;
+            How = construct_in_region(RegionVar),
+            MaybeSetArgs = no,
+            insert(!.Set, RegionVar, !:Set)
+        ;
             ( How = construct_statically(_)
             ; How = construct_dynamically
             ),
Index: structure_reuse.indirect.m
===================================================================
RCS file:
/home/mercury/mercury1/repository/mercury/compiler/structure_reuse.indirect.m,v
retrieving revision 1.10
diff -u -u -r1.10 structure_reuse.indirect.m
--- structure_reuse.indirect.m	12 Jun 2007 07:21:26 -0000	1.10
+++ structure_reuse.indirect.m	22 Jun 2007 12:29:32 -0000
@@ -302,6 +302,7 @@
             ;
                 ( HowToConstruct = construct_dynamically
                 ; HowToConstruct = reuse_cell(_)
+                ; HowToConstruct = construct_in_region(_) 
                 )
             )
         ;
Index: rbmm.condition_renaming.m
===================================================================
RCS file:
/home/mercury/mercury1/repository/mercury/compiler/rbmm.condition_renaming.m,v
retrieving revision 1.2
diff -u -u -r1.2 rbmm.condition_renaming.m
--- rbmm.condition_renaming.m	15 Jun 2007 11:46:11 -0000	1.2
+++ rbmm.condition_renaming.m	27 Jun 2007 06:05:22 -0000
@@ -16,6 +16,17 @@
 % program point so that the binding of non-local regions in the condition
 % goal of an if-then-else is resolved. 
 %
+% When reasoning about the renaming and reverse renaming needed for
+% an if-then-else here we take into account the changes to regions caused
+% by the renaming and renaming annotations needed for region resurrection.
+% This can be viewed as if the program is transformed by the renaming
+% and reverse renaming for region resurrection first. This is to solve the
+% problem with region resurrection. Then that transformed program is
+% transformed again to solve the problem with if-then-else. Note that the
+% first transformation may add to the problem with if-then-else, e.g.,
+% when it introduces reverse renaming to a non-local variable inside the
+% condition goal of an if-then-else.
+%
 %-----------------------------------------------------------------------------%
 
 :- module transform_hlds.rbmm.condition_renaming.
@@ -31,12 +42,14 @@
 :- import_module transform_hlds.rbmm.region_resurrection_renaming.
 
 :- import_module map.
+:- import_module set.
+:- import_module string.
 
 %-----------------------------------------------------------------------------%
 
 :- type proc_goal_path_regions_table ==
	map(pred_proc_id, goal_path_regions_table).
-:- type goal_path_regions_table == map(goal_path, region_set).
+:- type goal_path_regions_table == map(goal_path, set(string)).
 
	% This predicate collects two pieces of information.
	% 1. The non-local regions of if-then-elses.
@@ -46,17 +59,18 @@
	% 2. The regions which are created (get bound) in the condition
	% goals of if-then-else.
	% We will only store information about a procedure if the information
-	% exists. That means, for example, there is no entry from PPId to
-	% empty.
+	% exists. That means, for example, there is no entry which maps a PPId
+	% to empty.
	%
	% This information is used to compute the regions which need to be 
	% renamed, i.e., both non-local and created in the condition of an
	% if-then-else.
	%
 :- pred collect_non_local_and_in_cond_regions(module_info::in,
-	proc_pp_region_set_table::in, proc_pp_region_set_table::in, 
-	proc_goal_path_regions_table::out, proc_goal_path_regions_table::out)
-	is det.
+	rpta_info_table::in, proc_pp_region_set_table::in,
+	proc_pp_region_set_table::in, renaming_table::in, 
+	renaming_annotation_table::in, proc_goal_path_regions_table::out,
+	proc_goal_path_regions_table::out) is det.
 
	% After having the 2 pieces of information calculated above, this step
	% is simple. The only thing to note here is that we will only store
@@ -117,41 +131,50 @@
 :- import_module list.
 :- import_module pair.
 :- import_module set.
-:- import_module string.
 :- import_module svmap.
+:- import_module svset.
 
 %-----------------------------------------------------------------------------%
 
-collect_non_local_and_in_cond_regions(ModuleInfo, LRBeforeTable,
-		LRAfterTable, NonLocalRegionsTable, InCondRegionsTable) :-
+collect_non_local_and_in_cond_regions(ModuleInfo, RptaInfoTable,
+		LRBeforeTable, LRAfterTable, ResurRenamingTable,
+		ResurRenamingAnnoTable, NonLocalRegionsTable, InCondRegionsTable) :-
     module_info_predids(PredIds, ModuleInfo, _),
     list.foldl2(collect_non_local_and_in_cond_regions_pred(ModuleInfo,
-		LRBeforeTable, LRAfterTable), PredIds,
+		RptaInfoTable, LRBeforeTable, LRAfterTable, ResurRenamingTable,
+		ResurRenamingAnnoTable), PredIds,
		map.init, NonLocalRegionsTable, map.init, InCondRegionsTable).
 
 :- pred collect_non_local_and_in_cond_regions_pred(module_info::in,
-	proc_pp_region_set_table::in, proc_pp_region_set_table::in, pred_id::in,
+	rpta_info_table::in, proc_pp_region_set_table::in,
+	proc_pp_region_set_table::in, renaming_table::in,
+	renaming_annotation_table::in, pred_id::in,
	proc_goal_path_regions_table::in, proc_goal_path_regions_table::out,
	proc_goal_path_regions_table::in, proc_goal_path_regions_table::out)
	is det.
 
-collect_non_local_and_in_cond_regions_pred(ModuleInfo, LRBeforeTable,
-		LRAfterTable, PredId, !NonLocalRegionsTable, !InCondRegionsTable) :-
+collect_non_local_and_in_cond_regions_pred(ModuleInfo, RptaInfoTable,
+		LRBeforeTable, LRAfterTable, ResurRenamingTable,
+		ResurRenamingAnnoTable, PredId, !NonLocalRegionsTable,
+		!InCondRegionsTable) :-
     module_info_pred_info(ModuleInfo, PredId, PredInfo),
     ProcIds = pred_info_non_imported_procids(PredInfo),
     list.foldl2(collect_non_local_and_in_cond_regions_proc(ModuleInfo,
-		PredId, LRBeforeTable, LRAfterTable), ProcIds,
+		PredId, RptaInfoTable, LRBeforeTable, LRAfterTable,
+		ResurRenamingTable, ResurRenamingAnnoTable), ProcIds,
		!NonLocalRegionsTable, !InCondRegionsTable).
 
 :- pred collect_non_local_and_in_cond_regions_proc(module_info::in,
-	pred_id::in, proc_pp_region_set_table::in,
-	proc_pp_region_set_table::in, proc_id::in,
+	pred_id::in, rpta_info_table::in, proc_pp_region_set_table::in,
+	proc_pp_region_set_table::in, renaming_table::in,
+	renaming_annotation_table::in, proc_id::in,
	proc_goal_path_regions_table::in, proc_goal_path_regions_table::out,
	proc_goal_path_regions_table::in, proc_goal_path_regions_table::out)
	is det.
 
 collect_non_local_and_in_cond_regions_proc(ModuleInfo, PredId,
-		LRBeforeTable, LRAfterTable, ProcId,
+		RptaInfoTable, LRBeforeTable, LRAfterTable, ResurRenamingTable,
+		ResurRenamingAnnoTable, ProcId,
		!NonLocalRegionsTable, !InCondRegionsTable) :-
     PPId = proc(PredId, ProcId),
     ( if    some_are_special_preds([PPId], ModuleInfo)
@@ -160,115 +183,157 @@
             module_info_proc_info(ModuleInfo, PPId, ProcInfo0),
			fill_goal_path_slots(ModuleInfo, ProcInfo0, ProcInfo),
             proc_info_get_goal(ProcInfo, Goal),
+			map.lookup(RptaInfoTable, PPId, rpta_info(Graph, _)),
			map.lookup(LRBeforeTable, PPId, LRBeforeProc),
			map.lookup(LRAfterTable, PPId, LRAfterProc),
-            collect_non_local_and_in_cond_regions_goal(LRBeforeProc,
-				LRAfterProc, Goal,
+			( if	map.search(ResurRenamingTable, PPId,
+						ResurRenamingProc0)
+			  then	ResurRenamingProc = ResurRenamingProc0
+			  else	ResurRenamingProc = map.init
+			),
+			( if	map.search(ResurRenamingAnnoTable, PPId,
+						ResurRenamingAnnoProc0)
+			  then	ResurRenamingAnnoProc = ResurRenamingAnnoProc0
+			  else	ResurRenamingAnnoProc = map.init
+			),
+            collect_non_local_and_in_cond_regions_goal(Graph,
+				LRBeforeProc, LRAfterProc, ResurRenamingProc,
+				ResurRenamingAnnoProc, Goal,
				map.init, NonLocalRegionsProc,
				map.init, InCondRegionsProc),
			( if	map.count(NonLocalRegionsProc) = 0
-			  then	true
-			  else	svmap.set(PPId, NonLocalRegionsProc, !NonLocalRegionsTable)
+			  then	true
+			  else	svmap.set(PPId, NonLocalRegionsProc,
+						!NonLocalRegionsTable)
			),
			( if	map.count(InCondRegionsProc) = 0
-			  then	true
-			  else	svmap.set(PPId, InCondRegionsProc, !InCondRegionsTable)
+			  then	true
+			  else	svmap.set(PPId, InCondRegionsProc,
+						!InCondRegionsTable)
			)
     ).
 
-:- pred collect_non_local_and_in_cond_regions_goal(pp_region_set_table::in,
-	pp_region_set_table::in, hlds_goal::in,
+:- pred collect_non_local_and_in_cond_regions_goal(rpt_graph::in,
+	pp_region_set_table::in, pp_region_set_table::in,
+	renaming_proc::in, renaming_annotation_proc::in, hlds_goal::in,
     goal_path_regions_table::in, goal_path_regions_table::out,
	goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
-collect_non_local_and_in_cond_regions_goal(LRBeforeProc, LRAfterProc, Goal,
+collect_non_local_and_in_cond_regions_goal(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc, Goal,
		!NonLocalRegionsProc, !InCondRegionsProc) :- 
	Goal = hlds_goal(Expr, _),
-	collect_non_local_and_in_cond_regions_expr(LRBeforeProc, LRAfterProc,
-		Expr, !NonLocalRegionsProc, !InCondRegionsProc).
+	collect_non_local_and_in_cond_regions_expr(Graph, LRBeforeProc,
+		LRAfterProc, ResurRenamingProc, ResurRenamingAnnoProc, Expr,
+		!NonLocalRegionsProc, !InCondRegionsProc).
 
-:- pred collect_non_local_and_in_cond_regions_expr(pp_region_set_table::in,
-	pp_region_set_table::in, hlds_goal_expr::in,
+:- pred collect_non_local_and_in_cond_regions_expr(rpt_graph::in,
+	pp_region_set_table::in, pp_region_set_table::in,
+	renaming_proc::in, renaming_annotation_proc::in, hlds_goal_expr::in,
	goal_path_regions_table::in, goal_path_regions_table::out,
	goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
-collect_non_local_and_in_cond_regions_expr(LRBeforeProc, LRAfterProc,
-		conj(_, Conjs), !NonLocalRegionsProc, !InCondRegionsProc) :- 
-    list.foldl2(collect_non_local_and_in_cond_regions_goal(LRBeforeProc,
-					LRAfterProc),
+collect_non_local_and_in_cond_regions_expr(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc, conj(_, Conjs),
+		!NonLocalRegionsProc, !InCondRegionsProc) :- 
+    list.foldl2(collect_non_local_and_in_cond_regions_goal(Graph,
+					LRBeforeProc, LRAfterProc,
+					ResurRenamingProc,
+					ResurRenamingAnnoProc),
		Conjs, !NonLocalRegionsProc, !InCondRegionsProc). 
 
-collect_non_local_and_in_cond_regions_expr(_, _,
+collect_non_local_and_in_cond_regions_expr(_, _, _, _, _,
		plain_call(_, _, _, _, _, _),
		!NonLocalRegionsProc, !InCondRegionsProc).
-collect_non_local_and_in_cond_regions_expr(_, _, generic_call(_, _, _, _),
+collect_non_local_and_in_cond_regions_expr(_, _, _, _, _,
+		generic_call(_, _, _, _),
		!NonLocalRegionsProc, !InCondRegionsProc).
-collect_non_local_and_in_cond_regions_expr(_, _,
+collect_non_local_and_in_cond_regions_expr(_, _, _, _, _,
		call_foreign_proc(_, _, _, _, _, _, _),
		!NonLocalRegionsProc, !InCondRegionsProc).
 
-collect_non_local_and_in_cond_regions_expr(LRBeforeProc, LRAfterProc,
-		switch(_, _, Cases), !NonLocalRegionsProc, !InCondRegionsProc) :- 
-    list.foldl2(collect_non_local_and_in_cond_regions_case(LRBeforeProc,
-					LRAfterProc),
+collect_non_local_and_in_cond_regions_expr(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc, switch(_, _, Cases),
+		!NonLocalRegionsProc, !InCondRegionsProc) :- 
+    list.foldl2(collect_non_local_and_in_cond_regions_case(Graph,
+					LRBeforeProc, LRAfterProc,
+					ResurRenamingProc,
+					ResurRenamingAnnoProc),
		Cases, !NonLocalRegionsProc, !InCondRegionsProc).
-collect_non_local_and_in_cond_regions_expr(LRBeforeProc, LRAfterProc,
-		disj(Disjs), !NonLocalRegionsProc, !InCondRegionsProc) :-
-    list.foldl2(collect_non_local_and_in_cond_regions_goal(LRBeforeProc,
-					LRAfterProc),
+collect_non_local_and_in_cond_regions_expr(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc, disj(Disjs),
+		!NonLocalRegionsProc, !InCondRegionsProc) :-
+    list.foldl2(collect_non_local_and_in_cond_regions_goal(Graph,
+					LRBeforeProc, LRAfterProc,
+					ResurRenamingProc,
+					ResurRenamingAnnoProc),
		Disjs, !NonLocalRegionsProc, !InCondRegionsProc). 
-collect_non_local_and_in_cond_regions_expr(LRBeforeProc, LRAfterProc,
-		negation(Goal), !NonLocalRegionsProc, !InCondRegionsProc) :- 
-    collect_non_local_and_in_cond_regions_goal(LRBeforeProc, LRAfterProc,
-		Goal, !NonLocalRegionsProc, !InCondRegionsProc). 
-collect_non_local_and_in_cond_regions_expr(_, _, unify(_, _, _, _, _),
-		!NonLocalRegionsProc, !InCondRegionsProc).
+collect_non_local_and_in_cond_regions_expr(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc, negation(Goal),
+		!NonLocalRegionsProc, !InCondRegionsProc) :- 
+    collect_non_local_and_in_cond_regions_goal(Graph, LRBeforeProc,
+		LRAfterProc, ResurRenamingProc, ResurRenamingAnnoProc, Goal,
+		!NonLocalRegionsProc, !InCondRegionsProc). 
+collect_non_local_and_in_cond_regions_expr(_, _, _, _, _,
+		unify(_, _, _, _, _), !NonLocalRegionsProc, !InCondRegionsProc).
 
-collect_non_local_and_in_cond_regions_expr(LRBeforeProc, LRAfterProc,
-		scope(_, Goal), !NonLocalRegionsProc, !InCondRegionsProc) :- 
-	collect_non_local_and_in_cond_regions_goal(LRBeforeProc, LRAfterProc,
-		Goal, !NonLocalRegionsProc, !InCondRegionsProc).
+collect_non_local_and_in_cond_regions_expr(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc, scope(_, Goal),
+		!NonLocalRegionsProc, !InCondRegionsProc) :- 
+	collect_non_local_and_in_cond_regions_goal(Graph, LRBeforeProc,
+		LRAfterProc, ResurRenamingProc, ResurRenamingAnnoProc, Goal,
+		!NonLocalRegionsProc, !InCondRegionsProc).
 
-collect_non_local_and_in_cond_regions_expr(LRBeforeProc, LRAfterProc, Expr,
+collect_non_local_and_in_cond_regions_expr(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc, Expr,
		!NonLocalRegionProc, !InCondRegionsProc) :- 
	Expr = if_then_else(_, Cond, Then, Else),
 
	% We only care about regions created inside condition goals.
-	collect_regions_created_in_condition(LRBeforeProc, LRAfterProc, Cond,
+	collect_regions_created_in_condition(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc, Cond,
		!InCondRegionsProc),
 
	% The sets of non_local regions in the (Cond, Then) and in the (Else)
	% branch are the same, therefore we will only calculate in one of them.
	% As it is here, we calculate for (Else) with the hope that it is
	% usually more efficient (only Else compared to both Cond and Then).
-    collect_non_local_and_in_cond_regions_goal(LRBeforeProc, LRAfterProc,
+    collect_non_local_and_in_cond_regions_goal(Graph, LRBeforeProc,
+		LRAfterProc, ResurRenamingProc, ResurRenamingAnnoProc,
		Cond, !NonLocalRegionProc, !InCondRegionsProc),
-    collect_non_local_and_in_cond_regions_goal(LRBeforeProc, LRAfterProc,
+    collect_non_local_and_in_cond_regions_goal(Graph, LRBeforeProc,
+		LRAfterProc, ResurRenamingProc, ResurRenamingAnnoProc,
		Then, !NonLocalRegionProc, !InCondRegionsProc),
-    collect_non_local_regions_in_ite(LRBeforeProc, LRAfterProc, Else,
+    collect_non_local_regions_in_ite(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc, Else,
		!NonLocalRegionProc).
 
-collect_non_local_and_in_cond_regions_expr(_, _, shorthand(_),
+collect_non_local_and_in_cond_regions_expr(_, _, _, _, _, shorthand(_),
		!NonLocalRegionProc, !InCondRegionsProc) :- 
     unexpected(this_file, "collect_non_local_and_in_cond_regions_expr: "
		++ "shorthand not handled").
 
-:- pred collect_non_local_and_in_cond_regions_case(pp_region_set_table::in,
-	pp_region_set_table::in, case::in,
+:- pred collect_non_local_and_in_cond_regions_case(rpt_graph::in,
+	pp_region_set_table::in, pp_region_set_table::in,
+	renaming_proc::in, renaming_annotation_proc::in, case::in,
	goal_path_regions_table::in, goal_path_regions_table::out,
	goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
-collect_non_local_and_in_cond_regions_case(LRBeforeProc, LRAfterProc, Case,
+collect_non_local_and_in_cond_regions_case(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc, Case,
		!NonLocalRegionProc, !InCondRegionsProc) :-
     Case = case(_, Goal),
-    collect_non_local_and_in_cond_regions_goal(LRBeforeProc, LRAfterProc,
-		Goal, !NonLocalRegionProc, !InCondRegionsProc).
-
-:- pred collect_non_local_regions_in_ite(pp_region_set_table::in, 
-	pp_region_set_table::in, hlds_goal::in, goal_path_regions_table::in,
-	goal_path_regions_table::out) is det.
+    collect_non_local_and_in_cond_regions_goal(Graph, LRBeforeProc,
+		LRAfterProc, ResurRenamingProc, ResurRenamingAnnoProc, Goal,
+		!NonLocalRegionProc, !InCondRegionsProc).
+
+:- pred collect_non_local_regions_in_ite(rpt_graph::in,
+	pp_region_set_table::in, pp_region_set_table::in, renaming_proc::in,
+	renaming_annotation_proc::in, hlds_goal::in,
+	goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
-collect_non_local_regions_in_ite(LRBeforeProc, LRAfterProc, GoalInIte,
+collect_non_local_regions_in_ite(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc, GoalInIte,
		!NonLocalRegionProc) :-
	GoalInIte = hlds_goal(Expr, Info),
	( if	goal_is_atomic(Expr)
@@ -278,19 +343,80 @@
			map.lookup(LRBeforeProc, ProgPoint, LRBefore),
			map.lookup(LRAfterProc, ProgPoint, LRAfter),
			
-			% XXX We may also need VoidVarRegionTable to be included
-			% in RemovedAfter.
-			set.difference(LRBefore, LRAfter, RemovedAfter),
-			set.difference(LRAfter, LRBefore, CreatedBefore),
-
-			record_non_local_regions(GoalPath, CreatedBefore,
-				RemovedAfter, !NonLocalRegionProc)
+			% XXX We may also need VoidVarRegionTable to be
+			% included in RemovedAfter.
+			set.difference(LRBefore, LRAfter, RemovedAfterNodes),
+			set.difference(LRAfter, LRBefore, CreatedBeforeNodes),
+			% Those sets need to subject to resurrection renaming
+			% and annotations.
+			% Apply resurrection renaming to those sets.
+			% For each renaming annotation, the left one is put
+			% into CreatedBefore, and the right one is put into
+			% RemovedAfter.
+			( if	map.search(ResurRenamingProc, ProgPoint,
+						ResurRenaming0)
+			  then	ResurRenaming = ResurRenaming0
+			  else  ResurRenaming = map.init
+			),
+			set.fold(apply_region_renaming(Graph, ResurRenaming),
+				RemovedAfterNodes, set.init,
+				RemovedAfterRegions0),
+			set.fold(apply_region_renaming(Graph, ResurRenaming),
+				CreatedBeforeNodes, set.init,
+				CreatedBeforeRegions0),
+
+			( if	map.search(ResurRenamingAnnoProc, ProgPoint,
+						ResurRenamingAnnos0)
+			  then	ResurRenamingAnnos = ResurRenamingAnnos0
+			  else	ResurRenamingAnnos = []
+			),  
+			list.foldl2(renaming_annotation_to_regions,
+				ResurRenamingAnnos, set.init, LeftRegions,
+				set.init, RightRegions),
+			set.union(RemovedAfterRegions0, RightRegions,
+				RemovedAfterRegions),
+			set.union(CreatedBeforeRegions0, LeftRegions,
+				CreatedBeforeRegions),
+			record_non_local_regions(GoalPath, CreatedBeforeRegions,
+				RemovedAfterRegions, !NonLocalRegionProc)
	  else
-			collect_non_local_regions_in_ite_compound_goal(
-				LRBeforeProc, LRAfterProc, GoalInIte,
+			collect_non_local_regions_in_ite_compound_goal(Graph,
+				LRBeforeProc, LRAfterProc, ResurRenamingProc,
+				ResurRenamingAnnoProc, GoalInIte,
				!NonLocalRegionProc)
	).
 
+:- pred apply_region_renaming(rpt_graph::in, renaming::in, rptg_node::in,
+	set(string)::in, set(string)::out) is det.
+
+apply_region_renaming(Graph, Renaming, Node, !Regions) :-
+	RegionName = rptg_lookup_region_name(Graph, Node),	
+	( if	map.search(Renaming, RegionName, RenamedRegionName)
+	  then	svset.insert(RenamedRegionName, !Regions)
+	  else	svset.insert(RegionName, !Regions)
+	).
+			
+:- pred renaming_annotation_to_regions(string::in,
+	set(string)::in, set(string)::out,
+	set(string)::in, set(string)::out) is det.
+
+renaming_annotation_to_regions(RenameAnnotation, !LeftRegions,
+		!RightRegions) :-
+	( if	string.sub_string_search(RenameAnnotation, "=", Index)
+	  then
+			LeftRegion = string.substring(RenameAnnotation, 0,
+				Index - 1),
+
+			RightRegion = string.substring(RenameAnnotation,
+				Index + 2,
+				string.length(RenameAnnotation) - (Index + 2)),
+			svset.insert(LeftRegion, !LeftRegions),
+			svset.insert(RightRegion, !RightRegions)
+	  else
+			unexpected(this_file, "renaming_annotation_to_regions: "
+				++ "annotation is not assignment")
+	).
+
	% The non-local regions of an if-then-else will be attached to 
	% the goal path to the condition.
	% Non-local regions of an if-then-else are ones that are created
@@ -311,8 +437,8 @@
	% non-local sets of all the surrounding if-then-elses of this
	% program point.
	%
-:- pred record_non_local_regions(goal_path::in, region_set::in,
-	region_set::in, goal_path_regions_table::in,
+:- pred record_non_local_regions(goal_path::in, set(string)::in,
+	set(string)::in, goal_path_regions_table::in,
	goal_path_regions_table::out) is det.
 
 record_non_local_regions([], _, _, !NonLocalRegionProc).
@@ -324,17 +450,22 @@
		% The current NonLocalRegions are attached to the goal path to
		% the corresponding condition.
		PathToCond = [step_ite_cond | Steps],
-		( if	map.search(!.NonLocalRegionProc, PathToCond, NonLocalRegions0)
+		( if	map.search(!.NonLocalRegionProc, PathToCond,
+					NonLocalRegions0)
		  then
-				set.union(NonLocalRegions0, Created, NonLocalRegions1),
-				set.difference(NonLocalRegions1, Removed, NonLocalRegions)
+				set.union(NonLocalRegions0, Created,
+					NonLocalRegions1),
+				set.difference(NonLocalRegions1, Removed,
+					NonLocalRegions)
		  else
-				set.difference(Created, Removed, NonLocalRegions)
+				set.difference(Created, Removed,
+					NonLocalRegions)
		),
		% Only record if some non-local region(s) exist.
		( if	set.empty(NonLocalRegions)
		  then	true
-		  else	svmap.set(PathToCond, NonLocalRegions, !NonLocalRegionProc)
+		  else	svmap.set(PathToCond, NonLocalRegions,
+					!NonLocalRegionProc)
		)
	;
		true
@@ -344,41 +475,54 @@
	% one, if any.
	record_non_local_regions(Steps, Created, Removed, !NonLocalRegionProc).
 
-:- pred collect_non_local_regions_in_ite_compound_goal(
-	pp_region_set_table::in, pp_region_set_table::in, hlds_goal::in,
+:- pred collect_non_local_regions_in_ite_compound_goal(rpt_graph::in,
+	pp_region_set_table::in, pp_region_set_table::in,
+	renaming_proc::in, renaming_annotation_proc::in, hlds_goal::in,
	goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
-collect_non_local_regions_in_ite_compound_goal(LRBeforeProc, LRAfterProc,
+collect_non_local_regions_in_ite_compound_goal(Graph, LRBeforeProc,
+		LRAfterProc, ResurRenamingProc, ResurRenamingAnnoProc,
		GoalInIte, !NonLocalRegionProc) :-
	GoalInIte = hlds_goal(Expr, _),
	(
		Expr = conj(_, [Conj | Conjs]),
-		list.foldl(collect_non_local_regions_in_ite(LRBeforeProc, LRAfterProc), 
+		list.foldl(collect_non_local_regions_in_ite(Graph, LRBeforeProc,
+						LRAfterProc, ResurRenamingProc,
+						ResurRenamingAnnoProc), 
			[Conj | Conjs], !NonLocalRegionProc)
	;
		Expr = disj([Disj | Disjs]),
-		list.foldl(collect_non_local_regions_in_ite(LRBeforeProc, LRAfterProc), 
+		list.foldl(collect_non_local_regions_in_ite(Graph, LRBeforeProc,
+						LRAfterProc, ResurRenamingProc,
+						ResurRenamingAnnoProc), 
			[Disj | Disjs], !NonLocalRegionProc)
	;
		Expr = switch(_, _, Cases),
-		list.foldl(
-			collect_non_local_regions_in_ite_case(LRBeforeProc, LRAfterProc),
+		list.foldl(collect_non_local_regions_in_ite_case(Graph,
+						LRBeforeProc, LRAfterProc,
+						ResurRenamingProc,
+						ResurRenamingAnnoProc),
			Cases, !NonLocalRegionProc)
	;
		Expr = negation(Goal),
-		collect_non_local_regions_in_ite(LRBeforeProc, LRAfterProc,
+		collect_non_local_regions_in_ite(Graph, LRBeforeProc,
+			LRAfterProc, ResurRenamingProc, ResurRenamingAnnoProc,
			Goal, !NonLocalRegionProc)
	;
		Expr = scope(_, Goal),
-		collect_non_local_regions_in_ite(LRBeforeProc, LRAfterProc,
+		collect_non_local_regions_in_ite(Graph, LRBeforeProc,
+			LRAfterProc, ResurRenamingProc, ResurRenamingAnnoProc,
			Goal, !NonLocalRegionProc)
	;
		Expr = if_then_else(_, Cond, Then, Else),
-		collect_non_local_regions_in_ite(LRBeforeProc, LRAfterProc,
+		collect_non_local_regions_in_ite(Graph, LRBeforeProc,
+			LRAfterProc, ResurRenamingProc, ResurRenamingAnnoProc,
			Cond, !NonLocalRegionProc),
-		collect_non_local_regions_in_ite(LRBeforeProc, LRAfterProc,
+		collect_non_local_regions_in_ite(Graph, LRBeforeProc,
+			LRAfterProc, ResurRenamingProc, ResurRenamingAnnoProc,
			Then, !NonLocalRegionProc),
-		collect_non_local_regions_in_ite(LRBeforeProc, LRAfterProc,
+		collect_non_local_regions_in_ite(Graph, LRBeforeProc,
+			LRAfterProc, ResurRenamingProc, ResurRenamingAnnoProc,
			Else, !NonLocalRegionProc)
	;
		( Expr = unify(_, _, _, _, _) 
@@ -394,14 +538,16 @@
			++ "encountered atomic or unsupported goal")
	).
 
-:- pred collect_non_local_regions_in_ite_case(pp_region_set_table::in,
-	pp_region_set_table::in, case::in, goal_path_regions_table::in,
-	goal_path_regions_table::out) is det.
+:- pred collect_non_local_regions_in_ite_case(rpt_graph::in,
+	pp_region_set_table::in, pp_region_set_table::in,
+	renaming_proc::in, renaming_annotation_proc::in, case::in,
+	goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
-collect_non_local_regions_in_ite_case(LRBeforeProc, LRAfterProc, Case,
+collect_non_local_regions_in_ite_case(Graph, LRBeforeProc, LRAfterProc,
ResurRenamingProc, ResurRenamingAnnoProc, Case,
		!NonLocalRegionProc) :-
	Case = case(_, Goal),
-	collect_non_local_regions_in_ite(LRBeforeProc, LRAfterProc, Goal,
+	collect_non_local_regions_in_ite(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc, Goal,
		!NonLocalRegionProc).
 
 %-----------------------------------------------------------------------------%
@@ -417,11 +563,13 @@
	% The difference is that this predicate is used only in the scope of
	% a condition goal. 
	%
-:- pred collect_regions_created_in_condition(pp_region_set_table::in, 
-	pp_region_set_table::in, hlds_goal::in, goal_path_regions_table::in,
-	goal_path_regions_table::out) is det.
+:- pred collect_regions_created_in_condition(rpt_graph::in,
+	pp_region_set_table::in, pp_region_set_table::in,
+	renaming_proc::in, renaming_annotation_proc::in, hlds_goal::in,
+	goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
-collect_regions_created_in_condition(LRBeforeProc, LRAfterProc, Cond,
+collect_regions_created_in_condition(Graph, LRBeforeProc, LRAfterProc, 
+		ResurRenamingProc, ResurRenamingAnnoProc, Cond,
		!InCondRegionsProc) :-
	Cond = hlds_goal(Expr, Info),
	( if	goal_is_atomic(Expr)
@@ -431,21 +579,47 @@
			map.lookup(LRBeforeProc, ProgPoint, LRBefore),
			map.lookup(LRAfterProc, ProgPoint, LRAfter),
			
-			set.difference(LRAfter, LRBefore, Created),
-			record_regions_created_in_condition(GoalPath, Created,
-				!InCondRegionsProc)
+			set.difference(LRAfter, LRBefore, CreatedNodes),
+			% We need to apply renaming to this CreatedNodes set
+			% and look up the renaming annotations after this
+			% program point. For each renaming annotation the left
+			% one is created and the right is removed.
+			% XXX This CreatedNodes needs to subject to
+			% resurrection renaming and annotations.
+			( if	map.search(ResurRenamingProc, ProgPoint,
+						ResurRenaming0)
+			  then	ResurRenaming = ResurRenaming0
+			  else  ResurRenaming = map.init
+			),
+			set.fold(apply_region_renaming(Graph, ResurRenaming),
+				CreatedNodes, set.init, CreatedRegions0),
+
+			( if	map.search(ResurRenamingAnnoProc, ProgPoint,
+						ResurRenamingAnnos0)
+			  then	ResurRenamingAnnos = ResurRenamingAnnos0
+			  else	ResurRenamingAnnos = []
+			),  
+			list.foldl2(renaming_annotation_to_regions,
+				ResurRenamingAnnos, set.init, LeftRegions,
+				set.init, _RightRegions),
+			set.union(CreatedRegions0, LeftRegions, CreatedRegions),
+		
+			record_regions_created_in_condition(GoalPath,
+				CreatedRegions, !InCondRegionsProc)
	  else
			collect_regions_created_in_condition_compound_goal(
-				LRBeforeProc, LRAfterProc, Cond, !InCondRegionsProc)
+				Graph, LRBeforeProc, LRAfterProc,
+				ResurRenamingProc, ResurRenamingAnnoProc, Cond,
+				!InCondRegionsProc)
	).
-
+ 
	% The regions created inside the condition of an if-then-else will
	% be attached to the goal path to the condition.
	%
	% We need to update the sets of all the conditions surrounding this
	% program point.
	%
-:- pred record_regions_created_in_condition(goal_path::in, region_set::in,
+:- pred record_regions_created_in_condition(goal_path::in, set(string)::in,
	goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
 record_regions_created_in_condition([], _, !InCondRegionsProc).
@@ -455,57 +629,70 @@
		Step = step_ite_cond
	->
		( if	map.search(!.InCondRegionsProc, Path, InCondRegions0)
-		  then	set.union(InCondRegions0, Created, InCondRegions)
+		  then	set.union(InCondRegions0, Created,
+					InCondRegions)
		  else	InCondRegions = Created
		),
		% Only record if the some region(s) is actually created inside
		% the condition.
		( if	set.empty(InCondRegions)
		  then	true
-		  else	svmap.set(Path, InCondRegions, !InCondRegionsProc)
+		  else	svmap.set(Path, InCondRegions, !InCondRegionsProc)
		)
	;
		true
	),
	record_regions_created_in_condition(Steps, Created, !InCondRegionsProc).
 
-:- pred collect_regions_created_in_condition_compound_goal(
-	pp_region_set_table::in, pp_region_set_table::in, hlds_goal::in,
+:- pred collect_regions_created_in_condition_compound_goal(rpt_graph::in,
+	pp_region_set_table::in, pp_region_set_table::in,
+	renaming_proc::in, renaming_annotation_proc::in, hlds_goal::in,
	goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
-collect_regions_created_in_condition_compound_goal(LRBeforeProc,
-		LRAfterProc, GoalInIte, !InCondRegionsProc) :-
+collect_regions_created_in_condition_compound_goal(Graph, LRBeforeProc,
+		LRAfterProc, ResurRenamingProc, ResurRenamingAnnoProc, GoalInIte,
+		!InCondRegionsProc) :-
	GoalInIte = hlds_goal(Expr, _),
	(
		Expr = conj(_, [Conj | Conjs]),
-		list.foldl(collect_regions_created_in_condition(LRBeforeProc,
-			LRAfterProc), [Conj | Conjs], !InCondRegionsProc)
+		list.foldl(collect_regions_created_in_condition(Graph,
+			LRBeforeProc, LRAfterProc, ResurRenamingProc,
+			ResurRenamingAnnoProc), [Conj | Conjs],
+			!InCondRegionsProc)
	;
		Expr = disj([Disj | Disjs]),
-		list.foldl(collect_regions_created_in_condition(LRBeforeProc,
-			LRAfterProc), [Disj | Disjs], !InCondRegionsProc)
+		list.foldl(collect_regions_created_in_condition(Graph, 
+			LRBeforeProc, LRAfterProc, ResurRenamingProc,
+			ResurRenamingAnnoProc), [Disj | Disjs],
+			!InCondRegionsProc)
	;
		Expr = switch(_, _, Cases),
		list.foldl(
-			collect_regions_created_in_condition_case(LRBeforeProc,
-				LRAfterProc),
+			collect_regions_created_in_condition_case(Graph,
+			LRBeforeProc, LRAfterProc, ResurRenamingProc,
+			ResurRenamingAnnoProc),
			Cases, !InCondRegionsProc)
	;
		Expr = negation(Goal),
-		collect_regions_created_in_condition(LRBeforeProc,
-			LRAfterProc, Goal, !InCondRegionsProc)
+		collect_regions_created_in_condition(Graph, LRBeforeProc,
+			LRAfterProc, ResurRenamingProc,
+			ResurRenamingAnnoProc, Goal, !InCondRegionsProc)
	;
		Expr = scope(_, Goal),
-		collect_regions_created_in_condition(LRBeforeProc,
-			LRAfterProc, Goal, !InCondRegionsProc)
+		collect_regions_created_in_condition(Graph, LRBeforeProc,
+			LRAfterProc, ResurRenamingProc,
+			ResurRenamingAnnoProc, Goal, !InCondRegionsProc)
	;
		Expr = if_then_else(_, Cond, Then, Else),
-		collect_regions_created_in_condition(LRBeforeProc, LRAfterProc,
-			Cond, !InCondRegionsProc),
-		collect_regions_created_in_condition(LRBeforeProc, LRAfterProc,
-			Then, !InCondRegionsProc),
-		collect_regions_created_in_condition(LRBeforeProc, LRAfterProc,
-			Else, !InCondRegionsProc)
+		collect_regions_created_in_condition(Graph, LRBeforeProc,
+			LRAfterProc, ResurRenamingProc,
+			ResurRenamingAnnoProc, Cond, !InCondRegionsProc),
+		collect_regions_created_in_condition(Graph, LRBeforeProc,
+			LRAfterProc, ResurRenamingProc,
+			ResurRenamingAnnoProc, Then, !InCondRegionsProc),
+		collect_regions_created_in_condition(Graph, LRBeforeProc,
+			LRAfterProc, ResurRenamingProc,
+			ResurRenamingAnnoProc, Else, !InCondRegionsProc)
	;
		( Expr = unify(_, _, _, _, _) 
         ; Expr = plain_call(_, _, _, _, _, _) 
@@ -520,15 +707,18 @@
			++ "encountered atomic or unsupported goal")
	).
 
-:- pred collect_regions_created_in_condition_case(pp_region_set_table::in,
-	pp_region_set_table::in, case::in, goal_path_regions_table::in,
-	goal_path_regions_table::out) is det.
+:- pred collect_regions_created_in_condition_case(rpt_graph::in,
+	pp_region_set_table::in, pp_region_set_table::in,
+	renaming_proc::in, renaming_annotation_proc::in, case::in,
+	goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
-collect_regions_created_in_condition_case(LRBeforeProc, LRAfterProc, Case,
-		!InCondRegionsProc) :-
+collect_regions_created_in_condition_case(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc,
+		Case, !InCondRegionsProc) :-
	Case = case(_, Goal),
-	collect_regions_created_in_condition(LRBeforeProc, LRAfterProc, Goal,
-		!InCondRegionsProc).
+	collect_regions_created_in_condition(Graph, LRBeforeProc, LRAfterProc,
+		ResurRenamingProc, ResurRenamingAnnoProc,
+		Goal, !InCondRegionsProc).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -558,18 +748,15 @@
				InCondRegionsProc,
				map.init, IteRenamedRegionProc),
			( if	map.count(IteRenamedRegionProc) = 0
-			  then
-					true
-			  else
-					svmap.set(PPId, IteRenamedRegionProc,
+			  then	true
+			  else	svmap.set(PPId, IteRenamedRegionProc,
						!IteRenamedRegionTable)
			)
-	  else
-			true
+	  else	true
	).
 
 :- pred collect_ite_renamed_regions_ite(goal_path_regions_table::in,
-	goal_path::in, region_set::in,
+	goal_path::in, set(string)::in,
	goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
 collect_ite_renamed_regions_ite(NonLocalRegionsProc, PathToCond,
@@ -579,14 +766,11 @@
			set.intersect(NonLocalRegions, InCondRegions,
				RenamedRegions),
			( if	set.empty(RenamedRegions)
-			  then
-					true
-			  else
-					svmap.set(PathToCond, RenamedRegions,
+			  then	true
+			  else	svmap.set(PathToCond, RenamedRegions,
						!IteRenamedRegionProc)
			)
-	  else
-			true
+	  else	true
	).
 
 %-----------------------------------------------------------------------------%
@@ -710,11 +894,12 @@
				PathToClosestCond, 0, HowMany),
			( if	map.search(IteRenamedRegionProc,
						PathToClosestCond,
-						RenamedRegion)
+						RenamedRegions)
			  then
					set.fold(record_ite_renaming(ProgPoint,
						HowMany, Graph),
-						RenamedRegion, !IteRenamingProc)
+						RenamedRegions,
+						!IteRenamingProc)
			  else
					% No region needs to be renamed due to
					% if-then-else covering this program
@@ -730,10 +915,9 @@
	% A renaming is of the form: R --> R_ite_HowMany.
	%
 :- pred record_ite_renaming(program_point::in, int::in, rpt_graph::in,
-	rptg_node::in, renaming_proc::in, renaming_proc::out) is det.
+	string::in, renaming_proc::in, renaming_proc::out) is det.
 
-record_ite_renaming(ProgPoint, HowMany, Graph, Region, !IteRenamingProc) :-
-	RegName = rptg_lookup_region_name(Graph, Region),
+record_ite_renaming(ProgPoint, HowMany, _Graph, RegName, !IteRenamingProc) :-
	NewName = RegName ++ "_ite_" ++ string.int_to_string(HowMany),
	( if	map.search(!.IteRenamingProc, ProgPoint, IteRenaming0)
	  then	svmap.set(RegName, NewName, IteRenaming0, IteRenaming)
@@ -849,16 +1033,16 @@
	map.lookup(RptaInfoTable, PPId, RptaInfo),
	map.lookup(IteRenamingTable, PPId, IteRenamingProc),
	RptaInfo = rpta_info(Graph, _),
-	map.foldl(collect_ite_annotation_region_set(ExecPaths, Graph,
+	map.foldl(collect_ite_annotation_region_names(ExecPaths, Graph,
		IteRenamingProc),
		IteRenamedRegionProc, map.init, IteAnnotationProc),
	svmap.set(PPId, IteAnnotationProc, !IteAnnotationTable).
 
-:- pred collect_ite_annotation_region_set(list(execution_path)::in,
-	rpt_graph::in, renaming_proc::in, goal_path::in, region_set::in,
+:- pred collect_ite_annotation_region_names(list(execution_path)::in,
+	rpt_graph::in, renaming_proc::in, goal_path::in, set(string)::in,
	renaming_annotation_proc::in, renaming_annotation_proc::out) is det.
 
-collect_ite_annotation_region_set(ExecPaths, Graph, IteRenamingProc,
+collect_ite_annotation_region_names(ExecPaths, Graph, IteRenamingProc,
		PathToCond, RenamedRegions, !IteAnnotationProc) :-
	(
		PathToCond = [],
@@ -877,7 +1061,7 @@
 
 :- pred collect_ite_annotation_exec_path(rpt_graph::in,
	renaming_proc::in, goal_path::in,
-	region_set::in, int::in, execution_path::in,
+	set(string)::in, int::in, execution_path::in,
	renaming_annotation_proc::in, renaming_annotation_proc::out) is det.
 
 collect_ite_annotation_exec_path(_, _, _, _, _, [], !IteAnnotationProc).
@@ -906,12 +1090,11 @@
	% R --> R_1, then the annotation is R_1 = R_ite_HowMany.
	%
 :- pred introduce_reverse_renaming(rpt_graph::in, program_point::in,
-	renaming_proc::in, int::in, rptg_node::in,
+	renaming_proc::in, int::in, string::in,
	renaming_annotation_proc::in, renaming_annotation_proc::out) is det.
 
-introduce_reverse_renaming(Graph, ProgPoint, IteRenamingProc,
-		HowMany, RenamedRegion, !IteAnnotationProc) :-
-	RegName = rptg_lookup_region_name(Graph, RenamedRegion),
+introduce_reverse_renaming(_Graph, ProgPoint, IteRenamingProc,
+		HowMany, RegName, !IteAnnotationProc) :-
	RightHand =
		" = " ++ RegName ++ "_ite_" ++ string.int_to_string(HowMany),
	( if	map.search(IteRenamingProc, ProgPoint, Renaming)
Index: rbmm.execution_path.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.execution_path.m,v
retrieving revision 1.3
diff -u -u -r1.3 rbmm.execution_path.m
--- rbmm.execution_path.m	8 Jun 2007 06:45:11 -0000	1.3
+++ rbmm.execution_path.m	15 Jun 2007 01:05:02 -0000
@@ -207,7 +207,7 @@
     % the execution paths to have fewer program points than they should.
     % If this happens we need to add a program point for the removed
     % unification.  The goal corresponding to this introduced program
-    % point is the switch goal itself.  This is so thtat we can get
+    % point is the switch goal itself.  This is so that we can get
     % information about the switch var in the live variable analysis.
     %
 :- pred execution_paths_covered_cases(proc_info::in, hlds_goal::in, 
Index: rbmm.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.m,v
retrieving revision 1.4
diff -u -u -r1.4 rbmm.m
--- rbmm.m	15 Jun 2007 11:46:11 -0000	1.4
+++ rbmm.m	27 Jun 2007 06:05:48 -0000
@@ -28,6 +28,7 @@
 :- include_module region_instruction.
 :- include_module region_liveness_info.
 :- include_module region_resurrection_renaming.
+:- include_module region_transformation.
 
 :- import_module hlds.
 :- import_module hlds.hlds_module.
@@ -52,6 +53,9 @@
 :- import_module transform_hlds.rbmm.points_to_analysis.
 :- import_module transform_hlds.rbmm.region_instruction.
 :- import_module transform_hlds.rbmm.region_resurrection_renaming.
+:- import_module transform_hlds.rbmm.region_transformation.
+
+:- import_module map.
 
 %-----------------------------------------------------------------------------%
 
@@ -75,11 +79,11 @@
		VoidVarRegionTable0, VoidVarRegionTable),
     introduce_region_instructions(!.ModuleInfo, RptaInfoTable,
		ExecPathTable, LRBeforeTable, LRAfterTable, VoidVarRegionTable,
-		BornRTable, DeadRTable, LocalRTable, _AnnotationTable),
+		BornRTable, DeadRTable, LocalRTable, AnnotationTable),
 
     record_actual_region_arguments(!.ModuleInfo, RptaInfoTable,
		ConstantRTable, DeadRTable, BornRTable,
-		_ActualRegionArgumentTable),
+		ActualRegionArgumentTable),
 
	% The region analysis treats region variables as if they are
	% imperative-style updatable variables. They may also have scopes
@@ -90,23 +94,27 @@
     compute_resurrection_paths(ExecPathTable, LRBeforeTable, LRAfterTable, 
		BornRTable, LocalRTable, CreatedBeforeTable,
		ResurrectionPathTable),
+	collect_join_points(ResurrectionPathTable, ExecPathTable,
+		JoinPointTable),
     collect_region_resurrection_renaming(CreatedBeforeTable, LocalRTable,
		RptaInfoTable, ResurrectionPathTable, ResurrectionRenameTable),
-	collect_join_points(ResurrectionRenameTable, ExecPathTable,
-		JoinPointTable),
     collect_renaming_and_annotation(ResurrectionRenameTable, JoinPointTable,
		LRBeforeTable, BornRTable, RptaInfoTable, ResurrectionPathTable,
-		ExecPathTable, _RenamingAnnotationTable, _RenamingTable),
-
-	collect_non_local_and_in_cond_regions(!.ModuleInfo, LRBeforeTable,
-		LRAfterTable, LocalRegionsTable, InCondRegionsTable),
+		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),
	collect_ite_annotation(RenamedRegionsTable, ExecPathTable, 
-		RptaInfoTable, IteRenamingTable, _IteAnnoTable).
+		RptaInfoTable, IteRenamingTable, IteRenamingAnnoTable),
 
+	region_transform(RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
+		ActualRegionArgumentTable, ResurRenamingTable, IteRenamingTable,
+		AnnotationTable, ResurRenamingAnnoTable, IteRenamingAnnoTable,
+		map.init, _NameToVarTable, !ModuleInfo).
 
 %-----------------------------------------------------------------------------%
 :- end_module transform_hlds.rbmm.
Index: rbmm.region_resurrection_renaming.m
===================================================================
RCS file:
/home/mercury/mercury1/repository/mercury/compiler/rbmm.region_resurrection_renaming.m,v
retrieving revision 1.2
diff -u -u -r1.2 rbmm.region_resurrection_renaming.m
--- rbmm.region_resurrection_renaming.m	15 Jun 2007 11:46:12 -0000	1.2
+++ rbmm.region_resurrection_renaming.m	27 Jun 2007 08:55:27 -0000
@@ -56,19 +56,49 @@
 :- type join_point_region_name_table ==
     map(pred_proc_id, map(program_point, string)).
 
+    % This predicate traveses execution paths and computes two pieces of
+    % information:
+    % 1. The set of regions that become live before a program point
+    % (for each program point in a procedure).
+    % 2. For each procedure, compute the execution paths in which 
+    % resurrections of regions happen. For such an execution path
+    % it also calculates the regions which resurrect. Only procedures
+    % which contain resurrection are kept in the results. And for such
+    % procedures only execution paths that contain resurrection are
+    % kept.
+    %
 :- pred compute_resurrection_paths(execution_path_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_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.
 
-:- pred collect_join_points(renaming_table::in,
+    % 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.
+    %
+    % 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.
+    %
+:- pred collect_join_points(proc_resurrection_path_table::in,
     execution_path_table::in, join_point_region_name_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
+    % regions.
+    %
 :- 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,
@@ -92,6 +122,7 @@
 
 :- import_module assoc_list.
 :- import_module bool.
+:- import_module counter.
 :- import_module int.
 :- import_module pair.
 :- import_module set.
@@ -199,13 +230,95 @@
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-    % 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.
+    % We will only collect join points in procedures where resurrection
+    % happens, therefore use ResurrectionRenameTable just for the PPIds of
+    % such procedures.
+    %
+    % The new region name at a join point is formed by RegionName_jp_Number.
+    % If a region needs new names at several join points then Number will
+    % make the new names distinct.
+    %
+collect_join_points(PathContainsResurrectionTable, ExecPathTable,
+        JoinPointTable) :-
+    map.foldl(collect_join_points_proc(ExecPathTable),
+        PathContainsResurrectionTable, map.init, JoinPointTable).
+
+:- pred collect_join_points_proc(execution_path_table::in,
+    pred_proc_id::in, exec_path_region_set_table::in,
+    join_point_region_name_table::in,
+    join_point_region_name_table::out) is det.
+
+collect_join_points_proc(ExecPathTable, PPId, _, !JoinPointTable) :-
+    map.lookup(ExecPathTable, PPId, ExecPaths),
+    list.foldr(pred(ExecPath::in, Ps0::in, Ps::out) is det :- (
+                    assoc_list.keys(ExecPath, P),
+                    Ps = [P | Ps0]
+               ), ExecPaths, [], Paths),
+    list.foldl3(collect_join_points_path(Paths), Paths,
+        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,
+    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,
+        !JoinPointProc) :-
+    list.delete_all(Paths, Path, TheOtherPaths),
+    % We ignore the first program point in each path because
+    % it cannot be a join point.
+    ( if    Path = [PrevPoint, ProgPoint | ProgPoints]
+      then
+            ( if    is_join_point(ProgPoint, PrevPoint, TheOtherPaths)
+              then
+                    counter.allocate(N, !Counter),
+                    svmap.set(ProgPoint,
+                        "_jp_" ++ string.int_to_string(N),
+                        !JoinPointProc),
+                    svset.insert(ProgPoint, !JoinPoints)
+              else  true
+            ),
+            collect_join_points_path(Paths,
+                [ProgPoint | ProgPoints], !Counter, !JoinPoints,
+                !JoinPointProc)
+      else  true
+    ).
+
+    % This predicate succeeds if the first program point is a join point. 
+    % That means it is at least in another execution path and is preceded
+    % by some program point, which is different from the second one.
     %
+:- pred is_join_point(program_point::in, program_point::in, 
+    list(list(program_point))::in) is semidet.
+
+is_join_point(ProgPoint, PrevProgPoint, [Path | Paths]) :-
+    ( if    is_join_point_2(ProgPoint, PrevProgPoint, Path)
+      then  true
+      else  is_join_point(ProgPoint, PrevProgPoint, Paths)
+    ).
+    
+:- pred is_join_point_2(program_point::in, program_point::in, 
+    list(program_point)::in) is semidet.
+
+is_join_point_2(ProgPoint, PrevProgPoint, [P1, P2 | Ps]) :-
+    ( if    P2 = ProgPoint
+      then  P1 \= PrevProgPoint
+      else  is_join_point_2(ProgPoint, PrevProgPoint, [P2 | Ps])
+    ).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+% 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.
+%
+ 
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
 collect_region_resurrection_renaming(CreatedBeforeTable, LocalRTable,
         RptaInfoTable, PathContainsResurrectionTable,
         ResurrectionRenameTable) :-
@@ -264,8 +377,7 @@
     !: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.
+    rptg_node::in, renaming_proc::in, renaming_proc::out) is det.
 
 record_renaming_prog_point(Graph, ProgPoint, RenamingCounter, Region,
         !ResurrectionRenameProc) :-
@@ -283,99 +395,6 @@
     ),
     svmap.set(ProgPoint, RenamingProgPoint, !ResurrectionRenameProc).
 
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-    % 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.
-    %
-    % 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.
-    %
-    % We will only collect join points in procedures where resurrection
-    % happens.
-    %
-    % We use ResurrectionRenameTable just for the PPIds of procedures in
-    % which resurrection happens.
-    %
-    % The new region name at a join point is formed by RegionName_jp_Number.
-    % If a region needs new names at several join points then Number will
-    % make the new names distinct.
-    %
-collect_join_points(ResurrectionRenameTable, ExecPathTable, JoinPointTable) :-
-    map.foldl(collect_join_points_proc(ExecPathTable),
-        ResurrectionRenameTable, map.init, JoinPointTable).
-
-:- pred collect_join_points_proc(execution_path_table::in,
-    pred_proc_id::in, renaming_proc::in,
-    join_point_region_name_table::in,
-    join_point_region_name_table::out) is det.
-
-collect_join_points_proc(ExecPathTable, PPId, _, !JoinPointTable) :-
-    map.lookup(ExecPathTable, PPId, ExecPaths),
-    list.foldr(pred(ExecPath::in, Ps0::in, Ps::out) is det :- (
-                    assoc_list.keys(ExecPath, P),
-                    Ps = [P | Ps0]
-               ), ExecPaths, [], Paths), 
-    list.foldl3(collect_join_points_path(Paths), Paths,
-        1, _, 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, int::in, int::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,
-        !JoinPointProc) :-
-    list.delete_all(Paths, Path, TheOtherPaths),
-    % We ignore the first program point in each path because
-    % it cannot be a join point.
-    ( if    Path = [PrevPoint, ProgPoint | ProgPoints]
-      then
-            ( if    is_join_point(ProgPoint, PrevPoint, TheOtherPaths)
-              then
-                    svmap.set(ProgPoint,
-                        "_jp_" ++ string.int_to_string(!.Counter),
-                        !JoinPointProc),
-                    svset.insert(ProgPoint, !JoinPoints),
-                    !:Counter = !.Counter + 1
-              else
-                    true
-            ),
-            collect_join_points_path(Paths,
-                [ProgPoint | ProgPoints], !Counter, !JoinPoints,
-                !JoinPointProc)
-      else
-            true
-    ).
-
-    % This predicate succeeds if the first program point is a join point. 
-    % That means it is at least in another execution path and is preceded
-    % by some program point, which is different from the second one.
-    %
-:- pred is_join_point(program_point::in, program_point::in, 
-    list(list(program_point))::in) is semidet.
-
-is_join_point(ProgPoint, PrevProgPoint, [Path | Paths]) :-
-    ( if    is_join_point_2(ProgPoint, PrevProgPoint, Path)
-      then  
-            true
-      else
-            is_join_point(ProgPoint, PrevProgPoint, Paths)
-    ).
-    
-:- pred is_join_point_2(program_point::in, program_point::in, 
-    list(program_point)::in) is semidet.
-
-is_join_point_2(ProgPoint, PrevProgPoint, [P1, P2 | Ps]) :-
-    ( if    P2 = ProgPoint
-      then
-            P1 \= PrevProgPoint
-      else
-            is_join_point_2(ProgPoint, PrevProgPoint, [P2 | Ps])
-    ).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -390,11 +409,6 @@
 % goal is a construction the renaming is applied to the regions of the left
 % variable.
 
-    % 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
-    % regions.
-    %
 collect_renaming_and_annotation(ResurrectionRenameTable, JoinPointTable,
         LRBeforeTable, BornRTable, RptaInfoTable, ResurrectionPathTable,
         ExecPathTable, AnnotationTable, RenamingTable) :-
@@ -572,15 +586,19 @@
     svmap.det_insert(RegionName, NewName, !Renaming),
 
     % Add annotation to (after) the previous program point.
-    % Annotations are only added for resurrected regions that have been
+    % XXX Annotations are only added for resurrected regions that have been
     % renamed in this execution path (i.e., the execution path contains
     % PrevProgPoint and ProgPoint).
+    % It seems that we have to add annotations (reverse renaming) for
+    % ones that have not been renamed too. The only difference is that
+    % the reverse renaming is between the new name and the original name.
     ( if    map.search(PrevRenaming, RegionName, CurrentName)
       then
             Annotation = NewName ++ " = " ++ CurrentName,
             record_annotation(PrevProgPoint, Annotation, !AnnotationProc)
       else
-            true
+            Annotation = NewName ++ " = " ++ RegionName,
+            record_annotation(PrevProgPoint, Annotation, !AnnotationProc)
     ).
 
 :- pred add_annotation(program_point::in, rpt_graph::in, renaming::in,
Index: rbmm.region_transformation.m
===================================================================
RCS file: rbmm.region_transformation.m
diff -N rbmm.region_transformation.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ rbmm.region_transformation.m	29 Jun 2007 02:22:04 -0000
@@ -0,0 +1,1008 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2007 The University of Melbourne.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+% 
+% File: rbmm.region_transformation.m
+% Main author: quan.
+%
+% This module annotates the HLDS with region information.
+% The region information includes:
+% - Add extra region arguments (to pass regions around) to procedures and
+% calls.
+% - Update how_to_construct of construction unifications so that we can
+% construct terms in a region.
+% - Add region builtin calls (defined in region_builtin.m).
+% 
+%-----------------------------------------------------------------------------%
+
+:- module transform_hlds.rbmm.region_transformation.
+:- interface.
+
+:- import_module hlds.
+:- import_module hlds.hlds_module.
+:- import_module hlds.hlds_pred.
+:- import_module parse_tree.
+:- import_module parse_tree.prog_data.
+:- import_module transform_hlds.rbmm.actual_region_arguments.
+:- import_module transform_hlds.rbmm.points_to_info.
+:- import_module transform_hlds.rbmm.region_liveness_info.
+:- import_module transform_hlds.rbmm.region_resurrection_renaming.
+:- import_module transform_hlds.rbmm.region_instruction.
+
+:- import_module map.
+:- import_module string.
+%-----------------------------------------------------------------------------%
+
+	% Represent mapping from region name to a program variable that
+	% represents the region.
+	%
+:- type name_to_prog_var_table == map(pred_proc_id, name_to_prog_var).
+:- type name_to_prog_var == map(string, prog_var).
+
+	% XXX Besides changing the HLDS, this predicate also returns a mapping
+	% from a region name to a program variable which represents the
+	% region. We will only create a new program variable for a region
+	% name which is not yet in the map. Currently this map is only used
+	% in this transformation. If we do not need the map later on we should
+	% not return it.
+	%
+:- pred region_transform(rpta_info_table::in, proc_region_set_table::in,
+	proc_region_set_table::in, proc_region_set_table::in,
+	proc_pp_pair_region_list_table::in,
+	renaming_table::in, renaming_table::in, annotation_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.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module check_hlds.
+:- import_module check_hlds.goal_path.
+:- import_module check_hlds.mode_util.
+:- import_module check_hlds.purity.
+:- import_module check_hlds.type_util.
+:- import_module hlds.goal_util.
+:- import_module hlds.hlds_goal.
+:- import_module hlds.instmap.
+:- import_module hlds.pred_table.
+:- import_module hlds.quantification.
+:- import_module libs.
+:- import_module libs.compiler_util.
+:- import_module mdbcomp.prim_data.
+:- import_module parse_tree.prog_mode.
+:- import_module transform_hlds.rbmm.points_to_graph.
+:- import_module transform_hlds.smm_common.
+
+:- import_module bool.
+:- import_module int.
+:- import_module list.
+:- import_module pair.
+:- import_module set.
+:- import_module svmap.
+:- import_module svvarset.
+:- import_module term.
+:- import_module varset.
+%-----------------------------------------------------------------------------%
+
+region_transform(RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
+		ActualRegionArgTable, ResurRenamingTable, IteRenamingTable,
+		AnnotationTable, ResurRenamingAnnoTable, IteRenamingAnnoTable,
+		!NameToVarTable, !ModuleInfo) :-
+	map.foldl2(annotate_pred(DeadRTable, BornRTable), ConstantRTable, [],
+		PredIds, !ModuleInfo),
+	list.foldl2(region_transform_pred(RptaInfoTable,
+		ConstantRTable, DeadRTable, BornRTable, ActualRegionArgTable,
+		ResurRenamingTable, IteRenamingTable,
+		AnnotationTable, ResurRenamingAnnoTable, IteRenamingAnnoTable),
+		PredIds, !NameToVarTable, !ModuleInfo),
+	% We can only do the followings when all the procedures have been
+	% annotated with region information and recorded. This is necessary
+	% because recompute_instmap_delta_proc and repuritycheck_proc need to
+	% look up information about the (annotated) called procedures.
+	%
+    list.foldl(update_instmap_delta_pred, PredIds, !ModuleInfo),
+	list.foldl(check_purity_pred, PredIds, !ModuleInfo).
+
+	% This predicate updates pred_info structure. The following information
+	% is updated:
+	% 1. Original arity: orig_arity, which is updated with the old value +
+	% the number of region arguments.
+	% 2. Argument types: arg_types, updated with region type for region
+	% arguments.
+	%
+:- pred annotate_pred(proc_region_set_table::in, proc_region_set_table::in,
+	pred_proc_id::in, region_set::in, list(pred_id)::in, list(pred_id)::out,
+	module_info::in, module_info::out) is det.
+
+annotate_pred(DeadRTable, BornRTable, PPId, ConstantR, !Processed,
+		!ModuleInfo) :-
+	PPId = proc(PredId, _),
+	( if	list.member(PredId, !.Processed)
+	  then	true
+	  else  
+			some [!PredInfo] (
+				module_info_pred_info(!.ModuleInfo, PredId,
+					!:PredInfo),
+				map.lookup(DeadRTable, PPId, DeadR),
+				map.lookup(BornRTable, PPId, BornR),
+				NumberOfRegArgs = set.count(DeadR) +
+					set.count(BornR) + set.count(ConstantR),
+				Arity = pred_info_orig_arity(!.PredInfo),
+				pred_info_set_orig_arity(
+					Arity + NumberOfRegArgs, !PredInfo),
+
+				list.duplicate(NumberOfRegArgs,
+					make_region_type, RegionTypes),
+				pred_info_get_arg_types(!.PredInfo, TypeVarSet,
+					ExistQuantTVars, ArgTypes0),
+				PredOrFunc =
+					pred_info_is_pred_or_func(!.PredInfo),
+				(
+					PredOrFunc = pf_predicate,
+					ArgTypes = ArgTypes0 ++ RegionTypes	
+				;
+					PredOrFunc = pf_function,
+					% The output of function is always at
+					% the last.
+					list.split_last_det(ArgTypes0,
+						BeforeLast, Last),
+					ArgTypes = BeforeLast ++ RegionTypes
+						++ [Last]
+				),
+				pred_info_set_arg_types(TypeVarSet,
+					ExistQuantTVars, ArgTypes, !PredInfo),
+				module_info_set_pred_info(PredId, !.PredInfo,
+					!ModuleInfo)
+			),
+			!:Processed = [PredId | !.Processed]
+	).
+			
+	% This predicate transforms the procedures of a predicate.
+	%
+:- pred region_transform_pred(rpta_info_table::in, proc_region_set_table::in,
+	proc_region_set_table::in, proc_region_set_table::in,
+	proc_pp_pair_region_list_table::in,
+	renaming_table::in, renaming_table::in, annotation_table::in,
+	renaming_annotation_table::in, renaming_annotation_table::in,
+	pred_id::in, name_to_prog_var_table::in, name_to_prog_var_table::out,
+	module_info::in, module_info::out) is det.
+
+region_transform_pred(RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
+		ActualRegionArgTable, ResurRenamingTable, IteRenamingTable,
+		AnnotationTable, ResurRenamingAnnoTable, IteRenamingAnnoTable,
+		PredId, !NameToVarTable, !ModuleInfo) :-
+    module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
+    ProcIds = pred_info_non_imported_procids(PredInfo),
+    list.foldl2(region_transform_proc(RptaInfoTable,
+		ConstantRTable, DeadRTable, BornRTable, ActualRegionArgTable,
+		ResurRenamingTable, IteRenamingTable,
+		AnnotationTable, ResurRenamingAnnoTable, IteRenamingAnnoTable,
+		PredId), ProcIds, !NameToVarTable, !ModuleInfo).
+
+	% This predicate updates the proc_info data structure, representing 
+	% a procedure.
+	% - Introduce new variables for regions (and their region types).
+	% - Update headvars with region arguments (types and modes).
+	% - Update the body
+	%	+ region instructions,
+	%	+ actual region arguments at call sites,
+	%	+ how_to_construct at construction unifications.
+	% - *Requantify* the annotated proc.
+	% As said above, we will recompute instmap delta, recheck purity for
+	% this annotated procedure after all the procedures have been
+	% transformed.
+	%
+:- pred region_transform_proc(rpta_info_table::in, proc_region_set_table::in,
+	proc_region_set_table::in, proc_region_set_table::in,
+	proc_pp_pair_region_list_table::in,
+	renaming_table::in, renaming_table::in, annotation_table::in,
+	renaming_annotation_table::in, renaming_annotation_table::in,
+	pred_id::in, proc_id::in, name_to_prog_var_table::in,
+	name_to_prog_var_table::out, module_info::in, module_info::out) is det.
+
+region_transform_proc(RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
+		ActualRegionArgTable, ResurRenamingTable, IteRenamingTable,
+		AnnotationTable, ResurRenamingAnnoTable, IteRenamingAnnoTable,
+		PredId, ProcId, !NameToVarTable, !ModuleInfo) :-
+    PPId = proc(PredId, ProcId),
+	module_info_pred_proc_info(!.ModuleInfo, PPId, PredInfo0, ProcInfo0),
+	fill_goal_path_slots(!.ModuleInfo, ProcInfo0, ProcInfo1),
+	proc_info_get_varset(ProcInfo1, VarSet0),
+	proc_info_get_vartypes(ProcInfo1, VarTypes0),
+	proc_info_get_headvars(ProcInfo1, HeadVars0),
+	proc_info_get_argmodes(ProcInfo1, ActualArgModes0),
+	proc_info_get_goal(ProcInfo1, Goal0),
+	map.lookup(RptaInfoTable, PPId, rpta_info(Graph, _)),
+	map.lookup(ConstantRTable, PPId, ConstantR),
+	map.lookup(DeadRTable, PPId, DeadR),
+	map.lookup(BornRTable, PPId, BornR),
+	map.lookup(ActualRegionArgTable, PPId, ActualRegionArgProc),
+	( if	map.search(ResurRenamingTable, PPId, ResurRenamingProc0)
+	  then
+			ResurRenamingProc = ResurRenamingProc0,
+			map.lookup(ResurRenamingAnnoTable, PPId,
+				ResurRenamingAnnoProc)
+	  else
+			ResurRenamingProc = map.init,
+			ResurRenamingAnnoProc = map.init
+	),
+	( if	map.search(IteRenamingTable, PPId, IteRenamingProc0)
+	  then
+			IteRenamingProc = IteRenamingProc0,
+			map.lookup(IteRenamingAnnoTable, PPId,
+				IteRenamingAnnoProc)
+	  else
+			IteRenamingProc = map.init,
+			IteRenamingAnnoProc = map.init
+	),
+	map.lookup(AnnotationTable, PPId, AnnotationProc),
+	NameToVar0 = map.init,
+	annotate_proc(!.ModuleInfo, PredInfo0, Graph, ConstantR, DeadR, BornR,
+		ActualRegionArgProc, ResurRenamingProc, IteRenamingProc,
+		AnnotationProc, ResurRenamingAnnoProc, IteRenamingAnnoProc,
+		VarSet0, _, VarTypes0, _, HeadVars0, _, ActualArgModes0, _,
+		Goal0, _, NameToVar0, NameToVar, ProcInfo1, ProcInfo2),
+	requantify_proc(ProcInfo2, ProcInfo),
+	module_info_set_pred_proc_info(PPId, PredInfo0, ProcInfo, !ModuleInfo),
+	svmap.det_insert(PPId, NameToVar, !NameToVarTable).
+
+	% Currently for a procedure we annotate the following information:
+	% 1. VarSet with region variables
+	% 2. VarTypes with region variables and their types
+	% 3. HeadVars with formal region arguments
+	% 4. ActualHeadModes with the modes for region variables 
+	% 5. Body: 
+	%	+ new region arguments at calls
+	%	+ new calls to region instructions
+	%
+:- pred annotate_proc(module_info::in, pred_info::in, rpt_graph::in,
+	region_set::in, region_set::in, region_set::in,
+	pp_pair_region_list_table::in, renaming_proc::in, renaming_proc::in,
+	annotation_proc::in, renaming_annotation_proc::in,
+	renaming_annotation_proc::in, prog_varset::in, prog_varset::out,
+	vartypes::in, vartypes::out, list(prog_var)::in, list(prog_var)::out,
+	list(mer_mode)::in, list(mer_mode)::out, hlds_goal::in, hlds_goal::out,
+	name_to_prog_var::in, name_to_prog_var::out, proc_info::in,
+	proc_info::out) is det.
+
+annotate_proc(ModuleInfo, PredInfo, Graph, ConstantR, DeadR, BornR,
+		ActualRegionArgProc, ResurRenamingProc, IteRenamingProc,
+		AnnotationProc, ResurRenamingAnnoProc, IteRenamingAnnoProc,
+		!VarSet, !VarTypes, !HeadVars, !ActualArgModes, !Goal,
+		!NameToVar, !ProcInfo) :-
+	region_transform_goal(ModuleInfo, Graph, ResurRenamingProc,
+		IteRenamingProc, ActualRegionArgProc,
+		AnnotationProc, ResurRenamingAnnoProc, IteRenamingAnnoProc,
+		!Goal, !NameToVar, !VarSet, !VarTypes),
+
+	% Computing head_vars.
+	% Note that formal region arguments are not subjected to renaming.
+	set.to_sorted_list(ConstantR, LConstantR),
+	set.to_sorted_list(DeadR, LDeadR),
+	set.to_sorted_list(BornR, LBornR),
+	FormalInputNodes = LConstantR ++ LDeadR, 
+	FormalNodes = FormalInputNodes ++ LBornR,
+	list.map_foldl3(node_to_var(Graph), FormalNodes, FormalRegionArgs,
+		!NameToVar, !VarSet, !VarTypes),
+
+	% Computing actual_head_modes.
+	InMode = in_mode,
+	OutMode = out_mode,
+	list.duplicate(list.length(FormalInputNodes), InMode, InModes),
+	list.duplicate(list.length(LBornR), OutMode, OutModes),
+
+	% One thing to notice here is that the output of a function needs
+	% to be the last argument.
+	PredOrFunc = pred_info_is_pred_or_func(PredInfo),
+	(
+		PredOrFunc = pf_predicate,
+		!:HeadVars = !.HeadVars ++ FormalRegionArgs,
+		!:ActualArgModes = !.ActualArgModes ++ InModes ++ OutModes
+	;
+		PredOrFunc = pf_function,
+		list.split_last_det(!.HeadVars, BeforeLastHeadVar, LastHeadVar),
+		!:HeadVars = BeforeLastHeadVar ++ FormalRegionArgs
+			++ [LastHeadVar],
+		list.split_last_det(!.ActualArgModes, BeforeLastHeadMode,
+			LastHeadMode),
+		!:ActualArgModes = BeforeLastHeadMode ++ InModes
+			++ OutModes ++ [LastHeadMode]
+	),
+	
+	proc_info_set_varset(!.VarSet, !ProcInfo),
+	proc_info_set_goal(!.Goal, !ProcInfo),
+	proc_info_set_vartypes(!.VarTypes, !ProcInfo),
+	proc_info_set_headvars(!.HeadVars, !ProcInfo),
+	proc_info_set_argmodes(!.ActualArgModes, !ProcInfo).
+
+	% Basically, we will turn this atomic goal and all the region
+	% annotations attached to (before and after) it into a
+	% conjunction. When there is no annotation, the goal is just
+	% transformed and returned.
+	% If the newly created conjunction is a conjunct of a compounding
+	% conjunction then it will be flattened.
+	%
+	% Note: When both renamings (for resurrection and if-then-else) of a
+	% region exist at a program point, we will apply the resurrection one.
+	% This is due to the fact that when reasonning about what renaming is
+	% needed for if-then-else we have taken into account the changes 
+	% caused by renaming and annotations needed for resurrection problem.
+	% 
+:- pred region_transform_goal(module_info::in, rpt_graph::in,
+	renaming_proc::in, renaming_proc::in, pp_pair_region_list_table::in,
+	annotation_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.
+
+region_transform_goal(ModuleInfo, Graph, ResurRenamingProc, IteRenamingProc,
+		ActualRegionArgProc, AnnotationProc, ResurRenamingAnnoProc,
+		IteRenamingAnnoProc, !Goal, !NameToVar, !VarSet, !VarTypes) :-
+    !.Goal = hlds_goal(GoalExpr0, Info0), 
+	(	goal_is_atomic(GoalExpr0)
+	->
+		ProgPoint = program_point_init(Info0),
+		ProgPoint = pp(Context, _),
+		find_renamings_at_prog_point(ResurRenamingProc, IteRenamingProc,
+			ProgPoint, ResurRenaming, IteRenaming), 
+
+		% Depending on the expression, this call will annotate
+		% - a call with actual region arguments,
+		% - a construction unification with a region to construct in.
+		region_transform_goal_expr(ModuleInfo, Graph, ResurRenaming,
+			IteRenaming, ActualRegionArgProc, ProgPoint,
+			GoalExpr0, GoalExpr, Info0, Info, !NameToVar, !VarSet,
+			!VarTypes),
+
+		% Assignment unifications due to ite renaming.
+		assignments_from_ite_renaming_anno(IteRenamingAnnoProc,
+			ProgPoint, !NameToVar, !VarSet, !VarTypes,
+			[], IteRenamingAssignments),
+
+		% Region instructions before and after this program point.
+		(	map.search(AnnotationProc, ProgPoint,
+				before_after(Before, After))
+		->
+			% Region instructions before this program point.
+			list.foldl4(region_instruction_to_conj(ModuleInfo,
+				Context, ResurRenaming, IteRenaming), Before,
+				!NameToVar, !VarSet, !VarTypes,
+				IteRenamingAssignments, Conjs1),
+
+			% The goal at this program point itself.
+			Conjs2 = Conjs1 ++ [hlds_goal(GoalExpr, Info)],
+
+			% Region instructions after this program point.
+			list.foldl4(region_instruction_to_conj(ModuleInfo,
+				Context, ResurRenaming, IteRenaming), After,
+				!NameToVar, !VarSet, !VarTypes,
+				Conjs2, Conjs3)
+		;
+			% The goal at this program point itself.
+			Conjs3 = IteRenamingAssignments ++
+				[hlds_goal(GoalExpr, Info)]
+		),
+
+		% Assignment unifications due to region resurrection renaming.
+		assignments_from_resur_renaming_anno(ResurRenamingAnnoProc,
+			ProgPoint, IteRenaming, !NameToVar, !VarSet, !VarTypes,
+			Conjs3, Conjs),
+	
+		( if	Conjs = [_, _ | _]
+		  then
+				!:Goal = hlds_goal(conj(plain_conj, Conjs),
+					Info)
+		  else	!:Goal = hlds_goal(GoalExpr, Info)
+		)
+	;
+		region_transform_compound_goal(ModuleInfo, Graph,
+			ResurRenamingProc, IteRenamingProc, ActualRegionArgProc,
+			AnnotationProc, ResurRenamingAnnoProc,
+			IteRenamingAnnoProc, !Goal, !NameToVar, !VarSet,
+			!VarTypes)
+	).
+
+:- pred region_transform_goal_expr(module_info::in, rpt_graph::in,
+	renaming::in, renaming::in, pp_pair_region_list_table::in,
+	program_point::in, hlds_goal_expr::in, hlds_goal_expr::out,
+	hlds_goal_info::in, hlds_goal_info::out, name_to_prog_var::in,
+	name_to_prog_var::out, prog_varset::in, prog_varset::out,
+	vartypes::in, vartypes::out) is det.
+
+	% Annotate procedure calls with actual region arguments.
+	%
+region_transform_goal_expr(_, Graph, ResurRenaming, IteRenaming,
+		ActualRegionArgProc, ProgPoint, !GoalExpr, !GoalInfo,
+		!NameToVar, !VarSet, !VarTypes) :-
+	!.GoalExpr = plain_call(CalleePredId, CalleeProcId, Args0, Builtin,
+		Context, Name),
+	% XXX Callee may be a builtin or an imported procedure that we have
+	% not analysed, we just ignore such a call for now.
+	( if	map.search(ActualRegionArgProc, ProgPoint, ActualNodes0)
+	  then	ActualNodes = ActualNodes0
+	  else	ActualNodes = pair([],[])
+	),
+	ActualNodes = Ins - Outs,
+	AllNodes = Ins ++ Outs,
+	list.map_foldl3(node_to_var_with_both_renamings(Graph,
+		ResurRenaming, IteRenaming),
+		AllNodes, ActualRegionArgs, !NameToVar, !VarSet, !VarTypes),
+	Args = Args0 ++ ActualRegionArgs,
+	!:GoalExpr = plain_call(CalleePredId, CalleeProcId, Args, Builtin,
+		Context, Name).
+
+	% Annotate construction unifications with regions to construct in.
+	%
+region_transform_goal_expr(ModuleInfo, Graph, ResurRenaming, IteRenaming,
+		_, _, !GoalExpr, !GoalInfo, !NameToVar, !VarSet, !VarTypes) :-
+	!.GoalExpr = unify(LHS, RHS, Mode, Unification0, Context),
+    annotate_constructions_unification(ModuleInfo, Graph, ResurRenaming,
+		IteRenaming, Unification0, Unification, !NameToVar, !VarSet,
+		!VarTypes),
+	!:GoalExpr = unify(LHS, RHS, Mode, Unification, Context).
+
+region_transform_goal_expr(_, _, _, _, _, _, !GoalExpr, !GoalInfo, !NameToVar,
+		!VarSet, !VarTypes) :-
+	!.GoalExpr = generic_call(_, _, _, _),
+	sorry(this_file,
+		"region_transform_goal_expr: generic call is not handled.").
+
+region_transform_goal_expr(_, _, _, _, _, _, !GoalExpr, !GoalInfo, !NameToVar,
+		!VarSet, !VarTypes) :-
+	!.GoalExpr = call_foreign_proc(_, _, _, _, _, _, _),
+	sorry(this_file, "region_transform_goal_expr: " ++
+		"call to foreign procedure is not handled").
+
+region_transform_goal_expr(_, _, _, _, _, _, !GoalExpr, !GoalInfo, !NameToVar,
+		!VarSet, !VarTypes) :-
+	( !.GoalExpr = conj(_, [])
+	; !.GoalExpr = disj([])
+	).
+
+region_transform_goal_expr(_, _, _, _, _, _, !GoalExpr, !GoalInfo, !NameToVar,
+		!VarSet, !VarTypes) :-
+	( !.GoalExpr = conj(_, [_ | _])
+	; !.GoalExpr = disj([_ | _])
+	; !.GoalExpr = if_then_else(_, _, _, _)
+	; !.GoalExpr = negation(_)
+	; !.GoalExpr = switch(_, _, _)
+	; !.GoalExpr = scope(_, _)
+	; !.GoalExpr = shorthand(_)  
+	),
+	unexpected(this_file,
+		"region_transform_goal_expr: encounter compound goal").
+
+	% Because an atomic goal is turned into a conjunction, we need to
+	% flatten its compounding conjunction if it is in one.
+:- pred region_transform_compound_goal(module_info::in, rpt_graph::in,
+	renaming_proc::in, renaming_proc::in, pp_pair_region_list_table::in,
+	annotation_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.
+
+region_transform_compound_goal(ModuleInfo, Graph,
+		ResurRenamingProc, IteRenamingProc, ActualRegionArgProc,
+		AnnotationProc, ResurRenamingAnnoProc, IteRenamingAnnoProc,
+		hlds_goal(!.GoalExpr, !.GoalInfo), hlds_goal(!:GoalExpr, !:GoalInfo),
+		!NameToVar, !VarSet, !VarTypes) :-
+	(
+		!.GoalExpr = conj(ConjType, [Conj0 | Conjs0]),
+		list.map_foldl3(region_transform_goal(ModuleInfo, Graph,
+			ResurRenamingProc, IteRenamingProc,
+			ActualRegionArgProc, AnnotationProc,
+			ResurRenamingAnnoProc, IteRenamingAnnoProc),
+			[Conj0 | Conjs0], Conjs1, !NameToVar, !VarSet,
+			!VarTypes),
+		flatten_conj(Conjs1, Conjs),
+		!:GoalExpr = conj(ConjType, Conjs)
+	;
+		!.GoalExpr = disj([Disj0 | Disjs0]),
+		list.map_foldl3(region_transform_goal(ModuleInfo, Graph,
+			ResurRenamingProc, IteRenamingProc,
+			ActualRegionArgProc, AnnotationProc,
+			ResurRenamingAnnoProc, IteRenamingAnnoProc),
+			[Disj0 | Disjs0], Disjs, !NameToVar, !VarSet,
+			!VarTypes),
+		!:GoalExpr = disj(Disjs)
+	;
+		!.GoalExpr = switch(Var, CanFail, Cases0),
+		list.map_foldl3(region_transform_case(ModuleInfo, Graph,
+			ResurRenamingProc, IteRenamingProc,
+			ActualRegionArgProc, AnnotationProc,
+			ResurRenamingAnnoProc, IteRenamingAnnoProc,
+			hlds_goal(!.GoalExpr, !.GoalInfo)),
+			Cases0, Cases, !NameToVar, !VarSet, !VarTypes),
+		!:GoalExpr = switch(Var, CanFail, Cases)
+	;
+		!.GoalExpr = negation(Goal0),
+		region_transform_goal(ModuleInfo, Graph, ResurRenamingProc,
+			IteRenamingProc, ActualRegionArgProc, AnnotationProc,
+			ResurRenamingAnnoProc, IteRenamingAnnoProc, Goal0, Goal,
+			!NameToVar, !VarSet, !VarTypes),
+		!:GoalExpr = negation(Goal)
+	;
+		!.GoalExpr = scope(Reason, Goal0),
+		region_transform_goal(ModuleInfo, Graph, ResurRenamingProc,
+			IteRenamingProc, ActualRegionArgProc, AnnotationProc,
+			ResurRenamingAnnoProc, IteRenamingAnnoProc, Goal0, Goal,
+			!NameToVar, !VarSet, !VarTypes),
+		!:GoalExpr = scope(Reason, Goal)
+	;
+		!.GoalExpr = if_then_else(Vars, Cond0, Then0, Else0),
+		region_transform_goal(ModuleInfo, Graph, ResurRenamingProc,
+			IteRenamingProc, ActualRegionArgProc, AnnotationProc,
+			ResurRenamingAnnoProc, IteRenamingAnnoProc, Cond0, Cond,
+			!NameToVar, !VarSet, !VarTypes),
+		region_transform_goal(ModuleInfo, Graph, ResurRenamingProc,
+			IteRenamingProc, ActualRegionArgProc, AnnotationProc,
+			ResurRenamingAnnoProc, IteRenamingAnnoProc, Then0, Then,
+			!NameToVar, !VarSet, !VarTypes),
+		region_transform_goal(ModuleInfo, Graph, ResurRenamingProc,
+			IteRenamingProc, ActualRegionArgProc, AnnotationProc,
+			ResurRenamingAnnoProc, IteRenamingAnnoProc, Else0, Else,
+			!NameToVar, !VarSet, !VarTypes),
+		!:GoalExpr = if_then_else(Vars, Cond, Then, Else)
+	;	
+		( !.GoalExpr = shorthand(_)
+		; !.GoalExpr = unify(_, _, _, _, _)
+		; !.GoalExpr = plain_call(_, _, _, _, _, _)
+		; !.GoalExpr = generic_call(_, _, _, _)
+		; !.GoalExpr = call_foreign_proc(_, _, _, _, _, _, _)
+		; !.GoalExpr = conj(_, [])
+		; !.GoalExpr = disj([])
+		),
+		unexpected(this_file, "region_transform_compound_goal: " ++
+			"encounter shorthand or atomic goal")
+	).
+
+	% This predicate needs to be consistent with what are done in
+	% unify_gen.m, i.e., we will change how_to_construct to 
+	% construct_in_region(RegVar) only when the term is actually 
+	% stored in the heap.
+	% The current implementation may not be correct.
+	%
+:- pred annotate_constructions_unification(module_info::in, rpt_graph::in,
+	renaming::in, renaming::in, unification::in, unification::out,
+	name_to_prog_var::in, name_to_prog_var::out,
+	prog_varset::in, prog_varset::out, vartypes::in, vartypes::out) is det.
+
+annotate_constructions_unification(ModuleInfo, Graph, ResurRenaming,
+		IteRenaming, !Unification, !NameToVar, !VarSet, !VarTypes) :-
+	!.Unification = construct(Var, ConsId, Args, ArgModes, _HowToConstruct0,
+		IsUnique, SubInfo),
+	get_node_by_variable(Graph, Var, Node),
+	NodeType = rptg_lookup_node_type(Graph, Node),
+	( if	( type_is_atomic(ModuleInfo, NodeType)
+			; is_dummy_argument_type(ModuleInfo, NodeType)
+			)
+	  then  true
+	  else
+		Name = rptg_lookup_region_name(Graph, Node),
+		region_name_to_var_with_both_renamings(Name, ResurRenaming,
+			IteRenaming, RegVar, !NameToVar, !VarSet, !VarTypes),
+		HowToConstruct = construct_in_region(RegVar),
+		!:Unification = construct(Var, ConsId, Args, ArgModes,
+			HowToConstruct, IsUnique, SubInfo)
+	).
+
+annotate_constructions_unification(_, _, _, _, !Unification, !VarSet,
+		!VarTypes, !NameToVar) :-
+	(
+		( !.Unification = deconstruct(_, _, _, _, _, _)
+		; !.Unification = assign(_, _)
+		; !.Unification = simple_test(_, _)
+		)
+	;
+		!.Unification = complicated_unify(_, _, _),
+		unexpected(this_file, "annotate_construction_unification: "
+			++ "encounter complicated unify")
+	).
+	
+	% The process here is related to the way we treat the unifications 
+	% between the switch vars and a constant or a functor of arity zero.
+	% For more information about the treatment, see rbmm.execution_path.m.
+	% These unifications are not explicitly present in the goal but we 
+	% still need to insert annotations derived for them into the goal.
+	% Therefore we will make a conjunction of the annotations attached to an
+	% implicit unification. We transform the goal separately. Then we make
+	% another conjunction of the conjunction and the transformed goal.
+	% Finally, we try to flatten this new conjunction.
+	%
+:- pred region_transform_case(module_info::in, rpt_graph::in,
+	renaming_proc::in, renaming_proc::in, pp_pair_region_list_table::in,
+	annotation_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.
+
+region_transform_case(ModuleInfo, Graph, ResurRenamingProc,
+		IteRenamingProc, ActualRegionArgProc, AnnotationProc,
+		ResurRenamingAnnoProc, IteRenamingAnnoProc, Switch,
+		case(ConsId, !.Goal), case(ConsId, !:Goal),
+		!NameToVar, !VarSet, !VarTypes) :-
+	(	( ConsId = cons(_, 0)
+		; ConsId = int_const(_)
+		; ConsId = string_const(_)
+		; ConsId = float_const(_)
+		),
+		Switch = hlds_goal(switch(_, _, _), Info)
+	->
+		ProgPoint = program_point_init(Info),
+		ProgPoint = pp(Context, _),
+		find_renamings_at_prog_point(ResurRenamingProc, IteRenamingProc,
+			ProgPoint, ResurRenaming, IteRenaming), 
+
+		% Assignment unifications due to ite renaming.
+		assignments_from_ite_renaming_anno(IteRenamingAnnoProc,
+			ProgPoint, !NameToVar, !VarSet, !VarTypes,
+			[], IteRenamingAssignments),
+
+		% Region instructions before and after this program
+		% point.
+		(	map.search(AnnotationProc, ProgPoint,
+				before_after(Before, After))
+		->
+			% Region instructions before this program point.
+			list.foldl4(region_instruction_to_conj(
+				ModuleInfo, Context, ResurRenaming,
+				IteRenaming), Before, !NameToVar,
+				!VarSet, !VarTypes,
+				IteRenamingAssignments, Conjs1),
+
+			% Region instructions after this program point.
+			list.foldl4(region_instruction_to_conj(
+				ModuleInfo, Context, ResurRenaming,
+				IteRenaming), After, !NameToVar,
+				!VarSet, !VarTypes, Conjs1, Conjs2)
+		;
+			Conjs2 = IteRenamingAssignments
+		),
+
+		% Assignment unifications due to region resurrection
+		% renaming.
+		assignments_from_resur_renaming_anno(ResurRenamingAnnoProc,
+			ProgPoint, IteRenaming, !NameToVar, !VarSet, !VarTypes,
+			Conjs2, Conjs),
+	
+		RemovedGoal = hlds_goal(conj(plain_conj, Conjs), Info)
+	;
+		Switch = hlds_goal(_, Info),
+		RemovedGoal = hlds_goal(conj(plain_conj, []), Info)	
+	),
+	region_transform_goal(ModuleInfo, Graph, ResurRenamingProc,
+		IteRenamingProc, ActualRegionArgProc, AnnotationProc,
+		ResurRenamingAnnoProc, IteRenamingAnnoProc, !Goal, !NameToVar,
+		!VarSet, !VarTypes),
+	flatten_conj([RemovedGoal, !.Goal], FlatConjs),
+	Switch = hlds_goal(_, ConjsInfo),
+	!:Goal = hlds_goal(conj(plain_conj, FlatConjs), ConjsInfo).
+
+:- pred find_renamings_at_prog_point(renaming_proc::in, renaming_proc::in,
+	program_point::in, renaming::out, renaming::out) is det.
+
+find_renamings_at_prog_point(ResurRenamingProc, IteRenamingProc, ProgPoint,
+		ResurRenaming, IteRenaming) :-
+	( if	map.search(ResurRenamingProc, ProgPoint, ResurRenaming0)
+	  then	ResurRenaming = ResurRenaming0
+	  else	ResurRenaming = map.init
+	),
+	( if	map.search(IteRenamingProc, ProgPoint, IteRenaming0)
+	  then	IteRenaming = IteRenaming0
+	  else	IteRenaming = map.init
+	).
+
+:- pred assignments_from_ite_renaming_anno(renaming_annotation_proc::in,
+	program_point::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.
+
+assignments_from_ite_renaming_anno(IteRenamingAnnoProc, ProgPoint,
+		!NameToVar, !VarSet, !VarTypes, !IteRenamingAssignments) :-
+	% Assignment unifications due to ite renaming.
+	(	map.search(IteRenamingAnnoProc, ProgPoint, IteRenamingAnnos)
+	->
+		list.foldl4(ite_renaming_annotation_to_assignment,
+			IteRenamingAnnos, !NameToVar, !VarSet, !VarTypes,
+			!IteRenamingAssignments)
+	;	true
+	).
+
+:- pred assignments_from_resur_renaming_anno(renaming_annotation_proc::in,
+	program_point::in, renaming::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.
+
+assignments_from_resur_renaming_anno(ResurRenamingAnnoProc, ProgPoint,
+		IteRenaming, !NameToVar, !VarSet, !VarTypes, !Conjs) :-
+	(	map.search(ResurRenamingAnnoProc, ProgPoint,
+			ResurRenamingAnnos)
+	->
+		list.foldl4(resur_renaming_annotation_to_assignment(
+			IteRenaming), ResurRenamingAnnos, !NameToVar, !VarSet,
+			!VarTypes, !Conjs)
+	;	true
+	).
+
+	% Return the program variable representing the region which is
+	% represented by the node in the points-to graph.
+	% Come up with a new program variable if none exists yet.
+	% Each node is associated with a region name, so this predicate just
+	% delegates the task for region_name_to_var.
+	%
+:- pred node_to_var(rpt_graph::in, rptg_node::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.
+
+node_to_var(Graph, Node, RegVar, !NameToVar, !VarSet,
+		!VarTypes) :-
+	RegName = rptg_lookup_region_name(Graph, Node),
+	region_name_to_var(RegName, RegVar, !NameToVar, !VarSet, !VarTypes).
+ 
+	% Return the program variable representing the region name.
+	% Come up with a new one if none exists.
+	%
+:- pred region_name_to_var(string::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(Name, RegVar, !NameToVar, !VarSet, !VarTypes) :-
+	( if	map.search(!.NameToVar, Name, RegVar0)
+	  then	RegVar = RegVar0
+	  else
+			svvarset.new_named_var(Name, RegVar, !VarSet),
+			svmap.det_insert(RegVar, make_region_type, !VarTypes),
+			svmap.det_insert(Name, RegVar, !NameToVar)
+	).
+
+	% The same as node_to_var, but the corresponding region name is 
+	% subjected to resurrection and if-then-else renaming beforehand.
+	%
+:- pred node_to_var_with_both_renamings(rpt_graph::in, renaming::in,
+	renaming::in, rptg_node::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.
+
+node_to_var_with_both_renamings(Graph, ResurRenaming, IteRenaming,
+		Node, RegVar, !NameToVar, !VarSet, !VarTypes) :-
+	RegName = rptg_lookup_region_name(Graph, Node),
+	region_name_to_var_with_both_renamings(RegName, ResurRenaming,
+		IteRenaming, RegVar, !NameToVar, !VarSet, !VarTypes).
+
+	% 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.
+	%
+:- 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,
+	prog_varset::in, prog_varset::out, vartypes::in, vartypes::out) is det.
+
+region_name_to_var_with_both_renamings(Name0, ResurRenaming, IteRenaming,
+		RegVar, !NameToVar, !VarSet, !VarTypes) :-
+	( if	map.search(ResurRenaming, Name0, Name1)
+	  then	Name = Name1
+	  else
+			( if	map.search(IteRenaming, Name0, Name2)
+			  then	Name = Name2
+			  else  Name = Name0
+			)
+	),
+	region_name_to_var(Name, RegVar, !NameToVar, !VarSet, !VarTypes). 
+
+	% The same as region_name_to_var, but the region name here is 
+	% subjected to resurrection renaming in advance.
+	%
+:- pred region_name_to_var_with_renaming(string::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_renaming(Name0, ResurRenaming, RegVar,
+		!NameToVar, !VarSet, !VarTypes) :-
+	( if	map.search(ResurRenaming, Name0, Name1)
+	  then	Name = Name1
+	  else	Name = Name0
+	),
+	region_name_to_var(Name, RegVar, !NameToVar, !VarSet, !VarTypes). 
+
+:- func make_region_type = mer_type.
+
+make_region_type = RegionType :-
+	RegionTypeName = qualified(mercury_region_builtin_module, "region"),
+	RegionType = defined_type(RegionTypeName, [], kind_star).
+
+	% Instruction is of the form: "Tx: xxxxxx R..."
+	% The first x is the number of the rule, which is not important here.
+	% The next 6 x is either "remove" or "create", the last part is the
+	% region name. This region name will be 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  This is temporary. Using string to represent region instructions
+	% (create, remove, renaming, maybe some more in the future) is not good.
+	% Region instruction should become a specific type with distinct 
+	% constructor for each kind of instruction.
+	% XXX  Call to generate_simple_call here seems overkilled because we
+	% will recompute nonlocals, instmap delta anyway.
+	%
+:- pred region_instruction_to_conj(module_info::in, term.context::in,
+	renaming::in, renaming::in, string::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(ModuleInfo, Context, ResurRenaming, IteRenaming,
+		Instruction, !NameToVar, !VarSet, !VarTypes, Conjs0, Conjs) :-
+	string.substring(Instruction, 4, 6, Kind),
+	string.substring(Instruction, 11, string.length(Instruction) - 11,
+		RegionName),
+	region_name_to_var_with_both_renamings(RegionName, ResurRenaming,
+		IteRenaming, RegVar, !NameToVar, !VarSet, !VarTypes),
+	(	Kind = "create" ->
+		generate_simple_call(mercury_region_builtin_module,
+			"create_region", pf_predicate, only_mode, detism_det,
+			purity_impure, [RegVar], [], [],
+			ModuleInfo, Context, CallGoal)
+	;
+		Kind = "remove"
+	->
+		generate_simple_call(mercury_region_builtin_module,
+			"remove_region", pf_predicate, only_mode, detism_det,
+			purity_impure, [RegVar], [], [],
+			ModuleInfo, Context, CallGoal)
+	;
+		unexpected(this_file, "region_instruction_to_conj: " ++
+			"encounter unknown region 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.
+	% This predicate converts the anotation into an assigment unification.
+	% The original name of the region is subjected to the renaming due to
+	% if-then-else, if such a renaming exists at the current program point.
+	%
+:- pred resur_renaming_annotation_to_assignment(renaming::in, string::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.
+
+resur_renaming_annotation_to_assignment(IteRenaming, Annotation,
+		!NameToVar, !VarSet, !VarTypes, Conjs0, Conjs) :-
+	( if	string.sub_string_search(Annotation, "=", Index)
+	  then
+			Left = string.substring(Annotation, 0, Index - 1),
+			Right = string.substring(Annotation, Index + 2, 
+				string.length(Annotation) - (Index + 2)),
+			% Only the left region needs to be renamed. Ite renaming
+			% does not involve one on the right side.
+			region_name_to_var_with_renaming(Left, IteRenaming,
+				LeftRegVar, !NameToVar, !VarSet, !VarTypes),
+			region_name_to_var(Right, RightRegVar, !NameToVar,
+				!VarSet, !VarTypes),
+			make_assignment_goal(LeftRegVar, RightRegVar,
+				"resurrection renaming annotation",
+				AssignmentGoal),
+			Conjs = Conjs0 ++ [AssignmentGoal]
+	  else
+			unexpected(this_file, "resur_renaming_annotation_to_assignment: "
+				++ "annotation is not assigment")
+	).
+
+	% This predicate turns a renaming annotation due to if-then-else into
+	% an assignment. No renaming needs to be applied to the 
+	% if-then-else renaming annotations.
+	%
+:- pred ite_renaming_annotation_to_assignment(string::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.
+
+ite_renaming_annotation_to_assignment(Annotation, !NameToVar,
+		!VarSet, !VarTypes, Conjs0, Conjs) :-
+	( if	string.sub_string_search(Annotation, "=", Index)
+	  then
+			Left = string.substring(Annotation, 0, Index - 1),
+			Right = string.substring(Annotation, Index + 2, 
+				string.length(Annotation) - (Index + 2)),
+			region_name_to_var(Left, LeftRegVar, !NameToVar,
+				!VarSet, !VarTypes),
+			region_name_to_var(Right, RightRegVar, !NameToVar,
+				!VarSet, !VarTypes),
+			make_assignment_goal(LeftRegVar, RightRegVar,
+				"ite renaming annotation", AssignmentGoal),
+			Conjs = Conjs0 ++ [AssignmentGoal]
+	  else
+			unexpected(this_file, "ite_renaming_annotation_to_assignment: "
+				++ "annotation is not assignment")
+	).
+
+:- pred make_assignment_goal(prog_var::in, prog_var::in, string::in,
+	hlds_goal::out) is det.
+
+make_assignment_goal(LeftRegVar, RightRegVar, Context, AssignmentGoal) :-
+	AssignmentExpr = unify(LeftRegVar, rhs_var(RightRegVar),
+		out_mode - in_mode,
+		assign(LeftRegVar, RightRegVar),
+		unify_context(
+			umc_implicit(Context),
+			[]
+		)
+	),
+	% Nonlocals and instmap delta will be recomputed anyway, so just put
+	% dummy values in.
+	NonLocals = set.init,
+	instmap_delta_from_assoc_list([], InstmapDelta),
+	goal_info_init(NonLocals, InstmapDelta, detism_det, purity_pure,
+		AssignmentInfo),
+	AssignmentGoal = hlds_goal(AssignmentExpr, AssignmentInfo).
+
+%-----------------------------------------------------------------------------%
+%
+% Recompute instmap delta. 
+%
+
+:- pred update_instmap_delta_pred(pred_id::in, module_info::in,
+	module_info::out) is det.
+	
+update_instmap_delta_pred(PredId, !ModuleInfo) :-
+    module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
+    ProcIds = pred_info_non_imported_procids(PredInfo),
+    list.foldl(update_instmap_delta_proc(PredId), ProcIds, !ModuleInfo).
+
+:- pred update_instmap_delta_proc(pred_id::in, proc_id::in, 
+	module_info::in, module_info::out) is det.
+
+update_instmap_delta_proc(PredId, ProcId, !ModuleInfo) :-
+	PPId = proc(PredId, ProcId),
+	module_info_pred_proc_info(!.ModuleInfo, PPId, PredInfo, ProcInfo0),
+	RecomputeAtomic = yes,
+	recompute_instmap_delta_proc(RecomputeAtomic, ProcInfo0, ProcInfo,
+		!ModuleInfo),
+	module_info_set_pred_proc_info(PPId, PredInfo, ProcInfo, !ModuleInfo).
+
+%-----------------------------------------------------------------------------%
+%
+% Recheck purity.
+%
+
+:- pred check_purity_pred(pred_id::in, module_info::in,
+	module_info::out) is det.
+
+check_purity_pred(PredId, !ModuleInfo) :-
+    module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
+    ProcIds = pred_info_non_imported_procids(PredInfo),
+	list.foldl(check_purity_proc(PredId), ProcIds, !ModuleInfo).
+
+	% Recheck purity of the procedure.
+	% This predicate is only called when all the procedures have been
+	% annotated with region information and recorded. This is necessary
+	% because repuritycheck_proc looks up information
+	% about procedures.
+	%
+:- pred check_purity_proc(pred_id::in, proc_id::in, module_info::in,
+	module_info::out) is det.
+
+check_purity_proc(PredId, ProcId, !ModuleInfo) :- 
+	module_info_pred_info(!.ModuleInfo, PredId, PredInfo0),
+	% Recheck purity of this procedure.
+	PPId = proc(PredId, ProcId),
+	repuritycheck_proc(!.ModuleInfo, PPId, PredInfo0, PredInfo),
+	module_info_set_pred_info(PredId, PredInfo, !ModuleInfo).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "rbmm.region_transformation.m".
+
+%-----------------------------------------------------------------------------%
Index: rbmm.actual_region_arguments.m
===================================================================
RCS file:
/home/mercury/mercury1/repository/mercury/compiler/rbmm.actual_region_arguments.m,v
retrieving revision 1.1
diff -u -u -r1.1 rbmm.actual_region_arguments.m
--- rbmm.actual_region_arguments.m	8 Jun 2007 06:45:11 -0000	1.1
+++ rbmm.actual_region_arguments.m	27 Jun 2007 07:35:21 -0000
@@ -31,14 +31,23 @@
 
 :- import_module list.
 :- import_module map.
+:- import_module pair.
 
-:- type proc_pp_region_list_table == map(pred_proc_id, pp_region_list_table).
-
-:- type pp_region_list_table == map(program_point, list(rptg_node)).
+:- type proc_pp_pair_region_list_table
+    ==  map(
+                pred_proc_id,
+                pp_pair_region_list_table
+        ).
+
+:- type pp_pair_region_list_table
+    ==  map(
+                program_point,
+                pair(list(rptg_node), list(rptg_node))
+        ).
         
 :- pred record_actual_region_arguments(module_info::in, rpta_info_table::in,
     proc_region_set_table::in, proc_region_set_table::in,
-    proc_region_set_table::in, proc_pp_region_list_table::out) is det.
+    proc_region_set_table::in, proc_pp_pair_region_list_table::out) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -65,7 +74,8 @@
 :- pred record_actual_region_arguments_pred(module_info::in,
     rpta_info_table::in, proc_region_set_table::in,
     proc_region_set_table::in, proc_region_set_table::in, pred_id::in,
-    proc_pp_region_list_table::in, proc_pp_region_list_table::out) is det.
+    proc_pp_pair_region_list_table::in, proc_pp_pair_region_list_table::out)
+    is det.
 
 record_actual_region_arguments_pred(ModuleInfo, RptaInfoTable,
         ConstantRTable, DeadRTable, BornRTable, PredId,
@@ -79,7 +89,8 @@
 :- pred record_actual_region_arguments_proc(module_info::in, pred_id::in,
     rpta_info_table::in, proc_region_set_table::in,
     proc_region_set_table::in, proc_region_set_table::in, proc_id::in, 
-    proc_pp_region_list_table::in, proc_pp_region_list_table::out) is det.
+    proc_pp_pair_region_list_table::in, proc_pp_pair_region_list_table::out)
+    is det.
 
 record_actual_region_arguments_proc(ModuleInfo, PredId, RptaInfoTable,
         ConstantRTable, DeadRTable, BornRTable, ProcId,
@@ -101,7 +112,7 @@
 :- pred record_actual_region_arguments_goal(module_info::in,
     pred_proc_id::in, rpta_info_table::in, proc_region_set_table::in,
     proc_region_set_table::in, proc_region_set_table::in, hlds_goal::in, 
-    pp_region_list_table::in, pp_region_list_table::out) is det.
+    pp_pair_region_list_table::in, pp_pair_region_list_table::out) is det.
 
 record_actual_region_arguments_goal(ModuleInfo, PPId, RptaInfoTable,
         ConstantRTable, DeadRTable, BornRTable, Goal,
@@ -115,7 +126,7 @@
     hlds_goal_info::in, module_info::in, pred_proc_id::in,
     rpta_info_table::in, proc_region_set_table::in,
     proc_region_set_table::in, proc_region_set_table::in,
-    pp_region_list_table::in, pp_region_list_table::out) is det.
+    pp_pair_region_list_table::in, pp_pair_region_list_table::out) is det.
 
 record_actual_region_arguments_expr(conj(_, Conjs), _, ModuleInfo, PPId,
         RptaInfoTable, ConstantRTable, DeadRTable, BornRTable,
@@ -181,7 +192,7 @@
 :- pred record_actual_region_arguments_case(module_info::in,
     pred_proc_id::in, rpta_info_table::in, proc_region_set_table::in,
     proc_region_set_table::in, proc_region_set_table::in, case::in, 
-    pp_region_list_table::in, pp_region_list_table::out) is det.
+    pp_pair_region_list_table::in, pp_pair_region_list_table::out) is det.
 
 record_actual_region_arguments_case(ModuleInfo, PPId, RptaInfoTable,
         ConstantRTable, DeadRTable, BornRTable, Case, !ActualRegionArgProc) :-
@@ -207,7 +218,7 @@
     program_point::in, pred_proc_id::in,
     rpta_info_table::in, proc_region_set_table::in, 
     proc_region_set_table::in, proc_region_set_table::in, 
-    pp_region_list_table::in, pp_region_list_table::out) is det.
+    pp_pair_region_list_table::in, pp_pair_region_list_table::out) is det.
 
 record_actual_region_arguments_call_site(CallerPPId, CallSite,
         CalleePPId, RptaInfoTable, ConstantRTable, DeadRTable,
@@ -238,9 +249,9 @@
         LActualBornR0),
	list.reverse(LActualBornR0, LActualBornR),
 
-    % Record in the order: constants, deads, and borns.
-	L = LActualConstantR ++ LActualDeadR ++ LActualBornR,
-    svmap.det_insert(CallSite, L, !ActualRegionArgProc).
+    % Record in the order: (constants, deads) and borns.
+	Ins = LActualConstantR ++ LActualDeadR,
+    svmap.det_insert(CallSite, Ins - LActualBornR, !ActualRegionArgProc).
 
 :- pred find_actual_param(map(rptg_node, rptg_node)::in, rptg_node::in, 
     list(rptg_node)::in, list(rptg_node)::out) is det.
--------------------------------------------------------------------------
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