Commit Graph

288 Commits

Author SHA1 Message Date
Zoltan Somogyi
c643291d1f Add cons_list and snoc_list to cord.m.
library/cord.m:
    Add those two new predicates.

NEWS.md:
    Announce the additions.

compiler/*.m:
    Use snoc_list in many places.

tests/hard_coded/test_cord_2.{m,exp}:
    Extend this test case to test cons_list.
2025-10-10 18:48:26 +11:00
Zoltan Somogyi
d8a31e574e Move six utility modules from check_hlds to hlds.
compiler/inst_lookup.m:
compiler/inst_mode_type_prop.m:
compiler/inst_test.m:
compiler/inst_util.m:
compiler/mode_util.m:
compiler/type_util.m:
    Move these modules from the check_hlds package to the hlds package.
    The reason is that all the content of five of these modules, and
    most of the content of one module (inst_util.m) is not used
    exclusively during semantic checking passes. (A later diff
    should deal with the exception.) Some are used by the pass that
    builds the initial HLDS, and all are used by middle-end and backend
    passes. The move therefore reduces the number of inappropriate imports
    of the check_hlds package.

compiler/check_hlds.m:
compiler/hlds.m:
    Effect the transfer.

compiler/*.m:
    Conform to the changes above.
2025-10-08 23:07:13 +11:00
Zoltan Somogyi
3dd0f2e03b Act on all remaining warnings about unused state vars.
compiler/add_heap_ops.m:
compiler/check_import_accessibility.m:
compiler/comp_unit_interface.m:
compiler/convert_import_use.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/equiv_type.m:
compiler/generate_dep_d_files.m:
compiler/generate_mmakefile_fragments.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/higher_order.specialize_unify_compare.m:
compiler/jumpopt.m:
compiler/layout_out.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/llds_out_file.m:
compiler/make.build.m:
compiler/make.get_module_dep_info.m:
compiler/make.library_install.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.track_flags.m:
compiler/make_hlds_passes.m:
compiler/make_module_file_names.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_disj_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_lookup_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_test.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_target_util.m:
compiler/module_cmds.m:
compiler/opt_deps_spec.m:
compiler/optimize.m:
compiler/parse_dcg_goal.m:
compiler/parse_goal.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_string_format.m:
compiler/proc_gen.m:
compiler/prop_mode_constraints.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.region_analysis.m:
compiler/rbmm.region_transformation.m:
compiler/simplify_goal_disj.m:
compiler/ssdebug.m:
compiler/stack_opt.m:
compiler/string_switch.m:
compiler/switch_gen.m:
compiler/term_constr_build.m:
compiler/trace_gen.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/write_deps_file.m:
deep_profiler/autopar_calc_overlap.m:
deep_profiler/autopar_find_best_par.m:
deep_profiler/html_format.m:
deep_profiler/startup.m:
profiler/mercury_profile.m:
profiler/propagate.m:
    Act on the new warnings. In a few cases, conform to the changes
    resulting from acting on the warnings in other modules.

browser/Mercury.options:
compiler/Mercury.options:
library/Mercury.options:
mdbcomp/Mercury.options:
ssdb/Mercury.options:
    Specify options for disabling the new warnings for modules
    where we (probably) won't want them.

configure.ac:
    Require the installed compiler to understand the options that
    we now reference in the Mercury.options files above.

tests/debugger/tailrec1.exp:
    Expect variable names for the middle versions of state vars
    using the new naming scheme.

tests/invalid/Mercury.options:
    Fix references to obsolete test names.

tests/warnings/Mercury.options:
    Avoid a test failure with intermodule optimization.
2025-05-19 00:33:06 +10:00
Zoltan Somogyi
08972f76ba Ignore singleton arguments in MLDS unifications.
When we generated MLDS code for a deconstruct unification of the form
X = f(Y1, Y2, ..., Yn), we have always generated code that picked up
the values of *all* of the Yi, even the ones that did occur anywhere else.
The code of ml_unused_assign.m then came along and optimized away
the statement that assigned the value of a field to e.g. Y3 if Y3
is not visible outside the unification.

Simply not generating some MLDS code is simpler than generating it
and then later deleting it.

It also directly avoids the creation of some strange code. Given this
if-then-else,

    ( if L = [_H | T], T = [_ | _] then ... else ... )

the compiler used to generate this hlc.gc code for the condition:

    T_6 = ((MR_Word) ((MR_hl_field(1, L_3, (MR_Integer) 1))));
    succeeded = (T_6 != (MR_Word) ((MR_Unsigned) 0U));
    if (succeeded)
    {
    }

It did this because it generated code to pick up the values of *both*
the head and the tail in *both* cons cells, optimized away three of the
resulting four assignment statements, but left the if-then-else around
when it deleted all the statements in the then part.

compiler/ml_unify_gen_util.m:
    Change the utility predicate that decides, given an X = f(Yi) unification,
    which way each argument unification goes between a field of the X term
    and the corresponding variable Yi. If the assignment would notmally be
    to e.g. Y3 but Y3 is not in the unification's nonlocal set, then tell
    our caller that the argument unification is a no-op.

compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_deconstruct.m:
    Conform to the change in ml_unify_gen_util.m, mostly by passing around
    the nonlocals set to get it to the modified predicate.

compiler/ml_unused_assign.m:
    If we optimize away all statements from both arms of an if-then-else,
    delete the if-then-else altogether.

compiler/mlds_to_c_file.m:
    Unrelated change: fix inconsistent indentation in generated .c files.

compiler/Mercury.options:
    Specify an optimization option that a module updated above
    can benefit from.
2025-03-12 21:00:15 +11:00
Zoltan Somogyi
0c162fb50e Improve diagnostics for higher-order mode errors.
In case of a problem with an argument of a higher order call,
we used to generate diagnostics containing text such as

    in argument 2 (i.e. argument 1 of the called function)
    of impure higher-order function call:

This clumsy construction was needed because the HLDS did not contain
enough info. Specifically, it did not specify whether in the source code,
the higher order call was written as e.g. call(P, A, B, C) or as P(A, B, C).
If the former, then then a problem with e.g. A occurs in argument 2
of the call to the 'call' builtin; if the latter, then it occurs
in argument 1 of the call to 'P'.

This diff fixes that. It adds to the HLDS representation of higher order
calls a record of the original form of the call in the source code

compiler/hlds_goal.m:
    Add this field, the higher_order_syntax field, to the representation
    of higher order calls.

compiler/goal_expr_to_goal.m:
    Fill the higher_order_syntax field for higher order predicate calls.

compiler/resolve_unify_functor.m:
    Fill the higher_order_syntax field for higher order function calls.

compiler/hlds_pred.m:
    Change the representation of generic calls in call_ids, which we use
    to identify callees for diagnostics, to include both the variable
    specifying the callee in higher order calls (by changing from a
    generic_call_id to the generic_call from which it would be derived
    by throwing out that info), and the var_name_source needed to
    look up its name.

compiler/hlds_out_util.m:
    Use the new higher_order_syntax field to generate text that

    - identifies the higher order call as using either call(P, A, B, C)
      syntax or P(A, B, C) syntax, and likewise for function, and

    - specifies the exact argument number (which will depend on the above
      distinction).

    This should result in more easily understandable diagnostics.

    Add a version of this predicate that generates text that specifically
    describes the higher order callee, not the higher order call as a whole.

    Add an option to suppress the printing of variable names.
    We use this to *not* refer to e.g. "the predicate P" when reporting
    an error about P actually being a function, not a predicate.

compiler/mode_info.m:
    Rename mode_context_call to mode_context_call_arg, because
    the context it describes is one argument of a call.

    Add a new mode context, mode_context_call, which now describes
    a call as a whole.

compiler/mode_errors.m:
    Use the new facilies described above to generate better diagnostics
    for higher order calls.

compiler/modecheck_util.m:
    Document the reason why we handle argument numbers for higher order calls
    the way we do.

    When generating an error that relates the whole of a higher order call,
    use the new mechanism in mode_info.m to record the fact that the error
    is not specific to any one argument of the call. Not doing this would
    include the argument number in the context of the error, which would be
    misleading.

    Add a utility function that is needed by more than one module below.

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

tests/invalid/anys_in_negated_contexts.err_exp:
tests/invalid/bind_var_errors.err_exp:
tests/invalid/constrained_poly_insts_2.err_exp:
tests/invalid/det_errors_cc.err_exp:
tests/invalid/fbnf.err_exp:
tests/invalid/functor_ho_inst_bad_2.err_exp:
tests/invalid/higher_order_mode_mismatch.err_exp:
tests/invalid/ho_any_inst.err_exp:
tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/ho_unique_error.err_exp:
tests/invalid/mode_error_arg_number_ho.err_exp:
tests/invalid/no_ho_inst.err_exp:
tests/invalid/type_diff.err_exp:
tests/invalid_purity/impure_func_t5_fixed.err_exp:
tests/invalid_purity/impure_pred_t1_fixed.err_exp:
tests/invalid_purity/impure_pred_t2.err_exp:
tests/invalid_purity/purity_nonsense_1.err_exp:
tests/invalid_purity/purity_nonsense_2.err_exp:
    Expect updated error messages.
2024-11-01 13:56:55 +11:00
Julien Fischer
f5e71b1e90 Fix copyright notices in recently modified files.
compiler/*.m:
library/*.m:
mdbcomp/*.m:
runtime/*.[ch]:
    As above.

    Fix spelling in some spots.
2024-02-20 15:09:17 +11:00
Zoltan Somogyi
d0413592dc Get --auto-comments to print unmangled func names.
In LLDS grades, we have long added a comment before the C code we generated
for a Mercury predicate that gives the name of that predicate. In most cases,
the C code itself will contain that name, but the C code will contain the name
in a mangled form, and in cases where the predicate name contains graphic
characters, the mangling will make the name unrecognizable. The automatically
generate comment helps debug program transformation, such as type
specification, that either can, or always do, include such characters
in the names of the predicates they create.

Until now, --auto-comment printed only the predicate and procedure ids
of the Mercury predicate when invoked in MLDS grades. Change this
to print the unmangled predicate name as well. To make this simpler,
move the comment it generates from the middle of the C function declaration
to before the C function declaration. (When we generate C# or Java,
we already put the comment before the declaration.)

--auto-comments in MLDS grades now also prints more information
for various kinds of auxiliary functions.

compiler/mlds.m:
    Replace a maybe type with a bespoke type, both to improve readability,
    and to preserve the purpose of auxiliary functions.

compiler/mlds_to_target_util.m:
    Rewrite the predicate that wrote out the pre-function (or pre-method)
    comment for C# and Java. The new version

    - prints out the predicate's unmangled name as well its pred and proc ids,
      if the function (or method) implements a Mercury predicate,

    - prints out the kind of auxiliary function, if the function or method
      does not implement a (whole) Mercury predicate,

    - is used for C as well as for C# and Java.

compiler/mlds_to_c_func.m:
compiler/mlds_to_cs_func.m:
compiler/mlds_to_java_func.m:
    Call the rewritten function to generate the pre-function comment
    (if --auto-comment is enabled).

    In mlds_to_c_func.m, also factor out some common code.

compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_proc_gen.m:
compiler/ml_type_gen.m:
compiler/mlds_to_c_class.m:
compiler/mlds_to_java_wrap.m:
2024-02-01 19:05:42 +11:00
Zoltan Somogyi
783f4b2be4 Fix singleton warnings for code with 'some [...]' goals.
The code in make_hlds_warn.m that is intended to generate singleton warnings
hasn't ever been able to handle code containing 'some [...]' goals properly.
The reason is that

- add_clause.m invokes make_hlds_warn.m only *after* it does quantification
  on the body of the clause being added to the HLDS, but

- quantification has always replaced all lists of quantified variables
  with the empty list.

This meant that

- we never could report code in which the only occurrence of a variable
  was in a list of quantified variables, which is something we *should*
  warn about, and

- we always did generate a singleton warning for code such as
  "some [Val] map.search(Map, Key, Val)", which is something we *should not*
  warn about.

This diff fixes this problem.

The main change is a mechanism that allows us to tell quantification.m
to keep lists of quantified variables intact. However, since the rest
of the compiler does not react well to these lists not being empty,
this diff

- gets make_hlds_warn.m to report whether the clause body goal, in which
  quantification.m was told to preserve any lists of quantified variables,
  *actually contained* any nonempty lists of quantified variables, and

- if it did, then we invoke quantification.m again, this time telling it
  to nuke all lists of quantified variables.

This nuking has to be done relatively rarely, because only a very small
fraction of clauses contain any explicit quantification.

(An alternative design would be for make_hlds_warn.m to always nuke
any nonempty list of quantified variables it traversed. However, this would
require *always* rebuilding the clause body goal, which would probably
be slower on average.)

The above is the main change in this diff. However, the change that is
responsible for the bulk of the diff is the addition of a flag to
exist_quant scopes to specify whether that scope was created by the user
or by the compiler. This is needed because if make_hlds_warn.m sees code
such as "some [Val] map.search(Map, Key, Val)", it definitely *should*
generate a warning about Val being singleton (if it does not occur outside
this code) if the "some [Val]" scope was put there by the compiler.

compiler/make_hlds_warn.m:
    Treat user-generated exist_quant scopes as before (the old code did
    the right thing to generate warnings, it was just given wrong inputs).
    Treat compiler-generated exist_quant scopes as if they weren't there,
    for warning-generating purposes.

    To make this distinction possible, use separate code to handle
    exist_quant and promise_solutions scopes.

    Record whether the goal traversal has seen any nonempty lists of quantified
    variables, and return this info to the caller in add_clause.m.

    Encode the nonempty nature of a list in the argument structure of a
    predicate.

    Update some obsolete terminology in variable and field names.

    Clarify the logic of some code.

compiler/quantification.m:
    Add the keep_quant/do_not_keep_quant switch described above.

    Add some documentation of the predicates to which it is applicable.

    Add free_goal_expr_vars, a version of free_goal_vars that takes
    only a goal expr, without the goal info. At one point, I thought
    this diff needed it. It does not, so the new function is not used,
    but there is also not much point in deleting it, Simplify the code
    of free_goal_vars, deleting one of its callees after inlining it
    at its only call site.

    Replace a appended-to-at-the-front-and-then-reversed list with a cord.

compiler/hlds_goal.m:
    Add the created-by-user-or-compiler flag to exist_quant scopes.

compiler/add_clause.m:
    Move the code that invokes make_hlds_warn.m to warn about singletons
    into the clauses_info_add_clause predicate, whose subcontractor
    add_clause_transform does the initial quantification. The reason
    for this move is that we have never generated singleton variable warnings
    for clauses that were read in from .opt files, or for clauses which are
    known to have syntax errors. With the new setup, if we such clauses,
    clauses_info_add_clause can, and does, tell add_clause_transform
    to tell quantification.m to nuke lists of quantified variable
    right away. It is only for the clauses we *can* warn about
    that clauses_info_add_clause will tell add_clause_transform
    to keep those variables, and will then itself invoke the code
    in make_hlds_warn.m that warns about singletons, followed, if needed,
    by a var-list-nuking reinvocation of quantification.

    This centralization of the code relevant to warning code in
    clauses_info_add_clause also allows the deletion of several of its
    output arguments, since its two callers used those arguments
    only to invoke the warning-generation code. It also eliminates
    the duplication of code in those two callers.

compiler/instance_method_clauses.m:
    Conform to the change in add_clause.m.

compiler/add_foreign_proc.m:
compiler/assertion.m:
compiler/constraint.m:
compiler/cse_detection.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/goal_util.m:
compiler/hlds_desc.m:
compiler/hlds_out_goal.m:
compiler/interval.m:
compiler/lambda.m:
compiler/mark_tail_calls.m:
compiler/ml_code_gen.m:
compiler/mode_constraints.m:
compiler/modecheck_goal.m:
compiler/polymorphism_goal.m:
compiler/pre_quantification.m:
compiler/purity.m:
compiler/saved_vars.m:
compiler/simplify_goal_scope.m:
compiler/simplify_proc.m:
compiler/state_var.m:
compiler/stm_expand.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/try_expand.m:
compiler/typecheck.m:
compiler/unique_modes.m:
    Conform to the change in hlds_goal.m and/or quantification.m.

compiler/options.m:
    Add a way to detect the presence of this fix in the installed compiler.

tests/valid/Mmakefile:
    Enable the old test case for this problem, some_singleton,
    which we haven't passed until now.

tests/warnings/Mmakefile:
    Enable the missing_singleton_warning test case, which we haven't passed
    until now.
2023-06-10 09:59:00 +02:00
Zoltan Somogyi
404fea1bd2 Start removing non-var_table versions of predicates.
compiler/arg_info.m:
compiler/goal_util.m:
compiler/hlds_rtti.m:
compiler/instmap.m:
compiler/recompute_instmap_deltas.m:
compiler/type_util.m:
    For predicates which had both varset/vartypes and var_table versions,
    but the former is not used anymore because all its callers have been
    switched to the latter,

    - delete the former, and
    - rename the latter to the name of the former.

    In goal_util.m, switch two currently-unused predicates to use var_tables
    instead of varsets/vartypes, in case they are needed again.

compiler/hlds_pred.m:
    Likewise replace define_new_pred with define_new_pred_vt, but also
    change its implementation to use var_table for everything except
    the final construction of the proc_info.

compiler/accumulator.m:
compiler/call_gen.m:
compiler/code_loc_dep.m:
compiler/constraint.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/det_util.m:
compiler/float_regs.m:
compiler/follow_code.m:
compiler/higher_order.m:
compiler/interval.m:
compiler/lambda.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/loop_inv.m:
compiler/ml_code_gen.m:
compiler/modes.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/push_goals_together.m:
compiler/rbmm.region_liveness_info.m:
compiler/saved_vars.m:
compiler/simplify_goal.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/table_gen.m:
compiler/tupling.m:
compiler/unneeded_code.m:
compiler/untupling.m:
    Conform to the changes above.
2022-05-15 21:40:10 +10:00
Zoltan Somogyi
ea4f95a7ed Use var_tables in lco.m, and when dumping goals.
Since this is the first converted module that dumps out goals when
debugging trace flags are enabled, this required generalizing the code
that does that, to take either varsets or var_tables as a means of
specifying the names of variables. We do this via a new type,
var_name_source, which contains either a varset or a var_table.

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

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

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

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

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

    Define the var_name_source type.

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

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

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

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

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

    Fix some comments.

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

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

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

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

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_heap_ops.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_trail_ops.m:
compiler/analysis.m:
compiler/arg_info.m:
compiler/build_mode_constraints.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/check_promise.m:
compiler/closure_analysis.m:
compiler/closure_gen.m:
compiler/code_info.m:
compiler/code_loc_dep.m:
compiler/common.m:
compiler/compile_target_code.m:
compiler/complexity.m:
compiler/const_prop.m:
compiler/constraint.m:
compiler/continuation_info.m:
compiler/convert_parse_tree.m:
compiler/coverage_profiling.m:
compiler/cse_detection.m:
compiler/ctgc.datastruct.m:
compiler/ctgc.util.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
compiler/direct_arg_in_out.m:
compiler/disj_gen.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/exception_analysis.m:
compiler/file_names.m:
compiler/float_regs.m:
compiler/follow_vars.m:
compiler/format_call.m:
compiler/generate_dep_d_files.m:
compiler/get_dependencies.m:
compiler/goal_expr_to_goal.m:
compiler/goal_mode.m:
compiler/goal_path.m:
compiler/goal_store.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_clauses.m:
compiler/hlds_code_util.m:
compiler/hlds_error_util.m:
compiler/hlds_goal.m:
compiler/hlds_llds.m:
compiler/hlds_out_pred.m:
compiler/hlds_rtti.m:
compiler/hlds_statistics.m:
compiler/inlining.m:
compiler/inst_check.m:
compiler/inst_test.m:
compiler/inst_user.m:
compiler/instance_method_clauses.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/intermod_analysis.m:
compiler/interval.m:
compiler/introduce_exists_casts.m:
compiler/introduce_parallelism.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/llds.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_util.m:
compiler/lookup_switch.m:
compiler/loop_inv.m:
compiler/make.module_target.m:
compiler/make.util.m:
compiler/make_goal.m:
compiler/make_hlds_separate_items.m:
compiler/make_hlds_types.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/middle_rec.m:
compiler/ml_accurate_gc.m:
compiler/ml_args_util.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_proc_gen.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_unify_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_func.m:
compiler/mlds_to_c_global.m:
compiler/mlds_to_cs_class.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_data.m:
compiler/mlds_to_java_file.m:
compiler/mlds_to_java_stmt.m:
compiler/mlds_to_java_type.m:
compiler/mmc_analysis.m:
compiler/mode_comparison.m:
compiler/mode_constraints.m:
compiler/mode_debug.m:
compiler/mode_errors.m:
compiler/mode_info.m:
compiler/mode_ordering.m:
compiler/modecheck_call.m:
compiler/modecheck_coerce.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/module_cmds.m:
compiler/old_type_constraints.m:
compiler/opt_debug.m:
compiler/optimize.m:
compiler/options_file.m:
compiler/ordering_mode_constraints.m:
compiler/par_loop_control.m:
compiler/parse_item.m:
compiler/parse_string_format.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_to_term.m:
compiler/parse_util.m:
compiler/pd_debug.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/peephole.m:
compiler/polymorphism.m:
compiler/polymorphism_info.m:
compiler/polymorphism_lambda.m:
compiler/polymorphism_type_class_info.m:
compiler/polymorphism_type_info.m:
compiler/post_typecheck.m:
compiler/pragma_c_gen.m:
compiler/pred_name.m:
compiler/pred_table.m:
compiler/prog_item.m:
compiler/prog_rep.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/push_goals_together.m:
compiler/qual_info.m:
compiler/quantification.m:
compiler/rbmm.execution_path.m:
compiler/rbmm.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.points_to_graph.m:
compiler/rbmm.points_to_info.m:
compiler/rbmm.region_resurrection_renaming.m:
compiler/rbmm.region_transformation.m:
compiler/recompilation.used_file.m:
compiler/recompilation.version.m:
compiler/recompute_instmap_deltas.m:
compiler/resolve_unify_functor.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/saved_vars.m:
compiler/set_of_var.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_conj.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_goal_scope.m:
compiler/simplify_goal_switch.m:
compiler/simplify_goal_unify.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/smm_common.m:
compiler/ssdebug.m:
compiler/stack_alloc.m:
compiler/stack_layout.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/store_alloc.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_data.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/term_constr_main_types.m:
compiler/term_constr_util.m:
compiler/term_pass1.m:
compiler/term_traversal.m:
compiler/term_util.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/transform_llds.m:
compiler/try_expand.m:
compiler/tupling.m:
compiler/type_assign.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/typecheck_debug.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unify_gen_construct.m:
compiler/unify_gen_deconstruct.m:
compiler/unify_proc.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/var_locn.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2022-04-18 02:00:38 +10:00
Zoltan Somogyi
8ebe125a6a Introduce var_table.m.
Most compiler passes need to know both the names and the types
of the variables they operate on. Until now, they had to pass along
two separate data structures for that, the varset and the vartypes,
and many operations required looking a variable up in both of these.

The var table is a single data structure that records for each variable

- its name, as the varset has traditionally done,
- its type, as the vartypes has traditionally done,
- the is_dummy_type flag which says whether its type is a dummy type,
  which traditionally had to computed afresh at each lookup.

Switch the MLDS code generator to use var_tables instead of varsets and
vartypes. The code generator often needs to know the name and the type
of a variable at the same time, and it often needs to know which variables'
types are dummies, often enough that precomputing this info should be a win.

compiler/var_table.m:
    Add this new module which defines the var_table.

    Its operations are modelled after the operation in var_types.m.

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

compiler/prog_type.m:
compiler/type_util.m:
    Move the is_dummy_type from type_util.m, which is in the
    check_hlds package, to prog_type.m, which in the parse_tree package,
    to avoid having this part of the hlds package depend on check_hlds.
    (It already depends on parse_tree, for a lot of different things.)

    Given a function and a predicate that each took a vartypes arg,
    make new versions that take a var_table arg instead.
    Rationalize the argument list of the function.

compiler/ml_gen_info.m:
    Replace the varset and vartypes fields of the ml_gen_info with a
    var_table field.

compiler/ml_code_util.m:
    Replace code that used to operate on varsets and vartypes with code
    that operates on var_tables.

    Create new versions of a few operations to exploit the info in var_tables.

    Give some predicates more meaningful names.

compiler/ml_accurate_gc.m:
compiler/ml_args_util.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_lookup_switch.m:
compiler/ml_proc_gen.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_unify_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
    Replace code that used to operate on varsets and vartypes with code
    that operates on var_tables.

    In ml_switch_gen.m and ml_tag_switch.m, put some predicates' arguments
    into an reasonable order by moving related args next to each other.

compiler/vartypes.m:
    Delete an operation that was only needed in the MLDS backend,
    in code that this diff replaces.

compiler/switch_util.m:
    Put the larger input first in the arg list of a predicate.

compiler/closure_gen.m:
compiler/code_info.m:
compiler/code_loc_dep.m:
compiler/export.m:
compiler/lambda.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/llds.m:
compiler/llds_out_instr.m:
compiler/mark_tail_calls.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/stack_alloc.m:
compiler/stack_layout.m:
compiler/tag_switch.m:
compiler/term_constr_util.m:
compiler/tupling.m:
compiler/unify_gen.m:
compiler/unify_gen_deconstruct.m:
compiler/var_locn.m:
    Conform to the changes above.
2022-03-28 10:20:49 +11:00
Zoltan Somogyi
034a74ed16 Specialize codegen for detism_det conjunctions. 2022-03-23 03:05:14 +11:00
Zoltan Somogyi
9d2131e334 Clarify comment. 2022-03-17 14:44:37 +11:00
Zoltan Somogyi
3e7e7c8688 Fix the const_var_map after negated goals.
compiler/ml_code_gen.m:
    The old code for generating code for negations treated `Cond'
    as it were the one path that could reach the end of `not Cond'.
    However, since `not Cond' is equivalent to `if Cond then fail else true',
    executions that get to the end of Cond cannot reach the end of `not Cond';
    indeed, execution can get there only by having Cond fail. Handle the
    const var maps accordingly, by having the final value of the const var map
    be the same as its original value. This fixes Mantis bug #552.

    Fix a different bug in the handling of packed word maps, which should
    also be reset at the end to their original value. This was done for
    *most* kinds of negated goals, but not all. Fix that omission.
2022-03-17 13:51:20 +11:00
Zoltan Somogyi
9b6f1443a5 Add and use assoc_list.common_subset.
library/assoc_list.m:
    Add the new function.

NEWS:
    Announce the new function.

compiler/ml_code_gen.m:
    Use the new function.
2022-02-07 19:04:23 +11:00
Zoltan Somogyi
9ddb180757 Handle const_var_maps left by add_trail_ops.m.
This fixes Mantis bug #544.

The code of add_trail_ops.m can transform

    <code that adds an entry to const_var_map>

into

    (
        ...
        <code that adds an entry to const_var_map>
        ...
    ;
        ...,
        fail
    )

where the const_var_map in the MLDS code generator records which variables'
values are available as ground terms.

The MLDS code generator used to reset the const_var_map in its main data
structure, the ml_gen_info, at the end of every disjunction (actually,
at the end of every branched control structure) to the value it had
at the start. This was intended to prevent the code following the branched
structure from relying on const_var_map entries that were added to the
const_var_map on *some* branches, but not others. However, in this case,
it has the effect of forgetting the entry added by the first disjunct,
even though

- the code after the disjunction can be reached *only* via the first disjunct,
  and

- the code after the disjunction (legitimately, until add_trail_ops) depended
  on that entry being available.

The fix is to allow the code after a branched control structure to depend
on any const_var_map entry that is present in the final const_var_map
in every branch of the branched control structure whose end is reachable.

The LLDS code generator was not affected by the bug, because it uses
totally separate systems both for implementing trailing, and for keeping
track of what variables' values are available statically. In particular,
it does not rely on operations inserted and the annotations left on
unifications by the add_trail_ops and mark_static_term passes,
having been written long before either module existed.

compiler/hlds_goal.m:
    Document the update above to what may be marked static.

compiler/ml_gen_info.m:
    Document the updated protocol for handling the const_var_map field.

    Use a named type instead of its expansion.

compiler/ml_code_gen.m:
    Make the predicates that generate code for a branch in a branched
    control structure return the final const_var_maps from the branches
    whose endpoints are reachable.

    Add a predicate that computes the consensus of all the gathered
    const_var_maps.

    Compute consensus const_var_maps for if-then-elses and negations.

    Fix some inconsistencies in variable naming.

    Simplify some code.

compiler/ml_disj_gen.m:
    Compute consensus const_var_maps for disjunctions.

compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
    Compute consensus const_var_maps for various kinds of switches.

    In some predicates, put related arguments next to each other.

compiler/ml_unify_gen_construct.m:
    Delete "dynamic" from the names of several predicates that also handled
    non-dynamic construction unifications.

    Fix an out-of-date comment.

compiler/mark_static_terms:
    Fix grammar in a comment.

library/map.m:
    Fix a careless bug: when doing a merge in map.common_subset_loop,
    we threw away an entry from the wrong list in one of three cases.

    Make such bugs harder to overlook by

    - deleting the common parts from variable names, leaving the differences
      easier to see, and

    - replacing numeric suffixes for completely separate data structures
      with A and B suffixes.

tests/valid/bug544.m:
    A new test case for the bug.

tests/valid/Mercury.options:
tests/valid/Mmakefile:
    Enable the bug, and run it with -O5.
2022-02-07 17:30:32 +11:00
Peter Wang
615e808266 Represent coerce goals as a type of cast.
compiler/hlds_goal.m:
    Move subtype_coerce from a option of hlds_goal_expr into cast_kind.
    It was useful to identify places where we needed to consider
    coercions separately from other types of casts, but that's done now.

compiler/hlds_pred.m:
    Delete gcid_coerce option of generic_call_id.

compiler/arg_info.m:
compiler/build_mode_constraints.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/coverage_profiling.m:
compiler/deep_profiling.m:
compiler/exception_analysis.m:
compiler/float_regs.m:
compiler/follow_vars.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_desc.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
compiler/interval.m:
compiler/lambda.m:
compiler/live_vars.m:
compiler/ml_call_gen.m:
compiler/ml_code_gen.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/modecheck_goal.m:
compiler/old_type_constraints.m:
compiler/post_typecheck.m:
compiler/pre_quantification.m:
compiler/purity.m:
compiler/simplify_goal.m:
compiler/simplify_goal_call.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/superhomogeneous.m:
compiler/tabling_analysis.m:
compiler/term_traversal.m:
compiler/trailing_analysis.m:
compiler/tupling.m:
compiler/typecheck.m:
compiler/unique_modes.m:
compiler/unused_imports.m:
    Conform to changes.

compiler/hlds_statistics.m:
    Count coercions as casts, for consistency in terminology.

compiler/prog_rep.m:
    Delete XXX about adding a coerce_rep in addition to cast_rep.
2021-04-14 15:10:18 +10:00
Peter Wang
ac70f6d36b Parse and check coerce expressions.
This change implements parsing, typechecking, and modechecking of
"coerce" expressions from my subtypes proposal, i.e. coerce(Term).
Backends currently will abort if asked to generate code for coercions,
as subtypes do not yet share data representations with their base types,
so most coercions would lead to crashes at runtime anyway.

----------------

compiler/hlds_goal.m:
    Add new type of generic_call to represent coerce expressions.

compiler/hlds_pred.m:
    Add new generic_call_id for coerce expressions.

compiler/superhomogeneous.m:
    Treat var-functor unifications of the form "Var = coerce(Term)"
    as special, producing coerce generic_calls.

----------------

compiler/type_assign.m:
    Add a field to type_assign to hold coerce constraints to be checked,
    or known to be unsatisfiable, in the given type assignment.

compiler/typecheck.m:
compiler/typecheck_errors.m:
    Implement typechecking of coerce expressions.

compiler/prog_type.m:
    Add a predicate type_is_ground_except_vars.

----------------

compiler/check_hlds.m:
    Add new module modecheck_coerce.

compiler/modecheck_coerce.m:
    Implement modechecking of coerce expressions.

compiler/modecheck_goal.m:
    Call modecheck_coerce at a coerce generic call.

compiler/mode_errors.m:
    Add two mode errors relating to coerce expressions.

----------------

compiler/arg_info.m:
compiler/build_mode_constraints.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/coverage_profiling.m:
compiler/deep_profiling.m:
compiler/exception_analysis.m:
compiler/float_regs.m:
compiler/follow_vars.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_desc.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
compiler/interval.m:
compiler/lambda.m:
compiler/live_vars.m:
compiler/ml_call_gen.m:
compiler/ml_code_gen.m:
compiler/mode_constraints.m:
compiler/old_type_constraints.m:
compiler/post_typecheck.m:
compiler/pre_quantification.m:
compiler/tabling_analysis.m:
compiler/term_traversal.m:
compiler/trailing_analysis.m:
compiler/tupling.m:
compiler/unique_modes.m:
compiler/unused_imports.m:
compiler/purity.m:
compiler/simplify_goal.m:
compiler/simplify_goal_call.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
    Conform to changes.

compiler/prog_rep.m:
    Conform to changes. Reuse cast_rep for coercions for now.

compiler/hlds_statistics.m:
    Count coercions in proc stats.

----------------

tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/coerce_ambig.err_exp:
tests/invalid/coerce_ambig.m:
tests/invalid/coerce_clobbered.err_exp:
tests/invalid/coerce_clobbered.m:
tests/invalid/coerce_disambig.err_exp:
tests/invalid/coerce_disambig.m:
tests/invalid/coerce_implied_mode.err_exp:
tests/invalid/coerce_implied_mode.m:
tests/invalid/coerce_infer.err_exp:
tests/invalid/coerce_infer.m:
tests/invalid/coerce_instvar.err_exp:
tests/invalid/coerce_instvar.m:
tests/invalid/coerce_mode_error.err_exp:
tests/invalid/coerce_mode_error.m:
tests/invalid/coerce_non_du.err_exp:
tests/invalid/coerce_non_du.m:
tests/invalid/coerce_syntax.err_exp:
tests/invalid/coerce_syntax.m:
tests/invalid/coerce_type_error.err_exp:
tests/invalid/coerce_type_error.m:
tests/invalid/coerce_unify_tvars.err_exp:
tests/invalid/coerce_unify_tvars.m:
tests/invalid/coerce_uniq.err_exp:
tests/invalid/coerce_uniq.m:
tests/invalid/coerce_unreachable.err_exp:
tests/invalid/coerce_unreachable.m:
tests/invalid/coerce_void.err_exp:
tests/invalid/coerce_void.m:
    Add test cases.

tests/typeclasses/arbitrary_constraint_class.m:
tests/typeclasses/arbitrary_constraint_pred_1.m:
tests/typeclasses/arbitrary_constraint_pred_2.m:
    Wrap parentheses around calls to a coerce/1 method
    to prevent them being treated as coerce expressions.

----------------

doc/reference_manual.texi:
    Rewrite chapter on Type conversions (still commented out).
    In particular, the typechecking rules that I had written
    previously were insufficient.

NEWS:
    Mention backwards incompatibility.
2021-03-15 11:16:31 +11:00
Zoltan Somogyi
c1bdd2100b Delete unneeded $module args from aborts. 2019-04-16 04:13:35 +10:00
Zoltan Somogyi
ffe330abf2 Avoid generating empty if-then-elses.
compiler/ml_foreign_proc_gen.m:
    At the end semidet foreign_procs, we assign values to the output arguments
    *if* the proc succeeded. If the proc has no outputs, the then part of this
    if-then-else is empty, and it has no else part. This diff avoids generating
    such noop if-then-elses altogether for foreign_procs in C.

    Replace references to "pragma c_codes" in predicate names and
    documentation. We have preferred "foreign_proc" terminology for a long
    time now.

    Likewise, remove references to "ordinary" c_codes/foreign_procs; we removed
    support for non-ordinary (i.e. model_non) foreign_procs a long time ago.

compiler/ml_code_gen.m:
    Conform to the updated name of a predicate.
2018-09-27 13:54:44 +10:00
Zoltan Somogyi
6a915eef05 Optimize field updates inside packed arg words.
Since june, we have been copying words containing packed-together
sub-word-sized arguments all in one piece if possible, for hlc grades.
This means that given a type such as

:- type t
    --->    f1(int8, bool, int8, int, bool, int8, bool).

whose first three and last three arguments are packed into one word each,
and a predicate such as

    p(T0, T) :-
        T0 = f1(A, B, C, _, E, F, G),
        D = 42,
        T  = f1(A, B, C, D, E, F, G).

we generated code such as

    MR_Integer D_12 = (MR_Integer) 42;
    MR_Unsigned packed_args_0 =
        (MR_Unsigned) ((MR_hl_field(MR_mktag(0), T0_3, (MR_Integer) 0)));
    MR_Unsigned packed_args_1 =
        (MR_Unsigned) ((MR_hl_field(MR_mktag(0), T0_3, (MR_Integer) 2)));

    base = (MR_Word) MR_new_object(MR_Word,
        ((MR_Integer) 3 * sizeof(MR_Word)), NULL, NULL);
    *T_4 = base;
    MR_hl_field(MR_mktag(0), base, 0) = (MR_Box) (packed_args_0);
    MR_hl_field(MR_mktag(0), base, 1) = ((MR_Box) (D_12));
    MR_hl_field(MR_mktag(0), base, 2) = (MR_Box) (packed_args_1);

which does NOT pick up the values A, B, C, E, F and G individually.
However, until now, we could reuse packed-together words only in their
unchanged form.

This diff lifts that limitation, which means that now, we can *also*
optimize code such as

    p(T0, T) :-
        T0 = f1(A, B, _, D, E, _, G),
        C = 42i8,
        F = 43i8,
        T  = f1(A, B, C, D, E, F, G).

by generating code like this:

    base = (MR_Word) MR_new_object(MR_Word,
        (3 * sizeof(MR_Word)), NULL, NULL);
    *T_4 = base;
    MR_hl_field(MR_mktag(0), base, 0) = (MR_Box)
        ((((packed_word_0 & (~((MR_Unsigned) 255U)))) |
        (MR_Unsigned) ((uint8_t) (C_12))));
    MR_hl_field(MR_mktag(0), base, 1) = ((MR_Box) (D_8));
    MR_hl_field(MR_mktag(0), base, 2) = (MR_Box)
        ((((packed_word_1 & (~((MR_Unsigned) 510U)))) |
        (((MR_Unsigned) ((uint8_t) (F_13)) << 1))));

The general scheme when reusing *part* of a word is: first set the bits
not being reused to zero, and then OR in new values of those bits.

Make this optimization as general as possible by making it work
not just for

- words in memory cells containing only arguments,

but also for

- words in memory cells containing a remote sectag as well as arguments, and
- words in registers cells containing a ptag, a local sectag as well as
  arguments.

compiler/ml_gen_info.m:
    Generalize the data structure we use to represent information about
    packed words to make possible approximate as well as exact lookups.
    The key in the old map was "these bitfields with the values of these
    variables in them", while the key in the new map is just "these bitfields",
    with the associated value being a list, each element of which says
    "the word with these values in those bitfields is available in this rval".
    This makes it possible to look for matches words that have some, but not
    all, of the right values in the bitfields.

    Since the packed words may now contain tags as well as arguments,
    rename "packed args" to "packed word".

compiler/ml_unify_gen_deconstruct.m:
    When deconstructing a term containing packed words, add them to the
    packed word map even when one of the bitfields inside the packed word
    contains tag information.

    Move the code that adds a packed word to the map into a separate predicate,
    now that it is needed from more than one place.

compiler/ml_unify_gen_construct.m:
    Change the code that handles packed words to work in terms of filled
    bitfields. Use this not only to implement the optimization described
    at the top, but also to make the handling of bitfields more systematic.
    At least one previous bug was caused by doing sign extension differently
    for the bitfield containing the first packed argument in a word than for
    the later packed arguments in that word; with the new design, such
    inconsistencies should not happen.

compiler/ml_unify_gen_util.m:
    Add utility predicates now needed for both construct and deconstruct
    unifications.

compiler/mlds.m:
    Document the new use of lvnc_packed_word (renamed from lvnc_packed_args).

compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
    Conform to the changes above (mostly the packed_word rename).

compiler/mlds_to_c_data.m:
compiler/mlds_to_c_stmt.m:
    Omit unneeded casts from the output. Specifically, don't put (MR_Integer)
    casts in front of integer constants being used either as shift amounts,
    or as the number of words that a new_object MLDS operation should allocate.
    The casts only cluttered the output, making it harder to read, and
    therefore to judge its correctness.
2018-09-10 16:17:17 +10:00
Zoltan Somogyi
142f272142 Harmonize the ground term parts of {,ml_}unify_gen_construct.m.
compiler/unify_gen_construct.m:
compiler/ml_unify_gen_construct.m:
    As above.

compiler/hlds_data.m:
    Define an inst for use by the new code in the modules above.

compiler/ml_code_gen.m:
    Conform to a harmonised predicate name.
2018-07-16 20:21:25 +02:00
Zoltan Somogyi
582ba08c80 Harmonize unify_gen{,_util}.m with their MLDS counterparts.
This diff begins a process to make the code in the LLDS and MLDS backends
use similar code, using similar predicate names and predicate code structures,
similar type structures, and even similar variable names, for their similar
tasks in generating code for unifications. Where possible, this process
should make the predicates handling different kinds of unifications
even within the *same* backend use similar data- and code structures
and variable names.

The convention for names is that when two predicates do the same job
in the two backends, then if the predicate name in the LLDS backend is X,
then the predicate name in the MLDS backend is ml_X. This preserves the
usefulness of the tags file.

compiler/unify_gen.m:
compiler/ml_unify_gen.m:
    Mold the predicates that dispatch on the kind of unification being done
    (assign, test, construct or deconstruct) into similar structures.

    Make both these modules handle assignment and simple test unifications
    using similar code.

compiler/unify_gen_util.m:
compiler/ml_unify_gen_util.m:
    Give predicates and functions that do similar jobs in these two modules
    similar names. Document some of the reasons for differences between
    the backends that are not immediately obvious.

    Delete an output argument from a predicate that was always given the
    same value.

compiler/unify_gen_construct.m:
compiler/ml_unify_gen_construct.m:
    Make a start on harmonizing the contents of these two modules
    by making them process the various kinds of constants
    in the same order for dynamic unifications.

compiler/unify_gen_deconstruct.m:
compiler/ml_unify_gen_deconstruct.m:
    Make these modules handle *every* aspect of generating code for
    deconstruction unifications, not just *some*, to simplify the boundary
    between then and unify_gen.m/ml_unify_gen.m.

compiler/unify_gen_test.m:
    Delete the predicate handling simple test unifications, since it has now
    been moved to unify_gen.m. (The MLDS backend never had a separate
    predicate for this task in the first place.)

compiler/ml_unify_gen_test.m:
    Improve some comments.

compiler/closure_gen.m:
compiler/ml_closure_gen.m:
    Use similar names for predicates that generate code for construct
    unifications that create closures.

compiler/ml_code_gen.m:
    Conform to a predicate name change in ml_unify_gen.m.
2018-07-11 04:45:40 +02:00
Zoltan Somogyi
1fb59caa47 Split up ml_unify_gen.m.
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
    Carve these four modules out of ml_unify_gen.m. The first two handle
    the construction and deconstruction of terms, the third tests whether
    a variable is bound to a given cons_id, and the fourth contains utility
    types and predicates needed by more than one of the other modules.

compiler/ml_unify_gen.m:
    Remove the code moved to the modules above.

compiler/ml_backend.m:
compiler/notes/compiler_design.html:
    Add and document the new modules.

compiler/Mercury.options:
    Require the new modules to have consistency between the order of predicate
    declarations and the order of predicate definitions.

compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_top_gen.m:
    Conform to the change above.
2018-07-09 14:36:54 +02:00
Zoltan Somogyi
bbe0f28f3b Copy packed arguments all at once.
Copy words containing packed-together sub-word-sized arguments all
in one piece if possible, for hlc grades.

Given a type such as

:- type t
    --->    f1(int8, bool, int8, int, bool, int8, bool).

whose first three and last three arguments are packed into one word each,
and a predicate such as

p(T0, T) :-
    T0 = f1(A, B, C, _, E, F, G),
    D = 42,
    T  = f1(A, B, C, D, E, F, G).

we used to generate code that picked up each of the six named arguments
from T0, and used them to construct T. With this diff, we now translate
the above to

    MR_Integer D_12 = (MR_Integer) 42;
    MR_Unsigned packed_args_0 =
        (MR_Unsigned) ((MR_hl_field(MR_mktag(0), T0_3, (MR_Integer) 0)));
    MR_Unsigned packed_args_1 =
        (MR_Unsigned) ((MR_hl_field(MR_mktag(0), T0_3, (MR_Integer) 2)));

    base = (MR_Word) MR_new_object(MR_Word,
        ((MR_Integer) 3 * sizeof(MR_Word)), NULL, NULL);
    *T_4 = base;
    MR_hl_field(MR_mktag(0), base, 0) = (MR_Box) (packed_args_0);
    MR_hl_field(MR_mktag(0), base, 1) = ((MR_Box) (D_12));
    MR_hl_field(MR_mktag(0), base, 2) = (MR_Box) (packed_args_1);

compiler/ml_unify_gen.m:
    Implement the two main parts of this optimization.

    Part one is the change to deconstruction unifications. When we generate
    assignments from all the fields packed together into a word to their
    corresponding argument variables (such as A/B/C or E/F/G above),
    create a fresh variable (such as packed_args_0 above), assign to it
    the value of the whole word, and record in a new data structure (the
    packed_args_map) that these argument variables, in these positions
    within the word, are now available in the newly created variable.
    (We still define the argument variables as well, since they may be needed;
    deleting them if they are *not* needed is the job of ml_unused_assign.m.)

    Part two is the change to construction unifications. When we generate code
    to OR together the shifted and/or masked values of two or more variables
    to fill in one word in a new heap cell, we search the packed_args_map
    to see whether those variables, in the positions we need, are available
    in one of the variables created in part one. If yes, we discard
    the whole OR-ing together operation and we use that variable instead.

    Since part one can now create local variable definitions, return these
    upwards as needed.

compiler/ml_gen_info.m:
    Add two fields to the ml_gen_info structure (actually, to one of its
    substructures). One is the packed_args_map described above, the other
    is a counter we use to give a unique name to all the fresh variables.

    When creating ml_gen_infos, put the code defining each field of a
    substructure next to the creation of that substructure.

compiler/mlds.m:
    Add a kind of compiler-generated variable holding packed argument words.
    It is used in part one above.

compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
    Save, reset and restore the packed_args_map as necessary to ensure that
    a construction unification sees an entry in that map only if the
    deconstruction unification that created that entry *had* to be executed
    before execution reaches the construction unification.

    This means that when we process a branched control structure, we have to
    make sure that (a) entries created by one branch are not seen when
    we generate code for the other branches, and (b) that code *after* the
    branched control structure sees only the entries created *before* the
    branched control structure, since such code following cannot use an entry
    that was created by a branch that may or may NOT have been executed
    on the way there.

    We also reset the packed_args_map to empty when generating code
    that will end up inside a nested function, for two reasons. First,
    I am not sure whether the code in ml_elim_nested.m that flattens out
    nested functions is general enough to handle the new kind of compiler
    generated variable correctly. And second, even if it is, the additional
    memory traffic for putting those variables into environments, and later
    pulling them out again, would definitely reduce and maybe completely
    eliminate the speedup from optimizing constructions.

compiler/ml_closure_gen.m:
    Conform to the change in ml_unify_gen.m.

compiler/ml_proc_gen.m:
    Invoke ml_unused_assign.m in both branches of an if-then-else.
    Previously, it was invoked in only the rarely executed branch,
    which is what hid its bugs.

    Fix one bug: for model_semi procedures, include the succeeded variable
    in the set of variables whose values is needed after the generated
    function body.

    Work around another bug: the ml_unused_assign.m cannot yet handle
    nested functions properly, so throw away its output in their presence.

compiler/ml_unused_assign.m:
    As part of the same workaround, if a block contains nested functions,
    tell ml_proc_gen.m to use the original code.

    Fix several other bugs.

    Don't delete variables from the seen_set when the backwards traversal
    finds an assignment to them, because the variable's absence from
    the seen_set would lead to the declaration of the variable being deleted.

    Delete a sanity check that made sense only the presence of such deletions.

    Never delete assignments to compiler-generated variables; we generate
    such assignments only when their results *will* be needed.

    When exiting the traversal of a block, *do* delete the variables
    declared locally in that block from the seen_set; being undeclared there,
    they cannot possibly be seen before that block. leaving them in
    does not compromise correctness, but does reduce performance
    by making operations on the seen_set slower than necessary.

    If deleting unused assignments makes the else part of an if-then-else
    empty, then delete the whole else part.

compiler/mlds_to_c_stmt.m:
    Generate a valid C statement even for an MLDS comment. When an buggy
    version of ml_unused_assign.m (incorrectly) deleted assignments to
    succeeded, it sometimes left an else part containing only a comment,
    which lead gcc to report syntax errors.
2018-06-02 18:56:40 +02:00
Zoltan Somogyi
b9afc8b78e Delete the mlds_unary_op type.
compiler/mlds.m:
    We used to have a function symbol ml_unop in the mlds_rval type
    that applied one of four kinds of operations to an argument mlds_rval:
    boxing, unboxing, casting or a standard unary operation, with a value
    of type mlds_unary_op selecting between the four. Replace this system
    with four separate function symbols in the mlds_rval type directly,
    and delete the mlds_unary_op type.

    The new arrangement requires fewer memory cells to be allocated,
    and less indirection; it also leads to shorter and somewhat
    more readable code.

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

    Recognize that a cast has negligible cost.

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

    Keep private a predicate that is not used by any other module,
    after merging it with another previously-exported predicate
    that only *it* uses.

    Delete some other predicates that are not used anywhere.

compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_global_data.m:
compiler/ml_lookup_switch.m:
compiler/ml_rename_classes.m:
compiler/ml_string_switch.m:
compiler/ml_tag_switch.m:
compiler/ml_unify_gen.m:
compiler/ml_unused_assign.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/mlds_to_target_util.m:
compiler/rtti_to_mlds.m:
    Conform to the change above.
2018-05-13 12:23:38 +02:00
Zoltan Somogyi
955a69efff Give better names to some functions.
compiler/type_util.m:
    Rename the "check_dummy_type" function to "is_type_a_dummy", since this
    expresses its job more clearly.

    Make the implementation of "is_type_a_dummy" slightly more efficient,
    by avoiding some redundant actions.

    Provide a new function "is_either_type_a_dummy" that does
    what its name says, and which is somewhat more efficient than
    two separate calls to "is_type_a_dummy".

compiler/prog_type.m:
    Rename the "check_builtin_dummy_type_ctor" function to
    "is_type_ctor_a_builtin_dummy", since this expresses its job
    more clearly.

compiler/ml_unify_gen.m:
    Conform to the name changes.

    Use the new function where relevant to simplify some code.

    Fix some comments.

compiler/code_info.m:
compiler/code_loc_dep.m:
compiler/continuation_info.m:
compiler/erl_call_gen.m:
compiler/erl_code_gen.m:
compiler/erl_code_util.m:
compiler/erl_unify_gen.m:
compiler/export.m:
compiler/higher_order.m:
compiler/hlds_pred.m:
compiler/live_vars.m:
compiler/llds_out_instr.m:
compiler/mark_tail_calls.m:
compiler/ml_args_util.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/pragma_c_gen.m:
compiler/stack_layout.m:
compiler/term_constr_util.m:
compiler/trace_gen.m:
compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/var_locn.m:
compiler/write_module_interface_files.m:
    Use the new function where relevant.
2018-02-28 13:48:44 +11:00
Zoltan Somogyi
5c43340b11 Implement TRO for model_non procedures.
The one thing that tail recursion optimization (TRO) via ml_tailcalls.m
could do that TRO via the MLDS code generator couldn't was TRO for model_non
procedures. This diff eliminates that difference.

compiler/mark_tail_calls.m:
    Don't blow off marking tail calls in model_non procedures.

    Add a new reason why TRO does not apply to a tail call. If the tail
    call is in a nondet continuation, then the code we generate for it
    will be in a nested function, which will end up in a *separate* function.
    Implementing the tail call as a continue that jumps to the start of a
    while loop that wraps the entire function body won't work, since continues
    won't work from functions other than the one that contains the while loop.

compiler/ml_gen_info.m:
    Add a field to the code generator state that gives the number of nested
    functions the about-to-be-generated code will end up inside.

compiler/ml_call_gen.m:
    Don't apply TRO to a call if this nesting level isn't zero, since
    in that case the generated code would end up in a different function.

compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
    Increment the function nesting level before starting to generate code
    that will end up in nested function, and decrement it afterwards.

compiler/ml_proc_gen.m:
    Allow model_non procedures to be subject to TRO.

    When generating the comment identifying a function that results from TRO
    for a single procedure, make it specify its code_model.
2017-10-12 23:04:06 +11:00
Zoltan Somogyi
b0edecbc7e Return information about output args in an assoc list.
compiler/ml_args_util.m:
    Change the interface of the ml_gen_args predicate, which is used
    to generate argument passing code at call sites. Instead of returning
    information about output arguments in two lists, return a single list
    of pairs, since this encodes the relevant invariant (the two lists
    have to be of equal length) in the type.

compiler/ml_gen_info.m:
    Make the same change in the representation of information about
    output variables in success continuations. These continuations
    are often constructed from the data returned by ml_gen_args.

compiler/ml_call_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_proc_gen.m:
    Conform to the change above.

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

    Use the new list of pairs representation to greatly simplify
    a piece of code that used higher order constructs to excess.
2017-09-12 00:52:39 +10:00
Zoltan Somogyi
d412bd410e Use arg tuples to simplify more code.
compiler/ml_args_util.m:
    I recently changed most predicates that generate a description
    of a procedure's parameter passing interface by first constructing
    a tuple for each parameter containing the information that is relevant
    to the decision about how that parameter should be passed. This diff
    makes those predicates return these tuples, since some callers can
    also benefit from having this information in this convenient form.

    Use this kind of tuple when generating a description of the input
    parameters of mutually-tail-recursive procedures.

    Change ml_gen_args and its friends (the predicates that generate code
    for actually passing parameters) to take information about the value
    being passed as ml_call_args, which have either one of two forms.
    One is just the prog_var being passed; the other is a tuple containing
    the MLDS var representing the parameter, its lval, and its actual type
    (which may differ from the type of the corresponding formal parameter,
    by being its instance). The former should be used far more frequently
    (the second is used only when constructing closure wrapper functions),
    and in this case, our caller will have to construct just one list
    (a list of wrapped prog_vars) instead of three (the MLDS var names,
    the MLDS var lvals, and the actual types), and will have to do fewer tests.

    Export the copy_out_when type, and the function that computes the right
    copy_out_when value for a given procedure, for use by ml_closure_gen.m.

    In some predicates, put related parameters together.

    In some predicates, change the names of variables to state explicitly
    whether they contain information about the caller or the callee side
    of parameter passing.

    Use Head and Tail prefixes in variable names more consistently.

compiler/ml_call_gen.m:
    Use ml_call_args to represent the arguments of calls.

    In some predicates, put related parameters together.

    In some predicates, change the names of variables to state explicitly
    whether they contain information about the caller or the callee side
    of parameter passing.

compiler/ml_code_gen.m:
    When handling calls, simply pass the argument variables to ml_call_gen.m;
    let *it* decide how it wants to construct the argument passing code.

compiler/ml_closure_gen.m:
    Use ml_call_args (in their more complicated form) to represent
    the arguments of the single unusual call inside closure wrapper
    function definitions. (It is unusual because some parameters
    are not HLDS variables.)

    Use the tuple description of the callee's parameters to simplify
    the code generating the lvals used as the arguments of that call.

    In some predicates, put related parameters together.

compiler/ml_proc_gen.m:
    Use the tuples constructed by ml_args_util.m to describe procedures'
    arguments to simplify the code that boxes or unboxes arguments as needed.

compiler/ml_top_gen.m:
    Conform to the changes in ml_args_util.m.
2017-09-11 15:06:44 +10:00
Zoltan Somogyi
f4e0059a49 Eliminate hlc_nest and hl_nest grades ...
... by eliminating the grade component that calls for the use of gcc nested
functions.

runtime/mercury_grade.h:
compiler/compute_grade.m:
    Delete the gcc_nested_functions grade component, and the C macro
    that specifies its presence, MR_USE_GCC_NESTED_FUNCTIONS.

scripts/canonical_grade.sh-subr:
scripts/init_grade_options.sh-subr:
scripts/mgnuc.in:
scripts/parse_grade_options.sh-subr:
    Delete the code that parses the deleted grade component,
    and delete the code that signals its absence in other grades.

compiler/options.m:
    Delete the gcc_nested_functions grade option.

    Delete also the gcc_local_labels option, since it was useful
    only if gcc_nested_functions was set.

configure.ac:
    Delete the code that sometimes added hl*_nest grades to the list of grades
    to be installed.

    Fix a bunch of comments.

compiler/compile_target_code.m:
compiler/handle_options.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/ml_args_util.m:
compiler/ml_call_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_gen_info.m:
compiler/mlds_to_c.m:
library/backjump.m:
library/exception.m:
runtime/mercury_hlc_types.h:
runtime/mercury_tabling.c:
runtime/mercury_tabling.h:
    Delete code that was active only in grades with the deleted grade
    component.

compiler/ml_accurate_gc.m:
compiler/notes/grade_library.html:
runtime/mercury_conf_param.h:
    Delete mentions of the deleted grade component.

compiler/ml_code_gen.m:
    Delete mentions of the deleted grade component, and a bunch of other
    obsolete comments.

doc/user_guide.texi:
    Fix a line break.
2017-09-07 03:01:55 +10:00
Zoltan Somogyi
034cb97988 Don't module- or type-qualify MLDS local variables.
Some global variables generated by the MLDS backend need to be visible
across module boundaries, and therefore mlds_data definitions, which
contained global as well as other variables, used to have their names
qualified; usually module-qualified, though sometimes type-qualified.

However, since the diff that partitioned mlds_data_defns into the
definitions of local variables, global variables and field variables,
the qualification of local variables has *not* been necessary, so this diff
removes such qualifications. This makes the MLDS code generating references
to local variables simpler, more readable, and slightly faster.
The generated code is also shorter and easier to read.

There are two exceptional cases in which local variables *did* need
qualification, both of which stretch the meaning of "local".

One such case is the "local" variable dummy_var, which (by definition)
is only ever assigned to, and never used. It is also never defined
in MLDS-generated code; instead, it is defined defined in private_builtin.m
(for the Java and C# backends) or the runtime (for C). All three backends
currently require references to this variable in the runtime to be module
qualified. There are three possible fixes to this problem, which is caused
by the fact that this "local" variable is in fact global.

- Fix 1a would be to make dummy_vars global, not local.
- Fix 1b is to special-case dummy_vars in mlds_to_{c,cs,java}.m, and put
  the fixed "private_builtin" qualifier in front of it.
- Fix 1c would be to modify the compiler to never generate any references
  to dummy vars at all.

This diff uses fix 1b, because it is simple. I (zs) will explore fix 1c
in the future, and see if it is viable.

The second such case occurs when generating code for unifications
involving function symbols represented by the addresses of reserved objects.
These addresses used to be represented as the addresses of mlds_data
definitions, then as addresses of field variables cast as qualified
local variables. Since diff this makes all local variables unqualified,
this can't continue. Two possible fixes are

- Fix 2a: introduce an mlds const rval representing the address of a field
  variable, which solves the problem because unlike local variables,
  field variables can still be either module- or type-qualified.
- Fix 2b: prohibit the use of the addresses of reserved objects as tags.

After a (short) discussion on m-dev, this diff uses fix 2b.

compiler/mlds.m:
    Delete the qual_local_var_name type, and replace all its uses
    with the mlds_local_var_name type. Delete the module qualifier field
    in mlds_data_addr_local_var consts.

compiler/ml_code_util.m:
    Simplify the predicates and functions whose task is to build references
    to local variables. Delete the arguments that they don't need anymore.
    Delete one function entirely, since calling it now takes both more
    characters and more code than its shortened body does.

compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_rename_classes.m:
compiler/ml_string_switch.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds_to_target_util.m:
compiler/rtti_to_mlds.m:
    Conform to the changes above. Stop qualifying local variable names,
    and stop passing the parameters that used to be used *only* for
    qualifying local variable names.

compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
    Conform to the changes above, and implement fix 1b.

NEWS:
compiler/options.m:
compiler/make_tags.m:
    Implement fix 2b by disabling the --num-reserved-objects option.
    This ensures that we don't use the addresses of reserved objects as tags.

library/private_builtin.m:
    Move the C# definition of dummy_var next to the Java definition,
    and fix the comments on them.
2017-08-09 18:23:53 +02:00
Zoltan Somogyi
da9808036c Implement self-tail-call optimization in the MLDS code generator.
This is a step towards implementing not just self- but also mutual
tail recursion in the MLDS code generator.

compiler/options.m:
    Add an option, --optimize-tailcalls-codegen, that asks for MLDS backend
    to optimize self tail calls via the code generator, not ml_tailcall.m.
    (We still use ml_tailcall.m if the new option is not set.) The new option
    is set by default, but this can be changed if we find a problem
    with the new approach.

compiler/mark_tail_calls.m:
    Fix a bug. In a disjunction, the nonlast disjuncts cannot contain tail
    calls, because (a) if a nonlast disjunct is semidet, then after any
    such recursive call fails, we can still backtrack to later disjuncts,
    and (b) if the nonlast disjunct involved is det, the later disjuncts
    should have been optimized away, and the disjunct wouldn't be nonlast
    anymore.

    Export predicates that allow the MLDS backend to mark tail calls
    as *it* wants them marked.

    Reorganize the predicates that generate warnings to make them useable
    from the MLDS code generator as well, and export the required predicates.
    (The MLDS code generator needs this access because in some cases,
    a call that mark_tail_calls.m thinks is a tail call cannot be implemented
    as such. Since only the MLDS code generator knows this fact, only *it*
    can know when this warning may need to be generated.)

    Some of the reorganization of code that generates warnings factors out
    common code between mark_tail_calls.m and ml_tailcall.m.

compiler/ml_tailcall.m:
    Export some functionality for the code generator to use.

    Replace the found_recursive_call type, which used to be defined here,
    with the found_any_rec_calls type from mark_tail_calls.m, since they
    were isomorphic and had the same job.

    Delete the code that was factored out into mark_tail_calls.m.

compiler/mercury_compile_mlds_back_end.m:
    If --optimize-tailcalls-codegen is set, run the mark_tail_calls pass
    before MLDS codegen.

    Prepare for the code generator to generate warnings about calls that should
    be tail calls not actually being tail calls.

    Delete an unused exported predicate, and the imports it used to need.

compiler/mercury_compile_llds_back_end.m:
    Fix style.

compiler/ml_gen_info.m:
    Extend the code generator state with information needed for tail call
    optimization, and for generating warnings.

compiler/ml_proc_gen.m:
    When starting to generate code for a procedure, set up the new part
    of the code generator state with the information needed to handle tail
    calls, if we both (a) can optimize tail calls in the predicate, and (b)
    we have been asked to.

    After the code for the procedure body has been generated, *and* if
    we have actually turned some tail calls into jumps to the start of
    the procedure, create the wrapper around the MLDS code implementing
    the body goal that makes such jumps possible.

compiler/ml_call_gen.m:
    When generating code for a plain call, test whether it is a tail call,
    and if so, try to optimize it. If we fail, generate a warning about
    that fact, and fall back to generating code for it as we would do
    for any non-tail call.

    Provide mechanisms for this new code to compute the actual parameter
    lvals for the input arguments of a (tail) call, since only these
    have to be assigned from when replacing a tail call.

compiler/ml_code_util.m:
    Provide mechanisms for ml_proc_gen to compute the mlds_arguments
    of the formal parameters of just the input arguments of a procedure,
    since only these have be assigned to when replacing a tail call.

    (The predicates that perform these mirror image tasks should be
    next to each other, perhaps in a new ml_args_util.m module.)

compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_optimize.m:
    Export to ml_call_gen.m (a slightly modified form of) a predicate
    that is used in the replacement of tail calls.

    Peephole optimization a pattern that we now generate.

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

tests/hard_coded/semi_tail_call_in_nonlast_disjunct.{m,exp}:
    Add a test case for the bug fixed in mark_tail_calls.m. Without the fix,
    the updated MLDS code generator's output fails this test.

tests/hard_coded/Mmakefile:
    Enable the new test case.
2017-08-07 19:33:33 +02:00
Zoltan Somogyi
f4ab258e36 Improve some comments and a predicate name. 2017-07-30 03:32:55 +02:00
Zoltan Somogyi
1c01ed85eb Fix lines. 2017-07-29 14:15:15 +02:00
Zoltan Somogyi
91790794f1 Define the MLDS "succeeded" variable only if needed.
This makes the generated MLDS code less cluttered and easier to work on.

compiler/ml_gen_info.m:
    Add a field for recording whether the succeeded variable has been used.

compiler/ml_code_util.m:
    Change the predicates that return references to the succeeded variable
    to record that it has been used.

compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_lookup_switch.m:
compiler/ml_string_switch.m:
compiler/ml_unify_gen.m:
    Use the updated forms of the predicates in ml_code_util.m.

compiler/ml_proc_gen.m:
    Define the succeeded variable only if the new slot says it has been used.

compiler/ml_optimize.m:
    Fix a bug triggered by the above change: when a tail recursive call
    was the *entire body* of a MLDS function, ml_optimize.m did not find it,
    and thus did not do the setup needed to prepare for the tail recursion.
    Previously, the always-present declaration of "succeeded" made it
    impossible for the tail call to be the only thing in the body.
2017-07-29 01:40:56 +02:00
Zoltan Somogyi
11c232f060 Store different kinds of definitions in blocks separately.
An ml_stmt_block contains some definitions and some statements.
The definitions were traditionally stored in a single list of mlds_defns,
but lots of code knew that some kinds of mlds_defns just couldn't occur
in blocks. This diff, by storing the definitions of (a) local variables
and (b) continuation functions in separate field in ml_stmt_blocks,
gets the type system to enforce the invariant that other kinds of definitions
can't occur in blocks.

This also allows the compiler to do less work, since definitions
don't have to wrapped and then later unwrapped, and code that wants to look
at only e.g. the function definitions in a block don't have to traverse
the definitions of local variables (of which there are many more).

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

compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/mlds_to_target_util.m:
    Conform to the change above. This allows us to avoid lots of wrapping
    up definitions.

    In some cases, after this change, we don't need to process mlds_defns
    *in general*, which leaves the predicates that used to do that,
    and some of the predicates that they used to call, unused. Delete these.

    In code that generated MLDS code, consistently use names containing
    the word "Defn", instead of "Decl", for variables that contain
    mlds_local_var_defns or mlds_function_defns. Some such predicates
    generate lists of both local var definition and function definitions,
    but most generate only one, and some generate neither.
2017-07-26 00:57:13 +02:00
Zoltan Somogyi
47f1df4a0a Split mlds_data_defn into three separate types.
We used to use mlds_data_defns to represent three related but nevertheless
distinct kinds of entities: global variables, local variables, and fields
in classes. This diff replaces the mlds_data_defn type with three separate
types: mlds_global_var_defn, mlds_local_var_defn and mlds_field_var_defn
respectively, with corresponding changes to related types, such as
mlds_data_name.

The global variables are completely separate from the other two kinds.
Local and field variables are *mostly* separate from each other, but they
are related in one way. When we flatten out nested functions, the child
nested function can no longer access its parent function's local variables,
so we pass those variables to it as fields of an environment structure.
This requires turning local variables to fields of that structure,
and the code in the flattened previously-nested function that accesses
those fields naturally wants to treat them as if they were local variables
(as indeed they sort-of were before the flattening). There are therefore
ways to convert each of local and fields vars into the other.

This restructuring makes clear several invariants of the MLDS we generate
that were previously hidden. For example, variables with certain kinds of
names (in the before-this-diff, general version of the mlds_var_name type)
could appear only as function arguments or as locals in ml_stmt_blocks,
not in ml_global_data, while for some other names the opposite was the case.
And in several cases, functions used to take a general mlds_data_defn
as argument but aborted if given the "wrong kind" of mlds_data_defn.

This diff also makes possible further simplifications. For example,
local vars should not need some flags (since e.g. they are never per-instance),
and should never need either module or type qualification, while global
variables (which are also never per-instance) should never need type
qualification (since they are not fields of a type). The definitions
in blocks should consist of local variables and (before flattening) functions,
not global variables, field variables or classes, while the members in classes
should be only field variables and functions (and maybe classes), not
global or local variables. Those changes will be in future diffs;
this is already large enough.

compiler/mlds.m:
    Make the changes described above.

    Use tighter types where possible.

    Use (a generalized version) of the mlconst_named_const functor
    to represent values of enum types defined in the runtimes
    of the target platforms.

compiler/ml_global_data.m:
    Store *only* global variables in fields that previously stored general
    mlds_datas (that by design were always global).

    Store *only* closure wrapper functions in the previous non-flat-defns
    field. Before this diff, the code generator only put closure wrapper
    functions in this field, but then ml_elim_nested.m put everything
    resulting from the expansion of those functions back into those fields
    as well, some of which were not functions. It now puts those non-function
    things into the MLDS data structure directly.

compiler/ml_code_util.m:
compiler/ml_util.m:
    Conform to the changes above.

    Use tighter types where possible. If appropriate, change the name
    of the function or predicate accordingly.

    Represent references to enum constants defined in the runtime of the
    target language as named constants (since they is what they are),
    instead of representing them as MLDS "variables", which required
    the code of mlds_to_cs.m had to special-case the treatment
    of those "variables".

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

    Use tighter types where possible.

    Don't put the environment types resulting from flattening nested scopes
    back into the non-flat-defns slot of the ml_elim_info; instead, return
    them separately to code that puts them directly in the MLDS.

compiler/rtti.m:
    When returning the names of enum constants in the C runtime, return also
    the prefixes that you need to place in front of these to obtain their names
    in the Java and C# runtimes.

compiler/mercury_compile_mlds_back_end.m:
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/mlds_to_target_util.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
    Conform to the changes above.

    Move a utility function from ml_util.m to mlds_to_target_util.m,
    since it is used only in mlds_to_*.m.
2017-07-22 00:20:40 +02:00
Zoltan Somogyi
083f990dbb Simplify the use of contexts in the MLDS.
compiler/mlds.m:
    This diff fixes two minor annoyances imposed by the old use of the
    mlds_context type in the MLDS.

    The first annoyance was that the mlds_context type used to be an
    abstract type that was privately defined to be a trivial wrapper
    around a prog_context. It had the exact same information content
    as a prog_context, but you had to go through translation functions
    to translate prog_contexts to mlds_contexts and vice versa.
    I think Fergus's idea was that we may want to add other information
    to the mlds_context type. However, since we haven't felt the need
    to anything like that in the 18 years (almost to the day) that the
    mlds_context type existed, I think this turned out to be a classic
    case of YAGNI (you ain't gonna need it).

    This diff deletes the mlds_context type, and replaces its uses
    with prog_context.

    The second annoyance was that actual MLDS code, i.e. values of the
    mlds_stmt type, always had to wrapped up inside a term of the statement
    type, a term which paired a context with the mlds_stmt.

    This diff moves the context information (now prog_context, not
    mlds_context) into each function symbol of the mlds_stmt type,
    deletes the statement type, and replaces its uses with the now-expanded
    mlds_stmt type. This simplifies most code that deals with MLDS code.

compiler/ml_util.m:
    Add a function, get_mlds_stmt_context, for the (very rare) occasions
    where we want to know the context of an mlds_stmt *before* testing
    to see what function symbol it is bound to.

compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_global_data.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_to_mlds.m:
    Conform to the changes above.

    In some cases, a function was given two separate contexts, sometimes from
    two separate sources; a prog_context and an mlds_context. In such cases,
    keep only one source.

    Standardize on Stmt as the variable name for "statement".

    Delete redundant $module references from unexpected and other abort
    predicates.

    In one case, delete a function that was a duplicate of another function.

    Give some predicates and functions more meaningful names.
2017-07-09 18:44:05 +02:00
Zoltan Somogyi
27f57da2ff Delete a duplicate comment. 2017-06-02 22:09:10 +02:00
Zoltan Somogyi
869605956c Make MLDS definitions self-contained.
Until now, we used a single type, mlds_defn, to contain both

- generic information that we need for all MLDS definitions, such as
  name and context, and

- information that is specific to each different kind of MLDS definition,
  such as a variable's initializer or a function's list of parameter types.

The former were contained in three fields in the mlds_defns directly,
while the latter were contained in a fourth field that was a discriminated
union of mlds_data_defn, mlds_function_defn and mlds_class_defn.

While seemingly parsimonious, this design meant that if we had e.g. a list
of variable definitions, we would have to wrap the mlds_defn/4 wrapper around
them to give them their names, and thereafter, any code that processed
that list would have to be prepared to process not just variables but also
functions and classes.

This diff moves the three generic fields into each of the mlds_data_defn,
mlds_function_defn and mlds_class_defn types, making each those types
self-contained, and leaving mlds_defn as nothing more than a discriminated
union of those types.

In the few places that want to look at the generic fields *without*
caring about what kind of entity is being defined, this design requires
a bit of extra work compared to the old design, but in many other places,
the new design allows us to return mlds_data_defns, mlds_function_defns
or mlds_class_defns instead of just mlds_defns.

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

    Store type definions (for high level data) and table structures definitions
    separately from other definitions in the MLDS type, since we can now
    give them tighter types.

compiler/ml_global_data.m:
    Change the fields that store flat cells from storing mlds_defns to
    storing mlds_data_defns, since we can now do so.

    Add an XXX about an obsolete comment.

compiler/mercury_compile_mlds_back_end.m:
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_to_mlds.m:
    Conform to the changes above. Where possible with only local changes,
    return mlds_data_defns mlds_function_defns or mlds_class_defns instead
    of just mlds_defns. Put the mlds_data(_), mlds_function(_) or mlds_class(_)
    wrapper around those definitions as late as possible (typically, when
    our current code wants to put it into the same list as some other kind
    of definition), in the hope that in the future, that wrapping can be
    delayed even later, or even avoided altogether. Make the places where
    such improvements may be possible with "XXX MLDS_DEFN".

    In some places, the tighter data representation allows us to *delete*
    "XXX MLDS_DEFN" markers.

    Move some common code from mlds_to_{cs,java}.m to ml_util.m.

    In mlds_to_{cs,java}.m, add prefixes to the function symbols in a type
    to reduce ambiguity.
2017-05-24 09:45:21 +02:00
Zoltan Somogyi
8dbea9f096 Use a structured representation for MLDS variables.
compiler/mlds.m:
    Replace the old definition of mlds_var_name, which was a string
    with an optional integer. The integer was intended to be the number
    of a HLDS variable, while auxiliary variables created by the compiler,
    which do not correspond to a HLDS variable, would not have the optional
    integer.

    This design has a couple of minor problems. The first is that there is
    no place in the compiler where all the variable names are visible at once,
    and without such a place, we cannot be sure that two names constructed
    for different purposes don't accidentally end up with the same name.
    The probability of such a clash used to be astronomically small
    (which is why this hasn't been a problem), but it was not zero.

    The second problem is that several kinds of compiler-created MLDS variables
    want to have numerical suffixes too, usually with the suffix being a
    unique sequence number used as a means of disambiguation. Most of the
    places where these were created put the numerical suffix into the name
    string itself, while some put the sequence number as the optional integer.

    As it happens, neither of those actions is good when one wants to take
    the independently generated MLDS code of several procedures in an SCC
    and merge them into a single piece of MLDS code. For this, we want to
    rename apart both the HLDS variable numbers and the sequence numbers.
    Having the sequence number baked into the strings themselves obviously
    makes such renumbering unnecessarily hard, while having sequence numbers
    in the slots intended for HLDS variable numbers makes the job impossible
    to do safely.

    This diff switches to a new representation of mlds_var_names that
    has a separate function symbol for each different "origin story"
    that is possible for MLDS variables. This addresses both problems.

    The single predicate that converts this structured representation
    to a string is the place where we can ensure that two semantically
    different MLDS variables never get translated to the same string.
    The current version of this predicate does *not* offer this guarantee,
    but later versions could.

    And having all the integers used in mlds_var_names for different purposes
    stored as arguments of different function symbols (that clearly indicate
    their meaning) makes it possible to rename apart different sets
    of MLDS variables easily and reliably.

    Move the code for converting mlds_var_names from ml_code_util.m to here,
    to make it easier to maintain it together with the mlds_var_name type.

compiler/ml_code_util.m:
    Conform to the above change by generating structured MLDS var names.

    Delete a predicate that is not needed with structured var names.

    Delete the code moved to mlds.m.

    Delete a predicate that has been unused since we deleted the IL backend.

    Add ml_make_boxed_type as a version of ml_make_boxed_types that returns
    exactly one type. This simplifies some code elsewhere.

    Add "hld" to some predicate names to make clear that they are intended
    for use only with --high-level-data.

compiler/ml_type_gen.m:
    Conform to the above change by generating structured MLDS var names.

    Add "hld" to the names of the (many) predicates here that are used
    only with --high-level-data to make clear that fact.

compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
    Conform to the above change by generating structured MLDS var names.

    Add a "for_csharp" or "for_java" suffix to some predicate names
    to avoid ambiguities.

compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_gen_info.m:
compiler/ml_global_data.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_string_switch.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
    Conform to the above change by generating structured MLDS var names.

compiler/prog_type.m:
    Add var_to_type, as a version of var_list_to_type_list that returns
    exactly one type. This simplifies some code elsewhere.

compiler/java_names.m:
    Give some predicates and functions better names.

compiler/ml_code_gen.m:
    Fix typo.
2017-04-24 15:16:36 +10:00
Zoltan Somogyi
8f761b4968 Remove out_of_line_builtin.
compiler/hlds_goal.m:
    Delete out_of_line_builtin as a possible builtin_state, since we
    haven't had any builtin predicates implemented using out-of-line code
    in a long time, and we almost certainly never will again.
    Even if we did, there is no particular reason to believe that all
    the places that test the builtin_state do the right thing when they see
    an out_of_line_builtin; such decisions haven't had their correctness
    tested in more than a decade.

compiler/bytecode_gen.m:
compiler/code_gen.m:
compiler/coverage_profiling.m:
compiler/deep_profiling.m:
compiler/dep_par_conj.m:
compiler/erl_code_gen.m:
compiler/follow_vars.m:
compiler/goal_form.m:
compiler/hlds_dependency_graph.m:
compiler/hlds_out_goal.m:
compiler/interval.m:
compiler/live_vars.m:
compiler/middle_rec.m:
compiler/ml_code_gen.m:
compiler/pd_cost.m:
compiler/prog_rep.m:
compiler/simplify_goal.m:
compiler/ssdebug.m:
compiler/tupling.m:
    Conform to the above.
2017-03-31 05:10:32 +11:00
Zoltan Somogyi
e5daa207fa Fix disabling warnings for non-tail recursive calls with MLDS.
compiler/mlds.m:
    Add a field to call statements in MLDS that contains a (probably empty)
    set of markers. At the moment, the only marker possible is one that says
    "don't generate a non-tail recursive call warning for this call".

compiler/ml_gen_info.m:
    Add a field to the ml_gen_info type, which contains the state of the
    MLDS code generator, that records the set of warnings that are disabled
    for the HLDS goal currently being translated.

compiler/ml_code_gen.m:
    When processing the subgoal inside a disable_warnings scope,
    add the warnings disabled by the scope to the new field
    in the ml_gen_info.

compiler/ml_call_gen.m:
    When creating MLDS call statements, put the new marker in the call's new
    field if goal_warning_non_tail_recursive_calls is among the currently
    disabled warnings.

compiler/ml_tailcall.m:
    Don't generate warnings about a recursive call not being *tail* recursive
    if the call has the new marker.

compiler/ml_accurate_gc.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
    Conform to the changes above.
2017-01-19 20:47:26 +11:00
Zoltan Somogyi
4ebc3ffa04 Carve four modules out of prog_data.m.
The prog_data.m module is imported by most modules of the compiler; by
359 modules out of 488, to be exact. Yet it has many parts that most of
those 359 modules don't need. This diff puts those parts into four new
modules. The number of imports of these modules:

    348 modules import prog_data.m
     84 modules import prog_data_foreign.m
     62 modules import prog_data_pragma.m
     12 modules import prog_data_event.m
      5 modules import prog_data_used_modules.m

compiler/prog_data_event.m:
compiler/prog_data_foreign.m:
compiler/prog_data_pragma.m:
compiler/prog_data_used_modules.m:
    New modules. They contain the parts of the parse tree that deal
    respectively with the specification of events and event sets,
    interfacing to foreign languages, pragmas, and the sets of used
    (i.e. not unused) modules.

compiler/prog_data.m:
    Delete the stuff that is now in the new modules. Put the remaining parts
    of the module into a logical order.

compiler/parse_tree.m:
compiler/notes/compiler_design.html:
    Include and document the new modules.

compiler/globals.m:
    Move a type here from prog_data.m, since this is where it belongs.

compiler/add_foreign_proc.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_solver.m:
compiler/add_trail_ops.m:
compiler/call_gen.m:
compiler/code_gen.m:
compiler/code_loc_dep.m:
compiler/comp_unit_interface.m:
compiler/compile_target_code.m:
compiler/complexity.m:
compiler/continuation_info.m:
compiler/coverage_profiling.m:
compiler/ctgc.datastruct.m:
compiler/ctgc.livedata.m:
compiler/ctgc.selector.m:
compiler/deep_profiling.m:
compiler/dep_par_conj.m:
compiler/deps_map.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/elds_to_erlang.m:
compiler/equiv_type.m:
compiler/erl_call_gen.m:
compiler/exception_analysis.m:
compiler/export.m:
compiler/fact_table.m:
compiler/foreign.m:
compiler/frameopt.m:
compiler/get_dependencies.m:
compiler/goal_form.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/hlds_goal.m:
compiler/hlds_module.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_pred.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/ite_gen.m:
compiler/item_util.m:
compiler/jumpopt.m:
compiler/layout.m:
compiler/layout_out.m:
compiler/live_vars.m:
compiler/livemap.m:
compiler/llds.m:
compiler/llds_out_file.m:
compiler/llds_out_global.m:
compiler/llds_out_instr.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make_hlds.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/ml_call_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_proc_gen.m:
compiler/ml_tailcall.m:
compiler/ml_unify_gen.m:
compiler/mlds.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/modecheck_goal.m:
compiler/module_imports.m:
compiler/module_qual.m:
compiler/module_qual.qualify_items.m:
compiler/modules.m:
compiler/opt_debug.m:
compiler/par_conj_gen.m:
compiler/parse_pragma.m:
compiler/parse_tree_out_info.m:
compiler/parse_tree_out_pragma.m:
compiler/pd_cost.m:
compiler/polymorphism.m:
compiler/pragma_c_gen.m:
compiler/proc_gen.m:
compiler/prog_ctgc.m:
compiler/prog_event.m:
compiler/prog_foreign.m:
compiler/prog_item.m:
compiler/prog_out.m:
compiler/prog_util.m:
compiler/purity.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.points_to_graph.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_scope.m:
compiler/simplify_proc.m:
compiler/smm_common.m:
compiler/stack_layout.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_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/term_constr_main_types.m:
compiler/term_constr_pass2.m:
compiler/term_constr_util.m:
compiler/term_errors.m:
compiler/term_pass1.m:
compiler/term_pass2.m:
compiler/term_traversal.m:
compiler/term_util.m:
compiler/termination.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/type_constraints.m:
compiler/typecheck.m:
compiler/unique_modes.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/use_local_vars.m:
compiler/write_deps_file.m:
    Conform to the changes above.
2016-03-13 18:19:31 +11:00
Julien Fischer
94535ec121 Fix spelling and formatting throughout the system.
configure.ac:
browser/*.m:
compiler/*.m:
deep_profiler/*.m:
library/*.m:
ssdb/*.m:
runtime/mercury_conf.h.in:
runtime/*.[ch]:
scripts/Mmake.vars.in:
trace/*.[ch]:
util/*.c:
	Fix spelling and doubled-up words.

	Delete trailing whitespace.

	Convert tabs into spaces (where appropriate).
2015-12-02 18:46:14 +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
7654ec847e Convert (C->T;E) to (if C then T else E). 2015-09-18 09:37:29 +10:00
Zoltan Somogyi
04daa04751 Delete some unused imports. 2015-09-14 04:35:40 +10:00
Zoltan Somogyi
62ec97d443 Report imports shadowed by other imports.
If a module has two or more import_module or use_module declarations
for the same module, (typically, but not always, one being in its interface
and one in its implementation), generate an informational message about
each redundant declaration if --warn-unused-imports is enabled.

compiler/hlds_module.m:
    We used to record the set of imported/used modules, and the set of
    modules imported/used in the interface of the current module. However,
    these sets

    - did not record the distinction between imports and uses;
    - did not allow distinction between single and multiple imports/uses;
    - did not record the locations of the imports/uses.

    The first distinction was needed only by module_qual.m, which *did*
    pay attention to it; the other two were not needed at all.

    To generate messages for imports/uses shadowing other imports/uses,
    we need all three, so change the data structure storing such information
    for *direct* imports to one that records all three of the above kinds
    of information. (For imports made by read-in interface and optimization
    files, the old set of modules approach is fine, and this diff leaves
    the set of thus *indirectly* imported module names alone.)

compiler/unused_imports.m:
    Use the extra information now available to generate a
    severity_informational message about any import or use that is made
    redundant by an earlier, more general import or use.

    Fix two bugs in the code that generated warnings for just plain unused
    modules.

    (1) It did not consider that a use of the builtin type char justified
    an import of char.m, but without that import, the type is not visible.

    (2) It scanned cons_ids in goals in procedure bodies, but did not scan
    cons_ids that have been put into the const_struct_db. (I did not update
    the code here when I added the const_struct_db.)

    Also, add a (hopefully temporary) workaround for a bug in
    make_hlds_passes.m, which is noted below.

    However, there are at least three problems that prevent us from enabling
    --warn-unused-imports by default.

    (1) In some places, the import of a module is used only by clauses for
    a predicate that also has foreign procs. When compiled in a grade that
    selects one of those foreign_procs as the implementation of the predicate,
    the clauses are discarded *without* being added to the HLDS at all.
    This leads unused_imports.m to generate an uncalled-for warning in such
    cases. To fix this, we would need to preserve the Mercury clauses for
    *all* predicates, even those with foreign procs, and do all the semantic
    checks on them before throwing them away. (I tried to do this once, and
    failed, but the task should be easier after the item list change.)

    (2) We have two pieces of code to generate import warnings. The one in
    unused_imports.m operates on the HLDS after type and mode checking,
    while module_qual.m operates on the parse tree before the creation of
    the HLDS. The former is more powerful, since it knows e.g. what types and
    modes are used in the bodies of predicates, and hence can generate warnings
    about an import being unused *anywhere* in a module, as opposed to just
    unused in its interface.

    If --warn-unused-imports is enabled, we will get two separate set of
    reports about an interface import being unused in the interface,
    *unless* we get a type or mode error, in which case unused_imports.m
    won't be invoked. But in case we do get such errors, we don't want to
    throw away the warnings from module_qual.m. We could store them and
    throw them away only after we know we won't need them, or just get
    the two modules to generate identical error_specs for each warning,
    so that the sort_and_remove_dups of the error specs will do the
    throwing away for us for free, if we get that far.

    (3) The valid/bug100.m test case was added as a regression test for a bug
    that was fixed in module_qual.m. However the bug is still present in
    unused_imports.m.

compiler/make_hlds_passes.m:
    Give hlds_module.m the extra information it now needs for each item_avail.

    Add an XXX for a bug that cannot be fixed right now: the setting of
    the status of abstract instances to abstract_imported. (The "abstract"
    part is correct; the "imported" part may not be.)

compiler/intermod.m:
compiler/try_expand.m:
compiler/xml_documentation.m:
    Conform to the change in hlds_module.m.

compiler/module_qual.m:
    Update the documentation of the relationship of this module
    with unused_imports.m.

compiler/hlds_data.m:
    Document a problem with the status of instance definitions.

compiler/hlds_out_module.m:
    Update the code that prints out the module_info to conform to the change
    to hlds_module.m.

    Print status information about instances, which was needed to diagnose
    one of the bugs in unused_imports.m. Format the output for instances
    nicer.

compiler/prog_item.m:
    Add a convenience predicate.

compiler/prog_data.m:
    Remove a type synonym that makes things harder to understand, not easier.

compiler/modules.m:
    Delete an XXX that asks for the feature this diff implements.
    Add another XXX about how that feature could be improved.

compiler/Mercury.options.m:
    Add some more modules to the list of modules on which the compiler
    should be invoked with --no-warn-unused-imports.

compiler/*.m:
library/*.m:
mdbcomp/*.m:
browser/*.m:
deep_profiler/*.m:
mfilterjavac/*.m:
    Delete unneeded imports. Many of these shadow other imports, and some
    are just plain unneeded, as shown by --warn-unused-imports. In a few
    modules, there were a *lot* of unneeded imports, but most had just
    one or two.

    In a few cases, removing an import from a module, because it *itself*
    does not need it, required adding that same import to those of its
    submodules which *do* need it.

    In a few cases, conform to other changes above.

tests/invalid/Mercury.options:
    Test the generation of messages about import shadowing on the existing
    import_in_parent.m test case (although it was also tested very thoroughly
    when giving me the information needed for the deletion of all the
    unneeded imports above).

tests/*/*.{m,*exp}:
    Delete unneeded imports, and update any expected error messages
    to expect the now-smaller line numbers.
2015-08-25 00:38:49 +10:00