Skip to content

Commit c52cbd4

Browse files
committed
Move regs logic to jit_regs with maps backend
Signed-off-by: Paul Guyot <pguyot@kallisys.net>
1 parent a223458 commit c52cbd4

File tree

10 files changed

+558
-326
lines changed

10 files changed

+558
-326
lines changed

libs/jit/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ include(BuildErlang)
2525
set(ERLANG_MODULES
2626
jit
2727
jit_precompile
28+
jit_regs
2829
jit_stream_binary
2930
jit_stream_flash
3031
jit_stream_mmap

libs/jit/src/jit_aarch64.erl

Lines changed: 97 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136
branches :: [{non_neg_integer(), non_neg_integer(), non_neg_integer()}],
137137
jump_table_start :: non_neg_integer(),
138138
available_regs :: [aarch64_register()],
139-
used_regs :: [aarch64_register()],
139+
used_regs :: jit_regs:regs(),
140140
labels :: [{integer() | reference(), integer()}],
141141
variant :: non_neg_integer()
142142
}).
@@ -238,7 +238,7 @@ new(Variant, StreamModule, Stream) ->
238238
jump_table_start = 0,
239239
offset = StreamModule:offset(Stream),
240240
available_regs = ?AVAILABLE_REGS,
241-
used_regs = [],
241+
used_regs = jit_regs:new(),
242242
labels = [],
243243
variant = Variant
244244
}.
@@ -293,7 +293,7 @@ debugger(#state{stream_module = StreamModule, stream = Stream0} = State) ->
293293
%% @return The list of used registers
294294
%%-----------------------------------------------------------------------------
295295
-spec used_regs(state()) -> [aarch64_register()].
296-
used_regs(#state{used_regs = Used}) -> Used.
296+
used_regs(#state{used_regs = Used}) -> lists:sort(jit_regs:to_list(Used)).
297297

298298
%%-----------------------------------------------------------------------------
299299
%% @doc Return the list of currently available native scratch registers. This
@@ -343,7 +343,7 @@ free_native_register(State, _Other) ->
343343
%%-----------------------------------------------------------------------------
344344
-spec assert_all_native_free(state()) -> ok.
345345
assert_all_native_free(#state{
346-
available_regs = ?AVAILABLE_REGS, used_regs = []
346+
available_regs = ?AVAILABLE_REGS, used_regs = #{}
347347
}) ->
348348
ok.
349349

@@ -508,7 +508,7 @@ call_primitive_last(
508508
ArgsRegs = args_regs(Args),
509509
ScratchRegs = ?AVAILABLE_REGS -- ArgsRegs -- ParamRegs,
510510
[Temp | AvailableRegs1] = ScratchRegs,
511-
UsedRegs = ?AVAILABLE_REGS -- AvailableRegs1,
511+
UsedRegs = jit_regs:from_list(?AVAILABLE_REGS -- AvailableRegs1),
512512
PrepCall =
513513
case Primitive of
514514
0 ->
@@ -526,7 +526,7 @@ call_primitive_last(
526526
#state{stream = Stream2} = State1,
527527
Call = jit_aarch64_asm:br(Temp),
528528
Stream3 = StreamModule:append(Stream2, Call),
529-
State1#state{stream = Stream3, available_regs = ?AVAILABLE_REGS, used_regs = []}.
529+
State1#state{stream = Stream3, available_regs = ?AVAILABLE_REGS, used_regs = jit_regs:new()}.
530530

531531
%%-----------------------------------------------------------------------------
532532
%% @doc Emit a return of a value if it's not equal to ctx.
@@ -634,7 +634,7 @@ jump_to_continuation(
634634
Code = <<I1/binary, I2/binary, I3/binary>>,
635635
Stream1 = StreamModule:append(Stream0, Code),
636636
% Free all registers since this is a tail jump
637-
State#state{stream = Stream1, available_regs = ?AVAILABLE_REGS, used_regs = []}.
637+
State#state{stream = Stream1, available_regs = ?AVAILABLE_REGS, used_regs = jit_regs:new()}.
638638

639639
%% @private
640640
-spec rewrite_branch_instruction(
@@ -1064,22 +1064,24 @@ if_block_free_reg(Reg, State0) when ?IS_GPR(Reg) ->
10641064
State0.
10651065

10661066
%% @private
1067-
-spec merge_used_regs(state(), [aarch64_register()]) -> state().
1068-
merge_used_regs(#state{used_regs = UR0, available_regs = AvR0} = State, [
1069-
Reg | T
1070-
]) ->
1071-
case lists:member(Reg, UR0) of
1072-
true ->
1073-
merge_used_regs(State, T);
1074-
false ->
1075-
AvR1 = lists:delete(Reg, AvR0),
1076-
UR1 = [Reg | UR0],
1077-
merge_used_regs(
1078-
State#state{used_regs = UR1, available_regs = AvR1}, T
1079-
)
1080-
end;
1081-
merge_used_regs(State, []) ->
1082-
State.
1067+
-spec merge_used_regs(state(), jit_regs:regs()) -> state().
1068+
merge_used_regs(State, OtherRegs) ->
1069+
maps:fold(
1070+
fun(Reg, _, AccState) ->
1071+
#state{used_regs = UR, available_regs = AvR} = AccState,
1072+
case jit_regs:is_used(UR, Reg) of
1073+
true ->
1074+
AccState;
1075+
false ->
1076+
AccState#state{
1077+
used_regs = jit_regs:add(UR, Reg),
1078+
available_regs = lists:delete(Reg, AvR)
1079+
}
1080+
end
1081+
end,
1082+
State,
1083+
OtherRegs
1084+
).
10831085

10841086
%%-----------------------------------------------------------------------------
10851087
%% @doc Emit a shift register right by a fixed number of bits, effectively
@@ -1111,7 +1113,10 @@ shift_right(
11111113
->
11121114
I = jit_aarch64_asm:lsr(ResultReg, Reg, Shift),
11131115
Stream1 = StreamModule:append(Stream0, I),
1114-
{State#state{stream = Stream1, available_regs = T, used_regs = [ResultReg | UR]}, ResultReg}.
1116+
{
1117+
State#state{stream = Stream1, available_regs = T, used_regs = jit_regs:add(UR, ResultReg)},
1118+
ResultReg
1119+
}.
11151120

11161121
%%-----------------------------------------------------------------------------
11171122
%% @doc Emit a shift register left by a fixed number of bits, effectively
@@ -1159,8 +1164,9 @@ call_func_ptr(
11591164
end,
11601165
[FuncPtrTuple | Args]
11611166
),
1162-
UsedRegs1 = UsedRegs0 -- FreeRegs,
1163-
SavedRegs = [?LR_REG, ?CTX_REG, ?JITSTATE_REG, ?NATIVE_INTERFACE_REG | UsedRegs1],
1167+
UsedRegs1 = jit_regs:without(UsedRegs0, FreeRegs),
1168+
UsedRegsList = [R || R <- lists:reverse(?AVAILABLE_REGS), jit_regs:is_used(UsedRegs1, R)],
1169+
SavedRegs = [?LR_REG, ?CTX_REG, ?JITSTATE_REG, ?NATIVE_INTERFACE_REG | UsedRegsList],
11641170
{SavedRegsOdd, Stream1} = push_registers(SavedRegs, StreamModule, Stream0),
11651171

11661172
% Set up arguments following AArch64 calling convention
@@ -1201,9 +1207,8 @@ call_func_ptr(
12011207

12021208
Stream6 = pop_registers(SavedRegsOdd, lists:reverse(SavedRegs), StreamModule, Stream5),
12031209

1204-
AvailableRegs2 = lists:delete(ResultReg, AvailableRegs1),
1205-
AvailableRegs3 = ?AVAILABLE_REGS -- (?AVAILABLE_REGS -- AvailableRegs2),
1206-
UsedRegs2 = [ResultReg | UsedRegs1],
1210+
UsedRegs2 = jit_regs:add(UsedRegs1, ResultReg),
1211+
AvailableRegs3 = jit_regs:available(?AVAILABLE_REGS, UsedRegs2),
12071212
{
12081213
State1#state{
12091214
stream = Stream6,
@@ -1244,7 +1249,13 @@ set_args(
12441249
ParamRegs = parameter_regs(Args),
12451250
ArgsRegs = args_regs(Args),
12461251
AvailableScratchGP =
1247-
?SCRATCH_REGS -- ParamRegs -- ArgsRegs -- UsedRegs,
1252+
[
1253+
R
1254+
|| R <- ?SCRATCH_REGS,
1255+
not lists:member(R, ParamRegs),
1256+
not lists:member(R, ArgsRegs),
1257+
not jit_regs:is_used(UsedRegs, R)
1258+
],
12481259
Offset = StreamModule:offset(Stream0),
12491260
Args1 = [
12501261
case Arg of
@@ -1257,17 +1268,22 @@ set_args(
12571268
Stream1 = StreamModule:append(Stream0, SetArgsCode),
12581269
NewUsedRegs = lists:foldl(
12591270
fun
1260-
({free, {ptr, Reg}}, AccUsed) -> lists:delete(Reg, AccUsed);
1261-
({free, Reg}, AccUsed) -> lists:delete(Reg, AccUsed);
1271+
({free, {ptr, Reg}}, AccUsed) -> jit_regs:remove(AccUsed, Reg);
1272+
({free, Reg}, AccUsed) -> jit_regs:remove(AccUsed, Reg);
12621273
(_, AccUsed) -> AccUsed
12631274
end,
12641275
UsedRegs,
12651276
Args
12661277
),
12671278
State0#state{
12681279
stream = Stream1,
1269-
available_regs = ?AVAILABLE_REGS -- ParamRegs -- NewUsedRegs,
1270-
used_regs = ParamRegs ++ (NewUsedRegs -- ParamRegs)
1280+
available_regs = [
1281+
R
1282+
|| R <- ?AVAILABLE_REGS,
1283+
not lists:member(R, ParamRegs),
1284+
not jit_regs:is_used(NewUsedRegs, R)
1285+
],
1286+
used_regs = jit_regs:merge(NewUsedRegs, ParamRegs)
12711287
}.
12721288

12731289
%% @private
@@ -1628,7 +1644,9 @@ get_array_element(
16281644
Stream1 = StreamModule:append(Stream0, <<I1/binary>>),
16291645
{
16301646
State#state{
1631-
stream = Stream1, available_regs = AvailableT, used_regs = [ElemReg | UsedRegs0]
1647+
stream = Stream1,
1648+
available_regs = AvailableT,
1649+
used_regs = jit_regs:add(UsedRegs0, ElemReg)
16321650
},
16331651
ElemReg
16341652
}.
@@ -1743,7 +1761,10 @@ move_to_native_register(
17431761
) ->
17441762
I1 = jit_aarch64_asm:ldr(Reg, ?CP),
17451763
Stream1 = StreamModule:append(Stream0, I1),
1746-
{State#state{stream = Stream1, used_regs = [Reg | Used], available_regs = AvailT}, Reg};
1764+
{
1765+
State#state{stream = Stream1, used_regs = jit_regs:add(Used, Reg), available_regs = AvailT},
1766+
Reg
1767+
};
17471768
move_to_native_register(State, Reg) when is_atom(Reg) ->
17481769
{State, Reg};
17491770
move_to_native_register(
@@ -1765,7 +1786,10 @@ move_to_native_register(
17651786
->
17661787
I1 = jit_aarch64_asm:mov(Reg, Imm),
17671788
Stream1 = StreamModule:append(Stream0, I1),
1768-
{State#state{stream = Stream1, used_regs = [Reg | Used], available_regs = AvailT}, Reg};
1789+
{
1790+
State#state{stream = Stream1, used_regs = jit_regs:add(Used, Reg), available_regs = AvailT},
1791+
Reg
1792+
};
17691793
move_to_native_register(
17701794
#state{
17711795
stream_module = StreamModule,
@@ -1777,7 +1801,10 @@ move_to_native_register(
17771801
) ->
17781802
I1 = jit_aarch64_asm:ldr(Reg, ?X_REG(?MAX_REG)),
17791803
Stream1 = StreamModule:append(Stream0, I1),
1780-
{State#state{stream = Stream1, used_regs = [Reg | Used], available_regs = AvailT}, Reg};
1804+
{
1805+
State#state{stream = Stream1, used_regs = jit_regs:add(Used, Reg), available_regs = AvailT},
1806+
Reg
1807+
};
17811808
move_to_native_register(
17821809
#state{
17831810
stream_module = StreamModule,
@@ -1791,7 +1818,10 @@ move_to_native_register(
17911818
->
17921819
I1 = jit_aarch64_asm:ldr(Reg, ?X_REG(X)),
17931820
Stream1 = StreamModule:append(Stream0, I1),
1794-
{State#state{stream = Stream1, used_regs = [Reg | Used], available_regs = AvailT}, Reg};
1821+
{
1822+
State#state{stream = Stream1, used_regs = jit_regs:add(Used, Reg), available_regs = AvailT},
1823+
Reg
1824+
};
17951825
move_to_native_register(
17961826
#state{
17971827
stream_module = StreamModule,
@@ -1805,7 +1835,10 @@ move_to_native_register(
18051835
I2 = jit_aarch64_asm:ldr(Reg, {Reg, Y * ?WORD_SIZE}),
18061836
Code = <<I1/binary, I2/binary>>,
18071837
Stream1 = StreamModule:append(Stream0, Code),
1808-
{State#state{stream = Stream1, available_regs = AvailT, used_regs = [Reg | Used]}, Reg}.
1838+
{
1839+
State#state{stream = Stream1, available_regs = AvailT, used_regs = jit_regs:add(Used, Reg)},
1840+
Reg
1841+
}.
18091842

18101843
%%-----------------------------------------------------------------------------
18111844
%% @doc Move a value (integer, vm register, pointer or native register) to a
@@ -1873,7 +1906,12 @@ copy_to_native_register(
18731906
) when is_atom(Reg) ->
18741907
I1 = jit_aarch64_asm:mov(SaveReg, Reg),
18751908
Stream1 = StreamModule:append(Stream0, I1),
1876-
{State#state{stream = Stream1, available_regs = AvailT, used_regs = [SaveReg | Used]}, SaveReg};
1909+
{
1910+
State#state{
1911+
stream = Stream1, available_regs = AvailT, used_regs = jit_regs:add(Used, SaveReg)
1912+
},
1913+
SaveReg
1914+
};
18771915
copy_to_native_register(
18781916
#state{
18791917
stream_module = StreamModule,
@@ -1885,7 +1923,12 @@ copy_to_native_register(
18851923
) when is_atom(Reg) ->
18861924
I1 = jit_aarch64_asm:ldr(SaveReg, {Reg, 0}),
18871925
Stream1 = StreamModule:append(Stream0, I1),
1888-
{State#state{stream = Stream1, available_regs = AvailT, used_regs = [SaveReg | Used]}, SaveReg};
1926+
{
1927+
State#state{
1928+
stream = Stream1, available_regs = AvailT, used_regs = jit_regs:add(Used, SaveReg)
1929+
},
1930+
SaveReg
1931+
};
18891932
copy_to_native_register(State, Reg) ->
18901933
move_to_native_register(State, Reg).
18911934

@@ -2024,7 +2067,9 @@ get_module_index(
20242067
Code = <<I1/binary, I2/binary>>,
20252068
Stream1 = StreamModule:append(Stream0, Code),
20262069
{
2027-
State#state{stream = Stream1, available_regs = AvailableT, used_regs = [Reg | UsedRegs0]},
2070+
State#state{
2071+
stream = Stream1, available_regs = AvailableT, used_regs = jit_regs:add(UsedRegs0, Reg)
2072+
},
20282073
Reg
20292074
}.
20302075

@@ -2073,7 +2118,11 @@ and_(
20732118
Val
20742119
) ->
20752120
NewState = op_imm(
2076-
State#state{available_regs = T, used_regs = [ResultReg | UR]}, and_, ResultReg, Reg, Val
2121+
State#state{available_regs = T, used_regs = jit_regs:add(UR, ResultReg)},
2122+
and_,
2123+
ResultReg,
2124+
Reg,
2125+
Val
20772126
),
20782127
{NewState, ResultReg}.
20792128

@@ -2395,22 +2444,12 @@ return_labels_and_lines(
23952444
%% @private
23962445
-spec free_reg([aarch64_register()], [aarch64_register()], aarch64_register()) ->
23972446
{[aarch64_register()], [aarch64_register()]}.
2398-
free_reg(AvailableRegs0, UsedRegs0, Reg) when ?IS_GPR(Reg) ->
2399-
AvailableRegs1 = free_reg0(?AVAILABLE_REGS, AvailableRegs0, Reg, []),
2400-
true = lists:member(Reg, UsedRegs0),
2401-
UsedRegs1 = lists:delete(Reg, UsedRegs0),
2447+
free_reg(_AvailableRegs0, UsedRegs0, Reg) when ?IS_GPR(Reg) ->
2448+
true = jit_regs:is_used(UsedRegs0, Reg),
2449+
UsedRegs1 = jit_regs:remove(UsedRegs0, Reg),
2450+
AvailableRegs1 = jit_regs:available(?AVAILABLE_REGS, UsedRegs1),
24022451
{AvailableRegs1, UsedRegs1}.
24032452

2404-
%% @private
2405-
-spec free_reg0([aarch64_register()], [aarch64_register()], aarch64_register(), [aarch64_register()]) ->
2406-
[aarch64_register()].
2407-
free_reg0([Reg | _SortedT], PrevRegs0, Reg, Acc) ->
2408-
lists:reverse(Acc, [Reg | PrevRegs0]);
2409-
free_reg0([PrevReg | SortedT], [PrevReg | PrevT], Reg, Acc) ->
2410-
free_reg0(SortedT, PrevT, Reg, [PrevReg | Acc]);
2411-
free_reg0([_Other | SortedT], PrevRegs, Reg, Acc) ->
2412-
free_reg0(SortedT, PrevRegs, Reg, Acc).
2413-
24142453
%% @private
24152454
-spec args_regs([arg()]) -> [aarch64_register() | imm].
24162455
args_regs(Args) ->

0 commit comments

Comments
 (0)