Newtypes in STG

Simon Peyton Jones simonpj at microsoft.com
Mon Apr 1 08:22:38 UTC 2019


I printed out the full [StgTopBinding] list and got:

let {

  sat_s27NC [Occ=Once] :: IO Timeout

  [LclId] =

      [] \u [] fmap $fFunctorIO Timeout newUnique;

} in  >>= $fMonadIO sat_s27NC sat_s27NT;

That does look odd.  Can you explain how to reproduce this with HEAD?  That is, are we getting a newtype constructor in the argument position of an StgApp in HEAD too?

Newtype “data constructors” are always inlined, which is why I don’t understand what’s happening.

Simon


From: ghc-devs <ghc-devs-bounces at haskell.org> On Behalf Of Christopher Done
Sent: 30 March 2019 14:05
To: GHC developers <ghc-devs at haskell.org>
Subject: Newtypes in STG


Hi all,

Could you offer some insight into newtypes at the STG level? Here’s the
context:

1.       I’m working on this interpreter for STG
(https://github.com/chrisdone/prana<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fchrisdone%2Fprana&data=02%7C01%7Csimonpj%40microsoft.com%7C4e3af9edea7943b28d5108d6b518bb03%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636895515163475987&sdata=pKqvy%2BbHqITOzm%2FTOSNHdj0w9UT9mtrghK0w9RXQers%3D&reserved=0>) and I’m trying to generate a
pristine AST where all names in it are resolved to something known to
me.

2.       I’ve compiled ghc-prim and integer-gmp without issue, and I’m
compiling base and there remains one last frontier which is newtypes.

These are the culprits pointed out if I compile base:

chris at precision:~/Work/chrisdone/prana/ghc-8.4/libraries/base-4.11.1.0$<mailto:chris at precision:~/Work/chrisdone/prana/ghc-8.4/libraries/base-4.11.1.0$> PRANA_INDEX=../prana.idx stack build --exec './Setup build --ghc-options=-O0' --file-watch

Preprocessing library for base-4.11.1.0..

Building library for base-4.11.1.0..

[1 of 244] Compiling GHC.Base

[2 of 244] Compiling GHC.IO<https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2FGHC.IO&data=02%7C01%7Csimonpj%40microsoft.com%7C4e3af9edea7943b28d5108d6b518bb03%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636895515163485976&sdata=fk29d0sG6L9JTVEVws1efAf%2BwOjKeY9zjhCHZPMZY4M%3D&reserved=0>

[3 of 244] Compiling GHC.Real

[4 of 244] Compiling Data.Semigroup.Internal

... [snip] ...

[242 of 244] Compiling Data.Functor.Compose

[243 of 244] Compiling Data.Fixed

[244 of 244] Compiling Data.Complex



Errors in Data.Foldable:

  Variable name not found: base:Data.Semigroup.Internal.All

  Variable name not found: base:Data.Semigroup.Internal.Any



Errors in Foreign.Marshal.Pool:

  Variable name not found: base:Foreign.Marshal.Pool.Pool



Errors in GHC.ExecutionStack.Internal:

  Variable name not found: base:GHC.ExecutionStack.Internal.StackTrace



Errors in Data.Bifoldable:

  Variable name not found: base:Data.Semigroup.Internal.All

  Variable name not found: base:Data.Semigroup.Internal.Any



Errors in System.Timeout:

  Variable name not found: base:System.Timeout.Timeout



Errors in Data.Data:

  Variable name not found: base:Foreign.Ptr.WordPtr

  Variable name not found: base:Foreign.Ptr.IntPtr

  Variable name not found: base:Data.Semigroup.Internal.Any

  Variable name not found: base:Data.Semigroup.Internal.All

I looked these up, and they all appear to be uses of a
newtype.

For example, in the Timeout function:

http://hackage.haskell.org/package/base-4.12.0.0/docs/src/System.Timeout.html#timeout<https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fhackage.haskell.org%2Fpackage%2Fbase-4.12.0.0%2Fdocs%2Fsrc%2FSystem.Timeout.html%23timeout&data=02%7C01%7Csimonpj%40microsoft.com%7C4e3af9edea7943b28d5108d6b518bb03%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636895515163485976&sdata=u4tND6ZJNg7qEd8Kl4fNHvfs7JCOXQ9Sq0%2Ff82flDhw%3D&reserved=0>

I printed out the full [StgTopBinding] list and got:

let {

  sat_s27NC [Occ=Once] :: IO Timeout

  [LclId] =

      [] \u [] fmap $fFunctorIO Timeout newUnique;

} in  >>= $fMonadIO sat_s27NC sat_s27NT;

Oddly (or not?), they’re used as values, not constructors. This error
comes from this part of my code:

StgSyn.StgApp occ arguments ->

  AppExpr <$> lookupSomeVarId occ <*> traverse fromStgGenArg arguments

If it was used as a constructor, it’d appear in this position, where
looking up the ID would produce a “Data constructor name not found”
error:

StgSyn.StgConApp dataCon arguments types ->
ConAppExpr <$> lookupDataConId dataCon <> traverse fromStgGenArg arguments <>
pure (map (const Type) types)

My understanding of newtypes at this stage is hazy. It seems like:

·       They ought to be erased and replaced with coercions by now. If
they’re not replaced, it’s because they’re in a not-quite-id position
like fmap Timeout .... (Arguably these could be fixed in base with a
Data.Coerce.coerce?)

·       However, the CoreTidy/PrepPgm processing modules
don’t seem to have removed or replaced these, or introduced a binding
that would do something.

At this stage what would you recommend? At this point type-checking is
done, and I only care about interpreting the code. So I suppose they
could be id for all it matters to the interpreter?

I imagine they aren’t actually supposed to allocate something here. And
I’m certain that any pattern matching on a newtype is also erased away
by this point.

Cheers!

Chris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20190401/e6e9ef01/attachment.html>


More information about the ghc-devs mailing list