From c2c98edd4f74411e3a8ac0d40f2d817cd69a1ed7 Mon Sep 17 00:00:00 2001
From: Daniel Fischer
Date: Thu, 2 Jun 2011 21:41:48 +0200
Subject: [PATCH] Fix #5237
Added rules expanding powers with small exponents (2,3,4) for exponent
types Int, Integer and Word.
---
GHC/Real.lhs | 21 +++++++++++++++++++++
GHC/Word.hs | 23 ++++++++++++++++++++---
2 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/GHC/Real.lhs b/GHC/Real.lhs
index 0115409..f2bd40b 100644
--- a/GHC/Real.lhs
+++ b/GHC/Real.lhs
@@ -460,6 +460,27 @@ x ^^ n = if n >= 0 then x^n else recip (x^(negate n))
\d1 d2 x y -> blah
after the gentle round of simplification. -}
+{- Rules for powers with known small exponent
+ see # 5237
+ For small exponents, (^) is inefficient compared to manually
+ expanding the multiplication tree.
+ Here, rules for the most common exponent types are given.
+ The range of exponents for which rules are given is quite
+ arbitrary and kept small to not unduly increase the number of rules.
+ 0 and 1 are excluded based on the assumption that nobody would
+ write x^0 or x^1 in code and the cases where an exponent could
+ be statically resolved to 0 or 1 are rare.
+-}
+
+{-# RULES
+"^2/Int" forall x. x ^ (2 :: Int) = x*x
+"^3/Int" forall x. x ^ (3 :: Int) = (x*x)*x
+"^4/Int" forall x. x ^ (4 :: Int) = let y = x*x in y*y
+"^2/Integer" forall x. x ^ (2 :: Integer) = x*x
+"^3/Integer" forall x. x ^ (3 :: Integer) = (x*x)*x
+"^4/Integer" forall x. x ^ (4 :: Integer) = let y = x*x in y*y
+ #-}
+
-------------------------------------------------------
-- Special power functions for Rational
--
diff --git a/GHC/Word.hs b/GHC/Word.hs
index 9d3e1a6..5354edd 100644
--- a/GHC/Word.hs
+++ b/GHC/Word.hs
@@ -6,7 +6,7 @@
-- Module : GHC.Word
-- Copyright : (c) The University of Glasgow, 1997-2002
-- License : see libraries/base/LICENSE
---
+--
-- Maintainer : cvs-ghc@haskell.org
-- Stability : internal
-- Portability : non-portable (GHC Extensions)
@@ -193,6 +193,23 @@ instance Bits Word where
-- Going through Int isn't possible because Word's range is not
-- included in Int's, going through Integer may or may not be slower.
+{- Rules for powers with known small exponent
+ see # 5237
+ For small exponents, (^) is inefficient compared to manually
+ expanding the multiplication tree.
+ The range of exponents for which rules are given is quite
+ arbitrary and kept small to not unduly increase the number of rules.
+ 0 and 1 are excluded based on the assumption that nobody would
+ write x^0 or x^1 in code and the cases where an exponent could
+ be statically resolved to 0 or 1 are rare.
+-}
+
+{-# RULES
+"^2/Word" forall x. x ^ (2 :: Word) = x*x
+"^3/Word" forall x. x ^ (3 :: Word) = x*x*x
+"^4/Word" forall x. x ^ (4 :: Word) = let y = x*x in y*y
+ #-}
+
------------------------------------------------------------------------
-- type Word8
------------------------------------------------------------------------
@@ -555,7 +572,7 @@ instance Bits Word32 where
"fromIntegral/Word32->Word32" fromIntegral = id :: Word32 -> Word32
#-}
-#else
+#else
-- Word32 is represented in the same way as Word.
#if WORD_SIZE_IN_BITS > 32
@@ -718,7 +735,7 @@ instance Ix Word32 where
unsafeIndex (m,_) i = fromIntegral (i - m)
inRange (m,n) i = m <= i && i <= n
-instance Read Word32 where
+instance Read Word32 where
#if WORD_SIZE_IN_BITS < 33
readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
#else
--
1.7.1