Commit Graph

127 Commits

Author SHA1 Message Date
Zoltan Somogyi
ee0f9f73d7 Add library/fatter_sparse_bitset.m.
library/fatter_sparse_bitset.m:
    Add this version of fat_sparse_bitset.m, which stores *two* words
    worth of bits in each cell, not one. This word would otherwise be unused,
    because the Boehm-Demers-Weiser allocator rounds up requests for three
    word cells to four.

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

library/fat_sparse_bitset.m:
library/sparse_bitset.m:
library/tree_bitset.m:
    Update the documentation of all these other bitset modules. Copy
    the same basic introduction to all the relevant modules. Add documentation
    of the differences to tree_bitset.m and fatter_sparse_bitset.m, with
    a pointer in fat_sparse_bitset.m to fatter_sparse_bitset.m.

library/test_bitset.m:
    Test the new module as well as the others.

tests/hard_coded/speedtest_bitset.m:
    Extend the benchmarking of list_to_set operations to the new module.
    To allow the benchmarking to be tough enough to be informative, comment
    out the benchmarking of the old_list_to_set operations.
2023-01-31 18:36:16 +11:00
Zoltan Somogyi
83a1aaa52e Add a prefix to some functors to avoid ambiguity. 2022-11-29 16:40:22 +11:00
Zoltan Somogyi
5638bca5bf Fix too-long lines. 2022-11-18 20:23:11 +11:00
Zoltan Somogyi
5251f76ab6 Simplify the code writing out LLDS C code.
compiler/llds_out_util.m:
    Add decl_set_insert_new, which combines decl_set_is_member and
    decl_set_insert in their typical usage pattern.

compiler/layout_out.m:
compiler/llds_out_code_addr.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_global.m:
compiler/llds_out_instr.m:
compiler/rtti_out.m:
    Use decl_set_insert_new where applicable.

    Replace sequences of calls to io.write_{string,int}s with calls to
    io.format.
2022-10-01 19:27:54 +10:00
Zoltan Somogyi
b47b900f94 Delete output_to_be_quoted_string_LANG.
compiler/c_util.m:
    As above. output_to_be_quoted_string_c could put a character sequence
    into the middle of its output that was appropriate when called from
    one call site but not when called from any others. The versions for
    Java and C# did not have that flaw, but their existence as separate
    predicates did not add any value either.

compiler/rtti_out.m:
    Replace the only uses of output_to_be_quoted_string_LANG
    outside c_util.m itself, which used it inappropriately all along.
2022-09-29 13:09:50 +10:00
Zoltan Somogyi
0997b8ecbb Make output_quoted_X actually put quotes around X ...
... since the vast majority of callers do want to put quotes around
the X being quoted. (X being string, multi_string or char.)

compiler/c_util.m:
    Rename predicates whose names are output_quoted_X for some X
    to output_to_be_quoted_X, because while they escaped the characters in X
    if needed, they did not put quotes around the result.

    Add new predicates to take over the output_quoted_X names
    which *do* add the quotes.

    Likewise, rename quote_X functions to prepare_to_quote_X,
    and add new functions to take over the quote_X names
    that do add quotes.

compiler/llds_out_global.m:
    Conform to the changes above, and fix a bug in an earlier diff
    in this series.

compiler/bytecode.m:
compiler/fact_table.m:
compiler/layout_out.m:
compiler/llds_out_data.m:
compiler/llds_out_instr.m:
compiler/ml_foreign_proc_gen.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_global.m:
compiler/mlds_to_cs_data.m:
compiler/mlds_to_java_data.m:
compiler/opt_debug.m:
compiler/pragma_c_gen.m:
compiler/rtti_out.m:
    Conform to the changes above.

    Mark two places in rtti_out.m where the use of output_to_be_quoted_string
    is likely to be a bug.
2022-09-27 22:50:38 +10:00
Zoltan Somogyi
23d9b904e2 Add a "_c" suffix to the names of C-specific preds.
compiler/c_util.m:
    As abobe.

    Move should-be-related predicates next to each other.

    Put C-specific predicates before Java- and C#-specific predicates.

    Add some comments.

compiler/bytecode.m:
compiler/fact_table.m:
compiler/layout_out.m:
compiler/llds_out_data.m:
compiler/llds_out_global.m:
compiler/llds_out_instr.m:
compiler/ml_foreign_proc_gen.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_global.m:
compiler/opt_debug.m:
compiler/pragma_c_gen.m:
compiler/rtti_out.m:
    Add the new suffixes.
2022-09-27 11:59:24 +10:00
Zoltan Somogyi
28f0000487 Rename predicates to avoid ambiguities. 2022-07-06 14:33:10 +10:00
Zoltan Somogyi
ea4f95a7ed Use var_tables in lco.m, and when dumping goals.
Since this is the first converted module that dumps out goals when
debugging trace flags are enabled, this required generalizing the code
that does that, to take either varsets or var_tables as a means of
specifying the names of variables. We do this via a new type,
var_name_source, which contains either a varset or a var_table.

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

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

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

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

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

    Define the var_name_source type.

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

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

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

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

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

    Fix some comments.

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

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

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

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

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

configure.ac:
    Require the installed compiler to support this capability.
2021-06-16 15:23:58 +10:00
Peter Wang
e2b5ba8884 Make subtypes share high-level data representation with base type.
In the high-level data representation, make a subtype term be
represented using the class corresponding to the base type constructor
instead of its own class. This is necessary to be able to downcast
a term from a type to a subtype in Java and C#.

compiler/du_type_layout.m:
    Move get_base_type_ctor predicate to type_util.m.

    Abort in a couple of places that should not occur.

compiler/type_util.m:
    Add get_base_type_ctor predicate.

compiler/globals.m:
    Add compilation_target_high_level_data predicate.

compiler/lco.m:
    Use compilation_target_high_level_data predicate.

compiler/ml_type_gen.m:
    When using the high-level data representation,
    don't generate a MLDS type definition (class) for a subtype.

compiler/mlds.m:
    When using the high-level data representation,
    replace a Mercury subtype with its base type in an mlds_type.

    Move foreign_type_to_mlds_type.

compiler/ml_unify_gen_util.m:
    To access a field when using the high-level data representation,
    use field names from the base type constructor of a subtype.

compiler/unify_proc.m:
    When using the high-level data representation,
    generate unify/compare procs for subtypes that just call the
    unify/compare proc for the base type constructor.

compiler/options.m:
    Delete references to --high-level and --high-level-data.

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

runtime/mercury_type_info.h:
    Document a new field MR_type_ctor_base in MR_TypeCtorInfo_Struct.
    The field is unnecessary and does not exist in the
    MR_TypeCtorInfo_Struct for C.

runtime/mercury_dotnet.cs.in:
    Add type_ctor_base member to MR_TypeCtorInfo_Struct for C#.

java/runtime/TypeCtorInfo_Struct.java
    Add type_ctor_base member to MR_TypeCtorInfo_Struct for Java.

compiler/rtti.m:
compiler/type_ctor_info.m:
    Add field corresponding to MR_type_ctor_base in type_ctor_details
    for enum, notag and general du types.

compiler/rtti_to_mlds.m:
    Initialize the MR_type_ctor_base field in type_ctor_infos
    for high-level data grades.

compiler/rtti_out.m:
    Don't write out the MR_type_ctor_base field when using
    the low-level data representation.

library/rtti_implementation.m:
    In Java and C# grades (high-level data grades), use the
    MR_type_ctor_base field to get the type_ctor_info of the base type
    ctor when constructing or deconstructing terms of a subtype.
    It is necessary to perform reflection using class and field names
    from the base type constructor since there are no classes
    corresponding to subtypes.

    Clean up some code.

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

tests/hard_coded/Mmakefile:
tests/hard_coded/subtype_abstract.m:
tests/hard_coded/subtype_abstract_2.m:
tests/hard_coded/subtype_abstract.exp:
    Add a test case.

tests/hard_coded/subtype_rtti.m:
tests/hard_coded/subtype_rtti.exp2:
    Enable a test that was previously skipped in Java and C# grades.
2021-04-09 17:41:23 +10:00
Peter Wang
6a345ff5dc Make subtypes share low-level data representation with base type.
Make subtypes share data representation with base type when using
low-level data. High-level data grades are unchanged, so subtypes
are still represented with distinct classes from their base types.

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

compiler/prog_data.m:
    Add abstract_subtype option for type_details_abstract.

    Correct XXX comment.

compiler/prog_item.m:
    Add type item_type_repn_info_subtype.

    Add tcrepn_is_subtype_of option for type_ctor_repn_info.

compiler/equiv_type.m:
    Replace equivalences in tcrepn_is_subtype_of.

compiler/module_qual.qualify_items.m:
    Module qualify in tcrepn_is_subtype_of.

compiler/prog_type.m:
    Rename some predicates that can only work on non-subtype du types.

    Update comments.

compiler/check_parse_tree_type_defns.m:
    Classify subtype type definitions as std_mer_type_du_subtype
    instead of std_mer_type_du_all_plain_constants or
    std_mer_type_du_not_all_plain_constants.

    Update some comments.

compiler/du_type_layout.m:
    Add two sub-passes to handle subtypes.

compiler/comp_unit_interface.m:
    Extend this module to handle subtype type definitions,
    analogous to the way equivalence type definitions are handled.

    Rename some predicates to clarify that they must not be used
    to test subtypes.

    Record an abstract version of a subtype type definition using
    the abstract_subtype option in type_details_abstract.
    This allows the super type ctor of the subtype to be known,
    and hence the base type ctor, when a subtype is abstract exported.

    Update comments.

compiler/decide_type_repn.m:
    Extend this module to handle subtype type definitions.

    Generate type_representation items for subtype type definitions
    which include the super type ctor of the subtype.

compiler/parse_tree_out.m:
    Write out abstract_subtype as
    "where type_is_abstract_subtype(Name/Arity)" on type definitions.

compiler/parse_type_defn.m:
    Parse "type_is_abstract_subtype(Name/Arity)" declarations.

compiler/parse_tree_out_type_repn.m:
    Write type_representation items with "is_subtype_of(TypeCtor/Arity)".

compiler/parse_type_repn.m:
    Parse "is_subtype_of(TypeCtor/Arity)" in type_representation items.

compiler/add_type.m:
compiler/convert_parse_tree.m:
compiler/opt_debug.m:
compiler/type_util.m:
    Conform to changes.

    Update comments.

compiler/direct_arg_in_out.m:
    Delete XXX, nothing to do.

compiler/parse_util.m:
    Rename overly specific variable.

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

runtime/mercury_type_info.h:
    Add a flag in MR_TypeCtorInfo to indicate if the enum/du layout
    array may be indexed by an enum value or du ptag value.
    Subtypes break the invariant that the layout array contains entries
    for every enum/ptag value from 0 up to the maximum value.
    The presence of the flag MR_TYPE_CTOR_FLAG_LAYOUT_INDEXABLE tells
    the runtime that it can directly index the layout array instead of
    searching through it (which is the common case, for non-subtypes).

    Add a field MR_du_ptag to MR_DuPtagLayout. This is necessary to find
    an entry for a given primary tag value in a MR_DuPtagLayout array.

    Add a field MR_du_ptag_flags to MR_DuPtagLayout, currently with one
    possible flag MR_DU_PTAG_FLAG_SECTAG_ALTERNATIVES_INDEXABLE.
    As with primary tags, subtypes break the invariant that the
    sectag_alternatives array contains entries for every secondary tag
    value from 0 up to the maximum value. The presence of the flag tells
    the runtime that it can directly index the sectag_alternatives array
    (which is the common case, for non-subtypes).

    The two fields added to MR_DuPtagLayout occupy space that was
    previously padding, so the size of MR_DuPtagLayout is unchanged.

    In MR_EnumFunctorDesc, replace the MR_enum_functor_ordinal field by
    MR_enum_functor_value, i.e. the integer value representing the
    functor in memory. Storing *both* the functor ordinal and enum value
    would increase the size of the MR_EnumFunctorDesc struct, and would
    be redundant in the common case of non-subtype enums (both fields
    would contain equal values). We forgo having the functor ordinal
    directly available, at the cost of needing to search through an
    MR_EnumFunctorDesc array when a functor ordinal is required for a
    subtype enum, which should be rare.

compiler/rtti.m:
    Swap enum "functor ordinal" and "value" in places.

    Use a type 'enum_value' to try to ensure we do not mix up enum
    functor ordinals and enum values.

    Add code to encode the MR_TYPE_CTOR_FLAG_LAYOUT_INDEXABLE flag.

    Add code to encode the MR_DU_PTAG_FLAG_SECTAG_ALTERNATIVES_INDEXABLE
    flag.

