Commit Graph

127 Commits

Author SHA1 Message Date
Zoltan Somogyi
8e62f93c4d Use maps for several kinds of items in interface file parse trees.
Using lists to store type-, inst- and mode definitions, foreign enum
definitions and type representation items does nothing to enforce
uniqueness requirements, such as "every inst constructor should have
at most one one non-abstract definition in the interface of a module".
However, one can encode such requirements using maps.

This diff therefore changes the representation of these kinds of items
inside the interface-kind-specific parse trees of interface files to use
these kinds of maps. It does not take advantage of the possilities
offered by this diff; that is for a later change.

compiler/prog_item.m:
    Make the change described above.

    Since after this diff, the info in foreign_enum pragmas will be in a map,
    while the info in other kinds of pragmas will still be in a list, avoid
    the possibility of being able to represent invalid states by giving
    foreign enums their own item kind, separate from that of pragmas.
    Since foreign export enums are handled very similarly to foreign enum
    pragmas in many places, given them their own item kind as well.

    Update the predicates converting generic interface file parse trees
    to interface-kind-specific parse trees, and vice versa, to conform
    to the changes above.

compiler/comp_unit_interface.m:
    Convert lists to maps before putting them into interface-kind-specific
    parse trees where the above change requires it.

compiler/hlds_module.m:
    Delete types that contain almost exactly the same info as the item
    information we now keep for foreign enum and foreign export enum items.

    Include the item status next to foreign enum items, since that is the
    one piece of info the deleted types had that we need.

compiler/parse_pragma.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_pragma.m:
    Parse and print out foreign enums and foreign export enums as their
    own item kinds, not as kinds of pragmas.

compiler/add_foreign_enum.m:
compiler/canonicalize_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qual_errors.m:
compiler/module_qual.qualify_items.m:
compiler/prog_item_stats.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the changes above.
2019-09-12 03:52:10 +10:00
Zoltan Somogyi
cb5a1d5d6e Parse interface files via bespoke representations.
We used to read all kinds of interface files (.int0, .int, .int2 and .int3)
into the same representation, parse_tree_int. This diff makes the first step
towards returning the contents of each kind of interface file in its own
bespoke parse tree type, parse_tree_intN for N in {0,1,2,3}.

compiler/parse_module.m:
    Read in the contents of interface files using a cut-down grammar.
    The main changes are:

    - the file must start with a ":- module" declaration;
    - the start of each section must be an explicit section marker;
    - there can be at most two sections, the first an interface section
      and the second an implementation section, in that order,
      either (or both) of which can be missing;
    - version number maps are expected to be *before* the first section;
    - there cannot be any submodules;
    - there cannot be any source_file pragmas anywhere.

    Each of these changes enforces an invariant that is observed by the code
    constructing and writing out the automatically generated interface files.
    The change makes many invalid interface file contents unrepresentable.

    Add predicates for reading each kind interface file to its own
    bespoke parse tree type. These new predicates are not yet used.

    Change the generic predicate for reading in interface files
    to convert the generic parse_tree_int it generates to the given interface
    file's own specific parse tree type, and back. This *should* be an
    identity operation, but it generates an error message whenever it finds
    an entity of a kind that shouldn't be there. Print these messages
    unless inhibited by an option.

    This back-and-forth is intended to be temporary. Once we have sufficient
    experience with the system to be confident it works, i.e. it does not
    miscompile anything and never generates any of these diagnostics,
    we should be able to switch to using the kind-specific parse tree types
    exclusively.

compiler/options.m:
    Add that option, halt-at-invalid-interface, for now, enabled by default.
    We should be able to delete the option, making its effects permanent,
    when we make the switch mentioned above.

compiler/prog_item.m:
    Modify the representation of import_module and use_module declarations
    in .int0 files a bit to match their representations in other kinds of
    interface files.

    Add predicates to convert a parse_tree_int to each parse_tree_intN
    for N in {0,1,2,3}, generating error messages if they contain
    any kind of entity that they shouldn't contain.

    Add functions for describing such entities in the error messages.

    Add some other auxiliary functions, and field names, needed by
    the rest of this change.

