62 Commits

Author SHA1 Message Date
Zoltan Somogyi
b261c5fcb2 Enable dense switches on sized and unsigned ints.
Until now, the only integer type we generated dense switches
(including lookup switches) for was int itself; we did not do so
for any sized and/or unsigned integer types.

compiler/switch_util.m:
    Simplify the representation of whether a switch is on an integer type.
    The new version makes it impossible to make the mistake that caused
    bug582 in the first place: not having a single representation for
    for the switch being on *any* kind of integer type.

    This fix requires solving a problem we never had to solve before:
    representing information such as the min and max case values
    in a way that works for every integer type, signed or unsigned,
    sized or not. The solution that this diff adopts is to use int32s
    to represent those limits, which implies that whatever the type
    of the integer value being switched on, we will generate a dense
    or a lookup switch for it only if all case values fit into an int32.
    Since case values over two billion are vanishingly rare, this should be
    an acceptable restriction.

    Use uints instead of ints to represent counts of things.

    Delete an unneeded pair of arguments.

compiler/lookup_switch_util.m:
    Conform to the changes in switch_util.m. Use some of the new types
    there to make arguments in arguments lists less confusable.

    Provide some new utility operations.

    Add XXXs where the basic operations we need seem not to exist.

compiler/dense_switch.m:
compiler/lookup_switch.m:
    Use the new types in switch_util.m that can represent switches
    on any integer type.

compiler/ml_lookup_switch.m:
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/switch_gen.m:
    Conform to the changes above, and thereby gain the ability
    to generate switches on integer types other than int itself.

library/int64.m:
    Add a (commmented-out) declaration of an operation that could
    help resolve one of the issues in new code in the modules above.
    Similar operations would be needed in the modules of other
    sized integer types as well.

library/library.m:
    Fix a typo.

tests/hard_coded/bug582.{m,exp}:
    Add a test case for this issue. Note that while we test whether
    we get the expected output, there is no simple automatic way
    to detect whether it was generated using a lookup table.

tests/hard_coded/Mmakefile:
    Enable the new test case.
