Commit Graph

268 Commits

Author SHA1 Message Date
Zoltan Somogyi
d76c7bf617 Break up inst_util.m and mode_util.m.
This step significantly improves module cohesion.

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

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

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

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

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

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

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

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

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

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

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

compiler/add_pragma_tabling.m:
compiler/arg_info.m:
compiler/bytecode_gen.m:
compiler/closure_analysis.m:
compiler/complexity.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/error_msg_inst.m:
compiler/fact_table.m:
compiler/float_regs.m:
compiler/follow_code.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_pred.m:
compiler/hlds_rtti.m:
compiler/inlining.m:
compiler/inst_match.m:
compiler/inst_user.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/interval.m:
compiler/introduce_exists_casts.m:
compiler/lambda.m:
compiler/lco.m:
compiler/liveness.m:
compiler/lookup_util.m:
compiler/loop_inv.m:
compiler/mark_tail_calls.m:
compiler/ml_args_util.m:
compiler/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_util.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/modecheck_call.m:
compiler/modecheck_coerce.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/oisu_check.m:
compiler/par_conj_gen.m:
compiler/pd_util.m:
compiler/post_typecheck.m:
compiler/pragma_c_gen.m:
compiler/proc_requests.m:
compiler/prog_rep.m:
compiler/push_goals_together.m:
compiler/rbmm.region_transformation.m:
compiler/saved_vars.m:
compiler/simplify_goal_switch.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/stratify.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.domain.m:
compiler/superhomogeneous.m:
compiler/table_gen.m:
compiler/term_constr_build.m:
compiler/term_pass2.m:
compiler/term_util.m:
compiler/tupling.m:
compiler/unify_gen_construct.m:
compiler/unify_gen_util.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
    Conform to the changes above by importing the required new modules,
    sometimes in addition to inst_util.m or mode_util.m, but more usually
    instead of them.
2021-12-16 01:31:35 +11:00
Zoltan Somogyi
1ce46c2797 Pair lambda arg vars with their modes.
compiler/hlds_goal.m:
    This enforces the invariant that the there is one mode par argument var.

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

compiler/assertion.m:
compiler/build_mode_constraints.m:
compiler/check_promise.m:
compiler/cse_detection.m:
compiler/dead_proc_elim.m:
compiler/delay_partial_inst.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
compiler/float_regs.m:
compiler/format_call.m:
compiler/goal_path.m:
compiler/goal_util.m:
compiler/hhf.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_util.m:
compiler/hlds_statistics.m:
compiler/implementation_defined_literals.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/lco.m:
compiler/loop_inv.m:
compiler/make_hlds_warn.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/mode_ordering.m:
compiler/mode_util.m:
compiler/modecheck_unify.m:
compiler/old_type_constraints.m:
compiler/polymorphism.m:
compiler/polymorphism_lambda.m:
compiler/pre_quantification.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/quantification.m:
compiler/simplify_goal_unify.m:
compiler/stratify.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/try_expand.m:
compiler/typecheck.m:
compiler/unused_args.m:
compiler/unused_imports.m:
    Conform to the change above.
2021-08-21 17:49:42 +10:00
Zoltan Somogyi
254cd500bf Add bespoke type for du types' details.
compiler/hlds_data.m:
    As above. The other kinds of types already had bespoke types
    for *their* details.

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

compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/dead_proc_elim.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/equiv_type_hlds.m:
compiler/foreign.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
compiler/mlds.m:
compiler/mode_util.m:
compiler/post_term_analysis.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_ite.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/unify_proc.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.
2021-07-01 08:26:04 +10:00
Zoltan Somogyi
a818e42cb9 Put bigger/slower-varying inputs before others.
compiler/inst_match.m:
compiler/inst_test.m:
    As above.

compiler/common.m:
compiler/constraint.m:
compiler/goal_mode.m:
compiler/hlds_pred.m:
compiler/inst_util.m:
compiler/instmap.m:
compiler/mode_comparison.m:
compiler/mode_errors.m:
compiler/mode_util.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/pd_info.m:
compiler/simplify_goal_disj.m:
compiler/unique_modes.m:
compiler/unused_args.m:
    Conform to the changes above.
2021-06-14 16:48:19 +10:00
Zoltan Somogyi
30005cc8d2 Try to propagate the usual types first. 2021-06-08 09:46:13 +10:00
Zoltan Somogyi
6229771305 Propagate type char into bound_insts.
compiler/mode_util.m:
    As above. This is needed to allow the compiler to check whether
    a char constant matches an inst that is specific to the char type.

tests/invalid/char_inst.{m,err_exp}:
    A new test case for the fixed functionality.

tests/invalid/Mmakefile:
    Enable the new test case.
2021-06-08 07:57:52 +10:00
Zoltan Somogyi
40725f170e Replace ten int cons_ids with one.
We currently have one function symbol in the cons_id type for each
of our ten types of integer constants: signed vs unsigned, and
word-sized, 8-bit, 16-bit, 32-bit and 64-bit. In most places in the compiler,
these are all treated the same, and it gets tedious to have to write
the same logic ten times. This diff therefore changes things so that
the distinction between int constants of these ten types is pushed
to one level lower than the cons_id type.

compiler/prog_data.m:
    Replace the ten cons_ids {int,uint}{,8,16,32,64}_const with just one,
    some_int_const, whose argument now has those function symbols.

    Add some utility functions on integer constants.

compiler/prog_out.m:
    Add a utility predicate for converting int constants to strings.

compiler/parse_tree_to_term.m:
    Add a utility predicate for converting int constants to terms.

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

    Fix an old bug, though this does not matter since this module is unused.

compiler/add_pred.m:
compiler/bytecode_gen.m:
compiler/const_prop.m:
compiler/coverage_profiling.m:
compiler/ctgc.selector.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_dependency_graph.m:
compiler/hlds_out_util.m:
compiler/implementation_defined_literals.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/make_goal.m:
compiler/mercury_to_mercury.m:
compiler/ml_global_data.m:
compiler/mode_util.m:
compiler/modecheck_coerce.m:
compiler/modecheck_goal.m:
compiler/module_qual.qualify_items.m:
compiler/parse_util.m:
compiler/polymorphism.m:
compiler/polymorphism_type_info.m:
compiler/prog_ctgc.m:
compiler/prog_rep.m:
compiler/prog_type.m:
compiler/prog_util.m:
compiler/rbmm.execution_path.m:
compiler/rbmm.region_transformation.m:
compiler/simplify_goal_call.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/superhomogeneous.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above. Use the new utility predicates
    to avoid code duplication.
2021-06-03 23:58:32 +10:00
Zoltan Somogyi
715121485c Don't import unneeded modules in the interface. 2021-05-29 12:55:02 +10:00
Zoltan Somogyi
bd594dded2 Impose logical order on mode_info.m and mode_util.m.
compiler/mode_info.m:
compiler/mode_util.m:
    Put the predicates in these modules into logical groups, and ensure
    that the orders of the declarations and definitions match.

    Delete the unused predicate mode_info_set_how_to_check from mode_info.m.

    Delete the unused predicates select_output_vars, select_output_things,
    and partition_args from mode_util.m.

    Rename the unify_modes_to_X predicates to unify_mode_to_X, since each
    of these predicates operates on only *one* unify_mode.

    Move three predicates that are needed only during mode checking,
    and not during later compuiler passes, to modecheck_util.m.

compiler/modecheck_util.m:
    Add the predicates moved from mode_util.m.

compiler/Mercury.options:
    Require the order of predicates' definitions to match the order of
    their declarations in mode_info.m and mode_util.m.

compiler/common.m:
compiler/loop_inv.m:
compiler/modecheck_goal.m:
    Conform to the changes in mode_util.m.
2021-03-22 02:26:58 +11:00
Zoltan Somogyi
25b89ea8c6 Put bigger inputs first.
compiler/hlds_pred.m:
    Put a module_info input before a proc_info input.

