From 239578353f0adf584d813ecffb366f2eae4e7e31 Mon Sep 17 00:00:00 2001 From: Slava Pestov <slava@slava-pestovs-macbook-pro.local> Date: Fri, 17 Oct 2008 15:35:04 -0500 Subject: [PATCH] Simplifying vregs work in progress --- basis/compiler/cfg/builder/builder.factor | 2 +- .../cfg/instructions/instructions.factor | 60 ++++++------- basis/compiler/cfg/stacks/stacks.factor | 85 +++++++++---------- basis/compiler/cfg/templates/templates.factor | 19 ++--- basis/compiler/codegen/codegen.factor | 2 +- 5 files changed, 80 insertions(+), 88 deletions(-) diff --git a/basis/compiler/cfg/builder/builder.factor b/basis/compiler/cfg/builder/builder.factor index 3bc4a738c1..8b5202dd63 100755 --- a/basis/compiler/cfg/builder/builder.factor +++ b/basis/compiler/cfg/builder/builder.factor @@ -253,7 +253,7 @@ M: #dispatch emit-node type tagged boa phantom-push ; : emit-write-barrier ( -- ) - phantom-pop dup >vreg fresh-object? [ drop ] [ + phantom-pop dup fresh-object? [ drop ] [ int-regs next-vreg int-regs next-vreg ##write-barrier diff --git a/basis/compiler/cfg/instructions/instructions.factor b/basis/compiler/cfg/instructions/instructions.factor index d92520c77d..fd7d071518 100644 --- a/basis/compiler/cfg/instructions/instructions.factor +++ b/basis/compiler/cfg/instructions/instructions.factor @@ -1,21 +1,21 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: assocs accessors arrays kernel sequences namespaces +USING: assocs accessors arrays kernel sequences namespaces words math compiler.cfg.registers compiler.cfg.instructions.syntax ; IN: compiler.cfg.instructions ! Virtual CPU instructions, used by CFG and machine IRs -TUPLE: ##cond-branch < insn src ; -TUPLE: ##unary < insn dst src ; -TUPLE: ##nullary < insn dst ; +TUPLE: ##cond-branch < insn { src vreg } ; +TUPLE: ##unary < insn { dst vreg } { src vreg } ; +TUPLE: ##nullary < insn { dst vreg } ; ! Stack operations INSN: ##load-literal < ##nullary obj ; -INSN: ##peek < ##nullary loc ; -INSN: ##replace src loc ; -INSN: ##inc-d n ; -INSN: ##inc-r n ; +INSN: ##peek < ##nullary { loc loc } ; +INSN: ##replace { src vreg } { loc loc } ; +INSN: ##inc-d { n integer } ; +INSN: ##inc-r { n integer } ; ! Subroutine calls TUPLE: stack-frame @@ -33,8 +33,8 @@ INSN: ##return ; INSN: ##intrinsic quot defs-vregs uses-vregs ; ! Jump tables -INSN: ##dispatch-label label ; INSN: ##dispatch src temp ; +INSN: ##dispatch-label label ; ! Boxing and unboxing INSN: ##copy < ##unary ; @@ -44,12 +44,12 @@ INSN: ##unbox-f < ##unary ; INSN: ##unbox-alien < ##unary ; INSN: ##unbox-byte-array < ##unary ; INSN: ##unbox-any-c-ptr < ##unary ; -INSN: ##box-float < ##unary temp ; -INSN: ##box-alien < ##unary temp ; +INSN: ##box-float < ##unary { temp vreg } ; +INSN: ##box-alien < ##unary { temp vreg } ; ! Memory allocation -INSN: ##allot < ##nullary size type tag temp ; -INSN: ##write-barrier src card# table ; +INSN: ##allot < ##nullary size type tag { temp vreg } ; +INSN: ##write-barrier { src vreg } card# table ; INSN: ##gc ; ! FFI @@ -61,28 +61,28 @@ INSN: ##callback-return params ; GENERIC: defs-vregs ( insn -- seq ) GENERIC: uses-vregs ( insn -- seq ) -M: ##nullary defs-vregs dst>> >vreg 1array ; -M: ##unary defs-vregs dst>> >vreg 1array ; +M: ##nullary defs-vregs dst>> 1array ; +M: ##unary defs-vregs dst>> 1array ; M: ##write-barrier defs-vregs - [ card#>> >vreg ] [ table>> >vreg ] bi 2array ; + [ card#>> ] [ table>> ] bi 2array ; : allot-defs-vregs ( insn -- seq ) - [ dst>> >vreg ] [ temp>> >vreg ] bi 2array ; + [ dst>> ] [ temp>> ] bi 2array ; M: ##box-float defs-vregs allot-defs-vregs ; M: ##box-alien defs-vregs allot-defs-vregs ; M: ##allot defs-vregs allot-defs-vregs ; -M: ##dispatch defs-vregs temp>> >vreg 1array ; +M: ##dispatch defs-vregs temp>> 1array ; M: insn defs-vregs drop f ; -M: ##replace uses-vregs src>> >vreg 1array ; -M: ##unary uses-vregs src>> >vreg 1array ; -M: ##write-barrier uses-vregs src>> >vreg 1array ; -M: ##dispatch uses-vregs src>> >vreg 1array ; +M: ##replace uses-vregs src>> 1array ; +M: ##unary uses-vregs src>> 1array ; +M: ##write-barrier uses-vregs src>> 1array ; +M: ##dispatch uses-vregs src>> 1array ; M: insn uses-vregs drop f ; : intrinsic-vregs ( assoc -- seq' ) - [ nip >vreg ] { } assoc>map sift ; + values sift ; : intrinsic-defs-vregs ( insn -- seq ) defs-vregs>> intrinsic-vregs ; @@ -102,7 +102,7 @@ INSN: ##branch-f < ##cond-branch ; INSN: ##branch-t < ##cond-branch ; INSN: ##if-intrinsic quot defs-vregs uses-vregs ; -M: ##cond-branch uses-vregs src>> >vreg 1array ; +M: ##cond-branch uses-vregs src>> 1array ; M: ##if-intrinsic defs-vregs intrinsic-defs-vregs ; M: ##if-intrinsic uses-vregs intrinsic-uses-vregs ; @@ -113,20 +113,20 @@ INSN: _epilogue stack-frame ; INSN: _label id ; -TUPLE: _cond-branch < insn src label ; +TUPLE: _cond-branch < insn { src vreg } label ; INSN: _branch label ; INSN: _branch-f < _cond-branch ; INSN: _branch-t < _cond-branch ; INSN: _if-intrinsic label quot defs-vregs uses-vregs ; -M: _cond-branch uses-vregs src>> >vreg 1array ; +M: _cond-branch uses-vregs src>> 1array ; M: _if-intrinsic defs-vregs intrinsic-defs-vregs ; M: _if-intrinsic uses-vregs intrinsic-uses-vregs ; -INSN: _spill-integer src n ; -INSN: _reload-integer dst n ; +INSN: _spill-integer { src vreg } n ; +INSN: _reload-integer { dst vreg } n ; -INSN: _spill-float src n ; -INSN: _reload-float dst n ; +INSN: _spill-float { src vreg } n ; +INSN: _reload-float { dst vreg } n ; diff --git a/basis/compiler/cfg/stacks/stacks.factor b/basis/compiler/cfg/stacks/stacks.factor index 39d8109b05..8d0537c64d 100755 --- a/basis/compiler/cfg/stacks/stacks.factor +++ b/basis/compiler/cfg/stacks/stacks.factor @@ -16,10 +16,7 @@ PREDICATE: small-tagged < integer tag-fixnum small-enough? ; ! Value protocol GENERIC: move-spec ( obj -- spec ) GENERIC: live-loc? ( actual current -- ? ) -GENERIC# (lazy-load) 1 ( value spec -- value ) -GENERIC# (eager-load) 1 ( value spec -- value ) GENERIC: lazy-store ( dst src -- ) -GENERIC: minimal-ds-loc* ( min obj -- min ) ! This will be a multimethod soon DEFER: ##move @@ -28,7 +25,6 @@ PRIVATE> ! Default implementation M: value live-loc? 2drop f ; -M: value minimal-ds-loc* drop ; M: value lazy-store 2drop ; M: vreg move-spec reg-class>> move-spec ; @@ -40,7 +36,6 @@ M: int-regs value-class* drop object ; M: float-regs move-spec drop float ; M: float-regs value-class* drop float ; -M: ds-loc minimal-ds-loc* n>> min ; M: ds-loc live-loc? over ds-loc? [ [ n>> ] bi@ = not ] [ 2drop t ] if ; @@ -67,14 +62,14 @@ M: unboxed-c-ptr move-spec class ; M: constant move-spec class ; ! Moving values between locations and registers -: ##move-bug ( -- * ) "Bug in generator.registers" throw ; +: ##move-bug ( -- * ) "Bug in compiler.cfg.stacks" throw ; : ##unbox-c-ptr ( dst src -- ) dup value-class { - { [ dup \ f class<= ] [ drop ##unbox-f ] } - { [ dup simple-alien class<= ] [ drop ##unbox-alien ] } - { [ dup byte-array class<= ] [ drop ##unbox-byte-array ] } - [ drop ##unbox-any-c-ptr ] + { [ dup \ f class<= ] [ drop [ >vreg ] bi@ ##unbox-f ] } + { [ dup simple-alien class<= ] [ drop [ >vreg ] bi@ ##unbox-alien ] } + { [ dup byte-array class<= ] [ drop [ >vreg ] bi@ ##unbox-byte-array ] } + [ drop [ >vreg ] bi@ ##unbox-any-c-ptr ] } cond ; inline : ##move-via-temp ( dst src -- ) @@ -97,28 +92,28 @@ SYMBOL: fresh-objects : ##move ( dst src -- ) 2dup [ move-spec ] bi@ 2array { - { { f f } [ ##copy ] } - { { unboxed-alien unboxed-alien } [ ##copy ] } - { { unboxed-byte-array unboxed-byte-array } [ ##copy ] } - { { unboxed-f unboxed-f } [ ##copy ] } - { { unboxed-c-ptr unboxed-c-ptr } [ ##copy ] } - { { float float } [ ##copy-float ] } + { { f f } [ [ >vreg ] bi@ ##copy ] } + { { unboxed-alien unboxed-alien } [ [ >vreg ] bi@ ##copy ] } + { { unboxed-byte-array unboxed-byte-array } [ [ >vreg ] bi@ ##copy ] } + { { unboxed-f unboxed-f } [ [ >vreg ] bi@ ##copy ] } + { { unboxed-c-ptr unboxed-c-ptr } [ [ >vreg ] bi@ ##copy ] } + { { float float } [ [ >vreg ] bi@ ##copy-float ] } { { f unboxed-c-ptr } [ ##move-bug ] } { { f unboxed-byte-array } [ ##move-bug ] } - { { f constant } [ value>> ##load-literal ] } + { { f constant } [ [ >vreg ] [ value>> ] bi* ##load-literal ] } - { { f float } [ int-regs next-vreg ##box-float t fresh-object ] } - { { f unboxed-alien } [ int-regs next-vreg ##box-alien t fresh-object ] } - { { f loc } [ ##peek ] } + { { f float } [ [ >vreg ] bi@ int-regs next-vreg ##box-float t fresh-object ] } + { { f unboxed-alien } [ [ >vreg ] bi@ int-regs next-vreg ##box-alien t fresh-object ] } + { { f loc } [ [ >vreg ] dip ##peek ] } - { { float f } [ ##unbox-float ] } - { { unboxed-alien f } [ ##unbox-alien ] } - { { unboxed-byte-array f } [ ##unbox-byte-array ] } - { { unboxed-f f } [ ##unbox-f ] } + { { float f } [ [ >vreg ] bi@ ##unbox-float ] } + { { unboxed-alien f } [ [ >vreg ] bi@ ##unbox-alien ] } + { { unboxed-byte-array f } [ [ >vreg ] bi@ ##unbox-byte-array ] } + { { unboxed-f f } [ [ >vreg ] bi@ ##unbox-f ] } { { unboxed-c-ptr f } [ ##unbox-c-ptr ] } - { { loc f } [ swap ##replace ] } + { { loc f } [ >vreg swap ##replace ] } [ drop ##move-via-temp ] } case ; @@ -168,7 +163,7 @@ M: phantom-retainstack finalize-height : phantom-locs ( n phantom -- locs ) #! A sequence of n ds-locs or rs-locs indexing the stack. - >r <reversed> r> '[ _ <loc> ] map ; + [ <reversed> ] dip '[ _ <loc> ] map ; : phantom-locs* ( phantom -- locs ) [ stack>> length ] keep phantom-locs ; @@ -209,15 +204,6 @@ M: phantom-retainstack finalize-height : finalize-heights ( -- ) [ finalize-height ] each-phantom ; -: (live-locs) ( phantom -- seq ) - #! Discard locs which haven't moved - [ phantom-locs* ] [ stack>> ] bi zip - [ live-loc? ] assoc-filter - values ; - -: live-locs ( -- seq ) - [ (live-locs) ] each-phantom append prune ; - : reg-spec>class ( spec -- class ) float eq? double-float-regs int-regs ? ; @@ -231,6 +217,14 @@ M: phantom-retainstack finalize-height [ drop ] } case ; +: alloc-vreg-for ( value spec -- vreg ) + alloc-vreg swap value-class + over tagged? [ >>class ] [ drop ] if ; + +: (eager-load) ( value spec -- vreg ) + [ alloc-vreg-for ] [ drop ] 2bi + [ ##move ] [ drop >vreg ] 2bi ; + : compatible? ( value spec -- ? ) >r move-spec r> { { [ 2dup = ] [ t ] } @@ -240,20 +234,21 @@ M: phantom-retainstack finalize-height [ f ] } cond 2nip ; -: alloc-vreg-for ( value spec -- vreg ) - alloc-vreg swap value-class - over tagged? [ >>class ] [ drop ] if ; - -M: value (lazy-load) +: (lazy-load) ( value spec -- value ) { - { [ dup { small-slot small-tagged } memq? ] [ drop ] } - { [ 2dup compatible? ] [ drop ] } + { [ dup { small-slot small-tagged } memq? ] [ drop >vreg ] } + { [ 2dup compatible? ] [ drop >vreg ] } [ (eager-load) ] } cond ; -M: value (eager-load) ( value spec -- vreg ) - [ alloc-vreg-for ] [ drop ] 2bi - [ ##move ] [ drop ] 2bi ; +: (live-locs) ( phantom -- seq ) + #! Discard locs which haven't moved + [ phantom-locs* ] [ stack>> ] bi zip + [ live-loc? ] assoc-filter + values ; + +: live-locs ( -- seq ) + [ (live-locs) ] each-phantom append prune ; M: loc lazy-store 2dup live-loc? [ "live-locs" get at ##move ] [ 2drop ] if ; diff --git a/basis/compiler/cfg/templates/templates.factor b/basis/compiler/cfg/templates/templates.factor index 33c0efae55..9446d66683 100644 --- a/basis/compiler/cfg/templates/templates.factor +++ b/basis/compiler/cfg/templates/templates.factor @@ -7,14 +7,6 @@ IN: compiler.cfg.templates TUPLE: template input output scratch clobber gc ; -: phantom&spec ( phantom specs -- phantom' specs' ) - >r stack>> r> - [ length f pad-left ] keep - [ <reversed> ] bi@ ; inline - -: phantom&spec-agree? ( phantom spec quot -- ? ) - >r phantom&spec r> 2all? ; inline - : live-vregs ( -- seq ) [ stack>> [ >vreg ] map sift ] each-phantom append ; @@ -41,7 +33,7 @@ TUPLE: template input output scratch clobber gc ; ] with-scope ; : alloc-scratch ( template -- assoc ) - scratch>> [ swap alloc-vreg ] assoc-map ; + scratch>> [ swap alloc-vreg >vreg ] assoc-map ; : do-template-inputs ( template -- defs uses ) #! Load input values into registers and allocates scratch @@ -60,6 +52,11 @@ TUPLE: template input output scratch clobber gc ; [ do-template-outputs ] 2keep ] dip call ; inline +: phantom&spec ( phantom specs -- phantom' specs' ) + >r stack>> r> + [ length f pad-left ] keep + [ <reversed> ] bi@ ; inline + : value-matches? ( value spec -- ? ) #! If the spec is a quotation and the value is a literal #! fixnum, see if the quotation yields true when applied @@ -80,8 +77,8 @@ TUPLE: template input output scratch clobber gc ; >r >r value-class 2 r> ?nth class-matches? r> and ; : template-matches? ( template -- ? ) - input>> phantom-datastack get swap - [ spec-matches? ] phantom&spec-agree? ; + input>> phantom-datastack get swap phantom&spec + [ spec-matches? ] 2all? ; : find-template ( templates -- pair/f ) #! Pair has shape { quot assoc } diff --git a/basis/compiler/codegen/codegen.factor b/basis/compiler/codegen/codegen.factor index 0a79d14778..44e2fd6bac 100644 --- a/basis/compiler/codegen/codegen.factor +++ b/basis/compiler/codegen/codegen.factor @@ -24,7 +24,7 @@ M: constant v>operand value>> [ tag-fixnum ] [ \ f tag-number ] if* ; M: value v>operand - >vreg [ registers get at ] [ "Bad value" throw ] if* ; + registers get at [ "Bad value" throw ] unless* ; : generate-insns ( insns -- code ) [