Commit Graph

442 Commits

Author SHA1 Message Date
Zoltan Somogyi
ffb963b30f Add code to write parse trees to a string.
Traditionally, we always wrote out parse trees (of .intN files, for example)
to a file. However, we have also supported being able to write out *parts*
of parse trees to strings, because that ability is useful e.g.

- in error messages, printing the code that the error message is about,
- when debugging.

We are considering a use case which requires the ability to write out
the *whole* parse tree of a .intN file to a string. That use case is
comparing whether the old and new versions of a .intN file are identical
or not, because we want to update the actual .intN file only if they
differ. (Updating the .intN file if they are identical could trigger
the unnecessary recompilation of an unbounded number of other modules.)

Previously, we have done this comparison by writing out the new parse tree
to an .intN.tmp file, and compared it to the .intN file. It should be simpler
and quite possibly faster to

- read in the old .intN file as a string
- convert the new parse tree to a string
- compare the two strings
- write out the new string if and only if it differs from the old string.

This should be especially so if we can open the .intN file in read-write mode,
so the file would need to be opened just once, in step one, even if we do
need to write out the new parse tree in step four.

compiler/parse_tree_out.m:
    Add functions to convert parse_tree_int[0123]s to strings.

    To avoid having to reimplement all the code that currently writes
    out those parse trees, convert the current predicates that always do I/O
    into predicates that use the methods of the existing pt_output type class,
    which, depending on the selected instance, can either do I/O or can build
    up a string. This conversion has already been done for the constructs
    that make up some parts of those parse trees; this diff extends the
    conversion to every construct that is part of parse trees listed above.

    As part of our existing conventions, predicates that have been
    generalized in this way have the "output" or "write" in their names
    replaced with "format".

    We also perform this generalization for the predicates that write out
    parse_tree_srcs and parse_tree_module_srcs, because doing so requires
    almost no extra code.

compiler/parse_item.m:
compiler/parse_tree_out_clause.m:
compiler/parse_tree_out_info.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_out_misc.m:
compiler/parse_tree_out_pragma.m:
compiler/parse_tree_out_pred_decl.m:
compiler/parse_tree_out_type_repn.m:
compiler/prog_ctgc.m:
    Perform the generalization discussed above, both on predicates
    that write out Mercury constructs, and on some auxiliary predicates.

    In a few cases, the generalized versions already existed but were private,
    in which case this diff just exports them.

    In a few cases, rename predicates to avoid ambiguities.

compiler/add_clause.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_type_table.m:
compiler/hlds_out_typeclass_table.m:
compiler/intermod.m:
compiler/intermod_analysis.m:
    Conform to the changes above.
2023-11-01 19:53:40 +11:00
Zoltan Somogyi
a0967ee14c Carve var_table_hlds.m out of hlds_pred.m.
compiler/hlds_pred.m:
compiler/var_table_hlds.m:
    Move operations on var_tables from hlds_pred.m to the new module
    var_table_hlds.m. They can't go into var_table.m, because that module
    is in the parse_tree module, and cannot access the HLDS.

compiler/hlds.m:
    Add the new module to the HLDS package.

compiler/notes/compiler_design.html:
    Document the new module.

compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/build_mode_constraints.m:
compiler/higher_order.m:
compiler/hlds_out_pred.m:
compiler/intermod.m:
compiler/intermod_analysis.m:
compiler/mode_constraints.m:
compiler/old_type_constraints.m:
compiler/post_typecheck.m:
compiler/prop_mode_constraints.m:
compiler/typecheck.m:
compiler/unify_proc.m:
    Conform to the changes above.
2023-09-01 14:18:24 +10:00
Zoltan Somogyi
b2ba2dd917 Extend and fix the code for dumping insts.
The motivation for this diff is something I saw when I fixed the bug in
equiv_type_hlds.m on aug 13. During the bootcheck to verify the bug fix,
I enabled the end-of-front-end HLDS dump, and I saw that one module,
deep_profiler/display_report.m, had some references to MISSING_INSTs
in its HLDS dump. Since these could be signs of a bug in mode analysis,
I tracked them down. It turns out that the cause was an incompatibility
between the code that existed in error_msg_inst.m before that fix,
and the new code there added by that fix. But ironically, to find that
incompatibility, I first had to extend error_msg_inst.m's functionality
still further, specifically to make it possible to use it to write out insts
in HLDS dumps.

The reason for this need is that that the old code for dumping out insts
left a lot to be desired. It ignored (as in, it never wrote out) some parts
of specific kinds insts, such as the types in typed insts, without which
some parts of HLDS dumps did not make sense. For example, the ground inst
table in the HLDS dump of display_report.m contained several keys whose
printed versions were identical, seemingly indicating a bug in the code
that added new entries to that table (since it is supposed to add a new entry
to the table if the relevant key does not yet exist in the table). It turns
out that there was no bug; the keys differed, but only in the types.

compiler/error_msg_inst.m:
    Fix the incompatibility, and document both it, and its solution.

    Besides error_msg_inst, export a new function error_msg_inst_name,
    which does the same thing for inst_names as error_msg_inst does for insts.

    Add a flag to both functions that specifies whether the intended use
    of the return value is in an error message (whose audience is usually
    an ordinary Mercury user) or a HLDS dump (whose audience is always
    a Mercury developer). Include details such as the types in typed insts,
    and the structure of the compiler-generated inst names generally,
    which involve concepts that users do not know about, in the output
    only if the flag says the audience is Mercury developers.

    When printing out type or inst variables, use their actual names
    if these are available. To make this possible, require the callers
    of error_msg_{inst,inst_name} to provide tvarsets and inst_varsets,
    instead of always using empty varsets. The caller may still pass
    empty varsets if cannot do better than that, but most callers can,
    and now do pass valid varsets.

compiler/hlds_out_goal.m:
    Since we now want to pass a valid tvarset to error_msg_inst.m
    when printing the insts in goals' instmap_deltas, we need to pass around
    the tvarset, as well as the inst_varset, of the procedure that the goal
    was taken from. Instead of adding yet another parameter to all the affected
    predicates, replace all the existing parameters that have the same role
    (of which there were already about half a dozen) with a parameter
    of a new type named hlds_out_info_goal, which contains the values of
    all these old parameters, and the new one.

compiler/hlds_out_inst_table.m:
    Use the same setting to govern whether we use error_msg_inst.m's
    facilities for writing out insts and inst names in both the keys
    and the values of the various inst tables.

compiler/simplify_info.m:
    Include tvarsets in simplify_infos, since dumping out goals during
    simplification pass can now use this information.

compiler/add_clause.m:
compiler/add_mutable_aux_preds.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/direct_arg_in_out.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/hlds_out_pred.m:
compiler/inst_abstract_unify.m:
compiler/inst_lookup.m:
compiler/intermod.m:
compiler/lco.m:
compiler/liveness.m:
compiler/make_hlds_warn.m:
compiler/mode_errors.m:
compiler/pd_debug.m:
compiler/prog_mode.m:
compiler/push_goals_together.m:
compiler/saved_vars.m:
compiler/simplify_goal.m:
compiler/simplify_goal_conj.m:
compiler/simplify_proc.m:
compiler/stack_opt.m:
compiler/superhomogeneous.m:
compiler/unneeded_code.m:
    Conform to the changes above.
2023-08-31 16:25:31 +10:00
Zoltan Somogyi
0922461444 Include type_ctors in some iftc error conditions.
compiler/hlds_inst_mode.m:
    Modify the set of function symbols in the inst_for_type_ctor (iftc) type,
    in a way that allows the semantics of each function symbol to be descrribed
    exactly.

    Some of the new function symbols preserve the identity of the type_ctor
    originally recorded by the programmer for the inst. This allows the fixing
    of bug in the computation of the set of imported modules used by
    the current module.

compiler/inst_check.m:
    Update the code setting up the value of the iftc slot in inst definitions.

compiler/unused_imports.m:
    Apply that fix.

compiler/add_mode.m:
compiler/intermod.m:
compiler/recompilation.usage.m:
    Conform to the changes in hlds_inst_mode.m.
2023-08-11 15:23:20 +02:00
Zoltan Somogyi
9d38b252bf Separate marker pragmas from other decl/impl pragmas.
compiler/prog_item.m:
    Previously, both decl and impl pragmas contained some pragma kinds
    that contained only the specification of a predicate or function.
    These served only to specify a marker to be applied to the named
    predicate or function.

    This diff separates out those kinds of pragmas from the types of
    both the decl pragmas and the impl pragmas (the difference is that
    decl pragmas may appear in module interfaces, while impl pragmas may not),
    and gives them two new representations: decl markers and impl markers.

    While in the old representation, each kind of marker had its own wrapper
    around the predicate/function specification, in the new representation,
    they are side-by-side, which allows simpler construction techniques
    and smaller code.

    Update the definition of parse_tree_module_src, parse_tree_plain_opt,
    parse_tree_int0 and parse_tree_int1 to include markers alongside
    pragmas of each kind. Use subtypes to restrict the kinds of markers
    that can appear in parse_tree_plain_opts to the set that we actually
    can put into them. (Source files of course can contain any markers,
    and .intN files either get put into them either all of the markers
    that occur in the source file in a given section, or none of them.)

    Delete the item_pragma_info type, which was a wrapper around
    the specific info of each pragma, and stored a context and an item
    sequence number alongside it. Move the context and the item sequence
    number into the representation of each pragma. This should reduce
    visual clutter in the source code at places that construct or deconstruct
    pragmas, and at runtime (with direct args) it should reduce both
    the number of memory cells we need to allocate, and the number
    of pointers we need to follow.

    Include decl vs impl in the names of some function symbols.

    Partly to counteract that, shorten some names to avoid excessive
    line lengths.

compiler/add_pragma.m:
    Add predicates to add decl and impl markers.

    Move the predicates looping over lists of pragma next to the
    predicates handling those pragmas.

compiler/make_hlds_passes.m:
    Add both decl and impl markers before adding foreign_procs.
    The ability to do this was the original motivation for this diff.
    Update the comments both about this issue, and about why we delay
    adding tabling pragmas to the HLDS.

compiler/check_module_interface.m:
    Conform to the changes above.

    Add an XXX about something fishy.

compiler/item_util.m:
    Delete aux functions that are no longer needed.

compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/comp_unit_interface.m:
compiler/convert_parse_tree.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/hlds_module.m:
compiler/intermod.m:
compiler/intermod_analysis.m:
compiler/make_hlds_separate_items.m:
compiler/mercury_compile_middle_passes.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qual_errors.m:
compiler/module_qual.qualify_items.m:
compiler/parse_pragma.m:
compiler/parse_pragma_analysis.m:
compiler/parse_pragma_foreign.m:
compiler/parse_pragma_tabling.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_pragma.m:
compiler/prog_item_stats.m:
compiler/prog_mutable.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/unused_args.m:
    Conform to the changes above.
2023-08-06 12:33:55 +02:00
Zoltan Somogyi
155bc71d72 Make foreign_procs their own top-level item kind.
compiler/prog_item.m:
    Change foreign_procs from being one kind of impl_pragma item
    to being their own item kind. Because of this, the changes to
    some of the modules listed below delete "pragma" from the names
    of predicates and types referring to foreign_procs.

    Include foreign_proc items in parse_tree_module_srcs and
    parse_tree_plain_opts, the two kinds of parse trees that may contain
    foreign_procs.

compiler/make_hlds_separate_items.m:
    Gather foreign procs independently of impl pragmas.

compiler/make_hlds_passes.m:
    Add foreign_procs from the parse_tree_module_src and any
    parse_tree_plain_opts to the HLDS at the same time as we add
    foreign_procs generated by the compiler to implement solver types
    and mutables. Document the reason for this.

    Document also the reason why we should add all marker pragmas
    just before we do this. Document the reason why two tests will fail
    until that, or something similar, is done.

compiler/add_foreign_proc.m:
    Delete a test that was required only because we couldn't guarantee
    the relative order of adding foreign_procs and pragmas that mark
    predicates as external on one backend.

compiler/module_qual.qual_errors.m:
    Add foreign_procs as a possible context for errors during qualification.

compiler/status.m:
    Add a comment documented an old issue.

compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_solver.m:
compiler/check_module_interface.m:
compiler/comp_unit_interface.m:
compiler/convert_parse_tree.m:
compiler/coverage_profiling.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/equiv_type.m:
compiler/foreign.m:
compiler/get_dependencies.m:
compiler/goal_util.m:
compiler/grab_modules.m:
compiler/hlds_goal.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/parse_pragma_foreign.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_pragma.m:
compiler/pragma_c_gen.m:
compiler/prog_item_stats.m:
compiler/prog_mutable.m:
compiler/recompilation.version.m:
compiler/structure_sharing.domain.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_util.m:
compiler/termination.m:
compiler/trailing_analysis.m:
compiler/prog_data_foreign.m:
compiler/unify_proc.m:
    Conform to the changes above.
