Working on new codegen again

db4
Slava Pestov 2008-10-07 16:13:29 -05:00
parent 7c05a777ba
commit 6a5dd26c52
9 changed files with 86 additions and 72 deletions

View File

@ -1,15 +1,11 @@
! 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: accessors kernel namespaces make math sequences layouts USING: accessors kernel namespaces make math sequences layouts
alien.c-types alien.structs compiler.backend ; alien.c-types alien.structs cpu.architecture ;
IN: compiler.alien IN: compiler.alien
! Common utilities
: large-struct? ( ctype -- ? ) : large-struct? ( ctype -- ? )
dup c-struct? [ dup c-struct? [ struct-small-enough? not ] [ drop f ] if ;
heap-size struct-small-enough? not
] [ drop f ] if ;
: alien-parameters ( params -- seq ) : alien-parameters ( params -- seq )
dup parameters>> dup parameters>>
@ -31,16 +27,3 @@ IN: compiler.alien
[ parameter-align drop dup , ] keep stack-size + [ parameter-align drop dup , ] keep stack-size +
] reduce cell align ] reduce cell align
] { } make ; ] { } make ;
: return-size ( ctype -- n )
#! Amount of space we reserve for a return value.
dup large-struct? [ heap-size ] [ drop 0 ] if ;
: alien-stack-frame ( params -- n )
alien-parameters parameter-sizes drop ;
: alien-invoke-frame ( params -- n )
#! One cell is temporary storage, temp@
dup return>> return-size
swap alien-stack-frame +
cell + ;

View File

