[m-rev.] for review: Cache dependency sets computed by imports_012.

Peter Wang novalazy at gmail.com
Wed Dec 7 15:16:50 AEDT 2022


The imports_012 opreation computes the union of three subsets.
Since it is called frequently for the same modules, it can be worth
reusing a previously computed result.

This change improves the run time of a do-nothing build of Prince using
mmc --make on my machine from 1.20 s to 0.86 s.

compiler/make.dependencies.m:
    Add code to support caching of dependency sets computed from other
    dependency sets.

    Enabling caching in imports_012.

compiler/make.make_info.m
compiler/make.top_level.m
    Add a field to make_info to hold the cache results.

diff --git a/compiler/make.dependencies.m b/compiler/make.dependencies.m
index e4175cc6d..54c4aabe6 100644
--- a/compiler/make.dependencies.m
+++ b/compiler/make.dependencies.m
@@ -168,6 +168,9 @@
 :- type cached_transitive_dependencies.
 :- func init_cached_transitive_dependencies = cached_transitive_dependencies.
 
+:- type cached_computed_module_deps.
+:- func init_cached_computed_module_deps = cached_computed_module_deps.
+
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
 
@@ -385,11 +388,14 @@ compiled_code_dependencies(Globals) = Deps :-
 :- func imports_012 =
     (find_module_deps(dependency_file_index)::out(find_module_deps)) is det.
 
-imports_012 = combine_deps_list([
-        module_target_int0 `of` ancestors,
-        module_target_int1 `of` direct_imports,
-        module_target_int2 `of` indirect_imports
-    ]).
+imports_012 =
+    cache_computed_module_deps(computed_module_deps_import_012,
+        combine_deps_list([
+            module_target_int0 `of` ancestors,
+            module_target_int1 `of` direct_imports,
+            module_target_int2 `of` indirect_imports
+        ])
+    ).
 
 %---------------------------------------------------------------------------%
 
@@ -944,6 +950,32 @@ combine_deps_list([FindDeps]) = FindDeps.
 combine_deps_list([FindDeps1, FindDeps2 | FindDepsTail]) =
     combine_deps(FindDeps1, combine_deps_list([FindDeps2 | FindDepsTail])).
 
+%---------------------------------------------------------------------------%
+
+    % cache_computed_module_deps(Label, FindDeps) adds caching to FindDeps.
+    % Label is used to discriminate cache entries for the same module;
+    % it must uniquely identify the set that is computed by FindDeps.
+    %
+:- pred cache_computed_module_deps(computed_module_deps_label::in,
+    find_module_deps(dependency_file_index)::in(find_module_deps),
+    globals::in, module_index::in, maybe_succeeded::out,
+    deps_set(dependency_file_index)::out, make_info::in, make_info::out,
+    io::di, io::uo) is det.
+
+cache_computed_module_deps(Label, FindDeps, Globals, ModuleIndex, Succeeded,
+        Deps, !Info, !IO) :-
+    Cache0 = !.Info ^ mki_cached_computed_module_deps,
+    Key = computed_module_deps_key(ModuleIndex, Label),
+    ( if map.search(Cache0, Key, CachedResult) then
+        CachedResult = deps_result(Succeeded, Deps)
+    else
+        FindDeps(Globals, ModuleIndex, Succeeded, Deps, !Info, !IO),
+        Cache1 = !.Info ^ mki_cached_computed_module_deps,
+        Result = deps_result(Succeeded, Deps),
+        map.det_insert(Key, Result, Cache1, Cache),
+        !Info ^ mki_cached_computed_module_deps := Cache
+    ).
+
 %---------------------------------------------------------------------------%
 
     % XXX Document me.
@@ -1557,6 +1589,20 @@ init_cached_transitive_foreign_imports = map.init.
 
 init_cached_transitive_dependencies = map.init.
 
+:- type cached_computed_module_deps ==
+    map(computed_module_deps_key, deps_result(dependency_file_index)).
+
+:- type computed_module_deps_key
+    --->    computed_module_deps_key(
+                module_index,
+                computed_module_deps_label
+            ).
+
+:- type computed_module_deps_label
+    --->    computed_module_deps_import_012.
+
+init_cached_computed_module_deps = map.init.
+
 %---------------------------------------------------------------------------%
 :- end_module make.dependencies.
 %---------------------------------------------------------------------------%
diff --git a/compiler/make.make_info.m b/compiler/make.make_info.m
index 3be860673..9909344c9 100644
--- a/compiler/make.make_info.m
+++ b/compiler/make.make_info.m
@@ -111,6 +111,11 @@
                 mki_cached_transitive_foreign_imports
                                         :: cached_transitive_foreign_imports,
 
+                % This cache holds dependency sets that are a simple
+                % computation (union) on other dependency sets.
+                mki_cached_computed_module_deps
+                                        :: cached_computed_module_deps,
+
                 % Should the `.module_dep' files be rebuilt?
                 % Set to `do_not_rebuild_module_deps' for `mmc --make clean'.
                 mki_rebuild_module_deps :: rebuild_module_deps,
diff --git a/compiler/make.top_level.m b/compiler/make.top_level.m
index a4ecc9c67..3d386e870 100644
--- a/compiler/make.top_level.m
+++ b/compiler/make.top_level.m
@@ -138,6 +138,7 @@ make_process_compiler_args(Globals, DetectedGradeFlags, Variables, OptionArgs,
             init_cached_indirect_imports,
             init_cached_transitive_dependencies,
             init_cached_transitive_foreign_imports,
+            init_cached_computed_module_deps,
             ShouldRebuildModuleDeps,
             KeepGoing,
             ErrorFileModules,
-- 
2.38.0



More information about the reviews mailing list