[m-rev.] for post-commit review: getting OISU information to the feedback tool

Zoltan Somogyi zs at unimelb.edu.au
Wed Oct 24 14:59:26 AEDT 2012


Note that this diff is BREAKS binary compatibility for debug and deep
profiling grades.

For review by anyone.

Zoltan.

The algorithm that decides whether the order independent state update
transformation is applicable in a given module needs access to the list
of oisu pragmas in that module, and to information about the types
of variables in the procedures named in those pragmas. This diff
puts this information in Deep.procrep files, to make them available
to the autoparallelization feedback program, to which that algorithm
will later be added.

Compilers that have this diff will generate Deep.procrep files in a new,
slightly different format, but the deep profiler will be able to read
Deep.procrep files not just in the new format, but in the old format as well.

runtime/mercury_stack_layout.h:
	Add to module layout structures the fields holding the new information
	we want to put into Deep.procrep files. This means three things:

	- a bytecode array in module layout structures encoding the list
	  of oisu pragmas in the module;
	- additions to the bytecode arrays in procedure layout structures
	  mapping the procedure's variables to their types; and
	- a bytecode array containing the encoded versions of those types
	  themselves in the module layout structure. This allows us to
	  represent each type used in the module just once.

	Since there is now information in module layout structures that 
	is needed only for deep profiling, as well as information that is
	needed only for debugging, the old arrangement that split a module's
	information between two structures, MR_ModuleLayout (debug specific
	info) and MR_ModuleCommonLayout (info used by both debugging and
	profiling), is no longer approriate. We could add a third structure
	containing profiling-specific info, but it is simpler to move
	all the info into just one structure, some of whose fields
	may not be used. This wastes only a few words of memory per module,
	but allows the runtime system to avoid unnecessary indirections.

runtime/mercury_types.h:
	Remove the type synonym for the deleted type.

runtime/mercury_grade.h:
	The change in mercury_stack_layout.h destroys binary compatibility
	with previous versions of Mercury for debug and deep profiling grades,
	so bump their grade-component-specific version numbers.

runtime/mercury_deep_profiling.c:
	Write out the information in the new fields in module layout
	structures, if they are filled in.

	Since this changes the format of the Deep.procrep file, bump
	its version number.

runtime/mercury_deep_profiling.h:
runtime/mercury_stack_layout.c:
	Conform to the change to mercury_stack_layout.h.

mdbcomp/program_representation.m:
	Add to module representations information about the oisu pragmas
	defined in that module, and the type table of the module.
	Optionally add to procedure representations a map mapping
	the variables of the procedure to their types.

	Rename the old var_table type to be the var_name_table type,
	since it contains just names. Make the var to type map separate,
	since it will be there only for selected procedures.

	Modify the predicates reading in module and procedure representations
	to allow them to read in the new representation, while still accepting
	the old one. Use the version number in the Deep.procrep file to decide
	which format to expect.

mdbcomp/rtti_access.m:
	Add functions to encode the data representations that this module
	also decodes.

	Conform to the changes above.

mdbcomp/feedback.automatic_parallelism.m:
	Conform the changes above.

mdbcomp/prim_data.m:
	Fix layout.

compiler/layout.m:
	Update the compiler's representation of layout structures
	to conform to the change to runtime/mercury_stack_layout.h.

compiler/layout_out.m:
	Output the new parts of module layout structures.

compiler/opt_debug.m:
	Allow the debugging of code referring to the new parts of
	module layout structures.

compiler/llds_out_file.m:
	Conform to the move to a single module layout structure.

compiler/prog_rep_tables.m:
	This new module provided mechanisms for building the string table
	and the type table components of module layouts. The string table
	part is old (it is moved here from stack_layout.m); the type table
	part is new.

	Putting this code in a module of its own allows us to remove
	a circular dependency between prog_rep.m and stack_layout.m;
	instead, both now just depend on prog_rep_tables.m.

compiler/ll_backend.m:
	Add the new module.

compiler/notes/compiler_design.html:
	Describe the new module.

compiler/prog_rep.m:
	When generating the representation of a module for deep profiling,
	include the information needed by the order independent state update
	analysis: the list of oisu pragmas in the module, if any, and
	information about the types of variables in selected procedures.

	To avoid having these additions increasing the size of the bytecode
	representation too much, convert some fixed 32 bit numbers in the
	bytecode to use variable sized numbers, which will usually be 8 or 16
	bits.

	Do not use predicates from bytecode_gen.m to encode numbers,
	since there is nothing keeping these in sync with the code that
	reads them in mdbcomp/program_representation.m. Instead, use
	new predicates in program_representation.m itself.

compiler/stack_layout.m:
	Generate the new parts of module layouts.

	Remove the code moved to prog_rep_tables.m.

compiler/continuation_info.m:
compiler/proc_gen.m:
	Make some more information available to stack_layout.m.

compiler/prog_data.m:
	Fix some formatting.

compiler/introduce_parallelism.m:
	Conform to the renaming of the var_table type.

compiler/follow_code.m:
	Fix the bug that used to cause the failure of the
	hard_coded/mode_check_clauses test case in deep profiling grades.

deep_profiler/program_representation_utils.m:
	Output the new parts of module and procedure representations,
	to allow the correctness of this change to be tested.

deep_profiler/mdprof_create_feedback.m:
	If we cannot read the Deep.procrep file, print a single error message
	and exit, instead of continuing with an analysis that will generate
	a whole bunch of error messages, one for each attempt to access
	a procedure's representation.

deep_profiler/mdprof_procrep.m:
	Give this program an option that specifies what file it is to
	look at; do not hardwire in "Deep.procrep" in the current directory.

deep_profiler/report.m:
	Add a report type that just prints the representation of a module.
	It returns the same information as mdprof_procrep, but from within
	the deep profiler, which can be more convenient.

deep_profiler/create_report.m:
deep_profiler/display_report.m:
	Respectively create and display the new report type.

deep_profiler/query.m:
	Recognize a query asking for the new report type.

deep_profiler/autopar_calc_overlap.m:
deep_profiler/autopar_find_best_par.m:
deep_profiler/autopar_reports.m:
deep_profiler/autopar_search_callgraph.m:
deep_profiler/autopar_search_goals.m:
deep_profiler/autopar_types.m:
deep_profiler/branch_and_bound.m:
deep_profiler/coverage.m:
deep_profiler/display.m:
deep_profiler/html_format.m:
deep_profiler/mdprof_test.m:
deep_profiler/measurements.m:
deep_profiler/query.m:
deep_profiler/read_profile.m:
deep_profiler/recursion_patterns.m:
deep_profiler/top_procs.m:
deep_profiler/top_procs.m:
	Conform to the changes above.

	Fix layout.

tests/debugger/declarative/dependency.exp2:
	Add this file as a possible expected output. It contains the new
	field added to module representations.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/extra
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/extra
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/doc
cvs diff: Diffing boehm_gc/libatomic_ops/pkgconfig
cvs diff: Diffing boehm_gc/libatomic_ops/src
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/armcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops/tests
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/m4
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/continuation_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.107
diff -u -b -r1.107 continuation_info.m
--- compiler/continuation_info.m	2 Jul 2012 01:16:33 -0000	1.107
+++ compiler/continuation_info.m	24 Oct 2012 03:50:13 -0000
@@ -153,6 +153,7 @@
                 pli_need_all_names      :: bool,
                 % True iff we need the names of all the variables.
 
+                pli_oisu_kind_fors      :: list(oisu_pred_kind_for),
                 pli_deep_prof           :: maybe(proc_deep_prof_info)
             ).
 
