RPO linearization
parent
b36f610170
commit
411b38924f
|
@ -1,12 +1,10 @@
|
||||||
IN: compiler.cfg.builder.tests
|
IN: compiler.cfg.builder.tests
|
||||||
USING: compiler.cfg.builder tools.test kernel sequences
|
USING: tools.test kernel sequences
|
||||||
|
words sequences.private fry prettyprint alien
|
||||||
math.private compiler.tree.builder compiler.tree.optimizer
|
math.private compiler.tree.builder compiler.tree.optimizer
|
||||||
words sequences.private fry prettyprint alien ;
|
compiler.cfg.builder compiler.cfg.debugger ;
|
||||||
|
|
||||||
! Just ensure that various CFGs build correctly.
|
! Just ensure that various CFGs build correctly.
|
||||||
: test-cfg ( quot -- result )
|
|
||||||
build-tree optimize-tree gensym gensym build-cfg ;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
[ ]
|
[ ]
|
||||||
[ dup ]
|
[ dup ]
|
||||||
|
@ -28,10 +26,6 @@ words sequences.private fry prettyprint alien ;
|
||||||
'[ _ test-cfg drop ] [ ] swap unit-test
|
'[ _ test-cfg drop ] [ ] swap unit-test
|
||||||
] each
|
] each
|
||||||
|
|
||||||
: test-word-cfg ( word -- result )
|
|
||||||
[ build-tree-from-word nip optimize-tree ] keep dup
|
|
||||||
build-cfg ;
|
|
||||||
|
|
||||||
: test-1 ( -- ) test-1 ;
|
: test-1 ( -- ) test-1 ;
|
||||||
: test-2 ( -- ) 3 . test-2 ;
|
: test-2 ( -- ) 3 . test-2 ;
|
||||||
: test-3 ( a -- b ) dup [ test-3 ] when ;
|
: test-3 ( a -- b ) dup [ test-3 ] when ;
|
||||||
|
@ -41,5 +35,5 @@ words sequences.private fry prettyprint alien ;
|
||||||
test-2
|
test-2
|
||||||
test-3
|
test-3
|
||||||
} [
|
} [
|
||||||
'[ _ test-word-cfg drop ] [ ] swap unit-test
|
'[ _ test-cfg drop ] [ ] swap unit-test
|
||||||
] each
|
] each
|
||||||
|
|
|
@ -30,6 +30,8 @@ IN: compiler.cfg.builder
|
||||||
building off
|
building off
|
||||||
basic-block off ;
|
basic-block off ;
|
||||||
|
|
||||||
|
: stop-iterating ( -- next ) end-basic-block f ;
|
||||||
|
|
||||||
USE: qualified
|
USE: qualified
|
||||||
FROM: compiler.generator.registers => +input+ ;
|
FROM: compiler.generator.registers => +input+ ;
|
||||||
FROM: compiler.generator.registers => +output+ ;
|
FROM: compiler.generator.registers => +output+ ;
|
||||||
|
@ -49,7 +51,7 @@ SYMBOL: current-label-start
|
||||||
|
|
||||||
: add-procedure ( -- )
|
: add-procedure ( -- )
|
||||||
basic-block get current-word get current-label get
|
basic-block get current-word get current-label get
|
||||||
<procedure> procedures get push ;
|
<cfg> procedures get push ;
|
||||||
|
|
||||||
: begin-procedure ( word label -- )
|
: begin-procedure ( word label -- )
|
||||||
end-basic-block
|
end-basic-block
|
||||||
|
@ -100,17 +102,17 @@ GENERIC: emit-node ( node -- next )
|
||||||
: if-intrinsics ( #call -- quot )
|
: if-intrinsics ( #call -- quot )
|
||||||
word>> "if-intrinsics" word-prop ;
|
word>> "if-intrinsics" word-prop ;
|
||||||
|
|
||||||
: local-recursive-call ( basic-block -- )
|
: local-recursive-call ( basic-block -- next )
|
||||||
%branch
|
%branch
|
||||||
basic-block get successors>> push
|
basic-block get successors>> push
|
||||||
end-basic-block ;
|
stop-iterating ;
|
||||||
|
|
||||||
: emit-call ( word -- next )
|
: emit-call ( word -- next )
|
||||||
finalize-phantoms
|
finalize-phantoms
|
||||||
{
|
{
|
||||||
{ [ tail-call? not ] [ 0 %frame-required %call iterate-next ] }
|
{ [ tail-call? not ] [ 0 %frame-required %call iterate-next ] }
|
||||||
{ [ dup loops get key? ] [ loops get at local-recursive-call f ] }
|
{ [ dup loops get key? ] [ loops get at local-recursive-call ] }
|
||||||
[ %epilogue %jump f ]
|
[ %epilogue %jump stop-iterating ]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
! #recursive
|
! #recursive
|
||||||
|
@ -265,7 +267,7 @@ M: #return-recursive emit-node
|
||||||
[ %epilogue %return ] unless f ;
|
[ %epilogue %return ] unless f ;
|
||||||
|
|
||||||
! #terminate
|
! #terminate
|
||||||
M: #terminate emit-node drop end-basic-block f ;
|
M: #terminate emit-node drop stop-iterating ;
|
||||||
|
|
||||||
! FFI
|
! FFI
|
||||||
M: #alien-invoke emit-node
|
M: #alien-invoke emit-node
|
||||||
|
|
|
@ -3,45 +3,25 @@
|
||||||
USING: kernel accessors namespaces assocs sequences sets fry ;
|
USING: kernel accessors namespaces assocs sequences sets fry ;
|
||||||
IN: compiler.cfg
|
IN: compiler.cfg
|
||||||
|
|
||||||
TUPLE: procedure entry word label ;
|
TUPLE: cfg entry word label ;
|
||||||
|
|
||||||
C: <procedure> procedure
|
C: <cfg> cfg
|
||||||
|
|
||||||
! - "id" is a globally unique id used for hashcode*.
|
! - "number" and "visited" is used by linearization.
|
||||||
! - "number" is assigned by linearization.
|
|
||||||
TUPLE: basic-block < identity-tuple
|
TUPLE: basic-block < identity-tuple
|
||||||
id
|
visited
|
||||||
number
|
number
|
||||||
label
|
label
|
||||||
instructions
|
instructions
|
||||||
successors
|
successors
|
||||||
predecessors ;
|
predecessors ;
|
||||||
|
|
||||||
SYMBOL: next-block-id
|
|
||||||
|
|
||||||
: <basic-block> ( -- basic-block )
|
: <basic-block> ( -- basic-block )
|
||||||
basic-block new
|
basic-block new
|
||||||
next-block-id counter >>id
|
|
||||||
V{ } clone >>instructions
|
V{ } clone >>instructions
|
||||||
V{ } clone >>successors
|
V{ } clone >>successors
|
||||||
V{ } clone >>predecessors ;
|
V{ } clone >>predecessors ;
|
||||||
|
|
||||||
M: basic-block hashcode* id>> nip ;
|
TUPLE: mr instructions word label ;
|
||||||
|
|
||||||
! Utilities
|
C: <mr> mr
|
||||||
SYMBOL: visited-blocks
|
|
||||||
|
|
||||||
: visit-block ( basic-block quot -- )
|
|
||||||
over visited-blocks get 2dup key?
|
|
||||||
[ 2drop 2drop ] [ conjoin call ] if ; inline
|
|
||||||
|
|
||||||
: (each-block) ( basic-block quot -- )
|
|
||||||
'[
|
|
||||||
_
|
|
||||||
[ call ]
|
|
||||||
[ [ successors>> ] dip '[ _ (each-block) ] each ]
|
|
||||||
2bi
|
|
||||||
] visit-block ; inline
|
|
||||||
|
|
||||||
: each-block ( basic-block quot -- )
|
|
||||||
H{ } clone visited-blocks [ (each-block) ] with-variable ; inline
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
! Copyright (C) 2008 Slava Pestov.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: kernel words sequences quotations namespaces io
|
||||||
|
accessors prettyprint prettyprint.config
|
||||||
|
compiler.tree.builder compiler.tree.optimizer
|
||||||
|
compiler.cfg.builder compiler.cfg.linearization ;
|
||||||
|
IN: compiler.cfg.debugger
|
||||||
|
|
||||||
|
GENERIC: test-cfg ( quot -- cfgs )
|
||||||
|
|
||||||
|
M: callable test-cfg
|
||||||
|
build-tree optimize-tree gensym gensym build-cfg ;
|
||||||
|
|
||||||
|
M: word test-cfg
|
||||||
|
[ build-tree-from-word nip optimize-tree ] keep dup
|
||||||
|
build-cfg ;
|
||||||
|
|
||||||
|
: test-mr ( quot -- mrs ) test-cfg [ build-mr ] map ;
|
||||||
|
|
||||||
|
: mr. ( mrs -- )
|
||||||
|
[
|
||||||
|
boa-tuples? on
|
||||||
|
"=== word: " write
|
||||||
|
dup word>> pprint
|
||||||
|
", label: " write
|
||||||
|
dup label>> pprint nl nl
|
||||||
|
instructions>> .
|
||||||
|
nl
|
||||||
|
] each ;
|
|
@ -2,9 +2,9 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: namespaces sequences math math.order kernel assocs
|
USING: namespaces sequences math math.order kernel assocs
|
||||||
accessors vectors fry
|
accessors vectors fry
|
||||||
compiler.machine.linear-scan.live-intervals
|
compiler.cfg.linear-scan.live-intervals
|
||||||
compiler.backend ;
|
compiler.backend ;
|
||||||
IN: compiler.machine.linear-scan.allocation
|
IN: compiler.cfg.linear-scan.allocation
|
||||||
|
|
||||||
! Mapping from vregs to machine registers
|
! Mapping from vregs to machine registers
|
||||||
SYMBOL: register-allocation
|
SYMBOL: register-allocation
|
|
@ -1,12 +1,6 @@
|
||||||
! 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.
|
||||||
IN: compiler.machine.linear-scan
|
IN: compiler.cfg.linear-scan
|
||||||
|
|
||||||
! See http://www.cs.ucla.edu/~palsberg/course/cs132/linearscan.pdf
|
! See http://www.cs.ucla.edu/~palsberg/course/cs132/linearscan.pdf
|
||||||
|
|
||||||
! ! ! Step 1: compute live intervals
|
|
||||||
|
|
||||||
|
|
||||||
! ! ! Step 2: allocate registers
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: namespaces kernel assocs accessors sequences math
|
USING: namespaces kernel assocs accessors sequences math
|
||||||
math.order sorting compiler.instructions compiler.registers ;
|
math.order sorting compiler.instructions compiler.registers ;
|
||||||
IN: compiler.machine.linear-scan.live-intervals
|
IN: compiler.cfg.linear-scan.live-intervals
|
||||||
|
|
||||||
TUPLE: live-interval < identity-tuple vreg start end ;
|
TUPLE: live-interval < identity-tuple vreg start end ;
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
! Copyright (C) 2008 Slava Pestov.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: kernel math accessors sequences namespaces make
|
||||||
|
combinators compiler.cfg compiler.cfg.rpo compiler.instructions
|
||||||
|
compiler.instructions.syntax ;
|
||||||
|
IN: compiler.cfg.linearization
|
||||||
|
|
||||||
|
! Convert CFG IR to machine IR.
|
||||||
|
SYMBOL: frame-size
|
||||||
|
|
||||||
|
: compute-frame-size ( rpo -- )
|
||||||
|
[ instructions>> [ %frame-required? ] filter ] map concat
|
||||||
|
[ f ] [ [ n>> ] map supremum ] if-empty
|
||||||
|
frame-size set ;
|
||||||
|
|
||||||
|
GENERIC: linearize-insn ( basic-block insn -- )
|
||||||
|
|
||||||
|
: linearize-insns ( basic-block -- )
|
||||||
|
dup instructions>> [ linearize-insn ] with each ; inline
|
||||||
|
|
||||||
|
M: insn linearize-insn , drop ;
|
||||||
|
|
||||||
|
M: %frame-required linearize-insn 2drop ;
|
||||||
|
|
||||||
|
M: %prologue linearize-insn
|
||||||
|
2drop frame-size get [ _prologue ] when* ;
|
||||||
|
|
||||||
|
M: %epilogue linearize-insn
|
||||||
|
2drop frame-size get [ _epilogue ] when* ;
|
||||||
|
|
||||||
|
: useless-branch? ( basic-block successor -- ? )
|
||||||
|
#! If our successor immediately follows us in RPO, then we
|
||||||
|
#! don't need to branch.
|
||||||
|
[ number>> 1+ ] [ number>> ] bi* = ; inline
|
||||||
|
|
||||||
|
: branch-to-return? ( successor -- ? )
|
||||||
|
#! A branch to a block containing just a return is cloned.
|
||||||
|
instructions>> dup length 2 = [
|
||||||
|
[ first %epilogue? ] [ second %return? ] bi and
|
||||||
|
] [ drop f ] if ;
|
||||||
|
|
||||||
|
: emit-branch ( basic-block successor -- )
|
||||||
|
{
|
||||||
|
{ [ 2dup useless-branch? ] [ 2drop ] }
|
||||||
|
{ [ dup branch-to-return? ] [ nip linearize-insns ] }
|
||||||
|
[ nip label>> _branch ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
|
M: %branch linearize-insn
|
||||||
|
drop dup successors>> first emit-branch ;
|
||||||
|
|
||||||
|
: conditional ( basic-block -- basic-block successor1 label2 )
|
||||||
|
dup successors>> first2 swap label>> ; inline
|
||||||
|
|
||||||
|
: boolean-conditional ( basic-block insn -- basic-block successor vreg label2 )
|
||||||
|
[ conditional ] [ vreg>> ] bi* swap ; inline
|
||||||
|
|
||||||
|
M: %branch-f linearize-insn
|
||||||
|
boolean-conditional _branch-f emit-branch ;
|
||||||
|
|
||||||
|
M: %branch-t linearize-insn
|
||||||
|
boolean-conditional _branch-t emit-branch ;
|
||||||
|
|
||||||
|
M: %if-intrinsic linearize-insn
|
||||||
|
[ conditional ] [ [ quot>> ] [ vregs>> ] bi ] bi*
|
||||||
|
_if-intrinsic emit-branch ;
|
||||||
|
|
||||||
|
M: %boolean-intrinsic linearize-insn
|
||||||
|
[
|
||||||
|
"false" define-label
|
||||||
|
"end" define-label
|
||||||
|
"false" get over [ quot>> ] [ vregs>> ] bi _if-intrinsic
|
||||||
|
t over out>> %load-literal
|
||||||
|
"end" get _branch
|
||||||
|
"false" resolve-label
|
||||||
|
f over out>> %load-literal
|
||||||
|
"end" resolve-label
|
||||||
|
] with-scope
|
||||||
|
2drop ;
|
||||||
|
|
||||||
|
: linearize-basic-block ( bb -- )
|
||||||
|
[ label>> _label ] [ linearize-insns ] bi ;
|
||||||
|
|
||||||
|
: linearize-basic-blocks ( rpo -- insns )
|
||||||
|
[ [ linearize-basic-block ] each ] { } make ;
|
||||||
|
|
||||||
|
: build-mr ( cfg -- mr )
|
||||||
|
[
|
||||||
|
entry>> reverse-post-order [
|
||||||
|
[ compute-frame-size ]
|
||||||
|
[ linearize-basic-blocks ] bi
|
||||||
|
] with-scope
|
||||||
|
] [ word>> ] [ label>> ] tri <mr> ;
|
|
@ -0,0 +1,21 @@
|
||||||
|
! Copyright (C) 2008 Slava Pestov.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: kernel accessors namespaces make math sequences
|
||||||
|
compiler.instructions ;
|
||||||
|
IN: compiler.cfg.rpo
|
||||||
|
|
||||||
|
: post-order-traversal ( basic-block -- )
|
||||||
|
dup visited>> [ drop ] [
|
||||||
|
t >>visited
|
||||||
|
<label> >>label
|
||||||
|
[ successors>> [ post-order-traversal ] each ] [ , ] bi
|
||||||
|
] if ;
|
||||||
|
|
||||||
|
: post-order ( procedure -- blocks )
|
||||||
|
[ post-order-traversal ] { } make ;
|
||||||
|
|
||||||
|
: number-blocks ( blocks -- )
|
||||||
|
[ >>number drop ] each-index ;
|
||||||
|
|
||||||
|
: reverse-post-order ( procedure -- blocks )
|
||||||
|
post-order <reversed> dup number-blocks ; inline
|
|
@ -1,7 +1,7 @@
|
||||||
! 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: assocs accessors arrays kernel sequences
|
USING: assocs accessors arrays kernel sequences namespaces
|
||||||
compiler.instructions.syntax ;
|
math compiler.instructions.syntax ;
|
||||||
IN: compiler.instructions
|
IN: compiler.instructions
|
||||||
|
|
||||||
! Virtual CPU instructions, used by CFG and machine IRs
|
! Virtual CPU instructions, used by CFG and machine IRs
|
||||||
|
@ -17,9 +17,6 @@ INSN: %inc-r n ;
|
||||||
INSN: %load-literal obj vreg ;
|
INSN: %load-literal obj vreg ;
|
||||||
|
|
||||||
! Calling convention
|
! Calling convention
|
||||||
INSN: %prologue ;
|
|
||||||
INSN: %epilogue ;
|
|
||||||
INSN: %frame-required n ;
|
|
||||||
INSN: %return ;
|
INSN: %return ;
|
||||||
|
|
||||||
! Subroutine calls
|
! Subroutine calls
|
||||||
|
@ -31,15 +28,6 @@ INSN: %intrinsic quot vregs ;
|
||||||
INSN: %dispatch-label label ;
|
INSN: %dispatch-label label ;
|
||||||
INSN: %dispatch ;
|
INSN: %dispatch ;
|
||||||
|
|
||||||
! Unconditional branch to successor (CFG only)
|
|
||||||
INSN: %branch ;
|
|
||||||
|
|
||||||
! Conditional branches (CFG only)
|
|
||||||
INSN: %branch-f < %cond-branch ;
|
|
||||||
INSN: %branch-t < %cond-branch ;
|
|
||||||
INSN: %if-intrinsic quot vregs ;
|
|
||||||
INSN: %boolean-intrinsic quot vregs out ;
|
|
||||||
|
|
||||||
! Boxing and unboxing
|
! Boxing and unboxing
|
||||||
INSN: %copy < %unary ;
|
INSN: %copy < %unary ;
|
||||||
INSN: %copy-float < %unary ;
|
INSN: %copy-float < %unary ;
|
||||||
|
@ -64,9 +52,45 @@ M: insn uses-vregs drop f ;
|
||||||
M: %peek uses-vregs vreg>> 1array ;
|
M: %peek uses-vregs vreg>> 1array ;
|
||||||
M: %replace uses-vregs vreg>> 1array ;
|
M: %replace uses-vregs vreg>> 1array ;
|
||||||
M: %load-literal uses-vregs vreg>> 1array ;
|
M: %load-literal uses-vregs vreg>> 1array ;
|
||||||
M: %cond-branch uses-vregs vreg>> 1array ;
|
|
||||||
M: %unary uses-vregs [ dst>> ] [ src>> ] bi 2array ;
|
M: %unary uses-vregs [ dst>> ] [ src>> ] bi 2array ;
|
||||||
M: %intrinsic uses-vregs vregs>> values ;
|
M: %intrinsic uses-vregs vregs>> values ;
|
||||||
|
|
||||||
|
! Instructions used by CFG IR only.
|
||||||
|
INSN: %prologue ;
|
||||||
|
INSN: %epilogue ;
|
||||||
|
INSN: %frame-required n ;
|
||||||
|
|
||||||
|
INSN: %branch ;
|
||||||
|
INSN: %branch-f < %cond-branch ;
|
||||||
|
INSN: %branch-t < %cond-branch ;
|
||||||
|
INSN: %if-intrinsic quot vregs ;
|
||||||
|
INSN: %boolean-intrinsic quot vregs out ;
|
||||||
|
|
||||||
|
M: %cond-branch uses-vregs vreg>> 1array ;
|
||||||
M: %if-intrinsic uses-vregs vregs>> values ;
|
M: %if-intrinsic uses-vregs vregs>> values ;
|
||||||
M: %boolean-intrinsic uses-vregs
|
M: %boolean-intrinsic uses-vregs
|
||||||
[ vregs>> values ] [ out>> ] bi suffix ;
|
[ vregs>> values ] [ out>> ] bi suffix ;
|
||||||
|
|
||||||
|
! Instructions used by machine IR only.
|
||||||
|
INSN: _prologue n ;
|
||||||
|
INSN: _epilogue n ;
|
||||||
|
|
||||||
|
TUPLE: label id ;
|
||||||
|
|
||||||
|
INSN: _label label ;
|
||||||
|
|
||||||
|
: <label> ( -- label ) \ <label> counter label boa ;
|
||||||
|
: define-label ( name -- ) <label> swap set ;
|
||||||
|
|
||||||
|
: resolve-label ( label/name -- )
|
||||||
|
dup label? [ get ] unless _label ;
|
||||||
|
|
||||||
|
TUPLE: _cond-branch vreg label ;
|
||||||
|
|
||||||
|
INSN: _branch label ;
|
||||||
|
INSN: _branch-f < _cond-branch ;
|
||||||
|
INSN: _branch-t < _cond-branch ;
|
||||||
|
INSN: _if-intrinsic label quot vregs ;
|
||||||
|
|
||||||
|
M: _cond-branch uses-vregs vreg>> 1array ;
|
||||||
|
M: _if-intrinsic uses-vregs vregs>> values ;
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
|
||||||
USING: kernel math accessors sequences namespaces make
|
|
||||||
compiler.cfg compiler.instructions compiler.machine ;
|
|
||||||
IN: compiler.machine.builder
|
|
||||||
|
|
||||||
! Convert CFG IR to machine IR.
|
|
||||||
|
|
||||||
SYMBOL: block-counter
|
|
||||||
|
|
||||||
: number-basic-block ( basic-block -- )
|
|
||||||
#! Make this fancy later.
|
|
||||||
dup number>> [ drop ] [
|
|
||||||
<label> >>label
|
|
||||||
block-counter [ dup 1+ ] change >>number
|
|
||||||
[ , ] [
|
|
||||||
successors>> <reversed>
|
|
||||||
[ number-basic-block ] each
|
|
||||||
] bi
|
|
||||||
] if ;
|
|
||||||
|
|
||||||
: flatten-basic-blocks ( procedure -- blocks )
|
|
||||||
[
|
|
||||||
0 block-counter
|
|
||||||
[ number-basic-block ]
|
|
||||||
with-variable
|
|
||||||
] { } make ;
|
|
||||||
|
|
||||||
GENERIC: linearize* ( basic-block insn -- )
|
|
||||||
|
|
||||||
M: object linearize* , drop ;
|
|
||||||
|
|
||||||
M: %branch linearize*
|
|
||||||
drop successors>> first label>> _branch ;
|
|
||||||
|
|
||||||
: conditional ( basic-block -- label1 label2 )
|
|
||||||
successors>> first2 [ label>> ] bi@ swap ; inline
|
|
||||||
|
|
||||||
: boolean-conditional ( basic-block insn -- label1 vreg label2 )
|
|
||||||
[ conditional ] [ vreg>> ] bi* swap ; inline
|
|
||||||
|
|
||||||
M: %branch-f linearize*
|
|
||||||
boolean-conditional _branch-f _branch ;
|
|
||||||
|
|
||||||
M: %branch-t linearize*
|
|
||||||
boolean-conditional _branch-t _branch ;
|
|
||||||
|
|
||||||
M: %if-intrinsic linearize*
|
|
||||||
[ conditional ] [ [ quot>> ] [ vregs>> ] bi ] bi*
|
|
||||||
_if-intrinsic _branch ;
|
|
||||||
|
|
||||||
M: %boolean-intrinsic linearize*
|
|
||||||
[
|
|
||||||
"false" define-label
|
|
||||||
"end" define-label
|
|
||||||
"false" get over [ quot>> ] [ vregs>> ] bi _if-intrinsic
|
|
||||||
t over out>> %load-literal
|
|
||||||
"end" get _branch
|
|
||||||
"false" resolve-label
|
|
||||||
f over out>> %load-literal
|
|
||||||
"end" resolve-label
|
|
||||||
] with-scope
|
|
||||||
2drop ;
|
|
||||||
|
|
||||||
: build-machine ( procedure -- insns )
|
|
||||||
[
|
|
||||||
entry>> flatten-basic-blocks [
|
|
||||||
[ label>> _label ]
|
|
||||||
[ dup instructions>> [ linearize* ] with each ]
|
|
||||||
bi
|
|
||||||
] each
|
|
||||||
] { } make ;
|
|
|
@ -1,27 +0,0 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
|
||||||
USING: assocs accessors arrays namespaces kernel math
|
|
||||||
sequences compiler.instructions compiler.instructions.syntax ;
|
|
||||||
IN: compiler.machine
|
|
||||||
|
|
||||||
! Machine representation. Flat list of instructions, all
|
|
||||||
! registers allocated, with labels and jumps.
|
|
||||||
|
|
||||||
INSN: _prologue n ;
|
|
||||||
INSN: _epilogue n ;
|
|
||||||
|
|
||||||
INSN: _label label ;
|
|
||||||
|
|
||||||
: <label> ( -- label ) \ <label> counter ;
|
|
||||||
: define-label ( name -- ) <label> swap set ;
|
|
||||||
: resolve-label ( label/name -- ) dup integer? [ get ] unless _label ;
|
|
||||||
|
|
||||||
TUPLE: _cond-branch vreg label ;
|
|
||||||
|
|
||||||
INSN: _branch label ;
|
|
||||||
INSN: _branch-f < _cond-branch ;
|
|
||||||
INSN: _branch-t < _cond-branch ;
|
|
||||||
INSN: _if-intrinsic label quot vregs ;
|
|
||||||
|
|
||||||
M: _cond-branch uses-vregs vreg>> 1array ;
|
|
||||||
M: _if-intrinsic uses-vregs vregs>> values ;
|
|
|
@ -1,4 +0,0 @@
|
||||||
IN: compiler.machine.optimizer.tests
|
|
||||||
USING: compiler.machine.optimizer tools.test ;
|
|
||||||
|
|
||||||
\ optimize-machine must-infer
|
|
|
@ -1,39 +0,0 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
|
||||||
USING: kernel accessors math namespaces make sequences
|
|
||||||
sequences.next
|
|
||||||
compiler.instructions
|
|
||||||
compiler.instructions.syntax
|
|
||||||
compiler.machine ;
|
|
||||||
IN: compiler.machine.optimizer
|
|
||||||
|
|
||||||
: frame-required ( insns -- n/f )
|
|
||||||
[ %frame-required? ] filter
|
|
||||||
[ f ] [ [ n>> ] map supremum ] if-empty ;
|
|
||||||
|
|
||||||
GENERIC: optimize* ( next insn -- )
|
|
||||||
|
|
||||||
: useless-branch? ( next insn -- ? )
|
|
||||||
over _label? [ [ label>> ] bi@ = ] [ 2drop f ] if ;
|
|
||||||
|
|
||||||
M: _branch optimize*
|
|
||||||
#! Remove unconditional branches to labels immediately
|
|
||||||
#! following.
|
|
||||||
tuck useless-branch? [ drop ] [ , ] if ;
|
|
||||||
|
|
||||||
M: %prologue optimize*
|
|
||||||
2drop \ frame-required get [ _prologue ] when* ;
|
|
||||||
|
|
||||||
M: %epilogue optimize*
|
|
||||||
2drop \ frame-required get [ _epilogue ] when* ;
|
|
||||||
|
|
||||||
M: %frame-required optimize* 2drop ;
|
|
||||||
|
|
||||||
M: insn optimize* nip , ;
|
|
||||||
|
|
||||||
: optimize-machine ( insns -- insns )
|
|
||||||
[
|
|
||||||
[ frame-required \ frame-required set ]
|
|
||||||
[ [ optimize* ] each-next ]
|
|
||||||
bi
|
|
||||||
] { } make ;
|
|
Loading…
Reference in New Issue