Note [Return convention for non-tuple values]
The RETURN and ENTER instructions are used to return values. RETURN directly
returns the value at the top of the stack while ENTER evaluates it first (so
RETURN is only used when the result is already known to be evaluated), but the
end result is the same: control returns to the enclosing stack frame with the
result at the top of the stack.
The PUSH_ALTS instruction pushes a two-word stack frame that receives a single
lifted value. Its payload is a BCO that is executed when control returns, with
the stack set up as if a RETURN instruction had just been executed: the returned
value is at the top of the stack, and beneath it is the two-word frame being
returned to. It is the continuation BCO’s job to pop its own frame off the
stack, so the simplest possible continuation consists of two instructions:
SLIDE 1 2 -- pop the return frame off the stack, keeping the returned value
RETURN P -- return the returned value to our caller
RETURN and PUSH_ALTS are not really instructions but are in fact representation-
polymorphic *families* of instructions indexed by ArgRep. ENTER, however, is a
single real instruction, since it is only used to return lifted values, which
are always pointers.
The RETURN, ENTER, and PUSH_ALTS instructions are only used when the returned
value has nullary or unary representation. Returning/receiving an unboxed
tuple (or, indirectly, an unboxed sum, since unboxed sums have been desugared to
unboxed tuples by Unarise) containing two or more results uses the special
RETURN_TUPLE/PUSH_ALTS_TUPLE instructions, which use a different return
convention. See Note [unboxed tuple bytecodes and tuple_BCO] for details. References 1
- unboxed tuple bytecodes and tuple_BCO GHC.StgToByteCode
Referenced by 2
- GHC.ByteCode.Instr call site
- GHC.StgToByteCode call site