Files
mercury/compiler/make.deps_set.m
Zoltan Somogyi c2f92d5454 Partition extensions into ".m" and "all others".
This is a first step towards a much finer grained partition.

compiler/file_names.m:
    Split the ext type into ext_src and ext_other, as mentioned above.

    Add the first predicate for checking whether a string falls into
    a given category of extensions.

    Add an XXX proposing a better solution for an old problem that does not
    actually arise in practice.

compiler/compile_target_code.m:
    Split the two-moded predicate maybe_pic_object_file_extension into
    two separate one-mode predicates, one for each old mode. The
    implementations of the two modes were already separate, because
    the two modes already did different jobs: while one went from PIC
    to an "extension", the other went from an "extension string" to PIC.
    Until now, "extension" and "extension string" were equivalent;
    after this diff, they aren't anymore.

    Delete an unused argument.

compiler/make.util.m:
    Split the two-moded predicate target_extension into
    two separate one-mode predicates, one for each old mode,
    for the same reason as maybe_pic_object_file_extension above:
    the fact that "extension" and "extension string" are now distinct.

compiler/options_file.m:
    Move debug infrastructure here from mercury_compile_main.m, to help
    debug possible problems with options files. (I had such a problem
    while writing this diff.)

    Improve how progress messages are printed.

compiler/options.m:
    Make an error message more useful.

compiler/mercury_compile_main.m:
    Add infrastructure for debugging possible problems with command lines.
    (I had such a problem while writing this diff.)

compiler/analysis.m:
    Conform to the changes above. Put the arguments of some methods
    into the same order as similar predicates in file_names.m.

compiler/find_module.m:
    Conform to the changes above. Delete an unused argument,

compiler/analysis.file.m:
compiler/du_type_layout.m:
compiler/elds_to_erlang.m:
compiler/export.m:
compiler/fact_table.m:
compiler/file_kind.m:
compiler/generate_dep_d_files.m:
compiler/grab_modules.m:
compiler/llds_out_file.m:
compiler/make.build.m:
compiler/make.deps_set.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
compiler/mmc_analysis.m:
compiler/mode_constraints.m:
compiler/module_cmds.m:
compiler/prog_foreign.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/source_file_map.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
2020-08-17 23:43:15 +10:00

