mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-17 10:23:46 +00:00
083d376e6598628362ee91c2da170febd83590f4
107 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
de47db1ab7 |
Fix a comment.
compiler/switch_util.m:
As above.
|
||
|
|
f2c99cc0b2 |
More spelling fixes, etc.
compiler/cse_detection.m:
compiler/ml_lookup_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_target_util.m:
compiler/switch_util.m:
As above.
|
||
|
|
13a03cc5e5 | Clarify a comment. | ||
|
|
10a8473cc2 |
Simplify the management of smart indexing.
compiler/switch_util.m:
Simplify the interface of the find_switch_category predicate.
Instead of returning (a) a *smart switch category*, and (b) a flag
that says whether that category may be used, simply return
a *switch category*, which includes a non-smart switch category,
the if-then-else chain.
Give some data constructors in the switch_category type names that
clarify the differences between them.
Move the type_ctor_cat_to_switch_cat function just after its only caller.
compiler/ml_switch_gen.m:
compiler/switch_gen.m:
Flatten the switches on the return values of find_switch_category.
Merge arms of these switches that handle dumb switches and switches
on floats, because they are both implemented as if-then-else chains.
In ml_switch_gen.m, inline the ml_gen_smart_int64_switch predicate,
which made only one decision, at its only call site.
Add XXXs that point out opportunities for further simplification.
compiler/ml_lookup_switch.m:
Rename a predicate to conform to the new names of switch categories.
|
||
|
|
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.
|
||
|
|
8ebe125a6a |
Introduce var_table.m.
Most compiler passes need to know both the names and the types
of the variables they operate on. Until now, they had to pass along
two separate data structures for that, the varset and the vartypes,
and many operations required looking a variable up in both of these.
The var table is a single data structure that records for each variable
- its name, as the varset has traditionally done,
- its type, as the vartypes has traditionally done,
- the is_dummy_type flag which says whether its type is a dummy type,
which traditionally had to computed afresh at each lookup.
Switch the MLDS code generator to use var_tables instead of varsets and
vartypes. The code generator often needs to know the name and the type
of a variable at the same time, and it often needs to know which variables'
types are dummies, often enough that precomputing this info should be a win.
compiler/var_table.m:
Add this new module which defines the var_table.
Its operations are modelled after the operation in var_types.m.
compiler/hlds.m:
compiler/notes/compiler_design.html:
Add the new module to the hlds package.
compiler/prog_type.m:
compiler/type_util.m:
Move the is_dummy_type from type_util.m, which is in the
check_hlds package, to prog_type.m, which in the parse_tree package,
to avoid having this part of the hlds package depend on check_hlds.
(It already depends on parse_tree, for a lot of different things.)
Given a function and a predicate that each took a vartypes arg,
make new versions that take a var_table arg instead.
Rationalize the argument list of the function.
compiler/ml_gen_info.m:
Replace the varset and vartypes fields of the ml_gen_info with a
var_table field.
compiler/ml_code_util.m:
Replace code that used to operate on varsets and vartypes with code
that operates on var_tables.
Create new versions of a few operations to exploit the info in var_tables.
Give some predicates more meaningful names.
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_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_lookup_switch.m:
compiler/ml_proc_gen.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:
Replace code that used to operate on varsets and vartypes with code
that operates on var_tables.
In ml_switch_gen.m and ml_tag_switch.m, put some predicates' arguments
into an reasonable order by moving related args next to each other.
compiler/vartypes.m:
Delete an operation that was only needed in the MLDS backend,
in code that this diff replaces.
compiler/switch_util.m:
Put the larger input first in the arg list of a predicate.
compiler/closure_gen.m:
compiler/code_info.m:
compiler/code_loc_dep.m:
compiler/export.m:
compiler/lambda.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/llds.m:
compiler/llds_out_instr.m:
compiler/mark_tail_calls.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/stack_alloc.m:
compiler/stack_layout.m:
compiler/tag_switch.m:
compiler/term_constr_util.m:
compiler/tupling.m:
compiler/unify_gen.m:
compiler/unify_gen_deconstruct.m:
compiler/var_locn.m:
Conform to the changes above.
|
||
|
|
9012395ec2 |
Don't let ml_tag_switch.m generate duplicate fields.
This fixes the second problem identified by Mantis bug #548. compiler/ml_tag_switch.m: Detect the circumstances in which this problem would arise. In such cases, simply fail, and let ml_switch_gen.m fall back to implementing the switch as an if-then-else chain. compiler/ml_switch_gen.m: Implement that fallback. compiler/switch_util.m: The new code in ml_tag_switch.m needs to thread a fourth piece of state through the predicate it passes to group_cases_by_ptag, so change its argument list to accommodate such predicates. And since some other modules pass the same predicates to group_cases_by_ptag and string_binary_cases, make the same change in the argument list of that predicate as well. Delete one stray comment, and note that another comment seems misplaced. compiler/ml_string_switch.m: compiler/string_switch.m: compiler/switch_case.m: compiler/tag_switch.m: Conform to the changes in switch_util.m. tests/hard_coded/bug548.exp: tests/hard_coded/Mmakefile: Enable the previously-added test case for Mantis #548, after add an .exp file for it. |
||
|
|
09aff57259 |
Represent "is this a subtype" using a bespoke type.
compiler/prog_data.m:
compiler/hlds_data.m:
Use a new type, maybe_subtype, to say whether a du type is a subtype.
compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/add_type.m:
compiler/check_parse_tree_type_defns.m:
compiler/comp_unit_interface.m:
compiler/decide_type_repn.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/hlds_out_module.m:
compiler/ml_type_gen.m:
compiler/mlds.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/parse_type_defn.m:
compiler/prog_type.m:
compiler/recompilation.usage.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
Conform to the changes above.
|
||
|
|
254cd500bf |
Add bespoke type for du types' details.
compiler/hlds_data.m:
As above. The other kinds of types already had bespoke types
for *their* details.
compiler/add_type.m:
compiler/du_type_layout.m:
Instead of passing values of the hlds_type_body with an inst
that said they were du types, pass values of the new types instead,
which is significantly simpler.
compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/dead_proc_elim.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/equiv_type_hlds.m:
compiler/foreign.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
compiler/mlds.m:
compiler/mode_util.m:
compiler/post_term_analysis.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_ite.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/unify_proc.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
Conform to the changes above.
|
||
|
|
0925d052d8 |
Make type_range also succeed for discontiguous range of enum values.
compiler/switch_util.m:
Make type_range succeed for a subtype where the constructors are
assigned enum values in a discontiguous range. I checked that its
callers do not expect all values in the range to necessarily
be used by the type.
Clarify find_int_lookup_switch_params a bit.
Clarify comments.
compiler/dense_switch.m:
Use need_range_check type instead of can_fail in dense_switch_info,
as that is what the field actually means.
compiler/ml_simplify_switch.m:
Use need_range_check type instead of bool.
tests/hard_coded/dense_lookup_switch_non2.m:
Delete obsoleted XXX.
|
||
|
|
95f59cf7c9 |
Fix lookup switches on subtype enums.
compiler/switch_util.m:
Rename dont_need_bit_vec_check variant of need_bit_vec_check to
dont_need_bit_vec_check_no_gaps.
Add dont_need_bit_vec_check_with_gaps (see below).
Make type_range return the correct min and max values used by a
subtype enum type. For now, it fails unless the range of values
is contiguous.
Make find_int_lookup_switch_params use the min and max values for a
type returned by type_range, not assuming 0 to the max value.
Make find_int_lookup_switch_params return
dont_need_bit_vec_check_with_gaps when a bit vector check is not
required before a table lookup, yet the table is expected to contain
dummy rows. This is the case for a cannot_fail switch on a subtype
enum type type, where the subtype does not use some values between
the min and max values.
compiler/dense_switch.m:
Make tagged_case_list_is_dense_switch use the min and max values for
a type returned by type_range, not assuming 0 to the max value.
compiler/ml_lookup_switch.m:
Expect the generated lookup table to contain dummy rows or not
depending on dont_need_bit_vec_check_{with_gaps,no_gaps}.
Conform to change to need_bit_vec_check.
compiler/lookup_switch.m:
compiler/ml_string_switch.m:
Conform to change to need_bit_vec_check.
tests/hard_coded/Mmakefile:
tests/hard_coded/dense_lookup_switch4.exp:
tests/hard_coded/dense_lookup_switch4.m:
tests/hard_coded/dense_lookup_switch_non2.exp:
tests/hard_coded/dense_lookup_switch_non2.m:
Add test cases.
|
||
|
|
74a31ba8ef |
Parse and check subtype definitions.
This is the first step towards implementing a subtypes feature.
It introduces type definitions of the form
:- type subtype =< supertype ---> body.
Later, terms of a subtype should share a data representation with their
supertype, and it will be possible to convert terms between two types
that share "base types" using a coerce operation.
doc/reference_manual.texi:
Add documentation for subtypes.
Add documentation for a proposed `coerce' operation, commented out
for now.
Add "=<" to the list of reserved type names.
compiler/hlds_data.m:
Add supertype field to hlds_du_type.
compiler/prog_data.m:
Add du_supertype field to type_details_du.
Add comment for future work.
compiler/parse_type_defn.m:
Parse subtype definitions.
Check that variables which occur in the "=< supertype" part
also occur on the left hand side of the subtype definition.
compiler/parse_type_name.m:
Add a new context for why_no_ho_inst_info.
Add "=<" to is_known_type_name, i.e. prevent the user from defining
a type of that name (any longer).
compiler/add_type.m:
Rename add_du_ctors_check_foreign_type_for_cur_backend to
add_du_ctors_check_subtype_check_foreign_type.
In add_du_ctors_check_subtype_check_foreign_type, check that
subtype definitions satisfy the conditions documented in the
reference manual.
compiler/make_hlds_passes.m:
Conform to previous renaming.
compiler/comp_unit_interface.m:
Follow supertypes when computing the required type constructors
whose definitions need to be kept in the implementation section
of a .int file.
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
Replace equivalence types in supertypes.
compiler/module_qual.qualify_items.m:
Perform module qualification in supertypes.
compiler/hlds_out_module.m:
Write out the "=< supertype" part of subtype definitions.
compiler/parse_tree_out.m:
Write out the "=< supertype" part of subtype definitions.
compiler/recompilation.usage.m:
Follow supertypes when finding used items.
compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/check_parse_tree_type_defns.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/dead_proc_elim.m:
compiler/decide_type_repn.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/du_type_layout.m:
compiler/foreign.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
compiler/post_term_analysis.m:
compiler/prog_type.m:
compiler/recompilation.check.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_ite.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
Conform to HLDS changes.
Add comments for future work.
tests/invalid/Mmakefile:
tests/invalid/subtype_abstract.err_exp:
tests/invalid/subtype_abstract.m:
tests/invalid/subtype_circular.err_exp:
tests/invalid/subtype_circular.m:
tests/invalid/subtype_ctor_arg.err_exp:
tests/invalid/subtype_ctor_arg.m:
tests/invalid/subtype_eqv.err_exp:
tests/invalid/subtype_eqv.m:
tests/invalid/subtype_exist_constraints.err_exp:
tests/invalid/subtype_exist_constraints.m:
tests/invalid/subtype_exist_vars.err_exp:
tests/invalid/subtype_exist_vars.m:
tests/invalid/subtype_foreign.err_exp:
tests/invalid/subtype_foreign.m:
tests/invalid/subtype_foreign_supertype.err_exp:
tests/invalid/subtype_foreign_supertype.m:
tests/invalid/subtype_foreign_supertype2.err_exp:
tests/invalid/subtype_foreign_supertype2.err_exp2:
tests/invalid/subtype_foreign_supertype2.m:
tests/invalid/subtype_ho.err_exp:
tests/invalid/subtype_ho.m:
tests/invalid/subtype_invalid_supertype.err_exp:
tests/invalid/subtype_invalid_supertype.m:
tests/invalid/subtype_not_subset.err_exp:
tests/invalid/subtype_not_subset.m:
tests/invalid/subtype_syntax.err_exp:
tests/invalid/subtype_syntax.m:
tests/invalid_submodules/Mercury.options:
tests/invalid_submodules/Mmakefile:
tests/invalid_submodules/subtype_submodule.err_exp:
tests/invalid_submodules/subtype_submodule.m:
tests/valid/Mmakefile:
tests/valid/subtype_basic.m:
Add test cases.
|
||
|
|
181ada0dbf |
Avoid -O<n> resetting previously set options.
This implements Mantis feature request #495. NEWS: Announce the change. compiler/optimization_options.m: A new module for managing optimization options. It defines a separate bespoke type for every boolean optimization option to make it harder to confuse them. It defines a tuple type (opt_tuple) for accessing optimization options quickly. It implements the turning on (but NOT turning off) of optimizations when a given optimization level is selected. tools/make_optimization_options_middle: tools/make_optimization_options_db: The script that generates the meat of optimization_options.m, and the database of option names, kinds and initial values that it uses as its input. The script also generates some code for the special_handler predicate in compiler/options.m. tools/make_optimization_options_start: tools/make_optimization_options_end: The handwritten initial and final parts of optimization_options.m. tools/make_optimization_options: The script that pulls these parts together to form optimization_options.m. compiler/options.m: Make every optimization option a special option, to be handled by the special_handler predicate. That handling consists of simply adding a representation of the option to the end of a cord of optimization options, to be processed later by optimization_options.m. That processing will record the values of these options in the opt_tuple, which is where every other part of the compiler should get them from. Change the interface of special_handler to make the above possible. Add an "optopt_" (optimization option) prefix to the name of every optimization option, to make them inaccessible to the rest of the compiler under their old name, and thus help enforce the switch to using the opt_tuple. Any access to these options to look up their values would fail anyway, since the option data would no longer be e.g. bool(yes), but bool_special, but the name change makes this failure happen at compile time, not runtime. Reclassify a few options to make the above make sense. Some options (unneeded_code_debug, unneeded_code_debug_pred_name, and common_struct_preds) were classified as oc_opt even though they control only the *debugging* of optimizations, while some options (c_optimize and inline_alloc) were not classified as oc_opt even though we do set them automatically at some optimization levels. Delete the opt_level_number option, since it was not used anywhere. Delete the code for handling -ON and --opt-space, since that is now done in optimization_options.m. Add some XXXs. compiler/handle_options.m: Switch to using getopt_io.process_options_userdata_se, as required by the new interface of the special_handler in options.m. In the absence of errors, invoke optimization_options.m to initialize the opt_tuple. Then update the opt_tuple incrementally when processing option implications that affect optimization options. compiler/globals.m: Put the opt_tuple into a new field of the globals structure. compiler/accumulator.m: compiler/add_pragma_type_spec.m: compiler/add_trail_ops.m: compiler/code_info.m: compiler/code_loc_dep.m: compiler/compile_target_code.m: compiler/const_struct.m: compiler/deforest.m: compiler/dep_par_conj.m: compiler/disj_gen.m: compiler/erl_code_gen.m: compiler/format_call.m: compiler/global_data.m: compiler/grab_modules.m: compiler/higher_order.m: compiler/hlds_pred.m: compiler/inlining.m: compiler/intermod.m: compiler/ite_gen.m: compiler/jumpopt.m: compiler/libs.m: compiler/llds_out_code_addr.m: compiler/llds_out_data.m: compiler/llds_out_file.m: compiler/llds_out_instr.m: compiler/llds_out_util.m: compiler/matching.m: compiler/mercury_compile_front_end.m: compiler/mercury_compile_llds_back_end.m: compiler/mercury_compile_main.m: compiler/mercury_compile_middle_passes.m: compiler/mercury_compile_mlds_back_end.m: compiler/ml_disj_gen.m: compiler/ml_gen_info.m: compiler/ml_lookup_switch.m: compiler/ml_optimize.m: compiler/ml_proc_gen.m: compiler/ml_simplify_switch.m: compiler/ml_switch_gen.m: compiler/ml_unify_gen_construct.m: compiler/optimize.m: compiler/pd_util.m: compiler/peephole.m: compiler/polymorphism.m: compiler/proc_gen.m: compiler/simplify_goal_call.m: compiler/simplify_goal_scope.m: compiler/simplify_info.m: compiler/simplify_proc.m: compiler/simplify_tasks.m: compiler/stack_layout.m: compiler/stack_opt.m: compiler/switch_gen.m: compiler/switch_util.m: compiler/tag_switch.m: compiler/tupling.m: compiler/unify_gen_construct.m: compiler/unneeded_code.m: compiler/unused_args.m: Conform to the changes above, mostly by looking up optimization options in the opt_tuple. In some places, replace bools containing optimization options with the bespoke type of that specific optimization option. library/getopt_template: Fix a bug that screwed up an error message. The bug happened when processing a --file option. If one of the options in the file was a special option whose special handler failed, the code handling that failing option returned both an error indication, and the rest of the argument list read in from the file. The code handling the --file option then *ignored* the error indication from the failed special option, and returned an error message of its own complaining about the unconsumed remaining arguments in the file, believing them to be non-option arguments, even though these arguments were never looked it to see if they were options. The fix is for the code handling --flag options to check whether the code processing the file contents found any errors, and if so, return that error *without* looking at the list of remaining arguments. In an unrelated change, factor out a duplicate call. |
||
|
|
36c2000516 |
Add the one_or_more and one_or_more_map modules to the library.
library/one_or_more.m:
We used to have a type named one_or_more in the list module representing
nonempty lists. It had literally just two predicates and two functions
defined on it, three of which did conversions to and from lists, which
limited their usefulness.
This new module is the new home of the one_or_more type, together with
a vastly expanded set of utility predicates and functions. Specifically,
it implements every operation in list.m which makes sense for nonempty
lists.
library/list.m:
Delete the code moved over to one_or_more.m.
library/one_or_more_map.m:
This new module is a near copy of multi_map.m, with the difference being
that while the multi_map type defined in multi_map.m maps each key
to a list(V) of values (a list that happens to always be nonempty),
the one_or_more_map type defined in one_or_more_map.m maps each key
to a one_or_more(V) of values (which enforces the presence of at least
one value for each key in the type).
library/map.m:
Mention the existence of one_or_more_map.m as well as multi_map.m.
library/MODULES_DOC:
library/library.m:
List the new modules as belonging to the standard library.
NEWS:
Mention the new modules, and the non-backwards-compatible changes to
list.m.
compiler/*.m:
Import the one_or_more module when needed.
tests/hard_coded/test_one_or_more_chunk.{m,exp}:
Test the one predicate in one_or_more.m that is non-trivially different
from the corresponding predicate in list.m: the chunk predicate.
tests/hard_coded/Mmakefile:
Enable the new test case.
|
||
|
|
b6d4d3f30d | Fix more issues reported by --warn-inconsistent-pred-order-clauses. | ||
|
|
e9430b115a |
Prep for recording simple type representations in .int3 files.
compiler/decide_type_repn.m:
New module for computing the set of type representation items
to put into the interface files of a module. For now, it generates
this information only for .int3 files.
compiler/parse_tree.m:
compiler/notes/compiler_design.html:
Add the new module to the parse_tree package.
compiler/comp_unit_interface.m:
Invoke the new module to add type representation items to .int3 files
if the experiment option has the right value. Give it the information
it needs to do its job.
compiler/add_foreign_enum.m:
Export a predicate for use by decide_type_repn.m. Maybe eventually
it should be *moved* to decide_type_repn.m.
compiler/hlds_data.m:
compiler/prog_data.m:
Change the representation of lists of constructors in a type
from lists, which can be empty, with one_or_more, which cannot.
This encodes the invariant that a type constructor cannot have
zero data constructors in the structure of the type.
compiler/prog_item.m:
Change the representation of lists of constructors in a type
from lists, which can be empty, with one_or_more, which cannot.
This encodes the invariant that a type constructor cannot have
zero data constructors in the structure of the type.
Include information about assertions in type representation items
about foreign types.
Do not record whether a type whose representation item says its values
are guaranteed to be word aligned is a Mercury type or a foreign type.
We generate such items only for Mercury types; for foreign types,
their assertions will contain that information. We need this separation
because when we generate .int3 files, we don't the backend that we will
eventually generate code for, and thus do not know whether a given
foreign type declaration is in effect on that backend or not.
compiler/parse_tree_out.m:
Fix the printing of type representation items.
compiler/prog_type.m:
Conform to the changes above, and delete an unused predicate.
compiler/parse_type_repn.m:
Factor out some common code.
Fix an old bug about yes/no vs du_repn/no_du_repn.
Conform to the changes above.
compiler/parse_pragma.m:
Export a predicate for parse_type_repn.m.
Note a possible improvement.
Conform to the changes above.
compiler/add_special_pred.m:
compiler/add_type.m:
compiler/check_typeclass.m:
compiler/det_report.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/mode_util.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out_pragma.m:
compiler/parse_type_defn.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_util.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
Conform to the changes above.
compiler/simplify_goal_ite.m:
Add a comment.
compiler/canonicalize_interface.m:
compiler/get_dependencies.m:
Do not abort when seeing type representation items.
compiler/mmakefiles.m:
Delete a predicate that this diff adds to list.m.
library/list.m:
Add new predicates to convert from one_or_more to list
and vice versa.
NEWS:
Announce the new predicates.
library/bimap.m:
library/map.m:
library/tree234.m:
Expand a comment.
|
||
|
|
ca9d664391 |
Compute limits of integer tags for switches over all integer types.
This is a step towards getting smart indexing working for integer switches on
types other than 'int'.
compiler/switch_util.m:
Extend the maybe_int_switch_info/0 type to represent tag limits for
switches on all of the integer types.
Generalise the code that computes those limits to handle all builtin
integer types.
compiler/ml_switch_gen.m:
compiler/switch_gen.m:
Conform to the above change.
|
||
|
|
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.
|
||
|
|
cb4454ac28 |
Extend local arg packing to single-ctor types.
compiler/du_type_layout.m:
For the last three weeks, we have been packing subword-sized arguments
next to a local sectag (if the relevant option was set). However, we
did this only for types with two or more function symbols. This diff
extends this optimization to apply also to types with only one function
symbol, whose representation is decided by a separate piece of code.
Factor out a piece of code to be usable from both of those pieces of code.
Delete a sanity test. By not failing for the last three weeks,
it has done its job.
compiler/hlds_data.m:
Replace the shared_local_tag_with_args cons_tag added in that change
about three weeks ago with the local_args_tag cons_tag, which is more
general, in that it can indicate whether the function symbol is the only
one in its type or not. (We need to know this when generating code
for deconstruction unifications.)
compiler/bytecode_gen.m:
compiler/export.m:
compiler/ml_switch_gen.m:
compiler/ml_type_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/switch_util.m:
compiler/type_ctor_info.m:
compiler/unify_gen_construct.m:
compiler/unify_gen_deconstruct.m:
compiler/unify_gen_test.m:
Conform to the changes above.
|
||
|
|
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.
|
||
|
|
860f54cafd |
Make offset tracking work for C# (and Java).
My recent diff adding position information to the representation of constructor
arguments assumed that the remote secondary tag, if any, was always added
to the start of the memory cell by the compiler module handling unifications.
However, for the C# and Java grades, secondary tags are in fact added
by a class constructor, so the offsets of the arguments of such cells
were off by one, leading to an assertion failure in the compiler.
compiler/hlds_data.m:
Fix the above problem by recording with each remote secondary tag
whether it is added by the unify code or by the constructor.
compiler/du_type_layout.m:
Set the new field in remote secondary tags.
compiler/ml_unify_gen.m:
compiler/unify_gen.m:
Use the new field to decide whether a remote secondary tag counts
as occupying the first word of its memory cell.
compiler/bytecode_gen.m:
compiler/export.m:
compiler/lco.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/switch_util.m:
compiler/type_ctor_info.m:
Conform to the change in hlds_data.m.
|
||
|
|
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.
|
||
|
|
15aa457e12 | Delete $module arg from calls to unexpected. | ||
|
|
76cd5898d8 |
Give a type a less ambiguous name.
compiler/hlds_data.m:
Rename the type tag_bits as ptag, since it stands for primary tags
(whose standard abbreviation inside the compiler is ptag).
compiler/bytecode.m:
compiler/ml_tag_switch.m:
compiler/ml_unify_gen.m:
compiler/switch_util.m:
compiler/tag_switch.m:
compiler/unify_gen.m:
Conform to the change in hlds_data.m.
|
||
|
|
54ea0dbffc |
Fix a problem in switch code generation.
This problem is the cause of Mantis bug #452. compiler/switch_util.m: Don't require a bit vector check for cannot_fail switches, even in cases where the switch arms do not completely cover the range of possible values in the switched-on variable's type; if the switch is cannot_fail, then the switch variable cannot have any of the "missing" values when the switch is entered. tests/hard_coded/bug452.{m,exp}: A regression test for the bug. tests/hard_coded/Mmakefile: Enable the new test case. |
||
|
|
63572bc9a8 |
Fix bug #449 - switches on 64-bit integers in the Java grade.
Switches on 64-bit integers in the Java grade are causing us to generate
invalid Java code because Java's switch statement does not work with 64-bit
integers. (This limitation is apparently built into the JVM.)
Fix this for now by generating if-then-else chains for switches on 64-bit
integers. We can almost certainly do better, but that is future work.
compiler/switch_util.m:
Add a separate switch category for switches on 64-bit integer types.
compiler/switch_gen.m:
For the low-level C backend, treat switches on 64-bit integers as
other switches on atomic types.
compiler/ml_target_util.m:
Add a function that returns whether the target language supports
switching on 64-bit integers. Add another that allows us to
test whether switches on a given integer type are supported by
a given target language.
compiler/ml_switch_gen.m:
compiler/ml_simplify_switch.m:
Use the above functions to only generate switches on 64-bit integers
as target language switches if the target language supports switches
on 64-bit integers (C# and C do; Java does not).
|
||
|
|
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.
|
||
|
|
7eadb75739 | Iterate over constructors directly. | ||
|
|
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.
|
||
|
|
7c42aa1aa2 |
Use a separate type to describe integer tags.
compiler/hlds_data.m
Use a separate type to describe integer tags and parameterise
the int_tag functor of the cons_tag/0 type by that new type.
compiler/bytecode_gen.m:
compiler/dense_switch.m:
compiler/du_type_layout.m:
compiler/export.m:
compiler/hlds_code_util.m:
compiler/make_tags.m:
compiler/ml_type_gen.m:
compiler/ml_switch_gen.m:
compiler/ml_unify_gen.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/type_ctor_info.m:
compiler/unify_gen.m:
Conform to the above change.
compiler/ml_code_util.m:
Add a utility function for use by the above.
|
||
|
|
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.
|
||
|
|
2c9eb10bcd |
Undo workrounds that aren't needed anymore.
configure.ac:
Check whether the installed compiler is new enough to contain the fixes
that makes these workrounds unnecessary.
compiler/Mercury.options:
Undo the workaround for a bug in --warn-unused-imports.
compiler/switch_util.m:
Undo the workaround for the lack of implicit separate scopes
for trace-goal-only variables.
|
||
|
|
2ac8465659 |
Make the code adding new types to the HLDS readable.
The motivation for this diff was that I wanted the compiler to generate
a warning if a module declared the same type twice. (During the cleanup
of unify_proc.m I did recently, I found and fixed such a duplicate
declaration.)
compiler/add_type.m:
The old code of module_add_type_defn was not just long (210+ lines),
it is also very complex.
Part of this complexity was sort-of justified. It dealt with adding
three separate kinds of item_type_defns: abstract type "definitions",
which are actually declarations; the definitions of Mercury types,
and the definitions of foreign types. A single type could have more than
one of these (e.g. declaration and a definition, or a Mercury definition
and a foreign definition), and it had to be prepared to process these
in any order.
Part of this complexity was self-inflicted. The parts of the predicate
that dealt with the same kind of definition were not always next to each
other, and for some parts, it wasn't even clear *what* kind of definition
it was dealing with. It did the same tests on both the old and updated
versions of definitions, when those definitions were guaranteed to be
identical; the "updating" predicate was a no-op. And it used completely
different code for detecting and handling related errors.
This diff fixes the above problems. It separates the task of adding
an item_type_defn to the HLDS into three subtasks, done in three separate
predicates: adding type declarations, adding Mercury definitions, and
adding foreign definitions. It specializes each predicate to its task,
and simplifies its decision flow. It also delegates the creation of
(most) error messages to separate predicates. Together, these changes
make each of module_add_type_defn_{abstract,mercury,foreign} easily
understandable.
Generate a warning if a type is declared twice, i.e. if e.g.
":- type x." is followed by another ":- type x.".
Call module_info_incr_errors to register the presence of errors in just
one central place. (Before, some of the places that generated error
messages incremented the error count, and some places didn't.)
Improve the wording of some error messages.
Refer to type names in error messages by unqualified sym_names
in cases where the module qualifier being elided is obvious from
the name of the module being compiled.
Add documentation.
Add descriptions of potential future improvements.
Add some XXXs at places that I think deserve them.
Give some predicates and variables better names.
compiler/prog_data.m:
Change the parse tree representation of type definitions by
explicitly specifying a type for storing the contents of each kind
of type definition.
compiler/hlds_data.m:
Give a predicate a better name.
Use one of the new types in prog_data.m in the HLDS version of type
definitions, to minimize differences between the parse tree and HLDS
versions.
compiler/add_foreign_enum.m:
compiler/add_pragma.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/foreign.m:
compiler/get_dependencies.m:
compiler/hlds_code_util.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/make_tags.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/module_qual.qualify_items.m:
compiler/parse_pragma.m:
compiler/parse_tree_out.m:
compiler/parse_type_defn.m:
compiler/post_term_analysis.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_ite.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
Conform to the changes in prog_data.m.
library/io.m:
library/store.m:
Delete duplicate type declarations that add_type.m now complains about.
tests/invalid/bad_foreign_type.{m,err_exp}:
Extend this test to test the new warning.
Expect the updated versions of some error messages.
tests/invalid/extra_info_prompt.err_exp:
tests/invalid/foreign_type_visibility.err_exp:
tests/invalid/user_eq_dummy.err_exp:
Expect the updated versions of some error messages.
|
||
|
|
c45d34a837 |
Use explicit streams in several modules.
compiler/export.m:
compiler/hlds_dependency_graph.m:
compiler/hlds_goal.m:
compiler/hlds_out_goal.m:
compiler/switch_util.m:
As above.
|
||
|
|
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.
|
||
|
|
edaf0b64e4 | Convert (C->T;E) to (if C then T else E). | ||
|
|
62ec97d443 |
Report imports shadowed by other imports.
If a module has two or more import_module or use_module declarations
for the same module, (typically, but not always, one being in its interface
and one in its implementation), generate an informational message about
each redundant declaration if --warn-unused-imports is enabled.
compiler/hlds_module.m:
We used to record the set of imported/used modules, and the set of
modules imported/used in the interface of the current module. However,
these sets
- did not record the distinction between imports and uses;
- did not allow distinction between single and multiple imports/uses;
- did not record the locations of the imports/uses.
The first distinction was needed only by module_qual.m, which *did*
pay attention to it; the other two were not needed at all.
To generate messages for imports/uses shadowing other imports/uses,
we need all three, so change the data structure storing such information
for *direct* imports to one that records all three of the above kinds
of information. (For imports made by read-in interface and optimization
files, the old set of modules approach is fine, and this diff leaves
the set of thus *indirectly* imported module names alone.)
compiler/unused_imports.m:
Use the extra information now available to generate a
severity_informational message about any import or use that is made
redundant by an earlier, more general import or use.
Fix two bugs in the code that generated warnings for just plain unused
modules.
(1) It did not consider that a use of the builtin type char justified
an import of char.m, but without that import, the type is not visible.
(2) It scanned cons_ids in goals in procedure bodies, but did not scan
cons_ids that have been put into the const_struct_db. (I did not update
the code here when I added the const_struct_db.)
Also, add a (hopefully temporary) workaround for a bug in
make_hlds_passes.m, which is noted below.
However, there are at least three problems that prevent us from enabling
--warn-unused-imports by default.
(1) In some places, the import of a module is used only by clauses for
a predicate that also has foreign procs. When compiled in a grade that
selects one of those foreign_procs as the implementation of the predicate,
the clauses are discarded *without* being added to the HLDS at all.
This leads unused_imports.m to generate an uncalled-for warning in such
cases. To fix this, we would need to preserve the Mercury clauses for
*all* predicates, even those with foreign procs, and do all the semantic
checks on them before throwing them away. (I tried to do this once, and
failed, but the task should be easier after the item list change.)
(2) We have two pieces of code to generate import warnings. The one in
unused_imports.m operates on the HLDS after type and mode checking,
while module_qual.m operates on the parse tree before the creation of
the HLDS. The former is more powerful, since it knows e.g. what types and
modes are used in the bodies of predicates, and hence can generate warnings
about an import being unused *anywhere* in a module, as opposed to just
unused in its interface.
If --warn-unused-imports is enabled, we will get two separate set of
reports about an interface import being unused in the interface,
*unless* we get a type or mode error, in which case unused_imports.m
won't be invoked. But in case we do get such errors, we don't want to
throw away the warnings from module_qual.m. We could store them and
throw them away only after we know we won't need them, or just get
the two modules to generate identical error_specs for each warning,
so that the sort_and_remove_dups of the error specs will do the
throwing away for us for free, if we get that far.
(3) The valid/bug100.m test case was added as a regression test for a bug
that was fixed in module_qual.m. However the bug is still present in
unused_imports.m.
compiler/make_hlds_passes.m:
Give hlds_module.m the extra information it now needs for each item_avail.
Add an XXX for a bug that cannot be fixed right now: the setting of
the status of abstract instances to abstract_imported. (The "abstract"
part is correct; the "imported" part may not be.)
compiler/intermod.m:
compiler/try_expand.m:
compiler/xml_documentation.m:
Conform to the change in hlds_module.m.
compiler/module_qual.m:
Update the documentation of the relationship of this module
with unused_imports.m.
compiler/hlds_data.m:
Document a problem with the status of instance definitions.
compiler/hlds_out_module.m:
Update the code that prints out the module_info to conform to the change
to hlds_module.m.
Print status information about instances, which was needed to diagnose
one of the bugs in unused_imports.m. Format the output for instances
nicer.
compiler/prog_item.m:
Add a convenience predicate.
compiler/prog_data.m:
Remove a type synonym that makes things harder to understand, not easier.
compiler/modules.m:
Delete an XXX that asks for the feature this diff implements.
Add another XXX about how that feature could be improved.
compiler/Mercury.options.m:
Add some more modules to the list of modules on which the compiler
should be invoked with --no-warn-unused-imports.
compiler/*.m:
library/*.m:
mdbcomp/*.m:
browser/*.m:
deep_profiler/*.m:
mfilterjavac/*.m:
Delete unneeded imports. Many of these shadow other imports, and some
are just plain unneeded, as shown by --warn-unused-imports. In a few
modules, there were a *lot* of unneeded imports, but most had just
one or two.
In a few cases, removing an import from a module, because it *itself*
does not need it, required adding that same import to those of its
submodules which *do* need it.
In a few cases, conform to other changes above.
tests/invalid/Mercury.options:
Test the generation of messages about import shadowing on the existing
import_in_parent.m test case (although it was also tested very thoroughly
when giving me the information needed for the deletion of all the
unneeded imports above).
tests/*/*.{m,*exp}:
Delete unneeded imports, and update any expected error messages
to expect the now-smaller line numbers.
|
||
|
|
c3fd4a0ab3 |
Document where the target char value range is used.
Explicitly use the target's char value range in the appropriate places instead of the host's char value range. The range of char values is the same for all existing targets, though, so this change mainly serves as documentation. compiler/string_encoding.m: Add `target_char_range' predicate. compiler/switch_util.m: compiler/type_util.m: Use the target char value range where appropriate. Delete XXXs. |
||
|
|
d041b83943 |
Implement string switches via tries for the MLDS backend.
The code we emit to decide which arm of the switch is selected looks like this:
case_num = -1;
switch (MR_nth_code_unit(switchvar, 0)) {
case '98':
switch (MR_nth_code_unit(switchvar, 1)) {
case '99':
if (MR_offset_streq(2, switchvar, "abc"))
case_num = 0;
break;
case '100':
if (MR_offset_streq(2, switchvar, "aceg"))
case_num = 1;
break;
}
break;
case '99':
if (MR_offset_streq(2, switchvar, "bbb"))
case_num = 2;
break;
}
The part that acts on this will look like this for lookup switches:
if (case_num < 0)
succeeded = MR_FALSE;
else {
outvar1 = vector_common[case_num].f1;
...
outvarn = vector_common[case_num].fn;
succeeded = MR_TRUE;
}
and like this for non-lookup switches:
switch (case_num) {
case 0:
<code for case 0>
break;
...
case n:
<code for case n>
break;
default: /* if the switch is can_fail */
<code for failure>
break;
}
compiler/ml_string_switch.m:
Implement both non-lookup and lookup string switches via tries,
along the lines shown above.
compiler/ml_switch_gen.m:
Invoke the predicates that implement string switches via tries
in the circumstances in which option values call for them.
For now, we generate tries only for the C backend. Once the
problems identified for mlds_to_{cs,java,managed} below are fixed,
we can enable them on those backends as well.
compiler/options.m:
doc/user_guide.texi:
Add an option that governs the minimum size of trie switches.
compiler/ml_lookup_switch.m:
Factor out the code common to the implementation of all model-non
lookup switches, both in ml_lookup_switch.m and ml_string_switch.m,
and put it all into a new exported predicate.
The previously existing MLDS implementation methods for lookup switches
all build their lookup tables from maps that maps each cons_id
in the switch cases to the values of the output arguments of those cases.
For switch cases that apply to more than one cons_id, this map had
one entry for each of those cons_ids. For tries, we need a map
from *case ids*, not *cons ids* to the outputs. Since it is
easier to convert the one-to-one case_id->outputs map to the
many-to-one cons_id->outputs map than vice versa, change the
main data structure from which lookup tables are built to store data
in a case_id->outputs format, and provide predicates for its conversion
to the other (previously the only) format.
Rename ml_gen_lookup_switch to ml_gen_atomic_lookup_swith to distinguish
it from other predicates that also generate (other kinds of) lookup
switches.
compiler/switch_util.m:
Have the types representating lookup tables represent their contents
as a map, not as the assoc list derived from the map. Previously,
we didn't do anything with the map other than flatten it to the assoc list,
but for the MLDS backend, we may now also need to convert it to another
form of map (see immediately above).
compiler/builtin_ops.m:
Add two new builtin ops. The first, string_unsafe_index_code_unit,
returns the nth code unit in a string; the second, offset_str_eq,
does a string equality test on the nth and later code units of
two strings. They are used in the implementation of tries.
compiler/c_util.m:
Add a new binop category for each new binop, since they are not like
existing binops.
Put some existing binops into their own categories as well, since
bundling them with the other ops they were bundled with seems like
a bad idea.
compiler/hlds_goal.m:
Make the identifier of switch arms in tagged_cases a separate type
from int.
compiler/mlds_to_c.m:
compiler/llds_out_data.m:
Handle the new kinds of binops.
When writing out binop expressions, we used to do a switch on the binop
to get its category, and then another switch on the category. We now
switch on the binop directory, since this much harder to write out
code using new binops badly, and should be faster to boot.
In mlds_to_c.m, also make some cosmetic changes to the output to make it
easier to read, and thus to debug.
compiler/mlds_to_il.m:
Handle the new kinds of binops.
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
Do not handle the new kinds of binops, since doing so would require
changing the whole approach of how these modules handle binops.
Clean up some predicates.
compiler/bytecode.m:
compiler/erl_call_gen.m:
compiler/lookup_switch.m:
compiler/ml_global_data.m:
compiler/ml_optimize.m:
compiler/ml_tag_switch.m:
compiler/opt_debug.m:
compiler/string_switch.m:
Conform to the changes above.
compiler/ml_code_gen.m:
Put the predicates of this module into a consistent order.
library/string.m:
Fix white space.
runtime/mercury_string.h:
Add a macro for each of the two new builtin operations.
|
||
|
|
4776d05cbc | Fix the I/O section of the transition guide. | ||
|
|
dddb9e552d |
Factor out common code in code generation for switches.
compiler/switch_util.m:
Move here some code that was common to switch_gen.m and ml_switch_gen.m.
compiler/switch_gen.m:
compiler/ml_switch_gen.m:
Remove the code moved to switch_util.m.
In switch_gen.m, remove a long unused predicate.
compiler/code_info.m:
Simplify the interface of the init predicate for code_infos.
compiler/proc_gen.m:
Conform to the change in code_info.m.
|
||
|
|
8a6ffaab19 |
Fix Mantis bug #354.
I/O tabling has two main purposes. The first and more important is to allow the
debugger to replay parts of the program execution for the programmer, which
requires making I/O operations idempotent (so that we get the same results on
the second, third etc "execution" as on the first). The second purpose is to
let the person using the debugger actually see a list of the I/O actions, and
their results.
The root of the problem here is that the compiler can do the second part
only if it has access to the type_infos describing the types of the arguments
of the I/O action. With the current infrastructure for representing typeclass
information, this is not always possible in the presence of typeclass
constraints on I/O action predicates. The reason is that polymorphism.m can
put the typeinfo for a type variable that is subject to a typeclass constraint
arbitrarily deep inside the typeclass_info for that constraint, but the RTTI
can encode such locations only up to a fixed depth (currently only the
shallowest embedded is encodable).
Before this fix, the test case for this bug got a compiler abort when the
I/O tabling transformation tried to figure out how to table the typeclass
info representing the typeclass constraint on a I/O action predicate.
We still cannot table typeclass infos. We could store them (I/O tabling
does not require anything more complicated), but the problem of deeply buried
typeinfos inside them would still remain. So this fix consists of two parts:
- for typeclass constrained I/O primitives, recording only enough information
to allow them to replayed (the first purpose above), and not to print them
out (the second purpose), and
- getting the runtime system to understand this, and not crash with a core dump
in the absence of the information required for the second purpose.
This second part requires changes to the RTTI used by I/O tabling. These
changes BREAK BINARY COMPATIBILITY in debug grades.
runtime/mercury_stack_layout.h:
Rename the MR_TableIoDecl structure as the MR_TableIoEntry structure,
since the I/O table entries that it describes are used not just for
declarative debugging, but also for printing out I/O actions.
Add a field to it that specifies whether the fields describing
the types of the I/O action's arguments are meaningful.
runtime/mercury_grade.h:
Bump the debug-only binary compatibility version number, since
the change to mercury_stack_layout.h requires it.
runtime/mercury_trace_base.[ch]:
When returning information about a tabled I/O action, return a boolean
that says whether the information abouts its arguments is actually
present or not. Do not return information about the arguments if
we cannot convert them into univs due to missing type information.
browser/io_action.m:
Pay attention to the new info returned by MR_trace_get_action,
and avoid a potential core dump by generating a description of the
requested I/O action only if the argument type information needed
to generate that description is actually available.
trace/mercury_trace_vars.c:
Pay attention to the new info returned by MR_trace_get_action.
When the argument type information needed to generate an accurate
description of the I/O action is not available, generate a
"description" that mentions this fact.
trace/mercury_trace_cmd_browsing.c:
Make the fix to mercury_trace_vars.c easier to test by adding a mechanism
to print out all existing I/O actions, as long as there aren't too many
of them.
compiler/hlds_pred.m:
compiler/layout.m:
compiler/prog_data.m:
Prepare for the possibility that we have cannot record the information
needed to reconstruct the runtime types of the arguments of a I/O tabled
predicate.
compiler/table_gen.m:
If an I/O tabled predicate has one or more typeclass constraints,
do not attempt to record the RTTI needed to reconstruct the types
of its arguments at runtime.
compiler/continuation_info.m:
compiler/hlds_data.m:
Rename some data structures that referred to the old MR_TableIoDecl
structure to refer to its replacement, the MR_TableIoEntry structure.
compiler/bytecode_gen.m:
compiler/ctgc.selector.m:
compiler/dead_proc_elim.m:
compiler/dependency_graph.m:
compiler/erl_unify_gen.m:
compiler/export.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_out_mode.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/layout.m:
compiler/layout_out.m:
compiler/llds.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_util.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_to_mercury.m:
compiler/ml_global_data.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mode_util.m:
compiler/module_qual.m:
compiler/opt_debug.m:
compiler/proc_gen.m:
compiler/prog_data.m:
compiler/prog_out.m:
compiler/prog_rep.m:
compiler/prog_type.m:
compiler/prog_util.m:
compiler/rbmm.execution_path.m:
compiler/stack_layout.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/type_ctor_info.m:
compiler/unify_gen.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
runtime/mercury_misc.h:
runtime/mercury_tabling.h:
Conform to the above changes.
tests/debugger/tabled_typeclass.{m,inp,exp,exp2}:
New test case to test that I/O actions that have typeclass constraints
on them can be printed in mdb.
tests/debugger/Mmakefile:
tests/debugger/Mercury.options:
Enable the new case.
|
||
|
|
9a932f8d47 |
Provide finer grained control over --smart-indexing.
The --smart-indexing option enables a number of smart indexing strategies depending on the switch category and backend. This diff adds new developer only options that provide finer grained control over which smart indexing strategies are enabled. I need this to assist in tracking down some problems with the use of --smart-indexing on the MinGW64 port. compiler/options.m: Add new command line options that can be used to selectively disable various types of smart indexing. compiler/switch_util.m: Add a predicate to test whether the user has chosen to disable smart indexing for a particular category of switch. compiler/switch_gen.m: compiler/ml_switch_gen.m: Respect the new options. |
||
|
|
884838b9df |
If the backend supports constant structures, and we do not need unifications
Estimated hours taken: 8
Branches: main
If the backend supports constant structures, and we do not need unifications
to retain their original shapes, then convert each from_ground_term scope
into a unification with a cons_id that represents the ground term being
built up.
This speeds up the compilation of training_cars_full.m by about 6%.
compiler/simplify.m:
Make the conversion if enabled. By doing the conversion in this phase,
we don't have to teach the semantic analysis passes about unifications
with the new cons_id, but we do get the benefit of later passes being
faster, because they have less code to process.
compiler/const_struct.m:
The declarative debugger does not yet know how to handle the new
cons_id, so do not introduce it if we are preparing for declarative
debugging.
compiler/trace_params.m:
Export a predicate for const_struct.m.
compiler/prog_data.m:
Add the new cons_id, ground_term_const.
compiler/hlds_data.m:
Add the tag of the new cons_id, ground_term_const_tag.
compiler/hlds_code_util.m:
Convert the new cons_id to the new cons_tag.
Fix an old problem with that conversion process: it always converted
tuple_cons to single_functor_tag. However, arity-zero tuples are
(dummy) constants, not heap cells, so we now convert them to a (dummy)
integer tag. This matters now because the process that generates
code (actually data) for constant structures handles the cons_tags that
build constants and heap cells separately. As a side benefit, we
no longer reserve a word-sized heap cell for arity-zero tuples.
compiler/unify_gen.m:
compiler/ml_unify_gen.m:
Implement the generation of code for arbitrary constant structures,
not just those that can implement typeinfos and typeclass_infos.
compiler/term_norm.m:
Compute the sizes of ground terms for each of our norms.
compiler/term_traversal.m:
Manage the computation of sizes of ground terms.
Simplify and thereby speed up a predicate.
compiler/term_constr_build.m:
Note that we should manage the computation of sizes of ground terms.
compiler/term_util.m:
Simplify the style of a predicate.
compiler/layout.m:
Give some field names prefixes to avoid ambiguities.
compiler/bytecode_gen.m:
compiler/ctgc.selector.m:
compiler/dead_proc_elim.m:
compiler/dependency_graph.m:
compiler/erl_unify_gen.m:
compiler/export.m:
compiler/higher_order.m:
compiler/hlds_out_mode.m:
compiler/hlds_out_util.m:
compiler/implementation_defined_literals.m:
compiler/inst_check.m:
compiler/mercury_to_mercury.m:
compiler/ml_global_data.m:
compiler/ml_type_gen.m:
compiler/mode_util.m:
compiler/module_qual.m:
compiler/polymorphism.m:
compiler/prog_rep.m:
compiler/prog_type.m:
compiler/prog_util.m:
compiler/rbmm.execution_path.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/type_ctor_info.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
Conform to the changes above.
tests/hard_coded/ground_terms.{m,exp}:
A new test case to test the handling of ground terms.
tests/hard_coded/Mmakefile:
tests/hard_coded/Mercury.options:
Enable the new test case.
|
||
|
|
77adfe5439 |
Add all the copyright year updates that were left off in my previous commit
Estimated hours taken: 0.1 Branches: main Add all the copyright year updates that were left off in my previous commit over the ext protocol. |
||
|
|
ee63cb8d84 |
Heavily polymorphic code, such as that generated by g12, often builds the same
Estimated hours taken: 80 Branches: main Heavily polymorphic code, such as that generated by g12, often builds the same typeinfos and typeclass infos over and over again. We have long had caches that avoid building a new typeinfo or typeclass info if some variable in the current scope already contains the right value, but a program that has many scopes may still build the same typeinfo or typeclass info many times. If that typeinfo or typeclass info is a ground term, the code generators will recognize that fact, and will turn all the constructions of that ground term in different scopes into referencess to the same constant structure. However, in the meantime, the program can be much bigger than necessary. In the motivating test case for this change, a single call to fdic_post is preceded by 133 goals that build the four typeclass infos it needs. The main idea of this diff is to construct constant typeinfos and typeclass infos out of line, in a separate data structure. Polymorphism then binds variables representing typeinfo and typeclass infos to reference to these constant structures. In the motivating example, this allows polymorphism.m to insert just four goals before the call to fdic_post, the minimal possible number: one for each typeclass info that predicate needs. On Leslie's bug344 program, this change speeds up the compiler by a factor of five to eight (reducing compile time from about 80 or 85 seconds to 10 or 15). There is a drawback to this scheme, but it is minor. That drawback is that once a constant structure is entered into our database of constant structures, it cannot (yet) be removed. Even if all the references to a constant structure are eliminated by optimizations, the structure will remain. ------------------------------------------ CHANGES IN THE FRONT END compiler/const_struct.m: A new module to look after our new database of constant structures. Currently, its use is enable only on the LLDS and MLDS C backends. compiler/hlds.m: compiler/notes/compiler_design.html: Add the new module to the HLDS package. compiler/hlds_module.m: Include the constant structure database in the module_info. compiler/hlds_data.m: Add two new cons_ids, which refer to typeinfos and typeclass infos implemented as constant structures. Move the code for calculating the number of extra instance args in base_typeclass_infos here from base_typeclass_info.m, since polymorphism.m now needs it too. We can now also eliminate the duplicate copy of that code in higher_order.m. Make an independent optimization: make the restrict_list_elements function more efficient by avoiding redundant tests. compiler/polymorphism.m: When building typeinfo and typeclass infos, keep track of whether the structure being built is constant. If it is, then put it in the database of constant structures, and replace the code building it with a simple reference to that new entry. Since I now expect most goal sequences inserted before goals to be short, consistent use lists of goals to represent these, since the costs of conversions to and from cord form are unlikely to be paid back by the higher efficiency of cord operations on longer sequences. When we want to get the typeclass info of a superclass out of the typeclass info of a subclass, if the typeclass info of the subclass is known, do the extraction here. We used to do this optimization only in higher_order.m, but doing so here reduces the size of the HLDS between polymorphism.m and higher_order.m, and thus improves compilation time. Reorganize some of the structure of this module to make the above changes possible. In particular, our new approach requires making snapshots of the varsets and vartypes, and later restoring those snapshots if the variables allocated turn out to be unnecessary, due to all of them describing the components of a constant structure. The correctness of such code is much easier to check if the taking and restoring of each snapshot takes places in a single predicate. Remove the code moved to higher_order.m. Add some debugging code for now. If no issues arise in the next few weeks, it can be deleted. compiler/modecheck_unify.m: Treat unifications whose right hand side has a cons_id referring to a constant structure specially. compiler/base_typeclass_info.m: Replace the code that is now in num_extra_instance_args with a call to that predicate. Put the arguments of some predicates in a more logical order. compiler/higher_order.m: When looking up the components of existing typeclass infos, handle cases where those typeclass infos are constant structures. Give some types, fields and variables better names. Avoid a redundant map search. Avoid some redundant tests by providing separate predicates to handle higher order calls and method calls. Move the predicate is_typeclass_info_manipulator here from polymorphism.m, since this is the only module that uses that predicate. ------------------------------------------ CHANGES IN THE LLDS BACKEND: compiler/llds.m: Add a type to map constant structure numbers to rvals together with their LLDS types. Introduce a type to represent rvals together with their LLDS types. compiler/mercury_compile_llds_back_end.m: Before we generate code for the predicates of the module, convert the constant structures to typed LLDS rvals. Create a map mapping each constant structure number to the corresponding typed rvals. compiler/proc_gen.m: Take that map, and put it into the code_info, to allow references to those structures to be translated. Put the arguments of some predicates into a more logical order. compiler/code_info.m: Include a map giving the representation of each constant structure in the code_info. compiler/unify_gen.m: Add the predicates needed to convert the constant structures of a module to LLDS rvals. For now, this code works only on the kinds of constant structures generated by polymorphism.m. Handle unifications whose right hand side is a reference to a constant structure. compiler/global_data.m: compiler/stack_layout.m: Use the new typed_rval type where relevant. ------------------------------------------ CHANGES IN THE MLDS BACKEND: compiler/ml_proc_gen.m: Before we generate code for the predicates of the module, convert the constant structures to typed MLDS rvals. Create a map mapping each constant structure number to the corresponding typed rvals. Factor out some code into a predicate of its own. compiler/ml_gen_info.m: Include a map giving the representation of each constant structure in the ml_gen_info. Also add to the ml_gen_info an indication of what GC system we are generating code for, since the code generator needs to know this often. compiler/ml_unify_gen.m: Add the predicates needed to convert the constant structures of a module to MLDS rvals. For now, this code works only on the kinds of constant structures generated by polymorphism.m. Handle unifications whose right hand side is a reference to a constant structure. Simplify some existing code. ------------------------------------------ MINOR CHANGES: mdbcomp/prim_data.m: Add a predicate that gets both the module name and the base name from a sym_name at the same time. This is used for minor speedups in other code updated in this diff. compiler/dead_proc_elim.m: Scan constant structures for references to entities that need to be kept alive. compiler/term_constr_build.m: compiler/term_traversal.m: Do not build size constraints from references to constant structures. The sizes of constant terms don't change, so they are irrelevant when building constraints for finding argument size changes. ------------------------------------------ TRIVIAL CHANGES TO CONFORM TO OTHER CHANGES: compiler/hlds_out_module.m: Print out the constant structure database if asked. doc/user_guide.tex: Document how to ask for it. compiler/hlds_out_util.m: Print out the new cons_ids. compiler/hlds_out_mode.m: Print out the new cons_ids in insts. Remove a compiler abort, to help debug a problem. Improve the structure of a predicate. compiler/hlds_out_goal.m: Fix some missing newlines. compiler/hlds_code_util.m: Add some utility predicates needed by the modules above. Conform to the changes above. compiler/mlds_to_il.m: Reorder some predicates. Conform to the changes above. compiler/bytecode_gen.m: compiler/ctgc.selector.m: compiler/dependency_graph.m: compiler/erl_unify_gen.m: compiler/export.m: compiler/implementation_defined_literals.m: compiler/inst_check.m: compiler/llds_out_globals.m: compiler/mercury_to_mercury.m: compiler/ml_global_data.m: compiler/ml_switch_gen.m: compiler/ml_type_gen.m: compiler/module_qual.m: compiler/prog_rep.m: compiler/prog_type.m: compiler/prog_util.m: compiler/rbmm.execution_path.m: compiler/switch_gen.m: compiler/switch_util.m: compiler/type_ctor_info.m: compiler/unused_imports.m: compiler/var_locn.m: compiler/xml_documentation.m: Conform to the changes above. ------------------------------------------ OTHER INDEPENDENT CHANGES: compiler/handle_options.m: Add a dump option that is useful for debugging when working on polymorphism.m and constant structures. compiler/equiv_type_hlds.m: Fix an old performance bug: make the code handling try goals keep the old memory cells representing such goals, instead of rebuilding them, if no changes took place inside them. compiler/ml_accurate_gc.m: Move a test earlier, to allow us to avoid more work in the common case. compiler/erl_code_gen.m: compiler/error_util.m: compiler/hhf.m: compiler/inst_util.m: compiler/ml_code_util.m: compiler/ml_util.m: compiler/mlds_to_c.m: compiler/modecheck_call.m: compiler/modecheck_util.m: compiler/post_typecheck.m: compiler/size_prof.m: compiler/stack_opt.m: compiler/stratify.m: compiler/unused_args.m: compiler/post_type_analysis.m: library/erland_rtti_implementation.m: Minor cleanups. ------------------------------------------ CHANGES TO THE TEST SUITE: tests/invalid/any_passed_as_ground.err_exp2: tests/invalid/invalid_default_func_1.err_exp2: tests/invalid/invalid_default_func_3.err_exp2: tests/invalid/try_detism.err_exp2: Add second expected output files for these tests. We need alternate expected outputs because the numbers of some of the typeinfo variables mentioned in error message are different depending on whether or not const structures are enabled. |
||
|
|
de56f9b77c |
Implement lookup table versions of hash and binary search switches for strings
Estimated hours taken: 24 Branches: main Implement lookup table versions of hash and binary search switches for strings in the MLDS backend (those versions already exist in the LLDS backend). compiler/ml_string_switch.m: Make the above change. Where possible, factor out and reuse existing code. compiler/ml_lookup_switch.m: Break up the predicate that used to both test a switch whether it is a lookup switch and also generate code for it if it was, into two parts, each doing just one job. The first part is now useful for switches on strings as well. Group auxiliary predicates with the main predicates they support. Factor out some code into new predicates, and export them for use by the new code in ml_string_switch.m. Make some predicates tail recursive. Remove some predicates made unnecessary by changes to lookup_switch.m. compiler/ml_switch_gen.m: Invoke the new code when appropriate, and conform to the updated interface of ml_lookup_switch.m. compiler/switch_util.m: Change some types, and the predicates that operate on them, to make them useful for lookup switches for the MLDS backend as well the LLDS backend. Add some utility predicates. compiler/lookup_switch.m: Change the interface of some of the predicates in this module to allow us to factor out some common code from the higher order values passed by callers. Conform to the changes in switch_util.m. compiler/string_switch.m: Conform to changes in switch_util.m. compiler/switch_gen.m: Conform to changes in lookup_switch.m. |
||
|
|
b4092d2e4e |
Further improvements in the implementation of string switches, along with
Estimated hours taken: 12 Branches: main Further improvements in the implementation of string switches, along with some bug fixes. If the chosen hash function does not yield any collisions for the strings in the switch arms, then we can optimize away the table column that we would otherwise need for open addressing. This was implemented in a previous diff. For an ordinary (non-lookup) string switch, the hash table has two columns in the presence of collisions and one column in their absence. Therefore if doubling the size of the table allows us to eliminate collisions, the table size is unaffected, though the corresponding array of labels we have to put into the computed_goto instruction we generate has to double as well. Thus the only cost of such doubling is an increase in "code" size, and for small tables, the elimination of the open addressing loop may compensate for this, at least partially. For lookup string switches, doubling the table size this way has a bigger space cost, but the elimination of the open addressing loop still brings a useful speed boost. We therefore now DO double the table size if this eliminates collisions. In the library, compiler etc directories, this eliminates collisions in 19 out of 47 switch switches that had collisions with the standard table size. compiler/switch_util.m: Replace the separate sets of predicates we used to have for computing hash maps (one for lookup switches and one for non-lookup switches) with a single set that works for both. Change this set to double the table size if this eliminates collisions. This requires it to decide the table size, a task previously done separately by each of its callers. One version of this set had an old bug, which caused it to effectively ignore the second and third string hash functions. This diff fixes it. There were two bugs in my previous diff: the unneeded table column was not being optimized away from several_soln lookup switches, and the lookup code for one_soln lookup switches used the wrong column offset. This diff fixes these too. Since doubling the table size requires recalculating all the hash values, decouple the computation of the hash values from generating code for each switch arm, since the latter shouldn't be done more than once. Add a note on an old problem. compiler/ml_string_switch.m: compiler/string_switch.m: Bring the code for generating code for the arms of string switches here from switch_util.m. tests/hard_coded/Mmakefile: Fix the reason why the bugs mentioned above were not detected: the relevant test cases weren't enabled. tests/hard_coded/string_hash.m: Update this test case to test the correspondence of the compiler's and the runtime's versions of not just the first hash function, but also the second and third. runtime/mercury_string.h: Fix a typo in a comment. |
||
|
|
fe566dbf42 |
When doing hash table lookup as part of the implementation of switches on
Estimated hours taken: 8 Branches: main When doing hash table lookup as part of the implementation of switches on strings, we use open addressing to handle collisions. However, if the chosen hash function does not yield any collisions for the strings in the switch arms, then open addressing is unnecessary: if a lookup does not find the string bound to the switch variable in its home bucket, it won't be in the hash table at all. This diff optimizes such cases, by not generating for them the loop we would otherwise use for open addressing, and optimizing away the table column telling that loop where to check next. compiler/string_switch.m: Implement the above optimization both for ordinary switches on strings, and for lookup table switches (both one_soln and several_soln) on strings. compiler/ml_string_switch.m: Implement the above optimization for ordinary switches on strings. This module does not (yet) implement lookup table switches on strings. compiler/switch_util.m: When deciding what hash function to use, return the number of collisions for string_switch and ml_string_switch to use. Rename the other_switch category to float_switch, since the only type category it covers is switches on floats. compiler/switch_gen.m: compiler/ml_switch_gen.m: Make the module header comments more organized, and use the same template for both, so one can see the differences more easily. Put the switch arms for the smart indexing methods into the same order in both files. Fix an old problem in ml_switch_gen.m: the test to see whether we can apply a smart indexing method that uses switches on integers was testing not the availability of int switches in the target, but the availability of computed gotos. While ml_simplify_switch would transform the int-switch-using code to computed-goto-using code or an if-then-else chain in *some* cases, it would not do so in *all* cases. In ml_switch_gen.m, remove a test that could not succeed, and a procedure that was used only in that test. Conform to the changes in switch_util.m. compiler/lookup_switch.m: compiler/ml_simplify_switch.m: Update comments. |