summaryrefslogtreecommitdiff
path: root/libraries/base/GHC/Real.hs
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2017-11-21 21:15:29 -0500
committerBen Gamari <ben@smart-cactus.org>2017-11-21 21:15:30 -0500
commiteb5a40cea6c64f5300c7697231cb0ede2c554388 (patch)
tree921e82eb39f26f8684e39213af8eb4a802f73fcd /libraries/base/GHC/Real.hs
parent23116dfee485902cb3c26640e38f62032bebe72d (diff)
downloadhaskell-eb5a40cea6c64f5300c7697231cb0ede2c554388.tar.gz
base: Remove redundant subtraction in (^) and stimes
Subtraction `y - 1` is redundant. The value of y is guaranteed to be positive and odd, so ``` (y - 1) `quot` 2` = `y `quot` 2 ``` Test Plan: validate Reviewers: hvr, bgamari Reviewed By: bgamari Subscribers: rwbarton, thomie GHC Trac Issues: #14439 Differential Revision: https://phabricator.haskell.org/D4173
Diffstat (limited to 'libraries/base/GHC/Real.hs')
-rw-r--r--libraries/base/GHC/Real.hs10
1 files changed, 8 insertions, 2 deletions
diff --git a/libraries/base/GHC/Real.hs b/libraries/base/GHC/Real.hs
index f30a53e7a6..4ab4b2f793 100644
--- a/libraries/base/GHC/Real.hs
+++ b/libraries/base/GHC/Real.hs
@@ -493,17 +493,23 @@ x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
where -- f : x0 ^ y0 = x ^ y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
- | otherwise = g (x * x) ((y - 1) `quot` 2) x
+ | otherwise = g (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-- g : x0 ^ y0 = (x ^ y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
- | otherwise = g (x * x) ((y - 1) `quot` 2) (x * z)
+ | otherwise = g (x * x) (y `quot` 2) (x * z) -- See Note [Half of y - 1]
-- | raise a number to an integral power
(^^) :: (Fractional a, Integral b) => a -> b -> a
{-# INLINABLE [1] (^^) #-} -- See Note [Inlining (^)
x ^^ n = if n >= 0 then x^n else recip (x^(negate n))
+{- Note [Half of y - 1]
+ ~~~~~~~~~~~~~~~~~~~~~
+ Since y is guaranteed to be odd and positive here,
+ half of y - 1 can be computed as y `quot` 2, optimising subtraction away.
+-}
+
{- Note [Inlining (^)
~~~~~~~~~~~~~~~~~~~~~
The INLINABLE pragma allows (^) to be specialised at its call sites.