mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-22 04:43:53 +00:00
083d376e6598628362ee91c2da170febd83590f4
164 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6b28bef45a | Rename a predicate to avoid ambiguity. | ||
|
|
f7442dbb1a |
Change some "arity"s to "pred_form_arity"s.
compiler/hlds_rtti.m:
compiler/mlds.m:
As above.
compiler/add_pragma_tabling.m:
compiler/ml_accurate_gc.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_util.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_class.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_c_func.m:
compiler/mlds_to_c_name.m:
compiler/mlds_to_c_stmt.m:
compiler/mlds_to_cs_name.m:
compiler/mlds_to_java_name.m:
compiler/proc_label.m:
compiler/rtti_to_mlds.m:
Conform to the changes above.
Simplify some code that does output.
Delete some no-longer-relevant comments.
|
||
|
|
07f877bc3f |
Carve term_context.m out of term.m.
library/term.m:
library/term_context.m:
As above.
Rename the term.context type as term_context.term_context, with
term.context now being defined as an equivalence type.
Replace the context_init function and predicate and the dummy_context_init
function with just one function: dummy_context. This name includes
the important part (the fact that it return a *dummy* context) and deletes
the nonimportant part (dummy contexts are just about never updated,
so the function does not really "initialize" them).
Reduce function/predicate pairs that do the same thing to just a function.
library/MODULES_DOC:
library/library.m:
Add the new module to the list of standard library modules.
NEWS:
Mention the new module, and the obsoleting of the moved predicates
and functions in term.m.
compiler/*.m:
library/*.m:
Conform to the changes above.
|
||
|
|
ea4f95a7ed |
Use var_tables in lco.m, and when dumping goals.
Since this is the first converted module that dumps out goals when
debugging trace flags are enabled, this required generalizing the code
that does that, to take either varsets or var_tables as a means of
specifying the names of variables. We do this via a new type,
var_name_source, which contains either a varset or a var_table.
Almost all of this diff is there to implement this generalization.
A large part of it affects code in the parse_tree package that we use
to write out the parts of HLDS goals that are defined by types defined
in that package. Since we want to avoid making any part of the parse_tree
package dependent on the hlds package, this required defining the
var_name_source type in the parse_tree package, which in turn requires
var_table.m to be in that same package.
compiler/lco.m:
Convert this module to use var_tables instead of varsets and vartypes.
compiler/var_table.m:
Move this module from the hlds package to the parse_tree package.
To make this, possible, move the parts that required access to the HLDS
to hlds_pred.m, from where it was usually invoked.
Export some utility predicates to allow the moved code to work
in hlds_pred.m without access to the actual definition of the
var_table type.
Define the var_name_source type.
Add some utility functions for use by code writing out variable names.
compiler/hlds_pred.m:
Add the code moved from var_table.m.
compiler/vartypes.m:
Move this module from the hlds package to the parse_tree package,
for symmetry with var_table.m. It did not depend on being in hlds
in any way.
compiler/hlds.m:
compiler/parse_tree.m:
Move vartypes.m and var_table.m from the hlds package
to the parse_tree package.
compiler/hlds_out_goal.m:
Change all the predicates in this module to take a var_name_source
instead of a prog_varset.
Fix some comments.
compiler/hlds_out_util.m:
Change some of the predicates in this module (those called from
hlds_out_goal.m) to take a var_name_source instead of a prog_varset.
compiler/parse_tree_out_term.m:
Provide variants of some existing predicates and functions that take
var_name_sources instead of varsets. The code of the copies
duplicates the logic of the originals, though I hope that this
duplication can be done away with at the end of the transition.
(The best solution would be to use a typeclass with methods
that convert vars to their names, but we would want to ensure
that the compiler can specialize all the affected predicates
and functions to the two instances of this typeclass, which is
something that we cannot do yet. In the meantime, the lack of
any generalization in the old versions preserves their performance.)
tools/sort_imports:
tools/filter_sort_imports:
A new tool that automatically sorts any occurrences of consecutive
":- import_module" declarations in the named files. The sorting is done
in filter_sort_imports; sort_imports loops over the named files.
After automatically replacing all occurrences of hlds.{vartypes,var_table}
in import_module declarations with their parse_tree versions, the updated
import_module declarations were usually out of order with respect to
their neighbours. I used this script to fix that, and some earlier
out-of-order imports.
compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_heap_ops.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_trail_ops.m:
compiler/analysis.m:
compiler/arg_info.m:
compiler/build_mode_constraints.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/check_promise.m:
compiler/closure_analysis.m:
compiler/closure_gen.m:
compiler/code_info.m:
compiler/code_loc_dep.m:
compiler/common.m:
compiler/compile_target_code.m:
compiler/complexity.m:
compiler/const_prop.m:
compiler/constraint.m:
compiler/continuation_info.m:
compiler/convert_parse_tree.m:
compiler/coverage_profiling.m:
compiler/cse_detection.m:
compiler/ctgc.datastruct.m:
compiler/ctgc.util.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
compiler/direct_arg_in_out.m:
compiler/disj_gen.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/exception_analysis.m:
compiler/file_names.m:
compiler/float_regs.m:
compiler/follow_vars.m:
compiler/format_call.m:
compiler/generate_dep_d_files.m:
compiler/get_dependencies.m:
compiler/goal_expr_to_goal.m:
compiler/goal_mode.m:
compiler/goal_path.m:
compiler/goal_store.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_clauses.m:
compiler/hlds_code_util.m:
compiler/hlds_error_util.m:
compiler/hlds_goal.m:
compiler/hlds_llds.m:
compiler/hlds_out_pred.m:
compiler/hlds_rtti.m:
compiler/hlds_statistics.m:
compiler/inlining.m:
compiler/inst_check.m:
compiler/inst_test.m:
compiler/inst_user.m:
compiler/instance_method_clauses.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/intermod_analysis.m:
compiler/interval.m:
compiler/introduce_exists_casts.m:
compiler/introduce_parallelism.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/llds.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_util.m:
compiler/lookup_switch.m:
compiler/loop_inv.m:
compiler/make.module_target.m:
compiler/make.util.m:
compiler/make_goal.m:
compiler/make_hlds_separate_items.m:
compiler/make_hlds_types.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/middle_rec.m:
compiler/ml_accurate_gc.m:
compiler/ml_args_util.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_proc_gen.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_unify_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_func.m:
compiler/mlds_to_c_global.m:
compiler/mlds_to_cs_class.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_data.m:
compiler/mlds_to_java_file.m:
compiler/mlds_to_java_stmt.m:
compiler/mlds_to_java_type.m:
compiler/mmc_analysis.m:
compiler/mode_comparison.m:
compiler/mode_constraints.m:
compiler/mode_debug.m:
compiler/mode_errors.m:
compiler/mode_info.m:
compiler/mode_ordering.m:
compiler/modecheck_call.m:
compiler/modecheck_coerce.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/module_cmds.m:
compiler/old_type_constraints.m:
compiler/opt_debug.m:
compiler/optimize.m:
compiler/options_file.m:
compiler/ordering_mode_constraints.m:
compiler/par_loop_control.m:
compiler/parse_item.m:
compiler/parse_string_format.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_to_term.m:
compiler/parse_util.m:
compiler/pd_debug.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/peephole.m:
compiler/polymorphism.m:
compiler/polymorphism_info.m:
compiler/polymorphism_lambda.m:
compiler/polymorphism_type_class_info.m:
compiler/polymorphism_type_info.m:
compiler/post_typecheck.m:
compiler/pragma_c_gen.m:
compiler/pred_name.m:
compiler/pred_table.m:
compiler/prog_item.m:
compiler/prog_rep.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/push_goals_together.m:
compiler/qual_info.m:
compiler/quantification.m:
compiler/rbmm.execution_path.m:
compiler/rbmm.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.points_to_graph.m:
compiler/rbmm.points_to_info.m:
compiler/rbmm.region_resurrection_renaming.m:
compiler/rbmm.region_transformation.m:
compiler/recompilation.used_file.m:
compiler/recompilation.version.m:
compiler/recompute_instmap_deltas.m:
compiler/resolve_unify_functor.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/saved_vars.m:
compiler/set_of_var.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_conj.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_goal_scope.m:
compiler/simplify_goal_switch.m:
compiler/simplify_goal_unify.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/smm_common.m:
compiler/ssdebug.m:
compiler/stack_alloc.m:
compiler/stack_layout.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/store_alloc.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_data.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/term_constr_main_types.m:
compiler/term_constr_util.m:
compiler/term_pass1.m:
compiler/term_traversal.m:
compiler/term_util.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/transform_llds.m:
compiler/try_expand.m:
compiler/tupling.m:
compiler/type_assign.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/typecheck_debug.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unify_gen_construct.m:
compiler/unify_gen_deconstruct.m:
compiler/unify_proc.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/var_locn.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
Conform to the changes above.
|
||
|
|
0d7c8a7654 |
Specify pred or func for all pragmas.
*/*.m:
As above.
configure.ac:
Require the installed compiler to support this capability.
|
||
|
|
e2b5ba8884 |
Make subtypes share high-level data representation with base type.
In the high-level data representation, make a subtype term be
represented using the class corresponding to the base type constructor
instead of its own class. This is necessary to be able to downcast
a term from a type to a subtype in Java and C#.
compiler/du_type_layout.m:
Move get_base_type_ctor predicate to type_util.m.
Abort in a couple of places that should not occur.
compiler/type_util.m:
Add get_base_type_ctor predicate.
compiler/globals.m:
Add compilation_target_high_level_data predicate.
compiler/lco.m:
Use compilation_target_high_level_data predicate.
compiler/ml_type_gen.m:
When using the high-level data representation,
don't generate a MLDS type definition (class) for a subtype.
compiler/mlds.m:
When using the high-level data representation,
replace a Mercury subtype with its base type in an mlds_type.
Move foreign_type_to_mlds_type.
compiler/ml_unify_gen_util.m:
To access a field when using the high-level data representation,
use field names from the base type constructor of a subtype.
compiler/unify_proc.m:
When using the high-level data representation,
generate unify/compare procs for subtypes that just call the
unify/compare proc for the base type constructor.
compiler/options.m:
Delete references to --high-level and --high-level-data.
---------------
runtime/mercury_type_info.h:
Document a new field MR_type_ctor_base in MR_TypeCtorInfo_Struct.
The field is unnecessary and does not exist in the
MR_TypeCtorInfo_Struct for C.
runtime/mercury_dotnet.cs.in:
Add type_ctor_base member to MR_TypeCtorInfo_Struct for C#.
java/runtime/TypeCtorInfo_Struct.java
Add type_ctor_base member to MR_TypeCtorInfo_Struct for Java.
compiler/rtti.m:
compiler/type_ctor_info.m:
Add field corresponding to MR_type_ctor_base in type_ctor_details
for enum, notag and general du types.
compiler/rtti_to_mlds.m:
Initialize the MR_type_ctor_base field in type_ctor_infos
for high-level data grades.
compiler/rtti_out.m:
Don't write out the MR_type_ctor_base field when using
the low-level data representation.
library/rtti_implementation.m:
In Java and C# grades (high-level data grades), use the
MR_type_ctor_base field to get the type_ctor_info of the base type
ctor when constructing or deconstructing terms of a subtype.
It is necessary to perform reflection using class and field names
from the base type constructor since there are no classes
corresponding to subtypes.
Clean up some code.
---------------
tests/hard_coded/Mmakefile:
tests/hard_coded/subtype_abstract.m:
tests/hard_coded/subtype_abstract_2.m:
tests/hard_coded/subtype_abstract.exp:
Add a test case.
tests/hard_coded/subtype_rtti.m:
tests/hard_coded/subtype_rtti.exp2:
Enable a test that was previously skipped in Java and C# grades.
|
||
|
|
6a345ff5dc |
Make subtypes share low-level data representation with base type.
Make subtypes share data representation with base type when using
low-level data. High-level data grades are unchanged, so subtypes
are still represented with distinct classes from their base types.
----------------
compiler/prog_data.m:
Add abstract_subtype option for type_details_abstract.
Correct XXX comment.
compiler/prog_item.m:
Add type item_type_repn_info_subtype.
Add tcrepn_is_subtype_of option for type_ctor_repn_info.
compiler/equiv_type.m:
Replace equivalences in tcrepn_is_subtype_of.
compiler/module_qual.qualify_items.m:
Module qualify in tcrepn_is_subtype_of.
compiler/prog_type.m:
Rename some predicates that can only work on non-subtype du types.
Update comments.
compiler/check_parse_tree_type_defns.m:
Classify subtype type definitions as std_mer_type_du_subtype
instead of std_mer_type_du_all_plain_constants or
std_mer_type_du_not_all_plain_constants.
Update some comments.
compiler/du_type_layout.m:
Add two sub-passes to handle subtypes.
compiler/comp_unit_interface.m:
Extend this module to handle subtype type definitions,
analogous to the way equivalence type definitions are handled.
Rename some predicates to clarify that they must not be used
to test subtypes.
Record an abstract version of a subtype type definition using
the abstract_subtype option in type_details_abstract.
This allows the super type ctor of the subtype to be known,
and hence the base type ctor, when a subtype is abstract exported.
Update comments.
compiler/decide_type_repn.m:
Extend this module to handle subtype type definitions.
Generate type_representation items for subtype type definitions
which include the super type ctor of the subtype.
compiler/parse_tree_out.m:
Write out abstract_subtype as
"where type_is_abstract_subtype(Name/Arity)" on type definitions.
compiler/parse_type_defn.m:
Parse "type_is_abstract_subtype(Name/Arity)" declarations.
compiler/parse_tree_out_type_repn.m:
Write type_representation items with "is_subtype_of(TypeCtor/Arity)".
compiler/parse_type_repn.m:
Parse "is_subtype_of(TypeCtor/Arity)" in type_representation items.
compiler/add_type.m:
compiler/convert_parse_tree.m:
compiler/opt_debug.m:
compiler/type_util.m:
Conform to changes.
Update comments.
compiler/direct_arg_in_out.m:
Delete XXX, nothing to do.
compiler/parse_util.m:
Rename overly specific variable.
----------------
runtime/mercury_type_info.h:
Add a flag in MR_TypeCtorInfo to indicate if the enum/du layout
array may be indexed by an enum value or du ptag value.
Subtypes break the invariant that the layout array contains entries
for every enum/ptag value from 0 up to the maximum value.
The presence of the flag MR_TYPE_CTOR_FLAG_LAYOUT_INDEXABLE tells
the runtime that it can directly index the layout array instead of
searching through it (which is the common case, for non-subtypes).
Add a field MR_du_ptag to MR_DuPtagLayout. This is necessary to find
an entry for a given primary tag value in a MR_DuPtagLayout array.
Add a field MR_du_ptag_flags to MR_DuPtagLayout, currently with one
possible flag MR_DU_PTAG_FLAG_SECTAG_ALTERNATIVES_INDEXABLE.
As with primary tags, subtypes break the invariant that the
sectag_alternatives array contains entries for every secondary tag
value from 0 up to the maximum value. The presence of the flag tells
the runtime that it can directly index the sectag_alternatives array
(which is the common case, for non-subtypes).
The two fields added to MR_DuPtagLayout occupy space that was
previously padding, so the size of MR_DuPtagLayout is unchanged.
In MR_EnumFunctorDesc, replace the MR_enum_functor_ordinal field by
MR_enum_functor_value, i.e. the integer value representing the
functor in memory. Storing *both* the functor ordinal and enum value
would increase the size of the MR_EnumFunctorDesc struct, and would
be redundant in the common case of non-subtype enums (both fields
would contain equal values). We forgo having the functor ordinal
directly available, at the cost of needing to search through an
MR_EnumFunctorDesc array when a functor ordinal is required for a
subtype enum, which should be rare.
compiler/rtti.m:
Swap enum "functor ordinal" and "value" in places.
Use a type 'enum_value' to try to ensure we do not mix up enum
functor ordinals and enum values.
Add code to encode the MR_TYPE_CTOR_FLAG_LAYOUT_INDEXABLE flag.
Add code to encode the MR_DU_PTAG_FLAG_SECTAG_ALTERNATIVES_INDEXABLE
flag.
compiler/rtti_out.m:
Write out "enum_ordinal_ordered_tables" ordered by functor ordinals
instead of "enum_value_ordered_tables" ordered by enum values.
Output the enum value for MR_EnumFunctorDesc instead of functor
ordinal.
Output the MR_du_ptag and MR_du_ptag_flags fields for
MR_DuPtagLayout.
Relax sanity check on primary tags. A subtype may not necessarily
use ptag 0, and may skip ptag values.
compiler/rtti_to_mlds.m:
Generate "enum_ordinal_ordered_tables" instead of
"enum_value_ordered_tables".
Fill in the enum value for a MR_EnumFunctorDesc instead of
the functor ordinal.
compiler/type_ctor_info.m:
Add predicate to generate the MR_du_ptag_flags field.
Add the MR_TYPE_CTOR_FLAG_LAYOUT_INDEXABLE flag to type_ctor_infos
when appropriate.
Bump the type_ctor_info_rtti_version.
----------------
runtime/mercury_ml_expand_body.h:
Search through an enum layout array to find the matching enum value,
unless the array can be indexed.
Search through a ptag layout array to find the matching ptag value,
unless the array can be indexed.
Search through a sectag_alternatives array to find the matching
secondary tag value, unless the array can be indexed.
Factor out the code to search through a foreign enum layout array
into a separate macro.
runtime/mercury_construct.c:
runtime/mercury_construct.h:
Add a functor_ordinal field to the MR_Construct_Info_Struct.
This will hold the functor ordinal now that it is not available in
MR_EnumFunctorDesc.
Make MR_get_functors_check_range take an argument to indicate if the
functor_ordinal field needs to be filled in properly. Most callers
do not need the field.
library/construct.m:
Conform to changes to MR_get_functors_check_range and
MR_EnumFunctorDesc.
-------------------
runtime/mercury_dotnet.cs.in:
Modify RTTI classes for C# backend, analogous to the changes for the
C runtime.
Add methods to index/search through enum layout arrays, ptag layout
arrays, and sectag_alternatives arrays.
java/runtime/DuPtagLayout.java:
java/runtime/EnumFunctorDesc.java:
java/runtime/TypeCtorInfo_Struct.java:
Modify RTTI classes for Java backend, analogous to the changes for the
C runtime.
Add methods to index/search through enum layout arrays, ptag layout
arrays, and sectag_alternatives arrays.
library/rtti_implementation.m:
Conform to MR_EnumFunctorDesc field change.
Index or search through the enum layout array or ptag layout array
based on the MR_TYPE_CTOR_FLAG_LAYOUT_INDEXABLE flag.
Index or search through the sectag_alternatives array depending on
the MR_DU_PTAG_FLAG_SECTAG_ALTERNATIVES_INDEXABLE flag.
Add separator lines.
Slightly reorder some code.
----------------
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/subtype_pack.m:
tests/hard_coded/subtype_pack_2.m:
tests/hard_coded/subtype_pack.exp:
tests/hard_coded/subtype_rtti.m:
tests/hard_coded/subtype_rtti.exp:
tests/hard_coded/subtype_rtti.exp2:
Add test cases.
|
||
|
|
9cbe5d2caf |
Put type_repn items for complex types into .int files.
compiler/decide_type_repn.m:
Previously, this module computed type_repn items to put into .int3 files
for a subset of the type constructors defined in the current module:
the direct_dummy, enum and notag types (the *simple* types),
and the du types whose representation is guaranteed to be
a word-aligned pointer when targeting C. (We care about pointers
being word-aligned only when applying the direct arg optimization.
This optimization is applicable only with the low level data
representation, which we use only when targeting C.)
This diff adds code to decide the representations of *all* the
type constructors defined in the current module.
This code is based on the existing code in du_type_layout.m,
which it is intended to eventually replace, but its job is more general,
because it decides the representation of each type not just for
one platform (the one we want to generate code), but for all possible
platforms. This is because we want to put the descriptions of type
representations into the module's .int file to serve as a single source
of truth for all modules that use the types defined in this module,
and the contents of .int files should be platform-independent.
For our purposes, there are six kinds of platforms, which are
distinguished along three axes: 64 vs 32 bit machines, spf vs non-spf
grades, and direct arg optimization enabled vs disabled. That is eight
combinations, but on 64 bit machines, a float takes up one word whether
that float is single or double precision, so two combinations aren't valid.
Some of the change to this module consists of generalizing the existing
code so that it can decide simple types not just when targeting .int3 files
but .int files as well. However, the bulk of it is code for deciding
the representations of non-simple types. The code is not lifted straight
from du_type_layout.m. There are two main kinds of changes.
First, I took the opportunity to simplify the algorithms used.
For example, while du_type_layout.m passes over each function symbol
in the most general kind of type twice: once to assign it a cons_tag,
and once to decide how to pack its arguments, the code here does both jobs
in one pass. Another example is that for historical reasons,
du_type_layout.m computed the amount of space needed for an argument
in one place for sub-word-sized arguments, and in another place
for more-than-word-sized arguments; decide_type_repn.m does it all
in one place.
Second, since we compute a representation for each type six times,
I tried to avoid obvious inefficiencies, but only if the code
remained simple. In the future, we may want to use an approach
based on the idea that in the process of computing the first
representation, we look out for any indication that the representation
may be different on any of the other five platforms, and if not,
we just reuse the first representation on the other five platforms as well.
However, that would be appropriate only *after* we have a simpler
system that has proven to work in practice.
There is a third, smaller change: when deciding whether an argument
is packable, we take into account not just equivalence type
definitions, but the definitions of notag types as well.
This takes advantage of the fact that if a notag type is abstract
exported, its representation is put into the relevant .int3 file
even though its definition isn't. (This is why du_type_layout.m
couldn't "see through" notag types: it couldn't depend on knowing
which types were notags.)
compiler/prog_item.m:
Change the types we use for type representation information.
Their previous definitions baked in the assumption that the only
distinction between platforms that mattered was the 64 vs 32 bit
distinction, which is not the case.
Use a more consistent naming scheme for the types we use
to represent type representation information.
Include the "dereferenced" types of the arguments in functors'
representations. (I use "dereferencing" here to mean expanding
equivalence types and throwing away any notag wrappers.).
We don't need it when generating C code using the low level
data representation, but we do need it to create constructors
when generating e.g. Java code that uses the high level data
representation.
compiler/parse_type_repn.m:
Rewrite most of this module due to the changes in prog_item.m.
compiler/parse_tree_out_type_repn.m:
A new module containing the code for writing out type representations.
The original code used to be in parse_tree_out.m, but it has been
mostly rewritten. Partly this is due the changes in prog_item.m,
but partly it is to provide much more structured output for humans,
since this makes debugging so much easier.
compiler/parse_tree.m:
Add the new module to the parse_tree package.
compiler/parse_tree_out.m:
Delete the code moved to parse_tree_out_type_repn.m.
compiler/parse_tree_out_info.m:
Provide a mechanism for selecting between output for machines
(the default) and output for humans.
compiler/hlds_data.m:
compiler/prog_data.m:
Move the ptag type from hlds_data.m to prog_data.m, to make it
accessible in prog_item.m.
Add some documentation in prog_data.m.
compiler/comp_unit_interface.m:
If the experiment1 option is enabled, invoke decide_type_repn.m
to decide what type_repn items to put into the .int file we are
generating. Otherwise, maintain the status quo.
compiler/write_module_interface_files.m:
Pass the globals to comp_unit_interface.m so it can look up experiment1.
compiler/equiv_type.m:
Add a predicate for expanding equivalence types for use by
decide_type_repn.m. This predicate expands just one type,
but reports any use of circular equivalence types in that type.
Improve the error message for circular equivalence types by *naming*
the type constructors involved. To make this possible, pass around
sets of such type constructors instead of just a boolean saying
*whether* we have found *some* circular equivalence type.
Replace bools used as changed/unchanged flag with a bespoke type.
Standardize some variable names.
compiler/options.m:
Add the developer-only option --pack-everything, which, if set,
tells decide_type_repn.m to turn on all the packing options
that currently work. This is to allow the testing of decide_type_repn.m
in the eventual intended mode of operation, even if the various
allow-packing-... options used by du_type_layout.m are set to "no".
compiler/disj_gen.m:
compiler/equiv_type_hlds.m:
compiler/llds_out_data.m:
compiler/lookup_util.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/mlds_to_c_data.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/tag_switch.m:
Conform to the changes above (mostly the move of ptag to prog_data.m.)
compiler/parse_pragma.m:
Improve indentation.
tests/valid_make_int/test_repn.m:
tests/valid_make_int/test_repn_sub.m:
A fairly comprehensive test case of the new functionality.
test_repn_sub.m defines one ore more simple type constructors
of each possible kind, and test_repn.m uses them to define types
that use each possible kind of complex type representation.
tests/valid_make_int/Mmakefile:
tests/valid_make_int/Mercury.options:
Enable the new test case.
|
||
|
|
c1bdd2100b | Delete unneeded $module args from aborts. | ||
|
|
5f7d3e6bb2 |
Use consistent integer types for some RTTI fields.
runtime/mercury_type_info.h:
Use unsigned integer types for a few RTTI structure fields that
are known to hold non-negative values.
Add comments for other field types that could be changed later.
compiler/rtti.m:
Use fixed size integer types for fields matching the size
and signedness of the corresponding C RTTI structure fields.
Encode type ctor flags in a uint16 instead of int.
Make type_ctor_details_num_ptags and type_ctor_details_num_functors
return a maybe value, instead of a negative value to represent no
primary tags or no function symbols, respectively.
compiler/type_ctor_info.m:
Conform to type changes.
Use uint16 to represent the "contains var" bit vector.
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
Conform to type changes.
Add comments to make it easier to find the code that writes out
each particular RTTI structure field.
compiler/ml_util.m:
Add helper functions.
compiler/add_special_pred.m:
compiler/du_type_layout.m:
compiler/erl_rtti.m:
compiler/erlang_rtti.m:
compiler/hlds_data.m:
compiler/llds_out_data.m:
compiler/ml_unify_gen_construct.m:
compiler/opt_debug.m:
compiler/pseudo_type_info.m:
compiler/stack_layout.m:
compiler/unify_gen_construct.m:
Conform to type changes.
compiler/parse_type_defn.m:
compiler/prog_data.m:
Use uint32 for functor ordinal numbers.
library/rtti_implementation.m:
Use fixed size integer types for RTTI field accessor functions,
and update callers.
java/runtime/DuArgLocn.java:
java/runtime/DuExistInfo.java:
java/runtime/DuExistLocn.java:
java/runtime/DuFunctorDesc.java:
java/runtime/TypeCtorInfo_Struct.java:
Use integer types in RTTI structure definitions for Java that match
the types in the C versions of the same structures.
runtime/mercury_dotnet.cs.in:
Use integer types in RTTI structure definitions for C# that match
the types in the C versions of the same structures.
|
||
|
|
b66f45e4db |
Tighten the mlds_type type.
compiler/mlds.m:
Make two changes to mlds_type.
The simpler change is the deletion of the maybe(foreign_type_assertions)
field from the MLDS representations of Mercury types. It was never used,
because Mercury types that are defined in a foreign language that is
acceptable for the current MLDS target platform are represented
as mlds_foreign_type, not as mercury_type.
The more involved change is to change the representation of builtin types.
Until now, we had separate function symbols in mlds_type to represent
ints, uints, floats and chars, but not strings or values of the sized
types {int,uint}{8,16,32,64}; those had to be represented as Mercury types.
This is an unnecessary inconsistency. It also had two allowed
representations for ints, uints, floats and chars, which meant that
some of the code handling those conceptual types had to be duplicated
to handle both representations.
This diff provides mlds_builtin_type_{int(_),float,string,char} function
symbols to represent every builtin type, and changes mercury_type
to mercury_nb_type to make clear that it is NOT to be used for builtins
(the nb is short for "not builtin").
compiler/ml_code_util.m:
compiler/ml_util.m:
Delete functions that used to construct MLDS representations of builtin
types. The new representation of those types is so simple that using
such functions is no less cumbersome than writing down the representations
directly.
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_global_data.m:
compiler/ml_lookup_switch.m:
compiler/ml_proc_gen.m:
compiler/ml_rename_classes.m:
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_util.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_export.m:
compiler/mlds_to_c_func.m:
compiler/mlds_to_c_global.m:
compiler/mlds_to_c_stmt.m:
compiler/mlds_to_c_type.m:
compiler/mlds_to_cs_data.m:
compiler/mlds_to_cs_stmt.m:
compiler/mlds_to_cs_type.m:
compiler/mlds_to_java_data.m:
compiler/mlds_to_java_stmt.m:
compiler/mlds_to_java_type.m:
compiler/mlds_to_java_wrap.m:
compiler/rtti_to_mlds.m:
Conform to the changes above.
|
||
|
|
edac0e9b5c |
Move sub-word-sized args next to each other ...
... so they can be packed into the same word. |
||
|
|
d1ec3e3f55 |
Pack characters as sub-word-sized arguments.
compiler/options.m:
Add new options --allow-packing-chars and --allow-packing-mini-types,
for use by developers only.
compiler/du_type_layout.m:
If the new --allow-packing-chars option is set, then allow characters
to be packed as sub-word-sized arguments.
Record the value of the --allow-packing-mini-types in the parameters
as well, without using it as yet. (That is for a future change.)
Fix the test for what counts as suboptimal packing. Given an argument
list such as <sub-word-sized args, word-sized arg, sub-word-sized args>
where the two lots of sub-word-sized args could fit into a single word,
the old code did NOT emit a "this is suboptimal" message for it. This
was because it did not consider a reduction from 2n words to 2n-1 words
to be significant, as boehm_gc would always round up the number of words
to (at least) the next multiple of 2. The problem was that the code
used to apply this test ONLY to the number of words occupied by
sub-word-sized args. In this case, better packing would make that number
go from 2 to 1, so it did emit the message, even though the *total*
number of words in the memory cell would go from 3 to 2.
We could fix this by applying the round-up-to-even the test to the total
number of words, but it is simpler to eliminate round-up-to-even entirely.
This is desirable anyway, since we *should* prefer compresssing e.g.
a 4 word cell down to 3 if possible, since this would reduce traffic
to and from (some levels of) cache, even if it would not reduce
the size of the memory allocation.
Fix some too-long lines.
compiler/prog_data.m:
Add fill_char21 as a new kind of fill for sub-word-sized arguments.
(The 21 is a reminder of the 21 bit size of Unicode chars.)
runtime/mercury_type_info.h:
Document that fill_char21 arguments are treated the same way as enum args
in the RTTI.
compiler/hlds_out_module.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_util.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/unify_gen_util.m:
Conform to the changes above.
|
||
|
|
86f563a94d |
Pack subword-sized arguments next to a remote sectag.
compiler/du_type_layout.m:
If the --allow-packing-remote-sectag option is set, then try to pack
an initial subsequence of subword-sized arguments next to remote sectags.
To allow the polymorphism transformation to put the type_infos and/or
typeclass_infos it adds to a function symbol's argument list at the
*front* of that argument list, pack arguments next to remote sectags
only in function symbols that won't have any such extra arguments
added to them.
Do not write all new code for the new optimization; instead, generalize
the code that already does a very similar job for packing args next to
local sectags.
Delete the code we used to have that picked the packed representation
over the base unpacked representation only if it reduced the
"rounded-to-even" number of words. A case could be made for its usefulness,
but in the presence of the new optimization the extra code complexity
it requires is not worth it (in my opinion).
Extend the code that informs users about possible argument order
rearrangements that yield better packing to take packing next to sectags
into account.
compiler/hlds_data.m:
Provide a representation for cons_tags that use the new optimization.
Instead of adding a new cons_tag, we do this by replacing several old
cons_tags that all represent pointers to memory cells with a single
cons_tag named remote_args_tag with an argument that selects among
the old cons_tags being replaced, and adding a new alternative inside
this new type. The new alternative is remote_args_shared with a
remote_sectag whose size is rsectag_subword(...).
Instead of representing the value of the "data" field in classes
on the Java and C# backends as a strange kind of secondary tag
that is added to a memory cell by a class constructor instead of
having to be explicitly added to the front of the argument vector
by the code of a unification, represent it more directly as separate
kind of remote_args_tag. Continuing to treat it as a sectag would have
been very confusing to readers of the code of ml_unify_gen_*.m in the
presence of the new optimization.
Replacing several cons_tags that were usually treated similarly with
one cons_tag simplifies many switches. Instead of an switch with that
branches to the same switch arm for single_functor_tag, unshared_tag
and shared_remote_tag, and then switches on these three tags again
to get e.g. the primary tag of each, the new code of the switch arm
is executed for just cons_tag value (remote_args_tag), and switches
on the various kinds of remote args tags only when it needs to.
In is also more natural to pass around the argument of remote_args_tag
than to pass around a variable of type cons_tag that can be bound to only
single_functor_tag, unshared_tag or shared_remote_tag.
Add an XXX about possible further steps along these lines, such as
making a new cons_tag named something like "user_const_tag" represent
all user-visible constants.
compiler/unify_gen_construct.m:
compiler/unify_gen_deconstruct.m:
compiler/unify_gen_test.m:
compiler/unify_gen_util.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
Implement X = f(Yi) unifications where f uses the new representation,
i.e. some of its arguments are stored next to a remote sectag.
Some of the Yi are stored in a tagword (a word that also contains a tag,
in this case the remote secondary tag), while some are stored in other
words in a memory cell. This means that such unifications have similarities
both to unifications involving arguments being packed next to local
sectags, and to unifications involving ordinary arguments in memory cells.
Therefore wherever possible, their implemenation uses suitably generalized
versions of existing code that did those two jobs for two separate kinds of
cons_tags.
Making such generalizations possible in some cases required shifting the
boundary between predicates, moving work from a caller to a callee
or vice versa.
In unify_gen_deconstruct.m, stop using uni_vals to represent *either* a var
*or* a word in a memory cell. While this enabled us to factor out some
common code, the predicate boundaries it lead to are unsuitable for the
generalizations we now need.
Consistently use unsigned ints to represent both the whole and the parts
of words containing packed arguments (and maybe sectags), except when
comparing ptag constants with the result of applying the "tag" unop
to a word, (since that unop returns an int, at least for now).
In a few cases, avoid the recomputation of some information that we
already know. The motivation is not efficiency, since the recomputation
we avoid is usually cheap, but the simplification of the code's correctness
argument.
Use more consistent terminology in things such as variable names.
Note the possibility of further future improvements in several places.
compiler/ml_foreign_proc_gen.m:
Delete a long unused predicate.
compiler/mlds.m:
Add an XXX documenting a possible improvement.
compiler/rtti.m:
Update the compiler's internal representation of RTTI data structures
to make them able to describe secondary tags that are smaller than
a full word.
compiler/rtti_out.m:
Conform to the changes above, and delete a long-unused predicate.
compiler/type_ctor_info.m:
Use the RTTI's du_hl_rep to represent cons_tags that distinguish
between function symbols using a field in a class.
compiler/ml_type_gen.m:
Provide a specialized form of a function for code in ml_unify_gen_*.m.
Conform to the changes above.
compiler/add_special_pred.m:
compiler/bytecode_gen.m:
compiler/export.m:
compiler/hlds_code_util.m:
compiler/lco.m:
compiler/ml_closure_gen.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/rtti_to_mlds.m:
compiler/switch_util.m:
compiler/tag_switch.m:
Conform to the changes above.
runtime/mercury_type_info.h:
Update the runtime's representation of RTTI data structures to make them
able to describe remote secondary tags that are smaller than a full word.
runtime/mercury_deconstruct.[ch]:
runtime/mercury_deconstruct.h:
runtime/mercury_deconstruct_macros.h:
runtime/mercury_ml_expand_body.h:
runtime/mercury_ml_arg_body.h:
runtime/mercury_ml_deconstruct_body.h:
runtime/mercury_ml_functor_body.h:
These modules collectively implement the predicates in deconstruct.m
in the library, and provide access to its functionality to other C code,
e.g. in the debugger. Update these to be able to handle terms with the
new data representation optimization.
This update requires a significant change in the distribution of work
between these files for the predicates deconstruct.deconstruct and
deconstruct.limited_deconstruct. We used to have mercury_ml_expand_body.h
fill in the fields of their expand_info structures (whose types are
defined in mercury_deconstruct.h) with pointers to three vectors:
(a) a vector of arg_locns with one element per argument, with a NULL
pointer being equivalent to a vector with a given element in every slot;
(b) a vector of type_infos with one element per argument, constructed
dynamically (and later freed) if necessary; and (c) a vector of argument
words. Once upon a time, before double-word and sub-word arguments,
vector (c) also had one word per argument, but that hasn't been true
for a while; we added vector (a) help the consumers of the expand_info
decode the difference. The consumers of this info always used these
vectors to build up a Mercury term containing a list of univs,
with one univ for each argument.
This structure could be stretched to handle function symbols that store
*all* their arguments in a tagword next to a local sectag, but I found
that stretching it to cover function symbols that have *some* of their
arguments packed next to a remote sectag and *some other* of their
arguments in a memory cell as usual would have required a well-nigh
incomprehensibly complex, and therefore almost undebuggable, interface
between mercury_ml_expand_body.h and the other files above. This diff
therefore changes the interface to have mercury_ml_expand_body.h
build the list of univs directly. This make its code relatively simple
and self-contained, and it should be somewhat faster then the old code
as well, since it never needs to allocate, fill in and then free
vectors of type_infos (each such typeinfo now gets put into a univ
as soon as it is constructed). The downside is that if we ever wanted
to get all the arguments at once for a purpose other than constructing
a list of univs from them, it would nevertheless require constructing
that list of univs anyway as an intermediate data structure. I don't see
this downside is significant, because (a) I don't think such a use case
is very likely, and (b) even if one arises, debuggable but a bit slow
is probably preferable to faster but very hard to debug.
Reduce the level of indentation of some of these files to make the code
easier to edit. Do this by
- not adding an indent level from switch statements to their cases; and
- not adding an indent level when a case in a switch has a local block.
Move the break or return ending a case inside that case's block,
if it has one.
runtime/mercury_deep_copy_body.h:
runtime/mercury_table_type_body.h:
Update these to enable the copying or tabling of terms whose
representations uses the new optimization.
Use the techniques listed above to reduce the level of indentation
make the code easier to edit.
runtime/mercury_tabling.c:
runtime/mercury_term_size.c:
Conform to the changes above.
runtime/mercury_unify_compare_body.h:
Make this code compile after the changes above. It does need to work
correctly, since we only ever used this code to compare the speed
of unify-by-rtti with the speed of unify-by-compiler-generated-code,
and in real life, we always use the latter. (It hasn't been updated
to work right with previous arg packing changes either.)
library/construct.m:
Update to enable the code to construct terms whose representations
uses the new optimization.
Add some sanity checks.
library/private_builtin.m:
runtime/mercury_dotnet.cs.in:
java/runtime/Sectag_Locn.java:
Update the list of possible sectag kinds.
library/store.m:
Conform to the changes above.
trace/mercury_trace_vars.c:
Conform to the changes above.
tests/hard_coded/deconstruct_arg.{m,exp,exp2}:
Extend this test to test the deconstruction of terms whose
representations uses the new optimization.
Modify some of the existing terms being tested to make them more diverse,
in order to make the output easier to navigate.
tests/hard_coded/construct_packed.{m,exp}:
A new test case to test the construction of terms whose
representations uses the new optimization.
tests/debugger/browse_packed.{m,exp}:
A new test case to test access to the fields of terms whose
representations uses the new optimization.
tests/tabling/test_packed.{m,exp}:
A new test case to test the tabling of terms whose
representations uses the new optimization.
tests/debugger/Mmakefile:
tests/hard_coded/Mmakefile:
tests/tabling/Mmakefile:
Enable the new test cases.
|
||
|
|
66d20fc6d3 |
Treat apw_partial_first the same as apw_partial_shifted.
Their different treatment was to the root cause of the bug that was fixed
in commit
|
||
|
|
624aaa01f1 |
Pack subword-sized arguments next to a local sectag.
compiler/du_type_layout.m:
If a new option is set, then try to represent function symbols with
only subword-sized arguments by packing those arguments into the same word
as the primary tag and (if it is needed) a secondary tag.
If there are too many such function symbols for the available number of
bits, pick the ones that need the least number of bits, in order to
allow us to use this representation for as many such function symbols
as possible.
This diff implements this packing only for types that have more than one
argument, because implementing it for types that have only one argument
has two extra complications. One is the need for another new cons_id
(see below), which would make this diff bigger and harder to review.
The other is the need to consider interactions with the direct_arg
optimization.
Don't invoke the code for deciding the representation of arguments
if either (a) the function symbol has no arguments, or (b) its cons_id
alone dictates how we will treat its argument (in such cases, there is
always exactly one).
Fix a bug in computing the number of bits needed to distinguish N things.
Store the value of the "experiment" option in the params for now,
since it has helped track down bugs in this change, and may do the same
for my next change. It costs next to nothing.
compiler/options.m:
Add an option that controls whether we allow du_type_layout to pack
arguments next to local secondary tags. The default value is "no",
since "yes" may break binary compatibility.
Add an option that controls whether we allow du_type_layout to pack
arguments next to remote secondary tags. This option is not yet used.
compiler/hlds_data.m:
Add a new cons_id, shared_local_tag_with_args, to represent function
symbols in which the arguments are packed next to a local secondary tag.
Rename the existing shared_local_tag cons_id as shared_local_tag_no_args,
to clarify the distinction.
Redesign the representation of secondary tags a bit, to meet the
requirements I discovered while implementing the new data representation.
compiler/prog_data.m:
Document the now-expanded uses of the arg_pos_width type.
compiler/ml_unify_gen.m:
compiler/unify_gen.m:
Implement unifications involving the new cons_id.
compiler/var_locn.m:
Implement deconstruction unifications involving both right-to-left data
flow and the new cons_id for the LLDS backend requires var_locn.m
to implement a new kind of assignment to a variable: one that updates
its old value. Add a predicate for this. (Previously, deconstructions
with right-to-left flow could update the old value of a word in a
memory cell, whose state var_locn.m does *not* track.)
compiler/code_loc_dep.m:
Provide the interface between unify_gen. and var_locn.m.
compiler/code_info.m:
Store the number of primary tag bits in the code_info, to save it looking
up in the globals structure, since with its new code, unify_gen.m needs it
more often now.
compiler/hlds_out_module.m:
doc/user_guide.texi:
Implement the capability of restricting the dump of the type table
to only the types defined in the module being compiled. Without this,
the type table is cluttered with information about types in other
modules, including the automatically-included builtin modules.
compiler/handle_options.m:
Add a new value of the -D option. The new value, du, asks for the
dumping out of the representations of only the locally defined types.
compiler/ml_gen_info.m:
Store the number of primary tag bits as a uint8, not as int.
compiler/ml_tag_switch.m:
compiler/switch_util.m:
compiler/tag_switch.m:
Update the code that generates switches on du types to handle
local secondary tags that must be masked off before use.
compiler/rtti.m:
Update the compiler's representation of RTTI information to account for
the new data representation.
compiler/type_ctor_info.m:
Construct the updated RTTI representation.
compiler/bytecode_gen.m:
compiler/export.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/modecheck_goal.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
Conform for the changes above.
runtime/mercury_type_info.h:
Extend the representation of du functors in the RTTI to account for
the new data representation scheme. The extensions add only to the
*ends* of structures, or to lists of enum values, with the extensions
only being used if the representation is actually used, which should
allow the updated runtime to also work with .c files that were compiled
with a compiler that does *not* have this diff. For the same reason,
make the old enum value MR_SECTAG_LOCAL a synonym for the new
MR_SECTAG_LOCAL_REST_OF_WORD, which expresses a distinction that
did not previously exist.
Delete a reference to a file that no longer exists.
runtime/mercury_dotnet.cs.in:
library/rtti_implementation.m:
Update the C# and Mercury mirrors of the types updated in
mercury_type_info.h.
runtime/mercury_deconstruct.c:
runtime/mercury_deconstruct_macros.h:
runtime/mercury_ml_expand_body.h:
Implement the deconstruction of terms using the new data representation.
runtime/mercury_deep_copy_body.h:
Implement the copying of terms using the new data representation.
runtime/mercury_table_type_body.h:
Implement the tabling of terms using the new data representation.
runtime/mercury_term_size.c:
Implement computing the size of terms using the new data representation.
runtime/mercury_unify_compare_body.h:
Implement RTTI-based unifications of terms using the new data
representation. (Or at least make a first attempt at this implementation.
We never use RTTI-based unification, so this code has not been tested,
but it is not clear that it *needs* to be tested.)
library/construct.m:
Implement the construction of terms using the new data representation.
library/private_builtin.m:
List MR_SECTAG_LOCAL_REST_OF_WORD as a synonym of MR_SECTAG_LOCAL for Java,
since rtti_to_mlds.m will now emit the new version.
Note that the new data representation is not applicable to Java (or C#),
so it should never see the other kind of sectag (MR_SECTAG_LOCAL_BITS).
tests/hard_coded/sectag_bits.{m,exp}:
tests/hard_coded/sectag_bits_test_data:
A new test case to test the reading in and writing out (and therefore
the construction and deconstruction) of terms containing arguments
packed with a local sectag.
tests/hard_coded/Mmakefile:
Enable the new test case.
|
||
|
|
b06b2621b3 |
Move towards packing args with secondary tags.
compiler/hlds_data.m:
Add bespoke types to record information about local and remote secondary
tags. The one for local secondary tags includes the value of the
primary and secondary tag together, since construct unifications
need to assign this value, and it is better to compute this once,
instead leaving the target language compiler to do it, potentially
many times.
Use a wrapped uint8 to record primary tag values, and wrapped uints
to record secondary tag values. The wrap is to prevent any accidental
confusion with other values. The use of uint8 and uint has two purposes.
First, using the tighest possible representation. Tags are never negative,
and primary tags cannot exceed 7. Second, using these types in the compiler
help us eat our own dogfood; if a change causes a problem affecting
these types, its bootcheck should fail, alerting us to the problem.
Add commented-out types and fields that will be needed for packing
sub-word-sized arguments together with both local and remote secondary
tags.
compiler/du_type_layout.m:
Generate references to tags in the new format.
compiler/ml_unify_gen.m:
compiler/unify_gen.m:
compiler/modecheck_goal.m:
Conform to the changes above.
Fix an old bug: the inst corresponding to a constant with a primary
and a local secondary tag is not the secondary tag alone, but both tags
together.
compiler/bytecode.m:
compiler/bytecode_gen.m:
compiler/closure_gen.m:
compiler/disj_gen.m:
compiler/export.m:
compiler/hlds_code_util.m:
compiler/jumpopt.m:
compiler/lco.m:
compiler/llds_out_data.m:
compiler/llds_out_instr.m:
compiler/lookup_switch.m:
compiler/lookup_util.m:
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_type_gen.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_stmt.m:
compiler/opt_debug.m:
compiler/peephole.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/string_switch.m:
compiler/switch_util.m:
compiler/tag_switch.m:
compiler/type_ctor_info.m:
Conform to the change to hlds_data.m.
In two places, in rtti_out.m and rtti_to_mlds.m, delete old code
that was needed only to implement reserved tags, which we have
stopped supporting a few months ago.
library/uint8.m:
library/uint16.m:
library/uint32.m:
library/uint64.m:
Add predicates to cast from each of these types to uint.
|
||
|
|
ec6a40ed85 |
Put related args of ml_field next to each other.
compiler/mlds.m:
Put the *type* of the pointer next to the *value* of the pointer.
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_rename_classes.m:
compiler/ml_string_switch.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_unused_assign.m:
compiler/ml_util.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/mlds_to_target_util.m:
compiler/rtti_to_mlds.m:
Conform to the change above.
|
||
|
|
b9afc8b78e |
Delete the mlds_unary_op type.
compiler/mlds.m:
We used to have a function symbol ml_unop in the mlds_rval type
that applied one of four kinds of operations to an argument mlds_rval:
boxing, unboxing, casting or a standard unary operation, with a value
of type mlds_unary_op selecting between the four. Replace this system
with four separate function symbols in the mlds_rval type directly,
and delete the mlds_unary_op type.
The new arrangement requires fewer memory cells to be allocated,
and less indirection; it also leads to shorter and somewhat
more readable code.
compiler/ml_optimize.m:
Conform to the change above.
Recognize that a cast has negligible cost.
compiler/ml_code_util.m:
Conform to the change above.
Keep private a predicate that is not used by any other module,
after merging it with another previously-exported predicate
that only *it* uses.
Delete some other predicates that are not used anywhere.
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_global_data.m:
compiler/ml_lookup_switch.m:
compiler/ml_rename_classes.m:
compiler/ml_string_switch.m:
compiler/ml_tag_switch.m:
compiler/ml_unify_gen.m:
compiler/ml_unused_assign.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/mlds_to_target_util.m:
compiler/rtti_to_mlds.m:
Conform to the change above.
|
||
|
|
fc903a0911 |
Eliminate the double storage of types in the MLDS.
compiler/mlds.m:
When we record a Mercury type in the MLDS, we used to record with it
not just its type category (which some aux predicates need), but also
the name by which it is known to the target language compiler, if the
type is defined in that foreign language. Unfortunaly, the data structure
we used to represent the name of the foreign type (and any assertions
on it) also stored a duplicate copy of the Mercury type in the usual
case where the Mercury type was *not* defined in the foreign language.
Having two copies of the same information was dangerous, due to the
possibility of inconsistency between them. It was also unnecessary work
for the compiler passes that had to create the duplicate copies.
Eliminate these problems by always storing *one* copy of the Mercury type.
Store the Mercury and foreign type information next to each other.
compiler/foreign.m:
Make the above possible by deleting up the old exported_type type,
which contained the duplicate copy of the Mercury type in usual case
of a type that is not defined by foreign code, and replacing it
with a type that contains information about just a foreign type.
In the argument lists of the predicates and functions of this module,
replace arguments that used to be type exported_type with a pair
of the Mercury type and a maybe of the new type, which is yes(...)
iff the Mercury type *is* defined in foreign code.
Give some predicates and functions more meaningful names.
Make specialized versions of these functions available (specialized
e.g. to a target language) where these would be useful.
Delete the auxiliary predicates that aren't needed with the
new data structure design.
compiler/export.m:
compiler/ml_accurate_gc.m:
compiler/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_global_data.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_to_mlds.m:
Conform to the changes above.
|
||
|
|
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.
|
||
|
|
4b98f58d9d |
Don't use reserved addresses to represent functors.
Late last year, we agreed to delete the ability to use the addresses
of reserved objects as cons_tags. After another (very short) discussion
on m-dev, this diff also deletes the ability to use small integers
(including zero) acting as pointers.
compiler/options.m:
Delete the --num-reserved-addresses option.
Add a synomym for --compiler-sufficiently-recent, with the intention
that support for the representation of reserved addresses in RTTI
code in the runtime will be deleted when all installed compilers
have this new synonym.
compiler/hlds_data.m:
Delete any mention of the reserved addresses from the cons_tag type,
since we don't have reserved addresses anymore.
Don't record for each type whether it uses reserved addresses;
no type can do so anymore.
compiler/rtti.m:
Delete the part of the RTTI representation that dealt with reserved
addresses.
compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/bytecode_gen.m:
compiler/code_info.m:
compiler/du_type_layout.m:
compiler/equiv_type_hlds.m:
compiler/erl_rtti.m:
compiler/export.m:
compiler/hlds_out_module.m:
compiler/intermod.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/opt_debug.m:
compiler/prog_data.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_gen.m:
Conform to the changes above, mostly by deleting code that used to deal
with reserved addresses.
|
||
|
|
fb97df69ed |
Make "compute type representations" a separate pass.
The ultimate purpose of this diff is to prepare for future improvements
in type representations, allowing values of some data types to be represented
more compactly than up to now.
The main way this diff does that is by creating a separate pass for deciding
how values of each type should be represented. We have traditionally decided
data representations for each type as its type definition was processed
during the make_hlds pass, but these decisions were always tentative,
and could be overridden later, e.g. when we processed foreign_type or
foreign_enum pragmas for the type. This dispersed decision making algorithm
is hard to understand, and therefore to change.
This diff centralizes decisions about type representations in a separate
pass that does nothing else. It leaves the algorithm distributed among
several files (du_type_layout.m, make_tags.m, and add_foreign_enum.m) for now,
to make reviewing this diff easier, but soon after it is committed I intend
to move all the relevant code to du_type_layout.m, to centralize the decision
code in "space" as well as in time.
For the reason why this pass runs before any of the semantic analysis
passes, instead of after all of them as I originally intended and as we
discussed on m-dev in late october 2017, see the big comment at the start of
du_type_layout.m.
As per another part of that same discussion on m-dev, this diff
makes a start on implementing a new type of item, the type_repn item,
which is intended *only* to be used in compiler-generated interface files,
*not* in source files. It is only a start because we can use these items
only *after* the creation of a separate type representation decision pass,
and this diff is already very big. The code for making the compiler understand
these items will be added later. The code for generating them will be added
later still, once the code for understanding them has been installed on
all our systems.
Since I was going to be working on the affected code anyway, this diff
also carries out two other decisions that came out of that discussion:
- the deletion of the ability to reserve a tag in a type for HAL,
either via a compiler option or via a pragma, and
- the deletion of the ability to represent a functor using the address
of a statically allocated object (which we haven't used and won't use,
because it slows down accesses to *all the other functors* of the type).
compiler/mercury_compile_front_end.m:
Invoke the new pass for making decisions about type representations
after the make_hlds pass. (We used to do only the final part of it then.)
Fix a bad dump stage name.
Add an extra check for what it means for a module to be error free.
Make a sub-switch explicit.
compiler/hlds.m:
compiler/make_hlds.m:
Move the modules that implement the new pass from the make_hlds package
to the hlds package, to give the compiler's top level access to them.
Make the same move for the modules that the new pass's modules need.
Since they are now part of hlds, they cannot reach into make_hlds,
and I think this is a cleaner solution than forwarding predicates.
Delete some forwarding predicates that are no longer needed.
compiler/notes/compiler_design.html:
Document the updated location of the moved modules.
Add an XXX to note a place where the documentation has not been
updated in the past.
compiler/du_type_layout.m:
Add code to implement the new pass.
Keep the algorithm for deciding type representations as close
to the previously used algorithm as possible, since this diff
is already big enough. (The previous algorithm was scattered across
add_type.m, add_foreign_enum.m, and make_hlds_passes.m.)
Simplifications and optimizations will come later, after this module
is merged with make_tags.m and with (at least) the foreign_enum half of
add_foreign_enum.m.
compiler/make_tags.m:
Keep the functionality of this module, which does both the first part
of deciding type representations (tentatively assigning tags to functors,
an assignment that may be overridden later), and the last part (packing
multiple adjacent less-than-word-sized enum args into a single word,
if possible.), but simplify it where possible, and note possibilities
for further improvements.
compiler/add_foreign_enum.m:
This module has two halves, one dealing with foreign_enum pragmas
and one dealing with foreign_export_enum pragmas.
Change the half that deals with foreign_enum pragmas to just build
a data structure that du_type_layout.m will need to make its decisions,
this structure being a map from type_ctors to the foreign enum
specification applicable to the current target language. Include
in this structure a component that add_foreign_enum.m itself can use
to report better error messages for duplicate foreign_enum pragmas;
this component records, for each type_ctor and language, the context
of the previous foreign_enum pragma for that combo.
Change the input for the half that deals with foreign_export_enum pragmas
to reflect the fact that it is invoked by du_type_layout.m after all
decisions about type representations have already been made.
compiler/add_special_pred.m:
Move this module from the make_hlds package to the hlds package,
since the code that adds special preds for type is now called from
du_type_layout.m.
Change the names of predicates to make clear whether they add
only the declaration of a predicate, only its definition, or both.
Don't try to pre-guess whether the implementation of a type's
compare predicate will need an index predicate. Let the code
that generates calls to the index predicate both declare and define
the index predicate. This change removes the potential for
inconsistencies between the two pieces of code.
compiler/add_pred.m:
Move this module from the make_hlds package to the hlds package,
since add_special_pred.m needs access to it.
compiler/add_type.m:
When adding a type definition to the HLDS, don't try to decide
its representation. Any such decision was tentative anyway, due
to the possibility of e.g. the later processing of foreign_type
or foreign_enum pragmas for the type. Likewise, don't try to
create the special (unify, compare) predicates for the type.
Leave both tasks to the du_type_layout pass.
Likewise, don't try to pack the representation of types, or record
no_tag types in the table of no_tag types, during the post-processing
pass either; leave both of these to du_type_layout as well.
Rename the predicate that post_processes type definitions to reflect
the two tasks left for it to do.
compiler/prog_data.m:
Do not store width information about the arguments of those data
constructors in the parse tree. That information is not computed
until later; until then, it was always filled in with dummy values.
(But see hlds_data.m below.)
Use bespoke types to represent the presence or absence of user-specified
unify and compare predicates.
Change the representation of data constructors to use a single "maybe"
type, not two lists, to denote the presence or absence of existentially
typed arguments.
Give the HLDS the ability to hold representation information about
abstract types that in the future we will get from type_repn items
in the defining modules' interface files.
Delete the uses_reserved_tag type, since we never use reserved tags
anymore.
compiler/prog_item.m:
Add the new type_repn item type, which is not used yet.
Delete the reserve_tag pragma.
Fix an earlier mistake in the wording of a context message.
compiler/hlds_data.m:
Put all the fields of hlds_du_type (the type definition variant dealing
with discriminated union types) that deal with type representation
issues in a single "maybe" field that is set to "no" before the
type representation decision pass has been run.
Add new type, constructor_repn, that stores the same information as the old
constructor type (defined in prog_data.m), PLUS the information
describing how terms with that data constructor are stored.
Likewise, add a new type ctor_arg_rep, which likewise stores
the widths of each constructor argument. When we implement
argument reordering, we would store the offset of the arg as well.
Since the parse tree representations of constructors and their arguments
don't store representation information anymore, the cons_table they
are stored in doesn't either. Make the lookup of representation information
for a given constructor possible by adding a map to the new "maybe" field
of hlds_du_type.
Provide some utility predicates.
Optimize some existing predicates.
Rename some types to better reflect their meaning.
compiler/hlds_module.m:
Provide a slot in the module_info for storing the information
gathered by make_hlds.m that is needed by the new pass.
compiler/make_hlds_separate_items.m:
When we see either a foreign_enum or a foreign_export_enum pragma,
return values of a bespoke type for them (a type defined in
hlds_module.m), instead of an item_pragma. This makes handling them
considerably easier.
compiler/make_hlds_passes.m:
With the changes in this diff, adding a type to the HLDS won't
decide its representation. Therefore delete the code that used
to loop over foreign_export_enum pragmas; in the absence of
the final type representation information, it won't work right.
Record the information that the du_type_layout pass will need
in the module_info.
compiler/add_pragma.m:
Delete the code for passing on foreign_enum and foreign_export_enum
pragmas to add_foreign_enum.m; they are now passed to add_foreign_enum.m
by du_type_layout.m.
Move a utility predicate to make_hlds_error.m, to allow add_foreign_enum.m
to call it.
compiler/make_hlds_error.m:
Add the utility predicate moved from add_pragma.m.
Move the module from the make_hlds to the hlds package.
compiler/module_qual.m:
Provide a mechanism for recording error messages about e.g. undefined
types without recording that we found an undefined type. This sounds
strange, but there is a valid use case.
When a type definition declares a functor's argument to be of an
undefined type, that error is usually fatal; we stop the compiler
from proceeding even to typechecking, since the typechecker will
probably abort with a map lookup failure. Most other references
to undefined types are similarly fatal for the same reason. However,
if e.g. a foreign_export_enum pragma refers to an undefined type,
that error *won't* be visible to the typechecker, and therefore
won't crash it. The error will still cause the compiler to exit
without generating any target language code, but at least it will be
able to run the typechecker and other semantic analysis passes.
Without this change, the compiler will report only one error in
the ee_invalid.m test case; with it, it reports *every* error
in the test case expected output.
compiler/module_qual.qualify_items.m:
Use the capability describe above for undefined types in
foreign_export_enum pragmas.
compiler/module_qual.qual_errors.m:
Delete a (somewhat incorrect) copy of a predicate in prog_item.m,
to reduce code duplication.
compiler/prog_type.m:
Add ways to represent abstract types whose representations are nevertheless
known (from type_repn items in the defining modules' interface files)
to be notag or dummy types. This will be needed to fix Mantis bug #441,
a fix that will probably be one of the first later changes to build
on this diff.
Delete a type moved to type_util.m.
compiler/type_util.m:
Provide extra versions of some predicates, with the difference between
the old and the new versions being that one requires type representations
to have been decided already, and the other one does not.
Move the definition of the ctor_defn type here from prog_type.m,
since prog_type.m itself does not use it, but type_util.m does.
Give some predicates more meaningful names.
compiler/parse_type_defn.m:
Simplify the code for parsing type definitions, to make it easier
to reuse to parse type_repn items.
Add a sanity check that requires existential constraints to have
*some* existential variables to apply to.
Allow "type_is_representable_in_n_bits" as a synonym for
"type_is_abstract_enum", since in the future we want to be able to pack
e.g. multiple int8s, not just multiple enums, into a single word.
Generate more specific error messages for some classes of malformed input.
compiler/parse_type_repn.m:
New module to parse type_repn items.
compiler/polymorphism.m:
Make some predicates that operate on type constructors take
the type constructors themselves as input arguments, not a whole type
*using* that type constructor. Put the arguments of those predicates
in a more standard order.
Note that some predicates don't belong in this module.
compiler/special_pred.m:
Make the code that decides whether a special predicate for a type
constructor can be defined lazily avoid using type representation
information. (Actually, we now make decisions about lazy vs eager
definitions after type representation is available, but that was
not so in an earlier version of this change, and the new code
is more robust.)
compiler/unify_proc.m:
When we decide to generate code for a compare predicate that needs
the type to have an index predicate, don't presume that the index
predicate has already been declared and defined; instead, declare
and define it then and there. (Index predicates are *never* called
from anywhere else.)
Pack the information needed to define a special predicate
into a single structure, to simplify the above.
Since the creation of a clause for a compare predicate may now require
the declaration and definition of an index predicate, the module_info
field of the unify_proc_info is now a writeable field.
Give some predicates and function symbols more meaningful names.
Note some problems with the existing code.
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_solver.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/comp_unit_interface.m:
compiler/ctgc.selector.m:
compiler/ctgc.util.m:
compiler/default_func_mode.m:
compiler/det_report.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/erl_code_gen.m:
compiler/export.m:
compiler/foreign.m:
compiler/get_dependencies.m:
compiler/goal_expr_to_goal.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/inst_test.m:
compiler/inst_util.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds_warn.m:
compiler/ml_accurate_gc.m:
compiler/ml_simplify_switch.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/mode_util.m:
compiler/modecheck_goal.m:
compiler/module_qual.collect_mq_info.m:
compiler/modules.m:
compiler/parse_item.m:
compiler/parse_pragma.m:
compiler/parse_tree.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_pragma.m:
compiler/post_term_analysis.m:
compiler/proc_requests.m:
compiler/prog_item_stats.m:
compiler/qual_info.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/simplify_goal_ite.m:
compiler/stack_opt.m:
compiler/state_var.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/superhomogeneous.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_constr_build.m:
compiler/term_norm.m:
compiler/trailing_analysis.m:
compiler/type_constraints.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/unify_gen.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
Conform to the changes above.
tests/invalid/Mmakefile:
Disable the reserve_tag test case, as it is not applicable anymore.
tests/invalid/exported_foreign_enum.{m,err_exp}:
tests/invalid/pragma_qual_error.{m,err_exp}:
Delete reserve_tag pragmas from these test cases, and its effects
from the expected outputs.
tests/invalid/bad_foreign_type.err_exp:
tests/invalid/bigtest.err_exp:
tests/invalid/foreign_enum_invalid.err_exp:
tests/invalid/type_lhs_var.err_exp:
tests/invalid/uu_type.err_exp:
tests/invalid/where_abstract_enum.err_exp:
tests/invalid/where_direct_arg.err_exp:
Expect the updated messages for some errors.
tests/valid/Mmake.valid.common:
tests/valid/Mmakefile:
Disable any reserve_tag test cases, as they are not applicable anymore.
|
||
|
|
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.
|
||
|
|
f1906ece65 | Fix some too-long lines. | ||
|
|
756ed140d3 |
Improve non-tail recursion warnings from the MLDS code generator.
Consider two mutually recursive procedures p and q, where p tailcalls q
but q does not tailcall p. The LLDS backend can optimize the tailcall
from p to q, but the MLDS backend cannot, because it can optimize only
*mutual* tail recursion. In such cases, and in other cases where the
MLDS cannot implement a recursive call as a tail call even though the
LLDS backend can, add to the warning message we generate a description
of the reason why the MLDS code generator cannot do what the programmer
may expect them to do.
compiler/ml_gen_info.m:
Include in the state of the MLDS code generator tail-call-related
information not just about all the procedures in the current TSCC,
but about all the procedures in the current SCC. And instead of
storing warning messages about non-tail recursive calls in the code
generator state, store a list of the non-tail recursive calls themselves.
These two changes together allow us to gather a description of all
the non-tail recursive calls before we generate even the first warning.
This should allow a later to use this information to generate messages
such as "the recursive call from p to q here cannot be optimized
because the recursive call from q to p at this *other* context
cannot be optimized".
Make the names of some types and function symbols clearer.
compiler/ml_call_gen.m:
Whenever a recursive call cannot be optimized as a tail call,
record the reason behind that fact.
Use pred_proc_ids instead of separate pred_ids and proc_ids,
since this simplifies the code and should speed paramater passing.
compiler/ml_proc_gen.m:
Pass tail-call-related information about the procedures of the SCC along
as we generate code for the SCC's procedures.
Once we have generated code for all of the SCC's procedures,
turn the final list of the non-tail calls in the SCC into a list
of warnings for them.
compiler/options.m:
doc/user_guide.texi:
Add a compiler option that controls whether we report as non-tail
calls recursive calls that *obviously* cannot be tail calls, because
they are followed by other recursive calls. The standard example
is the first recursive call in qsort.
A comment by Paul has long called for such an option, and this diff
touches the same code anyway.
Fix an unrelated old blemish: document both of the old options
--warn-non-tail-recursion-{self,mutual}, but in a commented out form,
since they are internal-use options. Before this diff, only one was
documented, and only user_guide.texi.
compiler/mark_tail_calls.m:
Add parameters to the predicates that generate warnings that specify
why the recursive call cannot be optimized as a tail call (describing
the reason if it is a result of a limitation in the compiler, and
not a problem in the program being compiled), and whether the call
is obviously a non-tail call.
When marking a call as recursive, but the recursive call is obviously
not a tail call, mark it as such using a new goal feature. The MLDS
backend needs this to allow it to filter warnings for obviousness
the same way as mark_tail_calls.m itself.
compiler/hlds_goal.m:
Add the new goal feature mentioned above.
compiler/ml_closure_gen.m:
compiler/ml_tailcall.m:
compiler/rtti_to_mlds.m:
compiler/saved_vars.m:
Conform to the changes above.
tests/invalid/require_tailrec_1.err_exp2:
tests/invalid/require_tailrec_2.err_exp2:
tests/invalid/require_tailrec_3.err_exp2:
Add the expected warnings from the MLDS code generator.
tests/invalid/Mercury.options:
Specify -E for one of the tests above, to test the handling of the
verbose-only part of the warnings.
tests/EXPECT_FAIL_TESTS.hlc.gc:
Do not expect tests/invalid/require_tailrec_[123] to fail
in grade hlc.gc anymore.
|
||
|
|
eccd0bfab4 |
Implement mutual tail call optimization for the MLDS.
It does not (yet) optimize all the calls that the LLDS backend optimizes,
with the most significant limitation being that it handles only calls to
procedures that return all their arguments by reference. This rules out
det functions (thought it includes *semidet* functions), as well as the
backends that use copy-out. Lifting those limitations is future work.
compiler/ml_proc_gen.m:
Make the change described above.
compiler/mlds.m:
Add two new kinds of compiler-generated local variables to represent
the input and output arguments of procedures in TSCCs respectively.
They are key to allowing the code generation scheme used by ml_proc_gen.m
to work *without* having to rename apart either sets of HLDS variables
or set of MLDS variables. (Both those renames would be a lot of work.)
Add a new kind of compiler-generated local variable to represent
the identity of the tail-called procedure if the code generator is asked
not to use labels and gotos.
compiler/ml_args_util.m:
Provide a predicate that ml_proc_gen.m uses to generate argument handling
code for mutually recursive procedures.
compiler/ml_gen_info.m:
Generalize the existing support for self-tail-recursive calls
to also handle mutually-tail-recursive calls.
compiler/ml_call_gen.m:
Use the new generalized support to generate code for
mutually-tail-recursive calls as well as for self-tail-recursive calls.
For each call to a procedure that the ml_gen_info records as a potential
target for a tail recursive call (i.e. for each procedure in the TSCC
we are generating code for), record what kinds of calls we *do* generate
to it, for use by ml_proc_gen.m.
compiler/ml_code_util.m:
Add a slightly different form of an existing utility function,
to allow new code in ml_proc_gen.m to use it without doing redundant work.
Expand out a function's definition to allow mdb breakpoints on its
components.
compiler/options.m:
Provide developer-only options to control aspects of how ml_proc_gen.m
handles tail call optimization.
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
Provide a way for the MLDS to specify the printing of a blank line:
a comment containing an empty string. Some code in ml_proc_gen.m uses this
to make the comments it generates look nicer.
compiler/hlds_desc.m:
Add two utility functions that we now use to include descriptions
of TSCCs in the generated MLDS code, to help debug that code.
compiler/proc_gen.m:
Delete code that can now be replaced by calling one of the new utility
functions in hlds_desc.m. (The deleted code was used as the original
template for the code of that function.)
Delete an unused type.
compiler/rtti_to_mlds.m:
Conform to the changes in ml_gen_info.m.
|
||
|
|
57d58da6ff |
Factor out some common code.
compiler/ml_proc_gen.m:
Prepare for translating all HLDS procedures in a TSCC all at once to MLDS,
by taking some chunks of code that will be useful in this process
out of the predicate that translates a single HLDS procedure to MLDS
and making them predicates in their own right. The new mechanism for
translating a whole TSCC at once will take these pieces and put them,
or modified/generalized versions of them, together in different ways.
compiler/ml_args_util.m:
Factor out some code that is common to all exported predicates
that generate argument lists.
Add a "_no_gc_stmts" suffix to the names of the predicates that generate
argument lists that do not fill in the gc stmt field in the generated
mlds_arguments.
compiler/ml_gen_info.m:
Instead of storing the pred_id and proc_id of the procedure being
translated separately, store them together as a pred_proc_id, because
most users of ml_gen_info need both at the same time.
compiler/ml_code_util.m:
Make several predicates take pred_proc_ids instead of separate pred_ids
and proc_ids.
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_top_gen.m:
compiler/ml_unify_gen.m:
compiler/rtti_to_mlds.m:
Conform to the changes above.
|
||
|
|
bbd6c44a26 |
Create ml_args_util.m.
Both ml_code_util.m and ml_call_gen.m had predicates that used the same logic
to process lists of arguments. This is not a coincidence; they both process
argument lists, one from the point of the callee, the other from the point
of view of the caller. These have to be kept in lockstep. This is easier
if they are next to each other. This diff therefore moves those predicates
to the same module, a new module named ml_args_util.m.
compiler/ml_call_gen.m:
compiler/ml_code_util.m:
Delete the new code now in ml_args_util.m.
compiler/ml_args_util.m:
The new module.
compiler/ml_backend.m:
compiler/notes/compiler_design.html:
Mention the new module.
compiler/ml_closure_gen.m:
compiler/ml_proc_gen.m:
compiler/ml_top_gen.m:
compiler/rtti_to_mlds.m:
Conform to the changes above.
|
||
|
|
034cb97988 |
Don't module- or type-qualify MLDS local variables.
Some global variables generated by the MLDS backend need to be visible
across module boundaries, and therefore mlds_data definitions, which
contained global as well as other variables, used to have their names
qualified; usually module-qualified, though sometimes type-qualified.
However, since the diff that partitioned mlds_data_defns into the
definitions of local variables, global variables and field variables,
the qualification of local variables has *not* been necessary, so this diff
removes such qualifications. This makes the MLDS code generating references
to local variables simpler, more readable, and slightly faster.
The generated code is also shorter and easier to read.
There are two exceptional cases in which local variables *did* need
qualification, both of which stretch the meaning of "local".
One such case is the "local" variable dummy_var, which (by definition)
is only ever assigned to, and never used. It is also never defined
in MLDS-generated code; instead, it is defined defined in private_builtin.m
(for the Java and C# backends) or the runtime (for C). All three backends
currently require references to this variable in the runtime to be module
qualified. There are three possible fixes to this problem, which is caused
by the fact that this "local" variable is in fact global.
- Fix 1a would be to make dummy_vars global, not local.
- Fix 1b is to special-case dummy_vars in mlds_to_{c,cs,java}.m, and put
the fixed "private_builtin" qualifier in front of it.
- Fix 1c would be to modify the compiler to never generate any references
to dummy vars at all.
This diff uses fix 1b, because it is simple. I (zs) will explore fix 1c
in the future, and see if it is viable.
The second such case occurs when generating code for unifications
involving function symbols represented by the addresses of reserved objects.
These addresses used to be represented as the addresses of mlds_data
definitions, then as addresses of field variables cast as qualified
local variables. Since diff this makes all local variables unqualified,
this can't continue. Two possible fixes are
- Fix 2a: introduce an mlds const rval representing the address of a field
variable, which solves the problem because unlike local variables,
field variables can still be either module- or type-qualified.
- Fix 2b: prohibit the use of the addresses of reserved objects as tags.
After a (short) discussion on m-dev, this diff uses fix 2b.
compiler/mlds.m:
Delete the qual_local_var_name type, and replace all its uses
with the mlds_local_var_name type. Delete the module qualifier field
in mlds_data_addr_local_var consts.
compiler/ml_code_util.m:
Simplify the predicates and functions whose task is to build references
to local variables. Delete the arguments that they don't need anymore.
Delete one function entirely, since calling it now takes both more
characters and more code than its shortened body does.
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_rename_classes.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_target_util.m:
compiler/rtti_to_mlds.m:
Conform to the changes above. Stop qualifying local variable names,
and stop passing the parameters that used to be used *only* for
qualifying local variable names.
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
Conform to the changes above, and implement fix 1b.
NEWS:
compiler/options.m:
compiler/make_tags.m:
Implement fix 2b by disabling the --num-reserved-objects option.
This ensures that we don't use the addresses of reserved objects as tags.
library/private_builtin.m:
Move the C# definition of dummy_var next to the Java definition,
and fix the comments on them.
|
||
|
|
da9808036c |
Implement self-tail-call optimization in the MLDS code generator.
This is a step towards implementing not just self- but also mutual
tail recursion in the MLDS code generator.
compiler/options.m:
Add an option, --optimize-tailcalls-codegen, that asks for MLDS backend
to optimize self tail calls via the code generator, not ml_tailcall.m.
(We still use ml_tailcall.m if the new option is not set.) The new option
is set by default, but this can be changed if we find a problem
with the new approach.
compiler/mark_tail_calls.m:
Fix a bug. In a disjunction, the nonlast disjuncts cannot contain tail
calls, because (a) if a nonlast disjunct is semidet, then after any
such recursive call fails, we can still backtrack to later disjuncts,
and (b) if the nonlast disjunct involved is det, the later disjuncts
should have been optimized away, and the disjunct wouldn't be nonlast
anymore.
Export predicates that allow the MLDS backend to mark tail calls
as *it* wants them marked.
Reorganize the predicates that generate warnings to make them useable
from the MLDS code generator as well, and export the required predicates.
(The MLDS code generator needs this access because in some cases,
a call that mark_tail_calls.m thinks is a tail call cannot be implemented
as such. Since only the MLDS code generator knows this fact, only *it*
can know when this warning may need to be generated.)
Some of the reorganization of code that generates warnings factors out
common code between mark_tail_calls.m and ml_tailcall.m.
compiler/ml_tailcall.m:
Export some functionality for the code generator to use.
Replace the found_recursive_call type, which used to be defined here,
with the found_any_rec_calls type from mark_tail_calls.m, since they
were isomorphic and had the same job.
Delete the code that was factored out into mark_tail_calls.m.
compiler/mercury_compile_mlds_back_end.m:
If --optimize-tailcalls-codegen is set, run the mark_tail_calls pass
before MLDS codegen.
Prepare for the code generator to generate warnings about calls that should
be tail calls not actually being tail calls.
Delete an unused exported predicate, and the imports it used to need.
compiler/mercury_compile_llds_back_end.m:
Fix style.
compiler/ml_gen_info.m:
Extend the code generator state with information needed for tail call
optimization, and for generating warnings.
compiler/ml_proc_gen.m:
When starting to generate code for a procedure, set up the new part
of the code generator state with the information needed to handle tail
calls, if we both (a) can optimize tail calls in the predicate, and (b)
we have been asked to.
After the code for the procedure body has been generated, *and* if
we have actually turned some tail calls into jumps to the start of
the procedure, create the wrapper around the MLDS code implementing
the body goal that makes such jumps possible.
compiler/ml_call_gen.m:
When generating code for a plain call, test whether it is a tail call,
and if so, try to optimize it. If we fail, generate a warning about
that fact, and fall back to generating code for it as we would do
for any non-tail call.
Provide mechanisms for this new code to compute the actual parameter
lvals for the input arguments of a (tail) call, since only these
have to be assigned from when replacing a tail call.
compiler/ml_code_util.m:
Provide mechanisms for ml_proc_gen to compute the mlds_arguments
of the formal parameters of just the input arguments of a procedure,
since only these have be assigned to when replacing a tail call.
(The predicates that perform these mirror image tasks should be
next to each other, perhaps in a new ml_args_util.m module.)
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_optimize.m:
Export to ml_call_gen.m (a slightly modified form of) a predicate
that is used in the replacement of tail calls.
Peephole optimization a pattern that we now generate.
compiler/rtti_to_mlds.m:
Conform to the changes above.
tests/hard_coded/semi_tail_call_in_nonlast_disjunct.{m,exp}:
Add a test case for the bug fixed in mark_tail_calls.m. Without the fix,
the updated MLDS code generator's output fails this test.
tests/hard_coded/Mmakefile:
Enable the new test case.
|
||
|
|
c3d8d7a1a7 |
Fix two problems related to function names.
The first problem is that the MLDS constructs that defined functions and
the MLDS constructs that take the addresses of functions used different
data types to *name* those functions. The translations of these constructs
to each target language had to generate the same target language code,
but they did so via two (or in some cases more) separate pieces of code.
The second problem is that the MLDS functions that implement HLDS procedures,
and the auxiliary functions that are sometimes needed to help implement
those procedures, were not delineated as clearly as is they should be.
compiler/mlds.m:
To (mostly) fix the first problem, define the mlds_func_label type,
and use it to identify MLDS functions in both function definitions
and in the mlds_code_addr type that represents a reference to a function.
A full fix will require function definitions to use *qualified*
mlds_func_labels, as the mlds_code_addrs already do. However,
the problem that MLDS definitions are not qualified applies not just
to functions but to other entities as well, and is therefore better fixed
separately.
To fix the second problem, introduce the mlds_maybe_aux_func_id type.
This also addresses an old XXX by providing explicit ways to represent
gc trace functions for both auxiliary and non-auxiliary MLDS functions.
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_gen_info.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_rename_classes.m:
compiler/ml_tailcall.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/mlds_to_target_util.m:
compiler/rtti_to_mlds.m:
Conform to the above.
|
||
|
|
b390231f22 |
Use mlds_target_lang in the MLDS backend.
The overall compilation target language (which is recorded in the globals)
can be C, Java, C# or Erlang. The target language of the MLDS backend
can only be the first three. Use the mlds_target_lang type (which has
three functors) instead of the compilation_target type (which has four)
to make target-specific decisions in the MLDS backend.
compiler/mercury_compile_mlds_back_end.m:
Compute the MLDS target (which can be C, Java or C#) from the compilation
target (which can also be Erlang).
compiler/ml_closure_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_gen_info.m:
compiler/ml_global_data.m:
compiler/ml_proc_gen.m:
compiler/ml_string_switch.m:
compiler/ml_tag_switch.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds.m:
compiler/rtti_to_mlds.m:
Use the mlds_target_lang value computed in mercury_compile_mlds_back_end.m
to make decisions. Code in most modules get this from the ml_gen_info;
in some others, it is passed around, usually instead of the globals.
compiler/ml_code_util.m:
Unify two separate copies of a comment.
|
||
|
|
05433e82ea |
Don't use "flat" names in ml_global_data.m.
compiler/ml_global_data.m:
Don't use flat/nonflat as part of the names and description of the
components of ml_global_data, since (due to their now specialized types)
this isn't needed anymore.
Put fields of related types next to each other.
Delete an unused predicate.
Delete some old, now-misleading comments.
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_to_mlds.m:
Conform to the change above.
|
||
|
|
4cb6e63597 |
Simplify the flags field in global var definitions.
compiler/mlds.m:
Global variables are defined outside classes (except classes that function
as modules), so the one_copy/per_instance distinction does not make
sense for them. They also only have two possible levels of access:
the module, and the whole program. Change the flags field of global
variables to reflect this. Use a concrete type to represent such flags,
since abstraction buys us nothing useful in this case.
compiler/ml_global_data.m:
compiler/ml_proc_gen.m:
compiler/ml_type_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_to_mlds.m:
Conform to the change above.
|
||
|
|
fa5eee77c5 |
Specialize qual/3 for each type it was applied to.
The MLDS either module- or type-qualifies several kinds of entities.
It used to use the same qual/3 wrapper for all these entities. However,
many kinds of entities are never (and can never be) type-qualified,
because they are not defined inside a type.
This diff replaces the mlds_fully_qualified_name type, and its qual/3 wrapper,
with a separate type and a separate wrapper for each kind of entity.
For those entities that can be both module- and type-qualified, have this
wrapper continue to include a mlds_qual_kind (module_qual or type_qual) field;
for the entities that are only ever module qualified, omit this field.
compiler/mlds.m:
Make the change described above.
There are some related changes.
The first is that the argument of the ml_field_named rval specifying
the field used to be a string. Change this to be a field_var_name,
because if a field's name is given by a field_var_name in its definition,
it should be given by that same field_var_name in its uses as well.
Without this, it is unnecessarily hard to ensure that the code that
generates the target language versions of the field's name match
in definitions and uses; specification, it would be unnecessarily hard
to ensure that they do module- or type-qualification the same way.
The second is required by the first. We used to use "ptr_num"
as the name of only a compiler-generated local variable, but it is
actually the name of a field in a compiler-generated class, and the
local variable use actually refers to the field. Therefore this diff
moves the reference to this from the mlds_local_var_name type
to the mlds_field_var_name type.
The third is switching to a more consistent naming scheme:
having the unqualified name of entities of kind xxx be mlds_xxx_name
and the qualified version of those names being qual_xxx_name.
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_global_data.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_to_mlds.m:
Conform to the changes above.
compiler/java_names.m:
Clarify a variable name.
|
||
|
|
47f1df4a0a |
Split mlds_data_defn into three separate types.
We used to use mlds_data_defns to represent three related but nevertheless
distinct kinds of entities: global variables, local variables, and fields
in classes. This diff replaces the mlds_data_defn type with three separate
types: mlds_global_var_defn, mlds_local_var_defn and mlds_field_var_defn
respectively, with corresponding changes to related types, such as
mlds_data_name.
The global variables are completely separate from the other two kinds.
Local and field variables are *mostly* separate from each other, but they
are related in one way. When we flatten out nested functions, the child
nested function can no longer access its parent function's local variables,
so we pass those variables to it as fields of an environment structure.
This requires turning local variables to fields of that structure,
and the code in the flattened previously-nested function that accesses
those fields naturally wants to treat them as if they were local variables
(as indeed they sort-of were before the flattening). There are therefore
ways to convert each of local and fields vars into the other.
This restructuring makes clear several invariants of the MLDS we generate
that were previously hidden. For example, variables with certain kinds of
names (in the before-this-diff, general version of the mlds_var_name type)
could appear only as function arguments or as locals in ml_stmt_blocks,
not in ml_global_data, while for some other names the opposite was the case.
And in several cases, functions used to take a general mlds_data_defn
as argument but aborted if given the "wrong kind" of mlds_data_defn.
This diff also makes possible further simplifications. For example,
local vars should not need some flags (since e.g. they are never per-instance),
and should never need either module or type qualification, while global
variables (which are also never per-instance) should never need type
qualification (since they are not fields of a type). The definitions
in blocks should consist of local variables and (before flattening) functions,
not global variables, field variables or classes, while the members in classes
should be only field variables and functions (and maybe classes), not
global or local variables. Those changes will be in future diffs;
this is already large enough.
compiler/mlds.m:
Make the changes described above.
Use tighter types where possible.
Use (a generalized version) of the mlconst_named_const functor
to represent values of enum types defined in the runtimes
of the target platforms.
compiler/ml_global_data.m:
Store *only* global variables in fields that previously stored general
mlds_datas (that by design were always global).
Store *only* closure wrapper functions in the previous non-flat-defns
field. Before this diff, the code generator only put closure wrapper
functions in this field, but then ml_elim_nested.m put everything
resulting from the expansion of those functions back into those fields
as well, some of which were not functions. It now puts those non-function
things into the MLDS data structure directly.
compiler/ml_code_util.m:
compiler/ml_util.m:
Conform to the changes above.
Use tighter types where possible. If appropriate, change the name
of the function or predicate accordingly.
Represent references to enum constants defined in the runtime of the
target language as named constants (since they is what they are),
instead of representing them as MLDS "variables", which required
the code of mlds_to_cs.m had to special-case the treatment
of those "variables".
compiler/ml_elim_nested.m:
Conform to the changes above.
Use tighter types where possible.
Don't put the environment types resulting from flattening nested scopes
back into the non-flat-defns slot of the ml_elim_info; instead, return
them separately to code that puts them directly in the MLDS.
compiler/rtti.m:
When returning the names of enum constants in the C runtime, return also
the prefixes that you need to place in front of these to obtain their names
in the Java and C# runtimes.
compiler/mercury_compile_mlds_back_end.m:
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.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/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/mlds_to_target_util.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
Conform to the changes above.
Move a utility function from ml_util.m to mlds_to_target_util.m,
since it is used only in mlds_to_*.m.
|
||
|
|
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.
|
||
|
|
30ec420984 |
Fix an anomaly in how in MLDS treats scalar commons.
compiler/mlds.m:
The MLDS used to have two different ways to refer to scalar common
data structures. It had an rval for the *name* of the scalar common,
and an mlds_name for its *address*. The name could then be wrapped up
inside a mlconst_data_adr function symbol to convert it to rval.
An mlds_name is intended to be used for the names of data definitions
in the MLDS, but scalar commons were never defined in this way.
And the name and address of a scalar common differ in C only by
the addition of an "&" operator in front, so the fact that they
had to be processed by different code (due to them having different types)
*required* double maintenance.
This diff fixes this anomaly by making both the name and the address
of a scalar common its own specific function symbol in the mlds_rval type.
They differ in the presence or absence of an "_addr" suffix.
Since all references to a vector common are to its address, give
the existing mlds_rval function symbol for vector commons the "_addr
suffix as well, for consistency.
Replace the general mlconst_data_addr function symbol in the
mlds_rval_const with its remaining instances. This allows the code
constructing them to be smaller and simpler, and enables them
to be treated differently in the future, if needed.
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
Conform to the changes in mlds.m.
Put the code translating the various common structures next to each other,
where they werent' before. Add XXXs about the differences between them
that are probably unnecessary and may possibly be latent problems.
compiler/ml_util.m:
Conform to the changes in mlds.m.
Change the interface to a set of predicates that looks for variables
inside various MLDS constructs to take a variable name, not a data name,
as the thing being looked for.
compiler/ml_closure_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_global_data.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_string_switch.m:
compiler/ml_tailcall.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_target_util.m:
compiler/rtti_to_mlds.m:
Conform to the changes in mlds.m, and maybe ml_util.m.
In ml_proc_gen.m, put related arguments of some predicates and functions
next to each other.
|
||
|
|
e3a8aec982 | Delete unused layout references from the MLDS. | ||
|
|
c88a777501 |
Delete some dead predicates.
compiler/*.m:
Delete dead predicates that don't look likely to be used in the future
in their current form.
For dead predicates that may be needed in the future, shut up warnings
about them by adding a consider_used pragma for them.
In intermod.m, delete two unused fields in a structure.
|
||
|
|
083f990dbb |
Simplify the use of contexts in the MLDS.
compiler/mlds.m:
This diff fixes two minor annoyances imposed by the old use of the
mlds_context type in the MLDS.
The first annoyance was that the mlds_context type used to be an
abstract type that was privately defined to be a trivial wrapper
around a prog_context. It had the exact same information content
as a prog_context, but you had to go through translation functions
to translate prog_contexts to mlds_contexts and vice versa.
I think Fergus's idea was that we may want to add other information
to the mlds_context type. However, since we haven't felt the need
to anything like that in the 18 years (almost to the day) that the
mlds_context type existed, I think this turned out to be a classic
case of YAGNI (you ain't gonna need it).
This diff deletes the mlds_context type, and replaces its uses
with prog_context.
The second annoyance was that actual MLDS code, i.e. values of the
mlds_stmt type, always had to wrapped up inside a term of the statement
type, a term which paired a context with the mlds_stmt.
This diff moves the context information (now prog_context, not
mlds_context) into each function symbol of the mlds_stmt type,
deletes the statement type, and replaces its uses with the now-expanded
mlds_stmt type. This simplifies most code that deals with MLDS code.
compiler/ml_util.m:
Add a function, get_mlds_stmt_context, for the (very rare) occasions
where we want to know the context of an mlds_stmt *before* testing
to see what function symbol it is bound to.
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_global_data.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_to_mlds.m:
Conform to the changes above.
In some cases, a function was given two separate contexts, sometimes from
two separate sources; a prog_context and an mlds_context. In such cases,
keep only one source.
Standardize on Stmt as the variable name for "statement".
Delete redundant $module references from unexpected and other abort
predicates.
In one case, delete a function that was a duplicate of another function.
Give some predicates and functions more meaningful names.
|
||
|
|
91ba5278bc |
Tighten the type of flags in mlds_data_defns.
compiler/mlds.m:
As above.
compiler/ml_util.m:
Delete the predicate that returned the flags of *every* kind of definition
as a value of a single type.
Add a utility predicate used by both mlds_to_{cs,java}.m.
Delete utility predicates all of whose uses in the files below
this diff replaces with other code.
compiler/ml_closure_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_global_data.m:
compiler/ml_proc_gen.m:
compiler/ml_type_gen.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_to_mlds.m:
Conform to the above.
In mlds_to_c.m, simplify some other related code.
|
||
|
|
8f58542270 |
Tighten the type of names in mlds_data_defns.
compiler/mlds.m:
Make type of the name of an mlds_data_defn not an mlds_entity_name,
but an mlds_data_name, one of the several possibilities that
mlds_entity_name chooses amongst. For data definitions, we always
use a data name.
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_global_data.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_type_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_to_mlds.m:
Conform to the above: stop wrapping and unwrapping data names.
|
||
|
|
869605956c |
Make MLDS definitions self-contained.
Until now, we used a single type, mlds_defn, to contain both
- generic information that we need for all MLDS definitions, such as
name and context, and
- information that is specific to each different kind of MLDS definition,
such as a variable's initializer or a function's list of parameter types.
The former were contained in three fields in the mlds_defns directly,
while the latter were contained in a fourth field that was a discriminated
union of mlds_data_defn, mlds_function_defn and mlds_class_defn.
While seemingly parsimonious, this design meant that if we had e.g. a list
of variable definitions, we would have to wrap the mlds_defn/4 wrapper around
them to give them their names, and thereafter, any code that processed
that list would have to be prepared to process not just variables but also
functions and classes.
This diff moves the three generic fields into each of the mlds_data_defn,
mlds_function_defn and mlds_class_defn types, making each those types
self-contained, and leaving mlds_defn as nothing more than a discriminated
union of those types.
In the few places that want to look at the generic fields *without*
caring about what kind of entity is being defined, this design requires
a bit of extra work compared to the old design, but in many other places,
the new design allows us to return mlds_data_defns, mlds_function_defns
or mlds_class_defns instead of just mlds_defns.
compiler/mlds.m:
Make the change described above.
Store type definions (for high level data) and table structures definitions
separately from other definitions in the MLDS type, since we can now
give them tighter types.
compiler/ml_global_data.m:
Change the fields that store flat cells from storing mlds_defns to
storing mlds_data_defns, since we can now do so.
Add an XXX about an obsolete comment.
compiler/mercury_compile_mlds_back_end.m:
compiler/ml_accurate_gc.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_to_mlds.m:
Conform to the changes above. Where possible with only local changes,
return mlds_data_defns mlds_function_defns or mlds_class_defns instead
of just mlds_defns. Put the mlds_data(_), mlds_function(_) or mlds_class(_)
wrapper around those definitions as late as possible (typically, when
our current code wants to put it into the same list as some other kind
of definition), in the hope that in the future, that wrapping can be
delayed even later, or even avoided altogether. Make the places where
such improvements may be possible with "XXX MLDS_DEFN".
In some places, the tighter data representation allows us to *delete*
"XXX MLDS_DEFN" markers.
Move some common code from mlds_to_{cs,java}.m to ml_util.m.
In mlds_to_{cs,java}.m, add prefixes to the function symbols in a type
to reduce ambiguity.
|
||
|
|
49fc26b6ff |
Store the mlds_defns of functions and data in their own types.
compiler/mlds.m:
The mlds_defn type can store the definition of a piece of data,
a function, or a class. The information contained in the definition
of a class was stored in a separate type, but the information stored
in the other two kinds of definitions weren't, which made it impossible
to store e.g. a list of just *data* definitions. Fix this by providing
two types that store the information contains in data and function
definitions respectively.
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_global_data.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_tailcall.m:
compiler/ml_type_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_to_mlds.m:
Conform to the change above.
|
||
|
|
28f2f7f807 |
Make some previously incomplete switches complete.
All of these places were pointed out by the new --inform-incomplete-switch
option.
compiler/add_pred.m:
compiler/goal_form.m:
compiler/intermod.m:
compiler/ml_elim_nested.m:
compiler/post_term_analysis.m:
compiler/prog_mode.m:
compiler/prog_type.m:
compiler/unneeded_code.m:
compiler/var_locn.m:
As above. In some cases, this meant adding the missing cons_ids
with a simple `fail' as the goal. In other cases, it meant adding
comments on the `fail'. In yet other cases, it involved replacing
semidet predicates with functions returning bools.
In a few places, the code for the previously-missing cons_id
throws an exception.
In prog_mode.m and var_locn.m, the code for some previously-missing
cons_ids is neither `fail' nor an abort, but code that does the actual
job of the predicate it is in. In these cases, the fact that this code
was previously missing seems to have been a bug.
compiler/lp_rational.m:
Delete unnecessary module qualification on pred and func declarations.
Fix some comments.
compiler/rtti_to_mlds.m:
deep_profiler/html_format.m:
Fix some comments.
|
||
|
|
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.
|
||
|
|
3acbf03059 |
Implement combined higher-order types and insts.
These allow types to be defined in the following manner:
:- type job ---> job(pred(int::out, io::di, io::uo) is det).
For any construction unification using this functor the argument must
have the required higher-order inst; it is a mode error if it does not.
When terms of type job with inst ground are deconstructed, the argument
is inferred to have the given inst, allowing a higher-order call in that
mode.
The new type syntax is currently only permitted as the direct argument of
a functor in a du type definition. In future it would be meaningful to
support this syntax in other locations, but that is left for a separate
change.
In order to correctly implement the construct/3 library predicate, we
need to be able to dynamically check that arguments do not violate
any constraints on the argument insts. At the moment, we conservatively
abort if any such constraints are present irrespective of whether they
are satisfied or not. Since these constraints are a new feature, no
existing code will abort in this way.
The implementation refers to the inst information associated with types
as "subtype information". This is because, generally, we think of the
combination of a type with a fully bound inst (i.e., one that describes
terms that contain no unbound variables) describes a subtype of that type.
compiler/inst_util.m:
Ensure that arguments have the necessary insts in construction
unifications.
Where available, propagate the insts into arguments rather than
using ground(shared, none).
compiler/prog_io_type_name.m:
Parse the new form of types.
compiler/unparse.m:
Unparse the new form of types.
compiler/prog_io_type_defn.m:
Allow the new form of types in functor arguments.
compiler/prog_ctgc.m:
compiler/prog_io_item.m:
compiler/prog_io_mutable.m:
compiler/prog_io_pragma.m:
compiler/prog_io_typeclass.m:
compiler/superhomogeneous.m:
Disallow the new form of types in places other than functor
arguments.
compiler/prog_data.m:
Go back to representing function types with result type appended
to the arguments. In most case this now results in simpler code.
compiler/prog_type.m:
Abstract away the representation of predicate vs function arguments
by using a predicate to construct these types.
compiler/rtti.m:
compiler/type_ctor_info.m:
Include subtype information about the arguments of a du functor
and about the argument of a notag functor. Generate this
information from the argument types.
Currently, the information is one bit which says whether or not
any subtypes exist in the arguments.
Bump the RTTI version number from the compiler side.
compiler/rtti_out.m:
Output functor subtype information for the low-level C backend.
compiler/rtti_to_mlds.m:
Include functor subtype information in the MLDS.
compiler/mlds_to_cs.m:
Add the new runtime type to the special cases.
compiler/erl_rtti.m:
compiler/erlang_rtti.m:
library/erlang_rtti_implementation.m:
Include functor subtype info in the erlang RTTI.
java/runtime/DuFunctorDesc.java:
java/runtime/FunctorSubtypeInfo.java:
Include functor subtype information in the Java runtime.
runtime/mercury_dotnet.cs.in:
Include functor subtype information in the C# runtime.
runtime/mercury_type_info.h:
Include functor subtype information in the C runtime.
Bump the RTTI version number in the runtime.
Define macros to access the new field. These macros can correctly
handle the previous RTTI version, therefore we do not need to
change the minimum version at this time.
library/private_builtin.m:
Define constants for use by the Java backend.
library/construct.m:
library/rtti_implementation.m:
Use the new RTTI to ensure we don't attempt to construct terms
that violate the new insts.
compiler/prog_rep_tables.m:
Ignore the new inst info for now.
compiler/*.m:
Changes to conform to above.
doc/reference_manual.texi:
Document the new feature.
tests/hard_coded/functor_ho_inst.{m,exp}:
tests/hard_coded/functor_ho_inst_2.{m,exp}:
tests/hard_coded/functor_ho_inst_excp.{m,exp}:
tests/hard_coded/functor_ho_inst_excp_2.{m,exp}:
Test the new functionality.
tests/invalid/combined_ho_type_inst.{m,err_exp}:
tests/invalid/combined_ho_type_inst_2.{m,err_exp}:
Test that we don't allow the new types where they are not permitted,
or are incomplete.
tests/invalid/functor_ho_inst_bad.{m,err_exp}:
tests/invalid/functor_ho_inst_bad_2.{m,err_exp}:
tests/invalid/functor_ho_inst_bad_3.{m,err_exp}:
Test that the argument inst information is enforced as required.
tests/hard_coded/Mmakefile:
tests/invalid/Mmakefile:
Run the new test cases.
|
||
|
|
cc9912faa8 |
Don't import anything in packages.
Packages are modules whose only job is to serve as a container for submodules. Modules like top_level.m, hlds.m, parse_tree.m and ll_backend.m are packages in this (informal) sense. Besides the include_module declarations for their submodules, most of the packages in the compiler used to import some modules, mostly other packages whose component modules their submodules may need. For example, ll_backend.m used to import parse_tree.m. This meant that modules in the ll_backend package did not have to import parse_tree.m before importing modules in the parse_tree package. However, this had a price. When we add a new module to the parse_tree package, parse_tree.int would change, and this would require the recompilation of ALL the modules in the ll_backend package, even the ones that did NOT import ANY of the modules in the parse_tree package. This happened even at one remove. Pretty much all modules in every one of the backend have to import one or more modules in the hlds package, and they therefore have import hlds.m. Since hlds.m imported transform_hlds.m, any addition of a new middle pass to the transform_hlds package required the recompilation of all backend modules, even in the usual case of the two having nothing to do with each other. This diff removes all import_module declarations from the packages, and replaces them with import_module declarations in the modules that need them. This includes only a SUBSET of their child modules and of the non-child modules that import them. |