Commit Graph

81 Commits

Author SHA1 Message Date
Zoltan Somogyi
3ed9d76db6 Propagate a type into a user inst_name just once.
compiler/inst_mode_type_prop.m:
    Define a data structure, the tprop_cache, that records whether
    we have already propagated a type into a user defined inst name.

    Thread this data structure through all the code that propagates
    types into insts, and use it to propagate a type into a user inst name
    (which consists of doing a bunch of checks, and generating errors
    if those checks fail) only if have not done it before. For the
    valid/inst_perf_bug_2.m test case, this reduces the number of checks
    from more than 16 million to just 12. On my laptop, this reduces
    the compilation time from more than 13 seconds to just above one second.

    Call check_user_inst_args, the new version of maybe_check_user_inst_args,
    as part of do_check_for_bad_use_of_user_inst. maybe_check_user_inst_args
    only ever did anything if do_check_for_bad_use_of_user_inst gave it
    the data it needed, but the communication between the two predicates
    was bad. The two calls to maybe_check_user_inst_args invoked it under
    seemingly different conditions, but the conditions were actually identical,
    because they would have differed only if the inst name being worked was
    was both a user inst (tested in do_check_for_bad_use_of_user_inst) and
    a typed inst (test in its caller).

compiler/post_typecheck.m:
    Thread the tprop_cache through this module as well, since it is
    this module that invokes inst_mode_type_prop.m to do its job.

compiler/add_special_pred.m:
    Conform to the changes above.
2023-05-30 06:10:15 +02: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
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
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
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
72e0014003 Rename more predicates to avoid ambiguities. 2022-07-07 06:24:09 +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
b106006977 Prep for storing variable types in clauses_infos.
compiler/hlds_clauses.m:
    Provide a mechanism for code that creates clauses_infos to specify the
    types of the arguments. Comment it out for now, with an explanation of
    *why*.

compiler/higher_order.m:
    Similarly, write but comment out code that would create clauses_infos
    with filled in variable types.

    Encode the invariant that new predicates have one argument type
    for each argument (duh) into the higher order specialization request.

    Change the prefix on a type's function symbols in order to avoid
    ambiguity.

    Fix some misleading predicate and variable names.

    Replace a semidet function with a predicate.

compiler/arg_info.m:
    Switch a predicate to use var_tables instead of vartypes.

    Fix argument order.

compiler/table_gen.m:
    Switch a predicate to use var_tables instead of varsets/vartypes.

compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/instance_method_clauses.m:
compiler/liveness.m:
compiler/stack_opt.m:
compiler/tupling.m:
    Conform to the changes above.
