Commit Graph

88 Commits

Author SHA1 Message Date
Zoltan Somogyi
8dbea9f096 Use a structured representation for MLDS variables.
compiler/mlds.m:
    Replace the old definition of mlds_var_name, which was a string
    with an optional integer. The integer was intended to be the number
    of a HLDS variable, while auxiliary variables created by the compiler,
    which do not correspond to a HLDS variable, would not have the optional
    integer.

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

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

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

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

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

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

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

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

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

    Delete the code moved to mlds.m.

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

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

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

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

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

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

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

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

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

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

compiler/ml_code_gen.m:
    Fix typo.
2017-04-24 15:16:36 +10:00
Zoltan Somogyi
e2878130d8 Tighten the representation of mlds_arguments.
The mlds_argument type describes an argument of an MLDS function: its name,
its type and information about how to trace it for accurate gc. However,
it represented the argument name as an entity name, so the representation
in theory allowed the argument name *itself* to be a type, a function,
the name of a global variable holding rtti information etc. However, the
only kind of entity name that ever made sense is a variable name, and there
were some places in the compiler that threw an exception if they found
the argument name to be any kind of entity name other than a variable name.

compiler/mlds.m:
    Change the representation of the name in each mlds_argument
    from an entity name to a variable name.

compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/mlds_to_c.m:
    Conform to the change above. Mostly this is by using VarNames directly,
    not wrapping them up as entity_data(mlds_data_var(VarName)).
    In several places, it is by not having to remove this wrapping.
    And in a few places, it is by adding the wrapping back, to allow
    interfacing to code that has good reason to expect entity names.

compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
    As above, but additionally, rename some predicates involved in handling
    entity and variable names.

    For predicates that used to have different definitions but identical names
    in these two files, give them a "for_csharp" or "for_java" suffix
    to avoid the ambiguity, and thus make tags files work better.

    Convert some related predicates from clauses to explicit disjunctions.
2017-04-19 13:13:14 +10:00
Zoltan Somogyi
b96dacdcac Make a bunch of switches complete.
compiler/exception_analysis.m:
compiler/frameopt.m:
compiler/get_dependencies.m:
compiler/labelopt.m:
compiler/ml_global_data.m:
compiler/ml_optimize.m:
compiler/options_file.m:
compiler/parse_class.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/type_util.m:
compiler/var_locn.m:
    As above.

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

compiler/loop_inv.m:
    Add a module qualification.

compiler/opt_util.m:
    Delete two unused predicates.
2017-03-09 13:43:48 +11:00
Zoltan Somogyi
e5daa207fa Fix disabling warnings for non-tail recursive calls with MLDS.
compiler/mlds.m:
    Add a field to call statements in MLDS that contains a (probably empty)
    set of markers. At the moment, the only marker possible is one that says
    "don't generate a non-tail recursive call warning for this call".

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

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

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

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

compiler/ml_accurate_gc.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
    Conform to the changes above.
2017-01-19 20:47:26 +11:00
Zoltan Somogyi
42ee3cbe39 Clarify the code that tests for tail recursive calls.
compiler/ml_optimize.m:
    Move the call_optimize_tailcall predicate here, since it is called
    only from this module. Give it a name that better describes its job,
    and improve its documentation.

compiler/ml_util.m:
    Give the call_is_recursive predicate a more precise (and non-leading)
    name. Change its interface to avoid redundant tests in both this predicate
    and its callers (of whether the MLDS statement is a call, and of whether
    its callee is a constant code address), and also to avoid requiring
    its callers to construct a module qualified name.

compiler/ml_tailcall.m:
    Conform to the above changes.
2017-01-13 16:23:55 +11:00
Zoltan Somogyi
e923248fc7 Add a comment. 2017-01-12 00:54:11 +11:00
Zoltan Somogyi
f64de6a2b0 Use complete switches.
compiler/ml_optimize.m:
    Replace semidet disjunctions with require_complete_switch scopes,
    with some switch arms being `fail'. This should allow us to optimize
    some MLDS code we previously didn't, because the disjunctions weren't
    updated when static common data structures were added to the MLDS.

    Replace some multi-clause definitions with explicit disjunctions
    for better readability.

    Delete some obsolete comments. Fix the grammar in some other comments.
2017-01-11 03:14:52 +11:00
Paul Bone
652d89cf38 Add take_while and drop_while to the list module
Add new predicates and functions take_while and drop_while to the list
module.

Deprecate takewhile/4, replacing it with take_while/4.

library/list.m:
    As above.

NEWS:
    Announce this change.

browser/parse.m:
compiler/compute_grade.m:
compiler/deforest.m:
compiler/mercury_compile_main.m:
compiler/ml_optimize.m:
compiler/mode_robdd.equiv_vars.m:
compiler/options_file.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.domain.m:
compiler/structure_sharing.domain.m:
compiler/term_constr_data.m:
compiler/write_deps_file.m:
compiler/xml_documentation.m:
deep_profiler/read_profile.m:
deep_profiler/top_procs.m:
library/list.m:
    Conform to above changes.
2016-04-22 21:27:03 +10:00
Zoltan Somogyi
31baa5a5bb Give some predicates better names. 2016-03-28 01:50:49 +11:00
Paul Bone
c6cbc43448 Add new require_tail_recursion pragma.
This patch allows the pragma to be parsed, and records the information from
the pragma in the proc_info structure for the relevant procedures.

The patch uses the pragma for the MLDS backend.  However because mutual
recursion is not yet supported on the MLDS backend, mutually recursive calls
are ignored by the pragma.

The patch also documents the pragma in the reference manual, this
documentation is commented out until it is implemented for both LLDS and
MLDS backends.

The patch does not implement the SCC feature discussed on the mailing list.
That can be added later.

compiler/prog_data.m:
compiler/prog_item.m:
    Add new require_tail_recursion pragma.

compiler/prog_io_pragma.m:
    Parse the new pragma.

    Remove the arity_and_modes type and use pred_name_arity_mpf_mmode
    type from prog_item.m

compiler/parse_tree_out_pragma.m:
    Support pretty printing the new pragma.

compiler/hlds_pred.m:
    Add require_tailrec_info to the proc_info structure.

compiler/add_pragma.m:
    Add information from the pragma to the proc_info structure after
    parsing.

compiler/compiler_util.m:
    Add a general warning_or_error type.

compiler/mlds.m:
    Add require_tailrec_info to MLDS functions.

compiler/ml_proc_gen.m:
    Copy the require_tailrec_info information from the HLDS to the MLDS.

compiler/ml_tailcall.m:
    Generate errors and warnings with respect to the require_tail_recursion
    pragma.

compiler/mercury_compile.m:
compiler/mercury_compile_mlds_back_end.m:
    Return errors from the MLDS tailcall optimisation pass.

compiler/add_pragma.m:
compiler/comp_unit_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/item_util.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.qual_errors.m:
compiler/module_qual.qualify_items.m:
compiler/prog_item_stats.m:
compiler/recompilation.version.m:
compiler/write_module_interface_files.m:
    Conform to changes in prog_item.m.

compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_type_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
    Conform to changes in mlds.m.

doc/reference_manual.texi
    Document the require_tail_recursion pragma

tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/require_tail_recursion.err_exp:
tests/invalid/require_tail_recursion.m:
    Add require_tail_recursion test case
2015-12-08 22:54:59 +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
Julien Fischer
3dd02876a5 Delete the MLDS->IL backend.
compiler/mlds_to_il.m:
compiler/mlds_to_ilasm.m:
compiler/mlds_to_managed.m:
compiler/il_peephole.m:
compiler/ilasm.m:
compiler/ilds.m:
    Delete the modules making up the MLDS->IL code generator.

compiler/globals.m:
compiler/prog_data.m:
    Delete IL as a target and foreign language.

compiler/prog_io_pragma.m:
    Delete the max_stack_size/1 foreign proc attribute.  This was only
    ever required by the IL backend.

compiler/options.m
    Delete options used for the IL backend.

compiler/write_deps_file.m:
    Don't generate mmake targets for .il files etc.

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

compiler/notes/compiler_design.html
compiler/notes/work_in_progress.html
    Conform to the above changes.

library/*.m:
    Delete IL foreign_proc and foreign_export pragmas.

README.DotNet:
    Delete this file.

browser/Mmakefile:
compiler/Mmakefile:
deep_profiler/Mmakefile:
mdbcomp/Mmakefile:
mfilterjavac/Mmakefile:
profiler/Mmakefile:
runtime/Mmakefile:
slice/Mmakefile:
    Conform the above changes.

configure.ac:
    Don't check that IL is a supported foreign language when performing the
    up-to-date check.

    Delete the '--enable-dotnet-grades' option.

scripts/Mmake.vars.in:
    Delete variables used for the IL backend (and in on case by the Aditi
    backend).

scripts/Mercury.config.bootstrap.in:
scripts/Mercury.config.in:
scripts/Mmake.rules:
scripts/canonical_grade.sh-subr:
tools/bootcheck:
    Delete stuff related to the 'il' and 'ilc' grades.

doc/reference_manual.texi:
     Delete the documentation of the 'max_stack_size' option.

doc/user_guide.texi:
     Delete stuff related to the IL backend.

tests/hard_coded/csharp_test.{m,exp}:
tests/invalid/foreign_type_missing.{m,err_exp}:
tests/valid/csharp_hello.m:
	Delete these tests: they are no longer relevant.

tests/hard_coded/equality_pred_which_requires_boxing.m:
tests/hard_coded/foreign_import_module.m:
tests/hard_coded/foreign_import_module_2.m:
tests/hard_coded/foreign_type.m:
tests/hard_coded/foreign_type2.m:
tests/hard_coded/foreign_type3.m:
tests/hard_coded/intermod_foreign_type2.m:
tests/hard_coded/lp.m:
tests/hard_coded/user_compare.m:
tests/invalid/foreign_type_2.m:
tests/invalid/foreign_type_missing.{m,err_exp}:
tests/invalid/foreign_type_visibility.m:
tests/invalid/illtyped_compare.{m,err_exp}:
tests/submodules/external_unification_pred.m
tests/valid/big_foreign_type.m
tests/valid/solver_type_bug.m
tests/valid_seq/foreign_type_spec.m
tests/valid_seq/intermod_impure2.m
    Delete IL foreign_procs where necessary.

tests/hard_coded/Mmakefile
tests/invalid/Mercury.options
tests/invalid/Mmakefile
tests/submodules/Mmakefile
tests/valid/Mercury.options
tests/valid/Mmake.valid.common
tests/valid/Mmakefile
tests/valid_seq/Mmakefile
tests/valid_seq/Mercury.options
    Conform to the above changes.
2015-09-21 11:34:46 +10: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
d041b83943 Implement string switches via tries for the MLDS backend.
The code we emit to decide which arm of the switch is selected looks like this:

    case_num = -1;
    switch (MR_nth_code_unit(switchvar, 0)) {
        case '98':
            switch (MR_nth_code_unit(switchvar, 1)) {
                case '99':
                    if (MR_offset_streq(2, switchvar, "abc"))
                        case_num = 0;
                    break;
                case '100':
                    if (MR_offset_streq(2, switchvar, "aceg"))
                        case_num = 1;
                    break;
            }
            break;
        case '99':
            if (MR_offset_streq(2, switchvar, "bbb"))
                case_num = 2;
            break;
    }

The part that acts on this will look like this for lookup switches:

    if (case_num < 0)
        succeeded = MR_FALSE;
    else {
        outvar1 = vector_common[case_num].f1;
        ...
        outvarn = vector_common[case_num].fn;
        succeeded = MR_TRUE;
    }

and like this for non-lookup switches:

    switch (case_num) {
    case 0:
        <code for case 0>
        break;
    ...
    case n:
        <code for case n>
        break;
    default:                    /* if the switch is can_fail */
        <code for failure>
        break;
    }

compiler/ml_string_switch.m:
    Implement both non-lookup and lookup string switches via tries,
    along the lines shown above.

compiler/ml_switch_gen.m:
    Invoke the predicates that implement string switches via tries
    in the circumstances in which option values call for them.

    For now, we generate tries only for the C backend. Once the
    problems identified for mlds_to_{cs,java,managed} below are fixed,
    we can enable them on those backends as well.

compiler/options.m:
doc/user_guide.texi:
    Add an option that governs the minimum size of trie switches.

compiler/ml_lookup_switch.m:
    Factor out the code common to the implementation of all model-non
    lookup switches, both in ml_lookup_switch.m and ml_string_switch.m,
    and put it all into a new exported predicate.

    The previously existing MLDS implementation methods for lookup switches
    all build their lookup tables from maps that maps each cons_id
    in the switch cases to the values of the output arguments of those cases.
    For switch cases that apply to more than one cons_id, this map had
    one entry for each of those cons_ids. For tries, we need a map
    from *case ids*, not *cons ids* to the outputs. Since it is
    easier to convert the one-to-one case_id->outputs map to the
    many-to-one cons_id->outputs map than vice versa, change the
    main data structure from which lookup tables are built to store data
    in a case_id->outputs format, and provide predicates for its conversion
    to the other (previously the only) format.

    Rename ml_gen_lookup_switch to ml_gen_atomic_lookup_swith to distinguish
    it from other predicates that also generate (other kinds of) lookup
    switches.

compiler/switch_util.m:
    Have the types representating lookup tables represent their contents
    as a map, not as the assoc list derived from the map. Previously,
    we didn't do anything with the map other than flatten it to the assoc list,
    but for the MLDS backend, we may now also need to convert it to another
    form of map (see immediately above).

compiler/builtin_ops.m:
    Add two new builtin ops. The first, string_unsafe_index_code_unit,
    returns the nth code unit in a string; the second, offset_str_eq,
    does a string equality test on the nth and later code units of
    two strings. They are used in the implementation of tries.

compiler/c_util.m:
    Add a new binop category for each new binop, since they are not like
    existing binops.

    Put some existing binops into their own categories as well, since
    bundling them with the other ops they were bundled with seems like
    a bad idea.

compiler/hlds_goal.m:
    Make the identifier of switch arms in tagged_cases a separate type
    from int.

compiler/mlds_to_c.m:
compiler/llds_out_data.m:
    Handle the new kinds of binops.

    When writing out binop expressions, we used to do a switch on the binop
    to get its category, and then another switch on the category. We now
    switch on the binop directory, since this much harder to write out
    code using new binops badly, and should be faster to boot.

    In mlds_to_c.m, also make some cosmetic changes to the output to make it
    easier to read, and thus to debug.

compiler/mlds_to_il.m:
    Handle the new kinds of binops.

compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
    Do not handle the new kinds of binops, since doing so would require
    changing the whole approach of how these modules handle binops.

    Clean up some predicates.

compiler/bytecode.m:
compiler/erl_call_gen.m:
compiler/lookup_switch.m:
compiler/ml_global_data.m:
compiler/ml_optimize.m:
compiler/ml_tag_switch.m:
compiler/opt_debug.m:
compiler/string_switch.m:
    Conform to the changes above.

compiler/ml_code_gen.m:
    Put the predicates of this module into a consistent order.

library/string.m:
    Fix white space.

runtime/mercury_string.h:
    Add a macro for each of the two new builtin operations.
2015-02-24 16:03:30 +11:00
Zoltan Somogyi
500948d549 Break up mdbcomp/prim_data.m. The new modules have much better cohesion.
mdbcomp/sym_name.m:
    New module, containing the part of the old prim_data.m that
    dealt with sym_names.

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

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

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

browser/*.m:
compiler/*.m:
deep_proiler/*.m:
mdbcomp/*.m:
slice/*.m:
    Conform to the above changes.
2014-09-02 05:20:23 +02:00
Zoltan Somogyi
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
15da4e26e4 Add a peephole pass to the MLDS optimization suite.
Estimated hours taken: 6
Branches: main

compiler/ml_optimize.m:
	Add a peephole pass to the MLDS optimization suite.

	The one pattern we now optimize is code that has redundant tests:

	if (testcond) {
		...
	} else {
		...
	}
	if (testcond) {
		...
	} else {
		...
	}

	If neither the then-part nor the else-part of the first if-then-else
	updates any lval in testcond, then the second test is redundant, and
	the peephole pattern therefore optimizes it away.

	The pattern seems to occur mostly with semidet deconstructions.
	The semidet deconstruction tests whether the variable has the right
	functor, the then-part of that if-then-else picks up its argument
	values, there is no else part, and the next statement starts by testing
	whether the previous one succeeded, using the exact same condition
	as the semidet deconstruction.

compiler/mercury_compile_mlds_back_end.m:
	Improve the format of a comment.

compiler/options.m:
doc/user_guide.text:
	Add another name, --mlds-peephole, for the existing peephole
	optimization flag, which until now was used only by the LLDS backend.
2011-08-01 03:31:03 +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
Peter Wang
7e26b55e74 Implement a new form of memory profiling, which tells the user what memory
Branches: main

Implement a new form of memory profiling, which tells the user what memory
is being retained during a program run.  This is done by allocating an extra
word before each cell, which is used to "attribute" the cell to an
allocation site.  The attribution, or "allocation id", is an address to an
MR_AllocSiteInfo structure generated by the Mercury compiler, giving the
procedure, filename and line number of the allocation, and the type
constructor and arity of the cell that it allocates.

The user must manually instrument the program with calls to
`benchmarking.report_memory_attribution', which forces a GC and summarises
the live objects on the heap using the attributions.  The mprof tool is
extended with a new mode to parse and present that data.

