| ghc-6.10.4: The GHC API | Contents | Index

CoreSyn

Contents

Main data types
  `Expr` construction
  Simple `Expr` access functions and predicates
Unfolding data types
  Constructing `Unfolding`s
  Predicates and deconstruction on `Unfolding`
Strictness
Annotated expression data types
  Operations on annotations
Core rule data types
  Operations on `CoreRule`s

Description
CoreSyn holds all the main data types for use by for the Glasgow Haskell Compiler midsection
Synopsis

data Expr b

= Var Id
| Lit Literal
| App (Expr b) (Arg b)
| Lam b (Expr b)
| Let (Bind b) (Expr b)
| Case (Expr b) b Type [Alt b]
| Cast (Expr b) Coercion
| Note Note (Expr b)
| Type Type

type Alt b = (AltCon, [b], Expr b)

data Bind b

= NonRec b (Expr b)
| Rec [(b, Expr b)]

data AltCon

= DataAlt DataCon
| LitAlt Literal
| DEFAULT

type Arg b = Expr b

data Note

= SCC CostCentre
| InlineMe
| CoreNote String

type CoreExpr = Expr CoreBndr
type CoreAlt = Alt CoreBndr
type CoreBind = Bind CoreBndr
type CoreArg = Arg CoreBndr
type CoreBndr = Var
type TaggedExpr t = Expr (TaggedBndr t)
type TaggedAlt t = Alt (TaggedBndr t)
type TaggedBind t = Bind (TaggedBndr t)
type TaggedArg t = Arg (TaggedBndr t)
data TaggedBndr t = TB CoreBndr t
mkLets :: [Bind b] -> Expr b -> Expr b
mkLams :: [b] -> Expr b -> Expr b
mkApps :: Expr b -> [Arg b] -> Expr b
mkTyApps :: Expr b -> [Type] -> Expr b
mkVarApps :: Expr b -> [Var] -> Expr b
mkIntLit :: Integer -> Expr b
mkIntLitInt :: Int -> Expr b
mkWordLit :: Integer -> Expr b
mkWordLitWord :: Word -> Expr b
mkCharLit :: Char -> Expr b
mkStringLit :: String -> Expr b
mkFloatLit :: Rational -> Expr b
mkFloatLitFloat :: Float -> Expr b
mkDoubleLit :: Rational -> Expr b
mkDoubleLitDouble :: Double -> Expr b
mkConApp :: DataCon -> [Arg b] -> Expr b
mkTyBind :: TyVar -> Type -> CoreBind
varToCoreExpr :: CoreBndr -> Expr b
varsToCoreExprs :: [CoreBndr] -> [Expr b]
isTyVar :: Var -> Bool
isIdVar :: Var -> Bool
cmpAltCon :: AltCon -> AltCon -> Ordering
cmpAlt :: Alt b -> Alt b -> Ordering
ltAlt :: Alt b -> Alt b -> Bool
bindersOf :: Bind b -> [b]
bindersOfBinds :: [Bind b] -> [b]
rhssOfBind :: Bind b -> [Expr b]
rhssOfAlts :: [Alt b] -> [Expr b]
collectBinders :: Expr b -> ([b], Expr b)
collectTyBinders :: CoreExpr -> ([TyVar], CoreExpr)
collectValBinders :: CoreExpr -> ([Id], CoreExpr)
collectTyAndValBinders :: CoreExpr -> ([TyVar], [Id], CoreExpr)
collectArgs :: Expr b -> (Expr b, [Arg b])
coreExprCc :: Expr b -> CostCentre
flattenBinds :: [Bind b] -> [(b, Expr b)]
isValArg :: Expr b -> Bool
isTypeArg :: Expr b -> Bool
valArgCount :: [Arg b] -> Int
valBndrCount :: [CoreBndr] -> Int
isRuntimeArg :: CoreExpr -> Bool
isRuntimeVar :: Var -> Bool

data Unfolding

