compiler.cfg.linear-scan.assignment: modifies instructions in place instead of storing a registers assoc for further compile-time performance improvement

db4
Slava Pestov 2009-07-29 06:36:14 -05:00
parent 1532a6f2e3
commit 74766d1ccd
7 changed files with 116 additions and 145 deletions

View File

@ -7,11 +7,12 @@ compiler.cfg.renaming compiler.cfg.instructions compiler.cfg.utilities ;
IN: compiler.cfg.branch-splitting
: clone-instructions ( insns -- insns' )
[ clone dup fresh-insn-temps ] map ;
[ clone dup rename-insn-temps ] map ;
: clone-basic-block ( bb -- bb' )
! The new block gets the same RPO number as the old one.
! This is just to make 'back-edge?' work.
! The new block temporarily gets the same RPO number as the old one,
! until the next time RPO is computed. This is just to make
! 'back-edge?' work.
<basic-block>
swap
[ instructions>> clone-instructions >>instructions ]

View File

@ -13,28 +13,28 @@ TUPLE: insn ;
! Instruction with no side effects; if 'out' is never read, we
! can eliminate it.
TUPLE: ##flushable < insn { dst vreg } ;
TUPLE: ##flushable < insn dst ;
! Instruction which is referentially transparent; we can replace
! repeated computation with a reference to a previous value
TUPLE: ##pure < ##flushable ;
TUPLE: ##unary < ##pure { src vreg } ;
TUPLE: ##unary/temp < ##unary { temp vreg } ;
TUPLE: ##binary < ##pure { src1 vreg } { src2 vreg } ;
TUPLE: ##binary-imm < ##pure { src1 vreg } { src2 integer } ;
TUPLE: ##unary < ##pure src ;
TUPLE: ##unary/temp < ##unary temp ;
TUPLE: ##binary < ##pure src1 src2 ;
TUPLE: ##binary-imm < ##pure src1 { src2 integer } ;
TUPLE: ##commutative < ##binary ;
TUPLE: ##commutative-imm < ##binary-imm ;
! Instruction only used for its side effect, produces no values
TUPLE: ##effect < insn { src vreg } ;
TUPLE: ##effect < insn src ;
! Read/write ops: candidates for alias analysis
TUPLE: ##read < ##flushable ;
TUPLE: ##write < ##effect ;
TUPLE: ##alien-getter < ##flushable { src vreg } ;
TUPLE: ##alien-setter < ##effect { value vreg } ;
TUPLE: ##alien-getter < ##flushable src ;
TUPLE: ##alien-setter < ##effect value ;
! Stack operations
INSN: ##load-immediate < ##pure { val integer } ;
@ -63,14 +63,14 @@ INSN: ##no-tco ;
INSN: ##dispatch src temp ;
! Slot access
INSN: ##slot < ##read { obj vreg } { slot vreg } { tag integer } { temp vreg } ;
INSN: ##slot-imm < ##read { obj vreg } { slot integer } { tag integer } ;
INSN: ##set-slot < ##write { obj vreg } { slot vreg } { tag integer } { temp vreg } ;
INSN: ##set-slot-imm < ##write { obj vreg } { slot integer } { tag integer } ;
INSN: ##slot < ##read obj slot { tag integer } temp ;
INSN: ##slot-imm < ##read obj { slot integer } { tag integer } ;
INSN: ##set-slot < ##write obj slot { tag integer } temp ;
INSN: ##set-slot-imm < ##write obj { slot integer } { tag integer } ;
! String element access
INSN: ##string-nth < ##flushable { obj vreg } { index vreg } { temp vreg } ;
INSN: ##set-string-nth-fast < ##effect { obj vreg } { index vreg } { temp vreg } ;
INSN: ##string-nth < ##flushable obj index temp ;
INSN: ##set-string-nth-fast < ##effect obj index temp ;
! Integer arithmetic
INSN: ##add < ##commutative ;
@ -150,7 +150,7 @@ INSN: ##set-alien-float < ##alien-setter ;
INSN: ##set-alien-double < ##alien-setter ;
! Memory allocation
INSN: ##allot < ##flushable size class { temp vreg } ;
INSN: ##allot < ##flushable size class temp ;
UNION: ##allocation ##allot ##box-float ##box-alien ##integer>bignum ;
@ -173,10 +173,10 @@ INSN: ##branch ;
INSN: ##phi < ##pure inputs ;
! Conditionals
TUPLE: ##conditional-branch < insn { src1 vreg } { src2 vreg } cc ;
TUPLE: ##conditional-branch < insn src1 src2 cc ;
INSN: ##compare-branch < ##conditional-branch ;
INSN: ##compare-imm-branch { src1 vreg } { src2 integer } cc ;
INSN: ##compare-imm-branch src1 { src2 integer } cc ;
INSN: ##compare < ##binary cc temp ;
INSN: ##compare-imm < ##binary-imm cc temp ;
@ -185,12 +185,12 @@ INSN: ##compare-float-branch < ##conditional-branch ;
INSN: ##compare-float < ##binary cc temp ;
! Overflowing arithmetic
TUPLE: ##fixnum-overflow < insn { dst vreg } { src1 vreg } { src2 vreg } ;
TUPLE: ##fixnum-overflow < insn dst src1 src2 ;
INSN: ##fixnum-add < ##fixnum-overflow ;
INSN: ##fixnum-sub < ##fixnum-overflow ;
INSN: ##fixnum-mul < ##fixnum-overflow ;
INSN: ##gc { temp1 vreg } { temp2 vreg } live-values ;
INSN: ##gc temp1 temp2 live-values ;
! Instructions used by machine IR only.
INSN: _prologue stack-frame ;
@ -204,22 +204,22 @@ INSN: _loop-entry ;
INSN: _dispatch src temp ;
INSN: _dispatch-label label ;
TUPLE: _conditional-branch < insn label { src1 vreg } { src2 vreg } cc ;
TUPLE: _conditional-branch < insn label src1 src2 cc ;
INSN: _compare-branch < _conditional-branch ;
INSN: _compare-imm-branch label { src1 vreg } { src2 integer } cc ;
INSN: _compare-imm-branch label src1 { src2 integer } cc ;
INSN: _compare-float-branch < _conditional-branch ;
! Overflowing arithmetic
TUPLE: _fixnum-overflow < insn label { dst vreg } { src1 vreg } { src2 vreg } ;
TUPLE: _fixnum-overflow < insn label dst src1 src2 ;
INSN: _fixnum-add < _fixnum-overflow ;
INSN: _fixnum-sub < _fixnum-overflow ;
INSN: _fixnum-mul < _fixnum-overflow ;
TUPLE: spill-slot n ; C: <spill-slot> spill-slot
INSN: _gc { temp1 vreg } { temp2 vreg } gc-roots gc-root-count gc-root-size ;
INSN: _gc temp1 temp2 gc-roots gc-root-count gc-root-size ;
! These instructions operate on machine registers and not
! virtual registers

View File

@ -9,6 +9,7 @@ compiler.cfg.def-use
compiler.cfg.liveness
compiler.cfg.registers
compiler.cfg.instructions
compiler.cfg.renaming.functor
compiler.cfg.linear-scan.allocation
compiler.cfg.linear-scan.allocation.state
compiler.cfg.linear-scan.live-intervals ;
@ -95,13 +96,12 @@ SYMBOL: register-live-outs
GENERIC: assign-registers-in-insn ( insn -- )
: all-vregs ( insn -- vregs )
[ [ temp-vregs ] [ uses-vregs ] bi append ]
[ defs-vreg ] bi
[ suffix ] when* ;
: vreg>reg ( vreg -- reg ) pending-interval-assoc get at ;
RENAMING: assign [ vreg>reg ] [ vreg>reg ] [ vreg>reg ]
M: vreg-insn assign-registers-in-insn
dup all-vregs pending-interval-assoc get extract-keys >>regs drop ;
[ assign-insn-defs ] [ assign-insn-uses ] [ assign-insn-temps ] tri ;
M: ##gc assign-registers-in-insn
! This works because ##gc is always the first instruction

View File

@ -4,10 +4,11 @@ USING: functors assocs kernel accessors compiler.cfg.instructions
lexer parser ;
IN: compiler.cfg.renaming.functor
FUNCTOR: define-renaming ( NAME DEF-QUOT USE-QUOT -- )
FUNCTOR: define-renaming ( NAME DEF-QUOT USE-QUOT TEMP-QUOT -- )
rename-insn-defs DEFINES ${NAME}-insn-defs
rename-insn-uses DEFINES ${NAME}-insn-uses
rename-insn-temps DEFINES ${NAME}-insn-temps
WHERE
@ -111,6 +112,53 @@ M: ##phi rename-insn-uses
M: insn rename-insn-uses drop ;
GENERIC: rename-insn-temps ( insn -- )
M: ##write-barrier rename-insn-temps
TEMP-QUOT change-card#
TEMP-QUOT change-table
drop ;
M: ##unary/temp rename-insn-temps
TEMP-QUOT change-temp drop ;
M: ##allot rename-insn-temps
TEMP-QUOT change-temp drop ;
M: ##dispatch rename-insn-temps
TEMP-QUOT change-temp drop ;
M: ##slot rename-insn-temps
TEMP-QUOT change-temp drop ;
M: ##set-slot rename-insn-temps
TEMP-QUOT change-temp drop ;
M: ##string-nth rename-insn-temps
TEMP-QUOT change-temp drop ;
M: ##set-string-nth-fast rename-insn-temps
TEMP-QUOT change-temp drop ;
M: ##compare rename-insn-temps
TEMP-QUOT change-temp drop ;
M: ##compare-imm rename-insn-temps
TEMP-QUOT change-temp drop ;
M: ##compare-float rename-insn-temps
TEMP-QUOT change-temp drop ;
M: ##gc rename-insn-temps
TEMP-QUOT change-temp1
TEMP-QUOT change-temp2
drop ;
M: _dispatch rename-insn-temps
TEMP-QUOT change-temp drop ;
M: insn rename-insn-temps drop ;
;FUNCTOR
SYNTAX: RENAMING: scan scan-object scan-object define-renaming ;
SYNTAX: RENAMING: scan scan-object scan-object scan-object define-renaming ;

View File

@ -10,54 +10,7 @@ SYMBOL: renamings
: rename-value ( vreg -- vreg' )
renamings get ?at drop ;
RENAMING: rename [ rename-value ] [ rename-value ]
: fresh-vreg ( vreg -- vreg' )
: fresh-value ( vreg -- vreg' )
reg-class>> next-vreg ;
GENERIC: fresh-insn-temps ( insn -- )
M: ##write-barrier fresh-insn-temps
[ fresh-vreg ] change-card#
[ fresh-vreg ] change-table
drop ;
M: ##unary/temp fresh-insn-temps
[ fresh-vreg ] change-temp drop ;
M: ##allot fresh-insn-temps
[ fresh-vreg ] change-temp drop ;
M: ##dispatch fresh-insn-temps
[ fresh-vreg ] change-temp drop ;
M: ##slot fresh-insn-temps
[ fresh-vreg ] change-temp drop ;
M: ##set-slot fresh-insn-temps
[ fresh-vreg ] change-temp drop ;
M: ##string-nth fresh-insn-temps
[ fresh-vreg ] change-temp drop ;
M: ##set-string-nth-fast fresh-insn-temps
[ fresh-vreg ] change-temp drop ;
M: ##compare fresh-insn-temps
[ fresh-vreg ] change-temp drop ;
M: ##compare-imm fresh-insn-temps
[ fresh-vreg ] change-temp drop ;
M: ##compare-float fresh-insn-temps
[ fresh-vreg ] change-temp drop ;
M: ##gc fresh-insn-temps
[ fresh-vreg ] change-temp1
[ fresh-vreg ] change-temp2
drop ;
M: _dispatch fresh-insn-temps
[ fresh-vreg ] change-temp drop ;
M: insn fresh-insn-temps drop ;
RENAMING: rename [ rename-value ] [ rename-value ] [ fresh-value ]

View File

@ -84,7 +84,7 @@ SYMBOLS: stacks pushed ;
: top-name ( vreg -- vreg' )
stacks get at last ;
RENAMING: ssa-rename [ gen-name ] [ top-name ]
RENAMING: ssa-rename [ gen-name ] [ top-name ] [ ]
GENERIC: rename-insn ( insn -- )

View File

@ -24,14 +24,6 @@ H{ } clone insn-counts set-global
GENERIC: generate-insn ( insn -- )
SYMBOL: registers
: register ( vreg -- operand )
registers get at [ "Bad value" throw ] unless* ;
: ?register ( obj -- operand )
dup vreg? [ register ] when ;
TUPLE: asm label code calls ;
SYMBOL: calls
@ -60,9 +52,8 @@ SYMBOL: labels
instructions>>
[
[ class insn-counts get inc-at ]
[ regs>> registers set ]
[ generate-insn ]
tri
bi
] each
] bi
] with-fixup ;
@ -79,16 +70,16 @@ SYMBOL: labels
M: ##no-tco generate-insn drop ;
M: ##load-immediate generate-insn
[ dst>> register ] [ val>> ] bi %load-immediate ;
[ dst>> ] [ val>> ] bi %load-immediate ;
M: ##load-reference generate-insn
[ dst>> register ] [ obj>> ] bi %load-reference ;
[ dst>> ] [ obj>> ] bi %load-reference ;
M: ##peek generate-insn
[ dst>> register ] [ loc>> ] bi %peek ;
[ dst>> ] [ loc>> ] bi %peek ;
M: ##replace generate-insn
[ src>> register ] [ loc>> ] bi %replace ;
[ src>> ] [ loc>> ] bi %replace ;
M: ##inc-d generate-insn n>> %inc-d ;
@ -103,7 +94,7 @@ M: ##jump generate-insn word>> [ add-call ] [ %jump ] bi ;
M: ##return generate-insn drop %return ;
M: _dispatch generate-insn
[ src>> register ] [ temp>> register ] bi %dispatch ;
[ src>> ] [ temp>> ] bi %dispatch ;
M: _dispatch-label generate-insn
label>> lookup-label
@ -111,56 +102,34 @@ M: _dispatch-label generate-insn
rc-absolute-cell label-fixup ;
: >slot< ( insn -- dst obj slot tag )
{
[ dst>> register ]
[ obj>> register ]
[ slot>> ?register ]
[ tag>> ]
} cleave ; inline
{ [ dst>> ] [ obj>> ] [ slot>> ] [ tag>> ] } cleave ; inline
M: ##slot generate-insn
[ >slot< ] [ temp>> register ] bi %slot ;
[ >slot< ] [ temp>> ] bi %slot ;
M: ##slot-imm generate-insn
>slot< %slot-imm ;
: >set-slot< ( insn -- src obj slot tag )
{
[ src>> register ]
[ obj>> register ]
[ slot>> ?register ]
[ tag>> ]
} cleave ; inline
{ [ src>> ] [ obj>> ] [ slot>> ] [ tag>> ] } cleave ; inline
M: ##set-slot generate-insn
[ >set-slot< ] [ temp>> register ] bi %set-slot ;
[ >set-slot< ] [ temp>> ] bi %set-slot ;
M: ##set-slot-imm generate-insn
>set-slot< %set-slot-imm ;
M: ##string-nth generate-insn
{
[ dst>> register ]
[ obj>> register ]
[ index>> register ]
[ temp>> register ]
} cleave %string-nth ;
{ [ dst>> ] [ obj>> ] [ index>> ] [ temp>> ] } cleave %string-nth ;
M: ##set-string-nth-fast generate-insn
{
[ src>> register ]
[ obj>> register ]
[ index>> register ]
[ temp>> register ]
} cleave %set-string-nth-fast ;
{ [ src>> ] [ obj>> ] [ index>> ] [ temp>> ] } cleave %set-string-nth-fast ;
: dst/src ( insn -- dst src )
[ dst>> register ] [ src>> register ] bi ; inline
[ dst>> ] [ src>> ] bi ; inline
: dst/src1/src2 ( insn -- dst src1 src2 )
[ dst>> register ]
[ src1>> register ]
[ src2>> ?register ] tri ; inline
[ dst>> ] [ src1>> ] [ src2>> ] tri ; inline
M: ##add generate-insn dst/src1/src2 %add ;
M: ##add-imm generate-insn dst/src1/src2 %add-imm ;
@ -191,7 +160,7 @@ M: _fixnum-sub generate-insn label/dst/src1/src2 %fixnum-sub ;
M: _fixnum-mul generate-insn label/dst/src1/src2 %fixnum-mul ;
: dst/src/temp ( insn -- dst src temp )
[ dst/src ] [ temp>> register ] bi ; inline
[ dst/src ] [ temp>> ] bi ; inline
M: ##integer>bignum generate-insn dst/src/temp %integer>bignum ;
M: ##bignum>integer generate-insn dst/src/temp %bignum>integer ;
@ -222,7 +191,7 @@ M: ##alien-float generate-insn dst/src %alien-float ;
M: ##alien-double generate-insn dst/src %alien-double ;
: >alien-setter< ( insn -- src value )
[ src>> register ] [ value>> register ] bi ; inline
[ src>> ] [ value>> ] bi ; inline
M: ##set-alien-integer-1 generate-insn >alien-setter< %set-alien-integer-1 ;
M: ##set-alien-integer-2 generate-insn >alien-setter< %set-alien-integer-2 ;
@ -233,23 +202,23 @@ M: ##set-alien-double generate-insn >alien-setter< %set-alien-double ;
M: ##allot generate-insn
{
[ dst>> register ]
[ dst>> ]
[ size>> ]
[ class>> ]
[ temp>> register ]
[ temp>> ]
} cleave
%allot ;
M: ##write-barrier generate-insn
[ src>> register ]
[ card#>> register ]
[ table>> register ]
[ src>> ]
[ card#>> ]
[ table>> ]
tri %write-barrier ;
M: _gc generate-insn
{
[ temp1>> register ]
[ temp2>> register ]
[ temp1>> ]
[ temp2>> ]
[ gc-roots>> ]
[ gc-root-count>> ]
} cleave %gc ;
@ -257,7 +226,7 @@ M: _gc generate-insn
M: _loop-entry generate-insn drop %loop-entry ;
M: ##alien-global generate-insn
[ dst>> register ] [ symbol>> ] [ library>> ] tri
[ dst>> ] [ symbol>> ] [ library>> ] tri
%alien-global ;
! ##alien-invoke
@ -370,7 +339,7 @@ M: long-long-type flatten-value-type ( type -- types )
: objects>registers ( params -- )
#! Generate code for unboxing a list of C types, then
#! generate code for moving these parameters to register on
#! generate code for moving these parameters to registers on
#! architectures where parameters are passed in registers.
[
[ prepare-box-struct ] keep
@ -499,11 +468,11 @@ M: _branch generate-insn
: >compare< ( insn -- dst temp cc src1 src2 )
{
[ dst>> register ]
[ temp>> register ]
[ dst>> ]
[ temp>> ]
[ cc>> ]
[ src1>> register ]
[ src2>> ?register ]
[ src1>> ]
[ src2>> ]
} cleave ; inline
M: ##compare generate-insn >compare< %compare ;
@ -514,8 +483,8 @@ M: ##compare-float generate-insn >compare< %compare-float ;
{
[ label>> lookup-label ]
[ cc>> ]
[ src1>> register ]
[ src2>> ?register ]
[ src1>> ]
[ src2>> ]
} cleave ; inline
M: _compare-branch generate-insn