Objects which are unattributed (e.g. by hand-written C code which hasn't
been updated) are still accounted for, but show up in profiles as "unknown".

Currently this profiling mode only works in conjunction with the Boehm
garbage collector, though in principle it can work with any memory allocator
for which we can access a list of the live objects.  Since term size
profiling relies on the same technique of using an extra word per memory
cell, the two profiling modes are incompatible.

The output from `mprof -s' looks like this:

------ [1] some label ------
   cells            words         cumul  procedure / type (location)
   14150            38872                total

*   1949/ 13.8%      4872/ 12.5%  12.5%  <predicate `parser.parse_rest/7' mode 0>
     975/  6.9%      1950/  5.0%         list.list/1 (parser.m:502)
     487/  3.4%      1948/  5.0%         term.term/1 (parser.m:501)
     487/  3.4%       974/  2.5%         term.const/0 (parser.m:501)

*   1424/ 10.1%      4272/ 11.0%  23.5%  <predicate `parser.parse_simple_term_2/6' mode 0>
     708/  5.0%      2832/  7.3%         term.term/1 (parser.m:643)
     708/  5.0%      1416/  3.6%         term.const/0 (parser.m:643)
...


boehm_gc/alloc.c:
boehm_gc/include/gc.h:
boehm_gc/misc.c:
boehm_gc/reclaim.c:
	Add a callback function to be called for every live object after a GC.

	Add a function to write out the GC_size_map array.

compiler/layout.m:
	Define the alloc_site_info type which is equivalent to the
	MR_AllocSiteInfo C structure.

	Add alloc_site_array as a kind of "layout" array.

compiler/llds.m:
	Add allocation sites to `cfile' structure.

	Replace TypeMsg argument (which was also for profiling) on `incr_hp'
	instructions by an allocation site identifier.

	Add a new foreign_proc_component for allocation site ids.

compiler/code_info.m:
compiler/global_data.m:
compiler/proc_gen.m:
	Keep the set of allocation sites in the code_info and global_data
	structures.

compiler/unify_gen.m:
	Add allocation sites to LLDS allocation instructions.

compiler/layout_out.m:
compiler/llds_out_file.m:
compiler/llds_out_instr.m:
	Output MR_AllocSiteInfo arrays in generated C files.

	Output code to register the MR_AllocSiteInfo array with the Mercury
	runtime.

	Output allocation site ids for memory allocation instructions.

compiler/llds_out_util.m:
	Add allocation sites to llds_out_info.

compiler/pragma_c_gen.m:
compiler/ml_foreign_proc_gen.m:
	Generate a macro MR_ALLOC_ID which resolves to an allocation site
	structure, for every foreign_proc whose C code contains the string
	"MR_ALLOC_ID".  This is to be used by hand-written C code which
	allocates memory.

	MR_PROC_LABELs are retained for backwards compatibility.  Though
	they were introduced for profiling, they seem to have been co-opted
	for printf-debugging since then.

compiler/ml_global_data.m:
	Add allocation site structures to the MLDS global data.

compiler/mlds.m:
compiler/ml_unify_gen.m:
	Add allocation site id to `new_object' instruction.

compiler/mlds_to_c.m:
	Output allocation site arrays and allocation ids in high-level C code.

	Output a call to register the allocation site array with the Mercury
	runtime.

	Delete an unused predicate.

compiler/exprn_aux.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/mercury_compile_llds_back_end.m:
compiler/middle_rec.m:
compiler/ml_accurate_gc.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_util.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/use_local_vars.m:
compiler/var_locn.m:
	Conform to changes.

compiler/pickle.m:
compiler/prog_event.m:
compiler/timestamp.m:
	Conform to changes in memory allocation macros.

