diff --git a/basis/compiler/cfg/value-numbering/conditions/conditions.factor b/basis/compiler/cfg/value-numbering/conditions/conditions.factor deleted file mode 100644 index 5ef1c4fbc9..0000000000 --- a/basis/compiler/cfg/value-numbering/conditions/conditions.factor +++ /dev/null @@ -1,48 +0,0 @@ -! 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 ; diff --git a/basis/compiler/cfg/value-numbering/constant-fold/constant-fold.factor b/basis/compiler/cfg/value-numbering/constant-fold/constant-fold.factor deleted file mode 100644 index ed09bd7cec..0000000000 --- a/basis/compiler/cfg/value-numbering/constant-fold/constant-fold.factor +++ /dev/null @@ -1,18 +0,0 @@ -! 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 ; diff --git a/basis/compiler/cfg/value-numbering/liveness/liveness.factor b/basis/compiler/cfg/value-numbering/liveness/liveness.factor deleted file mode 100644 index 2dd2e56968..0000000000 --- a/basis/compiler/cfg/value-numbering/liveness/liveness.factor +++ /dev/null @@ -1,39 +0,0 @@ -! 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 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 -- ) - -: live-vn ( vn -- ) - #! Mark a VN and all VNs used in its computation as live. - dup live-vns get key? [ drop ] [ - [ live-vns get conjoin ] [ vn>expr live-expr ] bi - ] if ; - -: 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 ; - -: init-liveness ( -- ) - H{ } clone live-vns set ; - -GENERIC: eliminate ( insn -- insn' ) - -M: ##flushable eliminate dup dst>> live? [ drop f ] unless ; -M: insn eliminate ; diff --git a/basis/compiler/cfg/value-numbering/propagate/propagate.factor b/basis/compiler/cfg/value-numbering/propagate/propagate.factor index 5142c3c776..c1d6ea562f 100644 --- a/basis/compiler/cfg/value-numbering/propagate/propagate.factor +++ b/basis/compiler/cfg/value-numbering/propagate/propagate.factor @@ -60,5 +60,3 @@ M: ##dispatch propagate [ resolve ] change-src ; M: insn propagate ; - -M: f propagate ; diff --git a/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor b/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor new file mode 100644 index 0000000000..a5fcc58365 --- /dev/null +++ b/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor @@ -0,0 +1,55 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel sequences layouts accessors combinators namespaces +math +compiler.cfg.instructions +compiler.cfg.instructions.syntax +compiler.cfg.value-numbering.graph +compiler.cfg.value-numbering.expressions ; +IN: compiler.cfg.value-numbering.rewrite + +GENERIC: rewrite ( insn -- insn' ) + +: ##branch-t? ( insn -- ? ) + [ cc>> cc/= eq? ] [ src2>> \ f tag-number eq? ] bi and ; inline + +: rewrite-boolean-comparison? ( insn -- ? ) + dup ##branch-t? [ + src1>> vreg>expr compare-expr? + ] [ drop f ] if ; inline + +: >compare-expr< ( expr -- in1 in2 cc ) + [ in1>> vn>vreg ] [ in2>> vn>vreg ] [ cc>> ] tri ; inline + +: >compare-imm-expr< ( expr -- in1 in2 cc ) + [ in1>> vn>vreg ] [ in2>> vn>constant ] [ cc>> ] tri ; inline + +: rewrite-boolean-comparison ( expr -- insn ) + src1>> vreg>expr 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 ; + +: tag-fixnum-expr? ( expr -- ? ) + dup op>> \ ##shl-imm eq? + [ in2>> vn>expr value>> tag-bits get = ] [ drop f ] if ; + +: rewrite-tagged-comparison? ( insn -- ? ) + #! Are we comparing two tagged fixnums? Then untag them. + [ src1>> vreg>expr tag-fixnum-expr? ] + [ src2>> tag-mask get bitand 0 = ] + bi and ; inline + +: rewrite-tagged-comparison ( insn -- insn' ) + [ src1>> vreg>expr in1>> vn>vreg ] + [ src2>> tag-bits get neg shift ] + [ cc>> ] + tri + f \ ##compare-imm-branch boa ; + +M: ##compare-imm-branch rewrite + dup rewrite-boolean-comparison? [ rewrite-boolean-comparison ] when + dup rewrite-tagged-comparison? [ rewrite-tagged-comparison ] when ; + +M: insn rewrite ; diff --git a/basis/compiler/cfg/value-numbering/simplify/simplify.factor b/basis/compiler/cfg/value-numbering/simplify/simplify.factor index 4c3589d710..e51b0d211f 100644 --- a/basis/compiler/cfg/value-numbering/simplify/simplify.factor +++ b/basis/compiler/cfg/value-numbering/simplify/simplify.factor @@ -10,13 +10,6 @@ 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 ] } - { [ dup op>> \ ##not = ] [ in>> ] } - [ drop f ] - } cond ; - : simplify-box-float ( in -- vn/expr/f ) dup op>> \ ##unbox-float = [ in>> ] [ drop f ] if ; @@ -29,127 +22,11 @@ M: unary-expr simplify* [ 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 ; inline -! -! : constant-fold? ( in1 in2 -- ? ) -! [ constant-expr? ] both? ; -! -! : constant-fold ( in1 in2 quot -- expr ) -! 2over constant-fold? [ -! [ [ value>> ] bi@ ] dip call -! ] [ 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 ) @@ -158,3 +35,8 @@ M: expr simplify* drop f ; { [ dup expr? ] [ expr>vn nip ] } { [ dup integer? ] [ nip ] } } cond ; + +GENERIC: number-values ( insn -- ) + +M: ##flushable number-values [ >expr simplify ] [ dst>> ] bi set-vn ; +M: insn number-values drop ; diff --git a/basis/compiler/cfg/value-numbering/value-numbering-tests.factor b/basis/compiler/cfg/value-numbering/value-numbering-tests.factor index 81121f3fe9..c8a1d7884c 100644 --- a/basis/compiler/cfg/value-numbering/value-numbering-tests.factor +++ b/basis/compiler/cfg/value-numbering/value-numbering-tests.factor @@ -4,6 +4,7 @@ compiler.cfg.registers cpu.architecture tools.test kernel ; [ { 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 45 7 cc/= } } ] [ @@ -16,6 +17,7 @@ compiler.cfg.registers cpu.architecture tools.test kernel ; [ { + 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 } diff --git a/basis/compiler/cfg/value-numbering/value-numbering.factor b/basis/compiler/cfg/value-numbering/value-numbering.factor index b411efef3a..d17b2a7e1f 100644 --- a/basis/compiler/cfg/value-numbering/value-numbering.factor +++ b/basis/compiler/cfg/value-numbering/value-numbering.factor @@ -2,33 +2,14 @@ ! 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 ; +compiler.cfg.value-numbering.simplify +compiler.cfg.value-numbering.rewrite ; IN: compiler.cfg.value-numbering -: insn>vn ( insn -- vn ) >expr simplify ; inline - -GENERIC: number-values ( insn -- ) - -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 ( -- ) +: value-numbering ( insns -- insns' ) init-value-graph init-expressions - init-liveness ; - -: value-numbering ( insns -- insns' ) - init-value-numbering - [ [ number-values ] each ] - [ [ eliminate propagate ] map sift ] - bi ; + [ [ number-values ] [ rewrite propagate ] bi ] map ;