compiler/*.m:
    Conform to the above.
2020-11-30 17:34:42 +11:00
Zoltan Somogyi
833181f833 Reduce overheads in recompute_instmap_delta_1.
compiler/mode_util.m:
    Instead of testing the form of a goal three times (does it have
    subgoals, is it a rhs_lambda_goal unification, switch on goal_expr),
    test it just once (in the switch on goal_expr).

    Inline recompute_instmap_delta_2 into recompute_instmap_delta_1.

    The update_module_info predicate did not really help with readability,
    so delete it after inlining all the calls to it. This also avoids
    the overheads of higher order calls at the default optimization level.
2020-10-23 09:55:52 +11:00
Zoltan Somogyi
c5a65723c3 Replace {inst,mode}_id with {inst,mode}_ctor ...
.. since these two types play the same role for insts and modes respectively
as type_ctors do for types.

compiler/prog_data.m:
    As above.

compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/equiv_type.m:
compiler/hlds_defns.m:
compiler/hlds_inst_mode.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/inst_user.m:
compiler/intermod.m:
compiler/mode_util.m:
compiler/prog_mode.m:
compiler/recompilation.m:
compiler/recompilation.usage.m:
compiler/unused_imports.m:
    Conform to the above changes.
2020-03-15 11:45:04 +11:00
Zoltan Somogyi
36c2000516 Add the one_or_more and one_or_more_map modules to the library.
library/one_or_more.m:
    We used to have a type named one_or_more in the list module representing
    nonempty lists. It had literally just two predicates and two functions
    defined on it, three of which did conversions to and from lists, which
    limited their usefulness.

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

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

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

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

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

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

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

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

tests/hard_coded/Mmakefile:
    Enable the new test case.
2020-02-28 14:29:05 +11:00
Zoltan Somogyi
df9420c3e6 Flatten the unify_mode structure.
compiler/hlds_goal.m:
    Change the unify_mode structure from

        unify_modes_lhs_rhs(from_to_insts(LI, LF), from_to_insts(RI, RF))

    to

        unify_modes_li_lf_ri_rf(LI, LF, RI, RF)

    This requires fewer memory allocations (1 vs 3) and less memory
    (4 words vs 6), though the performance improvement is too small
    to measure.

    It should also require writing fewer function symbols in code.

compiler/instmap.m:
compiler/mode_util.m:
    For each utility predicate that works with from_to_insts, provide
    a version that works with the separate insts contained in it.
    Delete the from_to_insts version if no longer needed.

compiler/prog_mode.m:
    Delete utility predicates on from_to_insts that are not needed anymore.

compiler/accumulator.m:
compiler/add_pred.m:
compiler/bytecode_gen.m:
compiler/common.m:
compiler/const_prop.m:
compiler/deep_profiling.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/equiv_type_hlds.m:
compiler/erl_unify_gen.m:
compiler/float_regs.m:
compiler/format_call.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_mode.m:
compiler/interval.m:
compiler/lambda.m:
compiler/lco.m:
compiler/make_goal.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_util.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/polymorphism.m:
compiler/proc_requests.m:
compiler/prog_rep.m:
compiler/rbmm.region_transformation.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_scope.m:
compiler/simplify_goal_switch.m:
compiler/size_prof.m:
compiler/stm_expand.m:
compiler/term_util.m:
compiler/unify_gen_construct.m:
compiler/unify_gen_util.m:
compiler/unused_args.m:
    Conform to the changes above.
2019-10-27 02:53:46 +11:00
Zoltan Somogyi
17d684a11e Better arg orders in instmap.m.
compiler/instmap.m:
    Replace a non-state-var-friendly and a state-var-friendly pair
    of predicates with just one state-var-friendly predicate.

    Improve the arg order of another predicate as well.

    Improve documentation.

compiler/accumulator.m:
compiler/call_gen.m:
compiler/code_loc_dep.m:
compiler/constraint.m:
compiler/cse_detection.m:
compiler/delay_construct.m:
compiler/dep_par_conj.m:
compiler/erl_code_gen.m:
compiler/erl_code_util.m:
compiler/float_regs.m:
compiler/goal_mode.m:
compiler/goal_util.m:
compiler/hlds_pred.m:
compiler/introduce_parallelism.m:
compiler/lookup_util.m:
compiler/loop_inv.m:
compiler/mode_util.m:
compiler/modecheck_unify.m:
compiler/par_conj_gen.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/prog_rep.m:
compiler/stm_expand.m:
compiler/transform.m:
compiler/try_expand.m:
compiler/unneeded_code.m:
    Conform to the change above. Delete unneeded module qualifications.
2019-08-24 17:18:14 +10:00
Zoltan Somogyi
e9430b115a Prep for recording simple type representations in .int3 files.
compiler/decide_type_repn.m:
    New module for computing the set of type representation items
    to put into the interface files of a module. For now, it generates
    this information only for .int3 files.

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

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

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

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

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

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

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

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

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

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

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

    Conform to the changes above.

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

    Note a possible improvement.

    Conform to the changes above.

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

compiler/simplify_goal_ite.m:
    Add a comment.

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

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

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

NEWS:
    Announce the new predicates.

library/bimap.m:
library/map.m:
library/tree234.m:
    Expand a comment.
2019-05-27 11:45:10 +02:00
Zoltan Somogyi
acfe86aace Implement abstract insts and modes for use in .int3 files.
The syntax is

    :- abstract_inst((inst_name(instvar1, ..., instvarN))).
    :- abstract_mode((inst_name(instvar1, ..., instvarN))).

The rationale for that syntax is as follows.

First, I ruled out using the same scheme as for types, which would yield
the syntax

    :- inst (inst_name(V_1, ..., V_N)).
    :- mode (inst_name(V_1, ..., V_N)).

It would work for insts, but not for modes, because ":- mode p." would be
ambiguous: one couldn't tell whether it was defining a *mode* named p
of arity 0, or it was declaring a mode for a *predicate* named p
of arity 0. And I thought it made more sense for the syntax of insts
to follow the syntax of modes than to follow the syntax of types.
Hence the addition of the "abstract_" prefix. Since I intend to put
abstract insts and modes automatically into .int3 files, but NOT to add them
to the user visible part of the language, this should be fine.

Second, I wanted to avoid changing the set of operators in the language,
which is why there is no space after "abstract_inst" and "abstract_mode".

Third, there is a redundant set of parentheses around the argument
of those function symbols, just as there is around the inst name in
the non-abstract inst and mode definitions in .int3 file right now,
for the same reason: to guard against case that the inst or mode name
*is* an operator.

Fourth, the reason for listing the argument inst vars, instead of adding
a "/arity" suffix to the name, is to reuse the existing machinery
for reading in and writing out the heads of inst and mode definitions.

NOTE: the compiler still puts inst and mode definitions into .int3 files
in their original, non-abstract state. Changing that is for a later diff.

compiler/prog_item.m:
    Change the representation of inst and mode definitions to allow
    the inst or mode being defined to be abstract. These abstract versions
    do not make it into the HLDS.

compiler/prog_data.m:
compiler/hlds_inst_mode.m:
    We used to have a representation for abstract inst definitions inside
    both the parse tree and the HLDS, but any attempt to add the parse tree
    version to the HLDS would yield a compiler abort.

    Delete these representations, since they never worked, and are now not
    needed.

compiler/parse_inst_mode_defn.m:
compiler/parse_item.m:
    Parse the new syntax for abstract inst and mode definitions.

    Stop parsing the old syntax, which we have never used.

compiler/parse_tree_out.m:

compiler/add_mode.m:
    Add only nonabstract insts and modes to the HLDS. The abstract versions
    are used only during module qualification, which is done on the parse tree.

compiler/add_mutable_aux_preds.m:
compiler/equiv_type.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/inst_user.m:
compiler/intermod.m:
compiler/mode_util.m:
compiler/module_qual.qualify_items.m:
compiler/recompilation.usage.m:
compiler/unused_imports.m:
    Conform to the changes above.
2019-03-20 17:04:24 +11:00
Zoltan Somogyi
d247ae82a3 Rename a function symbol to avoid an ambiguity.
compiler/hlds_inst_mode.m:
    As above.

compiler/add_mode.m:
compiler/hlds_out_module.m:
compiler/intermod.m:
compiler/mode_util.m:
compiler/recompilation.usage.m:
compiler/unused_imports.m:
    Conform to the change above.

compiler/add_pred.m:
compiler/make_hlds_passes.m:
    Improve comments.

compiler/add_solver.m:
    Improve programming style.
2019-01-21 16:24:35 +11:00
Zoltan Somogyi
1c13290492 Store its ordinal number with each functor.
This will be needed by an upcoming change.

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

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

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

    Add some predicates needed by that upcoming change.

compiler/add_special_pred.m:
compiler/add_type.m:
compiler/check_typeclass.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/export.m:
compiler/hhf.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/ml_type_gen.m:
compiler/mode_util.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/prog_type.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/special_pred.m:
compiler/term_constr_build.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the changes above.
2018-06-08 02:58:00 +02:00
Zoltan Somogyi
15aa457e12 Delete $module arg from calls to unexpected. 2018-04-07 18:25:43 +10:00
Zoltan Somogyi
28e9a29fc2 Carve hlds_inst_mode.m out of hlds_data.m.
compiler/hlds_class.m:
    New module containing the parts of hlds_data.m that deal with
    insts and modes.

compiler/hlds_data.m:
    Delete the moved code.

compiler/hlds.m:
    Include the new module.

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

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

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

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

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

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

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

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

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

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

    Fix a bad dump stage name.

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

    Make a sub-switch explicit.

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

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

    Delete some forwarding predicates that are no longer needed.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Delete the reserve_tag pragma.

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

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

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

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

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

    Provide some utility predicates.

    Optimize some existing predicates.

    Rename some types to better reflect their meaning.

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

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

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

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

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

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

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

    Move the module from the make_hlds to the hlds package.

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

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

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

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

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

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

    Delete a type moved to type_util.m.

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

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

    Give some predicates more meaningful names.

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

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

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

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

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

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

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

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

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

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

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

    Give some predicates and function symbols more meaningful names.

    Note some problems with the existing code.

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

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

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

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

tests/valid/Mmake.valid.common:
tests/valid/Mmakefile:
    Disable any reserve_tag test cases, as they are not applicable anymore.
2018-01-31 17:54:40 +11:00
Julien Fischer
f519e26173 Add builtin 64-bit integer types -- Part 1.
Add the new builtin types: int64 and uint64.

Support for these new types will need to be bootstrapped over several changes.
This is the first such change and does the following:

- Extends the compiler to recognise 'int64' and 'uint64' as builtin types.
- Extends the set of builtin arithmetic, bitwise and relational operators
  to cover the new types.
- Adds the new internal option '--unboxed-int64s' to the compiler; this will be
  used to control whether 64-bit integer types are boxed or not.
- Extends all of the code generators to handle the new types.
- Extends the runtimes to support the new types.
- Adds new modules to the standard library intend to contain basic operations
  on the new types.  (These are currently empty and not documented.)

There are bunch of limitations marks with "XXX INT64"; these will be lifted in
part 2 of this change.  Also, 64-bit integer types are currently always boxed,
again this limitation will be lifted in later changes.

compiler/options.m:
    Add the new option --unboxed-int64s.

compiler/prog_type.m:
compiler/prog_data.m:
compiler/builtin_lib_types.m:
     Recognise int64 and uint64 as builtin types.

compiler/builtin_ops.m:
     Add builtin operations for the new types.

compiler/hlds_data.m:
     Add new tag types for the new types.

compiler/ctgc.selector.m:
compiler/dead_proc_elim.m:
compiler/export.m:
compiler/foreign.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_dependency_graph.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/implementation_defined_literals.m:
compiler/inst_check.m:
compiler/mercury_to_mercury.m:
compiler/mode_util.m:
compiler/module_qual.qualify_items.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_name.m:
compiler/polymorphism.m:
compiler/prog_out.m:
compiler/prog_util.m:
compiler/rbmm.execution_path.m:
compiler/rtti.m:
compiler/table_gen.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the above changes to the parse tree and HLDS.

compiler/c_util.m:
    Support writing out constants of the new types.

compiler/llds.m:
    Add a representation for constants of the new types to the LLDS.

compiler/stack_layout.m:
    Add a new field to the stack layout params that records whether
    64-bit integers are boxed or not.

compiler/call_gen.:m
compiler/code_info.m:
compiler/disj_gen.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/llds_out_data.m:
compiler/llds_out_instr.m:
compiler/lookup_switch.m:
compiler/mercury_compile_llds_back_end.m:
compiler/prog_rep.m:
compiler/prog_rep_tables.m:
compiler/var_locn.m b/compiler/var_locn.m:
    Support the new types in the LLDS code generator.

compiler/mlds.m:
    Support constants of the new types in the MLDS.

compiler/ml_call_gen.m:
compiler/ml_code_util.m:
compiler/ml_global_data.m:
compiler/ml_rename_classes.m:
compiler/ml_top_gen.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 above changes to the MLDS.

compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
    Generate the appropriate target code for constants of the new types
    and operations involving them.

compiler/bytecode.m:
compiler/bytecode_gen.m:
    Handle the new types in the bytecode generator; we just abort if we
    encounter them for now.

compiler/elds.m:
compiler/elds_to_erlang.m:
compiler/erl_call_gen.m:
compiler/erl_code_util.m:
compiler/erl_unify_gen.m:
    Handle the new types in the Erlang code generator.

library/private_builtin.m:
    Add placeholders for the builtin unify and compare operations for
    the new types.  Since the bootstrapping compiler will not recognise
    the new types we give them polymorphic arguments.  These can be
    replaced after this change has bootstrapped.

    Update the Java list of TypeCtorRep constants here.

library/int64.m:
library/uint64.m:
    New modules that will eventually contain builtin operations on the new
    types.

library/library.m:
library/MODULES_UNDOC:
    Do not include the above modules in the library documentation for now.

library/construct.m:
library/erlang_rtti_implementation.m:
library/rtti_implementation.m:
library/table_statistics.m:
deep_profiler/program_representation_utils.m:
mdbcomp/program_representation.m:
    Handle the new types.

configure.ac:
runtime/mercury_conf.h.in:
    Define the macro MR_BOXED_INT64S.  For now it is always defined, support for
    unboxed 64-bit integers will be enabled in a later change.

runtime/mercury_dotnet.cs.in:
java/runtime/TypeCtorRep.java:
runtime/mercury_type_info.h:
    Update the list of type_ctor reps.

runtime/mercury.h:
runtime/mercury_int.[ch]:
    Add macros for int64 / uint64 -> MR_Word conversion, boxing and
    unboxing.

    Add functions for hashing 64-bit integer types suitable for use
    with the tabling mechanism.

runtime/mercury_tabling.[ch]:
    Add additional HashTableSlot structs for 64-bit integer types.

    Omit the '%' character from the conversion specifiers we pass via
    the 'key_format' argument to the macros that generate the table lookup
    function.  This is so we can use the C99 exact size integer conversion
    specifiers (e.g. PRIu64 etc.) directly here.

runtime/mercury_hash_lookup_or_add_body.h:
    Add the '%' character that was omitted above to the call to debug_key_msg.

runtime/mercury_memory.h:
     Add new builtin allocation sites for boxed 64-bit integer types.

runtime/mercury_builtin_types.[ch]:
runtime/mercury_builitn_types_proc_layouts.h:
runtime/mercury_construct.c:
runtime/mercury_deconstruct.c:
runtime/mercury_deep_copy_body.h:
runtime/mercury_ml_expand_body.h:
runtime/mercury_table_type_body.h:
runtime/mercury_tabling_macros.h:
runtime/mercury_tabling_preds.h:
runtime/mercury_term_size.c:
runtime/mercury_unify_compare_body.h:
    Add the new builtin types and handle them throughout the runtime.

runtime/Mmakefile:
    Add mercury_int.c to the list of .c files.

doc/reference_manual.texi:
     Add the new types to the list of reserved type names.

     Add the mapping from the new types to their target language types.
     These are commented out for now.
2018-01-12 09:29:24 -05:00
Julien Fischer
8a240ba3f0 Add builtin 8, 16 and 32 bit integer types -- Part 1.
Add the new builtin types: int8, uint8, int16, uint16, int32 and uint32.
Support for these new types will need to be bootstrapped over several changes.
This is the first such change and does the following:

- Extends the compiler to recognise 'int8', 'uint8', 'int16', 'uint16', 'int32'
  and 'uint32' as builtin types.
- Extends the set of builtin arithmetic, bitwise and relational operators to
  cover the new types.
- Extends all of the code generators to handle new types.  There currently lots
  of limitations and placeholders marked by 'XXX FIXED SIZE INT'.  These will
  be lifted in later changes.
- Extends the runtimes to support the new types.
- Adds new modules to the standard library intended to hold the basic
  operations on the new types.  (These are currently empty and not documented.)

This change does not introduce the two 64-bit types, 'int64' and 'uint64'.
Their implementation is more complicated and is best left to a separate change.

compiler/prog_type.m:
compiler/prog_data.m:
compiler/builtin_lib_types.m:
    Recognise int8, uint8, int16, uint16, int32 and uint32 as builtin types.

    Add new type, int_type/0,that enumerates all the possible integer types.

    Extend the cons_id/0 type to cover the new types.

compiler/builtin_ops.m:
    Parameterize the integer operations in the unary_op/0 and binary_op/0
    types by the new int_type/0 type.

    Add builtin operations for all the new types.

compiler/hlds_data.m:
    Add new tag types for the new types.

compiler/hlds_pred.m:
    Parameterize integers in the table_trie_step/0 type.

compiler/ctgc.selector.m:
compiler/dead_proc_elim.m:
compiler/export.m:
compiler/foreign.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_dependency_graph.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/implementation_defined_literals.m:
compiler/inst_check.m:
compiler/mercury_to_mercury.m:
compiler/mode_util.m:
compiler/module_qual.qualify_items.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/parse_tree_out_info.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_name.m:
compiler/polymorphism.m:
compiler/prog_out.m:
compiler/prog_rep.m:
compiler/prog_rep_tables.m:
compiler/prog_util.m:
compiler/rbmm.exection_path.m:
compiler/rtti.m:
compiler/rtti_to_mlds.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/type_constraints.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the above changes to the parse tree and HLDS.

compiler/c_util.m:
    Support generating the builtin operations for the new types.

doc/reference_manual.texi:
    Add the new types to the list of reserved type names.

    Add the mapping from the new types to their target language types.
    These are commented out for now.

compiler/llds.m:
    Replace the lt_integer/0 and lt_unsigned functors of the llds_type/0,
    with a single lt_int/1 functor that is parameterized by the int_type/0
    type.

    Add a representations for constants of the new types to the LLDS.

compiler/call_gen.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/llds_out_data.m:
compiler/llds_out_global.m:
compiler/llds_out_instr.m:
compiler/lookup_switch.m:
compiler/middle_rec.m:
compiler/peephole.m:
compiler/pragma_c_gen.m:
compiler/stack_layout.m:
compiler/string_switch.m:
compiler/switch_gen.m:
compiler/tag_switch.m:
compiler/trace_gen.m:
compiler/transform_llds.m:
    Support the new types in the LLDS code generator.

compiler/mlds.m:
    Support constants of the new types in the MLDS.

compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_code_util.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_global_data.m:
compiler/ml_lookup_switch.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_target_util.m:
    Conform to the above changes to the MLDS.

compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
    Generate the appropriate target code for constants of the new
    types and operations involving them.

compiler/bytecode.m:
compiler/bytecode_gen.m:
    Handle the new types in the bytecode generator; we just abort if we
    encounter them for now.

compiler/elds.m:
compiler/elds_to_erlang.m:
compiler/erl_call_gen.m:
compiler/erl_code_util.m:
compiler/erl_rtti.m:
compiler/erl_unify_gen.m:
    Handle the new types in the Erlang code generator.

library/private_builtin.m:
    Add placeholders for the builtin unify and compare operations for
    the new types.  Since the bootstrapping compiler will not recognise
    the new types we give the polymorphic arguments.  These can be
    replaced after this change has bootstrapped.

    Update the Java list of TypeCtorRep constants.

library/int8.m:
library/int16.m:
library/int32.m:
library/uint8.m:
library/uint16.m:
library/uint32.m:
    New modules that will eventually contain builtin operations
    on the new types.

library/library.m:
library/MODULES_UNDOC:
    Do not include the above modules in the library documentation
    for now.

library/construct.m:
library/erlang_rtti_implementation.m:
library/rtti_implementation.m:
deep_profiler/program_representation_utils.m:
mdbcomp/program_representation.m:
    Handle the new types.

runtime/mercury_dotnet.cs.in:
java/runtime/TypeCtorRep.java:
runtime/mercury_type_info.h:
    Update the list of TypeCtorReps.

configure.ac:
runtime/mercury_conf.h.in:
    Check for the header stdint.h.

runtime/mercury_std.h:
    Include stdint.h; abort if that header is no present.

runtime/mercury_builtin_types.[ch]:
runtime/mercury_builtin_types_proc_layouts.h:
runtime/mercury_construct.c:
runtime/mercury_deconstruct.c:
runtime/mercury_deep_copy_body.h:
runtime/mercury_ml_expand_body.h
runtime/mercury_table_type_body.h:
runtime/mercury_tabling_macros.h:
runtime/mercury_tabling_preds.h:
runtime/mercury_term_size.c:
runtime/mercury_unify_compare_body.h:
    Add the new builtin types and handle them throughout the runtime.
2017-07-18 01:31:01 +10:00
Julien Fischer
092e175f45 Add a builtin unsigned word sized integer type -- Part 1.
Add a new builtin type: uint, which is an unsigned word sized integer type.
Support for this new type will need be bootstrapped over several changes.
This is the first such change and does the following:

- Extends the compiler to recognize 'uint' as a builtin type.
- Extends the set of builtin operations to include relational and (some)
  arithmetic operations on uints.
- Extends all of the code generators to handle the above.  There are some
  limitations currently marked by 'XXX UINT'.  These will be lifted once
  the compiler recognised uint and additional library support becomes
  available.
- Extends the runtime to support uints.

compiler/prog_type.m:
compiler/prog_data.m:
compiler/builtin_lib_types.m:
    Recognize uint as a builtin type.

    Add a new alternative to the cons_id/0 type corresponding to the uint type
    -- for bootstrapping purposes its argument is currently an int.

compiler/builtin_ops.m:
    Add builtin relational and arithmetic operations on uints.  Note that the
    existing 'unsigned_le' operation is actually intended for use with signed
    values.  Rather than attempt to modify its meaning, I have just added new
    operations specific to the uint type.

compiler/hlds_data.m:
    Add a new tag type for uints.

compiler/type_ctor_info.m:
    Recognise uint as a builtin.

    Bump the RTTI version number here.

compiler/ctgc.selector.m:
compiler/dead_proc_elim.m:
compiler/dependency_graph.m:
compiler/export.m:
compiler/foreign.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/hlds_pred.m:
compiler/implementation_defined_literals.m:
compiler/inst_check.m:
compiler/mercury_to_mercury.m:
compiler/mode_util.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_name.m:
compiler/polymorphism.m:
compiler/prog_out.m:
compiler/prog_rep.m:
compiler/prog_rep_tables.m:
compiler/prog_util.m:
compiler/rbmm.execution_path.m:
compiler/rtti.m:
compiler/special_pred.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/type_constraints.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the above changes to the parse tree and HLDS.

compiler/c_util.m:
    Support generating builtin operations for uints.

compiler/llds.m:
    Add a representation for uint constants to the LLDS.

    Map uints onto MR_Unsigned.

compiler/call_gen.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/llds_out_data.m:
compiler/llds_out_instr.m:
compiler/opt_debug.m:
compiler/opt_util.m:
    Support uints in the LLDS code generator.

compiler/mlds.m:
     Support uint constants in the MLDS.

compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_global_data.m:
compiler/ml_simplify_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/rtti_to_mlds.m:
    Conform to the above change to the MLDS.

compiler/mlds_to_c.m:
compiler/mlds_to_java.m:
compiler/mlds_to_cs.m:
     Generate the appropriate target code for uint constants and uint
     relational operations.

compiler/bytecode.m:
compiler/bytecode_gen.m:
     Handle uints in the bytecode generator: we just abort if we
     encounter them for now.

compiler/elds.m:
compiler/elds_to_erlang.m:
compiler/erl_call_gen.m:
compiler/erl_code_util.m:
compiler/erl_rtti.m:
compiler/erl_unify_gen.m:
    Handle uints in the Erlang code generator.

library/private_builtin.m:
    Add placeholders for builtin_{unify,compare}_uint.  Since the
    bootstrapping compiler will not recognize uint as a type, we
    give them polymorphic arguments.  These can be replaced after
    this change has bootstrapped.

    Update the Java list of TypeCtorRep constants, which for some
    reason is defined here.

library/uint.m:
    New module that will eventually contain operations on uints.

library/MODULES_DOCS:
library/library.m:
     Add the uint module.

library/construct.m:
library/erlang_rtti_implementation.m:
library/rtti_implementation.m:
mdbcomp/program_representation.m:
     Handle uints.

deep_profiler/program_representation_utils.m:
     Conform to the above change.

runtime/mercury_dotnet.cs.in:
     Update the list of TypeCtorReps for C#

java/runtime/TypeCtorRep.java:
     Update this, although the actual TypeCtorRep constants
     are defined the library.

runtime/mercury_type_info.h:
    Bump the RTTI version number.

    Add an alternative for uints to the tyepctor rep enum.

runtime/mercury_builtin_types.{h,c}:
runtime/mercury_builtin_types_proc_layouts.h:
runtime/mercury_deconstruct.c:
runtime/mercury_deep_copy_body.h:
runtime/mercury_table_type_body.h:
runtime/mercury_tabling.h:
runtime/mercury_tabling_macros.h:
runtime/mercury_unify_compare_body.h:
    Add uint as a builtin type and handle it throughout the runtime.

runtime/mercury_grade.h:
    Bump the binary compatibility version.

runtime/mercury_term_size.c:
runtime/mercury_ml_expand_body.h:
    Handle uint and fix probable bugs with the handling of ints on
    64-bit Windows.
2016-10-24 12:55:35 +11:00
Zoltan Somogyi
253378fe21 Improve error messages for malformed lambda expressions.
Do this by insisting that terms whose top level(s) look like lambda
expressions should be parsed as lambda expressions, and return error
messages if that parsing attempt fails.

I did this is in several commits to modules in the parse_tree.m package
that translated terms to the parse tree, i.e. to goal_exprs. This diff
does the same thing for lambda expressions.

NEWS:
    Document this change, as well as other, similar changes in the recent past.

compiler/superhomogeneous.m:
    When translating a var-functor unification, which has the form
    X = f(Y1, ..., Yn), to the HLDS, we parse the right hand side term,
    looking for Mercury constructs such as lambda expressions and
    field accesses. We used to do this by checking if the RHS was
    a well-formed version of the construct we were looking for,
    and falling back to parsing it as an ordinary term. That meant that
    terms that the programmer *intended* to be lambda expressions,
    but which contained a syntax error, were not diagnosed during the
    construction of the HLDS, but during a later pass. Virtually always,
    that later pass was typechecking. Since in such cases, the typechecker
    is given terms whose function symbols were *intended* to be the "keywords"
    of Mercury constructs (to the extent that Mercury *has* keywords),
    not the names of data constructors or predicates, those error messages
    were almost always confusing, and at best an *indirect* indication
    of the actual problem with the code.

    This diff changes things so that when the top function symbol on
    the RHS of a unification is a Mercury "keyword" used only in lambda
    expressions, we commit to parsing it as such. If the parsing fails,
    we now generate an error message that describes the problem *directly*.

    To make the task of generating good error messages easier, and to make it
    possible to generate *consistent* error messages for the same error
    in different contexts, unify the four separate pieces of code that
    *used* to parse different kinds of lambda expressions. These four
    pieces of code used to parse

    - predicates defined using DCG notation;
    - predicates defined using non-DCG notation;
    - functions that used the default function mode and determinism; and
    - functions that did not use the default function mode and determinism.

    The unified code allows a function lambda expression to omit the
    default argument modes *independently* of whether it omits the default
    determinism, and vice versa. The old code did not do that: if you didn't
    explicitly specify one, you couldn't explicitly specify the other either,
    probably because it would have required two more pieces of code.

    The language reference manual says, in section 8.1:

        As with ‘:- func’ declarations, if the modes and determinism
        of the function are omitted in a higher-order function term, then
        the modes default to ‘in’ for the arguments, ‘out’ for
        the function result, and the determinism defaults to ‘det’.

    This text is vague on whether the modes and determinism are *allowed*
    to be omitted independently. The old behavior was a strict reading
    of this text. The new behavior follows the most liberal possible reading,
    and thus allows all the behaviors that the old one did, and more.

    Integrate the test for big integers that are too big to be represented
    with the conversion of all ordinary functors into cons_ids, both to
    simplify the code, and to speed it up. In the process, improve the
    error message for too-big integers.

compiler/add_clause.m:
    Don't try to generate warnings for singleton variables in a clause
    if the clause had syntax errors. Part of the parser's recovery from
    those syntax errors (e.g. when they occur in lambda expressions' clause
    heads) may have included not translating parts of the original term
    into the parsed clause body, so any such warnings could be misleading.

    Such warnings could also be correct, but I expect most programmers
    would prefer to miss some correct singleton warnings while the
    syntax errors are present in their code, and get them only once
    they have fixed those syntax errors, than to have to wade through
    misleading errors messages for the initial syntax error to get to
    the real ones.

compiler/field_access.m:
    Clarify the text of an error message.

    Delete a predicate that superhomogeneous.m no longer needs.

compiler/mercury_compile_front_end.m:
    Don't proceed past typechecking if the parser found syntax errors,
    since any errors we find later, e.g. as part of mode checking,
    are quite likely to be avalanche errors caused by those syntax errors.

    The reason why this wasn't a problem in the past is that when
    the program contained malformed uses of builtin constructs such as
    lambda expressions and field accesses, the parser used to simply
    transform the terms containing the malformed constructs into the arguments
    of call goals and unifications, and it was the typechecker that discovered
    that these function symbols did not match any declared type.
    The "type errors" generated for such problems told the compiler
    not to run later compiler passes to prevent avalanche errors.

    We now report syntax errors earlier, during the construction of the HLDS,
    and it is entirely possible that the parser's recovery from those errors
    leaves *no* type errors to be reported. This is why we need to make
    the presence of syntax errors in a predicate block the invocation
    of later passes.

compiler/typecheck.m:
    Return whether the predicates we typechecked had syntax errors,
    to make the change in mercury_compile_front_end.m possible.

compiler/state_var.m:
    If a lambda expression has two or more arguments of the form !X,
    we now print an error message for each, with each message naming the bad
    state variable and giving the context of the argument. We used to
    print only a single message saying that *some* argument misused
    state variables this way. Similarly, we now print the correct context
    for !X appearing as a function result, whether in a lambda expression
    or at the top level of a clause.

    The actual printing of those error messages takes place elsewhere,
    but change the utility predicates exported by state_var.m to make
    the change possible.

    Change the error message we generate for !X appearing as a function
    result, to avoid suggesting a possible repair that is virtually never
    the right repair.

compiler/mode_util.m:
    Delete a predicate that was used only by superhomogeneous.m; an updated
    version of that predicate is now in superhomogeneous.m itself.

compiler/module_qual.m:
compiler/module_qual.qualify_items.m:
    Instead of exporting predicates to module qualify the whole list of
    argument modes of a lambda expression, export predicates that module
    qualify only one such mode, since that is what superhomogeneous.m
    now wants.

compiler/hlds_clauses.m:
    Add access predicates for fields of the clauses_info type that previously
    did not have them, including the one that records the presence of syntax
    errors.

    Put related fields of the clauses_info together.

    Group both the declarations and the definitions of the access predicates
    together, and put them in the same order as the fields themselves.

compiler/add_class.m:
compiler/add_pred.m:
compiler/add_pragma_type_spec.m:
compiler/higher_order.m:
compiler/hlds_pred.m:
compiler/unify_proc.m:
    Conform to the changes above.

tests/invalid/lambda_syntax_error.err_exp:
    Print one error message for each of the four malformed lambda expressions
    in this test case, instead of the 13 avalanche messages we used to get
    from the typechecker, which tried to interpret the malformed lambda
    expression heads as calls, unifications etc.

    The motivation for this diff was a set of similar set of avalanche error
    messages for a real-life syntax error in a lambda expression in a change
    I worked on a while ago.

tests/benchmarks/deriv.{m,exp}:
    This test case used to use "^" as a data constructor (to represent
    raising X to the Nth power). Since the parser now insists on treating it
    as a field access operator, replace "^" with "power". (This test has
    the excuse of predating the addition of field access syntax to Mercury
    by several years.)

tests/dppd/grammar_impl.m:
    This test case used to define a type which contained "is" as a data
    constructor. After this diff, this is no longer allowed (as part of
    "is detism", it looks to the parser like the top constructor in a
    lambda expression head, and therefore as the top constructor of
    the lambda expression as a whole if it has no body), so add the type
    name as a prefix to this data constructor. To future-proof the test case,
    do the same with the several other data constructors that also duplicate
    the names of Mercury keywords.

tests/hard_coded/pprint_test2.{m,exp}:
tests/hard_coded/write.{m,exp}:
tests/hard_coded/write_binary.{m,exp}:
    These test cases used to define a type which contained ":-" as a data
    constructor. After this diff, this is no longer allowed, so replace them
    with "?-". (The tests check how io.m formats terms whose data constructor
    is an operator, so the replacement needs to be an operator, and Mercury
    syntax does not use "?-"; library/ops.m lists it as an operator only
    because it is an operator in Prolog.)

    Update write_binary.m to conform to our current style guide, and to avoid
    using the recently-deprecated io.make_temp.

tests/invalid/invalid_int.err_exp:
    Expect the updated text of the error message for a too-big
    integer constant.

tests/invalid/record_syntax_error.err_exp:
    Expect the updated text of the error message for a malformed field name.

tests/invalid/state_vars_test3.err_exp:
    Expect the updated text of the error message for a !X appearing
    as the result of a lambda function.

tests/invalid/state_vars_test4.err_exp:
    Expect the error message for a !X lambda argument, but (since we now
    stop after typechecking in the presence of such syntax errors),
    don't expect the avalanche error messages we used to print from the
    mode checker.
2016-05-20 05:47:36 +10:00
Zoltan Somogyi
cfcfde1db7 Simplify the representation of modes of unifications.
Unifications (x = y) have long had two descriptions of their modes.
One is the unify_mode, which used to look like this:
    (initx -> finalx) - (inity -> finaly)
and other is the uni_mode, which used to look like this:
    (initx - inity) -> (finalx - finaly)
Each unification had one unify_mode, and each unification that includes
a function symbol had one uni_mode per argument of that function symbol.

The two forms of mode information looked similar enough to be easily
confusable, but were subtly different. As it turns out, there was no
particular reason for the difference, so this diff eliminates the
uni_mode type, and the difference along with it.

What rationale there was for the uni_mode type was that the two modes
it represented (one for each side of the unification) both had their
initial and final insts directly available. This is not true for modes
in general: a value of the mer_mode type could have the form
"InitInst -> FinalInst" (which this diff renames "from_to_mode(InitInst,
FinalInst)", but could also be a "user_defined_inst(...)", which required
a table lookup to turn it into an initial/final pair of insts. This matters,
because almost all code that processes the modes of unifications
works with the initial and final insts.

This diff therefore creates a new type, from_to_insts, which represents
mode information only in the form of terms such as "from_to_insts(InitInst,
FinalInst)", and makes a unify_mode take two values of this type, not mer_mode,
as arguments.

As discussed on m-rev, this diff also renames the old, deceptively named
"arg_mode" type: its new name is "top_functor_mode".

compiler/prog_data.m:
compiler/hlds_goal.m:
    As mentioned above, avoid using "->" as a function symbol, and replace
    both -> and - with bespoke function symbols.

compiler/mode_util.m:
    Add some utility predicates and functions on the new types, and
    delete the old utility routines that operated on uni_modes.

    Code that uses the new functions and predicates should have a higher level
    of abstraction than the code that used to do the same job "manually".

compiler/*.m:
    Conform to the changes above, using the new utility predicates and
    functions where relevant. In several cases, this required fixing
    confusion of the kind described at the top. In all but one case,
    the confusion affected only variable names, but in one case,
    deconstruct_functor in make_goal.m, it caused a bug. The bug has
    had no effect up till now because deconstruct_functor is called
    only from three places: try_expand.m, stm_expand.m, and untupling.m.
    The incorrect mode (which was the nonsensical ground -> free)
    generated by the code of try_expand.m itself was discarded and
    overwritten when try_expand.m invoked the modechecker. (I don't
    know whether this bugfix makes that invocation redundant or not.)
    The other two modules, stm_expand.m and untupling.m, may do something
    similar, but in any case, they don't yet work for other reasons.
    (A bootcheck with --untupling causes a compiler abort when compiling
    deep_profiler/query.m in stage 2 both without and with this fix.)

    Delete no-longer-needed imports of the pair module (and of some other
    modules).

    Put the arguments of some predicates into a more logical order.

    In bytecode_gen.m, replace clauses with disjunctions, and delete the
    arguments that this step has revealed to be unused.
2016-05-19 10:43:24 +10:00
Zoltan Somogyi
701ed0de9a Delete unused predicates. 2015-12-12 16:03:50 +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
Mark Brown
db464ca661 Consistently refer to "default" function modes instead of "standard". 2015-11-16 21:14:17 +11:00
Mark Brown
b2ae55c29c Change 'none' to 'none_or_default_func' in ho_inst_info.
This value of ho_inst_info is used for first-order values as well as
for functions that have the default inst, and the new name better
reflects that.

Places using this value have been checked for correctness. Issues that
need to be looked at have been marked with XXX, although have not been
addressed in this change.

compiler/prog_data.m:
	Update the type.

compiler/inst_match.m:
	Add XXX comments. This module needs to check for non-default
	function insts in a bunch of places.

compiler/inst_util.m:
	Add XXX comments. We lose information about non-default function
	insts when merging bound and any. The information needs to be
	either preserved or disallowed entirely.

compiler/float_regs.m:
	Add XXX comments. This module may miss cases involving default
	function insts.

compiler/modecheck_unify.m:
	Add XXX comment. We should exclude pred and non-default func
	lambda non-locals from becoming locked, an addition to default
	functions.

compiler/*.m:
	No special handling is required for other modules.
2015-11-16 21:13:04 +11:00
Mark Brown
7f5a08eb37 Split parts of inst_match.m into a new module, inst_test.m
Most modules that imported inst_match did so in order to use
predicates such as inst_is_ground to test properties of insts.
These predicates are split into a new module, leaving the more
complex parts of inst_match to be imported in fewer places.
This makes it easier to change inst_match (for example, to
address mantis bug 264) without unintentional changes to
the rest of the compiler.

compiler/inst_test.m:
    New module containing code from inst_match.m.

compiler/check_hlds.m:
    Include the new module.

compiler/inst_match.m:
    Move code to the new module.

compiler/inst_util.m:
    Move inst_expand and inst_expand_and_remove_constrained_inst_vars
    here rather than the new module, since they make more sense here.

compiler/build_mode_constraints.m:
compiler/cse_detection.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_report.m:
compiler/fact_table.m:
compiler/float_regs.m:
compiler/goal_util.m:
compiler/interval.m:
compiler/loop_inv.m:
compiler/modecheck_goal.m:
compiler/pd_util.m:
compiler/prog_rep.m:
compiler/simplify_goal_call.m:
compiler/size_prof.m:
compiler/stm_expand.m:
compiler/structure_sharing.domain.m:
compiler/switch_detection.m:
compiler/term_util.m:
compiler/trace_gen.m:
compiler/unify_proc.m:
compiler/unneeded_code.m:
    Only import inst_test.

compiler/common.m:
compiler/instmap.m:
compiler/mode_util.m:
compiler/modecheck_call.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/simplify_goal_disj.m:
    Import inst_test in addition to inst_match.

compiler/lco.m:
compiler/simplify_goal_switch.m:
    Import inst_test and inst_util, but not inst_match.
2015-11-06 20:52:25 +11:00
Zoltan Somogyi
87985abd95 Convert (C->T;E) to (if C then T else E). 2015-10-11 14:48:11 +11: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
Zoltan Somogyi
04dec8c205 Carve vartypes.m, prog_detism.m and prog_rename.m out of prog_data.m.
Besides defining most of the types representing the smaller parts of
parse trees (parts smaller than items), prog_data.m also has many utility
predicates that operate on values of these types. Carve the three substantial
clusters of predicates out of prog_data.m, and move them into their own
modules, which are each imported by fewer modules than prog_data.m itself.

compiler/vartypes.m:
    New module containing the vartypes type and the predicates that operate
    on it. The new module has *much* better cohesion than the old prog_data.m.

    The vartypes type does not appear in any parse tree; it is used only
    in the HLDS. So make vartypes.m part of the hlds.m package, not
    parse_tree.m.

    Move three predicates that perform renamings and substitutions on vartypes
    here from prog_type_subst.m, since the latter is part of the parse_tree.m
    package, and thus doesn't have access to hlds.vartypes. Make private
    the service predicate that these three moved predicates used to rely on,
    since it has no other callers.

compiler/prog_detism.m:
    New module containing utility predicates that operate on determinisms
    and determinism components.

compiler/prog_rename.m:
    New module containing utility predicates that rename variables in
    various data structures.

compiler/prog_data.m:
    Remove the stuff now in the three new modules.

compiler/prog_type_subst.m:
    Remove the three predicates now in vartypes.m.

compiler/mercury_to_mercury.m:
    Delete an unneded predicate, which was the only part of this module
    that referred to vartypes.

compiler/prog_type.m:
compiler/builtin_lib_types.m:
compiler/type_util.m:
    Move some utility predicates that refer to vartypes from prog_type.m
    and builtin_lib_types.m (both part of parse_tree.m) to type_util.m
    (part of check_hlds.m).

compiler/parse_tree.m:
compiler/hlds.m:
compiler/notes/compiler_design.html:
    Mention the new modules.

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/arg_info.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/clause_to_proc.m:
compiler/closure_analysis.m:
compiler/code_info.m:
compiler/code_loc_dep.m:
compiler/common.m:
compiler/complexity.m:
compiler/const_prop.m:
compiler/constraint.m:
compiler/continuation_info.m:
compiler/coverage_profiling.m:
compiler/cse_detection.m:
compiler/ctgc.datastruct.m:
compiler/ctgc.util.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
compiler/disj_gen.m:
compiler/equiv_type_hlds.m:
compiler/erl_call_gen.m:
compiler/erl_code_gen.m:
compiler/erl_code_util.m:
compiler/exception_analysis.m:
compiler/float_regs.m:
compiler/follow_code.m:
compiler/follow_vars.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/goal_path.m:
compiler/goal_store.m:
compiler/goal_util.m:
compiler/headvar_names.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_clauses.m:
compiler/hlds_goal.m:
compiler/hlds_llds.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_pred.m:
compiler/hlds_rtti.m:
compiler/inlining.m:
compiler/inst_util.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/interval.m:
compiler/lambda.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/lookup_switch.m:
compiler/make_goal.m:
compiler/mark_tail_calls.m:
compiler/ml_accurate_gc.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_disj_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_proc_gen.m:
compiler/ml_unify_gen.m:
compiler/mode_constraints.m:
compiler/mode_info.m:
compiler/mode_util.m:
compiler/modecheck_call.m:
compiler/modecheck_conj.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/par_loop_control.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/polymorphism.m:
compiler/post_typecheck.m:
compiler/prog_rep.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/quantification.m:
compiler/rbmm.points_to_graph.m:
compiler/rbmm.points_to_info.m:
compiler/rbmm.region_liveness_info.m:
compiler/rbmm.region_transformation.m:
compiler/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/ssdebug.m:
compiler/stack_alloc.m:
compiler/stack_layout.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/store_alloc.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/switch_detection.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_initial.m:
compiler/term_constr_util.m:
compiler/term_pass1.m:
compiler/term_traversal.m:
compiler/term_util.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/try_expand.m:
compiler/tupling.m:
compiler/type_assign.m:
compiler/type_constraints.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/var_locn.m:
    Conform to the above changes, mostly by importing some of the
    three new modules as well as, or instead of, prog_data.m.
2015-08-09 19:02:12 +10:00
Zoltan Somogyi
89628ae791 More speedups of inst handling code.
On tools/speedtest -l -m, my tests show a speedup of about 2%, but
on Dirk's stress test module, for which the compiler (used to) spend
almost all its time handling insts, the speedup is about 40%.

This diff also contains some small incidental changes I stumbled upon
the "need" for while working on the main change.

compiler/prog_data.m:
    The existing inst_test_results type used to be able to hold the results
    of four tests about a bound inst. Add two more: the set of inst vars that
    may occur in the inst, and whether a type constructor has already been
    propagated into the cons_ids of the bound insts.

    Put the fields of the the unify_inst and merge_inst inst_names into
    a more sensible order.

    Define types that hold the information stored in specific kinds of
    inst_names, for use by hlds_data.m (see below).

compiler/inst_user.m:
    For each user defined bound inst that matches exactly one parameterless
    type, propagate its type constructor into it, and record the fact that
    it has been done. This avoids having to do it many times later.
    Also record the set of inst vars in each inst, again to avoid having
    to repeat the test many times later.

compiler/mercury_compile_front_end.m:
    Invoke the inst_user module as soon after inst_check.m as we can.

compiler/hlds_data.m:
    Make the structure of six subtables of the inst table private, to allow
    them to be experimented with (and possibly changed) without code changes
    being required in other modules.

    The unify_inst_table, the ground_inst_table and the any_inst_table
    used to be maps whose keys were inst_names, but they were each only ever
    used with one kind of inst_name. Change their keys to the new types
    unify_inst_info, ground_inst_info and any_inst_info, which each contain
    the information in the unify_inst, ground_inst and any_inst inst_names
    respectively. That way, the searches in the maps will perform comparisons
    that don't need to switch on what kind of inst_name they are dealing with,
    and instead go directly to comparing the arguments.

    With the unify_inst_table, also go a step further. The unify_inst_info
    has two fields that are equivalent to booleans. Comparing these
    at every level of the map is wasteful, so switch the representation
    of the unify_inst_table from one map to four maps, one map for each
    possible combination of those booleans. This way, the two booleans
    in the unify_inst_info key are tested just once, when the applicable map
    is selected.

    The merge_inst_table used to have a pair of insts as keys. Replace that
    with the merge_inst_info type, which also holds a pair of insts,
    but on which comparisons should be a bit faster, since it is not
    polymorphic, and thus does not need an implicit typeinfo passed along.

    Provide a combined search_insert operation on each of the inst_tables,
    since their pattern of use is exactly that: search the table, and if
    the key is not found, insert a marker that says the entry is being
    worked on. This avoid one traversal of a possibly-large tree, with
    its associated (possibly very expensive) comparisons.

    For each inst table, provide conversion predicates to and from
    sorted association lists, for use by equiv_type_hlds.m

compiler/equiv_type_hlds.m:
    Expand equivalence types in the new structure of the inst tables.

compiler/inst_util.m:
    Use the new search_insert predicates for the various inst_tables.

    If one of the two insts being unified is free, then avoid using
    the unify_inst_table, since just doing the abstract unification
    is faster, and does not pollute the unify_inst_table.

    If both insts being merged are bound insts, then avoid using the
    merge_inst_table, since (a) the lookup is slower than just doing
    the merge, and (b) it can pollute the merge_inst_table to the extent
    that *all other lookups* in it become very slow.

compiler/inst_match.m:
    Use test result information in bound insts to speed up the corresponding
    tests.

compiler/set_of_var.m:
    Change the representation of sets of vars back to sparse_bitsets.
    I changed them to tree_bitsets several years ago to avoid some bad
    worst-case behavior with sparse_bitsets (which occurred when repeatedly
    appending to the "ends" of sets), but other algorithmic changes have
    since avoiding using set_of_vars in ways that induce that behavior,
    and now my benchmarking tells me that the bottleneck operation is
    conversion of set_of_vars to lists of vars. This is faster with
    sparse_bitsets, since unlike tree_bitsets, they don't have to unravel
    a tree structure.

compiler/mode_util.m:
    Export a predicate now needed by inst_user.m, and clean up the code a bit,
    factoring out repeated code.

compiler/modecheck_util.m:
    Modify an equality comparison of two insts to compare the instantiation
    states themselves, but NOT the test results about those instantiation
    states, since these can differ if the two insts have different histories.

compiler/hlds_code_util.m:
compiler/hlds_out_mode.m:
compiler/hlds_out_module.m:
compiler/mercury_to_mercury.m:
compiler/module_qual.m:
compiler/polymorphism.m:
compiler/prog_mode.m:
compiler/recompilation.usage.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.

The following changes are mostly incidental.

compiler/hlds_args.m:
    Speed up a predicate by avoiding the materialization of a list
    that is needed only for a test.

compiler/instmap.m:
    Clarify some code.

compiler/liveness.m:
    Avoid computing some value when it is not needed.

compiler/mode_errors.m:
    Avoid referring to "arguments" (plural) for errors involving *one*
    argument.

compiler/mode_info.m:
    Move the documentation of some predicates to their declarations.

compiler/modecheck_unify.m:
    Compute some data closer to where it is needed, to reduce the number
    of stack slots needed.

tests/invalid/constrained_poly_insts2.err_exp:
    Expect the updated error message from mode_errors.m (with "argument"
    in singular), as well as module qualified insts, since having inst_user.m
    push type_ctors into the definitions of named inst module qualifies
    the bound_insts inside those definitions.
2015-03-05 20:01:00 +11:00
Zoltan Somogyi
32008490e7 Speed up the compiler, and improve error messages for bad insts.
On tools/speedtest -l, my three tests shows speedups between 7% and 12%
for this diff. For Dirk's stress test module, for which the compiler
spends almost all its time handling insts, the speedup was bigger:
the compilation time went from 3.6 to 2.3 seconds.

compiler/inst_user.m:
    A new module that pretests user defined bound insts, and records
    the results in the insts themselves, so that those tests won't
    have to be done repeatedly, each time the compiler needs their results.

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

compiler/mercury_compile_front_end.m:
    Invoke the new module.

compiler/inst_check.m:
    Rewrite this module to record, for each user defined bound inst, the type
    constructor(s) that the top-level bound insts match. This should allow a
    later diff to make inst_user.m more effective by pre-pushing the one
    matching type constructor into the inst, for insts that *do* have exactly
    *one* matching type constructor.

    The information needed for this also allows us to generate more precise
    error messages, fulfilling an earlier TODO.

compiler/hlds_data.m:
    Add a field to inst definitions to allow this recording.

    Don't hide the representation of the table of user insts. It just makes
    code working with it harder, and provides no benefit, since any useful
    structure imposed on top of the current simple map would require the
    lookups to be done *inside* the abstraction barrier, which the current
    design does not allow.

compiler/prog_data.m:
    Add a redundant field to the representation of data constructors (function
    symbols) in type definitions. This field holds the number of arguments
    of the function symbols, computed just once when the representation is
    created, rather than many times later on in many parts of the compiler.

compiler/prog_io_type_defn.m:
    Fill in the new redundant field when the constructor representations
    are created.

compiler/mode_util.m:
    Avoid the use of higher order code in a predicate that happens to be
    performance critical when compiling Dirk's stress test module.

compiler/add_mode.m:
compiler/add_type.m:
compiler/check_typeclass.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/export.m:
compiler/hhf.m:
compiler/hlds_module.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/make_tags.m:
compiler/mercury_to_mercury.m:
compiler/ml_type_gen.m:
compiler/module_qual.m:
compiler/post_typecheck.m:
compiler/prog_type.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/special_pred.m:
compiler/term_constr_build.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the changes above.

library/Mercury.options:
    Disable the trace flag that calls for the runtime testing of the invariants
    of the tree_bitset.m module. We have tested it far more than necessary,
    and it has been just overhead for a long time now. This helps speed up
    quantification, which takes nontrivial time on Dirk's module.

library/multi_map.m:
    Add a utility predicate needed above. It is a reverse set, i.e. a set
    with a value, key argument order.

    Put the code for the function versions of predicates next to the code
    for the predicate versions.

tests/warnings/inst_with_no_type.m:
tests/valid/inst_perf_bug_1.m:
    Fix indentation.

tests/warnings/inst_with_no_type.exp:
    Update this file to expect the new and improved error messages now
    generated by inst_check.m.
2015-02-28 14:40:34 +11:00
Peter Wang
338b5cb98e Fix some bugs with constrained polymorphic modes.
1. An inst variable from the head of the clause could be bound in the body.
The mode error in the call `P(X)' was not detected because the inst
variable I could be bound to ground.

	:- pred p(pred(T), T).
	:- mode p(pred(in(I =< ground)) is det, in) is det.

	p(P, X) :- P(X).

2. In David Overton's thesis, a get_subst function produces an inst
substitution from the callee's initial insts to the arguments' initial
insts, and the substitution is applied to all insts from the callee.
In the implementation we actually build the substitution while matching
the arguments' insts with the callee's insts, but we lost some precision
by not applying the incremental substitutions built as we match a list
of insts.

3. We rename apart the callee's inst variables from our own, but did not
keep the merged inst varset.  When a renamed inst variable appears in a
mode error it would be printed without its original name.
(could this avert more serious problems?)

4. inst_merge_3 was missing a case.

Some of these bugs may not be apparent due to the hack in
inst_matches_final_3 which allows a ground inst to match any bound inst.
A similar hack exists in inst_matches_binding_3.

compiler/inst_util.m:
	Handle in inst_merge_3 the case
	    InstA \= constrained_inst_var(_, _),
	    InstB = constrained_inst_var(_, _).

	Move InstA = not_reached case to inst_merge_2 to maintain
	inst_merge(not_reached, InstB @ constrained_inst_var(_, _)) = InstB

compiler/inst_match.m:
	Improve precision of inst var substitution computed in
	handle_inst_var_subs_2, following dmo's thesis.

compiler/mode_util.m:
compiler/modecheck_call.m:
	Keep the merged inst varsets after renaming.

compiler/mode_info.m:
	Add "head inst vars" in mode_info structure.

compiler/modecheck_util.m:
	Add get_constrained_inst_vars to extract constrained inst vars from a
	list of mode.

	Make modecheck_var_has_inst_list_* fail if the computed substitution
	would change the constraints of any head inst variables.

compiler/modes.m:
	Initialise mode_info with head inst variables.

compiler/pd_info.m:
compiler/pd_util.m:
	Conform to change in mode_info_init (not specifically tested).

compiler/prog_mode.m:
	Export inst_apply_substitution.

	Make rename_apart_inst_vars return the merged inst varset.

	Fix comments.

tests/invalid/Mmakefile:
tests/invalid/constrained_poly_insts2.err_exp:
tests/invalid/constrained_poly_insts2.m:
tests/valid/Mmakefile:
tests/valid/constrained_poly_multi.m:
	Add test cases.

NEWS:
	Announce fix.
2014-09-12 16:11:28 +10:00
Zoltan Somogyi
13b6f03f46 Module qualify end_module declarations.
compiler/*.m:
    Module qualify the end_module declarations. In some cases, add them.

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

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

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

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

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

browser/*.m:
compiler/*.m:
deep_proiler/*.m:
mdbcomp/*.m:
slice/*.m:
    Conform to the above changes.
2014-09-02 05:20:23 +02:00
Zoltan Somogyi
8a6ffaab19 Fix Mantis bug #354.
I/O tabling has two main purposes. The first and more important is to allow the
debugger to replay parts of the program execution for the programmer, which
requires making I/O operations idempotent (so that we get the same results on
the second, third etc "execution" as on the first). The second purpose is to
let the person using the debugger actually see a list of the I/O actions, and
their results.

The root of the problem here is that the compiler can do the second part
only if it has access to the type_infos describing the types of the arguments
of the I/O action. With the current infrastructure for representing typeclass
information, this is not always possible in the presence of typeclass
constraints on I/O action predicates. The reason is that polymorphism.m can
put the typeinfo for a type variable that is subject to a typeclass constraint
arbitrarily deep inside the typeclass_info for that constraint, but the RTTI
can encode such locations only up to a fixed depth (currently only the
shallowest embedded is encodable).

Before this fix, the test case for this bug got a compiler abort when the
I/O tabling transformation tried to figure out how to table the typeclass
info representing the typeclass constraint on a I/O action predicate.

We still cannot table typeclass infos. We could store them (I/O tabling
does not require anything more complicated), but the problem of deeply buried
typeinfos inside them would still remain. So this fix consists of two parts:

- for typeclass constrained I/O primitives, recording only enough information
  to allow them to replayed (the first purpose above), and not to print them
  out (the second purpose), and
- getting the runtime system to understand this, and not crash with a core dump
  in the absence of the information required for the second purpose.

This second part requires changes to the RTTI used by I/O tabling. These
changes BREAK BINARY COMPATIBILITY in debug grades.

runtime/mercury_stack_layout.h:
    Rename the MR_TableIoDecl structure as the MR_TableIoEntry structure,
    since the I/O table entries that it describes are used not just for
    declarative debugging, but also for printing out I/O actions.

    Add a field to it that specifies whether the fields describing
    the types of the I/O action's arguments are meaningful.

runtime/mercury_grade.h:
    Bump the debug-only binary compatibility version number, since
    the change to mercury_stack_layout.h requires it.

runtime/mercury_trace_base.[ch]:
    When returning information about a tabled I/O action, return a boolean
    that says whether the information abouts its arguments is actually
    present or not. Do not return information about the arguments if
    we cannot convert them into univs due to missing type information.

browser/io_action.m:
    Pay attention to the new info returned by MR_trace_get_action,
    and avoid a potential core dump by generating a description of the
    requested I/O action only if the argument type information needed
    to generate that description is actually available.

trace/mercury_trace_vars.c:
    Pay attention to the new info returned by MR_trace_get_action.
    When the argument type information needed to generate an accurate
    description of the I/O action is not available, generate a
    "description" that mentions this fact.

trace/mercury_trace_cmd_browsing.c:
    Make the fix to mercury_trace_vars.c easier to test by adding a mechanism
    to print out all existing I/O actions, as long as there aren't too many
    of them.

compiler/hlds_pred.m:
compiler/layout.m:
compiler/prog_data.m:
    Prepare for the possibility that we have cannot record the information
    needed to reconstruct the runtime types of the arguments of a I/O tabled
    predicate.

compiler/table_gen.m:
    If an I/O tabled predicate has one or more typeclass constraints,
    do not attempt to record the RTTI needed to reconstruct the types
    of its arguments at runtime.

compiler/continuation_info.m:
compiler/hlds_data.m:
    Rename some data structures that referred to the old MR_TableIoDecl
    structure to refer to its replacement, the MR_TableIoEntry structure.

compiler/bytecode_gen.m:
compiler/ctgc.selector.m:
compiler/dead_proc_elim.m:
compiler/dependency_graph.m:
compiler/erl_unify_gen.m:
compiler/export.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_out_mode.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/hlds_pred.m:
compiler/implementation_defined_literals.m:
compiler/inst_check.m:
compiler/layout.m:
compiler/layout_out.m:
compiler/llds.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_util.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_to_mercury.m:
compiler/ml_global_data.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mode_util.m:
compiler/module_qual.m:
compiler/opt_debug.m:
compiler/proc_gen.m:
compiler/prog_data.m:
compiler/prog_out.m:
compiler/prog_rep.m:
compiler/prog_type.m:
compiler/prog_util.m:
compiler/rbmm.execution_path.m:
compiler/stack_layout.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/type_ctor_info.m:
compiler/unify_gen.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
runtime/mercury_misc.h:
runtime/mercury_tabling.h:
    Conform to the above changes.

tests/debugger/tabled_typeclass.{m,inp,exp,exp2}:
    New test case to test that I/O actions that have typeclass constraints
    on them can be printed in mdb.

tests/debugger/Mmakefile:
tests/debugger/Mercury.options:
    Enable the new case.
2014-08-30 00:48:53 +02:00
Zoltan Somogyi
633141efcb Remove most non-core predicates from hlds_goal.m.
compiler/hlds_goal.m:
    As above.

    Put some of the remaining stuff in a more logical order.

compiler/make_goal.m:
    This new module contains the predicates, previously in hlds_goal.m,
    that construct new goals.

compiler/hlds.m:
compiler/notes/compiler_design.html:
    Include the new module.

compiler/goal_form.m:
    Move to this existing module the predicates previously in hlds_goal.m
    that test whether goals have particular forms (which is the task of
    this module).

compiler/*.m:
    Conform to the above. Note that no module requires a new import
    of BOTH make_goal and goal_form.
2014-08-21 12:14:50 +02:00
Zoltan Somogyi
6d1bc24d0b Make vartypes an abstract data type, in preparation for exploring
Estimated hours taken: 4
Branches: main

compiler/prog_data.m:
	Make vartypes an abstract data type, in preparation for exploring
	better representations for it.

compiler/mode_util.m:
	Provide two different versions of a predicate. The generic version
	continues to use map lookups. The other version knows it works on
	prog_vars, so it can use the abstract operations on them provided
	by prog_data.m.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_heap_ops.m:
compiler/add_pragma.m:
compiler/add_pred.m:
compiler/add_trail_ops.m:
compiler/arg_info.m:
compiler/builtin_lib_types.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/clause_to_proc.m:
compiler/closure_analysis.m:
compiler/code_info.m:
compiler/common.m:
compiler/complexity.m:
compiler/const_prop.m:
compiler/constraint.m:
compiler/continuation_info.m:
compiler/cse_detection.m:
compiler/ctgc.datastruct.m:
compiler/ctgc.util.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
compiler/disj_gen.m:
compiler/equiv_type_hlds.m:
compiler/erl_call_gen.m:
compiler/erl_code_gen.m:
compiler/erl_code_util.m:
compiler/exception_analysis.m:
compiler/float_regs.m:
compiler/follow_vars.m:
compiler/format_call.m:
compiler/goal_path.m:
compiler/goal_util.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_clauses.m:
compiler/hlds_goal.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_pred.m:
compiler/hlds_pred.m:
compiler/hlds_rtti.m:
compiler/inlining.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/interval.m:
compiler/lambda.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/lookup_switch.m:
compiler/mercury_to_mercury.m:
compiler/ml_accurate_gc.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_disj_gen.m:
compiler/ml_lookup_switch.m:
compiler/ml_proc_gen.m:
compiler/ml_unify_gen.m:
compiler/mode_info.m:
compiler/modecheck_call.m:
compiler/modecheck_conj.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/par_loop_control.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/polymorphism.m:
compiler/post_typecheck.m:
compiler/prog_type_subst.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/rbmm.points_to_info.m:
compiler/rbmm.region_liveness_info.m:
compiler/rbmm.region_transformation.m:
compiler/saved_vars.m:
compiler/simplify.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/stack_alloc.m:
compiler/stack_opt.m:
compiler/store_alloc.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/switch_detection.m:
compiler/table_gen.m:
compiler/term_constr_build.m:
compiler/term_constr_util.m:
compiler/term_traversal.m:
compiler/term_util.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/try_expand.m:
compiler/tupling.m:
compiler/type_constraints.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/unique_modes.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/var_locn.m:
	Conform to the above.

compiler/prog_type.m:
compiler/rbmm.points_to_graph.m:
	Conform to the above.

	Move some comments where they belong.

compiler/stm_expand.m:
	Conform to the above.

	Do not export a predicate that is not used outside this module.

	Disable some debugging output unless it is asked for.

	Remove unnecessary prefixes on variable names.

library/version_array.m:
	Instead writing code for field access lookalike functions and defining
	lookup, set etc in terms of them, write code for lookup, set etc,
	and define the field access lookalike functions in terms of them.

	Change argument orders of some internal predicates to be
	more state variable friendly.

	Fix typos in comments.

tests/hard_coded/version_array_test.exp:
	Conform to the change to version_array.m.
2012-07-02 01:16:39 +00:00
Zoltan Somogyi
884838b9df If the backend supports constant structures, and we do not need unifications
Estimated hours taken: 8
Branches: main

If the backend supports constant structures, and we do not need unifications
to retain their original shapes, then convert each from_ground_term scope
into a unification with a cons_id that represents the ground term being
built up.

This speeds up the compilation of training_cars_full.m by about 6%.

compiler/simplify.m:
	Make the conversion if enabled. By doing the conversion in this phase,
	we don't have to teach the semantic analysis passes about unifications
	with the new cons_id, but we do get the benefit of later passes being
	faster, because they have less code to process.

compiler/const_struct.m:
	The declarative debugger does not yet know how to handle the new
	cons_id, so do not introduce it if we are preparing for declarative
	debugging.

compiler/trace_params.m:
	Export a predicate for const_struct.m.

compiler/prog_data.m:
	Add the new cons_id, ground_term_const.

compiler/hlds_data.m:
	Add the tag of the new cons_id, ground_term_const_tag.

compiler/hlds_code_util.m:
	Convert the new cons_id to the new cons_tag.

	Fix an old problem with that conversion process: it always converted
	tuple_cons to single_functor_tag. However, arity-zero tuples are
	(dummy) constants, not heap cells, so we now convert them to a (dummy)
	integer tag. This matters now because the process that generates
	code (actually data) for constant structures handles the cons_tags that
	build constants and heap cells separately. As a side benefit, we
	no longer reserve a word-sized heap cell for arity-zero tuples.

compiler/unify_gen.m:
compiler/ml_unify_gen.m:
	Implement the generation of code for arbitrary constant structures,
	not just those that can implement typeinfos and typeclass_infos.

compiler/term_norm.m:
	Compute the sizes of ground terms for each of our norms.

compiler/term_traversal.m:
	Manage the computation of sizes of ground terms.

	Simplify and thereby speed up a predicate.

compiler/term_constr_build.m:
	Note that we should manage the computation of sizes of ground terms.

compiler/term_util.m:
	Simplify the style of a predicate.

compiler/layout.m:
	Give some field names prefixes to avoid ambiguities.

compiler/bytecode_gen.m:
compiler/ctgc.selector.m:
compiler/dead_proc_elim.m:
compiler/dependency_graph.m:
compiler/erl_unify_gen.m:
compiler/export.m:
compiler/higher_order.m:
compiler/hlds_out_mode.m:
compiler/hlds_out_util.m:
compiler/implementation_defined_literals.m:
compiler/inst_check.m:
compiler/mercury_to_mercury.m:
compiler/ml_global_data.m:
compiler/ml_type_gen.m:
compiler/mode_util.m:
compiler/module_qual.m:
compiler/polymorphism.m:
compiler/prog_rep.m:
compiler/prog_type.m:
compiler/prog_util.m:
compiler/rbmm.execution_path.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/type_ctor_info.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
	Conform to the changes above.

tests/hard_coded/ground_terms.{m,exp}:
	A new test case to test the handling of ground terms.

tests/hard_coded/Mmakefile:
tests/hard_coded/Mercury.options:
	Enable the new test case.
2012-06-11 03:13:24 +00:00
Zoltan Somogyi
ee63cb8d84 Heavily polymorphic code, such as that generated by g12, often builds the same
Estimated hours taken: 80
Branches: main

Heavily polymorphic code, such as that generated by g12, often builds the same
typeinfos and typeclass infos over and over again. We have long had caches
that avoid building a new typeinfo or typeclass info if some variable in the
current scope already contains the right value, but a program that has many
scopes may still build the same typeinfo or typeclass info many times.
If that typeinfo or typeclass info is a ground term, the code generators
will recognize that fact, and will turn all the constructions of that ground
term in different scopes into referencess to the same constant structure.
However, in the meantime, the program can be much bigger than necessary.
In the motivating test case for this change, a single call to fdic_post
is preceded by 133 goals that build the four typeclass infos it needs.

The main idea of this diff is to construct constant typeinfos and typeclass
infos out of line, in a separate data structure. Polymorphism then binds
variables representing typeinfo and typeclass infos to reference to these
constant structures. In the motivating example, this allows polymorphism.m
to insert just four goals before the call to fdic_post, the minimal possible
number: one for each typeclass info that predicate needs.

On Leslie's bug344 program, this change speeds up the compiler by a factor
of five to eight (reducing compile time from about 80 or 85 seconds to
10 or 15).

There is a drawback to this scheme, but it is minor. That drawback is that
once a constant structure is entered into our database of constant structures,
it cannot (yet) be removed. Even if all the references to a constant structure
are eliminated by optimizations, the structure will remain.

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

CHANGES IN THE FRONT END

compiler/const_struct.m:
	A new module to look after our new database of constant structures.
	Currently, its use is enable only on the LLDS and MLDS C backends.

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

compiler/hlds_module.m:
	Include the constant structure database in the module_info.

compiler/hlds_data.m:
	Add two new cons_ids, which refer to typeinfos and typeclass infos
	implemented as constant structures.

	Move the code for calculating the number of extra instance args
	in base_typeclass_infos here from base_typeclass_info.m, since
	polymorphism.m now needs it too. We can now also eliminate the
	duplicate copy of that code in higher_order.m.

	Make an independent optimization: make the restrict_list_elements
	function more efficient by avoiding redundant tests.

compiler/polymorphism.m:
	When building typeinfo and typeclass infos, keep track of whether
	the structure being built is constant. If it is, then put it in the
	database of constant structures, and replace the code building it
	with a simple reference to that new entry.

	Since I now expect most goal sequences inserted before goals to be
	short, consistent use lists of goals to represent these, since the
	costs of conversions to and from cord form are unlikely to be paid back
	by the higher efficiency of cord operations on longer sequences.

	When we want to get the typeclass info of a superclass out of the
	typeclass info of a subclass, if the typeclass info of the subclass
	is known, do the extraction here. We used to do this optimization
	only in higher_order.m, but doing so here reduces the size of the HLDS
	between polymorphism.m and higher_order.m, and thus improves
	compilation time.

	Reorganize some of the structure of this module to make the above
	changes possible. In particular, our new approach requires making
	snapshots of the varsets and vartypes, and later restoring those
	snapshots if the variables allocated turn out to be unnecessary,
	due to all of them describing the components of a constant structure.
	The correctness of such code is much easier to check if the taking
	and restoring of each snapshot takes places in a single predicate.

	Remove the code moved to higher_order.m.

	Add some debugging code for now. If no issues arise in the next few
	weeks, it can be deleted.

compiler/modecheck_unify.m:
	Treat unifications whose right hand side has a cons_id referring to a
	constant structure specially.

compiler/base_typeclass_info.m:
	Replace the code that is now in num_extra_instance_args with a call
	to that predicate.

	Put the arguments of some predicates in a more logical order.

compiler/higher_order.m:
	When looking up the components of existing typeclass infos, handle
	cases where those typeclass infos are constant structures.

	Give some types, fields and variables better names.

	Avoid a redundant map search.

	Avoid some redundant tests by providing separate predicates to handle
	higher order calls and method calls.

	Move the predicate is_typeclass_info_manipulator here from
	polymorphism.m, since this is the only module that uses that predicate.

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

CHANGES IN THE LLDS BACKEND:

compiler/llds.m:
	Add a type to map constant structure numbers to rvals together with
	their LLDS types.

	Introduce a type to represent rvals together with their LLDS types.

compiler/mercury_compile_llds_back_end.m:
	Before we generate code for the predicates of the module, convert
	the constant structures to typed LLDS rvals. Create a map mapping
	each constant structure number to the corresponding typed rvals.

compiler/proc_gen.m:
	Take that map, and put it into the code_info, to allow references
	to those structures to be translated.

	Put the arguments of some predicates into a more logical order.

compiler/code_info.m:
	Include a map giving the representation of each constant structure
	in the code_info.

compiler/unify_gen.m:
	Add the predicates needed to convert the constant structures of a
	module to LLDS rvals. For now, this code works only on the kinds of
	constant structures generated by polymorphism.m.

	Handle unifications whose right hand side is a reference to a constant
	structure.

compiler/global_data.m:
compiler/stack_layout.m:
	Use the new typed_rval type where relevant.

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

CHANGES IN THE MLDS BACKEND:

compiler/ml_proc_gen.m:
	Before we generate code for the predicates of the module, convert
	the constant structures to typed MLDS rvals. Create a map mapping
	each constant structure number to the corresponding typed rvals.

	Factor out some code into a predicate of its own.

compiler/ml_gen_info.m:
	Include a map giving the representation of each constant structure
	in the ml_gen_info.

	Also add to the ml_gen_info an indication of what GC system we are
	generating code for, since the code generator needs to know this often.

compiler/ml_unify_gen.m:
	Add the predicates needed to convert the constant structures of a
	module to MLDS rvals. For now, this code works only on the kinds of
	constant structures generated by polymorphism.m.

	Handle unifications whose right hand side is a reference to a constant
	structure.

	Simplify some existing code.

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

MINOR CHANGES:

mdbcomp/prim_data.m:
	Add a predicate that gets both the module name and the base name
	from a sym_name at the same time. This is used for minor speedups
	in other code updated in this diff.

compiler/dead_proc_elim.m:
	Scan constant structures for references to entities that need to be
	kept alive.

compiler/term_constr_build.m:
compiler/term_traversal.m:
	Do not build size constraints from references to constant structures.
	The sizes of constant terms don't change, so they are irrelevant
	when building constraints for finding argument size changes.

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

TRIVIAL CHANGES TO CONFORM TO OTHER CHANGES:

compiler/hlds_out_module.m:
	Print out the constant structure database if asked.

doc/user_guide.tex:
	Document how to ask for it.

compiler/hlds_out_util.m:
	Print out the new cons_ids.

compiler/hlds_out_mode.m:
	Print out the new cons_ids in insts.

	Remove a compiler abort, to help debug a problem.

	Improve the structure of a predicate.

compiler/hlds_out_goal.m:
	Fix some missing newlines.

compiler/hlds_code_util.m:
	Add some utility predicates needed by the modules above.

	Conform to the changes above.

compiler/mlds_to_il.m:
	Reorder some predicates.

	Conform to the changes above.

compiler/bytecode_gen.m:
compiler/ctgc.selector.m:
compiler/dependency_graph.m:
compiler/erl_unify_gen.m:
compiler/export.m:
compiler/implementation_defined_literals.m:
compiler/inst_check.m:
compiler/llds_out_globals.m:
compiler/mercury_to_mercury.m:
compiler/ml_global_data.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/module_qual.m:
compiler/prog_rep.m:
compiler/prog_type.m:
compiler/prog_util.m:
compiler/rbmm.execution_path.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/type_ctor_info.m:
compiler/unused_imports.m:
compiler/var_locn.m:
compiler/xml_documentation.m:
	Conform to the changes above.

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

OTHER INDEPENDENT CHANGES:

compiler/handle_options.m:
	Add a dump option that is useful for debugging when working on
	polymorphism.m and constant structures.

compiler/equiv_type_hlds.m:
	Fix an old performance bug: make the code handling try goals keep
	the old memory cells representing such goals, instead of rebuilding
	them, if no changes took place inside them.

compiler/ml_accurate_gc.m:
	Move a test earlier, to allow us to avoid more work in the common case.

compiler/erl_code_gen.m:
compiler/error_util.m:
compiler/hhf.m:
compiler/inst_util.m:
compiler/ml_code_util.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/modecheck_call.m:
compiler/modecheck_util.m:
compiler/post_typecheck.m:
compiler/size_prof.m:
compiler/stack_opt.m:
compiler/stratify.m:
compiler/unused_args.m:
compiler/post_type_analysis.m:
library/erland_rtti_implementation.m:
	Minor cleanups.

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

CHANGES TO THE TEST SUITE:

tests/invalid/any_passed_as_ground.err_exp2:
tests/invalid/invalid_default_func_1.err_exp2:
tests/invalid/invalid_default_func_3.err_exp2:
tests/invalid/try_detism.err_exp2:
	Add second expected output files for these tests. We need alternate
	expected outputs because the numbers of some of the typeinfo variables
	mentioned in error message are different depending on whether or not
	const structures are enabled.
2012-06-08 15:37:07 +00:00
Zoltan Somogyi
7c43163c75 Avoid some redundant tests and unnecessary higher order calls.
Estimated hours taken: 1
Branches: main

compiler/mode_util.m:
	Avoid some redundant tests and unnecessary higher order calls.
2012-04-24 11:22:03 +00:00
Zoltan Somogyi
932f7256ba A large part of the cost of a large ground term is incurred not when the
Estimated hours taken: 40
Branches: main

A large part of the cost of a large ground term is incurred not when the
term is constructed, but when it is used. The inst of the term will be huge,
and will typically have to be traversed many times. Some of those traversals
would be linear if not for the fact that, in order to avoid infinite loops
on recursive insts, the predicate doing the traversal has to keep a set
of the insts visited so far. When the traversal is in the middle of the ground
term's inst, it is looking up that inst in a set of the insts of its containing
terms all the way up to the root. When the ground term contains a list with
many repeated elements near the start, the cost of the traversal is cubic
in the length of the list: a linear number of set membership tests, each
of which tests the current inst against a linear number of large insts,
the test itself being linear.

This diff aims to totally sidestep all that. It extends the mer_inst type
to allow (but not require) the creator of an inst to record what the outcome
of some tests on the inst would be. Is it ground? Does it contain "any"?
What inst names and types may it contain? If the creator records this answer,
which the code that creates ground terms does, then many tests will now run
in CONSTANT time, not linear, quadratic or cubic.

We do this only for bound insts. While the concept can apply to all insts,
for small insts it can cost more to interpret the results term than to
do the test directly. Insts cannot be large without being composed mostly
of bound insts, so by recording this info only for bound insts, we can
speed up the handling of all large insts.

This also has the side benefit that in many cases, a traversal that operates
on an inst will often do so in order to compute an updated version of that
inst. In many cases, the updated version is the same as the original version,
but since the traversal has to be prepared for updates, it makes a copy
of the inst anyway. The result of the traversal is thus an inst that has
the same value as the original inst but not the same address. This makes
it useless to try to do equality checks of related insts in constant time
by looking at the pointers. With this diff, many such traversals can be
avoided, allowing the updated inst to keep the address as well as the value
of the corresponding original inst.

Without this diff, the compiler takes more than 10 seconds to compile
zm_rcpsp_cpx.m, with most of that time being spent in mode checking.
With this diff, it takes less than 5 seconds. Basically, mode checking
went from 6+ seconds to 1. The profile of the compiler is now flat on this
input; no single pass takes much more time than the others.

The speed of the compiler is unaffected on tools/speedtest. (Actually, it
gets a very slight speedup, but it is in the noise.)

compiler/prog_data.m:
	Change the bound/2 functor of the mer_inst type to bound/3, adding
	a field that gives the outcome of some common tests performed on insts.
	When we attach insts to the variables representing parts of ground
	terms, we mark the insts accordingly. This allows us to perform many
	tests on insts in constant time, not in a time that is linear,
	quadratic or worse in the size of the inst.

compiler/add_pragma.m:
compiler/const_prop.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/float_regs.m:
compiler/hlds_code_util.m:
compiler/hlds_goal.m:
compiler/inst_check.m:
compiler/inst_match.m:
compiler/inst_util.m:
compiler/lco.m:
compiler/mercury_to_mercury.m:
compiler/mode_constraints.m:
compiler/mode_debug.m:
compiler/mode_util.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/module_qual.m:
compiler/pd_util.m:
compiler/polymorphism.m:
compiler/prog_io.m:
compiler/prog_io_util.m:
compiler/prog_mode.m:
compiler/prog_util.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/simplify.m:
compiler/try_expand.m:
compiler/unique_modes.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
	Conform to the above change.

	Obviously, this required the modification of most predicates dealing
	with insts. Where the original predicates used multiple clauses,
	inconsistent variable names and/or bad grouping or ordering of code,
	this diff fixes that.

	More to the point, while in many places, the new code ignores the new
	field in input insts as either not relevant or not useful, in several
	places, the new code

	- pays attention to this field in input insts and executes less or
	  faster code if the result of some test it needs is already available
	  in it, or

	- fills in the field in insts it generates as output.

	Most, but not all, of changes in the first of those two categories
	were in inst_util.m and inst_match.m.

compiler/hlds_out_mode.m:
	When writing out insts, or converting them to term form as the first
	step in printing them out, print the new field if we are generating
	debug output (such as a HLDS dump), but do not do so if we are
	generating actual Mercury code (such as a .opt file).

	Reorder the arguments of many predicates to move the context argument
	BEFORE the argument representing the object to be printed or converted
	to a term, since this allows us to use list.map on lists of such
	objects.

compiler/hlds_out_util.m:
	Define a type that allows us to distinguish between the two.

compiler/hlds_out_goal.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
	Thread values of this flag type through a bunch of predicates
	as needed.

compiler/intermod.m:
	Specify output_mercury when writing clauses for optimization files.
	This is needed because mode-specific clauses can have insts in their
	heads. (The mode declarations in .int* files are written out by
	a separate set of predicates, in mercury_to_mercury.m, which ALWAYS
	ignore the new field.)

compiler/prog_util.m:
	There were two predicates named construct_qualified_term, with
	different arities: one took a context, the other didn't. Rename
	the former to avoid the ambiguity.

compiler/goal_expr_to_goal.m:
	Conform to the change to prog_util.m.

compiler/prog_io.m:
	There were two predicates named constrain_inst_vars_in_mode;
	rename one.

	Add an XXX about why they are here in the first place.

compiler/format_call.m:
	Give some type and field names prefixes to avoid some ambiguities.
2012-04-23 03:34:49 +00:00
Peter Wang
b86f973fa9 Allow the use of Mercury abstract machine float registers for passing
Branches: main

Allow the use of Mercury abstract machine float registers for passing
double-precision float arguments in higher order calls.

In of itself this is not so useful for typical Mercury code.  However, as
all non-local procedures are potentially the targets of higher order calls,
without this change first order calls to non-local procedures could not use
float registers either.  That is the actual motivation for this change.

The basic mechanism is straightforward.  As before, do_call_closure_* is
invoked to place the closure's hidden arguments into r1, ..., rN, and extra
input arguments shifted into rN+1, etc.  With float registers, extra input
arguments may also be in f1, f2, etc. and the closure may also have hidden
float arguments.  Optimising for calls, we order the closure's hidden
arguments so that all float register arguments come after all regular
register arguments in the vector.  Having the arguments out of order does
complicate code which needs to deconstruct closures, but that is not so
important.

Polymorphism complicates things.  A closure with type pred(float) may be
passed to a procedure expecting pred(T).  Due to the `float' argument type,
the closure expects its argument in a float register.  But when passed to the
procedure, the polymorphic argument type means it would be called with the
argument in a regular register.

Higher-order insts already contain information about the calling convention,
without which a higher-order term cannot be called.  We extend higher-order
insts to include information about the register class required for each
argument.  For example, we can distinguish between:

	pred(in) is semidet /* arg regs: [reg_f] */