library/benchmarking.m:
	Add the `report_memory_attribution' instrumentation predicates.

	Conform to changes to MR_memprof_record.

library/array.m:
library/bit_buffer.m:
library/bitmap.m:
library/construct.m:
library/deconstruct.m:
library/dir.m:
library/io.m:
library/mutvar.m:
library/store.m:
library/string.m:
library/thread.semaphore.m:
library/version_array.m:
	Use attributed memory allocation throughout the standard library so
	that objects don't show up in the memory profile as "unknown".

	Replace MR_PROC_LABEL by MR_ALLOC_ID.

mdbcomp/program_representation.m:
mdbcomp/rtti_access.m:
	Replace MR_PROC_LABEL by MR_ALLOC_ID.

profiler/Mercury.options:
profiler/globals.m:
profiler/mercury_profile.m:
profiler/options.m:
profiler/output.m:
profiler/snapshots.m:
	Add a new mode to `mprof' to parse and present the data from
	`Prof.Snapshots' files.

	Add options for the new profiling mode.

profiler/process_file.m:
	Fix a typo.

runtime/mercury_conf_param.h:
	#define MR_MPROF_PROFILE_MEMORY_ATTRIBUTION if memory profiling
	is enabled and we are using Boehm GC.

runtime/mercury.h:
	Make MR_new_object take an allocation id argument.

	Conform to changes in memory allocation macros.

runtime/mercury_memory.c:
runtime/mercury_memory.h:
runtime/mercury_types.h:
	Define MR_AllocSiteInfo.

	Add memory allocation functions and macros which take into the
	account the additional word necessary for the new profiling mode.
	These should be used in preferences to the raw memory allocation
	functions wherever possible so that objects do not show up in the
	profile as "unknown".

	Add analogues of realloc/free which take into account the offset
	introduced by the attribution word.

	Add function versions of the MR_new_object macros, which can't be
	written in standard C.  They are only used when necessary.

	Add built-in allocation site ids, to be used in the runtime and
	other hand-written code when context-specific ids are unavailable.

runtime/mercury_heap.h:
	Make MR_tag_offset_incr_hp_msg and MR_tag_offset_incr_hp_atomic_msg
	allocate an extra word when memory attribution is desired, and store
	the allocation id there.

	Similarly for MR_create{1,2,3}_msg.

	Replace proclabel arguments in allocation macros by alloc_id
	arguments.

	Replace MR_hp_alloc_atomic by MR_hp_alloc_atomic_msg.  It was only
	used for boxing floats.

	Conform to change to MR_new_object macro.

runtime/mercury_bootstrap.h:
	Delete obsolete macro hp_alloc_atomic.

runtime/mercury_heap_profile.c:
runtime/mercury_heap_profile.h:
	Add the code to summarise the live objects on the Boehm GC heap and
	writes out the data to `Prof.Snapshots', for display by mprof.

	Don't store the procedure name in MR_memprof_record: the procedure
	address is enough and faster to compare.

runtime/mercury_prof.c:
	Finish and close the `Prof.Snapshots' file when the program
	terminates.

	Conform to changes in MR_memprof_record.

runtime/mercury_misc.h:
	Add a macro to expand to the name of the allocation sites array
	in LLDS grades.

runtime/mercury_bitmap.c:
runtime/mercury_bitmap.h:
	Pass allocation id through bitmap allocation functions.

	Delete unused function MR_string_to_bitmap.

runtime/mercury_string.h:
	Add MR_make_aligned_string_copy_msg.

	Make string allocation macros take allocation id arguments.

runtime/mercury.c:
runtime/mercury_array_macros.h:
runtime/mercury_context.c:
runtime/mercury_deconstruct.c:
runtime/mercury_deconstruct_macros.h:
runtime/mercury_dlist.c:
runtime/mercury_engine.c:
runtime/mercury_float.h:
runtime/mercury_hash_table.c:
runtime/mercury_ho_call.c:
runtime/mercury_label.c:
runtime/mercury_prof_mem.c:
runtime/mercury_stacks.c:
runtime/mercury_stm.c:
runtime/mercury_string.c:
runtime/mercury_thread.c:
runtime/mercury_trace_base.c:
runtime/mercury_trail.c:
runtime/mercury_type_desc.c:
runtime/mercury_type_info.c:
runtime/mercury_wsdeque.c:
	Use attributed memory allocation throughout the runtime so that
	objects don't show up in the profile as "unknown".

runtime/mercury_memory_zones.c:
	Attribute memory zones to the Mercury runtime.

runtime/mercury_tabling.c:
runtime/mercury_tabling.h:
	Use attributed memory allocation macros for tabling structures.

	Delete unused MR_table_realloc_* and MR_table_copy_bytes macros.

runtime/mercury_deep_copy_body.h:
	Try to retain the original attribution word when copying values.

runtime/mercury_ml_expand_body.h:
	Conform to changes in memory allocation macros.

runtime/mercury_tags.h:
	Replace proclabel arguments by alloc_id arguments in allocation macros.

runtime/mercury_wrapper.c:
	If memory attribution is enabled, tell Boehm GC that pointers may be
	displaced by an extra word.

trace/mercury_trace.c:
trace/mercury_trace_tables.c:
	Conform to changes in memory allocation macros.

extras/net/tcp.m:
extras/solver_types/library/any_array.m:
extras/trailed_update/tr_array.m:
	Conform to changes in memory allocation macros.

doc/user_guide.texi:
	Document the new profiling mode.

doc/reference_manual.texi:
	Update a commented out example.
2011-05-20 04:16:58 +00:00
Julien Fischer
78b0bf3c7f Use state variable field update syntax in more places.
Branches: main

Use state variable field update syntax in more places.

browser/*.m:
compiler/*.m:
deep_profiler/*.m:
	As above.
2011-05-05 07:11:52 +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
Peter Wang
57f9013259 Start a C# backend, adapted from mlds_to_java.m.
Branches: main

Start a C# backend, adapted from mlds_to_java.m.

Some `pragma foreign_*' declarations are commented out in this change because
no bootstrap compiler will yet accept "C#" in the language specification.

The compiler already supported C# foreign_procs for the IL backend, but the IL
backend and this new backend do not agree on naming and calling conventions so
the changes to the existing C# foreign_procs will further break the IL backend.
Nobody cares.

Only tested so far with Mono on Linux.

compiler/mlds_to_cs.m:
        New module.  In the CVS Attic there exists an obsolete file named
        mlds_to_csharp.m (replaced by mlds_to_managed.m) which we don't want to
        conflict with.

        For C# we need to know if a `pragma foreign_type' is a value or
        reference type.  Currently this is done by accepting a fake keyword
        `valuetype' before the type name, like for IL.

compiler/ml_backend.m:
compiler/mercury_compile.m:
compiler/mercury_compile_mlds_back_end.m:
        Hook up the C# backend.

compiler/globals.m:
        Add `target_csharp' as a target language.

compiler/options.m:
        Add `--csharp' and `--csharp-only' options and their synonyms.

compiler/handle_options.m:
        Handle `target_csharp' like `target_java', except for features which
        are still to be implemented.

compiler/add_pragma.m:
        Allow C# as a `pragma foreign_export' language.

        Allow C# for `pragma foreign_export_enum'.

        Conform to changes.

compiler/hlds_data.m:
compiler/prog_data.m:
compiler/prog_io_pragma.m:
        Accept C# as a language for `pragma foreign_type'.

        Accept `csharp' as the name of a grade in trace parameters.

compiler/make_hlds_passes.m:
        Reuse most of the code for implementing mutables on Java for C#.

compiler/mlds.m:
        Add a new MLDS target language, `ml_target_csharp'.

        Conform to changes.

compiler/ml_foreign_proc_gen.m:
        Generate foreign_procs for C#.

compiler/foreign.m:
        Update predicates to support C# targets.

compiler/c_util.m:
        Make `quote_string' use hexadecimal escapes in C# string literals.

compiler/parse_tree.m:
compiler/java_names.m:
        Add C# equivalents for predicates in this module.  `java_names' is a
        misleading module name, but the predicates for C# and Java share some
        code and may possibly be combined in the future.

compiler/rtti.m:
        Add predicates to return the names of RTTI structures in C#.

compiler/simplify.m:
        Handle the trace parameter `grade(csharp)'.

compiler/compile_target_code.m:
compiler/make.dependencies.m:
compiler/make.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.util.m:
        Add some support for building of executables and libraries with
        `--target csharp'.

compiler/ml_global_data.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/granularity.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_to_mercury.m:
compiler/ml_code_util.m:
compiler/ml_disj_gen.m:
compiler/mlds_to_c.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/modules.m:
compiler/pragma_c_gen.m:
compiler/prog_foreign.m:
compiler/special_pred.m:
compiler/write_deps_file.m:
        Conform to changes.

library/builtin.m:
library/rtti_implementation.m:
library/type_desc.m:
        Implement RTTI procedures for the new backend, which uses a high-level
        data representation (like the Java backend).  The existing C# code was
        designed for the IL backend, which used a low-level representation of
        the RTTI data structures.

        Most (if not all) of the the "new" code is exactly the same as the Java
        versions, with only syntactic changes.

        Rename the C# class `void_0' to `Void_0' to match the naming convention
        used by mlds_to_cs.m.

library/array.m:
        Update the existing C# code to work with the new backend.

        Use `object[]' as the type of all array of non-primitive types.
        The problem is one we encountered on the Java backend: when creating a
        new array based on the type of a single element, we don't know whether
        the new array should contain elements of the class or superclass.

library/bool.m:
        Export `bool' constants to C#.

library/exception.m:
        Update the existing C# code to work with the new backend.

        Move the `mercury.runtime.Exception' C# class to mercury_dotnet.cs.

library/float.m:
        Add C# implementations of `is_nan' and `is_inf'.

library/list.m:
        Add methods for manipulating lists from hand-written C# code.

library/string.m:
        Add C# implementations of string procedures which were missing.

library/dir.m:
library/io.m:
library/library.m:
        Update the existing C# code to work with the new backend.

library/private_builtin.m:
        Update the existing C# code to work with the new backend.

        Delete the static constants which are duplicated in mercury_dotnet.cs.
        The mlds_to_cs.m will emit references to the constants in the latter
        only.

library/backjump.m:
library/bitmap.m:
library/mutvar.m:
library/par_builtin.m:
library/region_builtin.m:
library/store.m:
library/thread.m:
library/thread.semaphore.m:
library/time.m:
library/univ.m:
        Make these modules compile with the C# backend.

