File 0274-Correct-order-of-optimization-passes.patch of Package erlang
From beb858d876071f2b83c3e2cb8482186055cb1a90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Mon, 3 May 2021 14:33:46 +0200
Subject: [PATCH] Correct order of optimization passes
81bc659e4cf0 switched the order of some optimization passes to
speed up compilation. Unfortunately, in rare circumstances that
would cause the `beam_ssa_bool` pass to do unsafe optimizations.
This commit eliminates the problem by running the `beam_ssa_bool` pass
before the `beam_ssa_share` pass (that is a partial revert of the
problematic commit). On my computer, that increases the compilation
time for the `String.Unicode` module in the Elixir standard library
with about 2 seconds (13 seconds instead of 11 seconds,
approximately).
Closes #4788.
---
lib/compiler/src/beam_ssa_bool.erl | 4 +++-
lib/compiler/src/compile.erl | 10 +++++-----
lib/compiler/test/guard_SUITE.erl | 18 ++++++++++++++++++
3 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/lib/compiler/src/beam_ssa_bool.erl b/lib/compiler/src/beam_ssa_bool.erl
index 1404d8197f..2830339410 100644
--- a/lib/compiler/src/beam_ssa_bool.erl
+++ b/lib/compiler/src/beam_ssa_bool.erl
@@ -110,7 +110,9 @@
%% the same control flow graph analysis and simplification as
%% bool_opt/2 already does.
%%
-
+%% This optimization pass must be first to be run after conversion
+%% to SSA code, both for correctness and effectiveness reasons.
+%%
-module(beam_ssa_bool).
-export([module/2]).
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index 515f5facd8..0d5fc5f400 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -854,14 +854,14 @@ kernel_passes() ->
{iff,dssa,{listing,"ssa"}},
{iff,ssalint,{pass,beam_ssa_lint}},
{delay,
- [{unless,no_share_opt,{pass,beam_ssa_share}},
- {iff,dssashare,{listing,"ssashare"}},
- {unless,no_share_opt,{iff,ssalint,{pass,beam_ssa_lint}}},
-
- {unless,no_bool_opt,{pass,beam_ssa_bool}},
+ [{unless,no_bool_opt,{pass,beam_ssa_bool}},
{iff,dbool,{listing,"bool"}},
{unless,no_bool_opt,{iff,ssalint,{pass,beam_ssa_lint}}},
+ {unless,no_share_opt,{pass,beam_ssa_share}},
+ {iff,dssashare,{listing,"ssashare"}},
+ {unless,no_share_opt,{iff,ssalint,{pass,beam_ssa_lint}}},
+
{unless,no_bsm_opt,{pass,beam_ssa_bsm}},
{iff,dssabsm,{listing,"ssabsm"}},
{unless,no_bsm_opt,{iff,ssalint,{pass,beam_ssa_lint}}},
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index 74aed42b1f..85e0bc0edd 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -2303,6 +2303,7 @@ beam_bool_SUITE(_Config) ->
erl1246(),
erl1253(),
erl1384(),
+ gh4788(),
ok.
before_and_inside_if() ->
@@ -2776,6 +2777,23 @@ erl1384_1(V) ->
_ -> gaffel
end.
+gh4788() ->
+ ok = do_gh4788(id(0)),
+ ok = do_gh4788(id(1)),
+ ok = do_gh4788(id(undefined)),
+ lt_0_or_undefined = catch do_gh4788(id(-1)),
+ ok.
+
+do_gh4788(N) ->
+ %% beam_ssa_bool would do an unsafe optimization when run after
+ %% the beam_ssa_share pass.
+ case {N >= 0, N == undefined} of
+ {true, _} -> ok;
+ {_, true} -> ok;
+ _ -> throw(lt_0_or_undefined)
+ end,
+ ok.
+
%%%
%%% End of beam_bool_SUITE tests.
%%%
--
2.26.2