summaryrefslogtreecommitdiff
path: root/libraries/integer-gmp
diff options
context:
space:
mode:
authorHerbert Valerio Riedel <hvr@gnu.org>2014-01-03 22:42:33 +0100
committerHerbert Valerio Riedel <hvr@gnu.org>2014-01-03 22:49:05 +0100
commit4cc6785ab434e781be40e88b27a36c490d257323 (patch)
tree2f22fc1fa2343ccf9b67952ef2446251450b980a /libraries/integer-gmp
parentfc8e15b8aca01608c79a42021c7b1efb878e680d (diff)
downloadhaskell-4cc6785ab434e781be40e88b27a36c490d257323.tar.gz
Make use of `quotRemInt#` primop in `quotRemInteger`
Otoh, `divModInt#` is not a proper primop (it's implemented as wrapper around `quotRemInt#` in `GHC.Base`), so we can't do the same for `divModInteger` yet. Signed-off-by: Herbert Valerio Riedel <hvr@gnu.org>
Diffstat (limited to 'libraries/integer-gmp')
-rw-r--r--libraries/integer-gmp/GHC/Integer/Type.lhs17
1 files changed, 7 insertions, 10 deletions
diff --git a/libraries/integer-gmp/GHC/Integer/Type.lhs b/libraries/integer-gmp/GHC/Integer/Type.lhs
index 77d529a572..a64f157387 100644
--- a/libraries/integer-gmp/GHC/Integer/Type.lhs
+++ b/libraries/integer-gmp/GHC/Integer/Type.lhs
@@ -28,7 +28,7 @@ import GHC.Prim (
-- Conversions between those types
int2Word#, int2Double#, int2Float#, word2Int#,
-- Operations on Int# that we use for operations on S#
- quotInt#, remInt#, negateInt#,
+ quotInt#, remInt#, quotRemInt#, negateInt#,
(*#), (-#),
(==#), (/=#), (<=#), (>=#), (<#), (>#),
mulIntMayOflo#, addIntC#, subIntC#,
@@ -216,14 +216,8 @@ Just using smartJ# in this way has good results:
{-# NOINLINE quotRemInteger #-}
quotRemInteger :: Integer -> Integer -> (# Integer, Integer #)
quotRemInteger a@(S# INT_MINBOUND) b = quotRemInteger (toBig a) b
-quotRemInteger (S# i) (S# j) = (# S# q, S# r #)
- where
- -- NB. don't inline these. (# S# (i `quotInt#` j), ... #) means
- -- (# let q = i `quotInt#` j in S# q, ... #) which builds a
- -- useless thunk. Placing the bindings here means they'll be
- -- evaluated strictly.
- !q = i `quotInt#` j
- !r = i `remInt#` j
+quotRemInteger (S# i) (S# j) = case quotRemInt# i j of
+ (# q, r #) -> (# S# q, S# r #)
quotRemInteger i1@(J# _ _) i2@(S# _) = quotRemInteger i1 (toBig i2)
quotRemInteger i1@(S# _) i2@(J# _ _) = quotRemInteger (toBig i1) i2
quotRemInteger (J# s1 d1) (J# s2 d2)
@@ -238,7 +232,10 @@ divModInteger :: Integer -> Integer -> (# Integer, Integer #)
divModInteger a@(S# INT_MINBOUND) b = divModInteger (toBig a) b
divModInteger (S# i) (S# j) = (# S# d, S# m #)
where
- -- NB. don't inline these. See quotRemInteger above.
+ -- NB. don't inline these. (# S# (i `quotInt#` j), ... #) means
+ -- (# let q = i `quotInt#` j in S# q, ... #) which builds a
+ -- useless thunk. Placing the bindings here means they'll be
+ -- evaluated strictly.
!d = i `divInt#` j
!m = i `modInt#` j