compiler/rtti_out.m:
    Write out "enum_ordinal_ordered_tables" ordered by functor ordinals
    instead of "enum_value_ordered_tables" ordered by enum values.

    Output the enum value for MR_EnumFunctorDesc instead of functor
    ordinal.

    Output the MR_du_ptag and MR_du_ptag_flags fields for
    MR_DuPtagLayout.

    Relax sanity check on primary tags. A subtype may not necessarily
    use ptag 0, and may skip ptag values.

compiler/rtti_to_mlds.m:
    Generate "enum_ordinal_ordered_tables" instead of
    "enum_value_ordered_tables".

    Fill in the enum value for a MR_EnumFunctorDesc instead of
    the functor ordinal.

compiler/type_ctor_info.m:
    Add predicate to generate the MR_du_ptag_flags field.

    Add the MR_TYPE_CTOR_FLAG_LAYOUT_INDEXABLE flag to type_ctor_infos
    when appropriate.

    Bump the type_ctor_info_rtti_version.

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

runtime/mercury_ml_expand_body.h:
    Search through an enum layout array to find the matching enum value,
    unless the array can be indexed.

    Search through a ptag layout array to find the matching ptag value,
    unless the array can be indexed.

    Search through a sectag_alternatives array to find the matching
    secondary tag value, unless the array can be indexed.

    Factor out the code to search through a foreign enum layout array
    into a separate macro.

runtime/mercury_construct.c:
runtime/mercury_construct.h:
    Add a functor_ordinal field to the MR_Construct_Info_Struct.
    This will hold the functor ordinal now that it is not available in
    MR_EnumFunctorDesc.

    Make MR_get_functors_check_range take an argument to indicate if the
    functor_ordinal field needs to be filled in properly. Most callers
    do not need the field.

library/construct.m:
    Conform to changes to MR_get_functors_check_range and
    MR_EnumFunctorDesc.

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

runtime/mercury_dotnet.cs.in:
    Modify RTTI classes for C# backend, analogous to the changes for the
    C runtime.

    Add methods to index/search through enum layout arrays, ptag layout
    arrays, and sectag_alternatives arrays.

java/runtime/DuPtagLayout.java:
java/runtime/EnumFunctorDesc.java:
java/runtime/TypeCtorInfo_Struct.java:
    Modify RTTI classes for Java backend, analogous to the changes for the
    C runtime.

    Add methods to index/search through enum layout arrays, ptag layout
    arrays, and sectag_alternatives arrays.

library/rtti_implementation.m:
    Conform to MR_EnumFunctorDesc field change.

    Index or search through the enum layout array or ptag layout array
    based on the MR_TYPE_CTOR_FLAG_LAYOUT_INDEXABLE flag.

    Index or search through the sectag_alternatives array depending on
    the MR_DU_PTAG_FLAG_SECTAG_ALTERNATIVES_INDEXABLE flag.

    Add separator lines.

    Slightly reorder some code.

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

tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/subtype_pack.m:
tests/hard_coded/subtype_pack_2.m:
tests/hard_coded/subtype_pack.exp:
tests/hard_coded/subtype_rtti.m:
tests/hard_coded/subtype_rtti.exp:
tests/hard_coded/subtype_rtti.exp2:
    Add test cases.
2021-04-09 17:36:38 +10:00
Zoltan Somogyi
5f50259d16 Write to explicitly named streams in many modules.
Right now, most parts of the compiler write to the "current output stream".
This was a pragmatic choice at the time, but has not aged well. The problem
is that the answer to the question "where is the current output stream going?"
is not obvious in *all* places in the compiler (although it is obvious in
most). When using such implicit streams, finding where the output is going
to in a given predicate requires inspecting not just the ancestors of that
predicate, but also all their older siblings (since any of them could have
changed the current stream), *including* their entire call trees. This is
usually an infeasible task. By constrast, if we explicitly pass streams
to all output operations, we need only follow the places where the variable
representing that stream is bound, which the mode system makes easy.

This diff switches large parts of the compiler over to doing output only
to explicitly passed streams, never to the implicit "current output stream".
The parts it switches over are the parts that rely to a significant degree
on the innermost change, which is to the "output" typeclass in
parse_tree_out_info.m. This is the part that has to be switched over to
explicit streams first, because (a) many modules such as mercury_to_mercury.m
rely on the output typeclass, and (b) most other modules that do output
call predicates in these modules. Starting anywhere else would be like
building a skyscraper starting at the top.

This typeclass, output(U), has two instances: output(io), and output(string),
so you could output either to the current output stream, or to a string.
To allow the specification of the destination stream in the first case,
this diff changes the typeclass to output(S, U) with a functional dependency
from U to S, with the two instances being output(io.text_output_stream, io)
and output(unit, string). (The unit arg is ignored in the second case.)

There is a complication with the output typeclass method, add_list, that
outputs a list of items. The complication is that each item is output
by a predicate supplied by the caller, but the separator between the items
(usually a comma) is output by add_list itself. We don't want to give
callers of this method the opportunity to screw up by specifying (possibly
implicitly) two different output streams for these two purposes, so we want
(a) the caller to tell add_list where to put the separators, and then
(b) for add_list, not its caller, tell the user-supplied predicate what
stream to write to. This works only if the stream argument is just before
the di,uo pair of I/O state arguments, which differs from our usual practice
of passing the stream at or near the left edge of the argument list,
not near the right. The result of this complication is that two categories
of predicates that are and are not used to print items in a list differ
in where they put the stream in their argument lists. This makes it easy
to pass the stream in the wrong argument position if you call a predicate
without looking up its signature, and may require *changing* the argument
order when a predicate is used to print an item in a list for the first time.
A complete switch over to always passing the stream just before !IO
would fix this inconsistency, but is far to big a change to make all at once.

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

    Add write_out_list, which is a variant of io.write_list specifically
    designed to address the "complication" described above. It also has
    the arguments in an order that is better suited for higher-order use.

    Make the same change to argument order in the class method add_list
    as well.

Almost all of the following changes consist of passing an extra stream
argument to output predicates. In some places, where I thought this would
aid readability, I replaced sequences of calls to output predicates
with a single io.format.

compiler/prog_out.m:
    This module had many predicates that wrote things to the current output
    stream. This diff adds versions of these predicates that take an
    explicit stream argument.

    If the originals are still needed after the changes to the other modules,
    keep them, but add "_to_cur_stream" to the end of their names.
    Otherwise, delete them. (Many of the changes below replace
    write_xyz(..., !IO) with io.write_string(Stream, xyz_to_string(...), !IO),
    especially when write_xyz did nothing except call xyz_to_string
    and wrote out the result.)

compiler/c_util.m:
    Add either an explicit stream argument to the argument list, or a
    "_current_stream" suffix to the name, of every predicate defined
    in this module that does output.

    Add a new predicate to print out the block comment containing
    input for mkinit. This factors out common code in the LLDS and MLDS
    backends.

compiler/name_mangle.m:
    Delete all predicates that used to write to the current output stream,
    after replacing them if necessary with functions that return a string,
    which the caller can print to wherever it wants. (The "if necessary"
    part is there because some of the "replacement" functions already
    existed.)

    When converting a proc_label to a string, *always* require the caller
    to say whether the label prefix should be added to the string,
    instead of silently assuming "yes, add it", as calls to one of the old,
    now deleted predicates had it.

compiler/file_util.m:
    Add output_to_file_stream, a version of output_to_file which
    simply passes the output file stream it opens to the predicate
    that is intended to define the contents of the newly created or
    updated file. The existing output_to_file, which instead sets
    and resets the current output stream around the equivalent
    predicate call, is still needed e.g. by the MLDS backend,
    but hopefully for not too long.

compiler/mercury_to_mercury.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_clause.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_out_pragma.m:
compiler/parse_tree_out_pred_decl.m:
compiler/parse_tree_out_term.m:
compiler/parse_tree_out_type_repn.m:
    Change the code writing out parse trees to explicitly pass a stream
    to every predicate that does output.

    In some places, this allows us to avoid changing the identity
    of the current output stream.

compiler/hlds_out.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_mode.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
    Change the code writing out HLDS code to explicitly pass a stream
    to every predicate that does output. (The changes to these modules
    belong in this diff because these modules call many of the output
    predicates in the parse tree package.)

    In hlds_out_util.m, delete some write_to_xyz(...) predicates that wrote
    the result of xyz_to_string(...) to the current output stream.
    Replace calls to the deleted predicates with calls to io.write_string
    with the string being written being computed by xyz_to_string.

    Add a predicate to hlds_out_util.m that outputs a comment containing
    the current context, if it is valid. This factors out code that used
    to be common to several of the other modules.

    In a few places in hlds_out_module.m, the new code generates a
    slighly different set of blank lines, but this should not be a problem.

compiler/layout_out.m:
compiler/llds_out_code_addr.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_global.m:
compiler/llds_out_instr.m:
compiler/llds_out_util.m:
compiler/opt_debug.m:
compiler/rtti_out.m:
    Change the code writing out the LLDS to explicitly pass a stream
    to every predicate that does output. (The changes to these modules
    belong in this diff because layout_out.m and rtti_out.m call
    many of the output predicates in the parse tree package,
    and through them, the rest of the LLDS backend is affected as well.)

compiler/make.module_dep_file.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
    Replace code that sets and resets the current output stream
    with code that simply passes an explicit output stream to a
    predicate that now *takes* an explicit stream as an argument.

compiler/accumulator.m:
compiler/add_clause.m:
compiler/code_gen.m:
compiler/code_loc_dep.m:
compiler/cse_detection.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/error_msg_inst.m:
compiler/export.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/ite_gen.m:
compiler/lco.m:
compiler/liveness.m:
compiler/lp_rational.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_c_global.m:
compiler/mode_debug.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/optimize.m:
compiler/passes_aux.m:
compiler/pd_debug.m:
compiler/pragma_c_gen.m:
compiler/proc_gen.m:
compiler/prog_ctgc.m:
compiler/push_goals_together.m:
compiler/rat.m:
compiler/recompilation.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/rtti.m:
compiler/saved_vars.m:
compiler/simplify_goal_conj.m:
compiler/stack_opt.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/superhomogeneous.m:
compiler/term_constr_build.m:
compiler/term_constr_data.m:
compiler/term_constr_fixpoint.m:
compiler/term_constr_pass2.m:
compiler/term_constr_util.m:
compiler/tupling.m:
compiler/type_assign.m:
compiler/unneeded_code.m:
compiler/write_deps_file.m:
    Conform to the changes above, mostly by passing streams explicitly.

compiler/hlds_dependency_graph.m:
    Conform to the changes above, mostly by passing streams explicitly.
    Move a predicate's definition next it only use.

compiler/Mercury.options:
    Specify --warn-implicit-stream-calls for all the modules in which
    this diff has replaced all implicit streams with explicit streams.
    (Unfortunately, debugging this diff has shown that --warn-implicit-
    stream-calls detects only *some*, and not *all*, uses of implicit
    streams.)

library/term_io.m:
    Fix documentation.
2020-11-14 15:07:55 +11:00
Zoltan Somogyi
91560d2dd7 Make --everything-in-one-c-function a bool option.
It used to be a special option that just set procs_per_c_function
to the special value of zero, but this behavior is inconsistent with
optimization_options taking the max of the old and new values of
integer options. This meant that --procs-per-c-function=5 -O6
would not put all procedures into one C function.

tools/make_optimization_options_db:
tools/make_optimization_options_end:
compiler/optimization_options.m:
    As above: make --everything-in-one-c-function a bool option,
    named use_just_one_c_func for brevity.

compiler/options.m:
    Move the code handling --everything-in-one-c-function next to the
    other optimization options.

compiler/mercury_compile_llds_back_end.m:
    When deciding which procedures should be put into which C functions,
    use the logic: if use_just_one_c_func, then put all procs into the
    same C function, otherwise, put them into one or more C functions
    with up to procs_per_c_function procedures per function.

    This is now the *only* place in the compiler that looks at
    procs_per_c_function; everywhere else looks at use_just_one_c_func.

compiler/code_util.m:
    Replace a maybe pair type that used to store the value of
    procs_per_c_function with a bespoke type storing use_just_one_c_func,
    which documents its meaning.

compiler/code_info.m:
    Replace a bool type with a bespoke type, again documenting
    its meaning.

compiler/call_gen.m:
compiler/closure_gen.m:
compiler/middle_rec.m:
compiler/pragma_c_gen.m:
compiler/proc_gen.m:
compiler/rtti_out.m:
    Conform to the changes above.

compiler/llds.m:
    Fix blank lines.