= NoUnfolding
| OtherCon [AltCon]
| CompulsoryUnfolding CoreExpr
| CoreUnfolding CoreExpr Bool Bool Bool UnfoldingGuidance

data UnfoldingGuidance

= UnfoldNever
| UnfoldIfGoodArgs Int [Int] Int Int

noUnfolding :: Unfolding
evaldUnfolding :: Unfolding
mkOtherCon :: [AltCon] -> Unfolding
unfoldingTemplate :: Unfolding -> CoreExpr
maybeUnfoldingTemplate :: Unfolding -> Maybe CoreExpr
otherCons :: Unfolding -> [AltCon]
isValueUnfolding :: Unfolding -> Bool
isEvaldUnfolding :: Unfolding -> Bool
isCheapUnfolding :: Unfolding -> Bool
isCompulsoryUnfolding :: Unfolding -> Bool
hasUnfolding :: Unfolding -> Bool
hasSomeUnfolding :: Unfolding -> Bool
neverUnfold :: Unfolding -> Bool
seqExpr :: CoreExpr -> ()
seqExprs :: [CoreExpr] -> ()
seqUnfolding :: Unfolding -> ()
type AnnExpr bndr annot = (annot, AnnExpr' bndr annot)

data AnnExpr' bndr annot

= AnnVar Id
| AnnLit Literal
| AnnLam bndr (AnnExpr bndr annot)
| AnnApp (AnnExpr bndr annot) (AnnExpr bndr annot)
| AnnCase (AnnExpr bndr annot) bndr Type [AnnAlt bndr annot]
| AnnLet (AnnBind bndr annot) (AnnExpr bndr annot)
| AnnCast (AnnExpr bndr annot) Coercion
| AnnNote Note (AnnExpr bndr annot)
| AnnType Type

data AnnBind bndr annot

= AnnNonRec bndr (AnnExpr bndr annot)
| AnnRec [(bndr, AnnExpr bndr annot)]

type AnnAlt bndr annot = (AltCon, [bndr], AnnExpr bndr annot)
deAnnotate :: AnnExpr bndr annot -> Expr bndr
deAnnotate' :: AnnExpr' bndr annot -> Expr bndr
deAnnAlt :: AnnAlt bndr annot -> Alt bndr
collectAnnBndrs :: AnnExpr bndr annot -> ([bndr], AnnExpr bndr annot)

data CoreRule

= Rule {

ru_name :: RuleName
ru_act :: Activation
ru_fn :: Name
ru_rough :: [Maybe Name]
ru_bndrs :: [CoreBndr]
ru_args :: [CoreExpr]
ru_rhs :: CoreExpr
ru_local :: Bool

}

| BuiltinRule {

ru_name :: RuleName
ru_fn :: Name
ru_nargs :: Int
ru_try :: [CoreExpr] -> Maybe CoreExpr

}

type RuleName = FastString
seqRules :: [CoreRule] -> ()
ruleArity :: CoreRule -> Int
ruleName :: CoreRule -> RuleName
ruleIdName :: CoreRule -> Name
ruleActivation_maybe :: CoreRule -> Maybe Activation
setRuleIdName :: Name -> CoreRule -> CoreRule
isBuiltinRule :: CoreRule -> Bool
isLocalRule :: CoreRule -> Bool

Main data types
data Expr b

This is the data type that represents GHCs core intermediate language. Currently GHC uses System FC http://research.microsoft.com/~simonpj/papers/ext-f/ for this purpose, which is closely related to the simpler and better known System F http://en.wikipedia.org/wiki/System_F.

We get from Haskell source to this Core language in a number of stages:

1. The source code is parsed into an abstract syntax tree, which is represented by the data type HsExpr.HsExpr with the names being RdrName.RdrNames

2. This syntax tree is renamed, which attaches a Unique.Unique to every RdrName.RdrName (yielding a `Name`) to disambiguate identifiers which are lexically identical. For example, this program:

          f x = let f x = x + 1
                in f (x - 2)

Would be renamed by having Uniques attached so it looked something like this:

          f_1 x_2 = let f_3 x_4 = x_4 + 1
                    in f_3 (x_2 - 2)

3. The resulting syntax tree undergoes type checking (which also deals with instantiating type class arguments) to yield a HsExpr.HsExpr type that has Id.Id as it's names.

4. Finally the syntax tree is desugared from the expressive HsExpr.HsExpr type into this `Expr` type, which has far fewer constructors and hence is easier to perform optimization, analysis and code generation on.

The type parameter `b` is for the type of binders in the expression tree.

Constructors

Var Id | Variables
Lit Literal | Primitive literals
App (Expr b) (Arg b) | Applications: note that the argument may be a `Type`. See CoreSyn 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.

The right hand sides of all top-level and recursive `let`s must be of lifted type (see Type for the meaning of lifted vs. unlifted).

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:

     y::Int# = x +# 1#

But this is not, as it may affect termination if the expression is floated out:

     y::Int# = fac 4#

In this situation you should use `case` rather than a `let`. The function CoreUtils.needsCaseBinding can help you determine which to generate, or alternatively use MkCore.mkCoreLet rather than this constructor directly, which will generate a `case` if necessary

We allow a non-recursive let to bind a type variable, thus:

     Let (NonRec tv (Type ty)) body

This can be very convenient for postponing type substitutions until the next run of the simplifier.

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 cannot do nested pattern matching directly with this).

