 : count-vregs ( reg-classes -- ) [ [ inc ] when* ] each ;
 
 : count-input-vregs ( phantom spec -- )
-    phantom&spec [ transfer-op allocation ] 2map
-    count-vregs ;
+    phantom&spec [ allocation ] 2map count-vregs ;
 
 : count-scratch-regs ( spec -- )
     [ first reg-spec>class ] map count-vregs ;


: finalize-locs ( -- )
    #! Perform any deferred stack shuffling.
    live-locs dup fast-shuffle?
    [ fast-shuffle ] [ slow-shuffle ] if ;

: finalize-values ( -- )
    #! Store any deferred literals to their final stack
    #! locations.
    [ dup value? [ (lazy-store) ] [ 2drop ] if ] each-loc ;

UNION: pseudo loc value ;

: finalize-vregs ( -- )
    #! Store any vregs to their final stack locations.
    [ dup pseudo? [ 2drop ] [ (lazy-store) ] if ] each-loc ;

: reusing-vregs ( quot -- )
    #! Any vregs allocated by quot are released again.
    >r \ free-vregs get [ clone ] assoc-map \ free-vregs r>
    with-variable ; inline

: finalize-contents ( -- )
    [ finalize-locs ] reusing-vregs
    [ finalize-values ] reusing-vregs
    finalize-vregs
    [ delete-all ] each-phantom ;

: %gc ( -- )
    0 frame-required

<PRIVATE

UNION: loc ds-loc rs-loc ;

! Moving values between locations and registers
GENERIC: move-spec ( obj -- spec )

M: int-regs move-spec drop f ;
M: float-regs move-spec drop float ;
M: value move-spec class ;
M: loc move-spec drop loc ;
M: f move-spec drop loc ;

: %move ( dst src -- )
    2dup [ move-spec ] 2apply swap 2array {
        { { f f } [ "Bug in generator.registers %move" throw ] }
        { { f float } [ %unbox-float ] }
        { { f loc } [ swap %replace ] }
        { { float f } [ %box-float ] }
        { { value f } [ value-literal swap load-literal ] }
        { { loc f } [ %peek ] }
        [ drop temp-reg swap %move temp-reg %move ]
    } case ;

! A compile-time stack
TUPLE: phantom-stack height ;
