aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe
diff options
context:
space:
mode:
authorMagnus Lång <[email protected]>2016-11-13 11:12:24 +0100
committerMagnus Lång <[email protected]>2016-11-16 17:22:04 +0100
commit40b7dc3ce63999a6e8d40c20a098de6d85676aeb (patch)
tree9ccb1538024162f9512fed031016f3640c525290 /lib/hipe
parente98df8fac977350b56319df621c65a823bfe86f4 (diff)
downloadotp-40b7dc3ce63999a6e8d40c20a098de6d85676aeb.tar.gz
otp-40b7dc3ce63999a6e8d40c20a098de6d85676aeb.tar.bz2
otp-40b7dc3ce63999a6e8d40c20a098de6d85676aeb.zip
hipe_tagscheme: x86 lea+test for mask_and_compare
By changing mask_and_compare from and,sub to sub,and, x86 can use a 3-address LEA immediate add, saving a mov. The RISC backends should see no change in sequence length. We make test_(heap_|sub)binary use mask_and_compare so they will benefit too.
Diffstat (limited to 'lib/hipe')
-rw-r--r--lib/hipe/rtl/hipe_tagscheme.erl24
1 files changed, 11 insertions, 13 deletions
diff --git a/lib/hipe/rtl/hipe_tagscheme.erl b/lib/hipe/rtl/hipe_tagscheme.erl
index 1d9861da7a..566a28cd59 100644
--- a/lib/hipe/rtl/hipe_tagscheme.erl
+++ b/lib/hipe/rtl/hipe_tagscheme.erl
@@ -183,8 +183,9 @@ get_header(Res, X) ->
mask_and_compare(X, Mask, Value, TrueLab, FalseLab, Pred) ->
Tmp = hipe_rtl:mk_new_reg_gcsafe(),
- [hipe_rtl:mk_alu(Tmp, X, 'and', hipe_rtl:mk_imm(Mask)),
- hipe_rtl:mk_branch(Tmp, 'eq', hipe_rtl:mk_imm(Value), TrueLab, FalseLab, Pred)].
+ [hipe_rtl:mk_alu(Tmp, X, 'sub', hipe_rtl:mk_imm(Value)),
+ hipe_rtl:mk_branch(Tmp, 'and', hipe_rtl:mk_imm(Mask),
+ eq, TrueLab, FalseLab, Pred)].
test_immed1(X, Value, TrueLab, FalseLab, Pred) ->
mask_and_compare(X, ?TAG_IMMED1_MASK, Value, TrueLab, FalseLab, Pred).
@@ -886,12 +887,10 @@ heap_arch_spec(HP) ->
hipe_rtl_arch:pcb_store(?P_OFF_HEAP_FIRST, HP)].
test_heap_binary(Binary, TrueLblName, FalseLblName) ->
- Tmp1 = hipe_rtl:mk_new_reg_gcsafe(),
- Tmp2 = hipe_rtl:mk_new_reg_gcsafe(),
- [get_header(Tmp1, Binary),
- hipe_rtl:mk_alu(Tmp2, Tmp1, 'and', hipe_rtl:mk_imm(?TAG_HEADER_MASK)),
- hipe_rtl:mk_branch(Tmp2, eq, hipe_rtl:mk_imm(?TAG_HEADER_HEAP_BIN),
- TrueLblName, FalseLblName)].
+ Tmp = hipe_rtl:mk_new_reg_gcsafe(),
+ [get_header(Tmp, Binary),
+ mask_and_compare(Tmp, ?TAG_HEADER_MASK, ?TAG_HEADER_HEAP_BIN,
+ TrueLblName, FalseLblName, 0.5)].
mk_sub_binary(Dst, ByteSize, ByteOffs, BitSize, BitOffs, Orig) ->
mk_sub_binary(Dst, ByteSize, ByteOffs, BitSize, BitOffs,
@@ -919,11 +918,10 @@ build_sub_binary(Dst, ByteSize, ByteOffs, BitSize, BitOffs,
set_field_from_term({sub_binary, orig}, Dst, Orig)].
test_subbinary(Binary, TrueLblName, FalseLblName) ->
- Tmp1 = hipe_rtl:mk_new_reg_gcsafe(),
- Tmp2 = hipe_rtl:mk_new_reg_gcsafe(),
- [get_header(Tmp1, Binary),
- hipe_rtl:mk_alu(Tmp2, Tmp1, 'and', hipe_rtl:mk_imm(?TAG_HEADER_MASK)),
- hipe_rtl:mk_branch(Tmp2, eq, hipe_rtl:mk_imm(?TAG_HEADER_SUB_BIN), TrueLblName, FalseLblName)].
+ Tmp = hipe_rtl:mk_new_reg_gcsafe(),
+ [get_header(Tmp, Binary),
+ mask_and_compare(Tmp, ?TAG_HEADER_MASK, ?TAG_HEADER_SUB_BIN,
+ TrueLblName, FalseLblName, 0.5)].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%