[m-rev.] for review: set_of_progvar

Zoltan Somogyi zs at csse.unimelb.edu.au
Tue Jul 19 16:49:18 AEST 2011


For review by anyone.

Julien: the bug fix described in the last paragraph of the log message
(a one-line diff) should be applied to the release branch as well.

Zoltan.

Predicates with many variables, such as some of those in zm_enums.m,
tickle pretty bad behavior in the liveness and stack_alloc passes.
This is because those passes manipulate sets of variables, which in
such cases are large sets of variables, and the quadratic behavior
of repeated operations on sets represents as sorted lists hurts us.

This diff changes the representation of the sets of variables involved
in those two passes, which are the prebirth, postbirth, predeath and postdeath
sets in goal_infos, to be values of an abstract type (set_of_progvar).
By default, these are implemented using tree_bitsets, which have much better
worst case behaviour that set_ordlists.

When compiling zm_enums with debugging enabled, this diff speeds up
the liveness pass by about half and the stack alloc pass by about a third,
with the overall speedup being about 6% (due to some other expensive passes).

On tools/speedtest -l, the result is a 3.4% slowdown. Since the slowdown
worsens slightly if I make the abstract representation of sets of prog_vars
be the existing representation (an ordinary set), I think this slowdown is
due to the conversions that are now required in some places between the
abstract representation and an explicit set(prog_var) representation.
As such, as other uses of set(progvar) get converted to set_of_progvar,

compiler/set_of_var.m:
	The new module that contains the set_of_progvar abstract data type.

	This module also contains a copy of the code of the graph_colour
	module. Since the set_of_progvar type is private, this is necessary
	if we want all the set operations done by graph colouring (which does
	the bulk of the work of the stack alloc pass) to use the preferred
	set representation.

compiler/graph_colour.m:
	Note that this module is no longer used.

compiler/stack_alloc.m:
compiler/liveness.m:
	Switch over to using the new module.

compiler/parse_tree.m:
	Include set_of_var among the modules of this package. (It is in this
	package because the prog_var type is defined in this package.)

compiler/test_bitset.m:
	A module that allows new set implementations to be tested. It is
	an extended and specialized version of the bitset_tester module
	from tests/hard_coded.

compiler/hlds_llds.m:
	Use the set_of_progvar type for the prebirth, postbirth, predeath
	and postdeath sets in goal_infos, and for other liveness-related
	sets of variables.

compiler/code_info.m:
	Some of the fields of the code_info structure represent sets of
	variables, and some of the predicates defined by this module have
	arguments that are sets of variables. If these sets represent entities
	that are computed from prebirth, postbirth, predeath and postdeath
	sets or from other goal_info fields that have been changed to the
	set_of_progvar representation, change them to use the set_of_progvar
	representation as well, or, in a few cases, to plain sorted lists.

	Conform to the above change.

compiler/proc_type.m:
	Add a utility predicate to operate of set_of_progvar.

	Replace a lambda expression with a named predicate.

compiler/quantification.m:
	Until now, quantification.m used its own private abstract type
	(defined as tree_bitset) to represent sets. Make it use set_of_progvar
	instead, since it has the same purpose. This eliminates a potential
	maintenance problem.

compiler/call_gen.m:
compiler/code_gen.m:
compiler/commit_gen.m:
compiler/delay_construct.m:
compiler/disj_gen.m:
compiler/hlds_out_goal.m:
compiler/hlds_rtti.m:
compiler/interval.m:
compiler/ite_gen.m:
compiler/live_vars.m:
compiler/lookup_switch.m:
compiler/lookup_util.m:
compiler/matching.m:
compiler/pd_util.m:
compiler/polymorphism.m:
compiler/pragma_c_gen.m:
compiler/proc_gen.m:
compiler/simplify.m:
compiler/stack_opt.m:
compiler/store_alloc.m:
compiler/string_switch.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/structure_sharing.domain.m:
compiler/switch_util.m:
compiler/trace_gen.m:
compiler/tupling.m:
compiler/unify_gen.m:
compiler/unused_args.m:
	Conform to the above change.

library/map.m:
	Add a utility predicate, map.select_sorted_list, which functions the
	same way as map.select, but takes a sorted list as argument instead of
	a set.

library/set_ordlist.m:
	Bring the interface of this module closer to set.m and tree_bitset.m
	to make them more easily interchangeable. This required adding the
	predicates is_non_empty and is_singleton, as well as adding predicate
	forms of union_list and intersect_list.

	I also added missing type_spec pragmas for some predicates frequently
	used by the compiler.

library/tree_bitset.m:
	Bring the interface of this module closer to set.m and set_ordlist.m
	to make them more easily interchangeable. This required adding the
	predicates is_non_empty and is_singleton, and both function and
	predicate forms of union_list and intersect_list.

	Fix an old bug in the difference operation. Given SetA - SetB,
	if SetA was the empty set, then this operation would correctly
	return the empty set if SetB was small (represented by a leaf list),
	but would incorrectly return SetB if it was large (represented by
	an interior node list).

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/extra
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/extra
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/doc
cvs diff: Diffing boehm_gc/libatomic_ops/src
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/armcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops/tests
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/m4
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/call_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/call_gen.m,v
retrieving revision 1.202
diff -u -b -r1.202 call_gen.m
--- compiler/call_gen.m	23 May 2011 05:08:00 -0000	1.202
+++ compiler/call_gen.m	10 Jul 2011 22:34:29 -0000
@@ -74,6 +74,7 @@
 :- import_module ll_backend.trace_gen.
 :- import_module mdbcomp.goal_path.
 :- import_module parse_tree.prog_event.
+:- import_module parse_tree.set_of_var.
 
 :- import_module bool.
 :- import_module cord.
@@ -543,18 +544,18 @@
     % and handle_return ignore them.
     %
 :- pred kill_dead_input_vars(assoc_list(prog_var, arg_info)::in,
-    hlds_goal_info::in, set(prog_var)::out,
+    hlds_goal_info::in, set_of_progvar::out,
     code_info::in, code_info::out) is det.
 
 kill_dead_input_vars(ArgsInfos, GoalInfo, NonLiveOutputs, !CI) :-
     get_forward_live_vars(!.CI, Liveness),
-    find_nonlive_outputs(ArgsInfos, Liveness, set.init, NonLiveOutputs),
+    find_nonlive_outputs(ArgsInfos, Liveness, set_of_var.init, NonLiveOutputs),
     goal_info_get_post_deaths(GoalInfo, PostDeaths),
-    set.difference(PostDeaths, NonLiveOutputs, ImmediatePostDeaths),
+    set_of_var.difference(PostDeaths, NonLiveOutputs, ImmediatePostDeaths),
     make_vars_forward_dead(ImmediatePostDeaths, !CI).
 
 :- pred handle_return(assoc_list(prog_var, arg_info)::in,
-    hlds_goal_info::in, set(prog_var)::in, instmap::in,
+    hlds_goal_info::in, set_of_progvar::in, instmap::in,
     list(liveinfo)::out, code_info::in, code_info::out) is det.
 
 handle_return(ArgsInfos, GoalInfo, _NonLiveOutputs, ReturnInstMap,
@@ -572,17 +573,17 @@
         ReturnInstMap, OkToDeleteAny, ReturnLiveLvalues).
 
 :- pred find_nonlive_outputs(assoc_list(prog_var, arg_info)::in,
-    set(prog_var)::in, set(prog_var)::in, set(prog_var)::out) is det.
+    set_of_progvar::in, set_of_progvar::in, set_of_progvar::out) is det.
 
 find_nonlive_outputs([], _, !NonLiveOutputs).
 find_nonlive_outputs([Var - arg_info(_ArgLoc, Mode) | Args],
         Liveness, !NonLiveOutputs) :-
     (
         Mode = top_out,
-        ( set.member(Var, Liveness) ->
+        ( set_of_var.member(Liveness, Var) ->
             true
         ;
-            set.insert(Var, !NonLiveOutputs)
+            set_of_var.insert(Var, !NonLiveOutputs)
         )
     ;
         ( Mode = top_in
@@ -592,7 +593,7 @@
     find_nonlive_outputs(Args, Liveness, !NonLiveOutputs).
 
 :- pred rebuild_registers(assoc_list(prog_var, arg_info)::in,
-    set(prog_var)::in, assoc_list(prog_var, arg_loc)::out,
+    set_of_progvar::in, assoc_list(prog_var, arg_loc)::out,
     code_info::in, code_info::out) is det.
 
 rebuild_registers([], _, [], !CI).
@@ -601,7 +602,7 @@
     rebuild_registers(Args, Liveness, OutputArgLocs1, !CI),
     (
         Mode = top_out,
-        set.member(Var, Liveness)
+        set_of_var.member(Liveness, Var)
     ->
         code_util.arg_loc_to_register(ArgLoc, Register),
         set_var_location(Var, Register, !CI),
Index: compiler/code_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_gen.m,v
retrieving revision 1.185
diff -u -b -r1.185 code_gen.m
--- compiler/code_gen.m	18 Jul 2011 05:09:34 -0000	1.185
+++ compiler/code_gen.m	18 Jul 2011 05:11:52 -0000
@@ -56,6 +56,7 @@
 :- import_module ll_backend.switch_gen.
 :- import_module ll_backend.unify_gen.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module bool.
 :- import_module cord.
@@ -229,7 +230,7 @@
 %---------------------------------------------------------------------------%
 
 :- pred generate_goal_expr(hlds_goal_expr::in, hlds_goal_info::in,
-    code_model::in, set(prog_var)::in, llds_code::out,
+    code_model::in, set_of_progvar::in, llds_code::out,
     code_info::in, code_info::out) is det.
 
 generate_goal_expr(GoalExpr, GoalInfo, CodeModel, ForwardLiveVarsBeforeGoal,
Index: compiler/code_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_info.m,v
retrieving revision 1.391
diff -u -b -r1.391 code_info.m
--- compiler/code_info.m	18 Jul 2011 05:09:35 -0000	1.391
+++ compiler/code_info.m	18 Jul 2011 05:10:55 -0000
@@ -47,6 +47,7 @@
 :- import_module mdbcomp.prim_data.
 :- import_module mdbcomp.goal_path.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module assoc_list.
 :- import_module bool.
@@ -159,11 +160,11 @@
 
     % Get the set of currently forward-live variables.
     %
-:- pred get_forward_live_vars(code_info::in, set(prog_var)::out) is det.
+:- pred get_forward_live_vars(code_info::in, set_of_progvar::out) is det.
 
     % Set the set of currently forward-live variables.
     %
-:- pred set_forward_live_vars(set(prog_var)::in,
+:- pred set_forward_live_vars(set_of_progvar::in,
     code_info::in, code_info::out) is det.
 
     % Get the table mapping variables to the current
@@ -258,9 +259,9 @@
 
 :- pred get_opt_no_return_calls(code_info::in, bool::out) is det.
 
-:- pred get_zombies(code_info::in, set(prog_var)::out) is det.
+:- pred get_zombies(code_info::in, set_of_progvar::out) is det.
 
-:- pred set_zombies(set(prog_var)::in, code_info::in, code_info::out) is det.
+:- pred set_zombies(set_of_progvar::in, code_info::in, code_info::out) is det.
 
 :- pred get_var_locn_info(code_info::in, var_locn_info::out) is det.
 
@@ -392,14 +393,14 @@
 :- type code_info_loc_dep
     --->    code_info_loc_dep(
                 % Variables that are forward live after this goal.
-                cild_forward_live_vars  :: set(prog_var),
+                cild_forward_live_vars  :: set_of_progvar,
 
                 % Current insts of the live variables.
                 cild_instmap            :: instmap,
 
                 % Zombie variables; variables that are not forward live
                 % but which are protected by an enclosing resume point.
-                cild_zombies            :: set(prog_var),
+                cild_zombies            :: set_of_progvar,
 
                 % A map storing the information about the status of each known
                 % variable. (Known vars = forward live vars + zombies.)
@@ -489,7 +490,8 @@
 
 code_info_init(SaveSuccip, Globals, PredId, ProcId, PredInfo, ProcInfo,
         FollowVars, ModuleInfo, StaticCellInfo, ResumePoint, TraceSlotInfo,
-        MaybeContainingGoalMap, TSRevStringTable, TSStringTableSize, CodeInfo) :-
+        MaybeContainingGoalMap, TSRevStringTable, TSStringTableSize,
+        CodeInfo) :-
     proc_info_get_initial_instmap(ProcInfo, ModuleInfo, InstMap),
     proc_info_get_liveness_info(ProcInfo, Liveness),
     CodeModel = proc_info_interface_code_model(ProcInfo),
@@ -526,7 +528,7 @@
     map.init(TempContentMap),
     set.init(PersistentTemps),
     set.init(TempsInUse),
-    set.init(Zombies),
+    Zombies = set_of_var.init,
     map.init(LayoutMap),
     max_var_slot(StackSlots, VarSlotMax),
     trace_reserved_slots(ModuleInfo, PredInfo, ProcInfo, Globals,
@@ -579,7 +581,7 @@
             MaybeContainingGoalMap
         ),
         code_info_loc_dep(
-            Liveness,
+            set_to_bitset(Liveness),
             InstMap,
             Zombies,
             VarLocnInfo,
@@ -848,7 +850,7 @@
 
 :- func lookup_cheaper_tag_test(code_info, mer_type) = maybe_cheaper_tag_test.
 
-:- func filter_region_vars(code_info, set(prog_var)) = set(prog_var).
+:- func filter_region_vars(code_info, set_of_progvar) = set_of_progvar.
 
     % Get the code model of the current procedure.
     %
@@ -869,7 +871,7 @@
     % Get the set of variables currently needed by the resume
     % points of enclosing goals.
     %
-:- func current_resume_point_vars(code_info) = set(prog_var).
+:- func current_resume_point_vars(code_info) = set_of_progvar.
 
 :- func variable_name(code_info, prog_var) = string.
 
@@ -1054,7 +1056,7 @@
 
 filter_region_vars(CI, ForwardLiveVarsBeforeGoal) = RegionVars :-
     VarTypes = code_info.get_var_types(CI),
-    RegionVars = set.filter(is_region_var(VarTypes),
+    RegionVars = set_of_var.filter(is_region_var(VarTypes),
         ForwardLiveVarsBeforeGoal).
 
 %---------------------------------------------------------------------------%
@@ -1086,7 +1088,7 @@
     stack.det_top(ResumePointStack, ResumePointInfo),
     pick_first_resume_point(ResumePointInfo, ResumeMap, _),
     map.keys(ResumeMap, ResumeMapVarList),
-    set.list_to_set(ResumeMapVarList, ResumeVars).
+    ResumeVars = set_of_var.list_to_set(ResumeMapVarList).
 
 variable_name(CI, Var) = Name :-
     get_varset(CI, Varset),
@@ -1269,13 +1271,15 @@
 
 :- type position_info
     --->    position_info(
-                code_info_loc_dep   % The location-dependent part of the
-                                    % code_info at a given position.
+                % The location-dependent part of the code_info
+                % at a given position.
+                code_info_loc_dep
             ).
 
 :- type branch_end_info
     --->    branch_end_info(
-                code_info           % The code_info at the end of a branch.
+                % The code_info at the end of a branch.
+                code_info
             ).
 
 :- func pos_get_fail_info(position_info) = fail_info.
@@ -1487,7 +1491,7 @@
     %
 :- type simple_neg_info.
 
-:- pred enter_simple_neg(set(prog_var)::in, hlds_goal_info::in,
+:- pred enter_simple_neg(list(prog_var)::in, hlds_goal_info::in,
     simple_neg_info::out, code_info::in, code_info::out) is det.
 
 :- pred leave_simple_neg(hlds_goal_info::in, simple_neg_info::in,
@@ -1498,13 +1502,13 @@
     % being cut across. If the goal succeeds, the commit will cut away
     % any choice points generated in the goal.
     %
-    % The set(prog_var) should be the set of variables live before
+    % The set_of_progvar should be the set of variables live before
     % the scope goal.
     %
 :- type det_commit_info.
 
 :- pred prepare_for_det_commit(add_trail_ops::in, add_region_ops::in,
-    set(prog_var)::in, hlds_goal_info::in, det_commit_info::out,
+    set_of_progvar::in, hlds_goal_info::in, det_commit_info::out,
     llds_code::out, code_info::in, code_info::out) is det.
 
 :- pred generate_det_commit(det_commit_info::in,
@@ -1521,7 +1525,7 @@
 :- type semi_commit_info.
 
 :- pred prepare_for_semi_commit(add_trail_ops::in, add_region_ops::in,
-    set(prog_var)::in, hlds_goal_info::in, semi_commit_info::out,
+    set_of_progvar::in, hlds_goal_info::in, semi_commit_info::out,
     llds_code::out, code_info::in, code_info::out) is det.
 
 :- pred generate_semi_commit(semi_commit_info::in,
@@ -1581,7 +1585,7 @@
 
     % Materialize the given variables into registers or stack slots.
     %
-:- pred produce_vars(set(prog_var)::in, resume_map::out, llds_code::out,
+:- pred produce_vars(list(prog_var)::in, resume_map::out, llds_code::out,
     code_info::in, code_info::out) is det.
 
     % Put the variables needed in enclosing failure continuations
@@ -1591,8 +1595,10 @@
     code_info::in, code_info::out) is det.
 
     % Set up the resume_point_info structure.
+    % The ResumeVars passed as the first arguments should be a sorted list
+    % without duplicates.
     %
-:- pred make_resume_point(set(prog_var)::in, resume_locs::in, resume_map::in,
+:- pred make_resume_point(list(prog_var)::in, resume_locs::in, resume_map::in,
     resume_point_info::out, code_info::in, code_info::out) is det.
 
     % Generate the code for a resume point.
@@ -1677,14 +1683,18 @@
     ;       disj_temp_frame
     ;       disj_quarter_hijack
     ;       disj_half_hijack(
-                lval        % The stack slot in which we saved
-                            % the value of the hijacked redoip.
+                % The stack slot in which we saved the value
+                % of the hijacked redoip.
+                lval
             )
     ;       disj_full_hijack(
-                lval,       % The stack slot in which we saved
-                            % the value of the hijacked redoip.
-                lval        % The stack slot in which we saved
-                            % the value of the hijacked redofr.
+                % The stack slot in which we saved the value
+                % of the hijacked redoip.
+                lval,
+
+                % The stack slot in which we saved the value
+                % of the hijacked redofr.
+                lval
             ).
 
 prepare_for_disj_hijack(CodeModel, HijackInfo, Code, !CI) :-
@@ -1856,21 +1866,26 @@
 :- type ite_hijack_type
     --->    ite_no_hijack
     ;       ite_temp_frame(
-                lval        % The stack slot in which we saved
-                            % the value of maxfr.
+                % The stack slot in which we saved the value of maxfr.
+                lval
             )
     ;       ite_quarter_hijack
     ;       ite_half_hijack(
-                lval        % The stack slot in which we saved
-                            % the value of the hijacked redoip.
+                % The stack slot in which we saved the value
+                % of the hijacked redoip.
+                lval
             )
     ;       ite_full_hijack(
-                lval,       % The stack slot in which we saved
-                            % the value of the hijacked redoip.
-                lval,       % The stack slot in which we saved
-                            % the value of the hijacked redofr.
-                lval        % The stack slot in which we saved
-                            % the value of maxfr.
+                % The stack slot in which we saved the value
+                % of the hijacked redoip.
+                lval,
+
+                % The stack slot in which we saved the value
+                % of the hijacked redofr.
+                lval,
+
+                % The stack slot in which we saved the value of maxfr.
+                lval
             ).
 
 prepare_for_ite_hijack(CondCodeModel, MaybeEmbeddedFrameId, HijackInfo, Code,
@@ -2096,9 +2111,8 @@
     % Therefore the only part of ResumePoint that matters is the set of
     % variables in the resume map; the other parts of ResumePoint
     % (the locations, the code address) will not be referenced.
-    set.to_sorted_list(ResumeVars, ResumeVarList),
     map.init(ResumeMap0),
-    make_fake_resume_map(ResumeVarList, ResumeMap0, ResumeMap),
+    make_fake_resume_map(ResumeVars, ResumeMap0, ResumeMap),
     ResumePoint = orig_only(ResumeMap, do_redo),
     effect_resume_point(ResumePoint, model_semi, Code, !CI),
     expect(is_empty(Code), $module, $pred, "nonempty code for simple neg"),
@@ -2122,28 +2136,30 @@
 
 :- type det_commit_info
     --->    det_commit_info(
-                maybe(lval),        % Location of saved maxfr.
-                maybe(pair(lval)),  % Location of saved ticket
-                                    % counter and trail pointer.
+                % Location of saved maxfr.
+                maybe(lval),
+
+                % Location of saved ticket % counter and trail pointer.
+                maybe(pair(lval)),
+
                 maybe(region_commit_stack_frame)
             ).
 
 :- type region_commit_stack_frame
     --->    region_commit_stack_frame(
-                embedded_stack_frame_id,
-                                    % The id of the region commit stack frame,
-                                    % which is emdedded in the current
-                                    % procedure's stack frame, and whose
-                                    % layout is:
+                % The id of the region commit stack frame, which is emdedded
+                % in the current procedure's stack frame, and whose layout is:
 
                                     % saved region_commit_stack_pointer
                                     % saved region sequence number
                                     % number of live nonprotected regions
-                                    % space reserved for the ids of live
-                                    %   nonprotected regions
+                % space reserved for the ids of live nonprotected regions
 
-                list(lval)          % The list of temporary slots that
-                                    % constitute this embedded stack frame.
+                embedded_stack_frame_id,
+
+                % The list of temporary slots that constitute
+                % this embedded stack frame.
+                list(lval)
             ).
 
 prepare_for_det_commit(AddTrailOps, AddRegionOps, ForwardLiveVarsBeforeGoal,
@@ -2197,33 +2213,43 @@
 
 :- type semi_commit_info
     --->    semi_commit_info(
-                fail_info,              % Fail_info on entry.
+                % Fail_info on entry.
+                fail_info,
+
                 resume_point_info,
                 commit_hijack_info,
-                maybe(pair(lval)),      % Location of saved ticket
-                                        % counter and trail pointer.
+
+                % Location of saved ticket counter and trail pointer.
+                maybe(pair(lval)),
+
                 maybe(region_commit_stack_frame)
             ).
 
 :- type commit_hijack_info
     --->    commit_temp_frame(
-                lval,       % The stack slot in which we saved
-                            % the old value of maxfr.
-                bool        % Do we bracket the goal with
-                            % MR_commit_mark and MR_commit_cut?
+                % The stack slot in which we saved the old value of maxfr.
+                lval,
+
+                % Do we bracket the goal with MR_commit_mark and MR_commit_cut?
+                bool
             )
     ;       commit_quarter_hijack
     ;       commit_half_hijack(
-                lval        % The stack slot in which we saved
-                            % the value of the hijacked redoip.
+                % The stack slot in which we saved the value
+                % of the hijacked redoip.
+                lval
             )
     ;       commit_full_hijack(
-                lval,       % The stack slot in which we saved
-                            % the value of the hijacked redoip.
-                lval,       % The stack slot in which we saved
-                            % the value of the hijacked redofr.
-                lval        % The stack slot in which we saved
-                            % the value of maxfr.
+                % The stack slot in which we saved the value
+                % of the hijacked redoip.
+                lval,
+
+                % The stack slot in which we saved the value
+                % of the hijacked redofr.
+                lval,
+
+                % The stack slot in which we saved the value of maxfr.
+                lval
             ).
 
 prepare_for_semi_commit(AddTrailOps, AddRegionOps, ForwardLiveVarsBeforeGoal,
@@ -2447,7 +2473,7 @@
 
 %---------------------------------------------------------------------------%
 
-:- pred maybe_save_region_commit_frame(add_region_ops::in, set(prog_var)::in,
+:- pred maybe_save_region_commit_frame(add_region_ops::in, set_of_progvar::in,
     hlds_goal_info::in, maybe(region_commit_stack_frame)::out, llds_code::out,
     code_info::in, code_info::out) is det.
 
@@ -2850,18 +2876,10 @@
 
 %---------------------------------------------------------------------------%
 
-produce_vars(Vars, Map, Code, !CI) :-
-    set.to_sorted_list(Vars, VarList),
-    produce_vars_2(VarList, Map, Code, !CI).
-
-:- pred produce_vars_2(list(prog_var)::in,
-    map(prog_var, set(lval))::out,
-    llds_code::out, code_info::in, code_info::out) is det.
-
-produce_vars_2([], Map, empty, !CI) :-
+produce_vars([], Map, empty, !CI) :-
     map.init(Map).
-produce_vars_2([Var | Vars], Map, Code, !CI) :-
-    produce_vars_2(Vars, Map0, CodeVars, !CI),
+produce_vars([Var | Vars], Map, Code, !CI) :-
+    produce_vars(Vars, Map0, CodeVars, !CI),
     produce_variable_in_reg_or_stack(Var, CodeVar, Lval, !CI),
     set.singleton_set(Lvals, Lval),
     map.set(Var, Lvals, Map0, Map),
@@ -2940,7 +2958,7 @@
 
 make_resume_point(ResumeVars, ResumeLocs, FullMap, ResumePoint, !CI) :-
     get_stack_slots(!.CI, StackSlots),
-    map.select(FullMap, ResumeVars, OrigMap),
+    map.select_sorted_list(FullMap, ResumeVars, OrigMap),
     (
         ResumeLocs = resume_locs_orig_only,
         get_next_label(OrigLabel, !CI),
@@ -3016,11 +3034,11 @@
         )
     ).
 
-:- pred make_stack_resume_map(set(prog_var)::in, stack_slots::in,
+:- pred make_stack_resume_map(list(prog_var)::in, stack_slots::in,
     map(prog_var, set(lval))::out) is det.
 
 make_stack_resume_map(ResumeVars, StackSlots, StackMap) :-
-    map.select(StackSlots, ResumeVars, StackMap0),
+    map.select_sorted_list(StackSlots, ResumeVars, StackMap0),
     map.to_assoc_list(StackMap0, AbsStackList),
     StackList0 = assoc_list.map_values_only(stack_slot_to_lval, AbsStackList),
     make_singleton_sets(StackList0, StackList),
@@ -3271,59 +3289,59 @@
 
 :- interface.
 
-:- pred add_forward_live_vars(set(prog_var)::in,
+:- pred add_forward_live_vars(set_of_progvar::in,
     code_info::in, code_info::out) is det.
 
 :- pred get_known_variables(code_info::in, list(prog_var)::out) is det.
 
 :- pred variable_is_forward_live(code_info::in, prog_var::in) is semidet.
 
-:- pred make_vars_forward_dead(set(prog_var)::in,
+:- pred make_vars_forward_dead(set_of_progvar::in,
     code_info::in, code_info::out) is det.
 
-:- pred maybe_make_vars_forward_dead(set(prog_var)::in, bool::in,
+:- pred maybe_make_vars_forward_dead(set_of_progvar::in, bool::in,
     code_info::in, code_info::out) is det.
 
-:- pred pickup_zombies(set(prog_var)::out,
+:- pred pickup_zombies(set_of_progvar::out,
     code_info::in, code_info::out) is det.
 
 %---------------------------------------------------------------------------%
 
 :- implementation.
 
-:- pred rem_forward_live_vars(set(prog_var)::in,
+:- pred rem_forward_live_vars(set_of_progvar::in,
     code_info::in, code_info::out) is det.
 
     % Make these variables appear magically live.
     % We don't care where they are put.
     %
-:- pred make_vars_forward_live(set(prog_var)::in,
+:- pred make_vars_forward_live(set_of_progvar::in,
     code_info::in, code_info::out) is det.
 
 get_known_variables(CI, VarList) :-
     get_forward_live_vars(CI, ForwardLiveVars),
     ResumeVars = current_resume_point_vars(CI),
-    set.union(ForwardLiveVars, ResumeVars, Vars),
-    set.to_sorted_list(Vars, VarList).
+    set_of_var.union(ForwardLiveVars, ResumeVars, Vars),
+    VarList = set_of_var.to_sorted_list(Vars).
 
 variable_is_forward_live(CI, Var) :-
     get_forward_live_vars(CI, Liveness),
-    set.member(Var, Liveness).
+    set_of_var.member(Liveness, Var).
 
 add_forward_live_vars(Births, !CI) :-
     get_forward_live_vars(!.CI, Liveness0),
-    set.union(Liveness0, Births, Liveness),
+    set_of_var.union(Liveness0, Births, Liveness),
     set_forward_live_vars(Liveness, !CI).
 
 rem_forward_live_vars(Deaths, !CI) :-
     get_forward_live_vars(!.CI, Liveness0),
-    set.difference(Liveness0, Deaths, Liveness),
+    set_of_var.difference(Liveness0, Deaths, Liveness),
     set_forward_live_vars(Liveness, !CI).
 
 make_vars_forward_live(Vars, !CI) :-
     get_stack_slots(!.CI, StackSlots),
     get_var_locn_info(!.CI, VarLocnInfo0),
-    set.to_sorted_list(Vars, VarList),
+    VarList = set_of_var.to_sorted_list(Vars),
     make_vars_forward_live_2(VarList, StackSlots, 1,
         VarLocnInfo0, VarLocnInfo),
     set_var_locn_info(VarLocnInfo, !CI).
@@ -3358,12 +3376,12 @@
 
 maybe_make_vars_forward_dead(Vars0, FirstTime, !CI) :-
     ResumeVars = current_resume_point_vars(!.CI),
-    set.intersect(Vars0, ResumeVars, FlushVars),
+    set_of_var.intersect(Vars0, ResumeVars, FlushVars),
     get_zombies(!.CI, Zombies0),
-    set.union(Zombies0, FlushVars, Zombies),
+    set_of_var.union(Zombies0, FlushVars, Zombies),
     set_zombies(Zombies, !CI),
-    set.difference(Vars0, Zombies, Vars),
-    set.to_sorted_list(Vars, VarList),
+    set_of_var.difference(Vars0, Zombies, Vars),
+    VarList = set_of_var.to_sorted_list(Vars),
     get_var_locn_info(!.CI, VarLocnInfo0),
     maybe_make_vars_forward_dead_2(VarList, FirstTime,
         VarLocnInfo0, VarLocnInfo),
@@ -3379,7 +3397,7 @@
 
 pickup_zombies(Zombies, !CI) :-
     get_zombies(!.CI, Zombies),
-    set_zombies(set.init, !CI).
+    set_zombies(set_of_var.init, !CI).
 
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
@@ -4039,7 +4057,8 @@
         RealStackVarLocs = [],
         DummyStackVarLocs = []
     ;
-        compute_forward_live_var_saves(!.CI, OutVarSet, ForwardVarLocs),
+        compute_forward_live_var_saves(!.CI, set_to_bitset(OutVarSet),
+            ForwardVarLocs),
         CodeModel = goal_info_get_code_model(GoalInfo),
         (
             CodeModel = model_non,
@@ -4112,7 +4131,7 @@
     assoc_list.values(ArgsLocns, LiveLocList),
     set.list_to_set(LiveLocList, LiveLocs),
     assoc_list.keys(ArgsLocns, ArgVars),
-    which_variables_are_forward_live(!.CI, ArgVars, set.init, DeadVars),
+    which_variables_are_forward_live(!.CI, ArgVars, set_of_var.init, DeadVars),
     make_vars_forward_dead(DeadVars, !CI).
 
 :- pred var_arg_info_to_lval(assoc_list(prog_var, arg_info)::in,
@@ -4125,14 +4144,14 @@
     var_arg_info_to_lval(RestInfos, RestLvals).
 
 :- pred which_variables_are_forward_live(code_info::in,
-    list(prog_var)::in, set(prog_var)::in, set(prog_var)::out) is det.
+    list(prog_var)::in, set_of_progvar::in, set_of_progvar::out) is det.
 
 which_variables_are_forward_live(_, [], !DeadVars).
 which_variables_are_forward_live(CI, [Var | Vars], !DeadVars) :-
     ( variable_is_forward_live(CI, Var) ->
         true
     ;
-        set.insert(Var, !DeadVars)
+        set_of_var.insert(Var, !DeadVars)
     ),
     which_variables_are_forward_live(CI, Vars, !DeadVars).
 
@@ -4169,7 +4188,7 @@
     set_var_locn_info(VarLocnInfo, !CI).
 
 save_variables(OutArgs, SavedLocs, Code, !CI) :-
-    compute_forward_live_var_saves(!.CI, OutArgs, VarLocs),
+    compute_forward_live_var_saves(!.CI, set_to_bitset(OutArgs), VarLocs),
     assoc_list.values(VarLocs, SavedLocList),
     set.list_to_set(SavedLocList, SavedLocs),
     place_vars(VarLocs, Code, !CI).
@@ -4179,19 +4198,19 @@
     place_vars(VarLocs, Code, !CI).
 
 :- pred compute_forward_live_var_saves(code_info::in,
-    set(prog_var)::in, assoc_list(prog_var, lval)::out) is det.
+    set_of_progvar::in, assoc_list(prog_var, lval)::out) is det.
 
 compute_forward_live_var_saves(CI, OutArgs, VarLocs) :-
     get_known_variables(CI, Variables0),
-    set.list_to_set(Variables0, Vars0),
+    Vars0 = set_of_var.list_to_set(Variables0),
     TypeInfoLiveness = body_typeinfo_liveness(CI),
     get_proc_info(CI, ProcInfo),
     proc_info_get_vartypes(ProcInfo, VarTypes),
     proc_info_get_rtti_varmaps(ProcInfo, RttiVarMaps),
     maybe_complete_with_typeinfo_vars(Vars0, TypeInfoLiveness, VarTypes,
         RttiVarMaps, Vars1),
-    set.difference(Vars1, OutArgs, Vars),
-    set.to_sorted_list(Vars, Variables),
+    set_of_var.difference(Vars1, OutArgs, Vars),
+    Variables = set_of_var.to_sorted_list(Vars),
     list.map(associate_stack_slot(CI), Variables, VarLocs).
 
 :- pred associate_stack_slot(code_info::in, prog_var::in,
@@ -4679,15 +4698,16 @@
         _VarLocnInfo, TempsInUse, _FailInfo, ParConjDepth),
     ( list.member(cic_forward_live_vars, Components) ->
         io.write_string("forward live vars: ", !IO),
-        mercury_output_vars(VarSet, yes, set.to_sorted_list(ForwardLiveVars),
-            !IO),
+        mercury_output_vars(VarSet, yes,
+            set_of_var.to_sorted_list(ForwardLiveVars), !IO),
         io.nl(!IO)
     ;
         true
     ),
     ( list.member(cic_zombies, Components) ->
         io.write_string("zombies: ", !IO),
-        mercury_output_vars(VarSet, yes, set.to_sorted_list(Zombies), !IO),
+        mercury_output_vars(VarSet, yes,
+            set_of_var.to_sorted_list(Zombies), !IO),
         io.nl(!IO)
     ;
         true
Index: compiler/commit_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/commit_gen.m,v
retrieving revision 1.24
diff -u -b -r1.24 commit_gen.m
--- compiler/commit_gen.m	23 May 2011 05:08:00 -0000	1.24
+++ compiler/commit_gen.m	10 Jul 2011 16:50:52 -0000
@@ -20,14 +20,12 @@
 :- import_module hlds.hlds_goal.
 :- import_module ll_backend.code_info.
 :- import_module ll_backend.llds.
-:- import_module parse_tree.prog_data.
-
-:- import_module set.
+:- import_module parse_tree.set_of_var.
 
 %---------------------------------------------------------------------------%
 
 :- pred generate_scope(scope_reason::in, code_model::in, hlds_goal_info::in,
-    set(prog_var)::in, hlds_goal::in, llds_code::out,
+    set_of_progvar::in, hlds_goal::in, llds_code::out,
     code_info::in, code_info::out) is det.
 
 %---------------------------------------------------------------------------%
@@ -36,6 +34,8 @@
 :- implementation.
 
 :- import_module ll_backend.code_gen.
+% :- import_module parse_tree.prog_data.
+% :- import_module set.
 
 :- import_module cord.
 :- import_module maybe.
@@ -57,7 +57,7 @@
             ForwardLiveVarsBeforeGoal, Goal, Code, !CI)
     ).
 
-:- pred generate_commit(code_model::in, hlds_goal_info::in, set(prog_var)::in,
+:- pred generate_commit(code_model::in, hlds_goal_info::in, set_of_progvar::in,
     hlds_goal::in, llds_code::out, code_info::in, code_info::out) is det.
 
 generate_commit(OuterCodeModel, OuterGoalInfo, ForwardLiveVarsBeforeGoal,
Index: compiler/delay_construct.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/delay_construct.m,v
retrieving revision 1.34
diff -u -b -r1.34 delay_construct.m
--- compiler/delay_construct.m	23 May 2011 05:08:01 -0000	1.34
+++ compiler/delay_construct.m	10 Jul 2011 16:57:43 -0000
@@ -46,6 +46,7 @@
 :- import_module hlds.instmap.
 :- import_module hlds.passes_aux.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module bool.
 :- import_module list.
@@ -218,13 +219,13 @@
         Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
         delay_construct_skippable(GoalExpr0, GoalInfo0),
         NonLocals = goal_info_get_nonlocals(GoalInfo0),
-        maybe_complete_with_typeinfo_vars(NonLocals,
+        maybe_complete_with_typeinfo_vars(set_to_bitset(NonLocals),
             DelayInfo ^ dci_body_typeinfo_liveness,
             DelayInfo ^ dci_vartypes,
             DelayInfo ^ dci_rtti_varmaps, CompletedNonLocals),
-        set.intersect(CompletedNonLocals, ConstructedVars0,
-            Intersection),
-        set.empty(Intersection),
+        set_of_var.intersect(CompletedNonLocals,
+            set_to_bitset(ConstructedVars0), Intersection),
+        set_of_var.is_empty(Intersection),
         goal_info_get_purity(GoalInfo0) = purity_pure
     ->
         delay_construct_in_conj(Goals0, InstMap1, DelayInfo,
Index: compiler/disj_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/disj_gen.m,v
retrieving revision 1.118
diff -u -b -r1.118 disj_gen.m
--- compiler/disj_gen.m	23 May 2011 05:08:01 -0000	1.118
+++ compiler/disj_gen.m	17 Jul 2011 23:17:07 -0000
@@ -48,6 +48,7 @@
 :- import_module ll_backend.lookup_util.
 :- import_module ll_backend.trace_gen.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module bool.
 :- import_module cord.
@@ -81,7 +82,7 @@
             ResumeVars = ResumeVarsPrime
         ;
             Resume = no_resume_point,
-            set.init(ResumeVars)
+            ResumeVars = set_of_var.init
         ),
         AddTrailOps = should_add_trail_ops(!.CI, GoalInfo),
         AddRegionOps = should_add_region_ops(!.CI, GoalInfo),
@@ -104,7 +105,7 @@
 
                 ldi_store_map           :: abs_store_map,
                 ldi_branch_end          :: branch_end,
-                ldi_liveness            :: set(prog_var),
+                ldi_liveness            :: set_of_progvar,
 
                 lds_cur_slot            :: lval,
 
@@ -125,7 +126,7 @@
             ).
 
 :- pred is_lookup_disj(add_trail_ops::in, add_region_ops::in,
-    set(prog_var)::in, list(hlds_goal)::in, hlds_goal_info::in,
+    set_of_progvar::in, list(hlds_goal)::in, hlds_goal_info::in,
     lookup_disj_info::out, code_info::in, code_info::out) is semidet.
 
 is_lookup_disj(AddTrailOps, AddRegionOps, ResumeVars, Disjuncts, DisjGoalInfo,
@@ -156,7 +157,8 @@
     VarTypes = get_var_types(!.CI),
     list.map(map.lookup(VarTypes), OutVars, OutTypes),
 
-    produce_vars(ResumeVars, ResumeMap, FlushCode, !CI),
+    produce_vars(set_of_var.to_sorted_list(ResumeVars), ResumeMap,
+        FlushCode, !CI),
 
     % We cannot release this stack slot anywhere within the disjunction,
     % since it will be needed after backtracking to later disjuncts.
@@ -193,7 +195,7 @@
         SaveHpCode, MaybeHpSlot, HijackInfo, PrepareHijackCode,
         Solns, LLDSTypes).
 
-:- pred generate_lookup_disj(set(prog_var)::in, lookup_disj_info::in,
+:- pred generate_lookup_disj(set_of_progvar::in, lookup_disj_info::in,
     llds_code::out, code_info::in, code_info::out) is det.
 
 generate_lookup_disj(ResumeVars, LookupDisjInfo, Code, !CI) :-
@@ -227,8 +229,8 @@
 
     remember_position(!.CI, DisjEntry),
 
-    make_resume_point(ResumeVars, resume_locs_stack_only,
-        ResumeMap, ResumePoint, !CI),
+    make_resume_point(set_of_var.to_sorted_list(ResumeVars),
+        resume_locs_stack_only, ResumeMap, ResumePoint, !CI),
     effect_resume_point(ResumePoint, model_non, UpdateRedoipCode, !CI),
     generate_offset_assigns(OutVars, 0, BaseReg, !CI),
     flush_resume_vars_to_stack(FirstFlushResumeVarsCode, !CI),
@@ -337,15 +339,16 @@
 %---------------------------------------------------------------------------%
 
 :- pred generate_real_disj(add_trail_ops::in, add_region_ops::in,
-    code_model::in, set(prog_var)::in, list(hlds_goal)::in, hlds_goal_info::in,
-    llds_code::out, code_info::in, code_info::out) is det.
+    code_model::in, set_of_progvar::in, list(hlds_goal)::in,
+    hlds_goal_info::in, llds_code::out, code_info::in, code_info::out) is det.
 
 generate_real_disj(AddTrailOps, AddRegionOps, CodeModel, ResumeVars, Goals,
         DisjGoalInfo, Code, !CI)  :-
     % Make sure that the variables whose values will be needed on backtracking
     % to any disjunct are materialized into registers or stack slots. Their
     % locations are recorded in ResumeMap.
-    produce_vars(ResumeVars, ResumeMap, FlushCode, !CI),
+    produce_vars(set_of_var.to_sorted_list(ResumeVars), ResumeMap,
+        FlushCode, !CI),
 
     % If we are using a trail, save the current trail state before the
     % first disjunct.
@@ -538,8 +541,8 @@
             BranchStart = BranchStart0
         ),
 
-        make_resume_point(ResumeVars, ResumeLocs, FullResumeMap,
-            NextResumePoint, !CI),
+        make_resume_point(set_of_var.to_sorted_list(ResumeVars),
+            ResumeLocs, FullResumeMap, NextResumePoint, !CI),
         effect_resume_point(NextResumePoint, CodeModel, ModContCode, !CI),
 
         maybe_generate_internal_event_code(Goal, DisjGoalInfo, TraceCode, !CI),
@@ -708,7 +711,7 @@
         % at the starts of some later disjuncts (i.e. aren't used only in the
         % first disjunct). We don't yet gather this information.
         SnapshotRegionVars = LiveRegionVars,
-        SnapshotRegionVarList = set.to_sorted_list(SnapshotRegionVars),
+        SnapshotRegionVarList = set_of_var.to_sorted_list(SnapshotRegionVars),
         list.length(SnapshotRegionVarList, NumSnapshotRegionVars),
 
         get_globals(!.CI, Globals),
Index: compiler/graph_colour.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/graph_colour.m,v
retrieving revision 1.22
diff -u -b -r1.22 graph_colour.m
--- compiler/graph_colour.m	23 May 2011 05:08:03 -0000	1.22
+++ compiler/graph_colour.m	10 Jul 2011 22:18:33 -0000
@@ -16,6 +16,12 @@
 % colour, ensuring that touching elements have different colours.
 % ("Good" means using as few colours as possible.)
 % 
+% XXX We do not use this module anymore. Instead, we use set_of_var.m,
+% which uses a more efficient representation of sets of elements. Since that
+% more efficient representation depends on knowing that the elements are
+% variables and therefore in the enum type class, a generic module like this
+% cannot use that representation.
+% 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
Index: compiler/hlds_llds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_llds.m,v
retrieving revision 1.26
diff -u -b -r1.26 hlds_llds.m
--- compiler/hlds_llds.m	23 May 2011 05:08:03 -0000	1.26
+++ compiler/hlds_llds.m	9 Jul 2011 19:50:21 -0000
@@ -20,11 +20,11 @@
 
 :- import_module hlds.hlds_goal.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module bool.
 :- import_module map.
 :- import_module maybe.
-:- import_module set.
 
 :- type stack_slot
     --->    det_slot(int)
@@ -67,7 +67,7 @@
 
     % see compiler/notes/allocation.html for what these alternatives mean
 :- type resume_point
-    --->    resume_point(set(prog_var), resume_locs)
+    --->    resume_point(set_of_progvar, resume_locs)
     ;       no_resume_point.
 
 :- type resume_locs
@@ -94,9 +94,9 @@
 
 :- type need_across_call
     --->    need_across_call(
-                call_forward_vars       :: set(prog_var),
-                call_resume_vars        :: set(prog_var),
-                call_nondet_vars        :: set(prog_var)
+                call_forward_vars       :: set_of_progvar,
+                call_resume_vars        :: set_of_progvar,
+                call_nondet_vars        :: set_of_progvar
             ).
 
     % resume_vars_on_stack is true if the resume point has a stack label.
@@ -110,8 +110,8 @@
 :- type need_in_resume
     --->    need_in_resume(
                 resume_vars_on_stack    :: bool,
-                resume_resume_vars      :: set(prog_var),
-                resume_nondet_vars      :: set(prog_var)
+                resume_resume_vars      :: set_of_progvar,
+                resume_nondet_vars      :: set_of_progvar
             ).
 
     % par_conj_engine_vars gives the set of variables that the execution
@@ -120,7 +120,7 @@
     %
 :- type need_in_par_conj
     --->    need_in_par_conj(
-                par_conj_engine_vars    :: set(prog_var)
+                par_conj_engine_vars    :: set_of_progvar
             ).
 
 :- type llds_code_gen_details.
@@ -135,16 +135,16 @@
 % both the pre-death and pre-birth sets.
 
 :- pred goal_info_get_pre_births(hlds_goal_info::in,
-    set(prog_var)::out) is det.
+    set_of_progvar::out) is det.
 
 :- pred goal_info_get_post_births(hlds_goal_info::in,
-    set(prog_var)::out) is det.
+    set_of_progvar::out) is det.
 
 :- pred goal_info_get_pre_deaths(hlds_goal_info::in,
-    set(prog_var)::out) is det.
+    set_of_progvar::out) is det.
 
 :- pred goal_info_get_post_deaths(hlds_goal_info::in,
-    set(prog_var)::out) is det.
+    set_of_progvar::out) is det.
 
 :- pred goal_info_get_follow_vars(hlds_goal_info::in,
     maybe(abs_follow_vars)::out) is det.
@@ -167,16 +167,16 @@
 %-----------------------------------------------------------------------------%
 
 :- pred goal_info_maybe_get_pre_births(hlds_goal_info::in,
-    set(prog_var)::out) is semidet.
+    set_of_progvar::out) is semidet.
 
 :- pred goal_info_maybe_get_post_births(hlds_goal_info::in,
-    set(prog_var)::out) is semidet.
+    set_of_progvar::out) is semidet.
 
 :- pred goal_info_maybe_get_pre_deaths(hlds_goal_info::in,
-    set(prog_var)::out) is semidet.
+    set_of_progvar::out) is semidet.
 
 :- pred goal_info_maybe_get_post_deaths(hlds_goal_info::in,
-    set(prog_var)::out) is semidet.
+    set_of_progvar::out) is semidet.
 
 :- pred goal_info_maybe_get_follow_vars(hlds_goal_info::in,
     maybe(abs_follow_vars)::out) is semidet.
@@ -201,23 +201,23 @@
     % goal_info_initialize_liveness_info(PreBirths, PostBirths,
     %   PreDeaths, PostDeaths, ResumePoint, !GoalInfo):
     % Updates !GoalInfo by overwriting the previous values of its
-    % pre_births, post_births, pre_deaths, post_deaths and resume_point
-    % fields.
+    % pre_births, post_births, pre_deaths, post_deaths and resume_point fields.
     %
 :- pred goal_info_initialize_liveness_info(
-    set(prog_var)::in, set(prog_var)::in, set(prog_var)::in, set(prog_var)::in,
+    set_of_progvar::in, set_of_progvar::in,
+    set_of_progvar::in, set_of_progvar::in,
     resume_point::in, hlds_goal_info::in, hlds_goal_info::out) is det.
 
-:- pred goal_info_set_pre_births(set(prog_var)::in,
+:- pred goal_info_set_pre_births(set_of_progvar::in,
     hlds_goal_info::in, hlds_goal_info::out) is det.
 
-:- pred goal_info_set_post_births(set(prog_var)::in,
+:- pred goal_info_set_post_births(set_of_progvar::in,
     hlds_goal_info::in, hlds_goal_info::out) is det.
 
-:- pred goal_info_set_pre_deaths(set(prog_var)::in,
+:- pred goal_info_set_pre_deaths(set_of_progvar::in,
     hlds_goal_info::in, hlds_goal_info::out) is det.
 
-:- pred goal_info_set_post_deaths(set(prog_var)::in,
+:- pred goal_info_set_post_deaths(set_of_progvar::in,
     hlds_goal_info::in, hlds_goal_info::out) is det.
 
 :- pred goal_info_set_follow_vars(maybe(abs_follow_vars)::in,
@@ -247,7 +247,7 @@
     hlds_goal::in, hlds_goal::out) is det.
 
 :- pred goal_info_resume_vars_and_loc(resume_point::in,
-    set(prog_var)::out, resume_locs::out) is det.
+    set_of_progvar::out, resume_locs::out) is det.
 
 %-----------------------------------------------------------------------------%
 
@@ -328,10 +328,10 @@
                 % All four of these fields are computed by liveness.m.
                 % For atomic goals, the post-deadness should be applied
                 % _before_ the goal.
-                pre_births          :: set(prog_var),
-                post_births         :: set(prog_var),
-                pre_deaths          :: set(prog_var),
-                post_deaths         :: set(prog_var),
+                pre_births          :: set_of_progvar,
+                post_births         :: set_of_progvar,
+                pre_deaths          :: set_of_progvar,
+                post_deaths         :: set_of_progvar,
 
                 % Initially set to `no' for all goals, which means the absence
                 % of the advisory information. Can be set to `yes' by the
@@ -660,7 +660,8 @@
 :- func init_llds_code_gen_details = llds_code_gen_details.
 
 init_llds_code_gen_details =
-    llds_code_gen_details(set.init, set.init, set.init, set.init,
+    llds_code_gen_details(set_of_var.init, set_of_var.init,
+        set_of_var.init, set_of_var.init,
         no, map.init, no_resume_point, no_need).
 
 %-----------------------------------------------------------------------------%
@@ -669,10 +670,10 @@
     Details0 = llds_code_gen_details(PreBirths0, PostBirths0,
         PreDeaths0, PostDeaths0, MaybeFollowVars0, StoreMap0,
         ResumePoint0, MaybeNeed0),
-    rename_vars_in_var_set(Must, Subn, PreBirths0, PreBirths),
-    rename_vars_in_var_set(Must, Subn, PostBirths0, PostBirths),
-    rename_vars_in_var_set(Must, Subn, PreDeaths0, PreDeaths),
-    rename_vars_in_var_set(Must, Subn, PostDeaths0, PostDeaths),
+    rename_vars_in_set_of_var(Must, Subn, PreBirths0, PreBirths),
+    rename_vars_in_set_of_var(Must, Subn, PostBirths0, PostBirths),
+    rename_vars_in_set_of_var(Must, Subn, PreDeaths0, PreDeaths),
+    rename_vars_in_set_of_var(Must, Subn, PostDeaths0, PostDeaths),
     (
         MaybeFollowVars0 = no,
         MaybeFollowVars = no
@@ -690,7 +691,8 @@
         ResumePoint = no_resume_point
     ;
         ResumePoint0 = resume_point(ResumePointVars0, ResumeLocs),
-        rename_vars_in_var_set(Must, Subn, ResumePointVars0, ResumePointVars),
+        rename_vars_in_set_of_var(Must, Subn,
+            ResumePointVars0, ResumePointVars),
         ResumePoint = resume_point(ResumePointVars, ResumeLocs)
     ),
     (
@@ -700,9 +702,9 @@
         MaybeNeed0 = need_call(NeedAcrossCall0),
         NeedAcrossCall0 = need_across_call(ForwardVars0,
             CallResumeVars0, CallNondetLiveVars0),
-        rename_vars_in_var_set(Must, Subn, ForwardVars0, ForwardVars),
-        rename_vars_in_var_set(Must, Subn, CallResumeVars0, CallResumeVars),
-        rename_vars_in_var_set(Must, Subn,
+        rename_vars_in_set_of_var(Must, Subn, ForwardVars0, ForwardVars),
+        rename_vars_in_set_of_var(Must, Subn, CallResumeVars0, CallResumeVars),
+        rename_vars_in_set_of_var(Must, Subn,
             CallNondetLiveVars0, CallNondetLiveVars),
         NeedAcrossCall = need_across_call(ForwardVars,
             CallResumeVars, CallNondetLiveVars),
@@ -710,14 +712,14 @@
     ;
         MaybeNeed0 = need_resume(NeedInResume0),
         NeedInResume0 = need_in_resume(OnStack, ResumeVars0, NondetLiveVars0),
-        rename_vars_in_var_set(Must, Subn, ResumeVars0, ResumeVars),
-        rename_vars_in_var_set(Must, Subn, NondetLiveVars0, NondetLiveVars),
+        rename_vars_in_set_of_var(Must, Subn, ResumeVars0, ResumeVars),
+        rename_vars_in_set_of_var(Must, Subn, NondetLiveVars0, NondetLiveVars),
         NeedInResume = need_in_resume(OnStack, ResumeVars, NondetLiveVars),
         MaybeNeed = need_resume(NeedInResume)
     ;
         MaybeNeed0 = need_par_conj(NeedInParConj0),
         NeedInParConj0 = need_in_par_conj(ParConjVars0),
-        rename_vars_in_var_set(Must, Subn, ParConjVars0, ParConjVars),
+        rename_vars_in_set_of_var(Must, Subn, ParConjVars0, ParConjVars),
         NeedInParConj = need_in_par_conj(ParConjVars),
         MaybeNeed = need_par_conj(NeedInParConj)
     ),
@@ -725,6 +727,15 @@
         PreDeaths, PostDeaths, MaybeFollowVars, StoreMap,
         ResumePoint, MaybeNeed).
 
+:- pred rename_vars_in_set_of_var(must_rename::in,
+    map(prog_var, prog_var)::in,
+    set_of_progvar::in, set_of_progvar::out) is det.
+
+rename_vars_in_set_of_var(Must, Subn, Set0, Set) :-
+    List0 = set_of_var.to_sorted_list(Set0),
+    list.map(rename_var(Must, Subn), List0, List),
+    Set = set_of_var.list_to_set(List).
+
 :- pred rename_vars_in_var_locn_map(must_rename::in,
     map(prog_var, prog_var)::in,
     map(prog_var, abs_locn)::in, map(prog_var, abs_locn)::out) is det.
Index: compiler/hlds_out_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out_goal.m,v
retrieving revision 1.7
diff -u -b -r1.7 hlds_out_goal.m
--- compiler/hlds_out_goal.m	23 May 2011 05:08:03 -0000	1.7
+++ compiler/hlds_out_goal.m	9 Jul 2011 19:59:54 -0000
@@ -131,6 +131,7 @@
 :- import_module parse_tree.prog_out.
 :- import_module parse_tree.prog_type.
 :- import_module parse_tree.prog_util.
+:- import_module parse_tree.set_of_var.
 
 :- import_module int.
 :- import_module map.
@@ -214,7 +215,7 @@
     ( string.contains_char(DumpOptions, 'p') ->
         (
             goal_info_maybe_get_pre_deaths(GoalInfo, PreDeaths),
-            set.to_sorted_list(PreDeaths, PreDeathList),
+            PreDeathList = set_of_var.to_sorted_list(PreDeaths),
             PreDeathList = [_ | _]
         ->
             write_indent(Indent, !IO),
@@ -226,7 +227,7 @@
         ),
         (
             goal_info_maybe_get_pre_births(GoalInfo, PreBirths),
-            set.to_sorted_list(PreBirths, PreBirthList),
+            PreBirthList = set_of_var.to_sorted_list(PreBirths),
             PreBirthList = [_ | _]
         ->
             write_indent(Indent, !IO),
@@ -417,7 +418,7 @@
     ( string.contains_char(DumpOptions, 'p') ->
         (
             goal_info_maybe_get_post_deaths(GoalInfo, PostDeaths),
-            set.to_sorted_list(PostDeaths, PostDeathList),
+            PostDeathList = set_of_var.to_sorted_list(PostDeaths),
             PostDeathList = [_ | _]
         ->
             write_indent(Indent, !IO),
@@ -429,7 +430,7 @@
         ),
         (
             goal_info_maybe_get_post_births(GoalInfo, PostBirths),
-            set.to_sorted_list(PostBirths, PostBirthList),
+            PostBirthList = set_of_var.to_sorted_list(PostBirths),
             PostBirthList = [_ | _]
         ->
             write_indent(Indent, !IO),
@@ -544,7 +545,7 @@
             Resume = no_resume_point
         ;
             Resume = resume_point(ResumeVars, Locs),
-            set.to_sorted_list(ResumeVars, ResumeVarList),
+            ResumeVarList = set_of_var.to_sorted_list(ResumeVars),
             write_indent(Indent, !IO),
             io.write_string("% resume point ", !IO),
             (
@@ -586,9 +587,9 @@
     ->
         NeedAcrossCall = need_across_call(CallForwardSet, CallResumeSet,
             CallNondetSet),
-        set.to_sorted_list(CallForwardSet, CallForwardList),
-        set.to_sorted_list(CallResumeSet, CallResumeList),
-        set.to_sorted_list(CallNondetSet, CallNondetList),
+        CallForwardList = set_of_var.to_sorted_list(CallForwardSet),
+        CallResumeList = set_of_var.to_sorted_list(CallResumeSet),
+        CallNondetList = set_of_var.to_sorted_list(CallNondetSet),
         write_indent(Indent, !IO),
         io.write_string("% need across call forward vars: ", !IO),
         (
@@ -631,8 +632,8 @@
     ->
         NeedInResume = need_in_resume(ResumeOnStack, ResumeResumeSet,
             ResumeNondetSet),
-        set.to_sorted_list(ResumeResumeSet, ResumeResumeList),
-        set.to_sorted_list(ResumeNondetSet, ResumeNondetList),
+        ResumeResumeList = set_of_var.to_sorted_list(ResumeResumeSet),
+        ResumeNondetList = set_of_var.to_sorted_list(ResumeNondetSet),
 
         write_indent(Indent, !IO),
         (
@@ -672,7 +673,7 @@
         MaybeNeedInParConj = yes(NeedInParConj)
     ->
         NeedInParConj = need_in_par_conj(ParConjSet),
-        set.to_sorted_list(ParConjSet, ParConjList),
+        ParConjList = set_of_var.to_sorted_list(ParConjSet),
         write_indent(Indent, !IO),
         io.write_string("% need in par_conj vars: ", !IO),
         write_vars(VarSet, AppendVarNums, ParConjList, !IO),
Index: compiler/hlds_rtti.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_rtti.m,v
retrieving revision 1.25
diff -u -b -r1.25 hlds_rtti.m
--- compiler/hlds_rtti.m	23 May 2011 05:08:03 -0000	1.25
+++ compiler/hlds_rtti.m	9 Jul 2011 20:27:56 -0000
@@ -21,12 +21,12 @@
 :- import_module hlds.hlds_pred.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module array.
 :- import_module assoc_list.
 :- import_module bool.
 :- import_module list.
-:- import_module set.
 
 %-----------------------------------------------------------------------------%
 
@@ -320,11 +320,11 @@
     % for accurate garbage collection - live variables need to have
     % their typeinfos stay live too.
     %
-:- pred get_typeinfo_vars(set(prog_var)::in, vartypes::in, rtti_varmaps::in,
-    set(prog_var)::out) is det.
+:- pred get_typeinfo_vars(set_of_progvar::in, vartypes::in, rtti_varmaps::in,
+    set_of_progvar::out) is det.
 
-:- pred maybe_complete_with_typeinfo_vars(set(prog_var)::in,
-    bool::in, vartypes::in, rtti_varmaps::in, set(prog_var)::out) is det.
+:- pred maybe_complete_with_typeinfo_vars(set_of_progvar::in,
+    bool::in, vartypes::in, rtti_varmaps::in, set_of_progvar::out) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -859,9 +859,9 @@
 
 get_typeinfo_vars(Vars, VarTypes, RttiVarMaps, TypeInfoVars) :-
     TVarMap = RttiVarMaps ^ rv_ti_varmap,
-    set.to_sorted_list(Vars, VarList),
+    VarList = set_of_var.to_sorted_list(Vars),
     get_typeinfo_vars_2(VarList, VarTypes, TVarMap, TypeInfoVarList),
-    set.list_to_set(TypeInfoVarList, TypeInfoVars).
+    TypeInfoVars = set_of_var.list_to_set(TypeInfoVarList).
 
     % Auxiliary predicate - traverses variables and builds a list of
     % variables that store typeinfos for these variables.
@@ -900,7 +900,7 @@
     (
         TypeInfoLiveness = yes,
         get_typeinfo_vars(Vars0, VarTypes, RttiVarMaps, TypeInfoVars),
-        set.union(Vars0, TypeInfoVars, Vars)
+        set_of_var.union(Vars0, TypeInfoVars, Vars)
     ;
         TypeInfoLiveness = no,
         Vars = Vars0
Index: compiler/interval.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/interval.m,v
retrieving revision 1.51
diff -u -b -r1.51 interval.m
--- compiler/interval.m	23 May 2011 05:08:04 -0000	1.51
+++ compiler/interval.m	9 Jul 2011 23:06:25 -0000
@@ -39,6 +39,7 @@
 :- import_module mdbcomp.goal_path.
 :- import_module parse_tree.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module bool.
 :- import_module counter.
@@ -84,22 +85,22 @@
 
 :- type branch_end_info
     --->    branch_end_info(
-                flushed_after_branch    :: set(prog_var),
-                accessed_after_branch   :: set(prog_var),
+                flushed_after_branch    :: set_of_progvar,
+                accessed_after_branch   :: set_of_progvar,
                 interval_after_branch   :: interval_id
             ).
 
 :- type insert_spec
     --->    insert_spec(
                 hlds_goal,
-                set(prog_var)
+                set_of_progvar
             ).
 
 :- type insert_map      ==  map(anchor, list(insert_spec)).
 
 :- type anchor_follow_info
     --->    anchor_follow_info(
-                set(prog_var),
+                set_of_progvar,
                 set(interval_id)
             ).
 
@@ -113,8 +114,8 @@
 :- type interval_info
     --->    interval_info(
                 ii_interval_params      :: interval_params,
-                ii_flushed_later        :: set(prog_var),
-                ii_accessed_later       :: set(prog_var),
+                ii_flushed_later        :: set_of_progvar,
+                ii_accessed_later       :: set_of_progvar,
                 ii_branch_resume_map    :: map(goal_id, resume_save_status),
                 ii_branch_end_map       :: map(goal_id, branch_end_info),
                 ii_cond_end_map         :: map(goal_id, interval_id),
@@ -126,8 +127,9 @@
                 ii_interval_start       :: map(interval_id, anchor),
                 ii_interval_end         :: map(interval_id, anchor),
                 ii_interval_succ        :: map(interval_id, list(interval_id)),
-                ii_interval_vars        :: map(interval_id, set(prog_var)),
-                ii_interval_delvars     :: map(interval_id, list(set(prog_var)))
+                ii_interval_vars        :: map(interval_id, set_of_progvar),
+                ii_interval_delvars     :: map(interval_id,
+                                            list(set_of_progvar))
             ).
 
 :- type maybe_needs_flush
@@ -146,8 +148,8 @@
 :- pred record_interval_vars(interval_id::in, list(prog_var)::in,
     interval_info::in, interval_info::out) is det.
 
-:- pred delete_interval_vars(interval_id::in, set(prog_var)::in,
-    set(prog_var)::out, interval_info::in, interval_info::out) is det.
+:- pred delete_interval_vars(interval_id::in, set_of_progvar::in,
+    set_of_progvar::out, interval_info::in, interval_info::out) is det.
 
 :- type rename_map  ==  map(prog_var, prog_var).
 
@@ -170,7 +172,7 @@
     % body. The resulting procedure definition will be isomorphic to the one
     % we would have get by applying the original renaming to the headvars.
     %
-:- pred apply_headvar_correction(set(prog_var)::in, rename_map::in,
+:- pred apply_headvar_correction(set_of_progvar::in, rename_map::in,
     hlds_goal::in, hlds_goal::out) is det.
 
 :- pred dump_interval_info(interval_info::in, io::di, io::uo) is det.
@@ -435,7 +437,7 @@
         MaybeNeedAcrossCall = yes(NeedAcrossCall),
         NeedAcrossCall = need_across_call(ForwardVars, ResumeVars,
             NondetLiveVars),
-        VarsOnStack0 = set.union_list([ForwardVars, ResumeVars,
+        VarsOnStack0 = set_of_var.union_list([ForwardVars, ResumeVars,
             NondetLiveVars]),
         GoalId = goal_info_get_goal_id(GoalInfo),
         CallAnchor = anchor_call_site(GoalId),
@@ -456,7 +458,7 @@
             % If the call cannot succeed, then execution cannot
             % get from BeforeCallId to AfterCallId.
             record_interval_no_succ(BeforeCallId, !IntervalInfo),
-            VarsOnStack = set.init
+            VarsOnStack = set_of_var.init
         ),
         set_cur_interval(BeforeCallId, !IntervalInfo),
         assign_open_intervals_to_anchor(CallAnchor, !IntervalInfo),
@@ -531,7 +533,7 @@
 
 :- pred reached_branch_end(hlds_goal_info::in, maybe(hlds_goal)::in,
     branch_construct::in, anchor::out, anchor::out,
-    interval_id::out, interval_id::out, maybe(set(prog_var))::out,
+    interval_id::out, interval_id::out, maybe(set_of_progvar)::out,
     interval_info::in, interval_info::out, T::in, T::out) is det
     <= build_interval_info_acc(T).
 
@@ -555,7 +557,7 @@
     record_branch_resume(GoalId, HasResumeSave, !IntervalInfo),
     ( goal_info_maybe_get_store_map(GoalInfo, StoreMap) ->
         map.sorted_keys(StoreMap, StoreMapVarList),
-        set.sorted_list_to_set(StoreMapVarList, StoreMapVars),
+        StoreMapVars = set_of_var.sorted_list_to_set(StoreMapVarList),
         require_flushed(StoreMapVars, !IntervalInfo)
     ;
         unexpected($module, $pred, "no store map")
@@ -622,7 +624,7 @@
     set_open_intervals(OpenIntervals, !IntervalInfo).
 
 :- pred leave_branch_start(branch_construct::in, anchor::in, interval_id::in,
-    maybe(set(prog_var))::in, set(interval_id)::in,
+    maybe(set_of_progvar)::in, set(interval_id)::in,
     interval_info::in, interval_info::out) is det.
 
 leave_branch_start(_BranchConstruct, StartArchor, BeforeId, MaybeResumeVars,
@@ -667,11 +669,12 @@
     IntervalVarMap = !.IntervalInfo ^ ii_interval_vars,
     CurOpenIntervals = !.IntervalInfo ^ ii_open_intervals,
     set.fold(gather_interval_vars(IntervalVarMap), CurOpenIntervals,
-        set.init, CurOpenIntervalVars),
+        set_of_var.init, CurOpenIntervalVars),
     ( map.search(AnchorFollowMap0, Anchor, AnchorFollowInfo0) ->
         AnchorFollowInfo0 =
             anchor_follow_info(OpenIntervalVars0, OpenIntervals0),
-        OpenIntervalVars = set.union(OpenIntervalVars0, CurOpenIntervalVars),
+        OpenIntervalVars =
+            set_of_var.union(OpenIntervalVars0, CurOpenIntervalVars),
         OpenIntervals = set.union(OpenIntervals0, CurOpenIntervals),
         AnchorFollowInfo =
             anchor_follow_info(OpenIntervalVars, OpenIntervals),
@@ -685,12 +688,12 @@
     ),
     !IntervalInfo ^ ii_anchor_follow_map := AnchorFollowMap.
 
-:- pred gather_interval_vars(map(interval_id, set(prog_var))::in,
-    interval_id::in, set(prog_var)::in, set(prog_var)::out) is det.
+:- pred gather_interval_vars(map(interval_id, set_of_progvar)::in,
+    interval_id::in, set_of_progvar::in, set_of_progvar::out) is det.
 
 gather_interval_vars(IntervalVarMap, IntervalId, !OpenIntervalVars) :-
     map.lookup(IntervalVarMap, IntervalId, IntervalVars),
-    !:OpenIntervalVars = set.union(!.OpenIntervalVars, IntervalVars).
+    !:OpenIntervalVars = set_of_var.union(!.OpenIntervalVars, IntervalVars).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -713,7 +716,7 @@
     IntervalVars0 = !.IntervalInfo ^ ii_interval_vars,
     counter.allocate(Num, Counter0, Counter),
     Id = interval_id(Num),
-    map.det_insert(Id, set.init, IntervalVars0, IntervalVars),
+    map.det_insert(Id, set_of_var.init, IntervalVars0, IntervalVars),
     !IntervalInfo ^ ii_interval_counter := Counter,
     !IntervalInfo ^ ii_interval_vars := IntervalVars.
 
@@ -781,10 +784,10 @@
 record_interval_vars(Id, NewVars, !IntervalInfo) :-
     VarsMap0 = !.IntervalInfo ^ ii_interval_vars,
     ( map.search(VarsMap0, Id, Vars0) ->
-        set.insert_list(NewVars, Vars0, Vars),
+        set_of_var.insert_list(NewVars, Vars0, Vars),
         map.det_update(Id, Vars, VarsMap0, VarsMap)
     ;
-        set.list_to_set(NewVars, Vars),
+        Vars = set_of_var.list_to_set(NewVars),
         map.det_insert(Id, Vars, VarsMap0, VarsMap)
     ),
     !IntervalInfo ^ ii_interval_vars := VarsMap.
@@ -792,8 +795,8 @@
 delete_interval_vars(Id, ToDeleteVars, DeletedVars, !IntervalInfo) :-
     VarsMap0 = !.IntervalInfo ^ ii_interval_vars,
     map.lookup(VarsMap0, Id, Vars0),
-    DeletedVars = set.intersect(Vars0, ToDeleteVars),
-    Vars = set.difference(Vars0, DeletedVars),
+    DeletedVars = set_of_var.intersect(Vars0, ToDeleteVars),
+    Vars = set_of_var.difference(Vars0, DeletedVars),
     map.det_update(Id, Vars, VarsMap0, VarsMap),
     !IntervalInfo ^ ii_interval_vars := VarsMap,
 
@@ -816,12 +819,12 @@
     CurIntervalId = !.IntervalInfo ^ ii_cur_interval,
     record_interval_vars(CurIntervalId, Vars, !IntervalInfo).
 
-:- pred require_flushed(set(prog_var)::in,
+:- pred require_flushed(set_of_progvar::in,
     interval_info::in, interval_info::out) is det.
 
 require_flushed(Vars, !IntervalInfo) :-
     FlushedLater0 = !.IntervalInfo ^ ii_flushed_later,
-    FlushedLater = set.union(FlushedLater0, Vars),
+    FlushedLater = set_of_var.union(FlushedLater0, Vars),
     !IntervalInfo ^ ii_flushed_later := FlushedLater.
 
 :- pred require_access(list(prog_var)::in,
@@ -829,7 +832,7 @@
 
 require_access(Vars, !IntervalInfo) :-
     AccessedLater0 = !.IntervalInfo ^ ii_accessed_later,
-    set.insert_list(Vars, AccessedLater0, AccessedLater),
+    set_of_var.insert_list(Vars, AccessedLater0, AccessedLater),
     !IntervalInfo ^ ii_accessed_later := AccessedLater.
 
 :- pred record_branch_resume(goal_id::in, resume_save_status::in,
@@ -1083,7 +1086,7 @@
         MaybeFeature, Goal),
     Info = interval_var_info(VarSet, VarTypes).
 
-:- pred create_shadow_vars(list(prog_var)::in, set(prog_var)::in,
+:- pred create_shadow_vars(list(prog_var)::in, set_of_progvar::in,
     prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
     rename_map::in, rename_map::out, rename_map::in, rename_map::out)
     is det.
@@ -1096,7 +1099,7 @@
     create_shadow_vars(Args, VarsToExtract, !VarSet, !VarTypes,
         !VarRename, !VoidRename).
 
-:- pred create_shadow_var(prog_var::in, set(prog_var)::in,
+:- pred create_shadow_var(prog_var::in, set_of_progvar::in,
     prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
     rename_map::in, rename_map::out, rename_map::in, rename_map::out) is det.
 
@@ -1106,7 +1109,7 @@
     varset.new_named_var(Name, Shadow, !VarSet),
     map.lookup(!.VarTypes, Arg, Type),
     map.det_insert(Shadow, Type, !VarTypes),
-    ( set.member(Arg, VarsToExtract) ->
+    ( set_of_var.member(VarsToExtract, Arg) ->
         map.det_insert(Arg, Shadow, !VarRename)
     ;
         map.det_insert(Arg, Shadow, !VoidRename)
@@ -1200,7 +1203,7 @@
 %-----------------------------------------------------------------------------%
 
 apply_headvar_correction(HeadVarSet, RenameMap, Goal0, Goal) :-
-    set.to_sorted_list(HeadVarSet, HeadVars),
+    HeadVars = set_of_var.to_sorted_list(HeadVarSet),
     build_headvar_subst(HeadVars, RenameMap, map.init, Subst),
     ( map.is_empty(Subst) ->
         Goal = Goal0
@@ -1280,7 +1283,7 @@
         io.write_string("no end\n", !IO)
     ),
     ( map.search(IntervalInfo ^ ii_interval_vars, IntervalId, Vars) ->
-        list.map(term.var_to_int, set.to_sorted_list(Vars), VarNums),
+        list.map(term.var_to_int, set_of_var.to_sorted_list(Vars), VarNums),
         io.write_string("vars [", !IO),
         write_int_list(VarNums, !IO),
         io.write_string("]\n", !IO)
@@ -1295,10 +1298,10 @@
         true
     ).
 
-:- pred dump_deletion(set(prog_var)::in, io::di, io::uo) is det.
+:- pred dump_deletion(set_of_progvar::in, io::di, io::uo) is det.
 
 dump_deletion(Vars, !IO) :-
-    list.map(term.var_to_int, set.to_sorted_list(Vars), VarNums),
+    list.map(term.var_to_int, set_of_var.to_sorted_list(Vars), VarNums),
     io.write_string(" [", !IO),
     write_int_list(VarNums, !IO),
     io.write_string("]", !IO).
@@ -1311,7 +1314,7 @@
     io.write_string("\n", !IO),
     io.write(Anchor, !IO),
     io.write_string(" =>\n", !IO),
-    list.map(term.var_to_int, set.to_sorted_list(Vars), VarNums),
+    list.map(term.var_to_int, set_of_var.to_sorted_list(Vars), VarNums),
     io.write_string("vars [", !IO),
     write_int_list(VarNums, !IO),
     io.write_string("]\nintervals: ", !IO),
Index: compiler/ite_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ite_gen.m,v
retrieving revision 1.113
diff -u -b -r1.113 ite_gen.m
--- compiler/ite_gen.m	23 May 2011 05:08:04 -0000	1.113
+++ compiler/ite_gen.m	17 Jul 2011 23:17:33 -0000
@@ -51,6 +51,7 @@
 :- import_module ll_backend.trace_gen.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 :- import_module transform_hlds.
 :- import_module transform_hlds.rbmm.
 :- import_module transform_hlds.rbmm.region_transformation.
@@ -101,7 +102,8 @@
     % Make sure that the variables whose values will be needed on backtracking
     % to the else part are materialized into registers or stack slots.
     % Their locations are recorded in ResumeMap.
-    produce_vars(ResumeVars, ResumeMap, FlushCode, !CI),
+    produce_vars(set_of_var.to_sorted_list(ResumeVars), ResumeMap,
+        FlushCode, !CI),
 
     % Maybe save the heap state current before the condition.
     % This is after produce_vars since code that flushes the cache
@@ -155,7 +157,8 @@
     prepare_for_ite_hijack(CondCodeModel, MaybeEmbeddedStackFrameId,
         HijackInfo, PrepareHijackCode, !CI),
 
-    make_resume_point(ResumeVars, ResumeLocs, ResumeMap, ResumePoint, !CI),
+    make_resume_point(set_of_var.to_sorted_list(ResumeVars),
+        ResumeLocs, ResumeMap, ResumePoint, !CI),
     effect_resume_point(ResumePoint, EffCodeModel, EffectResumeCode, !CI),
 
     % Generate the condition.
@@ -324,7 +327,8 @@
         % apply the pre- and post-goal updates that would normally be applied
         % by code_gen.generate_goal.
 
-        enter_simple_neg(ResumeVars, GoalInfo, SimpleNeg, !CI),
+        enter_simple_neg(set_of_var.to_sorted_list(ResumeVars), GoalInfo,
+            SimpleNeg, !CI),
         produce_variable(L, CodeL, ValL, !CI),
         produce_variable(R, CodeR, ValR, !CI),
         Type = variable_type(!.CI, L),
@@ -350,12 +354,13 @@
     % of the code for if-then-elses.
     %
 :- pred generate_negation_general(code_model::in,
-    hlds_goal::in, hlds_goal_info::in, set(prog_var)::in,
+    hlds_goal::in, hlds_goal_info::in, set_of_progvar::in,
     resume_locs::in, llds_code::out, code_info::in, code_info::out) is det.
 
 generate_negation_general(CodeModel, Goal, NotGoalInfo, ResumeVars, ResumeLocs,
         Code, !CI) :-
-    produce_vars(ResumeVars, ResumeMap, FlushCode, !CI),
+    produce_vars(set_of_var.to_sorted_list(ResumeVars), ResumeMap,
+        FlushCode, !CI),
 
     % Maybe save the heap state current before the condition; this ought to be
     % after we make the failure continuation because that causes the cache to
@@ -394,7 +399,8 @@
     prepare_for_ite_hijack(CodeModel, MaybeRegionSuccRecordSlot, HijackInfo,
         PrepareHijackCode, !CI),
 
-    make_resume_point(ResumeVars, ResumeLocs, ResumeMap, ResumePoint, !CI),
+    make_resume_point(set_of_var.to_sorted_list(ResumeVars),
+        ResumeLocs, ResumeMap, ResumePoint, !CI),
     effect_resume_point(ResumePoint, CodeModel, EffectResumeCode, !CI),
 
     % Generate the negated goal as a semi-deterministic goal; it cannot be
@@ -620,15 +626,17 @@
                 UnprotectedRemovedAtStartOfElse = set.intersect(
                     RemovedAtStartOfElse, CondCarriedRegionVars),
 
-                ProtectRegionVars = set.intersect(LiveRegionVars,
-                    NeedToBeProtectedRegionVars),
-                SnapshotRegionVars0 = set.intersect(LiveRegionVars,
-                    CondAllocRegionVars),
-                SnapshotRegionVars = set.difference(SnapshotRegionVars0,
-                    UnprotectedRemovedAtStartOfElse),
-
-                ProtectRegionVarList = set.to_sorted_list(ProtectRegionVars),
-                SnapshotRegionVarList = set.to_sorted_list(SnapshotRegionVars),
+                ProtectRegionVars = set_of_var.intersect(LiveRegionVars,
+                    set_to_bitset(NeedToBeProtectedRegionVars)),
+                SnapshotRegionVars0 = set_of_var.intersect(LiveRegionVars,
+                    set_to_bitset(CondAllocRegionVars)),
+                SnapshotRegionVars = set_of_var.difference(SnapshotRegionVars0,
+                    set_to_bitset(UnprotectedRemovedAtStartOfElse)),
+
+                ProtectRegionVarList =
+                    set_of_var.to_sorted_list(ProtectRegionVars),
+                SnapshotRegionVarList =
+                    set_of_var.to_sorted_list(SnapshotRegionVars),
 
                 list.length(ProtectRegionVarList, NumProtectRegionVars),
                 list.length(SnapshotRegionVarList, NumSnapshotRegionVars),
Index: compiler/live_vars.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/live_vars.m,v
retrieving revision 1.145
diff -u -b -r1.145 live_vars.m
--- compiler/live_vars.m	23 May 2011 05:08:04 -0000	1.145
+++ compiler/live_vars.m	10 Jul 2011 17:01:18 -0000
@@ -26,10 +26,9 @@
 :- import_module hlds.hlds_llds.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
-:- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module bool.
-:- import_module set.
 
 %-----------------------------------------------------------------------------%
 
@@ -51,9 +50,9 @@
 ].
 
 :- pred build_live_sets_in_goal_no_par_stack(hlds_goal::in, hlds_goal::out,
-    set(prog_var)::in, alloc_data::in, T::in, T::out,
-    set(prog_var)::in, set(prog_var)::out,
-    set(prog_var)::in, set(prog_var)::out) is det <= stack_alloc_info(T).
+    set_of_progvar::in, alloc_data::in, T::in, T::out,
+    set_of_progvar::in, set_of_progvar::out,
+    set_of_progvar::in, set_of_progvar::out) is det <= stack_alloc_info(T).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -66,6 +65,7 @@
 :- import_module hlds.hlds_llds.
 :- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
+:- import_module parse_tree.prog_data.
 
 :- import_module list.
 :- import_module map.
@@ -80,15 +80,15 @@
     --->    parallel_stackvars(
                 % Variables nonlocal to the parallel conjunction which need
                 % their own stack slots.
-                set(prog_var),
+                set_of_progvar,
 
                 % Variables local to parallel conjuncts prior to the
                 % current conjunct which need stack slots.
-                list(set(prog_var)),
+                list(set_of_progvar),
 
                 % Accumulating set of variables local to the current
                 % parallel conjunct which need stack slots.
-                set(prog_var)
+                set_of_progvar
             ).
 
 %-----------------------------------------------------------------------------%
@@ -99,15 +99,15 @@
 
 build_live_sets_in_goal_no_par_stack(Goal0, Goal,
         ResumeVars0, AllocData, !StackAlloc, !Liveness, !NondetLiveness) :-
-    ParStackVars0 = parallel_stackvars(set.init, [], set.init),
+    ParStackVars0 = parallel_stackvars(set_of_var.init, [], set_of_var.init),
     build_live_sets_in_goal(Goal0, Goal, ResumeVars0,
         AllocData, !StackAlloc, !Liveness, !NondetLiveness,
         ParStackVars0, _ParStackVars).
 
 :- pred build_live_sets_in_goal(hlds_goal::in, hlds_goal::out,
-    set(prog_var)::in, alloc_data::in, T::in, T::out,
-    set(prog_var)::in, set(prog_var)::out,
-    set(prog_var)::in, set(prog_var)::out,
+    set_of_progvar::in, alloc_data::in, T::in, T::out,
+    set_of_progvar::in, set_of_progvar::out,
+    set_of_progvar::in, set_of_progvar::out,
     parallel_stackvars::in, parallel_stackvars::out)
     is det <= stack_alloc_info(T).
 
@@ -120,8 +120,8 @@
     goal_info_get_post_births(GoalInfo0, PostBirths),
 
     % note: we must be careful to apply deaths before births
-    set.difference(!.Liveness, PreDeaths, !:Liveness),
-    set.union(!.Liveness, PreBirths, !:Liveness),
+    set_of_var.difference(!.Liveness, PreDeaths, !:Liveness),
+    set_of_var.union(!.Liveness, PreBirths, !:Liveness),
 
     % If the goal is atomic, we want to apply the postdeaths before processing
     % the goal, but if the goal is a compound goal, then we want to apply them
@@ -129,7 +129,7 @@
     HasSubGoals = goal_expr_has_subgoals(GoalExpr0),
     (
         HasSubGoals = does_not_have_subgoals,
-        set.difference(!.Liveness, PostDeaths, !:Liveness)
+        set_of_var.difference(!.Liveness, PostDeaths, !:Liveness)
     ;
         HasSubGoals = has_subgoals
     ),
@@ -142,7 +142,7 @@
     ;
         ResumePoint = resume_point(ResumePointVars, Locs),
         ( resume_locs_include_stack(Locs, yes) ->
-            set.union(ResumeVars0, ResumePointVars, ResumeVars1),
+            set_of_var.union(ResumeVars0, ResumePointVars, ResumeVars1),
             ResumeOnStack = yes
         ;
             ResumeVars1 = ResumeVars0,
@@ -161,10 +161,10 @@
         HasSubGoals = does_not_have_subgoals
     ;
         HasSubGoals = has_subgoals,
-        set.difference(!.Liveness, PostDeaths, !:Liveness)
+        set_of_var.difference(!.Liveness, PostDeaths, !:Liveness)
     ),
 
-    set.union(!.Liveness, PostBirths, !:Liveness),
+    set_of_var.union(!.Liveness, PostBirths, !:Liveness),
     Goal = hlds_goal(GoalExpr, GoalInfo).
 
 :- pred resume_locs_include_stack(resume_locs::in, bool::out) is det.
@@ -186,9 +186,9 @@
     %
 :- pred build_live_sets_in_goal_2(hlds_goal_expr::in, hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    set(prog_var)::in, alloc_data::in, T::in, T::out,
-    set(prog_var)::in, set(prog_var)::out,
-    set(prog_var)::in, set(prog_var)::out,
+    set_of_progvar::in, alloc_data::in, T::in, T::out,
+    set_of_progvar::in, set_of_progvar::out,
+    set_of_progvar::in, set_of_progvar::out,
     parallel_stackvars::in, parallel_stackvars::out)
     is det <= stack_alloc_info(T).
 
@@ -216,11 +216,12 @@
             % must be available in a stackslot past the parallel conjunction
             % as well.
             NonLocals = goal_info_get_code_gen_nonlocals(GoalInfo0),
-            LiveSet = set.union_list([NonLocals, !.Liveness, ResumeVars0]),
+            LiveSet = set_of_var.union_list([set_to_bitset(NonLocals),
+                !.Liveness, ResumeVars0]),
 
-            InnerNonLocals = LiveSet `set.union` OuterNonLocals,
+            InnerNonLocals = LiveSet `set_of_var.union` OuterNonLocals,
             InnerParStackVars0 =
-                parallel_stackvars(InnerNonLocals, [], set.init),
+                parallel_stackvars(InnerNonLocals, [], set_of_var.init),
             build_live_sets_in_par_conj(Goals0, Goals, ResumeVars0, AllocData,
                 !StackAlloc, !Liveness, !NondetLiveness,
                 InnerParStackVars0, InnerParStackVars),
@@ -231,8 +232,8 @@
             % slots. Variables local to a single conjunct could share stack
             % slots, as long as the _sets_ of stack slots allocated to
             % different parallel conjuncts are distinct.
-            NeedInParConj = need_in_par_conj(InnerNonLocals `set.union`
-                set.union_list(InnerStackVars)),
+            NeedInParConj = need_in_par_conj(InnerNonLocals `set_of_var.union`
+                    set_of_var.union_list(InnerStackVars)),
             record_par_conj(NeedInParConj, GoalInfo0, GoalInfo, !StackAlloc),
 
             % All the local variables which needed stack slots in the parallel
@@ -241,8 +242,9 @@
             % to but are needed in the parallel conjunctions also become part
             % of the accumulating set.
             OuterAccStackVars = OuterAccStackVars0
-                `set.union` set.union_list(InnerStackVars)
-                `set.union` (LiveSet `set.difference` OuterNonLocals),
+                `set_of_var.union` set_of_var.union_list(InnerStackVars)
+                `set_of_var.union`
+                    (LiveSet `set_of_var.difference` OuterNonLocals),
             !:ParStackVars = parallel_stackvars(OuterNonLocals,
                 OuterLocalStackVars, OuterAccStackVars)
         ),
@@ -279,7 +281,8 @@
                         resume_locs_include_stack(Locs, yes)
                     )
                 ->
-                    set.union(!.NondetLiveness, ResumeVars, !:NondetLiveness)
+                    set_of_var.union(!.NondetLiveness, ResumeVars,
+                        !:NondetLiveness)
                 ;
                     true
                 )
@@ -316,7 +319,8 @@
         build_live_sets_in_goal(Else0, Else, ResumeVars0, AllocData,
             !StackAlloc, Liveness0, Liveness,
             NondetLiveness0, NondetLivenessElse, !ParStackVars),
-        set.union(NondetLivenessThen, NondetLivenessElse, NondetLiveness),
+        set_of_var.union(NondetLivenessThen, NondetLivenessElse,
+            NondetLiveness),
         !:Liveness = Liveness,
         !:NondetLiveness = NondetLiveness,
         GoalExpr = if_then_else(Vars, Cond, Then, Else),
@@ -338,7 +342,7 @@
             % The scope does not contain any calls, resume points or parallel
             % conjunctions, so there are no updates to !StackAlloc,
             % !NondetLiveness, or !ParStackVars.
-            set.insert(TermVar, !Liveness)
+            set_of_var.insert(TermVar, !Liveness)
         ;
             NondetLiveness0 = !.NondetLiveness,
             build_live_sets_in_goal(SubGoal0, SubGoal, ResumeVars0, AllocData,
@@ -376,9 +380,9 @@
             ModuleInfo = AllocData ^ ad_module_info,
             arg_info.partition_generic_call_args(ModuleInfo, ArgVars,
                 Types, Modes, _InVars, OutVars, _UnusedVars),
-            build_live_sets_in_call(OutVars, GoalInfo0, GoalInfo,
-                ResumeVars0, AllocData, !StackAlloc, !.Liveness,
-                !NondetLiveness, !ParStackVars)
+            build_live_sets_in_call(set_to_bitset(OutVars),
+                GoalInfo0, GoalInfo, ResumeVars0, AllocData,
+                !StackAlloc, !.Liveness, !NondetLiveness, !ParStackVars)
         )
     ;
         GoalExpr0 = plain_call(PredId, ProcId, ArgVars, Builtin, _, _),
@@ -396,9 +400,9 @@
             ( Builtin = out_of_line_builtin
             ; Builtin = not_builtin
             ),
-            build_live_sets_in_call(OutVars, GoalInfo0, GoalInfo,
-                ResumeVars0, AllocData, !StackAlloc, !.Liveness,
-                !NondetLiveness, !ParStackVars)
+            build_live_sets_in_call(set_to_bitset(OutVars),
+                GoalInfo0, GoalInfo, ResumeVars0, AllocData,
+                !StackAlloc, !.Liveness, !NondetLiveness, !ParStackVars)
         )
     ;
         GoalExpr0 = unify(_, _, _, Unification, _),
@@ -442,9 +446,9 @@
             % (except for the output arguments produced by the call), plus
             % all the variables that may be needed at an enclosing resumption
             % point.
-            build_live_sets_in_call(OutVars, GoalInfo0, GoalInfo,
-                ResumeVars0, AllocData, !StackAlloc, !.Liveness,
-                !NondetLiveness, !ParStackVars)
+            build_live_sets_in_call(set_to_bitset(OutVars),
+                GoalInfo0, GoalInfo, ResumeVars0, AllocData,
+                !StackAlloc, !.Liveness, !NondetLiveness, !ParStackVars)
         )
     ;
         GoalExpr0 = shorthand(_),
@@ -460,16 +464,15 @@
     % arguments produced by the goal, plus all the variables that may be
     % needed at an enclosing resumption point.
     %
-:- pred build_live_sets_in_call(set(prog_var)::in, hlds_goal_info::in,
-    hlds_goal_info::out, set(prog_var)::in, alloc_data::in, T::in, T::out,
-    set(prog_var)::in, set(prog_var)::in, set(prog_var)::out,
+:- pred build_live_sets_in_call(set_of_progvar::in, hlds_goal_info::in,
+    hlds_goal_info::out, set_of_progvar::in, alloc_data::in, T::in, T::out,
+    set_of_progvar::in, set_of_progvar::in, set_of_progvar::out,
     parallel_stackvars::in, parallel_stackvars::out)
     is det <= stack_alloc_info(T).
 
 build_live_sets_in_call(OutVars, GoalInfo0, GoalInfo, ResumeVars0, AllocData,
         !StackAlloc, Liveness, !NondetLiveness, !ParStackVars) :-
-
-    set.difference(Liveness, OutVars, ForwardVars0),
+    set_of_var.difference(Liveness, OutVars, ForwardVars0),
 
     % Might need to add more live variables with typeinfo liveness
     % calculation.
@@ -482,7 +485,8 @@
         Detism = detism_erroneous,
         AllocData ^ ad_opt_no_return_calls = yes
     ->
-        NeedAcrossCall = need_across_call(set.init, set.init, set.init)
+        NeedAcrossCall = need_across_call(set_of_var.init, set_of_var.init,
+            set_of_var.init)
     ;
         NeedAcrossCall = need_across_call(ForwardVars, ResumeVars0,
             !.NondetLiveness)
@@ -500,7 +504,7 @@
         CodeModel = model_semi
     ;
         CodeModel = model_non,
-        set.union(!.NondetLiveness, ForwardVars, !:NondetLiveness)
+        set_of_var.union(!.NondetLiveness, ForwardVars, !:NondetLiveness)
     ),
 
     % In a parallel conjunction all the stack slots we need must not be reused
@@ -508,15 +512,16 @@
     % allocated stack slots in each conjunct.
 
     !.ParStackVars = parallel_stackvars(Nonlocals, ParallelVars, AccVars0),
-    AccVars = AccVars0 `set.union` (ForwardVars `set.difference` Nonlocals),
+    AccVars = AccVars0 `set_of_var.union`
+        (ForwardVars `set_of_var.difference` Nonlocals),
     !:ParStackVars = parallel_stackvars(Nonlocals, ParallelVars, AccVars).
 
 %-----------------------------------------------------------------------------%
 
 :- pred build_live_sets_in_conj(list(hlds_goal)::in, list(hlds_goal)::out,
-    set(prog_var)::in, alloc_data::in, T::in, T::out,
-    set(prog_var)::in, set(prog_var)::out,
-    set(prog_var)::in, set(prog_var)::out,
+    set_of_progvar::in, alloc_data::in, T::in, T::out,
+    set_of_progvar::in, set_of_progvar::out,
+    set_of_progvar::in, set_of_progvar::out,
     parallel_stackvars::in, parallel_stackvars::out)
     is det <= stack_alloc_info(T).
 
@@ -542,9 +547,9 @@
 %-----------------------------------------------------------------------------%
 
 :- pred build_live_sets_in_par_conj(list(hlds_goal)::in, list(hlds_goal)::out,
-    set(prog_var)::in, alloc_data::in, T::in, T::out,
-    set(prog_var)::in, set(prog_var)::out,
-    set(prog_var)::in, set(prog_var)::out,
+    set_of_progvar::in, alloc_data::in, T::in, T::out,
+    set_of_progvar::in, set_of_progvar::out,
+    set_of_progvar::in, set_of_progvar::out,
     parallel_stackvars::in, parallel_stackvars::out)
     is det <= stack_alloc_info(T).
 
@@ -559,7 +564,7 @@
         ParStackVars0, ParStackVars1),
     ParStackVars1 = parallel_stackvars(Nonlocals, PrevSets1, CurSet1),
     ParStackVars2 = parallel_stackvars(Nonlocals, [CurSet1 | PrevSets1],
-        set.init),
+        set_of_var.init),
     build_live_sets_in_par_conj(Goals0, Goals, ResumeVars0, AllocData,
         !StackAlloc, Liveness0, _Liveness1, !NondetLiveness,
         ParStackVars2, ParStackVars).
@@ -567,9 +572,9 @@
 %-----------------------------------------------------------------------------%
 
 :- pred build_live_sets_in_disj(list(hlds_goal)::in, list(hlds_goal)::out,
-    hlds_goal_info::in, set(prog_var)::in, alloc_data::in,
-    T::in, T::out, set(prog_var)::in, set(prog_var)::out,
-    set(prog_var)::in, set(prog_var)::out,
+    hlds_goal_info::in, set_of_progvar::in, alloc_data::in,
+    T::in, T::out, set_of_progvar::in, set_of_progvar::out,
+    set_of_progvar::in, set_of_progvar::out,
     parallel_stackvars::in, parallel_stackvars::out)
     is det <= stack_alloc_info(T).
 
@@ -591,13 +596,13 @@
         % NondetLiveness should be a set of prog_var sets. Instead of taking
         % the union of the NondetLive sets at the ends of disjuncts, we should
         % just keep them in this set of sets.
-        set.union(NondetLiveness1, NondetLiveness2, NondetLiveness3),
+        set_of_var.union(NondetLiveness1, NondetLiveness2, NondetLiveness3),
         goal_info_get_resume_point(GoalInfo, Resume),
         (
             Resume = resume_point(ResumePointVars, Locs),
             resume_locs_include_stack(Locs, yes)
         ->
-            set.union(NondetLiveness3, ResumePointVars, NondetLiveness)
+            set_of_var.union(NondetLiveness3, ResumePointVars, NondetLiveness)
         ;
             NondetLiveness = NondetLiveness3
         )
@@ -611,9 +616,9 @@
 %-----------------------------------------------------------------------------%
 
 :- pred build_live_sets_in_cases(list(case)::in, list(case)::out,
-    set(prog_var)::in, alloc_data::in, T::in, T::out,
-    set(prog_var)::in, set(prog_var)::out,
-    set(prog_var)::in, set(prog_var)::out,
+    set_of_progvar::in, alloc_data::in, T::in, T::out,
+    set_of_progvar::in, set_of_progvar::out,
+    set_of_progvar::in, set_of_progvar::out,
     parallel_stackvars::in, parallel_stackvars::out)
     is det <= stack_alloc_info(T).
 
@@ -630,7 +635,7 @@
     build_live_sets_in_cases(Cases0, Cases, ResumeVars0, AllocData,
         !StackAlloc, Liveness0, _Liveness2, NondetLiveness0, NondetLiveness2,
         !ParStackVars),
-    set.union(NondetLiveness1, NondetLiveness2, NondetLiveness).
+    set_of_var.union(NondetLiveness1, NondetLiveness2, NondetLiveness).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -654,7 +659,7 @@
     % since this makes a significant difference to the output set of vars.
     %
 :- pred maybe_add_typeinfo_liveness(proc_info::in, bool::in,
-    set(prog_var)::in, set(prog_var)::in, set(prog_var)::out) is det.
+    set_of_progvar::in, set_of_progvar::in, set_of_progvar::out) is det.
 
 maybe_add_typeinfo_liveness(ProcInfo, TypeInfoLiveness, OutVars, !LiveVars) :-
     (
@@ -663,8 +668,8 @@
         proc_info_get_rtti_varmaps(ProcInfo, RttiVarMaps),
         get_typeinfo_vars(!.LiveVars, VarTypes, RttiVarMaps, TypeInfoVarsLive),
         get_typeinfo_vars(OutVars, VarTypes, RttiVarMaps, TypeInfoVarsOut),
-        set.union(!.LiveVars, TypeInfoVarsOut, !:LiveVars),
-        set.union(!.LiveVars, TypeInfoVarsLive, !:LiveVars)
+        set_of_var.union(!.LiveVars, TypeInfoVarsOut, !:LiveVars),
+        set_of_var.union(!.LiveVars, TypeInfoVarsLive, !:LiveVars)
     ;
         TypeInfoLiveness = no
     ).
Index: compiler/liveness.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/liveness.m,v
retrieving revision 1.180
diff -u -b -r1.180 liveness.m
--- compiler/liveness.m	23 May 2011 05:08:04 -0000	1.180
+++ compiler/liveness.m	10 Jul 2011 16:58:38 -0000
@@ -156,9 +156,7 @@
 
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
-:- import_module parse_tree.prog_data.
-
-:- import_module set.
+:- import_module parse_tree.set_of_var.
 
 %-----------------------------------------------------------------------------%
 
@@ -178,7 +176,7 @@
     % Return the set of variables live at the start of the procedure.
     %
 :- pred initial_liveness(proc_info::in, pred_id::in, module_info::in,
-    set(prog_var)::out) is det.
+    set_of_progvar::out) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -202,6 +200,8 @@
 :- import_module libs.trace_params.
 :- import_module ll_backend.trace_gen.
 :- import_module parse_tree.mercury_to_mercury.
+:- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module assoc_list.
 :- import_module bool.
@@ -226,7 +226,6 @@
 %   need to either change them to use set_of_var, or do conversions before and
 %   after all calls to them.
 %
-:- type set_of_var == set(prog_var).
 
 %-----------------------------------------------------------------------------%
 
@@ -336,18 +335,19 @@
         eff_trace_level_needs_fail_vars(ModuleInfo, PredInfo, !.ProcInfo,
             TraceLevel) = yes
     ->
-        trace_fail_vars(ModuleInfo, !.ProcInfo, ResumeVars0)
+        trace_fail_vars(ModuleInfo, !.ProcInfo, ResumeVars0),
+        ResumeVars1 = set_to_bitset(ResumeVars0)
     ;
-        set.init(ResumeVars0)
+        ResumeVars1 = set_of_var.init
     ),
     detect_resume_points_in_goal(Goal3, Goal, Liveness0, _,
-        LiveInfo, ResumeVars0),
+        LiveInfo, ResumeVars1),
     trace [io(!IO)] (
         maybe_debug_liveness(ModuleInfo, "\nafter resume point",
             DebugLiveness, PredIdInt, VarSet, Goal, !IO)
     ),
     proc_info_set_goal(Goal, !ProcInfo),
-    proc_info_set_liveness_info(Liveness0, !ProcInfo).
+    proc_info_set_liveness_info(bitset_to_set(Liveness0), !ProcInfo).
 
 :- pred maybe_debug_liveness(module_info::in, string::in, int::in, int::in,
     prog_varset::in, hlds_goal::in, io::di, io::uo) is det.
@@ -368,28 +368,28 @@
 %-----------------------------------------------------------------------------%
 
 :- pred detect_liveness_in_goal(hlds_goal::in, hlds_goal::out,
-    set_of_var::in, set_of_var::out, live_info::in) is det.
+    set_of_progvar::in, set_of_progvar::out, live_info::in) is det.
 
 detect_liveness_in_goal(Goal0, Goal, Liveness0, FinalLiveness, LiveInfo) :-
     Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
     % Work out which variables get born in this goal.
     get_nonlocals_and_typeinfos(LiveInfo, GoalInfo0,
         BaseNonLocals, CompletedNonLocals),
-    set.difference(CompletedNonLocals, Liveness0, NewVarsSet),
-    set.to_sorted_list(NewVarsSet, NewVarsList),
+    set_of_var.difference(CompletedNonLocals, Liveness0, NewVarsSet),
+    NewVarsList = set_of_var.to_sorted_list(NewVarsSet),
     InstMapDelta = goal_info_get_instmap_delta(GoalInfo0),
-    set.init(Empty),
+    Empty = set_of_var.init,
     ( instmap_delta_is_unreachable(InstMapDelta) ->
         Births = Empty
     ;
-        set.init(Births0),
+        Births0 = set_of_var.init,
         find_value_giving_occurrences(NewVarsList, LiveInfo,
             InstMapDelta, Births0, Births1),
-        set.difference(CompletedNonLocals, BaseNonLocals, TypeInfos),
-        set.difference(TypeInfos, Liveness0, NewTypeInfos),
-        set.union(Births1, NewTypeInfos, Births)
+        set_of_var.difference(CompletedNonLocals, BaseNonLocals, TypeInfos),
+        set_of_var.difference(TypeInfos, Liveness0, NewTypeInfos),
+        set_of_var.union(Births1, NewTypeInfos, Births)
     ),
-    set.union(Liveness0, Births, FinalLiveness),
+    set_of_var.union(Liveness0, Births, FinalLiveness),
 
     (
         ( GoalExpr0 = plain_call(_, _, _, _, _, _)
@@ -397,10 +397,10 @@
         ; GoalExpr0 = call_foreign_proc(_,_,  _, _, _, _, _)
         ; GoalExpr0 = unify(_, _, _, _, _)
         ),
-        PreDeaths = set.init,
+        PreDeaths = set_of_var.init,
         PreBirths = Births,
-        PostDeaths = set.init,
-        PostBirths = set.init,
+        PostDeaths = set_of_var.init,
+        PostBirths = set_of_var.init,
         GoalExpr = GoalExpr0
     ;
         (
@@ -411,18 +411,18 @@
                     LiveInfo)
             ;
                 ConjType = parallel_conj,
-                set.init(Union0),
+                Union0 = set_of_var.init,
                 detect_liveness_in_par_conj(Goals0, Goals, Liveness0,
                     CompletedNonLocals, LiveInfo, Union0, Union),
-                set.union(Union, Liveness0, Liveness)
+                set_of_var.union(Union, Liveness0, Liveness)
             ),
             GoalExpr = conj(ConjType, Goals)
         ;
             GoalExpr0 = disj(Goals0),
-            set.init(Union0),
+            Union0 = set_of_var.init,
             detect_liveness_in_disj(Goals0, Goals, Liveness0,
                 CompletedNonLocals, LiveInfo, Union0, Union),
-            set.union(Union, Liveness0, Liveness),
+            set_of_var.union(Union, Liveness0, Liveness),
             GoalExpr = disj(Goals)
         ;
             GoalExpr0 = switch(Var, Det, Cases0),
@@ -452,12 +452,14 @@
             detect_liveness_in_goal(Else0, Else1, Liveness0, LivenessElse,
                 LiveInfo),
 
-            set.union(LivenessThen, LivenessElse, Liveness),
-            set.intersect(Liveness, CompletedNonLocals,
+            set_of_var.union(LivenessThen, LivenessElse, Liveness),
+            set_of_var.intersect(Liveness, CompletedNonLocals,
                 ITENonLocalLiveness),
 
-            set.difference(ITENonLocalLiveness, LivenessThen, ResidueThen),
-            set.difference(ITENonLocalLiveness, LivenessElse, ResidueElse),
+            set_of_var.difference(ITENonLocalLiveness, LivenessThen,
+                ResidueThen),
+            set_of_var.difference(ITENonLocalLiveness, LivenessElse,
+                ResidueElse),
 
             add_liveness_after_goal(Then1, ResidueThen, Then),
             add_liveness_after_goal(Else1, ResidueElse, Else),
@@ -479,12 +481,12 @@
             ),
             GoalExpr = scope(Reason, SubGoal)
         ),
-        PreDeaths = set.init,
-        PreBirths = set.init,
-        set.intersect(CompletedNonLocals, Liveness, NonLocalLiveness),
-        set.union(NonLocalLiveness, Liveness0, GoalFinalLiveness),
-        set.difference(GoalFinalLiveness, FinalLiveness, PostDeaths),
-        set.difference(FinalLiveness, GoalFinalLiveness, PostBirths)
+        PreDeaths = set_of_var.init,
+        PreBirths = set_of_var.init,
+        set_of_var.intersect(CompletedNonLocals, Liveness, NonLocalLiveness),
+        set_of_var.union(NonLocalLiveness, Liveness0, GoalFinalLiveness),
+        set_of_var.difference(GoalFinalLiveness, FinalLiveness, PostDeaths),
+        set_of_var.difference(FinalLiveness, GoalFinalLiveness, PostBirths)
     ;
         GoalExpr0 = shorthand(_),
         unexpected($module, $pred, "shorthand")
@@ -498,7 +500,7 @@
 %-----------------------------------------------------------------------------%
 
 :- pred detect_liveness_in_conj(list(hlds_goal)::in, list(hlds_goal)::out,
-    set_of_var::in, set_of_var::out, live_info::in) is det.
+    set_of_progvar::in, set_of_progvar::out, live_info::in) is det.
 
 detect_liveness_in_conj([], [], !Liveness, _LiveInfo).
 detect_liveness_in_conj([Goal0 | Goals0], [Goal | Goals], !Liveness,
@@ -522,59 +524,60 @@
 %-----------------------------------------------------------------------------%
 
 :- pred detect_liveness_in_disj(list(hlds_goal)::in, list(hlds_goal)::out,
-    set_of_var::in, set_of_var::in, live_info::in,
-    set_of_var::in, set_of_var::out) is det.
+    set_of_progvar::in, set_of_progvar::in, live_info::in,
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 detect_liveness_in_disj([], [], _Liveness, _NonLocals, _LiveInfo, !Union).
 detect_liveness_in_disj([Goal0 | Goals0], [Goal | Goals], Liveness0, NonLocals,
         LiveInfo, !Union) :-
     detect_liveness_in_goal(Goal0, Goal1, Liveness0, Liveness1, LiveInfo),
-    set.union(Liveness1, !Union),
+    set_of_var.union(Liveness1, !Union),
     detect_liveness_in_disj(Goals0, Goals, Liveness0, NonLocals, LiveInfo,
         !Union),
-    set.intersect(!.Union, NonLocals, NonLocalUnion),
-    set.difference(NonLocalUnion, Liveness1, Residue),
+    set_of_var.intersect(!.Union, NonLocals, NonLocalUnion),
+    set_of_var.difference(NonLocalUnion, Liveness1, Residue),
     add_liveness_after_goal(Goal1, Residue, Goal).
 
 %-----------------------------------------------------------------------------%
 
 :- pred detect_liveness_in_cases(list(case)::in, list(case)::out,
-    set_of_var::in, set_of_var::in, live_info::in,
-    set_of_var::in, set_of_var::out) is det.
+    set_of_progvar::in, set_of_progvar::in, live_info::in,
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 detect_liveness_in_cases([], [], _Liveness, _NonLocals, _LiveInfo, !Union).
 detect_liveness_in_cases([Case0 | Cases0], [Case | Cases], Liveness0,
         NonLocals, LiveInfo, !Union) :-
     Case0 = case(MainConsId, OtherConsIds, Goal0),
     detect_liveness_in_goal(Goal0, Goal1, Liveness0, Liveness1, LiveInfo),
-    set.union(Liveness1, !Union),
+    set_of_var.union(Liveness1, !Union),
     detect_liveness_in_cases(Cases0, Cases, Liveness0, NonLocals, LiveInfo,
         !Union),
-    set.intersect(!.Union, NonLocals, NonLocalUnion),
-    set.difference(NonLocalUnion, Liveness1, Residue),
+    set_of_var.intersect(!.Union, NonLocals, NonLocalUnion),
+    set_of_var.difference(NonLocalUnion, Liveness1, Residue),
     add_liveness_after_goal(Goal1, Residue, Goal),
     Case = case(MainConsId, OtherConsIds, Goal).
 
 %-----------------------------------------------------------------------------%
 
 :- pred detect_liveness_in_construct(hlds_goal::in, hlds_goal::out,
-    set_of_var::in, set_of_var::out, live_info::in, prog_var::in) is det.
+    set_of_progvar::in, set_of_progvar::out, live_info::in, prog_var::in)
+    is det.
 
 detect_liveness_in_construct(Goal0, Goal, !Liveness, LiveInfo, TermVar) :-
     Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
     ( GoalExpr0 = conj(plain_conj, Conjuncts0) ->
-        set.init(LocalLiveVars0),
+        LocalLiveVars0 = set_of_var.init,
         detect_liveness_in_construct_goal_loop(Conjuncts0, Conjuncts,
             LocalLiveVars0, LocalLiveVars),
-        ( set.singleton_set(LocalLiveVars, TermVar) ->
+        ( set_of_var.is_singleton(LocalLiveVars, TermVar) ->
             maybe_complete_with_typeinfos(LiveInfo,
-                set.make_singleton_set(TermVar), CompletedTermVars),
-            set.union(CompletedTermVars, !Liveness),
+                set_of_var.make_singleton(TermVar), CompletedTermVars),
+            set_of_var.union(CompletedTermVars, !Liveness),
             GoalExpr = conj(plain_conj, Conjuncts),
-            set.init(PreBirths),
-            set.init(PostBirths),
-            set.init(PreDeaths),
-            set.init(PostDeaths),
+            PreBirths  = set_of_var.init,
+            PostBirths = set_of_var.init,
+            PreDeaths  = set_of_var.init,
+            PostDeaths = set_of_var.init,
             goal_info_initialize_liveness_info(PreBirths, PostBirths,
                 PreDeaths, PostDeaths, no_resume_point, GoalInfo0, GoalInfo),
             Goal = hlds_goal(GoalExpr, GoalInfo)
@@ -587,7 +590,7 @@
 
 :- pred detect_liveness_in_construct_goal_loop(
     list(hlds_goal)::in, list(hlds_goal)::out,
-    set_of_var::in, set_of_var::out) is det.
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 detect_liveness_in_construct_goal_loop([], [], !LocalLiveVars).
 detect_liveness_in_construct_goal_loop([Goal0 | Goals0], [Goal | Goals],
@@ -598,12 +601,12 @@
         Unification = construct(LHSVar, _ConsId, RHSVars, _ArgModes,
             construct_statically, cell_is_shared, no_construct_sub_info)
     ->
-        ( set.remove_list(RHSVars, !LocalLiveVars) ->
-            set.insert(LHSVar, !LocalLiveVars),
-            PreBirths = set.make_singleton_set(LHSVar),
-            set.init(PostBirths),
-            set.init(PreDeaths),
-            set.list_to_set(RHSVars, PostDeaths),
+        ( set_of_var.remove_list(RHSVars, !LocalLiveVars) ->
+            set_of_var.insert(LHSVar, !LocalLiveVars),
+            PreBirths = set_of_var.make_singleton(LHSVar),
+            PostBirths = set_of_var.init,
+            PreDeaths  = set_of_var.init,
+            PostDeaths = set_of_var.list_to_set(RHSVars),
             goal_info_initialize_liveness_info(PreBirths, PostBirths,
                 PreDeaths, PostDeaths, no_resume_point, GoalInfo0, GoalInfo),
             Goal = hlds_goal(GoalExpr, GoalInfo)
@@ -618,18 +621,18 @@
 %-----------------------------------------------------------------------------%
 
 :- pred detect_liveness_in_par_conj(list(hlds_goal)::in, list(hlds_goal)::out,
-    set_of_var::in, set_of_var::in, live_info::in,
-    set_of_var::in, set_of_var::out) is det.
+    set_of_progvar::in, set_of_progvar::in, live_info::in,
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 detect_liveness_in_par_conj([], [], _Liveness, _NonLocals, _LiveInfo, !Union).
 detect_liveness_in_par_conj([Goal0 | Goals0], [Goal | Goals], Liveness0,
         NonLocals, LiveInfo, !Union) :-
     detect_liveness_in_goal(Goal0, Goal1, Liveness0, Liveness1, LiveInfo),
-    set.union(Liveness1, !Union),
+    set_of_var.union(Liveness1, !Union),
     detect_liveness_in_par_conj(Goals0, Goals, Liveness0, NonLocals,
         LiveInfo, !Union),
-    set.intersect(!.Union, NonLocals, NonLocalUnion),
-    set.difference(NonLocalUnion, Liveness1, Residue),
+    set_of_var.intersect(!.Union, NonLocals, NonLocalUnion),
+    set_of_var.difference(NonLocalUnion, Liveness1, Residue),
     add_liveness_after_goal(Goal1, Residue, Goal).
 
 %-----------------------------------------------------------------------------%
@@ -639,7 +642,7 @@
     % live now and whose values will be needed beyond that program point.
     % 
 :- pred detect_deadness_in_goal(hlds_goal::in, hlds_goal::out,
-    set_of_var::in, set_of_var::out, set_of_var::in,
+    set_of_progvar::in, set_of_progvar::out, set_of_progvar::in,
     live_info::in) is det.
 
 detect_deadness_in_goal(Goal0, Goal, !Deadness, !.Liveness, LiveInfo) :-
@@ -649,11 +652,11 @@
     goal_info_get_post_deaths(GoalInfo0, PostDeaths0),
     goal_info_get_post_births(GoalInfo0, PostBirths0),
 
-    set.difference(!.Deadness, PostBirths0, !:Deadness),
-    set.union(PostDeaths0, !Deadness),
+    set_of_var.difference(!.Deadness, PostBirths0, !:Deadness),
+    set_of_var.union(PostDeaths0, !Deadness),
 
-    set.difference(!.Liveness, PreDeaths0, !:Liveness),
-    set.union(PreBirths0, !Liveness),
+    set_of_var.difference(!.Liveness, PreDeaths0, !:Liveness),
+    set_of_var.union(PreBirths0, !Liveness),
 
     (
         ( GoalExpr0 = plain_call(_, _, _, _, _, _)
@@ -663,12 +666,12 @@
         ),
         get_nonlocals_and_typeinfos(LiveInfo, GoalInfo0,
             _BaseNonLocals, CompletedNonLocals),
-        set.intersect(!.Liveness, CompletedNonLocals, LiveNonLocals),
-        set.difference(LiveNonLocals, !.Deadness, NewPostDeaths),
-        set.union(NewPostDeaths, !Deadness),
+        set_of_var.intersect(!.Liveness, CompletedNonLocals, LiveNonLocals),
+        set_of_var.difference(LiveNonLocals, !.Deadness, NewPostDeaths),
+        set_of_var.union(NewPostDeaths, !Deadness),
         GoalExpr = GoalExpr0,
 
-        set.union(PostDeaths0, NewPostDeaths, PostDeaths),
+        set_of_var.union(PostDeaths0, NewPostDeaths, PostDeaths),
         goal_info_set_post_deaths(PostDeaths, GoalInfo0, GoalInfo)
     ;
         GoalExpr0 = conj(ConjType, Conjuncts0),
@@ -685,7 +688,7 @@
                 ConjType = parallel_conj,
                 get_nonlocals_and_typeinfos(LiveInfo, GoalInfo0,
                     _, CompletedNonLocals),
-                set.init(Union0),
+                Union0 = set_of_var.init,
                 detect_deadness_in_par_conj(Conjuncts0, Conjuncts, !.Deadness,
                     !.Liveness, CompletedNonLocals, LiveInfo, Union0, Union,
                     _CompletedNonLocalUnion),
@@ -701,7 +704,7 @@
             GoalExpr = GoalExpr0
         ;
             Disjuncts0 = [_ | _],
-            set.init(Union0),
+            Union0 = set_of_var.init,
             get_nonlocals_and_typeinfos(LiveInfo, GoalInfo0,
                 _, CompletedNonLocals),
             detect_deadness_in_disj(Disjuncts0, Disjuncts, !.Deadness,
@@ -712,7 +715,7 @@
         GoalInfo = GoalInfo0
     ;
         GoalExpr0 = switch(Var, Det, Cases0),
-        set.init(Union0),
+        Union0 = set_of_var.init,
         get_nonlocals_and_typeinfos(LiveInfo, GoalInfo0,
             _, CompletedNonLocals),
         detect_deadness_in_cases(Var, Cases0, Cases, !.Deadness, !.Liveness,
@@ -758,13 +761,13 @@
             ;
                 ElseInstmapReachable = no
             ),
-            set.init(Union0),
+            Union0 = set_of_var.init,
             union_branch_deadness(DeadnessCond, Deadness0,
                 CondThenInstmapReachable, Union0, Union1),
             union_branch_deadness(DeadnessElse, Deadness0,
                 ElseInstmapReachable, Union1, Union),
             Deadness = Union,
-            set.intersect(Deadness, CompletedNonLocals,
+            set_of_var.intersect(Deadness, CompletedNonLocals,
                 CompletedNonLocalDeadness),
             add_branch_pre_deaths(DeadnessCond, Deadness0,
                 CompletedNonLocalDeadness, CondThenInstmapReachable,
@@ -772,8 +775,8 @@
             add_branch_pre_deaths(DeadnessElse, Deadness0,
                 CompletedNonLocalDeadness, ElseInstmapReachable, Else1, Else)
         ;
-            set.union(DeadnessCond, DeadnessElse, Deadness),
-            set.intersect(Deadness, CompletedNonLocals,
+            set_of_var.union(DeadnessCond, DeadnessElse, Deadness),
+            set_of_var.intersect(Deadness, CompletedNonLocals,
                 CompletedNonLocalDeadness),
             InstmapReachable = no,
             add_branch_pre_deaths(DeadnessCond, Deadness0,
@@ -794,8 +797,8 @@
         GoalExpr0 = scope(Reason, SubGoal0),
         ( Reason = from_ground_term(TermVar, from_ground_term_construct) ->
             maybe_complete_with_typeinfos(LiveInfo,
-                set.make_singleton_set(TermVar), CompletedTermVars),
-            set.difference(!.Deadness, CompletedTermVars, !:Deadness),
+                set_of_var.make_singleton(TermVar), CompletedTermVars),
+            set_of_var.difference(!.Deadness, CompletedTermVars, !:Deadness),
 
             % The job on SubGoal0 was done by detect_liveness_in_goal.
             SubGoal = SubGoal0
@@ -811,13 +814,13 @@
     ),
 
     Goal = hlds_goal(GoalExpr, GoalInfo),
-    set.difference(!.Deadness, PreBirths0, !:Deadness),
-    set.union(PreDeaths0, !Deadness).
+    set_of_var.difference(!.Deadness, PreBirths0, !:Deadness),
+    set_of_var.union(PreDeaths0, !Deadness).
 
 %-----------------------------------------------------------------------------%
 
 :- pred detect_deadness_in_conj(list(hlds_goal)::in, list(hlds_goal)::out,
-    set_of_var::in, set_of_var::out, set_of_var::in,
+    set_of_progvar::in, set_of_progvar::out, set_of_progvar::in,
     live_info::in) is det.
 
 detect_deadness_in_conj([], [], !Deadness, _, _LiveInfo).
@@ -838,13 +841,13 @@
 %-----------------------------------------------------------------------------%
 
 :- pred detect_deadness_in_disj(list(hlds_goal)::in, list(hlds_goal)::out,
-    set_of_var::in, set_of_var::in, set_of_var::in,
-    live_info::in, set_of_var::in, set_of_var::out,
-    set_of_var::out) is det.
+    set_of_progvar::in, set_of_progvar::in, set_of_progvar::in,
+    live_info::in, set_of_progvar::in, set_of_progvar::out,
+    set_of_progvar::out) is det.
 
 detect_deadness_in_disj([], [], _Deadness0, _Liveness0, CompletedNonLocals,
         _LiveInfo, !Union, CompletedNonLocalUnion) :-
-    set.intersect(!.Union, CompletedNonLocals, CompletedNonLocalUnion).
+    set_of_var.intersect(!.Union, CompletedNonLocals, CompletedNonLocalUnion).
 detect_deadness_in_disj([Goal0 | Goals0], [Goal | Goals], Deadness0, Liveness0,
         CompletedNonLocals, LiveInfo, !Union, CompletedNonLocalUnion) :-
     detect_deadness_in_goal(Goal0, Goal1, Deadness0, DeadnessGoal,
@@ -865,17 +868,17 @@
 %-----------------------------------------------------------------------------%
 
 :- pred detect_deadness_in_cases(prog_var::in, list(case)::in, list(case)::out,
-    set_of_var::in, set_of_var::in, set_of_var::in, live_info::in,
-    set_of_var::in, set_of_var::out, set_of_var::out) is det.
+    set_of_progvar::in, set_of_progvar::in, set_of_progvar::in, live_info::in,
+    set_of_progvar::in, set_of_progvar::out, set_of_progvar::out) is det.
 
 detect_deadness_in_cases(SwitchVar, [], [], _Deadness0, _Liveness,
         CompletedNonLocals, LiveInfo, !Union, CompletedNonLocalUnion) :-
     % If the switch variable does not become dead in a case, it must be put in
     % the pre-death set of that case.
-    maybe_complete_with_typeinfos(LiveInfo, set.make_singleton_set(SwitchVar),
-        CompletedSwitchVar),
-    set.union(CompletedSwitchVar, !Union),
-    set.intersect(!.Union, CompletedNonLocals, CompletedNonLocalUnion).
+    maybe_complete_with_typeinfos(LiveInfo,
+        set_of_var.make_singleton(SwitchVar), CompletedSwitchVar),
+    set_of_var.union(CompletedSwitchVar, !Union),
+    set_of_var.intersect(!.Union, CompletedNonLocals, CompletedNonLocalUnion).
 detect_deadness_in_cases(SwitchVar, [Case0 | Cases0], [Case | Cases],
         Deadness0, Liveness0, CompletedNonLocals, LiveInfo, !Union,
         CompletedNonLocalUnion) :-
@@ -900,18 +903,18 @@
 %-----------------------------------------------------------------------------%
 
 :- pred detect_deadness_in_par_conj(list(hlds_goal)::in, list(hlds_goal)::out,
-    set_of_var::in, set_of_var::in, set_of_var::in, live_info::in,
-    set_of_var::in, set_of_var::out, set_of_var::out) is det.
+    set_of_progvar::in, set_of_progvar::in, set_of_progvar::in, live_info::in,
+    set_of_progvar::in, set_of_progvar::out, set_of_progvar::out) is det.
 
 detect_deadness_in_par_conj([], [], _Deadness0, _Liveness0, CompletedNonLocals,
         _LiveInfo, !Union, CompletedNonLocalUnion) :-
-    set.intersect(!.Union, CompletedNonLocals, CompletedNonLocalUnion).
+    set_of_var.intersect(!.Union, CompletedNonLocals, CompletedNonLocalUnion).
 detect_deadness_in_par_conj([Goal0 | Goals0], [Goal | Goals], Deadness0,
         Liveness0, CompletedNonLocals, LiveInfo, !Union,
         CompletedNonLocalUnion) :-
     detect_deadness_in_goal(Goal0, Goal1, Deadness0, DeadnessGoal,
         Liveness0, LiveInfo),
-    set.union(DeadnessGoal, !Union),
+    set_of_var.union(DeadnessGoal, !Union),
     detect_deadness_in_par_conj(Goals0, Goals, Deadness0,
         Liveness0, CompletedNonLocals, LiveInfo, !Union,
         CompletedNonLocalUnion),
@@ -957,38 +960,38 @@
 % in this fashion will be discarded when the erroneous goal is paralleled by
 % a non-erroneous branch of an enclosing branched control structure.
 
-:- pred union_branch_deadness(set_of_var::in, set_of_var::in,
-    bool::in, set_of_var::in, set_of_var::out) is det.
+:- pred union_branch_deadness(set_of_progvar::in, set_of_progvar::in,
+    bool::in, set_of_progvar::in, set_of_progvar::out) is det.
 
 union_branch_deadness(DeadnessGoal, Deadness0, InstmapReachable, !Union) :-
     (
         InstmapReachable = yes,
-        set.union(!.Union, DeadnessGoal, !:Union)
+        set_of_var.union(!.Union, DeadnessGoal, !:Union)
     ;
         InstmapReachable = no,
-        set.difference(DeadnessGoal, Deadness0, FilteredDeadnessGoal),
-        set.union(!.Union, FilteredDeadnessGoal, !:Union)
+        set_of_var.difference(DeadnessGoal, Deadness0, FilteredDeadnessGoal),
+        set_of_var.union(!.Union, FilteredDeadnessGoal, !:Union)
     ).
 
-:- pred add_branch_pre_deaths(set_of_var::in, set_of_var::in,
-    set_of_var::in, bool::in, hlds_goal::in, hlds_goal::out) is det.
+:- pred add_branch_pre_deaths(set_of_progvar::in, set_of_progvar::in,
+    set_of_progvar::in, bool::in, hlds_goal::in, hlds_goal::out) is det.
 
 add_branch_pre_deaths(DeadnessGoal, Deadness0, CompletedNonLocalUnion,
         InstmapReachable, !Goal) :-
-    set.difference(CompletedNonLocalUnion, DeadnessGoal, PreDeaths),
+    set_of_var.difference(CompletedNonLocalUnion, DeadnessGoal, PreDeaths),
     (
         InstmapReachable = yes,
         add_deadness_before_goal(PreDeaths, !Goal)
     ;
         InstmapReachable = no,
-        set.difference(PreDeaths, Deadness0, FilteredPreDeaths),
+        set_of_var.difference(PreDeaths, Deadness0, FilteredPreDeaths),
         add_deadness_before_goal(FilteredPreDeaths, !Goal)
     ).
 
 %-----------------------------------------------------------------------------%
 
 :- pred update_liveness_goal(hlds_goal::in, live_info::in,
-    set_of_var::in, set_of_var::out) is det.
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 update_liveness_goal(Goal, LiveInfo, !Liveness) :-
     Goal = hlds_goal(GoalExpr, GoalInfo),
@@ -998,19 +1001,19 @@
     goal_info_get_post_births(GoalInfo, PostBirths),
 
     Liveness0 = !.Liveness,
-    set.difference(!.Liveness, PreDeaths, !:Liveness),
-    set.union(PreBirths, !Liveness),
+    set_of_var.difference(!.Liveness, PreDeaths, !:Liveness),
+    set_of_var.union(PreBirths, !Liveness),
     update_liveness_expr(GoalExpr, LiveInfo, !Liveness),
-    set.difference(!.Liveness, PostDeaths, !:Liveness),
-    set.union(PostBirths, !Liveness),
+    set_of_var.difference(!.Liveness, PostDeaths, !:Liveness),
+    set_of_var.union(PostBirths, !Liveness),
 
-    set.divide_by_set(Liveness0, !.Liveness, OldLiveness, NewLiveness0),
+    set_of_var.divide_by_set(Liveness0, !.Liveness, OldLiveness, NewLiveness0),
     get_nonlocals_and_typeinfos(LiveInfo, GoalInfo, _, CompletedNonLocals),
-    set.intersect(NewLiveness0, CompletedNonLocals, NewLiveness),
-    set.union(OldLiveness, NewLiveness, !:Liveness).
+    set_of_var.intersect(NewLiveness0, CompletedNonLocals, NewLiveness),
+    set_of_var.union(OldLiveness, NewLiveness, !:Liveness).
 
 :- pred update_liveness_expr(hlds_goal_expr::in, live_info::in,
-    set_of_var::in, set_of_var::out) is det.
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 update_liveness_expr(GoalExpr, LiveInfo, !Liveness) :-
     (
@@ -1065,8 +1068,8 @@
         GoalExpr = scope(Reason, SubGoal),
         ( Reason = from_ground_term(TermVar, from_ground_term_construct) ->
             maybe_complete_with_typeinfos(LiveInfo,
-                set.make_singleton_set(TermVar), CompletedTermVars),
-            set.union(CompletedTermVars, !Liveness)
+                set_of_var.make_singleton(TermVar), CompletedTermVars),
+            set_of_var.union(CompletedTermVars, !Liveness)
         ;
             update_liveness_goal(SubGoal, LiveInfo, !Liveness)
         )
@@ -1076,7 +1079,7 @@
     ).
 
 :- pred update_liveness_conj(list(hlds_goal)::in, live_info::in,
-    set_of_var::in, set_of_var::out) is det.
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 update_liveness_conj([], _, !Liveness).
 update_liveness_conj([Goal | Goals], LiveInfo, !Liveness) :-
@@ -1127,20 +1130,20 @@
 % well.
 
 :- pred delay_death_proc_body(hlds_goal::in, hlds_goal::out, prog_varset::in,
-    set_of_var::in) is det.
+    set_of_progvar::in) is det.
 
 delay_death_proc_body(Goal0, Goal, VarSet, BornVars0) :-
-    delay_death_goal(Goal0, Goal1, BornVars0, _, set.init, DelayedDead,
+    delay_death_goal(Goal0, Goal1, BornVars0, _, set_of_var.init, DelayedDead,
         VarSet),
     Goal1 = hlds_goal(GoalExpr, GoalInfo1),
     goal_info_get_post_deaths(GoalInfo1, PostDeaths1),
-    set.union(PostDeaths1, DelayedDead, PostDeaths),
+    set_of_var.union(PostDeaths1, DelayedDead, PostDeaths),
     goal_info_set_post_deaths(PostDeaths, GoalInfo1, GoalInfo),
     Goal = hlds_goal(GoalExpr, GoalInfo).
 
 :- pred delay_death_goal(hlds_goal::in, hlds_goal::out,
-    set_of_var::in, set_of_var::out,
-    set_of_var::in, set_of_var::out, prog_varset::in) is det.
+    set_of_progvar::in, set_of_progvar::out,
+    set_of_progvar::in, set_of_progvar::out, prog_varset::in) is det.
 
 delay_death_goal(Goal0, Goal, !BornVars, !DelayedDead, VarSet) :-
     Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
@@ -1148,10 +1151,10 @@
     goal_info_get_pre_deaths(GoalInfo0, PreDeaths0),
     BornVars0 = !.BornVars,
 
-    set.union(PreBirths, !BornVars),
-    set.divide(var_is_named(VarSet), PreDeaths0,
+    set_of_var.union(PreBirths, !BornVars),
+    set_of_var.divide(var_is_named(VarSet), PreDeaths0,
         PreDelayedDead, UnnamedPreDeaths),
-    set.union(PreDelayedDead, !DelayedDead),
+    set_of_var.union(PreDelayedDead, !DelayedDead),
     goal_info_set_pre_deaths(UnnamedPreDeaths, GoalInfo0, GoalInfo1),
 
     delay_death_goal_expr(GoalExpr0, GoalExpr, GoalInfo1, GoalInfo2,
@@ -1160,12 +1163,13 @@
     goal_info_get_post_births(GoalInfo2, PostBirths),
     goal_info_get_post_deaths(GoalInfo2, PostDeaths2),
 
-    set.union(PostBirths, !BornVars),
-    set.divide(var_is_named(VarSet), PostDeaths2,
+    set_of_var.union(PostBirths, !BornVars),
+    set_of_var.divide(var_is_named(VarSet), PostDeaths2,
         PostDelayedDead, UnnamedPostDeaths),
-    set.union(PostDelayedDead, !DelayedDead),
-    set.divide_by_set(BornVars0, !.DelayedDead, !:DelayedDead, ToBeKilled),
-    set.union(UnnamedPostDeaths, ToBeKilled, PostDeaths),
+    set_of_var.union(PostDelayedDead, !DelayedDead),
+    set_of_var.divide_by_set(BornVars0, !.DelayedDead,
+        !:DelayedDead, ToBeKilled),
+    set_of_var.union(UnnamedPostDeaths, ToBeKilled, PostDeaths),
     goal_info_set_post_deaths(PostDeaths, GoalInfo2, GoalInfo),
     Goal = hlds_goal(GoalExpr, GoalInfo).
 
@@ -1176,8 +1180,8 @@
 
 :- pred delay_death_goal_expr(hlds_goal_expr::in, hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    set_of_var::in, set_of_var::out,
-    set_of_var::in, set_of_var::out, prog_varset::in) is det.
+    set_of_progvar::in, set_of_progvar::out,
+    set_of_progvar::in, set_of_progvar::out, prog_varset::in) is det.
 
 delay_death_goal_expr(!GoalExpr, !GoalInfo, !BornVars, !DelayedDead, VarSet) :-
     (
@@ -1240,8 +1244,8 @@
             DelayedDeadCond, DelayedDeadThen, VarSet),
         delay_death_goal(Else0, Else1, BornVars0, BornVarsElse,
             DelayedDead0, DelayedDeadElse, VarSet),
-        set.intersect(BornVarsThen, BornVarsElse, BornVars),
-        set.intersect(DelayedDeadThen, DelayedDeadElse, DelayedDead),
+        set_of_var.intersect(BornVarsThen, BornVarsElse, BornVars),
+        set_of_var.intersect(DelayedDeadThen, DelayedDeadElse, DelayedDead),
         Then = kill_excess_delayed_dead_goal(DelayedDead,
             Then1 - DelayedDeadThen),
         !:BornVars = BornVars,
@@ -1265,8 +1269,8 @@
     ).
 
 :- pred delay_death_conj(list(hlds_goal)::in, list(hlds_goal)::out,
-    set_of_var::in, set_of_var::out,
-    set_of_var::in, set_of_var::out, prog_varset::in) is det.
+    set_of_progvar::in, set_of_progvar::out,
+    set_of_progvar::in, set_of_progvar::out, prog_varset::in) is det.
 
 delay_death_conj([], [], !BornVars, !DelayedDead, _).
 delay_death_conj([Goal0 | Goals0], [Goal | Goals], !BornVars, !DelayedDead,
@@ -1275,8 +1279,8 @@
     delay_death_conj(Goals0, Goals, !BornVars, !DelayedDead, VarSet).
 
 :- pred delay_death_par_conj(list(hlds_goal)::in, list(hlds_goal)::out,
-    set_of_var::in, set_of_var::out,
-    set_of_var::in, set_of_var::out, prog_varset::in) is det.
+    set_of_progvar::in, set_of_progvar::out,
+    set_of_progvar::in, set_of_progvar::out, prog_varset::in) is det.
 
 delay_death_par_conj([], [], !BornVars, !DelayedDead, _).
 delay_death_par_conj([Goal0 | Goals0], [Goal | Goals],
@@ -1285,13 +1289,13 @@
         DelayedDead0, DelayedDeadGoal, VarSet),
     delay_death_par_conj(Goals0, Goals, BornVars0, BornVarsGoals,
         DelayedDead0, DelayedDeadGoals, VarSet),
-    set.union(BornVarsGoal, BornVarsGoals, BornVars),
-    set.union(DelayedDeadGoal, DelayedDeadGoals, DelayedDead).
+    set_of_var.union(BornVarsGoal, BornVarsGoals, BornVars),
+    set_of_var.union(DelayedDeadGoal, DelayedDeadGoals, DelayedDead).
 
 :- pred delay_death_disj(list(hlds_goal)::in,
-    assoc_list(hlds_goal, set_of_var)::out,
-    set_of_var::in, set_of_var::in, prog_varset::in,
-    maybe(pair(set_of_var))::out) is det.
+    assoc_list(hlds_goal, set_of_progvar)::out,
+    set_of_progvar::in, set_of_progvar::in, prog_varset::in,
+    maybe(pair(set_of_progvar))::out) is det.
 
 delay_death_disj([], [], _, _, _, no).
 delay_death_disj([Goal0 | Goals0], [Goal - DelayedDeadGoal | Goals],
@@ -1302,17 +1306,17 @@
         MaybeBornVarsDelayedDead),
     (
         MaybeBornVarsDelayedDead = yes(BornVarsGoals - DelayedDeadGoals),
-        set.intersect(BornVarsGoal, BornVarsGoals, BornVars),
-        set.intersect(DelayedDeadGoal, DelayedDeadGoals, DelayedDead)
+        set_of_var.intersect(BornVarsGoal, BornVarsGoals, BornVars),
+        set_of_var.intersect(DelayedDeadGoal, DelayedDeadGoals, DelayedDead)
     ;
         MaybeBornVarsDelayedDead = no,
         BornVars = BornVarsGoal,
         DelayedDead = DelayedDeadGoal
     ).
 
-:- pred delay_death_cases(list(case)::in, assoc_list(case, set_of_var)::out,
-    set_of_var::in, set_of_var::in, prog_varset::in,
-    maybe(pair(set_of_var))::out) is det.
+:- pred delay_death_cases(list(case)::in, assoc_list(case, set_of_progvar)::out,
+    set_of_progvar::in, set_of_progvar::in, prog_varset::in,
+    maybe(pair(set_of_progvar))::out) is det.
 
 delay_death_cases([], [], _, _, _, no).
 delay_death_cases([Case0 | Cases0], [Case - DelayedDeadGoal | Cases],
@@ -1325,8 +1329,8 @@
         MaybeBornVarsDelayedDead),
     (
         MaybeBornVarsDelayedDead = yes(BornVarsCases - DelayedDeadCases),
-        set.intersect(BornVarsGoal, BornVarsCases, BornVars),
-        set.intersect(DelayedDeadGoal, DelayedDeadCases, DelayedDead)
+        set_of_var.intersect(BornVarsGoal, BornVarsCases, BornVars),
+        set_of_var.intersect(DelayedDeadGoal, DelayedDeadCases, DelayedDead)
     ;
         MaybeBornVarsDelayedDead = no,
         BornVars = BornVarsGoal,
@@ -1337,26 +1341,26 @@
 % branched control structure to make sure that all branches kill the same
 % set of variables.
 
-:- func kill_excess_delayed_dead_goal(set_of_var,
-    pair(hlds_goal, set_of_var)) = hlds_goal.
+:- func kill_excess_delayed_dead_goal(set_of_progvar,
+    pair(hlds_goal, set_of_progvar)) = hlds_goal.
 
 kill_excess_delayed_dead_goal(FinalDelayedDead, Goal0 - DelayedDead0) = Goal :-
-    set.difference(DelayedDead0, FinalDelayedDead, ToBeKilled),
+    set_of_var.difference(DelayedDead0, FinalDelayedDead, ToBeKilled),
     Goal0 = hlds_goal(GoalExpr, GoalInfo0),
     goal_info_get_post_deaths(GoalInfo0, PostDeath0),
-    set.union(PostDeath0, ToBeKilled, PostDeath),
+    set_of_var.union(PostDeath0, ToBeKilled, PostDeath),
     goal_info_set_post_deaths(PostDeath, GoalInfo0, GoalInfo),
     Goal = hlds_goal(GoalExpr, GoalInfo).
 
-:- func kill_excess_delayed_dead_case(set_of_var,
-    pair(case, set_of_var)) = case.
+:- func kill_excess_delayed_dead_case(set_of_progvar,
+    pair(case, set_of_progvar)) = case.
 
 kill_excess_delayed_dead_case(FinalDelayedDead, Case0 - DelayedDead0) = Case :-
     Case0 = case(MainConsId, OtherConsIds, Goal0),
-    set.difference(DelayedDead0, FinalDelayedDead, ToBeKilled),
+    set_of_var.difference(DelayedDead0, FinalDelayedDead, ToBeKilled),
     Goal0 = hlds_goal(GoalExpr, GoalInfo0),
     goal_info_get_post_deaths(GoalInfo0, PostDeath0),
-    set.union(PostDeath0, ToBeKilled, PostDeath),
+    set_of_var.union(PostDeath0, ToBeKilled, PostDeath),
     goal_info_set_post_deaths(PostDeath, GoalInfo0, GoalInfo),
     Goal = hlds_goal(GoalExpr, GoalInfo),
     Case = case(MainConsId, OtherConsIds, Goal).
@@ -1365,8 +1369,8 @@
 %-----------------------------------------------------------------------------%
 
 :- pred detect_resume_points_in_goal(hlds_goal::in, hlds_goal::out,
-    set_of_var::in, set_of_var::out, live_info::in,
-    set_of_var::in) is det.
+    set_of_progvar::in, set_of_progvar::out, live_info::in,
+    set_of_progvar::in) is det.
 
 detect_resume_points_in_goal(Goal0, Goal, !Liveness, LiveInfo, ResumeVars0) :-
     Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
@@ -1375,8 +1379,8 @@
     goal_info_get_post_deaths(GoalInfo0, PostDeaths0),
     goal_info_get_post_births(GoalInfo0, PostBirths0),
 
-    set.difference(!.Liveness, PreDeaths0, !:Liveness),
-    set.union(PreBirths0, !Liveness),
+    set_of_var.difference(!.Liveness, PreDeaths0, !:Liveness),
+    set_of_var.union(PreBirths0, !Liveness),
 
     (
         GoalExpr0 = conj(ConjType, Goals0),
@@ -1418,11 +1422,11 @@
         % of the else part and attach this set to the condition.
         Else0 = hlds_goal(_ElseExpr0, ElseInfo0),
         goal_info_get_pre_deaths(ElseInfo0, ElsePreDeath0),
-        set.difference(Liveness0, ElsePreDeath0, CondResumeVars0),
+        set_of_var.difference(Liveness0, ElsePreDeath0, CondResumeVars0),
         maybe_complete_with_typeinfos(LiveInfo, CondResumeVars0,
             CondResumeVars1),
         % ResumeVars0 should already have been completed.
-        set.union(CondResumeVars1, ResumeVars0, CondResumeVars),
+        set_of_var.union(CondResumeVars1, ResumeVars0, CondResumeVars),
 
         detect_resume_points_in_goal(Cond0, Cond1, Liveness0, LivenessCond,
             LiveInfo, CondResumeVars),
@@ -1441,7 +1445,7 @@
         ->
             CondResumeLocs = resume_locs_orig_only
         ;
-            set.empty(CondResumeVars)
+            set_of_var.is_empty(CondResumeVars)
         ->
             % There is no difference between orig_only and stack_only when
             % there are no resume variables, but some parts of code_info
@@ -1473,7 +1477,7 @@
             LiveInfo, ResumeVars0),
         maybe_complete_with_typeinfos(LiveInfo, Liveness, CompletedLiveness),
         % ResumeVars0 should already have been completed.
-        set.union(CompletedLiveness, ResumeVars0, ResumeVars1),
+        set_of_var.union(CompletedLiveness, ResumeVars0, ResumeVars1),
         detect_resume_points_in_goal(SubGoal0, SubGoal1, Liveness0, _Liveness,
             LiveInfo, ResumeVars1),
 
@@ -1499,8 +1503,8 @@
         GoalExpr0 = scope(Reason, SubGoal0),
         ( Reason = from_ground_term(TermVar, from_ground_term_construct) ->
             maybe_complete_with_typeinfos(LiveInfo,
-                set.make_singleton_set(TermVar), CompletedTermVars),
-            set.union(CompletedTermVars, !Liveness),
+                set_of_var.make_singleton(TermVar), CompletedTermVars),
+            set_of_var.union(CompletedTermVars, !Liveness),
 
             % There are no resume points in these scopes.
             SubGoal = SubGoal0
@@ -1523,12 +1527,12 @@
     ),
 
     Goal = hlds_goal(GoalExpr, GoalInfo0),
-    set.difference(!.Liveness, PostDeaths0, !:Liveness),
-    set.union(PostBirths0, !Liveness).
+    set_of_var.difference(!.Liveness, PostDeaths0, !:Liveness),
+    set_of_var.union(PostBirths0, !Liveness).
 
 :- pred detect_resume_points_in_conj(list(hlds_goal)::in, list(hlds_goal)::out,
-    set_of_var::in, set_of_var::out,
-    live_info::in, set_of_var::in) is det.
+    set_of_progvar::in, set_of_progvar::out,
+    live_info::in, set_of_progvar::in) is det.
 
 detect_resume_points_in_conj([], [], !Liveness, _, _).
 detect_resume_points_in_conj([Goal0 | Goals0], [Goal | Goals],
@@ -1553,8 +1557,8 @@
     % needed by a non-last disjunct.
     %
 :- pred detect_resume_points_in_non_disj(list(hlds_goal)::in,
-    list(hlds_goal)::out, set_of_var::in, set_of_var::out,
-    live_info::in, set_of_var::in, set_of_var::out) is det.
+    list(hlds_goal)::out, set_of_progvar::in, set_of_progvar::out,
+    live_info::in, set_of_progvar::in, set_of_progvar::out) is det.
 
 detect_resume_points_in_non_disj([], _, _, _, _, _, _) :-
     unexpected($module, $pred, "empty nondet disjunction").
@@ -1578,11 +1582,11 @@
     ).
 
 :- pred detect_resume_points_in_pruned_disj(list(hlds_goal)::in,
-    list(hlds_goal)::out, set_of_var::in, set_of_var::out,
-    live_info::in, set_of_var::in, set_of_var::out) is det.
+    list(hlds_goal)::out, set_of_progvar::in, set_of_progvar::out,
+    live_info::in, set_of_progvar::in, set_of_progvar::out) is det.
 
 detect_resume_points_in_pruned_disj([], [], !Liveness, _, _, Needed) :-
-    set.init(Needed).
+    Needed = set_of_var.init.
 detect_resume_points_in_pruned_disj([Goal0 | Goals0], [Goal | Goals],
         Liveness0, Liveness, LiveInfo, ResumeVars0, Needed) :-
     Goal0 = hlds_goal(_, GoalInfo0),
@@ -1609,16 +1613,16 @@
     ).
 
 :- pred detect_resume_points_in_non_last_disjunct(hlds_goal::in,hlds_goal::out,
-    bool::in, set_of_var::in, set_of_var::in, live_info::in,
-    set_of_var::in, set_of_var::out,
-    set_of_var::in, set_of_var::out) is det.
+    bool::in, set_of_progvar::in, set_of_progvar::in, live_info::in,
+    set_of_progvar::in, set_of_progvar::out,
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 detect_resume_points_in_non_last_disjunct(Goal0, Goal, MayUseOrigOnly,
         Liveness0, LivenessRest, LiveInfo, ResumeVars0,
         Liveness, NeededRest, Needed) :-
     % We must save a variable across this disjunct if it is needed
     % in a later disjunct or in an enclosing resume point
-    set.union(NeededRest, ResumeVars0, ResumeVars1),
+    set_of_var.union(NeededRest, ResumeVars0, ResumeVars1),
     detect_resume_points_in_goal(Goal0, Goal1, Liveness0, Liveness,
         LiveInfo, ResumeVars1),
 
@@ -1645,16 +1649,16 @@
 
     Goal = hlds_goal(_, GoalInfo),
     goal_info_get_pre_deaths(GoalInfo, PreDeaths),
-    set.difference(Liveness0, PreDeaths, NeededFirst),
+    set_of_var.difference(Liveness0, PreDeaths, NeededFirst),
     maybe_complete_with_typeinfos(LiveInfo, NeededFirst, CompletedNeededFirst),
     % NeededRest has already been completed.
-    set.union(CompletedNeededFirst, NeededRest, Needed),
+    set_of_var.union(CompletedNeededFirst, NeededRest, Needed),
 
     require_equal(Liveness, LivenessRest, "disjunction", LiveInfo).
 
 :- pred detect_resume_points_in_last_disjunct(hlds_goal::in, hlds_goal::out,
-    set_of_var::in, set_of_var::out, live_info::in,
-    set_of_var::in, set_of_var::out) is det.
+    set_of_progvar::in, set_of_progvar::out, live_info::in,
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 detect_resume_points_in_last_disjunct(Goal0, Goal, Liveness0, Liveness,
         LiveInfo, ResumeVars0, CompletedNeeded) :-
@@ -1662,12 +1666,12 @@
         LiveInfo, ResumeVars0),
     Goal = hlds_goal(_, GoalInfo),
     goal_info_get_pre_deaths(GoalInfo, PreDeaths),
-    set.difference(Liveness0, PreDeaths, Needed),
+    set_of_var.difference(Liveness0, PreDeaths, Needed),
     maybe_complete_with_typeinfos(LiveInfo, Needed, CompletedNeeded).
 
 :- pred detect_resume_points_in_cases(list(case)::in, list(case)::out,
-    set_of_var::in, set_of_var::out,
-    live_info::in, set_of_var::in) is det.
+    set_of_progvar::in, set_of_progvar::out,
+    live_info::in, set_of_progvar::in) is det.
 
 detect_resume_points_in_cases([], [], !Liveness, _, _).
 detect_resume_points_in_cases([Case0 | Cases0], [Case | Cases],
@@ -1687,8 +1691,8 @@
     ).
 
 :- pred detect_resume_points_in_par_conj(list(hlds_goal)::in,
-    list(hlds_goal)::out, set_of_var::in, set_of_var::out,
-    live_info::in, set_of_var::in) is det.
+    list(hlds_goal)::out, set_of_progvar::in, set_of_progvar::out,
+    live_info::in, set_of_progvar::in) is det.
 
 detect_resume_points_in_par_conj([], [], !Liveness, _, _).
 detect_resume_points_in_par_conj([Goal0 | Goals0], [Goal | Goals],
@@ -1698,16 +1702,16 @@
     detect_resume_points_in_par_conj(Goals0, Goals,
         Liveness0, _LivenessRest, LiveInfo, ResumeVars0).
 
-:- pred require_equal(set_of_var::in, set_of_var::in, string::in,
+:- pred require_equal(set_of_progvar::in, set_of_progvar::in, string::in,
     live_info::in) is det.
 
 require_equal(LivenessFirst, LivenessRest, GoalType, LiveInfo) :-
-    ( set.equal(LivenessFirst, LivenessRest) ->
+    ( set_of_var.equal(LivenessFirst, LivenessRest) ->
         true
     ;
         VarSet = LiveInfo ^ li_varset,
-        set.to_sorted_list(LivenessFirst, FirstVars),
-        set.to_sorted_list(LivenessRest, RestVars),
+        FirstVars = set_of_var.to_sorted_list(LivenessFirst),
+        RestVars  = set_of_var.to_sorted_list(LivenessRest),
         FirstNames = mercury_vars_to_string(VarSet, yes, FirstVars),
         RestNames = mercury_vars_to_string(VarSet, yes, RestVars),
         Msg = "branches of " ++ GoalType ++ " disagree on liveness\n" ++
@@ -1723,7 +1727,7 @@
     proc_info_get_argmodes(ProcInfo, Modes),
     proc_info_get_vartypes(ProcInfo, VarTypes),
     map.apply_to_list(Vars, VarTypes, Types),
-    set.init(!:Liveness),
+    !:Liveness = set_of_var.init,
     ( initial_liveness_2(Vars, Modes, Types, ModuleInfo, !Liveness) ->
         true
     ;
@@ -1738,22 +1742,22 @@
 
     module_info_get_globals(ModuleInfo, Globals),
     proc_info_get_goal(ProcInfo, hlds_goal(_Goal, GoalInfo)),
-    NonLocals0 = goal_info_get_code_gen_nonlocals(GoalInfo),
+    NonLocals0 = set_to_bitset(goal_info_get_code_gen_nonlocals(GoalInfo)),
     module_info_pred_info(ModuleInfo, PredId, PredInfo),
     proc_info_get_rtti_varmaps(ProcInfo, RttiVarMaps),
     body_should_use_typeinfo_liveness(PredInfo, Globals, TypeinfoLiveness),
     maybe_complete_with_typeinfo_vars(NonLocals0, TypeinfoLiveness, VarTypes,
         RttiVarMaps, NonLocals),
-    set.intersect(!.Liveness, NonLocals, !:Liveness).
+    set_of_var.intersect(!.Liveness, NonLocals, !:Liveness).
 
 :- pred initial_liveness_2(list(prog_var)::in, list(mer_mode)::in,
     list(mer_type)::in, module_info::in,
-    set_of_var::in, set_of_var::out) is semidet.
+    set_of_progvar::in, set_of_progvar::out) is semidet.
 
 initial_liveness_2([], [], [], _ModuleInfo, !Liveness).
 initial_liveness_2([V | Vs], [M | Ms], [T | Ts], ModuleInfo, !Liveness) :-
     ( mode_to_arg_mode(ModuleInfo, M, T, top_in) ->
-        set.insert(V, !Liveness)
+        set_of_var.insert(V, !Liveness)
     ;
         true
     ),
@@ -1765,7 +1769,7 @@
     % of the procedure (i.e. its output arguments).
     %
 :- pred initial_deadness(proc_info::in, live_info::in, module_info::in,
-    set_of_var::out) is det.
+    set_of_progvar::out) is det.
 
 initial_deadness(ProcInfo, LiveInfo, ModuleInfo, Deadness) :-
     % The output arguments are all in the initial deadness.
@@ -1775,29 +1779,29 @@
     % to these.
     proc_info_get_vartypes(ProcInfo, VarTypes),
     proc_info_get_rtti_varmaps(ProcInfo, RttiVarMaps),
-    maybe_complete_with_typeinfo_vars(Deadness0,
+    maybe_complete_with_typeinfo_vars(set_to_bitset(Deadness0),
         LiveInfo ^ li_typeinfo_liveness, VarTypes, RttiVarMaps, Deadness).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-:- pred add_liveness_after_goal(hlds_goal::in, set_of_var::in,
+:- pred add_liveness_after_goal(hlds_goal::in, set_of_progvar::in,
     hlds_goal::out) is det.
 
 add_liveness_after_goal(Goal0, Residue, Goal) :-
     Goal0 = hlds_goal(GoalExpr, GoalInfo0),
     goal_info_get_post_births(GoalInfo0, PostBirths0),
-    set.union(PostBirths0, Residue, PostBirths),
+    set_of_var.union(PostBirths0, Residue, PostBirths),
     goal_info_set_post_births(PostBirths, GoalInfo0, GoalInfo),
     Goal = hlds_goal(GoalExpr, GoalInfo).
 
-:- pred add_deadness_before_goal(set_of_var::in,
+:- pred add_deadness_before_goal(set_of_progvar::in,
     hlds_goal::in, hlds_goal::out) is det.
 
 add_deadness_before_goal(Residue, Goal0, Goal) :-
     Goal0 = hlds_goal(GoalExpr, GoalInfo0),
     goal_info_get_pre_deaths(GoalInfo0, PreDeaths0),
-    set.union(PreDeaths0, Residue, PreDeaths),
+    set_of_var.union(PreDeaths0, Residue, PreDeaths),
     goal_info_set_pre_deaths(PreDeaths, GoalInfo0, GoalInfo),
     Goal = hlds_goal(GoalExpr, GoalInfo).
 
@@ -1813,7 +1817,7 @@
     % We don't handle the aliasing part yet.
     %
 :- pred find_value_giving_occurrences(list(prog_var)::in, live_info::in,
-    instmap_delta::in, set_of_var::in, set_of_var::out) is det.
+    instmap_delta::in, set_of_progvar::in, set_of_progvar::out) is det.
 
 find_value_giving_occurrences([], _, _, !ValueVars).
 find_value_giving_occurrences([Var | Vars], LiveInfo, InstMapDelta,
@@ -1825,7 +1829,7 @@
         ModuleInfo = LiveInfo ^ li_module_info,
         mode_to_arg_mode(ModuleInfo, (free -> Inst), Type, top_out)
     ->
-        set.insert(Var, !ValueVars)
+        set_of_var.insert(Var, !ValueVars)
     ;
         true
     ),
@@ -1837,15 +1841,15 @@
     % typeinfo vars for the nonlocals.
     %
 :- pred get_nonlocals_and_typeinfos(live_info::in,
-    hlds_goal_info::in, set_of_var::out, set_of_var::out) is det.
+    hlds_goal_info::in, set_of_progvar::out, set_of_progvar::out) is det.
 
 get_nonlocals_and_typeinfos(LiveInfo, GoalInfo,
         NonLocals, CompletedNonLocals) :-
-    NonLocals = goal_info_get_code_gen_nonlocals(GoalInfo),
+    NonLocals = set_to_bitset(goal_info_get_code_gen_nonlocals(GoalInfo)),
     maybe_complete_with_typeinfos(LiveInfo, NonLocals, CompletedNonLocals).
 
 :- pred maybe_complete_with_typeinfos(live_info::in,
-    set_of_var::in, set_of_var::out) is det.
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 maybe_complete_with_typeinfos(LiveInfo, Vars0, Vars) :-
     maybe_complete_with_typeinfo_vars(Vars0, LiveInfo ^ li_typeinfo_liveness,
Index: compiler/lookup_switch.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/lookup_switch.m,v
retrieving revision 1.91
diff -u -b -r1.91 lookup_switch.m
--- compiler/lookup_switch.m	23 May 2011 05:08:05 -0000	1.91
+++ compiler/lookup_switch.m	17 Jul 2011 23:17:49 -0000
@@ -52,10 +52,10 @@
 :- import_module ll_backend.code_info.
 :- import_module ll_backend.llds.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module list.
 :- import_module map.
-:- import_module set.
 
 %-----------------------------------------------------------------------------%
 
@@ -72,7 +72,7 @@
                 % for each case.
                 lsi_field_types         :: list(llds_type),
 
-                lsi_liveness            :: set(prog_var)
+                lsi_liveness            :: set_of_progvar
             ).
 
 :- pred record_lookup_for_tagged_cons_id_int(soln_consts(rval)::in,
@@ -154,8 +154,8 @@
     % solutions table.
     %
 :- pred generate_code_for_all_kinds(list(case_kind)::in, int::in,
-    list(prog_var)::in, set(prog_var)::in, label::in, abs_store_map::in,
-    set(prog_var)::in, add_trail_ops::in, lval::in, rval::in,
+    list(prog_var)::in, set_of_progvar::in, label::in, abs_store_map::in,
+    set_of_progvar::in, add_trail_ops::in, lval::in, rval::in,
     branch_end::in, branch_end::out, llds_code::out,
     code_info::in, code_info::out) is det.
 
@@ -182,6 +182,7 @@
 :- import_module maybe.
 :- import_module pair.
 :- import_module require.
+:- import_module set.
 :- import_module std_util.
 :- import_module string.
 
@@ -200,7 +201,7 @@
     remember_position(!.CI, CurPos),
     generate_constants_for_lookup_switch(RecordLookupForTaggedConsId,
         TaggedCases, OutVars, ArmNonLocals, StoreMap, Liveness,
-        map.init, CaseSolnMap, !MaybeEnd, set.init, ResumeVars,
+        map.init, CaseSolnMap, !MaybeEnd, set_of_var.init, ResumeVars,
         no, GoalsMayModifyTrail, !CI),
     map.to_assoc_list(CaseSolnMap, CaseSolns),
     reset_to_position(CurPos, !CI),
@@ -228,13 +229,13 @@
 :- pred generate_constants_for_lookup_switch(
     record_switch_lookup(Key)::in(record_switch_lookup),
     list(tagged_case)::in, list(prog_var)::in, set(prog_var)::in,
-    abs_store_map::in, set(prog_var)::out,
+    abs_store_map::in, set_of_progvar::out,
     map(Key, soln_consts(rval))::in, map(Key, soln_consts(rval))::out,
-    branch_end::in, branch_end::out, set(prog_var)::in, set(prog_var)::out,
+    branch_end::in, branch_end::out, set_of_progvar::in, set_of_progvar::out,
     bool::in, bool::out, code_info::in, code_info::out) is semidet.
 
 generate_constants_for_lookup_switch(_RecordLookupForTaggedConsId,
-        [], _Vars, _ArmNonLocals, _StoreMap, set.init, !IndexMap,
+        [], _Vars, _ArmNonLocals, _StoreMap, set_of_var.init, !IndexMap,
         !MaybeEnd, !ResumeVars, !GoalsMayModifyTrail, !CI).
 generate_constants_for_lookup_switch(RecordLookupForTaggedConsId,
         [TaggedCase | TaggedCases], Vars, ArmNonLocals, StoreMap, Liveness,
@@ -264,7 +265,7 @@
             goal_info_get_resume_point(FirstDisjunctGoalInfo, ThisResumePoint),
             (
                 ThisResumePoint = resume_point(ThisResumeVars, _),
-                set.union(ThisResumeVars, !ResumeVars)
+                set_of_var.union(ThisResumeVars, !ResumeVars)
             ;
                 ThisResumePoint = no_resume_point
             ),
@@ -388,7 +389,7 @@
 :- pred generate_simple_int_lookup_switch(rval::in, abs_store_map::in,
     int::in, int::in, assoc_list(int, list(rval))::in,
     list(prog_var)::in, list(llds_type)::in, need_bit_vec_check::in,
-    set(prog_var)::in, llds_code::out, code_info::in, code_info::out) is det.
+    set_of_progvar::in, llds_code::out, code_info::in, code_info::out) is det.
 
 generate_simple_int_lookup_switch(IndexRval, StoreMap, StartVal, EndVal,
         CaseValues, OutVars, OutTypes, NeedBitVecCheck, Liveness, Code, !CI) :-
@@ -486,9 +487,9 @@
 
 :- pred generate_several_soln_int_lookup_switch(rval::in, label::in,
     abs_store_map::in, int::in, int::in,
-    assoc_list(int, soln_consts(rval))::in, set(prog_var)::in,
+    assoc_list(int, soln_consts(rval))::in, set_of_progvar::in,
     add_trail_ops::in, list(prog_var)::in, list(llds_type)::in,
-    need_bit_vec_check::in, set(prog_var)::in,
+    need_bit_vec_check::in, set_of_progvar::in,
     branch_end::in, branch_end::out, llds_code::out,
     code_info::in, code_info::out) is det.
 
@@ -591,8 +592,8 @@
 case_kind_to_string(kind_several_solns) = "kind_several_solns".
 
 :- pred generate_code_for_each_kind(list(case_kind)::in, int::in,
-    list(prog_var)::in, set(prog_var)::in, position_info::in,
-    label::in, abs_store_map::in, set(prog_var)::in, add_trail_ops::in,
+    list(prog_var)::in, set_of_progvar::in, position_info::in,
+    label::in, abs_store_map::in, set_of_progvar::in, add_trail_ops::in,
     lval::in, lval::in, lval::in, rval::in,
     branch_end::in, branch_end::out, llds_code::out,
     code_info::in, code_info::out) is det.
@@ -632,7 +633,7 @@
         % The code below is modelled on the code in disj_gen, but is
         % specialized for the situation here.
 
-        produce_vars(ResumeVars, ResumeMap, FlushCode, !CI),
+        produce_vars(to_sorted_list(ResumeVars), ResumeMap, FlushCode, !CI),
         MinOffsetColumnRval = const(llconst_int(NumPrevColumns)),
         MaxOffsetColumnRval = const(llconst_int(NumPrevColumns + 1)),
         SaveSlotsCode = from_list([
@@ -653,8 +654,8 @@
 
         % Generate code for the non-last disjunct.
 
-        make_resume_point(ResumeVars, resume_locs_stack_only,
-            ResumeMap, ResumePoint, !CI),
+        make_resume_point(set_of_var.to_sorted_list(ResumeVars),
+            resume_locs_stack_only, ResumeMap, ResumePoint, !CI),
         effect_resume_point(ResumePoint, model_non, UpdateRedoipCode, !CI),
         generate_offset_assigns(OutVars, NumPrevColumns + 2, BaseReg, !CI),
         flush_resume_vars_to_stack(FirstFlushResumeVarsCode, !CI),
Index: compiler/lookup_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/lookup_util.m,v
retrieving revision 1.16
diff -u -b -r1.16 lookup_util.m
--- compiler/lookup_util.m	23 May 2011 05:08:05 -0000	1.16
+++ compiler/lookup_util.m	10 Jul 2011 19:57:48 -0000
@@ -24,9 +24,9 @@
 :- import_module ll_backend.code_info.
 :- import_module ll_backend.llds.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module list.
-:- import_module set.
 
     % Figure out which variables are bound in the goal.
     % We do this by using the current instmap and the instmap delta in the
@@ -50,11 +50,11 @@
     %
 :- pred generate_constants_for_arm(hlds_goal::in, list(prog_var)::in,
     abs_store_map::in, list(rval)::out, branch_end::in, branch_end::out,
-    set(prog_var)::out, code_info::in, code_info::out) is semidet.
+    set_of_progvar::out, code_info::in, code_info::out) is semidet.
 
 :- pred generate_constants_for_disjunct(hlds_goal::in,
     list(prog_var)::in, abs_store_map::in, list(rval)::out,
-    branch_end::in, branch_end::out, set(prog_var)::out,
+    branch_end::in, branch_end::out, set_of_progvar::out,
     code_info::in, code_info::out) is semidet.
 
 :- pred generate_constants_for_disjuncts(list(hlds_goal)::in,
@@ -67,7 +67,7 @@
     % to their indicated locations, and end the current branch, updating
     % !MaybeEnd in the process.
     %
-:- pred set_liveness_and_end_branch(abs_store_map::in, set(prog_var)::in,
+:- pred set_liveness_and_end_branch(abs_store_map::in, set_of_progvar::in,
     branch_end::in, branch_end::out, llds_code::out,
     code_info::in, code_info::out) is det.
 
@@ -90,6 +90,7 @@
 :- import_module int.
 :- import_module maybe.
 :- import_module require.
+:- import_module set.
 
 figure_out_output_vars(CI, GoalInfo, OutVars) :-
     InstMapDelta = goal_info_get_instmap_delta(GoalInfo),
@@ -122,7 +123,7 @@
 
 :- pred do_generate_constants_for_arm(hlds_goal::in, list(prog_var)::in,
     abs_store_map::in, bool::in, list(rval)::out,
-    branch_end::in, branch_end::out, set(prog_var)::out,
+    branch_end::in, branch_end::out, set_of_progvar::out,
     code_info::in, code_info::out) is semidet.
 
 do_generate_constants_for_arm(Goal, Vars, StoreMap, SetToUnknown, CaseRvals,
@@ -206,7 +207,7 @@
     % values aside.
     get_forward_live_vars(!.CI, OldLiveness),
     set_forward_live_vars(Liveness, !CI),
-    set.difference(OldLiveness, Liveness, DeadVars),
+    set_of_var.difference(OldLiveness, Liveness, DeadVars),
     maybe_make_vars_forward_dead(DeadVars, no, !CI),
     generate_branch_end(StoreMap, !MaybeEnd, BranchEndCode, !CI).
 
Index: compiler/matching.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/matching.m,v
retrieving revision 1.18
diff -u -b -r1.18 matching.m
--- compiler/matching.m	23 May 2011 05:08:05 -0000	1.18
+++ compiler/matching.m	9 Jul 2011 23:32:36 -0000
@@ -21,6 +21,7 @@
 
 :- import_module parse_tree.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module bool.
 :- import_module list.
@@ -76,9 +77,9 @@
     % and RealizedCostNodes give the benefit and cost nodes realized
     % by this choice.
     %
-:- pred find_via_cell_vars(prog_var::in, set(prog_var)::in, bool::in,
-    set(prog_var)::in, list(set(prog_var))::in, matching_params::in,
-    set(benefit_node)::out, set(cost_node)::out, set(prog_var)::out)
+:- pred find_via_cell_vars(prog_var::in, set_of_progvar::in, bool::in,
+    set_of_progvar::in, list(set_of_progvar)::in, matching_params::in,
+    set(benefit_node)::out, set(cost_node)::out, set_of_progvar::out)
     is det.
 
 %-----------------------------------------------------------------------------%
@@ -155,18 +156,18 @@
     InclAllCand = MatchingParams ^ include_all_candidates,
     (
         InclAllCand = no,
-        AllSegmentVars = set.union_list([BeforeFlush | AfterFlush]),
-        set.intersect(CandidateFieldVars, AllSegmentVars,
+        AllSegmentVars = set_of_var.union_list([BeforeFlush | AfterFlush]),
+        set_of_var.intersect(CandidateFieldVars, AllSegmentVars,
             OccurringCandidateFieldVars),
-        set.difference(CandidateFieldVars, OccurringCandidateFieldVars,
+        set_of_var.difference(CandidateFieldVars, OccurringCandidateFieldVars,
             NonOccurringCandidateFieldVars)
     ;
         InclAllCand = yes,
         OccurringCandidateFieldVars = CandidateFieldVars,
-        NonOccurringCandidateFieldVars = set.init
+        NonOccurringCandidateFieldVars = set_of_var.init
     ),
-    set.to_sorted_list(OccurringCandidateFieldVars,
-        OccurringCandidateFieldVarList),
+    OccurringCandidateFieldVarList =
+        set_of_var.to_sorted_list(OccurringCandidateFieldVars),
     list.filter_map(simplify_segment(CellVar, OccurringCandidateFieldVars),
         AfterFlush, FilteredAfterFlush),
     NumberedAfterFlush = number_segments(2, FilteredAfterFlush),
@@ -214,12 +215,12 @@
         % the .err file.
         % Nullified = no
     ;
-        ViaCellOccurringVars = set.init
+        ViaCellOccurringVars = set_of_var.init
         % Uncomment if you want to dump performance information into
         % the .err file.
         % Nullified = yes
     ),
-    ViaCellVars = set.union(ViaCellOccurringVars,
+    ViaCellVars = set_of_var.union(ViaCellOccurringVars,
         NonOccurringCandidateFieldVars).
     % Uncomment if you want to dump performance information into
     % the .err file.
@@ -237,15 +238,15 @@
     % SegmentVars, them simplify_segment succeeds after removing the
     % non-candidate variables from SegmentVars0.
     %
-:- pred simplify_segment(prog_var::in, set(prog_var)::in, set(prog_var)::in,
-    set(prog_var)::out) is semidet.
+:- pred simplify_segment(prog_var::in, set_of_progvar::in, set_of_progvar::in,
+    set_of_progvar::out) is semidet.
 
 simplify_segment(CellVar, CandidateArgVars, SegmentVars0, SegmentVars) :-
-    \+ set.member(CellVar, SegmentVars0),
-    SegmentVars = set.intersect(SegmentVars0, CandidateArgVars).
+    \+ set_of_var.member(SegmentVars0, CellVar),
+    SegmentVars = set_of_var.intersect(SegmentVars0, CandidateArgVars).
 
-:- func number_segments(int, list(set(prog_var))) =
-    assoc_list(int, set(prog_var)).
+:- func number_segments(int, list(set_of_progvar)) =
+    assoc_list(int, set_of_progvar).
 
 number_segments(_N, []) = [].
 number_segments(N, [Segment | Segments]) =
@@ -256,8 +257,8 @@
     % Find_costs_benefits computes the costs and benefits of accessing the
     % given field variable FieldVar via the cell variable CellVar.
     %
-:- func find_costs_benefits(prog_var, set(prog_var),
-    assoc_list(int, set(prog_var)), bool, matching_params, prog_var)
+:- func find_costs_benefits(prog_var, set_of_progvar,
+    assoc_list(int, set_of_progvar), bool, matching_params, prog_var)
     = field_costs_benefits.
 
 find_costs_benefits(CellVar, BeforeFlush, AfterFlush, CellVarFlushedLater,
@@ -271,7 +272,7 @@
         CostOps = [cell_var_store | CostOps0]
     ),
     BenefitOps0 = [field_var_store(FieldVar)],
-    ( set.member(CellVar, BeforeFlush) ->
+    ( set_of_var.member(BeforeFlush, CellVar) ->
         BenefitOps = BenefitOps0
     ;
         BenefitOps = [field_var_load(FieldVar) | BenefitOps0]
@@ -294,13 +295,13 @@
     FieldCostsBenefits = field_costs_benefits(FieldVar,
         CostNodeSet, BenefitNodeSet).
 
-:- pred find_cell_var_loads_for_field(assoc_list(int, set(prog_var))::in,
+:- pred find_cell_var_loads_for_field(assoc_list(int, set_of_progvar)::in,
     prog_var::in, list(cost_operation)::in, list(cost_operation)::out) is det.
 
 find_cell_var_loads_for_field([], _, !CostOps).
 find_cell_var_loads_for_field([SegmentNum - SegmentVars | AfterFlush],
         FieldVar, !CostOps) :-
-    ( set.member(FieldVar, SegmentVars) ->
+    ( set_of_var.member(SegmentVars, FieldVar) ->
         !:CostOps = [cell_var_load(SegmentNum) | !.CostOps]
     ;
         true
@@ -615,16 +616,16 @@
 %-----------------------------------------------------------------------------%
 
 :- func compute_via_cell_vars(list(field_costs_benefits), set(benefit_node))
-    = set(prog_var).
+    = set_of_progvar.
 
-compute_via_cell_vars([], _MarkedBenefits) = set.init.
+compute_via_cell_vars([], _MarkedBenefits) = set_of_var.init.
 compute_via_cell_vars([FieldCostsBenefits | FieldsCostsBenefits],
         MarkedBenefits) = ViaCellVars :-
     ViaCellVars1 = compute_via_cell_vars(FieldsCostsBenefits, MarkedBenefits),
     FieldCostsBenefits = field_costs_benefits(FieldVar, _, FieldBenefits),
     set.intersect(FieldBenefits, MarkedBenefits, MarkedFieldBenefits),
-    ( set.empty(MarkedFieldBenefits) ->
-        set.insert(FieldVar, ViaCellVars1, ViaCellVars)
+    ( set.is_empty(MarkedFieldBenefits) ->
+        set_of_var.insert(FieldVar, ViaCellVars1, ViaCellVars)
     ; set.equal(MarkedFieldBenefits, FieldBenefits) ->
         ViaCellVars = ViaCellVars1
     ;
@@ -672,9 +673,9 @@
     % the call to dump_results, and two lines computing one of the arguments of
     % that call.
     %
-:- pred dump_results(prog_var::in, set(prog_var)::in, list(prog_var)::in,
-    set(prog_var)::in, bool::in, set(prog_var)::in,
-    assoc_list(int, set(prog_var))::in,
+:- pred dump_results(prog_var::in, set_of_progvar::in, list(prog_var)::in,
+    set_of_progvar::in, bool::in, set_of_progvar::in,
+    assoc_list(int, set_of_progvar)::in,
     list(benefit_node)::in, list(benefit_operation)::in,
     list(cost_node)::in, list(cost_operation)::in, io::di, io::uo) is det.
 
@@ -682,9 +683,9 @@
         ViaCellOccurringVars, Nullified, BeforeFlush, AfterFlush,
         BenefitNodes, BenefitOps, CostNodes, CostOps, !IO) :-
     term.var_to_int(CellVar, CellVarInt),
-    set.to_sorted_list(CandidateFieldVars, CandidateFieldVarList),
-    set.to_sorted_list(ViaCellOccurringVars, ViaCellVarList),
-    set.to_sorted_list(BeforeFlush, BeforeFlushList),
+    CandidateFieldVarList = set_of_var.to_sorted_list(CandidateFieldVars),
+    ViaCellVarList = set_of_var.to_sorted_list(ViaCellOccurringVars),
+    BeforeFlushList = set_of_var.to_sorted_list(BeforeFlush),
     list.map(term.var_to_int, CandidateFieldVarList,
         CandidateFieldVarInts),
     list.map(term.var_to_int, OccurringCandidateFieldVarList,
@@ -730,11 +731,11 @@
     io.write(CostOps, !IO),
     io.write_string("\n%\n", !IO).
 
-:- pred dump_after_flush(pair(int, set(prog_var))::in,
+:- pred dump_after_flush(pair(int, set_of_progvar)::in,
     io::di, io::uo) is det.
 
 dump_after_flush(SegmentNum - SegmentVars, !IO) :-
-    set.to_sorted_list(SegmentVars, SegmentVarList),
+    SegmentVarList = set_of_var.to_sorted_list(SegmentVars),
     list.map(term.var_to_int, SegmentVarList, SegmentVarInts),
     io.write_string("% after flush, segment ", !IO),
     io.write_int(SegmentNum, !IO),
@@ -744,12 +745,12 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred realized_costs_benefits(set(prog_var)::in, field_costs_benefits::in)
+:- pred realized_costs_benefits(set_of_progvar::in, field_costs_benefits::in)
     is semidet.
 
 realized_costs_benefits(ViaCellOccurringVars, FieldCostsBenefits) :-
     FieldCostsBenefits = field_costs_benefits(FieldVar, _, _),
-    set.member(FieldVar, ViaCellOccurringVars).
+    set_of_var.member(ViaCellOccurringVars, FieldVar).
 
 :- func project_benefit_op(benefit_node) = benefit_operation.
 
Index: compiler/parse_tree.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/parse_tree.m,v
retrieving revision 1.23
diff -u -b -r1.23 parse_tree.m
--- compiler/parse_tree.m	16 Sep 2010 00:39:06 -0000	1.23
+++ compiler/parse_tree.m	9 Jul 2011 19:50:39 -0000
@@ -20,9 +20,9 @@
 :- import_module mdbcomp.
 
 % The parse tree data type itself.
-% The parse tree is split in two.  The parts defined in prog_item are
-% needed only by the frontend of the compiler, the parts in prog_data
-% are needed throughout.
+% The parse tree is split in two. The parts defined in prog_item are needed
+% only by the frontend of the compiler, the parts in prog_data are needed
+% throughout.
 :- include_module prog_item.
 :- include_module prog_data.
 
@@ -45,6 +45,9 @@
 :- include_module mercury_to_mercury.
 :- include_module prog_out.
 
+% Utility data structures.
+:- include_module set_of_var.
+
 % Utility routines.
 :- include_module builtin_lib_types.
 :- include_module error_util.
Index: compiler/pd_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/pd_util.m,v
retrieving revision 1.83
diff -u -b -r1.83 pd_util.m
--- compiler/pd_util.m	23 May 2011 05:08:09 -0000	1.83
+++ compiler/pd_util.m	10 Jul 2011 21:36:06 -0000
@@ -168,6 +168,7 @@
 :- import_module libs.options.
 :- import_module parse_tree.error_util.
 :- import_module parse_tree.prog_type.
+:- import_module parse_tree.set_of_var.
 :- import_module transform_hlds.constraint.
 :- import_module transform_hlds.pd_debug.
 
@@ -795,7 +796,7 @@
         proc_info_get_vartypes(!.ProcInfo, VarTypes0),
         proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
         implicitly_quantify_goal_general(ordinary_nonlocals_no_lambda,
-            NonLocals, _, Goal0, Goal, VarSet0, VarSet,
+            set_to_bitset(NonLocals), _, Goal0, Goal, VarSet0, VarSet,
             VarTypes0, VarTypes, RttiVarMaps0, RttiVarMaps),
         proc_info_set_varset(VarSet, !ProcInfo),
         proc_info_set_vartypes(VarTypes, !ProcInfo),
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.366
diff -u -b -r1.366 polymorphism.m
--- compiler/polymorphism.m	25 May 2011 09:10:44 -0000	1.366
+++ compiler/polymorphism.m	10 Jul 2011 21:35:24 -0000
@@ -412,6 +412,7 @@
 :- import_module parse_tree.prog_mode.
 :- import_module parse_tree.prog_type.
 :- import_module parse_tree.prog_type_subst.
+:- import_module parse_tree.set_of_var.
 
 :- import_module assoc_list.
 :- import_module bool.
@@ -2244,7 +2245,7 @@
         poly_info_get_rtti_varmaps(!.Info, RttiVarMaps0),
         OutsideVars = proc_arg_vector_to_set(HeadVars),
         implicitly_quantify_goal_general(ordinary_nonlocals_maybe_lambda,
-            OutsideVars, _Warnings, Goal0, Goal,
+            set_to_bitset(OutsideVars), _Warnings, Goal0, Goal,
             VarSet0, VarSet, VarTypes0, VarTypes, RttiVarMaps0, RttiVarMaps),
         poly_info_set_varset_and_types(VarSet, VarTypes, !Info),
         poly_info_set_rtti_varmaps(RttiVarMaps, !Info)
@@ -2280,7 +2281,7 @@
             ExistQVars, NonLocalsPlusArgs, NewOutsideVars),
         set.union(NonLocals, NewOutsideVars, OutsideVars),
         implicitly_quantify_goal_general(ordinary_nonlocals_maybe_lambda,
-            OutsideVars, _Warnings, !Goal,
+            set_to_bitset(OutsideVars), _Warnings, !Goal,
             VarSet0, VarSet, VarTypes0, VarTypes, RttiVarMaps0, RttiVarMaps),
         poly_info_set_varset_and_types(VarSet, VarTypes, !Info),
         poly_info_set_rtti_varmaps(RttiVarMaps, !Info)
Index: compiler/pragma_c_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/pragma_c_gen.m,v
retrieving revision 1.122
diff -u -b -r1.122 pragma_c_gen.m
--- compiler/pragma_c_gen.m	23 May 2011 05:08:09 -0000	1.122
+++ compiler/pragma_c_gen.m	10 Jul 2011 11:45:34 -0000
@@ -73,6 +73,7 @@
 :- import_module ll_backend.llds_out.llds_out_code_addr.
 :- import_module parse_tree.prog_foreign.
 :- import_module parse_tree.prog_type.
+:- import_module parse_tree.set_of_var.
 
 :- import_module bool.
 :- import_module cord.
@@ -464,7 +465,7 @@
     foreign_proc_select_out_args(CArgs, OutCArgs),
 
     goal_info_get_post_deaths(GoalInfo, PostDeaths),
-    set.init(DeadVars0),
+    DeadVars0 = set_of_var.init,
     find_dead_input_vars(InCArgs, PostDeaths, DeadVars0, DeadVars),
 
     % Generate code to <save live variables on stack>.
@@ -941,14 +942,14 @@
 
 %---------------------------------------------------------------------------%
 
-:- pred find_dead_input_vars(list(c_arg)::in, set(prog_var)::in,
-    set(prog_var)::in, set(prog_var)::out) is det.
+:- pred find_dead_input_vars(list(c_arg)::in, set_of_progvar::in,
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 find_dead_input_vars([], _, !DeadVars).
 find_dead_input_vars([Arg | Args], PostDeaths, !DeadVars) :-
     Arg = c_arg(Var, _MaybeName, _Type, _BoxPolicy, _ArgInfo),
-    ( set.member(Var, PostDeaths) ->
-        set.insert(Var, !DeadVars)
+    ( set_of_var.member(PostDeaths, Var) ->
+        set_of_var.insert(Var, !DeadVars)
     ;
         true
     ),
Index: compiler/proc_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/proc_gen.m,v
retrieving revision 1.49
diff -u -b -r1.49 proc_gen.m
--- compiler/proc_gen.m	7 Jul 2011 00:47:29 -0000	1.49
+++ compiler/proc_gen.m	10 Jul 2011 17:00:26 -0000
@@ -99,6 +99,7 @@
 :- import_module mdbcomp.program_representation.
 :- import_module parse_tree.prog_data.
 :- import_module parse_tree.prog_out.
+:- import_module parse_tree.set_of_var.
 
 :- import_module assoc_list.
 :- import_module bool.
@@ -724,7 +725,7 @@
 
         generate_resume_point(ResumePoint, ResumeCode, !CI),
         resume_point_vars(ResumePoint, ResumeVarList),
-        set.list_to_set(ResumeVarList, ResumeVars),
+        ResumeVars = set_of_var.list_to_set(ResumeVarList),
         set_forward_live_vars(ResumeVars, !CI),
         % XXX A context that gives the end of the procedure definition
         % would be better than ProcContext.
@@ -771,7 +772,7 @@
 
         generate_resume_point(ResumePoint, ResumeCode, !CI),
         resume_point_vars(ResumePoint, ResumeVarList),
-        set.list_to_set(ResumeVarList, ResumeVars),
+        ResumeVars = set_of_var.list_to_set(ResumeVarList),
         set_forward_live_vars(ResumeVars, !CI),
         % XXX A context that gives the end of the procedure definition
         % would be better than ProcContext.
Index: compiler/prog_type.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_type.m,v
retrieving revision 1.55
diff -u -b -r1.55 prog_type.m
--- compiler/prog_type.m	5 Jul 2011 03:34:33 -0000	1.55
+++ compiler/prog_type.m	18 Jul 2011 01:33:44 -0000
@@ -21,6 +21,7 @@
 :- import_module libs.globals.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module bool.
 :- import_module list.
@@ -254,6 +255,8 @@
 :- func remove_typeinfo_vars(vartypes, list(prog_var)) = list(prog_var).
 :- func remove_typeinfo_vars_from_set(vartypes, set(prog_var))
     = set(prog_var).
+:- func remove_typeinfo_vars_from_set_of_var(vartypes, set_of_progvar)
+    = set_of_progvar.
 
     % In the forwards mode, this predicate checks for a "new " prefix
     % at the start of the functor name, and removes it if present;
@@ -828,23 +831,35 @@
         TypeInfoVarsList, NonTypeInfoVarsList).
 
 remove_typeinfo_vars(VarTypes, VarsList) = NonTypeInfoVarsList :-
-    split_vars_typeinfo_no_typeinfo(VarsList, VarTypes, _,
-        NonTypeInfoVarsList).
+    list.negated_filter(var_is_introduced_type_info_type(VarTypes),
+        VarsList, NonTypeInfoVarsList).
 
-remove_typeinfo_vars_from_set(VarTypes, VarsSet) =
-    set.from_list(remove_typeinfo_vars(VarTypes,
-        set.to_sorted_list(VarsSet))).
+remove_typeinfo_vars_from_set(VarTypes, VarsSet0) = VarsSet :-
+    VarsList0 = set.to_sorted_list(VarsSet0),
+    VarsList = remove_typeinfo_vars(VarTypes, VarsList0),
+    VarsSet = set.sorted_list_to_set(VarsList).
+
+remove_typeinfo_vars_from_set_of_var(VarTypes, VarsSet0) = VarsSet :-
+    % XXX could be done more efficiently, operating directly on the set_of_var
+    VarsList0 = set_of_var.to_sorted_list(VarsSet0),
+    VarsList = remove_typeinfo_vars(VarTypes, VarsList0),
+    VarsSet = set_of_var.sorted_list_to_set(VarsList).
 
 :- pred split_vars_typeinfo_no_typeinfo(list(prog_var)::in,
     vartypes::in, list(prog_var)::out, list(prog_var)::out) is det.
 
 split_vars_typeinfo_no_typeinfo(VarsList, VarTypes, TypeInfoVarsList,
         NonTypeInfoVarsList) :-
-    list.filter((pred(Var::in) is semidet :-
-            Type = map.lookup(VarTypes, Var),
-            is_introduced_type_info_type(Type)),
+    list.filter(var_is_introduced_type_info_type(VarTypes),
         VarsList, TypeInfoVarsList, NonTypeInfoVarsList).
 
+:- pred var_is_introduced_type_info_type(vartypes::in, prog_var::in)
+    is semidet.
+
+var_is_introduced_type_info_type(VarTypes, Var) :-
+    map.lookup(VarTypes, Var, Type),
+    is_introduced_type_info_type(Type).
+
 remove_new_prefix(unqualified(Name0), unqualified(Name)) :-
     string.append("new ", Name, Name0).
 remove_new_prefix(qualified(Module, Name0), qualified(Module, Name)) :-
Index: compiler/quantification.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/quantification.m,v
retrieving revision 1.144
diff -u -b -r1.144 quantification.m
--- compiler/quantification.m	23 May 2011 05:08:10 -0000	1.144
+++ compiler/quantification.m	10 Jul 2011 19:54:25 -0000
@@ -37,6 +37,7 @@
 :- import_module hlds.hlds_pred.
 :- import_module hlds.hlds_rtti.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module list.
 :- import_module set.
@@ -76,7 +77,7 @@
     vartypes::in, vartypes::out, rtti_varmaps::in, rtti_varmaps::out) is det.
 
 :- pred implicitly_quantify_goal_general(nonlocals_to_recompute::in,
-    set(prog_var)::in, list(quant_warning)::out,
+    set_of_progvar::in, list(quant_warning)::out,
     hlds_goal::in, hlds_goal::out, prog_varset::in, prog_varset::out,
     vartypes::in, vartypes::out, rtti_varmaps::in, rtti_varmaps::out) is det.
 
@@ -112,7 +113,6 @@
 :- import_module pair.
 :- import_module require.
 :- import_module string.
-:- import_module tree_bitset.
 :- import_module term.
 :- import_module varset.
 
@@ -157,29 +157,17 @@
     %
 :- type quant_info
     --->    quant_info(
-                qi_outside              :: set_of_var,
-                qi_quant_vars           :: set_of_var,
-                qi_lambda_outside       :: set_of_var,
-                qi_nonlocals            :: set_of_var,
-                qi_seen                 :: set_of_var,
+                qi_outside              :: set_of_progvar,
+                qi_quant_vars           :: set_of_progvar,
+                qi_lambda_outside       :: set_of_progvar,
+                qi_nonlocals            :: set_of_progvar,
+                qi_seen                 :: set_of_progvar,
                 qi_varset               :: prog_varset,
                 qi_vartypes             :: vartypes,
                 qi_warnings             :: list(quant_warning),
                 qi_rtti_varmaps         :: rtti_varmaps
             ).
 
-    % Until we have user-specified pretty printing in the debugger,
-    % debugging will be much easier if set_of_var is just `set(prog_var)'.
-    % None of the calls to the predicates and functions operating on sets
-    % in this module are module qualified so we can switch representation
-    % just by changing this line.
-    %
-    % If you want to debug a new set representation, just import a version
-    % of the bitset_tester module from tests/hard_coded, and make set_of_var
-    % equivalent to the bitset_tester type.
-% :- type set_of_var == set(prog_var).
-:- type set_of_var == tree_bitset(prog_var).
-
 :- inst ordinary_nonlocals_maybe_lambda
     --->    ordinary_nonlocals_maybe_lambda.
 :- inst ordinary_nonlocals_no_lambda
@@ -191,7 +179,7 @@
 
 implicitly_quantify_clause_body_general(NonLocalsToRecompute, HeadVars,
         Warnings, !Goal, !Varset, !VarTypes, !RttiVarMaps) :-
-    list_to_set(HeadVars, OutsideVars),
+    OutsideVars = set_of_var.list_to_set(HeadVars),
     implicitly_quantify_goal_general(NonLocalsToRecompute, OutsideVars,
         Warnings, !Goal, !Varset, !VarTypes, !RttiVarMaps).
 
@@ -236,7 +224,7 @@
     ).
 
 :- pred implicitly_quantify_goal_2(nonlocals_to_recompute,
-    set(prog_var), list(quant_warning),
+    set_of_progvar, list(quant_warning),
     hlds_goal, hlds_goal, prog_varset, prog_varset,
     vartypes, vartypes, rtti_varmaps, rtti_varmaps) is det.
 :- mode implicitly_quantify_goal_2(in(ordinary_nonlocals_maybe_lambda),
@@ -246,9 +234,8 @@
 :- mode implicitly_quantify_goal_2(in(code_gen_nonlocals_no_lambda),
     in, out, in, out, in, out, in, out, in, out) is det.
 
-implicitly_quantify_goal_2(NonLocalsToRecompute, OutsideVars0, Warnings,
+implicitly_quantify_goal_2(NonLocalsToRecompute, OutsideVars, Warnings,
         !Goal, !Varset, !VarTypes, !RttiVarMaps) :-
-    OutsideVars = set_to_bitset(OutsideVars0),
     init_quant_info(OutsideVars, !.Varset, !.VarTypes, !.RttiVarMaps,
         QuantInfo0),
     implicitly_quantify_goal_quant_info(!Goal, NonLocalsToRecompute,
@@ -279,7 +266,7 @@
     intersect(SeenVars, LocalVars, RenameVars),
     % If there are any variables that are local to the goal
     % which we have come across before, then we rename them apart.
-    ( empty(RenameVars) ->
+    ( set_of_var.is_empty(RenameVars) ->
         GoalExpr = GoalExpr1,
         GoalInfo1 = GoalInfo0
     ;
@@ -322,7 +309,7 @@
     % goal_infos in the usual (no warning) case.
     %
 :- pred implicitly_quantify_goal_quant_info_2(hlds_goal_expr, hlds_goal_expr,
-    hlds_goal_info, nonlocals_to_recompute, set_of_var,
+    hlds_goal_info, nonlocals_to_recompute, set_of_progvar,
     quant_info, quant_info).
 :- mode implicitly_quantify_goal_quant_info_2(in, out, in,
     in(ordinary_nonlocals_maybe_lambda), out, in, out) is det.
@@ -358,7 +345,7 @@
         NonLocalVarSets0 = [],
         implicitly_quantify_disj(Goals0, Goals, NonLocalsToRecompute, !Info,
             NonLocalVarSets0, NonLocalVarSets),
-        union_list(NonLocalVarSets, NonLocalVars),
+        set_of_var.union_list(NonLocalVarSets, NonLocalVars),
         set_nonlocals(NonLocalVars, !Info),
         GoalExpr = disj(Goals),
         goal_expr_vars_bitset(NonLocalsToRecompute, GoalExpr0,
@@ -370,8 +357,8 @@
             NonLocalVarSets0, NonLocalVarSets),
         % The switch variable is guaranteed to be nonlocal to the switch, since
         % it has to be bound elsewhere, so we put it in the nonlocals here.
-        union_list(NonLocalVarSets, NonLocalVars0),
-        insert(Var, NonLocalVars0, NonLocalVars),
+        set_of_var.union_list(NonLocalVarSets, NonLocalVars0),
+        set_of_var.insert(Var, NonLocalVars0, NonLocalVars),
         set_nonlocals(NonLocalVars, !Info),
         GoalExpr = switch(Var, Det, Cases),
         goal_expr_vars_bitset(NonLocalsToRecompute, GoalExpr0,
@@ -384,8 +371,8 @@
         % unchanged).
         get_quant_vars(!.Info, QuantVars),
         get_outside(!.Info, OutsideVars),
-        union(OutsideVars, QuantVars, OutsideVars1),
-        QuantVars1 = init,
+        set_of_var.union(OutsideVars, QuantVars, OutsideVars1),
+        QuantVars1 = set_of_var.init,
         set_quant_vars(QuantVars1, !Info),
         set_outside(OutsideVars1, !Info),
         implicitly_quantify_goal_quant_info(SubGoal0, SubGoal,
@@ -405,13 +392,13 @@
         get_quant_vars(!.Info, QuantVars),
         get_outside(!.Info, OutsideVars),
         get_lambda_outside(!.Info, LambdaOutsideVars),
-        QVars = list_to_set(Vars0),
+        QVars = set_of_var.list_to_set(Vars0),
         % Rename apart those variables that are quantified to the cond and then
         % of the i-t-e that occur outside the i-t-e.
-        intersect(OutsideVars, QVars, RenameVars1),
-        intersect(LambdaOutsideVars, QVars, RenameVars2),
-        union(RenameVars1, RenameVars2, RenameVars),
-        ( empty(RenameVars) ->
+        set_of_var.intersect(OutsideVars, QVars, RenameVars1),
+        set_of_var.intersect(LambdaOutsideVars, QVars, RenameVars2),
+        set_of_var.union(RenameVars1, RenameVars2, RenameVars),
+        ( set_of_var.is_empty(RenameVars) ->
             Cond1 = Cond0,
             Then1 = Then0,
             Vars = Vars0
@@ -423,7 +410,7 @@
             rename_some_vars_in_goal(RenameMap, Then0, Then1),
             rename_var_list(need_not_rename, RenameMap, Vars0, Vars)
         ),
-        insert_list(Vars, QuantVars, QuantVars1),
+        set_of_var.insert_list(Vars, QuantVars, QuantVars1),
         (
             NonLocalsToRecompute = ordinary_nonlocals_maybe_lambda,
             goal_vars_both_maybe_lambda(NonLocalsToRecompute, Then1,
@@ -433,10 +420,10 @@
             ; NonLocalsToRecompute = code_gen_nonlocals_no_lambda
             ),
             goal_vars_both_no_lambda(NonLocalsToRecompute, Then1, VarsThen),
-            LambdaVarsThen = init
+            LambdaVarsThen = set_of_var.init
         ),
-        union(OutsideVars, VarsThen, OutsideVars1),
-        union(LambdaOutsideVars, LambdaVarsThen, LambdaOutsideVars1),
+        set_of_var.union(OutsideVars, VarsThen, OutsideVars1),
+        set_of_var.union(LambdaOutsideVars, LambdaVarsThen, LambdaOutsideVars1),
         set_quant_vars(QuantVars1, !Info),
         set_outside(OutsideVars1, !Info),
         set_lambda_outside(LambdaOutsideVars1, !Info),
@@ -444,7 +431,7 @@
         implicitly_quantify_goal_quant_info(Cond1, Cond, NonLocalsToRecompute,
             !Info),
         get_nonlocals(!.Info, NonLocalsCond),
-        union(OutsideVars, NonLocalsCond, OutsideVars2),
+        set_of_var.union(OutsideVars, NonLocalsCond, OutsideVars2),
         set_outside(OutsideVars2, !Info),
         set_lambda_outside(LambdaOutsideVars, !Info),
         implicitly_quantify_goal_quant_info(Then1, Then, NonLocalsToRecompute,
@@ -457,11 +444,12 @@
         GoalExpr = if_then_else([], Cond, Then, Else),
 
         get_nonlocals(!.Info, NonLocalsElse),
-        union(NonLocalsCond, NonLocalsThen, NonLocalsIfThen),
-        union(NonLocalsIfThen, NonLocalsElse, NonLocalsIfThenElse),
-        intersect(NonLocalsIfThenElse, OutsideVars, NonLocalsO),
-        intersect(NonLocalsIfThenElse, LambdaOutsideVars, NonLocalsL),
-        union(NonLocalsO, NonLocalsL, NonLocals),
+        set_of_var.union(NonLocalsCond, NonLocalsThen, NonLocalsIfThen),
+        set_of_var.union(NonLocalsIfThen, NonLocalsElse, NonLocalsIfThenElse),
+        set_of_var.intersect(NonLocalsIfThenElse, OutsideVars, NonLocalsO),
+        set_of_var.intersect(NonLocalsIfThenElse, LambdaOutsideVars,
+            NonLocalsL),
+        set_of_var.union(NonLocalsO, NonLocalsL, NonLocals),
         set_nonlocals(NonLocals, !Info),
         goal_expr_vars_bitset(NonLocalsToRecompute, GoalExpr0,
             PossiblyNonLocalGoalVars0)
@@ -528,33 +516,33 @@
             NonLocalsToRecompute, !Info),
         GoalExpr = unify(Var, UnifyRHS, Mode, Unification, UnifyContext),
         get_nonlocals(!.Info, VarsUnifyRHS),
-        insert(Var, VarsUnifyRHS, GoalVars0),
-        insert_list(TypeInfoVars, GoalVars0, GoalVars1),
+        set_of_var.insert(Var, VarsUnifyRHS, GoalVars0),
+        set_of_var.insert_list(TypeInfoVars, GoalVars0, GoalVars1),
         (
             MaybeReuseVar = yes(ReuseVar),
-            insert(ReuseVar, GoalVars1, GoalVars2)
+            set_of_var.insert(ReuseVar, GoalVars1, GoalVars2)
         ;
             MaybeReuseVar = no,
             GoalVars2 = GoalVars1
         ),
         (
             MaybeSizeVar = yes(SizeVar),
-            insert(SizeVar, GoalVars2, GoalVars3)
+            set_of_var.insert(SizeVar, GoalVars2, GoalVars3)
         ;
             MaybeSizeVar = no,
             GoalVars3 = GoalVars2
         ),
         (
             MaybeRegionVar = yes(RegionVar),
-            insert(RegionVar, GoalVars3, GoalVars)
+            set_of_var.insert(RegionVar, GoalVars3, GoalVars)
         ;
             MaybeRegionVar = no,
             GoalVars = GoalVars3
         ),
         update_seen_vars(GoalVars, !Info),
-        intersect(GoalVars, OutsideVars, NonLocalVars1),
-        intersect(GoalVars, LambdaOutsideVars, NonLocalVars2),
-        union(NonLocalVars1, NonLocalVars2, NonLocalVars),
+        set_of_var.intersect(GoalVars, OutsideVars, NonLocalVars1),
+        set_of_var.intersect(GoalVars, LambdaOutsideVars, NonLocalVars2),
+        set_of_var.union(NonLocalVars1, NonLocalVars2, NonLocalVars),
         set_nonlocals(NonLocalVars, !Info),
         goal_expr_vars_bitset(NonLocalsToRecompute, GoalExpr0,
             PossiblyNonLocalGoalVars0)
@@ -601,11 +589,12 @@
                 AllAtomicGoals = [],
                 unexpected($module, $pred, "AllAtomicGoals = []")
             ),
-            union_list(NonLocalVarSets, NonLocalVars0),
+            set_of_var.union_list(NonLocalVarSets, NonLocalVars0),
             (
                 GoalType = unknown_atomic_goal_type,
                 Outer = atomic_interface_vars(OuterDI, OuterUO),
-                insert_list([OuterDI, OuterUO], NonLocalVars0, NonLocalVars)
+                set_of_var.insert_list([OuterDI, OuterUO],
+                    NonLocalVars0, NonLocalVars)
             ;
                 ( GoalType = top_level_atomic_goal
                 ; GoalType = nested_atomic_goal
@@ -667,7 +656,7 @@
     OrElseGoals = [OrElseGoal | OrElseGoalsTail].
 
 :- pred implicitly_quantify_goal_quant_info_scope(scope_reason, hlds_goal,
-    hlds_goal_expr, hlds_goal_info, nonlocals_to_recompute, set_of_var,
+    hlds_goal_expr, hlds_goal_info, nonlocals_to_recompute, set_of_progvar,
     quant_info, quant_info).
 :- mode implicitly_quantify_goal_quant_info_scope(in, in, out, in,
     in(ordinary_nonlocals_maybe_lambda), out, in, out) is det.
@@ -691,7 +680,7 @@
         implicitly_quantify_goal_quant_info(SubGoal1, SubGoal,
             NonLocalsToRecompute, !Info),
         get_nonlocals(!.Info, NonLocals0),
-        delete_list(Vars, NonLocals0, NonLocals),
+        set_of_var.delete_list(Vars, NonLocals0, NonLocals),
         set_nonlocals(NonLocals, !Info)
     ;
         Reason0 = from_ground_term(TermVar, from_ground_term_construct),
@@ -703,7 +692,7 @@
         % will either set the kind to from_ground_term_other (or to
         % from_ground_term_deconstruct) or remove the scope altogether.
         SubGoal = SubGoal0,
-        NonLocals = make_singleton_set(TermVar),
+        NonLocals = set_of_var.make_singleton(TermVar),
         set_nonlocals(NonLocals, !Info),
         PossiblyNonLocalGoalVars0 = NonLocals
     ;
@@ -731,7 +720,7 @@
         implicitly_quantify_goal_quant_info(SubGoal1, SubGoal,
             NonLocalsToRecompute, !Info),
         get_nonlocals(!.Info, NonLocals0),
-        delete_list(Vars, NonLocals0, NonLocals),
+        set_of_var.delete_list(Vars, NonLocals0, NonLocals),
         set_nonlocals(NonLocals, !Info)
     ),
     set_quant_vars(QuantVars, !Info),
@@ -757,10 +746,10 @@
     % Rename apart all the quantified variables that occur
     % outside this goal.
     QVars = list_to_set(Vars0),
-    intersect(OutsideVars, QVars, RenameVars1),
-    intersect(LambdaOutsideVars, QVars, RenameVars2),
-    union(RenameVars1, RenameVars2, RenameVars),
-    ( empty(RenameVars) ->
+    set_of_var.intersect(OutsideVars, QVars, RenameVars1),
+    set_of_var.intersect(LambdaOutsideVars, QVars, RenameVars2),
+    set_of_var.union(RenameVars1, RenameVars2, RenameVars),
+    ( set_of_var.is_empty(RenameVars) ->
         SubGoal = SubGoal0,
         Vars = Vars0,
         Reason = Reason0
@@ -791,7 +780,7 @@
         )
     ),
     update_seen_vars(QVars, !Info),
-    insert_list(Vars, QuantVars0, QuantVars),
+    set_of_var.insert_list(Vars, QuantVars0, QuantVars),
     set_quant_vars(QuantVars, !Info).
 
 :- pred implicitly_quantify_goal_quant_info_bi_implication(
@@ -811,16 +800,16 @@
     % the quantified vars into the outside vars set, and initialize the new
     % quantified vars set to be empty (the lambda outside vars remain
     % unchanged).
-    union(OutsideVars0, QuantVars0, OutsideVars1),
-    QuantVars1 = init,
+    set_of_var.union(OutsideVars0, QuantVars0, OutsideVars1),
+    QuantVars1 = set_of_var.init,
     LambdaOutsideVars1 = LambdaOutsideVars0,
     set_quant_vars(QuantVars1, !Info),
 
     % Prepare for quantifying the LHS: add variables from the RHS to the
     % outside vars and the outside lambda vars sets.
     goal_vars_both_maybe_lambda_and_bi_impl(RHS0, RHS_Vars, RHS_LambdaVars),
-    union(OutsideVars1, RHS_Vars, LHS_OutsideVars),
-    union(LambdaOutsideVars1, RHS_LambdaVars, LHS_LambdaOutsideVars),
+    set_of_var.union(OutsideVars1, RHS_Vars, LHS_OutsideVars),
+    set_of_var.union(LambdaOutsideVars1, RHS_LambdaVars, LHS_LambdaOutsideVars),
 
     % Quantify the LHS.
     set_outside(LHS_OutsideVars, !Info),
@@ -833,7 +822,7 @@
     % outside vars. (We use the nonlocals rather than the more symmetric
     % approach of calling goal_vars on the LHS goal because it is more
     % efficient.)
-    union(OutsideVars1, LHS_NonLocalVars, RHS_OutsideVars),
+    set_of_var.union(OutsideVars1, LHS_NonLocalVars, RHS_OutsideVars),
     RHS_LambdaOutsideVars = LambdaOutsideVars1,
 
     % Quantify the RHS.
@@ -844,10 +833,10 @@
     get_nonlocals(!.Info, RHS_NonLocalVars),
 
     % Compute the nonlocals for this goal.
-    union(LHS_NonLocalVars, RHS_NonLocalVars, AllNonLocalVars),
-    intersect(AllNonLocalVars, OutsideVars0, NonLocalVarsO),
-    intersect(AllNonLocalVars, LambdaOutsideVars0, NonLocalVarsL),
-    union(NonLocalVarsO, NonLocalVarsL, NonLocalVars),
+    set_of_var.union(LHS_NonLocalVars, RHS_NonLocalVars, AllNonLocalVars),
+    set_of_var.intersect(AllNonLocalVars, OutsideVars0, NonLocalVarsO),
+    set_of_var.intersect(AllNonLocalVars, LambdaOutsideVars0, NonLocalVarsL),
+    set_of_var.union(NonLocalVarsO, NonLocalVarsL, NonLocalVars),
     set_nonlocals(NonLocalVars, !Info),
 
     % Restore the original values of various settings.
@@ -883,7 +872,7 @@
         negation(hlds_goal(conj(plain_conj, [RHS, NotLHS]), GI)),
     ReverseImplication0 = hlds_goal(ReverseImplicationExpr0, GI),
     goal_vars_bitset_maybe_lambda_and_bi_impl(ReverseImplication0, GoalVars),
-    difference(GoalVars, NonLocalVars, RenameVars),
+    set_of_var.difference(GoalVars, NonLocalVars, RenameVars),
     rename_apart(RenameVars, _, ordinary_nonlocals_maybe_lambda,
         ReverseImplication0, ReverseImplication, !Info),
 
@@ -897,9 +886,9 @@
     update_seen_vars(GoalVars, !Info),
     get_outside(!.Info, OutsideVars),
     get_lambda_outside(!.Info, LambdaOutsideVars),
-    intersect(GoalVars, OutsideVars, NonLocals1),
-    intersect(GoalVars, LambdaOutsideVars, NonLocals2),
-    union(NonLocals1, NonLocals2, NonLocals),
+    set_of_var.intersect(GoalVars, OutsideVars, NonLocals1),
+    set_of_var.intersect(GoalVars, LambdaOutsideVars, NonLocals2),
+    set_of_var.union(NonLocals1, NonLocals2, NonLocals),
     set_nonlocals(NonLocals, !Info).
 
 :- pred implicitly_quantify_unify_rhs(maybe(list(needs_update)),
@@ -916,7 +905,7 @@
         NonLocalsToRecompute, !Info) :-
     (
         !.RHS = rhs_var(X),
-        Vars = make_singleton_set(X),
+        Vars = set_of_var.make_singleton(X),
         set_nonlocals(Vars, !Info)
     ;
         !.RHS = rhs_functor(_, _, ArgVars),
@@ -942,11 +931,11 @@
         % does not assume this.
 
         get_outside(!.Info, OutsideVars0),
-        QVars = list_to_set(LambdaVars0),
+        QVars = set_of_var.list_to_set(LambdaVars0),
         % Figure out which variables have overlapping scopes because they occur
         % outside the goal and are also lambda-quantified vars.
-        intersect(OutsideVars0, QVars, RenameVars0),
-        ( empty(RenameVars0) ->
+        set_of_var.intersect(OutsideVars0, QVars, RenameVars0),
+        ( set_of_var.is_empty(RenameVars0) ->
             true
         ;
             Context = goal_info_get_context(GoalInfo0),
@@ -955,9 +944,9 @@
         % We need to rename apart any of the lambda vars that we have
         % already seen, since they are new instances.
         get_seen(!.Info, Seen0),
-        intersect(Seen0, QVars, RenameVars1),
+        set_of_var.intersect(Seen0, QVars, RenameVars1),
 
-        union(RenameVars0, RenameVars1, RenameVars),
+        set_of_var.union(RenameVars0, RenameVars1, RenameVars),
         rename_apart(RenameVars, RenameMap, NonLocalsToRecompute, Goal0, Goal1,
             !Info),
         rename_var_list(need_not_rename, RenameMap, LambdaVars0, LambdaVars),
@@ -966,18 +955,18 @@
         % so we insert the quantified vars into the outside vars set,
         % and initialize the new quantified vars set to be empty.
         get_quant_vars(!.Info, QuantVars0),
-        union(OutsideVars0, QuantVars0, OutsideVars1),
-        QuantVars = init,
+        set_of_var.union(OutsideVars0, QuantVars0, OutsideVars1),
+        QuantVars = set_of_var.init,
         set_quant_vars(QuantVars, !Info),
         % Add the lambda vars as outside vars, since they are outside of the
         % lambda goal.
-        insert_list(LambdaVars, OutsideVars1, OutsideVars),
+        set_of_var.insert_list(LambdaVars, OutsideVars1, OutsideVars),
         set_outside(OutsideVars, !Info),
         % Set the LambdaOutsideVars set to empty, because variables that occur
         % outside this lambda expression only in other lambda expressions
         % should not be considered nonlocal.
         get_lambda_outside(!.Info, LambdaOutsideVars0),
-        LambdaOutsideVars = init,
+        LambdaOutsideVars = set_of_var.init,
         set_lambda_outside(LambdaOutsideVars, !Info),
         implicitly_quantify_goal_quant_info(Goal1, Goal, NonLocalsToRecompute,
             !Info),
@@ -987,7 +976,7 @@
 
         get_nonlocals(!.Info, NonLocals0),
         % Lambda-quantified variables are local.
-        delete_list(LambdaVars, NonLocals0, NonLocals),
+        set_of_var.delete_list(LambdaVars, NonLocals0, NonLocals),
         set_quant_vars(QuantVars0, !Info),
         set_outside(OutsideVars0, !Info),
         set_lambda_outside(LambdaOutsideVars0, !Info),
@@ -1023,7 +1012,7 @@
                     "lambda term has size info")
             ),
             map.from_corresponding_lists(Args0, ArgModes0, ArgModesMap),
-            Args = to_sorted_list(NonLocals),
+            Args = set_of_var.to_sorted_list(NonLocals),
             map.apply_to_list(Args, ArgModesMap, ArgModes),
             !:Unification = construct(ConstructVar, ConsId, Args,
                 ArgModes, HowToConstruct, Uniq, SubInfo)
@@ -1040,7 +1029,7 @@
     ).
 
 :- pred implicitly_quantify_conj_maybe_lambda(list(hlds_goal), list(hlds_goal),
-    nonlocals_to_recompute, set_of_var, quant_info, quant_info).
+    nonlocals_to_recompute, set_of_progvar, quant_info, quant_info).
 :- mode implicitly_quantify_conj_maybe_lambda(in, out,
     in(ordinary_nonlocals_maybe_lambda), out, in, out) is det.
 
@@ -1052,7 +1041,7 @@
         NonLocalsToRecompute, !Info).
 
 :- pred implicitly_quantify_conj_no_lambda(list(hlds_goal), list(hlds_goal),
-    nonlocals_to_recompute, set_of_var, quant_info, quant_info).
+    nonlocals_to_recompute, set_of_progvar, quant_info, quant_info).
 :- mode implicitly_quantify_conj_no_lambda(in, out,
     in(ordinary_nonlocals_no_lambda), out, in, out) is det.
 :- mode implicitly_quantify_conj_no_lambda(in, out,
@@ -1065,14 +1054,14 @@
     implicitly_quantify_conj_no_lambda_2(FollowingVarsList, !Goals,
         NonLocalsToRecompute, !Info).
 
-:- pred implicitly_quantify_conj_maybe_lambda_2(list(pair(set_of_var)),
+:- pred implicitly_quantify_conj_maybe_lambda_2(list(pair(set_of_progvar)),
     list(hlds_goal), list(hlds_goal),
     nonlocals_to_recompute, quant_info, quant_info).
 :- mode implicitly_quantify_conj_maybe_lambda_2(in, in, out,
     in(ordinary_nonlocals_maybe_lambda), in, out) is det.
 
 implicitly_quantify_conj_maybe_lambda_2(_, [], [], _, !Info) :-
-    NonLocalVars = init,
+    NonLocalVars = set_of_var.init,
     set_nonlocals(NonLocalVars, !Info).
 implicitly_quantify_conj_maybe_lambda_2([], [_ | _], _, _, _, _) :-
     unexpected($module, $pred, "length mismatch").
@@ -1081,27 +1070,28 @@
     FollowingVarPair = FollowingVars - LambdaFollowingVars,
     get_outside(!.Info, OutsideVars),
     get_lambda_outside(!.Info, LambdaOutsideVars),
-    union(OutsideVars, FollowingVars, OutsideVars1),
-    union(LambdaOutsideVars, LambdaFollowingVars, LambdaOutsideVars1),
+    set_of_var.union(OutsideVars, FollowingVars, OutsideVars1),
+    set_of_var.union(LambdaOutsideVars, LambdaFollowingVars,
+        LambdaOutsideVars1),
     set_outside(OutsideVars1, !Info),
     set_lambda_outside(LambdaOutsideVars1, !Info),
     implicitly_quantify_goal_quant_info(Goal0, Goal, NonLocalsToRecompute,
         !Info),
     get_nonlocals(!.Info, NonLocalVars1),
-    union(OutsideVars, NonLocalVars1, OutsideVars2),
+    set_of_var.union(OutsideVars, NonLocalVars1, OutsideVars2),
     set_outside(OutsideVars2, !Info),
     set_lambda_outside(LambdaOutsideVars, !Info),
     implicitly_quantify_conj_maybe_lambda_2(FollowingVarPairs, Goals0, Goals,
         NonLocalsToRecompute, !Info),
     get_nonlocals(!.Info, NonLocalVars2),
-    union(NonLocalVars1, NonLocalVars2, NonLocalVarsConj),
-    intersect(NonLocalVarsConj, OutsideVars, NonLocalVarsO),
-    intersect(NonLocalVarsConj, LambdaOutsideVars, NonLocalVarsL),
-    union(NonLocalVarsO, NonLocalVarsL, NonLocalVars),
+    set_of_var.union(NonLocalVars1, NonLocalVars2, NonLocalVarsConj),
+    set_of_var.intersect(NonLocalVarsConj, OutsideVars, NonLocalVarsO),
+    set_of_var.intersect(NonLocalVarsConj, LambdaOutsideVars, NonLocalVarsL),
+    set_of_var.union(NonLocalVarsO, NonLocalVarsL, NonLocalVars),
     set_outside(OutsideVars, !Info),
     set_nonlocals(NonLocalVars, !Info).
 
-:- pred implicitly_quantify_conj_no_lambda_2(list(set_of_var),
+:- pred implicitly_quantify_conj_no_lambda_2(list(set_of_progvar),
     list(hlds_goal), list(hlds_goal),
     nonlocals_to_recompute, quant_info, quant_info).
 :- mode implicitly_quantify_conj_no_lambda_2(in, in, out,
@@ -1110,7 +1100,7 @@
     in(code_gen_nonlocals_no_lambda), in, out) is det.
 
 implicitly_quantify_conj_no_lambda_2(_, [], [], _, !Info) :-
-    NonLocalVars = init,
+    NonLocalVars = set_of_var.init,
     set_nonlocals(NonLocalVars, !Info).
 implicitly_quantify_conj_no_lambda_2([], [_ | _], _, _, _, _) :-
     unexpected($module, $pred, "length mismatch").
@@ -1122,19 +1112,19 @@
     implicitly_quantify_goal_quant_info(Goal0, Goal, NonLocalsToRecompute,
         !Info),
     get_nonlocals(!.Info, NonLocalVars1),
-    union(OutsideVars, NonLocalVars1, OutsideVars2),
+    set_of_var.union(OutsideVars, NonLocalVars1, OutsideVars2),
     set_outside(OutsideVars2, !Info),
     implicitly_quantify_conj_no_lambda_2(FollowingVarsList, Goals0, Goals,
         NonLocalsToRecompute, !Info),
     get_nonlocals(!.Info, NonLocalVars2),
-    union(NonLocalVars1, NonLocalVars2, NonLocalVarsConj),
-    intersect(NonLocalVarsConj, OutsideVars, NonLocalVars),
+    set_of_var.union(NonLocalVars1, NonLocalVars2, NonLocalVarsConj),
+    set_of_var.intersect(NonLocalVarsConj, OutsideVars, NonLocalVars),
     set_outside(OutsideVars, !Info),
     set_nonlocals(NonLocalVars, !Info).
 
 :- pred implicitly_quantify_disj(list(hlds_goal), list(hlds_goal),
     nonlocals_to_recompute, quant_info, quant_info,
-    list(set_of_var), list(set_of_var)).
+    list(set_of_progvar), list(set_of_progvar)).
 :- mode implicitly_quantify_disj(in, out, in(ordinary_nonlocals_maybe_lambda),
     in, out, in, out) is det.
 :- mode implicitly_quantify_disj(in, out, in(ordinary_nonlocals_no_lambda),
@@ -1155,7 +1145,7 @@
 :- pred implicitly_quantify_atomic_goals(
     list(pair(hlds_goal, atomic_interface_vars)), list(hlds_goal),
     nonlocals_to_recompute, quant_info, quant_info,
-    list(set_of_var), list(set_of_var)).
+    list(set_of_progvar), list(set_of_progvar)).
 :- mode implicitly_quantify_atomic_goals(in, out,
     in(ordinary_nonlocals_maybe_lambda), in, out, in, out) is det.
 :- mode implicitly_quantify_atomic_goals(in, out,
@@ -1174,7 +1164,7 @@
         % not inserted until the purity checking pass.
         Inner0 = atomic_interface_vars(InnerDI, InnerUO),
         get_outside(!.Info, OutsideVars0),
-        insert_list([InnerDI, InnerUO], OutsideVars0, OutsideVars),
+        set_of_var.insert_list([InnerDI, InnerUO], OutsideVars0, OutsideVars),
         set_outside(OutsideVars, !Info)
     ),
     implicitly_quantify_goal_quant_info(Goal0, Goal, NonLocalsToRecompute,
@@ -1186,7 +1176,7 @@
 
 :- pred implicitly_quantify_cases(list(case), list(case),
     nonlocals_to_recompute, quant_info, quant_info,
-    list(set_of_var), list(set_of_var)).
+    list(set_of_progvar), list(set_of_progvar)).
 :- mode implicitly_quantify_cases(in, out, in(ordinary_nonlocals_maybe_lambda),
     in, out, in, out) is det.
 :- mode implicitly_quantify_cases(in, out, in(ordinary_nonlocals_no_lambda),
@@ -1210,12 +1200,12 @@
 
     % Insert the given set of variables into the set of `seen' variables.
     %
-:- pred update_seen_vars(set_of_var::in, quant_info::in, quant_info::out)
+:- pred update_seen_vars(set_of_progvar::in, quant_info::in, quant_info::out)
     is det.
 
 update_seen_vars(NewVars, !Info) :-
     get_seen(!.Info, SeenVars0),
-    union(SeenVars0, NewVars, SeenVars),
+    set_of_var.union(SeenVars0, NewVars, SeenVars),
     set_seen(SeenVars, !Info).
 
 %-----------------------------------------------------------------------------%
@@ -1228,70 +1218,70 @@
     % second contains following variables that occur in lambda goals.
     %
 :- pred get_following_vars_maybe_lambda(nonlocals_to_recompute,
-    list(hlds_goal), list(pair(set_of_var)), set_of_var).
+    list(hlds_goal), list(pair(set_of_progvar)), set_of_progvar).
 :- mode get_following_vars_maybe_lambda(in(ordinary_nonlocals_maybe_lambda),
     in, out, out) is det.
 
-get_following_vars_maybe_lambda(_, [], [], init).
+get_following_vars_maybe_lambda(_, [], [], set_of_var.init).
 get_following_vars_maybe_lambda(NonLocalsToRecompute, [Goal | Goals],
         [Set - LambdaSet | SetPairs], PossiblyNonLocalGoalVars) :-
     get_following_vars_maybe_lambda_2(NonLocalsToRecompute, Goals,
         Set, LambdaSet, SetPairs),
-    union(Set, LambdaSet, GoalsBothSet),
+    set_of_var.union(Set, LambdaSet, GoalsBothSet),
     goal_vars_both_maybe_lambda(NonLocalsToRecompute, Goal,
         GoalSet, GoalLambdaSet),
-    union(GoalSet, GoalLambdaSet, GoalBothSet),
-    union(GoalBothSet, GoalsBothSet, PossiblyNonLocalGoalVars).
+    set_of_var.union(GoalSet, GoalLambdaSet, GoalBothSet),
+    set_of_var.union(GoalBothSet, GoalsBothSet, PossiblyNonLocalGoalVars).
 
 :- pred get_following_vars_no_lambda(nonlocals_to_recompute, list(hlds_goal),
-    list(set_of_var), set_of_var).
+    list(set_of_progvar), set_of_progvar).
 :- mode get_following_vars_no_lambda(in(ordinary_nonlocals_no_lambda),
     in, out, out) is det.
 :- mode get_following_vars_no_lambda(in(code_gen_nonlocals_no_lambda),
     in, out, out) is det.
 
-get_following_vars_no_lambda(_, [], [], init).
+get_following_vars_no_lambda(_, [], [], set_of_var.init).
 get_following_vars_no_lambda(NonLocalsToRecompute, [Goal | Goals],
         [Set | Sets], PossiblyNonLocalGoalVars) :-
     get_following_vars_no_lambda_2(NonLocalsToRecompute, Goals, Set, Sets),
     goal_vars_both_no_lambda(NonLocalsToRecompute, Goal, GoalSet),
-    union(GoalSet, Set, PossiblyNonLocalGoalVars).
+    set_of_var.union(GoalSet, Set, PossiblyNonLocalGoalVars).
 
 :- pred get_following_vars_maybe_lambda_2(nonlocals_to_recompute,
-    list(hlds_goal), set_of_var, set_of_var, list(pair(set_of_var))).
+    list(hlds_goal), set_of_progvar, set_of_progvar, list(pair(set_of_progvar))).
 :- mode get_following_vars_maybe_lambda_2(in(ordinary_nonlocals_maybe_lambda),
     in, out, out, out) is det.
 
 get_following_vars_maybe_lambda_2(_, [], Set, LambdaSet, []) :-
-    Set = init,
-    LambdaSet = init.
+    Set = set_of_var.init,
+    LambdaSet = set_of_var.init.
 get_following_vars_maybe_lambda_2(NonLocalsToRecompute, [Goal | Goals],
         Set, LambdaSet, SetPairList) :-
     get_following_vars_maybe_lambda_2(NonLocalsToRecompute, Goals,
         Set0, LambdaSet0, SetPairList0),
     goal_vars_both_maybe_lambda(NonLocalsToRecompute, Goal, Set1, LambdaSet1),
-    union(Set0, Set1, Set),
-    union(LambdaSet0, LambdaSet1, LambdaSet),
+    set_of_var.union(Set0, Set1, Set),
+    set_of_var.union(LambdaSet0, LambdaSet1, LambdaSet),
     SetPairList = [Set0 - LambdaSet0 | SetPairList0].
 
 :- pred get_following_vars_no_lambda_2(nonlocals_to_recompute, list(hlds_goal),
-    set_of_var, list(set_of_var)).
+    set_of_progvar, list(set_of_progvar)).
 :- mode get_following_vars_no_lambda_2(in(ordinary_nonlocals_no_lambda),
     in, out, out) is det.
 :- mode get_following_vars_no_lambda_2(in(code_gen_nonlocals_no_lambda),
     in, out, out) is det.
 
 get_following_vars_no_lambda_2(_, [], Set, []) :-
-    Set = init.
+    Set = set_of_var.init.
 get_following_vars_no_lambda_2(NonLocalsToRecompute, [Goal | Goals],
         Set, SetList) :-
     get_following_vars_no_lambda_2(NonLocalsToRecompute, Goals, Set0, SetList0),
     goal_vars_both_no_lambda(NonLocalsToRecompute, Goal, Set1),
-    union(Set0, Set1, Set),
+    set_of_var.union(Set0, Set1, Set),
     SetList = [Set0 | SetList0].
 
 :- pred conj_vars_maybe_lambda(nonlocals_to_recompute, list(hlds_goal),
-    set_of_var, set_of_var, set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar, set_of_progvar, set_of_progvar).
 :- mode conj_vars_maybe_lambda(in(ordinary_nonlocals_maybe_lambda),
     in, in, out, in, out) is det.
 
@@ -1304,7 +1294,7 @@
     conj_vars_maybe_lambda(NonLocalsToRecompute, Goals, !Set, !LambdaSet).
 
 :- pred conj_vars_maybe_lambda_and_bi_impl(list(hlds_goal),
-    set_of_var, set_of_var, set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar, set_of_progvar, set_of_progvar).
 :- mode conj_vars_maybe_lambda_and_bi_impl(
     in, in, out, in, out) is det.
 
@@ -1315,7 +1305,7 @@
     conj_vars_maybe_lambda_and_bi_impl(Goals, !Set, !LambdaSet).
 
 :- pred conj_vars_no_lambda(nonlocals_to_recompute, list(hlds_goal),
-    set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar).
 :- mode conj_vars_no_lambda(in(ordinary_nonlocals_no_lambda),
     in, in, out) is det.
 :- mode conj_vars_no_lambda(in(code_gen_nonlocals_no_lambda),
@@ -1328,7 +1318,7 @@
     conj_vars_no_lambda(NonLocalsToRecompute, Goals, !Set).
 
 :- pred disj_vars_maybe_lambda(nonlocals_to_recompute, list(hlds_goal),
-    set_of_var, set_of_var, set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar, set_of_progvar, set_of_progvar).
 :- mode disj_vars_maybe_lambda(in(ordinary_nonlocals_maybe_lambda),
     in, in, out, in, out) is det.
 
@@ -1337,23 +1327,23 @@
         [], GoalSets, [], GoalLambdaSets),
     (
         GoalSets = [],
-        GoalsSet = init
+        GoalsSet = set_of_var.init
     ;
         GoalSets = [_ | _],
-        union_list(GoalSets, GoalsSet)
+        set_of_var.union_list(GoalSets, GoalsSet)
     ),
     (
         GoalLambdaSets = [],
-        GoalsLambdaSet = init
+        GoalsLambdaSet = set_of_var.init
     ;
         GoalLambdaSets = [_ | _],
-        union_list(GoalLambdaSets, GoalsLambdaSet)
+        set_of_var.union_list(GoalLambdaSets, GoalsLambdaSet)
     ),
-    union(GoalsSet, !Set),
-    union(GoalsLambdaSet, !LambdaSet).
+    set_of_var.union(GoalsSet, !Set),
+    set_of_var.union(GoalsLambdaSet, !LambdaSet).
 
 :- pred disj_vars_maybe_lambda_and_bi_impl(list(hlds_goal),
-    set_of_var, set_of_var, set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar, set_of_progvar, set_of_progvar).
 :- mode disj_vars_maybe_lambda_and_bi_impl(
     in, in, out, in, out) is det.
 
@@ -1362,23 +1352,23 @@
         [], GoalSets, [], GoalLambdaSets),
     (
         GoalSets = [],
-        GoalsSet = init
+        GoalsSet = set_of_var.init
     ;
         GoalSets = [_ | _],
-        union_list(GoalSets, GoalsSet)
+        set_of_var.union_list(GoalSets, GoalsSet)
     ),
     (
         GoalLambdaSets = [],
-        GoalsLambdaSet = init
+        GoalsLambdaSet = set_of_var.init
     ;
         GoalLambdaSets = [_ | _],
-        union_list(GoalLambdaSets, GoalsLambdaSet)
+        set_of_var.union_list(GoalLambdaSets, GoalsLambdaSet)
     ),
-    union(GoalsSet, !Set),
-    union(GoalsLambdaSet, !LambdaSet).
+    set_of_var.union(GoalsSet, !Set),
+    set_of_var.union(GoalsLambdaSet, !LambdaSet).
 
 :- pred disj_vars_no_lambda(nonlocals_to_recompute, list(hlds_goal),
-    set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar).
 :- mode disj_vars_no_lambda(in(ordinary_nonlocals_no_lambda),
     in, in, out) is det.
 :- mode disj_vars_no_lambda(in(code_gen_nonlocals_no_lambda),
@@ -1388,15 +1378,16 @@
     compute_disj_vars_no_lambda(NonLocalsToRecompute, Goals, [], GoalSets),
     (
         GoalSets = [],
-        GoalsSet = init
+        GoalsSet = set_of_var.init
     ;
         GoalSets = [_ | _],
-        union_list(GoalSets, GoalsSet)
+        set_of_var.union_list(GoalSets, GoalsSet)
     ),
-    union(GoalsSet, !Set).
+    set_of_var.union(GoalsSet, !Set).
 
 :- pred compute_disj_vars_maybe_lambda(nonlocals_to_recompute, list(hlds_goal),
-    list(set_of_var), list(set_of_var), list(set_of_var), list(set_of_var)).
+    list(set_of_progvar), list(set_of_progvar),
+    list(set_of_progvar), list(set_of_progvar)).
 :- mode compute_disj_vars_maybe_lambda(in(ordinary_nonlocals_maybe_lambda),
     in, in, out, in, out) is det.
 
@@ -1411,7 +1402,8 @@
         !Sets, !LambdaSets).
 
 :- pred compute_disj_vars_maybe_lambda_and_bi_impl(list(hlds_goal),
-    list(set_of_var), list(set_of_var), list(set_of_var), list(set_of_var)).
+    list(set_of_progvar), list(set_of_progvar),
+    list(set_of_progvar), list(set_of_progvar)).
 :- mode compute_disj_vars_maybe_lambda_and_bi_impl(
     in, in, out, in, out) is det.
 
@@ -1424,7 +1416,7 @@
     compute_disj_vars_maybe_lambda_and_bi_impl(Goals, !Sets, !LambdaSets).
 
 :- pred compute_disj_vars_no_lambda(nonlocals_to_recompute, list(hlds_goal),
-    list(set_of_var), list(set_of_var)).
+    list(set_of_progvar), list(set_of_progvar)).
 :- mode compute_disj_vars_no_lambda(in(ordinary_nonlocals_no_lambda),
     in, in, out) is det.
 :- mode compute_disj_vars_no_lambda(in(code_gen_nonlocals_no_lambda),
@@ -1437,7 +1429,7 @@
     compute_disj_vars_no_lambda(NonLocalsToRecompute, Goals, !Sets).
 
 :- pred case_vars_maybe_lambda(nonlocals_to_recompute, list(case),
-    set_of_var, set_of_var, set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar, set_of_progvar, set_of_progvar).
 :- mode case_vars_maybe_lambda(in(ordinary_nonlocals_maybe_lambda),
     in, in, out, in, out) is det.
 
@@ -1449,20 +1441,20 @@
         unexpected($module, $pred, "no cases (1)")
     ;
         CaseSets = [_ | _],
-        union_list(CaseSets, CasesSet)
+        set_of_var.union_list(CaseSets, CasesSet)
     ),
     (
         CaseLambdaSets = [],
         unexpected($module, $pred, "no cases (2)")
     ;
         CaseLambdaSets = [_ | _],
-        union_list(CaseLambdaSets, CasesLambdaSet)
+        set_of_var.union_list(CaseLambdaSets, CasesLambdaSet)
     ),
-    union(CasesSet, !Set),
-    union(CasesLambdaSet, !LambdaSet).
+    set_of_var.union(CasesSet, !Set),
+    set_of_var.union(CasesLambdaSet, !LambdaSet).
 
 :- pred case_vars_maybe_lambda_and_bi_impl(list(case),
-    set_of_var, set_of_var, set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar, set_of_progvar, set_of_progvar).
 :- mode case_vars_maybe_lambda_and_bi_impl(
     in, in, out, in, out) is det.
 
@@ -1474,20 +1466,20 @@
         unexpected($module, $pred, "no cases (1)")
     ;
         CaseSets = [_ | _],
-        union_list(CaseSets, CasesSet)
+        set_of_var.union_list(CaseSets, CasesSet)
     ),
     (
         CaseLambdaSets = [],
         unexpected($module, $pred, "no cases (2)")
     ;
         CaseLambdaSets = [_ | _],
-        union_list(CaseLambdaSets, CasesLambdaSet)
+        set_of_var.union_list(CaseLambdaSets, CasesLambdaSet)
     ),
-    union(CasesSet, !Set),
-    union(CasesLambdaSet, !LambdaSet).
+    set_of_var.union(CasesSet, !Set),
+    set_of_var.union(CasesLambdaSet, !LambdaSet).
 
 :- pred case_vars_no_lambda(nonlocals_to_recompute, list(case),
-    set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar).
 :- mode case_vars_no_lambda(in(ordinary_nonlocals_no_lambda),
     in, in, out) is det.
 :- mode case_vars_no_lambda(in(code_gen_nonlocals_no_lambda),
@@ -1500,12 +1492,13 @@
         unexpected($module, $pred, "no cases (1)")
     ;
         CaseSets = [_ | _],
-        union_list(CaseSets, CasesSet)
+        set_of_var.union_list(CaseSets, CasesSet)
     ),
-    union(CasesSet, !Set).
+    set_of_var.union(CasesSet, !Set).
 
 :- pred compute_case_vars_maybe_lambda(nonlocals_to_recompute, list(case),
-    list(set_of_var), list(set_of_var), list(set_of_var), list(set_of_var)).
+    list(set_of_progvar), list(set_of_progvar),
+    list(set_of_progvar), list(set_of_progvar)).
 :- mode compute_case_vars_maybe_lambda(in(ordinary_nonlocals_maybe_lambda),
     in, in, out, in, out) is det.
 
@@ -1521,7 +1514,8 @@
         !Sets, !LambdaSets).
 
 :- pred compute_case_vars_maybe_lambda_and_bi_impl(list(case),
-    list(set_of_var), list(set_of_var), list(set_of_var), list(set_of_var)).
+    list(set_of_progvar), list(set_of_progvar),
+    list(set_of_progvar), list(set_of_progvar)).
 :- mode compute_case_vars_maybe_lambda_and_bi_impl(
     in, in, out, in, out) is det.
 
@@ -1535,7 +1529,7 @@
     compute_case_vars_maybe_lambda_and_bi_impl(Cases, !Sets, !LambdaSets).
 
 :- pred compute_case_vars_no_lambda(nonlocals_to_recompute, list(case),
-    list(set_of_var), list(set_of_var)).
+    list(set_of_progvar), list(set_of_progvar)).
 :- mode compute_case_vars_no_lambda(in(ordinary_nonlocals_no_lambda),
     in, in, out) is det.
 :- mode compute_case_vars_no_lambda(in(code_gen_nonlocals_no_lambda),
@@ -1548,33 +1542,6 @@
     !:Sets = [GoalSet | !.Sets],
     compute_case_vars_no_lambda(NonLocalsToRecompute, Cases, !Sets).
 
-:- pred union_list(list(set_of_var)::in, set_of_var::out) is det.
-
-union_list(Sets, Union) :-
-    (
-        Sets = [],
-        Union = init
-    ;
-        Sets = [_ | _],
-        union_list_pass(Sets, [], MergedSets),
-        ( MergedSets = [Set] ->
-            Union = Set
-        ;
-            union_list(MergedSets, Union)
-        )
-    ).
-
-:- pred union_list_pass(list(set_of_var)::in,
-    list(set_of_var)::in, list(set_of_var)::out) is det.
-
-union_list_pass([], !MergedSets).
-union_list_pass([Set], !MergedSets) :-
-    !:MergedSets = [Set | !.MergedSets].
-union_list_pass([Set1, Set2 | Sets], !MergedSets) :-
-    union(Set1, Set2, Set12),
-    !:MergedSets = [Set12 | !.MergedSets],
-    union_list_pass(Sets, !MergedSets).
-
 free_goal_vars(Goal) =
     free_goal_vars_nl_maybe_lambda(ordinary_nonlocals_maybe_lambda, Goal).
 
@@ -1605,7 +1572,7 @@
     goal_vars_bitset_no_lambda(NonLocalsToRecompute, Goal, BothSet).
 
 :- pred goal_vars_bitset(nonlocals_to_recompute,
-    hlds_goal, set_of_var).
+    hlds_goal, set_of_progvar).
 :- mode goal_vars_bitset(in(ordinary_nonlocals_maybe_lambda),
     in, out) is det.
 :- mode goal_vars_bitset(in(ordinary_nonlocals_no_lambda),
@@ -1625,7 +1592,7 @@
     ).
 
 :- pred goal_vars_bitset_maybe_lambda(nonlocals_to_recompute,
-    hlds_goal, set_of_var).
+    hlds_goal, set_of_progvar).
 :- mode goal_vars_bitset_maybe_lambda(in(ordinary_nonlocals_maybe_lambda),
     in, out) is det.
 
@@ -1635,7 +1602,7 @@
         Set, LambdaSet),
     BothSet = union(Set, LambdaSet).
 
-:- pred goal_vars_bitset_maybe_lambda_and_bi_impl(hlds_goal, set_of_var).
+:- pred goal_vars_bitset_maybe_lambda_and_bi_impl(hlds_goal, set_of_progvar).
 :- mode goal_vars_bitset_maybe_lambda_and_bi_impl(in, out) is det.
 
 goal_vars_bitset_maybe_lambda_and_bi_impl(Goal, BothSet) :-
@@ -1644,7 +1611,7 @@
     BothSet = union(Set, LambdaSet).
 
 :- pred goal_vars_bitset_no_lambda(nonlocals_to_recompute,
-    hlds_goal, set_of_var).
+    hlds_goal, set_of_progvar).
 :- mode goal_vars_bitset_no_lambda(in(ordinary_nonlocals_no_lambda),
     in, out) is det.
 :- mode goal_vars_bitset_no_lambda(in(code_gen_nonlocals_no_lambda),
@@ -1656,7 +1623,7 @@
     BothSet = Set.
 
 :- pred goal_expr_vars_bitset(nonlocals_to_recompute,
-    hlds_goal_expr, set_of_var).
+    hlds_goal_expr, set_of_progvar).
 :- mode goal_expr_vars_bitset(in(ordinary_nonlocals_maybe_lambda),
     in, out) is det.
 :- mode goal_expr_vars_bitset(in(ordinary_nonlocals_no_lambda),
@@ -1678,7 +1645,7 @@
     ).
 
 :- pred goal_expr_vars_bitset_maybe_lambda(nonlocals_to_recompute,
-    hlds_goal_expr, set_of_var).
+    hlds_goal_expr, set_of_progvar).
 :- mode goal_expr_vars_bitset_maybe_lambda(in(ordinary_nonlocals_maybe_lambda),
     in, out) is det.
 
@@ -1688,7 +1655,7 @@
     BothSet = union(Set, LambdaSet).
 
 :- pred goal_expr_vars_bitset_no_lambda(nonlocals_to_recompute,
-    hlds_goal_expr, set_of_var).
+    hlds_goal_expr, set_of_progvar).
 :- mode goal_expr_vars_bitset_no_lambda(in(ordinary_nonlocals_no_lambda),
     in, out) is det.
 :- mode goal_expr_vars_bitset_no_lambda(in(code_gen_nonlocals_no_lambda),
@@ -1707,7 +1674,7 @@
     % in Goal.
     %
 :- pred goal_vars_both_maybe_lambda(nonlocals_to_recompute, hlds_goal,
-    set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar).
 :- mode goal_vars_both_maybe_lambda(in(ordinary_nonlocals_maybe_lambda),
     in, out, out) is det.
 
@@ -1723,7 +1690,7 @@
     % from_groun_term scopes, not just the term variable.
     %
 :- pred goal_vars_both_maybe_lambda_and_bi_impl(hlds_goal,
-    set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar).
 :- mode goal_vars_both_maybe_lambda_and_bi_impl(in, out, out) is det.
 
 goal_vars_both_maybe_lambda_and_bi_impl(Goal, Set, LambdaSet) :-
@@ -1731,7 +1698,7 @@
     goal_expr_vars_both_maybe_lambda_and_bi_impl(GoalExpr, Set, LambdaSet).
 
 :- pred goal_vars_both_no_lambda(nonlocals_to_recompute, hlds_goal,
-    set_of_var).
+    set_of_progvar).
 :- mode goal_vars_both_no_lambda(in(ordinary_nonlocals_no_lambda),
     in, out) is det.
 :- mode goal_vars_both_no_lambda(in(code_gen_nonlocals_no_lambda),
@@ -1742,40 +1709,40 @@
     goal_expr_vars_both_no_lambda(NonLocalsToRecompute, GoalExpr, Set).
 
 :- pred goal_expr_vars_both_maybe_lambda(nonlocals_to_recompute, hlds_goal_expr,
-    set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar).
 :- mode goal_expr_vars_both_maybe_lambda(in(ordinary_nonlocals_maybe_lambda),
     in, out, out) is det.
 
 goal_expr_vars_both_maybe_lambda(NonLocalsToRecompute, GoalExpr,
         Set, LambdaSet) :-
-    Set0 = init,
-    LambdaSet0 = init,
+    Set0 = set_of_var.init,
+    LambdaSet0 = set_of_var.init,
     goal_expr_vars_maybe_lambda_2(NonLocalsToRecompute, GoalExpr, Set0, Set,
         LambdaSet0, LambdaSet).
 
 :- pred goal_expr_vars_both_maybe_lambda_and_bi_impl(hlds_goal_expr,
-    set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar).
 :- mode goal_expr_vars_both_maybe_lambda_and_bi_impl(in, out, out) is det.
 
 goal_expr_vars_both_maybe_lambda_and_bi_impl(GoalExpr, Set, LambdaSet) :-
-    Set0 = init,
-    LambdaSet0 = init,
+    Set0 = set_of_var.init,
+    LambdaSet0 = set_of_var.init,
     goal_expr_vars_maybe_lambda_and_bi_impl_2(GoalExpr, Set0, Set,
         LambdaSet0, LambdaSet).
 
 :- pred goal_expr_vars_both_no_lambda(nonlocals_to_recompute, hlds_goal_expr,
-    set_of_var).
+    set_of_progvar).
 :- mode goal_expr_vars_both_no_lambda(in(ordinary_nonlocals_no_lambda),
     in, out) is det.
 :- mode goal_expr_vars_both_no_lambda(in(code_gen_nonlocals_no_lambda),
     in, out) is det.
 
 goal_expr_vars_both_no_lambda(NonLocalsToRecompute, GoalExpr, Set) :-
-    Set0 = init,
+    Set0 = set_of_var.init,
     goal_expr_vars_no_lambda_2(NonLocalsToRecompute, GoalExpr, Set0, Set).
 
 :- pred goal_expr_vars_maybe_lambda_2(nonlocals_to_recompute, hlds_goal_expr,
-    set_of_var, set_of_var, set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar, set_of_progvar, set_of_progvar).
 :- mode goal_expr_vars_maybe_lambda_2(in(ordinary_nonlocals_maybe_lambda),
     in, in, out, in, out) is det.
 
@@ -1783,15 +1750,15 @@
         !Set, !LambdaSet) :-
     (
         GoalExpr = unify(LHS, RHS, _, Unification, _),
-        insert(LHS, !Set),
+        set_of_var.insert(LHS, !Set),
         (
             Unification = construct(_, _, _, _, How, _, SubInfo),
             (
                 How = reuse_cell(cell_to_reuse(ReuseVar, _, _)),
-                insert(ReuseVar, !Set)
+                set_of_var.insert(ReuseVar, !Set)
             ;
                 How = construct_in_region(RegionVar),
-                insert(RegionVar, !Set)
+                set_of_var.insert(RegionVar, !Set)
             ;
                 ( How = construct_statically
                 ; How = construct_dynamically
@@ -1801,7 +1768,7 @@
                 SubInfo = construct_sub_info(_, MaybeSize),
                 MaybeSize = yes(dynamic_size(SizeVar))
             ->
-                insert(SizeVar, !Set)
+                set_of_var.insert(SizeVar, !Set)
             ;
                 true
             )
@@ -1818,18 +1785,18 @@
             !Set, !LambdaSet)
     ;
         GoalExpr = plain_call(_, _, ArgVars, _, _, _),
-        insert_list(ArgVars, !Set)
+        set_of_var.insert_list(ArgVars, !Set)
     ;
         GoalExpr = generic_call(GenericCall, ArgVars1, _, _),
         goal_util.generic_call_vars(GenericCall, ArgVars0),
-        insert_list(ArgVars0, !Set),
-        insert_list(ArgVars1, !Set)
+        set_of_var.insert_list(ArgVars0, !Set),
+        set_of_var.insert_list(ArgVars1, !Set)
     ;
         GoalExpr = call_foreign_proc(_, _, _, Args, ExtraArgs, _, _),
         Vars = list.map(foreign_arg_var, Args),
         ExtraVars = list.map(foreign_arg_var, ExtraArgs),
         list.append(Vars, ExtraVars, AllVars),
-        insert_list(AllVars, !Set)
+        set_of_var.insert_list(AllVars, !Set)
     ;
         GoalExpr = conj(ConjType, Goals),
         (
@@ -1843,7 +1810,7 @@
         disj_vars_maybe_lambda(NonLocalsToRecompute, Goals, !Set, !LambdaSet)
     ;
         GoalExpr = switch(Var, _Det, Cases),
-        insert(Var, !Set),
+        set_of_var.insert(Var, !Set),
         case_vars_maybe_lambda(NonLocalsToRecompute, Cases, !Set, !LambdaSet)
     ;
         GoalExpr = if_then_else(Vars, Cond, Then, Else),
@@ -1856,14 +1823,14 @@
             ThenSet, ThenLambdaSet),
         goal_vars_both_maybe_lambda(NonLocalsToRecompute, Else,
             ElseSet, ElseLambdaSet),
-        union(CondSet, ThenSet, CondThenSet),
-        union(CondLambdaSet, ThenLambdaSet, CondThenLambdaSet),
-        delete_list(Vars, CondThenSet, SomeCondThenSet),
-        delete_list(Vars, CondThenLambdaSet, SomeCondThenLambdaSet),
-        union(!.Set, SomeCondThenSet, !:Set),
-        union(!.LambdaSet, SomeCondThenLambdaSet, !:LambdaSet),
-        union(!.Set, ElseSet, !:Set),
-        union(!.LambdaSet, ElseLambdaSet, !:LambdaSet)
+        set_of_var.union(CondSet, ThenSet, CondThenSet),
+        set_of_var.union(CondLambdaSet, ThenLambdaSet, CondThenLambdaSet),
+        set_of_var.delete_list(Vars, CondThenSet, SomeCondThenSet),
+        set_of_var.delete_list(Vars, CondThenLambdaSet, SomeCondThenLambdaSet),
+        set_of_var.union(!.Set, SomeCondThenSet, !:Set),
+        set_of_var.union(!.LambdaSet, SomeCondThenLambdaSet, !:LambdaSet),
+        set_of_var.union(!.Set, ElseSet, !:Set),
+        set_of_var.union(!.LambdaSet, ElseLambdaSet, !:LambdaSet)
     ;
         GoalExpr = negation(SubGoal),
         SubGoal = hlds_goal(SubGoalExpr, _SubGoalInfo),
@@ -1886,25 +1853,25 @@
             Reason = exist_quant(Vars),
             goal_vars_both_maybe_lambda(NonLocalsToRecompute, SubGoal,
                 !:Set, !:LambdaSet),
-            delete_list(Vars, !Set),
-            delete_list(Vars, !LambdaSet)
+            set_of_var.delete_list(Vars, !Set),
+            set_of_var.delete_list(Vars, !LambdaSet)
         ;
             Reason = promise_solutions(Vars, _Kind),
             goal_vars_both_maybe_lambda(NonLocalsToRecompute, SubGoal,
                 !:Set, !:LambdaSet),
-            insert_list(Vars, !Set)
+            set_of_var.insert_list(Vars, !Set)
         ;
             Reason = require_complete_switch(Var),
             goal_vars_both_maybe_lambda(NonLocalsToRecompute, SubGoal,
                 !:Set, !:LambdaSet),
-            insert(Var, !Set)
+            set_of_var.insert(Var, !Set)
         ;
             Reason = from_ground_term(TermVar, Kind),
             (
                 Kind = from_ground_term_construct,
-                !:Set = init,
-                insert(TermVar, !Set),
-                !:LambdaSet = init
+                !:Set = set_of_var.init,
+                set_of_var.insert(TermVar, !Set),
+                !:LambdaSet = set_of_var.init
             ;
                 ( Kind = from_ground_term_deconstruct
                 ; Kind = from_ground_term_other
@@ -1918,8 +1885,8 @@
                 % processed SubGoal, since it should appear in SubGoal.
             )
         ),
-        union(Set0, !Set),
-        union(LambdaSet0, !LambdaSet)
+        set_of_var.union(Set0, !Set),
+        set_of_var.union(LambdaSet0, !LambdaSet)
     ;
         GoalExpr = shorthand(ShortHand),
         (
@@ -1928,7 +1895,7 @@
             % XXX STM
             Outer = atomic_interface_vars(OuterDI, OuterUO),
             Inner = atomic_interface_vars(InnerDI, InnerUO),
-            insert_list([OuterDI, OuterUO, InnerDI, InnerUO], !Set),
+            set_of_var.insert_list([OuterDI, OuterUO, InnerDI, InnerUO], !Set),
             disj_vars_maybe_lambda(NonLocalsToRecompute,
                 [MainGoal | OrElseGoals], !Set, !LambdaSet)
         ;
@@ -1945,22 +1912,22 @@
     ).
 
 :- pred goal_expr_vars_maybe_lambda_and_bi_impl_2(hlds_goal_expr,
-    set_of_var, set_of_var, set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar, set_of_progvar, set_of_progvar).
 :- mode goal_expr_vars_maybe_lambda_and_bi_impl_2(
     in, in, out, in, out) is det.
 
 goal_expr_vars_maybe_lambda_and_bi_impl_2(GoalExpr, !Set, !LambdaSet) :-
     (
         GoalExpr = unify(LHS, RHS, _, Unification, _),
-        insert(LHS, !Set),
+        set_of_var.insert(LHS, !Set),
         (
             Unification = construct(_, _, _, _, How, _, SubInfo),
             (
                 How = reuse_cell(cell_to_reuse(ReuseVar, _, _)),
-                insert(ReuseVar, !Set)
+                set_of_var.insert(ReuseVar, !Set)
             ;
                 How = construct_in_region(RegionVar),
-                insert(RegionVar, !Set)
+                set_of_var.insert(RegionVar, !Set)
             ;
                 ( How = construct_statically
                 ; How = construct_dynamically
@@ -1970,13 +1937,13 @@
                 SubInfo = construct_sub_info(_, MaybeSize),
                 MaybeSize = yes(dynamic_size(SizeVar))
             ->
-                insert(SizeVar, !Set)
+                set_of_var.insert(SizeVar, !Set)
             ;
                 true
             )
         ;
             Unification = complicated_unify(_, _, TypeInfoVars),
-            insert_list(TypeInfoVars, !Set)
+            set_of_var.insert_list(TypeInfoVars, !Set)
         ;
             ( Unification = deconstruct(_, _, _, _, _, _)
             ; Unification = assign(_, _)
@@ -1986,18 +1953,18 @@
         unify_rhs_vars_maybe_lambda_and_bi_impl(RHS, !Set, !LambdaSet)
     ;
         GoalExpr = plain_call(_, _, ArgVars, _, _, _),
-        insert_list(ArgVars, !Set)
+        set_of_var.insert_list(ArgVars, !Set)
     ;
         GoalExpr = generic_call(GenericCall, ArgVars1, _, _),
         goal_util.generic_call_vars(GenericCall, ArgVars0),
-        insert_list(ArgVars0, !Set),
-        insert_list(ArgVars1, !Set)
+        set_of_var.insert_list(ArgVars0, !Set),
+        set_of_var.insert_list(ArgVars1, !Set)
     ;
         GoalExpr = call_foreign_proc(_, _, _, Args, ExtraArgs, _, _),
         Vars = list.map(foreign_arg_var, Args),
         ExtraVars = list.map(foreign_arg_var, ExtraArgs),
         list.append(Vars, ExtraVars, AllVars),
-        insert_list(AllVars, !Set)
+        set_of_var.insert_list(AllVars, !Set)
     ;
         GoalExpr = conj(ConjType, Goals),
         (
@@ -2011,7 +1978,7 @@
         disj_vars_maybe_lambda_and_bi_impl(Goals, !Set, !LambdaSet)
     ;
         GoalExpr = switch(Var, _Det, Cases),
-        insert(Var, !Set),
+        set_of_var.insert(Var, !Set),
         case_vars_maybe_lambda_and_bi_impl(Cases, !Set, !LambdaSet)
     ;
         GoalExpr = if_then_else(Vars, Cond, Then, Else),
@@ -2024,14 +1991,14 @@
             ThenSet, ThenLambdaSet),
         goal_vars_both_maybe_lambda_and_bi_impl(Else,
             ElseSet, ElseLambdaSet),
-        union(CondSet, ThenSet, CondThenSet),
-        union(CondLambdaSet, ThenLambdaSet, CondThenLambdaSet),
-        delete_list(Vars, CondThenSet, SomeCondThenSet),
-        delete_list(Vars, CondThenLambdaSet, SomeCondThenLambdaSet),
-        union(!.Set, SomeCondThenSet, !:Set),
-        union(!.LambdaSet, SomeCondThenLambdaSet, !:LambdaSet),
-        union(!.Set, ElseSet, !:Set),
-        union(!.LambdaSet, ElseLambdaSet, !:LambdaSet)
+        set_of_var.union(CondSet, ThenSet, CondThenSet),
+        set_of_var.union(CondLambdaSet, ThenLambdaSet, CondThenLambdaSet),
+        set_of_var.delete_list(Vars, CondThenSet, SomeCondThenSet),
+        set_of_var.delete_list(Vars, CondThenLambdaSet, SomeCondThenLambdaSet),
+        set_of_var.union(!.Set, SomeCondThenSet, !:Set),
+        set_of_var.union(!.LambdaSet, SomeCondThenLambdaSet, !:LambdaSet),
+        set_of_var.union(!.Set, ElseSet, !:Set),
+        set_of_var.union(!.LambdaSet, ElseLambdaSet, !:LambdaSet)
     ;
         GoalExpr = negation(SubGoal),
         SubGoal = hlds_goal(SubGoalExpr, _SubGoalInfo),
@@ -2054,18 +2021,18 @@
             Reason = exist_quant(Vars),
             goal_vars_both_maybe_lambda_and_bi_impl(SubGoal,
                 !:Set, !:LambdaSet),
-            delete_list(Vars, !Set),
-            delete_list(Vars, !LambdaSet)
+            set_of_var.delete_list(Vars, !Set),
+            set_of_var.delete_list(Vars, !LambdaSet)
         ;
             Reason = promise_solutions(Vars, _Kind),
             goal_vars_both_maybe_lambda_and_bi_impl(SubGoal,
                 !:Set, !:LambdaSet),
-            insert_list(Vars, !Set)
+            set_of_var.insert_list(Vars, !Set)
         ;
             Reason = require_complete_switch(Var),
             goal_vars_both_maybe_lambda_and_bi_impl(SubGoal,
                 !:Set, !:LambdaSet),
-            insert(Var, !Set)
+            set_of_var.insert(Var, !Set)
         ;
             Reason = from_ground_term(_TermVar, _Kind),
             goal_vars_both_maybe_lambda_and_bi_impl(SubGoal,
@@ -2073,8 +2040,8 @@
             % TermVar should have been put into the relevant sets when we
             % processed SubGoal, since it should appear in SubGoal.
         ),
-        union(Set0, !Set),
-        union(LambdaSet0, !LambdaSet)
+        set_of_var.union(Set0, !Set),
+        set_of_var.union(LambdaSet0, !LambdaSet)
     ;
         GoalExpr = shorthand(ShortHand),
         (
@@ -2083,7 +2050,7 @@
             % XXX STM
             Outer = atomic_interface_vars(OuterDI, OuterUO),
             Inner = atomic_interface_vars(InnerDI, InnerUO),
-            insert_list([OuterDI, OuterUO, InnerDI, InnerUO], !Set),
+            set_of_var.insert_list([OuterDI, OuterUO, InnerDI, InnerUO], !Set),
             disj_vars_maybe_lambda_and_bi_impl([MainGoal | OrElseGoals],
                 !Set, !LambdaSet)
         ;
@@ -2099,7 +2066,7 @@
     ).
 
 :- pred goal_expr_vars_no_lambda_2(nonlocals_to_recompute, hlds_goal_expr,
-    set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar).
 :- mode goal_expr_vars_no_lambda_2(in(ordinary_nonlocals_no_lambda),
     in, in, out) is det.
 :- mode goal_expr_vars_no_lambda_2(in(code_gen_nonlocals_no_lambda),
@@ -2108,17 +2075,17 @@
 goal_expr_vars_no_lambda_2(NonLocalsToRecompute, GoalExpr, !Set) :-
     (
         GoalExpr = unify(LHS, RHS, _, Unification, _),
-        insert(LHS, !Set),
+        set_of_var.insert(LHS, !Set),
         (
             Unification = construct(_, _, _, _, How, _, SubInfo),
             (
                 How = reuse_cell(cell_to_reuse(ReuseVar, _, SetArgs)),
                 MaybeSetArgs = yes(SetArgs),
-                insert(ReuseVar, !Set)
+                set_of_var.insert(ReuseVar, !Set)
             ;
                 How = construct_in_region(RegionVar),
                 MaybeSetArgs = no,
-                insert(RegionVar, !Set)
+                set_of_var.insert(RegionVar, !Set)
             ;
                 ( How = construct_statically
                 ; How = construct_dynamically
@@ -2129,14 +2096,14 @@
                 SubInfo = construct_sub_info(_, MaybeSize),
                 MaybeSize = yes(dynamic_size(SizeVar))
             ->
-                insert(SizeVar, !Set)
+                set_of_var.insert(SizeVar, !Set)
             ;
                 true
             )
         ;
             Unification = complicated_unify(_, _, TypeInfoVars),
             MaybeSetArgs = no,
-            insert_list(TypeInfoVars, !Set)
+            set_of_var.insert_list(TypeInfoVars, !Set)
         ;
             ( Unification = deconstruct(_, _, _, _, _, _)
             ; Unification = assign(_, _)
@@ -2147,18 +2114,18 @@
         unify_rhs_vars_no_lambda(NonLocalsToRecompute, RHS, MaybeSetArgs, !Set)
     ;
         GoalExpr = plain_call(_, _, ArgVars, _, _, _),
-        insert_list(ArgVars, !Set)
+        set_of_var.insert_list(ArgVars, !Set)
     ;
         GoalExpr = generic_call(GenericCall, ArgVars1, _, _),
         goal_util.generic_call_vars(GenericCall, ArgVars0),
-        insert_list(ArgVars0, !Set),
-        insert_list(ArgVars1, !Set)
+        set_of_var.insert_list(ArgVars0, !Set),
+        set_of_var.insert_list(ArgVars1, !Set)
     ;
         GoalExpr = call_foreign_proc(_, _, _, Args, ExtraArgs, _, _),
         Vars = list.map(foreign_arg_var, Args),
         ExtraVars = list.map(foreign_arg_var, ExtraArgs),
         list.append(Vars, ExtraVars, AllVars),
-        insert_list(AllVars, !Set)
+        set_of_var.insert_list(AllVars, !Set)
     ;
         GoalExpr = conj(ConjType, Goals),
         (
@@ -2172,7 +2139,7 @@
         disj_vars_no_lambda(NonLocalsToRecompute, Goals, !Set)
     ;
         GoalExpr = switch(Var, _Det, Cases),
-        insert(Var, !Set),
+        set_of_var.insert(Var, !Set),
         case_vars_no_lambda(NonLocalsToRecompute, Cases, !Set)
     ;
         GoalExpr = if_then_else(Vars, Cond, Then, Else),
@@ -2182,10 +2149,10 @@
         goal_vars_both_no_lambda(NonLocalsToRecompute, Cond, CondSet),
         goal_vars_both_no_lambda(NonLocalsToRecompute, Then, ThenSet),
         goal_vars_both_no_lambda(NonLocalsToRecompute, Else, ElseSet),
-        union(CondSet, ThenSet, CondThenSet),
-        delete_list(Vars, CondThenSet, SomeCondThenSet),
-        union(!.Set, SomeCondThenSet, !:Set),
-        union(!.Set, ElseSet, !:Set)
+        set_of_var.union(CondSet, ThenSet, CondThenSet),
+        set_of_var.delete_list(Vars, CondThenSet, SomeCondThenSet),
+        set_of_var.union(!.Set, SomeCondThenSet, !:Set),
+        set_of_var.union(!.Set, ElseSet, !:Set)
     ;
         GoalExpr = negation(SubGoal),
         SubGoal = hlds_goal(SubGoalExpr, _SubGoalInfo),
@@ -2204,22 +2171,22 @@
         ;
             Reason = exist_quant(Vars),
             goal_vars_both_no_lambda(NonLocalsToRecompute, SubGoal, !:Set),
-            delete_list(Vars, !Set)
+            set_of_var.delete_list(Vars, !Set)
         ;
             Reason = promise_solutions(Vars, _Kind),
             goal_vars_both_no_lambda(NonLocalsToRecompute, SubGoal, !:Set),
-            insert_list(Vars, !Set)
+            set_of_var.insert_list(Vars, !Set)
         ;
             Reason = require_complete_switch(Var),
             goal_vars_both_no_lambda(NonLocalsToRecompute, SubGoal, !:Set),
-            insert(Var, !Set)
+            set_of_var.insert(Var, !Set)
         ;
             Reason = from_ground_term(_TermVar, _),
             goal_vars_both_no_lambda(NonLocalsToRecompute, SubGoal, !:Set)
             % _TermVar should have been put into the relevant sets when we
             % processed SubGoal, since it should appear in SubGoal.
         ),
-        union(Set0, !Set)
+        set_of_var.union(Set0, !Set)
     ;
         GoalExpr = shorthand(ShortHand),
         (
@@ -2228,7 +2195,7 @@
             % XXX STM
             Outer = atomic_interface_vars(OuterDI, OuterUO),
             Inner = atomic_interface_vars(InnerDI, InnerUO),
-            insert_list([OuterDI, OuterUO, InnerDI, InnerUO], !Set),
+            set_of_var.insert_list([OuterDI, OuterUO, InnerDI, InnerUO], !Set),
             disj_vars_no_lambda(NonLocalsToRecompute, [MainGoal | OrElseGoals],
                 !Set)
         ;
@@ -2243,49 +2210,49 @@
     ).
 
 :- pred unify_rhs_vars_maybe_lambda(nonlocals_to_recompute, unify_rhs,
-    set_of_var, set_of_var, set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar, set_of_progvar, set_of_progvar).
 :- mode unify_rhs_vars_maybe_lambda(in(ordinary_nonlocals_maybe_lambda),
     in, in, out, in, out) is det.
 
 unify_rhs_vars_maybe_lambda(NonLocalsToRecompute, RHS, !Set, !LambdaSet) :-
     (
         RHS = rhs_var(Y),
-        insert(Y, !Set)
+        set_of_var.insert(Y, !Set)
     ;
         RHS = rhs_functor(_, _, ArgVars),
-        insert_list(ArgVars, !Set)
+        set_of_var.insert_list(ArgVars, !Set)
     ;
         RHS = rhs_lambda_goal(_, _, _, _, _, LambdaVars, _, _, Goal),
         % Note that the NonLocals list is not counted, since all the
         % variables in that list must occur in the goal.
         goal_vars_bitset_maybe_lambda(NonLocalsToRecompute, Goal, GoalVars0),
-        delete_list(LambdaVars, GoalVars0, GoalVars),
-        union(!.LambdaSet, GoalVars, !:LambdaSet)
+        set_of_var.delete_list(LambdaVars, GoalVars0, GoalVars),
+        set_of_var.union(!.LambdaSet, GoalVars, !:LambdaSet)
     ).
 
 :- pred unify_rhs_vars_maybe_lambda_and_bi_impl(unify_rhs,
-    set_of_var, set_of_var, set_of_var, set_of_var).
+    set_of_progvar, set_of_progvar, set_of_progvar, set_of_progvar).
 :- mode unify_rhs_vars_maybe_lambda_and_bi_impl(
     in, in, out, in, out) is det.
 
 unify_rhs_vars_maybe_lambda_and_bi_impl(RHS, !Set, !LambdaSet) :-
     (
         RHS = rhs_var(Y),
-        insert(Y, !Set)
+        set_of_var.insert(Y, !Set)
     ;
         RHS = rhs_functor(_, _, ArgVars),
-        insert_list(ArgVars, !Set)
+        set_of_var.insert_list(ArgVars, !Set)
     ;
         RHS = rhs_lambda_goal(_, _, _, _, _, LambdaVars, _, _, Goal),
         % Note that the NonLocals list is not counted, since all the
         % variables in that list must occur in the goal.
         goal_vars_bitset_maybe_lambda_and_bi_impl(Goal, GoalVars0),
-        delete_list(LambdaVars, GoalVars0, GoalVars),
-        union(!.LambdaSet, GoalVars, !:LambdaSet)
+        set_of_var.delete_list(LambdaVars, GoalVars0, GoalVars),
+        set_of_var.union(!.LambdaSet, GoalVars, !:LambdaSet)
     ).
 
 :- pred unify_rhs_vars_no_lambda(nonlocals_to_recompute, unify_rhs,
-    maybe(list(needs_update)), set_of_var, set_of_var).
+    maybe(list(needs_update)), set_of_progvar, set_of_progvar).
 :- mode unify_rhs_vars_no_lambda(in(ordinary_nonlocals_no_lambda),
     in, in, in, out) is det.
 :- mode unify_rhs_vars_no_lambda(in(code_gen_nonlocals_no_lambda),
@@ -2294,7 +2261,7 @@
 unify_rhs_vars_no_lambda(NonLocalsToRecompute, RHS, MaybeSetArgs, !Set) :-
     (
         RHS = rhs_var(Y),
-        insert(Y, !Set)
+        set_of_var.insert(Y, !Set)
     ;
         RHS = rhs_functor(_, _, ArgVars),
         (
@@ -2303,9 +2270,9 @@
         ->
             % Ignore the fields taken from the reused cell.
             get_updated_fields(SetArgs, ArgVars, ArgsToSet),
-            insert_list(ArgsToSet, !Set)
+            set_of_var.insert_list(ArgsToSet, !Set)
         ;
-            insert_list(ArgVars, !Set)
+            set_of_var.insert_list(ArgVars, !Set)
         )
     ;
         RHS = rhs_lambda_goal(_, _, _, _, _, _, _, _, _),
@@ -2313,11 +2280,11 @@
     ).
 
 :- pred insert_set_fields(list(needs_update)::in, list(prog_var)::in,
-    set_of_var::in, set_of_var::out) is det.
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 insert_set_fields(SetArgs, Args, !Set) :-
     get_updated_fields(SetArgs, Args,  ArgsToSet),
-    insert_list(ArgsToSet, !Set).
+    set_of_var.insert_list(ArgsToSet, !Set).
 
 :- pred get_updated_fields(list(needs_update)::in,
     list(prog_var)::in, list(prog_var)::out) is det.
@@ -2359,7 +2326,7 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred warn_overlapping_scope(set_of_var::in, prog_context::in,
+:- pred warn_overlapping_scope(set_of_progvar::in, prog_context::in,
     quant_info::in, quant_info::out) is det.
 
 warn_overlapping_scope(OverlapVars, Context, !Info) :-
@@ -2376,7 +2343,7 @@
     % and insert the mapping V->V' into RenameMap. Apply RenameMap
     % to Goal0 giving Goal.
     %
-:- pred rename_apart(set_of_var, map(prog_var, prog_var),
+:- pred rename_apart(set_of_progvar, map(prog_var, prog_var),
     nonlocals_to_recompute, hlds_goal, hlds_goal, quant_info, quant_info).
 :- mode rename_apart(in, out, in(ordinary_nonlocals_maybe_lambda),
     in, out, in, out) is det.
@@ -2393,7 +2360,7 @@
         % before the code-gen nonlocals -- any necessary renaming will have
         % been done while recomputing the ordinary nonlocals.
 
-        ( empty(RenameSet)
+        ( set_of_var.is_empty(RenameSet)
         ; NonLocalsToRecompute = code_gen_nonlocals_no_lambda
         )
     ->
@@ -2421,7 +2388,7 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred set_goal_nonlocals(set_of_var, nonlocals_to_recompute,
+:- pred set_goal_nonlocals(set_of_progvar, nonlocals_to_recompute,
     hlds_goal_info, hlds_goal_info, quant_info, quant_info).
 :- mode set_goal_nonlocals(in, in(ordinary_nonlocals_maybe_lambda),
     in, out, in, out) is det.
@@ -2434,7 +2401,7 @@
     set_goal_nonlocals_translate(NonLocals, _, NonLocalsToRecompute,
         !GoalInfo, !Info).
 
-:- pred set_goal_nonlocals_translate(set_of_var, set(prog_var),
+:- pred set_goal_nonlocals_translate(set_of_progvar, set(prog_var),
     nonlocals_to_recompute, hlds_goal_info, hlds_goal_info,
     quant_info, quant_info).
 :- mode set_goal_nonlocals_translate(in, out,
@@ -2459,47 +2426,37 @@
 
 %-----------------------------------------------------------------------------%
 
-:- func bitset_to_set(set_of_var) = set(prog_var).
-
-bitset_to_set(Bitset) = set.sorted_list_to_set(to_sorted_list(Bitset)).
-
-:- func set_to_bitset(set(prog_var)) = set_of_var.
-
-set_to_bitset(Bitset) = sorted_list_to_set(set.to_sorted_list(Bitset)).
-
-%-----------------------------------------------------------------------------%
-
-:- pred init_quant_info(set_of_var::in,
+:- pred init_quant_info(set_of_progvar::in,
     prog_varset::in, vartypes::in, rtti_varmaps::in, quant_info::out) is det.
 
 init_quant_info(OutsideVars, Varset, VarTypes, RttiVarMaps, QuantInfo) :-
     OverlapWarnings = [],
     QuantInfo = quant_info(OutsideVars, QuantVars, LambdaOutsideVars,
         NonLocals, Seen, Varset, VarTypes, OverlapWarnings, RttiVarMaps),
-    QuantVars = init,
-    NonLocals = init,
-    LambdaOutsideVars = init,
+    QuantVars = set_of_var.init,
+    NonLocals = set_of_var.init,
+    LambdaOutsideVars = set_of_var.init,
     Seen = OutsideVars.
 
-:- pred get_outside(quant_info::in, set_of_var::out) is det.
-:- pred get_quant_vars(quant_info::in, set_of_var::out) is det.
-:- pred get_lambda_outside(quant_info::in, set_of_var::out) is det.
-:- pred get_nonlocals(quant_info::in, set_of_var::out) is det.
-:- pred get_seen(quant_info::in, set_of_var::out) is det.
+:- pred get_outside(quant_info::in, set_of_progvar::out) is det.
+:- pred get_quant_vars(quant_info::in, set_of_progvar::out) is det.
+:- pred get_lambda_outside(quant_info::in, set_of_progvar::out) is det.
+:- pred get_nonlocals(quant_info::in, set_of_progvar::out) is det.
+:- pred get_seen(quant_info::in, set_of_progvar::out) is det.
 :- pred get_varset(quant_info::in, prog_varset::out) is det.
 :- pred get_vartypes(quant_info::in, vartypes::out) is det.
 :- pred get_warnings(quant_info::in, list(quant_warning)::out) is det.
 :- pred get_rtti_varmaps(quant_info::in, rtti_varmaps::out) is det.
 
-:- pred set_outside(set_of_var::in,
+:- pred set_outside(set_of_progvar::in,
     quant_info::in, quant_info::out) is det.
-:- pred set_quant_vars(set_of_var::in,
+:- pred set_quant_vars(set_of_progvar::in,
     quant_info::in, quant_info::out) is det.
-:- pred set_lambda_outside(set_of_var::in,
+:- pred set_lambda_outside(set_of_progvar::in,
     quant_info::in, quant_info::out) is det.
-:- pred set_nonlocals(set_of_var::in,
+:- pred set_nonlocals(set_of_progvar::in,
     quant_info::in, quant_info::out) is det.
-:- pred set_seen(set_of_var::in,
+:- pred set_seen(set_of_progvar::in,
     quant_info::in, quant_info::out) is det.
 :- pred set_varset(prog_varset::in,
     quant_info::in, quant_info::out) is det.
Index: compiler/set_of_var.m
===================================================================
RCS file: compiler/set_of_var.m
diff -N compiler/set_of_var.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ compiler/set_of_var.m	19 Jul 2011 06:02:39 -0000
@@ -0,0 +1,395 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2011 The University of Melbourne.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+%
+% File: set_of_var.m.
+%
+% A module to define the abstract data structure we use to represent
+% sets of variables.
+%
+%-----------------------------------------------------------------------------%
+
+:- module parse_tree.set_of_var.
+:- interface.
+
+:- import_module parse_tree.prog_data.
+
+:- import_module list.
+:- import_module set.
+:- import_module term.
+
+:- type set_of_var(T).
+:- type set_of_progvar == set_of_var(prog_var_type).
+:- type set_of_tvar    == set_of_var(tvar_type).
+
+:- func init = set_of_var(T).
+
+:- func make_singleton(var(T)) = set_of_var(T).
+
+%---------------
+% Tests.
+
+:- pred is_empty(set_of_var(T)::in) is semidet.
+:- pred is_non_empty(set_of_var(T)::in) is semidet.
+:- pred is_singleton(set_of_var(T)::in, var(T)::out) is semidet.
+
+:- pred member(set_of_var(T)::in, var(T)::in) is semidet.
+:- pred equal(set_of_var(T)::in, set_of_var(T)::in) is semidet.
+
+%---------------
+% Conversions.
+
+:- func list_to_set(list(var(T))) = set_of_var(T).
+:- func sorted_list_to_set(list(var(T))) = set_of_var(T).
+:- func to_sorted_list(set_of_var(T)) = list(var(T)).
+
+:- func set_to_bitset(set(var(T))) = set_of_var(T).
+:- func bitset_to_set(set_of_var(T)) = set(var(T)).
+
+%---------------
+% Updates.
+
+:- pred insert(var(T)::in,
+    set_of_var(T)::in, set_of_var(T)::out) is det.
+:- pred insert_list(list(var(T))::in,
+    set_of_var(T)::in, set_of_var(T)::out) is det.
+:- pred delete(var(T)::in,
+    set_of_var(T)::in, set_of_var(T)::out) is det.
+:- pred delete_list(list(var(T))::in,
+    set_of_var(T)::in, set_of_var(T)::out) is det.
+:- pred remove(var(T)::in,
+    set_of_var(T)::in, set_of_var(T)::out) is semidet.
+:- pred remove_list(list(var(T))::in,
+    set_of_var(T)::in, set_of_var(T)::out) is semidet.
+:- pred remove_least(var(T)::out,
+    set_of_var(T)::in, set_of_var(T)::out) is semidet.
+
+%---------------
+% Set operations.
+
+:- func union(set_of_var(T), set_of_var(T)) = set_of_var(T).
+:- pred union(set_of_var(T)::in, set_of_var(T)::in,
+    set_of_var(T)::out) is det.
+
+:- func union_list(list(set_of_var(T))) = set_of_var(T).
+:- pred union_list(list(set_of_var(T))::in, set_of_var(T)::out) is det.
+
+:- func intersect(set_of_var(T), set_of_var(T)) = set_of_var(T).
+:- pred intersect(set_of_var(T)::in, set_of_var(T)::in,
+    set_of_var(T)::out) is det.
+
+:- func intersect_list(list(set_of_var(T))) = set_of_var(T).
+:- pred intersect_list(list(set_of_var(T))::in, set_of_var(T)::out) is det.
+
+:- func difference(set_of_var(T), set_of_var(T)) = set_of_var(T).
+:- pred difference(set_of_var(T)::in, set_of_var(T)::in,
+    set_of_var(T)::out) is det.
+
+:- pred divide(pred(var(T))::in(pred(in) is semidet), set_of_var(T)::in,
+    set_of_var(T)::out, set_of_var(T)::out) is det.
+
+:- pred divide_by_set(set_of_var(T)::in, set_of_var(T)::in,
+    set_of_var(T)::out, set_of_var(T)::out) is det.
+
+%---------------
+% Traversals.
+
+:- pred fold(pred(var(T), Acc, Acc), set_of_var(T), Acc, Acc).
+:- mode fold(pred(in, in, out) is det, in, in, out) is det.
+:- mode fold(pred(in, in, out) is semidet, in, in, out) is semidet.
+
+    % `filter(Pred, Set) = TrueSet' returns the elements of Set for which
+    % Pred succeeds.
+    %
+:- func filter(pred(var(T))::in(pred(in) is semidet), set_of_var(T)::in)
+    = (set_of_var(T)::out) is det.
+
+    % `filter(Pred, Set, TrueSet, FalseSet)' returns the elements of Set
+    % for which Pred succeeds, and those for which it fails.
+    %
+:- pred filter(pred(var(T))::in(pred(in) is semidet),
+    set_of_var(T)::in, set_of_var(T)::out, set_of_var(T)::out) is det.
+
+%---------------
+% Graph colouring.
+
+    % Find a 'good' colouring of a graph.
+    % The predicate takes a set of sets each containing elements that touch,
+    % and returns a set of sets each containing elements that can be assigned
+    % the same colour, ensuring that touching elements have different colours.
+    % ("Good" means using as few colours as possible.)
+    %
+:- pred graph_colour_group_elements(set(set_of_var(T))::in,
+    set(set_of_var(T))::out) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+% We want to define set_of_var as tree_bitset for performance.
+% However, until we have user-specified pretty printing in the debugger,
+% debugging will be much easier if set_of_var is just a plain set.
+% The definition of the type is hidden here to make it relatively easy
+% to change.
+%
+% If you want to debug a new set representation, then
+%
+% - make the test_bitset.m module use the new representation instead of
+%   tree_bitset.m (all the operations will be run both on the new
+%   representation and on set_ordlist, aborting on any discrepancy),
+%
+% - change every occurrence of tree_bitset in this file that is on a line
+%   containing MODULE to tree_bitset.
+%
+% Once the representation has been proven, you can change all those occurrences
+% of test_bitset to the name of the module implementing the new representation.
+
+:- import_module tree_bitset.                                       % MODULE
+:- import_module require.
+
+:- type set_of_var(T) ==  tree_bitset(var(T)).                      % MODULE
+
+%-----------------------------------------------------------------------------%
+
+init = tree_bitset.init.                                            % MODULE
+
+make_singleton(Elem) = tree_bitset.make_singleton_set(Elem).        % MODULE
+
+%---------------
+% Tests.
+
+is_empty(Set) :-
+    tree_bitset.is_empty(Set).                                      % MODULE
+
+is_non_empty(Set) :-
+    tree_bitset.is_non_empty(Set).                                  % MODULE
+
+is_singleton(Set, Elem) :-
+    tree_bitset.is_singleton(Set, Elem).                            % MODULE
+
+member(Set, Elem) :-
+    tree_bitset.member(Elem, Set).                                  % MODULE
+
+equal(SetA, SetB) :-
+    tree_bitset.equal(SetA, SetB).                                  % MODULE
+
+%---------------
+% Conversions.
+
+list_to_set(List) = tree_bitset.list_to_set(List).                  % MODULE
+
+sorted_list_to_set(List) = tree_bitset.sorted_list_to_set(List).    % MODULE
+
+to_sorted_list(Set) = tree_bitset.to_sorted_list(Set).              % MODULE
+
+set_to_bitset(OrdSet) = tree_bitset.from_set(OrdSet).               % MODULE
+
+bitset_to_set(Set) = tree_bitset.to_set(Set).                       % MODULE
+
+%---------------
+% Updates.
+
+insert(Elem, !Set) :-
+    tree_bitset.insert(Elem, !Set).                                 % MODULE
+
+insert_list(Elems, !Set) :-
+    tree_bitset.insert_list(Elems, !Set).                           % MODULE
+
+delete(Elem, !Set) :-
+    tree_bitset.delete(Elem, !Set).                                 % MODULE
+
+delete_list(Elems, !Set) :-
+    tree_bitset.delete_list(Elems, !Set).                           % MODULE
+
+remove(Elem, !Set) :-
+    tree_bitset.remove(Elem, !Set).                                 % MODULE
+
+remove_list(Elems, !Set) :-
+    tree_bitset.remove_list(Elems, !Set).                           % MODULE
+
+remove_least(LeastElem, !Set) :-
+    tree_bitset.remove_least(LeastElem, !Set).                      % MODULE
+
+%---------------
+% Set operations.
+
+union(SetA, SetB) = tree_bitset.union(SetA, SetB).                  % MODULE
+union(SetA, SetB, Set) :-
+    tree_bitset.union(SetA, SetB, Set).                             % MODULE
+
+union_list(Sets) = tree_bitset.union_list(Sets).                    % MODULE
+union_list(Sets, Set) :-
+    tree_bitset.union_list(Sets, Set).                              % MODULE
+
+intersect(SetA, SetB) = tree_bitset.intersect(SetA, SetB).          % MODULE
+intersect(SetA, SetB, Set) :-
+    tree_bitset.intersect(SetA, SetB, Set).                         % MODULE
+
+intersect_list(Sets) = tree_bitset.intersect_list(Sets).            % MODULE
+intersect_list(Sets, Set) :-
+    tree_bitset.intersect_list(Sets, Set).                          % MODULE
+
+difference(SetA, SetB) = tree_bitset.difference(SetA, SetB).        % MODULE
+difference(SetA, SetB, Set) :-
+    tree_bitset.difference(SetA, SetB, Set).                        % MODULE
+
+divide(Pred, Set, InPart, OutPart) :-
+    tree_bitset.divide(Pred, Set, InPart, OutPart).                 % MODULE
+
+divide_by_set(DivideBySet, Set, InPart, OutPart) :-
+    tree_bitset.divide_by_set(DivideBySet, Set, InPart, OutPart).   % MODULE
+
+%---------------
+% Traversals.
+
+fold(P, Set, !Acc) :-
+    tree_bitset.foldl(P, Set, !Acc).                                % MODULE
+
+filter(P, Set) = tree_bitset.filter(P, Set).                        % MODULE
+
+filter(P, Set, Trues, Falses) :-
+     tree_bitset.filter(P, Set, Trues, Falses).                     % MODULE
+
+%---------------
+% Graph colouring.
+
+% The code of graph_colour_group_elements and its auxiliary predicates
+% is adapted from graph_colour.m.
+%
+% Note that this algorithm is NOT guaranteed to find the exact same colour
+% assignment as graph_colour.m. That is because the sorted list of sets that
+% find_all_colours iterates over is sorted by different criteria when the
+% elements are set(prog_var), as in graph_colour.m, and when they are
+% set_of_progvar, as they are here. The same is true for the set of colours
+% that graph_colour_group_elements returns. However, you *do* get the exact
+% same results if you re-sort both the input and output sets-of-sets using
+% the set.m set representation of the elements.
+
+graph_colour_group_elements(!.Constraints, Colours) :-
+    set.delete(set_of_var.init, !Constraints),
+    set.to_sorted_list(!.Constraints, ConstraintList),
+    set_of_var.union_list(ConstraintList, AllVars),
+    find_all_colours(ConstraintList, AllVars, ColourList),
+    Colours = set.list_to_set(ColourList).
+
+    % Iterate the assignment of a new colour until all constraints
+    % are satisfied.
+    %
+:- pred find_all_colours(list(set_of_var(T))::in, set_of_var(T)::in,
+    list(set_of_var(T))::out) is det.
+
+find_all_colours(ConstraintList, Vars, ColourList) :-
+    (
+        ConstraintList = [],
+        ColourList = []
+    ;
+        ConstraintList = [_ | _],
+        next_colour(Vars, ConstraintList, RemainingConstraints, Colour),
+        set_of_var.difference(Vars, Colour, RestVars),
+        find_all_colours(RemainingConstraints, RestVars, ColourList0),
+        ColourList = [Colour | ColourList0]
+    ).
+
+:- pred next_colour(set_of_var(T)::in, list(set_of_var(T))::in,
+    list(set_of_var(T))::out, set_of_var(T)::out) is det.
+
+next_colour(Vars0, ConstraintList, Remainder, SameColour) :-
+    % Check if there are any constraints left to be satisfied.
+    (
+        ConstraintList = [_ | _],
+        % Select a variable to assign a colour, ...
+        choose_var(Vars0, Var, Vars1),
+
+        % ... and divide the constraints into those that may be the same colour
+        % as that var and those that may not.
+        divide_constraints(Var, ConstraintList, WereContaining, NotContaining,
+            Vars1, RestVars),
+        (
+            % See if there are sets that can share a colour with the
+            % selected var.
+            NotContaining = [_ | _],
+            ( set_of_var.is_empty(RestVars) ->
+                % There were no variables left that could share a colour,
+                % so create a singleton set containing this variable.
+                SameColour = set_of_var.make_singleton(Var),
+                ResidueSets = NotContaining
+            ;
+                % If there is at least one variable that can share a colour
+                % with the selected variable, then recursively use the
+                % remaining constraints to assign a colour to one of the
+                % remaining vars, and assemble the constraint residues.
+                next_colour(RestVars, NotContaining, ResidueSets, SameColour0),
+
+                % Add this variable to the variables of the current colour.
+                set_of_var.insert(Var, SameColour0, SameColour)
+            )
+        ;
+            NotContaining = [],
+            % There were no more constraints which could be satisfied
+            % by assigning any variable a colour the same as the current
+            % variable, so create a signleton set with the current var,
+            % and assign the residue to the empty set.
+            SameColour = set_of_var.make_singleton(Var),
+            ResidueSets = []
+        ),
+        % The remaining constraints are the residue sets that could not be
+        % satisfied by assigning any variable to the current colour, and the
+        % constraints that were already satisfied by the assignment of the
+        % current variable to this colour.
+        list.append(ResidueSets, WereContaining, Remainder)
+    ;
+        % If there were no constraints, then no colours were needed.
+        ConstraintList = [],
+        Remainder = [],
+        SameColour = set_of_var.init
+    ).
+
+    % Divide_constraints takes a var and a list of sets of var, and divides
+    % the list into two lists: a list of sets containing the given variable
+    % and a list of sets not containing that variable. The sets in the list
+    % containing the variable have that variable removed. Additionally, a set
+    % of variables is threaded through the computation, and any variables that
+    % were in sets that also contained the given variables are removed from
+    % the threaded set.
+    %
+:- pred divide_constraints(var(T)::in, list(set_of_var(T))::in,
+    list(set_of_var(T))::out, list(set_of_var(T))::out,
+    set_of_var(T)::in, set_of_var(T)::out) is det.
+
+divide_constraints(_Var, [], [], [], !Vars).
+divide_constraints(Var, [S | Ss], C, NC, !Vars) :-
+    divide_constraints(Var, Ss, C0, NC0, !Vars),
+    ( set_of_var.member(S, Var) ->
+        set_of_var.delete(Var, S, T),
+        ( set_of_var.is_empty(T) ->
+            C = C0
+        ;
+            C = [T | C0]
+        ),
+        NC = NC0,
+        set_of_var.difference(!.Vars, T, !:Vars)
+    ;
+        C = C0,
+        NC = [S | NC0]
+    ).
+
+    % Choose_var/3, given a set of variables, chooses one, returns it
+    % and the set with that variable removed.
+    %
+:- pred choose_var(set_of_var(T)::in, var(T)::out, set_of_var(T)::out) is det.
+
+choose_var(Vars0, Var, Vars) :-
+    ( set_of_var.remove_least(VarPrime, Vars0, VarsPrime) ->
+        Var = VarPrime,
+        Vars = VarsPrime
+    ;
+        unexpected($module, $pred, "no vars!")
+    ).
+
+%-----------------------------------------------------------------------------%
+:- end_module set_of_var.
+%-----------------------------------------------------------------------------%
Index: compiler/simplify.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.266
diff -u -b -r1.266 simplify.m
--- compiler/simplify.m	16 Jun 2011 06:42:15 -0000	1.266
+++ compiler/simplify.m	10 Jul 2011 21:32:19 -0000
@@ -151,6 +151,7 @@
 :- import_module parse_tree.prog_type.
 :- import_module parse_tree.prog_type_subst.
 :- import_module parse_tree.prog_util.
+:- import_module parse_tree.set_of_var.
 :- import_module transform_hlds.    % for pd_cost, etc.
 :- import_module transform_hlds.const_prop.
 :- import_module transform_hlds.pd_cost.
@@ -693,7 +694,8 @@
             simplify_info_get_var_types(!.Info, !:VarTypes),
             simplify_info_get_rtti_varmaps(!.Info, !:RttiVarMaps),
             implicitly_quantify_goal_general(ordinary_nonlocals_maybe_lambda,
-                NonLocals, _, !Goal, !VarSet, !VarTypes, !RttiVarMaps),
+                set_to_bitset(NonLocals), _, !Goal,
+                !VarSet, !VarTypes, !RttiVarMaps),
 
             simplify_info_set_varset(!.VarSet, !Info),
             simplify_info_set_var_types(!.VarTypes, !Info),
Index: compiler/stack_alloc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/stack_alloc.m,v
retrieving revision 1.29
diff -u -b -r1.29 stack_alloc.m
--- compiler/stack_alloc.m	26 May 2011 06:20:05 -0000	1.29
+++ compiler/stack_alloc.m	19 Jul 2011 04:07:40 -0000
@@ -42,13 +42,13 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_llds.
 :- import_module libs.globals.
-:- import_module libs.graph_colour.
 :- import_module libs.options.
 :- import_module libs.trace_params.
 :- import_module ll_backend.live_vars.
 :- import_module ll_backend.liveness.
 :- import_module ll_backend.trace_gen.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module bool.
 :- import_module int.
@@ -69,16 +69,17 @@
         eff_trace_level_needs_fail_vars(ModuleInfo, PredInfo, !.ProcInfo,
             TraceLevel) = yes
     ->
-        trace_fail_vars(ModuleInfo, !.ProcInfo, FailVars)
+        trace_fail_vars(ModuleInfo, !.ProcInfo, FailVars0),
+        FailVars = set_to_bitset(FailVars0)
     ;
-        set.init(FailVars)
+        FailVars = set_of_var.init
     ),
     body_should_use_typeinfo_liveness(PredInfo, Globals, TypeInfoLiveness),
     globals.lookup_bool_option(Globals, opt_no_return_calls,
         OptNoReturnCalls),
     AllocData = alloc_data(ModuleInfo, !.ProcInfo, TypeInfoLiveness,
         OptNoReturnCalls),
-    set.init(NondetLiveness0),
+    NondetLiveness0 = set_of_var.init,
     SimpleStackAlloc0 = stack_alloc(set.make_singleton_set(FailVars)),
     proc_info_get_goal(!.ProcInfo, Goal0),
     build_live_sets_in_goal_no_par_stack(Goal0, Goal, FailVars, AllocData,
@@ -92,7 +93,7 @@
         NumReservedSlots, MaybeReservedVarInfo),
     (
         MaybeReservedVarInfo = yes(ResVar - _),
-        set.singleton_set(ResVarSet, ResVar),
+        ResVarSet = set_of_var.make_singleton(ResVar),
         set.insert(ResVarSet, LiveSets0, LiveSets1)
     ;
         MaybeReservedVarInfo = no,
@@ -101,8 +102,9 @@
     proc_info_get_vartypes(!.ProcInfo, VarTypes),
     filter_out_dummy_values(ModuleInfo, VarTypes, LiveSets1, LiveSets,
         DummyVars),
-    graph_colour.group_elements(LiveSets, ColourSets),
+    graph_colour_group_elements(LiveSets, ColourSets),
     set.to_sorted_list(ColourSets, ColourList),
+
     CodeModel = proc_info_interface_code_model(!.ProcInfo),
     allocate_stack_slots(ColourList, CodeModel, NumReservedSlots,
         MaybeReservedVarInfo, StackSlots1),
@@ -111,29 +113,29 @@
     proc_info_set_stack_slots(StackSlots, !ProcInfo).
 
 :- pred filter_out_dummy_values(module_info::in, vartypes::in,
-    set(set(prog_var))::in, set(set(prog_var))::out,
+    set(set_of_progvar)::in, set(set_of_progvar)::out,
     list(prog_var)::out) is det.
 
 filter_out_dummy_values(ModuleInfo, VarTypes, LiveSet0, LiveSet, DummyVars) :-
     set.to_sorted_list(LiveSet0, LiveList0),
     filter_out_dummy_values_2(ModuleInfo, VarTypes, LiveList0, LiveList,
-        set.init, Dummies),
+        set_of_var.init, Dummies),
     set.list_to_set(LiveList, LiveSet),
-    set.to_sorted_list(Dummies, DummyVars).
+    DummyVars = set_of_var.to_sorted_list(Dummies).
 
 :- pred filter_out_dummy_values_2(module_info::in, vartypes::in,
-    list(set(prog_var))::in, list(set(prog_var))::out,
-    set(prog_var)::in, set(prog_var)::out) is det.
+    list(set_of_progvar)::in, list(set_of_progvar)::out,
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 filter_out_dummy_values_2(_, _VarTypes, [], [], !Dummies).
 filter_out_dummy_values_2(ModuleInfo, VarTypes,
         [LiveSet0 | LiveSets0], LiveSets, !Dummies) :-
     filter_out_dummy_values_2(ModuleInfo, VarTypes, LiveSets0, LiveSets1,
         !Dummies),
-    set.filter(var_is_of_dummy_type(ModuleInfo, VarTypes), LiveSet0,
+    set_of_var.filter(var_is_of_dummy_type(ModuleInfo, VarTypes), LiveSet0,
         DummyVars, NonDummyVars),
-    set.union(DummyVars, !Dummies),
-    ( set.empty(NonDummyVars) ->
+    set_of_var.union(DummyVars, !Dummies),
+    ( set_of_var.is_empty(NonDummyVars) ->
         LiveSets = LiveSets1
     ;
         LiveSets = [NonDummyVars | LiveSets1]
@@ -144,8 +146,9 @@
 
 :- type stack_alloc
     --->    stack_alloc(
-                set(set(prog_var))  % The sets of vars that need to be
-                                    % on the stack at the same time.
+                % The sets of vars that need to be on the stack
+                % at the same time.
+                set(set_of_progvar)
             ).
 
 :- instance stack_alloc_info(stack_alloc) where [
@@ -159,7 +162,7 @@
 
 alloc_at_call_site(NeedAtCall, _GoalInfo, StackAlloc0, StackAlloc) :-
     NeedAtCall = need_across_call(ForwardVars, ResumeVars, NondetLiveVars),
-    LiveSet = set.union_list([ForwardVars, ResumeVars, NondetLiveVars]),
+    LiveSet = set_of_var.union_list([ForwardVars, ResumeVars, NondetLiveVars]),
     StackAlloc0 = stack_alloc(LiveSets0),
     LiveSets = set.insert(LiveSets0, LiveSet),
     StackAlloc = stack_alloc(LiveSets).
@@ -174,7 +177,7 @@
         StackAlloc = StackAlloc0
     ;
         ResumeOnStack = yes,
-        LiveSet = set.union(ResumeVars, NondetLiveVars),
+        LiveSet = set_of_var.union(ResumeVars, NondetLiveVars),
         StackAlloc0 = stack_alloc(LiveSets0),
         LiveSets = set.insert(LiveSets0, LiveSet),
         StackAlloc = stack_alloc(LiveSets)
@@ -192,7 +195,7 @@
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-:- pred allocate_stack_slots(list(set(prog_var))::in, code_model::in, int::in,
+:- pred allocate_stack_slots(list(set_of_progvar)::in, code_model::in, int::in,
     maybe(pair(prog_var, int))::in, stack_slots::out) is det.
 
 allocate_stack_slots(ColourList, CodeModel, NumReservedSlots,
@@ -203,7 +206,7 @@
     allocate_stack_slots_2(ColourList, CodeModel, FirstVarSlot,
         MaybeReservedVarInfo, map.init, StackSlots).
 
-:- pred allocate_stack_slots_2(list(set(prog_var))::in, code_model::in,
+:- pred allocate_stack_slots_2(list(set_of_progvar)::in, code_model::in,
     int::in, maybe(pair(prog_var, int))::in,
     stack_slots::in, stack_slots::out) is det.
 
@@ -212,7 +215,7 @@
         !StackSlots) :-
     (
         MaybeReservedVarInfo = yes(ResVar - ResSlotNum),
-        set.member(ResVar, Vars)
+        set_of_var.member(Vars, ResVar)
     ->
         SlotNum = ResSlotNum,
         N1 = N0
@@ -220,7 +223,7 @@
         SlotNum = N0,
         N1 = N0 + 1
     ),
-    set.to_sorted_list(Vars, VarList),
+    VarList = set_of_var.to_sorted_list(Vars),
     allocate_same_stack_slot(VarList, CodeModel, SlotNum, !StackSlots),
     allocate_stack_slots_2(VarSets, CodeModel, N1, MaybeReservedVarInfo,
         !StackSlots).
Index: compiler/stack_opt.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/stack_opt.m,v
retrieving revision 1.53
diff -u -b -r1.53 stack_opt.m
--- compiler/stack_opt.m	23 May 2011 05:08:12 -0000	1.53
+++ compiler/stack_opt.m	10 Jul 2011 22:42:51 -0000
@@ -105,6 +105,7 @@
 :- import_module mdbcomp.goal_path.
 :- import_module parse_tree.prog_data.
 :- import_module parse_tree.prog_type.
+:- import_module parse_tree.set_of_var.
 
 :- import_module bool.
 :- import_module counter.
@@ -128,7 +129,7 @@
 
 :- type opt_stack_alloc
     --->    opt_stack_alloc(
-                par_conj_own_slots  :: set(prog_var)
+                par_conj_own_slots      :: set_of_progvar
             ).
 
 :- type stack_opt_params
@@ -138,7 +139,7 @@
                 sop_fixpoint_loop       :: bool,
                 sop_full_path           :: bool,
                 sop_on_stack            :: bool,
-                sop_non_candidate_vars  :: set(prog_var)
+                sop_non_candidate_vars  :: set_of_progvar
             ).
 
 :- type matching_result
@@ -146,7 +147,7 @@
                 prog_var,
                 cons_id,
                 list(prog_var),
-                set(prog_var),
+                set_of_progvar,
                 goal_id,
                 set(interval_id),
                 set(interval_id),
@@ -182,9 +183,9 @@
     OptStackAlloc0 = init_opt_stack_alloc,
     set.init(FailVars),
     set.init(NondetLiveness0),
-    build_live_sets_in_goal_no_par_stack(Goal2, Goal, FailVars, AllocData,
-        OptStackAlloc0, OptStackAlloc, Liveness0, _Liveness,
-        NondetLiveness0, _NondetLiveness),
+    build_live_sets_in_goal_no_par_stack(Goal2, Goal, set_to_bitset(FailVars),
+        AllocData, OptStackAlloc0, OptStackAlloc, Liveness0, _Liveness,
+        set_to_bitset(NondetLiveness0), _NondetLiveness),
     proc_info_set_goal(Goal, !ProcInfo),
     allocate_store_maps(for_stack_opt, !.ModuleInfo, PredProcId, !ProcInfo),
     globals.lookup_int_option(Globals, debug_stack_opt, DebugStackOpt),
@@ -218,7 +219,7 @@
 
 :- func init_opt_stack_alloc = opt_stack_alloc.
 
-init_opt_stack_alloc = opt_stack_alloc(set.init).
+init_opt_stack_alloc = opt_stack_alloc(set_of_var.init).
 
 :- pred optimize_live_sets(module_info::in, opt_stack_alloc::in,
     proc_info::in, proc_info::out, bool::out, int::in, int::in) is det.
@@ -237,7 +238,8 @@
         optimize_saved_vars_cell_candidate_headvars, CandHeadvars),
     (
         CandHeadvars = no,
-        set.union(HeadVars, ParConjOwnSlot, NonCandidateVars)
+        set_of_var.union(set_to_bitset(HeadVars), ParConjOwnSlot,
+            NonCandidateVars)
     ;
         CandHeadvars = yes,
         NonCandidateVars = ParConjOwnSlot
@@ -246,10 +248,10 @@
     counter.allocate(CurInterval, Counter0, Counter1),
     CurIntervalId = interval_id(CurInterval),
     EndMap0 = map.singleton(CurIntervalId, anchor_proc_end),
-    InsertMap0 = map.init,
-    StartMap0 = map.init,
+    map.init(InsertMap0),
+    map.init(StartMap0),
     SuccMap0 = map.singleton(CurIntervalId, []),
-    VarsMap0 = map.singleton(CurIntervalId, OutputArgs),
+    VarsMap0 = map.singleton(CurIntervalId, set_to_bitset(OutputArgs)),
     globals.lookup_int_option(Globals,
         optimize_saved_vars_cell_cv_store_cost, CellVarStoreCost),
     globals.lookup_int_option(Globals,
@@ -278,7 +280,8 @@
     globals.lookup_bool_option(Globals,
         opt_no_return_calls, OptNoReturnCalls),
     IntParams = interval_params(ModuleInfo, VarTypes0, OptNoReturnCalls),
-    IntervalInfo0 = interval_info(IntParams, set.init, OutputArgs,
+    IntervalInfo0 = interval_info(IntParams,
+        set_of_var.init, set_to_bitset(OutputArgs),
         map.init, map.init, map.init, CurIntervalId, Counter1,
         set.make_singleton_set(CurIntervalId),
         map.init, set.init, StartMap0, EndMap0,
@@ -303,7 +306,8 @@
         record_decisions_in_goal(Goal0, Goal1, VarSet0, VarSet,
             VarTypes0, VarTypes, map.init, RenameMap,
             InsertMap, yes(feature_stack_opt)),
-        apply_headvar_correction(HeadVars, RenameMap, Goal1, Goal),
+        apply_headvar_correction(set_to_bitset(HeadVars), RenameMap,
+            Goal1, Goal),
         proc_info_set_goal(Goal, !ProcInfo),
         proc_info_set_varset(VarSet, !ProcInfo),
         proc_info_set_vartypes(VarTypes, !ProcInfo),
@@ -335,7 +339,7 @@
 opt_at_par_conj(NeedParConj, _GoalInfo, StackAlloc0, StackAlloc) :-
     NeedParConj = need_in_par_conj(StackVars),
     ParConjOwnSlots0 = StackAlloc0 ^ par_conj_own_slots,
-    ParConjOwnSlots = set.union(StackVars, ParConjOwnSlots0),
+    ParConjOwnSlots = set_of_var.union(StackVars, ParConjOwnSlots0),
     StackAlloc = StackAlloc0 ^ par_conj_own_slots := ParConjOwnSlots.
 
 %-----------------------------------------------------------------------------%
@@ -347,27 +351,31 @@
 
 :- type match_path_info
     --->    match_path_info(
-                set(prog_var),      % The set of vars referenced in
-                                    % the first interval, before
-                                    % the first flush point.
-                list(set(prog_var)) % The set of vars referenced in
-                                    % later intervals, after the
-                                    % first flush point.
+                % The set of vars referenced in the first interval,
+                % before the first flush point.
+                set_of_progvar,
+
+                % The set of vars referenced in later intervals,
+                % after the first flush point.
+                list(set_of_progvar)
             ).
 
 :- type match_info
     --->    match_info(
-                list(match_path_info),  % Information about the
-                                        % variables used along each
-                                        % path.
-                set(prog_var),          % The variables used after the
-                                        % deconstruction goes out of
-                                        % scope.
-                bool,                   % Have we stepped over a
-                                        % model_non goal?
-                set(anchor),            % The set of save points
-                                        % to which the results of the
+                % Information about the variables used along each path.
+                list(match_path_info),
+
+                % The variables used after the deconstruction
+                % goes out of scope.
+                set_of_progvar,
+
+                % Have we stepped over a model_non goal?
+                bool,
+
+                % The set of save points to which the results of the
                                         % matching applies.
+                set(anchor),
+
                 set(interval_id)
             ).
 
@@ -379,12 +387,12 @@
     FlushedLater = !.IntervalInfo ^ ii_flushed_later,
     StackOptParams = !.StackOptInfo ^ soi_stack_opt_params,
     NonCandidateVars = StackOptParams ^ sop_non_candidate_vars,
-    set.list_to_set(FieldVarList, FieldVars),
-    set.intersect(FieldVars, FlushedLater, FlushedLaterFieldVars),
-    set.difference(FlushedLaterFieldVars, NonCandidateVars,
+    FieldVars = set_of_var.list_to_set(FieldVarList),
+    set_of_var.intersect(FieldVars, FlushedLater, FlushedLaterFieldVars),
+    set_of_var.difference(FlushedLaterFieldVars, NonCandidateVars,
         CandidateArgVars0),
     (
-        set.empty(CandidateArgVars0)
+        set_of_var.is_empty(CandidateArgVars0)
     ->
         true
     ;
@@ -414,14 +422,15 @@
             fail
         )
     ->
-        RelevantVars = set.insert(FieldVars, CellVar),
+        set_of_var.insert(CellVar, FieldVars, RelevantVars),
         find_all_branches_from_cur_interval(RelevantVars, MatchInfo,
             !.IntervalInfo, !.StackOptInfo),
         MatchInfo = match_info(PathsInfo, RelevantAfterVars,
             AfterModelNon, InsertAnchors, InsertIntervals),
         (
             FreeOfCost = yes,
-            set.difference(CandidateArgVars0, RelevantAfterVars, ViaCellVars),
+            set_of_var.difference(CandidateArgVars0, RelevantAfterVars,
+                ViaCellVars),
             record_matching_result(CellVar, ConsId, FieldVarList, ViaCellVars,
                 Goal, InsertAnchors, InsertIntervals, !IntervalInfo,
                 !StackOptInfo)
@@ -430,11 +439,11 @@
             (
                 AfterModelNon = no,
                 OnStack = StackOptParams ^ sop_on_stack,
-                set.difference(CandidateArgVars0, RelevantAfterVars,
+                set_of_var.difference(CandidateArgVars0, RelevantAfterVars,
                     CandidateArgVars),
                 (
                     OnStack = yes,
-                    ( set.member(CellVar, FlushedLater) ->
+                    ( set_of_var.member(FlushedLater, CellVar) ->
                         CellVarFlushedLater = yes
                     ;
                         CellVarFlushedLater = no
@@ -445,7 +454,7 @@
                         list.member(PathInfo, PathsInfo),
                         PathInfo = match_path_info(_, Segments),
                         list.member(Segment, Segments),
-                        set.member(CellVar, Segment)
+                        set_of_var.member(Segment, CellVar)
                     ->
                         CellVarFlushedLater = yes
                     ;
@@ -467,7 +476,7 @@
 
 :- pred apply_matching(prog_var::in, bool::in, interval_params::in,
     stack_opt_params::in, list(match_path_info)::in,
-    set(prog_var)::in, set(prog_var)::out) is det.
+    set_of_progvar::in, set_of_progvar::out) is det.
 
 apply_matching(CellVar, CellVarFlushedLater, IntParams, StackOptParams,
         PathInfos, CandidateArgVars0, ViaCellVars) :-
@@ -482,13 +491,13 @@
     ( NumBenefitNodes * 100 >= NumCostNodes * AllPathNodeRatio ->
         ViaCellVars = ViaCellVars0
     ;
-        ViaCellVars = set.init
+        ViaCellVars = set_of_var.init
     ).
 
 :- pred apply_matching_loop(prog_var::in, bool::in, interval_params::in,
-    stack_opt_params::in, list(match_path_info)::in, set(prog_var)::in,
+    stack_opt_params::in, list(match_path_info)::in, set_of_progvar::in,
     list(set(benefit_node))::out, list(set(cost_node))::out,
-    set(prog_var)::out) is det.
+    set_of_progvar::out) is det.
 
 apply_matching_loop(CellVar, CellVarFlushedLater, IntParams, StackOptParams,
         PathInfos, CandidateArgVars0, BenefitNodeSets, CostNodeSets,
@@ -503,10 +512,10 @@
             PathViaCellVars = [ViaCellVars | _]
         ;
             PathViaCellVars = [],
-            ViaCellVars = set.init
+            ViaCellVars = set_of_var.init
         )
     ;
-        CandidateArgVars1 = set.intersect_list(PathViaCellVars),
+        CandidateArgVars1 = set_of_var.intersect_list(PathViaCellVars),
         FixpointLoop = StackOptParams ^ sop_fixpoint_loop,
         (
             FixpointLoop = no,
@@ -522,15 +531,15 @@
     ).
 
 :- pred apply_matching_for_path(prog_var::in, bool::in, stack_opt_params::in,
-    set(prog_var)::in, match_path_info::in,
-    set(benefit_node)::out, set(cost_node)::out, set(prog_var)::out) is det.
+    set_of_progvar::in, match_path_info::in,
+    set(benefit_node)::out, set(cost_node)::out, set_of_progvar::out) is det.
 
 apply_matching_for_path(CellVar, CellVarFlushedLater, StackOptParams,
         CandidateArgVars, PathInfo, BenefitNodes, CostNodes, ViaCellVars) :-
-    ( set.empty(CandidateArgVars) ->
+    ( set_of_var.is_empty(CandidateArgVars) ->
         BenefitNodes = set.init,
         CostNodes = set.init,
-        ViaCellVars = set.init
+        ViaCellVars = set_of_var.init
     ;
         PathInfo = match_path_info(FirstSegment, LaterSegments),
         MatchingParams = StackOptParams ^ sop_matching_params,
@@ -540,13 +549,13 @@
     ).
 
 :- pred record_matching_result(prog_var::in, cons_id::in,
-    list(prog_var)::in, set(prog_var)::in, hlds_goal::in, set(anchor)::in,
+    list(prog_var)::in, set_of_progvar::in, hlds_goal::in, set(anchor)::in,
     set(interval_id)::in, interval_info::in, interval_info::out,
     stack_opt_info::in, stack_opt_info::out) is det.
 
 record_matching_result(CellVar, ConsId, ArgVars, ViaCellVars, Goal,
         PotentialAnchors, PotentialIntervals, !IntervalInfo, !StackOptInfo) :-
-    ( set.empty(ViaCellVars) ->
+    ( set_of_var.is_empty(ViaCellVars) ->
         true
     ;
         set.to_sorted_list(PotentialIntervals, PotentialIntervalList),
@@ -568,7 +577,7 @@
         !StackOptInfo ^ soi_matching_results := MatchingResults
     ).
 
-:- pred record_cell_var_for_interval(prog_var::in, set(prog_var)::in,
+:- pred record_cell_var_for_interval(prog_var::in, set_of_progvar::in,
     interval_id::in, interval_info::in, interval_info::out,
     stack_opt_info::in, stack_opt_info::out,
     set(interval_id)::in, set(interval_id)::out) is det.
@@ -577,13 +586,13 @@
         !IntervalInfo, !StackOptInfo, !InsertIntervals) :-
     record_interval_vars(IntervalId, [CellVar], !IntervalInfo),
     delete_interval_vars(IntervalId, ViaCellVars, DeletedVars, !IntervalInfo),
-    ( set.non_empty(DeletedVars) ->
+    ( set_of_var.is_non_empty(DeletedVars) ->
         set.insert(IntervalId, !InsertIntervals)
     ;
         true
     ).
 
-:- pred add_anchor_inserts(hlds_goal::in, set(prog_var)::in,
+:- pred add_anchor_inserts(hlds_goal::in, set_of_progvar::in,
     set(interval_id)::in, anchor::in, interval_info::in,
     interval_info::out, stack_opt_info::in, stack_opt_info::out,
     set(anchor)::in, set(anchor)::out) is det.
@@ -620,24 +629,24 @@
 :- type path
     --->    path(
                 flush_state             :: current_segment_first_flush,
-                current_segment         :: set(prog_var),
-                first_segment           :: set(prog_var),
-                other_segments          :: list(set(prog_var)),
+                current_segment         :: set_of_progvar,
+                first_segment           :: set_of_progvar,
+                other_segments          :: list(set_of_progvar),
                 flush_anchors           :: set(anchor),
                 occurring_intervals     :: set(interval_id)
             ).
 
 :- type all_paths
     --->    all_paths(
-                paths_so_far            :: set(path),
                                         % The set of all paths so far.
+                paths_so_far            :: set(path),
+
+                % Have we stepped over model_non goals?
                 stepped_over_model_non  :: bool,
-                                        % Have we stepped over
-                                        % model_non goals?
-                used_after_scope        :: set(prog_var)
-                                        % The vars which are known to be used
-                                        % after the deconstruction goes out of
-                                        % scope.
+
+                % The vars which are known to be used after the deconstruction
+                % goes out of scope.
+                used_after_scope        :: set_of_progvar
             ).
 
 :- pred extract_match_and_save_info(path::in, match_path_info::out,
@@ -658,13 +667,13 @@
         FlushAnchors, IntervalIds),
     (
         FlushState = current_is_before_first_flush,
-        expect(set.empty(FirstSegment0), $module, $pred,
+        expect(set_of_var.is_empty(FirstSegment0), $module, $pred,
             "FirstSegment0 not empty"),
         FirstSegment = CurSegment,
         OtherSegments = OtherSegments0
     ;
         FlushState = current_is_after_first_flush,
-        ( set.empty(CurSegment) ->
+        ( set_of_var.is_empty(CurSegment) ->
             FirstSegment = FirstSegment0,
             OtherSegments = OtherSegments0
         ;
@@ -672,17 +681,17 @@
             OtherSegments = [CurSegment | OtherSegments0]
         )
     ),
-    Path = path(current_is_after_first_flush, set.init,
+    Path = path(current_is_after_first_flush, set_of_var.init,
         FirstSegment, OtherSegments, FlushAnchors, IntervalIds).
 
-:- func add_interval_to_path(interval_id, set(prog_var), path) = path.
+:- func add_interval_to_path(interval_id, set_of_progvar, path) = path.
 
 add_interval_to_path(IntervalId, Vars, !.Path) = !:Path :-
-    ( set.empty(Vars) ->
+    ( set_of_var.is_empty(Vars) ->
         true
     ;
         CurSegment0 = !.Path ^ current_segment,
-        CurSegment = set.union(Vars, CurSegment0),
+        CurSegment = set_of_var.union(Vars, CurSegment0),
         OccurringIntervals0 = !.Path ^ occurring_intervals,
         set.insert(IntervalId, OccurringIntervals0, OccurringIntervals),
         !Path ^ current_segment := CurSegment,
@@ -764,17 +773,17 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred find_all_branches_from_cur_interval(set(prog_var)::in,
+:- pred find_all_branches_from_cur_interval(set_of_progvar::in,
     match_info::out, interval_info::in, stack_opt_info::in) is det.
 
 find_all_branches_from_cur_interval(RelevantVars, MatchInfo, IntervalInfo,
         StackOptInfo) :-
     IntervalId = IntervalInfo ^ ii_cur_interval,
     map.lookup(IntervalInfo ^ ii_interval_vars, IntervalId, IntervalVars),
-    IntervalRelevantVars = set.intersect(RelevantVars, IntervalVars),
+    IntervalRelevantVars = set_of_var.intersect(RelevantVars, IntervalVars),
     Path0 = path(current_is_before_first_flush, IntervalRelevantVars,
-        set.init, [], set.init, set.init),
-    AllPaths0 = all_paths(set.make_singleton_set(Path0), no, set.init),
+        set_of_var.init, [], set.init, set.init),
+    AllPaths0 = all_paths(set.make_singleton_set(Path0), no, set_of_var.init),
     find_all_branches(RelevantVars, IntervalId, no, IntervalInfo,
         StackOptInfo, AllPaths0, AllPaths),
     AllPaths = all_paths(Paths, AfterModelNon, RelevantAfter),
@@ -786,7 +795,7 @@
     MatchInfo = match_info(MatchInputs, RelevantAfter, AfterModelNon,
         FlushAnchors, OccurringIntervals).
 
-:- pred find_all_branches(set(prog_var)::in, interval_id::in,
+:- pred find_all_branches(set_of_progvar::in, interval_id::in,
     maybe(anchor)::in, interval_info::in, stack_opt_info::in,
     all_paths::in, all_paths::out) is det.
 
@@ -816,17 +825,18 @@
             MaybeSearchAnchor0 = yes(SearchAnchor0),
             End = SearchAnchor0
         ->
-            !AllPaths ^ used_after_scope := set.init
+            !AllPaths ^ used_after_scope := set_of_var.init
         ;
             End = anchor_branch_end(_, EndGoalId),
             map.lookup(IntervalInfo ^ ii_branch_end_map, EndGoalId,
                 BranchEndInfo),
             OnStackAfterBranch = BranchEndInfo ^ flushed_after_branch,
             AccessedAfterBranch = BranchEndInfo ^ accessed_after_branch,
-            NeededAfterBranch = set.union(OnStackAfterBranch,
+            NeededAfterBranch = set_of_var.union(OnStackAfterBranch,
                 AccessedAfterBranch),
-            RelevantAfter = set.intersect(RelevantVars, NeededAfterBranch),
-            set.non_empty(RelevantAfter)
+            RelevantAfter = set_of_var.intersect(RelevantVars,
+                NeededAfterBranch),
+            set_of_var.is_non_empty(RelevantAfter)
         ->
             !AllPaths ^ used_after_scope := RelevantAfter
         ;
@@ -836,7 +846,7 @@
         )
     ).
 
-:- pred find_all_branches_from(anchor::in, set(prog_var)::in,
+:- pred find_all_branches_from(anchor::in, set_of_progvar::in,
     maybe(anchor)::in, interval_info::in, stack_opt_info::in,
     list(interval_id)::in, all_paths::in, all_paths::out) is det.
 
@@ -912,7 +922,7 @@
         )
     ).
 
-:- pred one_after_another(set(prog_var)::in, maybe(anchor)::in,
+:- pred one_after_another(set_of_progvar::in, maybe(anchor)::in,
     interval_info::in, stack_opt_info::in, list(interval_id)::in,
     all_paths::in, all_paths::out) is det.
 
@@ -927,7 +937,7 @@
     % We need a version of apply_interval_find_all_branches with this
     % argument order for use in higher order caode.
     %
-:- pred apply_interval_find_all_branches_map(set(prog_var)::in,
+:- pred apply_interval_find_all_branches_map(set_of_progvar::in,
     maybe(anchor)::in, interval_info::in, stack_opt_info::in,
     all_paths::in, interval_id::in, all_paths::out) is det.
 
@@ -936,14 +946,14 @@
     apply_interval_find_all_branches(RelevantVars, MaybeSearchAnchor0,
         IntervalInfo, StackOptInfo, IntervalId, !AllPaths).
 
-:- pred apply_interval_find_all_branches(set(prog_var)::in,
+:- pred apply_interval_find_all_branches(set_of_progvar::in,
     maybe(anchor)::in, interval_info::in, stack_opt_info::in,
     interval_id::in, all_paths::in, all_paths::out) is det.
 
 apply_interval_find_all_branches(RelevantVars, MaybeSearchAnchor0,
         IntervalInfo, StackOptInfo, IntervalId, !AllPaths) :-
     map.lookup(IntervalInfo ^ ii_interval_vars, IntervalId, IntervalVars),
-    RelevantIntervalVars = set.intersect(RelevantVars, IntervalVars),
+    RelevantIntervalVars = set_of_var.intersect(RelevantVars, IntervalVars),
     !.AllPaths = all_paths(Paths0, AfterModelNon0, RelevantAfter),
     Paths1 = set.map(add_interval_to_path(IntervalId, RelevantIntervalVars),
         Paths0),
@@ -956,8 +966,8 @@
         ),
         map.search(IntervalInfo ^ ii_anchor_follow_map, Start, StartInfo),
         StartInfo = anchor_follow_info(AnchorFollowVars, _),
-        set.intersect(RelevantVars, AnchorFollowVars, NeededVars),
-        set.non_empty(NeededVars)
+        set_of_var.intersect(RelevantVars, AnchorFollowVars, NeededVars),
+        set_of_var.is_non_empty(NeededVars)
     ->
         Paths2 = set.map(add_anchor_to_path(Start), Paths1)
     ;
@@ -983,7 +993,7 @@
     AfterModelNonList = list.map(project_after_model_non_from_all_paths,
         [First | Rest]),
     bool.or_list(AfterModelNonList, AfterModelNon),
-    AllPaths = all_paths(Paths, AfterModelNon, set.init).
+    AllPaths = all_paths(Paths, AfterModelNon, set_of_var.init).
 
 :- func project_paths_from_all_paths(all_paths) = set(path).
 
@@ -1050,7 +1060,7 @@
 :- pred dump_insert(insert_spec::in, io::di, io::uo) is det.
 
 dump_insert(insert_spec(Goal, Vars), !IO) :-
-    list.map(term.var_to_int, set.to_sorted_list(Vars), VarNums),
+    list.map(term.var_to_int, set_of_var.to_sorted_list(Vars), VarNums),
     io.write_string("vars [", !IO),
     write_int_list(VarNums, !IO),
     io.write_string("]: ", !IO),
@@ -1082,7 +1092,8 @@
     io.write_string("\n", !IO),
     term.var_to_int(CellVar, CellVarNum),
     list.map(term.var_to_int, ArgVars, ArgVarNums),
-    list.map(term.var_to_int, set.to_sorted_list(ViaCellVars), ViaCellVarNums),
+    list.map(term.var_to_int, set_of_var.to_sorted_list(ViaCellVars),
+        ViaCellVarNums),
     io.write_int(CellVarNum, !IO),
     io.write_string(" => ", !IO),
     write_cons_id_and_arity(ConsId, !IO),
Index: compiler/store_alloc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/store_alloc.m,v
retrieving revision 1.116
diff -u -b -r1.116 store_alloc.m
--- compiler/store_alloc.m	23 May 2011 05:08:12 -0000	1.116
+++ compiler/store_alloc.m	10 Jul 2011 22:04:49 -0000
@@ -56,6 +56,7 @@
 :- import_module ll_backend.llds.
 :- import_module ll_backend.trace_gen.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.set_of_var.
 
 :- import_module assoc_list.
 :- import_module bool.
@@ -94,16 +95,17 @@
         eff_trace_level_needs_fail_vars(ModuleInfo, PredInfo, !.ProcInfo,
             TraceLevel) = yes
     ->
-        trace_fail_vars(ModuleInfo, !.ProcInfo, ResumeVars0)
+        trace_fail_vars(ModuleInfo, !.ProcInfo, ResumeVars0),
+        ResumeVars1 = set_to_bitset(ResumeVars0)
     ;
-        set.init(ResumeVars0)
+        ResumeVars1 = set_of_var.init
     ),
     build_input_arg_list(!.ProcInfo, InputArgLvals),
     LastLocns0 = initial_last_locns(InputArgLvals),
     proc_info_get_stack_slots(!.ProcInfo, StackSlots),
     StoreAllocInfo = store_alloc_info(ModuleInfo, StackSlots),
     store_alloc_in_goal(Goal2, Goal, Liveness0, _, LastLocns0, _,
-        ResumeVars0, StoreAllocInfo),
+        ResumeVars1, StoreAllocInfo),
     proc_info_set_goal(Goal, !ProcInfo).
 
 :- func initial_last_locns(assoc_list(prog_var, lval)) = last_locns.
@@ -118,9 +120,9 @@
 :- type store_alloc_info
     --->    store_alloc_info(
                 sai_module_info     :: module_info,
+
+                % Maps each var to its stack slot (if it has one).
                 sai_stack_slots     :: stack_slots
-                                    % Maps each var to its stack slot
-                                    % (if it has one).
             ).
 
 :- type where_stored    == set(lval).   % These lvals may contain var() rvals.
@@ -128,34 +130,34 @@
 :- type last_locns  == map(prog_var, where_stored).
 
 :- pred store_alloc_in_goal(hlds_goal::in, hlds_goal::out,
-    liveness_info::in, liveness_info::out, last_locns::in, last_locns::out,
-    set(prog_var)::in, store_alloc_info::in) is det.
+    set_of_progvar::in, set_of_progvar::out, last_locns::in, last_locns::out,
+    set_of_progvar::in, store_alloc_info::in) is det.
 
-store_alloc_in_goal(hlds_goal(GoalExpr0, GoalInfo0),
-        hlds_goal(GoalExpr, GoalInfo), Liveness0, Liveness,
-        !LastLocns, ResumeVars0, StoreAllocInfo) :-
+store_alloc_in_goal(Goal0, Goal, Liveness0, Liveness, !LastLocns, ResumeVars0,
+        StoreAllocInfo) :-
+    Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
     % note: we must be careful to apply deaths before births
     goal_info_get_pre_deaths(GoalInfo0, PreDeaths),
     goal_info_get_pre_births(GoalInfo0, PreBirths),
     goal_info_get_post_deaths(GoalInfo0, PostDeaths),
     goal_info_get_post_births(GoalInfo0, PostBirths),
 
-    set.difference(Liveness0,  PreDeaths, Liveness1),
-    set.union(Liveness1, PreBirths, Liveness2),
+    set_of_var.difference(Liveness0,  PreDeaths, Liveness1),
+    set_of_var.union(Liveness1, PreBirths, Liveness2),
     store_alloc_in_goal_2(GoalExpr0, GoalExpr, Liveness2, Liveness3,
         !LastLocns, ResumeVars0, BranchedGoal, StoreAllocInfo),
-    set.difference(Liveness3, PostDeaths, Liveness4),
+    set_of_var.difference(Liveness3, PostDeaths, Liveness4),
     % If any variables magically become live in the PostBirths,
     % then they have to mundanely become live in a parallel goal,
     % so we don't need to allocate anything for them here.
-    set.union(Liveness4, PostBirths, Liveness),
+    set_of_var.union(Liveness4, PostBirths, Liveness),
     (
         BranchedGoal = is_branched_goal,
         % Any variables that become magically live at the
         % end of the goal should not be included in the store map.
         % That is why we use Liveness4 instead of Liveness here.
-        set.union(Liveness4, ResumeVars0, MappedSet),
-        set.to_sorted_list(MappedSet, MappedVars),
+        set_of_var.union(Liveness4, ResumeVars0, MappedSet),
+        MappedVars = set_of_var.to_sorted_list(MappedSet),
         ( goal_info_maybe_get_store_map(GoalInfo0, StoreMapPrime) ->
             AdvisoryStoreMap = StoreMapPrime
         ;
@@ -167,7 +169,8 @@
     ;
         BranchedGoal = is_not_branched_goal,
         GoalInfo = GoalInfo0
-    ).
+    ),
+    Goal = hlds_goal(GoalExpr, GoalInfo).
 
 %-----------------------------------------------------------------------------%
 
@@ -178,8 +181,8 @@
     % Here we process each of the different sorts of goals.
     %
 :- pred store_alloc_in_goal_2(hlds_goal_expr::in, hlds_goal_expr::out,
-    liveness_info::in, liveness_info::out,
-    last_locns::in, last_locns::out, set(prog_var)::in, branched_goal::out,
+    set_of_progvar::in, set_of_progvar::out,
+    last_locns::in, last_locns::out, set_of_progvar::in, branched_goal::out,
     store_alloc_info::in) is det.
 
 store_alloc_in_goal_2(GoalExpr0, GoalExpr, !Liveness, !LastLocns,
@@ -244,7 +247,7 @@
         GoalExpr0 = scope(Reason, SubGoal0),
         ( Reason = from_ground_term(TermVar, from_ground_term_construct) ->
             GoalExpr = GoalExpr0,
-            set.insert(TermVar, !Liveness)
+            set_of_var.insert(TermVar, !Liveness)
         ;
             store_alloc_in_goal(SubGoal0, SubGoal, !Liveness, !LastLocns,
                 ResumeVars0, StoreAllocInfo),
@@ -268,8 +271,8 @@
 %-----------------------------------------------------------------------------%
 
 :- pred store_alloc_in_conj(list(hlds_goal)::in, list(hlds_goal)::out,
-    liveness_info::in, liveness_info::out, last_locns::in, last_locns::out,
-    set(prog_var)::in, store_alloc_info::in) is det.
+    set_of_progvar::in, set_of_progvar::out, last_locns::in, last_locns::out,
+    set_of_progvar::in, store_alloc_info::in) is det.
 
 store_alloc_in_conj([], [], !Liveness, !LastLocns, _, _).
 store_alloc_in_conj([Goal0 | Goals0], [Goal | Goals], !Liveness, !LastLocns,
@@ -293,24 +296,24 @@
 %-----------------------------------------------------------------------------%
 
 :- pred store_alloc_in_par_conj(list(hlds_goal)::in, list(hlds_goal)::out,
-    liveness_info::in, liveness_info::out, last_locns::in, last_locns::out,
-    set(prog_var)::in, store_alloc_info::in) is det.
+    set_of_progvar::in, set_of_progvar::out, last_locns::in, last_locns::out,
+    set_of_progvar::in, store_alloc_info::in) is det.
 
-store_alloc_in_par_conj([], [], _Liveness0, set.init, !LastLocns, _, _).
+store_alloc_in_par_conj([], [], _Liveness0, set_of_var.init, !LastLocns, _, _).
 store_alloc_in_par_conj([Goal0 | Goals0], [Goal | Goals], Liveness0, Liveness,
         !LastLocns, ResumeVars0, StoreAllocInfo) :-
     store_alloc_in_goal(Goal0, Goal, Liveness0, Liveness1,
         !LastLocns, ResumeVars0, StoreAllocInfo),
     store_alloc_in_par_conj(Goals0, Goals, Liveness0, Liveness2,
         !LastLocns, ResumeVars0, StoreAllocInfo),
-    Liveness = set.union(Liveness1, Liveness2).
+    Liveness = set_of_var.union(Liveness1, Liveness2).
 
 %-----------------------------------------------------------------------------%
 
 :- pred store_alloc_in_disj(list(hlds_goal)::in, list(hlds_goal)::out,
-    liveness_info::in, liveness_info::out,
+    set_of_progvar::in, set_of_progvar::out,
     last_locns::in, list(last_locns)::out,
-    set(prog_var)::in, store_alloc_info::in) is det.
+    set_of_progvar::in, store_alloc_info::in) is det.
 
 store_alloc_in_disj([], [], !Liveness, _, [], _, _).
 store_alloc_in_disj([Goal0 | Goals0], [Goal | Goals], Liveness0, Liveness,
@@ -332,9 +335,9 @@
 %-----------------------------------------------------------------------------%
 
 :- pred store_alloc_in_cases(list(case)::in, list(case)::out,
-    liveness_info::in, liveness_info::out,
+    set_of_progvar::in, set_of_progvar::out,
     last_locns::in, list(last_locns)::out,
-    set(prog_var)::in, store_alloc_info::in) is det.
+    set_of_progvar::in, store_alloc_info::in) is det.
 
 store_alloc_in_cases([], [], !Liveness, _, [], _, _).
 store_alloc_in_cases([Case0 | Cases0], [Case | Cases], Liveness0, Liveness,
Index: compiler/string_switch.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/string_switch.m,v
retrieving revision 1.72
diff -u -b -r1.72 string_switch.m
--- compiler/string_switch.m	23 May 2011 05:08:12 -0000	1.72
+++ compiler/string_switch.m	10 Jul 2011 22:38:42 -0000
@@ -76,6 +76,7 @@
 :- import_module hlds.hlds_llds.
 :- import_module ll_backend.lookup_util.
 :- import_module ll_backend.switch_case.
+:- import_module parse_tree.set_of_var.
 
 :- import_module assoc_list.
 :- import_module bool.
@@ -202,7 +203,7 @@
 
 :- pred generate_string_hash_simple_lookup_switch(rval::in,
     assoc_list(string, list(rval))::in, list(prog_var)::in,
-    list(llds_type)::in, set(prog_var)::in,
+    list(llds_type)::in, set_of_progvar::in,
     can_fail::in, label::in, abs_store_map::in,
     branch_end::in, branch_end::out, llds_code::out,
     code_info::in, code_info::out) is det.
@@ -327,8 +328,8 @@
 %-----------------------------------------------------------------------------%
 
 :- pred generate_string_hash_several_soln_lookup_switch(rval::in,
-    assoc_list(string, soln_consts(rval))::in, set(prog_var)::in, bool::in,
-    list(prog_var)::in, list(llds_type)::in, set(prog_var)::in,
+    assoc_list(string, soln_consts(rval))::in, set_of_progvar::in, bool::in,
+    list(prog_var)::in, list(llds_type)::in, set_of_progvar::in,
     can_fail::in, label::in, abs_store_map::in,
     branch_end::in, branch_end::out, llds_code::out,
     code_info::in, code_info::out) is det.
@@ -679,7 +680,7 @@
 
 :- pred generate_string_binary_simple_lookup_switch(rval::in,
     assoc_list(string, list(rval))::in, list(prog_var)::in,
-    list(llds_type)::in, set(prog_var)::in,
+    list(llds_type)::in, set_of_progvar::in,
     can_fail::in, label::in, abs_store_map::in,
     branch_end::in, branch_end::out, llds_code::out,
     code_info::in, code_info::out) is det.
@@ -781,8 +782,8 @@
 %-----------------------------------------------------------------------------%
 
 :- pred generate_string_binary_several_soln_lookup_switch(rval::in,
-    assoc_list(string, soln_consts(rval))::in, set(prog_var)::in, bool::in,
-    list(prog_var)::in, list(llds_type)::in, set(prog_var)::in,
+    assoc_list(string, soln_consts(rval))::in, set_of_progvar::in, bool::in,
+    list(prog_var)::in, list(llds_type)::in, set_of_progvar::in,
     can_fail::in, label::in, abs_store_map::in,
     branch_end::in, branch_end::out, llds_code::out,
     code_info::in, code_info::out) is det.
Index: compiler/structure_reuse.lbu.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/structure_reuse.lbu.m,v
retrieving revision 1.15
diff -u -b -r1.15 structure_reuse.lbu.m
--- compiler/structure_reuse.lbu.m	23 May 2011 05:08:12 -0000	1.15
+++ compiler/structure_reuse.lbu.m	10 Jul 2011 16:53:56 -0000
@@ -43,6 +43,7 @@
 :- import_module hlds.hlds_llds.
 :- import_module parse_tree.prog_data.
 :- import_module parse_tree.prog_type.
+:- import_module parse_tree.set_of_var.
 
 :- import_module list.
 :- import_module require.
@@ -96,8 +97,11 @@
             goal_info_get_pre_births(Info0, PreBirths),
             goal_info_get_post_births(Info0, PostBirths),
             !:LBU = set.union_list([goal_info_get_lfu(Info0),
-                remove_typeinfo_vars_from_set(VarTypes, PreBirths),
-                remove_typeinfo_vars_from_set(VarTypes, PostBirths), !.LBU])
+                remove_typeinfo_vars_from_set(VarTypes,
+                    bitset_to_set(PreBirths)),
+                remove_typeinfo_vars_from_set(VarTypes,
+                    bitset_to_set(PostBirths)),
+                !.LBU])
         ;
             true
         )
@@ -176,7 +180,7 @@
     goal_info_get_resume_point(Info, ResPoint),
     (
         ResPoint = resume_point(ResVars, _),
-        Vars = remove_typeinfo_vars_from_set(VarTypes, ResVars)
+        Vars = remove_typeinfo_vars_from_set(VarTypes, bitset_to_set(ResVars))
     ;
         ResPoint = no_resume_point,
         Vars = set.init
Index: compiler/structure_reuse.lfu.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/structure_reuse.lfu.m,v
retrieving revision 1.17
diff -u -b -r1.17 structure_reuse.lfu.m
--- compiler/structure_reuse.lfu.m	23 May 2011 05:08:12 -0000	1.17
+++ compiler/structure_reuse.lfu.m	10 Jul 2011 16:54:33 -0000
@@ -46,6 +46,7 @@
 :- import_module hlds.hlds_llds.
 :- import_module hlds.hlds_pred.
 :- import_module parse_tree.prog_type.
+:- import_module parse_tree.set_of_var.
 
 :- import_module list.
 :- import_module map.
@@ -87,7 +88,7 @@
     ;
         HasSubGoals = has_subgoals,
         goal_info_get_pre_deaths(GoalInfo0, PreDeaths),
-        set.union(PreDeaths, !DeadVars),
+        set.union(bitset_to_set(PreDeaths), !DeadVars),
         forward_use_in_composite_goal(VarTypes, !Goal,
             !InstantiatedVars, !DeadVars)
     ).
@@ -104,9 +105,11 @@
     goal_info_get_post_deaths(Info, PostDeaths),
     goal_info_get_pre_deaths(Info, PreDeaths),
     !:Inst = set.union_list([
-        remove_typeinfo_vars_from_set(VarTypes, PreBirths),
-        remove_typeinfo_vars_from_set(VarTypes, PostBirths), !.Inst]),
-    !:Dead = set.union_list([PreDeaths, PostDeaths, !.Dead]).
+        remove_typeinfo_vars_from_set(VarTypes, bitset_to_set(PreBirths)),
+        remove_typeinfo_vars_from_set(VarTypes, bitset_to_set(PostBirths)),
+        !.Inst]),
+    !:Dead = set.union_list(
+        [bitset_to_set(PreDeaths), bitset_to_set(PostDeaths), !.Dead]).
 
 :- pred forward_use_in_composite_goal(vartypes::in, hlds_goal::in,
     hlds_goal::out, set(prog_var)::in, set(prog_var)::out,
Index: compiler/structure_sharing.domain.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/structure_sharing.domain.m,v
retrieving revision 1.46
diff -u -b -r1.46 structure_sharing.domain.m
--- compiler/structure_sharing.domain.m	23 May 2011 05:08:12 -0000	1.46
+++ compiler/structure_sharing.domain.m	10 Jul 2011 03:36:18 -0000
@@ -305,6 +305,7 @@
 :- import_module parse_tree.prog_ctgc.
 :- import_module parse_tree.prog_out.
 :- import_module parse_tree.prog_type.
+:- import_module parse_tree.set_of_var.
 :- import_module transform_hlds.ctgc.datastruct.
 :- import_module transform_hlds.ctgc.selector.
 :- import_module transform_hlds.ctgc.util.
@@ -606,7 +607,7 @@
     hlds_llds.goal_info_get_pre_births(GoalInfo, PreBirthSet),
     IsPreBirthArg = (pred(NumberedArg::in) is semidet :-
         Var = snd(NumberedArg),
-        set.member(Var, PreBirthSet)
+        set_of_var.member(PreBirthSet, Var)
     ),
     list.filter(IsPreBirthArg, !NumberedArgs).
 
@@ -615,14 +616,13 @@
 
 optimization_remove_deaths(ProcInfo, GoalInfo, Sharing0) = Sharing :-
     proc_info_get_headvars(ProcInfo, HeadVars),
-    set.list_to_set(HeadVars, HeadVarsSet),
+    HeadVarsSet = set_of_var.list_to_set(HeadVars),
     goal_info_get_post_deaths(GoalInfo, Deaths0),
-    %
+
     % Make sure to keep all the information about the headvars,
     % even if they are in the post deaths set.
-    %
-    set.difference(Deaths0, HeadVarsSet, Deaths),
-    set.to_sorted_list(Deaths, DeathsList),
+    set_of_var.difference(Deaths0, HeadVarsSet, Deaths),
+    DeathsList = set_of_var.to_sorted_list(Deaths),
     sharing_as_project_with_type(outproject, DeathsList, Sharing0, Sharing).
 
 add_foreign_proc_sharing(ModuleInfo, PredInfo, ProcInfo, ForeignPPId,
Index: compiler/switch_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/switch_util.m,v
retrieving revision 1.56
diff -u -b -r1.56 switch_util.m
--- compiler/switch_util.m	16 Jun 2011 06:42:15 -0000	1.56
+++ compiler/switch_util.m	9 Jul 2011 20:03:09 -0000
@@ -29,6 +29,7 @@
 :- import_module parse_tree.
 :- import_module parse_tree.prog_data.
 :- import_module parse_tree.prog_type.
+:- import_module parse_tree.set_of_var.
 
 :- import_module assoc_list.
 :- import_module bool.
@@ -120,11 +121,13 @@
             )
     ;       some_several_solns(
                 assoc_list(Key, soln_consts(Rval)),
-                set(prog_var),          % The resume vars.
-                bool                    % The Boolean "or" of the result
-                                        % of invoking goal_may_modify_trail
-                                        % on the goal_infos of the switch arms
+                % The resume vars.
+                set_of_progvar,
+
+                % The Boolean "or" of the result of invoking
+                % goal_may_modify_trail on the goal_infos of the switch arms
                                         % that are disjunctions.
+                bool
             ).
 
 :- type soln_consts(Rval)
Index: compiler/test_bitset.m
===================================================================
RCS file: compiler/test_bitset.m
diff -N compiler/test_bitset.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ compiler/test_bitset.m	19 Jul 2011 00:19:40 -0000
@@ -0,0 +1,544 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2011 The University of Melbourne.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+%
+% Test operations on bitsets by comparing the output with the output
+% from an ordinary set.
+%
+%-----------------------------------------------------------------------------%
+
+:- module test_bitset.
+
+:- interface.
+
+:- import_module enum.
+:- import_module list.
+:- import_module set.
+
+:- type test_bitset(T).
+
+:- type bitset_error(T)
+    --->    zero_argument(string,
+                test_bitset(T))
+    ;       one_argument(string,
+                test_bitset(T), test_bitset(T))
+    ;       two_arguments(string,
+                test_bitset(T), test_bitset(T), test_bitset(T)).
+
+:- func init = test_bitset(T).
+:- func singleton_set(T) = test_bitset(T) <= enum(T).
+:- func make_singleton_set(T) = test_bitset(T) <= enum(T).
+
+:- pred init(test_bitset(T)::out) is det.
+:- pred singleton_set(test_bitset(T)::out, T::in) is det <= enum(T).
+:- pred make_singleton_set(test_bitset(T)::out, T::in) is det <= enum(T).
+
+:- func count(test_bitset(T)) = int <= enum(T).
+
+%---------------
+% Tests.
+
+:- pred is_empty(test_bitset(T)::in) is semidet.
+:- pred is_non_empty(test_bitset(T)::in) is semidet.
+:- pred is_singleton(test_bitset(T)::in, T::out) is semidet <= enum(T).
+
+:- pred contains(test_bitset(T)::in, T::in) is semidet <= enum(T).
+:- pred member(T::in, test_bitset(T)::in) is semidet <= enum(T).
+:- pred equal(test_bitset(T)::in, test_bitset(T)::in) is semidet <= enum(T).
+
+:- pred subset(test_bitset(T)::in, test_bitset(T)::in) is semidet.
+:- pred superset(test_bitset(T)::in, test_bitset(T)::in) is semidet.
+
+%---------------
+% Conversions.
+
+:- func list_to_set(list(T)) = test_bitset(T) <= enum(T).
+:- func sorted_list_to_set(list(T)) = test_bitset(T) <= enum(T).
+:- func to_sorted_list(test_bitset(T)) = list(T) <= enum(T).
+
+:- pred list_to_set(list(T)::in, test_bitset(T)::out) is det <= enum(T).
+:- pred sorted_list_to_set(list(T)::in, test_bitset(T)::out) is det <= enum(T).
+:- pred to_sorted_list(test_bitset(T)::in, list(T)::out) is det <= enum(T).
+
+:- func set_to_bitset(set(T)) = test_bitset(T) <= enum(T).
+:- func bitset_to_set(test_bitset(T)) = set(T) <= enum(T).
+:- func from_set(set(T)) = test_bitset(T) <= enum(T).
+:- func to_set(test_bitset(T)) = set(T) <= enum(T).
+
+%---------------
+% Updates.
+
+:- pred insert(T::in, test_bitset(T)::in, test_bitset(T)::out)
+    is det <= enum(T).
+:- pred insert_list(list(T)::in, test_bitset(T)::in, test_bitset(T)::out)
+    is det <= enum(T).
+:- pred delete(T::in, test_bitset(T)::in, test_bitset(T)::out)
+    is det <= enum(T).
+:- pred delete_list(list(T)::in, test_bitset(T)::in, test_bitset(T)::out)
+    is det <= enum(T).
+:- pred remove(T::in, test_bitset(T)::in, test_bitset(T)::out)
+    is semidet <= enum(T).
+:- pred remove_list(list(T)::in, test_bitset(T)::in, test_bitset(T)::out)
+    is semidet <= enum(T).
+:- pred remove_least(T::out, test_bitset(T)::in, test_bitset(T)::out)
+    is semidet <= enum(T).
+
+%---------------
+% Set operations.
+
+:- func union(test_bitset(T), test_bitset(T)) = test_bitset(T) <= enum(T).
+:- func union_list(list(test_bitset(T))) = test_bitset(T) <= enum(T).
+:- func intersect(test_bitset(T), test_bitset(T)) = test_bitset(T) <= enum(T).
+:- func intersect_list(list(test_bitset(T))) = test_bitset(T) <= enum(T).
+:- func difference(test_bitset(T), test_bitset(T)) = test_bitset(T) <= enum(T).
+
+:- pred union(test_bitset(T)::in,
+    test_bitset(T)::in, test_bitset(T)::out) is det <= enum(T).
+:- pred union_list(list(test_bitset(T))::in, test_bitset(T)::out) is det
+    <= enum(T).
+:- pred intersect(test_bitset(T)::in,
+    test_bitset(T)::in, test_bitset(T)::out) is det <= enum(T).
+:- pred intersect_list(list(test_bitset(T))::in, test_bitset(T)::out) is det
+    <= enum(T).
+:- pred difference(test_bitset(T)::in,
+    test_bitset(T)::in, test_bitset(T)::out) is det <= enum(T).
+
+:- pred divide(pred(T)::in(pred(in) is semidet), test_bitset(T)::in,
+    test_bitset(T)::out, test_bitset(T)::out) is det <= enum(T).
+
+:- pred divide_by_set(test_bitset(T)::in, test_bitset(T)::in,
+    test_bitset(T)::out, test_bitset(T)::out) is det <= enum(T).
+
+%---------------
+% Traversals.
+
+:- pred foldl(pred(T, Acc, Acc), test_bitset(T), Acc, Acc) <= enum(T).
+:- mode foldl(pred(in, in, out) is det, in, in, out) is det.
+:- mode foldl(pred(in, in, out) is semidet, in, in, out) is semidet.
+
+:- func filter(pred(T)::in(pred(in) is semidet), test_bitset(T)::in)
+    = (test_bitset(T)::out) is det <= enum(T).
+:- pred filter(pred(T)::in(pred(in) is semidet),
+    test_bitset(T)::in, test_bitset(T)::out, test_bitset(T)::out)
+    is det <= enum(T).
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module bool.
+:- import_module exception.
+:- import_module int.
+:- import_module list.
+:- import_module maybe.
+:- import_module pair.
+:- import_module require.
+:- import_module set_ordlist.
+:- import_module string.
+:- import_module tree_bitset.
+
+:- type test_bitset(T) == pair(tree_bitset(T), set_ordlist(T)).
+
+%-----------------------------------------------------------------------------%
+
+init = tree_bitset.init - set_ordlist.init.
+
+singleton_set(A) =
+    tree_bitset.make_singleton_set(A) - set_ordlist.make_singleton_set(A).
+
+make_singleton_set(A) =
+    tree_bitset.make_singleton_set(A) - set_ordlist.make_singleton_set(A).
+
+init(init).
+singleton_set(test_bitset.singleton_set(A), A).
+make_singleton_set(test_bitset.make_singleton_set(A), A).
+
+count(SetA - SetB) = Count :-
+    CountA = tree_bitset.count(SetA),
+    CountB = set_ordlist.count(SetB),
+    ( CountA = CountB ->
+        Count = CountA
+    ;
+        error("test_bitset: count failed")
+    ).
+
+%-----------------------------------------------------------------------------%
+
+is_empty(A - B) :-
+    ( tree_bitset.is_empty(A) -> EmptyA = yes; EmptyA = no),
+    ( set_ordlist.is_empty(B) -> EmptyB = yes; EmptyB = no),
+    ( EmptyA = EmptyB ->
+        EmptyA = yes
+    ;
+        error("test_bitset: is_empty failed")
+    ).
+
+is_non_empty(A - B) :-
+    ( tree_bitset.is_non_empty(A) -> NonEmptyA = yes; NonEmptyA = no),
+    ( set_ordlist.non_empty(B) -> NonEmptyB = yes; NonEmptyB = no),
+    ( NonEmptyA = NonEmptyB ->
+        NonEmptyA = yes
+    ;
+        error("test_bitset: is_non_empty failed")
+    ).
+
+is_singleton(A - B, E) :-
+    ( tree_bitset.is_singleton(A, AE) -> NonEmptyA = yes(AE); NonEmptyA = no),
+    ( set_ordlist.singleton_set(B, BE) -> NonEmptyB = yes(BE); NonEmptyB = no),
+    ( NonEmptyA = NonEmptyB ->
+        NonEmptyA = yes(E)
+    ;
+        error("test_bitset: is_singleton failed")
+    ).
+
+contains(SetA - SetB, E) :-
+    ( tree_bitset.contains(SetA, E) -> InSetA = yes ; InSetA = no),
+    ( set_ordlist.contains(SetB, E) -> InSetB = yes ; InSetB = no),
+    ( InSetA = InSetB ->
+        InSetA = yes
+    ;
+        error("test_bitset: contains failed")
+    ).
+
+member(E, SetA - SetB) :-
+    ( tree_bitset.member(E, SetA) -> InSetA = yes ; InSetA = no),
+    ( set_ordlist.member(E, SetB) -> InSetB = yes ; InSetB = no),
+    ( InSetA = InSetB ->
+        InSetA = yes
+    ;
+        error("test_bitset: member failed")
+    ).
+
+equal(SetA1 - SetB1, SetA2 - SetB2) :-
+    ( tree_bitset.equal(SetA1, SetA2) -> EqualA = yes ; EqualA = no),
+    ( set_ordlist.equal(SetB1, SetB2) -> EqualB = yes ; EqualB = no),
+    ( EqualA = EqualB ->
+        EqualA = yes
+    ;
+        error("test_bitset: equal failed")
+    ).
+
+subset(SetA1 - SetB1, SetA2 - SetB2) :-
+    ( tree_bitset.subset(SetA1, SetA2) ->
+        ( set_ordlist.subset(SetB1, SetB2) ->
+            true
+        ;
+            error("test_bitset: subset succeeded unexpectedly")
+        )
+    ; set_ordlist.subset(SetB1, SetB2) ->
+        error("test_bitset: subset failed unexpectedly")
+    ;
+        fail
+    ).
+
+superset(SetA1 - SetB1, SetA2 - SetB2) :-
+    ( tree_bitset.superset(SetA1, SetA2) ->
+        ( set_ordlist.superset(SetB1, SetB2) ->
+            true
+        ;
+            error("test_bitset: superset succeeded unexpectedly")
+        )
+    ; set_ordlist.superset(SetB1, SetB2) ->
+        error("test_bitset: superset failed unexpectedly")
+    ;
+        fail
+    ).
+
+%-----------------------------------------------------------------------------%
+
+list_to_set(List) = Result :-
+    check0("list_to_set",
+        tree_bitset.list_to_set(List) - set_ordlist.list_to_set(List),
+        Result).
+
+sorted_list_to_set(List) = Result :-
+    check0("sorted_list_to_set",
+        tree_bitset.sorted_list_to_set(List) -
+            set_ordlist.sorted_list_to_set(List),
+        Result).
+
+to_sorted_list(A - B) = List :-
+    ListA = tree_bitset.to_sorted_list(A),
+    ListB = set_ordlist.to_sorted_list(B),
+    ( ListA = ListB ->
+        List = ListB
+    ;
+        error("test_bitset: to_sorted_list failed")
+    ).
+
+list_to_set(A, test_bitset.list_to_set(A)).
+sorted_list_to_set(A, test_bitset.sorted_list_to_set(A)).
+to_sorted_list(A, test_bitset.to_sorted_list(A)).
+
+set_to_bitset(Set) = A - B :-
+    set.to_sorted_list(Set, SortedList),
+    A - B = test_bitset.sorted_list_to_set(SortedList).
+
+bitset_to_set(A - B) = Set :-
+    SortedList = test_bitset.to_sorted_list(A - B),
+    set.sorted_list_to_set(SortedList, Set).
+
+from_set(Set) = set_to_bitset(Set).
+to_set(Set) = bitset_to_set(Set).
+
+%-----------------------------------------------------------------------------%
+
+insert(E, SetA0 - SetB0, Result) :-
+    tree_bitset.insert(E, SetA0, SetA),
+    set_ordlist.insert(E, SetB0, SetB),
+    check1("insert", SetA0 - SetB0, SetA - SetB, Result).
+
+insert_list(Es, SetA0 - SetB0, Result) :-
+    tree_bitset.insert_list(Es, SetA0, SetA),
+    set_ordlist.insert_list(Es, SetB0, SetB),
+    check1("insert_list", SetA0 - SetB0, SetA - SetB, Result).
+
+delete(E, SetA0 - SetB0, Result) :-
+    tree_bitset.delete(E, SetA0, SetA),
+    set_ordlist.delete(E, SetB0, SetB),
+    check1("delete", SetA0 - SetB0, SetA - SetB, Result).
+
+delete_list(Es, SetA0 - SetB0, Result) :-
+    tree_bitset.delete_list(Es, SetA0, SetA),
+    set_ordlist.delete_list(Es, SetB0, SetB),
+    check1("delete_list", SetA0 - SetB0, SetA - SetB, Result).
+
+remove(E, SetA0 - SetB0, Result) :-
+    ( tree_bitset.remove(E, SetA0, SetA1) ->
+        ( set_ordlist.remove(E, SetB0, SetB1) ->
+            SetA = SetA1,
+            SetB = SetB1
+        ;
+            error("test_bitset: remove succeeded unexpectedly")
+        )
+    ; set_ordlist.remove(E, SetB0, _) ->
+        error("test_bitset: remove failed unexpectedly")
+    ;
+        fail
+    ),
+    check1("remove", SetA0 - SetB0, SetA - SetB, Result).
+
+remove_list(Es, SetA0 - SetB0, Result) :-
+    ( tree_bitset.remove_list(Es, SetA0, SetA1) ->
+        ( set_ordlist.remove_list(Es, SetB0, SetB1) ->
+            SetA = SetA1,
+            SetB = SetB1
+        ;
+            error("test_bitset: remove succeeded unexpectedly")
+        )
+    ; set_ordlist.remove_list(Es, SetB0, _) ->
+        error("test_bitset: remove failed unexpectedly")
+    ;
+        fail
+    ),
+    check1("remove_list", SetA0 - SetB0, SetA - SetB, Result).
+
+remove_least(Least, SetA0 - SetB0, Result) :-
+    ( tree_bitset.remove_least(LeastA, SetA0, SetA1) ->
+        ( set_ordlist.remove_least(LeastB, SetB0, SetB1) ->
+            ( LeastA = LeastB ->
+                Least = LeastA,
+                check1("remove_least", SetA0 - SetB0, SetA1 - SetB1, Result)
+            ;
+                error("test_bitset: remove_least: wrong least element")
+            )
+        ;
+            error("test_bitset: remove_least: should be no least value")
+        )
+    ; set_ordlist.remove_least(_, SetB0, _) ->
+        error("test_bitset: remove_least: failed")
+    ;
+        fail
+    ).
+
+%-----------------------------------------------------------------------------%
+
+union(SetA1 - SetB1, SetA2 - SetB2) = Result :-
+    tree_bitset.union(SetA1, SetA2, SetA),
+    set_ordlist.union(SetB1, SetB2, SetB),
+    check2("union", SetA1 - SetB1, SetA2 - SetB2, SetA - SetB, Result).
+
+union_list(SetsAB) = Result :-
+    get_sets("union_list", SetsAB, SetsA, SetsB),
+    SetA = tree_bitset.union_list(SetsA),
+    SetB = set_ordlist.union_list(SetsB),
+    check0("union_list", SetA - SetB, Result).
+
+intersect(SetA1 - SetB1, SetA2 - SetB2) = Result :-
+    tree_bitset.intersect(SetA1, SetA2, SetA),
+    set_ordlist.intersect(SetB1, SetB2, SetB),
+    check2("intersect", SetA1 - SetB1, SetA2 - SetB2, SetA - SetB, Result).
+
+intersect_list(SetsAB) = Result :-
+    get_sets("intersect_list", SetsAB, SetsA, SetsB),
+    SetA = tree_bitset.intersect_list(SetsA),
+    SetB = set_ordlist.intersect_list(SetsB),
+    check0("intersect_list", SetA - SetB, Result).
+
+difference(SetA1 - SetB1, SetA2 - SetB2) = Result :-
+    tree_bitset.difference(SetA1, SetA2, SetA),
+    set_ordlist.difference(SetB1, SetB2, SetB),
+    check2("difference", SetA1 - SetB1, SetA2 - SetB2, SetA - SetB, Result).
+
+union(A, B, test_bitset.union(A, B)).
+union_list(Sets, test_bitset.union_list(Sets)).
+intersect(A, B, test_bitset.intersect(A, B)).
+intersect_list(Sets, test_bitset.intersect_list(Sets)).
+difference(A, B, test_bitset.difference(A, B)).
+
+:- pred get_sets(string::in, list(pair(tree_bitset(T), set_ordlist(T)))::in,
+    list(tree_bitset(T))::out, list(set_ordlist(T))::out) is det <= enum(T).
+
+get_sets(_, [], [], []).
+get_sets(Op, [SetA - SetB | SetsAB], [SetA | SetsA], [SetB | SetsB]) :-
+    SetListA = tree_bitset.to_sorted_list(SetA),
+    SetListB = set_ordlist.to_sorted_list(SetB),
+    ( SetListA = SetListB ->
+        get_sets(Op, SetsAB, SetsA, SetsB)
+    ;
+        error("test_bitset: get_sets: unequal sets in " ++ Op ++ " arg list")
+    ).
+
+divide(Pred, SetA - SetB, ResultIn, ResultOut) :-
+    tree_bitset.divide(Pred, SetA, InSetA, OutSetA),
+    set_ordlist.divide(Pred, SetB, InSetB, OutSetB),
+
+    SetListA = tree_bitset.to_sorted_list(SetA),
+    SetListB = set_ordlist.to_sorted_list(SetB),
+    InSetListA = tree_bitset.to_sorted_list(InSetA),
+    InSetListB = set_ordlist.to_sorted_list(InSetB),
+    OutSetListA = tree_bitset.to_sorted_list(OutSetA),
+    OutSetListB = set_ordlist.to_sorted_list(OutSetB),
+    (
+        SetListA = SetListB,
+        InSetListA = InSetListB,
+        OutSetListA = OutSetListB
+    ->
+        ResultIn = InSetA - InSetB,
+        ResultOut = OutSetA - OutSetB
+    ;
+        error("test_bitset: divide: unequal sets")
+    ).
+
+divide_by_set(DivideBySetA - DivideBySetB, SetA - SetB, ResultIn, ResultOut) :-
+    tree_bitset.divide_by_set(DivideBySetA, SetA, InSetA, OutSetA),
+    set_ordlist.divide_by_set(DivideBySetB, SetB, InSetB, OutSetB),
+
+    DivideBySetListA = tree_bitset.to_sorted_list(DivideBySetA),
+    DivideBySetListB = set_ordlist.to_sorted_list(DivideBySetB),
+    SetListA = tree_bitset.to_sorted_list(SetA),
+    SetListB = set_ordlist.to_sorted_list(SetB),
+    InSetListA = tree_bitset.to_sorted_list(InSetA),
+    InSetListB = set_ordlist.to_sorted_list(InSetB),
+    OutSetListA = tree_bitset.to_sorted_list(OutSetA),
+    OutSetListB = set_ordlist.to_sorted_list(OutSetB),
+    (
+        DivideBySetListA = DivideBySetListB,
+        SetListA = SetListB,
+        InSetListA = InSetListB,
+        OutSetListA = OutSetListB
+    ->
+        ResultIn = InSetA - InSetB,
+        ResultOut = OutSetA - OutSetB
+    ;
+        error("test_bitset: divide_by_set: unequal sets")
+    ).
+
+%-----------------------------------------------------------------------------%
+
+foldl(Pred, SetA - SetB, Acc0, Acc) :-
+    SetListA = tree_bitset.to_sorted_list(SetA),
+    SetListB = set_ordlist.to_sorted_list(SetB),
+    tree_bitset.foldl(Pred, SetA, Acc0, AccA),
+    set_ordlist.fold(Pred, SetB, Acc0, AccB),
+    ( SetListA = SetListB, AccA = AccB ->
+        Acc = AccA
+    ;
+        error("test_bitset: foldl failed")
+    ).
+
+filter(Pred, SetA - SetB) = Result :-
+    SetListA = tree_bitset.to_sorted_list(SetA),
+    SetListB = set_ordlist.to_sorted_list(SetB),
+    InSetA = tree_bitset.filter(Pred, SetA),
+    InSetB = set_ordlist.filter(Pred, SetB),
+    InSetListA = tree_bitset.to_sorted_list(InSetA),
+    InSetListB = set_ordlist.to_sorted_list(InSetB),
+    ( SetListA = SetListB, InSetListA = InSetListB ->
+        Result = InSetA - InSetB
+    ;
+        error("test_bitset: filter/2 failed")
+    ).
+
+filter(Pred, SetA - SetB, ResultIn, ResultOut) :-
+    SetListA = tree_bitset.to_sorted_list(SetA),
+    SetListB = set_ordlist.to_sorted_list(SetB),
+    tree_bitset.filter(Pred, SetA, InSetA, OutSetA),
+    set_ordlist.filter(Pred, SetB, InSetB, OutSetB),
+    InSetListA = tree_bitset.to_sorted_list(InSetA),
+    InSetListB = set_ordlist.to_sorted_list(InSetB),
+    OutSetListA = tree_bitset.to_sorted_list(OutSetA),
+    OutSetListB = set_ordlist.to_sorted_list(OutSetB),
+    ( SetListA = SetListB, InSetListA = InSetListB, OutSetListA = OutSetListB ->
+        ResultIn = InSetA - InSetB,
+        ResultOut = OutSetA - OutSetB
+    ;
+        error("test_bitset: filter/4 failed")
+    ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred check0(string::in, test_bitset(T)::in, test_bitset(T)::out) is det
+    <= enum(T).
+
+check0(Op, Tester, Result) :-
+    Tester = BitSet - Set,
+    BitSetList = tree_bitset.to_sorted_list(BitSet),
+    SetList = set_ordlist.to_sorted_list(Set),
+    ( BitSetList = SetList ->
+        Result = Tester
+    ;
+        throw(zero_argument(Op, Tester))
+    ).
+
+:- pred check1(string::in, test_bitset(T)::in, test_bitset(T)::in,
+    test_bitset(T)::out) is det <= enum(T).
+
+check1(Op, TesterA, Tester, Result) :-
+    TesterA = BitSetA - SetA,
+    BitSetListA = tree_bitset.to_sorted_list(BitSetA),
+    SetListA = set_ordlist.to_sorted_list(SetA),
+    Tester = BitSet - Set,
+    BitSetList = tree_bitset.to_sorted_list(BitSet),
+    SetList = set_ordlist.to_sorted_list(Set),
+    ( BitSetListA = SetListA, BitSetList = SetList ->
+        Result = Tester
+    ;
+        throw(one_argument(Op, TesterA, Tester))
+    ).
+
+:- pred check2(string::in, test_bitset(T)::in, test_bitset(T)::in,
+    test_bitset(T)::in, test_bitset(T)::out) is det <= enum(T).
+
+check2(Op, TesterA, TesterB, Tester, Result) :-
+    TesterA = BitSetA - SetA,
+    BitSetListA = tree_bitset.to_sorted_list(BitSetA),
+    SetListA = set_ordlist.to_sorted_list(SetA),
+    TesterB = BitSetB - SetB,
+    BitSetListB = tree_bitset.to_sorted_list(BitSetB),
+    SetListB = set_ordlist.to_sorted_list(SetB),
+    Tester = BitSet - Set,
+    BitSetList = tree_bitset.to_sorted_list(BitSet),
+    SetList = set_ordlist.to_sorted_list(Set),
+
+    ( BitSetListA = SetListA, BitSetListB = SetListB, BitSetList = SetList ->
+        Result = Tester
+    ;
+        throw(two_arguments(Op, TesterA, TesterB, Tester))
+    ).
+
+%-----------------------------------------------------------------------------%
Index: compiler/trace_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/trace_gen.m,v
retrieving revision 1.38
diff -u -b -r1.38 trace_gen.m
--- compiler/trace_gen.m	24 May 2011 00:53:02 -0000	1.38
+++ compiler/trace_gen.m	10 Jul 2011 04:10:29 -0000
@@ -244,6 +244,7 @@
 :- import_module ll_backend.layout_out.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_type.
+:- import_module parse_tree.set_of_var.
 
 :- import_module bool.
 :- import_module cord.
@@ -261,25 +262,27 @@
 :- type trace_port_info
     --->    port_info_external
     ;       port_info_tailrec_call(
-                forward_goal_path,
                 % The id of the tail recursive call.
-                assoc_list(prog_var, arg_info)
+                forward_goal_path,
+
                 % The list of arguments of this call.
+                assoc_list(prog_var, arg_info)
             )
     ;       port_info_internal(
-                forward_goal_path,
                 % The id of the goal whose start this port represents.
-                set(prog_var)
+                forward_goal_path,
+
                 % The pre-death set of this goal.
+                set_of_progvar
             )
     ;       port_info_negation_end(
-                forward_goal_path
                 % The id of the goal whose end (one way or another)
                 % this port represents.
+                forward_goal_path
             )
     ;       port_info_user(
-                forward_goal_path
                 % The id of the goal.
+                forward_goal_path
             ).
 
 trace_fail_vars(ModuleInfo, ProcInfo, FailVars) :-
@@ -1033,8 +1036,8 @@
     ;
         PortInfo = port_info_internal(Path, PreDeaths),
         ResumeVars = current_resume_point_vars(!.CI),
-        set.difference(PreDeaths, ResumeVars, RealPreDeaths),
-        set.to_sorted_list(RealPreDeaths, RealPreDeathList),
+        set_of_var.difference(PreDeaths, ResumeVars, RealPreDeaths),
+        RealPreDeathList = set_of_var.to_sorted_list(RealPreDeaths),
         list.delete_elems(LiveVars0, RealPreDeathList, LiveVars),
         TailRecResetCode = empty
     ;
Index: compiler/tupling.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/tupling.m,v
retrieving revision 1.62
diff -u -b -r1.62 tupling.m
--- compiler/tupling.m	23 May 2011 05:08:14 -0000	1.62
+++ compiler/tupling.m	18 Jul 2011 03:10:19 -0000
@@ -122,6 +122,7 @@
 :- import_module parse_tree.prog_mode.
 :- import_module parse_tree.prog_type.
 :- import_module parse_tree.prog_util.
+:- import_module parse_tree.set_of_var.
 :- import_module transform_hlds.dependency_graph.
 
 :- import_module assoc_list.
@@ -500,7 +501,7 @@
     --->    no_tupling
     ;       tupling(
                 cell_var            :: prog_var,
-                field_vars          :: prog_vars,
+                field_vars          :: list(prog_var),
                 field_var_arg_pos   :: assoc_list(prog_var, int)
             ).
 
@@ -670,7 +671,7 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred make_transformed_proc(prog_var::in, prog_vars::in, insert_map::in,
+:- pred make_transformed_proc(prog_var::in, list(prog_var)::in, insert_map::in,
     proc_info::in, proc_info::out) is det.
 
 make_transformed_proc(CellVar, FieldVarsList, InsertMap, !ProcInfo) :-
@@ -707,14 +708,15 @@
     %
     deconstruct_tuple(CellVar, FieldVarsList, ProcStartDeconstruct),
     ProcStartInsert = insert_spec(ProcStartDeconstruct,
-        set.from_list(FieldVarsList)),
+        set_of_var.list_to_set(FieldVarsList)),
     insert_proc_start_deconstruction(Goal1, Goal2,
         VarSet1, VarSet, VarTypes1, VarTypes,
         RenameMapB, ProcStartInsert),
     rename_some_vars_in_goal(RenameMapB, Goal2, Goal3),
 
     map.old_merge(RenameMapA, RenameMapB, RenameMap),
-    apply_headvar_correction(set.from_list(HeadVars), RenameMap, Goal3, Goal),
+    apply_headvar_correction(set_of_var.list_to_set(HeadVars), RenameMap,
+        Goal3, Goal),
     proc_info_set_goal(Goal, !ProcInfo),
     proc_info_set_varset(VarSet, !ProcInfo),
     proc_info_set_vartypes(VarTypes, !ProcInfo),
@@ -830,8 +832,8 @@
 
 :- type count_state
     --->    count_state(
-                cs_reg_vars             :: set(prog_var),
-                cs_stack_vars           :: set(prog_var),
+                cs_reg_vars             :: set_of_progvar,
+                cs_stack_vars           :: set_of_progvar,
                 cs_load_costs           :: float,
                 cs_store_costs          :: float
             ).
@@ -889,8 +891,8 @@
             !ReverseGoalPathMapMap),
         proc_info_get_goal(!.ProcInfo, Goal0),
         OptTupleAlloc0 = opt_tuple_alloc,
-        set.init(FailVars),
-        set.init(NondetLiveness0),
+        FailVars = set_of_var.init,
+        NondetLiveness0 = set_of_var.init,
         build_live_sets_in_goal_no_par_stack(Goal0, Goal, FailVars, AllocData,
             OptTupleAlloc0, _OptTupleAlloc, Liveness0, _Liveness,
             NondetLiveness0, _NondetLiveness),
@@ -994,7 +996,7 @@
     ProcInfo = CountInfo ^ ci_proc,
     ModuleInfo = CountInfo ^ ci_module,
     initial_liveness(ProcInfo, PredId, ModuleInfo, InitialLiveness),
-    CountState0 = count_state(InitialLiveness, set.init, 0.0, 0.0),
+    CountState0 = count_state(InitialLiveness, set_of_var.init, 0.0, 0.0),
     proc_info_get_goal(ProcInfo, Goal),
     count_load_stores_in_goal(Goal, CountInfo, CountState0, CountState1),
     arg_info.partition_proc_args(ProcInfo, ModuleInfo, _, OutputArgs, _),
@@ -1068,7 +1070,7 @@
                 length(InputArgs), _, GenericVarsArgInfos, _, _),
             assoc_list.keys(GenericVarsArgInfos, GenericVars),
             list.append(GenericVars, InputArgs, Inputs),
-            set.list_to_set(OutputArgs, Outputs),
+            Outputs = set.list_to_set(OutputArgs),
             count_load_stores_for_call(CountInfo, Inputs, Outputs,
                 MaybeNeedAcrossCall, GoalInfo, !CountState)
         ;
@@ -1171,12 +1173,8 @@
 
 %-----------------------------------------------------------------------------%
 
-:- inst call_goal_expr
-    ==  bound(plain_call(ground, ground, ground, ground, ground, ground)).
-:- mode in_call_goal
-    ==  in(call_goal_expr).
-
-:- pred count_load_stores_in_call_to_tupled(hlds_goal_expr::in_call_goal,
+:- pred count_load_stores_in_call_to_tupled(
+    hlds_goal_expr::in(goal_expr_plain_call),
     hlds_goal_info::in, count_info::in,
     tupling_proposal::in(bound(tupling(ground, ground, ground))),
     count_state::in, count_state::out) is det.
@@ -1228,7 +1226,8 @@
     count_load_stores_for_call(CountInfo, Inputs, Outputs,
         MaybeNeedAcrossCall, GoalInfo, !CountState).
 
-:- pred count_load_stores_in_call_to_not_tupled(hlds_goal_expr::in_call_goal,
+:- pred count_load_stores_in_call_to_not_tupled(
+    hlds_goal_expr::in(goal_expr_plain_call),
     hlds_goal_info::in, count_info::in, count_state::in, count_state::out)
     is det.
 
@@ -1241,23 +1240,23 @@
     ProcInfo = CountInfo ^ ci_proc,
     proc_info_get_vartypes(ProcInfo, VarTypes),
     arg_info.partition_proc_call_args(CalleeProcInfo, VarTypes,
-        ModuleInfo, ArgVars, InputArgs, Outputs, _),
+        ModuleInfo, ArgVars, InputArgs, OutputArgs, _),
     set.to_sorted_list(InputArgs, Inputs),
+    set.to_sorted_list(OutputArgs, Outputs),
     (
         Builtin = inline_builtin,
         cls_require_in_regs(CountInfo, Inputs, !CountState),
-        cls_put_in_regs(set.to_sorted_list(Outputs), !CountState)
+        cls_put_in_regs(Outputs, !CountState)
     ;
         ( Builtin = out_of_line_builtin
         ; Builtin = not_builtin
         ),
-        goal_info_get_maybe_need_across_call(GoalInfo,
-            MaybeNeedAcrossCall),
-        count_load_stores_for_call(CountInfo, Inputs, Outputs,
+        goal_info_get_maybe_need_across_call(GoalInfo, MaybeNeedAcrossCall),
+        count_load_stores_for_call(CountInfo, Inputs, OutputArgs,
             MaybeNeedAcrossCall, GoalInfo, !CountState)
     ).
 
-:- pred count_load_stores_for_call(count_info::in, prog_vars::in,
+:- pred count_load_stores_for_call(count_info::in, list(prog_var)::in,
     set(prog_var)::in, maybe(need_across_call)::in,
     hlds_goal_info::in, count_state::in, count_state::out) is det.
 
@@ -1268,7 +1267,8 @@
         MaybeNeedAcrossCall = yes(NeedAcrossCall),
         NeedAcrossCall = need_across_call(ForwardVars,
             ResumeVars, NondetLiveVars),
-        AllVars = set.union_list([ForwardVars, ResumeVars, NondetLiveVars]),
+        AllVars = set_of_var.union_list(
+            [ForwardVars, ResumeVars, NondetLiveVars]),
         cls_require_flushed(CountInfo, AllVars, !CountState),
         cls_clobber_regs(Outputs, !CountState)
     ;
@@ -1337,8 +1337,8 @@
 
     % Make the values of the given variables available in registers.
     %
-:- pred cls_require_in_regs(count_info::in, prog_vars::in, count_state::in,
-    count_state::out) is det.
+:- pred cls_require_in_regs(count_info::in, list(prog_var)::in,
+    count_state::in, count_state::out) is det.
 
 cls_require_in_regs(CountInfo, Vars, !CountState) :-
     list.foldl(cls_require_in_reg(CountInfo), Vars, !CountState).
@@ -1373,18 +1373,18 @@
 cls_require_field_var_in_reg(CountInfo, TuplingProposal, FieldVar,
         CountState0, CountState) :-
     CountState0 = count_state(RegVars0, StackVars, Loads0, Stores),
-    ( set.member(FieldVar, RegVars0) ->
+    ( set_of_var.member(RegVars0, FieldVar) ->
         CountState = CountState0
     ;
         TuplingProposal = tupling(CellVar, _, _),
         TuningParams = CountInfo ^ ci_params,
         CvLoadCost = float(TuningParams ^ tp_cell_var_load_cost),
         FvLoadCost = float(TuningParams ^ tp_field_var_load_cost),
-        ( set.member(CellVar, RegVars0) ->
-            set.insert(FieldVar, RegVars0, RegVars),
+        ( set_of_var.member(RegVars0, CellVar) ->
+            set_of_var.insert(FieldVar, RegVars0, RegVars),
             Loads = Loads0 + FvLoadCost
         ;
-            set.insert_list([CellVar, FieldVar], RegVars0, RegVars),
+            set_of_var.insert_list([CellVar, FieldVar], RegVars0, RegVars),
             Loads = Loads0 + CvLoadCost + FvLoadCost
         ),
         CountState = count_state(RegVars, StackVars, Loads, Stores)
@@ -1395,26 +1395,26 @@
 
 cls_require_var_in_reg_with_cost(LoadCost, Var, CountState0, CountState) :-
     CountState0 = count_state(RegVars0, StackVars, Loads0, Stores),
-    ( set.member(Var, RegVars0) ->
+    ( set_of_var.member(RegVars0, Var) ->
         CountState = CountState0
     ;
-        set.insert(Var, RegVars0, RegVars),
+        set_of_var.insert(Var, RegVars0, RegVars),
         Loads = Loads0 + float(LoadCost),
         CountState = count_state(RegVars, StackVars, Loads, Stores)
     ).
 
     % Put the values of the given variables into registers.
     %
-:- pred cls_put_in_regs(prog_vars::in, count_state::in, count_state::out)
+:- pred cls_put_in_regs(list(prog_var)::in, count_state::in, count_state::out)
     is det.
 
 cls_put_in_regs(Vars, !CountState) :-
     RegVars0 = !.CountState ^ cs_reg_vars,
-    set.insert_list(Vars, RegVars0, RegVars),
+    set_of_var.insert_list(Vars, RegVars0, RegVars),
     !CountState ^ cs_reg_vars := RegVars.
 
 :- pred cls_put_in_regs_via_deconstruct(count_info::in, prog_var::in,
-    prog_vars::in, count_state::in, count_state::out) is det.
+    list(prog_var)::in, count_state::in, count_state::out) is det.
 
 cls_put_in_regs_via_deconstruct(CountInfo,
         DeconstructCellVar, DeconstructFieldVars, !State) :-
@@ -1452,13 +1452,13 @@
     % Copy the given variables to the stack, if they have not been copied
     % previously.
     %
-:- pred cls_require_flushed(count_info::in, set(prog_var)::in,
+:- pred cls_require_flushed(count_info::in, set_of_progvar::in,
     count_state::in, count_state::out) is det.
 
 cls_require_flushed(CountInfo, Vars, !CountState) :-
     TuplingProposal = get_own_tupling_proposal(CountInfo),
     TuningParams = CountInfo ^ ci_params,
-    set.fold(cls_require_flushed_2(TuplingProposal, TuningParams),
+    set_of_var.fold(cls_require_flushed_2(TuplingProposal, TuningParams),
         Vars, !CountState).
 
 :- pred cls_require_flushed_2(tupling_proposal::in, tuning_params::in,
@@ -1484,11 +1484,11 @@
 cls_require_flushed_with_cost(StoreCost, Var,
         count_state(RegVars, StackVars0, Loads, Stores0),
         count_state(RegVars, StackVars, Loads, Stores)) :-
-    ( set.member(Var, StackVars0) ->
+    ( set_of_var.member(StackVars0, Var) ->
         StackVars = StackVars0,
         Stores = Stores0
     ;
-        StackVars = StackVars0 `insert` Var,
+        set_of_var.insert(Var, StackVars0, StackVars),
         Stores = Stores0 + float(StoreCost)
     ).
 
@@ -1501,7 +1501,7 @@
     is det.
 
 cls_clobber_regs(NewVars, !CountState) :-
-    !CountState ^ cs_reg_vars := NewVars.
+    !CountState ^ cs_reg_vars := set_to_bitset(NewVars).
 
 %-----------------------------------------------------------------------------%
 
@@ -1539,10 +1539,10 @@
     EndMap = map.singleton(CurIntervalId, anchor_proc_end),
     StartMap = map.init,
     SuccMap = map.singleton(CurIntervalId, []),
-    VarsMap = map.singleton(CurIntervalId, OutputArgs),
+    VarsMap = map.singleton(CurIntervalId, set_to_bitset(OutputArgs)),
     IntParams = interval_params(ModuleInfo, VarTypes, no),
-    IntervalInfo0 = interval_info(IntParams, set.init,
-        OutputArgs, map.init, map.init, map.init,
+    IntervalInfo0 = interval_info(IntParams, set_of_var.init,
+        set_to_bitset(OutputArgs), map.init, map.init, map.init,
         CurIntervalId, Counter,
         set.make_singleton_set(CurIntervalId),
         map.init, set.init, StartMap, EndMap,
@@ -1567,22 +1567,22 @@
     % deconstruction unification that is to be inserted _after_ the
     % interval beginning with that left anchor.
     %
-:- pred build_insert_map(prog_var::in, prog_vars::in, interval_info::in,
+:- pred build_insert_map(prog_var::in, list(prog_var)::in, interval_info::in,
     insert_map::out) is det.
 
 build_insert_map(CellVar, FieldVars, IntervalInfo, InsertMap) :-
-    FieldVarsSet = set.from_list(FieldVars),
+    FieldVarsSet = set_of_var.list_to_set(FieldVars),
     map.foldl(build_insert_map_2(CellVar, FieldVars, FieldVarsSet),
         IntervalInfo ^ ii_anchor_follow_map, map.init, InsertMap).
 
-:- pred build_insert_map_2(prog_var::in, list(prog_var)::in, set(prog_var)::in,
+:- pred build_insert_map_2(prog_var::in, list(prog_var)::in, set_of_progvar::in,
     anchor::in, anchor_follow_info::in, insert_map::in, insert_map::out)
     is det.
 
 build_insert_map_2(CellVar, FieldVars, FieldVarsSet, Anchor,
         anchor_follow_info(FollowVars, _), !InsertMap) :-
-    NeededFieldVars = FieldVarsSet `set.intersect` FollowVars,
-    ( set.empty(NeededFieldVars) ->
+    NeededFieldVars = FieldVarsSet `set_of_var.intersect` FollowVars,
+    ( set_of_var.is_empty(NeededFieldVars) ->
         true
     ;
         deconstruct_tuple(CellVar, FieldVars, Goal),
@@ -1610,7 +1610,7 @@
         A = insert_spec(Goal, ASet),
         B = insert_spec(Goal, BSet)
     ->
-        C = insert_spec(Goal, ASet `set.union` BSet),
+        C = insert_spec(Goal, ASet `set_of_var.union` BSet),
         Cs = Bs
     ;
         C = B,
@@ -1705,10 +1705,9 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred fix_calls_in_goal(hlds_goal::in, hlds_goal::out, prog_varset::in,
-    prog_varset::out, vartypes::in, vartypes::out,
-    rtti_varmaps::in, rtti_varmaps::out, transform_map::in)
-    is det.
+:- pred fix_calls_in_goal(hlds_goal::in, hlds_goal::out,
+    prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
+    rtti_varmaps::in, rtti_varmaps::out, transform_map::in) is det.
 
 fix_calls_in_goal(Goal0, Goal, !VarSet, !VarTypes, !RttiVarMaps,
         TransformMap) :-
@@ -1743,7 +1742,7 @@
                 unexpected($module, $pred, "not a call template")
             ),
             conj_list_to_goal([ConstructGoal, CallGoal], GoalInfo0, Goal1),
-            RequantifyVars = set.from_list([CellVar | Args0]),
+            RequantifyVars = set_of_var.list_to_set([CellVar | Args0]),
             implicitly_quantify_goal_general(ordinary_nonlocals_no_lambda,
                 RequantifyVars, _, Goal1, Goal,
                 !VarSet, !VarTypes, !RttiVarMaps)
@@ -1869,15 +1868,15 @@
     % Note again that the ordering of Selected and NotSelected are
     % determined by different lists!
     %
-:- pred extract_tupled_args_from_list(prog_vars::in, list(int)::in,
-    prog_vars::out, prog_vars::out) is det.
+:- pred extract_tupled_args_from_list(list(prog_var)::in, list(int)::in,
+    list(prog_var)::out, list(prog_var)::out) is det.
 
 extract_tupled_args_from_list(ArgList, Indices, Selected, NotSelected) :-
     list.map(list.det_index1(ArgList), Indices, Selected),
     extract_tupled_args_from_list_2(ArgList, 1, Indices, NotSelected).
 
-:- pred extract_tupled_args_from_list_2(prog_vars::in, int::in, list(int)::in,
-    prog_vars::out) is det.
+:- pred extract_tupled_args_from_list_2(list(prog_var)::in, int::in,
+    list(int)::in, list(prog_var)::out) is det.
 
 extract_tupled_args_from_list_2([], _Num, _Indices, []).
 extract_tupled_args_from_list_2([H | T], Num, Indices, NotSelected) :-
Index: compiler/unify_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unify_gen.m,v
retrieving revision 1.206
diff -u -b -r1.206 unify_gen.m
--- compiler/unify_gen.m	5 Jul 2011 03:34:34 -0000	1.206
+++ compiler/unify_gen.m	10 Jul 2011 16:53:08 -0000
@@ -81,6 +81,7 @@
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
 :- import_module parse_tree.prog_type.
+:- import_module parse_tree.set_of_var.
 
 :- import_module assoc_list.
 :- import_module bool.
@@ -1599,7 +1600,7 @@
                     ActiveMap0, ActiveMap),
                 map.to_assoc_list(ActiveMap, ActivePairs),
                 ( ActivePairs = [TermVar - GroundTerm] ->
-                    add_forward_live_vars(NonLocals, !CI),
+                    add_forward_live_vars(set_to_bitset(NonLocals), !CI),
                     set_static_cell_info(StaticCellInfo, !CI),
                     GroundTerm = Rval - _,
                     assign_const_to_var(TermVar, Rval, !CI)
Index: compiler/unused_args.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unused_args.m,v
retrieving revision 1.170
diff -u -b -r1.170 unused_args.m
--- compiler/unused_args.m	23 May 2011 05:08:15 -0000	1.170
+++ compiler/unused_args.m	10 Jul 2011 21:37:21 -0000
@@ -106,6 +106,7 @@
 :- import_module parse_tree.prog_out.
 :- import_module parse_tree.prog_type.
 :- import_module parse_tree.prog_util.
+:- import_module parse_tree.set_of_var.
 :- import_module transform_hlds.mmc_analysis.
 
 :- import_module bool.
@@ -1211,7 +1212,7 @@
         not_builtin, no, qualified(PredModule, PredName)),
     Goal1 = hlds_goal(GoalExpr, GoalInfo1),
     implicitly_quantify_goal_general(ordinary_nonlocals_no_lambda,
-        NonLocals, _, Goal1, Goal, VarSet0, VarSet,
+        set_to_bitset(NonLocals), _, Goal1, Goal, VarSet0, VarSet,
         VarTypes1, VarTypes, RttiVarMaps0, RttiVarMaps),
     proc_info_set_goal(Goal, !OldProc),
     proc_info_set_varset(VarSet, !OldProc),
@@ -1376,7 +1377,7 @@
         (
             Changed = yes,
             % If anything has changed, rerun quantification.
-            set.list_to_set(HeadVars, NonLocals),
+            NonLocals = set_of_var.list_to_set(HeadVars),
             proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
             implicitly_quantify_goal_general(ordinary_nonlocals_no_lambda,
                 NonLocals, _, !Goal, VarSet1, VarSet, VarTypes1, VarTypes,
cvs diff: Diffing compiler/notes
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/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_cairo
cvs diff: Diffing extras/graphics/mercury_cairo/samples
cvs diff: Diffing extras/graphics/mercury_cairo/samples/data
cvs diff: Diffing extras/graphics/mercury_cairo/tutorial
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/monte
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
Index: library/map.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/map.m,v
retrieving revision 1.126
diff -u -b -r1.126 map.m
--- library/map.m	19 May 2011 13:11:45 -0000	1.126
+++ library/map.m	17 Jul 2011 23:13:36 -0000
@@ -274,12 +274,19 @@
 :- pred map.overlay_large_map(map(K, V)::in, map(K, V)::in, map(K, V)::out)
     is det.
 
-    % map.select takes a map and a set of keys and returns a map
+    % map.select takes a map and a set of keys, and returns a map
     % containing the keys in the set and their corresponding values.
     %
 :- func map.select(map(K, V), set(K)) = map(K, V).
 :- pred map.select(map(K, V)::in, set(K)::in, map(K, V)::out) is det.
 
+    % map.select_sorted_list takes a map and a sorted list of keys, and returns
+    % a map containing the keys in the list and their corresponding values.
+    %
+:- func map.select_sorted_list(map(K, V), list(K)) = map(K, V).
+:- pred map.select_sorted_list(map(K, V)::in, list(K)::in, map(K, V)::out)
+    is det.
+
     % Given a list of keys, produce a list of their corresponding
     % values in a specified map.
     %
@@ -694,6 +701,9 @@
 :- pragma type_spec(map.select/2, K = var(_)).
 :- pragma type_spec(map.select/3, K = var(_)).
 
+:- pragma type_spec(map.select_sorted_list/2, K = var(_)).
+:- pragma type_spec(map.select_sorted_list/3, K = var(_)).
+
 :- pragma type_spec(map.elem/2, K = int).
 :- pragma type_spec(map.elem/2, K = var(_)).
 
@@ -1034,23 +1044,30 @@
 map.select(M1, S) = M2 :-
     map.select(M1, S, M2).
 
+map.select_sorted_list(M1, S) = M2 :-
+    map.select_sorted_list(M1, S, M2).
+
 map.select(Original, KeySet, NewMap) :-
-    set.to_sorted_list(KeySet, KeyList),
+    set.to_sorted_list(KeySet, Keys),
+    map.init(NewMap0),
+    map.select_loop(Keys, Original, NewMap0, NewMap).
+
+map.select_sorted_list(Original, Keys, NewMap) :-
     map.init(NewMap0),
-    map.select_2(KeyList, Original, NewMap0, NewMap).
+    map.select_loop(Keys, Original, NewMap0, NewMap).
 
-:- pred map.select_2(list(K)::in, map(K, V)::in,
+:- pred map.select_loop(list(K)::in, map(K, V)::in,
     map(K, V)::in, map(K, V)::out) is det.
-:- pragma type_spec(map.select_2/4, K = var(_)).
+:- pragma type_spec(map.select_loop/4, K = var(_)).
 
-map.select_2([], _Original, !New).
-map.select_2([K|Ks], Original, !New) :-
+map.select_loop([], _Original, !New).
+map.select_loop([K | Ks], Original, !New) :-
     ( map.search(Original, K, V) ->
-        map.set(K, V, !New)
+        map.det_insert(K, V, !New)
     ;
         true
     ),
-    map.select_2(Ks, Original, !New).
+    map.select_loop(Ks, Original, !New).
 
 %-----------------------------------------------------------------------------%
 
Index: library/set_ordlist.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/set_ordlist.m,v
retrieving revision 1.39
diff -u -b -r1.39 set_ordlist.m
--- library/set_ordlist.m	26 May 2011 06:20:09 -0000	1.39
+++ library/set_ordlist.m	19 Jul 2011 05:44:58 -0000
@@ -66,6 +66,7 @@
 :- mode set_ordlist.singleton_set(out, in) is det.
 
 :- func set_ordlist.make_singleton_set(T) = set_ordlist(T).
+:- pred set_ordlist.is_singleton(set_ordlist(T)::in, T::out) is semidet.
 
     % `set_ordlist.equal(SetA, SetB)' is true iff
     % `SetA' and `SetB' contain the same elements.
@@ -75,10 +76,10 @@
     % `set_ordlist.empty(Set)' is true iff `Set' is an empty set.
     %
 :- pred set_ordlist.empty(set_ordlist(_T)::in) is semidet.
+:- pred set_ordlist.is_empty(set_ordlist(T)::in) is semidet.
 
 :- pred set_ordlist.non_empty(set_ordlist(T)::in) is semidet.
-
-:- pred set_ordlist.is_empty(set_ordlist(T)::in) is semidet.
+:- pred set_ordlist.is_non_empty(set_ordlist(T)::in) is semidet.
 
     % `set_ordlist.subset(SetA, SetB)' is true iff `SetA' is a subset of
     % `SetB'.
@@ -168,12 +169,13 @@
     %
 :- pred set_ordlist.union(set_ordlist(T)::in, set_ordlist(T)::in,
     set_ordlist(T)::out) is det.
-
 :- func set_ordlist.union(set_ordlist(T), set_ordlist(T)) = set_ordlist(T).
 
     % `set_ordlist.union_list(A, B)' is true iff `B' is the union of
     % all the sets in `A'
     %
+:- pred set_ordlist.union_list(list(set_ordlist(T))::in, set_ordlist(T)::out)
+    is det.
 :- func set_ordlist.union_list(list(set_ordlist(T))) = set_ordlist(T).
 
     % `set_ordlist.power_union(A, B)' is true iff `B' is the union of
@@ -181,7 +183,6 @@
     %
 :- pred set_ordlist.power_union(set_ordlist(set_ordlist(T))::in,
     set_ordlist(T)::out) is det.
-
 :- func set_ordlist.power_union(set_ordlist(set_ordlist(T))) = set_ordlist(T).
 
     % `set_ordlist.intersect(SetA, SetB, Set)' is true iff `Set' is the
@@ -191,7 +192,6 @@
 :- pred set_ordlist.intersect(set_ordlist(T), set_ordlist(T), set_ordlist(T)).
 :- mode set_ordlist.intersect(in, in, out) is det.
 :- mode set_ordlist.intersect(in, in, in) is semidet.
-
 :- func set_ordlist.intersect(set_ordlist(T), set_ordlist(T))
     = set_ordlist(T).
 
@@ -207,6 +207,8 @@
     % intersection of all the sets in `A'.
     %
 :- func set_ordlist.intersect_list(list(set_ordlist(T))) = set_ordlist(T).
+:- pred set_ordlist.intersect_list(list(set_ordlist(T))::in,
+    set_ordlist(T)::out) is det.
 
     % `set_ordlist.difference(SetA, SetB, Set)' is true iff `Set' is the
     % set containing all the elements of `SetA' except those that
@@ -378,19 +380,18 @@
 :- import_module term.  % for var/1.
 
 :- pragma type_spec(set_ordlist.list_to_set/2, T = var(_)).
-
 :- pragma type_spec(set_ordlist.member(in, in), T = var(_)).
-
 :- pragma type_spec(set_ordlist.contains(in, in), T = var(_)).
-
 :- pragma type_spec(set_ordlist.insert/3, T = var(_)).
-
 :- pragma type_spec(set_ordlist.insert_list/3, T = var(_)).
-
+:- pragma type_spec(set_ordlist.delete/3, T = var(_)).
+:- pragma type_spec(set_ordlist.delete_list/3, T = var(_)).
+:- pragma type_spec(set_ordlist.remove/3, T = var(_)).
+:- pragma type_spec(set_ordlist.remove_list/3, T = var(_)).
 :- pragma type_spec(set_ordlist.union/3, T = var(_)).
-
+:- pragma type_spec(set_ordlist.union_list/2, T = var(_)).
 :- pragma type_spec(set_ordlist.intersect/3, T = var(_)).
-
+:- pragma type_spec(set_ordlist.intersect_list/2, T = var(_)).
 :- pragma type_spec(set_ordlist.difference/3, T = var(_)).
 
 %-----------------------------------------------------------------------------%
@@ -419,13 +420,15 @@
 
 set_ordlist.singleton_set(sol([X]), X).
 
+set_ordlist.is_singleton(sol([X]), X).
+
 set_ordlist.equal(Set, Set).
 
 set_ordlist.empty(sol([])).
+set_ordlist.is_empty(sol([])).
 
 set_ordlist.non_empty(sol([_ | _])).
-
-set_ordlist.is_empty(sol([])).
+set_ordlist.is_non_empty(sol([_ | _])).
 
 set_ordlist.list_to_set(Xs) = S :-
     set_ordlist.list_to_set(Xs, S).
@@ -584,6 +587,9 @@
     set_ordlist.init(Set0),
     set_ordlist.power_union_2(ListofSets, Set0, Set).
 
+set_ordlist.union_list(ListofSets, Set) :-
+    Set = set_ordlist.union_list(ListofSets).
+
 set_ordlist.power_union(SS) = S :-
     set_ordlist.power_union(SS, S).
 
@@ -643,6 +649,9 @@
         set_ordlist.intersect(S1, S0, S)
     ).
 
+set_ordlist.intersect_list(ListofSets, Set) :-
+    Set = set_ordlist.intersect_list(ListofSets).
+
 %--------------------------------------------------------------------------%
 
 set_ordlist.difference(S1, S2) = S3 :-
Index: library/tree_bitset.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/tree_bitset.m,v
retrieving revision 1.9
diff -u -b -r1.9 tree_bitset.m
--- library/tree_bitset.m	26 May 2011 06:20:09 -0000	1.9
+++ library/tree_bitset.m	19 Jul 2011 01:34:23 -0000
@@ -56,6 +56,8 @@
 
 :- pred is_empty(tree_bitset(T)::in) is semidet.
 
+:- pred is_non_empty(tree_bitset(T)::in) is semidet.
+
     % `equal(SetA, SetB)' is true iff `SetA' and `SetB' contain the same
     % elements. Takes O(min(card(SetA), card(SetB))) time.
     %
@@ -91,6 +93,10 @@
     %
 :- func make_singleton_set(T) = tree_bitset(T) <= enum(T).
 
+    % Is the given set a singleton, and if yes, what is the element?
+    %
+:- pred is_singleton(tree_bitset(T)::in, T::out) is semidet <= enum(T).
+
     % `subset(Subset, Set)' is true iff `Subset' is a subset of `Set'.
     % Same as `intersect(Set, Subset, Subset)', but may be more efficient.
     %
@@ -188,6 +194,11 @@
 :- pred union(tree_bitset(T)::in, tree_bitset(T)::in, tree_bitset(T)::out)
     is det.
 
+    % `union_list(Sets, Set)' returns the union of all the sets in Sets.
+    %
+:- func union_list(list(tree_bitset(T))) = tree_bitset(T).
+:- pred union_list(list(tree_bitset(T))::in, tree_bitset(T)::out) is det.
+
     % `intersect(SetA, SetB)' returns the intersection of `SetA' and `SetB'.
     % The efficiency of the intersection operation is not sensitive to the
     % argument ordering. Takes somewhere between
@@ -198,6 +209,12 @@
 :- pred intersect(tree_bitset(T)::in, tree_bitset(T)::in, tree_bitset(T)::out)
     is det.
 
+    % `intersect_list(Sets, Set)' returns the intersection of all the sets
+    % in Sets.
+    %
+:- func intersect_list(list(tree_bitset(T))) = tree_bitset(T).
+:- pred intersect_list(list(tree_bitset(T))::in, tree_bitset(T)::out) is det.
+
     % `difference(SetA, SetB)' returns the set containing all the elements
     % of `SetA' except those that occur in `SetB'. Takes somewhere between
     % O(log(card(SetA)) + log(card(SetB))) and O(card(SetA) + card(SetB)) time,
@@ -463,33 +480,34 @@
                 leaf_nodes      :: list(leaf_node)
             )
     ;       interior_list(
+                % Convenient but redundant; could be computed from the
+                % init_offset and limit_offset fields of the nodes.
                 level           :: int,
-                                % Convenient but redundant; could be computed
-                                % from the init_offset and limit_offset fields
-                                % of the nodes.
+
                 interior_nodes  :: list(interior_node)
             ).
 
 :- type leaf_node
     --->    leaf_node(
+                % Must be a multiple of bits_per_int.
                 leaf_offset     :: int,
-                                % multiple of bits_per_int
 
-                leaf_bits       :: int
                                 % bits offset .. offset + bits_per_int - 1
-                                % The tree_bitset operations all remove
-                                % elements of the list with a `bits'
-                                % field of zero.
+                % The tree_bitset operations all remove elements of the list
+                % with a `bits' field of zero.
+                leaf_bits       :: int
             ).
 
 :- type interior_node
     --->    interior_node(
+                % Must be a multiple of
+                % bits_per_int * 2 ^ (level * bits_per_level).
                 init_offset     :: int,
-                                % multiple of
-                                % bits_per_int * 2 ^ (level * bits_per_level)
-                limit_offset    :: int,
+
                                 % limit_offset = init_offset +
                                 %   bits_per_int * 2 ^ (level * bits_per_level)
+                limit_offset    :: int,
+
                 components      :: node_list
             ).
 
@@ -865,6 +883,9 @@
 
 is_empty(init).
 
+is_non_empty(Set) :-
+    not is_empty(Set).
+
 equal(SetA, SetB) :-
     trace [compile_time(flag("tree-bitset-integrity"))] (
         (
@@ -916,6 +937,15 @@
 
 make_singleton_set(A) = insert(init, A).
 
+is_singleton(Set, Elem) :-
+    Set = tree_bitset(List0),
+    List0 = leaf_list([Leaf]),
+    fold_bits(high_to_low, cons, Leaf ^ leaf_offset, Leaf ^ leaf_bits,
+        bits_per_int, [], List),
+    List = [Elem].
+
+%-----------------------------------------------------------------------------%
+
 insert(Set0, Elem) = Set :-
     Set0 = tree_bitset(List0),
     Index = enum_to_index(Elem),
@@ -2062,7 +2092,7 @@
         ListB = interior_list(LevelB, InteriorNodesB),
         (
             LeafNodesA = [],
-            List = ListB
+            List = ListA
         ;
             LeafNodesA = [FirstNodeA | LaterNodesA],
             raise_leaves_to_interior(FirstNodeA, LaterNodesA, InteriorNodeA),
@@ -2255,6 +2285,80 @@
 
 %-----------------------------------------------------------------------------%
 
+union_list(Sets) = Set :-
+    union_list(Sets, Set).
+
+union_list([], tree_bitset.init).
+union_list([Set], Set).
+union_list(Sets @ [_, _ | _], Set) :-
+    union_list_pass(Sets, [], MergedSets),
+    union_list(MergedSets, Set).
+
+    % Union adjacent pairs of sets, so that the resulting list has N sets
+    % if the input list has 2N or 2N-1 sets.
+    %
+    % We keep invoking union_list_pass until it yields a list of only one set.
+    %
+    % The point of this approach is that unioning a large set with a small set
+    % is often only slightly faster than unioning that large set with another
+    % large set, yet it gets significantly less work done. This is because
+    % the bitsets in a small set can be expected to be considerably sparser
+    % that bitsets in large sets.
+    %
+    % We expect that this approach should yield performance closer to NlogN
+    % than to N^2 when unioning a list of N sets.
+    %
+:- pred union_list_pass(list(tree_bitset(T))::in,
+    list(tree_bitset(T))::in, list(tree_bitset(T))::out)
+    is det.
+
+union_list_pass([], !MergedSets).
+union_list_pass([Set], !MergedSets) :-
+    !:MergedSets = [Set | !.MergedSets].
+union_list_pass([SetA, SetB | Sets0], !MergedSets) :-
+    union(SetA, SetB, SetAB),
+    !:MergedSets = [SetAB | !.MergedSets],
+    union_list_pass(Sets0, !MergedSets).
+
+%-----------------------------------------------------------------------------%
+
+intersect_list(Sets) = Set :-
+    intersect_list(Sets, Set).
+
+intersect_list([], tree_bitset.init).
+intersect_list([Set], Set).
+intersect_list(Sets @ [_, _ | _], Set) :-
+    intersect_list_pass(Sets, [], MergedSets),
+    intersect_list(MergedSets, Set).
+
+    % Intersect adjacent pairs of sets, so that the resulting list has N sets
+    % if the input list has 2N or 2N-1 sets.
+    %
+    % We keep invoking intersect_list_pass until it yields a list
+    % of only one set.
+    %
+    % The point of this approach is that intersecting a large set with a small
+    % set is often only slightly faster than intersecting that large set
+    % with another large set, yet it gets significantly less work done.
+    % This is because the bitsets in a small set can be expected to be
+    % considerably sparser that bitsets in large sets.
+    %
+    % We expect that this approach should yield performance closer to NlogN
+    % than to N^2 when intersecting a list of N sets.
+    %
+:- pred intersect_list_pass(list(tree_bitset(T))::in,
+    list(tree_bitset(T))::in, list(tree_bitset(T))::out) is det.
+
+intersect_list_pass([], !MergedSets).
+intersect_list_pass([Set], !MergedSets) :-
+    !:MergedSets = [Set | !.MergedSets].
+intersect_list_pass([SetA, SetB | Sets0], !MergedSets) :-
+    intersect(SetA, SetB, SetAB),
+    !:MergedSets = [SetAB | !.MergedSets],
+    intersect_list_pass(Sets0, !MergedSets).
+
+%-----------------------------------------------------------------------------%
+
 divide(Pred, Set, InSet, OutSet) :-
     Set = tree_bitset(List),
     (
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/appengine
cvs diff: Diffing samples/appengine/war
cvs diff: Diffing samples/appengine/war/WEB-INF
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/concurrency
cvs diff: Diffing samples/concurrency/dining_philosophers
cvs diff: Diffing samples/concurrency/midimon
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/java_interface
cvs diff: Diffing samples/java_interface/java_calls_mercury
cvs diff: Diffing samples/java_interface/mercury_calls_java
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
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/stm
cvs diff: Diffing tests/stm/orig
cvs diff: Diffing tests/stm/orig/stm-compiler
cvs diff: Diffing tests/stm/orig/stm-compiler/test1
cvs diff: Diffing tests/stm/orig/stm-compiler/test10
cvs diff: Diffing tests/stm/orig/stm-compiler/test2
cvs diff: Diffing tests/stm/orig/stm-compiler/test3
cvs diff: Diffing tests/stm/orig/stm-compiler/test4
cvs diff: Diffing tests/stm/orig/stm-compiler/test5
cvs diff: Diffing tests/stm/orig/stm-compiler/test6
cvs diff: Diffing tests/stm/orig/stm-compiler/test7
cvs diff: Diffing tests/stm/orig/stm-compiler/test8
cvs diff: Diffing tests/stm/orig/stm-compiler/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/stmqueue
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test10
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test11
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test9
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list