[m-rev.] for post-commit review: eliminate some parallelism dependencies

Zoltan Somogyi zs at csse.unimelb.edu.au
Mon Aug 23 14:15:26 AEST 2010


Make it possible to perform switch detection and common subexpression
elimination on more than one procedure in parallel by removing the requirement
for synchronization on the module_info.

compiler/cse_detection.m:
compiler/switch_detection.m:
	Make the change described above.

compiler/modes.m:
	Conform to the changes in the above files.

Zoltan.

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/cse_detection.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/cse_detection.m,v
retrieving revision 1.126
diff -u -b -r1.126 cse_detection.m
--- compiler/cse_detection.m	30 Jul 2010 05:16:09 -0000	1.126
+++ compiler/cse_detection.m	20 Aug 2010 04:17:13 -0000
@@ -26,7 +26,7 @@
 
 :- pred detect_cse_in_module(module_info::in, module_info::out) is det.
 
-:- pred detect_cse_in_proc(proc_id::in, pred_id::in,
+:- pred detect_cse_in_proc(pred_id::in, proc_id::in,
     module_info::in, module_info::out) is det.
 
 %-----------------------------------------------------------------------------%
@@ -93,17 +93,17 @@
 
 detect_cse_in_pred(PredId, PredInfo, !ModuleInfo) :-
     ProcIds = pred_info_non_imported_procids(PredInfo),
-    detect_cse_in_procs(ProcIds, PredId, !ModuleInfo).
+    detect_cse_in_procs(PredId, ProcIds, !ModuleInfo).
 
-:- pred detect_cse_in_procs(list(proc_id)::in, pred_id::in,
+:- pred detect_cse_in_procs(pred_id::in, list(proc_id)::in,
     module_info::in, module_info::out) is det.
 
-detect_cse_in_procs([], _PredId, !ModuleInfo).
-detect_cse_in_procs([ProcId | ProcIds], PredId, !ModuleInfo) :-
-    detect_cse_in_proc(ProcId, PredId, !ModuleInfo),
-    detect_cse_in_procs(ProcIds, PredId, !ModuleInfo).
+detect_cse_in_procs(_PredId, [], !ModuleInfo).
+detect_cse_in_procs(PredId, [ProcId | ProcIds], !ModuleInfo) :-
+    detect_cse_in_proc(PredId, ProcId, !ModuleInfo),
+    detect_cse_in_procs(PredId, ProcIds, !ModuleInfo).
 
-detect_cse_in_proc(ProcId, PredId, !ModuleInfo) :-
+detect_cse_in_proc(PredId, ProcId, !ModuleInfo) :-
     module_info_get_globals(!.ModuleInfo, Globals),
     globals.lookup_bool_option(Globals, very_verbose, VeryVerbose),
     (
@@ -116,7 +116,21 @@
     ;
         VeryVerbose = no
     ),
-    detect_cse_in_proc_pass(ProcId, PredId, Redo, !ModuleInfo),
+
+    % XXX We wouldn't have to keep getting the proc_info out of and back into
+    % the module_info if modecheck didn't take a whole module_info.
+    module_info_get_preds(!.ModuleInfo, PredTable0),
+    map.lookup(PredTable0, PredId, PredInfo0),
+    pred_info_get_procedures(PredInfo0, ProcTable0),
+    map.lookup(ProcTable0, ProcId, ProcInfo0),
+
+    detect_cse_in_proc_pass(!.ModuleInfo, Redo, ProcInfo0, ProcInfo1),
+
+    svmap.det_update(ProcId, ProcInfo1, ProcTable0, ProcTable1),
+    pred_info_set_procedures(ProcTable1, PredInfo0, PredInfo1),
+    svmap.det_update(PredId, PredInfo1, PredTable0, PredTable1),
+    module_info_set_preds(PredTable1, !ModuleInfo),
+
     globals.lookup_bool_option(Globals, detailed_statistics, Statistics),
     trace [io(!IO)] (
         maybe_report_stats(Statistics, !IO)
@@ -159,7 +173,20 @@
         ;
             VeryVerbose = no
         ),
-        detect_switches_in_proc(ProcId, PredId, !ModuleInfo),
+
+        module_info_get_preds(!.ModuleInfo, PredTable2),
+        map.lookup(PredTable2, PredId, PredInfo2),
+        pred_info_get_procedures(PredInfo2, ProcTable2),
+        map.lookup(ProcTable2, ProcId, ProcInfo2),
+
+        SwitchDetectInfo = init_switch_detect_info(!.ModuleInfo),
+        detect_switches_in_proc(SwitchDetectInfo, ProcInfo2, ProcInfo),
+
+        svmap.det_update(ProcId, ProcInfo, ProcTable2, ProcTable3),
+        pred_info_set_procedures(ProcTable3, PredInfo2, PredInfo3),
+        svmap.det_update(PredId, PredInfo3, PredTable2, PredTable3),
+        module_info_set_preds(PredTable3, !ModuleInfo),
+
         trace [io(!IO)] (
             maybe_report_stats(Statistics, !IO)
         ),
@@ -174,7 +201,7 @@
         ;
             VeryVerbose = no
         ),
-        detect_cse_in_proc(ProcId, PredId, !ModuleInfo)
+        detect_cse_in_proc(PredId, ProcId, !ModuleInfo)
     ).
 
 :- type cse_info
@@ -185,36 +212,30 @@
                 csei_module_info    :: module_info
             ).
 
-:- pred detect_cse_in_proc_pass(proc_id::in, pred_id::in, bool::out,
-    module_info::in, module_info::out) is det.
-
-detect_cse_in_proc_pass(ProcId, PredId, Redo, ModuleInfo0, ModuleInfo) :-
-    module_info_get_preds(ModuleInfo0, PredTable0),
-    map.lookup(PredTable0, PredId, PredInfo0),
-    pred_info_get_procedures(PredInfo0, ProcTable0),
-    map.lookup(ProcTable0, ProcId, ProcInfo0),
+:- pred detect_cse_in_proc_pass(module_info::in, bool::out,
+    proc_info::in, proc_info::out) is det.
 
