[m-rev.] for review: optimization_options.m
Peter Wang
novalazy at gmail.com
Mon Sep 28 16:01:52 AEST 2020
On Sun, 27 Sep 2020 12:30:16 +1000 "Zoltan Somogyi" <zoltan.somogyi at runbox.com> wrote:
> This implements Mantis feature request #495. For review by Peter,
> since he made the request.
>
> The diff does not contain a test case, since this kind of thing does not fit
> into our testing infrastructure. However, I did test it manually. An old mmc,
> when invoked with --deforestation -O2, does not perform deforestation,
> because the -O2 switches off deforestation. An mmc with this diff *does*
> perform deforestation with the same argument list.
>
> Zoltan.
>
> Avoid -O<n> resetting previously set options.
>
> This implements Mantis feature request #495.
>
...
>
> library/getopt_template:
> Fix a bug that screwed up an error message.
>
> The bug happensed when processing a --file option. If one of the
happened
> 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.
> diff --git a/compiler/optimization_options.m b/compiler/optimization_options.m
> index e69de29bb..fece027bf 100644
> --- a/compiler/optimization_options.m
> +++ b/compiler/optimization_options.m
> @@ -0,0 +1,1873 @@
> +%---------------------------------------------------------------------------%
> +% vim: ft=mercury ts=4 sw=4 et
> +%---------------------------------------------------------------------------%
> +% Copyright (C) 2020 The Mercury team.
> +% This file may only be copied under the terms of the GNU General
> +% Public License - see the file COPYING in the Mercury distribution.
> +%---------------------------------------------------------------------------%
> +%
> +% File: optimization_options.m
> +% Main author: zs, via tools/make_opt
I would make it clearer this file is automatically generated.
Note that git only tracks whether a file is executable or not.
Removing the write bit from a file in your workspace will prevent you
from modifying that file accidentally, but if you check out the file
again or someone else makes a fresh checkout, it will have mode 644 or 755.
> +process_optimization_options(OptionTable, OptOptions, !:OptTuple) :-
> + !:OptTuple = init_opt_tuple,
> + list.foldl2(update_opt_tuple(OptionTable), OptOptions,
> + !OptTuple, not_seen_opt_level, MaybeSeenOptLevel),
> + (
> + MaybeSeenOptLevel = not_seen_opt_level,
> + set_opts_upto_level(OptionTable, 0, 2,
> + !OptTuple, MaybeSeenOptLevel, _)
> + ;
> + MaybeSeenOptLevel = seen_opt_level
> + ).
> +
Maybe write "DefaultOptLevel = 2" to make it more obvious.
> +%---------------------%
> +
> +:- type maybe_seen_opt_level
> + ---> not_seen_opt_level
> + ; seen_opt_level.
> +
> +:- pred update_opt_tuple(option_table::in, optimization_option::in,
> + opt_tuple::in, opt_tuple::out,
> + maybe_seen_opt_level::in, maybe_seen_opt_level::out) is det.
> +update_opt_tuple(OptionTable, OptOption, !OptTuple, !MaybeSeenOptLevel) :-
> + (
> + OptOption = oo_allow_inlining(Bool),
> + ( if
> + Bool = yes,
> + !.OptTuple ^ ot_allow_inlining = do_not_allow_inlining
> + then
> + !OptTuple ^ ot_allow_inlining := allow_inlining
> + else
> + true
> + )
Hmm, how does --no-foo work?
> + ;
> + OptOption = oo_procs_per_c_function(N),
> + OldN = !.OptTuple ^ ot_procs_per_c_function,
> + !OptTuple ^ ot_procs_per_c_function := int.max(OldN, N)
I think all the other integer values set by -O<n> increase with n,
except for this one.
-O6 implies everything_in_one_c_function by internally setting
ot_procs_per_c_function to 0.
If the user passes "--procs-per-c-function 5 -O6" then
ot_procs_per_c_function will be set to 5 instead of 0.
This is a VERY minor issue.
> +:- pred opts_enabled_at_level(int::in, list(optimization_option)::out)
> + is semidet.
> +
> +opts_enabled_at_level(1, [
> + % Optimization level 1: apply optimizations which are cheap and
> + % have a good payoff while still keeping compilation time small.
> + oo_use_local_vars(yes),
> + oo_opt_c(yes), % XXX We want `gcc -O1'
> + oo_opt_frames(yes),
> + oo_opt_delay_slot(yes),
Maybe add a comment: % only if have_delay_slot = yes
> + oo_opt_middle_rec(yes),
> + oo_emit_c_loops(yes),
> + oo_opt_mlds_tailcalls(yes)
> +]).
> diff --git a/tools/make_optimization_options_middle b/tools/make_optimization_options_middle
> index e69de29bb..ca250ea69 100755
> --- a/tools/make_optimization_options_middle
> +++ b/tools/make_optimization_options_middle
> @@ -0,0 +1,293 @@
> +#!/usr/bin/awk -f
> +# vim: ts=4 sw=4 et ft=awk
> +#---------------------------------------------------------------------------#
> +# Copyright (C) 2020 The Mercury team.
> +# This file may only be copied under the terms of the GNU General
> +# Public License - see the file COPYING in the Mercury distribution.
> +#---------------------------------------------------------------------------#
> +#
> +# The input to this file, make_optimization_options_db, has one line
> +# for every optimization option. Each line must have either three
> +# or four fields.
> +#
> +# - The first field indicates what kind of option this is. It must be
> +# one of "bool", "int" and "string".
or
> +#
> +# - The second field gives the initial value of the option.
> +#
> +# - If the option is boolean, the initial value must be either "n" or "y".
> +#
> +# - If the option is an integer, the initial value must be an integer.
> +#
> +# - If the option is a strin, the initial value will be set
> +# to the empty string regardless of the contents of the second field.
string
> +#
> +# - The third field is the name of the option in options.m.
> +#
> +# - The fourth field, if it exists, gives the name of the option
> +# in the file this script helps generate, optimization_options.m.
> +# If there is no fourth field, the name is taken to be the same
> +# as the name in the third field.
> +#
> +# For boolean options, the name in optimization_options.m should be a verb,
> +# because when we generate a bespoke type for it, its two function symbols
> +# will be named "verb" and "do_not_verb".
> +#
> +
> +BEGIN {
> + default_opt_level = 2;
> + next_bool_opt = 0;
> + next_int_opt = 0;
> + next_string_opt = 0;
> + }
> + {
> + if (NF == 3 || NF == 4) {
You could assign the fields to variables, and handle the optional fourth
field here instead of each case.
> + if ($1 == "bool") {
> + bool_opts[next_bool_opt] = $3;
> + if (NF == 4) {
> + bool_field_names[next_bool_opt] = $4;
> + } else {
> + bool_field_names[next_bool_opt] = $3;
> + }
> + if ($2 == "y") {
> + bool_defaults[next_bool_opt] = bool_field_names[next_bool_opt];
> + } else if ($2 == "n") {
> + bool_defaults[next_bool_opt] = "do_not_" bool_field_names[next_bool_opt];
> + } else {
> + printf("ERROR: bad bool default<%s>\n", $0);
> + }
> + next_bool_opt++;
> + } else if ($1 == "int") {
> + int_opts[next_int_opt] = $3;
> + if (NF == 4) {
> + int_field_names[next_int_opt] = $4;
> + } else {
> + int_field_names[next_int_opt] = $3;
> + }
> + int_defaults[next_int_opt] = $2 + 0;
> + next_int_opt++;
> + } else if ($1 == "string") {
> + string_opts[next_string_opt] = $3;
> + if (NF == 4) {
> + string_field_names[next_string_opt] = $4;
> + } else {
> + string_field_names[next_string_opt] = $3;
> + }
> + # Ignore the default; strings always default to the empty string.
> + next_string_opt++;
Might as well require the second field to be "-" for now.
> + } else {
> + printf("ERROR: line with unknown type: <%s>\n", $0);
> + }
> + } else {
> + printf("ERROR: line with %d fields: <%s>\n", NF, $0);
> + }
> + }
The rest looks fine. Thanks for working on it!
Peter
More information about the reviews
mailing list