2023-08-04 11:42:46 +02:00
Zoltan Somogyi
d302a4e5ca Give some predicates/constructors more meaningful names.
compiler/module_cmds.m:
    Rename the update_interface_X predicates to copy_dot_tmp_to_base_file_X,
    because

    - this better describes what they do, and
    - some of the files they are invoked on are *not* interface files.

    Add an extra parameter to copy_dot_tmp_to_base_file_report_any_error
    that specifies what kind of file is being copied, and print *that*
    as part of any error message.

    Do a similar rename of update_interface_result type, and of its
    function symbols.

    Give more meaningful names to touch_interface_datestamp and
    touch_datestamp as well.

compiler/analysis.file.m:
compiler/analysis.m:
compiler/compile_target_code.m:
compiler/export.m:
compiler/intermod.m:
compiler/make.module_target.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/mlds_to_c_file.m:
compiler/recompilation.check.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2023-08-02 04:02:24 +02:00
Zoltan Somogyi
3e9a5114ce Carve four new modules out of intermod.m.
Each of the new modules, and intermod.m itself, has better cohesion
than the original intermod.m.

compiler/intermod_decide.m:
    New module that contains the code that decides what to put
    into .opt files.

compiler/intermod_info.m:
    New module that defines the intermod_info type, which records
    the results of those decisions.

compiler/intermod_mark_exported.m:
    New module that contains the code that updates the statuses of entitties
    that we *would* export if the compiler were asked to generate a .opt file,
    but its current task is something else.

compiler/intermod_status.m:
    New module that contains the code that decides whether an entity's
    status allows it to be opt-exported.

compiler/intermod.m:
    Delete the code moved to other modules.

compiler/transform_hlds.m:
    Include the new modules.

compiler/notes/compiler_design.html:
    Document the new modules.

compiler/mercury_compile_front_end.m:
    Conform to the changes above.

compiler/intermod_analysis.m:
    Fix a comment.
2023-07-28 12:43:33 +02:00
Zoltan Somogyi
1d3cd2d0b1 Delete invalid procs from their pred_info.
compiler/hlds_pred.m:
    This module used to maintain a distinction between valid and invalid
    procedures in a pred_info. The distinction was based on whether the
    proc_info field containing a list of mode_error_infos was empty
    (such procedures were valid) or nonempty (such procedures were invalid).

    This field was used only during the early phases of the compiler
    from mode analysis to unique mode analysis, but all later passes
    had to check whether the field was empty before processing the procedure.

    This diff deletes this field from proc_infos. The information that this
    field used to contain is now stored in *temporary* data structures
    maintained and used only by the mode and unique mode analysis phases.
    These phases use the code they share in modes.m to delete all invalid
    procedures from the HLDS before they hand over that HLDS to other phases.
    This means that outside these two compiler phases, *all* procedures in the
    HLDS will be valid.

    Delete all service predicates and functions that tested procedures
    for validity, since this has now become a meaningless test. In one case,
    where there was no non-validity-testing equivalent, make one.

compiler/mode_info.m:
    Define the proc_mode_error_map, which effectively replaces the fields
    deleted from proc_infos. Define the operations on it that we need.

compiler/modes.m:
    Initialize proc_mode_error_maps to empty, and then pass them through
    mode analysis as part of the mode_info, allowing mode analysis code
    to use it to check procedure validity.

    When a mode analysis phase (either ordinary or unique mode analysis)
    is done, delete the procedures that we have now detected are invalid.
    However, before we do, print any inference messages about them.

compiler/unique_modes.m:
    Use the new field in mode_info to check procedures' validity.

    Delete the unique_modes_check_proc predicate, because it had
    only one caller in modes.m, which called another predicate in modes.m
    through it.

compiler/modecheck_call.m:
compiler/modecheck_unify.m:
    Use the new field in mode_info to check procedures' validity.

compiler/try_expand.m:
    Conform to the changes above.

    When a mode check of a procedure repeated after try expansion finds
    an error, delete the now-detected-to-be-invalid procedure.

compiler/cse_detection.m:
    Conform to the changes above.

    When a mode check of a procedure repeated after common subexpression
    eliminate finds an error, don't bother to delete the now-detected-to-be-
    invalid procedure, because the code on that path throws an exception
    anyway.

    Fix an old incongruity: one trace goal created a new ProgressStream
    in a predicate that would have been given existing one if needed.

compiler/direct_arg_in_out.m:
    Conform to the changes above by deleting a validity test.

    Delete a predicate that had no job *except* that validity test.

compiler/style_checks.m:
    Use missing procedure ids to detect invalid procedures. Add an XXX
    about a limitation of this approach.

compiler/bytecode_gen.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/distance_granularity.m:
compiler/exception_analysis.m:
compiler/float_regs.m:
compiler/goal_mode.m:
compiler/higher_order.m:
compiler/hlds_call_tree.m:
compiler/hlds_dependency_graph.m:
compiler/hlds_out_pred.m:
compiler/intermod.m:
compiler/intermod_analysis.m:
compiler/introduce_parallelism.m:
compiler/lambda.m:
compiler/liveness.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_proc_gen.m:
compiler/passes_aux.m:
compiler/pd_util.m:
compiler/polymorphism.m:
compiler/polymorphism_goal.m:
compiler/proc_gen.m:
compiler/purity.m:
compiler/rbmm.condition_renaming.m:
compiler/rbmm.execution_path.m:
compiler/rbmm.live_region_analysis.m:
compiler/rbmm.live_variable_analysis.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.region_arguments.m:
compiler/rbmm.region_instruction.m:
compiler/rbmm.region_transformation.m:
compiler/ssdebug.m:
compiler/stm_expand.m:
compiler/stratify.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.m:
compiler/structure_reuse.domain.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/switch_detection.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_initial.m:
compiler/termination.m:
compiler/trailing_analysis.m:
compiler/untupling.m:
compiler/unused_args.m:
    Conform to the changes above, mostly by deleting validity tests.
2023-07-18 14:03:14 +02:00
Zoltan Somogyi
b6ec42a132 Make some arities into pred_form_arities.
compiler/hlds_pred.m:
    Replace the arity field in pred_infos with a pred_form_arity field.

    Move the pred_info's pred_or_func field to its usual position
    in predicate/function descriptions: at the front (pred/func name/arity).

compiler/hlds_pred.m:
    Change two utility operations to return pred_form_arities instead of
    just arities, since they get them from pred_infos.

compiler/inst_mode_type_prop.m:
compiler/llds.m:
compiler/rtti.m:
    Change some fields whose types used to be arity (or int) to be
    pred_form_arity.

    In llds.m, include a pred_or_func field in c_procedures,
    for use in procedure-start comments.

mdbcomp/prim_data.m:
mdbcomp/program_representation.m:
    Add notes about two possible future improvements along similar lines.

compiler/prog_data.m:
    Add a utility function to calculate the number of extra arguments
    added to predicates/functions by compiler passes such as polymorphism.

compiler/add_pragma.m:
    Conform to the changes above.

    Fix a bug in an error message about ":- external" pragmas:
    the message used the pred_form arity instead of the user arity.
    (See the diff to external2.err_exp below.)

compiler/hlds_defns.m:
    Conform to the changes above.

    Include pred/func prefixes before name/arity pairs in the output
    where relavnt. (The user guide does not need to be updated, because
    its wording permits both the old and the new behavior.)

    Fix two separate bugs that referred to functions in user-facing output
    with the predicate form of their arity.

compiler/table_gen.m:
compiler/unused_args.m:
    Conform to the changes above.

    Fix a bug in each module that referred to functions in user-facing output
    with the predicate form of their arity.

compiler/recompilation.usage.m:
compiler/xml_documentation.m:
    Conform to the changes above.

    Mark a probable bug in each module with an XXX.

compiler/direct_arg_in_out.m:
    Conform to the changes above.

    Improve the wording of an error message a bit.
    (See the diff to gh72_errors.err_exp below.)

compiler/accumulator.m:
compiler/bytecode_gen.m:
compiler/complexity.m:
compiler/default_func_mode.m:
compiler/det_report.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/exception_analysis.m:
compiler/higher_order.m:
compiler/hlds_defns.m:
compiler/hlds_error_util.m:
compiler/hlds_module.m:
compiler/intermod.m:
compiler/intermod_order_pred_info.m:
compiler/introduce_exists_casts.m:
compiler/introduce_parallelism.m:
compiler/llds_out_file.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_accurate_gc.m:
compiler/ml_args_util.m:
compiler/mode_errors.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/old_type_constraints.m:
compiler/optimize.m:
compiler/polymorphism.m:
compiler/polymorphism_goal.m:
compiler/post_typecheck.m:
compiler/pre_typecheck.m:
compiler/pred_table.m:
compiler/proc_gen.m:
compiler/rbmm.region_transformation.m:
compiler/recompilation.usage.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/simplify_goal_call.m:
compiler/ssdebug.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_initial.m:
compiler/termination.m:
compiler/trailing_analysis.m:
compiler/transform_llds.m:
compiler/tupling.m:
compiler/type_class_info.m:
compiler/typecheck.m:
compiler/typecheck_error_undef.m:
compiler/types_into_modes.m:
compiler/xml_documentation.m:
    Conform to the changes above.

compiler/recompilation.m:
    Add a note.

compiler/parse_tree_out_sym_name.m:
    Improve variable names.

tests/invalid/external2.err_exp:
    Expect the fixed arity in an error message.

tests/invalid/gh72_errors.err_exp:
    Expect the expanded text of an error message.
2023-07-03 01:57:10 +02:00
Zoltan Somogyi
7292ecb571 Don't generate duplicate instance declarations.
We used to include in the .int0 file the abstract form of all the instance
declarations in both the interface and the implementation sections.
When an instance is declared (in an already-abstract form) in the interface
section and defined in the implementation section, this resulted in the
abstract interface declaration being included in the .int0 file twice,
once in the interface section, and once in the implementation section.

compiler/comp_unit_interface.m:
    Fix this by including an abstract instance declaration in the
    implementation section of a .int0 file only if it does not also appear
    in the interface section.

    Conform to the changes in prog_item.m below.

compiler/parse_tree_out.m:
    To help implement the above test, add a function to return the string
    form of an abstract instance declaration.

    It is easy to make this change for *abstract* instance declarations,
    but not *concrete* instance definitions, because (in order to handle
    instances that define methods by clauses, instead of by pred/func names)
    the latter would require generalizing *all* the code for writing out
    clauses, with all the overhead associated with replacing first order calls
    with method calls.

    Another change (unrelated to the problem above) is to write out
    typeclass and instance definitions for typeclasses with no methods
    in a nicer form. Instead of looking like this:

        :- instance classname(argtypes) where [

        ].

    they now look like this:

        :- instance classname(argtypes) where [].

    Another formatting change unrelated to the above: don't put parentheses
    around typeclass names in instance declarations/definitions if the name
    is all alphanumeric and not an operator.

    Conform to the changes in prog_item.m below.

compiler/prog_data.m:
compiler/prog_item.m:
    To be able to use the new code to convert abstract instances to strings
    in comp_unit_interface, and to write out abstract instance declarations
    inside .int0 (and other .intN) files, it helps to know which instance
    items can only be abstract in these files. As it turns out, none can be
    concrete. So define a subtype of item_instance_info that can contain
    only abstract instance declarations, and use it to replace
    item_instance_info in parse_tree_intN for all N.

compiler/parse_tree_out_info.m:
    Add a utility function for new code in comp_unit_interface.m
    invoking new code in parse_tree_out.m.

compiler/convert_parse_tree.m:
    Conform to the changes in prog_item.m by insisting that instances
    read in from .intN files are all abstract.

    Fix some typos in some error messages (which people can see only if
    something has screwed up a .intN file).

compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/recompilation.version.m:
    Conform to the changes above.

compiler/intermod.m:
    Simplify some code.

tests/invalid/Mercury.options:
    Fix the failure of the instances_pc.instances_pc_helper_1 test case
    when intermodule optimization is enabled for a bootcheck by disabling
    intermodule optimization for this test. The old code to do so didn't
    work due to typos.

tests/invalid/instances_pc.instances_pc_helper_1.err_exp:
    Expect a reference to only ONE old instance declaration in
    instances_pc.int0. Expect it at a new line number, due to the first
    formatting change above.

tests/misc_tests/pretty_print_test.exp:
    Expect no unnecessary parentheses around a class name in an
    instance definition, due to the second formatting change.
2023-06-30 09:34:01 +02:00
Zoltan Somogyi
a47de48c4d s/input_stream/text_input_stream/ ...
... and the same for output streams.
2023-04-24 14:59:20 +10:00
Zoltan Somogyi
b6178ef723 Delete prog_out.m, moving its code to other modules.
compiler/parse_tree_out_cons_id.m:
    Move the predicates and functions in prog_out.m that deal with cons_ids
    to this module.

compiler/parse_tree_out_sym_name.m:
    Move the predicates and functions in prog_out.m that deal with sym_names
    and similar entities to this module.

compiler/parse_tree_out_type.m:
    Move the predicates and functions in prog_out.m that deal with types
    to this module.

compiler/parse_tree_out_misc.m:
    Move the predicates and functions in prog_out.m that deal with simple
    types to this module.

    Delete mercury_output_det and mercury_format_det, replacing all their
    uses with calls to mercury_det_to_string.

compiler/prog_out.m:
    Delete this module.

compiler/parse_tree.m:
    Delete prog_out from the parse_tree package.