+detect_cse_in_proc_pass(ModuleInfo, Redo, !ProcInfo) :-
     % To process each ProcInfo, we get the goal, initialize the instmap
     % based on the modes of the head vars, and pass these to
     % `detect_cse_in_goal'.
 
-    proc_info_get_goal(ProcInfo0, Goal0),
-    proc_info_get_initial_instmap(ProcInfo0, ModuleInfo0, InstMap0),
-    proc_info_get_varset(ProcInfo0, Varset0),
-    proc_info_get_vartypes(ProcInfo0, VarTypes0),
-    proc_info_get_rtti_varmaps(ProcInfo0, RttiVarMaps0),
-    CseInfo0 = cse_info(Varset0, VarTypes0, RttiVarMaps0, ModuleInfo0),
+    proc_info_get_goal(!.ProcInfo, Goal0),
+    proc_info_get_initial_instmap(!.ProcInfo, ModuleInfo, InstMap0),
+    proc_info_get_varset(!.ProcInfo, Varset0),
+    proc_info_get_vartypes(!.ProcInfo, VarTypes0),
+    proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
+    CseInfo0 = cse_info(Varset0, VarTypes0, RttiVarMaps0, ModuleInfo),
     detect_cse_in_goal(Goal0, Goal1, CseInfo0, CseInfo, InstMap0, Redo),
 
     (
-        Redo = no,
-        ModuleInfo = ModuleInfo0
+        Redo = no
     ;
         Redo = yes,
 
         % ModuleInfo should not be changed by detect_cse_in_goal.
         CseInfo = cse_info(VarSet1, VarTypes1, RttiVarMaps1, _),
-        proc_info_get_headvars(ProcInfo0, HeadVars),
+        proc_info_get_headvars(!.ProcInfo, HeadVars),
 
         implicitly_quantify_clause_body_general(
             ordinary_nonlocals_maybe_lambda,
@@ -222,15 +243,10 @@
             Goal1, Goal, VarSet1, VarSet, VarTypes1, VarTypes,
             RttiVarMaps1, RttiVarMaps),
 
-        proc_info_set_goal(Goal, ProcInfo0, ProcInfo1),
-        proc_info_set_varset(VarSet, ProcInfo1, ProcInfo2),
-        proc_info_set_vartypes(VarTypes, ProcInfo2, ProcInfo3),
-        proc_info_set_rtti_varmaps(RttiVarMaps, ProcInfo3, ProcInfo),
-
-        map.det_update(ProcTable0, ProcId, ProcInfo, ProcTable),
-        pred_info_set_procedures(ProcTable, PredInfo0, PredInfo),
-        map.det_update(PredTable0, PredId, PredInfo, PredTable),
-        module_info_set_preds(PredTable, ModuleInfo0, ModuleInfo)
+        proc_info_set_goal(Goal, !ProcInfo),
+        proc_info_set_varset(VarSet, !ProcInfo),
+        proc_info_set_vartypes(VarTypes, !ProcInfo),
+        proc_info_set_rtti_varmaps(RttiVarMaps, !ProcInfo)
     ).
 
 %-----------------------------------------------------------------------------%
Index: compiler/modes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modes.m,v
retrieving revision 1.390
diff -u -b -r1.390 modes.m
--- compiler/modes.m	30 Jul 2010 05:16:13 -0000	1.390
+++ compiler/modes.m	20 Aug 2010 04:17:13 -0000
@@ -936,14 +936,17 @@
         !:Changed, Specs) :-
     % Mark the procedure as ready to be processed.
     PredProcId = proc(PredId, ProcId),
+
     module_info_get_preds(!.ModuleInfo, Preds0),
     map.lookup(Preds0, PredId, PredInfo0),
     pred_info_get_procedures(PredInfo0, Procs0),
     map.lookup(Procs0, ProcId, ProcInfo0),
+
     proc_info_set_can_process(yes, ProcInfo0, ProcInfo1),
-    map.det_update(Procs0, ProcId, ProcInfo1, Procs1),
+
+    svmap.det_update(ProcId, ProcInfo1, Procs0, Procs1),
     pred_info_set_procedures(Procs1, PredInfo0, PredInfo1),
-    map.det_update(Preds0, PredId, PredInfo1, Preds1),
+    svmap.det_update(PredId, PredInfo1, Preds0, Preds1),
     module_info_set_preds(Preds1, !ModuleInfo),
 
     % Modecheck the procedure.
@@ -959,8 +962,21 @@
         ModeErrors = no,
         (
             HowToCheckGoal = check_unique_modes,
-            detect_switches_in_proc(ProcId, PredId, !ModuleInfo),
-            detect_cse_in_proc(ProcId, PredId, !ModuleInfo),
+
+            module_info_get_preds(!.ModuleInfo, Preds2),
+            map.lookup(Preds2, PredId, PredInfo2),
+            pred_info_get_procedures(PredInfo2, Procs2),
+            map.lookup(Procs2, ProcId, ProcInfo2),
+
+            SwitchDetectInfo = init_switch_detect_info(!.ModuleInfo),
+            detect_switches_in_proc(SwitchDetectInfo, ProcInfo2, ProcInfo3),
+
+            svmap.det_update(ProcId, ProcInfo3, Procs2, Procs3),
+            pred_info_set_procedures(Procs3, PredInfo2, PredInfo3),
+            svmap.det_update(PredId, PredInfo3, Preds2, Preds3),
+            module_info_set_preds(Preds3, !ModuleInfo),
+
+            detect_cse_in_proc(PredId, ProcId, !ModuleInfo),
             determinism_check_proc(ProcId, PredId, !ModuleInfo, DetismSpecs),
             expect(unify(DetismSpecs, []), this_file,
                 "modecheck_queued_proc: found detism error"),
Index: compiler/switch_detection.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/switch_detection.m,v
retrieving revision 1.149
diff -u -b -r1.149 switch_detection.m
--- compiler/switch_detection.m	30 Jul 2010 05:16:17 -0000	1.149
+++ compiler/switch_detection.m	20 Aug 2010 04:17:13 -0000
@@ -31,8 +31,12 @@
 
 :- pred detect_switches_in_module(module_info::in, module_info::out) is det.
 
-:- pred detect_switches_in_proc(proc_id::in, pred_id::in,
-    module_info::in, module_info::out) is det.
+:- type switch_detect_info.
+
+:- func init_switch_detect_info(module_info) = switch_detect_info.
+
+:- pred detect_switches_in_proc(switch_detect_info::in,
+    proc_info::in, proc_info::out) is det.
 
 :- type found_deconstruct
     --->    did_find_deconstruct
@@ -99,6 +103,12 @@
     --->    allow_multi_arm
     ;       dont_allow_multi_arm.
 
+:- type switch_detect_info
+    --->    switch_detect_info(
+                sdi_module_info     :: module_info,
+                sdi_allow_multi_arm :: allow_multi_arm
+            ).
+
 :- pred lookup_allow_multi_arm(module_info::in, allow_multi_arm::out) is det.
 
 lookup_allow_multi_arm(ModuleInfo, AllowMulti) :-
@@ -112,127 +122,152 @@
         AllowMulti = dont_allow_multi_arm
     ).
 
+init_switch_detect_info(ModuleInfo) = Info :-
+    lookup_allow_multi_arm(ModuleInfo, AllowMulti),
+    Info = switch_detect_info(ModuleInfo, AllowMulti).
+
+%-----------------------------------------------------------------------------%
+
 detect_switches_in_module(!ModuleInfo) :-
     % Traverse the module structure, calling `detect_switches_in_goal'
     % for each procedure body.
