[m-rev.] diff: cache timestamps for analysis files

Peter Wang novalazy at gmail.com
Mon Jul 7 15:22:25 AEST 2008


Estimated hours taken: 1
Branches: main

In `mmc --make', use the timestamp cache for `.analysis' files as well.

compiler/make.util.m:
    	As above.
    
compiler/make.module_target.m:
    	After making an `.analysis' file, remove all known timestamps of
    	`.analysis' files from the cache as those entries may no longer be
    	valid.
    
    	Be verbose about deleting timestamps when `--debug-make' is enabled.

diff --git a/compiler/make.module_target.m b/compiler/make.module_target.m
index 2ef9876..d8a5055 100644
--- a/compiler/make.module_target.m
+++ b/compiler/make.module_target.m
@@ -79,6 +79,7 @@
 :- import_module transform_hlds.mmc_analysis.
 
 :- import_module dir.
+:- import_module svmap.
 
 %-----------------------------------------------------------------------------%
 
@@ -691,15 +692,28 @@ record_made_target_2(Succeeded, TargetFile, TouchedTargetFiles,
 
     list.foldl(update_target_status(TargetStatus), TouchedTargetFiles, !Info),
 
-    DeleteTimestamp =
-        (pred(TouchedFile::in, MakeInfo0::in, MakeInfo::out) is det :-
-            MakeInfo = MakeInfo0 ^ file_timestamps :=
-                map.delete(MakeInfo0 ^ file_timestamps, TouchedFile)
-        ),
     list.map_foldl2(get_file_name(no), TouchedTargetFiles,
         TouchedTargetFileNames, !Info, !IO),
-    list.foldl(DeleteTimestamp, TouchedTargetFileNames, !Info),
-    list.foldl(DeleteTimestamp, OtherTouchedFiles, !Info).
+
+    some [!Timestamps] (
+        !:Timestamps = !.Info ^ file_timestamps,
+        list.foldl(delete_timestamp, TouchedTargetFileNames, !Timestamps),
+        list.foldl(delete_timestamp, OtherTouchedFiles, !Timestamps),
+
+        % When an .analysis file is made, that potentially invalidates other
+        % .analysis files so we have to delete their timestamps.  The exact
+        % list of files which might be affected can be found by reading the
+        % corresponding .imdg file.  But it's simpler to just delete the
+        % timestamps of all the .analysis files that we know about.
+        ( TargetFile = target_file(_, module_target_analysis_registry) ->
+            map.foldl(delete_analysis_registry_timestamps, !.Timestamps,
+                !Timestamps)
+        ;
+            true
+        ),
+
+        !Info ^ file_timestamps := !.Timestamps
+    ).
 
 :- pred update_target_status(dependency_status::in, target_file::in,
     make_info::in, make_info::out) is det.
@@ -708,6 +722,30 @@ update_target_status(TargetStatus, TargetFile, !Info) :-
     Dep = dep_target(TargetFile),
     !Info ^ dependency_status ^ elem(Dep) := TargetStatus.
 
+:- pred delete_analysis_registry_timestamps(string::in,
+    maybe_error(timestamp)::in,
+    file_timestamps::in, file_timestamps::out) is det.
+
+delete_analysis_registry_timestamps(FileName, _, !Timestamps) :-
+    ( string.suffix(FileName, ".analysis") ->
+        delete_timestamp(FileName, !Timestamps)
+    ;
+        true
+    ).
+
+:- pred delete_timestamp(string::in, file_timestamps::in, file_timestamps::out)
+    is det.
+
+delete_timestamp(TouchedFile, !Timestamps) :-
+    trace [io(!IO)] (
+        debug_msg((pred(!.IO::di, !:IO::uo) is det :-
+            io.write_string("Deleting timestamp for ", !IO),
+            io.write_string(TouchedFile, !IO),
+            io.nl(!IO)
+        ), !IO)
+    ),
+    svmap.delete(TouchedFile, !Timestamps).
+
 %-----------------------------------------------------------------------------%
 
 :- type compilation_task_result == pair(compilation_task_type, list(string)).
diff --git a/compiler/make.util.m b/compiler/make.util.m
index 1af072f..ba1057a 100644
--- a/compiler/make.util.m
+++ b/compiler/make.util.m
@@ -960,44 +960,52 @@ get_dependency_timestamp(dep_target(Target), MaybeTimestamp, !Info, !IO) :-
         MaybeTimestamp = MaybeTimestamp0
     ).
 
-get_target_timestamp(Search, Target, MaybeTimestamp, !Info, !IO) :-
-    ( Target = target_file(ModuleName, module_target_analysis_registry) ->
-        get_target_timestamp_analysis_registry(Search, ModuleName,
+get_target_timestamp(Search, TargetFile, MaybeTimestamp, !Info, !IO) :-
+    TargetFile = target_file(_ModuleName, FileType),
+    get_file_name(Search, TargetFile, FileName, !Info, !IO),
+    ( FileType = module_target_analysis_registry ->
+        get_target_timestamp_analysis_registry(Search, TargetFile, FileName,
             MaybeTimestamp, !Info, !IO)
     ;
-        get_target_timestamp_2(Search, Target, MaybeTimestamp, !Info, !IO)
+        get_target_timestamp_2(Search, TargetFile, FileName, MaybeTimestamp,
+            !Info, !IO)
     ).
 
     % Special treatment for `.analysis' files.  If the corresponding
     % `.analysis_status' file says the `.analysis' file is invalid then we
     % treat it as out of date.
     %
