diff options
author | Sylvain Henry <sylvain@haskus.fr> | 2021-05-31 15:47:56 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-08-09 15:11:23 -0400 |
commit | 748636388b052d22859b7265dec776edfa12a68c (patch) | |
tree | 3193ecc47420dbf522ce945f3c1d57254833aaeb /libraries/base/Foreign | |
parent | b128a880b225d3abc98f58a0426b58138aed5504 (diff) | |
download | haskell-748636388b052d22859b7265dec776edfa12a68c.tar.gz |
Remove ad-hoc fromIntegral rules
fromIntegral is defined as:
{-# NOINLINE [1] fromIntegral #-}
fromIntegral :: (Integral a, Num b) => a -> b
fromIntegral = fromInteger . toInteger
Before this patch, we had a lot of rewrite rules for fromIntegral, to
avoid passing through Integer when there is a faster way, e.g.:
"fromIntegral/Int->Word" fromIntegral = \(I# x#) -> W# (int2Word# x#)
"fromIntegral/Word->Int" fromIntegral = \(W# x#) -> I# (word2Int# x#)
"fromIntegral/Word->Word" fromIntegral = id :: Word -> Word
Since we have added sized types and primops (Word8#, Int16#, etc.) and
Natural, this approach didn't really scale as there is a combinatorial
explosion of types. In addition, we really want these conversions to be
optimized for all these types and in every case (not only when
fromIntegral is explicitly used).
This patch removes all those ad-hoc fromIntegral rules. Instead we rely
on inlining and built-in constant-folding rules. There are not too many
native conversions between Integer/Natural and fixed size types, so we
can handle them all explicitly.
Foreign.C.Types was using rules to ensure that fromIntegral rules "sees"
through the newtype wrappers,e.g.:
{-# RULES
"fromIntegral/a->CSize" fromIntegral = \x -> CSize (fromIntegral x)
"fromIntegral/CSize->a" fromIntegral = \(CSize x) -> fromIntegral x
#-}
But they aren't necessary because coercions due to newtype deriving are
pushed out of the way. So this patch removes these rules (as
fromIntegral is now inlined, they won't match anymore anyway).
Summary:
* INLINE `fromIntegral`
* Add some missing constant-folding rules
* Remove every fromIntegral ad-hoc rules (fix #19907)
Fix #20062 (missing fromIntegral rules for sized primitives)
Performance:
- T12545 wiggles (tracked by #19414)
Metric Decrease:
T12545
T10359
Metric Increase:
T12545
Diffstat (limited to 'libraries/base/Foreign')
-rw-r--r-- | libraries/base/Foreign/C/Types.hs | 46 |
1 files changed, 0 insertions, 46 deletions
diff --git a/libraries/base/Foreign/C/Types.hs b/libraries/base/Foreign/C/Types.hs index e2907ca2d8..05295a819f 100644 --- a/libraries/base/Foreign/C/Types.hs +++ b/libraries/base/Foreign/C/Types.hs @@ -146,33 +146,6 @@ INTEGRAL_TYPE(CULLong,HTYPE_UNSIGNED_LONG_LONG) -- @since 4.10.0.0 INTEGRAL_TYPE_WITH_CTYPE(CBool,bool,HTYPE_BOOL) -{-# RULES -"fromIntegral/a->CChar" fromIntegral = \x -> CChar (fromIntegral x) -"fromIntegral/a->CSChar" fromIntegral = \x -> CSChar (fromIntegral x) -"fromIntegral/a->CUChar" fromIntegral = \x -> CUChar (fromIntegral x) -"fromIntegral/a->CShort" fromIntegral = \x -> CShort (fromIntegral x) -"fromIntegral/a->CUShort" fromIntegral = \x -> CUShort (fromIntegral x) -"fromIntegral/a->CInt" fromIntegral = \x -> CInt (fromIntegral x) -"fromIntegral/a->CUInt" fromIntegral = \x -> CUInt (fromIntegral x) -"fromIntegral/a->CLong" fromIntegral = \x -> CLong (fromIntegral x) -"fromIntegral/a->CULong" fromIntegral = \x -> CULong (fromIntegral x) -"fromIntegral/a->CLLong" fromIntegral = \x -> CLLong (fromIntegral x) -"fromIntegral/a->CULLong" fromIntegral = \x -> CULLong (fromIntegral x) - -"fromIntegral/CChar->a" fromIntegral = \(CChar x) -> fromIntegral x -"fromIntegral/CSChar->a" fromIntegral = \(CSChar x) -> fromIntegral x -"fromIntegral/CUChar->a" fromIntegral = \(CUChar x) -> fromIntegral x -"fromIntegral/CShort->a" fromIntegral = \(CShort x) -> fromIntegral x -"fromIntegral/CUShort->a" fromIntegral = \(CUShort x) -> fromIntegral x -"fromIntegral/CInt->a" fromIntegral = \(CInt x) -> fromIntegral x -"fromIntegral/CUInt->a" fromIntegral = \(CUInt x) -> fromIntegral x -"fromIntegral/CLong->a" fromIntegral = \(CLong x) -> fromIntegral x -"fromIntegral/CULong->a" fromIntegral = \(CULong x) -> fromIntegral x -"fromIntegral/CLLong->a" fromIntegral = \(CLLong x) -> fromIntegral x -"fromIntegral/CULLong->a" fromIntegral = \(CULLong x) -> fromIntegral x -"fromIntegral/CBool->a" fromIntegral = \(CBool x) -> fromIntegral x - #-} - -- | Haskell type representing the C @float@ type. -- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ FLOATING_TYPE(CFloat,HTYPE_FLOAT) @@ -206,18 +179,6 @@ INTEGRAL_TYPE(CWchar,HTYPE_WCHAR_T) -- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CSigAtomic,HTYPE_SIG_ATOMIC_T) -{-# RULES -"fromIntegral/a->CPtrdiff" fromIntegral = \x -> CPtrdiff (fromIntegral x) -"fromIntegral/a->CSize" fromIntegral = \x -> CSize (fromIntegral x) -"fromIntegral/a->CWchar" fromIntegral = \x -> CWchar (fromIntegral x) -"fromIntegral/a->CSigAtomic" fromIntegral = \x -> CSigAtomic (fromIntegral x) - -"fromIntegral/CPtrdiff->a" fromIntegral = \(CPtrdiff x) -> fromIntegral x -"fromIntegral/CSize->a" fromIntegral = \(CSize x) -> fromIntegral x -"fromIntegral/CWchar->a" fromIntegral = \(CWchar x) -> fromIntegral x -"fromIntegral/CSigAtomic->a" fromIntegral = \(CSigAtomic x) -> fromIntegral x - #-} - -- | Haskell type representing the C @clock_t@ type. -- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ ARITHMETIC_TYPE(CClock,HTYPE_CLOCK_T) @@ -252,13 +213,6 @@ INTEGRAL_TYPE(CUIntPtr,HTYPE_UINTPTR_T) INTEGRAL_TYPE(CIntMax,HTYPE_INTMAX_T) INTEGRAL_TYPE(CUIntMax,HTYPE_UINTMAX_T) -{-# RULES -"fromIntegral/a->CIntPtr" fromIntegral = \x -> CIntPtr (fromIntegral x) -"fromIntegral/a->CUIntPtr" fromIntegral = \x -> CUIntPtr (fromIntegral x) -"fromIntegral/a->CIntMax" fromIntegral = \x -> CIntMax (fromIntegral x) -"fromIntegral/a->CUIntMax" fromIntegral = \x -> CUIntMax (fromIntegral x) - #-} - -- C99 types which are still missing include: -- wint_t, wctrans_t, wctype_t |