and
	pred(in) is semidet /* arg regs: [reg_r] */

Using this information, we can create a wrapper around a higher-order
variable if it appears in a context requiring a different calling convention.
We do this in a new HLDS pass, called float_regs.m.

Note: Mercury code has a tendency to lose insts for higher-order terms, then
"recover" them by hacky means.  The float_regs pass depends on higher-order
insts; it is impossible to create a wrapper for a procedure without knowing
how to call it.  The float_regs pass will report errors which we otherwise
accepted, due to higher-order insts being unavailable.  It should be possible
for the user to adjust the code to satisfy the pass, though the user may not
understand why it should be necessary.  In most cases, it probably really
*is* unnecessary.  We may be able to make the float_regs pass more tolerant
of missing higher-order insts in the future.

Class method calls do not use float registers because I didn't want to deal
with them yet.


compiler/options.m:
compiler/handle_options.m:
	Always enable float registers in low-level C grades when floats are
	wider than a word.

compiler/make_hlds_passes.m:
	Always allow double word floats to be stored unboxed in cells on C
	grades.

compiler/hlds_goal.m:
	Add an extra field to `generic_call' which gives the register class
	to use for each argument.  This is set by the float_regs pass.

compiler/prog_data.m:
	Add an extra field to `pred_inst_info' which records the register class
	to use for each argument.  This is set by the float_regs pass.

