Commit Graph

106 Commits

Author SHA1 Message Date
Zoltan Somogyi
24b98fdafe Pack sub-word-sized ints and dummies in terms.
Previously, the only situation in which we could pack two or more arguments
of a term into a single word was when all those arguments are enums. This diff
changes that, so that the arguments can also be sub-word-sized integers
(signed or unsigned), or values of dummy types (which occupy zero bits).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Handle the new dummy_tag.

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

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

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

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

    Delete an unused predicate.

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

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

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

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

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

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

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

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

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

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

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

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

    Conform to the changes above.

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

    Add notes about possible optimizations.

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

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

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

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

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

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

    Generate slightly better formatted output.

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

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

    Conform to the changes above.

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

compiler/llds_out_util.m:
    Add a comment.

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

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

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

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

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

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

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

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

    Give a macro a more descriptive name.

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

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

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

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

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

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

tests/hard_coded/Mmakefile:
    Enable the new test case.
2018-05-05 13:22:19 +02:00
Julien Fischer
ae94e32d46 Support 64-bit integers in static ground terms with the LLDS backend.
compiler/handle_options.m:
compiler/options.m:
    Add a new internal option --static-ground-int64s, whose value
    says whether 64-bit integers may be placed in static data.
    (As with floats currently, we always do this.)

compiler/llds_out_data.m:
    If 64-bit integers are boxed, then emit a static constant to hold
    the value of each 64-bit integer literal.

compiler/llds.m:
compiler/llds_out_util.m:
compiler/code_info.m:
     Keep track of whether we are using unboxed int64s and static ground int64s
     at various points in the code generator.

     Add decl_ids for the labels we generate for 64-bit integer constants.

compiler/exprn_aux.m:
     Fix an XXX: properly determine whether an expression containing 64-bit
     integers is constant or not.

compiler/c_util.m:
    Add functions for converting 64-bit integers into strings giving
    the C literal representation of those integers.
2018-01-23 01:31:24 -05:00
Julien Fischer
f519e26173 Add builtin 64-bit integer types -- Part 1.
Add the new builtin types: int64 and uint64.

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

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

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

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

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

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

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

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

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

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

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

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

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

compiler/ml_call_gen.m:
compiler/ml_code_util.m:
compiler/ml_global_data.m:
compiler/ml_rename_classes.m:
compiler/ml_top_gen.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds_to_target_util.m:
compiler/rtti_to_mlds.m:
     Conform to the above changes to the MLDS.

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

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

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

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

    Update the Java list of TypeCtorRep constants here.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Add builtin operations for all the new types.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Update the Java list of TypeCtorRep constants.

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

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

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

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

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

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

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

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

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

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

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

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

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

    Bump the RTTI version number here.

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

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

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

    Map uints onto MR_Unsigned.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Add an alternative for uints to the tyepctor rep enum.

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

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

runtime/mercury_term_size.c:
runtime/mercury_ml_expand_body.h:
    Handle uint and fix probable bugs with the handling of ints on
    64-bit Windows.
2016-10-24 12:55:35 +11:00
Zoltan Somogyi
f2b877500c Delete some unused predicates. 2015-12-05 06:36:14 +11:00
Zoltan Somogyi
ae17b527c9 Convert (C->T;E) to (if C then T else E).
In goal_util.m, process all goal types in tests, not just some.

Some other simplifications.
2015-10-26 00:06:53 +11:00
Zoltan Somogyi
ae612d2a4a compiler/exprn_aux.m:
Delete a redundant comment.
2014-01-22 10:03:53 +11:00
Peter Wang
4d38590690 Construct partially instantiated direct arg functor values.
Construction unifications of partially instantiated values involving direct
argument functors (where the single argument is free) did not generate any code
in both low-level and high-level backends.  Incorrect behaviour could result if
the program tried to deconstruct the value at run-time.

Also, in the LLDS backend, such a construction unification did not enter the
variable into the var_state_map, leading to a compiler abort when the variable
is looked up.

compiler/ml_unify_gen.m:
	Generate code for constructions of a direct arg functor with free
	argument.  This amounts to assigning a variable to a tagged null
	pointer.

compiler/llds.m:
	Add an rval option `mkword_hole', which is like `mkword' but the
	pointer to be tagged is unspecified.

compiler/unify_gen.m:
	Assign a variable to an `mkword_hole' rval, for a construction
	unification of a direct arg functor with a free argument.

	Reassign the variable to an `mkword' rval when the argument becomes
	bound in a later unification.

compiler/code_info.m:
compiler/var_locn.m:
	Add a predicate to reassign a variable from a `mkword_hole' expression
	to a `mkword' expression.

compiler/llds_out_data.m:
	Write out `mkword_hole' values as a tagged null pointer in C code.

compiler/call_gen.m:
compiler/code_util.m:
compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_to_x86_64.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/peephole.m:
compiler/stack_layout.m:
	Conform to addition of `mkword_hole'.

tests/hard_coded/Mmakefile:
tests/hard_coded/direct_arg_partial_inst.exp:
tests/hard_coded/direct_arg_partial_inst.m:
tests/hard_coded/direct_arg_partial_inst2.exp:
tests/hard_coded/direct_arg_partial_inst2.m:
	Add test cases.
2013-02-14 16:37:04 +11:00
Peter Wang
2ccac171dd Add float registers to the Mercury abstract machine, implemented as an
Branches: main

Add float registers to the Mercury abstract machine, implemented as an
array of MR_Float in the Mercury engine structure.

Float registers are only useful if a Mercury `float' is wider than a word
(i.e. when using double precision floats on 32-bit platforms) so we let them
exist only then.  In other cases floats may simply be passed via the regular
registers, as before.

Currently, higher order calls still require the use of the regular registers
for all arguments.  As all exported procedures are potentially the target of
higher order calls, exported procedures must use only the regular registers for
argument passing.  This can lead to more (un)boxing than if floats were simply
always boxed.  Until this is solved, float registers must be enabled explicitly
with the developer only option `--use-float-registers'.

The other aspect of this change is using two consecutive stack slots to hold a
single double variable.  Without that, the benefit of passing unboxed floats
via dedicated float registers would be largely eroded.


compiler/options.m:
	Add developer option `--use-float-registers'.

compiler/handle_options.m:
	Disable `--use-float-registers' if floats are not wider than words.

compiler/make_hlds_passes.m:
	If `--use-float-registers' is in effect, enable a previous change that
	allows float constructor arguments to be stored unboxed in structures.

compiler/hlds_llds.m:
	Move `reg_type' here from llds.m and `reg_f' option.

	Add stack slot width to `stack_slot' type.

	Add register type and stack slot width to `abs_locn' type.

	Remember next available float register in `abs_follow_vars'.

compiler/hlds_pred.m:
	Add register type to `arg_loc' type.

compiler/llds.m:
	Add a new kind of lval: double-width stack slots.
	These are used to hold double-precision floating point values only.

	Record setting of `--use-float-registers' in exprn_opts.

	Conform to addition of float registers and double stack slots.

compiler/code_info.m:
	Make predicates take the register type as an argument,
	where it can no longer be assumed.

	Remember whether float registers are being used.

	Remember max float register for calls to MR_trace.

	Count double width stack slots as two slots.

compiler/arg_info.m:
	Allocate float registers for procedure arguments when appropriate.

	Delete unused predicates.

compiler/var_locn.m:
	Make predicates working with registers either take the register type as
	an argument, or handle both register types at once.

	Select float registers for variables when appropriate.

compiler/call_gen.m:
	Explicitly use regular registers for all higher-order calls,
	which was implicit before.

compiler/pragma_c_gen.m:
	Use float registers, when available, at the interface between Mercury
	code and C foreign_procs.

compiler/export.m:
	Whether a float rval needs to be boxed/unboxed when assigned to/from a
	register depends on the register type.

compiler/fact_table.m:
	Use float registers for arguments to predicates defined by fact tables.

compiler/stack_alloc.m:
	Allocate two consecutive stack slots for float variables when
	appropriate.

compiler/stack_layout.m:
	Represent double-width stack slots in procedure layout structures.

	Conform to changes.

compiler/store_alloc.m:
	Allocate float registers (if they exist) for float variables.

compiler/use_local_vars.m:
	Substitute float abstract machine registers with MR_Float local
	variables.

compiler/llds_out_data.m:
compiler/llds_out_instr.m:
	Output float registers and double stack slots.

compiler/code_util.m:
compiler/follow_vars.m:
	Count float registers separately from regular registers.

compiler/layout.m:
compiler/layout_out.m:
compiler/trace_gen.m:
	Remember the max used float register for calls to MR_trace().

compiler/builtin_lib_types.m:
	Fix incorrect definition of float_type_ctor.

compiler/bytecode_gen.m:
compiler/continuation_info.m:
compiler/disj_gen.m:
compiler/dupelim.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/hlds_out_goal.m:
compiler/jumpopt.m:
compiler/llds_to_x86_64.m:
compiler/lookup_switch.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/par_conj_gen.m:
compiler/proc_gen.m:
compiler/string_switch.m:
compiler/tag_switch.m:
compiler/tupling.m:
compiler/x86_64_regs.m:
	Conform to changes.

runtime/mercury_engine.h:
	Add an array of fake float "registers" to the Mercury engine structure,
	when MR_Float is wider than MR_Word.

runtime/mercury_regs.h:
	Document float registers in the Mercury abstract machine.

	Add macros to access float registers in the Mercury engine.

runtime/mercury_stack_layout.h:
	Add new MR_LongLval cases to represent double-width stack slots.

	MR_LONG_LVAL_TAGBITS had to be increased to accomodate the new cases,
	which increases the number of integers in [0, 2^MR_LONG_LVAL_TAGBITS)
	equal to 0 modulo 4.  These are the new MR_LONG_LVAL_TYPE_CONS_n cases.

	Add max float register field to MR_ExecTrace.

runtime/mercury_layout_util.c:
runtime/mercury_layout_util.h:
	Extend MR_copy_regs_to_saved_regs and MR_copy_saved_regs_to_regs
	for float registers.

	Understand how to look up new kinds of MR_LongLval: MR_LONG_LVAL_TYPE_F
	(previously unused), MR_LONG_LVAL_TYPE_DOUBLE_STACKVAR,
	MR_LONG_LVAL_TYPE_DOUBLE_FRAMEVAR.

	Conform to the new MR_LONG_LVAL_TYPE_CONS_n cases.

runtime/mercury_float.h:
	Delete redundant #ifdef.

runtime/mercury_accurate_gc.c:
runtime/mercury_agc_debug.c:
	Conform to changes (untested).

trace/mercury_trace.c:
trace/mercury_trace.h:
trace/mercury_trace_declarative.c:
trace/mercury_trace_external.c:
trace/mercury_trace_internal.c:
trace/mercury_trace_spy.c:
trace/mercury_trace_vars.c:
trace/mercury_trace_vars.h:
	Handle float registers in the trace subsystem.  This is mostly a matter
	of saving/restoring them as with regular registers.
2011-10-17 04:31:33 +00:00
Zoltan Somogyi
517fbac88e Add four LLDS instructions Paul will soon need to implement the loop control
Estimated hours taken: 8
Branches: main

Add four LLDS instructions Paul will soon need to implement the loop control
transformation.

compiler/llds.m:
	Add the new instructions.

compiler/llds_out_instr.m:
	Output the new instructions. Paul may want to change the code
	we generate.

compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_to_x86_64.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/peephole.m:
compiler/reassign.m:
compiler/use_local_vars.m:
	Handle the new instructions.

	In opt_util.m, fix two old bugs. First, the restore_maxfr instruction
	behaved as if it updated hp, not maxfr. Second, the keep_assign
	instruction wasn't being handled as an assignment operation.

	In peephole.m, fix an old bug, in which assignments through mem_refs
	were not considered to invalidate the cached value of an lval.

	In use_local_vars, fix an old bug: the keep_assign instruction
	wasn't being handled as an assignment operation. Assignments
	themselves weren't being as optimized as they could be.
2011-09-30 05:53:51 +00:00
Peter Wang
4c2846593a Make it possible to store double-precision `float' constructor arguments in
Branches: main

Make it possible to store double-precision `float' constructor arguments in
unboxed form, in low-level C grades on 32-bit platforms, i.e. `float' (and
equivalent) arguments may occupy two machine words. However, until we implement
float registers, this does more harm than good so it remains disabled.

compiler/llds.m:
	Add a type `cell_arg' to hold information about an argument of a cell
	being constructed.

	Change `heap_ref' so that we can refer to a pointer with an unknown
	tag.

compiler/unify_gen.m:
	Use the `cell_arg' type to simplify code related to generating
	constructions.

	Handle double word arguments in constructions and deconstructions.

	Update enumeration packing code to account for the presence of double
	width arguments and the `cell_arg' type.

	Take double width arguments into account when generating ground terms.

compiler/code_info.m:
	Extend `assign_field_lval_expr_to_var' to work for expressions
	involving multiple field lvals of the same variable.

	Make `assign_cell_to_var' conform to changes.

compiler/code_util.m:
	Add a predicate to calculate the size of a cell given its cell_args.

compiler/var_locn.m:
	Conform to the use of the `cell_arg' type and the presense of double
	width arguments.

	Calculate cell size correctly in places.

	Move sanity checking from `var_locn_assign_field_lval_expr_to_var'
	to `code_info.assign_field_lval_expr_to_var'.

compiler/global_data.m:
	Make `rval_type_as_arg' take into account the width of the argument.

	Conform to changes.