-    lookup_allow_multi_arm(!.ModuleInfo, AllowMulti),
-    module_info_get_valid_predids(PredIds, !ModuleInfo),
-    detect_switches_in_preds_allow(PredIds, AllowMulti, !ModuleInfo).
-
-:- pred detect_switches_in_preds_allow(list(pred_id)::in, allow_multi_arm::in,
-    module_info::in, module_info::out) is det.
-
-detect_switches_in_preds_allow([], _, !ModuleInfo).
-detect_switches_in_preds_allow([PredId | PredIds], AllowMulti, !ModuleInfo) :-
-    module_info_get_preds(!.ModuleInfo, PredTable),
-    map.lookup(PredTable, PredId, PredInfo),
-    detect_switches_in_pred_allow(PredId, PredInfo, AllowMulti, !ModuleInfo),
-    detect_switches_in_preds_allow(PredIds, AllowMulti, !ModuleInfo).
+    Info = init_switch_detect_info(!.ModuleInfo),
+    module_info_get_valid_predids(ValidPredIds, !ModuleInfo),
+    ValidPredIdSet = set_tree234.list_to_set(ValidPredIds),
+
+    module_info_get_preds(!.ModuleInfo, PredMap0),
+    map.to_assoc_list(PredMap0, PredIdsInfos0),
+
+    detect_switches_in_preds(Info, ValidPredIdSet,
+        PredIdsInfos0, PredIdsInfos),
+    map.from_sorted_assoc_list(PredIdsInfos, PredMap),
+    module_info_set_preds(PredMap, !ModuleInfo).
+
+:- pred detect_switches_in_preds(switch_detect_info::in,
+    set_tree234(pred_id)::in,
+    assoc_list(pred_id, pred_info)::in, assoc_list(pred_id, pred_info)::out)
+    is det.
+
+detect_switches_in_preds(_, _, [], []).
+detect_switches_in_preds(Info, ValidPredIdSet,
+        [PredIdInfo0 | PredIdsInfos0], [PredIdInfo | PredIdsInfos]) :-
+    PredIdInfo0 = PredId - PredInfo0,
+    ( set_tree234.member(ValidPredIdSet, PredId) ->
+        detect_switches_in_pred(Info, PredId, PredInfo0, PredInfo),
+        PredIdInfo = PredId - PredInfo
+    ;
+        PredIdInfo = PredIdInfo0
+    ),
+    detect_switches_in_preds(Info, ValidPredIdSet,
+        PredIdsInfos0, PredIdsInfos).
 
-:- pred detect_switches_in_pred_allow(pred_id::in, pred_info::in,
-    allow_multi_arm::in, module_info::in, module_info::out) is det.
+:- pred detect_switches_in_pred(switch_detect_info::in, pred_id::in,
+    pred_info::in, pred_info::out) is det.
 
-detect_switches_in_pred_allow(PredId, PredInfo0, AllowMulti, !ModuleInfo) :-
-    ProcIds = pred_info_non_imported_procids(PredInfo0),
+detect_switches_in_pred(Info, PredId, !PredInfo) :-
+    NonImportedProcIds = pred_info_non_imported_procids(!.PredInfo),
     (
-        ProcIds = [_ | _],
+        NonImportedProcIds = [_ | _],
         trace [io(!IO)] (
+            ModuleInfo = Info ^ sdi_module_info,
             write_pred_progress_message("% Detecting switches in ", PredId,
-                !.ModuleInfo, !IO)
+                ModuleInfo, !IO)
         ),
-        detect_switches_in_procs_allow(ProcIds, PredId, AllowMulti,
-            !ModuleInfo)
+        pred_info_get_procedures(!.PredInfo, ProcTable0),
+        map.to_assoc_list(ProcTable0, ProcList0),
+        detect_switches_in_procs(Info, NonImportedProcIds,
+            ProcList0, ProcList),
+        map.from_sorted_assoc_list(ProcList, ProcTable),
+        pred_info_set_procedures(ProcTable, !PredInfo)
+
         % This is where we should print statistics, if we ever need
         % to debug the performance of switch detection.
     ;
-        ProcIds = []
+        NonImportedProcIds = []
     ).
 
