diff --git a/basis/compiler/cfg/optimizer/optimizer.factor b/basis/compiler/cfg/optimizer/optimizer.factor index 242189f3f6..598a4bfcea 100644 --- a/basis/compiler/cfg/optimizer/optimizer.factor +++ b/basis/compiler/cfg/optimizer/optimizer.factor @@ -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 ; diff --git a/basis/compiler/cfg/value-numbering/conditions/conditions.factor b/basis/compiler/cfg/value-numbering/conditions/conditions.factor new file mode 100644 index 0000000000..5ef1c4fbc9 --- /dev/null +++ b/basis/compiler/cfg/value-numbering/conditions/conditions.factor @@ -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 ; diff --git a/basis/compiler/cfg/value-numbering/constant-fold/constant-fold.factor b/basis/compiler/cfg/value-numbering/constant-fold/constant-fold.factor new file mode 100644 index 0000000000..ed09bd7cec --- /dev/null +++ b/basis/compiler/cfg/value-numbering/constant-fold/constant-fold.factor @@ -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 ; diff --git a/basis/compiler/cfg/value-numbering/expressions/expressions.factor b/basis/compiler/cfg/value-numbering/expressions/expressions.factor index f8fb0aab29..476ba7d0ab 100644 --- a/basis/compiler/cfg/value-numbering/expressions/expressions.factor +++ b/basis/compiler/cfg/value-numbering/expressions/expressions.factor @@ -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 -- 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 ) expr>vn ; inline GENERIC: >expr ( insn -- expr ) -M: ##peek >expr - [ class ] [ loc>> ] bi peek-expr boa ; +M: ##load-immediate >expr val>> ; -M: ##load-literal >expr - [ class ] [ obj>> ] bi load-literal-expr boa ; +M: ##load-indirect >expr obj>> ; 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 ; diff --git a/basis/compiler/cfg/value-numbering/graph/graph.factor b/basis/compiler/cfg/value-numbering/graph/graph.factor index b0ae044fb7..7ec9eaf7ce 100644 --- a/basis/compiler/cfg/value-numbering/graph/graph.factor +++ b/basis/compiler/cfg/value-numbering/graph/graph.factor @@ -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 exprs>vns set vregs>vns set ; - -: reset-value-graph ( -- ) - exprs>vns get clear-assoc - vregs>vns get clear-assoc ; diff --git a/basis/compiler/cfg/value-numbering/liveness/liveness.factor b/basis/compiler/cfg/value-numbering/liveness/liveness.factor index 127a584091..2dd2e56968 100644 --- a/basis/compiler/cfg/value-numbering/liveness/liveness.factor +++ b/basis/compiler/cfg/value-numbering/liveness/liveness.factor @@ -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 ; diff --git a/basis/compiler/cfg/value-numbering/propagate/propagate.factor b/basis/compiler/cfg/value-numbering/propagate/propagate.factor index 4bca1714ca..5142c3c776 100644 --- a/basis/compiler/cfg/value-numbering/propagate/propagate.factor +++ b/basis/compiler/cfg/value-numbering/propagate/propagate.factor @@ -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 ; diff --git a/basis/compiler/cfg/value-numbering/simplify/simplify.factor b/basis/compiler/cfg/value-numbering/simplify/simplify.factor new file mode 100644 index 0000000000..4c3589d710 --- /dev/null +++ b/basis/compiler/cfg/value-numbering/simplify/simplify.factor @@ -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 ] } + { [ 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 ; 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 ) + dup simplify* { + { [ dup not ] [ drop expr>vn ] } + { [ dup expr? ] [ expr>vn nip ] } + { [ dup integer? ] [ nip ] } + } cond ; diff --git a/basis/compiler/cfg/value-numbering/value-numbering-tests.factor b/basis/compiler/cfg/value-numbering/value-numbering-tests.factor new file mode 100644 index 0000000000..81121f3fe9 --- /dev/null +++ b/basis/compiler/cfg/value-numbering/value-numbering-tests.factor @@ -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 diff --git a/basis/compiler/cfg/value-numbering/value-numbering.factor b/basis/compiler/cfg/value-numbering/value-numbering.factor index a2957e59f8..b411efef3a 100644 --- a/basis/compiler/cfg/value-numbering/value-numbering.factor +++ b/basis/compiler/cfg/value-numbering/value-numbering.factor @@ -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 ;