2022-05-15 17:15:05 +10: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
9a9067171d Move more pred name creation to pred_name.m.
compiler/pred_name.m:
    Add two more pred name transforms: one used by I/O tabling,
    and one used by stm_expand.m.

    Change the names we generate for I/O tabling to fit in with our schemes,
    because we can (there is no part of the whole Mercury system that looks for
    the names we *used* to construct.

    Leave the names we generate for stm as they are, even though they also
    do not fit into our scheme, because changing them would obsolete
    the documentation (such as it is) in stm_expand.m.

    Return the name of instance predicates as strings, rather than
    as always-unqualified sym_names.

    Return the name of instance predicates and uci (unify, compare and index)
    predicates as strings, rather than as always-unqualified sym_names.

compiler/hlds_pred.m:
    Change the interface of the pred_info_create predicate to put the
    pred_or_func indication before the pred name. I did this originally
    to flush out places that constructed predicate names without
    going through pred_name.m. However, I also took the opportunity
    to fix an old issue, which was that

    - pred_info_create took in a sym_name to specify the name of the
      new predicate, but
    - it ignored the module name part of the sym_name, using a separately
      passed module name instead.

    This definitely violates the law of least astonishment.

    I change the interface of both pred_info_create and pred_info_init
    (which also had a similar issue, using the separately-passed module name
    only if the sym_name specifying the name was unqualified) to require
    their callers to decide the module name part of the name of the new pred,
    and pass it alongside the name that it qualifies. The changes to do this
    ended up being the bulk of the diff. (The define_new_pred predicate should
    also have this treatment applied to it, but that would have made the diff
    even larger.)

compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
    Conform to the changes above. Use variable names that distinguish
    raw names (strings) from sym_names.

    Require the sym_names in item_clause_infos, item_pred_decl_infos,
    item_mode_decl_infos, and various pragma_info_xyzs to be qualified.
    The parsing predicates that generate them implicitly qualify them
    if the name in the source code is unqualified.

    Delete the code that generated an error message when handed an
    item_pred_decl_info containing an unqualified sym_name. Due to
    the implicit quantification mentioned above, this can't happen.

    When adding foreign_procs to the HLDS, use the module name that
    came with the foreign_proc (which could have been explicit or implicit),
    *not* the name of the current module (which is what we used to use),
    when generating error messages. This difference could make the error
    message quite misleading. (We did not have a test case for this error
    message.)

compiler/add_pragma_type_spec.m:
    Conform to the changes above. Use variable names that distinguish
    raw names (strings) from sym_names.

    When adding adding type-specialized versions of predicates to the HLDS,
    use the module name that was created in parse_pragma.m; do not override
    it with the name of the module qualifier of the original predicate.
    If parse_pragma.m did its job right, the two should always be the same.

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

    Add an XXX for a questionable module qualifier we specify for a unify,
    compare or index predicate.

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

    Fix a variable version issue that caused progress messages to be
    printed at an unexpected time.

compiler/structure_reuse.versions.m:
    Conform to the changes above.

    Simplify the too-complex structure of the code that constructs
    predicate names.

compiler/accumulator.m:
compiler/check_typeclass.m:
compiler/dep_par_conj.m:
compiler/lambda.m:
compiler/par_loop_control.m:
compiler/stm_expand.m:
compiler/table_gen.m:
compiler/unused_args.m:
    Conform to the changes above.

compiler/make_hlds_error.m:
    Take the pred_or_func indicator before the predicate name.
    Use variable names that distinguish raw names (strings) from sym_names.

compiler/parse_util.m:
    Fix a missing undo of an nl_indent_delta.

compiler/foreign.m:
    Add a note about a predicate, that as far I can tell has not done
    anything useful for years, if not decades, is now unused. (This diff
    comments out the only call to it, in add_foreign_proc.m.) The only
    thing it *could* do was warn about a foreign_proc not being able
    to be implemented for the current target language, but that test
    in now done way earlier in the process, and foreign.m does not
    get called in any situation in which the message would be relevant.
2022-02-15 19:53:22 +11:00
Zoltan Somogyi
5750c35e64 Move pred-name-constructing code to pred_name.m.
compiler/pred_name.m:
    Support the construction of predicate names for more predicate transforms,
    including those done by higher_order.m and table_gen.m. Neither conformed
    to the naming scheme of the other predicate transformations. For the
    transforms done by higher_order.m, add XXXs noting this. For the transform
    done by table_gen.m, make it generate names that do conform to our pattern.
    We can do this because we only generate the affected predicates (and their
    names) in minimal model own stack grades, which are not operational :-(

    Move code to create names for the predicates implementing typeclass
    methods here.

    Move code to create names for unify, compare and index predicates here.

    Include "sym_name" in the names of the predicates that construct sym_names.

    Rename one of the existing transform_names to avoid ambiguity.

compiler/hlds_pred.m:
    Change the argument order of pred_info_init, partly to put first things
    first, but also to flush out places that construct predicate names.

compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/hlds_code_util.m:
    Delete the code moved to pred_name.m.

compiler/accumulator.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/base_typeclass_info.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/higher_order.m:
compiler/lambda.m:
compiler/layout_out.m:
compiler/loop_inv.m:
compiler/name_mangle.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/par_loop_control.m:
compiler/parse_pragma.m:
compiler/pd_info.m:
compiler/prog_rep.m:
compiler/special_pred.m:
compiler/structure_reuse.versions.m:
compiler/table_gen.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/unused_args.m:
    Conform to the changes above.

tests/debugger/mmos_print.exp:
    Update the only minimal_model_own_stack generator predicate name
    outside the compiler.
2022-02-09 11:07:10 +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
bb1b900ba6 Check "for type_ctor" annotations on user insts.
NEWS:
doc/reference_manual.texi:
    Document the fact that the compiler now does such checks.

compiler/post_typecheck.m:
    When propagating types into insts, ask inst_mode_type_prop.m to check
    whether the types being propagated into user defined insts violate the
    "for type_ctor" annotations on those insts.

    Fix a bug in my earlier change. We want to propagate types into insts,
    and check for applications of insts to values of inappropriate types
    for lambda expressions. We used try to do it by traversing each procedure's
    body goal, but this did nothing, because we copy goals to procedure bodies
    in a pass that happens *after* the post-typecheck pass. During the
    post-typecheck pass, these lambda expressions exist only in the predicate's
    clauses, so that is where now we process them.

compiler/inst_mode_type_prop.m:
    The code in this module is called not just from post_typecheck.m,
    which needs this new check, but also from other modules, which do not.
    To avoid excessive performance impact on the latter, make the
    checking optional through a typeclass with two instances,
    one of which prepares for and then does the checking, while the other
    replaces all those operations with no-ops. Then use type_spec pragmas
    to create two versions of all the predicates using this type class,
    effectively creating two versions, one with the checks and the other
    without the checks.

    Change the name of all the exported predicates of this module
    to specify whether they do these checks or not.

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

    Note a possible performance problem.

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

tests/invalid/bad_type_for_inst.{m,err_exp}:
    A test case for the error messages.

tests/invalid/Mmakefile:
    Enable the new test case.
2021-12-30 23:39:20 +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
09aff57259 Represent "is this a subtype" using a bespoke type.
compiler/prog_data.m:
compiler/hlds_data.m:
    Use a new type, maybe_subtype, to say whether a du type is a subtype.

compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/add_type.m:
compiler/check_parse_tree_type_defns.m:
compiler/comp_unit_interface.m:
compiler/decide_type_repn.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/hlds_out_module.m:
compiler/ml_type_gen.m:
compiler/mlds.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/parse_type_defn.m:
compiler/prog_type.m:
compiler/recompilation.usage.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
    Conform to the changes above.
2021-07-09 09:25:04 +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
Zoltan Somogyi
a72627888e Make the goal_type type more fit for purpose.
compiler/hlds_pred.m:
    Separate out goal types that implement a promise from those that do not.
    Document the latter. (The former is documented elsewhere.)

    When creating a new predicate, require the caller to specify
    the goal type; do not supply a default that may be wrong.

    Give some predicates more meaningful names.

compiler/add_pred.m:
    When adding an implicit predicate declaration for a promise,
    specify that the new predicate is for a promise, instead of letting
    hlds_pred.m assume by default that it is NOT for a promise.

compiler/add_clause.m:
    When adding a clause to the HLDS, do not require callers to supply
    information that they cannot possibly know.

    Specify the goal_type for a promise when creating its predicate,
    not later.

compiler/pre_typecheck.m:
    Record the goal type of field access functions, whose Mercury definition
    we just created, as containing only Mercury code. Previously, we falsely
    recorded it as containing both Mercury clauses and foreign procs.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_foreign_proc.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_special_pred.m:
compiler/check_promise.m:
compiler/check_typeclass.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/make_hlds_passes.m:
compiler/par_loop_control.m:
compiler/purity.m:
compiler/stm_expand.m:
compiler/structure_reuse.versions.m:
compiler/table_gen.m:
compiler/typecheck.m:
compiler/untupling.m:
    Conform to the changes above.
2021-05-20 00:46:18 +10:00
Zoltan Somogyi
99334e8469 Switch to structured item sequence numbers.
compiler/prog_data.m:
    Define a data type that encodes the distinction between valid
    and dummy item sequence numbers in the type. Previously, different
    parts of the compiler expressed this distinction in two different ways,
    either using "-1" to represent a dummy sequence number, or using "no"
    in a maybe(int) type.

compiler/prog_item.m:
    Use the new type instead of plain "int" as the sequence number in items.

compiler/hlds_pred.m:
    Use the new type instead of plain "int" as the sequence number
    in cur_user_decl_infos. Document the fact that the presence of a
    cur_user_decl_info in a pred_info does NOT guarantee a valid
    item sequence number.

compiler/add_foreign_proc.m:
    When adding a foreign_proc to the HLDS, pass a whole item_pragma_info,
    not its components. (This change is what this diff started as, before
    the item_seq_num changes overwhelmed it.)

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/comp_unit_interface.m:
compiler/decide_type_repn.m:
compiler/default_func_mode.m:
compiler/hlds_clauses.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/make_hlds_passes.m:
compiler/par_loop_control.m:
compiler/parse_class.m:
compiler/parse_dcg_goal.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_mutable.m:
compiler/parse_pragma.m:
compiler/parse_pragma_analysis.m:
compiler/parse_pragma_foreign.m:
compiler/parse_pragma_tabling.m:
compiler/parse_type_defn.m:
compiler/parse_type_repn.m:
compiler/parse_types.m:
compiler/proc_requests.m:
compiler/prog_mutable.m:
compiler/split_parse_tree_src.m:
compiler/stm_expand.m:
compiler/style_checks.m:
compiler/table_gen.m:
    Conform to the changes above.
2021-05-19 13:27:27 +10:00
Peter Wang
74a31ba8ef Parse and check subtype definitions.
This is the first step towards implementing a subtypes feature.
It introduces type definitions of the form

    :- type subtype =< supertype ---> body.

Later, terms of a subtype should share a data representation with their
supertype, and it will be possible to convert terms between two types
that share "base types" using a coerce operation.

doc/reference_manual.texi:
    Add documentation for subtypes.

    Add documentation for a proposed `coerce' operation, commented out
    for now.

    Add "=<" to the list of reserved type names.

compiler/hlds_data.m:
    Add supertype field to hlds_du_type.

compiler/prog_data.m:
    Add du_supertype field to type_details_du.

    Add comment for future work.

compiler/parse_type_defn.m:
    Parse subtype definitions.

    Check that variables which occur in the "=< supertype" part
    also occur on the left hand side of the subtype definition.

compiler/parse_type_name.m:
    Add a new context for why_no_ho_inst_info.

    Add "=<" to is_known_type_name, i.e. prevent the user from defining
    a type of that name (any longer).

compiler/add_type.m:
    Rename add_du_ctors_check_foreign_type_for_cur_backend to
    add_du_ctors_check_subtype_check_foreign_type.

    In add_du_ctors_check_subtype_check_foreign_type, check that
    subtype definitions satisfy the conditions documented in the
    reference manual.

compiler/make_hlds_passes.m:
    Conform to previous renaming.

compiler/comp_unit_interface.m:
    Follow supertypes when computing the required type constructors
    whose definitions need to be kept in the implementation section
    of a .int file.

compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
    Replace equivalence types in supertypes.

compiler/module_qual.qualify_items.m:
    Perform module qualification in supertypes.

compiler/hlds_out_module.m:
    Write out the "=< supertype" part of subtype definitions.

compiler/parse_tree_out.m:
    Write out the "=< supertype" part of subtype definitions.

compiler/recompilation.usage.m:
    Follow supertypes when finding used items.

compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/check_parse_tree_type_defns.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/dead_proc_elim.m:
compiler/decide_type_repn.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/du_type_layout.m:
compiler/foreign.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/post_term_analysis.m:
compiler/prog_type.m:
compiler/recompilation.check.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_ite.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to HLDS changes.

    Add comments for future work.

tests/invalid/Mmakefile:
tests/invalid/subtype_abstract.err_exp:
tests/invalid/subtype_abstract.m:
tests/invalid/subtype_circular.err_exp:
tests/invalid/subtype_circular.m:
tests/invalid/subtype_ctor_arg.err_exp:
tests/invalid/subtype_ctor_arg.m:
tests/invalid/subtype_eqv.err_exp:
tests/invalid/subtype_eqv.m:
tests/invalid/subtype_exist_constraints.err_exp:
tests/invalid/subtype_exist_constraints.m:
tests/invalid/subtype_exist_vars.err_exp:
tests/invalid/subtype_exist_vars.m:
tests/invalid/subtype_foreign.err_exp:
tests/invalid/subtype_foreign.m:
tests/invalid/subtype_foreign_supertype.err_exp:
tests/invalid/subtype_foreign_supertype.m:
tests/invalid/subtype_foreign_supertype2.err_exp:
tests/invalid/subtype_foreign_supertype2.err_exp2:
tests/invalid/subtype_foreign_supertype2.m:
tests/invalid/subtype_ho.err_exp:
tests/invalid/subtype_ho.m:
tests/invalid/subtype_invalid_supertype.err_exp:
tests/invalid/subtype_invalid_supertype.m:
tests/invalid/subtype_not_subset.err_exp:
tests/invalid/subtype_not_subset.m:
tests/invalid/subtype_syntax.err_exp:
tests/invalid/subtype_syntax.m:
tests/invalid_submodules/Mercury.options:
tests/invalid_submodules/Mmakefile:
tests/invalid_submodules/subtype_submodule.err_exp:
tests/invalid_submodules/subtype_submodule.m:
tests/valid/Mmakefile:
tests/valid/subtype_basic.m:
    Add test cases.
2021-03-15 11:16:31 +11:00
Zoltan Somogyi
1b58b0e931 Unroll an unneeded loop. 2020-08-19 10:19:33 +10:00
Zoltan Somogyi
36c2000516 Add the one_or_more and one_or_more_map modules to the library.
library/one_or_more.m:
    We used to have a type named one_or_more in the list module representing
    nonempty lists. It had literally just two predicates and two functions
    defined on it, three of which did conversions to and from lists, which
    limited their usefulness.

    This new module is the new home of the one_or_more type, together with
    a vastly expanded set of utility predicates and functions. Specifically,
    it implements every operation in list.m which makes sense for nonempty
    lists.

library/list.m:
    Delete the code moved over to one_or_more.m.

library/one_or_more_map.m:
    This new module is a near copy of multi_map.m, with the difference being
    that while the multi_map type defined in multi_map.m maps each key
    to a list(V) of values (a list that happens to always be nonempty),
    the one_or_more_map type defined in one_or_more_map.m maps each key
    to a one_or_more(V) of values (which enforces the presence of at least
    one value for each key in the type).

library/map.m:
    Mention the existence of one_or_more_map.m as well as multi_map.m.

library/MODULES_DOC:
library/library.m:
    List the new modules as belonging to the standard library.

NEWS:
    Mention the new modules, and the non-backwards-compatible changes to
    list.m.

compiler/*.m:
    Import the one_or_more module when needed.

tests/hard_coded/test_one_or_more_chunk.{m,exp}:
    Test the one predicate in one_or_more.m that is non-trivially different
    from the corresponding predicate in list.m: the chunk predicate.

tests/hard_coded/Mmakefile:
    Enable the new test case.
2020-02-28 14:29:05 +11:00
Zoltan Somogyi
e9430b115a Prep for recording simple type representations in .int3 files.
compiler/decide_type_repn.m:
    New module for computing the set of type representation items
    to put into the interface files of a module. For now, it generates
    this information only for .int3 files.

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

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

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

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

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

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

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

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

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

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

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

    Conform to the changes above.

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

    Note a possible improvement.

    Conform to the changes above.

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

compiler/simplify_goal_ite.m:
    Add a comment.

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

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

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

NEWS:
    Announce the new predicates.

library/bimap.m:
library/map.m:
library/tree234.m:
    Expand a comment.
2019-05-27 11:45:10 +02:00
Zoltan Somogyi
5722645ce5 Separate out type_info args and return values in mode error msgs.
compiler/mode_errors.m:
    When printing an error message that says "these args have these modes,
    which do not match any declared mode of the callee", avoid confusing
    users by not mentioning the extra type_info/typeclass_info args added by
    polymorphism, except in the very rare case that they could be the *cause*
    of the mode error.

    When the callee is a function, list its return value separately from
    the other arguments, again in an effort to reduce possible confusion.

compiler/mode_info.m:
    To make the above possible, record the actual pred_id of the callee
    for plain calls. This should actually be faster than the old code
    it replaces, because it avoids the computation of the call_id from
    the pred_id for all calls that do not result in error messages.

    Fix a misleading predicate name.

compiler/modecheck_goal.m:
compiler/modecheck_util.m:
compiler/unique_modes.m:
    Conform to the changes in mode_info.m.

compiler/hlds_pred.m:
    Fix a misleading predicate name.

compiler/polymorphism.m:
compiler/pred_table.m:
    Conform to the changes in hlds_pred.m.

compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/higher_order.m:
    Use variable names that specify which kind of arity they talk about:
    the one that counts functions' return values, or the one that doesn't.

tests/invalid/any_passed_as_ground.err_exp:
tests/invalid/ho_default_func_1.err_exp:
tests/invalid/ho_default_func_3.err_exp:
tests/invalid/ho_default_func_4.err_exp:
tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/state_vars_test1.err_exp:
tests/invalid/try_detism.err_exp:
    Update these expected output files to account for the change to
    mode_errors.m above.

tests/invalid/any_passed_as_ground.err_exp2:
    The old any_passed_as_ground.err_exp could not be matched for a long time
    now. The new any_passed_as_ground.err_exp actually updates the old
    any_passed_as_ground.err_exp2, since we can't have a .err_exp2 file
    without a .err_exp file. Since we now need only one expected output file,
    delete the .err_exp2 file.

tests/invalid/ho_default_func_1.err_exp2:
tests/invalid/ho_default_func_3.err_exp2:
    Delete these files, since they could not be matched for a long time now.

tests/invalid/try_detism.err_exp2:
    The same deal as with the any_passed_as_ground test case.
2019-03-13 01:33:02 +11:00
Peter Wang
5f7d3e6bb2 Use consistent integer types for some RTTI fields.
runtime/mercury_type_info.h:
    Use unsigned integer types for a few RTTI structure fields that
    are known to hold non-negative values.

    Add comments for other field types that could be changed later.

compiler/rtti.m:
    Use fixed size integer types for fields matching the size
    and signedness of the corresponding C RTTI structure fields.

    Encode type ctor flags in a uint16 instead of int.

    Make type_ctor_details_num_ptags and type_ctor_details_num_functors
    return a maybe value, instead of a negative value to represent no
    primary tags or no function symbols, respectively.

compiler/type_ctor_info.m:
    Conform to type changes.

    Use uint16 to represent the "contains var" bit vector.

compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
    Conform to type changes.

    Add comments to make it easier to find the code that writes out
    each particular RTTI structure field.

compiler/ml_util.m:
    Add helper functions.

compiler/add_special_pred.m:
compiler/du_type_layout.m:
compiler/erl_rtti.m:
compiler/erlang_rtti.m:
compiler/hlds_data.m:
compiler/llds_out_data.m:
compiler/ml_unify_gen_construct.m:
compiler/opt_debug.m:
compiler/pseudo_type_info.m:
compiler/stack_layout.m:
compiler/unify_gen_construct.m:
    Conform to type changes.

compiler/parse_type_defn.m:
compiler/prog_data.m:
    Use uint32 for functor ordinal numbers.

library/rtti_implementation.m:
    Use fixed size integer types for RTTI field accessor functions,
    and update callers.

java/runtime/DuArgLocn.java:
java/runtime/DuExistInfo.java:
java/runtime/DuExistLocn.java:
java/runtime/DuFunctorDesc.java:
java/runtime/TypeCtorInfo_Struct.java:
    Use integer types in RTTI structure definitions for Java that match
    the types in the C versions of the same structures.

runtime/mercury_dotnet.cs.in:
    Use integer types in RTTI structure definitions for C# that match
    the types in the C versions of the same structures.
2018-11-19 12:37:36 +11:00
Zoltan Somogyi
86f563a94d Pack subword-sized arguments next to a remote sectag.
compiler/du_type_layout.m:
    If the --allow-packing-remote-sectag option is set, then try to pack
    an initial subsequence of subword-sized arguments next to remote sectags.

    To allow the polymorphism transformation to put the type_infos and/or
    typeclass_infos it adds to a function symbol's argument list at the
    *front* of that argument list, pack arguments next to remote sectags
    only in function symbols that won't have any such extra arguments
    added to them.

    Do not write all new code for the new optimization; instead, generalize
    the code that already does a very similar job for packing args next to
    local sectags.

    Delete the code we used to have that picked the packed representation
    over the base unpacked representation only if it reduced the
    "rounded-to-even" number of words. A case could be made for its usefulness,
    but in the presence of the new optimization the extra code complexity
    it requires is not worth it (in my opinion).

    Extend the code that informs users about possible argument order
    rearrangements that yield better packing to take packing next to sectags
    into account.

compiler/hlds_data.m:
    Provide a representation for cons_tags that use the new optimization.
    Instead of adding a new cons_tag, we do this by replacing several old
    cons_tags that all represent pointers to memory cells with a single
    cons_tag named remote_args_tag with an argument that selects among
    the old cons_tags being replaced, and adding a new alternative inside
    this new type. The new alternative is remote_args_shared with a
    remote_sectag whose size is rsectag_subword(...).

    Instead of representing the value of the "data" field in classes
    on the Java and C# backends as a strange kind of secondary tag
    that is added to a memory cell by a class constructor instead of
    having to be explicitly added to the front of the argument vector
    by the code of a unification, represent it more directly as separate
    kind of remote_args_tag. Continuing to treat it as a sectag would have
    been very confusing to readers of the code of ml_unify_gen_*.m in the
    presence of the new optimization.

    Replacing several cons_tags that were usually treated similarly with
    one cons_tag simplifies many switches. Instead of an switch with that
    branches to the same switch arm for single_functor_tag, unshared_tag
    and shared_remote_tag, and then switches on these three tags again
    to get e.g. the primary tag of each, the new code of the switch arm
    is executed for just cons_tag value (remote_args_tag), and switches
    on the various kinds of remote args tags only when it needs to.
    In is also more natural to pass around the argument of remote_args_tag
    than to pass around a variable of type cons_tag that can be bound to only
    single_functor_tag, unshared_tag or shared_remote_tag.

    Add an XXX about possible further steps along these lines, such as
    making a new cons_tag named something like "user_const_tag" represent
    all user-visible constants.

compiler/unify_gen_construct.m:
compiler/unify_gen_deconstruct.m:
compiler/unify_gen_test.m:
compiler/unify_gen_util.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:
    Implement X = f(Yi) unifications where f uses the new representation,
    i.e. some of its arguments are stored next to a remote sectag.

    Some of the Yi are stored in a tagword (a word that also contains a tag,
    in this case the remote secondary tag), while some are stored in other
    words in a memory cell. This means that such unifications have similarities
    both to unifications involving arguments being packed next to local
    sectags, and to unifications involving ordinary arguments in memory cells.
    Therefore wherever possible, their implemenation uses suitably generalized
    versions of existing code that did those two jobs for two separate kinds of
    cons_tags.

    Making such generalizations possible in some cases required shifting the
    boundary between predicates, moving work from a caller to a callee
    or vice versa.

    In unify_gen_deconstruct.m, stop using uni_vals to represent *either* a var
    *or* a word in a memory cell. While this enabled us to factor out some
    common code, the predicate boundaries it lead to are unsuitable for the
    generalizations we now need.

    Consistently use unsigned ints to represent both the whole and the parts
    of words containing packed arguments (and maybe sectags), except when
    comparing ptag constants with the result of applying the "tag" unop
    to a word, (since that unop returns an int, at least for now).

    In a few cases, avoid the recomputation of some information that we
    already know. The motivation is not efficiency, since the recomputation
    we avoid is usually cheap, but the simplification of the code's correctness
    argument.

    Use more consistent terminology in things such as variable names.

    Note the possibility of further future improvements in several places.

compiler/ml_foreign_proc_gen.m:
    Delete a long unused predicate.

compiler/mlds.m:
    Add an XXX documenting a possible improvement.

compiler/rtti.m:
    Update the compiler's internal representation of RTTI data structures
    to make them able to describe secondary tags that are smaller than
    a full word.

compiler/rtti_out.m:
    Conform to the changes above, and delete a long-unused predicate.

compiler/type_ctor_info.m:
    Use the RTTI's du_hl_rep to represent cons_tags that distinguish
    between function symbols using a field in a class.

compiler/ml_type_gen.m:
    Provide a specialized form of a function for code in ml_unify_gen_*.m.
    Conform to the changes above.

compiler/add_special_pred.m:
compiler/bytecode_gen.m:
compiler/export.m:
compiler/hlds_code_util.m:
compiler/lco.m:
compiler/ml_closure_gen.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/rtti_to_mlds.m:
compiler/switch_util.m:
compiler/tag_switch.m:
    Conform to the changes above.

runtime/mercury_type_info.h:
    Update the runtime's representation of RTTI data structures to make them
    able to describe remote secondary tags that are smaller than a full word.

runtime/mercury_deconstruct.[ch]:
runtime/mercury_deconstruct.h:
runtime/mercury_deconstruct_macros.h:
runtime/mercury_ml_expand_body.h:
runtime/mercury_ml_arg_body.h:
runtime/mercury_ml_deconstruct_body.h:
runtime/mercury_ml_functor_body.h:
    These modules collectively implement the predicates in deconstruct.m
    in the library, and provide access to its functionality to other C code,
    e.g. in the debugger. Update these to be able to handle terms with the
    new data representation optimization.

    This update requires a significant change in the distribution of work
    between these files for the predicates deconstruct.deconstruct and
    deconstruct.limited_deconstruct. We used to have mercury_ml_expand_body.h
    fill in the fields of their expand_info structures (whose types are
    defined in mercury_deconstruct.h) with pointers to three vectors:
    (a) a vector of arg_locns with one element per argument, with a NULL
    pointer being equivalent to a vector with a given element in every slot;
    (b) a vector of type_infos with one element per argument, constructed
    dynamically (and later freed) if necessary; and (c) a vector of argument
    words. Once upon a time, before double-word and sub-word arguments,
    vector (c) also had one word per argument, but that hasn't been true
    for a while; we added vector (a) help the consumers of the expand_info
    decode the difference. The consumers of this info  always used these
    vectors to build up a Mercury term containing a list of univs,
    with one univ for each argument.

    This structure could be stretched to handle function symbols that store
    *all* their arguments in a tagword next to a local sectag, but I found
    that stretching it to cover function symbols that have *some* of their
    arguments packed next to a remote sectag and *some other* of their
    arguments in a memory cell as usual would have required a well-nigh
    incomprehensibly complex, and therefore almost undebuggable, interface
    between mercury_ml_expand_body.h and the other files above. This diff
    therefore changes the interface to have mercury_ml_expand_body.h
    build the list of univs directly. This make its code relatively simple
    and self-contained, and it should be somewhat faster then the old code
    as well, since it never needs to allocate, fill in and then free
    vectors of type_infos (each such typeinfo now gets put into a univ
    as soon as it is constructed). The downside is that if we ever wanted
    to get all the arguments at once for a purpose other than constructing
    a list of univs from them, it would nevertheless require constructing
    that list of univs anyway as an intermediate data structure. I don't see
    this downside is significant, because (a) I don't think such a use case
    is very likely, and (b) even if one arises, debuggable but a bit slow
    is probably preferable to faster but very hard to debug.

    Reduce the level of indentation of some of these files to make the code
    easier to edit. Do this by

    - not adding an indent level from switch statements to their cases; and
    - not adding an indent level when a case in a switch has a local block.

    Move the break or return ending a case inside that case's block,
    if it has one.

runtime/mercury_deep_copy_body.h:
runtime/mercury_table_type_body.h:
    Update these to enable the copying or tabling of terms whose
    representations uses the new optimization.

    Use the techniques listed above to reduce the level of indentation
    make the code easier to edit.

runtime/mercury_tabling.c:
runtime/mercury_term_size.c:
    Conform to the changes above.

runtime/mercury_unify_compare_body.h:
    Make this code compile after the changes above. It does need to work
    correctly, since we only ever used this code to compare the speed
    of unify-by-rtti with the speed of unify-by-compiler-generated-code,
    and in real life, we always use the latter. (It hasn't been updated
    to work right with previous arg packing changes either.)

library/construct.m:
    Update to enable the code to construct terms whose representations
    uses the new optimization.

    Add some sanity checks.

library/private_builtin.m:
runtime/mercury_dotnet.cs.in:
java/runtime/Sectag_Locn.java:
    Update the list of possible sectag kinds.

library/store.m:
    Conform to the changes above.

trace/mercury_trace_vars.c:
    Conform to the changes above.

tests/hard_coded/deconstruct_arg.{m,exp,exp2}:
    Extend this test to test the deconstruction of terms whose
    representations uses the new optimization.

    Modify some of the existing terms being tested to make them more diverse,
    in order to make the output easier to navigate.

tests/hard_coded/construct_packed.{m,exp}:
    A new test case to test the construction of terms whose
    representations uses the new optimization.

tests/debugger/browse_packed.{m,exp}:
    A new test case to test access to the fields of terms whose
    representations uses the new optimization.

tests/tabling/test_packed.{m,exp}:
    A new test case to test the tabling of terms whose
    representations uses the new optimization.

tests/debugger/Mmakefile:
tests/hard_coded/Mmakefile:
tests/tabling/Mmakefile:
    Enable the new test cases.
2018-08-30 05:14:38 +10:00
Zoltan Somogyi
1c13290492 Store its ordinal number with each functor.
This will be needed by an upcoming change.

compiler/prog_data.m:
compiler/hlds_data.m:
    Add the new field to (respectively) the parse tree and the HLDS
    representations of constructors.

compiler/parse_type_defn.m:
    Fill in the new field when parsing function symbols in type definitions.

compiler/du_type_layout.m:
    Transmit the ordinal number from the parse tree representation of
    constructors to their HLDS representation.

    Add some predicates needed by that upcoming change.

compiler/add_special_pred.m:
compiler/add_type.m:
compiler/check_typeclass.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/export.m:
compiler/hhf.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/ml_type_gen.m:
compiler/mode_util.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/prog_type.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/special_pred.m:
compiler/term_constr_build.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the changes above.
2018-06-08 02:58:00 +02:00
Zoltan Somogyi
24b98fdafe Pack sub-word-sized ints and dummies in terms.
Previously, the only situation in which we could pack two or more arguments
of a term into a single word was when all those arguments are enums. This diff
changes that, so that the arguments can also be sub-word-sized integers
(signed or unsigned), or values of dummy types (which occupy zero bits).

This diff also records, for each argument of a function symbol, not just
whether, and if yes, how it is packed into a word, but also at *what offset*
that word is in the term's heap cell. It is more economical to compute this
once, when the representation of the type is being decided, than to compute
it over and over again when terms with that function symbol are being
constructed or deconstructed. However, for a transition period, we compute
these offsets at *both* times, to check the consistency of the new algorithm
for computing offsets that is run at "decide representation time" with
the old algorithms run at "generate code for a unification time".

compiler/du_type_layout.m:
    Make the changes described above: pack sub-word-sized integers and
    dummy values into argument words, if possible, and if the relevant
    new option allows it. These options are temporary. If we find no problems
    with the new packing algorithm in a few weeks, we should be able to
    delete them.

    Allow 64 bit ints and uints to be stored in unboxed in two words
    on 32 bit platforms, if the relevant new option allows it. Support
    for this is not yet complete, but it makes sense to implement the
    RTTI changes for both this change and one described in the above
    paragraph together.

    For each packed argument, record not just its width, its shift and
    the mask, but also the number of bits the argument takes. Previously,
    we computed this on demand from the mask, but there is no real need
    for that when simply storing this info is so cheap.

    For all arguments, packed or not, record its offset, relative to both
    the start of the arguments, and the start of the memory cell. (The two
    are different if the arguments are preceded by either a remote secondary
    tag, the typeinfos and/or typeclass_infos describing some existentially
    typed arguments, or both.) The reason for this is given at the top.

    Centralize the decision of the parameters of packing in one predicate.

    If the option --inform-suboptimal-packing is given, print an informational
    message whenever the code deciding type representations finds that
    reordering the arguments of a function symbol would allow it to pack
    the arguments of that function symbol into less space.

compiler/options.m:
    Add the option --allow-packing-ints which controls whether
    du_type_layout.m will attempt to pack {int,uint}{8,16,32} arguments
    alongside enum arguments.

    Add the option --allow-packing-dummies which controls whether
    du_type_layout.m will optimize away (in other words, represent in 0 bits)
    arguments of dummy types.

    Add the option --allow-double-word-ints which controls whether
    du_type_layout.m will store arguments of the types int64 and uint64
    unboxed in two words on 32 bit platforms, the way it currently stores
    double precision floats.

    All three those options are off by default, which preserves binary
    compatibility with existing code. However, the first two are ready
    to be switched on (the third is not).

    All three options are intended to be present in the compiler
    only until these changes are tested. Once we deem them sufficiently
    tested, I will modify the compiler to always do the packing they control,
    at which point we can delete these options. This is why they are not
    documented.

    Add the option --inform-suboptimal-packing, whose meaning is described
    above.

doc/user_guide.texi:
    Document --inform-suboptimal-packing.

compiler/prog_data.m:
    For each argument of a function symbol in a type definition, use
    a new type called arg_pos_width to record the extra information
    mentioned above in (offsets for all arguments, and number of bits
    for packed arguments).

    For each function symbol that has some existential type constraints,
    record the extra information mentioned for parse_type_defn.m below.

compiler/hlds_data.m:
    Include the position, as well as the width, in the representation
    of the arguments of function symbols.

    Previously, we used the integer 0 as a tag for dummies. Add a tag to
    represent dummy values, since this gives more information to any code
    that sees that tag.

compiler/ml_unify_gen.m:
compiler/unify_gen.m:
    Handle the packing of dummy values, and of sub-word-sized ints and uints.

    Compare the cell offset of each argument computed using existing
    algorithms here with the cell offset recorded in the argument's
    representation, and abort if they are different.

    In some cases, restructure code a bit to make it possible.
    For example, for tuples and closures, this means that instead of
    simply recording that each tuple argument or closure element
    is a full word, we must record its correct offset as well.

    Handle the new dummy_tag.

    Add prelim (not yet finished) support for double-word int64s/uint64s
    on 32 bit platforms.

    When packing the values of two or more variables (or constants) into a
    single word in a memory cell, optimize away operations that are no-ops,
    such as shifting anything by zero bits, shifting the constant zero
    by any number of bits, and ORing anything with zero. This makes the
    generated code easier to read. It is probably also faster for us
    to do it here than to write out a bigger expression, have the C compiler
    read in the bigger expression, and then later make the same optimization.

    In ml_unify_gen.m, avoid the unnecessary use of a list of the argument
    variables' types separate from the list of the argument variables
    themselves; just look up the type of each argument variable when it is
    processed.

compiler/add_special_pred.m:
    When creating special (unify and compare) predicates for tuples,
    include the offsets in the representation of their arguments.

    Delete an unused predicate.

compiler/llds.m:
    Add a new way to create an rval: a cast. We use it to implement
    the extraction of signed sub-word-sized integers from packed argument
    words in terms. Masking the right N bits out of the packed word
    leaves the other 32-N or 64-N bits as zeroes; a cast to int8_t,
    int16_t or int32_t will copy the sign bit to these bits.
    Likewise, when we pack signed int{8,16,32} values into words,
    we cast them to their unsigned versions to throw away any sign-extension
    bits in their original word-sized representations.

    No similar change is needed for the MLDS, since that already had
    a mechanism for casts.

compiler/mlds.m:
    Note a potential simplification in the MLDS.

compiler/builtin_lib_types.m:
    Add functions to return the Mercury representation of the int64
    and uint64 types.

compiler/foreign.m:
    Export a specialized version of an existing predicate, to allow
    ml_unify_gen.m to avoid the costs of the more general version.

compiler/hlds_out_module.m:
    Always print the representations of all arguments, since the
    inclusion of position information in those representation means that
    the representations of even all-full-word-argument terms are of potential
    interest when debugging term representations.

compiler/lco.m:
    Do not try to apply LCO to arguments of dummy types. (We could optimize
    them differently, by filling them in before they are "computed", but
    that is a separate optimization, which is of *very* low priority.)

compiler/liveness.m:
    Do not include variables of dummy types in resume points.

    The reason for this is that the code that establishes a resume point
    returns, for each such variable, a list of *lvals* where that variable
    can be found. The new code in unify_gen.m will optimize away assignments
    to values of dummy types, so there is *no* lval where they can be found.
    We could allocate one, but doing so would be a pessimization. Instead,
    we simply don't save and restore such values. When their value (which is
    always 0) is needed, we can create them out of thin air.

compiler/ml_global_data.m:
    Include the target language in the ml_global_data structure, to prevent
    some of its users having to look it up in the module_info.

    Add notes about the specializing the implementation of arrays of
    int64s/uint64s on 32 bit platforms.

compiler/check_typeclass.m:
compiler/ml_type_gen.m:
    Add sanity checks of the new precomputed fields of exist_constraints.

    Conform to the changes above.

compiler/mlds_to_c.m:
    Add prelim (not yet finished) support for double-word int64s/uint64s
    on 32 bit platforms.

    Add notes about possible optimizations.

compiler/parse_type_defn.m:
    When a function symbol in a type definition contains existential
    arguments, precompute and store the set of constrained and unconstrained
    type variables. The code in du_type_layout.m needs this information
    to compute the number of slots occupied by typeinfos and typeclass_infos
    in memory cells for this function symbol, and several other places
    in the compiler do too. It is easier and faster to compute this
    information just once, and this is the earliest time what that can be done.

compiler/type_ctor_info.m:
    Use the prerecorded information about existential types to simplify
    the code here

compiler/polymorphism.m:
    Add an XXX about possibly using the extra info we now record in
    exist_constraints to simplify the job of polymorphism.m.

compiler/pragma_c_gen.m:
compiler/var_locn.m:
    Create the values of dummy variables from scratch, if needed.

compiler/rtti.m:
    Replace a bool with a bespoke type.

compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
    When generating RTTI information for the LLDS and MLDS backends
    respectively, record new kinds of arguments as needing special
    treatment. These are int64s and uint64s stored unboxed in two words
    on 32 bit platforms, {int,uint}{8,16,32} values packed into words,
    and dummy arguments. Each of these has a special code: its own negative
    negative value in the num_bits field of the argument.

    Generate slightly better formatted output.

compiler/type_util.m:
    Delete a predicate that isn't needed anymore.

compiler/opt_util.m:
    Delete a function that hasn't been needed for a while.

    Conform to the changes above.

compiler/arg_pack.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/code_util.m:
compiler/ctgc.selector.m:
compiler/dupelim.m:
compiler/dupproc.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/erl_code_gen.m:
compiler/erl_rtti.m:
compiler/export.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_out_data.m:
compiler/middle_rec.m:
compiler/ml_closure_gen.m:
compiler/ml_switch_gen.m:
compiler/ml_top_gen.m:
compiler/module_qual.qualify_items.m:
compiler/opt_debug.m:
compiler/parse_tree_out.m:
compiler/peephole.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/stack_layout.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/switch_util.m:
compiler/typecheck.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.

compiler/llds_out_util.m:
    Add a comment.

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

runtime/mercury_type_info.h:
    Allocate special values of the MR_arg_bits field of the MR_DuArgLocn type
    to designate arguments as two word int64/uint64s, as sub-word-sized
    arguments of types {int,uint}{8,16,32}, or as arguments of dummy types.
    (We already had a special value for two word float arguments.)

    Document the list of places that know about this code, so that they
    can be updated if and when it changes.

library/construct.m:
    Handle the construction of terms with two-word int64/uint64 arguments,
    with packed {int,uint}{8,16,32} arguments, and with dummy arguments.

    Factor out the code common to the sectag-present and sectag-absent cases,
    to make it possible to do the above in just *one* place.

library/store.m:
    Add an XXX to a place that I don't think handles two word arguments
    correctly. (I think this is an old bug.)

runtime/mercury_deconstruct.c:
    Handle the deconstruction of terms with two-word int64/uint64 arguments,
    with packed {int,uint}{8,16,32} arguments, and with dummy arguments.

runtime/mercury_deep_copy_body.h:
    Handle the copying of terms with two-word int64/uint64 arguments,
    with packed {int,uint}{8,16,32} arguments, and with dummy arguments.

    Give a macro a more descriptive name.

runtime/mercury_type_info.c:
    Handle taking the size of terms with two-word int64/uint64 arguments,
    with packed {int,uint}{8,16,32} arguments, and with dummy arguments.

runtime/mercury.h:
    Put related definitions next to each other.

runtime/mercury_deconstruct.h:
runtime/mercury_ml_expand_body.h:
    Fix indentation.

tests/hard_coded/construct_test.{m,exp}:
    Add to this test case a test of the construction, via the library's
    construct.m module, of terms containing packed sub-word-sized integers,
    and packed dummies.

tests/hard_coded/deconstruct_arg.{m,exp}:
    Convert the source code of this test case to state variable notation,
    and update the line number references (in the names of predicates created
    from lambda expressions) accordingly.

tests/hard_coded/uint64_ground_term.{m,exp}:
    A new test case to check that uint64 values too large to be int64 values
    can be stored in static structures.

tests/hard_coded/Mmakefile:
    Enable the new test case.
2018-05-05 13:22:19 +02:00
Zoltan Somogyi
05689ec08d Delete the cons_id_to_tag_map field in du_type_repns.
compiler/hlds_data.m:
    As above. The last part of the compiler that still used this field
    was du_type_layout_old.m.

    Delete the definition of the type of that field, since it is not now
    needed in most places.

compiler/add_foreign_enum.m:
    Add the definition of the type of that field, since it *is* needed here.

compiler/add_special_pred.m:
compiler/du_type_layout.m:
    Don't fill in the deleted field.

compiler/equiv_type_hlds.m:
compiler/hlds_out_module.m:
compiler/intermod.m:
compiler/ml_type_gen.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
    Don't copy or ignore the deleted field.
2018-02-24 16:20:40 +11:00
Zoltan Somogyi
4b98f58d9d Don't use reserved addresses to represent functors.
Late last year, we agreed to delete the ability to use the addresses
of reserved objects as cons_tags. After another (very short) discussion
on m-dev, this diff also deletes the ability to use small integers
(including zero) acting as pointers.

compiler/options.m:
    Delete the --num-reserved-addresses option.

    Add a synomym for --compiler-sufficiently-recent, with the intention
    that support for the representation of reserved addresses in RTTI
    code in the runtime will be deleted when all installed compilers
    have this new synonym.

compiler/hlds_data.m:
    Delete any mention of the reserved addresses from the cons_tag type,
    since we don't have reserved addresses anymore.

    Don't record for each type whether it uses reserved addresses;
    no type can do so anymore.

compiler/rtti.m:
    Delete the part of the RTTI representation that dealt with reserved
    addresses.

compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/bytecode_gen.m:
compiler/code_info.m:
compiler/du_type_layout.m:
compiler/equiv_type_hlds.m:
compiler/erl_rtti.m:
compiler/export.m:
compiler/hlds_out_module.m:
compiler/intermod.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/opt_debug.m:
compiler/prog_data.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_gen.m:
    Conform to the changes above, mostly by deleting code that used to deal
    with reserved addresses.
2018-02-06 16:03:44 +11:00
Zoltan Somogyi
fa50753045 Delete some redundant code. 2018-02-01 23:33:39 +11:00
Zoltan Somogyi
5d5c167d1d Make unify_proc.m more cohesive.
compiler/unify_proc.m:
compiler/add_special_pred.m:
    Move the predicates in unify_proc.m that were not concerned with
    the creation of clauses for unify, index and compare predicates
    to add_special_pred.m. Since they *were* concerned with the creation
    of special predicates, that is where they belonged.

    Delete some no-longer-relevant comments in add_special_pred.m.

compiler/higher_order.m:
compiler/proc_requests.m:
    Conform to the change above.
2018-02-01 15:13:45 +11:00
Zoltan Somogyi
fb97df69ed Make "compute type representations" a separate pass.
The ultimate purpose of this diff is to prepare for future improvements
in type representations, allowing values of some data types to be represented
more compactly than up to now.

The main way this diff does that is by creating a separate pass for deciding
how values of each type should be represented. We have traditionally decided
data representations for each type as its type definition was processed
during the make_hlds pass, but these decisions were always tentative,
and could be overridden later, e.g. when we processed foreign_type or
foreign_enum pragmas for the type. This dispersed decision making algorithm
is hard to understand, and therefore to change.

This diff centralizes decisions about type representations in a separate
pass that does nothing else. It leaves the algorithm distributed among
several files (du_type_layout.m, make_tags.m, and add_foreign_enum.m) for now,
to make reviewing this diff easier, but soon after it is committed I intend
to move all the relevant code to du_type_layout.m, to centralize the decision
code in "space" as well as in time.

For the reason why this pass runs before any of the semantic analysis
passes, instead of after all of them as I originally intended and as we
discussed on m-dev in late october 2017, see the big comment at the start of
du_type_layout.m.

As per another part of that same discussion on m-dev, this diff
makes a start on implementing a new type of item, the type_repn item,
which is intended *only* to be used in compiler-generated interface files,
*not* in source files. It is only a start because we can use these items
only *after* the creation of a separate type representation decision pass,
and this diff is already very big. The code for making the compiler understand
these items will be added later. The code for generating them will be added
later still, once the code for understanding them has been installed on
all our systems.

Since I was going to be working on the affected code anyway, this diff
also carries out two other decisions that came out of that discussion:

- the deletion of the ability to reserve a tag in a type for HAL,
  either via a compiler option or via a pragma, and

- the deletion of the ability to represent a functor using the address
  of a statically allocated object (which we haven't used and won't use,
  because it slows down accesses to *all the other functors* of the type).

compiler/mercury_compile_front_end.m:
    Invoke the new pass for making decisions about type representations
    after the make_hlds pass. (We used to do only the final part of it then.)

    Fix a bad dump stage name.

    Add an extra check for what it means for a module to be error free.

    Make a sub-switch explicit.

compiler/hlds.m:
compiler/make_hlds.m:
    Move the modules that implement the new pass from the make_hlds package
    to the hlds package, to give the compiler's top level access to them.

    Make the same move for the modules that the new pass's modules need.
    Since they are now part of hlds, they cannot reach into make_hlds,
    and I think this is a cleaner solution than forwarding predicates.

    Delete some forwarding predicates that are no longer needed.

compiler/notes/compiler_design.html:
    Document the updated location of the moved modules.

    Add an XXX to note a place where the documentation has not been
    updated in the past.

compiler/du_type_layout.m:
    Add code to implement the new pass.

    Keep the algorithm for deciding type representations as close
    to the previously used algorithm as possible, since this diff
    is already big enough. (The previous algorithm was scattered across
    add_type.m, add_foreign_enum.m, and make_hlds_passes.m.)

    Simplifications and optimizations will come later, after this module
    is merged with make_tags.m and with (at least) the foreign_enum half of
    add_foreign_enum.m.

compiler/make_tags.m:
    Keep the functionality of this module, which does both the first part
    of deciding type representations (tentatively assigning tags to functors,
    an assignment that may be overridden later), and the last part (packing
    multiple adjacent less-than-word-sized enum args into a single word,
    if possible.), but simplify it where possible, and note possibilities
    for further improvements.

compiler/add_foreign_enum.m:
    This module has two halves, one dealing with foreign_enum pragmas
    and one dealing with foreign_export_enum pragmas.

    Change the half that deals with foreign_enum pragmas to just build
    a data structure that du_type_layout.m will need to make its decisions,
    this structure being a map from type_ctors to the foreign enum
    specification applicable to the current target language. Include
    in this structure a component that add_foreign_enum.m itself can use
    to report better error messages for duplicate foreign_enum pragmas;
    this component records, for each type_ctor and language, the context
    of the previous foreign_enum pragma for that combo.

    Change the input for the half that deals with foreign_export_enum pragmas
    to reflect the fact that it is invoked by du_type_layout.m after all
    decisions about type representations have already been made.

compiler/add_special_pred.m:
    Move this module from the make_hlds package to the hlds package,
    since the code that adds special preds for type is now called from
    du_type_layout.m.

    Change the names of predicates to make clear whether they add
    only the declaration of a predicate, only its definition, or both.

    Don't try to pre-guess whether the implementation of a type's
    compare predicate will need an index predicate. Let the code
    that generates calls to the index predicate both declare and define
    the index predicate. This change removes the potential for
    inconsistencies between the two pieces of code.

compiler/add_pred.m:
    Move this module from the make_hlds package to the hlds package,
    since add_special_pred.m needs access to it.

compiler/add_type.m:
    When adding a type definition to the HLDS, don't try to decide
    its representation. Any such decision was tentative anyway, due
    to the possibility of e.g. the later processing of foreign_type
    or foreign_enum pragmas for the type. Likewise, don't try to
    create the special (unify, compare) predicates for the type.
    Leave both tasks to the du_type_layout pass.

    Likewise, don't try to pack the representation of types, or record
    no_tag types in the table of no_tag types, during the post-processing
    pass either; leave both of these to du_type_layout as well.
    Rename the predicate that post_processes type definitions to reflect
    the two tasks left for it to do.

compiler/prog_data.m:
    Do not store width information about the arguments of those data
    constructors in the parse tree. That information is not computed
    until later; until then, it was always filled in with dummy values.
    (But see hlds_data.m below.)

    Use bespoke types to represent the presence or absence of user-specified
    unify and compare predicates.

    Change the representation of data constructors to use a single "maybe"
    type, not two lists, to denote the presence or absence of existentially
    typed arguments.

    Give the HLDS the ability to hold representation information about
    abstract types that in the future we will get from type_repn items
    in the defining modules' interface files.

    Delete the uses_reserved_tag type, since we never use reserved tags
    anymore.

compiler/prog_item.m:
    Add the new type_repn item type, which is not used yet.

    Delete the reserve_tag pragma.

    Fix an earlier mistake in the wording of a context message.

compiler/hlds_data.m:
    Put all the fields of hlds_du_type (the type definition variant dealing
    with discriminated union types) that deal with type representation
    issues in a single "maybe" field that is set to "no" before the
    type representation decision pass has been run.

    Add new type, constructor_repn, that stores the same information as the old
    constructor type (defined in prog_data.m), PLUS the information
    describing how terms with that data constructor are stored.

    Likewise, add a new type ctor_arg_rep, which likewise stores
    the widths of each constructor argument. When we implement
    argument reordering, we would store the offset of the arg as well.

    Since the parse tree representations of constructors and their arguments
    don't store representation information anymore, the cons_table they
    are stored in doesn't either. Make the lookup of representation information
    for a given constructor possible by adding a map to the new "maybe" field
    of hlds_du_type.

    Provide some utility predicates.

    Optimize some existing predicates.

    Rename some types to better reflect their meaning.

compiler/hlds_module.m:
    Provide a slot in the module_info for storing the information
    gathered by make_hlds.m that is needed by the new pass.

compiler/make_hlds_separate_items.m:
    When we see either a foreign_enum or a foreign_export_enum pragma,
    return values of a bespoke type for them (a type defined in
    hlds_module.m), instead of an item_pragma. This makes handling them
    considerably easier.

compiler/make_hlds_passes.m:
    With the changes in this diff, adding a type to the HLDS won't
    decide its representation. Therefore delete the code that used
    to loop over foreign_export_enum pragmas; in the absence of
    the final type representation information, it won't work right.

    Record the information that the du_type_layout pass will need
    in the module_info.

compiler/add_pragma.m:
    Delete the code for passing on foreign_enum and foreign_export_enum
    pragmas to add_foreign_enum.m; they are now passed to add_foreign_enum.m
    by du_type_layout.m.

    Move a utility predicate to make_hlds_error.m, to allow add_foreign_enum.m
    to call it.

compiler/make_hlds_error.m:
    Add the utility predicate moved from add_pragma.m.

    Move the module from the make_hlds to the hlds package.

compiler/module_qual.m:
    Provide a mechanism for recording error messages about e.g. undefined
    types without recording that we found an undefined type. This sounds
    strange, but there is a valid use case.

    When a type definition declares a functor's argument to be of an
    undefined type, that error is usually fatal; we stop the compiler
    from proceeding even to typechecking, since the typechecker will
    probably abort with a map lookup failure. Most other references
    to undefined types are similarly fatal for the same reason. However,
    if e.g. a foreign_export_enum pragma refers to an undefined type,
    that error *won't* be visible to the typechecker, and therefore
    won't crash it. The error will still cause the compiler to exit
    without generating any target language code, but at least it will be
    able to run the typechecker and other semantic analysis passes.

    Without this change, the compiler will report only one error in
    the ee_invalid.m test case; with it, it reports *every* error
    in the test case expected output.

compiler/module_qual.qualify_items.m:
    Use the capability describe above for undefined types in
    foreign_export_enum pragmas.

compiler/module_qual.qual_errors.m:
    Delete a (somewhat incorrect) copy of a predicate in prog_item.m,
    to reduce code duplication.

compiler/prog_type.m:
    Add ways to represent abstract types whose representations are nevertheless
    known (from type_repn items in the defining modules' interface files)
    to be notag or dummy types. This will be needed to fix Mantis bug #441,
    a fix that will probably be one of the first later changes to build
    on this diff.

    Delete a type moved to type_util.m.

compiler/type_util.m:
    Provide extra versions of some predicates, with the difference between
    the old and the new versions being that one requires type representations
    to have been decided already, and the other one does not.

    Move the definition of the ctor_defn type here from prog_type.m,
    since prog_type.m itself does not use it, but type_util.m does.

    Give some predicates more meaningful names.

compiler/parse_type_defn.m:
    Simplify the code for parsing type definitions, to make it easier
    to reuse to parse type_repn items.

    Add a sanity check that requires existential constraints to have
    *some* existential variables to apply to.

    Allow "type_is_representable_in_n_bits" as a synonym for
    "type_is_abstract_enum", since in the future we want to be able to pack
    e.g. multiple int8s, not just multiple enums, into a single word.

    Generate more specific error messages for some classes of malformed input.

compiler/parse_type_repn.m:
    New module to parse type_repn items.

compiler/polymorphism.m:
    Make some predicates that operate on type constructors take
    the type constructors themselves as input arguments, not a whole type
    *using* that type constructor. Put the arguments of those predicates
    in a more standard order.

    Note that some predicates don't belong in this module.

compiler/special_pred.m:
    Make the code that decides whether a special predicate for a type
    constructor can be defined lazily avoid using type representation
    information. (Actually, we now make decisions about lazy vs eager
    definitions after type representation is available, but that was
    not so in an earlier version of this change, and the new code
    is more robust.)

compiler/unify_proc.m:
    When we decide to generate code for a compare predicate that needs
    the type to have an index predicate, don't presume that the index
    predicate has already been declared and defined; instead, declare
    and define it then and there. (Index predicates are *never* called
    from anywhere else.)

    Pack the information needed to define a special predicate
    into a single structure, to simplify the above.

    Since the creation of a clause for a compare predicate may now require
    the declaration and definition of an index predicate, the module_info
    field of the unify_proc_info is now a writeable field.

    Give some predicates and function symbols more meaningful names.

    Note some problems with the existing code.

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_solver.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/comp_unit_interface.m:
compiler/ctgc.selector.m:
compiler/ctgc.util.m:
compiler/default_func_mode.m:
compiler/det_report.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/erl_code_gen.m:
compiler/export.m:
compiler/foreign.m:
compiler/get_dependencies.m:
compiler/goal_expr_to_goal.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/inst_test.m:
compiler/inst_util.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds_warn.m:
compiler/ml_accurate_gc.m:
compiler/ml_simplify_switch.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/mode_util.m:
compiler/modecheck_goal.m:
compiler/module_qual.collect_mq_info.m:
compiler/modules.m:
compiler/parse_item.m:
compiler/parse_pragma.m:
compiler/parse_tree.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_pragma.m:
compiler/post_term_analysis.m:
compiler/proc_requests.m:
compiler/prog_item_stats.m:
compiler/qual_info.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/simplify_goal_ite.m:
compiler/stack_opt.m:
compiler/state_var.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/superhomogeneous.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_constr_build.m:
compiler/term_norm.m:
compiler/trailing_analysis.m:
compiler/type_constraints.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/unify_gen.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the changes above.

tests/invalid/Mmakefile:
    Disable the reserve_tag test case, as it is not applicable anymore.

tests/invalid/exported_foreign_enum.{m,err_exp}:
tests/invalid/pragma_qual_error.{m,err_exp}:
    Delete reserve_tag pragmas from these test cases, and its effects
    from the expected outputs.

tests/invalid/bad_foreign_type.err_exp:
tests/invalid/bigtest.err_exp:
tests/invalid/foreign_enum_invalid.err_exp:
tests/invalid/type_lhs_var.err_exp:
tests/invalid/uu_type.err_exp:
tests/invalid/where_abstract_enum.err_exp:
tests/invalid/where_direct_arg.err_exp:
    Expect the updated messages for some errors.

tests/valid/Mmake.valid.common:
tests/valid/Mmakefile:
    Disable any reserve_tag test cases, as they are not applicable anymore.
2018-01-31 17:54:40 +11:00
Zoltan Somogyi
feac1af8a4 Disable the --no-special-preds option.
compiler/options.m:
    Disable the (non-user-visible) --no-special-preds option, which was
    only ever used for a few experiments. Document why.

compiler/add_special_pred.m:
compiler/higher_order.m:
compiler/simplify_goal_unify.m:
compiler/special_pred.m:
compiler/type_ctor_info.m:
    Simplify the code that used to have to deal with the option.

tests/valid/Mercury.options:
    Don't specify the option for a test. It does not affect the test anyway.
2018-01-03 02:51:01 +11:00
Zoltan Somogyi
0e5f192401 Redo the workaround I removed yesterday.
It seems there was another reason for it, besides the originally documented
one. I documented the other reason.
2017-12-28 15:08:13 +11:00
Zoltan Somogyi
3c5a0ec926 Remove an old workaround.
compiler/type_util.m:
    Recognize the builtin primitive types when module qualified as well as
    when unqualified.

compiler/make_hlds_passes.m:
    Remove a workaround that was needed only by the absence of the above fix.

compiler/add_special_pred.m:
    Dont export a predicate whose export was needed only for the workaround.
2017-12-26 23:44:48 +11:00
Zoltan Somogyi
2ac8465659 Make the code adding new types to the HLDS readable.
The motivation for this diff was that I wanted the compiler to generate
a warning if a module declared the same type twice. (During the cleanup
of unify_proc.m I did recently, I found and fixed such a duplicate
declaration.)

compiler/add_type.m:
    The old code of module_add_type_defn was not just long (210+ lines),
    it is also very complex.

    Part of this complexity was sort-of justified. It dealt with adding
    three separate kinds of item_type_defns: abstract type "definitions",
    which are actually declarations; the definitions of Mercury types,
    and the definitions of foreign types. A single type could have more than
    one of these (e.g. declaration and a definition, or a Mercury definition
    and a foreign definition), and it had to be prepared to process these
    in any order.

    Part of this complexity was self-inflicted. The parts of the predicate
    that dealt with the same kind of definition were not always next to each
    other, and for some parts, it wasn't even clear *what* kind of definition
    it was dealing with. It did the same tests on both the old and updated
    versions of definitions, when those definitions were guaranteed to be
    identical; the "updating" predicate was a no-op. And it used completely
    different code for detecting and handling related errors.

    This diff fixes the above problems. It separates the task of adding
    an item_type_defn to the HLDS into three subtasks, done in three separate
    predicates: adding type declarations, adding Mercury definitions, and
    adding foreign definitions. It specializes each predicate to its task,
    and simplifies its decision flow. It also delegates the creation of
    (most) error messages to separate predicates. Together, these changes
    make each of module_add_type_defn_{abstract,mercury,foreign} easily
    understandable.

    Generate a warning if a type is declared twice, i.e. if e.g.
    ":- type x." is followed by another ":- type x.".

    Call module_info_incr_errors to register the presence of errors in just
    one central place. (Before, some of the places that generated error
    messages incremented the error count, and some places didn't.)

    Improve the wording of some error messages.

    Refer to type names in error messages by unqualified sym_names
    in cases where the module qualifier being elided is obvious from
    the name of the module being compiled.

    Add documentation.

    Add descriptions of potential future improvements.

    Add some XXXs at places that I think deserve them.

    Give some predicates and variables better names.

compiler/prog_data.m:
    Change the parse tree representation of type definitions by
    explicitly specifying a type for storing the contents of each kind
    of type definition.

compiler/hlds_data.m:
    Give a predicate a better name.

    Use one of the new types in prog_data.m in the HLDS version of type
    definitions, to minimize differences between the parse tree and HLDS
    versions.

compiler/add_foreign_enum.m:
compiler/add_pragma.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/foreign.m:
compiler/get_dependencies.m:
compiler/hlds_code_util.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/make_tags.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/module_qual.qualify_items.m:
compiler/parse_pragma.m:
compiler/parse_tree_out.m:
compiler/parse_type_defn.m:
compiler/post_term_analysis.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_ite.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the changes in prog_data.m.

library/io.m:
library/store.m:
    Delete duplicate type declarations that add_type.m now complains about.

tests/invalid/bad_foreign_type.{m,err_exp}:
    Extend this test to test the new warning.

    Expect the updated versions of some error messages.

tests/invalid/extra_info_prompt.err_exp:
tests/invalid/foreign_type_visibility.err_exp:
tests/invalid/user_eq_dummy.err_exp:
    Expect the updated versions of some error messages.
2017-06-27 18:15:58 +02:00
Zoltan Somogyi
95ff02b1bf Add options to check the ordering of module contents.
One option, --warn-non-contiguous-decls, generates warnings if the
mode declarations of a predicate or function aren't in a contiguous block
immediately following the pred or func declaration. Since this is a rare
kind of "style error", this option is enabled by default.

Two options, --warn-inconsistent-pred-order-clauses and
--warn-inconsistent-pred-order-foreign-procs, warn about inconsistencies
between (a) the order in which predicates (and functions) are declared,
and (b) the order in which they are defined. The two options differ in
their scope. The latter applies to all predicates and functions defined
in the module, while the former applies only to those whose definitions
include Mercury clauses.

Since an exported predicate or function may need nonexported auxiliary
predicates and/or functions, imposing a single order the declarations and
definitions of *all* the predicates and functions in a module is not a good
idea. Instead, both options divide the predicates and functions defined
in a module two groups, the exported and the nonexported, and expect
a consistent order only within each group.

The result is output that looks like this:

    time.m:021: Warning: the order of the declarations and definitions of the
    time.m:021:   exported predicates is inconsistent, as shown by this diff:
    time.m:021:
    time.m:021:   --- declaration order
    time.m:021:   +++ definition order
    time.m:021:   @@ -1,7 +1,7 @@
    time.m:021:    predicate `clock'/3
    time.m:021:   -predicate `time'/3
    time.m:021:    predicate `times'/4
    time.m:021:    function `clk_tck'/0
    time.m:021:   +predicate `time'/3
    time.m:021:    function `difftime'/2
    time.m:021:    predicate `localtime'/4
    time.m:021:    function `localtime'/1

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

compiler/style_checks.m:
    A new module that generates the new warnings if warranted.

compiler/check_hlds.m:
compiler/notes/compiler_design.html:
    Include and document the new module.

compiler/mercury_compile_front_end.m:
    Invoke the new module if any of the three new options is set.

compiler/hlds_pred.m:
    Record the item number of every predicate, function, and mode declaration
    in the module being compiled. We need this for information for the
    new warnings.

compiler/hlds_module.m:
    Record the context of the module declaration. We use this context
    for warnings about inconsistent order, since there isn't a better one.

compiler/hlds_clauses.m:
    Add a mechanism to retrieve the item numbers of a set of clauses
    even if they are contiguous.

    Document some old data types.

compiler/error_util.m:
    Add a new phase for style checks.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/clause_to_proc.m:
compiler/from_ground_term_util.m:
compiler/lambda.m:
compiler/make_hlds.m:
compiler/make_hlds_passes.m:
compiler/mercury_compile.m:
compiler/par_loop_control.m:
compiler/polymorphism.m:
compiler/stm_expand.m:
compiler/table_gen.m:
compiler/unify_proc.m:
    Conform the changes to the HLDS above.

compiler/typecheck_errors.m:
    Fix style of error messages.

library/array2d.m:
library/assoc_list.m:
library/benchmarking.m:
library/bit_buffer.write.m:
library/bool.m:
library/builtin.m:
library/construct.m:
library/cord.m:
library/counter.m:
library/float.m:
library/injection.m:
library/lazy.m:
library/lexer.m:
library/ops.m:
library/private_builtin.m:
library/profiling_builtin.m:
library/prolog.m:
library/queue.m:
library/rational.m:
library/require.m:
library/stack.m:
library/std_util.m:
library/store.m:
library/thread.semaphore.m:
library/tree234.m:
library/univ.m:
library/version_store.m:
    Move declarations or definitions around to avoid some of the warnings
    that we can now generate. (There are many more left.)

    Make some minor style improvements in the process.

tests/warnings/inconsistent_pred_order.{m,exp}:
tests/warnings/non_contiguous_decls.{m,exp}:
    New test cases to test the new options. They are both copies of
    tests/benchmarks/queens.m, with intentionally-screwed-up style.

tests/warnings/Mmakefile:
    Enable the new test cases.

tests/warnings/Mercury.options:
    Specify the options being tested for the new test cases.

tests/benchmarks/queens.m:
    Bring the style of this module up to date (before copying it).

tests/invalid/mode_decl_in_wrong_section.err_exp:
    Expect the warnings we now generate.
2016-10-15 17:26:32 +11:00
Zoltan Somogyi
1da267e9f0 Fix a bug in handling instances with --warn-unused-imports.
This fixes Mantis bug #412.

compiler/unused_imports.m:
    Consider that an instance declaration makes a module "used" only if
    it occurs in the module being compiled, not in an imported or ancestor
    module. (Mantis bug 412 was caused by instance declarations in implicitly
    imported modules.)

    Fixing #412 also exposed another bug. When computing the set of modules
    used by predicates, we considered (besides some non-type entities)
    only the types of the predicate's arguments, not the types of non-argument
    variables. In one case in the compiler (mmc_analysis.m), this lead to
    some actually-used modules not being marked as such, which lead to
    false unused-import warnings to be generated for them. Fix this by scanning
    the types of all variables in all of a predicate's procedures, not just
    the arguments.

    Improve the infrastructure for debugging similar problems.

    Note some possibilities for future improvement.

    Change a predicate name to fit the naming scheme.

compiler/analysis.m:
    Add an XXX about a possible improvement.

compiler/hlds_out_module.m:
    Make the output we generate for instance methods more readable.
    As part of this, fix an old bug in the printing of the instance table:
    the first line of the first method of each concrete instance declaration
    was accidentally commented out.

compiler/parse_tree_out.m:
    Export a different utility predicate for hlds_out_module.m. Make its name
    conform to the scheme used by related predicates.

browser/browse.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/check_for_missing_type_defns.m:
compiler/check_promise.m:
compiler/exception_analysis.m:
compiler/handle_options.m:
compiler/inst_match.m:
compiler/mercury_to_mercury.m:
compiler/ml_tailcall.m:
compiler/module_qual.m:
compiler/op_mode.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_tree_out_clause.m:
compiler/parse_tree_out_info.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_out_pragma.m:
compiler/parse_tree_out_pred_decl.m:
compiler/parse_tree_out_term.m:
compiler/parse_type_defn.m:
compiler/parse_type_name.m:
compiler/parse_util.m:
compiler/parse_vars.m:
compiler/prog_ctgc.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/term_constr_main.m:
compiler/term_constr_main_types.m:
compiler/write_deps_file.m:
library/bt_array.m:
    Delete unused imports.

compiler/module_qual.qual_errors.m:
    Import a module that the parent module_qual.m doesn't import anymore.

tests/warnings/bug412.{m,exp}:
    The test case for this bug.

tests/warnings/Mmakefile:
tests/warnings/Mercury.options:
    Enable the new test case.

tests/invalid/import_in_parent.err_exp:
    Update the expected output for this test case. The parent module
    does not use the imported module (bool) at all, so this is what the
    error message says after this diff, though its submodule does use bool.
2016-07-17 10:20:29 +02:00
Zoltan Somogyi
a0760327b6 Do stricter checking of mode and determinism declarations.
Specifically, we now do three new checks:

BAD_DETISM: We now generate error messages for predicate declarations
that specify a determinism without also specifying argument modes.

BAD_PREDMODE: We now generate error messages for standalone mode declarations
for predicates whose predicate declaration includes modes for the arguments.

BAD_MODE_SECTION: We now generate error messages for standalone mode
declarations that are not in the same section as the predicate's (or
function's) type declaration.

compiler/hlds_pred.m:
    Add a slot to the pred_sub_info. If the predicate is explicitly defined by
    the user in the current module, this contains the id of the section that
    contains its predicate declaration (for the BAD_MODE_SECTION check)
    and whether that predicate declaration also had modes for the arguments
    (for the BAD_PREDMODE check).

compiler/add_pred.m:
    When adding adding new predicate declarations, perform the BAD_DETISM
    check, and record the info needed for the BAD_PREDMODE and BAD_MODE_SECTION
    checks.

    When adding adding new mode declarations, perform the BAD_PREDMODE
    and BAD_MODE_SECTION checks.

compiler/add_class.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_solver.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/dep_par_conj.m:
compiler/higher_order.m:
compiler/make_hlds_passes.m:
compiler/table_gen.m:
compiler/unused_args.m:
    Conform to the changes above.

mdbcomp/builtin_modules.m:
    Add a utility predicate for use by new code in add_pred.m.

compiler/comp_unit_interface.m:
compiler/goal_util.m:
compiler/prog_rename.m:
compiler/quantification.m:
deep_profiler/program_representation_utils.m:
library/calendar.m:
library/mutvar.m:
library/pretty_printer.m:
library/random.m:
library/set_ctree234.m:
library/solutions.m:
library/stream.string_writer.m:
profiler/globals.m:
tests/accumulator/nonrec.m:
tests/accumulator/out_to_in.m:
tests/declarative_debugging/library_forwarding.m:
tests/dppd/applast_impl.m:
tests/dppd/grammar_impl.m:
tests/dppd/regexp.m:
tests/dppd/transpose_impl.m:
tests/hard_coded/copy_pred.m:
tests/hard_coded/ho_func_default_inst.m:
tests/recompilation/unchanged_pred_nr_2.m.1:
tests/recompilation/unchanged_pred_nr_2.m.2:
tests/valid/det_switch.m:
tests/valid/inlining_bug.m:
    Delete determinism declarations from predicate and function declarations
    that have no argument mode information, since the BAD_DETISM check
    now makes these errors.

tests/valid/two_pragma_c_codes.m:
    Move some mode declarations to the right section, since the
    BAD_MODE_SECTION check now generates an error for the old code.

tests/invalid/typeclass_bad_method_mode.{m,err_exp}:
    New test case to test for the BAD_PREDMODE check.

tests/invalid/mode_decl_in_wrong_section.{m,err_exp}:
    New test case to test for the BAD_MODE_SECTION check.

tests/invalid/bad_detism.err_exp:
    Add an expected output for this old, but never enabled test case,
    which tests for new check BAD_DETISM.

tests/invalid/Mmakefile:
    Enable the new test cases.

tests/invalid/typeclass_dup_method_mode.m:
    This test case used to have two bugs. One is now by itself in the new
    typeclass_bad_method_mode.m test case, so modify it to contain only
    the other (indistinguishable modes).

tests/invalid/func_errors.err_exp:
tests/invalid/tc_err1.err_exp:
tests/invalid/undef_lambda_mode.err_exp:
tests/invalid/undef_type_mode_qual.err_exp:
    Expect an extra error message from the BAD_DETISM check.
2016-01-13 02:03:16 +11:00
Zoltan Somogyi
73ef502981 Delete unneeded imports. 2015-12-05 06:33:48 +11:00
Zoltan Somogyi
c6ab550db8 Remove the code for automatic initialization of solver vars.
We haven't supported it in years, and keeping it in the compiler
is just a maintenance burden and a performance problem.

mdbcomp/prim_data.m:
    Delete the spec_pred_init functor, since we don't support special
    "init" predicates anymore.

compiler/prog_data.m:
    Delete the slot in solver type details that record the name of the
    auto-initialization predicate.

compiler/prog_io_type_defn.m:
    Don't allow a type definition to specify an auto-initialization predicate.

compiler/options.m:
compiler/globals.m:
    Delete the option that allowed support for auto-initialization to be
    turned back on.

compiler/inst_match.m:
compiler/inst_util.m:
    Delete comments about auto-initialization.

compiler/mode_info.m:
    Delete the record of whether we have variables that can be
    auto-initialized (we never do anymore) and the flag that controls whether
    auto-initialization is permitted or not.

compiler/modecheck_conj.m:
    Simplify the code that modechecks conjunctions, since it no longer
    has to figure out where to insert auto-initializations of solver vars.

compiler/modecheck_goal.m:
    Delete the code that ensured that if one branch of a branched
    control structure auto-initialized a solver variable, then they
    all did.

compiler/modecheck_unify.m:
    Don't auto-initializate variables before unifications.

compiler/modecheck_util.m:
    Delete the code that auto-initialized solver variables at the ends
    of procedure bodies if this needed to be done and wasn't done before.

compiler/add_special_pred.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/get_dependencies.m:
compiler/hlds_module.m:
compiler/hlds_pred.m:
compiler/modecheck_call.m:
compiler/modes.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/post_term_analysis.m:
compiler/smm_common.m:
compiler/special_pred.m:
compiler/term_constr_errors.m:
compiler/term_constr_initial.m:
compiler/term_util.m:
compiler/termination.m:
compiler/trace_params.m:
compiler/type_util.m:
compiler/unify_proc.m:
    Delete code that handled stuff related to auto-initialization,
    and now always take the path that would normally be taken in the
    absence of auto-initialization.

deep_profiler/read_profile.m:
runtime/mercury_layout_util.c:
runtime/mercury_stack_trace.c:
util/mdemangle.c:
    Remove code that recognized the compiler-generated name of initialization
    predicates.

tests/debugger/solver_test.m:
tests/hard_coded/solver_construction_init_test.m:
tests/hard_coded/solver_disj_inits.m:
tests/hard_coded/solver_ite_inits.m:
tests/invalid/missing_init_pred.m:
tests/invalid/zinc2mer_lib.m:
tests/valid/fz_conf.m:
tests/valid/solver_type_bug_2.m:
tests/valid/solver_type_mutable_bug.m:
    These tests tested the handling of auto-initialization, which we
    no longer support. Keep them around (and a bit more visible than
    inside the git repo) in case we need them again, but add a comment
    to each saying that the test is disabled.

tests/debugger/Mercury.options:
tests/debugger/Mmakefile:
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/valid/Mercury.options:
tests/valid/Mmakefile:
    Disable those tests.

tests/warnings/non_term_user_special.{m,exp}:
    Part of this test tested the handling of auto-initialization;
    delete that part.

tests/warnings/Mercury.options:
    Delete the flag required by the deleted part, since we don't support it
    anymore.
2015-12-03 05:06:28 +11:00
Zoltan Somogyi
cc9912faa8 Don't import anything in packages.
Packages are modules whose only job is to serve as a container for submodules.
Modules like top_level.m, hlds.m, parse_tree.m and ll_backend.m are packages
in this (informal) sense.

Besides the include_module declarations for their submodules, most of the
packages in the compiler used to import some modules, mostly other packages
whose component modules their submodules may need. For example, ll_backend.m
used to import parse_tree.m. This meant that modules in the ll_backend package
did not have to import parse_tree.m before importing modules in the parse_tree
package.

However, this had a price. When we add a new module to the parse_tree package,
parse_tree.int would change, and this would require the recompilation of ALL
the modules in the ll_backend package, even the ones that did NOT import ANY
of the modules in the parse_tree package.

This happened even at one remove. Pretty much all modules in every one
of the backend have to import one or more modules in the hlds package,
and they therefore have import hlds.m. Since hlds.m imported transform_hlds.m,
any addition of a new middle pass to the transform_hlds package required
the recompilation of all backend modules, even in the usual case of the two
having nothing to do with each other.

This diff removes all import_module declarations from the packages,
and replaces them with import_module declarations in the modules that need
them. This includes only a SUBSET of their child modules and of the non-child
modules that import them.
2015-11-13 15:03:20 +11:00
Zoltan Somogyi
f2acc09ce6 Speed up operations on special pred maps.
The special_pred_map type used to have a pair of a special_pred_id and a
type_ctor as its key. This meant that we compared the special_pred_ids
on every level of a lookup. Since there are only four special_pred_ids
(for unify, index, compare and solver init predicates), this is wasteful.

Replace the special_pred_map type with the special_pred_maps type,
which is a tuple of four maps, one for each special_pred_id, in which
the keys are just type_ctors. Looking at the special_pred_id just once
should speed up operations.

compiler/special_pred.m:
    As above.

    Provide search and lookup predicates on the special_pred_maps type,
    since it is no longer just a simple map.search or map.lookup.

    Put the definitions of predicates into the same order as their
    declarations.

compiler/hlds_pred.m:
    Remove an unnecessary cell from the representation of origin_special_pred.

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

    Use map.det_insert instead of map.set when adding new entries
    to the special_pred_maps.

compiler/deep_profiling.m:
compiler/det_report.m:
compiler/elds_to_erlang.m:
compiler/exception_analysis.m:
compiler/float_regs.m:
compiler/hlds_error_util.m:
compiler/hlds_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
compiler/layout_out.m:
compiler/liveness.m:
compiler/ml_code_util.m:
compiler/mode_errors.m:
compiler/oisu_check.m:
compiler/polymorphism.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/proc_gen.m:
compiler/proc_label.m:
compiler/simplify_goal_unify.m:
compiler/smm_common.m:
compiler/structure_reuse.direct.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.domain.m:
compiler/term_constr_initial.m:
compiler/termination.m:
compiler/trace_params.m:
compiler/type_constraints.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/unused_args.m:
    Conform to the above changes.
2015-09-12 12:04:18 +10:00
Zoltan Somogyi
656493dfdf Use separate types for the status of different entity kinds.
We used the old import_status type to represent the status of six different
kinds of entities:

- types
- insts
- modes
- typeclasses
- instances
- predicates

even though some statuses that made sense for one kind of entity didn't for
another another (e.g. predicates can be pseudo imported/exported, but the
other five kinds of entities cannot).

Create the new types type_status, inst_status, ..., pred_status to represent
the status of these entities in the HLDS. For now, these are just wrappers
around the renamed old_import_status type, but I plan to replace them with
status types that *are* specialized to the applicable kind of entity,
along the lines of compiler/notes/status_proposal. This is a necessary
first step towards that proposal.

compiler/status.m:
    Define the six new entity-kind-specific status types, and replicate
    the test predicates that used to work on the import_status type
    to work on these instead.

    Define a status type, item_mercury_status, that contains just the info
    that is common to all entities in an item block, for use during
    the process of adding items to the HLDS.

    Move the predicates that converted section markers to statuses
    from here to make_hlds_passes.m, since that is the only place
    where they are used, or can be used.

    Move the combine_status predicate here from add_type.m, since
    it is needed for combining the statuses of other kinds of entities
    as well, not just types.

compiler/hlds_data.m:
    Change the HLDS types that record the information we have about
    types, du type fields, insts, modes, typeclasses and instances
    to have kind-specific status fields, instead of the old generic
    import_status type.

    Change the prefix on the field names of the hlds_instance_defn type
    to avoid a name clash, and to make them more meaningful.

    Change the prefix on the field names of the hlds_class_defn type
    to make them more meaningful.

compiler/hlds_pred.m:
    Change the HLDS type that records the information we have about predicates
    to have a kind-specific status field, instead of the old generic
    import_status type.

    Update the predicates that test predicate statuses accordingly.

compiler/hlds_module.m:
    Change the HLDS types that record the information we have about
    type constructors to be type_status, not the old generic import_status.

compiler/make_hlds_passes.m:
    As we process each item block, pass along an item_mercury_status
    instead of an import_status. The code used to use only a subset
    of the possible values of the import_status type, since we can never say
    that all the entities in an item block are e.g. pseudo-exported.
    An item_mercury_status has just the information we actually *know*
    about the item block as a whole. We convert the item_mercury_status
    to a kind-specific status if and when we need to, but for several purposes,
    the item_mercury_status is enough on its own.

    In a few cases, add a new predicate to do this conversion.

    Pass the need_qualifier flag separately from the status. It is needed
    in only a few places, but this was not apparent when we always passed it
    around paired with the import_status.

    Move the predicates that converted section markers to statuses
    to here from status.m, since here is the only place where they are used,
    or can be used.

compiler/add_class.m:
    Convert the statuses of typeclasses and instances to the statuses
    of the predicates implementing their virtual and concrete methods.

compiler/check_typeclass.m:
    Simplify some over-complex code.

compiler/add_special_pred.m:
    Convert the statuses of types to the statuses of the predicates
    implementing their unify, index, compare and solver init operations.
    Note some places where the process of this conversion is (to say the least)
    unclear and undocumented.

compiler/hlds_out_util.m:
    Provide utility predicates to print all the new kinds of statuses.
    These replace the old predicate that did the same in hlds_out_pred.m,
    but printing e.g. type statuses in hlds_out_pred doesn't seem right.

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

    Consistently use switches on the booleans returned by xxx_status_to_write,
    instead wrapping a semidet predicate around it and calling that.
    The switches yield code that is both smaller and more maintainable.

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

    Delete a simple wrapper predicate that was used only in one place.
    That place now does the wrapping itself.

compiler/qual_info.m:
    Replace the import_status field in the qual_info with a simple
    is_opt_imported/is_not_opt_imported flag, since that was the only
    thing we used the import_status field for.

compiler/accumulator.m:
compiler/add_clause.m:
compiler/add_foreign_enum.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_type.m:
compiler/base_typeclass_info.m:
compiler/ctgc.util.m:
compiler/dead_proc_elim.m:
compiler/dep_par_conj.m:
compiler/dependency_graph.m:
compiler/det_report.m:
compiler/elds_to_erlang.m:
compiler/equiv_type_hlds.m:
compiler/erl_code_gen.m:
compiler/export.m:
compiler/float_regs.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/inst_check.m:
compiler/lambda.m:
compiler/lco.m:
compiler/make_hlds.m:
compiler/make_hlds_warn.m:
compiler/make_tags.m:
compiler/ml_proc_gen.m:
compiler/ml_type_gen.m:
compiler/mode_errors.m:
compiler/oisu_check.m:
compiler/par_loop_control.m:
compiler/polymorphism.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/prop_mode_constraints.m:
compiler/recompilation.usage.m:
compiler/simplify_proc.m:
compiler/smm_common.m:
compiler/special_pred.m:
compiler/ssdebug.m:
compiler/status.m:
compiler/stm_expand.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/superhomogeneous.m:
compiler/table_gen.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/termination.m:
compiler/trace_params.m:
compiler/type_class_info.m:
compiler/type_constraints.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/typecheck_info.m:
compiler/typeclasses.m:
compiler/unify_proc.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.
2015-09-12 09:07:45 +10:00
Zoltan Somogyi
f2043fc9bd Replace the item list with more structured ASTs.
The parts of the compiler that run before the HLDS is constructed used to use
a raw list of items to represent source files (.m), interface files (.int0,
.int3, .int2 and .int) and optimization files (.opt, and .trans_opt).
These lists had structure, but this structure was implicit, not explicit,
and its invariants were never really documented.

This diff changes that. It replaces the item list with FIVE separate types.

Three of these each represent the unprocessed content of one file:

- parse_tree_int represents the contents of one interface file;
- parse_tree_opt represents the contents of one optimization file;
- parse_tree_src represents the contents of one source file.

Two of these each represent the processed contents of one or more files:

- raw_compilation_unit represents the contents of one module in a source file.
  (The source file may contain several nested modules; the compilation unit
  represents just one.)
- aug_compilation_unit represents the contents of one module in a source file,
  just like raw_compilation_unit, but it is augmented with the contents of the
  interface and optimization files of the other modules imported (directly or
  indirectly) by the original module.

These five separate concepts all used to be represented by the same type,
list(item), but different invariants applied to the structure of those lists.
The most important of those invariants at least are now explicit in the types.
I think it is entirely possible that there are other invariants I haven't
discovered and documented (for example, .int3 files must have stricter
invariants on what can appear in them than .int files), but discovering
and documenting these should be MUCH easier after this change.

I have marked many further opportunities for improvements with "XXX ITEM_LIST".
Some of these include moving code between modules, and the creation of new
modules. However, I have left acting on those XXXs until later, in order to
keep the size of this diff down as much as possible, for easier reviewing.

compiler/prog_item.m:
    Define the five new AST types described above, and utility predicates
    that operate on them.

    In the rest of this change, I tried, as much as possible, to change
    predicates that used to take item lists as arguments to make them change
    one of these types instead. In many cases, this required putting
    the argument lists of those predicates into a more consistent order.
    (Often, predicates that operated on the contents of the module
    took the name of the module and the list of items in the module
    not just as separate arguments, but as separate arguments that
    weren't even next to each other.)

    Define types that identify the different kinds of interface and
    optimization files (.int, .int2 etc). These replace the string suffixes
    we used to use to identify file types. Predicates that used to take strings
    representing suffixes as arguments now have to specify whether they can
    handle all these file types (source, interface and optimization),
    or just (e.g.) all interface file types.

    We used to have items corresponding to `:- module' and `:- end_module'.
    Delete these; this information is now implicit in the structure of the
    relevant AST. The parser handles the corresponding terms as markers,
    not items; these markers are live only during parsing.

    We used to have module_defns corresponding to `:- interface' and
    `:- implementation'. Delete these; this information is now also implicit
    in the structure of the relevant AST. Delete also, for the same reason,
    the module_defns used to mark the starts of sublists in the overall lists
    of items whose items came from the interface files or optimization files
    of other modules. The former are now markers during parsing. The latter
    are never parsed, but are created directly, after parsing has been done.

    Delete the pragma type for `:- pragma source_file'. This is never
    needed later; it is now a marker during parsing.

    Change the internal representation of `:- import' and `:- use'.
    It used to store a list of module names, but that list was an actual list
    only during parsing; after that, it always had exactly one element.
    It now stores one module name, and the parser has a mechanism to convert
    one read-in term to more than one item, for use with terms such as
    `:- import_module a, b'.

    Delete the internal representation of `:- export', which was never
    implemented, since if it IS ever implemented, it will almost certainly
    be in a different form, which will need different support.

    Document some further opportunities for simplification, later.
    (This diff is already more than big enough.)

compiler/prog_io_item.m:
    Rewrite the top-level part of this module. Instead of returning an item
    for every parsed term, distinguish between parsing items that end up
    in item lists inside ASTs, and parsing markers that end up creating
    the STRUCTURE of those ASTs.

compiler/prog_io.m:
    Rewrite the meat of this module. Instead of reading in a simple item list,
    we now have to read in three different parse trees with three different
    grammars, each of which is more complex than a simple list.

compiler/read_modules.m:
    We used to have a map that mapped file names to the contents of those
    files. We now need three separate maps, for interface files, optimization
    files and source files, due to their separate types.
    (We don't actually use the map for optimization files, which seems
    to be a potential performance bug. The root cause of that problem
    us that while intermod.m and the grab_*modules part of modules.m do
    similar jobs, they don't use the same mechanisms.)

    Replace the read_module predicate with the predicates read_module_src
    and read_module_int, since these now return different types.

    To avoid having to create AST-type-specialized variants of
    read_module_ignore_errors and read_module_if_changed, give each of
    read_module_{src,int} arguments that optionally tell them to ignore errors
    and/or to read the module only if changed (though the "and" part of
    "and/or" should not be needed.) These options already existed, but
    they weren't exported.

compiler/timestamp.m:
    Define the type we use for this option in read_modules.

compiler/status.m:
    New module, containing mostly

    - stuff carved out of hlds_pred.m, which defines the import_status type,
      and the predicates that operate on it;
    - stuff carved out of make_hlds_passes.m, which defines the item_status
      type and the predicates that operate on that; and
    - stuff carved out prog_data.m, which defines the section (now
      module_section) and import_locn types.

    It also contains the new section kinds we now use to represent item blocks
    that were imported from interface and optimization files.

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

compiler/hlds_pred.m:
compiler/prog_data.m:
    Remove the stuff now in status.m.

compiler/error_util.m:
    Provide a mechanism to control the order of messages with respect to
    ALL other messages, not just those that also specify ordering.

compiler/mercury_to_mercury.m:
    Provide predicates for printing out parse_tree_* and *_compilation_unit,
    since printing out a simple item list is no longer enough for debugging.

    Pretty-print type definitions nicely.

    Replace a boolean with a purpose-specific enum.

compiler/modules.m:
    Rewrite virtually all this module to make it work on the new AST
    representations. Generate more detailed error messages for duplicate
    module inclusions. Note lots of possibilities for further improvements,
    including in the documentation. Mark places I am still not sure about,
    especially places where I am not sure *why* the code is doing
    what it is doing.

compiler/module_imports.m:
    This module stores the data structure in which we accumulate the stuff
    imported into a compilation unit, i.e. it is in these data structures
    that a raw_compilation_unit becomes an aug_compilation_unit. Modify
    the data structure and the predicates that operate on it to work on the
    new AST representations, not on an (apparently) simple list of items.

    Avoid ambiguities by adding a prefix to field names.

    Add some convenience predicates.

compiler/module_qual.m:
    Perform module qualification on both raw lists of items (for use when
    generating .int3 files) but also on item blocks (for use pretty much
    in every other situation).

    Generate warnings about module imports that are unnecessarily in the
    module interface using the module's context (the context of the `:- module'
    declaration), not line 1 of the relevant file.

compiler/prog_io_error.m:
    Split some error categories more finely, since some error kinds here
    actually used to be reported for more than one distinct situation.

compiler/prog_io_util.m:
    Provide utility predicates that operate on nonempty lists.

compiler/recompilation.version.m:
    Make the comparison of the old and new contents of the interface file
    work on two parse_tree_ints, not on two raw sequences of items.

    Delete a boolean option that was always `yes', never 'no'.

compiler/recompilation.m:
    Turn some functions into predicates to allow the use of state variable
    notation.

    Avoid ambiguities by adding a prefix to field names.

compiler/write_module_interface_files.m:
    Besides updating the code in this module to work on the new parse tree
    representations, also use cords instead of reversed lists in several cases.
    Note many possibilities for further improvements.

library/list.m:
    Move the type one_or_more here from the compiler directory, since
    we now use it in more than one compiler module, and this is its natural
    home.

mdbcomp/sym_name.m:
    Rename "match_sym_name" to "partial_sym_name_matches_full", since this
    better describes its job.

    Add a det version of sym_name_get_module_name.

compiler/equiv_type.m:
    Rename some types to make them more expressive.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_foreign_enum.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_special_pred.m:
compiler/add_type.m:
compiler/assertion.m:
compiler/base_typeclass_info.m:
compiler/check_typeclass.m:
compiler/ctgc.util.m:
compiler/dead_proc_elim.m:
compiler/dep_par_conj.m:
compiler/dependency_graph.m:
compiler/deps_map.m:
compiler/det_report.m:
compiler/elds_to_erlang.m:
compiler/equiv_type_hlds.m:
compiler/erl_code_gen.m:
compiler/export.m:
compiler/format_call.m:
compiler/higher_order.m:
compiler/hlds_data.m:
compiler/hlds_module.m:
compiler/hlds_out_pred.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/lco.m:
compiler/make.module_dep_file.m:
compiler/make_hlds.m:
compiler/make_hlds_error.m:
compiler/make_hlds_passes.m:
compiler/make_tags.m:
compiler/mercury_compile.m:
compiler/ml_proc_gen.m:
compiler/ml_type_gen.m:
compiler/mode_errors.m:
compiler/oisu_check.m:
compiler/par_loop_control.m:
compiler/polymorphism.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/pred_table.m:
compiler/prog_io_dcg.m:
compiler/prog_io_find.m:
compiler/prog_io_pragma.m:
compiler/prog_io_sym_name.m:
compiler/prog_io_type_defn.m:
compiler/prog_io_typeclass.m:
compiler/prop_mode_constraints.m:
compiler/push_goals_together.m:
compiler/qual_info.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/simplify_proc.m:
compiler/smm_common.m:
compiler/special_pred.m:
compiler/ssdebug.m:
compiler/stm_expand.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/table_gen.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/termination.m:
compiler/trace_params.m:
compiler/trans_opt.m:
compiler/type_class_info.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unify_proc.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/write_deps_file.m:
compiler/xml_documentation.m:
    Conform to the changes above.

tests/hard_coded/higher_order_func_test.m:
tests/hard_coded/higher_order_syntax.m:
    Avoid a warning about importing a module in the interface, not the
    implementation.

tests/invalid/after_end_module.err_exp:
tests/invalid/any_mode.err_exp:
tests/invalid/bad_end_module.err_exp:
tests/invalid/bigtest.err_exp:
tests/invalid/bug113.err_exp:
tests/invalid/duplicate_modes.err_exp:
tests/invalid/errors.err_exp:
tests/invalid/errors1.err_exp:
tests/invalid/errors2.err_exp:
tests/invalid/funcs_as_preds.err_exp:
tests/invalid/inst_list_dup.err_exp:
tests/invalid/invalid_main.err_exp:
tests/invalid/missing_interface_import2.err_exp:
tests/invalid/no_exports.err_exp:
tests/invalid/occurs.err_exp:
tests/invalid/predmode.err_exp:
tests/invalid/prog_io_erroneous.err_exp:
tests/invalid/type_inf_loop.err_exp:
tests/invalid/typeclass_missing_det_3.err_exp:
tests/invalid/typeclass_test_11.err_exp:
tests/invalid/types.err_exp:
tests/invalid/undef_inst.err_exp:
tests/invalid/undef_mode.err_exp:
tests/invalid/undef_type.err_exp:
tests/invalid/unicode1.err_exp:
tests/invalid/unicode2.err_exp:
tests/invalid/vars_in_wrong_places.err_exp:
tests/warnings/unused_import.exp:
tests/warnings/unused_interface_import.exp:
    Update the expected outputs in the invalid and warnings directories
    to account for one or more of the following five changes.

    Error messages that warn about a module not exporting anything
    used to always refer to line 1 of the module's source file.
    Now expect these messages to refer to the actual context of the module,
    which is the context of its `:- module' declaration.

    Expect a similarly updated context for messages that warn about
    unnecessarily importing modules in the interface, not in the
    implementation.

    Expect a similarly updated context for messages that warn about
    importing a module via both `:- import_module' and `:- use_module'.

    For the modules that follow the `:- module' declaration directly with code,
    also expect an error message about the missing section marker.

    For modules that have terms after the `:- end_module' declaration,
    replace "end_module" with "`:- end_module'" in the error message.

tests/invalid/func_class.{m,err_exp}:
    New test case. It is a copy of the old tests/valid/func_class.m, which
    is missing more than one module marker. The expected output is what I think
    we should generate. The test case currently fails, because we currently
    print only a subset of the expected errors. I am pretty sure the reason
    for that is that old code I have not modified simply throws away the
    missing error messages. Fixing this is work for the near future.

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

tests/misc_tests/pretty_print_test.exp:
    Expect the pretty-printed output to use four-space indentation,
    per our current style guide, since the compiler now generates such output.

tests/misc_tests/pretty_print_test.m:
    Clean up the source code of the test as well.

tests/valid/complicated_unify.m:
tests/valid/det_switch.m:
tests/valid/easy_nondet_test.m:
tests/valid/error.m:
tests/valid/func_class.m:
tests/valid/func_int_bug_main.m:
tests/valid/higher_order.m:
tests/valid/higher_order2.m:
tests/valid/implied_mode.m:
tests/valid/indexing.m:
tests/valid/multidet_test.m:
tests/valid/nasty_func_test.m:
tests/valid/semidet_disj.m:
tests/valid/stack_alloc.m:
tests/valid/switches.m:
    Add missing section markers to these modules. They used to follow
    the `:- module' declaration directly with code.
2015-07-21 04:06:52 +10:00
Zoltan Somogyi
8dc5a0071c Miscellaneous cleanups.
Just fixes to comments, better variable and predicate names, and the like.
No algorithmic changes.
2015-01-02 16:15:30 +11:00
Zoltan Somogyi
13b6f03f46 Module qualify end_module declarations.
compiler/*.m:
    Module qualify the end_module declarations. In some cases, add them.

compiler/table_gen.m:
    Remove an unused predicate, and inline another in the only place
    where it is used.

compiler/add_pragma.m:
    Give some predicates more meaningful names.
2014-09-04 00:24:52 +02:00
Zoltan Somogyi
500948d549 Break up mdbcomp/prim_data.m. The new modules have much better cohesion.
mdbcomp/sym_name.m:
    New module, containing the part of the old prim_data.m that
    dealt with sym_names.

mdbcomp/builtin_modules.m:
    New module, containing the part of the old prim_data.m that
    dealt with builtin modules.

mdbcomp/prim_data.m:
    Remove the things that are now in the two new modules.

mdbcomp/mdbcomp.m:
deep_proiler/Mmakefile:
slice/Mmakefile:
    Add the two new modules.

browser/*.m:
compiler/*.m:
deep_proiler/*.m:
mdbcomp/*.m:
slice/*.m:
    Conform to the above changes.
2014-09-02 05:20:23 +02:00
Zoltan Somogyi
1e184398f0 Fix the has_parallel_conj field of generated procedures (Mantis bug 351).
The event sequence that lead to the compiler abort in Mantis 351 was:

1 With -O5 --intermod-opt, the loop invariant optimization finds a loop
  invariant in the pos_mul_karatsuba predicate in library/integer.m.

2 To create the inner predicate (the one that has the already-computed
  invariant passed to it), it tries to make a copy of the original predicate,
  but sets the has_parallel_conj field of the new proc's proc_info to the
  default value, which is has_no_parallel_conj.

3 A later compiler pass has the task of (in par grades) adding synchronization
  to parallel conjunctions, and (in non-par grades) converting the parallel
  conjunctions to sequential. However, due to the has_no_parallel_conj flag
  in the proc_info, it thinks it has no work to do. It therefore leaves the
  parallel conjunction intact.

4 The pre-code-generation simplification pass traverses the entire body of
  the predicate, and, seeing a parallel conjunction, puts a has_parallel_conj
  flag on the proc_info.

5 generate_proc_code sees this flag, but since the target grade is not
  parallel, it ignores the flag. Since debugging is not enabled either,
  it does NOT create a ContainingGoalMap. (The debugger and parallel
  conjunctions are the two things that need this map.)

6 When trying to create the id for the parallel conjunction, par_conj_gen.m
  looks for the ContainingGoalMap. Not finding it, it aborts.

The problem arises in step 2, and the main part of the bug fix is to step 2.
However, it adds a sanity check to step 5 as well, to make any such problems
easier to diagnose in the future.

compiler/hlds_pred.m:
    Require callers of proc_info_create and similar predicates to specify
    whether the new procedure has parallel conjunctions or not.

    Arrange the code of these predicates so that all the fields in the
    proc_info are filled in with variables whose names say what they stand
    for. Previously, many of the fields were just "no" or "[]", not saying
    what `maybe' type or list there was no information for.

    Put these variables in the same order as the fields.

    Add a XXX about the possibility of similar bugs.

compiler/loop_inv.m:
    When creating the inner procedure (and its containing predicate),
    pass the has_parallel_conj flag of the original predicate. This is
    the actual bug fix.

compiler/par_conj_gen.m:
    Improve some comments.

compiler/parallel_to_plain_conj.m:
    Set a procedure's flag to has_no_parallel_conj right after eliminating
    all the parallel conjunctions in it.

compiler/proc_gen.m:
    Add a sanity check: if a procedure has has_parallel_conj, then require
    that the grade be a parallel grade.

compiler/accumulator.m:
compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/clause_to_proc.m:
compiler/clause_to_proc.m:
compiler/clause_to_proc.m:
compiler/lambda.m:
compiler/make_hlds.m:
compiler/par_loop_control.m:
compiler/pd_info.m:
compiler/stm_expand.m:
compiler/table_gen.m:
compiler/tupling.m:
compiler/unify_proc.m:
compiler/untupling.m:
    Conform to the changes above.
2014-08-11 02:54:17 +02:00
Zoltan Somogyi
295415090e Convert almost all remaining modules in the compiler to use
Estimated hours taken: 6
Branches: main

compiler/*.m:
	Convert almost all remaining modules in the compiler to use
	"$module, $pred" instead of "this_file" in error messages.

	In a few cases, the old error message was misleading, since it
	contained an incorrect, out-of-date or cut-and-pasted predicate name.

tests/invalid/unresolved_overloading.err_exp:
	Update an expected output containing an updated error message.
2011-05-23 05:08:24 +00:00