compiler/hlds_pred.m:
	Add a field to `proc_sub_info' which lists the headvars which must be
	passed via regular registers despite their types.

	Add a field to `pred_sub_info' to record the original unsubstituted
	argument types for instance method predicates.

compiler/check_typeclass.m:
	In the pred_info of an instance method predicate, record the original
	argument types before substituting the type variables for the instance.

compiler/float_regs.m:
compiler/transform_hlds.m:
	Add the new HLDS pass.

compiler/mercury_compile_middle_passes.m:
	Run the new pass if float registers are enabled.

compiler/lambda.m:
	Export the predicate to produce a predicate from a lambda.
	This is reused by float_regs.m to create wrapper closures.

	Add an argument to `expand_lambda' to set the reg_r_headvars field on
	the newly created procedure.

	Delete some unused fields from `lambda_info'.

compiler/arg_info.m:
	Make `generate_proc_arg_info' no longer always use regular registers
	for calls to exported procedures.  Do always use regular registers for
	class methods calls.

	Add a version of `make_arg_infos' which takes an explicit list of
	argument registers.  Rename the previous version.

	Add `generic_call_arg_reg_types' to return the argument registers
	for a generic call.

	Add a version of `compute_in_and_out_vars' which additionally separates
	arguments for float and regular registers.

