File 2101-compiler-Turn-is_lt-into-is_ge-if-possible.patch of Package erlang
From 55c15fe02b8dc9d40dd75ae19e2300c7d40f5ca7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Sun, 1 May 2022 07:31:37 +0200
Subject: [PATCH 1/3] compiler: Turn is_lt into is_ge if possible
This is not an optimization in itself but it reduces the number
of permutations of adjacent relational operators and thus will
simplify instruction combination optimizations for the JIT.
---
lib/compiler/src/beam_jump.erl | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl
index c961fdabf6..997fb2341e 100644
--- a/lib/compiler/src/beam_jump.erl
+++ b/lib/compiler/src/beam_jump.erl
@@ -605,20 +605,23 @@ find_fixpoint(OptFun, Is0) ->
opt([{test,is_eq_exact,{f,L},_}|[{jump,{f,L}}|_]=Is], Acc, St) ->
%% The is_eq_exact test is not needed.
opt(Is, Acc, St);
-opt([{test,Test0,{f,L}=Lbl,Ops}=I|[{jump,To}|Is]=Is0], Acc, St) ->
+opt([{test,Test0,{f,L}=Lbl,Ops}=I0|[{jump,To}|Is]=Is0], Acc, St) ->
case is_label_defined(Is, L) of
false ->
+ I = is_lt_to_is_ge(I0),
opt(Is0, [I|Acc], label_used(Lbl, St));
true ->
case invert_test(Test0) of
not_possible ->
+ I = is_lt_to_is_ge(I0),
opt(Is0, [I|Acc], label_used(Lbl, St));
Test ->
%% Invert the test and remove the jump.
opt([{test,Test,To,Ops}|Is], Acc, St)
end
end;
-opt([{test,_,{f,_}=Lbl,_}=I|Is], Acc, St) ->
+opt([{test,_,{f,_}=Lbl,_}=I0|Is], Acc, St) ->
+ I = is_lt_to_is_ge(I0),
opt(Is, [I|Acc], label_used(Lbl, St));
opt([{test,_,{f,_}=Lbl,_,_,_}=I|Is], Acc, St) ->
opt(Is, [I|Acc], label_used(Lbl, St));
@@ -679,6 +682,17 @@ opt([], Acc, #st{replace=Replace0}) when Replace0 =/= #{} ->
opt([], Acc, #st{replace=Replace}) when Replace =:= #{} ->
reverse(Acc).
+is_lt_to_is_ge({test,is_lt,Lbl,Args}=I) ->
+ case Args of
+ [{integer,N},{tr,_,#t_integer{}}=Src] ->
+ {test,is_ge,Lbl,[Src,{integer,N+1}]};
+ [{tr,_,#t_integer{}}=Src,{integer,N}] ->
+ {test,is_ge,Lbl,[{integer,N-1},Src]};
+ [_,_] ->
+ I
+ end;
+is_lt_to_is_ge(I) -> I.
+
prune_redundant_values([_Val,F|Vls], F) ->
prune_redundant_values(Vls, F);
prune_redundant_values([Val,Lbl|Vls], F) ->
--
2.35.3