guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] 02/02: Reduce quo, rem, mod for power-of-two divisors


From: Andy Wingo
Subject: [Guile-commits] 02/02: Reduce quo, rem, mod for power-of-two divisors
Date: Mon, 9 Dec 2019 16:03:11 -0500 (EST)

wingo pushed a commit to branch master
in repository guile.

commit 70ad8a2e728417cf524eede9dafa0c979cafda55
Author: Andy Wingo <address@hidden>
Date:   Mon Dec 9 21:48:20 2019 +0100

    Reduce quo, rem, mod for power-of-two divisors
    
    * module/language/cps/type-fold.scm (power-of-two?): New helper.
      (quo, rem, mod): New reducers for when the denominator is a power of
      two.
---
 module/language/cps/type-fold.scm | 55 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/module/language/cps/type-fold.scm 
b/module/language/cps/type-fold.scm
index 25354ad..5cb7447 100644
--- a/module/language/cps/type-fold.scm
+++ b/module/language/cps/type-fold.scm
@@ -303,6 +303,61 @@
     (lambda (cps k src param arg0 type0 min0 max0 arg1 type1 min1 max1)
       body ...)))
 
+(define (power-of-two? constant)
+  (and (positive? constant)
+       (zero? (logand constant (1- constant)))))
+
+(define-binary-primcall-reducer (quo cps k src param
+                                     arg0 type0 min0 max0
+                                     arg1 type1 min1 max1)
+  (cond
+   ((not (type<=? (logior type0 type1) &exact-integer))
+    (with-cps cps #f))
+   ((and (eqv? type1 &fixnum) (eqv? min1 max1) (power-of-two? min1))
+    (with-cps cps
+      (build-term
+        ($continue k src
+          ($primcall 'rsh/immediate (logcount (1- min1)) (arg0))))))
+   (else
+    (with-cps cps #f))))
+
+(define-binary-primcall-reducer (rem cps k src param
+                                     arg0 type0 min0 max0
+                                     arg1 type1 min1 max1)
+  (cond
+   ((not (type<=? (logior type0 type1) &exact-integer))
+    (with-cps cps #f))
+   ((and (eqv? type1 &fixnum) (eqv? min1 max1) (power-of-two? min1)
+         (<= 0 min0))
+    (with-cps cps
+      (letv mask)
+      (letk kmask
+            ($kargs ('mask) (mask)
+              ($continue k src
+                ($primcall 'logand #f (arg0 mask)))))
+      (build-term
+        ($continue kmask src ($const (1- min1))))))
+   (else
+    (with-cps cps #f))))
+
+(define-binary-primcall-reducer (mod cps k src param
+                                     arg0 type0 min0 max0
+                                     arg1 type1 min1 max1)
+  (cond
+   ((not (type<=? (logior type0 type1) &exact-integer))
+    (with-cps cps #f))
+   ((and (eqv? type1 &fixnum) (eqv? min1 max1) (power-of-two? min1))
+    (with-cps cps
+      (letv mask)
+      (letk kmask
+            ($kargs ('mask) (mask)
+              ($continue k src
+                ($primcall 'logand #f (arg0 mask)))))
+      (build-term
+        ($continue kmask src ($const (1- min1))))))
+   (else
+    (with-cps cps #f))))
+
 (define-unary-primcall-reducer (mul/immediate cps k src constant
                                               arg type min max)
   (cond



reply via email to

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