diff --git a/basis/compiler/cfg/stacks/clearing/clearing-tests.factor b/basis/compiler/cfg/stacks/clearing/clearing-tests.factor index 14fe4f0fc9..d1737bdd92 100644 --- a/basis/compiler/cfg/stacks/clearing/clearing-tests.factor +++ b/basis/compiler/cfg/stacks/clearing/clearing-tests.factor @@ -7,8 +7,8 @@ IN: compiler.cfg.stacks.clearing.tests { V{ T{ ##inc { loc D 2 } { insn# 0 } } - T{ ##replace-imm { src 17 } { loc T{ ds-loc { n 1 } } } } - T{ ##replace-imm { src 17 } { loc T{ ds-loc } } } + T{ ##replace-imm { src 297 } { loc T{ ds-loc { n 1 } } } } + T{ ##replace-imm { src 297 } { loc T{ ds-loc } } } T{ ##peek { loc D 2 } { insn# 1 } } } } [ @@ -17,31 +17,39 @@ IN: compiler.cfg.stacks.clearing.tests ] unit-test ! dangerous-insn? -{ t f f } [ +{ + t f t +} [ { { 0 { } } { 0 { } } } T{ ##peek { loc D 0 } } dangerous-insn? - { { 1 { 0 } } { 0 { } } } T{ ##peek { loc D 0 } } dangerous-insn? - { { 0 { -1 } } { 0 { } } } T{ ##peek { loc D -1 } } dangerous-insn? + { { 1 { } } { 0 { } } } T{ ##peek { loc D 0 } } dangerous-insn? + { { 2 { 0 1 } } { 0 { } } } T{ ##peek { loc D 2 } } dangerous-insn? ] unit-test ! state>replaces { - { - T{ ##replace-imm { src 17 } { loc D 1 } } - T{ ##replace-imm { src 17 } { loc D 0 } } - } + { } } [ { { 2 { } } { 0 { } } } state>replaces ] unit-test +{ + { + T{ ##replace-imm { src 297 } { loc D 1 } } + T{ ##replace-imm { src 297 } { loc D 0 } } + } +} [ + { { 2 { 0 1 } } { 0 { } } } state>replaces +] unit-test + { { } } [ { { 0 { } } { 0 { } } } state>replaces ] unit-test { { - T{ ##replace-imm { src 17 } { loc T{ ds-loc } } } - T{ ##replace-imm { src 17 } { loc T{ rs-loc } } } + T{ ##replace-imm { src 297 } { loc T{ ds-loc } } } + T{ ##replace-imm { src 297 } { loc T{ rs-loc } } } } } [ - { { 1 { } } { 1 { } } } state>replaces + { { 1 { 0 } } { 1 { 0 } } } state>replaces ] unit-test diff --git a/basis/compiler/cfg/stacks/clearing/clearing.factor b/basis/compiler/cfg/stacks/clearing/clearing.factor index 5df62202a5..128302fba2 100644 --- a/basis/compiler/cfg/stacks/clearing/clearing.factor +++ b/basis/compiler/cfg/stacks/clearing/clearing.factor @@ -3,9 +3,11 @@ compiler.cfg.instructions compiler.cfg.registers compiler.cfg.rpo compiler.cfg.stacks compiler.cfg.stacks.padding kernel math sequences ; IN: compiler.cfg.stacks.clearing +! This step maybe is redundant. + : state>replaces ( state -- replaces ) - [ stack>vacant ] map { ds-loc rs-loc } [ swap create-locs ] 2map concat - [ 17 swap f ##replace-imm boa ] map ; + [ second ] map { ds-loc rs-loc } [ swap create-locs ] 2map concat + [ 297 swap f ##replace-imm boa ] map ; : dangerous-insn? ( state insn -- ? ) { [ nip ##peek? ] [ underflowable-peek? ] } 2&& ; diff --git a/basis/compiler/cfg/stacks/padding/padding-tests.factor b/basis/compiler/cfg/stacks/padding/padding-tests.factor index b74f07c3f4..8fd719f0f4 100644 --- a/basis/compiler/cfg/stacks/padding/padding-tests.factor +++ b/basis/compiler/cfg/stacks/padding/padding-tests.factor @@ -3,9 +3,10 @@ compiler.cfg.stacks.padding compiler.cfg.utilities kernel sequences sorting vectors tools.test ; IN: compiler.cfg.stacks.padding.tests -! classify-read: vacant locations -{ 2 2 2 } [ +! classify-read: initialized locations +{ 0 0 0 } [ { 3 { } } 2 classify-read + ! Negative locations aren't tracked really. { 0 { } } -1 classify-read { 3 { } } -1 classify-read ] unit-test @@ -19,44 +20,38 @@ IN: compiler.cfg.stacks.padding.tests { 1 { 0 } } 4 classify-read ] unit-test -! classify-read: initialized locations -{ 0 0 0 } [ +! classify-read: vacant locations +{ 2 2 2 } [ { 1 { 0 } } 0 classify-read { 2 { 0 1 2 } } 0 classify-read { 0 { 0 1 2 } } 0 classify-read ] unit-test -! fill-stack +! all-live { - { 2 { 4 5 0 1 } } + { { 0 { } } { 2 { } } } + { { 0 { } } { 2 { } } } } [ - { 2 { 4 5 } } fill-stack + { { 0 { } } { 2 { } } } all-live + { { 0 { } } { 2 { 0 } } } all-live ] unit-test -{ - { -1 { 3 4 } } -} [ - { -1 { 3 4 } } fill-stack -] unit-test - -! fill-vacancies -{ - { { 0 { } } { 2 { 0 1 } } } - { { 0 { } } { 2 { 0 1 } } } - { { 0 { -1 -2 } } { 2 { 0 1 } } } -} [ - { { 0 { } } { 2 { } } } fill-vacancies - { { 0 { } } { 2 { 0 } } } fill-vacancies - { { 0 { -1 -2 } } { 2 { 0 } } } fill-vacancies -] unit-test - -! combined-state +! combine-states { { { 4 { } } { 2 { 0 1 } } } } [ V{ { { 4 { } } { 2 { 0 1 } } } } combine-states ] unit-test +{ + { { 2 { 0 1 } } { 2 { 0 1 } } } +} [ + V{ + { { 2 { 0 1 } } { 2 { } } } + { { 2 { } } { 2 { 0 1 } } } + } combine-states +] unit-test + { { { 0 { } } { 0 { } } } } [ @@ -73,17 +68,6 @@ IN: compiler.cfg.stacks.padding.tests combine-states ] [ height-mismatches? ] must-fail-with -! stack>vacant -{ - { 0 1 2 } - { } - { 1 } -} [ - { 3 { } } stack>vacant - { -2 { } } stack>vacant - { 3 { 0 2 } } stack>vacant -] unit-test - ! visit-insn ##inc ! We assume that overinitialized locations are always dead. @@ -93,13 +77,18 @@ IN: compiler.cfg.stacks.padding.tests { { 3 { 0 } } { 0 { } } } T{ ##inc { loc D -3 } } visit-insn ] unit-test -! visit-insn ##call { { { 3 { 0 1 2 } } { 0 { } } } } [ - initial-state T{ ##call { height 3 } } visit-insn + { { 0 { } } { 0 { } } } T{ ##inc { loc D 3 } } visit-insn ] unit-test +! visit-insn ##call +{ + { { 3 { } } { 0 { } } } +} [ + initial-state T{ ##call { height 3 } } visit-insn +] unit-test { { { -1 { } } { 0 { } } } @@ -107,16 +96,15 @@ IN: compiler.cfg.stacks.padding.tests initial-state T{ ##call { height -1 } } visit-insn ] unit-test - { - { { 4 { 2 3 0 1 } } { 0 { } } } + { { 4 { } } { 0 { } } } } [ - { { 2 { 0 1 } } { 0 { } } } T{ ##call { height 2 } } visit-insn + { { 2 { } } { 0 { } } } T{ ##call { height 2 } } visit-insn ] unit-test ! This looks weird but is right. { - { { 0 { 0 1 } } { 0 { } } } + { { 0 { } } { 0 { } } } } [ { { -2 { } } { 0 { } } } T{ ##call { height 2 } } visit-insn ] unit-test @@ -126,66 +114,40 @@ IN: compiler.cfg.stacks.padding.tests ! visisted then something is wrong. ##call might gc and the ! uninitialized locations would cause a crash. [ - { { 3 { } } { 0 { } } } T{ ##call { height 3 } } visit-insn + { { 3 { 0 1 2 } } { 0 { } } } T{ ##call { height 3 } } visit-insn ] [ vacant-when-calling? ] must-fail-with -! ! Overinitialized locations can't be live when ##call is visited. They -! ! could be garbage collected in the called word so they maybe wouldn't -! ! survive. -! [ -! { { 0 { -1 -2 } } { 0 { -1 -2 } } } T{ ##call { height 0 } } visit-insn -! ] [ overinitialized-when-calling? ] must-fail-with - -! This is tricky. Normally, there should be no overinitialized -! locations before a ##call (I think). But if they are, we can at -! least be sure they are dead after the call. -{ - { { 2 { 0 1 } } { 0 { } } } -} [ - { { 2 { 0 1 -1 } } { 0 { } } } T{ ##call { height 0 } } visit-insn -] unit-test - ! visit-insn ##call-gc -! ##call-gc ofcourse fills all uninitialized locations. +! ##call-gc ofcourse fills all uninitialized locations. ##peek still +! shouldn't look at them, but if we gc again we don't need to exept ##them. { - { { 4 { 0 1 2 3 } } { 0 { } } } + { { 4 { } } { 0 { } } } } [ - { { 4 { } } { 0 { } } } T{ ##call-gc } visit-insn + { { 4 { 0 1 2 3 } } { 0 { } } } T{ ##call-gc } visit-insn ] unit-test - -[ - { { 2 { -1 0 1 } } { 0 { } } } T{ ##call-gc } visit-insn -] [ overinitialized-when-gc? ] must-fail-with - ! visit-insn ##peek { { { 3 { 0 } } { 0 { } } } } [ - { { 3 { 0 } } { 0 { } } } T{ ##peek { dst 1 } { loc D 0 } } visit-insn + { { 3 { 0 } } { 0 { } } } T{ ##peek { dst 1 } { loc D 1 } } visit-insn ] unit-test ! After a ##peek that can cause a stack underflow, it is certain that ! all stack locations are initialized. { - { { 0 { } } { 2 { 0 1 2 } } } - { { 2 { 0 1 2 } } { 0 { } } } + { { 0 { } } { 2 { } } } + { { 2 { } } { 0 { } } } } [ - { { 0 { } } { 2 { } } } T{ ##peek { dst 1 } { loc R 2 } } visit-insn - { { 2 { } } { 0 { } } } T{ ##peek { dst 1 } { loc D 2 } } visit-insn -] unit-test - -{ - { { 2 { 0 1 } } { 2 { 0 1 2 } } } -} [ - { { 2 { } } { 2 { } } } T{ ##peek { dst 1 } { loc R 2 } } visit-insn + { { 0 { } } { 2 { 0 1 } } } T{ ##peek { dst 1 } { loc R 2 } } visit-insn + { { 2 { 0 1 } } { 0 { } } } T{ ##peek { dst 1 } { loc D 2 } } visit-insn ] unit-test ! If the ##peek can't cause a stack underflow, then we don't have the ! same guarantees. [ - { { 3 { } } { 0 { } } } T{ ##peek { dst 1 } { loc D 0 } } visit-insn + { { 3 { 0 1 2 } } { 0 { } } } T{ ##peek { dst 1 } { loc D 0 } } visit-insn ] [ vacant-peek? ] must-fail-with : following-stack-state ( insns -- state ) @@ -201,11 +163,11 @@ IN: compiler.cfg.stacks.padding.tests } { 1 - { { 2 { } } { 0 { } } } + { { 2 { 0 1 } } { 0 { } } } } { 2 - { { 2 { 0 1 2 } } { 0 { } } } + { { 2 { } } { 0 { } } } } } } [ @@ -231,8 +193,8 @@ IN: compiler.cfg.stacks.padding.tests { H{ { 0 { { 0 { } } { 0 { } } } } - { 1 { { 3 { } } { 0 { } } } } - { 2 { { 3 { 0 1 2 3 } } { 0 { } } } } + { 1 { { 3 { 0 1 2 } } { 0 { } } } } + { 2 { { 3 { } } { 0 { } } } } } } [ V{ @@ -243,22 +205,6 @@ IN: compiler.cfg.stacks.padding.tests insns>cfg trace-stack-state2 ] unit-test -! Replace -1 then peek is ok. -{ - H{ - { 0 { { 0 { } } { 0 { } } } } - { 1 { { 0 { -1 } } { 0 { } } } } - { 2 { { 0 { -1 } } { 0 { } } } } - } -} [ - V{ - T{ ##replace { src 10 } { loc D -1 } } - T{ ##peek { loc D -1 } } - T{ ##branch } - } - insns>cfg trace-stack-state2 -] unit-test - : cfg1 ( -- cfg ) V{ T{ ##inc f D 1 } @@ -273,9 +219,9 @@ IN: compiler.cfg.stacks.padding.tests { H{ { 0 { { 0 { } } { 0 { } } } } - { 1 { { 1 { } } { 0 { } } } } - { 2 { { 1 { 0 } } { 0 { } } } } - { 3 { { 1 { 0 } } { 0 { } } } } + { 1 { { 1 { 0 } } { 0 { } } } } + { 2 { { 1 { } } { 0 { } } } } + { 3 { { 1 { } } { 0 { } } } } } } [ cfg1 trace-stack-state2 ] unit-test @@ -333,25 +279,26 @@ IN: compiler.cfg.stacks.padding.tests { 1 { { 0 { } } { 0 { } } } } { 2 { { 0 { } } { 0 { } } } } { 3 { { 0 { } } { 0 { } } } } - { 4 { { 2 { } } { 0 { } } } } - { 5 { { 2 { 1 } } { 0 { } } } } - { 6 { { 2 { 1 0 } } { 0 { } } } } - { 7 { { 2 { 1 0 } } { 0 { } } } } - { 8 { { 2 { 1 0 } } { 0 { } } } } - { 9 { { 2 { 1 0 } } { 0 { } } } } - { 10 { { 4 { 3 2 } } { 0 { } } } } - { 11 { { 4 { 3 2 } } { 0 { } } } } - { 12 { { 4 { 3 2 } } { 0 { } } } } - { 13 { { 4 { 3 2 1 } } { 0 { } } } } - { 14 { { 4 { 3 2 1 } } { 0 { } } } } - { 15 { { 4 { 3 2 1 } } { 0 { } } } } - { 16 { { 7 { 6 5 4 } } { 0 { } } } } - { 17 { { 7 { 6 5 4 0 } } { 0 { } } } } - { 18 { { 7 { 6 5 4 0 1 } } { 0 { } } } } - { 19 { { 7 { 6 5 4 0 1 2 } } { 0 { } } } } - { 20 { { 7 { 6 5 4 0 1 2 3 } } { 0 { } } } } - { 21 { { 4 { 3 2 1 0 } } { 0 { } } } } - { 22 { { 4 { 3 2 1 0 } } { 0 { } } } } + { 4 { { 2 { 0 1 } } { 0 { } } } } + { 5 { { 2 { 0 } } { 0 { } } } } + { 6 { { 2 { } } { 0 { } } } } + { 7 { { 2 { } } { 0 { } } } } + { 8 { { 2 { } } { 0 { } } } } + { 9 { { 2 { } } { 0 { } } } } + { 10 { { 4 { 0 1 } } { 0 { } } } } + { 11 { { 4 { 0 1 } } { 0 { } } } } + { 12 { { 4 { 0 1 } } { 0 { } } } } + { 13 { { 4 { 0 } } { 0 { } } } } + { 14 { { 4 { 0 } } { 0 { } } } } + { 15 { { 4 { 0 } } { 0 { } } } } + { 16 { { 7 { 3 0 1 2 } } { 0 { } } } } + { 17 { { 7 { 3 1 2 } } { 0 { } } } } + { 18 { { 7 { 3 2 } } { 0 { } } } } + { 19 { { 7 { 3 } } { 0 { } } } } + { 20 { { 7 { } } { 0 { } } } } + { 21 { { 4 { } } { 0 { } } } } + ! gc-map here + { 22 { { 4 { } } { 0 { } } } } } } [ bug1021-cfg trace-stack-state2 @@ -458,77 +405,237 @@ IN: compiler.cfg.stacks.padding.tests { H{ { 0 { { 0 { } } { 0 { } } } } - { 1 { { 3 { } } { 0 { } } } } - { 2 { { 3 { 2 } } { 0 { } } } } - { 3 { { 3 { 2 0 } } { 0 { } } } } - { 4 { { 3 { 2 0 1 } } { 0 { } } } } - { 5 { { 2 { 1 0 } } { 0 { } } } } - { 6 { { 2 { 1 0 } } { 0 { } } } } - { 7 { { 2 { 1 0 } } { 0 { } } } } - { 8 { { 3 { 2 1 } } { 0 { } } } } - { 9 { { 3 { 2 1 } } { 1 { } } } } - { 10 { { 3 { 2 } } { 1 { 0 } } } } - { 11 { { 1 { 0 } } { 1 { 0 } } } } - { 12 { { 1 { 0 } } { 6 { 5 } } } } - { 13 { { 1 { 0 } } { 6 { 5 3 } } } } - { 14 { { 1 { 0 } } { 6 { 5 3 } } } } - { 15 { { 1 { 0 } } { 6 { 5 3 4 } } } } - { 16 { { 1 { 0 } } { 6 { 5 3 4 2 } } } } - { 17 { { 1 { 0 } } { 6 { 5 3 4 2 1 } } } } - { 18 { { 1 { 0 } } { 6 { 5 3 4 2 1 0 } } } } - { 19 { { 1 { 0 } } { 6 { 5 3 4 2 1 0 } } } } - { 20 { { 1 { 0 } } { 6 { 5 3 4 2 1 0 } } } } - { 21 { { 1 { 0 } } { 6 { 5 3 4 2 1 0 } } } } - { 22 { { 1 { 0 } } { 6 { 5 3 4 2 1 0 } } } } - { 23 { { 1 { 0 } } { 6 { 5 3 4 2 1 0 } } } } - { 24 { { 1 { 0 } } { 6 { 5 3 4 2 1 0 } } } } - { 25 { { 1 { 0 } } { 6 { 5 3 4 2 1 0 } } } } - { 26 { { 3 { 2 } } { 6 { 5 3 4 2 1 0 } } } } - { 27 { { 3 { 2 } } { 1 { 0 } } } } - { 28 { { 3 { 2 } } { 1 { 0 } } } } - { 29 { { 3 { 2 } } { 1 { 0 } } } } - { 30 { { 0 { } } { 1 { 0 } } } } - { 31 { { 1 { } } { 1 { 0 } } } } - { 32 { { 1 { } } { 0 { } } } } + { 1 { { 3 { 0 1 2 } } { 0 { } } } } + { 2 { { 3 { 0 1 } } { 0 { } } } } + { 3 { { 3 { 1 } } { 0 { } } } } + { 4 { { 3 { } } { 0 { } } } } + { 5 { { 2 { } } { 0 { } } } } + { 6 { { 2 { } } { 0 { } } } } + { 7 { { 2 { } } { 0 { } } } } + { 8 { { 3 { 0 } } { 0 { } } } } + { 9 { { 3 { 0 } } { 1 { 0 } } } } + { 10 { { 3 { 0 1 } } { 1 { } } } } + { 11 { { 1 { } } { 1 { } } } } + { 12 { { 1 { } } { 6 { 0 1 2 3 4 } } } } + { 13 { { 1 { } } { 6 { 0 1 2 4 } } } } + { 14 { { 1 { } } { 6 { 0 1 2 4 } } } } + { 15 { { 1 { } } { 6 { 0 1 2 } } } } + { 16 { { 1 { } } { 6 { 0 1 } } } } + { 17 { { 1 { } } { 6 { 0 } } } } + { 18 { { 1 { } } { 6 { } } } } + { 19 { { 1 { } } { 6 { } } } } + { 20 { { 1 { } } { 6 { } } } } + { 21 { { 1 { } } { 6 { } } } } + { 22 { { 1 { } } { 6 { } } } } + { 23 { { 1 { } } { 6 { } } } } + { 24 { { 1 { } } { 6 { } } } } + { 25 { { 1 { } } { 6 { } } } } + { 26 { { 3 { 0 1 } } { 6 { } } } } + { 27 { { 3 { 0 1 } } { 1 { } } } } + ! gc-map here + { 28 { { 3 { 0 1 } } { 1 { } } } } + { 29 { { 3 { 0 1 } } { 1 { } } } } + { 30 { { 0 { } } { 1 { } } } } + { 31 { { 1 { 0 } } { 1 { } } } } + { 32 { { 1 { 0 } } { 0 { } } } } } } [ bug1289-cfg trace-stack-state2 ] unit-test +: bug-benchmark-terrain-cfg ( -- cfg ) + H{ + { 0 V{ } } + { + 1 V{ + T{ ##peek { loc D 0 } } + T{ ##peek { loc D 1 } } + T{ ##inc { loc D -1 } } + } + } + { + 2 V{ + T{ ##inc { loc D -1 } } + T{ ##replace { loc D 1 } } + T{ ##replace { loc D 0 } } + T{ ##inc { loc D 1 } } + T{ ##replace { loc D 0 } } + } + } + { 3 V{ T{ ##call { height -1 } } } } + { 4 V{ } } + { 5 V{ T{ ##call { height 0 } } } } + { 6 V{ T{ ##peek { loc D 0 } } } } + { 7 V{ } } + { + 8 V{ + T{ ##replace { loc D 2 } } + T{ ##replace { loc D 1 } } + T{ ##replace { loc D 0 } } + } + } + { 9 V{ T{ ##call { height -1 } } } } + { + 10 V{ + T{ ##inc { loc D 1 } } + T{ ##replace { loc D 0 } } + } + } + { 11 V{ T{ ##call { height -1 } } } } + { 12 V{ } } + { 13 V{ T{ ##call { height 0 } } } } + { 14 V{ T{ ##peek { loc D 0 } } } } + { 15 V{ } } + { + 16 V{ + T{ ##inc { loc D 1 } } + T{ ##replace { loc D 0 } } + } + } + { 17 V{ T{ ##call { height 0 } } } } + { + 18 V{ + T{ ##peek { loc D 2 } } + T{ ##peek { loc D 1 } } + T{ ##peek { loc D 0 } } + T{ ##inc { loc D 1 } } + } + } + { 19 V{ } } + { 20 V{ } } + { + 21 V{ + T{ ##inc { loc D -3 } } + T{ ##replace { loc D 0 } } + } + } + { 22 V{ T{ ##call { height 0 } } } } + { 23 V{ } } + { 24 V{ T{ ##call { height 0 } } } } + { + 25 V{ + T{ ##peek { loc D 0 } } + T{ ##inc { loc D 3 } } + } + } + { 26 V{ } } + { 27 V{ } } + { 28 V{ } } + { 29 V{ } } + { 30 V{ T{ ##call-gc } } } + { 31 V{ } } + { + 32 V{ + T{ ##inc { loc D -4 } } + T{ ##inc { loc D 1 } } + T{ ##replace { loc D 0 } } + } + } + { 33 V{ } } + } [ over insns>block ] assoc-map dup + { + { 0 1 } + { 1 2 } { 1 8 } + { 2 3 } + { 3 4 } + { 4 5 } + { 5 6 } + { 7 16 } + { 8 9 } + { 9 10 } + { 10 11 } + { 11 12 } + { 12 13 } + { 13 14 } + { 14 15 } + { 15 16 } + { 16 17 } + { 17 18 } + { 18 19 } + { 19 20 } + { 20 27 } + { 21 22 } + { 22 23 } + { 23 24 } + { 24 25 } + { 25 26 } + { 26 27 } + { 27 28 } { 27 32 } + { 28 29 } { 28 30 } + { 29 21 } + { 20 31 } + { 31 21 } + { 32 33 } + } make-edges 0 of block>cfg ; + +{ + H{ + { 0 { { 0 { } } { 0 { } } } } + { 1 { { 0 { } } { 0 { } } } } + { 2 { { 0 { } } { 0 { } } } } + { 3 { { -1 { } } { 0 { } } } } + { 4 { { -1 { } } { 0 { } } } } + { 5 { { -1 { } } { 0 { } } } } + { 6 { { -1 { } } { 0 { } } } } + { 7 { { -2 { } } { 0 { } } } } + { 8 { { -1 { 0 } } { 0 { } } } } + { 9 { { -1 { } } { 0 { } } } } + { 10 { { -2 { } } { 0 { } } } } + { 11 { { -2 { } } { 0 { } } } } + { 12 { { -2 { } } { 0 { } } } } + { 13 { { -1 { 0 } } { 0 { } } } } + { 14 { { -1 { } } { 0 { } } } } + { 15 { { -1 { } } { 0 { } } } } + { 16 { { -1 { } } { 0 { } } } } + { 17 { { -1 { } } { 0 { } } } } + { 18 { { -1 { } } { 0 { } } } } + { 19 { { 0 { 0 1 2 } } { 0 { } } } } + { 20 { { -3 { } } { 0 { } } } } + { 21 { { -3 { } } { 0 { } } } } + { 22 { { -3 { } } { 0 { } } } } + { 23 { { -3 { } } { 0 { } } } } + { 24 { { -3 { } } { 0 { } } } } + ! gc-map here + { 25 { { 0 { 0 1 2 } } { 0 { } } } } + { 26 { { 0 { 0 1 2 } } { 0 { } } } } + { 27 { { -4 { } } { 0 { } } } } + { 28 { { -3 { 0 } } { 0 { } } } } + { 29 { { -1 { } } { 0 { } } } } + { 30 { { -2 { } } { 0 { } } } } + { 31 { { -2 { } } { 0 { } } } } + { 32 { { -2 { } } { 0 { } } } } + { 33 { { -1 { 0 } } { 0 { } } } } + { 34 { { -1 { } } { 0 { } } } } + { 35 { { -2 { } } { 0 { } } } } + { 36 { { -2 { } } { 0 { } } } } + } +} [ + bug-benchmark-terrain-cfg trace-stack-state2 +] unit-test + + ! following-stack-state { { { 0 { } } { 0 { } } } } [ V{ } following-stack-state ] unit-test { - { { 1 { } } { 0 { } } } + { { 1 { 0 } } { 0 { } } } } [ V{ T{ ##inc f D 1 } } following-stack-state ] unit-test { - { { 0 { } } { 1 { } } } + { { 0 { } } { 1 { 0 } } } } [ V{ T{ ##inc f R 1 } } following-stack-state ] unit-test ! Here the peek refers to a parameter of the word. { - { { 0 { 25 } } { 0 { } } } + { { 0 { } } { 0 { } } } } [ V{ T{ ##peek { loc D 25 } } } following-stack-state ] unit-test -! Should be ok because the value was at 0 when the gc ran. { - { { -1 { -1 } } { 0 { } } } -} [ - V{ - T{ ##replace { src 10 } { loc D 0 } } - T{ ##alien-invoke { gc-map T{ gc-map { scrub-d { } } } } } - T{ ##inc f D -1 } - T{ ##peek { loc D -1 } } - } following-stack-state -] unit-test - -{ - { { 0 { 0 1 2 } } { 0 { } } } + { { 0 { } } { 0 { } } } } [ V{ T{ ##replace { src 10 } { loc D 0 } } @@ -538,7 +645,7 @@ IN: compiler.cfg.stacks.padding.tests ] unit-test { - { { 1 { 1 0 } } { 0 { } } } + { { 1 { } } { 0 { } } } } [ V{ T{ ##replace { src 10 } { loc D 0 } } @@ -548,7 +655,7 @@ IN: compiler.cfg.stacks.padding.tests ] unit-test { - { { 0 { 0 } } { 0 { } } } + { { 0 { } } { 0 { } } } } [ V{ T{ ##replace { src 10 } { loc D 0 } } diff --git a/basis/compiler/cfg/stacks/padding/padding.factor b/basis/compiler/cfg/stacks/padding/padding.factor index 2ca0b95a32..3bc728dbbf 100644 --- a/basis/compiler/cfg/stacks/padding/padding.factor +++ b/basis/compiler/cfg/stacks/padding/padding.factor @@ -1,49 +1,36 @@ ! Copyright (C) 2015 Björn Lindqvist. ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays assocs compiler.cfg.dataflow-analysis -compiler.cfg.instructions compiler.cfg.linearization compiler.cfg.predecessors -compiler.cfg.registers compiler.cfg.stacks compiler.cfg.stacks.local -compiler.cfg.stacks.global fry grouping kernel math math.order namespaces +compiler.cfg.instructions compiler.cfg.linearization compiler.cfg.registers +compiler.cfg.stacks.local fry grouping kernel math math.order namespaces sequences ; QUALIFIED: sets IN: compiler.cfg.stacks.padding -ERROR: overinitialized-when-gc seq ; -ERROR: vacant-when-calling seq ; - -: safe-iota ( n -- seq ) - 0 max iota ; - ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! !! Stack ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ERROR: height-mismatches seq ; : register-write ( n stack -- stack' ) - first2 rot suffix sets:members 2array ; - -: adjust-stack ( n stack -- stack' ) - first2 pick '[ _ + ] map [ + ] dip 2array ; - -: stack>vacant ( stack -- seq ) - first2 [ safe-iota ] dip sets:diff ; + first2 swapd remove 2array ; : combine-stacks ( stacks -- stack ) [ [ first ] map dup all-equal? [ first ] [ height-mismatches ] if ] - [ [ second ] map refine ] bi 2array ; - -: fill-stack ( stack -- stack' ) - first2 over safe-iota sets:union 2array ; + [ [ second ] map sets:combine ] bi 2array ; : classify-read ( stack n -- val ) - swap 2dup second member? [ 2drop 0 ] [ first >= [ 1 ] [ 2 ] if ] if ; + swap 2dup second member? [ 2drop 2 ] [ first >= [ 1 ] [ 0 ] if ] if ; -: push-items ( n stack -- stack' ) - first2 pick '[ _ + ] map pick safe-iota sets:union [ + ] dip 2array ; +: shift-stack ( n stack -- stack' ) + first2 pick '[ _ + ] map [ 0 >= ] filter pick 0 max iota sets:union + [ + ] dip 2array ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! !! States ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +ERROR: vacant-when-calling seq ; + CONSTANT: initial-state { { 0 { } } { 0 { } } } : apply-stack-op ( state insn quote: ( n stack -- stack' ) -- state' ) @@ -53,36 +40,29 @@ CONSTANT: initial-state { { 0 { } } { 0 { } } } : combine-states ( states -- state ) [ initial-state ] [ flip [ combine-stacks ] map ] if-empty ; -: mark-location ( state insn -- state' ) +: live-location ( state insn -- state' ) [ register-write ] apply-stack-op ; : ensure-no-vacant ( state -- ) - [ stack>vacant ] map dup { { } { } } = - [ drop ] [ vacant-when-calling ] if ; + [ second ] map dup { { } { } } = [ drop ] [ vacant-when-calling ] if ; -: ensure-no-overinitialized ( state -- ) - [ second [ 0 < ] filter ] map dup { { } { } } = - [ drop ] [ overinitialized-when-gc ] if ; - -: fill-vacancies ( state -- state' ) - [ fill-stack ] map ; +: all-live ( state -- state' ) + [ first { } 2array ] map ; GENERIC: visit-insn ( state insn -- state' ) M: ##inc visit-insn ( state insn -- state' ) - [ adjust-stack ] apply-stack-op - [ first2 [ 0 >= ] filter 2array ] map ; + [ shift-stack ] apply-stack-op ; -M: ##replace-imm visit-insn mark-location ; -M: ##replace visit-insn mark-location ; +M: ##replace-imm visit-insn live-location ; +M: ##replace visit-insn live-location ; M: ##call visit-insn ( state insn -- state' ) - over ensure-no-vacant - height>> swap first2 [ push-items ] dip 2array - [ first2 [ 0 >= ] filter 2array ] map ; + over ensure-no-vacant height>> + 0 2array [ swap first2 [ + ] dip 2array ] 2map ; M: ##call-gc visit-insn ( state insn -- state' ) - drop dup ensure-no-overinitialized fill-vacancies ; + drop all-live ; M: gc-map-insn visit-insn ( state insn -- state' ) drop ; @@ -94,7 +74,8 @@ ERROR: vacant-peek insn ; dup 2 = [ drop vacant-peek ] [ 2nip 1 = ] if ; M: ##peek visit-insn ( state insn -- state ) - 2dup underflowable-peek? [ [ fill-vacancies ] dip ] when mark-location ; + dup loc>> n>> 0 >= t assert= + dupd underflowable-peek? [ all-live ] when ; M: insn visit-insn ( state insn -- state' ) drop ; diff --git a/basis/compiler/cfg/stacks/vacant/vacant-tests.factor b/basis/compiler/cfg/stacks/vacant/vacant-tests.factor index 8d17b8a54a..f4b1b6f1f0 100644 --- a/basis/compiler/cfg/stacks/vacant/vacant-tests.factor +++ b/basis/compiler/cfg/stacks/vacant/vacant-tests.factor @@ -5,19 +5,24 @@ compiler.cfg.utilities compiler.cfg.stacks.vacant kernel math sequences sorting tools.test vectors ; IN: compiler.cfg.stacks.vacant.tests +! state>gc-data { { { } { } } } [ - { { 4 { 3 2 1 -3 0 -2 -1 } } { 0 { -1 } } } state>gc-data + { { 3 { } } { 3 { } } } state>gc-data ] unit-test -{ { { 1 0 0 } { 0 } } } [ - { { 3 { 0 } } { 1 { } } } state>gc-data +{ + { { 0 1 0 } { } } + { { 1 0 0 } { 0 } } +} [ + { { 3 { 0 2 } } { 3 { } } } state>gc-data + { { 3 { 1 2 } } { 3 { 0 } } } state>gc-data ] unit-test ! visit-insn should set the gc info. { { 0 0 } { } } [ - { { 2 { } } { 0 { } } } + { { 2 { 0 1 } } { 0 { } } } T{ ##alien-invoke { gc-map T{ gc-map } } } [ gc-map>> set-gc-map ] keep gc-map>> [ scrub-d>> ] [ scrub-r>> ] bi ] unit-test diff --git a/basis/compiler/cfg/stacks/vacant/vacant.factor b/basis/compiler/cfg/stacks/vacant/vacant.factor index 4f9f26c3d5..32806425e3 100644 --- a/basis/compiler/cfg/stacks/vacant/vacant.factor +++ b/basis/compiler/cfg/stacks/vacant/vacant.factor @@ -10,7 +10,7 @@ IN: compiler.cfg.stacks.vacant ] if-empty ; : state>gc-data ( state -- gc-data ) - [ stack>vacant vacant>bits ] map ; + [ second vacant>bits ] map ; : set-gc-map ( state gc-map -- ) swap state>gc-data first2 -rot >>scrub-d swap >>scrub-r drop ;