compiler.cfg: Major restructuring -- do not compute liveness before local optimization, and instead change local optimizations to be more permissive of undefined values. Now, liveness is only computed once, after phi elimination and before register allocation. This means liveness analysis does not need to take phi nodes into account and can now use the new compiler.cfg.dataflow-analysis framework

db4
Slava Pestov 2009-07-22 03:08:28 -05:00
parent c105b033ef
commit 21a012e3d7
28 changed files with 170 additions and 263 deletions

View File

@ -3,8 +3,7 @@
USING: kernel math namespaces assocs hashtables sequences arrays USING: kernel math namespaces assocs hashtables sequences arrays
accessors vectors combinators sets classes compiler.cfg accessors vectors combinators sets classes compiler.cfg
compiler.cfg.registers compiler.cfg.instructions compiler.cfg.registers compiler.cfg.instructions
compiler.cfg.copy-prop compiler.cfg.rpo compiler.cfg.copy-prop compiler.cfg.rpo compiler.cfg.def-use ;
compiler.cfg.liveness compiler.cfg.local ;
IN: compiler.cfg.alias-analysis IN: compiler.cfg.alias-analysis
! We try to eliminate redundant slot operations using some simple heuristics. ! We try to eliminate redundant slot operations using some simple heuristics.
@ -197,7 +196,10 @@ M: ##set-slot insn-object obj>> resolve ;
M: ##set-slot-imm insn-object obj>> resolve ; M: ##set-slot-imm insn-object obj>> resolve ;
M: ##alien-global insn-object drop \ ##alien-global ; M: ##alien-global insn-object drop \ ##alien-global ;
: init-alias-analysis ( live-in -- ) : inputs ( insns -- seq )
[ [ ##phi? not ] filter gen-set ] [ kill-set ] bi assoc-diff keys ;
: init-alias-analysis ( insns -- insns' )
H{ } clone histories set H{ } clone histories set
H{ } clone vregs>acs set H{ } clone vregs>acs set
H{ } clone acs>vregs set H{ } clone acs>vregs set
@ -208,7 +210,7 @@ M: ##alien-global insn-object drop \ ##alien-global ;
0 ac-counter set 0 ac-counter set
next-ac heap-ac set next-ac heap-ac set
[ set-heap-ac ] each ; dup inputs [ set-heap-ac ] each ;
GENERIC: analyze-aliases* ( insn -- insn' ) GENERIC: analyze-aliases* ( insn -- insn' )
@ -280,9 +282,10 @@ M: insn eliminate-dead-stores* ;
[ insn# set eliminate-dead-stores* ] map-index sift ; [ insn# set eliminate-dead-stores* ] map-index sift ;
: alias-analysis-step ( insns -- insns' ) : alias-analysis-step ( insns -- insns' )
init-alias-analysis
analyze-aliases analyze-aliases
compute-live-stores compute-live-stores
eliminate-dead-stores ; eliminate-dead-stores ;
: alias-analysis ( cfg -- cfg' ) : alias-analysis ( cfg -- cfg' )
[ init-alias-analysis ] [ alias-analysis-step ] local-optimization ; [ alias-analysis-step ] local-optimization ;

View File

@ -1,7 +1,7 @@
! Copyright (C) 2009 Slava Pestov. ! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel compiler.cfg.instructions compiler.cfg.rpo USING: kernel compiler.cfg.instructions compiler.cfg.rpo
compiler.cfg.def-use compiler.cfg.linearization compiler.cfg.liveness compiler.cfg.def-use compiler.cfg.linearization
combinators.short-circuit accessors math sequences sets assocs ; combinators.short-circuit accessors math sequences sets assocs ;
IN: compiler.cfg.checker IN: compiler.cfg.checker
@ -54,8 +54,6 @@ ERROR: undefined-values uses defs ;
2dup subset? [ 2drop ] [ undefined-values ] if ; 2dup subset? [ 2drop ] [ undefined-values ] if ;
: check-cfg ( cfg -- ) : check-cfg ( cfg -- )
compute-liveness
[ entry>> live-in assoc-empty? [ bad-live-in ] unless ]
[ [ check-basic-block ] each-basic-block ] [ [ check-basic-block ] each-basic-block ]
[ flatten-cfg check-mr ] [ flatten-cfg check-mr ]
tri ; bi ;

View File

@ -20,7 +20,7 @@ MIXIN: dataflow-analysis
GENERIC# compute-in-set 2 ( bb out-sets dfa -- set ) GENERIC# compute-in-set 2 ( bb out-sets dfa -- set )
M: kill-block compute-in-set 3drop f ; ! M: kill-block compute-in-set 3drop f ;
M:: basic-block compute-in-set ( bb out-sets dfa -- set ) M:: basic-block compute-in-set ( bb out-sets dfa -- set )
bb dfa predecessors [ out-sets at ] map dfa join-sets ; bb dfa predecessors [ out-sets at ] map dfa join-sets ;
@ -31,7 +31,7 @@ M:: basic-block compute-in-set ( bb out-sets dfa -- set )
GENERIC# compute-out-set 2 ( bb out-sets dfa -- set ) GENERIC# compute-out-set 2 ( bb out-sets dfa -- set )
M: kill-block compute-out-set 3drop f ; ! M: kill-block compute-out-set 3drop f ;
M:: basic-block compute-out-set ( bb in-sets dfa -- set ) M:: basic-block compute-out-set ( bb in-sets dfa -- set )
bb in-sets at bb dfa transfer-set ; bb in-sets at bb dfa transfer-set ;

View File

@ -7,7 +7,7 @@ parser compiler.tree.builder compiler.tree.optimizer
compiler.cfg.builder compiler.cfg.linearization compiler.cfg.builder compiler.cfg.linearization
compiler.cfg.registers compiler.cfg.stack-frame compiler.cfg.registers compiler.cfg.stack-frame
compiler.cfg.linear-scan compiler.cfg.two-operand compiler.cfg.linear-scan compiler.cfg.two-operand
compiler.cfg.liveness compiler.cfg.optimizer compiler.cfg.optimizer
compiler.cfg.mr compiler.cfg ; compiler.cfg.mr compiler.cfg ;
IN: compiler.cfg.debugger IN: compiler.cfg.debugger

View File

@ -1,6 +1,7 @@
! Copyright (C) 2008, 2009 Slava Pestov. ! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays kernel assocs compiler.cfg.instructions ; USING: accessors arrays kernel assocs sequences
sets compiler.cfg.instructions ;
IN: compiler.cfg.def-use IN: compiler.cfg.def-use
GENERIC: defs-vregs ( insn -- seq ) GENERIC: defs-vregs ( insn -- seq )
@ -62,3 +63,12 @@ UNION: vreg-insn
_conditional-branch _conditional-branch
_compare-imm-branch _compare-imm-branch
_dispatch ; _dispatch ;
: map-unique ( seq quot -- assoc )
map concat unique ; inline
: gen-set ( instructions -- seq )
[ uses-vregs ] map-unique ;
: kill-set ( instructions -- seq )
[ defs-vregs ] map-unique ;

View File

@ -4,14 +4,15 @@ USING: accessors kernel math assocs namespaces sequences heaps
fry make combinators sets locals fry make combinators sets locals
cpu.architecture cpu.architecture
compiler.cfg compiler.cfg
compiler.cfg.rpo
compiler.cfg.def-use compiler.cfg.def-use
compiler.cfg.liveness
compiler.cfg.registers compiler.cfg.registers
compiler.cfg.instructions compiler.cfg.instructions
compiler.cfg.linear-scan.mapping compiler.cfg.linear-scan.mapping
compiler.cfg.linear-scan.allocation compiler.cfg.linear-scan.allocation
compiler.cfg.linear-scan.allocation.state compiler.cfg.linear-scan.allocation.state
compiler.cfg.linear-scan.live-intervals ; compiler.cfg.linear-scan.live-intervals
compiler.cfg.linear-scan.liveness ;
IN: compiler.cfg.linear-scan.assignment IN: compiler.cfg.linear-scan.assignment
! This contains both active and inactive intervals; any interval ! This contains both active and inactive intervals; any interval
@ -185,6 +186,6 @@ ERROR: bad-vreg vreg ;
] V{ } make ] V{ } make
] change-instructions drop ; ] change-instructions drop ;
: assign-registers ( live-intervals rpo -- ) : assign-registers ( live-intervals cfg -- )
[ init-assignment ] dip [ init-assignment ] dip
[ assign-registers-in-block ] each ; [ assign-registers-in-block ] each-basic-block ;