compiler/call_gen.m:
	Use float registers for argument passing in higher-order calls, as
	directed by the new field in `generic_call'.

compiler/code_util.m:
	Add a function to encode the number of regular and float register
	arguments when making a higher-order call.

compiler/llds.m:
	Say that the `do_call_closure_N' functions only work for zero float
	register arguments.

compiler/follow_vars.m:
compiler/interval.m:
	Account for the use of float registers by generic call goals in these
	passes.

compiler/unify_gen.m:
	Move float register arguments to the end of a closure's hidden
	arguments vector, after regular register arguments.

	Count hidden regular and float register arguments separately, but
	encode them in the same word in the closure.  This is preferable to
	using two words because it reduces the differences between grades
	with and without float registers present.

	Disable generating code which creates a closure from an existing
	closure, if float registers exist.  That code does not understand the
	reordered hidden arguments vector yet.

compiler/continuation_info.m:
	Replace an argument's type_info in the closure layout if the argument
	is a float *and* is passed via a regular register, when floats are
	normally passed via float registers.  Instead, give it the type_info
	for `private_builtin.float_box'.

compiler/builtin_lib_types.m:
	Add function to return the type of `private_builtin.float_box/0'.

compiler/hlds_out_goal.m:
compiler/hlds_out_pred.m:
compiler/mercury_to_mercury.m:
	Dump the new fields added to `generic_call', `pred_inst_info' and
	`proc_sub_info'.

compiler/prog_type.m:
	Add helper predicate.

compiler/*.m:
	Conform to changes.

library/private_builtin.m:
	Add a type `float_box'.

