mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-19 03:13:40 +00:00
083d376e6598628362ee91c2da170febd83590f4
45 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9ddb180757 |
Handle const_var_maps left by add_trail_ops.m.
This fixes Mantis bug #544. The code of add_trail_ops.m can transform <code that adds an entry to const_var_map> into ( ... <code that adds an entry to const_var_map> ... ; ..., fail ) where the const_var_map in the MLDS code generator records which variables' values are available as ground terms. The MLDS code generator used to reset the const_var_map in its main data structure, the ml_gen_info, at the end of every disjunction (actually, at the end of every branched control structure) to the value it had at the start. This was intended to prevent the code following the branched structure from relying on const_var_map entries that were added to the const_var_map on *some* branches, but not others. However, in this case, it has the effect of forgetting the entry added by the first disjunct, even though - the code after the disjunction can be reached *only* via the first disjunct, and - the code after the disjunction (legitimately, until add_trail_ops) depended on that entry being available. The fix is to allow the code after a branched control structure to depend on any const_var_map entry that is present in the final const_var_map in every branch of the branched control structure whose end is reachable. The LLDS code generator was not affected by the bug, because it uses totally separate systems both for implementing trailing, and for keeping track of what variables' values are available statically. In particular, it does not rely on operations inserted and the annotations left on unifications by the add_trail_ops and mark_static_term passes, having been written long before either module existed. compiler/hlds_goal.m: Document the update above to what may be marked static. compiler/ml_gen_info.m: Document the updated protocol for handling the const_var_map field. Use a named type instead of its expansion. compiler/ml_code_gen.m: Make the predicates that generate code for a branch in a branched control structure return the final const_var_maps from the branches whose endpoints are reachable. Add a predicate that computes the consensus of all the gathered const_var_maps. Compute consensus const_var_maps for if-then-elses and negations. Fix some inconsistencies in variable naming. Simplify some code. compiler/ml_disj_gen.m: Compute consensus const_var_maps for disjunctions. compiler/ml_string_switch.m: compiler/ml_switch_gen.m: compiler/ml_tag_switch.m: Compute consensus const_var_maps for various kinds of switches. In some predicates, put related arguments next to each other. compiler/ml_unify_gen_construct.m: Delete "dynamic" from the names of several predicates that also handled non-dynamic construction unifications. Fix an out-of-date comment. compiler/mark_static_terms: Fix grammar in a comment. library/map.m: Fix a careless bug: when doing a merge in map.common_subset_loop, we threw away an entry from the wrong list in one of three cases. Make such bugs harder to overlook by - deleting the common parts from variable names, leaving the differences easier to see, and - replacing numeric suffixes for completely separate data structures with A and B suffixes. tests/valid/bug544.m: A new test case for the bug. tests/valid/Mercury.options: tests/valid/Mmakefile: Enable the bug, and run it with -O5. |
||
|
|
715121485c | Don't import unneeded modules in the interface. | ||
|
|
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.
|
||
|
|
948d23e23e |
Move maybe_mark_static_terms to mark_static_terms.m.
compiler/mark_static_terms.m:
compiler/mercury_compile_mlds_back_end.m:
As above.
compiler/mercury_compile_middle_passes.m:
Import mark_static_terms.m, not mercury_compile_mlds_back_end.m.
|
||
|
|
d49f6eab84 |
Add missing imports of parent modules.
These imports were missing from source files, but were included in imported modules' .int3 files. An upcoming change will delete these from those .int3 files. |
||
|
|
15aa457e12 | Delete $module arg from calls to unexpected. | ||
|
|
0682548bce | Convert (C->T;E) to (if C then T else E). | ||
|
|
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. |
||
|
|
55cf491e34 |
Fix bug #229. A term with an argument produced in a from_ground_term_construct
Branches: main, 11.07 Fix bug #229. A term with an argument produced in a from_ground_term_construct scope was not itself being marked to be constructed statically. A side-effect was an exception being thrown while generating a lookup switch in high-level C grades. compiler/mark_static_terms.m: Add the variable constructed in a from_ground_term_construct scope to the set of static variables. tests/valid/Mercury.options: tests/valid/Mmakefile: tests/valid/mark_static_bug.m: Add test case. |
||
|
|
295415090e |
Convert almost all remaining modules in the compiler to use
Estimated hours taken: 6 Branches: main compiler/*.m: Convert almost all remaining modules in the compiler to use "$module, $pred" instead of "this_file" in error messages. In a few cases, the old error message was misleading, since it contained an incorrect, out-of-date or cut-and-pasted predicate name. tests/invalid/unresolved_overloading.err_exp: Update an expected output containing an updated error message. |
||
|
|
022b559584 |
Make error messages for require_complete_switch scopes report the missing
Estimated hours taken: 8 Branches: main Make error messages for require_complete_switch scopes report the missing functors. Knowing which functors are missing requires knowing not only the set of functors in the switched-on variable's type, but also which of these functors have been eliminated by earlier tests, which requires having the instmap at the point of entry to the switch. Simplification, which initially detected unmet require_complete_switch requirements, does not have the instmap, and threading the instmap through it would make it significantly less efficient. So instead we now detect any problems with require_complete_switch scopes (and require_detism scopes, which are similar) during determinism checking. compiler/det_report.m: Factor out the code for finding the missing functors in conventional determinism errors, to allow it to be used for this new purpose. Check whether the requirements of require_complete_switch and require_detism scopes are met IF the predicate has any such scopes. compiler/det_analysis.m: compiler/det_util.m: Record whether the predicate has any such scopes. compiler/hlds_pred.m: Add a predicate marker that allows this recording. compiler/simplify.m: Delete the code that checks the require_complete_switch and require_detism scopes. Keep the code that deletes those scopes. (We have to do that here because determinism error reporting never updates the goal). compiler/prog_out.m: Delete an unused predicate. compiler/*.m: Remove unnecesary imports as flagged by --warn-unused-imports. |
||
|
|
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. |
||
|
|
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. |
||
|
|
5af57da91d |
Further compiler speedups.
Estimated hours taken: 4 Branches: main Further compiler speedups. library/varset.m: Speed up predicates by avoding making the same decisions over and over again. library/tree234.m: library/map.m: NEWS: Add tree234.map_values_only and map.map_values_only. compiler/add_pragma.m: compiler/analysis.m: compiler/code_info.m: compiler/cse_detection.m: compiler/cse_detection.m: compiler/equiv_type_hlds.m: compiler/global_data.m: compiler/hlds_out.m: compiler/hlds_rtti.m: compiler/inst_graph.m: compiler/lp_rational.m: compiler/hlds_out.m: compiler/mlds_to_il.m: compiler/modules.m: compiler/par_conj_gen.m: compiler/polymorphism.m: compiler/prog_data.m: compiler/prog_type_subst.m: compiler/recompilation.version.m: compiler/simplify.m: compiler/stack_layout.m: compiler/type_util.m: compiler/unneeded_code.m: Use the new predicates. compiler/mark_static_terms.m: Do not bother traversing from_ground_term_construct scopes. Remove a redundant test. compiler/ml_unify_gen.m: Speed up a predicate by avoding making the same decisions over and over again. compiler/mlds.m: Factor out some code. compiler/typecheck_info.m: Operate on vartypes directly as maps; don't transform them unnecessarily into association lists. Do not bother to apply empty substitutions. |
||
|
|
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.
|
||
|
|
cc88711d63 |
Implement true multi-cons_id arm switches, i.e. switches in which we associate
Estimated hours taken: 40
Branches: main
Implement true multi-cons_id arm switches, i.e. switches in which we associate
more than one cons_id with a switch arm. Previously, for switches like this:
(
X = a,
goal1
;
( X = b
; X = c
),
goal2
)
we duplicated goal2. With this diff, goal2 won't be duplicated. We still
duplicate goals when that is necessary, i.e. in cases which the inner
disjunction contains code other than a functor test on the switched-on var,
like this:
(
X = a,
goal1
;
(
X = b,
goalb
;
X = c
goalc
),
goal2
)
For now, true multi-cons_id arm switches are supported only by the LLDS
backend. Supporting them on the MLDS backend is trickier, because some MLDS
target languages (e.g. Java) don't support the concept at all. So when
compiling to MLDS, we still duplicate the goal in switch detection (although
we could delay the duplication to just before code generation, if we wanted.)
compiler/options.m:
Add an internal option that tells switch detection whether to look for
multi-cons_id switch arms.
compiler/handle_options.m:
Set this option based on the back end.
Add a version of the "trans" dump level that doesn't print unification
details.
compiler/hlds_goal.m:
Extend the representation of switch cases to allow more than one
cons_id for a switch arm.
Add a type for representing switches that also includes tag information
(for use by the backends).
compiler/hlds_data.m:
For du types, record whether it is possible to speed up tests for one
cons_id (e.g. cons) by testing for the other (nil) and negating the
result. Recording this information once is faster than having
unify_gen.m trying to compute it from scratch for every single
tag test.
Add a type for representing a cons_id together with its tag.
compiler/hlds_out.m:
Print out the cheaper_tag_test information for types, and possibly
several cons_ids for each switch arm.
Add some utility predicates for describing switch arms in terms of
which cons_ids they are for.
Replace some booleans with purpose-specific types.
Make hlds_out honor is documentation, and not print out detailed
information about unifications (e.g. uniqueness and static allocation)
unless the right character ('u') is present in the control string.
compiler/add_type.m:
Fill in the information about cheaper tag tests when adding a du type.
compiler/switch_detection.m:
Extend the switch detection algorithm to detect multi-cons_id switch
arms.
When entering a switch arm, update the instmap to reflect that the
switched-on variable can now be bound only to the cons_ids that this
switch arm is for. We now need to do this, because if the arm contains
another switch on the same variable, computing the can_fail field of
that switch correctly requires us to know this information.
(Obviously, an arm for a single cons_id is unlikely to have switch on
the same variable, and for arms for several cons_ids, we previously
duplicated the arm and left the unification with the cons_id in each
copy, and this unification allowed the correct handling of any later
switches. However, the code of a multi-cons_id switch arm obviously
cannot have a unification with each cons_id in it, which is why
we now need to get the binding information from the switch itself.)
Replace some booleans with purpose-specific types, and give some
predicates better names.
compiler/instmap.m:
Provide predicates for recording that a switched-on variable has
one of several given cons_ids, for use at the starts of switch arms.
Give some predicates better names.
compiler/modes.m:
Provide predicates for updating the mode_info at the start of a
multi-cons_id switch arm.
compiler/det_report.m:
Handle multi-cons_id switch arms.
Update the instmap when entering each switch arm, since this is needed
to provide good (i.e. non-misleading) error messages when one switch on
a variable exists inside another switch on the same variable.
Since updating the instmap requires updating the module_info (since
the new inst may require a new entry in an inst table), thread the
det_info through as updateable state.
Replace some multi-clause predicate definitions with single clauses,
to make it easier to print the arguments in mdb.
Fix some misleading variable names.
compiler/det_analysis.m:
Update the instmap when entering each switch arm and thread the
det_info through as updateable state, since the predicates we call
in det_report.m require this.
compiler/det_util.m:
Handle multi-cons_id switch arms.
Rationalize the argument order of some access predicates.
compiler/switch_util.m:
Change the parts of this module that deal with string and tag switches
to optionally convert each arm to an arbitrary representation of the
arm. In the LLDS backend, the conversion process generated code for
the arm, and the arm's representation is the label at the start of
this code. This way, we can duplicate the label without duplicating
the code.
Add a new part of this module that associates each cons_id with its
tag, and (during the same pass) checks whether all the cons_ids are
integers, and if so what are min and max of these integers (needed
for dense switches). This scan is needed because the old way of making
this test had single-cons_id switch arms as one of its basic
assumptions, and doing it while adding tags to each case reduces
the number of traversals required.
Give better names to some predicates.
compiler/switch_case.m:
New module to handle the tasks associated with managing multi-cons_id
switch arms, including representing them for switch_util.m.
compiler/ll_backend.m:
Include the new module.
compiler/notes/compiler_design.html:
Note the new module.
compiler/llds.m:
Change the computed goto instruction to take a list of maybe labels
instead of a list of labels, with any missing labels meaning "not
reached".
compiler/string_switch.m:
compiler/tag_switch.m:
Reorganize the way these modules work. We can't generate the code of
each arm in place anymore, since it is now possible for more than one
cons_id to call for the execution of the same code. Instead, in
string_switch.m, we generate the codes of all the arms all at once,
and construct the hash index afterwards. (This approach simplifies
the code significantly.)
In tag switches (unlike string switches), we can get locality benefits
if the code testing for a cons_id is close to the code for that
cons_id, so we still try to put them next to each other when such
a locality benefit is available.
In both modules, the new approach uses a utility predicate in
switch_case.m to actually generate the code of each switch arm,
eliminating several copies the same code in the old versions of these
modules.
In tag_switch.m, don't create a local label that simply jumps to the
code address do_not_reached. Previously, we had to do this for
positions in jump tables that corresponded to cons_ids that the switch
variable could not be bound to. With the change to llds.m, we now
simply generate a "no" instead.
compiler/lookup_switch.m:
Get the info about int switch limits from our caller; don't compute it
here.
Give some variables better names.
compiler/dense_switch.m:
Generate the codes of the cases all at once, then assemble the table,
duplicate the labels as needed. This separation of concerns allows
significant simplifications.
Pack up all the information shared between the predicate that detects
whether a dense switch is appropriate and the predicate that actually
generates the dense switch.
Move some utility predicates to switch_util.
compiler/switch_gen.m:
Delete the code for tagging cons_ids, since that functionality is now
in switch_util.m.
The old version of this module could call the code generator to produce
(i.e. materialize) the switched-on variable repeatedly. We now produce
the variable once, and do the switch on the resulting rval.
compiler/unify_gen.m:
Use the information about cheaper tag tests in the type constructor's
entry in the HLDS type table, instead of trying to recompute it
every time.
Provide the predicates switch_gen.m now needs to perform tag tests
on rvals, as opposed to variables, and against possible more than one
cons_id.
Allow the caller to provide the tag corresponding to the cons_id(s)
in tag tests, since when we are generating code for switches, the
required computations have already been done.
Factor out some code to make all this possible.
Give better names to some predicates.
compiler/code_info.m:
Provide some utility predicates for the new code in other modules.
Give better names to some existing predicates.
compiler/hlds_code_util.m:
Rationalize the argument order of some predicates.
Replace some multi-clause predicate definitions with single clauses,
to make it easier to print the arguments in mdb.
compiler/accumulator.m:
compiler/add_heap_ops.m:
compiler/add_pragma.m:
compiler/add_trail_ops.m:
compiler/assertion.m:
compiler/build_mode_constraints.m:
compiler/check_typeclass.m:
compiler/closure_analysis.m:
compiler/code_util.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/dupproc.m:
compiler/equiv_type_hlds.m:
compiler/erl_code_gen.m:
compiler/exception_analysis.m:
compiler/export.m:
compiler/follow_code.m:
compiler/follow_vars.m:
compiler/foreign.m:
compiler/format_call.m:
compiler/frameopt.m:
compiler/goal_form.m:
compiler/goal_path.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/implicit_parallelism.m:
compiler/inlining.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/interval.m:
compiler/lambda.m:
compiler/lambda.m:
compiler/lambda.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/livemap.m:
compiler/liveness.m:
compiler/llds_out.m:
compiler/llds_to_x86_64.m:
compiler/loop_inv.m:
compiler/make_hlds_warn.m:
compiler/mark_static_terms.m:
compiler/middle_rec.m:
compiler/ml_tag_switch.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/mode_util.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/pd_cost.m:
compiler/pd_into.m:
compiler/pd_util.m:
compiler/peephole.m:
compiler/polymorphism.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/purity.m:
compiler/quantification.m:
compiler/rbmm.actual_region_arguments.m:
compiler/rbmm.add_rbmm_goal_infos.m:
compiler/rbmm.condition_renaming.m:
compiler/rbmm.execution_paths.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.region_transformation.m:
compiler/recompilation.usage.m:
compiler/saved_vars.m:
compiler/simplify.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/store_alloc.m:
compiler/stratify.m:
compiler/structure_reuse.direct.choose_reuse.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/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_norm.m:
compiler/term_pass1.m:
compiler/term_traversal.m:
compiler/trailing_analysis.m:
compiler/transform_llds.m:
compiler/tupling.m:
compiler/type_ctor_info.m:
compiler/type_util.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/xml_documentation.m:
Make the changes necessary to conform to the changes above, principally
to handle multi-cons_id arm switches.
compiler/ml_string_switch.m:
Make the changes necessary to conform to the changes above, principally
to handle multi-cons_id arm switches.
Give some predicates better names.
compiler/dependency_graph.m:
Make the changes necessary to conform to the changes above, principally
to handle multi-cons_id arm switches. Change the order of arguments
of some predicates to make this easier.
compiler/bytecode.m:
compiler/bytecode_data.m:
compiler/bytecode_gen.m:
Make the changes necessary to conform to the changes above, principally
to handle multi-cons_id arm switches. (The bytecode interpreter
has not been updated.)
compiler/prog_rep.m:
mdbcomp/program_representation.m:
Change the byte sequence representation of goals to allow switch arms
with more than one cons_id. compiler/prog_rep.m now writes out the
updated representation, while mdbcomp/program_representation.m reads in
the updated representation.
deep_profiler/mdbprof_procrep.m:
Conform to the updated program representation.
tools/binary:
Fix a bug: if the -D option was given, the stage 2 directory wasn't
being initialized.
Abort if users try to give that option more than once.
compiler/Mercury.options:
Work around bug #32 in Mantis.
|
||
|
|
ba93a52fe7 |
This diff changes a few types from being defined as equivalent to a pair
Estimated hours taken: 10 Branches: main This diff changes a few types from being defined as equivalent to a pair to being discriminated union types with their own function symbol. This was motivated by an error message (one of many, but the one that broke the camel's back) about "-" being used in an ambiguous manner. It will reduce the number of such messages in the future, and will make compiler data structures easier to inspect in the debugger. The most important type changed by far is hlds_goal, whose function symbol is now "hlds_goal". Second and third in importance are llds.instruction (function symbol "llds_instr") and prog_item.m's item_and_context (function symbol "item_and_context"). There are some others as well. In several places, I rearranged predicates to factor the deconstruction of goals into hlds_goal_expr and hlds_goal_into out of each clause into a single point. In many places, I changed variable names that used "Goal" to refer to just hlds_goal_exprs to use "GoalExpr" instead. I also changed variable names that used "Item" to refer to item_and_contexts to use "ItemAndContext" instead. This should make reading such code less confusing. I renamed some function symbols and predicates to avoid ambiguities. I only made one algorithmic change (at least intentionally). In assertion.m, comparing two goals for equality now ignores goal_infos for all kinds of goals, whereas previously it ignored them for most kinds of goals, but for shorthand goals it was insisting on them being equal. This seemed to me to be a bug. Pete, can you confirm this? |
||
|
|
b4c3bb1387 |
Clean up in unused module imports in the Mercury system detected
Estimated hours taken: 3 Branches: main Clean up in unused module imports in the Mercury system detected by --warn-unused-imports. analysis/*.m: browser/*.m: deep_profiler/*.m: compiler/*.m: library/*.m: mdbcomp/*.m: profiler/*.m: slice/*.m: Remove unused module imports. Fix some minor departures from our coding standards. analysis/Mercury.options: browser/Mercury.options: deep_profiler/Mercury.options: compiler/Mercury.options: library/Mercury.options: mdbcomp/Mercury.options: profiler/Mercury.options: slice/Mercury.options: Set --no-warn-unused-imports for those modules that are used as packages or otherwise break --warn-unused-imports, e.g. because they contain predicates with both foreign and Mercury clauses and some of the imports only depend on the latter. |
||
|
|
aeeedd2c13 |
Standardize formatting of comments at the beginning of modules.
compiler/*.m: Standardize formatting of comments at the beginning of modules. |
||
|
|
9d23d8e2e7 |
Implement the trace goal construct we discussed, for now for the LLDS backends
Estimated hours taken: 70
Branches: main
Implement the trace goal construct we discussed, for now for the LLDS backends
only.
Since the syntax of trace goals is non-trivial, useful feedback on syntax
errors inside trace goal attributes is essential. With the previous setup, this
wasn't possible, since the code that turned terms into parse tree goals turned
*all* terms into goals; it couldn't recognize any errors, sweeping them under
the rug as calls. This diff changes that. Now, if this code recognizes a
keyword that indicates a particular construct, it insists on the rest of the
code following the syntax required for that construct, and returns error
messages if it doesn't.
We handle the trace goal attributes that specify state variables to be threaded
through the trace goal (either the I/O state or a mutable variable) in
add_clause.m, at the point at which we transform the list of items to the HLDS.
We handle the compile-time condition on trace goals in the invocation of
simplify at the end of semantics analysis, by eliminating the goal if the
compile-time condition isn't met. We handle run-time conditions on trace goals
partially in the same invocation of simplify: we transform trace goals with
runtime conditions into an if-then-else with the trace goal as the then part
and `true' as the else part, the condition being a foreign_proc that is handled
specially by the code generator, that special handling being to replace
the actual code of the foreign_proc (which is a dummy) with the evaluation of
the runtime condition.
Since these changes require significant changes to some of our key data
structures, I took the liberty of doing some renaming of function symbols
at the same time to avoid using ambiguities with respect to language keywords.
library/ops.m:
Add "trace" as an operator.
compiler/prog_data.m:
Define data types to represent the various attributes of trace goals.
Rename some function symbols to avoid ambiguities.
compiler/prog_item.m:
Extend the parse tree representation of goals with a trace goal.
compiler/mercury_to_mercury.m:
Output the new kind of goal and its components.
compiler/hlds_goal.m:
Extend the HLDS representation of scopes with a scope_reason
representing trace goals.
Add a mechanism (an extra argument in foreign_procs) to allow
the representation of goals that evaluate runtime trace conditions.
Since this requires modifying all code that traverses the HLDS,
do some renames that were long overdue: rename not as negation,
rename call as plain_call, and rename foreign_proc as
call_foreign_proc. These renames all avoid using language keywords
as function symbols.
Change the way we record goals' purities. Instead of optional features
to indicate impure or semipure, which is error-prone, use a plain
field in the goal_info, accessed in the usual way.
Add a way to represent that a goal contains a trace goal, and should
therefore be treated as if it were impure when considering whether to
optimize it away.
Reformat some comments describing function symbols.
compiler/hlds_out.m:
Output the new construct in the HLDS.
compiler/prog_io_util.m:
Generalize the maybe[123] types to allow the representation of more
than one error message. Add functions to extract the error messages.
Add a maybe4 type. Rename the function symbols of these types to
avoid massive ambiguity.
Change the order of some predicates to bring related predicates
next to each other.
compiler/prog_io.m:
compiler/prog_io_dcg.m:
compiler/prog_io_goal.m:
compiler/prog_io_pragma.m:
Rework these modules almost completely to find and accumulate syntax
errors as terms are being parsed. In some cases, this allowed us to
replace "XXX this is a hack" markers with meaningful error-reporting
code.
In prog_io_goal.m, add code for parsing trace goals.
In a bunch of places, update obsolete coding practices, such as using
nested chains of closures instead of simple sequential code, and
using A0 and A to refer to values of different types (terms and goals
respectively). Use more meaningful variable names.
Break up some too-large predicates.
compiler/superhomogeneous.m:
Find and accumulate syntax errors as terms are being parsed.
compiler/add_clause.m:
Add code to transform trace goals from the parse tree to the HLDS.
This is where the IO state and mutable variable attributes of trace
goals are handled.
Eliminate the practice of using the naming scheme Body0 and Body
to refer to values of different types (prog_item.goal and hlds_goal
respectively).
Use error_util for some error messages.
library/private_builtin.m:
Add the predicates referred to by the transformation in add_clause.m.
compiler/goal_util.m:
Rename a predicate to avoid ambiguity.
compiler/typecheck.m:
Do not print error messages about missing clauses if some errors have
been detected previously.
compiler/purity.m:
Instead of just computing purity, compute (and record) also whether
a goal contains a trace goal. However, treat trace goals as pure.
compiler/mode_info.m:
Add trace goals as a reason for locking variables.
Rename some function symbols to avoid ambiguity.
compiler/modes.m:
When analyzing trace goal scopes, lock the scope's nonlocal variables
to prevent them from being further instantiated.
compiler/det_analysis.m:
Insist on the code in trace goal scopes being det or cc_multi.
compiler/det_report.m:
Generate the error message if the code in a trace goal scope isn't det
or cc_multi.
compiler/simplify.m:
At the end of the front end, eliminate trace goal scopes if their
compile-time condition is false. Transform trace goals with runtime
conditions as described at the top.
Treat goals that contain trace goals as if they were impure when
considering whether to optimize them away.
compiler/mercury_compile.m:
Tell simplify when it is being invoked at the end of the front end.
Rename a predicate to avoid ambiguity.
compiler/trace_params.m:
Provide the predicates simplify.m need to be able to evaluate the trace
goal conditions regarding trace levels.
compiler/trace.m:
compiler/trace_gen.m:
Rename the trace module as trace_gen, since "trace" is now an operator.
Rename some predicates exported by the module, now that it is no longer
possible to preface calls with "trace." as a module qualifier.
compiler/notes/compiler_design.html:
Document this name change.
compiler/options.m:
Rename the trace option as trace_level internally, since "trace"
is now an operator. The user-visible name remains the same.
Add the new --trace-flag option.
Delete an obsolete option.
compiler/handle_options.m:
Rename the function symbols of the grade_component type,
since "trace" is now an operator.
compiler/llds.m:
Extend the LLDS with a mechanism to refer to C global variables.
For now, these are used to refer to C globals that will be created
by mkinit to represent the initial values of the environment variables
referred to by trace goals.
compiler/commit_gen.m:
Check that no trace goal with a runtime condition survives to code
generation; they should have been transformed by simplify.m.
compiler/code_gen.m:
Tell commit_gen.m what kind of scope it is generating code for.
compiler/pragma_c_gen.m:
Generate code for runtime conditions when handling the foreign_procs
created by simplify.m.
compiler/code_info.m:
Allow pragma_c_gen.m to record what environment variables it has
generated references to.
compiler/proc_gen.m:
Record the set of environment variables a procedure refers to
in the LLDS procedure header, for efficient access by llds_out.m.
compiler/llds_out.m:
Handle the new LLDS construct, and tell mkinit which environment
variables need C globals created for them.
compiler/pd_util.m:
Rename some predicates to avoid ambiguity.
compiler/*.m:
Conform to the changes above, mainly the renames of function symbols
and predicates, the changed signatures of some predicates, and the new
handling of purity.
util/mkinit.c:
Generate the definitions and the initializations of any C globals
representing the initial status (set or not set) of environment
variables needed by trace goals.
library/assoc_list.m:
Add some predicates that are useful in prog_io*.m.
library/term_io.m:
Minor cleanup.
tests/hard_coded/trace_goal_{1,2}.{m,exp}:
New test cases to test the new construct, identical except for whether
the trace goal is enabled at compile time.
tests/hard_coded/trace_goal_env_{1,2}.{m,exp}:
New test cases to test the new construct, identical except for whether
the trace goal is enabled at run time.
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
Enable the new test cases.
tests/invalid/*.err_exp:
Update the expected output for the new versions of the error messages
now being generated.
|
||
|
|
459847a064 |
Move the univ, maybe, pair and unit types from std_util into their own
Estimated hours taken: 18 Branches: main Move the univ, maybe, pair and unit types from std_util into their own modules. std_util still contains the general purpose higher-order programming constructs. library/std_util.m: Move univ, maybe, pair and unit (plus any other related types and procedures) into their own modules. library/maybe.m: New module. This contains the maybe and maybe_error types and the associated procedures. library/pair.m: New module. This contains the pair type and associated procedures. library/unit.m: New module. This contains the types unit/0 and unit/1. library/univ.m: New module. This contains the univ type and associated procedures. library/library.m: Add the new modules. library/private_builtin.m: Update the declaration of the type_ctor_info struct for univ. runtime/mercury.h: Update the declaration for the type_ctor_info struct for univ. runtime/mercury_mcpp.h: runtime/mercury_hlc_types.h: Update the definition of MR_Univ. runtime/mercury_init.h: Fix a comment: ML_type_name is now exported from type_desc.m. compiler/mlds_to_il.m: Update the the name of the module that defines univs (which are handled specially by the il code generator.) library/*.m: compiler/*.m: browser/*.m: mdbcomp/*.m: profiler/*.m: deep_profiler/*.m: Conform to the above changes. Import the new modules where they are needed; don't import std_util where it isn't needed. Fix formatting in lots of modules. Delete duplicate module imports. tests/*: Update the test suite to confrom to the above changes. |
||
|
|
12deb40264 |
Rename all the get access predicates in these modules that don't
Estimated hours taken: 0.1 Branches: main compiler/hlds_clauses.m: compiler/hlds_pred.m: Rename all the get access predicates in these modules that don't already have put "get" in their name. (The names of the set access predicates were OK already.) compiler/*.m: Conform to the above. All this was done by this sed script: s/clauses_info_varset/clauses_info_get_varset/ s/clauses_info_explicit_vartypes/clauses_info_get_explicit_vartypes/ s/clauses_info_vartypes/clauses_info_get_vartypes/ s/clauses_info_headvars/clauses_info_get_headvars/ s/clauses_info_clauses_rep/clauses_info_get_clauses_rep/ s/clauses_info_rtti_varmaps/clauses_info_get_rtti_varmaps/ s/pred_info_import_status/pred_info_get_import_status/ s/pred_info_arg_types/pred_info_get_arg_types/ s/pred_info_typevarset/pred_info_get_typevarset/ s/pred_info_tvar_kinds/pred_info_get_tvar_kinds/ s/pred_info_procedures/pred_info_get_procedures/ s/proc_info_context/proc_info_get_context/ s/proc_info_varset/proc_info_get_varset/ s/proc_info_vartypes/proc_info_get_vartypes/ s/proc_info_headvars/proc_info_get_headvars/ s/proc_info_inst_varset/proc_info_get_inst_varset/ s/proc_info_maybe_declared_argmodes/proc_info_get_maybe_declared_argmodes/ s/proc_info_argmodes/proc_info_get_argmodes/ s/proc_info_maybe_arglives/proc_info_get_maybe_arglives/ s/proc_info_declared_determinism/proc_info_get_declared_determinism/ s/proc_info_inferred_determinism/proc_info_get_inferred_determinism/ s/proc_info_goal/proc_info_get_goal/ s/proc_info_can_process/proc_info_get_can_process/ s/proc_info_rtti_varmaps/proc_info_get_rtti_varmaps/ s/proc_info_eval_method/proc_info_get_eval_method/ s/proc_info_is_address_taken/proc_info_get_is_address_taken/ s/proc_info_stack_slots/proc_info_get_stack_slots/ s/proc_info_liveness_info/proc_info_get_liveness_info/ s/proc_info_context/proc_info_get_context/ s/proc_info_context/proc_info_get_context/ s/proc_info_context/proc_info_get_context/ s/proc_info_context/proc_info_get_context/ s/proc_info_context/proc_info_get_context/ s/proc_info_context/proc_info_get_context/ s/proc_info_context/proc_info_get_context/ |
||
|
|
be5b71861b |
Convert almost all the compiler modules to use . instead of __ as
Estimated hours taken: 6 Branches: main compiler/*.m: Convert almost all the compiler modules to use . instead of __ as the module qualifier. In some cases, change the names of predicates and types to make them meaningful without the module qualifier. In particular, most of the types that used to be referred to with an "mlds__" prefix have been changed to have a "mlds_" prefix instead of changing the prefix to "mlds.". There are no algorithmic changes. |
||
|
|
5b8f96f61d |
Prepare for an extension of promise_equivalent_solutions that will allow us
Estimated hours taken: 5 Branches: main Prepare for an extension of promise_equivalent_solutions that will allow us to better handle values of user-defined types. The problem is that currently, the deconstruction of a value of such a type can be followed only by code that cannot fail, otherwise the cc_multi deconstruction is not in the required single-solution context. If the following code is naturally semidet, this can be worked around by turning it into det code returning a maybe and testing the maybe outside the promise_equivalent_solutions, but this is inefficient, and in any case it does not generalize to nondet code without even more horrendous inefficiency and inconvenience. (You have to create a nondet closure and call it outside the promise_equivalent_solutions.) The solution I came up with is something is to have a construct that contains - a list of deconstructions on types with user-defined equality, - a goal, and - the list of outputs of that goal. The idea is that this would be transformed into a conjunction of the first and second items, and wrapped inside a special kind of conj that provides a scope for the implicit promise, which is that the set of solutions of the goal in the second item doesn't depend on what concrete terms the deconstructions in the first item return out of the set of concrete terms they *could* return. The deconstructions in the first item would be marked to tell determinism analysis to effectively ignore the fact that they involve user-defined equality. The actual addition of that construct is left for a future change, after we agree on the syntax. compiler/hlds_goal.m: Generalize the existing promise_equivalent_solutions scope to a promise_solutions scope with a flag that says whether in the source code it was originally the existing "promise_equivalent_solutions" construct or the new construct (which doesn't exist yet, but is indicated by the symbol "same_solutions" for now). Replace the conj and par_conj hlds_goal_exprs with a single goal expression: conj with an additional argument which is either plain_conj or parallel_conj. This was part of an earlier design in which a third kind of disjunction took the role now assigned to the new kind of promise_solutions scope, but turned out to be a good idea anyway, since in many places the compiler does treat the two kinds of conjunctions the same. This part of the change is responsible for the fact that this change results in a net *reduction* of about 40 lines. Move the most frequently used kinds of goal expressions to the front of the type declaration to allow the compiler to make better decisions about tag allocation. Add the goal marker we will add to the deconstructions in the first item. Replace the true_goal and fail_goal predicates with functions to make them easier to use, and rename their variants that take a context argument to avoid unnecessary ambiguity. compiler/*.m: Conform to the change in hlds_goal.m. Misc changes to make code more robust, e.g. replacing semidet predicates on goal expressions with functions returning bool. Misc cleanups, e.g. removal of unnecessary module qualifications that made lines too long, renaming predicates whose names include "disj" if they are also used to process parallel conjunctions (since in both parallel conjunctions and in disjunctions the goals are independent), and turning semidet predicates that switch on goal expressions into bool functions (to make similar changes more rebust in the future). |
||
|
|
45fdb6c451 |
Use expect/3 in place of require/2 throughout most of the
Estimated hours taken: 4 Branches: main compiler/*.m: Use expect/3 in place of require/2 throughout most of the compiler. Use unexpected/2 (or sorry/2) in place of error/1 in more places. Fix more dodgy assertion error messages. s/map(prog_var, mer_type)/vartypes/ where the latter is meant. |
||
|
|
5f589e98fb |
Various cleanups for the modules in the compiler directory.
Estimated hours taken: 4 Branches: main Various cleanups for the modules in the compiler directory. The are no changes to algorithms except the replacement of some if-then-elses that would naturally be switches with switches and the replacement of most of the calls to error/1. compiler/*.m: Convert calls to error/1 to calls to unexpected/2 or sorry/2 as appropriate throughout most or the compiler. Fix inaccurate assertion failure messages, e.g. identifying the assertion failure as taking place in the wrong module. Add :- end_module declarations. Fix formatting problems and bring the positioning of comments into line with our current coding standards. Fix some overlong lines. Convert some more modules to 4-space indentation. Fix some spots where previous conversions to 4-space indentation have stuffed the formatting of the code up. Fix a bunch of typos in comments. Use state variables in more places; use library predicates from the sv* modules where appropriate. Delete unnecessary and duplicate module imports. Misc. other small cleanups. |
||
|
|
f9fe8dcf61 |
Improve the error messages generated for determinism errors involving committed
Estimated hours taken: 8
Branches: main
Improve the error messages generated for determinism errors involving committed
choice contexts. Previously, we printed a message to the effect that e.g.
a cc pred is called in context that requires all solutions, but we didn't say
*why* the context requires all solutions. We now keep track of all the goals
to the right that could fail, since it is these goals that may reject the first
solution of a committed choice goal.
The motivation for this diff was the fact that I found that locating the
failing goal can be very difficult if the conjunction to the right is
a couple of hundred lines long. This would have been a nontrivial problem,
since (a) unifications involving values of user-defined types are committed
choice goals, and (b) we can expect uses of user-defined types to increase.
compiler/det_analysis.m:
Keep track of goals to the right of the current goal that could fail,
and include them in the error representation if required.
compiler/det_report.m:
Include the list of failing goals to the right in the representations
of determinism errors involving committed committed choice goals.
Convert the last part of this module that wasn't using error_util
to use error_util. Make most parts of this module just construct
error message specifications; print those specifications (using
error_util) in only a few places.
compiler/hlds_out.m:
Add a function for use by the new code in det_report.m.
compiler/error_util.m:
Add a function for use by the new code in det_report.m.
compiler/error_util.m:
compiler/compiler_util.m:
Error_util is still changing reasonably often, and yet it is
included in lots of modules, most of which need only a few simple
non-parse-tree-related predicates from it (e.g. unexpected).
Move those predicates to a new module, compiler_util.m. This also
eliminates some undesirable dependencies from libs to parse_tree.
compiler/libs.m:
Include compiler_util.m.
compiler/notes/compiler_design.html:
Document compiler_util.m, and fix the documentation of some other
modules.
compiler/*.m:
Import compiler_util instead of or in addition to error_util.
To make this easier, consistently use . instead of __ for module
qualifying module names.
tests/invalid/det_errors_cc.{m,err_exp}:
Add this new test case to test the error messages for cc contexts.
tests/invalid/det_errors_deet.{m,err_exp}:
Add this new test case to test the error messages for unifications
inside function symbols.
tests/invalid/Mmakefile:
Add the new test cases.
tests/invalid/det_errors.err_exp:
tests/invalid/magicbox.err_exp:
Change the expected output to conform to the change in det_report.m,
which is now more consistent.
|
||
|
|
bed20104c7 |
Write out more information about construction unifications.
Estimated hours taken: 1 Branches: main compiler/hlds_out.m: Write out more information about construction unifications. compiler/mark_static_terms.m: compiler/mlds.m: Convert to four space indentation. Fix departures from our coding standards. compiler/mode_constraints.m: Minor cleanups. |
||
|
|
8b8b3b7d3f |
Replace the some() HLDS goal with a more general scope() goal, which can be
Estimated hours taken: 12
Branches: main
Replace the some() HLDS goal with a more general scope() goal, which can be
used not just for existential quantification but also for other purposes.
The main such purposes are new goal types that allow the programmer
to annotate arbitrary goals, and not just whole procedure bodies, with the
equivalents of promise_pure/promise_semipure and promise_only_solution:
promise_pure ( <impure/semipure goal> )
promise_semipure ( <impure goal> )
promise_equivalent_solutions [OutVar1, OutVar2] (
<cc_multi/cc_nondet goal that computed OutVar1 & OutVar2>
)
Both are intended to be helpful in writing constraint solvers, as well as in
other situations.
doc/reference_manual.texi:
Document the new constructs.
library/ops.m:
Add the keywords of the new constructs to the list of operators.
Since they work similarly to the "some" operator, they have the same
precedence.
compiler/hlds_goal.m:
Replace the some(Vars, SubGoal) HLDS construct, with its optional
keep_this_commit attribute, with the new scope(Reason, SubGoal)
construct. The Reason argument may say that this scope is an
existential quantification, but it can also say that it represents
a purity promise, the introduction of a single-solution context
with promise_equivalent_solutions, or a decision by a compiler pass.
It can also say that the scope represents a set of goals that all arise
from the unraveling of a unification between a variable and a ground
term. This was intended to speed up mode checking by significantly
reducing the number of delays and wakeups, but the cost of the scopes
themselves turned out to be bigger than the gain in modechecking speed.
Update the goal_path_step type to refer to scope goals instead of just
existential quantification.
compiler/prog_data.m:
Add new function symbols to the type we use to represent goals in items
to stand for the new Mercury constructs.
compiler/prog_io_goal.m:
Add code to read in the new language constructs.
compiler/prog_io_util.m:
Add a utility predicate for use by the new code in prog_io_goal.m.
compiler/make_hlds.m:
Convert the item representation of the new constructs to the HLDS
representation.
Document how the from_ground_term scope reason would work, but do not
enable the code.
compiler/purity.m:
When checking the purity of goals, respect the new promise_pure and
promise_semipure scopes. Generate warnings if such scopes are
redundant.
compiler/det_analysis.m:
Make the insides of promise_equivalent_solutions goals single solution
contexts.
compiler/det_report.m:
Provide mechanisms for reporting inappropriate usage of
promise_equivalent_solutions goals.
compiler/instmap.m:
Add a utility predicate for use by one of the modules above.
compiler/deep_profiling.m:
Use one of the new scope reasons to prevent simplify from optimizing
away commits of goals that have been made impure, instead of the old
keep_this_commit goal feature.
compiler/modes.m:
Handle from_ground_term scopes when present; for now, they won't be
present, since make_hlds isn't creating them.
compiler/options.m:
Add two new compiler options, for use by implementors only, to allow
finer control over the amount of output one gets with --debug-modes.
(I used them when debugging the performance of the from_ground_term
scope reason.) The options are --debug-modes-minimal and
--debug-modes-verbose.
compiler/handle_options.m:
Make the options that are meaningful only in the presence of
--debug-modes imply --debug-modes, since this allows more convenient
(shorter) invocations.
compiler/mode_debug.m:
Respect the new options when deciding how much data to print
when debugging of the mode checking process is enabled.
compiler/switch_detect.m:
Rename a predicate to make it differ from another predicate by more
than just its arity.
compiler/passes_aux.m:
Bring this module up to date with our current style guidelines,
by using state variable syntax where appropriate.
compiler/*.m:
Minor changes to conform to the change in the HLDS and/or parse tree
goal type.
mdbcomp/program_representation.m:
Rename the some goal to the scope goal, and the same for path steps,
to keep them in sync with the HLDS.
browser/declarative_tree.m:
Conform to the change in goal representations.
tests/hard_coded/promise_equivalent_solutions_test.{m,exp}:
A new test case to test the handling of the
promise_equivalent_solutions construct.
tests/hard_coded/Mmakefile:
Enable the new test.
tests/hard_coded/purity/promise_pure_test.{m,exp}:
A new test case to test the handling of the promise_pure and
promise_semipure constructs.
tests/hard_coded/purity/Mmakefile:
Enable the new test.
tests/invalid/promise_equivalent_solutions.{m,err_exp}:
A new test case to test the error messages for improper use of the
promise_pure and promise_semipure constructs.
tests/invalid/Mmakefile:
Enable the new test.
|
||
|
|
c08ca7fbc8 |
Import only one module per line in the modules of the compiler
Estimated hours taken: 3 Branches: main compiler/*.m: Import only one module per line in the modules of the compiler where my previous diff did not already do so. Misc other cleanups. Where relevant, use the new mechanism in tree.m. compiler/tree.m: Fix a performance problem I noticed while update :- import_module items. Instead of supplying a function to convert lists of trees to a tree, make the tree data structure able to hold a list of subtrees directly. This reduces the number of times where we have to convert list of trees to trees that are sticks just to stay within the old definition of what a tree is. |
||
|
|
3c60c0e485 |
Change a bunch of modules to import only one module per line, even
Estimated hours taken: 4 Branches: main compiler/*.m: Change a bunch of modules to import only one module per line, even from the library. compiler/mlds_to_il.m: compiler/mlds_to_managed.m: Convert these modules to our current coding style. Use state variables where appropriate. Use predmode declarations where possible. |
||
|
|
885fd4a387 |
Remove almost all dependencies by the modules of parse_tree.m on the modules
Estimated hours taken: 12 Branches: main Remove almost all dependencies by the modules of parse_tree.m on the modules of hlds.m. The only such dependencies remaining now are on type_util.m. compiler/hlds_data.m: compiler/prog_data.m: Move the cons_id type from hlds_data to prog_data, since several parts of the parse tree data structure depend on it (particularly insts). Remove the need to import HLDS modules in prog_data.m by making the cons_ids that refer to procedure ids refer to them via a new type that contains shrouded pred_ids and proc_ids. Since pred_ids and proc_ids are abstract types in hlds_data, add predicates to hlds_data to shroud and unshroud them. Also move some other types, e.g. mode_id and class_id, from hlds_data to prog_data. compiler/hlds_data.m: compiler/prog_util.m: Move predicates for manipulating cons_ids from hlds_data to prog_util. compiler/inst.m: compiler/prog_data.m: Move the contents of inst.m to prog_data.m, since that is where it belongs, and since doing so eliminates a circular dependency. The separation doesn't serve any purpose any more, since we don't need to import hlds_data.m anymore to get access to the cons_id type. compiler/mode_util.m: compiler/prog_mode.m: compiler/parse_tree.m: Move the predicates in mode_util that don't depend on the HLDS to a new module prog_mode, which is part of parse_tree.m. compiler/notes/compiler_design.m: Mention prog_mode.m, and delete the mention of inst.m. compiler/mercury_to_mercury.m: compiler/hlds_out.m: Move the predicates that depend on HLDS out of mercury_to_mercury.m to hlds_out.m. Export from mercury_to_mercury.m the predicates needed by the moved predicates. compiler/hlds_out.m: compiler/prog_out.m: Move predicates for printing parts of the parse tree out of hlds_out.m to prog_out.m, since mercury_to_mercury.m needs to use them. compiler/purity.m: compiler/prog_out.m: Move predicates for printing purities from purity.m, which is part of check_hlds.m, to prog_out.m, since mercury_to_mercury.m needs to use them. compiler/passes_aux.m: compiler/prog_out.m: Move some utility predicates (e.g. for printing progress messages) from passes_aux.m to prog_out.m, since some predicates in submodules of parse_tree.m need to use them. compiler/foreign.m: compiler/prog_data.m: Move some types from foreign.m to prog_data.m to allow the elimination of some dependencies on foreign.m from submodules of parse_tree.m. compiler/*.m: Conform to the changes above, mostly by updating lists of imported modules and module qualifications. In some cases, also do some local cleanups such as converting predicate declarations to predmode syntax and fixing white space. |
||
|
|
7bf0cd03af |
Reduce the overhead of all forms of tabling by eliminating in many cases
Estimated hours taken: 32
Branches: main
Reduce the overhead of all forms of tabling by eliminating in many cases
the overhead of transferring data across the C/Mercury boundary. These
involve lots of control transfers as well as assignments to and from
Mercury abstract machine registers, which are not real machine registers
on x86 machines. Benchmarking in Uppsala revealed this overhead to be
a real problem.
The way we do that is by changing the tabling transformation so that instead
of generating sequences of calls to predicates from library/table_builtin.m,
we generate sequences of calls to C macros from runtime/mercury_tabling_pred.h,
and emit the resulting code string as the body of a foreign_proc goal.
(The old transformation is still available via a new option,
--no-tabling-via-extra-args.)
Since the number of inputs and outputs of the resulting C code sequences
are not always fixed (they can depend on the number of input or output
arguments of predicate being transformed), implementing this required
adding to foreign_procs a new field that allows the specification of extra
arguments to be passed to and from the given foreign code fragment. For now,
this mechanism is implemented only by the C backends, since it is needed
only by the C backends. (We don't support yet tabling on other backends.)
To simplify the new implementation of the field on foreign_procs, consolidate
three existing fields into one. Each of these fields was a list with one
element per argument, so turning them into a single list with a combined record
per argument should also improve reliability, since it reduces the likelyhood
of updates leaving the data structure inconsistent.
The goal paths of components of a tabled predicate depend on whether
-no-tabling-via-extra-args was specified. To enable the expected outputs
of the debugger test cases testing tabling, we add a new mdb command,
goal_paths, that controls whether goal paths are printed by the debugger
at events, and turn off the printing of events in the relevant test cases.
Also, prepare for a future change to optimize the trie structure for
user-defined types by handling type_infos (and once we support them,
typeclass_infos) specially.
compiler/table_gen.m:
Change the tabling transformation along the lines described above.
To allow us to factor out as much of the new code as possible,
we change the meaning of the call_table_tip variable for minimal
model subgoals: instead of the trie node at the end of the answer
table, it is not now the subgoal reachable from it. This change
has no effect as yet, because we use call_table_tip variables
only to perform resets across retries in the debugger, and we
don't do retries across calls to minimal model tabled predicates.
Put predicates into logical groups.
library/table_builtin.m:
runtime/mercury_tabling_preds.h:
When the new transformations in table_gen.m generate foreign_procs
with variable numbers of arguments, the interfaces of those
foreign_procs often do not match the interfaces of the existing
library predicates at their core: they frequently have one more
or one fewer argument. To prevent any possible confusion, in such
cases we add a new variant of the predicate. These predicates
have the suffix _shortcut in their name. Their implementations
are dummy macros that do nothing; they serve merely as placeholders
before or after which the macros that actually do the work are
inserted.
Move the definitions of the lookup, save and restore predicates
into mercury_tabling_preds.h. Make the naming scheme of their
arguments more regular.
runtime/mercury_minimal_model.c:
runtime/mercury_tabling_preds.h:
Move the definition of a predicate from mercury_minimal_model.c
to mercury_tabling_preds.h, since the compiler now needs to be
able to generate an inlined version of it.
compiler/hlds_goal.m:
Replace the three existing fields describing the arguments of
foreign_procs with one, and add a new field describing the extra
arguments that may be inserted by table_gen.m.
Add utility predicates for processing the arguments of foreign_procs.
Change the order of some existing groups of declarations make it
more logical.
compiler/hlds_pred.m:
runtime/mercury_stack_layout.h:
Extend the data structures recording the structure of tabling tries
to allow the representation of trie steps for type_infos and
typeclass_infos.
runtime/mercury_tabling_macros.c:
Fix a bug regarding the tabling of typeclass_infos, which is now
required for a clean compile.
compiler/pragma_c_gen.m:
compiler/ml_code_gen.m:
Modify the generation of code for foreign_procs to handle extra
arguments, and to conform to the new data structures for foreign_proc
arguments.
compiler/llds.m:
The tabling transformations can now generate significantly sized
foreign_procs bodies, which the LLDS code generator translates to
pragma_c instructions. Duplicating these by jump optimization
may lose more by worsening locality than it gains in avoiding jumps,
so we add an extra field to pragma_c instructions that tells jumpopt
not to duplicate code sequences containing such pragma_cs.
compiler/jumpopt.m:
Respect the new flag on pragma_cs.
compiler/goal_util.m:
Add a predicate to create foreign_procs with specified contents,
modelled on the existing predicate to create calls.
Change the order of the arguments of that existing predicate
to make it more logical.
compiler/polymorphism.m:
Conform to the new definition of foreign_procs. Try to simplify
the mechanism for generating the type_info and typeclass_info
arguments of foreign_proc goals, but it is not clear that this
code is even ever executed.
compiler/aditi_builtin_ops.m:
compiler/assertion.m:
compiler/bytecode_gen.m:
compiler/clause_to_proc.m:
compiler/code_gen.m:
compiler/code_info.m:
compiler/code_util.m:
compiler/constraint.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/dependency_graph.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/dnf.m:
compiler/dupelim.m:
compiler/equiv_type_hlds.m:
compiler/exprn_aux.m:
compiler/follow_code.m:
compiler/follow_vars.m:
compiler/frameopt.m:
compiler/goal_form.m:
compiler/goal_path.m:
compiler/higher_order.m:
compiler/higher_order.m:
compiler/hlds_module.m:
compiler/hlds_out.m:
compiler/inlining.m:
compiler/ite_gen.m:
compiler/layout_out.m:
compiler/livemap.m:
compiler/liveness.m:
compiler/llds_out.m:
compiler/loop_inv.m:
compiler/magic.m:
compiler/make_hlds.m:
compiler/mark_static_terms.m:
compiler/middle_rec.m:
compiler/modes.m:
compiler/modules.m:
compiler/opt_debug.m:
compiler/pd_cost.m:
compiler/prog_rep.m:
compiler/purity.m:
compiler/quantification.m:
compiler/reassign.m:
compiler/rl_exprn.m:
compiler/saved_vars.m:
compiler/simplify.m:
compiler/size_prof.m:
compiler/store_alloc.m:
compiler/stratify.m:
compiler/switch_detection.m:
compiler/term_pass1.m:
compiler/term_traversal.m:
compiler/termination.m:
compiler/trace.m:
compiler/typecheck.m:
compiler/unify_proc.m:
compiler/unique_modes.m:
compiler/unneeed_code.m:
compiler/unused_args.m:
compiler/use_local_vars.m:
Conform to the new definition of foreign_procs, pragma_cs and/or
table trie steps, or to changed argument orders.
compiler/add_heap_ops.m:
compiler/add_trail_ops.m:
compiler/cse_detection.m:
compiler/dead_proc_elim.m:
compiler/equiv_type.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/lco.m:
compiler/module_util.m:
compiler/opt_util.m:
compiler/stack_opt.m:
compiler/trans_opt.m:
Conform to the new definition of foreign_procs.
Bring these modules up to date with our current code style guidelines,
using predmode declarations, state variable syntax and unification
expressions as appropriate.
compiler/mercury_compile.m:
Conform to the changed argument order of a predicate in trans_opt.m.
compiler/options.m:
Add the --no-tabling-via-extra-args option, but leave the
documentation commented out since the option is for developers only.
doc/user_guide.texi:
Document --no-tabling-via-extra-args option, though leave the
documentation commented out since the option is for developers only.
doc/user_guide.texi:
doc/mdb_categories:
Document the new goal_paths mdb command.
trace/mercury_trace_internals.c:
Implement the new goal_paths mdb command.
tests/debugger/completion.exp:
Conform to the presence of the goal_paths mdb command.
tests/debugger/mdb_command_test.inp:
Test the existence of documentation for the goal_paths mdb command.
tests/debugger/print_table.{inp,exp*}:
tests/debugger/retry.{inp,exp*}:
Use the goal_paths command to avoid having the expected output
depend on the presence or absence of --tabling-via-extra-args.
tests/tabling/table_foreign_output.{m,exp}:
Add a new test case to test the save/restore of arguments of foreign
types.
tests/tabling/Mmakefile:
Enable the new test case.
tests/tabling/test_tabling:
Make this script more robust.
Add an option for testing only the standard model forms of tabling.
|
||
|
|
8693e293a2 |
This diff makes hlds_pred.m and many callers of its predicates easier to read
Estimated hours taken: 4 Branches: main This diff makes hlds_pred.m and many callers of its predicates easier to read and to maintain, but contains no changes in algorithms whatsoever. compiler/hlds_pred.m: Bring this module into line with our current coding standards. Use predmode declarations, functions, and state variable syntax when appropriate. Reorder arguments of predicates where necessary for the use of state variable syntax, and where this improves readability. Replace old-style lambdas with new-style lambdas or with partially applied named procedures. Standardize indentation. compiler/*.m: Conform to the changes in hlds_pred.m. This mostly means using the new argument orders of predicates exported by hlds_pred.m. Where this is now conveniently possible, change predicates to use state variable notation. In some modules, using state variable notation required changing the orders of arguments in the module's top predicate. compiler/passes_aux.m: Change the order of arguments in the calls this module makes to allow the callees to use state variable notation. Convert this module to state variable notation too. |
||
|
|
9551640f55 |
Import only one compiler module per line. Sort the blocks of imports.
Estimated hours taken: 2 Branches: main compiler/*.m: Import only one compiler module per line. Sort the blocks of imports. This makes it easier to merge in changes. In a couple of places, remove unnecessary imports. |
||
|
|
189b9215ae |
This diff implements stack slot optimization for the LLDS back end based on
Estimated hours taken: 400
Branches: main
This diff implements stack slot optimization for the LLDS back end based on
the idea that after a unification such as A = f(B, C, D), saving the
variable A on the stack indirectly also saves the values of B, C and D.
Figuring out what subset of {B,C,D} to access via A and what subset to access
via their own stack slots is a tricky optimization problem. The algorithm we
use to solve it is described in the paper "Using the heap to eliminate stack
accesses" by Zoltan Somogyi and Peter Stuckey, available in ~zs/rep/stackslot.
That paper also describes (and has examples of) the source-to-source
transformation that implements the optimization.
The optimization needs to know what variables are flushed at call sites
and at program points that establish resume points (e.g. entries to
disjunctions and if-then-elses). We already had code to compute this
information in live_vars.m, but this code was being invoked too late.
This diff modifies live_vars.m to allow it to be invoked both by the stack
slot optimization transformation and by the code generator, and allows its
function to be tailored to the requirements of each invocation.
The information computed by live_vars.m is specific to the LLDS back end,
since the MLDS back ends do not (yet) have the same control over stack
frame layout. We therefore store this information in a new back end specific
field in goal_infos. For uniformity, we make all the other existing back end
specific fields in goal_infos, as well as the similarly back end specific
store map field of goal_exprs, subfields of this new field. This happens
to significantly reduce the sizes of goal_infos.
To allow a more meaningful comparison of the gains produced by the new
optimization, do not save any variables across erroneous calls even if
the new optimization is not enabled.
compiler/stack_opt.m:
New module containing the code that performs the transformation
to optimize stack slot usage.
compiler/matching.m:
New module containing an algorithm for maximal matching in bipartite
graphs, specialized for the graphs needed by stack_opt.m.
compiler/mercury_compile.m:
Invoke the new optimization if the options ask for it.
compiler/stack_alloc.m:
New module containing code that is shared between the old,
non-optimizing stack slot allocation system and the new, optimizing
stack slot allocation system, and the code for actually allocating
stack slots in the absence of optimization.
Live_vars.m used to have two tasks: find out what variables need to be
saved on the stack, and allocating those variables to stack slots.
Live_vars.m now does only the first task; stack_alloc.m now does
the second, using code that used to be in live_vars.m.
compiler/trace_params:
Add a new function to test the trace level, which returns yes if we
want to preserve the values of the input headvars.
compiler/notes/compiler_design.html:
Document the new modules (as well as trace_params.m, which wasn't
documented earlier).
compiler/live_vars.m:
Delete the code that is now in stack_alloc.m and graph_colour.m.
Separate out the kinds of stack uses due to nondeterminism: the stack
slots used by nondet calls, and the stack slots used by resumption
points, in order to allow the reuse of stack slots used by resumption
points after execution has left their scope. This should allow the
same stack slots to be used by different variables in the resumption
point at the start of an else branch and nondet calls in the then
branch, since the resumption point of the else branch is not in effect
when the then branch is executed.
If the new option --opt-no-return-calls is set, then say that we do not
need to save any values across erroneous calls.
Use type classes to allow the information generated by this module
to be recorded in the way required by its invoker.
Package up the data structures being passed around readonly into a
single tuple.
compiler/store_alloc.m:
Allow this module to be invoked by stack_opt.m without invoking the
follow_vars transformation, since applying follow_vars before the form
of the HLDS code is otherwise final can be a pessimization.
Make the module_info a part of the record containing the readonly data
passed around during the traversal.
compiler/common.m:
Do not delete or move around unifications created by stack_opt.m.
compiler/call_gen.m:
compiler/code_info.m:
compiler/continuation_info.m:
compiler/var_locn.m:
Allow the code generator to delete its last record of the location
of a value when generating code to make an erroneous call, if the new
--opt-no-return-calls option is set.
compiler/code_gen.m:
Use a more useful algorithm to create the messages/comments that
we put into incr_sp instructions, e.g. by distinguishing between
predicates and functions. This is to allow the new scripts in the
tool directory to gather statistics about the effect of the
optimization on stack frame sizes.
library/exception.m:
Make a hand-written incr_sp follow the new pattern.
compiler/arg_info.m:
Add predicates to figure out the set of input, output and unused
arguments of a procedure in several different circumstances.
Previously, variants of these predicates were repeated in several
places.
compiler/goal_util.m:
Export some previously private utility predicates.
compiler/handle_options.m:
Turn off stack slot optimizations when debugging, unless
--trace-optimized is set.
Add a new dump format useful for debugging --optimize-saved-vars.
compiler/hlds_llds.m:
New module for handling all the stuff specific to the LLDS back end
in HLDS goal_infos.
compiler/hlds_goal.m:
Move all the relevant stuff into the new back end specific field
in goal_infos.
compiler/notes/allocation.html:
Update the documentation of store maps to reflect their movement
into a subfield of goal_infos.
compiler/*.m:
Minor changes to accomodate the placement of all back end specific
information about goals from goal_exprs and individual fields of
goal_infos into a new field in goal_infos that gathers together
all back end specific information.
compiler/use_local_vars.m:
Look for sequences in which several instructions use a fake register
or stack slot as a base register pointing to a cell, and make those
instructions use a local variable instead.
Without this, a key assumption of the stack slot optimization,
that accessing a field in a cell costs only one load or store
instruction, would be much less likely to be true. (With this
optimization, the assumption will be false only if the C compiler's
code generator runs out of registers in a basic block, which for
the code we generate should be unlikely even on x86s.)
compiler/options.m:
Make the old option --optimize-saved-vars ask for both the old stack
slot optimization (implemented by saved_vars.m) that only eliminates
the storing of constants in stack slots, and the new optimization.
Add two new options --optimize-saved-vars-{const,cell} to turn on
the two optimizations separately.
Add a bunch of options to specify the parameters of the new
optimizations, both in stack_opt.m and use_local_vars.m. These are
for implementors only; they are deliberately not documented.
Add a new option, --opt-no-return-cells, that governs whether we avoid
saving variables on the stack at calls that cannot return, either by
succeeding or by failing. This is for implementors only, and thus
deliberately documented only in comments. It is enabled by default.
compiler/optimize.m:
Transmit the value of a new option to use_local_vars.m.
doc/user_guide.texi:
Update the documentation of --optimize-saved-vars.
library/tree234.m:
Undo a previous change of mine that effectively applied this
optimization by hand. That change complicated the code, and now
the compiler can do the optimization automatically.
tools/extract_incr_sp:
A new script for extracting stack frame sizes and messages from
stack increment operations in the C code for LLDS grades.
tools/frame_sizes:
A new script that uses extract_incr_sp to extract information about
stack frame sizes from the C files saved from a stage 2 directory
by makebatch and summarizes the resulting information.
tools/avg_frame_size:
A new script that computes average stack frame sizes from the files
created by frame_sizes.
tools/compare_frame_sizes:
A new script that compares the stack frame size information
extracted from two different stage 2 directories by frame_sizes,
reporting on both average stack frame sizes and on specific procedures
that have different stack frame sizes in the two versions.
|
||
|
|
7597790760 |
Use sub-modules to structure the modules in the Mercury compiler directory.
The main aim of this change is to make the overall, high-level structure of the compiler clearer, and to encourage better encapsulation of the major components. compiler/libs.m: compiler/backend_libs.m: compiler/parse_tree.m: compiler/hlds.m: compiler/check_hlds.m: compiler/transform_hlds.m: compiler/bytecode_backend.m: compiler/aditi_backend.m: compiler/ml_backend.m: compiler/ll_backend.m: compiler/top_level.m: New files. One module for each of the major components of the Mercury compiler. These modules contain (as separate sub-modules) all the other modules in the Mercury compiler, except gcc.m and mlds_to_gcc.m. Mmakefile: compiler/Mmakefile: Handle the fact that the top-level module is now `top_level', not `mercury_compile' (since `mercury_compile' is a sub-module of `top_level'). compiler/Mmakefile: Update settings of *FLAGS-<modulename> to use the appropriate nested module names. compiler/recompilation_check.m: compiler/recompilation_version.m: compiler/recompilation_usage.m: compiler/recompilation.check.m: compiler/recompilation.version.m: compiler/recompilation.version.m: Convert the `recompilation_*' modules into sub-modules of the `recompilation' module. compiler/*.m: compiler/*.pp: Module-qualify the module names in `:- module', `:- import_module', and `:- use_module' declarations. compiler/base_type_info.m: compiler/base_type_layout.m: Deleted these unused empty modules. compiler/prog_data.m: compiler/globals.m: Move the `foreign_language' type from prog_data to globals. compiler/mlds.m: compiler/ml_util.m: compiler/mlds_to_il.m: Import `globals', for `foreign_language'. Mmake.common.in: trace/Mmakefile: runtime/Mmakefile: Rename the %.check.c targets as %.check_hdr.c, to avoid conflicts with compiler/recompilation.check.c. |
||
|
|
1c65d003f7 |
Add the shorthand_goal_expr wrapper type to ease hlds->hlds transformations.
Estimated hours taken: 4.5
Branches: main
Add the shorthand_goal_expr wrapper type to ease hlds->hlds transformations.
compiler/hlds_goal.m
Create a new type, the `shorthand_goal_expr', for goals kinds that
are implemented by a (ordinary_hlds + shorthand) -> (ordinary_hlds)
transformation. At present, bi_implication is the only kind of
of goal that is implemented in this way.
Moved bi_implication functor from the type goal_expr to the new
shorthand_goal_expr type.
Added the functor shorthand to the goal_expr type.
compiler/*.m
Change switches on hlds_goal_expr that call error when they recognise
`bi_implication' from calling error when they recognise
`bi_implication' to calling error when they recognise `shorthand'.
For all predicates K that
a) switch on hlds_goal_expr and
b) perform non-trivial processing when they recognise
`bi_implication'
change K such that it now calls K_shorthand upon recognising the
functor `shorthand'. Define K_shorthand to switch on
shorthand_goal_expr, where the code for the `bi_implication' case
formerly contained in K is now contained in K_shorthand.
|
||
|
|
711da78188 |
Rename foreign_code as foreign_proc where appropriate in the compiler.
Estimated hours taken: 4.0 Branches: main Rename foreign_code as foreign_proc where appropriate in the compiler. The rationale for this change is that it makes maintaining the code much simpler because it is clear whether `foreign' refers to a slab of code (foreign_code) or a procedure (foreign_proc). :- type pragma_foreign_code_attributes :- type pragma_foreign_proc_attributes The functors for pragma_type foreign(Lang, BodyCode) foreign(Attributes, Name, PredOrFunc, Vars, Varset, Impl) become foreign_code(Lang, BodyCode) foreign_proc(Attributes, Name, PredOrFunc, Vars, Varset, Impl) And the HLDS goal `pragma_foreign_code' becomes `foreign_proc'. compiler/*.m: Update the compiler to use the new names. |
||
|
|
477ecb18f6 |
Implement pragma foreign_code for Managed C++.
Estimated hours taken: 60 Implement pragma foreign_code for Managed C++. Currently you can only write MC++ code if your backend is capable of generating use MC++ as its "native" foreign language. The IL backend is the only backend that does this at the moment (the other backends have C as their "native" foreign language). Most of the machinery is in place to call from C to (normal) C++ but there is little work done on actually spitting out the C++ code into a separate file. The IL backend does this step already with managed C++. The intention is to turn foreign_code for C++ into a pragma import (which imports the C++ function from a separate file) and foreign_code for C (which calls the imported function). The C++ code will be inserted into a separate file that is compiled using C linkage. The important improvement this change gives is that you can write a module with a C and a MC++ implementations side-by-side. The target backend will select the most appropriate foreign language to use. You can override its choice using --use-foreign-language. Later on we will probably want more flexibility than just a single language selection option). This change also implements :- pragma foreign_decl, which allows header file style declarations to be written in languages other than C. compiler/code_gen.m: Reject code that is not C when generating LLDS. compiler/export.m: Start renaming C as foreign. Reject code that is not C when generating exports. compiler/foreign.m: A new module to handle foreign language interfacing. The bulk of the code for pragma import has been moved here from make_hlds. compiler/globals.m: Convert foreign language names to foreign_language. This code has been moved closer to the similar conversion we do for target language names. Add globals__io_lookup_foreign_language_option to make it easier to deterministically lookup the options relating to foreign languages. compiler/hlds_module.m: Move module_add_foreign_decl and module_add_foreign_body_code from make_hlds.m (where they were called module_add_c_header and module_add_c_code). compiler/hlds_out.m: Write the foreign language out in HLDS dumps. compiler/llds.m: Change foreign_header_info to foreign_decl_info. Change definitions of foreign_decl_code and foreign_body_code to include the language. compiler/llds_out.m: Reject code that is not C when writing out LLDS. compiler/make_hlds.m: Add foreign language information to the bodys and decls when creating them. Update error messages to refer to foreign code instead of C code. Use foreign.m to generate interfaces from the backend language to the foreign language. Hardcode C as the language for fact tables. compiler/mercury_compile.m: Collect the appropriate foreign language code together for output to the backend. compiler/intermod.m: compiler/mercury_to_mercury.m: Output the foreign language string. Change a few names to foreign_code instead of c_code. compiler/ml_code_gen.m: Filter the foreign language bodys and decls so that we only get the ones we are in (given by the use-foreign-language option). compiler/mlds_to_c.m: Abort if we are given non C foreign language code to output (we might handle it here in future, or we might handle it elsewhere). compiler/mlds_to_ilasm.m: Abort if we are given non MC++ foreign language code to output (we might handle it here in future, or we might handle it elsewhere). compiler/options.m: compiler/handle_options.m: Add --use-foreign-language as a user option to control the preferred foreign language to use as the implementation of this module. Add backend_foreign_language as an internal option which stores the foreign language that the compiler will use as a default (e.g. the natural foreign language for the backend to use). Set the preferred backend foreign language depending on the target. compiler/prog_data.m: Add managedcplusplus as a new alternative for the foreign_language type. Make c_header_code into foreign_decl. Give the foreign language for foreign_code as an attribute of the code. Write code to turn attributes into a list of strings (suitable for writing out by mercury_to_mercury). This fixes what appears to be a bug in tabled_for_io -- the tabled_for_io attribute was not being written out. Structure the code so this bug is difficult to repeat in future. compiler/prog_io_pragma.m: Parse foreign_decl. Turn c_header_code into a special case of foreign_decl. compiler/*.m: Remove the language field from pragma_foreign_code, it is now an attribute of the code. Various type and variable renamings. tests/invalid/pragma_c_code_and_clauses1.err_exp: tests/invalid/pragma_c_code_dup_var.err_exp: tests/warnings/singleton_test.exp: Update the tests to reflect the new error messages talking about :- pragma foreign_code rather than :- pragma c_code. |
||
|
|
e823aa5838 |
Fix some bugs in the static ground term optimization for the MLDS
Estimated hours taken: 20 Fix some bugs in the static ground term optimization for the MLDS back-end. compiler/ml_code_util.m: compiler/ml_code_gen.m: Ensure that declarations for a goal are generated in such a way that they scope over the C code generated for any following goals. This is needed to ensure that we don't generate references to undeclared names in static constants. compiler/ml_unify_gen.m: compiler/ml_code_util.m: Ensure that all static consts get unique names, so that ml_elim_nested.m can hoist them to the top level. Also move ml_gen_static_const_decl_flags from ml_unify_gen.m to ml_code_util.m, for use by ml_code_gen.m. compiler/ml_elim_nested.m: Hoist out the definitions of static constants to the top level in cases where they might be referenced from nested functions. Also change the name of the local_vars field of the ml_elim_info to local_data, to make it clear that it can hold constants too. compiler/mark_static_terms.m: Fix some typos in the comments. compiler/mlds_to_c.m: Fix an XXX: it was not outputting `static' in the right places. tests/valid/Mmakefile: tests/valid/static.m: Add some regression tests. |
||
|
|
35d1d914e7 |
Update the MLDS backend to handle structure reuse and compile time gc.
Estimated hours taken: 20
Update the MLDS backend to handle structure reuse and compile time gc.
Note that currently no pass on the main branch currently generates this
information yet.
mlds.m:
Add a new instruction delete_object which is to be inserted
whenever a lval can be compile time garbage collected.
ml_unify_gen.m:
Handle the case where the HowToConstruct field of a construction
is reuse_cell(_).
Handle the case where a deconstruction can be compile time gc'd.
hlds_goal.m:
Add a new field, can_cgc, to deconstruction unifications. This
field is `yes' if the deconstruction unification can be compile time
garbage collected.
hlds_out.m:
Output the can_cgc field. Output unification information if we
request the structure reuse information.
ml_elim_nested.m:
mlds_to_c.m:
Handle the delete_object instruction.
builtin_ops.m:
Fix a bug where body was an unary op instead of a binary op.
bytecode.m:
c_util.m:
llds.m:
opt_debug.m:
vn_cost.m:
Changes to reflect that body is a binary op.
bytecode_gen.m:
code_aux.m:
common.m:
cse_detection.m:
dependency_graph.m:
det_analysis.m:
goal_util.m:
higher_order.m:
mark_static_terms.m:
mode_util.m:
modecheck_unify.m:
pd_cost.m:
pd_util.m:
prog_rep.m:
rl_exprn.m:
rl_key.m:
simplify.m:
switch_detection.m:
term_traversal.m:
unify_gen.m:
unused_args.m:
Handle the can compile time gc field in deconstruction unifications.
|
||
|
|
c192d50143 |
Add preliminary support for a new pragma:
Estimated hours taken: 15 Add preliminary support for a new pragma: :- pragma foreign_code(LanguageString, .... <same args as c_code>). This is intended to be the eventual replacement of pragma c_code. Presently the only valid language is "C". The existing pragma c_code is simply turned into pragma foreign_code. pragma foreign_code is not a supported pragma at the moment. There are several other changes that are intended (for example, foreign_code will be impure by default). This change also changes the HLDS goal pragma_c_code/7 to pragma_foreign_code/8 where the extra argument is the foreign language. Any code currently generating output for pragma C code simply checks that the foreign language is set to "c". Since this is the only alternative of the type foreign_language, it will always succeed. However when new alternatives are added it should be fairly easy to find where the changes need to be made. Some type names and predicate names have also been updated, however there are many more that haven't yet been touched. compiler/prog_io_pragma.m: Accept the new syntax. Turn the old syntax into the new item. compiler/hlds_goal.m: Change pragma_c_code/7 to pragma_foreign_code/8. Define the foreign_language type. compiler/llds.m: Change user_c_code/2 to user_foreign_code/3. compiler/*.m: Update the rest of the compiler to handle these types. Make a few small changes to update variable names, predicate names and type names. |
||
|
|
082b084ac7 |
Implement static allocation of grounds terms for the
Estimated hours taken: 20 Implement static allocation of grounds terms for the MLDS back-end. compiler/hlds_goal.m: Change the `maybe(cell_to_reuse)' field of `construct' unifications from a `maybe(cell_to_reuse)' into a `how_to_construct' type with three alternatives, `reuse_cell(cell_to_reuse)', `construct_dynamically', and the new alternative `construct_statically(static_cons)'. `static_cons' is a new type that provides information on how to construct a static ground term. compiler/goal_util.m: compiler/lambda.m: compiler/magic.m: compiler/magic_util.m: compiler/modecheck_unify.m: compiler/polymorphism.m: compiler/quantification.m: Trivial changes to handle the change to the `maybe(cell_to_reuse)' field of `construct' unifications. compiler/mark_static_terms.m: New module. This traverses the HLDS and marks terms which can be construction unifications which can be allocated statically with the `construct_statically' flag. compiler/mercury_compile.m: For the MLDS back-end, if the static_ground_terms option is set, invoke the mark_static_terms pass. compiler/ml_unify_gen.m: When generating code for construction unifications, pass down the `how_to_reuse' field. If this is `construct_statically', then generate a local initialized static constant, rather than using `new_object' to allocate the memory dynamically. (This required some fairly substantial reorganization. I changed ml_gen_construct so that no_tag types and compound terms, including closures, are handled separately from constants. I moved some of the code from ml_gen_construct_rep into ml_gen_construct, and the remainder, which deals with constants, was simplified and renamed ml_get_constant. The code for constructing closures was moved into a separate predicate ml_gen_closure, and was simplified by elimination of some code duplication. I also added a bunch of new procedures for generating static constants.) compiler/mlds.m: Add a new alternative `mlds__array_type' to the mlds__type type. This is needed by ml_unify_gen.m for static constants. compiler/mlds_to_c.m: Handle `mlds__array_type'. This required splitting mlds_output_type into mlds_output_type_prefix and mlds_output_type_suffix. compiler/ml_code_util.m: Reorder the code slightly, to improve readability. |