From 2ace87370e9e37948526be7476b6a2499fc1de33 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 14 Jul 2009 16:05:25 -0500 Subject: [PATCH] compiler.cfg.value-numbering: more optimizations --- .../value-numbering/rewrite/rewrite.factor | 236 +++++++++++------- .../value-numbering/simplify/simplify.factor | 61 ++++- .../value-numbering-tests.factor | 201 +++++++++++++-- .../value-numbering/value-numbering.factor | 3 +- basis/compiler/tests/codegen.factor | 4 +- 5 files changed, 393 insertions(+), 112 deletions(-) diff --git a/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor b/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor index bc8fc50547..a0e8dd6146 100755 --- a/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor +++ b/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors locals combinators combinators.short-circuit arrays fry kernel layouts math namespaces sequences cpu.architecture -math.bitwise +math.bitwise classes compiler.cfg.hats compiler.cfg.comparisons compiler.cfg.instructions @@ -11,9 +11,15 @@ compiler.cfg.value-numbering.graph compiler.cfg.value-numbering.simplify ; IN: compiler.cfg.value-numbering.rewrite -GENERIC: rewrite ( insn -- insn' ) +! Outputs f to mean no change -M: insn rewrite ; +GENERIC: rewrite* ( insn -- insn/f ) + +: rewrite ( insn -- insn' ) + dup [ number-values ] [ rewrite* ] bi + [ rewrite ] [ ] ?if ; + +M: insn rewrite* drop f ; : ##branch-t? ( insn -- ? ) dup ##compare-imm-branch? [ @@ -61,7 +67,7 @@ M: insn rewrite ; [ cc>> ] tri ; inline -GENERIC: rewrite-tagged-comparison ( insn -- insn' ) +GENERIC: rewrite-tagged-comparison ( insn -- insn/f ) M: ##compare-imm-branch rewrite-tagged-comparison (rewrite-tagged-comparison) \ ##compare-imm-branch new-insn ; @@ -70,11 +76,12 @@ M: ##compare-imm rewrite-tagged-comparison [ dst>> ] [ (rewrite-tagged-comparison) ] bi i \ ##compare-imm new-insn ; -M: ##compare-imm-branch rewrite - dup rewrite-boolean-comparison? [ rewrite-boolean-comparison ] when - dup ##compare-imm-branch? [ - dup rewrite-tagged-comparison? [ rewrite-tagged-comparison ] when - ] when ; +M: ##compare-imm-branch rewrite* + { + { [ dup rewrite-boolean-comparison? ] [ rewrite-boolean-comparison ] } + { [ dup rewrite-tagged-comparison? ] [ rewrite-tagged-comparison ] } + [ drop f ] + } cond ; :: >compare-imm ( insn swap? -- insn' ) insn dst>> @@ -89,12 +96,12 @@ M: ##compare-imm-branch rewrite [ value>> small-enough? ] } 1&& ; -M: ##compare rewrite +M: ##compare rewrite* dup [ src1>> ] [ src2>> ] bi [ vreg-small-constant? ] bi@ 2array { { { f t } [ f >compare-imm ] } { { t f } [ t >compare-imm ] } - [ drop ] + [ 2drop f ] } case ; :: >compare-imm-branch ( insn swap? -- insn' ) @@ -103,12 +110,12 @@ M: ##compare rewrite insn cc>> swap? [ swap-cc ] when \ ##compare-imm-branch new-insn ; inline -M: ##compare-branch rewrite +M: ##compare-branch rewrite* dup [ src1>> ] [ src2>> ] bi [ vreg-small-constant? ] bi@ 2array { { { f t } [ f >compare-imm-branch ] } { { t f } [ t >compare-imm-branch ] } - [ drop ] + [ 2drop f ] } case ; : rewrite-redundant-comparison? ( insn -- ? ) @@ -126,103 +133,158 @@ M: ##compare-branch rewrite } case swap cc= eq? [ [ negate-cc ] change-cc ] when ; -M: ##compare-imm rewrite - dup rewrite-redundant-comparison? [ - rewrite-redundant-comparison - dup number-values rewrite - ] when - dup ##compare-imm? [ - dup rewrite-tagged-comparison? [ - rewrite-tagged-comparison - dup number-values rewrite - ] when - ] when ; +M: ##compare-imm rewrite* + { + { [ dup rewrite-redundant-comparison? ] [ rewrite-redundant-comparison ] } + { [ dup rewrite-tagged-comparison? ] [ rewrite-tagged-comparison ] } + [ drop f ] + } cond ; + +: constant-fold? ( insn -- ? ) + src1>> vreg>expr constant-expr? ; inline + +GENERIC: constant-fold* ( x y insn -- z ) + +M: ##add-imm constant-fold* drop + ; +M: ##sub-imm constant-fold* drop - ; +M: ##mul-imm constant-fold* drop * ; +M: ##and-imm constant-fold* drop bitand ; +M: ##or-imm constant-fold* drop bitor ; +M: ##xor-imm constant-fold* drop bitxor ; +M: ##shr-imm constant-fold* drop [ cell-bits 2^ wrap ] dip neg shift ; +M: ##sar-imm constant-fold* drop neg shift ; +M: ##shl-imm constant-fold* drop shift ; : constant-fold ( insn -- insn' ) - dup dst>> vreg>expr dup constant-expr? [ - [ dst>> ] [ value>> ] bi* \ ##load-immediate new-insn - dup number-values - ] [ - drop - ] if ; + [ dst>> ] + [ [ src1>> vreg>constant ] [ src2>> ] [ ] tri constant-fold* ] bi + \ ##load-immediate new-insn ; inline -: (new-imm-insn) ( insn dst src1 n op -- new-insn/insn ) - [ cell-bits bits ] dip over small-enough? [ - new-insn dup number-values nip - ] [ - 2drop 2drop - ] if constant-fold ; inline +:: new-imm-insn ( insn dst src1 src2 op -- new-insn/insn ) + src2 small-enough? [ dst src1 src2 op new-insn ] [ insn ] if ; inline -: new-imm-insn ( insn dst src n op -- n' op' ) - 2dup [ sgn ] dip 2array - { - { { -1 ##add-imm } [ drop neg \ ##sub-imm (new-imm-insn) ] } - { { -1 ##sub-imm } [ drop neg \ ##add-imm (new-imm-insn) ] } - [ drop (new-imm-insn) ] - } case ; inline +: reassociate? ( insn -- ? ) + [ src1>> vreg>expr op>> ] [ class ] bi = ; inline -: combine-imm? ( insn op -- ? ) - [ src1>> vreg>expr op>> ] dip = ; - -: (combine-imm) ( insn quot op -- insn ) +: reassociate ( insn op -- insn ) [ { [ ] [ dst>> ] [ src1>> vreg>expr [ in1>> vn>vreg ] [ in2>> vn>constant ] bi ] [ src2>> ] - } cleave - ] [ call ] [ ] tri* new-imm-insn ; inline + [ ] + } cleave constant-fold* + ] dip new-imm-insn ; inline -:: combine-imm ( insn quot op -- insn ) - insn op combine-imm? [ - insn quot op (combine-imm) - ] [ - insn - ] if ; inline - -M: ##add-imm rewrite +M: ##add-imm rewrite* { - { [ dup \ ##add-imm combine-imm? ] [ [ + ] \ ##add-imm (combine-imm) ] } - { [ dup \ ##sub-imm combine-imm? ] [ [ - ] \ ##sub-imm (combine-imm) ] } - [ ] + { [ dup constant-fold? ] [ constant-fold ] } + { [ dup reassociate? ] [ \ ##add-imm reassociate ] } + [ drop f ] } cond ; -M: ##sub-imm rewrite +: sub-imm>add-imm ( insn -- insn' ) + dup [ dst>> ] [ src1>> ] [ src2>> neg ] tri dup small-enough? + [ \ ##add-imm new-insn nip ] [ 2drop 2drop f ] if ; + +M: ##sub-imm rewrite* { - { [ dup \ ##add-imm combine-imm? ] [ [ - ] \ ##add-imm (combine-imm) ] } - { [ dup \ ##sub-imm combine-imm? ] [ [ + ] \ ##sub-imm (combine-imm) ] } - [ ] + { [ dup constant-fold? ] [ constant-fold ] } + [ sub-imm>add-imm ] } cond ; -M: ##mul-imm rewrite - dup src2>> dup power-of-2? [ - [ [ dst>> ] [ src1>> ] bi ] [ log2 ] bi* \ ##shl-imm new-insn - dup number-values - ] [ - drop [ * ] \ ##mul-imm combine-imm - ] if ; +: strength-reduce-mul ( insn -- insn' ) + [ [ dst>> ] [ src1>> ] bi ] [ src2>> log2 ] bi \ ##shl-imm new-insn ; -M: ##and-imm rewrite [ bitand ] \ ##and-imm combine-imm ; +: strength-reduce-mul? ( insn -- ? ) + src2>> power-of-2? ; -M: ##or-imm rewrite [ bitor ] \ ##or-imm combine-imm ; +M: ##mul-imm rewrite* + { + { [ dup constant-fold? ] [ constant-fold ] } + { [ dup strength-reduce-mul? ] [ strength-reduce-mul ] } + { [ dup reassociate? ] [ \ ##mul-imm reassociate ] } + [ drop f ] + } cond ; -M: ##xor-imm rewrite [ bitxor ] \ ##xor-imm combine-imm ; +M: ##and-imm rewrite* + { + { [ dup constant-fold? ] [ constant-fold ] } + { [ dup reassociate? ] [ \ ##and-imm reassociate ] } + [ drop f ] + } cond ; -: new-arithmetic ( obj op -- ) - [ - [ dst>> ] - [ src1>> ] - [ src2>> vreg>constant ] tri - ] dip new-insn dup number-values ; inline +M: ##or-imm rewrite* + { + { [ dup constant-fold? ] [ constant-fold ] } + { [ dup reassociate? ] [ \ ##or-imm reassociate ] } + [ drop f ] + } cond ; + +M: ##xor-imm rewrite* + { + { [ dup constant-fold? ] [ constant-fold ] } + { [ dup reassociate? ] [ \ ##xor-imm reassociate ] } + [ drop f ] + } cond ; + +M: ##shl-imm rewrite* + { + { [ dup constant-fold? ] [ constant-fold ] } + [ drop f ] + } cond ; + +M: ##shr-imm rewrite* + { + { [ dup constant-fold? ] [ constant-fold ] } + [ drop f ] + } cond ; + +M: ##sar-imm rewrite* + { + { [ dup constant-fold? ] [ constant-fold ] } + [ drop f ] + } cond ; + +:: insn>imm-insn ( insn op swap? -- ) + insn + insn dst>> + insn src1>> + insn src2>> swap? [ swap ] when vreg>constant + op new-imm-insn ; inline : rewrite-arithmetic ( insn op -- ? ) - over src2>> vreg-small-constant? [ - new-arithmetic constant-fold - ] [ - drop - ] if ; inline + { + { [ over src2>> vreg-small-constant? ] [ f insn>imm-insn ] } + [ 2drop f ] + } cond ; inline -M: ##add rewrite \ ##add-imm rewrite-arithmetic ; +: rewrite-arithmetic-commutative ( insn op -- ? ) + { + { [ over src2>> vreg-small-constant? ] [ f insn>imm-insn ] } + { [ over src1>> vreg-small-constant? ] [ t insn>imm-insn ] } + [ 2drop f ] + } cond ; inline -M: ##sub rewrite \ ##sub-imm rewrite-arithmetic ; +M: ##add rewrite* \ ##add-imm rewrite-arithmetic-commutative ; + +: subtraction-identity? ( insn -- ? ) + [ src1>> ] [ src2>> ] bi [ vreg>vn ] bi@ eq? ; + +: rewrite-subtraction-identity ( insn -- insn' ) + dst>> 0 \ ##load-immediate new-insn ; + +M: ##sub rewrite* + { + { [ dup subtraction-identity? ] [ rewrite-subtraction-identity ] } + [ \ ##sub-imm rewrite-arithmetic ] + } cond ; + +M: ##mul rewrite* \ ##mul-imm rewrite-arithmetic-commutative ; + +M: ##and rewrite* \ ##and-imm rewrite-arithmetic-commutative ; + +M: ##or rewrite* \ ##or-imm rewrite-arithmetic-commutative ; + +M: ##xor rewrite* \ ##xor-imm rewrite-arithmetic-commutative ; diff --git a/basis/compiler/cfg/value-numbering/simplify/simplify.factor b/basis/compiler/cfg/value-numbering/simplify/simplify.factor index b7526528e4..a956498af4 100644 --- a/basis/compiler/cfg/value-numbering/simplify/simplify.factor +++ b/basis/compiler/cfg/value-numbering/simplify/simplify.factor @@ -32,6 +32,8 @@ M: unary-expr simplify* : expr-zero? ( expr -- ? ) T{ constant-expr f f 0 } = ; inline +: expr-one? ( expr -- ? ) T{ constant-expr f f 1 } = ; inline + : >binary-expr< ( expr -- in1 in2 ) [ in1>> vn>expr ] [ in2>> vn>expr ] bi ; inline @@ -44,18 +46,54 @@ M: unary-expr simplify* : simplify-sub ( expr -- vn/expr/f ) >binary-expr< { - { [ 2dup eq? ] [ 2drop T{ constant-expr f f 0 } ] } { [ dup expr-zero? ] [ drop ] } [ 2drop f ] } cond ; inline -: useless-shift? ( in1 in2 -- ? ) +: simplify-mul ( expr -- vn/expr/f ) + >binary-expr< { + { [ over expr-one? ] [ drop ] } + { [ dup expr-one? ] [ drop ] } + [ 2drop f ] + } cond ; inline + +: simplify-and ( expr -- vn/expr/f ) + >binary-expr< { + { [ 2dup eq? ] [ drop ] } + [ 2drop f ] + } cond ; inline + +: simplify-or ( expr -- vn/expr/f ) + >binary-expr< { + { [ 2dup eq? ] [ drop ] } + { [ over expr-zero? ] [ nip ] } + { [ dup expr-zero? ] [ drop ] } + [ 2drop f ] + } cond ; inline + +: simplify-xor ( expr -- vn/expr/f ) + >binary-expr< { + { [ over expr-zero? ] [ nip ] } + { [ dup expr-zero? ] [ drop ] } + [ 2drop f ] + } cond ; inline + +: useless-shr? ( in1 in2 -- ? ) over op>> \ ##shl-imm eq? [ [ in2>> ] [ expr>vn ] bi* = ] [ 2drop f ] if ; inline -: simplify-shift ( expr -- vn/expr/f ) - >binary-expr< - 2dup useless-shift? [ drop in1>> ] [ 2drop f ] if ; inline +: simplify-shr ( expr -- vn/expr/f ) + >binary-expr< { + { [ 2dup useless-shr? ] [ drop in1>> ] } + { [ dup expr-zero? ] [ drop ] } + [ 2drop f ] + } cond ; inline + +: simplify-shl ( expr -- vn/expr/f ) + >binary-expr< { + { [ dup expr-zero? ] [ drop ] } + [ 2drop f ] + } cond ; inline M: binary-expr simplify* dup op>> { @@ -63,8 +101,17 @@ M: binary-expr simplify* { \ ##add-imm [ simplify-add ] } { \ ##sub [ simplify-sub ] } { \ ##sub-imm [ simplify-sub ] } - { \ ##shr-imm [ simplify-shift ] } - { \ ##sar-imm [ simplify-shift ] } + { \ ##mul [ simplify-mul ] } + { \ ##mul-imm [ simplify-mul ] } + { \ ##and [ simplify-and ] } + { \ ##and-imm [ simplify-and ] } + { \ ##or [ simplify-or ] } + { \ ##or-imm [ simplify-or ] } + { \ ##xor [ simplify-xor ] } + { \ ##xor-imm [ simplify-xor ] } + { \ ##shr-imm [ simplify-shr ] } + { \ ##sar-imm [ simplify-shr ] } + { \ ##shl-imm [ simplify-shl ] } [ 2drop f ] } case ; diff --git a/basis/compiler/cfg/value-numbering/value-numbering-tests.factor b/basis/compiler/cfg/value-numbering/value-numbering-tests.factor index 0166f8f834..6ed0a74da5 100644 --- a/basis/compiler/cfg/value-numbering/value-numbering-tests.factor +++ b/basis/compiler/cfg/value-numbering/value-numbering-tests.factor @@ -2,7 +2,7 @@ IN: compiler.cfg.value-numbering.tests USING: compiler.cfg.value-numbering compiler.cfg.instructions compiler.cfg.registers compiler.cfg.debugger compiler.cfg.comparisons cpu.architecture tools.test kernel math combinators.short-circuit -accessors sequences compiler.cfg vectors arrays ; +accessors sequences compiler.cfg vectors arrays layouts ; : trim-temps ( insns -- insns ) [ @@ -140,7 +140,7 @@ accessors sequences compiler.cfg vectors arrays ; { T{ ##peek f V int-regs 0 D 0 } T{ ##load-immediate f V int-regs 1 100 } - T{ ##sub-imm f V int-regs 2 V int-regs 0 100 } + T{ ##add-imm f V int-regs 2 V int-regs 0 -100 } } ] [ { @@ -150,6 +150,18 @@ accessors sequences compiler.cfg vectors arrays ; } test-value-numbering ] unit-test +[ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 0 } + } +] [ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##sub f V int-regs 1 V int-regs 0 V int-regs 0 } + } test-value-numbering +] unit-test + [ { T{ ##peek f V int-regs 0 D 0 } @@ -285,7 +297,7 @@ accessors sequences compiler.cfg vectors arrays ; T{ ##peek f V int-regs 0 D 0 } T{ ##load-immediate f V int-regs 1 100 } T{ ##compare f V int-regs 2 V int-regs 0 V int-regs 1 cc<= } - } test-value-numbering + } test-value-numbering trim-temps ] unit-test [ @@ -389,9 +401,9 @@ accessors sequences compiler.cfg vectors arrays ; { T{ ##peek f V int-regs 0 D 0 } T{ ##load-immediate f V int-regs 1 100 } - T{ ##sub-imm f V int-regs 2 V int-regs 0 100 } + T{ ##add-imm f V int-regs 2 V int-regs 0 -100 } T{ ##load-immediate f V int-regs 3 50 } - T{ ##sub-imm f V int-regs 4 V int-regs 0 150 } + T{ ##add-imm f V int-regs 4 V int-regs 0 -150 } } ] [ { @@ -552,8 +564,8 @@ accessors sequences compiler.cfg vectors arrays ; { T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 1 D 1 } - T{ ##sub f V int-regs 2 V int-regs 1 V int-regs 1 } - T{ ##add f V int-regs 3 V int-regs 0 V int-regs 2 } + T{ ##load-immediate f V int-regs 2 0 } + T{ ##add-imm f V int-regs 3 V int-regs 0 0 } T{ ##replace f V int-regs 0 D 0 } } ] [ @@ -570,8 +582,8 @@ accessors sequences compiler.cfg vectors arrays ; { T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 1 D 1 } - T{ ##sub f V int-regs 2 V int-regs 1 V int-regs 1 } - T{ ##sub f V int-regs 3 V int-regs 0 V int-regs 2 } + T{ ##load-immediate f V int-regs 2 0 } + T{ ##add-imm f V int-regs 3 V int-regs 0 0 } T{ ##replace f V int-regs 0 D 0 } } ] [ @@ -588,8 +600,8 @@ accessors sequences compiler.cfg vectors arrays ; { T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 1 D 1 } - T{ ##sub f V int-regs 2 V int-regs 1 V int-regs 1 } - T{ ##or f V int-regs 3 V int-regs 0 V int-regs 2 } + T{ ##load-immediate f V int-regs 2 0 } + T{ ##or-imm f V int-regs 3 V int-regs 0 0 } T{ ##replace f V int-regs 0 D 0 } } ] [ @@ -606,8 +618,8 @@ accessors sequences compiler.cfg vectors arrays ; { T{ ##peek f V int-regs 0 D 0 } T{ ##peek f V int-regs 1 D 1 } - T{ ##sub f V int-regs 2 V int-regs 1 V int-regs 1 } - T{ ##xor f V int-regs 3 V int-regs 0 V int-regs 2 } + T{ ##load-immediate f V int-regs 2 0 } + T{ ##xor-imm f V int-regs 3 V int-regs 0 0 } T{ ##replace f V int-regs 0 D 0 } } ] [ @@ -624,7 +636,7 @@ accessors sequences compiler.cfg vectors arrays ; { T{ ##peek f V int-regs 0 D 0 } T{ ##load-immediate f V int-regs 1 1 } - T{ ##mul f V int-regs 2 V int-regs 0 V int-regs 1 } + T{ ##shl-imm f V int-regs 2 V int-regs 0 0 } T{ ##replace f V int-regs 0 D 0 } } ] [ @@ -634,4 +646,163 @@ accessors sequences compiler.cfg vectors arrays ; T{ ##mul f V int-regs 2 V int-regs 0 V int-regs 1 } T{ ##replace f V int-regs 2 D 0 } } test-value-numbering -] unit-test \ No newline at end of file +] unit-test + +! Constant folding +[ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 1 } + T{ ##load-immediate f V int-regs 2 3 } + T{ ##load-immediate f V int-regs 3 4 } + } +] [ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 1 } + T{ ##load-immediate f V int-regs 2 3 } + T{ ##add f V int-regs 3 V int-regs 1 V int-regs 2 } + } test-value-numbering +] unit-test + +[ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 1 } + T{ ##load-immediate f V int-regs 2 3 } + T{ ##load-immediate f V int-regs 3 -2 } + } +] [ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 1 } + T{ ##load-immediate f V int-regs 2 3 } + T{ ##sub f V int-regs 3 V int-regs 1 V int-regs 2 } + } test-value-numbering +] unit-test + +[ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 2 } + T{ ##load-immediate f V int-regs 2 3 } + T{ ##load-immediate f V int-regs 3 6 } + } +] [ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 2 } + T{ ##load-immediate f V int-regs 2 3 } + T{ ##mul f V int-regs 3 V int-regs 1 V int-regs 2 } + } test-value-numbering +] unit-test + +[ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 2 } + T{ ##load-immediate f V int-regs 2 1 } + T{ ##load-immediate f V int-regs 3 0 } + } +] [ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 2 } + T{ ##load-immediate f V int-regs 2 1 } + T{ ##and f V int-regs 3 V int-regs 1 V int-regs 2 } + } test-value-numbering +] unit-test + +[ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 2 } + T{ ##load-immediate f V int-regs 2 1 } + T{ ##load-immediate f V int-regs 3 3 } + } +] [ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 2 } + T{ ##load-immediate f V int-regs 2 1 } + T{ ##or f V int-regs 3 V int-regs 1 V int-regs 2 } + } test-value-numbering +] unit-test + +[ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 2 } + T{ ##load-immediate f V int-regs 2 3 } + T{ ##load-immediate f V int-regs 3 1 } + } +] [ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 2 } + T{ ##load-immediate f V int-regs 2 3 } + T{ ##xor f V int-regs 3 V int-regs 1 V int-regs 2 } + } test-value-numbering +] unit-test + +[ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 1 } + T{ ##load-immediate f V int-regs 3 8 } + } +] [ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 1 } + T{ ##shl-imm f V int-regs 3 V int-regs 1 3 } + } test-value-numbering +] unit-test + +cell 8 = [ + [ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 -1 } + T{ ##load-immediate f V int-regs 3 HEX: ffffffffffff } + } + ] [ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 -1 } + T{ ##shr-imm f V int-regs 3 V int-regs 1 16 } + } test-value-numbering + ] unit-test +] when + +[ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 -8 } + T{ ##load-immediate f V int-regs 3 -4 } + } +] [ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 -8 } + T{ ##sar-imm f V int-regs 3 V int-regs 1 1 } + } test-value-numbering +] unit-test + +cell 8 = [ + [ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 65536 } + T{ ##load-immediate f V int-regs 2 140737488355328 } + T{ ##add f V int-regs 3 V int-regs 0 V int-regs 2 } + } + ] [ + { + T{ ##peek f V int-regs 0 D 0 } + T{ ##load-immediate f V int-regs 1 65536 } + T{ ##shl-imm f V int-regs 2 V int-regs 1 31 } + T{ ##add f V int-regs 3 V int-regs 0 V int-regs 2 } + } test-value-numbering + ] unit-test +] when \ No newline at end of file diff --git a/basis/compiler/cfg/value-numbering/value-numbering.factor b/basis/compiler/cfg/value-numbering/value-numbering.factor index f0efa5dcca..9e6e058b52 100644 --- a/basis/compiler/cfg/value-numbering/value-numbering.factor +++ b/basis/compiler/cfg/value-numbering/value-numbering.factor @@ -29,8 +29,7 @@ IN: compiler.cfg.value-numbering ] with-variable ; : value-numbering-step ( insns -- insns' ) - [ [ number-values ] [ rewrite ] bi ] map - dup rename-uses ; + [ rewrite ] map dup rename-uses ; : value-numbering ( cfg -- cfg' ) [ init-value-numbering ] [ value-numbering-step ] local-optimization ; diff --git a/basis/compiler/tests/codegen.factor b/basis/compiler/tests/codegen.factor index 82da31b5fe..1463dbadb5 100644 --- a/basis/compiler/tests/codegen.factor +++ b/basis/compiler/tests/codegen.factor @@ -314,4 +314,6 @@ M: cucumber equal? "The cucumber has no equal" throw ; ! Regression from Doug's value numbering changes [ t ] [ 2 [ 1 swap fixnum< ] compile-call ] unit-test -[ 3 ] [ 2 [ 1 swap fixnum< [ 3 ] [ 4 ] if ] compile-call ] unit-test \ No newline at end of file +[ 3 ] [ 2 [ 1 swap fixnum< [ 3 ] [ 4 ] if ] compile-call ] unit-test + +[ 0 ] [ 101 [ dup fixnum-fast 1 fixnum+fast 20 fixnum-shift-fast 20 fixnum-shift-fast ] compile-call ] unit-test \ No newline at end of file