The binder gets bound to the value of the scrutinee, and the `Type` must be that of all the case alternatives

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 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.

The list of alternatives must be exhaustive. An exhaustive 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.

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

Instances

OutputableBndr b => Outputable (Expr b)

type Alt b = (AltCon, [b], Expr b)
A case split alternative. Consists of the constructor leading to the alternative, the variables bound from the constructor, and the expression to be executed given that binding. The default alternative is `(DEFAULT, [], rhs)`
data Bind b

Binding, used for top level bindings in a module and local bindings in a `let`.
Constructors

NonRec b (Expr b) |
Rec [(b, Expr b)] |

Instances

OutputableBndr b => Outputable (Bind b)

data AltCon

A case alternative constructor (i.e. pattern match)
Constructors

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 { _ -> ... }`

Instances

Eq AltCon
Ord AltCon
Show AltCon
Outputable AltCon

type Arg b = Expr b
Type synonym for expressions that occur in function argument positions. Only `Arg` should contain a `Type` at top level, general `Expr` should not
data Note

Allows attaching extra information to points in expressions rather than e.g. identifiers.
Constructors

SCC CostCentre | A cost centre annotation for profiling
InlineMe | Instructs the core simplifer to treat the enclosed expression as very small, and inline it at its call sites
CoreNote String | A generic core annotation, propagated but not used by GHC

type CoreExpr = Expr CoreBndr
Expressions where binders are `CoreBndr`s
type CoreAlt = Alt CoreBndr
Case alternatives where binders are `CoreBndr`s
type CoreBind = Bind CoreBndr
Binding groups where binders are `CoreBndr`s
type CoreArg = Arg CoreBndr
Argument expressions where binders are `CoreBndr`s
type CoreBndr = Var
The common case for the type of binders and variables when we are manipulating the Core language within GHC
type TaggedExpr t = Expr (TaggedBndr t)
type TaggedAlt t = Alt (TaggedBndr t)
type TaggedBind t = Bind (TaggedBndr t)
type TaggedArg t = Arg (TaggedBndr t)
data TaggedBndr t

Binders are tagged with a t
Constructors

TB CoreBndr t |

Instances

Outputable b => OutputableBndr (TaggedBndr b)
Outputable b => Outputable (TaggedBndr b)

`Expr` construction
mkLets :: [Bind b] -> Expr b -> Expr b
Bind all supplied binding groups over an expression in a nested let expression. Prefer to use CoreUtils.mkCoreLets if possible
mkLams :: [b] -> Expr b -> Expr b
Bind all supplied binders over an expression in a nested lambda expression. Prefer to use CoreUtils.mkCoreLams if possible
mkApps :: Expr b -> [Arg b] -> Expr b
Apply a list of argument expressions to a function expression in a nested fashion. Prefer to use CoreUtils.mkCoreApps if possible
mkTyApps :: Expr b -> [Type] -> Expr b
Apply a list of type argument expressions to a function expression in a nested fashion
mkVarApps :: Expr b -> [Var] -> Expr b
Apply a list of type or value variables to a function expression in a nested fashion
mkIntLit :: Integer -> Expr b
Create a machine integer literal expression of type `Int#` from an `Integer`. If you want an expression of type `Int` use MkCore.mkIntExpr
mkIntLitInt :: Int -> Expr b
Create a machine integer literal expression of type `Int#` from an `Int`. If you want an expression of type `Int` use MkCore.mkIntExpr
mkWordLit :: Integer -> Expr b
Create a machine word literal expression of type `Word#` from an `Integer`. If you want an expression of type `Word` use MkCore.mkWordExpr
mkWordLitWord :: Word -> Expr b
Create a machine word literal expression of type `Word#` from a `Word`. If you want an expression of type `Word` use MkCore.mkWordExpr
mkCharLit :: Char -> Expr b
Create a machine character literal expression of type `Char#`. If you want an expression of type `Char` use MkCore.mkCharExpr
mkStringLit :: String -> Expr b
Create a machine string literal expression of type `Addr#`. If you want an expression of type `String` use MkCore.mkStringExpr
mkFloatLit :: Rational -> Expr b
Create a machine single precision literal expression of type `Float#` from a `Rational`. If you want an expression of type `Float` use MkCore.mkFloatExpr
mkFloatLitFloat :: Float -> Expr b
Create a machine single precision literal expression of type `Float#` from a `Float`. If you want an expression of type `Float` use MkCore.mkFloatExpr
mkDoubleLit :: Rational -> Expr b
Create a machine double precision literal expression of type `Double#` from a `Rational`. If you want an expression of type `Double` use MkCore.mkDoubleExpr
mkDoubleLitDouble :: Double -> Expr b
Create a machine double precision literal expression of type `Double#` from a `Double`. If you want an expression of type `Double` use MkCore.mkDoubleExpr
mkConApp :: DataCon -> [Arg b] -> Expr b
Apply a list of argument expressions to a data constructor in a nested fashion. Prefer to use MkCore.mkCoreConApps if possible
mkTyBind :: TyVar -> Type -> CoreBind
Create a binding group where a type variable is bound to a type. Per CoreSyn, this can only be used to bind something in a non-recursive `let` expression
varToCoreExpr :: CoreBndr -> Expr b
Convert a binder into either a `Var` or `Type` `Expr` appropriately
varsToCoreExprs :: [CoreBndr] -> [Expr b]
isTyVar :: Var -> Bool
isIdVar :: Var -> Bool
cmpAltCon :: AltCon -> AltCon -> Ordering
Compares `AltCon`s within a single list of alternatives
cmpAlt :: Alt b -> Alt b -> Ordering
ltAlt :: Alt b -> Alt b -> Bool
Simple `Expr` access functions and predicates
bindersOf :: Bind b -> [b]
Extract every variable by this group
bindersOfBinds :: [Bind b] -> [b]
`bindersOf` applied to a list of binding groups
rhssOfBind :: Bind b -> [Expr b]
rhssOfAlts :: [Alt b] -> [Expr b]
collectBinders :: Expr b -> ([b], Expr b)
We often want to strip off leading lambdas before getting down to business. This function is your friend.
collectTyBinders :: CoreExpr -> ([TyVar], CoreExpr)
Collect as many type bindings as possible from the front of a nested lambda
collectValBinders :: CoreExpr -> ([Id], CoreExpr)
Collect as many value bindings as possible from the front of a nested lambda
collectTyAndValBinders :: CoreExpr -> ([TyVar], [Id], CoreExpr)
Collect type binders from the front of the lambda first, then follow up by collecting as many value bindings as possible from the resulting stripped expression
collectArgs :: Expr b -> (Expr b, [Arg b])
Takes a nested application expression and returns the the function being applied and the arguments to which it is applied
coreExprCc :: Expr b -> CostCentre
Gets the cost centre enclosing an expression, if any. It looks inside lambdas because `(scc "foo" \x.e) = \x. scc "foo" e`
flattenBinds :: [Bind b] -> [(b, Expr b)]
Collapse all the bindings in the supplied groups into a single list of lhs/rhs pairs suitable for binding in a `Rec` binding group
isValArg :: Expr b -> Bool
Returns `False` iff the expression is a `Type` expression at its top level
isTypeArg :: Expr b -> Bool
Returns `True` iff the expression is a `Type` expression at its top level
valArgCount :: [Arg b] -> Int
The number of argument expressions that are values rather than types at their top level
valBndrCount :: [CoreBndr] -> Int
The number of binders that bind values rather than types
isRuntimeArg :: CoreExpr -> Bool
Will this argument expression exist at runtime?
isRuntimeVar :: Var -> Bool
Will this variable exist at runtime?
Unfolding data types
data Unfolding

