Update to new TUPLE instruction
... and minor fixes
This commit is contained in:
parent
c045e5d653
commit
0409a658b0
@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
{erl_opts, [debug_info]}.
|
{erl_opts, [debug_info]}.
|
||||||
|
|
||||||
{deps, [ {aebytecode, {git, "https://github.com/aeternity/aebytecode.git",
|
{deps, [ {aebytecode, {git, "https://github.com/aeternity/aebytecode.git", {ref, "f129887"}}}
|
||||||
{ref, "241a96e"}}}
|
|
||||||
, {getopt, "1.0.1"}
|
, {getopt, "1.0.1"}
|
||||||
, {jsx, {git, "https://github.com/talentdeficit/jsx.git",
|
, {jsx, {git, "https://github.com/talentdeficit/jsx.git",
|
||||||
{tag, "2.8.0"}}}
|
{tag, "2.8.0"}}}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{"1.1.0",
|
{"1.1.0",
|
||||||
[{<<"aebytecode">>,
|
[{<<"aebytecode">>,
|
||||||
{git,"https://github.com/aeternity/aebytecode.git",
|
{git,"https://github.com/aeternity/aebytecode.git",
|
||||||
{ref,"241a96ebaa3e041781003cd20532a59ace87eb87"}},
|
{ref,"f1298870e526f4e9330447d3a281af5ef4e06e17"}},
|
||||||
0},
|
0},
|
||||||
{<<"aeserialization">>,
|
{<<"aeserialization">>,
|
||||||
{git,"https://github.com/aeternity/aeserialization.git",
|
{git,"https://github.com/aeternity/aeserialization.git",
|
||||||
|
@ -159,7 +159,7 @@ add_default_init_function(SFuns, {tuple, []}) ->
|
|||||||
SFuns;
|
SFuns;
|
||||||
error ->
|
error ->
|
||||||
Sig = {[], {tuple, []}},
|
Sig = {[], {tuple, []}},
|
||||||
Body = [aeb_fate_ops:tuple(0)],
|
Body = [tuple(0)],
|
||||||
SFuns#{ InitName => {Sig, Body} }
|
SFuns#{ InitName => {Sig, Body} }
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ to_scode(Env, {con, Ar, I, As}) ->
|
|||||||
to_scode(Env, {tuple, As}) ->
|
to_scode(Env, {tuple, As}) ->
|
||||||
N = length(As),
|
N = length(As),
|
||||||
[[ to_scode(notail(Env), A) || A <- As ],
|
[[ to_scode(notail(Env), A) || A <- As ],
|
||||||
aeb_fate_ops:tuple(N)];
|
tuple(N)];
|
||||||
|
|
||||||
to_scode(Env, {proj, E, I}) ->
|
to_scode(Env, {proj, E, I}) ->
|
||||||
[to_scode(notail(Env), E),
|
[to_scode(notail(Env), E),
|
||||||
@ -396,7 +396,7 @@ builtin_to_scode(_Env, get_state, []) ->
|
|||||||
[push(?s)];
|
[push(?s)];
|
||||||
builtin_to_scode(Env, set_state, [_] = Args) ->
|
builtin_to_scode(Env, set_state, [_] = Args) ->
|
||||||
call_to_scode(Env, [aeb_fate_ops:store(?s, ?a),
|
call_to_scode(Env, [aeb_fate_ops:store(?s, ?a),
|
||||||
aeb_fate_ops:tuple(0)], Args);
|
tuple(0)], Args);
|
||||||
builtin_to_scode(_Env, event, [_] = _Args) ->
|
builtin_to_scode(_Env, event, [_] = _Args) ->
|
||||||
?TODO(fate_event_instruction);
|
?TODO(fate_event_instruction);
|
||||||
builtin_to_scode(_Env, map_empty, []) ->
|
builtin_to_scode(_Env, map_empty, []) ->
|
||||||
@ -409,7 +409,7 @@ builtin_to_scode(Env, abort, [_] = Args) ->
|
|||||||
call_to_scode(Env, aeb_fate_ops:abort(?a), Args);
|
call_to_scode(Env, aeb_fate_ops:abort(?a), Args);
|
||||||
builtin_to_scode(Env, chain_spend, [_, _] = Args) ->
|
builtin_to_scode(Env, chain_spend, [_, _] = Args) ->
|
||||||
call_to_scode(Env, [aeb_fate_ops:spend(?a, ?a),
|
call_to_scode(Env, [aeb_fate_ops:spend(?a, ?a),
|
||||||
aeb_fate_ops:tuple(0)], Args);
|
tuple(0)], Args);
|
||||||
builtin_to_scode(Env, chain_balance, [_] = Args) ->
|
builtin_to_scode(Env, chain_balance, [_] = Args) ->
|
||||||
call_to_scode(Env, aeb_fate_ops:balance_other(?a, ?a), Args);
|
call_to_scode(Env, aeb_fate_ops:balance_other(?a, ?a), Args);
|
||||||
builtin_to_scode(Env, chain_block_hash, [_] = Args) ->
|
builtin_to_scode(Env, chain_block_hash, [_] = Args) ->
|
||||||
@ -516,6 +516,9 @@ op_to_scode(int_to_str) -> aeb_fate_ops:int_to_str(?a, ?a).
|
|||||||
%% easier, and specialize to PUSH (which is cheaper) at the end.
|
%% easier, and specialize to PUSH (which is cheaper) at the end.
|
||||||
push(A) -> aeb_fate_ops:store(?a, A).
|
push(A) -> aeb_fate_ops:store(?a, A).
|
||||||
|
|
||||||
|
tuple(0) -> push(?i({tuple, {}}));
|
||||||
|
tuple(N) -> aeb_fate_ops:tuple(?a, N).
|
||||||
|
|
||||||
%% -- Phase II ---------------------------------------------------------------
|
%% -- Phase II ---------------------------------------------------------------
|
||||||
%% Optimize
|
%% Optimize
|
||||||
|
|
||||||
@ -605,7 +608,7 @@ ann_writes([{switch, Arg, Type, Alts, Def} | Code], Writes, Acc) ->
|
|||||||
Writes1 = ordsets:union(Writes, ordsets:intersection([WritesDef | WritesAlts])),
|
Writes1 = ordsets:union(Writes, ordsets:intersection([WritesDef | WritesAlts])),
|
||||||
ann_writes(Code, Writes1, [{switch, Arg, Type, Alts1, Def1} | Acc]);
|
ann_writes(Code, Writes1, [{switch, Arg, Type, Alts1, Def1} | Acc]);
|
||||||
ann_writes([I | Code], Writes, Acc) ->
|
ann_writes([I | Code], Writes, Acc) ->
|
||||||
Ws = var_writes(I),
|
Ws = [ W || W <- var_writes(I), not ?IsState(W) ],
|
||||||
Writes1 = ordsets:union(Writes, Ws),
|
Writes1 = ordsets:union(Writes, Ws),
|
||||||
Ann = #{ writes_in => Writes, writes_out => Writes1 },
|
Ann = #{ writes_in => Writes, writes_out => Writes1 },
|
||||||
ann_writes(Code, Writes1, [{i, Ann, I} | Acc]);
|
ann_writes(Code, Writes1, [{i, Ann, I} | Acc]);
|
||||||
@ -662,13 +665,13 @@ attributes(I) ->
|
|||||||
{'SWITCH_V3', A, _, _, _} -> Impure(pc, A);
|
{'SWITCH_V3', A, _, _, _} -> Impure(pc, A);
|
||||||
{'SWITCH_VN', A, _} -> Impure(pc, A);
|
{'SWITCH_VN', A, _} -> Impure(pc, A);
|
||||||
{'PUSH', A} -> Pure(?a, A);
|
{'PUSH', A} -> Pure(?a, A);
|
||||||
'DUPA' -> Pure(?a, []);
|
'DUPA' -> Pure(?a, ?a);
|
||||||
{'DUP', A} -> Pure(?a, A);
|
{'DUP', A} -> Pure(?a, A);
|
||||||
{'POP', A} -> Pure(A, ?a);
|
{'POP', A} -> Pure(A, ?a);
|
||||||
{'STORE', A, B} -> Pure(A, B);
|
{'STORE', A, B} -> Pure(A, B);
|
||||||
'INCA' -> Pure(?a, ?a);
|
'INCA' -> Pure(?a, ?a);
|
||||||
{'INC', A} -> Pure(A, A);
|
{'INC', A} -> Pure(A, A);
|
||||||
'DECA' -> Pure(?a, []);
|
'DECA' -> Pure(?a, ?a);
|
||||||
{'DEC', A} -> Pure(A, A);
|
{'DEC', A} -> Pure(A, A);
|
||||||
{'ADD', A, B, C} -> Pure(A, [B, C]);
|
{'ADD', A, B, C} -> Pure(A, [B, C]);
|
||||||
{'SUB', A, B, C} -> Pure(A, [B, C]);
|
{'SUB', A, B, C} -> Pure(A, [B, C]);
|
||||||
@ -685,7 +688,7 @@ attributes(I) ->
|
|||||||
{'AND', A, B, C} -> Pure(A, [B, C]);
|
{'AND', A, B, C} -> Pure(A, [B, C]);
|
||||||
{'OR', A, B, C} -> Pure(A, [B, C]);
|
{'OR', A, B, C} -> Pure(A, [B, C]);
|
||||||
{'NOT', A, B} -> Pure(A, B);
|
{'NOT', A, B} -> Pure(A, B);
|
||||||
{'TUPLE', _} -> Pure(?a, []);
|
{'TUPLE', A, N} -> Pure(A, [?a || N > 0]);
|
||||||
{'ELEMENT', A, B, C} -> Pure(A, [B, C]);
|
{'ELEMENT', A, B, C} -> Pure(A, [B, C]);
|
||||||
{'SETELEMENT', A, B, C, D} -> Pure(A, [B, C, D]);
|
{'SETELEMENT', A, B, C, D} -> Pure(A, [B, C, D]);
|
||||||
{'MAP_EMPTY', A} -> Pure(A, []);
|
{'MAP_EMPTY', A} -> Pure(A, []);
|
||||||
@ -870,8 +873,7 @@ merge_rules() ->
|
|||||||
|
|
||||||
rules() ->
|
rules() ->
|
||||||
merge_rules() ++
|
merge_rules() ++
|
||||||
[?RULE(r_dup_to_push),
|
[?RULE(r_swap_push),
|
||||||
?RULE(r_swap_push),
|
|
||||||
?RULE(r_swap_write),
|
?RULE(r_swap_write),
|
||||||
?RULE(r_constant_propagation),
|
?RULE(r_constant_propagation),
|
||||||
?RULE(r_prune_impossible_branches),
|
?RULE(r_prune_impossible_branches),
|
||||||
@ -880,11 +882,6 @@ rules() ->
|
|||||||
].
|
].
|
||||||
|
|
||||||
%% Removing pushes that are immediately consumed.
|
%% Removing pushes that are immediately consumed.
|
||||||
r_push_consume({i, Ann1, {'STORE', ?a, A}}, [{i, Ann2, {'POP', B}} | Code]) ->
|
|
||||||
case live_out(B, Ann2) of
|
|
||||||
true -> {[{i, merge_ann(Ann1, Ann2), {'STORE', B, A}}], Code};
|
|
||||||
false -> {[], Code}
|
|
||||||
end;
|
|
||||||
r_push_consume({i, Ann1, {'STORE', ?a, A}}, Code) ->
|
r_push_consume({i, Ann1, {'STORE', ?a, A}}, Code) ->
|
||||||
inline_push(Ann1, A, 0, Code, []);
|
inline_push(Ann1, A, 0, Code, []);
|
||||||
%% Writing directly to memory instead of going through the accumulator.
|
%% Writing directly to memory instead of going through the accumulator.
|
||||||
@ -930,14 +927,6 @@ split_stack_arg(N, [A | As], Acc) ->
|
|||||||
true -> N end,
|
true -> N end,
|
||||||
split_stack_arg(N1, As, [A | Acc]).
|
split_stack_arg(N1, As, [A | Acc]).
|
||||||
|
|
||||||
%% Changing PUSH A, DUPA to PUSH A, PUSH A enables further optimisations
|
|
||||||
r_dup_to_push({i, Ann1, Push={'STORE', ?a, _}}, [{i, Ann2, 'DUPA'} | Code]) ->
|
|
||||||
#{ live_in := LiveIn } = Ann1,
|
|
||||||
Ann1_ = Ann1#{ live_out => LiveIn },
|
|
||||||
Ann2_ = Ann2#{ live_in => LiveIn },
|
|
||||||
{[{i, Ann1_, Push}, {i, Ann2_, Push}], Code};
|
|
||||||
r_dup_to_push(_, _) -> false.
|
|
||||||
|
|
||||||
%% Move PUSH A past non-stack instructions.
|
%% Move PUSH A past non-stack instructions.
|
||||||
r_swap_push(Push = {i, _, {'STORE', ?a, _}}, [I | Code]) ->
|
r_swap_push(Push = {i, _, {'STORE', ?a, _}}, [I | Code]) ->
|
||||||
case independent(Push, I) of
|
case independent(Push, I) of
|
||||||
|
Loading…
x
Reference in New Issue
Block a user