Estimated hours taken: 40
Branches: main
Output Managed C++ code using the same mechanisms as we do for C#
code, rather than using pragma_c_gen to generate MC++ code. This
fixes the problem that functions couldn't be defined in MC++, and also
should make the code more maintainable in the future as MC++ is much
more similar to C# than to C.
compiler/mlds.m:
Add a new field to outline_foreign_proc. This field has
information which links the mlds variables with the variable
names used in the foreign code.
compiler/ml_code_gen.m:
Generate a foreign proc for MC++ the same way we generate a
foreign proc for C#.
Generate the data for the new field in outline_foreign_proc.
Use the context of the string which contains the pragma foreign
proc body for the context of the foreign proc. This ensures that
error messages refer to the correct line number.
compiler/mlds_to_il.m:
Add to the list of foreign languages defined in the module to
include those which don't have a foreign_proc defined in them.
Move the relevant code from atomic_statement_to_il to
generate_method so that we handle external procedures correctly.
compiler/mlds_to_ilasm.m:
Call mlds_to_managed.
compiler/ml_backend.m:
Add the new module and remove mlds_to_mcpp and mlds_to_csharp.
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_java.m:
Minor changes to handling the new field in outline_foreign_proc.
compiler/mlds_to_csharp.m:
compiler/mlds_to_mcpp.m:
Removed files whose functionality has been subsumed by
mlds_to_managed.
library/construct.m:
library/float.m:
library/io.m:
library/std_util.m:
library/type_desc.m:
Changes required to get the library to be able compile in the
ilc grade.
Estimated hours taken: 2
Branches: main
A performance improvement for accurate GC.
compiler/mercury_compile.m:
Fix an XXX comment: invoke tail call optimization before
ml_elim_nested.m. This ensures that the stack setup code for
accurate garbage collection gets put outside the tail-recursive
loop rather than inside the loop.
compiler/ml_optimize.m:
When optimizing tail calls, generate assignments rather than
initializers for the temporary variables. This is needed now
that tail call optimization is done before ml_elim_nested.m.
Also mark those temporary variables as not needing GC.
The main aim of this change is to make the overall, high-level structure
of the compiler clearer, and to encourage better encapsulation of the
major components.
compiler/libs.m:
compiler/backend_libs.m:
compiler/parse_tree.m:
compiler/hlds.m:
compiler/check_hlds.m:
compiler/transform_hlds.m:
compiler/bytecode_backend.m:
compiler/aditi_backend.m:
compiler/ml_backend.m:
compiler/ll_backend.m:
compiler/top_level.m:
New files. One module for each of the major components of the
Mercury compiler. These modules contain (as separate sub-modules)
all the other modules in the Mercury compiler, except gcc.m and
mlds_to_gcc.m.
Mmakefile:
compiler/Mmakefile:
Handle the fact that the top-level module is now `top_level',
not `mercury_compile' (since `mercury_compile' is a sub-module
of `top_level').
compiler/Mmakefile:
Update settings of *FLAGS-<modulename> to use the appropriate
nested module names.
compiler/recompilation_check.m:
compiler/recompilation_version.m:
compiler/recompilation_usage.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/recompilation.version.m:
Convert the `recompilation_*' modules into sub-modules of the
`recompilation' module.
compiler/*.m:
compiler/*.pp:
Module-qualify the module names in `:- module', `:- import_module',
and `:- use_module' declarations.
compiler/base_type_info.m:
compiler/base_type_layout.m:
Deleted these unused empty modules.
compiler/prog_data.m:
compiler/globals.m:
Move the `foreign_language' type from prog_data to globals.
compiler/mlds.m:
compiler/ml_util.m:
compiler/mlds_to_il.m:
Import `globals', for `foreign_language'.
Mmake.common.in:
trace/Mmakefile:
runtime/Mmakefile:
Rename the %.check.c targets as %.check_hdr.c,
to avoid conflicts with compiler/recompilation.check.c.
Estimated hours taken: 0.5
Branches: main
Improve the efficiency of code generated for
`--restore-hp-on-failure' with the MLDS back-end.
compiler/ml_optimize.m:
Convert calls to private_builtin:mark_hp() and
private_builtin:restore_hp() into the MLDS builtin
mark_hp and restore_hp statements, so that they
get generated as inline code.
Estimated hours taken: 24
Branches: main
Generate closure layouts for the MLDS back-end.
compiler/ml_unify_gen.m:
Add code to generate closure layouts.
XXX Note that we still don't fill in the MR_closure_id field yet.
compiler/stack_layout.m:
Export stack_layout__represent_locn_as_int,
for use by ml_unify_gen.m.
compiler/mercury_compile.m:
Invoke the arg_info.m pass for the MLDS back-end, since the
arg_infos are needed by the code in continuation_info.m which
ml_unify_gen.m calls to generate closure layouts.
compiler/ml_elim_nested.m:
compiler/ml_util.m:
compiler/ml_code_util.m:
Fix a bug, exposed by the changes above, which led to some
dangling references. The bug was that it was not hoisting out
local static RTTI data even when this data was referred to by
other static constants were being hoisted, because it was only
checking for references via `var(mlds__var)' lvals, not via
`data_addr_const(data_addr)' rvals. The fix was to change the code
for *_contains_var so that it accepts a data_name rather than
a var_name, and counts references via data_addr_consts,
and to change the code for ml_decl_is_static_const so that
it just checks for `data(_)' rather than `data(var(_))'.
Hoisting RTTI data also required adding code to ml_elim_nested.m
to eliminate duplicate definitions.
compiler/rtti_to_mlds.m:
Mark RTTI definitions as `final'; this is needed to ensure
that they have the same flags (apart from the access) as
ml_static_const_flags, so that ml_decl_is_static_const succeeeds
for these.
compiler/ml_optimize.m:
Update to reflect the interface changes in ml_util.m.
runtime/mercury_deep_copy_body.h:
Delete a call to MR_fatal_error(), since it is no longer needed.
tests/hard_coded/Mmakefile:
Re-enable the copy_pred and copy_pred_2 test cases for the
MLDS back-end, since they now pass.
Estimated hours taken: 2
Branches: main
Implement tail call optimization for the Java back-end.
compiler/mlds.m:
Add support for C-style `break' and `continue' statements:
change the argument of the MLDS `goto' statement from a label
to a new type `goto_target' which is either `break', `continue',
or a label.
compiler/ml_optimize.m:
Add a new predicate `target_supports_break_and_continue',
and for targets where this predicate succeeds, generate tail
recursion using while/break/continue rather than label/goto.
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
Minor changes to handle the new type for the argument of the
`goto' statement.
Estimated hours taken: 10
Branches: main
Add a new MLDS->MLDS optimization option, --eliminate-local-variables.
The aim of this pass is to improve performance in cases where local
variables are costly -- for nondeterministic procedures,
for MLDS->C accurate GC, and for the .NET back-end.
compiler/ml_optimize.m:
Add a pass to eliminate local variables.
Also, don't optimize tail calls unless --optimize-tailcalls is set.
compiler/mercury_compile.m:
Invoke the ml_optimize pass once before ml_elim_nested
(with --optimize-tailcalls disabled), as well as once after it.
compiler/options.m:
doc/user_guide.texi:
Add an option --eliminate-local-variables to enable the new
optimization.
compiler/ml_elim_nested.m:
compiler/ml_util.m:
Move statement_contains_var and definition_contains_var
from ml_elim_nested.m to ml_util.m, for use by ml_optimize.m.
compiler/ml_elim_nested.m:
- Handle local variables with initializers; this is neccessary
now that ml_optimize gets run before ml_elim_nested.
- Don't allocate a stack frame struct and link it into the chain
if there are no local variables that contain pointers.
- In fixup_atomic_statement, handle foreign_proc_code more consistently.
- Add some comments.
Branches: main
Estimated hours taken: 50
Another substantial step towards supporting accurate garbage
collection for the MLDS->C back-end: generate code for the
GC tracing functions.
compiler/mlds.m:
Add new fields to store, with each local variable or argument
declaration, the code for the GC to trace that local variable
or argument.
compiler/ml_code_util.m:
Add a new procedure ml_gen_maybe_gc_trace_code to generate the
code for GC tracing a variable. The generated MLDS code calls
private_builtin:gc_trace/1, passing the variable's address and
the type_info for that variable. This code is generated by
invoking polymorphism__make_type_info_var to generate HLDS code
to build the type_infos needed, and then calling ml_code_gen.m
to convert that to MLDS.
library/private_builtin.m:
Add a new procedure gc_trace, which calls MR_agc_deep_copy().
This gets invoked by the code generated by ml_code_util.m.
compiler/polymorphism.m:
Export polymorphism__make_type_info_var, for use by ml_code_util.m.
compiler/mercury_compile.m:
Invoke the chain_gc_stack_frames pass before invoking the
hoist_nested_functions pass, since otherwise it doesn't work.
compiler/handle_options.m
Add a couple of checks for options that are not supported
in combination with `--gc accurate'.
compiler/ml_call_gen.m:
compiler/ml_code_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_string_switch.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_csharp.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/mlds_to_mcpp.m:
compiler/rtti_to_mlds.m:
Various changes to handle the GC trace code field for variable and
argument declarations.
Estimated hours taken: 2
Branches: main
Merge changes to add attributes to the HLDS, MLDS and ILDS from the
dotnet-foreign branch. We don't merge the changes to add syntax for
attributes, as the syntax is still very experimental.
compiler/hlds_pred.m:
compiler/prog_data.m:
Add attributes to the pred_info (they are a bit like markers,
but are more than just boolean flags).
compiler/ilasm.m:
Add custom attributes to appropriate positions (on assemblies,
IL types and methods).
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_util.m:
compiler/mlds.m:
compiler/mlds_to_c.m:
compiler/mlds_to_csharp.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_java.m:
compiler/mlds_to_mcpp.m:
Add mlds__attributes, which are the MLDS version of custom attributes.
Convert hlds_pred__attributes into mlds__attributes.
Add a list of mlds__attributes to the mlds__function defn.
compiler/mlds_to_il.m:
Convert MLDS attributes to IL custom attributes.
Estimated hours taken: 0.75
Branches: main
Use a new mlds__function_body type to represent function bodies, as the old
usage of maybe/1 was error prone ("no" meant the function had been declared
using :- pragma external, not merely that the body was missing).
compiler/mlds.m:
Add mlds__function_body type.
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_tailcall.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_csharp.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/mlds_to_mcpp.m:
Handle this change.
Estimated hours taken: 40
Branches: main
Refactor the top level of mlds_to_il so that we only do one pass over
the MLDS to generate the ILDS. As a side effect of this change nondet
code now works again.
compiler/mlds_to_il.m:
Do a MLDS to MLDS transformation which places all the procedures and
data into the mercury_code class. Then modify all the qualifiers to
take account of this change to the code.
Rewrite the top level so that it only does one pass over the MLDS
data structure.
Examine the flags when deciding which attributes to place on a
method, field or class.
compiler/mlds.m:
Add a new field to mlds__class_defn which is the list of
defns which are constructors for this class.
Add the functions mlds__append_mercury_code and mlds__append_name
which append either "mercury_code" or an arbitary string to the
module qualifier of a name.
compiler/ml_elim_nested.m:
Rather then hardcoding the generation of the constructor for the
environment class, we generate it here as an MLDS method.
On the IL backend the mercury code is placed in a seperate class to
the environment data, so the env_type decls must be public so as to
be accessible from the code.
compiler/ml_code_util.m:
Wrapper functions should be static methods not instance methods.
Fix ml_gen_label_func_decl_flags to make this true.
compiler/rtti_to_mlds.m:
Rtti data structures should be one_copy (ie static) not per_instance.
compiler/ml_optimize.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_java.m:
Misc changes to handle the additon of a list of constructors to the
mlds__class_defn.
compiler/mlds_to_csharp.m:
compiler/mlds_to_mcpp.m:
Use the function class_name rather then mercury_module_name_to_mlds.
Estimated hours taken: 4
Branches: main
The .NET backend requires that names are not only qualified with their
namespace but the source package the name comes from. In this change we
back out a previous solution to this problem and implement a much
neater solution where we hide the package name in the abstract type
mlds_module_name.
This solution is neater because the package name shouldn't change once
the name is defined. All that we may have to change is the qualifiers
to the name.
compiler/mlds.m:
Add the package name to the abstract type mlds_module_name.
compiler/ml_call_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_csharp.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/mlds_to_mcpp.m:
compiler/rtti_to_mlds.m:
Back out previous solution.
Estimated hours taken: 16
Branches: main
The .NET backend requires that names are not only qualified with their
namespace but the source package the name comes from. In this change we
add to the name type the name of the source package which this name is
defined in. This change will be needed for implementing foreign_class
in the .NET backend where it will no longer be possible to determine
the package name from the fully qualified name.
compiler/mlds.m:
Add the new field to the mlds__fully_qualified_name type.
compiler/ml_call_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_csharp.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/mlds_to_mcpp.m:
compiler/rtti_to_mlds.m:
Propogate the changes around.
Estimated hours taken: 45
Branches: main
Implement a C# interface for the .NET backend.
To use it, you currently need to set
--backend-foreign-language csharp --use-foreign-language csharp
in your MCFLAGS.
The C# foreign language interface works by introducing a new sort of
MLDS statement called outline_foreign_proc. outline_foreign_proc is expected
to be turned into a separate procedure in a separate file. This is
quite different to normal foreign code which has been renamed as inline
target code, as it is really intended to be generated inline, inside the
generated code.
Because outline_foreign_proc is expected to be generated outside the
normal code, we don't need to generate variable renamings,
initializations, casts and other complicated interfacing code.
Any marshalling is done by the backend, which knows how to marshall
arguments across the boundary into the outline code and back. In the
case of marshalling to C# from the .NET backend, we currently don't do
anything special (part of the point of .NET is that data
representation don't have to change very often just because you are
using different languages, so this is a property we should try to
preserve).
The actual implementation of the foreign code is therefore very simple.
Simply generate an appropriate procedure, and insert the user's code in
the middle.
The bulk of this change to delay the mangling of MLDS var names, so we
can still use the original user's var name when we output the outline
procedure (since the user's foreign code will refer to these var names,
it's important to keep them around).
compiler/foreign.m:
Handle the csharp foreign language.
compiler/globals.m:
Fix an XXX about converting to lowercase to do language name
comparisons.
Add new predicates to make conversion of foreign languages
to strings more uniform.
compiler/handle_options.m:
Don't set backend_foreign_language to the default if it has
already been set by hand.
compiler/ml_call_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
Delay the mangling of MLDS var names by keeping the variable
number around until the output phase.
Slightly generalize the handling of foreign language interfacing.
Handle C# foreign language interfacing.
Add value_output_vars to the ml_gen_info, which are the variables
returned rather than passed by reference. We need to know
these variables for C# interfacing so that we can handle the return
value of the forwarding function.
Mark the beginning and end of the MLDS foreign language processing as
a "sub-module" (in comments at least). Later I may put this code
into a separate module.
Rename some predicates from c_code to foreign_code.
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_string_switch.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/rtti_to_mlds.m:
Handle the new var_name type, and the new target_code constructors.
compiler/mlds.m:
Add outline_foreign_proc which is handled differently to the old
target_code (which has been renamed inline_target_code).
Change the definiton for mlds__var_name.
compiler/mlds_to_c.m:
Factor out mlds_output_to_file.
Handle the new var_name type, and the new target_code constructors.
compiler/mlds_to_csharp.m:
A new module to generate C# code suitable for foreign language
interfacing. This is largely lifted from the MC++ code, with a few
changes to the output syntax.
compiler/mlds_to_il.m:
Return the set of foreign languages processed instead of a bool
saying wither MC++ was present. This is so we can generate the
appropriate output .cs or .cpp files, and because we need to keep
track of all the external assembly references we need to put in the
.il file.
Handle the inline_target_code and mlds__var_name changes.
compiler/mlds_to_ilasm.m:
Output .cpp and .cs files conditionally.
Factor out output_to_file.
Move MC++ output code to mlds_to_mcpp.m
compiler/mlds_to_java.m:
Factor out output_to_file.
Handle the new var_name type, and the new target_code constructors.
compiler/mlds_to_mcpp.m:
New file to handle generating MC++ code suitable for foreign language
interfacing.
compiler/options.m:
Add a way of setting the backend-foreign-language option.
compiler/passes_aux.m:
Add output_to_file which is used by the MLDS backend to generate
output files.
compiler/prog_data.m:
Uncomment csharp as a foreign language.
Estimated hours taken: 20
General improvements and bug fixes to the MLDS backend, most
of which were prompted by working on the Java backend.
The definition of mlds__lval now includes type information for
variables. This is necessary because if enumerations are treated
as objects (as in the Java backend) rather than integers we need to know
when to create new objects. At the level this occurs there was
previously no way to distinguish between an integer that is an integer,
and one that represents an enumeration.
Added the access specifier `local' to the declaration flags. This fixes
a bug in which the local variables of a function were being declared
`private'.
Redefined ctor_name so that they are fully qualified. This was necessary
because the Java backend represents discriminated unions as nested
classes and we need to be able to determine the fully qualified name of
the constructor in order to call it, do casts, etc.
Added `mlds__unknown_type' to `mlds__type'. This is due to the change
in the definition of mlds_lval above. In ml_code_util.m, env_ptr's are
created as dangling references. The new definition of mlds__lval expects
there to be a type as well, but at this point it hasn't been
generated (and won't be until the ml_elim_nested pass). Rather than just
guess the type we should declare the type to be unknown and print out an
error message if an unknown type makes it through to one of the backends.
Fixed a bug in the `--det-copy-out' option.
Shifted code for detecting entry point to main/2 from mercury_compile.m
to ml_util.m
compiler/mercury_compile.m:
compiler/ml_util.m:
Shifted code for detecting entry point to main/2 from mercury_compile.m
to ml_util.m
compiler/mlds.m:
Added `local' as an access specifier.
Extended definition of mlds__lval to include type information
for variables.
Added `mlds__unknown_type' to the mlds types so that when
the compiler generates variables without yet knowing their
type we can mark them as this, rather than hoping that the
correct types eventually get added.
Redefined ctor_name so that it is fully qualified.
Made changes to comments to reflect above changes.
compiler/ml_code_gen.m:
Mark the generated functions as `one_copy' rather than `per_instance',
so that they get generated as static methods for the Java back-end.
Fixed a bug with the --det-copy-out option.
compiler/ml_code_util.m:
Fixed a bug that was causing the wrong declaration flags to be
set for fields in du constructors.
Changed the name of the predicate `ml_qualify_var' to
`ml_gen_var_lval'.
compiler/ml_type_gen.m:
Mark the generated types as `one_copy' rather than `per_instance',
so that they get generated as static nested classes for the Java
back-end.
Changed comments to reflect that classes and enumeration constants
should be static.
Export functions that generate declaration flags because they
are used in other modules as well.
Added a new predicate `ml_gen_mlds_field_decl' that correctly
generates fields of classes in discriminated unions.
compiler/ml_unify_gen.m:
Changed the code that generates ctor_id's so that it generates
the new sort.
compiler/ml_call_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_string_switch.m:
compiler/ml_tailcall.m:
compiler/mlds_to_il.m:
compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_ilasm.m:
compiler/rtti_to_mlds.m:
Fixed things so that they conform to the changes above.
Estimated hours taken: 0.25
Address juliensf's review comments on my recent change to add an MLDS
optimization to convert assignments into initializers.
compiler/ml_optimize.m:
doc/user_guide.texi:
Fix some typos.
compiler/options.m:
Wrap some long lines.
Estimated hours taken: 1.5
Add an MLDS optimization to convert assignments into
initializers.
compiler/options.m:
doc/user_guide.texi:
Add new option `--optimize-initializations'.
compiler/ml_optimize.m:
Implement the new optimization.
compiler/ml_elim_nested.m:
compiler/ml_util.m:
Move initializer_contains_var, rval_contains_var and related
predicates from ml_elim_nested.m to ml_util.m, for use by
ml_optimize.m.
Estimated hours taken: 16
Add an MLDS to MLDS transformation that converts MLDS switches
into computed gotos or if-then-else chains. (Eventually we
should make this code also handle binary searches.)
This transformation should allow tag switch optimization to work for
the IL back-end. It also replaces ml_dense_switch.m and lets us
simplify ml_string_switch.m.
compiler/mlds.m:
Add a new `switch_range' field to the `switch' stmt.
compiler/ml_simplify_switch.m:
The new transformation. This converts MLDS switches into
computed gotos or if-then-else chains.
It uses the new `switch_range' field to determine how big
it would need to make the jump table to cover all cases.
compiler/ml_switch_gen.m:
compiler/ml_string_switch.m:
compiler/ml_tag_switch.m:
compiler/ml_dense_switch.m:
Generate the new field.
Change the places that generate switches so that after
generating the switch they invoke the new transformation.
Delete ml_dense_switch.m, since it is now redundant,
and significantly simplify ml_string_switch.m.
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_tailcall.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_il.m:
Trivial changes to handle the new field.
compiler/switch_util.m:
compiler/dense_switch.m:
Move most of the code from the `type_range' procedure from
dense_switch.m to switch_util.m, so we can use it in
ml_switch_gen.m for computing the switch range.
Estimated hours taken: 8
Get the MLDS back-end to generate better code for switches.
It now compiles Mercury switches on int/char/enums into C switches.
compiler/mlds.m:
Add `switch' as a new alternative in the `mlds__stmt' type.
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_tailcall.m:
compiler/ml_util.m:
Minor changes to handle the new `switch' statement.
compiler/ml_code_gen.m:
Move the code for handling switches to ml_switch_gen.m.
Export `ml_gen_goal', for use in ml_switch_gen.m.
compiler/ml_switch_gen.m:
compiler/ml_dense_switch.m:
New files, adapted from switch_gen.m and dense_switch.m, but
with significant changes. These now handle three forms of switch:
- dense switches, implemented as computed gotos;
- "direct mapped" switches, which get implemented using the
MLDS switch statement, which in turn gets mapped to the
target language's switch statement;
- if-then-else chains
compiler/ml_code_util.m:
Add a label counter to the ml_gen_info, and define predicates
for allocating new labels.
compiler/mlds_to_c.m:
Output switch statements. Also fix a layout bug in the output:
make sure we output newlines at the end of comments.
compiler/mlds_to_il.m:
Call error/1 for MLDS switch statements. The code generator
will generate MLDS computed_gotos (which map to IL `switch'
instructions) rather than MLDS switch statements, so we should
never get MLDS switch statements here.
compiler/options.m:
Add a new option `--prefer-switch', defaulting to enabled,
which says to generate switches rather than computed gotos
where possible.
Estimated hours taken: 0.5
Various fixes for problems fjh pointed out in a review.
compiler/ml_code_util.m:
Fix a typo.
compiler/ml_optimize.m:
compiler/mlds_to_c.m:
Move some comments from mlds_output_assign_args to
generate_assign_args.
Remove mlds_output_assign_args as it is now dead code.
compiler/options.m:
Fix a typo, llds-optimize should be mlds-optimize.
doc/user_guide.texi:
Document --no-mlds-optimize.
Estimated hours taken: 5
Do the transformation of self-tailcalls into loops as an MLDS->MLDS
transformation (instead of during mlds_to_c.m). Both the IL and C
backends for MLDS use this transformation.
Also, we transform into label/goto instead of for/continue. This is
because IL doesn't have a for/continue construct. It may be worth
revisiting this decision in future and performing benchmarks.
compiler/mercury_compile.m:
Add an optimization phase to the MLDS end of the compiler.
compiler/ml_optimize.m:
New file that performs MLDS->MLDS optimizations such as turning
self-tail calls into loops.
compiler/ml_tailcall.m:
Use ml_util.
compiler/ml_util.m:
New file containing generic MLDS utilities.
Contents are can_optimize_tailcall and statements_contain_statements.
This code was in mlds_to_c but will be used by more than just
this backend.
compiler/mlds_to_c.m:
Delete old tailcall transformation code (it is either moved into
ml_optimize, ml_util or it is no longer needed).
Only handle general tailcalls.