[m-rev.] for review: switch generation cleanups

Zoltan Somogyi zs at csse.unimelb.edu.au
Mon Nov 26 13:42:35 AEDT 2007


For review by anyone.

Zoltan.

Make the code in the LLDS backend that handles switches more systematic:
clarify the code that decides what kind of switch we will generate, make it
more configurable, document the decision algorithm better, rename predicates
to make their purpose clearer and avoid ambiguities,

compiler/switch_gen.m:
compiler/dense_switch.m:
	Make the changes listed above.

compiler/options.m:
	Add two new options that allow some decisions of switch_gen to be
	controlled by the user.

compiler/code_info.m:
	Add a utility predicate for use by switch_gen.m.

compiler/code_gen.m:
compiler/disj_gen.m:
compiler/middle_rec.m:
compiler/pragma_c_gen.m:
compiler/proc_gen.m:
compiler/trace_gen.m:
compiler/unify_gen.m:
	Delete unnecessary module qualifications.

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/include
cvs diff: Diffing boehm_gc/include/private
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/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: [02:09:28] waiting for uid20308's lock in /home/mercury/mercury1/repository/mercury/compiler
cvs diff: [02:09:58] waiting for uid20308's lock in /home/mercury/mercury1/repository/mercury/compiler
cvs diff: [02:10:28] obtained lock in /home/mercury/mercury1/repository/mercury/compiler
Index: compiler/code_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_gen.m,v
retrieving revision 1.174
diff -u -b -r1.174 code_gen.m
--- compiler/code_gen.m	23 Nov 2007 07:34:55 -0000	1.174
+++ compiler/code_gen.m	23 Nov 2007 07:45:36 -0000
@@ -71,7 +71,7 @@
     % the generic data structures before and after the actual code generation,
     % which is delegated to goal-specific predicates.
 
-    code_info.get_forward_live_vars(!.CI, ForwardLiveVarsBeforeGoal),
+    get_forward_live_vars(!.CI, ForwardLiveVarsBeforeGoal),
 
     % Make any changes to liveness before Goal.
     ( goal_is_atomic(GoalExpr) ->
@@ -79,8 +79,8 @@
     ;
         IsAtomic = no
     ),
-    code_info.pre_goal_update(GoalInfo, IsAtomic, !CI),
-    code_info.get_instmap(!.CI, InstMap),
+    pre_goal_update(GoalInfo, IsAtomic, !CI),
+    get_instmap(!.CI, InstMap),
     ( instmap.is_reachable(InstMap) ->
         CodeModel = goal_info_get_code_model(GoalInfo),
         % Sanity check: code of some code models should occur
@@ -112,7 +112,7 @@
         generate_goal_2(GoalExpr, GoalInfo, CodeModel,
             ForwardLiveVarsBeforeGoal, GoalCode, !CI),
         Features = goal_info_get_features(GoalInfo),
-        code_info.get_proc_info(!.CI, ProcInfo),
+        get_proc_info(!.CI, ProcInfo),
 
         % If the predicate's evaluation method is memo, loopcheck or minimal
         % model, the goal generated the variable that represents the call table
@@ -125,13 +125,12 @@
         % to have a stack slot.
         (
             set.member(feature_call_table_gen, Features),
-            code_info.get_proc_info(!.CI, ProcInfo),
+            get_proc_info(!.CI, ProcInfo),
             proc_info_get_call_table_tip(ProcInfo, MaybeCallTableVar),
             MaybeCallTableVar = yes(CallTableVar),
-            code_info.get_maybe_trace_info(!.CI, yes(_))
+            get_maybe_trace_info(!.CI, yes(_))
         ->
-            code_info.save_variables_on_stack([CallTableVar], TipSaveCode,
-                !CI),
+            save_variables_on_stack([CallTableVar], TipSaveCode, !CI),
             CodeUptoTip = tree(GoalCode, TipSaveCode)
         ;
             CodeUptoTip = GoalCode
@@ -161,8 +160,8 @@
 
         % Make live any variables which subsequent goals will expect to be
         % live, but were not generated.
-        code_info.set_instmap(InstMap, !CI),
-        code_info.post_goal_update(GoalInfo, !CI)
+        set_instmap(InstMap, !CI),
+        post_goal_update(GoalInfo, !CI)
     ;
         Code = empty
     ).
@@ -289,7 +288,7 @@
 generate_goals([], _, empty, !CI).
 generate_goals([Goal | Goals], CodeModel, Code, !CI) :-
     generate_goal(CodeModel, Goal, Code1, !CI),
-    code_info.get_instmap(!.CI, Instmap),
+    get_instmap(!.CI, Instmap),
     ( instmap.is_unreachable(Instmap) ->
         Code = Code1
     ;
Index: compiler/code_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_info.m,v
retrieving revision 1.353
diff -u -b -r1.353 code_info.m
--- compiler/code_info.m	23 Nov 2007 07:34:56 -0000	1.353
+++ compiler/code_info.m	23 Nov 2007 07:45:36 -0000
@@ -731,6 +731,18 @@
     %
 :- func variable_type(code_info, prog_var) = mer_type.
 
+    % Compute the principal type constructor of the given type, and return the
+    % definition of this type constructor, if it has one (some type
+    % constructors are built in, and some are hidden behind abstraction
+    % barriers).
+    %
+:- pred search_type_defn(code_info::in, mer_type::in, hlds_type_defn::out) is
+    semidet.
+
+    % Compute the principal type constructor of the given type, and return the
+    % definition of this type constructor. Abort if it doesn't have a
+    % definition (e.g. because it is a builtin).
+    %
 :- func lookup_type_defn(code_info, mer_type) = hlds_type_defn.
 
 :- func filter_region_vars(code_info, set(prog_var)) = set(prog_var).
@@ -905,15 +917,22 @@
 variable_type(CI, Var) = Type :-
     map.lookup(get_var_types(CI), Var, Type).
 
-lookup_type_defn(CI, Type) = TypeDefn :-
+search_type_defn(CI, Type, TypeDefn) :-
     get_module_info(CI, ModuleInfo),
     ( type_to_ctor_and_args(Type, TypeCtorPrime, _) ->
         TypeCtor = TypeCtorPrime
     ;
-        unexpected(this_file, "unknown type in lookup_type_defn")
+        unexpected(this_file, "unknown type in search_type_defn")
     ),
     module_info_get_type_table(ModuleInfo, TypeTable),
-    map.lookup(TypeTable, TypeCtor, TypeDefn).
+    map.search(TypeTable, TypeCtor, TypeDefn).
+
+lookup_type_defn(CI, Type) = TypeDefn :-
+    ( search_type_defn(CI, Type, TypeDefnPrime) ->
+        TypeDefn = TypeDefnPrime
+    ;
+        unexpected(this_file, "lookup_type_defn: type ctor has no definition")
+    ).
 
 filter_region_vars(CI, ForwardLiveVarsBeforeGoal) = RegionVars :-
     VarTypes = code_info.get_var_types(CI),
Index: compiler/dense_switch.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dense_switch.m,v
retrieving revision 1.68
diff -u -b -r1.68 dense_switch.m
--- compiler/dense_switch.m	23 Nov 2007 07:34:59 -0000	1.68
+++ compiler/dense_switch.m	23 Nov 2007 07:45:37 -0000
@@ -146,7 +146,7 @@
         RangeCheck = empty
     ),
     % Now generate the jump table and the cases.
-    generate_cases(Cases, StartVal, EndVal, CodeModel, SwitchGoalInfo,
+    generate_dense_cases(Cases, StartVal, EndVal, CodeModel, SwitchGoalInfo,
         EndLabel, MaybeEnd0, MaybeEnd, Labels, CasesCode, !CI),
 
     % XXX We keep track of the code_info at the end of one of the non-fail
@@ -160,12 +160,12 @@
     % Assemble the code fragments.
     Code = tree_list([VarCode, RangeCheck, DoJump, CasesCode]).
 
-:- pred generate_cases(cases_list::in, int::in, int::in, code_model::in,
+:- pred generate_dense_cases(cases_list::in, int::in, int::in, code_model::in,
     hlds_goal_info::in, label::in, branch_end::in, branch_end::out,
     list(label)::out, code_tree::out, code_info::in, code_info::out) is det.
 
-generate_cases(Cases0, NextVal, EndVal, CodeModel, SwitchGoalInfo, EndLabel,
-        !MaybeEnd, Labels, Code, !CI) :-
+generate_dense_cases(Cases0, NextVal, EndVal, CodeModel, SwitchGoalInfo,
+        EndLabel, !MaybeEnd, Labels, Code, !CI) :-
     ( NextVal > EndVal ->
         Labels = [],
         Code = node([
@@ -173,7 +173,7 @@
         ])
     ;
         get_next_label(ThisLabel, !CI),
-        generate_case(Cases0, Cases1, NextVal, CodeModel,
+        generate_dense_case(Cases0, Cases1, NextVal, CodeModel,
             SwitchGoalInfo, !MaybeEnd, ThisCode, Comment, !CI),
         LabelCode = node([
             llds_instr(label(ThisLabel), Comment)
@@ -184,20 +184,20 @@
         ]),
         % Generate the rest of the cases.
         NextVal1 = NextVal + 1,
-        generate_cases(Cases1, NextVal1, EndVal, CodeModel, SwitchGoalInfo,
-            EndLabel, !MaybeEnd, Labels1, OtherCasesCode, !CI),
+        generate_dense_cases(Cases1, NextVal1, EndVal, CodeModel,
+            SwitchGoalInfo, EndLabel, !MaybeEnd, Labels1, OtherCasesCode, !CI),
         Labels = [ThisLabel | Labels1],
         Code = tree_list([LabelCode, ThisCode, JumpCode, OtherCasesCode])
     ).
 
 %---------------------------------------------------------------------------%
 
-:- pred generate_case(cases_list::in, cases_list::out, int::in, code_model::in,
-    hlds_goal_info::in, branch_end::in, branch_end::out, code_tree::out,
-    string::out, code_info::in, code_info::out) is det.
+:- pred generate_dense_case(cases_list::in, cases_list::out, int::in,
+    code_model::in, hlds_goal_info::in, branch_end::in, branch_end::out,
+    code_tree::out, string::out, code_info::in, code_info::out) is det.
 
-generate_case(!Cases, NextVal, CodeModel, SwitchGoalInfo, !MaybeEnd, Code,
-        Comment, !CI) :-
+generate_dense_case(!Cases, NextVal, CodeModel, SwitchGoalInfo, !MaybeEnd,
+        Code, Comment, !CI) :-
     (
         !.Cases = [Case | !:Cases],
         Case = extended_case(_, int_tag(NextVal), _, Goal)
Index: compiler/disj_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/disj_gen.m,v
retrieving revision 1.106
diff -u -b -r1.106 disj_gen.m
--- compiler/disj_gen.m	9 Oct 2007 07:59:46 -0000	1.106
+++ compiler/disj_gen.m	9 Oct 2007 08:04:40 -0000
@@ -347,8 +347,7 @@
     % for semi and det disjunctions, and delay saving the ticket until
     % necessary.
     get_globals(!.CI, Globals),
-    maybe_save_ticket(AddTrailOps, SaveTicketCode, MaybeTicketSlot,
-        !CI),
+    maybe_save_ticket(AddTrailOps, SaveTicketCode, MaybeTicketSlot, !CI),
 
     % If we are using a grade in which we can recover memory by saving
     % and restoring the heap pointer, set up for doing so if necessary.
Index: compiler/lookup_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/lookup_util.m,v
retrieving revision 1.5
diff -u -b -r1.5 lookup_util.m
--- compiler/lookup_util.m	7 Aug 2007 07:09:58 -0000	1.5
+++ compiler/lookup_util.m	9 Oct 2007 13:03:30 -0000
@@ -95,8 +95,8 @@
     ( instmap_delta_is_unreachable(InstMapDelta) ->
         OutVars = []
     ;
-        code_info.get_instmap(CI, CurrentInstMap),
-        code_info.get_module_info(CI, ModuleInfo),
+        get_instmap(CI, CurrentInstMap),
+        get_module_info(CI, ModuleInfo),
         instmap_delta_changed_vars(InstMapDelta, ChangedVars),
         instmap.apply_instmap_delta(CurrentInstMap, InstMapDelta,
             InstMapAfter),
@@ -146,14 +146,14 @@
 
 do_generate_constants_for_arm(Goal, Vars, StoreMap, SetToUnknown, CaseRvals,
         !MaybeEnd, Liveness, !CI) :-
-    code_info.remember_position(!.CI, BranchStart),
+    remember_position(!.CI, BranchStart),
     Goal = hlds_goal(_GoalExpr, GoalInfo),
     CodeModel = goal_info_get_code_model(GoalInfo),
     code_gen.generate_goal(CodeModel, Goal, Code, !CI),
     tree.tree_of_lists_is_empty(Code),
-    code_info.get_forward_live_vars(!.CI, Liveness),
+    get_forward_live_vars(!.CI, Liveness),
 
-    code_info.get_globals(!.CI, Globals),
+    get_globals(!.CI, Globals),
     globals.get_options(Globals, Options),
     exprn_aux.init_exprn_opts(Options, ExprnOpts),
     get_arm_rvals(Vars, CaseRvals, !CI, ExprnOpts),
@@ -161,13 +161,13 @@
         SetToUnknown = no
     ;
         SetToUnknown = yes,
-        code_info.set_resume_point_to_unknown(!CI)
+        set_resume_point_to_unknown(!CI)
     ),
     % EndCode code may contain instructions that place Vars in the locations
     % dictated by StoreMap, and thus does not have to be empty. (The array
     % lookup code will put those variables in those locations directly.)
-    code_info.generate_branch_end(StoreMap, !MaybeEnd, _EndCode, !CI),
-    code_info.reset_to_position(BranchStart, !CI).
+    generate_branch_end(StoreMap, !MaybeEnd, _EndCode, !CI),
+    reset_to_position(BranchStart, !CI).
 
 generate_constants_for_disjuncts([], _Vars, _StoreMap, [], !MaybeEnd,
         no, !CI).
@@ -191,7 +191,7 @@
 
 get_arm_rvals([], [], !CI, _ExprnOpts).
 get_arm_rvals([Var | Vars], [Rval | Rvals], !CI, ExprnOpts) :-
-    code_info.produce_variable(Var, Code, Rval, !CI),
+    produce_variable(Var, Code, Rval, !CI),
     tree.tree_of_lists_is_empty(Code),
     rval_is_constant(Rval, ExprnOpts),
     get_arm_rvals(Vars, Rvals, !CI, ExprnOpts).
@@ -219,14 +219,13 @@
     % We keep track of what variables are supposed to be live at the end
     % of cases. We have to do this explicitly because generating a `fail' slot
     % last would yield the wrong liveness.
-    code_info.set_forward_live_vars(Liveness, !CI),
-    code_info.generate_branch_end(StoreMap, MaybeEnd0, _MaybeEnd,
-        BranchEndCode, !CI).
+    set_forward_live_vars(Liveness, !CI),
+    generate_branch_end(StoreMap, MaybeEnd0, _MaybeEnd, BranchEndCode, !CI).
 
 generate_offset_assigns([], _, _, !CI).
 generate_offset_assigns([Var | Vars], Offset, BaseReg, !CI) :-
     LookupLval = field(yes(0), lval(BaseReg), const(llconst_int(Offset))),
-    code_info.assign_lval_to_var(Var, LookupLval, Code, !CI),
+    assign_lval_to_var(Var, LookupLval, Code, !CI),
     expect(tree.is_empty(Code), this_file,
         "generate_offset_assigns: nonempty code"),
     generate_offset_assigns(Vars, Offset + 1, BaseReg, !CI).
Index: compiler/middle_rec.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/middle_rec.m,v
retrieving revision 1.131
diff -u -b -r1.131 middle_rec.m
--- compiler/middle_rec.m	11 Oct 2007 11:45:19 -0000	1.131
+++ compiler/middle_rec.m	8 Nov 2007 06:22:14 -0000
@@ -107,9 +107,9 @@
 is_recursive_call(Goal, CodeInfo) :-
     Goal = plain_call(CallPredId, CallProcId, _, BuiltinState, _, _),
     BuiltinState = not_builtin,
-    code_info.get_pred_id(CodeInfo, PredId),
+    get_pred_id(CodeInfo, PredId),
     PredId = CallPredId,
-    code_info.get_proc_id(CodeInfo, ProcId),
+    get_proc_id(CodeInfo, ProcId),
     ProcId = CallProcId.
 
     % contains_only_builtins(G) returns `yes' if G is a leaf procedure,
@@ -225,37 +225,35 @@
 
 middle_rec_generate_switch(Var, BaseConsId, Base, Recursive, SwitchGoalInfo,
         Instrs, !CI) :-
-    code_info.get_stack_slots(!.CI, StackSlots),
-    code_info.get_varset(!.CI, VarSet),
+    get_stack_slots(!.CI, StackSlots),
+    get_varset(!.CI, VarSet),
     SlotsComment = explain_stack_slots(StackSlots, VarSet),
-    code_info.get_module_info(!.CI, ModuleInfo),
-    code_info.get_pred_id(!.CI, PredId),
-    code_info.get_proc_id(!.CI, ProcId),
+    get_module_info(!.CI, ModuleInfo),
+    get_pred_id(!.CI, PredId),
+    get_proc_id(!.CI, ProcId),
     EntryLabel = make_local_entry_label(ModuleInfo, PredId, ProcId, no),
 
-    code_info.pre_goal_update(SwitchGoalInfo, no, !CI),
+    pre_goal_update(SwitchGoalInfo, no, !CI),
     unify_gen.generate_tag_test(Var, BaseConsId, branch_on_success,
         BaseLabel, EntryTestCode, !CI),
     tree.flatten(EntryTestCode, EntryTestListList),
     list.condense(EntryTestListList, EntryTestList),
 
     goal_info_get_store_map(SwitchGoalInfo, StoreMap),
-    code_info.remember_position(!.CI, BranchStart),
+    remember_position(!.CI, BranchStart),
     code_gen.generate_goal(model_det, Base, BaseGoalCode, !CI),
-    code_info.generate_branch_end(StoreMap, no, MaybeEnd1,
-        BaseSaveCode, !CI),
-    code_info.reset_to_position(BranchStart, !CI),
+    generate_branch_end(StoreMap, no, MaybeEnd1, BaseSaveCode, !CI),
+    reset_to_position(BranchStart, !CI),
     code_gen.generate_goal(model_det, Recursive, RecGoalCode, !CI),
-    code_info.generate_branch_end(StoreMap, MaybeEnd1, MaybeEnd,
-        RecSaveCode, !CI),
+    generate_branch_end(StoreMap, MaybeEnd1, MaybeEnd, RecSaveCode, !CI),
 
-    code_info.post_goal_update(SwitchGoalInfo, !CI),
-    code_info.after_all_branches(StoreMap, MaybeEnd, !CI),
+    post_goal_update(SwitchGoalInfo, !CI),
+    after_all_branches(StoreMap, MaybeEnd, !CI),
 
-    ArgModes = code_info.get_arginfo(!.CI),
-    HeadVars = code_info.get_headvars(!.CI),
+    ArgModes = get_arginfo(!.CI),
+    HeadVars = get_headvars(!.CI),
     assoc_list.from_corresponding_lists(HeadVars, ArgModes, Args),
-    code_info.setup_return(Args, LiveArgs, EpilogCode, !CI),
+    setup_return(Args, LiveArgs, EpilogCode, !CI),
 
     BaseCode = tree(BaseGoalCode, tree(BaseSaveCode, EpilogCode)),
     RecCode = tree(RecGoalCode, tree(RecSaveCode, EpilogCode)),
@@ -278,9 +276,9 @@
     split_rec_code(RecList, BeforeList0, AfterList),
     add_counter_to_livevals(BeforeList0, AuxReg, BeforeList),
 
-    code_info.get_next_label(Loop1Label, !CI),
-    code_info.get_next_label(Loop2Label, !CI),
-    code_info.get_total_stackslot_count(!.CI, FrameSize),
+    get_next_label(Loop1Label, !CI),
+    get_next_label(Loop2Label, !CI),
+    get_total_stackslot_count(!.CI, FrameSize),
 
     generate_downloop_test(EntryTestList, Loop1Label, Loop1Test),
 
Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.604
diff -u -b -r1.604 options.m
--- compiler/options.m	23 Nov 2007 07:35:18 -0000	1.604
+++ compiler/options.m	26 Nov 2007 02:01:55 -0000
@@ -637,6 +637,8 @@
     ;         tag_switch_size
     ;         try_switch_size
     ;         binary_switch_size
+    ;         switch_single_rec_base_first
+    ;         switch_multi_rec_base_first
     ;       static_ground_terms
     ;       use_atomic_cells
     ;       middle_rec
@@ -1418,6 +1420,8 @@
     tag_switch_size                     -   int(3),
     try_switch_size                     -   int(3),
     binary_switch_size                  -   int(4),
+    switch_single_rec_base_first        -   bool(no),
+    switch_multi_rec_base_first         -   bool(yes),
     static_ground_terms                 -   bool(no),
     use_atomic_cells                    -   bool(no),
     middle_rec                          -   bool(no),
@@ -2239,6 +2243,8 @@
 long_option("tag-switch-size",      tag_switch_size).
 long_option("try-switch-size",      try_switch_size).
 long_option("binary-switch-size",   binary_switch_size).
+long_option("switch-single-rec-base-first", switch_single_rec_base_first).
+long_option("switch-multi-rec-base-first",  switch_multi_rec_base_first).
 long_option("static-ground-terms",  static_ground_terms).
 long_option("use-atomic-cells",     use_atomic_cells).
 long_option("middle-rec",           middle_rec).
@@ -4580,6 +4586,13 @@
         "--binary-switch-size <n>",
         "\tThe number of alternatives in a binary search switch",
         "\tmust be at least this number (default: 4).",
+% These options are only for performance tests.
+%       "--switch-single-rec-base-first",
+%       "\tIn a switch with two arms, one a base case and one with a single",
+%       "\trecursive call, put the base case first.
+%       "--switch-multi-rec-base-first",
+%       "\tIn a switch with two arms, one a base case and one with multiple",
+%       "\trecursive calls, put the base case first.
         "--no-static-ground-terms",
         "\tDisable the optimization of constructing constant ground terms",
         "\tat compile time and storing them as static constants.",
Index: compiler/pragma_c_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/pragma_c_gen.m,v
retrieving revision 1.110
diff -u -b -r1.110 pragma_c_gen.m
--- compiler/pragma_c_gen.m	23 Nov 2007 07:35:20 -0000	1.110
+++ compiler/pragma_c_gen.m	23 Nov 2007 07:51:22 -0000
@@ -407,8 +407,8 @@
 
 generate_trace_runtime_cond_foreign_proc_code(RuntimeExpr, Code, !CI) :-
     generate_runtime_cond_code(RuntimeExpr, CondRval, !CI),
-    code_info.get_next_label(SuccessLabel, !CI),
-    code_info.generate_failure(FailCode, !CI),
+    get_next_label(SuccessLabel, !CI),
+    generate_failure(FailCode, !CI),
     CondCode = node([
         llds_instr(if_val(CondRval, code_label(SuccessLabel)),
             "environment variable tests")
@@ -476,9 +476,9 @@
         ThreadSafe = proc_not_thread_safe
     ),
     % First we need to get a list of input and output arguments.
-    ArgInfos = code_info.get_pred_proc_arginfo(!.CI, PredId, ProcId),
+    ArgInfos = get_pred_proc_arginfo(!.CI, PredId, ProcId),
     make_c_arg_list(Args, ArgInfos, OrigCArgs),
-    code_info.get_module_info(!.CI, ModuleInfo),
+    get_module_info(!.CI, ModuleInfo),
     make_extra_c_arg_list(ExtraArgs, ModuleInfo, ArgInfos, ExtraCArgs),
     list.append(OrigCArgs, ExtraCArgs, CArgs),
     foreign_proc_select_in_args(CArgs, InCArgs),
@@ -495,14 +495,14 @@
     ;
         MayCallMercury = proc_may_call_mercury,
         % The C code might call back Mercury code which clobbers the succip.
-        code_info.succip_is_used(!CI),
+        succip_is_used(!CI),
 
         % The C code might call back Mercury code which clobbers the
         % other registers, so we need to save any live variables
         % (other than the output args) onto the stack.
         get_c_arg_list_vars(OutCArgs, OutVars),
         set.list_to_set(OutVars, OutVarsSet),
-        code_info.save_variables(OutVarsSet, _, SaveVarsCode, !CI)
+        save_variables(OutVarsSet, _, SaveVarsCode, !CI)
     ),
 
     % Generate the values of input variables.
@@ -515,15 +515,15 @@
     % finished generating the code producing the input variables.
     % (The forward dead variables will be dead after the call_foreign_proc,
     % but are live during its input phase.)
-    code_info.make_vars_forward_dead(DeadVars, !CI),
+    make_vars_forward_dead(DeadVars, !CI),
 
     % Generate <declaration of one local variable for each arg>.
     make_foreign_proc_decls(CArgs, ModuleInfo, CanOptAwayUnnamedArgs, Decls),
 
     % Generate #define MR_PROC_LABEL <procedure label> /* see note (5) */
     % and #undef MR_PROC_LABEL.
-    code_info.get_pred_id(!.CI, CallerPredId),
-    code_info.get_proc_id(!.CI, CallerProcId),
+    get_pred_id(!.CI, CallerPredId),
+    get_proc_id(!.CI, CallerProcId),
     make_proc_label_hash_define(ModuleInfo, CallerPredId, CallerProcId,
         ProcLabelHashDefine, ProcLabelHashUndef),
 
@@ -577,7 +577,7 @@
             CheckSuccess_Comp = foreign_proc_noop,
             MaybeFailLabel = no
         ;
-            code_info.get_next_label(FailLabel, !CI),
+            get_next_label(FailLabel, !CI),
             CheckSuccess_Comp = foreign_proc_fail_to(FailLabel),
             MaybeFailLabel = yes(FailLabel)
         ),
@@ -627,7 +627,7 @@
         ;
             OkToDelete = yes
         ),
-        code_info.clear_all_registers(OkToDelete, !CI)
+        clear_all_registers(OkToDelete, !CI)
     ),
 
     % <assignment of the output values from local variables to registers>
@@ -680,8 +680,8 @@
 
     (
         MaybeFailLabel = yes(TheFailLabel),
-        code_info.get_next_label(SkipLabel, !CI),
-        code_info.generate_failure(FailCode, !CI),
+        get_next_label(SkipLabel, !CI),
+        generate_failure(FailCode, !CI),
         GotoSkipLabelCode = node([
             llds_instr(goto(code_label(SkipLabel)), "Skip past failure code")
         ]),
@@ -692,7 +692,7 @@
     ;
         MaybeFailLabel = no,
         ( Detism = detism_failure ->
-            code_info.generate_failure(FailureCode, !CI)
+            generate_failure(FailureCode, !CI)
         ;
             FailureCode = empty
         )
@@ -750,9 +750,9 @@
 
     % Generate #define MR_PROC_LABEL <procedure label> /* see note (5) */
     % and #undef MR_PROC_LABEL.
-    code_info.get_module_info(!.CI, ModuleInfo),
-    code_info.get_pred_id(!.CI, CallerPredId),
-    code_info.get_proc_id(!.CI, CallerProcId),
+    get_module_info(!.CI, ModuleInfo),
+    get_pred_id(!.CI, CallerPredId),
+    get_proc_id(!.CI, CallerProcId),
     make_proc_label_hash_define(ModuleInfo, CallerPredId, CallerProcId,
         ProcLabelDefine, ProcLabelUndef),
 
@@ -761,7 +761,7 @@
         PredId, ProcId),
 
     % Get a list of input and output arguments.
-    ArgInfos = code_info.get_pred_proc_arginfo(!.CI, PredId, ProcId),
+    ArgInfos = get_pred_proc_arginfo(!.CI, PredId, ProcId),
     make_c_arg_list(Args, ArgInfos, CArgs),
     foreign_proc_select_in_args(CArgs, InCArgs),
     foreign_proc_select_out_args(CArgs, OutCArgs),
@@ -786,7 +786,7 @@
         [s(StructName), s(StructName)],
         InitSaveStruct),
 
-    code_info.get_next_label(RetryLabel, !CI),
+    get_next_label(RetryLabel, !CI),
     ModFrameCode = node([
         llds_instr(assign(redoip_slot(lval(curfr)),
             const(llconst_code_addr(code_label(RetryLabel)))),
@@ -796,18 +796,16 @@
         llds_instr(label(RetryLabel), "Start of the retry block")
     ]),
 
-    code_info.get_globals(!.CI, Globals),
+    get_globals(!.CI, Globals),
 
     globals.lookup_bool_option(Globals, reclaim_heap_on_nondet_failure,
         ReclaimHeap),
-    code_info.maybe_save_hp(ReclaimHeap, SaveHeapCode, MaybeHpSlot, !CI),
-    code_info.maybe_restore_hp(MaybeHpSlot, RestoreHeapCode),
+    maybe_save_hp(ReclaimHeap, SaveHeapCode, MaybeHpSlot, !CI),
+    maybe_restore_hp(MaybeHpSlot, RestoreHeapCode),
 
-    code_info.get_emit_trail_ops(!.CI, AddTrailOps),
-    code_info.maybe_save_ticket(AddTrailOps, SaveTicketCode, MaybeTicketSlot,
-        !CI),
-    code_info.maybe_reset_ticket(MaybeTicketSlot, reset_reason_undo,
-        RestoreTicketCode),
+    get_emit_trail_ops(!.CI, AddTrailOps),
+    maybe_save_ticket(AddTrailOps, SaveTicketCode, MaybeTicketSlot, !CI),
+    maybe_reset_ticket(MaybeTicketSlot, reset_reason_undo, RestoreTicketCode),
     (
         FirstContext = yes(ActualFirstContext)
     ;
@@ -1006,7 +1004,7 @@
         Code = tree_list([ModFrameCode, FirstDisjunctCode, CallBlockCode,
             RetryLabelCode, LaterDisjunctCode, RetryBlockCode])
     ;
-        code_info.get_next_label(SharedLabel, !CI),
+        get_next_label(SharedLabel, !CI),
         SharedLabelCode = node([
             llds_instr(label(SharedLabel), "Start of the shared block")
         ]),
@@ -1416,9 +1414,9 @@
     (
         MaybeName = yes(Name),
         VarType = variable_type(!.CI, Var),
-        code_info.produce_variable(Var, FirstCode, Rval, !CI),
+        produce_variable(Var, FirstCode, Rval, !CI),
         MaybeForeign = get_maybe_foreign_type_info(!.CI, OrigType),
-        code_info.get_module_info(!.CI, ModuleInfo),
+        get_module_info(!.CI, ModuleInfo),
         ( is_dummy_argument_type(ModuleInfo, VarType) ->
             IsDummy = yes
         ;
@@ -1441,7 +1439,7 @@
     maybe(foreign_proc_type).
 
 get_maybe_foreign_type_info(CI, Type) = MaybeForeignTypeInfo :-
-    code_info.get_module_info(CI, Module),
+    get_module_info(CI, Module),
     module_info_get_type_table(Module, Types),
     (
         type_to_ctor_and_args(Type, TypeId, _SubTypes),
@@ -1475,7 +1473,7 @@
 foreign_proc_acquire_regs([], [], !CI).
 foreign_proc_acquire_regs([Arg | Args], [Reg | Regs], !CI) :-
     Arg = c_arg(Var, _, _, _, _),
-    code_info.acquire_reg_for_var(Var, Reg, !CI),
+    acquire_reg_for_var(Var, Reg, !CI),
     foreign_proc_acquire_regs(Args, Regs, !CI).
 
 %---------------------------------------------------------------------------%
@@ -1494,15 +1492,15 @@
     place_foreign_proc_output_args_in_regs(Args, Regs, CanOptAwayUnnamedArgs,
         OutputsTail, !CI),
     Arg = c_arg(Var, MaybeArgName, OrigType, BoxPolicy, _ArgInfo),
-    code_info.release_reg(Reg, !CI),
-    ( code_info.variable_is_forward_live(!.CI, Var) ->
-        code_info.set_var_location(Var, Reg, !CI),
+    release_reg(Reg, !CI),
+    ( variable_is_forward_live(!.CI, Var) ->
+        set_var_location(Var, Reg, !CI),
         MaybeForeign = get_maybe_foreign_type_info(!.CI, OrigType),
         MaybeName = var_should_be_passed(CanOptAwayUnnamedArgs, Var,
             MaybeArgName),
         (
             MaybeName = yes(Name),
-            code_info.get_module_info(!.CI, ModuleInfo),
+            get_module_info(!.CI, ModuleInfo),
             VarType = variable_type(!.CI, Var),
             ( is_dummy_argument_type(ModuleInfo, VarType) ->
                 IsDummy = yes
@@ -1545,7 +1543,7 @@
         ArgInfo = arg_info(N, _),
         Reg = reg(reg_r, N),
         MaybeForeign = get_maybe_foreign_type_info(CI, OrigType),
-        code_info.get_module_info(CI, ModuleInfo),
+        get_module_info(CI, ModuleInfo),
         ( is_dummy_argument_type(ModuleInfo, VarType) ->
             IsDummy = yes
         ;
@@ -1579,7 +1577,7 @@
         ArgInfo = arg_info(N, _),
         Reg = reg(reg_r, N),
         MaybeForeign = get_maybe_foreign_type_info(CI, OrigType),
-        code_info.get_module_info(CI, ModuleInfo),
+        get_module_info(CI, ModuleInfo),
         ( is_dummy_argument_type(ModuleInfo, VarType) ->
             IsDummy = yes
         ;
Index: compiler/proc_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/proc_gen.m,v
retrieving revision 1.24
diff -u -b -r1.24 proc_gen.m
--- compiler/proc_gen.m	11 Oct 2007 11:45:20 -0000	1.24
+++ compiler/proc_gen.m	8 Nov 2007 06:22:14 -0000
@@ -348,14 +348,14 @@
     generate_category_code(CodeModel, ProcContext, Goal, OutsideResumePoint,
         TraceSlotInfo, CodeTree, MaybeTraceCallLabel, FrameInfo,
         CodeInfo0, CodeInfo),
-    code_info.get_max_reg_in_use_at_trace(CodeInfo, MaxTraceReg),
-    code_info.get_static_cell_info(CodeInfo, StaticCellInfo),
+    get_max_reg_in_use_at_trace(CodeInfo, MaxTraceReg),
+    get_static_cell_info(CodeInfo, StaticCellInfo),
     global_data_set_static_cell_info(StaticCellInfo, !GlobalData),
 
     globals.get_trace_level(Globals, TraceLevel),
-    code_info.get_created_temp_frame(CodeInfo, CreatedTempFrame),
+    get_created_temp_frame(CodeInfo, CreatedTempFrame),
 
-    code_info.get_proc_trace_events(CodeInfo, ProcTraceEvents),
+    get_proc_trace_events(CodeInfo, ProcTraceEvents),
     % You can have user trace events even if the effective trace level is none.
     (
         ProcTraceEvents =  yes,
@@ -399,7 +399,7 @@
     ->
         % Create the procedure layout structure.
         RttiProcLabel = make_rtti_proc_label(ModuleInfo, PredId, ProcId),
-        code_info.get_layout_info(CodeInfo, InternalMap),
+        get_layout_info(CodeInfo, InternalMap),
         EntryLabel = make_local_entry_label(ModuleInfo, PredId, ProcId, no),
         proc_info_get_eval_method(ProcInfo, EvalMethod),
         proc_info_get_initial_instmap(ProcInfo, ModuleInfo, InstMap0),
@@ -463,14 +463,14 @@
         true
     ),
 
-    code_info.get_closure_layouts(CodeInfo, ClosureLayouts),
+    get_closure_layouts(CodeInfo, ClosureLayouts),
     global_data_add_new_closure_layouts(ClosureLayouts, !GlobalData),
     ProcLabel = make_proc_label(ModuleInfo, PredId, ProcId),
 
     Name = pred_info_name(PredInfo),
     Arity = pred_info_orig_arity(PredInfo),
 
-    code_info.get_label_counter(CodeInfo, LabelCounter),
+    get_label_counter(CodeInfo, LabelCounter),
     % You can have user trace events even if the effective trace level is none.
     (
         ProcTraceEvents = no,
@@ -501,7 +501,7 @@
         ProcInstructions = Instructions,
         ProcLabelCounter = LabelCounter
     ),
-    code_info.get_used_env_vars(CodeInfo, UsedEnvVars),
+    get_used_env_vars(CodeInfo, UsedEnvVars),
     Proc = c_procedure(Name, Arity, proc(PredId, ProcId), CodeModel,
         ProcInstructions, ProcLabel, ProcLabelCounter, MayAlterRtti,
         UsedEnvVars).
@@ -624,16 +624,17 @@
 generate_category_code(model_det, ProcContext, Goal, ResumePoint,
         TraceSlotInfo, Code, MaybeTraceCallLabel, FrameInfo, !CI) :-
     % Generate the code for the body of the procedure.
+    get_globals(!.CI, Globals),
+    globals.lookup_bool_option(Globals, middle_rec, MiddleRec),
     (
-        code_info.get_globals(!.CI, Globals),
-        globals.lookup_bool_option(Globals, middle_rec, yes),
+        MiddleRec = yes,
         middle_rec.match_and_generate(Goal, MiddleRecCode, !CI)
     ->
         Code = MiddleRecCode,
         MaybeTraceCallLabel = no,
         FrameInfo = frame(0, no, no)
     ;
-        code_info.get_maybe_trace_info(!.CI, MaybeTraceInfo),
+        get_maybe_trace_info(!.CI, MaybeTraceInfo),
         (
             MaybeTraceInfo = yes(TraceInfo),
             generate_call_event(TraceInfo, ProcContext, MaybeTraceCallLabel,
@@ -659,7 +660,7 @@
         llds_instr(livevals(FailureLiveRegs), ""),
         llds_instr(goto(code_succip), "Return from procedure call")
     ]),
-    code_info.get_maybe_trace_info(!.CI, MaybeTraceInfo),
+    get_maybe_trace_info(!.CI, MaybeTraceInfo),
     (
         MaybeTraceInfo = yes(TraceInfo),
         generate_call_event(TraceInfo, ProcContext, MaybeTraceCallLabel,
@@ -670,10 +671,10 @@
         generate_exit(model_semi, FrameInfo, TraceSlotInfo,
             ProcContext, RestoreDeallocCode, ExitCode, !CI),
 
-        code_info.generate_resume_point(ResumePoint, ResumeCode, !CI),
-        code_info.resume_point_vars(ResumePoint, ResumeVarList),
+        generate_resume_point(ResumePoint, ResumeCode, !CI),
+        resume_point_vars(ResumePoint, ResumeVarList),
         set.list_to_set(ResumeVarList, ResumeVars),
-        code_info.set_forward_live_vars(ResumeVars, !CI),
+        set_forward_live_vars(ResumeVars, !CI),
         % XXX A context that gives the end of the procedure definition
         % would be better than ProcContext.
         generate_external_event_code(external_port_fail, TraceInfo,
@@ -695,14 +696,14 @@
             FrameInfo, EntryCode),
         generate_exit(model_semi, FrameInfo, TraceSlotInfo,
             ProcContext, RestoreDeallocCode, ExitCode, !CI),
-        code_info.generate_resume_point(ResumePoint, ResumeCode, !CI),
+        generate_resume_point(ResumePoint, ResumeCode, !CI),
         Code = tree_list([EntryCode, BodyCode, ExitCode,
             ResumeCode, RestoreDeallocCode, FailCode])
     ).
 
 generate_category_code(model_non, ProcContext, Goal, ResumePoint,
         TraceSlotInfo, Code, MaybeTraceCallLabel, FrameInfo, !CI) :-
-    code_info.get_maybe_trace_info(!.CI, MaybeTraceInfo),
+    get_maybe_trace_info(!.CI, MaybeTraceInfo),
     (
         MaybeTraceInfo = yes(TraceInfo),
         generate_call_event(TraceInfo, ProcContext, MaybeTraceCallLabel,
@@ -713,10 +714,10 @@
         generate_exit(model_non, FrameInfo, TraceSlotInfo,
             ProcContext, _, ExitCode, !CI),
 
-        code_info.generate_resume_point(ResumePoint, ResumeCode, !CI),
-        code_info.resume_point_vars(ResumePoint, ResumeVarList),
+        generate_resume_point(ResumePoint, ResumeCode, !CI),
+        resume_point_vars(ResumePoint, ResumeVarList),
         set.list_to_set(ResumeVarList, ResumeVars),
-        code_info.set_forward_live_vars(ResumeVars, !CI),
+        set_forward_live_vars(ResumeVars, !CI),
         % XXX A context that gives the end of the procedure definition
         % would be better than ProcContext.
         generate_external_event_code(external_port_fail, TraceInfo,
@@ -736,7 +737,7 @@
                 % allocated, i.e. only if MR_trace_from_full was true on entry.
                 FromFullSlotLval =
                     llds.stack_slot_num_to_lval(nondet_stack, FromFullSlot),
-                code_info.get_next_label(SkipLabel, !CI),
+                get_next_label(SkipLabel, !CI),
                 DiscardTraceTicketCode = node([
                     llds_instr(
                         if_val(unop(logical_not, lval(FromFullSlotLval)),
@@ -815,22 +816,22 @@
 
 generate_entry(CI, CodeModel, Goal, OutsideResumePoint, FrameInfo,
         EntryCode) :-
-    code_info.get_stack_slots(CI, StackSlots),
-    code_info.get_varset(CI, VarSet),
+    get_stack_slots(CI, StackSlots),
+    get_varset(CI, VarSet),
     SlotsComment = explain_stack_slots(StackSlots, VarSet),
     StartComment = node([
         llds_instr(comment("Start of procedure prologue"), ""),
         llds_instr(comment(SlotsComment), "")
     ]),
-    code_info.get_total_stackslot_count(CI, MainSlots),
-    code_info.get_pred_id(CI, PredId),
-    code_info.get_proc_id(CI, ProcId),
-    code_info.get_module_info(CI, ModuleInfo),
+    get_total_stackslot_count(CI, MainSlots),
+    get_pred_id(CI, PredId),
+    get_proc_id(CI, ProcId),
+    get_module_info(CI, ModuleInfo),
     EntryLabel = make_local_entry_label(ModuleInfo, PredId, ProcId, no),
     LabelCode = node([
         llds_instr(label(EntryLabel), "Procedure entry point")
     ]),
-    code_info.get_succip_used(CI, Used),
+    get_succip_used(CI, Used),
     (
         % Do we need to save the succip across calls?
         Used = yes,
@@ -849,7 +850,7 @@
         TotalSlots = MainSlots,
         MaybeSuccipSlot = no
     ),
-    code_info.get_maybe_trace_info(CI, MaybeTraceInfo),
+    get_maybe_trace_info(CI, MaybeTraceInfo),
     (
         MaybeTraceInfo = yes(TraceInfo),
         generate_slot_fill_code(CI, TraceInfo, TraceFillCode)
@@ -865,8 +866,7 @@
     PushMsg = push_msg(ModuleInfo, PredId, ProcId),
     (
         CodeModel = model_non,
-        code_info.resume_point_stack_addr(OutsideResumePoint,
-            OutsideResumeAddress),
+        resume_point_stack_addr(OutsideResumePoint, OutsideResumeAddress),
         (
             Goal = hlds_goal(call_foreign_proc(_, _, _, _, _, _, PragmaCode),
                 _),
@@ -986,15 +986,15 @@
         ExitCode = tree_list([StartComment, UndefCode, EndComment])
     ;
         NondetPragma = no,
-        code_info.get_instmap(!.CI, InstMap),
-        ArgModes = code_info.get_arginfo(!.CI),
-        HeadVars = code_info.get_headvars(!.CI),
+        get_instmap(!.CI, InstMap),
+        ArgModes = get_arginfo(!.CI),
+        HeadVars = get_headvars(!.CI),
         assoc_list.from_corresponding_lists(HeadVars, ArgModes, Args),
         ( instmap.is_unreachable(InstMap) ->
             OutLvals = set.init,
             FlushCode = empty
         ;
-            code_info.setup_return(Args, OutLvals, FlushCode, !CI)
+            setup_return(Args, OutLvals, FlushCode, !CI)
         ),
         (
             MaybeSuccipSlot = yes(SuccipSlot),
@@ -1035,8 +1035,8 @@
                 StackId = code_model_to_main_stack(CodeModel),
                 FromFullSlotLval =
                     llds.stack_slot_num_to_lval(StackId, FromFullSlot),
-                code_info.get_next_label(SkipLabel, !CI),
-                code_info.get_next_label(SkipLabelCopy, !CI),
+                get_next_label(SkipLabel, !CI),
+                get_next_label(SkipLabelCopy, !CI),
                 PruneTraceTicketCode = node([
                     llds_instr(if_val(unop(logical_not, lval(FromFullSlotLval)),
                         code_label(SkipLabel)), ""),
@@ -1066,7 +1066,7 @@
         RestoreDeallocCodeCopy = tree_list([RestoreSuccipCode,
             PruneTraceTicketCodeCopy, DeallocCode]),
 
-        code_info.get_maybe_trace_info(!.CI, MaybeTraceInfo),
+        get_maybe_trace_info(!.CI, MaybeTraceInfo),
         (
             MaybeTraceInfo = yes(TraceInfo),
             % XXX A context that gives the end of the procedure definition
@@ -1100,7 +1100,7 @@
             LiveLvals = OutLvals
         ),
 
-        code_info.get_proc_info(!.CI, ProcInfo),
+        get_proc_info(!.CI, ProcInfo),
         proc_info_get_maybe_special_return(ProcInfo, MaybeSpecialReturn),
         (
             CodeModel = model_det,
Index: compiler/switch_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/switch_gen.m,v
retrieving revision 1.105
diff -u -b -r1.105 switch_gen.m
--- compiler/switch_gen.m	27 Sep 2007 10:42:06 -0000	1.105
+++ compiler/switch_gen.m	26 Nov 2007 02:07:45 -0000
@@ -116,11 +116,8 @@
             CaseVarTypeBody ^ du_type_reserved_addr = uses_reserved_address
         )
     ->
-        % XXX If the type uses reserved addresses, we should try to generate
-        % code that uses the other indexing mechanisms *after* testing for the
-        % reserved addresses.
-        generate_all_cases(TaggedCases, CaseVar, CodeModel, CanFail, GoalInfo,
-            EndLabel, no, MaybeEnd, Code, !CI)
+        order_and_generate_cases(TaggedCases, CaseVar, CodeModel, CanFail,
+            GoalInfo, EndLabel, no, MaybeEnd, Code, !CI)
     ;
         (
             SwitchCategory = atomic_switch,
@@ -153,8 +150,8 @@
                     CodeModel, CanFail1, GoalInfo, EndLabel, no, MaybeEnd,
                     Code, !CI)
             ;
-                generate_all_cases(TaggedCases, CaseVar, CodeModel, CanFail,
-                    GoalInfo, EndLabel, no, MaybeEnd, Code, !CI)
+                order_and_generate_cases(TaggedCases, CaseVar, CodeModel,
+                    CanFail, GoalInfo, EndLabel, no, MaybeEnd, Code, !CI)
             )
         ;
             SwitchCategory = string_switch,
@@ -164,8 +161,8 @@
                 generate_string_switch(TaggedCases, CaseVar, CodeModel,
                     CanFail, GoalInfo, EndLabel, no, MaybeEnd, Code, !CI)
             ;
-                generate_all_cases(TaggedCases, CaseVar, CodeModel, CanFail,
-                    GoalInfo, EndLabel, no, MaybeEnd, Code, !CI)
+                order_and_generate_cases(TaggedCases, CaseVar, CodeModel,
+                    CanFail, GoalInfo, EndLabel, no, MaybeEnd, Code, !CI)
             )
         ;
             SwitchCategory = tag_switch,
@@ -175,13 +172,13 @@
                 generate_tag_switch(TaggedCases, CaseVar, CodeModel, CanFail,
                     GoalInfo, EndLabel, no, MaybeEnd, Code, !CI)
             ;
-                generate_all_cases(TaggedCases, CaseVar, CodeModel, CanFail,
-                    GoalInfo, EndLabel, no, MaybeEnd, Code, !CI)
+                order_and_generate_cases(TaggedCases, CaseVar, CodeModel,
+                    CanFail, GoalInfo, EndLabel, no, MaybeEnd, Code, !CI)
             )
         ;
             SwitchCategory = other_switch,
-            generate_all_cases(TaggedCases, CaseVar, CodeModel, CanFail,
-                GoalInfo, EndLabel, no, MaybeEnd, Code, !CI)
+            order_and_generate_cases(TaggedCases, CaseVar, CodeModel,
+                CanFail, GoalInfo, EndLabel, no, MaybeEnd, Code, !CI)
         )
     ),
     after_all_branches(StoreMap, MaybeEnd, !CI).
@@ -240,14 +237,146 @@
     % and put that one first. This minimizes the number of pipeline
     % breaks caused by taken branches.
     %
-:- pred generate_all_cases(list(extended_case)::in, prog_var::in,
+:- pred order_and_generate_cases(list(extended_case)::in, prog_var::in,
     code_model::in, can_fail::in, hlds_goal_info::in, label::in,
     branch_end::in, branch_end::out, code_tree::out,
     code_info::in, code_info::out) is det.
 
-generate_all_cases(Cases0, Var, CodeModel, CanFail, GoalInfo, EndLabel,
+order_and_generate_cases(Cases0, Var, CodeModel, CanFail, GoalInfo, EndLabel,
         !MaybeEnd, Code, !CI) :-
-    produce_variable(Var, VarCode, _Rval, !CI),
+    % XXX We should use _VarRval below; we shouldn't produce the variable
+    % again.
+    produce_variable(Var, VarCode, _VarRval, !CI),
+    VarType = variable_type(!.CI, Var),
+    order_cases(Cases0, Cases, VarType, CodeModel, CanFail, !.CI),
+    generate_if_then_else_chain_cases(Cases, Var, CodeModel, CanFail, GoalInfo,
+        EndLabel, !MaybeEnd, CasesCode, !CI),
+    Code = tree(VarCode, CasesCode).
+
+:- pred order_cases(list(extended_case)::in, list(extended_case)::out,
+    mer_type::in, code_model::in, can_fail::in, code_info::in) is det.
+
+order_cases(Cases0, Cases, VarType, CodeModel, CanFail, CI) :-
+    % We do ordering here based on three out of four considerations.
+    %
+    % - We try to put tests against reserved addresses first, so later cases
+    %   can assume those tests have already been done.
+    % - We try to put cases that can succeed before ones that cannot, since
+    %   cases that cannot succeed clearly won't be executed frequently.
+    % - If the recursion structure of the predicate is sufficiently simple that
+    %   we can make a good guess at which case will be executed more
+    %   frequently, we try to put the frequent case first.
+    % - We try to put cheap-to-execute tests first.
+    %
+    % order_cases acts on the first consideration. order_cannot_succeed_cases
+    % acts on the second and indirectly (by calling order_recursive_cases) the
+    % third.
+    %
+    % The fourth consideration has already been acted upon when the switch
+    % priorities were put into each extended case, and the list of cases sorted
+    % on that priority. That is why we take care not to upset the existing
+    % order except when one of the first three considerations dictate a need
+    % to do so.
+
+    (
+        search_type_defn(CI, VarType, VarTypeDefn),
+        get_type_defn_body(VarTypeDefn, VarTypeDefnBody),
+        VarTypeDefnBody ^ du_type_reserved_addr = uses_reserved_address
+    ->
+        separate_reserved_address_cases(Cases0,
+            ReservedAddrCases0, NonReservedAddrCases0),
+        order_cannot_succeed_cases(ReservedAddrCases0, ReservedAddrCases,
+            CodeModel, CanFail, CI),
+        order_cannot_succeed_cases(NonReservedAddrCases0, NonReservedAddrCases,
+            CodeModel, CanFail, CI),
+        Cases = ReservedAddrCases ++ NonReservedAddrCases
+    ;
+        % The type is either not a discriminated union type (e.g. in int or
+        % string), or it is a discriminated union type that does not use
+        % reserved addresses.
+        order_cannot_succeed_cases(Cases0, Cases, CodeModel, CanFail, CI)
+    ).
+
+:- pred separate_reserved_address_cases(list(extended_case)::in,
+    list(extended_case)::out, list(extended_case)::out) is det.
+
+separate_reserved_address_cases([], [], []).
+separate_reserved_address_cases([Case | Cases],
+        ReservedAddrCases, NonReservedAddrCases) :-
+    separate_reserved_address_cases(Cases,
+        ReservedAddrCases1, NonReservedAddrCases1),
+    Case = extended_case(_, ConsTag, _, _),
+    (
+        ConsTag = reserved_address_tag(_),
+        ReservedAddrCases = [Case | ReservedAddrCases1],
+        NonReservedAddrCases = NonReservedAddrCases1
+    ;
+        ( ConsTag = no_tag
+        ; ConsTag = base_typeclass_info_tag(_, _, _)
+        ; ConsTag = deep_profiling_proc_layout_tag(_, _)
+        ; ConsTag = float_tag(_)
+        ; ConsTag = foreign_tag(_, _)
+        ; ConsTag = int_tag(_)
+        ; ConsTag = pred_closure_tag(_, _, _)
+        ; ConsTag = shared_local_tag(_, _)
+        ; ConsTag = shared_remote_tag(_, _)
+        ; ConsTag = shared_with_reserved_addresses_tag(_, _)
+        ; ConsTag = single_functor_tag
+        ; ConsTag = string_tag(_)
+        ; ConsTag = table_io_decl_tag(_, _)
+        ; ConsTag = tabling_info_tag(_, _)
+        ; ConsTag = type_ctor_info_tag(_, _, _)
+        ; ConsTag = unshared_tag(_)
+        ),
+        ReservedAddrCases = ReservedAddrCases1,
+        NonReservedAddrCases = [Case | NonReservedAddrCases1]
+    ).
+
+:- pred order_cannot_succeed_cases(
+    list(extended_case)::in, list(extended_case)::out,
+    code_model::in, can_fail::in, code_info::in) is det.
+
+order_cannot_succeed_cases(Cases0, Cases, CodeModel, CanFail, CI) :-
+    separate_cannot_succeed_cases(Cases0, CanSucceedCases, CannotSucceedCases),
+    (
+        CannotSucceedCases = [],
+        order_recursive_cases(Cases0, Cases, CodeModel, CanFail, CI)
+    ;
+        CannotSucceedCases = [_ | _],
+        % There is no point in calling order_recursive_cases in this situation.
+        Cases = CanSucceedCases ++ CannotSucceedCases
+    ).
+
+:- pred separate_cannot_succeed_cases(list(extended_case)::in,
+    list(extended_case)::out, list(extended_case)::out) is det.
+
+separate_cannot_succeed_cases([], [], []).
+separate_cannot_succeed_cases([Case | Cases],
+        CanSucceedCases, CannotSucceedCases) :-
+    separate_cannot_succeed_cases(Cases,
+        CanSucceedCases1, CannotSucceedCases1),
+    Case = extended_case(_, _, _, Goal),
+    Goal = hlds_goal(_, GoalInfo),
+    Detism = goal_info_get_determinism(GoalInfo),
+    determinism_components(Detism, _CanFail, SolnCount),
+    (
+        ( SolnCount = at_most_one
+        ; SolnCount = at_most_many_cc
+        ; SolnCount = at_most_many
+        ),
+        CanSucceedCases = [Case | CanSucceedCases1],
+        CannotSucceedCases = CannotSucceedCases1
+    ;
+        SolnCount = at_most_zero,
+        CanSucceedCases = CanSucceedCases1,
+        CannotSucceedCases = [Case | CannotSucceedCases1]
+    ).
+
+:- pred order_recursive_cases(
+    list(extended_case)::in, list(extended_case)::out,
+    code_model::in, can_fail::in, code_info::in) is det.
+
+order_recursive_cases(Cases0, Cases, CodeModel, CanFail, CI) :-
     (
         CodeModel = model_det,
         CanFail = cannot_fail,
@@ -255,61 +384,92 @@
         Case1 = extended_case(_, _, _, Goal1),
         Case2 = extended_case(_, _, _, Goal2)
     ->
-        get_pred_id(!.CI, PredId),
-        get_proc_id(!.CI, ProcId),
+        get_module_info(CI, ModuleInfo),
+        module_info_get_globals(ModuleInfo, Globals),
+        get_pred_id(CI, PredId),
+        get_proc_id(CI, ProcId),
         count_recursive_calls(Goal1, PredId, ProcId, Min1, Max1),
         count_recursive_calls(Goal2, PredId, ProcId, Min2, Max2),
         (
+            (
             Max1 = 0,   % Goal1 is a base case
             Min2 = 1    % Goal2 is probably singly recursive
         ->
-            Cases = [Case2, Case1]
+                BaseCase = Case1,
+                SingleRecCase = Case2
+            ;
+                Max2 = 0,   % Goal2 is a base case
+                Min1 = 1    % Goal1 is probably singly recursive
+            ->
+                BaseCase = Case2,
+                SingleRecCase = Case1
+            ;
+                fail
+            )
+        ->
+            globals.lookup_bool_option(Globals, switch_single_rec_base_first,
+                SingleRecBaseFirst),
+            (
+                SingleRecBaseFirst = yes,
+                Cases = [SingleRecCase, BaseCase]
+            ;
+                SingleRecBaseFirst = no,
+                Cases = [BaseCase, SingleRecCase]
+            )
+        ;
+            (
+                Max1 = 0,   % Goal1 is a base case
+                Min2 > 1    % Goal2 is at least doubly recursive
+            ->
+                BaseCase = Case1,
+                MultiRecCase = Case2
         ;
             Max2 = 0,   % Goal2 is a base case
             Min1 > 1    % Goal1 is at least doubly recursive
         ->
-            Cases = [Case2, Case1]
+                BaseCase = Case2,
+                MultiRecCase = Case1
+            ;
+                fail
+            )
+        ->
+            globals.lookup_bool_option(Globals, switch_multi_rec_base_first,
+                MultiRecBaseFirst),
+            (
+                MultiRecBaseFirst = yes,
+                Cases = [BaseCase, MultiRecCase]
+            ;
+                MultiRecBaseFirst = no,
+                Cases = [MultiRecCase, BaseCase]
+            )
         ;
             Cases = Cases0
         )
     ;
         Cases = Cases0
-    ),
-    generate_cases(Cases, Var, CodeModel, CanFail, GoalInfo, EndLabel,
-        !MaybeEnd, CasesCode, !CI),
-    Code = tree(VarCode, CasesCode).
+    ).
 
-:- pred generate_cases(list(extended_case)::in, prog_var::in,
-    code_model::in, can_fail::in, hlds_goal_info::in, label::in,
+%-----------------------------------------------------------------------------%
+
+:- pred generate_if_then_else_chain_cases(list(extended_case)::in,
+    prog_var::in, code_model::in, can_fail::in, hlds_goal_info::in, label::in,
     branch_end::in, branch_end::out, code_tree::out,
     code_info::in, code_info::out) is det.
 
-generate_cases([], _Var, _CodeModel, CanFail, _GoalInfo, EndLabel, !MaybeEnd,
-        Code, !CI) :-
+generate_if_then_else_chain_cases(Cases, Var, CodeModel, CanFail,
+        SwitchGoalInfo, EndLabel, !MaybeEnd, Code, !CI) :-
     (
-        CanFail = can_fail,
-        % At the end of a locally semidet switch, we fail because we came
-        % across a tag which was not covered by one of the cases. It is
-        % followed by the end of switch label to which the cases branch.
-        generate_failure(FailCode, !CI)
-    ;
-        CanFail = cannot_fail,
-        FailCode = empty
-    ),
-    EndCode = node([llds_instr(label(EndLabel), "end of switch")]),
-    Code = tree(FailCode, EndCode).
-
-generate_cases([extended_case(_, _, Cons, Goal) | Cases], Var, CodeModel,
-        CanFail, SwitchGoalInfo, EndLabel, !MaybeEnd, CasesCode, !CI) :-
+        Cases = [HeadCase | TailCases],
+        HeadCase = extended_case(_, _, Cons, Goal),
     remember_position(!.CI, BranchStart),
     goal_info_get_store_map(SwitchGoalInfo, StoreMap),
     (
-        ( Cases = [_|_]
+            ( TailCases = [_ | _]
         ; CanFail = can_fail
         )
     ->
-        unify_gen.generate_tag_test(Var, Cons, branch_on_failure, NextLabel,
-            TestCode, !CI),
+            unify_gen.generate_tag_test(Var, Cons, branch_on_failure,
+                NextLabel, TestCode, !CI),
         maybe_generate_internal_event_code(Goal, SwitchGoalInfo, TraceCode,
             !CI),
         code_gen.generate_goal(CodeModel, Goal, GoalCode, !CI),
@@ -319,18 +479,33 @@
                 "skip to the end of the switch"),
             llds_instr(label(NextLabel), "next case")
         ]),
-        ThisCaseCode = tree_list([TestCode, TraceCode, GoalCode, SaveCode,
+            HeadCaseCode = tree_list([TestCode, TraceCode, GoalCode, SaveCode,
              ElseCode])
     ;
         maybe_generate_internal_event_code(Goal, SwitchGoalInfo, TraceCode,
             !CI),
         code_gen.generate_goal(CodeModel, Goal, GoalCode, !CI),
         generate_branch_end(StoreMap, !MaybeEnd, SaveCode, !CI),
-        ThisCaseCode = tree_list([TraceCode, GoalCode, SaveCode])
+            HeadCaseCode = tree_list([TraceCode, GoalCode, SaveCode])
     ),
     reset_to_position(BranchStart, !CI),
-    generate_cases(Cases, Var, CodeModel, CanFail,
-        SwitchGoalInfo, EndLabel, !MaybeEnd, OtherCasesCode, !CI),
-    CasesCode = tree(ThisCaseCode, OtherCasesCode).
+        generate_if_then_else_chain_cases(TailCases, Var, CodeModel, CanFail,
+            SwitchGoalInfo, EndLabel, !MaybeEnd, TailCasesCode, !CI),
+        Code = tree(HeadCaseCode, TailCasesCode)
+    ;
+        Cases = [],
+        (
+            CanFail = can_fail,
+            % At the end of a locally semidet switch, we fail because we came
+            % across a tag which was not covered by one of the cases. It is
+            % followed by the end of switch label to which the cases branch.
+            generate_failure(FailCode, !CI)
+        ;
+            CanFail = cannot_fail,
+            FailCode = empty
+        ),
+        EndCode = node([llds_instr(label(EndLabel), "end of switch")]),
+        Code = tree(FailCode, EndCode)
+    ).
 
 %-----------------------------------------------------------------------------%
Index: compiler/trace_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/trace_gen.m,v
retrieving revision 1.21
diff -u -b -r1.21 trace_gen.m
--- compiler/trace_gen.m	23 Nov 2007 07:35:29 -0000	1.21
+++ compiler/trace_gen.m	23 Nov 2007 07:45:40 -0000
@@ -458,7 +458,7 @@
 
 trace_setup(ModuleInfo, PredInfo, ProcInfo, Globals, TraceSlotInfo, TraceInfo,
         !CI) :-
-    CodeModel = code_info.get_proc_model(!.CI),
+    CodeModel = get_proc_model(!.CI),
     globals.get_trace_level(Globals, TraceLevel),
     globals.get_trace_suppress(Globals, TraceSuppress),
     globals.lookup_bool_option(Globals, trace_table_io, TraceTableIo),
@@ -468,7 +468,7 @@
         TraceRedo = yes,
         CodeModel = model_non
     ->
-        code_info.get_next_label(RedoLayoutLabel, !CI),
+        get_next_label(RedoLayoutLabel, !CI),
         MaybeRedoLayoutLabel = yes(RedoLayoutLabel),
         NextSlotAfterRedoLayout = 5
     ;
@@ -545,7 +545,7 @@
         MaybeMaxfrLval, MaybeCallTableLval, MaybeRedoLayoutLabel).
 
 generate_slot_fill_code(CI, TraceInfo, TraceCode) :-
-    CodeModel = code_info.get_proc_model(CI),
+    CodeModel = get_proc_model(CI),
     MaybeFromFullSlot  = TraceInfo ^ from_full_lval,
     MaybeIoSeqSlot     = TraceInfo ^ io_seq_lval,
     MaybeTrailLvals    = TraceInfo ^ trail_lvals,
@@ -656,8 +656,8 @@
     TraceCode = tree(TraceCode1, tree(TraceCode2, TraceCode3)).
 
 trace_prepare_for_call(CI, TraceCode) :-
-    code_info.get_maybe_trace_info(CI, MaybeTraceInfo),
-    CodeModel = code_info.get_proc_model(CI),
+    get_maybe_trace_info(CI, MaybeTraceInfo),
+    CodeModel = get_proc_model(CI),
     (
         MaybeTraceInfo = yes(TraceInfo),
         MaybeFromFullSlot = TraceInfo ^ from_full_lval,
@@ -681,7 +681,7 @@
     ).
 
 maybe_generate_internal_event_code(Goal, OutsideGoalInfo, Code, !CI) :-
-    code_info.get_maybe_trace_info(!.CI, MaybeTraceInfo),
+    get_maybe_trace_info(!.CI, MaybeTraceInfo),
     (
         MaybeTraceInfo = yes(TraceInfo),
         Goal = hlds_goal(_, GoalInfo),
@@ -717,9 +717,9 @@
             unexpected(this_file, "generate_internal_event_code: bad path")
         ),
         (
-            code_info.get_module_info(!.CI, ModuleInfo),
-            code_info.get_pred_info(!.CI, PredInfo),
-            code_info.get_proc_info(!.CI, ProcInfo),
+            get_module_info(!.CI, ModuleInfo),
+            get_pred_info(!.CI, PredInfo),
+            get_proc_info(!.CI, ProcInfo),
             eff_trace_needs_port(ModuleInfo, PredInfo, ProcInfo,
                 TraceInfo ^ trace_level,
                 TraceInfo ^ trace_suppress_items, Port) = yes
@@ -745,7 +745,7 @@
     ).
 
 maybe_generate_negated_event_code(Goal, OutsideGoalInfo, NegPort, Code, !CI) :-
-    code_info.get_maybe_trace_info(!.CI, MaybeTraceInfo),
+    get_maybe_trace_info(!.CI, MaybeTraceInfo),
     (
         MaybeTraceInfo = yes(TraceInfo),
         (
@@ -755,9 +755,9 @@
             NegPort = neg_success,
             Port = port_neg_success
         ),
-        code_info.get_module_info(!.CI, ModuleInfo),
-        code_info.get_pred_info(!.CI, PredInfo),
-        code_info.get_proc_info(!.CI, ProcInfo),
+        get_module_info(!.CI, ModuleInfo),
+        get_pred_info(!.CI, PredInfo),
+        get_proc_info(!.CI, ProcInfo),
         eff_trace_needs_port(ModuleInfo, PredInfo, ProcInfo,
             TraceInfo ^ trace_level,
             TraceInfo ^ trace_suppress_items, Port) = yes
@@ -777,13 +777,13 @@
     ).
 
 maybe_generate_foreign_proc_event_code(PragmaPort, Context, Code, !CI) :-
-    code_info.get_maybe_trace_info(!.CI, MaybeTraceInfo),
+    get_maybe_trace_info(!.CI, MaybeTraceInfo),
     (
         MaybeTraceInfo = yes(TraceInfo),
         Port = convert_nondet_foreign_proc_port_type(PragmaPort),
-        code_info.get_module_info(!.CI, ModuleInfo),
-        code_info.get_pred_info(!.CI, PredInfo),
-        code_info.get_proc_info(!.CI, ProcInfo),
+        get_module_info(!.CI, ModuleInfo),
+        get_pred_info(!.CI, PredInfo),
+        get_proc_info(!.CI, ProcInfo),
         eff_trace_needs_port(ModuleInfo, PredInfo, ProcInfo,
             TraceInfo ^ trace_level,
             TraceInfo ^ trace_suppress_items, Port) = yes
@@ -807,9 +807,9 @@
 generate_external_event_code(ExternalPort, TraceInfo, Context,
         MaybeExternalInfo, !CI) :-
     Port = convert_external_port_type(ExternalPort),
-    code_info.get_module_info(!.CI, ModuleInfo),
-    code_info.get_pred_info(!.CI, PredInfo),
-    code_info.get_proc_info(!.CI, ProcInfo),
+    get_module_info(!.CI, ModuleInfo),
+    get_pred_info(!.CI, PredInfo),
+    get_proc_info(!.CI, ProcInfo),
     NeedPort = eff_trace_needs_port(ModuleInfo, PredInfo, ProcInfo,
         TraceInfo ^ trace_level, TraceInfo ^ trace_suppress_items, Port),
     (
@@ -830,15 +830,15 @@
 
 generate_event_code(Port, PortInfo, MaybeTraceInfo, Context, HideEvent,
         MaybeUserInfo, Label, TvarDataMap, Code, !CI) :-
-    code_info.get_next_label(Label, !CI),
-    code_info.get_known_variables(!.CI, LiveVars0),
+    get_next_label(Label, !CI),
+    get_known_variables(!.CI, LiveVars0),
     (
         PortInfo = port_info_external,
         LiveVars = LiveVars0,
         Path = empty
     ;
         PortInfo = port_info_internal(Path, PreDeaths),
-        ResumeVars = code_info.current_resume_point_vars(!.CI),
+        ResumeVars = current_resume_point_vars(!.CI),
         set.difference(PreDeaths, ResumeVars, RealPreDeaths),
         set.to_sorted_list(RealPreDeaths, RealPreDeathList),
         list.delete_elems(LiveVars0, RealPreDeathList, LiveVars)
@@ -860,20 +860,20 @@
                 "generate_event_code: bad nondet foreign_proc port")
         )
     ),
-    VarTypes = code_info.get_var_types(!.CI),
-    code_info.get_varset(!.CI, VarSet),
-    code_info.get_instmap(!.CI, InstMap),
+    VarTypes = get_var_types(!.CI),
+    get_varset(!.CI, VarSet),
+    get_instmap(!.CI, InstMap),
     trace_produce_vars(LiveVars, VarSet, VarTypes, InstMap, Port,
         set.init, TvarSet, [], VarInfoList, ProduceCode, !CI),
-    code_info.max_reg_in_use(!.CI, MaxReg),
-    code_info.get_max_reg_in_use_at_trace(!.CI, MaxTraceReg0),
+    max_reg_in_use(!.CI, MaxReg),
+    get_max_reg_in_use_at_trace(!.CI, MaxTraceReg0),
     ( MaxTraceReg0 < MaxReg ->
-        code_info.set_max_reg_in_use_at_trace(MaxReg, !CI)
+        set_max_reg_in_use_at_trace(MaxReg, !CI)
     ;
         true
     ),
-    code_info.variable_locations(!.CI, VarLocs),
-    code_info.get_proc_info(!.CI, ProcInfo),
+    variable_locations(!.CI, VarLocs),
+    get_proc_info(!.CI, ProcInfo),
     set.to_sorted_list(TvarSet, TvarList),
     continuation_info.find_typeinfos_for_tvars(TvarList, VarLocs, ProcInfo,
         TvarDataMap),
@@ -901,9 +901,9 @@
         "path <" ++ goal_path_to_string(Path) ++ "> */\n" ++
         TraceStmt0,
 
-    code_info.add_trace_layout_for_label(Label, Context, Port, HideEvent,
+    add_trace_layout_for_label(Label, Context, Port, HideEvent,
         Path, MaybeUserInfo, LayoutLabelInfo, !CI),
-    code_info.set_proc_trace_events(yes, !CI),
+    set_proc_trace_events(yes, !CI),
     (
         Port = port_fail,
         MaybeTraceInfo = yes(TraceInfo),
@@ -919,7 +919,7 @@
         % at procedure entry. Therefore setup reserves a label
         % for the redo event, whose layout information is filled in
         % when we get to the fail event.
-        code_info.add_trace_layout_for_label(RedoLabel, Context, port_redo,
+        add_trace_layout_for_label(RedoLabel, Context, port_redo,
             HideEvent, Path, no, LayoutLabelInfo, !CI)
     ;
         true
@@ -990,7 +990,7 @@
 trace_produce_vars([Var | Vars], VarSet, VarTypes, InstMap, Port,
         !TVars, !VarInfos, tree(VarCode, VarsCode), !CI) :-
     map.lookup(VarTypes, Var, Type),
-    code_info.get_module_info(!.CI, ModuleInfo),
+    get_module_info(!.CI, ModuleInfo),
     ( is_dummy_argument_type(ModuleInfo, Type) ->
         VarCode = empty
     ;
@@ -1005,9 +1005,9 @@
     code_info::in, code_info::out) is det.
 
 trace_produce_var(Var, VarSet, InstMap, !Tvars, VarInfo, VarCode, !CI) :-
-    code_info.produce_variable_in_reg_or_stack(Var, VarCode, Lval, !CI),
-    Type = code_info.variable_type(!.CI, Var),
-    code_info.get_module_info(!.CI, ModuleInfo),
+    produce_variable_in_reg_or_stack(Var, VarCode, Lval, !CI),
+    Type = variable_type(!.CI, Var),
+    get_module_info(!.CI, ModuleInfo),
     ( varset.search_name(VarSet, Var, SearchName) ->
         Name = SearchName
     ;
Index: compiler/unify_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unify_gen.m,v
retrieving revision 1.184
diff -u -b -r1.184 unify_gen.m
--- compiler/unify_gen.m	23 Nov 2007 07:35:31 -0000	1.184
+++ compiler/unify_gen.m	23 Nov 2007 07:45:41 -0000
@@ -97,7 +97,7 @@
     ),
     (
         Uni = assign(Left, Right),
-        ( code_info.variable_is_forward_live(!.CI, Left) ->
+        ( variable_is_forward_live(!.CI, Left) ->
             generate_assignment(Left, Right, Code, !CI)
         ;
             Code = empty
@@ -112,7 +112,7 @@
             SubInfo = construct_sub_info(MaybeTakeAddr, MaybeSize)
         ),
         (
-            ( code_info.variable_is_forward_live(!.CI, Var)
+            ( variable_is_forward_live(!.CI, Var)
             ; MaybeTakeAddr = yes(_)
             )
         ->
@@ -158,8 +158,8 @@
     code_info::in, code_info::out) is det.
 
 generate_assignment(VarA, VarB, empty, !CI) :-
-    ( code_info.variable_is_forward_live(!.CI, VarA) ->
-        code_info.assign_var_to_var(VarA, VarB, !CI)
+    ( variable_is_forward_live(!.CI, VarA) ->
+        assign_var_to_var(VarA, VarB, !CI)
     ;
         % For free-free unifications, the mode analysis reports them as
         % assignment to the dead variable. For such unifications we of course
@@ -178,10 +178,9 @@
     code_info::in, code_info::out) is det.
 
 generate_test(VarA, VarB, Code, !CI) :-
-    code_info.produce_variable(VarA, CodeA, ValA, !CI),
-    code_info.produce_variable(VarB, CodeB, ValB, !CI),
-    CodeAB = tree(CodeA, CodeB),
-    Type = code_info.variable_type(!.CI, VarA),
+    produce_variable(VarA, CodeA, ValA, !CI),
+    produce_variable(VarB, CodeB, ValB, !CI),
+    Type = variable_type(!.CI, VarA),
     ( Type = builtin_type(builtin_type_string) ->
         Op = str_eq
     ; Type = builtin_type(builtin_type_float) ->
@@ -189,13 +188,13 @@
     ;
         Op = eq
     ),
-    code_info.fail_if_rval_is_false(binop(Op, ValA, ValB), FailCode, !CI),
-    Code = tree(CodeAB, FailCode).
+    fail_if_rval_is_false(binop(Op, ValA, ValB), FailCode, !CI),
+    Code = tree_list([CodeA, CodeB, FailCode]).
 
 %---------------------------------------------------------------------------%
 
 generate_tag_test(Var, ConsId, Sense, ElseLab, Code, !CI) :-
-    code_info.produce_variable(Var, VarCode, Rval, !CI),
+    produce_variable(Var, VarCode, Rval, !CI),
     % As an optimization, for data types with exactly two alternatives,
     % one of which is a constant, we make sure that we test against the
     % constant (negating the result of the test, if needed),
@@ -204,8 +203,8 @@
         ConsId = cons(_, Arity),
         Arity > 0
     ->
-        Type = code_info.variable_type(!.CI, Var),
-        TypeDefn = code_info.lookup_type_defn(!.CI, Type),
+        Type = variable_type(!.CI, Var),
+        TypeDefn = lookup_type_defn(!.CI, Type),
         hlds_data.get_type_defn_body(TypeDefn, TypeBody),
         ( ConsTable = TypeBody ^ du_type_cons_tag_values ->
             map.to_assoc_list(ConsTable, ConsList),
@@ -228,25 +227,24 @@
     ;
         Reverse = no
     ),
-    VarName = code_info.variable_to_string(!.CI, Var),
+    VarName = variable_to_string(!.CI, Var),
     ConsIdName = hlds_out.cons_id_to_string(ConsId),
+    Comment0 = "checking that " ++ VarName ++ " has functor " ++ ConsIdName,
     (
         Reverse = no,
-        string.append_list(["checking that ", VarName, " has functor ",
-            ConsIdName], Comment),
+        Comment = Comment0,
         CommentCode = node([llds_instr(comment(Comment), "")]),
         Tag = cons_id_to_tag_for_var(!.CI, Var, ConsId),
         generate_tag_test_rval_2(Tag, Rval, TestRval)
     ;
         Reverse = yes(TestConsId),
-        string.append_list(["checking that ", VarName, " has functor ",
-            ConsIdName, " (inverted test)"], Comment),
+        Comment = Comment0 ++ " (inverted test)",
         CommentCode = node([llds_instr(comment(Comment), "")]),
         Tag = cons_id_to_tag_for_var(!.CI, Var, TestConsId),
         generate_tag_test_rval_2(Tag, Rval, NegTestRval),
         code_util.neg_rval(NegTestRval, TestRval)
     ),
-    code_info.get_next_label(ElseLab, !CI),
+    get_next_label(ElseLab, !CI),
     (
         Sense = branch_on_success,
         TheRval = TestRval
@@ -257,7 +255,7 @@
     TestCode = node([
         llds_instr(if_val(TheRval, code_label(ElseLab)), "tag test")
     ]),
-    Code = tree(VarCode, tree(CommentCode, TestCode)).
+    Code = tree_list([VarCode, CommentCode, TestCode]).
 
 %---------------------------------------------------------------------------%
 
@@ -265,7 +263,7 @@
     rval::out, code_tree::out, code_info::in, code_info::out) is det.
 
 generate_tag_test_rval(Var, ConsId, TestRval, Code, !CI) :-
-    code_info.produce_variable(Var, Code, Rval, !CI),
+    produce_variable(Var, Code, Rval, !CI),
     Tag = cons_id_to_tag_for_var(!.CI, Var, ConsId),
     generate_tag_test_rval_2(Tag, Rval, TestRval).
 
@@ -388,22 +386,22 @@
         TakeAddr, MaybeSize, GoalInfo, Code, !CI) :-
     (
         ConsTag = string_tag(String),
-        code_info.assign_const_to_var(Var, const(llconst_string(String)), !CI),
+        assign_const_to_var(Var, const(llconst_string(String)), !CI),
         Code = empty
     ;
         ConsTag = int_tag(Int),
-        code_info.assign_const_to_var(Var, const(llconst_int(Int)), !CI),
+        assign_const_to_var(Var, const(llconst_int(Int)), !CI),
         Code = empty
     ;
         ConsTag = foreign_tag(Lang, Val),
         expect(unify(Lang, lang_c), this_file,
             "foreign_tag for language other than C"),
         ForeignConst = const(llconst_foreign(Val, integer)),
-        code_info.assign_const_to_var(Var, ForeignConst, !CI),
+        assign_const_to_var(Var, ForeignConst, !CI),
         Code = empty
     ;
         ConsTag = float_tag(Float),
-        code_info.assign_const_to_var(Var, const(llconst_float(Float)), !CI),
+        assign_const_to_var(Var, const(llconst_float(Float)), !CI),
         Code = empty
     ;
         ConsTag = no_tag,
@@ -413,7 +411,7 @@
         ->
             (
                 TakeAddr = [],
-                Type = code_info.variable_type(!.CI, Arg),
+                Type = variable_type(!.CI, Arg),
                 generate_sub_unify(ref(Var), ref(Arg), Mode, Type, Code, !CI)
             ;
                 TakeAddr = [_ | _],
@@ -447,7 +445,7 @@
             MaybeSize, FieldAddrs, MayUseAtomic, Code, !CI)
     ;
         ConsTag = shared_local_tag(Bits1, Num1),
-        code_info.assign_const_to_var(Var,
+        assign_const_to_var(Var,
             mkword(Bits1, unop(mkbody, const(llconst_int(Num1)))), !CI),
         Code = empty
     ;
@@ -457,15 +455,14 @@
         RttiTypeCtor = rtti_type_ctor(ModuleName, TypeName, TypeArity),
         DataAddr = rtti_addr(ctor_rtti_id(RttiTypeCtor,
             type_ctor_type_ctor_info)),
-        code_info.assign_const_to_var(Var,
-            const(llconst_data_addr(DataAddr, no)), !CI),
+        assign_const_to_var(Var, const(llconst_data_addr(DataAddr, no)), !CI),
         Code = empty
     ;
         ConsTag = base_typeclass_info_tag(ModuleName, ClassId, Instance),
         expect(unify(Args, []), this_file,
             "generate_construction_2: base_typeclass_info constant has args"),
         TCName = generate_class_name(ClassId),
-        code_info.assign_const_to_var(Var,
+        assign_const_to_var(Var,
             const(llconst_data_addr(rtti_addr(tc_rtti_id(TCName,
                 type_class_base_typeclass_info(ModuleName, Instance))), no)),
                 !CI),
@@ -474,19 +471,18 @@
         ConsTag = tabling_info_tag(PredId, ProcId),
         expect(unify(Args, []), this_file,
             "generate_construction_2: tabling_info constant has args"),
-        code_info.get_module_info(!.CI, ModuleInfo),
+        get_module_info(!.CI, ModuleInfo),
         ProcLabel = make_proc_label(ModuleInfo, PredId, ProcId),
         module_info_get_name(ModuleInfo, ModuleName),
         DataAddr = data_addr(ModuleName,
             proc_tabling_ref(ProcLabel, tabling_info)),
-        code_info.assign_const_to_var(Var,
-            const(llconst_data_addr(DataAddr, no)), !CI),
+        assign_const_to_var(Var, const(llconst_data_addr(DataAddr, no)), !CI),
         Code = empty
     ;
         ConsTag = deep_profiling_proc_layout_tag(PredId, ProcId),
         expect(unify(Args, []), this_file,
             "generate_construction_2: deep_profiling_proc_static has args"),
-        code_info.get_module_info(!.CI, ModuleInfo),
+        get_module_info(!.CI, ModuleInfo),
         RttiProcLabel = make_rtti_proc_label(ModuleInfo, PredId, ProcId),
         Origin = RttiProcLabel ^ pred_info_origin,
         ( Origin = origin_special_pred(_) ->
@@ -496,24 +492,22 @@
         ),
         ProcKind = proc_layout_proc_id(UserOrUCI),
         DataAddr = layout_addr(proc_layout(RttiProcLabel, ProcKind)),
-        code_info.assign_const_to_var(Var,
-            const(llconst_data_addr(DataAddr, no)), !CI),
+        assign_const_to_var(Var, const(llconst_data_addr(DataAddr, no)), !CI),
         Code = empty
     ;
         ConsTag = table_io_decl_tag(PredId, ProcId),
         expect(unify(Args, []), this_file,
             "generate_construction_2: table_io_decl has args"),
-        code_info.get_module_info(!.CI, ModuleInfo),
+        get_module_info(!.CI, ModuleInfo),
         RttiProcLabel = make_rtti_proc_label(ModuleInfo, PredId, ProcId),
         DataAddr = layout_addr(table_io_decl(RttiProcLabel)),
-        code_info.assign_const_to_var(Var,
-            const(llconst_data_addr(DataAddr, no)), !CI),
+        assign_const_to_var(Var, const(llconst_data_addr(DataAddr, no)), !CI),
         Code = empty
     ;
         ConsTag = reserved_address_tag(RA),
         expect(unify(Args, []), this_file,
             "generate_construction_2: reserved_address constant has args"),
-        code_info.assign_const_to_var(Var, generate_reserved_address(RA), !CI),
+        assign_const_to_var(Var, generate_reserved_address(RA), !CI),
         Code = empty
     ;
         ConsTag = shared_with_reserved_addresses_tag(_RAs, ThisTag),
@@ -541,7 +535,7 @@
     code_info::in, code_info::out) is det.
 
 generate_closure(PredId, ProcId, EvalMethod, Var, Args, GoalInfo, Code, !CI) :-
-    code_info.get_module_info(!.CI, ModuleInfo),
+    get_module_info(!.CI, ModuleInfo),
     module_info_preds(ModuleInfo, Preds),
     map.lookup(Preds, PredId, PredInfo),
     pred_info_get_procedures(PredInfo, Procs),
@@ -600,15 +594,15 @@
         (
             CallArgs = [],
             % If there are no new arguments, we can just use the old closure.
-            code_info.assign_var_to_var(Var, CallPred, !CI),
+            assign_var_to_var(Var, CallPred, !CI),
             Code = empty
         ;
             CallArgs = [_ | _],
-            code_info.get_next_label(LoopStart, !CI),
-            code_info.get_next_label(LoopTest, !CI),
-            code_info.acquire_reg(reg_r, LoopCounter, !CI),
-            code_info.acquire_reg(reg_r, NumOldArgs, !CI),
-            code_info.acquire_reg(reg_r, NewClosure, !CI),
+            get_next_label(LoopStart, !CI),
+            get_next_label(LoopTest, !CI),
+            acquire_reg(reg_r, LoopCounter, !CI),
+            acquire_reg(reg_r, NumOldArgs, !CI),
+            acquire_reg(reg_r, NewClosure, !CI),
             Zero = const(llconst_int(0)),
             One = const(llconst_int(1)),
             Two = const(llconst_int(2)),
@@ -617,8 +611,7 @@
             NumNewArgs_Rval = const(llconst_int(NumNewArgs)),
             NumNewArgsPlusThree = NumNewArgs + 3,
             NumNewArgsPlusThree_Rval = const(llconst_int(NumNewArgsPlusThree)),
-            code_info.produce_variable(CallPred, OldClosureCode,
-                OldClosure, !CI),
+            produce_variable(CallPred, OldClosureCode, OldClosure, !CI),
             % The new closure contains a pointer to the old closure.
             NewClosureMayUseAtomic = may_not_use_atomic_alloc,
             NewClosureCode = node([
@@ -668,10 +661,10 @@
             ]),
             generate_extra_closure_args(CallArgs, LoopCounter, NewClosure,
                 ExtraArgsCode, !CI),
-            code_info.release_reg(LoopCounter, !CI),
-            code_info.release_reg(NumOldArgs, !CI),
-            code_info.release_reg(NewClosure, !CI),
-            code_info.assign_lval_to_var(Var, NewClosure, AssignCode, !CI),
+            release_reg(LoopCounter, !CI),
+            release_reg(NumOldArgs, !CI),
+            release_reg(NewClosure, !CI),
+            assign_lval_to_var(Var, NewClosure, AssignCode, !CI),
             Code = tree_list([OldClosureCode, NewClosureCode, ExtraArgsCode,
                  AssignCode])
         )
@@ -687,20 +680,19 @@
         term.context_line(Context, LineNumber),
         GoalPath = goal_info_get_goal_path(GoalInfo),
         GoalPathStr = goal_path_to_string(GoalPath),
-        code_info.get_cur_proc_label(!.CI, CallerProcLabel),
-        code_info.get_next_closure_seq_no(SeqNo, !CI),
-        code_info.get_static_cell_info(!.CI, StaticCellInfo0),
+        get_cur_proc_label(!.CI, CallerProcLabel),
+        get_next_closure_seq_no(SeqNo, !CI),
+        get_static_cell_info(!.CI, StaticCellInfo0),
         hlds.hlds_pred.pred_info_get_origin(PredInfo, PredOrigin),
         stack_layout.construct_closure_layout(CallerProcLabel,
             SeqNo, ClosureInfo, ProcLabel, ModuleName, FileName, LineNumber,
             PredOrigin, GoalPathStr, StaticCellInfo0, StaticCellInfo,
             ClosureLayoutRvalsTypes, Data),
-        code_info.set_static_cell_info(StaticCellInfo, !CI),
-        code_info.add_closure_layout(Data, !CI),
+        set_static_cell_info(StaticCellInfo, !CI),
+        add_closure_layout(Data, !CI),
         % For now, closures always have zero size, and the size slot
         % is never looked at.
-        code_info.add_scalar_static_cell(ClosureLayoutRvalsTypes,
-            ClosureDataAddr, !CI),
+        add_scalar_static_cell(ClosureLayoutRvalsTypes, ClosureDataAddr, !CI),
         ClosureLayoutRval = const(llconst_data_addr(ClosureDataAddr, no)),
         list.length(Args, NumArgs),
         proc_info_arg_info(ProcInfo, ArgInfo),
@@ -716,8 +708,8 @@
         ],
         % XXX construct_dynamically is just a dummy value. We just want
         % something which is not construct_in_region(_).
-        code_info.assign_cell_to_var(Var, no, 0, Vector,
-            construct_dynamically, no, [], "closure", MayUseAtomic, Code, !CI)
+        assign_cell_to_var(Var, no, 0, Vector, construct_dynamically, no, [],
+            "closure", MayUseAtomic, Code, !CI)
     ).
 
 :- pred generate_extra_closure_args(list(prog_var)::in, lval::in,
@@ -726,7 +718,7 @@
 generate_extra_closure_args([], _, _, empty, !CI).
 generate_extra_closure_args([Var | Vars], LoopCounter, NewClosure, Code,
         !CI) :-
-    code_info.produce_variable(Var, Code0, Value, !CI),
+    produce_variable(Var, Code0, Value, !CI),
     One = const(llconst_int(1)),
     Code1 = node([
         llds_instr(
@@ -769,7 +761,7 @@
 
 generate_cons_args(Vars, Types, Modes, FirstOffset, FirstArgNum, TakeAddr,
         CI, !:Args, !:FieldAddrs, !:MayUseAtomic) :-
-    code_info.get_module_info(CI, ModuleInfo),
+    get_module_info(CI, ModuleInfo),
     !:MayUseAtomic = initial_may_use_atomic(ModuleInfo),
     (
         generate_cons_args_2(Vars, Types, Modes, FirstOffset, FirstArgNum,
@@ -794,10 +786,10 @@
 generate_cons_args_2([Var | Vars], [Type | Types], [UniMode | UniModes],
         FirstOffset, CurArgNum, !.TakeAddr, CI, [MaybeRval | MaybeRvals],
         FieldAddrs, !MayUseAtomic) :-
-    code_info.get_module_info(CI, ModuleInfo),
+    get_module_info(CI, ModuleInfo),
     update_type_may_use_atomic_alloc(ModuleInfo, Type, !MayUseAtomic),
     ( !.TakeAddr = [CurArgNum | !:TakeAddr] ->
-        code_info.get_lcmc_null(CI, LCMCNull),
+        get_lcmc_null(CI, LCMCNull),
         (
             LCMCNull = no,
             MaybeRval = no
@@ -849,7 +841,7 @@
 
 construct_cell(Var, Ptag, MaybeRvals, HowToConstruct, MaybeSize, FieldAddrs,
         MayUseAtomic, Code, !CI) :-
-    VarType = code_info.variable_type(!.CI, Var),
+    VarType = variable_type(!.CI, Var),
     var_type_msg(VarType, VarTypeMsg),
     % If we're doing accurate GC, then for types which hold RTTI that
     % will be traversed by the collector at GC-time, we need to allocate
@@ -858,7 +850,7 @@
     % in the "from" space, but this can't be done for objects which will be
     % referenced during the garbage collection process.
     (
-        code_info.get_globals(!.CI, Globals),
+        get_globals(!.CI, Globals),
         globals.get_gc_method(Globals, GCMethod),
         GCMethod = gc_accurate,
         is_introduced_type_info_type(VarType)
@@ -868,7 +860,7 @@
         ReserveWordAtStart = no
     ),
     FieldNums = list.map(fst, FieldAddrs),
-    code_info.assign_cell_to_var(Var, ReserveWordAtStart, Ptag, MaybeRvals,
+    assign_cell_to_var(Var, ReserveWordAtStart, Ptag, MaybeRvals,
         HowToConstruct, MaybeSize, FieldNums, VarTypeMsg, MayUseAtomic,
         CellCode, !CI),
     (
@@ -904,7 +896,7 @@
     is det.
 
 var_types(CI, Vars, Types) :-
-    code_info.get_proc_info(CI, ProcInfo),
+    get_proc_info(CI, ProcInfo),
     proc_info_get_vartypes(ProcInfo, VarTypes),
     map.apply_to_list(Vars, VarTypes, Types).
 
@@ -972,8 +964,8 @@
             Args = [Arg],
             Modes = [Mode]
         ->
-            VarType = code_info.variable_type(!.CI, Var),
-            code_info.get_module_info(!.CI, ModuleInfo),
+            VarType = variable_type(!.CI, Var),
+            get_module_info(!.CI, ModuleInfo),
             ( is_dummy_argument_type(ModuleInfo, VarType) ->
                 % We must handle this case specially. If we didn't, the
                 % generated code would copy the reference to the Var's
@@ -983,14 +975,13 @@
                 % This can happen in the unify/compare routines for e.g.
                 % io.state.
                 ( variable_is_forward_live(!.CI, Arg) ->
-                    code_info.assign_const_to_var(Arg, const(llconst_int(0)),
-                        !CI)
+                    assign_const_to_var(Arg, const(llconst_int(0)), !CI)
                 ;
                     true
                 ),
                 Code = empty
             ;
-                ArgType = code_info.variable_type(!.CI, Arg),
+                ArgType = variable_type(!.CI, Arg),
                 generate_sub_unify(ref(Var), ref(Arg), Mode, ArgType, Code,
                     !CI)
             )
@@ -1036,9 +1027,9 @@
 
 generate_semi_deconstruction(Var, Tag, Args, Modes, Code, !CI) :-
     generate_tag_test(Var, Tag, branch_on_success, SuccLab, TagTestCode, !CI),
-    code_info.remember_position(!.CI, AfterUnify),
-    code_info.generate_failure(FailCode, !CI),
-    code_info.reset_to_position(AfterUnify, !CI),
+    remember_position(!.CI, AfterUnify),
+    generate_failure(FailCode, !CI),
+    reset_to_position(AfterUnify, !CI),
     generate_det_deconstruction(Var, Tag, Args, Modes, DeconsCode, !CI),
     SuccessLabelCode = node([llds_instr(label(SuccLab), "")]),
     Code = tree_list([TagTestCode, FailCode, SuccessLabelCode, DeconsCode]).
@@ -1078,7 +1069,7 @@
 
 generate_sub_unify(L, R, Mode, Type, Code, !CI) :-
     Mode = ((LI - RI) -> (LF - RF)),
-    code_info.get_module_info(!.CI, ModuleInfo),
+    get_module_info(!.CI, ModuleInfo),
     mode_to_arg_mode(ModuleInfo, (LI -> LF), Type, LeftMode),
     mode_to_arg_mode(ModuleInfo, (RI -> RF), Type, RightMode),
     (
@@ -1129,21 +1120,21 @@
         Right = ref(Var),
         % Assignment from a variable to an lvalue - cannot cache
         % so generate immediately.
-        code_info.produce_variable(Var, SourceCode, Source, !CI),
-        code_info.materialize_vars_in_lval(Lval0, Lval, MaterializeCode, !CI),
+        produce_variable(Var, SourceCode, Source, !CI),
+        materialize_vars_in_lval(Lval0, Lval, MaterializeCode, !CI),
         CopyCode = node([llds_instr(assign(Lval, Source), "Copy value")]),
         Code = tree_list([SourceCode, MaterializeCode, CopyCode])
     ;
         Left = ref(Lvar),
-        ( code_info.variable_is_forward_live(!.CI, Lvar) ->
+        ( variable_is_forward_live(!.CI, Lvar) ->
             (
                 Right = lval(Lval),
                 % Assignment of a value to a variable, generate now.
-                code_info.assign_lval_to_var(Lvar, Lval, Code, !CI)
+                assign_lval_to_var(Lvar, Lval, Code, !CI)
             ;
                 Right = ref(Rvar),
                 % Assignment of a variable to a variable, so cache it.
-                code_info.assign_var_to_var(Lvar, Rvar, !CI),
+                assign_var_to_var(Lvar, Rvar, !CI),
                 Code = empty
             )
         ;
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
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/concurrency
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_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/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: [02:10:38] waiting for uid20308's lock in /home/mercury/mercury1/repository/mercury/extras/references
cvs diff: [02:11:08] obtained lock in /home/mercury/mercury1/repository/mercury/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 mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: [02:11:11] waiting for uid20308's lock in /home/mercury/mercury1/repository/mercury/runtime
cvs diff: [02:11:41] obtained lock in /home/mercury/mercury1/repository/mercury/runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
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/diff
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/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
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/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