diff options
author | Ben Gamari <ben@smart-cactus.org> | 2017-11-21 21:15:29 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-11-21 21:15:30 -0500 |
commit | eb5a40cea6c64f5300c7697231cb0ede2c554388 (patch) | |
tree | 921e82eb39f26f8684e39213af8eb4a802f73fcd /libraries/base/GHC/Real.hs | |
parent | 23116dfee485902cb3c26640e38f62032bebe72d (diff) | |
download | haskell-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.hs | 10 |
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. |