compiler.cfg arrays locals byte-arrays kernel.private math
slots.private vectors sbufs strings math.partial-dispatch
hashtables assocs combinators.short-circuit
-strings.private accessors compiler.cfg.instructions ;
+strings.private accessors compiler.cfg.instructions
+compiler.cfg.representations ;
FROM: alien.c-types => int ;
IN: compiler.cfg.builder.tests
M: basic-block hashcode* nip id>> ;
TUPLE: cfg { entry basic-block } word label
-spill-area-size reps
+spill-area-size
post-order linear-order
predecessors-valid? dominance-valid? loops-valid? ;
USING: kernel combinators.short-circuit accessors math sequences
sets assocs compiler.cfg.instructions compiler.cfg.rpo
compiler.cfg.def-use compiler.cfg.linearization
-compiler.cfg.utilities compiler.cfg.mr compiler.utilities ;
+compiler.cfg.utilities compiler.cfg.finalization compiler.cfg.mr
+compiler.utilities ;
IN: compiler.cfg.checker
! Check invariants
: check-cfg ( cfg -- )
[ [ check-basic-block ] each-basic-block ]
- [ build-mr check-mr ]
+ [ finalize-cfg build-mr check-mr ]
bi ;
compiler.tree.optimizer cpu.architecture compiler.cfg.builder
compiler.cfg.linearization compiler.cfg.registers
compiler.cfg.stack-frame compiler.cfg.linear-scan
-compiler.cfg.optimizer compiler.cfg.instructions
-compiler.cfg.utilities compiler.cfg.def-use compiler.cfg.rpo
-compiler.cfg.mr compiler.cfg.representations.preferred
-compiler.cfg ;
+compiler.cfg.optimizer compiler.cfg.finalization
+compiler.cfg.instructions compiler.cfg.utilities
+compiler.cfg.def-use compiler.cfg.rpo compiler.cfg.mr
+compiler.cfg.representations.preferred compiler.cfg ;
IN: compiler.cfg.debugger
GENERIC: test-cfg ( quot -- cfgs )
test-cfg [
[
optimize-cfg
+ finalize-cfg
build-mr
] with-cfg
] map ;
--- /dev/null
+Slava Pestov
--- /dev/null
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: compiler.cfg.empty-blocks compiler.cfg.gc-checks
+compiler.cfg.linear-scan compiler.cfg.representations
+compiler.cfg.save-contexts compiler.cfg.ssa.destruction ;
+IN: compiler.cfg.finalization
+
+: finalize-cfg ( cfg -- cfg' )
+ select-representations
+ insert-gc-checks
+ insert-save-contexts
+ destruct-ssa
+ delete-empty-blocks
+ linear-scan ;
2bi ;
: assign-spill ( live-interval -- )
- dup vreg>> vreg-spill-slot >>spill-to drop ;
+ dup [ vreg>> ] [ last-use rep>> ] bi
+ assign-spill-slot >>spill-to drop ;
: spill-before ( before -- before/f )
! If the interval does not have any usages before the spill location,
] if ;
: assign-reload ( live-interval -- )
- dup vreg>> vreg-spill-slot >>reload-from drop ;
+ dup [ vreg>> ] [ first-use rep>> ] bi
+ assign-spill-slot >>reload-from drop ;
: spill-after ( after -- after/f )
! If the interval has no more usages after the spill location,
! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: accessors assocs combinators cpu.architecture fry heaps
-kernel math math.order namespaces sequences vectors
+USING: arrays accessors assocs combinators cpu.architecture fry
+heaps kernel math math.order namespaces sequences vectors
linked-assocs compiler.cfg compiler.cfg.registers
-compiler.cfg.instructions compiler.cfg.linear-scan.live-intervals ;
+compiler.cfg.instructions
+compiler.cfg.linear-scan.live-intervals ;
IN: compiler.cfg.linear-scan.allocation.state
! Start index of current live interval. We ensure that all
! Mapping from vregs to spill slots
SYMBOL: spill-slots
-: vreg-spill-slot ( vreg -- spill-slot )
- spill-slots get [ rep-of next-spill-slot ] cache ;
+: assign-spill-slot ( coalesced-vreg rep -- spill-slot )
+ spill-slots get [ nip next-spill-slot ] 2cache ;
+
+: lookup-spill-slot ( coalesced-vreg rep -- spill-slot )
+ 2array spill-slots get ?at [ ] [ bad-vreg ] if ;
: init-allocator ( registers -- )
registers set
ERROR: bad-vreg vreg ;
-: (vreg>reg) ( vreg pending -- reg )
+:: (vreg>reg) ( vreg pending -- reg )
! If a live vreg is not in the pending set, then it must
! have been spilled.
- ?at [ spill-slots get ?at [ ] [ bad-vreg ] if ] unless ;
+ vreg pending at* [
+ drop vreg vreg rep-of lookup-spill-slot
+ ] unless ;
: vreg>reg ( vreg -- reg )
pending-interval-assoc get (vreg>reg) ;
H{ } clone register-live-outs set
init-unhandled ;
-: spill-rep ( live-interval -- rep ) vreg>> rep-of ;
-
: insert-spill ( live-interval -- )
- [ reg>> ] [ spill-rep ] [ spill-to>> ] tri ##spill ;
+ [ reg>> ] [ first-use rep>> ] [ spill-to>> ] tri ##spill ;
: handle-spill ( live-interval -- )
dup spill-to>> [ insert-spill ] [ drop ] if ;
: expire-old-intervals ( n -- )
pending-interval-heap get (expire-old-intervals) ;
-: reload-rep ( live-interval -- rep ) vreg>> rep-of ;
-
: insert-reload ( live-interval -- )
- [ reg>> ] [ reload-rep ] [ reload-from>> ] tri ##reload ;
+ [ reg>> ] [ first-use rep>> ] [ reload-from>> ] tri ##reload ;
: insert-reload? ( live-interval -- ? )
! Don't insert a reload if the register will be written to
{ reg-class float-regs }
{ start 0 }
{ end 2 }
- { uses V{ T{ vreg-use f 0 } T{ vreg-use f 1 } } }
+ { uses V{ T{ vreg-use f float-rep 0 } T{ vreg-use f float-rep 1 } } }
{ ranges V{ T{ live-range f 0 2 } } }
{ spill-to T{ spill-slot f 0 } }
}
{ reg-class float-regs }
{ start 5 }
{ end 5 }
- { uses V{ T{ vreg-use f 5 } } }
+ { uses V{ T{ vreg-use f float-rep 5 } } }
{ ranges V{ T{ live-range f 5 5 } } }
{ reload-from T{ spill-slot f 0 } }
}
{ reg-class float-regs }
{ start 0 }
{ end 5 }
- { uses V{ T{ vreg-use f 0 } T{ vreg-use f 1 } T{ vreg-use f 5 } } }
+ { uses V{ T{ vreg-use f float-rep 0 } T{ vreg-use f float-rep 1 } T{ vreg-use f float-rep 5 } } }
{ ranges V{ T{ live-range f 0 5 } } }
} 2 split-for-spill
] unit-test
{ reg-class float-regs }
{ start 0 }
{ end 1 }
- { uses V{ T{ vreg-use f 0 } } }
+ { uses V{ T{ vreg-use f float-rep 0 } } }
{ ranges V{ T{ live-range f 0 1 } } }
{ spill-to T{ spill-slot f 4 } }
}
{ reg-class float-regs }
{ start 1 }
{ end 5 }
- { uses V{ T{ vreg-use f 1 } T{ vreg-use f 5 } } }
+ { uses V{ T{ vreg-use f float-rep 1 } T{ vreg-use f float-rep 5 } } }
{ ranges V{ T{ live-range f 1 5 } } }
{ reload-from T{ spill-slot f 4 } }
}
{ reg-class float-regs }
{ start 0 }
{ end 5 }
- { uses V{ T{ vreg-use f 0 } T{ vreg-use f 1 } T{ vreg-use f 5 } } }
+ { uses V{ T{ vreg-use f float-rep 0 } T{ vreg-use f float-rep 1 } T{ vreg-use f float-rep 5 } } }
{ ranges V{ T{ live-range f 0 5 } } }
} 0 split-for-spill
] unit-test
{ reg-class float-regs }
{ start 0 }
{ end 1 }
- { uses V{ T{ vreg-use f 0 } } }
+ { uses V{ T{ vreg-use f float-rep 0 } } }
{ ranges V{ T{ live-range f 0 1 } } }
{ spill-to T{ spill-slot f 8 } }
}
{ reg-class float-regs }
{ start 20 }
{ end 30 }
- { uses V{ T{ vreg-use f 20 } T{ vreg-use f 30 } } }
+ { uses V{ T{ vreg-use f float-rep 20 } T{ vreg-use f float-rep 30 } } }
{ ranges V{ T{ live-range f 20 30 } } }
{ reload-from T{ spill-slot f 8 } }
}
{ reg-class float-regs }
{ start 0 }
{ end 30 }
- { uses V{ T{ vreg-use f 0 } T{ vreg-use f 20 } T{ vreg-use f 30 } } }
+ { uses V{ T{ vreg-use f float-rep 0 } T{ vreg-use f float-rep 20 } T{ vreg-use f float-rep 30 } } }
{ ranges V{ T{ live-range f 0 8 } T{ live-range f 10 18 } T{ live-range f 20 30 } } }
} 10 split-for-spill
] unit-test
{ reg 1 }
{ start 1 }
{ end 15 }
- { uses V{ T{ vreg-use f 1 } T{ vreg-use f 3 } T{ vreg-use f 7 } T{ vreg-use f 10 } T{ vreg-use f 15 } } }
+ { uses V{ T{ vreg-use f int-rep 1 } T{ vreg-use f int-rep 3 } T{ vreg-use f int-rep 7 } T{ vreg-use f int-rep 10 } T{ vreg-use f int-rep 15 } } }
}
T{ live-interval
{ vreg 2 }
{ reg 2 }
{ start 3 }
{ end 8 }
- { uses V{ T{ vreg-use f 3 } T{ vreg-use f 4 } T{ vreg-use f 8 } } }
+ { uses V{ T{ vreg-use f int-rep 3 } T{ vreg-use f int-rep 4 } T{ vreg-use f int-rep 8 } } }
}
T{ live-interval
{ vreg 3 }
{ reg 3 }
{ start 3 }
{ end 10 }
- { uses V{ T{ vreg-use f 3 } T{ vreg-use f 10 } } }
+ { uses V{ T{ vreg-use f int-rep 3 } T{ vreg-use f int-rep 10 } } }
}
}
}
{ reg-class int-regs }
{ start 5 }
{ end 5 }
- { uses V{ T{ vreg-use f 5 } } }
+ { uses V{ T{ vreg-use f int-rep 5 } } }
}
spill-status
] unit-test
{ reg 1 }
{ start 1 }
{ end 15 }
- { uses V{ T{ vreg-use f 1 } } }
+ { uses V{ T{ vreg-use f int-rep 1 } } }
}
T{ live-interval
{ vreg 2 }
{ reg 2 }
{ start 3 }
{ end 8 }
- { uses V{ T{ vreg-use f 3 } T{ vreg-use f 8 } } }
+ { uses V{ T{ vreg-use f int-rep 3 } T{ vreg-use f int-rep 8 } } }
}
}
}
{ reg-class int-regs }
{ start 5 }
{ end 5 }
- { uses V{ T{ vreg-use f 5 } } }
+ { uses V{ T{ vreg-use f int-rep 5 } } }
}
spill-status
] unit-test
{ reg-class int-regs }
{ start 0 }
{ end 100 }
- { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } }
+ { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 100 } } }
{ ranges V{ T{ live-range f 0 100 } } }
}
}
{ reg-class int-regs }
{ start 0 }
{ end 10 }
- { uses V{ T{ vreg-use f 0 } T{ vreg-use f 10 } } }
+ { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 10 } } }
{ ranges V{ T{ live-range f 0 10 } } }
}
T{ live-interval
{ reg-class int-regs }
{ start 11 }
{ end 20 }
- { uses V{ T{ vreg-use f 11 } T{ vreg-use f 20 } } }
+ { uses V{ T{ vreg-use f int-rep 11 } T{ vreg-use f int-rep 20 } } }
{ ranges V{ T{ live-range f 11 20 } } }
}
}
{ reg-class int-regs }
{ start 0 }
{ end 100 }
- { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } }
+ { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 100 } } }
{ ranges V{ T{ live-range f 0 100 } } }
}
T{ live-interval
{ reg-class int-regs }
{ start 30 }
{ end 60 }
- { uses V{ T{ vreg-use f 30 } T{ vreg-use f 60 } } }
+ { uses V{ T{ vreg-use f int-rep 30 } T{ vreg-use f int-rep 60 } } }
{ ranges V{ T{ live-range f 30 60 } } }
}
}
{ reg-class int-regs }
{ start 0 }
{ end 100 }
- { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } }
+ { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 100 } } }
{ ranges V{ T{ live-range f 0 100 } } }
}
T{ live-interval
{ reg-class int-regs }
{ start 30 }
{ end 200 }
- { uses V{ T{ vreg-use f 30 } T{ vreg-use f 200 } } }
+ { uses V{ T{ vreg-use f int-rep 30 } T{ vreg-use f int-rep 200 } } }
{ ranges V{ T{ live-range f 30 200 } } }
}
}
{ reg-class int-regs }
{ start 0 }
{ end 100 }
- { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } }
+ { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 100 } } }
{ ranges V{ T{ live-range f 0 100 } } }
}
T{ live-interval
{ reg-class int-regs }
{ start 30 }
{ end 100 }
- { uses V{ T{ vreg-use f 30 } T{ vreg-use f 100 } } }
+ { uses V{ T{ vreg-use f int-rep 30 } T{ vreg-use f int-rep 100 } } }
{ ranges V{ T{ live-range f 30 100 } } }
}
}
{ reg-class int-regs }
{ start 0 }
{ end 20 }
- { uses V{ T{ vreg-use f 0 } T{ vreg-use f 10 } T{ vreg-use f 20 } } }
+ { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 10 } T{ vreg-use f int-rep 20 } } }
{ ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } }
}
T{ live-interval
{ reg-class int-regs }
{ start 0 }
{ end 20 }
- { uses V{ T{ vreg-use f 0 } T{ vreg-use f 10 } T{ vreg-use f 20 } } }
+ { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 10 } T{ vreg-use f int-rep 20 } } }
{ ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } }
}
T{ live-interval
{ reg-class int-regs }
{ start 4 }
{ end 8 }
- { uses V{ T{ vreg-use f 6 } } }
+ { uses V{ T{ vreg-use f int-rep 6 } } }
{ ranges V{ T{ live-range f 4 8 } } }
}
T{ live-interval
{ reg-class int-regs }
{ start 4 }
{ end 8 }
- { uses V{ T{ vreg-use f 8 } } }
+ { uses V{ T{ vreg-use f int-rep 8 } } }
{ ranges V{ T{ live-range f 4 8 } } }
}
{ reg-class int-regs }
{ start 4 }
{ end 8 }
- { uses V{ T{ vreg-use f 8 } } }
+ { uses V{ T{ vreg-use f int-rep 8 } } }
{ ranges V{ T{ live-range f 4 8 } } }
}
}
{ reg-class int-regs }
{ start 0 }
{ end 10 }
- { uses V{ T{ vreg-use f 0 } T{ vreg-use f 6 } T{ vreg-use f 10 } } }
+ { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 6 } T{ vreg-use f int-rep 10 } } }
{ ranges V{ T{ live-range f 0 10 } } }
}
{ reg-class int-regs }
{ start 2 }
{ end 8 }
- { uses V{ T{ vreg-use f 8 } } }
+ { uses V{ T{ vreg-use f int-rep 8 } } }
{ ranges V{ T{ live-range f 2 8 } } }
}
}
{ start 8 }
{ end 10 }
{ ranges V{ T{ live-range f 8 10 } } }
- { uses V{ T{ vreg-use f 8 } T{ vreg-use f 10 } } }
+ { uses V{ T{ vreg-use f int-rep 8 } T{ vreg-use f int-rep 10 } } }
}
register-status
] unit-test
T{ ##copy
{ dst 689607 }
{ src 689604 }
+ { rep int-rep }
}
T{ ##copy
{ dst 689608 }
! Copyright (C) 2008, 2010 Slava Pestov.
! 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.linearization.order
-compiler.cfg cpu.architecture ;
+USING: namespaces kernel assocs accessors locals sequences math
+math.order fry combinators binary-search
+compiler.cfg.instructions compiler.cfg.registers
+compiler.cfg.def-use compiler.cfg.liveness
+compiler.cfg.linearization.order
+compiler.cfg
+cpu.architecture ;
IN: compiler.cfg.linear-scan.live-intervals
TUPLE: live-range from to ;
SYMBOLS: +def+ +use+ +memory+ ;
-TUPLE: vreg-use n type ;
+TUPLE: vreg-use rep n type ;
C: <vreg-use> vreg-use
2dup extend-range?
[ extend-range ] [ add-new-range ] if ;
-: add-use ( insn live-interval type -- )
- dup +memory+ eq? [ 3drop ] [
- swap [ [ insn#>> ] dip <vreg-use> ] dip
- uses>> push
- ] if ;
+:: add-use ( rep n type live-interval -- )
+ type +memory+ eq? [
+ rep n type <vreg-use>
+ live-interval uses>> push
+ ] unless ;
-: <live-interval> ( vreg -- live-interval )
+: <live-interval> ( vreg reg-class -- live-interval )
\ live-interval new
V{ } clone >>uses
V{ } clone >>ranges
- over rep-of reg-class-of >>reg-class
+ swap >>reg-class
swap >>vreg ;
: block-from ( bb -- n ) instructions>> first insn#>> 1 - ;
: block-to ( bb -- n ) instructions>> last insn#>> ;
+SYMBOLS: from to ;
+
! Mapping from vreg to live-interval
SYMBOL: live-intervals
: live-interval ( vreg -- live-interval )
- live-intervals get [ <live-interval> ] cache ;
+ live-intervals get [ dup rep-of reg-class-of <live-interval> ] cache ;
GENERIC: compute-live-intervals* ( insn -- )
M: insn compute-live-intervals* drop ;
-: handle-output ( insn vreg type -- )
- [ live-interval ] dip
- [ drop [ insn#>> ] dip shorten-range ] [ add-use ] 3bi ;
+:: handle-output ( vreg n type -- )
+ vreg rep-of :> rep
+ vreg live-interval :> live-interval
+
+ n live-interval shorten-range
+ rep n type live-interval add-use ;
+
+:: handle-input ( vreg n type -- )
+ vreg rep-of :> rep
+ vreg live-interval :> live-interval
+
+ from get n live-interval add-range
+ rep n type live-interval add-use ;
+
+:: handle-temp ( vreg n -- )
+ vreg rep-of :> rep
+ vreg live-interval :> live-interval
-: handle-input ( insn vreg type -- )
- [ live-interval ] dip
- [ drop [ [ basic-block get block-from ] dip insn#>> ] dip add-range ]
- [ add-use ]
- 3bi ;
+ n n live-interval add-range
+ rep n +def+ live-interval add-use ;
-: handle-temp ( insn vreg -- )
- live-interval
- [ [ insn#>> dup ] dip add-range ] [ +def+ add-use ] 2bi ;
+M:: vreg-insn compute-live-intervals* ( insn -- )
+ insn insn#>> :> n
-M: vreg-insn compute-live-intervals*
- [ dup defs-vreg [ +def+ handle-output ] with when* ]
- [ dup uses-vregs [ +use+ handle-input ] with each ]
- [ dup temp-vregs [ handle-temp ] with each ]
- tri ;
+ insn defs-vreg [ n +def+ handle-output ] when*
+ insn uses-vregs [ n +use+ handle-input ] each
+ insn temp-vregs [ n handle-temp ] each ;
-M: clobber-insn compute-live-intervals*
- [ dup defs-vreg [ +use+ handle-output ] with when* ]
- [ dup uses-vregs [ +memory+ handle-input ] with each ]
- [ dup temp-vregs [ handle-temp ] with each ]
- tri ;
+M:: clobber-insn compute-live-intervals* ( insn -- )
+ insn insn#>> :> n
+
+ insn defs-vreg [ n +use+ handle-output ] when*
+ insn uses-vregs [ n +memory+ handle-input ] each
+ insn temp-vregs [ n handle-temp ] each ;
: handle-live-out ( bb -- )
- [ block-from ] [ block-to ] [ live-out keys ] tri
- [ live-interval add-range ] with with each ;
+ live-out dup assoc-empty? [ drop ] [
+ [ from get to get ] dip keys
+ [ live-interval add-range ] with with each
+ ] if ;
! A location where all registers have to be spilled
TUPLE: sync-point n ;
M: insn compute-sync-points* drop ;
: compute-live-intervals-step ( bb -- )
- [ basic-block set ]
- [ handle-live-out ]
- [
- instructions>> <reversed> [
- [ compute-live-intervals* ]
- [ compute-sync-points* ]
- bi
- ] each
- ] tri ;
+ {
+ [ block-from from set ]
+ [ block-to to set ]
+ [ handle-live-out ]
+ [
+ instructions>> <reversed> [
+ [ compute-live-intervals* ]
+ [ compute-sync-points* ]
+ bi
+ ] each
+ ]
+ } cleave ;
: init-live-intervals ( -- )
H{ } clone live-intervals set
-! Copyright (C) 2009 Slava Pestov.
+! Copyright (C) 2009, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: kernel namespaces accessors compiler.cfg
-compiler.cfg.linearization compiler.cfg.linear-scan
-compiler.cfg.build-stack-frame ;
+USING: compiler.cfg.linearization compiler.cfg.build-stack-frame ;
IN: compiler.cfg.mr
: build-mr ( cfg -- mr )
- linear-scan
flatten-cfg
build-stack-frame ;
\ No newline at end of file
! Copyright (C) 2008, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: kernel sequences accessors combinators namespaces
-compiler.cfg.tco
+USING: compiler.cfg.tco
compiler.cfg.useless-conditionals
compiler.cfg.branch-splitting
compiler.cfg.block-joining
compiler.cfg.checker ;
IN: compiler.cfg.optimizer
-SYMBOL: check-optimizer?
-
-: ?check ( cfg -- cfg' )
- check-optimizer? get [
- dup check-cfg
- ] when ;
-
: optimize-cfg ( cfg -- cfg' )
optimize-tail-calls
delete-useless-conditionals
value-numbering
copy-propagation
eliminate-dead-code
- eliminate-write-barriers
- select-representations
- insert-gc-checks
- insert-save-contexts
- destruct-ssa
- delete-empty-blocks
- ?check ;
+ eliminate-write-barriers ;
! Copyright (C) 2009, 2010 Slava Pestov
! See http://factorcode.org/license.txt for BSD license.
-USING: accessors combinators namespaces
+USING: combinators
compiler.cfg
compiler.cfg.registers
compiler.cfg.predecessors
[ compute-representations ]
[ insert-conversions ]
[ ]
- } cleave
- representations get cfg get (>>reps) ;
+ } cleave ;
: leader ( vreg -- vreg' ) leader-map get compress-path ;
+! Maps basic blocks to ##phi instruction outputs
+SYMBOL: phi-sets
+
+: phi-set ( bb -- vregs ) phi-sets get at ;
+
! Maps leaders to equivalence class elements.
SYMBOL: class-element-map
[ call-next-method drop ]
[ [ dst>> ] [ src>> ] bi eq? not ] bi ;
-M: ##phi rename-insn drop f ;
+SYMBOL: current-phi-set
+
+M: ##phi rename-insn dst>> current-phi-set get push f ;
M: ##call-gc rename-insn
[ renamings get '[ _ at ] map members ] change-gc-roots drop t ;
M: insn rename-insn drop t ;
+: renaming-in-block ( bb -- )
+ V{ } clone current-phi-set set
+ [ [ current-phi-set ] dip phi-sets get set-at ]
+ [ instructions>> [ rename-insn ] filter! drop ]
+ bi ;
+
: perform-renaming ( cfg -- )
+ H{ } clone phi-sets set
leader-map get keys [ dup leader ] H{ } map>assoc renamings set
- [ instructions>> [ rename-insn ] filter! drop ] each-basic-block ;
+ [ renaming-in-block ] each-basic-block ;
: destruct-ssa ( cfg -- cfg' )
needs-dominance
compiler.cfg
compiler.cfg.builder
compiler.cfg.optimizer
+compiler.cfg.finalization
compiler.cfg.mr
compiler.codegen ;
: backend ( tree word -- )
build-cfg [
- [ optimize-cfg build-mr ] with-cfg
+ [ optimize-cfg finalize-cfg build-mr ] with-cfg
[ generate ] [ label>> ] bi compiled get set-at
] each ;
USING: accessors assocs compiler compiler.cfg
compiler.cfg.debugger compiler.cfg.instructions compiler.cfg.mr
-compiler.cfg.registers compiler.codegen compiler.units
-cpu.architecture hashtables kernel namespaces sequences
-tools.test vectors words layouts literals math arrays
+compiler.cfg.registers compiler.cfg.linear-scan compiler.codegen
+compiler.units cpu.architecture hashtables kernel namespaces
+sequences tools.test vectors words layouts literals math arrays
alien.c-types alien.syntax math.private ;
IN: compiler.tests.low-level-ir
: compile-cfg ( cfg -- word )
gensym
- [ build-mr generate ] dip
+ [ linear-scan build-mr generate ] dip
[ associate >alist t t modify-code-heap ] keep ;
: compile-test-cfg ( -- word )
cfg new 0 get >>entry
dup cfg set
- dup fake-representations representations get >>reps
+ dup fake-representations
compile-cfg ;
: compile-test-bb ( insns -- result )