runtime/mercury_dotnet.cs.in:
        Add RTTI classes to the `mercury.runtime' namespace, equivalent to
        those on the Java backend.

        Use enumerations `MR_TYPECTOR_REP_*' and `MR_SECTAG_*' constants so we
        can switch on them.

        Add the `UnreachableDefault' exception class.

        Hide old classes which are unused with the new backend behind
        #ifdef !MR_HIGHLEVEL_DATA.
2010-09-16 00:39:12 +00:00
Peter Wang
ea45fb3083 Make the Java backend use generics in the output.
Branches: main, 10.04

Make the Java backend use generics in the output.  We do not use generics
everywhere, only where it interfaces with hand written code:

- in classes generated for Mercury types
- in the signatures of foreign_exported procedures
- in the variables which interface with foreign_proc code

Make `--java-export-ref-out' be the default.  Both changes will require users
to update their code so we might as well make them together.


compiler/mlds.m:
compiler/ml_proc_gen.m:
compiler/ml_type_gen.m:
        Record type parameters for classes generated for Mercury types.

        Record universally quantified type variables for exported procedures.

        Assume `--java-export-ref-out'.

compiler/mlds_to_java.m:
        Output type variables in the appropriate places in the Java output.

compiler/ml_code_util.m:
        Add functions to return the MLDS types for jmercury.runtime.MercuryType
        and MercuryEnum.

compiler/ml_elim_nested.m:
compiler/ml_global_data.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:
        Conform to previous changes.

compiler/hlds_pred.m:
        Change a wrong use of a type synonym.

compiler/options.m:
        Make `--java-export-ref-out' into a synonym for
        compiler_sufficiently_recent.  This may be used to test if the compiler
        supports that behaviour, and for compatibility with existing makefiles.

        Add an option for testing if the compiler generates Java code with
        generics.

doc/reference_manual.texi:
        Update manual to mention use of generics.

        Remove description of `--no-java-export-ref-out'.

library/exception.m:
library/io.m:
library/list.m:
library/rtti_implementation.m:
library/string.m:
library/type_desc.m:
        Update code to comply with use of generics and `--java-export-ref-out'.

tests/hard_coded/exceptions/Mmakefile:
        Allow `java' grade testing in this directory.
2010-04-15 02:56:02 +00:00
Zoltan Somogyi
4ebe3d0d7e Stop storing globals in the I/O state, and divide mercury_compile.m
Estimated hours taken: 60
Branches: main

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

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

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

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

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

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

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

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

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

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

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

	Give the fields of the globals structure a distinguishing prefix.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	Rename some predicates to avoid ambiguity.

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

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

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

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

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

	Conform to the changes above.

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

	Conform to the changes above.

	Convert these modules to our current programming style.

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

	Conform to the changes above.

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

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

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

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

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

compiler/add_pragma.m:
	Add notes.

compiler/string.m:
NEWS:
	Add a det version of remove_suffix, for use by new code above.
2009-10-14 05:28:53 +00:00
Peter Wang
78d25df9cc Restore high-level data C grades.
Branches: main

Restore high-level data C grades.

- Earlier, I inadvertently disabled unboxing of foreign input arguments in
  high-level data C grades.

- Earlier, I incorrectly assumed that high-level data structures don't require
  secondary tag initialiser arguments, but that is only true when targetting an
  OOP language where the object constructor sets the secondary tag.

compiler/ml_foreign_proc_gen.m:
        Make `input_arg_assignable_with_cast' fail on foreign type arguments
        without the `can_pass_as_mercury_type' assertion in hl.* grades, so the
        argument will be correctly unboxed.

        Rename HasSecTag variables to ExplicitSecTag.

compiler/ml_type_gen.m:
        Export ml_target_uses_constructors.

compiler/ml_unify_gen.m:
        Use ml_target_uses_constructors to decide if an explicit secondary tag
        argument is required when initialising a new object, not whether
        high-level data is in effect.

        Rename HasSecTag variables to ExplicitSecTag.

compiler/mlds.m:
        Clarify that the `HasSecTag' field of `new_object' means whether an
        explicit secondary tag argument is at the head of the list of
        arguments, not whether objects of that type require secondary tags.

        Rename HasSecTag variables to ExplicitSecTag.

compiler/mlds_to_il.m:
        Abort if we see a `new_object' with an explicit secondary tag, instead
        of skipping it.

compiler/ml_accurate_gc.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_java.m:
compiler/structure_reuse.direct.choose_reuse.m:
        Rename HasSecTag variables to ExplicitSecTag.
2009-10-05 04:07:44 +00:00
Zoltan Somogyi
bea43284e7 Implement lookup disjunctions and model_non lookup switches.
Estimated hours taken: 24
Branches: main

Implement lookup disjunctions and model_non lookup switches.

compiler/ml_disj_gen.m:
	New module that looks after code generation for disjunctions.
	Note the link to disj_gen.m.

	Part of the code in it comes from ml_code_gen.m, but the part that
	implements lookup disjunctions is new, and its bulk is what justifies
	a separate module.

	Even the old code has been restructured to make the decision
	about whether this is a model_non disj or not just once, instead
	of once for every single disjunct.

compiler/ml_backend.m:
compiler/notes/compiler_design.html:
	Mention the new module.

compiler/mlds.m:
	Use a purpose-specific type instead of a bool to represent
	whether a loop can loop zero times.

compiler/ml_code_gen.m:
	Remove the code moved to ml_disj_gen.m.

	Improve the style of the ml_gen_maybe_convert_goal_code_model
	predicate.

compiler/ml_lookup_switch.m:
	Implement model_non lookup switches.

	Note the link to lookup_switch.m.

	Give better names to some predicates and variables.

	Remove the predicates moved to ml_code_util.m, goal_form.m and
	ml_util.m.

compiler/switch_util.m:
	When a switch arm has several solutions, store the first solution
	separately. This assures statically that there IS a first solution
	(which a simple list of solutions does not), and prepares the first
	solution for its special treatment (it is stored in a different vector
	than the later solutions, and in the LLDS backend, we take the liveness
	after the arms from it).

compiler/ml_code_util.m:
	Move here the predicates previously in ml_lookup_switch.m that are now
	needed by ml_disj_gen.m as well. Make it possible to generate
	constants for individual arms, as well as individual field assigns,
	since ml_disj_gen.m now needs this capability.

compiler/goal_form.m:
	Move here a suitably generalized version of the two previously
	backend-specific versions of the predicates that test goals to see
	if they can be part of a lookup switch or disjunction.

compiler/ml_util.m:
	Move here from ml_lookup_switch.m a predicate now needed by
	ml_disj_gen.m as well.

compiler/lookup_util.m:
	Remove the predicate moved to goal_form.m.

	Make it possible to generate constants for a single disjunct.

	Avoid uselessly wrapping up a return argument in a yes().

compiler/disj_gen.m:
compiler/lookup_switch.m:
	Move a cheap test significantly earlier, to avoid wasting time
	on disjunctions on which it would fail.

	Conform to the changes in the backend libraries.

	In lookup_switch.m, note the paper that describes the code generation
	scheme followed by the module.

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

	When generating scalar and vector static cells, indicate the row
	numbers in comments, since without this, it is too difficult to check
	visually whether the generated code is correct.

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

	Improve the style of a big predicate.

compiler/ml_accurate_gc.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tailcall.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
	Conform to the changes above.

tests/hard_coded/dense_lookup_switch_non.{m,exp}:
	Make this test case significantly more comprehensive, by making it
	test all combinations of the presence and absence of both range checks
	and bit vector checks.

tests/hard_coded/lookup_switch_simple_bitvec.{m,exp}:
	This test was not doing its job, because the switch had too few arms
	for ml_switch_gen.m to decide that a lookup switch was worthwhile.
	It succeeded, but did not exercise the lookup switch code that existed
	in the MLDS backend before this diff. Fix this by adding more arms.
2009-10-02 03:55:36 +00:00
Zoltan Somogyi
00ea415659 Implement scalar and vector global data for the MLDS backend, modelled on
Estimated hours taken: 32
Branches: main

Implement scalar and vector global data for the MLDS backend, modelled on
the implementation of global data for the LLDS backend. Use scalar global
data to eliminate redundant copies of static memory cells. Use vector global
data to implement lookup switches, and to implement string switches more
efficiently.

The diff reduces the compiler executable's size by 3.3% by eliminating
duplicate copies of static cells. The diff can reduce the sizes of object files
not only through this reduction in the size of read-only data, but also through
reductions in the size of the needed relocation info: even in the absence of
duplicated cells, using one global variable that holds an array of all the
cells of the same type requires less relocation info than a whole bunch of
separate global variables each holding one cell. If C debugging is enabled,
we can also expect a significant reduction in the size of the debug information
stored in object files AND in executables, for the same reason. (This was the
original motivation for scalar static data on the LLDS backend; the large
amount of relocation information in object files, especially if Mercury
debugging was enabled, led to long link times.)

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

compiler/ml_lookup_switch.m:
	This new module implements lookup switches for the MLDS backend.
	For now, it implements only model_det and model_semi switches.

compiler/ml_switch_gen.m:
	Call the new module when appropriate.

	Do not require the switch generation methods that never generate
	definitions to return an empty list of definitions.

compiler/ml_backend.m:
	Add the new module.

compiler/notes/compiler_design.html:
	Mention the new module, and fix some documentation rot.

compiler/mlds.m:
	Extend the relevant types to allow the generated MLDS code to refer
	to both scalar and vector global data.

	Move a predicate that belongs here from ml_code_util.m.

	Rename a predicate to avoid ambiguity with its own return type.

	Give the functors of some types distinguishing prefixes.

compiler/ml_util.m:
	Replace some semidet predicates with functions returning bool,
	since the semidet predicates silently did the wrong thing on the new
	additions to the MLDS.

compiler/ml_code_gen.m:
	Ensure that we do not generate references to scalar and vector common
	cells on platforms which do not (yet) support them. At the moment,
	they are supported only when generating C.

	Put some code into a predicate of its own.

compiler/builtin_ops.m:
	Extend the type that represents array elements to allow them to be
	structures, which they are for vector globals.

compiler/ml_code_util.m:
	Add some new utility predicates and functions.

	Move some predicates that are now needed in more than one module here.

	Remove the predicates moved to mlds.m.

	Conform to the changes above.

compiler/ml_string_switch.m:
compiler/string_switch.m:
	Instead of two separate arrays, use one array of structures (a static
	vector), since they way, the string and the next slot indicator,
	which are accesses together, are next to each other and thus
	in the same cache block.

compiler/lookup_switch.m:
compiler/switch_util.m:
	Move several predicates from lookup_switch.m to switch_util.m,
	since now ml_lookup_switch.m needs them too. Parameterize the moved
	predicates as needed.

	Conform to the changes above.

compiler/llds.m:
	Add prefixes to some functor names to avoid ambiguities.

compiler/llds_out.m:
compiler/lookup_util.m:
compiler/mercury_compile.m:
	Minor style improvements.

compiler/global_data.m:
	Minor cleanups. Give names to some data types, and add prefixes to some
	field names.

	Conform to the changes above.

compiler/jumpopt.m:
	Minor style improvements.

	Conform to the changes above.

compiler/opt_debug.m:
	Fix some misleading variable names.

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

compiler/ll_pseudo_type_info.m:
compiler/ml_closure_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_tag_switch.m:
compiler/ml_tailcall.m:
compiler/ml_unify_gen.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:
compiler/rtti_to_mlds.m:
compiler/stack_layout.m:
compiler/unify_gen.m:
	Conform to the changes above.

tests/hard_coded/lookup_switch_simple.{m,exp}:
tests/hard_coded/lookup_switch_simple_bitvec.{m,exp}:
tests/hard_coded/lookup_switch_simple_non.{m,exp}:
tests/hard_coded/lookup_switch_simple_opt.{m,exp}:
	New test cases to exercise the new functionality.

tests/hard_coded/Mmakefile:
tests/hard_coded/Mercury.options:
	Enable the new tests.
2009-09-21 04:09:06 +00:00
Zoltan Somogyi
62d7496a7e Significant further improvements in the worst-case behavior of the compiler
Estimated hours taken: 16
Branches: main

Significant further improvements in the worst-case behavior of the compiler
when working on code such as zm_eq20.m and zm_coerce_tuples.m. On my laptop,
zm_eq20.m and zm_coerce_tuples.m now compile in 2.5s and 12.9s respectively;
the times before were 86.4s and 54.0s. The sizes of the stage 110 HLDS dumps
(the stage just after lambda expansion) go from 8.5Mb and 760Mb (!) to
just 0.4Mb and 7.4Mb respectively.

compiler/polymorphism.m:
	Remember not just which typeinfos we have constructed, but also what
	type_ctor_infos, base_typeclass_infos and typeclass_infos we have
	constructed, so that we don't have to construct them again for code
	that is executed later.

	The maintenance of the additional maps adds some overhead that in
	typical code probably cannot be made back through the resulting
	reductions in the workload of later compiler passes. However,
	the avoidance of horrible worst-case behavior trumps small increases
	in normal-case runtime.

	For zm_coerce_tuples, polymorphism.m now generates as good HLDS code
	as can be expected within each lambda expression. There is still
	a lot of duplicated code, with each copy being in a different lambda
	expression, but factoring out these commonalities will require a
	fundamentally different approach.

	Avoid using the misleading prefix "TypeClassInfo_" on the names of
	variables holding base_typeclass_infos.

compiler/ml_elim_nested.m:
	Don't look for static definitions where they cannot occur anymore.

	When deciding whether a definition needs to be hoisted out,
	don't look for it being used in later static definitions,
	since all the static definitions are now elsewhere.

	In order to avoid running the compiler out of nondet stack space
	on zm_coerce_tuples.m, avoid the use of enumerating all the
	definitions in a potentially huge piece of MLDS by backtracking.

compiler/hlds_rtti.m:
	Avoid enumerating all the members of a potentially huge list
	by backtracking in order to avoid running the compiler out of nondet
	stack space on zm_coerce_tuples.m.

	I first tried to do this by constructing the list with det code,
	but this turned out not to fix the underlying problem, which was that
	almost all of the list's elements were copies of each other, and we
	then had to get rid of the copies. The actual fix is to gather the
	types we need directly as a set.

	Provide restrict_rtti_varmaps for use by lambda.m.

	Give the field names of the rtti_varmaps type a distinguishing prefix.

compiler/lambda.m:
	The fundamental reason for the bad performance of the equiv_type_hlds
	pass on zm_coerce_tuples.m was that even with the recent improvements
	to polymorphism.m, a couple of big predicates had about ten thousand
	variables each, and when lambda.m created about 200 new procedures
	from the lambda expressions inside them, it duplicated those huge
	vartypes and rtti_varmaps for each one.

	The fix is to restrict the vartypes and the rtti_varmaps of both
	the newly created procedures and the old procedure they were taken from
	to the variables that actually occur in them.

	We could potentially avoid the need to restrict the rtti_varmap
	of the original procedure for the new procedures created for lambda
	goals by having polymorphism.m give each rhs_lambda_goal its own
	rtti_varmap in the first place, but that would be future work.

	Use the "no lambda" version of quantification after the lambda pass,
	since we have just removed all the lambdas from the goal being
	quantified.

	Give the predicates of this module more expressive names.

compiler/mercury_compile.m:
	Conform to the change in lambda.m.

compiler/equiv_type_hlds.m:
	Use specialized versions of the predicates in equiv_type.m, since
	the general versions do some things (finding circularities, recording
	used modules) that this pass does not need. Use some new predicates
	from the standard library to reduce overhead.

compiler/ml_optimize.m:
	In order to avoid running the compiler out of nondet stack space
	on zm_coerce_tuples.m, avoid the use of enumerating all the members
	of a potentially huge list by backtracking.

	Move a cheap test before a more expensive one.

compiler/modes.m:
compiler/modecheck_unify.m:
	Avoid some unnecessary overheads when modechecking typeinfos and
	related variables. One overhead was iteration over a list of exactly
	one element, another is a redundant lookup of the variable's type,
	and the third is the redundant setting of the unify context.

compiler/inst_match.m:
	Use set_tree234s instead sets to keep track of expansions in one group
	of predicates indicated by benchmarking.

library/list.m:
	Add a new predicate, list.find_first_match, which is a version of
	filter that returns only the first matching item. This is for use
	in ml_elim_nested.m.

	Make list.sort_and_remove_dups remove duplicates as it goes,
	not all at the end, since this (a) allows us to avoid a separate
	duplicate-elimination pass at the end, and (b) any duplicate eliminated
	in one merge pass reduces the workload for any later merge passes.

	Put some code in its proper order, since preserving tail recursion
	in Prolog is no longer an issue.

library/map.m:
	Add  versions of map.foldl{,2,3} and map.map_foldl{,2,3} that do not
	pass the key to the higher order argument, for use by some of the
	compiler modules above.

	Group the declarations of all the foldr predicates together.

library/tree.m:
	Make the same changes as in map.m, in order to implement map.m's new
	predicates.

library/varset.m:
	Minor style improvements.

library/set_tree234.m:
	Fix a wrong comment.

NEWS:
	Mention the new additions to the library.
2009-09-16 02:32:56 +00:00
Peter Wang
ac3d1c6027 Expose correct types to Java foreign code, e.g. a variable with a non-foreign
Branches: main

Expose correct types to Java foreign code, e.g. a variable with a non-foreign
type like `list(T)' is now visible to Java foreign code with the type
`list.List_1' instead of `java.lang.Object'.