runtime/mercury_ho_call.h:
	Describe the modified closure representation.

	Rename the field which counts the number of hidden arguments to prevent
	it being used incorrectly, as it now encodes two numbers (potentially).

	Add macros to unpack the encoded field.

runtime/mercury_ho_call.c:
	Update the description of how higher-order calls work.

	Update code which extracts closure arguments to take account the
	arguments being reordered in the hidden arguments vector.

runtime/mercury_deep_copy.c:
runtime/mercury_deep_copy_body.h:
runtime/mercury_layout_util.c:
runtime/mercury_ml_expand_body.h:
	Update code which extracts closure arguments to take account the
	arguments being reordered in the hidden arguments vector.

runtime/mercury_type_info.c:
runtime/mercury_type_info.h:
	Add helper function.

tools/make_spec_ho_call:
	Update the generated do_call_closure_* functions to place float
	register arguments.

tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/ho_float_reg.exp:
tests/hard_coded/ho_float_reg.m:
	Add new test case.

tests/hard_coded/copy_pred.exp:
tests/hard_coded/copy_pred.m:
tests/hard_coded/deconstruct_arg.exp:
tests/hard_coded/deconstruct_arg.exp2:
tests/hard_coded/deconstruct_arg.m:
	Extend test cases with float arguments in closures.

