factor/basis/compiler/cfg/gc-checks/gc-checks.factor

96 lines
2.4 KiB
Factor
Raw Normal View History

2010-04-27 10:51:00 -04:00
! Copyright (C) 2009, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
2010-04-27 10:51:00 -04:00
USING: accessors assocs combinators fry kernel layouts locals
math make namespaces sequences cpu.architecture
compiler.cfg
compiler.cfg.rpo
2010-04-27 10:51:00 -04:00
compiler.cfg.hats
compiler.cfg.registers
2010-04-27 10:51:00 -04:00
compiler.cfg.utilities
compiler.cfg.comparisons
compiler.cfg.instructions
compiler.cfg.predecessors ;
IN: compiler.cfg.gc-checks
2010-04-27 10:51:00 -04:00
<PRIVATE
! Garbage collection check insertion. This pass runs after
! representation selection, since it needs to know which vregs
! can contain tagged pointers.
: insert-gc-check? ( bb -- ? )
2010-05-14 18:18:29 -04:00
dup kill-block?>>
[ drop f ] [ instructions>> [ ##allocation? ] any? ] if ;
: blocks-with-gc ( cfg -- bbs )
post-order [ insert-gc-check? ] filter ;
2010-04-27 10:51:00 -04:00
! A GC check for bb consists of two new basic blocks, gc-check
! and gc-call:
!
! gc-check
! / \
! | gc-call
! \ /
! bb
! Any ##phi instructions at the start of bb are transplanted
! into the gc-check block.
: <gc-check> ( phis size -- bb )
[ <basic-block> ] 2dip
2010-04-27 10:51:00 -04:00
[
[ % ]
[
cc<= int-rep next-vreg-rep int-rep next-vreg-rep
##check-nursery-branch
] bi*
2010-04-27 10:51:00 -04:00
] V{ } make >>instructions ;
: <gc-call> ( -- bb )
<basic-block>
[ <gc-map> ##call-gc ##branch ] V{ } make
2010-04-27 10:51:00 -04:00
>>instructions t >>unlikely? ;
:: insert-guard ( body check bb -- )
bb predecessors>> check predecessors<<
V{ bb body } check successors<<
2010-04-27 10:51:00 -04:00
V{ check } body predecessors<<
V{ bb } body successors<<
2010-04-27 10:51:00 -04:00
V{ check body } bb predecessors<<
2010-04-27 10:51:00 -04:00
check predecessors>> [ bb check update-successors ] each ;
: (insert-gc-check) ( phis size bb -- )
[ [ <gc-call> ] 2dip <gc-check> ] dip insert-guard ;
2010-04-27 10:51:00 -04:00
GENERIC: allocation-size* ( insn -- n )
M: ##allot allocation-size* size>> ;
M: ##box-alien allocation-size* drop 5 cells ;
M: ##box-displaced-alien allocation-size* drop 5 cells ;
: allocation-size ( bb -- n )
instructions>>
[ ##allocation? ] filter
2009-11-02 18:41:36 -05:00
[ allocation-size* data-alignment get align ] map-sum ;
: remove-phis ( bb -- phis )
[ [ ##phi? ] partition ] change-instructions drop ;
2010-04-27 10:51:00 -04:00
: insert-gc-check ( bb -- )
[ remove-phis ] [ allocation-size ] [ ] tri (insert-gc-check) ;
2010-04-27 10:51:00 -04:00
PRIVATE>
: insert-gc-checks ( cfg -- cfg' )
dup blocks-with-gc [
[ needs-predecessors ] dip
[ insert-gc-check ] each
2010-04-27 10:51:00 -04:00
cfg-changed
2009-10-29 15:34:04 -04:00
] unless-empty ;