Index: compiler/follow_code.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/follow_code.m,v
retrieving revision 1.107
diff -u -b -r1.107 follow_code.m
--- compiler/follow_code.m	13 Feb 2012 00:11:37 -0000	1.107
+++ compiler/follow_code.m	24 Oct 2012 03:50:13 -0000
@@ -213,6 +213,13 @@
     (
         Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
         goal_util.goal_is_branched(GoalExpr0),
+        % A goal that has the mode_check_clauses marker on it will not
+        % have its set of output variables updated by recompute_instmap_delta.
+        % If we move new code into it, this lack of recomputation will
+        % be a bug if that code binds any variables, which it almost certainly
+        % will.
+        not goal_info_has_feature(GoalInfo0, feature_mode_check_clauses_goal),
+
         move_follow_code_select(Goals0, RttiVarMaps, FollowGoals,
             RestGoalsPrime, ConjPurity, WorstPurity),
         FollowGoals = [_ | _],
Index: compiler/introduce_parallelism.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/introduce_parallelism.m,v
retrieving revision 1.6
diff -u -b -r1.6 introduce_parallelism.m
--- compiler/introduce_parallelism.m	27 Sep 2011 04:41:25 -0000	1.6
+++ compiler/introduce_parallelism.m	24 Oct 2012 03:50:13 -0000
@@ -274,7 +274,7 @@
 
 parallelise_proc(CPCProc, PredInfo, !ProcInfo,
         IntroducedParallelism, !ModuleInfo, !Specs) :-
-    CPCProc = candidate_par_conjunctions_proc(VarTable, PushGoals,
+    CPCProc = candidate_par_conjunctions_proc(VarNameTable, PushGoals,
         CPCs0),
     (
         PushGoals = []
@@ -304,7 +304,7 @@
     % ones before earlier ones.
     list.sort_and_remove_dups(compare_candidate_par_conjunctions, CPCs0, CPCs),
     list.foldl3(
-        maybe_parallelise_goal(PredInfo, ProgRepInfo, VarTable, Instmap),
+        maybe_parallelise_goal(PredInfo, ProgRepInfo, VarNameTable, Instmap),
         CPCs, Goal0, Goal,
         have_not_introduced_parallelism, IntroducedParallelism, !Specs),
     (
@@ -319,7 +319,7 @@
 
 %-----------------------------------------------------------------------------%
 
-    % maybe_parallelise_goal(ProgRepInfo, VarTable, CPC, !Goal,
+    % maybe_parallelise_goal(ProgRepInfo, VarNameTable, CPC, !Goal,
     %   !IntroducedParallelism).
     %
     % Attempt to parallelise some part of !.Goal returning !:Goal.
@@ -327,13 +327,13 @@
     % will be unmodified.
     %
 :- pred maybe_parallelise_goal(pred_info::in, prog_rep_info::in,
-    var_table::in, instmap::in, candidate_par_conjunction::in,
+    var_name_table::in, instmap::in, candidate_par_conjunction::in,
     hlds_goal::in, hlds_goal::out,
     introduced_parallelism::in, introduced_parallelism::out,
     list(error_spec)::in, list(error_spec)::out) is det.
 
-maybe_parallelise_goal(PredInfo, ProgRepInfo, VarTable, Instmap0, CPC, Goal0,
-        Goal, !IntroducedParallelism, !Specs) :-
+maybe_parallelise_goal(PredInfo, ProgRepInfo, VarNameTable, Instmap0, CPC,
+        Goal0, Goal, !IntroducedParallelism, !Specs) :-
     TargetGoalPathString = CPC ^ cpc_goal_path,
     ( goal_path_from_string(TargetGoalPathString, TargetGoalPathPrime) ->
         TargetGoalPath = TargetGoalPathPrime
@@ -342,7 +342,7 @@
             "Invalid goal path in CPC Feedback Information")
     ),
     maybe_transform_goal_at_goal_path_with_instmap(
-        maybe_parallelise_conj(ProgRepInfo, VarTable, CPC),
+        maybe_parallelise_conj(ProgRepInfo, VarNameTable, CPC),
         TargetGoalPath, Instmap0, Goal0, MaybeGoal),
     (
         MaybeGoal = ok(Goal),
@@ -363,11 +363,11 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred maybe_parallelise_conj(prog_rep_info::in, var_table::in,
+:- pred maybe_parallelise_conj(prog_rep_info::in, var_name_table::in,
     candidate_par_conjunction::in, instmap::in, hlds_goal::in,
     maybe_error(hlds_goal)::out) is det.
 
-maybe_parallelise_conj(ProgRepInfo, VarTable, CPC, Instmap0,
+maybe_parallelise_conj(ProgRepInfo, VarNameTable, CPC, Instmap0,
         Goal0, MaybeGoal) :-
     Goal0 = hlds_goal(GoalExpr0, _GoalInfo0),
     % We have reached the point indicated by the goal path.
@@ -376,15 +376,15 @@
     (
         GoalExpr0 = conj(plain_conj, Conjs0),
         flatten_conj(Conjs0, Conjs1),
-        find_first_goal(FirstGoalRep, Conjs1, ProgRepInfo, VarTable, Instmap0,
-            found_first_goal(GoalsBefore, FirstGoal, OtherGoals))
+        find_first_goal(FirstGoalRep, Conjs1, ProgRepInfo, VarNameTable,
+            Instmap0, found_first_goal(GoalsBefore, FirstGoal, OtherGoals))
     ->
         GoalsBeforeInstDeltas = list.map(
             (func(G) = goal_info_get_instmap_delta(G ^ hlds_goal_info)),
             GoalsBefore),
         list.foldl(apply_instmap_delta_sv, GoalsBeforeInstDeltas,
             Instmap0, Instmap),
-        build_par_conjunction(ProgRepInfo, VarTable, Instmap,
+        build_par_conjunction(ProgRepInfo, VarNameTable, Instmap,
             [FirstGoal | OtherGoals], CPC, MaybeParConjunction),
         (
             MaybeParConjunction = ok(
@@ -432,21 +432,21 @@
             ).
 
 :- pred find_first_goal(pard_goal::in, list(hlds_goal)::in,
-    prog_rep_info::in, var_table::in, instmap::in,
+    prog_rep_info::in, var_name_table::in, instmap::in,
     find_first_goal_result::out) is det.
 
 find_first_goal(_, [], _, _, _, did_not_find_first_goal).
-find_first_goal(GoalRep, [Goal | Goals], ProcRepInfo, VarTable, !.Instmap,
+find_first_goal(GoalRep, [Goal | Goals], ProcRepInfo, VarNameTable, !.Instmap,
         Result) :-
     (
-        pard_goal_match_hlds_goal(ProcRepInfo, VarTable, !.Instmap, GoalRep,
-            Goal)
+        pard_goal_match_hlds_goal(ProcRepInfo, VarNameTable, !.Instmap,
+            GoalRep, Goal)
     ->
         Result = found_first_goal([], Goal, Goals)
     ;
         InstmapDelta = goal_info_get_instmap_delta(Goal ^ hlds_goal_info),
         apply_instmap_delta_sv(InstmapDelta, !Instmap),
-        find_first_goal(GoalRep, Goals, ProcRepInfo, VarTable, !.Instmap,
+        find_first_goal(GoalRep, Goals, ProcRepInfo, VarNameTable, !.Instmap,
             Result0),
         (
             Result0 = did_not_find_first_goal,
@@ -465,22 +465,22 @@
                 pcrg_remaining_goals            :: hlds_goals
             ).
 
-:- pred build_par_conjunction(prog_rep_info::in, var_table::in, instmap::in,
-    hlds_goals::in, candidate_par_conjunction::in,
+:- pred build_par_conjunction(prog_rep_info::in, var_name_table::in,
+    instmap::in, hlds_goals::in, candidate_par_conjunction::in,
     maybe_error(par_conjunction_and_remaining_goals)::out) is det.
 
-build_par_conjunction(ProcRepInfo, VarTable, Instmap0, !.Goals, CPC,
+build_par_conjunction(ProcRepInfo, VarNameTable, Instmap0, !.Goals, CPC,
         MaybeParConjunction) :-
     GoalRepsBefore = CPC ^ cpc_goals_before,
     GoalRepsAfter = CPC ^ cpc_goals_after,
     ParConjReps = CPC ^ cpc_conjs,
     some [!Instmap] (
         !:Instmap = Instmap0,
-        build_seq_conjuncts(ProcRepInfo, VarTable, GoalRepsBefore,
+        build_seq_conjuncts(ProcRepInfo, VarNameTable, GoalRepsBefore,
             MaybeGoalsBefore, !Goals, !Instmap),
-        build_par_conjuncts(ProcRepInfo, VarTable, ParConjReps,
+        build_par_conjuncts(ProcRepInfo, VarNameTable, ParConjReps,
             MaybeParConjuncts, !Goals, !Instmap),
-        build_seq_conjuncts(ProcRepInfo, VarTable, GoalRepsAfter,
+        build_seq_conjuncts(ProcRepInfo, VarNameTable, GoalRepsAfter,
             MaybeGoalsAfter, !Goals, !Instmap),
         _ = !.Instmap
     ),
@@ -512,21 +512,21 @@
             ++ "conjunction do not match those in the feedback file")
     ).
 
-:- pred build_par_conjuncts(prog_rep_info::in, var_table::in,
+:- pred build_par_conjuncts(prog_rep_info::in, var_name_table::in,
     list(seq_conj)::in, maybe(hlds_goals)::out,
     hlds_goals::in, hlds_goals::out, instmap::in, instmap::out) is det.
 
 build_par_conjuncts(_, _, [], yes([]), !Goals, !Instmap).
-build_par_conjuncts(ProcRepInfo, VarTable, [GoalRep | GoalReps], MaybeConjs,
-        !Goals, !Instmap) :-
+build_par_conjuncts(ProcRepInfo, VarNameTable, [GoalRep | GoalReps],
+        MaybeConjs, !Goals, !Instmap) :-
     GoalRep = seq_conj(SeqConjs),
-    build_seq_conjuncts(ProcRepInfo, VarTable, SeqConjs, MaybeConj, !Goals,
-        !Instmap),
+    build_seq_conjuncts(ProcRepInfo, VarNameTable, SeqConjs, MaybeConj,
+        !Goals, !Instmap),
     (
         MaybeConj = yes(Conj0),
         create_conj_from_list(Conj0, plain_conj, Conj),
-        build_par_conjuncts(ProcRepInfo, VarTable, GoalReps, MaybeConjs0,
-            !Goals, !Instmap),
+        build_par_conjuncts(ProcRepInfo, VarNameTable, GoalReps,
+            MaybeConjs0, !Goals, !Instmap),
         (
             MaybeConjs0 = yes(Conjs0),
             MaybeConjs = yes([Conj | Conjs0])
@@ -539,21 +539,23 @@
         MaybeConjs = no
     ).
 
-:- pred build_seq_conjuncts(prog_rep_info::in, var_table::in,
+:- pred build_seq_conjuncts(prog_rep_info::in, var_name_table::in,
     list(pard_goal)::in, maybe(hlds_goals)::out,
     hlds_goals::in, hlds_goals::out, instmap::in, instmap::out) is det.
 
 build_seq_conjuncts(_, _, [], yes([]), !Goals, !Instmap).
-build_seq_conjuncts(ProcRepInfo, VarTable, [GoalRep | GoalReps], MaybeConjs,
-        !Goals, !Instmap) :-
+build_seq_conjuncts(ProcRepInfo, VarNameTable, [GoalRep | GoalReps],
+        MaybeConjs, !Goals, !Instmap) :-
     (
         !.Goals = [Goal | !:Goals],
-        ( pard_goal_match_hlds_goal(ProcRepInfo, VarTable, !.Instmap, GoalRep,
-                Goal) ->
+        (
+            pard_goal_match_hlds_goal(ProcRepInfo, VarNameTable, !.Instmap,
+                GoalRep, Goal)
+        ->
             InstmapDelta = goal_info_get_instmap_delta(Goal ^ hlds_goal_info),
             apply_instmap_delta_sv(InstmapDelta, !Instmap),
-            build_seq_conjuncts(ProcRepInfo, VarTable, GoalReps, MaybeConjs0,
-                !Goals, !Instmap),
+            build_seq_conjuncts(ProcRepInfo, VarNameTable, GoalReps,
+                MaybeConjs0, !Goals, !Instmap),
             (
                 MaybeConjs0 = yes(Conjs0),
                 MaybeConjs = yes([Goal | Conjs0])
@@ -661,50 +663,51 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred pard_goal_match_hlds_goal(prog_rep_info::in, var_table::in,
+:- pred pard_goal_match_hlds_goal(prog_rep_info::in, var_name_table::in,
     instmap::in, pard_goal::in, hlds_goal::in) is semidet.
 
-pard_goal_match_hlds_goal(ProgRepInfo, VarTable, Instmap, GoalRepA, GoalB) :-
+pard_goal_match_hlds_goal(ProgRepInfo, VarNameTable, Instmap,
+        GoalRepA, GoalB) :-
     goal_to_goal_rep(ProgRepInfo, Instmap, GoalB, GoalRepB),
-    goal_reps_match(VarTable, GoalRepA, GoalRepB).
+    goal_reps_match(VarNameTable, GoalRepA, GoalRepB).
 
-:- pred goal_reps_match(var_table::in, goal_rep(A)::in, goal_rep(B)::in)
+:- pred goal_reps_match(var_name_table::in, goal_rep(A)::in, goal_rep(B)::in)
     is semidet.
 
-goal_reps_match(VarTable, GoalA, GoalB) :-
+goal_reps_match(VarNameTable, GoalA, GoalB) :-
     GoalA = goal_rep(GoalRepA, Detism, _),
     GoalB = goal_rep(GoalRepB, Detism, _),
     (
         GoalRepA = conj_rep(ConjsA),
         GoalRepB = conj_rep(ConjsB),
-        zip_all_true(goal_reps_match(VarTable), ConjsA, ConjsB)
+        zip_all_true(goal_reps_match(VarNameTable), ConjsA, ConjsB)
     ;
         GoalRepA = disj_rep(DisjsA),
         GoalRepB = disj_rep(DisjsB),
-        zip_all_true(goal_reps_match(VarTable), DisjsA, DisjsB)
+        zip_all_true(goal_reps_match(VarNameTable), DisjsA, DisjsB)
     ;
         GoalRepA = switch_rep(VarRepA, CanFail, CasesA),
         GoalRepB = switch_rep(VarRepB, CanFail, CasesB),
-        var_reps_match(VarTable, VarRepA, VarRepB),
+        var_reps_match(VarNameTable, VarRepA, VarRepB),
         % Note that GoalRepA and GoalRepB could be equivalent
         % even they contained the same cases but a different order.
         list.sort(CasesA, SortedCasesA),
         list.sort(CasesB, SortedCasesB),
-        zip_all_true(case_reps_match(VarTable), SortedCasesA, SortedCasesB)
+        zip_all_true(case_reps_match(VarNameTable), SortedCasesA, SortedCasesB)
     ;
         GoalRepA = ite_rep(CondA, ThenA, ElseA),
         GoalRepB = ite_rep(CondB, ThenB, ElseB),
-        goal_reps_match(VarTable, CondA, CondB),
-        goal_reps_match(VarTable, ThenA, ThenB),
-        goal_reps_match(VarTable, ElseA, ElseB)
+        goal_reps_match(VarNameTable, CondA, CondB),
+        goal_reps_match(VarNameTable, ThenA, ThenB),
+        goal_reps_match(VarNameTable, ElseA, ElseB)
     ;
         GoalRepA = negation_rep(SubGoalA),
         GoalRepB = negation_rep(SubGoalB),
-        goal_reps_match(VarTable, SubGoalA, SubGoalB)
+        goal_reps_match(VarNameTable, SubGoalA, SubGoalB)
     ;
         GoalRepA = scope_rep(SubGoalA, MaybeCut),
         GoalRepB = scope_rep(SubGoalB, MaybeCut),
-        goal_reps_match(VarTable, SubGoalA, SubGoalB)
+        goal_reps_match(VarNameTable, SubGoalA, SubGoalB)
     ;
         GoalRepA = atomic_goal_rep(_, _, _, AtomicGoalA),
         GoalRepB = atomic_goal_rep(_, _, _, AtomicGoalB),
@@ -714,13 +717,13 @@
         %
         % Vars are not matched here either, we only consider the vars
         % within the atomic_goal_rep structures.
-        atomic_goal_reps_match(VarTable, AtomicGoalA, AtomicGoalB)
+        atomic_goal_reps_match(VarNameTable, AtomicGoalA, AtomicGoalB)
     ).
 
-:- pred atomic_goal_reps_match(var_table::in,
+:- pred atomic_goal_reps_match(var_name_table::in,
     atomic_goal_rep::in, atomic_goal_rep::in) is semidet.
 
-atomic_goal_reps_match(VarTable, AtomicRepA, AtomicRepB) :-
+atomic_goal_reps_match(VarNameTable, AtomicRepA, AtomicRepB) :-
     (
         (
             AtomicRepA = unify_construct_rep(VarA, ConsId, ArgsA),
@@ -735,8 +738,8 @@
             AtomicRepA = method_call_rep(VarA, MethodNum, ArgsA),
             AtomicRepB = method_call_rep(VarB, MethodNum, ArgsB)
         ),
-        var_reps_match(VarTable, VarA, VarB),
-        zip_all_true(var_reps_match(VarTable), ArgsA, ArgsB)
+        var_reps_match(VarNameTable, VarA, VarB),
+        zip_all_true(var_reps_match(VarNameTable), ArgsA, ArgsB)
     ;
         (
             AtomicRepA = partial_deconstruct_rep(VarA, ConsId, MaybeArgsA),
@@ -745,8 +748,9 @@
             AtomicRepA = partial_construct_rep(VarA, ConsId, MaybeArgsA),
             AtomicRepB = partial_construct_rep(VarB, ConsId, MaybeArgsB)
         ),
-        var_reps_match(VarTable, VarA, VarB),
-        zip_all_true(maybe_var_reps_match(VarTable), MaybeArgsA, MaybeArgsB)
+        var_reps_match(VarNameTable, VarA, VarB),
+        zip_all_true(maybe_var_reps_match(VarNameTable),
+            MaybeArgsA, MaybeArgsB)
     ;
         (
             AtomicRepA = unify_assign_rep(VarA1, VarA2),
@@ -758,8 +762,8 @@
             AtomicRepA = unify_simple_test_rep(VarA1, VarA2),
             AtomicRepB = unify_simple_test_rep(VarB1, VarB2)
         ),
-        var_reps_match(VarTable, VarA1, VarB1),
-        var_reps_match(VarTable, VarA2, VarB2)
+        var_reps_match(VarNameTable, VarA1, VarB1),
+        var_reps_match(VarNameTable, VarA2, VarB2)
     ;
         (
             AtomicRepA = pragma_foreign_code_rep(ArgsA),
@@ -774,21 +778,22 @@
             AtomicRepA = event_call_rep(EventName, ArgsA),
             AtomicRepB = event_call_rep(EventName, ArgsB)
         ),
-        zip_all_true(var_reps_match(VarTable), ArgsA, ArgsB)
+        zip_all_true(var_reps_match(VarNameTable), ArgsA, ArgsB)
     ).
 
-:- pred case_reps_match(var_table::in, case_rep(A)::in, case_rep(B)::in)
+:- pred case_reps_match(var_name_table::in, case_rep(A)::in, case_rep(B)::in)
     is semidet.
 
-case_reps_match(VarTable, CaseRepA, CaseRepB) :-
+case_reps_match(VarNameTable, CaseRepA, CaseRepB) :-
     CaseRepA = case_rep(ConsId, OtherConsIds, GoalRepA),
     CaseRepB = case_rep(ConsId, OtherConsIds, GoalRepB),
-    goal_reps_match(VarTable, GoalRepA, GoalRepB).
+    goal_reps_match(VarNameTable, GoalRepA, GoalRepB).
 
-:- pred var_reps_match(var_table::in, var_rep::in, var_rep::in) is semidet.
+:- pred var_reps_match(var_name_table::in, var_rep::in, var_rep::in)
+    is semidet.
 
-var_reps_match(VarTable, VarA, VarB) :-
-    ( search_var_name(VarTable, VarA, _) ->
+var_reps_match(VarNameTable, VarA, VarB) :-
+    ( search_var_name(VarNameTable, VarA, _) ->
         % Variables named by the programmer _must_ match, we expect to find
         % them in the var table, and that they would be identical.  (Since one
         % of the variables will be built using its name and the var table
@@ -797,16 +802,17 @@
     ;
         % Unnamed variables match implicitly. They will usually be identical,
         % but we do not REQUIRE them to be identical, to allow the program
-        % to change a little after being profiled but before being parallelised.
+        % to change a little after being profiled but before being
+        % parallelised.
         true
     ).
 
-:- pred maybe_var_reps_match(var_table::in,
+:- pred maybe_var_reps_match(var_name_table::in,
     maybe(var_rep)::in, maybe(var_rep)::in) is semidet.
 
 maybe_var_reps_match(_, no, no).
-maybe_var_reps_match(VarTable, yes(VarA), yes(VarB)) :-
-    var_reps_match(VarTable, VarA, VarB).
+maybe_var_reps_match(VarNameTable, yes(VarA), yes(VarB)) :-
+    var_reps_match(VarNameTable, VarA, VarB).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout.m,v
retrieving revision 1.46
diff -u -b -r1.46 layout.m
--- compiler/layout.m	11 Jun 2012 03:13:21 -0000	1.46
+++ compiler/layout.m	24 Oct 2012 03:50:13 -0000
@@ -235,8 +235,8 @@
                 % The procedure body represented as a list of bytecodes.
                 proc_body_bytes         :: maybe(layout_slot_name),
 
-                % The name of the module_common_layout structure.
-                proc_module_common      :: layout_name
+                % The name of the module_layout structure.
+                proc_module_layout      :: layout_name
             ).
 
 :- type proc_layout_data
@@ -275,16 +275,31 @@
             ).
 
 :- type module_layout_data
-    --->    module_layout_common_data(
-                % defines MR_ModuleCommonLayout
-                mlcd_module_common_name     :: module_name,
-                mlcd_string_table_size      :: int,
-                mlcd_string_table           :: string_with_0s
-            )
-    ;       module_layout_data(
-                % defines MR_ModuleLayout
+    --->    module_layout_data(
+                % The part of MR_ModuleLayout that is needed for both
+                % deep profiling and debugging.
                 mld_module_name             :: module_name,
-                mld_module_common           :: layout_name,
+                mld_string_table_size       :: int,
+                mld_string_table            :: string_with_0s,
+
+                % The parts that are specific to deep profiling and to
+                % debugging.
+                mld_maybe_deep_prof         :: maybe(module_layout_deep_prof),
+                mld_maybe_debug             :: maybe(module_layout_debug)
+            ).
+
+:- type module_layout_deep_prof
+    --->    module_layout_deep_prof(
+                % Defines part of MR_ModuleLayout.
+                mldp_num_oisu_types         :: int,
+                mldp_oisu_bytes             :: list(int),
+                mldp_num_table_types        :: int,
+                mldp_type_table_bytes       :: list(int)
+            ).
+
+:- type module_layout_debug
+    --->    module_layout_debug(
+                % Defines part of MR_ModuleLayout.
                 mld_proc_layout_names       :: list(layout_name),
                 mld_file_layouts            :: list(file_layout_data),
                 mld_trace_level             :: trace_level,
@@ -295,7 +310,7 @@
 
 %-----------------------------------------------------------------------------%
 %
-% Allocation site information
+% Allocation site information.
 %
 
 :- type alloc_site_info
@@ -397,7 +412,8 @@
     ;       module_layout_event_synth_attr_order(module_name, int, int)
     ;       module_layout_event_synth_order(module_name, int)
     ;       module_layout_event_specs(module_name)
-    ;       module_common_layout(module_name)
+    ;       module_layout_oisu_bytes(module_name)
+    ;       module_layout_type_table_bytes(module_name)
     ;       module_layout(module_name).
 
 %-----------------------------------------------------------------------------%
Index: compiler/layout_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout_out.m,v
retrieving revision 1.126
diff -u -b -r1.126 layout_out.m
--- compiler/layout_out.m	20 Oct 2011 13:44:31 -0000	1.126
+++ compiler/layout_out.m	24 Oct 2012 03:50:13 -0000
@@ -99,10 +99,9 @@
     ;       being_defined.
 
     % Given a reference to a layout structure, output the storage class
-    % (e.g. static), type and name of the global variable that will
-    % hold it. The second arg says whether the output is part of the definition
-    % of that variable (this influences e.g. whether we output "extern"
-    % or not).
+    % (e.g. static), type and name of the global variable that will hold it.
+    % The second arg says whether the output is part of the definition of that
+    % variable; this influences e.g. whether we output "extern" or not.
     %
 :- pred output_layout_name_storage_type_name(layout_name::in,
     being_defined::in, io::di, io::uo) is det.
@@ -110,8 +109,8 @@
     % Given a mangled module name and a reference to a layout array, output
     % the storage class (e.g. static), type and name of the global variable
     % that will hold it. The bool says whether the output is part of the
-    % definition of that variable (this influences e.g. whether we output
-    % "extern" or not).
+    % definition of that variable; this influences e.g. whether we output
+    % "extern" or not.
     %
 :- pred output_layout_array_name_storage_type_name(string::in,
     layout_array_name::in, being_defined::in, io::di, io::uo) is det.
@@ -189,6 +188,7 @@
 :- import_module map.
 :- import_module pair.
 :- import_module require.
+:- import_module std_util.
 :- import_module string.
 :- import_module term.
 :- import_module varset.
@@ -1969,9 +1969,15 @@
         ModuleNameStr = sym_name_mangle(ModuleName),
         io.write_string(ModuleNameStr, !IO)
     ;
-        Name = module_common_layout(ModuleName),
+        Name = module_layout_oisu_bytes(ModuleName),
         io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_module_common_layout__", !IO),
+        io.write_string("_module_layout_oisu_bytes__", !IO),
+        ModuleNameStr = sym_name_mangle(ModuleName),
+        io.write_string(ModuleNameStr, !IO)
+    ;
+        Name = module_layout_type_table_bytes(ModuleName),
+        io.write_string(mercury_data_prefix, !IO),
+        io.write_string("_module_layout_type_table_bytes__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
         io.write_string(ModuleNameStr, !IO)
     ;
@@ -2209,9 +2215,15 @@
         output_layout_name(Name, !IO),
         io.write_string("[]", !IO)
     ;
-        Name = module_common_layout(_ModuleName),
-        io.write_string("static const MR_ModuleCommonLayout ", !IO),
-        output_layout_name(Name, !IO)
+        Name = module_layout_oisu_bytes(_ModuleName),
+        io.write_string("static const MR_uint_least8_t ", !IO),
+        output_layout_name(Name, !IO),
+        io.write_string("[]", !IO)
+    ;
+        Name = module_layout_type_table_bytes(_ModuleName),
+        io.write_string("static const MR_uint_least8_t ", !IO),
+        output_layout_name(Name, !IO),
+        io.write_string("[]", !IO)
     ;
         Name = module_layout(_ModuleName),
         io.write_string("static const MR_ModuleLayout ", !IO),
@@ -2236,7 +2248,8 @@
         ; LayoutName = module_layout_event_synth_attr_order(_, _, _)
         ; LayoutName = module_layout_event_synth_order(_, _)
         ; LayoutName = module_layout_event_specs(_)
-        ; LayoutName = module_common_layout(_)
+        ; LayoutName = module_layout_oisu_bytes(_)
+        ; LayoutName = module_layout_type_table_bytes(_)
         ; LayoutName = module_layout(_)
         ),
         InclCodeAddr = no
@@ -2303,9 +2316,9 @@
         MaybeRest = no_proc_id_and_more,
         Kind = proc_layout_traversal
     ;
-        MaybeRest = proc_id_and_more(_, _, _, ModuleCommonLayoutDecl),
+        MaybeRest = proc_id_and_more(_, _, _, ModuleLayoutDecl),
         Kind = proc_layout_proc_id(proc_label_user_or_uci(ProcLabel)),
-        output_layout_decl(ModuleCommonLayoutDecl, !DeclSet, !IO)
+        output_layout_decl(ModuleLayoutDecl, !DeclSet, !IO)
     ),
 
     io.write_string("\n", !IO),
@@ -2343,7 +2356,7 @@
         io.write_string("-1\n", !IO)
     ;
         MaybeRest = proc_id_and_more(MaybeProcStatic, MaybeExecTrace,
-            MaybeProcBodyBytes, ModuleCommonLayout),
+            MaybeProcBodyBytes, ModuleLayout),
 
         % Output the proc_id structure.
         io.write_string("{\n", !IO),
@@ -2380,9 +2393,9 @@
             io.write_string(",\n", !IO)
         ),
         io.write_string("&", !IO),
-        output_layout_name(ModuleCommonLayout, !IO)
+        output_layout_name(ModuleLayout, !IO)
     ),
-    io.write_string("};\n", !IO),
+    io.write_string("\n};\n", !IO),
     DeclId = decl_layout_id(ProcLayoutName),
     decl_set_insert(DeclId, !DeclSet).
 
@@ -2599,21 +2612,6 @@
 
 %-----------------------------------------------------------------------------%
 
-output_module_layout_data_defn(Info, Data, !DeclSet, !IO) :-
-    (
-        Data = module_layout_common_data(ModuleName,
-            StringTableSize, StringTable),
-        output_module_common_layout_data_defn(ModuleName, StringTableSize,
-            StringTable, !DeclSet, !IO)
-    ;
-        Data = module_layout_data(ModuleName, ModuleCommonLayoutName,
-            ProcLayoutNames, FileLayouts, TraceLevel,
-            SuppressedEvents, NumLabels, MaybeEventSet),
-        output_module_layout_data_defn(Info, ModuleName,
-            ModuleCommonLayoutName, ProcLayoutNames, FileLayouts, TraceLevel,
-            SuppressedEvents, NumLabels, MaybeEventSet, !DeclSet, !IO)
-    ).
-
     % The version of the layout data structures -- useful for bootstrapping.
     % If you write runtime code that checks this version number and can
     % at least handle the previous version of the data structure,
@@ -2627,130 +2625,212 @@
     %
 :- func layout_version_number = int.
 
-layout_version_number = 4.
+layout_version_number = 5.
 
-:- pred output_module_common_layout_data_defn(module_name::in, int::in,
-    string_with_0s::in, decl_set::in, decl_set::out, io::di, io::uo) is det.
+output_module_layout_data_defn(Info, Data, !DeclSet, !IO) :-
+    Data = module_layout_data(ModuleName, StringTableSize, StringTable,
+        MaybeDeepProfData, MaybeDebugData),
 
-output_module_common_layout_data_defn(ModuleName, StringTableSize, StringTable,
-        !DeclSet, !IO) :-
     output_module_string_table(ModuleName, StringTableSize, StringTable,
         !DeclSet, !IO),
 
-    ModuleCommonLayoutName = module_common_layout(ModuleName),
+    (
+        MaybeDeepProfData = yes(DeepProfData),
+        DeepProfData = module_layout_deep_prof(NumOISUTypesA, OISUBytes,
+            NumTypesA, TypeTableBytes),
+        ( NumOISUTypesA = 0 ->
+            MaybeOISUBytesLayoutNameA = no
+        ;
+            OISUBytesLayoutNameA = module_layout_oisu_bytes(ModuleName),
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(ModuleCommonLayoutName,
+            output_layout_name_storage_type_name(OISUBytesLayoutNameA,
         being_defined, !IO),
-    io.write_string(" = {\n", !IO),
-    io.write_int(layout_version_number, !IO),
-    io.write_string(",\n", !IO),
-    quote_and_write_string(sym_name_to_string(ModuleName), !IO),
-    io.write_string(",\n", !IO),
-    io.write_int(StringTableSize, !IO),
-    io.write_string(",\n", !IO),
-    ModuleStringTableName = module_layout_string_table(ModuleName),
-    output_layout_name(ModuleStringTableName, !IO),
-    io.write_string("\n};\n", !IO),
-
-    decl_set_insert(decl_layout_id(ModuleCommonLayoutName), !DeclSet).
+            io.write_string(" = {", !IO),
+            output_bytecodes_driver(OISUBytes, !IO),
+            io.write_string("};\n", !IO),
+            decl_set_insert(decl_layout_id(OISUBytesLayoutNameA), !DeclSet),
+            MaybeOISUBytesLayoutNameA = yes(OISUBytesLayoutNameA)
+        ),
+        (
+            TypeTableBytes = [],
+            MaybeTypeTableLayoutNameA = no
+        ;
+            TypeTableBytes = [_ | _],
+            TypeTableLayoutNameA = module_layout_type_table_bytes(ModuleName),
+            io.write_string("\n", !IO),
+            output_layout_name_storage_type_name(TypeTableLayoutNameA,
+                being_defined, !IO),
+            io.write_string(" = {", !IO),
+            output_bytecodes_driver(TypeTableBytes, !IO),
+            io.write_string("};\n", !IO),
+            decl_set_insert(decl_layout_id(TypeTableLayoutNameA), !DeclSet),
+            MaybeTypeTableLayoutNameA = yes(TypeTableLayoutNameA)
+        ),
+        OISUInfo = {NumOISUTypesA, MaybeOISUBytesLayoutNameA,
+            NumTypesA, MaybeTypeTableLayoutNameA}
+    ;
+        MaybeDeepProfData = no,
+        OISUInfo = {0, no, 0, no}
+    ),
 
-:- pred output_module_layout_data_defn(llds_out_info::in,
-    module_name::in, layout_name::in, list(layout_name)::in,
-    list(file_layout_data)::in, trace_level::in, int::in, int::in,
-    maybe(event_set_layout_data)::in,
-    decl_set::in, decl_set::out, io::di, io::uo) is det.
+    (
+        MaybeDebugData = yes(DebugData),
+        DebugData = module_layout_debug(ProcLayoutNames, FileLayouts,
+            TraceLevelA, SuppressedEventsA, NumLabelsA, MaybeEventSetA),
 
-output_module_layout_data_defn(Info, ModuleName,
-        ModuleCommonLayoutName, ProcLayoutNames, FileLayouts, TraceLevel,
-        SuppressedEvents, NumLabels, MaybeEventSetLayout, !DeclSet, !IO) :-
-    output_layout_decl(module_common_layout(ModuleName), !DeclSet, !IO),
     output_module_layout_proc_vector_defn(ModuleName, ProcLayoutNames,
-        ProcVectorName, !DeclSet, !IO),
+            ProcLayoutVectorNameA, !DeclSet, !IO),
+        list.length(ProcLayoutNames, ProcLayoutVectorLengthA),
     output_file_layout_data_defns(Info, ModuleName,
         0, FileLayouts, FileLayoutNames, !DeclSet, !IO),
+        list.length(FileLayouts, FileLayoutVectorLengthA),
     output_file_layout_vector_data_defn(ModuleName, FileLayoutNames,
-        FileVectorName, !DeclSet, !IO),
+            FileLayoutVectorNameA, !DeclSet, !IO),
 
     io.write_string("\n", !IO),
-    LabelExecCountName = module_layout_label_exec_count(ModuleName,
-        NumLabels),
-    output_layout_name_storage_type_name(LabelExecCountName,
+        LabelExecCountNameA = module_layout_label_exec_count(ModuleName,
+            NumLabelsA),
+        output_layout_name_storage_type_name(LabelExecCountNameA,
         being_defined, !IO),
     io.write_string(";\n", !IO),
-    decl_set_insert(decl_layout_id(LabelExecCountName), !DeclSet),
+        decl_set_insert(decl_layout_id(LabelExecCountNameA), !DeclSet),
 
     (
-        MaybeEventSetLayout = no
+            MaybeEventSetA = no,
+            MaybeEventInfoA = no
     ;
-        MaybeEventSetLayout = yes(EventSetDataLayout),
+            MaybeEventSetA = yes(EventSetDataLayout),
         EventSetDataLayout =
             event_set_layout_data(EventSetDataA, TypesRvalMap),
-        EventSetDataA = event_set_data(_EventSetName, EventSetDesc,
-            EventSpecsA, _MaxNumAttr),
-        output_event_set_desc_defn(ModuleName, EventSetDesc, !DeclSet, !IO),
-        output_event_specs_and_components(Info, EventSpecsA, ModuleName,
-            TypesRvalMap, !DeclSet, !IO)
+            EventSetDataA = event_set_data(EventSetNameA, EventSetDesc,
+                EventSpecs, MaxNumAttrA),
+            output_event_set_desc_defn(ModuleName, EventSetDesc,
+                EventSetDescLayoutNameA, !DeclSet, !IO),
+            output_event_specs_and_components(Info, EventSpecs, ModuleName,
+                TypesRvalMap, EventSpecsLayoutNameA, !DeclSet, !IO),
+            list.length(EventSpecs, NumEventSpecsA),
+            MaybeEventInfoA = yes({EventSetNameA, MaxNumAttrA, NumEventSpecsA,
+                EventSetDescLayoutNameA, EventSpecsLayoutNameA})
+        ),
+
+        MaybeDebugInfo = yes({ProcLayoutVectorLengthA, ProcLayoutVectorNameA,
+            FileLayoutVectorLengthA, FileLayoutVectorNameA,
+            TraceLevelA, SuppressedEventsA, NumLabelsA, LabelExecCountNameA,
+            MaybeEventInfoA})
+    ;
+        MaybeDebugData = no,
+        MaybeDebugInfo = no
     ),
 
     ModuleLayoutName = module_layout(ModuleName),
     io.write_string("\n", !IO),
     output_layout_name_storage_type_name(ModuleLayoutName, being_defined, !IO),
     io.write_string(" = {\n", !IO),
-    io.write_string("&", !IO),
-    output_layout_name(ModuleCommonLayoutName, !IO),
+    io.write_int(layout_version_number, !IO),
     io.write_string(",\n", !IO),
-    list.length(ProcLayoutNames, ProcLayoutVectorLength),
-    io.write_int(ProcLayoutVectorLength, !IO),
+    quote_and_write_string(sym_name_to_string(ModuleName), !IO),
     io.write_string(",\n", !IO),
-    output_layout_name(ProcVectorName, !IO),
+    io.write_int(StringTableSize, !IO),
     io.write_string(",\n", !IO),
-    list.length(FileLayouts, FileLayoutVectorLength),
-    io.write_int(FileLayoutVectorLength, !IO),
+    ModuleStringTableName = module_layout_string_table(ModuleName),
+    output_layout_name(ModuleStringTableName, !IO),
     io.write_string(",\n", !IO),
-    output_layout_name(FileVectorName, !IO),
+
+    OISUInfo = {NumOISUTypesB, MaybeOISUBytesLayoutNameB,
+        NumTypesB, MaybeTypeTableLayoutNameB},
+    io.write_int(NumOISUTypesB, !IO),
     io.write_string(",\n", !IO),
-    io.write_string(trace_level_rep(TraceLevel), !IO),
+    (
+        MaybeOISUBytesLayoutNameB = yes(OISUBytesLayoutNameB),
+        output_layout_name(OISUBytesLayoutNameB, !IO),
+        io.write_string(",\n", !IO)
+    ;
+        MaybeOISUBytesLayoutNameB = no,
+        io.write_string("NULL,\n", !IO)
+    ),
+    io.write_int(NumTypesB, !IO),
     io.write_string(",\n", !IO),
-    io.write_int(SuppressedEvents, !IO),
+    (
+        MaybeTypeTableLayoutNameB = yes(TypeTableLayoutNameB),
+        output_layout_name(TypeTableLayoutNameB, !IO),
+        io.write_string(",\n", !IO)
+    ;
+        MaybeTypeTableLayoutNameB = no,
+        io.write_string("NULL,\n", !IO)
+    ),
+
+    (
+        MaybeDebugInfo = yes({ProcLayoutVectorLengthB, ProcLayoutVectorNameB,
+            FileLayoutVectorLengthB, FileLayoutVectorNameB,
+            TraceLevelB, SuppressedEventsB, NumLabelsB, LabelExecCountNameB,
+            MaybeEventInfoB}),
+
+        io.write_int(ProcLayoutVectorLengthB, !IO),
+        io.write_string(",\n", !IO),
+        output_layout_name(ProcLayoutVectorNameB, !IO),
+        io.write_string(",\n", !IO),
+        io.write_int(FileLayoutVectorLengthB, !IO),
+        io.write_string(",\n", !IO),
+        output_layout_name(FileLayoutVectorNameB, !IO),
     io.write_string(",\n", !IO),
-    io.write_int(NumLabels, !IO),
+        io.write_string(trace_level_rep(TraceLevelB), !IO),
     io.write_string(",\n", !IO),
-    output_layout_name(LabelExecCountName, !IO),
+        io.write_int(SuppressedEventsB, !IO),
     io.write_string(",\n", !IO),
+        io.write_int(NumLabelsB, !IO),
+        io.write_string(",\n", !IO),
+        output_layout_name(LabelExecCountNameB, !IO),
+        io.write_string(",\n", !IO),
+
     (
-        MaybeEventSetLayout = no,
+            MaybeEventInfoB = no,
         io.write_string("NULL,\n", !IO),
         io.write_string("NULL,\n", !IO),
         io.write_string("0,\n", !IO),
         io.write_string("0,\n", !IO),
-        io.write_string("NULL", !IO)
+            io.write_string("NULL\n", !IO)
     ;
-        MaybeEventSetLayout = yes(EventSetDataLayoutB),
-        EventSetDataLayoutB =
-            event_set_layout_data(EventSetDataB, _TypesRvalMap),
-        EventSetDataB = event_set_data(EventSetName, _EventSetDesc,
-            EventSpecsB, MaxNumAttr),
-        quote_and_write_string(EventSetName, !IO),
-        io.write_string(",\n", !IO),
-        EventSetDescLayoutName = module_layout_event_set_desc(ModuleName),
-        output_layout_name(EventSetDescLayoutName, !IO),
+            MaybeEventInfoB = yes({EventSetNameB, MaxNumAttrB, NumEventSpecsB,
+                EventSetDescLayoutNameB, EventSpecsLayoutNameB}),
+            quote_and_write_string(EventSetNameB, !IO),
+            io.write_string(",\n", !IO),
+            output_layout_name(EventSetDescLayoutNameB, !IO),
         io.write_string(",\n", !IO),
-        io.write_int(MaxNumAttr, !IO),
+            io.write_int(MaxNumAttrB, !IO),
         io.write_string(",\n", !IO),
-        io.write_int(list.length(EventSpecsB), !IO),
+            io.write_int(NumEventSpecsB, !IO),
         io.write_string(",\n", !IO),
-        EventSpecLayoutName = module_layout_event_specs(ModuleName),
-        output_layout_name(EventSpecLayoutName, !IO)
+            output_layout_name(EventSpecsLayoutNameB, !IO),
+            io.write_string("\n", !IO)
+        )
+    ;
+        MaybeDebugInfo = no,
+
+        io.write_string("0,\n", !IO),
+        io.write_string("NULL,\n", !IO),
+        io.write_string("0,\n", !IO),
+        io.write_string("NULL,\n", !IO),
+        io.write_string("MR_TRACE_LEVEL_NONE,\n", !IO),
+        io.write_string("0,\n", !IO),
+        io.write_string("0,\n", !IO),
+        io.write_string("NULL,\n", !IO),
+
+        io.write_string("NULL,\n", !IO),
+        io.write_string("NULL,\n", !IO),
+        io.write_string("0,\n", !IO),
+        io.write_string("0,\n", !IO),
+        io.write_string("NULL\n", !IO)
     ),
-    io.write_string("\n};\n", !IO),
+
+    io.write_string("};\n", !IO),
     decl_set_insert(decl_layout_id(ModuleLayoutName), !DeclSet).
 
 :- pred output_event_specs_and_components(llds_out_info::in,
     list(event_spec)::in, module_name::in, map(int, rval)::in,
-    decl_set::in, decl_set::out, io::di, io::uo) is det.
+    layout_name::out, decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_event_specs_and_components(Info, EventSpecs, ModuleName, TypesRvalMap,
-        !DeclSet, !IO) :-
+        LayoutName, !DeclSet, !IO) :-
     list.foldl2(output_event_spec_components(ModuleName), EventSpecs,
         !DeclSet, !IO),
 
@@ -2952,9 +3032,10 @@
 %-----------------------------------------------------------------------------%
 
 :- pred output_event_set_desc_defn(module_name::in, string::in,
-    decl_set::in, decl_set::out, io::di, io::uo) is det.
+    layout_name::out, decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_event_set_desc_defn(ModuleName, EventSetDesc, !DeclSet, !IO) :-
+output_event_set_desc_defn(ModuleName, EventSetDesc, LayoutName,
+        !DeclSet, !IO) :-
     LayoutName = module_layout_event_set_desc(ModuleName),
     io.write_string("\n", !IO),
     output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
Index: compiler/ll_backend.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ll_backend.m,v
retrieving revision 1.23
diff -u -b -r1.23 ll_backend.m
--- compiler/ll_backend.m	4 Nov 2009 03:44:48 -0000	1.23
+++ compiler/ll_backend.m	24 Oct 2012 03:50:13 -0000
@@ -67,6 +67,7 @@
    :- include_module layout.
    :- include_module stack_layout.
    :- include_module prog_rep.
+   :- include_module prog_rep_tables.
    :- include_module global_data.
 %:- end_module llds_data.
 
Index: compiler/llds_out_file.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds_out_file.m,v
retrieving revision 1.9
diff -u -b -r1.9 llds_out_file.m
--- compiler/llds_out_file.m	16 Aug 2011 03:26:31 -0000	1.9
+++ compiler/llds_out_file.m	24 Oct 2012 03:50:13 -0000
@@ -389,14 +389,13 @@
     io.write_string(
         "write_out_proc_statics(FILE *deep_fp, FILE *procrep_fp)\n", !IO),
     io.write_string("{\n", !IO),
-    ModuleCommonLayoutName = module_common_layout(ModuleName),
     io.write_string("\tMR_write_out_module_proc_reps_start(procrep_fp, &",
         !IO),
-    output_layout_name(ModuleCommonLayoutName, !IO),
+    ModuleLayoutName = module_layout(ModuleName),
+    output_layout_name(ModuleLayoutName, !IO),
     io.write_string(");\n", !IO),
     output_write_proc_static_list(ProcLayoutDatas, !IO),
-    io.write_string("\tMR_write_out_module_proc_reps_end(procrep_fp);\n",
-        !IO),
+    io.write_string("\tMR_write_out_module_proc_reps_end(procrep_fp);\n", !IO),
     io.write_string("}\n", !IO),
     io.write_string("\n#endif\n\n", !IO),
 
@@ -597,15 +596,12 @@
 
 output_debugger_init_list([], !IO).
 output_debugger_init_list([Data | Datas], !IO) :-
-    ( Data = module_layout_data(ModuleName, _, _, _, _, _, _, _) ->
+    Data = module_layout_data(ModuleName, _, _, _, _),
         io.write_string("\tif (MR_register_module_layout != NULL) {\n", !IO),
         io.write_string("\t\t(*MR_register_module_layout)(", !IO),
         io.write_string("\n\t\t\t&", !IO),
         output_layout_name(module_layout(ModuleName), !IO),
-        io.write_string(");\n\t}\n", !IO)
-    ;
-        true
-    ),
+    io.write_string(");\n\t}\n", !IO),
     output_debugger_init_list(Datas, !IO).
 
 :- pred output_write_proc_static_list(list(proc_layout_data)::in,
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.227
diff -u -b -r1.227 opt_debug.m
--- compiler/opt_debug.m	18 Oct 2011 06:27:08 -0000	1.227
+++ compiler/opt_debug.m	24 Oct 2012 03:50:13 -0000
@@ -642,8 +642,10 @@
 dump_layout_name(module_layout_event_synth_order(ModuleName, EventNum)) =
     "module_layout_event_synth_order(" ++ sym_name_mangle(ModuleName) ++
         ", " ++ int_to_string(EventNum) ++ ")".
-dump_layout_name(module_common_layout(ModuleName)) =
-    "module_common_layout(" ++ sym_name_mangle(ModuleName) ++ ")".
+dump_layout_name(module_layout_oisu_bytes(ModuleName)) =
+    "module_layout_oisu_bytes(" ++ sym_name_mangle(ModuleName) ++ ")".
+dump_layout_name(module_layout_type_table_bytes(ModuleName)) =
+    "module_layout_type_table_bytes(" ++ sym_name_mangle(ModuleName) ++ ")".
 dump_layout_name(module_layout(ModuleName)) =
     "module_layout(" ++ sym_name_mangle(ModuleName) ++ ")".
 
Index: compiler/proc_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/proc_gen.m,v
retrieving revision 1.54
diff -u -b -r1.54 proc_gen.m
--- compiler/proc_gen.m	8 Jun 2012 15:37:00 -0000	1.54
+++ compiler/proc_gen.m	24 Oct 2012 03:50:13 -0000
@@ -495,12 +495,13 @@
                 MaybeTableInfo = yes(proc_table_io_decl(TableIOInfo))
             )
         ),
+        proc_info_get_oisu_kind_fors(ProcInfo, OISUKindFors),
         ProcLayout = proc_layout_info(RttiProcLabel, EntryLabel,
             Detism, TotalSlots, MaybeSuccipSlot, EvalMethod,
             EffTraceLevel, MaybeTraceCallLabel, MaxTraceRegR, MaxTraceRegF,
             HeadVars, ArgModes, Goal, NeedGoalRep, InstMap0,
             TraceSlotInfo, ForceProcId, VarSet, VarTypes,
-            InternalMap, MaybeTableInfo, NeedsAllNames,
+            InternalMap, MaybeTableInfo, NeedsAllNames, OISUKindFors,
             MaybeDeepProfInfo),
         global_data_add_new_proc_layout(proc(PredId, ProcId), ProcLayout,
             !GlobalData)
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.246
diff -u -b -r1.246 prog_data.m
--- compiler/prog_data.m	10 Sep 2012 13:33:07 -0000	1.246
+++ compiler/prog_data.m	24 Oct 2012 03:50:13 -0000
@@ -1897,8 +1897,8 @@
 
     ;       apply_n_type(tvar, list(mer_type), kind)
             % An apply/N expression.  `apply_n(V, [T1, ...], K)'
-            % would be the representation of type `V(T1, ...)'
-            % with kind K.  The list must be non-empty.
+            % would be the representation of type `V(T1, ...)' with kind K.
+            % The list must be non-empty.
 
     ;       kinded_type(mer_type, kind).
             % A type expression with an explicit kind annotation.
@@ -2327,9 +2327,9 @@
     %   `ground(shared, higher_order(PredInstInfo))' or
     %   `any(shared, higher_order(PredInstInfo))'
     % where the PredInstInfo contains the extra modes and the determinism
-    % for the predicate.  The higher-order predicate term itself cannot be
-    % free.  If it contains non-local variables with inst `any' then it
-    % must be in the latter form, otherwise it may be in the former.
+    % for the predicate. The higher-order predicate term itself cannot be free.
+    % If it contains non-local variables with inst `any' then it must be
+    % in the latter form, otherwise it may be in the former.
     %
     % Note that calling/applying a higher-order value that has the `any'
     % inst may bind that variable further, hence these values cannot safely
Index: compiler/prog_rep.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_rep.m,v
retrieving revision 1.79
diff -u -b -r1.79 prog_rep.m
--- compiler/prog_rep.m	11 Jun 2012 03:13:21 -0000	1.79
+++ compiler/prog_rep.m	24 Oct 2012 03:50:13 -0000
@@ -4,7 +4,7 @@
 % Copyright (C) 2000-2012 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: prog_rep.m.
 % Authors: zs, maclarty.
@@ -15,7 +15,7 @@
 % only the information required by the declarative debugger. The structure
 % of this representation is defined by mdbcomp/program_representation.m.
 %
-%---------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- module ll_backend.prog_rep.
 :- interface.
@@ -23,15 +23,17 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_module.
 :- import_module hlds.instmap.
-:- import_module ll_backend.stack_layout.
+:- import_module ll_backend.prog_rep_tables.
 :- import_module mdbcomp.program_representation.
 :- import_module parse_tree.prog_data.
 
+:- import_module assoc_list.
+:- import_module cord.
 :- import_module list.
 :- import_module map.
 :- import_module pair.
 
-%---------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
     % A var_num_map maps each variable that occurs in any of a procedure's
     % layout structures to a number that uniquely identifies that variable,
@@ -45,22 +47,21 @@
     %
 :- type var_num_map == map(prog_var, pair(int, string)).
 
-    % Describe whether a variable name table should be included in the
-    % bytecode.  The variable name table actually adds the strings into the
-    % module's string table.
+    % Encode the information in a module's oisu pragmas into bytecode,
+    % for use by the automatic parallelization feedback tool.
     %
-:- type include_variable_table
-    --->    include_variable_table
-    ;       do_not_include_variable_table.
+:- pred encode_oisu_type_procs(module_info::in,
+    assoc_list(type_ctor, oisu_preds)::in, int::out, cord(int)::out) is det.
 
     % Create the bytecodes for the given procedure.
     %
 :- pred represent_proc_as_bytecodes(list(prog_var)::in, hlds_goal::in,
     instmap::in, vartypes::in, var_num_map::in, module_info::in,
-    include_variable_table::in, determinism::in, 
-    string_table::in, string_table::out, list(int)::out) is det.
+    maybe_include_var_name_table::in, maybe_include_var_types::in,
+    determinism::in, string_table_info::in, string_table_info::out,
+    type_table_info::in, type_table_info::out, list(int)::out) is det.
 
-%---------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- type prog_rep_info
     --->    prog_rep_info(
@@ -79,20 +80,22 @@
 :- pred goal_to_goal_rep(prog_rep_info::in, instmap::in, hlds_goal::in, 
     goal_rep::out) is det.
 
-%---------------------------------------------------------------------------%
-%---------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- implementation.
 
-:- import_module backend_libs.bytecode_data.
+:- import_module backend_libs.proc_label.
 :- import_module check_hlds.inst_match.
 :- import_module check_hlds.mode_util.
 :- import_module hlds.code_model.
 :- import_module hlds.goal_util.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.special_pred.
 :- import_module mdbcomp.
 :- import_module mdbcomp.goal_path.
 :- import_module mdbcomp.prim_data.
+:- import_module mdbcomp.rtti_access.
 :- import_module parse_tree.prog_util.
 :- import_module parse_tree.set_of_var.
 
@@ -105,45 +108,167 @@
 :- import_module term.
 :- import_module unit.
 
-%---------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+encode_oisu_type_procs(_ModuleInfo, [], 0, cord.init).
+encode_oisu_type_procs(ModuleInfo, [Pair | Pairs], NumOISUTypes, Bytes) :-
+    encode_oisu_type_procs(ModuleInfo, Pairs, TailNumOISUTypes, TailBytes),
+    module_info_get_name(ModuleInfo, ModuleName),
+    Pair = TypeCtor - Preds,
+    TypeCtor = type_ctor(TypeCtorSymName, _TypeCtorArity),
+    (
+        TypeCtorSymName = qualified(TypeCtorModuleName, TypeCtorName)
+    ;
+        TypeCtorSymName = unqualified(_),
+        unexpected($module, $pred, "unqualified type_ctor name")
+    ),
+    ( TypeCtorModuleName = ModuleName ->
+        encode_len_string(TypeCtorName, TypeCtorNameBytes),
+        Preds = oisu_preds(CreatorPreds, MutatorPreds, DestructorPreds),
+
+        list.length(CreatorPreds, NumCreatorPreds),
+        list.length(MutatorPreds, NumMutatorPreds),
+        list.length(DestructorPreds, NumDestructorPreds),
+        encode_num_det(NumCreatorPreds, NumCreatorPredsBytes),
+        encode_num_det(NumMutatorPreds, NumMutatorPredsBytes),
+        encode_num_det(NumDestructorPreds, NumDestructorPredsBytes),
+        list.map(encode_oisu_proc(ModuleInfo), CreatorPreds,
+            CreatorPredBytes),
+        list.map(encode_oisu_proc(ModuleInfo), MutatorPreds,
+            MutatorPredBytes),
+        list.map(encode_oisu_proc(ModuleInfo), DestructorPreds,
+            DestructorPredBytes),
+
+        HeadBytes = cord.from_list(TypeCtorNameBytes)
+            ++ cord.from_list(NumCreatorPredsBytes)
+            ++ cord.cord_list_to_cord(CreatorPredBytes)
+            ++ cord.from_list(NumMutatorPredsBytes)
+            ++ cord.cord_list_to_cord(MutatorPredBytes)
+            ++ cord.from_list(NumDestructorPredsBytes)
+            ++ cord.cord_list_to_cord(DestructorPredBytes),
+
+        NumOISUTypes = 1 + TailNumOISUTypes,
+        Bytes = HeadBytes ++ TailBytes
+    ;
+        NumOISUTypes = TailNumOISUTypes,
+        Bytes = TailBytes
+    ).
+
+:- pred encode_oisu_proc(module_info::in, pred_id::in, cord(int)::out) is det.
+
+encode_oisu_proc(ModuleInfo, PredId, BytesCord) :-
+    module_info_pred_info(ModuleInfo, PredId, PredInfo),
+    pred_info_get_procedures(PredInfo, ProcTable),
+    map.to_assoc_list(ProcTable, Procs),
+    ( Procs = [ProcId - _ProcInfo] ->
+        ProcLabel = make_proc_label(ModuleInfo, PredId, ProcId),
+        encode_string_proc_label(ProcLabel, BytesCord)
+    ;
+        unexpected($module, $pred, "OISU pred should have exactly one proc")
+    ).
+
+:- pred encode_string_proc_label(proc_label::in, cord(int)::out) is det.
+
+encode_string_proc_label(ProcLabel, BytesCord) :-
+    (
+        ProcLabel = ordinary_proc_label(DefModuleName, PredOrFunc,
+            DeclModuleName, PredName, Arity, ModeNum),
+        (
+            PredOrFunc = pf_predicate,
+            KindByte = string_proclabel_kind_user_predicate
+        ;
+            PredOrFunc = pf_function,
+            KindByte = string_proclabel_kind_user_function
+        ),
+        encode_len_string(sym_name_to_string(DeclModuleName),
+            DeclModuleNameBytes),
+        encode_len_string(sym_name_to_string(DefModuleName),
+            DefModuleNameBytes),
+        encode_len_string(PredName, PredNameBytes),
+        encode_num_det(Arity, ArityBytes),
+        encode_num_det(ModeNum, ModeNumBytes),
+        BytesCord = cord.from_list([KindByte | DeclModuleNameBytes])
+            ++ cord.from_list(DefModuleNameBytes)
+            ++ cord.from_list(PredNameBytes)
+            ++ cord.from_list(ArityBytes)
+            ++ cord.from_list(ModeNumBytes)
+    ;
+        ProcLabel = special_proc_label(DefModuleName, SpecialPredId,
+            TypeModuleName, TypeName, TypeArity, ModeNum),
+        TypeCtor = type_ctor(qualified(TypeModuleName, TypeName), TypeArity),
+        PredName = special_pred_name(SpecialPredId, TypeCtor),
+
+        KindByte = string_proclabel_kind_special,
+        encode_len_string(TypeName, TypeNameBytes),
+        encode_len_string(sym_name_to_string(TypeModuleName),
+            TypeModuleNameBytes),
+        encode_len_string(sym_name_to_string(DefModuleName),
+            DefModuleNameBytes),
+        encode_len_string(PredName, PredNameBytes),
+        encode_num_det(TypeArity, TypeArityBytes),
+        encode_num_det(ModeNum, ModeNumBytes),
+        BytesCord = cord.from_list([KindByte | TypeNameBytes])
+            ++ cord.from_list(TypeModuleNameBytes)
+            ++ cord.from_list(DefModuleNameBytes)
+            ++ cord.from_list(PredNameBytes)
+            ++ cord.from_list(TypeArityBytes)
+            ++ cord.from_list(ModeNumBytes)
+    ).
+
+    % The definitions of these functions should be kept in sync with
+    % the definition of the MR_ProcLabelToken type in mercury_deep_profiling.h.
+    %
+:- func string_proclabel_kind_user_predicate = int.
+:- func string_proclabel_kind_user_function = int.
+:- func string_proclabel_kind_special = int.
+
+string_proclabel_kind_user_predicate = 0.
+string_proclabel_kind_user_function = 1.
+string_proclabel_kind_special = 2.
+
+%-----------------------------------------------------------------------------%
 
 represent_proc_as_bytecodes(HeadVars, Goal, InstMap0, VarTypes, VarNumMap,
-        ModuleInfo, IncludeVarTable, ProcDetism, !StringTable, ProcRepBytes) :-
+        ModuleInfo, IncludeVarNameTable, IncludeVarTypes, ProcDetism,
+        !StringTable, !TypeTable, ProcRepBytes) :-
     Goal = hlds_goal(_, GoalInfo),
     Context = goal_info_get_context(GoalInfo),
     term.context_file(Context, FileName),
-    represent_var_table_as_bytecode(IncludeVarTable, VarNumMap, VarNumRep,
-        VarTableBytes, !StringTable),
+    represent_var_table_as_bytecode(IncludeVarNameTable, IncludeVarTypes,
+        VarTypes, VarNumMap, VarNumRep, VarNameTableBytes,
+        !StringTable, !TypeTable),
     Info = prog_rep_info(FileName, VarTypes, VarNumMap, VarNumRep, ModuleInfo,
         expect_no_par_conjs),
     InstmapDelta = goal_info_get_instmap_delta(GoalInfo),
 
-    string_to_byte_list(FileName, FileNameBytes, !StringTable),
+    encode_string_as_table_offset(FileName, FileNameBytes, !StringTable),
     goal_to_byte_list(Goal, InstMap0, Info, GoalBytes, !StringTable),
     DetismByte = represent_determinism(ProcDetism),
-    ProcRepBytes0 = FileNameBytes ++ VarTableBytes ++
-        head_vars_to_byte_list(Info, InstMap0, InstmapDelta, HeadVars) ++
+    ProcRepBytes0 = FileNameBytes ++ VarNameTableBytes ++
+        encode_head_vars_func(Info, InstMap0, InstmapDelta, HeadVars) ++
         GoalBytes ++ [DetismByte],
-    int32_to_byte_list(list.length(ProcRepBytes0) + 4, LimitBytes),
+    encode_int32_det(list.length(ProcRepBytes0) + 4, LimitBytes),
     ProcRepBytes = LimitBytes ++ ProcRepBytes0.
 
-%---------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
-    % Create bytecodes for the variable table.
+    % Create bytecodes for the variable name table.
     %
-    % If a variable table is not requested, an empty table is created.
-    % The variable table also includes information about the representation
-    % of variable numbers within the bytecode.
+    % If a variable name table is not requested, an empty table is created.
+    % The variable name table also includes information about the
+    % representation of variable numbers within the bytecode.
     %
-    % The representation of variables and the variable table restricts the
-    % number of possible variables in a procedure to 2^31.
+    % The representation of variables and the variable name table
+    % restricts the number of possible variables in a procedure to 2^31.
     %
-:- pred represent_var_table_as_bytecode(include_variable_table::in,
+:- pred represent_var_table_as_bytecode(maybe_include_var_name_table::in,
+    maybe_include_var_types::in, vartypes::in,
     var_num_map::in, var_num_rep::out, list(int)::out, 
-    string_table::in, string_table::out) is det.
+    string_table_info::in, string_table_info::out,
+    type_table_info::in, type_table_info::out) is det.
 
-represent_var_table_as_bytecode(IncludeVarTable, VarNumMap, VarNumRep,
-        ByteList, !StringTable) :-
+represent_var_table_as_bytecode(IncludeVarNameTable, IncludeVarTypes,
+        VarTypes, VarNumMap, VarNumRep, Bytes, !StringTable, !TypeTable) :-
     map.foldl(max_var_num, VarNumMap, 0) = MaxVarNum,
     ( MaxVarNum =< 127 ->
         VarNumRep = var_num_1_byte
@@ -152,53 +277,128 @@
     ;
         VarNumRep = var_num_4_bytes
     ),
-    var_num_rep_byte(VarNumRep, VarNumRepByte),
+    var_flag_byte(VarNumRep, IncludeVarNameTable, IncludeVarTypes, FlagByte),
     (
-        IncludeVarTable = include_variable_table,
-        map.foldl3(var_table_entry_bytelist(VarNumRep), VarNumMap, 0, NumVars, 
-            [], VarTableEntriesBytes, !StringTable)
-    ;
-        IncludeVarTable = do_not_include_variable_table,
-        NumVars = 0,
-        VarTableEntriesBytes = []
-    ),
-    int32_to_byte_list(NumVars, NumVarsBytes),
-    ByteList = [VarNumRepByte] ++ NumVarsBytes ++ VarTableEntriesBytes.
+        IncludeVarNameTable = include_var_name_table,
+        (
+            IncludeVarTypes = do_not_include_var_types,
+            % It is more efficient to make the switch over the representation
+            % size just once here, than to make it when representing each
+            % variable.
+            (
+                VarNumRep = var_num_1_byte,
+                map.foldl3(encode_var_name_table_entry_1_byte, VarNumMap,
+                    0, NumVars, [], VarNameTableEntriesBytes, !StringTable)
+            ;
+                VarNumRep = var_num_2_bytes,
+                map.foldl3(encode_var_name_table_entry_2_byte, VarNumMap,
+                    0, NumVars, [], VarNameTableEntriesBytes, !StringTable)
+            ;
+                VarNumRep = var_num_4_bytes,
+                map.foldl3(encode_var_name_table_entry_4_byte, VarNumMap,
+                    0, NumVars, [], VarNameTableEntriesBytes, !StringTable)
+            )
+        ;
+            IncludeVarTypes = include_var_types,
+            map.foldl4(encode_var_name_type_table_entry(VarNumRep, VarTypes),
+                VarNumMap, 0, NumVars,
+                [], VarNameTableEntriesBytes, !StringTable, !TypeTable)
+        ),
+        encode_num_det(NumVars, NumVarsBytes),
+        Bytes = [FlagByte] ++ NumVarsBytes ++ VarNameTableEntriesBytes
+    ;
+        IncludeVarNameTable = do_not_include_var_name_table,
+        expect(unify(IncludeVarTypes, do_not_include_var_types),
+            $module, $pred, "IncludeVarTypes but not IncludeVarNameTable"),
+        Bytes = [FlagByte]
+    ).
 
 :- func max_var_num(prog_var, pair(int, string), int) = int.
 
 max_var_num(_, VarNum1 - _, VarNum2) = Max :-
     Max = max(VarNum1, VarNum2).
 
-:- pred var_table_entry_bytelist(var_num_rep::in, 
-    prog_var::in, pair(int, string)::in, int::in, int::out, 
-    list(int)::in, list(int)::out,
-    string_table::in, string_table::out) is det.
+%-----------------------------------------------------------------------------%
+%
+% To avoid repeated tests of the size of variable representations, we have
+% a specialized version for each different variable number encoding size.
+%
+% Some variables that the compiler creates are named automatically,
+% these and unnamed variables should not be included in the variable
+% name table.
+%
 
-var_table_entry_bytelist(VarNumRep, _ProgVar, VarNum - VarName, 
-        !NumVars, !VarTableBytes, !StringTable) :-
-    (
-        % Some variables that the compiler creates are named automatically,
-        % these and unnamed variables should not be included in the variable
-        % table.
-        compiler_introduced_varname(VarName)
-    ->
+:- pred encode_var_name_table_entry_1_byte(prog_var::in, pair(int, string)::in,
+    int::in, int::out, list(int)::in, list(int)::out,
+    string_table_info::in, string_table_info::out) is det.
+
+encode_var_name_table_entry_1_byte(_ProgVar, VarNum - VarName,
+        !NumVars, !VarNameTableBytes, !StringTable) :-
+    ( compiler_introduced_varname(VarName) ->
+        true
+    ;
+        !:NumVars = !.NumVars + 1,
+        VarBytes = [VarNum],
+        encode_string_as_table_offset(VarName, VarNameBytes, !StringTable),
+        !:VarNameTableBytes = VarBytes ++ VarNameBytes ++ !.VarNameTableBytes
+    ).
+
+:- pred encode_var_name_table_entry_2_byte(prog_var::in, pair(int, string)::in,
+    int::in, int::out, list(int)::in, list(int)::out,
+    string_table_info::in, string_table_info::out) is det.
+
+encode_var_name_table_entry_2_byte(_ProgVar, VarNum - VarName,
+        !NumVars, !VarNameTableBytes, !StringTable) :-
+    ( compiler_introduced_varname(VarName) ->
         true
     ;
         !:NumVars = !.NumVars + 1,
+        encode_short_det(VarNum, VarBytes),
+        encode_string_as_table_offset(VarName, VarNameBytes, !StringTable),
+        !:VarNameTableBytes = VarBytes ++ VarNameBytes ++ !.VarNameTableBytes
+    ).
+
+:- pred encode_var_name_table_entry_4_byte(prog_var::in, pair(int, string)::in,
+    int::in, int::out, list(int)::in, list(int)::out,
+    string_table_info::in, string_table_info::out) is det.
+
+encode_var_name_table_entry_4_byte(_ProgVar, VarNum - VarName,
+        !NumVars, !VarNameTableBytes, !StringTable) :-
+    ( compiler_introduced_varname(VarName) ->
+        true
+    ;
+        !:NumVars = !.NumVars + 1,
+        encode_int32_det(VarNum, VarBytes),
+        encode_string_as_table_offset(VarName, VarNameBytes, !StringTable),
+        !:VarNameTableBytes = VarBytes ++ VarNameBytes ++ !.VarNameTableBytes
+    ).
+
+:- pred encode_var_name_type_table_entry(var_num_rep::in, vartypes::in,
+    prog_var::in, pair(int, string)::in, int::in, int::out,
+    list(int)::in, list(int)::out,
+    string_table_info::in, string_table_info::out,
+    type_table_info::in, type_table_info::out) is det.
+
+encode_var_name_type_table_entry(VarNumRep, VarTypes, Var, VarNum - VarName,
+        !NumVars, !VarNameTableBytes, !StringTable, !TypeTable) :-
+    !:NumVars = !.NumVars + 1,
+    lookup_var_type(VarTypes, Var, Type),
         (
             VarNumRep = var_num_1_byte,
             VarBytes = [VarNum]
         ;
             VarNumRep = var_num_2_bytes,
-            short_to_byte_list(VarNum, VarBytes)
+        encode_short_det(VarNum, VarBytes)
         ;
             VarNumRep = var_num_4_bytes,
-            int32_to_byte_list(VarNum, VarBytes)
+        encode_int32_det(VarNum, VarBytes)
         ),
-        string_to_byte_list(VarName, VarNameBytes, !StringTable),
-        !:VarTableBytes = VarBytes ++ VarNameBytes ++ !.VarTableBytes
-    ).
+    encode_string_as_table_offset(VarName, VarNameBytes, !StringTable),
+    encode_type_as_table_ref(Type, TypeBytes, !StringTable, !TypeTable),
+    !:VarNameTableBytes = VarBytes ++ VarNameBytes ++ TypeBytes
+        ++ !.VarNameTableBytes.
+
+%-----------------------------------------------------------------------------%
 
 :- pred compiler_introduced_varname(string::in) is semidet.
 
@@ -220,14 +420,14 @@
     ),
     prefix(VarName, Prefix).
 
-%---------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pred goal_to_byte_list(hlds_goal::in, instmap::in, prog_rep_info::in,
-    list(int)::out, string_table::in, string_table::out) is det.
+    list(int)::out, string_table_info::in, string_table_info::out) is det.
 
 goal_to_byte_list(Goal, InstMap0, Info, Bytes, !StringTable) :-
     goal_to_goal_rep(Info, InstMap0, Goal, GoalRep),
-    goal_rep_to_byte_list(Info, GoalRep, Bytes, !StringTable).
+    encode_goal_rep(Info, GoalRep, Bytes, !StringTable).
 
 goal_to_goal_rep(Info, Instmap0, hlds_goal(GoalExpr, GoalInfo), GoalRep) :-
     Detism = goal_info_get_determinism(GoalInfo),
@@ -319,8 +519,8 @@
                         AtomicGoalRep = unify_construct_rep(VarRep, ConsIdRep, 
                             ArgsRep)
                     ;
-                        AtomicGoalRep = partial_construct_rep(VarRep, ConsIdRep,
-                            MaybeArgsRep)
+                        AtomicGoalRep = partial_construct_rep(VarRep,
+                            ConsIdRep, MaybeArgsRep)
                     )
                 ;
                     Uni = deconstruct(_, _, _, _, _, _),
@@ -328,8 +528,8 @@
                         AtomicGoalRep = partial_deconstruct_rep(VarRep,
                             ConsIdRep, MaybeArgsRep)
                     ;
-                        AtomicGoalRep = unify_deconstruct_rep(VarRep, ConsIdRep,
-                            ArgsRep)
+                        AtomicGoalRep = unify_deconstruct_rep(VarRep,
+                            ConsIdRep, ArgsRep)
                     )
                 )
             ;
@@ -440,43 +640,43 @@
 detism_to_detism_rep(detism_erroneous, erroneous_rep).
 detism_to_detism_rep(detism_failure, failure_rep).
 
-:- pred goal_rep_to_byte_list(prog_rep_info::in, goal_rep::in, 
-    list(int)::out, string_table::in, string_table::out) is det.
+:- pred encode_goal_rep(prog_rep_info::in, goal_rep::in, list(int)::out,
+    string_table_info::in, string_table_info::out) is det.
 
-goal_rep_to_byte_list(Info, goal_rep(GoalExpr, Detism, _), Bytes, !StringTable) :-
+encode_goal_rep(Info, goal_rep(GoalExpr, Detism, _), Bytes, !StringTable) :-
     (
         GoalExpr = conj_rep(GoalReps),
-        map_foldl(goal_rep_to_byte_list(Info), GoalReps, ConjBytesList,
+        map_foldl(encode_goal_rep(Info), GoalReps, ConjBytesList,
             !StringTable),
         ExprBytes = [goal_type_to_byte(goal_conj)] ++
-            length_to_byte_list(GoalReps) ++ condense(ConjBytesList)
+            encode_length_func(GoalReps) ++ condense(ConjBytesList)
     ;
         GoalExpr = disj_rep(GoalReps),
-        map_foldl(goal_rep_to_byte_list(Info), GoalReps, DisjBytesList,
+        map_foldl(encode_goal_rep(Info), GoalReps, DisjBytesList,
             !StringTable),
         ExprBytes = [goal_type_to_byte(goal_disj)] ++
-            length_to_byte_list(GoalReps) ++ condense(DisjBytesList)
+            encode_length_func(GoalReps) ++ condense(DisjBytesList)
     ;
         GoalExpr = negation_rep(SubGoal),
-        goal_rep_to_byte_list(Info, SubGoal, SubGoalBytes, !StringTable),
+        encode_goal_rep(Info, SubGoal, SubGoalBytes, !StringTable),
         ExprBytes = [goal_type_to_byte(goal_neg)] ++ SubGoalBytes
     ;
         GoalExpr = ite_rep(Cond, Then, Else), 
-        goal_rep_to_byte_list(Info, Cond, CondBytes, !StringTable),
-        goal_rep_to_byte_list(Info, Then, ThenBytes, !StringTable),
-        goal_rep_to_byte_list(Info, Else, ElseBytes, !StringTable),
+        encode_goal_rep(Info, Cond, CondBytes, !StringTable),
+        encode_goal_rep(Info, Then, ThenBytes, !StringTable),
+        encode_goal_rep(Info, Else, ElseBytes, !StringTable),
         ExprBytes = [goal_type_to_byte(goal_ite)] ++
             CondBytes ++ ThenBytes ++ ElseBytes
     ;
         GoalExpr = atomic_goal_rep(FileName, Line, BoundVars, AtomicGoalRep),
-        string_to_byte_list(FileName, FileNameBytes, !StringTable),
-        AtomicBytes = FileNameBytes ++ lineno_to_byte_list(Line) ++
-            var_reps_to_byte_list(Info, BoundVars), 
+        encode_string_as_table_offset(FileName, FileNameBytes, !StringTable),
+        AtomicBytes = FileNameBytes ++ encode_lineno_func(Line) ++
+            encode_var_reps_func(Info, BoundVars),
         (
             AtomicGoalRep = unify_assign_rep(Target, Source),
             ExprBytes = [goal_type_to_byte(goal_assign)] ++
-                var_rep_to_byte_list(Info, Target) ++
-                var_rep_to_byte_list(Info, Source) ++
+                encode_var_rep_func(Info, Target) ++
+                encode_var_rep_func(Info, Source) ++
                 AtomicBytes
         ;
             ( AtomicGoalRep = unify_construct_rep(_, _, _)
@@ -492,7 +692,7 @@
                     AtomicGoalRep = unify_deconstruct_rep(Var, ConsId, Args),
                     AtomicTypeByte = goal_type_to_byte(goal_deconstruct)
                 ),
-                ArgsBytes = var_reps_to_byte_list(Info, Args)
+                ArgsBytes = encode_var_reps_func(Info, Args)
             ;
                 (
                     AtomicGoalRep = partial_deconstruct_rep(Var, ConsId,
@@ -504,43 +704,44 @@
                         MaybeArgs),
                     AtomicTypeByte = goal_type_to_byte(goal_partial_construct)
                 ),
-                ArgsBytes = maybe_var_reps_to_byte_list(Info, MaybeArgs)
+                ArgsBytes = encode_maybe_var_reps_func(Info, MaybeArgs)
             ),
-            string_to_byte_list(ConsId, ConsIdBytes, !StringTable),
-            VarBytes = var_rep_to_byte_list(Info, Var),
+            encode_string_as_table_offset(ConsId, ConsIdBytes, !StringTable),
+            VarBytes = encode_var_rep_func(Info, Var),
             ExprBytes = [AtomicTypeByte] ++ VarBytes ++ ConsIdBytes ++
                 ArgsBytes ++ AtomicBytes
         ;
             AtomicGoalRep = unify_simple_test_rep(Var1, Var2),
             ExprBytes = [goal_type_to_byte(goal_simple_test)] ++
-                var_rep_to_byte_list(Info, Var1) ++
-                var_rep_to_byte_list(Info, Var2) ++
+                encode_var_rep_func(Info, Var1) ++
+                encode_var_rep_func(Info, Var2) ++
                 AtomicBytes
         ;
             AtomicGoalRep = higher_order_call_rep(PredVar, Args),
             ExprBytes = [goal_type_to_byte(goal_ho_call)] ++
-                var_rep_to_byte_list(Info, PredVar) ++
-                var_reps_to_byte_list(Info, Args) ++
+                encode_var_rep_func(Info, PredVar) ++
+                encode_var_reps_func(Info, Args) ++
                 AtomicBytes
         ;
             AtomicGoalRep = method_call_rep(Var, MethodNum, Args),
             ExprBytes = [goal_type_to_byte(goal_method_call)] ++
-                var_rep_to_byte_list(Info, Var) ++
-                method_num_to_byte_list(MethodNum) ++
-                var_reps_to_byte_list(Info, Args) ++
+                encode_var_rep_func(Info, Var) ++
+                encode_method_num_func(MethodNum) ++
+                encode_var_reps_func(Info, Args) ++
                 AtomicBytes
         ;
             AtomicGoalRep = event_call_rep(EventName, Args),
-            string_to_byte_list(EventName, EventNameBytes, !StringTable),
+            encode_string_as_table_offset(EventName, EventNameBytes,
+                !StringTable),
             ExprBytes = [goal_type_to_byte(goal_event_call)] ++
                 EventNameBytes ++
-                var_reps_to_byte_list(Info, Args) ++
+                encode_var_reps_func(Info, Args) ++
                 AtomicBytes
         ;
             AtomicGoalRep = cast_rep(Target, Source),
             ExprBytes = [goal_type_to_byte(goal_cast)] ++
-                var_rep_to_byte_list(Info, Target) ++
-                var_rep_to_byte_list(Info, Source) ++
+                encode_var_rep_func(Info, Target) ++
+                encode_var_rep_func(Info, Source) ++
                 AtomicBytes
         ;
             (
@@ -550,49 +751,50 @@
                 AtomicGoalRep = builtin_call_rep(ModuleName, PredName, Args),
                 CallType = goal_builtin_call
             ),
-            string_to_byte_list(ModuleName, ModuleNameBytes, !StringTable),
-            string_to_byte_list(PredName, PredNameBytes, !StringTable),
+            encode_string_as_table_offset(ModuleName, ModuleNameBytes,
+                !StringTable),
+            encode_string_as_table_offset(PredName, PredNameBytes,
+                !StringTable),
             ExprBytes = [goal_type_to_byte(CallType)] ++
                 ModuleNameBytes ++
                 PredNameBytes ++
-                var_reps_to_byte_list(Info, Args) ++
+                encode_var_reps_func(Info, Args) ++
                 AtomicBytes
         ;
             AtomicGoalRep = pragma_foreign_code_rep(Args),
             ExprBytes = [goal_type_to_byte(goal_foreign)] ++
-                var_reps_to_byte_list(Info, Args) ++ AtomicBytes
+                encode_var_reps_func(Info, Args) ++ AtomicBytes
         )
     ;
         GoalExpr = switch_rep(SwitchVar, CanFail, Cases),
-        map_foldl(case_rep_to_byte_list(Info), Cases, CasesBytesList,
+        list.map_foldl(encode_case_rep(Info), Cases, CasesBytesList,
             !StringTable),
         can_fail_byte(CanFail, CanFailByte),
         ExprBytes = [goal_type_to_byte(goal_switch)] ++
             [CanFailByte] ++
-            var_rep_to_byte_list(Info, SwitchVar) ++
-            length_to_byte_list(Cases) ++ condense(CasesBytesList) 
+            encode_var_rep_func(Info, SwitchVar) ++
+            encode_length_func(Cases) ++ list.condense(CasesBytesList)
     ;
         GoalExpr = scope_rep(SubGoal, MaybeCut),
         cut_byte(MaybeCut, MaybeCutByte),
-        goal_rep_to_byte_list(Info, SubGoal, SubGoalBytes, !StringTable),  
+        encode_goal_rep(Info, SubGoal, SubGoalBytes, !StringTable),
         ExprBytes = [goal_type_to_byte(goal_scope)] ++ [MaybeCutByte] ++ 
             SubGoalBytes
     ),
     determinism_representation(Detism, DetismByte),
     Bytes = ExprBytes ++ [DetismByte].
 
-:- pred case_rep_to_byte_list(prog_rep_info::in, case_rep::in, list(int)::out,
-    string_table::in, string_table::out) is det.
+:- pred encode_case_rep(prog_rep_info::in, case_rep::in, list(int)::out,
+    string_table_info::in, string_table_info::out) is det.
 
-case_rep_to_byte_list(Info, Case, Bytes, !StringTable) :-
+encode_case_rep(Info, Case, Bytes, !StringTable) :-
     Case = case_rep(MainConsId, OtherConsIds, Goal),
-    goal_rep_to_byte_list(Info, Goal, GoalBytes, !StringTable),
-    cons_id_and_arity_rep_to_byte_list(MainConsId, MainConsIdBytes,
-        !StringTable),
-    map_foldl(cons_id_and_arity_rep_to_byte_list, 
+    encode_goal_rep(Info, Goal, GoalBytes, !StringTable),
+    encode_cons_id_and_arity_rep(MainConsId, MainConsIdBytes, !StringTable),
+    map_foldl(encode_cons_id_and_arity_rep,
         OtherConsIds, OtherConsIdsByteLists, !StringTable),
-    Bytes = MainConsIdBytes ++ length_to_byte_list(OtherConsIds) ++
-        condense(OtherConsIdsByteLists) ++ GoalBytes.
+    Bytes = MainConsIdBytes ++ encode_length_func(OtherConsIds) ++
+        list.condense(OtherConsIdsByteLists) ++ GoalBytes.
 
 :- pred lhs_final_is_ground(prog_rep_info::in, uni_mode::in) is semidet.
 
@@ -621,7 +823,7 @@
 filter_input_args(_, [_ | _], [], _) :-
     unexpected($module, $pred, "mismatched lists").
 
-%---------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pred goal_info_to_atomic_goal_rep_fields(hlds_goal_info::in, instmap::in,
     prog_rep_info::in, string::out, int::out, list(prog_var)::out) is det.
@@ -642,20 +844,20 @@
         Info ^ pri_module_info, ChangedVars),
     set_of_var.to_sorted_list(ChangedVars, BoundVars).
 
-:- pred cons_id_and_arity_rep_to_byte_list(cons_id_arity_rep::in, 
-    list(int)::out, string_table::in, string_table::out) is det.
+:- pred encode_cons_id_and_arity_rep(cons_id_arity_rep::in, list(int)::out,
+    string_table_info::in, string_table_info::out) is det.
 
-cons_id_and_arity_rep_to_byte_list(ConsIdArity, ConsIdBytes, !StringTable) :-
+encode_cons_id_and_arity_rep(ConsIdArity, ConsIdBytes, !StringTable) :-
     ConsIdArity = cons_id_arity_rep(ConsId, Arity),
-    string_to_byte_list(ConsId, FunctorBytes, !StringTable),
-    short_to_byte_list(Arity, ArityBytes),
+    encode_string_as_table_offset(ConsId, FunctorBytes, !StringTable),
+    encode_short_det(Arity, ArityBytes),
     ConsIdBytes = FunctorBytes ++ ArityBytes.
 
-:- pred cons_id_to_byte_list(cons_id::in, list(int)::out,
-    string_table::in, string_table::out) is det.
+:- pred encode_cons_id(cons_id::in, list(int)::out,
+    string_table_info::in, string_table_info::out) is det.
 
-cons_id_to_byte_list(SymName, Bytes, !StringTable) :-
-    string_to_byte_list(cons_id_rep(SymName), Bytes, !StringTable).
+encode_cons_id(SymName, Bytes, !StringTable) :-
+    encode_string_as_table_offset(cons_id_rep(SymName), Bytes, !StringTable).
 
 :- func cons_id_rep(cons_id) = string.
 
@@ -686,7 +888,7 @@
 sym_base_name_to_string(unqualified(String)) = String.
 sym_base_name_to_string(qualified(_, String)) = String.
 
-%---------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 % The operations to convert primitive constructs to bytecode.
 %
@@ -699,79 +901,87 @@
 % but we here use them to represent unsigned quantities. This effectively
 % halves their range.
 
-:- pred string_to_byte_list(string::in, list(int)::out,
-    string_table::in, string_table::out) is det.
+:- pred encode_string_as_table_offset(string::in, list(int)::out,
+    string_table_info::in, string_table_info::out) is det.
 
-string_to_byte_list(String, Bytes, !StringTable) :-
-    stack_layout.lookup_string_in_table(String, Index, !StringTable),
-    int32_to_byte_list(Index, Bytes).
-
-:- func var_reps_to_byte_list(prog_rep_info, list(var_rep)) = list(int).
-
-var_reps_to_byte_list(Info, Vars) =
-    length_to_byte_list(Vars) ++
-    list.condense(list.map(var_rep_to_byte_list(Info), Vars)).
+encode_string_as_table_offset(String, Bytes, !StringTable) :-
+    lookup_string_in_table(String, Index, !StringTable),
+    encode_int32_det(Index, Bytes).
+
+:- pred encode_type_as_table_ref(mer_type::in, list(int)::out,
+    string_table_info::in, string_table_info::out,
+    type_table_info::in, type_table_info::out) is det.
+
+encode_type_as_table_ref(Type, Bytes, !StringTable, !TypeTable) :-
+    lookup_type_in_table(Type, Index, !StringTable, !TypeTable),
+    encode_num_det(Index, Bytes).
+
+:- func encode_var_reps_func(prog_rep_info, list(var_rep)) = list(int).
+
+encode_var_reps_func(Info, Vars) =
+    encode_length_func(Vars) ++
+    list.condense(list.map(encode_var_rep_func(Info), Vars)).
 
 :- func var_to_var_rep(prog_rep_info, prog_var) = int.
 
 var_to_var_rep(Info, Var) = Num :-
     map.lookup(Info ^ pri_var_num_map, Var, Num - _).
 
-:- func var_rep_to_byte_list(prog_rep_info, var_rep) = list(int).
+:- func encode_var_rep_func(prog_rep_info, var_rep) = list(int).
 
-var_rep_to_byte_list(Info, Var) = Bytes :-
+encode_var_rep_func(Info, Var) = Bytes :-
+    VarNumRep = Info ^ pri_var_num_rep,
     (
-        Info ^ pri_var_num_rep = var_num_1_byte,
+        VarNumRep = var_num_1_byte,
         Bytes = [Var]
     ; 
-        Info ^ pri_var_num_rep = var_num_2_bytes,
-        short_to_byte_list(Var, Bytes)
+        VarNumRep = var_num_2_bytes,
+        encode_short_det(Var, Bytes)
     ; 
-        Info ^ pri_var_num_rep = var_num_4_bytes,
-        int32_to_byte_list(Var, Bytes)
+        VarNumRep = var_num_4_bytes,
+        encode_int32_det(Var, Bytes)
     ).
 
-:- func maybe_var_reps_to_byte_list(prog_rep_info, list(maybe(var_rep))) =
+:- func encode_maybe_var_reps_func(prog_rep_info, list(maybe(var_rep))) =
     list(int).
 
-maybe_var_reps_to_byte_list(Info, Vars) =
-    length_to_byte_list(Vars) ++
-    list.condense(list.map(maybe_var_rep_to_byte_list(Info), Vars)).
+encode_maybe_var_reps_func(Info, Vars) =
+    encode_length_func(Vars) ++
+    list.condense(list.map(encode_maybe_var_rep_func(Info), Vars)).
 
-:- func maybe_var_rep_to_byte_list(prog_rep_info, maybe(var_rep)) = list(int).
+:- func encode_maybe_var_rep_func(prog_rep_info, maybe(var_rep)) = list(int).
 
-maybe_var_rep_to_byte_list(Info, MaybeVar) = Bytes :-
+encode_maybe_var_rep_func(Info, MaybeVar) = Bytes :-
     % This is not the most efficient representation, however maybe(var_rep)s
-    % are only used for partial unifications which are rare.
+    % are only used for partial unifications, which are rare.
     (
         MaybeVar = yes(Var),
-        Bytes = [1 | var_rep_to_byte_list(Info, Var)]
+        Bytes = [1 | encode_var_rep_func(Info, Var)]
     ;
         MaybeVar = no,
         Bytes = [0]
     ).
 
-:- func head_vars_to_byte_list(prog_rep_info, instmap, instmap_delta,
+:- func encode_head_vars_func(prog_rep_info, instmap, instmap_delta,
     list(prog_var)) = list(int).
 
-head_vars_to_byte_list(Info, InitialInstmap, InstmapDelta, Vars) =
-    length_to_byte_list(Vars) ++
+encode_head_vars_func(Info, InitialInstmap, InstmapDelta, Vars) =
+    encode_length_func(Vars) ++
     list.condense(list.map(
-        head_var_to_byte_list(Info, InitialInstmap, InstmapDelta), Vars)).
+        encode_head_var_func(Info, InitialInstmap, InstmapDelta), Vars)).
 
-:- func head_var_to_byte_list(prog_rep_info, instmap, instmap_delta,
+:- func encode_head_var_func(prog_rep_info, instmap, instmap_delta,
     prog_var) = list(int).
 
-head_var_to_byte_list(Info, InitialInstmap, InstmapDelta, Var) = Bytes :-
-    var_rep_to_byte_list(Info, var_to_var_rep(Info, Var)) = VarBytes,
+encode_head_var_func(Info, InitialInstmap, InstmapDelta, Var) = Bytes :-
+    encode_var_rep_func(Info, var_to_var_rep(Info, Var)) = VarBytes,
     ModuleInfo = Info ^ pri_module_info,
     instmap_lookup_var(InitialInstmap, Var, InitialInst),
     ( instmap_delta_search_var(InstmapDelta, Var, FinalInstPrime) ->
         FinalInst = FinalInstPrime
     ;
-        % if the variable is not in the instmap delta, then its instantiation
-        % cannot possibly change.  It has the same instantiation that it begun
-        % with.
+        % If the variable is not in the instmap delta, then its instantiation
+        % cannot possibly change.
         FinalInst = InitialInst
     ),
     Bytes = VarBytes ++ [inst_to_byte(ModuleInfo, InitialInst),
@@ -795,21 +1005,21 @@
     ),
     inst_representation(InstRep, Byte).
 
-:- func length_to_byte_list(list(T)) = list(int).
+:- func encode_length_func(list(T)) = list(int).
 
-length_to_byte_list(List) = Bytes :-
-    int32_to_byte_list(list.length(List), Bytes).
+encode_length_func(List) = Bytes :-
+    encode_int32_det(list.length(List), Bytes).
 
-:- func lineno_to_byte_list(int) = list(int).
+:- func encode_lineno_func(int) = list(int).
 
-lineno_to_byte_list(VarNum) = Bytes :-
-    int32_to_byte_list(VarNum, Bytes).
+encode_lineno_func(VarNum) = Bytes :-
+    encode_int32_det(VarNum, Bytes).
 
-:- func method_num_to_byte_list(int) = list(int).
+:- func encode_method_num_func(int) = list(int).
 
-method_num_to_byte_list(VarNum) = Bytes :-
-    short_to_byte_list(VarNum, Bytes).
+encode_method_num_func(VarNum) = Bytes :-
+    encode_short_det(VarNum, Bytes).
 
-%---------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 :- end_module ll_backend.prog_rep.
-%---------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
Index: compiler/prog_rep_tables.m
===================================================================
RCS file: compiler/prog_rep_tables.m
diff -N compiler/prog_rep_tables.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ compiler/prog_rep_tables.m	24 Oct 2012 03:50:13 -0000
@@ -0,0 +1,402 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%---------------------------------------------------------------------------%
+% Copyright (C) 2012 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: prog_rep_tables.m.
+% Author: zs.
+%
+% This module contains predicates to build the tables included in program
+% representations for debugging and/or deep profiling (mostly the latter).
+%
+%---------------------------------------------------------------------------%
+
+:- module ll_backend.prog_rep_tables.
+:- interface.
+
+:- import_module parse_tree.prog_data.
+
+:- import_module list.
+
+%---------------------------------------------------------------------------%
+
+:- type string_table_info.
+
+:- func init_string_table_info = string_table_info.
+
+:- pred lookup_string_in_table(string::in, int::out,
+    string_table_info::in, string_table_info::out) is det.
+
+:- pred get_string_table_contents(string_table_info::in,
+    list(string)::out, int::out) is det.
+
+%---------------------------------------------------------------------------%
+
+:- type type_table_info.
+
+:- func init_type_table_info = type_table_info.
+
+:- pred lookup_type_in_table(mer_type::in, int::out,
+    string_table_info::in, string_table_info::out,
+    type_table_info::in, type_table_info::out) is det.
+
+:- pred get_type_table_contents(type_table_info::in, int::out,
+    list(int)::out) is det.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module mdbcomp.
+:- import_module mdbcomp.prim_data.
+:- import_module mdbcomp.rtti_access.
+
+:- import_module char.
+:- import_module cord.
+:- import_module int.
+:- import_module map.
+:- import_module maybe.
+:- import_module require.
+:- import_module string.
+:- import_module term.
+
+%---------------------------------------------------------------------------%
+
+:- type string_table_info
+    --->    string_table_info(
+                % Maps strings to their offsets.
+                map(string, int),
+
+                % The list of strings so far, in reverse order.
+                list(string),
+
+                % The next available offset.
+                int
+            ).
+
+init_string_table_info = !:StringTable :-
+    map.init(StringMap0),
+    !:StringTable = string_table_info(StringMap0, [], 0),
+    lookup_string_in_table("", _, !StringTable),
+    lookup_string_in_table("<too many variables>", _, !StringTable).
+
+lookup_string_in_table(String, StringCode, !StringTable) :-
+    % The encoding used here is decoded by MR_name_in_string_table
+    % in runtime/mercury_stack_layout.c. The code here and there
+    % must be kept in sync.
+    (
+        is_var_name_in_special_form(String, KindCode, MaybeBaseName, N),
+        N < int.unchecked_left_shift(1, 10),
+        (
+            MaybeBaseName = yes(BaseName),
+            lookup_raw_string_in_table(BaseName, MaybeOffset, !StringTable),
+            MaybeOffset = yes(Offset),
+            Offset < int.unchecked_left_shift(1, 16)
+        ;
+            MaybeBaseName = no,
+            Offset = 0
+        )
+    ->
+        % | ... offset ... | ... N ... | Kind | 1 |
+        % special form indication: 1 bit:   bit 0
+        % kind indication:         5 bits:  bits 1-5
+        % N:                       10 bits: bits 6-15
+        % Offset:                  16 bits: bits 16-31
+        StringCode = 1 \/
+            int.unchecked_left_shift(KindCode, 1) \/
+            int.unchecked_left_shift(N, 6) \/
+            int.unchecked_left_shift(Offset, 16)
+    ;
+        lookup_raw_string_in_table(String, MaybeOffset, !StringTable),
+        (
+            MaybeOffset = yes(Offset)
+        ;
+            MaybeOffset = no,
+            % Says that the name of the variable is "TOO_MANY_VARIABLES".
+            Offset = 1
+        ),
+        StringCode = int.unchecked_left_shift(Offset, 1)
+    ).
+
+:- pred is_var_name_in_special_form(string::in,
+    int::out, maybe(string)::out, int::out) is semidet.
+
+is_var_name_in_special_form(String, KindCode, MaybeBaseName, N) :-
+    % state_var.m constructs variable names that always contain
+    % the state var name, and usually but not always a numeric suffix.
+    % The numeric suffic may be zero or positive. We could represent
+    % the lack of a suffix using a negative number, but mixing unsigned
+    % and signed fields in a single word is tricky, especially since
+    % the size of the variable name descriptor word we generate (32 bits)
+    % may or may not be the same as the word size of the compiler.
+    % Instead, we simply add one to any actual suffix values, and use
+    % zero to represent the absence of a numeric suffix.
+
+    % polymorphism.m adds a numeric suffix but no type name
+    % to type_ctor_infos and type_infos.
+
+    % polymorphism.m adds a class id but no numeric suffix to
+    % base_typeclass_infos and typeclass_infos. Since the usual string table
+    % already does a good enough job for these, the code for handling them
+    % specially is commented out.
+
+    ( string.remove_prefix("STATE_VARIABLE_", String, NoPrefix) ->
+        KindCode = 0,
+        string.to_char_list(NoPrefix, NoPrefixChars),
+        ( find_number_suffix(NoPrefixChars, BaseNameChars, Num) ->
+            string.from_char_list(BaseNameChars, BaseName),
+            MaybeBaseName = yes(BaseName),
+            N = Num + 1
+        ;
+            MaybeBaseName = yes(NoPrefix),
+            N = 0
+        )
+    ; string.remove_prefix("TypeCtorInfo_", String, NoPrefix) ->
+        ( string.to_int(NoPrefix, Num) ->
+            KindCode = 1,
+            MaybeBaseName = no,
+            N = Num
+        ;
+            fail
+        )
+    ; string.remove_prefix("TypeInfo_", String, NoPrefix) ->
+        ( string.to_int(NoPrefix, Num) ->
+            KindCode = 2,
+            MaybeBaseName = no,
+            N = Num
+        ;
+            fail
+        )
+%   ; string.remove_prefix("BaseTypeClassInfo_for_", String, NoPrefix) ->
+%       KindCode = 3,
+%       MaybeBaseName = yes(NoPrefix),
+%       N = 0
+%   ; string.remove_prefix("TypeClassInfo_for_", String, NoPrefix) ->
+%       KindCode = 4,
+%       MaybeBaseName = yes(NoPrefix),
+%       N = 0
+    ; string.remove_prefix("PolyConst", String, NoPrefix) ->
+        ( string.to_int(NoPrefix, Num) ->
+            KindCode = 5,
+            MaybeBaseName = no,
+            N = Num
+        ;
+            fail
+        )
+    ;
+        fail
+    ).
+
+    % Given e.g. "Info_15" as input, we return "Info" as BeforeNum
+    % and 15 as Num.
+    %
+:- pred find_number_suffix(list(char)::in, list(char)::out, int::out)
+    is semidet.
+
+find_number_suffix(String, BeforeNum, Num) :-
+    list.reverse(String, RevString),
+    rev_find_number_suffix(RevString, 0, Num, 1, Scale, RevRest),
+    Scale > 1,
+    list.reverse(RevRest, BeforeNum).
+
+:- pred rev_find_number_suffix(list(char)::in, int::in, int::out,
+    int::in, int::out, list(char)::out) is semidet.
+
+rev_find_number_suffix([RevHead | RevTail], !Num, !Scale, RevRest) :-
+    ( char.digit_to_int(RevHead, Digit) ->
+        !:Num = !.Num + (!.Scale * Digit),
+        !:Scale = !.Scale * 10,
+        rev_find_number_suffix(RevTail, !Num, !Scale, RevRest)
+    ; RevHead = '_' ->
+        RevRest = RevTail
+    ;
+        fail
+    ).
+
+:- pred lookup_raw_string_in_table(string::in, maybe(int)::out,
+    string_table_info::in, string_table_info::out) is det.
+
+lookup_raw_string_in_table(String, MaybeOffset, !StringTable) :-
+    !.StringTable = string_table_info(TableMap0, TableList0, TableOffset0),
+    ( map.search(TableMap0, String, OldOffset) ->
+        MaybeOffset = yes(OldOffset)
+    ;
+        Length = string.count_utf8_code_units(String),
+        TableOffset = TableOffset0 + Length + 1,
+        % We use a 32 bit unsigned integer to represent the offset. Computing
+        % that limit exactly without getting an overflow or using unportable
+        % code isn't trivial. The code below is overly conservative, requiring
+        % the offset to be representable in only 30 bits. The over-conservatism
+        % should not be an issue; the machine will run out of virtual memory
+        % before the test below fails, for the next several years anyway.
+        % (Compiling a module that has a 1 Gb string table will require
+        % several tens of Gb of other compiler structures.)
+        TableOffset < (1 << 30)
+    ->
+        MaybeOffset = yes(TableOffset0),
+        map.det_insert(String, TableOffset0, TableMap0, TableMap),
+        TableList = [String | TableList0],
+        !:StringTable = string_table_info(TableMap, TableList, TableOffset)
+    ;
+        MaybeOffset = no
+    ).
+
+get_string_table_contents(StringTable, Strings, StringTableSize) :-
+    StringTable = string_table_info(_, RevStrings, StringTableSize),
+    list.reverse(RevStrings, Strings).
+
+%---------------------------------------------------------------------------%
+%
+% The type table data structure.
+%
+
+:- type type_table_info
+    --->    type_table_info(
+                % Maps the types in the type table to their representations.
+                map(mer_type, int),
+
+                % The bytecode representing the types in the first field.
+                cord(int),
+
+                % The next available type number.
+                int
+            ).
+
+init_type_table_info = type_table_info(map.init, cord.init, 0).
+
+lookup_type_in_table(Type, TypeCode, !StringTable, !TypeTable) :-
+    !.TypeTable = type_table_info(TypeMap0, _, _),
+    ( map.search(TypeMap0, Type, TypeCodePrime) ->
+        TypeCode = TypeCodePrime
+    ;
+        add_type_to_table(Type, TypeCode, !StringTable, !TypeTable)
+    ).
+
+:- pred add_type_to_table(mer_type::in, int::out,
+    string_table_info::in, string_table_info::out,
+    type_table_info::in, type_table_info::out) is det.
+
+add_type_to_table(Type, TypeCode, !StringTable, !TypeTable) :-
+    % The encoding used here is decoded by read_encoded_type in mdbcomp/
+    % program_representation.m. The code here and there must be kept in sync.
+    (
+        Type = defined_type(TypeCtorSymName, ArgTypes, _Kind),
+        list.map_foldl2(lookup_type_in_table, ArgTypes, ArgTypeCodes,
+            !StringTable, !TypeTable),
+        TypeCtorSymNameStr = sym_name_to_string(TypeCtorSymName),
+        lookup_string_in_table(TypeCtorSymNameStr, TypeCtorSymNameCode,
+            !StringTable),
+        encode_int32_det(TypeCtorSymNameCode, TypeCtorSymNameBytes),
+        (
+            ArgTypeCodes = [],
+            Selector = 0,
+            ArgTypeBytesCord = cord.init
+        ;
+            ArgTypeCodes = [ArgTypeCode1],
+            Selector = 1,
+            ArgTypeBytesCord = cord.from_list(encode_num_func(ArgTypeCode1))
+        ;
+            ArgTypeCodes = [ArgTypeCode1, ArgTypeCode2],
+            Selector = 2,
+            ArgTypeBytesCord = cord.from_list(encode_num_func(ArgTypeCode1))
+                ++ cord.from_list(encode_num_func(ArgTypeCode2))
+        ;
+            ArgTypeCodes = [ArgTypeCode1, ArgTypeCode2, ArgTypeCode3],
+            Selector = 3,
+            ArgTypeBytesCord = cord.from_list(encode_num_func(ArgTypeCode1))
+                ++ cord.from_list(encode_num_func(ArgTypeCode2))
+                ++ cord.from_list(encode_num_func(ArgTypeCode3))
+        ;
+            ArgTypeCodes = [_, _, _, _ | _],
+            Selector = 4,
+            encode_arg_type_codes(ArgTypeCodes, ArgTypeBytesCord)
+        ),
+        TypeBytesCord =
+            cord.from_list([Selector | TypeCtorSymNameBytes])
+            ++ ArgTypeBytesCord
+    ;
+        Type = builtin_type(BuiltinType),
+        (
+            BuiltinType = builtin_type_int,
+            Selector = 5
+        ;
+            BuiltinType = builtin_type_float,
+            Selector = 6
+        ;
+            BuiltinType = builtin_type_string,
+            Selector = 7
+        ;
+            BuiltinType = builtin_type_char,
+            Selector = 8
+        ),
+        TypeBytesCord = cord.singleton(Selector)
+    ;
+        Type = tuple_type(ArgTypes, _Kind),
+        Selector = 9,
+        list.map_foldl2(lookup_type_in_table, ArgTypes, ArgTypeCodes,
+            !StringTable, !TypeTable),
+        encode_arg_type_codes(ArgTypeCodes, ArgTypeBytesCord),
+        TypeBytesCord = cord.singleton(Selector) ++ ArgTypeBytesCord
+    ;
+        Type = higher_order_type(ArgTypes, MaybeReturnType,
+            _Purity, _EvalMethod),
+        list.map_foldl2(lookup_type_in_table, ArgTypes, ArgTypeCodes,
+            !StringTable, !TypeTable),
+        encode_arg_type_codes(ArgTypeCodes, ArgTypeBytesCord),
+        (
+            MaybeReturnType = no,
+            Selector = 10,
+            TypeBytesCord = cord.singleton(Selector)
+                ++ ArgTypeBytesCord
+        ;
+            MaybeReturnType = yes(ReturnType),
+            Selector = 11,
+            lookup_type_in_table(ReturnType, ReturnTypeCode,
+                !StringTable, !TypeTable),
+            encode_num_det(ReturnTypeCode, ReturnTypeBytes),
+            TypeBytesCord = cord.singleton(Selector)
+                ++ ArgTypeBytesCord
+                ++ cord.from_list(ReturnTypeBytes)
+        )
+    ;
+        Type = apply_n_type(_TVar, _ArgTypes, _Kind),
+        unexpected($module, $pred, "apply_n_type")
+    ;
+        Type = kinded_type(_Kind, _SubType),
+        unexpected($module, $pred, "kinded_type")
+    ;
+        Type = type_variable(TVar, _Kind),
+        Selector = 12,
+        var_to_int(TVar, TVarNum),
+        encode_num_det(TVarNum, TVarNumBytes),
+        TypeBytesCord = cord.singleton(Selector) ++
+            cord.from_list(TVarNumBytes)
+    ),
+    !.TypeTable = type_table_info(TypeMap0, TypeTableCord0, NextTypeNum0),
+    TypeCode = NextTypeNum0,
+    NextTypeNum = NextTypeNum0 + 1,
+    map.det_insert(Type, TypeCode, TypeMap0, TypeMap),
+    TypeTableCord = TypeTableCord0 ++ TypeBytesCord,
+    !:TypeTable = type_table_info(TypeMap, TypeTableCord, NextTypeNum).
+
+:- pred encode_arg_type_codes(list(int)::in, cord(int)::out) is det.
+
+encode_arg_type_codes(ArgTypeCodes, ArgTypeBytesCord) :-
+    list.map(encode_num_det, ArgTypeCodes, ArgTypeByteLists),
+    ArgTypeByteCords = list.map(cord.from_list, ArgTypeByteLists),
+    ArgTypeBytesCord0 = cord.cord_list_to_cord(ArgTypeByteCords),
+    list.length(ArgTypeCodes, NumArgTypeCodes),
+    ArgTypeBytesCord = cord.from_list(encode_num_func(NumArgTypeCodes))
+        ++ ArgTypeBytesCord0.
+
+get_type_table_contents(TypeTable, NumTypes, TypeBytes) :-
+    TypeTable = type_table_info(_, TypeBytesCord, NumTypes),
+    TypeBytes = cord.list(TypeBytesCord).
+
+%---------------------------------------------------------------------------%
+:- end_module ll_backend.prog_rep_tables.
+%---------------------------------------------------------------------------%
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.169
diff -u -b -r1.169 stack_layout.m
--- compiler/stack_layout.m	8 Jun 2012 15:37:00 -0000	1.169
+++ compiler/stack_layout.m	24 Oct 2012 03:50:13 -0000
@@ -84,10 +84,6 @@
     %
 :- pred represent_determinism_rval(determinism::in, rval::out) is det.
 
-:- type string_table.
-:- pred lookup_string_in_table(string::in, int::out,
-    string_table::in, string_table::out) is det.
-
 %---------------------------------------------------------------------------%
 
 :- pred compute_var_number_map(list(prog_var)::in, prog_varset::in,
@@ -99,6 +95,7 @@
 
 :- implementation.
 
+:- import_module backend_libs.bytecode_data.
 :- import_module backend_libs.proc_label.
 :- import_module backend_libs.rtti.
 :- import_module check_hlds.type_util.
@@ -113,8 +110,10 @@
 :- import_module ll_backend.layout.
 :- import_module ll_backend.layout_out.
 :- import_module ll_backend.ll_pseudo_type_info.
+:- import_module ll_backend.prog_rep_tables.
 :- import_module ll_backend.trace_gen.
 :- import_module mdbcomp.goal_path.
+:- import_module mdbcomp.rtti_access.
 :- import_module parse_tree.prog_event.
 :- import_module parse_tree.set_of_var.
 
@@ -145,16 +144,18 @@
 
     Params = init_stack_layout_params(ModuleInfo),
     map.init(LabelTables0),
-    StringTable0 = init_string_table,
+    StringTable0 = init_string_table_info,
+    TypeTable0 = init_type_table_info,
     global_data_get_static_cell_info(!.GlobalData, StaticCellInfo0),
     LabelLayoutInfo0 = init_label_layouts_info,
     ProcLayoutInfo0 = init_proc_layouts_info,
 
     global_data_get_all_proc_layouts(!.GlobalData, ProcLayoutList),
-    list.foldl5(construct_proc_and_label_layouts_for_proc(Params),
+    list.foldl6(construct_proc_and_label_layouts_for_proc(Params),
         ProcLayoutList,
         LabelTables0, LabelTables,
         StringTable0, StringTable,
+        TypeTable0, TypeTable,
         StaticCellInfo0, StaticCellInfo1,
         LabelLayoutInfo0, LabelLayoutInfo,
         ProcLayoutInfo0, ProcLayoutInfo),
@@ -221,14 +222,43 @@
     InternalLabelToLayoutMap = LabelLayoutInfo ^ lli_i_label_to_layout_map,
     ProcLabelToLayoutMap = ProcLayoutInfo ^ pli_p_label_to_layout_map,
 
-    StringTable = string_table(_, RevStringList, StringOffset),
-    list.reverse(RevStringList, StringList),
-    ConcatStrings = string_with_0s(StringList),
+    DeepProfiling = Params ^ slp_deep_profiling,
+    (
+        DeepProfiling = yes,
+        module_info_get_oisu_map(ModuleInfo, OISUMap),
+        map.to_assoc_list(OISUMap, OISUPairs),
+        encode_oisu_type_procs(ModuleInfo, OISUPairs,
+            NumOISUTypes, OISUBytesCord),
+        OISUBytes0 = cord.list(OISUBytesCord),
+        (
+            OISUBytes0 = [],
+            OISUBytes = []
+        ;
+            OISUBytes0 = [_ | _],
+            encode_int32_det(list.length(OISUBytes0) + 4, OISULimitBytes),
+            OISUBytes = OISULimitBytes ++ OISUBytes0
+        ),
+
+        get_type_table_contents(TypeTable, NumTypes, TypeBytes0),
+        (
+            TypeBytes0 = [],
+            TypeBytes = []
+        ;
+            TypeBytes0 = [_ | _],
+            encode_int32_det(list.length(TypeBytes0) + 4, TypeTableSizeBytes),
+            TypeBytes = TypeTableSizeBytes ++ TypeBytes0
+        ),
+        DeepProfInfo = module_layout_deep_prof(NumOISUTypes, OISUBytes,
+            NumTypes, TypeBytes),
+        MaybeDeepProfInfo = yes(DeepProfInfo)
+    ;
+        DeepProfiling = no,
+        MaybeDeepProfInfo = no
+    ),
 
     TraceLayout = Params ^ slp_trace_stack_layout,
     (
         TraceLayout = yes,
-        module_info_get_name(ModuleInfo, ModuleName),
         RttiLineNumbers = Params ^ slp_rtti_line_numbers,
         (
             RttiLineNumbers = yes,
@@ -263,28 +293,29 @@
                 EventArgTypeInfoMap),
             MaybeEventSet = yes(EventSetLayoutData)
         ),
-        ModuleCommonLayout = module_layout_common_data(ModuleName,
-            StringOffset, ConcatStrings),
-        ModuleCommonLayoutName = module_common_layout(ModuleName),
+
         TraceLevel = Params ^ slp_trace_level,
-        ModuleLayout = module_layout_data(ModuleName,
-            ModuleCommonLayoutName, ProcLayoutNames, SourceFileLayouts,
+        DebugInfo = module_layout_debug(ProcLayoutNames, SourceFileLayouts,
             TraceLevel, SuppressedEvents, NumLabels, MaybeEventSet),
-        ModuleLayouts = [ModuleCommonLayout, ModuleLayout]
+        MaybeDebugInfo = yes(DebugInfo)
     ;
         TraceLayout = no,
-        DeepProfiling = Params ^ slp_deep_profiling,
+        StaticCellInfo = StaticCellInfo1,
+        MaybeDebugInfo = no
+    ),
         (
-            DeepProfiling = yes,
-            module_info_get_name(ModuleInfo, ModuleName),
-            ModuleCommonLayout = module_layout_common_data(ModuleName,
-                StringOffset, ConcatStrings),
-            ModuleLayouts = [ModuleCommonLayout]
-        ;
-            DeepProfiling = no,
+        MaybeDeepProfInfo = no,
+        MaybeDebugInfo = no
+    ->
             ModuleLayouts = []
-        ),
-        StaticCellInfo = StaticCellInfo1
+    ;
+        module_info_get_name(ModuleInfo, ModuleName),
+        get_string_table_contents(StringTable, StringList, StringTableSize),
+        StringTableContents = string_with_0s(StringList),
+        ModuleLayout = module_layout_data(ModuleName,
+            StringTableSize, StringTableContents,
+            MaybeDeepProfInfo, MaybeDebugInfo),
+        ModuleLayouts = [ModuleLayout]
     ),
     global_data_set_static_cell_info(StaticCellInfo, !GlobalData).
 
@@ -391,19 +422,22 @@
 :- pred construct_proc_and_label_layouts_for_proc(stack_layout_params::in,
     proc_layout_info::in,
     label_tables::in, label_tables::out,
-    string_table::in, string_table::out,
+    string_table_info::in, string_table_info::out,
+    type_table_info::in, type_table_info::out,
     static_cell_info::in, static_cell_info::out,
     label_layouts_info::in, label_layouts_info::out,
     proc_layouts_info::in, proc_layouts_info::out) is det.
 
 construct_proc_and_label_layouts_for_proc(Params, PLI, !LabelTables,
-        !StringTable, !StaticCellInfo, !LabelLayoutInfo, !ProcLayoutInfo) :-
+        !StringTable, !TypeTable, !StaticCellInfo,
+        !LabelLayoutInfo, !ProcLayoutInfo) :-
     PLI = proc_layout_info(RttiProcLabel, EntryLabel,
         _Detism, _StackSlots, _SuccipLoc, _EvalMethod, _EffTraceLevel,
         _MaybeCallLabel, _MaxTraceRegR, _MaxTraceRegF, HeadVars, _ArgModes,
         Goal, _NeedGoalRep, _InstMap,
         _TraceSlotInfo, ForceProcIdLayout, VarSet, _VarTypes,
-        InternalMap, MaybeTableIoDecl, _NeedsAllNames, _MaybeDeepProfInfo),
+        InternalMap, MaybeTableIoDecl, _NeedsAllNames, _OISUKindFors,
+        _MaybeDeepProfInfo),
     map.to_assoc_list(InternalMap, Internals),
     compute_var_number_map(HeadVars, VarSet, Internals, Goal, VarNumMap),
 
@@ -437,7 +471,7 @@
     list.foldl(update_label_table, InternalLabelInfos, !LabelTables),
     construct_proc_layout(Params, PLI, ProcLayoutName, Kind,
         InternalLabelInfos, VarNumMap, !.LabelLayoutInfo,
-        !StringTable, !StaticCellInfo, !ProcLayoutInfo).
+        !StringTable, !TypeTable, !StaticCellInfo, !ProcLayoutInfo).
 
 %---------------------------------------------------------------------------%
 
@@ -545,20 +579,22 @@
     %
 :- pred construct_proc_layout(stack_layout_params::in, proc_layout_info::in,
     layout_name::in, proc_layout_kind::in, list(internal_label_info)::in,
-    var_num_map::in,
-    label_layouts_info::in, string_table::in, string_table::out,
+    var_num_map::in, label_layouts_info::in,
+    string_table_info::in, string_table_info::out,
+    type_table_info::in, type_table_info::out,
     static_cell_info::in, static_cell_info::out,
     proc_layouts_info::in, proc_layouts_info::out) is det.
 
-construct_proc_layout(Params, PLI, ProcLayoutName, Kind,
-        InternalLabelInfos, VarNumMap, LabelLayoutInfo,
-        !StringTable, !StaticCellInfo, !ProcLayoutInfo) :-
+construct_proc_layout(Params, PLI, ProcLayoutName, Kind, InternalLabelInfos,
+        VarNumMap, LabelLayoutInfo, !StringTable, !TypeTable,
+        !StaticCellInfo, !ProcLayoutInfo) :-
     PLI = proc_layout_info(RttiProcLabel, EntryLabel,
         Detism, StackSlots, SuccipLoc, EvalMethod, EffTraceLevel,
         MaybeCallLabel, MaxTraceRegR, MaxTraceRegF, HeadVars, ArgModes,
         Goal, NeedGoalRep, InstMap,
         TraceSlotInfo, _ForceProcIdLayout, VarSet, VarTypes,
-        InternalMap, MaybeTableInfo, NeedsAllNames, MaybeDeepProfInfo),
+        InternalMap, MaybeTableInfo, NeedsAllNames, OISUKindFors,
+        MaybeDeepProfInfo),
     construct_proc_traversal(Params, EntryLabel, Detism, StackSlots,
         SuccipLoc, Traversal),
     PredId = RttiProcLabel ^ rpl_pred_id,
@@ -600,6 +636,7 @@
             MaybeExecTraceSlotName = no
         ),
         ModuleInfo = Params ^ slp_module_info,
+        module_info_get_name(ModuleInfo, ModuleName),
         DeepProfiling = Params ^ slp_deep_profiling,
         (
             ( NeedGoalRep = trace_needs_body_rep
@@ -608,14 +645,22 @@
         ->
             (
                 DeepProfiling = yes,
-                IncludeVarTable = include_variable_table
+                IncludeVarNameTable = include_var_name_table,
+                (
+                    OISUKindFors = [],
+                    IncludeVarTypes = do_not_include_var_types
+                ;
+                    OISUKindFors = [_ | _],
+                    IncludeVarTypes = include_var_types
+                )
             ;
                 DeepProfiling = no,
-                IncludeVarTable = do_not_include_variable_table
+                IncludeVarNameTable = do_not_include_var_name_table,
+                IncludeVarTypes = do_not_include_var_types
             ),
 
             % When the program is compiled with deep profiling, use
-            % the version of the procedure saved before the deep profiling
+            % the version of the procedure saved *before* the deep profiling
             % transformation as the program representation.
             (
                 MaybeDeepProfInfo = yes(DeepProfInfo),
@@ -643,8 +688,8 @@
             ),
             represent_proc_as_bytecodes(BytecodeHeadVars, BytecodeBody,
                 BytecodeInstMap, BytecodeVarTypes, BytecodeVarNumMap,
-                ModuleInfo, IncludeVarTable, BytecodeDetism, !StringTable,
-                ProcBytes),
+                ModuleInfo, IncludeVarNameTable, IncludeVarTypes,
+                BytecodeDetism, !StringTable, !TypeTable, ProcBytes),
 
             % Calling find_sequence on ProcBytes is very unlikely to find
             % any matching sequences, though there is no reason why we
@@ -678,11 +723,9 @@
             ),
             MaybeProcBytesSlotName = no
         ),
-        module_info_get_name(ModuleInfo, ModuleName),
-        ModuleCommonLayoutName = module_common_layout(ModuleName),
+        ModuleLayoutName = module_layout(ModuleName),
         More = proc_id_and_more(MaybeProcStaticSlotName,
-            MaybeExecTraceSlotName, MaybeProcBytesSlotName,
-            ModuleCommonLayoutName)
+            MaybeExecTraceSlotName, MaybeProcBytesSlotName, ModuleLayoutName)
     ),
 
     ProcLayout = proc_layout_data(RttiProcLabel, Traversal, More),
@@ -872,7 +915,7 @@
     maybe(proc_layout_table_info)::in, bool::in, var_num_map::in,
     list(internal_label_info)::in, layout_slot_name::out,
     label_layouts_info::in,
-    string_table::in, string_table::out,
+    string_table_info::in, string_table_info::out,
     exec_traces_info::in, exec_traces_info::out) is det.
 
 construct_exec_trace_layout(Params, RttiProcLabel, EvalMethod,
@@ -1167,7 +1210,7 @@
 
 :- pred construct_var_name_vector(var_num_map::in,
     bool::in, int::out, list(int)::out,
-    string_table::in, string_table::out) is det.
+    string_table_info::in, string_table_info::out) is det.
 
 construct_var_name_vector(VarNumMap, NeedsAllNames, MaxVarNum, Offsets,
         !StringTable) :-
@@ -1198,7 +1241,7 @@
 
 :- pred construct_var_name_rvals(assoc_list(int, string)::in,
     int::in, int::in, int::out, list(int)::out,
-    string_table::in, string_table::out) is det.
+    string_table_info::in, string_table_info::out) is det.
 
 construct_var_name_rvals([], _CurNum, MaxNum, MaxNum, [], !StringTable).
 construct_var_name_rvals(VarNamesHeadTail @ [Var - Name | VarNamesTail],
@@ -1353,7 +1396,7 @@
 :- pred construct_internal_layout(stack_layout_params::in,
     proc_label::in, layout_name::in, var_num_map::in,
     pair(int, internal_layout_info)::in, internal_label_info::out,
-    string_table::in, string_table::out,
+    string_table_info::in, string_table_info::out,
     static_cell_info::in, static_cell_info::out,
     label_layouts_info::in, label_layouts_info::out) is det.
 
@@ -1367,7 +1410,7 @@
         map.init(TraceTypeVarMap),
         MaybeUserInfo = no
     ;
-        Trace = yes(trace_port_layout_info(_,_,_,_, MaybeUserInfo,
+        Trace = yes(trace_port_layout_info(_, _, _, _, MaybeUserInfo,
             TraceLayout)),
         TraceLayout = layout_label_info(TraceLiveVarSet, TraceTypeVarMap)
     ),
@@ -2575,193 +2618,5 @@
         StaticCodeAddr, UnboxedFloat, RttiLineNumbers).
 
 %---------------------------------------------------------------------------%
-%
-% The string_table data structure.
-%
-
-:- type string_table
-    --->    string_table(
-                % Maps strings to their offsets.
-                map(string, int),
-
-                % The list of strings so far, in reverse order.
-                list(string),
-
-                % The next available offset.
-                int
-            ).
-
-:- func init_string_table = string_table.
-
-init_string_table = !:StringTable :-
-    map.init(StringMap0),
-    !:StringTable = string_table(StringMap0, [], 0),
-    lookup_string_in_table("", _, !StringTable),
-    lookup_string_in_table("<too many variables>", _, !StringTable).
-
-lookup_string_in_table(String, StringCode, !StringTable) :-
-    % The encoding used here is decoded by MR_name_in_string_table
-    % in runtime/mercury_stack_layout.c. The code here and there
-    % must be kept in sync.
-    (
-        is_var_name_in_special_form(String, KindCode, MaybeBaseName, N),
-        N < int.unchecked_left_shift(1, 10),
-        (
-            MaybeBaseName = yes(BaseName),
-            lookup_raw_string_in_table(BaseName, MaybeOffset, !StringTable),
-            MaybeOffset = yes(Offset),
-            Offset < int.unchecked_left_shift(1, 16)
-        ;
-            MaybeBaseName = no,
-            Offset = 0
-        )
-    ->
-        % | ... offset ... | ... N ... | Kind | 1 |
-        % special form indication: 1 bit:   bit 0
-        % kind indication:         5 bits:  bits 1-5
-        % N:                       10 bits: bits 6-15
-        % Offset:                  16 bits: bits 16-31
-        StringCode = 1 \/
-            int.unchecked_left_shift(KindCode, 1) \/
-            int.unchecked_left_shift(N, 6) \/
-            int.unchecked_left_shift(Offset, 16)
-    ;
-        lookup_raw_string_in_table(String, MaybeOffset, !StringTable),
-        (
-            MaybeOffset = yes(Offset)
-        ;
-            MaybeOffset = no,
-            % Says that the name of the variable is "TOO_MANY_VARIABLES".
-            Offset = 1
-        ),
-        StringCode = int.unchecked_left_shift(Offset, 1)
-    ).
-
-:- pred is_var_name_in_special_form(string::in,
-    int::out, maybe(string)::out, int::out) is semidet.
-
-is_var_name_in_special_form(String, KindCode, MaybeBaseName, N) :-
-    % state_var.m constructs variable names that always contain
-    % the state var name, and usually but not always a numeric suffix.
-    % The numeric suffic may be zero or positive. We could represent
-    % the lack of a suffix using a negative number, but mixing unsigned
-    % and signed fields in a single word is tricky, especially since
-    % the size of the variable name descriptor word we generate (32 bits)
-    % may or may not be the same as the word size of the compiler.
-    % Instead, we simply add one to any actual suffix values, and use
-    % zero to represent the absence of a numeric suffix.
-
-    % polymorphism.m adds a numeric suffix but no type name
-    % to type_ctor_infos and type_infos.
-
-    % polymorphism.m adds a class id but no numeric suffix to
-    % base_typeclass_infos and typeclass_infos. Since the usual string table
-    % already does a good enough job for these, the code for handling them
-    % specially is commented out.
-
-    ( string.remove_prefix("STATE_VARIABLE_", String, NoPrefix) ->
-        KindCode = 0,
-        string.to_char_list(NoPrefix, NoPrefixChars),
-        ( find_number_suffix(NoPrefixChars, BaseNameChars, Num) ->
-            string.from_char_list(BaseNameChars, BaseName),
-            MaybeBaseName = yes(BaseName),
-            N = Num + 1
-        ;
-            MaybeBaseName = yes(NoPrefix),
-            N = 0
-        )
-    ; string.remove_prefix("TypeCtorInfo_", String, NoPrefix) ->
-        ( string.to_int(NoPrefix, Num) ->
-            KindCode = 1,
-            MaybeBaseName = no,
-            N = Num
-        ;
-            fail
-        )
-    ; string.remove_prefix("TypeInfo_", String, NoPrefix) ->
-        ( string.to_int(NoPrefix, Num) ->
-            KindCode = 2,
-            MaybeBaseName = no,
-            N = Num
-        ;
-            fail
-        )
-%   ; string.remove_prefix("BaseTypeClassInfo_for_", String, NoPrefix) ->
-%       KindCode = 3,
-%       MaybeBaseName = yes(NoPrefix),
-%       N = 0
-%   ; string.remove_prefix("TypeClassInfo_for_", String, NoPrefix) ->
-%       KindCode = 4,
-%       MaybeBaseName = yes(NoPrefix),
-%       N = 0
-    ; string.remove_prefix("PolyConst", String, NoPrefix) ->
-        ( string.to_int(NoPrefix, Num) ->
-            KindCode = 5,
-            MaybeBaseName = no,
-            N = Num
-        ;
-            fail
-        )
-    ;
-        fail
-    ).
-
-    % Given e.g. "Info_15" as input, we return "Info" as BeforeNum
-    % and 15 as Num.
-    %
-:- pred find_number_suffix(list(char)::in, list(char)::out, int::out)
-    is semidet.
-
-find_number_suffix(String, BeforeNum, Num) :-
-    list.reverse(String, RevString),
-    rev_find_number_suffix(RevString, 0, Num, 1, Scale, RevRest),
-    Scale > 1,
-    list.reverse(RevRest, BeforeNum).
-
-:- pred rev_find_number_suffix(list(char)::in, int::in, int::out,
-    int::in, int::out, list(char)::out) is semidet.
-
-rev_find_number_suffix([RevHead | RevTail], !Num, !Scale, RevRest) :-
-    ( char.digit_to_int(RevHead, Digit) ->
-        !:Num = !.Num + (!.Scale * Digit),
-        !:Scale = !.Scale * 10,
-        rev_find_number_suffix(RevTail, !Num, !Scale, RevRest)
-    ; RevHead = '_' ->
-        RevRest = RevTail
-    ;
-        fail
-    ).
-
-:- pred lookup_raw_string_in_table(string::in, maybe(int)::out,
-    string_table::in, string_table::out) is det.
-
-lookup_raw_string_in_table(String, MaybeOffset, !StringTable) :-
-    !.StringTable = string_table(TableMap0, TableList0, TableOffset0),
-    ( map.search(TableMap0, String, OldOffset) ->
-        MaybeOffset = yes(OldOffset)
-    ;
-        Length = string.count_utf8_code_units(String),
-        TableOffset = TableOffset0 + Length + 1,
-        % We use a 32 bit unsigned integer to represent the offset.
-        % Computing that limit exactly without getting an overflow
-        % or using unportable code isn't trivial. The code below
-        % is overly conservative, requiring the offset to be
-        % representable in only 30 bits. The over-conservatism
-        % should not be an issue; the machine will run out of
-        % virtual memory before the test below fails, for the
-        % next several years anyway. (Compiling a module that has
-        % a 1 Gb string table will require several tens of Gb
-        % of other compiler structures.)
-        TableOffset < (1 << ((4 * byte_bits) - 2))
-    ->
-        MaybeOffset = yes(TableOffset0),
-        map.det_insert(String, TableOffset0, TableMap0, TableMap),
-        TableList = [String | TableList0],
-        !:StringTable = string_table(TableMap, TableList, TableOffset)
-    ;
-        MaybeOffset = no
-    ).
-
-%---------------------------------------------------------------------------%
 :- end_module ll_backend.stack_layout.
 %---------------------------------------------------------------------------%
cvs diff: Diffing compiler/notes
Index: compiler/notes/compiler_design.html
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/notes/compiler_design.html,v
retrieving revision 1.158
diff -u -b -r1.158 compiler_design.html
--- compiler/notes/compiler_design.html	8 Oct 2012 04:14:48 -0000	1.158
+++ compiler/notes/compiler_design.html	24 Oct 2012 03:50:13 -0000
@@ -1522,7 +1522,9 @@
   collected in continuation_info.m.
 
   Stack_layout.m uses prog_rep.m to generate bytecode representations
-  of procedure bodies for use by the declarative debugger.
+  of procedure bodies for use by the declarative debugger and the deep
+  profiler, and prog_rep_tables.m to generate the string tables and type tables
+  that these representations use.
 
 <li> Type_ctor_info structures and stack_layout structures both contain
   pseudo_type_infos, which are type_infos with holes for type variables;
cvs diff: Diffing deep_profiler
Index: deep_profiler/autopar_calc_overlap.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/autopar_calc_overlap.m,v
retrieving revision 1.4
diff -u -b -r1.4 autopar_calc_overlap.m
--- deep_profiler/autopar_calc_overlap.m	30 Mar 2012 04:05:11 -0000	1.4
+++ deep_profiler/autopar_calc_overlap.m	24 Oct 2012 03:50:13 -0000
@@ -82,7 +82,8 @@
     Overlap0 = peo_empty_conjunct,
 
     SharedVars = ip_calc_sharedvars_set(!.Parallelisation),
-    CostData0 = parallelisation_cost_data(SharedVars, Overlap0, Metrics0, init),
+    CostData0 = parallelisation_cost_data(SharedVars, Overlap0, Metrics0,
+        init),
     NumMiddleGoals = ip_get_num_goals_middle(!.Parallelisation),
     list.foldl3(calculate_parallel_cost_step(Info, NumMiddleGoals), ParConj,
         1, _, 0, _, CostData0, CostData),
Index: deep_profiler/autopar_find_best_par.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/autopar_find_best_par.m,v
retrieving revision 1.7
diff -u -b -r1.7 autopar_find_best_par.m
--- deep_profiler/autopar_find_best_par.m	4 Apr 2012 01:45:59 -0000	1.7
+++ deep_profiler/autopar_find_best_par.m	24 Oct 2012 03:50:13 -0000
@@ -790,7 +790,8 @@
     conjuncts_are_dependent::out) is det.
 
 par_conj_overlap_is_dependent(peo_empty_conjunct, conjuncts_are_independent).
-par_conj_overlap_is_dependent(peo_conjunction(Left, _, VarSet0), IsDependent) :-
+par_conj_overlap_is_dependent(peo_conjunction(Left, _, VarSet0),
+        IsDependent) :-
     par_conj_overlap_is_dependent(Left, IsDependent0),
     (
         IsDependent0 = conjuncts_are_dependent(VarSetLeft),
@@ -862,7 +863,8 @@
 % XXX
 % :- semipure pred add_goals_into_first_par_conj(
 %     bnb_state(full_parallelisation)::in,
-%     incomplete_parallelisation::in, incomplete_parallelisation::out) is multi.
+%     incomplete_parallelisation::in, incomplete_parallelisation::out)
+%     is multi.
 %
 % add_goals_into_first_par_conj(BNBState, !Parallelisation) :-
 %     FirstGoal0 = !.Parallelisation ^ ip_first_par_goal,
@@ -872,8 +874,8 @@
 %         Goal = lookup(Goals, FirstGoal0 - 1),
 %         can_parallelise_goal(Goal),
 %
-%         % There are goals before the parallel conjunction that can be included
-%         % in the parallel conjunction.
+%         % There are goals before the parallel conjunction that can be
+%         % included in the parallel conjunction.
 %         add_one_goal_into_first_par_conj(!Parallelisation),
 %         semipure test_parallelisation(BNBState, !Parallelisation),
 %         semipure add_goals_into_first_par_conj(BNBState, !Parallelisation)
@@ -883,7 +885,8 @@
 %
 % :- semipure pred add_goals_into_last_par_conj(
 %     bnb_state(full_parallelisation)::in,
-%     incomplete_parallelisation::in, incomplete_parallelisation::out) is multi.
+%     incomplete_parallelisation::in, incomplete_parallelisation::out)
+%     is multi.
 %
 % add_goals_into_last_par_conj(BNBState, !Parallelisation) :-
 %     NumGoals = ip_get_num_goals(!.Parallelisation),
Index: deep_profiler/autopar_reports.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/autopar_reports.m,v
retrieving revision 1.4
diff -u -b -r1.4 autopar_reports.m
--- deep_profiler/autopar_reports.m	26 Sep 2011 07:08:57 -0000	1.4
+++ deep_profiler/autopar_reports.m	24 Oct 2012 03:50:13 -0000
@@ -27,7 +27,7 @@
 :- pred print_feedback_report(string::in, feedback_info::in, io::di, io::uo)
     is det.
 
-:- pred create_candidate_parallel_conj_report(var_table::in,
+:- pred create_candidate_parallel_conj_report(var_name_table::in,
     candidate_par_conjunction(pard_goal)::in, cord(string)::out) is det.
 
 %-----------------------------------------------------------------------------%
@@ -146,7 +146,7 @@
     pair(T, candidate_par_conjunctions_proc)::in, int::in, int::out) is det.
 
 count_conjunctions_in_procs(_ - Cands, !NumConjs) :-
-    Cands = candidate_par_conjunctions_proc(_VarTable, _Pushes, Conjs),
+    Cands = candidate_par_conjunctions_proc(_VarNameTable, _Pushes, Conjs),
     !:NumConjs = !.NumConjs + length(Conjs).
 
 :- pred best_par_algorithm_string(best_par_algorithm::in, string::out) is det.
@@ -168,11 +168,11 @@
 
 create_candidate_parallel_conj_proc_report(Proc - CandidateParConjunctionProc,
         Report) :-
-    CandidateParConjunctionProc = candidate_par_conjunctions_proc(VarTable,
+    CandidateParConjunctionProc = candidate_par_conjunctions_proc(VarNameTable,
         PushGoals, CandidateParConjunctions),
     print_proc_label_to_string(Proc, ProcString),
     list.map(create_push_goal_report, PushGoals, PushGoalReports),
-    list.map(create_candidate_parallel_conj_report(VarTable),
+    list.map(create_candidate_parallel_conj_report(VarNameTable),
         CandidateParConjunctions, CandidateParConjunctionReports),
     Header = string.format("    %s\n", [s(ProcString)]),
     Report = cord.singleton(Header) ++
@@ -197,7 +197,7 @@
     pair(string_proc_label, candidate_par_conjunctions_proc)::in,
     cord(string)::out) is det.
 
-create_candidate_parallel_conj_report(VarTable, CandidateParConjunction,
+create_candidate_parallel_conj_report(VarNameTable, CandidateParConjunction,
         Report) :-
     CandidateParConjunction = candidate_par_conjunction(GoalPathString,
         MaybePushGoal, FirstConjNum, IsDependent, GoalsBefore, GoalsBeforeCost,
@@ -211,7 +211,7 @@
         DependanceString = "no"
     ;
         IsDependent = conjuncts_are_dependent(Vars),
-        map(lookup_var_name(VarTable), Vars, VarNames),
+        map(lookup_var_name(VarNameTable), Vars, VarNames),
         VarsString = join_list(", ", to_sorted_list(VarNames)),
         DependanceString = format("on %s", [s(VarsString)])
     ),
@@ -277,19 +277,19 @@
     ),
     some [!ConjNum] (
         !:ConjNum = FirstConjNum,
-        format_sequential_conjunction(VarTable, 4, RevGoalPath,
+        format_sequential_conjunction(VarNameTable, 4, RevGoalPath,
             GoalsBefore, GoalsBeforeCost, !.ConjNum, ReportGoalsBefore0),
         ReportGoalsBefore = indent(3) ++ singleton("Goals before:\n") ++
             ReportGoalsBefore0,
 
         !:ConjNum = !.ConjNum + length(GoalsBefore),
-        format_parallel_conjunction(VarTable, 4, RevGoalPath,
+        format_parallel_conjunction(VarNameTable, 4, RevGoalPath,
             !.ConjNum, Conjs, ReportParConj0),
         ReportParConj = indent(3) ++ singleton("Parallel conjunction:\n") ++
             ReportParConj0,
 
         !:ConjNum = !.ConjNum + 1,
-        format_sequential_conjunction(VarTable, 4, RevGoalPath,
+        format_sequential_conjunction(VarNameTable, 4, RevGoalPath,
             GoalsAfter, GoalsAfterCost, !.ConjNum, ReportGoalsAfter0),
         ReportGoalsAfter = indent(3) ++ singleton("Goals after:\n") ++
             ReportGoalsAfter0
@@ -297,26 +297,26 @@
     Report = Header1 ++ Header2 ++ Header3 ++ ReportGoalsBefore ++ nl
         ++ ReportParConj ++ nl ++ ReportGoalsAfter ++ nl.
 
-:- pred format_parallel_conjunction(var_table::in, int::in,
+:- pred format_parallel_conjunction(var_name_table::in, int::in,
     reverse_goal_path::in, int::in,
     list(seq_conj(pard_goal))::in, cord(string)::out) is det.
 
-format_parallel_conjunction(VarTable, Indent, RevGoalPath, ConjNum, Conjs,
+format_parallel_conjunction(VarNameTable, Indent, RevGoalPath, ConjNum, Conjs,
         !:Report) :-
     IndentStr = indent(Indent),
     !:Report = IndentStr ++ singleton("(\n"),
-    format_parallel_conjuncts(VarTable, Indent,
+    format_parallel_conjuncts(VarNameTable, Indent,
         rgp_cons(RevGoalPath, step_conj(ConjNum)), 1, Conjs, !Report).
 
-:- pred format_parallel_conjuncts(var_table::in, int::in,
+:- pred format_parallel_conjuncts(var_name_table::in, int::in,
     reverse_goal_path::in, int::in, list(seq_conj(pard_goal))::in,
     cord(string)::in, cord(string)::out) is det.
 
-format_parallel_conjuncts(_VarTable, Indent, _RevGoalPath, _ConjNum0,
+format_parallel_conjuncts(_VarNameTable, Indent, _RevGoalPath, _ConjNum0,
         [], !Report) :-
     IndentStr = indent(Indent),
     !:Report = snoc(!.Report ++ IndentStr, ")\n").
-format_parallel_conjuncts(VarTable, Indent, RevGoalPath, ConjNum0,
+format_parallel_conjuncts(VarNameTable, Indent, RevGoalPath, ConjNum0,
         [Conj | Conjs], !Report) :-
     Conj = seq_conj(Goals),
     (
@@ -328,16 +328,16 @@
         (
             GoalsTail = [],
             % A singleton conjunction gets printed as a single goal.
-            print_goal_to_strings(print_goal_info(id, VarTable), Indent + 1,
-                RevInnerGoalPath, Goal, ConjReport)
+            print_goal_to_strings(print_goal_info(id, VarNameTable),
+                Indent + 1, RevInnerGoalPath, Goal, ConjReport)
         ;
             GoalsTail = [_ | _],
             Cost = foldl(
                 (func(GoalI, Acc) =
                     Acc + GoalI ^ goal_annotation ^ pga_cost_percall),
                 Goals, 0.0),
-            format_sequential_conjunction(VarTable, Indent + 1,
-                RevInnerGoalPath, Goals, Cost, 1, ConjReport)
+            format_sequential_conjunction(VarNameTable,
+                Indent + 1, RevInnerGoalPath, Goals, Cost, 1, ConjReport)
         )
     ),
     !:Report = !.Report ++ ConjReport,
@@ -348,14 +348,14 @@
         !:Report = snoc(!.Report ++ indent(Indent), "&\n")
     ),
     ConjNum = ConjNum0 + 1,
-    format_parallel_conjuncts(VarTable, Indent, RevGoalPath, ConjNum,
+    format_parallel_conjuncts(VarNameTable, Indent, RevGoalPath, ConjNum,
         Conjs, !Report).
 
-:- pred format_sequential_conjunction(var_table::in, int::in,
+:- pred format_sequential_conjunction(var_name_table::in, int::in,
     reverse_goal_path::in, list(pard_goal)::in, float::in, int::in,
     cord(string)::out) is det.
 
-format_sequential_conjunction(VarTable, Indent, RevGoalPath, Goals, Cost,
+format_sequential_conjunction(VarNameTable, Indent, RevGoalPath, Goals, Cost,
         FirstConjNum, !:Report) :-
     !:Report = empty,
     ( FirstConjNum = 1 ->
@@ -370,17 +370,17 @@
     ;
         true
     ),
-    format_sequential_conjuncts(VarTable, Indent, RevGoalPath, Goals,
+    format_sequential_conjuncts(VarNameTable, Indent, RevGoalPath, Goals,
         FirstConjNum, _, !Report).
 
-:- pred format_sequential_conjuncts(var_table::in, int::in,
+:- pred format_sequential_conjuncts(var_name_table::in, int::in,
     reverse_goal_path::in, list(pard_goal)::in, int::in, int::out,
     cord(string)::in, cord(string)::out) is det.
 
 format_sequential_conjuncts(_, _, _, [], !ConjNum, !Report).
-format_sequential_conjuncts(VarTable, Indent, RevGoalPath, [Conj | Conjs],
+format_sequential_conjuncts(VarNameTable, Indent, RevGoalPath, [Conj | Conjs],
         !ConjNum, !Report) :-
-    print_goal_to_strings(print_goal_info(id, VarTable), Indent,
+    print_goal_to_strings(print_goal_info(id, VarNameTable), Indent,
         rgp_cons(RevGoalPath, step_conj(!.ConjNum)), Conj, ConjReport),
     !:Report = !.Report ++ ConjReport,
     !:ConjNum = !.ConjNum + 1,
@@ -389,7 +389,7 @@
     ;
         Conjs = [_ | _],
         !:Report = !.Report ++ indent(Indent) ++ singleton(",\n"),
-        format_sequential_conjuncts(VarTable, Indent, RevGoalPath, Conjs,
+        format_sequential_conjuncts(VarNameTable, Indent, RevGoalPath, Conjs,
             !ConjNum, !Report)
     ).
 
@@ -397,10 +397,10 @@
     pred(print_goal_annotation_to_strings/3) is format_pard_goal_annotation
 ].
 
-:- pred format_pard_goal_annotation(var_table::in, pard_goal_annotation::in,
-    cord(cord(string))::out) is det.
+:- pred format_pard_goal_annotation(var_name_table::in,
+    pard_goal_annotation::in, cord(cord(string))::out) is det.
 
-format_pard_goal_annotation(VarTable, GoalAnnotation, Report) :-
+format_pard_goal_annotation(VarNameTable, GoalAnnotation, Report) :-
     GoalAnnotation = pard_goal_annotation(CostPercall, CostAboveThreshold,
         Productions, Consumptions),
     (
@@ -412,9 +412,9 @@
     ),
     CostLine = singleton(format("cost: %s (%s)",
         [s(two_decimal_fraction(CostPercall)), s(CostAboveThresholdStr)])),
-    format_var_use_report(VarTable, productions, Productions,
+    format_var_use_report(VarNameTable, productions, Productions,
         ProductionsReport),
-    format_var_use_report(VarTable, consumptions, Consumptions,
+    format_var_use_report(VarNameTable, consumptions, Consumptions,
         ConsumptionsReport),
     Report = singleton(CostLine) ++ ProductionsReport ++ ConsumptionsReport.
 
@@ -426,24 +426,24 @@
 
 consumptions = "Consumptions".
 
-:- pred format_var_use_report(var_table::in, string::in,
+:- pred format_var_use_report(var_name_table::in, string::in,
     assoc_list(var_rep, float)::in, cord(cord(string))::out) is det.
 
-format_var_use_report(VarTable, Label, List, Report) :-
+format_var_use_report(VarNameTable, Label, List, Report) :-
     (
         List = [_ | _],
-        list.map(format_var_use_line(VarTable), List, Lines),
+        list.map(format_var_use_line(VarNameTable), List, Lines),
         Report = singleton(singleton(Label ++ ":")) ++ cord.from_list(Lines)
     ;
         List = [],
         Report = empty
     ).
 
-:- pred format_var_use_line(var_table::in, pair(var_rep, float)::in,
+:- pred format_var_use_line(var_name_table::in, pair(var_rep, float)::in,
     cord(string)::out) is det.
 
-format_var_use_line(VarTable, Var - Use, singleton(String)) :-
+format_var_use_line(VarNameTable, Var - Use, singleton(String)) :-
     format("    %s: %s", [s(VarName), s(two_decimal_fraction(Use))], String),
-    lookup_var_name(VarTable, Var, VarName).
+    lookup_var_name(VarNameTable, Var, VarName).
 
 %-----------------------------------------------------------------------------%
Index: deep_profiler/autopar_search_callgraph.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/autopar_search_callgraph.m,v
retrieving revision 1.9
diff -u -b -r1.9 autopar_search_callgraph.m
--- deep_profiler/autopar_search_callgraph.m	30 Mar 2012 04:05:11 -0000	1.9
+++ deep_profiler/autopar_search_callgraph.m	24 Oct 2012 03:50:13 -0000
@@ -415,12 +415,13 @@
     candidate_par_conjunctions_proc(T)::out) is det.
 
 merge_candidate_par_conjs_proc(A, B, Result) :-
-    A = candidate_par_conjunctions_proc(VarTableA, PushGoalsA, CPCsA),
-    B = candidate_par_conjunctions_proc(VarTableB, PushGoalsB, CPCsB),
+    A = candidate_par_conjunctions_proc(VarNameTableA, PushGoalsA, CPCsA),
+    B = candidate_par_conjunctions_proc(VarNameTableB, PushGoalsB, CPCsB),
     CPCs = CPCsA ++ CPCsB,
     merge_pushes_for_proc(PushGoalsA ++ PushGoalsB, PushGoals),
-    ( VarTableA = VarTableB ->
-        Result = candidate_par_conjunctions_proc(VarTableA, PushGoals, CPCs)
+    ( VarNameTableA = VarNameTableB ->
+        Result = candidate_par_conjunctions_proc(VarNameTableA, PushGoals,
+            CPCs)
     ;
         unexpected($module, $pred, "var tables do not match")
     ).
@@ -512,7 +513,7 @@
             MaybeProcRep = ok(ProcRep),
             ProcDefnRep = ProcRep ^ pr_defn,
             Goal0 = ProcDefnRep ^ pdr_goal,
-            VarTable = ProcDefnRep ^ pdr_var_table,
+            VarNameTable = ProcDefnRep ^ pdr_var_name_table,
 
             % Label the goals with IDs.
             label_goals(LastGoalId, ContainingGoalMap, Goal0, Goal),
@@ -551,7 +552,7 @@
                 Info = implicit_parallelism_info(Deep, ProgRep, Opts,
                     CliquePtr, CallSitesMap, RecursiveCallSiteCostMap,
                     ContainingGoalMap, CoverageArray, InstMapArray,
-                    RecursionType, VarTable, ProcLabel),
+                    RecursionType, VarNameTable, ProcLabel),
                 goal_to_pard_goal(Info, rgp_nil, Goal, PardGoal, !Messages),
                 goal_get_conjunctions_worth_parallelising(Info,
                     rgp_nil, PardGoal, _, CandidatesCord0, PushesCord,
@@ -569,7 +570,7 @@
                         Candidates0 = [_ | _],
                         merge_pushes_for_proc(Pushes, MergedPushes),
                         CandidateProc = candidate_par_conjunctions_proc(
-                            VarTable, MergedPushes, Candidates0),
+                            VarNameTable, MergedPushes, Candidates0),
                         Candidates = map.singleton(ProcLabel, CandidateProc)
                     )
                 ;
@@ -594,22 +595,24 @@
     ).
 
 :- pred build_candidate_par_conjunction_maps(string_proc_label::in,
-    var_table::in, candidate_par_conjunction(pard_goal_detail)::in,
+    var_name_table::in, candidate_par_conjunction(pard_goal_detail)::in,
     candidate_par_conjunctions::in, candidate_par_conjunctions::out) is det.
 
-build_candidate_par_conjunction_maps(ProcLabel, VarTable, Candidate, !Map) :-
+build_candidate_par_conjunction_maps(ProcLabel, VarNameTable, Candidate,
+        !Map) :-
     % XXX: This predicate will also need to add pushes to CandidateProc.
     ( map.search(!.Map, ProcLabel, CandidateProc0) ->
-        CandidateProc0 = candidate_par_conjunctions_proc(VarTablePrime,
+        CandidateProc0 = candidate_par_conjunctions_proc(VarNameTablePrime,
             PushGoals, CPCs0),
         CPCs = [Candidate | CPCs0],
-        expect(unify(VarTable, VarTablePrime), $module, $pred,
+        expect(unify(VarNameTable, VarNameTablePrime), $module, $pred,
             "var tables do not match")
     ;
         CPCs = [Candidate],
         PushGoals = []
     ),
-    CandidateProc = candidate_par_conjunctions_proc(VarTable, PushGoals, CPCs),
+    CandidateProc = candidate_par_conjunctions_proc(VarNameTable, PushGoals,
+        CPCs),
     map.set(ProcLabel, CandidateProc, !Map).
 
 %----------------------------------------------------------------------------%
Index: deep_profiler/autopar_search_goals.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/autopar_search_goals.m,v
retrieving revision 1.7
diff -u -b -r1.7 autopar_search_goals.m
--- deep_profiler/autopar_search_goals.m	30 Mar 2012 04:05:11 -0000	1.7
+++ deep_profiler/autopar_search_goals.m	24 Oct 2012 03:50:13 -0000
@@ -752,7 +752,7 @@
 
                 convert_candidate_par_conjunction(
                     pard_goal_detail_to_pard_goal, Candidate, FBCandidate),
-                VarTable = Info ^ ipi_var_table,
+                VarTable = Info ^ ipi_var_name_table,
                 create_candidate_parallel_conj_report(VarTable,
                     FBCandidate, Report),
                 print_proc_label_to_string(ProcLabel, ProcLabelString),
Index: deep_profiler/autopar_types.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/autopar_types.m,v
retrieving revision 1.4
diff -u -b -r1.4 autopar_types.m
--- deep_profiler/autopar_types.m	4 Apr 2012 01:46:00 -0000	1.4
+++ deep_profiler/autopar_types.m	24 Oct 2012 03:50:13 -0000
@@ -53,7 +53,7 @@
                 ipi_coverage_array  :: goal_attr_array(coverage_info),
                 ipi_inst_map_array  :: goal_attr_array(inst_map_info),
                 ipi_recursion_type  :: recursion_type,
-                ipi_var_table       :: var_table,
+                ipi_var_name_table  :: var_name_table,
                 ipi_proc_label      :: string_proc_label
             ).
 
Index: deep_profiler/branch_and_bound.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/branch_and_bound.m,v
retrieving revision 1.4
diff -u -b -r1.4 branch_and_bound.m
--- deep_profiler/branch_and_bound.m	27 Jan 2011 08:03:53 -0000	1.4
+++ deep_profiler/branch_and_bound.m	24 Oct 2012 03:50:13 -0000
@@ -53,7 +53,8 @@
     % Use a branch and bound search to return the set of BestSolutions
     % according to the ObjectiveFn that GenerateSolutions can generate.
     %
-    % Note that more optimal solutions return _smaller_ values from ObjectiveFn.
+    % Note that more optimal solutions return _smaller_ values
+    % from ObjectiveFn.
     %
     % The set of best solutions is returned, it is up to the caller to break
     % ties if necessary.
Index: deep_profiler/coverage.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/coverage.m,v
retrieving revision 1.17
diff -u -b -r1.17 coverage.m
--- deep_profiler/coverage.m	16 May 2012 06:27:09 -0000	1.17
+++ deep_profiler/coverage.m	24 Oct 2012 03:50:13 -0000
@@ -189,8 +189,8 @@
         array.lookup(DynamicArray, Num, Count),
         CP = coverage_point(Count, GoalPath, CPType),
         !:CoveragePoints = [CP | !.CoveragePoints],
-        coverage_point_arrays_to_list_2(Num + 1, Max, StaticArray, DynamicArray,
-            !CoveragePoints)
+        coverage_point_arrays_to_list_2(Num + 1, Max,
+            StaticArray, DynamicArray, !CoveragePoints)
     ;
         true
     ).
@@ -230,8 +230,9 @@
     %       algorithm to proceed past the problem and allow the programmer to
     %       view erroneous output.
     %
-procrep_annotate_with_coverage(ProcRep, OwnProf, CallSites, SolnsCoveragePoints,
-        BranchCoveragePoints, ContainingGoalMap, LastGoalId, CoverageArray) :-
+procrep_annotate_with_coverage(ProcRep, OwnProf, CallSites,
+        SolnsCoveragePoints, BranchCoveragePoints, ContainingGoalMap,
+        LastGoalId, CoverageArray) :-
     GoalRep = ProcRep ^ pr_defn ^ pdr_goal,
     ProcLabel = ProcRep ^ pr_id,
     goal_annotate_with_coverage(ProcLabel, GoalRep, OwnProf,
@@ -587,7 +588,8 @@
             SumBeforeExecCount = 0
         )
     ->
-        BeforeCase = before_coverage(SwitchBeforeExecCount - SumBeforeExecCount)
+        BeforeCase =
+            before_coverage(SwitchBeforeExecCount - SumBeforeExecCount)
     ;
         % Search for a coverage point for this case.
         RevCaseGoalPath = map.lookup(Info ^ cri_goal_path_map,
@@ -614,7 +616,8 @@
     goal_attr_array(coverage_info)::gaa_di,
     goal_attr_array(coverage_info)::gaa_uo) is det.
 
-ite_annotate_coverage(Cond, Then, Else, Info, RevGoalPath, Before, After, !Array) :-
+ite_annotate_coverage(Cond, Then, Else, Info, RevGoalPath, Before, After,
+        !Array) :-
     CondDetism = Cond ^ goal_detism_rep,
     GoalPathMap = Info ^ cri_goal_path_map,
 
Index: deep_profiler/create_report.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/create_report.m,v
retrieving revision 1.37
diff -u -b -r1.37 create_report.m
--- deep_profiler/create_report.m	20 Oct 2012 12:17:16 -0000	1.37
+++ deep_profiler/create_report.m	24 Oct 2012 03:50:13 -0000
@@ -96,6 +96,7 @@
 
 :- import_module array.
 :- import_module char.
+:- import_module cord.
 :- import_module float.
 :- import_module int.
 :- import_module list.
@@ -161,6 +162,10 @@
             MaybeModuleGetterSettersReport),
         Report = report_module_getter_setters(MaybeModuleGetterSettersReport)
     ;
+        Cmd = deep_cmd_module_rep(ModuleName),
+        create_module_rep_report(Deep, ModuleName, MaybeModuleRepReport),
+        Report = report_module_rep(MaybeModuleRepReport)
+    ;
         Cmd = deep_cmd_top_procs(Limit, CostKind, InclDesc, Scope),
         create_top_procs_report(Deep, Limit, CostKind, InclDesc, Scope,
             MaybeTopProcsReport),
@@ -784,6 +789,45 @@
         DataStructNameChars = [FirstNameChar | LaterDataStructNameChars]
     ).
 
+
+%-----------------------------------------------------------------------------%
+%
+% Code to build a module_rep report.
+%
+
+    % Create a module_rep report, from the given data with the specified
+    % parameters.
+    %
+:- pred create_module_rep_report(deep::in, string::in,
+    maybe_error(module_rep_report)::out) is det.
+
+create_module_rep_report(Deep, ModuleName, MaybeModuleRepReport) :-
+    MaybeProgRep = Deep ^ procrep_file,
+    (
+        MaybeProgRep = yes(MaybeErrorProgRep),
+        (
+            MaybeErrorProgRep = ok(ProgRep),
+            ProgRep = prog_rep(ModuleRepMap),
+            ( map.search(ModuleRepMap, ModuleName, ModuleRep) ->
+                print_module_to_strings(ModuleRep, CordStrs),
+                Str = string.append_list(cord.list(CordStrs)),
+                ModuleRepReport = module_rep_report(ModuleName, Str),
+                MaybeModuleRepReport = ok(ModuleRepReport)
+            ;
+                Msg = string.format("There is no module named %s.\n",
+                    [s(ModuleName)]),
+                MaybeModuleRepReport = error(Msg)
+            )
+        ;
+            MaybeErrorProgRep = error(Msg),
+            MaybeModuleRepReport = error(Msg)
+        )
+    ;
+        MaybeProgRep = no,
+        Msg = "Information about module representations is not available.\n",
+        MaybeModuleRepReport = error(Msg)
+    ).
+
 %-----------------------------------------------------------------------------%
 %
 % Code to build a top_procs report.
@@ -1340,7 +1384,7 @@
         (
             MaybeProcrep = ok(Procrep),
             HeadVars = Procrep ^ pr_defn ^ pdr_head_vars,
-            VarTable = Procrep ^ pr_defn ^ pdr_var_table,
+            VarNameTable = Procrep ^ pr_defn ^ pdr_var_name_table,
             deep_lookup_clique_index(Deep, CallerPDPtr, ParentCliquePtr),
             deep_lookup_clique_index(Deep, CalleePDPtr, CalleeCliquePtr),
             create_clique_recursion_costs_report(Deep, ParentCliquePtr,
@@ -1360,7 +1404,7 @@
                 (
                     MaybeCost = ok(Cost),
                     map_foldl(call_site_dynamic_var_use_arg(Deep, CSDPtr,
-                            RecursionType, Cost, VarTable),
+                            RecursionType, Cost, VarNameTable),
                         HeadVars, Uses0, 0, _),
                     list_maybe_error_to_maybe_error_list(Uses0, MaybeUses),
                     (
@@ -1391,10 +1435,10 @@
     ).
 
 :- pred call_site_dynamic_var_use_arg(deep::in, call_site_dynamic_ptr::in,
-    recursion_type::in, float::in, var_table::in, head_var_rep::in,
+    recursion_type::in, float::in, var_name_table::in, head_var_rep::in,
     maybe_error(var_use_and_name)::out, int::in, int::out) is det.
 
-call_site_dynamic_var_use_arg(Deep, CSDPtr, RecursionType, Cost, VarTable,
+call_site_dynamic_var_use_arg(Deep, CSDPtr, RecursionType, Cost, VarNameTable,
         HeadVar, MaybeUseAndName, !ArgNum) :-
     HeadVar = head_var_rep(Var, Mode),
     var_mode_to_var_use_type(Mode, UseType),
@@ -1404,7 +1448,7 @@
         Cost, UseOptions, MaybeUse),
     (
         MaybeUse = ok(Use),
-        lookup_var_name(VarTable, Var, Name),
+        lookup_var_name(VarNameTable, Var, Name),
         MaybeUseAndName = ok(var_use_and_name(Name, Use))
     ;
         MaybeUse = error(Error),
Index: deep_profiler/display.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/display.m,v
retrieving revision 1.15
diff -u -b -r1.15 display.m
Index: deep_profiler/display_report.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/display_report.m,v
retrieving revision 1.37
diff -u -b -r1.37 display_report.m
--- deep_profiler/display_report.m	20 Oct 2012 12:17:16 -0000	1.37
+++ deep_profiler/display_report.m	24 Oct 2012 03:50:13 -0000
@@ -135,6 +135,15 @@
             Display = display(no, [display_heading(Msg)])
         )
     ;
+        Report = report_module_rep(MaybeModuleRepReport),
+        (
+            MaybeModuleRepReport = ok(ModuleRepReport),
+            display_report_module_rep(Prefs, ModuleRepReport, Display)
+        ;
+            MaybeModuleRepReport = error(Msg),
+            Display = display(no, [display_heading(Msg)])
+        )
+    ;
         Report = report_top_procs(MaybeTopProcsReport),
         (
             MaybeTopProcsReport = ok(TopProcsReport),
@@ -1165,6 +1174,9 @@
     GetterSetterCmd = deep_cmd_module_getter_setters(ModuleName),
     GetterSetterControl = display_link(deep_link(GetterSetterCmd, yes(Prefs),
         attr_str([], "Show field getters and setters"), link_class_link)),
+    RepCmd = deep_cmd_module_rep(ModuleName),
+    RepControl = display_link(deep_link(RepCmd, yes(Prefs),
+        attr_str([], "Show module representation"), link_class_link)),
 
     InactiveControls = inactive_proc_controls(Prefs, Cmd),
     FieldControls = field_controls(Prefs, Cmd),
@@ -1174,6 +1186,7 @@
     Display = display(yes(Title),
         [DisplayTable,
         display_paragraph_break, GetterSetterControl,
+        display_paragraph_break, RepControl,
         display_paragraph_break, InactiveControls,
         display_paragraph_break, FieldControls,
         display_paragraph_break, FormatControls,
@@ -1190,7 +1203,7 @@
 % Code to display a module_getter_setters report.
 %
 
-    % Create a display_report structure for a top_procedures report.
+    % Create a display_report structure for a module_getter_setters report.
     %
 :- pred display_report_module_getter_setters(preferences::in,
     module_getter_setters_report::in, display::out) is det.
@@ -1311,6 +1324,34 @@
 
 %-----------------------------------------------------------------------------%
 %
+% Code to display a module_rep report.
+%
+
+    % Create a display_report structure for a module_rep report.
+    %
+:- pred display_report_module_rep(preferences::in, module_rep_report::in,
+    display::out) is det.
+
+display_report_module_rep(Prefs, Report, Display) :-
+    Report = module_rep_report(ModuleName, ModuleRepStr),
+    Title = string.format("The representation of module %s:",
+        [s(ModuleName)]),
+
+    BodyItem = display_verbatim(ModuleRepStr),
+
+    ModuleCmd = deep_cmd_module(ModuleName),
+    ModuleControl = display_link(deep_link(ModuleCmd, yes(Prefs),
+        attr_str([], "Show all the procedures of the module"),
+        link_class_link)),
+    MenuResetQuitControls = cmds_menu_restart_quit(yes(Prefs)),
+    Controls =
+        [display_paragraph_break, ModuleControl,
+        display_paragraph_break, MenuResetQuitControls],
+
+    Display = display(yes(Title), [BodyItem | Controls]).
+
+%-----------------------------------------------------------------------------%
+%
 % Code to display a top procedures report.
 %
 
@@ -2053,7 +2094,7 @@
     % Print the coverage information for a goal, this is used by
     % print_proc_to_strings.
     %
-:- pred coverage_to_cord_string(var_table::in, coverage_info::in,
+:- pred coverage_to_cord_string(var_name_table::in, coverage_info::in,
     cord(cord(string))::out) is det.
 
 coverage_to_cord_string(_, Coverage, singleton(singleton(String))) :-
Index: deep_profiler/html_format.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/html_format.m,v
retrieving revision 1.41
diff -u -b -r1.41 html_format.m
--- deep_profiler/html_format.m	20 Oct 2012 12:17:16 -0000	1.41
+++ deep_profiler/html_format.m	24 Oct 2012 03:50:13 -0000
@@ -192,8 +192,8 @@
         ->
             HTML = empty
         ;
-            list_to_html(FormatInfo, !StyleControlMap, Class, MaybeTitle, Items,
-                TableHTML),
+            list_to_html(FormatInfo, !StyleControlMap, Class, MaybeTitle,
+                Items, TableHTML),
             HTML = wrap_tags(StartTag, EndTag, TableHTML)
         )
     ;
@@ -1018,7 +1018,8 @@
     string.foldr(replace_special_char_2(SpecialCharTable), String0, [], Chars),
     string.from_char_list(Chars, String).
 
-:- pred replace_special_char_2(pred(char, string)::in(pred(in, out) is semidet),
+:- pred replace_special_char_2(
+    pred(char, string)::in(pred(in, out) is semidet),
     char::in, list(char)::in, list(char)::out) is det.
 
 replace_special_char_2(SpecialCharTable, Char, !Acc) :-
Index: deep_profiler/mdprof_create_feedback.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/mdprof_create_feedback.m,v
retrieving revision 1.2
diff -u -b -r1.2 mdprof_create_feedback.m
--- deep_profiler/mdprof_create_feedback.m	5 Dec 2011 05:58:05 -0000	1.2
+++ deep_profiler/mdprof_create_feedback.m	24 Oct 2012 03:50:13 -0000
@@ -120,6 +120,9 @@
         read_deep_file(InputFileName, DebugReadProfile, MaybeDeep, !IO),
         (
             MaybeDeep = ok(Deep),
+            deep_get_maybe_progrep(Deep, MaybeProgRep),
+            (
+                MaybeProgRep = ok(_),
             ProfileProgName = Deep ^ profile_stats ^ prs_program_name,
             feedback.read_or_create(OutputFileName, ProfileProgName,
                 FeedbackReadResult, !IO),
@@ -158,6 +161,11 @@
                 io.set_exit_status(1, !IO)
             )
         ;
+                MaybeProgRep = error(Error),
+                io.set_exit_status(1, !IO),
+                io.format(Stderr, "%s: %s\n", [s(ProgName), s(Error)], !IO)
+            )
+        ;
             MaybeDeep = error(Error),
             io.set_exit_status(1, !IO),
             io.format(Stderr, "%s: error reading %s: %s\n",
Index: deep_profiler/mdprof_procrep.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/mdprof_procrep.m,v
retrieving revision 1.7
diff -u -b -r1.7 mdprof_procrep.m
--- deep_profiler/mdprof_procrep.m	27 Jan 2011 08:03:53 -0000	1.7
+++ deep_profiler/mdprof_procrep.m	24 Oct 2012 03:50:13 -0000
@@ -31,7 +31,9 @@
 :- import_module mdbcomp.program_representation.
 :- import_module program_representation_utils.
 
+:- import_module char.
 :- import_module cord.
+:- import_module getopt.
 :- import_module list.
 :- import_module map.
 :- import_module maybe.
@@ -40,7 +42,28 @@
 %-----------------------------------------------------------------------------%
 
 main(!IO) :-
-    io.command_line_arguments(Args, !IO),
+    io.progname_base("mdprof_procrep", ProgName, !IO),
+    io.command_line_arguments(Args0, !IO),
+    getopt.process_options(option_ops_multi(short, long, defaults),
+        Args0, Args, MaybeOptions),
+    io.stderr_stream(StdErr, !IO),
+    (
+        MaybeOptions = error(Msg),
+        io.format(StdErr, "%s: error parsing options: %s\n",
+            [s(ProgName), s(Msg)], !IO),
+        io.write_string(help_message(ProgName), !IO),
+        io.set_exit_status(1, !IO)
+    ;
+        MaybeOptions = ok(Options),
+        lookup_string_option(Options, filename, FileName),
+        read_prog_rep_file(FileName, ProgRepRes, !IO),
+        (
+            ProgRepRes = error(Error),
+            io.error_message(Error, Msg),
+            io.format("%s: %s\n", [s(ProgName), s(Msg)], !IO)
+        ;
+            ProgRepRes = ok(ProgRep),
+            ProgRep = prog_rep(ModuleReps),
     (
         Args = [],
         MaybeModules = no
@@ -48,17 +71,35 @@
         Args = [_ | _],
         MaybeModules = yes(Args)
     ),
-    read_prog_rep_file("Deep.procrep", ProgRepRes, !IO),
-    (
-        ProgRepRes = ok(ProgRep),
-        ProgRep = prog_rep(ModuleReps),
         print_selected_modules(ModuleReps, MaybeModules, !IO)
-    ;
-        ProgRepRes = error(Error),
-        io.error_message(Error, Msg),
-        io.format("mdprof_procrep: %s\n", [s(Msg)], !IO)
+        )
     ).
 
+:- func help_message(string) = string.
+
+help_message(ProgName) =
+    string.format(
+        "Usage: %s [-f procrepfilename] [module1, module2, ...]\n",
+        [s(ProgName)]).
+
+:- type option
+    --->    filename
+    ;       dummy.      % This is needed to shut up a warning about defaults
+                        % being det instead of multi.
+
+:- pred short(char::in, option::out) is semidet.
+
+short('f', filename).
+
+:- pred long(string::in, option::out) is semidet.
+
+long("file", filename).
+
+:- pred defaults(option::out, option_data::out) is multi.
+
+defaults(filename, string("Deep.procrep")).
+defaults(dummy, string("dummy")).
+
 %-----------------------------------------------------------------------------%
 
 :- pred print_selected_modules(module_map::in, maybe(list(string))::in,
@@ -67,24 +108,27 @@
 print_selected_modules(ModuleReps, MaybeModules, !IO) :-
     (
         MaybeModules = no,
-        map.foldl((pred(_::in, ModuleRep::in, IO0::di, IO::uo) is det :-
+        map.foldl(
+            (pred(_::in, ModuleRep::in, IO0::di, IO::uo) is det :-
                 print_module(ModuleRep, IO0, IO)
             ), ModuleReps, !IO)
     ;
         MaybeModules = yes(Modules),
-        list.foldl((pred(ModuleName::in, IO0::di, IO::uo) is det :-
+        list.foldl(
+            (pred(ModuleName::in, IO0::di, IO::uo) is det :-
             ( map.search(ModuleReps, ModuleName, ModuleRep) ->
                 print_module(ModuleRep, IO0, IO)
             ;
                 IO = IO0
-            )), Modules, !IO)
+                )
+            ), Modules, !IO)
     ).
 
 :- pred print_module(module_rep::in, io::di, io::uo) is det.
 
 print_module(ModuleRep, !IO) :-
     print_module_to_strings(ModuleRep, Strings),
-    io.write_string(string.append_list(list(Strings)), !IO).
+    io.write_string(string.append_list(cord.list(Strings)), !IO).
 
 %-----------------------------------------------------------------------------%
 :- end_module mdprof_procrep.
Index: deep_profiler/mdprof_test.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/mdprof_test.m,v
retrieving revision 1.26
diff -u -b -r1.26 mdprof_test.m
--- deep_profiler/mdprof_test.m	27 Jan 2011 08:03:53 -0000	1.26
+++ deep_profiler/mdprof_test.m	24 Oct 2012 03:50:13 -0000
@@ -304,8 +304,8 @@
 
 test_procrep_dynamic_coverages(Cur, Max, Pref, Deep, Options, !IO) :-
     ( Cur =< Max ->
-        try_exec(deep_cmd_dynamic_procrep_coverage(proc_dynamic_ptr(Cur)), Pref,
-            Deep, HTML, !IO),
+        try_exec(deep_cmd_dynamic_procrep_coverage(proc_dynamic_ptr(Cur)),
+            Pref, Deep, HTML, !IO),
         write_test_html(Options, "procrep_static_coverage", Cur, HTML, !IO),
         test_procrep_dynamic_coverages(Cur + 1, Max, Pref, Deep, Options, !IO)
     ;
Index: deep_profiler/measurements.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/measurements.m,v
retrieving revision 1.32
diff -u -b -r1.32 measurements.m
--- deep_profiler/measurements.m	19 Mar 2012 06:38:38 -0000	1.32
+++ deep_profiler/measurements.m	24 Oct 2012 03:50:13 -0000
@@ -240,10 +240,10 @@
     % has some amount of parallelism and there is a probability of
     % ChildRunnableProb that the child will be executed.
     %
-    % In the three argument version we assume that the child has no parallelism.
-    % In this version it's useful to think of the ChildRunnableProb as the
-    % chance a forked off child (of a pair of two) will be 'runnable' during
-    % the execution of it's sibling.
+    % In the three argument version we assume that the child has no
+    % parallelism. In this version it is useful to think of ChildRunnableProb
+    % as the chance a forked off child (of a pair of two) will be 'runnable'
+    % during the execution of it's sibling.
     %
 :- pred sub_computation_parallelism(parallelism_amount::in, probability::in,
     parallelism_amount::in, parallelism_amount::out) is det.
@@ -1143,15 +1143,19 @@
 :- func parallel_exec_metrics_internal_get_par_time(
     parallel_exec_metrics_internal, float, int) = float.
 
-parallel_exec_metrics_internal_get_par_time(pem_left_most(_, ParTime, _), _, _) =
-        ParTime.
-parallel_exec_metrics_internal_get_par_time(pem_additional(MetricsLeft,
-        _, _, _, TimeRightPar, TimeRightDead), SparkDelay, Depth) = Time :-
-    TimeRight = TimeRightPar + TimeRightDead + SparkDelay * float(Depth - 1),
-    TimeLeft =
-        parallel_exec_metrics_internal_get_par_time(MetricsLeft, SparkDelay,
-            Depth - 1),
-    Time = max(TimeLeft, TimeRight).
+parallel_exec_metrics_internal_get_par_time(PEM, SparkDelay, Depth) = Time :-
+    (
+        PEM = pem_left_most(_, ParTime, _),
+        Time = ParTime
+    ;
+        PEM = pem_additional(MetricsLeft, _, _, _,
+            TimeRightPar, TimeRightDead),
+        TimeRight = TimeRightPar + TimeRightDead +
+            SparkDelay * float(Depth - 1),
+        TimeLeft = parallel_exec_metrics_internal_get_par_time(MetricsLeft,
+            SparkDelay, Depth - 1),
+        Time = max(TimeLeft, TimeRight)
+    ).
 
     % The expected sequential execution time.
     %
Index: deep_profiler/program_representation_utils.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/program_representation_utils.m,v
retrieving revision 1.36
diff -u -b -r1.36 program_representation_utils.m
--- deep_profiler/program_representation_utils.m	26 Sep 2011 07:08:57 -0000	1.36
+++ deep_profiler/program_representation_utils.m	24 Oct 2012 03:50:13 -0000
@@ -56,7 +56,7 @@
 :- type print_goal_info(Key, GoalAnn)
     --->    print_goal_info(
                 pgi_lookup_annotation       :: (func(Key) = GoalAnn),
-                pgi_var_table               :: var_table
+                pgi_var_name_table          :: var_name_table
             ).
 
     % print_goal_to_strings(Lookup, VarTable, Indent, RevGoalPath, Goal,
@@ -74,7 +74,7 @@
     % Print the goal annotation for inclusion by print_proc_to_strings
     % above.
     %
-    pred print_goal_annotation_to_strings(var_table::in, T::in,
+    pred print_goal_annotation_to_strings(var_name_table::in, T::in,
         cord(cord(string))::out) is det
 ].
 
@@ -215,11 +215,163 @@
 %----------------------------------------------------------------------------%
 
 print_module_to_strings(ModuleRep, Strings) :-
-    ModuleRep = module_rep(ModuleName, _StringTable, ProcReps),
+    ModuleRep = module_rep(ModuleName, _StringTable, OISUTypesProcs,
+        TypeTableMap, ProcReps),
+    HeaderString = string.format("Module %s\n", [s(ModuleName)]),
+    list.foldl(accumulate_print_oisu_type_procs_to_strings, OISUTypesProcs,
+        cord.empty, OISUStrs),
+    map.foldl(accumulate_print_type_table_entries_to_strings, TypeTableMap,
+        cord.empty, TypeTableStrs0),
+    ( cord.is_empty(TypeTableStrs0) ->
+        TypeTableStrs = TypeTableStrs0
+    ;
+        TypeTableStrs = cord.singleton("\nType table:\n") ++
+            TypeTableStrs0 ++ nl
+    ),
     map.foldl(accumulate_print_proc_to_strings, ProcReps,
-        cord.empty, ProcStrings),
-    Strings = cord.cons(string.format("Module %s\n", [s(ModuleName)]),
-        ProcStrings).
+        cord.empty, ProcRepStrs),
+    Strings = cord.singleton(HeaderString) ++ OISUStrs ++ TypeTableStrs
+        ++ ProcRepStrs.
+
+%----------------------------------------------------------------------------%
+
+:- pred accumulate_print_oisu_type_procs_to_strings(oisu_type_procs::in,
+    cord(string)::in, cord(string)::out) is det.
+
+accumulate_print_oisu_type_procs_to_strings(OISUTypeProcs, !Strings) :-
+    print_oisu_type_procs_to_strings(OISUTypeProcs, OISUStr),
+    !:Strings = !.Strings ++ OISUStr.
+
+:- pred print_oisu_type_procs_to_strings(oisu_type_procs::in,
+    cord(string)::out) is det.
+
+print_oisu_type_procs_to_strings(OISUTypeProcs, Str) :-
+    OISUTypeProcs = oisu_type_procs(TypeCtor,
+        CreatorProcLabels, MutatorProcLabels, DestructorProcLabels),
+    list.map(print_proc_label_to_string, CreatorProcLabels, CreatorStrs),
+    list.map(print_proc_label_to_string, MutatorProcLabels, MutatorStrs),
+    list.map(print_proc_label_to_string, DestructorProcLabels, DestructorStrs),
+    CreatorNlCords = list.map(add_nl, CreatorStrs),
+    MutatorNlCords = list.map(add_nl, MutatorStrs),
+    DestructorNlCords = list.map(add_nl, DestructorStrs),
+    Str = cord.from_list(["\nOISU type constructor ", TypeCtor])
+        ++ cord.cons("\nCreator procs:\n",
+            cord.cord_list_to_cord(CreatorNlCords))
+        ++ cord.cons("\nMutator procs:\n",
+            cord.cord_list_to_cord(MutatorNlCords))
+        ++ cord.cons("\nDestructor procs:\n",
+            cord.cord_list_to_cord(DestructorNlCords)).
+
+%----------------------------------------------------------------------------%
+
+:- pred accumulate_print_type_table_entries_to_strings(int::in,
+    type_rep::in, cord(string)::in, cord(string)::out) is det.
+
+accumulate_print_type_table_entries_to_strings(TypeNum, TypeRep, !Strings) :-
+    string.int_to_string(TypeNum, TypeNumStr),
+    type_rep_to_strings(TypeRep, TypeRepStrCord),
+    Str = cord.singleton(TypeNumStr)
+        ++ cord.singleton(" -> ")
+        ++ TypeRepStrCord
+        ++ cord.singleton("\n"),
+    !:Strings = !.Strings ++ Str.
+
+:- pred type_rep_to_strings(type_rep::in, cord(string)::out) is det.
+
+type_rep_to_strings(TypeRep, Cord) :-
+    (
+        TypeRep = defined_type_rep(TypeCtorSymName, ArgTypes),
+        TypeCtorSymNameStr = sym_name_to_string(TypeCtorSymName),
+        TypeCtorSymNameCord = cord.singleton(TypeCtorSymNameStr),
+        (
+            ArgTypes = [],
+            Cord = TypeCtorSymNameCord
+        ;
+            ArgTypes = [HeadTypeRep | TailTypeReps],
+            arg_type_reps_to_strings(HeadTypeRep, TailTypeReps, ArgTypesCord),
+            Cord = TypeCtorSymNameCord
+                ++ cord.singleton("(")
+                ++ ArgTypesCord
+                ++ cord.singleton(")")
+        )
+    ;
+        TypeRep = builtin_type_rep(BuiltinTypeRep),
+        (
+            BuiltinTypeRep = builtin_type_int_rep,
+            TypeNameStr = "int"
+        ;
+            BuiltinTypeRep = builtin_type_float_rep,
+            TypeNameStr = "float"
+        ;
+            BuiltinTypeRep = builtin_type_string_rep,
+            TypeNameStr = "string"
+        ;
+            BuiltinTypeRep = builtin_type_char_rep,
+            TypeNameStr = "char"
+        ),
+        Cord = cord.singleton(TypeNameStr)
+    ;
+        TypeRep = tuple_type_rep(ArgTypes),
+        (
+            ArgTypes = [],
+            Cord = cord.singleton("{}")
+        ;
+            ArgTypes = [HeadTypeRep | TailTypeReps],
+            arg_type_reps_to_strings(HeadTypeRep, TailTypeReps, ArgTypesCord),
+            Cord =
+                cord.singleton("{")
+                ++ ArgTypesCord
+                ++ cord.singleton("}")
+        )
+    ;
+        TypeRep = higher_order_type_rep(ArgTypes, MaybeResultType),
+        (
+            MaybeResultType = no,
+            (
+                ArgTypes = [],
+                Cord = cord.singleton("pred ()")
+            ;
+                ArgTypes = [HeadTypeRep | TailTypeReps],
+                arg_type_reps_to_strings(HeadTypeRep, TailTypeReps,
+                    ArgTypesCord),
+                Cord = cord.singleton("pred(")
+                    ++ ArgTypesCord
+                    ++ cord.singleton(")")
+            )
+        ;
+            MaybeResultType = yes(ResultType),
+            type_rep_to_strings(ResultType, ResultTypeCord),
+            (
+                ArgTypes = [],
+                Cord = cord.singleton("func = ") ++ ResultTypeCord
+            ;
+                ArgTypes = [HeadTypeRep | TailTypeReps],
+                arg_type_reps_to_strings(HeadTypeRep, TailTypeReps,
+                    ArgTypesCord),
+                Cord = cord.singleton("func(")
+                    ++ ArgTypesCord
+                    ++ cord.singleton(") = ")
+                    ++ ResultTypeCord
+            )
+        )
+    ;
+        TypeRep = type_var_rep(N),
+        string.int_to_string(N, NStr),
+        Cord = cord.singleton("T" ++ NStr)
+    ).
+
+:- pred arg_type_reps_to_strings(type_rep::in, list(type_rep)::in,
+    cord(string)::out) is det.
+
+arg_type_reps_to_strings(HeadTypeRep, [], Cord) :-
+    type_rep_to_strings(HeadTypeRep, Cord).
+arg_type_reps_to_strings(HeadTypeRep, [HeadTailTypeRep | TailTailTypeReps],
+        Cord) :-
+    type_rep_to_strings(HeadTypeRep, HeadCord),
+    arg_type_reps_to_strings(HeadTailTypeRep, TailTailTypeReps, TailCord),
+    Cord = HeadCord ++ cord.singleton(", ") ++ TailCord.
+
+%----------------------------------------------------------------------------%
 
     % Print a procedure to a string representation.
     %
@@ -243,16 +395,45 @@
 
 print_proc_to_strings_2(Lookup, ProcRep, Strings) :-
     ProcRep = proc_rep(ProcLabel, ProcDefnRep),
-    ProcDefnRep = proc_defn_rep(ArgVarReps, GoalRep, VarTable, Detism),
+    ProcDefnRep = proc_defn_rep(ArgVarReps, GoalRep, VarNameTable,
+        MaybeVarTypeTable, Detism),
     print_proc_label_to_string(ProcLabel, ProcLabelString0),
     detism_to_string(Detism, DetismString),
     ProcLabelString = DetismString ++ cord.singleton(" ") ++
         cord.singleton(ProcLabelString0),
-    print_args_to_strings(print_head_var, VarTable, ArgVarReps, ArgsString),
-    print_goal_to_strings(print_goal_info(Lookup, VarTable), 1, rgp_nil,
+    print_args_to_strings(print_head_var, VarNameTable, ArgVarReps,
+        ArgsString),
+    print_goal_to_strings(print_goal_info(Lookup, VarNameTable), 1, rgp_nil,
         GoalRep, GoalString),
-    Strings = ProcLabelString ++ ArgsString ++ cord.singleton(" :-\n") ++
-        GoalString ++ nl.
+    MainStrings = ProcLabelString ++ ArgsString ++ cord.singleton(" :-\n") ++
+        GoalString ++ nl,
+    (
+        MaybeVarTypeTable = no,
+        Strings = MainStrings
+    ;
+        MaybeVarTypeTable = yes(VarTypeTable),
+        map.foldl(accumulate_var_type_table_entry_strings(VarNameTable),
+            VarTypeTable, cord.init, TypeTableStrings),
+        Strings = TypeTableStrings ++ MainStrings
+    ).
+
+:- pred accumulate_var_type_table_entry_strings(var_name_table::in,
+    var_rep::in, type_rep::in, cord(string)::in, cord(string)::out) is det.
+
+accumulate_var_type_table_entry_strings(VarNameTable, VarNum, TypeRep,
+        !Strings) :-
+    string.int_to_string(VarNum, VarNumStr),
+    (
+        search_var_name(VarNameTable, VarNum, VarName),
+        not VarName = ""
+    ->
+        VarIdStrs = cord.from_list([VarName, " ", VarNumStr, " -> "])
+    ;
+        VarIdStrs = cord.from_list(["unnamed_var ", VarNumStr, " -> "])
+    ),
+    type_rep_to_strings(TypeRep, TypeRepStrs),
+    EntryStrs = VarIdStrs ++ TypeRepStrs ++ nl,
+    !:Strings = !.Strings ++ EntryStrs.
 
 print_proc_label_to_string(ProcLabel, String) :-
     (
@@ -278,7 +459,7 @@
 
 print_goal_to_strings(Info, Indent, RevGoalPath, GoalRep, Strings) :-
     GoalRep = goal_rep(GoalExprRep, DetismRep, AnnotationKey),
-    VarTable = Info ^ pgi_var_table,
+    VarTable = Info ^ pgi_var_name_table,
     (
         GoalExprRep = conj_rep(ConjGoalReps),
         print_conj_to_strings(Info, Indent, RevGoalPath,
@@ -482,7 +663,7 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred print_atomic_goal_to_strings(var_table::in, atomic_goal_rep::in,
+:- pred print_atomic_goal_to_strings(var_name_table::in, atomic_goal_rep::in,
     cord(string)::out) is det.
 
 print_atomic_goal_to_strings(VarTable, AtomicGoalRep, Strings) :-
@@ -573,7 +754,7 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred print_args_to_strings(pred(var_table, T, string), var_table,
+:- pred print_args_to_strings(pred(var_name_table, T, string), var_name_table,
     list(T), cord(string)).
 :- mode print_args_to_strings(pred(in, in, out) is det, in, in, out) is det.
 
@@ -587,8 +768,8 @@
         Strings = cord.cons("(", cord.snoc(ArgsStr, ")"))
     ).
 
-:- pred print_args_2_to_strings(pred(var_table, T, string), var_table,
-    list(T), cord(string), cord(string)).
+:- pred print_args_2_to_strings(pred(var_name_table, T, string),
+    var_name_table, list(T), cord(string), cord(string)).
 :- mode print_args_2_to_strings(pred(in, in, out) is det, in, in, in, out)
     is det.
 
@@ -599,13 +780,15 @@
         ArgsString),
     Strings = Prefix ++ cord.cons(ArgName, ArgsString).
 
-:- pred print_maybe_var(var_table::in, maybe(var_rep)::in, string::out) is det.
+:- pred print_maybe_var(var_name_table::in, maybe(var_rep)::in, string::out)
+    is det.
 
 print_maybe_var(_, no, "_").
 print_maybe_var(VarTable, yes(VarRep), VarName) :-
     lookup_var_name(VarTable, VarRep, VarName).
 
-:- pred print_head_var(var_table::in, head_var_rep::in, string::out) is det.
+:- pred print_head_var(var_name_table::in, head_var_rep::in, string::out)
+    is det.
 
 print_head_var(VarTable, head_var_rep(VarRep, VarMode), String) :-
     lookup_var_name(VarTable, VarRep, VarName),
@@ -670,14 +853,18 @@
 
 nl = cord.singleton("\n").
 
+:- func add_nl(string) = cord(string).
+
+add_nl(Str) = cord.from_list([Str, "\n"]).
+
 %----------------------------------------------------------------------------%
 
 :- instance goal_annotation(unit) where [
     pred(print_goal_annotation_to_strings/3) is print_unit_to_strings
 ].
 
-:- pred print_unit_to_strings(var_table::in, unit::in, cord(cord(string))::out)
-    is det.
+:- pred print_unit_to_strings(var_name_table::in, unit::in,
+    cord(cord(string))::out) is det.
 
 print_unit_to_strings(_, _, cord.empty).
 
@@ -878,7 +1065,8 @@
     inst_map::in, inst_map::out, seen_duplicate_instantiation::in,
     seen_duplicate_instantiation::out) is det.
 
-inst_map_ground_var(DepVars0, Var, InstMap0, InstMap, !SeenDuplicateInstantiation) :-
+inst_map_ground_var(DepVars0, Var, InstMap0, InstMap,
+        !SeenDuplicateInstantiation) :-
     InstMap0 = inst_map(VarToInst0, VarToDepVars0),
     ( map.search(VarToInst0, Var, InstPrime) ->
         Inst = InstPrime
Index: deep_profiler/query.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/query.m,v
retrieving revision 1.42
diff -u -b -r1.42 query.m
--- deep_profiler/query.m	27 Jan 2011 08:03:53 -0000	1.42
+++ deep_profiler/query.m	24 Oct 2012 03:50:13 -0000
@@ -41,7 +41,7 @@
 
 %-----------------------------------------------------------------------------%
 %
-% Declarations for reading and writing querys.
+% Declarations for reading and writing queries.
 %
 
     % A deep profiler query.
@@ -113,6 +113,12 @@
     ;       deep_cmd_module(
                 cmd_module_module_name          :: string
             )
+    ;       deep_cmd_module_getter_setters(
+                cmd_mgs_module_name             :: string
+            )
+    ;       deep_cmd_module_rep(
+                cmd_mr_module_name              :: string
+            )
     ;       deep_cmd_top_procs(
                 cmd_tp_display_limit            :: display_limit,
                 cmd_tp_sort_cost_kind           :: cost_kind,
@@ -125,9 +131,6 @@
     ;       deep_cmd_dynamic_procrep_coverage(
                 cmd_dynamic_coverage_pd         :: proc_dynamic_ptr
             )
-    ;       deep_cmd_module_getter_setters(
-                cmd_mgs_module_name             :: string
-            )
 
     % The following commands are for debugging.
 
@@ -601,6 +604,10 @@
             [s(cmd_str_module_getter_setters), c(cmd_separator_char),
             s(ModuleName)])
     ;
+        Cmd = deep_cmd_module_rep(ModuleName),
+        CmdStr = string.format("%s%c%s",
+            [s(cmd_str_module_rep), c(cmd_separator_char), s(ModuleName)])
+    ;
         Cmd = deep_cmd_top_procs(Limit, CostKind, InclDesc, Scope),
         LimitStr = limit_to_string(Limit),
         CostKindStr = cost_kind_to_string(CostKind),
@@ -641,7 +648,8 @@
         Cmd = deep_cmd_dump_call_site_dynamic(CSDPtr),
         CSDPtr = call_site_dynamic_ptr(CSDI),
         CmdStr = string.format("%s%c%d",
-            [s(cmd_str_dump_call_site_dynamic), c(cmd_separator_char), i(CSDI)])
+            [s(cmd_str_dump_call_site_dynamic), c(cmd_separator_char),
+                i(CSDI)])
     ;
         Cmd = deep_cmd_dump_clique(CliquePtr),
         CliquePtr = clique_ptr(CliqueNum),
@@ -764,6 +772,11 @@
         Cmd = deep_cmd_module_getter_setters(ModuleName),
         MaybeCmd = yes(Cmd)
     ;
+        Pieces = [cmd_str_module_rep, ModuleName]
+    ->
+        Cmd = deep_cmd_module_rep(ModuleName),
+        MaybeCmd = yes(Cmd)
+    ;
         Pieces = [cmd_str_top_procs, LimitStr, CostKindStr, InclDescStr,
             ScopeStr],
         string_to_limit(LimitStr, Limit),
@@ -1322,6 +1335,9 @@
 :- func cmd_str_module_getter_setters = string.
 cmd_str_module_getter_setters = "module_getter_setters".
 
+:- func cmd_str_module_rep = string.
+cmd_str_module_rep = "module_rep".
+
 :- func cmd_str_top_procs = string.
 cmd_str_top_procs = "top_procs".
 
Index: deep_profiler/read_profile.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/read_profile.m,v
retrieving revision 1.38
diff -u -b -r1.38 read_profile.m
--- deep_profiler/read_profile.m	26 Sep 2011 07:08:57 -0000	1.38
+++ deep_profiler/read_profile.m	24 Oct 2012 03:50:13 -0000
@@ -1484,7 +1484,7 @@
         io.write_string("\n", !TIO)
     ).
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pred deep_insert(array(T)::in, int::in, T::in, array(T)::out) is det.
 
@@ -1499,7 +1499,7 @@
         set(Ind, Item, u(A0), A)
     ).
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- func make_csdptr(int) = call_site_dynamic_ptr.
 :- func make_cssptr(int) = call_site_static_ptr.
@@ -1521,7 +1521,7 @@
 make_dummy_pdptr = proc_dynamic_ptr(-1).
 make_dummy_psptr = proc_static_ptr(-1).
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pragma foreign_decl("C", "#include ""mercury_deep_profiling.h""").
 
@@ -1563,5 +1563,5 @@
     }
 ").
 
-%------------------------------------------------------------------------------%
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
Index: deep_profiler/recursion_patterns.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/recursion_patterns.m,v
retrieving revision 1.17
diff -u -b -r1.17 recursion_patterns.m
--- deep_profiler/recursion_patterns.m	26 Sep 2011 07:08:57 -0000	1.17
+++ deep_profiler/recursion_patterns.m	24 Oct 2012 03:50:13 -0000
@@ -126,7 +126,8 @@
         proc_dynamic_paired_call_site_slots(Deep, PDPtr, Slots),
         foldl(build_dynamic_call_site_cost_and_callee_map(Deep),
             Slots, map.init, CallSitesMap),
-        Info = recursion_analysis_info(ThisClique, CallSitesMap, CoverageArray),
+        Info = recursion_analysis_info(ThisClique, CallSitesMap,
+            CoverageArray),
         goal_recursion_data(Info, rgp_nil, Goal, RecursionData),
         recursion_data_to_recursion_type(ParentCalls, TotalCalls,
             RecursionData, RecursionType),
@@ -988,7 +989,8 @@
         own_and_inherit_to_perf_row_data(Deep, unit, Own, Inherit, Summary),
         MaybeSummary = yes(Summary)
     ),
-    map_values(finalize_histogram_proc_rec_type(Deep, NumCliques), !EntryProcs).
+    map_values(finalize_histogram_proc_rec_type(Deep, NumCliques),
+        !EntryProcs).
 
 :- pred finalize_histogram_proc_rec_type(deep::in, float::in,
     proc_static_ptr::in,
Index: deep_profiler/report.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/report.m,v
retrieving revision 1.33
diff -u -b -r1.33 report.m
--- deep_profiler/report.m	20 Oct 2012 12:17:16 -0000	1.33
+++ deep_profiler/report.m	24 Oct 2012 03:50:13 -0000
@@ -65,6 +65,9 @@
     ;       report_module_getter_setters(
                 maybe_error(module_getter_setters_report)
             )
+    ;       report_module_rep(
+                maybe_error(module_rep_report)
+            )
     ;       report_top_procs(
                 maybe_error(top_procs_report)
             )
@@ -357,12 +360,19 @@
 
 :- type module_getter_setters_report
     --->    module_getter_setters_report(
-                % Summary information about all the procedures in one module
-                % of the program.
+                % Summary information about all the getter/setter procedures
+                % in one module of the program.
                 mgsr_module_name            :: string,
                 mgsr_procs                  :: gs_ds_map
             ).
 
+:- type module_rep_report
+    --->    module_rep_report(
+                % A representation of one module of the program.
+                mrr_module_name             :: string,
+                mrr_report                  :: string
+            ).
+
 :- type top_procs_report
     --->    top_procs_report(
                 % Information about the most expensive procedures. The ordering
Index: deep_profiler/top_procs.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/top_procs.m,v
retrieving revision 1.15
diff -u -b -r1.15 top_procs.m
--- deep_profiler/top_procs.m	15 Dec 2010 06:30:35 -0000	1.15
+++ deep_profiler/top_procs.m	24 Oct 2012 03:50:13 -0000
@@ -222,9 +222,9 @@
 find_top_sort_predicate(cost_words,  self_and_desc, per_call, yes,
     compare_ps_words_both_percall,  filter_ps_words_both).
 
-:- pred find_threshold_percent_predicate(cost_kind::in, include_descendants::in,
-    bool::out, pred(deep, float, int)::out(pred(in, in, in) is semidet))
-    is det.
+:- pred find_threshold_percent_predicate(cost_kind::in,
+    include_descendants::in, bool::out,
+    pred(deep, float, int)::out(pred(in, in, in) is semidet)) is det.
 
 find_threshold_percent_predicate(cost_calls,  self,          no,
     threshold_percent_ps_time_self).
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_cairo
cvs diff: Diffing extras/graphics/mercury_cairo/samples
cvs diff: Diffing extras/graphics/mercury_cairo/samples/data
cvs diff: Diffing extras/graphics/mercury_cairo/tutorial
cvs diff: Diffing extras/graphics/mercury_glfw
cvs diff: Diffing extras/graphics/mercury_glfw/samples
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/monte
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing m4
cvs diff: Diffing mdbcomp
Index: mdbcomp/feedback.automatic_parallelism.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/feedback.automatic_parallelism.m,v
retrieving revision 1.19
diff -u -b -r1.19 feedback.automatic_parallelism.m
--- mdbcomp/feedback.automatic_parallelism.m	14 Dec 2011 04:55:20 -0000	1.19
+++ mdbcomp/feedback.automatic_parallelism.m	24 Oct 2012 03:50:13 -0000
@@ -146,7 +146,7 @@
     --->    candidate_par_conjunctions_proc(
                 % A variable name table for the variables that have
                 % sensible names.
-                cpcp_var_table  :: var_table,
+                cpcp_var_table  :: var_name_table,
 
                 % Each push represents a program transformation.
                 % Most of the time, we expect the list to be empty,
Index: mdbcomp/prim_data.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/prim_data.m,v
retrieving revision 1.40
diff -u -b -r1.40 prim_data.m
--- mdbcomp/prim_data.m	8 Jun 2012 15:37:06 -0000	1.40
+++ mdbcomp/prim_data.m	24 Oct 2012 03:50:13 -0000
@@ -596,7 +596,8 @@
 mercury_profiling_builtin_module = unqualified("profiling_builtin").
 mercury_term_size_prof_builtin_module = unqualified("term_size_prof_builtin").
 mercury_par_builtin_module = unqualified("par_builtin").
-mercury_rtti_implementation_builtin_module = unqualified("rtti_implementation").
+mercury_rtti_implementation_builtin_module =
+    unqualified("rtti_implementation").
 mercury_ssdb_builtin_module = unqualified("ssdb").
 mercury_list_module = unqualified("list").
 mercury_string_module = unqualified("string").
Index: mdbcomp/program_representation.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/program_representation.m,v
retrieving revision 1.64
diff -u -b -r1.64 program_representation.m
--- mdbcomp/program_representation.m	27 Sep 2011 00:49:27 -0000	1.64
+++ mdbcomp/program_representation.m	24 Oct 2012 03:50:13 -0000
@@ -10,7 +10,7 @@
 % Authors: zs, dougl
 %
 % This module defines the representation of procedure bodies used by the
-% declarative debugger (and maybe the deep profiler).
+% declarative debugger and the deep profiler.
 %
 % One of the things we want the declarative debugger to be able to do
 % is to let the user specify which part of which output argument of an
@@ -69,11 +69,36 @@
     --->    module_rep(
                 mr_name         :: string,          % The module name.
                 mr_string_table :: string_table,
+                mr_oisu_types       :: list(oisu_type_procs),
+                mr_type_rep_table   :: map(int, type_rep),
                 mr_procs        :: proc_map(GoalAnnotation)
             ).
 
 :- type module_rep == module_rep(unit).
 
+:- type oisu_type_procs
+    --->    oisu_type_procs(
+                otp_type_ctor   :: string,      % name of type_ctor; arity 0
+                otp_creators    :: list(string_proc_label),
+                otp_mutators    :: list(string_proc_label),
+                otp_destructors :: list(string_proc_label)
+            ).
+
+:- type type_rep
+    --->    defined_type_rep(sym_name, list(type_rep))
+    ;       builtin_type_rep(builtin_type_rep)
+    ;       tuple_type_rep(list(type_rep))
+    ;       higher_order_type_rep(list(type_rep), maybe(type_rep))
+    ;       type_var_rep(int).
+
+:- type encoded_type_table == map(int, type_rep).
+
+:- type builtin_type_rep
+    --->    builtin_type_int_rep
+    ;       builtin_type_float_rep
+    ;       builtin_type_string_rep
+    ;       builtin_type_char_rep.
+
     % A map of proc names to proc_reps.
     %
 :- type proc_map(GoalAnnotation) ==
@@ -91,13 +116,14 @@
     % A string_proc_label is a data structure that uniquely identifies a
     % procedure. It is a version of the proc_label type from prim_data.m
     % that can be used outside the compiler, e.g. in RTTI data structures
-    % and in data filed generated by deep profiling.
+    % and in data files generated by deep profiling.
     %
     % When procedures are imported from one module to another, for example for
-    % inter-module optimisations the def_module field may be different to the
-    % decl_module feild. In this case a procedure has been imported into the
-    % def_module from the decl_module. This is also true for the type_module
-    % and def_module fields in the str_special_proc_label constructor.
+    % inter-module optimisations, the def_module field may be different to the
+    % decl_module field. If this is the case, then the procedure has been
+    % imported into the def_module from the decl_module. This is also true
+    % for the type_module and def_module fields in the str_special_proc_label
+    % constructor.
     %
 :- type string_proc_label
     --->    str_ordinary_proc_label(
@@ -141,11 +167,14 @@
                 % The procedure body.
                 pdr_goal                :: goal_rep(GoalAnnotation),
 
-                % The variable table.
-                pdr_var_table           :: var_table,
+                % The variable name table.
+                pdr_var_name_table      :: var_name_table,
+
+                % The variable type table, if present.
+                pdr_var_type_table      :: maybe(var_type_table),
 
-                % The determinism of the procedure, this may be different from
-                % procedure's goal's determinism.
+                % The determinism of the procedure. Note that this may be
+                % looser than the determinism of the procedure's body goal.
                 pdr_detism              :: detism_rep
             ).
 
@@ -326,8 +355,8 @@
     --->    ir_free_rep
     ;       ir_ground_rep
     ;       ir_other_rep.
-                % Instantiation states that arn't understood by the bytecode
-                % representation are grouped within this value.
+            % Instantiation states that are not understood by the bytecode
+            % representation are stored as ir_other_rep.
 
 :- type cons_id_arity_rep
     --->    cons_id_arity_rep(
@@ -378,19 +407,29 @@
     % created by the compiler are not included. The table may be empty if it is
     % not required, such as when used with the declarative debugger.
     %
-:- type var_table.
+:- type var_name_table.
 
     % Lookup the name of a variable within the variable table. If the variable
     % is unknown a distinct name is automatically generated.
     %
-:- pred lookup_var_name(var_table::in, var_rep::in, string::out) is det.
+:- pred lookup_var_name(var_name_table::in, var_rep::in, string::out) is det.
 
     % Retrieve the name for this variable if it is known, otherwise fail.
     %
-:- pred search_var_name(var_table::in, var_rep::in, string::out) is semidet.
+:- pred search_var_name(var_name_table::in, var_rep::in, string::out)
+    is semidet.
 
-:- pred maybe_search_var_name(var_table::in, var_rep::in, maybe(string)::out)
-    is det.
+:- pred maybe_search_var_name(var_name_table::in, var_rep::in,
+    maybe(string)::out) is det.
+
+    % A table mapping var_reps to representations of the variables' types.
+    % It is intended to be used by a program analysis for order-independent
+    % state update in the auto-parallelisation feedback tool.
+    %
+    % This table should exist in any procedure that is named in a oisu pragma.
+    % In other procedures, it may or or may not be there (currently, it isn't).
+    %
+:- type var_type_table == map(var_rep, type_rep).
 
     % If the given atomic goal behaves like a call in the sense that it
     % generates events as ordinary calls do, then return the list of variables
@@ -412,6 +451,7 @@
     is semidet.
 
     % The atomic goal's module, name and arity.
+    %
 :- type atomic_goal_id
     --->    atomic_goal_id(string, string, int).
 
@@ -424,7 +464,7 @@
 :- func head_var_to_var(head_var_rep) = var_rep.
 
     % Extract the goal from a case, this is implemented here so it can be used
-    % in as a higher order value.
+    % as a higher order value.
     %
 :- pred case_get_goal(case_rep(T)::in, goal_rep(T)::out) is det.
 
@@ -549,10 +589,37 @@
     ;       var_num_2_bytes
     ;       var_num_4_bytes.
 
+
+    % Describe whether a variable name table should be included in the
+    % bytecode. The variable name table actually adds the strings into the
+    % module's string table.
+    %
+:- type maybe_include_var_name_table
+    --->    do_not_include_var_name_table
+    ;       include_var_name_table.
+
+    % Describe whether references to the types of variables should be included
+    % in the variable table. The types themselves are in a separate table next
+    % to the module's string table.
+    %
+:- type maybe_include_var_types
+    --->    do_not_include_var_types
+    ;       include_var_types.
+
+    % This predicate is here only for reading Deep.procrep files in an
+    % old format, for backwards compatibility.
+    %
 :- pred var_num_rep_byte(var_num_rep, int).
 :- mode var_num_rep_byte(in, out) is det.
 :- mode var_num_rep_byte(out, in) is semidet.
 
+    % This predicate is the replacement for var_num_rep_byte.
+    %
+:- pred var_flag_byte(var_num_rep,
+    maybe_include_var_name_table, maybe_include_var_types, int).
+:- mode var_flag_byte(in, in, in, out) is det.
+:- mode var_flag_byte(out, out, out, in) is semidet.
+
     % Represent whether a scope goal cuts away solutions or not.
     %
 :- pred cut_byte(maybe_cut, int).
@@ -722,6 +789,8 @@
 
 goal_rep_type = type_of(_ : goal_rep).
 
+%-----------------------------------------------------------------------------%
+
 transform_goal_rep(Pred, Goal0, Goal) :-
     Goal0 = goal_rep(Expr0, Detism, A),
     transform_goal_expr(Pred, Expr0, Expr),
@@ -859,27 +928,53 @@
 var_num_rep_byte(var_num_2_bytes, 1).
 var_num_rep_byte(var_num_4_bytes, 2).
 
-:- type var_table == map(var_rep, string).
+var_flag_byte(var_num_1_byte,
+    do_not_include_var_name_table, do_not_include_var_types, 0).
+var_flag_byte(var_num_1_byte,
+    do_not_include_var_name_table, include_var_types, 1).
+var_flag_byte(var_num_1_byte,
+    include_var_name_table, do_not_include_var_types, 2).
+var_flag_byte(var_num_1_byte,
+    include_var_name_table, include_var_types, 3).
+var_flag_byte(var_num_2_bytes,
+    do_not_include_var_name_table, do_not_include_var_types, 4).
+var_flag_byte(var_num_2_bytes,
+    do_not_include_var_name_table, include_var_types, 5).
+var_flag_byte(var_num_2_bytes,
+    include_var_name_table, do_not_include_var_types, 6).
+var_flag_byte(var_num_2_bytes,
+    include_var_name_table, include_var_types, 7).
+var_flag_byte(var_num_4_bytes,
+    do_not_include_var_name_table, do_not_include_var_types, 8).
+var_flag_byte(var_num_4_bytes,
+    do_not_include_var_name_table, include_var_types, 9).
+var_flag_byte(var_num_4_bytes,
+    include_var_name_table, do_not_include_var_types, 10).
+var_flag_byte(var_num_4_bytes,
+    include_var_name_table, include_var_types, 11).
+
+:- type var_name_table == map(var_rep, string).
 
-lookup_var_name(VarTable, VarRep, String) :-
-    ( search_var_name(VarTable, VarRep, StringPrime) ->
+lookup_var_name(VarNameTable, VarRep, String) :-
+    ( search_var_name(VarNameTable, VarRep, StringPrime) ->
         String = StringPrime
     ;
         % Generate an automatic name for the variable.
         String = string.format("V_%d", [i(VarRep)])
     ).
 
-search_var_name(VarTable, VarRep, String) :-
-    map.search(VarTable, VarRep, String).
+search_var_name(VarNameTable, VarRep, String) :-
+    map.search(VarNameTable, VarRep, String).
 
-maybe_search_var_name(VarTable, VarRep, MaybeString) :-
-    ( search_var_name(VarTable, VarRep, String) ->
+maybe_search_var_name(VarNameTable, VarRep, MaybeString) :-
+    ( search_var_name(VarNameTable, VarRep, String) ->
         MaybeString = yes(String)
     ;
         MaybeString = no
     ).
 
 %-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pred read_file_as_bytecode(string::in, io.res(bytecode)::out,
     io::di, io::uo) is det.
@@ -963,8 +1058,15 @@
             some [!Pos] (
                 !:Pos = 0,
                 read_line(ByteCode, Line, !Pos),
-                Line = procrep_id_string,
-                read_module_reps(ByteCode, map.init, ModuleReps, !Pos),
+                ( Line = old_procrep_id_string ->
+                    ExpectNewFormat = no
+                ; Line = new_procrep_id_string ->
+                    ExpectNewFormat = yes
+                ;
+                    fail
+                ),
+                read_module_reps(ExpectNewFormat, ByteCode,
+                    map.init, ModuleReps, !Pos),
                 ByteCode = bytecode(_, Size),
                 !.Pos = Size
             )
@@ -978,67 +1080,252 @@
 
     % Return the string written out by MR_write_out_procrep_id_string.
     %
-:- func procrep_id_string = string.
+:- func old_procrep_id_string = string.
+:- func new_procrep_id_string = string.
 
-procrep_id_string = "Mercury deep profiler procrep version 5\n".
+old_procrep_id_string = "Mercury deep profiler procrep version 5\n".
+new_procrep_id_string = "Mercury deep profiler procrep version 6\n".
 
-:- pred read_module_reps(bytecode::in,
+%-----------------------------------------------------------------------------%
+
+:- pred read_module_reps(bool::in, bytecode::in,
     module_map(unit)::in, module_map(unit)::out,
     int::in, int::out) is semidet.
 
-read_module_reps(ByteCode, !ModuleReps, !Pos) :-
+read_module_reps(ExpectNewFormat, ByteCode, !ModuleReps, !Pos) :-
     read_byte(ByteCode, MoreByte, !Pos),
     is_more_modules(MoreByte, MoreModules),
     (
         MoreModules = no_more_modules
     ;
         MoreModules = next_module,
-        read_module_rep(ByteCode, ModuleRep, !Pos),
+        read_module_rep(ExpectNewFormat, ByteCode, ModuleRep, !Pos),
         map.det_insert(ModuleRep ^ mr_name, ModuleRep, !ModuleReps),
-        read_module_reps(ByteCode, !ModuleReps, !Pos)
+        read_module_reps(ExpectNewFormat, ByteCode, !ModuleReps, !Pos)
     ).
 
-:- pred read_module_rep(bytecode::in, module_rep(unit)::out, int::in, int::out)
-    is semidet.
+:- pred read_module_rep(bool::in, bytecode::in, module_rep(unit)::out,
+    int::in, int::out) is semidet.
 
-read_module_rep(ByteCode, ModuleRep, !Pos) :-
+read_module_rep(ExpectNewFormat, ByteCode, ModuleRep, !Pos) :-
     read_len_string(ByteCode, ModuleName, !Pos),
+    trace [io(!IO), compiletime(flag("debug_oisu_bytecode"))] (
+        io.write_string("module rep for ", !IO),
+        io.write_string(ModuleName, !IO),
+        io.nl(!IO)
+    ),
     read_string_table(ByteCode, StringTable, !Pos),
-    read_proc_reps(ByteCode, StringTable, map.init, ProcReps, !Pos),
-    ModuleRep = module_rep(ModuleName, StringTable, ProcReps).
+    (
+        ExpectNewFormat = no,
+        OISUTypes = [],
+        map.init(TypeTable)
+    ;
+        ExpectNewFormat = yes,
+        read_num(ByteCode, NumOISUTypes, !Pos),
+        ( NumOISUTypes > 0 ->
+            OISUStartPos = !.Pos,
+            read_int32(ByteCode, OISUSize, !Pos),
+            trace [io(!IO), compiletime(flag("debug_oisu_bytecode"))] (
+                io.write_string("OISU num types ", !IO),
+                io.write_int(NumOISUTypes, !IO),
+                io.nl(!IO),
+                io.write_string("OISU bytecode size ", !IO),
+                io.write_int(OISUSize, !IO),
+                io.nl(!IO)
+            ),
+            read_n_items(read_oisu_type_procs(ByteCode), NumOISUTypes,
+                OISUTypes, !Pos),
+            expect(unify(!.Pos, OISUStartPos + OISUSize), $module, $pred,
+                "oisu limit mismatch")
+        ;
+            OISUTypes = []
+        ),
+        read_num(ByteCode, NumTableTypes, !Pos),
+        ( NumTableTypes > 0 ->
+            TypeStartPos = !.Pos,
+            read_int32(ByteCode, TypeSize, !Pos),
+            trace [io(!IO), compiletime(flag("debug_oisu_bytecode"))] (
+                io.write_string("num types ", !IO),
+                io.write_int(NumOISUTypes, !IO),
+                io.nl(!IO),
+                io.write_string("type bytecode size ", !IO),
+                io.write_int(TypeSize, !IO),
+                io.nl(!IO)
+            ),
+            read_n_encoded_types(ByteCode, StringTable, 0, NumTableTypes,
+                map.init, TypeTable, !Pos),
+            expect(unify(!.Pos, TypeStartPos + TypeSize), $module, $pred,
+                "type limit mismatch")
+        ;
+            map.init(TypeTable)
+        )
+    ),
+    read_proc_reps(ExpectNewFormat, ByteCode, StringTable, TypeTable,
+        map.init, ProcReps, !Pos),
+    ModuleRep = module_rep(ModuleName, StringTable, OISUTypes, TypeTable,
+        ProcReps).
 
-:- pred read_proc_reps(bytecode::in, string_table::in,
-    proc_map(unit)::in, proc_map(unit)::out, int::in, int::out)
-    is semidet.
+%-----------------------------------------------------------------------------%
+
+:- pred read_oisu_type_procs(bytecode::in, oisu_type_procs::out,
+    int::in, int::out) is semidet.
+
+read_oisu_type_procs(ByteCode, OISUTypeProcs, !Pos) :-
+    read_len_string(ByteCode, TypeCtorName, !Pos),
+    read_num(ByteCode, NumCreators, !Pos),
+    read_n_items(read_string_proc_label(ByteCode), NumCreators,
+        CreatorProcLabels, !Pos),
+    read_num(ByteCode, NumMutators, !Pos),
+    read_n_items(read_string_proc_label(ByteCode), NumMutators,
+        MutatorProcLabels, !Pos),
+    read_num(ByteCode, NumDestructors, !Pos),
+    read_n_items(read_string_proc_label(ByteCode), NumDestructors,
+        DestructorProcLabels, !Pos),
+    OISUTypeProcs = oisu_type_procs(TypeCtorName,
+        CreatorProcLabels, MutatorProcLabels, DestructorProcLabels).
+
+%-----------------------------------------------------------------------------%
+
+:- pred read_n_encoded_types(bytecode::in, string_table::in, int::in, int::in,
+    encoded_type_table::in, encoded_type_table::out,
+    int::in, int::out) is semidet.
 
-read_proc_reps(ByteCode, StringTable, !ProcReps, !Pos) :-
+read_n_encoded_types(ByteCode, StringTable, CurTypeNum, NumTableTypes,
+        !TypeTable, !Pos) :-
+    ( CurTypeNum < NumTableTypes ->
+        read_encoded_type(ByteCode, StringTable, !.TypeTable, TypeRep, !Pos),
+        map.det_insert(CurTypeNum, TypeRep, !TypeTable),
+        read_n_encoded_types(ByteCode, StringTable,
+            CurTypeNum + 1, NumTableTypes, !TypeTable, !Pos)
+    ;
+        true
+    ).
+
+:- pred read_encoded_type(bytecode::in, string_table::in,
+    encoded_type_table::in, type_rep::out, int::in, int::out) is semidet.
+
+read_encoded_type(ByteCode, StringTable, TypeTable, TypeRep, !Pos) :-
+    % The encoding read here is created by add_type_to_table in compiler/
+    % prog_rep_table.m. The code here and there must be kept in sync.
+    read_byte(ByteCode, Selector, !Pos),
+    (
+        Selector = 0,
+        read_string_via_offset(ByteCode, StringTable, TypeCtorStr, !Pos),
+        TypeCtorSymName = string_to_sym_name(TypeCtorStr),
+        TypeRep = defined_type_rep(TypeCtorSymName, [])
+    ;
+        Selector = 1,
+        read_string_via_offset(ByteCode, StringTable, TypeCtorStr, !Pos),
+        TypeCtorSymName = string_to_sym_name(TypeCtorStr),
+        read_num(ByteCode, TypeNumArg1, !Pos),
+        map.lookup(TypeTable, TypeNumArg1, TypeRepArg1),
+        TypeRep = defined_type_rep(TypeCtorSymName, [TypeRepArg1])
+    ;
+        Selector = 2,
+        read_string_via_offset(ByteCode, StringTable, TypeCtorStr, !Pos),
+        TypeCtorSymName = string_to_sym_name(TypeCtorStr),
+        read_num(ByteCode, TypeNumArg1, !Pos),
+        read_num(ByteCode, TypeNumArg2, !Pos),
+        map.lookup(TypeTable, TypeNumArg1, TypeRepArg1),
+        map.lookup(TypeTable, TypeNumArg2, TypeRepArg2),
+        TypeRep = defined_type_rep(TypeCtorSymName, [TypeRepArg1, TypeRepArg2])
+    ;
+        Selector = 3,
+        read_string_via_offset(ByteCode, StringTable, TypeCtorStr, !Pos),
+        TypeCtorSymName = string_to_sym_name(TypeCtorStr),
+        read_num(ByteCode, TypeNumArg1, !Pos),
+        read_num(ByteCode, TypeNumArg2, !Pos),
+        read_num(ByteCode, TypeNumArg3, !Pos),
+        map.lookup(TypeTable, TypeNumArg1, TypeRepArg1),
+        map.lookup(TypeTable, TypeNumArg2, TypeRepArg2),
+        map.lookup(TypeTable, TypeNumArg3, TypeRepArg3),
+        TypeRep = defined_type_rep(TypeCtorSymName,
+            [TypeRepArg1, TypeRepArg2, TypeRepArg3])
+    ;
+        Selector = 4,
+        read_string_via_offset(ByteCode, StringTable, TypeCtorStr, !Pos),
+        TypeCtorSymName = string_to_sym_name(TypeCtorStr),
+        read_num(ByteCode, NumArgs, !Pos),
+        read_n_items(read_num(ByteCode), NumArgs, TypeNumArgs, !Pos),
+        list.map(map.lookup(TypeTable), TypeNumArgs, TypeRepArgs),
+        TypeRep = defined_type_rep(TypeCtorSymName, TypeRepArgs)
+    ;
+        Selector = 5,
+        TypeRep = builtin_type_rep(builtin_type_int_rep)
+    ;
+        Selector = 6,
+        TypeRep = builtin_type_rep(builtin_type_float_rep)
+    ;
+        Selector = 7,
+        TypeRep = builtin_type_rep(builtin_type_string_rep)
+    ;
+        Selector = 8,
+        TypeRep = builtin_type_rep(builtin_type_char_rep)
+    ;
+        Selector = 9,
+        read_num(ByteCode, NumArgs, !Pos),
+        read_n_items(read_num(ByteCode), NumArgs, TypeNumArgs, !Pos),
+        list.map(map.lookup(TypeTable), TypeNumArgs, TypeRepArgs),
+        TypeRep = tuple_type_rep(TypeRepArgs)
+    ;
+        Selector = 10,
+        read_num(ByteCode, NumArgs, !Pos),
+        read_n_items(read_num(ByteCode), NumArgs, TypeNumArgs, !Pos),
+        list.map(map.lookup(TypeTable), TypeNumArgs, TypeRepArgs),
+        TypeRep = higher_order_type_rep(TypeRepArgs, no)
+    ;
+        Selector = 11,
+        read_num(ByteCode, NumArgs, !Pos),
+        read_n_items(read_num(ByteCode), NumArgs, TypeNumArgs, !Pos),
+        list.map(map.lookup(TypeTable), TypeNumArgs, TypeRepArgs),
+        read_num(ByteCode, TypeNumReturn, !Pos),
+        map.lookup(TypeTable, TypeNumReturn, TypeRepReturn),
+        TypeRep = higher_order_type_rep(TypeRepArgs, yes(TypeRepReturn))
+    ;
+        Selector = 12,
+        read_num(ByteCode, VarNum, !Pos),
+        TypeRep = type_var_rep(VarNum)
+    ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred read_proc_reps(bool::in, bytecode::in, string_table::in,
+    encoded_type_table::in, proc_map(unit)::in, proc_map(unit)::out,
+    int::in, int::out) is semidet.
+
+read_proc_reps(ExpectNewFormat, ByteCode, StringTable, TypeTable, !ProcReps,
+        !Pos) :-
     read_byte(ByteCode, MoreByte, !Pos),
     is_more_procs(MoreByte, MoreProcs),
     (
         MoreProcs = no_more_procs
     ;
         MoreProcs = next_proc,
-        read_proc_rep(ByteCode, StringTable, ProcRep, !Pos),
+        read_proc_rep(ExpectNewFormat, ByteCode, StringTable, TypeTable,
+            ProcRep, !Pos),
         map.det_insert(ProcRep ^ pr_id, ProcRep, !ProcReps),
-        read_proc_reps(ByteCode, StringTable, !ProcReps, !Pos)
+        read_proc_reps(ExpectNewFormat, ByteCode, StringTable, TypeTable,
+            !ProcReps, !Pos)
     ).
 
-:- pred read_proc_rep(bytecode::in, string_table::in, proc_rep(unit)::out,
-    int::in, int::out) is semidet.
+:- pred read_proc_rep(bool::in, bytecode::in, string_table::in,
+    encoded_type_table::in, proc_rep(unit)::out, int::in, int::out) is semidet.
 
-read_proc_rep(ByteCode, StringTable, ProcRep, !Pos) :-
+read_proc_rep(ExpectNewFormat, ByteCode, StringTable, TypeTable, ProcRep,
+        !Pos) :-
     read_string_proc_label(ByteCode, ProcLabel, !Pos),
     StartPos = !.Pos,
     read_int32(ByteCode, Size, !Pos),
     read_string_via_offset(ByteCode, StringTable, FileName, !Pos),
     Info = read_proc_rep_info(FileName),
-    read_var_table(ByteCode, StringTable, VarNumRep, VarTable, !Pos),
+    read_var_table(ExpectNewFormat, ByteCode, StringTable, TypeTable,
+        VarNumRep, VarNameTable, MaybeVarTypeTable, !Pos),
     read_head_vars(VarNumRep, ByteCode, HeadVars, !Pos),
     read_goal(VarNumRep, ByteCode, StringTable, Info, Goal, !Pos),
     read_determinism(ByteCode, Detism, !Pos),
-    ProcDefnRep = proc_defn_rep(HeadVars, Goal, VarTable, Detism),
-    require(unify(!.Pos, StartPos + Size),
-        "trace_read_proc_defn_rep: limit mismatch"),
+    ProcDefnRep = proc_defn_rep(HeadVars, Goal, VarNameTable,
+        MaybeVarTypeTable, Detism),
+    expect(unify(!.Pos, StartPos + Size), $module, $pred, "limit mismatch"),
     ProcRep = proc_rep(ProcLabel, ProcDefnRep).
 
 :- pred read_string_proc_label(bytecode::in, string_proc_label::out,
@@ -1076,36 +1363,92 @@
 
 %-----------------------------------------------------------------------------%
 
-    % Read the var table from the bytecode. The var table names all the
-    % variables used in the procedure representation.
-    %
-    % The representation of variables and the variable table restricts the
-    % number of possible variables in a procedure to 2^16.
-    %
-:- pred read_var_table(bytecode::in, string_table::in,  var_num_rep::out,
-    map(var_rep, string)::out, int::in, int::out) is semidet.
+    % Read the var table from the bytecode. The var table contains the names
+    % of all the variables used in the procedure representation, and may
+    % (or may not) also contain their types.
+    %
+:- pred read_var_table(bool::in, bytecode::in, string_table::in,
+    encoded_type_table::in, var_num_rep::out, var_name_table::out,
+    maybe(var_type_table)::out, int::in, int::out) is semidet.
 
-read_var_table(ByteCode, StringTable, VarNumRep, VarTable, !Pos) :-
+read_var_table(ExpectNewFormat, ByteCode, StringTable, TypeTable, VarNumRep,
+        VarNameTable, MaybeVarTypeTable, !Pos) :-
+    (
+        ExpectNewFormat = no,
     read_var_num_rep(ByteCode, VarNumRep, !Pos),
     read_int32(ByteCode, NumVarsInTable, !Pos),
-    read_var_table_entries(NumVarsInTable, VarNumRep, ByteCode, StringTable,
-        map.init, VarTable, !Pos).
+        read_var_name_table_entries(NumVarsInTable, VarNumRep, ByteCode,
+            StringTable, map.init, VarNameTable, !Pos),
+        MaybeVarTypeTable = no
+    ;
+        ExpectNewFormat = yes,
+        read_var_flag(ByteCode, VarNumRep, IncludeVarNameTable,
+            IncludeVarTypes, !Pos),
+        (
+            IncludeVarNameTable = do_not_include_var_name_table,
+            expect(unify(IncludeVarTypes, do_not_include_var_types),
+                $module, $pred, "var types but not names"),
+            map.init(VarNameTable),
+            MaybeVarTypeTable = no
+        ;
+            IncludeVarNameTable = include_var_name_table,
+            (
+                IncludeVarTypes = do_not_include_var_types,
+                read_num(ByteCode, NumVarsInTable, !Pos),
+                read_var_name_table_entries(NumVarsInTable, VarNumRep,
+                    ByteCode, StringTable, map.init, VarNameTable, !Pos),
+                MaybeVarTypeTable = no
+            ;
+                IncludeVarTypes = include_var_types,
+                read_num(ByteCode, NumVarsInTable, !Pos),
+                read_var_name_type_table_entries(NumVarsInTable, VarNumRep,
+                    ByteCode, StringTable, TypeTable, map.init, VarNameTable,
+                    map.init, VarTypeTable, !Pos),
+                MaybeVarTypeTable = yes(VarTypeTable)
+            )
+        )
+    ).
 
-    % Read entries from the symbol table until the number of entries left to
-    % read is zero.
+    % Read entries from the variable name table until there are no more
+    % entries left to read.
     %
-:- pred read_var_table_entries(var_rep::in, var_num_rep::in, bytecode::in,
-    string_table::in, map(var_rep, string)::in, map(var_rep, string)::out,
+:- pred read_var_name_table_entries(var_rep::in, var_num_rep::in,
+    bytecode::in, string_table::in, var_name_table::in, var_name_table::out,
     int::in, int::out) is semidet.
 
-read_var_table_entries(NumVarsInTable, VarNumRep, ByteCode, StringTable,
-        !VarTable, !Pos) :-
-    ( NumVarsInTable > 0 ->
+read_var_name_table_entries(NumVarsLeftInTable, VarNumRep,
+        ByteCode, StringTable, !VarNameTable, !Pos) :-
+    ( NumVarsLeftInTable > 0 ->
         read_var(VarNumRep, ByteCode, VarRep, !Pos),
         read_string_via_offset(ByteCode, StringTable, VarName, !Pos),
-        map.insert(VarRep, VarName, !VarTable),
-        read_var_table_entries(NumVarsInTable - 1, VarNumRep, ByteCode,
-            StringTable, !VarTable, !Pos)
+        map.det_insert(VarRep, VarName, !VarNameTable),
+        read_var_name_table_entries(NumVarsLeftInTable - 1, VarNumRep,
+            ByteCode, StringTable, !VarNameTable, !Pos)
+    ;
+        % No more variables to read.
+        true
+    ).
+
+    % Read entries from the variable name and type table until
+    % there are no more entries left to read.
+    %
+:- pred read_var_name_type_table_entries(var_rep::in, var_num_rep::in,
+    bytecode::in, string_table::in, encoded_type_table::in,
+    var_name_table::in, var_name_table::out,
+    var_type_table::in, var_type_table::out, int::in, int::out) is semidet.
+
+read_var_name_type_table_entries(NumVarsLeftInTable, VarNumRep,
+        ByteCode, StringTable, TypeTable, !VarNameTable, !VarTypeTable, !Pos) :-
+    ( NumVarsLeftInTable > 0 ->
+        read_var(VarNumRep, ByteCode, VarRep, !Pos),
+        read_string_via_offset(ByteCode, StringTable, VarName, !Pos),
+        map.det_insert(VarRep, VarName, !VarNameTable),
+        read_num(ByteCode, TypeNum, !Pos),
+        map.lookup(TypeTable, TypeNum, TypeRep),
+        map.det_insert(VarRep, TypeRep, !VarTypeTable),
+        read_var_name_type_table_entries(NumVarsLeftInTable - 1, VarNumRep,
+            ByteCode, StringTable, TypeTable, !VarNameTable, !VarTypeTable,
+            !Pos)
     ;
         % No more variables to read.
         true
@@ -1118,10 +1461,10 @@
 
 trace_read_proc_defn_rep(Bytes, LabelLayout, ProcDefnRep) :-
     ProcLayout = containing_proc_layout(LabelLayout),
-    ( containing_module_common_layout(ProcLayout, ModuleCommonLayout) ->
-        StringTable = module_common_string_table(ModuleCommonLayout)
+    ( containing_module_layout(ProcLayout, ModuleLayout) ->
+        StringTable = module_string_table(ModuleLayout)
     ;
-        error("trace_read_proc_defn_rep: no module common layout")
+        unexpected($module, $pred, "no module layout")
     ),
     some [!Pos] (
         !:Pos = 0,
@@ -1132,18 +1475,22 @@
         ByteCode = bytecode(Bytes, Size),
         read_string_via_offset(ByteCode, StringTable, FileName, !Pos),
         Info = read_proc_rep_info(FileName),
-        read_var_table(ByteCode, StringTable, VarNumRep, VarTable, !Pos),
+        % The declarative debugger does not need variable type representations
+        % from the bytecode. It has access to actual type_infos in label
+        % layouts.
+        ExpectNewFormat = yes,
+        read_var_table(ExpectNewFormat, ByteCode, StringTable,
+            map.init, VarNumRep, VarNameTable, _MaybeVarTypeTable, !Pos),
         read_head_vars(VarNumRep, ByteCode, HeadVars, !Pos),
         read_goal(VarNumRep, ByteCode, StringTable, Info, Goal, !Pos),
         read_determinism(ByteCode, Detism, !Pos),
-        ProcDefnRep = proc_defn_rep(HeadVars, Goal, VarTable, Detism),
-        require(unify(!.Pos, Size),
-            "trace_read_proc_defn_rep: limit mismatch")
+        ProcDefnRep = proc_defn_rep(HeadVars, Goal, VarNameTable, no, Detism),
+        expect(unify(!.Pos, Size), $module, $pred, "limit mismatch")
     ).
 
 :- type read_proc_rep_info
     --->    read_proc_rep_info(
-                filename    :: string
+                rpri_filename       :: string
             ).
 
 :- pred read_goal(var_num_rep::in, bytecode::in, string_table::in,
@@ -1228,7 +1575,7 @@
             ( cut_byte(MaybeCutPrime, MaybeCutByte) ->
                 MaybeCut = MaybeCutPrime
             ;
-                error("read_goal: bad maybe_cut")
+                unexpected($module, $pred, "bad maybe_cut")
             ),
             read_goal(VarNumRep, ByteCode, StringTable, Info, SubGoal, !Pos),
             GoalExpr = scope_rep(SubGoal, MaybeCut)
@@ -1287,7 +1634,7 @@
         read_determinism(ByteCode, Detism, !Pos),
         Goal = goal_rep(GoalExpr, Detism, unit)
     ;
-        error("read_goal: invalid goal type")
+        unexpected($module, $pred, "invalid goal type")
     ).
 
 :- pred read_atomic_info(var_num_rep::in, bytecode::in, string_table::in,
@@ -1298,7 +1645,7 @@
         !Pos) :-
     read_string_via_offset(ByteCode, StringTable, FileName0, !Pos),
     ( FileName0 = "" ->
-        FileName = Info ^ filename
+        FileName = Info ^ rpri_filename
     ;
         FileName = FileName0
     ),
@@ -1383,7 +1730,7 @@
     ; YesOrNo = 0 ->
         MaybeVar = no
     ;
-        error("read_maybe_var: invalid yes or no flag")
+        unexpected($module, $pred, "invalid yes or no flag")
     ).
 
 :- pred read_head_vars(var_num_rep::in, bytecode::in,
@@ -1434,10 +1781,28 @@
 
 read_var_num_rep(ByteCode, VarNumRep, !Pos) :-
     read_byte(ByteCode, Byte, !Pos),
-    ( var_num_rep_byte(VarNumRep0, Byte) ->
-        VarNumRep = VarNumRep0
+    ( var_num_rep_byte(VarNumRepPrime, Byte) ->
+        VarNumRep = VarNumRepPrime
     ;
-        error("read_var_num_rep: unknown var_num_rep")
+        unexpected($module, $pred, "unknown var_num_rep")
+    ).
+
+:- pred read_var_flag(bytecode::in, var_num_rep::out,
+    maybe_include_var_name_table::out, maybe_include_var_types::out,
+    int::in, int::out) is semidet.
+
+read_var_flag(ByteCode, VarNumRep, IncludeVarNameTable, IncludeVarTypes,
+        !Pos) :-
+    read_byte(ByteCode, Byte, !Pos),
+    (
+        var_flag_byte(VarNumRepPrime,
+            IncludeVarNameTablePrime, IncludeVarTypesPrime, Byte)
+    ->
+        VarNumRep = VarNumRepPrime,
+        IncludeVarNameTable = IncludeVarNameTablePrime,
+        IncludeVarTypes = IncludeVarTypesPrime
+    ;
+        unexpected($module, $pred, "unknown var_flag_byte")
     ).
 
 :- pred read_determinism(bytecode::in, detism_rep::out, int::in, int::out)
@@ -1448,7 +1813,7 @@
     ( determinism_representation(DetismPrime, DetismByte) ->
         Detism = DetismPrime
     ;
-        error("read_goal: bad detism")
+        unexpected($module, $pred, "bad detism")
     ).
 
 :- pred read_switch_can_fail(bytecode::in, switch_can_fail_rep::out,
@@ -1467,7 +1832,7 @@
     ->
         CanFail = CanFailPrime
     ;
-        error("read_goal: bad switch_can_fail")
+        unexpected($module, $pred, "bad switch_can_fail")
     ).
 
 cut_byte(scope_is_no_cut, 0).
@@ -1476,6 +1841,8 @@
 can_fail_byte(switch_can_fail_rep, 0).
 can_fail_byte(switch_can_not_fail_rep, 1).
 
+%-----------------------------------------------------------------------------%
+
     % An abstraction to read the given number of items using the higher order
     % predicate.
     %
Index: mdbcomp/rtti_access.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/rtti_access.m,v
retrieving revision 1.21
diff -u -b -r1.21 rtti_access.m
--- mdbcomp/rtti_access.m	26 Sep 2011 04:29:36 -0000	1.21
+++ mdbcomp/rtti_access.m	24 Oct 2012 03:50:13 -0000
@@ -47,7 +47,7 @@
 
 :- func get_proc_name(proc_label) = string.
 
-    % find_initial_version_arg_num(Proc, OutputArgNum, InputArgNum).
+    % find_initial_version_arg_num(Proc, OutputArgNum, InputArgNum):
     %
     % Given a procedure and an output argument number of that procedure,
     % find an input argument which has the same name as the output argument,
@@ -56,9 +56,9 @@
     % input argument's numerical suffix should be less that the numerical
     % suffix of the output argument.  This procedure is used as a heuristic to
     % determine when it is worth checking if a subterm appearing in the output
-    % argument also appears in the same position in the input argument.  The
-    % heuristic is used by the subterm dependency tracking algorithm to help
-    % speed up the search.
+    % argument also appears in the same position in the input argument.
+    % The heuristic is used by the subterm dependency tracking algorithm
+    % to help speed up the search.
     % Argument numbers start at one.
     % This procedure is implemented in C to avoid having to allocate memory
     % to import non-word-aligned strings into Mercury code.
@@ -77,18 +77,20 @@
 :- type string_table
     --->    string_table(
                 string_table_chars,
-                            % The characters of the string table, which
-                            % may include null characters.
-                int         % The number of characters in the string table.
+                % The characters of the string table, which may include
+                % null characters.
+
+                int
+                % The number of characters in the string table.
             ).
 
-:- type module_common_layout.
+:- type module_layout.
 :- type string_table_chars.
 
-:- pred containing_module_common_layout(proc_layout::in,
-    module_common_layout::out) is semidet.
+:- pred containing_module_layout(proc_layout::in, module_layout::out)
+    is semidet.
 
-:- func module_common_string_table(module_common_layout) = string_table.
+:- func module_string_table(module_layout) = string_table.
 
 :- func lookup_string_table(string_table, int) = string.
 
@@ -96,7 +98,7 @@
 
 :- type bytecode
     --->    bytecode(
-                bytecode_bytes,     % The bytes of the bytecode.`
+                bytecode_bytes,     % The bytes of the bytecode.
                 int                 % The number of bytes in the bytecode.
             ).
 
@@ -169,6 +171,27 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred encode_byte(int::in, list(int)::out) is semidet.
+:- pred encode_byte_det(int::in, list(int)::out) is det.
+:- func encode_byte_func(int) = list(int).
+
+:- pred encode_short(int::in, list(int)::out) is semidet.
+:- pred encode_short_det(int::in, list(int)::out) is det.
+:- func encode_short_func(int) = list(int).
+
+:- pred encode_int32(int::in, list(int)::out) is semidet.
+:- pred encode_int32_det(int::in, list(int)::out) is det.
+:- func encode_int32_func(int) = list(int).
+
+:- pred encode_num(int::in, list(int)::out) is semidet.
+:- pred encode_num_det(int::in, list(int)::out) is det.
+:- func encode_num_func(int) = list(int).
+
+:- pred encode_len_string(string::in, list(int)::out) is det.
+:- func encode_len_string_func(string) = list(int).
+
+%-----------------------------------------------------------------------------%
+
 :- implementation.
 
 :- import_module char.
@@ -584,13 +607,12 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pragma foreign_type("C", module_common_layout,
-    "const MR_ModuleCommonLayout *",
+:- pragma foreign_type("C", module_layout, "const MR_ModuleLayout *",
     [can_pass_as_mercury_type, stable]).
     % The following definitions are only stubs.
-:- pragma foreign_type("C#", module_common_layout, "object", []).
-:- pragma foreign_type("Java", module_common_layout, "java.lang.Object", []).
-:- pragma foreign_type("Erlang", module_common_layout, "").
+:- pragma foreign_type("C#", module_layout, "object", []).
+:- pragma foreign_type("Java", module_layout, "java.lang.Object", []).
+:- pragma foreign_type("Erlang", module_layout, "").
 
 :- pragma foreign_type("C", string_table_chars, "MR_ConstString",
     [can_pass_as_mercury_type, stable]).
@@ -600,31 +622,31 @@
 :- pragma foreign_type("Erlang", string_table_chars, "").
 
 :- pragma foreign_proc("C",
-    containing_module_common_layout(ProcLayout::in, ModuleCommonLayout::out),
+    containing_module_layout(ProcLayout::in, ModuleLayout::out),
     [will_not_call_mercury, thread_safe, promise_pure],
 "
     if (MR_PROC_LAYOUT_HAS_THIRD_GROUP(ProcLayout)) {
-        ModuleCommonLayout = ProcLayout->MR_sle_module_common_layout;
+        ModuleLayout = ProcLayout->MR_sle_module_layout;
         SUCCESS_INDICATOR = MR_TRUE;
     } else {
         SUCCESS_INDICATOR = MR_FALSE;
     }
 ").
 
-module_common_string_table(ModuleCommonLayout) = StringTable :-
-    module_string_table_components(ModuleCommonLayout, StringTableChars, Size),
+module_string_table(ModuleLayout) = StringTable :-
+    module_string_table_components(ModuleLayout, StringTableChars, Size),
     StringTable = string_table(StringTableChars, Size).
 
-:- pred module_string_table_components(module_common_layout::in,
+:- pred module_string_table_components(module_layout::in,
     string_table_chars::out, int::out) is det.
 
 :- pragma foreign_proc("C",
-    module_string_table_components(ModuleCommonLayout::in,
+    module_string_table_components(ModuleLayout::in,
         StringTableChars::out, Size::out),
     [will_not_call_mercury, thread_safe, promise_pure],
 "
-    StringTableChars = ModuleCommonLayout->MR_mlc_string_table;
-    Size = ModuleCommonLayout->MR_mlc_string_table_size;
+    StringTableChars = ModuleLayout->MR_ml_string_table;
+    Size = ModuleLayout->MR_ml_string_table_size;
 ").
 
 lookup_string_table(StringTable, NameCode) = Str :-
@@ -782,5 +804,94 @@
 ").
 
 %-----------------------------------------------------------------------------%
+
+encode_byte(Byte, [Byte]) :-
+    Byte >= 0,
+    Byte < 128.
+
+encode_byte_det(Byte, Bytes) :-
+    ( encode_byte(Byte, BytesPrime) ->
+        Bytes = BytesPrime
+    ;
+        unexpected($module, $pred, "encode_byte failed")
+    ).
+
+encode_byte_func(Byte) = Bytes :-
+    encode_byte_det(Byte, Bytes).
+
+encode_short(Short, [Byte1, Byte2]) :-
+    Short >= 0,
+    Byte2 = Short /\ 255,
+    Byte1 = Short / 256,
+    Byte1 < 128.
+
+encode_short_det(Short, Bytes) :-
+    ( encode_short(Short, BytesPrime) ->
+        Bytes = BytesPrime
+    ;
+        unexpected($module, $pred, "encode_short failed")
+    ).
+
+encode_short_func(Short) = Bytes :-
+    encode_short_det(Short, Bytes).
+
+encode_int32(Int32, [Byte1, Byte2, Byte3, Byte4]) :-
+    Int32 >= 0,
+    Byte4 = Int32 /\ 255,
+    Bytes123 = Int32 / 256,
+    Byte3 = Bytes123 /\ 255,
+    Bytes12 = Bytes123 / 256,
+    Byte2 = Bytes12 /\ 255,
+    Byte1 = Bytes12 / 256,
+    Byte1 < 128.
+
+encode_int32_det(Int32, Bytes) :-
+    ( encode_int32(Int32, BytesPrime) ->
+        Bytes = BytesPrime
+    ;
+        unexpected($module, $pred, "encode_int32 failed")
+    ).
+
+encode_int32_func(Int32) = Bytes :-
+    encode_int32_det(Int32, Bytes).
+
+encode_num(Num, Bytes) :-
+    Num >= 0,
+    LastByte = Num /\ 127,
+    NextNum = Num / 128,
+    encode_num_2(NextNum, [LastByte], Bytes).
+
+:- pred encode_num_2(int::in, list(int)::in, list(int)::out) is det.
+
+encode_num_2(Num, RestBytes, Bytes) :-
+    ( Num = 0 ->
+        Bytes = RestBytes
+    ;
+        CurByte = (Num /\ 127) \/ 128,
+        NextNum = Num / 128,
+        encode_num_2(NextNum, [CurByte | RestBytes], Bytes)
+    ).
+
+encode_num_det(Num, Bytes) :-
+    ( encode_num(Num, BytesPrime) ->
+        Bytes = BytesPrime
+    ;
+        unexpected($module, $pred, "encode_num failed")
+    ).
+
+encode_num_func(Num) = Bytes :-
+    encode_num_det(Num, Bytes).
+
+encode_len_string(String, Bytes) :-
+    string.length(String, Length),
+    encode_num_det(Length, LengthBytes),
+    string.to_char_list(String, Chars),
+    CharBytes = list.map(char.to_int, Chars),
+    Bytes = LengthBytes ++ CharBytes.
+
+encode_len_string_func(String) = Bytes :-
+    encode_len_string(String, Bytes).
+
+%-----------------------------------------------------------------------------%
 :- end_module mdbcomp.rtti_access.
 %-----------------------------------------------------------------------------%
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_deep_profiling.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_deep_profiling.c,v
retrieving revision 1.39
diff -u -b -r1.39 mercury_deep_profiling.c
--- runtime/mercury_deep_profiling.c	14 Dec 2011 03:26:01 -0000	1.39
+++ runtime/mercury_deep_profiling.c	24 Oct 2012 03:50:13 -0000
@@ -758,10 +758,10 @@
 MR_write_out_procrep_id_string(FILE *fp)
 {
     /*
-    ** Must be the same as procrep_id_string in
-    ** mdbcomp/program_representation.m
+    ** Must be the same as procrep_id_string (or new_procrep_id_string) in
+    ** mdbcomp/program_representation.m.
     */
-    const char  *id_string = "Mercury deep profiler procrep version 5\n";
+    const char  *id_string = "Mercury deep profiler procrep version 6\n";
 
     fputs(id_string, fp);
 }
@@ -796,15 +796,56 @@
 
 void
 MR_write_out_module_proc_reps_start(FILE *procrep_fp,
-    const MR_ModuleCommonLayout *module_common)
+    const MR_ModuleLayout *module_layout)
 {
-    int         i;
+    const MR_uint_least8_t  *oisu_bytecode;
+    const MR_uint_least8_t  *type_bytecode;
+    int                     size;
+    int                     bytenum;
 
     putc(MR_next_module, procrep_fp);
-    MR_write_string(procrep_fp, module_common->MR_mlc_name);
-    MR_write_num(procrep_fp, module_common->MR_mlc_string_table_size);
-    for (i = 0; i < module_common->MR_mlc_string_table_size; i++) {
-        putc(module_common->MR_mlc_string_table[i], procrep_fp);
+    MR_write_string(procrep_fp, module_layout->MR_ml_name);
+
+    MR_write_num(procrep_fp, module_layout->MR_ml_string_table_size);
+    size = module_layout->MR_ml_string_table_size;
+    for (bytenum = 0; bytenum < size; bytenum++) {
+        putc(module_layout->MR_ml_string_table[bytenum], procrep_fp);
+    }
+
+    MR_write_num(procrep_fp, module_layout->MR_ml_num_oisu_types);
+    oisu_bytecode = module_layout->MR_ml_oisu_bytes;
+    if (module_layout->MR_ml_num_oisu_types == 0) {
+        if (oisu_bytecode != NULL) {
+            MR_fatal_error("num_oisu_types == 0 but bytecode != NULL");
+        }
+    } else {
+        if (oisu_bytecode == NULL) {
+            MR_fatal_error("num_oisu_types != 0 but bytecode == NULL");
+        }
+
+        size = (oisu_bytecode[0] << 24) + (oisu_bytecode[1] << 16) +
+            (oisu_bytecode[2] << 8) + oisu_bytecode[3];
+        for (bytenum = 0; bytenum < size; bytenum++) {
+            putc(oisu_bytecode[bytenum], procrep_fp);
+        }
+    }
+
+    MR_write_num(procrep_fp, module_layout->MR_ml_num_table_types);
+    type_bytecode = module_layout->MR_ml_type_table_bytes;
+    if (module_layout->MR_ml_num_table_types == 0) {
+        if (type_bytecode != NULL) {
+            MR_fatal_error("num_types == 0 but bytecode != NULL");
+        }
+    } else {
+        if (type_bytecode == NULL) {
+            MR_fatal_error("num_types != 0 but bytecode == NULL");
+        }
+
+        size = (type_bytecode[0] << 24) + (type_bytecode[1] << 16) +
+            (type_bytecode[2] << 8) + type_bytecode[3];
+        for (bytenum = 0; bytenum < size; bytenum++) {
+            putc(type_bytecode[bytenum], procrep_fp);
+        }
     }
 }
 
Index: runtime/mercury_deep_profiling.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_deep_profiling.h,v
retrieving revision 1.22
diff -u -b -r1.22 mercury_deep_profiling.h
--- runtime/mercury_deep_profiling.h	21 Sep 2010 01:09:17 -0000	1.22
+++ runtime/mercury_deep_profiling.h	24 Oct 2012 03:50:13 -0000
@@ -157,6 +157,10 @@
 	MR_next_proc
 } MR_MoreProcs;
 
+/*
+** The definition of this type should be kept in sync with the code of
+** the string_proclabel_kind_* functions in compiler/prog_rep.m.
+*/
 typedef enum {
 	MR_proclabel_user_predicate,
 	MR_proclabel_user_function,
@@ -449,7 +453,7 @@
 extern	void	MR_write_out_proc_static(FILE *deep_fp, FILE *procrep_fp,
 			const MR_ProcLayout *proc_layout);
 extern	void	MR_write_out_module_proc_reps_start(FILE *procrep_fp,
-			const MR_ModuleCommonLayout *module_common);
+			const MR_ModuleLayout *module_layout);
 extern	void	MR_write_out_module_proc_reps_end(FILE *procrep_fp);
 extern	void	MR_write_out_profiling_tree(void);
 
Index: runtime/mercury_grade.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_grade.h,v
retrieving revision 1.87
diff -u -b -r1.87 mercury_grade.h
--- runtime/mercury_grade.h	26 Sep 2011 04:30:47 -0000	1.87
+++ runtime/mercury_grade.h	24 Oct 2012 03:50:13 -0000
@@ -65,8 +65,8 @@
 */
 
 #define MR_GRADE_PART_0 v18_
-#define MR_GRADE_EXEC_TRACE_VERSION_NO  10
-#define MR_GRADE_DEEP_PROF_VERSION_NO   3
+#define MR_GRADE_EXEC_TRACE_VERSION_NO  11
+#define MR_GRADE_DEEP_PROF_VERSION_NO   4
 #define MR_GRADE_LLC_PAR_VERSION_NO 1
 
 #ifdef MR_HIGHLEVEL_CODE
Index: runtime/mercury_stack_layout.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_layout.c,v
retrieving revision 1.4
diff -u -b -r1.4 mercury_stack_layout.c
--- runtime/mercury_stack_layout.c	26 Sep 2011 04:29:37 -0000	1.4
+++ runtime/mercury_stack_layout.c	24 Oct 2012 03:50:13 -0000
@@ -21,14 +21,14 @@
 MR_hlds_var_name(const MR_ProcLayout *entry, int hlds_var_num,
     int *should_copy)
 {
-    const MR_ModuleCommonLayout *module_common;
+    const MR_ModuleLayout   *module_layout;
     const char                  *string_table;
     MR_Integer                  string_table_size;
     int                         name_code;
 
-    module_common = entry->MR_sle_module_common_layout;
-    string_table = module_common->MR_mlc_string_table;
-    string_table_size = module_common->MR_mlc_string_table_size;
+    module_layout = entry->MR_sle_module_layout;
+    string_table = module_layout->MR_ml_string_table;
+    string_table_size = module_layout->MR_ml_string_table_size;
 
     if (hlds_var_num == 0) {
         /* this value is not a variable */
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.125
diff -u -b -r1.125 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h	5 Jun 2012 18:19:32 -0000	1.125
+++ runtime/mercury_stack_layout.h	24 Oct 2012 03:50:13 -0000
@@ -1067,7 +1067,7 @@
     MR_STATIC_CODE_CONST MR_ExecTrace   *MR_sle_exec_trace;
     MR_ProcStatic                       *MR_sle_proc_static;
     const MR_uint_least8_t              *MR_sle_body_bytes;
-    const MR_ModuleCommonLayout         *MR_sle_module_common_layout;
+    const MR_ModuleLayout               *MR_sle_module_layout;
 };
 
 typedef struct MR_ProcLayoutUser_Struct {
@@ -1076,7 +1076,7 @@
     MR_STATIC_CODE_CONST MR_ExecTrace   *MR_sle_exec_trace;
     MR_ProcStatic                       *MR_sle_proc_static;
     const MR_uint_least8_t              *MR_sle_body_bytes;
-    const MR_ModuleCommonLayout         *MR_sle_module_common_layout;
+    const MR_ModuleLayout               *MR_sle_module_layout;
 } MR_ProcLayoutUser;
 
 typedef struct MR_ProcLayoutUCI_Struct {
@@ -1085,7 +1085,7 @@
     MR_STATIC_CODE_CONST MR_ExecTrace   *MR_sle_exec_trace;
     MR_ProcStatic                       *MR_sle_proc_static;
     const MR_uint_least8_t              *MR_sle_body_bytes;
-    const MR_ModuleCommonLayout         *MR_sle_module_common_layout;
+    const MR_ModuleLayout               *MR_sle_module_layout;
 } MR_ProcLayoutUCI;
 
 typedef struct MR_ProcLayout_Traversal_Struct {
@@ -1446,21 +1446,27 @@
 ** compiler/layout_out.m.
 */
 
-#define MR_LAYOUT_VERSION                   MR_LAYOUT_VERSION__COMMON
+#define MR_LAYOUT_VERSION                   MR_LAYOUT_VERSION__OISU
 #define MR_LAYOUT_VERSION__USER_DEFINED     1
 #define MR_LAYOUT_VERSION__EVENTSETNAME     2
 #define MR_LAYOUT_VERSION__SYNTH_ATTR       3
 #define MR_LAYOUT_VERSION__COMMON           4
-
-struct MR_ModuleCommonLayout_Struct {
-    MR_uint_least8_t                MR_mlc_version_number;
-    MR_ConstString                  MR_mlc_name;
-    MR_Integer                      MR_mlc_string_table_size;
-    const char                      *MR_mlc_string_table;
-};
+#define MR_LAYOUT_VERSION__OISU             5
 
 struct MR_ModuleLayout_Struct {
-    const MR_ModuleCommonLayout     *MR_ml_common;
+    /* The fields that are of interest to both deep profiling and debugging. */
+    MR_uint_least8_t                MR_ml_version_number;
+    MR_ConstString                  MR_ml_name;
+    MR_Integer                      MR_ml_string_table_size;
+    const char                      *MR_ml_string_table;
+
+    /* The fields that are of interest only to deep profiling. */
+    MR_Integer                      MR_ml_num_oisu_types;
+    const MR_uint_least8_t          *MR_ml_oisu_bytes;
+    MR_Integer                      MR_ml_num_table_types;
+    const MR_uint_least8_t          *MR_ml_type_table_bytes;
+
+    /* The fields that are of interest only to debugging. */
     MR_Integer                      MR_ml_proc_count;
     const MR_ProcLayout             **MR_ml_procs;
     MR_Integer                      MR_ml_filename_count;
@@ -1476,11 +1482,6 @@
     MR_UserEventSpec                *MR_ml_user_event_specs;
 };
 
-#define MR_ml_version_number        MR_ml_common->MR_mlc_version_number
-#define MR_ml_name                  MR_ml_common->MR_mlc_name
-#define MR_ml_string_table_size     MR_ml_common->MR_mlc_string_table_size
-#define MR_ml_string_table          MR_ml_common->MR_mlc_string_table
-
 /*-------------------------------------------------------------------------*/
 /*
 ** Definitions for MR_ClosureId.
Index: runtime/mercury_types.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_types.h,v
retrieving revision 1.63
diff -u -b -r1.63 mercury_types.h
--- runtime/mercury_types.h	2 Aug 2011 08:28:19 -0000	1.63
+++ runtime/mercury_types.h	24 Oct 2012 03:50:13 -0000
@@ -255,7 +255,6 @@
 typedef struct MR_CallSiteDynList_Struct        MR_CallSiteDynList;
 
 typedef struct MR_ProcLayout_Struct             MR_ProcLayout;
-typedef struct MR_ModuleCommonLayout_Struct     MR_ModuleCommonLayout;
 typedef struct MR_ModuleLayout_Struct           MR_ModuleLayout;
 typedef struct MR_LabelLayout_Struct            MR_LabelLayout;
 typedef struct MR_SynthAttr_Struct              MR_SynthAttr;
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing runtime/notes
cvs diff: Diffing samples
cvs diff: Diffing samples/appengine
cvs diff: Diffing samples/appengine/war
cvs diff: Diffing samples/appengine/war/WEB-INF
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/concurrency
cvs diff: Diffing samples/concurrency/dining_philosophers
cvs diff: Diffing samples/concurrency/midimon
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/java_interface
cvs diff: Diffing samples/java_interface/java_calls_mercury
cvs diff: Diffing samples/java_interface/mercury_calls_java
cvs diff: Diffing samples/lazy_list
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
Index: tests/debugger/declarative/dependency.exp2
===================================================================
RCS file: tests/debugger/declarative/dependency.exp2
diff -N tests/debugger/declarative/dependency.exp2
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/declarative/dependency.exp2	24 Oct 2012 03:50:14 -0000
@@ -0,0 +1,102 @@
+       1:      1  1 CALL pred dependency.main/2-0 (cc_multi) dependency.m:11
+mdb> echo on
+Command echo enabled.
+mdb> register --quiet
+mdb> goto 3
+       3:      2  2 EXIT pred dependency.turn_on_origin_debug/0-0 (det) dependency.m:69 (dependency.m:12)
+mdb> dd -d 3 -n 7
+turn_on_origin_debug
+Valid? browse 1
+Invalid argument number
+dd> quit
+Diagnosis aborted.
+       3:      2  2 EXIT pred dependency.turn_on_origin_debug/0-0 (det) dependency.m:69 (dependency.m:12)
+mdb> step
+       4:      3  2 CALL pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
+mdb> finish
+      18:      3  2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
+mdb> format_param depth 20
+mdb> format_param size 201
+mdb> format raw_pretty
+mdb> p proc_body
+	
+proc_defn_rep(
+  [|](head_var_rep(1, var_mode_rep(ir_free_rep, ir_ground_rep)), []), 
+  goal_rep(
+    conj_rep(
+      [|](
+        goal_rep(atomic_goal_rep/4, det_rep, unit), 
+        [|](goal_rep/3, [|](goal_rep/3, [|]/2)))), 
+    cc_multidet_rep, 
+    unit), 
+  empty, 
+  no, 
+  cc_multidet_rep)
+mdb> dd -d 3 -n 7
+test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
+Valid? browse 1
+browser> ^1
+browser> mark
+Origin: origin_primitive_op("dependency.m", 22, primop_unification)
+p(1)
+Valid? quit
+Diagnosis aborted.
+      18:      3  2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
+mdb> dd -d 3 -n 7
+test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
+Valid? browse 1
+browser> ^2^1
+browser> mark
+Origin: output(r, any_head_var_from_back(1), [1])
+r(1, [|](3, [|](4, [])), -(3, 4))
+Valid? browse 2
+browser> print
+[|](3, [|](4, []))
+browser> mark
+Origin: origin_primitive_op("dependency.m", 29, primop_unification)
+p(1)
+Valid? quit
+Diagnosis aborted.
+      18:      3  2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
+mdb> dd -d 3 -n 7
+test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
+Valid? browse 1
+browser> ^2^2^1
+browser> mark
+Origin: origin_primitive_op("dependency.m", 41, primop_unification)
+p(1)
+Valid? quit
+Diagnosis aborted.
+      18:      3  2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
+mdb> dd -d 3 -n 7
+test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
+Valid? browse 1
+browser> ^2^2^2^1
+browser> mark
+Origin: origin_primitive_op("dependency.m", 22, primop_unification)
+p(1)
+Valid? quit
+Diagnosis aborted.
+      18:      3  2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
+mdb> dd -d 3 -n 7
+test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
+Valid? browse 1
+browser> ^2^2^2^2^1
+browser> mark
+Origin: output(r, any_head_var_from_back(1), [1])
+r(1, [|](3, [|](4, [])), -(3, 4))
+Valid? quit
+Diagnosis aborted.
+      18:      3  2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
+mdb> dd -d 3 -n 7
+test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
+Valid? browse 1
+browser> ^2^2^2^2^2
+browser> mark
+Origin: origin_primitive_op("dependency.m", 43, primop_unification)
+p(1)
+Valid? quit
+Diagnosis aborted.
+      18:      3  2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
+mdb> continue
+[1, 3, 6, 1, 3].
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/feedback
cvs diff: Diffing tests/feedback/mandelbrot
cvs diff: Diffing tests/feedback/mmc
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/stm
cvs diff: Diffing tests/stm/orig
cvs diff: Diffing tests/stm/orig/stm-compiler
cvs diff: Diffing tests/stm/orig/stm-compiler/test1
cvs diff: Diffing tests/stm/orig/stm-compiler/test10
cvs diff: Diffing tests/stm/orig/stm-compiler/test2
cvs diff: Diffing tests/stm/orig/stm-compiler/test3
cvs diff: Diffing tests/stm/orig/stm-compiler/test4
cvs diff: Diffing tests/stm/orig/stm-compiler/test5
cvs diff: Diffing tests/stm/orig/stm-compiler/test6
cvs diff: Diffing tests/stm/orig/stm-compiler/test7
cvs diff: Diffing tests/stm/orig/stm-compiler/test8
cvs diff: Diffing tests/stm/orig/stm-compiler/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/stmqueue
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test10
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test11
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test9
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
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