[libmath-prime-util-perl] 73/181: various XSUB optimizations
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:51:08 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.36
in repository libmath-prime-util-perl.
commit 4e0e6abf4b193a8f51bf8d01609856ec183adf4b
Author: bulk88 <bulk88 at hotmail.com>
Date: Mon Dec 30 21:15:59 2013 -0500
various XSUB optimizations
in prime_memfree convert _XS_prime_maxbitsm from alias to pure perl
possibly constant folding const sub
in _XS_prime_count, if G_VOID, don't alloc or fetch any SVs if returning
nothing, use TARG to return a UV, PUSHu unrolled for locality to
put XSprePUSH near PUSHs and PUTBACK into a 3 statement function call free
area of stack manipulation
in _XS_miller_rabin, XSRETURN_IV would generate a new mortal SVIV,
instead of using the TARG SV* already allocated and set to IV on one
particular execution path, TARG is more efficient since it often is a
pad SV of the caller pure perl sub, and takes a shortcut through sv_setsv
if both src and dest SV*s are identical
in _XS_ExponentialIntegral factor out the SvNV and SvUV, teach compiler to
optimize out the default and not complain about it on < 4 branch (in
theory, var ix could be negative since its an I32), MPUASSUME code is from
Perl 5.19
in _validate_num read my_perl->Istack_base less often (inside ST macro)
---
XS.xs | 67 +++++++++++++++++++++++++++++++++++++++++++++++-----------------
ptypes.h | 19 ++++++++++++++++++
2 files changed, 68 insertions(+), 18 deletions(-)
diff --git a/XS.xs b/XS.xs
index 851142f..7b5578d 100644
--- a/XS.xs
+++ b/XS.xs
@@ -146,6 +146,12 @@ MODULE = Math::Prime::Util PACKAGE = Math::Prime::Util
PROTOTYPES: ENABLE
+BOOT:
+{
+ SV * sv = newSViv(BITS_PER_WORD);
+ HV * stash = gv_stashpv("Math::Prime::Util", TRUE);
+ newCONSTSUB(stash, "_XS_prime_maxbits", sv);
+}
void
prime_memfree()
@@ -154,7 +160,6 @@ prime_memfree()
_XS_get_verbose = 2
_XS_get_callgmp = 3
_get_prime_cache_size = 4
- _XS_prime_maxbits = 5
PPCODE:
UV ret = 0;
switch (ix) {
@@ -163,7 +168,6 @@ prime_memfree()
case 2: ret = _XS_get_verbose(); break;
case 3: ret = _XS_get_callgmp(); break;
case 4: ret = get_prime_cache(0,0); break;
- case 5: ret = BITS_PER_WORD; break;
}
if (ix > 1) XSRETURN_UV(ret);
@@ -182,16 +186,30 @@ prime_precalc(IN UV n)
void
_XS_prime_count(IN UV low, IN UV high = 0)
- PPCODE:
+ CODE:
if (high == 0) { /* Without a Perl layer in front of this, we'll have */
high = low; /* the pathological case of a-0 turning into 0-a. */
low = 0;
}
if (GIMME_V == G_VOID) {
prime_precalc(high);
+ /* doing PPCODE: (implied XSprePUSH) and jumping to the PUTBACK was less
+ efficient machine code wise than these 2 return paths*/
+ XSRETURN(0);
} else {
- PUSHs(sv_2mortal(newSVuv( _XS_prime_count(low, high) )));
+ UV RETVAL;
+ RETVAL = _XS_prime_count(low, high);
+ {
+ dXSTARG;
+ sv_setuv(TARG, RETVAL);
+ SvSETMAGIC(TARG);
+ XSprePUSH;
+ PUSHs(TARG);
+ PUTBACK;
+ return;
+ }
}
+ /*unreachable*/
UV
_XS_nth_prime(IN UV n)
@@ -367,9 +385,9 @@ _XS_miller_rabin(IN UV n, ...)
CODE:
if (items < 2)
croak("No bases given to miller_rabin");
- if ( (n == 0) || (n == 1) ) XSRETURN_IV(0); /* 0 and 1 are composite */
- if ( (n == 2) || (n == 3) ) XSRETURN_IV(1); /* 2 and 3 are prime */
- if (( n % 2 ) == 0) XSRETURN_IV(0); /* MR works with odd n */
+ if ( (n == 0) || (n == 1) ) {RETVAL = 0; goto return_iv;} /* 0 and 1 are composite */
+ if ( (n == 2) || (n == 3) ) {RETVAL = 1; goto return_iv;} /* 2 and 3 are prime */
+ if (( n % 2 ) == 0) {RETVAL = 0; goto return_iv;} /* MR works with odd n */
while (c < items) {
int b = 0;
while (c < items) {
@@ -382,6 +400,7 @@ _XS_miller_rabin(IN UV n, ...)
break;
}
RETVAL = prob_prime;
+ return_iv:
OUTPUT:
RETVAL
@@ -568,13 +587,22 @@ _XS_ExponentialIntegral(IN SV* x)
PREINIT:
double ret;
CODE:
- switch (ix) {
- case 0: ret = _XS_ExponentialIntegral(SvNV(x)); break;
- case 1: ret = _XS_LogarithmicIntegral(SvNV(x)); break;
- case 2: ret = (double) ld_riemann_zeta(SvNV(x)); break;
- case 3: ret = _XS_RiemannR(SvNV(x)); break;
- case 4: ret = _XS_chebyshev_theta(SvUV(x)); break;
- default:ret = _XS_chebyshev_psi(SvUV(x)); break;
+ if(ix < 4 ) {
+ NV nv = SvNV(x);
+ switch (ix) {
+ case 0: ret = _XS_ExponentialIntegral(nv); break;
+ case 1: ret = _XS_LogarithmicIntegral(nv); break;
+ case 2: ret = (double) ld_riemann_zeta(nv); break;
+ case 3: ret = _XS_RiemannR(nv); break;
+ default: MPUNOT_REACHED; break; /* CC thinks ix is negative */
+ }
+ } else {
+ UV uv = SvUV(x);
+ switch (ix) {
+ case 4: ret = _XS_chebyshev_theta(uv); break;
+ case 5:
+ default: ret = _XS_chebyshev_psi(uv); break;
+ }
}
RETVAL = ret;
OUTPUT:
@@ -687,6 +715,9 @@ carmichael_lambda(IN SV* svn)
int
_validate_num(SV* svn, ...)
+ PREINIT:
+ SV* sv1;
+ SV* sv2;
CODE:
RETVAL = 0;
if (_validate_int(aTHX_ svn, 0)) {
@@ -694,13 +725,13 @@ _validate_num(SV* svn, ...)
UV n = my_svuv(svn);
sv_setuv(svn, n);
}
- if (items > 1 && SvOK(ST(1))) {
+ if (items > 1 && ((sv1 = ST(1)), SvOK(sv1))) {
UV n = my_svuv(svn);
- UV min = my_svuv(ST(1));
+ UV min = my_svuv(sv1);
if (n < min)
croak("Parameter '%"UVuf"' must be >= %"UVuf, n, min);
- if (items > 2 && SvOK(ST(2))) {
- UV max = my_svuv(ST(2));
+ if (items > 2 && ((sv2 = ST(2)), SvOK(sv2))) {
+ UV max = my_svuv(sv2);
if (n > max)
croak("Parameter '%"UVuf"' must be <= %"UVuf, n, max);
MPUassert( items <= 3, "_validate_num takes at most 3 parameters");
diff --git a/ptypes.h b/ptypes.h
index 1259198..6c51e4d 100644
--- a/ptypes.h
+++ b/ptypes.h
@@ -102,4 +102,23 @@ typedef __int8 int8_t;
#define MPUassert(c,text) if (!(c)) { croak("Math::Prime::Util internal error: " text); }
+#ifndef DEBUGGING
+# if __has_builtin(__builtin_unreachable) \
+ || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5 || __GNUC__ > 5) /* 4.5 -> */
+# define MPUASSUME(x) ((x) ? (void) 0 : __builtin_unreachable())
+# elif defined(_MSC_VER)
+# define MPUASSUME(x) __assume(x)
+# elif defined(__ARMCC_VERSION) /* untested */
+# define MPUASSUME(x) __promise(x)
+# else
+/* a random compiler might define assert to its own special optimization token
+ so pass it through to C lib as a last resort */
+# define MPUASSUME(x) assert(x)
+# endif
+#else
+# define MPUASSUME(x) assert(x)
+#endif
+
+#define MPUNOT_REACHED MPUASSUME(0)
+
#endif
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git
More information about the Pkg-perl-cvs-commits
mailing list