[ [ ##peek? ] count 1 assert= ]
[ [ ##replace? ] count 1 assert= ]
tri
+] unit-test
+
+! Sync before a back-edge, not after
+[ 1 ] [
+ [ 1000 [ ] times ] test-stack-analysis eliminate-dead-code linearize-basic-blocks
+ [ ##add-imm? ] count
] unit-test
\ No newline at end of file
USING: accessors assocs kernel namespaces math sequences fry grouping
sets make combinators compiler.cfg.copy-prop compiler.cfg.def-use
compiler.cfg.instructions compiler.cfg.registers compiler.cfg.rpo
-compiler.cfg.hats ;
+compiler.cfg.hats compiler.cfg ;
IN: compiler.cfg.stack-analysis
! Convert stack operations to register operations
M: neutral-insn visit , ;
+UNION: sync-if-back-edge
+ ##branch
+ ##conditional-branch
+ ##compare-imm-branch ;
+
+M: sync-if-back-edge visit
+ basic-block get [ successors>> ] [ number>> ] bi '[ number>> _ < ] any?
+ [ sync-state ] when
+ , ;
+
: adjust-d ( n -- ) state get [ + ] change-d-height drop ;
M: ##inc-d visit [ , ] [ n>> adjust-d ] bi ;
: with-state ( state quot -- )
[ state ] dip with-variable ; inline
-: handle-back-edge ( bb states -- )
- [ predecessors>> ] dip [
- dup [
- [ [ sync-state ] modify-instructions ] with-state
- ] [ 2drop ] if
- ] 2each ;
-
ERROR: must-equal-failed seq ;
: must-equal ( seq -- elt )
[
drop
dup [ not ] any? [
- handle-back-edge <state>
+ 2drop <state>
] [
dup [ poisoned?>> ] any? [
cannot-merge-poisoned
! block-in-state may add phi nodes at the start of the basic block
! so we wrap the whole thing with a 'make'
[
+ dup basic-block set
dup block-in-state
[ swap set-block-in-state ] [
[