[m-rev.] for review: speed up .opt file reading and deps
Peter Wang
novalazy at gmail.com
Tue Sep 2 11:50:08 AEST 2008
On 2008-09-01, Zoltan Somogyi <zs at csse.unimelb.edu.au> wrote:
> On 01-Sep-2008, Peter Wang <novalazy at gmail.com> wrote:
> > compiler/module_imports.m:
> > Change `module_imports' to hold items in a queue instead of a list.
>
> Why a queue? I would have thought that the natural data structure to use
> in this case is a cord.
I simply forgot about it. Here is a new diff. Note that one of the
test case expected outputs was changed slightly.
Branches: main
Change some data representations to avoid repeatedly appending lists when
reading optimisation interface files and calculating dependencies.
compiler/module_imports.m:
Change `module_imports' to hold items in a cord instead of a list.
Add getter/setter for items that work with lists, as most code will
continue to use lists.
Make `get_dependencies' and `get_dependencies_int_imp' accumulate
sets of modules instead of lists.
compiler/intermod.m:
Conform to `module_imports' changes.
Make `read_optimization_interfaces' accumulate cords of items
so that appending a list of items doesn't rebuild as big a list.
compiler/make.module_dep_file.m:
compiler/mercury_compile.m:
compiler/modules.m:
compiler/trans_opt.m:
compiler/write_deps_file.m:
Conform to `module_imports' changes.
tests/warnings/ambiguous_overloading.exp:
Update expected output, which was changed due to the `get_dependencies'
change.
diff --git a/compiler/intermod.m b/compiler/intermod.m
index 38a41c8..60009b0 100644
--- a/compiler/intermod.m
+++ b/compiler/intermod.m
@@ -122,6 +122,7 @@
:- import_module transform_hlds.inlining.
:- import_module assoc_list.
+:- import_module cord.
:- import_module getopt_io.
:- import_module int.
:- import_module map.
@@ -2289,13 +2290,15 @@ grab_opt_files(!Module, FoundError, !IO) :-
ModulesProcessed = set.insert(set.sorted_list_to_set(OptFiles),
ModuleName),
read_optimization_interfaces(Transitive, ModuleName, OptFiles,
- ModulesProcessed, [], OptItems, no, OptError, !IO),
+ ModulesProcessed, cord.empty, OptItemsCord, no, OptError, !IO),
+ OptItems = cord.list(OptItemsCord),
% Append the items to the current item list, using a `opt_imported'
% psuedo-declaration to let make_hlds know the opt_imported stuff
% is coming.
module_imports_get_items(!.Module, Items0),
- Items1 = Items0 ++ [make_pseudo_decl(md_opt_imported) | OptItems],
+ Items1 = Items0 ++ cord.from_list([
+ make_pseudo_decl(md_opt_imported) | OptItems]),
module_imports_set_items(Items1, !Module),
% Get the :- pragma unused_args(...) declarations created when writing
@@ -2318,7 +2321,8 @@ grab_opt_files(!Module, FoundError, !IO) :-
)
->
read_optimization_interfaces(no, ModuleName, [ModuleName],
- set.init, [], LocalItems, no, UA_SR_Error, !IO),
+ set.init, cord.empty, LocalItemsCord, no, UA_SR_Error, !IO),
+ LocalItems = cord.list(LocalItemsCord),
KeepPragma = (pred(Item::in) is semidet :-
Item = item_pragma(ItemPragma),
ItemPragma = item_pragma_info(_, Pragma, _, _),
@@ -2333,7 +2337,7 @@ grab_opt_files(!Module, FoundError, !IO) :-
list.filter(KeepPragma, LocalItems, PragmaItems),
module_imports_get_items(!.Module, Items2),
- list.append(Items2, PragmaItems, Items),
+ Items = Items2 ++ cord.from_list(PragmaItems),
module_imports_set_items(Items, !Module)
;
UA_SR_Error = no
@@ -2386,7 +2390,7 @@ grab_opt_files(!Module, FoundError, !IO) :-
:- pred read_optimization_interfaces(bool::in, module_name::in,
list(module_name)::in, set(module_name)::in,
- list(item)::in, list(item)::out, bool::in, bool::out,
+ cord(item)::in, cord(item)::out, bool::in, bool::out,
io::di, io::uo) is det.
read_optimization_interfaces(_, _, [], _, !Items, !Error, !IO).
@@ -2406,7 +2410,7 @@ read_optimization_interfaces(Transitive, ModuleName,
prog_io.read_opt_file(FileName, ModuleToRead, OptItems, Specs, ModuleError,
!IO),
update_error_status(opt_file, FileName, ModuleError, Specs, !Error, !IO),
- !:Items = !.Items ++ OptItems,
+ !:Items = !.Items ++ cord.from_list(OptItems),
maybe_write_string(VeryVerbose, "% done.\n", !IO),
globals.io_get_globals(Globals, !IO),
diff --git a/compiler/make.module_dep_file.m b/compiler/make.module_dep_file.m
index 90806c3..d36f050 100644
--- a/compiler/make.module_dep_file.m
+++ b/compiler/make.module_dep_file.m
@@ -53,6 +53,7 @@
:- import_module parse_tree.prog_out.
:- import_module assoc_list.
+:- import_module cord.
:- import_module dir.
:- import_module getopt_io.
:- import_module parser.
@@ -244,7 +245,8 @@ module_dependencies_version_number = 1.
write_module_dep_file(Imports0, !IO) :-
% Make sure all the required fields are filled in.
globals.io_get_globals(Globals, !IO),
- strip_imported_items(Imports0 ^ items, Items),
+ module_imports_get_items_list(Imports0, Items0),
+ strip_imported_items(Items0, Items),
init_dependencies(Imports0 ^ source_file_name,
Imports0 ^ source_file_module_name,
Imports0 ^ nested_children, no_module_errors, Globals,
@@ -476,7 +478,7 @@ read_module_dependencies_2(RebuildModuleDeps, SearchDirs, ModuleName, !Info,
Imports ^ has_foreign_code = ContainsForeignCode,
Imports ^ foreign_import_modules = ForeignImports,
Imports ^ contains_foreign_export = ContainsForeignExport,
- Imports ^ items = [], % not used.
+ Imports ^ items = cord.empty, % not used.
Imports ^ error = no_module_errors, % not used.
Imports ^ maybe_timestamps = no, % not used.
Imports ^ has_main = HasMain,
diff --git a/compiler/mercury_compile.m b/compiler/mercury_compile.m
index 530e1ec..ab714a9 100644
--- a/compiler/mercury_compile.m
+++ b/compiler/mercury_compile.m
@@ -1864,7 +1864,7 @@ pre_hlds_pass(ModuleImports0, DontWriteDFile0, HLDS1, QualInfo,
)
),
- module_imports_get_items(ModuleImports1, Items1),
+ module_imports_get_items_list(ModuleImports1, Items1),
MaybeTimestamps = ModuleImports1 ^ maybe_timestamps,
invoke_module_qualify_items(Items1, Items2, EventSpecMap1, EventSpecMap2,
diff --git a/compiler/module_imports.m b/compiler/module_imports.m
index 7967fb1..5e779f0 100644
--- a/compiler/module_imports.m
+++ b/compiler/module_imports.m
@@ -25,11 +25,14 @@
:- import_module parse_tree.prog_io. % for module_error;
% undesirable dependency
+:- import_module cord.
:- import_module list.
:- import_module map.
:- import_module maybe.
:- import_module pair.
+%-----------------------------------------------------------------------------%
+
% When doing smart recompilation record for each module the suffix of
% the file that was read and the modification time of the file.
%
@@ -109,7 +112,7 @@
contains_foreign_export :: contains_foreign_export,
% The contents of the module and its imports.
- items :: list(item),
+ items :: cord(item),
% Whether an error has been encountered when reading in
% this module.
@@ -132,10 +135,14 @@
is det.
:- pred module_imports_get_impl_deps(module_imports::in,
list(module_name)::out) is det.
-:- pred module_imports_get_items(module_imports::in, list(item)::out) is det.
+:- pred module_imports_get_items(module_imports::in, cord(item)::out) is det.
+:- pred module_imports_get_items_list(module_imports::in, list(item)::out)
+ is det.
:- pred module_imports_get_error(module_imports::in, module_error::out) is det.
-:- pred module_imports_set_items(list(item)::in,
+:- pred module_imports_set_items(cord(item)::in,
+ module_imports::in, module_imports::out) is det.
+:- pred module_imports_set_items_list(list(item)::in,
module_imports::in, module_imports::out) is det.
:- pred module_imports_set_error(module_error::in,
module_imports::in, module_imports::out) is det.
@@ -226,6 +233,7 @@
:- pred get_fact_table_dependencies(list(item)::in, list(string)::out) is det.
%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
:- implementation.
@@ -236,14 +244,20 @@
:- import_module bool.
:- import_module dir.
:- import_module set.
+:- import_module svset.
:- import_module term.
+%-----------------------------------------------------------------------------%
+
module_imports_get_source_file_name(Module, Module ^ source_file_name).
module_imports_get_module_name(Module, Module ^ module_name).
module_imports_get_impl_deps(Module, Module ^ impl_deps).
module_imports_get_items(Module, Module ^ items).
+module_imports_get_items_list(Module, cord.list(Module ^ items)).
module_imports_get_error(Module, Module ^ error).
module_imports_set_items(Items, Module, Module ^ items := Items).
+module_imports_set_items_list(Items, Module, Module ^ items := Cord) :-
+ Cord = cord.from_list(Items).
module_imports_set_error(Error, Module, Module ^ error := Error).
module_imports_set_int_deps(IntDeps, Module, Module ^ int_deps := IntDeps).
module_imports_set_impl_deps(ImplDeps, Module,
@@ -332,26 +346,31 @@ init_dependencies(FileName, SourceFileModuleName, NestedModuleNames,
ImplementationDeps, IndirectDeps, IncludeDeps,
InterfaceIncludeDeps, NestedDeps, FactTableDeps,
ContainsForeignCode, ForeignImports, ContainsPragmaExport,
- [], Error, no, HasMain, dir.this_directory).
+ cord.empty, Error, no, HasMain, dir.this_directory).
%-----------------------------------------------------------------------------%
get_dependencies(Items, ImportDeps, UseDeps) :-
- get_dependencies_implementation(Items,
- [], IntImportDeps, [], IntUseDeps, [], ImpImportDeps, [], ImpUseDeps),
+ get_dependencies_int_imp(Items, IntImportDeps, IntUseDeps,
+ ImpImportDeps, ImpUseDeps),
ImportDeps = IntImportDeps ++ ImpImportDeps,
UseDeps = IntUseDeps ++ ImpUseDeps.
get_dependencies_int_imp(Items, IntImportDeps, IntUseDeps,
ImpImportDeps, ImpUseDeps) :-
get_dependencies_implementation(Items,
- [], IntImportDeps, [], IntUseDeps, [], ImpImportDeps, [], ImpUseDeps).
+ set.init, IntImportDepsSet, set.init, IntUseDepsSet,
+ set.init, ImpImportDepsSet, set.init, ImpUseDepsSet),
+ IntImportDeps = set.to_sorted_list(IntImportDepsSet),
+ ImpImportDeps = set.to_sorted_list(ImpImportDepsSet),
+ IntUseDeps = set.to_sorted_list(IntUseDepsSet),
+ ImpUseDeps = set.to_sorted_list(ImpUseDepsSet).
:- pred get_dependencies_implementation(list(item)::in,
- list(module_name)::in, list(module_name)::out,
- list(module_name)::in, list(module_name)::out,
- list(module_name)::in, list(module_name)::out,
- list(module_name)::in, list(module_name)::out) is det.
+ set(module_name)::in, set(module_name)::out,
+ set(module_name)::in, set(module_name)::out,
+ set(module_name)::in, set(module_name)::out,
+ set(module_name)::in, set(module_name)::out) is det.
get_dependencies_implementation([],
!IntImportDeps, !IntUseDeps, !ImpImportDeps, !ImpUseDeps).
@@ -364,9 +383,9 @@ get_dependencies_implementation([Item | Items],
!IntImportDeps, !IntUseDeps, !ImpImportDeps, !ImpUseDeps)
;
( ModuleDefn = md_import(Modules) ->
- !:ImpImportDeps = !.ImpImportDeps ++ Modules
+ svset.insert_list(Modules, !ImpImportDeps)
; ModuleDefn = md_use(Modules) ->
- !:ImpUseDeps = !.ImpUseDeps ++ Modules
+ svset.insert_list(Modules, !ImpUseDeps)
;
true
),
@@ -379,10 +398,10 @@ get_dependencies_implementation([Item | Items],
).
:- pred get_dependencies_interface(list(item)::in,
- list(module_name)::in, list(module_name)::out,
- list(module_name)::in, list(module_name)::out,
- list(module_name)::in, list(module_name)::out,
- list(module_name)::in, list(module_name)::out) is det.
+ set(module_name)::in, set(module_name)::out,
+ set(module_name)::in, set(module_name)::out,
+ set(module_name)::in, set(module_name)::out,
+ set(module_name)::in, set(module_name)::out) is det.
get_dependencies_interface([],
!IntImportDeps, !IntUseDeps, !ImpImportDeps, !ImpUseDeps).
@@ -395,9 +414,9 @@ get_dependencies_interface([Item | Items],
!IntImportDeps, !IntUseDeps, !ImpImportDeps, !ImpUseDeps)
;
( ModuleDefn = md_import(Modules) ->
- !:IntImportDeps = !.IntImportDeps ++ Modules
+ svset.insert_list(Modules, !IntImportDeps)
; ModuleDefn = md_use(Modules) ->
- !:IntUseDeps = !.IntUseDeps ++ Modules
+ svset.insert_list(Modules, !IntUseDeps)
;
true
),
diff --git a/compiler/modules.m b/compiler/modules.m
index d0903e8..662ff49 100644
--- a/compiler/modules.m
+++ b/compiler/modules.m
@@ -377,6 +377,7 @@
:- import_module recompilation.version.
:- import_module char.
+:- import_module cord.
:- import_module dir.
:- import_module getopt_io.
:- import_module int.
@@ -417,7 +418,7 @@ make_private_interface(SourceFileName, SourceFileModuleName, ModuleName,
"`", FileName, "' not written.\n"], !IO)
;
% Module-qualify all items.
- module_imports_get_items(Module, Items1),
+ module_imports_get_items_list(Module, Items1),
globals.io_get_globals(Globals, !IO),
module_name_to_file_name(ModuleName, ".m", do_not_create_dirs,
FileName, !IO),
@@ -531,7 +532,7 @@ make_interface(SourceFileName, SourceFileModuleName, ModuleName,
ModuleName, !.InterfaceItems, Module0, Error, !IO),
% Check whether we succeeded.
- module_imports_get_items(Module0, !:InterfaceItems),
+ module_imports_get_items_list(Module0, !:InterfaceItems),
% XXX zs: why does this code not check for fatal_module_errors?
( Error = some_module_errors ->
module_name_to_file_name(ModuleName, ".int", do_not_create_dirs,
@@ -1741,7 +1742,7 @@ grab_imported_modules(SourceFileName, SourceFileModuleName, ModuleName,
[[make_pseudo_decl(md_interface) | InterfaceItems],
[make_pseudo_decl(md_private_interface) | ImplDecls],
[make_pseudo_decl(md_implementation) | Clauses]], Items1),
- module_imports_set_items(Items1, !Module)
+ module_imports_set_items_list(Items1, !Module)
),
% Add `builtin' and `private_builtin' to the list of imported modules.
@@ -1830,7 +1831,7 @@ grab_imported_modules(SourceFileName, SourceFileModuleName, ModuleName,
make_pseudo_decl(md_abstract_imported),
!Module, !IO),
- module_imports_get_items(!.Module, Items),
+ module_imports_get_items_list(!.Module, Items),
check_imports_accessibility(ModuleName,
IntImportedModules ++ IntUsedModules ++
ImpImportedModules ++ ImpUsedModules, Items, !Specs),
@@ -1928,7 +1929,7 @@ grab_unqual_imported_modules(SourceFileName, SourceFileModuleName, ModuleName,
some [!Specs] (
!:Specs = [],
- module_imports_get_items(!.Module, Items),
+ module_imports_get_items_list(!.Module, Items),
check_imports_accessibility(ModuleName,
IntImportDeps ++ IntUseDeps ++ ImpImportDeps ++ ImpUseDeps,
Items, !Specs),
@@ -1943,7 +1944,7 @@ grab_unqual_imported_modules(SourceFileName, SourceFileModuleName, ModuleName,
append_pseudo_decl(PseudoDecl, Module0, Module) :-
Items0 = Module0 ^ items,
- list.append(Items0, [make_pseudo_decl(PseudoDecl)], Items),
+ Items = cord.snoc(Items0, make_pseudo_decl(PseudoDecl)),
Module = Module0 ^ items := Items.
make_pseudo_decl(PseudoDecl) = Item :-
@@ -2787,7 +2788,7 @@ process_module_private_interfaces(ReadModules, [Ancestor | Ancestors],
get_dependencies(Items, AncDirectImports, AncDirectUses),
!:DirectImports = !.DirectImports ++ AncDirectImports,
!:DirectUses = !.DirectUses ++ AncDirectUses,
- ModItems = ModItems0 ++ Items,
+ ModItems = ModItems0 ++ cord.from_list(Items),
!:Module = !.Module ^ items := ModItems,
!:Module = !.Module ^ parent_deps := ModAncestors,
!:Module = !.Module ^ error := ModError,
@@ -2846,7 +2847,7 @@ process_module_long_interfaces(ReadModules, NeedQualifier, [Import | Imports],
++ IndirectUses1,
!:ImplIndirectImports = !.ImplIndirectImports
++ ImplIndirectImports1 ++ ImplIndirectUses1,
- ModItems = ModItems0 ++ Items,
+ ModItems = ModItems0 ++ cord.from_list(Items),
!:Module = !.Module ^ impl_deps := ModImplementationImports,
!:Module = !.Module ^ items := ModItems,
!:Module = !.Module ^ error := ModError,
@@ -3021,7 +3022,7 @@ process_module_short_interfaces(ReadModules, [Import | Imports], Ext,
ModIndirectImports = [Import | ModIndirectImports0],
!:IndirectImports = !.IndirectImports ++ IntImports1 ++ IntUses1,
!:ImpIndirectImports = !.ImpIndirectImports ++ ImpImports1 ++ ImpUses1,
- ModItems = ModItems0 ++ Items,
+ ModItems = ModItems0 ++ cord.from_list(Items),
!:Module = !.Module ^ indirect_deps := ModIndirectImports,
!:Module = !.Module ^ items := ModItems,
!:Module = !.Module ^ error := ModError,
@@ -3411,10 +3412,11 @@ init_module_imports(SourceFileName, SourceFileModuleName, ModuleName,
% module_imports.m is this call. This should be fixed, preferably
% by changing the module_imports structure.
maybe_add_foreign_import_module(ModuleName, Items0, Items),
+ ItemsCord = cord.from_list(Items),
Module = module_imports(SourceFileName, SourceFileModuleName,
ModuleName, [], [], [], [], [], PublicChildren,
NestedChildren, FactDeps, contains_foreign_code_unknown, [],
- contains_no_foreign_export, Items, no_module_errors,
+ contains_no_foreign_export, ItemsCord, no_module_errors,
MaybeTimestamps, no_main, dir.this_directory).
:- pred maybe_add_foreign_import_module(module_name::in,
diff --git a/compiler/trans_opt.m b/compiler/trans_opt.m
index cf5bbb8..097d992 100644
--- a/compiler/trans_opt.m
+++ b/compiler/trans_opt.m
@@ -107,6 +107,7 @@
:- import_module transform_hlds.trailing_analysis.
:- import_module assoc_list.
+:- import_module cord.
:- import_module list.
:- import_module map.
:- import_module pair.
@@ -197,18 +198,19 @@ grab_trans_opt_files(TransOptDeps, !Module, FoundError, !IO) :-
maybe_write_string(Verbose, "% Reading .trans_opt files..\n", !IO),
maybe_flush_output(Verbose, !IO),
- read_trans_opt_files(TransOptDeps, [], OptItems, no, FoundError, !IO),
+ read_trans_opt_files(TransOptDeps, cord.empty, OptItems, no, FoundError,
+ !IO),
append_pseudo_decl(md_opt_imported, !Module),
module_imports_get_items(!.Module, Items0),
- list.append(Items0, OptItems, Items),
+ Items = Items0 ++ OptItems,
module_imports_set_items(Items, !Module),
module_imports_set_error(no_module_errors, !Module),
maybe_write_string(Verbose, "% Done.\n", !IO).
-:- pred read_trans_opt_files(list(module_name)::in, list(item)::in,
- list(item)::out, bool::in, bool::out, io::di, io::uo) is det.
+:- pred read_trans_opt_files(list(module_name)::in, cord(item)::in,
+ cord(item)::out, bool::in, bool::out, io::di, io::uo) is det.
read_trans_opt_files([], !Items, !Error, !IO).
read_trans_opt_files([Import | Imports], !Items, !Error, !IO) :-
@@ -229,7 +231,7 @@ read_trans_opt_files([Import | Imports], !Items, !Error, !IO) :-
intermod.update_error_status(trans_opt_file, FileName, ModuleError,
Specs, !Error, !IO),
- list.append(!.Items, NewItems, !:Items),
+ !:Items = !.Items ++ cord.from_list(NewItems),
read_trans_opt_files(Imports, !Items, !Error, !IO).
%-----------------------------------------------------------------------------%
diff --git a/compiler/write_deps_file.m b/compiler/write_deps_file.m
index dee2a1b..904a9f0 100644
--- a/compiler/write_deps_file.m
+++ b/compiler/write_deps_file.m
@@ -75,6 +75,7 @@
string::in, list(module_name)::out, io::di, io::uo) is det.
%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
:- implementation.
@@ -91,12 +92,15 @@
:- import_module parse_tree.source_file_map.
:- import_module assoc_list.
+:- import_module cord.
:- import_module dir.
:- import_module library.
:- import_module map.
:- import_module string.
:- import_module pair.
+%-----------------------------------------------------------------------------%
+
write_dependency_file(Module, AllDepsSet, MaybeTransOptDeps, !IO) :-
Module = module_imports(SourceFileName, SourceFileModuleName,
ModuleName, ParentDeps, IntDeps, ImplDeps, IndirectDeps,
@@ -513,7 +517,7 @@ write_dependency_file(Module, AllDepsSet, MaybeTransOptDeps, !IO) :-
ForeignImports = ForeignImports0
;
ContainsForeignCode = contains_foreign_code_unknown,
- get_item_list_foreign_code(Globals, Items, LangSet,
+ get_item_list_foreign_code(Globals, cord.list(Items), LangSet,
ForeignImports1, _),
% If we're generating the `.dep' file, ForeignImports0 will contain
% a conservative approximation to the set of foreign imports
diff --git a/tests/warnings/ambiguous_overloading.exp b/tests/warnings/ambiguous_overloading.exp
index 328bca1..3bd2a56 100644
--- a/tests/warnings/ambiguous_overloading.exp
+++ b/tests/warnings/ambiguous_overloading.exp
@@ -31,8 +31,8 @@ ambiguous_overloading.m:056: The following symbol was overloaded in the
ambiguous_overloading.m:056: following contexts.
ambiguous_overloading.m:050: The predicate symbol predicate `<'/2.
ambiguous_overloading.m:050: The possible matches are:
-ambiguous_overloading.m:050: predicate `float.<'/2,
-ambiguous_overloading.m:050: predicate `int.<'/2.
+ambiguous_overloading.m:050: predicate `int.<'/2,
+ambiguous_overloading.m:050: predicate `float.<'/2.
ambiguous_overloading.m:051: The predicate symbol predicate `<'/2 is also
ambiguous_overloading.m:051: overloaded here.
ambiguous_overloading.m:052: The predicate symbol predicate `<'/2 is also
--------------------------------------------------------------------------
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