tests/debugger/higher_order.exp2:
	Add alternative output, changed due to closure wrapping.

tests/hard_coded/ho_univ_to_type.m:
	Adjust test case so that the float_regs pass does not report errors
	about missing higher-order insts.

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

	Delete a duplicated paragraph.

compiler/notes/todo.html:
TODO:
	Delete one hundred billion year old todos.
2012-02-13 00:11:57 +00:00
Zoltan Somogyi
585c1d623c Fix a problem with from_ground_term scopes.
Estimated hours taken: 20
Branches: main

Fix a problem with from_ground_term scopes. When they are built, the scopes
are tentantively marked as from_ground_term_construct scopes, and the
unifications inside them are in a top down order. Mode analysis therefore
expected the unifications inside from_ground_term_construct scopes to have
that order.

The problem was that mode analysis, when it confirmed that a
from_ground_term scope is indeed a from_ground_term_construct scope,
itself reversed the order of the unifications, putting them in a bottom up
order. When mode analysis is reinvoked, either for unique mode checking, or
after cse_detection finds common subexpressions, this meant that
mode analysis found the unifications in the "wrong" order, and therefore
disregarded the scope, discarding all its performance benefits.

This diff separates out the two notions that we previously conflated.
The scope kind from_ground_term_construct now refers only to scopes
which are definitely known to construct ground terms. We can know that
only after mode analysis. Until then, from_ground_term scopes are now marked
as from_ground_term_initial. The two kinds have different though overlapping
sets of invariants; in particular, they promise different orderings of the
unifications in the scope.