2020-09-29 10:25:42 +10:00
Zoltan Somogyi
9cbe5d2caf Put type_repn items for complex types into .int files.
compiler/decide_type_repn.m:
    Previously, this module computed type_repn items to put into .int3 files
    for a subset of the type constructors defined in the current module:
    the direct_dummy, enum and notag types (the *simple* types),
    and the du types whose representation is guaranteed to be
    a word-aligned pointer when targeting C. (We care about pointers
    being word-aligned only when applying the direct arg optimization.
    This optimization is applicable only with the low level data
    representation, which we use only when targeting C.)

    This diff adds code to decide the representations of *all* the
    type constructors defined in the current module.

    This code is based on the existing code in du_type_layout.m,
    which it is intended to eventually replace, but its job is more general,
    because it decides the representation of each type not just for
    one platform (the one we want to generate code), but for all possible
    platforms. This is because we want to put the descriptions of type
    representations into the module's .int file to serve as a single source
    of truth for all modules that use the types defined in this module,
    and the contents of .int files should be platform-independent.
    For our purposes, there are six kinds of platforms, which are
    distinguished along three axes: 64 vs 32 bit machines, spf vs non-spf
    grades, and direct arg optimization enabled vs disabled. That is eight
    combinations, but on 64 bit machines, a float takes up one word whether
    that float is single or double precision, so two combinations aren't valid.

    Some of the change to this module consists of generalizing the existing
    code so that it can decide simple types not just when targeting .int3 files
    but .int files as well. However, the bulk of it is code for deciding
    the representations of non-simple types. The code is not lifted straight
    from du_type_layout.m. There are two main kinds of changes.

    First, I took the opportunity to simplify the algorithms used.
    For example, while du_type_layout.m passes over each function symbol
    in the most general kind of type twice: once to assign it a cons_tag,
    and once to decide how to pack its arguments, the code here does both jobs
    in one pass. Another example is that for historical reasons,
    du_type_layout.m computed the amount of space needed for an argument
    in one place for sub-word-sized arguments, and in another place
    for more-than-word-sized arguments; decide_type_repn.m does it all
    in one place.

    Second, since we compute a representation for each type six times,
    I tried to avoid obvious inefficiencies, but only if the code
    remained simple. In the future, we may want to use an approach
    based on the idea that in the process of computing the first
    representation, we look out for any indication that the representation
    may be different on any of the other five platforms, and if not,
    we just reuse the first representation on the other five platforms as well.
    However, that would be appropriate only *after* we have a simpler
    system that has proven to work in practice.

    There is a third, smaller change: when deciding whether an argument
    is packable, we take into account not just equivalence type
    definitions, but the definitions of notag types as well.
    This takes advantage of the fact that if a notag type is abstract
    exported, its representation is put into the relevant .int3 file
    even though its definition isn't. (This is why du_type_layout.m
    couldn't "see through" notag types: it couldn't depend on knowing
    which types were notags.)

compiler/prog_item.m:
    Change the types we use for type representation information.
    Their previous definitions baked in the assumption that the only
    distinction between platforms that mattered was the 64 vs 32 bit
    distinction, which is not the case.

    Use a more consistent naming scheme for the types we use
    to represent type representation information.

    Include the "dereferenced" types of the arguments in functors'
    representations. (I use "dereferencing" here to mean expanding
    equivalence types and throwing away any notag wrappers.).
    We don't need it when generating C code using the low level
    data representation, but we do need it to create constructors
    when generating e.g. Java code that uses the high level data
    representation.

compiler/parse_type_repn.m:
    Rewrite most of this module due to the changes in prog_item.m.

compiler/parse_tree_out_type_repn.m:
    A new module containing the code for writing out type representations.
    The original code used to be in parse_tree_out.m, but it has been
    mostly rewritten. Partly this is due the changes in prog_item.m,
    but partly it is to provide much more structured output for humans,
    since this makes debugging so much easier.

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

compiler/parse_tree_out.m:
    Delete the code moved to parse_tree_out_type_repn.m.

compiler/parse_tree_out_info.m:
    Provide a mechanism for selecting between output for machines
    (the default) and output for humans.

compiler/hlds_data.m:
compiler/prog_data.m:
    Move the ptag type from hlds_data.m to prog_data.m, to make it
    accessible in prog_item.m.

    Add some documentation in prog_data.m.

compiler/comp_unit_interface.m:
    If the experiment1 option is enabled, invoke decide_type_repn.m
    to decide what type_repn items to put into the .int file we are
    generating. Otherwise, maintain the status quo.

compiler/write_module_interface_files.m:
    Pass the globals to comp_unit_interface.m so it can look up experiment1.

compiler/equiv_type.m:
    Add a predicate for expanding equivalence types for use by
    decide_type_repn.m. This predicate expands just one type,
    but reports any use of circular equivalence types in that type.

    Improve the error message for circular equivalence types by *naming*
    the type constructors involved. To make this possible, pass around
    sets of such type constructors instead of just a boolean saying
    *whether* we have found *some* circular equivalence type.

    Replace bools used as changed/unchanged flag with a bespoke type.

    Standardize some variable names.

compiler/options.m:
    Add the developer-only option --pack-everything, which, if set,
    tells decide_type_repn.m to turn on all the packing options
    that currently work. This is to allow the testing of decide_type_repn.m
    in the eventual intended mode of operation, even if the various
    allow-packing-... options used by du_type_layout.m are set to "no".

compiler/disj_gen.m:
compiler/equiv_type_hlds.m:
compiler/llds_out_data.m:
compiler/lookup_util.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/mlds_to_c_data.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/tag_switch.m:
    Conform to the changes above (mostly the move of ptag to prog_data.m.)

compiler/parse_pragma.m:
    Improve indentation.

tests/valid_make_int/test_repn.m:
tests/valid_make_int/test_repn_sub.m:
    A fairly comprehensive test case of the new functionality.
    test_repn_sub.m defines one ore more simple type constructors
    of each possible kind, and test_repn.m uses them to define types
    that use each possible kind of complex type representation.

tests/valid_make_int/Mmakefile:
tests/valid_make_int/Mercury.options:
    Enable the new test case.
2020-05-28 07:41:44 +10:00
Zoltan Somogyi
4ef4402ecf Make --warn-inconsistent-pred-order-clauses default for the compiler.
compiler/COMP_FLAGS.in:
    As above.

compiler/Mercury.options:
    List the modules for we need --no-warn-inconsistent-pred-order-clauses
    for now.

compiler/call_gen.m:
compiler/code_util.m:
compiler/deep_profiling.m:
compiler/equiv_type.m:
compiler/error_util.m:
compiler/exprn_aux.m:
compiler/get_dependencies.m:
compiler/global_data.m:
compiler/layout_out.m:
compiler/liveness.m:
compiler/ll_pseudo_type_info.m:
compiler/llds.m:
compiler/llds_out_code_addr.m:
compiler/llds_out_data.m:
compiler/module_cmds.m:
compiler/module_qual.m:
compiler/module_qual.qualify_items.m:
compiler/opt_debug.m:
compiler/parse_class.m:
compiler/parse_goal.m:
compiler/parse_sym_name.m:
compiler/parse_type_defn.m:
compiler/rtti_out.m:
compiler/stack_layout.m:
compiler/trace_gen.m:
    Fix issues reported by --warn-inconsistent-pred-order-clauses
    for these modules.
2019-08-23 18:36:18 +10:00
Zoltan Somogyi
c1bdd2100b Delete unneeded $module args from aborts. 2019-04-16 04:13:35 +10:00
Zoltan Somogyi
d49f6eab84 Add missing imports of parent modules.
These imports were missing from source files, but were included in imported
modules' .int3 files. An upcoming change will delete these from those .int3
files.
2019-03-20 03:57:10 +11:00
Peter Wang
5f7d3e6bb2 Use consistent integer types for some RTTI fields.
runtime/mercury_type_info.h:
    Use unsigned integer types for a few RTTI structure fields that
    are known to hold non-negative values.

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

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

    Encode type ctor flags in a uint16 instead of int.

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

compiler/type_ctor_info.m:
    Conform to type changes.

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

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

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

compiler/ml_util.m:
    Add helper functions.

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

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

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

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

runtime/mercury_dotnet.cs.in:
    Use integer types in RTTI structure definitions for C# that match
    the types in the C versions of the same structures.
2018-11-19 12:37:36 +11:00
Zoltan Somogyi
edac0e9b5c Move sub-word-sized args next to each other ...
... so they can be packed into the same word.
2018-08-31 02:38:26 +10:00
Zoltan Somogyi
d1ec3e3f55 Pack characters as sub-word-sized arguments.
compiler/options.m:
    Add new options --allow-packing-chars and --allow-packing-mini-types,
    for use by developers only.

compiler/du_type_layout.m:
    If the new --allow-packing-chars option is set, then allow characters
    to be packed as sub-word-sized arguments.

    Record the value of the --allow-packing-mini-types in the parameters
    as well, without using it as yet. (That is for a future change.)

    Fix the test for what counts as suboptimal packing. Given an argument
    list such as <sub-word-sized args, word-sized arg, sub-word-sized args>
    where the two lots of sub-word-sized args could fit into a single word,
    the old code did NOT emit a "this is suboptimal" message for it. This
    was because it did not consider a reduction from 2n words to 2n-1 words
    to be significant, as boehm_gc would always round up the number of words
    to (at least) the next multiple of 2. The problem was that the code
    used to apply this test ONLY to the number of words occupied by
    sub-word-sized args. In this case, better packing would make that number
    go from 2 to 1, so it did emit the message, even though the *total*
    number of words in the memory cell would go from 3 to 2.

    We could fix this by applying the round-up-to-even the test to the total
    number of words, but it is simpler to eliminate round-up-to-even entirely.
    This is desirable anyway, since we *should* prefer compresssing e.g.
    a 4 word cell down to 3 if possible, since this would reduce traffic
    to and from (some levels of) cache, even if it would not reduce
    the size of the memory allocation.

    Fix some too-long lines.

compiler/prog_data.m:
    Add fill_char21 as a new kind of fill for sub-word-sized arguments.
    (The 21 is a reminder of the 21 bit size of Unicode chars.)

runtime/mercury_type_info.h:
    Document that fill_char21 arguments are treated the same way as enum args
    in the RTTI.

compiler/hlds_out_module.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_util.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/unify_gen_util.m:
    Conform to the changes above.
2018-08-30 23:26:56 +10:00
Zoltan Somogyi
86f563a94d Pack subword-sized arguments next to a remote sectag.
compiler/du_type_layout.m:
    If the --allow-packing-remote-sectag option is set, then try to pack
    an initial subsequence of subword-sized arguments next to remote sectags.

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

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

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

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

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

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

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

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

compiler/unify_gen_construct.m:
compiler/unify_gen_deconstruct.m:
compiler/unify_gen_test.m:
compiler/unify_gen_util.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
    Implement X = f(Yi) unifications where f uses the new representation,
    i.e. some of its arguments are stored next to a remote sectag.

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

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

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

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

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

    Use more consistent terminology in things such as variable names.

    Note the possibility of further future improvements in several places.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Add some sanity checks.

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

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

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

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

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

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

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

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

tests/debugger/Mmakefile:
tests/hard_coded/Mmakefile:
tests/tabling/Mmakefile:
    Enable the new test cases.
2018-08-30 05:14:38 +10:00
Zoltan Somogyi
66d20fc6d3 Treat apw_partial_first the same as apw_partial_shifted.
Their different treatment was to the root cause of the bug that was fixed
in commit 83336e031e.

compiler/prog_data.m:
    Add a shift field to apw_partial_first. This erases a difference
    from apw_partial_shifted, and prepares for a switch for putting
    sub-word-sized fields into words in most-to-least-significant order.
    Unlike the current least-to-most-significant order, most-to-least-
    significant order should allow compare predicates to compare
    any sequence of consecutive unsigned fields at once, not just
    for equality/inequality, but also for order.

compiler/du_type_layout.m:
    Conform to the changes in prog_data.m. Keep the least-to-most-significant
    allocation order for now.

compiler/unify_gen_construct.m:
compiler/ml_unify_gen_construct.m:
    Model unify_gen_construct.m's handling of the packing of sub-word-sized
    arguments into a word on the approach used by (three quarters of)
    ml_unify_gen_construct.m, since that was the cleaner, more uniform
    approach, which already treated apw_partial_first the same as
    apw_partial_shifted. (The fix of the remaining quarter is for
    a separate change.)

compiler/unify_gen_util.m:
compiler/ml_unify_gen_util.m:
    Make the left shift operations operate exclusively on word-sized unsigned
    numbers, as the updated code of {ml_,}unify_gen_construct.m now expect.

    Optimize away shifts of zeros regardless of the size or signednesses
    of that zero.

compiler/ml_unify_gen_deconstruct.m:
compiler/unify_gen_deconstruct.m:
    Make a start on harmonizing variable names.

    Conform to the changes in prog_data.m.

compiler/hlds_out_module.m:
compiler/lco.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
    Conform to the changes in prog_data.m.