View File

@ -7,7 +7,6 @@ compiler.cfg
compiler.cfg.optimizer compiler.cfg.optimizer
compiler.cfg.instructions compiler.cfg.instructions
compiler.cfg.registers compiler.cfg.registers
compiler.cfg.liveness
compiler.cfg.predecessors compiler.cfg.predecessors
compiler.cfg.rpo compiler.cfg.rpo
compiler.cfg.linearization compiler.cfg.linearization
@ -1507,9 +1506,7 @@ SYMBOL: linear-scan-result
[ [
cfg new 0 get >>entry cfg new 0 get >>entry
compute-predecessors compute-predecessors
compute-liveness dup { { int-regs regs } } (linear-scan)
dup reverse-post-order
{ { int-regs regs } } (linear-scan)
cfg-changed cfg-changed
flatten-cfg 1array mr. flatten-cfg 1array mr.
] with-scope ; ] with-scope ;
@ -2331,9 +2328,6 @@ test-diamond
! early in bootstrap on x86-32 ! early in bootstrap on x86-32
[ t ] [ [ t ] [
[ [
H{ } clone live-ins set
H{ } clone live-outs set
H{ } clone phi-live-ins set
T{ basic-block T{ basic-block
{ id 12345 } { id 12345 }
{ instructions { instructions
@ -2353,7 +2347,8 @@ test-diamond
T{ ##replace f V int-regs 5 D 0 } T{ ##replace f V int-regs 5 D 0 }
} }
} }
} dup 1array { { int-regs V{ 0 1 2 3 } } } (linear-scan) } cfg new over >>entry
{ { int-regs V{ 0 1 2 3 } } } (linear-scan)
instructions>> first instructions>> first
live-values>> assoc-empty? live-values>> assoc-empty?
] with-scope ] with-scope

View File

@ -6,6 +6,7 @@ compiler.cfg
compiler.cfg.rpo compiler.cfg.rpo
compiler.cfg.instructions compiler.cfg.instructions
compiler.cfg.linear-scan.numbering compiler.cfg.linear-scan.numbering
compiler.cfg.linear-scan.liveness
compiler.cfg.linear-scan.live-intervals compiler.cfg.linear-scan.live-intervals
compiler.cfg.linear-scan.allocation compiler.cfg.linear-scan.allocation
compiler.cfg.linear-scan.allocation.state compiler.cfg.linear-scan.allocation.state
@ -28,17 +29,18 @@ IN: compiler.cfg.linear-scan
! by Omri Traub, Glenn Holloway, Michael D. Smith ! by Omri Traub, Glenn Holloway, Michael D. Smith
! http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.8435 ! http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.8435
:: (linear-scan) ( rpo machine-registers -- ) :: (linear-scan) ( cfg machine-registers -- )
rpo number-instructions cfg compute-live-sets
rpo compute-live-intervals machine-registers allocate-registers cfg number-instructions
rpo assign-registers cfg compute-live-intervals machine-registers allocate-registers
rpo resolve-data-flow cfg assign-registers
rpo check-numbering ; cfg resolve-data-flow
cfg check-numbering ;
: linear-scan ( cfg -- cfg' ) : linear-scan ( cfg -- cfg' )
[ [
init-mapping init-mapping
dup reverse-post-order machine-registers (linear-scan) dup machine-registers (linear-scan)
spill-counts get >>spill-counts spill-counts get >>spill-counts
cfg-changed cfg-changed
] with-scope ; ] with-scope ;

View File

@ -2,7 +2,8 @@
! 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 math.order fry USING: namespaces kernel assocs accessors sequences math math.order fry
combinators binary-search compiler.cfg.instructions compiler.cfg.registers combinators binary-search compiler.cfg.instructions compiler.cfg.registers
compiler.cfg.def-use compiler.cfg.liveness compiler.cfg ; compiler.cfg.def-use compiler.cfg.linear-scan.liveness compiler.cfg.rpo
compiler.cfg ;
IN: compiler.cfg.linear-scan.live-intervals IN: compiler.cfg.linear-scan.live-intervals
TUPLE: live-range from to ; TUPLE: live-range from to ;
@ -144,10 +145,10 @@ ERROR: bad-live-interval live-interval ;
} cleave } cleave
] each ; ] each ;
: compute-live-intervals ( rpo -- live-intervals ) : compute-live-intervals ( cfg -- live-intervals )
H{ } clone [ H{ } clone [
live-intervals set live-intervals set
<reversed> [ compute-live-intervals-step ] each post-order [ compute-live-intervals-step ] each
] keep values dup finish-live-intervals ; ] keep values dup finish-live-intervals ;
: relevant-ranges ( interval1 interval2 -- ranges1 ranges2 ) : relevant-ranges ( interval1 interval2 -- ranges1 ranges2 )

View File

@ -0,0 +1,17 @@
! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel accessors assocs compiler.cfg.def-use
compiler.cfg.dataflow-analysis ;
IN: compiler.cfg.linear-scan.liveness
! See http://en.wikipedia.org/wiki/Liveness_analysis
BACKWARD-ANALYSIS: live
M: live-analysis transfer-set
drop instructions>>
[ gen-set assoc-union ] keep
kill-set assoc-diff ;
M: live-analysis join-sets
drop assoc-combine ;

