[m-rev.] for review: make analysis framework not require I/O state

Peter Wang novalazy at gmail.com
Thu Feb 21 11:13:57 AEDT 2008


Estimated hours taken: 6
Branches: main

Make the intermodule analysis framework not require the I/O state for looking
up and recording analysis results.  The I/O state was required because
analysis files were loaded "on demand" but in most cases this was pointless.
Now we just load all the analysis files of imported modules before we run
anything that uses the analysis framework.

compiler/analysis.file.m:
compiler/analysis.m:
	Make the main change above.

	Use `unexpected' instead of `error' for fatal errors.

	Replace `{Call, Answer, analysis_status}' tuples by a new type
	`analysis_result'.

	Rename the existing existentially-typed `analysis_result' to
	`some_analysis_result'.

	Remove the `module_is_local' method from the `compiler' typeclass.
	Replace it by a plain procedure that takes an `analysis_info' as
	input, instead of using the I/O state.

	Use trace goals for debugging output, where we no longer have the I/O
	state.

	Clean up some code.

compiler/mercury_compile.m:
	Before running anything that uses the analysis framework, read in all
	the analysis files which might be needed.

compiler/mmc_analysis.m:
	Delete `module_is_local' method.

compiler/constraint.m:
compiler/deforest.m:
compiler/exception_analysis.m:
compiler/goal_form.m:
compiler/goal_util.m:
compiler/pd_util.m:
compiler/simplify.m:
compiler/size_prof.m:
compiler/tabling_analysis.m:
compiler/trailing_analysis.m:
compiler/unused_args.m:
	Conform to the changes above.

	Don't thread I/O state through procedures which no longer require it.

Index: compiler/analysis.file.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/analysis.file.m,v
retrieving revision 1.1
diff -u -r1.1 analysis.file.m
--- compiler/analysis.file.m	20 Feb 2008 03:09:59 -0000	1.1
+++ compiler/analysis.file.m	20 Feb 2008 23:48:11 -0000
@@ -7,7 +7,7 @@
 %-----------------------------------------------------------------------------%
 %
 % File: analysis.file.m
-% Main author: stayl
+% Main author: stayl, wangp.
 %
 % An analysis file contains analysis results for a single module.
 %
@@ -33,7 +33,7 @@
     % from a `.analysis' file.
     %
 :- pred read_module_analysis_results(analysis_info::in, module_id::in,
-    analysis_status::out, module_analysis_map(analysis_result)::out,
+    analysis_status::out, module_analysis_map(some_analysis_result)::out,
     module_extra_info_map::out, io::di, io::uo) is det.
 
     % write_module_analysis_results(AnalysisInfo, ModuleId,
@@ -44,7 +44,7 @@
     %
 :- pred write_module_analysis_results(analysis_info::in,
     module_id::in, analysis_status::in,
-    module_analysis_map(analysis_result)::in,
+    module_analysis_map(some_analysis_result)::in,
     module_extra_info_map::in, io::di, io::uo) is det.
 
     % read_module_analysis_requests(AnalysisInfo, ModuleId, ModuleRequests,
@@ -92,6 +92,17 @@
 
 :- implementation.
 
+:- import_module bool.
+:- import_module exception.
+:- import_module parser.
+:- import_module term.
+:- import_module term_io.
+:- import_module varset.
+
+:- import_module libs.compiler_util.
+
+%-----------------------------------------------------------------------------%
+
 % The format of an analysis result file is:
 %
 % version_number.
@@ -112,21 +123,23 @@
 % version_number.
 % analysis_name(analysis_version, func_id, call_pattern).
 
-:- import_module bool, exception, parser, term, term_io, varset.
-
 :- type invalid_analysis_file
     --->    invalid_analysis_file.
 
 :- func version_number = int.
+
 version_number = 2.
 
 :- func analysis_registry_suffix = string.
+
 analysis_registry_suffix = ".analysis".
 
 :- func imdg_suffix = string.
+
 imdg_suffix = ".imdg".
 
 :- func request_suffix = string.
+
 request_suffix = ".request".
 
 %-----------------------------------------------------------------------------%
@@ -213,7 +226,7 @@
     ).
 
 :- pred read_module_analysis_results_2(Compiler::in, string::in,
-    analysis_status::out, module_analysis_map(analysis_result)::out,
+    analysis_status::out, module_analysis_map(some_analysis_result)::out,
     module_extra_info_map::out, io::di, io::uo) is det <= compiler(Compiler).
 
 read_module_analysis_results_2(Compiler, AnalysisFileName,
@@ -223,8 +236,8 @@
     (
         OpenResult = ok(Stream),
         debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-            io.print("Reading analysis registry file ", !IO),
-            io.print(AnalysisFileName, !IO),
+            io.write_string("% Reading analysis registry file ", !IO),
+            io.write_string(AnalysisFileName, !IO),
             io.nl(!IO)
         ), !IO),
         io.set_input_stream(Stream, OldStream, !IO),
@@ -263,8 +276,8 @@
     ;
         OpenResult = error(_),
         debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-            io.print("Error reading analysis registry file: ", !IO),
-            io.print(AnalysisFileName, !IO),
+            io.write_string("% Error reading analysis registry file: ", !IO),
+            io.write_string(AnalysisFileName, !IO),
             io.nl(!IO)
         ), !IO),
         ModuleStatus = optimal,
@@ -327,7 +340,7 @@
     ).
 
 :- pred parse_result_entry(Compiler::in)
-    `with_type` parse_entry(module_analysis_map(analysis_result))
+    `with_type` parse_entry(module_analysis_map(some_analysis_result))
     `with_inst` parse_entry <= compiler(Compiler).
 
 parse_result_entry(Compiler, Term, Results0, Results) :-
@@ -353,7 +366,7 @@
             VersionNumberTerm = term.functor(
                 term.integer(VersionNumber), [], _)
         ->
-            Result = 'new analysis_result'(CallPattern, AnswerPattern,
+            Result = 'new some_analysis_result'(CallPattern, AnswerPattern,
                 Status),
             ( AnalysisResults0 = map.search(Results0, AnalysisName) ->
                 AnalysisResults1 = AnalysisResults0
@@ -496,8 +509,15 @@
             ModuleResults0, ModuleResults, !IO)
     ;
         MaybeAnalysisFileName = error(Message),
-        debug_msg(io.print("Couldn't open " ++ Suffix ++
-            " for module " ++ ModuleId ++ ": " ++ Message ++ "\n"), !IO),
+        debug_msg((pred(!.IO::di, !:IO::uo) is det :-
+            io.write_string("Couldn't open ", !IO),
+            io.write_string(Suffix, !IO),
+            io.write_string(" for module ", !IO),
+            io.write_string(ModuleId, !IO),
+            io.write_string(": ", !IO),
+            io.write_string(Message, !IO),
+            io.nl(!IO)
+        ), !IO),
         ModuleResults = ModuleResults0
     ).
 
@@ -510,8 +530,8 @@
     (
         OpenResult = ok(Stream),
         debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-            io.print("Reading analysis file ", !IO),
-            io.print(AnalysisFileName, !IO),
+            io.write_string("% Reading analysis file ", !IO),
+            io.write_string(AnalysisFileName, !IO),
             io.nl(!IO)
         ), !IO),
         io.set_input_stream(Stream, OldStream, !IO),
@@ -538,8 +558,8 @@
     ;
         OpenResult = error(_),
         debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-            io.print("Error reading analysis file: ", !IO),
-            io.print(AnalysisFileName, !IO),
+            io.write_string("Error reading analysis file: ", !IO),
+            io.write_string(AnalysisFileName, !IO),
             io.nl(!IO)
         ), !IO),
         ModuleResults = ModuleResults0
@@ -578,10 +598,10 @@
 %-----------------------------------------------------------------------------%
 
 write_module_analysis_results(Info, ModuleId, ModuleStatus, ModuleResults,
-    ExtraInfo, !IO) :-
+        ExtraInfo, !IO) :-
     debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-        io.print("Writing module analysis results for ", !IO),
-        io.print(ModuleId, !IO),
+        io.write_string("% Writing module analysis results for ", !IO),
+        io.write_string(ModuleId, !IO),
         io.nl(!IO)
     ), !IO),
     WriteHeader = write_module_status_and_extra_info(ModuleStatus, ExtraInfo),
@@ -613,11 +633,11 @@
     ValueTerm = functor(string(Value), [], context_init).
 
 :- pred write_result_entry
-    `with_type` write_entry(analysis_result)
+    `with_type` write_entry(some_analysis_result)
     `with_inst` write_entry.
 
 write_result_entry(AnalysisName, FuncId, Result, !IO) :-
-    Result = analysis_result(Call, Answer, Status),
+    Result = some_analysis_result(Call, Answer, Status),
     VersionNumber = analysis_version_number(Call, Answer),
     analysis_status_to_string(Status, StatusString),
     term_io.write_term_nl(varset.init : varset,
@@ -636,8 +656,8 @@
     module_id_to_write_file_name(Compiler, ModuleId, request_suffix,
         AnalysisFileName, !IO),
     debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-        io.print("Writing module analysis requests to ", !IO),
-        io.print(AnalysisFileName, !IO),
+        io.write_string("% Writing module analysis requests to ", !IO),
+        io.write_string(AnalysisFileName, !IO),
         io.nl(!IO)
     ), !IO),
     io.open_input(AnalysisFileName, InputResult, !IO),
@@ -694,8 +714,8 @@
     ->
         VersionNumber = analysis_version_number(_ : Call, _ :  Answer)
     ;
-        error("write_request_entry: unknown analysis type")
-
+        unexpected(this_file,
+            "write_request_entry: unknown analysis type")
     ),
     term_io.write_term_nl(varset.init : varset,
         functor(atom(AnalysisName), [
@@ -722,7 +742,8 @@
     ->
         VersionNumber = analysis_version_number(_ : Call, _ : Answer)
     ;
-        error("write_imdg_arc: unknown analysis type")
+        unexpected(this_file,
+            "write_imdg_arc: unknown analysis type")
     ),
     term_io.write_term_nl(varset.init : varset,
         functor(atom("->"), [
@@ -803,8 +824,8 @@
     module_id_to_write_file_name(Info ^ compiler, ModuleId, request_suffix,
         RequestFileName, !IO),
     debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-        io.print("Removing request file ", !IO),
-        io.print(RequestFileName, !IO),
+        io.write_string("% Removing request file ", !IO),
+        io.write_string(RequestFileName, !IO),
         io.nl(!IO)
     ), !IO),
     io.remove_file(RequestFileName, _, !IO).
@@ -816,3 +837,5 @@
 nop(!IO).
 
 %-----------------------------------------------------------------------------%
+:- end_module analysis.file.
+%-----------------------------------------------------------------------------%
Index: compiler/analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/analysis.m,v
retrieving revision 1.1
diff -u -r1.1 analysis.m
--- compiler/analysis.m	20 Feb 2008 03:09:59 -0000	1.1
+++ compiler/analysis.m	20 Feb 2008 23:48:11 -0000
@@ -48,15 +48,7 @@
     % module_id_to_write_file_name(Compiler, ModuleId, Ext, FileName)
     %
     pred module_id_to_write_file_name(Compiler::in, module_id::in,
-        string::in, string::out, io::di, io::uo) is det,
-
-    % module_is_local(Compiler, ModuleId, IsLocal, !IO)
-    %
-    % IsLocal is `yes' if the module is not a "library" module, i.e. we are
-    % able to reanalyse the module, not just use results that already exist.
-    %
-    pred module_is_local(Compiler::in, module_id::in, bool::out,
-        io::di, io::uo) is det
+        string::in, string::out, io::di, io::uo) is det
 ].
 
 :- type module_id == string.
@@ -124,6 +116,13 @@
 
 :- typeclass extra_info(ExtraInfo) <= to_string(ExtraInfo) where [].
 
