refactored inlined recursive blocks
parent
0e6236e6f6
commit
e82f069649
|
@ -18,7 +18,6 @@
|
||||||
- on win64: to_cell will break
|
- on win64: to_cell will break
|
||||||
- .h .b .o for ratios and floats is broken
|
- .h .b .o for ratios and floats is broken
|
||||||
- amd64 to do:
|
- amd64 to do:
|
||||||
- fixnum<< overflow check
|
|
||||||
- alien calls
|
- alien calls
|
||||||
- relocation problem
|
- relocation problem
|
||||||
- compiling sheet runs out of memory
|
- compiling sheet runs out of memory
|
||||||
|
|
|
@ -1,20 +1,23 @@
|
||||||
! Copyright (C) 2004, 2005 Slava Pestov.
|
! Copyright (C) 2004, 2005 Slava Pestov.
|
||||||
IN: compiler
|
IN: compiler
|
||||||
USING: compiler-backend compiler-frontend errors inference io
|
USING: compiler-backend compiler-frontend errors hashtables
|
||||||
kernel lists math namespaces optimizer prettyprint sequences
|
inference io kernel lists math namespaces optimizer prettyprint
|
||||||
words ;
|
sequences words ;
|
||||||
|
|
||||||
: precompile ( quotation -- basic-blocks )
|
: (compile) ( word -- basic-blocks )
|
||||||
dataflow optimize linearize split-blocks simplify ;
|
|
||||||
|
|
||||||
: (compile) ( word -- )
|
|
||||||
#! Should be called inside the with-compiler scope.
|
#! Should be called inside the with-compiler scope.
|
||||||
"Compiling " write dup . flush
|
dup word-def dataflow optimize linearize
|
||||||
dup word-def precompile generate ;
|
[ split-blocks simplify generate ] hash-each ;
|
||||||
|
|
||||||
|
: inform-compile ( word -- ) "Compiling " write . flush ;
|
||||||
|
|
||||||
: compile-postponed ( -- )
|
: compile-postponed ( -- )
|
||||||
compile-words get dup empty?
|
compile-words get dup empty? [
|
||||||
[ dup pop (compile) compile-postponed ] unless drop ;
|
dup pop
|
||||||
|
dup inform-compile
|
||||||
|
(compile)
|
||||||
|
compile-postponed
|
||||||
|
] unless drop ;
|
||||||
|
|
||||||
: compile ( word -- )
|
: compile ( word -- )
|
||||||
[ postpone-word compile-postponed ] with-compiler ;
|
[ postpone-word compile-postponed ] with-compiler ;
|
||||||
|
|
|
@ -1,21 +1,45 @@
|
||||||
! Copyright (C) 2004, 2005 Slava Pestov.
|
! Copyright (C) 2004, 2005 Slava Pestov.
|
||||||
! See http://factor.sf.net/license.txt for BSD license.
|
! See http://factor.sf.net/license.txt for BSD license.
|
||||||
IN: compiler-frontend
|
IN: compiler-frontend
|
||||||
USING: arrays compiler-backend errors generic inference kernel
|
USING: arrays compiler-backend errors generic hashtables
|
||||||
lists math namespaces prettyprint sequences strings words ;
|
inference kernel lists math namespaces prettyprint sequences
|
||||||
|
strings words ;
|
||||||
|
|
||||||
: in-1 0 0 %peek-d , ;
|
: in-1 0 0 %peek-d , ;
|
||||||
: in-2 0 1 %peek-d , 1 0 %peek-d , ;
|
: in-2 0 1 %peek-d , 1 0 %peek-d , ;
|
||||||
: in-3 0 2 %peek-d , 1 1 %peek-d , 2 0 %peek-d , ;
|
: in-3 0 2 %peek-d , 1 1 %peek-d , 2 0 %peek-d , ;
|
||||||
: out-1 T{ vreg f 0 } 0 %replace-d , ;
|
: out-1 T{ vreg f 0 } 0 %replace-d , ;
|
||||||
|
|
||||||
|
! A map from words to linear IR.
|
||||||
|
SYMBOL: linearized
|
||||||
|
|
||||||
|
! Renamed labels. To avoid problems with labels with the same
|
||||||
|
! name in different scopes.
|
||||||
|
SYMBOL: renamed-labels
|
||||||
|
|
||||||
|
: rename-label ( label -- label )
|
||||||
|
<label> dup rot renamed-labels get set-hash ;
|
||||||
|
|
||||||
|
: renamed-label ( label -- label )
|
||||||
|
renamed-labels get hash ;
|
||||||
|
|
||||||
GENERIC: linearize* ( node -- )
|
GENERIC: linearize* ( node -- )
|
||||||
|
|
||||||
: linearize ( dataflow -- linear )
|
: linearize-1 ( word dataflow -- )
|
||||||
#! Transform dataflow IR into linear IR. This strips out
|
#! Transform dataflow IR into linear IR. This strips out
|
||||||
#! stack flow information, and flattens conditionals into
|
#! stack flow information, and flattens conditionals into
|
||||||
#! jumps and labels.
|
#! jumps and labels.
|
||||||
[ %prologue , linearize* ] { } make ;
|
[ %prologue , linearize* ] { } make
|
||||||
|
swap linearized get set-hash ;
|
||||||
|
|
||||||
|
: init-linearizer ( -- )
|
||||||
|
H{ } clone linearized set
|
||||||
|
H{ } clone renamed-labels set ;
|
||||||
|
|
||||||
|
: linearize ( word dataflow -- linearized )
|
||||||
|
#! Outputs a hashtable mapping from labels to their
|
||||||
|
#! respective linear IR.
|
||||||
|
init-linearizer linearize-1 linearized get ;
|
||||||
|
|
||||||
: linearize-next node-successor linearize* ;
|
: linearize-next node-successor linearize* ;
|
||||||
|
|
||||||
|
@ -23,23 +47,19 @@ M: f linearize* ( f -- ) drop ;
|
||||||
|
|
||||||
M: node linearize* ( node -- ) linearize-next ;
|
M: node linearize* ( node -- ) linearize-next ;
|
||||||
|
|
||||||
|
: linearize-call ( node label -- )
|
||||||
|
over node-successor #return?
|
||||||
|
[ %jump , drop ] [ %call , linearize-next ] if ;
|
||||||
|
|
||||||
|
: linearize-call-label ( node -- )
|
||||||
|
dup node-param rename-label linearize-call ;
|
||||||
|
|
||||||
M: #label linearize* ( node -- )
|
M: #label linearize* ( node -- )
|
||||||
#! We remap the IR node's label to a new label object here,
|
#! We remap the IR node's label to a new label object here,
|
||||||
#! to avoid problems with two IR #label nodes having the
|
#! to avoid problems with two IR #label nodes having the
|
||||||
#! same label in different lexical scopes.
|
#! same label in different lexical scopes.
|
||||||
<label> [
|
dup linearize-call-label dup node-param renamed-label
|
||||||
%return-to ,
|
swap node-child linearize-1 ;
|
||||||
<label> dup pick node-param set %label ,
|
|
||||||
dup node-child linearize*
|
|
||||||
] keep %label ,
|
|
||||||
linearize-next ;
|
|
||||||
|
|
||||||
: ?tail-call ( node label caller jumper -- next )
|
|
||||||
>r >r over node-successor #return? [
|
|
||||||
r> drop r> execute , drop
|
|
||||||
] [
|
|
||||||
r> execute , r> drop linearize-next
|
|
||||||
] if ; inline
|
|
||||||
|
|
||||||
: intrinsic ( #call -- quot ) node-param "intrinsic" word-prop ;
|
: intrinsic ( #call -- quot ) node-param "intrinsic" word-prop ;
|
||||||
|
|
||||||
|
@ -61,12 +81,12 @@ M: #call linearize* ( node -- )
|
||||||
dup intrinsic [
|
dup intrinsic [
|
||||||
dupd call linearize-next
|
dupd call linearize-next
|
||||||
] [
|
] [
|
||||||
dup node-param \ %call \ %jump ?tail-call
|
dup node-param linearize-call
|
||||||
] if*
|
] if*
|
||||||
] if* ;
|
] if* ;
|
||||||
|
|
||||||
M: #call-label linearize* ( node -- )
|
M: #call-label linearize* ( node -- )
|
||||||
dup node-param get \ %call-label \ %jump-label ?tail-call ;
|
dup node-param renamed-label linearize-call ;
|
||||||
|
|
||||||
M: #if linearize* ( node -- )
|
M: #if linearize* ( node -- )
|
||||||
<label> dup in-1 -1 %inc-d , 0 %jump-t , linearize-if ;
|
<label> dup in-1 -1 %inc-d , 0 %jump-t , linearize-if ;
|
||||||
|
|
|
@ -27,15 +27,6 @@ M: %prologue generate-node ( vop -- )
|
||||||
1 1 stack-increment ADDI
|
1 1 stack-increment ADDI
|
||||||
0 MTLR ;
|
0 MTLR ;
|
||||||
|
|
||||||
M: %call-label generate-node ( vop -- )
|
|
||||||
#! Near calling convention for inlined recursive combinators
|
|
||||||
#! Note: length of instruction sequence is hard-coded.
|
|
||||||
vop-label
|
|
||||||
compiled-offset 20 + 18 LOAD32 rel-2/2 rel-address
|
|
||||||
1 1 stack-increment neg STWU
|
|
||||||
18 1 stack-increment lr@ STW
|
|
||||||
B ;
|
|
||||||
|
|
||||||
: word-addr ( word -- )
|
: word-addr ( word -- )
|
||||||
#! Load a word address into r3.
|
#! Load a word address into r3.
|
||||||
dup word-xt 3 LOAD32 rel-2/2 rel-word ;
|
dup word-xt 3 LOAD32 rel-2/2 rel-word ;
|
||||||
|
@ -56,18 +47,9 @@ M: %call generate-node ( vop -- )
|
||||||
M: %jump generate-node ( vop -- )
|
M: %jump generate-node ( vop -- )
|
||||||
drop compile-epilogue label compile-jump ;
|
drop compile-epilogue label compile-jump ;
|
||||||
|
|
||||||
M: %jump-label generate-node ( vop -- )
|
|
||||||
drop label B ;
|
|
||||||
|
|
||||||
M: %jump-t generate-node ( vop -- )
|
M: %jump-t generate-node ( vop -- )
|
||||||
drop 0 input-operand 0 swap f address CMPI label BNE ;
|
drop 0 input-operand 0 swap f address CMPI label BNE ;
|
||||||
|
|
||||||
M: %return-to generate-node ( vop -- )
|
|
||||||
drop
|
|
||||||
label 0 3 LOAD32 absolute-2/2
|
|
||||||
1 1 stack-increment neg STWU
|
|
||||||
3 1 stack-increment lr@ STW ;
|
|
||||||
|
|
||||||
M: %return generate-node ( vop -- )
|
M: %return generate-node ( vop -- )
|
||||||
drop compile-epilogue BLR ;
|
drop compile-epilogue BLR ;
|
||||||
|
|
||||||
|
|
|
@ -114,26 +114,14 @@ TUPLE: %return ;
|
||||||
C: %return make-vop ;
|
C: %return make-vop ;
|
||||||
: %return empty-vop <%return> ;
|
: %return empty-vop <%return> ;
|
||||||
|
|
||||||
TUPLE: %return-to ;
|
|
||||||
C: %return-to make-vop ;
|
|
||||||
: %return-to label-vop <%return-to> ;
|
|
||||||
|
|
||||||
TUPLE: %jump ;
|
TUPLE: %jump ;
|
||||||
C: %jump make-vop ;
|
C: %jump make-vop ;
|
||||||
: %jump label-vop <%jump> ;
|
: %jump label-vop <%jump> ;
|
||||||
|
|
||||||
TUPLE: %jump-label ;
|
|
||||||
C: %jump-label make-vop ;
|
|
||||||
: %jump-label label-vop <%jump-label> ;
|
|
||||||
|
|
||||||
TUPLE: %call ;
|
TUPLE: %call ;
|
||||||
C: %call make-vop ;
|
C: %call make-vop ;
|
||||||
: %call label-vop <%call> ;
|
: %call label-vop <%call> ;
|
||||||
|
|
||||||
TUPLE: %call-label ;
|
|
||||||
C: %call-label make-vop ;
|
|
||||||
: %call-label label-vop <%call-label> ;
|
|
||||||
|
|
||||||
TUPLE: %jump-t ;
|
TUPLE: %jump-t ;
|
||||||
C: %jump-t make-vop ;
|
C: %jump-t make-vop ;
|
||||||
: %jump-t <vreg> label/src-vop <%jump-t> ;
|
: %jump-t <vreg> label/src-vop <%jump-t> ;
|
||||||
|
|
|
@ -8,21 +8,15 @@ kernel-internals lists math memory namespaces sequences words ;
|
||||||
M: %prologue generate-node ( vop -- )
|
M: %prologue generate-node ( vop -- )
|
||||||
drop compile-prologue ;
|
drop compile-prologue ;
|
||||||
|
|
||||||
: (call-label)
|
: (%call)
|
||||||
label dup postpone-word
|
label dup postpone-word
|
||||||
dup primitive? [ address-operand ] when ;
|
dup primitive? [ address-operand ] when ;
|
||||||
|
|
||||||
M: %call generate-node ( vop -- )
|
M: %call generate-node ( vop -- )
|
||||||
drop (call-label) CALL ;
|
drop (%call) CALL ;
|
||||||
|
|
||||||
M: %call-label generate-node ( vop -- )
|
|
||||||
drop label CALL ;
|
|
||||||
|
|
||||||
M: %jump generate-node ( vop -- )
|
M: %jump generate-node ( vop -- )
|
||||||
drop compile-epilogue (call-label) JMP ;
|
drop compile-epilogue (%call) JMP ;
|
||||||
|
|
||||||
M: %jump-label generate-node ( vop -- )
|
|
||||||
drop label JMP ;
|
|
||||||
|
|
||||||
M: %jump-t generate-node ( vop -- )
|
M: %jump-t generate-node ( vop -- )
|
||||||
drop
|
drop
|
||||||
|
@ -31,9 +25,6 @@ M: %jump-t generate-node ( vop -- )
|
||||||
! If not equal, jump
|
! If not equal, jump
|
||||||
label JNE ;
|
label JNE ;
|
||||||
|
|
||||||
M: %return-to generate-node ( vop -- )
|
|
||||||
drop label address-operand PUSH compile-prologue ;
|
|
||||||
|
|
||||||
M: %return generate-node ( vop -- )
|
M: %return generate-node ( vop -- )
|
||||||
drop compile-epilogue RET ;
|
drop compile-epilogue RET ;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
! Copyright (C) 2004, 2005 Slava Pestov.
|
! Copyright (C) 2004, 2005 Slava Pestov.
|
||||||
! See http://factor.sf.net/license.txt for BSD license.
|
! See http://factor.sf.net/license.txt for BSD license.
|
||||||
IN: compiler
|
IN: compiler
|
||||||
USING: assembler errors generic hashtables kernel
|
USING: assembler compiler-backend compiler-frontend errors
|
||||||
kernel-internals lists math namespaces prettyprint sequences
|
generic hashtables kernel kernel-internals lists math namespaces
|
||||||
strings vectors words ;
|
prettyprint sequences strings vectors words ;
|
||||||
|
|
||||||
! We use a hashtable "compiled-xts" that maps words to
|
! We use a hashtable "compiled-xts" that maps words to
|
||||||
! xt's that are currently being compiled. The commit-xt's word
|
! xt's that are currently being compiled. The commit-xt's word
|
||||||
|
@ -168,8 +168,11 @@ SYMBOL: compile-words
|
||||||
: compiling? ( word -- ? )
|
: compiling? ( word -- ? )
|
||||||
#! A word that is compiling or already compiled will not be
|
#! A word that is compiling or already compiled will not be
|
||||||
#! added to the list of words to be compiled.
|
#! added to the list of words to be compiled.
|
||||||
dup compiled? over compile-words get member? or
|
dup compiled?
|
||||||
[ drop t ] [ compiled-xts get hash ] if ;
|
over label? or
|
||||||
|
over linearized get hash or
|
||||||
|
over compile-words get member? or
|
||||||
|
swap compiled-xts get hash or ;
|
||||||
|
|
||||||
: fixup-xts ( -- )
|
: fixup-xts ( -- )
|
||||||
deferred-xts get [ dup resolve swap fixup ] each ;
|
deferred-xts get [ dup resolve swap fixup ] each ;
|
||||||
|
|
|
@ -8,8 +8,8 @@ USE: words
|
||||||
|
|
||||||
: fie [ ] [ ] if ;
|
: fie [ ] [ ] if ;
|
||||||
|
|
||||||
[ ] [ \ fie word-def dataflow linearize drop ] unit-test
|
[ ] [ \ fie dup word-def dataflow linearize drop ] unit-test
|
||||||
|
|
||||||
: foo [ drop ] each-word ;
|
: foo [ drop ] each-word ;
|
||||||
|
|
||||||
[ ] [ \ foo word-def dataflow linearize drop ] unit-test
|
[ ] [ \ foo dup word-def dataflow linearize drop ] unit-test
|
||||||
|
|
Loading…
Reference in New Issue