aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Lång <[email protected]>2017-04-09 13:27:51 +0200
committerMagnus Lång <[email protected]>2017-11-05 19:07:07 +0100
commit354f6d1c29ecaabab8a5aa3f1c95a4188a0aa542 (patch)
tree6e193c79976cb6e2c4e7121e39f790a0e234b7b1
parentd71a2715c181f4659251723575eea79ee531729a (diff)
downloadotp-354f6d1c29ecaabab8a5aa3f1c95a4188a0aa542.tar.gz
otp-354f6d1c29ecaabab8a5aa3f1c95a4188a0aa542.tar.bz2
otp-354f6d1c29ecaabab8a5aa3f1c95a4188a0aa542.zip
HiPE: Make is_divisible a primop
Since gcunsafe values are live over is_divisible calls (although only the happy path, which never GCd), it should be a primop so there cannot be any GCs.
-rw-r--r--erts/emulator/hipe/hipe_bif_list.m42
-rw-r--r--erts/emulator/hipe/hipe_native_bif.c10
-rw-r--r--erts/emulator/hipe/hipe_native_bif.h4
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary_construct.erl10
4 files changed, 14 insertions, 12 deletions
diff --git a/erts/emulator/hipe/hipe_bif_list.m4 b/erts/emulator/hipe/hipe_bif_list.m4
index 08c1ab9318..23b6709cd0 100644
--- a/erts/emulator/hipe/hipe_bif_list.m4
+++ b/erts/emulator/hipe/hipe_bif_list.m4
@@ -222,7 +222,7 @@ standard_bif_interface_2(nbif_rethrow, hipe_rethrow)
standard_bif_interface_3(nbif_find_na_or_make_stub, hipe_find_na_or_make_stub)
standard_bif_interface_2(nbif_nonclosure_address, hipe_nonclosure_address)
nocons_nofail_primop_interface_0(nbif_fclearerror_error, hipe_fclearerror_error)
-standard_bif_interface_2(nbif_is_divisible, hipe_is_divisible)
+noproc_primop_interface_2(nbif_is_divisible, hipe_is_divisible)
noproc_primop_interface_1(nbif_is_unicode, hipe_is_unicode)
/*
diff --git a/erts/emulator/hipe/hipe_native_bif.c b/erts/emulator/hipe/hipe_native_bif.c
index 4d20fbdb90..e444e3dc5d 100644
--- a/erts/emulator/hipe/hipe_native_bif.c
+++ b/erts/emulator/hipe/hipe_native_bif.c
@@ -506,16 +506,12 @@ int hipe_bs_validate_unicode_retract(ErlBinMatchBuffer* mb, Eterm arg)
return 1;
}
-/* Called via standard_bif_interface_2 */
-BIF_RETTYPE nbif_impl_hipe_is_divisible(NBIF_ALIST_2)
+Uint hipe_is_divisible(Uint dividend, Uint divisor)
{
- /* Arguments are Eterm-sized unsigned integers */
- Uint dividend = BIF_ARG_1;
- Uint divisor = BIF_ARG_2;
if (dividend % divisor) {
- BIF_ERROR(BIF_P, BADARG);
+ return 0;
} else {
- return NIL;
+ return 1;
}
}
diff --git a/erts/emulator/hipe/hipe_native_bif.h b/erts/emulator/hipe/hipe_native_bif.h
index aa961ab6d0..71f63875a4 100644
--- a/erts/emulator/hipe/hipe_native_bif.h
+++ b/erts/emulator/hipe/hipe_native_bif.h
@@ -69,7 +69,7 @@ AEXTERN(Eterm,nbif_bs_get_utf16,(void));
AEXTERN(Eterm,nbif_bs_validate_unicode,(Process*,Eterm));
AEXTERN(Uint,nbif_is_unicode,(Eterm));
AEXTERN(Eterm,nbif_bs_validate_unicode_retract,(void));
-AEXTERN(void,nbif_is_divisible,(Process*,Uint,Uint));
+AEXTERN(Uint,nbif_is_divisible,(Uint,Uint));
AEXTERN(void,nbif_select_msg,(Process*));
AEXTERN(Eterm,nbif_cmp_2,(void));
@@ -96,7 +96,7 @@ BIF_RETTYPE nbif_impl_hipe_bs_validate_unicode(NBIF_ALIST_1);
Uint hipe_is_unicode(Eterm);
struct erl_bin_match_buffer;
int hipe_bs_validate_unicode_retract(struct erl_bin_match_buffer*, Eterm);
-BIF_RETTYPE nbif_impl_hipe_is_divisible(NBIF_ALIST_2);
+Uint hipe_is_divisible(Uint, Uint);
#ifdef NO_FPE_SIGNALS
AEXTERN(void,nbif_emulate_fpe,(Process*));
diff --git a/lib/hipe/rtl/hipe_rtl_binary_construct.erl b/lib/hipe/rtl/hipe_rtl_binary_construct.erl
index bc215e3abe..bc29e1d081 100644
--- a/lib/hipe/rtl/hipe_rtl_binary_construct.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary_construct.erl
@@ -1210,6 +1210,12 @@ is_divisible(Dividend, Divisor, SuccLbl, FailLbl) ->
[hipe_rtl:mk_branch(Dividend, 'and', Mask, eq, SuccLbl, FailLbl, 0.99)];
false ->
%% We need division, fall back to a primop
- [hipe_rtl:mk_call([], is_divisible, [Dividend, hipe_rtl:mk_imm(Divisor)],
- SuccLbl, FailLbl, not_remote)]
+ [Tmp] = create_regs(1),
+ RetLbl = hipe_rtl:mk_new_label(),
+ [hipe_rtl:mk_call([Tmp], is_divisible,
+ [Dividend, hipe_rtl:mk_imm(Divisor)],
+ hipe_rtl:label_name(RetLbl), [], not_remote),
+ RetLbl,
+ hipe_rtl:mk_branch(Tmp, ne, hipe_rtl:mk_imm(0),
+ SuccLbl, FailLbl, 0.99)]
end.