2018-07-14 03:48:23 +02:00
Zoltan Somogyi
624aaa01f1 Pack subword-sized arguments next to a local sectag.
compiler/du_type_layout.m:
    If a new option is set, then try to represent function symbols with
    only subword-sized arguments by packing those arguments into the same word
    as the primary tag and (if it is needed) a secondary tag.

    If there are too many such function symbols for the available number of
    bits, pick the ones that need the least number of bits, in order to
    allow us to use this representation for as many such function symbols
    as possible.

    This diff implements this packing only for types that have more than one
    argument, because implementing it for types that have only one argument
    has two extra complications. One is the need for another new cons_id
    (see below), which would make this diff bigger and harder to review.
    The other is the need to consider interactions with the direct_arg
    optimization.

    Don't invoke the code for deciding the representation of arguments
    if either (a) the function symbol has no arguments, or (b) its cons_id
    alone dictates how we will treat its argument (in such cases, there is
    always exactly one).

    Fix a bug in computing the number of bits needed to distinguish N things.

    Store the value of the "experiment" option in the params for now,
    since it has helped track down bugs in this change, and may do the same
    for my next change. It costs next to nothing.

compiler/options.m:
    Add an option that controls whether we allow du_type_layout to pack
    arguments next to local secondary tags. The default value is "no",
    since "yes" may break binary compatibility.

    Add an option that controls whether we allow du_type_layout to pack
    arguments next to remote secondary tags. This option is not yet used.

compiler/hlds_data.m:
    Add a new cons_id, shared_local_tag_with_args, to represent function
    symbols in which the arguments are packed next to a local secondary tag.
    Rename the existing shared_local_tag cons_id as shared_local_tag_no_args,
    to clarify the distinction.

    Redesign the representation of secondary tags a bit, to meet the
    requirements I discovered while implementing the new data representation.

compiler/prog_data.m:
    Document the now-expanded uses of the arg_pos_width type.

compiler/ml_unify_gen.m:
compiler/unify_gen.m:
    Implement unifications involving the new cons_id.

compiler/var_locn.m:
    Implement deconstruction unifications involving both right-to-left data
    flow and the new cons_id for the LLDS backend requires var_locn.m
    to implement a new kind of assignment to a variable: one that updates
    its old value. Add a predicate for this. (Previously, deconstructions
    with right-to-left flow could update the old value of a word in a
    memory cell, whose state var_locn.m does *not* track.)

compiler/code_loc_dep.m:
    Provide the interface between unify_gen. and var_locn.m.

compiler/code_info.m:
    Store the number of primary tag bits in the code_info, to save it looking
    up in the globals structure, since with its new code, unify_gen.m needs it
    more often now.

compiler/hlds_out_module.m:
doc/user_guide.texi:
    Implement the capability of restricting the dump of the type table
    to only the types defined in the module being compiled. Without this,
    the type table is cluttered with information about types in other
    modules, including the automatically-included builtin modules.

compiler/handle_options.m:
    Add a new value of the -D option. The new value, du, asks for the
    dumping out of the representations of only the locally defined types.

compiler/ml_gen_info.m:
    Store the number of primary tag bits as a uint8, not as int.

compiler/ml_tag_switch.m:
compiler/switch_util.m:
compiler/tag_switch.m:
    Update the code that generates switches on du types to handle
    local secondary tags that must be masked off before use.

compiler/rtti.m:
    Update the compiler's representation of RTTI information to account for
    the new data representation.

compiler/type_ctor_info.m:
    Construct the updated RTTI representation.

compiler/bytecode_gen.m:
compiler/export.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/modecheck_goal.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
    Conform for the changes above.

runtime/mercury_type_info.h:
    Extend the representation of du functors in the RTTI to account for
    the new data representation scheme. The extensions add only to the
    *ends* of structures, or to lists of enum values, with the extensions
    only being used if the representation is actually used, which should
    allow the updated runtime to also work with .c files that were compiled
    with a compiler that does *not* have this diff. For the same reason,
    make the old enum value MR_SECTAG_LOCAL a synonym for the new
    MR_SECTAG_LOCAL_REST_OF_WORD, which expresses a distinction that
    did not previously exist.

    Delete a reference to a file that no longer exists.

runtime/mercury_dotnet.cs.in:
library/rtti_implementation.m:
    Update the C# and Mercury mirrors of the types updated in
    mercury_type_info.h.

runtime/mercury_deconstruct.c:
runtime/mercury_deconstruct_macros.h:
runtime/mercury_ml_expand_body.h:
    Implement the deconstruction of terms using the new data representation.

runtime/mercury_deep_copy_body.h:
    Implement the copying of terms using the new data representation.

runtime/mercury_table_type_body.h:
    Implement the tabling of terms using the new data representation.

runtime/mercury_term_size.c:
    Implement computing the size of terms using the new data representation.

runtime/mercury_unify_compare_body.h:
    Implement RTTI-based unifications of terms using the new data
    representation. (Or at least make a first attempt at this implementation.
    We never use RTTI-based unification, so this code has not been tested,
    but it is not clear that it *needs* to be tested.)

library/construct.m:
    Implement the construction of terms using the new data representation.

