diff --git a/TODO.FACTOR.txt b/TODO.FACTOR.txt index 3ca88c2bcf..a15d844c13 100644 --- a/TODO.FACTOR.txt +++ b/TODO.FACTOR.txt @@ -1,3 +1,5 @@ +- remove t object and type + + ui: - fix up the min thumb size hack @@ -48,10 +50,8 @@ + compiler: +- declare slot types for built-ins - remove dead code after a 'throw' -- when doing comparison with one arg being a float, inline method -- investigate overzealous math inlining -- shuffles: eliminate dead loads - floating point intrinsics - flushing optimization - fix fixnum/mod overflow on PowerPC @@ -78,7 +78,6 @@ - specialized arrays - there is a problem with hashcodes of words and bootstrapping - delegating generic words with a non-standard picker -- powerpc has weird callstack residue - instances: do not use make-list - vectors: ensure its ok with bignum indices - code gc @@ -91,8 +90,6 @@ - investigate if rehashing on startup is really necessary - vectorize >n, n>, (get) - mutable strings simplifying string operarations -- 2each, find*, subset are ugly -- map and 2map duplicate logic + i/o: diff --git a/library/alien/compiler.factor b/library/alien/compiler.factor index 6be67f90a5..0e824ec550 100644 --- a/library/alien/compiler.factor +++ b/library/alien/compiler.factor @@ -116,19 +116,19 @@ C: alien-node make-node ; dup stack-space %parameters , dup unbox-parameters load-parameters ; -: linearize-return ( return -- ) +: linearize-return ( node -- ) alien-node-return dup "void" = [ drop ] [ c-type [ "boxer" get "reg-class" get ] bind %box , ] ifte ; -M: alien-node linearize-node* ( node -- ) +M: alien-node linearize* ( node -- ) dup parameters linearize-parameters dup node-param dup uncons %alien-invoke , cdr library-abi "stdcall" = [ dup parameters stack-space %cleanup , ] unless - linearize-return ; + dup linearize-return linearize-next ; : unpair ( seq -- odds evens ) 2 swap group flip dup empty? diff --git a/library/bootstrap/boot-stage1.factor b/library/bootstrap/boot-stage1.factor index 36823d8fc0..87b0f8e3c9 100644 --- a/library/bootstrap/boot-stage1.factor +++ b/library/bootstrap/boot-stage1.factor @@ -138,7 +138,7 @@ sequences io vectors words ; "/library/compiler/linearizer.factor" "/library/compiler/stack.factor" "/library/compiler/intrinsics.factor" - "/library/compiler/simplifier.factor" + "/library/compiler/basic-blocks.factor" "/library/compiler/generator.factor" "/library/compiler/compiler.factor" diff --git a/library/collections/lists.factor b/library/collections/lists.factor index 9ebeedf077..1903a3dde4 100644 --- a/library/collections/lists.factor +++ b/library/collections/lists.factor @@ -9,6 +9,8 @@ M: cons length cdr length 1 + ; M: f empty? drop t ; M: cons empty? drop f ; +M: f peek ( f -- f ) ; + M: cons peek ( list -- last ) #! Last element of a list. last car ; diff --git a/library/collections/namespaces.factor b/library/collections/namespaces.factor index 78a875244a..2ddf0bf6be 100644 --- a/library/collections/namespaces.factor +++ b/library/collections/namespaces.factor @@ -102,6 +102,8 @@ SYMBOL: building #! Add to the sequence being built with make-seq. building get push ; +: ?, ( obj ? -- ) [ , ] [ drop ] ifte ; + : % ( seq -- ) #! Append to the sequence being built with make-seq. building get swap nappend ; diff --git a/library/collections/slicing.factor b/library/collections/slicing.factor index 40fdc337af..4607eb3303 100644 --- a/library/collections/slicing.factor +++ b/library/collections/slicing.factor @@ -92,4 +92,6 @@ M: object tail ( index seq -- seq ) [ tail-slice ] keep like ; : split ( seq subseq -- seq ) [ (split) ] [ ] make ; flushable -: cut ( n seq -- ) [ head ] 2keep tail ; flushable +: (cut) ( n seq -- ) [ head ] 2keep tail-slice ; flushable + +: cut ( n seq -- ) [ (cut) ] keep like ; flushable diff --git a/library/compiler/basic-blocks.factor b/library/compiler/basic-blocks.factor new file mode 100644 index 0000000000..9c7c134e01 --- /dev/null +++ b/library/compiler/basic-blocks.factor @@ -0,0 +1,129 @@ +IN: compiler-backend +USING: kernel math namespaces sequences vectors ; + +: (split-blocks) ( n linear -- ) + 2dup length = [ + dup like , drop + ] [ + 2dup nth basic-block? [ + >r 1 + r> (split-blocks) + ] [ + (cut) >r , 1 r> (cut) >r , 0 r> (split-blocks) + ] ifte + ] ifte ; + +: split-blocks ( linear -- blocks ) + [ 0 swap (split-blocks) ] { } make ; + +SYMBOL: d-height +SYMBOL: r-height + +! combining %inc-d/%inc-r +GENERIC: simplify-stack* ( vop -- ) + +M: tuple simplify-stack* ( vop -- ) drop ; + +: accum-height ( vop var -- ) + >r dup 0 vop-in r> [ + ] change 0 swap 0 set-vop-in ; + +M: %inc-d simplify-stack* ( vop -- ) d-height accum-height ; + +M: %inc-r simplify-stack* ( vop -- ) r-height accum-height ; + +: update-ds ( vop -- ) + dup ds-loc-n d-height get - swap set-ds-loc-n ; + +: update-cs ( vop -- ) + dup cs-loc-n r-height get - swap set-cs-loc-n ; + +M: %peek-d simplify-stack* ( vop -- ) 0 vop-in update-ds ; + +M: %peek-r simplify-stack* ( vop -- ) 0 vop-in update-cs ; + +M: %replace-d simplify-stack* ( vop -- ) 0 vop-out update-ds ; + +M: %replace-r simplify-stack* ( vop -- ) 0 vop-out update-cs ; + +: simplify-stack ( block -- ) + #! Combine all %inc-d/%inc-r into two final ones. + #! Destructively modifies the VOPs in the block. + [ simplify-stack* ] each ; + +: each-tail ( seq quot -- | quot: tail -- ) + >r dup length [ swap tail-slice ] map-with r> each ; inline + +! removing dead loads/stores +: preserves-location? ( exitcc location vop -- ? ) + #! If the VOP writes the register, call the loop exit + #! continuation with 'f'. + { + { [ 2dup vop-inputs member? ] [ 3drop t ] } + { [ 2dup vop-outputs member? ] [ 2drop f swap call ] } + { [ t ] [ 3drop f ] } + } cond ; + +GENERIC: live@end? ( location -- ? ) + +M: tuple live@end? drop t ; + +M: ds-loc live@end? ds-loc-n d-height get + 0 >= ; + +M: cs-loc live@end? cs-loc-n r-height get + 0 >= ; + +: location-live? ( location tail -- ? ) + #! A location is not live if and only if it is overwritten + #! before the end of the basic block. + [ + -rot [ >r 2dup r> preserves-location? ] contains? + [ dup live@end? ] unless* + ] callcc1 2nip ; + +! Set if trim-dead* removed some VOPs. +GENERIC: trim-dead* ( tail vop -- ) + +M: tuple trim-dead* ( tail vop -- ) , drop ; + +: simplify-inc ( vop -- ) dup 0 vop-in 0 = not ?, ; + +M: %inc-d trim-dead* ( tail vop -- ) simplify-inc drop ; + +M: %inc-r trim-dead* ( tail vop -- ) simplify-inc drop ; + +: ?dead-load ( tail vop -- ) + #! If the VOP's output location is overwritten before being + #! read again, kill the VOP. + dup 0 vop-out rot location-live? ?, ; + +M: %peek-d trim-dead* ( tail vop -- ) ?dead-load ; + +M: %peek-r trim-dead* ( tail vop -- ) ?dead-load ; + +M: %replace-d trim-dead* ( tail vop -- ) ?dead-load ; + +M: %replace-r trim-dead* ( tail vop -- ) ?dead-load ; + +M: %immediate trim-dead* ( tail vop -- ) ?dead-load ; + +M: %indirect trim-dead* ( tail vop -- ) ?dead-load ; + +: trim-dead ( block -- ) + #! Remove dead loads and stores. + [ dup first >r 1 swap tail-slice r> trim-dead* ] each-tail ; + +: simplify-block ( block -- block ) + #! Destructively modifies the VOPs in the block. + [ + 0 d-height set + 0 r-height set + dup simplify-stack + d-height get %inc-d r-height get %inc-r 2vector append + trim-dead + ] { } make ; + +: keep-simplifying ( block -- block ) + dup length >r simplify-block dup length r> + = [ keep-simplifying ] unless ; + +: simplify ( blocks -- blocks ) + #! Simplify basic block IR. + [ keep-simplifying ] map ; diff --git a/library/compiler/compiler.factor b/library/compiler/compiler.factor index 45c927fd93..12d1056746 100644 --- a/library/compiler/compiler.factor +++ b/library/compiler/compiler.factor @@ -6,20 +6,12 @@ kernel lists math namespaces prettyprint sequences words ; : supported-cpu? ( -- ? ) cpu "unknown" = not ; -GENERIC: (compile) ( word -- ) +: precompile ( quotation -- basic-blocks ) + dataflow optimize linearize split-blocks simplify ; -M: word (compile) drop ; - -M: compound (compile) ( word -- ) +: (compile) ( word -- ) #! Should be called inside the with-compiler scope. - "Compiling " write dup . - dup word-def dataflow optimize linearize simplify generate ; - -: precompile ( word -- ) - #! Print linear IR of word. - [ - word-def dataflow optimize linearize simplify [ . ] each - ] with-scope ; + "Compiling " write dup . dup word-def precompile generate ; : compile-postponed ( -- ) compile-words get [ @@ -38,8 +30,7 @@ M: compound (compile) ( word -- ) : compile-all ( -- ) [ try-compile ] each-word ; -: recompile ( word -- ) - dup update-xt compile ; +: recompile ( word -- ) dup update-xt compile ; : compile-1 ( quot -- ) #! Compute and call a quotation. diff --git a/library/compiler/generator.factor b/library/compiler/generator.factor index f4a1ebb035..51c39bb690 100644 --- a/library/compiler/generator.factor +++ b/library/compiler/generator.factor @@ -64,7 +64,7 @@ M: integer v>operand tag-bits shift ; M: f v>operand address ; : dest/src ( vop -- dest src ) - dup vop-out-1 v>operand swap vop-in-1 v>operand ; + dup 0 vop-out v>operand swap 0 vop-in v>operand ; ! These constants must match native/card.h : card-bits 7 ; diff --git a/library/compiler/intrinsics.factor b/library/compiler/intrinsics.factor index 14028a952c..1b66ea595a 100644 --- a/library/compiler/intrinsics.factor +++ b/library/compiler/intrinsics.factor @@ -31,13 +31,13 @@ sequences vectors words ; \ slot [ dup slot@ [ - -1 %inc-d, + -1 %inc-d , in-1 0 swap slot@ %fast-slot , ] [ drop in-2 - -1 %inc-d, + -1 %inc-d , 0 %untag , 1 0 %slot , ] ifte out-1 @@ -45,14 +45,14 @@ sequences vectors words ; \ set-slot [ dup slot@ [ - -1 %inc-d, + -1 %inc-d , in-2 - -2 %inc-d, + -2 %inc-d , slot@ >r 0 1 r> %fast-set-slot , ] [ drop in-3 - -3 %inc-d, + -3 %inc-d , 1 %untag , 0 1 2 %set-slot , ] ifte @@ -76,17 +76,17 @@ sequences vectors words ; ] "intrinsic" set-word-prop \ getenv [ - -1 %inc-d, + -1 %inc-d , node-peek literal-value 0 swap %getenv , - 1 %inc-d, + 1 %inc-d , out-1 ] "intrinsic" set-word-prop \ setenv [ - -1 %inc-d, + -1 %inc-d , in-1 node-peek literal-value 0 swap %setenv , - -1 %inc-d, + -1 %inc-d , ] "intrinsic" set-word-prop : value/vreg-list ( in -- list ) @@ -100,7 +100,7 @@ sequences vectors words ; : load-inputs ( node -- in ) dup node-in-d values>vregs - [ >r node-out-d length r> length - %inc-d, ] keep ; + [ >r node-out-d length r> length - %inc-d , ] keep ; : binary-op-reg ( node op -- ) >r load-inputs first2 swap dup r> execute , @@ -110,7 +110,7 @@ sequences vectors words ; dup literal? [ literal-value immediate? ] [ drop f ] ifte ; : binary-op-imm ( imm op -- ) - -1 %inc-d, in-1 + -1 %inc-d , in-1 >r 0 dup r> execute , 0 0 %replace-d , ; inline @@ -143,7 +143,7 @@ sequences vectors words ; ] each : fast-fixnum* ( n -- ) - -1 %inc-d, + -1 %inc-d , in-1 log2 0 0 %fixnum<< , 0 0 %replace-d , ; @@ -169,7 +169,7 @@ sequences vectors words ; ! be EDX there. drop in-2 - -1 %inc-d, + -1 %inc-d , 1 0 2 %fixnum-mod , 2 0 %replace-d , ] "intrinsic" set-word-prop @@ -201,7 +201,7 @@ sequences vectors words ; : slow-shift ( -- ) \ fixnum-shift %call , ; : negative-shift ( n -- ) - -1 %inc-d, + -1 %inc-d , in-1 dup cell -8 * <= [ drop 0 2 %fixnum-sgn , @@ -213,7 +213,7 @@ sequences vectors words ; : positive-shift ( n -- ) dup cell 8 * tag-bits - <= [ - -1 %inc-d, + -1 %inc-d , in-1 0 0 %fixnum<< , out-1 @@ -223,7 +223,7 @@ sequences vectors words ; : fast-shift ( n -- ) dup 0 = [ - -1 %inc-d, + -1 %inc-d , drop ] [ dup 0 < [ diff --git a/library/compiler/linearizer.factor b/library/compiler/linearizer.factor index 867447f6b0..845080b4be 100644 --- a/library/compiler/linearizer.factor +++ b/library/compiler/linearizer.factor @@ -5,82 +5,72 @@ USING: compiler-backend errors generic lists inference kernel math namespaces prettyprint sequences strings words ; -GENERIC: linearize-node* ( node -- ) - -M: f linearize-node* ( f -- ) drop ; - -M: node linearize-node* ( node -- ) drop ; - -: linearize-node ( node -- ) - [ - dup linearize-node* node-successor linearize-node - ] when* ; +GENERIC: linearize* ( node -- ) : linearize ( dataflow -- linear ) #! Transform dataflow IR into linear IR. This strips out #! stack flow information, and flattens conditionals into #! jumps and labels. - [ %prologue , linearize-node ] [ ] make ; + [ %prologue , linearize* ] { } make ; -M: #label linearize-node* ( node -- ) +: linearize-next node-successor linearize* ; + +M: f linearize* ( f -- ) drop ; + +M: node linearize* ( node -- ) linearize-next ; + +M: #label linearize* ( node -- )