A complication is that foreign code for mutables is generated in the compiler
frontend, which doesn't know about the types used by the backends.  For Java,
mutable variables had the generic type `Object' (except for primitives types)
but as we now generate foreign procs with the correct variable types, the code
for accessing a mutable would be type incorrect, e.g.

        X = mutable_var;  /* list.List_1 = Object */

Here we handle generated mutable predicates as a special case, using `Object'
for the global variable and argument types and generating typecasts as before.
The correct fix would be to move mutable code generation into the backends.


compiler/make_hlds_passes.m:
        Make Java mutable variables always have the type `java.lang.Object'.

        Mark Java mutable predicates with `may_not_duplicate' attributes, as
        the generated code doesn't contain class-qualifiers for the mutable
        variable, so copying that code into other Java files won't work.

compiler/mlds.m:
        Add a new target code component `target_code_type(Type)' which is a
        placeholder for a type, to be substituted by the backend when target
        code is being printed out.

compiler/ml_code_gen.m:
        Generate Java foreign procs using `target_code_type' to declare local
        variables, except for mutable predicates as described above.

        Rename a predicate shared for C and Java.

        Assign dummy type variables the value `null' in the Java backend
        instead of `0'.

compiler/foreign.m:
        Add a comment for `exported_type_to_string'.

compiler/mlds_to_java.m:
        Handle the addition of `target_code_type'.

        Output `java.lang.Output' for builtin dummy types.  We were
        inconsistent as to whether builtin dummy types should be represented by
        `int' or `Object'.

        Output line number context in another spot.

compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_il.m:
        Conform to the addition of `target_code_type'.

library/exception.m:
library/io.m:
library/list.m:
library/rtti_implementation.m:
library/string.m:
library/type_desc.m:
        Delete casts in some Java foreign code which are no longer required.
2009-09-02 05:48:02 +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
Peter Wang
23f281a411 Add the ability, when structure reuse is enabled, to free dead heap cells which
Branches: main

Add the ability, when structure reuse is enabled, to free dead heap cells which
can't otherwise be reused.

Fix a bug where we might try to reuse static data in MLDS grades.  As with the
the LLDS grades, check at run-time that the cell to reuse is within the heap
range.

compiler/options.m:
	Add `--structure-reuse-free-cells' option (disabled by default).

compiler/structure_reuse.direct.choose_reuse.m:
	Fix a bug which caused the code to mark deconstructions with `can_cgc'
	to never be run.  Run the code if `--structure-reuse-free-cells'
	is enabled.

compiler/unify_gen.m:
	Generate `free_heap' instructions after deconstructions marked with
	`can_cgc'.  As in the case of cell reuse, we need to ensure that all
	the needed fields are available from other locations before freeing the
	cell.

compiler/code_info.m:
compiler/var_locn.m:
	Export the code which saves cell fields before the cell is reused
	or freed.

compiler/ml_unify_gen.m:
	Make the code which implements cell reuse generate code like this:

	    MR_assign_if_in_heap(Lval, Rval);
	    if (Lval) {
		/* assign fields */
	    } else {
		Lval = MR_new_object(...);
	    }

	where `MR_assign_if_in_heap' assigns NULL to Lval if Rval doesn't look
	like a dynamically allocated address.

	Strip tag bits off the argument to `delete_object' statements.

compiler/mlds.m:
	Add an MLDS statement `assign_if_in_heap'.

	Change `delete_object' to take an rval argument instead of an lval,
	for stripping tag bits.

compiler/mlds_to_c.m:
	Generate output for `assign_if_in_heap' and `delete_object'.

compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
	Conform to MLDS statement changes.