compiler/Mercury.options:
compiler/notes/compiler_design.html:
    Delete references to prog_out.m.

compiler/*.m:
    Update imports and any explicit module qualifications to account
    for the moved code.

tools/filter_sort_imports:
    Automatically filter out any repeated imports. This can help with
    changes like this that redistribute the contents of one module to other
    modules. In this case, after a global replacement of prog_out's import
    with the import of parse_tree_out_misc, this updated script could
    remove this changed import from modules that already imported
    parse_tree_out_misc.
2023-04-09 16:23:13 +10:00
Zoltan Somogyi
e2a8a8cbfa Break up mercury_to_mercury.m.
compiler/mercury_to_mercury.m:
    Delete this module, and replace it with ...

compiler/parse_tree_out_cons_id.m:
compiler/parse_tree_out_sym_name.m:
compiler/parse_tree_out_type.m:
compiler/parse_tree_out_misc.m:
    ... these four modules. The first three write out the entities
    in their names: cons_ids, sym_names, and types. The fourth contains
    the rest of the old mercury_to_mercury.m, plus a few predicates
    moved there from prog_out.m that deal with indentation.

compiler/parse_tree.m:
    Include the four new modules, and stop including the deleted module.

compiler/notes/compiler_design.html:
    Document the new modules.

compiler/prog_out.m:
    Delete the code moved to parse_tree_out_misc.m.

compiler/*.m:
    Adjust the imports as needed. Most modules need only one, maybe two
    of mercury_to_mercury's four successor modules.
2023-04-06 15:32:48 +10:00
Zoltan Somogyi
18817d62d0 Record more than a pred_proc_id for each method.
Class and instance definitions both contain lists of methods,
predicates and/or functions, that each have one or more procedures.
Until now, we represented the methods in class and instance definitions
as lists of nothing more than pred_proc_ids. This fact complicated
several operations,

- partly because there was no simple way to tell which procedures
  were part of the same predicate or function, and

- partly because the order of the list is important (we identify
  each method procedure in our equivalent of vtables with a number,
  which is simply the procedure's position in this list), but there was
  absolutely no information about recorded about this.

This diff therefore replaces the lists of pred_proc_ids with lists of
method_infos. Each method_info contains

- the method procedure number, i.e. the vtable index,

- the pred_or_func, sym_name and user arity of the predicate or function
  that the method procedure is a part of, to make it simple to test
  whether two method_infos represent different modes of the same predicate
  or function, or not,

- the original pred_proc_id of the method procedure, which never changes,
  and

- the current pred_proc_id, which program transformations *can* change.

compiler/hlds_class.m:
    Make the change above in the representations of class and instance
    definitions.

    Put the fields of both types into a better order, by putting
    related fields next to each other.

    Put a notag wrapper around method procedure numbers to prevent
    accidentally mixing them up with plain integers.

    Add some utility functions.

compiler/prog_data.m:
    Replace three fields containing pred_or_func, sym_name and arity
    in the parse tree representation of instance methods with just one,
    which contains all three pieces of info. This makes it easier to operate
    on them as a unit.

    Change the representation of methods defined by clauses from a list
    of clauses to a cord of clauses, since this supports constant-time
    append.

compiler/hlds_goal.m:
    Switch from plain ints to the new notag representation of method
    procedure numbers in method call goals.

compiler/add_class.m:
    Simplify the code for adding new classes to the HLDS.

    Give some predicates better names.

compiler/check_typeclass.m:
    Significantly simplify the code for that generates the pred_infos and
    proc_infos implementing all the methods of an instances definition,
    and construct lists of method_infos instead of lists of pred_proc_ids.

    Give some predicates better names.

    Some error messages about problems in instance definitions started with

        In instance declaration for class/arity:

    while others started with

        In instance declaration for class(module_a.foo, module_b.bar):

    Replace both with

        In instance declaration for class(foo, bar):

    because it contains more useful information than the first, and less
    non-useful information than the second. Improve the wording of some
    error messages.

    Factor out some common code.

compiler/prog_mode.m:
compiler/prog_type.m:
compiler/prog_util.m:
    Generalize the existing predicates for stripping "builtin.m" module
    qualifiers from sym_names, cons_ids, insts, types and modes
    to allow also the stripping of *all* module qualifiers. This capability
    is now used when we print an instance's type vector as a context
    for diagnostics about problems inside instance definitions.

compiler/add_pred.m:
    Add a mechanism for returning the pred_id of a newly created pred_info,
    whether or not it was declared using a predmode declaration. This
    capability is now needed by add_class.m.

    Move the code creating an error message into its own function, and export
    that function for add_class.m.

compiler/polymorphism_type_info.m:
    Fix some comment rot.

compiler/base_typeclass_info.m:
compiler/call_gen.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/direct_arg_in_out.m:
compiler/error_msg_inst.m:
compiler/float_regs.m:
compiler/get_dependencies.m:
compiler/higher_order.m:
compiler/hlds_error_util.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_typeclass_table.m:
compiler/instance_method_clauses.m:
compiler/intermod.m:
compiler/make_hlds_error.m:
compiler/ml_call_gen.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/module_qual.qualify_items.m:
compiler/old_type_constraints.m:
compiler/parse_class.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_inst.m:
compiler/polymorphism_post_copy.m:
compiler/polymorphism_type_class_info.m:
compiler/prog_item.m:
compiler/prog_rep.m:
compiler/recompilation.usage.m:
compiler/state_var.m:
compiler/type_class_info.m:
compiler/typecheck_debug.m:
compiler/typecheck_error_type_assign.m:
compiler/typecheck_errors.m:
compiler/typecheck_msgs.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.

tests/invalid/bug476.err_exp:
tests/invalid/tc_err1.err_exp:
tests/invalid/tc_err2.err_exp:
tests/invalid/typeclass_bogus_method.err_exp:
tests/invalid/typeclass_missing_mode.err_exp:
tests/invalid/typeclass_missing_mode_2.err_exp:
tests/invalid/typeclass_mode.err_exp:
tests/invalid/typeclass_mode_2.err_exp:
tests/invalid/typeclass_mode_3.err_exp:
tests/invalid/typeclass_mode_4.err_exp:
tests/invalid/typeclass_test_10.err_exp:
tests/invalid/typeclass_test_3.err_exp:
tests/invalid/typeclass_test_4.err_exp:
tests/invalid/typeclass_test_5.err_exp:
tests/invalid/typeclass_test_9.err_exp:
    Expect the updated wording of some error messages.
2022-11-22 02:27:33 +11:00
Zoltan Somogyi
07f877bc3f Carve term_context.m out of term.m.
library/term.m:
library/term_context.m:
    As above.

    Rename the term.context type as term_context.term_context, with
    term.context now being defined as an equivalence type.

    Replace the context_init function and predicate and the dummy_context_init
    function with just one function: dummy_context. This name includes
    the important part (the fact that it return a *dummy* context) and deletes
    the nonimportant part (dummy contexts are just about never updated,
    so the function does not really "initialize" them).

    Reduce function/predicate pairs that do the same thing to just a function.

library/MODULES_DOC:
library/library.m:
    Add the new module to the list of standard library modules.

NEWS:
    Mention the new module, and the obsoleting of the moved predicates
    and functions in term.m.

compiler/*.m:
library/*.m:
    Conform to the changes above.
2022-08-23 12:56:37 +10:00
Zoltan Somogyi
3e2cde2c33 Don't abort compilation for unresolved overloading.
compiler/pred_table.m:
    When we find more than one match for a predicate or function signature,
    we used to generate an error message, print it, and then abort
    compilation. Fix this by returning the error message to be handled
    by our callers.

    The compiler now has to pick one of the matches to continue with.
    The compiler's pick (the first match) may not be the match intended
    by the programmer, and it is possible that the compiler will later generate
    some error messages that would not happen if we picked the match
    intended by the programmer. We therefore warn the programmer about
    this possibility.

compiler/purity.m:
compiler/resolve_unify_functor.m:
    Include the error messages now returned by pred_table.m among
    all the other error messages generated by the purity pass,
    which, amongst other things, does the last part of the job
    of the typechecker.

compiler/intermod.m:
    Ignore the errors caused by unresolved overloading when generating
    .opt files. They will be reported when the compiler tries to generate
    target language code.

library/list.m:
    Add three related utility predicates that we discussed earlier,
    each of which was needed by one version or another of the code
    for constructing the error message in pred_table.m.

NEWS:
    Announce the additions to list.m.

tests/invalid_submodules/unresolved_overloading.{m,err_exp}:
    Expect the updated error message, and the *absence* of a compiler abort.
2022-08-21 15:28:55 +10:00
Zoltan Somogyi
752bb66f5b Carve four modules out of term.m.
Most modules that imported the old term.m need only a small subset
of its functionality. After this diff, most modules that used to import
term.m will need to import just one more module, and will import many
fewer predicates and functions in total.

library/term_int.m:
    A new module carved out of term.m containing the predicates
    that recognize terms containing integers, and the functions
    that construct such terms.

    While this job has *some* similarity to the job of the existing
    term_conversion.m module, most modules in the compiler use only one
    of those two modules, so merging them would not be a good idea.

library/term_subst.m:
    A new module carved out of term.m containing code to do
    substitutions and renames of various kinds.

    Rename the occurs predicate as var_occurs_in_subst_term,
    and occurs_list as var_occurs_in_subst_terms, since the latter
    are much more descriptive. Change the argument order to match
    the new names (var, subst, term/terms), as the old one did not
    even have the term/terms and the substitution next to each other,
    even though neither makes sense without the other.

library/term_unify.m:
    A new module carved out of term.m containing code to do unifications.

    Give all the predicates more meaningful names:

    unify_term ->                   unify_terms
    unify_term_list ->              unify_term_lists
    unify_term_dont_bind ->         unify_terms_dont_bind
    unify_term_list_dont_bind ->    unify_term_lists_dont_bind
    list_subsumes ->                first_term_list_subsumes_second

library/term_vars.m:
    A new module carved out of term.m containing code that find variables
    in terms.

    Give all the predicates more meaningful names:

    vars ->                         vars_in_term
    vars_2 ->                       vars_in_term_acc
    vars_list ->                    vars_in_terms
    contains_var ->                 term_contains_var
    contains_var_list ->            terms_contain_var

    Don't move the function version of vars_2 to term_vars.m, effectively
    deleting it, since operations that update an accumulator are awkward
    for functions.

library/term.m:
    Keep the moved predicates and functions in term.m, but

    - change their implementation to simply call the moved copy, and
    - obsolete the original in favor of the moved copy.

    Eventually, after either the next release or the release after the next,
    we should delete the obsoleted predicates and functions.

library/MODULES_DOC:
library/library.m:
    Add the new modules as documented parts of the standard library.

browser/interactive_query.m:
compiler/analysis.file.m:
compiler/det_util.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_passes.m:
compiler/parse_class.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_item.m:
compiler/parse_mutable.m:
compiler/parse_pragma.m:
compiler/parse_pragma_analysis.m:
compiler/parse_sym_name.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_defn.m:
compiler/parse_util.m:
compiler/prog_ctgc.m:
compiler/prog_util.m:
compiler/recompilation.used_file.m:
compiler/recompilation.version.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/typecheck.m:
library/io.m:
library/term_conversion.m:
library/varset.m:
    Conform to the changes above.
2022-08-21 01:01:21 +10:00
Zoltan Somogyi
f7355f708b Move var_db and var_{name,type}_source to var_db.m.
In the process, restrict the use of these types to just those modules
that need to provide services both other modules that use var_tables,
and modules that do not. The latter are modules that either can,
or always do, execute before var_tables are set up.

In some cases, code that previously operated on e.g. var_name_sources
had all its callers converted to use var_tables. In those cases, replace
the use of var_name_sources with var_tables directly.

In other cases, code that previously operated on e.g. var_name_sources
still has some callers that use varsets. In those cases,

- provide versions using var_tables if most callers use var_tables,
  renaming predicates/functions to make this the version seem the default,

- leave the operation to work on var_name_sources if some its callers
  also have only var_name_sources,

- if there are no such callers, keep just the two versions operating
  on varsets and var_tables respectively.

compiler/var_db.m:
compiler/var_table.m:
    Move the part of var_table.m that contains the definitions
    of the above three types, and the operations on them, to the
    new module var_db.m. Only 25 modules currently need var_db.m,
    compared to 176 for var_table.m.

compiler/parse_tree.m:
compiler/notes/compiler_design.html:
    Add and document the new module.

compiler/parse_tree_out_term.m:
    Add a "_vs" suffix to the names of operations that print variables
    or terms using varsets, and reuse their old names for versions
    that use var_table arguments. For the operations that need var_name_source
    versions, make it just select between the varset and var_table versions.

compiler/hlds_out_goal.m:
compiler/instmap.m:
compiler/hlds_out_mode.m:
compiler/hlds_out_util.m:
compiler/hlds_pred.m:
compiler/pd_info.m:
    Change some predicates that used to operate on var_{name,type}_sources
    to operate on var_tables.

    In hlds_out_mode.m, delete some unused predicates, and stop exporting
    a predicate whose only caller is local.

compiler/*.m:
    Conform to the changes above.
2022-08-19 10:44:39 +10:00
Zoltan Somogyi
d787ee9355 Store var_tables in proc_infos.
This fixes the performance problem reported in Mantis bug #562.

compiler/hlds_pred.m:
    Instead of storing a varset and a vartypes in each proc_info,
    store just a var_table. Update the predicates that create
    or clone procedures accordingly.

    Where we had operations on proc_infos that had two versions,
    one operating on a varset/vartypes pair and one operating on var_table,
    keep only the latter, with the (shorter) name of the former.

    Delete the arity argument of proc_info_init, because the only
    valid value of that argument is the length of the list of the
    argument types. (In other words, this arg has been redundant
    all along.)

    Change the operations that create new variables in a procedure
    to get the caller to specify the (base) name of the new variable
    up front.

    Delete the unused predicate proc_info_ensure_unique_names.

compiler/type_util.m:
    Due to the change above, we now construct var_tables during the
    construction of the HLDS. The code that does that needs to fill in
    the field that says whether the type of each variable in the table
    is a dummy type or not. However, at this time, the pass that decides
    type representations has not been run yet. The code of is_type_a_dummy
    used to throw an exception in such situations.

    Change this so that in such situations, is_type_a_dummy returns
    a placeholder, not-guaranteed-to-be-correct value. Document why
    this is ok.

compiler/post_typecheck.m:
    Replace the placeholder values in vte_is_dummy fields in all
    the entries in the var_tables in all (valid) predicates with valid data.
    (If there are any invalid predicates, the compilation will fail anyway.)
    The clause_to_proc pass will copy these updated var_tables
    to be the initial var_tables in procedures.

compiler/make_goal.m:
    Change the operations that create new variables in a procedure
    to get the caller to specify the (base) name of the new variable
    up front. This is simpler than the old method, which created new
    variables without a name, and had the caller give them a name as
    a separate operation. And since var_tables need this info,
    get the caller to also specify whether the type is a dummy,
    if the type is not a builtin type which is known not to be a dummy.

compiler/var_table.m:
    Document the times when the types and is_dummy fields in var_table
    entries become meaningful.

    Fix a potential bug: when performing type substitutions in
    var_table entries, updating a variable's type may change whether
    that variable is a dummy or not, so recompute that info.
    It is quite possible that we *never* replace a nondummy type
    with a dummy type or vice versa, but in the absence of a convincing
    correctness argument for that proposition, better safe than sorry.

    Export the previously-private predicate transform_var_table
    to post_typecheck.

    Add code to implement the unused predicate deleted from hlds_pred.m:
    at the time I wrote it, I haven't yet realised that it was unused.
    The code I wrote here is therefore unused as well, so it is commented out.
    I did not delete it, because it may be useful later on.

compiler/direct_arg_in_out.m:
    Don't make and split var_tables, since it is no longer needed.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_heap_ops.m:
compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/add_trail_ops.m:
compiler/arg_info.m:
compiler/build_mode_constraints.m:
compiler/bytecode_gen.m:
compiler/check_typeclass.m:
compiler/clause_to_proc.m:
compiler/closure_analysis.m:
compiler/code_gen.m:
compiler/code_loc_dep.m:
compiler/complexity.m:
compiler/continuation_info.m:
compiler/cse_detection.m:
compiler/ctgc.livedata.m:
compiler/deep_profiling.m:
compiler/default_func_mode.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/exception_analysis.m:
compiler/float_regs.m:
compiler/follow_code.m:
compiler/goal_mode.m:
compiler/goal_path.m:
compiler/higher_order.m:
compiler/hlds_out_pred.m:
compiler/hlds_rtti.m:
compiler/hlds_statistics.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/intermod_analysis.m:
compiler/introduce_exists_casts.m:
compiler/introduce_parallelism.m:
compiler/lambda.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/loop_inv.m:
compiler/mark_tail_calls.m:
compiler/ml_accurate_gc.m:
compiler/ml_args_util.m:
compiler/ml_closure_gen.m:
compiler/ml_gen_info.m:
compiler/ml_proc_gen.m:
compiler/mode_errors.m:
compiler/mode_info.m:
compiler/modecheck_goal.m:
compiler/par_loop_control.m:
compiler/pd_debug.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/polymorphism_info.m:
compiler/post_typecheck.m:
compiler/proc_gen.m:
compiler/proc_requests.m:
compiler/purity.m:
compiler/push_goals_together.m:
compiler/quantification.m:
compiler/rbmm.add_rbmm_goal_infos.m:
compiler/rbmm.live_variable_analysis.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.points_to_graph.m:
compiler/rbmm.points_to_info.m:
compiler/rbmm.region_liveness_info.m:
compiler/rbmm.region_transformation.m:
compiler/recompute_instmap_deltas.m:
compiler/saved_vars.m:
compiler/simplify_goal_unify.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/stack_alloc.m:
compiler/stack_layout.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/store_alloc.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/switch_detection.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_initial.m:
compiler/term_errors.m:
compiler/term_pass1.m:
compiler/term_pass2.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/try_expand.m:
compiler/tupling.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/unused_imports.m:
    Conform to the changes above. Mostly this means

    - not passing a module_info to get a var_table out of a proc_info, but
    - having to pass a module_info to code that either constructs a var_table,
      or adds entries to a var_table (since we now need the type table
      to figure out whether variables' types are dummies).
2022-08-18 18:53:15 +10:00
Zoltan Somogyi
26be4bb8e3 Add --warn-ambiguous-pragmas.
The new option is on by default, and it generates a warning about pragmas
that specify a name/arity pair that matches both a predicate and a function,
but does not say which one it is intended to apply to.

compiler/options.m:
doc/user_guide.texi:
    Add the new option.

NEWS:
    Announce the new option.

compiler/add_pragma.m:
    Implement the new option.

    Move to one predicate, get_matching_pred_ids, the code for dealing with
    both the absence of any matches, and the presence of more than one match,
    when looking up name/arity pairs in the predicate table. This allows us
    to delete the mostly-duplicate code fragments that did the same thing
    in all of get_matching_pred_ids's callers.

    Simplify the handling of conflicts between marker pragmas.

compiler/hlds_pred.m:
    Separate out no_inline decisions made by the compiler itself from
    the similar decisions made by users, in order to allow that simplification.

    Move the two inline markers next to each other.

compiler/make_hlds_error.m:
    Change a predicate called from add_pragma*.m to take user arities
    in their semantic form, not their int form, which raises the level
    of the predicate's interface, and factors out duplicate code in its
    callers.

compiler/add_pragma_type_spec.m:
compiler/intermod.m:
compiler/table_gen.m:
    Conform to the changes above.

doc/reference_manual.texi:
    Document pred(...) and func(...) wrappers around name/arity pairs
    in pragmas.

    Delete the commented out section on reserve_tag pragmas, which were
    deleted a while ago.

tests/invalid/inline_conflict.m:
    Expand this test case to test the *absence* of a warning for an
    ambiguous pragma with --no-warn-ambiguous-pragma.

tests/invalid/inline_conflict_warn.{m,err_exp}:
tests/invalid/Mercury.options:
    Add a copy of the inline_conflict test case to test the presence of
    a warning for an actually ambiguous pragma.

tests/invalid_nodepend/fact_table_in_interface.err_exp:
    Expect the updated wording of a warning.
2022-07-31 18:17:02 +10:00
Zoltan Somogyi
4c9d04434a Classify pred_names into four categories.
compiler/pred_name.m:
    Group pred_origins into four categories, giving each category its own
    function symbol. The categories are

    - predicates that contain, or may contain, code directly written
      by the user;
    - predicates created wholly by the compiler,
    - predicates created by the compiler by transforming a predicate, and
    - predicates created by the compiler by transforming a procedure.

    We distinguish between the first two because we want to report
    errors only in user-written code, since reporting an error that
    the user is powerless to fix is not a good idea.

    We distinguish between the last two just to allow us to store
    the proc_id of the transformed procedure next to its pred_id.

compiler/higher_order.m:
    Replace a boolean with value of a bespoke type.

    Rename some predicates to avoid ambiguity.

compiler/*.m:
    Conform to the changes above.
2022-07-23 09:28:40 +10:00
Zoltan Somogyi
1eb1e239b3 Move the pred_origin type to pred_name.m.
compiler/pred_name.m:
    Add the pred_origin type and its component types, moved here from
    hlds_pred.m and hlds_rtti.m.

    Also, add the functions and predicates that convert pred_origins to
    strings, moved here from hlds_pred.m, hlds_out_util.m and layout_out.m.

compiler/hlds_pred.m:
    Delete the pred_origin type moved to pred_name.m.

compiler/hlds_rtti.m:
    Delete the instance_method_constraints type moved to pred_name.m.
    It has nothing to do with RTTI, and was not used in hlds_rtti.m itself.
    The only data structure it is part of is pred_origin, though
    it is used as temporary data by a few other modules.

compiler/hlds_out_util.m:
compiler/hlds_pred.m:
compiler/layout_out.m:
    Delete the functions and predicates moved to pred_name.m.

compiler/*.m:
    Conform to the change above, mostly by adding imports of pred_name.m,
    in a few cases replacing hlds_pred.m or hlds_rtti.m.
2022-07-21 05:02:44 +10:00
Zoltan Somogyi
08365979d0 Move pred_name.m to the HLDS package.
This is so that it can become the home of the type currently named
pred_origin in hlds_pred.m, which (after being given new name) will become
a structured representation of predicate names.

The only thing that kept pred_name.m in the parse_tree package was the fact
that parse_pragma.m, which has no access to the hlds package, called it
to create the name of a type-specialized predicate when parsing
type_spec pragmas. The main part of this diff, apart from the trivial
updates to import hlds.pred_name instead parse_tree.pred_name, deals
with this issue.

The problem is how to ensure that the compiler invocations that create
type-specialized predicates (invocations that compile the module containing
the type_spec pragma that calls for this) and the invocations that create
the calls to those predicates (invocations that mostly compile other modules)
agree on the name of the name of the type-specialized predicate.

The old approach was this.

    When reading in (say) mod1.m which contains a type_spec pragma,
    we construct the name of the type-specialized predicate from

    - the name of the module (mod1),
    - the name of the predicate to be specialized, and
    - the type substitution in the pragma.

    We then record this name in the pragma.

    If the compiler invocation generates code, we use this name in the
    predicate definition. If the compiler invocation creates a .int file,
    we record the name in the third argument of the type_spec pragma.
    This third argument is NOT allowed to exist in .m files.

    Other compiler invocations that read in mod1.int when compiling
    another module, e.g. mod2.m, use the specialized name in the third argument
    of the type_spec pragma as the name to use in calls.

In this approach, the single-source-of-truth about the name of the
type-specialized predicate is the name constructed when parsing mod1.m,
which is conveyed to compiler invocations on other modules through
the third argument of the type_spec pragma.

The new approach is this:

    When reading in (say) mod1.m which contains a type_spec pragma,
    we give guaranteed-to-be-unique names to all the anonymous variables
    in the type_spec pragma. We also record in the type_spec pragma
    the name of the module whose (source or interface) file we read
    the pragma from. The name of the predicate to be specialized
    was of course already in the pragma.

    If the compiler invocation generates code, we construct the name
    of the type-specialized version of the predicate when we add the
    all-tvars-are-named type_spec pragma to the HLDS. If the compiler
    invocation creates a .int file, we write out the all-tvars-are-named
    version of the type_spec pragma. The pragma also contains the predicate
    name to be specialized. It does not contain the name of the module,
    but we will write out type_spec pragmas from module_x.m *only* to
    module_x.int, never to any other .int file, so any readers of
    the type_spec pragma from mod1.int will also know the name of the
    module that the pragma came from.

    Other compiler invocations that read in mod1.int when compiling
    another module, e.g. mod2.m, therefore get exactly the same

    - module name,
    - the name of the predicate to be specialized, and
    - the type substitution in the pragma

    as the compiler invocations on mod1.m. The module name are the
    predicate name are never changed by being written out and then
    read back in, and *due to the explicit names given to any formerly
    anonymous variables*, the type substitution is changed by this either.
    This means that the compiler invocations on mod1.m and mod2.m
    give the same parameters to the same function, and therefore they are
    guaranteed to get the same string as the name of the type-specialized
    version of the predicate.

In this approach, the single-source-of-truth about the name of the
type-specialized predicate is the function constructing that name
and its inputs.

compiler/hlds.m:
compiler/parse_tree.m:
compiler/pred_name.m:
    Move pred_name.m from the parse_tree package to the hlds package.

compiler/prog_item.m:
    Change the representation of type_spec pragmas to

    - delete the name of the specialized predicate, and replace it with
    - the name of the module the pragma was read in from.

compiler/parse_pragma.m:
    Delete the code for parsing the third argument of type_spec pragmas.
    Allow them to exist for a short transition period, but ignore them.
    (If we read in files containing them, the result will be a link error
    if the type substitution contains anonymous variables. In that case,
    a rebuild of the program with all modules compiled using the *same
    compiler version* will work.)

    Give guaranteed-to-be-unique names to all anonymous type variable
    in the type substitution part of the type_spec pragma we construct.

compiler/add_pragma_type_spec.m:
    Construct the name of the type-specialized predicate as the type_spec
    pragma is added to the HLDS.

compiler/parse_tree_out_pragma.m:
    Never write out a type_spec par_loop_control with a third argument.

    Delete the var_name_print argument of the predicate that writes out
    type_spec pragmas. Instead, *always* use print_name_only.

compiler/options.m:
    Add a way of testing whether the installed compiler has this change.

compiler/accumulator.m:
compiler/add_pragma_tabling.m:
compiler/add_special_pred.m:
compiler/base_typeclass_info.m:
compiler/check_typeclass.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/layout_out.m:
compiler/lco.m:
compiler/loop_inv.m:
compiler/make_hlds_passes.m:
compiler/name_mangle.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/par_loop_control.m:
compiler/parse_tree_out.m:
compiler/pd_info.m:
compiler/prog_rep.m:
compiler/ssdebug.m:
compiler/stm_expand.m:
compiler/structure_reuse.versions.m:
compiler/table_gen.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/unused_args.m:
2022-07-20 21:33:09 +10:00
Zoltan Somogyi
28f0000487 Rename predicates to avoid ambiguities. 2022-07-06 14:33:10 +10:00
Zoltan Somogyi
8122e83d2a Record typechecking results in var_tables.
compiler/hlds_clauses.m:
    The clauses_info type used to have two fields whose type is "vartypes".
    One contained type information we knew before typechecking, e.g. from
    explicit "Var : type" annotations, while the other contained the
    *results* of typechecking. Keep the former, but replace the latter
    with a var_table.

    Allow compiler passes that construct clauses to fill in the first field
    with the types of the head variables, because for the clauses of some
    kinds of predicates (such as predicates implementing builtins) that are
    "constructed correct" and do not need typechecking, this is all we need.

    Put the fields of clauses_info that deal with variables and their types
    next to each other, in the order in which they are filled in.

compiler/add_clause.m:
    Don't construct the context pieces needed for parsing mode annotations
    on arguments in the clause head unless the clause head's arguments
    *have* mode annotations, which they virtually never do.

compiler/add_pred.m:
compiler/add_special_pred.m:
    Put the types of the head variables into the var_table in the clauses_info
    we create for clauses for builtin predicates and unify/compare/index
    predicates respectively, for use by unused_imports.m.

compiler/typecheck.m:
    Fill in the var_table field in

    - predicates we have typechecked,
    - predicates for which we have created stub clauses that are
      "born type-correct", and
    - predicates for class methods whose code will be created later,
      during the polymorphism pass.

    In the last case, we fill in only the types of the head variables,
    preserving old behavior.

    Give some predicates more meaningful names. Inline a predicate at its
    only call site.

compiler/post_typecheck.m:
    Switch to using the var_tables computed by typechecking.

    Reset varsets in clauses_infos to empty, to tell hlds_out_pred.m
    not use it as the source of variable name info.

compiler/hlds_pred.m:
    Provide functionality to record the types of head variables
    in both vartypes and in var_tables.

compiler/hlds_out_pred.m:
    Get information about variable names from either the clauses_info's
    varset field (if the varset is nonempty, not yet having been reset
    by post_typecheck.m), or from its var_table field (if the varset
    *has* been reset to empty).

    Likewise, get information about variable types from either the
    clauses_info's var_table field (if it is not empty, having been filled in
    either by typechecking or by code created the type clauses "type-correct"
    at the start), or from its explicit_vartypes field (if the var_table field
    has not yet been filled in).

    It is possible that in the future, we may want to dump out the
    contents of the explicit_vartypes field even if the var_table
    has also been filled in. However, since the old code of write_pred
    had no such functionality, the chance we will need that in the future
    is small, and we can deal with it when the issue does arise.

compiler/goal_path.m:
compiler/hlds_out_goal.m:
compiler/intermod.m:
compiler/unify_proc.m:
    Convert these modules to use var_tables.

compiler/prog_type.m:
compiler/type_util.m:
    Record the fact that the builtin type "store_at_ref_type" is not a dummy
    type. Without this special-casing, the creation of a var_table containing
    a variable of this type would crash the compiler, because

    - unlike other builtin types, this one *has* a definition, in
      private_builtin.m, but
    - since it is a builtin type, its "definition" in the type table
      has no representation information, so the code of is_type_a_dummy
      cannot tell if that "definition" is a dummy or not.

compiler/prog_util.m:
    Provide the var_table equivalent of an existing utility predicate
    for varsets.

compiler/qual_info.m:
    Give a field of the qual_info type a more meaningful name.

compiler/typecheck_errors.m:
    Fix argument order and variable names.

compiler/vartypes.m:
compiler/var_table.m:
    Add a predicate to check whether a variable has a user-given name.

    Replace the varset_vartypes type in vartypes.m with the type_qual type
    in var_table.m, which uses var_tables, since its user, hlds_out_goal.m,
    has been converted to use var_tables. (Most variables of this type
    have been named TypeQual, which is why the type now has that name.)

compiler/inst_graph.m:
    Conform to the changes above.

    Export the definition of the inst_graph_info type, instead of exporting
    a getter and a setter for every one of its fields.

compiler/higher_order.m:
    Conform to the changes above, by calling clauses_info_init,
    instead of repeating its code here.

compiler/accumulator.m:
compiler/add_foreign_proc.m:
compiler/add_pragma_type_spec.m:
compiler/build_mode_constraints.m:
compiler/check_promise.m:
compiler/clause_to_proc.m:
compiler/format_call.m:
compiler/hhf.m:
compiler/instance_method_clauses.m:
compiler/lambda.m:
compiler/mode_constraints.m:
compiler/old_type_constraints.m:
compiler/par_loop_control.m:
compiler/polymorphism.m:
compiler/polymorphism_info.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/stm_expand.m:
compiler/structure_reuse.versions.m:
compiler/table_gen.m:
    Conform to the changes above.

tests/invalid/illtyped_compare.err_exp:
    Expect an improved variable name from unify_proc.m.

tests/invalid/try_detism.err_exp:
    Expect a different variable number for an unnamed variable.
2022-05-29 15:22:16 +10:00
Zoltan Somogyi
e10ecf5d69 Replace more varsets/vartypes with var_tables.
compiler/hlds_rtti.m:
compiler/hlds_statistics.m:
compiler/intermod.m:
compiler/loop_inv.m:
compiler/recompute_instmap_deltas.m:
    As above.

compiler/special_pred.m:
    Make some predicate names more meaningful.

compiler/hlds_goal.m:
    Fix one of two instances of an ancient bug, which is not looking for
    variables inside the call_unify_context field of plain calls.
    In this instance, apply substitutions to the variables there.

    Make the names of the predicates involved more meaningful.

compiler/lambda.m:
    Fix the other instance of that ancient bug, which was that the code
    was not looking for variables inside the call_unify_context fields
    of plain calls. Fix this by looking for used variables there as well.
    Without this, the code just added to hlds_goal.m may fail when invoked
    on the procedure we construct for a lambda, because a variable is included
    in the var_table of that procedure if lambda.m knows that variable
    is actually used in the original lambda goal.

compiler/var_table.m:
    Allow searches (as opposed to lookups) for variable names in var_tables
    as part of transition arrangements to fail. Without this, finding the
    bug in lambda.m would have been much harder, by causing HLDS dumps
    to fail.
2022-05-15 14:47:06 +10:00
Zoltan Somogyi
ea4f95a7ed Use var_tables in lco.m, and when dumping goals.
Since this is the first converted module that dumps out goals when
debugging trace flags are enabled, this required generalizing the code
that does that, to take either varsets or var_tables as a means of
specifying the names of variables. We do this via a new type,
var_name_source, which contains either a varset or a var_table.

Almost all of this diff is there to implement this generalization.
A large part of it affects code in the parse_tree package that we use
to write out the parts of HLDS goals that are defined by types defined
in that package. Since we want to avoid making any part of the parse_tree
package dependent on the hlds package, this required defining the
var_name_source type in the parse_tree package, which in turn requires
var_table.m to be in that same package.

compiler/lco.m:
    Convert this module to use var_tables instead of varsets and vartypes.

compiler/var_table.m:
    Move this module from the hlds package to the parse_tree package.

    To make this, possible, move the parts that required access to the HLDS
    to hlds_pred.m, from where it was usually invoked.

    Export some utility predicates to allow the moved code to work
    in hlds_pred.m without access to the actual definition of the
    var_table type.

    Define the var_name_source type.

    Add some utility functions for use by code writing out variable names.

compiler/hlds_pred.m:
    Add the code moved from var_table.m.

compiler/vartypes.m:
    Move this module from the hlds package to the parse_tree package,
    for symmetry with var_table.m. It did not depend on being in hlds
    in any way.

compiler/hlds.m:
compiler/parse_tree.m:
    Move vartypes.m and var_table.m from the hlds package
    to the parse_tree package.

compiler/hlds_out_goal.m:
    Change all the predicates in this module to take a var_name_source
    instead of a prog_varset.

    Fix some comments.

compiler/hlds_out_util.m:
    Change some of the predicates in this module (those called from
    hlds_out_goal.m) to take a var_name_source instead of a prog_varset.

compiler/parse_tree_out_term.m:
    Provide variants of some existing predicates and functions that take
    var_name_sources instead of varsets. The code of the copies
    duplicates the logic of the originals, though I hope that this
    duplication can be done away with at the end of the transition.
    (The best solution would be to use a typeclass with methods
    that convert vars to their names, but we would want to ensure
    that the compiler can specialize all the affected predicates
    and functions to the two instances of this typeclass, which is
    something that we cannot do yet. In the meantime, the lack of
    any generalization in the old versions preserves their performance.)

tools/sort_imports:
tools/filter_sort_imports:
    A new tool that automatically sorts any occurrences of consecutive
    ":- import_module" declarations in the named files. The sorting is done
    in filter_sort_imports; sort_imports loops over the named files.

    After automatically replacing all occurrences of hlds.{vartypes,var_table}
    in import_module declarations with their parse_tree versions, the updated
    import_module declarations were usually out of order with respect to
    their neighbours. I used this script to fix that, and some earlier
    out-of-order imports.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_heap_ops.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_trail_ops.m:
compiler/analysis.m:
compiler/arg_info.m:
compiler/build_mode_constraints.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/check_promise.m:
compiler/closure_analysis.m:
compiler/closure_gen.m:
compiler/code_info.m:
compiler/code_loc_dep.m:
compiler/common.m:
compiler/compile_target_code.m:
compiler/complexity.m:
compiler/const_prop.m:
compiler/constraint.m:
compiler/continuation_info.m:
compiler/convert_parse_tree.m:
compiler/coverage_profiling.m:
compiler/cse_detection.m:
compiler/ctgc.datastruct.m:
compiler/ctgc.util.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
compiler/direct_arg_in_out.m:
compiler/disj_gen.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/exception_analysis.m:
compiler/file_names.m:
compiler/float_regs.m:
compiler/follow_vars.m:
compiler/format_call.m:
compiler/generate_dep_d_files.m:
compiler/get_dependencies.m:
compiler/goal_expr_to_goal.m:
compiler/goal_mode.m:
compiler/goal_path.m:
compiler/goal_store.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_clauses.m:
compiler/hlds_code_util.m:
compiler/hlds_error_util.m:
compiler/hlds_goal.m:
compiler/hlds_llds.m:
compiler/hlds_out_pred.m:
compiler/hlds_rtti.m:
compiler/hlds_statistics.m:
compiler/inlining.m:
compiler/inst_check.m:
compiler/inst_test.m:
compiler/inst_user.m:
compiler/instance_method_clauses.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/intermod_analysis.m:
compiler/interval.m:
compiler/introduce_exists_casts.m:
compiler/introduce_parallelism.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/llds.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_util.m:
compiler/lookup_switch.m:
compiler/loop_inv.m:
compiler/make.module_target.m:
compiler/make.util.m:
compiler/make_goal.m:
compiler/make_hlds_separate_items.m:
compiler/make_hlds_types.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/middle_rec.m:
compiler/ml_accurate_gc.m:
compiler/ml_args_util.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_proc_gen.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_unify_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_func.m:
compiler/mlds_to_c_global.m:
compiler/mlds_to_cs_class.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_data.m:
compiler/mlds_to_java_file.m:
compiler/mlds_to_java_stmt.m:
compiler/mlds_to_java_type.m:
compiler/mmc_analysis.m:
compiler/mode_comparison.m:
compiler/mode_constraints.m:
compiler/mode_debug.m:
compiler/mode_errors.m:
compiler/mode_info.m:
compiler/mode_ordering.m:
compiler/modecheck_call.m:
compiler/modecheck_coerce.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/module_cmds.m:
compiler/old_type_constraints.m:
compiler/opt_debug.m:
compiler/optimize.m:
compiler/options_file.m:
compiler/ordering_mode_constraints.m:
compiler/par_loop_control.m:
compiler/parse_item.m:
compiler/parse_string_format.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_to_term.m:
compiler/parse_util.m:
compiler/pd_debug.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/peephole.m:
compiler/polymorphism.m:
compiler/polymorphism_info.m:
compiler/polymorphism_lambda.m:
compiler/polymorphism_type_class_info.m:
compiler/polymorphism_type_info.m:
compiler/post_typecheck.m:
compiler/pragma_c_gen.m:
compiler/pred_name.m:
compiler/pred_table.m:
compiler/prog_item.m:
compiler/prog_rep.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/push_goals_together.m:
compiler/qual_info.m:
compiler/quantification.m:
compiler/rbmm.execution_path.m:
compiler/rbmm.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.points_to_graph.m:
compiler/rbmm.points_to_info.m:
compiler/rbmm.region_resurrection_renaming.m:
compiler/rbmm.region_transformation.m:
compiler/recompilation.used_file.m:
compiler/recompilation.version.m:
compiler/recompute_instmap_deltas.m:
compiler/resolve_unify_functor.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/saved_vars.m:
compiler/set_of_var.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_conj.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_goal_scope.m:
compiler/simplify_goal_switch.m:
compiler/simplify_goal_unify.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/smm_common.m:
compiler/ssdebug.m:
compiler/stack_alloc.m:
compiler/stack_layout.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/store_alloc.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_data.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/term_constr_main_types.m:
compiler/term_constr_util.m:
compiler/term_pass1.m:
compiler/term_traversal.m:
compiler/term_util.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/transform_llds.m:
compiler/try_expand.m:
compiler/tupling.m:
compiler/type_assign.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/typecheck_debug.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unify_gen_construct.m:
compiler/unify_gen_deconstruct.m:
compiler/unify_proc.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/var_locn.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2022-04-18 02:00:38 +10:00
Zoltan Somogyi
3f3045c9e2 Get and set varsets/vartypes in proc_infos together.
compiler/hlds_pred.m:
    We eventually want to replace the varset and vartypes fields in
    each proc_info with a var_table, but it is not practical to do so
    at once; it will have to be done gradually, a few modules at most
    at a time. During this process, we will need a way either

    - to let already converted modules get a var_table out of the proc_info,
      and put an updated var_table back into a proc_info, even though
      proc_infos still contain varset and vartypes fields, or

    - to let not-yet-converted modules get varsets and vartypes out of the
      proc_info, and put updated varsets and vartypes back into a proc_info,
      even though proc_infos already store a var_table.

    The latter cannot be done in two halves (i.e. set the varset half
    of the var_table, and then set its vartypes half), and while the former
    *can* be done that way, it is more efficient to do them at the same time.

    Therefore as a first step, this diff replaces the indiviual getter
    and setter predicates of the varset and vartypes fields of proc_info
    with a getter that gets both and a setter that sets both.

    Put the varset and vartypes next to each other in a structure.

compiler/code_info.m:
    Delete a function that duplicates a function in var_table.m.

    Conform to the change above.

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

    Conform to the change above.

compiler/det_util.m:
    Delete a no-longer-needed predicate.

    Conform to the change above.

compiler/higher_order.m:
    Fix an old oversight: when deleting variables from the vartypes,
    delete them from the varset as well.

    Conform to the change above.

compiler/liveness.m:
    Avoid constructing and traversing a list unnecessarily.

    Conform to the change above.

compiler/accumulator.m:
compiler/add_heap_ops.m:
compiler/add_trail_ops.m:
compiler/arg_info.m:
compiler/build_mode_constraints.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/clause_to_proc.m:
compiler/closure_analysis.m:
compiler/code_gen.m:
compiler/code_loc_dep.m:
compiler/complexity.m:
compiler/continuation_info.m:
compiler/cse_detection.m:
compiler/ctgc.datastruct.m:
compiler/ctgc.util.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/direct_arg_in_out.m:
compiler/disj_gen.m:
compiler/equiv_type_hlds.m:
compiler/exception_analysis.m:
compiler/float_regs.m:
compiler/follow_code.m:
compiler/goal_mode.m:
compiler/goal_path.m:
compiler/hlds_out_pred.m:
compiler/hlds_rtti.m:
compiler/hlds_statistics.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/intermod_analysis.m:
compiler/introduce_exists_casts.m:
compiler/introduce_parallelism.m:
compiler/lambda.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/loop_inv.m:
compiler/mark_tail_calls.m:
compiler/ml_accurate_gc.m:
compiler/ml_args_util.m:
compiler/ml_closure_gen.m:
compiler/ml_gen_info.m:
compiler/ml_proc_gen.m:
compiler/mode_info.m:
compiler/modecheck_goal.m:
compiler/modes.m:
compiler/par_loop_control.m:
compiler/pd_debug.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/polymorphism_info.m:
compiler/proc_gen.m:
compiler/purity.m:
compiler/push_goals_together.m:
compiler/quantification.m:
compiler/rbmm.add_rbmm_goal_infos.m:
compiler/rbmm.live_variable_analysis.m:
compiler/rbmm.points_to_graph.m:
compiler/rbmm.points_to_info.m:
compiler/rbmm.region_liveness_info.m:
compiler/rbmm.region_transformation.m:
compiler/recompute_instmap_deltas.m:
compiler/saved_vars.m:
compiler/simplify_goal_unify.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/stack_alloc.m:
compiler/stack_layout.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/store_alloc.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/switch_detection.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_initial.m:
compiler/term_errors.m:
compiler/term_pass1.m:
compiler/term_pass2.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/try_expand.m:
compiler/tupling.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/unused_imports.m:
    Conform to the change above.
2022-04-07 21:22:21 +10:00
Zoltan Somogyi
3a306a7f1f Prepare to add new warnings about instances.
Prepare for these new options, --warn-unnecessarily-private-instance and
--warn-inconsistent-instance-order, by

- moving some checks on instance declarations to a point in time
  when the set of instance declarations in the module is complete, and

- adding a new field to instance declarations to record a context needed
  for the second of the above warnings.

compiler/add_class.m
compiler/check_typeclass.m
    Move some checks on instances from add_class.m, where they have to
    work with incomplete data, to check_typeclass.m, where they have access
    to all instance declarations. The tests moved are

    - the test whether the abstract and concrete forms of an instance
      specify the same constraints or not,
    - the test for duplicate concrete instances, and
    - the test for overlapping instances.

    The new code can be, and is, much more systematic in looking for
    inconsistencies between instance declarations. For example,
    it distinguishes between duplicate and overlapping instance declarations,
    whereas the old code did not. This allows it to generate more precise
    messages.

    We do in fact generate a new warning message, for duplicate abstract
    instance declarations.

    Crucially, the new code can also gather the information needed
    for --warn-inconsistent-instance-order, although the gathered info
    is then throw away. This will change soon.

    Record phase_type_check as the phase of all the error_specs generated
    in this module, not just most of them.

    Avoid constructing doing a global traversal of the entire instance table
    when a local traversal of just the part for one class_id will do.

    Give some predicates more meaningful names.

compiler/hlds_class.m
    To check whether abstract instance declarations are in the same order
    as concrete instance declarations, check_typeclass.m needs to record,
    with each concrete instance declaration, the context of the corresponding
    abstract instance declaration (if any). Add a slot for this information.

    Change instance_id from an equivalence type to a notag type,
    to reduce the chances of values of that type being confused
    with integers whose semantics is something else.

    Document why the structure of the instance table is what it is.

compiler/base_typeclass_info.m
compiler/dead_proc_elim.m
compiler/higher_order.m
compiler/hlds_code_util.m
compiler/hlds_defns.m
compiler/hlds_out_typeclass_table.m
compiler/intermod.m
compiler/polymorphism_type_class_info.m
compiler/recompilation.usage.m
compiler/typeclasses.m
compiler/unused_imports.m
    Conform to the change in hlds_class.m.

compiler/hlds_out_util.m
    Add a utility function for use by new code in hlds_out_typeclass_table.m.

tests/invalid/incompatible_instance_constraints.err_exp
tests/invalid/missing_concrete_instance.err_exp
tests/invalid/typeclass_test_9.err_exp
    Expect updated error messages.
2022-03-19 14:41:58 +11:00
Zoltan Somogyi
e657a091e4 Encode the arity kind in the type in pred lookups.
compiler/pred_table.m:
    Some predicates in this module have traditionally taken an arity argument
    that *included* function result arguments, while others took an arity
    arguments that *excluded* function result arguments. While the difference
    was documented, it was not enforced in the types. Change this by
    switching the two kinds of arities to pred_form_arities and user_arities
    respectively.

    Change the internal data structures to specify in the types
    that they operate on user_arities.

    Change the operation of lookup_builtin_pred_proc_id as part of the
    change to goal_util.m (described below).

compiler/goal_util.m:
    When looking up the pred_info of a builtin, callers used to pass to the
    predicates that did that (generate_simple_call and generate_foreign_proc)
    a list of the arguments of the call without specifying which arguments
    were type_info/typeclass_info arguments added by polymorphism.
    This meant that the length of the argument list was *not* necessarily
    the called predicate or function's pred form arity, but could exceed it
    by the number of arguments added by polymorphism. The only reason this
    worked was because the lookup_builtin_pred_proc_id procedure they used
    to look up the named predicate in the pred table compensated for it

    - by doing a lookup on the original arity plus one, if the lookup on the
      original arity failed, and

    - in all the calls to generate_simple_call and generate_foreign_proc,
      the number of arguments added by polymorphism was either zero or one.

    Nevertheless, the system was fragile. It could have broken either

    - because when looking up the arity that included a type_info argument,
      (e.g. one typeinfo and two original args) the lookup could have found
      a false match (a predicate with the same name with three original args),

    - or because a new call to a new builtin could need to specify two or more
      arguments added by polymorphism.

    Fix this issue by

    - requiring calls to generate_simple_call and generate_foreign_proc
      to pass the arguments added by polymorphism separately, so the number
      of the original arguments specifies the predicate's pred_form_arity, and

    - deleting the code in lookup_builtin_pred_proc_id that tried to
      compensate for the presence of an "unannounced" typeinfo argument.

compiler/analysis.m:
    Change the type of a slot in a structure from arity to pred_form_arity,
    since that seems to have been how that slot was used.

compiler/recompilation.check.m:
compiler/recompilation.m:
compiler/recompilation.usage.m:
    Conform to the changes above, but only in a minimal fashion,
    because I don't *know* whether the values of type 'arity' passed around
    in the recompilation modules represent user arities or pred form arities.
    Record my guesses, but also record the fact that they are *only* guesses.
    Mark suspect code with "XXX ARITY BUG".

compiler/add_heap_ops.m:
compiler/add_trail_ops.m:
compiler/stm_expand.m:
compiler/table_gen.m:
    Conform to the changes above.

    Rationalize the argument order of the internal module-specific predicates
    they use to generate calls to builtins.

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/analysis.file.m:
compiler/check_typeclass.m:
compiler/complexity.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/dep_par_conj.m:
compiler/direct_arg_in_out.m:
compiler/distance_granularity.m:
compiler/format_call.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/higher_order.m:
compiler/hlds_module.m:
compiler/intermod.m:
compiler/lco.m:
compiler/make_hlds_passes.m:
compiler/mmc_analysis.m:
compiler/modecheck_goal.m:
compiler/par_loop_control.m:
compiler/polymorphism_type_class_info.m:
compiler/polymorphism_type_info.m:
compiler/pred_table.m:
compiler/purity.m:
compiler/rbmm.region_transformation.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_scope.m:
compiler/simplify_goal_unify.m:
compiler/size_prof.m:
compiler/special_pred.m:
compiler/ssdebug.m:
compiler/try_expand.m:
compiler/typecheck.m:
compiler/unify_proc.m:
    Conform to the changes above.
2022-02-22 23:59:20 +11:00
Zoltan Somogyi
ee0a21b98c Replace some 'arity's with {pred_form,user}_arity.
This removes uncertainty in the affected places in the compiler,
because unlike the 'arity' type, the pred_form_arity and user_arity
types specify *which definition* of arity they represent.

Whether I replaced a use of arity with pred_form_arity or user_arity
depended on whether I believed the original arity to have been intended to be
- a pred_form_arity without the wrapper, or
- a user_arity without the wrapper.
The reason for the size of this diff is that when I replaced one use of
arity with pred_form_arity or user_arity, I often could not be sure about
the right way to propagate this change to the rest of the affected code
without making similar replacements elsewhere, and seeing whether
*that* worked. This diff is in effect the "smallest fixpoint" of this process.

In places where the pred form arity of predicate or function
is inherent in a list which has one element for each argument
(the element may be a term, a type, a mode, etc), do not take
a separate arity argument as well, since (a) it is not needed, and
(b) it is a potential source of inconsistencies. The only downside
is that we may need to take the length of a list in both the caller
and the callee, but this cost is negligible.

Add "XXX ARITY" comments to mark opportunities for future improvements.

compiler/hlds_clauses.m:
    Make clauses_info_init take a pred_form_arity instead of an arity
    as argument.

compiler/hlds_pred.m:
    Make pred_info_init take a pred_form_arity instead of an arity
    as argument.

compiler/prog_data.m:
    Specify that the arity part of the pf_sym_name_arity type
    is a pred_form_arity.

    Add a variant of the sym_name_arity type, which does not say
    what kind of arity it contains, which does say that it contains
    a pred_form_arity.

    Store the arities of instance methods as user_arity, not arity.

    Move the definition of an instance method out of between
    the instance's name and its arity.

    Add a convenience function for computing the pred_form_arity
    of an argument list.

    Delete a type moved to parse_sym_name.m.

compiler/prog_item.m:
    Use user_arities in item_initialise_infos and item_finalise_infos.

compiler/typecheck_errors.m:
    Specify that the arity in an arg_vector_plain_pred_call,
    and in the argument list of a function that construct a message
    for a related type error, is a pred_form_arity.

compiler/add_class.m:
    In the predicate that converts clauses to instance methods,
    delete its arity argument, given that another argument is
    the list of argument terms.

    Move the generator of a variable before its first consumer.

compiler/add_clause.m:
    In predicates that add clauses to the HLDS, delete their arity argument
    where another argument is the list of argument terms.

compiler/superhomogeneous.m:
    Explicit specify that the arity of a clause is recorded as a
    pred_form_arity.

compiler/add_foreign_proc.m:
    In predicates that add foreign_procs to the HLDS, delete their arity
    argument where another argument is the list of argument terms.

compiler/check_typeclass.m:
    Record the arity of the method being checked as user_arity.

    Fix incorrect arities in the error messages we generate.

compiler/make_hlds_error.m:
    Get callers to specify the pred_form_arity of a missing predicate or
    function. If that predicate or function exists with other arities,
    we try to be helpful and print out those arities in the error message.
    This process had some bugs, which this diff fixes.

compiler/typecheck_info.m:
    Specify that the arity we record for overloaded symbols is the
    pred_form_arity.

compiler/dep_par_conj.m:
    Conform to the changes above.

    Move a comment to the code it is about.

compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
    Conform to the changes above.

    In two comments, write out the user arities of function methods,
    not their pred form arity.

compiler/make_hlds_passes.m:
    Conform to the change in the representation of initialise and finalise
    items.

    Use the new method for constructing target names in prog_foreign.m.

    Indent the code example part of an error message.

compiler/prog_foreign.m:
    Provide a single predicate for creating target language names
    for initialise and finalise predicates. This new predicate factors out
    what used to be duplicate code in make_hlds_passes.m.

compiler/parse_sym_name.m:
    Move a type here from prog_data.m, since it is used only by
    parse_sym_name.m and the modules that call it.

compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/check_promise.m:
compiler/det_report.m:
compiler/get_dependencies.m:
compiler/goal_expr_to_goal.m:
compiler/higher_order.m:
compiler/hlds_out_typeclass_table.m:
compiler/intermod.m:
compiler/mark_tail_calls.m:
compiler/parse_class.m:
compiler/parse_mutable.m:
compiler/parse_tree_out.m:
compiler/pred_name.m:
compiler/prog_mutable.m:
compiler/prog_out.m:
compiler/state_var.m:
compiler/table_gen.m:
compiler/typecheck.m:
compiler/unused_args.m:
    Conform to the changes above.

compiler/make_hlds.m:
    Conform to the change in add_class.m.

tests/invalid/bad_pred_arity.err_exp:
tests/invalid/mode_decl_in_wrong_section.err_exp:
tests/invalid/pragma_c_code_dup_var.err_exp:
tests/invalid/state_vars_test3.err_exp:
tests/invalid/typeclass_bogus_method.err_exp:
tests/invalid/typeclass_test_3.err_exp:
tests/invalid/typeclass_test_4.err_exp:
    Update these expected outputs for the bug fixes above.

tests/invalid_nodepend/bad_finalise_decl.err_exp:
tests/invalid_nodepend/bad_initialise_decl.err_exp:
    Update these expected outputs for formatting change above.

tests/invalid/no_method.{m,err_exp}:
    A new test case for an arity-related error message that wasn't
    being exercised before.

tests/invalid/Mmakefile:
    Enable the new test case.
2022-02-17 22:21:16 +11:00
Zoltan Somogyi
f5ec674e18 Rename the hlds_class_interface type.
compiler/hlds_class.m:
    The name "hlds_class_interface" suggests that it is a HLDS version
    of the "class_interface" type defined in prog_data.m, but it is
    not that at all. While the class_interface type does contain
    the compiler's internal version of what is between the []s in an
    instance declaration, the hlds_class_interface type was defined
    to be hold a list of pred_proc_ids. They are the pred_proc_ids
    of the implementations of the methods, but they are not an interface.

    Therefore this diff renames the hlds_class_interface type
    to method_pred_proc_ids, and renames the fields of the structures
    representing typeclasses and instances accordingly.

compiler/base_typeclass_info.m:
compiler/check_typeclass.m:
compiler/dead_proc_elim.m:
compiler/direct_arg_in_out.m:
compiler/float_regs.m:
compiler/higher_order.m:
compiler/hlds_out_typeclass_table.m:
compiler/intermod.m:
compiler/old_type_constraints.m:
compiler/polymorphism_post_copy.m:
compiler/polymorphism_type_class_info.m:
compiler/type_class_info.m:
compiler/xml_documentation.m:
    Conform to the change above, updating variable names as well as
    the changed type and field names.

    In check_typeclass.m, put class_interface arguments before
    method_pred_proc_ids arguments.
2022-02-08 21:01:26 +11:00
Zoltan Somogyi
5cada10369 Rename pred_table to pred_id_table.
compiler/pred_table.m:
    As above. This addresses half of an old XXX, which is that the two types
    defined in this module, predicate_table and pred_table (as it was then)
    should have names that (a) say what they do, and (b) are distinct.
    Addressing the other half requires a more descriptive but not-too-long
    name to replace "predicate_table".

    Rename the predicates that operate on the type to follow the name change.

    Add a distinguishing prefix to the names of the fields of the
    predicate_table type.

compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/arg_info.m:
compiler/bytecode_gen.m:
compiler/clause_to_proc.m:
compiler/closure_gen.m:
compiler/cse_detection.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/default_func_mode.m:
compiler/det_analysis.m:
compiler/det_util.m:
compiler/direct_arg_in_out.m:
compiler/distance_granularity.m:
compiler/export.m:
compiler/float_regs.m:
compiler/goal_mode.m:
compiler/granularity.m:
compiler/hlds_defns.m:
compiler/hlds_error_util.m:
compiler/hlds_module.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_module.m:
compiler/hlds_out_util.m:
compiler/hlds_pred.m:
compiler/hlds_statistics.m:
compiler/implementation_defined_literals.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/introduce_exists_casts.m:
compiler/introduce_parallelism.m:
compiler/lambda.m:
compiler/lco.m:
compiler/make_hlds_passes.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_proc_gen.m:
compiler/mode_info.m:
compiler/modecheck_call.m:
compiler/modes.m:
compiler/oisu_check.m:
compiler/old_type_constraints.m:
compiler/passes_aux.m:
compiler/polymorphism.m:
compiler/polymorphism_post_copy.m:
compiler/post_typecheck.m:
compiler/pre_typecheck.m:
compiler/proc_gen.m:
compiler/proc_requests.m:
compiler/simplify_proc.m:
compiler/stm_expand.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.m:
compiler/structure_sharing.analysis.m:
compiler/switch_detection.m:
compiler/table_gen.m:
compiler/term_constr_build.m:
compiler/term_constr_initial.m:
compiler/term_constr_util.m:
compiler/term_util.m:
compiler/termination.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the change in pred_table.m.

    Refer to values of the renamed type using a consistent naming scheme.

    When the affected code repeats the body of existing helper predicates
    for lookup up a pred_info or proc_info, or updating a proc_info
    inside a pred_info, or updating a pred_info inside a module_info,
    call the helper predicate instead. This makes code shorter and less
    cluttered, and the use of the helper predicates for updates automatically
    ensures that we don't accidentally update a stale version of the relevant
    table. (This has sometimes been a problem in the past.)

    In a few places, carve a new predicate for processing one element
    of a list out of an existing predicate for processing all list elements.
2022-02-03 10:01:21 +11:00
Zoltan Somogyi
3373860871 Prepare for checking insts' "for type_ctor/arity".
This consists of two main parts.

The first part is creating a single point in time in a compiler invocation
when this check can be done. This point in time has to be after typechecking,
because (in the presence of type inference) this is the earliest point
when type information is guaranteed to be available (in the absence of
type errors, of course). The logical time is therefore the post-typecheck pass.
The post-typecheck pass also does the closely related task of propagating type
information into insts, but only the insts inside predicates' mode
declarations. Before this diff, the task of propagating type information
into the insts in the modes in lambda expressions was left to be done
*during*, not *before*, mode checking. (I think the rationale was that
you want to have propagated types into an inst in a procedure signature before
you may see a call to that procedure. Mode checking may encounter a call
to procedure of a predicate before processing that procedure, but due to
mode reordering, it won't ever encounter a call to a lambda expression
before processing the unification whose right hand side contains that
lambda expression.) However, it is conceptually simpler if the post-typecheck
pass takes over the propagation of types into insts even in lambda expressions,
which is what this diff does.

The second part is cleaning up the code that does this propagation,
to allow that cleanup to be reviewed separately from its modification
to check for uses of user-defined insts for values of types other than
the types that they are declared to be for.

compiler/inst_mode_type_prop.m:
    Give most predicates in this module more descriptive names
    that also fit into a single naming scheme.

compiler/hlds_pred.m:
    Add a predicate marker that allows typechecking to tell the
    post-typecheck pass that a predicate contains one or more lambda
    expressions.

compiler/typecheck_info.m:
    Add a slot to the typecheck_info in which we can record the presence
    of a lambda expression.

compiler/typecheck.m:
    When processing lambdas, record this fact in the new typecheck_info slot.

    When processing a predicate bodies causes this slot to be set,
    add the new marker to the predicate.

compiler/post_typecheck.m:
    For predicates for which the typechecking pass left this marker,
    propagate types not just into the insts in the predicate's mode
    declarations, but also into the insts in lambda expressions.
    This is an extra traversal of the predicate body, but only
    a relatively small minority of predicate bodies will need it done.

    Rename a predicate to fit in with the new naming scheme in
    inst_mode_type_prop.m.

    Improve the wording of an error message.

compiler/modecheck_unify.m:
    Do not propagate type info into the insts in lambda expressions,
    since the post-typecheck will have already done that task.

compiler/add_special_pred.m:
compiler/inst_lookup.m:
compiler/inst_user.m:
compiler/intermod.m:
compiler/table_gen.m:
    Conform to the changes above.

tests/invalid_nodepend/invalid_main.err_exp:
    Expect the updated error message from post_typecheck.m..
2021-12-24 23:28:08 +11:00
Zoltan Somogyi
d76c7bf617 Break up inst_util.m and mode_util.m.
This step significantly improves module cohesion.

compiler/inst_abstract_unify.m:
    New module carved out of inst_util.m, which does abstract unifications
    on insts.

compiler/inst_merge.m:
    New module carved out of inst_util.m, which merges insts.

compiler/inst_lookup.m:
    New module carved partly out of inst_util.m and partly out of mode_util.m,
    which looks up insts in the module_info, and then possibly expands out
    the result.

compiler/mode_test.m:
    New module carved out of mode_util.m, whose predicates
    perform tests on modes.

compiler/mode_top_functor.m:
    New module carved out of mode_util.m, which computes top_functor_modes
    from modes.

compiler/inst_mode_type_prop.m:
    New module carved out of mode_util.m, which propagates type information
    into both insts and modes.

compiler/recompute_instmap_deltas.m:
    New module carved out of mode_util.m, which recomputes goals'
    instmap_deltas.

compiler/inst_test.m:
    Move here the predicates in inst_util.m that perform tests on insts.

compiler/inst_util.m:
compiler/mode_util.m:
    Delete the code that this diff moves to other modules.

compiler/check_hlds.m:
    Add the new modules to the check_hlds package, the package that also
    contains inst_util.m and mode_util.m. (Some of these modules could
    be argued to fit better in the hlds package, but moving them there
    would not be desirable while they depend on code that is still in the
    check_hlds package.)

compiler/notes/compiler_design.html:
    Document the new modules.

compiler/add_pragma_tabling.m:
compiler/arg_info.m:
compiler/bytecode_gen.m:
compiler/closure_analysis.m:
compiler/complexity.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/error_msg_inst.m:
compiler/fact_table.m:
compiler/float_regs.m:
compiler/follow_code.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_pred.m:
compiler/hlds_rtti.m:
compiler/inlining.m:
compiler/inst_match.m:
compiler/inst_user.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/interval.m:
compiler/introduce_exists_casts.m:
compiler/lambda.m:
compiler/lco.m:
compiler/liveness.m:
compiler/lookup_util.m:
compiler/loop_inv.m:
compiler/mark_tail_calls.m:
compiler/ml_args_util.m:
compiler/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_util.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/modecheck_call.m:
compiler/modecheck_coerce.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/oisu_check.m:
compiler/par_conj_gen.m:
compiler/pd_util.m:
compiler/post_typecheck.m:
compiler/pragma_c_gen.m:
compiler/proc_requests.m:
compiler/prog_rep.m:
compiler/push_goals_together.m:
compiler/rbmm.region_transformation.m:
compiler/saved_vars.m:
compiler/simplify_goal_switch.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/stratify.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.domain.m:
compiler/superhomogeneous.m:
compiler/table_gen.m:
compiler/term_constr_build.m:
compiler/term_pass2.m:
compiler/term_util.m:
compiler/tupling.m:
compiler/unify_gen_construct.m:
compiler/unify_gen_util.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
    Conform to the changes above by importing the required new modules,
    sometimes in addition to inst_util.m or mode_util.m, but more usually
    instead of them.
2021-12-16 01:31:35 +11:00
Zoltan Somogyi
638551faaa Add missing code for parsing 'promise_ex's.
compiler/parse_item.m:
    Add previously missing code for parsing promise_ex declarations
    (promise_exclusive, promise_exhaustive, and promise_exclusive_exhaustive)
    of the form ":- all [vars] promise_ex... goal."

    Comment out the code for parsing another form of such declarations,
    ":- promise_ex... goal.", which also had missing code and thus
    never worked.

    Check whether the first argument of a "some" or "all" quantifier
    is a list of variables in just one place.

compiler/status.m:
    Fix a bug in code that already had an XXX. Without this fix,
    the new test case would get a spurious error from check_promise.m.

compiler/check_promise.m:
    Fix several instances of another bug uncovered by the fix in status.m.
    The problem was that the code that checked promises in the interface
    section to see whether they contained any inappropriate references
    to predicates or data constructors defined in the implementation section
    considered, due to the bug now fixed in status.m, predicates and data
    constructors imported from other modules to be defined in the
    implementation section of this module. In fact, it did not even consider
    the question of whether the predicate or data constructor was defined
    in the current module at all.

    Fixing this requires making a choice: may promises in the interface
    refer to predicates and data constructors defined in other modules,
    or not? The language manual does not answer this question, or any
    other, about promises, since (a) all its documentation of promise
    declarations is commented out, and (b) even the commented-out prose
    is silent on references to other modules in promises.

    The fix chosen by this diff is to let a promise refer to other modules
    only if it is in the implementation section. The reason for this is that
    I would find it strange to have module A rely on a promise made by
    module B about the properties of e.g. a predicate in module C.
    While having the code of module B itself rely on a promise that
    module B itself makes about module C is not ideal, at least if the
    promise is wrong, the effect of the wrong promise will be local.
    (In a review comment, Julien pointed out that having module B make promise
    about a predicate in module C may make sense if module C was provided
    by an external entity, which may make moving the promise itself
    to module C problematic in practice.)

    Make error messages clearer via additional punctuation.

compiler/intermod.m:
    Make the result of writing out a promise look better.

compiler/parse_tree_out.m:
    Make the code writing out promises add a parentheses, without which
    we could not read the promise back in.

tests/valid/promise_ex.m:
    Add a test case for whether we can parse a promise_ex declaration.

tests/valid/Mmakefile:
    Enable the new test case.

tests/invalid/assert_in_interface.err_exp:
    Expect the error message we now generate for cross-module promises
    in interface sections.

tests/invalid/tricky_assert1.err_exp:
    Expect additional punctuation in an error message.
2021-12-07 17:04:03 +11:00
Zoltan Somogyi
3b9ff2f37b Gather pred declarations.
compiler/intermod.m:
    Gather pred declarations, and print them as a whole. Delete some code
    that duplicates functionality in parse_tree_out_pred_decl.m.

    Print the declarations of all predicates the same way, using
    print_name_only for any type variables in the predicate's signature.
    We used to print type variables this way if the predicate has foreign code,
    where it is required (due to the possible presence of TypeInfo_for_T
    variables in the foreign code), but we used to use print_name_and_num
    for other predicates. Document why we now consistently use print_name_only.

compiler/parse_tree_out.m:
    Export a predicate for use by intermod.m, after carving it out of another
    predicate.

    Add a parameter to the predicates that output predicate declarations
    to allow the caller to specify how type variables should be printed,
    in case we want to change things again later.

compiler/parse_tree_out_pred_decl.m:
    Add a parameter to the predicates that output parts of predicate
    declarations to allow the caller to specify how type variables
    should be printed, in case we want to change things again later.

    Break up too-long lines.
2021-12-06 07:08:21 +11:00
Zoltan Somogyi
d04db87a83 Gather mode declarations without the I/O state.
compiler/intermod.m:
    As above.

    Delete some code that duplicates functionality in parse_tree_out.m.

compiler/parse_tree_out.m:
    Export a predicate for use by intermod.m.

    Improve some variable names.
2021-12-06 07:08:21 +11:00
Zoltan Somogyi
ad773929c7 Gather preds' pragmas without the I/O state.
compiler/intermod.m:
    Instead of writing out definitions of type_spec and pred_marker pragmas
    for a predicate as we find them, print them all at once. This is a stepping
    stone towards creating .opt files by creating and then writing out
    a parse_tree_plain_opt.

    Print use_module and foreign_import_module declarations in a block.

    Delete a predicate that duplicates one in parse_tree_out.m.

compiler/parse_tree_out.m:
    Export a predicate for use by intermod.m.

    Add some comments.

compiler/parse_tree_out_pragma.m:
    Fix indentation.
2021-12-06 07:08:21 +11:00
Zoltan Somogyi
5340876581 Do more work without the I/O state.
compiler/intermod.m:
    Instead of writing out definitions of types, insts, modes, typeclasses
    and instances as we find them, print them all at once. This is a stepping
    stone towards creating .opt files by creating and then writing out
    a parse_tree_plain_opt.

    Factor out some common code.

compiler/parse_tree_out.m:
    Export some predicates for use by intermod.m.
2021-12-02 01:52:23 +11:00
Zoltan Somogyi
ac66a3c788 Carve two new modules out of intermod.m.
compiler/intermod_analysis.m:
compiler/intermod_order_pred_info.m:
    Carve these two new moduiles out of intermod.m.

    intermod_analysis.m contains the parts of the old intermod.m that
    deal with collecting program analysis results in the forms of
    compiler-generated pragmas, and writing them out. These pragmas make up
    the second half of .opt files, and the entirety of .trans_opt files.

    intermod_order_pred_info.m contains some utilities that are needed
    by both intermod_analysis.m and the code that is left in intermod.m.

compiler/intermod.m:
    Remove the code moded to the new modules.

compiler/transform_hlds.m:
    Include the new modules in the transform_hlds package.

compiler/notes/compiler_design.html:
    Describe the new arrangement.

compiler/item_util.m:
    Move a utility function here from intermod.m, since it is (a) now needed
    by intermod_analysis.m as well, and (b) this is its natural home.

compiler/exception_analysis.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_middle_passes.m:
compiler/structure_reuse.analysis.m:
compiler/structure_sharing.analysis.m:
compiler/tabling_analysis.m:
compiler/trailing_analysis.m:
    Conform to the changes above.
2021-12-01 01:42:18 +11:00
Zoltan Somogyi
82294d9936 Improve the code generating .opt/.trans_opt files.
compiler/intermod.m:
    We put analysis results into both .opt and .trans_opt files,
    but a large chunk of the code that did this was duplicated.
    Factor out the commonalities.

    Separate the code that gathers the analysis results, and the code
    that writes out those results. This allows us to avoid passing
    the I/O state through large parts of this module.

    Delete the code in this module that wrote out the results of the
    termination2 analysis; use the existing code in parse_tree_out_pragma.m
    instead.

    We put both declarations and definitions of predicates into .opt files.
    Call the definitions "definitions" and not "clauses", since the definitions
    of predicates consist not of clauses, but of foreign_procs or promises.

    Put the declarations before the definitions of predicates in
    intermod_infos, since this is the usual order in Mercury programs.

    Print foreign_import_module items just after Mercury import or use items,
    since they do similar jobs.

    Give some predicates better names.

compiler/parse_tree_out.m:
    Print foreign_import_module items just after Mercury import or use items,
    since they do similar jobs.

    Put blank lines between blocks containing different kinds of analysis
    results in .opt and .trans_opt files, to match the corresponding output
    generated by intermod.m.

    Add a new auxiliary predicate for this, and export it to intermod.m.

compiler/parse_tree_out_pragma.m:
    Simplify the writing out of many kinds of pragmas using string.format
    and io.format.

compiler/rat.m:
    Replace write_rat with to_rat_string, which is strictly more flexible.

    Rename to_string to to_arith_string, since the job it does is
    quite different from to_rat_string's job.

    Use a consistent set of variable names.

    Delete unneeded module qualifications.

compiler/lp_rational.m:
    Simplify code that outputs things.

compiler/term_errors.m:
    Improve the style of some comments.
2021-11-30 22:18:47 +11:00
Zoltan Somogyi
4df3268af0 Use bespoke types in intermod.m.
compiler/intermod.m:
    Instead of passing along five paramaters one by one, pass them in one
    structure. Use bespoke types instead of booleans for its fields.

    Replace DoWrite = yes with MayOptExportPred = may_opt_export_pred,
    which expresses its meaning much more clearly.

    Fix some misleading predicate names.
2021-11-30 03:19:04 +11:00
Zoltan Somogyi
4126519139 Separate subtypes from du types in parse trees.
compiler/prog_data.m:
    Split type_details_sub from type_details_du, and separate
    parse_tree_sub_type from parse_tree_du_type. This gets us two things:

    - It allows us to encode the prohibition on user-specified equality and
      comparison predicates, and "where direct_arg is" clauses,
      on subtype definitions.

    - It gives us data types we can use to represent (a) only subtype
      definitions, and (b) only non-subtype du definitions.

    Note that this diff deliberately leaves the HLDS representation
    of subtypes unchanged. This is because while a subtype *definition*
    may not specify e.g. equality and comparison predicates, a subtype *can*
    have equality and comparison predicates; it just has to get them from
    its base type. And the same applies to direct args.

compiler/parse_type_defn.m:
    Enforce the invariant that subtypes may not have user-specified equality
    and comparison predicates, or "where direct_arg is" clauses.

    If we find a subtype definition that does have one or both of these
    non-allowed and now-nonrepresentable components, we do still want to
    return the rest of the type definition, in order to avoid misleading
    error messages about that type having no definition at all. To make this
    possible, allow the parsing predicate to return error_specs "alongside",
    as well as "instead of", the item or marker being parsed.

compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_class.m:
    Handle these "alongside" error messages.

compiler/prog_item.m:
    Separate out subtypes from other du types in type definition maps.

compiler/add_type.m:
    Delete a semantic check that is now in parse_type_defn.m.

    Conform to the change to the representations of subtypes/du types
    in the parse tree.

compiler/item_util.m:
    Add a new utility function for subtypes.

compiler/check_type_inst_mode_defns.m:
compiler/comp_unit_interface.m:
compiler/convert_parse_tree.m:
compiler/decide_type_repn.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/intermod.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/prog_type.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the change to the representations of subtypes/du types
    in the parse tree.
2021-10-02 16:45:26 +10:00
Zoltan Somogyi
1ce46c2797 Pair lambda arg vars with their modes.
compiler/hlds_goal.m:
    This enforces the invariant that the there is one mode par argument var.

    Document that that "nonlocals" field of the lambda actually contains
    the variables that will be put into the closure.

compiler/assertion.m:
compiler/build_mode_constraints.m:
compiler/check_promise.m:
compiler/cse_detection.m:
compiler/dead_proc_elim.m:
compiler/delay_partial_inst.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
compiler/float_regs.m:
compiler/format_call.m:
compiler/goal_path.m:
compiler/goal_util.m:
compiler/hhf.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_util.m:
compiler/hlds_statistics.m:
compiler/implementation_defined_literals.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/lco.m:
compiler/loop_inv.m:
compiler/make_hlds_warn.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/mode_ordering.m:
compiler/mode_util.m:
compiler/modecheck_unify.m:
compiler/old_type_constraints.m:
compiler/polymorphism.m:
compiler/polymorphism_lambda.m:
compiler/pre_quantification.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/quantification.m:
compiler/simplify_goal_unify.m:
compiler/stratify.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/try_expand.m:
compiler/typecheck.m:
compiler/unused_args.m:
compiler/unused_imports.m:
    Conform to the change above.
2021-08-21 17:49:42 +10:00
Zoltan Somogyi
72ccb2cb5d Simplify write_promise.
compiler/intermod.m:
    Delete the parameters whose value is always the same.

    Simplify the code writing out the quantified variables.

compiler/parse_tree_out.m:
    Make the same changes in mercury_output_item_promise.

    Simplify some adjacent code, and delete a misleading comment.

compiler/mercury_to_mercury.m:
    Add a utility function needed by the above changes.
2021-08-08 05:20:40 +10:00
Zoltan Somogyi
c796749739 Move a predicate next to its only call. 2021-08-08 03:47:24 +10:00
Zoltan Somogyi
254cd500bf Add bespoke type for du types' details.
compiler/hlds_data.m:
    As above. The other kinds of types already had bespoke types
    for *their* details.

compiler/add_type.m:
compiler/du_type_layout.m:
    Instead of passing values of the hlds_type_body with an inst
    that said they were du types, pass values of the new types instead,
    which is significantly simpler.

compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/dead_proc_elim.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/equiv_type_hlds.m:
compiler/foreign.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
compiler/mlds.m:
compiler/mode_util.m:
compiler/post_term_analysis.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_ite.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/unify_proc.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.
2021-07-01 08:26:04 +10:00
Julien Fischer
48a8d92585 Fix doubled-up words and spelling.
compiler/*.m:
compiler/notes/*:
    As above.
2021-06-20 20:29:50 +10:00