More progress

db4
Slava Pestov 2008-09-15 04:22:12 -05:00
parent f7cb6e3051
commit 389b04ad42
12 changed files with 64 additions and 70 deletions

View File

@ -7,5 +7,5 @@ IN: compiler.backend.x86.32
M: x86.32 machine-registers M: x86.32 machine-registers
{ {
{ int-regs { EAX ECX EDX EBP EBX } } { int-regs { EAX ECX EDX EBP EBX } }
{ float-regs { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } } { double-float-regs { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } }
} ; } ;

View File

@ -7,7 +7,7 @@ IN: compiler.backend.x86.64
M: x86.64 machine-registers M: x86.64 machine-registers
{ {
{ int-regs { RAX RCX RDX RBP RSI RDI R8 R9 R10 R11 R12 R13 } } { int-regs { RAX RCX RDX RBP RSI RDI R8 R9 R10 R11 R12 R13 } }
{ float-regs { { double-float-regs {
XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7
XMM8 XMM9 XMM10 XMM11 XMM12 XMM13 XMM14 XMM15 XMM8 XMM9 XMM10 XMM11 XMM12 XMM13 XMM14 XMM15
} } } }

View File

@ -1,14 +1,14 @@
! Copyright (C) 2008 Slava Pestov. ! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: assocs accessors arrays kernel sequences namespaces USING: assocs accessors arrays kernel sequences namespaces
math compiler.cfg.instructions.syntax ; math compiler.cfg.registers compiler.cfg.instructions.syntax ;
IN: compiler.cfg.instructions IN: compiler.cfg.instructions
! Virtual CPU instructions, used by CFG and machine IRs ! Virtual CPU instructions, used by CFG and machine IRs
INSN: %cond-branch src ; TUPLE: %cond-branch < insn src ;
INSN: %unary dst src ; TUPLE: %unary < insn dst src ;
INSN: %nullary dst ; TUPLE: %nullary < insn dst ;
! Stack operations ! Stack operations
INSN: %load-literal < %nullary obj ; INSN: %load-literal < %nullary obj ;
@ -50,12 +50,12 @@ INSN: %alien-callback params ;
GENERIC: defs-vregs ( insn -- seq ) GENERIC: defs-vregs ( insn -- seq )
GENERIC: uses-vregs ( insn -- seq ) GENERIC: uses-vregs ( insn -- seq )
M: %nullary defs-vregs dst>> 1array ; M: %nullary defs-vregs dst>> >vreg 1array ;
M: %unary defs-vregs dst>> 1array ; M: %unary defs-vregs dst>> >vreg 1array ;
M: insn defs-vregs drop f ; M: insn defs-vregs drop f ;
M: %replace uses-vregs src>> 1array ; M: %replace uses-vregs src>> >vreg 1array ;
M: %unary uses-vregs src>> 1array ; M: %unary uses-vregs src>> >vreg 1array ;
M: insn uses-vregs drop f ; M: insn uses-vregs drop f ;
! M: %intrinsic uses-vregs vregs>> values ; ! M: %intrinsic uses-vregs vregs>> values ;
@ -75,7 +75,7 @@ M: %cond-branch uses-vregs src>> 1array ;
! M: %if-intrinsic uses-vregs vregs>> values ; ! M: %if-intrinsic uses-vregs vregs>> values ;
M: %boolean-intrinsic defs-vregs out>> 1array ; M: %boolean-intrinsic defs-vregs dst>> 1array ;
! M: %boolean-intrinsic uses-vregs ! M: %boolean-intrinsic uses-vregs
! [ vregs>> values ] [ out>> ] bi suffix ; ! [ vregs>> values ] [ out>> ] bi suffix ;
@ -94,14 +94,14 @@ INSN: _label label ;
: resolve-label ( label/name -- ) : resolve-label ( label/name -- )
dup label? [ get ] unless _label ; dup label? [ get ] unless _label ;
TUPLE: _cond-branch src label ; TUPLE: _cond-branch < insn src label ;
INSN: _branch label ; INSN: _branch label ;
INSN: _branch-f < _cond-branch ; INSN: _branch-f < _cond-branch ;
INSN: _branch-t < _cond-branch ; INSN: _branch-t < _cond-branch ;
INSN: _if-intrinsic label quot vregs ; INSN: _if-intrinsic label quot vregs ;
M: _cond-branch uses-vregs src>> 1array ; M: _cond-branch uses-vregs src>> >vreg 1array ;
! M: _if-intrinsic uses-vregs vregs>> values ; ! M: _if-intrinsic uses-vregs vregs>> values ;
INSN: _spill src n ; INSN: _spill src n ;

View File

@ -1,15 +1,15 @@
! Copyright (C) 2008 Slava Pestov. ! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: classes.tuple classes.tuple.parser kernel words USING: classes.tuple classes.tuple.parser kernel words
make parser ; make fry sequences parser ;
IN: compiler.cfg.instructions.syntax IN: compiler.cfg.instructions.syntax
TUPLE: insn ; TUPLE: insn ;
: INSN: : INSN:
parse-tuple-definition parse-tuple-definition "regs" suffix
[ dup tuple eq? [ drop insn ] when ] dip [ dup tuple eq? [ drop insn ] when ] dip
[ define-tuple-class ] [ define-tuple-class ]
[ 2drop save-location ] [ 2drop save-location ]
[ 2drop dup [ boa , ] curry define-inline ] [ 2drop dup '[ f _ boa , ] define-inline ]
3tri ; parsing 3tri ; parsing

View File

@ -140,7 +140,7 @@ SYMBOL: spill-counter
: init-allocator ( registers -- ) : init-allocator ( registers -- )
V{ } clone active-intervals set V{ } clone active-intervals set
<min-heap> unhandled-intervals set <min-heap> unhandled-intervals set
[ >vector ] assoc-map free-registers set [ reverse >vector ] assoc-map free-registers set
0 spill-counter set 0 spill-counter set
-1 progress set ; -1 progress set ;
@ -150,10 +150,10 @@ SYMBOL: spill-counter
: (allocate-registers) ( -- ) : (allocate-registers) ( -- )
unhandled-intervals get [ handle-interval ] slurp-heap ; unhandled-intervals get [ handle-interval ] slurp-heap ;
: allocate-registers ( live-intervals machine-registers -- ) : allocate-registers ( live-intervals machine-registers -- live-intervals )
#! This modifies the input live-intervals. #! This modifies the input live-intervals.
[ [
init-allocator init-allocator
init-unhandled dup init-unhandled
(allocate-registers) (allocate-registers)
] with-scope ; ] with-scope ;

View File

@ -0,0 +1,4 @@
USING: compiler.cfg.linear-scan.assignment tools.test ;
IN: compiler.cfg.linear-scan.assignment.tests
\ assign-registers must-infer

View File

@ -5,7 +5,7 @@ fry make
compiler.cfg.registers compiler.cfg.registers
compiler.cfg.instructions compiler.cfg.instructions
compiler.cfg.linear-scan.live-intervals ; compiler.cfg.linear-scan.live-intervals ;
IN: compiler.cfg.linear-scan.rewriting IN: compiler.cfg.linear-scan.assignment
! A vector of live intervals. There is linear searching involved ! A vector of live intervals. There is linear searching involved
! but since we never have too many machine registers (around 30 ! but since we never have too many machine registers (around 30
@ -55,45 +55,24 @@ SYMBOL: unhandled-intervals
] [ 2drop ] if ] [ 2drop ] if
] if ; ] if ;
GENERIC: rewrite-instruction ( insn -- ) : (assign-registers) ( insn -- )
dup
[ defs-vregs ] [ uses-vregs ] bi append
active-intervals get swap '[ vreg>> _ member? ] filter
[ [ vreg>> ] [ reg>> ] bi ] { } map>assoc
>>regs drop ;
M: %cond-branch rewrite-instruction : init-assignment ( live-intervals -- )
[ lookup-register ] change-vreg V{ } clone active-intervals set
drop ; <min-heap> unhandled-intervals set
init-unhandled ;
M: %unary rewrite-instruction : assign-registers ( insns live-intervals -- insns' )
[ lookup-register ] change-dst
[ lookup-register ] change-src
drop ;
M: %peek rewrite-instruction
[ lookup-register ] change-vreg
drop ;
M: %replace rewrite-instruction
[ lookup-register ] change-vreg
drop ;
M: %load-literal rewrite-instruction
[ lookup-register ] change-vreg
drop ;
: lookup-registers ( assoc -- assoc' )
[ dup vreg? [ lookup-register ] when ] assoc-map ;
M: %intrinsic rewrite-instruction
[ lookup-registers ] change-vregs
drop ;
M: _if-intrinsic rewrite-instruction
[ lookup-registers ] change-vregs
drop ;
: rewrite-instructions ( insns -- insns' )
[ [
init-assignment
[ [
[ activate-new-intervals ] [ activate-new-intervals ]
[ drop [ rewrite-instruction ] [ , ] bi ] [ drop [ (assign-registers) ] [ , ] bi ]
[ expire-old-intervals ] [ expire-old-intervals ]
tri tri
] each-index ] each-index

View File

@ -19,5 +19,5 @@ IN: compiler.cfg.linear-scan.debugger
] [ 1array ] if ; ] [ 1array ] if ;
: check-linear-scan ( live-intervals machine-registers -- ) : check-linear-scan ( live-intervals machine-registers -- )
[ [ clone ] map dup ] dip allocate-registers [ [ clone ] map ] dip allocate-registers
[ split-children ] map concat check-assigned ; [ split-children ] map concat check-assigned ;

View File

@ -1,6 +1,19 @@
! Copyright (C) 2008 Slava Pestov. ! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel accessors
compiler.backend
compiler.cfg
compiler.cfg.linear-scan.live-intervals
compiler.cfg.linear-scan.allocation
compiler.cfg.linear-scan.assignment ;
IN: compiler.cfg.linear-scan IN: compiler.cfg.linear-scan
! See http://www.cs.ucla.edu/~palsberg/course/cs132/linearscan.pdf ! See http://www.cs.ucla.edu/~palsberg/course/cs132/linearscan.pdf
! and http://www.ssw.uni-linz.ac.at/Research/Papers/Wimmer04Master/
: linear-scan ( mr -- mr' )
[
dup compute-live-intervals
machine-registers allocate-registers
assign-registers
] change-instructions ;

View File

@ -33,15 +33,17 @@ SYMBOL: live-intervals
: compute-live-intervals* ( insn n -- ) : compute-live-intervals* ( insn n -- )
live-intervals get live-intervals get
[ [ uses-vregs ] 2dip '[ _ swap >vreg _ add-use ] each ] [ [ uses-vregs ] 2dip '[ _ swap _ add-use ] each ]
[ [ defs-vregs ] 2dip '[ _ swap >vreg _ new-live-interval ] each ] [ [ defs-vregs ] 2dip '[ _ swap _ new-live-interval ] each ]
3bi ; 3bi ;
: finalize-live-intervals ( -- ) : finalize-live-intervals ( assoc -- seq' )
#! Reverse uses lists so that we can pop values off. #! Reverse uses lists so that we can pop values off.
live-intervals get [ nip uses>> reverse-here ] assoc-each ; values dup [ uses>> reverse-here ] each ;
: compute-live-intervals ( instructions -- ) : compute-live-intervals ( instructions -- live-intervals )
H{ } clone live-intervals set H{ } clone [
[ compute-live-intervals* ] each-index live-intervals [
finalize-live-intervals ; [ compute-live-intervals* ] each-index
] with-variable
] keep finalize-live-intervals ;

View File

@ -1,4 +0,0 @@
USING: compiler.cfg.linear-scan.rewriting tools.test ;
IN: compiler.cfg.linear-scan.rewriting.tests
\ rewrite-instructions must-infer

View File

@ -56,7 +56,7 @@ M: %branch linearize-insn
dup successors>> first2 swap label>> ; inline dup successors>> first2 swap label>> ; inline
: boolean-conditional ( basic-block insn -- basic-block successor vreg label2 ) : boolean-conditional ( basic-block insn -- basic-block successor vreg label2 )
[ conditional ] [ dst>> ] bi* swap ; inline [ conditional ] [ src>> ] bi* swap ; inline
M: %branch-f linearize-insn M: %branch-f linearize-insn
boolean-conditional _branch-f emit-branch ; boolean-conditional _branch-f emit-branch ;
@ -73,10 +73,10 @@ M: %boolean-intrinsic linearize-insn
"false" define-label "false" define-label
"end" define-label "end" define-label
"false" get over [ quot>> ] [ vregs>> ] bi _if-intrinsic "false" get over [ quot>> ] [ vregs>> ] bi _if-intrinsic
dup out>> t %load-literal dup dst>> t %load-literal
"end" get _branch "end" get _branch
"false" resolve-label "false" resolve-label
dup out>> f %load-literal dup dst>> f %load-literal
"end" resolve-label "end" resolve-label
] with-scope ] with-scope
2drop ; 2drop ;