X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2FcoreSyn%2FCoreSyn.lhs;h=05de8607bbd20c1e7278c767c7018ed56a2f834e;hp=67245d1ac6d270728e9c4f601d8d8fbd28ae5e20;hb=7fc749a43b4b6b85d234fa95d4928648259584f4;hpb=7a327c1297615a9498e7117a0017b09ff2458d53 diff --git a/compiler/coreSyn/CoreSyn.lhs b/compiler/coreSyn/CoreSyn.lhs index 67245d1..05de860 100644 --- a/compiler/coreSyn/CoreSyn.lhs +++ b/compiler/coreSyn/CoreSyn.lhs @@ -6,6 +6,13 @@ CoreSyn: A data type for the Haskell compiler midsection \begin{code} +{-# OPTIONS -w #-} +-- The above warning supression flag is a temporary kludge. +-- While working on this module you are encouraged to remove it and fix +-- any warnings in the module. See +-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings +-- for details + module CoreSyn ( Expr(..), Alt, Bind(..), AltCon(..), Arg, Note(..), CoreExpr, CoreAlt, CoreBind, CoreArg, CoreBndr, @@ -54,13 +61,11 @@ import Var import Type import Coercion import Name -import OccName import Literal import DataCon import BasicTypes import FastString import Outputable -import Module infixl 4 `mkApps`, `mkValApps`, `mkTyApps`, `mkVarApps` -- Left associative, so that we can say (f `mkTyApps` xs `mkVarApps` ys) @@ -80,37 +85,17 @@ infixl 8 `App` -- App brackets to the left data Expr b -- "b" for the type of binders, = Var Id | Lit Literal - | App (Expr b) (Arg b) + | App (Expr b) (Arg b) -- See Note [CoreSyn let/app invariant] | Lam b (Expr b) - | Let (Bind b) (Expr b) + | Let (Bind b) (Expr b) -- See [CoreSyn let/app invariant], + -- and [CoreSyn letrec invariant] | Case (Expr b) b Type [Alt b] -- Binder gets bound to value of scrutinee - -- Invariant: The list of alternatives is ALWAYS EXHAUSTIVE, - -- meaning that it covers all cases that can occur - -- See the example below - -- - -- Invariant: The DEFAULT case must be *first*, if it occurs at all - -- Invariant: The remaining cases are in order of increasing - -- tag (for DataAlts) - -- lit (for LitAlts) - -- This makes finding the relevant constructor easy, - -- and makes comparison easier too + -- See Note [CoreSyn case invariants] | Cast (Expr b) Coercion | Note Note (Expr b) | Type Type -- This should only show up at the top -- level of an Arg --- An "exhausive" case does not necessarily mention all constructors: --- data Foo = Red | Green | Blue --- --- ...case x of --- Red -> True --- other -> f (case x of --- Green -> ... --- Blue -> ... ) --- The inner case does not need a Red alternative, because x can't be Red at --- that program point. - - type Arg b = Expr b -- Can be a Type type Alt b = (AltCon, [b], Expr b) -- (DEFAULT, [], rhs) is the default alternative @@ -124,7 +109,61 @@ data AltCon = DataAlt DataCon -- Invariant: the DataCon is always from data Bind b = NonRec b (Expr b) | Rec [(b, (Expr b))] +\end{code} + +-------------------------- CoreSyn INVARIANTS --------------------------- + +Note [CoreSyn top-level invariant] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* The RHSs of all top-level lets must be of LIFTED type. + +Note [CoreSyn letrec invariant] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* The RHS of a letrec must be of LIFTED type. + +Note [CoreSyn let/app invariant] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* The RHS 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. e.g. + y::Int# = x +# 1# ok + y::Int# = fac 4# not ok [use case instead] +This is intially enforced by DsUtils.mkDsLet and mkDsApp + +Note [CoreSyn case invariants] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Invariant: The DEFAULT case must be *first*, if it occurs at all + +Invariant: The remaining cases are in order of increasing + tag (for DataAlts) + lit (for LitAlts) + This makes finding the relevant constructor easy, + and makes comparison easier too + +Invariant: The list of alternatives is ALWAYS EXHAUSTIVE, + meaning that it covers all cases that can occur + An "exhausive" case does not necessarily mention all constructors: + data Foo = Red | Green | Blue + + ...case x of + Red -> True + other -> f (case x of + Green -> ... + Blue -> ... ) + The inner case does not need a Red alternative, because x can't be Red at + that program point. + + +Note [CoreSyn let goal] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* The simplifier tries to ensure that if the RHS of a let is a constructor + application, its arguments are trivial, so that the constructor can be + inlined vigorously. + + +\begin{code} data Note = SCC CostCentre @@ -133,11 +172,6 @@ data Note | CoreNote String -- A generic core annotation, propagated but not used by GHC - | TickBox Module !Int -- ^Tick box for Hpc-style coverage - | BinaryTickBox Module !Int !Int - -- ^Binary tick box, with a tick for result = True, result = False - - -- NOTE: we also treat expressions wrapped in InlineMe as -- 'cheap' and 'dupable' (in the sense of exprIsCheap, exprIsDupable) -- What this means is that we obediently inline even things that don't @@ -149,23 +183,6 @@ data Note -- should inline f even inside lambdas. In effect, we should trust the programmer. \end{code} -INVARIANTS: - -* The RHS of a letrec, and the RHSs of all top-level lets, - must be of LIFTED type. - -* The RHS of a let, 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. e.g. - y::Int# = x +# 1# ok - y::Int# = fac 4# not ok [use case instead] - -* The argument of an App can be of any type. - -* The simplifier tries to ensure that if the RHS of a let is a constructor - application, its arguments are trivial, so that the constructor can be - inlined vigorously. - %************************************************************************ %* * @@ -206,18 +223,25 @@ data CoreRule ru_rhs :: CoreExpr, -- Locality - ru_local :: Bool, -- The fn at the head of the rule is + ru_local :: Bool -- The fn at the head of the rule is -- defined in the same module as the rule - - -- Orphan-hood; see Note [Orphans] in InstEnv - ru_orph :: Maybe OccName } + -- and is not an implicit Id (like a record sel + -- class op, or data con) + -- NB: ru_local is *not* used to decide orphan-hood + -- c.g. MkIface.coreRuleToIfaceRule + } | BuiltinRule { -- Built-in rules are used for constant folding ru_name :: RuleName, -- and suchlike. It has no free variables. ru_fn :: Name, -- Name of the Id at -- the head of this rule - ru_nargs :: Int, -- Number of args that ru_try expects + ru_nargs :: Int, -- Number of args that ru_try expects, + -- including type args ru_try :: [CoreExpr] -> Maybe CoreExpr } + -- This function does the rewrite. It given too many + -- arguments, it simply discards them; the returned CoreExpr + -- is just the rewrite of ru_fn applied to the first ru_nargs args + -- See Note [Extra args in rule matching] in Rules.lhs isBuiltinRule (BuiltinRule {}) = True isBuiltinRule _ = False @@ -626,9 +650,6 @@ seqExprs [] = () seqExprs (e:es) = seqExpr e `seq` seqExprs es seqNote (CoreNote s) = s `seq` () -seqNote (TickBox m n) = m `seq` () -- no need for seq on n, because n is strict -seqNote (BinaryTickBox m t f) - = m `seq` () -- likewise on t and f. seqNote other = () seqBndr b = b `seq` ()