guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 01/02: Optimize integer-expt for fixnums


From: Andy Wingo
Subject: [Guile-commits] 01/02: Optimize integer-expt for fixnums
Date: Mon, 10 Jan 2022 05:57:09 -0500 (EST)

wingo pushed a commit to branch wip-inline-digits
in repository guile.

commit c467ab16c54322bd3ff7a6fddc0d7262db824c2e
Author: Andy Wingo <wingo@pobox.com>
AuthorDate: Mon Jan 10 11:12:36 2022 +0100

    Optimize integer-expt for fixnums
    
    * libguile/integers.c (scm_integer_expt_ii): Add some optimizations for
    cases in which we can avoid allocating an mpz.
---
 libguile/integers.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/libguile/integers.c b/libguile/integers.c
index de1d2b3d5..a173d01f2 100644
--- a/libguile/integers.c
+++ b/libguile/integers.c
@@ -2265,6 +2265,27 @@ SCM
 scm_integer_expt_ii (scm_t_inum n, scm_t_inum k)
 {
   ASSERT (k >= 0);
+  if (k == 0)
+    return SCM_INUM1;
+  if (k == 1)
+    return SCM_I_MAKINUM (n);
+  if (n == -1)
+    return scm_is_integer_odd_i (k) ? SCM_I_MAKINUM (-1) : SCM_INUM1;
+  if (n == 2)
+    {
+      if (k < SCM_I_FIXNUM_BIT - 1)
+        return SCM_I_MAKINUM (1L << k);
+      if (k < 64)
+        return scm_integer_from_uint64 (((uint64_t) 1) << k);
+      size_t nlimbs = k / (sizeof (mp_limb_t)*8) + 1;
+      size_t high_shift = k & (sizeof (mp_limb_t)*8 - 1);
+      struct scm_bignum *result = allocate_bignum (nlimbs);
+      mp_limb_t *rd = bignum_limbs (result);
+      mpn_zero(rd, nlimbs - 1);
+      rd[nlimbs - 1] = ((mp_limb_t) 1) << high_shift;
+      return scm_from_bignum (result);
+    }
+
   mpz_t res;
   mpz_init (res);
   mpz_ui_pow_ui (res, inum_magnitude (n), k);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]