+:- type analysis_result(Call, Answer)
+    --->    analysis_result(
+                ar_call     :: Call,
+                ar_answer   :: Answer,
+                ar_status   :: analysis_status
+            ).
+
 :- typeclass partial_order(T) where [
     pred more_precise_than(T::in, T::in) is semidet,
     pred equivalent(T::in, T::in) is semidet
@@ -164,14 +163,15 @@
 
 :- func init_analysis_info(Compiler) = analysis_info <= compiler(Compiler).
 
+%-----------------------------------------------------------------------------%
+
     % Look up all results for a given function.
     %
     % N.B. Newly recorded results will NOT be found. This is intended
     % for looking up results from _other_ modules.
     %
-:- pred lookup_results(module_id::in, func_id::in,
-    list({Call, Answer, analysis_status})::out,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det
+:- pred lookup_results(analysis_info::in, module_id::in, func_id::in,
+    list(analysis_result(Call, Answer))::out) is det
     <= analysis(Call, Answer).
 
     % Look up all results for a given function and call pattern CP such
@@ -181,9 +181,8 @@
     % N.B. Newly recorded results will NOT be found. This is intended
     % for looking up results from _other_ modules.
     %
-:- pred lookup_matching_results(module_id::in, func_id::in, Call::in,
-    list({Call, Answer, analysis_status})::out,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det
+:- pred lookup_matching_results(analysis_info::in, module_id::in, func_id::in,
+    Call::in, list(analysis_result(Call, Answer))::out) is det
     <= analysis(Call, Answer).
 
     % Look up the best result matching a given call.
@@ -196,9 +195,8 @@
     % responsibility to request a more precise analysis from the called module,
     % using `record_request'.
     %
-:- pred lookup_best_result(module_id::in, func_id::in, Call::in,
-    maybe({Call, Answer, analysis_status})::out,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det
+:- pred lookup_best_result(analysis_info::in, module_id::in, func_id::in,
+    Call::in, maybe(analysis_result(Call, Answer))::out) is det
     <= analysis(Call, Answer).
 
     % Record an analysis result for a (usually local) function.
@@ -206,9 +204,8 @@
     % XXX At the moment the result is assumed to be for a function local to
     % the currently-compiled module and things will probably break if it isn't.
     %
-:- pred record_result(module_id::in, func_id::in, Call::in,
-    Answer::in, analysis_status::in,
-    analysis_info::in, analysis_info::out) is det
+:- pred record_result(module_id::in, func_id::in, Call::in, Answer::in,
+    analysis_status::in, analysis_info::in, analysis_info::out) is det
     <= analysis(Call, Answer).
 
     % Record the dependency of a module on the analysis result of another
@@ -220,9 +217,9 @@
 
     % Lookup all the requests for a given (usually local) function.
     %
-:- pred lookup_requests(analysis_name::in, module_id::in, func_id::in,
-    list(Call)::out, analysis_info::in, analysis_info::out,
-    io::di, io::uo) is det <= call_pattern(Call).
+:- pred lookup_requests(analysis_info::in, analysis_name::in, module_id::in,
+    func_id::in, list(Call)::out) is det
+    <= call_pattern(Call).
 
     % Record a request for a function in an imported module.
     %
@@ -230,11 +227,13 @@
     Call::in, analysis_info::in, analysis_info::out) is det
     <= call_pattern(Call).
 
+%-----------------------------------------------------------------------------%
+
     % Lookup extra information about a module, using the key given.
     %
-:- pred lookup_module_extra_info(module_id::in, extra_info_key::in,
-    maybe(ExtraInfo)::out, analysis_info::in, analysis_info::out,
-    io::di, io::uo) is det <= extra_info(ExtraInfo).
+:- pred lookup_module_extra_info(analysis_info::in, module_id::in,
+    extra_info_key::in, maybe(ExtraInfo)::out) is det
+    <= extra_info(ExtraInfo).
 
     % Record extra information about a module under the given key.
     %
@@ -242,6 +241,28 @@
     ExtraInfo::in, analysis_info::in, analysis_info::out) is det
     <= extra_info(ExtraInfo).
 
+%-----------------------------------------------------------------------------%
+
+    % prepare_intermodule_analysis(ModuleIds, LocalModuleIds, !Info, !IO)
+    %
+    % This predicate should be called before any pass begins to use the
+    % analysis framework.  It ensures that all the analysis files 
+    % are loaded so that lookups can be satisfied.  ModuleIds is the set of
+    % all modules that are directly or indirectly imported by the module being
+    % analysed.  LocalModuleIds is the set of non-"library" modules.
+    %
+:- pred prepare_intermodule_analysis(set(module_id)::in, set(module_id)::in,
+    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
+
+     % module_is_local(Info, ModuleId, IsLocal).
+     %
+     % IsLocal is `yes' if the module is not a "library" module, i.e. we are
+     % able to reanalyse the module. The set of local modules is set in
+     % `prepare_intermodule_analysis'.
+    %
+:- pred module_is_local(analysis_info::in, module_id::in, bool::out)
+    is det.
+
     % Should be called after all analysis is completed to write the
     % requests and results for the current compilation to the
     % analysis files.
@@ -250,6 +271,8 @@
     analysis_info::in, analysis_info::out, io::di, io::uo) is det
     <= compiler(Compiler).
 
+%-----------------------------------------------------------------------------%
+
     % read_module_overall_status(Compiler, ModuleId, MaybeModuleStatus, !IO)
     %
     % Attempt to read the overall status from a module `.analysis' file.
@@ -266,7 +289,10 @@
 :- implementation.
 
 :- include_module analysis.file.
+
 :- import_module analysis.file.
+:- import_module libs.
+:- import_module libs.compiler_util.
 
 :- import_module map.
 :- import_module require.
@@ -280,6 +306,11 @@
             analysis_info(
                 compiler :: Compiler,
 
+                % The set of local modules, i.e. for which we can issue
+                % requests.
+                %
+                local_module_ids :: set(module_id),
+
                 % Holds outstanding requests for more specialised variants
                 % of procedures. Requests are added to this map as analyses
                 % proceed and written out to disk at the end of the
@@ -299,8 +330,8 @@
                 % invalidated as a result. Then "new" results are moved
                 % into the "old" map, from where they can be written to disk.
                 %
-                old_analysis_results :: analysis_map(analysis_result),
-                new_analysis_results :: analysis_map(analysis_result),
+                old_analysis_results :: analysis_map(some_analysis_result),
+                new_analysis_results :: analysis_map(some_analysis_result),
 
                 % The extra info map stores any extra information needed
                 % by one or more analysis results.
@@ -333,12 +364,12 @@
     % An analysis result is a call pattern paired with an answer.
     % The result has a status associated with it.
     %
-:- type analysis_result
+:- type some_analysis_result
     --->    some [Call, Answer]
-            analysis_result(
-                Call,
-                Answer,
-                analysis_status
+            some_analysis_result(
+                some_ar_call    :: Call,
+                some_ar_answer  :: Answer,
+                some_ar_status  :: analysis_status
             )
             => analysis(Call, Answer).
 
@@ -385,46 +416,47 @@
 %-----------------------------------------------------------------------------%
 
 init_analysis_info(Compiler) =
-    'new analysis_info'(Compiler, map.init, map.init, map.init, map.init,
-        map.init, map.init, map.init, map.init).
+    'new analysis_info'(Compiler, set.init, map.init, map.init, map.init,
+        map.init, map.init, map.init, map.init, map.init).
 
 %-----------------------------------------------------------------------------%
 
-lookup_results(ModuleId, FuncId, ResultList, !Info, !IO) :-
-    lookup_results(no, ModuleId, FuncId, ResultList, !Info, !IO).
+lookup_results(Info, ModuleId, FuncId, ResultList) :-
+    lookup_results(Info, ModuleId, FuncId, no, ResultList).
 
-:- pred lookup_results(bool::in, module_id::in, func_id::in,
-    list({Call, Answer, analysis_status})::out,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det
+:- pred lookup_results(analysis_info::in, module_id::in, func_id::in,
+    bool::in, list(analysis_result(Call, Answer))::out) is det
     <= analysis(Call, Answer).
 
-lookup_results(AllowInvalidModules, ModuleId, FuncId, ResultList,
-    !Info, !IO) :-
-    debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-        io.write_string("Looking up analysis results for ", !IO),
-        io.write_string(ModuleId, !IO),
-        io.write_string(".", !IO),
-        io.write_string(FuncId, !IO),
-        io.nl(!IO)
-    ), !IO),
-    ensure_old_module_analysis_results_loaded(ModuleId, !Info, !IO),
+lookup_results(Info, ModuleId, FuncId, AllowInvalidModules, ResultList) :-
+    trace [io(!IO)] (
+        debug_msg((pred(!.IO::di, !:IO::uo) is det :-
+            io.write_string("% Looking up analysis results for ", !IO),
+            io.write_string(ModuleId, !IO),
+            io.write_string(".", !IO),
+            io.write_string(FuncId, !IO),
+            io.nl(!IO)
+        ), !IO)
+    ),
     (
         AllowInvalidModules = no,
-        !.Info ^ module_statuses ^ det_elem(ModuleId) = invalid
+        Info ^ module_statuses ^ det_elem(ModuleId) = invalid
     ->
         ResultList = []
     ;
-        lookup_results_2(!.Info ^ old_analysis_results, ModuleId, FuncId,
+        lookup_results_2(Info ^ old_analysis_results, ModuleId, FuncId,
             ResultList),
-        debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-            io.write_string("Found these results: ", !IO),
-            io.print(ResultList, !IO),
-            io.nl(!IO)
-        ), !IO)
+        trace [io(!IO)] (
+            debug_msg((pred(!.IO::di, !:IO::uo) is det :-
+                io.write_string("% Found these results: ", !IO),
+                io.print(ResultList, !IO),
+                io.nl(!IO)
+            ), !IO)
+        )
     ).
 
-:- pred lookup_results_2(analysis_map(analysis_result)::in, module_id::in,
-    func_id::in, list({Call, Answer, analysis_status})::out) is det
+:- pred lookup_results_2(analysis_map(some_analysis_result)::in, module_id::in,
+    func_id::in, list(analysis_result(Call, Answer))::out) is det
     <= analysis(Call, Answer).
 
 lookup_results_2(Map, ModuleId, FuncId, ResultList) :-
@@ -436,8 +468,8 @@
         % XXX we might have to discard results which are
         % `invalid' or `fixpoint_invalid' if they are written at all
         ResultList = list.map(
-            (func(Result) = {Call, Answer, Status} :-
-                Result = analysis_result(Call0, Answer0, Status),
+            (func(Result) = analysis_result(Call, Answer, Status) :-
+                Result = some_analysis_result(Call0, Answer0, Status),
                 det_univ_to_type(univ(Call0), Call),
                 det_univ_to_type(univ(Answer0), Answer)
             ), Results)
@@ -445,25 +477,27 @@
         ResultList = []
     ).
 
-lookup_matching_results(ModuleId, FuncId, Call, ResultList, !Info, !IO) :-
-    lookup_results(ModuleId, FuncId, AllResultsList, !Info, !IO),
+lookup_matching_results(Info, ModuleId, FuncId, Call, ResultList) :-
+    lookup_results(Info, ModuleId, FuncId, AllResultsList),
     ResultList = list.filter(
-        (pred(({ResultCall, _, _})::in) is semidet :-
+        (pred(Result::in) is semidet :-
+            ResultCall = Result ^ ar_call,
             ( more_precise_than(Call, ResultCall)
             ; equivalent(Call, ResultCall)
             )
         ), AllResultsList).
 
-lookup_best_result(ModuleId, FuncId, Call, MaybeBestResult, !Info, !IO) :-
-    debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-        io.write_string("Looking up best analysis result for ", !IO),
-        io.write_string(ModuleId, !IO),
-        io.write_string(".", !IO),
-        io.write_string(FuncId, !IO),
-        io.nl(!IO)
-    ), !IO),
-    lookup_matching_results(ModuleId, FuncId, Call, MatchingResults,
-        !Info, !IO),
+lookup_best_result(Info, ModuleId, FuncId, Call, MaybeBestResult) :-
+    trace [io(!IO)] (
+        debug_msg((pred(!.IO::di, !:IO::uo) is det :-
+            io.write_string("% Looking up best analysis result for ", !IO),
+            io.write_string(ModuleId, !IO),
+            io.write_string(".", !IO),
+            io.write_string(FuncId, !IO),
+            io.nl(!IO)
+        ), !IO)
+    ),
+    lookup_matching_results(Info, ModuleId, FuncId, Call, MatchingResults),
     (
         MatchingResults = [],
         MaybeBestResult = no
@@ -474,38 +508,38 @@
     ).
 
 :- pred most_precise_answer(
-    list({Call, Answer, analysis_status})::in(non_empty_list),
-    {Call, Answer, analysis_status}::out) is det
+    list(analysis_result(Call, Answer))::in(non_empty_list),
+    analysis_result(Call, Answer)::out) is det
     <= analysis(Call, Answer).
 
 most_precise_answer([Result | Results], BestResult) :-
     list.foldl(more_precise_answer, Results, Result, BestResult).
 
-:- pred more_precise_answer({Call, Answer, analysis_status}::in,
-    {Call, Answer, analysis_status}::in,
-    {Call, Answer, analysis_status}::out) is det
+:- pred more_precise_answer(analysis_result(Call, Answer)::in,
+    analysis_result(Call, Answer)::in,
+    analysis_result(Call, Answer)::out) is det
     <= analysis(Call, Answer).
 
 more_precise_answer(Result, Best0, Best) :-
-    Result = {_, ResultAnswer, _},
-    Best0  = {_, BestAnswer0, _},
+    ResultAnswer = Result ^ ar_answer,
+    BestAnswer0 = Best0 ^ ar_answer,
     ( more_precise_than(ResultAnswer, BestAnswer0) ->
         Best = Result
     ; 
         Best = Best0
     ).
 
-:- pred lookup_exactly_matching_result_even_from_invalid_modules(module_id::in,
-    func_id::in, Call::in, maybe({Call, Answer, analysis_status})::out,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det
+:- pred lookup_exactly_matching_result_even_from_invalid_modules(
+    analysis_info::in, module_id::in, func_id::in, Call::in,
+    maybe(analysis_result(Call, Answer))::out) is det
     <= analysis(Call, Answer).
 
-lookup_exactly_matching_result_even_from_invalid_modules(ModuleId,
-    FuncId, Call, MaybeResult, !Info, !IO) :-
-    lookup_results(yes, ModuleId, FuncId, AllResultsList, !Info, !IO),
+lookup_exactly_matching_result_even_from_invalid_modules(Info, ModuleId,
+        FuncId, Call, MaybeResult) :-
+    lookup_results(Info, ModuleId, FuncId, yes, AllResultsList),
     ResultList = list.filter(
-        (pred(({ResultCall, _, _})::in) is semidet :-
-            equivalent(Call, ResultCall)
+        (pred(R::in) is semidet :-
+            equivalent(Call, R ^ ar_call)
         ), AllResultsList),
     (
         ResultList = [],
@@ -515,7 +549,8 @@
         MaybeResult = yes(Result)
     ;
         ResultList = [_, _ | _],
-        error("lookup_exactly_matching_result: " ++
+        unexpected(this_file,
+            "lookup_exactly_matching_result: " ++
             "zero or one exactly matching results expected")
     ).
 
@@ -525,12 +560,12 @@
     Map0 = !.Info ^ new_analysis_results,
     record_result_in_analysis_map(ModuleId, FuncId,
     CallPattern, AnswerPattern, Status, Map0, Map),
-    !:Info = !.Info ^ new_analysis_results := Map.
+    !Info ^ new_analysis_results := Map.
 
 :- pred record_result_in_analysis_map(module_id::in, func_id::in,
     Call::in, Answer::in, analysis_status::in,
-    analysis_map(analysis_result)::in,
-    analysis_map(analysis_result)::out) is det
+    analysis_map(some_analysis_result)::in,
+    analysis_map(some_analysis_result)::out) is det
     <= analysis(Call, Answer).
 
 record_result_in_analysis_map(ModuleId, FuncId,
@@ -552,20 +587,15 @@
         FuncResults1 = []
     ),
     !:Map = map.set(!.Map, ModuleId,
-    map.set(ModuleResults1, AnalysisName,
-        map.set(AnalysisResults1, FuncId, FuncResults))),
+        map.set(ModuleResults1, AnalysisName,
+            map.set(AnalysisResults1, FuncId, FuncResults))),
     FuncResults = [Result | FuncResults1],
-    Result = 'new analysis_result'(CallPattern, AnswerPattern, Status).
+    Result = 'new some_analysis_result'(CallPattern, AnswerPattern, Status).
 
 %-----------------------------------------------------------------------------%
 
-lookup_requests(AnalysisName, ModuleId, FuncId, CallPatterns, !Info, !IO) :-
-    ( map.search(!.Info ^ analysis_requests, ModuleId, ModuleRequests0) ->
-        ModuleRequests = ModuleRequests0
-    ;
-        read_module_analysis_requests(!.Info, ModuleId, ModuleRequests, !IO),
-        !:Info = !.Info ^ analysis_requests ^ elem(ModuleId) := ModuleRequests
-    ),
+lookup_requests(Info, AnalysisName, ModuleId, FuncId, CallPatterns) :-
+    map.lookup(Info ^ analysis_requests, ModuleId, ModuleRequests),
     ( CallPatterns0 = ModuleRequests ^ elem(AnalysisName) ^ elem(FuncId) ->
         CallPatterns = list.filter_map(
             (func(analysis_request(Call0)) = Call is semidet :-
@@ -591,7 +621,7 @@
     ;
         FuncResults1 = []
     ),
-    !:Info = !.Info ^ analysis_requests :=
+    !Info ^ analysis_requests :=
         map.set(!.Info ^ analysis_requests, ModuleId,
             map.set(ModuleResults1, AnalysisName,
                 map.set(AnalysisResults1, FuncId,
@@ -629,7 +659,7 @@
         ( list.member(Dep, FuncArcs1) ->
             true
         ;
-            !:Info = !.Info ^ new_imdg :=
+            !Info ^ new_imdg :=
                 map.set(!.Info ^ new_imdg, CalleeModuleId,
                     map.set(Analyses1, AnalysisName,
                         map.set(Funcs1, FuncId, FuncArcs))),
@@ -639,9 +669,8 @@
 
 %-----------------------------------------------------------------------------%
 
-lookup_module_extra_info(ModuleId, Key, MaybeExtraInfo, !Info, !IO) :-
-    ensure_old_module_analysis_results_loaded(ModuleId, !Info, !IO),
-    ModuleExtraInfos = !.Info ^ old_extra_infos ^ det_elem(ModuleId),
+lookup_module_extra_info(Info, ModuleId, Key, MaybeExtraInfo) :-
+    ModuleExtraInfos = Info ^ old_extra_infos ^ det_elem(ModuleId),
     (
         String = ModuleExtraInfos ^ elem(Key),
         ExtraInfo = from_string(String)
@@ -658,7 +687,7 @@
         ModuleMap1 = map.init
     ),
     ModuleMap = map.set(ModuleMap1, Key, to_string(ExtraInfo)),
-    !:Info = !.Info ^ new_extra_infos ^ elem(ModuleId) := ModuleMap.
+    !Info ^ new_extra_infos ^ elem(ModuleId) := ModuleMap.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -689,34 +718,32 @@
     %
 :- pred update_analysis_registry(analysis_info::in, analysis_info::out,
     io::di, io::uo) is det.
-:- pred update_analysis_registry_2(module_id::in,
-    module_analysis_map(analysis_result)::in,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
-:- pred update_analysis_registry_3(module_id::in, analysis_name::in,
-    func_analysis_map(analysis_result)::in,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
-:- pred update_analysis_registry_4(module_id::in, analysis_name::in,
-    func_id::in, list(analysis_result)::in,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
-:- pred update_analysis_registry_5(module_id::in, analysis_name::in,
-    func_id::in, analysis_result::in,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
 
 update_analysis_registry(!Info, !IO) :-
-    debug_msg(io.print("Updating analysis registry.\n"), !IO),
+    debug_msg(io.write_string("% Updating analysis registry.\n"), !IO),
     map.foldl2(update_analysis_registry_2, !.Info ^ new_analysis_results,
         !Info, !IO),
-    !:Info = !.Info ^ new_analysis_results := map.init.
+    !Info ^ new_analysis_results := map.init.
+
+:- pred update_analysis_registry_2(module_id::in,
+    module_analysis_map(some_analysis_result)::in,
+    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
 
 update_analysis_registry_2(ModuleId, ModuleMap, !Info, !IO) :-
-    ensure_old_module_analysis_results_loaded(ModuleId, !Info, !IO),
-    ensure_old_imdg_loaded(ModuleId, !Info, !IO),
     map.foldl2(update_analysis_registry_3(ModuleId), ModuleMap, !Info, !IO).
 
+:- pred update_analysis_registry_3(module_id::in, analysis_name::in,
+    func_analysis_map(some_analysis_result)::in,
+    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
+
 update_analysis_registry_3(ModuleId, AnalysisName, FuncMap, !Info, !IO) :-
     map.foldl2(update_analysis_registry_4(ModuleId, AnalysisName),
         FuncMap, !Info, !IO).
 
+:- pred update_analysis_registry_4(module_id::in, analysis_name::in,
+    func_id::in, list(some_analysis_result)::in,
+    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
+
 update_analysis_registry_4(ModuleId, AnalysisName, FuncId, NewResults,
         !Info, !IO) :-
     % XXX Currently we do not prevent there being more than one recorded result
@@ -724,25 +751,30 @@
     list.foldl2(update_analysis_registry_5(ModuleId, AnalysisName, FuncId),
         NewResults, !Info, !IO).
 
+:- pred update_analysis_registry_5(module_id::in, analysis_name::in,
+    func_id::in, some_analysis_result::in,
+    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
+
 update_analysis_registry_5(ModuleId, AnalysisName, FuncId, NewResult,
         !Info, !IO) :-
-    NewResult = analysis_result(Call, NewAnswer, NewStatus),
-    lookup_exactly_matching_result_even_from_invalid_modules(ModuleId, FuncId,
-        Call, MaybeResult, !Info, !IO),
+    NewResult = some_analysis_result(Call, NewAnswer, NewStatus),
+    lookup_exactly_matching_result_even_from_invalid_modules(!.Info,
+        ModuleId, FuncId, Call, MaybeResult),
     (
         % There was a previous answer for this call pattern.
         %
-        MaybeResult = yes({_OldCall, OldAnswer, OldStatus}),
+        MaybeResult = yes(OldResult),
+        OldResult = analysis_result(_OldCall, OldAnswer, OldStatus),
         ( equivalent(NewAnswer, OldAnswer) ->
             debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-                io.print("No change in the result ", !IO),
-                io.print(ModuleId, !IO),
-                io.print(".", !IO),
-                io.print(FuncId, !IO),
-                io.print(":", !IO),
-                io.print(Call, !IO),
-                io.print(" --> ", !IO),
-                io.print(NewAnswer, !IO),
+                io.write_string("% No change in the result ", !IO),
+                io.write_string(ModuleId, !IO),
+                io.write_string(".", !IO),
+                io.write_string(FuncId, !IO),
+                io.write_string(":", !IO),
+                io.write(Call, !IO),
+                io.write_string(" --> ", !IO),
+                io.write(NewAnswer, !IO),
                 io.nl(!IO)
             ), !IO),
 
@@ -750,7 +782,7 @@
                 OldMap0 = !.Info ^ old_analysis_results,
                 replace_result_in_analysis_map(ModuleId, FuncId,
                     Call, NewAnswer, NewStatus, OldMap0, OldMap),
-                !:Info = !.Info ^ old_analysis_results := OldMap
+                !Info ^ old_analysis_results := OldMap
             ;
                 true
             )
@@ -760,7 +792,7 @@
             OldMap0 = !.Info ^ old_analysis_results,
             replace_result_in_analysis_map(ModuleId, FuncId,
                 Call, NewAnswer, NewStatus, OldMap0, OldMap),
-            !:Info = !.Info ^ old_analysis_results := OldMap,
+            !Info ^ old_analysis_results := OldMap,
 
             % If the answer is more precise than before then dependent modules
             % should be marked suboptimal. Otherwise the answer is less precise
@@ -771,15 +803,16 @@
                 Status = invalid
             ),
             debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-                io.print(OldAnswer, !IO),
-                io.print(" changed to ", !IO),
-                io.print(NewAnswer, !IO),
+                io.write_string("% ", !IO),
+                io.write(OldAnswer, !IO),
+                io.write_string(" changed to ", !IO),
+                io.write(NewAnswer, !IO),
                 io.nl(!IO),
-                io.print("Mark dependent modules as ", !IO),
-                io.print(Status, !IO),
+                io.write_string("Mark dependent modules as ", !IO),
+                io.write(Status, !IO),
                 io.nl(!IO),
-                io.print("The modules to mark are: ", !IO),
-                io.print(DepModules, !IO),
+                io.write_string("The modules to mark are: ", !IO),
+                io.write(DepModules, !IO),
                 io.nl(!IO)
             ), !IO),
             DepModules = imdg_dependent_modules(
@@ -795,7 +828,7 @@
         OldMap0 = !.Info ^ old_analysis_results,
         record_result_in_analysis_map(ModuleId, FuncId,
             Call, NewAnswer, NewStatus, OldMap0, OldMap),
-        !:Info = !.Info ^ old_analysis_results := OldMap
+        !Info ^ old_analysis_results := OldMap
     ).
 
     % replace_result_in_analysis_map(ModuleId, FuncId, Call, Answer, Status,
@@ -807,8 +840,8 @@
     %
 :- pred replace_result_in_analysis_map(module_id::in, func_id::in,
     Call::in, Answer::in, analysis_status::in,
-    analysis_map(analysis_result)::in,
-    analysis_map(analysis_result)::out) is det
+    analysis_map(some_analysis_result)::in,
+    analysis_map(some_analysis_result)::out) is det
     <= analysis(Call, Answer).
 
 replace_result_in_analysis_map(ModuleId, FuncId, CallPattern, AnswerPattern,
@@ -824,20 +857,25 @@
     map.det_update(AnalysisResults0, FuncId, FuncResults))).
 
 :- pred replace_result_in_list(Call::in, Answer::in, analysis_status::in,
-    list(analysis_result)::in, list(analysis_result)::out)
+    list(some_analysis_result)::in, list(some_analysis_result)::out)
     is det <= analysis(Call, Answer).
 
-replace_result_in_list(_Call, _Answer, _Status, [], _) :-
-    error("replace_result_in_list/5: found no result to replace").
-replace_result_in_list(Call, Answer, Status, [H0 | T0], [H | T]) :-
-    H0 = analysis_result(HCall0, _, _),
-    det_univ_to_type(univ(HCall0), HCall),
-    ( equivalent(Call, HCall) ->
-        H = 'new analysis_result'(Call, Answer, Status),
-        T = T0
-    ;
-        H = H0,
-        replace_result_in_list(Call, Answer, Status, T0, T)
+replace_result_in_list(Call, Answer, Status, Results0, Results) :-
+    (
+        Results0 = [],
+        unexpected(this_file,
+            "replace_result_in_list: found no result to replace")
+    ;
+        Results0 = [H0 | T0],
+        det_univ_to_type(univ(H0 ^ some_ar_call), HCall),
+        ( equivalent(Call, HCall) ->
+            H = 'new some_analysis_result'(Call, Answer, Status),
+            T = T0
+        ;
+            H = H0,
+            replace_result_in_list(Call, Answer, Status, T0, T)
+        ),
+        Results = [H | T]
     ).
 
 :- func imdg_dependent_modules(module_analysis_map(imdg_arc), analysis_name,
@@ -872,17 +910,23 @@
         ( Status = suboptimal
         ; Status = invalid
         ),
+
+        % We may not have loaded the analysis results for this module yet.
+        % Even though we loaded all the analysis files of modules reachable
+        % from the initial module beforehand, a _caller_ of the initial module
+        % may not be part of that set.
         ensure_old_module_analysis_results_loaded(ModuleId, !Info, !IO),
+
+        ModuleStatus0 = !.Info ^ module_statuses ^ det_elem(ModuleId),
+        ModuleStatus = lub(ModuleStatus0, Status),
         debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-            io.print("Tainting the overall module status of ", !IO),
+            io.print("% Tainting the overall module status of ", !IO),
             io.print(ModuleId, !IO),
             io.print(" with ", !IO),
             io.print(ModuleStatus, !IO),
             io.nl(!IO)
         ), !IO),
-        ModuleStatus0 = !.Info ^ module_statuses ^ det_elem(ModuleId),
-        ModuleStatus = lub(ModuleStatus0, Status),
-        !:Info = !.Info ^ module_statuses ^ elem(ModuleId) := ModuleStatus
+        !Info ^ module_statuses ^ elem(ModuleId) := ModuleStatus
     ).
 
 %-----------------------------------------------------------------------------%
@@ -892,8 +936,8 @@
 update_extra_infos(!Info) :-
     map.foldl(update_extra_infos_2,
         !.Info ^ new_extra_infos, !.Info ^ old_extra_infos, ExtraInfos),
-    !:Info = !.Info ^ old_extra_infos := ExtraInfos,
-    !:Info = !.Info ^ new_extra_infos := map.init.
+    !Info ^ old_extra_infos := ExtraInfos,
+    !Info ^ new_extra_infos := map.init.
 
 :- pred update_extra_infos_2(module_id::in, module_extra_info_map::in,
     map(module_id, module_extra_info_map)::in,
@@ -916,24 +960,25 @@
     %       add P^M:DP --> Q^N:DQ to N's IMDG
     %
 :- pred update_intermodule_dependencies(module_id::in, set(module_id)::in,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
+    analysis_info::in, analysis_info::out) is det.
 
-update_intermodule_dependencies(ModuleId, ImportedModules, !Info, !IO) :-
-    set.fold2(update_intermodule_dependencies_2(ModuleId),
-        ImportedModules, !Info, !IO).
+update_intermodule_dependencies(ModuleId, ImportedModules, !Info) :-
+    set.fold(update_intermodule_dependencies_2(ModuleId), ImportedModules,
+        !Info).
 
 :- pred update_intermodule_dependencies_2(module_id::in, module_id::in,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
+    analysis_info::in, analysis_info::out) is det.
 
-update_intermodule_dependencies_2(ModuleId, ImportedModuleId, !Info, !IO) :-
-    debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-        io.print("Clearing entries involving ", !IO),
-        io.print(ModuleId, !IO),
-        io.print(" from ", !IO),
-        io.print(ImportedModuleId, !IO),
-        io.print("'s IMDG.\n", !IO)
-    ), !IO),
-    ensure_old_imdg_loaded(ImportedModuleId, !Info, !IO),
+update_intermodule_dependencies_2(ModuleId, ImportedModuleId, !Info) :-
+    trace [io(!IO)] (
+        debug_msg((pred(!.IO::di, !:IO::uo) is det :-
+            io.print("% Clearing entries involving ", !IO),
+            io.print(ModuleId, !IO),
+            io.print(" from ", !IO),
+            io.print(ImportedModuleId, !IO),
+            io.print("'s IMDG.\n", !IO)
+        ), !IO)
+    ),
     IMDG0 = !.Info ^ old_imdg ^ det_elem(ImportedModuleId),
     clear_imdg_entries_pointing_at(ModuleId, IMDG0, IMDG1),
 
@@ -942,24 +987,27 @@
     ;
         IMDG = IMDG1
     ),
-    !:Info = !.Info ^ old_imdg ^ elem(ImportedModuleId) := IMDG,
-    !:Info = !.Info  ^ new_imdg :=
-        map.delete(!.Info ^ new_imdg, ImportedModuleId).
+    !Info ^ old_imdg ^ elem(ImportedModuleId) := IMDG,
+    !Info ^ new_imdg := map.delete(!.Info ^ new_imdg, ImportedModuleId).
 
 :- pred clear_imdg_entries_pointing_at(module_id::in,
     module_analysis_map(imdg_arc)::in,
     module_analysis_map(imdg_arc)::out) is det.
+
+clear_imdg_entries_pointing_at(ModuleId, Map0, Map) :-
+    map.map_values(clear_imdg_entries_pointing_at_2(ModuleId), Map0, Map).
+
 :- pred clear_imdg_entries_pointing_at_2(module_id::in, analysis_name::in,
     func_analysis_map(imdg_arc)::in,
     func_analysis_map(imdg_arc)::out) is det.
-:- pred clear_imdg_entries_pointing_at_3(module_id::in, func_id::in,
-    list(imdg_arc)::in, list(imdg_arc)::out) is det.
 
-clear_imdg_entries_pointing_at(ModuleId, Map0, Map) :-
-    map.map_values(clear_imdg_entries_pointing_at_2(ModuleId), Map0, Map).
 clear_imdg_entries_pointing_at_2(ModuleId, _, FuncMap0, FuncMap) :-
     map.map_values(clear_imdg_entries_pointing_at_3(ModuleId),
         FuncMap0, FuncMap).
+
+:- pred clear_imdg_entries_pointing_at_3(module_id::in, func_id::in,
+    list(imdg_arc)::in, list(imdg_arc)::out) is det.
+
 clear_imdg_entries_pointing_at_3(ModuleId, _, Arcs0, Arcs) :-
     list.filter((pred(imdg_arc(_, ModId)::in) is semidet :- ModuleId \= ModId),
         Arcs0, Arcs).
@@ -977,6 +1025,17 @@
 
 %-----------------------------------------------------------------------------%
 
+prepare_intermodule_analysis(ModuleIds, LocalModuleIds, !Info, !IO) :-
+    set.fold2(ensure_analysis_files_loaded, ModuleIds, !Info, !IO),
+    !Info ^ local_module_ids := LocalModuleIds.
+
+:- pred ensure_analysis_files_loaded(module_id::in,
+    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
+
+ensure_analysis_files_loaded(ModuleId, !Info, !IO) :-
+    ensure_old_module_analysis_results_loaded(ModuleId, !Info, !IO),
+    ensure_old_imdg_loaded(ModuleId, !Info, !IO).
+
 :- pred ensure_old_module_analysis_results_loaded(module_id::in,
     analysis_info::in, analysis_info::out, io::di, io::uo) is det.
 
@@ -987,10 +1046,9 @@
     ;
         read_module_analysis_results(!.Info, ModuleId,
             ModuleStatus, ModuleResults, ExtraInfos, !IO),
-        !:Info = !.Info ^ module_statuses ^ elem(ModuleId) := ModuleStatus,
-        !:Info = !.Info ^ old_analysis_results ^ elem(ModuleId)
-            := ModuleResults,
-        !:Info = !.Info ^ old_extra_infos ^ elem(ModuleId) := ExtraInfos
+        !Info ^ module_statuses ^ elem(ModuleId) := ModuleStatus,
+        !Info ^ old_analysis_results ^ elem(ModuleId) := ModuleResults,
+        !Info ^ old_extra_infos ^ elem(ModuleId) := ExtraInfos
     ).
 
 :- pred ensure_old_imdg_loaded(module_id::in, analysis_info::in,
@@ -1004,7 +1062,14 @@
     ;
         read_module_imdg(!.Info, ModuleId, IMDG, !IO),
         map.det_insert(Map0, ModuleId, IMDG, Map),
-        !:Info = !.Info ^ old_imdg := Map
+        !Info ^ old_imdg := Map
+    ).
+
+module_is_local(Info, ModuleId, IsLocal) :-
+    ( set.contains(Info ^ local_module_ids, ModuleId) ->
+        IsLocal = yes
+    ;
+        IsLocal = no
     ).
 
 %-----------------------------------------------------------------------------%
@@ -1022,15 +1087,15 @@
         ModuleStatus = optimal,
         % Force an `.analysis' file to be written out for this module,
         % even though there are no results recorded for it.
-        !:Info = !.Info ^ new_analysis_results ^ elem(ModuleId) := map.init
+        !Info ^ new_analysis_results ^ elem(ModuleId) := map.init
     ),
 
     update_analysis_registry(!Info, !IO),
     update_extra_infos(!Info),
 
-    !:Info = !.Info ^ module_statuses ^ elem(ModuleId) := ModuleStatus,
+    !Info ^ module_statuses ^ elem(ModuleId) := ModuleStatus,
 
-    update_intermodule_dependencies(ModuleId, ImportedModuleIds, !Info, !IO),
+    update_intermodule_dependencies(ModuleId, ImportedModuleIds, !Info),
     (
         map.is_empty(!.Info ^ new_analysis_results),
         map.is_empty(!.Info ^ new_extra_infos)
@@ -1065,7 +1130,7 @@
     % Touch a timestamp file to indicate the last time that this module was
     % analysed.
     module_id_to_write_file_name(Compiler, ModuleId, ".analysis_date",
-    TimestampFileName, !IO),
+        TimestampFileName, !IO),
     io.open_output(TimestampFileName, Result, !IO),
     (
         Result = ok(OutputStream),
@@ -1073,7 +1138,8 @@
         io.close_output(OutputStream, !IO)
     ;
         Result = error(IOError),
-        error(io.error_message(IOError))
+        unexpected(this_file,
+            "write_analysis_files: " ++ io.error_message(IOError))
     ).
 
 :- type write_module_analysis_map(T) ==
@@ -1083,29 +1149,30 @@
 :- pred write_local_modules(analysis_info::in,
     write_module_analysis_map(T)::write_module_analysis_map,
     analysis_map(T)::in, io::di, io::uo) is det.
-:- pred write_local_modules_2(analysis_info::in,
-    write_module_analysis_map(T)::write_module_analysis_map,
-    module_id::in, module_analysis_map(T)::in, io::di, io::uo) is det.
 
 write_local_modules(Info, Write, AnalysisMap, !IO) :-
     map.foldl(write_local_modules_2(Info, Write), AnalysisMap, !IO).
 
+:- pred write_local_modules_2(analysis_info::in,
+    write_module_analysis_map(T)::write_module_analysis_map,
+    module_id::in, module_analysis_map(T)::in, io::di, io::uo) is det.
+
 write_local_modules_2(Info, Write, ModuleId, ModuleResults, !IO) :-
-    module_is_local(Info ^ compiler, ModuleId, IsLocal, !IO),
+    module_is_local(Info, ModuleId, IsLocal),
     (
         IsLocal = yes,
         Write(Info, ModuleId, ModuleResults, !IO)
     ;
         IsLocal = no,
         debug_msg((pred(!.IO::di, !:IO::uo) is det :-
-            io.write_string("Not writing file for non-local module ", !IO),
+            io.write_string("% Not writing file for non-local module ", !IO),
             io.write_string(ModuleId, !IO),
             io.nl(!IO)
         ), !IO)
     ).
 
 :- pred write_module_analysis_results(analysis_info::in, module_id::in,
-    module_analysis_map(analysis_result)::in, io::di, io::uo) is det.
+    module_analysis_map(some_analysis_result)::in, io::di, io::uo) is det.
 
 write_module_analysis_results(Info, ModuleId, ModuleResults, !IO) :-
     ModuleStatus = Info ^ module_statuses ^ det_elem(ModuleId),
@@ -1115,7 +1182,7 @@
         ModuleExtraInfo = map.init
     ),
     analysis.file.write_module_analysis_results(Info, ModuleId,
-    ModuleStatus, ModuleResults, ModuleExtraInfo, !IO).
+        ModuleStatus, ModuleResults, ModuleExtraInfo, !IO).
 
 %-----------------------------------------------------------------------------%
 
@@ -1124,6 +1191,7 @@
         MaybeModuleStatus, !IO).
 
 %-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 lub(StatusA, StatusB) = Status :-
     compare(Cmp, StatusA, StatusB),
@@ -1138,23 +1206,29 @@
         Status = StatusB
     ).
 
-:- func lub_result_statuses(module_analysis_map(analysis_result))
-    = analysis_status.
-:- func lub_result_statuses_2(analysis_name,
-    func_analysis_map(analysis_result), analysis_status) = analysis_status.
-:- func lub_result_statuses_3(func_id, list(analysis_result), analysis_status)
-    = analysis_status.
-:- func lub_result_statuses_4(analysis_result, analysis_status)
+:- func lub_result_statuses(module_analysis_map(some_analysis_result))
     = analysis_status.
 
 lub_result_statuses(ModuleMap) =
     map.foldl(lub_result_statuses_2, ModuleMap, optimal).
+
+:- func lub_result_statuses_2(analysis_name,
+    func_analysis_map(some_analysis_result), analysis_status) =
+    analysis_status.
+
 lub_result_statuses_2(_AnalysisName, FuncMap, Acc) =
     map.foldl(lub_result_statuses_3, FuncMap, Acc).
+
+:- func lub_result_statuses_3(func_id, list(some_analysis_result),
+    analysis_status) = analysis_status.
+
 lub_result_statuses_3(_FuncId, Results, Acc) =
     list.foldl(lub_result_statuses_4, Results, Acc).
-lub_result_statuses_4(analysis_result(_, _, Status), Acc) =
-    lub(Status, Acc).
+
+:- func lub_result_statuses_4(some_analysis_result, analysis_status)
+    = analysis_status.
+
+lub_result_statuses_4(Result, Acc) = lub(Result ^ some_ar_status, Acc).
 
 %-----------------------------------------------------------------------------%
 
@@ -1174,3 +1248,13 @@
     ;
         Debug = no
     ).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "analysis.m".
+
+%-----------------------------------------------------------------------------%
+:- end_module analysis.
+%-----------------------------------------------------------------------------%
Index: compiler/constraint.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/constraint.m,v
retrieving revision 1.89
diff -u -r1.89 constraint.m
--- compiler/constraint.m	29 Jan 2008 04:59:37 -0000	1.89
+++ compiler/constraint.m	20 Feb 2008 23:48:11 -0000
@@ -25,7 +25,6 @@
 :- import_module parse_tree.prog_data.
 
 :- import_module bool.
-:- import_module io.
 
 %-----------------------------------------------------------------------------%
 
@@ -38,7 +37,7 @@
     % goal feature.
     %
 :- pred propagate_constraints_in_goal(hlds_goal::in, hlds_goal::out,
-    constraint_info::in, constraint_info::out, io::di, io::uo) is det.
+    constraint_info::in, constraint_info::out) is det.
 
 :- pred constraint_info_init(module_info::in, vartypes::in, prog_varset::in,
     instmap::in, constraint_info::out) is det.
@@ -68,7 +67,7 @@
 
 %-----------------------------------------------------------------------------%
 
-propagate_constraints_in_goal(Goal0, Goal, !Info, !IO) :-
+propagate_constraints_in_goal(Goal0, Goal, !Info) :-
     % We need to strip off any existing constraint markers first.
     % Constraint markers are meant to indicate where a constraint is
     % meant to be attached to a call, and that deforest.m should
@@ -76,20 +75,19 @@
     % deforest.m rearranges the goal, the constraints may not remain
     % next to the call.
     Goal1 = strip_constraint_markers(Goal0),
-    propagate_goal(Goal1, [], Goal, !Info, !IO).
+    propagate_goal(Goal1, [], Goal, !Info).
 
 :- pred propagate_goal(hlds_goal::in, list(constraint)::in,
-    hlds_goal::out, constraint_info::in, constraint_info::out,
-    io::di, io::uo) is det.
+    hlds_goal::out, constraint_info::in, constraint_info::out) is det.
 
-propagate_goal(Goal0, Constraints, Goal, !Info, !IO) :-
+propagate_goal(Goal0, Constraints, Goal, !Info) :-
     % We need to treat all single goals as conjunctions so that propagate_conj
     % can move the constraints to the left of the goal if that is allowed.
     Goal0 = hlds_goal(_, GoalInfo0),
     Features0 = goal_info_get_features(GoalInfo0),
     Context = goal_info_get_context(GoalInfo0),
     goal_to_conj_list(Goal0, Goals0),
-    propagate_conj(Goals0, Constraints, Goals, !Info, !IO),
+    propagate_conj(Goals0, Constraints, Goals, !Info),
     goal_list_nonlocals(Goals, NonLocals),
     goal_list_instmap_delta(Goals, Delta),
     goal_list_determinism(Goals, ConjDetism),
@@ -102,9 +100,9 @@
 
 :- pred propagate_conj_sub_goal(hlds_goal::in,
     list(constraint)::in, hlds_goals::out,
-    constraint_info::in, constraint_info::out, io::di, io::uo) is det.
+    constraint_info::in, constraint_info::out) is det.
 
-propagate_conj_sub_goal(Goal0, Constraints, Goals, !Info, !IO) :-
+propagate_conj_sub_goal(Goal0, Constraints, Goals, !Info) :-
     Goal0 = hlds_goal(GoalExpr0, _),
     ( goal_is_atomic(GoalExpr0) ->
         true
@@ -115,20 +113,19 @@
         constraint_info_update_changed(Constraints, !Info)
     ),
     InstMap0 = !.Info ^ constr_instmap,
-    propagate_conj_sub_goal_2(Goal0, Constraints, Goals, !Info, !IO),
+    propagate_conj_sub_goal_2(Goal0, Constraints, Goals, !Info),
     !:Info = !.Info ^ constr_instmap := InstMap0.
 
 :- pred propagate_conj_sub_goal_2(hlds_goal::in, list(constraint)::in,
-    list(hlds_goal)::out, constraint_info::in, constraint_info::out,
-    io::di, io::uo) is det.
+    list(hlds_goal)::out, constraint_info::in, constraint_info::out) is det.
 
 propagate_conj_sub_goal_2(hlds_goal(GoalExpr, GoalInfo), Constraints,
-        FinalGoals, !Info, !IO) :-
+        FinalGoals, !Info) :-
     (
         GoalExpr = conj(ConjType, Goals0),
         (
             ConjType = plain_conj,
-            propagate_conj(Goals0, Constraints, Goals, !Info, !IO),
+            propagate_conj(Goals0, Constraints, Goals, !Info),
             FinalGoals = [hlds_goal(conj(ConjType, Goals), GoalInfo)]
         ;
             ConjType = parallel_conj,
@@ -136,17 +133,17 @@
             % parallel conjunctions must have determinism det. However, we can
             % propagate constraints *within* the goals of the conjunction.
             flatten_constraints(Constraints, MoreGoals),
-            propagate_in_independent_goals(Goals0, [], Goals, !Info, !IO),
+            propagate_in_independent_goals(Goals0, [], Goals, !Info),
             FinalGoals = [hlds_goal(conj(ConjType, Goals), GoalInfo) |
                 MoreGoals]
         )
     ;
         GoalExpr = disj(Goals0),
-        propagate_in_independent_goals(Goals0, Constraints, Goals, !Info, !IO),
+        propagate_in_independent_goals(Goals0, Constraints, Goals, !Info),
         FinalGoals = [hlds_goal(disj(Goals), GoalInfo)]
     ;
         GoalExpr = switch(Var, CanFail, Cases0),
-        propagate_cases(Var, Constraints, Cases0, Cases, !Info, !IO),
+        propagate_cases(Var, Constraints, Cases0, Cases, !Info),
         FinalGoals = [hlds_goal(switch(Var, CanFail, Cases), GoalInfo)]
     ;
         GoalExpr = if_then_else(Vars, Cond0, Then0, Else0),
@@ -154,11 +151,11 @@
         % We can't safely propagate constraints into the condition of an
         % if-then-else, because that would change the answers generated
         % by the procedure.
-        propagate_goal(Cond0, [], Cond, !Info, !IO),
+        propagate_goal(Cond0, [], Cond, !Info),
         constraint_info_update_goal(Cond, !Info),
-        propagate_goal(Then0, Constraints, Then, !Info, !IO),
+        propagate_goal(Then0, Constraints, Then, !Info),
         !:Info = !.Info ^ constr_instmap := InstMap0,
-        propagate_goal(Else0, Constraints, Else, !Info, !IO),
+        propagate_goal(Else0, Constraints, Else, !Info),
         FinalGoals =
             [hlds_goal(if_then_else(Vars, Cond, Then, Else), GoalInfo)]
     ;
@@ -167,7 +164,7 @@
             ( Reason = exist_quant(_)
             ; Reason = from_ground_term(_)
             ),
-            propagate_goal(SubGoal0, Constraints, SubGoal, !Info, !IO),
+            propagate_goal(SubGoal0, Constraints, SubGoal, !Info),
             FinalGoals = [hlds_goal(scope(Reason, SubGoal), GoalInfo)]
         ;
             ( Reason = promise_solutions(_, _)
@@ -178,7 +175,7 @@
             ),
             % We can't safely propagate constraints into one of these scopes.
             % However, we can propagate constraints inside the scope goal.
-            propagate_goal(SubGoal0, [], SubGoal, !Info, !IO),
+            propagate_goal(SubGoal0, [], SubGoal, !Info),
             flatten_constraints(Constraints, ConstraintGoals),
             FinalGoals = [hlds_goal(scope(Reason, SubGoal), GoalInfo) |
                 ConstraintGoals]
@@ -187,7 +184,7 @@
         GoalExpr = negation(NegGoal0),
         % We can't safely propagate constraints into a negation,
         % because that would change the answers computed by the procedure.
-        propagate_goal(NegGoal0, [], NegGoal, !Info, !IO),
+        propagate_goal(NegGoal0, [], NegGoal, !Info),
         flatten_constraints(Constraints, ConstraintGoals),
         FinalGoals = [hlds_goal(negation(NegGoal), GoalInfo) | ConstraintGoals]
     ;
@@ -222,33 +219,32 @@
 %-----------------------------------------------------------------------------%
 
 :- pred propagate_in_independent_goals(hlds_goals::in, list(constraint)::in,
-    hlds_goals::out, constraint_info::in, constraint_info::out,
-    io::di, io::uo) is det.
+    hlds_goals::out, constraint_info::in, constraint_info::out) is det.
 
-propagate_in_independent_goals([], _, [], !Info, !IO).
+propagate_in_independent_goals([], _, [], !Info).
 propagate_in_independent_goals([Goal0 | Goals0], Constraints, [Goal | Goals],
-        !Info, !IO) :-
+        !Info) :-
     InstMap0 = !.Info ^ constr_instmap,
-    propagate_goal(Goal0, Constraints, Goal, !Info, !IO),
+    propagate_goal(Goal0, Constraints, Goal, !Info),
     !:Info = !.Info ^ constr_instmap := InstMap0,
-    propagate_in_independent_goals(Goals0, Constraints, Goals, !Info, !IO).
+    propagate_in_independent_goals(Goals0, Constraints, Goals, !Info).
 
 %-----------------------------------------------------------------------------%
 
 :- pred propagate_cases(prog_var::in, list(constraint)::in,
     list(case)::in, list(case)::out,
-    constraint_info::in, constraint_info::out, io::di, io::uo) is det.
+    constraint_info::in, constraint_info::out) is det.
 
-propagate_cases(_, _, [], [], !Info, !IO).
+propagate_cases(_, _, [], [], !Info).
 propagate_cases(Var, Constraints, [Case0 | Cases0], [Case | Cases],
-        !Info, !IO) :-
+        !Info) :-
     Case0 = case(MainConsId, OtherConsIds, Goal0),
     InstMap0 = !.Info ^ constr_instmap,
     constraint_info_bind_var_to_functors(Var, MainConsId, OtherConsIds, !Info),
-    propagate_goal(Goal0, Constraints, Goal, !Info, !IO),
+    propagate_goal(Goal0, Constraints, Goal, !Info),
     !:Info = !.Info ^ constr_instmap := InstMap0,
     Case = case(MainConsId, OtherConsIds, Goal),
-    propagate_cases(Var, Constraints, Cases0, Cases, !Info, !IO).
+    propagate_cases(Var, Constraints, Cases0, Cases, !Info).
 
 %-----------------------------------------------------------------------------%
 
@@ -258,10 +254,9 @@
     % to increase the likelihood of folding recursive calls.
     %
 :- pred propagate_conj(hlds_goals::in, list(constraint)::in,
-    hlds_goals::out, constraint_info::in, constraint_info::out,
-    io::di, io::uo) is det.
+    hlds_goals::out, constraint_info::in, constraint_info::out) is det.
 
-propagate_conj(Goals0, Constraints, Goals, !Info, !IO) :-
+propagate_conj(Goals0, Constraints, Goals, !Info) :-
     constraint_info_update_changed(Constraints, !Info),
     (
         Goals0 = [],
@@ -272,7 +267,7 @@
             GoalsTail0 = [],
             Constraints = []
         ->
-            propagate_conj_sub_goal(Goal0, [], Goals, !Info, !IO)
+            propagate_conj_sub_goal(Goal0, [], Goals, !Info)
         ;
             InstMap0 = !.Info ^ constr_instmap,
             ModuleInfo = !.Info ^ constr_module_info,
@@ -280,8 +275,8 @@
             annotate_conj_output_vars(Goals0, ModuleInfo,
                 VarTypes, InstMap0, [], RevGoals1),
             annotate_conj_constraints(ModuleInfo, RevGoals1,
-                Constraints, [], Goals2, !Info, !IO),
-            propagate_conj_constraints(Goals2, [], Goals, !Info, !IO)
+                Constraints, [], Goals2, !Info),
+            propagate_conj_constraints(Goals2, [], Goals, !Info)
         )
     ).
 
@@ -399,9 +394,9 @@
     %
 :- pred annotate_conj_constraints(module_info::in, annotated_conj::in,
     list(constraint)::in, constrained_conj::in, constrained_conj::out,
-    constraint_info::in, constraint_info::out, io::di, io::uo) is det.
+    constraint_info::in, constraint_info::out) is det.
 
-annotate_conj_constraints(_, [], Constraints0, Goals0, Goals, !Info, !IO) :-
+annotate_conj_constraints(_, [], Constraints0, Goals0, Goals, !Info) :-
     flatten_constraints(Constraints0, Constraints1),
     list.map((pred(Goal::in, CnstrGoal::out) is det :-
             CnstrGoal = Goal - []
@@ -409,14 +404,14 @@
     list.append(Constraints, Goals0, Goals).
 annotate_conj_constraints(ModuleInfo,
         [Conjunct | RevConjuncts0],
-        Constraints0, Goals0, Goals, !Info, !IO) :-
+        Constraints0, Goals0, Goals, !Info) :-
     Conjunct = annotated_conjunct(Goal, ChangedVars, OutputVars,
         IncompatibleInstVars),
     Goal = hlds_goal(GoalExpr, GoalInfo),
     NonLocals = goal_info_get_nonlocals(GoalInfo),
     CI_ModuleInfo0 = !.Info ^ constr_module_info,
     goal_can_loop_or_throw(Goal, GoalCanLoopOrThrow,
-        CI_ModuleInfo0, CI_ModuleInfo, !IO),
+        CI_ModuleInfo0, CI_ModuleInfo),
     !:Info = !.Info ^ constr_module_info := CI_ModuleInfo,
     (
         % Propagate goals that can fail and have no output variables.
@@ -507,7 +502,7 @@
         Goals1 = [attach_constraints(Goal, DependentConstraints) | Goals0]
     ),
     annotate_conj_constraints(ModuleInfo, RevConjuncts0, Constraints1,
-        Goals1, Goals, !Info, !IO).
+        Goals1, Goals, !Info).
 
 :- pred add_empty_constraints(hlds_goal::in,
     pair(hlds_goal, list(constraint))::out) is det.
@@ -656,22 +651,22 @@
     %
 :- pred propagate_conj_constraints(constrained_conj::in,
     list(hlds_goal)::in, list(hlds_goal)::out,
-    constraint_info::in, constraint_info::out, io::di, io::uo) is det.
+    constraint_info::in, constraint_info::out) is det.
 
-propagate_conj_constraints([], RevGoals, Goals, !Info, !IO) :-
+propagate_conj_constraints([], RevGoals, Goals, !Info) :-
     list.reverse(RevGoals, Goals).
 propagate_conj_constraints([Goal0 - Constraints0 | Goals0],
-        RevGoals0, RevGoals, !Info, !IO) :-
+        RevGoals0, RevGoals, !Info) :-
     filter_complex_constraints(Constraints0,
         SimpleConstraints, ComplexConstraints0),
-    propagate_conj_sub_goal(Goal0, SimpleConstraints, GoalList1, !Info, !IO),
+    propagate_conj_sub_goal(Goal0, SimpleConstraints, GoalList1, !Info),
     flatten_constraints(ComplexConstraints0, ComplexConstraints),
     list.reverse(ComplexConstraints, RevComplexConstraints),
     list.reverse(GoalList1, RevGoalList1),
     list.condense([RevComplexConstraints, RevGoalList1, RevGoals0],
         RevGoals1),
     constraint_info_update_goal(Goal0, !Info),
-    propagate_conj_constraints(Goals0, RevGoals1, RevGoals, !Info, !IO).
+    propagate_conj_constraints(Goals0, RevGoals1, RevGoals, !Info).
 
 :- pred filter_complex_constraints(list(constraint)::in,
     list(constraint)::out, list(constraint)::out) is det.
Index: compiler/deforest.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/deforest.m,v
retrieving revision 1.83
diff -u -r1.83 deforest.m
--- compiler/deforest.m	30 Dec 2007 08:23:34 -0000	1.83
+++ compiler/deforest.m	20 Feb 2008 23:48:12 -0000
@@ -209,7 +209,7 @@
         % Inlining may have created some opportunities for simplification.
         globals.io_get_globals(Globals, !IO),
         simplify.find_simplifications(no, Globals, Simplifications),
-        pd_util.pd_simplify_goal(Simplifications, !Goal, !PDInfo, !IO),
+        pd_util.pd_simplify_goal(Simplifications, !Goal, !PDInfo),
 
         pd_util.propagate_constraints(!Goal, !PDInfo, !IO),
 
@@ -1687,7 +1687,7 @@
     % This helps achieve folding in some cases.
     SimpList = [simp_extra_common_struct | SimpList0],
     Simplifications = list_to_simplifications(SimpList),
-    pd_util.pd_simplify_goal(Simplifications, Goal2, Goal3, !PDInfo, !IO),
+    pd_util.pd_simplify_goal(Simplifications, Goal2, Goal3, !PDInfo),
     pd_info_set_instmap(InstMap0, !PDInfo),
 
     % Perform any folding which may now be possible.
@@ -1926,7 +1926,7 @@
         pd_info_get_module_info(!.PDInfo, ModuleInfo),
         module_info_get_globals(ModuleInfo, Globals),
         simplify.find_simplifications(no, Globals, Simplifications),
-        pd_util.pd_simplify_goal(Simplifications, Goal3, Goal4, !PDInfo, !IO),
+        pd_util.pd_simplify_goal(Simplifications, Goal3, Goal4, !PDInfo),
 
         pd_info_get_cost_delta(!.PDInfo, CostDelta1),
         CostDelta = CostDelta1 - CostDelta0,
Index: compiler/exception_analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/exception_analysis.m,v
retrieving revision 1.44
diff -u -r1.44 exception_analysis.m
--- compiler/exception_analysis.m	18 Feb 2008 23:57:44 -0000	1.44
+++ compiler/exception_analysis.m	20 Feb 2008 23:48:12 -0000
@@ -109,8 +109,7 @@
     %       update the IMDG as well.
     %
 :- pred lookup_exception_analysis_result(pred_proc_id::in,
-    exception_status::out, module_info::in, module_info::out, io::di, io::uo)
-    is det.
+    exception_status::out, module_info::in, module_info::out) is det.
 
 %----------------------------------------------------------------------------%
 %
@@ -159,7 +158,7 @@
     module_info_ensure_dependency_info(!ModuleInfo),
     module_info_dependency_info(!.ModuleInfo, DepInfo),
     hlds_dependency_info_get_dependency_ordering(DepInfo, SCCs),
-    list.foldl2(check_scc_for_exceptions, SCCs, !ModuleInfo, !IO),
+    list.foldl(check_scc_for_exceptions, SCCs, !ModuleInfo),
     % Only write exception analysis pragmas to `.opt' files for
     % `--intermodule-optimization', not `--intermodule-analysis'.
     globals.io_lookup_bool_option(make_optimization_interface, MakeOptInt,
@@ -205,10 +204,10 @@
             ).
 
 :- pred check_scc_for_exceptions(scc::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-check_scc_for_exceptions(SCC, !ModuleInfo, !IO) :-
-    check_procs_for_exceptions(SCC, ProcResults, !ModuleInfo, !IO),
+check_scc_for_exceptions(SCC, !ModuleInfo) :-
+    check_procs_for_exceptions(SCC, ProcResults, !ModuleInfo),
     %
     % The `Results' above are the results of analysing each individual
     % procedure in the SCC - we now have to combine them in a meaningful way.
@@ -227,8 +226,9 @@
     %
     % Record the analysis results for intermodule analysis.
     %
-    globals.io_lookup_bool_option(make_analysis_registry,
-        MakeAnalysisRegistry, !IO),
+    module_info_get_globals(!.ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, make_analysis_registry,
+        MakeAnalysisRegistry),
     (
         MakeAnalysisRegistry = yes,
         (
@@ -247,11 +247,11 @@
     % Check each procedure in the SCC individually.
     %
 :- pred check_procs_for_exceptions(scc::in, proc_results::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-check_procs_for_exceptions(SCC, Result, !ModuleInfo, !IO) :-
-    list.foldl3(check_proc_for_exceptions(SCC), SCC, [], Result,
-        !ModuleInfo, !IO).
+check_procs_for_exceptions(SCC, Result, !ModuleInfo) :-
+    list.foldl2(check_proc_for_exceptions(SCC), SCC, [], Result,
+        !ModuleInfo).
 
     % Examine how procedures interact with other procedures that are
     % mutually-recursive to them.
@@ -331,40 +331,41 @@
 %
 
 :- pred check_proc_for_exceptions(scc::in, pred_proc_id::in,
-    proc_results::in, proc_results::out, module_info::in, module_info::out,
-    io::di, io::uo) is det.
+    proc_results::in, proc_results::out, module_info::in, module_info::out)
+    is det.
 
-check_proc_for_exceptions(SCC, PPId, !Results, !ModuleInfo, !IO) :-
+check_proc_for_exceptions(SCC, PPId, !Results, !ModuleInfo) :-
     module_info_pred_proc_info(!.ModuleInfo, PPId, _, ProcInfo),
     proc_info_get_goal(ProcInfo, Body),
     proc_info_get_vartypes(ProcInfo, VarTypes),
-    globals.io_lookup_bool_option(intermodule_analysis, IntermodAnalysis,
-        !IO),
+    module_info_get_globals(!.ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, intermodule_analysis,
+        IntermodAnalysis),
     MaybeAnalysisStatus0 = maybe_optimal(IntermodAnalysis),
     Result0 = proc_result(PPId, will_not_throw, type_will_not_throw,
         MaybeAnalysisStatus0),
     check_goal_for_exceptions(SCC, VarTypes, Body, Result0, Result,
-        !ModuleInfo, !IO),
+        !ModuleInfo),
     list.cons(Result, !Results).
 
-:- pred check_goal_for_exceptions(scc::in, vartypes::in,
-    hlds_goal::in, proc_result::in, proc_result::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+:- pred check_goal_for_exceptions(scc::in, vartypes::in, hlds_goal::in,
+    proc_result::in, proc_result::out, module_info::in, module_info::out)
+    is det.
 
 check_goal_for_exceptions(SCC, VarTypes, hlds_goal(GoalExpr, GoalInfo),
-        !Result, !ModuleInfo, !IO) :-
+        !Result, !ModuleInfo) :-
     ( goal_info_get_determinism(GoalInfo) = detism_erroneous ->
         !:Result = !.Result ^ status := may_throw(user_exception)
     ;
         check_goal_for_exceptions_2(SCC, VarTypes, GoalExpr, GoalInfo,
-            !Result, !ModuleInfo, !IO)
+            !Result, !ModuleInfo)
     ).
 
 :- pred check_goal_for_exceptions_2(scc::in, vartypes::in,
     hlds_goal_expr::in, hlds_goal_info::in, proc_result::in, proc_result::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-check_goal_for_exceptions_2(_, _, Goal, _, !Result, !ModuleInfo, !IO) :-
+check_goal_for_exceptions_2(_, _, Goal, _, !Result, !ModuleInfo) :-
     Goal = unify(_, _, _, Kind, _),
     ( 
         Kind = complicated_unify(_, _, _),
@@ -377,7 +378,7 @@
         )
     ).
 check_goal_for_exceptions_2(SCC, VarTypes, Goal, _, !Result,
-        !ModuleInfo, !IO) :-
+        !ModuleInfo) :-
     Goal = plain_call(CallPredId, CallProcId, CallArgs, _, _, _),
     CallPPId = proc(CallPredId, CallProcId),
     module_info_pred_info(!.ModuleInfo, CallPredId, CallPredInfo),
@@ -417,27 +418,29 @@
         % types of the arguments.  In particular whether some component of
         % that type has a user-defined equality/comparison predicate that
         % throws an exception.
-        globals.io_lookup_bool_option(intermodule_analysis, IntermodAnalysis,
-            !IO),
+        module_info_get_globals(!.ModuleInfo, Globals),
+        globals.lookup_bool_option(Globals, intermodule_analysis,
+            IntermodAnalysis),
         MaybeAnalysisStatus = maybe_optimal(IntermodAnalysis),
         check_vars(!.ModuleInfo, VarTypes, CallArgs, MaybeAnalysisStatus,
             !Result)
     ;
         Imported = pred_to_bool(pred_info_is_imported(CallPredInfo)),
         check_nonrecursive_call(SCC, VarTypes, CallPPId, CallArgs,
-            Imported, !Result, !ModuleInfo, !IO)
+            Imported, !Result, !ModuleInfo)
     ).
-check_goal_for_exceptions_2(SCC, VarTypes, Goal, GoalInfo,
-        !Result, !ModuleInfo, !IO) :-
+check_goal_for_exceptions_2(SCC, VarTypes, Goal, GoalInfo, !Result,
+        !ModuleInfo) :-
     Goal = generic_call(Details, Args, _ArgModes, _),
-    globals.io_lookup_bool_option(intermodule_analysis, IntermodAnalysis,
-        !IO),
+    module_info_get_globals(!.ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, intermodule_analysis,
+        IntermodAnalysis),
     (
         Details = higher_order(Var, _, _,  _),
         ClosureValueMap = goal_info_get_ho_values(GoalInfo),
         ( ClosureValues = ClosureValueMap ^ elem(Var) ->
             get_closures_exception_status(IntermodAnalysis, SCC, ClosureValues,
-                MaybeWillNotThrow, MaybeAnalysisStatus, !ModuleInfo, !IO),
+                MaybeWillNotThrow, MaybeAnalysisStatus, !ModuleInfo),
             (
                 MaybeWillNotThrow = maybe_will_not_throw(ConditionalProcs),
                 (
@@ -488,14 +491,13 @@
         Details = cast(_)
     ).
 check_goal_for_exceptions_2(SCC, VarTypes, negation(Goal), _,
-        !Result, !ModuleInfo, !IO) :-
-    check_goal_for_exceptions(SCC, VarTypes, Goal, !Result, !ModuleInfo, !IO).
-check_goal_for_exceptions_2(SCC, VarTypes, Goal, _,
-        !Result, !ModuleInfo, !IO) :-
+        !Result, !ModuleInfo) :-
+    check_goal_for_exceptions(SCC, VarTypes, Goal, !Result, !ModuleInfo).
+check_goal_for_exceptions_2(SCC, VarTypes, Goal, _, !Result, !ModuleInfo) :-
     Goal = scope(_, ScopeGoal),
     check_goal_for_exceptions(SCC, VarTypes, ScopeGoal, !Result,
-        !ModuleInfo, !IO).
-check_goal_for_exceptions_2(_, _, Goal, _, !Result, !ModuleInfo, !IO) :-
+        !ModuleInfo).
+check_goal_for_exceptions_2(_, _, Goal, _, !Result, !ModuleInfo) :-
     Goal = call_foreign_proc(Attributes, _, _, _, _, _, _),
     %    
     % NOTE: for --intermodule-analysis the results for for foreign_procs will
@@ -519,36 +521,31 @@
     ;
         MayCallMercury = proc_will_not_call_mercury
     ).
-check_goal_for_exceptions_2(_, _, shorthand(_), _, _, _, _, _, _, _) :-
+check_goal_for_exceptions_2(_, _, shorthand(_), _, _, _, _, _) :-
     unexpected(this_file,
         "shorthand goal encountered during exception analysis.").
-check_goal_for_exceptions_2(SCC, VarTypes, Goal, _, !Result, !ModuleInfo,
-        !IO) :-
+check_goal_for_exceptions_2(SCC, VarTypes, Goal, _, !Result, !ModuleInfo) :-
     Goal = switch(_, _, Cases),
     CaseGoals = list.map((func(case(_, _, CaseGoal)) = CaseGoal), Cases),
-    check_goals_for_exceptions(SCC, VarTypes, CaseGoals, !Result, !ModuleInfo,
-        !IO).
-check_goal_for_exceptions_2(SCC, VarTypes, Goal, _, !Result,
-        !ModuleInfo, !IO) :-
+    check_goals_for_exceptions(SCC, VarTypes, CaseGoals, !Result, !ModuleInfo).
+check_goal_for_exceptions_2(SCC, VarTypes, Goal, _, !Result, !ModuleInfo) :-
     Goal = if_then_else(_, If, Then, Else),
     check_goals_for_exceptions(SCC, VarTypes, [If, Then, Else],
-        !Result, !ModuleInfo, !IO).
-check_goal_for_exceptions_2(SCC, VarTypes, Goal, _, !Result, !ModuleInfo,
-        !IO) :-
+        !Result, !ModuleInfo).
+check_goal_for_exceptions_2(SCC, VarTypes, Goal, _, !Result, !ModuleInfo) :-
     ( Goal = disj(Goals)
     ; Goal = conj(_, Goals)
     ),
-    check_goals_for_exceptions(SCC, VarTypes, Goals, !Result, !ModuleInfo,
-        !IO).
+    check_goals_for_exceptions(SCC, VarTypes, Goals, !Result, !ModuleInfo).
 
 :- pred check_goals_for_exceptions(scc::in, vartypes::in,
     hlds_goals::in, proc_result::in, proc_result::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-check_goals_for_exceptions(_, _, [], !Result, !ModuleInfo, !IO).
-check_goals_for_exceptions(SCC, VarTypes, [Goal | Goals], !Result, !ModuleInfo,
-        !IO) :-
-    check_goal_for_exceptions(SCC, VarTypes, Goal, !Result, !ModuleInfo, !IO),
+check_goals_for_exceptions(_, _, [], !Result, !ModuleInfo).
+check_goals_for_exceptions(SCC, VarTypes, [Goal | Goals], !Result,
+        !ModuleInfo) :-
+    check_goal_for_exceptions(SCC, VarTypes, Goal, !Result, !ModuleInfo),
 
     % We can stop searching if we find a user exception.  However if we find
     % a type exception then we still need to check that there is not a user
@@ -562,8 +559,7 @@
         ; CurrentStatus = throw_conditional
         ; CurrentStatus = may_throw(type_exception)
         ),
-        check_goals_for_exceptions(SCC, VarTypes, Goals, !Result, !ModuleInfo,
-            !IO)
+        check_goals_for_exceptions(SCC, VarTypes, Goals, !Result, !ModuleInfo)
     ).
 
 %----------------------------------------------------------------------------%
@@ -592,32 +588,32 @@
     %
 :- pred get_closures_exception_status(bool::in, scc::in, set(pred_proc_id)::in,
     closures_exception_status::out, maybe(analysis_status)::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
 get_closures_exception_status(IntermodAnalysis, SCC, Closures,
-        Conditionals, AnalysisStatus, !ModuleInfo, !IO) :-
+        Conditionals, AnalysisStatus, !ModuleInfo) :-
     module_info_get_exception_info(!.ModuleInfo, ExceptionInfo),
     AnalysisStatus0 = maybe_optimal(IntermodAnalysis),
-    set.fold4(
+    set.fold3(
         get_closure_exception_status(IntermodAnalysis, SCC, ExceptionInfo),
         Closures, maybe_will_not_throw([]), Conditionals,
-        AnalysisStatus0, AnalysisStatus, !ModuleInfo, !IO).
+        AnalysisStatus0, AnalysisStatus, !ModuleInfo).
 
 :- pred get_closure_exception_status(
     bool::in, scc::in, exception_info::in, pred_proc_id::in,
     closures_exception_status::in, closures_exception_status::out,
     maybe(analysis_status)::in, maybe(analysis_status)::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
 get_closure_exception_status(IntermodAnalysis, SCC, ExceptionInfo, PPId,
-        !MaybeWillNotThrow, !AS, !ModuleInfo, !IO) :-
+        !MaybeWillNotThrow, !AS, !ModuleInfo) :-
     module_info_pred_proc_info(!.ModuleInfo, PPId, PredInfo, _),
     (
         IntermodAnalysis = yes,
         pred_info_is_imported(PredInfo)
     ->
         search_analysis_status(PPId, ExceptionStatus, AnalysisStatus, SCC,
-            !ModuleInfo, !IO),
+            !ModuleInfo),
         MaybeAnalysisStatus = yes(AnalysisStatus)
     ;
         ( ProcExceptionInfo = ExceptionInfo ^ elem(PPId) ->
@@ -692,11 +688,13 @@
 
 :- pred check_nonrecursive_call(scc::in, vartypes::in,
     pred_proc_id::in, prog_vars::in, bool::in, proc_result::in,
-    proc_result::out, module_info::in, module_info::out, io::di, io::uo) is det.
+    proc_result::out, module_info::in, module_info::out) is det.
 
 check_nonrecursive_call(SCC, VarTypes, PPId, Args, Imported, !Result,
-        !ModuleInfo, !IO) :-
-    globals.io_lookup_bool_option(intermodule_analysis, IntermodAnalysis, !IO),
+        !ModuleInfo) :-
+    module_info_get_globals(!.ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, intermodule_analysis,
+        IntermodAnalysis),
     (
         % If we are using `--intermodule-analysis' then use the analysis
         % framework for imported procedures.
@@ -704,7 +702,7 @@
         Imported = yes
     ->
         search_analysis_status(PPId, CalleeResult, AnalysisStatus, SCC,
-            !ModuleInfo, !IO),
+            !ModuleInfo),
         MaybeAnalysisStatus = yes(AnalysisStatus),
         update_proc_result(CalleeResult, MaybeAnalysisStatus, !Result)
     ;   
@@ -1048,30 +1046,32 @@
 
 :- pred search_analysis_status(pred_proc_id::in,
     exception_status::out, analysis_status::out, scc::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
 search_analysis_status(PPId, Result, AnalysisStatus, CallerSCC,
-        !ModuleInfo, !IO) :-
+        !ModuleInfo) :-
     module_info_get_analysis_info(!.ModuleInfo, AnalysisInfo0),
     search_analysis_status_2(!.ModuleInfo, PPId, Result, AnalysisStatus,
-        CallerSCC, AnalysisInfo0, AnalysisInfo, !IO),
+        CallerSCC, AnalysisInfo0, AnalysisInfo),
     module_info_set_analysis_info(AnalysisInfo, !ModuleInfo).
 
 :- pred search_analysis_status_2(module_info::in, pred_proc_id::in,
     exception_status::out, analysis_status::out, scc::in,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
+    analysis_info::in, analysis_info::out) is det.
 
 search_analysis_status_2(ModuleInfo, PPId, Result, AnalysisStatus, CallerSCC,
-        !AnalysisInfo, !IO) :-
+        !AnalysisInfo) :-
     module_id_func_id(ModuleInfo, PPId, ModuleId, FuncId),
     Call = any_call,
-    lookup_best_result(ModuleId, FuncId, Call, MaybeBestStatus, !AnalysisInfo,
-        !IO),
-    globals__io_lookup_bool_option(make_analysis_registry,
-        MakeAnalysisRegistry, !IO),
+    lookup_best_result(!.AnalysisInfo, ModuleId, FuncId, Call,
+        MaybeBestResult),
+    module_info_get_globals(ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, make_analysis_registry,
+        MakeAnalysisRegistry),
     (
-        MaybeBestStatus = yes({BestCall, exception_analysis_answer(Result),
-            AnalysisStatus}),
+        MaybeBestResult = yes(analysis_result(BestCall, BestAnswer,
+            AnalysisStatus)),
+        BestAnswer = exception_analysis_answer(Result),
         (
             MakeAnalysisRegistry = yes,
             record_dependencies(ModuleId, FuncId, BestCall, ModuleInfo,
@@ -1080,12 +1080,12 @@
             MakeAnalysisRegistry = no
         )
     ;
-        MaybeBestStatus = no,
+        MaybeBestResult = no,
         % If we do not have any information about the callee procedure then
         % assume that it throws an exception.
         top(Call) = Answer,
         Answer = exception_analysis_answer(Result),
-        module_is_local(mmc, ModuleId, IsLocal, !IO),
+        module_is_local(!.AnalysisInfo, ModuleId, IsLocal),
         (
             IsLocal = yes,
             AnalysisStatus = suboptimal,
@@ -1257,12 +1257,13 @@
 % External interface to exception analysis information
 %
 
-lookup_exception_analysis_result(PPId, ExceptionStatus, !ModuleInfo, !IO) :-
+lookup_exception_analysis_result(PPId, ExceptionStatus, !ModuleInfo) :-
     PPId = proc(PredId, _),
     module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
     IsImported = pred_to_bool(pred_info_is_imported(PredInfo)),
-    globals.io_lookup_bool_option(intermodule_analysis, IntermodAnalysis,
-        !IO),
+    module_info_get_globals(!.ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, intermodule_analysis,
+        IntermodAnalysis),
     %
     % If we the procedure we are calling is imported and we are using
     % intermodule-analysis then we need to look up the exception status in the
@@ -1287,10 +1288,11 @@
         some [!AnalysisInfo] (
             module_info_get_analysis_info(!.ModuleInfo, !:AnalysisInfo),
             module_id_func_id(!.ModuleInfo, PPId, ModuleId, FuncId),
-            lookup_best_result(ModuleId, FuncId, any_call, MaybeBestStatus,
-                !AnalysisInfo, !IO),
+            lookup_best_result(!.AnalysisInfo, ModuleId, FuncId, any_call,
+                MaybeBestResult),
             (
-                MaybeBestStatus = yes({_Call, Answer, AnalysisStatus}),
+                MaybeBestResult = yes(analysis_result(_Call, Answer,
+                    AnalysisStatus)),
                 (
                     AnalysisStatus = invalid,
                     unexpected(this_file,
@@ -1302,7 +1304,7 @@
                     Answer = exception_analysis_answer(ExceptionStatus)
                 )
             ;
-                MaybeBestStatus = no,
+                MaybeBestResult = no,
                 ExceptionStatus = may_throw(user_exception) 
             ),
             module_info_get_name(!.ModuleInfo, ThisModuleName),
Index: compiler/goal_form.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_form.m,v
retrieving revision 1.42
diff -u -r1.42 goal_form.m
--- compiler/goal_form.m	30 Dec 2007 08:23:39 -0000	1.42
+++ compiler/goal_form.m	20 Feb 2008 23:48:12 -0000
@@ -23,7 +23,6 @@
 :- import_module hlds.hlds_pred.
 
 :- import_module bool.
-:- import_module io.
 
 %-----------------------------------------------------------------------------%
 
@@ -62,13 +61,13 @@
     % be read and in case IMDGs need to be updated.
     %
 :- pred goal_can_throw(hlds_goal::in, goal_throw_status::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
     % Return `can_loop_or_throw' if the goal may loop forever or throw an
     % exception and return `cannot_loop_or_throw' otherwise.
     %
 :- pred goal_can_loop_or_throw(hlds_goal::in, goal_loop_or_throw_status::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
 %-----------------------------------------------------------------------------%
 
@@ -190,19 +189,18 @@
 % intermodule-analysis framework
 %
 
-goal_can_throw(hlds_goal(GoalExpr, GoalInfo), Result, !ModuleInfo, !IO) :-
+goal_can_throw(hlds_goal(GoalExpr, GoalInfo), Result, !ModuleInfo) :-
     Determinism = goal_info_get_determinism(GoalInfo),
     ( Determinism \= detism_erroneous ->
-        goal_can_throw_2(GoalExpr, GoalInfo, Result, !ModuleInfo, !IO)
+        goal_can_throw_2(GoalExpr, GoalInfo, Result, !ModuleInfo)
     ;
         Result = can_throw
     ).
 
 :- pred goal_can_throw_2(hlds_goal_expr::in, hlds_goal_info::in,
-    goal_throw_status::out, module_info::in, module_info::out,
-    io::di, io::uo) is det.
+    goal_throw_status::out, module_info::in, module_info::out) is det.
 
-goal_can_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
+goal_can_throw_2(Goal, _GoalInfo, Result, !ModuleInfo) :-
     (
         Goal = conj(_, Goals)
     ;
@@ -211,11 +209,11 @@
         Goal = if_then_else(_, IfGoal, ThenGoal, ElseGoal),
         Goals = [IfGoal, ThenGoal, ElseGoal]
     ),
-    goals_can_throw(Goals, Result, !ModuleInfo, !IO).
-goal_can_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
+    goals_can_throw(Goals, Result, !ModuleInfo).
+goal_can_throw_2(Goal, _GoalInfo, Result, !ModuleInfo) :-
     Goal = plain_call(PredId, ProcId, _, _, _, _),
     lookup_exception_analysis_result(proc(PredId, ProcId), Status,
-        !ModuleInfo, !IO),
+        !ModuleInfo),
     (
         Status = will_not_throw,
         Result = cannot_throw
@@ -225,14 +223,14 @@
         ),
         Result = can_throw
     ).
-goal_can_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
+goal_can_throw_2(Goal, _GoalInfo, Result, !ModuleInfo) :-
     % XXX We should use results form closure analysis here.
     Goal = generic_call(_, _, _, _),
     Result = can_throw.
-goal_can_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
+goal_can_throw_2(Goal, _GoalInfo, Result, !ModuleInfo) :-
     Goal = switch(_, _, Cases),
-    cases_can_throw(Cases, Result, !ModuleInfo, !IO).
-goal_can_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
+    cases_can_throw(Cases, Result, !ModuleInfo).
+goal_can_throw_2(Goal, _GoalInfo, Result, !ModuleInfo) :-
     Goal = unify(_, _, _, Uni, _),
     % Complicated unifies are _non_builtin_
     (
@@ -246,14 +244,14 @@
         ),
         Result = cannot_throw
     ).
-goal_can_throw_2(OuterGoal, _, Result, !ModuleInfo, !IO) :-
+goal_can_throw_2(OuterGoal, _, Result, !ModuleInfo) :-
     (
         OuterGoal = negation(InnerGoal)
     ;
         OuterGoal = scope(_, InnerGoal)
     ),
-    goal_can_throw(InnerGoal, Result, !ModuleInfo, !IO).
-goal_can_throw_2(Goal, _, Result, !ModuleInfo, !IO) :-
+    goal_can_throw(InnerGoal, Result, !ModuleInfo).
+goal_can_throw_2(Goal, _, Result, !ModuleInfo) :-
     Goal = call_foreign_proc(Attributes, _, _, _, _, _, _),
     ExceptionStatus = get_may_throw_exception(Attributes),
     (
@@ -268,43 +266,43 @@
     ;
         Result = can_throw
     ).
-goal_can_throw_2(Goal, _, can_throw, !ModuleInfo, !IO) :-
+goal_can_throw_2(Goal, _, can_throw, !ModuleInfo) :-
     Goal = shorthand(_).    % XXX maybe call unexpected/2 here.
 
 :- pred goals_can_throw(hlds_goals::in, goal_throw_status::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-goals_can_throw([], cannot_throw, !ModuleInfo, !IO).
-goals_can_throw([Goal | Goals], Result, !ModuleInfo, !IO) :-
-    goal_can_throw(Goal, Result0, !ModuleInfo, !IO),
+goals_can_throw([], cannot_throw, !ModuleInfo).
+goals_can_throw([Goal | Goals], Result, !ModuleInfo) :-
+    goal_can_throw(Goal, Result0, !ModuleInfo),
     (
         Result0 = cannot_throw,
-        goals_can_throw(Goals, Result, !ModuleInfo, !IO)
+        goals_can_throw(Goals, Result, !ModuleInfo)
     ;
         Result0 = can_throw,
         Result  = can_throw
     ).
 
 :- pred cases_can_throw(list(case)::in, goal_throw_status::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-cases_can_throw([], cannot_throw, !ModuleInfo, !IO).
-cases_can_throw([Case | Cases], Result, !ModuleInfo, !IO) :-
+cases_can_throw([], cannot_throw, !ModuleInfo).
+cases_can_throw([Case | Cases], Result, !ModuleInfo) :-
     Case = case(_, _, Goal),
-    goal_can_throw(Goal, Result0, !ModuleInfo, !IO),
+    goal_can_throw(Goal, Result0, !ModuleInfo),
     (
         Result0 = cannot_throw,
-        cases_can_throw(Cases, Result, !ModuleInfo, !IO)
+        cases_can_throw(Cases, Result, !ModuleInfo)
     ;
         Result0 = can_throw,
         Result  = can_throw
     ).
 
-goal_can_loop_or_throw(Goal, Result, !ModuleInfo, !IO) :-
+goal_can_loop_or_throw(Goal, Result, !ModuleInfo) :-
     % XXX This will need to change after the termination analyses are converted
     % to use the intermodule-analysis framework.
     ( goal_cannot_loop(!.ModuleInfo, Goal) ->
-        goal_can_throw(Goal, ThrowResult, !ModuleInfo, !IO),
+        goal_can_throw(Goal, ThrowResult, !ModuleInfo),
         (
             ThrowResult = can_throw,
             Result = can_loop_or_throw
Index: compiler/goal_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.155
diff -u -r1.155 goal_util.m
--- compiler/goal_util.m	29 Jan 2008 00:58:42 -0000	1.155
+++ compiler/goal_util.m	20 Feb 2008 23:48:12 -0000
@@ -30,7 +30,6 @@
 
 :- import_module assoc_list.
 :- import_module bool.
-:- import_module io.
 :- import_module list.
 :- import_module maybe.
 :- import_module set.
@@ -252,7 +251,7 @@
     instmap::in, hlds_goal::in, instmap::in, hlds_goal::in) is semidet.
 
     % can_reorder_goals(VarTypes, FullyStrict, InstmapBeforeGoal1, Goal1,
-    %   InstmapBeforeGoal2, Goal2, Result, !ModuleInfo, !IO).
+    %   InstmapBeforeGoal2, Goal2, Result, !ModuleInfo).
     %
     % Result is `yes' if the goals can be reordered; no otherwise.
     %
@@ -267,7 +266,7 @@
     %
 :- pred can_reorder_goals(vartypes::in, bool::in, instmap::in,
     hlds_goal::in, instmap::in, hlds_goal::in, bool::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
     % reordering_maintains_termination_old(ModuleInfo, FullyStrict,
     %   Goal1, Goal2).
@@ -295,8 +294,7 @@
     %       intermodule-analysis framework.
     %
 :- pred reordering_maintains_termination(bool::in, hlds_goal::in,
-    hlds_goal::in, bool::out, module_info::in, module_info::out,
-    io::di, io::uo) is det.
+    hlds_goal::in, bool::out, module_info::in, module_info::out) is det.
 
     % generate_simple_call(ModuleName, ProcName, PredOrFunc, ModeNo, Detism,
     %   Purity, Args, Features, InstMapDelta, ModuleInfo, Context, CallGoal):
@@ -1313,7 +1311,7 @@
 
 can_reorder_goals(VarTypes, FullyStrict, InstmapBeforeEarlierGoal,
         EarlierGoal, InstmapBeforeLaterGoal, LaterGoal, CanReorder,
-        !ModuleInfo, !IO) :-
+        !ModuleInfo) :-
     % The logic here is mostly duplicated in can_reorder_goals_old above
     % and in pd_can_reorder_goals in pd_util.m.
 
@@ -1333,7 +1331,7 @@
         CanReorder = no
     ;
         reordering_maintains_termination(FullyStrict,
-            EarlierGoal, LaterGoal, MaintainsTermination, !ModuleInfo, !IO),
+            EarlierGoal, LaterGoal, MaintainsTermination, !ModuleInfo),
         (
             MaintainsTermination = no,
             CanReorder = no
@@ -1394,7 +1392,7 @@
     ).
 
 reordering_maintains_termination(FullyStrict, EarlierGoal, LaterGoal,
-        MaintainsTermination, !ModuleInfo, !IO) :-
+        MaintainsTermination, !ModuleInfo) :-
     EarlierGoal = hlds_goal(_, EarlierGoalInfo),
     LaterGoal = hlds_goal(_, LaterGoalInfo),
 
@@ -1405,8 +1403,7 @@
 
     % If --fully-strict was specified, don't convert (can_loop, can_fail) into
     % (can_fail, can_loop).
-    goal_can_loop_or_throw(EarlierGoal, EarlierCanLoopOrThrow, !ModuleInfo,
-        !IO),
+    goal_can_loop_or_throw(EarlierGoal, EarlierCanLoopOrThrow, !ModuleInfo),
     (
         FullyStrict = yes,
         EarlierCanLoopOrThrow = can_loop_or_throw,
@@ -1418,7 +1415,7 @@
         % this could worsen the termination properties of the program.
         %
         goal_can_loop_or_throw(LaterGoal, LaterCanLoopOrThrow,
-            !ModuleInfo, !IO),
+            !ModuleInfo),
         (
             EarlierCanFail = can_fail,
             LaterCanLoopOrThrow = can_loop_or_throw
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.462
diff -u -r1.462 mercury_compile.m
--- compiler/mercury_compile.m	18 Feb 2008 23:57:45 -0000	1.462
+++ compiler/mercury_compile.m	20 Feb 2008 23:48:13 -0000
@@ -1552,14 +1552,16 @@
             output_trans_opt_file(HLDS21, !DumpInfo, !IO),
             FactTableObjFiles = []
         ; MakeAnalysisRegistry = yes ->
-            output_analysis_file(ModuleName, HLDS21, !DumpInfo, !IO),
+            prepare_intermodule_analysis(HLDS21, HLDS22, !IO),
+            output_analysis_file(ModuleName, HLDS22, !DumpInfo, !IO),
             FactTableObjFiles = []
         ; MakeXmlDocumentation = yes ->
             xml_documentation(HLDS21, !IO),
             FactTableObjFiles = []
         ;
+            maybe_prepare_intermodule_analysis(HLDS21, HLDS22, !IO),
             mercury_compile_after_front_end(NestedSubModules,
-                FindTimestampFiles, MaybeTimestamps, ModuleName, HLDS21,
+                FindTimestampFiles, MaybeTimestamps, ModuleName, HLDS22,
                 FactTableObjFiles, !DumpInfo, !IO)
         )
     ;
@@ -1574,6 +1576,36 @@
         FactTableObjFiles = []
     ).
 
+:- pred maybe_prepare_intermodule_analysis(module_info::in, module_info::out,
+    io::di, io::uo) is det.
+
+maybe_prepare_intermodule_analysis(!HLDS, !IO) :-
+    globals.io_lookup_bool_option(intermodule_analysis, IntermodAnalysis, !IO),
+    (
+        IntermodAnalysis = yes,
+        prepare_intermodule_analysis(!HLDS, !IO)
+    ;
+        IntermodAnalysis = no
+    ).
+
+:- pred prepare_intermodule_analysis(module_info::in, module_info::out,
+    io::di, io::uo) is det.
+
+prepare_intermodule_analysis(!HLDS, !IO) :-
+    module_info_get_name(!.HLDS, ThisModuleName),
+    module_info_get_all_deps(!.HLDS, ModuleNamesSet0),
+    set.insert(ModuleNamesSet0, ThisModuleName, ModuleNamesSet),
+    ModuleIds = set.map(module_name_to_module_id, ModuleNamesSet),
+
+    globals.io_lookup_accumulating_option(local_module_id, LocalModulesList,
+        !IO),
+    LocalModuleIds = set.from_list(LocalModulesList),
+
+    module_info_get_analysis_info(!.HLDS, AnalysisInfo0),
+    analysis.prepare_intermodule_analysis(ModuleIds, LocalModuleIds,
+        AnalysisInfo0, AnalysisInfo, !IO),
+    module_info_set_analysis_info(AnalysisInfo, !HLDS).
+
 :- pred mercury_compile_after_front_end(list(module_name)::in,
     find_timestamp_file_names::in(find_timestamp_file_names),
     maybe(module_timestamps)::in, module_name::in, module_info::in,
Index: compiler/mmc_analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mmc_analysis.m,v
retrieving revision 1.21
diff -u -r1.21 mmc_analysis.m
--- compiler/mmc_analysis.m	1 Dec 2006 15:04:11 -0000	1.21
+++ compiler/mmc_analysis.m	20 Feb 2008 23:48:13 -0000
@@ -90,10 +90,7 @@
         mmc_module_id_to_read_file_name(ModuleId, Ext, FileName, !IO),
 
     module_id_to_write_file_name(mmc, ModuleId, Ext, FileName, !IO) :-
-        mmc_module_id_to_write_file_name(ModuleId, Ext, FileName, !IO),
-
-    module_is_local(mmc, ModuleId, IsLocal, !IO) :-
-        mmc_module_is_local(ModuleId, IsLocal, !IO)
+        mmc_module_id_to_write_file_name(ModuleId, Ext, FileName, !IO)
 ].
 
 :- pred mmc_module_id_to_read_file_name(module_id::in, string::in,
@@ -119,13 +116,6 @@
     ModuleName = module_id_to_module_name(ModuleId),
     module_name_to_file_name(ModuleName, Ext, yes, FileName, !IO).
 
-:- pred mmc_module_is_local(module_id::in, bool::out, io::di, io::uo) is det.
-
-mmc_module_is_local(ModuleId, IsLocal, !IO) :-
-    globals.io_lookup_accumulating_option(local_module_id, LocalModuleIds,
-        !IO),
-    IsLocal = (if ModuleId `list.member` LocalModuleIds then yes else no).
-
 module_name_to_module_id(ModuleName) = sym_name_to_string(ModuleName).
 
 module_id_to_module_name(ModuleId) = string_to_sym_name(ModuleId).
Index: compiler/pd_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/pd_util.m,v
retrieving revision 1.67
diff -u -r1.67 pd_util.m
--- compiler/pd_util.m	22 Jan 2008 15:06:14 -0000	1.67
+++ compiler/pd_util.m	20 Feb 2008 23:48:13 -0000
@@ -46,7 +46,7 @@
     % Apply simplify.m to the goal.
     %
 :- pred pd_simplify_goal(simplifications::in, hlds_goal::in,
-    hlds_goal::out, pd_info::in, pd_info::out, io::di, io::uo) is det.
+    hlds_goal::out, pd_info::in, pd_info::out) is det.
 
     % Apply unique_modes.m to the goal.
     %
@@ -208,7 +208,7 @@
         constraint_info_init(ModuleInfo0, VarTypes0, VarSet0, InstMap, CInfo0),
         Goal0 = hlds_goal(_, GoalInfo0),
         NonLocals = goal_info_get_nonlocals(GoalInfo0),
-        constraint.propagate_constraints_in_goal(!Goal, CInfo0, CInfo, !IO),
+        constraint.propagate_constraints_in_goal(!Goal, CInfo0, CInfo),
         constraint_info_deconstruct(CInfo, ModuleInfo, VarTypes, VarSet,
             Changed),
         pd_info_set_module_info(ModuleInfo, !PDInfo),
@@ -224,7 +224,7 @@
             rerun_det_analysis(!Goal, !PDInfo, !IO),
             module_info_get_globals(ModuleInfo, Globals),
             simplify.find_simplifications(no, Globals, Simplifications),
-            pd_simplify_goal(Simplifications, !Goal, !PDInfo, !IO)
+            pd_simplify_goal(Simplifications, !Goal, !PDInfo)
         ;
             % Use Goal0 rather than the output of propagate_constraints_in_goal
             % because constraint propagation can make the quantification
@@ -239,7 +239,7 @@
 
 %-----------------------------------------------------------------------------%
 
-pd_simplify_goal(Simplifications, Goal0, Goal, !PDInfo, !IO) :-
+pd_simplify_goal(Simplifications, Goal0, Goal, !PDInfo) :-
     % Construct a simplify_info.
     pd_info_get_module_info(!.PDInfo, ModuleInfo0),
     pd_info_get_pred_proc_id(!.PDInfo, proc(PredId, ProcId)),
@@ -251,8 +251,8 @@
     simplify_info_init(DetInfo0, Simplifications, InstMap0, ProcInfo0,
         SimplifyInfo0),
 
-    simplify_process_clause_body_goal(Goal0, Goal, SimplifyInfo0, SimplifyInfo,
-        !IO),
+    simplify_process_clause_body_goal(Goal0, Goal,
+        SimplifyInfo0, SimplifyInfo),
 
     % Deconstruct the simplify_info.
     simplify_info_get_module_info(SimplifyInfo, ModuleInfo),
Index: compiler/simplify.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.226
diff -u -r1.226 simplify.m
--- compiler/simplify.m	11 Feb 2008 21:26:08 -0000	1.226
+++ compiler/simplify.m	20 Feb 2008 23:48:13 -0000
@@ -59,11 +59,10 @@
 
 :- pred simplify_proc_return_msgs(simplifications::in, pred_id::in,
     proc_id::in, module_info::in, module_info::out,
-    proc_info::in, proc_info::out, list(error_spec)::out,
-    io::di, io::uo) is det.
+    proc_info::in, proc_info::out, list(error_spec)::out) is det.
 
 :- pred simplify_process_clause_body_goal(hlds_goal::in, hlds_goal::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
     % simplify_may_introduce_calls(ModuleName, PredName, Arity):
     %
@@ -313,7 +312,7 @@
     ),
     ErrorSpecs0 = init_error_spec_accumulator,
     simplify_procs(Simplifications, PredId, ProcIds, !ModuleInfo, !PredInfo,
-        ErrorSpecs0, ErrorSpecs, !IO),
+        ErrorSpecs0, ErrorSpecs),
     module_info_get_globals(!.ModuleInfo, Globals),
     SpecsList = error_spec_accumulator_to_list(ErrorSpecs),
     !:Specs = SpecsList ++ !.Specs,
@@ -323,16 +322,15 @@
 :- pred simplify_procs(simplifications::in, pred_id::in,
     list(proc_id)::in, module_info::in, module_info::out,
     pred_info::in, pred_info::out,
-    error_spec_accumulator::in, error_spec_accumulator::out,
-    io::di, io::uo) is det.
+    error_spec_accumulator::in, error_spec_accumulator::out) is det.
 
-simplify_procs(_, _, [], !ModuleInfo, !PredInfo, !ErrorSpecs, !IO).
+simplify_procs(_, _, [], !ModuleInfo, !PredInfo, !ErrorSpecs).
 simplify_procs(Simplifications, PredId, [ProcId | ProcIds], !ModuleInfo,
-        !PredInfo, !ErrorSpecs, !IO) :-
+        !PredInfo, !ErrorSpecs) :-
     pred_info_get_procedures(!.PredInfo, ProcTable0),
     map.lookup(ProcTable0, ProcId, ProcInfo0),
     simplify_proc_return_msgs(Simplifications, PredId, ProcId,
-        !ModuleInfo, ProcInfo0, ProcInfo, ProcSpecs, !IO),
+        !ModuleInfo, ProcInfo0, ProcInfo, ProcSpecs),
     % This is ugly, but we want to avoid running the dependent parallel
     % conjunction pass on predicates and even modules that do not contain
     % parallel conjunctions (nearly all of them).  Since simplification
@@ -356,19 +354,19 @@
     pred_info_set_procedures(ProcTable, !PredInfo),
     accumulate_error_specs_for_proc(ProcSpecs, !ErrorSpecs),
     simplify_procs(Simplifications, PredId, ProcIds, !ModuleInfo, !PredInfo,
-        !ErrorSpecs, !IO).
+        !ErrorSpecs).
 
 simplify_proc(Simplifications, PredId, ProcId, !ModuleInfo, !ProcInfo, !IO)  :-
     write_pred_progress_message("% Simplifying ", PredId, !.ModuleInfo, !IO),
     simplify_proc_return_msgs(Simplifications, PredId, ProcId, !ModuleInfo,
-        !ProcInfo, _, !IO).
+        !ProcInfo, _).
 
 :- func turn_off_common_struct_threshold = int.
 
 turn_off_common_struct_threshold = 1000.
 
 simplify_proc_return_msgs(Simplifications0, PredId, ProcId, !ModuleInfo,
-        !ProcInfo, !:ErrorSpecs, !IO) :-
+        !ProcInfo, !:ErrorSpecs) :-
     proc_info_get_vartypes(!.ProcInfo, VarTypes0),
     NumVars = map.count(VarTypes0),
     ( NumVars > turn_off_common_struct_threshold ->
@@ -402,7 +400,7 @@
         Goal1 = Goal0
     ),
 
-    simplify_process_clause_body_goal(Goal1, Goal, Info0, Info, !IO),
+    simplify_process_clause_body_goal(Goal1, Goal, Info0, Info),
 
     simplify_info_get_varset(Info, VarSet1),
     ( simplify_do_after_front_end(Info) ->
@@ -500,7 +498,7 @@
         IsDefinedHere = yes
     ).
 
-simplify_process_clause_body_goal(Goal0, Goal, !Info, !IO) :-
+simplify_process_clause_body_goal(Goal0, Goal, !Info) :-
     simplify_info_get_simplifications(!.Info, Simplifications0),
     simplify_info_get_instmap(!.Info, InstMap0),
     (
@@ -513,7 +511,7 @@
             ^ do_excess_assign := no),
         simplify_info_set_simplifications(Simplifications1, !Info),
 
-        do_process_clause_body_goal(Goal0, Goal1, !Info, !IO),
+        do_process_clause_body_goal(Goal0, Goal1, !Info),
 
         Simplifications2 = ((((Simplifications0
             ^ do_warn_simple_code := no)
@@ -526,7 +524,7 @@
     ),
     % On the second pass do excess assignment elimination and some cleaning up
     % after the common structure pass.
-    do_process_clause_body_goal(Goal1, Goal2, !Info, !IO),
+    do_process_clause_body_goal(Goal1, Goal2, !Info),
     simplify_info_get_found_contains_trace(!.Info, FoundContainsTrace),
     (
         FoundContainsTrace = no,
@@ -537,11 +535,11 @@
     ).
 
 :- pred do_process_clause_body_goal(hlds_goal::in, hlds_goal::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-do_process_clause_body_goal(Goal0, Goal, !Info, !IO) :-
+do_process_clause_body_goal(Goal0, Goal, !Info) :-
     simplify_info_get_instmap(!.Info, InstMap0),
-    simplify_goal(Goal0, Goal1, !Info, !IO),
+    simplify_goal(Goal0, Goal1, !Info),
     simplify_info_get_varset(!.Info, VarSet0),
     simplify_info_get_var_types(!.Info, VarTypes0),
     simplify_info_get_rtti_varmaps(!.Info, RttiVarMaps0),
@@ -603,9 +601,9 @@
 %-----------------------------------------------------------------------------%
 
 :- pred simplify_goal(hlds_goal::in, hlds_goal::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_goal(Goal0, hlds_goal(GoalExpr, GoalInfo), !Info, !IO) :-
+simplify_goal(Goal0, hlds_goal(GoalExpr, GoalInfo), !Info) :-
     Goal0 = hlds_goal(_, GoalInfo0),
     simplify_info_get_inside_duplicated_for_switch(!.Info,
         InsideDuplForSwitch),
@@ -622,8 +620,8 @@
     Detism = goal_info_get_determinism(GoalInfo0),
     simplify_info_get_det_info(!.Info, DetInfo),
     simplify_info_get_module_info(!.Info, ModuleInfo0),
-    goal_can_loop_or_throw(Goal0, Goal0CanLoopOrThrow, ModuleInfo0, ModuleInfo,
-         !IO),
+    goal_can_loop_or_throw(Goal0, Goal0CanLoopOrThrow,
+        ModuleInfo0, ModuleInfo),
     simplify_info_set_module_info(ModuleInfo, !Info),
     Purity = goal_info_get_purity(GoalInfo0),
     (
@@ -767,7 +765,7 @@
     ),
     simplify_info_maybe_clear_structs(before, Goal3, !Info),
     Goal3 = hlds_goal(GoalExpr3, GoalInfo3),
-    simplify_goal_2(GoalExpr3, GoalExpr, GoalInfo3, GoalInfo4, !Info, !IO),
+    simplify_goal_2(GoalExpr3, GoalExpr, GoalInfo3, GoalInfo4, !Info),
     simplify_info_maybe_clear_structs(after, hlds_goal(GoalExpr, GoalInfo4),
         !Info),
     simplify_info_set_inside_duplicated_for_switch(InsideDuplForSwitch, !Info),
@@ -831,47 +829,45 @@
 
 :- pred simplify_goal_2(hlds_goal_expr::in, hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_goal_2(!GoalExpr, !GoalInfo, !Info, !IO) :-
+simplify_goal_2(!GoalExpr, !GoalInfo, !Info) :-
     (
         !.GoalExpr = conj(ConjType, Goals),
         (
             ConjType = plain_conj,
-            simplify_goal_2_plain_conj(Goals, !:GoalExpr, !GoalInfo, !Info,
-                !IO)
+            simplify_goal_2_plain_conj(Goals, !:GoalExpr, !GoalInfo, !Info)
         ;
             ConjType = parallel_conj,
-            simplify_goal_2_parallel_conj(Goals, !:GoalExpr, !GoalInfo, !Info,
-                !IO)
+            simplify_goal_2_parallel_conj(Goals, !:GoalExpr, !GoalInfo, !Info)
         )
     ;
         !.GoalExpr = disj(_),
-        simplify_goal_2_disj(!GoalExpr, !GoalInfo, !Info, !IO)
+        simplify_goal_2_disj(!GoalExpr, !GoalInfo, !Info)
     ;
         !.GoalExpr = switch(_, _, _),
-        simplify_goal_2_switch(!GoalExpr, !GoalInfo, !Info, !IO)
+        simplify_goal_2_switch(!GoalExpr, !GoalInfo, !Info)
     ;
         !.GoalExpr = generic_call(_, _, _, _),
-        simplify_goal_2_generic_call(!GoalExpr, !GoalInfo, !Info, !IO)
+        simplify_goal_2_generic_call(!GoalExpr, !GoalInfo, !Info)
     ;
         !.GoalExpr = plain_call(_, _, _, _, _, _),
-        simplify_goal_2_plain_call(!GoalExpr, !GoalInfo, !Info, !IO)
+        simplify_goal_2_plain_call(!GoalExpr, !GoalInfo, !Info)
     ;
         !.GoalExpr = unify(_, _, _, _, _),
-        simplify_goal_2_unify(!GoalExpr, !GoalInfo, !Info, !IO)
+        simplify_goal_2_unify(!GoalExpr, !GoalInfo, !Info)
     ;
         !.GoalExpr = if_then_else(_, _, _, _),
-        simplify_goal_2_ite(!GoalExpr, !GoalInfo, !Info, !IO)
+        simplify_goal_2_ite(!GoalExpr, !GoalInfo, !Info)
     ;
         !.GoalExpr = negation(_),
-        simplify_goal_2_neg(!GoalExpr, !GoalInfo, !Info, !IO)
+        simplify_goal_2_neg(!GoalExpr, !GoalInfo, !Info)
     ;
         !.GoalExpr = scope(_, _),
-        simplify_goal_2_scope(!GoalExpr, !GoalInfo, !Info, !IO)
+        simplify_goal_2_scope(!GoalExpr, !GoalInfo, !Info)
     ;
         !.GoalExpr = call_foreign_proc(_, _, _, _, _, _, _),
-        simplify_goal_2_foreign_proc(!GoalExpr, !GoalInfo, !Info, !IO)
+        simplify_goal_2_foreign_proc(!GoalExpr, !GoalInfo, !Info)
     ;
         !.GoalExpr = shorthand(_),
         % These should have been expanded out by now.
@@ -880,13 +876,12 @@
 
 :- pred simplify_goal_2_plain_conj(list(hlds_goal)::in, hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_goal_2_plain_conj(Goals0, GoalExpr, GoalInfo0, GoalInfo,
-        !Info, !IO) :-
+simplify_goal_2_plain_conj(Goals0, GoalExpr, GoalInfo0, GoalInfo, !Info) :-
     simplify_info_get_instmap(!.Info, InstMap0),
     excess_assigns_in_conj(GoalInfo0, Goals0, Goals1, !Info),
-    simplify_conj(Goals1, [], Goals, GoalInfo0, !Info, !IO),
+    simplify_conj(Goals1, [], Goals, GoalInfo0, !Info),
     simplify_info_set_instmap(InstMap0, !Info),
     (
         Goals = [],
@@ -922,10 +917,9 @@
 
 :- pred simplify_goal_2_parallel_conj(list(hlds_goal)::in, hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_goal_2_parallel_conj(Goals0, GoalExpr, GoalInfo0, GoalInfo,
-        !Info, !IO) :-
+simplify_goal_2_parallel_conj(Goals0, GoalExpr, GoalInfo0, GoalInfo, !Info) :-
     (
         Goals0 = [],
         Context = goal_info_get_context(GoalInfo0),
@@ -933,13 +927,13 @@
     ;
         Goals0 = [SingleGoal0],
         simplify_goal(SingleGoal0, hlds_goal(SingleGoal, SingleGoalInfo),
-            !Info, !IO),
+            !Info),
         maybe_wrap_goal(GoalInfo0, SingleGoalInfo, SingleGoal, GoalExpr,
             GoalInfo, !Info)
     ;
         Goals0 = [_, _ | _],
         GoalInfo = GoalInfo0,
-        simplify_par_conj(Goals0, Goals, !.Info, !Info, !IO),
+        simplify_par_conj(Goals0, Goals, !.Info, !Info),
         GoalExpr = conj(parallel_conj, Goals),
         simplify_info_set_has_parallel_conj(yes, !Info)
     ).
@@ -947,12 +941,12 @@
 :- pred simplify_goal_2_disj(
     hlds_goal_expr::in(goal_expr_disj), hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_goal_2_disj(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info, !IO) :-
+simplify_goal_2_disj(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info) :-
     GoalExpr0 = disj(Disjuncts0),
     simplify_info_get_instmap(!.Info, InstMap0),
-    simplify_disj(Disjuncts0, [], Disjuncts, [], InstMaps, !.Info, !Info, !IO),
+    simplify_disj(Disjuncts0, [], Disjuncts, [], InstMaps, !.Info, !Info),
     (
         Disjuncts = [],
         Context = goal_info_get_context(GoalInfo0),
@@ -999,9 +993,9 @@
 :- pred simplify_goal_2_switch(
     hlds_goal_expr::in(goal_expr_switch), hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_goal_2_switch(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info, !IO) :-
+simplify_goal_2_switch(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info) :-
     GoalExpr0 = switch(Var, SwitchCanFail0, Cases0),
     simplify_info_get_instmap(!.Info, InstMap0),
     simplify_info_get_module_info(!.Info, ModuleInfo0),
@@ -1016,7 +1010,7 @@
         MaybeConsIds = no
     ),
     simplify_switch(Var, Cases1, [], Cases, [], InstMaps,
-        SwitchCanFail0, SwitchCanFail, !.Info, !Info, !IO),
+        SwitchCanFail0, SwitchCanFail, !.Info, !Info),
     (
         Cases = [],
         % An empty switch always fails.
@@ -1119,10 +1113,9 @@
 :- pred simplify_goal_2_generic_call(
     hlds_goal_expr::in(goal_expr_generic_call), hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_goal_2_generic_call(GoalExpr0, GoalExpr, GoalInfo, GoalInfo,
-        !Info, !IO) :-
+simplify_goal_2_generic_call(GoalExpr0, GoalExpr, GoalInfo, GoalInfo, !Info) :-
     GoalExpr0 = generic_call(GenericCall, Args, Modes, Det),
     (
         GenericCall = higher_order(Closure, Purity, _, _),
@@ -1162,10 +1155,9 @@
 :- pred simplify_goal_2_plain_call(
     hlds_goal_expr::in(goal_expr_plain_call), hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_goal_2_plain_call(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo,
-        !Info, !IO) :-
+simplify_goal_2_plain_call(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info) :-
     GoalExpr0 = plain_call(PredId, ProcId, Args, IsBuiltin, _, _),
     simplify_info_get_module_info(!.Info, ModuleInfo),
     module_info_pred_info(ModuleInfo, PredId, PredInfo),
@@ -1199,9 +1191,9 @@
 :- pred simplify_goal_2_unify(
     hlds_goal_expr::in(goal_expr_unify), hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_goal_2_unify(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info, !IO) :-
+simplify_goal_2_unify(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info) :-
     GoalExpr0 = unify(LT0, RT0, M, U0, C),
     (
         RT0 = rhs_lambda_goal(Purity, Groundness, PredOrFunc, EvalMethod,
@@ -1219,7 +1211,7 @@
         simplify_info_set_common_info(common_info_init, !Info),
 
         % Don't attempt to pass structs out of lambda_goals.
-        simplify_goal(LambdaGoal0, LambdaGoal, !Info, !IO),
+        simplify_goal(LambdaGoal0, LambdaGoal, !Info),
         simplify_info_set_common_info(Common1, !Info),
         simplify_info_set_instmap(InstMap1, !Info),
         RT = rhs_lambda_goal(Purity, Groundness, PredOrFunc, EvalMethod,
@@ -1243,7 +1235,7 @@
             (
                 RT0 = rhs_var(V),
                 process_compl_unify(LT0, V, UniMode, CanFail, TypeInfoVars, C,
-                    GoalInfo0, GoalExpr1, !Info, !IO),
+                    GoalInfo0, GoalExpr1, !Info),
                 GoalExpr1 = hlds_goal(GoalExpr, GoalInfo)
             ;
                 RT0 = rhs_functor(_, _, _),
@@ -1276,9 +1268,9 @@
 :- pred simplify_goal_2_ite(
     hlds_goal_expr::in(goal_expr_ite), hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_goal_2_ite(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info, !IO) :-
+simplify_goal_2_ite(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info) :-
     % (A -> B ; C) is logically equivalent to (A, B ; ~A, C).
     % If the determinism of A means that one of these disjuncts
     % cannot succeed, then we replace the if-then-else with the
@@ -1314,7 +1306,7 @@
         goal_to_conj_list(Then0, ThenList),
         list.append(CondList, ThenList, List),
         simplify_goal(hlds_goal(conj(plain_conj, List), GoalInfo0),
-            hlds_goal(GoalExpr, GoalInfo), !Info, !IO),
+            hlds_goal(GoalExpr, GoalInfo), !Info),
         simplify_info_get_inside_duplicated_for_switch(!.Info,
             InsideDuplForSwitch),
         (
@@ -1378,7 +1370,7 @@
             goal_to_conj_list(Else0, ElseList),
             List = [Cond | ElseList],
             simplify_goal(hlds_goal(conj(plain_conj, List), GoalInfo0),
-                hlds_goal(GoalExpr, GoalInfo), !Info, !IO),
+                hlds_goal(GoalExpr, GoalInfo), !Info),
             simplify_info_get_inside_duplicated_for_switch(!.Info,
                 InsideDuplForSwitch),
             (
@@ -1408,24 +1400,24 @@
             ; CondSolns0 = at_most_many_cc
             ),
             simplify_goal_2_ordinary_ite(Vars, Cond0, Then0, Else0, GoalExpr,
-                GoalInfo0, GoalInfo, !Info, !IO)
+                GoalInfo0, GoalInfo, !Info)
         )
     ).
 
 :- pred simplify_goal_2_ordinary_ite(list(prog_var)::in,
     hlds_goal::in, hlds_goal::in, hlds_goal::in, hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
 simplify_goal_2_ordinary_ite(Vars, Cond0, Then0, Else0, GoalExpr,
-        GoalInfo0, GoalInfo, !Info, !IO) :-
+        GoalInfo0, GoalInfo, !Info) :-
     ( Else0 = hlds_goal(disj([]), _) ->
         % (A -> C ; fail) is equivalent to (A, C)
         goal_to_conj_list(Cond0, CondList),
         goal_to_conj_list(Then0, ThenList),
         list.append(CondList, ThenList, List),
         simplify_goal(hlds_goal(conj(plain_conj, List), GoalInfo0),
-            hlds_goal(GoalExpr, GoalInfo), !Info, !IO),
+            hlds_goal(GoalExpr, GoalInfo), !Info),
         simplify_info_set_requantify(!Info),
         simplify_info_set_rerun_det(!Info)
     ;
@@ -1434,11 +1426,11 @@
 
         Info0 = !.Info,
         simplify_info_get_instmap(!.Info, InstMap0),
-        simplify_goal(Cond0, Cond, !Info, !IO),
+        simplify_goal(Cond0, Cond, !Info),
         simplify_info_update_instmap(Cond, !Info),
-        simplify_goal(Then0, Then, !Info, !IO),
+        simplify_goal(Then0, Then, !Info),
         simplify_info_post_branch_update(Info0, !Info),
-        simplify_goal(Else0, Else, !Info, !IO),
+        simplify_goal(Else0, Else, !Info),
         simplify_info_post_branch_update(Info0, !Info),
         Cond = hlds_goal(_, CondInfo),
         CondDelta = goal_info_get_instmap_delta(CondInfo),
@@ -1477,7 +1469,7 @@
         ->
             simplify_info_undo_goal_updates(Info0, !Info),
             simplify_goal_2(IfThenElse, GoalExpr, GoalInfo1, GoalInfo,
-                !Info, !IO)
+                !Info)
         ;
             simplify_info_get_module_info(!.Info, ModuleInfo),
             warn_switch_for_ite_cond(ModuleInfo, VarTypes, Cond,
@@ -1672,14 +1664,14 @@
 :- pred simplify_goal_2_neg(
     hlds_goal_expr::in(goal_expr_neg), hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_goal_2_neg(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info, !IO) :-
+simplify_goal_2_neg(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info) :-
     GoalExpr0 = negation(SubGoal0),
     % Can't use calls or unifications seen within a negation,
     % since non-local variables may not be bound within the negation.
     simplify_info_get_common_info(!.Info, Common),
-    simplify_goal(SubGoal0, SubGoal1, !Info, !IO),
+    simplify_goal(SubGoal0, SubGoal1, !Info),
     simplify_info_set_common_info(Common, !Info),
     SubGoal1 = hlds_goal(_, SubGoalInfo1),
     Detism = goal_info_get_determinism(SubGoalInfo1),
@@ -1736,12 +1728,12 @@
 :- pred simplify_goal_2_scope(
     hlds_goal_expr::in(goal_expr_scope), hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_goal_2_scope(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info, !IO) :-
+simplify_goal_2_scope(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info) :-
     GoalExpr0 = scope(Reason0, SubGoal0), 
     simplify_info_get_common_info(!.Info, Common),
-    simplify_goal(SubGoal0, SubGoal, !Info, !IO),
+    simplify_goal(SubGoal0, SubGoal, !Info),
     nested_scopes(Reason0, SubGoal, GoalInfo0, Goal1),
     Goal1 = hlds_goal(GoalExpr1, GoalInfo1),
     ( GoalExpr1 = scope(FinalReason, FinalSubGoal) ->
@@ -1893,9 +1885,9 @@
 :- pred simplify_goal_2_foreign_proc(
     hlds_goal_expr::in(goal_expr_foreign_proc), hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_goal_2_foreign_proc(GoalExpr0, GoalExpr, !GoalInfo, !Info, !IO) :-
+simplify_goal_2_foreign_proc(GoalExpr0, GoalExpr, !GoalInfo, !Info) :-
     GoalExpr0 = call_foreign_proc(Attributes, PredId, ProcId,
         Args0, ExtraArgs0, MaybeTraceRuntimeCond, Impl),
     (
@@ -2411,11 +2403,10 @@
 
 :- pred process_compl_unify(prog_var::in, prog_var::in, uni_mode::in,
     can_fail::in, list(prog_var)::in, unify_context::in, hlds_goal_info::in,
-    hlds_goal::out, simplify_info::in, simplify_info::out,
-    io::di, io::uo) is det.
+    hlds_goal::out, simplify_info::in, simplify_info::out) is det.
 
 process_compl_unify(XVar, YVar, UniMode, CanFail, _OldTypeInfoVars, Context,
-        GoalInfo0, Goal, !Info, !IO) :-
+        GoalInfo0, Goal, !Info) :-
     simplify_info_get_module_info(!.Info, ModuleInfo),
     simplify_info_get_var_types(!.Info, VarTypes),
     map.lookup(VarTypes, XVar, Type),
@@ -2438,7 +2429,7 @@
             "builtin_unify_pred", pf_predicate, mode_no(0), detism_semi,
             purity_pure, [XVar, YVar], [], [], ModuleInfo, GContext,
             hlds_goal(Call0, _)),
-        simplify_goal_2(Call0, Call1, GoalInfo0, GoalInfo, !Info, !IO),
+        simplify_goal_2(Call0, Call1, GoalInfo0, GoalInfo, !Info),
         Call = hlds_goal(Call1, GoalInfo),
         ExtraGoals = []
     ;
@@ -2498,8 +2489,7 @@
             make_type_info_vars(TypeArgs, TypeInfoVars, ExtraGoals, !Info),
             call_specific_unify(TypeCtor, TypeInfoVars, XVar, YVar, ProcId,
                 ModuleInfo, Context, GoalInfo0, Call0, CallGoalInfo0),
-            simplify_goal_2(Call0, Call1, CallGoalInfo0, CallGoalInfo1, !Info,
-                !IO),
+            simplify_goal_2(Call0, Call1, CallGoalInfo0, CallGoalInfo1, !Info),
             Call = hlds_goal(Call1, CallGoalInfo1)
         )
     ),
@@ -2773,25 +2763,25 @@
 
 :- pred simplify_conj(list(hlds_goal)::in, list(hlds_goal)::in,
     list(hlds_goal)::out, hlds_goal_info::in,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_conj([], RevGoals, Goals, _, !Info, !IO) :-
+simplify_conj([], RevGoals, Goals, _, !Info) :-
     list.reverse(RevGoals, Goals).
-simplify_conj([Goal0 | Goals0], !.RevGoals, Goals, ConjInfo, !Info, !IO) :-
+simplify_conj([Goal0 | Goals0], !.RevGoals, Goals, ConjInfo, !Info) :-
     Info0 = !.Info,
     % Flatten conjunctions.
     ( Goal0 = hlds_goal(conj(plain_conj, SubGoals), _) ->
         list.append(SubGoals, Goals0, Goals1),
-        simplify_conj(Goals1, !.RevGoals, Goals, ConjInfo, !Info, !IO)
+        simplify_conj(Goals1, !.RevGoals, Goals, ConjInfo, !Info)
     ;
-        simplify_goal(Goal0, Goal1, !Info, !IO),
+        simplify_goal(Goal0, Goal1, !Info),
         (
             % Flatten conjunctions.
             Goal1 = hlds_goal(conj(plain_conj, SubGoals1), _)
         ->
             simplify_info_undo_goal_updates(Info0, !Info),
             list.append(SubGoals1, Goals0, Goals1),
-            simplify_conj(Goals1, !.RevGoals, Goals, ConjInfo, !Info, !IO)
+            simplify_conj(Goals1, !.RevGoals, Goals, ConjInfo, !Info)
         ;
             % Delete unreachable goals.
             (
@@ -2828,7 +2818,7 @@
         ;
             conjoin_goal_and_rev_goal_list(Goal1, !RevGoals),
             simplify_info_update_instmap(Goal1, !Info),
-            simplify_conj(Goals0, !.RevGoals, Goals, ConjInfo, !Info, !IO)
+            simplify_conj(Goals0, !.RevGoals, Goals, ConjInfo, !Info)
         )
     ).
 
@@ -2846,19 +2836,18 @@
 %-----------------------------------------------------------------------------%
 
 :- pred simplify_par_conj(list(hlds_goal)::in, list(hlds_goal)::out,
-    simplify_info::in, simplify_info::in, simplify_info::out,
-    io::di, io::uo) is det.
+    simplify_info::in, simplify_info::in, simplify_info::out) is det.
 
-simplify_par_conj([], [], _, !Info, !IO).
-simplify_par_conj([Goal0 |Goals0], [Goal | Goals], Info0, !Info, !IO) :-
-    simplify_goal(Goal0, Goal, !Info, !IO),
+simplify_par_conj([], [], _, !Info).
+simplify_par_conj([Goal0 |Goals0], [Goal | Goals], Info0, !Info) :-
+    simplify_goal(Goal0, Goal, !Info),
     simplify_info_update_instmap(Goal, !Info),
     % Reset common_info to what it was at the start of the parallel
     % conjunction, so as not to introduce more dependencies due to
     % removal of duplicate calls, etc.
     simplify_info_get_common_info(Info0, Common),
     simplify_info_set_common_info(Common, !Info),
-    simplify_par_conj(Goals0, Goals, Info0, !Info, !IO).
+    simplify_par_conj(Goals0, Goals, Info0, !Info).
 
 %-----------------------------------------------------------------------------%
 
@@ -2996,12 +2985,12 @@
 :- pred simplify_switch(prog_var::in, list(case)::in, list(case)::in,
     list(case)::out, list(instmap_delta)::in, list(instmap_delta)::out,
     can_fail::in, can_fail::out, simplify_info::in,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-simplify_switch(_, [], RevCases, Cases, !InstMaps, !CanFail, _, !Info, !IO) :-
+simplify_switch(_, [], RevCases, Cases, !InstMaps, !CanFail, _, !Info) :-
     list.reverse(RevCases, Cases).
 simplify_switch(Var, [Case0 | Cases0], RevCases0, Cases, !InstMaps,
-        !CanFail, Info0, !Info, !IO) :-
+        !CanFail, Info0, !Info) :-
     simplify_info_get_instmap(Info0, InstMap0),
     Case0 = case(MainConsId, OtherConsIds, Goal0),
     simplify_info_get_module_info(!.Info, ModuleInfo0),
@@ -3011,7 +3000,7 @@
         InstMap0, InstMap1, ModuleInfo0, ModuleInfo1),
     simplify_info_set_module_info(ModuleInfo1, !Info),
     simplify_info_set_instmap(InstMap1, !Info),
-    simplify_goal(Goal0, Goal, !Info, !IO),
+    simplify_goal(Goal0, Goal, !Info),
 
         % Remove failing branches.
     ( Goal = hlds_goal(disj([]), _) ->
@@ -3039,7 +3028,7 @@
 
     simplify_info_post_branch_update(Info0, !Info),
     simplify_switch(Var, Cases0, RevCases, Cases, !InstMaps, !CanFail, Info0,
-        !Info, !IO).
+        !Info).
 
     % Create a semidet unification at the start of a singleton case
     % in a can_fail switch.
@@ -3093,14 +3082,13 @@
 :- pred simplify_disj(list(hlds_goal)::in, list(hlds_goal)::in,
     list(hlds_goal)::out,
     list(instmap_delta)::in, list(instmap_delta)::out,
-    simplify_info::in, simplify_info::in, simplify_info::out,
-    io::di, io::uo) is det.
+    simplify_info::in, simplify_info::in, simplify_info::out) is det.
 
-simplify_disj([], RevGoals, Goals, !PostBranchInstMaps, _, !Info, !IO) :-
+simplify_disj([], RevGoals, Goals, !PostBranchInstMaps, _, !Info) :-
     list.reverse(RevGoals, Goals).
 simplify_disj([Goal0 | Goals0], RevGoals0, Goals, !PostBranchInstMaps,
-        Info0, !Info, !IO) :-
-    simplify_goal(Goal0, Goal, !Info, !IO),
+        Info0, !Info) :-
+    simplify_goal(Goal0, Goal, !Info),
     Goal = hlds_goal(_, GoalInfo),
     Purity = goal_info_get_purity(GoalInfo),
 
@@ -3163,8 +3151,7 @@
     ),
 
     simplify_info_post_branch_update(Info0, !Info),
-    simplify_disj(Goals0, RevGoals1, Goals, !PostBranchInstMaps, Info0, !Info,
-        !IO).
+    simplify_disj(Goals0, RevGoals1, Goals, !PostBranchInstMaps, Info0, !Info).
 
     % Disjunctions that cannot succeed more than once when viewed from the
     % outside generally need some fixing up, and/or some warnings to be issued.
@@ -3196,11 +3183,11 @@
     %
 :- pred fixup_disj(list(hlds_goal)::in, determinism::in, bool::in,
     hlds_goal_info::in, hlds_goal_expr::out,
-    simplify_info::in, simplify_info::out, io::di, io::uo) is det.
+    simplify_info::in, simplify_info::out) is det.
 
-fixup_disj(Disjuncts, _, _OutputVars, GoalInfo, Goal, !Info, !IO) :-
+fixup_disj(Disjuncts, _, _OutputVars, GoalInfo, Goal, !Info) :-
     det_disj_to_ite(Disjuncts, GoalInfo, IfThenElse),
-    simplify_goal(IfThenElse, Simplified, !Info, !IO),
+    simplify_goal(IfThenElse, Simplified, !Info),
     Simplified = hlds_goal(Goal, _).
 
     % det_disj_to_ite is used to transform disjunctions that occur
Index: compiler/size_prof.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/size_prof.m,v
retrieving revision 1.56
diff -u -r1.56 size_prof.m
--- compiler/size_prof.m	29 Jan 2008 04:59:43 -0000	1.56
+++ compiler/size_prof.m	20 Feb 2008 23:48:14 -0000
@@ -222,22 +222,21 @@
         hlds_out.write_pred_proc_id_pair(!.ModuleInfo, PredId, ProcId, !IO),
         io.write_string(": ", !IO),
         process_proc(Transform, PredId, ProcId, ProcInfo0, ProcInfo,
-            !ModuleInfo, !IO),
+            !ModuleInfo),
         io.write_string("done.\n", !IO)
     ;
         VeryVerbose = no,
         process_proc(Transform, PredId, ProcId, ProcInfo0, ProcInfo,
-            !ModuleInfo, !IO)
+            !ModuleInfo)
     ).
 
 :- pred process_proc(construct_transform::in, pred_id::in, proc_id::in,
-    proc_info::in, proc_info::out, module_info::in, module_info::out,
-    io::di, io::uo) is det.
+    proc_info::in, proc_info::out, module_info::in, module_info::out) is det.
 
-process_proc(Transform, PredId, ProcId, !ProcInfo, !ModuleInfo, !IO) :-
+process_proc(Transform, PredId, ProcId, !ProcInfo, !ModuleInfo) :-
     Simplifications = list_to_simplifications([]),
     simplify_proc_return_msgs(Simplifications, PredId, ProcId,
-        !ModuleInfo, !ProcInfo, _Msgs, !IO),
+        !ModuleInfo, !ProcInfo, _Msgs),
 
     proc_info_get_goal(!.ProcInfo, Goal0),
     proc_info_get_varset(!.ProcInfo, VarSet0),
Index: compiler/tabling_analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/tabling_analysis.m,v
retrieving revision 1.13
diff -u -r1.13 tabling_analysis.m
--- compiler/tabling_analysis.m	18 Feb 2008 23:57:45 -0000	1.13
+++ compiler/tabling_analysis.m	20 Feb 2008 23:48:14 -0000
@@ -135,8 +135,8 @@
         module_info_dependency_info(!.ModuleInfo, DepInfo),
         hlds_dependency_info_get_dependency_ordering(DepInfo, SCCs),
         globals.io_lookup_bool_option(debug_mm_tabling_analysis, Debug, !IO),
-        list.foldl2(analyse_mm_tabling_in_scc(Debug, Pass1Only), SCCs,
-            !ModuleInfo, !IO),
+        list.foldl(analyse_mm_tabling_in_scc(Debug, Pass1Only), SCCs,
+            !ModuleInfo),
         % Only write mm_tabling_info pragmas to `.opt' files for
         % `--intermodule-optimisation' not `--intermodule-analysis'.
         (
@@ -168,14 +168,14 @@
             ).
 
 :- pred analyse_mm_tabling_in_scc(bool::in, bool::in, scc::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-analyse_mm_tabling_in_scc(Debug, Pass1Only, SCC, !ModuleInfo, !IO) :-
+analyse_mm_tabling_in_scc(Debug, Pass1Only, SCC, !ModuleInfo) :-
     %
     % Begin by analysing each procedure in the SCC.
     %
-    list.foldl3(check_proc_for_mm_tabling(SCC), SCC, [], ProcResults,
-        !ModuleInfo, !IO),
+    list.foldl2(check_proc_for_mm_tabling(SCC), SCC, [], ProcResults,
+        !ModuleInfo),
     combine_individual_proc_results(ProcResults, TablingStatus,
         MaybeAnalysisStatus),
     %
@@ -183,8 +183,10 @@
     %
     (
         Debug = yes,
-        dump_mm_tabling_analysis_debug_info(!.ModuleInfo, SCC,
-            TablingStatus, !IO)
+        trace [io(!IO)] (
+            dump_mm_tabling_analysis_debug_info(!.ModuleInfo, SCC,
+                TablingStatus, !IO)
+        )
     ;
         Debug = no
     ),
@@ -201,8 +203,9 @@
     %
     % Record the analysis results for the intermodule analysis
     %
-    globals.io_lookup_bool_option(make_analysis_registry,
-        MakeAnalysisRegistry, !IO),
+    module_info_get_globals(!.ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, make_analysis_registry,
+        MakeAnalysisRegistry),
     (
         MakeAnalysisRegistry = yes,
         (
@@ -218,7 +221,7 @@
     ),
     (
         Pass1Only = no,
-        list.foldl2(annotate_proc, SCC, !ModuleInfo, !IO)
+        list.foldl(annotate_proc, SCC, !ModuleInfo)
     ;
         Pass1Only = yes
     ).
@@ -282,10 +285,9 @@
 %
 
 :- pred check_proc_for_mm_tabling(scc::in, pred_proc_id::in, proc_results::in,
-    proc_results::out, module_info::in, module_info::out, io::di, io::uo)
-    is det.
+    proc_results::out, module_info::in, module_info::out) is det.
 
-check_proc_for_mm_tabling(SCC, PPId, !Results, !ModuleInfo, !IO) :-
+check_proc_for_mm_tabling(SCC, PPId, !Results, !ModuleInfo) :-
     module_info_pred_proc_info(!.ModuleInfo, PPId, _, ProcInfo),
     proc_info_get_eval_method(ProcInfo, EvalMethod),
     (
@@ -301,7 +303,7 @@
         proc_info_get_goal(ProcInfo, Body),
         proc_info_get_vartypes(ProcInfo, VarTypes),
         check_goal_for_mm_tabling(SCC, VarTypes, Body, Result,
-            MaybeAnalysisStatus, !ModuleInfo, !IO)
+            MaybeAnalysisStatus, !ModuleInfo)
     ),
     list.cons(proc_result(PPId, Result, MaybeAnalysisStatus), !Results).
 
@@ -312,10 +314,10 @@
 
 :- pred check_goal_for_mm_tabling(scc::in, vartypes::in, hlds_goal::in,
     mm_tabling_status::out, maybe(analysis_status)::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
 check_goal_for_mm_tabling(SCC, VarTypes, Goal, Result, MaybeAnalysisStatus,
-        !ModuleInfo, !IO) :-
+        !ModuleInfo) :-
     Goal = hlds_goal(GoalExpr, _GoalInfo),
     (
         GoalExpr = unify(_, _, _, Kind, _),
@@ -336,7 +338,7 @@
         GoalExpr = plain_call(CalleePredId, CalleeProcId, CallArgs, _, _, _),
         CalleePPId = proc(CalleePredId, CalleeProcId),
         check_call_for_mm_tabling(CalleePPId, CallArgs, SCC, VarTypes, Result,
-            MaybeAnalysisStatus, !ModuleInfo, !IO)
+            MaybeAnalysisStatus, !ModuleInfo)
     ;
         GoalExpr = generic_call(Details, _Args, _ArgModes, _),
         (
@@ -363,7 +365,7 @@
         ; GoalExpr = scope(_, SubGoal)
         ),
         check_goal_for_mm_tabling(SCC, VarTypes, SubGoal, Result,
-            MaybeAnalysisStatus, !ModuleInfo, !IO)
+            MaybeAnalysisStatus, !ModuleInfo)
     ;
         (
             GoalExpr = conj(_, Goals)
@@ -377,7 +379,7 @@
             Goals = list.map((func(case(_, _, CaseGoal)) = CaseGoal), Cases)
         ),
         check_goals_for_mm_tabling(SCC, VarTypes, Goals, Result,
-            MaybeAnalysisStatus, !ModuleInfo, !IO)
+            MaybeAnalysisStatus, !ModuleInfo)
     ;
         GoalExpr = shorthand(_),
         unexpected(this_file,
@@ -386,12 +388,12 @@
 
 :- pred check_goals_for_mm_tabling(scc::in, vartypes::in,
     hlds_goals::in, mm_tabling_status::out, maybe(analysis_status)::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
 check_goals_for_mm_tabling(SCC, VarTypes, Goals, Result, MaybeAnalysisStatus,
-        !ModuleInfo, !IO) :-
-    list.map2_foldl2(check_goal_for_mm_tabling(SCC, VarTypes), Goals,
-        Results, MaybeAnalysisStatuses, !ModuleInfo, !IO),
+        !ModuleInfo) :-
+    list.map2_foldl(check_goal_for_mm_tabling(SCC, VarTypes), Goals,
+        Results, MaybeAnalysisStatuses, !ModuleInfo),
     list.foldl(combine_mm_tabling_status, Results, mm_tabled_will_not_call,
         Result),
     list.foldl(combine_maybe_analysis_status, MaybeAnalysisStatuses,
@@ -404,10 +406,10 @@
 
 :- pred check_call_for_mm_tabling(pred_proc_id::in, prog_vars::in,
     scc::in, vartypes::in, mm_tabling_status::out, maybe(analysis_status)::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
 check_call_for_mm_tabling(CalleePPId, CallArgs, SCC, VarTypes, Result,
-        MaybeAnalysisStatus, !ModuleInfo, !IO) :-
+        MaybeAnalysisStatus, !ModuleInfo) :-
     CalleePPId = proc(CalleePredId, _),
     module_info_pred_info(!.ModuleInfo, CalleePredId, CalleePredInfo),
     (
@@ -444,7 +446,8 @@
         MaybeAnalysisStatus = yes(optimal)
     ;
         % Handle normal calls.
-        globals.io_lookup_bool_option(intermodule_analysis, Intermod, !IO),
+        module_info_get_globals(!.ModuleInfo, Globals),
+        globals.lookup_bool_option(Globals, intermodule_analysis, Intermod),
         (
             Intermod = yes,
             pred_info_is_imported(CalleePredInfo)
@@ -453,7 +456,7 @@
             % procedure and `--intermodule-analysis' is enabled.
             %
             search_analysis_status(CalleePPId, Result0, AnalysisStatus, SCC,
-                !ModuleInfo, !IO),
+                !ModuleInfo),
             (
                 Result0 = mm_tabled_conditional,
                 % XXX user-defined uc
@@ -566,26 +569,25 @@
     % `will_not_call_mm_tabled' feature to the goal_infos of those goals that
     % do not make calls to minimal model tabled procedures.
     %
-:- pred annotate_proc(pred_proc_id::in, module_info::in, module_info::out,
-    io::di, io::uo) is det.
+:- pred annotate_proc(pred_proc_id::in, module_info::in, module_info::out)
+    is det.
 
-annotate_proc(PPId, !ModuleInfo, !IO) :-
+annotate_proc(PPId, !ModuleInfo) :-
     some [!ProcInfo, !Body] (
       module_info_pred_proc_info(!.ModuleInfo, PPId, PredInfo, !:ProcInfo),
       proc_info_get_goal(!.ProcInfo, !:Body),
       proc_info_get_vartypes(!.ProcInfo, VarTypes),
-      annotate_goal(VarTypes, !Body, _Status, !ModuleInfo, !IO),
+      annotate_goal(VarTypes, !Body, _Status, !ModuleInfo),
       proc_info_set_goal(!.Body, !ProcInfo),
       module_info_set_pred_proc_info(PPId, PredInfo, !.ProcInfo, !ModuleInfo)
     ).
 
 :- pred annotate_goal(vartypes::in, hlds_goal::in, hlds_goal::out,
-    mm_tabling_status::out, module_info::in, module_info::out,
-    io::di, io::uo) is det.
+    mm_tabling_status::out, module_info::in, module_info::out) is det.
 
-annotate_goal(VarTypes, !Goal, Status, !ModuleInfo, !IO) :-
+annotate_goal(VarTypes, !Goal, Status, !ModuleInfo) :-
     !.Goal = hlds_goal(GoalExpr0, GoalInfo0),
-    annotate_goal_2(VarTypes, GoalExpr0, GoalExpr, Status, !ModuleInfo, !IO),
+    annotate_goal_2(VarTypes, GoalExpr0, GoalExpr, Status, !ModuleInfo),
     (
         Status = mm_tabled_will_not_call,
         goal_info_add_feature(feature_will_not_call_mm_tabled,
@@ -599,10 +601,9 @@
     !:Goal = hlds_goal(GoalExpr, GoalInfo).
 
 :- pred annotate_goal_2(vartypes::in, hlds_goal_expr::in, hlds_goal_expr::out,
-    mm_tabling_status::out, module_info::in, module_info::out, io::di, io::uo)
-    is det.
+    mm_tabling_status::out, module_info::in, module_info::out) is det.
 
-annotate_goal_2(VarTypes, !GoalExpr, Status, !ModuleInfo, !IO) :-
+annotate_goal_2(VarTypes, !GoalExpr, Status, !ModuleInfo) :-
     (
         !.GoalExpr = unify(_, _, _, Kind, _),
         (
@@ -619,7 +620,7 @@
     ;
         !.GoalExpr = plain_call(CalleePredId, CalleeProcId, CallArgs, _, _, _),
         CalleePPId = proc(CalleePredId, CalleeProcId),
-        annotate_call(CalleePPId, CallArgs, VarTypes, Status, !ModuleInfo, !IO)
+        annotate_call(CalleePPId, CallArgs, VarTypes, Status, !ModuleInfo)
     ;
         !.GoalExpr = call_foreign_proc(Attributes, _, _, _, _, _, _),
         Status = get_mm_tabling_status_from_attributes(Attributes)
@@ -642,22 +643,22 @@
     ;
         !.GoalExpr = conj(ConjType, Conjuncts0),
         annotate_goal_list(VarTypes, Conjuncts0, Conjuncts, Status,
-            !ModuleInfo, !IO),
+            !ModuleInfo),
         !:GoalExpr = conj(ConjType, Conjuncts)
     ;
         !.GoalExpr = disj(Disjuncts0),
         annotate_goal_list(VarTypes, Disjuncts0, Disjuncts, Status,
-            !ModuleInfo, !IO),
+            !ModuleInfo),
         !:GoalExpr = disj(Disjuncts)
     ;
         !.GoalExpr = switch(Var, CanFail, Cases0),
-        annotate_cases(VarTypes, Cases0, Cases, Status, !ModuleInfo, !IO),
+        annotate_cases(VarTypes, Cases0, Cases, Status, !ModuleInfo),
         !:GoalExpr = switch(Var, CanFail, Cases)
     ;
         !.GoalExpr = if_then_else(Vars, Cond0, Then0, Else0),
-        annotate_goal(VarTypes, Cond0, Cond, CondStatus, !ModuleInfo, !IO),
-        annotate_goal(VarTypes, Then0, Then, ThenStatus, !ModuleInfo, !IO),
-        annotate_goal(VarTypes, Else0, Else, ElseStatus, !ModuleInfo, !IO),
+        annotate_goal(VarTypes, Cond0, Cond, CondStatus, !ModuleInfo),
+        annotate_goal(VarTypes, Then0, Then, ThenStatus, !ModuleInfo),
+        annotate_goal(VarTypes, Else0, Else, ElseStatus, !ModuleInfo),
         (
             CondStatus = mm_tabled_will_not_call,
             ThenStatus = mm_tabled_will_not_call,
@@ -670,11 +671,11 @@
         !:GoalExpr = if_then_else(Vars, Cond, Then, Else)
     ;
         !.GoalExpr = negation(SubGoal0),
-        annotate_goal(VarTypes, SubGoal0, SubGoal, Status, !ModuleInfo, !IO),
+        annotate_goal(VarTypes, SubGoal0, SubGoal, Status, !ModuleInfo),
         !:GoalExpr = negation(SubGoal)
     ;
         !.GoalExpr = scope(Reason, SubGoal0),
-        annotate_goal(VarTypes, SubGoal0, SubGoal, Status, !ModuleInfo, !IO),
+        annotate_goal(VarTypes, SubGoal0, SubGoal, Status, !ModuleInfo),
         !:GoalExpr = scope(Reason, SubGoal)
     ;
         !.GoalExpr = shorthand(_),
@@ -682,39 +683,35 @@
     ).
 
 :- pred annotate_goal_list(vartypes::in, hlds_goals::in, hlds_goals::out,
-    mm_tabling_status::out, module_info::in, module_info::out, io::di, io::uo)
-    is det.
+    mm_tabling_status::out, module_info::in, module_info::out) is det.
 
-annotate_goal_list(VarTypes, !Goals, Status, !ModuleInfo, !IO) :-
-    list.map2_foldl2(annotate_goal(VarTypes), !Goals, Statuses,
-        !ModuleInfo, !IO),
+annotate_goal_list(VarTypes, !Goals, Status, !ModuleInfo) :-
+    list.map2_foldl(annotate_goal(VarTypes), !Goals, Statuses,
+        !ModuleInfo),
     list.foldl(combine_mm_tabling_status, Statuses, mm_tabled_will_not_call,
         Status).
 
 :- pred annotate_cases(vartypes::in, list(case)::in, list(case)::out,
-    mm_tabling_status::out, module_info::in, module_info::out,
-    io::di, io::uo) is det.
+    mm_tabling_status::out, module_info::in, module_info::out) is det.
 
-annotate_cases(VarTypes, !Cases, Status, !ModuleInfo, !IO) :-
-    list.map2_foldl2(annotate_case(VarTypes), !Cases, Statuses, !ModuleInfo,
-        !IO),
+annotate_cases(VarTypes, !Cases, Status, !ModuleInfo) :-
+    list.map2_foldl(annotate_case(VarTypes), !Cases, Statuses, !ModuleInfo),
     list.foldl(combine_mm_tabling_status, Statuses, mm_tabled_will_not_call,
         Status).
 
 :- pred annotate_case(vartypes::in, case::in, case::out,
-    mm_tabling_status::out, module_info::in, module_info::out,
-    io::di, io::uo) is det.
+    mm_tabling_status::out, module_info::in, module_info::out)
+    is det.
 
-annotate_case(VarTypes, !Case, Status, !ModuleInfo, !IO) :-
+annotate_case(VarTypes, !Case, Status, !ModuleInfo) :-
     !.Case = case(MainConsId, OtherConsIds, Goal0),
-    annotate_goal(VarTypes, Goal0, Goal, Status, !ModuleInfo, !IO),
+    annotate_goal(VarTypes, Goal0, Goal, Status, !ModuleInfo),
     !:Case = case(MainConsId, OtherConsIds, Goal).
 
 :- pred annotate_call(pred_proc_id::in, prog_vars::in, vartypes::in,
-    mm_tabling_status::out, module_info::in, module_info::out, io::di, io::uo)
-    is det.
+    mm_tabling_status::out, module_info::in, module_info::out) is det.
 
-annotate_call(CalleePPId, CallArgs, VarTypes, Status, !ModuleInfo, !IO) :-
+annotate_call(CalleePPId, CallArgs, VarTypes, Status, !ModuleInfo) :-
     CalleePPId = proc(CalleePredId, _),
     module_info_pred_info(!.ModuleInfo, CalleePredId, CalleePredInfo),
     (
@@ -737,8 +734,9 @@
         % XXX user-defined uc
         Status = mm_tabled_may_call
     ;
-        globals.io_lookup_bool_option(intermodule_analysis, IntermodAnalysis,
-            !IO),
+        module_info_get_globals(!.ModuleInfo, Globals),
+        globals.lookup_bool_option(Globals, intermodule_analysis,
+            IntermodAnalysis),
         (
             IntermodAnalysis = yes,
             pred_info_is_imported(CalleePredInfo)
@@ -749,7 +747,7 @@
             % target code.
             SCC = [],
             search_analysis_status(CalleePPId, Result, AnalysisStatus, SCC,
-                !ModuleInfo, !IO),
+                !ModuleInfo),
             (
                 AnalysisStatus = invalid,
                 unexpected(this_file,
@@ -942,31 +940,32 @@
     "mm_tabled_conditional").
 
 :- pred search_analysis_status(pred_proc_id::in,
-        mm_tabling_status::out, analysis_status::out, scc::in,
-        module_info::in, module_info::out, io::di, io::uo) is det.
+    mm_tabling_status::out, analysis_status::out, scc::in,
+    module_info::in, module_info::out) is det.
 
 search_analysis_status(PPId, Result, AnalysisStatus, CallerSCC,
-        !ModuleInfo, !IO) :-
+        !ModuleInfo) :-
     module_info_get_analysis_info(!.ModuleInfo, AnalysisInfo0),
     search_analysis_status_2(!.ModuleInfo, PPId, Result, AnalysisStatus,
-        CallerSCC, AnalysisInfo0, AnalysisInfo, !IO),
+        CallerSCC, AnalysisInfo0, AnalysisInfo),
     module_info_set_analysis_info(AnalysisInfo, !ModuleInfo).
 
 :- pred search_analysis_status_2(module_info::in, pred_proc_id::in,
     mm_tabling_status::out, analysis_status::out, scc::in,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
+    analysis_info::in, analysis_info::out) is det.
 
 search_analysis_status_2(ModuleInfo, PPId, Result, AnalysisStatus, CallerSCC,
-        !AnalysisInfo, !IO) :-
+        !AnalysisInfo) :-
     mmc_analysis.module_id_func_id(ModuleInfo, PPId, ModuleId, FuncId),
     Call = any_call,
-    analysis.lookup_best_result(ModuleId, FuncId, Call,
-        MaybeBestStatus, !AnalysisInfo, !IO),
-    globals.io_lookup_bool_option(make_analysis_registry,
-        MakeAnalysisRegistry, !IO),
+    analysis.lookup_best_result(!.AnalysisInfo, ModuleId, FuncId, Call,
+        MaybeBestStatus),
+    module_info_get_globals(ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, make_analysis_registry,
+        MakeAnalysisRegistry),
     (
-        MaybeBestStatus = yes({BestCall, mm_tabling_analysis_answer(Result),
-            AnalysisStatus}),
+        MaybeBestStatus = yes(analysis_result(BestCall,
+            mm_tabling_analysis_answer(Result), AnalysisStatus)),
         (
             MakeAnalysisRegistry = yes,
             record_dependencies(ModuleId, FuncId, BestCall,
@@ -981,7 +980,7 @@
         % procedure.
         top(Call) = Answer,
         Answer = mm_tabling_analysis_answer(Result),
-        module_is_local(mmc, ModuleId, IsLocal, !IO),
+        module_is_local(!.AnalysisInfo, ModuleId, IsLocal),
         (
             IsLocal = yes,
             AnalysisStatus = suboptimal,
Index: compiler/trailing_analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/trailing_analysis.m,v
retrieving revision 1.32
diff -u -r1.32 trailing_analysis.m
--- compiler/trailing_analysis.m	18 Feb 2008 23:57:45 -0000	1.32
+++ compiler/trailing_analysis.m	20 Feb 2008 23:48:14 -0000
@@ -145,7 +145,7 @@
         module_info_dependency_info(!.ModuleInfo, DepInfo),
         hlds_dependency_info_get_dependency_ordering(DepInfo, SCCs),
         globals.io_lookup_bool_option(debug_trail_usage, Debug, !IO),
-        list.foldl2(process_scc(Debug, Pass1Only), SCCs, !ModuleInfo, !IO),
+        list.foldl(process_scc(Debug, Pass1Only), SCCs, !ModuleInfo),
         % Only write trailing analysis pragmas to `.opt' files for
         % `--intermodule-optimization', not `--intermodule-analysis'.
         (
@@ -177,10 +177,10 @@
             ).
 
 :- pred process_scc(bool::in, bool::in, scc::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-process_scc(Debug, Pass1Only, SCC, !ModuleInfo, !IO) :-
-    check_procs_for_trail_mods(SCC, ProcResults, !ModuleInfo, !IO),
+process_scc(Debug, Pass1Only, SCC, !ModuleInfo) :-
+    check_procs_for_trail_mods(SCC, ProcResults, !ModuleInfo),
 
     % The `Results' above are the results of analysing each individual
     % procedure in the SCC - we now have to combine them in a meaningful way.
@@ -189,7 +189,9 @@
 
     (
         Debug = yes,
-        dump_trail_usage_debug_info(!.ModuleInfo, SCC, TrailingStatus, !IO)
+        trace [io(!IO)] (
+            dump_trail_usage_debug_info(!.ModuleInfo, SCC, TrailingStatus, !IO)
+        )
     ;
         Debug = no
     ),
@@ -204,8 +206,9 @@
     module_info_set_trailing_info(TrailingInfo, !ModuleInfo),
 
     % Record the analysis results for the intermodule analysis.
-    globals.io_lookup_bool_option(make_analysis_registry,
-        MakeAnalysisRegistry, !IO),
+    module_info_get_globals(!.ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, make_analysis_registry,
+        MakeAnalysisRegistry),
     (
         MakeAnalysisRegistry = yes,
         (
@@ -221,7 +224,7 @@
     ),
     (
         Pass1Only = no,
-        list.foldl2(annotate_proc, SCC, !ModuleInfo, !IO)
+        list.foldl(annotate_proc, SCC, !ModuleInfo)
     ;
         Pass1Only = yes
     ).
@@ -229,11 +232,10 @@
     % Check each procedure in the SCC individually.
     %
 :- pred check_procs_for_trail_mods(scc::in, proc_results::out,
-        module_info::in, module_info::out, io::di, io::uo) is det.
+        module_info::in, module_info::out) is det.
 
-check_procs_for_trail_mods(SCC, Result, !ModuleInfo, !IO) :-
-    list.foldl3(check_proc_for_trail_mods(SCC), SCC, [], Result,
-        !ModuleInfo, !IO).
+check_procs_for_trail_mods(SCC, Result, !ModuleInfo) :-
+    list.foldl2(check_proc_for_trail_mods(SCC), SCC, [], Result, !ModuleInfo).
 
     % Examine how the procedures interact with other procedures that
     % are mutually-recursive to them.
@@ -295,14 +297,14 @@
 
 :- pred check_proc_for_trail_mods(scc::in,
     pred_proc_id::in, proc_results::in, proc_results::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-check_proc_for_trail_mods(SCC, PPId, !Results, !ModuleInfo, !IO) :-
+check_proc_for_trail_mods(SCC, PPId, !Results, !ModuleInfo) :-
     module_info_pred_proc_info(!.ModuleInfo, PPId, _, ProcInfo),
     proc_info_get_goal(ProcInfo, Body),
     proc_info_get_vartypes(ProcInfo, VarTypes),
     check_goal_for_trail_mods(SCC, VarTypes, Body,
-        Result, MaybeAnalysisStatus, !ModuleInfo, !IO),
+        Result, MaybeAnalysisStatus, !ModuleInfo),
     list.cons(proc_result(PPId, Result, MaybeAnalysisStatus), !Results).
 
 %----------------------------------------------------------------------------%
@@ -312,10 +314,10 @@
 
 :- pred check_goal_for_trail_mods(scc::in, vartypes::in, hlds_goal::in,
     trailing_status::out, maybe(analysis_status)::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
 check_goal_for_trail_mods(SCC, VarTypes, Goal, Result, MaybeAnalysisStatus,
-        !ModuleInfo, !IO) :-
+        !ModuleInfo) :-
     Goal = hlds_goal(GoalExpr, GoalInfo),
     (
         GoalExpr = unify(_, _, _, Kind, _),
@@ -376,7 +378,9 @@
             Result = Result0,
             MaybeAnalysisStatus = yes(optimal)
         ;
-            globals.io_lookup_bool_option(intermodule_analysis, Intermod, !IO),
+            module_info_get_globals(!.ModuleInfo, Globals),
+            globals.lookup_bool_option(Globals, intermodule_analysis,
+                Intermod),
             (
                 Intermod = yes,
                 pred_info_is_imported(CallPredInfo)
@@ -385,7 +389,7 @@
                 % results for locally defined procedures, otherwise we use
                 % the intermodule analysis framework.
                 search_analysis_status(CallPPId, Result0, AnalysisStatus, SCC,
-                    !ModuleInfo, !IO),
+                    !ModuleInfo),
                 (
                     Result0 = trail_conditional,
                     Result = check_vars(!.ModuleInfo, VarTypes, CallArgs)
@@ -443,11 +447,11 @@
     ;
         GoalExpr = conj(_ConjType, Goals),
         check_goals_for_trail_mods(SCC, VarTypes, Goals,
-            Result, MaybeAnalysisStatus, !ModuleInfo, !IO)
+            Result, MaybeAnalysisStatus, !ModuleInfo)
     ;
         GoalExpr = disj(Goals),
         check_goals_for_trail_mods(SCC, VarTypes, Goals,
-            _Result0, MaybeAnalysisStatus, !ModuleInfo, !IO),
+            _Result0, MaybeAnalysisStatus, !ModuleInfo),
         % XXX Currently we have to put trailing code around disjunctions.
         % If we introduce trail specialisation, it may be possible to omit it.
         Result = trail_may_modify
@@ -455,11 +459,11 @@
         GoalExpr = switch(_, _, Cases),
         CaseGoals = list.map((func(case(_, _, CaseGoal)) = CaseGoal), Cases),
         check_goals_for_trail_mods(SCC, VarTypes, CaseGoals,
-            Result, MaybeAnalysisStatus, !ModuleInfo, !IO)
+            Result, MaybeAnalysisStatus, !ModuleInfo)
     ;
         GoalExpr = if_then_else(_, Cond, Then, Else),
         check_goals_for_trail_mods(SCC, VarTypes, [Cond, Then, Else],
-            Result0, MaybeAnalysisStatus, !ModuleInfo, !IO),
+            Result0, MaybeAnalysisStatus, !ModuleInfo),
         (
             % If the condition of an if-then-else does not modify the trail
             % and is not model_non then we can omit the trailing ops around
@@ -490,12 +494,12 @@
     ;
         GoalExpr = negation(SubGoal),
         check_goal_for_trail_mods(SCC, VarTypes, SubGoal, Result,
-            MaybeAnalysisStatus, !ModuleInfo, !IO)
+            MaybeAnalysisStatus, !ModuleInfo)
     ;
         GoalExpr = scope(_, InnerGoal),
         OuterGoalInfo = GoalInfo,
         check_goal_for_trail_mods(SCC, VarTypes, InnerGoal, Result0,
-            MaybeAnalysisStatus, !ModuleInfo, !IO),
+            MaybeAnalysisStatus, !ModuleInfo),
         InnerGoal = hlds_goal(_, InnerGoalInfo),
         InnerCodeModel = goal_info_get_code_model(InnerGoalInfo),
         OuterCodeModel = goal_info_get_code_model(OuterGoalInfo),
@@ -514,12 +518,12 @@
 
 :- pred check_goals_for_trail_mods(scc::in, vartypes::in,
     hlds_goals::in, trailing_status::out, maybe(analysis_status)::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
 check_goals_for_trail_mods(SCC, VarTypes, Goals,
-        Result, MaybeAnalysisStatus, !ModuleInfo, !IO) :-
-    list.map2_foldl2(check_goal_for_trail_mods(SCC, VarTypes), Goals,
-        Results, MaybeAnalysisStatuses, !ModuleInfo, !IO),
+        Result, MaybeAnalysisStatus, !ModuleInfo) :-
+    list.map2_foldl(check_goal_for_trail_mods(SCC, VarTypes), Goals,
+        Results, MaybeAnalysisStatuses, !ModuleInfo),
     list.foldl(combine_trailing_status, Results, trail_will_not_modify,
         Result),
     list.foldl(combine_maybe_analysis_status, MaybeAnalysisStatuses,
@@ -811,27 +815,26 @@
     % features to the goal_infos of those procedure that cannot modify the
     % trail.
     %
-:- pred annotate_proc(pred_proc_id::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+:- pred annotate_proc(pred_proc_id::in, module_info::in, module_info::out)
+    is det.
 
-annotate_proc(PPId, !ModuleInfo, !IO) :-
+annotate_proc(PPId, !ModuleInfo) :-
     some [!ProcInfo, !Body] (
       module_info_pred_proc_info(!.ModuleInfo, PPId, PredInfo, !:ProcInfo),
       proc_info_get_goal(!.ProcInfo, !:Body),
       proc_info_get_vartypes(!.ProcInfo, VarTypes),
-      annotate_goal(VarTypes, !Body, _Status, !ModuleInfo, !IO),
+      annotate_goal(VarTypes, !Body, _Status, !ModuleInfo),
       proc_info_set_goal(!.Body, !ProcInfo),
       module_info_set_pred_proc_info(PPId, PredInfo, !.ProcInfo, !ModuleInfo)
     ).
 
 :- pred annotate_goal(vartypes::in, hlds_goal::in, hlds_goal::out,
-    trailing_status::out, module_info::in, module_info::out,
-    io::di, io::uo) is det.
+    trailing_status::out, module_info::in, module_info::out) is det.
 
-annotate_goal(VarTypes, !Goal, Status, !ModuleInfo, !IO) :-
+annotate_goal(VarTypes, !Goal, Status, !ModuleInfo) :-
     !.Goal = hlds_goal(GoalExpr0, GoalInfo0),
     annotate_goal_2(VarTypes, GoalInfo0, GoalExpr0, GoalExpr, Status,
-        !ModuleInfo, !IO),
+        !ModuleInfo),
     (
         Status = trail_will_not_modify,
         goal_info_add_feature(feature_will_not_modify_trail,
@@ -846,9 +849,9 @@
 
 :- pred annotate_goal_2(vartypes::in, hlds_goal_info::in,
     hlds_goal_expr::in, hlds_goal_expr::out, trailing_status::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-annotate_goal_2(VarTypes, GoalInfo, !GoalExpr, Status, !ModuleInfo, !IO) :-
+annotate_goal_2(VarTypes, GoalInfo, !GoalExpr, Status, !ModuleInfo) :-
     (
         !.GoalExpr = unify(_, _, _, Kind, _),
         (
@@ -890,8 +893,9 @@
         ->
             Status = Status0
         ;
-            globals.io_lookup_bool_option(intermodule_analysis,
-                IntermodAnalysis, !IO),
+            module_info_get_globals(!.ModuleInfo, Globals), 
+            globals.lookup_bool_option(Globals, intermodule_analysis,
+                IntermodAnalysis),
             (
                 IntermodAnalysis = yes,
                 pred_info_is_imported(CallPredInfo)
@@ -902,7 +906,7 @@
                 % when compiling to target code.
                 SCC = [],
                 search_analysis_status(CallPPId, Result, AnalysisStatus, SCC,
-                    !ModuleInfo, !IO),
+                    !ModuleInfo),
 
                 % XXX We shouldn't be getting invalid analysis results at this
                 % stage so maybe we should just call unexpected/2 here?
@@ -950,22 +954,22 @@
     ;
         !.GoalExpr = conj(ConjType, Conjuncts0),
         annotate_goal_list(VarTypes, Conjuncts0, Conjuncts, Status,
-            !ModuleInfo, !IO),
+            !ModuleInfo),
         !:GoalExpr = conj(ConjType, Conjuncts)
     ;
         !.GoalExpr = disj(Disjuncts0),
         annotate_goal_list(VarTypes, Disjuncts0, Disjuncts, Status,
-            !ModuleInfo, !IO),
+            !ModuleInfo),
         !:GoalExpr = disj(Disjuncts)
     ;
         !.GoalExpr = switch(Var, CanFail, Cases0),
-        annotate_cases(VarTypes, Cases0, Cases, Status, !ModuleInfo, !IO),
+        annotate_cases(VarTypes, Cases0, Cases, Status, !ModuleInfo),
         !:GoalExpr = switch(Var, CanFail, Cases)
     ;
         !.GoalExpr = if_then_else(Vars, If0, Then0, Else0),
-        annotate_goal(VarTypes, If0, If, IfStatus, !ModuleInfo, !IO),
-        annotate_goal(VarTypes, Then0, Then, ThenStatus, !ModuleInfo, !IO),
-        annotate_goal(VarTypes, Else0, Else, ElseStatus, !ModuleInfo, !IO),
+        annotate_goal(VarTypes, If0, If, IfStatus, !ModuleInfo),
+        annotate_goal(VarTypes, Then0, Then, ThenStatus, !ModuleInfo),
+        annotate_goal(VarTypes, Else0, Else, ElseStatus, !ModuleInfo),
         (
             IfStatus   = trail_will_not_modify,
             ThenStatus = trail_will_not_modify,
@@ -978,13 +982,12 @@
         !:GoalExpr = if_then_else(Vars, If, Then, Else)
     ;
         !.GoalExpr = negation(SubGoal0),
-        annotate_goal(VarTypes, SubGoal0, SubGoal, Status, !ModuleInfo, !IO),
+        annotate_goal(VarTypes, SubGoal0, SubGoal, Status, !ModuleInfo),
         !:GoalExpr = negation(SubGoal)
     ;
         !.GoalExpr = scope(Reason, InnerGoal0),
         OuterGoalInfo = GoalInfo,
-        annotate_goal(VarTypes, InnerGoal0, InnerGoal, Status0,
-            !ModuleInfo, !IO),
+        annotate_goal(VarTypes, InnerGoal0, InnerGoal, Status0, !ModuleInfo),
         InnerGoal = hlds_goal(_, InnerGoalInfo),
         InnerCodeModel = goal_info_get_code_model(InnerGoalInfo),
         OuterCodeModel = goal_info_get_code_model(OuterGoalInfo),
@@ -998,31 +1001,27 @@
 
 :- pred annotate_goal_list(vartypes::in, hlds_goals::in,
     hlds_goals::out, trailing_status::out, module_info::in,
-    module_info::out, io::di, io::uo) is det.
+    module_info::out) is det.
 
-annotate_goal_list(VarTypes, !Goals, Status, !ModuleInfo, !IO) :-
-    list.map2_foldl2(annotate_goal(VarTypes), !Goals, Statuses, !ModuleInfo,
-        !IO),
+annotate_goal_list(VarTypes, !Goals, Status, !ModuleInfo) :-
+    list.map2_foldl(annotate_goal(VarTypes), !Goals, Statuses, !ModuleInfo),
     list.foldl(combine_trailing_status, Statuses, trail_will_not_modify,
         Status).
 
 :- pred annotate_cases(vartypes::in, list(case)::in, list(case)::out,
-    trailing_status::out, module_info::in, module_info::out,
-    io::di, io::uo) is det.
+    trailing_status::out, module_info::in, module_info::out) is det.
 
-annotate_cases(VarTypes, !Cases, Status, !ModuleInfo, !IO) :-
-    list.map2_foldl2(annotate_case(VarTypes), !Cases, Statuses, !ModuleInfo,
-        !IO),
+annotate_cases(VarTypes, !Cases, Status, !ModuleInfo) :-
+    list.map2_foldl(annotate_case(VarTypes), !Cases, Statuses, !ModuleInfo),
     list.foldl(combine_trailing_status, Statuses, trail_will_not_modify,
         Status).
 
 :- pred annotate_case(vartypes::in, case::in, case::out,
-    trailing_status::out, module_info::in, module_info::out,
-    io::di, io::uo) is det.
+    trailing_status::out, module_info::in, module_info::out) is det.
 
-annotate_case(VarTypes, !Case, Status, !ModuleInfo, !IO) :-
+annotate_case(VarTypes, !Case, Status, !ModuleInfo) :-
     !.Case = case(MainConsId, OtherConsIds, Goal0),
-    annotate_goal(VarTypes, Goal0, Goal, Status, !ModuleInfo, !IO),
+    annotate_goal(VarTypes, Goal0, Goal, Status, !ModuleInfo),
     !:Case = case(MainConsId, OtherConsIds, Goal).
 
 %----------------------------------------------------------------------------%
@@ -1174,30 +1173,31 @@
 
 :- pred search_analysis_status(pred_proc_id::in,
     trailing_status::out, analysis_status::out, scc::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
 search_analysis_status(PPId, Result, AnalysisStatus, CallerSCC,
-        !ModuleInfo, !IO) :-
+        !ModuleInfo) :-
     module_info_get_analysis_info(!.ModuleInfo, AnalysisInfo0),
     search_analysis_status_2(!.ModuleInfo, PPId, Result, AnalysisStatus,
-        CallerSCC, AnalysisInfo0, AnalysisInfo, !IO),
+        CallerSCC, AnalysisInfo0, AnalysisInfo),
     module_info_set_analysis_info(AnalysisInfo, !ModuleInfo).
 
 :- pred search_analysis_status_2(module_info::in, pred_proc_id::in,
     trailing_status::out, analysis_status::out, scc::in,
-    analysis_info::in, analysis_info::out, io::di, io::uo) is det.
+    analysis_info::in, analysis_info::out) is det.
 
 search_analysis_status_2(ModuleInfo, PPId, Result, AnalysisStatus, CallerSCC,
-        !AnalysisInfo, !IO) :-
+        !AnalysisInfo) :-
     mmc_analysis.module_id_func_id(ModuleInfo, PPId, ModuleId, FuncId),
     Call = any_call,
-    analysis.lookup_best_result(ModuleId, FuncId, Call,
-        MaybeBestStatus, !AnalysisInfo, !IO),
-    globals.io_lookup_bool_option(make_analysis_registry,
-        MakeAnalysisRegistry, !IO),
+    analysis.lookup_best_result(!.AnalysisInfo, ModuleId, FuncId, Call,
+        MaybeBestStatus),
+    module_info_get_globals(ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, make_analysis_registry,
+        MakeAnalysisRegistry),
     (
-        MaybeBestStatus = yes({BestCall, trailing_analysis_answer(Result),
-            AnalysisStatus}),
+        MaybeBestStatus = yes(analysis_result(BestCall,
+            trailing_analysis_answer(Result), AnalysisStatus)),
         (
             MakeAnalysisRegistry = yes,
             record_dependencies(ModuleId, FuncId, BestCall,
@@ -1211,7 +1211,7 @@
         % then assume that it modifies the trail.
         top(Call) = Answer,
         Answer = trailing_analysis_answer(Result),
-        module_is_local(mmc, ModuleId, IsLocal, !IO),
+        module_is_local(!.AnalysisInfo, ModuleId, IsLocal),
         (
             IsLocal = yes,
             AnalysisStatus = suboptimal,
Index: compiler/unused_args.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unused_args.m,v
retrieving revision 1.150
diff -u -r1.150 unused_args.m
--- compiler/unused_args.m	18 Feb 2008 23:57:45 -0000	1.150
+++ compiler/unused_args.m	20 Feb 2008 23:48:14 -0000
@@ -221,7 +221,7 @@
 process_module(!ModuleInfo, !Specs, !IO) :-
     module_info_get_globals(!.ModuleInfo, Globals),
     globals.lookup_bool_option(Globals, very_verbose, VeryVerbose),
-    init_var_usage(VarUsage0, PredProcs, ProcCallInfo0, !ModuleInfo, !IO),
+    init_var_usage(VarUsage0, PredProcs, ProcCallInfo0, !ModuleInfo),
     % maybe_write_string(VeryVerbose, "% Finished initialisation.\n", !IO),
 
     unused_args_pass(PredProcs, VarUsage0, VarUsage),
@@ -290,8 +290,8 @@
     globals.lookup_bool_option(Globals, optimize_unused_args, DoFixup),
     (
         DoFixup = yes,
-        list.foldl3(create_new_pred(UnusedArgInfo), PredProcsToFix,
-            ProcCallInfo0, ProcCallInfo, !ModuleInfo, !IO),
+        list.foldl2(create_new_pred(UnusedArgInfo), PredProcsToFix,
+            ProcCallInfo0, ProcCallInfo, !ModuleInfo),
         % maybe_write_string(VeryVerbose, "% Finished new preds.\n",
         %   !IO),
         fixup_unused_args(VarUsage, PredProcs, ProcCallInfo, !ModuleInfo,
@@ -318,40 +318,39 @@
     % iteration over.
     %
 :- pred init_var_usage(var_usage::out, pred_proc_list::out,
-    proc_call_info::out, module_info::in, module_info::out,
-    io::di, io::uo) is det.
+    proc_call_info::out, module_info::in, module_info::out) is det.
 
-init_var_usage(VarUsage, PredProcList, ProcCallInfo, !ModuleInfo, !IO) :-
+init_var_usage(VarUsage, PredProcList, ProcCallInfo, !ModuleInfo) :-
     map.init(ProcCallInfo0),
     map.init(VarUsage0),
     module_info_predids(PredIds, !ModuleInfo),
     setup_local_var_usage(PredIds, VarUsage0, VarUsage, [], PredProcList,
-        ProcCallInfo0, ProcCallInfo, !ModuleInfo, !IO).
+        ProcCallInfo0, ProcCallInfo, !ModuleInfo).
 
     % Setup args for the whole module.
     %
 :- pred setup_local_var_usage(list(pred_id)::in,
     var_usage::in, var_usage::out, pred_proc_list::in, pred_proc_list::out,
     proc_call_info::in, proc_call_info::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-setup_local_var_usage([], !VarUsage, !PredProcs, !OptProcs, !ModuleInfo, !IO).
+setup_local_var_usage([], !VarUsage, !PredProcs, !OptProcs, !ModuleInfo).
 setup_local_var_usage([PredId | PredIds], !VarUsage, !PredProcList, !OptProcs,
-        !ModuleInfo, !IO) :-
+        !ModuleInfo) :-
     maybe_setup_pred_args(PredId, !VarUsage, !PredProcList, !OptProcs,
-        !ModuleInfo, !IO),
+        !ModuleInfo),
     setup_local_var_usage(PredIds, !VarUsage, !PredProcList, !OptProcs,
-        !ModuleInfo, !IO).
+        !ModuleInfo).
 
     % Setup args for the given predicate if required.
     %
 :- pred maybe_setup_pred_args(pred_id::in, var_usage::in, var_usage::out,
     pred_proc_list::in, pred_proc_list::out,
     proc_call_info::in, proc_call_info::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-maybe_setup_pred_args(PredId, !VarUsage, !PredProcList, !OptProcs, !ModuleInfo,
-        !IO) :-
+maybe_setup_pred_args(PredId, !VarUsage, !PredProcList, !OptProcs,
+        !ModuleInfo) :-
     module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
     (
         % The builtins use all their arguments. We also want to treat stub
@@ -368,7 +367,7 @@
     ;
         ProcIds = pred_info_procids(PredInfo),
         setup_pred_args(PredId, ProcIds, !VarUsage, !PredProcList, !OptProcs,
-            !ModuleInfo, !IO)
+            !ModuleInfo)
     ).
 
     % Setup args for each mode of a predicate.
@@ -376,30 +375,31 @@
 :- pred setup_pred_args(pred_id::in, list(proc_id)::in,
     var_usage::in, var_usage::out, pred_proc_list::in, pred_proc_list::out,
     proc_call_info::in, proc_call_info::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-setup_pred_args(_, [], !VarUsage, !PredProcs, !OptProcs, !ModuleInfo, !IO).
+setup_pred_args(_, [], !VarUsage, !PredProcs, !OptProcs, !ModuleInfo).
 setup_pred_args(PredId, [ProcId | ProcIds], !VarUsage,
-        !PredProcs, !OptProcs, !ModuleInfo, !IO) :-
+        !PredProcs, !OptProcs, !ModuleInfo) :-
     setup_proc_args(PredId, ProcId, !VarUsage, !PredProcs,
-        !OptProcs, !ModuleInfo, !IO),
+        !OptProcs, !ModuleInfo),
     setup_pred_args(PredId, ProcIds, !VarUsage, !PredProcs,
-        !OptProcs, !ModuleInfo, !IO).
+        !OptProcs, !ModuleInfo).
 
     % Setup args for the procedure.
     %
 :- pred setup_proc_args(pred_id::in, proc_id::in,
     var_usage::in, var_usage::out, pred_proc_list::in, pred_proc_list::out,
     proc_call_info::in, proc_call_info::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
-setup_proc_args(PredId, ProcId, !VarUsage, !PredProcs, !OptProcs, !ModuleInfo,
-        !IO) :-
+setup_proc_args(PredId, ProcId, !VarUsage, !PredProcs, !OptProcs,
+        !ModuleInfo) :-
     module_info_pred_proc_info(!.ModuleInfo, PredId, ProcId,
         PredInfo, ProcInfo),
+    module_info_get_globals(!.ModuleInfo, Globals),
     some [!VarDep] (
         map.init(!:VarDep),
-        globals.io_lookup_bool_option(intermodule_analysis, Intermod, !IO),
+        globals.lookup_bool_option(Globals, intermodule_analysis, Intermod),
         (
             % Don't use the intermodule analysis info when we have the clauses
             % (opt_imported preds) since we may be able to do better with the
@@ -416,10 +416,11 @@
                 PredName, PredArity, ProcId),
             Call = unused_args_call(PredArity),
             module_info_get_analysis_info(!.ModuleInfo, AnalysisInfo0),
-            lookup_best_result(PredModuleId, FuncId, Call,
-                MaybeBestResult, AnalysisInfo0, AnalysisInfo1, !IO),
+            lookup_best_result(AnalysisInfo0, PredModuleId, FuncId, Call,
+                MaybeBestResult),
             (
-                MaybeBestResult = yes({_, unused_args(UnusedArgs), _}),
+                MaybeBestResult = yes(analysis_result(_, BestAnswer, _)),
+                BestAnswer = unused_args(UnusedArgs),
                 ( 
                     UnusedArgs = [_ | _],
                     proc_info_get_headvars(ProcInfo, HeadVars),
@@ -428,8 +429,8 @@
                     initialise_vardep(UnusedVars, !.VarDep, VarDep),
                     PredProcId = proc(PredId, ProcId),
                     svmap.set(PredProcId, VarDep, !VarUsage),
-                    globals.io_lookup_bool_option(optimize_unused_args,
-                        OptimizeUnusedArgs, !IO),
+                    globals.lookup_bool_option(Globals,
+                        optimize_unused_args, OptimizeUnusedArgs),
                     (
                         OptimizeUnusedArgs = yes,
                         make_imported_unused_args_pred_info(PredProcId,
@@ -440,34 +441,34 @@
                 ;
                     UnusedArgs = [] 
                 ),
-                AnalysisInfo = AnalysisInfo1
+                AnalysisInfo = AnalysisInfo0
             ;
                 MaybeBestResult = no,
-                module_is_local(mmc, PredModuleId, IsLocal, !IO),
+                module_is_local(AnalysisInfo0, PredModuleId, IsLocal),
                 (
                     IsLocal = yes,
                     % XXX makes too many requests
-                    globals.io_lookup_bool_option(make_analysis_registry,
-                        MakeAnalysisRegistry, !IO),
+                    globals.lookup_bool_option(Globals,
+                        make_analysis_registry, MakeAnalysisRegistry),
                     (
                         MakeAnalysisRegistry = yes,
                         ( is_unify_or_compare_pred(PredInfo) ->
-                            AnalysisInfo = AnalysisInfo1
+                            AnalysisInfo = AnalysisInfo0
                         ;
                             analysis.record_result(PredModuleId, FuncId,
                                 Call, top(Call) : unused_args_answer,
-                                suboptimal, AnalysisInfo1, AnalysisInfo2),
+                                suboptimal, AnalysisInfo0, AnalysisInfo1),
                             analysis.record_request(analysis_name,
-                                PredModuleId, FuncId, Call, AnalysisInfo2,
+                                PredModuleId, FuncId, Call, AnalysisInfo1,
                                 AnalysisInfo)
                         )
                     ;
                         MakeAnalysisRegistry = no,
-                        AnalysisInfo = AnalysisInfo1
+                        AnalysisInfo = AnalysisInfo0
                     )
                 ;
                     IsLocal = no,
-                    AnalysisInfo = AnalysisInfo1
+                    AnalysisInfo = AnalysisInfo0
                 )
             ),
             module_info_set_analysis_info(AnalysisInfo, !ModuleInfo)
@@ -491,7 +492,6 @@
             initialise_vardep(Vars, !VarDep),
             setup_output_args(!.ModuleInfo, ProcInfo, !VarDep),
 
-            module_info_get_globals(!.ModuleInfo, Globals),
             proc_interface_should_use_typeinfo_liveness(PredInfo, ProcId,
                 Globals, TypeInfoLiveness),
             (
@@ -982,17 +982,18 @@
     %
 :- pred create_new_pred(unused_arg_info::in, pred_proc_id::in,
     proc_call_info::in, proc_call_info::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.
 
 create_new_pred(UnusedArgInfo, proc(PredId, ProcId), !ProcCallInfo,
-        !ModuleInfo, !IO) :-
+        !ModuleInfo) :-
     map.lookup(UnusedArgInfo, proc(PredId, ProcId), UnusedArgs),
     module_info_pred_proc_info(!.ModuleInfo, PredId, ProcId,
         OrigPredInfo, OrigProcInfo),
     PredModule = pred_info_module(OrigPredInfo),
     PredName = pred_info_name(OrigPredInfo),
 
-    globals.io_lookup_bool_option(intermodule_analysis, Intermod, !IO),
+    module_info_get_globals(!.ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, intermodule_analysis, Intermod),
     (
         Intermod = yes,
         module_info_get_analysis_info(!.ModuleInfo, AnalysisInfo0),
@@ -1004,11 +1005,10 @@
         Call = unused_args_call(PredArity),
         Answer = unused_args(UnusedArgs),
 
-        analysis.lookup_results(ModuleId, FuncId,
-            IntermodResultsTriples : list({unused_args_call,
-                unused_args_answer, analysis_status}),
-            AnalysisInfo0, AnalysisInfo1, !IO),
-        IntermodOldAnswers = list.map((func({_, Ans, _}) = Ans),
+        analysis.lookup_results(AnalysisInfo0, ModuleId, FuncId,
+            IntermodResultsTriples : list(analysis_result(unused_args_call,
+                unused_args_answer))),
+        IntermodOldAnswers = list.map((func(R) = R ^ ar_answer),
             IntermodResultsTriples),
         FilterUnused = (pred(VersionAnswer::in) is semidet :-
             VersionAnswer \= Answer,
@@ -1021,8 +1021,8 @@
         % XXX: optimal?  If we know some output arguments are not going to be
         % used by the caller then more input arguments could be deduced to be
         % unused.  This analysis doesn't handle that yet.
-        globals.io_lookup_bool_option(make_analysis_registry,
-            MakeAnalysisRegistry, !IO),
+        globals.lookup_bool_option(Globals, make_analysis_registry,
+            MakeAnalysisRegistry),
         ( 
             MakeAnalysisRegistry = yes,
             procedure_is_exported(!.ModuleInfo, OrigPredInfo, ProcId),
@@ -1033,9 +1033,9 @@
             %     (See exception_analysis.should_write_exception_info/4).
         ->
             analysis.record_result(ModuleId, FuncId, Call, Answer, optimal,
-                AnalysisInfo1, AnalysisInfo)
+                AnalysisInfo0, AnalysisInfo)
         ;
-            AnalysisInfo = AnalysisInfo1
+            AnalysisInfo = AnalysisInfo0
         ),
         module_info_set_analysis_info(AnalysisInfo, !ModuleInfo)
     ;

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