! See http://factorcode.org/license.txt for BSD license.
USING: accessors combinators.short-circuit kernel sequences math
compiler.utilities compiler.cfg compiler.cfg.instructions compiler.cfg.rpo
-compiler.cfg.utilities ;
+compiler.cfg.predecessors compiler.cfg.utilities ;
IN: compiler.cfg.block-joining
! Joining blocks that are not calls and are connected by a single CFG edge.
-! Predecessors must be recomputed after this. Also this pass does not
-! update ##phi nodes and should therefore only run before stack analysis.
+! This pass does not update ##phi nodes and should therefore only run
+! before stack analysis.
: join-block? ( bb -- ? )
{
[ kill-block? not ]
[ join-instructions ] [ update-successors ] 2bi ;
: join-blocks ( cfg -- cfg' )
+ needs-predecessors
+
dup post-order [
dup join-block?
[ dup predecessor join-block ] [ drop ] if
] each
- cfg-changed ;
+
+ cfg-changed predecessors-changed ;
: check-predecessors ( cfg -- )
[ get-predecessors ]
- [ compute-predecessors drop ]
+ [ needs-predecessors drop ]
[ get-predecessors ] tri assert= ;
: check-branch-splitting ( cfg -- )
- compute-predecessors
+ needs-predecessors
split-branches
check-predecessors ;
! See http://factorcode.org/license.txt for BSD license.
USING: accessors combinators.short-circuit kernel math math.order
sequences assocs namespaces vectors fry arrays splitting
-compiler.cfg.def-use compiler.cfg compiler.cfg.rpo
+compiler.cfg.def-use compiler.cfg compiler.cfg.rpo compiler.cfg.predecessors
compiler.cfg.renaming compiler.cfg.instructions compiler.cfg.utilities ;
IN: compiler.cfg.branch-splitting
] if ;
: split-branches ( cfg -- cfg' )
+ needs-predecessors
+
dup [
dup split-branch? [ split-branch ] [ drop ] if
] each-basic-block
+
cfg-changed ;
prettyprint alien alien.accessors math.private compiler.tree.builder
compiler.tree.optimizer compiler.cfg.builder compiler.cfg.debugger
compiler.cfg.optimizer compiler.cfg.predecessors compiler.cfg.checker
-arrays locals byte-arrays kernel.private math slots.private vectors sbufs
-strings math.partial-dispatch strings.private ;
+compiler.cfg arrays locals byte-arrays kernel.private math
+slots.private vectors sbufs strings math.partial-dispatch
+strings.private ;
! Just ensure that various CFGs build correctly.
: unit-test-cfg ( quot -- )
- '[ _ test-cfg [ optimize-cfg check-cfg ] each ] [ ] swap unit-test ;
+ '[ _ test-cfg [ [ optimize-cfg check-cfg ] with-cfg ] each ] [ ] swap unit-test ;
: blahblah ( nodes -- ? )
{ fixnum } declare [
V{ } clone >>predecessors
\ basic-block counter >>id ;
-TUPLE: cfg { entry basic-block } word label spill-area-size reps post-order ;
+TUPLE: cfg { entry basic-block } word label
+spill-area-size reps
+post-order linear-order
+predecessors-valid? dominance-valid? loops-valid? ;
: <cfg> ( entry word label -- cfg )
cfg new
swap >>word
swap >>entry ;
-: cfg-changed ( cfg -- cfg ) f >>post-order ; inline
+: cfg-changed ( cfg -- cfg )
+ f >>post-order
+ f >>linear-order
+ f >>dominance-valid?
+ f >>loops-valid? ; inline
+
+: predecessors-changed ( cfg -- cfg )
+ f >>predecessors-valid? ;
+
+: with-cfg ( cfg quot: ( cfg -- ) -- )
+ [ dup cfg ] dip with-variable ; inline
TUPLE: mr { instructions array } word label ;
! See http://factorcode.org/license.txt for BSD license.
USING: kernel namespaces assocs accessors sequences grouping
combinators compiler.cfg.rpo compiler.cfg.renaming
-compiler.cfg.instructions ;
+compiler.cfg.instructions compiler.cfg.predecessors ;
IN: compiler.cfg.copy-prop
! The first three definitions are also used in compiler.cfg.alias-analysis.
PRIVATE>
: copy-propagation ( cfg -- cfg' )
+ needs-predecessors
+
[ collect-copies ]
[ rename-copies ]
[ ]
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs deques dlists kernel locals sequences lexer
namespaces functors compiler.cfg.rpo compiler.cfg.utilities
-compiler.cfg ;
+compiler.cfg.predecessors compiler.cfg ;
IN: compiler.cfg.dataflow-analysis
GENERIC: join-sets ( sets dfa -- set )
] when ; inline
:: run-dataflow-analysis ( cfg dfa -- in-sets out-sets )
+ cfg needs-predecessors drop
H{ } clone :> in-sets
H{ } clone :> out-sets
cfg dfa <dfa-worklist> :> work-list
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs sets kernel namespaces sequences
compiler.cfg.instructions compiler.cfg.def-use
-compiler.cfg.rpo ;
+compiler.cfg.rpo compiler.cfg.predecessors ;
IN: compiler.cfg.dce
! Maps vregs to sequences of vregs
M: insn live-insn? drop t ;
: eliminate-dead-code ( cfg -- cfg' )
+ needs-predecessors
+
init-dead-code
dup
[ [ instructions>> [ build-liveness-graph ] each ] each-basic-block ]
: test-mr ( quot -- mrs )
test-cfg [
- optimize-cfg
- build-mr
+ [
+ optimize-cfg
+ build-mr
+ ] with-cfg
] map ;
: insn. ( insn -- )
: test-dominance ( -- )
cfg new 0 get >>entry
- compute-predecessors
- compute-dominance ;
+ needs-dominance drop ;
! Example with no back edges
V{ } 0 test-bb
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs combinators sets math fry kernel math.order
dlists deques vectors namespaces sequences sorting locals
-compiler.cfg.rpo ;
+compiler.cfg.rpo compiler.cfg.predecessors ;
IN: compiler.cfg.dominance
! Reference:
H{ } clone maxpreorder set
[ 0 ] dip entry>> (compute-dfs) drop ;
+: compute-dominance ( cfg -- cfg' )
+ [ compute-dom-parents compute-dom-children ] [ compute-dfs ] [ ] tri ;
+
PRIVATE>
-: compute-dominance ( cfg -- )
- [ compute-dom-parents compute-dom-children ] [ compute-dfs ] bi ;
+: needs-dominance ( cfg -- cfg' )
+ needs-predecessors
+ dup dominance-valid?>> [ compute-dominance t >>dominance-valid? ] unless ;
: dominates? ( bb1 bb2 -- ? )
swap [ pre-of ] [ [ pre-of ] [ maxpre-of ] bi ] bi* between? ;
! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: kernel accessors sequences combinators combinators.short-circuit
-classes vectors compiler.cfg compiler.cfg.instructions compiler.cfg.rpo ;
+USING: kernel accessors sequences namespaces combinators
+combinators.short-circuit classes vectors compiler.cfg
+compiler.cfg.instructions compiler.cfg.rpo ;
IN: compiler.cfg.empty-blocks
-
+
+<PRIVATE
+
: update-predecessor ( bb -- )
! We have to replace occurrences of bb with bb's successor
! in bb's predecessor's list of successors.
2dup eq? [ drop predecessors>> first ] [ nip ] if
] with map
] change-predecessors drop ;
-
+
+SYMBOL: changed?
+
: delete-basic-block ( bb -- )
- [ update-predecessor ] [ update-successor ] bi ;
+ [ update-predecessor ] [ update-successor ] bi
+ changed? on ;
: delete-basic-block? ( bb -- ? )
{
[ successors>> length 1 = ]
[ instructions>> first ##branch? ]
} 1&& ;
-
+
+PRIVATE>
+
: delete-empty-blocks ( cfg -- cfg' )
+ changed? off
dup [ dup delete-basic-block? [ delete-basic-block ] [ drop ] if ] each-basic-block
- cfg-changed ;
\ No newline at end of file
+ changed? get [ cfg-changed ] when ;
\ No newline at end of file
: test-gc-checks ( -- )
H{ } clone representations set
cfg new 0 get >>entry
- compute-predecessors
insert-gc-checks
drop ;
fry make combinators sets locals arrays
cpu.architecture
compiler.cfg
-compiler.cfg.rpo
compiler.cfg.def-use
compiler.cfg.liveness
compiler.cfg.registers
compiler.cfg.instructions
compiler.cfg.renaming.functor
+compiler.cfg.linearization.order
compiler.cfg.linear-scan.allocation
compiler.cfg.linear-scan.allocation.state
compiler.cfg.linear-scan.live-intervals ;
: assign-registers ( live-intervals cfg -- )
[ init-assignment ] dip
- [ assign-registers-in-block ] each-basic-block ;
+ linearization-order [ assign-registers-in-block ] each ;
:: test-linear-scan-on-cfg ( regs -- )
[
cfg new 0 get >>entry
- compute-predecessors
+ dup cfg set
dup fake-representations
dup { { int-regs regs } } (linear-scan)
- cfg-changed
flatten-cfg 1array mr.
] with-scope ;
cfg check-numbering ;
: linear-scan ( cfg -- cfg' )
- [
- dup machine-registers (linear-scan)
- cfg-changed
- ] with-scope ;
+ dup machine-registers (linear-scan) ;
! See http://factorcode.org/license.txt for BSD license.
USING: namespaces kernel assocs accessors sequences math math.order fry
combinators binary-search compiler.cfg.instructions compiler.cfg.registers
-compiler.cfg.def-use compiler.cfg.liveness compiler.cfg.rpo
+compiler.cfg.def-use compiler.cfg.liveness compiler.cfg.linearization.order
compiler.cfg ;
IN: compiler.cfg.linear-scan.live-intervals
: compute-live-intervals ( cfg -- live-intervals )
H{ } clone [
live-intervals set
- post-order [ compute-live-intervals-step ] each
+ linearization-order <reversed>
+ [ compute-live-intervals-step ] each
] keep values dup finish-live-intervals ;
: relevant-ranges ( interval1 interval2 -- ranges1 ranges2 )
! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel accessors math sequences grouping namespaces
-compiler.cfg.rpo ;
+compiler.cfg.linearization.order ;
IN: compiler.cfg.linear-scan.numbering
: number-instructions ( rpo -- )
- [ 0 ] dip [
+ linearization-order 0 [
instructions>> [
[ (>>insn#) ] [ drop 2 + ] 2bi
] each
- ] each-basic-block drop ;
+ ] reduce drop ;
SYMBOL: check-numbering?
[ drop ] [ bad-numbering ] if ;
: check-numbering ( cfg -- )
- check-numbering? get [ [ check-block-numbering ] each-basic-block ] [ drop ] if ;
\ No newline at end of file
+ check-numbering? get
+ [ linearization-order [ check-block-numbering ] each ] [ drop ] if ;
\ No newline at end of file
USING: accessors arrays assocs combinators
combinators.short-circuit fry kernel locals namespaces
make math sequences hashtables
+compiler.cfg
compiler.cfg.rpo
compiler.cfg.liveness
compiler.cfg.registers
: perform-mappings ( bb to mappings -- )
dup empty? [ 3drop ] [
- mapping-instructions <simple-block>
- insert-basic-block
+ mapping-instructions <simple-block> insert-basic-block
+ cfg get cfg-changed drop
] if ;
: resolve-edge-data-flow ( bb to -- )
! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel math accessors sequences namespaces make
-combinators assocs arrays locals layouts cpu.architecture
+combinators assocs arrays locals layouts hashtables
+cpu.architecture
compiler.cfg
compiler.cfg.comparisons
compiler.cfg.stack-frame
compiler.cfg.linearization.order ;
IN: compiler.cfg.linearization
+<PRIVATE
+
+SYMBOL: numbers
+
+: block-number ( bb -- n ) numbers get at ;
+
+: number-blocks ( bbs -- ) [ 2array ] map-index >hashtable numbers set ;
+
! Convert CFG IR to machine IR.
GENERIC: linearize-insn ( basic-block insn -- )
: linearize-basic-blocks ( cfg -- insns )
[
- [ linearization-order [ linearize-basic-block ] each ]
- [ spill-area-size>> _spill-area-size ]
- bi
+ [
+ linearization-order
+ [ number-blocks ]
+ [ [ linearize-basic-block ] each ] bi
+ ] [ spill-area-size>> _spill-area-size ] bi
] { } make ;
+PRIVATE>
+
: flatten-cfg ( cfg -- mr )
[ linearize-basic-blocks ] [ word>> ] [ label>> ] tri
<mr> ;
! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: accessors assocs deques dlists kernel make
+USING: accessors assocs deques dlists kernel make sorting
namespaces sequences combinators combinators.short-circuit
-fry math sets compiler.cfg.rpo compiler.cfg.utilities ;
+fry math sets compiler.cfg.rpo compiler.cfg.utilities
+compiler.cfg.loop-detection ;
IN: compiler.cfg.linearization.order
! This is RPO except loops are rotated. Based on SBCL's src/compiler/control.lisp
<PRIVATE
-SYMBOLS: work-list loop-heads visited numbers next-number ;
+SYMBOLS: work-list loop-heads visited ;
: visited? ( bb -- ? ) visited get key? ;
work-list get push-back
] if ;
+: init-linearization-order ( cfg -- )
+ <dlist> work-list set
+ H{ } clone visited set
+ entry>> add-to-work-list ;
+
: (find-alternate-loop-head) ( bb -- bb' )
dup {
[ predecessor visited? not ]
add-to-work-list
] [ drop ] if ;
-: assign-number ( bb -- )
- next-number [ get ] [ inc ] bi swap numbers get set-at ;
+: sorted-successors ( bb -- seq )
+ successors>> [ loop-nesting-at ] sort-with ;
: process-block ( bb -- )
- {
- [ , ]
- [ assign-number ]
- [ visited get conjoin ]
- [ successors>> <reversed> [ process-successor ] each ]
- } cleave ;
+ [ , ]
+ [ visited get conjoin ]
+ [ sorted-successors [ process-successor ] each ]
+ tri ;
+
+: (linearization-order) ( cfg -- bbs )
+ init-linearization-order
+
+ [ work-list get [ process-block ] slurp-deque ] { } make ;
PRIVATE>
: linearization-order ( cfg -- bbs )
- ! We call 'post-order drop' to ensure blocks receive their
- ! RPO numbers.
- <dlist> work-list set
- H{ } clone visited set
- H{ } clone numbers set
- 0 next-number set
- [ post-order drop ]
- [ entry>> add-to-work-list ] bi
- [ work-list get [ process-block ] slurp-deque ] { } make ;
+ needs-post-order needs-loops
-: block-number ( bb -- n ) numbers get at ;
+ dup linear-order>> [ ] [
+ dup (linearization-order)
+ >>linear-order linear-order>>
+ ] ?if ;
\ No newline at end of file
: test-liveness ( -- )
cfg new 1 get >>entry
- compute-predecessors
compute-live-sets ;
! Sanity check...
! 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 compiler.cfg.liveness compiler.cfg.utilities ;
+compiler.cfg.rpo compiler.cfg.liveness compiler.cfg.utilities
+compiler.cfg.predecessors ;
IN: compiler.cfg.liveness.ssa
! TODO: merge with compiler.cfg.liveness
] [ drop ] if ;
: compute-ssa-live-sets ( cfg -- cfg' )
+ needs-predecessors
+
<hashed-dlist> work-list set
H{ } clone live-ins set
H{ } clone phi-live-ins set
0 { 1 2 } edges
2 0 edge
-: test-loop-detection ( -- ) cfg new 0 get >>entry compute-predecessors detect-loops drop ;
+: test-loop-detection ( -- ) cfg new 0 get >>entry needs-loops drop ;
[ ] [ test-loop-detection ] unit-test
! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs combinators deques dlists fry kernel
-namespaces sequences sets compiler.cfg ;
+namespaces sequences sets compiler.cfg compiler.cfg.predecessors ;
IN: compiler.cfg.loop-detection
-! Loop detection -- predecessors must be computed first
-
TUPLE: natural-loop header index ends blocks ;
<PRIVATE
[ values ] dip '[ blocks>> values [ _ inc-at ] each ] each
] keep loop-nesting set ;
-PRIVATE>
-
-: loop-nesting-at ( bb -- n ) loop-nesting get at 0 or ;
-
: detect-loops ( cfg -- cfg' )
+ needs-predecessors
H{ } clone loops set
H{ } clone visited set
H{ } clone active set
H{ } clone loop-nesting set
- dup entry>> find-loop-headers process-loop-headers compute-loop-nesting ;
\ No newline at end of file
+ dup entry>> find-loop-headers process-loop-headers compute-loop-nesting ;
+
+PRIVATE>
+
+: loop-nesting-at ( bb -- n ) loop-nesting get at 0 or ;
+
+: needs-loops ( cfg -- cfg' )
+ needs-predecessors
+ dup loops-valid?>> [ detect-loops t >>loops-valid? ] unless ;
\ No newline at end of file
! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: kernel namespaces accessors compiler.cfg compiler.cfg.registers
+USING: kernel namespaces accessors compiler.cfg
compiler.cfg.linearization compiler.cfg.gc-checks
compiler.cfg.linear-scan compiler.cfg.build-stack-frame ;
IN: compiler.cfg.mr
: build-mr ( cfg -- mr )
- dup cfg [
- cfg get reps>> representations set
- insert-gc-checks
- linear-scan
- flatten-cfg
- build-stack-frame
- ] with-variable ;
\ No newline at end of file
+ insert-gc-checks
+ linear-scan
+ flatten-cfg
+ build-stack-frame ;
\ No newline at end of file
! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel sequences accessors combinators namespaces
-compiler.cfg
compiler.cfg.tco
compiler.cfg.useless-conditionals
compiler.cfg.branch-splitting
compiler.cfg.dce
compiler.cfg.write-barrier
compiler.cfg.representations
-compiler.cfg.loop-detection
compiler.cfg.two-operand
compiler.cfg.ssa.destruction
compiler.cfg.empty-blocks
-compiler.cfg.predecessors
-compiler.cfg.rpo
compiler.cfg.checker ;
IN: compiler.cfg.optimizer
] when ;
: optimize-cfg ( cfg -- cfg' )
- ! Note that compute-predecessors has to be called several times.
- ! The passes that need this document it.
- dup cfg [
- optimize-tail-calls
- delete-useless-conditionals
- compute-predecessors
- split-branches
- join-blocks
- compute-predecessors
- construct-ssa
- alias-analysis
- value-numbering
- compute-predecessors
- copy-propagation
- eliminate-dead-code
- eliminate-write-barriers
- detect-loops
- select-representations
- convert-two-operand
- destruct-ssa
- delete-empty-blocks
- ?check
- ] with-variable ;
+ optimize-tail-calls
+ delete-useless-conditionals
+ split-branches
+ join-blocks
+ construct-ssa
+ alias-analysis
+ value-numbering
+ copy-propagation
+ eliminate-dead-code
+ eliminate-write-barriers
+ select-representations
+ convert-two-operand
+ destruct-ssa
+ delete-empty-blocks
+ ?check ;
compiler.cfg.instructions compiler.cfg.utilities ;
IN: compiler.cfg.predecessors
+<PRIVATE
+
: update-predecessors ( bb -- )
dup successors>> [ predecessors>> push ] with each ;
[ [ update-phis ] each-basic-block ]
[ ]
} cleave ;
+
+PRIVATE>
+
+: needs-predecessors ( cfg -- cfg' )
+ dup predecessors-valid?>>
+ [ compute-predecessors t >>predecessors-valid? ] unless ;
\ No newline at end of file
compiler.cfg.representations.preferred ;
IN: compiler.cfg.representations
-! Virtual register representation selection. Predecessors and loops
-! must be computed first.
+! Virtual register representation selection.
: emit-conversion ( dst src dst-rep src-rep -- )
2array {
PRIVATE>
: select-representations ( cfg -- cfg' )
+ needs-loops
+
{
[ compute-possibilities ]
[ compute-representations ]
[ change-instructions drop ] 2bi ; inline
: local-optimization ( cfg quot: ( insns -- insns' ) -- cfg' )
- dupd '[ _ optimize-basic-block ] each-basic-block ; inline
\ No newline at end of file
+ dupd '[ _ optimize-basic-block ] each-basic-block ; inline
+
+: needs-post-order ( cfg -- cfg' )
+ dup post-order drop ;
\ No newline at end of file
: test-ssa ( -- )
cfg new 0 get >>entry
dup cfg set
- compute-predecessors
construct-ssa
drop ;
compiler.cfg.ssa.construction.tdmsc ;
IN: compiler.cfg.ssa.construction
-! SSA construction. Predecessors must be computed first.
-
! The phi placement algorithm is implemented in
! compiler.cfg.ssa.construction.tdmsc.
: construct-ssa ( cfg -- cfg' )
{
- [ ]
[ compute-live-sets ]
- [ compute-dominance ]
[ compute-merge-sets ]
[ compute-defs compute-phi-nodes insert-phi-nodes ]
[ rename ]
+ [ ]
} cleave ;
\ No newline at end of file
: test-tdmsc ( -- )
cfg new 0 get >>entry dup cfg set
- compute-predecessors
- dup compute-dominance
compute-merge-sets ;
V{ } 0 test-bb
PRIVATE>
: compute-merge-sets ( cfg -- )
+ needs-dominance
+
H{ } clone visited set
[ compute-levels ]
[ init-merge-sets ]
] each-basic-block ;
: destruct-ssa ( cfg -- cfg' )
+ needs-dominance
+
dup construct-cssa
dup compute-defs
- dup compute-dominance
compute-ssa-live-sets
dup compute-live-ranges
dup prepare-coalescing
: test-interference ( -- )
cfg new 0 get >>entry
compute-ssa-live-sets
- compute-predecessors
dup compute-defs
- dup compute-dominance
compute-live-ranges ;
V{
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs fry kernel namespaces sequences math
arrays compiler.cfg.def-use compiler.cfg.instructions
-compiler.cfg.liveness.ssa compiler.cfg.rpo ;
+compiler.cfg.liveness.ssa compiler.cfg.rpo compiler.cfg.dominance ;
IN: compiler.cfg.ssa.interference.live-ranges
! Live ranges for interference testing
PRIVATE>
: compute-live-ranges ( cfg -- )
+ needs-dominance
+
H{ } clone def-indices set
H{ } clone kill-indices set
[ compute-local-live-ranges ] each-basic-block ;
: test-liveness ( -- )
cfg new 0 get >>entry
- compute-predecessors
dup compute-defs
dup compute-uses
- dup compute-dominance
+ needs-dominance
precompute-liveness ;
V{
USING: namespaces assocs kernel fry accessors sequences make math locals
combinators compiler.cfg compiler.cfg.hats compiler.cfg.instructions
compiler.cfg.utilities compiler.cfg.rpo compiler.cfg.stacks.local
-compiler.cfg.stacks.global compiler.cfg.stacks.height ;
+compiler.cfg.stacks.global compiler.cfg.stacks.height
+compiler.cfg.predecessors ;
IN: compiler.cfg.stacks.finalize
! This pass inserts peeks and replaces.
[ predecessors>> ] keep '[ _ visit-edge ] each ;
: finalize-stack-shuffling ( cfg -- cfg' )
+ needs-predecessors
+
dup [ visit-block ] each-basic-block
+
cfg-changed ;
\ No newline at end of file
: end-stack-analysis ( -- )
cfg get
- compute-predecessors
compute-global-sets
finalize-stack-shuffling
drop ;
: test-uninitialized ( -- )
cfg new 0 get >>entry
- compute-predecessors
compute-uninitialized-sets ;
V{
compiler.cfg.utilities ;
IN: compiler.cfg.tco
-! Tail call optimization. You must run compute-predecessors after this
+! Tail call optimization.
: return? ( bb -- ? )
skip-empty-blocks
: optimize-tail-calls ( cfg -- cfg' )
dup [ optimize-tail-call ] each-basic-block
- cfg-changed ;
\ No newline at end of file
+
+ cfg-changed predecessors-changed ;
\ No newline at end of file
dup [
dup delete-conditional? [ delete-conditional ] [ drop ] if
] each-basic-block
- cfg-changed ;
+
+ cfg-changed predecessors-changed ;
[ ] [
cfg new 0 get >>entry dup cfg set
value-numbering
- compute-predecessors
- detect-loops
select-representations
destruct-ssa drop
] unit-test
[ ] [
cfg new 0 get >>entry
- compute-predecessors
value-numbering
- compute-predecessors
eliminate-dead-code
drop
] unit-test
compiler.cfg.value-numbering.rewrite ;
IN: compiler.cfg.value-numbering
-! Local value numbering. Predecessors must be recomputed after this
+! Local value numbering.
+
: >copy ( insn -- insn/##copy )
dup dst>> dup vreg>vn vn>vreg
2dup eq? [ 2drop ] [ any-rep \ ##copy new-insn nip ] if ;
[ process-instruction ] map ;
: value-numbering ( cfg -- cfg' )
- [ value-numbering-step ] local-optimization cfg-changed ;
+ [ value-numbering-step ] local-optimization
+
+ cfg-changed predecessors-changed ;
compiler.tree.builder
compiler.tree.optimizer
+compiler.cfg
compiler.cfg.builder
compiler.cfg.optimizer
compiler.cfg.mr
: backend ( tree word -- )
build-cfg [
- optimize-cfg
- build-mr
+ [ optimize-cfg build-mr ] with-cfg
generate
save-asm
] each ;
: compile-test-cfg ( -- word )
cfg new 0 get >>entry
+ dup cfg set
dup fake-representations representations get >>reps
compile-cfg ;
dup "Wrote " prepend print
[ [ concat ] dip ascii set-file-lines ]
[ { "dot" "-Tpng" "-O" } swap suffix try-process ]
- [ ".png" append image. ]
+ [ ".png" append "open" swap 2array try-process ]
tri ; inline
: attrs>string ( seq -- str )
: dom-trees ( cfgs -- )
[
[
- compute-predecessors
- compute-dominance
+ needs-dominance drop
dom-childrens get [
[
bb-edge,