Fix interaction of exprIsCheap and the lone-variable inlining check
[ghc-hetmet.git] / compiler / coreSyn / CoreSyn.lhs
index 04d3906..2ddc7a5 100644 (file)
@@ -4,6 +4,7 @@
 %
 
 \begin{code}
+{-# LANGUAGE DeriveDataTypeable #-}
 
 -- | CoreSyn holds all the main data types for use by for the Glasgow Haskell Compiler midsection
 module CoreSyn (
@@ -83,6 +84,7 @@ import FastString
 import Outputable
 import Util
 
+import Data.Data
 import Data.Word
 
 infixl 4 `mkApps`, `mkTyApps`, `mkVarApps`
@@ -135,11 +137,15 @@ infixl 8 `App`    -- App brackets to the left
 -- The type parameter @b@ is for the type of binders in the expression tree.
 data Expr b
   = Var          Id                            -- ^ Variables
+
   | Lit   Literal                       -- ^ Primitive literals
+
   | App   (Expr b) (Arg b)             -- ^ Applications: note that the argument may be a 'Type'.
                                         --
                                         -- See "CoreSyn#let_app_invariant" for another invariant
+
   | Lam   b (Expr b)                    -- ^ Lambda abstraction
+
   | Let   (Bind b) (Expr b)            -- ^ Recursive and non recursive @let@s. Operationally
                                         -- this corresponds to allocating a thunk for the things
                                         -- bound and then executing the sub-expression.
@@ -152,14 +158,16 @@ data Expr b
                                         -- the meaning of /lifted/ vs. /unlifted/).
                                         --
                                         -- #let_app_invariant#
-                                        -- The right hand side of of a non-recursive 'Let' _and_ the argument of an 'App',
+                                        -- The right hand side of of a non-recursive 'Let' 
+                                        -- _and_ the argument of an 'App',
                                         -- /may/ be of unlifted type, but only if the expression 
-                                        -- is ok-for-speculation.  This means that the let can be floated around 
-                                        -- without difficulty. For example, this is OK:
+                                        -- is ok-for-speculation.  This means that the let can be floated 
+                                        -- around without difficulty. For example, this is OK:
                                         --
                                        -- > y::Int# = x +# 1#
                                        --
-                                       -- But this is not, as it may affect termination if the expression is floated out:
+                                       -- But this is not, as it may affect termination if the 
+                                        -- expression is floated out:
                                        --
                                        -- > y::Int# = fac 4#
                                        --
@@ -179,6 +187,7 @@ data Expr b
                                         -- At the moment, the rest of the compiler only deals with type-let
                                         -- in a Let expression, rather than at top level.  We may want to revist
                                         -- this choice.
+
   | Case  (Expr b) b Type [Alt b]      -- ^ Case split. Operationally this corresponds to evaluating
                                         -- the scrutinee (expression examined) to weak head normal form
                                         -- and then examining at most one level of resulting constructor (i.e. you
@@ -188,15 +197,17 @@ data Expr b
                                         -- and the 'Type' must be that of all the case alternatives
                                        --
                                        -- #case_invariants#
-                                       -- This is one of the more complicated elements of the Core language, and comes
-                                       -- with a number of restrictions:
+                                       -- This is one of the more complicated elements of the Core language, 
+                                       -- and comes with a number of restrictions:
                                        --
-                                       -- The 'DEFAULT' case alternative must be first in the list, if it occurs at all.
+                                       -- The 'DEFAULT' case alternative must be first in the list, 
+                                        -- if it occurs at all.
                                        --
                                        -- The remaining cases are in order of increasing 
                                        --      tag     (for 'DataAlts') or
                                        --      lit     (for 'LitAlts').
-                                       -- This makes finding the relevant constructor easy, and makes comparison easier too.
+                                       -- This makes finding the relevant constructor easy, 
+                                        -- and makes comparison easier too.
                                        --
                                        -- The list of alternatives must be exhaustive. An /exhaustive/ case 
                                        -- does not necessarily mention all constructors:
@@ -210,14 +221,19 @@ data Expr b
                                         --                      Blue  -> ... ) ...
                                         -- @
                                         --
-                                        -- The inner case does not need a @Red@ alternative, because @x@ can't be @Red@ at
-                                        -- that program point.
-  | Cast  (Expr b) Coercion             -- ^ Cast an expression to a particular type. This is used to implement @newtype@s
-                                        -- (a @newtype@ constructor or destructor just becomes a 'Cast' in Core) and GADTs.
+                                        -- The inner case does not need a @Red@ alternative, because @x@ 
+                                        -- can't be @Red@ at that program point.
+
+  | Cast  (Expr b) Coercion             -- ^ Cast an expression to a particular type. 
+                                        -- This is used to implement @newtype@s (a @newtype@ constructor or 
+                                        -- destructor just becomes a 'Cast' in Core) and GADTs.
+
   | Note  Note (Expr b)                 -- ^ Notes. These allow general information to be
                                         -- added to expressions in the syntax tree
+
   | Type  Type                         -- ^ A type: this should only show up at the top
                                         -- level of an Arg
+  deriving (Data, Typeable)
 
 -- | Type synonym for expressions that occur in function argument positions.
 -- Only 'Arg' should contain a 'Type' at top level, general 'Expr' should not
@@ -233,11 +249,12 @@ data AltCon = DataAlt DataCon     -- ^ A plain data constructor: @case e of { Foo x
                                 -- Invariant: the 'DataCon' is always from a @data@ type, and never from a @newtype@
            | LitAlt  Literal   -- ^ A literal: @case e of { 1 -> ... }@
            | DEFAULT           -- ^ Trivial alternative: @case e of { _ -> ... }@
-        deriving (Eq, Ord)
+        deriving (Eq, Ord, Data, Typeable)
 
 -- | Binding, used for top level bindings in a module and local bindings in a @let@.
 data Bind b = NonRec b (Expr b)
            | Rec [(b, (Expr b))]
+  deriving (Data, Typeable)
 \end{code}
 
 -------------------------- CoreSyn INVARIANTS ---------------------------
@@ -277,6 +294,7 @@ See #type_let#
 data Note
   = SCC CostCentre      -- ^ A cost centre annotation for profiling
   | CoreNote String     -- ^ A generic core annotation, propagated but not used by GHC
+  deriving (Data, Typeable)
 \end{code}
 
 
@@ -474,6 +492,7 @@ data UnfoldingGuidance
                 -- See Note [INLINE for small functions] in CoreUnfold
       ug_unsat_ok  :: Bool,    -- True <=> ok to inline even if unsaturated
       ug_boring_ok :: Bool      -- True <=> ok to inline even if the context is boring
+               -- So True,True means "always"
     }
 
   | UnfIfGoodArgs {    -- Arose from a normal Id; the info here is the
@@ -621,6 +640,7 @@ unfoldingArity _                                = panic "unfoldingArity"
 
 isClosedUnfolding :: Unfolding -> Bool         -- No free variables
 isClosedUnfolding (CoreUnfolding {}) = False
+isClosedUnfolding (DFunUnfolding {}) = False
 isClosedUnfolding _                  = True
 
 -- | Only returns False if there is no unfolding information available at all
@@ -645,11 +665,13 @@ When you say
 you intend that calls (f e) are replaced by <rhs>[e/x] So we
 should capture (\x.<rhs>) in the Unfolding of 'f', and never meddle
 with it.  Meanwhile, we can optimise <rhs> to our heart's content,
-leaving the original unfolding intact in Unfolding of 'f'.
+leaving the original unfolding intact in Unfolding of 'f'. For example
+       all xs = foldr (&&) True xs
+       any p = all . map p  {-# INLINE any #-}
+We optimise any's RHS fully, but leave the InlineRule saying "all . map p",
+which deforests well at the call site.
 
-So the representation of an Unfolding has changed quite a bit
-(see CoreSyn).  An INLINE pragma gives rise to an InlineRule 
-unfolding.  
+So INLINE pragma gives rise to an InlineRule, which captures the original RHS.
 
 Moreover, it's only used when 'f' is applied to the
 specified number of arguments; that is, the number of argument on