runtime/mercury_heap.h:
	Make `MR_free_heap' macro test that its argument is the heap range
	before calling `GC_FREE', so we don't try to free static data.

	Add `MR_assign_if_in_heap'.
2008-09-08 03:39:07 +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
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
94a45f1477 Fix a problem that was causing warnings from the C compiler for some of the
Estimated hours taken: 2
Branches: main

Fix a problem that was causing warnings from the C compiler for some of the
versions of the Java parser.

There is no test case, since we don't have a test mechanism for C compiler
warnings.

compiler/foreign.m:
	Return MR_Tuple as the C type that represents Mercury tuples in C,
	since the hlc backend requires this. (We used to generate MR_Word,
	which is what lead to the problem.)

	Rename the functions that generated the foreign language type names,
	both to make their names more expressive and to eliminate the ambiguity
	between them.

	Add a comment about my remaining concerns, and note the link between
	this code and code elsewhere.

	Rename some function symbols to avoid ambiguity.

compiler/ml_code_util.m:
	Rename a predicate to avoid an ambiguity.

compiler/*.m:
	Conform to the renamed predicates and functions.

runtime/mercury_types.h:
runtime/mercury_hlc_types.h:
	Move the definition of MR_Tuple from mercury_hlc_types to
	mercury_types, since foreign.m now generates references to it
	for the low level backend as well.
2007-08-13 01:27:52 +00:00
Peter Wang
637c76926d Add some preliminary infrastructure for an HLDS->Erlang code generator.
Estimated hours take: 4
Branches: main

Add some preliminary infrastructure for an HLDS->Erlang code generator.

compiler/globals.m:
compiler/options.m:
        Recognise "erlang" as a valid compilation target.

        Add new options: `--erlang' and `--erlang-only' as synonyms
        for `--target erlang' and `--target erlang --target-code-only'.
        XXX the new options are currently undocumented.

compiler/hlds_data.m:
compiler/prog_data.m:
compiler/prog_io_pragma.m:
	Recognise "Erlang" as a valid language for foreign code.

compiler/handle_options.m:
	For erlang targets, set the gc_method to automatic and disable
	optimize_constructor_last_call.

compiler/add_pragma.m:
compiler/add_type.m:
compiler/code_gen.m:
compiler/compile_target_code.m:
compiler/export.m:
compiler/foreign.m:
compiler/granularity.m:
compiler/intermod.m:
compiler/llds_out.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make_hlds_passes.m:
compiler/mercury_compile.m:
compiler/mercury_to_mercury.m:
compiler/ml_code_gen.m:
compiler/ml_optimize.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_il.m:
compiler/mlds_to_ilasm.m:
compiler/mlds_to_java.m:
compiler/modules.m:
compiler/pragma_c_gen.m:
compiler/prog_foreign.m:
compiler/simplify.m:
	Conform to the above changes.
2007-05-07 05:21:36 +00:00
Zoltan Somogyi
b56885be93 Fix a bug that caused bootchecks with --optimize-constructor-last-call to fail.
Estimated hours taken: 12
Branches: main

Fix a bug that caused bootchecks with --optimize-constructor-last-call to fail.

The problem was not in lco.m, but in follow_code.m. In some cases,
(specifically, the LCMC version of insert_2 in sparse_bitset.m),
follow_code.m moved an impure goal (store_at_ref) into the arms of an
if-then-else without marking those arms, or the if-then-else, as impure.
The next pass, simplify, then deleted the entire if-then-else, since it
had no outputs. (The store_at_ref that originally appeared after the
if-then-else was the only consumer of its only output.)

The fix is to get follow_code.m to make branched control structures such as
if-then-elses, as well as their arms, semipure or impure if a goal being moved
into them is semipure or impure, or if they came from an semipure or impure
conjunction.

Improve the optimization of the LCMC version of sparse_bitset.insert_2, which
had a foreign_proc invocation of bits_per_int in it: replace such invocations
with a unification of the bits_per_int constant if not cross compiling.

Add a new option, --optimize-constructor-last-call-null. When set, LCMC will
assign NULLs to the fields not yet filled in, to avoid any junk happens to be
there from being followed by the garbage collector's mark phase.

This diff also makes several other changes that helped me to track down
the bug above.

compiler/follow_code.m:
	Make the fix described above.

	Delete all the provisions for --prev-code; it won't be implemented.

	Don't export a predicate that is not now used anywhere else.

compiler/simplify.m:
	Make the optimization described above.

compiler/lco.m:
	Make sure that the LCMC specialized procedure is a predicate, not a
	function: having a function with the mode LCMC_insert_2(in, in) = in
	looks wrong.

	To avoid name collisions when a function and a predicate with the same
	name and arity have LCMC applied to them, include the predicate vs
	function status of the original procedure included in the name of the
	new procedure.

	Update the sym_name of calls to LCMC variants, not just the pred_id,
	because without that, the HLDS dump looks misleading.

compiler/pred_table.m:
	Don't have optimizations like LCMC insert new predicates at the front
	of the list of predicates. Maintain the list of predicates in the
	module as a two part list, to allow efficient addition of new pred_ids
	at the (logical) end without using O(N^2) algorithms. Having predicates
	in chronological order makes it easier to look at HLDS dumps and
	.c files.

compiler/hlds_module.m:
	Make module_info_predids return a module_info that is physically
	updated though logically unchanged.

compiler/options.m:
	Add --optimize-constructor-last-call-null.

	Make the options --dump-hlds-pred-id, --debug-opt-pred-id and
	--debug-opt-pred-name into accumulating options, to allow the user
	to specify more than one predicate to be dumped (e.g. insert_2 and
	its LCMC variant).

	Delete --prev-code.

doc/user_guide.texi:
	Document the changes in options.m.

compiler/code_info.m:
	Record the value of --optimize-constructor-last-call-null in the
	code_info, to avoid lookup at every cell construction.

compiler/unify_gen.m:
compiler/var_locn.m:
	When deciding whether a cell can be static or not, make sure that
	we never make static a cell that has some fields initialized with
	dummy zeros, to be filled in for real later.

compiler/hlds_out.m:
	For goals that are semipure or impure, note this fact. This info was
	lost when I changed the representation of impurity from markers to a
	field.

mdbcomp/prim_data.m:
	Rename some ambiguous function symbols.

compiler/intermod.m:
compiler/trans_opt.m:
	Rename the main predicates (and some function symbols) of these modules
	to avoid ambiguity and to make them more expressive.

compiler/llds.m:
	Don't print line numbers for foreign_code fragments if the user has
	specified --no-line-numbers.

compiler/make.dependencies.m:
compiler/mercury_to_mercury.m:
compiler/recompilation.usage.m:
	Don't use io.write to write out information to files we may need to
	parse again, because this is vulnerable to changes to the names of
	function symbols (e.g. the one to mdbcomp/prim_data.m).

	The compiler still contains some uses of io.write, but they are
	for debugging. I added an item to the todo list of the one exception,
	ilasm.m.

compiler/recompilation.m:
	Rename a misleading function symbol name.

compiler/parse_tree.m:
	Don't import recompilation.m here. It is not needed (all the components
	of parse_tree that need recompilation.m already import it themselves),
	and deleting the import avoids recompiling almost everything when
	recompilation.m changes.

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