251 lines
8.6 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 2002-2011 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%---------------------------------------------------------------------------%
%
% File: make.deps_set.m.
%
% Dependency computation does a lot of unions so we use a set representation
% suited to that purpose, namely bitsets. We can't store module_names and
% dependency_files in those sets, so we keep two maps
%
% module_name <-> module_index, and
% dependency_file <-> dependency_file_index
%
% in the make_info structure, and work with sets of indices instead.
%
%---------------------------------------------------------------------------%
:- module make.deps_set.
:- interface.
:- import_module bool.
:- import_module enum.
:- import_module io.
:- import_module set.
:- import_module sparse_bitset.
%---------------------------------------------------------------------------%
% sparse_bitset is faster than tree_bitset by my tests.
%
:- type deps_set(T) == sparse_bitset(T).
% :- type deps_set(T) == tree_bitset(T).
:- type module_index.
:- instance enum(module_index).
:- type dependency_file_index.
:- instance enum(dependency_file_index).
%---------------------------------------------------------------------------%
% Convert a module_name to a module_index.
%
:- pred module_name_to_index(module_name::in, module_index::out,
make_info::in, make_info::out) is det.
% Convert a list of module_names to a module_index set.
%
:- pred module_names_to_index_set(list(module_name)::in,
deps_set(module_index)::out,
make_info::in, make_info::out) is det.
% Convert a module_index to a module_name.
%
:- pred module_index_to_name(make_info::in,
module_index::in, module_name::out) is det.
% Convert a module_index set to a module_name set.
%
:- pred module_index_set_to_plain_set(make_info::in,
deps_set(module_index)::in, set(module_name)::out) is det.
%---------------------------------------------------------------------------%
% Convert a dependency file to a dependency_file_index.
%
:- pred dependency_file_to_index(dependency_file::in,
dependency_file_index::out, make_info::in, make_info::out) is det.
% Convert a list of dependency files to a dependency_file_index set.
%
:- pred dependency_files_to_index_set(list(dependency_file)::in,
deps_set(dependency_file_index)::out, make_info::in, make_info::out)
is det.
% Convert a dependency_file_index set to a dependency_file set.
%
:- pred dependency_file_index_set_to_plain_set(make_info::in,
deps_set(dependency_file_index)::in, set(dependency_file)::out) is det.
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- implementation.
:- import_module libs.
:- import_module libs.file_util.
:- import_module libs.globals.
:- import_module make.util.
:- import_module parse_tree.
:- import_module parse_tree.file_names.
:- import_module dir.
:- import_module int.
:- import_module maybe.
%---------------------------------------------------------------------------%
%
% Bitset indices.
%
:- type module_index
---> module_index(int).
:- type dependency_file_index
---> dependency_file_index(int).
:- instance enum(module_index) where [
to_int(module_index(I)) = I,
from_int(I) = module_index(I)
].
:- instance enum(dependency_file_index) where [
to_int(dependency_file_index(I)) = I,
from_int(I) = dependency_file_index(I)
].
%---------------------------------------------------------------------------%
module_name_to_index(ModuleName, Index, !Info) :-
Map0 = !.Info ^ module_index_map,
Map0 = module_index_map(Forward0, _Reverse0, _Size0),
( if version_hash_table.search(Forward0, ModuleName, Index0) then
Index = Index0
else
Map0 = module_index_map(_Forward0, Reverse0, Size0),
Index = module_index(Size0),
Size = Size0 + 1,
version_hash_table.det_insert(ModuleName, Index, Forward0, Forward),
TrueSize = version_array.size(Reverse0),
( if Size > TrueSize then
NewSize = increase_array_size(TrueSize),
version_array.resize(NewSize, ModuleName, Reverse0, Reverse)
else
version_array.set(Size0, ModuleName, Reverse0, Reverse)
),
Map = module_index_map(Forward, Reverse, Size),
!Info ^ module_index_map := Map
).
:- func increase_array_size(int) = int.
increase_array_size(N) = (if N = 0 then 1 else N * 2).
%---------------------%
module_names_to_index_set(ModuleNames, IndexSet, !Info) :-
module_names_to_index_set_2(ModuleNames,
sparse_bitset.init, IndexSet, !Info).
:- pred module_names_to_index_set_2(list(module_name)::in,
deps_set(module_index)::in, deps_set(module_index)::out,
make_info::in, make_info::out) is det.
module_names_to_index_set_2([], !IndexSet, !Info).
module_names_to_index_set_2([ModuleName | ModuleNames], !Set, !Info) :-
module_name_to_index(ModuleName, ModuleIndex, !Info),
sparse_bitset.insert(ModuleIndex, !Set),
module_names_to_index_set_2(ModuleNames, !Set, !Info).
%---------------------------------------------------------------------------%
module_index_to_name(Info, Index, ModuleName) :-
Info ^ module_index_map = module_index_map(_Forward, Reverse, _Size),
Index = module_index(I),
ModuleName = version_array.lookup(Reverse, I).
%---------------------%
module_index_set_to_plain_set(Info, ModuleIndices, Modules) :-
foldl(module_index_set_to_plain_set_2(Info), ModuleIndices,
set.init, Modules).
:- pred module_index_set_to_plain_set_2(make_info::in, module_index::in,
set(module_name)::in, set(module_name)::out) is det.
module_index_set_to_plain_set_2(Info, ModuleIndex, !Set) :-
module_index_to_name(Info, ModuleIndex, ModuleName),
set.insert(ModuleName, !Set).
%---------------------------------------------------------------------------%
dependency_file_to_index(DepFile, Index, !Info) :-
Map0 = !.Info ^ dep_file_index_map,
ForwardMap0 = Map0 ^ dfim_forward_map,
( if version_hash_table.search(ForwardMap0, DepFile, Index0) then
Index = Index0
else
Map0 = dependency_file_index_map(Forward0, Reverse0, Size0),
Index = dependency_file_index(Size0),
Size = Size0 + 1,
version_hash_table.det_insert(DepFile, Index, Forward0, Forward),
TrueSize = version_array.size(Reverse0),
( if Size > TrueSize then
NewSize = increase_array_size(TrueSize),
version_array.resize(NewSize, DepFile, Reverse0, Reverse)
else
version_array.set(Size0, DepFile, Reverse0, Reverse)
),
Map = dependency_file_index_map(Forward, Reverse, Size),
!Info ^ dep_file_index_map := Map
).
%---------------------%
dependency_files_to_index_set(DepFiles, DepIndexSet, !Info) :-
list.foldl2(dependency_files_to_index_set_2, DepFiles,
init, DepIndexSet, !Info).
:- pred dependency_files_to_index_set_2(dependency_file::in,
deps_set(dependency_file_index)::in, deps_set(dependency_file_index)::out,
make_info::in, make_info::out) is det.
dependency_files_to_index_set_2(DepFiles, !Set, !Info) :-
dependency_file_to_index(DepFiles, DepIndex, !Info),
insert(DepIndex, !Set).
%---------------------------------------------------------------------------%
:- pred index_to_dependency_file(make_info::in, dependency_file_index::in,
dependency_file::out) is det.
index_to_dependency_file(Info, Index, DepFile) :-
Info ^ dep_file_index_map =
dependency_file_index_map(_Forward, Reverse, _Size),
Index = dependency_file_index(I),
DepFile = version_array.lookup(Reverse, I).
%---------------------%
dependency_file_index_set_to_plain_set(Info, DepIndices, DepFiles) :-
foldl(dependency_file_index_set_to_plain_set_2(Info), DepIndices,
[], DepFilesList),
DepFiles = set.list_to_set(DepFilesList).
:- pred dependency_file_index_set_to_plain_set_2(make_info::in,
dependency_file_index::in,
list(dependency_file)::in, list(dependency_file)::out) is det.
dependency_file_index_set_to_plain_set_2(Info, DepIndex, List0, List) :-
index_to_dependency_file(Info, DepIndex, DepFile),
List = [DepFile | List0].
%---------------------------------------------------------------------------%
:- end_module make.deps_set.
%---------------------------------------------------------------------------%