105 lines
3.0 KiB
Factor
105 lines
3.0 KiB
Factor
! Copyright (C) 2009, 2011 Slava Pestov.
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
USING: accessors arrays assocs combinators
|
|
combinators.short-circuit compiler.cfg compiler.cfg.instructions
|
|
compiler.cfg.linear-scan.allocation.state
|
|
compiler.cfg.linear-scan.assignment compiler.cfg.parallel-copy
|
|
compiler.cfg.predecessors compiler.cfg.registers
|
|
compiler.cfg.rpo compiler.cfg.utilities cpu.architecture fry
|
|
kernel locals make namespaces sequences ;
|
|
IN: compiler.cfg.linear-scan.resolve
|
|
|
|
TUPLE: location
|
|
{ reg read-only }
|
|
{ rep read-only }
|
|
{ reg-class read-only } ;
|
|
|
|
: <location> ( reg rep -- location )
|
|
dup reg-class-of location boa ;
|
|
|
|
M: location equal?
|
|
over location? [
|
|
{ [ [ reg>> ] same? ] [ [ reg-class>> ] same? ] } 2&&
|
|
] [ 2drop f ] if ;
|
|
|
|
M: location hashcode*
|
|
reg>> hashcode* ;
|
|
|
|
SYMBOL: temp-spills
|
|
|
|
: temp-spill ( rep -- spill-slot )
|
|
rep-size temp-spills get
|
|
[ cfg get next-spill-slot ] cache ;
|
|
|
|
SYMBOL: temp-locations
|
|
|
|
: temp-location ( loc -- temp )
|
|
rep>> temp-locations get
|
|
[ [ temp-spill ] keep <location> ] cache ;
|
|
|
|
: init-resolve ( -- )
|
|
H{ } clone temp-spills set
|
|
H{ } clone temp-locations set ;
|
|
|
|
: add-mapping ( from to rep -- )
|
|
'[ _ <location> ] bi@ 2array , ;
|
|
|
|
:: resolve-value-data-flow ( vreg live-out live-in edge-live-in -- )
|
|
vreg live-out ?at [ bad-vreg ] unless
|
|
vreg live-in ?at [ edge-live-in ?at [ bad-vreg ] unless ] unless
|
|
2dup = [ 2drop ] [ vreg rep-of add-mapping ] if ;
|
|
|
|
:: compute-mappings ( bb to -- mappings )
|
|
bb machine-live-out :> live-out
|
|
to machine-live-in :> live-in
|
|
bb to machine-edge-live-in :> edge-live-in
|
|
live-out assoc-empty? [ f ] [
|
|
[
|
|
live-in keys edge-live-in keys append [
|
|
live-out live-in edge-live-in
|
|
resolve-value-data-flow
|
|
] each
|
|
] { } make
|
|
] if ;
|
|
|
|
: memory->register ( from to -- )
|
|
swap [ reg>> ] [ [ rep>> ] [ reg>> ] bi ] bi* ##reload, ;
|
|
|
|
: register->memory ( from to -- )
|
|
[ [ reg>> ] [ rep>> ] bi ] [ reg>> ] bi* ##spill, ;
|
|
|
|
: register->register ( from to -- )
|
|
swap [ reg>> ] [ [ reg>> ] [ rep>> ] bi ] bi* ##copy, ;
|
|
|
|
: >insn ( from to -- )
|
|
{
|
|
{ [ over reg>> spill-slot? ] [ memory->register ] }
|
|
{ [ dup reg>> spill-slot? ] [ register->memory ] }
|
|
[ register->register ]
|
|
} cond ;
|
|
|
|
: mapping-instructions ( alist -- insns )
|
|
[ swap ] H{ } assoc-map-as [
|
|
[ temp-location ] [ swap >insn ] parallel-mapping
|
|
##branch,
|
|
] { } make ;
|
|
|
|
: perform-mappings ( bb to mappings -- )
|
|
[ 2drop ] [
|
|
mapping-instructions insert-basic-block
|
|
cfg get cfg-changed
|
|
] if-empty ;
|
|
|
|
: resolve-edge-data-flow ( bb to -- )
|
|
2dup compute-mappings perform-mappings ;
|
|
|
|
: resolve-block-data-flow ( bb -- )
|
|
dup kill-block?>> [ drop ] [
|
|
dup successors>> [ resolve-edge-data-flow ] with each
|
|
] if ;
|
|
|
|
: resolve-data-flow ( cfg -- )
|
|
init-resolve
|
|
[ needs-predecessors ]
|
|
[ [ resolve-block-data-flow ] each-basic-block ] bi ;
|