compiler/*.m:
browser/*.m:
slice/*.m:
	Conform to the change to mdbcomp.

library/sparse_bitset.m:
	Use some better variable names.
2007-01-19 07:05:06 +00:00
Julien Fischer
74b6457c51 Add some preliminary infrastructure for the LLDS->x86_64 assembler
Estimated hours taken: 2
Branches: main

Add some preliminary infrastructure for the LLDS->x86_64 assembler
code generator that Fransiska is working on.

compiler/globals.m:
compiler/options.m:
compiler/handle_options.m:
compiler/mercury_compile.m:
	Recognise "x86_64" as a valid compilation target.

	Add new options: `--x86_64' and `--x86_64-only' as synonyms
	for `--target x86_64' and `--target x86_64 --target-code-only'.

	In the backend passes for the lowlevel backend branch
	appropriately depending on whether we are generating C or
	x86_64 assembler.

compiler/foreign.m:
compiler/prog_foreign.m:
	When compiling to x86_64 assembler use C as the preferred foreign
	language.

compiler/mlds.m:
compiler/ml_code_gen.m:
compiler/ml_optimize.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_c.m:
	Handle "x86_64" as a target in the MLDS backend.  This does
	(and should) cause a compiler abort since "x86_64" is intended
	to be an MLDS target language.

compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/modules.m:
	Add placeholders for --target x86_64 in the build systems.

compiler/make_hlds_passes.m.
	We don't currently support mutables with --target x86_64.

compiler/simplify.m:
	We don't currently support runtime conditions on trace goals
	with --target x86_64.

compiler/add_type.m:
compiler/compile_target_code.m:
compiler/granularity.m:
compiler/intermod.m:
	Conform to the above changes.
2007-01-08 03:03:15 +00:00
Ben Schmidt
5ea8dc3c2b Bug fixes for the MLDS accurate garbage collector.
Estimated hours taken: 25 (though some were spent learning build system, etc.)
Branches: main

Bug fixes for the MLDS accurate garbage collector.

compiler/mlds.m:
	Change type of mlds_maybe_gc_trace_code to a discriminated union,
	mlds_gc_statement to allow separation of initialisation and variable
	tracing code, rather than the standard maybe type.

compiler/ml_elim_nested.m:
	- Update extract_gc_trace_code (now extract_gc_statments) to
	  provide initialisation and variable tracing code separately.
	- Change method of flattening so that hoisting of variables into
	  structs and changing references to those structs are
	  sequenced, not interleaved. This fixes a bug where references to
	  a variable could be processed before that variable was hoisted
	  into a struct, and thus the references not properly updated.
	- Conform to the change in mlds.m.

compiler/ml_closure_gen.m:
	- Flag GC initialisation code as such as it must be executed before
	  GC tracing code.
	- Conform to the change in mlds.m.

compiler/ml_code_util.m:
compiler/ml_code_gen.m:
compiler/ml_call_gen.m:
compiler/ml_optimize.m:
compiler/ml_string_switch.m:
compiler/ml_type_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:
compiler/rtti_to_mlds.m:
	Conform to the change in mlds.m.
2006-12-23 12:49:25 +00:00
Julien Fischer
b4c3bb1387 Clean up in unused module imports in the Mercury system detected
Estimated hours taken: 3
Branches: main

Clean up in unused module imports in the Mercury system detected
by --warn-unused-imports.

analysis/*.m:
browser/*.m:
deep_profiler/*.m:
compiler/*.m:
library/*.m:
mdbcomp/*.m:
profiler/*.m:
slice/*.m:
	Remove unused module imports.

	Fix some minor departures from our coding standards.

analysis/Mercury.options:
browser/Mercury.options:
deep_profiler/Mercury.options:
compiler/Mercury.options:
library/Mercury.options:
mdbcomp/Mercury.options:
profiler/Mercury.options:
slice/Mercury.options:
	Set --no-warn-unused-imports for those modules that are used as
	packages or otherwise break --warn-unused-imports, e.g. because they
	contain predicates with both foreign and Mercury clauses and some of
	the imports only depend on the latter.
2006-12-01 15:04:40 +00:00
Zoltan Somogyi
863874df85 Document my recent change implementing coverage testing.
Estimated hours taken: 6
Branches: main

Document my recent change implementing coverage testing. At the same time,
eliminate the old hack that allowed a file containing a list of file names to
be considered a trace count file. We haven't needed it since the addition of
mtc_union, and it can lead to incomprensible error messages. (The presence
of the old hack made documenting coverage testing harder.)

In the process, fix the tools code for rerunning failed test cases only.

doc/user_guide.texi:
	Document my recent change implementing coverage testing, and the
	elimination of the old hack.

mdbcomp/trace_counts.m:
	Modify the predicates for reading in trace count files along the lines
	above.

mdbcomp/slice_and_dice.m:
	Modify the predicates for reading in slices and dices along the lines
	above.

	Rename some function symbols to avoid ambiguities.

compiler/tupling.m:
slice/mcov.m:
slice/mtc_diff.m:
slice/mtc_union.m:
trace/mercury_trace_declarative.c:
	Conform to the changes above.

slice/mcov.m:
	Fix the usage message, which referred to this program by its old name
	mct.

	Allow the output to be restricted to a set of named modules only.
	This is to make testing easier.

slice/mtc_diff.m:
	Rename the long form of the -o option from --out to --output-file,
	to make it consistent with the other programs.

tests/run_one_test:
tools/bootcheck:
	Modify the algorithm we use to gather trace counts for the Mercury
	compiler from both passed and failed test cases to run mtc_union
	periodically instead of gathering all the trace counts file and keeping
	them to the end (which takes far too much disk space).

	Fix an old bug: gather trace counts from executions of the Mercury
	compiler only.

tests/debugger/Mmakefile:
tests/debugger/dice.passes:
	Modify the dice test case to compute the union of the trace counts for
	the passed versions of this test case to use mtc_union to create
	dice.passes, instead of having dice.passes statically contain the list
	of the names of the passed trace count files (since that capability
	is deleted by this diff).

tools/bootcheck:
tests/Mmake.common:
	Fix the code for rerunning failed tests only.

mdbcomp/prim_data.m:
	Eliminate some ambiguities in predicate names.

compiler/*.m:
	Conform to the change to prim_data.m.

compiler/error_util.m:
	Add reading files as a phase in error messages.

compiler/mercury_compile.m:
	Use the new facilities in error_util for printing an error message.
2006-10-02 05:21:44 +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
Zoltan Somogyi
4924dfb1c9 One of Hans Boehm's papers says that heap cells allocated by GC_MALLOC_ATOMIC
Estimated hours taken: 5
Branches: main

One of Hans Boehm's papers says that heap cells allocated by GC_MALLOC_ATOMIC
are grouped together into pages, and these pages aren't scanned during the
sweep phase of the garbage collector. I therefore modified the compiler
to use GC_MALLOC_ATOMIC instead of GC_MALLOC whereever possible, i.e
when the cell being allocated is guaranteed not to have any pointer to
GCable memory inside it.

My first benchmarking run showed a speedup of 4.5% in asm_fast.gc:

EXTRA_MCFLAGS = --use-atomic-cells
mercury_compile.01 average of 6 with ignore=1     18.30
EXTRA_MCFLAGS = --no-use-atomic-cells
mercury_compile.02 average of 6 with ignore=1     19.17

However, later benchmarks, after the upgrade to version 7.0 of boehm_gc,
show a less favourable and more mixed picture, with e.g. a 4% speedup
in hlc.gc at -O3, a 3% slowdown in asm_fast.gc at -O4, and little effect
otherwise:

EXTRA_MCFLAGS = -O1 --use-atomic-cells
GRADE = asm_fast.gc
mercury_compile.01 average of 6 with ignore=1     23.30
EXTRA_MCFLAGS = -O1 --no-use-atomic-cells
GRADE = asm_fast.gc
mercury_compile.02 average of 6 with ignore=1     23.28

EXTRA_MCFLAGS = -O2 --use-atomic-cells
GRADE = asm_fast.gc
mercury_compile.03 average of 6 with ignore=1     18.51
EXTRA_MCFLAGS = -O2 --no-use-atomic-cells
GRADE = asm_fast.gc
mercury_compile.04 average of 6 with ignore=1     18.66

EXTRA_MCFLAGS = -O3 --use-atomic-cells
GRADE = asm_fast.gc
mercury_compile.05 average of 6 with ignore=1     18.44
EXTRA_MCFLAGS = -O3 --no-use-atomic-cells
GRADE = asm_fast.gc
mercury_compile.06 average of 6 with ignore=1     18.48

EXTRA_MCFLAGS = -O4 --use-atomic-cells
GRADE = asm_fast.gc
mercury_compile.07 average of 6 with ignore=1     18.28
EXTRA_MCFLAGS = -O4 --no-use-atomic-cells
GRADE = asm_fast.gc
mercury_compile.08 average of 6 with ignore=1     17.70

EXTRA_MCFLAGS = -O1 --use-atomic-cells
GRADE = hlc.gc
mercury_compile.09 average of 6 with ignore=1     24.78
EXTRA_MCFLAGS = -O1 --no-use-atomic-cells
GRADE = hlc.gc
mercury_compile.10 average of 6 with ignore=1     24.69

EXTRA_MCFLAGS = -O2 --use-atomic-cells
GRADE = hlc.gc
mercury_compile.11 average of 6 with ignore=1     19.36
EXTRA_MCFLAGS = -O2 --no-use-atomic-cells
GRADE = hlc.gc
mercury_compile.12 average of 6 with ignore=1     19.26

EXTRA_MCFLAGS = -O3 --use-atomic-cells
GRADE = hlc.gc
mercury_compile.13 average of 6 with ignore=1     18.64
EXTRA_MCFLAGS = -O3 --no-use-atomic-cells
GRADE = hlc.gc
mercury_compile.14 average of 6 with ignore=1     19.38

EXTRA_MCFLAGS = -O4 --use-atomic-cells
GRADE = hlc.gc
mercury_compile.15 average of 6 with ignore=1     19.39
EXTRA_MCFLAGS = -O4 --no-use-atomic-cells
GRADE = hlc.gc
mercury_compile.16 average of 6 with ignore=1     19.41

runtime/mercury_heap.h:
	Define atomic equivalents of the few heap allocation macros
	that didn't already have one. These macros are used by the LLDS
	backend.

runtime/mercury.h:
	Define an atomic equivalent of the MR_new_object macro.
	These macros are used by the MLDS backend.

	Use MR_new_object_atomic instead of MR_new_object to box floats.

compiler/hlds_data.m:
compiler/llds.m:
compiler/mlds.m:
	Modify the representations of the heap allocations constructs
	to include a flag that says whether we should use the atomic variants
	of the heap allocation macros.

compiler/llds_out.m:
compiler/mlds_to_c.m:
	Respect this extract flag when emitting C code.

	In mlds_to_c.m, also add some white space that makes the code easier
	for humans to read.

compiler/type_util.m:
	Add a mechanism for finding out whether we can put a value of a given
	type into an atomic cell.

	Put the definitions of functions and predicates in this module
	in the same order as their declarations.

	Turn some predicates into functions. Change the argument order of
	some predicates to conform to our usual conventions.

compiler/unify_gen.m:
compiler/ml_unify_gen.m:
	Use the new mechanism in type_util.m to generate code that creates
	atomic heap cells if this is possible and is requested.

compiler/code_info.m:
compiler/var_locn.m:
	Act on the information provided by unify_gen.m.

compiler/options.m:
doc/user_guide.texi:
	Add an option to control whether the compiler should try to use
	atomic cells.

compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/higher_order.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/middle_rec.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_util.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/modecheck_unify.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/par_conj_gen.m:
compiler/polymorphism.m:
compiler/reassign.m:
compiler/size_prof.m:
compiler/structure_sharing.domain.m:
compiler/use_local_vars.m:
	Minor diffs to conform to the changes above.

compiler/structure_reuse.direct.choose_reuse.m:
	Add an XXX comment about the interaction of the new capability
	with structure reuse.
2006-08-20 05:01:48 +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
997b5a1c8c Implement the trace goal construct for the hlc grades.
Estimated hours taken: 5
Branches: main

Implement the trace goal construct for the hlc grades.

compiler/mlds.m:
	Extend the MLDS in a similar way to how the previous diff extended
	the LLDS. This means extending lvals to allow references to global
	variables representing the initial snapshots of environment variables,
	and recording the set of environment variables referred to by each
	definition.

compiler/mlds_to_c.m:
	Handle the extensions to the MLDS.

compiler/llds_out.m:
util/mkinit.c:
	Note that mlds_to_c.m now also depends on the naming scheme for the
	global variables representing environment variables.

compiler/ml_code_gen.m:
	When generating code for a procedure, remember the set of environment
	variables it refers to.

	When generating code for the special form of call_foreign_proc created
	by the transformation of trace goals with runtime conditions by
	simplify.m, generate the appropriate boolean expression involving
	references to environment variables.

compiler/ml_code_util.m:
	Provide storage space for recording the set of environment variables
	used in functions.

compiler/mlds_to_il.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
	Abort if asked to translate functions that include references to
	environment variables, since this is preferable to silently doing
	the wrong thing.

compiler/*.m:
	Misc changes required to conform to the change to the MLDS.
2006-07-31 03:13:53 +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
Zoltan Somogyi
74ce85d476 Provide a mechanism for collecting statistics about tabling operations,
Estimated hours taken: 60
Branches: main

Provide a mechanism for collecting statistics about tabling operations,
and provide a much more convenient mechanism for resetting tables.

Since it would too complex to do this while preserving the capability
of setting --tabling-via-extra-args to no, eliminate that capability
and the option. That option was useful only for measurements of the
performance boost from setting --tabling-via-extra-args to yes in any case,
so users lose no functionality.

Previously, the only way to debug the low level details of the tabling
mechanism was to build a runtime with a specific C macro (MR_TABLE_DEBUG)
and link with that runtime; this was cumbersome. Change that so that
every one of the debuggable tabling macros has a bool argument that says
whether debugging is enabled or not. The compiler can then set this to
MR_TRUE if the new option --table-debug is given, and to MR_FALSE otherwise.
If set to MR_FALSE, the C compiler should optimize away the debug code,
with zero impact on program size or speed.

Since these changes to macros require nontrivial bootstrapping, which we don't
want to do unnecessarily, modify the interface of the tabling macros as
required to support size limits on tables. This diff also implements the
parsing of size limit specifications on tables, but does not implement them
yet; that is for a future change.

To make the syntax simpler, this diff deletes the free-standing fast_loose_memo
pragma. The same functionality is now available with a fast_loose annotation
on an ordinary memo pragma.

Make a bunch of changes to improve readability and maintainability
in the process. These mostly take the form of renaming ambiguous and/or
not sufficiently expressive function symbols.

runtime/mercury_stack_layout.h:
runtime/mercury_tabling.h:
	Move the description of structure of tables from mercury_stack_layout.h
	to mercury_tabling.h, since we now need it for statistics even if
	execution tracing is not enabled.

	Modify those data structures to have room for the statistics.

	Don't distinguish "strict", "fast_loose" and "specified" memoing
	as separate eval methods; treat them as just different kinds
	of the same eval method: "memo".

	Remove underscores from the names of some types that the style guide
	says shouldn't be there.

runtime/mercury_tabling_preds.h:
runtime/mercury_tabling_macros.h:
	Modify the approach we use for macros that implement the predicates
	of library/table_builtin.m. Instead of selecting between debug and
	nondebug based on whether MR_TABLE_DEBUG is defined or not, add
	an explicit argument controlling this to each debuggable macro.
	The advantage of the new arrangement is that it scales. Another
	argument controls whether we are computing statistics (and if yes,
	where do we put it), and a third argument controls whether we maintain
	back links in the tries and hash tables (this last argument is present
	but is ignored for now).

	Since the values of the arguments will be known when the .c files
	containing calls to these macros are compiled, we pay the space and
	time cost of debugging, statistics gathering and the maintenance of
	back links if and only we need the revelant functionality.

	Provide macros for limited backward compatibility with the old set
	of macros; these allow workspaces created by old compilers to work
	with the new macros in the runtime. The old macros followed the
	naming scheme MR_table_*, the new ones are named MR_tbl_*.

runtime/mercury_table_int_fix_index_body.h:
runtime/mercury_table_int_start_index_body.h:
runtime/mercury_table_type_body.h:
	New files containing parts of the old mercury_tabling.c. Each of these
	files contains the body of the functions that used to be in
	mercury_tabling.c. The new mercury_tabling.c #includes each of these
	files more than once, to provide more than one variant of the old
	function. These variants differ in aspects such as whether debugging
	is enabled or statistics is being collected. Each variant therefore
	incurs only the time costs it needs to. (We pay the space cost of
	having all these variants all the time of course, but this cost
	is negligible.)

runtime/mercury_tabling_stats_defs.h:
runtime/mercury_tabling_stats_nodefs.h:
runtime/mercury_tabling_stats_undefs.h:
	New files that serve as wrappers around the newly #included files,
	controlling how they handle statistics.

runtime/mercury_tabling.c:
	Delete functions now in the new files, and #include them instead.
	Delete the data structures that used to contain summary statistics;
	the new approach keeps statistics in compiler-generated,
	procedure-specific data structures.

runtime/mercury_trace_base.c:
	Use the new versions of the tabling macros to access the I/O table.

runtime/mercury_type_info.h:
	Update some documentation for the movement of code out of
	mercury_tabling.c.

runtime/mercury_types.h:
	Provide forward declarations of the identifiers denoting the new types
	in mercury_tabling.h.

runtime/mercury_grade.h:
	Increment the exec trace version number, since we have changed
	a part of the exec trace structure.

runtime/mercury_bootstrap.h:
	Fix some temporary issues that arise from some renames above.

runtime/mercury_hash_lookup_or_add_body.h:
	Fix comment.

runtime/Mmakefile:
	Mention the new files and the dependencies that involve them.

library/table_builtin.m:
	Provide a type for representing statistics and a predicate for
	printing statistics.

	Use the updated versions of the macros in
	runtime/mercury_tabling_preds.h.

compiler/prog_item.m:
	Change representation of tabling pragmas to allow room for the new
	attributes.

	Allow an item to be marked as being generated by the compiler
	as a result of a pragma memo attribute. We use this for the reset
	and statistics predicates.

compiler/mercury_to_mercury.m:
	Write out the new attributes of the tabling pragma.

compiler/prog_data.m:
compiler/hlds_data.m:
	Change the cons_id that used to refer to a procedure's call table root
	to refer to the entirety of the new data structure now containing it.
	The compiler now needs a way to refer to the other components of this
	new data structure, since it contains the statistics.

	As in the runtime, don't distinguish "strict", "fast_loose" and
	"specified" memoing as separate eval methods; treat them as just
	different kinds of the same eval method: "memo".

	Rename some of the uses of the function symbols "c", "java", "il".

compiler/hlds_pred.m:
	Add an extra field in proc_infos for storing any tabling attributes.

	Change the existing proc_info field that records information about
	the kinds of arguments of tabled procedures to record the information
	needed by the debugger too. This was needed to allow us to shift all
	the RTTI for procedure-specific tables (as opposed to the RTTI for
	the global I/O table) from mercury_stack_layout.h to mercury_tabling.h
	without duplicating the data (which would be a maintenance problem).

	Reformat some comments to make them easier to read.

compiler/layout.m:
compiler/layout_out.m:
	Delete the part of the exec trace information that used to record
	RTTI for tables, since this information is not generated only as
	part of the debugger data structures anymore.

compiler/prog_io_pragma.m:
	Recognize the updated syntax for tabling pragmas.

compiler/add_pragma.m:
	When processing tabling pragmas for inclusion in the HLDS, create
	any reset and statistics predicates they ask for.

compiler/make_hlds_passes.m:
	Export a predicate now needed by add_pragma.m.

	Handle the new attributes on tabling pragmas

compiler/globals.m:
	Change the function symbols of the types describing backends and
	foreign languages to say what they are. Previously, both types (as well
	as several others) included the function symbol "c"; now, they are
	target_c and lang_c respectively.

compiler/table_gen.m:
	Implement the changes described at the top.

	When passing around varsets and vartypes, pass the arguments in the
	standard order.

compiler/goal_util.m:
compiler/hlds_goal.m:
	When passing around varsets and vartypes, pass the arguments in the
	standard order.

compiler/rtti.m:
	Provide types for representing the runtime's data structures for
	tabling (which are now significantly more complex than a single word)
	and predicates for manipulating them, for use by both the ml and ll
	backends.

compiler/llds.m:
	Replace the comp_gen_c_var type with the tabling_info_struct type,
	which contains the information needed to create the per-procedure
	tabling data structures.

	Replace references to call tables with references to the various
	components of the new tabling data structures.

compiler/llds_out.m:
	Add code to write out tabling_info_structs.

	Delete the code required for the old, hacky way of resetting tables.

	Reorder some code more logically.

compiler/proc_gen.m:
	Generate tabling_info_structs.

compiler/stack_layout.m:
	Don't generate the information now generated in proc_gen.m.

compiler/mlds.m:
	Give mlds_proc_labels their own function symbols, instead of using
	a pair. Rename some other function symbols to avoid ambiguity and add
	expressiveness.

	Provide for the representation of references to the various components
	of the new tabling data structures, and for the representation of their
	types.

compiler/ml_code_gen.m:
	When generating code for a tabled procedure, generate also the data
	structures required for its table.

compiler/rtti_to_mlds.m:
compiler/ml_util.m:
	Move some predicates from rtti_to_mlds.m to ml_util.m, since we
	now also want to call them from ml_code_gen.m.

compiler/name_mangle.m:
	Add some utility predicates.

compiler/options.m:
	Delete the old --allow-table-reset option.

	Add the new --table-debug option.

	Comment out an implementor-only option.

compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_trail_ops.m:
compiler/add_type.m:
compiler/bytecode_gen.m:
compiler/code_gen.m:
compiler/compile_target_code.m:
compiler/complexity.m:
compiler/dependency_graph.m:
compiler/det_report.m:
compiler/export.m:
compiler/fact_table.m:
compiler/foreign.m:
compiler/global_data.m:
compiler/globals.m:
compiler/handle_options.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_data.m:
compiler/hlds_goal.m:
compiler/hlds_out.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/make.dependencies.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.util.m:
compiler/make_hlds_passes.m:
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_switch_gen.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_ilasm.m:
compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
compiler/modes.m:
compiler/module_qual.m:
compiler/modules.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/polymorphism.m:
compiler/pragma_c_gen.m:
compiler/proc_label.m:
compiler/prog_data.m:
compiler/prog_foreign.m:
compiler/prog_item.m:
compiler/prog_mutable.m:
compiler/prog_out.m:
compiler/prog_rep.m:
compiler/prog_util.m:
compiler/recompilation.version.m:
compiler/size_prof.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/transform_llds.m:
compiler/tupling.m:
compiler/type_ctor_info.m:
compiler/unify_gen.m:
	Conform to the changes above, and/or improve some comments.

mdbcomp/prim_data.m:
	Make the names of the function symbols of the proc_label type more
	expressive and less ambiguous.

mdbcomp/prim_data.m:
mdbcomp/mdbcomp.m:
mdbcomp/program_representation.m:
mdbcomp/rtti_access.m:
mdbcomp/slice_and_dice.m:
mdbcomp/trace_counts.m:
	Use . instead of __ as module qualifier.

	Conform to the change to prim_data.m.

browser/declarative_execution.m:
browser/declarative_oracle.m:
browser/declarative_tree.m:
	Conform the change to mdbcomp/prim_data.m.

tests/debugger/Mercury.options:
	Don't specify --allow-table-reset for fib.m, since that option
	doesn't exist anymore.

tests/debugger/fib.m:
	Use the new mechanism for resetting the table.

tests/debugger/print_table.m:
	Use the new syntax for pragma memo attributes.

tests/invalid/specified.{m,err_exp}:
	Use to the new syntax and reset method for pragma memo attributes.
	Test the handling of errors in the new attribute syntax.

tests/tabling/Mercury.options:
	Don't specify --allow-table-reset for specified.m, since that option
	doesn't exist anymore.

tests/tabling/specified.m:
	Use the new syntax for pragma memo attributes, and use the new
	mechanism for resetting tables. We could also use this test case
	for testing the printing of statistics, but the format of that
	output is still not final.

tests/tabling/fast_loose.m:
	Use the new syntax for pragma memo attributes, and use the new
	mechanism for resetting tables.

trace/mercury_trace.c:
trace/mercury_trace_cmd_developer.c:
	Conform to the changes in the RTTI data structures regarding tabling.

	Remove underscores from the names of some types that the style guide
	says shouldn't be there.

library/robdd.m:
	Comment out the tabling pragma until this change is bootstrapped.
	Without this, the conflict between the old calls to macros generated
	by the existing compiler and the new definition of those macros
	in the runtime would cause errors from the C compiler.
2006-06-08 08:20:17 +00:00