diff options
author | Magnus Lång <[email protected]> | 2016-10-02 13:18:51 +0200 |
---|---|---|
committer | Magnus Lång <[email protected]> | 2016-11-15 14:59:00 +0100 |
commit | 921638f8b22479473482bdcaa25f8031ac85e7e8 (patch) | |
tree | 6aa26ac07bd3cbfe39eaf9f34bfdc5a2d5d45bb5 /lib | |
parent | df04801d5585f52ddc042d30873bdc95da019af6 (diff) | |
download | otp-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')
-rw-r--r-- | lib/hipe/x86/hipe_rtl_to_x86.erl | 14 | ||||
-rw-r--r-- | lib/hipe/x86/hipe_x86.erl | 4 |
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. |