Commit bd438b2d authored by Simon Peyton Jones's avatar Simon Peyton Jones

Get evaluated-ness right in the back end

See Trac #14626, comment:4.  We want to maintain evaluted-ness
info on Ids into the code generateor for two reasons
(see Note [Preserve evaluated-ness in CorePrep] in CorePrep)

- DataToTag magic
- Potentially using it in the codegen (this is Gabor's
  current work)

But it was all being done very inconsistently, and actually
outright wrong -- the DataToTag magic hasn't been working for
years.

This patch tidies it all up, with Notes to match.
parent 9e5535ca
......@@ -29,7 +29,7 @@ module IdInfo (
-- ** Zapping various forms of Info
zapLamInfo, zapFragileInfo,
zapDemandInfo, zapUsageInfo, zapUsageEnvInfo, zapUsedOnceInfo,
zapTailCallInfo, zapCallArityInfo,
zapTailCallInfo, zapCallArityInfo, zapUnfolding,
-- ** The ArityInfo type
ArityInfo,
......@@ -547,6 +547,11 @@ zapFragileUnfolding unf
| isFragileUnfolding unf = noUnfolding
| otherwise = unf
zapUnfolding :: Unfolding -> Unfolding
-- Squash all unfolding info, preserving only evaluated-ness
zapUnfolding unf | isEvaldUnfolding unf = evaldUnfolding
| otherwise = noUnfolding
zapTailCallInfo :: IdInfo -> Maybe IdInfo
zapTailCallInfo info
= case occInfo info of
......
......@@ -407,23 +407,21 @@ cpeBind top_lvl env (NonRec bndr rhs)
= do { (_, bndr1) <- cpCloneBndr env bndr
; let dmd = idDemandInfo bndr
is_unlifted = isUnliftedType (idType bndr)
; (floats, bndr2, rhs2) <- cpePair top_lvl NonRecursive
dmd
is_unlifted
env bndr1 rhs
; (floats, rhs1) <- cpePair top_lvl NonRecursive
dmd is_unlifted
env bndr1 rhs
-- See Note [Inlining in CorePrep]
; if exprIsTrivial rhs2 && isNotTopLevel top_lvl
then return (extendCorePrepEnvExpr env bndr rhs2, floats, Nothing)
; if exprIsTrivial rhs1 && isNotTopLevel top_lvl
then return (extendCorePrepEnvExpr env bndr rhs1, floats, Nothing)
else do {
; let new_float = mkFloat dmd is_unlifted bndr2 rhs2
; let new_float = mkFloat dmd is_unlifted bndr1 rhs1
-- We want bndr'' in the envt, because it records
-- the evaluated-ness of the binder
; return (extendCorePrepEnv env bndr bndr2,
; return (extendCorePrepEnv env bndr bndr1,
addFloat floats new_float,
Nothing) }}
| otherwise -- See Note [Join points and floating]
| otherwise -- A join point; see Note [Join points and floating]
= ASSERT(not (isTopLevel top_lvl)) -- can't have top-level join point
do { (_, bndr1) <- cpCloneBndr env bndr
; (bndr2, rhs1) <- cpeJoinPair env bndr1 rhs
......@@ -434,14 +432,17 @@ cpeBind top_lvl env (NonRec bndr rhs)
cpeBind top_lvl env (Rec pairs)
| not (isJoinId (head bndrs))
= do { (env', bndrs1) <- cpCloneBndrs env bndrs
; stuff <- zipWithM (cpePair top_lvl Recursive topDmd False env') bndrs1 rhss
; stuff <- zipWithM (cpePair top_lvl Recursive topDmd False env')
bndrs1 rhss
; let (floats_s, bndrs2, rhss2) = unzip3 stuff
all_pairs = foldrOL add_float (bndrs2 `zip` rhss2)
; let (floats_s, rhss1) = unzip stuff
all_pairs = foldrOL add_float (bndrs1 `zip` rhss1)
(concatFloats floats_s)
; return (extendCorePrepEnvList env (bndrs `zip` bndrs2),
; return (extendCorePrepEnvList env (bndrs `zip` bndrs1),
unitFloat (FloatLet (Rec all_pairs)),
Nothing) }
| otherwise -- See Note [Join points and floating]
= do { (env', bndrs1) <- cpCloneBndrs env bndrs
; pairs1 <- zipWithM (cpeJoinPair env') bndrs1 rhss
......@@ -461,9 +462,10 @@ cpeBind top_lvl env (Rec pairs)
---------------
cpePair :: TopLevelFlag -> RecFlag -> Demand -> Bool
-> CorePrepEnv -> Id -> CoreExpr
-> UniqSM (Floats, Id, CpeRhs)
-> CorePrepEnv -> OutId -> CoreExpr
-> UniqSM (Floats, CpeRhs)
-- Used for all bindings
-- The binder is already cloned, hence an OutId
cpePair top_lvl is_rec dmd is_unlifted env bndr rhs
= ASSERT(not (isJoinId bndr)) -- those should use cpeJoinPair
do { (floats1, rhs1) <- cpeRhsE env rhs
......@@ -485,15 +487,7 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs
-- Wrap floating ticks
; let (floats4, rhs4) = wrapTicks floats3 rhs3
-- Record if the binder is evaluated
-- and otherwise trim off the unfolding altogether
-- It's not used by the code generator; getting rid of it reduces
-- heap usage and, since we may be changing uniques, we'd have
-- to substitute to keep it right
; let bndr' | exprIsHNF rhs3 = bndr `setIdUnfolding` evaldUnfolding
| otherwise = bndr `setIdUnfolding` noUnfolding
; return (floats4, bndr', rhs4) }
; return (floats4, rhs4) }
where
platform = targetPlatform (cpe_dynFlags env)
......@@ -573,7 +567,6 @@ cpeJoinPair env bndr rhs
{-
Note [Arity and join points]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Up to now, we've allowed a join point to have an arity greater than its join
arity (minus type arguments), since this is what's useful for eta expansion.
However, for code gen purposes, its arity must be exactly the number of value
......@@ -644,9 +637,7 @@ cpeRhsE env expr@(Lam {})
cpeRhsE env (Case scrut bndr ty alts)
= do { (floats, scrut') <- cpeBody env scrut
; let bndr1 = bndr `setIdUnfolding` evaldUnfolding
-- Record that the case binder is evaluated in the alternatives
; (env', bndr2) <- cpCloneBndr env bndr1
; (env', bndr2) <- cpCloneBndr env bndr
; let alts'
-- This flag is intended to aid in debugging strictness
-- analysis bugs. These are particularly nasty to chase down as
......@@ -1083,16 +1074,26 @@ saturateDataToTag sat_expr
eval_data2tag_arg other -- Should not happen
= pprPanic "eval_data2tag" (ppr other)
{-
Note [dataToTag magic]
~~~~~~~~~~~~~~~~~~~~~~
Horrid: we must ensure that the arg of data2TagOp is evaluated
(data2tag x) --> (case x of y -> data2tag y)
{- Note [dataToTag magic]
~~~~~~~~~~~~~~~~~~~~~~~~~
We must ensure that the arg of data2TagOp is evaluated. So
in general CorePrep does this transformation:
data2tag e --> case e of y -> data2tag y
(yuk yuk) take into account the lambdas we've now introduced
How might it not be evaluated? Well, we might have floated it out
of the scope of a `seq`, or dropped the `seq` altogether.
We only do this if 'e' is not a WHNF. But if it's a simple
variable (common case) we need to know it's evaluated-ness flag.
Example:
data T = MkT !Bool
f v = case v of
MkT y -> dataToTag# y
Here we don't want to generate an extra case on 'y', because it's
already evaluated. So we want to keep the evaluated-ness flag
on y. See Note [Preserve evaluated-ness in CorePrep].
************************************************************************
* *
......@@ -1545,26 +1546,67 @@ getMkIntegerId = cpe_mkIntegerId
-- Cloning binders
-- ---------------------------------------------------------------------------
cpCloneBndrs :: CorePrepEnv -> [Var] -> UniqSM (CorePrepEnv, [Var])
cpCloneBndrs :: CorePrepEnv -> [InVar] -> UniqSM (CorePrepEnv, [OutVar])
cpCloneBndrs env bs = mapAccumLM cpCloneBndr env bs
cpCloneBndr :: CorePrepEnv -> Var -> UniqSM (CorePrepEnv, Var)
cpCloneBndr :: CorePrepEnv -> InVar -> UniqSM (CorePrepEnv, OutVar)
cpCloneBndr env bndr
| isLocalId bndr, not (isCoVar bndr)
= do bndr' <- setVarUnique bndr <$> getUniqueM
-- We are going to OccAnal soon, so drop (now-useless) rules/unfoldings
-- so that we can drop more stuff as dead code.
-- See also Note [Dead code in CorePrep]
let bndr'' = bndr' `setIdUnfolding` noUnfolding
`setIdSpecialisation` emptyRuleInfo
return (extendCorePrepEnv env bndr bndr'', bndr'')
| otherwise -- Top level things, which we don't want
-- to clone, have become GlobalIds by now
-- And we don't clone tyvars, or coercion variables
| not (isId bndr)
= return (env, bndr)
| otherwise
= do { bndr' <- clone_it bndr
-- Drop (now-useless) rules/unfoldings
-- See Note [Drop unfoldings and rules]
-- and Note [Preserve evaluated-ness in CorePrep]
; let unfolding' = zapUnfolding (realIdUnfolding bndr)
-- Simplifier will set the Id's unfolding
bndr'' = bndr' `setIdUnfolding` unfolding'
`setIdSpecialisation` emptyRuleInfo
; return (extendCorePrepEnv env bndr bndr'', bndr'') }
where
clone_it bndr
| isLocalId bndr, not (isCoVar bndr)
= do { uniq <- getUniqueM; return (setVarUnique bndr uniq) }
| otherwise -- Top level things, which we don't want
-- to clone, have become GlobalIds by now
-- And we don't clone tyvars, or coercion variables
= return bndr
{- Note [Drop unfoldings and rules]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We want to drop the unfolding/rules on every Id:
- We are now past interface-file generation, and in the
codegen pipeline, so we really don't need full unfoldings/rules
- The unfolding/rule may be keeping stuff alive that we'd like
to discard. See Note [Dead code in CorePrep]
- Getting rid of unnecessary unfoldings reduces heap usage
- We are changing uniques, so if we didn't discard unfoldings/rules
we'd have to substitute in them
HOWEVER, we want to preserve evaluated-ness; see
Note [Preserve evaluated-ness in CorePrep]
Note [Preserve evaluated-ness in CorePrep]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We want to preserve the evaluated-ness of each binder (via
evaldUnfolding) for two reasons
* In the code generator if we have
case x of y { Red -> e1; DEFAULT -> y }
we can return 'y' rather than entering it, if we know
it is evaluated (Trac #14626)
* In the DataToTag magic (in CorePrep itself) we rely on
evaluated-ness. See Note Note [dataToTag magic].
-}
------------------------------------------------------------------------------
-- Cloning ccall Ids; each must have a unique name,
......
......@@ -159,9 +159,7 @@ tidyIdBndr env@(tidy_env, var_env) id
`setOneShotInfo` oneShotInfo old_info
old_info = idInfo id
old_unf = unfoldingInfo old_info
new_unf | isEvaldUnfolding old_unf = evaldUnfolding
| otherwise = noUnfolding
-- See Note [Preserve evaluatedness]
new_unf = zapUnfolding old_unf -- See Note [Preserve evaluatedness]
in
((tidy_env', var_env'), id')
}
......@@ -207,11 +205,10 @@ tidyLetBndr rec_tidy_env env@(tidy_env, var_env) (id,rhs)
`setInlinePragInfo` inlinePragInfo old_info
`setUnfoldingInfo` new_unf
old_unf = unfoldingInfo old_info
new_unf | isStableUnfolding old_unf = tidyUnfolding rec_tidy_env old_unf old_unf
| isEvaldUnfolding old_unf = evaldUnfolding
| otherwise = zapUnfolding old_unf
-- See Note [Preserve evaluatedness]
| otherwise = noUnfolding
old_unf = unfoldingInfo old_info
in
((tidy_env', var_env'), id') }
......
......@@ -437,8 +437,15 @@ toIfUnfolding lb (DFunUnfolding { df_bndrs = bndrs, df_args = args })
-- No need to serialise the data constructor;
-- we can recover it from the type of the dfun
toIfUnfolding _ _
= Nothing
toIfUnfolding _ (OtherCon {}) = Nothing
-- The binding site of an Id doesn't have OtherCon, except perhaps
-- where we have called zapUnfolding; and that evald'ness info is
-- not needed by importing modules
toIfUnfolding _ BootUnfolding = Nothing
-- Can't happen; we only have BootUnfolding for imported binders
toIfUnfolding _ NoUnfolding = Nothing
{-
************************************************************************
......
......@@ -221,18 +221,22 @@ globaliseAndTidyId id
Plan B: include pragmas, make interfaces
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Figure out which Ids are externally visible
* Step 1: Figure out which Ids are externally visible
See Note [Choosing external Ids]
* Tidy the bindings, externalising appropriate Ids
* Step 2: Gather the extenally visible rules, separately from
the top-level bindings.
See Note [Finding external rules]
* Step 3: Tidy the bindings, externalising appropriate Ids
See Note [Tidy the top-level bindings]
* Drop all Ids from the TypeEnv, and add all the External Ids from
the bindings. (This adds their IdInfo to the TypeEnv; and adds
floated-out Ids that weren't even in the TypeEnv before.)
Step 1: Figure out external Ids
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note [choosing external names]
Note [Choosing external Ids]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See also the section "Interface stability" in the
RecompilationAvoidance commentary:
http://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/RecompilationAvoidance
......@@ -272,8 +276,8 @@ as the bindings themselves are deterministic (they sometimes aren't!),
the order in which they are presented to the tidying phase does not
affect the names we assign.
Step 2: Tidy the program
~~~~~~~~~~~~~~~~~~~~~~~~
Note [Tidy the top-level bindings]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Next we traverse the bindings top to bottom. For each *top-level*
binder
......@@ -621,7 +625,7 @@ get_defn id = NonRec id (unfoldingTemplate (realIdUnfolding id))
* *
************************************************************************
See Note [Choosing external names].
See Note [Choosing external Ids].
-}
type UnfoldEnv = IdEnv (Name{-new name-}, Bool {-show unfolding-})
......@@ -780,7 +784,7 @@ a VarSet, which is in a non-deterministic order when converted to a
list. Hence, here we define a free-variable finder that returns
the free variables in the order that they are encountered.
See Note [Choosing external names]
See Note [Choosing external Ids]
-}
bndrFvsInOrder :: Bool -> Id -> [Id]
......@@ -1244,6 +1248,8 @@ tidyTopIdInfo dflags rhs_tidy_env name orig_rhs tidy_rhs idinfo show_unfold caf_
`setCafInfo` caf_info
`setArityInfo` arity
`setStrictnessInfo` final_sig
`setUnfoldingInfo` minimal_unfold_info -- See note [Preserve evaluatedness]
-- in CoreTidy
| otherwise -- Externally-visible Ids get the whole lot
= vanillaIdInfo
......@@ -1280,7 +1286,8 @@ tidyTopIdInfo dflags rhs_tidy_env name orig_rhs tidy_rhs idinfo show_unfold caf_
--------- Unfolding ------------
unf_info = unfoldingInfo idinfo
unfold_info | show_unfold = tidyUnfolding rhs_tidy_env unf_info unf_from_rhs
| otherwise = noUnfolding
| otherwise = minimal_unfold_info
minimal_unfold_info = zapUnfolding unf_info
unf_from_rhs = mkTopUnfolding dflags is_bot tidy_rhs
is_bot = isBottomingSig final_sig
-- NB: do *not* expose the worker if show_unfold is off,
......@@ -1297,6 +1304,7 @@ tidyTopIdInfo dflags rhs_tidy_env name orig_rhs tidy_rhs idinfo show_unfold caf_
-- for bottoming functions), but we might still have a worker/wrapper
-- split (see Note [Worker-wrapper for bottoming functions] in WorkWrap.hs
--------- Arity ------------
-- Usually the Id will have an accurate arity on it, because
-- the simplifier has just run, but not always.
......
......@@ -5,6 +5,9 @@ include $(TOP)/mk/test.mk
T2578:
'$(TEST_HC)' $(TEST_HC_OPTS) --make T2578 -fforce-recomp -v0
T14626:
'$(TEST_HC)' $(TEST_HC_OPTS) -c -O -ddump-prep -dsuppress-uniques T14626.hs | grep case
debug:
# Without optimisations, we should get annotations for basically
# all expressions in the example program.
......
{-# LANGUAGE MagicHash #-}
module T14626 where
import GHC.Prim
data T = MkT !Bool
f v = case v of
MkT y -> dataToTag# y
-- This should /not/ produce an inner case on the y, thus:
-- f v = case v of
-- MkT y -> case y of z -> dataToTag# z
-- But it was! See Trac #14626 comment:4
case dt of dt { __DEFAULT -> T14626.MkT dt }
case v of { T14626.MkT y [Occ=Once] ->
......@@ -30,8 +30,11 @@ test('debug',
run_command, ['$MAKE -s --no-print-directory debug'])
test('T9964', normal, compile, ['-O'])
test('T10518', [cmm_src], compile, [''])
test('T10667', [ when((arch('powerpc64') or arch('powerpc64le')),
test('T10667', [ when((arch('powerpc64') or arch('powerpc64le')),
expect_broken(11261))],
compile, ['-g'])
test('T12115', normal, compile, [''])
test('T12355', normal, compile, [''])
test('T14626',
normal,
run_command, ['$MAKE -s --no-print-directory T14626'])
......@@ -19,52 +19,52 @@ T2431.$WRefl
-- RHS size: {terms: 4, types: 8, coercions: 0, joins: 0/0}
absurd :: forall a. (Int :~: Bool) -> a
[GblId, Arity=1, Caf=NoCafRefs, Str=<L,U>x]
[GblId, Arity=1, Caf=NoCafRefs, Str=<L,U>x, Unf=OtherCon []]
absurd = \ (@ a) (x :: Int :~: Bool) -> case x of { }
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule1 :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule1 = "main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule2 :: GHC.Types.TrName
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule2 = GHC.Types.TrNameS $trModule1
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule3 :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule3 = "T2431"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule4 :: GHC.Types.TrName
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule4 = GHC.Types.TrNameS $trModule3
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
T2431.$trModule :: GHC.Types.Module
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
T2431.$trModule = GHC.Types.Module $trModule2 $trModule4
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$krep :: GHC.Types.KindRep
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$krep = GHC.Types.KindRepVar 0#
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$tc:~:1 :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$tc:~:1 = ":~:"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$tc:~:2 :: GHC.Types.TrName
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$tc:~:2 = GHC.Types.TrNameS $tc:~:1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
T2431.$tc:~: :: GHC.Types.TyCon
[GblId]
[GblId, Unf=OtherCon []]
T2431.$tc:~:
= GHC.Types.TyCon
4608886815921030019##
......@@ -76,34 +76,34 @@ T2431.$tc:~:
-- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0}
$krep1 :: [GHC.Types.KindRep]
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$krep1
= GHC.Types.:
@ GHC.Types.KindRep $krep (GHC.Types.[] @ GHC.Types.KindRep)
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
$krep2 :: [GHC.Types.KindRep]
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$krep2 = GHC.Types.: @ GHC.Types.KindRep $krep $krep1
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
$krep3 :: GHC.Types.KindRep
[GblId]
[GblId, Unf=OtherCon []]
$krep3 = GHC.Types.KindRepTyConApp T2431.$tc:~: $krep2
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$tc'Refl1 :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$tc'Refl1 = "'Refl"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$tc'Refl2 :: GHC.Types.TrName
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$tc'Refl2 = GHC.Types.TrNameS $tc'Refl1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
T2431.$tc'Refl :: GHC.Types.TyCon
[GblId]
[GblId, Unf=OtherCon []]
T2431.$tc'Refl
= GHC.Types.TyCon
2478588351447975921##
......
......@@ -5,12 +5,12 @@ Result size of Tidy Core
-- RHS size: {terms: 2, types: 2, coercions: 0, joins: 0/0}
convert1 :: Wrap Age -> Wrap Age
[GblId, Arity=1, Caf=NoCafRefs]
[GblId, Arity=1, Caf=NoCafRefs, Unf=OtherCon []]
convert1 = \ (ds :: Wrap Age) -> ds
-- RHS size: {terms: 1, types: 0, coercions: 5, joins: 0/0}
convert :: Wrap Age -> Int
[GblId, Arity=1, Caf=NoCafRefs]
[GblId, Arity=1, Caf=NoCafRefs, Unf=OtherCon []]
convert
= convert1
`cast` (<Wrap Age>_R ->_R Roles13.N:Wrap[0] (Roles13.N:Age[0])
......@@ -18,54 +18,54 @@ convert
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule1 :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule1 = "main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule2 :: GHC.Types.TrName
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule2 = GHC.Types.TrNameS $trModule1
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule3 :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule3 = "Roles13"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule4 :: GHC.Types.TrName
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule4 = GHC.Types.TrNameS $trModule3
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
Roles13.$trModule :: GHC.Types.Module
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
Roles13.$trModule = GHC.Types.Module $trModule2 $trModule4
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
$krep :: GHC.Types.KindRep
[GblId]
[GblId, Unf=OtherCon []]
$krep
= GHC.Types.KindRepTyConApp
GHC.Types.$tcInt (GHC.Types.[] @ GHC.Types.KindRep)
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$krep1 :: GHC.Types.KindRep
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$krep1 = GHC.Types.KindRepVar 0#
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$tcAge1 :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$tcAge1 = "Age"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$tcAge2 :: GHC.Types.TrName
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$tcAge2 = GHC.Types.TrNameS $tcAge1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
Roles13.$tcAge :: GHC.Types.TyCon
[GblId]
[GblId, Unf=OtherCon []]
Roles13.$tcAge
= GHC.Types.TyCon
3456257068627873222##
......@@ -77,29 +77,29 @@ Roles13.$tcAge
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
$krep2 :: GHC.Types.KindRep
[GblId]
[GblId, Unf=OtherCon []]
$krep2
= GHC.Types.KindRepTyConApp
Roles13.$tcAge (GHC.Types.[] @ GHC.Types.KindRep)
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
$krep3 :: GHC.Types.KindRep
[GblId]
[GblId, Unf=OtherCon []]
$krep3 = GHC.Types.KindRepFun $krep $krep2
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$tc'MkAge1 :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$tc'MkAge1 = "'MkAge"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$tc'MkAge2 :: GHC.Types.TrName
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$tc'MkAge2 = GHC.Types.TrNameS $tc'MkAge1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
Roles13.$tc'MkAge :: GHC.Types.TyCon
[GblId]
[GblId, Unf=OtherCon []]
Roles13.$tc'MkAge
= GHC.Types.TyCon
18264039750958872441##
......@@ -111,17 +111,17 @@ Roles13.$tc'MkAge
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$tcWrap1 :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$tcWrap1 = "Wrap"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$tcWrap2 :: GHC.Types.TrName
[GblId, Caf=NoCafRefs]
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$tcWrap2 = GHC.Types.TrNameS $tcWrap1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
Roles13.$tcWrap :: GHC.Types.TyCon
[GblId]
[GblId, Unf=OtherCon []]
Roles13.$tcWrap
= GHC.Types.TyCon