library/private_builtin.m:
    List MR_SECTAG_LOCAL_REST_OF_WORD as a synonym of MR_SECTAG_LOCAL for Java,
    since rtti_to_mlds.m will now emit the new version.

    Note that the new data representation is not applicable to Java (or C#),
    so it should never see the other kind of sectag (MR_SECTAG_LOCAL_BITS).

tests/hard_coded/sectag_bits.{m,exp}:
tests/hard_coded/sectag_bits_test_data:
    A new test case to test the reading in and writing out (and therefore
    the construction and deconstruction) of terms containing arguments
    packed with a local sectag.

tests/hard_coded/Mmakefile:
    Enable the new test case.
2018-07-08 17:54:11 +02:00
Zoltan Somogyi
b06b2621b3 Move towards packing args with secondary tags.
compiler/hlds_data.m:
    Add bespoke types to record information about local and remote secondary
    tags. The one for local secondary tags includes the value of the
    primary and secondary tag together, since construct unifications
    need to assign this value, and it is better to compute this once,
    instead leaving the target language compiler to do it, potentially
    many times.

    Use a wrapped uint8 to record primary tag values, and wrapped uints
    to record secondary tag values. The wrap is to prevent any accidental
    confusion with other values. The use of uint8 and uint has two purposes.
    First, using the tighest possible representation. Tags are never negative,
    and primary tags cannot exceed 7. Second, using these types in the compiler
    help us eat our own dogfood; if a change causes a problem affecting
    these types, its bootcheck should fail, alerting us to the problem.

    Add commented-out types and fields that will be needed for packing
    sub-word-sized arguments together with both local and remote secondary
    tags.

compiler/du_type_layout.m:
    Generate references to tags in the new format.

compiler/ml_unify_gen.m:
compiler/unify_gen.m:

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

    Fix an old bug: the inst corresponding to a constant with a primary
    and a local secondary tag is not the secondary tag alone, but both tags
    together.

compiler/bytecode.m:
compiler/bytecode_gen.m:
compiler/closure_gen.m:
compiler/disj_gen.m:
compiler/export.m:
compiler/hlds_code_util.m:
compiler/jumpopt.m:
compiler/lco.m:
compiler/llds_out_data.m:
compiler/llds_out_instr.m:
compiler/lookup_switch.m:
compiler/lookup_util.m:
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_type_gen.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_stmt.m:
compiler/opt_debug.m:
compiler/peephole.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/string_switch.m:
compiler/switch_util.m:
compiler/tag_switch.m:
compiler/type_ctor_info.m:
    Conform to the change to hlds_data.m.

    In two places, in rtti_out.m and rtti_to_mlds.m, delete old code
    that was needed only to implement reserved tags, which we have
    stopped supporting a few months ago.

library/uint8.m:
library/uint16.m:
library/uint32.m:
library/uint64.m:
    Add predicates to cast from each of these types to uint.
2018-06-06 03:35:20 +02:00
Zoltan Somogyi
24b98fdafe Pack sub-word-sized ints and dummies in terms.
Previously, the only situation in which we could pack two or more arguments
of a term into a single word was when all those arguments are enums. This diff
changes that, so that the arguments can also be sub-word-sized integers
(signed or unsigned), or values of dummy types (which occupy zero bits).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Handle the new dummy_tag.

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

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

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

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

    Delete an unused predicate.

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

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

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

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

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

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

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

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

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

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

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

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

    Conform to the changes above.

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

    Add notes about possible optimizations.

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

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

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

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

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

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

    Generate slightly better formatted output.

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

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

    Conform to the changes above.

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

compiler/llds_out_util.m:
    Add a comment.

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

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

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

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

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

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

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

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

    Give a macro a more descriptive name.

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

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

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

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

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

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

tests/hard_coded/Mmakefile:
    Enable the new test case.
2018-05-05 13:22:19 +02:00
Zoltan Somogyi
4b98f58d9d Don't use reserved addresses to represent functors.
Late last year, we agreed to delete the ability to use the addresses
of reserved objects as cons_tags. After another (very short) discussion
on m-dev, this diff also deletes the ability to use small integers
(including zero) acting as pointers.

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

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

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

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

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

compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/bytecode_gen.m:
compiler/code_info.m:
compiler/du_type_layout.m:
compiler/equiv_type_hlds.m:
compiler/erl_rtti.m:
compiler/export.m:
compiler/hlds_out_module.m:
compiler/intermod.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/opt_debug.m:
compiler/prog_data.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_gen.m:
    Conform to the changes above, mostly by deleting code that used to deal
    with reserved addresses.
2018-02-06 16:03:44 +11:00
Zoltan Somogyi
fb97df69ed Make "compute type representations" a separate pass.
The ultimate purpose of this diff is to prepare for future improvements
in type representations, allowing values of some data types to be represented
more compactly than up to now.

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

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

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

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

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

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

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

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

    Fix a bad dump stage name.

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

    Make a sub-switch explicit.

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

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

    Delete some forwarding predicates that are no longer needed.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Delete the reserve_tag pragma.

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

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

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

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

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

    Provide some utility predicates.

    Optimize some existing predicates.

    Rename some types to better reflect their meaning.

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

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

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

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

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

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

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

    Move the module from the make_hlds to the hlds package.

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

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

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

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

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

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

    Delete a type moved to type_util.m.

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

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

    Give some predicates more meaningful names.

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

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

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

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

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

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

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

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

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

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

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

    Give some predicates and function symbols more meaningful names.

    Note some problems with the existing code.

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

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

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

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

tests/valid/Mmake.valid.common:
tests/valid/Mmakefile:
    Disable any reserve_tag test cases, as they are not applicable anymore.
2018-01-31 17:54:40 +11:00
Zoltan Somogyi
47f1df4a0a Split mlds_data_defn into three separate types.
We used to use mlds_data_defns to represent three related but nevertheless
distinct kinds of entities: global variables, local variables, and fields
in classes. This diff replaces the mlds_data_defn type with three separate
types: mlds_global_var_defn, mlds_local_var_defn and mlds_field_var_defn
respectively, with corresponding changes to related types, such as
mlds_data_name.

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

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

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

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

    Use tighter types where possible.

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

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

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

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

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

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

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

    Use tighter types where possible.

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

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

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

    Move a utility function from ml_util.m to mlds_to_target_util.m,
    since it is used only in mlds_to_*.m.
2017-07-22 00:20:40 +02:00
Zoltan Somogyi
b96dacdcac Make a bunch of switches complete.
compiler/exception_analysis.m:
compiler/frameopt.m:
compiler/get_dependencies.m:
compiler/labelopt.m:
compiler/ml_global_data.m:
compiler/ml_optimize.m:
compiler/options_file.m:
compiler/parse_class.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/type_util.m:
compiler/var_locn.m:
    As above.

compiler/inst_match.m:
    Fix a stray piece of code.

compiler/loop_inv.m:
    Add a module qualification.

compiler/opt_util.m:
    Delete two unused predicates.
2017-03-09 13:43:48 +11:00
Zoltan Somogyi
31ad78c1a9 Make c_util.m and file_util.m use explicit streams.
compiler/c_util.m:
compiler/file_util.m:
    Replace every predicate that implicitly wrote to the current output stream
    with two predicates: a predicate with the old name that takes an explicit
    output stream parameter, and a predicate that still writes to the current
    output stream, but whose name makes this fact clear.

    Make some other minor improvements.

compiler/bytecode.m:
compiler/elds_to_erlang.m:
compiler/export.m:
compiler/fact_table.m:
compiler/layout_out.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_global.m:
compiler/llds_out_instr.m:
compiler/llds_out_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_out.m:
    Conform to the changes above.
2016-09-06 20:01:14 +10:00
Mark Brown
3acbf03059 Implement combined higher-order types and insts.
These allow types to be defined in the following manner:

    :- type job ---> job(pred(int::out, io::di, io::uo) is det).

For any construction unification using this functor the argument must
have the required higher-order inst; it is a mode error if it does not.
When terms of type job with inst ground are deconstructed, the argument
is inferred to have the given inst, allowing a higher-order call in that
mode.

The new type syntax is currently only permitted as the direct argument of
a functor in a du type definition. In future it would be meaningful to
support this syntax in other locations, but that is left for a separate
change.

In order to correctly implement the construct/3 library predicate, we
need to be able to dynamically check that arguments do not violate
any constraints on the argument insts. At the moment, we conservatively
abort if any such constraints are present irrespective of whether they
are satisfied or not. Since these constraints are a new feature, no
existing code will abort in this way.

The implementation refers to the inst information associated with types
as "subtype information". This is because, generally, we think of the
combination of a type with a fully bound inst (i.e., one that describes
terms that contain no unbound variables) describes a subtype of that type.

compiler/inst_util.m:
	Ensure that arguments have the necessary insts in construction
	unifications.

	Where available, propagate the insts into arguments rather than
	using ground(shared, none).

compiler/prog_io_type_name.m:
	Parse the new form of types.

compiler/unparse.m:
	Unparse the new form of types.

compiler/prog_io_type_defn.m:
	Allow the new form of types in functor arguments.

compiler/prog_ctgc.m:
compiler/prog_io_item.m:
compiler/prog_io_mutable.m:
compiler/prog_io_pragma.m:
compiler/prog_io_typeclass.m:
compiler/superhomogeneous.m:
	Disallow the new form of types in places other than functor
	arguments.

compiler/prog_data.m:
	Go back to representing function types with result type appended
	to the arguments. In most case this now results in simpler code.

compiler/prog_type.m:
	Abstract away the representation of predicate vs function arguments
	by using a predicate to construct these types.

compiler/rtti.m:
compiler/type_ctor_info.m:
	Include subtype information about the arguments of a du functor
	and about the argument of a notag functor. Generate this
	information from the argument types.

	Currently, the information is one bit which says whether or not
	any subtypes exist in the arguments.

	Bump the RTTI version number from the compiler side.

compiler/rtti_out.m:
	Output functor subtype information for the low-level C backend.

compiler/rtti_to_mlds.m:
	Include functor subtype information in the MLDS.

compiler/mlds_to_cs.m:
	Add the new runtime type to the special cases.

compiler/erl_rtti.m:
compiler/erlang_rtti.m:
library/erlang_rtti_implementation.m:
	Include functor subtype info in the erlang RTTI.

java/runtime/DuFunctorDesc.java:
java/runtime/FunctorSubtypeInfo.java:
	Include functor subtype information in the Java runtime.

runtime/mercury_dotnet.cs.in:
	Include functor subtype information in the C# runtime.

runtime/mercury_type_info.h:
	Include functor subtype information in the C runtime.

	Bump the RTTI version number in the runtime.

	Define macros to access the new field. These macros can correctly
	handle the previous RTTI version, therefore we do not need to
	change the minimum version at this time.

library/private_builtin.m:
	Define constants for use by the Java backend.

library/construct.m:
library/rtti_implementation.m:
	Use the new RTTI to ensure we don't attempt to construct terms
	that violate the new insts.

compiler/prog_rep_tables.m:
	Ignore the new inst info for now.

compiler/*.m:
	Changes to conform to above.

doc/reference_manual.texi:
	Document the new feature.

tests/hard_coded/functor_ho_inst.{m,exp}:
tests/hard_coded/functor_ho_inst_2.{m,exp}:
tests/hard_coded/functor_ho_inst_excp.{m,exp}:
tests/hard_coded/functor_ho_inst_excp_2.{m,exp}:
	Test the new functionality.

tests/invalid/combined_ho_type_inst.{m,err_exp}:
tests/invalid/combined_ho_type_inst_2.{m,err_exp}:
	Test that we don't allow the new types where they are not permitted,
	or are incomplete.

tests/invalid/functor_ho_inst_bad.{m,err_exp}:
tests/invalid/functor_ho_inst_bad_2.{m,err_exp}:
tests/invalid/functor_ho_inst_bad_3.{m,err_exp}:
	Test that the argument inst information is enforced as required.

tests/hard_coded/Mmakefile:
tests/invalid/Mmakefile:
	Run the new test cases.
2016-02-08 16:09:01 +11:00
Zoltan Somogyi
3cb166eb07 Delete some unused predicates; add consider_used pragmas for some others. 2015-12-29 01:50:46 +11:00
Zoltan Somogyi
cc9912faa8 Don't import anything in packages.
Packages are modules whose only job is to serve as a container for submodules.
Modules like top_level.m, hlds.m, parse_tree.m and ll_backend.m are packages
in this (informal) sense.

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

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

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

This diff removes all import_module declarations from the packages,
and replaces them with import_module declarations in the modules that need
them. This includes only a SUBSET of their child modules and of the non-child
modules that import them.
2015-11-13 15:03:20 +11:00
Zoltan Somogyi
58e34cbbfa Convert (C->T;E) to (if C then T else E). 2015-10-23 11:15:53 +11: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
16bd4acd2f Shorten lines longer than 79 characters.
Estimated hours taken: 2
Branches: main

compiler/*.m:
	Shorten lines longer than 79 characters.
2012-10-24 05:49:47 +00:00
Peter Wang
257efbd678 Store double-precision `float' constructor arguments in unboxed form,
Branches: main

Store double-precision `float' constructor arguments in unboxed form,
in high-level C grades on 32-bit platforms, i.e. `float' (and equivalent)
arguments may occupy two machine words.

As the C code generated by the MLDS back-end makes use of MR_Float variables
and parameters, float (un)boxing may be reduced substantially in many programs.

compiler/prog_data.m:
	Add `double_word' as a new option for constructor argument widths,
	only used for float arguments as yet.

compiler/make_hlds_passes.m:
	Set constructor arguments to have `double_word' width if required,
	and possible.

compiler/type_util.m:
	Add helper predicate.

compiler/builtin_ops.m:
compiler/c_util.m:
compiler/llds.m:
	Add two new binary operators used by the MLDS back-end.

compiler/arg_pack.m:
	Handle `double_word' arguments.

compiler/ml_code_util.m:
	Deciding whether or not a float constructor argument requires boxing
	now depends on the width of the field.

compiler/ml_global_data.m:
	When a float constant appears as an initialiser of a generic array
	element, it is now always unboxed, irrespective of --unboxed-float.

compiler/ml_type_gen.m:
	Take double-word arguments into account when generating structure
	fields.

compiler/ml_unify_gen.m:
	Handle double-word float constructor arguments in (de)constructions.
	In some cases we break a float argument into its two words, so
	generating two assignments statements or two separate rvals.

	Take double-word arguments into account when calculating field offsets.

compiler/mlds_to_c.m:
	The new binary operators require no changes here.

	As a special case, write `MR_float_from_dword_ptr(&X)' instead of
	`MR_float_from_dword(X, Y)' when X, Y are consecutive words within a
	field. The definition of `MR_float_from_dword_ptr' is more
	straightforward, and gcc produces better code than if we use the more
	general `MR_float_from_dword'.

compiler/rtti_out.m:
	For double-word arguments, generate MR_DuArgLocn structures with
	MR_arg_bits set to -1.

compiler/rtti_to_mlds.m:
	Handle double-word arguments in field offset calculation.

compiler/unify_gen.m:
	Partially handle double_word arguments in LLDS back-end.

compiler/handle_options.m:
	Set --unboxed-float when targetting Java, C# and Erlang.

compiler/structure_reuse.direct.choose_reuse.m:
	Rename a predicate.

compiler/bytecode.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/llds_to_x86_64.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/opt_debug.m:
	Conform to changes.

library/construct.m:
library/store.m:
	Handle double-word constructor arguments.

runtime/mercury_conf.h.in:
	Clarify what `MR_BOXED_FLOAT' now means.

runtime/mercury_float.h:
	Add helper macros for converting between doubles and word/dwords.

runtime/mercury_deconstruct.c:
runtime/mercury_deconstruct.h:
	Add a macro `MR_arg_value' and a helper function to extract a
	constructor argument value.  This replaces `MR_unpack_arg'.

runtime/mercury_type_info.h:
	Remove `MR_unpack_arg'.

	Document that MR_DuArgLocn.MR_arg_bits may be -1.

runtime/mercury_deconstruct_macros.h:
runtime/mercury_deep_copy_body.h:
runtime/mercury_ml_arg_body.h:
runtime/mercury_table_type_body.h:
runtime/mercury_tabling.c:
runtime/mercury_type_info.c:
	Handle double-word constructor arguments.

tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/lco_double.exp:
tests/hard_coded/lco_double.m:
tests/hard_coded/pack_args_float.exp:
tests/hard_coded/pack_args_float.m:
	Add test cases.

trace/mercury_trace_vars.c:
	Conform to changes.
2011-09-06 05:20:45 +00:00
Peter Wang
64bb189f34 Fix bug #204. Deconstruct of packed arguments was broken due to a mistake in
Branches: main

Fix bug #204.  Deconstruct of packed arguments was broken due to a mistake in
the RTTI tables.

compiler/prog_data.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
	Correct the computation of the number of bits occupied by a packed
	argument, given the bit-mask.

tests/hard_coded/Mmakefile:
tests/hard_coded/zinc_pack_bug.exp:
tests/hard_coded/zinc_pack_bug.m:
	Add test case.
2011-07-13 00:41:22 +00:00
Peter Wang
0ae65de577 Pack consecutive enumeration arguments in discriminated union types into a
Branches: main

Pack consecutive enumeration arguments in discriminated union types into a
single word to reduce cell sizes.  Argument packing is only enabled on C
back-ends with low-level data, and reordering arguments to improve
opportunities for packing is not yet attempted.  The RTTI implementations for
other back-ends will need to be updated, but that is best left until after any
argument reordering change.

Modules which import abstract enumeration types are notified so by writing
declarations of the form:

	:- type foo where type_is_abstract_enum(NumBits).

into the interface file for the module which defines the type.


compiler/prog_data.m:
	Add an `arg_width' argument to constructor arguments.

	Replace `is_solver_type' by `abstract_type_details', with an extra
	option for abstract exported enumeration types.

compiler/handle_options.m:
compiler/options.m:
	Add an internal option `--allow-argument-packing'.

compiler/make_hlds_passes.m:
	Determine whether and how to pack enumeration arguments, updating the
	`arg_width' fields of constructor arguments before constructors are
	added to the HLDS.

compiler/mercury_to_mercury.m:
compiler/modules.m:
	Write `where type_is_abstract_enum(NumBits)' to interface files
	for abstract exported enumeration types.

compiler/prog_io_type_defn.m:
	Parse `where type_is_abstract_enum(NumBits)' attributes on type
	definitions.

compiler/arg_pack.m:
compiler/backend_libs.m:
	Add a new module.  This mainly contains a predicate which packs rvals
	according to arg_widths, which is used by both LLDS and MLDS back-ends.

compiler/ml_unify_gen.m:
compiler/unify_gen.m:
	Take argument packing into account when generating code for
	constructions and deconstructions.  Only a relatively small part of the
	compiler actually needs to understand argument packing.  The rest works
	at the HLDS level with constructor arguments and variables, or at the
	LLDS and MLDS levels with structure fields.

compiler/code_info.m:
compiler/var_locn.m:
	Add assign_field_lval_expr_to_var and
	var_locn_assign_field_lval_expr_to_var.

	Allow more kinds of rvals in assign_cell_arg.  I do not know why it was
	previously restricted, except that the other kinds of rvals were not
	encountered as cell arguments before.

compiler/mlds.m:
	We can now rely on the compiler to pack arguments in the
	mlds_decl_flags type instead of doing it manually.  A slight downside
	is that though the type is packed down to a single word cell, it will
	still incur a memory allocation per cell.  However, I did not notice
	any difference in compiler speed.

compiler/rtti.m:
compiler/rtti_out.m:
	Add and output a new field for MR_DuFunctorDesc instances, which, if
	any arguments are packed, points to an array of MR_DuArgLocn.  Each
	array element describes the offset in the cell at which the argument's
	value is held, and which bits of the word it occupies.  In the more
	common case where no arguments are packed, the new field is simply
	null.

compiler/rtti_to_mlds.m:
	Generate the new field to MR_DuFunctorDesc.

compiler/structure_reuse.direct.choose_reuse.m:
	For now, prevent structure reuse reusing a dead cell which has a
	different constructor to the new cell.  The code to determine whether a
	dead cell will hold the arguments of a new cell with a different
	constructor will need to be updated to account for argument packing.

compiler/type_ctor_info.m:
	Bump RTTI version number.

	Conform to changes.

compiler/add_type.m:
compiler/check_typeclass.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/erl_rtti.m:
compiler/hlds_data.m:
compiler/hlds_out_module.m:
compiler/intermod.m:
compiler/make_tags.m:
compiler/mlds_to_gcc.m:
compiler/opt_debug.m:
compiler/prog_type.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/special_pred.m:
compiler/type_constraints.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/xml_documentation.m:
	Conform to changes.

	Reduce code duplication in classify_type_defn.

compiler/hlds_goal.m:
	Clarify a comment.

library/construct.m:
	Make `construct' pack arguments when necessary.

	Remove an old RTTI version number check as recommended in
	mercury_grade.h.

library/store.m:
	Deal with packed arguments in this module.

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

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

	Add MR_DuArgLocn structure definition.

	Add a macro to unpack an argument as described by MR_DuArgLocn.

	Add a function to determine a cell's size, since the number of
	arguments is no longer correct.

runtime/mercury_deconstruct.c:
runtime/mercury_deconstruct.h:
runtime/mercury_deconstruct_macros.h:
runtime/mercury_ml_arg_body.h:
runtime/mercury_ml_expand_body.h:
	Deal with packed arguments when deconstructing.

	Remove an old RTTI version number check as recommended in
	mercury_grade.h.

runtime/mercury_deep_copy_body.h:
	Deal with packed arguments when copying.

runtime/mercury_table_type_body.h:
	Deal with packed arguments in tabling.

runtime/mercury_dotnet.cs.in:
	Add DuArgLocn field to DuFunctorDesc. Argument packing is not enabled
	for the C# back-end yet so this is unused.

trace/mercury_trace_vars.c:
	Deal with packed arguments in MR_select_specified_subterm,
	use for the `hold' command.

java/runtime/DuArgLocn.java:
java/runtime/DuFunctorDesc.java:
	Add DuArgLocn field to DuFunctorDesc. Argument packing is not enabled
	for the Java back-end yet so this is unused.

extras/trailed_update/tr_store.m:
	Deal with packed arguments in this module (untested).

extras/trailed_update/samples/interpreter.m:
extras/trailed_update/tr_array.m:
	Conform to argument reordering in the array, map and other modules in
	previous changes.

tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/lco_pack_args.exp:
tests/hard_coded/lco_pack_args.m:
tests/hard_coded/pack_args.exp:
tests/hard_coded/pack_args.m:
tests/hard_coded/pack_args_copy.exp:
tests/hard_coded/pack_args_copy.m:
tests/hard_coded/pack_args_intermod1.exp:
tests/hard_coded/pack_args_intermod1.m:
tests/hard_coded/pack_args_intermod2.m:
tests/hard_coded/pack_args_reuse.exp:
tests/hard_coded/pack_args_reuse.m:
tests/hard_coded/store_ref.exp:
tests/hard_coded/store_ref.m:
tests/invalid/Mmakefile:
tests/invalid/where_abstract_enum.err_exp:
tests/invalid/where_abstract_enum.m:
tests/tabling/Mmakefile:
tests/tabling/pack_args_memo.exp:
tests/tabling/pack_args_memo.m:
	Add new test cases.

tests/hard_coded/deconstruct_arg.exp:
tests/hard_coded/deconstruct_arg.exp2:
tests/hard_coded/deconstruct_arg.m:
	Add constructors with packed arguments to these cases.

tests/invalid/where_direct_arg.err_exp:
	Update expected output.
2011-07-05 03:34:39 +00:00
Peter Wang
12281f3419 Implement a type representation optimisation ("direct argument functors"),
Branches: main

Implement a type representation optimisation ("direct argument functors"),
where a functor with exactly one argument can be represented by a tagged
pointer to the argument value, which itself does not require the tag bits,
e.g.

	:- type maybe_foo ---> yes(foo) ; no.
	:- type foo       ---> foo(int, int).  % aligned pointer

To ensure that all modules which could construct or deconstruct the functor
agree on the type representation, I had planned to automatically output
extra information to .int files to notify importing modules about functors
using the optimised representation:

	:- type maybe_foo ---> yes(foo) ; no
		where direct_arg is [yes/1].

However, the compiler does not perform enough (or any) semantic analysis
while making interface files.  The fallback solution is to only use the
optimised representation when all importing modules can be guaranteed to
import both the top-level type and the argument type, namely, when both
types are exported from the same module.  We also allow certain built-in
argument types; currently this only includes tuples.

Non-exported types may use the optimised representation, but when
intermodule optimisation is enabled, they may be written out to .opt files.
Then, we *do* add direct_arg attributes to .opt files to ensure that importing
modules agree on the type representation.  The attributes may also be added by
Mercury programmers to source files, which will be copied directly into .int
files without analysis.  They will be checked when the module is actually
compiled.

This patch includes work by Zoltan, who independently implemented a version
of this change.


compiler/hlds_data.m:
	Record the direct arg functors in hlds_du_type.

	Add a new option to cons_tag.

	Fix some comments.

compiler/prog_data.m:
compiler/prog_io_type_defn.m:
	Parse and record `direct_arg' attributes on type definitions.

compiler/prog_io_pragma.m:
	Issue an error if the `direct_arg' attribute is used with a foreign
	type.

compiler/make_tags.m:
compiler/mercury_compile_front_end.m:
	Add a pass to convert suitable functors to use the direct argument
	representation.  The argument type must have been added to the type
	table, so we do this after all type definitions have been added.

	Move code to compute cheaper_tag_test here.

compiler/ml_unify_gen.m:
compiler/unify_gen.m:
	Generate different code to construct/deconstruct direct argument
	functors.

compiler/intermod.m:
	Write `direct_arg' attributes to .opt files for functors
	using the direct argument representation.

compiler/mercury_to_mercury.m:
	Write out `direct_arg' attributes.

compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
	Add an option to the types which describe the location of secondary
	tag options. The functors which can use the optimised representation
	are a subset of those which require no secondary tag.

	Output "MR_SECTAG_NONE_DIRECT_ARG" instead of "MR_SECTAG_NONE" in
	RTTI structures when applicable.

compiler/add_pragma.m:
compiler/add_type.m:
compiler/bytecode_gen.m:
compiler/check_typeclass.m
compiler/code_info.m:
compiler/equiv_type.m:
compiler/export.m:
compiler/foreign.m:
compiler/hlds_code_util.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/ml_proc_gen.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_type_gen.m:
compiler/module_qual.m:
compiler/modules.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/simplify.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/tag_switch.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
	Conform to changes.

	Bump RTTI version number.

doc/reference_manual.texi:
	Add commented out documentation for `direct_arg' attributes.

library/construct.m:
	Handle MR_SECTAG_NONE_DIRECT_ARG in construct.construct/3.

library/private_builtin.m:
	Add MR_SECTAG_NONE_DIRECT_ARG constant for Java for consistency,
	though it won't be used.

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

runtime/mercury_type_info.h:
	Bump RTTI version number.

	Add MR_SECTAG_NONE_DIRECT_ARG.

runtime/mercury_deconstruct.c:
runtime/mercury_deep_copy_body.h:
runtime/mercury_ml_expand_body.h:
runtime/mercury_table_type_body.h:
runtime/mercury_term_size.c:
runtime/mercury_unify_compare_body.h:
	Handle MR_SECTAG_NONE_DIRECT_ARG in RTTI code.

tests/debugger/Mmakefile:
tests/debugger/chooser_tag_test.exp:
tests/debugger/chooser_tag_test.inp:
tests/debugger/chooser_tag_test.m:
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/construct_test.exp:
tests/hard_coded/construct_test.m:
tests/hard_coded/direct_arg_cyclic1.exp:
tests/hard_coded/direct_arg_cyclic1.m:
tests/hard_coded/direct_arg_cyclic2.m:
tests/hard_coded/direct_arg_cyclic3.m:
tests/hard_coded/direct_arg_intermod1.exp:
tests/hard_coded/direct_arg_intermod1.m:
tests/hard_coded/direct_arg_intermod2.m:
tests/hard_coded/direct_arg_intermod3.m:
tests/hard_coded/direct_arg_parent.exp:
tests/hard_coded/direct_arg_parent.m:
tests/hard_coded/direct_arg_sub.m:
tests/invalid/Mmakefile:
tests/invalid/where_direct_arg.err_exp:
tests/invalid/where_direct_arg.m:
tests/invalid/where_direct_arg2.err_exp:
tests/invalid/where_direct_arg2.m:
	Add test cases.

tests/invalid/ee_invalid.err_exp:
	Update expected output.
2011-06-16 06:42:19 +00:00
Zoltan Somogyi
295415090e Convert almost all remaining modules in the compiler to use
Estimated hours taken: 6
Branches: main

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

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

tests/invalid/unresolved_overloading.err_exp:
	Update an expected output containing an updated error message.
2011-05-23 05:08:24 +00:00
Julien Fischer
9f68c330f0 Change the argument order of many of the predicates in the map, bimap, and
Branches: main

Change the argument order of many of the predicates in the map, bimap, and
multi_map modules so they are more conducive to the use of state variable
notation, i.e. make the order the same as in the sv* modules.

Prepare for the deprecation of the sv{bimap,map,multi_map} modules by
removing their use throughout the system.

library/bimap.m:
library/map.m:
library/multi_map.m:
	As above.
NEWS:
	Announce the change.

	Separate out the "highlights" from the "detailed listing" for
	the post-11.01 NEWS.

	Reorganise the announcement of the Unicode support.

benchmarks/*/*.m:
browser/*.m:
compiler/*.m:
deep_profiler/*.m:
extras/*/*.m:
mdbcomp/*.m:
profiler/*.m:
tests/*/*.m:
ssdb/*.m:
samples/*/*.m
slice/*.m:
	Conform to the above change.

	Remove any dependencies on the sv{bimap,map,multi_map} modules.
2011-05-03 04:35:04 +00:00
Zoltan Somogyi
1c3bc03415 Make the system compiler with --warn-unused-imports.
Estimated hours taken: 2
Branches: main, release

Make the system compiler with --warn-unused-imports.

browser/*.m:
library/*.m:
compiler/*.m:
	Remove unnecesary imports as flagged by --warn-unused-imports.

	In some files, do some minor cleanup along the way.
2010-12-30 11:18:04 +00:00
Zoltan Somogyi
8a28e40c9b Add the predicates sorry, unexpected and expect to library/error.m.
Estimated hours taken: 2
Branches: main

Add the predicates sorry, unexpected and expect to library/error.m.

compiler/compiler_util.m:
library/error.m:
	Move the predicates sorry, unexpected and expect from compiler_util
	to error.

	Put the predicates in error.m into the same order as their
	declarations.

compiler/*.m:
	Change imports as needed.

compiler/lp.m:
compiler/lp_rational.m:
	Change imports as needed, and some minor cleanups.

deep_profiler/*.m:
	Switch to using the new library predicates, instead of calling error
	directly. Some other minor cleanups.

NEWS:
	Mention the new predicates in the standard library.
2010-12-15 06:30:36 +00:00
Zoltan Somogyi
30aafc69a0 Split up three big compiler modules: llds_out.m, hlds_out.m (5000+ lines each)
Estimated hours taken: 12
Branches: main

Split up three big compiler modules: llds_out.m, hlds_out.m (5000+ lines each)
and deep_profiling.m (3000+ lines). Put the predicates in the resulting
smaller modules into cohesive groups where possible. A few of the predicates
in the original modules were unused; this diff deletes them.

There are no algorithmic changes.

compiler/llds_out_code_addr.m:
	New module containing the part of llds_out.m that outputs
	code addresses and labels.

compiler/llds_out_data.m:
	New module containing the part of llds_out.m that outputs
	lvals, rvals and their components.

compiler/llds_out_global.m:
	New module containing the part of llds_out.m that generates
	global static C data structures.

compiler/llds_out_instr.m:
	New module containing the part of llds_out.m that outputs
	instructions

compiler/llds_out_file.m:
	New module containing the top level part of llds_out.m,
	which coordinates the generation of a whole C source file.

compiler/llds_out_util.m:
	New module containing the utility parts of llds_out.m.

compiler/llds_out.m:
	Replace everything in this file with just the includes of the
	submodules that now have all its previous contents.

compiler/hlds_llds.m:
	Move a predicate here from llds_out.m, since it is a utility
	predicate operating on a type defined here.

compiler/rtti_out.m:
	Move a predicate here from llds_out.m, since it is a predicate
	generating output from a rtti type.

compiler/hlds_out_mode.m:
	The part of hlds_out.m that deals with writing out insts and modes.

compiler/hlds_out_goal.m:
	The part of hlds_out.m that deals with writing out goals.

compiler/hlds_out_pred.m:
	The part of hlds_out.m that deals with writing out predicates and
	procedures.

compiler/hlds_out_module.m:
	The part of hlds_out.m that deals with writing out module-wide tables.

compiler/hlds_out_util.m:
	Parts of hlds_out.m that don't fit in anywhere else.

compiler/hlds_out.m:
	Replace everything in this file with just the includes of the
	submodules that now have all its previous contents.

compiler/simplify.m:
compiler/hlds_goal.m:
	Move some insts from simplify.m to hlds_goal.m to allow
	hlds_out_goal.m to use them also.

compiler/coverage_profiling.m:
	The part of deep_profiling.m that deals with coverage profiling.

compiler/deep_profiling.m:
	Remove the code moved to coverage_profiling.m, and export the utility
	predicates needed by coverage_profiling.m.

	Remove the things moved to prog_data.m and hlds_goal.m.

	Put the predicates into a more logical order.

compiler/hlds_goal.m:
	Move some predicates here from deep_profiling.m, since they
	belong here.

compiler/prog_data.m:
	Move a type from deep_profiling.m here, since it belongs here.

compiler/add_pragma.m:
	Add a predicate from llds_out.m that is used only here.

compiler/*.m:
	Conform to the changes above.
2009-11-04 03:44:52 +00:00
Zoltan Somogyi
d4bbcda309 Move all the frequently occurring layout structures and components of layout
Estimated hours taken: 40
Branches: main

Move all the frequently occurring layout structures and components of layout
structures into arrays where possible. By replacing N global variables holding
individual layout structures or layout structure components with one global
variable holding an array of them, we reduce the sizes of the symbol tables
stored in object files, which should speed up both the C compiler and the
linker.

Measured on the modules of the library, mdbcomp and compiler directories
compiled in grade asm_fast.gc.debug, this diff reduces the size of the
generated C source files by 7.8%, the size of the generated object files
by 10.4%, and the number of symbols in the symbol tables of those object files
by a whopping 42.8%. (These improvements include, and are not on top of,
the improvements in my previous similar diff.)

runtime/mercury_stack_layout.h:
	Each label layout structure has information about the type and
	location of every variable that is live at that label. We store
	this information in three arrays: an array of pseudo-typeinfos giving
	the types of all these variables, and two arrays MR_ShortLvals and
	MR_LongLvals respectively giving their locations. (Most of the time,
	the location's encoded form fits into one byte (the MR_ShortLval)
	but sometimes it needs more bits (this is when we use MR_LongLval)).

	We used to store these three arrays, whose elements are different
	types, in a single occurrence-specific common structure,
	one after the other, with a cumbersome mechanism being required
	to access them. We now store them as segments of three separate arrays,
	of pseudo-typeinfos, MR_ShortLvals and MR_LongLvals respectively.
	This makes access simpler and faster (which will matter more to any
	accurate garbage collector than it does to the debugger). It also
	allows more scope for compression, since reusing an existing segment of
	one of the three arrays is easier than reusing an entire common
	structure, which would require the equivalent of exact matches
	on all three arrays.

	Since most label layout structures that have information about
	variables can encode the variables' locations using only MR_ShortLvals,
	create a version of the label layout structure type that omits the
	field used to record the whereabouts of the long location descriptors.

	Add macros now generated by the compiler to initialize layout
	structures.

	Simplify a one-field struct.

runtime/mercury_grade.h:
	Increment the binary compatibility version number for debuggable
	executables, since .c and .o files from before and after the change
	to label layout structures are NOT compatible.

runtime/mercury_type_info.h:
	Fix some binary-compatibility-related bit rot.

runtime/mercury_misc.h:
	Move here the existing macros used by the compiler when generating
	references to layout arrays, and add new ones.

runtime/mercury_goto.h:
	Delete the macros moved to mercury_misc.h.
	Conform to the changes in mercury_stack_layout.h.

runtime/Mmakefile:
	Prevent the unnecessary rebuilding of mercury_conf.h.

runtime/mercury_accurate_gc.c:
runtime/mercury_agc_debug.c:
runtime/mercury_layout_util.c:
runtime/mercury_stack_trace.c:
runtime/mercury_types.h:
trace/mercury_trace.c:
trace/mercury_trace_vars.c:
	Conform to the changes in mercury_stack_layout.h.

runtime/mercury_wrapper.c:
	Improve the debug support a bit.

runtime/mercury_engine.h:
	Fix style.

compiler/layout.m:
	Make the change described at the top. Almost all layout structures
	are now in arrays. The only exceptions are those that occur rarely,
	and proc layouts, whose names need to be derivable from the name
	of the procedure itself.

	Instead of having a single type "layout_data" that can represent
	different kinds of single global variables (not array slots), have
	different kinds for different purposes. This makes the code clearer
	and allows traversals that do not have to skip over inapplicable kinds
	of layout structures.

compiler/layout_out.m:
	Output the new arrays.

compiler/stack_layout.m:
	Generate the new arrays. Previously, an individual term generated by
	stack_layout.m could represent several components of a layout
	structure, with the components separated by layout_out.m. We now
	do the separation in stack_layout.m itself, adding each component
	to the array to which it belongs.

	Instead of passing around a single stack_layout_info structure,
	pass around several smaller one. This is preferable, since I found out
	the hard way that including everything in one structure would give the
	structure 51 fields. Most parts of the module work with only one
	or two of these structures, which makes their role clearer.

	Cluster related predicates together.

compiler/options.m:
doc/user_guide.texi:
	Add an option that control whether stack_layout.m will attempt to
	compress the layout arrays that can meaningfully be comressed.

compiler/llds.m:
	Remove the old distinction between a data_addr and a data_name,
	replacing both types with a single new one: data_id. Since different
	kinds of data_names were treated differently in many places,
	the distinction in types (which was intended to allow us to process
	data_addrs that wrapped data_names differently from other kinds of
	data_addrs) wasn't buying us anything anymore.

	The new data_id type allows for the possibility that the code generator
	wants to generate a reference to an address it does not know yet,
	because it is a slot in a layout array, and the slot has not been
	allocated yet.

	Add the information from which the new layout array structures
	will be generated to the LLDS.

compiler/llds_out.m:
	Call layout_out.m to output the new layout arrays.

	Adapt the decl_id type to the replacement of data_addrs by data_ids.
	Don't both keeping track of the have-vs-have-not-declared status
	of structures that are always declared at the start.

	When writing out a data_addr, for some kinds of data_addr, llds_out.m
	would write out the name of the relevant variable, while for some other
	kinds, it would write out its address. This diff separates out those
	those things into separate predicates, each of which behaves
	consistently.

compiler/mercury_compile_llds_back_end.m:
	Convey the intended contents of the new layout arrays from
	stack_layout.m to llds_out.m.

compiler/continuation_info.m:
	Add a type required by the way we now generate proc_static structures
	for deep profiling.

compiler/hlds_rtti.m:
	Add distinguishing prefixes to the field names of the rtti_proc_label
	type.

compiler/code_info.m:
compiler/code_util.m:
compiler/erl_rtti.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/ll_pseudo_type_info.m:
compiler/ml_code_util.m:
compiler/opt_debug.m:
compiler/proc_gen.m:
compiler/prog_rep.m:
compiler/rtti_out.m:
compiler/unify_gen.m:
	Conform to the changes above.

tests/debugger/declarative/track_through_catch.exp:
	Expect procedures to be listed in the proper order.

tests/EXPECT_FAIL_TESTS.asm_fast.gc.debug:
tests/EXPECT_FAIL_TESTS.asm_fast.gc.profdeep:
	Add these files to ignore expected failues in these grades.
2009-10-30 03:33:34 +00:00
Zoltan Somogyi
4ebe3d0d7e Stop storing globals in the I/O state, and divide mercury_compile.m
Estimated hours taken: 60
Branches: main

Stop storing globals in the I/O state, and divide mercury_compile.m
into smaller, more cohesive modules. (This diff started out as doing
only the latter, but it became clear that this was effectively impossible
without the former, and the former ended up accounting for the bulk of the
changes.)

Taking the globals out of the I/O state required figuring out how globals
data flowed between pieces of code that were often widely separated.
Such flows were invisible when globals could be hidden in the I/O state,
but now they are visible, because the affected code now passes around
globals structures explicitly.

In some cases, the old flow looked buggy, as when one job invoked by
mmc --make could affect the globals value of its parent or the globals value
passed to the next job. I tried to fix such problems when I saw them. I am
not 100% sure I succeeded in every case (I may have replaced old bugs with
new ones), but at least now the flow is out in the open, and any bugs
should be much easier to track down and fix.

In most cases, changes the globals after the initial setup are intended to be
in effect only during the invocation of a few calls. This used to be done
by remembering the initial values of the to-be-changed options, changing their
values in the globals in the I/O state, making the calls, and restoring the old
values of the options. We now simply create a new version of the globals
structure, pass it to the calls to be affected, and then discard it.

In two cases, when discovering reasons why (1) smart recompilation should
not be done or (2) item version numbers should not be generated, the record
of the discovery needs to survive this discarding. This is why in those cases,
we record the discovery by setting a mutable attached to the I/O state.
We use pure code (with I/O states) both to read and to write the mutables,
so this is no worse semantically than storing the information in the globals
structure inside the I/O state. (Also, we were already using such a mutable
for recording whether -E could add more information.)

In many modules, the globals information had to be threaded through
several predicates in the module. In some places, this was made more
difficult by predicates being defined by many clauses. In those cases,
this diff converts those predicates to using explicit disjunctions.

compiler/globals.m:
	Stop storing the globals structure in the I/O state, and remove
	the predicates that accessed it there.

	Move a mutable and its access predicate here from handle_options.m,
	since here is when the mutables treated the same way are.

	In a couple of cases, the value of an option is available in a mutable
	for speed of access from inside performance-critical code. Set the
	values of those mutables from the option when the processing of option
	values is finished, not when it is starting, since otherwise the copies
	of each option could end up inconsistent.

	Validate the reuse strategy option here, since doing it during ctgc
	analysis (a) is too late, and (b) would require an update to the
	globals to be done at an otherwise inconvenient place in the code.
	Put the reuse strategy into the globals structure.

	Two fields in the globals structure were unused. One
	(have_printed_usage) was made redundant when the one predicate
	that used it itself became unused; the other (source_file_map)
	was effectively replaced by a mutable some time ago. Delete
	these fields from the globals.

	Give the fields of the globals structure a distinguishing prefix.

	Put the type declarations, predicate declarations and predicate
	definitions in a consistent order.

compiler/source_file_map.m:
	Record this module's results only in the mutable (it serves as a
	cache), not in globals structure. Use explicitly passed globals
	structure for other purposes.

compiler/handle_options.m:
	Rename handle_options as handle_given_options, since it does not
	process THE options to the program, but the options it is given,
	and even during the processing of a single module, it can be invoked
	up the three times in a row, each time being given different options.
	(It was up to four times in a row before this diff.)

	Make handle_given_options explicitly return the globals structure it
	creates. Since it does not take an old global structure as input
	and globals are not stored in the I/O state, it is now clear that
	the globals structure it returns is affected only by the default values
	of the options and the options it processes. Before this diff,
	in the presence of errors in the options, handle_options *could*
	return (implicitly, in the I/O state) the globals structure that
	happened to be in the I/O state when it was invoked.

	Provide a separate predicate for generating a dummy globals based only
	on the default values of options. This allows by mercury_compile.m
	to stop abusing a more general-purpose predicate from handle_options.m,
	which we no longer export.

	Remove the mutable and access predicate moved to globals.m.

compiler/options.m:
	Document the fact that two options, smart_recompilation and
	generate_item_version_numbers, should not be used without seeing
	whether the functionalities they call for have been disabled.

compiler/mercury_compile_front_end.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mercury_compile_erl_back_end.m:
	New modules carved out of the old mercury_compile.m. They each cover
	exactly the areas suggested by their names.

	Each of the modules is more cohesive than the old mercury_compile.m.
	Their code is also arranged in a more logical order, with predicates
	representing compiler passes being defined in the order of their
	invocation.

	Some of these modules export predicates for use by their siblings,
	showing the dependencies between the groups of passes.

compiler/top_level.m:
compiler/notes/compiler_design.html:
	Add the new modules.

compiler/mark_static_terms.m:
	Move this module from the ml_backend package to the hlds package,
	since (a) it does not depend on the MLDS in any way, and (b) it is
	also needed by a compiler pass (loop invariants) in the middle passes.

compiler/hlds.m:
compiler/ml_backend.m:
compiler/notes/compiler_design.html:
	Reflect mark_static_terms.m's change of package.

compiler/passes_aux.m:
	Move the predicates for dumping out the hLDS here from
	mercury_compile.m, since the new modules also need them.

	Look up globals in the HLDS, not the I/O state.

compiler/hlds_module.m:
	Store the prefix (common part) of HLDS dump file names in the HLDS
	itself, so that the code moved to passes_aux.m can figure out the
	file name for a HLDS dump without doing system calls.

	Give the field names of some structures prefixes to avoid ambiguity.

compiler/mercury_compile.m:
	Remove the code moved to the other modules. This module now looks
	after only option handling (such as deciding whether to generate .int3
	files, .int files, .opt files etc), and the compilation passes
	up to and including the creation of the first version of the HLDS.
	Everything after that is subcontracted to the new modules.

	Simplify and make explicit the flow of globals information.
	When invoking predicates that could disable smart recompilation,
	check whether they have done so, and if yes, update the globals
	accordingly.

	When compiling via gcc, we need to link into the executable
	the object files of any separate C files we generate for C code
	foreign_procs, which we cannot translate into gcc's internal
	structures without becoming a C compiler as well as a Mercury compiler.
	Instead of adding such files to the accumulating option for extra
	object files in the globals structure, we return their names using
	the already existing mechanism we have always used to link the object
	files of fact tables into the executable.

	Give several predicates more descriptive names. Put predicates
	in a more logical order.

compiler/make.m:
compiler/make.dependencies.m:
compiler/make.module_target.m:
compiler/make.module_dep_file.m:
compiler/make.program_target.m:
compiler/make.util.m:
	Require callers to supply globals structures explicitly, not via the
	I/O state. Afterward pass them around explicitly, passing modified
	versions to mercury_compile.m when invoking it with module- and/or
	task-specific options.

	Due the extensive use of partial application for higher order code
	in these modules, passing around the globals structures explicitly
	is quite tricky here. There may be cases where a predicate uses
	an old globals structure it got from a closure instead of the updated
	module- and/or task-specific globals it should be using, or vice versa.
	However, it is just as likely that, this diff fixes old problems
	by preventing the implicit flow of updated-only-for-one-invocation
	globals structures back to the original invoking context.

	Although I have tried to be careful about this, it is also possible
	that in some places, the code is using an updated-for-an-invocation
	globals structure in some but not all of the places where it
	SHOULD be used.

compiler/c_util.m:
compiler/compile_target_code.m:
compiler/compiler_util.m:
compiler/error_util.m:
compiler/file_names.m:
compiler/file_util.m:
compiler/ilasm.m:
compiler/ml_optimize.m:
compiler/mlds_to_managed.m:
compiler/module_cmds.m:
compiler/modules.m:
compiler/options_file.m:
compiler/pd_debug.m:
compiler/prog_io.m:
compiler/transform_llds.m:
compiler/write_deps_file.m:
	Require callers to supply globals structures explicitly, not via the
	I/O state.

	In some cases, the explicit globals structure argument allows
	a predicate to dispense with the I/O states previously passed to it.

	In some modules, rename some predicates, types and/or function symbols
	to avoid ambiguity.

compiler/read_modules.m:
	Require callers to supply globals structures explicitly, not via the
	I/O state.

	Record when smart recompilation and the generation of item version
	numbers should be disabled.

compiler/opt_debug.m:
compiler/process_util.m:
	Require callers to supply the needed options explicitly, not via the
	globals in the I/O state.

compiler/analysis.m:
compiler/analysis.file.m:
compiler/mmc_analysis.m:
	Make the analysis framework's methods take their global structures
	as explicit arguments, not as implicit data stored in the I/O state.

	Stop using `with_type` and `with_inst` declarations unnecessarily.

	Rename some predicates to avoid ambiguity.

compiler/hlds_out.m:
compiler/llds_out.m:
compiler/mercury_to_mercury.m:
compiler/mlds_to_c.m:
compiler/mlds_to_java.m:
compiler/optimize.m:
	Make these modules stop accessing the globals from the I/O state.
	Do this by requiring the callers of their top predicates to explicitly
	supply a globals structure. To compensate for the cost of having to
	pass around a representation of the options, look up the values of the
	options of interest just once, to make further access much faster.

	(In the case of mlds_to_c.m, the code already did much of this,
	but it still had a few accesses to globals in the I/O state that
	this diff eliminates.)

	If the module exports a predicate that needs these pre-looked-up
	options, then export the type of this data structure and its
	initialization function.

compiler/frameopt.m:
	Since this module needs only one option from the globals, pass that
	option instead of the globals.

compiler/accumulator.m:
compiler/add_clause.m:
compiler/closure_analysis.m:
compiler/complexity.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/elds_to_erlang.m:
compiler/exception_analysis.m:
compiler/fact_table.m:
compiler/intermod.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/pd_util.m:
compiler/post_term_analysis.m:
compiler/recompilation.usage.m:
compiler/size_prof.usage.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.m:
compiler/structure_sharing.analysis.m:
compiler/tabling_analysis.m:
compiler/term_constr_errors.m:
compiler/term_constr_fixpoint.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/term_constr_util.m:
compiler/trailing_analysis.m:
compiler/trans_opt.m:
compiler/typecheck_info.m:
	Look up globals information from the HLDS, not the I/O state.

	Conform to the changes above.

compiler/gcc.m:
compiler/maybe_mlds_to_gcc.pp:
compiler/mlds_to_gcc.m:
	Look up globals information from the HLDS, not the I/O state.

	Conform to the changes above.

	Convert these modules to our current programming style.

compiler/termination.m:
	Look up globals information from the HLDS, not the I/O state.

	Conform to the changes above.

	Report some warnings with error_specs, instead of immediately
	printing them out.

compiler/export.m:
compiler/il_peephole.m:
compiler/layout_out.m:
compiler/rtti_out.m:
compiler/liveness.m:
compiler/make_hlds.m:
compiler/make_hlds_passes.m:
compiler/mlds_to_il.m:
compiler/mlds_to_ilasm.m:
compiler/recompilation.check.m:
compiler/stack_opt.m:
compiler/superhomogeneous.m:
compiler/tupling..m:
compiler/unneeded_code.m:
compiler/unused_args.m:
compiler/unused_import.m:
compiler/xml_documentation.m:
	Conform to the changes above.

compiler/equiv_type_hlds.m:
	Give the field names of a structure prefixes to avoid ambiguity.

	Stop using `with_type` and `with_inst` declarations unnecessarily.

compiler/loop_inv.m:
compiler/pd_info.m:
compiler/stack_layout.m:
	Give the field names of some structures prefixes to avoid ambiguity.

compiler/add_pragma.m:
	Add notes.

compiler/string.m:
NEWS:
	Add a det version of remove_suffix, for use by new code above.
2009-10-14 05:28:53 +00:00
Zoltan Somogyi
d69ba1a1f0 Include the type_ctor in cons_ids for user-defined types.
Estimated hours taken: 32
Branches: main

Include the type_ctor in cons_ids for user-defined types. The intention is
two-fold:

- It prepares for a future in which we allow more than one function symbol to
  with the same name to be defined in a module.

- It makes the HLDS code more self-contained. In many places, processing
  construction and deconstruction unifications required knowing which type
  the cons_id belongs to, but until now, code couldn't know that unless it
  kept track of the type of the variable unified with the cons_id.

With this diff, user-defined cons_ids are represented as

	cons(SymName, Arity, TypeCtor)

The last field is filled in during post-typecheck. After that time, any module
qualification in the SymName (which may initially be partial) is redundant,
since it is also available in the TypeCtor.

In the future, we could make all those SymNames be just unqualified(_) at that
time. We could also replace the current maps in HLDS type definitions with
full cons_id keys with just name/arity keys (since the module qualifier is a
given for any given type definition), we could also support partially
qualified cons_ids in source code using a map from name/arity pairs to a list
of all the type_ctors that have function symbols with that name/arity, instead
of our current practice of inserting all possible partially module qualified
version of every cons_id into a single giant table, and we could do the same
thing with the field names table.

This diff also separates tuples out from user-defined types, since in many
respects they are different (they don't have a single type_ctor, for starters).
It also separates out character constants, since they were alreay treated
specially in most places, though not in some places where they *ought* to
have been treated specially. Take the opportunity to give some other cons_ids
better names.

compiler/prog_data.m:
	Make the change described above, and document it.

	Put the implementations of the predicates declared in each part
	of this module next to the declarations, instead of keeping all the
	code until the very end (where it was usually far from their
	declarations).

	Remove three predicates with identical definitions from inst_match.m,
	inst_util.m and mode_constraints.m, and put the common definition
	in prog_data.m.

library/term_io.m:
	Add a new predicate that is basically a reversible version of
	the existing function espaced_char, since the definition of char_consts
	needs reversibilty.

compiler/post_typecheck.m:
	For functors of user-defined types, record their type_ctor. For tuples
	and char constants, record them as such.

compiler/builtin_lib_types.m:
compiler/parse_tree.m:
compiler/notes/compiler_design.html:
	New module to centralize knowledge about builtin types, specially
	handled library types, and their function symbols. Previously,
	the stuff now in this module used to be in several different places,
	including prog_type.m and stm_expand.m, and some of it was duplicated.

mdbcomp/prim_data.m:
	Add some predicates now needed by builtin_lib_types.m.

compiler/builtin_ops.m:
	Factor out some duplicated code.

compiler/add_type.m:
	Include the relevant type_ctors in the cons_ids generated in type
	definitions.

compiler/hlds_data.m:
	Document an existing type better.

	Rename a cons_tag in sync with its corresponding cons_id.

	Put some declarations into logical order.

compiler/hlds_out.m:
	Rename a misleadingly-named predicate.

compiler/prog_ctgc.m:
compiler/term_constr_build.m:
	Add XXXs for questionable existing code.

compiler/add_clause.m:
compiler/add_heap_ops.m:
compiler/add_pragma.m:
compiler/add_pred.m:
compiler/add_trail_ops.m:
compiler/assertion.m:
compiler/bytecode_gen.m:
compiler/closure_analysis.m:
compiler/code_info.m:
compiler/complexity.m:
compiler/ctgc_selector.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/delay_partial_inst.m:
compiler/dependency_graph.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/distance_granularity.m:
compiler/erl_rtti.m:
compiler/erl_unify_gen.m:
compiler/export.m:
compiler/field_access.m:
compiler/foreign.m:
compiler/format_call.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_desc.m:
compiler/hlds_goal.m:
compiler/implementation_defined_literals.m:
compiler/inst_check.m:
compiler/inst_graph.m:
compiler/inst_match.m:
compiler/inst_util.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/interval.m:
compiler/lambda.m:
compiler/lco.m:
compiler/make_tags.m:
compiler/mercury_compile.m:
compiler/mercury_to_mercury.m:
compiler/middle_rec.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_java.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/mode_ordering.m:
compiler/mode_util.m:
compiler/modecheck_unify.m:
compiler/modes.m:
compiler/module_qual.m:
compiler/polymorphism.m:
compiler/prog_ctgc.m:
compiler/prog_event.m:
compiler/prog_io_util.m:
compiler/prog_mode.m:
compiler/prog_mutable.m:
compiler/prog_out.m:
compiler/prog_type.m:
compiler/prog_util.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/rbmm.add_rbmm_goal_infos.m:
compiler/rbmm.execution_path.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.region_transformation.m:
compiler/recompilation.usage.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/simplify.m:
compiler/simplify.m:
compiler/special_pred.m:
compiler/ssdebug.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/stratify.m:
compiler/structure_reuse.direct.detect_garbagem:
compiler/superhomoegenous.m:
compiler/switch_detection.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_constr_build.m:
compiler/term_norm.m:
compiler/try_expand.m:
compiler/type_constraints.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/unify_modes.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
	Minor changes, mostly to ignore the type_ctor in cons_ids in places
	where it is not needed, take the type_ctor from the cons_id in places
	where it is more convenient, conform to the new names of some cons_ids,
	conform to the changes in hlds_out.m, and/or add now-needed imports
	of builtin_lib_types.m.

	In some places, the handling previously applied to cons/2 (which
	included tuples and character constants as well as user-defined
	function symbols) is now applied only to user-defined function symbols
	or to user-defined function symbols and tuples, as appropriate,
	with character constants being handled more like the other kinds of
	constants.

	In inst_match.m, rename a whole bunch of predicates to avoid
	ambiguities.

	In prog_util.m, remove two predicates that did almost nothing yet were
	far too easy to misuse.
2009-06-11 07:00:38 +00:00
Peter Wang
58537374bb Predefine MR_TypeClassConstaint_NStructs for type classes with arities up
Branches: main

Predefine MR_TypeClassConstaint_NStructs for type classes with arities up
to 10 (was 5).  Although low-level C grades would define the structures
for higher arities on demand, this is not currently implemented for
high-level C grades.

runtime/mercury_type_info.h:
	Define MR_TypeClassConstaint_NStructs for N =< 10.

compiler/rtti_out.m:
	Bump max_always_declared_arity_type_class_constraint.

tests/valid/Mmakefile:
tests/valid/typeclass_constraint_arity.m:
	Add test case.
2008-10-30 06:45:59 +00:00