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

Quan Phan Quan.Phan at cs.kuleuven.be
Mon Jun 18 23:12:46 AEST 2007


Hi,

Estimated hours taken: 25.
Branch: main.

Annotate the HLDS with information about regions. This includes calls to
region builtins, extra region arguments for procedures and calls, regions
for construction unifications.

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/quantification.m
compiler/structure_reuse.indirect.m
	Change to suit with the above additional type constructor.

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.

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.

Regards,
Quan

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_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	8 Jun 2007 06:51:38 -0000
@@ -764,12 +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
 
+    ;
+            construct_in_region(prog_var)
+
     ;       reuse_cell(cell_to_reuse).
             % Reuse an existing heap cell.
 
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: 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	18 Jun 2007 12:35:51 -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: contruct in region")
+            ;
                 ( HowToConstruct = construct_statically(_)
                 ; HowToConstruct = construct_dynamically
                 )
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: 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	18 Jun 2007 12:37:41 -0000
@@ -517,6 +517,8 @@
         ;
             ( How = construct_statically(_)
             ; How = construct_dynamically
+            % XXX Temporary for the time being.
+            ; How = construct_in_region(_)
             ),
             MaybeSetArgs = no,
             MaybeReuseVar = no
@@ -1129,6 +1131,8 @@
         ;
             ( How = construct_statically(_)
             ; How = construct_dynamically
+            % XXX Temporary for the time being.
+            ; How = construct_in_region(_)
             ),
             MaybeSetArgs = no
         ),
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	18 Jun 2007 07:46:31 -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
+% 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 surrection 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_renaming(Graph, ResurRenaming),
+				RemovedAfterNodes, set.init,
+				RemovedAfterRegions0),
+			set.fold(apply_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_renaming(rpt_graph::in, renaming::in, rptg_node::in,
+	set(string)::in, set(string)::out) is det.
+
+apply_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_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	18 Jun 2007 07:32: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,10 @@
 :- 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.
+:- import_module hlds.hlds_out.
 
 %-----------------------------------------------------------------------------%
 
@@ -75,11 +80,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 +95,28 @@
     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, Module),
+	write_hlds(2, Module, !IO).
 
 %-----------------------------------------------------------------------------%
 :- 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	18 Jun 2007 07:49:45 -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 2 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,
@@ -199,13 +229,97 @@
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-    % 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,
+        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])
+    ).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+% 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 +378,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 +396,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 +410,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 +587,20 @@
     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)
+            %true
     ).
 
 :- 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	18 Jun 2007 06:46:46 -0000
