342 lines
8.4 KiB
Factor
342 lines
8.4 KiB
Factor
USING: accessors arrays assocs compiler.cfg
|
|
compiler.cfg.dataflow-analysis.private compiler.cfg.instructions
|
|
compiler.cfg.linearization compiler.cfg.registers
|
|
compiler.cfg.utilities compiler.cfg.stacks.map kernel math namespaces
|
|
sequences sorting tools.test vectors ;
|
|
IN: compiler.cfg.stacks.map.tests
|
|
|
|
! classify-read: vacant locations
|
|
{ 2 2 2 } [
|
|
{ 3 { } } 2 classify-read
|
|
{ 0 { } } -1 classify-read
|
|
{ 3 { } } -1 classify-read
|
|
] unit-test
|
|
|
|
! classify-read: over locations
|
|
{ 1 1 1 1 1 } [
|
|
{ 1 { 0 } } 1 classify-read
|
|
{ 0 { } } 0 classify-read
|
|
{ 3 { } } 4 classify-read
|
|
{ 0 { } } 4 classify-read
|
|
{ 1 { 0 } } 4 classify-read
|
|
] unit-test
|
|
|
|
! classify-read: initialized locations
|
|
{ 0 0 0 } [
|
|
{ 1 { 0 } } 0 classify-read
|
|
{ 2 { 0 1 2 } } 0 classify-read
|
|
{ 0 { 0 1 2 } } 0 classify-read
|
|
] 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
|
|
|
|
! visit-insn
|
|
|
|
! After a ##peek that can cause a stack underflow, it is certain that
|
|
! all stack locations are initialized.
|
|
{
|
|
{ { 2 { 0 1 2 } } { 0 { } } }
|
|
} [
|
|
{ { 2 { } } { 0 { } } } T{ ##peek f f D 2 } visit-insn
|
|
] unit-test
|
|
|
|
! If the ##peek can't cause a stack underflow, then we don't have the
|
|
! same guarantees.
|
|
[
|
|
{ { 2 { } } { 0 { } } } T{ ##peek f f D 0 } visit-insn
|
|
] [ vacant-peek? ] must-fail-with
|
|
|
|
! verboten peek
|
|
[
|
|
{ { 1 { } } { 0 { } } } T{ ##peek { loc D 0 } } visit-insn
|
|
] [ vacant-peek? ] must-fail-with
|
|
|
|
|
|
! trace-stack-state
|
|
{
|
|
H{
|
|
{
|
|
0
|
|
{ { 0 { } } { 0 { } } }
|
|
}
|
|
{
|
|
1
|
|
{ { 2 { } } { 0 { } } }
|
|
}
|
|
{
|
|
2
|
|
{ { 2 { 0 1 2 } } { 0 { } } }
|
|
}
|
|
}
|
|
} [
|
|
{
|
|
T{ ##inc f D 2 }
|
|
T{ ##peek f f D 2 }
|
|
T{ ##inc f D 0 }
|
|
} insns>cfg trace-stack-state
|
|
] unit-test
|
|
|
|
! Runs the analysis and check what the resulting stack map becomes.
|
|
: following-stack-state ( insns -- state )
|
|
T{ ##branch } suffix insns>cfg trace-stack-state
|
|
>alist [ first ] sort-with last second ;
|
|
|
|
! Initially both the d and r stacks are empty.
|
|
{
|
|
{ { 0 { } } { 0 { } } }
|
|
} [ V{ } following-stack-state ] unit-test
|
|
|
|
{
|
|
H{
|
|
{ 0 { { 0 { } } { 0 { } } } }
|
|
{ 1 { { 0 { } } { 0 { } } } }
|
|
{ 2 { { 0 { } } { 0 { } } } }
|
|
}
|
|
} [
|
|
V{ T{ ##safepoint } T{ ##prologue } T{ ##branch } }
|
|
insns>cfg trace-stack-state
|
|
] unit-test
|
|
|
|
{
|
|
{ { 1 { } } { 0 { } } }
|
|
} [ V{ T{ ##inc f D 1 } } following-stack-state ] unit-test
|
|
|
|
{
|
|
{ { 0 { } } { 1 { } } }
|
|
} [ V{ T{ ##inc f R 1 } } following-stack-state ] unit-test
|
|
|
|
! Here the peek refers to a parameter of the word.
|
|
{
|
|
{ { 0 { 25 } } { 0 { } } }
|
|
} [
|
|
V{
|
|
T{ ##peek { loc D 25 } }
|
|
} following-stack-state
|
|
] unit-test
|
|
|
|
! The peek "causes" the vacant locations to become populated.
|
|
{
|
|
H{
|
|
{ 0 { { 0 { } } { 0 { } } } }
|
|
{ 1 { { 3 { } } { 0 { } } } }
|
|
{ 2 { { 3 { 0 1 2 3 } } { 0 { } } } }
|
|
}
|
|
} [
|
|
V{
|
|
T{ ##inc f D 3 }
|
|
T{ ##peek { loc D 3 } }
|
|
T{ ##branch }
|
|
}
|
|
insns>cfg trace-stack-state
|
|
] 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-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 { } } }
|
|
} [
|
|
V{
|
|
T{ ##replace { src 10 } { loc D 0 } }
|
|
T{ ##replace { src 10 } { loc D 1 } }
|
|
T{ ##replace { src 10 } { loc D 2 } }
|
|
} following-stack-state
|
|
] unit-test
|
|
|
|
{
|
|
{ { 1 { 1 0 } } { 0 { } } }
|
|
} [
|
|
V{
|
|
T{ ##replace { src 10 } { loc D 0 } }
|
|
T{ ##inc f D 1 }
|
|
T{ ##replace { src 10 } { loc D 0 } }
|
|
} following-stack-state
|
|
] unit-test
|
|
|
|
{
|
|
{ { 0 { 0 } } { 0 { } } }
|
|
} [
|
|
V{
|
|
T{ ##replace { src 10 } { loc D 0 } }
|
|
T{ ##inc f D 1 }
|
|
T{ ##replace { src 10 } { loc D 0 } }
|
|
T{ ##inc f D -1 }
|
|
} following-stack-state
|
|
] unit-test
|
|
|
|
{
|
|
{ { 0 { } } { 0 { } } }
|
|
} [
|
|
V{
|
|
T{ ##inc f D 1 }
|
|
T{ ##replace { src 10 } { loc D 0 } }
|
|
T{ ##inc f D -1 }
|
|
} following-stack-state
|
|
] unit-test
|
|
|
|
! ##call clears the overinitialized slots.
|
|
{
|
|
{ { -1 { } } { 0 { } } }
|
|
} [
|
|
V{
|
|
T{ ##replace { src 10 } { loc D 0 } }
|
|
T{ ##inc f D -1 }
|
|
T{ ##call }
|
|
} following-stack-state
|
|
] unit-test
|
|
|
|
! Should not be ok because the value wasn't initialized when gc ran.
|
|
[
|
|
V{
|
|
T{ ##inc f D 1 }
|
|
T{ ##alien-invoke { gc-map T{ gc-map { scrub-d { } } } } }
|
|
T{ ##peek { loc D 0 } }
|
|
} following-stack-state
|
|
] [ vacant-peek? ] must-fail-with
|
|
|
|
[
|
|
V{
|
|
T{ ##inc f D 1 }
|
|
T{ ##peek { loc D 0 } }
|
|
} following-stack-state
|
|
] [ vacant-peek? ] must-fail-with
|
|
|
|
[
|
|
V{
|
|
T{ ##inc f R 1 }
|
|
T{ ##peek { loc R 0 } }
|
|
} following-stack-state
|
|
] [ vacant-peek? ] must-fail-with
|
|
|
|
: cfg1 ( -- cfg )
|
|
V{
|
|
T{ ##inc f D 1 }
|
|
T{ ##replace { src 10 } { loc D 0 } }
|
|
} 0 insns>block
|
|
V{
|
|
T{ ##peek { dst 37 } { loc D 0 } }
|
|
T{ ##inc f D -1 }
|
|
} 1 insns>block
|
|
1vector >>successors block>cfg ;
|
|
|
|
{
|
|
H{
|
|
{ 0 { { 0 { } } { 0 { } } } }
|
|
{ 1 { { 1 { } } { 0 { } } } }
|
|
{ 2 { { 1 { 0 } } { 0 { } } } }
|
|
{ 3 { { 1 { 0 } } { 0 { } } } }
|
|
}
|
|
} [ cfg1 trace-stack-state ] unit-test
|
|
|
|
! Same cfg structure as the bug1021:run-test word but with
|
|
! non-datastack instructions mostly omitted.
|
|
: bug1021-cfg ( -- cfg )
|
|
{
|
|
{ 0 V{ T{ ##safepoint } T{ ##prologue } T{ ##branch } } }
|
|
{
|
|
1 V{
|
|
T{ ##inc f D 2 }
|
|
T{ ##replace { src 0 } { loc D 1 } }
|
|
T{ ##replace { src 0 } { loc D 0 } }
|
|
}
|
|
}
|
|
{
|
|
2 V{
|
|
T{ ##call { word <array> } }
|
|
}
|
|
}
|
|
{
|
|
3 V{
|
|
T{ ##peek { dst 0 } { loc D 0 } }
|
|
T{ ##peek { dst 0 } { loc D 1 } }
|
|
T{ ##inc f D 2 }
|
|
T{ ##replace { src 0 } { loc D 2 } }
|
|
T{ ##replace { src 0 } { loc D 3 } }
|
|
T{ ##replace { src 0 } { loc D 1 } }
|
|
}
|
|
}
|
|
{
|
|
8 V{
|
|
T{ ##peek { dst 0 } { loc D 2 } }
|
|
T{ ##peek { dst 0 } { loc D 1 } }
|
|
T{ ##inc f D 3 }
|
|
T{ ##replace { src 0 } { loc D 0 } }
|
|
T{ ##replace { src 0 } { loc D 1 } }
|
|
T{ ##replace { src 0 } { loc D 2 } }
|
|
T{ ##replace { src 0 } { loc D 3 } }
|
|
}
|
|
}
|
|
{
|
|
10 V{
|
|
T{ ##inc f D -3 }
|
|
T{ ##peek { dst 0 } { loc D 0 } }
|
|
T{ ##alien-invoke { gc-map T{ gc-map { scrub-d { } } } } }
|
|
}
|
|
}
|
|
} [ over insns>block ] assoc-map dup
|
|
{ { 0 1 } { 1 2 } { 2 3 } { 3 8 } { 8 10 } } make-edges 0 of block>cfg ;
|
|
|
|
{
|
|
H{
|
|
{ 0 { { 0 { } } { 0 { } } } }
|
|
{ 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 { } } } }
|
|
}
|
|
} [
|
|
bug1021-cfg trace-stack-state
|
|
] unit-test
|