2026-03-04 19:51:35 +11:00
Zoltan Somogyi
386160f937 s/dont/do_not/ in the compiler directory.
compiler/*.m:
    Standardize on the do_not spelling over the dont contraction
    in the compiler directory. (We used to have a lot of both spellings.)
2024-08-12 12:49:23 +02:00
Zoltan Somogyi
28ab8c2ade Group together related builtin operations.
compiler/builtin_ops.m:
    Replace six individual builtin comparison ops for str_{eq,ne,lt,le,gt,ge}
    with a single str_cmp/1 function symbol, whose *argument*
    is one of {eq,ne,lt,le,gt,ge}. Do the same with comparison operations
    on integers (including the operations that compare signed integers
    as if they were unsigned) and floats. The eq and ne operations
    on integers had names that did not fit into the scheme used by the
    other binops; this diff fixes that.

    Replace five individual builtin arithmetic ops for int_{add,sub,mul,mod}
    with a single int_arity/2 function symbol, one of whose arguments
    is one of {add,sub,mul,rem}. (This diff renames the "mod" (modulus)
    op to "rem" (remainder), as an XXX has been asking for a long time.)
    The other argument specifies *which* integer type the operation is on.
    Do a similar change for float arithmetic ops, with the exception that
    floats don't support the remainder op.

    The points of the above changes are

    - to allow us to factor out commonalities between operations,
      both between e.g. all comparison operations on integers,
      and between  e.g. lt comparisons on values of different types.

    - to stop forcing switches on binops to make distinctions that
      they do not actually care about.

    Rename the old str_cmp op, which returns a negative, zero or positive
    result (as does strcmp in C) to str_nzp, since the str_cmp name
    is now used for something else.

    Add some utility functions here, to allow the deletion of the
    many existing copies of the bodies of those functions elsewhere
    in the compiler.

compiler/closure_gen.m:
compiler/code_util.m:
compiler/dense_switch.m:
compiler/disj_gen.m:
compiler/ite_gen.m:
compiler/jumpopt.m:
compiler/llds.m:
compiler/llds_out_data.m:
compiler/lookup_switch.m:
compiler/middle_rec.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_global_data.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/ml_unify_gen.m:
compiler/ml_unify_gen_test.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_cs_data.m:
compiler/mlds_to_java_data.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/peephole.m:
compiler/pragma_c_gen.m:
compiler/string_switch.m:
compiler/tag_switch.m:
compiler/trace_gen.m:
compiler/transform_llds.m:
compiler/unify_gen.m:
compiler/unify_gen_test.m:
    Conform to the changes above, by either generating or consuming
    binops in their new form.
2024-07-13 15:02:08 +02:00
Zoltan Somogyi
a6d81a3bb9 Carve three new modules out of switch_util.m.
compiler/lookup_switch_util.m:
compiler/string_switch_util.m:
compiler/tag_switch_util.m:
    Carve these three new modules out of switch_util.m. As their names imply,
    they contain the parts of the old switch_util.m that are concerned with
    lookup switches, switches on strings, and switches on tags respectively.

compiler/switch_util.m:
    Delete the code moved to the new modules.

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

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

compiler/dense_switch.m:
compiler/lookup_switch.m:
compiler/ml_lookup_switch.m:
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/simplify_goal_switch.m:
compiler/string_switch.m:
compiler/switch_case.m:
compiler/switch_gen.m:
compiler/tag_switch.m:
    Conform to the changes above by importing one, or sometimes two, of
    the new modules, usually instead of switch_util.m, sometimes
    in addition to switch_util.m.

    In a few cases, delete explicit module qualifications that
    this diff has made incorrect.
2024-03-12 22:13:59 +11:00
Zoltan Somogyi
9f3a779851 Enforce an invariant by using a subtype.
compiler/prog_type.m:
    Define a subtype of type_ctor_category, nb_type_ctor_category,
    that cannot be a (non-dummy) builtin type.

compiler/mlds.m:
    Use that new subtype to enforce our invariant that the mercury_nb_type
    function symbol of the mlds_type type cannot represent a nondummy
    builtin type.

compiler/prog_data.m:
    Add a commented-out subtype of mer_type, which could help enforce
    the same invariant, if this help were needed.

compiler/format_call.m:
compiler/ml_accurate_gc.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/mlds_to_c_stmt.m:
compiler/mlds_to_c_type.m:
compiler/mlds_to_cs_data.m:
compiler/mlds_to_cs_type.m:
compiler/mlds_to_java_data.m:
compiler/mlds_to_java_type.m:
    Conform to the changes above.
2023-07-16 02:44:47 +02:00
Zoltan Somogyi
e98b25b67f Represent global structs using a bespoke type.
compiler/mlds.m:
    Add the type mlds_struct_defn, which is a version of mlds_class_defn
    that is specialized to represent the global structures we use in the
    MLDS backend to implement static data. The original mlds_class_defn
    has 13 fields; mlds_struct_defn has only four. This difference
    effectively encodes a whole lot of invariants about static structures.
    Not only does it omit fields of mlds_class_defns that are always the same
    for all global structs, it also omits fields of mlds_class_defns that can
    differ between target languages but which are always the same for
    any given target language. These differences are implemented by
    mlds_to_*_class.m.

    Add mlds_struct_id as a new type to represent the ids of global static
    structures.

    Add mlds_struct_type as a new function symbol in the mlds_type type
    to represent the type of global static structures.

    Delete the mlds_struct alternative from the mlds_class_kind type,
    since after this diff, we won't generate such mlds_class_defns anymore.

compiler/ml_global_data.m:
    Generate mlds_struct_defns instead of mlds_class_defns to represent
    global static structures, and include these structures, instead of
    mlds_class_defns, in the ml_vector_cell_group component of the
    ml_global_data type.

compiler/ml_type_gen.m:
    Provide a function, ml_gen_struct_constructor_function, to construct
    a constructor for a mlds_struct_defn. This new code is a version of
    ml_gen_constructor_function that is specialized for mlds_struct_defns.
    Add a similarly specialized function to construct the definitions
    of mlds_struct_defns' fields.

compiler/mlds_to_c_class.m:
compiler/mlds_to_cs_class.m:
compiler/mlds_to_java_class.m:
    Add code to write out mlds_struct_defns. In each case, this code is
    a version of the code to write out mlds_class_defns, specialized
    to the invariants of global static structures.

compiler/mlds_to_c_global.m:
compiler/mlds_to_cs_global.m:
compiler/mlds_to_java_global.m:
    Call the new code in mlds_to_X_class.m when processing vector cell groups
    in ml_global_data structures.

compiler/mlds_to_cs_data.m:
    Conform to the changes above, and factor out some common code in a switch.

compiler/ml_accurate_gc.m:
compiler/ml_lookup_switch.m:
compiler/ml_rename_classes.m:
compiler/ml_simplify_switch.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_export.m:
compiler/mlds_to_c_stmt.m:
compiler/mlds_to_c_type.m:
compiler/mlds_to_cs_type.m:
compiler/mlds_to_java_data.m:
compiler/mlds_to_java_type.m:
    Conform to the changes above.
2023-07-16 00:31:50 +02:00
Zoltan Somogyi
6d00821f0d Represent environments using a bespoke type.
compiler/mlds.m:
    Add the type mlds_env_defn, which is a version of mlds_class_defn
    that is specialized to represent the environment structures we use
    in the MLDS backend to implement model_non continuations. The original
    mlds_class_defn has 13 fields; mlds_env_defn has only three. This
    difference effectively encodes a whole lot of invariants about
    environments. Not only does it omit fields of mlds_class_defns
    that are always the same for all environments, it also omits
    fields of mlds_class_defns that can differ between target languages
    but which are always the same for any given target language.
    These differences are implemented by mlds_to_*_class.m.

    Add mlds_env_id as a new type to represent the ids of environment
    structures.

    Add mlds_env_type as a new function symbol in the mlds_type type
    to represent the type of environment structures.

    Include a list of mlds_env_defns in the MLDS representation of the
    translated module.

compiler/ml_elim_nested.m:
    Generate mlds_env_defns instead of mlds_class_defns to represent
    environment structures.

compiler/mlds_to_c_class.m:
compiler/mlds_to_cs_class.m:
compiler/mlds_to_java_class.m:
    Add code to write out mlds_env_defns. In each case, this code is
    a version of the code to write out mlds_class_defns, specialized
    to the invariants of environment structures.

compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
    Call the new code in mlds_to_X_class.m.

compiler/ml_rename_classes.m:
    Add utility predicates for operating on environment structures.

compiler/mercury_compile_mlds_back_end.m:
compiler/ml_accurate_gc.m:
compiler/ml_lookup_switch.m:
compiler/ml_simplify_switch.m:
compiler/ml_top_gen.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_export.m:
compiler/mlds_to_c_stmt.m:
compiler/mlds_to_c_type.m:
compiler/mlds_to_cs_data.m:
compiler/mlds_to_cs_type.m:
compiler/mlds_to_java_data.m:
compiler/mlds_to_java_type.m:
    Conform to the changes above.

tools/bootcheck:
    Redirect the input of mmake in each test directory to come from
    /dev/null, to avoid bootchecks in the Java grade being temporarily
    suspended for input from the terminal.
2023-07-14 03:48:22 +02:00
Zoltan Somogyi
58bc167ff4 Separate enum classes from other classes in MLDS.
Classes representing enums have always treated differently from the
other kinds of classes by many pieces of code that operate on classes.
Representing them using a separate construct codifies this, and allows us
to encode the unique invariants applying to enum classes in the types.

compiler/mlds.m:
    Define a new type, mlds_enum_class_defn, which is a copy of the old
    mlds_class_defn type which has been specialized for the classes
    representing enums. This is done by deleting the fields that are
    not applicable to enum classes, and restricting the types of some
    other fields.

    Delete the mlds_enum alternative from the mlds_class_kind type,
    which is still part of the mlds_class_defn type, thus indicating
    that enums can no longer be represented by mlds_class_defns.

    Separate mlds_enum_class_id from mlds_class_ids.
    Separate mlds_enum_class_types from mlds_class_types.

    Include the list of mlds_enum_class_defns in the overall MLDS structure.

compiler/ml_type_gen.m:
    Construct mlds_enum_class_defns, not mlds_class_defn, to represent
    enum types when using the high-level data representation (i.e. when
    targeting C# and Java).

compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
    Output the mlds_enum_class_defns as well as the mlds_class_defns.

compiler/mlds_to_c_file.m:
    Insist of there being no mlds_enum_class_defns to output.

compiler/mlds_to_cs_class.m:
compiler/mlds_to_java_class.m:
    Add code to output mlds_enum_class_defns, as a copy of the original
    code to output mlds_class_defns, but specialized for the invariants
    of mlds_enum_class_defns.

compiler/mlds_to_c_class.m:
    Update some existing code to output enum constant definitions.
    Since we never generate classes for enum types when targeting C,
    and the separation of mlds_enum_class_defns from mlds_class_defns
    makes this clear, this code is now unused, so mark it with a
    consider_used pragma.

compiler/ml_accurate_gc.m:
compiler/ml_elim_nested.m:
compiler/ml_lookup_switch.m:
compiler/ml_rename_classes.m:
compiler/ml_simplify_switch.m:
compiler/ml_top_gen.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_export.m:
compiler/mlds_to_c_stmt.m:
compiler/mlds_to_c_type.m:
compiler/mlds_to_cs_data.m:
compiler/mlds_to_cs_export.m:
compiler/mlds_to_cs_type.m:
compiler/mlds_to_java_data.m:
compiler/mlds_to_java_export.m:
compiler/mlds_to_java_type.m:
    Conform to the changes above.

compiler/mlds_to_target_util.m:
    Delete now no-longer-needed predicate.
2023-06-13 08:47:09 +02: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
Peter Wang
0925d052d8 Make type_range also succeed for discontiguous range of enum values.
compiler/switch_util.m:
    Make type_range succeed for a subtype where the constructors are
    assigned enum values in a discontiguous range. I checked that its
    callers do not expect all values in the range to necessarily
    be used by the type.

    Clarify find_int_lookup_switch_params a bit.

    Clarify comments.

compiler/dense_switch.m:
    Use need_range_check type instead of can_fail in dense_switch_info,
    as that is what the field actually means.

compiler/ml_simplify_switch.m:
    Use need_range_check type instead of bool.

tests/hard_coded/dense_lookup_switch_non2.m:
    Delete obsoleted XXX.
2021-04-13 15:04:55 +10:00
Zoltan Somogyi
181ada0dbf Avoid -O<n> resetting previously set options.
This implements Mantis feature request #495.

NEWS:
    Announce the change.

compiler/optimization_options.m:
    A new module for managing optimization options.

    It defines a separate bespoke type for every boolean optimization option
    to make it harder to confuse them. It defines a tuple type (opt_tuple)
    for accessing optimization options quickly. It implements the turning on
    (but NOT turning off) of optimizations when a given optimization level
    is selected.

tools/make_optimization_options_middle:
tools/make_optimization_options_db:
    The script that generates the meat of optimization_options.m,
    and the database of option names, kinds and initial values
    that it uses as its input. The script also generates some code
    for the special_handler predicate in compiler/options.m.

tools/make_optimization_options_start:
tools/make_optimization_options_end:
    The handwritten initial and final parts of optimization_options.m.

tools/make_optimization_options:
    The script that pulls these parts together to form optimization_options.m.

compiler/options.m:
    Make every optimization option a special option, to be handled by
    the special_handler predicate. That handling consists of simply
    adding a representation of the option to the end of a cord of
    optimization options, to be processed later by optimization_options.m.
    That processing will record the values of these options in the opt_tuple,
    which is where every other part of the compiler should get them from.

    Change the interface of special_handler to make the above possible.

    Add an "optopt_" (optimization option) prefix to the name of
    every optimization option, to make them inaccessible to the rest
    of the compiler under their old name, and thus help enforce the switch
    to using the opt_tuple. Any access to these options to look up
    their values would fail anyway, since the option data would no longer be
    e.g. bool(yes), but bool_special, but the name change makes this failure
    happen at compile time, not runtime.

    Reclassify a few options to make the above make sense. Some options
    (unneeded_code_debug, unneeded_code_debug_pred_name, and
    common_struct_preds) were classified as oc_opt even though they
    control only the *debugging* of optimizations, while some options
    (c_optimize and inline_alloc) were not classified as oc_opt
    even though we do set them automatically at some optimization levels.

    Delete the opt_level_number option, since it was not used anywhere.

    Delete the code for handling -ON and --opt-space, since that is now
    done in optimization_options.m.

    Add some XXXs.

compiler/handle_options.m:
    Switch to using getopt_io.process_options_userdata_se, as required
    by the new interface of the special_handler in options.m.
    In the absence of errors, invoke optimization_options.m to initialize
    the opt_tuple. Then update the opt_tuple incrementally when processing
    option implications that affect optimization options.

compiler/globals.m:
    Put the opt_tuple into a new field of the globals structure.

compiler/accumulator.m:
compiler/add_pragma_type_spec.m:
compiler/add_trail_ops.m:
compiler/code_info.m:
compiler/code_loc_dep.m:
compiler/compile_target_code.m:
compiler/const_struct.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/disj_gen.m:
compiler/erl_code_gen.m:
compiler/format_call.m:
compiler/global_data.m:
compiler/grab_modules.m:
compiler/higher_order.m:
compiler/hlds_pred.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/ite_gen.m:
compiler/jumpopt.m:
compiler/libs.m:
compiler/llds_out_code_addr.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_instr.m:
compiler/llds_out_util.m:
compiler/matching.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/ml_disj_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/optimize.m:
compiler/pd_util.m:
compiler/peephole.m:
compiler/polymorphism.m:
compiler/proc_gen.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_scope.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
compiler/simplify_tasks.m:
compiler/stack_layout.m:
compiler/stack_opt.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/tag_switch.m:
compiler/tupling.m:
compiler/unify_gen_construct.m:
compiler/unneeded_code.m:
compiler/unused_args.m:
    Conform to the changes above, mostly by looking up optimization options
    in the opt_tuple. In some places, replace bools containing optimization
    options with the bespoke type of that specific optimization option.

library/getopt_template:
    Fix a bug that screwed up an error message.

    The bug happened when processing a --file option. If one of the
    options in the file was a special option whose special handler failed,
    the code handling that failing option returned both an error indication,
    and the rest of the argument list read in from the file. The code
    handling the --file option then *ignored* the error indication from
    the failed special option, and returned an error message of its own
    complaining about the unconsumed remaining arguments in the file,
    believing them to be non-option arguments, even though these arguments
    were never looked it to see if they were options.

    The fix is for the code handling --flag options to check whether
    the code processing the file contents found any errors, and if so,
    return that error *without* looking at the list of remaining arguments.

    In an unrelated change, factor out a duplicate call.
2020-09-28 18:16:13 +10:00
Zoltan Somogyi
742917114b Fix indentation. 2020-05-02 01:09:35 +10:00
Zoltan Somogyi
b66f45e4db Tighten the mlds_type type.
compiler/mlds.m:
    Make two changes to mlds_type.

    The simpler change is the deletion of the maybe(foreign_type_assertions)
    field from the MLDS representations of Mercury types. It was never used,
    because Mercury types that are defined in a foreign language that is
    acceptable for the current MLDS target platform are represented
    as mlds_foreign_type, not as mercury_type.

    The more involved change is to change the representation of builtin types.
    Until now, we had separate function symbols in mlds_type to represent
    ints, uints, floats and chars, but not strings or values of the sized
    types {int,uint}{8,16,32,64}; those had to be represented as Mercury types.
    This is an unnecessary inconsistency. It also had two allowed
    representations for ints, uints, floats and chars, which meant that
    some of the code handling those conceptual types had to be duplicated
    to handle both representations.

    This diff provides mlds_builtin_type_{int(_),float,string,char} function
    symbols to represent every builtin type, and changes mercury_type
    to mercury_nb_type to make clear that it is NOT to be used for builtins
    (the nb is short for "not builtin").

compiler/ml_code_util.m:
compiler/ml_util.m:
    Delete functions that used to construct MLDS representations of builtin
    types. The new representation of those types is so simple that using
    such functions is no less cumbersome than writing down the representations
    directly.

compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_global_data.m:
compiler/ml_lookup_switch.m:
compiler/ml_proc_gen.m:
compiler/ml_rename_classes.m:
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_util.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_export.m:
compiler/mlds_to_c_func.m:
compiler/mlds_to_c_global.m:
compiler/mlds_to_c_stmt.m:
compiler/mlds_to_c_type.m:
compiler/mlds_to_cs_data.m:
compiler/mlds_to_cs_stmt.m:
compiler/mlds_to_cs_type.m:
compiler/mlds_to_java_data.m:
compiler/mlds_to_java_stmt.m:
compiler/mlds_to_java_type.m:
compiler/mlds_to_java_wrap.m:
compiler/rtti_to_mlds.m:
    Conform to the changes above.
2018-09-28 23:07:23 +10:00
Zoltan Somogyi
fc903a0911 Eliminate the double storage of types in the MLDS.
compiler/mlds.m:
    When we record a Mercury type in the MLDS, we used to record with it
    not just its type category (which some aux predicates need), but also
    the name by which it is known to the target language compiler, if the
    type is defined in that foreign language. Unfortunaly, the data structure
    we used to represent the name of the foreign type (and any assertions
    on it) also stored a duplicate copy of the Mercury type in the usual
    case where the Mercury type was *not* defined in the foreign language.
    Having two copies of the same information was dangerous, due to the
    possibility of inconsistency between them. It was also unnecessary work
    for the compiler passes that had to create the duplicate copies.

    Eliminate these problems by always storing *one* copy of the Mercury type.

    Store the Mercury and foreign type information next to each other.

compiler/foreign.m:
    Make the above possible by deleting up the old exported_type type,
    which contained the duplicate copy of the Mercury type in usual case
    of a type that is not defined by foreign code, and replacing it
    with a type that contains information about just a foreign type.

    In the argument lists of the predicates and functions of this module,
    replace arguments that used to be type exported_type with a pair
    of the Mercury type and a maybe of the new type, which is yes(...)
    iff the Mercury type *is* defined in foreign code.

    Give some predicates and functions more meaningful names.

    Make specialized versions of these functions available (specialized
    e.g. to a target language) where these would be useful.

    Delete the auxiliary predicates that aren't needed with the
    new data structure design.

compiler/export.m:
compiler/ml_accurate_gc.m:
compiler/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_global_data.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_to_mlds.m:
    Conform to the changes above.
2018-05-08 00:17:34 +02:00
Julien Fischer
63572bc9a8 Fix bug #449 - switches on 64-bit integers in the Java grade.
Switches on 64-bit integers in the Java grade are causing us to generate
invalid Java code because Java's switch statement does not work with 64-bit
integers.  (This limitation is apparently built into the JVM.)

Fix this for now by generating if-then-else chains for switches on 64-bit
integers.   We can almost certainly do better, but that is future work.

compiler/switch_util.m:
    Add a separate switch category for switches on 64-bit integer types.

compiler/switch_gen.m:
    For the low-level C backend, treat switches on 64-bit integers as
    other switches on atomic types.

compiler/ml_target_util.m:
    Add a function that returns whether the target language supports
    switching on 64-bit integers.   Add another that allows us to
    test whether switches on a given integer type are supported by
    a given target language.

compiler/ml_switch_gen.m:
compiler/ml_simplify_switch.m:
    Use the above functions to only generate switches on 64-bit integers
    as target language switches if the target language supports switches
    on 64-bit integers (C# and C do; Java does not).
2018-02-12 20:52:34 -05: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
7b0ca6345f Encode invariants about class inheritance in types.
compiler/mlds.m:
    Make mlds_interface_id its own type, instead of identifying all
    interfaces by an MLDS type using the mlds_class_type/3 data constructors.

    Make mlds_class_id its own type, instead of identifying (almost all)
    classes by an MLDS type using the mlds_class_type/3 data constructors.

    Change the field of mlds_class_defns that says what base classes the
    class inherits from to reflect the facts that

    - the "classes" representing environments that we put on the heap
      when targeting C# or Java have a base *type*, not a base *class*, and

    - no current MLDS target language supports multiple inheritance,
      so an MLDS class cannot inherit from more than one base class.

    Change the mlds_class_type data constructor of the mlds_type type
    to take a complete mlds_class_id as an argument, instead of its pieces.

compiler/ml_accurate_gc.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_global_data.m:
compiler/ml_lookup_switch.m:
compiler/ml_rename_classes.m:
compiler/ml_simplify_switch.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:
    Conform to the changes above.
2017-10-19 19:13:28 +11:00
Zoltan Somogyi
1c01ed85eb Fix lines. 2017-07-29 14:15:15 +02:00
Zoltan Somogyi
11c232f060 Store different kinds of definitions in blocks separately.
An ml_stmt_block contains some definitions and some statements.
The definitions were traditionally stored in a single list of mlds_defns,
but lots of code knew that some kinds of mlds_defns just couldn't occur
in blocks. This diff, by storing the definitions of (a) local variables
and (b) continuation functions in separate field in ml_stmt_blocks,
gets the type system to enforce the invariant that other kinds of definitions
can't occur in blocks.

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

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

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

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

    In code that generated MLDS code, consistently use names containing
    the word "Defn", instead of "Decl", for variables that contain
    mlds_local_var_defns or mlds_function_defns. Some such predicates
    generate lists of both local var definition and function definitions,
    but most generate only one, and some generate neither.
2017-07-26 00:57:13 +02:00
Julien Fischer
8a240ba3f0 Add builtin 8, 16 and 32 bit integer types -- Part 1.
Add the new builtin types: int8, uint8, int16, uint16, int32 and uint32.
Support for these new types will need to be bootstrapped over several changes.
This is the first such change and does the following:

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

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

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

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

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

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

    Add builtin operations for all the new types.

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

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

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

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

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

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

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

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

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

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

compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_code_util.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_global_data.m:
compiler/ml_lookup_switch.m:
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds_to_target_util.m:
    Conform to the above changes to the MLDS.

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

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

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

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

    Update the Java list of TypeCtorRep constants.

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

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

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

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

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

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

runtime/mercury_builtin_types.[ch]:
runtime/mercury_builtin_types_proc_layouts.h:
runtime/mercury_construct.c:
runtime/mercury_deconstruct.c:
runtime/mercury_deep_copy_body.h:
runtime/mercury_ml_expand_body.h
runtime/mercury_table_type_body.h:
runtime/mercury_tabling_macros.h:
runtime/mercury_tabling_preds.h:
runtime/mercury_term_size.c:
runtime/mercury_unify_compare_body.h:
    Add the new builtin types and handle them throughout the runtime.
2017-07-18 01:31:01 +10:00
Zoltan Somogyi
083f990dbb Simplify the use of contexts in the MLDS.
compiler/mlds.m:
    This diff fixes two minor annoyances imposed by the old use of the
    mlds_context type in the MLDS.

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

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

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

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

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

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

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

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

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

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

    Give some predicates and functions more meaningful names.
2017-07-09 18:44:05 +02:00
Julien Fischer
092e175f45 Add a builtin unsigned word sized integer type -- Part 1.
Add a new builtin type: uint, which is an unsigned word sized integer type.
Support for this new type will need be bootstrapped over several changes.
This is the first such change and does the following:

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

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

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

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

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

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

    Bump the RTTI version number here.

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

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

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

    Map uints onto MR_Unsigned.

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

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

compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_global_data.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/rtti_to_mlds.m:
    Conform to the above change to the MLDS.

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

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

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

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

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

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

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

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

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

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

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

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

    Add an alternative for uints to the tyepctor rep enum.

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

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

runtime/mercury_term_size.c:
runtime/mercury_ml_expand_body.h:
    Handle uint and fix probable bugs with the handling of ints on
    64-bit Windows.
2016-10-24 12:55:35 +11:00
Zoltan Somogyi
cc9912faa8 Don't import anything in packages.
Packages are modules whose only job is to serve as a container for submodules.
Modules like top_level.m, hlds.m, parse_tree.m and ll_backend.m are packages
in this (informal) sense.

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

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

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

This diff removes all import_module declarations from the packages,
and replaces them with import_module declarations in the modules that need
them. This includes only a SUBSET of their child modules and of the non-child
modules that import them.
2015-11-13 15:03:20 +11:00
Zoltan Somogyi
7654ec847e Convert (C->T;E) to (if C then T else E). 2015-09-18 09:37:29 +10:00
Zoltan Somogyi
62ec97d443 Report imports shadowed by other imports.
If a module has two or more import_module or use_module declarations
for the same module, (typically, but not always, one being in its interface
and one in its implementation), generate an informational message about
each redundant declaration if --warn-unused-imports is enabled.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

compiler/prog_item.m:
    Add a convenience predicate.

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

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

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

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

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

    In a few cases, conform to other changes above.

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

tests/*/*.{m,*exp}:
    Delete unneeded imports, and update any expected error messages
    to expect the now-smaller line numbers.
