diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2015-07-09 13:19:53 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2015-07-21 15:56:58 +0100 |
commit | 0df2348a329ed5f4b3893e6b8dc77066a0d77242 (patch) | |
tree | 8547bb61fb3762ac512ca4ad40cf31b31a46295f /libraries | |
parent | aa78cd64af14b227fa982ce9a35c56d4d2ffcf7b (diff) | |
download | haskell-0df2348a329ed5f4b3893e6b8dc77066a0d77242.tar.gz |
Comments and layout only
This patch adds a lot of visual structure to this key module
Diffstat (limited to 'libraries')
-rw-r--r-- | libraries/ghc-prim/GHC/Types.hs | 187 |
1 files changed, 125 insertions, 62 deletions
diff --git a/libraries/ghc-prim/GHC/Types.hs b/libraries/ghc-prim/GHC/Types.hs index a25d7ffaf2..7bc746f256 100644 --- a/libraries/ghc-prim/GHC/Types.hs +++ b/libraries/ghc-prim/GHC/Types.hs @@ -17,6 +17,12 @@ ----------------------------------------------------------------------------- module GHC.Types ( + -- Data types that are built-in syntax + -- They are defined here, but not explicitly exported + -- + -- Lists: []( [], (:) ) + -- Type equality: (~)( Eq# ) + Bool(..), Char(..), Int(..), Word(..), Float(..), Double(..), Ordering(..), IO(..), @@ -31,6 +37,12 @@ import GHC.Prim infixr 5 : +{- ********************************************************************* +* * + Nat and Symbol +* * +********************************************************************* -} + -- | (Kind) This is the kind of type-level natural numbers. data Nat @@ -38,9 +50,32 @@ data Nat -- Declared here because class IP needs it data Symbol + +{- ********************************************************************* +* * + Lists + + NB: lists are built-in syntax, and hence not explicitly exported +* * +********************************************************************* -} + data [] a = [] | a : [a] -data {-# CTYPE "HsBool" #-} Bool = False | True + +{- ********************************************************************* +* * + Ordering +* * +********************************************************************* -} + +data Ordering = LT | EQ | GT + + +{- ********************************************************************* +* * + Int, Char, Word, Float, Double +* * +********************************************************************* -} {- | The character type 'Char' is an enumeration whose values represent Unicode (or equivalently ISO\/IEC 10646) characters (see @@ -73,7 +108,12 @@ data {-# CTYPE "HsFloat" #-} Float = F# Float# -- to the IEEE double-precision type. data {-# CTYPE "HsDouble" #-} Double = D# Double# -data Ordering = LT | EQ | GT + +{- ********************************************************************* +* * + IO +* * +********************************************************************* -} {- | A value of type @'IO' a@ is a computation which, when performed, @@ -90,12 +130,21 @@ or the '>>' and '>>=' operations from the 'Monad' class. -} newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #)) type role IO representational -{- -The above role annotation is redundant but is included because this role -is significant in the normalisation of FFI types. Specifically, if this -role were to become nominal (which would be very strange, indeed!), changes -elsewhere in GHC would be necessary. See [FFI type roles] in TcForeign. --} + +{- The 'type role' role annotation for IO is redundant but is included +because this role is significant in the normalisation of FFI +types. Specifically, if this role were to become nominal (which would +be very strange, indeed!), changes elsewhere in GHC would be +necessary. See [FFI type roles] in TcForeign. -} + + +{- ********************************************************************* +* * + (~) and Coercible + + NB: (~) is built-in syntax, and hence not explicitly exported +* * +********************************************************************* -} {- Note [Kind-changing of (~) and Coercible] @@ -178,64 +227,78 @@ data Coercible a b = MkCoercible ((~#) a b) -- | Alias for 'tagToEnum#'. Returns True if its parameter is 1# and False -- if it is 0#. +{- ********************************************************************* +* * + Bool, and isTrue# +* * +********************************************************************* -} + +data {-# CTYPE "HsBool" #-} Bool = False | True + {-# INLINE isTrue# #-} isTrue# :: Int# -> Bool -- See Note [Optimizing isTrue#] isTrue# x = tagToEnum# x --- Note [Optimizing isTrue#] --- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- --- Current definition of isTrue# is a temporary workaround. We would like to --- have functions isTrue# and isFalse# defined like this: --- --- isTrue# :: Int# -> Bool --- isTrue# 1# = True --- isTrue# _ = False --- --- isFalse# :: Int# -> Bool --- isFalse# 0# = True --- isFalse# _ = False --- --- These functions would allow us to safely check if a tag can represent True --- or False. Using isTrue# and isFalse# as defined above will not introduce --- additional case into the code. When we scrutinize return value of isTrue# --- or isFalse#, either explicitly in a case expression or implicitly in a guard, --- the result will always be a single case expression (given that optimizations --- are turned on). This results from case-of-case transformation. Consider this --- code (this is both valid Haskell and Core): --- --- case isTrue# (a ># b) of --- True -> e1 --- False -> e2 --- --- Inlining isTrue# gives: --- --- case (case (a ># b) of { 1# -> True; _ -> False } ) of --- True -> e1 --- False -> e2 --- --- Case-of-case transforms that to: --- --- case (a ># b) of --- 1# -> case True of --- True -> e1 --- False -> e2 --- _ -> case False of --- True -> e1 --- False -> e2 --- --- Which is then simplified by case-of-known-constructor: --- --- case (a ># b) of --- 1# -> e1 --- _ -> e2 --- --- While we get good Core here, the code generator will generate very bad Cmm --- if e1 or e2 do allocation. It will push heap checks into case alternatives --- which results in about 2.5% increase in code size. Until this is improved we --- just make isTrue# an alias to tagToEnum#. This is a temporary solution (if --- you're reading this in 2023 then things went wrong). See #8326. --- +{- Note [Optimizing isTrue#] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Current definition of isTrue# is a temporary workaround. We would like to +have functions isTrue# and isFalse# defined like this: + + isTrue# :: Int# -> Bool + isTrue# 1# = True + isTrue# _ = False + + isFalse# :: Int# -> Bool + isFalse# 0# = True + isFalse# _ = False + +These functions would allow us to safely check if a tag can represent True +or False. Using isTrue# and isFalse# as defined above will not introduce +additional case into the code. When we scrutinize return value of isTrue# +or isFalse#, either explicitly in a case expression or implicitly in a guard, +the result will always be a single case expression (given that optimizations +are turned on). This results from case-of-case transformation. Consider this +code (this is both valid Haskell and Core): + +case isTrue# (a ># b) of + True -> e1 + False -> e2 + +Inlining isTrue# gives: + +case (case (a ># b) of { 1# -> True; _ -> False } ) of + True -> e1 + False -> e2 + +Case-of-case transforms that to: + +case (a ># b) of + 1# -> case True of + True -> e1 + False -> e2 + _ -> case False of + True -> e1 + False -> e2 + +Which is then simplified by case-of-known-constructor: + +case (a ># b) of + 1# -> e1 + _ -> e2 + +While we get good Core here, the code generator will generate very bad Cmm +if e1 or e2 do allocation. It will push heap checks into case alternatives +which results in about 2.5% increase in code size. Until this is improved we +just make isTrue# an alias to tagToEnum#. This is a temporary solution (if +you're reading this in 2023 then things went wrong). See #8326. +-} + + +{- ********************************************************************* +* * + SPEC +* * +********************************************************************* -} -- | 'SPEC' is used by GHC in the @SpecConstr@ pass in order to inform -- the compiler when to be particularly aggressive. In particular, it |