This diff reduces the time needed to compile mas_objects.data.m
from about 221 seconds to about 8.

compiler/hlds_goal.m:
	Add the from_ground_term_initial kind. Document the invariants
	that each kind of from_ground_term scope promises.

compiler/superhomogeneous.m:
	Mark from_ground_term scopes initially as from_ground_term_initial,
	not from_ground_term_construct.

compiler/post_typecheck.m:
	Make the predicate that converts function calls that look like
	unifications (such as X = int.min) into actual function calls
	say whether it performed such a conversion.

compiler/purity.m:
	Use the new functionality in post_typecheck.m to convert
	from_ground_term_initial scopes into from_ground_term_other scopes
	if the conversion of a unification into a call means that we have to
	break an invariant expected of from_ground_term_initial scopes.

compiler/cse_detection.m:
compiler/switch_detection.m:
	Maintain the invariants we now expect of from_ground_term_deconstruct
	scopes.

compiler/modecheck_goal.m:
	Maintain the invariants we now expect of the different
	from_ground_term scopes.

	Avoid traversing such scopes if a previous invocation of mode analysis
	says we can.

	Optimize away from_ground_term_construct scopes if the variable being
	constructed is not needed later.

compiler/quantification.m:
	If the variable named in a from_ground_term_initial or
	from_ground_term_construct scope is not referred to outside the scope,
	set the nonlocals set of the scope to empty, which allows later
	compiler passes to optimize it away.

	Avoid some unnecessary work by the compiler.

compiler/add_trail_ops.m:
compiler/closure_analysis.m:
compiler/constraint.m:
compiler/dead_proc_elim.m:
compiler/deep_profile.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/dependency_graph.m:
compiler/exception_analysis.m:
compiler/follow_code.m:
compiler/follow_vars.m:
compiler/goal_form.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/inlining.m:
compiler/interval.m:
compiler/lambda.m:
compiler/lco.m:
compiler/middle_rec.m:
compiler/mode_util.m:
compiler/parallel_to_plain.m:
compiler/simplify.m:
compiler/stm_expand.m:
compiler/stratify.m:
compiler/tabling_analysis.m:
compiler/term_pass1.m:
compiler/try_expand.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/unused_args.m:
	Avoid traversing from_ground_term_deconstruct scopes in cases
	where the invariants that now hold (mainly the absence of anything
	but deconstruct unifications) make such traversals unnecessary.

compiler/live_vars.m:
compiler/liveness.m:
compiler/structure_reuse.lbu.m:
	Add comments about exploiting from_ground_term_deconstruct scopes.

compiler/det_analysis.m:
compiler/hlds_out_goal.m:
compiler/polymorphism.m:
compiler/saved_vars.m:
compiler/unique_modes.m:
	Handle from_ground_term_initial scopes.

compiler/handle_options.m:
	Add a dump verbosity option that is useful for comparing HLDS dumps
	created by two different compilers.

compiler/type_util.m:
	Minor speedup.

compiler/mode_info.m:
compiler/modecheck_conj.m:
compiler/prog_data.m:
compiler/rbmm.region_transformation.m:
compiler/typecheck.m:
	Improve documentation.
2011-08-31 07:59:35 +00:00
Zoltan Somogyi
d00ea69529 Switch from using set(prog_var), which is represented using set_ordlist,
Estimated hours taken: 12
Branches: main

Switch from using set(prog_var), which is represented using set_ordlist,
to set_of_progvar, which is represented using tree_bitset, for most sets
of variables in the compiler, including the nonlocals sets in goal_infos.

This diff yields about a 5% speedup when compiling the training_cars_full.m
stress test, but also about a 1% slowdown on tools/speedtest. Both of these
are with the current default state in which tree_bitset is compiled with
a whole bunch of sanity checks. If these are disabled, we get roughly a 1%
speedup on tools/speedtest. I intend to disable those sanity checks after
a shakedown period of a week or two in which the updated version of the
compiler is installed on our platforms.

compiler/hlds_goal.m:
	Replace almost all occurrences of set(prog_var) with set_of_progvar.
	The main exceptions are the types supporting rbmm.

compiler/set_of_var.m:
	Add some more predicates and functions that previous existed on sets
	but not yet on set_of_vars.

compiler/*.m:
	Conform to the change in hlds_goal.m, and make similar changes
	in set representations.

library/bag.m:
	Add a predicate and function for creating a bag from a sorted list.
	We already had them for creating a bag from a set, but a set_of_progvar
	shouldn't have to be converted to a set.

library/robdd.m:
	Fix deviations from our programming style.
2011-08-16 03:26:40 +00:00