2015-08-25 00:38:49 +10:00
Peter Wang
573e6f2f00 Support unboxed float fields in high-level C grades.
Branches: main

Support unboxed float fields in high-level C grades.

When the representation of `float' is no wider than a machine word, d.u.
functor arguments of type `float' (or equivalent) will be stored directly
within cells constructed for that functor, instead of a pointer to the box
containing the value.  This was already so for low-level C grades.

compiler/mlds.m:
	Add an option to mlds_type, equivalent to
	`mlds_array_type(mlds_generic_type)' except that some elements are
	known to be floats.

	Update some comments.

compiler/ml_global_data.m:
	Remember the `--unboxed-float' option in `ml_global_data'.

	Special case generic arrays in `ml_gen_static_scalar_const_addr' and
	`ml_gen_static_scalar_const_value'.  Float literals cannot be used to
	initialize an element of a generic array in C.  If any appear, replace
	the generic array type by an instance of
	`mlds_mostly_generic_array_type' with float fields in the positions
	which have float initializers.

compiler/ml_code_util.m:
	Make `ml_must_box_field_type' and `ml_gen_box_const_rval' depend on the
	`--unboxed-float' option.

	Delete some now-misleading comments.

	Delete an unused predicate.

compiler/mlds_to_c.m:
	Update code that writes out scalar static data to handle
	`mlds_mostly_generic_array_type'.

	In one case, for `--high-level-data' only, output float constants by
	their integer representation, so that they may be cast to pointer
	types.

compiler/ml_unify_gen.m:
	Rename some predicates for clarity.

compiler/ml_accurate_gc.m:
compiler/ml_lookup_switch.m:
compiler/ml_proc_gen.m:
compiler/ml_simplify_switch.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
	Conform to changes.

library/float.m:
	Add hidden functions to return the integer representation of the bit
	layout of floating point values.

library/exception.m:
	Delete mention of MR_AVOID_MACROS.

runtime/mercury.c:
runtime/mercury.h:
	Make MR_box_float/MR_unbox_float act like "casts" when MR_BOXED_FLOAT
	is undefined, and only define them in high-level grades.  I think they
	should be replaced by MR_float_to_word/MR_word_to_float (which have
	less confusing names when there is no boxing) but that would require
	some header file reshuffling which I don't want to undertake yet.

	Delete references to MR_AVOID_MACROS.  Apparently it existed to support
	the defunct gcc back-end but I cannot see it ever being defined.

runtime/mercury_conf_param.h:
	MR_HIGHLEVEL_CODE no longer implies MR_BOXED_FLOAT.

	Delete mention of MR_AVOID_MACROS.

runtime/mercury_float.h:
	Fix a comment.

tests/hard_coded/Mmakefile:
tests/hard_coded/float_ground_term.exp:
tests/hard_coded/float_ground_term.m:
	Add a test case.
2011-08-22 07:56:10 +00:00
Zoltan Somogyi
7ca1a07296 Allow the MLDS backend to generate indexing switches (switches implemented
Estimated hours taken: 16
Branches: main

Allow the MLDS backend to generate indexing switches (switches implemented
more efficiently than just a if-then-else chain) for strings even if the target
language does not support gotos.

Previously, we use always used gotos to break out of search loops
after we found a match:

    do {
        if (we have a match) {
            ... handle the match ...
            goto end
        } else {
            ... handle nonmatches ...
        }
    } while (loop should continue);
    maybe some code to handle the failure of the search
end:

Now, if the "maybe some code" is empty, we prefer to use break statements
if the target language supports this:

    do {
        if (we have a match) {
            ... handle the match ...
            break;
        } else {
            ... handle nonmatches ...
        }
    } while (loop should continue)

If we cannot use either gotos or break statements, we instead use
a boolean variable named "stop_loop":

    stop_loop = 0;
    do {
        if (we have a match) {
            ... handle the match ...
            stop_loop = 1;
        } else {
            ... handle nonmatches ...
        }
    } while (stop_loop == 0 && loop should continue)
    if (stop_loop == 0) {
    	maybe some code to handle the failure of the search
    }

We omit the final if statement if the then-part would be empty.

The break method generates the smallest code, followed by the goto code.
I don't have information on speed, since we don't have a benchmark that
runs long enough, and the compiler itself does not spend any significant
amount of time on string switches. Probably the break method is also the
fastest, simply because it leaves the code looking most like normal C code.
(Some optimizations are harder to apply to code containing gotos, and some
optimizer writers do not bother.)

For C, we now normally prefer to generate code using the second method
(breaks), if we can, though normally "maybe some code" is not empty,
in which case we use the first method (goto).

However, if the value of the --experiment option is set to "use_stop_loop",
we always use the third method, and if it is set to "use_end_label", we always
use the first, even when we could use the second. This allow us to test all
three approaches using the C back end.

With backends that support neither gotos nor break, we always use the third
method (stop_loop).

With backends that don't support gotos but do support breaks, we also always
use the third method. This is because trying to use the second method would
require us to commit to not creating the stop_loop variable BEFORE we know
that the "maybe some code to handle the failure of the search" is empty,
and if it isn't empty, then we don't have the goto method to fall back on.

compiler/ml_string_switch.m:
	Make the change described above. Where possible, make the required
	change not to the original code, but to a version in which common
	parts have been factored out. (Previously, the duplicated code was
	small; now, it would be big.)

compiler/ml_target_util.m:
	A new module containing existing functions that test various properties
	of the target language. Keeping some of those functions in their
	original modules would have introduced a circular dependency.

compiler/ml_switch_gen.m:
	Enable the new functionality by removing the tests that previously
	prevented the compiler from using indexing switches on strings
	if the target language did not support gotos.

	Remove the code moved to ml_target_util.m.

compiler/ml_optimize.m:
compiler/ml_unify_gen.m:
	Remove the code moved to ml_target_util.m.

compiler/ml_backend.m:
compiler/notes/compiler_design.m:
	Add the new module.

compiler/ml_proc_gen.m:
	Delete a predicate that hasn't been used for a long time.

tools/makebatch:
	Fix an old pair of typos.
2011-08-15 06:23:20 +00:00
Zoltan Somogyi
fe566dbf42 When doing hash table lookup as part of the implementation of switches on
Estimated hours taken: 8
Branches: main

When doing hash table lookup as part of the implementation of switches on
strings, we use open addressing to handle collisions. However, if the chosen
hash function does not yield any collisions for the strings in the switch arms,
then open addressing is unnecessary: if a lookup does not find the string bound
to the switch variable in its home bucket, it won't be in the hash table
at all.

This diff optimizes such cases, by not generating for them the loop we would
otherwise use for open addressing, and optimizing away the table column
telling that loop where to check next.

compiler/string_switch.m:
	Implement the above optimization both for ordinary switches on strings,
	and for lookup table switches (both one_soln and several_soln) on
	strings.

compiler/ml_string_switch.m:
	Implement the above optimization for ordinary switches on strings.
	This module does not (yet) implement lookup table switches on strings.

compiler/switch_util.m:
	When deciding what hash function to use, return the number of
	collisions for string_switch and ml_string_switch to use.

	Rename the other_switch category to float_switch, since the only
	type category it covers is switches on floats.

compiler/switch_gen.m:
compiler/ml_switch_gen.m:
	Make the module header comments more organized, and use the same
	template for both, so one can see the differences more easily.

	Put the switch arms for the smart indexing methods into the same
	order in both files.

	Fix an old problem in ml_switch_gen.m: the test to see whether we can
	apply a smart indexing method that uses switches on integers was
	testing not the availability of int switches in the target, but
	the availability of computed gotos. While ml_simplify_switch
	would transform the int-switch-using code to computed-goto-using
	code or an if-then-else chain in *some* cases, it would not do so
	in *all* cases.

	In ml_switch_gen.m, remove a test that could not succeed, and
	a procedure that was used only in that test.

	Conform to the changes in switch_util.m.

compiler/lookup_switch.m:
compiler/ml_simplify_switch.m:
	Update comments.
2011-07-26 00:25:22 +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
022b559584 Make error messages for require_complete_switch scopes report the missing
Estimated hours taken: 8
Branches: main

Make error messages for require_complete_switch scopes report the missing
functors.

Knowing which functors are missing requires knowing not only the set of
functors in the switched-on variable's type, but also which of these functors
have been eliminated by earlier tests, which requires having the instmap at
the point of entry to the switch. Simplification, which initially detected
unmet require_complete_switch requirements, does not have the instmap, and
threading the instmap through it would make it significantly less efficient.
So instead we now detect any problems with require_complete_switch scopes
(and require_detism scopes, which are similar) during determinism checking.

compiler/det_report.m:
	Factor out the code for finding the missing functors in conventional
	determinism errors, to allow it to be used for this new purpose.

	Check whether the requirements of require_complete_switch and
	require_detism scopes are met IF the predicate has any such scopes.

compiler/det_analysis.m:
compiler/det_util.m:
	Record whether the predicate has any such scopes.

compiler/hlds_pred.m:
	Add a predicate marker that allows this recording.

compiler/simplify.m:
	Delete the code that checks the require_complete_switch and
	require_detism scopes. Keep the code that deletes those scopes.
	(We have to do that here because determinism error reporting
	never updates the goal).

compiler/prog_out.m:
	Delete an unused predicate.

compiler/*.m:
	Remove unnecesary imports as flagged by --warn-unused-imports.
2011-01-02 14:38:08 +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
439e9d474d Divide the old 4100, 2900 and 4600 line modules ml_code_gen.m, ml_code_util.m
Estimated hours taken: 4
Branches: main

Divide the old 4100, 2900 and 4600 line modules ml_code_gen.m, ml_code_util.m
and modes.m into smaller, more cohesive modules. In the process, put
related predicates next to each other. There are no algorithmic changes.

compiler/ml_proc_gen.m:
	New module that looks after code generation tasks that affect a
	procedure as a whole. Its code is taken from the old ml_code_gen.m.
	Analogous to proc_gen.m, which does the same job for the LLDS backend.

compiler/ml_foreign_proc_gen.m:
	New module that generates code for foreign_proc goals.
	Its code is taken from the old ml_code_gen.m.
	Analogous to pragma_c_gen.m in the LLDS backend.

compiler/ml_commit_gen.m:
	New module that generates code for commit goals.
	Its code is taken from the old ml_code_gen.m.
	Analogous to commit_gen.m in the LLDS backend.

compiler/ml_gen_info.m:
	New module that encapsulates the ml_gen_info structure.
	Its code is taken from the old ml_code_util.m.
	Analogous to code_info.m in the LLDS backend.

compiler/ml_accurate_gc.m:
	New module that generates the data and goals needed for accurate gc.
	Its code is taken from the old ml_code_util.m.

compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
	Move some predicates that are used by other modules of the MLDS backend
	to ml_code_util, in order to avoid otherwise unneeded dependencies.

compiler/mode_util.m:
	Move a predicate here from ml_code_util.m, since it is needed by
	several MLDS backend modules but is not MLDS specific.

compiler/ml_code_gen.m:
	Remove the code moved to other modules.

	Delete an old note about a problem fixed long ago.

compiler/ml_code_util.m:
	Remove the code moved to other modules.

	Add the code moved here from other modules.

compiler/modecheck_conj.m:
	New module that handles mode analysis of conjunctions.
	Its code is taken from the old modes.m.

compiler/modecheck_goal.m:
	New module that handles mode analysis of most types of goals,
	except conjunctions, unifications and calls.
	Its code is taken from the old modes.m.

compiler/modecheck_util.m:
	New module containing utility predicates used more one of the modules
	do mode analysis. Its code is taken from the old modes.m.

compiler/mode_util.m:
	Move a predicate here from modes.m, since this is where a related
	predicate already is.

	Give a predicate a more meaningful name.

compiler/goal_util.m:
	Move a predicate here from modes.m, since this is where a related
	predicate already is.

compiler/modes.m:
	Remove the code moved to other modules.

compiler/ml_backend.m:
compiler/check_hlds.m:
	Add the new modules.

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

compiler/prog_data.m:
	Give some function symbols disambiguating prefixes.

compiler/add_solver.m:
compiler/deforest.m:
compiler/make_hlds_passes.m:
compiler/mercury_compile.m:
compiler/ml_lookup_switch.m:
compiler/ml_simplify_switch.m:
compiler/ml_string.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_unify_gen.m:
compiler/modecheck_call.m:
compiler/modecheck_unify.m:
compiler/prog_io_type_defn.m:
compiler/rtti_to_mlds.m:
compiler/type_ctor_info.m:
compiler/unify_proc.m:
	Conform to the changes above.
2009-09-25 05:13:23 +00:00
Zoltan Somogyi
cbe2ebf496 Implement multi-arm switches for the MLDS backend.
Estimated hours taken: 24
Branches: main

Implement multi-arm switches for the MLDS backend. When possible, the code of a
switch arm that has more than one cons_id is included in the output only once,
though of course with a condition that causes it to be executed for any of its
matching cons_ids. However, in the case of a tag switch in which a switch arm
has cons_ids with different primary tags, at least one of which has a
secondary tag that requires a switch on *it*, we duplicate the MLDS code of the
switch arm (we generate one copy for each such primary tag).

The diff yields a speedup of 0.4% on speedtest and a 0.5% reduction in code
size, but the main reason for it is so that programmers don't have any
incentive anymore to prefer an if-then-else chain to a switch for code
that is logically a switch with a default case that applies to many cons_ids.

compiler/handle_options.m:
	Keep disabling multi-arm switches for non-C MLDS backends, but stop
	disabling it for the C MLDS backend.

compiler/hlds_goal.m:
	Add a case number to the tagged_case type. This is to allow us to
	create maps that effectively function as maps from pieces of code
	(the code generated for the goal in the tagged case) to other things
	(various forms of the switch conditions in which that code applies)
	without making the code itself the key in the map; we can use the
	code's associated case number as the key instead.

compiler/mlds.m:
	Change the representation of the match conditions of a switch arm
	from just a simple list of conditions to a first condition and a list
	of other conditions. This enforces the invariant that the switch arm
	must always apply in at least one condition.

compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
	Implement the above.

	In ml_switch_gen.m, change the structure of the predicate that decides
	which code generation scheme to employ from an if-then-else chain
	to being basically a switch. This structure, which is modelled on the
	one used in the LLDS code generator, should be significantly clearer.

	As part of this change of structure, sort the cases by the cost of the
	tag tests only if the chosen code generation wants the cases sorted in
	this way.

compiler/switch_util.m:
	Add facilities for grouping together primary tags that both have
	exactly the same code, so that we don't have to duplicate its code.
	This is possible only when neither primary tag is shared by more
	than one cons_id. This grouping benefits even the LLDS backend.

	This involved separating out the types and predicates that are intended
	for use in compilation schemes in which more than one switch value can
	share the same piece of code (such as switches or if-then-else chains
	in C) from those intended for use in compilation in which this is not
	possible (such as lookup tables).

	Replace several uses of pairs with named types and function symbols.

	Delete a predicate that isn't needed anymore.

	Add a predicate to support the fix to switch_gen.m.

compiler/switch_gen.m:
	Fix an old oversight. When I added multi-arm switches for the LLDS
	backend, I did not update the test for whether the switch is big enough
	for each kind of nontrivial indexing to count cons_ids rather than
	switch arms (the benefit of smart indexing is proportional to the
	former). This diff fixes that.

compiler/ml_unify_gen.m:
	Change the interface of some predicates to make them more useful
	for generating code for switches.

compiler/tag_switch.m:
	Conform to the changes in switch_util.m.

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

	Rename some predicates to better reflect their purpose.

compiler/dense_switch.m:
compiler/lookup_switch.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_tailcall.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/switch_case.m:
	Conform to the changes above.

tests/hard_coded/multi_arm_switch_2.{m,exp}:
tests/hard_coded/string_switch.{m,exp}:
	New test cases to exercise the new functionality.

tests/hard_coded/Mmakefile:
	Enable the new tests.
2009-08-25 23:47:00 +00:00
Zoltan Somogyi
98b724457c Add prefixes to some function symbols to prevent ambiguities.
Estimated hours taken: 3
Branches: main

compiler/mlds.m:
	Add prefixes to some function symbols to prevent ambiguities.

compiler/*.m:
	Conform to the change in mlds.m. There are no algorithmic changes.
2009-06-10 06:26:22 +00:00
Zoltan Somogyi
bc58c406ca Misc cleanups of MLDS code generation.
Estimated hours taken: 6
Branches: main

compiler/mercury_compile.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds.m:
compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/modules.m:
compiler/rtti_to_mlds.m:
compiler/switch_detection.m:
	Misc cleanups of MLDS code generation.
2009-01-16 02:31:26 +00:00
Zoltan Somogyi
097b45acec Fix two problems that together caused bug Mantis bug #44.
Estimated hours taken: 12
Branches: main

Fix two problems that together caused bug Mantis bug #44.

The first bug was that unify_gen.m wasn't checking whether a variable it was
adding to a closure was of dummy type or not.

The second bug was that the code for recognizing whether a type is dummy or not
recognized only two cases: builtin dummy types such as io.state, and types
with one function symbol of arity zero. In this program, there is a notag
wrapper around a dummy type. Since the representation of a notag type is
always the same as the type it wraps, this notag type should be recognized
as a dummy type too.

compiler/unify_gen.m:
	Fix the first bug by adding the required checks.

compiler/code_info.m:
	Add a utility predicate to factor out some now common code in
	unify_gen.m.

(The modifications to all the following files were to fix the second bug.)

compiler/hlds_data.m:
compiler/prog_type.m:
	Change the type_category type (in prog_type.m) and the enum_or_dummy
	type (in hlds_data.m) to separate out the representation of notag types
	from other du types. This allows the fix for the second bug, and
	incidentally allows some parts of the compiler to avoid the same tests
	over and over.

	To ensure that all places in the compiler that could need special
	handling for notag types get them, rename those types to
	type_ctor_category (since it does *not* take argument types into
	account) and du_type_kind respectively.

	Since the type_ctor_category type needs to be modified anyway,
	change it to allow code that manipulates values of the type to
	factor out common code fragments.

	Rename some predicates, and turn some into functions where this helps
	to make code (either here or in clients) more robust.

compiler/make_tags.m:
	When creating a HLDS representation for a du type, record whether
	it is a notag type (we already recorded whether it is enum or dummy).

compiler/type_util.m:
	Fix the predicate that tests for dummy types by recognizing the third
	way a type can be a dummy type.

	Don't test for dummyness of the argument when deciding whether
	a type could be a notag types; just record it as a notag type,
	and let later lookup code use the new fixed algorithm to do the right
	thing.

	Add a type for recording the is_dummy_type/is_not_dummy_type
	distinction.

	Rename some predicates, and turn some into functions where this helps
	to make code (either here or in clients) more robust.

	Add an XXX about possible redundant code.

compiler/llds.m:
	Use the new type instead of booleans in some places.

compiler/add_pragma.m:
compiler/add_special_pred.m:
compiler/add_type.m:
compiler/bytecode_gen.m:
compiler/continuation_info.m:
compiler/ctgc.selector.m:
compiler/ctgc.util.m:
compiler/equiv_type_hlds.m:
compiler/erl_call_gen.m:
compiler/erl_code_gen.m:
compiler/erl_code_util.m:
compiler/erl_unify_gen.m:
compiler/exception_analysis.m:
compiler/export.m:
compiler/foreign.m:
compiler/higher_order.m:
compiler/hlds_data.m:
compiler/hlds_out.m:
compiler/hlds_pred.m:
compiler/inst_match.m:
compiler/intermod.m:
compiler/llds_out.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds.m:
compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/polymorphism.m:
compiler/pragma_c_gen.m:
compiler/prog_type.m:
compiler/rtti_to_mlds.m:
compiler/simplify.m:
compiler/special_pred.m:
compiler/stack_layout.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_constr_util.m:
compiler/term_norm.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/var_locn.m:
	Conform to the changes above.

	Make a few analyses more precise by using the new detail in the
	type_ctor_category type to make less conservative assumptions about
	du types that are either notag or dummy.

	In ctgc.selector.m, ctgc.util.m, make_tags.m, mlds_to_java.m
	and special_pred.m, add XXXs about possible bugs.

tests/valid/fzn_debug_abort.m:
	Add the bug demo program from Mantis as a regression test.

tests/valid/Mmakefile:
tests/valid/Mercury.options:
	Enable the new test, and run it with the old bug-inducing option.
2008-02-11 21:27:48 +00:00
Zoltan Somogyi
9ad83d648d Convert predicates that used to have one clause for each kind of
Estimated hours taken: 12
Branches: main

compiler/*.m:
	Convert predicates that used to have one clause for each kind of
	HLDS goal into explicit disjunctions, since this gives the debugger
	a meaningful name for each argument. In some cases, this exposed
	arguments that were used by *no* clause. In other cases, it allowed
	factoring out common code, as well as code that *should* have been
	common but wasn't.

	Put the disjuncts in a meaningful order. In too many cases, they were
	almost random.

	Merge the resulting predicates into their parents, in places where
	the Prolog indexing one could get from separate clauses was the only
	reason for separating those predicates from their parents in the first
	place. Similarly, merge child predicates handling generic call kinds
	and such back into the main predicate where this improves clarity.
	In some cases, this allows putting the extraction of hlds_goal_expr
	from a hlds_goal into one place, instead of repeating it in lots of
	places.

	Give some predicates more descriptive names. In some cases, rationalize
	argument order. In some cases, rationalize the order of predicates
	in the module.

	Replace some uses of booleans with purpose-specific types.

	Give some fields names, and put type-identifying prefixes on the names
	of other fields, to make tag files work better.

	In some cases, reorder fields to them put into related groups.

	Use more standard and/or more descriptive variable names

	Use a standard syntax for if-then-else in each module.

	Follow our style convention for comments.
2008-01-21 00:32:55 +00:00
Zoltan Somogyi
672f77c4ec Add a new compiler option. --inform-ite-instead-of-switch.
Estimated hours taken: 20
Branches: main

Add a new compiler option. --inform-ite-instead-of-switch. If this is enabled,
the compiler will generate informational messages about if-then-elses that
it thinks should be converted to switches for the sake of program reliability.

Act on the output generated by this option.

compiler/simplify.m:
	Implement the new option.

	Fix an old bug that could cause us to generate warnings about code
	that was OK in one duplicated copy but not in another (where a switch
	arm's code is duplicated due to the case being selected for more than
	one cons_id).

compiler/options.m:
	Add the new option.

	Add a way to test for the bug fix in simplify.

doc/user_guide.texi:
	Document the new option.

NEWS:
	Mention the new option.

library/*.m:
mdbcomp/*.m:
browser/*.m:
compiler/*.m:
deep_profiler/*.m:
	Convert if-then-elses to switches at most of the sites suggested by the
	new option. At the remaining sites, switching to switches would have
	nontrivial downsides. This typically happens with the switched-on type
	has many functors, and we treat one or two specially (e.g. cons/2 in
	the cons_id type).

	Perform misc cleanups in the vicinity of the if-then-else to switch
	conversions.

	In a few cases, improve the error messages generated.

compiler/accumulator.m:
compiler/hlds_goal.m:
	(Rename and) move insts for particular kinds of goal from
	accumulator.m to hlds_goal.m, to allow them to be used in other
	modules. Using these insts allowed us to eliminate some if-then-elses
	entirely.

compiler/exprn_aux.m:
	Instead of fixing some if-then-elses, delete the predicates containing
	them, since they aren't used, and (as pointed out by the new option)
	would need considerable other fixing if they were ever needed again.

compiler/lp_rational.m:
	Add prefixes to the names of the function symbols on some types,
	since without those prefixes, it was hard to figure out what type
	the switch corresponding to an old if-then-else was switching on.

tests/invalid/reserve_tag.err_exp:
	Expect a new, improved error message.
2007-11-23 07:36:01 +00:00
Julien Fischer
f6e8e9bc53 Replace a pair with a specific d.u. type.
Estimated hours taken: 0.5
Branches: main

Replace a pair with a specific d.u. type.

compiler/mlds.m:
	Use a specific d.u. type to represent switches in the MLDS instead
	of a pair.

compiler/ml_closure_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_tailcall.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
	Conform to the above change.
2007-08-21 17:40:33 +00:00
Julien Fischer
1a4256fa32 Rename some function symbols in the MLDS in order avoid ambiguities.
Estimated hours taken: 1
Branches: main

Rename some function symbols in the MLDS in order avoid ambiguities.

Fix an omission in the MLDS backend's handling of switches on foreign
enumerations.

compiler/mlds.m:
	Add the prefix `ml_stmt_' to the constructors of the mlds_stmt/0 type.
	The current names conflict with those in the HLDS and LLDS.