-:- pred detect_switches_in_procs_allow(list(proc_id)::in, pred_id::in,
-    allow_multi_arm::in, module_info::in, module_info::out) is det.
-
-detect_switches_in_procs_allow([], _PredId, _AllowMulti, !ModuleInfo).
-detect_switches_in_procs_allow([ProcId | ProcIds], PredId, AllowMulti,
-        !ModuleInfo) :-
-    detect_switches_in_proc_allow(ProcId, PredId, AllowMulti, !ModuleInfo),
-    detect_switches_in_procs_allow(ProcIds, PredId, AllowMulti, !ModuleInfo).
-
-detect_switches_in_proc(ProcId, PredId, !ModuleInfo) :-
-    lookup_allow_multi_arm(!.ModuleInfo, AllowMulti),
-    detect_switches_in_proc_allow(ProcId, PredId, AllowMulti, !ModuleInfo).
-
-:- pred detect_switches_in_proc_allow(proc_id::in, pred_id::in,
-    allow_multi_arm::in, module_info::in, module_info::out) is det.
-
-detect_switches_in_proc_allow(ProcId, PredId, AllowMulti, !ModuleInfo) :-
-    module_info_get_preds(!.ModuleInfo, PredTable0),
-    map.lookup(PredTable0, PredId, PredInfo0),
-    pred_info_get_procedures(PredInfo0, ProcTable0),
-    map.lookup(ProcTable0, ProcId, ProcInfo0),
+:- pred detect_switches_in_procs(switch_detect_info::in, list(proc_id)::in,
+    assoc_list(proc_id, proc_info)::in, assoc_list(proc_id, proc_info)::out)
+    is det.
+
+detect_switches_in_procs(_Info, _NonImportedProcIds, [], []).
+detect_switches_in_procs(Info, NonImportedProcIds,
+        [ProcIdInfo0 | ProcIdsInfos0], [ProcIdInfo | ProcIdsInfos]) :-
+    ProcIdInfo0 = ProcId - ProcInfo0,
+    ( list.member(ProcId, NonImportedProcIds) ->
+        detect_switches_in_proc(Info, ProcInfo0, ProcInfo),
+        ProcIdInfo = ProcId - ProcInfo
+    ;
+        ProcIdInfo = ProcIdInfo0
+    ),
+    detect_switches_in_procs(Info, NonImportedProcIds,
+        ProcIdsInfos0, ProcIdsInfos).
 
