mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-18 15:26:31 +00:00
cdf9ccf352049af16824810a403be67a69f11c0b
10 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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. |
||
|
|
b816836f02 |
Optimize away stack slots storing dummy values; values of the io__state and
Estimated hours taken: 8
Branches: main
Optimize away stack slots storing dummy values; values of the io__state and
store__store types.
compiler/stack_alloc.m:
Allocate distinct negative stack slot numbers to values of dummy types.
We need
compiler/hlds_pred.m:
Add a predicate for testing whether a value is of a dummy type.
compiler/code_into.m:
When constructing the list of live locations after a call, do not
include the negative stack slots containing dummy values. The list
of live locations is used by the (future) native collector, which
should ignore dummy types, and by the debugger. The debugger can't
do anything with these dummy values on the stack except tell the
user about their existence, which doesn't do the debugger user any
good.
We still keep liveness information about dummy values in registers
at calls and returns, since both the procedural and declarative
debuggers need to know procedures' full argument lists.
With respect to the list of live locations before the call, which
was used only by the (now extinct) value numbering optimization,
filter out all dummy types, since their values need not be preserved.
compiler/trace.m:
Do not ask the code generator to preserve values of dummy types,
since doing so would require referring to negative stack slots.
compiler/unify_gen.m:
compiler/var_locn.m:
Fix a couple of situations in which we could refer to the negative
stack slots we now allocate to dummy values.
compiler/call_gen.m:
Reorder some code to make the source match what happens at runtime.
compiler/llds_out.m:
Fix the formatting of the sanity check for negative stack slots.
compiler/handle_options.m:
Since the --debug-opt-pred-id option is useless without --debug-opt,
make --debug-opt-pred-id option imply --debug-opt. This was useful
in debugging this diff.
trace/mercury_trace.c:
Adapt the test for whether a retry is across I/O. We used to base the
test on whether the retried predicate has any I/O state arguments,
and if so, whether the original I/O state variable is still around
on the stack. After this change, the answer to the second half of
that question would always be "no", so we now use only the first half:
whether the retried predicate has any I/O state arguments. This
requires us to consider more retries to be retries across I/O, but
from the point of view of a user who may not remember whether the I/O
predicate has done any I/O so far or not, is arguably more consistent
than our previous policy.
Allow retries even if a value of type store.store is missing, since
store.store is a dummy type just as io.state is.
trace/mercury_trace.c:
compiler/type_util.m:
Document the fact that you need to update both these files if you
want to modify the set of dummy types.
tests/debugger/retry.{inp,exp,exp2}:
Due to the change in mercury_trace.c, one retry in this test case
changes to being retry over I/O. Update the test input to force this
retry over I/O, and expect the expanded input to be echoed in the
output.
tests/debugger/nondet_stack.{exp,exp2}:
Update these expected outputs to account for the fact that we now need
fewer stack slots to hold old I/O states when debugging is enabled.
|
||
|
|
d332038ee1 |
Bring these modules up to date with our coding guidelines.
Estimated hours taken: 16 Branches: main compiler/aditi_builtin_ops.m: compiler/bytecode.m: compiler/bytecode_backend.m: compiler/bytecode_gen.m: compiler/c_util.m: compiler/code_gen.m: compiler/deep_profiling.m: compiler/deforest.m: compiler/dependency_graph.m: compiler/fact_table.m: compiler/follow_code.m: compiler/handle_options.m: compiler/hlds_out.m: compiler/il_peephole.m: compiler/ilasm.m: compiler/java_util.m: compiler/liveness.m: compiler/magic.m: compiler/magic_util.m: compiler/make.dependencies.m: compiler/make.m: compiler/make.module_dep_file.m: compiler/make.program_target.m: compiler/make.util.m: compiler/matching.m: compiler/name_mangle.m: compiler/opt_debug.m: compiler/opt_util.m: compiler/options.m: compiler/options_file.m: compiler/prog_io.m: compiler/rtti_out.m: compiler/rtti_to_mlds.m: compiler/saved_vars.m: compiler/source_file_map.m: compiler/stack_alloc.m: compiler/stack_layout.m: compiler/stratify.m: compiler/switch_detection.m: compiler/term_errors.m: compiler/type_ctor_info.m: compiler/unify_proc.m: compiler/unique_modes.m: Bring these modules up to date with our coding guidelines. Use predmode syntax for declarations. Use state variable syntax where appropriate, and reorder arguments where this is needed for the use of state variable syntax. Remove module qualification from the names of defined predicates when the module qualification was used inconsistently (causing problems for the use of tags) or was causing problems with indentation. There are no changes in algorithms. |
||
|
|
bd1ea24cc3 |
Remove the dependence of this module on ll_backend.llds by defining
Estimated hours taken: 6 Branches: main compiler/hlds_llds.m: Remove the dependence of this module on ll_backend.llds by defining types using abstract descriptions of LLDS storage locations. These have the added advantage that they express the intent of the affected data structures more directly. For example, the stack slot type used to be able to map a variable to a register or to a field of a cell on the heap, which doesn't make sense. This is no longer the case. The cost of the conversion operations now required is partly paid for by our new ability to avoid some old sanity checks. compiler/llds.m: compiler/code_util.m: Add some utility predicates to operate on the new data structures. compiler/code_aux.m: compiler/code_gen.m: compiler/code_info.m: compiler/continuation_info.m: compiler/follow_vars.m: compiler/lookup_switch.m: compiler/par_conj_gen.m: compiler/stack_alloc.m: compiler/store_alloc.m: compiler/var_locn.m: Conform to the changes in hlds_llds.m. In some cases, improve the style of the affected predicates, e.g. by introducing state variable syntax. compiler/hlds_out.m: Conform to the changes in hlds_llds.m, and avoid importing ll_backend. |
||
|
|
5d6fd3bd6f |
Reduce the dependence of earlier parts of the compiler on the later ones.
Estimated hours taken: 4 Branches: main Reduce the dependence of earlier parts of the compiler on the later ones. Unnecessary import_module declarations in top level modules such as hlds.m cause unnecessary recompilations when adding new types in later modules, such as submodules of ll_backend.m. This change reduces the number of such unnecessary imports. There are no changes in algorithms, only functionality being moved around. compiler/code_model.m: Change this module from being a submodule of backend_libs.m to being a submodule of hlds.m, since nothing in it is dependent on any backend. compiler/arg_info.m: compiler/code_util.m: Change arg_info.m from being a submodule of ll_backend.m to being a submodule of hlds.m, since most of it is applicable to all current and foreseeable backends. Move the one exported predicate that is ll_backend dependent, and its support predicates, to code_util.m. compiler/backend_libs.m: compiler/ll_backend.m: compiler/hlds.m: Update include_module declarations in accordance with the above. compiler/prog_data.m: compiler/term_util.m: Instead of defining two separate types for holding argument size and termination information, one including HLDS-specific information (in term_util.m) and one not (in prog_data.m), use a polymorphic type defined in prog_data.m and two monomorphic instances. compiler/termination.m: compiler/mercury_to_mercury.m: Change the predicates for writing out argument size and termination information to handle the polymorphic type (we don't need special handling of the monomorphic versions), and move them from termination.m to mercury_to_mercury.m, since this allows us to avoid some undesirable dependencies. compiler/base_typeclass_info.m: compiler/hlds_code_util.m: Move the predicate make_instance_string from base_typeclass_info.m to hlds_code_util.m, again because it allows us to remove some undesirable dependencies. compiler/top_level.m: compiler/backend_libs.m: compiler/check_hlds.m: compiler/hlds.m: compiler/ll_backend.m: compiler/parse_tree.m: compiler/transform_hlds.m: Delete some import_module declarations of other top level modules in these top level modules. Some imports were totally unnecessary. Some imports were useful in only a small minority of submodules; those submodules now import the necessary top level modules directly. Move remaining import_module declarations to the implementation section where this is feasible. Where we still need to import modules we ideally shouldn't, note why. compiler/*.m: Update imports of code_util and arg_info. In some cases, import top level modules no longer imported by the parent module. In some cases, delete unnecessary imports. |
||
|
|
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. |
||
|
|
01899e087b |
Do not allocate a stack slot to a variable just because it is live at an
Estimated hours taken: 0.5 Branches: main Do not allocate a stack slot to a variable just because it is live at an unsafe_cast generic_call. compiler/live_vars.m: Treat unsafe_casts as assignments. Convert the file to use state variable syntax, reordering arguments as required. compiler/call_gen.m: Document the reliance of live_vars.m on the absence of stack flushes at unsafe_casts. compiler/stack_alloc.m: Conform to the new argument order in live_vars.m. compiler/stack_opt.m: Conform to the new argument order in live_vars.m, and convert the predicate concerned to state variable syntax. |
||
|
|
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. |
||
|
|
ed83fe4623 |
Optimize shallow traced modules by not adding calls to MR_trace to shallow
Estimated hours taken: 12
Branches: main
Optimize shallow traced modules by not adding calls to MR_trace to shallow
traced procedures which cannot be called from a deep traced environment.
A shallow traced procedure can be optimized in this way if it is neither
exported from its defining module nor has its address taken.
The main purpose of this optimization is not the avoidance of the cost of the
MR_trace calls as much as it is the restoration of tail recursion optimization.
Previously, compiling a program in a debug grade would disable all tail
recursion in the program (since debug grades require at least shallow tracing
every module). This was a problem because it limited the sizes of the inputs
the debugged program could process before running out of memory. As long as
the procedures that recurse on the input are in the implementation section
of a shallow traced module, this should no longer happen.
compiler/trace_params.m:
Introduce the concept of a procedure's effective trace level. This is
identical to the global trace level, except if the procedure is not
exported and doesn't have its address taken, and the global trace level
is shallow. In that case, we say that the procedure's effective trace
level is none.
Computing a procedure's effective trace level requires its proc_info
and its parent pred_info, so require callers to supply these as
parameters.
compiler/code_info.m:
Store the current pred_info as well as the current proc_info, for
trace parameter lookups.
compiler/continuation_info.m:
compiler/code_gen.m:
Record the required trace parameters of a procedure in its layout
structure, since it can no longer be computed from the global trace
level.
compiler/stack_layout.m:
Use the trace parameters in procedures' layout structures, instead of
trying to compute them from the global trace level.
compiler/inlining.m:
compiler/liveness.m:
compiler/stack_alloc.m:
compiler/store_alloc.m:
compiler/trace.m:
Use procedures' effective trace level instead of the global trace level
where relevant.
compiler/llds.m:
Record the required trace parameter of a procedure in its c_procedure
representation, since it can no longer be computed from the global
trace level.
Delete an obsolete field.
compiler/optimize.m:
compiler/jumpopt.m:
Use a required trace parameter of a procedure in its c_procedure
representation, since it can no longer be computed from the global
trace level.
compiler/compile_target_code.m:
compiler/handle_options.m:
compiler/llds_out.m:
compiler/mercury_compile.m:
Trivial changes to conform to updated interfaces.
compiler/stack_opt.m:
Use the option opt_no_return_calls, instead of approximating it
with the trace level. (The old code was a holdover from before the
creation of the option.)
tests/debugger/shallow.m:
tests/debugger/shallow2.m:
tests/debugger/shallow.{inp,exp*}:
Divide the old test case in shallow.m in two. The top level predicates
stay in shallow.m and continue to be shallow traced. The two bottom
predicates move to shallow2.m and are now deep traced.
The new test input checks whether the debugger can walk across the
stack frames of procedures in shallow traced modules whose effective
trace level is "none" (such as queen/2).
|
||
|
|
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.
|