From 5293d44e876c4d08a1a1f19b037a8afd54961eb8 Mon Sep 17 00:00:00 2001
From: Raymond Toy <toy.raymond@gmail.com>
Date: Sun, 19 Aug 2012 07:58:06 -0700
Subject: [PATCH] Floating-point micro-optimizations

o Convert x/n to x*(1/n) when n is a power of two since 1/n has an
  exact representation.
o Convert 2*x to x+x.
---
 src/compiler/float-tran.lisp | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/src/compiler/float-tran.lisp b/src/compiler/float-tran.lisp
index 7a82135b9..d0a3703cc 100644
--- a/src/compiler/float-tran.lisp
+++ b/src/compiler/float-tran.lisp
@@ -634,6 +634,28 @@
   (frob >)
   (frob =))
 
+;; Convert (/ x n) to (* x (/ n)) when x is a float and n is a power
+;; of two, because (/ n) can be reprsented exactly.
+(deftransform / ((x y) (float float) * :when :both)
+  (unless (constant-continuation-p y)
+    (give-up))
+  (let ((val (continuation-value y)))
+    (multiple-value-bind (frac exp sign)
+	(decode-float val)
+      (unless (= frac 0.5)
+	(give-up))
+      `(* x (float (/ ,val) x)))))
+
+;; Convert 2*x to x+x.
+(deftransform * ((x y) (float real) * :when :both)
+  (unless (constant-continuation-p y)
+    (give-up))
+  (let ((val (continuation-value y)))
+    (unless (= val 2)
+      (give-up))
+    '(+ x x)))
+
+	      
 
 ;;;; Irrational transforms:
 
-- 
GitLab