File 1321-Reduce-compilation-times-for-code-with-many-element-.patch of Package erlang

From 437c3957e873685789df3ffdcc2440b74c5195a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Fri, 6 Mar 2026 15:23:20 +0100
Subject: [PATCH] Reduce compilation times for code with many element/2 calls

Improve the compile-time performance of code with many uses of
`element/2`. This reduces the time of the `beam_ssa_opt` pass
to about 6 seconds down from 11 seconds on my computer.

Resolves #10807
---
 lib/compiler/src/beam_ssa_alias.erl | 28 +++++++++++-----------------
 lib/compiler/src/beam_ssa_type.erl  | 23 ++++++++++++-----------
 2 files changed, 23 insertions(+), 28 deletions(-)

diff --git a/lib/compiler/src/beam_ssa_alias.erl b/lib/compiler/src/beam_ssa_alias.erl
index 7cbc4843c1..2bf285e660 100644
--- a/lib/compiler/src/beam_ssa_alias.erl
+++ b/lib/compiler/src/beam_ssa_alias.erl
@@ -1653,11 +1653,12 @@ rur_args([], _) ->
 %% forcibly alias the variable when it is defined.
 %%
 forced_aliasing(Linear) ->
-    forced_aliasing(Linear, #{0=>#{}}, sets:new()).
+    SeenDb0 = #{0 => #{}, ?EXCEPTION_BLOCK => #{}},
+    forced_aliasing(Linear, SeenDb0, sets:new()).
 
-forced_aliasing([{Lbl,#b_blk{last=Last,is=Is}}|Rest], SeenDb0, ToExtend0) ->
+forced_aliasing([{Lbl,#b_blk{is=Is}=Block}|Rest], SeenDb0, ToExtend0) ->
     #{Lbl:=Seen0} = SeenDb0,
-    Successors = fa_successors(Last),
+    Successors = beam_ssa:successors(Block),
     {Seen,ToExtend} = forced_aliasing_is(Is, Seen0, ToExtend0),
     SeenDb = foldl(fun(Succ, Acc) -> fa_merge(Seen, Succ, Acc) end,
                    SeenDb0, Successors),
@@ -1710,18 +1711,11 @@ forced_aliasing_extend_to(Dst, Aliases, ToExtend) ->
     foldl(fun sets:add_element/2,
           sets:add_element(Dst, ToExtend), Aliases).
 
-fa_successors(#b_ret{}) ->
-    [];
-fa_successors(#b_br{succ=S,fail=F}) ->
-    [S,F];
-fa_successors(#b_switch{list=Ls,fail=F}) ->
-    [F|[L || {_,L} <:- Ls]].
-
-fa_merge(Seen, Succ, SeenDb) ->
+fa_merge(_Seen, ?EXCEPTION_BLOCK, SeenDb) ->
+    SeenDb;
+fa_merge(Seen0, Succ, SeenDb) ->
     Other = maps:get(Succ, SeenDb, #{}),
-    SeenDb#{Succ=>maps:merge_with(
-                    fun(_, A, B) ->
-                            ordsets:union(A, B)
-                    end,
-                    Seen, Other)}.
-
+    Seen = maps:merge_with(fun(_, A, A) -> A;
+                              (_, A, B) -> ordsets:union(A, B)
+                           end, Seen0, Other),
+    SeenDb#{Succ=>Seen}.
diff --git a/lib/compiler/src/beam_ssa_type.erl b/lib/compiler/src/beam_ssa_type.erl
index 4d40651df8..473bf60965 100644
--- a/lib/compiler/src/beam_ssa_type.erl
+++ b/lib/compiler/src/beam_ssa_type.erl
@@ -2961,17 +2961,18 @@ join_types(Ts, Ts) ->
 join_types(LHS, RHS) ->
     if
         map_size(LHS) < map_size(RHS) ->
-            join_types_1(maps:keys(LHS), RHS, LHS);
+            join_types_1(maps:next(maps:iterator(LHS)), RHS, LHS);
         true ->
-            join_types_1(maps:keys(RHS), LHS, RHS)
+            join_types_1(maps:next(maps:iterator(RHS)), LHS, RHS)
     end.
 
 %% Joins two type maps, keeping the variables that are common to both maps.
-join_types_1([V | Vs], Bigger, Smaller) ->
-    case {Bigger, Smaller} of
-        {#{ V := Same }, #{ V := Same }} ->
-            join_types_1(Vs, Bigger, Smaller);
-        {#{ V := LHS0 }, #{ V := RHS0 }} ->
+join_types_1({V, RHS0, Iter0}, Bigger, Smaller) ->
+    Iter = maps:next(Iter0),
+    case Bigger of
+        #{V := RHS0} ->
+            join_types_1(Iter, Bigger, Smaller);
+        #{V := LHS0} ->
             %% Inlined concrete_type/2 for performance.
             LHS = case is_function(LHS0) of
                       true -> LHS0(Bigger);
@@ -2982,11 +2983,11 @@ join_types_1([V | Vs], Bigger, Smaller) ->
                       false -> RHS0
                   end,
             T = beam_types:join(LHS, RHS),
-            join_types_1(Vs, Bigger, Smaller#{ V := T });
-        {#{}, #{ V := _ }} ->
-            join_types_1(Vs, Bigger, maps:remove(V, Smaller))
+            join_types_1(Iter, Bigger, Smaller#{V := T});
+        #{} ->
+            join_types_1(Iter, Bigger, maps:remove(V, Smaller))
     end;
-join_types_1([], _Bigger, Smaller) ->
+join_types_1(none, _Bigger, Smaller) ->
     Smaller.
 
 meet_types([{#b_literal{}=Lit, T0} | Vs], Ts) ->
-- 
2.51.0

openSUSE Build Service is sponsored by