Records the unfolding of an identifier, which is approximately the form the identifier would have if we substituted its definition in for the identifier. This type should be treated as abstract everywhere except in CoreUnfold
Constructors

NoUnfolding | We have no information about the unfolding

OtherCon [AltCon]

It ain't one of these constructors. `OtherCon xs` also indicates that something has been evaluated and hence there's no point in re-evaluating it. `OtherCon []` is used even for non-data-type values to indicated evaluated-ness. Notably:

     data C = C !(Int -> Int)
     case x of { C f -> ... }

Here, `f` gets an `OtherCon []` unfolding.

CompulsoryUnfolding CoreExpr | There is no original definition, so you'd better unfold.

CoreUnfolding CoreExpr Bool Bool Bool UnfoldingGuidance

An unfolding with redundant cached information. Parameters:

1) Template used to perform unfolding; binder-info is correct

2) Is this a top level binding?

3) exprIsHNF template (cached); it is ok to discard a `seq` on this variable

4) Does this waste only a little work if we expand it inside an inlining? Basically this is a cached version of exprIsCheap

5) Tells us about the size of the unfolding template

Instances

Outputable Unfolding

data UnfoldingGuidance

When unfolding should take place
Constructors

UnfoldNever |
UnfoldIfGoodArgs Int [Int] Int Int |

