CoreSyn
Contents
Description
CoreSyn holds all the main data types for use by for the Glasgow Haskell Compiler midsection
- data Expr b
- type Alt b = (AltCon, [b], Expr b)
- data Bind b
- data AltCon
- type Arg b = Expr b
- data Note
- = SCC CostCentre
- | 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
- mkCoApps :: Expr b -> [Coercion] -> 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
- mkCoBind :: CoVar -> Coercion -> CoreBind
- varToCoreExpr :: CoreBndr -> Expr b
- varsToCoreExprs :: [CoreBndr] -> [Expr b]
- isId :: 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
- isTyCoArg :: Expr b -> Bool
- valArgCount :: [Arg b] -> Int
- valBndrCount :: [CoreBndr] -> Int
- isRuntimeArg :: CoreExpr -> Bool
- isRuntimeVar :: Var -> Bool
- notSccNote :: Note -> Bool
- data Unfolding
- = NoUnfolding
- | OtherCon [AltCon]
- | DFunUnfolding Arity DataCon [CoreExpr]
- | CoreUnfolding { }
- data UnfoldingGuidance
- = UnfWhen {
- ug_unsat_ok :: Bool
- ug_boring_ok :: Bool
- | UnfIfGoodArgs { }
- | UnfNever
- = UnfWhen {
- data UnfoldingSource
- noUnfolding :: Unfolding
- evaldUnfolding :: Unfolding
- mkOtherCon :: [AltCon] -> Unfolding
- needSaturated, unSaturatedOk :: Bool
- boringCxtNotOk, boringCxtOk :: Bool
- unfoldingTemplate :: Unfolding -> CoreExpr
- setUnfoldingTemplate :: Unfolding -> CoreExpr -> Unfolding
- expandUnfolding_maybe :: Unfolding -> Maybe CoreExpr
- maybeUnfoldingTemplate :: Unfolding -> Maybe CoreExpr
- otherCons :: Unfolding -> [AltCon]
- unfoldingArity :: Unfolding -> Arity
- isValueUnfolding :: Unfolding -> Bool
- isEvaldUnfolding :: Unfolding -> Bool
- isCheapUnfolding :: Unfolding -> Bool
- isExpandableUnfolding :: Unfolding -> Bool
- isConLikeUnfolding :: Unfolding -> Bool
- isCompulsoryUnfolding :: Unfolding -> Bool
- isStableUnfolding :: Unfolding -> Bool
- isStableCoreUnfolding_maybe :: Unfolding -> Maybe UnfoldingSource
- isClosedUnfolding :: Unfolding -> Bool
- hasSomeUnfolding :: Unfolding -> Bool
- canUnfold :: Unfolding -> Bool
- neverUnfoldGuidance :: UnfoldingGuidance -> Bool
- isStableSource :: UnfoldingSource -> 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) (annot, Coercion)
- | AnnNote Note (AnnExpr bndr annot)
- | AnnType Type
- | AnnCoercion Coercion
- data AnnBind bndr annot
- type AnnAlt bndr annot = (AltCon, [bndr], AnnExpr bndr annot)
- collectAnnArgs :: AnnExpr b a -> (AnnExpr b a, [AnnExpr b a])
- 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 { }
- | BuiltinRule { }
- type RuleName = FastString
- type IdUnfoldingFun = Id -> Unfolding
- seqRules :: [CoreRule] -> ()
- ruleArity :: CoreRule -> Int
- ruleName :: CoreRule -> RuleName
- ruleIdName :: CoreRule -> Name
- ruleActivation :: CoreRule -> Activation
- setRuleIdName :: Name -> CoreRule -> CoreRule
- isBuiltinRule :: CoreRule -> Bool
- isLocalRule :: CoreRule -> Bool
- data CoreVect
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:
- The source code is parsed into an abstract syntax tree, which is represented
by the data type
HsExpr.HsExpr
with the names beingRdrName.RdrNames
- This syntax tree is renamed, which attaches a
Unique.Unique
to everyRdrName.RdrName
(yielding aName
) 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 Unique
s 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)
- The resulting syntax tree undergoes type checking (which also deals with instantiating
type class arguments) to yield a
HsExpr.HsExpr
type that hasId.Id
as it's names. - Finally the syntax tree is desugared from the expressive
HsExpr.HsExpr
type into thisExpr
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 See CoreSyn for another invariant |
Lam b (Expr b) | Lambda abstraction |
Let (Bind b) (Expr b) | Recursive and non recursive The right hand sides of all top-level and recursive
The right hand side of of a non-recursive 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 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 This is one of the more complicated elements of the Core language, and comes with a number of restrictions: The The remaining cases are in order of increasing
tag (for 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 |
Cast (Expr b) Coercion | Cast an expression to a particular type.
This is used to implement |
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 |
Coercion Coercion | A coercion |
Instances
Typeable1 Expr | |
Data b => Data (Expr b) | |
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
.
Instances
Typeable1 Bind | |
Data b => Data (Bind b) | |
OutputableBndr b => Outputable (Bind b) |
data AltCon
A case alternative constructor (i.e. pattern match)
data Note
Allows attaching extra information to points in expressions rather than e.g. identifiers.
Constructors
SCC CostCentre | A cost centre annotation for profiling |
CoreNote String | A generic core annotation, propagated but not used by GHC |
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
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
mkCoApps :: Expr b -> [Coercion] -> Expr b
Apply a list of coercion 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
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
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
mkCoBind :: CoVar -> Coercion -> 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
varsToCoreExprs :: [CoreBndr] -> [Expr b]
Simple Expr
access functions and predicates
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
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?
notSccNote :: Note -> Bool
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.
data C = C !(Int -> Int) case x of { C f -> ... } Here, |
DFunUnfolding Arity DataCon [CoreExpr] | |
CoreUnfolding | An unfolding with redundant cached information. Parameters: uf_tmpl: Template used to perform unfolding; NB: Occurrence info is guaranteed correct: see Note [OccInfo in unfoldings and rules] uf_is_top: Is this a top level binding? uf_is_value: uf_is_cheap: Does this waste only a little work if we expand it inside an inlining?
Basically this is a cached version of uf_guidance: Tells us about the size of the unfolding template |
Fields
|
Instances
data UnfoldingGuidance
UnfoldingGuidance
says when unfolding should take place
Constructors
UnfWhen | |
Fields
| |
UnfIfGoodArgs | |
UnfNever |
Instances
Constructing Unfolding
s
There is no known 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
setUnfoldingTemplate :: Unfolding -> CoreExpr -> Unfolding
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
unfoldingArity :: Unfolding -> Arity
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?
isConLikeUnfolding :: Unfolding -> Bool
True
if the unfolding is a constructor application, the application
of a CONLIKE function or OtherCon
isStableUnfolding :: Unfolding -> Bool
isClosedUnfolding :: Unfolding -> Bool
hasSomeUnfolding :: Unfolding -> Bool
Only returns False if there is no unfolding information available at all
Strictness
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) (annot, Coercion) | |
AnnNote Note (AnnExpr bndr annot) | |
AnnType Type | |
AnnCoercion Coercion |
type AnnAlt bndr annot = (AltCon, [bndr], AnnExpr bndr annot)
A clone of the Alt
type but allowing annotation at every tree node
Operations on annotated expressions
collectAnnArgs :: AnnExpr b a -> (AnnExpr b a, [AnnExpr b a])
Takes a nested application expression and returns the the function being applied and the arguments to which it is applied
Operations on annotations
deAnnotate :: AnnExpr bndr annot -> Expr bndr
deAnnotate' :: AnnExpr' bndr annot -> Expr 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 | |
Fields
| |
BuiltinRule | Built-in rules are used for constant folding and suchlike. They have no free variables. |
Fields
|
Instances
type RuleName = FastString
type IdUnfoldingFun = Id -> Unfolding
Operations on CoreRule
s
The number of arguments the ru_fn
must be applied
to before the rule can match on it
ruleIdName :: CoreRule -> Name
The Name
of the Id.Id
at the head of the rule left hand side
ruleActivation :: CoreRule -> 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