@@ -0,0 +1,944 @@
+%-----------------------------------------------------------------------------%
+% 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.
+%-----------------------------------------------------------------------------%
+
+:- 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_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 hlds.goal_util.
+:- import_module hlds.hlds_goal.
+:- import_module hlds.instmap.
+:- import_module hlds.pred_table.
+:- 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 int.
+:- import_module list.
+:- import_module pair.
+:- import_module set.
+:- import_module svmap.
+:- 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).
+
+	% 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
+	  		module_info_pred_info(!.ModuleInfo, PredId, PredInfo0),
+	  		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(PredInfo0),
+			pred_info_set_orig_arity(Arity + NumberOfRegArgs,
+				PredInfo0, PredInfo1),
+
+			generate_list_of_region_type(NumberOfRegArgs,
+				make_region_type, RegionTypes),
+			pred_info_get_arg_types(PredInfo1, TypeVarSet,
+				ExistQuantTVars, ArgTypes0),
+			PredOrFunc = pred_info_is_pred_or_func(PredInfo1),
+			(
+				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, PredInfo1, PredInfo2),
+			module_info_set_pred_info(PredId, PredInfo2,
+				!ModuleInfo),
+			!:Processed = [PredId | !.Processed]
+	).
+			
+:- pred generate_list_of_region_type(int::in, mer_type::in,
+	list(mer_type)::out) is det.
+
+generate_list_of_region_type(N, RegType, RegTypes) :-
+	( if	N = 0
+	  then
+	  	    RegTypes = []
+	  else
+			generate_list_of_region_type(N - 1, RegType, RegTypes0),
+			RegTypes = [RegType | RegTypes0]
+	).
+
+	% 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_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.
+	%
+:- 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_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, PredInfo, 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, PredInfo, Graph, ConstantR, DeadR, BornR,
+		ActualRegionArgProc, ResurRenamingProc, IteRenamingProc,
+		AnnotationProc, ResurRenamingAnnoProc, IteRenamingAnnoProc,
+		VarSet0, _, VarTypes0, _, HeadVars0, _, ActualArgModes0, _,
+		Goal0, _, NameToVar0, NameToVar, ProcInfo1, ProcInfo),
+
+	module_info_set_pred_proc_info(PPId, PredInfo, 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
+	%
+	% XXX What about head_var_caller_liveness and
+	% prog_sub_info -> arg_pass_info
+	%
+	%
+:- pred annotate_proc(module_info::in, pred_info::in, rpt_graph::in,
+	region_set::in, region_set::in, region_set::in,
+	pp_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_reg_var(Graph), FormalNodes, FormalRegionArgs,
+		!NameToVar, !VarSet, !VarTypes),
+
+	% Computing actual_head_modes.
+	InMode = in_mode,
+	OutMode = out_mode,
+	list.foldl(generate_mode_list(InMode), FormalInputNodes, [], InModes),
+	list.foldl(generate_mode_list(OutMode), LBornR, [], 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).
+
+:- pred generate_mode_list(mer_mode::in, rptg_node::in, list(mer_mode)::in,
+	list(mer_mode)::out) is det.
+
+generate_mode_list(Mode, _Node, Modes0, [Mode | Modes0]).
+
+	% Basically, we will turn this atomic goal and all the region
+	% annotations attached to (before and after) it into a
+	% conjunction (even when there is no annotation). 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_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, Info), 
+	(	goal_is_atomic(GoalExpr0)
+	->
+		ProgPoint = program_point_init(Info),
+		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(Graph, ResurRenaming,
+			IteRenaming, ActualRegionArgProc, ProgPoint,
+			GoalExpr0, GoalExpr, !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),
+	
+		!:Goal = hlds_goal(conj(plain_conj, Conjs), Info)
+	;
+		region_transform_compound_goal(ModuleInfo, Graph,
+			ResurRenamingProc, IteRenamingProc, ActualRegionArgProc,
+			AnnotationProc, ResurRenamingAnnoProc,
+			IteRenamingAnnoProc, !Goal, !NameToVar, !VarSet,
+			!VarTypes)
+	).
+
+:- pred region_transform_goal_expr(rpt_graph::in, renaming::in,
+	renaming::in, pp_region_list_table::in, program_point::in,
+	hlds_goal_expr::in, hlds_goal_expr::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, !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 = []
+	),
+	list.map_foldl3(node_to_reg_var_with_both_renamings(Graph,
+		ResurRenaming, IteRenaming),
+		ActualNodes, 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(Graph, ResurRenaming, IteRenaming,
+		_, _, !GoalExpr, !NameToVar, !VarSet, !VarTypes) :-
+	!.GoalExpr = unify(LHS, RHS, Mode, Unification0, Context),
+    annotate_constructions_unification(Graph, ResurRenaming, IteRenaming,
+		Unification0, Unification, !NameToVar, !VarSet, !VarTypes),
+	!:GoalExpr = unify(LHS, RHS, Mode, Unification, Context).
+
+region_transform_goal_expr(_, _, _, _, _, !GoalExpr, !NameToVar,
+		!VarSet, !VarTypes) :-
+	!.GoalExpr = generic_call(_, _, _, _),
+	sorry(this_file,
+		"region_transform_goal_expr: generic call is not handled.").
+
+region_transform_goal_expr(_, _, _, _, _, !GoalExpr, !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, !NameToVar,
+		!VarSet, !VarTypes) :-
+	( !.GoalExpr = conj(_, [])
+	; !.GoalExpr = disj([])
+	).
+
+region_transform_goal_expr(_, _, _, _, _, !GoalExpr, !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.
+	% For switch, 
+:- pred region_transform_compound_goal(module_info::in, rpt_graph::in,
+	renaming_proc::in, renaming_proc::in, pp_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_conjunction(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")
+	).
+
+:- pred annotate_constructions_unification(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(Graph, ResurRenaming, IteRenaming,
+		!Unification, !NameToVar, !VarSet, !VarTypes) :-
+	!.Unification = construct(Var, ConsId, Args, ArgModes, _HowToConstruct0,
+		IsUnique, SubInfo),
+	get_node_by_variable(Graph, Var, Node),
+	Name = rptg_lookup_region_name(Graph, Node),
+	name_to_reg_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(_, _)
+		),
+		true
+	;
+		!.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_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_conjunction([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
+	).
+	
+	% XXX This flatten predicate is copied and pasted from
+	% prop_mode_constraints.m.
+	%
+    % flatten_conjunction(!Goals) flattens the conjunction Goals - that
+    % is, moves the conjuncts from nested conjunctions into Goals.
+    % 
+:- pred flatten_conjunction(hlds_goals::in, hlds_goals::out) is det.
+
+flatten_conjunction(!Goals) :-
+    list.foldr(add_to_conjunction, !.Goals, [], !:Goals).
+
+    % add_to_conjunction(Goal, !Goals) adds Goal to the front of
+    % the conjunction Goals. It keeps the conjunction flat, so
+    % nested conjunctions are scrapped and their conjuncts prepended
+    % to Goals.
+    %
+:- pred add_to_conjunction(hlds_goal::in, hlds_goals::in, hlds_goals::out)
+    is det.
+
+add_to_conjunction(Goal, !Goals) :-
+    ( Goal = hlds_goal(conj(plain_conj, SubGoals), _) ->
+        list.append(SubGoals, !Goals)
+    ;
+        list.cons(Goal, !Goals)
+    ).
+
+:- pred node_to_reg_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_reg_var(Graph, Node, RegVar, !NameToVar, !VarSet,
+		!VarTypes) :-
+	RegName = rptg_lookup_region_name(Graph, Node),
+	name_to_reg_var(RegName, RegVar, !NameToVar, !VarSet, !VarTypes).
+ 
+:- pred name_to_reg_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.
+
+name_to_reg_var(Name, RegVar, !NameToVar, !VarSet, !VarTypes) :-
+	( if	map.search(!.NameToVar, Name, RegVar0)
+	  then
+			RegVar = RegVar0
+	  else
+			varset.new_named_var(!.VarSet, Name, RegVar, !:VarSet),
+			svmap.det_insert(RegVar, make_region_type, !VarTypes),
+			svmap.det_insert(Name, RegVar, !NameToVar)
+	).
+
+:- pred node_to_reg_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_reg_var_with_both_renamings(Graph, ResurRenaming, IteRenaming,
+		Node, RegVar, !NameToVar, !VarSet, !VarTypes) :-
+	RegName = rptg_lookup_region_name(Graph, Node),
+	name_to_reg_var_with_both_renamings(RegName, ResurRenaming, IteRenaming,
+		RegVar, !NameToVar, !VarSet, !VarTypes).
+
+:- pred name_to_reg_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.
+
+name_to_reg_var_with_renaming(Name0, ResurRenaming, RegVar,
+		!NameToVar, !VarSet, !VarTypes) :-
+	( if	map.search(ResurRenaming, Name0, Name1)
+	  then
+	  		Name = Name1
+	  else
+			Name = Name0
+	),
+	name_to_reg_var(Name, RegVar, !NameToVar, !VarSet, !VarTypes). 
+
+	% Resurrection renaming will be applied first. If a renaming exists
+	% for the name (therefore the name is changed to another name) then
+	% ite renaming need not to be applied because actually it is not
+	% applicable anymore.
+:- pred name_to_reg_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.
+
+name_to_reg_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
+			)
+	),
+	name_to_reg_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).
+
+:- 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.
+
+	% 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.
+	%
+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),
+	name_to_reg_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], [], [RegVar - free_inst],
+			ModuleInfo, Context, CallGoal)
+	;
+		Kind = "remove"
+	->
+		generate_simple_call(mercury_region_builtin_module,
+			"remove_region", pf_predicate, only_mode, detism_det,
+			purity_impure, [RegVar], [], [RegVar - ground_inst],
+			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.
+			name_to_reg_var_with_renaming(Left, IteRenaming,
+				LeftRegVar, !NameToVar, !VarSet, !VarTypes),
+			name_to_reg_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)),
+			name_to_reg_var(Left, LeftRegVar, !NameToVar,
+				!VarSet, !VarTypes),
+			name_to_reg_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 = set.from_list([LeftRegVar, RightRegVar]),
+	instmap_delta_from_assoc_list([LeftRegVar - free_inst,
+		RightRegVar - ground_inst], InstmapDelta),
+	goal_info_init(NonLocals, InstmapDelta, detism_det,
+		purity_pure, AssignmentInfo),
+	AssignmentGoal = hlds_goal(AssignmentExpr, AssignmentInfo).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "rbmm.region_transformation.m".
+
+%-----------------------------------------------------------------------------%
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	18 Jun 2007 12:50:00 -0000
@@ -302,6 +302,8 @@
             ;
                 ( HowToConstruct = construct_dynamically
                 ; HowToConstruct = reuse_cell(_)
+                % XXX Temporary for the time being.
+                ; HowToConstruct = construct_in_region(_) 
                 )
             )
         ;


--------------------------------------------------------------------------
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