From 6b17fd584e9135b2c1eed1d3ff5b2c42322c2b73 Mon Sep 17 00:00:00 2001
From: Daniel Fischer
Date: Sat, 1 Oct 2011 21:15:22 +0200
Subject: [PATCH] Add rules for powers with small exponents (fixes #5237)
---
GHC/Real.lhs | 38 ++++++++++++++++++++++++++++++++++++++
1 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/GHC/Real.lhs b/GHC/Real.lhs
index 8597c45..125713d 100644
--- a/GHC/Real.lhs
+++ b/GHC/Real.lhs
@@ -469,6 +469,44 @@ 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) = let u = x in u*u
+"^3/Int" forall x. x ^ (3 :: Int) = let u = x in (u*u)*u
+"^4/Int" forall x. x ^ (4 :: Int) = let u = x; y = u*u in y*y
+"^2/Integer" forall x. x ^ (2 :: Integer) = let u = x in u*u
+"^3/Integer" forall x. x ^ (3 :: Integer) = let u = x in (u*u)*u
+"^4/Integer" forall x. x ^ (4 :: Integer) = let u = x; y = u*u in y*y
+ #-}
+
+{- With the above, (x :: Type1) ^ (2 :: Type2) isn't rewritten if
+ there is a specialisation for (^) :: Type1 -> Type2 -> Type1,
+ hence special rules for those cases.
+-}
+
+{-# RULES
+"^2/Int2" forall (x :: Int). x ^ (2 :: Int) = let u = x in u*u
+"^3/Int2" forall (x :: Int). x ^ (3 :: Int) = let u = x in (u*u)*u
+"^4/Int2" forall (x :: Int). x ^ (4 :: Int) = let u = x; y = u*u in y*y
+"^2/Integer2" forall (x :: Integer). x ^ (2 :: Integer) = let u = x in u*u
+"^3/Integer2" forall (x :: Integer). x ^ (3 :: Integer) = let u = x in (u*u)*u
+"^4/Integer2" forall (x :: Integer). x ^ (4 :: Integer) = let u = x; y = u*u in y*y
+"^2/Integer3" forall (x :: Integer). x ^ (2 :: Int) = let u = x in u*u
+"^3/Integer3" forall (x :: Integer). x ^ (3 :: Int) = let u = x in (u*u)*u
+"^4/Integer3" forall (x :: Integer). x ^ (4 :: Int) = let u = x; y = u*u in y*y
+ #-}
+
-------------------------------------------------------
-- Special power functions for Rational
--
--
1.7.3.4