@ -33,10 +33,7 @@ GENERIC# load-literal 1 ( obj reg -- )
HOOK: load-indirect cpu ( obj reg -- ) HOOK: load-indirect cpu ( obj reg -- )
HOOK: stack-frame cpu ( frame-size -- n ) HOOK: stack-frame-size cpu ( frame-size -- n )
: stack-frame* ( -- n )
\ stack-frame get stack-frame ;
! Set up caller stack frame ! Set up caller stack frame
HOOK: %prologue cpu ( n -- ) HOOK: %prologue cpu ( n -- )

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs combinators hashtables kernel USING: accessors arrays assocs combinators hashtables kernel
math fry namespaces make sequences words byte-arrays math fry namespaces make sequences words byte-arrays
locals layouts locals layouts alien.c-types alien.structs
stack-checker.inlining stack-checker.inlining
compiler.intrinsics compiler.intrinsics
compiler.tree compiler.tree
@ -107,7 +107,7 @@ SYMBOL: +if-intrinsics+
: emit-call ( word -- next ) : emit-call ( word -- next )
finalize-phantoms finalize-phantoms
{ {
{ [ tail-call? not ] [ 0 ##frame-required ##call iterate-next ] } { [ tail-call? not ] [ ##simple-stack-frame ##call iterate-next ] }
{ [ dup loops get key? ] [ loops get at local-recursive-call ] } { [ dup loops get key? ] [ loops get at local-recursive-call ] }
[ ##epilogue ##jump stop-iterating ] [ ##epilogue ##jump stop-iterating ]
} cond ; } cond ;
@ -235,7 +235,7 @@ M: #dispatch emit-node
(write-barrier) (write-barrier)
} [ t "intrinsic" set-word-prop ] each } [ t "intrinsic" set-word-prop ] each
: allot-size ( #call -- n ) : allot-size ( -- n )
1 phantom-datastack get phantom-input first value>> ; 1 phantom-datastack get phantom-input first value>> ;
:: emit-allot ( size type tag -- ) :: emit-allot ( size type tag -- )
@ -306,21 +306,41 @@ M: #return-recursive emit-node
M: #terminate emit-node drop stop-iterating ; M: #terminate emit-node drop stop-iterating ;
! FFI ! FFI
: return-size ( ctype -- n )
#! Amount of space we reserve for a return value.
{
{ [ dup c-struct? not ] [ drop 0 ] }
{ [ dup large-struct? not ] [ drop 2 cells ] }
[ heap-size ]
} cond ;
: <alien-stack-frame> ( params -- stack-frame )
stack-frame new
swap
[ return>> return-size >>return ]
[ alien-parameters parameter-sizes drop >>params ] bi
dup [ params>> ] [ return>> ] bi + >>size ;
: alien-stack-frame ( node -- )
params>> <alien-stack-frame> ##stack-frame ;
: emit-alien-node ( node quot -- next )
[ drop alien-stack-frame ]
[ [ params>> ] dip call ] 2bi
iterate-next ; inline
M: #alien-invoke emit-node M: #alien-invoke emit-node
params>> [ ##alien-invoke ] emit-alien-node ;
[ alien-invoke-frame ##frame-required ]
[ ##alien-invoke iterate-next ]
bi ;
M: #alien-indirect emit-node M: #alien-indirect emit-node
params>> [ ##alien-indirect ] emit-alien-node ;
[ alien-invoke-frame ##frame-required ]
[ ##alien-indirect iterate-next ]
bi ;
M: #alien-callback emit-node M: #alien-callback emit-node
params>> dup xt>> dup params>> dup xt>> dup
[ init-phantoms ##alien-callback ] with-cfg-builder [
init-phantoms
[ ##alien-callback ] emit-alien-node drop
] with-cfg-builder
iterate-next ; iterate-next ;
! No-op nodes ! No-op nodes

View File

@ -19,7 +19,7 @@ successors ;
V{ } clone >>instructions V{ } clone >>instructions
V{ } clone >>successors ; V{ } clone >>successors ;
TUPLE: mr instructions word label frame-size spill-counts ; TUPLE: mr instructions word label ;
: <mr> ( instructions word label -- mr ) : <mr> ( instructions word label -- mr )
mr new mr new

View File

@ -17,12 +17,19 @@ INSN: ##replace src loc ;
INSN: ##inc-d n ; INSN: ##inc-d n ;
INSN: ##inc-r n ; INSN: ##inc-r n ;
! Calling convention
INSN: ##return ;
! Subroutine calls ! Subroutine calls
TUPLE: stack-frame
{ size integer }
{ params integer }
{ return integer }
{ total-size integer } ;
INSN: ##stack-frame stack-frame ;
: ##simple-stack-frame ( -- ) T{ stack-frame } ##stack-frame ;
INSN: ##call word ; INSN: ##call word ;
INSN: ##jump word ; INSN: ##jump word ;
INSN: ##return ;
INSN: ##intrinsic quot defs-vregs uses-vregs ; INSN: ##intrinsic quot defs-vregs uses-vregs ;
! Jump tables ! Jump tables
@ -87,7 +94,6 @@ M: ##intrinsic uses-vregs intrinsic-uses-vregs ;
! Instructions used by CFG IR only. ! Instructions used by CFG IR only.
INSN: ##prologue ; INSN: ##prologue ;
INSN: ##epilogue ; INSN: ##epilogue ;
INSN: ##frame-required n ;
INSN: ##branch ; INSN: ##branch ;
INSN: ##branch-f < ##cond-branch ; INSN: ##branch-f < ##cond-branch ;
@ -100,8 +106,8 @@ M: ##if-intrinsic defs-vregs intrinsic-defs-vregs ;
M: ##if-intrinsic uses-vregs intrinsic-uses-vregs ; M: ##if-intrinsic uses-vregs intrinsic-uses-vregs ;
! Instructions used by machine IR only. ! Instructions used by machine IR only.
INSN: _prologue ; INSN: _prologue stack-frame ;
INSN: _epilogue ; INSN: _epilogue stack-frame ;
INSN: _label id ; INSN: _label id ;

View File

@ -7,40 +7,47 @@ IN: compiler.cfg.stack-frame
SYMBOL: frame-required? SYMBOL: frame-required?
SYMBOL: frame-size
SYMBOL: spill-counts SYMBOL: spill-counts
: init-stack-frame-builder ( -- ) : init-stack-frame-builder ( -- )
frame-required? off frame-required? off
0 frame-size set ; T{ stack-frame } clone stack-frame set ;
GENERIC: compute-frame-size* ( insn -- ) GENERIC: compute-stack-frame* ( insn -- )
M: ##frame-required compute-frame-size* : max-stack-frame ( frame1 frame2 -- frame3 )
{
[ [ size>> ] bi@ max ]
[ [ params>> ] bi@ max ]
[ [ return>> ] bi@ max ]
[ [ total-size>> ] bi@ max ]
} cleave
stack-frame boa ;
M: ##stack-frame compute-stack-frame*
frame-required? on frame-required? on
n>> frame-size [ max ] change ; stack-frame>> stack-frame [ max-stack-frame ] change ;
M: _spill-integer compute-frame-size* M: _spill-integer compute-stack-frame*
drop frame-required? on ; drop frame-required? on ;
M: _spill-float compute-frame-size* M: _spill-float compute-stack-frame*
drop frame-required? on ; drop frame-required? on ;
M: insn compute-frame-size* drop ; M: insn compute-stack-frame* drop ;
: compute-frame-size ( insns -- ) : compute-stack-frame ( insns -- )
[ compute-frame-size* ] each ; [ compute-stack-frame* ] each ;
GENERIC: insert-pro/epilogues* ( insn -- ) GENERIC: insert-pro/epilogues* ( insn -- )
M: ##frame-required insert-pro/epilogues* drop ; M: ##stack-frame insert-pro/epilogues* drop ;
M: ##prologue insert-pro/epilogues* M: ##prologue insert-pro/epilogues*
drop frame-required? get [ _prologue ] when ; drop frame-required? get [ stack-frame get _prologue ] when ;
M: ##epilogue insert-pro/epilogues* M: ##epilogue insert-pro/epilogues*
drop frame-required? get [ _epilogue ] when ; drop frame-required? get [ stack-frame get _epilogue ] when ;
M: insn insert-pro/epilogues* , ; M: insn insert-pro/epilogues* , ;
@ -51,9 +58,8 @@ M: insn insert-pro/epilogues* , ;
[ [
init-stack-frame-builder init-stack-frame-builder
[ [
[ compute-frame-size ] [ compute-stack-frame ]
[ insert-pro/epilogues ] [ insert-pro/epilogues ]
bi bi
] change-instructions ] change-instructions
frame-size get >>frame-size
] with-scope ; ] with-scope ;

View File

@ -312,7 +312,7 @@ M: loc lazy-store
finalize-contents finalize-contents
finalize-heights finalize-heights
fresh-objects get [ fresh-objects get [
empty? [ 0 ##frame-required ##gc ] unless empty? [ ##simple-stack-frame ##gc ] unless
] [ delete-all ] bi ; ] [ delete-all ] bi ;
: init-phantoms ( -- ) : init-phantoms ( -- )

View File

@ -28,13 +28,10 @@ TUPLE: template input output scratch clobber gc ;
: lazy-load ( specs -- seq ) : lazy-load ( specs -- seq )
[ length phantom-datastack get phantom-input ] keep [ length phantom-datastack get phantom-input ] keep
[ drop ] [ [
[ 2dup second clobbered?
2dup second clobbered? [ first (eager-load) ] [ first (lazy-load) ] if
[ first (eager-load) ] [ first (lazy-load) ] if ] 2map ;
] 2map
] 2bi
[ substitute-vregs ] keep ;
: load-inputs ( template -- assoc ) : load-inputs ( template -- assoc )
[ [

View File

@ -10,7 +10,8 @@ compiler.backend
compiler.codegen.fixup compiler.codegen.fixup
compiler.cfg compiler.cfg
compiler.cfg.instructions compiler.cfg.instructions
compiler.cfg.registers ; compiler.cfg.registers
compiler.cfg.builder ;
IN: compiler.codegen IN: compiler.codegen
GENERIC: generate-insn ( insn -- ) GENERIC: generate-insn ( insn -- )
@ -71,10 +72,14 @@ M: _label generate-insn
id>> lookup-label , ; id>> lookup-label , ;
M: _prologue generate-insn M: _prologue generate-insn
drop %prologue ; stack-frame>>
[ stack-frame set ]
[ dup size>> stack-frame-size >>total-size drop ]
[ total-size>> %prologue ]
tri ;
M: _epilogue generate-insn M: _epilogue generate-insn
drop %epilogue ; stack-frame>> total-size>> %epilogue ;
M: ##load-literal generate-insn M: ##load-literal generate-insn
[ obj>> ] [ dst>> v>operand ] bi load-literal ; [ obj>> ] [ dst>> v>operand ] bi load-literal ;
@ -276,8 +281,8 @@ M: long-long-type flatten-value-type ( type -- types )
#! parameters. If the C function is returning a structure, #! parameters. If the C function is returning a structure,
#! the first parameter is an implicit target area pointer, #! the first parameter is an implicit target area pointer,
#! so we need to use a different offset. #! so we need to use a different offset.
return>> dup large-struct? return>> large-struct?
[ heap-size %prepare-box-struct cell ] [ drop 0 ] if ; [ %prepare-box-struct cell ] [ 0 ] if ;
: objects>registers ( params -- ) : objects>registers ( params -- )
#! Generate code for unboxing a list of C types, then #! Generate code for unboxing a list of C types, then
@ -413,7 +418,7 @@ TUPLE: callback-context ;
: callback-unwind ( params -- n ) : callback-unwind ( params -- n )
{ {
{ [ dup abi>> "stdcall" = ] [ alien-stack-frame ] } { [ dup abi>> "stdcall" = ] [ <alien-stack-frame> size>> ] }
{ [ dup return>> large-struct? ] [ drop 4 ] } { [ dup return>> large-struct? ] [ drop 4 ] }
[ drop 0 ] [ drop 0 ]
} cond ; } cond ;