Value numbering
parent
084e64d0bc
commit
d723b69990
|
@ -1,12 +1,22 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: compiler.cfg.rpo compiler.cfg.height
|
||||
compiler.cfg.alias-analysis compiler.cfg.write-barrier ;
|
||||
USING: kernel sequences compiler.cfg.rpo
|
||||
compiler.cfg.instructions
|
||||
compiler.cfg.height
|
||||
compiler.cfg.alias-analysis
|
||||
compiler.cfg.value-numbering
|
||||
compiler.cfg.write-barrier ;
|
||||
IN: compiler.cfg.optimizer
|
||||
|
||||
: trivial? ( insns -- ? )
|
||||
dup length 1 = [ first ##call? ] [ drop f ] if ;
|
||||
|
||||
: optimize-cfg ( cfg -- cfg' )
|
||||
[
|
||||
normalize-height
|
||||
alias-analysis
|
||||
eliminate-write-barriers
|
||||
dup trivial? [
|
||||
normalize-height
|
||||
alias-analysis
|
||||
value-numbering
|
||||
eliminate-write-barriers
|
||||
] unless
|
||||
] change-basic-blocks ;
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: kernel sequences layouts accessors combinators
|
||||
compiler.cfg.instructions
|
||||
compiler.cfg.value-numbering.graph
|
||||
compiler.cfg.value-numbering.expressions
|
||||
compiler.cfg.value-numbering.liveness
|
||||
compiler.cfg.value-numbering ;
|
||||
IN: compiler.cfg.value-numbering.conditions
|
||||
|
||||
! The CFG builder produces naive code for the following code
|
||||
! sequence:
|
||||
!
|
||||
! fixnum< [ ... ] [ ... ] if
|
||||
!
|
||||
! The fixnum< comparison generates a boolean, which is then
|
||||
! tested against f.
|
||||
!
|
||||
! Using value numbering, we optimize the comparison of a boolean
|
||||
! against f where the boolean is the result of comparison.
|
||||
|
||||
: ##branch-t? ( insn -- ? )
|
||||
[ cc>> cc/= eq? ] [ src2>> \ f tag-number eq? ] bi and ; inline
|
||||
|
||||
: of-boolean? ( insn -- expr/f ? )
|
||||
src1>> vreg>expr dup compare-expr? ; inline
|
||||
|
||||
: eliminate-boolean ( insn -- expr/f )
|
||||
dup ##branch-t? [
|
||||
of-boolean? [ drop f ] unless
|
||||
] [ drop f ] if ; inline
|
||||
|
||||
M: ##compare-imm-branch number-values
|
||||
dup eliminate-boolean [
|
||||
[ in1>> live-vn ] [ in2>> live-vn ] bi
|
||||
] [ call-next-method ] ?if ;
|
||||
|
||||
: >compare-expr< [ in1>> vn>vreg ] [ in2>> vn>vreg ] [ cc>> ] tri ; inline
|
||||
: >compare-imm-expr< [ in1>> vn>vreg ] [ in2>> vn>constant ] [ cc>> ] tri ; inline
|
||||
|
||||
M: ##compare-imm-branch eliminate
|
||||
dup eliminate-boolean [
|
||||
dup op>> {
|
||||
{ \ ##compare [ >compare-expr< f \ ##compare-branch boa ] }
|
||||
{ \ ##compare-imm [ >compare-imm-expr< f \ ##compare-imm-branch boa ] }
|
||||
{ \ ##compare-float [ >compare-expr< f \ ##compare-float-branch boa ] }
|
||||
} case
|
||||
] [ call-next-method ] ?if ;
|
|
@ -0,0 +1,18 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors kernel
|
||||
compiler.cfg.value-numbering.graph
|
||||
compiler.cfg.value-numbering.expressions ;
|
||||
IN: compiler.cfg.value-numbering.constant-fold
|
||||
|
||||
GENERIC: constant-fold ( insn -- insn' )
|
||||
|
||||
M: vop constant-fold ;
|
||||
|
||||
: expr>insn ( out constant-expr -- constant-op )
|
||||
[ value>> ] [ op>> ] bi new swap >>value swap >>out ;
|
||||
|
||||
M: pure-op constant-fold
|
||||
dup out>>
|
||||
dup vreg>expr
|
||||
dup constant-expr? [ expr>insn nip ] [ 2drop ] if ;
|
|
@ -1,23 +1,88 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors classes kernel math namespaces combinators
|
||||
compiler.cfg.instructions compiler.cfg.value-numbering.graph ;
|
||||
IN: compiler.cfg.value-numbering.expressions
|
||||
|
||||
! Referentially-transparent expressions.
|
||||
|
||||
! Referentially-transparent expressions
|
||||
TUPLE: expr op ;
|
||||
|
||||
! op is always %peek
|
||||
TUPLE: peek-expr < expr loc ;
|
||||
TUPLE: unary-expr < expr in ;
|
||||
TUPLE: load-literal-expr < expr obj ;
|
||||
TUPLE: binary-expr < expr in1 in2 ;
|
||||
TUPLE: commutative-expr < binary-expr ;
|
||||
TUPLE: compare-expr < binary-expr cc ;
|
||||
TUPLE: constant-expr < expr value ;
|
||||
|
||||
: <constant> ( constant -- expr )
|
||||
f swap constant-expr boa ; inline
|
||||
|
||||
M: constant-expr equal?
|
||||
over constant-expr? [
|
||||
[ [ value>> ] bi@ = ]
|
||||
[ [ value>> class ] bi@ = ] 2bi
|
||||
and
|
||||
] [ 2drop f ] if ;
|
||||
|
||||
SYMBOL: input-expr-counter
|
||||
|
||||
: next-input-expr ( -- n )
|
||||
input-expr-counter [ dup 1 + ] change ;
|
||||
|
||||
! Expressions whose values are inputs to the basic block. We
|
||||
! can eliminate a second computation having the same 'n' as
|
||||
! the first one; we can also eliminate input-exprs whose
|
||||
! result is not used.
|
||||
TUPLE: input-expr < expr n ;
|
||||
|
||||
: constant>vn ( constant -- vn ) <constant> expr>vn ; inline
|
||||
|
||||
GENERIC: >expr ( insn -- expr )
|
||||
|
||||
M: ##peek >expr
|
||||
[ class ] [ loc>> ] bi peek-expr boa ;
|
||||
M: ##load-immediate >expr val>> <constant> ;
|
||||
|
||||
M: ##load-literal >expr
|
||||
[ class ] [ obj>> ] bi load-literal-expr boa ;
|
||||
M: ##load-indirect >expr obj>> <constant> ;
|
||||
|
||||
M: ##unary >expr
|
||||
[ class ] [ src>> vreg>vn ] bi unary-expr boa ;
|
||||
|
||||
M: ##binary >expr
|
||||
[ class ] [ src1>> vreg>vn ] [ src2>> vreg>vn ] tri
|
||||
binary-expr boa ;
|
||||
|
||||
M: ##binary-imm >expr
|
||||
[ class ] [ src1>> vreg>vn ] [ src2>> constant>vn ] tri
|
||||
binary-expr boa ;
|
||||
|
||||
M: ##commutative >expr
|
||||
[ class ] [ src1>> vreg>vn ] [ src2>> vreg>vn ] tri
|
||||
commutative-expr boa ;
|
||||
|
||||
M: ##commutative-imm >expr
|
||||
[ class ] [ src1>> vreg>vn ] [ src2>> constant>vn ] tri
|
||||
commutative-expr boa ;
|
||||
|
||||
: compare>expr ( insn -- expr )
|
||||
{
|
||||
[ class ]
|
||||
[ src1>> vreg>vn ]
|
||||
[ src2>> vreg>vn ]
|
||||
[ cc>> ]
|
||||
} cleave compare-expr boa ; inline
|
||||
|
||||
M: ##compare >expr compare>expr ;
|
||||
|
||||
: compare-imm>expr ( insn -- expr )
|
||||
{
|
||||
[ class ]
|
||||
[ src1>> vreg>vn ]
|
||||
[ src2>> constant>vn ]
|
||||
[ cc>> ]
|
||||
} cleave compare-expr boa ; inline
|
||||
|
||||
M: ##compare-imm >expr compare-imm>expr ;
|
||||
|
||||
M: ##compare-float >expr compare>expr ;
|
||||
|
||||
M: ##flushable >expr class next-input-expr input-expr boa ;
|
||||
|
||||
: init-expressions ( -- )
|
||||
0 input-expr-counter set ;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors kernel math namespaces assocs biassocs ;
|
||||
IN: compiler.cfg.value-numbering.graph
|
||||
|
||||
SYMBOL: vn-counter
|
||||
|
@ -13,7 +14,6 @@ SYMBOL: exprs>vns
|
|||
|
||||
: vn>expr ( vn -- expr ) exprs>vns get value-at ;
|
||||
|
||||
! biassoc mapping vregs to value numbers
|
||||
SYMBOL: vregs>vns
|
||||
|
||||
: vreg>vn ( vreg -- vn ) vregs>vns get at ;
|
||||
|
@ -22,11 +22,11 @@ SYMBOL: vregs>vns
|
|||
|
||||
: set-vn ( vn vreg -- ) vregs>vns get set-at ;
|
||||
|
||||
: vreg>expr ( vreg -- expr ) vreg>vn vn>expr ; inline
|
||||
|
||||
: vn>constant ( vn -- constant ) vn>expr value>> ; inline
|
||||
|
||||
: init-value-graph ( -- )
|
||||
0 vn-counter set
|
||||
<bihash> exprs>vns set
|
||||
<bihash> vregs>vns set ;
|
||||
|
||||
: reset-value-graph ( -- )
|
||||
exprs>vns get clear-assoc
|
||||
vregs>vns get clear-assoc ;
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: namespaces kernel assocs sets accessors
|
||||
compiler.cfg.instructions
|
||||
compiler.cfg.instructions.syntax
|
||||
compiler.cfg.value-numbering.graph
|
||||
compiler.cfg.value-numbering.expressions ;
|
||||
IN: compiler.cfg.value-numbering.liveness
|
||||
|
||||
! A set of VNs which are (transitively) used by side-effecting
|
||||
! instructions.
|
||||
! A set of VNs which are (transitively) used by effect-ops. This
|
||||
! is precisely the set of VNs whose value is needed outside of
|
||||
! the basic block.
|
||||
SYMBOL: live-vns
|
||||
|
||||
GENERIC: live-expr ( expr -- )
|
||||
|
@ -14,12 +20,12 @@ GENERIC: live-expr ( expr -- )
|
|||
[ live-vns get conjoin ] [ vn>expr live-expr ] bi
|
||||
] if ;
|
||||
|
||||
M: peek-expr live-expr drop ;
|
||||
M: unary-expr live-expr in>> live-vn ;
|
||||
M: load-literal-expr live-expr in>> live-vn ;
|
||||
|
||||
: live-vreg ( vreg -- ) vreg>vn live-vn ;
|
||||
|
||||
M: expr live-expr drop ;
|
||||
M: unary-expr live-expr in>> live-vn ;
|
||||
M: binary-expr live-expr [ in1>> live-vn ] [ in2>> live-vn ] bi ;
|
||||
|
||||
: live? ( vreg -- ? )
|
||||
dup vreg>vn tuck vn>vreg =
|
||||
[ live-vns get key? ] [ drop f ] if ;
|
||||
|
@ -27,12 +33,7 @@ M: load-literal-expr live-expr in>> live-vn ;
|
|||
: init-liveness ( -- )
|
||||
H{ } clone live-vns set ;
|
||||
|
||||
GENERIC: eliminate ( insn -- insn/f )
|
||||
GENERIC: eliminate ( insn -- insn' )
|
||||
|
||||
: (eliminate) ( insn -- insn/f )
|
||||
dup dst>> live? [ drop f ] unless ;
|
||||
|
||||
M: ##peek eliminate (eliminate) ;
|
||||
M: ##unary eliminate (eliminate) ;
|
||||
M: ##load-literal eliminate (eliminate) ;
|
||||
M: ##flushable eliminate dup dst>> live? [ drop f ] unless ;
|
||||
M: insn eliminate ;
|
||||
|
|
|
@ -1,58 +1,64 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: namespaces assocs sequences kernel accessors
|
||||
compiler.cfg.instructions compiler.cfg.instructions.syntax
|
||||
compiler.cfg.value-numbering.graph ;
|
||||
IN: compiler.cfg.value-numbering.propagate
|
||||
|
||||
! If two vregs compute the same value, replace references to
|
||||
! the latter with the former.
|
||||
|
||||
: resolve ( vreg -- vreg' ) vreg>vn vn>vreg ;
|
||||
: resolve ( vreg -- vreg' ) vreg>vn vn>vreg ; inline
|
||||
|
||||
GENERIC: propogate ( insn -- insn )
|
||||
GENERIC: propagate ( insn -- insn )
|
||||
|
||||
M: ##unary-branch propagate [ resolve ] change-src ;
|
||||
M: ##effect propagate
|
||||
[ resolve ] change-src ;
|
||||
|
||||
M: ##unary propogate [ resolve ] change-src ;
|
||||
M: ##unary propagate
|
||||
[ resolve ] change-src ;
|
||||
|
||||
M: ##flushable propagate ;
|
||||
M: ##binary propagate
|
||||
[ resolve ] change-src1
|
||||
[ resolve ] change-src2 ;
|
||||
|
||||
M: ##replace propagate [ resolve ] change-src ;
|
||||
M: ##binary-imm propagate
|
||||
[ resolve ] change-src1 ;
|
||||
|
||||
M: ##inc-d propagate ;
|
||||
M: ##slot propagate
|
||||
[ resolve ] change-obj
|
||||
[ resolve ] change-slot ;
|
||||
|
||||
M: ##inc-r propagate ;
|
||||
M: ##slot-imm propagate
|
||||
[ resolve ] change-obj ;
|
||||
|
||||
M: ##stack-frame propagate ;
|
||||
M: ##set-slot propagate
|
||||
call-next-method
|
||||
[ resolve ] change-obj
|
||||
[ resolve ] change-slot ;
|
||||
|
||||
M: ##call propagate ;
|
||||
M: ##set-slot-imm propagate
|
||||
call-next-method
|
||||
[ resolve ] change-obj ;
|
||||
|
||||
M: ##jump propagate ;
|
||||
M: ##alien-getter propagate
|
||||
call-next-method
|
||||
[ resolve ] change-src ;
|
||||
|
||||
M: ##return propagate ;
|
||||
M: ##alien-setter propagate
|
||||
call-next-method
|
||||
[ resolve ] change-value ;
|
||||
|
||||
M: ##intrinsic propagate
|
||||
[ [ resolve ] assoc-map ] change-defs-vregs
|
||||
[ [ resolve ] assoc-map ] change-uses-vregs ;
|
||||
M: ##conditional-branch propagate
|
||||
[ resolve ] change-src1
|
||||
[ resolve ] change-src2 ;
|
||||
|
||||
M: ##dispatch propagate [ resolve ] change-src ;
|
||||
M: ##compare-imm-branch propagate
|
||||
[ resolve ] change-src1 ;
|
||||
|
||||
M: ##dispatch-label propagate ;
|
||||
M: ##dispatch propagate
|
||||
[ resolve ] change-src ;
|
||||
|
||||
M: ##write-barrier propagate [ resolve ] change-src ;
|
||||
M: insn propagate ;
|
||||
|
||||
M: ##alien-invoke propagate ;
|
||||
|
||||
M: ##alien-indirect propagate ;
|
||||
|
||||
M: ##alien-callback propagate ;
|
||||
|
||||
M: ##callback-return propagate ;
|
||||
|
||||
M: ##prologue propagate ;
|
||||
|
||||
M: ##epilogue propagate ;
|
||||
|
||||
M: ##branch propagate ;
|
||||
|
||||
M: ##if-intrinsic propagate
|
||||
[ [ resolve ] assoc-map ] change-defs-vregs
|
||||
[ [ resolve ] assoc-map ] change-uses-vregs ;
|
||||
M: f propagate ;
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: kernel accessors combinators classes math layouts
|
||||
compiler.cfg.instructions
|
||||
compiler.cfg.instructions.syntax
|
||||
compiler.cfg.value-numbering.graph
|
||||
compiler.cfg.value-numbering.expressions ;
|
||||
IN: compiler.cfg.value-numbering.simplify
|
||||
|
||||
! Return value of f means we didn't simplify.
|
||||
GENERIC: simplify* ( expr -- vn/expr/f )
|
||||
|
||||
: simplify-not ( in -- vn/expr/f )
|
||||
{
|
||||
{ [ dup constant-expr? ] [ value>> bitnot <constant> ] }
|
||||
{ [ dup op>> \ ##not = ] [ in>> ] }
|
||||
[ drop f ]
|
||||
} cond ;
|
||||
|
||||
: simplify-box-float ( in -- vn/expr/f )
|
||||
dup op>> \ ##unbox-float = [ in>> ] [ drop f ] if ;
|
||||
|
||||
: simplify-unbox-float ( in -- vn/expr/f )
|
||||
dup op>> \ ##box-float = [ in>> ] [ drop f ] if ;
|
||||
|
||||
M: unary-expr simplify*
|
||||
#! Note the copy propagation: a copy always simplifies to
|
||||
#! its source VN.
|
||||
[ in>> vn>expr ] [ op>> ] bi {
|
||||
{ \ ##copy [ ] }
|
||||
{ \ ##copy-float [ ] }
|
||||
{ \ ##not [ simplify-not ] }
|
||||
{ \ ##box-float [ simplify-box-float ] }
|
||||
{ \ ##unbox-float [ simplify-unbox-float ] }
|
||||
[ 2drop f ]
|
||||
} case ;
|
||||
|
||||
! : expr-zero? ( expr -- ? ) T{ constant-expr f f 0 } = ; inline
|
||||
!
|
||||
! : expr-one? ( expr -- ? ) T{ constant-expr f f 1 } = ; inline
|
||||
!
|
||||
! : expr-neg-one? ( expr -- ? ) T{ constant-expr f f -1 } = ; inline
|
||||
!
|
||||
! : identity ( in1 in2 val -- expr ) 2nip <constant> ; inline
|
||||
!
|
||||
! : constant-fold? ( in1 in2 -- ? )
|
||||
! [ constant-expr? ] both? ;
|
||||
!
|
||||
! : constant-fold ( in1 in2 quot -- expr )
|
||||
! 2over constant-fold? [
|
||||
! [ [ value>> ] bi@ ] dip call <constant>
|
||||
! ] [ 3drop f ] if ; inline
|
||||
!
|
||||
! : simplify-add ( in1 in2 -- vn/expr/f )
|
||||
! {
|
||||
! { [ over expr-zero? ] [ nip ] }
|
||||
! { [ dup expr-zero? ] [ drop ] }
|
||||
! [ [ + ] constant-fold ]
|
||||
! } cond ;
|
||||
!
|
||||
! : simplify-mul ( in1 in2 -- vn/expr/f )
|
||||
! {
|
||||
! { [ over expr-one? ] [ nip ] }
|
||||
! { [ dup expr-one? ] [ drop ] }
|
||||
! [ [ * ] constant-fold ]
|
||||
! } cond ;
|
||||
!
|
||||
! : simplify-and ( in1 in2 -- vn/expr/f )
|
||||
! {
|
||||
! { [ dup expr-zero? ] [ 0 identity ] }
|
||||
! { [ dup expr-neg-one? ] [ drop ] }
|
||||
! { [ 2dup = ] [ drop ] }
|
||||
! [ [ bitand ] constant-fold ]
|
||||
! } cond ;
|
||||
!
|
||||
! : simplify-or ( in1 in2 -- vn/expr/f )
|
||||
! {
|
||||
! { [ dup expr-zero? ] [ drop ] }
|
||||
! { [ dup expr-neg-one? ] [ -1 identity ] }
|
||||
! { [ 2dup = ] [ drop ] }
|
||||
! [ [ bitor ] constant-fold ]
|
||||
! } cond ;
|
||||
!
|
||||
! : simplify-xor ( in1 in2 -- vn/expr/f )
|
||||
! {
|
||||
! { [ dup expr-zero? ] [ drop ] }
|
||||
! [ [ bitxor ] constant-fold ]
|
||||
! } cond ;
|
||||
!
|
||||
! : commutative-operands ( expr -- in1 in2 )
|
||||
! [ in1>> vn>expr ] [ in2>> vn>expr ] bi
|
||||
! over constant-expr? [ swap ] when ;
|
||||
!
|
||||
! M: commutative-expr simplify*
|
||||
! [ commutative-operands ] [ op>> ] bi {
|
||||
! { ##add [ simplify-add ] }
|
||||
! { ##mul [ simplify-mul ] }
|
||||
! { ##and [ simplify-and ] }
|
||||
! { ##or [ simplify-or ] }
|
||||
! { ##xor [ simplify-xor ] }
|
||||
! [ 3drop f ]
|
||||
! } case ;
|
||||
!
|
||||
! : simplify-sub ( in1 in2 -- vn/expr/f )
|
||||
! {
|
||||
! { [ dup expr-zero? ] [ drop ] }
|
||||
! { [ 2dup = ] [ 0 identity ] }
|
||||
! [ [ - ] constant-fold ]
|
||||
! } cond ;
|
||||
!
|
||||
! : simplify-shl ( in1 in2 -- vn/expr/f )
|
||||
! {
|
||||
! { [ dup expr-zero? ] [ drop ] }
|
||||
! { [ over expr-zero? ] [ drop ] }
|
||||
! [ [ shift ] constant-fold ]
|
||||
! } cond ;
|
||||
!
|
||||
! : unsigned ( n -- n' )
|
||||
! cell-bits 2^ 1- bitand ;
|
||||
!
|
||||
! : useless-shift? ( in1 in2 -- ? )
|
||||
! over op>> ##shl = [ [ in2>> ] [ expr>vn ] bi* = ] [ 2drop f ] if ;
|
||||
!
|
||||
! : simplify-shr ( in1 in2 -- vn/expr/f )
|
||||
! {
|
||||
! { [ dup expr-zero? ] [ drop ] }
|
||||
! { [ over expr-zero? ] [ drop ] }
|
||||
! { [ 2dup useless-shift? ] [ drop in1>> ] }
|
||||
! [ [ neg shift unsigned ] constant-fold ]
|
||||
! } cond ;
|
||||
!
|
||||
! : simplify-sar ( in1 in2 -- vn/expr/f )
|
||||
! {
|
||||
! { [ dup expr-zero? ] [ drop ] }
|
||||
! { [ over expr-zero? ] [ drop ] }
|
||||
! { [ 2dup useless-shift? ] [ drop in1>> ] }
|
||||
! [ [ neg shift ] constant-fold ]
|
||||
! } cond ;
|
||||
!
|
||||
! : simplify-compare ( in1 in2 -- vn/expr/f )
|
||||
! = [ +eq+ %cconst constant ] [ f ] if ;
|
||||
!
|
||||
! M: binary-expr simplify*
|
||||
! [ in1>> vn>expr ] [ in2>> vn>expr ] [ op>> ] tri {
|
||||
! { ##sub [ simplify-isub ] }
|
||||
! { ##shl [ simplify-shl ] }
|
||||
! { ##shr [ simplify-shr ] }
|
||||
! { ##sar [ simplify-sar ] }
|
||||
! { ##compare [ simplify-compare ] }
|
||||
! [ 3drop f ]
|
||||
! } case ;
|
||||
|
||||
M: expr simplify* drop f ;
|
||||
|
||||
: simplify ( expr -- vn )
|
||||
dup simplify* {
|
||||
{ [ dup not ] [ drop expr>vn ] }
|
||||
{ [ dup expr? ] [ expr>vn nip ] }
|
||||
{ [ dup integer? ] [ nip ] }
|
||||
} cond ;
|
|
@ -0,0 +1,50 @@
|
|||
IN: compiler.cfg.value-numbering.tests
|
||||
USING: compiler.cfg.value-numbering compiler.cfg.instructions
|
||||
compiler.cfg.registers cpu.architecture tools.test kernel ;
|
||||
[
|
||||
{
|
||||
T{ ##peek f V int-regs 45 D 1 }
|
||||
T{ ##compare-imm-branch f V int-regs 45 7 cc/= }
|
||||
}
|
||||
] [
|
||||
{
|
||||
T{ ##peek f V int-regs 45 D 1 }
|
||||
T{ ##copy f V int-regs 48 V int-regs 45 }
|
||||
T{ ##compare-imm-branch f V int-regs 48 7 cc/= }
|
||||
} value-numbering
|
||||
] unit-test
|
||||
|
||||
[
|
||||
{
|
||||
T{ ##peek f V int-regs 3 D 0 }
|
||||
T{ ##slot-imm f V int-regs 4 V int-regs 3 1 3 }
|
||||
T{ ##replace f V int-regs 4 D 0 }
|
||||
}
|
||||
] [
|
||||
{
|
||||
T{ ##load-immediate f V int-regs 2 8 }
|
||||
T{ ##peek f V int-regs 3 D 0 }
|
||||
T{ ##slot-imm f V int-regs 4 V int-regs 3 1 3 }
|
||||
T{ ##replace f V int-regs 4 D 0 }
|
||||
} value-numbering
|
||||
] unit-test
|
||||
|
||||
[ t ] [
|
||||
{
|
||||
T{ ##peek f V int-regs 1 D 0 }
|
||||
T{ ##dispatch f V int-regs 1 V int-regs 2 }
|
||||
} dup value-numbering =
|
||||
] unit-test
|
||||
|
||||
[ t ] [
|
||||
{
|
||||
T{ ##peek f V int-regs 16 D 0 }
|
||||
T{ ##peek f V int-regs 17 D -1 }
|
||||
T{ ##sar-imm f V int-regs 18 V int-regs 17 3 }
|
||||
T{ ##add-imm f V int-regs 19 V int-regs 16 13 }
|
||||
T{ ##add f V int-regs 21 V int-regs 18 V int-regs 19 }
|
||||
T{ ##alien-unsigned-1 f V int-regs 22 V int-regs 21 }
|
||||
T{ ##shl-imm f V int-regs 23 V int-regs 22 3 }
|
||||
T{ ##replace f V int-regs 23 D 0 }
|
||||
} dup value-numbering =
|
||||
] unit-test
|
|
@ -1,46 +1,34 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: namespaces assocs biassocs classes kernel math accessors
|
||||
sorting sets sequences
|
||||
compiler.cfg.def-use
|
||||
compiler.cfg.instructions
|
||||
compiler.cfg.instructions.syntax
|
||||
compiler.cfg.value-numbering.graph
|
||||
compiler.cfg.value-numbering.expressions
|
||||
compiler.cfg.value-numbering.liveness
|
||||
compiler.cfg.value-numbering.propagate
|
||||
compiler.cfg.value-numbering.simplify ;
|
||||
IN: compiler.cfg.value-numbering
|
||||
|
||||
: insn>vn ( insn -- vn ) >expr simplify ; inline
|
||||
|
||||
GENERIC: make-value-node ( insn -- )
|
||||
GENERIC: number-values ( insn -- )
|
||||
|
||||
M: ##unary-branch make-value-node src>> live-vreg ;
|
||||
M: ##unary make-value-node [ insn>vn ] [ dst>> ] bi set-vn ;
|
||||
M: ##flushable make-value-node drop ;
|
||||
M: ##load-literal make-value-node [ insn>vn ] [ dst>> ] bi set-vn ;
|
||||
M: ##peek make-value-node [ insn>vn ] [ dst>> ] bi set-vn ;
|
||||
M: ##replace make-value-node reset-value-graph ;
|
||||
M: ##inc-d make-value-node reset-value-graph ;
|
||||
M: ##inc-r make-value-node reset-value-graph ;
|
||||
M: ##stack-frame make-value-node reset-value-graph ;
|
||||
M: ##call make-value-node reset-value-graph ;
|
||||
M: ##jump make-value-node reset-value-graph ;
|
||||
M: ##return make-value-node reset-value-graph ;
|
||||
M: ##intrinsic make-value-node uses-vregs [ live-vreg ] each ;
|
||||
M: ##dispatch make-value-node reset-value-graph ;
|
||||
M: ##dispatch-label make-value-node reset-value-graph ;
|
||||
M: ##allot make-value-node drop ;
|
||||
M: ##write-barrier make-value-node drop ;
|
||||
M: ##gc make-value-node reset-value-graph ;
|
||||
M: ##replace make-value-node reset-value-graph ;
|
||||
M: ##alien-invoke make-value-node reset-value-graph ;
|
||||
M: ##alien-indirect make-value-node reset-value-graph ;
|
||||
M: ##alien-callback make-value-node reset-value-graph ;
|
||||
M: ##callback-return make-value-node reset-value-graph ;
|
||||
M: ##prologue make-value-node reset-value-graph ;
|
||||
M: ##epilogue make-value-node reset-value-graph ;
|
||||
M: ##branch make-value-node reset-value-graph ;
|
||||
M: ##if-intrinsic make-value-node uses-vregs [ live-vreg ] each ;
|
||||
M: ##flushable number-values
|
||||
dup ##pure? [ dup call-next-method ] unless
|
||||
[ insn>vn ] [ dst>> ] bi set-vn ;
|
||||
|
||||
M: insn number-values uses-vregs [ live-vreg ] each ;
|
||||
|
||||
: init-value-numbering ( -- )
|
||||
init-value-graph
|
||||
init-expressions
|
||||
init-liveness ;
|
||||
|
||||
: value-numbering ( instructions -- instructions )
|
||||
: value-numbering ( insns -- insns' )
|
||||
init-value-numbering
|
||||
[ [ make-value-node ] [ propagate ] bi ] map
|
||||
[ eliminate ] map
|
||||
sift ;
|
||||
[ [ number-values ] each ]
|
||||
[ [ eliminate propagate ] map sift ]
|
||||
bi ;
|
||||
|
|
Loading…
Reference in New Issue