compiler/file_kind.m:
    Replace ifk_int with ifk_int1, because we consistently use numeric
    suffixes after interface file kinds everywhere else. (Partly this is
    to disambiguate "int" as short for "interface file", not for
    "interface section of a module".

compiler/parse_types.m:
    Provide a mechanism to describe all entities read in during parsing,
    not just those that end up in parse trees, for use in error messages
    in parse_module.m.

compiler/comp_unit_interface.m:
compiler/deps_map.m:
compiler/grab_modules.m:
compiler/make_hlds_error.m:
compiler/module_qual.qual_errors.m:
    Conform to the changes above.
2019-09-05 11:49:17 +10:00
Zoltan Somogyi
a39adc549d Centralize decisions about which aux preds a mutable needs.
The implementation of a mutable requires several predicates, some user visible,
some not. Exactly what set of predicates a mutable needs depends both on its
attributes and on the target platform. Previously, we computed that set of
predicates three times:

- when adding their declarations to the HLDS,
- when adding their definitions to the HLDS, and
- when adding (a subset of) their declarations to a .int0 file.

This diff tries to centralizes these decisions in one place. It does not
quite get there, because getting there would require compromises that are
undesirable for other reasons, but it gets close.

compiler/prog_data.m:
    Document the uses of the various kinds of predicates we can generate
    for a mutable.

compiler/prog_mutable.m:
    Add a predicate that decides which public auxiliary predicates
    a mutable needs, for use by both add_mutable_aux_preds.m and by
    comp_unit_interface.m.

    Add a predicate that constructs the pred_decl item of any given
    mutable auxiliary predicate, again for use by add_mutable_aux_preds.m
    and by comp_unit_interface.m.

    Move predicates that are used only by add_mutable_aux_preds.m
    to add_mutable_aux_preds.m.

    Delete predicates that are no longer needed.

compiler/add_mutable_aux_preds.m:
    Add a predicate that decides which private auxiliary predicates
    a mutable needs,

    Use the new mechanisms above to declare a mutable's auxiliary procedures.

    Use the new mechanisms above to define a mutable's auxiliary procedures,
    mostly. There is still some code that repeats the logic of the decision
    predicate for public auxiliary predicates, but now a sanity check
    ensures that the two decision procedures arrived at the same result.

    Move predicates that are used only by add_mutable_aux_preds.m
    here from prog_mutable.m.

    Delete predicates that are no longer needed.

    Give several predicates more descriptive names. Standardize
    argument orders.

compiler/add_pred.m:
    Add a mechanism for adding a pred_decl item as a whole to the HLDS.
    (Previously, we could a pred_decl to the HLDS by first breaking it down
    to its components.) The code is mostly copied from make_hlds_passes.m.

compiler/comp_unit_interface.m:
    Use the new mechanisms above to declare a mutable's auxiliary procedures.
    The new code does not need any knowledge of what auxiliary predicates
    a mutable needs.

compiler/make_hlds_passes.m:
    Use the new mechanism in add_pred.m, in order to avoid code duplication.

library/set.m:
    Add a new predicate for add_mutable_aux_preds.m.
2019-09-01 18:22:06 +10:00
Zoltan Somogyi
18d5c48076 Add comments describing possible future improvements. 2019-08-30 11:45:12 +10:00
Zoltan Somogyi
2b6709bc67 Put type_repn items for simple types into .int2 files.
compiler/comp_unit_interface.m:
    If the experiment1 option is set, we used to put type_repn items
    for simple types into .int3 files.

    With this diff, under the same conditions, we also put type_repn items
    for simple types into .int2 files, which are mostly module qualified
    versions of .int3 files.

compiler/equiv_type.m:
    Do not abort when asked to expand equivalence types in type_repn items,
    since such items from .int2 files *do* end up being passed here.
2019-08-29 14:49:10 +10:00
Zoltan Somogyi
d33555a0bf Generate .int0 files via a bespoke representation.
compiler/prog_item.m:
    Define a type that represents the possible contents of .int0 files.

    Provide a way to convert from this new representation to the generic
    interface file representation.

compiler/comp_unit_interface.m:
    Generate the contents of .int0 files using the new bespoke representation.
2019-08-28 23:05:39 +10:00
Zoltan Somogyi
fbe63c9b67 Switch permanently to minimal FIMs in .int2 files. 2019-08-27 22:15:30 +10:00
Zoltan Somogyi
c45719f5cb Don't report errors when creating interface files.
When deciding the contents of interface files, we used to generate
messages for these three kinds of errors:

- clauses in the module interface
- not-allowed-in-the-interface pragmas in the module interface
- empty module interface

None of these affected the interface file we were building, and their
reporting can easily be delayed until we are compiling the affected module
to target language code. At that time, the error messages get put into
.err files, whereas any messages printed when creating interface files
tends to get lost in the overall sea of compiler invocation messages
when running mmake.

compiler/comp_unit_interface.m:
    Do not generate error messages when building the contents of interface
    files.

compiler/write_module_interface_files.m:
    Do not print the error messages that are no longer being generated.
    We *do* still print any of the other kinds of error messages we have
    been printing, such as for those when a needed .int3 file cannot be read,
    or when ambiguity prevents full module qualification. (The contents of
    .int and .int2 files must be fully module qualified to do their jobs.)

compiler/add_pragma.m:
    Report an error when processing a pass 3 pragma that occurs in the
    interface but is not allowed in the interface.

    add_pragma.m has already been doing this for all other kinds of pragmas,
    and in general, compiler invocations that generate target language code
    do generate the messages for all the conditions whose messages we are
    no longer printing when generating interface files.

tests/invalid/bad_item_in_interface.{m,err_exp}:
tests/invalid/ft_examples:
    A new test case to test the above assertion with respect to
    inappropriate items in the interface of a module.

tests/invalid/empty_interface.{m,err_exp}:
    A new test case to test the above assertion with respect to
    the interface of a module being empty.

tests/invalid/Mercury.options:
    Specify the right options for the empty_interface test case.

tests/invalid/Mmakefile:
    Enable the new test cases.
2019-08-27 06:06:17 +10:00
Zoltan Somogyi
0399f0d9fe Simplify some code.
compiler/comp_unit_interface.m:
    The original form of the affected code was there to allow a potential
    future change. That change turns out not to work.
2019-08-24 18:27:12 +10:00
Zoltan Somogyi
5266d61514 Restrict foreign_import_modules in .int2 files to the minimum needed.
compiler/comp_unit_interface.m:
    Do the above if the experiment3 option is set, which is the default.
2019-08-24 10:32:11 +10:00
Zoltan Somogyi
5b43964b06 Create and use bespoke parse trees for .int and .int2 files.
For now, we construct the contents of those files using the new bespoke types,
but convert them to the general parse_tree_int type when that is done.

Later changes should extend the use of the bespoke types to the later
processing of interface file contents (computation of version number maps,
standardization, and writing out) as well as their processing when
being read in.

compiler/prog_item.m:
    Create the bespoke types parse_tree_int1 and parse_tree_int2
    for the parse trees of .int and .int2 files respectively.
    These types make explicit significantly more of the structural invariants
    required of the contents of these interface files than the old general
    parse_tre_int type.

    Add conversion functions from the new bespoke types to that general type.

    Create a bespoke type for representing version number fields,
    mainly to provide a central place for documenting how such fields
    are filled in.

    Make predicate definition order match predicate declaration order.

compiler/comp_unit_interface.m:
    When generating .int and .int2 files, create their contents as values
    of the new bespoke types, converting them to the general parse_tree_int
    type when that is done.

compiler/module_imports.m:
compiler/parse_module.m:
compiler/parse_tree_out.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/write_module_interface_files.m:
    Conform to the change in version number representation.
2019-08-23 15:57:43 +10:00
Zoltan Somogyi
615d2795c8 Take foreign_import_modules out of the item type.
compiler/prog_item.m:
    Even though we express foreign import module declarations syntactically
    as pragmas, semantically, they are much closer to import_module
    declarations. This means that the treatment they require in most places
    in the compiler is similar to the treatment of import_module declarations,
    and quite different from the treatment of other kinds of items.
    Therefore this diff takes foreign_import_module declarations (FIMs
    for short) out of item type. From now on, in parse trees and their
    components, FIMs are stored in data structures of their own, next to
    import_module declarations.

compiler/parse_types.m:
    Provide a mechanism for the parser to return FIMs as an entity kind
    of its own, not as an item.

compiler/comp_unit_interface.m:
    Conform to the changes above, and give a predicate a more specific name.

compiler/module_qual.m:
    Conform to the changes above, and require .int3 files to contain no FIMs.

compiler/canonicalize_interface.m:
compiler/check_raw_comp_unit.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/hlds_module.m:
compiler/item_util.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/module_imports.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/parse_module.m:
compiler/parse_pragma.m:
compiler/parse_tree_out.m:
compiler/prog_item_stats.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/split_parse_tree_src.m:
    Conform to the changes above.
2019-08-22 09:31:10 +10:00
Zoltan Somogyi
8d493ad4d2 Add two comments. 2019-08-21 14:40:04 +10:00
Zoltan Somogyi
8ebc3c5dc3 Delete predicates that recently became dead. 2019-08-21 14:34:37 +10:00
Zoltan Somogyi
899abd6fb2 Switch to the new algorithm for generating .int2 files.
Delete the possibility of switching back to the old algorithm.
2019-08-20 19:17:04 +10:00
Zoltan Somogyi
4d60e1a2a6 Convert all import_modules in .int files into use_modules permanently.
compiler/comp_unit_interface.m:
    Do the above conversion without requiring the experiment3 option to be set.
2019-08-16 14:42:55 +10:00
Zoltan Somogyi
8f47f23581 The second step in reducing .int2 files to essentials.
Like the first, it aims to eliminate all the items from .int2 files
that do not need to be there.

compiler/comp_unit_interface.m:
    Modify the algorithm we use to generate .int2 files if the option
    experiment4 is set to "yes" (which it is by default). The modification
    is to include a use_module declaration for a module in the interface
    of the .int2 file only if an item we are including in that interface
    refers to that module.
2019-08-15 13:46:26 +10:00
Zoltan Somogyi
bd369d63be Factor out common code. 2019-08-07 01:45:55 +02:00
Zoltan Somogyi
f0dda66a70 Give a predicate a better name. 2019-08-06 22:58:39 +02:00
Zoltan Somogyi
8a25de8b63 Move a predicate to the only module where it is used. 2019-08-06 14:46:34 +02:00
Zoltan Somogyi
45d6c5bde3 The first step in reducing .int2 files to essentials.
This change, and later changes, aim to eliminate all the items
from .int2 files that do not need to be there.

compiler/comp_unit_interface.m:
    If the option experiment4 is set to "yes", switch to a modified algorithm
    for computing the contents of .int2 files. As a first step, this eliminates
    from implementation sections all items other than type definitions,
    and all import_module and use_module declarations. The interface section
    is left as is, for now.

compiler/options.m:
    Set the default value of experiment4 to "yes".
2019-08-06 14:40:59 +02:00
Zoltan Somogyi
19034b3b1a Start using a bespoke type for .int3 parse trees.
compiler/prog_item.m:
    Define parse_tree_int3, a type that represents the parse trees
    of .int3 files. It enforces several structural invariants that
    the old parse_tree_int type (which was designed to represent the
    contents of *all* interface files) does not: the absence of anything
    in the implementation section, the absence of use_module declarations,
    the absence of repeated include_module or import_module declarations,
    and the absence of any items other than the (a) the definitions of
    types, insts, modes, typeclasses and instances, and later
    (b) type_repn items.

    Define a function to convert from parse_tree_int3s to parse_tree_ints.

    Define auxiliaty predicates and functions now needed by
    comp_unit_interface.m, and similar predicates and functions
    for related types, that may be needed later.

compiler/comp_unit_interface.m:
    Compute the contents of .int3 files into parse_tree_int3s.
    Translate these to parse_tree_ints for the rest of the compiler,
    which does use the new type yet.

compiler/decide_type_repn.m:
    Return type representation information for .int3 files
    in the format required by the updated code in comp_unit_interface.m.

compiler/write_module_interface_files.m:
    Ignore the new parse_tree_int3 returned by comp_unit_interface.m
    until the rest of this module has been taught to use it.
2019-08-04 20:47:03 +02:00
Zoltan Somogyi
a6367d23b4 Give a field a more expressive name.
compiler/prog_item.m:
    Rename the tc_constraints field of typeclass items to tc_superclasses.

compiler/comp_unit_interface.m:
compiler/parse_class.m:
    Conform to this change.
2019-08-04 15:39:09 +02:00
Zoltan Somogyi
3486d32734 Convert all import_modules in .int files into use_modules.
compiler/comp_unit_interface.m:
    If the option experiment3 is set, then replace all import_module
    declarations in .int files with use_module declarations.

compiler/options.m:
    Set experiment3 to true by default.

compiler/notes/interface_files.html:
    Document that we do this, and why.
2019-08-04 15:36:36 +02:00
Zoltan Somogyi
b063063713 Generate .int2 files using the mechanism for .int3 files, experimentally.
compiler/write_module_interface_files.m:
    If the right experiment option is set, when we generate m.int2,
    generate m.int2.via3 as well, using the same algorithm we use
    to generate .int3 files. This new file is not used anywhere.
    It is purely an experiment, one that allows us to compare the
    advertised nature of .int2 files (as fully module qualified versions
    of .int3 files) with the reality.

    Modify a service predicate to make the above possible, and to delete
    a long-unused argument.

compiler/options.m:
    Add a bunch of boolean experiment options, to control this and other
    (upcoming) experiments. Update the documentation of the experiment
    options.

compiler/comp_unit_interface.m:
    Add a predicate for generating .int2 files using the algorithm we use
    for .int3 files.

    Switch to using one the new, bool experiment options for an existing
    experiment.
2019-08-04 14:31:36 +02:00
Zoltan Somogyi
64199df56b Compute which modules to import in .int files more directly.
compiler/comp_unit_interface.m:
    Instead of computing (a) a set of modules we should import in the interface
    and (b) *whether* we need to import *any* modules in the interface,
    switch to using just (a). Part (b) was flawed anyway. Besides saying
    that items that added modules to (a) needed imported modules, it also
    said that e.g. definitions of dummy and enum types needed imported modules,
    which they do not.

    Switch from handling imports and uses as lists of items
    to handling them as sets of the names of imported and used modules.
    Given the four sets
        imported in interface
        used in interface
        imported in implementation
        used in implementation
    we use this to ensure that
    (a) no module can appear more than once in a set, and
    (b) no module can appear in more than one set.

    Add XXXs documenting possible further improvements.

    Separate the two jobs of make_imp_type_abstract.

compiler/notes/interface_files.html:
    Describe what import_module and use_module declarations
    we put into .int files.
2019-08-02 08:29:03 +02:00
Zoltan Somogyi
3b9faa901c Update more documentation. 2019-07-31 09:10:08 +02:00
Zoltan Somogyi
bca36c02f8 Update comments. 2019-07-31 09:04:08 +02:00
Zoltan Somogyi
704701cc37 Simplify the code putting foreign_import_modules into .int files.
compiler/comp_unit_interface.m:
    Decide what foreign_import_modules (FIMs) items we need to put
    into .int files when we decide to put into the .int file
    the item (e.g. the definition of a foreign type) that *needs* the FIM.
    This means gathering information about which FIMs are needed
    during the pass that processes all the items in the .m file,
    instead of separate later passes over all items.

    Switch from handling these FIMs as lists to handling them as sets,
    with respect to both FIMs that are explicit in the .m file, and those
    that are implicitly needed. This eliminates the possibility of
    including the same FIM in the .int file twice.

    Put both explicit and implicit FIMs from each section of the .m file
    into the corresponding section of the .int file.

    Do not put into the implementation section of the .int file
    a FIM item that we put into its interface section.

    Clarify in variable names which section we are processing.

    Disambiguate the func vs pred versions of some calls to init.
2019-07-31 08:55:07 +02:00
Zoltan Somogyi
36074cb0f6 Fix typo. 2019-07-17 14:42:04 +02:00
Zoltan Somogyi
e75c7225e3 Move the pre-grab computation of implicit FIMs to post-grab.
compiler/comp_unit_interface.m:
    We used to compute the set of foreign_import_modules implicitly needed
    by a module, and add them to the module's items, both *before* we grabbed
    the imported modules and used them to module qualify the current module,
    and *after*.

    There was never any need to do any of this work pre-grab, because
    neither the grabbing process nor module qualification pays any attention
    to foreign_import_modules: they neither modify them nor do they base
    any decisions on their presence or absence.

    This diff just moves the pre-grab code to run post-grab. Unifying
    this moved code with the original post-grab code for adding implicit
    foreign_import_modules is the next step.
2019-07-17 14:31:55 +02:00
Zoltan Somogyi
f252bddf4a Improve comp_unit_interface.m.
compiler/comp_unit_interface.m:
    Include a foreign_enum pragma in the .int file if *any* of its
    exported definitions is non-abstract. Previously, we required it
    to have *exactly one* exported definition, which does not allow
    for a redundant declaration as well as a du definition.

    Abort if we find a solver type definition in the interface
    *after* we are supposed to have converted all such definitions
    to abstract types.

    Inline a function in its only caller.

    Give some variables and predicates more descriptive names.

    Clarify some comments. Add some XXXs where relevant.
2019-07-16 10:24:06 +02:00
Zoltan Somogyi
43ebb15bbc Move a predicate to where it is used.
compiler/comp_unit_interface.m:
    Move a predicate here from item_util.m, since it is used only here.

    Inline a one-line predicate from item_util.m.

compiler/item_util.m:
    Delete the moved predicate, the inlined predicate (since it has no calls
    left to it), and a third predicate that has been dead for a while.
2019-07-11 13:57:26 +02:00
Zoltan Somogyi
9c6c421cf9 Avoid a compiler abort.
When making .int files, do not abort when we find a mutable, initialise
or finalise in the interface.
2019-07-11 13:52:20 +02:00
Zoltan Somogyi
84f1715972 Delete unused predicates. 2019-07-05 11:13:02 +02:00
Zoltan Somogyi
b6a5a97335 Module qualify .int3 files just once.
compiler/module_qual.m:
    Rename module_qualify_parse_tree_int as module_qualify_parse_tree_int3,
    since it is used only to module qualify .int3 files.

    Resolve an old XXX inside it about the treatment of implementation sections
    by requiring the implementation section to be empty (which it always is
    in .int3 files).

compiler/comp_unit_interface.m:
    Conform to the change above.

compiler/write_module_interface_files.m:
    Don't call module_qualify_parse_tree_int3, since the predicate in
    comp_unit_interface we just called has already done that.
2019-06-30 12:16:50 +02:00
Zoltan Somogyi
0b0976b801 Record imports from an ancestor's interface as such.
compiler/comp_unit_interface.m:
    When constructing .int0 files, we used to copy all import_module
    declarations in the interface to the implementation as well.

    Remove this duplication.

    Without this duplication, the invalid/import_in_parent test case
    used to fail. The changes to the following files are about fixing
    the underlying cause of the failure that this duplication worked around.

compiler/prog_item.m:
    That cause was the limited expressiveness of the statuses we associate
    with items. It recorded modules imported in ancestor's interfaces
    as if they were imported in the current module's OWN interface.

    Fix this limitation, by expanding the import_locn type to include
    the interfaces of ancestor modules.

compiler/modules.m:
    When reading in .int0 files, mark the items in their interfaces
    as coming from the interface of an ancestor, not as coming from
    the interface of THIS module.

compiler/make_hlds_passes.m:
    Treat modules imported by an ancestor in the interface the same as
    modules imported by an ancestor in the implementation. The lack of this
    equal treatment was the cause of the need for the above workaround
    to make invalid/import_in_parent work.

compiler/du_type_layout.m:
compiler/hlds_out_util.m:
compiler/module_qual.collect_mq_info.m:
compiler/status.m:
    Conform to the change in prog_item.m.
2019-06-29 19:00:58 +02:00
Zoltan Somogyi
a26d93e201 Factor out common code. 2019-06-26 15:07:02 +02:00
Zoltan Somogyi
19fa71b594 Put only necessary info into .int3 files.
This pulls the changes from the interface_files git branch onto master.

compiler/comp_unit_interface.m:
    Put abstract forms of insts and modes into .int3 files.

    Strip superclasses from class decls in .int3s.

    Delete redundant fields from a structure.

    Delete XXXs based on a misunderstanding.

    Delete an obsolete comment.

compiler/get_dependencies.m:
    Fix a comment.

compiler/modules.m:
    Add each section's implicit imports to its OWN section when reading
    interface files (.int and .int2 files). (Until now, we added
    all implicit dependencies to the interface section, including those
    that were required only by the implementation section.)

    Don't duplicate abstract instance decls from int to imp.

    Delete XXXs based on a misunderstanding.
2019-06-25 22:39:06 +02:00
Zoltan Somogyi
0c1068ef56 Don't put use_module items into .int3 files.
compiler/comp_unit_interface.m:
    As above. They are not needed, since modules made accessible by
    ":- use_module" declarations should never be used to module qualify names.

compiler/notes/interface_files.html:
    Document the change to .int3 files (and implicitly the lack of change,
    for now, to the rest of the compiler).
2019-06-12 20:06:22 +02:00
Zoltan Somogyi
7e5c8e586c Prepare for deciding type representations for complex types.
compiler/decide_type_repn.m:
    A later change will put into .int/.int2 files type representation items
    that report the representation of complex types. For this, the compiler
    will need to know the representation of *all* the simple types in the
    module, not just the exported ones. Make this information available
    to a future caller.

compiler/comp_unit_interface.m:
    Conform to the change above.
2019-06-06 19:46:14 +02:00
Zoltan Somogyi
e9430b115a Prep for recording simple type representations in .int3 files.
compiler/decide_type_repn.m:
    New module for computing the set of type representation items
    to put into the interface files of a module. For now, it generates
    this information only for .int3 files.

compiler/parse_tree.m:
compiler/notes/compiler_design.html:
    Add the new module to the parse_tree package.

compiler/comp_unit_interface.m:
    Invoke the new module to add type representation items to .int3 files
    if the experiment option has the right value. Give it the information
    it needs to do its job.

compiler/add_foreign_enum.m:
    Export a predicate for use by decide_type_repn.m. Maybe eventually
    it should be *moved* to decide_type_repn.m.

compiler/hlds_data.m:
compiler/prog_data.m:
    Change the representation of lists of constructors in a type
    from lists, which can be empty, with one_or_more, which cannot.
    This encodes the invariant that a type constructor cannot have
    zero data constructors in the structure of the type.

compiler/prog_item.m:
    Change the representation of lists of constructors in a type
    from lists, which can be empty, with one_or_more, which cannot.
    This encodes the invariant that a type constructor cannot have
    zero data constructors in the structure of the type.

    Include information about assertions in type representation items
    about foreign types.

    Do not record whether a type whose representation item says its values
    are guaranteed to be word aligned is a Mercury type or a foreign type.
    We generate such items only for Mercury types; for foreign types,
    their assertions will contain that information. We need this separation
    because when we generate .int3 files, we don't the backend that we will
    eventually generate code for, and thus do not know whether a given
    foreign type declaration is in effect on that backend or not.

compiler/parse_tree_out.m:
    Fix the printing of type representation items.

compiler/prog_type.m:
    Conform to the changes above, and delete an unused predicate.

compiler/parse_type_repn.m:
    Factor out some common code.

    Fix an old bug about yes/no vs du_repn/no_du_repn.

    Conform to the changes above.

compiler/parse_pragma.m:
    Export a predicate for parse_type_repn.m.

    Note a possible improvement.

    Conform to the changes above.

compiler/add_special_pred.m:
compiler/add_type.m:
compiler/check_typeclass.m:
compiler/det_report.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/mode_util.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out_pragma.m:
compiler/parse_type_defn.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_util.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.

compiler/simplify_goal_ite.m:
    Add a comment.

compiler/canonicalize_interface.m:
compiler/get_dependencies.m:
    Do not abort when seeing type representation items.

compiler/mmakefiles.m:
    Delete a predicate that this diff adds to list.m.

library/list.m:
    Add new predicates to convert from one_or_more to list
    and vice versa.

NEWS:
    Announce the new predicates.

library/bimap.m:
library/map.m:
library/tree234.m:
    Expand a comment.
2019-05-27 11:45:10 +02:00
Zoltan Somogyi
9867404681 Don't export a predicate unnecessarily. 2019-05-18 14:28:35 +02:00
Zoltan Somogyi
a745ed5dd9 Delete a predicate ...
... that recent changes have made unused, and make the simplifications
that this change makes possible.
2019-05-02 14:45:15 +10:00
Zoltan Somogyi
995dd51705 Switch to the new code constructing initial ModuleAndImports.
compiler/modules.m:
    Delete the old code for constructing the initial values
    of ModuleAndImports in the grab_*qual_modules predicates.

    Delete also the checks comparing the output of the old and the new code,
    the auxiliary predicates needed only by the old code, and the new_
    prefixes on predicate and variable names.

    Put related predicates next to each other.

compiler/comp_unit_interface.m:
compiler/get_dependencies.m:
    Delete predicates that were needed only by the deleted code.

compiler/prog_item.m:
    Add an auxiliary predicate needed by the new code, now that its
    output is used for more than just sanity checks.

    Export a predicate to allow the deletion of its duplicate.

    Update a comment.
2019-04-24 16:53:24 +10:00
Zoltan Somogyi
466bcfbc5c Add direct code for creating module_and_imports structures.
compiler/modules.m:
    The two main top-level predicates in this module grab the
    qualified and unqualified interface files respectively of the modules
    that the given raw compilation unit depends on.

    Before the grabbing part can begin, they both need to create
    the initial version of the module_and_imports structure.
    The code they use to do this is hard to understand for several reasons:

    - they do this in many separate passes over the compilation unit's
      item blocks;
    - some of those passes are over *modified* versions of the item blocks;
    - many of the passes are in other modules.

    This diff adds new code to do the same job more directly:

    - the new code has many fewer passes;
    - none of those passes are over modified data structures;
    - all the code is in modules.m.

    For a transition period, execute both the old and new code,
    and require their output to be the same (modulo irrelevant details)
    as a sanity check.

    At the end of that period, we should be able to delete the sanity check,
    the code of the old algorithm in modules.m, and the predicates in other
    modules whose only caller was the old algorithm.

compiler/comp_unit_interface.m:
    Export a predicate for use by the new code in modules.m.

    Add a note about soon-to-be-obsolete code.

compiler/get_dependencies.m:
    Export several related predicates, and the types they need,
    for use by the new code in modules.m.

    Simplify those predicates by not making them record a context
    for the module names they collect. The context being recorded
    was always a dummy, which is not useful.

    Add a note about soon-to-be-obsolete code.

compiler/hlds_module.m:
compiler/module_qual.m:
    Conform to the change in get_dependencies.m.

compiler/module_imports.m:
    Conform to the change in get_dependencies.m.

    Note possibilities for future improvement.
2019-04-20 05:05:51 +10:00
Zoltan Somogyi
b70bdb2d95 Delete the context field from item_blocks.
compiler/prog_item.m:
    The context field in item_blocks was used only in setting the context
    fields of other item blocks. There was no end user, and many places
    that created item_blocks ab initio put a dummy value into the field
    anyway, so this diff deletes the field.

    The intent is to prepare for future changes to the module_and_imports
    structure that replace lists of item blocks, each which may be
    of any section, with just one list of items, one list of includes
    and one list of avails per section kind.

    In some places, this should allow us to avoid searching item blocks
    for the right sections; in other places, it should allow us to replace
    two nested loops (on blocks and on e.g. items) with just one loop
    (e.g. on items).

    We do still record section contexts during parsing, because this is
    needed for the context of some error messages (e.g. the one we generate
    for an implementation section in a submodule that is included in the
    interface section of its parent module).

compiler/check_raw_comp_unit.m:
compiler/comp_unit_interface.m:
compiler/deps_map.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_separate_items.m:
compiler/module_imports.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.m:
compiler/module_qual.qualify_items.m:
compiler/modules.m:
compiler/parse_module.m:
compiler/parse_tree_out.m:
compiler/prog_item_stats.m:
compiler/recompilation.check.m:
compiler/split_parse_tree_src.m:
    Conform to the change above.
2019-04-16 06:16:52 +10:00
Zoltan Somogyi
f149a2ca5a Simplify the code in modules.m creating module_and_imports structures.
compiler/modules.m:
    The old predicate make_initial_module_and_imports did two almost
    completely different jobs for its two different callers. Inline it
    into its two callers, simplifying each copy.

compiler/comp_unit_interface.m:
    Centralize the decision about whether we add the foreign_import_module
    items needed by a list of item blocks to the interface or to the
    implementation to two adjacent predicates (the maximum extent possible,
    given that we need to handle the interface/implementation distinction
    in two separate types). Mark both sites, and a related third site,
    with a FIM_SECTION marker, to help later changes.

    Simplify the interface of the predicates involved in the above
    by deleting a redundant argument.

compiler/module_imports.m:
    Delete an argument for which the caller always passed the same value.
2019-04-16 02:57:52 +10:00
Zoltan Somogyi
399dce00fe Fix an old inconsistency.
compiler/comp_unit_interface.m:
    When splitting a raw_comp_unit into interface and implementation,
    don't put parts of the implementation into a section marked
    "ms_interface" by mistake.

compiler/modules.m:
    Add a sanity check for this, and delete the old XXX that explained
    the reason why it wouldn't work until now.
2019-04-15 05:05:48 +10:00
Zoltan Somogyi
de0a5f13b7 Delete item_nothing.
compiler/prog_item.m:
    Delete item_nothing as an alternative in the item type.

    These items never occur in parse trees, being handled fully at the time
    when the parse tree is constructed. Nevertheless, their presence in
    the item type required code that handles parse trees to worry NOW about
    how they should handle item_nothings in case a possible future change
    let them survive the parse tree construction process.

compiler/parse_types.m:
    Replace item_nothing with iom_handled in the item_or_marker type,
    whose values are used only during the parse tree construction process.

    The replacement is significantly simplified compared with the original,
    containing only the functionality that our current use cases need.

compiler/parse_error.m:
    Remove rme_warn_item_nothing from the read_module_error type.
    It was being added to error sets, but nothing ever tested for its presence.
    Its task as a signifier of the presence of a compilation-stopping error
    now belongs to the severity of the associated error_specs.

compiler/parse_item.m:
    Fix the logic of the code that decides whether the format of the
    version_numbers_map item is recorded in an obsolete format
    (i.e. whether its *own* version is too old). Specificially,
    treat non-numerical "version number" terms as being malformed,
    not as being obsolete.

compiler/canonicalize_interface.m:
compiler/check_raw_comp_unit.m:
compiler/comp_unit_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/item_util.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/modules.m:
compiler/parse_module.m:
compiler/parse_pragma.m:
compiler/parse_tree_out.m:
compiler/prog_item_stats.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the changes above.
2019-04-15 03:30:15 +10:00