[m-rev.] for review: --split-switch-arms
Julien Fischer
jfischer at opturion.com
Mon Jul 24 23:54:01 AEST 2023
On Mon, 24 Jul 2023, Zoltan Somogyi wrote:
> Add new optimization option --split-switch-arms.
...
> diff --git a/compiler/notes/compiler_design.html b/compiler/notes/compiler_design.html
> index 4f725ee5e..cefe0acdb 100644
> --- a/compiler/notes/compiler_design.html
> +++ b/compiler/notes/compiler_design.html
> @@ -1376,6 +1376,13 @@ simplify.m is a package of submodules.
> It also attempts to partially evaluate the correct calls,
> essentially interpreting the format string at compile time, not runtime.
> <li>
> + split_switch_arms.m optimizes code in which one or more switches
> + on a variable are nested inside one arm of a larger switch on the same
> + variable. It does so by making all the distinctions between the cons_id
> + of that outermost arm that any of the switches nested inside of it do.
> + By splitting up that arm according to those distintions, it effectively
s/distintions/distinctions/
> + replaces several switches with just one switch.
> + <li>
> simplify_proc.m handles the top-level processing of procedures
> and their bodies.
> <li>
...
> diff --git a/compiler/options.m b/compiler/options.m
> index 284a50b35..3b2663678 100644
> --- a/compiler/options.m
> +++ b/compiler/options.m
...
> @@ -5951,6 +5964,11 @@ options_help_hlds_hlds_optimization(Stream, !IO) :-
> "\tDo not attempt to interpret the format string in calls to",
> "\tstring.format and related predicates at compile time;",
> "\talways leave this to be done at runtime.",
> + "--split-switch-arms",
> + "\tWhen a switch on a variable has an inner switch on that",
> + "\tsame variable inside one of its arm, split up that arm of the",
its arms
> + "\touter switch along the same lines, effectively inlining",
> + "\tthe inner switch.",
> "--optimize-duplicate-calls",
> "\tOptimize away multiple calls to a predicate",
> "\twith the same input arguments.",
...
> --- a/compiler/simplify_proc.m
> +++ b/compiler/simplify_proc.m
> diff --git a/compiler/simplify_tasks.m b/compiler/simplify_tasks.m
> index 1eafd6a11..85179b52f 100644
> --- a/compiler/simplify_tasks.m
> +++ b/compiler/simplify_tasks.m
> @@ -98,9 +98,17 @@
> % on a data structure that the code *does* refer to using
> % state variable notation.
>
> - ; simptask_warn_no_solution_disjunct.
> + ; simptask_warn_no_solution_disjunct
> % Warn about disjuncts that can have no solution.
>
> + ; simptask_split_switch_arms.
> + % Invoke split_switch_arms.m to perform its transformation,
> + % if the main part of simplification discovers that has some
that it has some
> + % redundant switches to optimize.
> + %
> + % For the details of the transformation done by
> + % split_switch_arms.m, see its top-of-module comment.
> +
> %---------------------%
>
> :- type maybe_warn_simple_code
...
> diff --git a/compiler/split_switch_arms.m b/compiler/split_switch_arms.m
> index e69de29bb..a1c9ed783 100644
> --- a/compiler/split_switch_arms.m
> +++ b/compiler/split_switch_arms.m
> @@ -0,0 +1,579 @@
> +%----------------------------------------------------------------------------%
> +% vim: ft=mercury ts=4 sw=4 et
> +%----------------------------------------------------------------------------%
> +% Copyright (C) 2023 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: split_switch_arms.m.
> +%
> +% This module implements a program transformation that replaces code like this:
> +%
> +% (
> +% ( X = f1
> +% ; X = f2
> +% ; X = f3
> +% ; X = f4
> +% ),
> +% <initial code to handle f1,f2,f3,f4>,
> +% (
> +% X = f1,
> +% <code to handle f1>
> +% ;
> +% ( X = f2
> +% ; X = f3
> +% ),
> +% <code to handle f2,f3>
> +% ;
> +% X = f4,
> +% <code to handle f4>
> +% ),
> +% <final code to handle f1,f2,f3,f4>
> +% ;
> +% X = f5,
> +% <code to handle f5>
> +% )
> +%
> +% with code like this:
> +% (
> +% X = f1,
> +% <initial code to handle f1,f2,f3,f4>,
> +% <code to handle f1>,
> +% <final code to handle f1,f2,f3,f4>
> +% ;
> +% ( X = f2
> +% ; X = f3
> +% ),
> +% <initial code to handle f1,f2,f3,f4>,
> +% <code to handle f2,f3>,
> +% <final code to handle f1,f2,f3,f4>
> +% ;
> +% X = f4,
> +% <initial code to handle f1,f2,f3,f4>,
> +% <code to handle f4>,
> +% <final code to handle f1,f2,f3,f4>
> +% ;
> +% X = f5,
> +% <code to handle f5>
> +% )
> +%
> +% The idea is that if inside a switch on a variable, there are other switches
> +% on that same variable that subdivide the set of cons_ids even further, then
> +% we do the following.
> +%
> +% - We partition the cons_ids of the top-level switch arm to make all the
> +% distinctions between its cons_ids that any of the (one or more) switches
> +% on the same variable inside the top-level switch arm make,
> +%
> +% In this case, we would partition {f1,f2,f3,f4} into three sets:
> +% {f1}, {f2,f3} and {f4}.
> +%
> +% - We replace the original switch arm with a separate switch arm for each
> +% partition.
> +%
> +% In this case, this would replace the arm for {f1,f2,f3,f4}
> +% with three arms for {f1}, {f2,f3} and {f4} respectively.
> +% The three arms would initially contain the same code as the original
> +% switch arm. This would mean that each would contain the whole of
> +% nested switch on X with the three arms for {f1}, {f2,f3} and {f4}.
> +%
> +% - We restrict the goal in each of the resulting switch arms to refer to
> +% only the cons_ids of its own partion in any nested switches on the
> +% original switched-on variable, and we then simplify away any trivial
> +% switches generated by this process.
> +%
> +% In this case, in the new {f1}-only arm of the top switch, would replace
> +% the inner switch on X with the arms for {f1}, {f2,f3} and {f4}
> +% with just the arm for {f1}, and then optimize away the now-unnecessary
> +% switch wrapper around the goal inside that arm. We would do the same
> +% with the other two arms.
I suggest adding the rationale for performing this transformation here
(i.e. from the log message).
That looks fine otherwise.
Julien.
More information about the reviews
mailing list