reworking simplifier and basic blocks

cvs
Slava Pestov 2005-09-09 02:23:54 +00:00
parent b3003e4759
commit 55e2a9e232
33 changed files with 351 additions and 467 deletions

View File

@ -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:

View File

@ -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?

View File

@ -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"

View File

@ -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 ;

View File

@ -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 ;

View File

@ -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

View File

@ -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 ;

View File

@ -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.

View File

@ -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 ;

View File

@ -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 <vreg> 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 <vreg> 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 <vreg> 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 <vreg> 0 <vreg> %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 <vreg> 0 <vreg> 2 <vreg> %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 <vreg> 2 <vreg> %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 <vreg> 0 <vreg> %fixnum<< ,
out-1
@ -223,7 +223,7 @@ sequences vectors words ;
: fast-shift ( n -- )
dup 0 = [
-1 %inc-d,
-1 %inc-d ,
drop
] [
dup 0 < [

View File

@ -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 -- )
<label> dup %return-to , >r
dup node-param %label ,
node-child linearize-node
r> %label , ;
dup node-child linearize*
r> %label ,
linearize-next ;
M: #call linearize-node* ( node -- )
dup node-param
dup "intrinsic" word-prop [ call ] [ %call , drop ] ?ifte ;
: ?tail-call ( node caller jumper -- next )
>r >r dup node-successor #return? [
node-param r> drop r> execute ,
] [
dup node-param r> execute , r> drop linearize-next
] ifte ; inline
M: #call-label linearize-node* ( node -- )
node-param %call-label , ;
: intrinsic ( #call -- quot ) node-param "intrinsic" word-prop ;
: immediate? ( obj -- ? )
#! fixnums and f have a pointerless representation, and
#! are compiled immediately. Everything else can be moved
#! by GC, and is indexed through a table.
dup fixnum? swap f eq? or ;
M: #call linearize* ( node -- )
dup intrinsic [
dupd call linearize-next
] [
\ %call \ %jump ?tail-call
] ifte* ;
GENERIC: load-value ( vreg n value -- )
M: #call-label linearize* ( node -- )
\ %call-label \ %jump-label ?tail-call ;
M: object load-value ( vreg n value -- )
drop %peek-d , ;
: ifte-head ( label -- ) in-1 -1 %inc-d , 0 %jump-t , ;
: push-literal ( vreg value -- )
literal-value dup
immediate? [ %immediate ] [ %indirect ] ifte , ;
M: literal load-value ( vreg n value -- )
nip push-literal ;
: ifte-head ( label -- )
in-1 -1 %inc-d, 0 %jump-t , ;
M: #ifte linearize-node* ( node -- )
M: #ifte linearize* ( node -- )
node-children first2
<label> dup ifte-head
swap linearize-node ( false branch )
swap linearize* ( false branch )
%label , ( branch target of BRANCH-T )
linearize-node ( true branch ) ;
linearize* ( true branch ) ;
: dispatch-head ( vtable -- label/code )
#! Output the jump table insn and return a list of
#! label/branch pairs.
in-1
-1 %inc-d,
-1 %inc-d ,
0 %untag-fixnum ,
0 %dispatch ,
[ <label> dup %target-label , cons ] map
%end-dispatch , ;
: dispatch-body ( label/param -- )
#! Output each branch, with a jump to the end label.
[ uncons %label , linearize-node ] each ;
[ uncons %label , linearize* ] each ;
M: #dispatch linearize-node* ( vtable -- )
#! The parameter is a list of lists, each one is a branch to
M: #dispatch linearize* ( vtable -- )
#! The parameter is a list of nodes, each one is a branch to
#! take in case the top of stack has that type.
node-children dispatch-head dispatch-body ;
M: #return linearize-node* ( node -- )
drop f %return , ;
M: #return linearize* ( node -- )
drop f %return , ;

View File

@ -4,13 +4,13 @@ IN: compiler-backend
USING: alien assembler kernel math ;
M: %alien-invoke generate-node ( vop -- )
dup vop-in-1 swap vop-in-2 load-library compile-c-call ;
dup 0 vop-in swap 1 vop-in load-library compile-c-call ;
: stack-reserve 8 + 16 align ;
: stack@ 12 + ;
M: %parameters generate-node ( vop -- )
vop-in-1 dup 0 =
0 vop-in dup 0 =
[ drop ] [ stack-reserve 1 1 rot SUBI ] ifte ;
GENERIC: store-insn
@ -28,19 +28,19 @@ M: float-regs load-insn
>r 1 + 1 rot r> float-regs-size 4 = [ LFS ] [ LFD ] ifte ;
M: %unbox generate-node ( vop -- )
[ vop-in-2 f compile-c-call ] keep
[ vop-in-3 return-reg 1 ] keep
[ vop-in-1 stack@ ] keep
vop-in-3 store-insn ;
[ 1 vop-in f compile-c-call ] keep
[ 2 vop-in return-reg 1 ] keep
[ 0 vop-in stack@ ] keep
2 vop-in store-insn ;
M: %parameter generate-node ( vop -- )
dup vop-in-1 stack@
over vop-in-2
rot vop-in-3 load-insn ;
dup 0 vop-in stack@
over 1 vop-in
rot 2 vop-in load-insn ;
M: %box generate-node ( vop -- )
vop-in-1 f compile-c-call ;
0 vop-in f compile-c-call ;
M: %cleanup generate-node ( vop -- )
vop-in-1 dup 0 =
0 vop-in dup 0 =
[ drop ] [ stack-reserve 1 1 rot ADDI ] ifte ;

View File

@ -5,9 +5,9 @@ USING: assembler compiler kernel math math-internals memory
namespaces words ;
: >3-imm< ( vop -- out1 in2 in1 )
[ vop-out-1 v>operand ] keep
[ vop-in-2 v>operand ] keep
vop-in-1 ;
[ 0 vop-out v>operand ] keep
[ 1 vop-in v>operand ] keep
0 vop-in ;
: >3-vop< ( vop -- out1 in1 in2 )
>3-imm< v>operand swap ;
@ -24,7 +24,7 @@ namespaces words ;
drop
"s48_long_to_bignum" f compile-c-call
! An untagged pointer to the bignum is now in r3; tag it
3 swap vop-out-1 v>operand bignum-tag ORI
3 swap 0 vop-out v>operand bignum-tag ORI
"end" get save-xt ; inline
M: %fixnum+ generate-node ( vop -- )
@ -114,7 +114,7 @@ M: %fixnum<< generate-node ( vop -- )
! This has specific register requirements.
<label> "no-overflow" set
<label> "end" set
vop-in-1
0 vop-in
! check for potential overflow
dup shift-add dup 5 LOAD
4 3 5 ADD
@ -142,7 +142,7 @@ M: %fixnum-sgn generate-node ( vop -- )
dest/src dupd 31 SRAWI dup untag ;
: compare ( vop -- )
dup vop-in-2 v>operand swap vop-in-1 dup integer? [
dup 1 vop-in v>operand swap 0 vop-in dup integer? [
0 -rot address CMPI
] [
0 swap v>operand CMP
@ -161,7 +161,7 @@ M: %fixnum-sgn generate-node ( vop -- )
"end" get save-xt ; inline
: fixnum-pred ( vop word -- dest )
>r [ compare ] keep vop-out-1 v>operand r> load-boolean ;
>r [ compare ] keep 0 vop-out v>operand r> load-boolean ;
inline
M: %fixnum< generate-node ( vop -- ) \ BLT fixnum-pred ;

View File

@ -53,7 +53,7 @@ M: %jump-label generate-node ( vop -- )
vop-label B ;
: conditional ( vop -- label )
dup vop-in-1 v>operand 0 swap f address CMPI vop-label ;
dup 0 vop-in v>operand 0 swap f address CMPI vop-label ;
M: %jump-f generate-node ( vop -- )
conditional BEQ ;
@ -119,4 +119,4 @@ M: %type generate-node ( vop -- )
3 4 MR ;
M: %tag generate-node ( vop -- )
dup vop-in-1 v>operand swap vop-out-1 v>operand tag-mask ANDI ;
dup 0 vop-in v>operand swap 0 vop-out v>operand tag-mask ANDI ;

View File

@ -8,32 +8,32 @@ M: %slot generate-node ( vop -- )
dest/src
! turn tagged fixnum slot # into an offset, multiple of 4
dup dup 1 SRAWI
! compute slot address in vop-out-1
! compute slot address in 0 vop-out
>r dup dup r> ADD
! load slot value in vop-out-1
! load slot value in 0 vop-out
dup 0 LWZ ;
M: %fast-slot generate-node ( vop -- )
dup vop-out-1 v>operand dup rot vop-in-1 LWZ ;
dup 0 vop-out v>operand dup rot 0 vop-in LWZ ;
M: %set-slot generate-node ( vop -- )
dup vop-in-3 v>operand over vop-in-2 v>operand
dup 2 vop-in v>operand over 1 vop-in v>operand
! turn tagged fixnum slot # into an offset, multiple of 4
over dup 1 SRAWI
! compute slot address in vop-in-2
! compute slot address in 1 vop-in
over dup rot ADD
! store new slot value
>r vop-in-1 v>operand r> 0 STW ;
>r 0 vop-in v>operand r> 0 STW ;
M: %fast-set-slot generate-node ( vop -- )
[ vop-in-1 v>operand ] keep
[ vop-in-2 v>operand ] keep
vop-in-3 STW ;
[ 0 vop-in v>operand ] keep
[ 1 vop-in v>operand ] keep
2 vop-in STW ;
M: %write-barrier generate-node ( vop -- )
#! Mark the card pointed to by vreg.
#! Uses r6 for storage.
vop-in-1 v>operand
0 vop-in v>operand
dup dup card-bits SRAWI
dup dup 16 ADD
6 over 0 LBZ
@ -45,10 +45,10 @@ M: %write-barrier generate-node ( vop -- )
"userenv" f dlsym swap LOAD32 0 1 rel-userenv ;
M: %getenv generate-node ( vop -- )
dup vop-out-1 v>operand dup userenv
dup rot vop-in-1 cell * LWZ ;
dup 0 vop-out v>operand dup userenv
dup rot 0 vop-in cell * LWZ ;
M: %setenv generate-node ( vop -- )
! bad! need to formalize scratch register usage
4 <vreg> v>operand dup userenv >r
dup vop-in-1 v>operand r> rot vop-in-2 cell * STW ;
dup 0 vop-in v>operand r> rot 1 vop-in cell * STW ;

View File

@ -7,28 +7,28 @@ USING: assembler compiler errors kernel math memory words ;
: cs-op cell * neg 15 swap ;
M: %immediate generate-node ( vop -- )
dup vop-in-1 address swap vop-out-1 v>operand LOAD ;
dup 0 vop-in address swap 0 vop-out v>operand LOAD ;
: load-indirect ( dest literal -- )
intern-literal over LOAD dup 0 LWZ ;
M: %indirect generate-node ( vop -- )
dup vop-out-1 v>operand swap vop-in-1 load-indirect ;
dup 0 vop-out v>operand swap 0 vop-in load-indirect ;
M: %peek-d generate-node ( vop -- )
dup vop-out-1 v>operand swap vop-in-1 ds-op LWZ ;
dup 0 vop-out v>operand swap 0 vop-in ds-op LWZ ;
M: %replace-d generate-node ( vop -- )
dup vop-in-2 v>operand swap vop-in-1 ds-op STW ;
dup 1 vop-in v>operand swap 0 vop-in ds-op STW ;
M: %inc-d generate-node ( vop -- )
14 14 rot vop-in-1 cell * ADDI ;
14 14 rot 0 vop-in cell * ADDI ;
M: %inc-r generate-node ( vop -- )
15 15 rot vop-in-1 cell * ADDI ;
15 15 rot 0 vop-in cell * ADDI ;
M: %peek-r generate-node ( vop -- )
dup vop-out-1 v>operand swap vop-in-1 cs-op LWZ ;
dup 0 vop-out v>operand swap 0 vop-in cs-op LWZ ;
M: %replace-r generate-node ( vop -- )
dup vop-in-2 v>operand swap vop-in-1 cs-op STW ;
dup 1 vop-in v>operand swap 0 vop-in cs-op STW ;

View File

@ -1,261 +0,0 @@
! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
IN: compiler-backend
USING: generic kernel lists math namespaces
prettyprint sequences strings words ;
! A peephole optimizer operating on the linear IR.
! The linear IR being simplified is stored in this variable.
SYMBOL: simplifying
GENERIC: simplify-node ( linear vop -- linear ? )
! The next node following this node in terms of control flow, or
! f if this is a conditional.
GENERIC: next-logical ( linear vop -- linear )
! No delegation.
M: tuple simplify-node drop f ;
: simplify-1 ( list -- list ? )
#! Return a new linear IR.
dup [
dup car simplify-node
[ uncons simplify-1 drop cons t ]
[ uncons simplify-1 >r cons r> ] ifte
] [
f
] ifte ;
: simplify ( linear -- linear )
#! Keep simplifying until simplify-1 returns f.
[
dup simplifying set simplify-1
] with-scope [ simplify ] when ;
: label-called? ( label -- ? )
simplifying get [ calls-label? ] contains-with? ;
M: %label simplify-node ( linear vop -- linear ? )
vop-label label-called? [ f ] [ cdr t ] ifte ;
: next-physical? ( linear class -- vop ? )
#! If the following op has given class, remove it and
#! return it.
over cdr dup [
car class = [ second t ] [ f ] ifte
] [
3drop f f
] ifte ;
M: %inc-d simplify-node ( linear vop -- linear ? )
#! %inc-d cancels a following %inc-d.
dup vop-in-1 0 = [
drop cdr t
] [
>r dup \ %inc-d next-physical? [
vop-in-1 r> vop-in-1 +
%inc-d >r cdr cdr r> swons t
] [
r> 2drop f
] ifte
] ifte ;
: operands= ( vop vop -- ? )
over vop-inputs over vop-inputs =
>r swap vop-outputs swap vop-outputs = r> and ;
: cancel ( linear class -- linear ? )
dupd next-physical?
[ over first operands= [ cdr cdr t ] [ f ] ifte ]
[ drop f ] ifte ;
M: %retag-fixnum simplify-node ( linear vop -- linear ? )
drop \ %untag-fixnum cancel ;
: basic-block ( linear quot -- | quot: vop -- ? )
#! Keep applying the quotation to each VOP until either a
#! VOP answering f to basic-block?, or the quotation answers
#! f.
over car basic-block? [
>r uncons r> tuck >r >r call [
r> r> basic-block
] [
r> r> 2drop
] ifte
] [
2drop
] ifte ; inline
: reads-vreg? ( vreg linear -- ? )
#! Tests if the vreg is read before being written in the
#! current basic block. Outputs a true value if the vreg
#! is not read or written before the end of the basic block.
[
2dup vop-inputs member? [
! we are reading the vreg
2drop t f
] [
2dup vop-outputs member? [
! we are writing the vreg
2drop f f
] [
! keep checking
drop t
] ifte
] ifte
] basic-block ;
: dead-load ( vreg linear -- linear ? )
#! If the vreg is not read before being written, drop
#! the current VOP.
tuck cdr reads-vreg? [ f ] [ cdr t ] ifte ;
M: %peek-d simplify-node ( linear vop -- linear ? )
vop-out-1 swap dead-load ;
M: %immediate simplify-node ( linear vop -- linear ? )
vop-out-1 swap dead-load ;
M: %indirect simplify-node ( linear vop -- linear ? )
vop-out-1 swap dead-load ;
: dead-peek? ( linear vop -- ? )
#! Is the %replace-d followed by a %peek-d of the same
#! stack slot and vreg?
swap second dup %peek-d? [
over vop-in-2 over vop-out-1 = >r
swap vop-in-1 swap vop-in-1 = r> and
] [
2drop f
] ifte ;
: dead-replace? ( linear n -- ? )
#! Is the %replace-d followed by a %dec-d, so the stored
#! value is lost?
swap \ %inc-d next-physical? [
vop-in-1 + 0 <
] [
2drop f
] ifte ;
M: %replace-d simplify-node ( linear vop -- linear ? )
2dup dead-peek? [
drop uncons cdr cons t
] [
dupd vop-in-1 dead-replace? [ cdr t ] [ f ] ifte
] ifte ;
: pop? ( vop -- ? ) dup %inc-d? swap vop-in-1 -1 = and ;
: can-fast-branch? ( linear -- ? )
unswons class fast-branch [
unswons pop? [ car %jump-t? ] [ drop f ] ifte
] [
drop f
] ifte ;
: fast-branch-params ( linear -- src dest label linear )
uncons >r dup vop-in-1 swap vop-out-1 r> cdr
uncons >r vop-label r> ;
: make-fast-branch ( linear op -- linear ? )
>r dup can-fast-branch? [
fast-branch-params r> swap >r
execute >r -1 %inc-d r>
r> cons cons t
] [
r> drop f
] ifte ;
M: fast-branch simplify-node ( linear vop -- linear ? )
class fast-branch make-fast-branch ;
: ?label ( symbol linear -- ? )
car dup %label? [ vop-label = ] [ 2drop f ] ifte ;
: (find-label) ( label linear -- linear )
dup
[ 2dup ?label [ nip ] [ cdr (find-label) ] ifte ]
[ 2drop f ] ifte ;
: find-label ( label -- rest )
simplifying get (find-label) ;
M: %label next-logical ( linear vop -- linear )
drop cdr dup car next-logical ;
M: %jump-label next-logical ( linear vop -- linear )
nip vop-label find-label cdr ;
M: %target-label next-logical ( linear vop -- linear )
nip vop-label find-label cdr ;
M: object next-logical ( linear vop -- linear )
drop ;
: next-logical? ( op linear -- ? )
dup car next-logical dup [ car class = ] [ 2drop f ] ifte ;
: collapse ( linear op new -- linear ? )
>r over cdr next-logical? [
dup car vop-label
r> execute swap cdr cons t
] [
r> drop f
] ifte ; inline
M: %call simplify-node ( linear vop -- ? )
#! Tail call optimization.
drop \ %return \ %jump collapse ;
M: %call-label simplify-node ( linear vop -- ? )
#! Tail call optimization.
drop \ %return \ %jump-label collapse ;
: double-jump ( linear op2 op1 -- linear ? )
#! A jump to a jump is just a jump. If the next logical node
#! is a jump of type op1, replace the jump at the car of the
#! list with a jump of type op2.
pick next-logical? [
>r dup dup car next-logical car vop-label
r> execute swap cdr cons t
] [ drop f ] ifte ; inline
: useless-jump ( linear -- linear ? )
#! A jump to a label immediately following is not needed.
dup car vop-label find-label find-label
over cdr eq? [ cdr t ] [ f ] ifte ;
: (dead-code) ( linear -- linear ? )
#! Remove all nodes until the next #label.
dup [
dup car %label?
[ f ] [ cdr (dead-code) t or ] ifte
] [ f ] ifte ;
: dead-code ( linear -- linear ? )
uncons (dead-code) >r cons r> ;
M: %jump-label simplify-node ( linear vop -- linear ? )
drop {
{ [ \ %return dup double-jump ] [ t ] }
{ [ \ %jump-label dup double-jump ] [ t ] }
{ [ \ %jump dup double-jump ] [ t ] }
{ [ useless-jump ] [ t ] }
{ [ t ] [ dead-code ] }
} cond ;
M: %target-label simplify-node ( linear vop -- linear ? )
drop
\ %target-label \ %jump-label double-jump ;
M: %jump simplify-node ( linear vop -- linear ? )
drop dead-code ;
M: %return simplify-node ( linear vop -- linear ? )
drop dead-code ;
M: %end-dispatch simplify-node ( linear vop -- linear ? )
drop dead-code ;

View File

@ -18,6 +18,9 @@ parser sequences vectors words ;
: label? ( obj -- ? )
dup word? [ "label" word-prop ] [ drop f ] ifte ;
! A location is a virtual register or a stack slot. We can
! ask a VOP if it reads or writes a location.
! A virtual register
TUPLE: vreg n ;
@ -25,22 +28,24 @@ TUPLE: vreg n ;
TUPLE: int-regs ;
TUPLE: float-regs size ;
! A data stack location.
TUPLE: ds-loc n ;
! A call stack location.
TUPLE: cs-loc n ;
! A virtual operation
TUPLE: vop inputs outputs label ;
: vop-in-1 ( vop -- input ) vop-inputs first ;
: vop-in-2 ( vop -- input ) vop-inputs second ;
: vop-in-3 ( vop -- input ) vop-inputs third ;
: vop-out-1 ( vop -- output ) vop-outputs first ;
: vop-out-2 ( vop -- output ) vop-outputs second ;
: vop-in ( vop n -- input ) swap vop-inputs nth ;
: set-vop-in ( input vop n -- ) swap vop-inputs set-nth ;
: vop-out ( vop n -- input ) swap vop-outputs nth ;
: set-vop-out ( input vop n -- ) swap vop-outputs set-nth ;
GENERIC: basic-block? ( vop -- ? )
M: vop basic-block? drop f ;
! simplifies some code
M: f basic-block? drop f ;
GENERIC: calls-label? ( label vop -- ? )
M: vop calls-label? vop-label = ;
: make-vop ( inputs outputs label vop -- vop )
[ >r <vop> r> set-delegate ] keep ;
@ -64,7 +69,6 @@ C: %prologue make-vop ;
TUPLE: %label ;
C: %label make-vop ;
: %label label-vop <%label> ;
M: %label calls-label? 2drop f ;
! Return vops take a label that is ignored, to have the
! same stack effect as jumps. This is needed for the
@ -121,41 +125,57 @@ C: %end-dispatch make-vop ;
! stack operations
TUPLE: %peek-d ;
C: %peek-d make-vop ;
: %peek-d ( vreg n -- vop ) swap <vreg> src/dest-vop <%peek-d> ;
: %peek-d ( vreg n -- vop )
<ds-loc> swap <vreg> src/dest-vop <%peek-d> ;
M: %peek-d basic-block? drop t ;
TUPLE: %replace-d ;
C: %replace-d make-vop ;
: %replace-d ( vreg n -- vop ) swap <vreg> 2-in-vop <%replace-d> ;
: %replace-d ( vreg n -- vop )
<ds-loc> swap <vreg> swap src/dest-vop <%replace-d> ;
M: %replace-d basic-block? drop t ;
TUPLE: %inc-d ;
C: %inc-d make-vop ;
: %inc-d ( n -- node ) src-vop <%inc-d> ;
M: %inc-d basic-block? drop t ;
: %inc-d, ( n -- ) dup 0 = [ dup %inc-d , ] unless drop ;
M: %inc-d basic-block? drop t ;
TUPLE: %immediate ;
C: %immediate make-vop ;
: %immediate ( vreg obj -- vop )
swap <vreg> src/dest-vop <%immediate> ;
M: %immediate basic-block? drop t ;
TUPLE: %peek-r ;
C: %peek-r make-vop ;
: %peek-r ( vreg n -- vop ) swap <vreg> src/dest-vop <%peek-r> ;
: %peek-r ( vreg n -- vop )
<cs-loc> swap <vreg> src/dest-vop <%peek-r> ;
M: %peek-r basic-block? drop t ;
TUPLE: %replace-r ;
C: %replace-r make-vop ;
: %replace-r ( vreg n -- vop ) swap <vreg> 2-in-vop <%replace-r> ;
: %replace-r ( vreg n -- vop )
<cs-loc> swap <vreg> swap src/dest-vop <%replace-r> ;
M: %replace-r basic-block? drop t ;
TUPLE: %inc-r ;
C: %inc-r make-vop ;
: %inc-r ( n -- ) src-vop <%inc-r> ;
: %inc-r, ( n -- ) dup 0 = [ dup %inc-r , ] unless drop ;
M: %inc-r basic-block? drop t ;
: in-1 0 0 %peek-d , ;
: in-2 0 1 %peek-d , 1 0 %peek-d , ;
@ -222,14 +242,22 @@ TUPLE: %fixnum/i ;
C: %fixnum/i make-vop ; : %fixnum/i 3-vop <%fixnum/i> ;
TUPLE: %fixnum/mod ;
C: %fixnum/mod make-vop ; : %fixnum/mod f <%fixnum/mod> ;
TUPLE: %fixnum-bitand ;
C: %fixnum-bitand make-vop ; : %fixnum-bitand 3-vop <%fixnum-bitand> ;
M: %fixnum-bitand basic-block? drop t ;
TUPLE: %fixnum-bitor ;
C: %fixnum-bitor make-vop ; : %fixnum-bitor 3-vop <%fixnum-bitor> ;
M: %fixnum-bitor basic-block? drop t ;
TUPLE: %fixnum-bitxor ;
C: %fixnum-bitxor make-vop ; : %fixnum-bitxor 3-vop <%fixnum-bitxor> ;
M: %fixnum-bitxor basic-block? drop t ;
TUPLE: %fixnum-bitnot ;
C: %fixnum-bitnot make-vop ; : %fixnum-bitnot 2-vop <%fixnum-bitnot> ;
M: %fixnum-bitnot basic-block? drop t ;
TUPLE: %fixnum<= ;
C: %fixnum<= make-vop ; : %fixnum<= 3-vop <%fixnum<=> ;
@ -252,12 +280,17 @@ C: %eq? make-vop ; : %eq? 3-vop <%eq?> ;
! - shifts with a large negative count: %fixnum-sgn
TUPLE: %fixnum<< ;
C: %fixnum<< make-vop ; : %fixnum<< 3-vop <%fixnum<<> ;
TUPLE: %fixnum>> ;
C: %fixnum>> make-vop ; : %fixnum>> 3-vop <%fixnum>>> ;
M: %fixnum>> basic-block? drop t ;
! due to x86 limitations the destination of this VOP must be
! vreg 2 (EDX), and the source must be vreg 0 (EAX).
TUPLE: %fixnum-sgn ;
C: %fixnum-sgn make-vop ; : %fixnum-sgn src/dest-vop <%fixnum-sgn> ;
M: %fixnum-sgn basic-block? drop t ;
! Integer comparison followed by a conditional branch is
! optimized
@ -317,10 +350,10 @@ C: %untag-fixnum make-vop ;
M: %untag-fixnum basic-block? drop t ;
: check-dest ( vop reg -- )
swap vop-out-1 = [ "bad VOP destination" throw ] unless ;
swap 0 vop-out = [ "bad VOP destination" throw ] unless ;
: check-src ( vop reg -- )
swap vop-in-1 = [ "bad VOP source" throw ] unless ;
swap 0 vop-in = [ "bad VOP source" throw ] unless ;
TUPLE: %getenv ;
C: %getenv make-vop ;

View File

@ -6,7 +6,7 @@ kernel-internals lists math memory namespaces words ;
M: %alien-invoke generate-node
#! call a C function.
dup vop-in-1 swap vop-in-2 load-library compile-c-call ;
dup 0 vop-in swap 1 vop-in load-library compile-c-call ;
M: %parameters generate-node
#! x86 does not pass parameters in registers
@ -28,12 +28,12 @@ M: float-regs push-reg
4 = [ FSTPS ] [ FSTPL ] ifte ;
M: %unbox generate-node
dup vop-in-2 f compile-c-call vop-in-3 push-reg ;
dup 1 vop-in f compile-c-call 2 vop-in push-reg ;
M: %box generate-node
dup vop-in-2 push-reg
dup vop-in-1 f compile-c-call
vop-in-2 ESP swap reg-size ADD ;
dup 1 vop-in push-reg
dup 0 vop-in f compile-c-call
1 vop-in ESP swap reg-size ADD ;
M: %cleanup generate-node
vop-in-1 dup 0 = [ drop ] [ ESP swap ADD ] ifte ;
0 vop-in dup 0 = [ drop ] [ ESP swap ADD ] ifte ;

View File

@ -112,7 +112,7 @@ M: %fixnum-bitxor generate-node ( vop -- ) dest/src XOR ;
M: %fixnum-bitnot generate-node ( vop -- )
! Negate the bits of the operand
vop-out-1 v>operand dup NOT
0 vop-out v>operand dup NOT
! Mask off the low 3 bits to give a fixnum tag
tag-mask XOR ;
@ -122,7 +122,7 @@ M: %fixnum<< generate-node
<label> "end" set
! make a copy
ECX EAX MOV
vop-in-1
0 vop-in
! check for potential overflow
dup shift-add ECX over ADD
2 * 1 - ECX swap CMP
@ -147,7 +147,7 @@ M: %fixnum<< generate-node
M: %fixnum>> generate-node
! shift register
dup vop-out-1 v>operand dup rot vop-in-1 SAR
dup 0 vop-out v>operand dup rot 0 vop-in SAR
! give it a fixnum tag
tag-mask bitnot AND ;
@ -155,7 +155,7 @@ M: %fixnum-sgn generate-node
! store 0 in EDX if EAX is >=0, otherwise store -1.
CDQ
! give it a fixnum tag.
vop-out-1 v>operand tag-bits SHL ;
0 vop-out v>operand tag-bits SHL ;
: load-boolean ( dest cond -- )
#! Compile this after a conditional jump to store f or t
@ -170,7 +170,7 @@ M: %fixnum-sgn generate-node
"end" get save-xt ; inline
: fixnum-compare ( vop -- dest )
dup vop-out-1 v>operand dup rot vop-in-1 v>operand CMP ;
dup 0 vop-out v>operand dup rot 0 vop-in v>operand CMP ;
M: %fixnum< generate-node ( vop -- )
fixnum-compare \ JL load-boolean ;
@ -188,7 +188,7 @@ M: %eq? generate-node ( vop -- )
fixnum-compare \ JE load-boolean ;
: fixnum-jump ( vop -- label )
dup vop-in-2 v>operand over vop-in-1 v>operand CMP
dup 1 vop-in v>operand over 0 vop-in v>operand CMP
vop-label ;
M: %jump-fixnum< generate-node ( vop -- ) fixnum-jump JL ;

View File

@ -23,7 +23,7 @@ M: %jump-label generate-node ( vop -- )
vop-label JMP ;
: conditional ( vop -- label )
dup vop-in-1 v>operand f address CMP vop-label ;
dup 0 vop-in v>operand f address CMP vop-label ;
M: %jump-f generate-node ( vop -- )
conditional JE ;
@ -38,19 +38,19 @@ M: %return generate-node ( vop -- )
drop RET ;
M: %untag generate-node ( vop -- )
vop-out-1 v>operand BIN: 111 bitnot AND ;
0 vop-out v>operand BIN: 111 bitnot AND ;
M: %retag-fixnum generate-node ( vop -- )
vop-out-1 v>operand 3 SHL ;
0 vop-out v>operand 3 SHL ;
M: %untag-fixnum generate-node ( vop -- )
vop-out-1 v>operand 3 SHR ;
0 vop-out v>operand 3 SHR ;
M: %dispatch generate-node ( vop -- )
#! Compile a piece of code that jumps to an offset in a
#! jump table indexed by the fixnum at the top of the stack.
#! The jump table must immediately follow this macro.
vop-in-1 v>operand
0 vop-in v>operand
! Multiply by 4 to get a jump table offset
dup 2 SHL
! Add to jump table base
@ -64,10 +64,10 @@ M: %dispatch generate-node ( vop -- )
M: %type generate-node ( vop -- )
#! Intrinstic version of type primitive. It outputs an
#! UNBOXED value in vop-out-1.
#! UNBOXED value in 0 vop-out.
<label> "f" set
<label> "end" set
vop-out-1 v>operand
0 vop-out v>operand
! Make a copy
ECX over MOV
! Get the tag
@ -91,5 +91,5 @@ M: %type generate-node ( vop -- )
"end" get save-xt ;
M: %tag generate-node ( vop -- )
dup dup vop-in-1 check-dest
vop-in-1 v>operand tag-mask AND ;
dup dup 0 vop-in check-dest
0 vop-in v>operand tag-mask AND ;

View File

@ -8,45 +8,45 @@ M: %slot generate-node ( vop -- )
dest/src
! turn tagged fixnum slot # into an offset, multiple of 4
dup 1 SHR
! compute slot address in vop-out-1
! compute slot address in 0 vop-out
dupd ADD
! load slot value in vop-out-1
! load slot value in 0 vop-out
dup unit MOV ;
M: %fast-slot generate-node ( vop -- )
dup vop-in-1 swap vop-out-1 v>operand tuck >r 2list r>
dup 0 vop-in swap 0 vop-out v>operand tuck >r 2list r>
swap MOV ;
: card-offset 1 getenv ;
M: %write-barrier generate-node ( vop -- )
#! Mark the card pointed to by vreg.
vop-in-1 v>operand
0 vop-in v>operand
dup card-bits SHR
card-offset 2list card-mark OR
0 rel-cards ;
M: %set-slot generate-node ( vop -- )
dup vop-in-3 v>operand over vop-in-2 v>operand
dup 2 vop-in v>operand over 1 vop-in v>operand
! turn tagged fixnum slot # into an offset, multiple of 4
over 1 SHR
! compute slot address in vop-in-2
! compute slot address in 1 vop-in
dupd ADD
! store new slot value
>r vop-in-1 v>operand r> unit swap MOV ;
>r 0 vop-in v>operand r> unit swap MOV ;
M: %fast-set-slot generate-node ( vop -- )
dup vop-in-3 over vop-in-2 v>operand
swap 2list swap vop-in-1 v>operand MOV ;
dup 2 vop-in over 1 vop-in v>operand
swap 2list swap 0 vop-in v>operand MOV ;
: userenv@ ( n -- addr )
cell * "userenv" f dlsym + ;
M: %getenv generate-node ( vop -- )
dup vop-out-1 v>operand swap vop-in-1
dup 0 vop-out v>operand swap 0 vop-in
[ userenv@ unit MOV ] keep 0 rel-userenv ;
M: %setenv generate-node ( vop -- )
dup vop-in-2
[ userenv@ unit swap vop-in-1 v>operand MOV ] keep
dup 1 vop-in
[ userenv@ unit swap 0 vop-in v>operand MOV ] keep
0 rel-userenv ;

View File

@ -8,30 +8,30 @@ memory sequences words ;
: ds-op ( n -- op ) ESI swap reg-stack ;
: cs-op ( n -- op ) EBX swap reg-stack ;
: (%peek) dup vop-out-1 v>operand swap vop-in-1 ;
: (%peek) dup 0 vop-out v>operand swap 0 vop-in ;
M: %peek-d generate-node ( vop -- ) (%peek) ds-op MOV ;
M: %peek-r generate-node ( vop -- ) (%peek) cs-op MOV ;
: (%replace) dup vop-in-2 v>operand swap vop-in-1 ;
: (%replace) dup 1 vop-in v>operand swap 0 vop-in ;
M: %replace-d generate-node ( vop -- ) (%replace) ds-op swap MOV ;
M: %replace-r generate-node ( vop -- ) (%replace) cs-op swap MOV ;
: (%inc) swap vop-in-1 cell * dup 0 > [ ADD ] [ neg SUB ] ifte ;
: (%inc) swap 0 vop-in cell * dup 0 > [ ADD ] [ neg SUB ] ifte ;
M: %inc-d generate-node ( vop -- ) ESI (%inc) ;
M: %inc-r generate-node ( vop -- ) EBX (%inc) ;
M: %immediate generate-node ( vop -- )
dup vop-out-1 v>operand swap vop-in-1 address MOV ;
dup 0 vop-out v>operand swap 0 vop-in address MOV ;
: load-indirect ( dest literal -- )
intern-literal unit MOV 0 0 rel-address ;
M: %indirect generate-node ( vop -- )
#! indirect load of a literal through a table
dup vop-out-1 v>operand swap vop-in-1 load-indirect ;
dup 0 vop-out v>operand swap 0 vop-in load-indirect ;

View File

@ -144,7 +144,7 @@ M: absolute-16/16 fixup ( absolute -- ) >absolute fixup-16/16 ;
] with-scope ;
: postpone-word ( word -- )
dup compiling? [
dup compiling? over compound? not or [
drop
] [
compile-words [ unique ] change

View File

@ -447,10 +447,10 @@ memory parser sequences strings vectors words prettyprint ;
\ set-integer-slot [ [ integer object fixnum ] [ ] ] "infer-effect" set-word-prop
\ char-slot [ [ object fixnum ] [ fixnum ] ] "infer-effect" set-word-prop
\ char-slot [ [ fixnum object ] [ fixnum ] ] "infer-effect" set-word-prop
\ char-slot t "flushable" set-word-prop
\ set-char-slot [ [ integer object fixnum ] [ ] ] "infer-effect" set-word-prop
\ set-char-slot [ [ integer fixnum object ] [ ] ] "infer-effect" set-word-prop
\ resize-array [ [ integer array ] [ array ] ] "infer-effect" set-word-prop
\ resize-string [ [ integer string ] [ string ] ] "infer-effect" set-word-prop

View File

@ -50,7 +50,7 @@ M: integer ^ ( z w -- z^w )
"0^0 is not defined" throw
] [
dup 0 < [ neg ^ recip ] [ (integer^) ] ifte
] ifte ; foldable
] ifte ;
: (^mod) ( n z w -- z^w )
1 swap [

View File

@ -34,7 +34,8 @@ test vectors words ;
[ [ 1 2 3 ] [ 4 5 6 ] [ 1 2 3 ] ] [ kill-6 ] unit-test
: kill-set*
dataflow kill-set [ literal-value ] map ;
dataflow dup solve-recursion dup split-node
kill-set [ literal-value ] map ;
: foo 1 2 3 ;

View File

@ -31,3 +31,5 @@ USE: test
[ 1 3 ] [ [[ 1 2 ]] [[ 3 4 ]] 2car ] unit-test
[ 2 4 ] [ [[ 1 2 ]] [[ 3 4 ]] 2cdr ] unit-test
[ f ] [ f peek ] unit-test

View File

@ -44,7 +44,7 @@ parser prettyprint sequences io strings vectors words ;
PREDICATE: cons kernel-error ( obj -- ? )
car kernel-error = ;
M: f error. ( f -- ) ;
M: f error. ( f -- ) drop ;
M: kernel-error error. ( error -- )
#! Kernel errors are indexed by integers.

View File

@ -53,11 +53,7 @@ unparser vectors words ;
: instances ( quot -- list )
#! Return a list of all object that return true when the
#! quotation is applied to them.
[
[
[ swap call ] 2keep rot [ , ] [ drop ] ifte
] each-object drop
] [ ] make ;
[ [ [ swap call ] 2keep rot ?, ] each-object drop ] [ ] make ;
G: each-slot ( obj quot -- )
[ over ] standard-combination ; inline

View File

@ -63,8 +63,6 @@ SYMBOL: commands
[ compound? ] "Annotate with breakpoint" [ break ] define-command
[ compound? ] "Annotate with profiling" [ profile ] define-command
[ word? ] "Compile" [ recompile ] define-command
[ word? ] "Show stack effect" [ unit infer . ] define-command
[ word? ] "Show dataflow IR" [ word-def t dataflow. ] define-command
[ word? ] "Show linear IR" [ precompile ] define-command
[ word? ] "Infer stack effect" [ unit infer . ] define-command
[ [ gadget? ] is? ] "Display gadget" [ gadget. ] define-command

View File

@ -1,5 +1,12 @@
#include "factor.h"
F_FLOAT* make_float(double n)
{
F_FLOAT* flo = allot_object(FLOAT_TYPE,sizeof(F_FLOAT));
flo->n = n;
return flo;
}
double to_float(CELL tagged)
{
F_RATIO* r;

View File

@ -3,12 +3,7 @@ typedef struct {
double n;
} F_FLOAT;
INLINE F_FLOAT* make_float(double n)
{
F_FLOAT* flo = allot_object(FLOAT_TYPE,sizeof(F_FLOAT));
flo->n = n;
return flo;
}
F_FLOAT* make_float(double n);
INLINE double untag_float_fast(CELL tagged)
{