Comments and layout only
authorSimon Peyton Jones <simonpj@microsoft.com>
Thu, 9 Jul 2015 12:19:53 +0000 (13:19 +0100)
committerSimon Peyton Jones <simonpj@microsoft.com>
Tue, 21 Jul 2015 14:56:58 +0000 (15:56 +0100)
This patch adds a lot of visual structure to this key module

libraries/ghc-prim/GHC/Types.hs

index a25d7ff..7bc746f 100644 (file)
 -----------------------------------------------------------------------------
 
 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