Optimize truncate, ceiling and friends when divisor is 1 or -1.
authorStas Boukarev <stassats@gmail.com>
Mon, 7 May 2012 12:18:33 +0000 (16:18 +0400)
committerStas Boukarev <stassats@gmail.com>
Mon, 7 May 2012 12:18:33 +0000 (16:18 +0400)
If divisor is 1, return (values x 0), if it's -1 (values (- x) 0). If
it's a floating point truncation, like ftruncate or fceiling,
(values (- (float x)) 0).

NEWS
src/compiler/srctran.lisp

diff --git a/NEWS b/NEWS
index a820ca0..71ddcd1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -123,6 +123,8 @@ changes in sbcl-1.0.55 relative to sbcl-1.0.54:
   * optimization: the compiler no longer refuses to coerce large fixnums to
     single floats inline, except on x86 where this limitation is still
     necessary.
+  * optimization: truncation operations with constant divisor arguments
+    1 and -1 are optimized away.
   * bug fix: deadlock detection could report the same deadlock twice, for
     two different threads. Now a single deadlock is reported exactly once.
   * bug fix: interval-arithmetic division during type derivation did not
index e666b87..ad7abbc 100644 (file)
   (def round)
   (def floor)
   (def ceiling))
+
+(macrolet ((def (name &optional float)
+             (let ((x (if float '(float x) 'x)))
+               `(deftransform ,name ((x y) (integer (constant-arg (member 1 -1)))
+                                     *)
+                  "fold division by 1"
+                  `(values ,(if (minusp (lvar-value y))
+                                '(%negate ,x)
+                                ',x)  0)))))
+  (def truncate)
+  (def round)
+  (def floor)
+  (def ceiling)
+  (def ftruncate t)
+  (def fround t)
+  (def ffloor t)
+  (def fceiling t))
+
 \f
 ;;;; character operations