[GHC] #15627: Absent unlifted bindings

GHC ghc-devs at haskell.org
Tue Sep 11 15:13:34 UTC 2018


#15627: Absent unlifted bindings
-------------------------------------+-------------------------------------
        Reporter:  sgraf             |                Owner:  (none)
            Type:  task              |               Status:  new
        Priority:  normal            |            Milestone:  ⊥
       Component:  Compiler          |              Version:  8.4.3
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #9279 #4328       |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------
Description changed by simonpj:

Old description:

> As simonpj put it in ticket:9279#comment:20:
>
> > For a long time, the worker/wrapper splitter has given up on absent
> > arguments of certain unlifted types: see `Literal.absentLiteralOf` and
> > `Note [Absent errors]` in `WwLib`.  This is very annoying because it
> means
> > that we get left with functions that take a bunch of arguments they do
> not
> > use, as in this ticket (#9279).
> >
> > For lifted types T we build an absent value as a thunk of form
> > {{{
> >   aBSENT_ERROR_ID @T "Used absent value"
> > }}}
> > This does two things
> > A.  It gives us something, of the right type, to use in place of the
> value
> >     we aren't passing any more.
> > B.  It gives an extra sanity check: if that value is ever used (a
> compiler
> >     bug) we'll get a runtime error message.
> >
> > For unlifted types we don't have thunks, so we can't do this.  As you
> can
> > see in `absentLiteralOf`, for some types we just make up a silly value:
> > e.g. for `Char#` we use `'x#'`; for `Int#` we use `0#`.
> >
> > Note, however that
> >
> > * Substituting a particular value serves purpose (A) but not purpose
> >   (B).  A compiler bug would go undetected.  This is sad: e.g. #11126
> >   is a real bug that was detected by (B).  But I see no way out.
> >
> > * It doesn't work for `Array#`, `MutVar#`, `TVar#` etc because we have
> >   no available literal values of those types.
> >
> > So Sebastian is suggesting that we add a new literal value -- call it
> > a '''rubbish value''' -- which can work for any (unlifted type),
> > extending `Literal` something like this
> > {{{
> > data Literal = ...
> >   | RubbishLit Type
> > }}}
> > We need to store the type so we can still do `literalType`.
> >
> > Now
> > * Maybe we could get rid of `MachNullAddr` in favour of this new
> literal.
> >
> > * I think -- but I am not sure -- that this literal should never occur
> >   in code generation. For example, we should never pass a rubbish value
> >   to a function. Before then dead-code elimination should have got rid
> >   of it  I'm not 100% certain, but if this was true, it'd be a great
> >   sanity check.
> >
> > * Yes, `Literal` has `Eq` and `Ord` -- but I'm not sure why.  Try
> removing
> >   them and seeing what happens!  (Generally I think it'd be better to
> >   define `eqLit` and `cmpLit` and cal them, rather than use `==` and
> `>`;
> >   so much easier to grep for!
> >
> >   And in fact, we do have `eqType` and `cmpType`.
> >
> > * Do we need to spit out a `RubbishLit` in the `Binary` instance.
> >   This seems more likely, because perhaps these rubbish values can
> occur
> >   in unfoldings, which are serialised as their parse tree.  But
> >   the we can just serialise the `Type`.  It won't happen much.

New description:

 Transferred from ticket:9279#comment:20:

 For a long time, the worker/wrapper splitter has given up on absent
 arguments of certain unlifted types: see `Literal.absentLiteralOf` and
 `Note [Absent errors]` in `WwLib`.  This is very annoying because it means
 that we get left with functions that take a bunch of arguments they do not
 use, as in this ticket (#9279).

 For lifted types T we build an absent value as a thunk of form
 {{{
   aBSENT_ERROR_ID @T "Used absent value"
 }}}
 This does two things
 A.  It gives us something, of the right type, to use in place of the value
     we aren't passing any more.
 B.  It gives an extra sanity check: if that value is ever used (a compiler
     bug) we'll get a runtime error message.

 For unlifted types we don't have thunks, so we can't do this.  As you can
 see in `absentLiteralOf`, for some types we just make up a silly value:
 e.g. for `Char#` we use `'x#'`; for `Int#` we use `0#`.

 Note, however that

 * Substituting a particular value serves purpose (A) but not purpose
   (B).  A compiler bug would go undetected.  This is sad: e.g. #11126
   is a real bug that was detected by (B).  But I see no way out.

 * It doesn't work for `Array#`, `MutVar#`, `TVar#` etc because we have
   no available literal values of those types.

 So Sebastian is suggesting that we add a new literal value -- call it
 a '''rubbish value''' -- which can work for any (unlifted type),
 extending `Literal` something like this
 {{{
 data Literal = ...
   | RubbishLit Type
 }}}
 We need to store the type so we can still do `literalType`.

 Now
 * Maybe we could get rid of `MachNullAddr` in favour of this new literal.

 * I think -- but I am not sure -- that this literal should never occur
   in code generation. For example, we should never pass a rubbish value
   to a function. Before then dead-code elimination should have got rid
   of it  I'm not 100% certain, but if this was true, it'd be a great
   sanity check.

 * Yes, `Literal` has `Eq` and `Ord` -- but I'm not sure why.  Try removing
   them and seeing what happens!  (Generally I think it'd be better to
   define `eqLit` and `cmpLit` and cal them, rather than use `==` and `>`;
   so much easier to grep for!

   And in fact, we do have `eqType` and `cmpType`.

 * Do we need to spit out a `RubbishLit` in the `Binary` instance.
   This seems more likely, because perhaps these rubbish values can occur
   in unfoldings, which are serialised as their parse tree.  But
   the we can just serialise the `Type`.  It won't happen much.

--

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15627#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list