compiler/c_util.m:
	Add a new binop category.  Unlike the existing macro_binop category,
	the arguments of macros in this category cannot all be assumed to be
	of integral types.

compiler/llds_out_data.m:
compiler/llds_out_instr.m:
	Output calls to the macros `MR_float_word_bits', `MR_float_from_dword'
	and `MR_float_from_dword_ptr' which were introduced previously.

	When a `heap_ref' has an unknown tag, make the generated code mask off
	the tag bits.

compiler/lco.m:
	Disable the optimisation when float arguments are present, on the basis
	of whether Mercury floats are wider than a machine word.  The comments
	about when floats are stored in boxed form are out of date.

compiler/arg_pack.m:
	Rename a predicate.

compiler/make_hlds_passes.m:
	Update a comment.

compiler/disj_gen.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/llds_to_x86_64.m:
compiler/lookup_switch.m:
compiler/mlds_to_c.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/stack_layout.m:
compiler/string_switch.m:
	Conform to changes.

runtime/mercury_float.h:
	Add a cast to `MR_float_word_bits' to avoid a gcc error.

tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/heap_ref_mask_tag.exp:
tests/hard_coded/heap_ref_mask_tag.m:
tests/hard_coded/reuse_double.exp:
tests/hard_coded/reuse_double.m:
	Add test cases.

tests/hard_coded/lookup_disj.exp:
tests/hard_coded/lookup_disj.m:
	Extend existing test case.
2011-09-16 07:03:36 +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
Paul Bone
322feaf217 Add more threadscope instrumentation.
This change introduces instrumentation that tracks sparks as well as parallel
conjunctions and their conjuncts.  This should hopefully give us more
information to diagnose runtime performance issues.

As of this date the ThreadScope program hasn't been updated to read or
understand these new events.

runtime/mercury_threadscope.[ch]:
    Added a function and types to register all the threadscope strings from an
    array.

    Add functions to post the new events (see below).

runtime/mercury_threadscope.c:
    Added support for 5 new threadscope events.
        Registering a string so that other messages may refer to a constant
        string.

        Marking the beginning and ends of parallel conjunctions.

        Creating a spark for a parallel conjunct.

        Finishing a parallel conjunct.

    Re-arranged event IDs, I've started allocating IDs from 38 onwards for
    general purposes and 100 onwards for mercury specific events after talking
    with Duncan Coutts.

    Trimmed excess whitespace from the end of lines.

runtime/mercury_context.h:
    Post a beginning parallel conjunction message when the sync term for the
    parallel conjunction is initialized.

    Post an event when creating a spark for a parallel conjunction.

    Add a MR_spark_id field to the MR_Spark structure, these identify sparks to
    threadscope.

runtime/mercury_context.c:
    Post threadscope messages when a spark is about to be executed.

    Post a threadscope event when a parallel conjunct is completed.

    Add a missing memory barrier.

runtime/mercury_wrapper.[ch]:
    Create a global function pointer for the code that registers strings in the
    threadscope string table, this is filled in by mkinit.

    Call this function pointer immediatly after setting up threadscope.

runtime/mercury_wsdeque.[ch]:
    Modify MR_wsdeque_pop_bottom to return the spark pointer (which points onto
    the queue) rather then returning a result through a pointer and bool if the
    operation was successful.  This pointer is safe to dereference until
    MR_wsdeque_push_bottom is used.

runtime/mercury_wsdeque.c:
    Corrected a code comment.

runtime/mercury_engine.h:
    Documented some of the fields of the engine structure that hadn't been
    documented.

    Add a next spark ID field to the engine structure.

    Change the type of the engine ID field to MR_uint_least16_t

compiler/llds.m:
    Add a third field to the init_sync_term instruction that stores the index
    into the threadscope string table of the static conjunction ID.

    Add a field to the c_file structure containing the threadscope string
    table.

compiler/layout.m:
    Added a new layout array name for the threadscope string table.

compiler/layout_out.m:
    Implement code to write out the threadscope string table.

compiler/llds_out_file.m:
    Write out the threadscope string table when writing out the c_file.

compiler/par_conj_gen.m:
    Create strings that statically identify parallel conjunctions for each
    init_sync_term LLDS instruction.  These strings are added to a table in the
    !CodeInfo and the index of the string is added to the init_sync_term
    instruction.

    Add an extra instruction after a parallel conjunction to post the message
    that the parallel conjunction has completed.

compiler/global_data.m:
    Add fields to the global data structure to represent the threadscope string
    table and its current size.

    Add predicates to update and retrieve the table.

    Handle merging of threadscope string tables in global data by allowing the
    references to the strings to be remapped.

    Refactored remapping code so that a caller such as proc_gen only needs to
    call one remapping predicate after merging global data..

compiler/code_info.m:
    Add a table of strings for use with threadscope to the code_info_persistent
    type.

    Modify the code_info_init to initialise the threadscope string table fields.

    Add a predicate to get the string table and another to update it.

compiler/proc_gen.m:
    Build the containing goal map before code generation for procedures with
    parallel conjunctions in a parallel grade.  par_conj_gen.m depends on this.

    Conform to changes in code_info.m and global_data.m

compiler/llds_out_instr.m:
    Write out the extra parameter in the init_sync_term instruction.

compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_to_x86_64.m:
compiler/mercury_compile_llds_back_end.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/peephole.m:
compiler/reassign.m:
compiler/use_local_vars.m:
    Conform to changes in llds.m

compiler/opt_debug.m:
    Conform to changes in layout.m

compiler/mercury_compile_llds_back_end.m:
    Fix some trailing whitespace.

util/mkinit.c:
    Build an initialisation function that registers all the strings in
    threadscope string tables.

    Correct the layout of a comment.
2011-03-25 03:13:42 +00:00
Zoltan Somogyi
1c3bc03415 Make the system compiler with --warn-unused-imports.
Estimated hours taken: 2
Branches: main, release

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

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

	In some files, do some minor cleanup along the way.
2010-12-30 11:18:04 +00:00
Zoltan Somogyi
d4bbcda309 Move all the frequently occurring layout structures and components of layout
Estimated hours taken: 40
Branches: main

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

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

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

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

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

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

	Simplify a one-field struct.

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

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

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

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

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

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

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

runtime/mercury_engine.h:
	Fix style.

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

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

compiler/layout_out.m:
	Output the new arrays.

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

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

	Cluster related predicates together.

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

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

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

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

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

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

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

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

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

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

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

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

tests/EXPECT_FAIL_TESTS.asm_fast.gc.debug:
tests/EXPECT_FAIL_TESTS.asm_fast.gc.profdeep:
	Add these files to ignore expected failues in these grades.
2009-10-30 03:33:34 +00:00
Zoltan Somogyi
9bdc5db590 Try to work around the Snow Leopard linker's performance problem with
Estimated hours taken: 20
Branches: main

Try to work around the Snow Leopard linker's performance problem with
debug grade object files by greatly reducing the number of symbols needed
to represent the debugger's data structures.

Specifically, this diff groups all label layouts in a module, each of which
previously had its own named global variable, into only a few (one to four)
global variables, each of which is an array. References to the old global
variables are replaced by references to slots in these arrays.

This same treatment could also be applied to other layout structures. However,
most layouts are label layouts, so doing just label layouts gets most of the
available benefit.

When the library and compiler are compiled in grade asm_fast.gc.debug,
this diff leads to about a 1.5% increase in the size of their generated C
source files (from 338 to 343 Mb), but a more significant reduction (about 17%)
in the size of the corresponding object files (from 155 to 128 Mb). This leads
to an overall reduction in disk requirements from 493 to 471 Mb (about 4.5%).
Since we generate the same code and data as before, with the data just being
arranged differently, the decrease in object file sizes is coming from the
reduction in relocation information, the information processed by the linker.
This should speed up the linker.

compiler/layout.m:
	Make the change described above. We now define up to four arrays:
	one each for label layouts with and without information about
	variables, one for the layout structures of user events,
	and one for the variable number lists of user events.

compiler/layout_out.m:
	Generate the new arrays that the module being compiled needs.

	Use purpose-specific types instead of booleans.

compiler/trace_gen.m:
	Use a new field in foreign_proc_code instructions to record the
	identity of any labels whose layout structures we want to refer to,
	even though layout structures have not been generated yet. The labels
	will be looked up in a map (generated together with the layout
	structures) by llds_out.m.

compiler/llds.m:
	Add this extra field to foreign_proc_code instructions.

	Add the map (which is actually in two parts) to the c_file type,
	which is the data structure representing the entire LLDS.

	Also add to the c_file type some other data structures that previously
	we used to hand around alongside it. Some of these data structures
	used to conmingle layout structures that we now separate.

compiler/stack_layout.m:
	Generate array slots instead of separate structures for label layouts.
	Return the different arrays separately.

compiler/llds_out.m:
	Order the output of layout structures to require fewer forward
	declarations. The forward declarations of the few arrays holding the
	label layout structures replace a lot of the declarations previously
	needed.

	Include the information needed by layout_out.m in the llds_out_info,
	and conform to the changes above.

	As a side-effect of all these changes, we now generate proc layout
	structures in the same order as the procedures' appearence in the HLDS,
	which is the same as their order in the source code, modulo any
	procedures added by the compiler itself (for lambdas, unification
	predicates, etc).

compiler/code_info.m:
compiler/dupelim.m:
compiler/dup_proc.m:
compiler/exprn_aux.m:
compiler/frameopt.m:
compiler/global_data.m:
compiler/ite_gen.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_to_x86_64.m:
compiler/mercury_compile_llds_back_end.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/pragma_c_gen.m:
compiler/proc_gen.m:
compiler/reassign.m:
compiler/use_local_vars.m:
	Conform to the changes above.

runtime/mercury_goto.h:
	Add the macros used by the new code in layout_out.m and llds_out.m.
	We need new macros because the old ones assumed that the
	C preprocessor can construct the address of a label's layout structure
	from the name of the label, which is obviously no longer possible.

	Make even existing families of macros handle in bulk up to 10 labels,
	up from the previous 8.

runtime/mercury_stack_layout.h:
	Add macros for use by the new code in layout.m.

tests/debugger/*.{inp,exp}:
tests/debugger/declarative/*.{inp,exp}:
	Update these test cases to account for the new (and better) order
	of proc layout structures. Where inputs changed, this was to ensure
	that we still select the same procedures from lists of procedures,
	e.g. to put a breakpoint on.
2009-10-21 06:36:37 +00:00
Zoltan Somogyi
659a11984f Fix the failure of the valid/two_way_unif test case, which used to get a code
Estimated hours taken: 8
Branches: main

Fix the failure of the valid/two_way_unif test case, which used to get a code
generator abort. The root cause of the abort was a mismatch between two
meanings of the option --static-ground-terms. The code in exprn_aux.m
was using it to govern whether an unboxed float was considered to be
a constant or not, whereas code_info.m and var_locn.m assumed that
*all* function symbols of arity 0, including floats, are always constants.

The fix is to rename the name of the option inside the compiler from
static_ground_terms to static_ground_cells (keeping the user-visible
name the same), and to add another option, static_ground_floats that
governs whether floats are considered static data. For now, and until
(if ever) the code generator is modified, they always are.

I also took the opportunity to add another option, static_code_addresses,
that is set based on the values of a couple of other options. This avoids
the repeated execution of a computation.

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

compiler/handle_options.m:
	Add code to set the values of the two new options.

compiler/var_locn.m:
compiler/code_info.m:
	Move the data structure that packages up the values of the options
	relevant to the code generation of expressions from the var_locn
	structure directly to the code_info structure, to allow parts of
	the code generator *outside* var_locn to also access it. Put the
	values of the new options in it too.

	Add a XXX marker for some redundant data.

compiler/exprn_aux.m:
compiler/llds.m:
	Move the definition of that data structure from exprn_aux.m to llds.m,
	to allow those parts of the code generator outside var_locn to use it
	without importing exprn_aux.m.

	Change the fields of this data structure from confusable bools to
	purpose-specific types.

compiler/disj_gen.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/globals.m:
compiler/liveness.m:
compiler/llds_out.m:
compiler/lookup_switch.m:
compiler/lookup_util.m:
compiler/mercury_compile.m:
compiler/stack_layout.m:
	Take advantage of (or just conform to) the above changes.

	In llds_out.m, avoid generating unnecessary casts for string
	comparisons.
2008-06-02 02:27:29 +00:00
Peter Wang
e0ff2b1903 Implement conditional structure reuse for LLDS backends using Boehm GC.
Estimated hours taken: 15
Branches: main

Implement conditional structure reuse for LLDS backends using Boehm GC.
Verify at run time, just before reusing a dead cell, that the base address of
the cell was dynamically allocated.  If not, fall back to allocating a new
object on the heap.  This makes structure reuse safe without having to disable
static data.

In the simple case, the generated C code looks like this:

    MR_tag_reuse_or_alloc_heap(dest, tag, addr_of_reuse_cell,
	MR_tag_alloc_heap(dest, tag, count));
    ...assign fields...

If some of the fields are known to already have the correct values then we can
avoid assigning them.  We need to handle both reuse and non-reuse cases:

    MR_tag_reuse_or_alloc_heap_flag(dest, flag_reg, tag, addr_of_reuse_cell,
	MR_tag_alloc_heap(dest, tag, count));
    /* flag_reg is non-zero iff reuse is possible */
    if (flag_reg) {
	goto skip;
    }
    ...assign fields which don't need to be assigned in reuse case...
  skip:
    ...assign fields which must be assigned in both cases...

It may be that it is not worth the branch to avoid assigning known fields.
I haven't yet checked.


compiler/llds.m:
	Extend the `incr_hp' instruction to hold information for structure
	reuse.

