mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-17 06:47:17 +00:00
05ce757fdfdb43da74be8ee56c541cf7edfb22b8
31 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d00ea69529 |
Switch from using set(prog_var), which is represented using set_ordlist,
Estimated hours taken: 12 Branches: main Switch from using set(prog_var), which is represented using set_ordlist, to set_of_progvar, which is represented using tree_bitset, for most sets of variables in the compiler, including the nonlocals sets in goal_infos. This diff yields about a 5% speedup when compiling the training_cars_full.m stress test, but also about a 1% slowdown on tools/speedtest. Both of these are with the current default state in which tree_bitset is compiled with a whole bunch of sanity checks. If these are disabled, we get roughly a 1% speedup on tools/speedtest. I intend to disable those sanity checks after a shakedown period of a week or two in which the updated version of the compiler is installed on our platforms. compiler/hlds_goal.m: Replace almost all occurrences of set(prog_var) with set_of_progvar. The main exceptions are the types supporting rbmm. compiler/set_of_var.m: Add some more predicates and functions that previous existed on sets but not yet on set_of_vars. compiler/*.m: Conform to the change in hlds_goal.m, and make similar changes in set representations. library/bag.m: Add a predicate and function for creating a bag from a sorted list. We already had them for creating a bag from a set, but a set_of_progvar shouldn't have to be converted to a set. library/robdd.m: Fix deviations from our programming style. |
||
|
|
295415090e |
Convert almost all remaining modules in the compiler to use
Estimated hours taken: 6 Branches: main compiler/*.m: Convert almost all remaining modules in the compiler to use "$module, $pred" instead of "this_file" in error messages. In a few cases, the old error message was misleading, since it contained an incorrect, out-of-date or cut-and-pasted predicate name. tests/invalid/unresolved_overloading.err_exp: Update an expected output containing an updated error message. |
||
|
|
9f68c330f0 |
Change the argument order of many of the predicates in the map, bimap, and
Branches: main
Change the argument order of many of the predicates in the map, bimap, and
multi_map modules so they are more conducive to the use of state variable
notation, i.e. make the order the same as in the sv* modules.
Prepare for the deprecation of the sv{bimap,map,multi_map} modules by
removing their use throughout the system.
library/bimap.m:
library/map.m:
library/multi_map.m:
As above.
NEWS:
Announce the change.
Separate out the "highlights" from the "detailed listing" for
the post-11.01 NEWS.
Reorganise the announcement of the Unicode support.
benchmarks/*/*.m:
browser/*.m:
compiler/*.m:
deep_profiler/*.m:
extras/*/*.m:
mdbcomp/*.m:
profiler/*.m:
tests/*/*.m:
ssdb/*.m:
samples/*/*.m
slice/*.m:
Conform to the above change.
Remove any dependencies on the sv{bimap,map,multi_map} modules.
|
||
|
|
b3fa535100 |
A rewrite of the state variable transformation from the ground up.
Estimated hours taken: 60
Branches: main
A rewrite of the state variable transformation from the ground up.
The initial aim was to avoid situations (encountered in the g12 project)
in which the old state variable transformation generated code that
did not satisfy the mode checker, due to unnecessary unifications.
The new system tries hard to minimize the number of unifications added to the
program. It does this by relying extensively on the idea that in a branched
structure such as an disjunction, if two branches both update the same state
variable, and the variables representing the last state of the state variable
in the two branches are (say) X and Y, and we pick X to represent the current
state after the disjunction, then we don't have to put the assignment X := Y
into the second branch; instead, we can RENAME Y to X in that branch.
To avoid renaming a goal several times (for itself, for its parent, for its
grandparent etc), we delay all renamings until the end, when we do it all
in one traversal.
The old state var system was opaque and hard to understand, partly because
its basic operations did different things in different contexts. The new system
is a much more direct expression of the intuitive meaning of state variables;
it keeps track of their state much as the programmer writing the original code
would. It should therefore be significantly easier to understand and to modify
in the future.
The new system can also detect more kinds of errors in the use of state
variables. For example it can discover that some branches of a disjunction or
if-then-else set the initial value of a state variable and some do not.
This is ok if the non-setting-branch cannot succeed; if it can, then it is
a bug. We therefore generate messages about such branches, but print them
only if mode analysis finds a bug in the procedure, since in that case,
the lack of initialization may be the cause of the bug.
doc/reference_manual.texi:
Replaced an old example that didn't know what it was talking about,
and thoroughly confused the issue of what is legal use of state
variables and what is not.
compiler/state_var.m:
Rewrite this module along the lines mentioned above.
compiler/options.m:
Add two new options. One, warn-state-var-shadowing, controls whether
we generate warnings for one state var shadowing another (which
G12 has lots of). The other, --allow-defn-for-builtins, is for
developers only; it is needed to bootstrap changes that add new
builtins. I needed this for a form of the state variable transformation
that used calls to a new builtin predicate to copy the values of state
variables in branches that did not modify them, even though other
branches did. I ultimately used unifications to do this copying,
for reasons documented in state_var.m.
compiler/add_clause.m:
compiler/add_pragma.m:
Respect the new --allow-defn-for-builtins option.
(Previously, we changed the code that now looks up the value of the
option.)
doc/user_guide.texi:
Document the --warn-state-var-shadowing option.
Fix some old documentation about dump options.
compiler/simplify.m:
Fix an old oversight: list the predicates in table_builtin.m that may
have calls introduced to them by table_gen.m.
compiler/superhomogeneous.m:
compiler/field_access.m:
compiler/add_clause.m:
compiler/goal_expr_to_goal.m:
Together with state_var.m, these modules contain the transformation
from the parse tree to the HLDS. Since the change to state_var.m
involves significant changes in its interface (such as separating out
the persistent and location-dependent aspects of the information needed
by the state variable transformation), and needing callbacks at
different points than the old transformation, these modules had to
change extensively as well to conform.
goal_expr_to_goal.m is a new module carved out of add_clause.m.
It deserves a module of its own because its code has a significantly
different purpose than add_clause.m. The two separate modules each
have much better cohesion than the old conjoined module did.
In superhomogeneous.m, replace two predicates that did the same thing
with one predicate.
compiler/make_hlds.m:
compiler/notes/compiler_design.html.m:
Mention the new module.
compiler/hlds_goal.m:
Add a mechanism to do the kind of incremental renaming that the state
variable transformation needs.
Add some utility predicates needed by the new code in other modules.
compiler/hlds_clause.m:
compiler/hlds_pred.m:
Add an extra piece of information to clauses and proc_infos:
a list of informational messages generated by the state variable
transformation about some branches of branched goals not giving initial
values to some state variables, while other branches do.
The state variable transformation fills in this field in clauses
where relevant.
compiler/clause_to_proc.m:
Copy this list of messages from clauses to proc_infos.
compiler/modes.m:
When generating an error message for a procedure, include this list
of messages from the state var transformation in the output.
compiler/handle_options.m:
Add a dump alias for debugging the state var transformation.
compiler/hlds_out_goal.m:
Add a predicate that is useful in trace messages when debugging
the compiler.
compiler/hlds_out_pred.m:
Print goal path and goal id information in clauses as well as
proc_infos, since the state var transformation now uses goal ids.
compiler/prog_item.m:
In lists of quantified vars in scope headers, separate out the vars
introduced as !S from those introduced as !.S and !:S. This makes it
easier for the state var transformation to handle them.
Document that we expect lists of quantified variables and state
variables to contain no duplicates. The state var transformation
is slightly simpler if we impose this requirement, and quantifying
a variable twice in the same scope does not make sense, and is
therefore almost certainly an error.
compiler/prog_io_util.m:
Generate error messages when a variable or state variable IS
listed twice in the same quantification list.
Factor out some code used to generate error messages.
compiler/typecheck.m:
Conform to the changes above.
Break a very large predicate into two smaller pieces.
compiler/add_class.m:
compiler/add_pragma.m:
compiler/add_pred.m:
compiler/assertion.m:
compiler/dead_proc_elim.m:
compiler/dependency_graph.m:
compiler/goal_path.m:
compiler/goal_util.m:
compiler/headvar_names.m:
compiler/hhf.m:
compiler/hlds_out_module.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/mercury_to_mercury.m:
compiler/module_imports.m:
compiler/module_qual.m:
compiler/post_typecheck.m:
compiler/prog_io_goal.m:
compiler/prog_util.m:
compiler/purity.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
Conform to the changes above.
compiler/mode_constraints.m:
compiler/modules.m:
compiler/structure_reuse.analysis.m:
Avoid the warnings we now generate about one state variable shadowing
another.
browser/declarative_user.m:
compiler/hlds_out_util.m:
compiler/ordering_mode_constraints.m:
compiler/table_gen.m:
deep_profiler/read_profile.m:
Improve programming style.
library/require.m:
Add expect_not, a negated version of expect.
library/varset.m:
Return lists of new variables in order, not reverse order.
mdbcomp/mdbcomp.goal_path.m:
compiler/prog_mode.m:
Add a utility predicate.
tests/debugger/tailrec1.exp:
tests/invalid/any_passed_as_ground.err_exp:
tests/invalid/bad_sv_unify_msg.err_exp:
tests/invalid/state_vars_test1.err_exp:
tests/invalid/state_vars_test4.err_exp:
tests/invalid/try_bad_params.err_exp:
tests/invalid/try_detism.err_exp:
tests/invalid/purity/impure_pred_t1_fixed.err_exp:
tests/invalid/purity/impure_pred_t2.err_exp:
Update the expected outputs of these test cases to account for
incidental changes in variable numbers and goal paths after this
change.
tests/general/state_vars_tests.{m,exp}:
Remove the code that expected the state var transformation to do
something that was actually AGAINST the reference manual: treating
the step from the condition to the then part of an if-then-else
expression (not a goal) as a sequence point.
tests/general/state_vars_trace.m:
Add a test case that is not enabled yet, since we don't pass it.
tests/hard_coded/bit_buffer_test.m:
Fix a bug in the test itself: the introduction of a state var twice
in the same scope.
tests/hard_coded/try_syntax_6.m:
Avoid a warning about state var shadowing.
tests/hard_coded/if_then_else_expr_state_var.{m,exp}:
A new test to check the proper handling of state vars in if-then-else
expressions.
tests/hard_coded/Mmakefile:
Enable the new test.
|
||
|
|
a2cd0da5b3 |
The existing representation of goal_paths is suboptimal for several reasons.
Estimated hours taken: 80 Branches: main The existing representation of goal_paths is suboptimal for several reasons. - Sometimes we need forward goal paths (e.g. to look up goals), and sometimes we need reverse goal paths (e.g. when computing goal paths in the first place). We had two types for them, but - their names, goal_path and goal_path_consable, were not expressive, and - we could store only one of them in goal_infos. - Testing whether goal A is a subgoal of goal B is quite error-prone using either form of goal paths. - Using a goal path as a key in a map, which several compiler passes want to do, requires lots of expensive comparisons. This diff replaces most uses of goal paths with goal ids. A goal id is an integer, so it can be used as a key in faster maps, or even in arrays. Every goal in the body of a procedure gets its id allocated in a depth first search. Since we process each goal before we dive into is descendants, the goal representing the whole body of a procedure always gets goal id 0. The depth first traversal also builds up a map (the containing goal map) that tells us the parent goal of ever subgoal, with the obvious exception of the root goal itself. From the containing goal map, one can compute both reverse and forward goal paths. It can also serve as the basis of an efficient test of whether the goal identified by goal id A is an ancestor of another goal identified by goal id B. We don't yet use this test, but I expect we will in the future. mdbcomp/program_representation.m: Add the goal_id type. Replace the existing goal_path and goal_path_consable types with two new types, forward_goal_path and reverse_goal_path. Since these now have wrappers around the list of goal path steps that identify each kind of goal path, it is now ok to expose their representations. This makes several compiler passes easier to code. Update the set of operations on goal paths to work on the new data structures. Add a couple of step types to represent lambdas and try goals. Their omission prior to this would have been a bug for constraint-based mode analysis, or any other compiler pass prior to the expansion out of lambda and try goals that wanted to use goal paths to identify subgoals. browser/declarative_tree.m: mdbcomp/rtti_access.m: mdbcomp/slice_and_dice.m: mdbcomp/trace_counts.m: slice/mcov.m: deep_profiler/*.m: Conform to the changes in goal path representation. compiler/hlds_goal: Replace the goal_path field with a goal_id field in the goal_info, indicating that from now on, this should be used to identify goals. Keep a reverse_goal_path field in the goal_info for use by RBMM and CTGC. Those analyses were too hard to convert to using goal_ids, especially since RBMM uses goal_paths to identify goals in multi-pass algorithms that should be one-pass and should not NEED to identify any goals for later processing. compiler/goal_path: Add predicates to fill in goal_ids, and update the predicates filling in the now deprecated reverse goal path fields. Add the operations needed by the rest of the compiler on goal ids and containing goal maps. Remove the option to set goal paths using "mode equivalent steps". Constraint based mode analysis now uses goal ids, and can now do its own equivalent optimization quite simply. Move the goal_path module from the check_hlds package to the hlds package. compiler/*.m: Conform to the changes in goal path representation. Most modules now use goal_ids to identify goals, and use a containing goal map to convert the goal ids to goal paths when needed. However, the ctgc and rbmm modules still use (reverse) goal paths. library/digraph.m: library/group.m: library/injection.m: library/pprint.m: library/pretty_printer.m: library/term_to_xml.m: Minor style improvements. |
||
|
|
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. |
||
|
|
1bf42bbc38 |
Avoid more dependencies between the processing of different procedures
Estimated hours taken: 8 Branches: main Avoid more dependencies between the processing of different procedures when the compiler is executed in parallel. compiler/accumulator.m: Instead of printing out error messages here, pass error_specs back to the top level. compiler/complexity.m: Use trace goals to print progress messages. compiler/passes_aux.m: Add the traversal type now needed by accumulator.m, and remove others that are no longer needed. Since now NO task needs I/O states, make the traversal predicates not take I/O state pair arguments any more. compiler/deforest.m: compiler/mercury_compile_llds_back_end.m: compiler/mercury_compile_mlds_back_end.m: compiler/mercury_compile_middle_passes.m: compiler/ssdebug.m: compiler/structure_reuse.analysis.m: compiler/structure_sharing.analysis.m: Conform to the changes in passes_aux.m and in accumulator.m. compiler/error_util.m: compiler/pd_util.m: Style fixes. tests/warnings/arg_order_rearrangement.exp: Expect the new and improved warning message. tests/warnings/arg_order_rearrangement.exp2: Mark this file as not an expected output, since a part of it doesn't seem to be ever generated by the compiler anymore. |
||
|
|
543fc6e342 |
Change the way the typechecker iterates over the predicates of the program.
Estimated hours taken: 12 Branches: main Change the way the typechecker iterates over the predicates of the program. We used to do it by looking up each predicate in the module_info, typechecking it, and putting it back into the module_info. We now do it by converting the predicate table into a list, iterating over the list transforming each pred_info in it, converting the updated list back to a predicate table. The original intention of this change was to allow different predicates to be typechecked in parallel by removing a synchronization bottleneck: the typechecking of a predicate now doesn't have to wait for the typechecking of the previous predicate to generate the updated version of the module_info. However, it turned out that the change is good for sequential execution as well, improving the time on tools/speedtest from 11.33 seconds to 11.08 seconds, a speedup of 2.2%. On tools/speedtest -l, which tests the compilation of more modules, the speedup is even better: 3.1% (from 32.63 to 31.60s). compiler/typecheck.m: Implement the above change. compiler/hlds_module.m: compiler/pred_table.m: Add a new operation, setting the list of valid pred_ids, now needed by typecheck.m, to both modules. Make the names of the predicates for accessing the predicate table more expressive, and make them conform to our naming conventions. compiler/*.m: Trivial changes to conform to the change in hlds_module.m. library/assoc_list.m: Add new predicates used by the new version of typecheck.m (at some time in its development). NEWS: Mention the new predicates. library/list.m: Improve documentation that is now copied to assoc_list.m. tools/speedtest: Make the test command more easily configurable. |
||
|
|
30aafc69a0 |
Split up three big compiler modules: llds_out.m, hlds_out.m (5000+ lines each)
Estimated hours taken: 12 Branches: main Split up three big compiler modules: llds_out.m, hlds_out.m (5000+ lines each) and deep_profiling.m (3000+ lines). Put the predicates in the resulting smaller modules into cohesive groups where possible. A few of the predicates in the original modules were unused; this diff deletes them. There are no algorithmic changes. compiler/llds_out_code_addr.m: New module containing the part of llds_out.m that outputs code addresses and labels. compiler/llds_out_data.m: New module containing the part of llds_out.m that outputs lvals, rvals and their components. compiler/llds_out_global.m: New module containing the part of llds_out.m that generates global static C data structures. compiler/llds_out_instr.m: New module containing the part of llds_out.m that outputs instructions compiler/llds_out_file.m: New module containing the top level part of llds_out.m, which coordinates the generation of a whole C source file. compiler/llds_out_util.m: New module containing the utility parts of llds_out.m. compiler/llds_out.m: Replace everything in this file with just the includes of the submodules that now have all its previous contents. compiler/hlds_llds.m: Move a predicate here from llds_out.m, since it is a utility predicate operating on a type defined here. compiler/rtti_out.m: Move a predicate here from llds_out.m, since it is a predicate generating output from a rtti type. compiler/hlds_out_mode.m: The part of hlds_out.m that deals with writing out insts and modes. compiler/hlds_out_goal.m: The part of hlds_out.m that deals with writing out goals. compiler/hlds_out_pred.m: The part of hlds_out.m that deals with writing out predicates and procedures. compiler/hlds_out_module.m: The part of hlds_out.m that deals with writing out module-wide tables. compiler/hlds_out_util.m: Parts of hlds_out.m that don't fit in anywhere else. compiler/hlds_out.m: Replace everything in this file with just the includes of the submodules that now have all its previous contents. compiler/simplify.m: compiler/hlds_goal.m: Move some insts from simplify.m to hlds_goal.m to allow hlds_out_goal.m to use them also. compiler/coverage_profiling.m: The part of deep_profiling.m that deals with coverage profiling. compiler/deep_profiling.m: Remove the code moved to coverage_profiling.m, and export the utility predicates needed by coverage_profiling.m. Remove the things moved to prog_data.m and hlds_goal.m. Put the predicates into a more logical order. compiler/hlds_goal.m: Move some predicates here from deep_profiling.m, since they belong here. compiler/prog_data.m: Move a type from deep_profiling.m here, since it belongs here. compiler/add_pragma.m: Add a predicate from llds_out.m that is used only here. compiler/*.m: Conform to the changes above. |
||
|
|
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. |
||
|
|
a37c4f3b75 |
Avoid a linking problem that can occur when using structure reuse and
Branches: main Avoid a linking problem that can occur when using structure reuse and `--intermodule-analysis'. When making an `.analysis' we may find that a procedure has conditional reuse, but when making the target code we may find that procedure has unconditional or no reuse. If another module calls the conditional reuse version of the procedure, which doesn't exist, that would lead to a linking error. The solution is to produce a fake conditional reuse procedure which forwards to the unconditional/no-reuse procedure if we detect this situation. We already did that when using `--intermodule-optimisation'. compiler/structure_reuse.analysis.m: As above. |
||
|
|
0d10146979 |
Memoise type_contains_subtype. This greatly speeds up structure
Branches: main compiler/ctgc.selector.m: Memoise type_contains_subtype. This greatly speeds up structure sharing/reuse analysis on some modules. Add a predicate to reset the memo table. Add a comment. compiler/structure_reuse.analysis.m: compiler/structure_sharing.analysis.m: Reset the memo table after these analyses. |
||
|
|
04608b04e7 |
In structure sharing and structure reuse analyses, we weren't renaming
Branches: main In structure sharing and structure reuse analyses, we weren't renaming variables from imported `sharing_as' and `reuse_as' structures to match the variable names used in the current compiler run. It was only by luck if a particular variable number referred to the same thing in an imported answer as in the procedure being analysed. We *were* doing it for `--transitive-' and `--intermodule-optimisation' but not for `--intermodule-analysis'. compiler/structure_reuse.analysis.m: compiler/structure_sharing.analysis.m: Change structure sharing and reuse answers to store `structure_sharing_domain', `structure_reuse_domain' structures instead of `sharing_as' and `reuse_as' structures. Rename the variables from imported answers. Bump analysis versions. compiler/structure_sharing.domain.m: Hide `sharing_as' again as we no longer need it outside this module. tests/analysis/ctgc/reuse_runtest.sh: Update test cases for changed answer formats. |
||
|
|
1339110d8d |
Fix a problem with intermodule analysis and structure reuse analysis.
Branches: main Fix a problem with intermodule analysis and structure reuse analysis. During the `--make-analysis-registry' step we may find one set of reuse conditions for a procedure, but during the making target code step, we find a different, harsher set of reuse conditions (due to extra information being available later). We cannot generate code which would violate the weaker conditions presented in the analysis file, as calls from external modules may satisfy the weaker conditions but not the stronger conditions. The same problem occurs with --transitive- and `--intermodule-optimisation'. compiler/structure_reuse.versions.m: compiler/structure_reuse.analysis.m: Fix the problem above. compiler/structure_reuse.domain.m: Improve reverse lookups for a field in the reuse_as_table. compiler/structure_reuse.indirect.m: Conform to reuse_as_table change. |
||
|
|
a00596c283 |
The file modules.m contains lots of different kinds of functionality.
Estimated hours taken: 16 Branches: main The file modules.m contains lots of different kinds of functionality. While much of it belongs together, much of it does not. This diff moves most of the functionality that does not belong with the rest to several new modules: libs.file_util parse_tree.deps_map parse_tree.file_names parse_tree.module_cmds parse_tree.module_imports parse_tree.read_module parse_tree.write_deps_file To make them coherent, move some predicates from hlds.passes_aux, parse_tree.prog_io and parse_tree.prog_out to the new modules, making them more accessible, reducing the required access from the hlds package to parse_tree, or from the parse_tree package to libs. In the same spirit, this diff also moves some simple predicates and functions dealing with sym_names from prog_util.m to mdbcomp/prim_data.m. This allows several modules to avoid depending on parse_tree.prog_util. Rename some of the moved predicates and function symbols where this avoids ambiguity. (There were several that differed from other predicates or function symbols only in arity.) Replace several uses of bools with purpose-specific types. This makes some of the code significantly easier to read. This diff moves modules.m from being by far the largest module, to being only the seventh largest, from 8900+ lines to just 4200+. It also reduces the number of modules that import parse_tree.modules considerably; most modules that imported it now import only one or two of the new modules instead. Despite the size of the diff, there should be no algorithmic changes. compiler/modules.m: compiler/passes_aux.m: compiler/prog_io.m: compiler/prog_out.m: Delete the moved functionality. compiler/file_util.m: New module in the libs package. Its predicates search for files and do simple error or progress reporting. compiler/file_names.m: New module in the parse_tree package. It contains predicates for converting module names to file names. compiler/module_cmds.m: New module in the parse_tree package. Its predicates handle the commands for manipulating interface files of various kinds. compiler/module_import.m: New module in the parse_tree package. It contains the module_imports type and its access predicates, and the predicates that compute various sorts of direct dependencies (those caused by imports) between modules. compiler/deps_map.m: New module in the parse_tree package. It contains the data structure for recording indirect dependencies between modules, and the predicates for creating it. compiler/read_module.m: New module in the parse_tree package. Its job is reading in modules, both human-written and machine-written (such as interface and optimization files). compiler/write_deps_file.m: New module in the parse_tree package. Its job is writing out makefile fragments. compiler/libs.m: compiler/parse_tree.m: Include the new modules. compiler/notes/compiler_design.m: Document the new modules. mdbcomp/prim_data.m: compiler/prog_util.m: Move the predicates that operate on nothing but sym_names from prog_util to prim_data. Move get_ancestors from modules to prim_data. compiler/prog_item.m: Move stuff that looks for foreign code in a list of items here from modules.m. compiler/source_file_map.m: Note why this module needs to be in the parse_tree package. compiler/add_pred.m: compiler/add_special_pred.m: compiler/analysis.file.m: compiler/analysis.m: compiler/assertion.m: compiler/check_typeclass.m: compiler/compile_target_code.m: compiler/cse_detection.m: compiler/det_analysis.m: compiler/elds_to_erlang.m: compiler/exception_analysis.m: compiler/export.m: compiler/fact_table.m: compiler/higher_order.m: compiler/hlds_module.m: compiler/hlds_pred.m: compiler/intermod.m: compiler/llds_out.m: compiler/make.dependencies.m: compiler/make.m: compiler/make.module_dep_file.m: compiler/make.module_target.m: compiler/make.program_target.m: compiler/make.util.m: compiler/make_hlds_passes.m: compiler/maybe_mlds_to_gcc.pp: compiler/mercury_compile.m: compiler/mlds.m: compiler/mlds_to_c.m: compiler/mlds_to_gcc.m: compiler/mlds_to_ilasm.m: compiler/mlds_to_java.m: compiler/mmc_analysis.m: compiler/mode_constraints.m: compiler/mode_debug.m: compiler/modes.m: compiler/module_qual.m: compiler/optimize.m: compiler/passes_aux.m: compiler/proc_gen.m: compiler/prog_foreign.m: compiler/prog_io.m: compiler/prog_io_util.m: compiler/prog_mutable.m: compiler/prog_out.m: compiler/pseudo_type_info.m: compiler/purity.m: compiler/recompilation.check.m: compiler/recompilation.usage.m: compiler/simplify.m: compiler/structure_reuse.analysis.m: compiler/structure_reuse.direct.detect_garbage.m: compiler/structure_reuse.direct.m: compiler/structure_sharing.analysis.m: compiler/tabling_analysis.m: compiler/term_constr_main.m: compiler/termination.m: compiler/trailing_analysis.m: compiler/trans_opt.m: compiler/type_util.m: compiler/typecheck.m: compiler/typecheck_info.m: compiler/unify_proc.m: compiler/unused_args.m: compiler/unused_imports.m: compiler/xml_documentation.m: Minor changes to conform to the changes above. |
||
|
|
36b7bd4ea0 |
Store call and answer patterns as terms in `.analysis' (and related) files and
Branches: main Store call and answer patterns as terms in `.analysis' (and related) files and not strings. It's easier to convert complex patterns to/from terms than strings. Also change the module names and function-ids while we're at it. compiler/analysis.m: Replace the `to_string' typeclass with a `to_term' typeclass. Make call and answer patterns convert to/from terms instead of strings. compiler/analysis.file.m: Read/write terms for call and answer patterns. Read/write module names and function-ids with more natural syntax than the term representations of internal data structures. Bump the analysis file version number. Move some code around. Use promise_equivalent_solutions goals instead of promise_equivalent_solution_io. compiler/exception_analysis.m: compiler/structure_reuse.analysis.m: compiler/structure_sharing.analysis.m: compiler/tabling_analysis.m: compiler/trailing_analysis.m: compiler/unused_args.m: Conform to `to_term' typeclass interface. tests/analysis/ctgc/reuse_runtest.sh: tests/analysis/excp/excp_runtest.sh: tests/analysis/sharing/sharing_runtest.sh: tests/analysis/unused_args/unused_args_runtest.sh: Update test scripts for changed file formats. compiler/mercury_compile.m: Print verbose messages and report stats when reading in files for intermodule analysis. |
||
|
|
6eab527191 |
More changes to the intermodule analysis framework.
Branches: main More changes to the intermodule analysis framework. This patch mainly deals with incorrect treatment of :- external procedures, opt_imported procedures, and forcing the correct reanalyses when answers change or requests are satisfied. - Previously, the way to ensure that a module M is reanalysed if a request in module N is satisfied was, while analysing M: assume an answer for the procedure in N; record that as a result in N; and record that M has a dependency on that answer. When N is analysed, if the real answer is better than the assumed answer, M would be marked `suboptimal' and later reanalysed. That's complicated and wasn't always done correctly. Now we remember the module which makes a request. When the request is satisfied, we mark the requesting module as `suboptimal'. This also means the `.analysis' file of a module will only be modified when analysing that module and no others, which should be useful for parallel builds. - In most analyses we weren't recording results for exported `:- external' procedures as we don't have their clauses and don't analyse them. Other modules would happily make requests for `:- external' procedures, which would never be satisfied. - We shouldn't make intermodule requests for `opt_imported' procedures as we actually have their clauses. Even if the request is satisfied, we'd probably not look them up since we do have their clauses. - If a module M opt_imports a procedure P from module N (its clauses are available while analysing M) then M also needs to depend on any answers required by P. Otherwise a change to an answer required by P won't cause M to be reanalysed. - There doesn't seem to be any reason to keep track of the analysis status of individual results. If an answer changes requiring another module to be reanalysed, the *whole module* will be marked suboptimal or invalid. And if that results in changed answers, its dependant modules will be marked. This patch doesn't remove the status of individual results but makes them always `optimal'. compiler/analysis.m: Remember the name of the module being analysed in the analysis_info. Simplify some predicate interfaces with this information. Remember whether we're currently making an analysis file or just reading from them. Make the record_* predicates do nothing in the latter case, so the caller doesn't need to check. Also make the record predicates do the right thing if the callee module is non-local, e.g. don't make requests to non-local modules. Automatically add a request if depending on a result that doesn't exist. Add a procedure to return the existing call patterns for a procedure, regardless of whether the module has been marked `invalid'. Add some assertions to check the analysis framework is being used as intended. Minor cleanups. compiler/analysis.file.m: Record the module that made the request in `.request' files. Bump the analysis file version number. compiler/hlds_module.m: Pass extra arguments to `init_analysis_info'. compiler/hlds_pred.m: Add `pred_info_is_imported_not_external' which doesn't succeed on `:- external' procedures (defined in the current module), unlike `pred_info_is_imported'. compiler/exception_analysis.m: compiler/tabling_analysis.m: compiler/trailing_analysis.m: compiler/unused_args.m: Record results for `:- external' procedures. Don't look up results for our own `:- external' procedures from the analysis registry. In general, fix many spots where external procs would be treated as imported. Write out results for procedures which are exported to submodules. Conform to analysis framework changes. Remove some redundant checks which have been moved into the framework. compiler/mercury_compile.m: Conform to analysis framework changes. compiler/structure_reuse.analysis.m: Be careful not to read in requests and call patterns for `opt_imported' procedures as if they were defined in the current module. If depending on an answer that doesn't exist, also make a request for that answer. Conform to analysis framework changes. Write out messages when removing useless reuse version procedures. compiler/structure_reuse.indirect.m: Use `pred_info_is_imported_not_external' so as not to look up results for our own `:- external' procedures from the analysis registry. Treat `opt_imported' procedures as intra-module as far as requests are concerned. We need to satisfy requests for them in the current compiler invocation rather than when analysing imported modules. compiler/structure_sharing.analysis.m: Fix treatment of `:- external' procedures. Conform to analysis framework changes. compiler/structure_sharing.domain.m: Don't return suboptimal when unable to look up a result. compiler/mmc_analysis.m: Replace pred_or_func_name_arity_to_func_id by a higher-level predicate. tests/Mmakefile: tests/analysis/Mmakefile: tests/analysis/common.sh: tests/analysis/excp/Mercury.options: tests/analysis/excp/Mmakefile: tests/analysis/excp/excp_m1.m.exception: tests/analysis/excp/excp_m1.m.no_exception: tests/analysis/excp/excp_m2.m: tests/analysis/excp/excp_m3.m: tests/analysis/excp/excp_runtest.sh: tests/analysis/ext/Mercury.options: tests/analysis/ext/Mmakefile: tests/analysis/ext/ext.m: tests/analysis/ext/ext2.m: tests/analysis/ext/ext2_runtest.sh: tests/analysis/ext/ext_runtest.sh: tests/analysis/sharing/Mercury.options: tests/analysis/sharing/Mmakefile: tests/analysis/sharing/sharing_m1.m.no_share: tests/analysis/sharing/sharing_m1.m.share: tests/analysis/sharing/sharing_m2.m: tests/analysis/sharing/sharing_m3.m: tests/analysis/sharing/sharing_runtest.sh: tests/analysis/table/Mercury.options: tests/analysis/table/Mmakefile: tests/analysis/table/table_m1.m.no_tabling: tests/analysis/table/table_m1.m.tabling: tests/analysis/table/table_m2.m: tests/analysis/table/table_m3.m: tests/analysis/table/table_runtest.sh: tests/analysis/trail/Mercury.options: tests/analysis/trail/Mmakefile: tests/analysis/trail/trail_m1.m.no_trail: tests/analysis/trail/trail_m1.m.trail: tests/analysis/trail/trail_m2.m: tests/analysis/trail/trail_m3.m: tests/analysis/trail/trail_runtest.sh: tests/analysis/unused_args/Mercury.options: tests/analysis/unused_args/Mmakefile: tests/analysis/unused_args/ua_m1.m.no_unused_args: tests/analysis/unused_args/ua_m1.m.unused_args: tests/analysis/unused_args/ua_m2.m: tests/analysis/unused_args/ua_m3.m: tests/analysis/unused_args/unused_args_runtest.sh: Add test cases. |
||
|
|
470fc542e7 |
Add initial support for performing call-specific structure reuse analysis.
Branches: main Add initial support for performing call-specific structure reuse analysis. If a call site violates the conditions for calling the reuse version of a procedure, it can request a different reuse version of the procedure with possibly laxer reuse conditions. At least for now, I have chosen call patterns to simply be lists of argument positions, the arguments which cannot be clobbered by the callee. Requests across module boundaries are supported when using the `--intermodule-analysis' option. This initial version does a lot of unnecessary reanalysis so must be switched on explicitly with a `--structure-reuse-repeat <n>' option. This option shouldn't be needed in the future. compiler/options.m: Add a `--structure-reuse-repeat <n>' option. compiler/analysis.m: compiler/mercury_compile.m: Read in the `.request' file for the current module being analysed when we're preparing to use the intermodule analysis framework. Don't return duplicates when looking up analysis requests. compiler/structure_reuse.analysis.m: Read in old reuse analysis answers and new requests when using `--intermodule-analysis'. Make procedures corresponding to old Answers (as expected by other modules) and new requests (so we analyse the procedures with the requested call patterns). When `--structure-reuse-repeat' is used, use the requests from the latest indirect reuse pass to create new reuse procedures with the extra constraints on some of the head variables (that they must not be clobbered). Perform direct reuse analysis on those procedures, then repeat indirect reuse on the whole module so those new procedures might be called. Record intermodule requests when using `--intermodule-analysis'. Delete reuse versions of procedures we may have created, which after analysis turn out to have no reuse opportunities at all. compiler/structure_reuse.lfu.m: Add a procedure that adds a set of variables to all the local-forward-use sets of a procedure. compiler/structure_reuse.direct.m: Add code to perform direct reuse on a specific list of procedures instead of all the procedures in a module. compiler/structure_reuse.indirect.m: Add code to re-run indirect reuse analysis which when analysing an SCC also analyses the reuse versions of procedures that were created from the procedures in the SCC. Remember and return intra- and inter-module requests when existing reuse procedures can't be called, for later passes and for later analyses of other modules. When looking up reuse information for a procedure, if we don't have that information we should take that assumed result is `optimal'. Otherwise, the analysis results of mutually recursive procedures will never get out of the `suboptimal' state. (Other analyses make the same mistake.) compiler/structure_reuse.domain.m: Extend the `reuse_as_table' with a mapping from an original (non-reuse) procedure plus call pattern to the procedure which actually implements that reuse. Make `reuse_as_satisfied' try to return all of the variables at a call site that violate the reuse conditions. That is, instead of just giving one reason that a reuse procedure call can't be made, try to return all the reasons so we don't waste effort requesting laxer reuse procedures which wouldn't be lax enough for the call site anyway. compiler/structure_reuse.versions.m: Account for multiple reuse versions of procedures. compiler/prog_util.m: Use `make_pred_name' to make the names for reuse predicates. compiler/hlds_goal.m: compiler/hlds_out.m: Record in HLDS goals which reuse version of a procedure to call, since there can be multiple to choose from. compiler/hlds_module.m: compiler/trans_opt.m: Replace the `structure_reuse_map' field in the module structure by a simple set of pred_ids of reuse predicates. The old map from procedures to their reuse counterparts is not needed outside of the structure reuse passes, which has the same information in a separate table anyway. compiler/structure_sharing.analysis.m: Assume guessed structure sharing answers are `optimal' instead of `suboptimal', as above. compiler/structure_reuse.direct.choose_reuse.m: compiler/structure_reuse.direct.detect_garbage.m: Module import changes. |
||
|
|
d302ab27b7 |
A recent change caused (useless) structure sharing and structure reuse
Estimated hours taken: 0.5 Branches: main compiler/structure_reuse.analysis.m: compiler/structure_sharing.analysis.m: A recent change caused (useless) structure sharing and structure reuse pragmas to be written to `.trans_opt' files even when those analyses were not run. Fix that. |
||
|
|
2dffc6b4c5 |
Make the structure reuse analysis able to use the intermodule analysis
Branches: main Make the structure reuse analysis able to use the intermodule analysis framework. compiler/hlds_pred.m: Keep the analysis status with the structure reuse domain in the proc_info. compiler/hlds_out.m: Conform to the above. compiler/mmc_analysis.m: Add structure reuse to the list of analyses. compiler/structure_reuse.analysis.m: Add the usual code to interface an analysis pass with the analysis framework. Load reuse information about imported procedures from the analysis registry. Record reuse analysis results and dependencies to the analysis registry. We were not writing out results for `:- external' procedures even if they were exported; do that. Write out the results for type specialised procedures if making `.analysis' files, because we can, but not for `.opt' files, since we can't. compiler/structure_reuse.direct.m: Add reuse results for `:- external' procedures to the reuse table so that they will be written out to `.opt' and `.analysis' files. compiler/structure_reuse.domain.m: Keep the analysis status with the reuse_as in the reuse table. Change a semidet function to a predicate. compiler/structure_reuse.indirect.m: Keep track of the procedures which we depended on during the analysis. Rename AnalysisInfo to IrInfo everywhere as AnalysisInfo usually refers to the analysis_info of the intermodule analysis framework. compiler/structure_reuse.versions.m: Don't try to create reuse versions of imported procedures which may appear in the reuse table. compiler/structure_sharing.analysis.m: Write out results for `:- external' procedures. Make sure not to write out results for unify/compare predicates (although it doesn't seem to happen anyway). Write out results for type specialised procedures to `.analysis' files but not `.opt' files. compiler/structure_sharing.domain.m: Add a question to investigate later. |
||
|
|
033d854ef1 |
Various fixes for intermodule optimisation and structure reuse analysis.
Branches: main Various fixes for intermodule optimisation and structure reuse analysis. compiler/structure_reuse.analysis.m: Write `:- pragma structure_reuse' declarations when making `.opt' files. Write structure_reuse pragmas for procedures exported to submodules. Don't write structure_reuse pragmas for the reuse versions of procedures. Create forwarding procedures for procedures that, according to the .opt file, have conditional reuse versions, but when generating target code we find has no reuse. compiler/structure_reuse.versions.m: Add predicates to create forwarding procedures. Record the origin of reuse procedures as `transform_structure_reuse'. Mark reuse versions of procedures as `status_local' if the original procedure was `opt_imported' so they don't get removed by dead proc elimination. compiler/intermod.m: If structure reuse is enabled, read in a module's own `.opt' file and keep any `:- pragma structure_reuse' declarations so that we can know whether we need to create forwarding procedures. compiler/mercury_compile.m: Perform higher-order specialisation, inlining and deforestation before CTGC passes when making intermodule optimisation or analysis files. This reduces the discrepancy between the CTGC results we get while making .opt/.trans_opt files and while making .c files. compiler/ctgc.util.m: Don't abort in get_type_substitution if the caller's actual arguments don't match the callee's argument types and some compiler-generated procedures are type-incorrect. compiler/hlds_pred.m: compiler/layout_out.m: Add `transform_structure_reuse' option for `pred_transformation'. |
||
|
|
29f25e0bf2 |
Commit some simple changes accumulating in a workspaces to reduce clutter.
Branches: main Commit some simple changes accumulating in a workspaces to reduce clutter. compiler/ctgc.datastruct.m: Write datastructs_subsumed_by_list more declaratively. compiler/ctgc.util.m: Rename `preds_requiring_no_analysis' to `some_preds_requiring_no_analysis' to reflect what it does and simplify the implementation. compiler/hlds_goal.m: Use `needs_update' instead of `bool' in a spot. Update comments. compiler/quantification.m: compiler/structure_reuse.versions.m: Conform to use of `needs_update' instead of `bool'. compiler/hlds_pred.m: compiler/prog_data.m: compiler/prog_io_pragma.m: compiler/structure_reuse.direct.m: Update comments. compiler/liveness.m: Move a goal into execution order. compiler/structure_reuse.direct.detect_garbage.m: Delete an unnecessary (and overloaded) predicate. compiler/structure_reuse.analysis.m: compiler/structure_reuse.domain.m: Make the reuse information dump more readable (longer strings instead of single character codes, names instead of ids). compiler/structure_reuse.indirect.m: Use `map.apply_to_list' instead of higher order calls. Use readable strings for fixpoint table short descriptions. compiler/structure_sharing.analysis.m: Rename some variables. Use `map.apply_to_list' instead of higher order calls. compiler/trans_opt.m: Use `assoc_list.keys' instead of higher order calls. compiler/type_util.m: Fix typo. |
||
|
|
27aaaf412c |
Fix the failure of the invalid/modes_erroneous test case, whose symptom was
Estimated hours taken: 5 Branches: main Fix the failure of the invalid/modes_erroneous test case, whose symptom was an error message about a "mode error in unification of `X' and `X'". The root cause of the problem was that the renaming of head variables computed by headvar_names.m was being applied too early, during typechecking. The fix is to apply it after the frontend (all the passes that can generate error messages). To avoid slowdowns from larger pred_infos, this diff also moves the least frequently used fields of pred_infos to a subterm. (Proc_infos already had a subterm.) This leads to an almost 3% speedup. compiler/headvar_names.m: Store the renaming instead of applying it. compiler/simplify.m: Apply the renaming in invocations after the front end, since doing so may allow some excess assignments to be eliminated. compiler/hlds_pred.m: Add fields to pred_infos and proc_infos for the renaming. Move the least frequently used fields of pred_infos into a pred_sub_info. Some fields of pred_infos were being accessed using predicates that did not follow our naming conventions, and some were accessed using field access functions that are now inappropriate; fix them all. Require the caller to provide the renaming when creating new pred_infos and proc_infos. This is to force the compiler components that do this to propagate the renaming fields of the original predicates and/or procedures to their modified versions. Convert that some old code that used if-then-elses to use switches instead. compiler/hlds_out.m: Write out the new pred_info and proc_info fields. compiler/*.m: Conform to the changes in hlds_pred.m. compiler/hlds_clauses.m: Avoid ambiguity by giving a prefix to the fields of the clauses_info type. tests/invalid/ho_type_mode_bug.err_exp: tests/invalid/merge_ground_any.err_exp: Don't expect error messages about "X = X" anymore. |
||
|
|
b56885be93 |
Fix a bug that caused bootchecks with --optimize-constructor-last-call to fail.
Estimated hours taken: 12 Branches: main Fix a bug that caused bootchecks with --optimize-constructor-last-call to fail. The problem was not in lco.m, but in follow_code.m. In some cases, (specifically, the LCMC version of insert_2 in sparse_bitset.m), follow_code.m moved an impure goal (store_at_ref) into the arms of an if-then-else without marking those arms, or the if-then-else, as impure. The next pass, simplify, then deleted the entire if-then-else, since it had no outputs. (The store_at_ref that originally appeared after the if-then-else was the only consumer of its only output.) The fix is to get follow_code.m to make branched control structures such as if-then-elses, as well as their arms, semipure or impure if a goal being moved into them is semipure or impure, or if they came from an semipure or impure conjunction. Improve the optimization of the LCMC version of sparse_bitset.insert_2, which had a foreign_proc invocation of bits_per_int in it: replace such invocations with a unification of the bits_per_int constant if not cross compiling. Add a new option, --optimize-constructor-last-call-null. When set, LCMC will assign NULLs to the fields not yet filled in, to avoid any junk happens to be there from being followed by the garbage collector's mark phase. This diff also makes several other changes that helped me to track down the bug above. compiler/follow_code.m: Make the fix described above. Delete all the provisions for --prev-code; it won't be implemented. Don't export a predicate that is not now used anywhere else. compiler/simplify.m: Make the optimization described above. compiler/lco.m: Make sure that the LCMC specialized procedure is a predicate, not a function: having a function with the mode LCMC_insert_2(in, in) = in looks wrong. To avoid name collisions when a function and a predicate with the same name and arity have LCMC applied to them, include the predicate vs function status of the original procedure included in the name of the new procedure. Update the sym_name of calls to LCMC variants, not just the pred_id, because without that, the HLDS dump looks misleading. compiler/pred_table.m: Don't have optimizations like LCMC insert new predicates at the front of the list of predicates. Maintain the list of predicates in the module as a two part list, to allow efficient addition of new pred_ids at the (logical) end without using O(N^2) algorithms. Having predicates in chronological order makes it easier to look at HLDS dumps and .c files. compiler/hlds_module.m: Make module_info_predids return a module_info that is physically updated though logically unchanged. compiler/options.m: Add --optimize-constructor-last-call-null. Make the options --dump-hlds-pred-id, --debug-opt-pred-id and --debug-opt-pred-name into accumulating options, to allow the user to specify more than one predicate to be dumped (e.g. insert_2 and its LCMC variant). Delete --prev-code. doc/user_guide.texi: Document the changes in options.m. compiler/code_info.m: Record the value of --optimize-constructor-last-call-null in the code_info, to avoid lookup at every cell construction. compiler/unify_gen.m: compiler/var_locn.m: When deciding whether a cell can be static or not, make sure that we never make static a cell that has some fields initialized with dummy zeros, to be filled in for real later. compiler/hlds_out.m: For goals that are semipure or impure, note this fact. This info was lost when I changed the representation of impurity from markers to a field. mdbcomp/prim_data.m: Rename some ambiguous function symbols. compiler/intermod.m: compiler/trans_opt.m: Rename the main predicates (and some function symbols) of these modules to avoid ambiguity and to make them more expressive. compiler/llds.m: Don't print line numbers for foreign_code fragments if the user has specified --no-line-numbers. compiler/make.dependencies.m: compiler/mercury_to_mercury.m: compiler/recompilation.usage.m: Don't use io.write to write out information to files we may need to parse again, because this is vulnerable to changes to the names of function symbols (e.g. the one to mdbcomp/prim_data.m). The compiler still contains some uses of io.write, but they are for debugging. I added an item to the todo list of the one exception, ilasm.m. compiler/recompilation.m: Rename a misleading function symbol name. compiler/parse_tree.m: Don't import recompilation.m here. It is not needed (all the components of parse_tree that need recompilation.m already import it themselves), and deleting the import avoids recompiling almost everything when recompilation.m changes. compiler/*.m: Conform to the changes above. compiler/*.m: browser/*.m: slice/*.m: Conform to the change to mdbcomp. library/sparse_bitset.m: Use some better variable names. |
||
|
|
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. |
||
|
|
2b2f3d3cbe |
This diff contains no algorithmic changes.
Estimated hours taken: 8 Branches: main This diff contains no algorithmic changes. It merely renames apart a bunch of function symbols to reduce ambiguity. Basically I went through prog_data.m, prog_item.m, hlds_data.m, hlds_goal.m and hlds_pred.m looking for type definitions containing function symbol names that were either language "keywords" (e.g. "terminates", which is an annotation on foreign_procs), used with slightly different meanings in several types (e.g. "sym"), or both (e.g. "call"). When I found such type definitions, I changed the names of the function symbols, usually by adding a prefix or suffix indicating the type to all function symbols of the type. For example, the old function symbol "foreign_proc" in type "pragma_type" is now named "pragma_foreign_proc", and the names of all other function symbols in that type also start with "pragma_". All of this should yield simpler compiler error messages when we make mistakes, and will make it more likely that looking up a function symbol using a tags file will take you to the actual definition of the relevant instance of that function symbol. However, the most important benefit is the increase in the readability of unfamiliar code; the reader won't have to emulate the compiler's type ambiguity resolution algorithm (which in many cases used to require distinguishing between f/14 and f/15 by counting the arguments, e.g. for "pred_or_func"). compiler/prog_data.m: compiler/prog_item.m: compiler/hlds_data.m: compiler/hlds_goal.m: compiler/hlds_pred.m: Rename function symbols as explained above. compiler/*.m: Conform to the function symbol renames. In some cases, rename other function symbols as well. Minor style fixes, e.g. replace if-then-elses with switches, or simple det predicates with functions. |
||
|
|
aeeedd2c13 |
Standardize formatting of comments at the beginning of modules.
compiler/*.m: Standardize formatting of comments at the beginning of modules. |
||
|
|
3e88907653 |
Create optimised versions for all the procedures for which possibilities for
Estimated hours taken: 20 Branches: main Create optimised versions for all the procedures for which possibilities for structure reuse are detected. Put the mechanism in place to generate reuse pragmas, and to parse them back in. compiler/add_pragma.m: compiler/structure_sharing.analysis.m: compiler/hlds_pred.m: Postpone the processing (renaming) of structure sharing pragmas until the beginning of the actual structure sharing analysis. compiler/add_pragma.m: compiler/hlds_pred.m: compiler/make_hlds_passes.m: compiler/mercury_to_mercury.m: compiler/prog_ctgc.m: compiler/prog_io_pragma.m: compiler/trans_opt.m: Add the mechanism to output and parse the structure_reuse pragmas. (Remove the name of the reuse-version procedures in the pragma structure_reuse). compiler/hlds_module.m: Simplify the type structure_reuse_info. compiler/prog_data.m: Add types for the public representation of reuse conditions. (remove the previous name "reuse_tuple", which simply does not sound adequate). compiler/module_qual.m: compiler/modules.m: compiler/prog_item.m: compiler/recompilation.version.m: Remove the name of the reuse-version procedures in the pragma structure_reuse. compiler/prog_type.m: compiler/structure_reuse.lbu.m: compiler/structure_reuse.lfu.m: Add functions to remove all typeinfo-vars from a given list (resp. set) of vars. These functions are used when deriving the variables in local and forward use, where typeinfo-variables are irrelevant. compiler/structure_reuse.analysis.m: compiler/structure_reuse.versions.m: compiler/structure_reuse.m: Process the reuse information of any imported procedures. Create optimised versions for the procedures for which reuse was detected. (structure_reuse.versions.m = new file) compiler/structure_reuse.domain.m: Conversion procedures between the public and private representation for structure reuse conditions. compiler/structure_reuse.indirect.m: Do not try to replace call information even when you know the pred_proc_id of the reuse version of that call (which is the case for imported procedures with reuse). It is more consistent to do this at the same time when all the other conversions are done, i.e. when generating the optimised versions of the procedures with reuse (even with unconditional reuse). |
||
|
|
f5de906db6 |
Minor style cleanups for the CTGC system. There are no changes to any
Estimated hours taken: 1 Branches: main Minor style cleanups for the CTGC system. There are no changes to any algorithms. compiler/ctgc.*.m: compiler/prog_ctgc.m: compiler/structure_reuse.*.m: compiler/structure_sharing.*.m: Minor style cleanups. compiler/builtin_ops.m: compiler/check_hlds.m: compiler/exception_analysis.m: compiler/hlds_rtti.m: compiler/process_util.m: s/__/./ in a couple of spots and fix a few other formatting problems. |
||
|
|
c3e7b34393 |
Provide the indirect reuse analysis part of the CTGC system.
Estimated hours taken: 12 Branches: main Provide the indirect reuse analysis part of the CTGC system. Using a fixpoint computation, this propagates the reuse conditions determined by the direct reuse analysis step through procedure calls. compiler/ctgc.datastruct.m: Minor additions. compiler/ctgc.livedata.m: (new file) Types and operations needed for defining the lattice of possibly live datastructures. compiler/ctgc.m: Add livedata submodule. compiler/ctgc.util.m: Provide the operations for determining variable and type renamings, used both by the structure sharing analysis as well as the reuse analysis. compiler/hlds_module.m: Add structure reuse information to collect the mapping between procedures, and their reuse versions. compiler/prog_data.m: New types "dead_vars", "live_vars". compiler/structure_reuse.analysis.m: Add the indirect reuse analysis step. compiler/structure_reuse.direct.detect_garbage.m: compiler/structure_sharing.domain.m: Mainly moving the operation of looking up sharing information and combining it with existing sharing to a more appropriate place, namely structure_sharing.domain.m (also rename the bottom and top elements of the structure sharing domain). compiler/structure_reuse.domain.m: Add a renaming operation but especially two predicates needed to verify whether a given procedure call satisfies the derived reuse conditions, and to translate these reuse conditions to the head variables of the procedure in which the procedure call occurs. compiler/structure_reuse.indirect.m: The actual indirect reuse analysis. compiler/structure_reuse.m: Add "structure_reuse.indirect" as a submodule. compiler/structure_sharing.analysis.m: small changes. |
||
|
|
d3e5a8eda4 |
Provide the direct reuse analysis part of the structure reuse analysis (which
Estimated hours taken: 25 Branches: main Provide the direct reuse analysis part of the structure reuse analysis (which itself is part of the CTGC system). compiler/ctgc.datastruct.m: compiler/ctgc.util.m: Additional predicates. compiler/ctgc.m: Add structure reuse module. compiler/handle_options.m: compiler/options.m: Add new options "structure_reuse_analysis" and related ones. compiler/handle_options.m: compiler/hlds_out.m: Add dump option "R" to dump structure reuse related information in the hlds_dump files. compiler/hlds_goal.m: Types to record structure reuse information at the level of each goal. Additional "case_get_goal" function to extract the goal from an case. compiler/mercury_compile.m: Add structure reuse analysis as a new compiler stage. compiler/structure_reuse.analysis.m: The top level analysis predicates. compiler/structure_reuse.direct.m: compiler/structure_reuse.direct.choose_reuse.m: compiler/structure_reuse.direct.detect_garbage.m: Direct reuse analysis is split into 2 steps: determining when and how data structures become garbage, and then choosing how these dead data structures might best be reused. compiler/structure_reuse.domain.m: The abstract domain for keeping track of reuse conditions, the main domain in the structure reuse analysis. compiler/structure_reuse.lbu.m: compiler/structure_reuse.lfu.m: To determine whether data structures become dead or not, one needs to know which variables in a goal are needed with respect to forward execution (lfu = local forward use), and backward execution, i.e. backtracking (lbu = local backward use). These two modules provide the necessary functionality to pre-annotate the goals with lfu and lbu information. compiler/structure_sharing.analysis.m: compiler/structure_sharing.domain.m: Remove the structure sharing table from the interface of the analysis predicate in structure_sharing.analysis.m; Move predicates to structure_sharing.domain.m so that they become more easily accessible for the structure_reuse modules. compiler/prog_data.m: New types "dead_var", "live_var" and alike. |