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

openSUSE Build Service is sponsored by