compiler/code_info.m:
	Generate a label and pass it to `var_locn_assign_cell_to_var'.  The
	label is only needed for the type of code shown above.

compiler/var_locn.m:
	Change the code generated for cell reuse.  Rather than assigning the
	dead cell's address to the target lval unconditionally, generate an
	`incr_hp' instruction with the reuse field filled in.

	Generate code that avoids filling in known fields if possible.

	Abort if we see `construct_statically(_)' in
	`var_locn_assign_dynamic_cell_to_var'.

runtime/mercury_heap.h:
runtime/mercury_conf_param.h:
	Add a macro to check if an address is between
	`GC_least_plausible_heap_addr' and `GC_greatest_plausible_heap_addr',
	which are therefore in the heap.

	Add macros to conditionally reuse a cell or otherwise fall back to
	allocating a new object.

	Make it possible to revert to unconditional structure reuse by
	defining the C macro `MR_UNCONDITIONAL_STRUCTURE_REUSE'.

compiler/llds_out.m:
	Call the new macros in `mercury_heap.h' for `incr_hp' instructions
	with reuse information filled in.

compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_to_x86_64.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/reassign.m:
compiler/unify_gen.m:
compiler/use_local_vars.m:
	Conform to the changed `incr_hp' instruction.
2008-02-11 03:56:13 +00:00
Zoltan Somogyi
672f77c4ec Add a new compiler option. --inform-ite-instead-of-switch.
Estimated hours taken: 20
Branches: main

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

Act on the output generated by this option.

compiler/simplify.m:
	Implement the new option.

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

compiler/options.m:
	Add the new option.

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

doc/user_guide.texi:
	Document the new option.

NEWS:
	Mention the new option.

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

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

	In a few cases, improve the error messages generated.

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

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

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

tests/invalid/reserve_tag.err_exp:
	Expect a new, improved error message.
2007-11-23 07:36:01 +00:00
Peter Wang
fa80b9a01a Make the parallel conjunction execution mechanism more efficient.
Branches: main

Make the parallel conjunction execution mechanism more efficient.

1. Don't allocate sync terms on the heap.  Sync terms are now allocated in
the stack frame of the procedure call which originates a parallel
conjunction.

2. Don't allocate individual sparks on the heap.  Sparks are now stored in
preallocated, growing arrays using an algorithm that doesn't use locks.

3. Don't have one mutex per sync term.  Just use one mutex to protect
concurrent accesses to all sync terms (it's is rarely needed anyway).  This
makes sync terms smaller and saves initialising a mutex for each parallel
conjunction encountered.

4. We don't bother to acquire the global sync term lock if we know a parallel
conjunction couldn't be executing in parallel.  In a highly parallel program,
the majority of parallel conjunctions will be executed sequentially so
protecting the sync terms from concurrent accesses is unnecessary.


par_fib(39) is ~8.4 times faster (user time) on my laptop (Linux 2.6, x86_64),
which is ~3.5 as slow as sequential execution.


configure.in:
	Update the configuration for a changed MR_SyncTerm structure.

compiler/llds.m:
	Make the fork instruction take a second argument, which is the base
	stack slot of the sync term.

	Rename it to fork_new_child to match the macro name in the runtime.

compiler/par_conj_gen.m:
	Change the generated code for parallel conjunctions to allocate sync
	terms on the stack and to pass the sync term to fork_new_child.

compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_out.m:
compiler/llds_to_x86_64.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/reassign.m:
compiler/use_local_vars.m:
	Conform to the change in the fork instruction.

compiler/liveness.m:
compiler/proc_gen.m:
	Disable use of the parallel conjunction operator in the compiler as
	older versions of the compiler will generate code incompatible with
	the new runtime.

runtime/mercury_context.c:
runtime/mercury_context.h:
	Remove the next pointer field from MR_Spark as it's no longer needed.

	Remove the mutex from MR_SyncTerm.  Add a field to record if a spark
	belonging to the sync term was scheduled globally, i.e. if the
	parallel conjunction might be executed in parallel.

	Define MR_SparkDeque and MR_SparkArray.

	Use MR_SparkDeques to hold per-context sparks and global sparks.

	Change the abstract machine instructions MR_init_sync_term,
	MR_fork_new_child, MR_join_and_continue as per the main change log.

	Use a preprocessor macro MR_LL_PARALLEL_CONJ as a shorthand for
	!MR_HIGHLEVEL_CODE && MR_THREAD_SAFE.

	Take the opportunity to clean things up a bit.

runtime/mercury_wsdeque.c:
runtime/mercury_wsdeque.h:
	New files containing an implementation of work-stealing deques.  We
	don't do work stealing yet but we use the underlying data structure.

runtime/mercury_atomic.c:
runtime/mercury_atomic.h:
	New files to contain atomic operations.  Currently it just contains
	compare-and-swap for gcc/x86_64, gcc/x86 and gcc-4.1.

runtime/Mmakefile:
	Add the new files.

runtime/mercury_engine.h:
runtime/mercury_mm_own_stacks.c:
runtime/mercury_wrapper.c:
	Conform to runtime changes.

runtime/mercury_conf_param.h:
	Update an outdated comment.
2007-10-11 11:45:22 +00:00
Julien Fischer
1fac629e6d Add support for foreign enumerations to Mercury.
Estimated hours taken: 50
Branches: main

Add support for foreign enumerations to Mercury.  These allow the
programmer to assign foreign language values as the representation of
enumeration constructors.

e.g.
	:- type status
		--->	optimal
		;	infeasible
		;	unbounded
		;	unknown.

	:- pragma foreign_enum("C", status/0, [
		optimal    - "STATUS_OPTIMAL",
		infeasible - "STATUS_INFEASIBLE",
		unbounded  - "STATUS_UNBOUNDED",
		unknown    - "STATUS_UNKNOWN"
	]).

The advantage of this is that when values of type status/0 are passed to
foreign code (C in this case) no translation is necessary.  This should
simplify the task of writing bindings to foreign language libraries.

Unification and comparison for foreign enumerations are the usual
unification and comparison for enumeration types, except that the default
ordering on them is determined by the foreign representation of the
constructors.  User-defined equality and comparison also work for foreign
enumeration types.

In order to implement foreign enumerations we have to introduce two
new type_ctor representations.  The existing ones for enum type do not
work since they use the value of an enumeration constructor to perform
table lookups in the RTTI data structures.  For foreign enumerations
we need to perform a linear search at the corresponding points.  This
means that some RTTI operations related to deconstruction are more
expensive.

The dummy type optimisation is not applied to foreign enumerations as
the code generators currently initialise the arguments of non-builtin
dummy type foreign_proc arguments to zero.  For unit foreign enumerations
they should be initialised to the correct foreign value.  (This is could be
implemented but in practice it's probably not going to be worth it.)

Currently, foreign enumerations are only supported by the C backends.

compiler/prog_io_pragma.m:
	Parse foreign_enum pragmas.

	Generalise the code used to parse association lists of sym_names
	and strings since this is now used by the code to parse foreign_enum
	pragmas as well as that for foreign_export_enum pragmas.

	Fix a typo: s/foreign_expor_enum/foreign_export_enum/

compiler/prog_item.m:
	Represent foreign_enum pragmas in the parse tree.

compiler/prog_type.m:
	Add a new type category for foreign enumerations.

compiler/modules.m:
	Add any foreign_enum pragmas for enumeration types defined in the
	interface of a module to the interface files.

	Output foreign_import_module pragmas in the interface file
	if any foreign_enum pragmas are included in it.  This ensures that
	the contents that any foreign declarations that are needed by the
	foreign_enum pragmas are visible.

compiler/make_hlds_passes.m:
compiler/add_pragma.m:
	Add pragma foreign_enum items to the HLDS after all the types
	have been added.  As they are added, error check them.

	Change the constructor tag values of foreign enum types to their
	foreign values.

compiler/module_qual.m:
	Module qualify pragma foreign_enum items.

compiler/mercury_to_mercury.m:
	Output foreign_enum pragmas.

	Generalise some of the existing code for writing out association
	lists in foreign_export_enum pragmas for use with foreign_enum
	pragmas as well.

compiler/hlds_data.m:
	Add the alternative `is_foreign_type' to the type enum_or_dummy/0.

	Add new type of cons_tag, foreign_tag, whose values are directly
	embedded in the target language.

compiler/intermod.m:
	Write out any foreign_enum pragmas for opt_exported types.
	(The XXX concerning attaching language information to foreign tags
	will be addressed in a subsequent change.)

compiler/llds.m:
compiler/mlds.m:
	Support new kinds of rval constants: llconst_foreign and
	mlconst_foreign respectively.  Both of these represent tag values
	as strings that are intended to be directly embedded in the target
	language.

compiler/llds_out.m:
	Add code to write out the new kind of rval_const.

	s/Integer/MR_Integer/ in a spot.
	s/Float/MR_Float/ in a spot.

compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/type_ctor_info.m:
	Add support the RTTI required by foreign enums.

compiler/switch_util.m:
	Handle switches on foreign_enums as-per normal enumerations.

compiler/table_gen.m:
	Tabling of foreign_enums is also like normal enumerations.

compiler/type_util.m:
	Add a predicate that tests whether a type is a foreign enumeration.

compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/ml_unify_gen.m:
	Handle unification and comparison of foreign enumeration values.
	They are treated like normal enumerations for the purposes of
	implementing these operations.

compiler/ml_type_gen.m:
	Handle foreign enumerations when generating the MLDS representation
	of enumerations.

compiler/ml_util.m:
	Add a function to create an initializer for an object with a
	foreign tag.

compiler/mlds_to_c.m:
	Handle mlconst_foreign/1 rval constants.

compiler/bytecode_gen.m:
compiler/dupproc.m:
compiler/erl_rtti.m:
compiler/exception_analysis.m:
compiler/export.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/hlds_out.m:
compiler/higher_order.m:
compiler/inst_match.m:
compiler/jumpopt.m:
compiler/llds_to_x86_64.m:
compiler/ml_code_util.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/polymorphism.m:
compiler/recompilation.version.m:
compiler/term_norm.m:
compiler/trailing_analysis.m:
	Conform to the above changes.

doc/reference_manual.texi:
	Document the new pragma.

	Fix some typos: s/pramga/pragma/, s/behavior/behaviour/

library/construct.m:
	Handle the two new type_ctor reps.

	Break an over-long line.

library/rtti_implementation.m:
	Support the two new type_ctor reps.
	(XXX The Java versions of some of this cannot be implemented until
	support for foreign enumerations is added to mlds_to_java.m.)

	Reformat the inst usereq/0 and extend it to include foreign enums.

runtime/mercury_type_info.h:
	Add two new type_ctor reps.  One for foreign enumerations and
	another for foreign enumerations with user equality.

	Define new types (and extend existing ones) in order to support
	RTTI for foreign enumerations.

runtime/mercury_unify_compare_body.h:
	Implement generic unify and compare for foreign enumerations.
	(It is the same as that for regular enumerations.)

runtime/mercury_construct.[ch]:
runtime/mercury_deconstruct.h:
	Handle (de)construction of foreign enumeration values.

runtime/mercury_deep_copy_body.h:
	Implement deep copy for foreign enumerations.

runtime/mercury_table_type_body.h:
runtime/mercury_term_size.c:
	Handle the new type_ctor representations.

java/runtime/ForeignEnumFunctorDesc.java:
	Add a Java version of the MR_ForeignEnumFuntorDesc structure.
	(Note: this is untested, as the java grade runtime doesn't work
	anyway.)

java/runtime/TypeFunctors.java:
	Add a constructor method for foreign enumerations.
	(Likewise, untested.)

NEWS:
	Announce pragma foreign_enum.

vim/syntax/mercury.vim:
	Highlight the new pragma appropriately.

tests/hard_coded/.cvsignore:
	Ignore executables generated by the new tests.

	Ignore a bunch of other files create by the Mercury compiler.

tests/hard_coded/Mmakefile:
tests/hard_coded/foreign_enum_rtti.{m,exp}:
	Test RTTI for foreign enumerations.

tests/hard_coded/foreign_enum_dummy.{m,exp}:
	Check that dummy type optimisation is disabled for foreign
	enumerations.

tests/hard_coded/Mercury.options:
tests/hard_coded/foreign_enum_mod1.{m,exp}:
tests/hard_coded/foreign_enum_mod2.m:
	Test that foreign_enum pragmas are hoisted into interface files
	and that they are handled correctly in optimization interfaces.

tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/foreign_enum_import.{m,err_exp}:
tests/invalid/foreign_enum_invalid.{m,err_exp}:
	Test that errors in foreign_enum pragmas are reported.

tests/tabling/Mmakefile:
tests/hard_coded/table_foreign_enum.{m,exp}:
	Test case for tabling of foreign enumerations.
2007-08-20 03:39:31 +00:00
Zoltan Somogyi
b48eaf8073 Add a first draft of the code generator support for region based memory
Estimated hours taken: 30
Branches: main

Add a first draft of the code generator support for region based memory
management. It is known to be incomplete; the missing parts are marked by XXXs.
It may also be buggy; it will be tested after Quan adds the runtime support,
i.e. the C macros invoked by the new LLDS instructions. However, the changes
in this diff shouldn't affect non-RBMM operations.

