109 lines
3.0 KiB
Factor
109 lines
3.0 KiB
Factor
! Copyright (C) 2009, 2010 Slava Pestov.
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
USING: accessors arrays assocs combinators
|
|
combinators.short-circuit fry kernel locals namespaces
|
|
make math sequences hashtables
|
|
cpu.architecture
|
|
compiler.cfg
|
|
compiler.cfg.rpo
|
|
compiler.cfg.liveness
|
|
compiler.cfg.registers
|
|
compiler.cfg.utilities
|
|
compiler.cfg.instructions
|
|
compiler.cfg.predecessors
|
|
compiler.cfg.parallel-copy
|
|
compiler.cfg.ssa.destruction
|
|
compiler.cfg.linear-scan.assignment
|
|
compiler.cfg.linear-scan.allocation.state ;
|
|
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>> ] bi@ = ] [ [ reg-class>> ] bi@ = ] } 2&&
|
|
] [ 2drop f ] if ;
|
|
|
|
M: location hashcode*
|
|
reg>> hashcode* ;
|
|
|
|
SYMBOL: spill-temps
|
|
|
|
: spill-temp ( rep -- n )
|
|
rep-size spill-temps get [ next-spill-slot ] cache ;
|
|
|
|
: 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 ;
|
|
|
|
: temp->register ( from to -- )
|
|
nip [ reg>> ] [ rep>> ] [ rep>> spill-temp ] tri ##reload ;
|
|
|
|
: register->temp ( from to -- )
|
|
drop [ [ reg>> ] [ rep>> ] bi ] [ rep>> spill-temp ] bi ##spill ;
|
|
|
|
: register->register ( from to -- )
|
|
swap [ reg>> ] [ [ reg>> ] [ rep>> ] bi ] bi* ##copy ;
|
|
|
|
SYMBOL: temp
|
|
|
|
: >insn ( from to -- )
|
|
{
|
|
{ [ over temp eq? ] [ temp->register ] }
|
|
{ [ dup temp eq? ] [ register->temp ] }
|
|
{ [ 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 [ swap >insn ] parallel-mapping ##branch ] { } make ;
|
|
|
|
: perform-mappings ( bb to mappings -- )
|
|
dup empty? [ 3drop ] [
|
|
mapping-instructions insert-basic-block
|
|
cfg get cfg-changed drop
|
|
] if ;
|
|
|
|
: resolve-edge-data-flow ( bb to -- )
|
|
2dup compute-mappings perform-mappings ;
|
|
|
|
: resolve-block-data-flow ( bb -- )
|
|
dup successors>> [ resolve-edge-data-flow ] with each ;
|
|
|
|
: resolve-data-flow ( cfg -- )
|
|
needs-predecessors
|
|
|
|
H{ } clone spill-temps set
|
|
[ resolve-block-data-flow ] each-basic-block ;
|