View File

@ -1,6 +1,7 @@
! Copyright (C) 2009 Slava Pestov. ! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel accessors math sequences grouping namespaces ; USING: kernel accessors math sequences grouping namespaces
compiler.cfg.rpo ;
IN: compiler.cfg.linear-scan.numbering IN: compiler.cfg.linear-scan.numbering
: number-instructions ( rpo -- ) : number-instructions ( rpo -- )
@ -8,7 +9,7 @@ IN: compiler.cfg.linear-scan.numbering
instructions>> [ instructions>> [
[ (>>insn#) ] [ drop 2 + ] 2bi [ (>>insn#) ] [ drop 2 + ] 2bi
] each ] each
] each drop ; ] each-basic-block drop ;
SYMBOL: check-numbering? SYMBOL: check-numbering?
@ -18,5 +19,5 @@ ERROR: bad-numbering bb ;
dup instructions>> [ insn#>> ] map sift [ <= ] monotonic? dup instructions>> [ insn#>> ] map sift [ <= ] monotonic?
[ drop ] [ bad-numbering ] if ; [ drop ] [ bad-numbering ] if ;
: check-numbering ( rpo -- ) : check-numbering ( cfg -- )
check-numbering? get [ [ check-block-numbering ] each ] [ drop ] if ; check-numbering? get [ [ check-block-numbering ] each-basic-block ] [ drop ] if ;

View File

@ -3,10 +3,12 @@
USING: accessors arrays assocs combinators USING: accessors arrays assocs combinators
combinators.short-circuit fry kernel locals combinators.short-circuit fry kernel locals
make math sequences make math sequences
compiler.cfg.rpo
compiler.cfg.utilities compiler.cfg.utilities
compiler.cfg.instructions compiler.cfg.instructions
compiler.cfg.linear-scan.assignment compiler.cfg.linear-scan.assignment
compiler.cfg.linear-scan.mapping compiler.cfg.liveness ; compiler.cfg.linear-scan.mapping
compiler.cfg.linear-scan.liveness ;
IN: compiler.cfg.linear-scan.resolve IN: compiler.cfg.linear-scan.resolve
: add-mapping ( from to reg-class -- ) : add-mapping ( from to reg-class -- )
@ -43,5 +45,5 @@ IN: compiler.cfg.linear-scan.resolve
: resolve-block-data-flow ( bb -- ) : resolve-block-data-flow ( bb -- )
dup successors>> [ resolve-edge-data-flow ] with each ; dup successors>> [ resolve-edge-data-flow ] with each ;
: resolve-data-flow ( rpo -- ) : resolve-data-flow ( cfg -- )
[ resolve-block-data-flow ] each ; [ resolve-block-data-flow ] each-basic-block ;

View File

@ -4,7 +4,6 @@ USING: kernel math accessors sequences namespaces make
combinators assocs arrays locals cpu.architecture combinators assocs arrays locals cpu.architecture
compiler.cfg compiler.cfg
compiler.cfg.rpo compiler.cfg.rpo
compiler.cfg.liveness
compiler.cfg.comparisons compiler.cfg.comparisons
compiler.cfg.stack-frame compiler.cfg.stack-frame
compiler.cfg.instructions ; compiler.cfg.instructions ;

View File

@ -1 +0,0 @@
Slava Pestov

View File

@ -1,15 +0,0 @@
USING: compiler.cfg compiler.cfg.instructions compiler.cfg.registers
compiler.cfg.liveness accessors tools.test cpu.architecture ;
IN: compiler.cfg.liveness.tests
[
H{
{ "A" H{ { V int-regs 1 V int-regs 1 } { V int-regs 4 V int-regs 4 } } }
{ "B" H{ { V int-regs 3 V int-regs 3 } { V int-regs 2 V int-regs 2 } } }
}
] [
<basic-block> V{
T{ ##phi f V int-regs 0 { { "A" V int-regs 1 } { "B" V int-regs 2 } } }
T{ ##phi f V int-regs 1 { { "B" V int-regs 3 } { "A" V int-regs 4 } } }
} >>instructions compute-phi-live-in
] unit-test

View File

@ -1,79 +0,0 @@
! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel namespaces deques accessors sets sequences assocs fry
hashtables dlists compiler.cfg.def-use compiler.cfg.instructions
compiler.cfg.rpo ;
IN: compiler.cfg.liveness
! This is a backward dataflow analysis. See http://en.wikipedia.org/wiki/Liveness_analysis
! Assoc mapping basic blocks to sets of vregs
SYMBOL: live-ins
: live-in ( basic-block -- set ) live-ins get at ;
! Assoc mapping basic blocks to sequences of sets of vregs; each sequence
! is in conrrespondence with a predecessor
SYMBOL: phi-live-ins
: phi-live-in ( predecessor basic-block -- set ) phi-live-ins get at at ;
! Assoc mapping basic blocks to sets of vregs
SYMBOL: live-outs
: live-out ( basic-block -- set ) live-outs get at ;
SYMBOL: work-list
: add-to-work-list ( basic-blocks -- )
work-list get '[ _ push-front ] each ;
: map-unique ( seq quot -- assoc )
map concat unique ; inline
: gen-set ( instructions -- seq )
[ ##phi? not ] filter [ uses-vregs ] map-unique ;
: kill-set ( instructions -- seq )
[ [ defs-vregs ] [ temp-vregs ] bi append ] map-unique ;
: compute-live-in ( basic-block -- live-in )
dup instructions>>
[ [ live-out ] [ gen-set ] bi* assoc-union ]
[ nip kill-set ]
2bi assoc-diff ;
: compute-phi-live-in ( basic-block -- phi-live-in )
instructions>> [ ##phi? ] filter [ f ] [
H{ } clone [
'[ inputs>> [ swap _ conjoin-at ] assoc-each ] each
] keep
] if-empty ;
: update-live-in ( basic-block -- changed? )
[ [ compute-live-in ] keep live-ins get maybe-set-at ]
[ [ compute-phi-live-in ] keep phi-live-ins get maybe-set-at ]
bi and ;
: compute-live-out ( basic-block -- live-out )
[ successors>> [ live-in ] map ]
[ dup successors>> [ phi-live-in ] with map ] bi
append assoc-combine ;
: update-live-out ( basic-block -- changed? )
[ compute-live-out ] keep
live-outs get maybe-set-at ;
: liveness-step ( basic-block -- )
dup update-live-out [
dup update-live-in
[ predecessors>> add-to-work-list ] [ drop ] if
] [ drop ] if ;
: compute-liveness ( cfg -- cfg' )
<hashed-dlist> work-list set
H{ } clone live-ins set
H{ } clone phi-live-ins set
H{ } clone live-outs set
dup post-order add-to-work-list
work-list get [ liveness-step ] slurp-deque ;

View File

@ -1 +0,0 @@
Slava Pestov

View File

@ -1,14 +0,0 @@
! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: locals accessors kernel assocs namespaces
compiler.cfg compiler.cfg.liveness compiler.cfg.rpo ;
IN: compiler.cfg.local
:: optimize-basic-block ( bb init-quot insn-quot -- )
bb basic-block set
bb live-in keys init-quot call
bb insn-quot change-instructions drop ; inline
:: local-optimization ( cfg init-quot: ( live-in -- ) insn-quot: ( insns -- insns' ) -- cfg' )
cfg [ init-quot insn-quot optimize-basic-block ] each-basic-block
cfg ; inline

View File

@ -1,13 +1,12 @@
! Copyright (C) 2009 Slava Pestov. ! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: compiler.cfg.linearization compiler.cfg.two-operand USING: compiler.cfg.linearization compiler.cfg.two-operand
compiler.cfg.liveness compiler.cfg.gc-checks compiler.cfg.linear-scan compiler.cfg.gc-checks compiler.cfg.linear-scan
compiler.cfg.build-stack-frame compiler.cfg.rpo ; compiler.cfg.build-stack-frame compiler.cfg.rpo ;
IN: compiler.cfg.mr IN: compiler.cfg.mr
: build-mr ( cfg -- mr ) : build-mr ( cfg -- mr )
convert-two-operand convert-two-operand
compute-liveness
insert-gc-checks insert-gc-checks
linear-scan linear-scan
flatten-cfg flatten-cfg

View File

@ -11,7 +11,6 @@ compiler.cfg.alias-analysis
compiler.cfg.value-numbering compiler.cfg.value-numbering
compiler.cfg.dce compiler.cfg.dce
compiler.cfg.write-barrier compiler.cfg.write-barrier
compiler.cfg.liveness
compiler.cfg.rpo compiler.cfg.rpo
compiler.cfg.phi-elimination compiler.cfg.phi-elimination
compiler.cfg.checker ; compiler.cfg.checker ;
@ -35,7 +34,6 @@ SYMBOL: check-optimizer?
join-blocks join-blocks
compute-predecessors compute-predecessors
stack-analysis stack-analysis
compute-liveness
alias-analysis alias-analysis
value-numbering value-numbering
compute-predecessors compute-predecessors

View File

@ -6,7 +6,7 @@ IN: compiler.cfg.renaming
SYMBOL: renamings SYMBOL: renamings
: rename-value ( vreg -- vreg' ) renamings get at ; : rename-value ( vreg -- vreg' ) renamings get ?at drop ;
GENERIC: rename-insn-defs ( insn -- ) GENERIC: rename-insn-defs ( insn -- )

View File

@ -33,3 +33,10 @@ SYMBOL: visited
: each-basic-block ( cfg quot -- ) : each-basic-block ( cfg quot -- )
[ reverse-post-order ] dip each ; inline [ reverse-post-order ] dip each ; inline
: optimize-basic-block ( bb quot -- )
[ drop basic-block set ]
[ change-instructions drop ] 2bi ; inline
: local-optimization ( cfg quot: ( insns -- insns' ) -- cfg' )
dupd '[ _ optimize-basic-block ] each-basic-block ; inline

View File

@ -1,7 +1,7 @@
! Copyright (C) 2008, 2009 Slava Pestov. ! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors kernel sequences make compiler.cfg.instructions USING: accessors kernel sequences make compiler.cfg.instructions
compiler.cfg.local cpu.architecture ; compiler.cfg.rpo cpu.architecture ;
IN: compiler.cfg.two-operand IN: compiler.cfg.two-operand
! On x86, instructions take the form x = x op y ! On x86, instructions take the form x = x op y
@ -54,7 +54,6 @@ M: insn convert-two-operand* , ;
: convert-two-operand ( cfg -- cfg' ) : convert-two-operand ( cfg -- cfg' )
two-operand? [ two-operand? [
[ drop ]
[ [ [ convert-two-operand* ] each ] V{ } make ] [ [ [ convert-two-operand* ] each ] V{ } make ]
local-optimization local-optimization
] when ; ] when ;

View File

@ -6,7 +6,6 @@ compiler.cfg.value-numbering.graph ;
IN: compiler.cfg.value-numbering.expressions IN: compiler.cfg.value-numbering.expressions
! Referentially-transparent expressions ! Referentially-transparent expressions
TUPLE: expr op ;
TUPLE: unary-expr < expr in ; TUPLE: unary-expr < expr in ;
TUPLE: binary-expr < expr in1 in2 ; TUPLE: binary-expr < expr in1 in2 ;
TUPLE: commutative-expr < binary-expr ; TUPLE: commutative-expr < binary-expr ;
@ -37,17 +36,6 @@ M: reference-expr equal?
} cond } cond
] [ 2drop f ] if ; ] [ 2drop f ] if ;
! Expressions whose values are inputs to the basic block. We
! can eliminate a second computation having the same 'n' as
! the first one; we can also eliminate input-exprs whose
! result is not used.
TUPLE: input-expr < expr n ;
SYMBOL: input-expr-counter
: next-input-expr ( class -- expr )
input-expr-counter [ dup 1 + ] change input-expr boa ;
: constant>vn ( constant -- vn ) <constant> expr>vn ; inline : constant>vn ( constant -- vn ) <constant> expr>vn ; inline
GENERIC: >expr ( insn -- expr ) GENERIC: >expr ( insn -- expr )
@ -97,7 +85,7 @@ M: ##compare-imm >expr compare-imm>expr ;
M: ##compare-float >expr compare>expr ; M: ##compare-float >expr compare>expr ;
M: ##flushable >expr class next-input-expr ; M: ##flushable >expr drop next-input-expr ;
: init-expressions ( -- ) : init-expressions ( -- )
0 input-expr-counter set ; 0 input-expr-counter set ;

View File

@ -10,13 +10,24 @@ SYMBOL: vn-counter
! biassoc mapping expressions to value numbers ! biassoc mapping expressions to value numbers
SYMBOL: exprs>vns SYMBOL: exprs>vns
TUPLE: expr op ;
: expr>vn ( expr -- vn ) exprs>vns get [ drop next-vn ] cache ; : expr>vn ( expr -- vn ) exprs>vns get [ drop next-vn ] cache ;
: vn>expr ( vn -- expr ) exprs>vns get value-at ; : vn>expr ( vn -- expr ) exprs>vns get value-at ;
! Expressions whose values are inputs to the basic block.
TUPLE: input-expr < expr n ;
SYMBOL: input-expr-counter
: next-input-expr ( -- expr )
f input-expr-counter counter input-expr boa ;
SYMBOL: vregs>vns SYMBOL: vregs>vns
: vreg>vn ( vreg -- vn ) vregs>vns get at ; : vreg>vn ( vreg -- vn )
vregs>vns get [ drop next-input-expr expr>vn ] cache ;
: vn>vreg ( vn -- vreg ) vregs>vns get value-at ; : vn>vreg ( vn -- vreg ) vregs>vns get value-at ;

View File

@ -3,7 +3,7 @@ USING: compiler.cfg.value-numbering compiler.cfg.instructions
compiler.cfg.registers compiler.cfg.debugger compiler.cfg.comparisons compiler.cfg.registers compiler.cfg.debugger compiler.cfg.comparisons
cpu.architecture tools.test kernel math combinators.short-circuit cpu.architecture tools.test kernel math combinators.short-circuit
accessors sequences compiler.cfg.predecessors locals accessors sequences compiler.cfg.predecessors locals
compiler.cfg.phi-elimination compiler.cfg.dce compiler.cfg.liveness compiler.cfg.phi-elimination compiler.cfg.dce
compiler.cfg assocs vectors arrays layouts namespaces ; compiler.cfg assocs vectors arrays layouts namespaces ;
: trim-temps ( insns -- insns ) : trim-temps ( insns -- insns )
@ -15,10 +15,6 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
} 1|| [ f >>temp ] when } 1|| [ f >>temp ] when
] map ; ] map ;
: test-value-numbering ( insns -- insns )
{ } init-value-numbering
value-numbering-step ;
! Folding constants together ! Folding constants together
[ [
{ {
@ -33,7 +29,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##load-reference f V int-regs 1 -0.0 } T{ ##load-reference f V int-regs 1 -0.0 }
T{ ##replace f V int-regs 0 D 0 } T{ ##replace f V int-regs 0 D 0 }
T{ ##replace f V int-regs 1 D 1 } T{ ##replace f V int-regs 1 D 1 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -49,7 +45,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##load-reference f V int-regs 1 0.0 } T{ ##load-reference f V int-regs 1 0.0 }
T{ ##replace f V int-regs 0 D 0 } T{ ##replace f V int-regs 0 D 0 }
T{ ##replace f V int-regs 1 D 1 } T{ ##replace f V int-regs 1 D 1 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -65,7 +61,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##load-reference f V int-regs 1 t } T{ ##load-reference f V int-regs 1 t }
T{ ##replace f V int-regs 0 D 0 } T{ ##replace f V int-regs 0 D 0 }
T{ ##replace f V int-regs 1 D 1 } T{ ##replace f V int-regs 1 D 1 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
! Copy propagation ! Copy propagation
@ -80,7 +76,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 45 D 1 } T{ ##peek f V int-regs 45 D 1 }
T{ ##copy f V int-regs 48 V int-regs 45 } T{ ##copy f V int-regs 48 V int-regs 45 }
T{ ##compare-imm-branch f V int-regs 48 7 cc/= } T{ ##compare-imm-branch f V int-regs 48 7 cc/= }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
! Compare propagation ! Compare propagation
@ -99,7 +95,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##compare f V int-regs 4 V int-regs 2 V int-regs 1 cc> } T{ ##compare f V int-regs 4 V int-regs 2 V int-regs 1 cc> }
T{ ##compare-imm f V int-regs 6 V int-regs 4 5 cc/= } T{ ##compare-imm f V int-regs 6 V int-regs 4 5 cc/= }
T{ ##replace f V int-regs 6 D 0 } T{ ##replace f V int-regs 6 D 0 }
} test-value-numbering trim-temps } value-numbering-step trim-temps
] unit-test ] unit-test
[ [
@ -117,7 +113,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##compare f V int-regs 4 V int-regs 2 V int-regs 1 cc<= } T{ ##compare f V int-regs 4 V int-regs 2 V int-regs 1 cc<= }
T{ ##compare-imm f V int-regs 6 V int-regs 4 5 cc= } T{ ##compare-imm f V int-regs 6 V int-regs 4 5 cc= }
T{ ##replace f V int-regs 6 D 0 } T{ ##replace f V int-regs 6 D 0 }
} test-value-numbering trim-temps } value-numbering-step trim-temps
] unit-test ] unit-test
[ [
@ -139,7 +135,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##compare-float f V int-regs 12 V double-float-regs 10 V double-float-regs 11 cc< } T{ ##compare-float f V int-regs 12 V double-float-regs 10 V double-float-regs 11 cc< }
T{ ##compare-imm f V int-regs 14 V int-regs 12 5 cc= } T{ ##compare-imm f V int-regs 14 V int-regs 12 5 cc= }
T{ ##replace f V int-regs 14 D 0 } T{ ##replace f V int-regs 14 D 0 }
} test-value-numbering trim-temps } value-numbering-step trim-temps
] unit-test ] unit-test
[ [
@ -155,7 +151,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 30 D -2 } T{ ##peek f V int-regs 30 D -2 }
T{ ##compare f V int-regs 33 V int-regs 29 V int-regs 30 cc<= } T{ ##compare f V int-regs 33 V int-regs 29 V int-regs 30 cc<= }
T{ ##compare-imm-branch f V int-regs 33 5 cc/= } T{ ##compare-imm-branch f V int-regs 33 5 cc/= }
} test-value-numbering trim-temps } value-numbering-step trim-temps
] unit-test ] unit-test
! Immediate operand conversion ! Immediate operand conversion
@ -170,7 +166,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##add f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##add f V int-regs 2 V int-regs 0 V int-regs 1 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -184,7 +180,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##add f V int-regs 2 V int-regs 1 V int-regs 0 } T{ ##add f V int-regs 2 V int-regs 1 V int-regs 0 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -198,7 +194,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##sub f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##sub f V int-regs 2 V int-regs 0 V int-regs 1 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -210,7 +206,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
{ {
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##sub f V int-regs 1 V int-regs 0 V int-regs 0 } T{ ##sub f V int-regs 1 V int-regs 0 V int-regs 0 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -224,7 +220,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##mul f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##mul f V int-regs 2 V int-regs 0 V int-regs 1 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -238,7 +234,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##mul f V int-regs 2 V int-regs 1 V int-regs 0 } T{ ##mul f V int-regs 2 V int-regs 1 V int-regs 0 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -250,7 +246,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
{ {
T{ ##peek f V int-regs 1 D 0 } T{ ##peek f V int-regs 1 D 0 }
T{ ##mul-imm f V int-regs 2 V int-regs 1 8 } T{ ##mul-imm f V int-regs 2 V int-regs 1 8 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -264,7 +260,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##and f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##and f V int-regs 2 V int-regs 0 V int-regs 1 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -278,7 +274,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##and f V int-regs 2 V int-regs 1 V int-regs 0 } T{ ##and f V int-regs 2 V int-regs 1 V int-regs 0 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -292,7 +288,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##or f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##or f V int-regs 2 V int-regs 0 V int-regs 1 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -306,7 +302,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##or f V int-regs 2 V int-regs 1 V int-regs 0 } T{ ##or f V int-regs 2 V int-regs 1 V int-regs 0 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -320,7 +316,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##xor f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##xor f V int-regs 2 V int-regs 0 V int-regs 1 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -334,7 +330,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##xor f V int-regs 2 V int-regs 1 V int-regs 0 } T{ ##xor f V int-regs 2 V int-regs 1 V int-regs 0 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -348,7 +344,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##compare f V int-regs 2 V int-regs 0 V int-regs 1 cc<= } T{ ##compare f V int-regs 2 V int-regs 0 V int-regs 1 cc<= }
} test-value-numbering trim-temps } value-numbering-step trim-temps
] unit-test ] unit-test
[ [
@ -362,7 +358,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##compare f V int-regs 2 V int-regs 1 V int-regs 0 cc<= } T{ ##compare f V int-regs 2 V int-regs 1 V int-regs 0 cc<= }
} test-value-numbering trim-temps } value-numbering-step trim-temps
] unit-test ] unit-test
[ [
@ -376,7 +372,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##compare-branch f V int-regs 0 V int-regs 1 cc<= } T{ ##compare-branch f V int-regs 0 V int-regs 1 cc<= }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -390,7 +386,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 100 } T{ ##load-immediate f V int-regs 1 100 }
T{ ##compare-branch f V int-regs 1 V int-regs 0 cc<= } T{ ##compare-branch f V int-regs 1 V int-regs 0 cc<= }
} test-value-numbering trim-temps } value-numbering-step trim-temps
] unit-test ] unit-test
! Reassociation ! Reassociation
@ -409,7 +405,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##add f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##add f V int-regs 2 V int-regs 0 V int-regs 1 }
T{ ##load-immediate f V int-regs 3 50 } T{ ##load-immediate f V int-regs 3 50 }
T{ ##add f V int-regs 4 V int-regs 2 V int-regs 3 } T{ ##add f V int-regs 4 V int-regs 2 V int-regs 3 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -427,7 +423,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##add f V int-regs 2 V int-regs 1 V int-regs 0 } T{ ##add f V int-regs 2 V int-regs 1 V int-regs 0 }
T{ ##load-immediate f V int-regs 3 50 } T{ ##load-immediate f V int-regs 3 50 }
T{ ##add f V int-regs 4 V int-regs 3 V int-regs 2 } T{ ##add f V int-regs 4 V int-regs 3 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -445,7 +441,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##add f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##add f V int-regs 2 V int-regs 0 V int-regs 1 }
T{ ##load-immediate f V int-regs 3 50 } T{ ##load-immediate f V int-regs 3 50 }
T{ ##sub f V int-regs 4 V int-regs 2 V int-regs 3 } T{ ##sub f V int-regs 4 V int-regs 2 V int-regs 3 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -463,7 +459,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##sub f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##sub f V int-regs 2 V int-regs 0 V int-regs 1 }
T{ ##load-immediate f V int-regs 3 50 } T{ ##load-immediate f V int-regs 3 50 }
T{ ##sub f V int-regs 4 V int-regs 2 V int-regs 3 } T{ ##sub f V int-regs 4 V int-regs 2 V int-regs 3 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -481,7 +477,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##mul f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##mul f V int-regs 2 V int-regs 0 V int-regs 1 }
T{ ##load-immediate f V int-regs 3 50 } T{ ##load-immediate f V int-regs 3 50 }
T{ ##mul f V int-regs 4 V int-regs 2 V int-regs 3 } T{ ##mul f V int-regs 4 V int-regs 2 V int-regs 3 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -499,7 +495,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##mul f V int-regs 2 V int-regs 1 V int-regs 0 } T{ ##mul f V int-regs 2 V int-regs 1 V int-regs 0 }
T{ ##load-immediate f V int-regs 3 50 } T{ ##load-immediate f V int-regs 3 50 }
T{ ##mul f V int-regs 4 V int-regs 3 V int-regs 2 } T{ ##mul f V int-regs 4 V int-regs 3 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -517,7 +513,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##and f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##and f V int-regs 2 V int-regs 0 V int-regs 1 }
T{ ##load-immediate f V int-regs 3 50 } T{ ##load-immediate f V int-regs 3 50 }
T{ ##and f V int-regs 4 V int-regs 2 V int-regs 3 } T{ ##and f V int-regs 4 V int-regs 2 V int-regs 3 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -535,7 +531,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##and f V int-regs 2 V int-regs 1 V int-regs 0 } T{ ##and f V int-regs 2 V int-regs 1 V int-regs 0 }
T{ ##load-immediate f V int-regs 3 50 } T{ ##load-immediate f V int-regs 3 50 }
T{ ##and f V int-regs 4 V int-regs 3 V int-regs 2 } T{ ##and f V int-regs 4 V int-regs 3 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -553,7 +549,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##or f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##or f V int-regs 2 V int-regs 0 V int-regs 1 }
T{ ##load-immediate f V int-regs 3 50 } T{ ##load-immediate f V int-regs 3 50 }
T{ ##or f V int-regs 4 V int-regs 2 V int-regs 3 } T{ ##or f V int-regs 4 V int-regs 2 V int-regs 3 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -571,7 +567,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##or f V int-regs 2 V int-regs 1 V int-regs 0 } T{ ##or f V int-regs 2 V int-regs 1 V int-regs 0 }
T{ ##load-immediate f V int-regs 3 50 } T{ ##load-immediate f V int-regs 3 50 }
T{ ##or f V int-regs 4 V int-regs 3 V int-regs 2 } T{ ##or f V int-regs 4 V int-regs 3 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -589,7 +585,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##xor f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##xor f V int-regs 2 V int-regs 0 V int-regs 1 }
T{ ##load-immediate f V int-regs 3 50 } T{ ##load-immediate f V int-regs 3 50 }
T{ ##xor f V int-regs 4 V int-regs 2 V int-regs 3 } T{ ##xor f V int-regs 4 V int-regs 2 V int-regs 3 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -607,7 +603,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##xor f V int-regs 2 V int-regs 1 V int-regs 0 } T{ ##xor f V int-regs 2 V int-regs 1 V int-regs 0 }
T{ ##load-immediate f V int-regs 3 50 } T{ ##load-immediate f V int-regs 3 50 }
T{ ##xor f V int-regs 4 V int-regs 3 V int-regs 2 } T{ ##xor f V int-regs 4 V int-regs 3 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
! Simplification ! Simplification
@ -626,7 +622,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##sub f V int-regs 2 V int-regs 1 V int-regs 1 } T{ ##sub f V int-regs 2 V int-regs 1 V int-regs 1 }
T{ ##add f V int-regs 3 V int-regs 0 V int-regs 2 } T{ ##add f V int-regs 3 V int-regs 0 V int-regs 2 }
T{ ##replace f V int-regs 3 D 0 } T{ ##replace f V int-regs 3 D 0 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -644,7 +640,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##sub f V int-regs 2 V int-regs 1 V int-regs 1 } T{ ##sub f V int-regs 2 V int-regs 1 V int-regs 1 }
T{ ##sub f V int-regs 3 V int-regs 0 V int-regs 2 } T{ ##sub f V int-regs 3 V int-regs 0 V int-regs 2 }
T{ ##replace f V int-regs 3 D 0 } T{ ##replace f V int-regs 3 D 0 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -662,7 +658,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##sub f V int-regs 2 V int-regs 1 V int-regs 1 } T{ ##sub f V int-regs 2 V int-regs 1 V int-regs 1 }
T{ ##or f V int-regs 3 V int-regs 0 V int-regs 2 } T{ ##or f V int-regs 3 V int-regs 0 V int-regs 2 }
T{ ##replace f V int-regs 3 D 0 } T{ ##replace f V int-regs 3 D 0 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -680,7 +676,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##sub f V int-regs 2 V int-regs 1 V int-regs 1 } T{ ##sub f V int-regs 2 V int-regs 1 V int-regs 1 }
T{ ##xor f V int-regs 3 V int-regs 0 V int-regs 2 } T{ ##xor f V int-regs 3 V int-regs 0 V int-regs 2 }
T{ ##replace f V int-regs 3 D 0 } T{ ##replace f V int-regs 3 D 0 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -696,7 +692,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##load-immediate f V int-regs 1 1 } T{ ##load-immediate f V int-regs 1 1 }
T{ ##mul f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##mul f V int-regs 2 V int-regs 0 V int-regs 1 }
T{ ##replace f V int-regs 2 D 0 } T{ ##replace f V int-regs 2 D 0 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
! Constant folding ! Constant folding
@ -713,7 +709,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##load-immediate f V int-regs 1 1 } T{ ##load-immediate f V int-regs 1 1 }
T{ ##load-immediate f V int-regs 2 3 } T{ ##load-immediate f V int-regs 2 3 }
T{ ##add f V int-regs 3 V int-regs 1 V int-regs 2 } T{ ##add f V int-regs 3 V int-regs 1 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -729,7 +725,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##load-immediate f V int-regs 1 1 } T{ ##load-immediate f V int-regs 1 1 }
T{ ##load-immediate f V int-regs 2 3 } T{ ##load-immediate f V int-regs 2 3 }
T{ ##sub f V int-regs 3 V int-regs 1 V int-regs 2 } T{ ##sub f V int-regs 3 V int-regs 1 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -745,7 +741,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##load-immediate f V int-regs 1 2 } T{ ##load-immediate f V int-regs 1 2 }
T{ ##load-immediate f V int-regs 2 3 } T{ ##load-immediate f V int-regs 2 3 }
T{ ##mul f V int-regs 3 V int-regs 1 V int-regs 2 } T{ ##mul f V int-regs 3 V int-regs 1 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -761,7 +757,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##load-immediate f V int-regs 1 2 } T{ ##load-immediate f V int-regs 1 2 }
T{ ##load-immediate f V int-regs 2 1 } T{ ##load-immediate f V int-regs 2 1 }
T{ ##and f V int-regs 3 V int-regs 1 V int-regs 2 } T{ ##and f V int-regs 3 V int-regs 1 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -777,7 +773,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##load-immediate f V int-regs 1 2 } T{ ##load-immediate f V int-regs 1 2 }
T{ ##load-immediate f V int-regs 2 1 } T{ ##load-immediate f V int-regs 2 1 }
T{ ##or f V int-regs 3 V int-regs 1 V int-regs 2 } T{ ##or f V int-regs 3 V int-regs 1 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -793,7 +789,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##load-immediate f V int-regs 1 2 } T{ ##load-immediate f V int-regs 1 2 }
T{ ##load-immediate f V int-regs 2 3 } T{ ##load-immediate f V int-regs 2 3 }
T{ ##xor f V int-regs 3 V int-regs 1 V int-regs 2 } T{ ##xor f V int-regs 3 V int-regs 1 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -807,7 +803,7 @@ compiler.cfg assocs vectors arrays layouts namespaces ;
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 1 } T{ ##load-immediate f V int-regs 1 1 }
T{ ##shl-imm f V int-regs 3 V int-regs 1 3 } T{ ##shl-imm f V int-regs 3 V int-regs 1 3 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
cell 8 = [ cell 8 = [
@ -822,7 +818,7 @@ cell 8 = [
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 -1 } T{ ##load-immediate f V int-regs 1 -1 }
T{ ##shr-imm f V int-regs 3 V int-regs 1 16 } T{ ##shr-imm f V int-regs 3 V int-regs 1 16 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
] when ] when
@ -837,7 +833,7 @@ cell 8 = [
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 1 -8 } T{ ##load-immediate f V int-regs 1 -8 }
T{ ##sar-imm f V int-regs 3 V int-regs 1 1 } T{ ##sar-imm f V int-regs 3 V int-regs 1 1 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
cell 8 = [ cell 8 = [
@ -854,7 +850,7 @@ cell 8 = [
T{ ##load-immediate f V int-regs 1 65536 } T{ ##load-immediate f V int-regs 1 65536 }
T{ ##shl-imm f V int-regs 2 V int-regs 1 31 } T{ ##shl-imm f V int-regs 2 V int-regs 1 31 }
T{ ##add f V int-regs 3 V int-regs 0 V int-regs 2 } T{ ##add f V int-regs 3 V int-regs 0 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -868,7 +864,7 @@ cell 8 = [
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##load-immediate f V int-regs 2 140737488355328 } T{ ##load-immediate f V int-regs 2 140737488355328 }
T{ ##add f V int-regs 3 V int-regs 0 V int-regs 2 } T{ ##add f V int-regs 3 V int-regs 0 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -884,7 +880,7 @@ cell 8 = [
T{ ##load-immediate f V int-regs 2 2147483647 } T{ ##load-immediate f V int-regs 2 2147483647 }
T{ ##add f V int-regs 3 V int-regs 0 V int-regs 2 } T{ ##add f V int-regs 3 V int-regs 0 V int-regs 2 }
T{ ##add f V int-regs 4 V int-regs 3 V int-regs 2 } T{ ##add f V int-regs 4 V int-regs 3 V int-regs 2 }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
] when ] when
@ -900,7 +896,7 @@ cell 8 = [
T{ ##load-immediate f V int-regs 1 1 } T{ ##load-immediate f V int-regs 1 1 }
T{ ##load-immediate f V int-regs 2 2 } T{ ##load-immediate f V int-regs 2 2 }
T{ ##compare f V int-regs 3 V int-regs 1 V int-regs 2 cc= } T{ ##compare f V int-regs 3 V int-regs 1 V int-regs 2 cc= }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -914,7 +910,7 @@ cell 8 = [
T{ ##load-immediate f V int-regs 1 1 } T{ ##load-immediate f V int-regs 1 1 }
T{ ##load-immediate f V int-regs 2 2 } T{ ##load-immediate f V int-regs 2 2 }
T{ ##compare f V int-regs 3 V int-regs 1 V int-regs 2 cc/= } T{ ##compare f V int-regs 3 V int-regs 1 V int-regs 2 cc/= }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -928,7 +924,7 @@ cell 8 = [
T{ ##load-immediate f V int-regs 1 1 } T{ ##load-immediate f V int-regs 1 1 }
T{ ##load-immediate f V int-regs 2 2 } T{ ##load-immediate f V int-regs 2 2 }
T{ ##compare f V int-regs 3 V int-regs 1 V int-regs 2 cc< } T{ ##compare f V int-regs 3 V int-regs 1 V int-regs 2 cc< }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -942,7 +938,7 @@ cell 8 = [
T{ ##load-immediate f V int-regs 1 1 } T{ ##load-immediate f V int-regs 1 1 }
T{ ##load-immediate f V int-regs 2 2 } T{ ##load-immediate f V int-regs 2 2 }
T{ ##compare f V int-regs 3 V int-regs 2 V int-regs 1 cc< } T{ ##compare f V int-regs 3 V int-regs 2 V int-regs 1 cc< }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -954,7 +950,7 @@ cell 8 = [
{ {
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##compare f V int-regs 1 V int-regs 0 V int-regs 0 cc< } T{ ##compare f V int-regs 1 V int-regs 0 V int-regs 0 cc< }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -966,7 +962,7 @@ cell 8 = [
{ {
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##compare f V int-regs 1 V int-regs 0 V int-regs 0 cc<= } T{ ##compare f V int-regs 1 V int-regs 0 V int-regs 0 cc<= }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -978,7 +974,7 @@ cell 8 = [
{ {
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##compare f V int-regs 1 V int-regs 0 V int-regs 0 cc> } T{ ##compare f V int-regs 1 V int-regs 0 V int-regs 0 cc> }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -990,7 +986,7 @@ cell 8 = [
{ {
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##compare f V int-regs 1 V int-regs 0 V int-regs 0 cc>= } T{ ##compare f V int-regs 1 V int-regs 0 V int-regs 0 cc>= }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -1002,7 +998,7 @@ cell 8 = [
{ {
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##compare f V int-regs 1 V int-regs 0 V int-regs 0 cc/= } T{ ##compare f V int-regs 1 V int-regs 0 V int-regs 0 cc/= }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
[ [
@ -1014,12 +1010,12 @@ cell 8 = [
{ {
T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 0 D 0 }
T{ ##compare f V int-regs 1 V int-regs 0 V int-regs 0 cc= } T{ ##compare f V int-regs 1 V int-regs 0 V int-regs 0 cc= }
} test-value-numbering } value-numbering-step
] unit-test ] unit-test
: test-branch-folding ( insns -- insns' n ) : test-branch-folding ( insns -- insns' n )
<basic-block> <basic-block>
[ V{ 0 1 } clone >>successors basic-block set test-value-numbering ] keep [ V{ 0 1 } clone >>successors basic-block set value-numbering-step ] keep
successors>> first ; successors>> first ;
[ [
@ -1208,7 +1204,6 @@ test-diamond
[ ] [ [ ] [
cfg new 0 get >>entry cfg new 0 get >>entry
compute-liveness
value-numbering value-numbering
compute-predecessors compute-predecessors
eliminate-phis drop eliminate-phis drop
@ -1253,7 +1248,6 @@ test-diamond
[ ] [ [ ] [
cfg new 0 get >>entry cfg new 0 get >>entry
compute-predecessors compute-predecessors
compute-liveness
value-numbering value-numbering
compute-predecessors compute-predecessors
eliminate-dead-code eliminate-dead-code
@ -1324,7 +1318,7 @@ V{
[ ] [ [ ] [
cfg new 0 get >>entry cfg new 0 get >>entry
compute-liveness value-numbering eliminate-dead-code drop value-numbering eliminate-dead-code drop
] unit-test ] unit-test
[ f ] [ 1 get instructions>> [ ##peek? ] any? ] unit-test [ f ] [ 1 get instructions>> [ ##peek? ] any? ] unit-test

View File

@ -3,8 +3,7 @@
USING: namespaces assocs biassocs classes kernel math accessors USING: namespaces assocs biassocs classes kernel math accessors
sorting sets sequences fry sorting sets sequences fry
compiler.cfg compiler.cfg
compiler.cfg.local compiler.cfg.rpo
compiler.cfg.liveness
compiler.cfg.renaming compiler.cfg.renaming
compiler.cfg.value-numbering.graph compiler.cfg.value-numbering.graph
compiler.cfg.value-numbering.expressions compiler.cfg.value-numbering.expressions
@ -13,15 +12,6 @@ compiler.cfg.value-numbering.rewrite ;
IN: compiler.cfg.value-numbering IN: compiler.cfg.value-numbering
! Local value numbering. Predecessors must be recomputed after this ! Local value numbering. Predecessors must be recomputed after this
: number-input-values ( live-in -- )
[ [ f next-input-expr simplify ] dip set-vn ] each ;
: init-value-numbering ( live-in -- )
init-value-graph
init-expressions
number-input-values ;
: vreg>vreg-mapping ( -- assoc ) : vreg>vreg-mapping ( -- assoc )
vregs>vns get [ keys ] keep vregs>vns get [ keys ] keep
'[ dup _ [ at ] [ value-at ] bi ] H{ } map>assoc ; '[ dup _ [ at ] [ value-at ] bi ] H{ } map>assoc ;
@ -32,8 +22,10 @@ IN: compiler.cfg.value-numbering
] with-variable ; ] with-variable ;
: value-numbering-step ( insns -- insns' ) : value-numbering-step ( insns -- insns' )
[ rewrite ] map dup rename-uses ; init-value-graph
init-expressions
[ rewrite ] map
dup rename-uses ;
: value-numbering ( cfg -- cfg' ) : value-numbering ( cfg -- cfg' )
[ init-value-numbering ] [ value-numbering-step ] local-optimization [ value-numbering-step ] local-optimization cfg-changed ;
cfg-changed ;

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: kernel accessors namespaces assocs sets sequences locals USING: kernel accessors namespaces assocs sets sequences locals
compiler.cfg compiler.cfg.instructions compiler.cfg.copy-prop compiler.cfg compiler.cfg.instructions compiler.cfg.copy-prop
compiler.cfg.liveness compiler.cfg.local ; compiler.cfg.rpo ;
IN: compiler.cfg.write-barrier IN: compiler.cfg.write-barrier
! Eliminate redundant write barrier hits. ! Eliminate redundant write barrier hits.
@ -43,4 +43,4 @@ M: insn eliminate-write-barrier ;
[ eliminate-write-barrier ] map sift ; [ eliminate-write-barrier ] map sift ;
: eliminate-write-barriers ( cfg -- cfg' ) : eliminate-write-barriers ( cfg -- cfg' )
[ drop ] [ write-barriers-step ] local-optimization ; [ write-barriers-step ] local-optimization ;