mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-13 12:53:53 +00:00
4ee7e744b715b7adf665a267de3814131839a617
106 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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.
|
||
|
|
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.
|
||
|
|
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.
|
||
|
|
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.
|
||
|
|
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.
|
||
|
|
f2b877500c | Delete some unused predicates. | ||
|
|
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. |
||
|
|
ae612d2a4a |
compiler/exprn_aux.m:
Delete a redundant comment. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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.
|
||
|
|
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.
|
||
|
|
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. |
||
|
|
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. |
||
|
|
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.
|
||
|
|
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. |
||
|
|
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.
|
||
|
|
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. |
||
|
|
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. |
||
|
|
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.
|
||
|
|
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. |
||
|
|
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.
|
||
|
|
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. |
||
|
|
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? |
||
|
|
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. |
||
|
|
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.) |
||
|
|
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. |
||
|
|
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. |
||
|
|
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.) |
||
|
|
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. |
||
|
|
aeeedd2c13 |
Standardize formatting of comments at the beginning of modules.
compiler/*.m: Standardize formatting of comments at the beginning of modules. |
||
|
|
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. |
||
|
|
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.
|
||
|
|
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.
|
||
|
|
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.
|
||
|
|
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. |
||
|
|
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. |
||
|
|
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).
|
||
|
|
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. |
||
|
|
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.
|
||
|
|
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'. |
||
|
|
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.
|
||
|
|
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. |
||
|
|
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.
|
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |