1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 20:00:19 +02:00

Optimize scm_integer_mul_zz.

* libguile/integers.c (scm_integer_mul_zz): Optimize to avoid temporary
allocations.
This commit is contained in:
Andy Wingo 2022-01-09 16:46:27 +01:00
parent d89f75c535
commit ad6811a12b

View file

@ -2939,13 +2939,25 @@ scm_integer_mul_zi (struct scm_bignum *x, scm_t_inum y)
SCM SCM
scm_integer_mul_zz (struct scm_bignum *x, struct scm_bignum *y) scm_integer_mul_zz (struct scm_bignum *x, struct scm_bignum *y)
{ {
mpz_t result, zx, zy; size_t xn = bignum_limb_count (x);
mpz_init (result); size_t yn = bignum_limb_count (y);
alias_bignum_to_mpz (x, zx); if (xn == 0 || yn == 0)
alias_bignum_to_mpz (y, zy); return SCM_INUM0;
mpz_mul (result, zx, zy);
struct scm_bignum *result = allocate_bignum (xn + yn);
mp_limb_t *rd = bignum_limbs (result);
const mp_limb_t *xd = bignum_limbs (x);
const mp_limb_t *yd = bignum_limbs (y);
int negate = bignum_is_negative (x) != bignum_is_negative (y);
if (xd == yd)
mpn_sqr (rd, xd, xn);
else if (xn <= yn)
mpn_mul (rd, yd, yn, xd, xn);
else
mpn_mul (rd, xd, xn, yd, yn);
scm_remember_upto_here_2 (x, y); scm_remember_upto_here_2 (x, y);
return take_mpz (result); return normalize_bignum
(bignum_negate_if (negate, (bignum_trim1 (result))));
} }
int int