##branch, [ begin-basic-block ] dip
[ label>> id>> loops get set-at ] [ child>> emit-nodes ] 2bi ;
-M: #recursive emit-node ( block node -- block' )
+M: #recursive emit-node
dup label>> loop?>> [ emit-loop ] [ emit-recursive ] if ;
! #if
! loc>vreg sync
ds-pop any-rep ^^copy f cc/= ##compare-imm-branch, emit-if ;
-M: #if emit-node ( block node -- block' )
+M: #if emit-node
{
{ [ dup trivial-if? ] [ drop emit-trivial-if ] }
{ [ dup trivial-not-if? ] [ drop emit-trivial-not-if ] }
[ emit-actual-if ]
} cond ;
-M: #dispatch emit-node ( block node -- block' )
+M: #dispatch emit-node
! Inputs to the final instruction need to be copied because of
! loc>vreg sync. ^^offset>slot always returns a fresh vreg,
! though.
ds-pop ^^offset>slot next-vreg ##dispatch, emit-if ;
-M: #call emit-node ( block node -- block' )
+M: #call emit-node
dup word>> dup "intrinsic" word-prop [
nip call( block #call -- block' )
] [ swap call-height emit-call ] if* ;
-M: #call-recursive emit-node ( block node -- block' )
+M: #call-recursive emit-node
[ label>> id>> ] [ call-height ] bi emit-call ;
-M: #push emit-node ( block node -- block )
+M: #push emit-node
literal>> ^^load-literal ds-push ;
! #shuffle
[ make-input-map ] [ mapping>> ] [ extract-outputs ] tri
[ [ of of peek-loc ] 2with map ] 2with map ;
-M: #shuffle emit-node ( block node -- block )
+M: #shuffle emit-node
[ out-vregs/stack ] keep store-height-changes
first2 [ ds-loc store-vregs ] [ rs-loc store-vregs ] bi* ;
t >>kill-block?
##safepoint, ##epilogue, ##return, ;
-M: #return emit-node ( block node -- block' )
+M: #return emit-node
drop end-word ;
-M: #return-recursive emit-node ( block node -- block' )
+M: #return-recursive emit-node
label>> id>> loops get key? [ ] [ end-word ] if ;
! #terminate
-M: #terminate emit-node ( block node -- block' )
+M: #terminate emit-node
drop ##no-tco, end-basic-block f ;
! No-op nodes