mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 09:23:44 +00:00
e00722533b25ea353e4c3adcc178f00a92fcfbf3
11 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ae820da5b1 |
Delete the --inline-linear-tail-rec-sccs option ...
... including the --inline-linear-tail-rec-sccs-max-extra option
that was its parameter.
This option was added as a quick-and-dirty workaround before we taught
the MLDS backend how to implement tail recursion for mutually recursive
predicates, and has not been needed since that capability has proven itself.
compiler/options.m:
Delete both options from the option table.
tools/make_optimization_options_db:
Delete both options from the opt_tuple.
compiler/inlining.m:
Delete the implementation of this option.
compiler/mercury_compile_middle_passes.m:
compiler/optimization_options.m:
doc/user_guide.texi:
Conform to the changes above.
|
||
|
|
51b1304b0d |
Record the initial values of the bool_special options ...
... which are managed by tools/make_optimization_options.
tools/make_optimization_options_middle:
When creating compiler/optimization_options.m, put into it
a new predicate that records, for each bool_special option
managed by this module, its initial value.
compiler/print_help.m:
Handle bool_special options whose initial value this new predicate
makes known the same way we now handle plain bool options.
The difference this makes is that bool_special options that
default to "yes" will now have their --no-xyz form listed as
the user-visible form of the option, not their --xyz form.
tools/make_optimization_options_db:
tools/make_optimization_options_end:
Fix a discrepancy that made documenting the smart indexing
unnecessarily complicated. The first such option defaulted to "no",
but was switched to "yes" at -O0, while the others all defaulted
to "yes". Allow these options to be documented in the same manner
by making them *all* default to "no", and switch them all on at -O0.
compiler/optimization_options.m:
Rebuilt with the updated make_optimization_options.
compiler/options.m:
Many of the bool_special options that default to "yes" had
help text that already assumed that this text followed
the option name being printed as --no-xyz.
For the others, which assumed that they followed --xyz,
change the help text to be appropriate when following
the --no-xyz form.
tests/warnings/help_text.err_exp:
Expect the updated help texts.
doc/user_guide.texi:
Expect the updated help texts, from this and earlier commits.
tests/warnings/help_opt_level.err_exp:
Expect the added level-enabled options.
|
||
|
|
96e1ed99e1 |
Give many optimization options backend-specific names ...
... and delete their second name.
compiler/options.m:
The internal names of many optimization options have traditionally
given no clue about which backend(s) they apply to, which made it
hard to document them. Change this by including either llds or mlds
in the names of these options, unless the rest of the name already
ruled out one or the other backend.
In one case, this exercise relevaled that an option that was classified
as MLDS-only is used by the LLDS backend as well. Reclassify this option.
Also, rename many options to the names they have in the opt_tuple.
Those names are more recent, and their naming is more consistent
(e.g. they are all verb phrases).
tools/make_optimization_options_db:
Delete the different-from-the-opt-tuple name alternatives.
tools/make_optimization_options_end:
Conform to the option renames.
Also, fix a bug. The list of options enabled at each optimization
level lists each option twice, once by its name in the opt_tuple
(which is what we use to actually implement optimization levels)
and once by its name in options.m (which we use to implement
the option that prints out the optimization levels). In one case,
the two names did not match; fix this.
compiler/optimization_options.m:
Rebuild this module with tools/make_optimization_options.
compiler/add_trail_ops.m:
compiler/global_data.m:
compiler/handle_options.m:
compiler/ite_gen.m:
compiler/jumpopt.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/ml_optimize.m:
compiler/optimize.m:
compiler/options.m:
compiler/proc_gen.m:
compiler/stack_layout.m:
Conform to the option renames.
tests/warnings/help_opt_levels.err_exp:
Expect the fix to make_optimization_options_end.
tests/warnings/help_text.err_exp:
Expect the option reclassification.
|
||
|
|
96022cee60 |
Prepare to document optimization levels ...
... by having the automatically-generated optimization_options.m module
export the information we will need for that documentation.
tools/make_optimization_options_end:
Modify the predicate that lists the options at each optimization level
in two distinct ways:
- by turning the existing comments documenting the meaning of each
optimization level into strings that we can include the documentation,
and
- by adding next to each optimization_option setting, which cannot be
easily turned into the user-facing names of the options being set,
the option and its new value, which can be turned into that.
There was another possible way to get the second job done. This was
to have tools/make_optimization_options_middle generate TWO versions
of the code that is now bodily included in options.m between
INCLUDE_HANDLER_FILE_{START,END}: the one we have there now,
and one that can do the conversion in the reverse direction.
I judged this extra 500+ lines of code to be too much, even if
automatically generated.
(Putting the code as the body of a predicate with two modes would work,
but this would separate the parts of switch on Option inside the
special_handler that are automatically generated from the parts
which are hand-written, and would therefore allow any accidental
duplicate arms (options handled in both parts) to be undetected.
I judged this to be unacceptable also.)
The method I chose does duplicate some code (each level lists the
same info in two different ways), but since the consistency is trivial
to check visually, and we update levels so rarely, this should not matter.
tools/make_optimization_options_middle:
tools/make_optimization_options_start:
Conform to the changes above.
tools/make_optimization_options_db:
compiler/options.m:
Rename the optopt_everything_in_one_c_function option to the name
it has inside optimization_options.m, optopt_use_just_one_c_func.
Since this did not break anything, move the option to the
oc_unused category.
compiler/optimization_options.m:
Automatic update after the changes in tools/make_optimization_options*.
|
||
|
|
2d1b247e43 |
Classify all the optimization options ...
compiler/options.m:
... based on what data structures (HLDS, MLDS, LLDS, target code)
they take as input and generate as output. This defines the effective
domain of applicability of each option.
Rename the oc_spec_opt category as oc_opt_hh_exp, with _exp being
short for experimental.
The optopt_optimize and optopt_peep internal options each had
separate user-facing names (such as "llds-optimize" and "mlds-optimize)
that implied different and separate functions, but mapping the different
user-facing option names to the same internal option linked them together.
This could manifest itself as e.g. "--mlds-optimize --no-llds-optimize"
switching off mlds optimizations after the user explicitly switched
them on. The same issue also arose for peephole optimizations. Fix this
by using internal options that form a bijection with the user facing
names (modulo spelling).
tools/make_optimization_options_db:
tools/make_optimization_options_end:
Conform to the split of the optimize and peep options.
compiler/handle_options.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/ml_optimize.m:
compiler/optimization_options.m:
compiler/optimize.m:
compiler/peephole.m:
Conform to the changes above.
|
||
|
|
4f9c0bef9a |
Shorten the names of many optimization options.
There are no algorithmic changes.
compiler/options.m:
tools/make_optimization_options_db:
As above.
tools/make_optimization_options_db_start:
Update the copyright years we put into optimization_options.m.
compiler/optimization_options.m:
Regenerated with the new make_optimization_options_db.
compiler/inlining.m:
compiler/mercury_compile_middle_passes.m:
Conform to the changes above.
|
||
|
|
43dd12bd5b |
Merge consecutive switches on the same variable.
compiler/simplify_goal_conj.m:
When a switch on a variable is followed by a switch on the *same* variable,
merge the two switches together, if doing so looks like it can save
the execution of some branches for at least some input values.
This transform is the second one to merge the goal following a switch
into the switch itself. Move the parts of the code involved that are
common between the two transformation to its caller, to reduce runtime
overhead.
compiler/simplify_goal.m:
Add infrastructure for printing the pre- and post-simplification versions
of specific goals. This helped debug the new code in simplify_goal_conj.m.
Fix an inadvertent unification between two module_infos.
This was caused by code that
- defined the variable ModuleInfo, and then
- reuses the "ModuleInfo" variable name for a slightly different purpose,
but did so in the condition of an if-then-else, where the semidet nature
of the implicit unification between the new value intended to be assigned
to ModuleInfo, and its old value, was expected.
compiler/simplify_proc.m:
Add infrastructure for printing versions of the procedure body
before and after quantification, instmap delta recomputation, and
determinism analysis have been rerun. This helped debug the new code
in simplify_goal_conj.m.
The rest of the changes concern the option that
- previously called only for the existing transformation to merge a test
unification following a switch into a switch
- and which now also calls for the merging of two succesive switches
on the same variable.
compiler/options.m:
The option was named test_after_switch; this diff updates its name to
merge_code_after_switch.
compiler/handle_options.m:
compiler/simplify_info.m:
compiler/simplify_tasks.m:
compiler/optimization_options.m:
tools/make_optimization_options_db:
tools/make_optimization_options_end:
Conform to this name change.
|
||
|
|
88d4bccdba |
Add new optimization option --split-switch-arms.
Given a switch arm that matches several cons_ids, and which contains
one or more switches on the *same* variable, such as the arm for
f1/f2/f3/f4 below,
(
(X = f1 ; X = f2 ; X = f3 ; X = f4),
...
(
X = f1,
...
;
(X = f2 ; X = f3),
...
;
X = f4,
...
),
...
;
...
)
this new optimization
- partitions the set of cons_id in that arm (in this case, {f1,f2,f3,f4})
as finely as needed by any other the switches on X in that arm
(in this case, that is three partitions containing {f1}, {f2,f3} and {f4}),
- splits that original switch arm into N arms, one arm for each partition,
making a copy of the switch arm's goal for each partition,
- restricts any switches on the original switch variable (in this case, X)
inside the copy of the arm goal inside each new case to only the cons_ids
in that case's partition, and then replacing any resulting one-arm switches
with the just goal inside that one arm.
The code resulting from these three steps will include some code duplication
(some of the pieces of code denoted by ... in the example above would be
duplicated), but it will need to execute fewer transfers of control.
This is worthwhile because (a) the branch instructions used to implement
switches are hard to predict unless most paths through the nested switches
are rarely if ever taken, and (b) the pipeline breaks caused by branches
that are not correctly predicted are one of the two major contributors
to the runtime of Mercury programs. (The other major contributors are
data cache misses.)
The implementation of this option has two major parts.
- Part 1 consists of discovering whether a procedure body contains
any code in which a switch on a variable is nested inside an arm
of another switch on that same variable. For any instance of such
a pair of switches, it records the identity of the variable and
the set of cons_ids of the outermost arm.
- Part 2 consists of actually transforming the procedure body
by splitting each outermost switch arm thus recorded. (This part
contains all three of the steps above.)
We integrate part 1 with the usual procedure body traversal of the
simplification pass, which makes it quite cheap. In most procedure bodies,
it won't find any nested switches meeting its criteria. We execute part 2,
which is relatively expensive, only if it does.
compiler/simplify_info.m:
Add a new type, switch_arm, which represents one arm of a switch.
Add a new field to the simplify_nested_context type. Its type
is list(switch_arm), and it represents the stack of switch arms (if any)
that the goal currently being simplified is inside. simplify_goal_switch.m
uses this field to detect switches that occur inside an arm of an
ancestor goal that is also a switch on the same variable.
Add a new field to the simplify_info, a set of switch_arms,
that denotes the set of switch arms from which that detection
has actually happened, and which should therefore be
partitioned and split.
compiler/simplify_goal_switch.m:
Add the code for doing the detection and recording mentioned just above.
This is the Part 1 mentioned above.
compiler/split_switch_arms.m:
This new module implements the splitting up process.
This is the Part 2 mentioned above.
compiler/simplify.m:
Include the new module in the simplify subpackage of the check_hlds
package.
compiler/notes/compiler_design.html:
Document the new module.
compiler/simplify_proc.m:
Invoke split_switch_arms.m (part 2) if the part of simplify_goal_switch.m
implementing part 1 has found any work for it to do.
compiler/simplify_tasks.m:
Add split_switch_arms as one of the tasks that simplification
may be asked to do. Set its default value from the value of
a new optimization option that, when specified, calls for it to be done.
compiler/options.m:
Add this option, --split-switch-arms.
Change the internal name of an existing option,
everything_in_one_c_function, to the one expected by
tools/make_optimization_options_middle.
Replace the part of this file that is constructed by
tools/make_optimization_options_middle.
doc/user_guide.texi:
Document the new option.
tools/make_optimization_options_db:
Add --split-switch-arms to the optimization tuple.
Fix software rot by
- renaming optimize_tailcalls to optimize_mlds_tailcalls inside the
optimization tuple, as it has been in options.m, and
- deleting erlang_switch_on_strings_as_atoms from the opt_tuple,
as it has been from options.m.
tools/make_optimization_options_end:
Enable the new option by default at optimization level 2.
tools/make_optimization_options_middle:
Fix bugs in this script, which generates compiler/optimization_options.m.
One bug was that it referred to the opt_level and opt_space options
by the wrong name (optopt_level and optopt_space respectively).
The other bug was that it expected opt_level to be a string_special option,
when it is an int_special option.
Make the handler_file this script generates easier to put into options.m
by not generating a line that (a) already exists in options.m, and
(b) would need to have a comma put after it, if one wanted this line
to replace the copy already in options.m.
compiler/optimization_options.m:
Rebuild this file after the changes above.
compiler/simplify_goal_unify.m:
Conform to the changes above.
compiler/inst_merge.m:
Mark two predicates, inst_merge_[34], to be inlined. The intention
is that inst_merge_4 should be inlined into inst_merge_3, and then
inst_merge_3 should be inlined inside inst_merge_2; that would then
generate six levels of switches, three on one of the insts to be
merged and three on the other, which the new optimization could
then flatten. Unfortunately, inlining does not do this yet.
tests/hard_coded/test_split_switch_arms.{m,exp}:
A new test case for the the new transformation.
tests/hard_coded/Mmakefile:
tests/hard_coded/Mercury.options:
Enable the new test case, and specify the new option for it.
|
||
|
|
9c4a8be0f6 |
Let simplify introduce ground_term_const cons_ids.
This diff gives simplification the ability to look for construction
unifications X = f(...) that construct static terms, and to replace
those unifications with unifications X = ground_term_const(N), where
entry #N in the const_struct_db is f(...).
The idea is to ask simplification to do this when it is invoked
at the end of the front end. Later on, if and when we identify one or more
middle passes that may introduce new code that benefit from this
optimization, we could ask the pre-code-generation invocation
of simplification to repeat this optimization; until then,
such a repeat is not warranted.
In the long term, this diff should enable us to discard mark_static_terms.m,
the construct_statically code path in ml_unify_gen_construct.m, and the
equivalent code in the LLDS code generator.
compiler/common.m:
This new optimization is done in common.m. The reason for this is that
when this optimization is applicable, it overrides one part of common.m's
functionality (replacing X = f(...) with X = Y, if Y already contains
f(...)), but not another (gathering information about variable
equivalences for use in optimizing away and/or warning about
duplicate calls). Such half-override would be effectively impossible
to arrange from a new module.
Because of the need for this partial override, have this module,
rather than simplify_goal_unify.m, make decisions about exactly
what is to be done for each unification.
For a similar reason, bring part of the logic controlling the recording
of stack flushes here from simplify_goal.m.
compiler/simplify_tasks.m:
Add the new optimization as a new task that simplification may be asked
to do.
Rather than add it as yet another bool field in the simplify_tasks
structure, add it with its own bespoke bool-like type, and replace
all the other bools with separate bespoke types as well.
Do the same with the "should we generate warnings" flag for
find_simplify_tasks. Fix simplify_tasks's arg order.
Switch from (C->T;E) to (if C then T else E) syntax.
compiler/optimization_options.m:
compiler/options.m:
tools/make_optimization_options_db:
To let simplify_tasks.m know whether the use of constant structures
is allowed, either for terms created by the polymorphism pass,
or for user terms, use two separate optimization options for these two
separate though related concepts. Keep the one that is relevant only
for the polymorphism pass invisible to users.
compiler/handle_options.m:
compiler/const_struct.m:
Move the code that adjusts the values of these two options
based on the target language and on the values of other options
from const_struct.m to handle_options.m, so that information
simplify_tasks.m needs is available in the globals structure
it is passed (i.e. so that we don't have to pass it a const_struct_db).
Suppress the use of const structs for user terms when generating
optimization interface files, because after this change to common.m,
their use could result in dangling references to the const_struct_db
in those files.
compiler/mercury_compile_front_end.m:
Ask for the new optimization to be done during the after-front-end
invocation of simplification, if the option settings allow it.
compiler/simplify_proc.m:
Fit the new optimization into the logic that decides whether
we need two passes through the procedure body, or just one.
Factor out some common code.
compiler/simplify_goal.m:
compiler/simplify_goal_unify.m:
Delete code whose job has been moved to common.m.
compiler/simplify_info.m:
Delete some no-longer-needed test predicates.
Conform to the changes above.
compiler/simplify_goal_call.m:
Add an XXX about code that relies on common_info even in situations
in which it may not have been set up.
compiler/deforest.m:
compiler/mercury_compile_llds_back_end.m:
compiler/pd_util.m:
compiler/polymorphism.m:
compiler/polymorphism_type_info.m:
compiler/simplify_goal_scope.m:
compiler/size_prof.m:
compiler/stack_opt.m:
compiler/structure_sharing.analysis.m:
Conform to the changes above.
|
||
|
|
91560d2dd7 |
Make --everything-in-one-c-function a bool option.
It used to be a special option that just set procs_per_c_function
to the special value of zero, but this behavior is inconsistent with
optimization_options taking the max of the old and new values of
integer options. This meant that --procs-per-c-function=5 -O6
would not put all procedures into one C function.
tools/make_optimization_options_db:
tools/make_optimization_options_end:
compiler/optimization_options.m:
As above: make --everything-in-one-c-function a bool option,
named use_just_one_c_func for brevity.
compiler/options.m:
Move the code handling --everything-in-one-c-function next to the
other optimization options.
compiler/mercury_compile_llds_back_end.m:
When deciding which procedures should be put into which C functions,
use the logic: if use_just_one_c_func, then put all procs into the
same C function, otherwise, put them into one or more C functions
with up to procs_per_c_function procedures per function.
This is now the *only* place in the compiler that looks at
procs_per_c_function; everywhere else looks at use_just_one_c_func.
compiler/code_util.m:
Replace a maybe pair type that used to store the value of
procs_per_c_function with a bespoke type storing use_just_one_c_func,
which documents its meaning.
compiler/code_info.m:
Replace a bool type with a bespoke type, again documenting
its meaning.
compiler/call_gen.m:
compiler/closure_gen.m:
compiler/middle_rec.m:
compiler/pragma_c_gen.m:
compiler/proc_gen.m:
compiler/rtti_out.m:
Conform to the changes above.
compiler/llds.m:
Fix blank lines.
|
||
|
|
181ada0dbf |
Avoid -O<n> resetting previously set options.
This implements Mantis feature request #495. NEWS: Announce the change. compiler/optimization_options.m: A new module for managing optimization options. It defines a separate bespoke type for every boolean optimization option to make it harder to confuse them. It defines a tuple type (opt_tuple) for accessing optimization options quickly. It implements the turning on (but NOT turning off) of optimizations when a given optimization level is selected. tools/make_optimization_options_middle: tools/make_optimization_options_db: The script that generates the meat of optimization_options.m, and the database of option names, kinds and initial values that it uses as its input. The script also generates some code for the special_handler predicate in compiler/options.m. tools/make_optimization_options_start: tools/make_optimization_options_end: The handwritten initial and final parts of optimization_options.m. tools/make_optimization_options: The script that pulls these parts together to form optimization_options.m. compiler/options.m: Make every optimization option a special option, to be handled by the special_handler predicate. That handling consists of simply adding a representation of the option to the end of a cord of optimization options, to be processed later by optimization_options.m. That processing will record the values of these options in the opt_tuple, which is where every other part of the compiler should get them from. Change the interface of special_handler to make the above possible. Add an "optopt_" (optimization option) prefix to the name of every optimization option, to make them inaccessible to the rest of the compiler under their old name, and thus help enforce the switch to using the opt_tuple. Any access to these options to look up their values would fail anyway, since the option data would no longer be e.g. bool(yes), but bool_special, but the name change makes this failure happen at compile time, not runtime. Reclassify a few options to make the above make sense. Some options (unneeded_code_debug, unneeded_code_debug_pred_name, and common_struct_preds) were classified as oc_opt even though they control only the *debugging* of optimizations, while some options (c_optimize and inline_alloc) were not classified as oc_opt even though we do set them automatically at some optimization levels. Delete the opt_level_number option, since it was not used anywhere. Delete the code for handling -ON and --opt-space, since that is now done in optimization_options.m. Add some XXXs. compiler/handle_options.m: Switch to using getopt_io.process_options_userdata_se, as required by the new interface of the special_handler in options.m. In the absence of errors, invoke optimization_options.m to initialize the opt_tuple. Then update the opt_tuple incrementally when processing option implications that affect optimization options. compiler/globals.m: Put the opt_tuple into a new field of the globals structure. compiler/accumulator.m: compiler/add_pragma_type_spec.m: compiler/add_trail_ops.m: compiler/code_info.m: compiler/code_loc_dep.m: compiler/compile_target_code.m: compiler/const_struct.m: compiler/deforest.m: compiler/dep_par_conj.m: compiler/disj_gen.m: compiler/erl_code_gen.m: compiler/format_call.m: compiler/global_data.m: compiler/grab_modules.m: compiler/higher_order.m: compiler/hlds_pred.m: compiler/inlining.m: compiler/intermod.m: compiler/ite_gen.m: compiler/jumpopt.m: compiler/libs.m: compiler/llds_out_code_addr.m: compiler/llds_out_data.m: compiler/llds_out_file.m: compiler/llds_out_instr.m: compiler/llds_out_util.m: compiler/matching.m: compiler/mercury_compile_front_end.m: compiler/mercury_compile_llds_back_end.m: compiler/mercury_compile_main.m: compiler/mercury_compile_middle_passes.m: compiler/mercury_compile_mlds_back_end.m: compiler/ml_disj_gen.m: compiler/ml_gen_info.m: compiler/ml_lookup_switch.m: compiler/ml_optimize.m: compiler/ml_proc_gen.m: compiler/ml_simplify_switch.m: compiler/ml_switch_gen.m: compiler/ml_unify_gen_construct.m: compiler/optimize.m: compiler/pd_util.m: compiler/peephole.m: compiler/polymorphism.m: compiler/proc_gen.m: compiler/simplify_goal_call.m: compiler/simplify_goal_scope.m: compiler/simplify_info.m: compiler/simplify_proc.m: compiler/simplify_tasks.m: compiler/stack_layout.m: compiler/stack_opt.m: compiler/switch_gen.m: compiler/switch_util.m: compiler/tag_switch.m: compiler/tupling.m: compiler/unify_gen_construct.m: compiler/unneeded_code.m: compiler/unused_args.m: Conform to the changes above, mostly by looking up optimization options in the opt_tuple. In some places, replace bools containing optimization options with the bespoke type of that specific optimization option. library/getopt_template: Fix a bug that screwed up an error message. The bug happened when processing a --file option. If one of the options in the file was a special option whose special handler failed, the code handling that failing option returned both an error indication, and the rest of the argument list read in from the file. The code handling the --file option then *ignored* the error indication from the failed special option, and returned an error message of its own complaining about the unconsumed remaining arguments in the file, believing them to be non-option arguments, even though these arguments were never looked it to see if they were options. The fix is for the code handling --flag options to check whether the code processing the file contents found any errors, and if so, return that error *without* looking at the list of remaining arguments. In an unrelated change, factor out a duplicate call. |