From 74766d1ccdbe0af56c393c845ff3fdf0e151f1da Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 29 Jul 2009 06:36:14 -0500 Subject: [PATCH] compiler.cfg.linear-scan.assignment: modifies instructions in place instead of storing a registers assoc for further compile-time performance improvement --- .../branch-splitting/branch-splitting.factor | 7 +- .../cfg/instructions/instructions.factor | 46 ++++----- .../linear-scan/assignment/assignment.factor | 10 +- .../cfg/renaming/functor/functor.factor | 52 ++++++++++- basis/compiler/cfg/renaming/renaming.factor | 51 +--------- .../cfg/ssa/construction/construction.factor | 2 +- basis/compiler/codegen/codegen.factor | 93 +++++++------------ 7 files changed, 116 insertions(+), 145 deletions(-) diff --git a/basis/compiler/cfg/branch-splitting/branch-splitting.factor b/basis/compiler/cfg/branch-splitting/branch-splitting.factor index 8618932e14..e5583a14ab 100644 --- a/basis/compiler/cfg/branch-splitting/branch-splitting.factor +++ b/basis/compiler/cfg/branch-splitting/branch-splitting.factor @@ -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. swap [ instructions>> clone-instructions >>instructions ] diff --git a/basis/compiler/cfg/instructions/instructions.factor b/basis/compiler/cfg/instructions/instructions.factor index 066d20ddec..17c46fa0ea 100644 --- a/basis/compiler/cfg/instructions/instructions.factor +++ b/basis/compiler/cfg/instructions/instructions.factor @@ -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 -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 diff --git a/basis/compiler/cfg/linear-scan/assignment/assignment.factor b/basis/compiler/cfg/linear-scan/assignment/assignment.factor index 5cc964a197..071118d60f 100644 --- a/basis/compiler/cfg/linear-scan/assignment/assignment.factor +++ b/basis/compiler/cfg/linear-scan/assignment/assignment.factor @@ -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 diff --git a/basis/compiler/cfg/renaming/functor/functor.factor b/basis/compiler/cfg/renaming/functor/functor.factor index 2a9d8d4911..ffb824f093 100644 --- a/basis/compiler/cfg/renaming/functor/functor.factor +++ b/basis/compiler/cfg/renaming/functor/functor.factor @@ -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 ; \ No newline at end of file +SYNTAX: RENAMING: scan scan-object scan-object scan-object define-renaming ; \ No newline at end of file diff --git a/basis/compiler/cfg/renaming/renaming.factor b/basis/compiler/cfg/renaming/renaming.factor index 9de3fdd8d8..3d032f7510 100644 --- a/basis/compiler/cfg/renaming/renaming.factor +++ b/basis/compiler/cfg/renaming/renaming.factor @@ -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 ; \ No newline at end of file +RENAMING: rename [ rename-value ] [ rename-value ] [ fresh-value ] diff --git a/basis/compiler/cfg/ssa/construction/construction.factor b/basis/compiler/cfg/ssa/construction/construction.factor index 3bbbb887f0..d2c7698999 100644 --- a/basis/compiler/cfg/ssa/construction/construction.factor +++ b/basis/compiler/cfg/ssa/construction/construction.factor @@ -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 -- ) diff --git a/basis/compiler/codegen/codegen.factor b/basis/compiler/codegen/codegen.factor index 993edbf812..f9a4786eb5 100755 --- a/basis/compiler/codegen/codegen.factor +++ b/basis/compiler/codegen/codegen.factor @@ -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