compiler/ml_simplify_switch.m:
	Fix the above omission.

	Try to avoid something similar occurring again by change the semidet
	predicate is_integral_type/1 into a boolean function that switches
	on the type mlds_type/0.

compiler/ml_elim_nested.m:
	Turn some if-then-elses into the switches.

compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_optimize.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
	Conform to the above change.
2007-08-21 15:50:44 +00:00
Zoltan Somogyi
e21193c283 Rename a bunch of predicates and function symbols to eliminate
Estimated hours taken: 6
Branches: main

browser/*.m:
compiler/*.m:
	Rename a bunch of predicates and function symbols to eliminate
	ambiguities.

	The only real change is factoring out some common code in the mlds
	and llds code generators, replacing them with single definitions
	in switch_util.m.
2006-10-15 23:26:56 +00:00
Zoltan Somogyi
00741b0162 This diff contains no algorithmic changes.
Estimated hours taken: 6
Branches: main

This diff contains no algorithmic changes. It merely renames apart a bunch more
function symbols to reduce ambiguity.

After this diff, the summary line from the mdb command "ambiguity -f" is

	Total: 351 names used 975 times, maximum 31, average: 2.78

browser/*.m:
compiler/*.m:
	Rename function symbols to eliminate ambiguities.

tests/debugger/declarative/dependency.exp:
tests/debugger/declarative/dependency2.exp:
	Update the expected out where some internal function symbol names
	appear in the output of the debugger. (This output is meant for
	implementors only.)
2006-08-22 05:04:29 +00:00
Julien Fischer
aeeedd2c13 Standardize formatting of comments at the beginning of modules.
compiler/*.m:
	Standardize formatting of comments at the beginning of modules.
2006-07-31 08:32:11 +00:00
Zoltan Somogyi
469f1dc09b This diff contains no algorithmic changes.
Estimated hours taken: 1.5
Branches: main

This diff contains no algorithmic changes.

compiler/llds.m:
compiler/mlds.m:
	Rename some function symbols and field names to avoid ambiguities
	with respect to language keywords.

compiler/*.m:
	Conform to the changes in llds.m and mlds.m.
2006-07-28 05:08:15 +00:00
Julien Fischer
459847a064 Move the univ, maybe, pair and unit types from std_util into their own
Estimated hours taken: 18
Branches: main

Move the univ, maybe, pair and unit types from std_util into their own
modules.  std_util still contains the general purpose higher-order programming
constructs.

library/std_util.m:
	Move univ, maybe, pair and unit (plus any other related types
	and procedures) into their own modules.

library/maybe.m:
	New module.  This contains the maybe and maybe_error types and
	the associated procedures.

library/pair.m:
	New module.  This contains the pair type and associated procedures.

library/unit.m:
	New module. This contains the types unit/0 and unit/1.

library/univ.m:
	New module. This contains the univ type and associated procedures.

library/library.m:
	Add the new modules.

library/private_builtin.m:
	Update the declaration of the type_ctor_info struct for univ.

runtime/mercury.h:
	Update the declaration for the type_ctor_info struct for univ.

runtime/mercury_mcpp.h:
runtime/mercury_hlc_types.h:
	Update the definition of MR_Univ.

runtime/mercury_init.h:
	Fix a comment: ML_type_name is now exported from type_desc.m.

compiler/mlds_to_il.m:
	Update the the name of the module that defines univs (which are
	handled specially by the il code generator.)

library/*.m:
compiler/*.m:
browser/*.m:
mdbcomp/*.m:
profiler/*.m:
deep_profiler/*.m:
	Conform to the above changes.  Import the new modules where they
	are needed; don't import std_util where it isn't needed.

	Fix formatting in lots of modules.  Delete duplicate module
	imports.

tests/*:
	Update the test suite to confrom to the above changes.
2006-03-29 08:09:58 +00:00
Zoltan Somogyi
be5b71861b Convert almost all the compiler modules to use . instead of __ as
Estimated hours taken: 6
Branches: main

compiler/*.m:
	Convert almost all the compiler modules to use . instead of __ as
	the module qualifier.

	In some cases, change the names of predicates and types to make them
	meaningful without the module qualifier. In particular, most of the
	types that used to be referred to with an "mlds__" prefix have been
	changed to have a "mlds_" prefix instead of changing the prefix to
	"mlds.".

	There are no algorithmic changes.
2006-03-17 01:40:46 +00:00
Julien Fischer
45fdb6c451 Use expect/3 in place of require/2 throughout most of the
Estimated hours taken: 4
Branches: main

compiler/*.m:
	Use expect/3 in place of require/2 throughout most of the
	compiler.

	Use unexpected/2 (or sorry/2) in place of error/1 in more
	places.

	Fix more dodgy assertion error messages.

	s/map(prog_var, mer_type)/vartypes/ where the latter is meant.
2005-11-28 04:11:59 +00:00
Zoltan Somogyi
21685c9e22 Improve the error messages generated for determinism errors involving committed
Estimated hours taken: 6
Branches: main

Improve the error messages generated for determinism errors involving committed
choice contexts. Previously, we printed a message to the effect that e.g.
a cc pred is called in context that requires all solutions, but we didn't say
*why* the context requires all solutions. We now keep track of all the goals
to the right that could fail, since it is these goals that may reject the first
solution of a committed choice goal.

The motivation for this diff was the fact that I found that locating the
failing goal can be very difficult if the conjunction to the right is
a couple of hundred lines long. This would have been a nontrivial problem,
since (a) unifications involving values of user-defined types are committed
choice goals, and (b) we can expect uses of user-defined types to increase.

compiler/det_analysis.m:
	Keep track of goals to the right of the current goal that could fail,
	and include them in the error representation if required.

compiler/det_report.m:
	Include the list of failing goals to the right in the representations
	of determinism errors involving committed committed choice goals.

	Convert the last part of this module that wasn't using error_util
	to use error_util. Make most parts of this module just construct
	error message specifications; print those specifications (using
	error_util) in only a few places.

compiler/hlds_out.m:
	Add a function for use by the new code in det_report.m.

compiler/error_util.m:
	Add a function for use by the new code in det_report.m.

compiler/error_util.m:
compiler/compiler_util.m:
	Error_util is still changing reasonably often, and yet it is
	included in lots of modules, most of which need only a few simple
	non-parse-tree-related predicates from it (e.g. unexpected).
	Move those predicates to a new module, compiler_util.m. This also
	eliminates some undesirable dependencies from libs to parse_tree.

compiler/libs.m:
	Include compiler_util.m.

compiler/notes/compiler_design.html:
	Document compiler_util.m, and fix the documentation of some other
	modules.

compiler/*.m:
	Import compiler_util instead of or in addition to error_util.
	To make this easier, consistently use . instead of __ for module
	qualifying module names.

tests/invalid/det_errors_cc.{m,err_exp}:
	Add this new test case to test the error messages for cc contexts.

tests/invalid/det_errors_deet.{m,err_exp}:
	Add this new test case to test the error messages for unifications
	inside function symbols.

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

tests/invalid/det_errors.err_exp:
tests/invalid/magicbox.err_exp:
	Change the expected output to conform to the change in det_report.m,
	which is now more consistent.
2005-11-04 03:41:09 +00:00
Zoltan Somogyi
f9fe8dcf61 Improve the error messages generated for determinism errors involving committed
Estimated hours taken: 8
Branches: main

Improve the error messages generated for determinism errors involving committed
choice contexts. Previously, we printed a message to the effect that e.g.
a cc pred is called in context that requires all solutions, but we didn't say
*why* the context requires all solutions. We now keep track of all the goals
to the right that could fail, since it is these goals that may reject the first
solution of a committed choice goal.

The motivation for this diff was the fact that I found that locating the
failing goal can be very difficult if the conjunction to the right is
a couple of hundred lines long. This would have been a nontrivial problem,
since (a) unifications involving values of user-defined types are committed
choice goals, and (b) we can expect uses of user-defined types to increase.

compiler/det_analysis.m:
	Keep track of goals to the right of the current goal that could fail,
	and include them in the error representation if required.

compiler/det_report.m:
	Include the list of failing goals to the right in the representations
	of determinism errors involving committed committed choice goals.

	Convert the last part of this module that wasn't using error_util
	to use error_util. Make most parts of this module just construct
	error message specifications; print those specifications (using
	error_util) in only a few places.

compiler/hlds_out.m:
	Add a function for use by the new code in det_report.m.

compiler/error_util.m:
	Add a function for use by the new code in det_report.m.

compiler/error_util.m:
compiler/compiler_util.m:
	Error_util is still changing reasonably often, and yet it is
	included in lots of modules, most of which need only a few simple
	non-parse-tree-related predicates from it (e.g. unexpected).
	Move those predicates to a new module, compiler_util.m. This also
	eliminates some undesirable dependencies from libs to parse_tree.

compiler/libs.m:
	Include compiler_util.m.

compiler/notes/compiler_design.html:
	Document compiler_util.m, and fix the documentation of some other
	modules.

compiler/*.m:
	Import compiler_util instead of or in addition to error_util.
	To make this easier, consistently use . instead of __ for module
	qualifying module names.

tests/invalid/det_errors_cc.{m,err_exp}:
	Add this new test case to test the error messages for cc contexts.

tests/invalid/det_errors_deet.{m,err_exp}:
	Add this new test case to test the error messages for unifications
	inside function symbols.

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

tests/invalid/det_errors.err_exp:
tests/invalid/magicbox.err_exp:
	Change the expected output to conform to the change in det_report.m,
	which is now more consistent.
2005-10-28 02:11:03 +00:00