diff options
author | Sebastian Graf <sebastian.graf@kit.edu> | 2020-05-14 14:40:41 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-05-21 12:19:37 -0400 |
commit | a95bbd0bdf06d7d61b0bef6de77b59ca31b2c32d (patch) | |
tree | 55d752c5f4caf6fc4fa12ecb7ac3aa48d13f9554 /libraries | |
parent | 2b363ebb988cbf8c92df24eef5366293a80ecb19 (diff) | |
download | haskell-a95bbd0bdf06d7d61b0bef6de77b59ca31b2c32d.tar.gz |
Make `Int`'s `mod` and `rem` strict in their first arguments
They used to be strict until 4d2ac2d (9 years ago).
It's obviously better to be strict for performance reasons.
It also blocks #18067.
NoFib results:
```
--------------------------------------------------------------------------------
Program Allocs Instrs
--------------------------------------------------------------------------------
integer -1.1% +0.4%
wheel-sieve2 +21.2% +20.7%
--------------------------------------------------------------------------------
Min -1.1% -0.0%
Max +21.2% +20.7%
Geometric Mean +0.2% +0.2%
```
The regression in `wheel-sieve2` is due to reboxing that likely will go
away with the resolution of #18067. See !3282 for details.
Fixes #18187.
Diffstat (limited to 'libraries')
-rw-r--r-- | libraries/base/GHC/Real.hs | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/libraries/base/GHC/Real.hs b/libraries/base/GHC/Real.hs index 38a3aa2870..1425f8c306 100644 --- a/libraries/base/GHC/Real.hs +++ b/libraries/base/GHC/Real.hs @@ -334,11 +334,8 @@ instance Integral Int where -- in GHC.Int | otherwise = a `quotInt` b - a `rem` b + !a `rem` b -- See Note [Special case of mod and rem is lazy] | b == 0 = divZeroError - -- The quotRem CPU instruction fails for minBound `quotRem` -1, - -- but minBound `rem` -1 is well-defined (0). We therefore - -- special-case it. | b == (-1) = 0 | otherwise = a `remInt` b @@ -348,11 +345,8 @@ instance Integral Int where -- in GHC.Int | otherwise = a `divInt` b - a `mod` b + !a `mod` b -- See Note [Special case of mod and rem is lazy] | b == 0 = divZeroError - -- The divMod CPU instruction fails for minBound `divMod` -1, - -- but minBound `mod` -1 is well-defined (0). We therefore - -- special-case it. | b == (-1) = 0 | otherwise = a `modInt` b @@ -368,6 +362,15 @@ instance Integral Int where | b == (-1) && a == minBound = (overflowError, 0) | otherwise = a `divModInt` b +{- Note [Special case of mod and rem is lazy] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The `quotRem`/`divMod` CPU instruction fails for minBound `quotRem` -1, but +minBound `rem` -1 is well-defined (0). We therefore special-case for `b == -1`, +but not for `a == minBound` because of Note [Order of tests] in GHC.Int. But +now we have to make sure the function stays strict in a, to guarantee unboxing. +Hence the bang on a, see #18187. +-} + -------------------------------------------------------------- -- Instances for @Word@ -------------------------------------------------------------- |