Skip to content

Commit 186cabd

Browse files
committed
JIT: optimize shift_right for platforms with 3 operands
Signed-off-by: Paul Guyot <pguyot@kallisys.net>
1 parent 88b87ca commit 186cabd

File tree

7 files changed

+235
-132
lines changed

7 files changed

+235
-132
lines changed

libs/jit/src/jit.erl

Lines changed: 92 additions & 92 deletions
Large diffs are not rendered by default.

libs/jit/src/jit_aarch64.erl

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -983,13 +983,29 @@ merge_used_regs(State, []) ->
983983
%% @param Shift number of bits to shift
984984
%% @return new state
985985
%%-----------------------------------------------------------------------------
986-
-spec shift_right(state(), aarch64_register(), non_neg_integer()) -> state().
987-
shift_right(#state{stream_module = StreamModule, stream = Stream0} = State, Reg, Shift) when
986+
-spec shift_right(#state{}, maybe_free_aarch64_register(), non_neg_integer()) ->
987+
{#state{}, aarch64_register()}.
988+
shift_right(#state{stream_module = StreamModule, stream = Stream0} = State, {free, Reg}, Shift) when
988989
?IS_GPR(Reg) andalso is_integer(Shift)
989990
->
990991
I = jit_aarch64_asm:lsr(Reg, Reg, Shift),
991992
Stream1 = StreamModule:append(Stream0, I),
992-
State#state{stream = Stream1}.
993+
{State#state{stream = Stream1}, Reg};
994+
shift_right(
995+
#state{
996+
stream_module = StreamModule,
997+
stream = Stream0,
998+
available_regs = [ResultReg | T],
999+
used_regs = UR
1000+
} = State,
1001+
Reg,
1002+
Shift
1003+
) when
1004+
?IS_GPR(Reg) andalso is_integer(Shift)
1005+
->
1006+
I = jit_aarch64_asm:lsr(ResultReg, Reg, Shift),
1007+
Stream1 = StreamModule:append(Stream0, I),
1008+
{State#state{stream = Stream1, available_regs = T, used_regs = [ResultReg | UR]}, ResultReg}.
9931009

9941010
%%-----------------------------------------------------------------------------
9951011
%% @doc Emit a shift register left by a fixed number of bits, effectively

libs/jit/src/jit_armv6m.erl

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,12 +1381,29 @@ merge_used_regs(State, []) ->
13811381
%% @param Shift number of bits to shift
13821382
%% @return new state
13831383
%%-----------------------------------------------------------------------------
1384-
shift_right(#state{stream_module = StreamModule, stream = Stream0} = State, Reg, Shift) when
1384+
-spec shift_right(#state{}, maybe_free_armv6m_register(), non_neg_integer()) ->
1385+
{#state{}, armv6m_register()}.
1386+
shift_right(#state{stream_module = StreamModule, stream = Stream0} = State, {free, Reg}, Shift) when
13851387
?IS_GPR(Reg) andalso is_integer(Shift)
13861388
->
13871389
I = jit_armv6m_asm:lsrs(Reg, Reg, Shift),
13881390
Stream1 = StreamModule:append(Stream0, I),
1389-
State#state{stream = Stream1}.
1391+
{State#state{stream = Stream1}, Reg};
1392+
shift_right(
1393+
#state{
1394+
stream_module = StreamModule,
1395+
stream = Stream0,
1396+
available_regs = [ResultReg | T],
1397+
used_regs = UR
1398+
} = State,
1399+
Reg,
1400+
Shift
1401+
) when
1402+
?IS_GPR(Reg) andalso is_integer(Shift)
1403+
->
1404+
I = jit_armv6m_asm:lsrs(ResultReg, Reg, Shift),
1405+
Stream1 = StreamModule:append(Stream0, I),
1406+
{State#state{stream = Stream1, available_regs = T, used_regs = [ResultReg | UR]}, ResultReg}.
13901407

13911408
%%-----------------------------------------------------------------------------
13921409
%% @doc Emit a shift register left by a fixed number of bits, effectively

libs/jit/src/jit_x86_64.erl

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -877,12 +877,30 @@ merge_used_regs(State, []) ->
877877
%% @param Shift number of bits to shift
878878
%% @return new state
879879
%%-----------------------------------------------------------------------------
880-
shift_right(#state{stream_module = StreamModule, stream = Stream0} = State, Reg, Shift) when
880+
-spec shift_right(#state{}, maybe_free_x86_64_register(), non_neg_integer()) ->
881+
{#state{}, x86_64_register()}.
882+
shift_right(#state{stream_module = StreamModule, stream = Stream0} = State, {free, Reg}, Shift) when
881883
?IS_GPR(Reg) andalso is_integer(Shift)
882884
->
883885
I = jit_x86_64_asm:shrq(Shift, Reg),
884886
Stream1 = StreamModule:append(Stream0, I),
885-
State#state{stream = Stream1}.
887+
{State#state{stream = Stream1}, Reg};
888+
shift_right(
889+
#state{
890+
stream_module = StreamModule,
891+
available_regs = [ResultReg | T],
892+
used_regs = UR,
893+
stream = Stream0
894+
} = State,
895+
Reg,
896+
Shift
897+
) when
898+
?IS_GPR(Reg) andalso is_integer(Shift)
899+
->
900+
I1 = jit_x86_64_asm:movq(Reg, ResultReg),
901+
I2 = jit_x86_64_asm:shrq(Shift, ResultReg),
902+
Stream1 = StreamModule:append(Stream0, <<I1/binary, I2/binary>>),
903+
{State#state{stream = Stream1, available_regs = T, used_regs = [ResultReg | UR]}, ResultReg}.
886904

887905
%%-----------------------------------------------------------------------------
888906
%% @doc Emit a shift register left by a fixed number of bits, effectively

tests/libs/jit/jit_aarch64_tests.erl

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -760,17 +760,34 @@ if_else_block_test() ->
760760
>>,
761761
?assertEqual(dump_to_bin(Dump), Stream).
762762

763-
shift_right_test() ->
764-
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
765-
{State1, Reg} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}),
766-
State2 = ?BACKEND:shift_right(State1, Reg, 3),
767-
Stream = ?BACKEND:stream(State2),
768-
Dump =
769-
<<
770-
" 0: f9401807 ldr x7, [x0, #48]\n"
771-
" 4: d343fce7 lsr x7, x7, #3"
772-
>>,
773-
?assertEqual(dump_to_bin(Dump), Stream).
763+
shift_right_test_() ->
764+
[
765+
?_test(begin
766+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
767+
{State1, Reg} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}),
768+
{State2, Reg} = ?BACKEND:shift_right(State1, {free, Reg}, 3),
769+
Stream = ?BACKEND:stream(State2),
770+
Dump =
771+
<<
772+
" 0: f9401807 ldr x7, [x0, #48]\n"
773+
" 4: d343fce7 lsr x7, x7, #3"
774+
>>,
775+
?assertEqual(dump_to_bin(Dump), Stream)
776+
end),
777+
?_test(begin
778+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
779+
{State1, Reg} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}),
780+
{State2, OtherReg} = ?BACKEND:shift_right(State1, Reg, 3),
781+
?assertNotEqual(OtherReg, Reg),
782+
Stream = ?BACKEND:stream(State2),
783+
Dump =
784+
<<
785+
" 0: f9401807 ldr x7, [x0, #48]\n"
786+
" 4: d343fce8 lsr x8, x7, #3"
787+
>>,
788+
?assertEqual(dump_to_bin(Dump), Stream)
789+
end)
790+
].
774791

775792
shift_left_test() ->
776793
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),

tests/libs/jit/jit_armv6m_tests.erl

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,17 +1183,34 @@ if_else_block_test() ->
11831183
>>,
11841184
?assertEqual(dump_to_bin(Dump), Stream).
11851185

1186-
shift_right_test() ->
1187-
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
1188-
{State1, Reg} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}),
1189-
State2 = ?BACKEND:shift_right(State1, Reg, 3),
1190-
Stream = ?BACKEND:stream(State2),
1191-
Dump =
1192-
<<
1193-
" 0: 6987 ldr r7, [r0, #24]\n"
1194-
" 2: 08ff lsrs r7, r7, #3"
1195-
>>,
1196-
?assertEqual(dump_to_bin(Dump), Stream).
1186+
shift_right_test_() ->
1187+
[
1188+
?_test(begin
1189+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
1190+
{State1, Reg} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}),
1191+
{State2, Reg} = ?BACKEND:shift_right(State1, {free, Reg}, 3),
1192+
Stream = ?BACKEND:stream(State2),
1193+
Dump =
1194+
<<
1195+
" 0: 6987 ldr r7, [r0, #24]\n"
1196+
" 2: 08ff lsrs r7, r7, #3"
1197+
>>,
1198+
?assertEqual(dump_to_bin(Dump), Stream)
1199+
end),
1200+
?_test(begin
1201+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
1202+
{State1, Reg} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}),
1203+
{State2, OtherReg} = ?BACKEND:shift_right(State1, Reg, 3),
1204+
?assertNotEqual(OtherReg, Reg),
1205+
Stream = ?BACKEND:stream(State2),
1206+
Dump =
1207+
<<
1208+
" 0: 6987 ldr r7, [r0, #24]\n"
1209+
" 2: 08fe lsrs r6, r7, #3"
1210+
>>,
1211+
?assertEqual(dump_to_bin(Dump), Stream)
1212+
end)
1213+
].
11971214

11981215
shift_left_test() ->
11991216
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),

tests/libs/jit/jit_x86_64_tests.erl

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -820,17 +820,35 @@ if_else_block_test() ->
820820
>>,
821821
?assertEqual(dump_to_bin(Dump), Stream).
822822

823-
shift_right_test() ->
824-
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
825-
{State1, Reg} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}),
826-
State2 = ?BACKEND:shift_right(State1, Reg, 3),
827-
Stream = ?BACKEND:stream(State2),
828-
Dump =
829-
<<
830-
" 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n"
831-
" 4: 48 c1 e8 03 shr $0x3,%rax"
832-
>>,
833-
?assertEqual(dump_to_bin(Dump), Stream).
823+
shift_right_test_() ->
824+
[
825+
?_test(begin
826+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
827+
{State1, Reg} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}),
828+
{State2, Reg} = ?BACKEND:shift_right(State1, {free, Reg}, 3),
829+
Stream = ?BACKEND:stream(State2),
830+
Dump =
831+
<<
832+
" 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n"
833+
" 4: 48 c1 e8 03 shr $0x3,%rax"
834+
>>,
835+
?assertEqual(dump_to_bin(Dump), Stream)
836+
end),
837+
?_test(begin
838+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
839+
{State1, Reg} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}),
840+
{State2, OtherReg} = ?BACKEND:shift_right(State1, Reg, 3),
841+
?assertNotEqual(OtherReg, Reg),
842+
Stream = ?BACKEND:stream(State2),
843+
Dump =
844+
<<
845+
" 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n"
846+
" 4: 49 89 c3 mov %rax,%r11\n"
847+
" 7: 49 c1 eb 03 shr $0x3,%r11"
848+
>>,
849+
?assertEqual(dump_to_bin(Dump), Stream)
850+
end)
851+
].
834852

835853
shift_left_test() ->
836854
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),

0 commit comments

Comments
 (0)