aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe
diff options
context:
space:
mode:
authorMagnus Lång <[email protected]>2016-10-02 13:18:51 +0200
committerMagnus Lång <[email protected]>2016-11-15 14:59:00 +0100
commit921638f8b22479473482bdcaa25f8031ac85e7e8 (patch)
tree6aa26ac07bd3cbfe39eaf9f34bfdc5a2d5d45bb5 /lib/hipe
parentdf04801d5585f52ddc042d30873bdc95da019af6 (diff)
downloadotp-921638f8b22479473482bdcaa25f8031ac85e7e8.tar.gz
otp-921638f8b22479473482bdcaa25f8031ac85e7e8.tar.bz2
otp-921638f8b22479473482bdcaa25f8031ac85e7e8.zip
hipe_rtl_to_x86: Use LEA only for immediate adds
It seems that most 3-address adds of temps can be move coalesced. Therefore, we limit the behaviour added by 1567585dda8 to only affect immediate adds. Also, add conversion of immediate mov+sub to lea.
Diffstat (limited to 'lib/hipe')
-rw-r--r--lib/hipe/x86/hipe_rtl_to_x86.erl14
-rw-r--r--lib/hipe/x86/hipe_x86.erl4
2 files changed, 15 insertions, 3 deletions
diff --git a/lib/hipe/x86/hipe_rtl_to_x86.erl b/lib/hipe/x86/hipe_rtl_to_x86.erl
index ccb9b7632b..851b7da2dd 100644
--- a/lib/hipe/x86/hipe_rtl_to_x86.erl
+++ b/lib/hipe/x86/hipe_rtl_to_x86.erl
@@ -257,7 +257,9 @@ conv_insn(I, Map, Data) ->
conv_alu_nocc(Dst, Src1, 'add', Src2, Tail) ->
case (not same_opnd(Dst, Src1)) andalso (not same_opnd(Dst, Src2))
- andalso (hipe_x86:is_temp(Src1) orelse hipe_x86:is_temp(Src2))
+ %% We could use orelse instead of xor here to generate lea T1(T2), T3, but
+ %% they seem to move coalesce so well that move+add is better for them.
+ andalso (hipe_x86:is_temp(Src1) xor hipe_x86:is_temp(Src2))
of
false -> conv_alu(Dst, Src1, 'add', Src2, Tail);
true -> % Use LEA
@@ -268,6 +270,16 @@ conv_alu_nocc(Dst, Src1, 'add', Src2, Tail) ->
end,
[hipe_x86:mk_lea(Mem, Dst) | Tail]
end;
+conv_alu_nocc(Dst, Src1, 'sub', Src2, Tail) ->
+ case (not same_opnd(Dst, Src1)) andalso hipe_x86:is_temp(Src1)
+ andalso (not hipe_x86:is_temp(Src2))
+ of
+ false -> conv_alu(Dst, Src1, 'sub', Src2, Tail);
+ true -> % Use LEA
+ Imm = hipe_x86:mk_imm(-hipe_x86:imm_value(Src2)),
+ Mem = hipe_x86:mk_mem(Src1, Imm, typeof_dst(Dst)),
+ [hipe_x86:mk_lea(Mem, Dst) | Tail]
+ end;
conv_alu_nocc(Dst, Src1, BinOp, Src2, Tail) ->
conv_alu(Dst, Src1, BinOp, Src2, Tail).
diff --git a/lib/hipe/x86/hipe_x86.erl b/lib/hipe/x86/hipe_x86.erl
index e7c4497cda..95af3f9c67 100644
--- a/lib/hipe/x86/hipe_x86.erl
+++ b/lib/hipe/x86/hipe_x86.erl
@@ -37,7 +37,7 @@
mk_imm_from_addr/2,
mk_imm_from_atom/1,
is_imm/1,
- %% imm_value/1,
+ imm_value/1,
mk_mem/3,
%% is_mem/1,
@@ -241,7 +241,7 @@ mk_imm_from_addr(Addr, Type) ->
mk_imm_from_atom(Atom) ->
mk_imm(Atom).
is_imm(X) -> case X of #x86_imm{} -> true; _ -> false end.
-%% imm_value(#x86_imm{value=Value}) -> Value.
+imm_value(#x86_imm{value=Value}) -> Value.
mk_mem(Base, Off, Type) -> #x86_mem{base=Base, off=Off, type=Type}.
%% is_mem(X) -> case X of #x86_mem{} -> true; _ -> false end.