-:- pred get_target_timestamp_analysis_registry(bool::in, module_name::in,
-    maybe_error(timestamp)::out, make_info::in, make_info::out,
+:- pred get_target_timestamp_analysis_registry(bool::in, target_file::in,
+    file_name::in, maybe_error(timestamp)::out, make_info::in, make_info::out,
     io::di, io::uo) is det.
 
-get_target_timestamp_analysis_registry(Search, ModuleName, MaybeTimestamp,
-        !Info, !IO) :-
-    analysis.read_module_overall_status(mmc, ModuleName, Status, !IO),
-    (
-        ( Status = optimal
-        ; Status = suboptimal
-        ),
-        get_target_timestamp_2(Search,
-            target_file(ModuleName, module_target_analysis_registry),
-            MaybeTimestamp, !Info, !IO)
+get_target_timestamp_analysis_registry(Search, TargetFile, FileName,
+        MaybeTimestamp, !Info, !IO) :-
+    TargetFile = target_file(ModuleName, _FileType),
+    ( MaybeTimestamp0 = !.Info ^ file_timestamps ^ elem(FileName) ->
+        MaybeTimestamp = MaybeTimestamp0
     ;
-        Status = invalid,
-        MaybeTimestamp = error("invalid module")
+        analysis.read_module_overall_status(mmc, ModuleName, Status, !IO),
+        (
+            ( Status = optimal
+            ; Status = suboptimal
+            ),
+            get_target_timestamp_2(Search, TargetFile, FileName,
+                MaybeTimestamp, !Info, !IO)
+        ;
+            Status = invalid,
+            MaybeTimestamp = error("invalid module"),
+            !Info ^ file_timestamps ^ elem(FileName) := MaybeTimestamp
+        )
     ).
 
-:- pred get_target_timestamp_2(bool::in, target_file::in,
+:- pred get_target_timestamp_2(bool::in, target_file::in, file_name::in,
     maybe_error(timestamp)::out, make_info::in, make_info::out,
     io::di, io::uo) is det.
 
-get_target_timestamp_2(Search, TargetFile, MaybeTimestamp, !Info, !IO) :-
+get_target_timestamp_2(Search, TargetFile, FileName, MaybeTimestamp,
+        !Info, !IO) :-
     TargetFile = target_file(ModuleName, FileType),
-    get_file_name(Search, TargetFile, FileName, !Info, !IO),
     (
         Search = yes,
         get_search_directories(FileType, SearchDirs, !IO)


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