mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-18 02:43:40 +00:00
083d376e6598628362ee91c2da170febd83590f4
96 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
07f877bc3f |
Carve term_context.m out of term.m.
library/term.m:
library/term_context.m:
As above.
Rename the term.context type as term_context.term_context, with
term.context now being defined as an equivalence type.
Replace the context_init function and predicate and the dummy_context_init
function with just one function: dummy_context. This name includes
the important part (the fact that it return a *dummy* context) and deletes
the nonimportant part (dummy contexts are just about never updated,
so the function does not really "initialize" them).
Reduce function/predicate pairs that do the same thing to just a function.
library/MODULES_DOC:
library/library.m:
Add the new module to the list of standard library modules.
NEWS:
Mention the new module, and the obsoleting of the moved predicates
and functions in term.m.
compiler/*.m:
library/*.m:
Conform to the changes above.
|
||
|
|
2a1c2bb88a |
Make quantification using var_tables the default.
compiler/quantification.m:
Add a "_vs" suffix to the names of predicates that use varsets, and
delete the "_vt" suffix from the names of predicates that use var_tables.
Keep private a predicate that now has no callers outside this module.
Shorten the names of some function symbols.
compiler/recompute_instmap_deltas.m:
Shorten the names of some function symbols.
compiler/equiv_type_hlds.m:
Give a predicate a more meaningful name.
compiler/*.m:
Conform to the change above.
|
||
|
|
d787ee9355 |
Store var_tables in proc_infos.
This fixes the performance problem reported in Mantis bug #562. compiler/hlds_pred.m: Instead of storing a varset and a vartypes in each proc_info, store just a var_table. Update the predicates that create or clone procedures accordingly. Where we had operations on proc_infos that had two versions, one operating on a varset/vartypes pair and one operating on var_table, keep only the latter, with the (shorter) name of the former. Delete the arity argument of proc_info_init, because the only valid value of that argument is the length of the list of the argument types. (In other words, this arg has been redundant all along.) Change the operations that create new variables in a procedure to get the caller to specify the (base) name of the new variable up front. Delete the unused predicate proc_info_ensure_unique_names. compiler/type_util.m: Due to the change above, we now construct var_tables during the construction of the HLDS. The code that does that needs to fill in the field that says whether the type of each variable in the table is a dummy type or not. However, at this time, the pass that decides type representations has not been run yet. The code of is_type_a_dummy used to throw an exception in such situations. Change this so that in such situations, is_type_a_dummy returns a placeholder, not-guaranteed-to-be-correct value. Document why this is ok. compiler/post_typecheck.m: Replace the placeholder values in vte_is_dummy fields in all the entries in the var_tables in all (valid) predicates with valid data. (If there are any invalid predicates, the compilation will fail anyway.) The clause_to_proc pass will copy these updated var_tables to be the initial var_tables in procedures. compiler/make_goal.m: Change the operations that create new variables in a procedure to get the caller to specify the (base) name of the new variable up front. This is simpler than the old method, which created new variables without a name, and had the caller give them a name as a separate operation. And since var_tables need this info, get the caller to also specify whether the type is a dummy, if the type is not a builtin type which is known not to be a dummy. compiler/var_table.m: Document the times when the types and is_dummy fields in var_table entries become meaningful. Fix a potential bug: when performing type substitutions in var_table entries, updating a variable's type may change whether that variable is a dummy or not, so recompute that info. It is quite possible that we *never* replace a nondummy type with a dummy type or vice versa, but in the absence of a convincing correctness argument for that proposition, better safe than sorry. Export the previously-private predicate transform_var_table to post_typecheck. Add code to implement the unused predicate deleted from hlds_pred.m: at the time I wrote it, I haven't yet realised that it was unused. The code I wrote here is therefore unused as well, so it is commented out. I did not delete it, because it may be useful later on. compiler/direct_arg_in_out.m: Don't make and split var_tables, since it is no longer needed. compiler/accumulator.m: compiler/add_class.m: compiler/add_clause.m: compiler/add_heap_ops.m: compiler/add_pred.m: compiler/add_special_pred.m: compiler/add_trail_ops.m: compiler/arg_info.m: compiler/build_mode_constraints.m: compiler/bytecode_gen.m: compiler/check_typeclass.m: compiler/clause_to_proc.m: compiler/closure_analysis.m: compiler/code_gen.m: compiler/code_loc_dep.m: compiler/complexity.m: compiler/continuation_info.m: compiler/cse_detection.m: compiler/ctgc.livedata.m: compiler/deep_profiling.m: compiler/default_func_mode.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/distance_granularity.m: compiler/equiv_type_hlds.m: compiler/exception_analysis.m: compiler/float_regs.m: compiler/follow_code.m: compiler/goal_mode.m: compiler/goal_path.m: compiler/higher_order.m: compiler/hlds_out_pred.m: compiler/hlds_rtti.m: compiler/hlds_statistics.m: compiler/inlining.m: compiler/intermod.m: compiler/intermod_analysis.m: compiler/introduce_exists_casts.m: compiler/introduce_parallelism.m: compiler/lambda.m: compiler/lco.m: compiler/live_vars.m: compiler/liveness.m: compiler/loop_inv.m: compiler/mark_tail_calls.m: compiler/ml_accurate_gc.m: compiler/ml_args_util.m: compiler/ml_closure_gen.m: compiler/ml_gen_info.m: compiler/ml_proc_gen.m: compiler/mode_errors.m: compiler/mode_info.m: compiler/modecheck_goal.m: compiler/par_loop_control.m: compiler/pd_debug.m: compiler/pd_info.m: compiler/pd_util.m: compiler/polymorphism_info.m: compiler/post_typecheck.m: compiler/proc_gen.m: compiler/proc_requests.m: compiler/purity.m: compiler/push_goals_together.m: compiler/quantification.m: compiler/rbmm.add_rbmm_goal_infos.m: compiler/rbmm.live_variable_analysis.m: compiler/rbmm.points_to_analysis.m: compiler/rbmm.points_to_graph.m: compiler/rbmm.points_to_info.m: compiler/rbmm.region_liveness_info.m: compiler/rbmm.region_transformation.m: compiler/recompute_instmap_deltas.m: compiler/saved_vars.m: compiler/simplify_goal_unify.m: compiler/simplify_info.m: compiler/simplify_proc.m: compiler/size_prof.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_reuse.versions.m: compiler/structure_sharing.analysis.m: compiler/structure_sharing.domain.m: compiler/switch_detection.m: compiler/table_gen.m: compiler/tabling_analysis.m: compiler/term_constr_build.m: compiler/term_constr_initial.m: compiler/term_errors.m: compiler/term_pass1.m: compiler/term_pass2.m: compiler/trace_gen.m: compiler/trailing_analysis.m: compiler/try_expand.m: compiler/tupling.m: compiler/unneeded_code.m: compiler/untupling.m: compiler/unused_args.m: compiler/unused_imports.m: Conform to the changes above. Mostly this means - not passing a module_info to get a var_table out of a proc_info, but - having to pass a module_info to code that either constructs a var_table, or adds entries to a var_table (since we now need the type table to figure out whether variables' types are dummies). |
||
|
|
4c9d04434a |
Classify pred_names into four categories.
compiler/pred_name.m:
Group pred_origins into four categories, giving each category its own
function symbol. The categories are
- predicates that contain, or may contain, code directly written
by the user;
- predicates created wholly by the compiler,
- predicates created by the compiler by transforming a predicate, and
- predicates created by the compiler by transforming a procedure.
We distinguish between the first two because we want to report
errors only in user-written code, since reporting an error that
the user is powerless to fix is not a good idea.
We distinguish between the last two just to allow us to store
the proc_id of the transformed procedure next to its pred_id.
compiler/higher_order.m:
Replace a boolean with value of a bespoke type.
Rename some predicates to avoid ambiguity.
compiler/*.m:
Conform to the changes above.
|
||
|
|
08365979d0 |
Move pred_name.m to the HLDS package.
This is so that it can become the home of the type currently named
pred_origin in hlds_pred.m, which (after being given new name) will become
a structured representation of predicate names.
The only thing that kept pred_name.m in the parse_tree package was the fact
that parse_pragma.m, which has no access to the hlds package, called it
to create the name of a type-specialized predicate when parsing
type_spec pragmas. The main part of this diff, apart from the trivial
updates to import hlds.pred_name instead parse_tree.pred_name, deals
with this issue.
The problem is how to ensure that the compiler invocations that create
type-specialized predicates (invocations that compile the module containing
the type_spec pragma that calls for this) and the invocations that create
the calls to those predicates (invocations that mostly compile other modules)
agree on the name of the name of the type-specialized predicate.
The old approach was this.
When reading in (say) mod1.m which contains a type_spec pragma,
we construct the name of the type-specialized predicate from
- the name of the module (mod1),
- the name of the predicate to be specialized, and
- the type substitution in the pragma.
We then record this name in the pragma.
If the compiler invocation generates code, we use this name in the
predicate definition. If the compiler invocation creates a .int file,
we record the name in the third argument of the type_spec pragma.
This third argument is NOT allowed to exist in .m files.
Other compiler invocations that read in mod1.int when compiling
another module, e.g. mod2.m, use the specialized name in the third argument
of the type_spec pragma as the name to use in calls.
In this approach, the single-source-of-truth about the name of the
type-specialized predicate is the name constructed when parsing mod1.m,
which is conveyed to compiler invocations on other modules through
the third argument of the type_spec pragma.
The new approach is this:
When reading in (say) mod1.m which contains a type_spec pragma,
we give guaranteed-to-be-unique names to all the anonymous variables
in the type_spec pragma. We also record in the type_spec pragma
the name of the module whose (source or interface) file we read
the pragma from. The name of the predicate to be specialized
was of course already in the pragma.
If the compiler invocation generates code, we construct the name
of the type-specialized version of the predicate when we add the
all-tvars-are-named type_spec pragma to the HLDS. If the compiler
invocation creates a .int file, we write out the all-tvars-are-named
version of the type_spec pragma. The pragma also contains the predicate
name to be specialized. It does not contain the name of the module,
but we will write out type_spec pragmas from module_x.m *only* to
module_x.int, never to any other .int file, so any readers of
the type_spec pragma from mod1.int will also know the name of the
module that the pragma came from.
Other compiler invocations that read in mod1.int when compiling
another module, e.g. mod2.m, therefore get exactly the same
- module name,
- the name of the predicate to be specialized, and
- the type substitution in the pragma
as the compiler invocations on mod1.m. The module name are the
predicate name are never changed by being written out and then
read back in, and *due to the explicit names given to any formerly
anonymous variables*, the type substitution is changed by this either.
This means that the compiler invocations on mod1.m and mod2.m
give the same parameters to the same function, and therefore they are
guaranteed to get the same string as the name of the type-specialized
version of the predicate.
In this approach, the single-source-of-truth about the name of the
type-specialized predicate is the function constructing that name
and its inputs.
compiler/hlds.m:
compiler/parse_tree.m:
compiler/pred_name.m:
Move pred_name.m from the parse_tree package to the hlds package.
compiler/prog_item.m:
Change the representation of type_spec pragmas to
- delete the name of the specialized predicate, and replace it with
- the name of the module the pragma was read in from.
compiler/parse_pragma.m:
Delete the code for parsing the third argument of type_spec pragmas.
Allow them to exist for a short transition period, but ignore them.
(If we read in files containing them, the result will be a link error
if the type substitution contains anonymous variables. In that case,
a rebuild of the program with all modules compiled using the *same
compiler version* will work.)
Give guaranteed-to-be-unique names to all anonymous type variable
in the type substitution part of the type_spec pragma we construct.
compiler/add_pragma_type_spec.m:
Construct the name of the type-specialized predicate as the type_spec
pragma is added to the HLDS.
compiler/parse_tree_out_pragma.m:
Never write out a type_spec par_loop_control with a third argument.
Delete the var_name_print argument of the predicate that writes out
type_spec pragmas. Instead, *always* use print_name_only.
compiler/options.m:
Add a way of testing whether the installed compiler has this change.
compiler/accumulator.m:
compiler/add_pragma_tabling.m:
compiler/add_special_pred.m:
compiler/base_typeclass_info.m:
compiler/check_typeclass.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/layout_out.m:
compiler/lco.m:
compiler/loop_inv.m:
compiler/make_hlds_passes.m:
compiler/name_mangle.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/par_loop_control.m:
compiler/parse_tree_out.m:
compiler/pd_info.m:
compiler/prog_rep.m:
compiler/ssdebug.m:
compiler/stm_expand.m:
compiler/structure_reuse.versions.m:
compiler/table_gen.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/unused_args.m:
|
||
|
|
af196031ea |
Move pred_origin towards a structured pred_name.
compiler/hlds_pred.m:
Add a long comment about using pred_origin as a structured pred name.
Delete the origin_created pred_origin with origin_deforestation,
which was one of two ways that the compiler could create new predicates
that weren't derived from one existing predicate, procedure, or other
single Mercury construct. (Deforestation picks a conjunction of two
or more goals, and created a new predicate out of *them*.)
Replace the other, created_by_io_tabling, with a pred_transformation,
since in that case, the new predicate *is* derived from a single
existing predicate.
Add a mechanism for recording the predicates created by the distance
granularity transformation, which previously was recorded in the predicate
name, but not in the pred_origin.
Deleted the dnf predicate transform, since it hasn't been used
since the Aditi backend was deleted in 2006.
Include the pred_or_func distinction, and the original user arity,
in the pred_origin of user defined predicates and functions.
Include in most other pred transformations the parameters that are
now recorded in the corresponding transform_name used in pred_name.m,
with the exception of the pred_or_func distinction, since it is now
available by following the chain of transforms to the base pred_origin,
which should include that info.
Use a type_ctor, not its components, in a pred origin.
Shorten the too-long names of some function symbols.
compiler/distance_granularity.m:
Record the transform done by this module.
Use state variables where appropriate.
Use more consistent variable names.
Eliminate excessive indentation in the example transformation
in the module introduction comment.
compiler/loop_inv.m:
Fix a bug. The sequence number field of the transform_name
was being filled with something other than a sequence number,
which could be the same for two transformations. (Or at least,
I have seen no convincing argument for why they couldn't be.
If such an argument existed, the sequence number field would
not be needed, so the old code would still have been wrong,
just for a different reason :-)
Rename a predicate to avoid ambiguity.
compiler/hlds_module.m:
Add the per-context counter needed by the new code in loop_inv.m.
compiler/pd_info.m:
The predicate that defines a new predicate always specifies
the transform_name as tn_deforestation, so don't leave it up
to the caller to specify the pred_origin of the new predicate;
instead, construct it here as a deforestation transform of the
base predicate. That is the origin argument that our one caller
always specified anyway.
compiler/purity.m:
Use a full switch over pred_origins, not a partial one,
to make a decision.
compiler/accumulator.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/higher_order.m:
compiler/hlds_defns.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/inlining.m:
compiler/layout_out.m:
compiler/lco.m:
compiler/mode_errors.m:
compiler/par_loop_control.m:
compiler/polymorphism.m:
compiler/prog_item.m:
compiler/ssdebug.m:
compiler/table_gen.m:
compiler/trace_params.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/xml_documentation.m:
Conform to the changes above.
|
||
|
|
404fea1bd2 |
Start removing non-var_table versions of predicates.
compiler/arg_info.m:
compiler/goal_util.m:
compiler/hlds_rtti.m:
compiler/instmap.m:
compiler/recompute_instmap_deltas.m:
compiler/type_util.m:
For predicates which had both varset/vartypes and var_table versions,
but the former is not used anymore because all its callers have been
switched to the latter,
- delete the former, and
- rename the latter to the name of the former.
In goal_util.m, switch two currently-unused predicates to use var_tables
instead of varsets/vartypes, in case they are needed again.
compiler/hlds_pred.m:
Likewise replace define_new_pred with define_new_pred_vt, but also
change its implementation to use var_table for everything except
the final construction of the proc_info.
compiler/accumulator.m:
compiler/call_gen.m:
compiler/code_loc_dep.m:
compiler/constraint.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/det_util.m:
compiler/float_regs.m:
compiler/follow_code.m:
compiler/higher_order.m:
compiler/interval.m:
compiler/lambda.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/loop_inv.m:
compiler/ml_code_gen.m:
compiler/modes.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/push_goals_together.m:
compiler/rbmm.region_liveness_info.m:
compiler/saved_vars.m:
compiler/simplify_goal.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/table_gen.m:
compiler/tupling.m:
compiler/unneeded_code.m:
compiler/untupling.m:
Conform to the changes above.
|
||
|
|
e10ecf5d69 |
Replace more varsets/vartypes with var_tables.
compiler/hlds_rtti.m:
compiler/hlds_statistics.m:
compiler/intermod.m:
compiler/loop_inv.m:
compiler/recompute_instmap_deltas.m:
As above.
compiler/special_pred.m:
Make some predicate names more meaningful.
compiler/hlds_goal.m:
Fix one of two instances of an ancient bug, which is not looking for
variables inside the call_unify_context field of plain calls.
In this instance, apply substitutions to the variables there.
Make the names of the predicates involved more meaningful.
compiler/lambda.m:
Fix the other instance of that ancient bug, which was that the code
was not looking for variables inside the call_unify_context fields
of plain calls. Fix this by looking for used variables there as well.
Without this, the code just added to hlds_goal.m may fail when invoked
on the procedure we construct for a lambda, because a variable is included
in the var_table of that procedure if lambda.m knows that variable
is actually used in the original lambda goal.
compiler/var_table.m:
Allow searches (as opposed to lookups) for variable names in var_tables
as part of transition arrangements to fail. Without this, finding the
bug in lambda.m would have been much harder, by causing HLDS dumps
to fail.
|
||
|
|
f83def1d7f |
Move related arguments next to each other.
compiler/hlds_pred.m:
As above.
compiler/loop_inv.m:
compiler/pd_info.m:
compiler/tupling.m:
compiler/untupling.m:
Conform to the change.
|
||
|
|
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.
|
||
|
|
3f3045c9e2 |
Get and set varsets/vartypes in proc_infos together.
compiler/hlds_pred.m:
We eventually want to replace the varset and vartypes fields in
each proc_info with a var_table, but it is not practical to do so
at once; it will have to be done gradually, a few modules at most
at a time. During this process, we will need a way either
- to let already converted modules get a var_table out of the proc_info,
and put an updated var_table back into a proc_info, even though
proc_infos still contain varset and vartypes fields, or
- to let not-yet-converted modules get varsets and vartypes out of the
proc_info, and put updated varsets and vartypes back into a proc_info,
even though proc_infos already store a var_table.
The latter cannot be done in two halves (i.e. set the varset half
of the var_table, and then set its vartypes half), and while the former
*can* be done that way, it is more efficient to do them at the same time.
Therefore as a first step, this diff replaces the indiviual getter
and setter predicates of the varset and vartypes fields of proc_info
with a getter that gets both and a setter that sets both.
Put the varset and vartypes next to each other in a structure.
compiler/code_info.m:
Delete a function that duplicates a function in var_table.m.
Conform to the change above.
compiler/det_report.m:
Factor out some common code.
Conform to the change above.
compiler/det_util.m:
Delete a no-longer-needed predicate.
Conform to the change above.
compiler/higher_order.m:
Fix an old oversight: when deleting variables from the vartypes,
delete them from the varset as well.
Conform to the change above.
compiler/liveness.m:
Avoid constructing and traversing a list unnecessarily.
Conform to the change above.
compiler/accumulator.m:
compiler/add_heap_ops.m:
compiler/add_trail_ops.m:
compiler/arg_info.m:
compiler/build_mode_constraints.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/clause_to_proc.m:
compiler/closure_analysis.m:
compiler/code_gen.m:
compiler/code_loc_dep.m:
compiler/complexity.m:
compiler/continuation_info.m:
compiler/cse_detection.m:
compiler/ctgc.datastruct.m:
compiler/ctgc.util.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/direct_arg_in_out.m:
compiler/disj_gen.m:
compiler/equiv_type_hlds.m:
compiler/exception_analysis.m:
compiler/float_regs.m:
compiler/follow_code.m:
compiler/goal_mode.m:
compiler/goal_path.m:
compiler/hlds_out_pred.m:
compiler/hlds_rtti.m:
compiler/hlds_statistics.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/intermod_analysis.m:
compiler/introduce_exists_casts.m:
compiler/introduce_parallelism.m:
compiler/lambda.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/loop_inv.m:
compiler/mark_tail_calls.m:
compiler/ml_accurate_gc.m:
compiler/ml_args_util.m:
compiler/ml_closure_gen.m:
compiler/ml_gen_info.m:
compiler/ml_proc_gen.m:
compiler/mode_info.m:
compiler/modecheck_goal.m:
compiler/modes.m:
compiler/par_loop_control.m:
compiler/pd_debug.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/polymorphism_info.m:
compiler/proc_gen.m:
compiler/purity.m:
compiler/push_goals_together.m:
compiler/quantification.m:
compiler/rbmm.add_rbmm_goal_infos.m:
compiler/rbmm.live_variable_analysis.m:
compiler/rbmm.points_to_graph.m:
compiler/rbmm.points_to_info.m:
compiler/rbmm.region_liveness_info.m:
compiler/rbmm.region_transformation.m:
compiler/recompute_instmap_deltas.m:
compiler/saved_vars.m:
compiler/simplify_goal_unify.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
compiler/size_prof.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.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/switch_detection.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_initial.m:
compiler/term_errors.m:
compiler/term_pass1.m:
compiler/term_pass2.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/try_expand.m:
compiler/tupling.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/unused_imports.m:
Conform to the change above.
|
||
|
|
20bb6e4bd4 |
Stop generating duplicate aux MLDS functions.
compiler/ml_tag_switch.m:
As above. This fixes one of the two problems detected by Mantis bug #548.
tests/hard_coded/bug548.m:
A new small test case for Mantis bug #548. It includes, and documents,
both problems, and makes them visible in all hlc grades (not just pregen)
and at all optimization levels, provided inlining is turned on.
Since the second problem is not yet fixed, this test case
is not yet enabled.
tests/hard_coded/Mercury.options:
Enable inlining for the new test case.
compiler/loop_inv.m:
Rewrite the code that tickled Mantis bug #548. bug548.m takes over
from that code as an examplar of the bug, and the code, though short,
was conceptually more complex than its replacement.
Note similar issues with nearby code.
|
||
|
|
5750c35e64 |
Move pred-name-constructing code to pred_name.m.
compiler/pred_name.m:
Support the construction of predicate names for more predicate transforms,
including those done by higher_order.m and table_gen.m. Neither conformed
to the naming scheme of the other predicate transformations. For the
transforms done by higher_order.m, add XXXs noting this. For the transform
done by table_gen.m, make it generate names that do conform to our pattern.
We can do this because we only generate the affected predicates (and their
names) in minimal model own stack grades, which are not operational :-(
Move code to create names for the predicates implementing typeclass
methods here.
Move code to create names for unify, compare and index predicates here.
Include "sym_name" in the names of the predicates that construct sym_names.
Rename one of the existing transform_names to avoid ambiguity.
compiler/hlds_pred.m:
Change the argument order of pred_info_init, partly to put first things
first, but also to flush out places that construct predicate names.
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/hlds_code_util.m:
Delete the code moved to pred_name.m.
compiler/accumulator.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/base_typeclass_info.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/higher_order.m:
compiler/lambda.m:
compiler/layout_out.m:
compiler/loop_inv.m:
compiler/name_mangle.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/par_loop_control.m:
compiler/parse_pragma.m:
compiler/pd_info.m:
compiler/prog_rep.m:
compiler/special_pred.m:
compiler/structure_reuse.versions.m:
compiler/table_gen.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/unused_args.m:
Conform to the changes above.
tests/debugger/mmos_print.exp:
Update the only minimal_model_own_stack generator predicate name
outside the compiler.
|
||
|
|
b6bb5285b9 |
Put define_new_pred's args into a sensible order.
compiler/hlds_pred.m:
As above. The old argument list was a mess.
compiler/pd_info.m:
Conform to the change above.
Remove an ambiguity by addinga "pd_info_" prefix to the define_new_pred
predicate in *this* module, as well as several other predicates
that were usually already referred to using "pd_info." prefixes.
compiler/deforest.m:
compiler/loop_inv.m:
compiler/tupling.m:
compiler/untupling.m:
Conform to the changes above.
|
||
|
|
b80ba7095a |
Move to a unified scheme for pred name transforms.
compiler/pred_name.m:
Put all the information needed to create a name for a transformed
predicate or function into one data structure. This centralizes
knowledge about the format of transformed names here, for the
compiler components that use pred_name.m to construct new pred names.
(Making all the *other* compiler components that now construct
new pred names switch to use pred_names.m is future work.)
This central data structure, transform_name, contains information
that used to supplies using separate arguments, such as the initial
prefix identifying the program transformation that creates the name,
and an indication whether it is being applied to a predicate or a function.
In cases where callers used to post-process the sym_name we return
to add a procedure # as a suffix (to go after the suffix that pred_name.m
adds to the name :-(), make such shenanigans unnecessary by making
the proc_id number part of the transform_name.
Replace the code that constructs lists of things (integers and
substitutions for type vars) with shorter code, whose functionality
is underdtandable at a glance. It is slower, but the construction
of predicate names is rare it for that not to matter.
compiler/accumulator.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/lambda.m:
compiler/loop_inv.m:
compiler/par_loop_control.m:
compiler/parse_pragma.m:
compiler/pd_info.m:
compiler/structure_reuse.versions.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/unused_args.m:
Conform to the changes above.
In pd_info.m, delete unneeded module qualifications on clause heads.
In distance_granularity.m, delete code that duplicates code in pred_name.m.
In structure_reuse.versions.m, delete an unhelpful type synonym.
In several places, improve variable names.
|
||
|
|
2eeeddaae0 |
Carve pred_name.m out of prog_util.m.
compiler/pred_name.m:
compiler/prog_util.m:
As above.
compiler/notes/compiler_design.html:
Document the new module.
compiler/accumulator.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/lambda.m:
compiler/loop_inv.m:
compiler/par_loop_control.m:
compiler/parse_pragma.m:
compiler/parse_tree.m:
compiler/pd_info.m:
compiler/structure_reuse.versions.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/unused_args.m:
Conform to the change above.
|
||
|
|
d76c7bf617 |
Break up inst_util.m and mode_util.m.
This step significantly improves module cohesion.
compiler/inst_abstract_unify.m:
New module carved out of inst_util.m, which does abstract unifications
on insts.
compiler/inst_merge.m:
New module carved out of inst_util.m, which merges insts.
compiler/inst_lookup.m:
New module carved partly out of inst_util.m and partly out of mode_util.m,
which looks up insts in the module_info, and then possibly expands out
the result.
compiler/mode_test.m:
New module carved out of mode_util.m, whose predicates
perform tests on modes.
compiler/mode_top_functor.m:
New module carved out of mode_util.m, which computes top_functor_modes
from modes.
compiler/inst_mode_type_prop.m:
New module carved out of mode_util.m, which propagates type information
into both insts and modes.
compiler/recompute_instmap_deltas.m:
New module carved out of mode_util.m, which recomputes goals'
instmap_deltas.
compiler/inst_test.m:
Move here the predicates in inst_util.m that perform tests on insts.
compiler/inst_util.m:
compiler/mode_util.m:
Delete the code that this diff moves to other modules.
compiler/check_hlds.m:
Add the new modules to the check_hlds package, the package that also
contains inst_util.m and mode_util.m. (Some of these modules could
be argued to fit better in the hlds package, but moving them there
would not be desirable while they depend on code that is still in the
check_hlds package.)
compiler/notes/compiler_design.html:
Document the new modules.
compiler/add_pragma_tabling.m:
compiler/arg_info.m:
compiler/bytecode_gen.m:
compiler/closure_analysis.m:
compiler/complexity.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/error_msg_inst.m:
compiler/fact_table.m:
compiler/float_regs.m:
compiler/follow_code.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_pred.m:
compiler/hlds_rtti.m:
compiler/inlining.m:
compiler/inst_match.m:
compiler/inst_user.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/interval.m:
compiler/introduce_exists_casts.m:
compiler/lambda.m:
compiler/lco.m:
compiler/liveness.m:
compiler/lookup_util.m:
compiler/loop_inv.m:
compiler/mark_tail_calls.m:
compiler/ml_args_util.m:
compiler/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_util.m:
compiler/mode_constraints.m:
compiler/mode_errors.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/oisu_check.m:
compiler/par_conj_gen.m:
compiler/pd_util.m:
compiler/post_typecheck.m:
compiler/pragma_c_gen.m:
compiler/proc_requests.m:
compiler/prog_rep.m:
compiler/push_goals_together.m:
compiler/rbmm.region_transformation.m:
compiler/saved_vars.m:
compiler/simplify_goal_switch.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/stratify.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.domain.m:
compiler/superhomogeneous.m:
compiler/table_gen.m:
compiler/term_constr_build.m:
compiler/term_pass2.m:
compiler/term_util.m:
compiler/tupling.m:
compiler/unify_gen_construct.m:
compiler/unify_gen_util.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
Conform to the changes above by importing the required new modules,
sometimes in addition to inst_util.m or mode_util.m, but more usually
instead of them.
|
||
|
|
1ce46c2797 |
Pair lambda arg vars with their modes.
compiler/hlds_goal.m:
This enforces the invariant that the there is one mode par argument var.
Document that that "nonlocals" field of the lambda actually contains
the variables that will be put into the closure.
compiler/assertion.m:
compiler/build_mode_constraints.m:
compiler/check_promise.m:
compiler/cse_detection.m:
compiler/dead_proc_elim.m:
compiler/delay_partial_inst.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
compiler/float_regs.m:
compiler/format_call.m:
compiler/goal_path.m:
compiler/goal_util.m:
compiler/hhf.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_util.m:
compiler/hlds_statistics.m:
compiler/implementation_defined_literals.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/lco.m:
compiler/loop_inv.m:
compiler/make_hlds_warn.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/mode_ordering.m:
compiler/mode_util.m:
compiler/modecheck_unify.m:
compiler/old_type_constraints.m:
compiler/polymorphism.m:
compiler/polymorphism_lambda.m:
compiler/pre_quantification.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/quantification.m:
compiler/simplify_goal_unify.m:
compiler/stratify.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/try_expand.m:
compiler/typecheck.m:
compiler/unused_args.m:
compiler/unused_imports.m:
Conform to the change above.
|
||
|
|
48e714d43f |
Make constant prop work with loop invariant opt.
compiler/common.m:
The code that tries to optimize X = f(...) into X = Y if Y already
contains f(...) used to insist on the X = f(...) construction unification
being marked as a dynamic unification, i.e. one that constructs a term
on the heap on each invocation. This was part of the fix of Mantis bug
#493, which affected only the MLDS code generator, but for LLDS backend,
in the presence of --loop-invariants, it prevented a constant propagation
optimization that we had a test for (tests/hard_coded/constant_prop_2).
So make both backends happy by insisting on construct_dynamically
only for the MLDS backend.
compiler/simplify_info.m:
Record for common.m whether the backend we are targeting pays
any attention to whether a cell is construct_dynamically.
Replace some bools with bespoke types, to eliminate the risk of confusion.
compiler/hlds_goal.m:
For each construction unification marked construct_statically, record
whether the term was "born static" by being created as a static term
by a compiler pass, or whether it is a user-written unification that was
"marked static" by mark_static_terms.m. Document the meaning of both.
(I originally thought this distinction would be useful in the bug fix,
but it turned out not to be.)
compiler/deep_profiling.m:
compiler/dep_par_conj.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/polymorphism.m:
compiler/polymorphism_type_info.m:
Record compiler-generated static terms as born static.
compiler/mark_static_terms.m:
Mark discovered-to-be-static terms as marked static.
compiler/hlds_out_goal.m:
compiler/interval.m:
compiler/liveness.m:
compiler/loop_inv.m:
compiler/ml_unify_gen_construct.m:
compiler/quantification.m:
compiler/rbmm.add_rbmm_goal_infos.m:
compiler/simplify_goal.m:
compiler/simplify_goal_conj.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_scope.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.versions.m:
compiler/unify_gen_construct.m:
compiler/var_locn.m:
Conform to the changes above.
tests/hard_coded/constant_prop_loop_inv.{m,exp}:
A new test case. It contains the part of the constant_prop_2 test case
that used to fail in LLDS grades with --loop-invariants.
tests/hard_coded/Mercury.options:
Specify --loop-invariants for the new test case, even if it is not
specified for constant_prop_2.
tests/hard_coded/Mmakefile:
Enable the new test case.
tests/hard_coded/constant_prop_2.m:
Fix programming style.
|
||
|
|
bd594dded2 |
Impose logical order on mode_info.m and mode_util.m.
compiler/mode_info.m:
compiler/mode_util.m:
Put the predicates in these modules into logical groups, and ensure
that the orders of the declarations and definitions match.
Delete the unused predicate mode_info_set_how_to_check from mode_info.m.
Delete the unused predicates select_output_vars, select_output_things,
and partition_args from mode_util.m.
Rename the unify_modes_to_X predicates to unify_mode_to_X, since each
of these predicates operates on only *one* unify_mode.
Move three predicates that are needed only during mode checking,
and not during later compuiler passes, to modecheck_util.m.
compiler/modecheck_util.m:
Add the predicates moved from mode_util.m.
compiler/Mercury.options:
Require the order of predicates' definitions to match the order of
their declarations in mode_info.m and mode_util.m.
compiler/common.m:
compiler/loop_inv.m:
compiler/modecheck_goal.m:
Conform to the changes in mode_util.m.
|
||
|
|
25b89ea8c6 |
Put bigger inputs first.
compiler/hlds_pred.m:
Put a module_info input before a proc_info input.
compiler/*.m:
Conform to the above.
|
||
|
|
17d684a11e |
Better arg orders in instmap.m.
compiler/instmap.m:
Replace a non-state-var-friendly and a state-var-friendly pair
of predicates with just one state-var-friendly predicate.
Improve the arg order of another predicate as well.
Improve documentation.
compiler/accumulator.m:
compiler/call_gen.m:
compiler/code_loc_dep.m:
compiler/constraint.m:
compiler/cse_detection.m:
compiler/delay_construct.m:
compiler/dep_par_conj.m:
compiler/erl_code_gen.m:
compiler/erl_code_util.m:
compiler/float_regs.m:
compiler/goal_mode.m:
compiler/goal_util.m:
compiler/hlds_pred.m:
compiler/introduce_parallelism.m:
compiler/lookup_util.m:
compiler/loop_inv.m:
compiler/mode_util.m:
compiler/modecheck_unify.m:
compiler/par_conj_gen.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/prog_rep.m:
compiler/stm_expand.m:
compiler/transform.m:
compiler/try_expand.m:
compiler/unneeded_code.m:
Conform to the change above. Delete unneeded module qualifications.
|
||
|
|
15aa457e12 | Delete $module arg from calls to unexpected. | ||
|
|
b96dacdcac |
Make a bunch of switches complete.
compiler/exception_analysis.m:
compiler/frameopt.m:
compiler/get_dependencies.m:
compiler/labelopt.m:
compiler/ml_global_data.m:
compiler/ml_optimize.m:
compiler/options_file.m:
compiler/parse_class.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/type_util.m:
compiler/var_locn.m:
As above.
compiler/inst_match.m:
Fix a stray piece of code.
compiler/loop_inv.m:
Add a module qualification.
compiler/opt_util.m:
Delete two unused predicates.
|
||
|
|
cfcfde1db7 |
Simplify the representation of modes of unifications.
Unifications (x = y) have long had two descriptions of their modes.
One is the unify_mode, which used to look like this:
(initx -> finalx) - (inity -> finaly)
and other is the uni_mode, which used to look like this:
(initx - inity) -> (finalx - finaly)
Each unification had one unify_mode, and each unification that includes
a function symbol had one uni_mode per argument of that function symbol.
The two forms of mode information looked similar enough to be easily
confusable, but were subtly different. As it turns out, there was no
particular reason for the difference, so this diff eliminates the
uni_mode type, and the difference along with it.
What rationale there was for the uni_mode type was that the two modes
it represented (one for each side of the unification) both had their
initial and final insts directly available. This is not true for modes
in general: a value of the mer_mode type could have the form
"InitInst -> FinalInst" (which this diff renames "from_to_mode(InitInst,
FinalInst)", but could also be a "user_defined_inst(...)", which required
a table lookup to turn it into an initial/final pair of insts. This matters,
because almost all code that processes the modes of unifications
works with the initial and final insts.
This diff therefore creates a new type, from_to_insts, which represents
mode information only in the form of terms such as "from_to_insts(InitInst,
FinalInst)", and makes a unify_mode take two values of this type, not mer_mode,
as arguments.
As discussed on m-rev, this diff also renames the old, deceptively named
"arg_mode" type: its new name is "top_functor_mode".
compiler/prog_data.m:
compiler/hlds_goal.m:
As mentioned above, avoid using "->" as a function symbol, and replace
both -> and - with bespoke function symbols.
compiler/mode_util.m:
Add some utility predicates and functions on the new types, and
delete the old utility routines that operated on uni_modes.
Code that uses the new functions and predicates should have a higher level
of abstraction than the code that used to do the same job "manually".
compiler/*.m:
Conform to the changes above, using the new utility predicates and
functions where relevant. In several cases, this required fixing
confusion of the kind described at the top. In all but one case,
the confusion affected only variable names, but in one case,
deconstruct_functor in make_goal.m, it caused a bug. The bug has
had no effect up till now because deconstruct_functor is called
only from three places: try_expand.m, stm_expand.m, and untupling.m.
The incorrect mode (which was the nonsensical ground -> free)
generated by the code of try_expand.m itself was discarded and
overwritten when try_expand.m invoked the modechecker. (I don't
know whether this bugfix makes that invocation redundant or not.)
The other two modules, stm_expand.m and untupling.m, may do something
similar, but in any case, they don't yet work for other reasons.
(A bootcheck with --untupling causes a compiler abort when compiling
deep_profiler/query.m in stage 2 both without and with this fix.)
Delete no-longer-needed imports of the pair module (and of some other
modules).
Put the arguments of some predicates into a more logical order.
In bytecode_gen.m, replace clauses with disjunctions, and delete the
arguments that this step has revealed to be unused.
|
||
|
|
02466fbf52 | Delete some unused predicates; add consider_used pragmas for some others. | ||
|
|
5de235065d | Fix too-long lines. | ||
|
|
cc9912faa8 |
Don't import anything in packages.
Packages are modules whose only job is to serve as a container for submodules. Modules like top_level.m, hlds.m, parse_tree.m and ll_backend.m are packages in this (informal) sense. Besides the include_module declarations for their submodules, most of the packages in the compiler used to import some modules, mostly other packages whose component modules their submodules may need. For example, ll_backend.m used to import parse_tree.m. This meant that modules in the ll_backend package did not have to import parse_tree.m before importing modules in the parse_tree package. However, this had a price. When we add a new module to the parse_tree package, parse_tree.int would change, and this would require the recompilation of ALL the modules in the ll_backend package, even the ones that did NOT import ANY of the modules in the parse_tree package. This happened even at one remove. Pretty much all modules in every one of the backend have to import one or more modules in the hlds package, and they therefore have import hlds.m. Since hlds.m imported transform_hlds.m, any addition of a new middle pass to the transform_hlds package required the recompilation of all backend modules, even in the usual case of the two having nothing to do with each other. This diff removes all import_module declarations from the packages, and replaces them with import_module declarations in the modules that need them. This includes only a SUBSET of their child modules and of the non-child modules that import them. |
||
|
|
7f5a08eb37 |
Split parts of inst_match.m into a new module, inst_test.m
Most modules that imported inst_match did so in order to use
predicates such as inst_is_ground to test properties of insts.
These predicates are split into a new module, leaving the more
complex parts of inst_match to be imported in fewer places.
This makes it easier to change inst_match (for example, to
address mantis bug 264) without unintentional changes to
the rest of the compiler.
compiler/inst_test.m:
New module containing code from inst_match.m.
compiler/check_hlds.m:
Include the new module.
compiler/inst_match.m:
Move code to the new module.
compiler/inst_util.m:
Move inst_expand and inst_expand_and_remove_constrained_inst_vars
here rather than the new module, since they make more sense here.
compiler/build_mode_constraints.m:
compiler/cse_detection.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_report.m:
compiler/fact_table.m:
compiler/float_regs.m:
compiler/goal_util.m:
compiler/interval.m:
compiler/loop_inv.m:
compiler/modecheck_goal.m:
compiler/pd_util.m:
compiler/prog_rep.m:
compiler/simplify_goal_call.m:
compiler/size_prof.m:
compiler/stm_expand.m:
compiler/structure_sharing.domain.m:
compiler/switch_detection.m:
compiler/term_util.m:
compiler/trace_gen.m:
compiler/unify_proc.m:
compiler/unneeded_code.m:
Only import inst_test.
compiler/common.m:
compiler/instmap.m:
compiler/mode_util.m:
compiler/modecheck_call.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/simplify_goal_disj.m:
Import inst_test in addition to inst_match.
compiler/lco.m:
compiler/simplify_goal_switch.m:
Import inst_test and inst_util, but not inst_match.
|
||
|
|
a828e36796 |
Convert (C->T;E) to (if C then T else E).
Avoid the use of semidet functions. |
||
|
|
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.
|
||
|
|
500948d549 |
Break up mdbcomp/prim_data.m. The new modules have much better cohesion.
mdbcomp/sym_name.m:
New module, containing the part of the old prim_data.m that
dealt with sym_names.
mdbcomp/builtin_modules.m:
New module, containing the part of the old prim_data.m that
dealt with builtin modules.
mdbcomp/prim_data.m:
Remove the things that are now in the two new modules.
mdbcomp/mdbcomp.m:
deep_proiler/Mmakefile:
slice/Mmakefile:
Add the two new modules.
browser/*.m:
compiler/*.m:
deep_proiler/*.m:
mdbcomp/*.m:
slice/*.m:
Conform to the above changes.
|
||
|
|
633141efcb |
Remove most non-core predicates from hlds_goal.m.
compiler/hlds_goal.m:
As above.
Put some of the remaining stuff in a more logical order.
compiler/make_goal.m:
This new module contains the predicates, previously in hlds_goal.m,
that construct new goals.
compiler/hlds.m:
compiler/notes/compiler_design.html:
Include the new module.
compiler/goal_form.m:
Move to this existing module the predicates previously in hlds_goal.m
that test whether goals have particular forms (which is the task of
this module).
compiler/*.m:
Conform to the above. Note that no module requires a new import
of BOTH make_goal and goal_form.
|
||
|
|
1e184398f0 |
Fix the has_parallel_conj field of generated procedures (Mantis bug 351).
The event sequence that lead to the compiler abort in Mantis 351 was:
1 With -O5 --intermod-opt, the loop invariant optimization finds a loop
invariant in the pos_mul_karatsuba predicate in library/integer.m.
2 To create the inner predicate (the one that has the already-computed
invariant passed to it), it tries to make a copy of the original predicate,
but sets the has_parallel_conj field of the new proc's proc_info to the
default value, which is has_no_parallel_conj.
3 A later compiler pass has the task of (in par grades) adding synchronization
to parallel conjunctions, and (in non-par grades) converting the parallel
conjunctions to sequential. However, due to the has_no_parallel_conj flag
in the proc_info, it thinks it has no work to do. It therefore leaves the
parallel conjunction intact.
4 The pre-code-generation simplification pass traverses the entire body of
the predicate, and, seeing a parallel conjunction, puts a has_parallel_conj
flag on the proc_info.
5 generate_proc_code sees this flag, but since the target grade is not
parallel, it ignores the flag. Since debugging is not enabled either,
it does NOT create a ContainingGoalMap. (The debugger and parallel
conjunctions are the two things that need this map.)
6 When trying to create the id for the parallel conjunction, par_conj_gen.m
looks for the ContainingGoalMap. Not finding it, it aborts.
The problem arises in step 2, and the main part of the bug fix is to step 2.
However, it adds a sanity check to step 5 as well, to make any such problems
easier to diagnose in the future.
compiler/hlds_pred.m:
Require callers of proc_info_create and similar predicates to specify
whether the new procedure has parallel conjunctions or not.
Arrange the code of these predicates so that all the fields in the
proc_info are filled in with variables whose names say what they stand
for. Previously, many of the fields were just "no" or "[]", not saying
what `maybe' type or list there was no information for.
Put these variables in the same order as the fields.
Add a XXX about the possibility of similar bugs.
compiler/loop_inv.m:
When creating the inner procedure (and its containing predicate),
pass the has_parallel_conj flag of the original predicate. This is
the actual bug fix.
compiler/par_conj_gen.m:
Improve some comments.
compiler/parallel_to_plain_conj.m:
Set a procedure's flag to has_no_parallel_conj right after eliminating
all the parallel conjunctions in it.
compiler/proc_gen.m:
Add a sanity check: if a procedure has has_parallel_conj, then require
that the grade be a parallel grade.
compiler/accumulator.m:
compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/clause_to_proc.m:
compiler/clause_to_proc.m:
compiler/clause_to_proc.m:
compiler/lambda.m:
compiler/make_hlds.m:
compiler/par_loop_control.m:
compiler/pd_info.m:
compiler/stm_expand.m:
compiler/table_gen.m:
compiler/tupling.m:
compiler/unify_proc.m:
compiler/untupling.m:
Conform to the changes above.
|
||
|
|
1f82bd0606 |
Minor cleanup before fixing Mantis bug 351. (This is NOT the bug fix.)
compiler/hlds_pred.m:
Replace some uses of booleans in proc_infos with specialized types.
Put the fields involved into a more logical order. Give their access
predicates more meaningful names.
When creating new proc_infos, give names to all the arguments of
proc_infos and proc_sub_infos. (I believe Mantis bug 351 is in
these arguments.)
compiler/hlds_module.m:
Use the new types in hlds_pred.m where relevant.
compiler/parallel_to_plain_conj.m:
Add some conditionally combined debugging output that helped me track down
the problem.
compiler/loop_inv.m:
mdbcomp/mdbcomp.goal_path.m:
Minor cleanup of some comments.
compiler/code_info.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/granularity.m:
compiler/hlds_out_pred.m:
compiler/inlining.m:
compiler/introduce_parallelism.m:
compiler/lambda.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_middle_passes.m:
compiler/par_loop_control.m:
compiler/proc_gen.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_conj.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
compiler/trace_gen.m:
compiler/trace_params.m:
Conform to the changes above.
|
||
|
|
765f9c6bdc |
Suppress unused argument warnings in procedures generated by the loop-invariant
Branches: main Suppress unused argument warnings in procedures generated by the loop-invariant hoisting pass. A variable which is determined to be invariant may become unused in the auxiliary procedure after invariant goals are deleted, because the variable only appears in invariant goals. It is not that easy to detect such variables (I tried) so we rely on the unused argument elimination pass to remove them, and suppress the warnings. compiler/unused_args.m: As above. compiler/loop_inv.m: Add a comment about the unused arguments. |
||
|
|
b86f973fa9 |
Allow the use of Mercury abstract machine float registers for passing
Branches: main Allow the use of Mercury abstract machine float registers for passing double-precision float arguments in higher order calls. In of itself this is not so useful for typical Mercury code. However, as all non-local procedures are potentially the targets of higher order calls, without this change first order calls to non-local procedures could not use float registers either. That is the actual motivation for this change. The basic mechanism is straightforward. As before, do_call_closure_* is invoked to place the closure's hidden arguments into r1, ..., rN, and extra input arguments shifted into rN+1, etc. With float registers, extra input arguments may also be in f1, f2, etc. and the closure may also have hidden float arguments. Optimising for calls, we order the closure's hidden arguments so that all float register arguments come after all regular register arguments in the vector. Having the arguments out of order does complicate code which needs to deconstruct closures, but that is not so important. Polymorphism complicates things. A closure with type pred(float) may be passed to a procedure expecting pred(T). Due to the `float' argument type, the closure expects its argument in a float register. But when passed to the procedure, the polymorphic argument type means it would be called with the argument in a regular register. Higher-order insts already contain information about the calling convention, without which a higher-order term cannot be called. We extend higher-order insts to include information about the register class required for each argument. For example, we can distinguish between: pred(in) is semidet /* arg regs: [reg_f] */ and pred(in) is semidet /* arg regs: [reg_r] */ Using this information, we can create a wrapper around a higher-order variable if it appears in a context requiring a different calling convention. We do this in a new HLDS pass, called float_regs.m. Note: Mercury code has a tendency to lose insts for higher-order terms, then "recover" them by hacky means. The float_regs pass depends on higher-order insts; it is impossible to create a wrapper for a procedure without knowing how to call it. The float_regs pass will report errors which we otherwise accepted, due to higher-order insts being unavailable. It should be possible for the user to adjust the code to satisfy the pass, though the user may not understand why it should be necessary. In most cases, it probably really *is* unnecessary. We may be able to make the float_regs pass more tolerant of missing higher-order insts in the future. Class method calls do not use float registers because I didn't want to deal with them yet. compiler/options.m: compiler/handle_options.m: Always enable float registers in low-level C grades when floats are wider than a word. compiler/make_hlds_passes.m: Always allow double word floats to be stored unboxed in cells on C grades. compiler/hlds_goal.m: Add an extra field to `generic_call' which gives the register class to use for each argument. This is set by the float_regs pass. compiler/prog_data.m: Add an extra field to `pred_inst_info' which records the register class to use for each argument. This is set by the float_regs pass. compiler/hlds_pred.m: Add a field to `proc_sub_info' which lists the headvars which must be passed via regular registers despite their types. Add a field to `pred_sub_info' to record the original unsubstituted argument types for instance method predicates. compiler/check_typeclass.m: In the pred_info of an instance method predicate, record the original argument types before substituting the type variables for the instance. compiler/float_regs.m: compiler/transform_hlds.m: Add the new HLDS pass. compiler/mercury_compile_middle_passes.m: Run the new pass if float registers are enabled. compiler/lambda.m: Export the predicate to produce a predicate from a lambda. This is reused by float_regs.m to create wrapper closures. Add an argument to `expand_lambda' to set the reg_r_headvars field on the newly created procedure. Delete some unused fields from `lambda_info'. compiler/arg_info.m: Make `generate_proc_arg_info' no longer always use regular registers for calls to exported procedures. Do always use regular registers for class methods calls. Add a version of `make_arg_infos' which takes an explicit list of argument registers. Rename the previous version. Add `generic_call_arg_reg_types' to return the argument registers for a generic call. Add a version of `compute_in_and_out_vars' which additionally separates arguments for float and regular registers. compiler/call_gen.m: Use float registers for argument passing in higher-order calls, as directed by the new field in `generic_call'. compiler/code_util.m: Add a function to encode the number of regular and float register arguments when making a higher-order call. compiler/llds.m: Say that the `do_call_closure_N' functions only work for zero float register arguments. compiler/follow_vars.m: compiler/interval.m: Account for the use of float registers by generic call goals in these passes. compiler/unify_gen.m: Move float register arguments to the end of a closure's hidden arguments vector, after regular register arguments. Count hidden regular and float register arguments separately, but encode them in the same word in the closure. This is preferable to using two words because it reduces the differences between grades with and without float registers present. Disable generating code which creates a closure from an existing closure, if float registers exist. That code does not understand the reordered hidden arguments vector yet. compiler/continuation_info.m: Replace an argument's type_info in the closure layout if the argument is a float *and* is passed via a regular register, when floats are normally passed via float registers. Instead, give it the type_info for `private_builtin.float_box'. compiler/builtin_lib_types.m: Add function to return the type of `private_builtin.float_box/0'. compiler/hlds_out_goal.m: compiler/hlds_out_pred.m: compiler/mercury_to_mercury.m: Dump the new fields added to `generic_call', `pred_inst_info' and `proc_sub_info'. compiler/prog_type.m: Add helper predicate. compiler/*.m: Conform to changes. library/private_builtin.m: Add a type `float_box'. runtime/mercury_ho_call.h: Describe the modified closure representation. Rename the field which counts the number of hidden arguments to prevent it being used incorrectly, as it now encodes two numbers (potentially). Add macros to unpack the encoded field. runtime/mercury_ho_call.c: Update the description of how higher-order calls work. Update code which extracts closure arguments to take account the arguments being reordered in the hidden arguments vector. runtime/mercury_deep_copy.c: runtime/mercury_deep_copy_body.h: runtime/mercury_layout_util.c: runtime/mercury_ml_expand_body.h: Update code which extracts closure arguments to take account the arguments being reordered in the hidden arguments vector. runtime/mercury_type_info.c: runtime/mercury_type_info.h: Add helper function. tools/make_spec_ho_call: Update the generated do_call_closure_* functions to place float register arguments. tests/hard_coded/Mercury.options: tests/hard_coded/Mmakefile: tests/hard_coded/ho_float_reg.exp: tests/hard_coded/ho_float_reg.m: Add new test case. tests/hard_coded/copy_pred.exp: tests/hard_coded/copy_pred.m: tests/hard_coded/deconstruct_arg.exp: tests/hard_coded/deconstruct_arg.exp2: tests/hard_coded/deconstruct_arg.m: Extend test cases with float arguments in closures. tests/debugger/higher_order.exp2: Add alternative output, changed due to closure wrapping. tests/hard_coded/ho_univ_to_type.m: Adjust test case so that the float_regs pass does not report errors about missing higher-order insts. compiler/notes/compiler_design.html: Describe the new module. Delete a duplicated paragraph. compiler/notes/todo.html: TODO: Delete one hundred billion year old todos. |
||
|
|
d00ea69529 |
Switch from using set(prog_var), which is represented using set_ordlist,
Estimated hours taken: 12 Branches: main Switch from using set(prog_var), which is represented using set_ordlist, to set_of_progvar, which is represented using tree_bitset, for most sets of variables in the compiler, including the nonlocals sets in goal_infos. This diff yields about a 5% speedup when compiling the training_cars_full.m stress test, but also about a 1% slowdown on tools/speedtest. Both of these are with the current default state in which tree_bitset is compiled with a whole bunch of sanity checks. If these are disabled, we get roughly a 1% speedup on tools/speedtest. I intend to disable those sanity checks after a shakedown period of a week or two in which the updated version of the compiler is installed on our platforms. compiler/hlds_goal.m: Replace almost all occurrences of set(prog_var) with set_of_progvar. The main exceptions are the types supporting rbmm. compiler/set_of_var.m: Add some more predicates and functions that previous existed on sets but not yet on set_of_vars. compiler/*.m: Conform to the change in hlds_goal.m, and make similar changes in set representations. library/bag.m: Add a predicate and function for creating a bag from a sorted list. We already had them for creating a bag from a set, but a set_of_progvar shouldn't have to be converted to a set. library/robdd.m: Fix deviations from our programming style. |
||
|
|
295415090e |
Convert almost all remaining modules in the compiler to use
Estimated hours taken: 6 Branches: main compiler/*.m: Convert almost all remaining modules in the compiler to use "$module, $pred" instead of "this_file" in error messages. In a few cases, the old error message was misleading, since it contained an incorrect, out-of-date or cut-and-pasted predicate name. tests/invalid/unresolved_overloading.err_exp: Update an expected output containing an updated error message. |
||
|
|
1c3bc03415 |
Make the system compiler with --warn-unused-imports.
Estimated hours taken: 2 Branches: main, release Make the system compiler with --warn-unused-imports. browser/*.m: library/*.m: compiler/*.m: Remove unnecesary imports as flagged by --warn-unused-imports. In some files, do some minor cleanup along the way. |
||
|
|
8a28e40c9b |
Add the predicates sorry, unexpected and expect to library/error.m.
Estimated hours taken: 2 Branches: main Add the predicates sorry, unexpected and expect to library/error.m. compiler/compiler_util.m: library/error.m: Move the predicates sorry, unexpected and expect from compiler_util to error. Put the predicates in error.m into the same order as their declarations. compiler/*.m: Change imports as needed. compiler/lp.m: compiler/lp_rational.m: Change imports as needed, and some minor cleanups. deep_profiler/*.m: Switch to using the new library predicates, instead of calling error directly. Some other minor cleanups. NEWS: Mention the new predicates in the standard library. |
||
|
|
6e336e38f6 |
Fix Mantis bug #128.
Estimated hours taken: 4 Branches: main Fix Mantis bug #128. compiler/loop_inv.m: Fix the bug. The bug was that the loop invariants pass considered the unification that constructed a partially instantiated term to be an invariant goal, and attempted to hoist it out of its predicate. Due to the free variable inside the term, this yielded a compiler abort. Improve the names of predicates and types. tests/valid/bug128.m: Add the regression test for this bug. tests/valid/Mmakefile: tests/valid/Mercury.options: Enable the test case. |
||
|
|
90c505afe0 |
Eliminate dependencies between the processing of different predicates or
Estimated hours taken: 16 Branches: main Eliminate dependencies between the processing of different predicates or procedures in as many cases as possible in passes_aux.m and in optimize.m, so that they can be processed in parallel. The effect of this diff on performance is negligible (a 0.1% speedup, within the noise limit). compiler/passes_aux.m: Don't export predicates that do not need to be exported. Since they were each used for one thing, inline them into their callers. Simplify the main traversal predicates to do just what is needed, and specialize them to their tasks. For tasks that do not update the module_info, the I/O state or anything else while updating a proc_info, allow the procedures of the module to be processed in parallel. Use a systematic naming scheme for the tasks. Use pred_proc_ids to identify the procedure being processed in all tasks, to avoid unnecessary variations in whether the predicates invoked by the tasks need the pred_id, the proc_id or both. compiler/mercury_compile_front_end.m: compiler/mercury_compile_middle_end.m: Update this code to conform to the changes in passes_aux.m. In several cases, conform to changes in the predicates inside the tasks as well, since (after the changes described below) several don't take a pair of I/O states anymore. compiler/mercury_compile_llds_back_end.m: Update this code to conform to the changes in passes_aux.m. In several cases, conform to changes in the predicates inside the tasks as well, since (after the changes described below) several don't take a pair of I/O states anymore. Allow the optimization of different procedures to be done in parallel with --trad-passes. compiler/accumulator.m: compiler/complexity.m: compiler/follow_code.m: compiler/loop_inv.m: compiler/mark_tail_calls.m: compiler/size_prof.m: compiler/ssdebug.m: compiler/store_alloc.m: compiler/structure_sharing.analysis.m: compiler/tupling.m: Conform to the change in passes_aux.m. compiler/deforest.m: compiler/delay_construct.m: compiler/liveness.m: compiler/optimize.m: compiler/pd_info.m: compiler/pd_util.m: compiler/saved_vars.m: compiler/stack_alloc.m: compiler/stack_opt.m: compiler/unneeded_code.m: Conform to the change in passes_aux.m. Consistently use trace goals for progress messages, and eliminate I/O states outside those trace goals. |
||
|
|
ffad388738 |
Fix problems with the ssdebug transformation at higher optimisation levels
Branches: main, 10.04
Fix problems with the ssdebug transformation at higher optimisation levels
and with less conventional code.
compiler/ssdebug.m:
Transform code without relying on a determinism pass afterwards.
Handle procedures with inferred determinisms tighter than declared
determinisms, i.e. inferred semidet but declared cc_nondet, and
inferred cc_multi but declared cc_nondet. We transform the procedure
according to the inferred determinism, but in those two cases we have
to introduce promise_equivalent_solutions scopes.
Do not treat input arguments with more precise final insts,
i.e. ground >> bound(...), as if they were output arguments.
Handle procedures with existentially typed head variables. The
corresponding type_info argument is an output variable, which gets
renamed away to a temporary variable, and is only assigned just before
leaving the procedure. At the point where we build up the variable
list for the exit port, we must use the temporary variable.
Factor out common code in the four process_proc* predicates.
compiler/mercury_compile_middle_passes.m:
Remove an unnecessary determinism pass.
compiler/hlds_pred.m:
Make define_new_pred take a sym_name as the name of the predicate to
define. Thus the new predicate does not have to have the current
module as the module qualifier.
compiler/loop_inv.m:
Auxiliary predicates generated from procedures with the same name from
different modules could clash (in target code) if they had the same
line number. Retain the module qualifier from the original predicate
to distinguish between them.
However, that is still not enough to distinguish special predicates.
Use the predicate id in place of a counter to distinguish between
special predicates for different types. This should only affect
ssdebug grades; special predicates normally wouldn't contain anything
to hoist.
compiler/pd_info.m:
compiler/tupling.m:
compiler/untupling.m:
Conform to change to define_new_pred.
compiler/unused_args.m:
Simplify a bit of code.
|
||
|
|
25c0cebc4d |
Fix bug #145.
Branches: main, 10.04 Fix bug #145. compiler/loop_inv.m: Fix a bug wherein the variable holding the higher order term being called was not considered a goal input. Hence the goal may be incorrectly considered loop-invariant. tests/hard_coded/Mercury.options: tests/hard_coded/Mmakefile: tests/hard_coded/loop_inv_test4.exp: tests/hard_coded/loop_inv_test4.m: Add test case. Enable loop_inv_test3 which seems to have been left out accidentally. |
||
|
|
590216cceb |
Fix a bug. An `unused' variable in an invariant call was treated
Branches: main
compiler/loop_inv.m:
Fix a bug. An `unused' variable in an invariant call was treated
like an output variable and added to the invariant variables list,
and hoisted.
tests/hard_coded/Mercury.options:
tests/hard_coded/loop_inv_test3.exp:
tests/hard_coded/loop_inv_test3.m:
Add test case.
|
||
|
|
4ebe3d0d7e |
Stop storing globals in the I/O state, and divide mercury_compile.m
Estimated hours taken: 60 Branches: main Stop storing globals in the I/O state, and divide mercury_compile.m into smaller, more cohesive modules. (This diff started out as doing only the latter, but it became clear that this was effectively impossible without the former, and the former ended up accounting for the bulk of the changes.) Taking the globals out of the I/O state required figuring out how globals data flowed between pieces of code that were often widely separated. Such flows were invisible when globals could be hidden in the I/O state, but now they are visible, because the affected code now passes around globals structures explicitly. In some cases, the old flow looked buggy, as when one job invoked by mmc --make could affect the globals value of its parent or the globals value passed to the next job. I tried to fix such problems when I saw them. I am not 100% sure I succeeded in every case (I may have replaced old bugs with new ones), but at least now the flow is out in the open, and any bugs should be much easier to track down and fix. In most cases, changes the globals after the initial setup are intended to be in effect only during the invocation of a few calls. This used to be done by remembering the initial values of the to-be-changed options, changing their values in the globals in the I/O state, making the calls, and restoring the old values of the options. We now simply create a new version of the globals structure, pass it to the calls to be affected, and then discard it. In two cases, when discovering reasons why (1) smart recompilation should not be done or (2) item version numbers should not be generated, the record of the discovery needs to survive this discarding. This is why in those cases, we record the discovery by setting a mutable attached to the I/O state. We use pure code (with I/O states) both to read and to write the mutables, so this is no worse semantically than storing the information in the globals structure inside the I/O state. (Also, we were already using such a mutable for recording whether -E could add more information.) In many modules, the globals information had to be threaded through several predicates in the module. In some places, this was made more difficult by predicates being defined by many clauses. In those cases, this diff converts those predicates to using explicit disjunctions. compiler/globals.m: Stop storing the globals structure in the I/O state, and remove the predicates that accessed it there. Move a mutable and its access predicate here from handle_options.m, since here is when the mutables treated the same way are. In a couple of cases, the value of an option is available in a mutable for speed of access from inside performance-critical code. Set the values of those mutables from the option when the processing of option values is finished, not when it is starting, since otherwise the copies of each option could end up inconsistent. Validate the reuse strategy option here, since doing it during ctgc analysis (a) is too late, and (b) would require an update to the globals to be done at an otherwise inconvenient place in the code. Put the reuse strategy into the globals structure. Two fields in the globals structure were unused. One (have_printed_usage) was made redundant when the one predicate that used it itself became unused; the other (source_file_map) was effectively replaced by a mutable some time ago. Delete these fields from the globals. Give the fields of the globals structure a distinguishing prefix. Put the type declarations, predicate declarations and predicate definitions in a consistent order. compiler/source_file_map.m: Record this module's results only in the mutable (it serves as a cache), not in globals structure. Use explicitly passed globals structure for other purposes. compiler/handle_options.m: Rename handle_options as handle_given_options, since it does not process THE options to the program, but the options it is given, and even during the processing of a single module, it can be invoked up the three times in a row, each time being given different options. (It was up to four times in a row before this diff.) Make handle_given_options explicitly return the globals structure it creates. Since it does not take an old global structure as input and globals are not stored in the I/O state, it is now clear that the globals structure it returns is affected only by the default values of the options and the options it processes. Before this diff, in the presence of errors in the options, handle_options *could* return (implicitly, in the I/O state) the globals structure that happened to be in the I/O state when it was invoked. Provide a separate predicate for generating a dummy globals based only on the default values of options. This allows by mercury_compile.m to stop abusing a more general-purpose predicate from handle_options.m, which we no longer export. Remove the mutable and access predicate moved to globals.m. compiler/options.m: Document the fact that two options, smart_recompilation and generate_item_version_numbers, should not be used without seeing whether the functionalities they call for have been disabled. compiler/mercury_compile_front_end.m: compiler/mercury_compile_middle_passes.m: compiler/mercury_compile_llds_back_end.m: compiler/mercury_compile_mlds_back_end.m: compiler/mercury_compile_erl_back_end.m: New modules carved out of the old mercury_compile.m. They each cover exactly the areas suggested by their names. Each of the modules is more cohesive than the old mercury_compile.m. Their code is also arranged in a more logical order, with predicates representing compiler passes being defined in the order of their invocation. Some of these modules export predicates for use by their siblings, showing the dependencies between the groups of passes. compiler/top_level.m: compiler/notes/compiler_design.html: Add the new modules. compiler/mark_static_terms.m: Move this module from the ml_backend package to the hlds package, since (a) it does not depend on the MLDS in any way, and (b) it is also needed by a compiler pass (loop invariants) in the middle passes. compiler/hlds.m: compiler/ml_backend.m: compiler/notes/compiler_design.html: Reflect mark_static_terms.m's change of package. compiler/passes_aux.m: Move the predicates for dumping out the hLDS here from mercury_compile.m, since the new modules also need them. Look up globals in the HLDS, not the I/O state. compiler/hlds_module.m: Store the prefix (common part) of HLDS dump file names in the HLDS itself, so that the code moved to passes_aux.m can figure out the file name for a HLDS dump without doing system calls. Give the field names of some structures prefixes to avoid ambiguity. compiler/mercury_compile.m: Remove the code moved to the other modules. This module now looks after only option handling (such as deciding whether to generate .int3 files, .int files, .opt files etc), and the compilation passes up to and including the creation of the first version of the HLDS. Everything after that is subcontracted to the new modules. Simplify and make explicit the flow of globals information. When invoking predicates that could disable smart recompilation, check whether they have done so, and if yes, update the globals accordingly. When compiling via gcc, we need to link into the executable the object files of any separate C files we generate for C code foreign_procs, which we cannot translate into gcc's internal structures without becoming a C compiler as well as a Mercury compiler. Instead of adding such files to the accumulating option for extra object files in the globals structure, we return their names using the already existing mechanism we have always used to link the object files of fact tables into the executable. Give several predicates more descriptive names. Put predicates in a more logical order. compiler/make.m: compiler/make.dependencies.m: compiler/make.module_target.m: compiler/make.module_dep_file.m: compiler/make.program_target.m: compiler/make.util.m: Require callers to supply globals structures explicitly, not via the I/O state. Afterward pass them around explicitly, passing modified versions to mercury_compile.m when invoking it with module- and/or task-specific options. Due the extensive use of partial application for higher order code in these modules, passing around the globals structures explicitly is quite tricky here. There may be cases where a predicate uses an old globals structure it got from a closure instead of the updated module- and/or task-specific globals it should be using, or vice versa. However, it is just as likely that, this diff fixes old problems by preventing the implicit flow of updated-only-for-one-invocation globals structures back to the original invoking context. Although I have tried to be careful about this, it is also possible that in some places, the code is using an updated-for-an-invocation globals structure in some but not all of the places where it SHOULD be used. compiler/c_util.m: compiler/compile_target_code.m: compiler/compiler_util.m: compiler/error_util.m: compiler/file_names.m: compiler/file_util.m: compiler/ilasm.m: compiler/ml_optimize.m: compiler/mlds_to_managed.m: compiler/module_cmds.m: compiler/modules.m: compiler/options_file.m: compiler/pd_debug.m: compiler/prog_io.m: compiler/transform_llds.m: compiler/write_deps_file.m: Require callers to supply globals structures explicitly, not via the I/O state. In some cases, the explicit globals structure argument allows a predicate to dispense with the I/O states previously passed to it. In some modules, rename some predicates, types and/or function symbols to avoid ambiguity. compiler/read_modules.m: Require callers to supply globals structures explicitly, not via the I/O state. Record when smart recompilation and the generation of item version numbers should be disabled. compiler/opt_debug.m: compiler/process_util.m: Require callers to supply the needed options explicitly, not via the globals in the I/O state. compiler/analysis.m: compiler/analysis.file.m: compiler/mmc_analysis.m: Make the analysis framework's methods take their global structures as explicit arguments, not as implicit data stored in the I/O state. Stop using `with_type` and `with_inst` declarations unnecessarily. Rename some predicates to avoid ambiguity. compiler/hlds_out.m: compiler/llds_out.m: compiler/mercury_to_mercury.m: compiler/mlds_to_c.m: compiler/mlds_to_java.m: compiler/optimize.m: Make these modules stop accessing the globals from the I/O state. Do this by requiring the callers of their top predicates to explicitly supply a globals structure. To compensate for the cost of having to pass around a representation of the options, look up the values of the options of interest just once, to make further access much faster. (In the case of mlds_to_c.m, the code already did much of this, but it still had a few accesses to globals in the I/O state that this diff eliminates.) If the module exports a predicate that needs these pre-looked-up options, then export the type of this data structure and its initialization function. compiler/frameopt.m: Since this module needs only one option from the globals, pass that option instead of the globals. compiler/accumulator.m: compiler/add_clause.m: compiler/closure_analysis.m: compiler/complexity.m: compiler/deforest.m: compiler/delay_construct.m: compiler/elds_to_erlang.m: compiler/exception_analysis.m: compiler/fact_table.m: compiler/intermod.m: compiler/mode_constraints.m: compiler/mode_errors.m: compiler/pd_util.m: compiler/post_term_analysis.m: compiler/recompilation.usage.m: compiler/size_prof.usage.m: compiler/structure_reuse.analysis.m: compiler/structure_reuse.direct.choose_reuse.m: compiler/structure_reuse.direct.m: compiler/structure_sharing.analysis.m: compiler/tabling_analysis.m: compiler/term_constr_errors.m: compiler/term_constr_fixpoint.m: compiler/term_constr_initial.m: compiler/term_constr_main.m: compiler/term_constr_util.m: compiler/trailing_analysis.m: compiler/trans_opt.m: compiler/typecheck_info.m: Look up globals information from the HLDS, not the I/O state. Conform to the changes above. compiler/gcc.m: compiler/maybe_mlds_to_gcc.pp: compiler/mlds_to_gcc.m: Look up globals information from the HLDS, not the I/O state. Conform to the changes above. Convert these modules to our current programming style. compiler/termination.m: Look up globals information from the HLDS, not the I/O state. Conform to the changes above. Report some warnings with error_specs, instead of immediately printing them out. compiler/export.m: compiler/il_peephole.m: compiler/layout_out.m: compiler/rtti_out.m: compiler/liveness.m: compiler/make_hlds.m: compiler/make_hlds_passes.m: compiler/mlds_to_il.m: compiler/mlds_to_ilasm.m: compiler/recompilation.check.m: compiler/stack_opt.m: compiler/superhomogeneous.m: compiler/tupling..m: compiler/unneeded_code.m: compiler/unused_args.m: compiler/unused_import.m: compiler/xml_documentation.m: Conform to the changes above. compiler/equiv_type_hlds.m: Give the field names of a structure prefixes to avoid ambiguity. Stop using `with_type` and `with_inst` declarations unnecessarily. compiler/loop_inv.m: compiler/pd_info.m: compiler/stack_layout.m: Give the field names of some structures prefixes to avoid ambiguity. compiler/add_pragma.m: Add notes. compiler/string.m: NEWS: Add a det version of remove_suffix, for use by new code above. |
||
|
|
77a6a6c10c |
Implement several more changes that together speed up compilation time
Estimated hours taken: 16 Branches: main Implement several more changes that together speed up compilation time on training_cars_full by 12%, and also improve tools/speedtest -h by 7.2% and tools/speedtest by 1.6%. The first change is designed to eliminate the time that the compiler spends constructing error messages that are then ignored. The working predicates of prog_io_sym_name used to always return a single result, which either gave a description of the thing being looked, or an error message. However, in many places, the caller did not consider not finding the thing being looked for to be an error, and thus threw away the error message, keeping only the "not found" indication. For each predicate with such callers, this diff provides a parallel predicate that indicates "not found" simply by failing. This allows us to eliminate the construction of the error message, the preparation for the construction of the error message (usually by describing the context), and the construction of the "ok" wrapper. The second change is to specialize the handling of from_ground_term_construct scopes in the termination analyzer. To make this easier, I also cleaned up of the infrastructure of the termination analyzer. The third change is to avoid traversing from_ground_term_construct scopes in quantification.m when finding the variables in a goal, since termination analysis no longer needs the information it gathers. The fourth change is to avoid traversing second and later conjuncts in conjunctions twice. The first step in handling conjunctions is to call implicitly_quantify_conj, which builds up a data structure that pairs each conjunct with the variables that occur free in all the conjuncts following it. However, after this was done and each conjunct was annotated with its nonlocals, we used to compute the variables that occur free in the conjunction as a whole from scratch. This diff changes the code so that we now compute that set based on the information we gathered earlier, avoiding a redundant traversal. The fifth change is to create specialized, lower-arity versions of many of the predicates in quantification.m. These versions are intended for traversals that take place after the compiler has replaced lambda expressions with references to separate procedures. These traversals do not need to pass around arguments representing the variables occurring free in the (now non-existent) lambda expressions. compiler/prog_io_sym_name.m: Make the first change described above. Change some predicate names to adopt a consistent naming scheme in which predicates that do the same job and differ only in how they handle errors have names that differ only in a "try_" prefix. Add some predicate versions that do common tests on the output of the base versions. For example, try_parse_sym_name_and_no_args is a version of try_parse_sym_name_and_args that insists on finding an empty argument list. Remove the unused "error term" argument that we used to need a while ago. Move some predicate definitions to make their order match the order of their declarations. Turn a predicate into a function for its caller's convenience. compiler/term_constr_build.m: Make the second change described above by modeling each from_ground_term_construct scope as a single unification, assigning the total size of the ground term to the variable being built. compiler/term_constr_util.m: Put the arguments of some predicates into a more standard order. compiler/lp_rational.m: Change the names of some function symbols to avoid both the use of graphic characters that require quoting and clashes with other types. Change the names of some predicates to make their purpose clear, and to avoid ambiguity. compiler/quantification.m: Make the third, fourth and fifth changes described above. compiler/*.m: Conform to the changes above. |
||
|
|
cc9423e35d |
Rationalize the way the MLDS code generator handles global data structures.
Estimated hours taken: 80
Branches: main
Rationalize the way the MLDS code generator handles global data structures.
The previous way was somewhat perverse in several respects.
The first respect was that static Mercury terms were translated into global
MLDS definitions, those MLDS definitions were turned into local definitions,
and then later turned back into global definitions. However, while they were
local definitions, they were part of the list of definitions processed
by ml_elim_nested. Since the complexity of ml_elim_nested is at least O(n^2)
and probably O(n^3) or worse, and since the definitions representing static
terms could increase the value of n from dozens or hundred to many thousands,
this was a BAD IDEA, especially since by construction, the MLDS definitions
representing ground terms cannot have other definitions nested inside them.
This problem was the main reason why previously the compiler took effectively
forever to compile any program with large tables of facts in MLDS grades.
The second respect has to do with the fact that terms are represented as tagged
pointers to memory cells. When generating an MLDS definition (a static cell)
for a ground term, ml_unify_gen.m remembered the name of the MLDS variable
representing the static cell, but forgot the tag on the pointer. So when
that ground term was used as an argument in another, bigger ground term,
it had to figure out the tag all over again. The argument of the
construct_statically functor in construct unifications had as its sole purpose
the provision of the data needed by this recomputation.
The third respect was that the code generator could generate duplicate
definitions (same variable name, same content) when two conjoined goals
referred to two or more type_infos or pseudo_type_infos for the same type.
The code generator used to handle it by wrapping a scope around the later
definitions, which (a) wasted memory, and (b) could yield warnings from
the C compiler about shadowed declarations. This problem used to prevent
the compiler from bootchecking in grade hlc_nest.gc; with this diff,
we can again bootcheck in grade hlc_nest.gc.
The fourth respect was that the code generator's record of which variables are
bound to constant terms was inaccurate, because it was never reset. If a
variable was bound to a constant term in one branch of a control structure,
the MLDS code generator state's record of this binding was still there
when the compiler generated code for the later branches of that control
structure. It did not use the record, but it was still there.
The MLDS code generator also used a horribly inefficient algorithm for figuring
out which Mercury variables should have their corresponding MLDS variables
declared at a given goal. It gathered up all the goals's variables, and then
gathered up all the variables in the goal's immediate subgoals. This meant
that the entire goal had to be traversed TWICE, with the second traversal
being needed only because the first one gathered too much information.
Those traversals were a huge performance problem on programs with large static
terms, since their representation is large conjunctions of unifications,
which have large numbers of variables. To add insult to injury, the traversals
used ordered lists to represent the sets, which meant that (given the ascending
variable numbers in from_ground_term scopes), adding the n'th unification's
new variable to the set took O(n) time, with the complexity of the whole
algorithm being quadratic.
Besides fixing these problems, this diff makes the MLDS code generator
handle from_ground_term_construct scopes specially, in a streamlined fashion,
just as the LLDS backend has done for a while now. It also fixes a bunch
of other performance problems pointed out by profiling.
This diff reduces the compilation time on the training_cars_150.m benchmark,
which has nothing but ground terms, from 94+ seconds to less than 2 seconds,
a 98% speedup. (This is with from_ground_term scopes enabled, as is
appropriate.) For ordinary programs, compilation time in grade hlc.gc
is reduced by about 3%.
compiler/ml_global_data.m:
A new module that manages the MLDS code generator's records about
static definitions. It separates those definitions into different
categories based on what kind of processing they need. At the moment,
the categories are: definitions of cells for ground terms and
definitions of cells for RTTI, with the latter being subdivided
into those that may need to be processed by ml_elim_nested
and those that are known not to need such processing.
It also records whether we have generated representation for a
type_info or pseudo_type yet, so that we can avoid generating duplicate
definitions. This, and the code that uses this, fixes the third
problem.
compiler/ml_backend.m:
compiler/notes/compiler_design.html:
Add the new module.
compiler/goal_util.m:
Add a warning about the bad complexity of goal_vars.
compiler/hlds_goal.m:
Remove the static_cons type, since it is no longer needed.
Remove the static_cons argument of the construct_statically
functor of the how_to_construct type.
Fix an out-of-date comment about from_ground_term scopes.
compiler/mark_static_terms.m:
Change the data structure being threaded through this module
from being a map(prog_var, static_cons) to a set_tree234(prog_var),
since we no longer need the information stored in static_conses.
compiler/modes.m:
Do not compute static_conses.
compiler/mlds.m:
Put the information about global data into a separate field of
the MLDS, since some classes of such data can have their treatment
optimized.
Put the arguments of some functions into a more logical order.
Give some function symbol names prefixes to avoid ambiguities.
Change or add some field name prefixes to avoid ambiguities.
Avoid the unnecessary use of higher order code in handling the flags of
MLDS definitions. The new code is simpler as well as faster than the
old.
compiler/ml_code_util.m:
Make ml_global_data a part of the MLDS code generator state. This
allows a bunch of predicates in the MLDS code generator to no longer
return lists of definitions, since those definitions are now put
into this new part of ml_gen_info, which ml_elim_nested won't touch.
This is part of the solution of the first problem.
Replace the field that mapped vars to the name of the global static
definition involved in representing the ground term bound to that var
with a field that maps the var to the actual rval (which will be a
tagged pointer to that static definition), though we also remember
the variable's type, since this is needed for making decisions about
boxing. This is part of the solution for the second problem.
Rename the extra_defns field of the ml_gen_info to the
closure_wrapper_defns field, since this is the only thing that
it is used for.
Add fields to the ml_gen_info holding the value of the --highlevel-data
option and the compilation target, since these are needed very often,
and looking them up in the globals is too slow.
Access all fields of ml_gen_info via access predicates, not via field
notation, so that the number of accesses to each field can be measured
by deep profiling.
Separate the ml_gen_info structure into a main structure whose fields
are frequently updated and which fits into an 8-word block of memory,
and a substructure whose fields are read-only or rarely updated.
This should help improve memory performance.
Provide more useful access predicates to some of the counters,
and make them harder to confuse by using fewer type synonyms.
Provide some more convenient predicates for creating auxiliary MLDS
variables (those that do not correspond to Mercury variables).
Delete ml_join_decls, since fixing the third problem means that it is
no longer needed.
Delete some other predicates whose job has been taken over by
ml_global_data.m.
Put the arguments of some predicates into a more logical order.
Rename some predicates to avoid ambiguities.
compiler/ml_code_gen.m:
As part of the fix for the repeated traversals of parts of the
procedure body with goal_vars, we now have to run quantification
before generating MLDS for a procedure. Quantification does in
one optimized pass what the old code used to do in many unoptimized
passes. However, since quantification can change the HLDS, this
requires a small change in the module's interface. HLDS dump 499
now dumps to the HLDS version *output* by MLDS code generation,
not the HLDS version that is its input.
Use the (now guaranteed accurate) nonlocals fields of the goal and
its immediate subgoals to figure out what variables need to declared at
each goal. This fixes the fifth problem.
Special case from_ground_term_construct scopes. (This code recognizes
such scopes; the code that handles them is in ml_unify_gen.m.)
Use trace goals to print progress messages.
Avoid the use of io.format and string.format (see below).
Group the predicates of this module a bit more meaningfully.
(A really good order requires more reordering, but that will be
a separate change.)
Give some predicates more meaningful names.
Add predicates that allow the convenient implementation of branched
control structures.
Use them in the implementation of the branched control structures
handled in this module
Together, these solve the fourth problem.
compiler/ml_switch_gen.m:
compiler/ml_string_switch.m:
Use them in the implementation of the branched control structures
handled in these modules.
Use the new module to generate constant data.
compiler/ml_unify_gen.m:
Implement the changes described at the top.
Divide ml_gen_new_object, a predicate that used to be 220 lines long,
into several pieces, one for each different method of constructing new
objects (memory cells).
Delete the (extensive) code that used to recreate the tags on
pointers to static cells. This code used to also recreate static
arguments in their entirety if they were NOT pointers to cells,
e.g. if they were integers or floats or strings, so we now record
the values of such non-tagged-pointer constant terms also.
Put the arguments of some predicates into a more logical order.
In addition, some predicates now need ml_global_data threaded through
them, but avoid returning lists of definitions.
compiler/ml_call_gen.m:
Simplify the interface of the predicate that decides on boxing and
unboxing, making it callable from places that do not have a full code
generator state (such as the streamlined code in ml_unify_gen handling
from_ground_term_construct scopes).
Avoid the unnecessary use of higher order code.
Rename a predicate to avoid ambiguity.
compiler/ml_closure_gen.m;
Generate the closure layout information as static global data.
compiler/ml_elim_nested.m:
Thread the globals through this module instead of the I/O state,
since the only thing the I/O state was used for was accessing the
globals.
Traverse only the small subset of global data that needs to be
traversed.
compiler/ml_type_gen.m:
Use trace goals to print progress messages.
Replace a semidet predicate with a function returning a tailored type,
for improved robustness.
Look up stuff in the globals structure less frequently, by reusing the
results of past lookups.
compiler/rtti_to_mlds.m:
Restructure the code in this module in two respects.
First, instead of having predicates returning lists of
MLDS definitions, make them add those definitions to a ml_global_data
data structure threaded through the module. Since the ml_global_data
structure records which type_infos and pseudo_type_infos we have
already generated definitions for, this allows us to avoid generating
duplicate static cells for them. This allows us to avoid the old
code's roundabout way of handling of such cells.
Second, several predicates of this module returned initializers,
which their caller then stuck into a static definition. This diff
changes things so that wherever possible, the predicate that computes
the initializers also creates the cell definition. This improves the
code's cohesion.
Also, rename some predicates where, after the above changes, their old
names are no longer appropriate.
compiler/mlds_to_c.m:
Avoid the use of io.format and string.format, since (after the more
extensive changes described at the top of this log message) this
turned out to account for a nontrivial percentage of the compiler's
runtime.
Instead of repeatedly looking up the values of some options
in a copy of the globals obtained from the I/O state, thread
through this module a term that records all the information
that this module needs from globals.
Threading this data through this module instead of looking something
upo in the I/O state leads to a slight slowdown, but not having to do
option lookups in large trees leads to a larger speedup.
Rename some predicates to ambiguity.
Convert some predicate definitions from multiple clauses into one,
for clarity.
Conform to the changes in the structure of the MLDS.
compiler/mlds_to_gcc.m:
Conform to the changes in the structure of the MLDS.
compiler/mlds_to_il.m:
compiler/mlds_to_ilasm.m:
compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
Conform to the changes in the structure of the MLDS.
Pass the globals to this module instead of looking it up in the
I/O state.
Rename some predicates to ambiguity.
Avoid the unnecessary use of higher order code.
In mlds_to_managed.m, thread a previously frequently-looked-up value
through the module.
compiler/typecheck_info.m:
The code for expanding equivalence types in a procedure's vartypes
field used to iterate on the keys of the vartypes map, and then
looked up the associated values in the map. This diff replaces hat
with new code that iterates on an association list that puts the
value right next to its key (a list that the old code just threw away).
The var/type assoc list we compute is still sorted on the variables,
so create the new vartypes map not by repeated insertion, but
directly (using map.from_sorted_assoc_list).
compiler/purity.m:
Add a note about a possible future speedup.
compiler/prog_io_sym_name.m:
Rename a predicate to avoid an ambiguity, and to make its purpose
clearer.
compiler/globals.m:
compiler/handle_options.m:
compiler/mlds_to_il.m:
Check whether the mmc option that specifies the IL version number is
well formed at the start of the compilation, in handle_options.m,
when all the other option values are checked if needed, rather than
when generating IL code. This way, we can generate an error message,
not a compiler abort.
The IL version number is now recorded in the globals structure.
compiler/make_hlds_warn.m:
Do not descend into from_ground_term scopes, since by construction,
they cannot contain singleton variables.
compiler/analysis.file.m:
compiler/deep_profiling..m:
compiler/field_access.m:
compiler/hlds_out.m:
compiler/interval.m:
compiler/liveness.m:
compiler/loop_inv.m:
compiler/make.module_dep_file.m:
compiler/mercury_compile.m:
compiler/loop_inv.m:
compiler/ml_tailcall.m:
compiler/module_qual.m:
compiler/prog_ctgc.m:
compiler/prog_io_dcg.m:
compiler/prog_io_goal.m:
compiler/prog_io_pragma.m:
compiler/prog_io_typeclass.m:
compiler/prog_io_util.m:
compiler/quantification.m:
compiler/rbmm.add_rbmm_goal_infos.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/structure_reuse.indirect.m:
compiler/superhomogeneous.m:
compiler/var_locn.m:
Conform to the changes above.
compiler/unused_args.m:
Fix an ambiguous predicate name.
tests/hard_coded/float_field.{m,exp}:
Add some more test situations to this test case. These test
the handling of notag types in static terms more thoroughly
than before.
|
||
|
|
5ad9a27793 |
Speed up the compiler's handling of code that constructs large ground terms
Estimated hours taken: 80
Branches: main
Speed up the compiler's handling of code that constructs large ground terms
by specializing the treatment of such code.
This diff reduces the compilation time for training_cars_full.m from 106.9
seconds to 30.3 seconds on alys, my laptop. The time on tools/speedtest
stays pretty much the same.
compiler/hlds_goal.m:
Record the classification of from_ground_term scopes as purely
constructing terms, purely deconstructing them or something other.
Fix an old potential bug: variables inside the construct_how fields
of unifications weren't being renamed along with other variables.
This is a bug if any part of the compiler later looks at those
variables. (I am not sure whether or not this happens.)
compiler/superhomogenous.m:
Provisionally mark newly constructed static terms as being
from_ground_term_construct. Mode checking will either confirm this
or change the scope kind.
compiler/options.m:
compiler/handle_options.m:
Add a new option, from_ground_term_threshold, that allows the user to
set the boundary between ground terms that get scopes and ground terms
do not. I plan to experiment with different settings later.
compiler/modes.m:
Make this classification. For scopes that construct ground terms,
use a specialized algorithm that avoids quadratic behavior.
(It does not access the unify_inst_table, which is where the
factor of N other than the length of the goal list came from.)
The total size of the instmap_deltas, if printed out, still looks like
O(N^2) in size, but due to structure sharing it needs only O(N) memory.
For scopes that construct ground terms, set the determinism information
so that det_analysis.m doesn't have to traverse such scopes.
When handling disjunctions, check whether some nonlocals of the
disjunctions are constructed by from_ground_term_construct scopes.
For any such nonlocals, set their insts to just ground, throwing away
the precise information we have about exactly what function symbols
they and ALL their subterms are bound to. This is HUGE win, since
it allows us avoid spending a lot of time building a huge merge_inst
table, which later passes of the compiler (e.g. equiv_type_hlds) would
then have to spend similarly huge times traversing.
This approach does have a down side. If lots of arms of a disjunction
bind a nonlocal to a large ground term, but a few bind it to a SMALL
ground term, a term below the from_ground_term_threshold, this
optimization won't kick in. That could be one purpose of the new
option. It isn't documented yet; I will seek feedback about its
usefulness first.
compiler/modecheck_unify.m:
Handle the three different kinds of right hand sides separately.
This yields a small speedup, because now we don't test rhs_vars and
rhs_functors (the common right hand sides) for a special case
(goals containing "any" insts) that is applicable only to
rhs_lambda_goals.
compiler/unique_modes.m:
Don't traverse scopes that construct ground terms, since modes.m has
already done everything that needs to be done.
compiler/det_analysis.m:
Don't traverse scopes that construct ground terms, since modes.m has
already done the needed work.
compiler/instmap.m:
Add a new predicate for use by modes.m.
Many predicate names in this module were quite uninformative; give them
informative names.
compiler/polymorphism.m:
If this pass invalidates the from_ground_term_construct invariants,
then mark the relevant scope as from_ground_term_other.
Delete two unused access predicates.
compiler/equiv_type_hlds.m:
Don't traverse scopes that construct ground terms, since modes.m
ensures that their instmap deltas do not contain typed insts, and
thus the scope cannot contain types that need to be expanded.
Convert some predicates to single clauses.
compiler/goal_form.m:
compiler/goal_util.m:
In predicates that test goals for various properties, don't traverse
scopes that construct ground terms when the outcome of the test
is the same for all such scopes.
Convert some predicates to single clauses.
compiler/simplify.m:
Do not look for common structs in from_ground_term_construct scopes,
both because this speeds up the compiler, and because retaining
references to ground terms is in fact a pessimization, not an
optimization. This is because (a) those references need to be stored in
stack slots across calls, and (b) the C code generators ensure that
the cells representing ground terms will be shared as needed.
If all arms of a switch are from_ground_term_construct scopes,
do not merge the instmap_deltas from those arms, since this is
both time-consuming (even after the other changes in this diff)
and extremely unlikely to improve the instmap_delta.
Disable common_struct in from_ground_term_construct scopes,
since for these scopes, it is actually a pessimization.
Do not delete from_ground_term_construct scopes, since many
compiler passes can now use them.
Do some manual deforestation, break up some large predicates,
and give better names to some.
compiler/liveness.m
Special-case the handling from_ground_term_construct scopes. This
allows us to traverse them just once instead of three times, and this
traversal is simpler and faster than any of the three.
In some traversals, we were switching on the goal type twice; once
in e.g. detect_liveness_in_goal_2, and once by calling
goal_expr_has_subgoals. Eliminate the double switching by merging
the relevant predicates. (The double-switching structure was easier
to work with before we had multi-cons-id switches.)
compiler/typecheck.m:
Move a lookup after a test, so we don't have to do it if the test
fails.
Provide a specialized mode for a predicate. This should allow the
compiler to eliminate an argument and a test in the common case.
Note a possible chance for a speedup.
compiler/typecheck_info.m:
Don't apply empty substitutions to the types of a possibly very large
set of variables.
compiler/quantification.m:
Don't quantify from_ground_term_construct scopes. They are created
correctly quantified, and any compiler pass that invalidates that
quantification also removes the from_ground_term_construct mark.
Don't apply empty renamings to a possibly very large set of variables.
Move the code for handling scopes to its own predicate, to avoid
overwhelming the code that handles other kinds of goals. Even from
this, factor out the renaming code, since it is needed only for
some kinds of scopes.
Make some predicate names better reflect what the predicate does.
compiler/pd_cost.m:
For from_ground_term_construct scopes, instead of computing their cost
by adding up the costs of the goals inside, make their cost a constant,
since binding a variable to a static term takes constant time.
compiler/pd_info.m:
Add prefixes on field names to avoid ambiguities.
compiler/add_heap_ops.m:
compiler/add_trail_ops.m:
compiler/closure_analysis.m:
compiler/constraint.m:
compiler/cse_detection.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/distance_granularity.m:
compiler/exception_analysis.m:
compiler/follow_code.m:
compiler/follow_vars.m:
compiler/format_call.m:
compiler/granularity.m:
compiler/higher_order.m:
compiler/implicit_parallelism.m:
compiler/inlining.m:
compiler/interval.m:
compiler/lambda.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/loop_inv.m:
compiler/middle_rec.m:
compiler/mode_util.m:
compiler/parallel_to_plain_conj.m:
compiler/saved_vars.m:
compiler/stm_expand.m:
compiler/store_alloc.m:
compiler/stratify.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.lbu.m:
compiler/structure_sharing.analysis.m:
compiler/switch_detection.analysis.m:
compiler/trail_analysis.m:
compiler/term_pass1.m:
compiler/tupling.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
These passes have nothing to do in from_ground_term_construct scopes,
so don't traverse them.
In some modules (e.g. dead_proc_elim), some traversals had to be kept.
In loop_inv.m, replace a code structure that updated accumulators
with functions (which prevented the natural use of state variables),
that in lots of places reconstructed the term it had just
deconstructed, and obscured the identical handling of different kinds
of goals, with a structure based on predicates, state variables and
shared code for different goal types where possible.
In store_alloc.m, avoid some double switching on the same value.
In stratify.m, unneeded_code.m and unused_args.m, rename predicates
to avoid ambiguities.
compiler/goal_path.m:
compiler/goal_util.m:
compiler/implementation_defined_literals.m:
compiler/intermode.m:
compiler/mark_static_terms.m:
compiler/ml_code_gen.m:
compiler/mode_ordering.m:
compiler/ordering_mode_constraints.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/rbmm.actual_region_arguments.m:
compiler/rbmm.add_rbmm_goal_infos.m:
compiler/rbmm.condition_renaming.m:
compiler/rbmm.execution_path.m:
compiler/rbmm.region_transformation.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lfu.m:
compiler/structure_reuse.versions.m:
compiler/term_const_build.m:
compiler/term_traversal.m:
compiler/unused_imports.m:
Mark places where we cannot (yet) special case
from_ground_term_construct scopes.
In structure_reuse.lfu.m, turn nested if-then-elses into a switch in.
compiler/size_prof.m:
Turn from_ground_term_construct scopes into from_ground_term_other
scopes, since in term size profiling grades, we need to attach sizes to
terms.
Give predicates better names.
compiler/*.m:
Minor changes to conform to the changes above.
compiler/make_hlds_passes.m:
With -S, print statistics after the third pass over items, since
this is the time-consuming one.
compiler/mercury_compile.m:
Conform to the new names of some predicates.
When declining to output a HLDS dump because it would be identical to
the previous dump, don't confuse the user either by being silent about
the decision, or by leaving an old dump laying around that could be
mistaken for a new one.
tools/binary:
tools/binary_step:
Bring these tools up to date.
compiler/Mmakefile:
Add an int3s target for use by the new code in the tools. The
Mmakefiles in the other directories with Mercury code already have
such a target.
compiler/notes/allocation.html:
Fix an out-of-date reference.
tests/debugger/polymorphic_ground_term.{m,inp,exp}:
New test case to check whether liveness.m handles typeinfo liveness
of ground terms correctly.
tests/debugger/Mmakefile:
Enable the new test case.
tests/debugger/polymorphic_output.{m,exp}:
Fix tab/space mixup.
|