compiler/llds.m:
	Add five new LLDS instructions. Four are specific to RBMM operations.
	RBMM embeds three new stacks in compiler-reserved temp slots in
	procedure's usual Mercury stack frames, and the new LLDS instructions
	respectively

	(i)   push those stack frames onto their respective stacks,
	(ii)  fill some variable parts of those stack frames,
	(iii) fill fixed slots of those stack frames, and
	(iv)  use the contents of and/or pop those stack frames.

	(The pushing and popping affect only the new embedded stacks, not the
	usual Mercury stacks.)

	The last instruction is a new variant of the old assign instruction.
	It has identical semantics, but restricts optimization. An assign

	(a) can be deleted if its target lval is not used, and
	(b) its target lval can be changed (e.g. to a temp register) as long as
	    all the later instructions referring to that lval are changed to
	    use the new lval instead.

	Neither is permitted for the new keep_assign instruction. This is
	required because in an earlier draft we used it to assign to stack
	variables (parts of the embedded stack frames) that aren't explicitly
	referred to in later LLDS code, but are nevertheless implicitly
	referred to by some instructions (specifically iv above). We now
	use a specialized instruction (iii above) for this (since the macro
	it invokes can refer to C structure names, this makes it easier to
	keep the compiler in sync with the runtime system), but given that
	keep_assign is already implemented, may be useful later and shouldn't
	cause appreciable slowdown of the compiler, this diff keeps it.

	Extend the type that describe the contents of lvals to allow it
	to describe the new kinds of things we can now store in them.

	Add types to manage and describe the new embedded stack frames,
	and some utility functions. Change some existing utility functions
	to make all this more conceptually consistent.

compiler/ite_gen.m:
	Surround the code we generate for the condition of if-then-elses
	with the code required to ensure that regions that are logically
	removed in the condition aren't physically destroyed until we know
	that the condition succeeds (since the region may still be needed
	in the else branch), and to make sure that if the condition fails,
	all the memory allocated since the entry into the condition is
	reclaimed instantly.

compiler/disj_gen.m:
	Surround the code we generate for disjunctions with the code required
	to ensure that regions that are logically removed in a disjunct
	aren't physically destroyed if a later disjunct needs them, and to
	make sure that at entry into a non-first disjunct, all the memory
	allocated since the entry into the disjunction is reclaimed instantly.

compiler/commit_gen.m:
compiler/code_info.m:
	The protection against destruction offered by a disjunction disappears
	when a commit cuts away all later alternatives in that disjunct, so we
	must undo that protection. We therefore surround the scope of a commit
	goal with goal that achieves that objective.

	Add some new utility predicates to code_info. Remove some old utility
	functions that are now in llds.m.

compiler/continuation_info.m:
	Extend the type that describe the contents of stack slots to allow it
	to describe the new kinds of things we can now store in them.

	Rename the function symbols of that type to eliminate some ambiguities.

compiler/code_gen.m:
	Remember the set of variables live at the start of the goal
	(before the pre_goal_update updates it), since the region operations
	need to know this.

	Leave the lookup of AddTrailOps (and now AddRegionOps) to the specific
	kinds of goals that need it (the most frequent goals, unify and call,
	do not). Make both AddTrailOps and AddRegionOps use a self-explanatory
	type instead of a boolean.

compiler/lookup_switch.m:
	Conform to the change to AddTrailOps.

	Fix some misleading variable names.

compiler/options.m:
	Add some options to control the number of stack slots needed for
	various purposes. These have to correspond to the sizes of some C
	structures in the runtime system. Eventually these will be constants,
	but it is handy to keep them easily changeable while the C data
	structures are still being worked on.

	Add an option for optimizing away region ops whereever possible.
	The intention is that these should be on all the time, but we
	will want to turn them off for benchmarking.

compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/frameopt.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_out.m:
compiler/llds_to_x86_64.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/par_conj_gen.m:
compiler/reassign.m:
compiler/stack_layout.m:
compiler/stdlabel.m:
compiler/trace_gen.m:
compiler/use_local_vars.m:
	Conform to the changes above, which mostly means handling the new
	LLDS instructions.

	In some cases, factor out existing common code, turn if-then-elses
	into switches, group common cases in switches, rationalize argument
	orders or variable names, and/or put code in execution order.

	In reassign.m, fix some old oversights that could (in some unlikely
	cases) cause bugs in the generated code.

compiler/pragma_c_gen.m:
	Exploit the capabilities of code_info.m.

compiler/prog_type.m:
	Add a utility predicate.
2007-07-31 01:56:41 +00:00
Quan Phan
d4818a3ca4 Modify the code generator so that it recognizes construct_in_region and
Estimated hours taken: 35.
Branch: main.

Modify the code generator so that it recognizes construct_in_region and
generates suitable code when RBMM is used. The main
changes are in unify_gen.m. incr_hp is also changed to receive one more
(maybe) argument for region.

compiler/unify_gen.m:
	Make it aware of HowToConstruct. This is the starting point of the
	changes in the code generator so that it can generate code which
	constructs terms in regions.

compiler/code_info.m:
compiler/var_locn.m:
        Change in accordance with the introduction of how_to_construct in
	unify_gen.m.

compiler/llds.m:
	Add one extra argument to incr_hp for the region to construct terms
	in.

compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_to_x86_64.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/par_conj_gen.m:
compiler/reassign.m:
compiler/use_local_vars.m:
	Change to deal with the extra maybe region argument in incr_hp.

compiler/llds_out.m:
	Modify so that when RBMM is used it generates suitable call to
	the region runtime for allocating terms in regions. The region
	runtime (in C code) will be posted in anothe email.

compiler/hlds_data.m:
	Fix a typo.

compiler/rbmm.interproc_region_lifetime.m:
	Change to comply with coding standard.
2007-07-09 13:28:36 +00:00
Simon Taylor
5647714667 Make all functions which create strings from characters throw an exception
Estimated hours taken: 15
Branches: main

Make all functions which create strings from characters throw an exception
or fail if the list of characters contains a null character.