Instances

Outputable UnfoldingGuidance

Constructing `Unfolding`s
noUnfolding :: Unfolding
There is no known `Unfolding`
evaldUnfolding :: Unfolding
This unfolding marks the associated thing as being evaluated
mkOtherCon :: [AltCon] -> Unfolding
Predicates and deconstruction on `Unfolding`
unfoldingTemplate :: Unfolding -> CoreExpr
Retrieves the template of an unfolding: panics if none is known
maybeUnfoldingTemplate :: Unfolding -> Maybe CoreExpr
Retrieves the template of an unfolding if possible
otherCons :: Unfolding -> [AltCon]
The constructors that the unfolding could never be: returns `[]` if no information is available
isValueUnfolding :: Unfolding -> Bool
Determines if it is certainly the case that the unfolding will yield a value (something in HNF): returns `False` if unsure
isEvaldUnfolding :: Unfolding -> Bool
Determines if it possibly the case that the unfolding will yield a value. Unlike `isValueUnfolding` it returns `True` for `OtherCon`
isCheapUnfolding :: Unfolding -> Bool
Is the thing we will unfold into certainly cheap?
isCompulsoryUnfolding :: Unfolding -> Bool
Must this unfolding happen for the code to be executable?
hasUnfolding :: Unfolding -> Bool
Do we have an available or compulsory unfolding?
hasSomeUnfolding :: Unfolding -> Bool
Only returns False if there is no unfolding information available at all
neverUnfold :: Unfolding -> Bool
Similar to `not . hasUnfolding`, but also returns `True` if it has an unfolding that says it should never occur
Strictness
seqExpr :: CoreExpr -> ()
seqExprs :: [CoreExpr] -> ()
seqUnfolding :: Unfolding -> ()
Annotated expression data types
type AnnExpr bndr annot = (annot, AnnExpr' bndr annot)
Annotated core: allows annotation at every node in the tree
data AnnExpr' bndr annot

A clone of the `Expr` type but allowing annotation at every tree node
Constructors

AnnVar Id |
AnnLit Literal |
AnnLam bndr (AnnExpr bndr annot) |
AnnApp (AnnExpr bndr annot) (AnnExpr bndr annot) |
AnnCase (AnnExpr bndr annot) bndr Type [AnnAlt bndr annot] |
AnnLet (AnnBind bndr annot) (AnnExpr bndr annot) |
AnnCast (AnnExpr bndr annot) Coercion |
AnnNote Note (AnnExpr bndr annot) |
AnnType Type |

data AnnBind bndr annot

A clone of the `Bind` type but allowing annotation at every tree node
Constructors

AnnNonRec bndr (AnnExpr bndr annot) |
AnnRec [(bndr, AnnExpr bndr annot)] |

type AnnAlt bndr annot = (AltCon, [bndr], AnnExpr bndr annot)
A clone of the `Alt` type but allowing annotation at every tree node
Operations on annotations
deAnnotate :: AnnExpr bndr annot -> Expr bndr
deAnnotate' :: AnnExpr' bndr annot -> Expr bndr
deAnnAlt :: AnnAlt bndr annot -> Alt bndr
collectAnnBndrs :: AnnExpr bndr annot -> ([bndr], AnnExpr bndr annot)
As `collectBinders` but for `AnnExpr` rather than `Expr`
Core rule data types
data CoreRule

A `CoreRule` is:

- "Local" if the function it is a rule for is defined in the same module as the rule itself.
- "Orphan" if nothing on the LHS is defined in the same module as the rule itself

Constructors

Rule |

ru_name :: RuleName | Name of the rule, for communication with the user
ru_act :: Activation | When the rule is active
ru_fn :: Name | Name of the Id.Id at the head of this rule
ru_rough :: [Maybe Name] | Name at the head of each argument to the left hand side
ru_bndrs :: [CoreBndr] | Variables quantified over
ru_args :: [CoreExpr] | Left hand side arguments
ru_rhs :: CoreExpr | Right hand side of the rule
ru_local :: Bool | `True` iff the fn at the head of the rule is defined in the same module as the rule and is not an implicit `Id` (like a record selector, class operation, or data constructor)

BuiltinRule | Built-in rules are used for constant folding and suchlike. They have no free variables.

ru_name :: RuleName | As above
ru_fn :: Name | As above
ru_nargs :: Int | Number of arguments that `ru_try` expects, including type arguments
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

Instances

Outputable CoreRule

type RuleName = FastString
Operations on `CoreRule`s
seqRules :: [CoreRule] -> ()
ruleArity :: CoreRule -> Int
The number of arguments the `ru_fn` must be applied to before the rule can match on it
ruleName :: CoreRule -> RuleName
ruleIdName :: CoreRule -> Name
The `Name` of the Id.Id at the head of the rule left hand side
ruleActivation_maybe :: CoreRule -> Maybe Activation
setRuleIdName :: Name -> CoreRule -> CoreRule
Set the `Name` of the Id.Id at the head of the rule left hand side
isBuiltinRule :: CoreRule -> Bool
isLocalRule :: CoreRule -> Bool
Produced by Haddock version 2.4.2