Supporting unboxed tuples in the bytecode compiler

Simon Marlow marlowsd at
Mon Jul 25 13:07:09 UTC 2016

If I remember correctly, it's returning and case alternatives that are the
problem (unarise is relatively new, for a long time you could only use
unboxed tuples in returns and case alternatives).  Take your case
expression example:

case e1 of
          (# bndr1, bndr2, ..., bndrN #) -> RHS

Now suppose that e1 is a call to a compiled function, and the RHS is byte
code.  Normally when this happens we push a stack frame that will capture
the values returned by the compiled code, save them on the stack, and pass
control to the interpreter.  These are the stg_ctoi_XXX frames in

The problem with unboxed tuples is that we would need an infinite number of
these to handle all the possible return conventions for unboxed tuples.

Since we can't use pre-compiled stack frames, we would need to use a scheme
that involves some separate description of the stack, using a bitmap of
some kind.  I think this should be possible, but there isn't an existing
stack frame that does the right thing - the closest is RET_BCO, but then
you'd have to make another BCO just for the purpose of containing the
bitmap to describe the stack layout.  And you somehow have to extract the
values that are being returned in registers and save them on the stack too.

The other half of the problem is returning an arbitrary unboxed tuple to
compiled code, where we would have to arrange that the correct values get
put in the correct registers according to the return convention, and here
we would need some kind of descriptor and an interpretive loop in Cmm to do
the loading of values from the stack into registers.

So I think it's possible, but there are quite a lot of fiddly details.


On 25 July 2016 at 11:14, Ömer Sinan Ağacan <omeragacan at> wrote:

> Simon,
> I was looking at the bytecode compiler to understand what's needed to
> support
> unboxed tuples. It seems like if we generate bytecode after unarise it
> should be
> very easy to support unboxed tuples, because after unarise we don't have
> any
> unboxed tuple binders (all binders have UnaryType). So only places we see
> unboxed tuples are:
>     - Return positions. We just push contents of the tuple to the stack.
>     - Case alternatives. The case expression in this case has to have this
> form:
>         case e1 of
>           (# bndr1, bndr2, ..., bndrN #) -> RHS
>       All binders will have unary types again. We just bind ids in the
>       environment to their stack locations and compile RHS.
> I think that's it. We also get unboxed sums support for free when we do
> this
> after unarise.
> What do you think about compiling to bytecode from STG? Have you
> considered that
> before? Would that be a problem for GHCi's debugger or any other features?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the ghc-devs mailing list