This removes a potential source of security vulnerabilities where one
part of the program performs checks against the whole of a string passed
in by an attacker (processing the string as a list of characters or using
`unsafe_index' to look past the null character), but then passes the string
to another part of the program or an operating system call that only sees
up to the first null character.  Even if Mercury stored the length with
the string, allowing the creation of strings containing nulls would be a
bad idea because it would be too easy to pass a string to foreign code
without checking.

For examples see:
<http://insecure.org/news/P55-07.txt>
<http://www.securiteam.com/securitynews/5WP0B1FKKQ.html>
<http://www.securityfocus.com/archive/1/445788>
<http://www.securityfocus.com/archive/82/368750>
<http://secunia.com/advisories/16420/>

NEWS:
	Document the change.

library/string.m:
	Throw an exception if null characters are found in
	string.from_char_list and string.from_rev_char_list.

	Add string.from_char_list_semidet and string.from_rev_char_list_semidet
	which fail rather throwing an exception.  This doesn't match the
	normal naming convention, but string.from_{,rev_}char_list are widely
	used, so changing their determinism would be a bit too disruptive.

	Don't allocate an unnecessary extra word for each string created by
	from_char_list and from_rev_char_list.

	Explain that to_upper and to_lower only work on un-accented
	Latin letters.

library/lexer.m:
	Check for invalid characters when reading Mercury strings and
	quoted names.

	Improve error messages by skipping to the end of any string
	or quoted name containing an error.  Previously we just stopped
	processing at the error leaving an unmatched quote.

library/io.m:
	Make io.read_line_as_string and io.read_file_as_string return
	an error code if the input file contains a null character.

	Fix an XXX: '\0\' is not recognised as a character constant,
	but char.det_from_int can be used to make a null character.

library/char.m:
	Explain the workaround for '\0\' not being accepted as a char
	constant.

	Explain that to_upper and to_lower only work on un-accented
	Latin letters.

compiler/layout.m:
compiler/layout_out.m:
compiler/c_util.m:
compiler/stack_layout.m:
compiler/llds.m:
compiler/mlds.m:
compiler/ll_backend.*.m:
compiler/ml_backend.*.m:
	Don't pass around strings containing null characters (the string
	tables for the debugger).  This doesn't cause any problems now,
	but won't work with the accurate garbage collector.  Use lists
	of strings instead, and add the null characters when writing the
	strings out.

tests/hard_coded/null_char.{m,exp}:
	Change an existing test case to test that creation of a string
	containing a null throws an exception.

tests/hard_coded/null_char.exp2:
	Deleted because alternative output is no longer needed.

tests/invalid/Mmakefile:
tests/invalid/null_char.m:
tests/invalid/null_char.err_exp:
	Test error messages for construction of strings containing null
	characters by the lexer.

tests/invalid/unicode{1,2}.err_exp:
	Update the expected output after the change to the handling of
	invalid quoted names and strings.
2007-03-18 23:35:04 +00:00
Zoltan Somogyi
ba93a52fe7 This diff changes a few types from being defined as equivalent to a pair
Estimated hours taken: 10
Branches: main

This diff changes a few types from being defined as equivalent to a pair
to being discriminated union types with their own function symbol. This
was motivated by an error message (one of many, but the one that broke
the camel's back) about "-" being used in an ambiguous manner. It will
reduce the number of such messages in the future, and will make compiler
data structures easier to inspect in the debugger.

The most important type changed by far is hlds_goal, whose function symbol
is now "hlds_goal". Second and third in importance are llds.instruction
(function symbol "llds_instr") and prog_item.m's item_and_context (function
symbol "item_and_context"). There are some others as well.

In several places, I rearranged predicates to factor the deconstruction of
goals into hlds_goal_expr and hlds_goal_into out of each clause into a single
point. In many places, I changed variable names that used "Goal" to refer
to just hlds_goal_exprs to use "GoalExpr" instead. I also changed variable
names that used "Item" to refer to item_and_contexts to use "ItemAndContext"
instead. This should make reading such code less confusing.

I renamed some function symbols and predicates to avoid ambiguities.

I only made one algorithmic change (at least intentionally).
In assertion.m, comparing two goals for equality now ignores goal_infos
for all kinds of goals, whereas previously it ignored them for most kinds
of goals, but for shorthand goals it was insisting on them being equal.
This seemed to me to be a bug. Pete, can you confirm this?
2007-01-06 09:23:59 +00:00
Zoltan Somogyi
d66ed699a1 Add fields to structures representing the C code itself that says whether
Estimated hours taken: 4
Branches: main

Add fields to structures representing the C code itself that says whether
or not the C code affects the liveness of lvals. This is intended as the basis
for future improvements in the optimization of such code.

Implement a new foreign_proc attribute that allows programmers to set
the value of this field.

Eliminate names referring to `pragma c_code' in the LLDS backend in favor
of names referring to foreign_procs.

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

	Consistently put the field containing C code last in the function
	symbols that contain them.

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

	Rename some other function symbols to avoid ambiguity.

compiler/prog_io_pragma.m:
	Parse the new foreign_proc attribute.

doc/reference_manual.texi:
	Document the new attribute.

compiler/pragma_c_gen.m:
	Rename the main predicates.

compiler/opt_util.m:
	Change some predicates into functions, for more convenient invocation.

compiler/livemap.m:
	Rename the predicates in this module to avoid ambiguity and the need
	for module qualification.

compiler/*.m:
	Conform to the changes above.
2007-01-03 07:20:47 +00:00
Zoltan Somogyi
ecf1ee3117 Add a mechanism for growing the stacks on demand by adding new segments
Estimated hours taken: 20
Branches: main

Add a mechanism for growing the stacks on demand by adding new segments
to them. You can ask for the new mechanism via a new grade component, stseg
(short for "stack segments").

The mechanism works by adding a test to each increment of a stack pointer (sp
or maxfr). If the test indicates that we are about to run out of stack, we
allocate a new stack segment, allocate a placeholder frame on the new segment,
and then allocate the frame we wanted in the first place on top of the
placeholder. We also override succip to make it point code that will (1)
release the new segment when the newly created stack frame returns, and then
(2) go to the place indicated by the original, overridden succip.

For leaf procedures on the det stack, we optimize away the check of the stack
pointer. We can do this because we reserve some space on each stack for the
use of such stack frames.

My intention is that doc/user_guide.texi and NEWS will be updated once we have
used the feature ourselves for a while and it seems to be stable.

runtime/mercury_grade.h:
	Add the new grade component.

runtime/mercury_conf_param.h:
	Document the new grade component, and the option used to debug stack
	segments.

runtime/mercury_context.[ch]:
	Add new fields to contexts to hold the list of previous segments of the
	det and nondet stacks.

runtime/mercury_memory_zones.[ch]:
	Include a threshold in all zones, for use in stack segments.
	Set it when a zone is allocated.

	Restore the previous #ifdef'd out function MR_unget_zone, for use
	when freeing stack segments execution has fallen out of.

runtime/mercury_debug.[ch]:
	When printing the offsets of pointers into the det and nondet stacks,
	print the number of the segment the pointer points into (unless it is
	the first, in which case we suppress this in the interest of brevity
	and simplicity).

	Make all the functions in this module take a FILE * as an input
	argument; don't print to stdout by default.

runtime/mercury_stacks.[ch]:
	Modify the macros that allocate stack frames to invoke the code for
	adding new stack segments when we are about to run out of stack.

	Standardize on "nondet" over "nond" as the abbreviation referring to
	the nondet stack.

	Conform to the changes in mercury_debug.c.

runtime/mercury_stack_trace.c:
	When traversing the stack, step over the placeholder stack frames
	at the bottoms of stack segments.

	Conform to the changes in mercury_debug.c.

runtime/mercury_wrapper.[ch]:
	Make the default stack size small in grades that support stack
	segments.

	Standardize on "nondet" over "nond" as the abbreviation referring to
	the nondet stack.

	Conform to the changes in mercury_debug.c.

runtime/mercury_memory.c:
	Standardize on "nondet" over "nond" as the abbreviation referring to
	the nondet stack.

runtime/mercury_engine.[ch]:
runtime/mercury_overflow.h:
	Standardize on "nondet" over "nond" as the abbreviation referring to
	the nondet stack.

	Convert these files to four-space indentation.

runtime/mercury_minimal_model.c:
trace/mercury_trace.c:
trace/mercury_trace_util.c:
	Conform to the changes in mercury_debug.c.

compiler/options.m:
	Add the new grade option for stack segments.

compiler/compile_target_code.m:
compiler/handle_options.m:
	Add the new grade component, and handle its exclusions with other grade
	components and optimizations.

compiler/llds.m:
	Extend the incr_sp instruction to record whether the stack frame
	is for a leaf procedure.

compiler/llds_out.m:
	Output the extended incr_sp instruction.

compiler/proc_gen.m:
	Fill in the extra slot in incr_sp instructions.

compiler/goal_util.m:
	Provide a predicate for testing whether a procedure body is a leaf.

compiler/delay_slot.m:
compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/frameopt.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/peephole.m:
compiler/reassign.m:
compiler/use_local_vars.m:
	Conform to the change in llds.m.

scripts/canonicate_grade.sh-subr:
scripts/init_grade_options.sh-subr:
scripts/parse_grade_options.sh-subr:
scripts/final_grade_options.sh-subr:
scripts/mgnuc.in:
	Handle the new grade component.

	Convert parse_grade_options.sh-subr to four-space indentation.

Mmake.workspace:
	Fix an old bug that prevented bootcheck from working in the new grade:
	when computing the gc grade, use the workspace's version of ml (which
	in this case understands the new grade components), rather than the
	installed ml (which does not).

	(This was a devil to track down, because neither make --debug nor
	strace on make revealed how the installed ml was being invoked,
	and there was no explicit invocation in the Makefile either; the error
	message appeared to come out of thin air just before the completion
	of the stage 2 library. It turned out the invocation happened
	implicitly, as a result of expanding a make variable.)
2006-11-01 02:31:19 +00:00
Zoltan Somogyi
e21193c283 Rename a bunch of predicates and function symbols to eliminate
Estimated hours taken: 6
Branches: main

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

	The only real change is factoring out some common code in the mlds
	and llds code generators, replacing them with single definitions
	in switch_util.m.
2006-10-15 23:26:56 +00:00
Peter Wang
712027f307 This patch changes the parallel execution mechanism in the low level backend.
Estimated hours taken: 100
Branches: main

This patch changes the parallel execution mechanism in the low level backend.
The main idea is that, even in programs with only moderate parallelism, we
won't have enough processors to exploit it all.  We should try to reduce the
cost in the common case, i.e. when a parallel conjunction gets executed
sequentially.  This patch does two things along those lines:

(1) Instead of unconditionally executing all parallel conjuncts (but the last)
in separate Mercury contexts, we allow a context to continue execution of the
next conjunct of a parallel conjunction if it has just finished executing the
previous conjunct.  This saves on allocating unnecessary contexts, which can
be a big reduction in memory usage.

We also try to execute conjuncts left-to-right so as to minimise the
need to suspend contexts when there are dependencies between conjuncts.

(2) Conjuncts that *are* executed in parallel still need separate contexts.
We used to pass variable bindings to those conjuncts by flushing input
variable values to stack slots and copying the procedure's stack frame to the
new context.  When the conjunct finished, we would copy new variable bindings
back to stack slots in the original context.

What happens now is that we don't do any copying back and forth.  We introduce
a new abstract machine register `parent_sp' which points to the location of
the stack pointer at the time that a parallel conjunction began.  In parallel
conjuncts we refer to all stack slots via the `parent_sp' pointer, since we
could be running on a different context altogether and `sp' would be pointing
into a new detstack.  Since parallel conjuncts now share the procedure's stack
frame, we have to allocate stack slots such that all parallel conjuncts in a
procedure that could be executing simultaneously have distinct sets of stack
slots.  We currently use the simplest possible strategy, i.e. don't allow
variables in parallel conjuncts to reuse stack slots.

Note: in effect parent_sp is a frame pointer which is only set for and used by
the code of parallel conjuncts.  We don't call it a frame pointer as it can be
confused with "frame variables" which have to do with the nondet stack.


compiler/code_info.m:
	Add functionality to keep track of how deep inside of nested parallel
	conjunctions the code generator is.

	Add functionality to acquire and release "persistent" temporary stack
	slots.  Unlike normal temporary stack slots, these don't get implicitly
	released when the code generator's location-dependent state is reset.

	Conform to additions of `parent_sp' and parent stack variables.

compiler/exprn_aux.m:
	Generalise the `substitute_lval_in_*' predicates by
	`transform_lval_in_*' predicates.  Instead of performing a fixed
	substitution, these take a higher order predicate which performs some
	operation on each lval.  Redefine the substitution predicates in terms
	of the transformation predicates.

	Conform to changes in `fork', `join_and_terminate' and
	`join_and_continue' instructions.

	Conform to additions of `parent_sp' and parent stack variables.

	Remove `substitute_rval_in_args' and `substitute_rval_in_arg' which
	were unused.

compiler/live_vars.m:
	Introduce a new type `parallel_stackvars' which is threaded through
	`build_live_sets_in_goal'.  We accumulate the sets of variables which
	are assigned stack slots in each parallel conjunct.  At the end of
	processing a parallel conjunction, use this information to force
	variables which are assigned stack slots to have distinct slots.

compiler/llds.m:
	Change the semantics of the `fork' instruction.  It now takes a single
	argument: the label of the next conjunct after the current one.  The
	instruction now "sparks" the next conjunct to be run, either in a
	different context (possibly in parallel, on another Mercury engine) or
	is queued to be executed in the current context after the current
	conjunct is finished.

	Change the semantics of the `join_and_continue' instruction.  This
	instruction now serves to end all parallel conjuncts, not just the
	last one in a parallel conjunction.

	Remove the `join_and_terminate' instruction (no longer used).

	Add the new abstract machine register `parent_sp'.

	Introduce "parent stack slots", which are similar to normal stack
	slots but relative to the `parent_sp' register.

compiler/par_conj_gen.m:
	Change the code generated for parallel conjunctions.  That is:

	- use the new `fork' instruction at the beginning of a parallel
	  conjunct;

	- use the `join_and_continue' instruction at the end of all parallel
	  conjuncts;

	- keep track of how deep the code generator currently is in parallel
	  conjunctions;

	- set and restore the `parent_sp' register when entering a non-nested
	  parallel conjunction;

	- after generating the code of a parallel conjunct, replace all
	  references to stack slots by parent stack slots;

	- remove code to copy back output variables when a parallel conjunct
	  finishes.

	Update some comments.

runtime/mercury_context.c:
runtime/mercury_context.h:
	Add the type `MR_Spark'.  Sparks are allocated on the heap and contain
	enough information to begin execution of a single parallel conjunct.

	Add globals `MR_spark_queue_head' and `MR_spark_queue_tail'.  These
	are pointers to the start and end of a global queue of sparks.  Idle
	engines can pick up work from this queue in the same way that they can
	pick up work from the global context queue (the "run queue").

	Add new fields to the MR_Context structure.  `MR_ctxt_parent_sp' is a
	saved copy of the `parent_sp' register for when the context is
	suspended.  `MR_ctxt_spark_stack' is a stack of sparks that we decided
	not to put on the global spark queue.

	Update `MR_load_context' and `MR_save_context' to save and restore
	`MR_ctxt_parent_sp'.

	Add the counters `MR_num_idle_engines' and
	`MR_num_outstanding_contexts_and_sparks'.  These are used to decide,
	when a `fork' instruction is reached, whether a spark should be put on
	the global spark queue (with potential for parallelism but also more
	overhead) or on the calling context's spark stack (no parallelism and
	less overhead).

	Rename `MR_init_context' to `MR_init_context_maybe_generator'.  When
	initialising contexts, don't reset redzones of already allocated
	stacks.  It seems to be unnecessary (and the reset implementation is
	buggy anyway, though it's fine on Linux).

	Rename `MR_schedule' to `MR_schedule_context'.  Add new functions
	`MR_schedule_spark_globally' and `MR_schedule_spark_locally'.

	In `MR_do_runnext', add code for idle engines to get work from the
	global spark queue.  Resuming contexts are prioritised over sparks.

	Rename `MR_fork_new_context' to `MR_fork_new_child'.  Change the
	definitions of `MR_fork_new_child' and `MR_join_and_continue' as per
	the new behaviour of the `fork' and `join_and_continue' instructions.
	Delete `MR_join_and_terminate'.

	Add a new field `MR_st_orig_context' to the MR_SyncTerm structure to
	record which context originated the parallel conjunction instance
	represented by a MR_SyncTerm instance, and update `MR_init_sync_term'.
	This is needed by the new behaviour of `MR_join_and_continue'.

	Update some comments.

runtime/mercury_engine.h:
runtime/mercury_regs.c:
runtime/mercury_regs.h:
runtime/mercury_stacks.h:
	Add the abstract machine register `parent_sp' and code to copy it to
	and from the fake_reg array.

	Add a macro `MR_parent_sv' to access stack slots via `parent_sp'.

	Add `MR_eng_parent_sp' to the MercuryEngine structure.

runtime/mercury_wrapper.c:
runtime/mercury_wrapper.h:
	Add Mercury runtime option `--max-contexts-per-thread' which is saved
	in the global variable `MR_max_contexts_per_thread'.  The number
	`MR_max_outstanding_contexts' is derived from this.  It sets a soft
	limit on the number of sparks we put in the global spark queue,
	relative to the number of threads we are running.  We don't want to
	put too many sparks on the global queue if there are plenty of ready
	contexts or sparks already on the global queues, as they are likely to
	result in new contexts being allocated.

	When initially creating worker engines, wait until all the worker
	engines have acknowledged that they are idle before continuing.  This
	is mainly so programs (especially benchmarks and test cases) with only
	a few fork instructions near the beginning of the program don't
	execute the forks before any worker engines are ready, resulting in no
	parallelism.

runtime/mercury_engine.c:
runtime/mercury_thread.c:
	Don't allocate a context at the time a Mercury engine is created.  An
	engine only needs a new context when it is about to pick up a spark.

configure.in:
compiler/options.m:
scripts/Mercury.config.in:
	Update to reflect the extra field in MR_SyncTerm.

	Add the option `--sync-term-size' and actually make use the result of
	the sync term size calculated during configuration.

compiler/code_util.m:
compiler/continuation_info.m:
compiler/dupelim.m:
compiler/dupproc.m:
compiler/global_data.m:
compiler/hlds_llds.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_out.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/reassign.m:
compiler/stack_layout.m:
compiler/use_local_vars.m:
compiler/var_locn.m:
	Conform to changes in `fork', `join_and_terminate' and
	`join_and_continue' instructions.

	Conform to additions of `parent_sp' and parent stack variables.

	XXX not sure about the changes in stack_layout.m

library/par_builtin.m:
	Conform to changes in the runtime system.
2006-09-26 03:53:23 +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
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
9d23d8e2e7 Implement the trace goal construct we discussed, for now for the LLDS backends
Estimated hours taken: 70
Branches: main

Implement the trace goal construct we discussed, for now for the LLDS backends
only.

Since the syntax of trace goals is non-trivial, useful feedback on syntax
errors inside trace goal attributes is essential. With the previous setup, this
wasn't possible, since the code that turned terms into parse tree goals turned
*all* terms into goals; it couldn't recognize any errors, sweeping them under
the rug as calls. This diff changes that. Now, if this code recognizes a
keyword that indicates a particular construct, it insists on the rest of the
code following the syntax required for that construct, and returns error
messages if it doesn't.

We handle the trace goal attributes that specify state variables to be threaded
through the trace goal (either the I/O state or a mutable variable) in
add_clause.m, at the point at which we transform the list of items to the HLDS.
We handle the compile-time condition on trace goals in the invocation of
simplify at the end of semantics analysis, by eliminating the goal if the
compile-time condition isn't met. We handle run-time conditions on trace goals
partially in the same invocation of simplify: we transform trace goals with
runtime conditions into an if-then-else with the trace goal as the then part
and `true' as the else part, the condition being a foreign_proc that is handled
specially by the code generator, that special handling being to replace
the actual code of the foreign_proc (which is a dummy) with the evaluation of
the runtime condition.

Since these changes require significant changes to some of our key data
structures, I took the liberty of doing some renaming of function symbols
at the same time to avoid using ambiguities with respect to language keywords.

library/ops.m:
	Add "trace" as an operator.

compiler/prog_data.m:
	Define data types to represent the various attributes of trace goals.

	Rename some function symbols to avoid ambiguities.

compiler/prog_item.m:
	Extend the parse tree representation of goals with a trace goal.

compiler/mercury_to_mercury.m:
	Output the new kind of goal and its components.

compiler/hlds_goal.m:
	Extend the HLDS representation of scopes with a scope_reason
	representing trace goals.

	Add a mechanism (an extra argument in foreign_procs) to allow
	the representation of goals that evaluate runtime trace conditions.

	Since this requires modifying all code that traverses the HLDS,
	do some renames that were long overdue: rename not as negation,
	rename call as plain_call, and rename foreign_proc as
	call_foreign_proc. These renames all avoid using language keywords
	as function symbols.

	Change the way we record goals' purities. Instead of optional features
	to indicate impure or semipure, which is error-prone, use a plain
	field in the goal_info, accessed in the usual way.

	Add a way to represent that a goal contains a trace goal, and should
	therefore be treated as if it were impure when considering whether to
	optimize it away.

	Reformat some comments describing function symbols.

compiler/hlds_out.m:
	Output the new construct in the HLDS.

compiler/prog_io_util.m:
	Generalize the maybe[123] types to allow the representation of more
	than one error message. Add functions to extract the error messages.
	Add a maybe4 type. Rename the function symbols of these types to
	avoid massive ambiguity.

	Change the order of some predicates to bring related predicates
	next to each other.

compiler/prog_io.m:
compiler/prog_io_dcg.m:
compiler/prog_io_goal.m:
compiler/prog_io_pragma.m:
	Rework these modules almost completely to find and accumulate syntax
	errors as terms are being parsed. In some cases, this allowed us to
	replace "XXX this is a hack" markers with meaningful error-reporting
	code.

	In prog_io_goal.m, add code for parsing trace goals.

	In a bunch of places, update obsolete coding practices, such as using
	nested chains of closures instead of simple sequential code, and
	using A0 and A to refer to values of different types (terms and goals
	respectively). Use more meaningful variable names.

	Break up some too-large predicates.

compiler/superhomogeneous.m:
	Find and accumulate syntax errors as terms are being parsed.

compiler/add_clause.m:
	Add code to transform trace goals from the parse tree to the HLDS.
	This is where the IO state and mutable variable attributes of trace
	goals are handled.

	Eliminate the practice of using the naming scheme Body0 and Body
	to refer to values of different types (prog_item.goal and hlds_goal
	respectively).

	Use error_util for some error messages.

library/private_builtin.m:
	Add the predicates referred to by the transformation in add_clause.m.

compiler/goal_util.m:
	Rename a predicate to avoid ambiguity.

compiler/typecheck.m:
	Do not print error messages about missing clauses if some errors have
	been detected previously.

compiler/purity.m:
	Instead of just computing purity, compute (and record) also whether
	a goal contains a trace goal. However, treat trace goals as pure.

compiler/mode_info.m:
	Add trace goals as a reason for locking variables.

	Rename some function symbols to avoid ambiguity.

compiler/modes.m:
	When analyzing trace goal scopes, lock the scope's nonlocal variables
	to prevent them from being further instantiated.

compiler/det_analysis.m:
	Insist on the code in trace goal scopes being det or cc_multi.

compiler/det_report.m:
	Generate the error message if the code in a trace goal scope isn't det
	or cc_multi.

compiler/simplify.m:
	At the end of the front end, eliminate trace goal scopes if their
	compile-time condition is false. Transform trace goals with runtime
	conditions as described at the top.

	Treat goals that contain trace goals as if they were impure when
	considering whether to optimize them away.

compiler/mercury_compile.m:
	Tell simplify when it is being invoked at the end of the front end.

	Rename a predicate to avoid ambiguity.

compiler/trace_params.m:
	Provide the predicates simplify.m need to be able to evaluate the trace
	goal conditions regarding trace levels.

compiler/trace.m:
compiler/trace_gen.m:
	Rename the trace module as trace_gen, since "trace" is now an operator.

	Rename some predicates exported by the module, now that it is no longer
	possible to preface calls with "trace." as a module qualifier.

compiler/notes/compiler_design.html:
	Document this name change.

compiler/options.m:
	Rename the trace option as trace_level internally, since "trace"
	is now an operator. The user-visible name remains the same.

	Add the new --trace-flag option.

	Delete an obsolete option.

compiler/handle_options.m:
	Rename the function symbols of the grade_component type,
	since "trace" is now an operator.

compiler/llds.m:
	Extend the LLDS with a mechanism to refer to C global variables.
	For now, these are used to refer to C globals that will be created
	by mkinit to represent the initial values of the environment variables
	referred to by trace goals.

compiler/commit_gen.m:
	Check that no trace goal with a runtime condition survives to code
	generation; they should have been transformed by simplify.m.

compiler/code_gen.m:
	Tell commit_gen.m what kind of scope it is generating code for.

compiler/pragma_c_gen.m:
	Generate code for runtime conditions when handling the foreign_procs
	created by simplify.m.

compiler/code_info.m:
	Allow pragma_c_gen.m to record what environment variables it has
	generated references to.

compiler/proc_gen.m:
	Record the set of environment variables a procedure refers to
	in the LLDS procedure header, for efficient access by llds_out.m.

compiler/llds_out.m:
	Handle the new LLDS construct, and tell mkinit which environment
	variables need C globals created for them.

compiler/pd_util.m:
	Rename some predicates to avoid ambiguity.

compiler/*.m:
	Conform to the changes above, mainly the renames of function symbols
	and predicates, the changed signatures of some predicates, and the new
	handling of purity.

util/mkinit.c:
	Generate the definitions and the initializations of any C globals
	representing the initial status (set or not set) of environment
	variables needed by trace goals.

library/assoc_list.m:
	Add some predicates that are useful in prog_io*.m.

library/term_io.m:
	Minor cleanup.

tests/hard_coded/trace_goal_{1,2}.{m,exp}:
	New test cases to test the new construct, identical except for whether
	the trace goal is enabled at compile time.

tests/hard_coded/trace_goal_env_{1,2}.{m,exp}:
	New test cases to test the new construct, identical except for whether
	the trace goal is enabled at run time.

tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
	Enable the new test cases.

tests/invalid/*.err_exp:
	Update the expected output for the new versions of the error messages
	now being generated.
2006-07-27 05:03:54 +00:00
Zoltan Somogyi
d5d5986472 Implement lookup switches in which a switch arm may contain more than one
Estimated hours taken: 40
Branches: main

Implement lookup switches in which a switch arm may contain more than one
solution, such as this code here:

	p(d, "four", f1, 4.4).
	p(e, "five", f2, 5.5).
	p(e, "five2", f3(5), 55.5).
	p(f, "six", f4("hex"), 6.6).
	p(g, "seven", f5(77.7), 7.7).
	p(g, "seven2", f1, 777.7).
	p(g, "seven3", f2, 7777.7).

Such code occurs frequently in benchmark programs used to evaluate the
performance of tabled logic programming systems.

Change frameopt.m, which previously worked only on det and semidet code,
to also work for nondet code. For predicates such as the one above, frameopt
can now arrange for the predicate's nondet stack frame to be created only
when a switch arm that has more than one solution is selected.

compiler/lookup_switch.m:
	Extend the existing code for recognizing and implementing lookup
	switches to recognize and implement them even if they are model_non.

compiler/lookup_util.m:
	New module containing utility predicates useful for implementing
	both lookup switches, and in the future, lookup disjunctions (i.e.
	disjunctions that correspond to a nondet arm of a lookup switch).

compiler/ll_backend.m:
	Include the new module.

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

compiler/global_data.m:
	Move the job of filling in dummy slots to our caller, in this case
	lookup_switch.m.

compiler/frameopt.m:
	Generalize the existing code for delaying stack frame creation,
	which worked only on predicates that live on the det stack, to work
	also on predicates that live on the nondet stack. Without this,
	predicates whose bodies are model_non lookup switches would create
	a nonstack stack frame before the switch is ever entered, which
	is wasteful if the selected switch arm has at most one solution.

	Since the structure of model_non predicates is more complex (you can
	cause a branch to a label by storing its address in a redoip slot,
	you can succeed from the frame without removing the frame), this
	required considerable extra work. To make the new code debuggable,
	record, for each basic block that needs a stack frame, *why* it
	needs that stack frame.

compiler/opt_util.m:
	Be more conservative about what refers to the stack. Export some
	previously internal functionality for frameopt. Turn some predicates
	into functions, and rename them to better reflect their purpose.

compiler/opt_debug.m:
	Print much more information about pragma_c and call LLDS instructions.

compiler/prog_data.m:
	Add an extra attribute to foreign_procs that says that the code
	of the foreign_proc assumes the existence of a stack frame.
	This is needed to avoid frameopt optimizing the stack frame away.

compiler/add_pragma.m:
	When processing fact tables, we create foreign_procs that assume
	the existence of the stack frame, so set the new attribute.

compiler/pragma_c_gen.m:
	When processing foreign_procs, transmit the information in the
	attribute to the generated LLDS code.

compiler/llds.m:
	Rename the function symbols referring to the fixed slots in nondet
	stack frames to make them clearer and to avoid overloading function
	symbols such as curfr and succip.

	Rename the function symbols of the call_model type to avoid overloading
	the function symbols of the code_model type.

	Add a new field to the c_procedure type giving the code_model of the
	procedure, and give names to all the fields.

	Describe the stack slots used by lookup switches to the debugger
	and native gc.

compiler/options.m:
doc/user_guide.texi:
	Add a new option, --debug-opt-pred-name, that does when the existing
	--debug-opt-pred-id options does, but taking a user-friendly predicate
	name rather than a pred_id as its argument.

compiler/handle_options.m:
	Process --debug-opt-pred-name, and make --frameopt-comments imply
	--auto-comments, since it is not useful without it.

	Reformat some existing comments that were written in the days of
	8-space indentation.

compiler/optimize.m:
	Implement the new option.

	Use the new field of the c_procedure type to try only the version
	of frameopt appropriate for the code model of the current procedure.

	Do a peephole pass after frameopt, since frameopt can generate code
	sequences that peephole can optimize.

	Make the mechanism for recording the process of optimizing procedure
	bodies more easily usable by including the name of the optimization
	that created a given version of the code in the name of the file
	that contains that version of the code, and ensuring that all numbers
	are two characters long, so that "vi procname*.opt*" looks at the
	relevant files in the proper chronological sequence, instead of having
	version 11 appear before version 2.

compiler/peephole.m:
	Add a new optimization pattern: a "mkframe, goto fail" pair (which
	can be generated by frameopt) should be replaced by a simple "goto
	redo".

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

compiler/llds_out.m:
	Ensure that C comments nested inside comment(_) LLDS instructions
	aren't emitted as nested C comments, since C compilers cannot handle
	these.

compiler/code_info.m:
compiler/code_util.m:
compiler/continuation_info.m:
compiler/dupelim.m:
compiler/exprn_aux.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_out.m:
compiler/mercury_compile.m:
compiler/middle_rec.m:
compiler/ml_code_gen.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/peephole.m:
compiler/stack_layout.m:
compiler/transform_llds.m:
compiler/var_locn.m:
	Conform to the change to prog_data.m, opt_util.m and/or llds.m.

compiler/handle_options.m:
	Don't execute the code in stdlabel.m if doing so would cause a compiler
	abort.

tests/hard_coded/dense_lookup_switch_non.{m,exp}:
	New test case to exercise the new algorithm.

tests/hard_coded/Mmakefile:
	Enable the new test case.

tests/hard_coded/cycles.m:
	Make this test case conform to our coding convention.
2006-04-26 03:06:29 +00:00
Zoltan Somogyi
4fe703c7b9 Implement a more cache-friendly translation of lookup switches.
Estimated hours taken: 8
Branches: main

Implement a more cache-friendly translation of lookup switches. Previously,
for a switch such as the one in

	:- pred p(foo::in, string::out, bar::out, float::out) is semidet.

	p(d, "four", f1, 4.4).
	p(e, "five", f2, 5.5).
	p(f, "six", f4("hex"), 6.6).
	p(g, "seven", f5(77.7), 7.7).

we generated three static cells, one for each argument, and then indexed
into each one in turn to get the values of HeadVar__2, HeadVar__3 and
HeadVar__4. The different static cells each represent a column here.
Each of the loads accessing the columns will access a different cache block,
so with this technique we expect to get as many cache misses as there are
output variables.

This diff changes the code we generate to use a vector of static cells
where each cell represents a row. The assignments to the output variables
will now access the different fields of a row, which will be next to each
other. We thus expect only one cache miss irrespective of the number of output
variables, at least up to the number of variables that actually fit into one
cache block.

compiler/global_data.m:
	Provide a mechanism for creating not just single (scalar) static cells,
	but arrays (vectors) of them.

compiler/lookup_switch.m:
	Use the new mechanism to generate code along the lines described above.

	Put the information passed between the two halves of the lookup switch
	implementation (detection and code generation) into an opaque data
	structure.

compiler/switch_gen.m:
	Conform to the new interface of lookup_switch.m.

compiler/ll_pseudo_type_info.m:
compiler/stack_layout.m:
compiler/string_switch.m:
compiler/unify_gen.m:
compiler/var_locn.m:
	Conform to the change to global_data.m.

compiler/llds.m:
	Define the data structures for holding vectors of static cells. Rename
	the function symbols we used to use to refer to static cells to make
	clear that they apply to scalar cells only. Provide similar mechanisms
	for representing static cell vectors and references to them.

	Generalize heap_ref heap references to allow the index to be computed
	at runtime, not compile time. For symmetry's sake, do likewise
	for stack references.

compiler/llds_out.m:
	Add the code required to write out static cell vectors.

	Rename decl_ids to increase clarity and avoid ambiguity.

compiler/code_util.m:
compiler/exprn_aux.m:
	Modify code that traverses rvals to now also traverse the new rvals
	inside memory references.

compiler/name_mangle.m:
	Provide the prefix for static cell vectors.

compiler/layout_out.m:
compiler/rtti_out.m:
compiler/opt_debug.m:
	Conform to the change to data_addrs and decl_ids.

compiler/code_info.m:
	Provide access to the new functionality in global_data.m, and conform
	to the change to llds.m.

	Provide a utility predicate needed by lookup_switch.m.

compiler/hlds_llds.m:
	Fix the formatting of some comments.

tools/binary:
tools/binary_step:
	Fix the bit rot that has set in since they were last used (the rest
	of the system has changed quite a lot since then). I had to do so
	to debug one part of this change.

tests/hard_coded/dense_lookup_switch2.{m,exp}:
tests/hard_coded/dense_lookup_switch3.{m,exp}:
	New test cases to exercise the new algorithm.

tests/hard_coded/Mmakefile:
	Enable the new test cases, as well as an old one (from 1997!)
	that seems never to have been enabled.
2006-03-30 02:46:08 +00:00
Julien Fischer
459847a064 Move the univ, maybe, pair and unit types from std_util into their own
Estimated hours taken: 18
Branches: main

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

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

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

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

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

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

library/library.m:
	Add the new modules.

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

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

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

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

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

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

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

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

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

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

	There are no algorithmic changes.
2006-03-17 01:40:46 +00:00
Zoltan Somogyi
4d377aba26 Fix a bug reported by Greg Duck. The bug was that the compiler always generated
Estimated hours taken: 5
Branches: main

Fix a bug reported by Greg Duck. The bug was that the compiler always generated
a global variable of type MR_Word for each mutable, but could then assign
variables of other types to and from this global. If this other type is
float, the assignments discard the fractional part. If this other type
is something else, the result can be even worse.

There are two ways to fix this discrepancy. One is to change the type of the
global, and the other is to change the type of the variables it is assigned
to and from. The former looks cleaner, but it would mean that every call
to the get predicate would require a boxing operation, and that can be
relatively slow, since (e.g. for floats) it may require allocating a heap cell.
This diff implements both solutions.

We use the second solution on the LLDS backend because of its better
performance. We have to use the first solution on the MLDS backend,
because on that backend the type of the mutable variable is reflected
in the signature of the getter and setter predicates (whereas on the
LLDS backend all arguments are always MR_Words).

compiler/options.m:
	Add an internal-only option that controls whether we use the first
	solution or the second.

compiler/handle_options.m:
	Make the MLDS backend imply the first solution.

compiler/prog_data.m:
	For each argument of a foreign_proc item, record whether we want to
	keep it boxed in the foreign code.

	Add a foreign_proc attribute that asks for every arg to be kept boxed.
	We can attach this to the mutable implementation foreign_procs we write
	out to .opt files. This attribute is deliberately undocumented since
	users should never use it.

compiler/make_hlds_passes.m:
	For each argument of the get and set foreign_procs we create for
	mutables, record that we do want to keep it boxed.

	Move the action of creating the foreign code for the mutable's
	declaration and definition to the third pass, since during the second
	pass we don't necessarily know yet what its foreign type is (we may not
	have processed a foreign_type declaration affecting it). Move the code
	for creating the foreign code here from prog_mutable, since it depends
	on the HLDS (and prog_mutable.m is in the parse_tree package).

	Hoist some error handling code to put it where it belongs,
	and to avoid some errors being reported twice.

compiler/hlds_goal.m:
	For each argument of a foreign_proc goal, record whether we want to
	keep it boxed in the foreign code.

compiler/llds_out.m:
compiler/pragma_c_gen.m:
compiler/ml_code_gen.m:
compiler/ml_call_gen.m:
	If a foreign_proc argument is noted as being kept boxed in the
	foreign_proc code, then keep it that way.

compiler/prog_io_pragma.m:
	Parse the new foreign_proc annotation.

compiler/simplify.m:
	If a foreign_proc has the always_boxed annotation, attach this info
	to each of its args. We do this here because simplify is guaranteed
	to be executed before all the code that may inspect these arguments.
	Since nothing ever deletes an always_boxed annotation of a foreign_proc
	arg, the code that attaches the annotation is idempotent, so the fact
	that the compiler executes simplify twice is not a problem.

compiler/*.m:
	Minor changes to conform to the changes in data structures above.

compiler/prog_type.m:
	Move a function definition from prog_mutable to prog_type, and
	fix the lack of abstraction in its code.

compiler/prog_mutable.m:
	Delete the code moved to make_hlds_passes.m and prog_type.m.

compiler/notes/compiler_design.html:
	Make the documentation of prog_mutable.m easier to read in source.

tests/hard_coded/float_gv.{m,exp}:
	An extended version of Greg's code as a new test case.

tests/hard_coded/Mmakefile:
	Enable the new test case.

tests/hard_coded/sub-modules/non_word_mutable.{m,exp}:
tests/hard_coded/sub-modules/non_word_mutable.child.m:
	A version of the float_gv test case in which the compiler-generated
	get and set foreign_procs should end up in .opt files.

tests/hard_coded/sub-modules/Mmakefile:
tests/hard_coded/sub-modules/Mercury_options:
	Enable the new test case, and make it execute with intermodule
	optimization.

tests/invalid/bad_mutable.err_exp:
	Expect the new output (in which an error is reported just once,
	not twice).
2006-02-24 01:42:19 +00:00
Julien Fischer
5f589e98fb Various cleanups for the modules in the compiler directory.
Estimated hours taken: 4
Branches: main

Various cleanups for the modules in the compiler directory.  The are
no changes to algorithms except the replacement of some if-then-elses
that would naturally be switches with switches and the replacement of
most of the calls to error/1.

compiler/*.m:
	Convert calls to error/1 to calls to unexpected/2 or sorry/2 as
	appropriate throughout most or the compiler.

	Fix inaccurate assertion failure messages, e.g. identifying the
	assertion failure as taking place in the wrong module.

	Add :- end_module declarations.

	Fix formatting problems and bring the positioning of comments
	into line with our current coding standards.

	Fix some overlong lines.

	Convert some more modules to 4-space indentation.  Fix some spots
	where previous conversions to 4-space indentation have stuffed
	the formatting of the code up.

	Fix a bunch of typos in comments.

	Use state variables in more places; use library predicates
	from the sv* modules where appropriate.

	Delete unnecessary and duplicate module imports.

	Misc. other small cleanups.
2005-11-17 15:57:34 +00:00
Zoltan Somogyi
f9fe8dcf61 Improve the error messages generated for determinism errors involving committed
Estimated hours taken: 8
Branches: main

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

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

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

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

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

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

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

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

compiler/libs.m:
	Include compiler_util.m.

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

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

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

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

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

tests/invalid/det_errors.err_exp:
tests/invalid/magicbox.err_exp:
	Change the expected output to conform to the change in det_report.m,
	which is now more consistent.
2005-10-28 02:11:03 +00:00
Zoltan Somogyi
b2012c0c0e Rename the types 'type', 'inst' and 'mode' to 'mer_type', 'mer_inst'
Estimated hours taken: 8
Branches: main

compiler/*.m:
	Rename the types 'type', 'inst' and 'mode' to 'mer_type', 'mer_inst'
	and 'mer_mode'. This is to avoid the need to parenthesize these type
	names in some contexts, and to prepare for the possibility of a parser
	that considers those words to be reserved words.

	Rename some other uses of those names (e.g. as item types in
	recompilation.m).

	Delete some redundant synonyms (prog_type, mercury_type) for mer_type.

	Change some type names (e.g. mlds__type) and predicate names (e.g.
	deforest__goal) to make them unique even without module qualification.

	Rename the function symbols (e.g. pure, &) that need to be renamed
	to avoid the need to parenthesize them. Make their replacement names
	more expressive.

	Convert some more modules to four space indentation.

	Avoid excessively long lines, such as those resulting from the
	automatic substitution of 'mer_type' for 'type'.
2005-10-24 04:14:34 +00:00
Zoltan Somogyi
d609181cb9 Consider types of the form
Estimated hours taken: 30
Branches: main

Consider types of the form

	:- type x ---> f.

to be dummy types, since they contain no information. Optimize them the same
way we currently optimize io.state and store.store.

runtime/mercury_type_info.h:
	Add a new type_ctor_rep for dummy types.

runtime/mercury_tabling.h:
	Add a representation for "tabled" dummy types, which don't actually
	have a level in the trie, so that the runtime system can handle that
	fact.

runtime/mercury_ml_expand_body.h:
	When deconstructing a value of a dummy type, ignore the actual value
	(since it will contain garbage) and instead return the only possible
	value of the type.

runtime/mercury_construct.c:
runtime/mercury_deconstruct.c:
runtime/mercury_deep_copy_body.c:
runtime/mercury_tabling.c:
runtime/mercury_unify_compare_body.h:
library/rtti_implementation.m:
	Handle the type_ctor_rep of dummy types.

runtime/mercury_builtin_types.c:
	Provide a place to record profiling information about unifications and
	comparisons for dummy types.

runtime/mercury_mcpp.h:
java/runtime/TypeCtorRep.java:
library/private_builtin.m:
	Add a new type_ctor_rep for dummy types, and fix some previous
	discrepancies in type_ctor_reps.

mdbcomp/prim_data.m:
	Move a bunch of predicates for manipulating special_pred_ids here from
	the browser and compiler directories.

	Rename the function symbols of the special_pred_id type to avoid the
	need to parenthesize the old `initialise' function symbol.

	Convert to four-space indentation.

mdbcomp/rtti_access.m:
	Don't hardcode the names of special preds: use the predicates in
	prim_data.m.

	Convert to four-space indentation.

browser/declarative_execution.m:
	Delete some predicates whose functionality is now in
	mdbcomp/prim_data.m.

compiler/hlds_data.m:
	Replace the part of du type that says whether a type an enum, which
	used to be a bool, with something that also says whether the type is a
	dummy type.

	Convert to four-space indentation.

compiler/make_tags.m:
	Compute the value for the new field of du type definitions.

compiler/hlds_out.m:
	Write out the new field of du type definitions.

compiler/rtti.m:
	Modify the data structures we use to create type_ctor_infos to allow
	for dummy types.

	Convert to four-space indentation.

compiler/type_ctor_info.m:
	Modify the code that generates type_ctor_infos to handle dummy types.

compiler/type_util.m:
	Provide predicates for recognizing dummy types.

	Convert to four-space indentation.

compiler/unify_proc.m:
	Generate the unify and compare predicates of dummy types using a new
	code scheme that avoids referencing arguments that contain garbage.

	When generating code for unifying or comparing other types, ignore
	any arguments of function symbols that are dummy types.

	Don't use DCG style access predicates.

compiler/higher_order.m:
	Specialize the unification and comparison of values of dummy types.

	Break up an excessively large predicate, and factor out common code
	from the conditions of a chain of if-then-elses.

compiler/llds.m:
	For each input and output of a foreign_proc, include a field saying
	whether the value is of a dummy type.

compiler/pragma_c_gen.m:
	Fill in the new fields in foreign_proc arguments.

compiler/hlds_goal.m:
	Rename some predicates for constructing unifications to avoid
	unnecessary ad-hoc overloading. Clarify their documentation.

	Rename a predicate to make clear the restriction on its use,
	and document the restriction.

	Add a predicate for creating simple tests.

	Add a utility predicate for setting the context of a goal directly.

compiler/modules.m:
	Include dummy types interface files, even if they are private to the
	module. This is necessary because with the MLDS backend, the generated
	code inside the module and outside the module must agree whether a
	function returning a value of the type returns a real value or a void
	value, and this requires them to agree on whether the type is dummy
	or not.

	The impact on interface files is minimal, since very few types are
	dummy types, and changing a type from a dummy type to a non-dummy type
	or vice versa is an ever rarer change.

compiler/hlds_pred.m:
	Provide a representation in the compiler of the trie step for dummy
	types.

compiler/layout_out.m:
	Print the trie step for dummy types.

compiler/table_gen.m:
	Don't table values of dummy types, and record the fact that we don't
	by including a dummy trie step in the list of trie steps.

compiler/add_pragma.m:
compiler/add_special_pred.m:
compiler/add_type.m:
compiler/aditi_builtin_ops.m:
compiler/bytecode.m:
compiler/bytecode_gen.m:
compiler/code_gen.m:
compiler/code_info.m:
compiler/continuation_info.m:
compiler/cse_detection.m:
compiler/det_report.m:
compiler/exception_analysis.m:
compiler/inst_match.m:
compiler/livemap.m:
compiler/llds_out.m:
compiler/llds_out.m:
compiler/middle_rec.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.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_il.m:
compiler/modecheck_unify.m:
compiler/modes.m:
compiler/opt_util.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/qual_info.m:
compiler/rl.m:
compiler/rl_exprn.m:
compiler/rl_key.m:
compiler/rtti_out.m:
compiler/simplify.m:
compiler/size_prof.m:
compiler/term_constr_initial.m:
compiler/term_constr_util.m:
compiler/term_norm.m:
compiler/termination.m:
compiler/trace.m:
compiler/typecheck.m:
compiler/unify_gen.m:
	Conform to the changes above.

compiler/export.m:
compiler/exprn_aux.m:
compiler/foreign.m:
compiler/polymorphism.m:
compiler/proc_label.m:
compiler/rtti_to_mlds.m:
compiler/special_pred.m:
compiler/stack_alloc.m:
compiler/stack_layout.m:
compiler/state_var.m:
compiler/switch_util.m:
compiler/trace_params.m:
	Conform to the changes above.

	Convert to four-space indentation.

compiler/mlds_to_java.m:
compiler/var_locn.m:
	Conform to the changes above, which requires threading the module_info
	through the module.

	Convert to four-space indentation.

compiler/mercury_compile.m:
	Pass the module_info to mlds_to_java.m.

compiler/ml_util.m:
compiler/polymorphism.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
	Delete some previously missed references to the temporary types used
	to bootstrap the change to the type_info type's arity.

compiler/polymorphism.m:
	Turn back on an optimization that avoids passing parameters (such as
	type_infos) to foreign_procs if they are not actually referred to.

compiler/prog_data.m:
	Convert to four-space indentation.

library/svvarset.m:
	Add a missing predicate.

trace/mercury_trace.c:
	Delete the unused function that used to check for dummy types.

tests/debugger/field_names.{m,inp,exp}:
	Add to this test case a test of the handling of dummy types. Check that
	their values can be printed out during normal execution, and that the
	debugger doesn't consider them live nondummy variables, just as it
	doesn't consider I/O states live nondummy variables.
2005-10-05 06:34:27 +00:00
Zoltan Somogyi
753d9755ae When returning from det and semidet predicates, load the return address into a
Estimated hours taken: 3
Branches: main

When returning from det and semidet predicates, load the return address into a
local C variable instead of the succip abstract machine "register" before
popping the stack frame and returning. This gives the C compiler more freedom
to reorder instructions.

This diff gets a 1.4% speed increase on the compiler.

runtime/mercury_stacks.h:
	Provide a new macro, MR_decr_sp_and_return, to do the combined job that
	its name describes.

compiler/llds.m:
	Add a new LLDS instruction that corresponds to the new macro.

compiler/llds_out.m:
	Output the new LLDS instruction.

compiler/peephole.m:
	Add a predicate that looks for and exploits opportunities for using
	the new instruction.

compiler/optimize.m:
	Invoke the new peephole predicate as the next-to-last optimization
	pass. (The last is wrapping up blocks created by --use-local-vars.)

compiler/*.m:
	Minor changes to handle the new instruction.
2005-09-14 01:29:21 +00:00
Zoltan Somogyi
1ed891b7b1 Introduce a mechanism for extending the det and nondet stacks when needed.
Estimated hours taken: 24
Branches: main

Introduce a mechanism for extending the det and nondet stacks when needed.
The mechanism takes the form of a new grade component, .exts ("extend stacks").

While the new mechanism may be useful in its own right, it is intended mainly
to support a new implementation of minimal model tabling, which will use a
separate Mercury context for each distinct subgoal. Each context has its own
det and nondet stack. Clearly, we can't have hundreds of contexts each with
megabyte sized det stacks. The intention is that the stacks of the subgoals
will start small, and be expanded when needed.

The runtime expansion of stacks doesn't work yet, but it is unnecessarily
hard to debug without an installed compiler that understands the new grade
component, which is why this diff will be committed before that is fixed.

compiler/handle_options.m:
compiler/options.m:
runtime/mercury_grade.h:
scripts/canonical_grade.sh-subr
scripts/init_grade_options.sh-subr
scripts/parse_grade_options.sh-subr
scripts/mgnuc.in
	Handle the new grade component.

runtime/mercury_memory_zones.h:
	Add MR_ prefixes to the names of the fields of the zone structure.

	Record not just the actual size of each zone, which includes various
	kinds of buffers, but also the desired size of the zone exclusive of
	buffers.

	Format the documentation of the zone structure fields more
	comprehensibly.

runtime/mercury_memory_zones.c:
	Instead of implementing memalign if it is not provided by the operating
	system, implement a function that allows us to reallocate the returned
	area of memory.

	Provide a prototype implementation of memory zone extension. It doesn't
	work yet.

	Factor out the code for setting up redzones, since it is now needed
	in more than place.

	Convert to four space indentation.

	Make the debugging functions a bit more flexible.

runtime/mercury_wrapper.c:
	Conform to the improved interface of the debugging functions.

runtime/mercury_overflow.h:
runtime/mercury_std.h:
	Move a generally useful macro from mercury_overflow.h to mercury_std.h.

runtime/mercury_stacks.c:
	Add functions to extend the stacks.

runtime/mercury_stacks.h:
	Add the tests required to invoke the functions that extend the stacks.

	Add the macros needed by the change to compiler/llds.m.

	Convert to four space indentation.

runtime/mercury_conf.h.in:
	Prepare for the use of the posix_memalign function, which is the
	current replacement of the obsolete memalign library function.
	We don't yet use it.

runtime/mercury_context.h:
	Format the documentation of the context structure fields more
	comprehensibly.

	Put MR_ prefixes on the names of the fields of some structures
	that didn't previously have them.

	Conform to the new names of the fields of the zone structure.

runtime/mercury_context.c:
runtime/mercury_debug.c:
runtime/mercury_deep_copy.c:
runtime/mercury_engine.c:
runtime/mercury_memory_handlers.c:
library/benchmarking.m:
library/exception.m:
	Conform to the new names of the fields of the zone structure.

	In some cases, add missing MR_ prefixes to function names
	and/or convert to four space indentation.

runtime/mercury_engine.h:
	Add a new low level debug flag for debugging stack extensions.

	Format the documentation of the engine structure fields more
	comprehensibly.

	Convert to four space indentation.

runtime/mercury_conf_param.h:
	Document a new low level debug flag for debugging stack extensions.

compiler/compile_target_code.m:
compiler/handle_options.m:
compiler/options.m:
	Handle the new grade component.

compiler/llds.m:
	Add two new kinds of LLDS instructions, save_maxfr and restore_maxfr.
	These are needed because the nondet stack may be relocated between
	saving and the restoring of maxfr, and the saved maxfr may point to
	the old stack. In .exts grades, these instructions will save not a
	pointer but the offset of maxfr from the start of the nondet stack,
	since offsets are not affected by the movement of the nondet stack.

compiler/code_info.m:
	Use the new instructions where relevant. (Some more work may be
	needed on this score; the relevant places are marked with XXX.)

compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_out.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/reassign.m:
compiler/use_local_vars.m:
	Handle the new LLDS instructions.

tools/bootcheck:
	Provide a mechanism for setting the initial stack sizes for a
	bootcheck.
2005-09-13 08:25:44 +00:00
Zoltan Somogyi
f0dbbcaa34 Generate better code for base relations such as the ones in the transitive
Estimated hours taken: 16
Branches: main

Generate better code for base relations such as the ones in the transitive
closure benchmarkings in the paper on minimal model tabling. These improvements
yield speedups ranging from 5 to 25% on those benchmarks.

compiler/use_local_vars.m:
	Make this optimization operate on extended basic blocks instead of
	plain basic blocks. The greater length of extended basic blocks
	allows the local variables to have maximum scope possible. The price
	is that the test for whether assignment to a given lvalue can be
	avoided or not is now dependent on which of the constituent basic
	blocks of extended basic block contains the assignment, and thus the
	test has to be evaluate once for each assignment we try to optimize
	instead of once per block.

	Don't allocate temporary variables if the optimization they are
	intended for turns out not to be allowed. This change avoids having
	declarations for unused temporary variables in the resulting C code.

	If --auto-comments is set, insert use_local_vars.m's main data
	structure, the livemap, into the generated LLDS code as a comment.

compiler/peephole.m:
	Look for the pattern

		mkframe(Size, Redoip)
		<straight line instructions that don't use stack slots>
		succeed

	and optimize away the mkframe. This pattern always arises for
	procedures that are actually semidet but are declared nondet (such
	as the base relations in the tabling benchmarks), and may also arise
	for semidet branches of nondet procedures.

compiler/llds.m:
	Allow an existing peephole pattern to work better. The pattern is

		mkframe(Seize, do_fail)
		<straight line instructions>
		redoip(curfr) = Redoip

	Previously, if some compiler-generated C code was among the straight
	line instructions, the pattern couldn't be applied, since peephole.m
	couldn't know whether it branched away through the redoip slot of the
	frame. This diff adds an extra slot to the relevant pragma_c component
	that tells peephole.m (actually, the predicate in opt_util.m that
	peephole relies on) whether this is the case.

compiler/basic_block.m:
	Provide functionality for merging basic blocks into extended basic
	blocks.

compiler/dupelim.m:
	Conform to the change in basic_block.m's interface.

	Convert to four-space indentation, and fix departures from our style
	guidelines.

compiler/opt_util.m:
	Provide extra information now needed by use_local_vars.

	Convert to four-space indentation, and fix departures from our style
	guidelines.

compiler/opt_debug.m:
	Show the user friendly versions of label names when dumping livemaps
	and instructions.

	Shorten the dumped descriptions of registers and stack slots.

	Dump instructions inside blocks.

compiler/frameopt.m:
	Conform to the changes in opt_util and opt_debug's interfaces.

compiler/optimize.m:
	Use the facilities of opt_debug instead of llds_out when dumping the
	LLDS after each optimization, since these are now more compact and
	thus reader friendly.

	Print unmangled names when writing progress messages.

	Put the dump files we generate with --opt-debug in a separate
	subdirectory, since when compiling e.g. tree234.m, the process
	can generate more than a thousand files. Give the dump files
	minimally mangled names.

compiler/code_gen.m:
compiler/pragma_c_gen.m:
	Convert to four-space indentation, and fix departures from our style
	guidelines.

	Conform to the change in llds.m.

compiler/code_info.m:
compiler/exprn_aux.m:
compiler/ite_gen.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_out.m:
compiler/middle_rec.m:
compiler/trace.m:
	Conform to the change in llds.m.
2005-09-07 06:51:57 +00:00
Zoltan Somogyi
5b105a0968 Optimize higher order calls by providing variants of the relevant code that
Estimated hours taken: 6
Branches: main

Optimize higher order calls by providing variants of the relevant code that
are specialized to a given number of explicitly given arguments.

runtime/mercury_ho_call.[ch]:
	Define variants of do_call_closure and do_call_class_method
	specialized to 0, 1, 2 or 3 explicit input arguments. Apart from
	not needing to be passed the number of explicit input arguments
	in a register, these avoid some runtime tests and unroll loops.

	Harmonize the variable names used in the do_call_closure and
	do_call_class_method variants. Since they are near-copies of each
	other, factor out their documentation. (Factoring out the code itself
	would be possible, but would not make maintenance easier and would make
	the code harder to read.)

	Provide a mechanism to gather statistics about the numbers of hidden
	and explicit arguments if the macro MR_DO_CALL_STATS is set.

compiler/options.m:
	Add options that specify how many of these variants exist. These
	provide the necessary synchronization between the runtime and the
	compiler. They are not meant to be set from the command line, even by
	implementors.

runtime/mercury_conf_params.h:
	Document MR_DO_CALL_STATS.

runtime/mercury_wrapper.c:
	If MR_DO_CALL_STATS is set, print the gathered statistics when
	execution ends.

runtime/mecury_mm_own_stack.c:
	Fix a typo that prevented the stage2 library from linking in jump.gc
	grade.

compiler/llds.m:
	Provide a way to represent the labels of the new specialized variants.

compiler/llds__out.m:
	Output the labels of the new specialized variants if required.

	Convert to four-space indentation.

compiler/call_gen.m:
	Call the specialized variants of do_call_closure or
	do_call_class_method if they are applicable.

code_info/follow_vars.m:
code_info/interval.m:
code_info/tupling.m:
	Conform to the change in call_gen.m.

code_info/dupproc.m:
code_info/exprn_aux.m:
code_info/livemap.m:
code_info/opt_util.m:
	Conform to the change in llds.m.

compiler/code_info.m:
	Minor style cleanups.

tools/bootcheck:
	Enable the collection of statistics from the compilation of stage 3
	and the test cases, for use when the stage 2 is built with
	MR_DO_CALL_STATS enabled.

tools/ho_call_stats:
	A new script to analyze the statistics collected.

tools/makebatch:
	Add a new option --save-stage2-on-no-compiler, which is a variant of
	the existing option --save-stage2-on-error.
2005-08-29 15:44:32 +00:00
Zoltan Somogyi
68b1a6c0ea Add a new LLDS optimization we discussed on thursday: elimination of procedures
Estimated hours taken: 4
Branches: main

Add a new LLDS optimization we discussed on thursday: elimination of procedures
whose code is an exact copy of the code of another mode of the same predicate.
This happens with in,out vs di,uo and also possibly with in,out vs any,any.
The new optimization reduces the compiler's code size by 0.6%.

compiler/dupproc.m:
	A new module implementing the new optimization.

compiler/ll_backend.m:
	Add dupproc.m as a new submodule.

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

compiler/options.m:
	Add an option, --optimize-proc-dups, enabling the new optimization.
	Make --opt-space imply the new option.

doc/user_guide.texi:
	Document the new option.

compiler/mercury_compile.m:
	Invoke the new optimization when compiling by predicates.

	Move the imports of library modules to their own section.

compiler/handle_options.m:
	Make --optimize-proc-dups imply compiling by predicates.

The rest of these changes are cosmetic only.

compiler/llds.m:
	Delete an obsolete form of constant we haven't used in a long time.

compiler/exprn_aux.m:
compiler/jumpopt.m:
compiler/llds_out.m:
compiler/opt_debug.m:
compiler/opt_util.m:
	Conform to the change in llds.m.

compiler/dependency_graph.m:
	Clean up some comments.

compiler/dupelim.m:
	Fix some variable names.

compiler/hlds_module.m:
compiler/hlds_pred.m:
	Minor cleanups.
2005-07-08 04:22:13 +00:00