+detect_switches_in_proc(Info, !ProcInfo) :-
     % To process each ProcInfo, we get the goal, initialize the instmap
     % based on the modes of the head vars, and pass these to
     % `detect_switches_in_goal'.
-    proc_info_get_goal(ProcInfo0, Goal0),
-    proc_info_get_vartypes(ProcInfo0, VarTypes),
-    proc_info_get_initial_instmap(ProcInfo0, !.ModuleInfo, InstMap0),
-    detect_switches_in_goal(VarTypes, AllowMulti, InstMap0,
-        Goal0, Goal, !ModuleInfo, do_not_need_to_requantify, Requant),
-
-    proc_info_set_goal(Goal, ProcInfo0, ProcInfo1),
+    Info = switch_detect_info(ModuleInfo, AllowMulti),
+    proc_info_get_vartypes(!.ProcInfo, VarTypes),
+    LocalInfo0 =  local_switch_detect_info(ModuleInfo, AllowMulti, VarTypes,
+        do_not_need_to_requantify),
+
+    proc_info_get_goal(!.ProcInfo, Goal0),
+    proc_info_get_initial_instmap(!.ProcInfo, ModuleInfo, InstMap0),
+    detect_switches_in_goal(InstMap0, Goal0, Goal,
+        LocalInfo0, LocalInfo),
+    proc_info_set_goal(Goal, !ProcInfo),
+    Requant = LocalInfo ^ lsdi_requant,
     (
         Requant = need_to_requantify,
-        requantify_proc_general(ordinary_nonlocals_maybe_lambda,
-            ProcInfo1, ProcInfo)
+        requantify_proc_general(ordinary_nonlocals_maybe_lambda, !ProcInfo)
     ;
-        Requant = do_not_need_to_requantify,
-        ProcInfo = ProcInfo1
-    ),
-    map.det_update(ProcTable0, ProcId, ProcInfo, ProcTable),
-    pred_info_set_procedures(ProcTable, PredInfo0, PredInfo),
-    map.det_update(PredTable0, PredId, PredInfo, PredTable),
-    module_info_set_preds(PredTable, !ModuleInfo).
+        Requant = do_not_need_to_requantify
+    ).
 
 %-----------------------------------------------------------------------------%
 
+:- type local_switch_detect_info
+    --->    local_switch_detect_info(
+                lsdi_module_info        :: module_info,
+                lsdi_allow_multi_arm    :: allow_multi_arm,
+                lsdi_vartypes           :: vartypes,
+                lsdi_requant            :: need_to_requantify
+            ).
+
     % Given a goal, and the instmap on entry to that goal,
     % replace disjunctions with switches whereever possible.
     %
-:- pred detect_switches_in_goal(vartypes::in, allow_multi_arm::in, instmap::in,
-    hlds_goal::in, hlds_goal::out, module_info::in, module_info::out, 
-    need_to_requantify::in, need_to_requantify::out) is det.
-
-detect_switches_in_goal(VarTypes, AllowMulti, InstMap0,
-        !Goal, !ModuleInfo, !Requant) :-
-    detect_switches_in_goal_update_instmap(VarTypes, AllowMulti,
-        InstMap0, _InstMap, !Goal, !ModuleInfo, !Requant).
+:- pred detect_switches_in_goal(instmap::in, hlds_goal::in, hlds_goal::out,
+    local_switch_detect_info::in, local_switch_detect_info::out) is det.
+
+detect_switches_in_goal(InstMap0, !Goal, !LocalInfo) :-
+    detect_switches_in_goal_update_instmap(InstMap0, _InstMap, !Goal,
+        !LocalInfo).
 
     % This version is the same as the above except that it returns the
     % resulting instmap on exit from the goal, which is computed by applying
     % the instmap delta specified in the goal's goalinfo.
     %
-:- pred detect_switches_in_goal_update_instmap(vartypes::in,
-    allow_multi_arm::in, instmap::in, instmap::out,
-    hlds_goal::in, hlds_goal::out, module_info::in, module_info::out, 
-    need_to_requantify::in, need_to_requantify::out) is det.
+:- pred detect_switches_in_goal_update_instmap(instmap::in, instmap::out,
+    hlds_goal::in, hlds_goal::out,
+    local_switch_detect_info::in, local_switch_detect_info::out) is det.
 
-detect_switches_in_goal_update_instmap(VarTypes, AllowMulti,
-        !InstMap, Goal0, Goal, !ModuleInfo, !Requant) :-
+detect_switches_in_goal_update_instmap(!InstMap, Goal0, Goal, !LocalInfo) :-
     Goal0 = hlds_goal(GoalExpr0, GoalInfo),
-    detect_switches_in_goal_expr(VarTypes, AllowMulti, !.InstMap,
-        GoalInfo, GoalExpr0, GoalExpr, !ModuleInfo, !Requant),
+    detect_switches_in_goal_expr(!.InstMap, GoalInfo, GoalExpr0, GoalExpr,
+        !LocalInfo),
     Goal = hlds_goal(GoalExpr, GoalInfo),
     update_instmap(Goal0, !InstMap).
 
     % Here we process each of the different sorts of goals.
     %
-:- pred detect_switches_in_goal_expr(vartypes::in, allow_multi_arm::in,
-    instmap::in, hlds_goal_info::in, hlds_goal_expr::in, hlds_goal_expr::out,
-    module_info::in, module_info::out, 
-    need_to_requantify::in, need_to_requantify::out) is det.
+:- pred detect_switches_in_goal_expr(instmap::in, hlds_goal_info::in,
+    hlds_goal_expr::in, hlds_goal_expr::out,
+    local_switch_detect_info::in, local_switch_detect_info::out) is det.
 
-detect_switches_in_goal_expr(VarTypes, AllowMulti, InstMap0,
-        GoalInfo, GoalExpr0, GoalExpr, !ModuleInfo, !Requant) :-
+detect_switches_in_goal_expr(InstMap0, GoalInfo, GoalExpr0, GoalExpr,
+        !LocalInfo) :-
     (
         GoalExpr0 = disj(Disjuncts0),
         (
@@ -243,32 +278,26 @@
             NonLocals = goal_info_get_nonlocals(GoalInfo),
             set.to_sorted_list(NonLocals, NonLocalsList),
             detect_switches_in_disj(GoalInfo, NonLocalsList,
-                VarTypes, AllowMulti, Disjuncts0, NonLocalsList, InstMap0,
-                [], GoalExpr, !ModuleInfo, !Requant)
+                Disjuncts0, NonLocalsList, InstMap0, [], GoalExpr, !LocalInfo)
         )
     ;
         GoalExpr0 = conj(ConjType, Goals0),
-        detect_switches_in_conj(VarTypes, AllowMulti, InstMap0,
-            Goals0, Goals, !ModuleInfo, !Requant),
+        detect_switches_in_conj(InstMap0, Goals0, Goals, !LocalInfo),
         GoalExpr = conj(ConjType, Goals)
     ;
         GoalExpr0 = negation(SubGoal0),
-        detect_switches_in_goal(VarTypes, AllowMulti, InstMap0,
-            SubGoal0, SubGoal, !ModuleInfo, !Requant),
+        detect_switches_in_goal(InstMap0, SubGoal0, SubGoal, !LocalInfo),
         GoalExpr = negation(SubGoal)
     ;
         GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
-        detect_switches_in_goal_update_instmap(VarTypes, AllowMulti,
-            InstMap0, InstMap1, Cond0, Cond, !ModuleInfo, !Requant),
-        detect_switches_in_goal(VarTypes, AllowMulti,
-            InstMap1, Then0, Then, !ModuleInfo, !Requant),
-        detect_switches_in_goal(VarTypes, AllowMulti,
-            InstMap0, Else0, Else, !ModuleInfo, !Requant),
+        detect_switches_in_goal_update_instmap(InstMap0, InstMap1, Cond0, Cond,
+            !LocalInfo),
+        detect_switches_in_goal(InstMap1, Then0, Then, !LocalInfo),
+        detect_switches_in_goal(InstMap0, Else0, Else, !LocalInfo),
         GoalExpr = if_then_else(Vars, Cond, Then, Else)
     ;
         GoalExpr0 = switch(Var, CanFail, Cases0),
-        detect_switches_in_cases(Var, VarTypes, AllowMulti, InstMap0,
-            Cases0, Cases,  !ModuleInfo, !Requant),
+        detect_switches_in_cases(Var, InstMap0, Cases0, Cases, !LocalInfo),
         GoalExpr = switch(Var, CanFail, Cases)
     ;
         GoalExpr0 = scope(Reason, SubGoal0),
@@ -277,8 +306,7 @@
             % inside these scopes.
             SubGoal = SubGoal0
         ;
-            detect_switches_in_goal(VarTypes, AllowMulti, InstMap0,
-                SubGoal0, SubGoal, !ModuleInfo, !Requant)
+            detect_switches_in_goal(InstMap0, SubGoal0, SubGoal, !LocalInfo)
         ),
         GoalExpr = scope(Reason, SubGoal)
     ;
@@ -287,10 +315,11 @@
             RHS0 = rhs_lambda_goal(_, _, _, _, _, Vars, Modes, _, LambdaGoal0),
             % We need to insert the initial insts for the lambda variables
             % in the instmap before processing the lambda goal.
-            instmap.pre_lambda_update(!.ModuleInfo, Vars, Modes,
+            ModuleInfo = !.LocalInfo ^ lsdi_module_info,
+            instmap.pre_lambda_update(ModuleInfo, Vars, Modes,
                 InstMap0, InstMap1),
-            detect_switches_in_goal(VarTypes, AllowMulti, InstMap1,
-                LambdaGoal0, LambdaGoal, !ModuleInfo, !Requant),
+            detect_switches_in_goal(InstMap1, LambdaGoal0, LambdaGoal,
+                !LocalInfo),
             RHS = RHS0 ^ rhs_lambda_goal := LambdaGoal,
             GoalExpr = GoalExpr0 ^ unify_rhs := RHS
         ;
@@ -310,25 +339,73 @@
         (
             ShortHand0 = atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
                 MainGoal0, OrElseGoals0, OrElseInners),
-            detect_switches_in_goal(VarTypes, AllowMulti, InstMap0,
-                MainGoal0, MainGoal, !ModuleInfo, !Requant),
-            detect_switches_in_orelse(VarTypes, AllowMulti, InstMap0,
-                OrElseGoals0, OrElseGoals, !ModuleInfo, !Requant),
+            detect_switches_in_goal(InstMap0, MainGoal0, MainGoal, !LocalInfo),
+            detect_switches_in_orelse(InstMap0, OrElseGoals0, OrElseGoals,
+                !LocalInfo),
             ShortHand = atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
                 MainGoal, OrElseGoals, OrElseInners)
         ;
             ShortHand0 = try_goal(MaybeIO, ResultVar, SubGoal0),
-            detect_switches_in_goal(VarTypes, AllowMulti, InstMap0,
-                SubGoal0, SubGoal, !ModuleInfo, !Requant),
+            detect_switches_in_goal(InstMap0, SubGoal0, SubGoal, !LocalInfo),
             ShortHand = try_goal(MaybeIO, ResultVar, SubGoal)
         ;
             ShortHand0 = bi_implication(_, _),
             % These should have been expanded out by now.
-            unexpected(this_file, "detect_switches_in_goal_2: bi_implication")
+            unexpected(this_file,
+                "detect_switches_in_goal_expr: bi_implication")
         ),
         GoalExpr = shorthand(ShortHand)
     ).
 
+:- pred detect_sub_switches_in_disj(instmap::in,
+    list(hlds_goal)::in, list(hlds_goal)::out,
+    local_switch_detect_info::in, local_switch_detect_info::out) is det.
+
+detect_sub_switches_in_disj(_, [], [], !LocalInfo).
+detect_sub_switches_in_disj(InstMap, [Goal0 | Goals0], [Goal | Goals],
+        !LocalInfo) :-
+    detect_switches_in_goal(InstMap, Goal0, Goal, !LocalInfo),
+    detect_sub_switches_in_disj(InstMap, Goals0, Goals, !LocalInfo).
+
+:- pred detect_switches_in_cases(prog_var::in, instmap::in,
+    list(case)::in, list(case)::out,
+    local_switch_detect_info::in, local_switch_detect_info::out) is det.
+
+detect_switches_in_cases(_, _, [], [], !LocalInfo).
+detect_switches_in_cases(Var, InstMap0, [Case0 | Cases0], [Case | Cases],
+        !LocalInfo) :-
+    Case0 = case(MainConsId, OtherConsIds, Goal0),
+    VarTypes = !.LocalInfo ^ lsdi_vartypes,
+    ModuleInfo0 = !.LocalInfo ^ lsdi_module_info,
+    map.lookup(VarTypes, Var, VarType),
+    bind_var_to_functors(Var, VarType, MainConsId, OtherConsIds,
+        InstMap0, InstMap1, ModuleInfo0, ModuleInfo),
+    !LocalInfo ^ lsdi_module_info := ModuleInfo,
+    detect_switches_in_goal(InstMap1, Goal0, Goal, !LocalInfo),
+    Case = case(MainConsId, OtherConsIds, Goal),
+    detect_switches_in_cases(Var, InstMap0, Cases0, Cases, !LocalInfo).
+
+:- pred detect_switches_in_conj(instmap::in,
+    list(hlds_goal)::in, list(hlds_goal)::out,
+    local_switch_detect_info::in, local_switch_detect_info::out) is det.
+
+detect_switches_in_conj(_, [], [], !LocalInfo).
+detect_switches_in_conj(InstMap0,
+        [Goal0 | Goals0], [Goal | Goals], !LocalInfo) :-
+    detect_switches_in_goal_update_instmap(InstMap0, InstMap1, Goal0, Goal,
+        !LocalInfo),
+    detect_switches_in_conj(InstMap1, Goals0, Goals, !LocalInfo).
+
+:- pred detect_switches_in_orelse(instmap::in,
+    list(hlds_goal)::in, list(hlds_goal)::out,
+    local_switch_detect_info::in, local_switch_detect_info::out) is det.
+
+detect_switches_in_orelse(_, [], [], !LocalInfo).
+detect_switches_in_orelse(InstMap, [Goal0 | Goals0], [Goal | Goals],
+        !LocalInfo) :-
+    detect_switches_in_goal(InstMap, Goal0, Goal, !LocalInfo),
+    detect_switches_in_orelse(InstMap, Goals0, Goals, !LocalInfo).
+
 %-----------------------------------------------------------------------------%
 
 :- type case_arm
@@ -524,20 +601,19 @@
     % of the disjuncts such that each group of disjunctions can only succeed
     % if the variable is bound to a different functor.
     %
-:- pred detect_switches_in_disj(hlds_goal_info::in,
-    list(prog_var)::in, vartypes::in, allow_multi_arm::in,
+:- pred detect_switches_in_disj(hlds_goal_info::in, list(prog_var)::in,
     list(hlds_goal)::in, list(prog_var)::in, instmap::in, list(again)::in,
-    hlds_goal_expr::out, module_info::in, module_info::out,
-    need_to_requantify::in, need_to_requantify::out) is det.
+    hlds_goal_expr::out,
+    local_switch_detect_info::in, local_switch_detect_info::out) is det.
 
-detect_switches_in_disj(GoalInfo, AllVars, VarTypes, AllowMulti, Disjuncts0,
-        [Var | Vars], InstMap, AgainList0, GoalExpr, !ModuleInfo, !Requant) :-
+detect_switches_in_disj(GoalInfo, AllVars, Disjuncts0,
+        [Var | Vars], InstMap, AgainList0, GoalExpr, !LocalInfo) :-
     % Can we do at least a partial switch on this variable?
     (
         instmap_lookup_var(InstMap, Var, VarInst0),
-        inst_is_bound(!.ModuleInfo, VarInst0),
-        partition_disj(AllowMulti, Disjuncts0, Var, GoalInfo, Left, CasesList,
-            !Requant)
+        ModuleInfo = !.LocalInfo ^ lsdi_module_info,
+        inst_is_bound(ModuleInfo, VarInst0),
+        partition_disj(Disjuncts0, Var, GoalInfo, Left, CasesList, !LocalInfo)
     ->
         % A switch needs to have at least two cases.
         %
@@ -550,11 +626,10 @@
             % Are there any disjuncts that are not part of the switch? No.
             Left = [],
             ( CasesList = [_, _ | _] ->
-                cases_to_switch(Var, VarTypes, AllowMulti,
-                    CasesList, InstMap, GoalExpr, !ModuleInfo, !Requant)
+                cases_to_switch(Var, CasesList, InstMap, GoalExpr, !LocalInfo)
             ;
-                detect_sub_switches_in_disj(VarTypes, AllowMulti,
-                    InstMap, Disjuncts0, Disjuncts, !ModuleInfo, !Requant),
+                detect_sub_switches_in_disj(InstMap, Disjuncts0, Disjuncts,
+                    !LocalInfo),
                 GoalExpr = disj(Disjuncts)
             )
         ;
@@ -568,29 +643,25 @@
                 AgainList1 = AgainList0
             ),
             % Try to find a switch.
-            detect_switches_in_disj(GoalInfo, AllVars, VarTypes,
-                AllowMulti, Disjuncts0, Vars, InstMap, AgainList1, GoalExpr,
-                !ModuleInfo, !Requant)
+            detect_switches_in_disj(GoalInfo, AllVars, Disjuncts0,
+                Vars, InstMap, AgainList1, GoalExpr, !LocalInfo)
         )
     ;
-        detect_switches_in_disj(GoalInfo, AllVars, VarTypes,
-            AllowMulti, Disjuncts0, Vars, InstMap, AgainList0, GoalExpr,
-            !ModuleInfo, !Requant)
+        detect_switches_in_disj(GoalInfo, AllVars, Disjuncts0,
+            Vars, InstMap, AgainList0, GoalExpr, !LocalInfo)
     ).
-detect_switches_in_disj(GoalInfo, AllVars, VarTypes, AllowMulti, Disjuncts0,
-        [], InstMap, AgainList0, disj(Disjuncts), !ModuleInfo, !Requant) :-
+detect_switches_in_disj(GoalInfo, AllVars, Disjuncts0,
+        [], InstMap, AgainList0, disj(Disjuncts), !LocalInfo) :-
     (
         AgainList0 = [],
-        detect_sub_switches_in_disj(VarTypes, AllowMulti, InstMap,
-            Disjuncts0, Disjuncts, !ModuleInfo, !Requant)
+        detect_sub_switches_in_disj(InstMap, Disjuncts0, Disjuncts, !LocalInfo)
     ;
         AgainList0 = [Again | AgainList1],
         select_best_switch(AgainList1, Again, BestAgain),
         BestAgain = again(Var, Left0, CasesList),
-        cases_to_switch(Var, VarTypes, AllowMulti,
-            CasesList, InstMap, SwitchGoalExpr, !ModuleInfo, !Requant),
-        detect_switches_in_disj(GoalInfo, AllVars, VarTypes, AllowMulti,
-            Left0, AllVars, InstMap, [], Left, !ModuleInfo, !Requant),
+        cases_to_switch(Var, CasesList, InstMap, SwitchGoalExpr, !LocalInfo),
+        detect_switches_in_disj(GoalInfo, AllVars, Left0, AllVars, InstMap,
+            [], Left, !LocalInfo),
         goal_to_disj_list(hlds_goal(Left, GoalInfo), LeftList),
         Disjuncts = [hlds_goal(SwitchGoalExpr, GoalInfo) | LeftList]
     ).
@@ -612,69 +683,9 @@
     ),
     select_best_switch(AgainList, BestAgain1, BestAgain).
 
-:- pred detect_sub_switches_in_disj(vartypes::in,
-    allow_multi_arm::in, instmap::in,
-    list(hlds_goal)::in, list(hlds_goal)::out,
-    module_info::in, module_info::out,
-    need_to_requantify::in, need_to_requantify::out) is det.
-
-detect_sub_switches_in_disj(_, _, _, [], [], !ModuleInfo, !Requant).
-detect_sub_switches_in_disj(VarTypes, AllowMulti, InstMap,
-        [Goal0 | Goals0], [Goal | Goals], !ModuleInfo, !Requant) :-
-    detect_switches_in_goal(VarTypes, AllowMulti, InstMap,
-        Goal0, Goal, !ModuleInfo, !Requant),
-    detect_sub_switches_in_disj(VarTypes, AllowMulti, InstMap,
-        Goals0, Goals, !ModuleInfo, !Requant).
-
-:- pred detect_switches_in_cases(prog_var::in, vartypes::in,
-    allow_multi_arm::in, instmap::in, list(case)::in, list(case)::out,
-    module_info::in, module_info::out,
-    need_to_requantify::in, need_to_requantify::out) is det.
-
-detect_switches_in_cases(_, _, _, _, [], [], !ModuleInfo, !Requant).
-detect_switches_in_cases(Var, VarTypes, AllowMulti, InstMap0,
-        [Case0 | Cases0], [Case | Cases], !ModuleInfo, !Requant) :-
-    Case0 = case(MainConsId, OtherConsIds, Goal0),
-    map.lookup(VarTypes, Var, VarType),
-    bind_var_to_functors(Var, VarType, MainConsId, OtherConsIds,
-        InstMap0, InstMap1, !ModuleInfo),
-    detect_switches_in_goal(VarTypes, AllowMulti, InstMap1,
-        Goal0, Goal, !ModuleInfo, !Requant),
-    Case = case(MainConsId, OtherConsIds, Goal),
-    detect_switches_in_cases(Var, VarTypes, AllowMulti, InstMap0,
-        Cases0, Cases, !ModuleInfo, !Requant).
-
-:- pred detect_switches_in_conj(vartypes::in,
-    allow_multi_arm::in, instmap::in,
-    list(hlds_goal)::in, list(hlds_goal)::out,
-    module_info::in, module_info::out,
-    need_to_requantify::in, need_to_requantify::out) is det.
-
-detect_switches_in_conj(_, _, _, [], [], !ModuleInfo, !Requant).
-detect_switches_in_conj(VarTypes, AllowMulti, InstMap0,
-        [Goal0 | Goals0], [Goal | Goals], !ModuleInfo, !Requant) :-
-    detect_switches_in_goal_update_instmap(VarTypes, AllowMulti,
-        InstMap0, InstMap1, Goal0, Goal, !ModuleInfo, !Requant),
-    detect_switches_in_conj(VarTypes, AllowMulti,
-        InstMap1, Goals0, Goals, !ModuleInfo, !Requant).
-
-:- pred detect_switches_in_orelse(vartypes::in, allow_multi_arm::in,
-    instmap::in, list(hlds_goal)::in, list(hlds_goal)::out,
-    module_info::in, module_info::out,
-    need_to_requantify::in, need_to_requantify::out) is det.
-
-detect_switches_in_orelse(_, _, _, [], [], !ModuleInfo, !Requant).
-detect_switches_in_orelse(VarTypes, AllowMulti, InstMap,
-        [Goal0 | Goals0], [Goal | Goals], !ModuleInfo, !Requant) :-
-    detect_switches_in_goal(VarTypes, AllowMulti, InstMap, Goal0, Goal,
-        !ModuleInfo, !Requant),
-    detect_switches_in_orelse(VarTypes, AllowMulti, InstMap, Goals0, Goals,
-        !ModuleInfo, !Requant).
-
 %-----------------------------------------------------------------------------%
 
-    % partition_disj(AllowMulti, Disjuncts, Var, GoalInfo, VarTypes,
-    %   ModuleInfo, Left, Cases):
+    % partition_disj(Disjuncts, Var, GoalInfo, Left, Cases, !LocalInfo):
     %
     % Attempts to partition the disjunction `Disjuncts' into a switch on `Var'.
     % If at least partially successful, returns the resulting `Cases', with
@@ -687,11 +698,11 @@
     % unifications at the start of each disjunction, to build up a
     % substitution.
     %
-:- pred partition_disj(allow_multi_arm::in, list(hlds_goal)::in,
-    prog_var::in, hlds_goal_info::in, list(hlds_goal)::out, list(case)::out,
-    need_to_requantify::in, need_to_requantify::out) is semidet.
+:- pred partition_disj(list(hlds_goal)::in, prog_var::in, hlds_goal_info::in,
+    list(hlds_goal)::out, list(case)::out,
+    local_switch_detect_info::in, local_switch_detect_info::out) is semidet.
 
-partition_disj(AllowMulti, Disjuncts0, Var, GoalInfo, Left, Cases, !Requant) :-
+partition_disj(Disjuncts0, Var, GoalInfo, Left, Cases, !LocalInfo) :-
     CasesTable0 = cases_table(map.init, set_tree234.init),
     partition_disj_trial(Disjuncts0, Var, [], Left1, CasesTable0, CasesTable1),
     (
@@ -705,11 +716,12 @@
         % We don't insist on there being at least one case in CasesTable1,
         % to allow for switches in which *all* cases contain subsidiary
         % disjunctions.
+        AllowMulti = !.LocalInfo ^ lsdi_allow_multi_arm,
         ( expand_sub_disjs(AllowMulti, Var, Left1, CasesTable1, CasesTable) ->
             Left = [],
             num_cases_in_table(CasesTable) >= 1,
             Cases = convert_cases_table(GoalInfo, CasesTable),
-            !:Requant = need_to_requantify
+            !LocalInfo ^ lsdi_requant := need_to_requantify
         ;
             Left = Left1,
             Cases = convert_cases_table(GoalInfo, CasesTable1)
@@ -1019,23 +1031,23 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred cases_to_switch(prog_var::in, vartypes::in, allow_multi_arm::in,
-    list(case)::in, instmap::in, hlds_goal_expr::out,
-    module_info::in, module_info::out, 
-    need_to_requantify::in, need_to_requantify::out) is det.
-
-cases_to_switch(Var, VarTypes, AllowMulti, Cases0, InstMap, GoalExpr,
-        !ModuleInfo, !Requant) :-
+:- pred cases_to_switch(prog_var::in, list(case)::in, instmap::in,
+    hlds_goal_expr::out,
+    local_switch_detect_info::in, local_switch_detect_info::out) is det.
+
+cases_to_switch(Var, Cases0, InstMap, GoalExpr, !LocalInfo) :-
+    ModuleInfo = !.LocalInfo ^ lsdi_module_info,
+    VarTypes = !.LocalInfo ^ lsdi_vartypes,
     instmap_lookup_var(InstMap, Var, VarInst),
     map.lookup(VarTypes, Var, Type),
-    ( inst_is_bound_to_functors(!.ModuleInfo, VarInst, Functors) ->
+    ( inst_is_bound_to_functors(ModuleInfo, VarInst, Functors) ->
         type_to_ctor_det(Type, TypeCtor),
         bound_insts_to_cons_ids(TypeCtor, Functors, ConsIds),
         delete_unreachable_cases(Cases0, ConsIds, Cases1),
         CanFail = compute_can_fail(ConsIds, Cases1)
     ;
         Cases1 = Cases0,
-        ( switch_type_num_functors(!.ModuleInfo, Type, NumFunctors) ->
+        ( switch_type_num_functors(ModuleInfo, Type, NumFunctors) ->
             % We could check for each cons_id of the type whether a case covers
             % it, but given that type checking ensures that the set of covered
             % cons_ids is a subset of the set of cons_ids of the type, checking
@@ -1048,8 +1060,7 @@
             CanFail = can_fail
         )
     ),
-    detect_switches_in_cases(Var, VarTypes, AllowMulti, InstMap,
-        Cases1, Cases, !ModuleInfo, !Requant),
+    detect_switches_in_cases(Var, InstMap, Cases1, Cases, !LocalInfo),
 
     % We turn switches with no arms into fail, since this avoids having
     % the code generator flush the control variable of the switch.
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/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/monte
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing 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/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/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