]> gitweb.factorcode.org Git - factor.git/commitdiff
move compiler.cfg.graphviz & compiler.cfg.gvn from basis to extra, just to keep organized
authorAlex Vondrak <ajvondrak@csupomona.edu>
Sat, 4 Jun 2011 19:55:42 +0000 (12:55 -0700)
committerJohn Benediktsson <mrjbq7@gmail.com>
Wed, 12 Sep 2012 22:14:07 +0000 (15:14 -0700)
56 files changed:
basis/compiler/cfg/graphviz/graphviz.factor [deleted file]
basis/compiler/cfg/gvn/1.png [deleted file]
basis/compiler/cfg/gvn/2.png [deleted file]
basis/compiler/cfg/gvn/3.png [deleted file]
basis/compiler/cfg/gvn/4.png [deleted file]
basis/compiler/cfg/gvn/5.png [deleted file]
basis/compiler/cfg/gvn/alien/alien.factor [deleted file]
basis/compiler/cfg/gvn/alien/authors.txt [deleted file]
basis/compiler/cfg/gvn/comparisons/authors.txt [deleted file]
basis/compiler/cfg/gvn/comparisons/comparisons.factor [deleted file]
basis/compiler/cfg/gvn/expressions/expressions.factor [deleted file]
basis/compiler/cfg/gvn/expressions/summary.txt [deleted file]
basis/compiler/cfg/gvn/folding/authors.txt [deleted file]
basis/compiler/cfg/gvn/folding/folding.factor [deleted file]
basis/compiler/cfg/gvn/graph/graph.factor [deleted file]
basis/compiler/cfg/gvn/graph/summary.txt [deleted file]
basis/compiler/cfg/gvn/gvn-tests.factor [deleted file]
basis/compiler/cfg/gvn/gvn.factor [deleted file]
basis/compiler/cfg/gvn/math/authors.txt [deleted file]
basis/compiler/cfg/gvn/math/math.factor [deleted file]
basis/compiler/cfg/gvn/misc/authors.txt [deleted file]
basis/compiler/cfg/gvn/misc/misc.factor [deleted file]
basis/compiler/cfg/gvn/rewrite/rewrite.factor [deleted file]
basis/compiler/cfg/gvn/rewrite/summary.txt [deleted file]
basis/compiler/cfg/gvn/simd/simd.factor [deleted file]
basis/compiler/cfg/gvn/slots/authors.txt [deleted file]
basis/compiler/cfg/gvn/slots/slots.factor [deleted file]
basis/compiler/cfg/gvn/summary.txt [deleted file]
extra/compiler/cfg/graphviz/graphviz.factor [new file with mode: 0644]
extra/compiler/cfg/gvn/1.png [new file with mode: 0644]
extra/compiler/cfg/gvn/2.png [new file with mode: 0644]
extra/compiler/cfg/gvn/3.png [new file with mode: 0644]
extra/compiler/cfg/gvn/4.png [new file with mode: 0644]
extra/compiler/cfg/gvn/5.png [new file with mode: 0644]
extra/compiler/cfg/gvn/alien/alien.factor [new file with mode: 0644]
extra/compiler/cfg/gvn/alien/authors.txt [new file with mode: 0644]
extra/compiler/cfg/gvn/comparisons/authors.txt [new file with mode: 0644]
extra/compiler/cfg/gvn/comparisons/comparisons.factor [new file with mode: 0644]
extra/compiler/cfg/gvn/expressions/expressions.factor [new file with mode: 0644]
extra/compiler/cfg/gvn/expressions/summary.txt [new file with mode: 0644]
extra/compiler/cfg/gvn/folding/authors.txt [new file with mode: 0644]
extra/compiler/cfg/gvn/folding/folding.factor [new file with mode: 0644]
extra/compiler/cfg/gvn/graph/graph.factor [new file with mode: 0644]
extra/compiler/cfg/gvn/graph/summary.txt [new file with mode: 0644]
extra/compiler/cfg/gvn/gvn-tests.factor [new file with mode: 0644]
extra/compiler/cfg/gvn/gvn.factor [new file with mode: 0644]
extra/compiler/cfg/gvn/math/authors.txt [new file with mode: 0644]
extra/compiler/cfg/gvn/math/math.factor [new file with mode: 0644]
extra/compiler/cfg/gvn/misc/authors.txt [new file with mode: 0644]
extra/compiler/cfg/gvn/misc/misc.factor [new file with mode: 0644]
extra/compiler/cfg/gvn/rewrite/rewrite.factor [new file with mode: 0644]
extra/compiler/cfg/gvn/rewrite/summary.txt [new file with mode: 0644]
extra/compiler/cfg/gvn/simd/simd.factor [new file with mode: 0644]
extra/compiler/cfg/gvn/slots/authors.txt [new file with mode: 0644]
extra/compiler/cfg/gvn/slots/slots.factor [new file with mode: 0644]
extra/compiler/cfg/gvn/summary.txt [new file with mode: 0644]

diff --git a/basis/compiler/cfg/graphviz/graphviz.factor b/basis/compiler/cfg/graphviz/graphviz.factor
deleted file mode 100644 (file)
index 0fd6ae1..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-! Copyright (C) 2011 Alex Vondrak.
-! See http://factorcode.org/license.txt for BSD license
-
-USING: accessors fry io io.directories io.pathnames
-io.streams.string kernel math math.parser namespaces
-prettyprint sequences splitting strings tools.annotations
-
-compiler.cfg
-compiler.cfg.builder
-compiler.cfg.debugger
-compiler.cfg.linearization
-compiler.cfg.finalization
-compiler.cfg.optimizer
-compiler.cfg.rpo
-
-compiler.cfg.value-numbering
-compiler.cfg.value-numbering.graph
-
-graphviz
-graphviz.notation
-graphviz.render
-;
-FROM: compiler.cfg.linearization => number-blocks ;
-IN: compiler.cfg.graphviz
-
-: left-justify ( str -- str' )
-    string-lines "\\l" join ;
-
-: bb-label ( bb -- str )
-    [
-        instructions>> [ insn. ] each
-    ] with-string-writer left-justify ;
-
-: add-cfg-vertex ( graph bb -- graph' )
-    [ number>> <node> ]
-    [ bb-label =label ]
-    [ kill-block?>> [ "grey" =color "filled" =style ] when ]
-    tri add ;
-
-: add-cfg-edges ( graph bb -- graph' )
-    dup successors>> [
-        [ number>> ] bi@ ->
-    ] with each ;
-
-: cfgviz ( cfg -- graph )
-    <digraph>
-        graph[ "t" =labelloc ];
-        node[ "box" =shape "Courier" =fontname 10 =fontsize ];
-        swap [
-            [ add-cfg-vertex ] [ add-cfg-edges ] bi
-        ] each-basic-block ;
-
-: perform-pass ( cfg pass pass# -- cfg' )
-    drop def>> call( cfg -- cfg' ) ;
-
-: draw-cfg ( cfg pass pass# -- cfg )
-    [ dup cfgviz ]
-    [ name>> "After " prepend =label ]
-    [ number>string png ]
-    tri* ;
-
-: watch-pass ( cfg pass pass# -- cfg' )
-    [ perform-pass ] 2keep draw-cfg ;
-
-: begin-watching-passes ( cfg -- cfg )
-    \ build-cfg 0 draw-cfg ;
-
-: watch-passes ( cfg -- cfg' )
-    \ optimize-cfg def>> [ 1 + watch-pass ] each-index ;
-
-: finish-watching-passes ( cfg -- )
-    \ finalize-cfg
-    \ optimize-cfg def>> length 1 +
-    watch-pass drop ;
-
-: watch-cfg ( path cfg -- )
-    over make-directories
-    [
-        [
-            begin-watching-passes
-            watch-passes
-            finish-watching-passes
-        ] with-cfg
-    ] curry with-directory ;
-
-: watch-cfgs ( path cfgs -- )
-    [
-        number>string "cfg" prepend append-path
-        swap watch-cfg
-    ] with each-index ;
-
-: watch-optimizer* ( path quot -- )
-    test-builder
-    dup length 1 = [ first watch-cfg ] [ watch-cfgs ] if ;
-
-: watch-optimizer ( quot -- )
-    [ "" ] dip watch-optimizer* ;
diff --git a/basis/compiler/cfg/gvn/1.png b/basis/compiler/cfg/gvn/1.png
deleted file mode 100644 (file)
index 29234d5..0000000
Binary files a/basis/compiler/cfg/gvn/1.png and /dev/null differ
diff --git a/basis/compiler/cfg/gvn/2.png b/basis/compiler/cfg/gvn/2.png
deleted file mode 100644 (file)
index 0fd6bdd..0000000
Binary files a/basis/compiler/cfg/gvn/2.png and /dev/null differ
diff --git a/basis/compiler/cfg/gvn/3.png b/basis/compiler/cfg/gvn/3.png
deleted file mode 100644 (file)
index 6d4afc9..0000000
Binary files a/basis/compiler/cfg/gvn/3.png and /dev/null differ
diff --git a/basis/compiler/cfg/gvn/4.png b/basis/compiler/cfg/gvn/4.png
deleted file mode 100644 (file)
index 8c9683c..0000000
Binary files a/basis/compiler/cfg/gvn/4.png and /dev/null differ
diff --git a/basis/compiler/cfg/gvn/5.png b/basis/compiler/cfg/gvn/5.png
deleted file mode 100644 (file)
index 4feb312..0000000
Binary files a/basis/compiler/cfg/gvn/5.png and /dev/null differ
diff --git a/basis/compiler/cfg/gvn/alien/alien.factor b/basis/compiler/cfg/gvn/alien/alien.factor
deleted file mode 100644 (file)
index a95a959..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-! Copyright (C) 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors combinators combinators.short-circuit fry
-kernel make math sequences
-cpu.architecture
-compiler.cfg.hats
-compiler.cfg.utilities
-compiler.cfg.registers
-compiler.cfg.instructions
-compiler.cfg.gvn.math
-compiler.cfg.gvn.graph
-compiler.cfg.gvn.rewrite ;
-IN: compiler.cfg.gvn.alien
-
-M: ##box-displaced-alien rewrite
-    dup displacement>> vreg>insn zero-insn?
-    [ [ dst>> ] [ base>> ] bi <copy> ] [ drop f ] if ;
-
-! ##box-displaced-alien f 1 2 3 <class>
-! ##unbox-c-ptr 4 1 <class>
-! =>
-! ##box-displaced-alien f 1 2 3 <class>
-! ##unbox-c-ptr 5 3 <class>
-! ##add 4 5 2
-
-: rewrite-unbox-alien ( insn box-insn -- insn )
-    [ dst>> ] [ src>> ] bi* <copy> ;
-
-: rewrite-unbox-displaced-alien ( insn box-insn -- insns )
-    [
-        [ dst>> ]
-        [ [ base>> ] [ base-class>> ] [ displacement>> ] tri ] bi*
-        [ ^^unbox-c-ptr ] dip
-        ##add
-    ] { } make ;
-
-: rewrite-unbox-any-c-ptr ( insn -- insn/f )
-    dup src>> vreg>insn
-    {
-        { [ dup ##box-alien? ] [ rewrite-unbox-alien ] }
-        { [ dup ##box-displaced-alien? ] [ rewrite-unbox-displaced-alien ] }
-        [ 2drop f ]
-    } cond ;
-
-M: ##unbox-any-c-ptr rewrite rewrite-unbox-any-c-ptr ;
-
-M: ##unbox-alien rewrite rewrite-unbox-any-c-ptr ;
-
-! Fuse ##add-imm into ##load-memory(-imm) and ##store-memory(-imm)
-! just update the offset in the instruction
-: fuse-base-offset? ( insn -- ? )
-    base>> vreg>insn ##add-imm? ;
-
-: fuse-base-offset ( insn -- insn' )
-    dup base>> vreg>insn
-    [ src1>> ] [ src2>> ] bi
-    [ >>base ] [ '[ _ + ] change-offset ] bi* ;
-
-! Fuse ##add-imm into ##load-memory and ##store-memory
-! just update the offset in the instruction
-: fuse-displacement-offset? ( insn -- ? )
-    { [ scale>> 0 = ] [ displacement>> vreg>insn ##add-imm? ] } 1&& ;
-
-: fuse-displacement-offset ( insn -- insn' )
-    dup displacement>> vreg>insn
-    [ src1>> ] [ src2>> ] bi
-    [ >>displacement ] [ '[ _ + ] change-offset ] bi* ;
-
-! Fuse ##add into ##load-memory-imm and ##store-memory-imm
-! construct a new ##load-memory or ##store-memory with the
-! ##add's operand as the displacement
-: fuse-displacement? ( insn -- ? )
-    {
-        [ offset>> 0 = complex-addressing? or ]
-        [ base>> vreg>insn ##add? ]
-    } 1&& ;
-
-GENERIC: alien-insn-value ( insn -- value )
-
-M: ##load-memory-imm alien-insn-value dst>> ;
-M: ##store-memory-imm alien-insn-value src>> ;
-
-GENERIC: new-alien-insn ( value base displacement scale offset rep c-type insn -- insn )
-
-M: ##load-memory-imm new-alien-insn drop \ ##load-memory new-insn ;
-M: ##store-memory-imm new-alien-insn drop \ ##store-memory new-insn ;
-
-: fuse-displacement ( insn -- insn' )
-    {
-        [ alien-insn-value ]
-        [ base>> vreg>insn [ src1>> ] [ src2>> ] bi ]
-        [ drop 0 ]
-        [ offset>> ]
-        [ rep>> ]
-        [ c-type>> ]
-        [ ]
-    } cleave new-alien-insn ;
-
-! Fuse ##shl-imm into ##load-memory or ##store-memory
-: scale-insn? ( insn -- ? )
-    { [ ##shl-imm? ] [ src2>> { 1 2 3 } member? ] } 1&& ;
-
-: fuse-scale? ( insn -- ? )
-    { [ scale>> 0 = ] [ displacement>> vreg>insn scale-insn? ] } 1&& ;
-
-: fuse-scale ( insn -- insn' )
-    dup displacement>> vreg>insn
-    [ src1>> ] [ src2>> ] bi
-    [ >>displacement ] [ >>scale ] bi* ;
-
-: rewrite-memory-op ( insn -- insn/f )
-    complex-addressing? [
-        {
-            { [ dup fuse-base-offset? ] [ fuse-base-offset ] }
-            { [ dup fuse-displacement-offset? ] [ fuse-displacement-offset ] }
-            { [ dup fuse-scale? ] [ fuse-scale ] }
-            [ drop f ]
-        } cond
-    ] [ drop f ] if ;
-
-: rewrite-memory-imm-op ( insn -- insn/f )
-    {
-        { [ dup fuse-base-offset? ] [ fuse-base-offset ] }
-        { [ dup fuse-displacement? ] [ fuse-displacement ] }
-        [ drop f ]
-    } cond ;
-
-M: ##load-memory rewrite rewrite-memory-op ;
-M: ##load-memory-imm rewrite rewrite-memory-imm-op ;
-M: ##store-memory rewrite rewrite-memory-op ;
-M: ##store-memory-imm rewrite rewrite-memory-imm-op ;
diff --git a/basis/compiler/cfg/gvn/alien/authors.txt b/basis/compiler/cfg/gvn/alien/authors.txt
deleted file mode 100644 (file)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/basis/compiler/cfg/gvn/comparisons/authors.txt b/basis/compiler/cfg/gvn/comparisons/authors.txt
deleted file mode 100644 (file)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/basis/compiler/cfg/gvn/comparisons/comparisons.factor b/basis/compiler/cfg/gvn/comparisons/comparisons.factor
deleted file mode 100644 (file)
index 531e4d5..0000000
+++ /dev/null
@@ -1,316 +0,0 @@
-! Copyright (C) 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors combinators kernel math math.order namespaces
-sequences vectors combinators.short-circuit
-cpu.architecture
-compiler.cfg
-compiler.cfg.comparisons
-compiler.cfg.instructions
-compiler.cfg.registers
-compiler.cfg.gvn.math
-compiler.cfg.gvn.graph
-compiler.cfg.gvn.rewrite ;
-IN: compiler.cfg.gvn.comparisons
-
-! Optimizations performed here:
-!
-! 1) Eliminating intermediate boolean values when the result of
-! a comparison is used by a compare-branch
-! 2) Folding comparisons where both inputs are literal
-! 3) Folding comparisons where both inputs are congruent
-! 4) Converting compare instructions into compare-imm instructions
-
-: fold-compare-imm? ( insn -- ? )
-    src1>> vreg>insn literal-insn? ;
-
-: evaluate-compare-imm ( insn -- ? )
-    [ src1>> vreg>literal ] [ src2>> ] [ cc>> ] tri
-    {
-        { cc= [ eq? ] }
-        { cc/= [ eq? not ] }
-    } case ;
-
-: fold-compare-integer-imm? ( insn -- ? )
-    src1>> vreg>insn ##load-integer? ;
-
-: evaluate-compare-integer-imm ( insn -- ? )
-    [ src1>> vreg>integer ] [ src2>> ] [ cc>> ] tri
-    [ <=> ] dip evaluate-cc ;
-
-: fold-test-imm? ( insn -- ? )
-    src1>> vreg>insn ##load-integer? ;
-
-: evaluate-test-imm ( insn -- ? )
-    [ src1>> vreg>integer ] [ src2>> ] [ cc>> ] tri
-    [ bitand ] dip {
-        { cc= [ 0 = ] }
-        { cc/= [ 0 = not ] }
-    } case ;
-
-: rewrite-into-test? ( insn -- ? )
-    {
-        [ drop test-instruction? ]
-        [ cc>> { cc= cc/= } member-eq? ]
-        [ src2>> 0 = ]
-    } 1&& ;
-
-: >compare< ( insn -- in1 in2 cc )
-    [ src1>> ] [ src2>> ] [ cc>> ] tri ; inline
-
-: >test-vector< ( insn -- src1 temp rep vcc )
-    {
-        [ src1>> ]
-        [ drop next-vreg ]
-        [ rep>> ]
-        [ vcc>> ]
-    } cleave ; inline
-
-UNION: scalar-compare-insn
-    ##compare
-    ##compare-imm
-    ##compare-integer
-    ##compare-integer-imm
-    ##test
-    ##test-imm
-    ##compare-float-unordered
-    ##compare-float-ordered ;
-
-UNION: general-compare-insn scalar-compare-insn ##test-vector ;
-
-: rewrite-boolean-comparison? ( insn -- ? )
-    {
-        [ src1>> vreg>insn general-compare-insn? ]
-        [ src2>> not ]
-        [ cc>> cc/= eq? ]
-    } 1&& ; inline
-
-: rewrite-boolean-comparison ( insn -- insn )
-    src1>> vreg>insn {
-        { [ dup ##compare? ] [ >compare< \ ##compare-branch new-insn ] }
-        { [ dup ##compare-imm? ] [ >compare< \ ##compare-imm-branch new-insn ] }
-        { [ dup ##compare-integer? ] [ >compare< \ ##compare-integer-branch new-insn ] }
-        { [ dup ##compare-integer-imm? ] [ >compare< \ ##compare-integer-imm-branch new-insn ] }
-        { [ dup ##test? ] [ >compare< \ ##test-branch new-insn ] }
-        { [ dup ##test-imm? ] [ >compare< \ ##test-imm-branch new-insn ] }
-        { [ dup ##compare-float-unordered? ] [ >compare< \ ##compare-float-unordered-branch new-insn ] }
-        { [ dup ##compare-float-ordered? ] [ >compare< \ ##compare-float-ordered-branch new-insn ] }
-        { [ dup ##test-vector? ] [ >test-vector< \ ##test-vector-branch new-insn ] }
-    } cond ;
-
-: fold-branch ( ? -- insn )
-    0 1 ?
-    basic-block get [ nth 1vector ] change-successors drop
-    \ ##branch new-insn ;
-
-: fold-compare-imm-branch ( insn -- insn/f )
-    evaluate-compare-imm fold-branch ;
-
-: >test-branch ( insn -- insn )
-    [ src1>> ] [ src1>> ] [ cc>> ] tri \ ##test-branch new-insn ;
-
-M: ##compare-imm-branch rewrite
-    {
-        { [ dup rewrite-boolean-comparison? ] [ rewrite-boolean-comparison ] }
-        { [ dup fold-compare-imm? ] [ fold-compare-imm-branch ] }
-        [ drop f ]
-    } cond ;
-
-: fold-compare-integer-imm-branch ( insn -- insn/f )
-    evaluate-compare-integer-imm fold-branch ;
-
-M: ##compare-integer-imm-branch rewrite
-    {
-        { [ dup fold-compare-integer-imm? ] [ fold-compare-integer-imm-branch ] }
-        { [ dup rewrite-into-test? ] [ >test-branch ] }
-        [ drop f ]
-    } cond ;
-
-: fold-test-imm-branch ( insn -- insn/f )
-    evaluate-test-imm fold-branch ;
-
-M: ##test-imm-branch rewrite
-    {
-        { [ dup fold-test-imm? ] [ fold-test-imm-branch ] }
-        [ drop f ]
-    } cond ;
-
-: swap-compare ( src1 src2 cc swap? -- src1 src2 cc )
-    [ [ swap ] dip swap-cc ] when ; inline
-
-: (>compare-imm-branch) ( insn swap? -- src1 src2 cc )
-    [ [ src1>> ] [ src2>> ] [ cc>> ] tri ] dip swap-compare ; inline
-
-: >compare-imm-branch ( insn swap? -- insn' )
-    (>compare-imm-branch)
-    [ vreg>literal ] dip
-    \ ##compare-imm-branch new-insn ; inline
-
-: >compare-integer-imm-branch ( insn swap? -- insn' )
-    (>compare-imm-branch)
-    [ vreg>integer ] dip
-    \ ##compare-integer-imm-branch new-insn ; inline
-
-: evaluate-self-compare ( insn -- ? )
-    cc>> { cc= cc<= cc>= } member-eq? ;
-
-: rewrite-self-compare-branch ( insn -- insn' )
-    evaluate-self-compare fold-branch ;
-
-M: ##compare-branch rewrite
-    {
-        { [ dup src1>> vreg-immediate-comparand? ] [ t >compare-imm-branch ] }
-        { [ dup src2>> vreg-immediate-comparand? ] [ f >compare-imm-branch ] }
-        { [ dup diagonal? ] [ rewrite-self-compare-branch ] }
-        [ drop f ]
-    } cond ;
-
-M: ##compare-integer-branch rewrite
-    {
-        { [ dup src1>> vreg-immediate-arithmetic? ] [ t >compare-integer-imm-branch ] }
-        { [ dup src2>> vreg-immediate-arithmetic? ] [ f >compare-integer-imm-branch ] }
-        { [ dup diagonal? ] [ rewrite-self-compare-branch ] }
-        [ drop f ]
-    } cond ;
-
-: (>compare-imm) ( insn swap? -- dst src1 src2 cc )
-    [ { [ dst>> ] [ src1>> ] [ src2>> ] [ cc>> ] } cleave ] dip
-    swap-compare ; inline
-
-: >compare-imm ( insn swap? -- insn' )
-    (>compare-imm)
-    [ vreg>literal ] dip
-    next-vreg \ ##compare-imm new-insn ; inline
-
-: >compare-integer-imm ( insn swap? -- insn' )
-    (>compare-imm)
-    [ vreg>integer ] dip
-    next-vreg \ ##compare-integer-imm new-insn ; inline
-
-: >boolean-insn ( insn ? -- insn' )
-    [ dst>> ] dip \ ##load-reference new-insn ;
-
-: rewrite-self-compare ( insn -- insn' )
-    dup evaluate-self-compare >boolean-insn ;
-
-M: ##compare rewrite
-    {
-        { [ dup src1>> vreg-immediate-comparand? ] [ t >compare-imm ] }
-        { [ dup src2>> vreg-immediate-comparand? ] [ f >compare-imm ] }
-        { [ dup diagonal? ] [ rewrite-self-compare ] }
-        [ drop f ]
-    } cond ;
-
-M: ##compare-integer rewrite
-    {
-        { [ dup src1>> vreg-immediate-arithmetic? ] [ t >compare-integer-imm ] }
-        { [ dup src2>> vreg-immediate-arithmetic? ] [ f >compare-integer-imm ] }
-        { [ dup diagonal? ] [ rewrite-self-compare ] }
-        [ drop f ]
-    } cond ;
-
-: rewrite-redundant-comparison? ( insn -- ? )
-    {
-        [ src1>> vreg>insn scalar-compare-insn? ]
-        [ src2>> not ]
-        [ cc>> { cc= cc/= } member? ]
-    } 1&& ; inline
-
-: rewrite-redundant-comparison ( insn -- insn' )
-    [ cc>> ] [ dst>> ] [ src1>> vreg>insn ] tri {
-        { [ dup ##compare? ] [ >compare< next-vreg \ ##compare new-insn ] }
-        { [ dup ##compare-imm? ] [ >compare< next-vreg \ ##compare-imm new-insn ] }
-        { [ dup ##compare-integer? ] [ >compare< next-vreg \ ##compare-integer new-insn ] }
-        { [ dup ##compare-integer-imm? ] [ >compare< next-vreg \ ##compare-integer-imm new-insn ] }
-        { [ dup ##test? ] [ >compare< next-vreg \ ##test new-insn ] }
-        { [ dup ##test-imm? ] [ >compare< next-vreg \ ##test-imm new-insn ] }
-        { [ dup ##compare-float-unordered? ] [ >compare< next-vreg \ ##compare-float-unordered new-insn ] }
-        { [ dup ##compare-float-ordered? ] [ >compare< next-vreg \ ##compare-float-ordered new-insn ] }
-    } cond
-    swap cc= eq? [ [ negate-cc ] change-cc ] when ;
-
-: fold-compare-imm ( insn -- insn' )
-    dup evaluate-compare-imm >boolean-insn ;
-
-M: ##compare-imm rewrite
-    {
-        { [ dup rewrite-redundant-comparison? ] [ rewrite-redundant-comparison ] }
-        { [ dup fold-compare-imm? ] [ fold-compare-imm ] }
-        [ drop f ]
-    } cond ;
-
-: fold-compare-integer-imm ( insn -- insn' )
-    dup evaluate-compare-integer-imm >boolean-insn ;
-
-: >test ( insn -- insn' )
-    { [ dst>> ] [ src1>> ] [ src1>> ] [ cc>> ] [ temp>> ] } cleave
-    \ ##test new-insn ;
-
-M: ##compare-integer-imm rewrite
-    {
-        { [ dup fold-compare-integer-imm? ] [ fold-compare-integer-imm ] }
-        { [ dup rewrite-into-test? ] [ >test ] }
-        [ drop f ]
-    } cond ;
-
-: (simplify-test) ( insn -- src1 src2 cc )
-    [ src1>> vreg>insn [ src1>> ] [ src2>> ] bi ] [ cc>> ] bi ; inline
-
-: simplify-test ( insn -- insn )
-    dup (simplify-test) drop [ >>src1 ] [ >>src2 ] bi* ; inline
-
-: simplify-test-branch ( insn -- insn )
-    dup (simplify-test) drop [ >>src1 ] [ >>src2 ] bi* ; inline
-
-: (simplify-test-imm) ( insn -- src1 src2 cc )
-    [ src1>> vreg>insn [ src1>> ] [ src2>> ] bi ] [ cc>> ] bi ; inline
-
-: simplify-test-imm ( insn -- insn )
-    [ dst>> ] [ (simplify-test-imm) ] [ temp>> ] tri \ ##test-imm new-insn ; inline
-
-: simplify-test-imm-branch ( insn -- insn )
-    (simplify-test-imm) \ ##test-imm-branch new-insn ; inline
-
-: >test-imm ( insn ? -- insn' )
-    (>compare-imm) [ vreg>integer ] dip next-vreg
-    \ ##test-imm new-insn ; inline
-
-: >test-imm-branch ( insn ? -- insn' )
-    (>compare-imm-branch) [ vreg>integer ] dip
-    \ ##test-imm-branch new-insn ; inline
-
-M: ##test rewrite
-    {
-        { [ dup src1>> vreg-immediate-comparand? ] [ t >test-imm ] }
-        { [ dup src2>> vreg-immediate-comparand? ] [ f >test-imm ] }
-        { [ dup diagonal? ] [
-            {
-                { [ dup src1>> vreg>insn ##and? ] [ simplify-test ] }
-                { [ dup src1>> vreg>insn ##and-imm? ] [ simplify-test-imm ] }
-                [ drop f ]
-            } cond
-        ] }
-        [ drop f ]
-    } cond ;
-
-M: ##test-branch rewrite
-    {
-        { [ dup src1>> vreg-immediate-comparand? ] [ t >test-imm-branch ] }
-        { [ dup src2>> vreg-immediate-comparand? ] [ f >test-imm-branch ] }
-        { [ dup diagonal? ] [
-            {
-                { [ dup src1>> vreg>insn ##and? ] [ simplify-test-branch ] }
-                { [ dup src1>> vreg>insn ##and-imm? ] [ simplify-test-imm-branch ] }
-                [ drop f ]
-            } cond
-        ] }
-        [ drop f ]
-    } cond ;
-
-: fold-test-imm ( insn -- insn' )
-    dup evaluate-test-imm >boolean-insn ;
-
-M: ##test-imm rewrite
-    {
-        { [ dup fold-test-imm? ] [ fold-test-imm ] }
-        [ drop f ]
-    } cond ;
diff --git a/basis/compiler/cfg/gvn/expressions/expressions.factor b/basis/compiler/cfg/gvn/expressions/expressions.factor
deleted file mode 100644 (file)
index 6af5dd0..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-! Copyright (C) 2008, 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays classes classes.algebra combinators fry
-generic.parser kernel math namespaces quotations sequences slots
-words make sets
-compiler.cfg.instructions
-compiler.cfg.instructions.syntax
-compiler.cfg.gvn.graph ;
-FROM: sequences.private => set-array-nth ;
-IN: compiler.cfg.gvn.expressions
-
-<<
-
-GENERIC: >expr ( insn -- expr )
-
-: input-values ( slot-specs -- slot-specs' )
-    [ type>> { use literal } member-eq? ] filter ;
-
-: slot->expr-quot ( slot-spec -- quot )
-    [ name>> reader-word 1quotation ]
-    [
-        type>> {
-            { use [ [ vreg>vn ] ] }
-            { literal [ [ ] ] }
-        } case
-    ] bi append ;
-
-: narray-quot ( length -- quot )
-    [
-        [ , [ f <array> ] % ]
-        [ 
-            dup iota [
-                - 1 - , [ swap [ set-array-nth ] keep ] %
-            ] with each
-        ] bi
-    ] [ ] make ;
-
-: >expr-quot ( insn slot-specs -- quot )
-    [
-        [ literalize , \ swap , ]
-        [
-            [ [ slot->expr-quot ] map cleave>quot % ]
-            [ length 1 + narray-quot % ]
-            bi
-        ] bi*
-    ] [ ] make ;
-
-: define->expr-method ( insn slot-specs -- )
-    [ drop \ >expr create-method-in ] [ >expr-quot ] 2bi define ;
-
-insn-classes get
-[ foldable-insn class<= ] filter
-{ ##copy ##load-integer ##load-reference } diff
-[
-    dup "insn-slots" word-prop input-values
-    define->expr-method
-] each
-
->>
-
-TUPLE: integer-expr value ;
-
-C: <integer-expr> integer-expr
-
-TUPLE: reference-expr value ;
-
-C: <reference-expr> reference-expr
-
-M: reference-expr equal?
-    over reference-expr? [
-        [ value>> ] bi@
-        2dup [ float? ] both?
-        [ fp-bitwise= ] [ eq? ] if
-    ] [ 2drop f ] if ;
-
-M: reference-expr hashcode*
-    nip value>> dup float? [ double>bits ] [ identity-hashcode ] if ;
-
-M: insn >expr drop input-expr-counter counter neg ;
-
-M: ##copy >expr "Fail" throw ;
-
-M: ##load-integer >expr val>> <integer-expr> ;
-
-M: ##load-reference >expr obj>> <reference-expr> ;
diff --git a/basis/compiler/cfg/gvn/expressions/summary.txt b/basis/compiler/cfg/gvn/expressions/summary.txt
deleted file mode 100644 (file)
index 22aacde..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Value numbering expressions
diff --git a/basis/compiler/cfg/gvn/folding/authors.txt b/basis/compiler/cfg/gvn/folding/authors.txt
deleted file mode 100644 (file)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/basis/compiler/cfg/gvn/folding/folding.factor b/basis/compiler/cfg/gvn/folding/folding.factor
deleted file mode 100644 (file)
index ca6c2ef..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-! Copyright (C) 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel layouts math math.bitwise
-compiler.cfg.instructions
-compiler.cfg.gvn.graph
-compiler.cfg.gvn.rewrite ;
-IN: compiler.cfg.gvn.folding
-
-: binary-constant-fold? ( insn -- ? )
-    src1>> vreg>insn ##load-integer? ; inline
-
-GENERIC: binary-constant-fold* ( x y insn -- z )
-
-M: ##add-imm binary-constant-fold* drop + ;
-M: ##sub-imm binary-constant-fold* drop - ;
-M: ##mul-imm binary-constant-fold* drop * ;
-M: ##and-imm binary-constant-fold* drop bitand ;
-M: ##or-imm binary-constant-fold* drop bitor ;
-M: ##xor-imm binary-constant-fold* drop bitxor ;
-M: ##shr-imm binary-constant-fold* drop [ cell-bits 2^ wrap ] dip neg shift ;
-M: ##sar-imm binary-constant-fold* drop neg shift ;
-M: ##shl-imm binary-constant-fold* drop shift ;
-
-: binary-constant-fold ( insn -- insn' )
-    [ dst>> ]
-    [ [ src1>> vreg>integer ] [ src2>> ] [ ] tri binary-constant-fold* ] bi
-    \ ##load-integer new-insn ; inline
-
-: unary-constant-fold? ( insn -- ? )
-    src>> vreg>insn ##load-integer? ; inline
-
-GENERIC: unary-constant-fold* ( x insn -- y )
-
-M: ##not unary-constant-fold* drop bitnot ;
-M: ##neg unary-constant-fold* drop neg ;
-
-: unary-constant-fold ( insn -- insn' )
-    [ dst>> ] [ [ src>> vreg>integer ] [ ] bi unary-constant-fold* ] bi
-    \ ##load-integer new-insn ; inline
diff --git a/basis/compiler/cfg/gvn/graph/graph.factor b/basis/compiler/cfg/gvn/graph/graph.factor
deleted file mode 100644 (file)
index e951d15..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-! Copyright (C) 2008, 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel math namespaces assocs ;
-IN: compiler.cfg.gvn.graph
-
-SYMBOL: input-expr-counter
-
-! assoc mapping vregs to value numbers
-! this is the identity on canonical representatives
-SYMBOL: vregs>vns
-
-! assoc mapping expressions to value numbers
-SYMBOL: exprs>vns
-
-! assoc mapping value numbers to instructions
-SYMBOL: vns>insns
-
-! assoc mapping vregs to *global* value numbers
-SYMBOL: vregs>gvns
-
-SYMBOL: changed?
-
-: vn>insn ( vn -- insn ) vns>insns get at ;
-
-! : vreg>vn ( vreg -- vn ) vregs>vns get [ ] cache ;
-
-: vreg>vn ( vreg -- vn ) vregs>gvns get at ;
-
-! : set-vn ( vn vreg -- ) vregs>vns get set-at ;
-
-: local-vn ( vn vreg -- lvn )
-    vregs>vns get ?at
-    [ nip ]
-    [ dupd vregs>vns get set-at ] if ;
-
-: set-vn ( vn vreg -- )
-    [ local-vn ] keep
-    vregs>gvns get maybe-set-at [ changed? on ] when ;
-
-: vreg>insn ( vreg -- insn ) vreg>vn vn>insn ;
-
-: init-gvn ( -- )
-    H{ } clone vregs>gvns set ;
-
-: init-value-graph ( -- )
-    0 input-expr-counter set
-    H{ } clone vregs>vns set
-    H{ } clone exprs>vns set
-    H{ } clone vns>insns set ;
diff --git a/basis/compiler/cfg/gvn/graph/summary.txt b/basis/compiler/cfg/gvn/graph/summary.txt
deleted file mode 100644 (file)
index f6fb58d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Value numbering expression graph
diff --git a/basis/compiler/cfg/gvn/gvn-tests.factor b/basis/compiler/cfg/gvn/gvn-tests.factor
deleted file mode 100644 (file)
index 4732698..0000000
+++ /dev/null
@@ -1,3098 +0,0 @@
-USING: compiler.cfg.gvn 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.predecessors locals compiler.cfg.dce
-compiler.cfg.ssa.destruction compiler.cfg.loop-detection
-compiler.cfg.representations compiler.cfg assocs vectors arrays
-layouts literals namespaces alien compiler.cfg.gvn.simd system
-;
-QUALIFIED-WITH: alien.c-types c
-IN: compiler.cfg.gvn.tests
-
-: trim-temps ( insns -- insns )
-    [
-        dup {
-            [ ##compare? ]
-            [ ##compare-imm? ]
-            [ ##compare-integer? ]
-            [ ##compare-integer-imm? ]
-            [ ##compare-float-unordered? ]
-            [ ##compare-float-ordered? ]
-            [ ##test? ]
-            [ ##test-imm? ]
-            [ ##test-vector? ]
-            [ ##test-vector-branch? ]
-        } 1|| [ f >>temp ] when
-    ] map ;
-
-! Folding constants together
-[
-    {
-        T{ ##load-reference f 0 0.0 }
-        T{ ##load-reference f 1 -0.0 }
-    }
-] [
-    {
-        T{ ##load-reference f 0 0.0 }
-        T{ ##load-reference f 1 -0.0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-reference f 0 0.0 }
-        T{ ##copy f 1 0 any-rep }
-    }
-] [
-    {
-        T{ ##load-reference f 0 0.0 }
-        T{ ##load-reference f 1 0.0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-reference f 0 t }
-        T{ ##copy f 1 0 any-rep }
-    }
-] [
-    {
-        T{ ##load-reference f 0 t }
-        T{ ##load-reference f 1 t }
-    } value-numbering-step
-] unit-test
-
-! ##load-reference/##replace fusion
-cpu x86? [
-    [
-        {
-            T{ ##load-integer f 0 10 }
-            T{ ##replace-imm f 10 D 0 }
-        }
-    ] [
-        {
-            T{ ##load-integer f 0 10 }
-            T{ ##replace f 0 D 0 }
-        } value-numbering-step
-    ] unit-test
-
-    [
-        {
-            T{ ##load-reference f 0 f }
-            T{ ##replace-imm f f D 0 }
-        }
-    ] [
-        {
-            T{ ##load-reference f 0 f }
-            T{ ##replace f 0 D 0 }
-        } value-numbering-step
-    ] unit-test
-] when
-
-cpu x86.32? [
-    [
-        {
-            T{ ##load-reference f 0 + }
-            T{ ##replace-imm f + D 0 }
-        }
-    ] [
-        {
-            T{ ##load-reference f 0 + }
-            T{ ##replace f 0 D 0 }
-        } value-numbering-step
-    ] unit-test
-] when
-
-cpu x86.64? [
-    [
-        {
-            T{ ##load-integer f 0 10,000,000,000 }
-            T{ ##replace f 0 D 0 }
-        }
-    ] [
-        {
-            T{ ##load-integer f 0 10,000,000,000 }
-            T{ ##replace f 0 D 0 }
-        } value-numbering-step
-    ] unit-test
-
-    ! Boundary case
-    [
-        {
-            T{ ##load-integer f 0 HEX: 7fffffff }
-            T{ ##replace f 0 D 0 }
-        }
-    ] [
-        {
-            T{ ##load-integer f 0 HEX: 7fffffff }
-            T{ ##replace f 0 D 0 }
-        } value-numbering-step
-    ] unit-test
-] when
-
-! Double compare elimination
-[
-    {
-        T{ ##peek f 1 D 1 }
-        T{ ##peek f 2 D 2 }
-        T{ ##compare f 4 2 1 cc= }
-        T{ ##copy f 6 4 any-rep }
-        T{ ##replace f 6 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 1 D 1 }
-        T{ ##peek f 2 D 2 }
-        T{ ##compare f 4 2 1 cc= }
-        T{ ##compare-imm f 6 4 f cc/= }
-        T{ ##replace f 6 D 0 }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 1 D 1 }
-        T{ ##compare-imm f 2 1 16 cc= }
-        T{ ##copy f 3 2 any-rep }
-        T{ ##replace f 3 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 1 D 1 }
-        T{ ##compare-imm f 2 1 16 cc= }
-        T{ ##compare-imm f 3 2 f cc/= }
-        T{ ##replace f 3 D 0 }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 1 D 1 }
-        T{ ##peek f 2 D 2 }
-        T{ ##compare-integer f 4 2 1 cc> }
-        T{ ##copy f 6 4 any-rep }
-        T{ ##replace f 6 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 1 D 1 }
-        T{ ##peek f 2 D 2 }
-        T{ ##compare-integer f 4 2 1 cc> }
-        T{ ##compare-imm f 6 4 f cc/= }
-        T{ ##replace f 6 D 0 }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 1 D 1 }
-        T{ ##peek f 2 D 2 }
-        T{ ##compare-integer f 4 2 1 cc<= }
-        T{ ##compare-integer f 6 2 1 cc/<= }
-        T{ ##replace f 6 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 1 D 1 }
-        T{ ##peek f 2 D 2 }
-        T{ ##compare-integer f 4 2 1 cc<= }
-        T{ ##compare-imm f 6 4 f cc= }
-        T{ ##replace f 6 D 0 }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 1 D 1 }
-        T{ ##compare-integer-imm f 2 1 100 cc<= }
-        T{ ##compare-integer-imm f 3 1 100 cc/<= }
-        T{ ##replace f 3 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 1 D 1 }
-        T{ ##compare-integer-imm f 2 1 100 cc<= }
-        T{ ##compare-imm f 3 2 f cc= }
-        T{ ##replace f 3 D 0 }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 8 D 0 }
-        T{ ##peek f 9 D -1 }
-        T{ ##compare-float-unordered f 12 8 9 cc< }
-        T{ ##compare-float-unordered f 14 8 9 cc/< }
-        T{ ##replace f 14 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 8 D 0 }
-        T{ ##peek f 9 D -1 }
-        T{ ##compare-float-unordered f 12 8 9 cc< }
-        T{ ##compare-imm f 14 12 f cc= }
-        T{ ##replace f 14 D 0 }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 29 D -1 }
-        T{ ##peek f 30 D -2 }
-        T{ ##compare f 33 29 30 cc= }
-        T{ ##compare-branch f 29 30 cc= }
-    }
-] [
-    {
-        T{ ##peek f 29 D -1 }
-        T{ ##peek f 30 D -2 }
-        T{ ##compare f 33 29 30 cc= }
-        T{ ##compare-imm-branch f 33 f cc/= }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 29 D -1 }
-        T{ ##peek f 30 D -2 }
-        T{ ##compare-integer f 33 29 30 cc<= }
-        T{ ##compare-integer-branch f 29 30 cc<= }
-    }
-] [
-    {
-        T{ ##peek f 29 D -1 }
-        T{ ##peek f 30 D -2 }
-        T{ ##compare-integer f 33 29 30 cc<= }
-        T{ ##compare-imm-branch f 33 f cc/= }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 29 D -1 }
-        T{ ##peek f 30 D -2 }
-        T{ ##test f 33 29 30 cc= }
-        T{ ##test-branch f 29 30 cc= }
-    }
-] [
-    {
-        T{ ##peek f 29 D -1 }
-        T{ ##peek f 30 D -2 }
-        T{ ##test f 33 29 30 cc= }
-        T{ ##compare-imm-branch f 33 f cc/= }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 29 D -1 }
-        T{ ##test-imm f 33 29 30 cc= }
-        T{ ##test-imm-branch f 29 30 cc= }
-    }
-] [
-    {
-        T{ ##peek f 29 D -1 }
-        T{ ##test-imm f 33 29 30 cc= }
-        T{ ##compare-imm-branch f 33 f cc/= }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 1 D -1 }
-        T{ ##test-vector f 2 1 f float-4-rep vcc-any }
-        T{ ##test-vector-branch f 1 f float-4-rep vcc-any }
-    }
-] [
-    {
-        T{ ##peek f 1 D -1 }
-        T{ ##test-vector f 2 1 f float-4-rep vcc-any }
-        T{ ##compare-imm-branch f 2 f cc/= }
-    } value-numbering-step trim-temps
-] unit-test
-
-cpu x86.32? [
-    [
-        {
-            T{ ##peek f 1 D 0 }
-            T{ ##compare-imm f 2 1 + cc= }
-            T{ ##compare-imm-branch f 1 + cc= }
-        }
-    ] [
-        {
-            T{ ##peek f 1 D 0 }
-            T{ ##compare-imm f 2 1 + cc= }
-            T{ ##compare-imm-branch f 2 f cc/= }
-        } value-numbering-step trim-temps
-    ] unit-test
-] when
-
-! Immediate operand fusion
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##add-imm f 2 0 100 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##add f 2 0 1 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##add-imm f 2 0 100 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##add f 2 1 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##add-imm f 2 0 -100 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##sub f 2 0 1 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##sub f 1 0 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##mul-imm f 2 0 100 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##mul f 2 0 1 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##mul-imm f 2 0 100 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##mul f 2 1 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 1 D 0 }
-        T{ ##shl-imm f 2 1 3 }
-    }
-] [
-    {
-        T{ ##peek f 1 D 0 }
-        T{ ##mul-imm f 2 1 8 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 -1 }
-        T{ ##neg f 2 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 -1 }
-        T{ ##mul f 2 0 1 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 -1 }
-        T{ ##neg f 2 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 -1 }
-        T{ ##mul f 2 1 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 0 }
-        T{ ##neg f 2 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 0 }
-        T{ ##sub f 2 1 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 0 }
-        T{ ##neg f 2 0 }
-        T{ ##copy f 3 0 any-rep }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 0 }
-        T{ ##sub f 2 1 0 }
-        T{ ##sub f 3 1 2 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##neg f 1 0 }
-        T{ ##copy f 2 0 any-rep }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##neg f 1 0 }
-        T{ ##neg f 2 1 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##not f 1 0 }
-        T{ ##copy f 2 0 any-rep }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##not f 1 0 }
-        T{ ##not f 2 1 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##and-imm f 2 0 100 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##and f 2 0 1 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##and-imm f 2 0 100 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##and f 2 1 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##or-imm f 2 0 100 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##or f 2 0 1 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##or-imm f 2 0 100 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##or f 2 1 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##xor-imm f 2 0 100 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##xor f 2 0 1 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##xor-imm f 2 0 100 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##xor f 2 1 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##compare-imm f 2 0 100 cc= }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##compare f 2 0 1 cc= }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##compare-integer-imm f 2 0 100 cc<= }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##compare-integer f 2 0 1 cc<= }
-    } value-numbering-step trim-temps
-] unit-test
-
-cpu x86.32? [
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-reference f 1 + }
-            T{ ##compare-imm f 2 0 + cc= }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-reference f 1 + }
-            T{ ##compare f 2 0 1 cc= }
-        } value-numbering-step trim-temps
-    ] unit-test
-
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-reference f 1 + }
-            T{ ##compare-imm-branch f 0 + cc= }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-reference f 1 + }
-            T{ ##compare-branch f 0 1 cc= }
-        } value-numbering-step trim-temps
-    ] unit-test
-] when
-
-cpu x86.32? [
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-reference f 1 3.5 }
-            T{ ##compare f 2 0 1 cc= }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-reference f 1 3.5 }
-            T{ ##compare f 2 0 1 cc= }
-        } value-numbering-step trim-temps
-    ] unit-test
-
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-reference f 1 3.5 }
-            T{ ##compare-branch f 0 1 cc= }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-reference f 1 3.5 }
-            T{ ##compare-branch f 0 1 cc= }
-        } value-numbering-step trim-temps
-    ] unit-test
-] unless
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##compare-integer-imm f 2 0 100 cc>= }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##compare-integer f 2 1 0 cc<= }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##compare-integer-imm-branch f 0 100 cc<= }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##compare-integer-branch f 0 1 cc<= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##compare-integer-imm-branch f 0 100 cc>= }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##compare-integer-branch f 1 0 cc<= }
-    } value-numbering-step trim-temps
-] unit-test
-
-! Compare folding
-[
-    {
-        T{ ##load-integer f 1 100 }
-        T{ ##load-integer f 2 200 }
-        T{ ##load-reference f 3 t }
-    }
-] [
-    {
-        T{ ##load-integer f 1 100 }
-        T{ ##load-integer f 2 200 }
-        T{ ##compare-integer f 3 1 2 cc<= }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 100 }
-        T{ ##load-integer f 2 200 }
-        T{ ##load-reference f 3 f }
-    }
-] [
-    {
-        T{ ##load-integer f 1 100 }
-        T{ ##load-integer f 2 200 }
-        T{ ##compare-integer f 3 1 2 cc= }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 100 }
-        T{ ##load-reference f 2 f }
-    }
-] [
-    {
-        T{ ##load-integer f 1 100 }
-        T{ ##compare-integer-imm f 2 1 123 cc= }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 10 }
-        T{ ##load-integer f 2 20 }
-        T{ ##load-reference f 3 f }
-    }
-] [
-    {
-        T{ ##load-integer f 1 10 }
-        T{ ##load-integer f 2 20 }
-        T{ ##compare-integer f 3 1 2 cc= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 2 }
-        T{ ##load-reference f 3 t }
-    }
-] [
-    {
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 2 }
-        T{ ##compare-integer f 3 1 2 cc/= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 2 }
-        T{ ##load-reference f 3 t }
-    }
-] [
-    {
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 2 }
-        T{ ##compare-integer f 3 1 2 cc< }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 10 }
-        T{ ##load-integer f 2 20 }
-        T{ ##load-reference f 3 f }
-    }
-] [
-    {
-        T{ ##load-integer f 1 10 }
-        T{ ##load-integer f 2 20 }
-        T{ ##compare-integer f 3 2 1 cc< }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-reference f 1 f }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare-integer f 1 0 0 cc< }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##copy f 1 0 any-rep }
-        T{ ##load-reference f 2 f }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##copy f 1 0 any-rep }
-        T{ ##compare-integer f 2 0 1 cc< }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-reference f 1 t }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare-integer f 1 0 0 cc<= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-reference f 1 f }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare-integer f 1 0 0 cc> }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-reference f 1 t }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare-integer f 1 0 0 cc>= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-reference f 1 f }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare-integer f 1 0 0 cc/= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-reference f 1 t }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare-integer f 1 0 0 cc= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 10 }
-        T{ ##load-reference f 2 t }
-    }
-] [
-    {
-        T{ ##load-integer f 1 10 }
-        T{ ##compare-imm f 2 1 10 cc= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 10 }
-        T{ ##load-reference f 2 f }
-    }
-] [
-    {
-        T{ ##load-integer f 1 10 }
-        T{ ##compare-imm f 2 1 20 cc= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 10 }
-        T{ ##load-reference f 2 t }
-    }
-] [
-    {
-        T{ ##load-integer f 1 10 }
-        T{ ##compare-imm f 2 1 100 cc/= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 10 }
-        T{ ##load-reference f 2 f }
-    }
-] [
-    {
-        T{ ##load-integer f 1 10 }
-        T{ ##compare-imm f 2 1 10 cc/= }
-    } value-numbering-step
-] unit-test
-
-cpu x86.32? [
-    [
-        {
-            T{ ##load-reference f 1 + }
-            T{ ##load-reference f 2 f }
-        }
-    ] [
-        {
-            T{ ##load-reference f 1 + }
-            T{ ##compare-imm f 2 1 + cc/= }
-        } value-numbering-step
-    ] unit-test
-
-    [
-        {
-            T{ ##load-reference f 1 + }
-            T{ ##load-reference f 2 t }
-        }
-    ] [
-        {
-            T{ ##load-reference f 1 + }
-            T{ ##compare-imm f 2 1 * cc/= }
-        } value-numbering-step
-    ] unit-test
-
-    [
-        {
-            T{ ##load-reference f 1 + }
-            T{ ##load-reference f 2 t }
-        }
-    ] [
-        {
-            T{ ##load-reference f 1 + }
-            T{ ##compare-imm f 2 1 + cc= }
-        } value-numbering-step
-    ] unit-test
-
-    [
-        {
-            T{ ##load-reference f 1 + }
-            T{ ##load-reference f 2 f }
-        }
-    ] [
-        {
-            T{ ##load-reference f 1 + }
-            T{ ##compare-imm f 2 1 * cc= }
-        } value-numbering-step
-    ] unit-test
-] when
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-reference f 1 t }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare f 1 0 0 cc= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-reference f 1 f }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare f 1 0 0 cc/= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 12 }
-        T{ ##load-reference f 3 t }
-    }
-] [
-    {
-        T{ ##load-integer f 1 12 }
-        T{ ##test-imm f 3 1 13 cc/= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 15 }
-        T{ ##load-reference f 3 f }
-    }
-] [
-    {
-        T{ ##load-integer f 1 15 }
-        T{ ##test-imm f 3 1 16 cc/= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 12 }
-        T{ ##load-reference f 3 f }
-    }
-] [
-    {
-        T{ ##load-integer f 1 12 }
-        T{ ##test-imm f 3 1 13 cc= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 15 }
-        T{ ##load-reference f 3 t }
-    }
-] [
-    {
-        T{ ##load-integer f 1 15 }
-        T{ ##test-imm f 3 1 16 cc= }
-    } value-numbering-step
-] unit-test
-
-! Rewriting a ##test of an ##and into a ##test
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##and f 2 0 1 }
-        T{ ##test f 3 0 1 cc= }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##and f 2 0 1 }
-        T{ ##test f 3 2 2 cc= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##and-imm f 2 0 12 }
-        T{ ##test-imm f 3 0 12 cc= }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##and-imm f 2 0 12 }
-        T{ ##test f 3 2 2 cc= }
-    } value-numbering-step
-] unit-test
-
-! Rewriting ##test into ##test-imm
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 10 }
-        T{ ##test-imm f 2 0 10 cc= }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 10 }
-        T{ ##test f 2 0 1 cc= }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 10 }
-        T{ ##test-imm f 2 0 10 cc= }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 10 }
-        T{ ##test f 2 1 0 cc= }
-    } value-numbering-step trim-temps
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 10 }
-        T{ ##test-imm-branch f 0 10 cc= }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 10 }
-        T{ ##test-branch f 0 1 cc= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 10 }
-        T{ ##test-imm-branch f 0 10 cc= }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 10 }
-        T{ ##test-branch f 1 0 cc= }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 10 }
-        T{ ##test-imm-branch f 0 10 cc= }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 10 }
-        T{ ##test-branch f 1 0 cc= }
-    } value-numbering-step
-] unit-test
-
-! Make sure the immediate fits
-cpu x86.64? [
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-integer f 1 100000000000 }
-            T{ ##test f 2 1 0 cc= }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-integer f 1 100000000000 }
-            T{ ##test f 2 1 0 cc= }
-        } value-numbering-step
-    ] unit-test
-
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-integer f 1 100000000000 }
-            T{ ##test-branch f 1 0 cc= }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-integer f 1 100000000000 }
-            T{ ##test-branch f 1 0 cc= }
-        } value-numbering-step
-    ] unit-test
-] when
-
-! Rewriting ##compare into ##test
-cpu x86? [
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##test f 1 0 0 cc= }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##compare-integer-imm f 1 0 0 cc= }
-        } value-numbering-step
-    ] unit-test
-
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##test f 1 0 0 cc/= }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##compare-integer-imm f 1 0 0 cc/= }
-        } value-numbering-step
-    ] unit-test
-
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##compare-integer-imm f 1 0 0 cc<= }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##compare-integer-imm f 1 0 0 cc<= }
-        } value-numbering-step
-    ] unit-test
-    
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##test-branch f 0 0 cc= }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##compare-integer-imm-branch f 0 0 cc= }
-        } value-numbering-step
-    ] unit-test
-
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##test-branch f 0 0 cc/= }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##compare-integer-imm-branch f 0 0 cc/= }
-        } value-numbering-step
-    ] unit-test
-
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##compare-integer-imm-branch f 0 0 cc<= }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##compare-integer-imm-branch f 0 0 cc<= }
-        } value-numbering-step
-    ] unit-test
-] when
-
-! Reassociation
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##add-imm f 2 0 100 }
-        T{ ##load-integer f 3 50 }
-        T{ ##add-imm f 4 0 150 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##add f 2 0 1 }
-        T{ ##load-integer f 3 50 }
-        T{ ##add f 4 2 3 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##add-imm f 2 0 100 }
-        T{ ##load-integer f 3 50 }
-        T{ ##add-imm f 4 0 150 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##add f 2 1 0 }
-        T{ ##load-integer f 3 50 }
-        T{ ##add f 4 3 2 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##add-imm f 2 0 100 }
-        T{ ##load-integer f 3 50 }
-        T{ ##add-imm f 4 0 50 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##add f 2 0 1 }
-        T{ ##load-integer f 3 50 }
-        T{ ##sub f 4 2 3 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##add-imm f 2 0 -100 }
-        T{ ##load-integer f 3 50 }
-        T{ ##add-imm f 4 0 -150 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##sub f 2 0 1 }
-        T{ ##load-integer f 3 50 }
-        T{ ##sub f 4 2 3 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##mul-imm f 2 0 100 }
-        T{ ##load-integer f 3 50 }
-        T{ ##mul-imm f 4 0 5000 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##mul f 2 0 1 }
-        T{ ##load-integer f 3 50 }
-        T{ ##mul f 4 2 3 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##mul-imm f 2 0 100 }
-        T{ ##load-integer f 3 50 }
-        T{ ##mul-imm f 4 0 5000 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##mul f 2 1 0 }
-        T{ ##load-integer f 3 50 }
-        T{ ##mul f 4 3 2 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##and-imm f 2 0 100 }
-        T{ ##load-integer f 3 50 }
-        T{ ##and-imm f 4 0 32 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##and f 2 0 1 }
-        T{ ##load-integer f 3 50 }
-        T{ ##and f 4 2 3 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##and-imm f 2 0 100 }
-        T{ ##load-integer f 3 50 }
-        T{ ##and-imm f 4 0 32 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##and f 2 1 0 }
-        T{ ##load-integer f 3 50 }
-        T{ ##and f 4 3 2 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##or-imm f 2 0 100 }
-        T{ ##load-integer f 3 50 }
-        T{ ##or-imm f 4 0 118 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##or f 2 0 1 }
-        T{ ##load-integer f 3 50 }
-        T{ ##or f 4 2 3 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##or-imm f 2 0 100 }
-        T{ ##load-integer f 3 50 }
-        T{ ##or-imm f 4 0 118 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##or f 2 1 0 }
-        T{ ##load-integer f 3 50 }
-        T{ ##or f 4 3 2 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##xor-imm f 2 0 100 }
-        T{ ##load-integer f 3 50 }
-        T{ ##xor-imm f 4 0 86 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##xor f 2 0 1 }
-        T{ ##load-integer f 3 50 }
-        T{ ##xor f 4 2 3 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##xor-imm f 2 0 100 }
-        T{ ##load-integer f 3 50 }
-        T{ ##xor-imm f 4 0 86 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 100 }
-        T{ ##xor f 2 1 0 }
-        T{ ##load-integer f 3 50 }
-        T{ ##xor f 4 3 2 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##shl-imm f 1 0 10 }
-        T{ ##shl-imm f 2 0 21 }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##shl-imm f 1 0 10 }
-        T{ ##shl-imm f 2 1 11 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##shl-imm f 1 0 10 }
-        T{ ##shl-imm f 2 1 $[ cell-bits 1 - ] }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##shl-imm f 1 0 10 }
-        T{ ##shl-imm f 2 1 $[ cell-bits 1 - ] }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##sar-imm f 1 0 10 }
-        T{ ##sar-imm f 2 0 21 }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##sar-imm f 1 0 10 }
-        T{ ##sar-imm f 2 1 11 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##sar-imm f 1 0 10 }
-        T{ ##sar-imm f 2 1 $[ cell-bits 1 - ] }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##sar-imm f 1 0 10 }
-        T{ ##sar-imm f 2 1 $[ cell-bits 1 - ] }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##shr-imm f 1 0 10 }
-        T{ ##shr-imm f 2 0 21 }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##shr-imm f 1 0 10 }
-        T{ ##shr-imm f 2 1 11 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##shr-imm f 1 0 10 }
-        T{ ##shr-imm f 2 1 $[ cell-bits 1 - ] }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##shr-imm f 1 0 10 }
-        T{ ##shr-imm f 2 1 $[ cell-bits 1 - ] }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##shr-imm f 1 0 10 }
-        T{ ##sar-imm f 2 1 11 }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##shr-imm f 1 0 10 }
-        T{ ##sar-imm f 2 1 11 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-! Distributive law
-2 \ vreg-counter set-global
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##add-imm f 1 0 10 }
-        T{ ##shl-imm f 3 0 2 }
-        T{ ##add-imm f 2 3 40 }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##add-imm f 1 0 10 }
-        T{ ##shl-imm f 2 1 2 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##add-imm f 1 0 10 }
-        T{ ##mul-imm f 4 0 3 }
-        T{ ##add-imm f 2 4 30 }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##add-imm f 1 0 10 }
-        T{ ##mul-imm f 2 1 3 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##add-imm f 1 0 -10 }
-        T{ ##shl-imm f 5 0 2 }
-        T{ ##add-imm f 2 5 -40 }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##sub-imm f 1 0 10 }
-        T{ ##shl-imm f 2 1 2 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##add-imm f 1 0 -10 }
-        T{ ##mul-imm f 6 0 3 }
-        T{ ##add-imm f 2 6 -30 }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##sub-imm f 1 0 10 }
-        T{ ##mul-imm f 2 1 3 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-! Simplification
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##copy f 3 0 any-rep }
-        T{ ##replace f 3 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##add-imm f 3 0 0 }
-        T{ ##replace f 3 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##copy f 3 0 any-rep }
-        T{ ##replace f 3 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##or-imm f 3 0 0 }
-        T{ ##replace f 3 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##copy f 3 0 any-rep }
-        T{ ##replace f 3 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##xor-imm f 3 0 0 }
-        T{ ##replace f 3 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##and-imm f 1 0 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##copy f 1 0 any-rep }
-        T{ ##replace f 1 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##and-imm f 1 0 -1 }
-        T{ ##replace f 1 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##copy f 1 0 any-rep }
-        T{ ##replace f 1 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##and f 1 0 0 }
-        T{ ##replace f 1 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##copy f 1 0 any-rep }
-        T{ ##replace f 1 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##or-imm f 1 0 0 }
-        T{ ##replace f 1 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 -1 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##or-imm f 1 0 -1 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##copy f 1 0 any-rep }
-        T{ ##replace f 1 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##or f 1 0 0 }
-        T{ ##replace f 1 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##copy f 1 0 any-rep }
-        T{ ##replace f 1 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##xor-imm f 1 0 0 }
-        T{ ##replace f 1 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##not f 1 0 }
-        T{ ##replace f 1 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##xor-imm f 1 0 -1 }
-        T{ ##replace f 1 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##xor f 1 0 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##copy f 2 0 any-rep }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##mul-imm f 2 0 1 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##copy f 2 0 any-rep }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##shl-imm f 2 0 0 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##copy f 2 0 any-rep }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##shr-imm f 2 0 0 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##copy f 2 0 any-rep }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##sar-imm f 2 0 0 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-! Constant folding
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 3 }
-        T{ ##load-integer f 3 4 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 3 }
-        T{ ##add f 3 1 2 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 3 }
-        T{ ##load-integer f 3 -2 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 3 }
-        T{ ##sub f 3 1 2 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 2 }
-        T{ ##load-integer f 2 3 }
-        T{ ##load-integer f 3 6 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 2 }
-        T{ ##load-integer f 2 3 }
-        T{ ##mul f 3 1 2 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 2 }
-        T{ ##load-integer f 2 1 }
-        T{ ##load-integer f 3 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 2 }
-        T{ ##load-integer f 2 1 }
-        T{ ##and f 3 1 2 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 2 }
-        T{ ##load-integer f 2 1 }
-        T{ ##load-integer f 3 3 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 2 }
-        T{ ##load-integer f 2 1 }
-        T{ ##or f 3 1 2 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 2 }
-        T{ ##load-integer f 2 3 }
-        T{ ##load-integer f 3 1 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 2 }
-        T{ ##load-integer f 2 3 }
-        T{ ##xor f 3 1 2 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 3 8 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 1 }
-        T{ ##shl-imm f 3 1 3 }
-    } value-numbering-step
-] unit-test
-
-cell 8 = [
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-integer f 1 -1 }
-            T{ ##load-integer f 3 HEX: ffffffffffff }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-integer f 1 -1 }
-            T{ ##shr-imm f 3 1 16 }
-        } value-numbering-step
-    ] unit-test
-] when
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 -8 }
-        T{ ##load-integer f 3 -4 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 -8 }
-        T{ ##sar-imm f 3 1 1 }
-    } value-numbering-step
-] unit-test
-
-cell 8 = [
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-integer f 1 65536 }
-            T{ ##load-integer f 2 140737488355328 }
-            T{ ##add f 3 0 2 }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-integer f 1 65536 }
-            T{ ##shl-imm f 2 1 31 }
-            T{ ##add f 3 0 2 }
-        } value-numbering-step
-    ] unit-test
-
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-integer f 2 140737488355328 }
-            T{ ##add f 3 0 2 }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-integer f 2 140737488355328 }
-            T{ ##add f 3 0 2 }
-        } value-numbering-step
-    ] unit-test
-
-    [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-integer f 2 2147483647 }
-            T{ ##add-imm f 3 0 2147483647 }
-            T{ ##add-imm f 4 3 2147483647 }
-        }
-    ] [
-        {
-            T{ ##peek f 0 D 0 }
-            T{ ##load-integer f 2 2147483647 }
-            T{ ##add f 3 0 2 }
-            T{ ##add f 4 3 2 }
-        } value-numbering-step
-    ] unit-test
-] when
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 -1 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 1 }
-        T{ ##neg f 2 1 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 -2 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 1 1 }
-        T{ ##not f 2 1 }
-    } value-numbering-step
-] unit-test
-
-! ##tagged>integer constant folding
-[
-    {
-        T{ ##load-reference f 1 f }
-        T{ ##load-integer f 2 $[ \ f type-number ] }
-        T{ ##copy f 3 2 any-rep }
-    }
-] [
-    {
-        T{ ##load-reference f 1 f }
-        T{ ##tagged>integer f 2 1 }
-        T{ ##and-imm f 3 2 15 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 100 }
-        T{ ##load-integer f 2 $[ 100 tag-fixnum ] }
-        T{ ##load-integer f 3 $[ 100 tag-fixnum 1 + ] }
-    }
-] [
-    {
-        T{ ##load-integer f 1 100 }
-        T{ ##tagged>integer f 2 1 }
-        T{ ##add-imm f 3 2 1 }
-    } value-numbering-step
-] unit-test
-
-! Alien boxing and unboxing
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##box-alien f 1 0 }
-        T{ ##copy f 2 0 any-rep }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##box-alien f 1 0 }
-        T{ ##unbox-alien f 2 1 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##box-alien f 1 0 }
-        T{ ##copy f 2 0 any-rep }
-        T{ ##replace f 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##box-alien f 1 0 }
-        T{ ##unbox-any-c-ptr f 2 1 }
-        T{ ##replace f 2 D 0 }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 2 0 }
-        T{ ##copy f 1 0 any-rep }
-        T{ ##replace f 1 D 0 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 2 0 }
-        T{ ##box-displaced-alien f 1 2 0 c-ptr }
-        T{ ##replace f 1 D 0 }
-    } value-numbering-step
-] unit-test
-
-3 vreg-counter set-global
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 2 16 }
-        T{ ##box-displaced-alien f 1 2 0 c-ptr }
-        T{ ##unbox-any-c-ptr f 4 0 }
-        T{ ##add-imm f 3 4 16 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 2 16 }
-        T{ ##box-displaced-alien f 1 2 0 c-ptr }
-        T{ ##unbox-any-c-ptr f 3 1 }
-    } value-numbering-step
-] unit-test
-
-4 vreg-counter set-global
-
-[
-    {
-        T{ ##box-alien f 0 1 }
-        T{ ##load-integer f 2 16 }
-        T{ ##box-displaced-alien f 3 2 0 c-ptr }
-        T{ ##copy f 5 1 any-rep }
-        T{ ##add-imm f 4 5 16 }
-    }
-] [
-    {
-        T{ ##box-alien f 0 1 }
-        T{ ##load-integer f 2 16 }
-        T{ ##box-displaced-alien f 3 2 0 c-ptr }
-        T{ ##unbox-any-c-ptr f 4 3 }
-    } value-numbering-step
-] unit-test
-
-3 vreg-counter set-global
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 2 0 }
-        T{ ##copy f 3 0 any-rep }
-        T{ ##replace f 3 D 1 }
-    }
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-integer f 2 0 }
-        T{ ##box-displaced-alien f 3 2 0 c-ptr }
-        T{ ##replace f 3 D 1 }
-    } value-numbering-step
-] unit-test
-
-! Various SIMD simplifications
-[
-    {
-        T{ ##vector>scalar f 1 0 float-4-rep }
-        T{ ##copy f 2 0 any-rep }
-    }
-] [
-    {
-        T{ ##vector>scalar f 1 0 float-4-rep }
-        T{ ##scalar>vector f 2 1 float-4-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##copy f 1 0 any-rep }
-    }
-] [
-    {
-        T{ ##shuffle-vector-imm f 1 0 { 0 1 2 3 } float-4-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##shuffle-vector-imm f 1 0 { 1 2 3 0 } float-4-rep }
-        T{ ##shuffle-vector-imm f 2 0 { 0 2 3 1 } float-4-rep }
-    }
-] [
-    {
-        T{ ##shuffle-vector-imm f 1 0 { 1 2 3 0 } float-4-rep }
-        T{ ##shuffle-vector-imm f 2 1 { 3 1 2 0 } float-4-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##shuffle-vector-imm f 1 0 { 1 2 3 0 } float-4-rep }
-        T{ ##shuffle-vector-imm f 2 1 { 1 0 } double-2-rep }
-    }
-] [
-    {
-        T{ ##shuffle-vector-imm f 1 0 { 1 2 3 0 } float-4-rep }
-        T{ ##shuffle-vector-imm f 2 1 { 1 0 } double-2-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 0 55 }
-        T{ ##load-reference f 1 B{ 55 0 0 0  55 0 0 0  55 0 0 0  55 0 0 0 } }
-        T{ ##load-reference f 2 B{ 55 0 0 0  55 0 0 0  55 0 0 0  55 0 0 0 } }
-    }
-] [
-    {
-        T{ ##load-integer f 0 55 }
-        T{ ##scalar>vector f 1 0 int-4-rep }
-        T{ ##shuffle-vector-imm f 2 1 { 0 0 0 0 } float-4-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-reference f 0 1.25 }
-        T{ ##load-reference f 1 B{ 0 0 160 63 0 0 160 63 0 0 160 63 0 0 160 63 } }
-        T{ ##load-reference f 2 B{ 0 0 160 63 0 0 160 63 0 0 160 63 0 0 160 63 } }
-    }
-] [
-    {
-        T{ ##load-reference f 0 1.25 }
-        T{ ##scalar>vector f 1 0 float-4-rep }
-        T{ ##shuffle-vector-imm f 2 1 { 0 0 0 0 } float-4-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-reference f 0 1.25 }
-        T{ ##load-reference f 1 B{ 0 0 160 63 0 0 160 63 0 0 160 63 0 0 160 63 } }
-        T{ ##load-reference f 2 B{ 0 0 160 63 0 0 160 63 0 0 160 63 0 0 160 63 } }
-    }
-] [
-    {
-        T{ ##load-reference f 0 1.25 }
-        T{ ##scalar>vector f 1 0 float-4-rep }
-        T{ ##shuffle-vector-imm f 2 1 { 0 0 0 0 } float-4-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 0 55 }
-        T{ ##load-reference f 1 B{ 55 0 55 0 55 0 55 0 55 0 55 0 55 0 55 0 } }
-        T{ ##load-reference f 2 B{ 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 } }
-        T{ ##load-reference f 3 B{ 0 55 0 55 0 55 0 55 0 55 0 55 0 55 0 55 } }
-    }
-] [
-    {
-        T{ ##load-integer f 0 55 }
-        T{ ##scalar>vector f 1 0 short-8-rep }
-        T{ ##load-reference f 2 B{ 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 } }
-        T{ ##shuffle-vector f 3 1 2 float-4-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-reference f 0 1.25 }
-        T{ ##load-reference f 2 3.75 }
-        T{ ##load-reference f 4 B{ 0 0 0 0 0 0 244 63 0 0 0 0 0 0 14 64 } }
-    }
-] [
-    {
-        T{ ##load-reference f 0 1.25 }
-        T{ ##load-reference f 2 3.75 }
-        T{ ##gather-vector-2 f 4 0 2 double-2-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 0 125 }
-        T{ ##load-integer f 2 375 }
-        T{ ##load-reference f 4 B{ 125 0 0 0 0 0 0 0 119 1 0 0 0 0 0 0 } }
-    }
-] [
-    {
-        T{ ##load-integer f 0 125 }
-        T{ ##load-integer f 2 375 }
-        T{ ##gather-vector-2 f 4 0 2 longlong-2-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-reference f 0 1.25 }
-        T{ ##load-reference f 1 2.50 }
-        T{ ##load-reference f 2 3.75 }
-        T{ ##load-reference f 3 5.00 }
-        T{ ##load-reference f 4 B{ 0 0 160 63 0 0 32 64 0 0 112 64 0 0 160 64 } }
-    }
-] [
-    {
-        T{ ##load-reference f 0 1.25 }
-        T{ ##load-reference f 1 2.50 }
-        T{ ##load-reference f 2 3.75 }
-        T{ ##load-reference f 3 5.00 }
-        T{ ##gather-vector-4 f 4 0 1 2 3 float-4-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 0 125 }
-        T{ ##load-integer f 1 250 }
-        T{ ##load-integer f 2 375 }
-        T{ ##load-integer f 3 500 }
-        T{ ##load-reference f 4 B{ 125 0 0 0 250 0 0 0 119 1 0 0 244 1 0 0 } }
-    }
-] [
-    {
-        T{ ##load-integer f 0 125 }
-        T{ ##load-integer f 1 250 }
-        T{ ##load-integer f 2 375 }
-        T{ ##load-integer f 3 500 }
-        T{ ##gather-vector-4 f 4 0 1 2 3 int-4-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##zero-vector f 2 float-4-rep }
-    }
-] [
-    {
-        T{ ##xor-vector f 2 1 1 float-4-rep }
-    } value-numbering-step
-] unit-test
-
-! NOT x AND y => x ANDN y
-
-[
-    {
-        T{ ##fill-vector f 3 float-4-rep }
-        T{ ##xor-vector  f 4 0 3 float-4-rep }
-        T{ ##andn-vector f 5 0 1 float-4-rep }
-    }
-] [
-    {
-        T{ ##fill-vector f 3 float-4-rep }
-        T{ ##xor-vector  f 4 0 3 float-4-rep }
-        T{ ##and-vector  f 5 4 1 float-4-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##not-vector  f 4 0 float-4-rep }
-        T{ ##andn-vector f 5 0 1 float-4-rep }
-    }
-] [
-    {
-        T{ ##not-vector  f 4 0 float-4-rep }
-        T{ ##and-vector  f 5 4 1 float-4-rep }
-    } value-numbering-step
-] unit-test
-
-! x AND NOT y => y ANDN x
-
-[
-    {
-        T{ ##fill-vector f 3 float-4-rep }
-        T{ ##xor-vector  f 4 0 3 float-4-rep }
-        T{ ##andn-vector f 5 0 1 float-4-rep }
-    }
-] [
-    {
-        T{ ##fill-vector f 3 float-4-rep }
-        T{ ##xor-vector  f 4 0 3 float-4-rep }
-        T{ ##and-vector  f 5 1 4 float-4-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##not-vector  f 4 0 float-4-rep }
-        T{ ##andn-vector f 5 0 1 float-4-rep }
-    }
-] [
-    {
-        T{ ##not-vector  f 4 0 float-4-rep }
-        T{ ##and-vector  f 5 1 4 float-4-rep }
-    } value-numbering-step
-] unit-test
-
-! NOT x ANDN y => x AND y
-
-[
-    {
-        T{ ##fill-vector f 3 float-4-rep }
-        T{ ##xor-vector  f 4 0 3 float-4-rep }
-        T{ ##and-vector  f 5 0 1 float-4-rep }
-    }
-] [
-    {
-        T{ ##fill-vector f 3 float-4-rep }
-        T{ ##xor-vector  f 4 0 3 float-4-rep }
-        T{ ##andn-vector f 5 4 1 float-4-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##not-vector  f 4 0 float-4-rep }
-        T{ ##and-vector  f 5 0 1 float-4-rep }
-    }
-] [
-    {
-        T{ ##not-vector  f 4 0 float-4-rep }
-        T{ ##andn-vector f 5 4 1 float-4-rep }
-    } value-numbering-step
-] unit-test
-
-! AND <=> ANDN
-
-[
-    {
-        T{ ##fill-vector f 3 float-4-rep }
-        T{ ##xor-vector  f 4 0 3 float-4-rep }
-        T{ ##andn-vector f 5 0 1 float-4-rep }
-        T{ ##and-vector  f 6 0 2 float-4-rep }
-        T{ ##or-vector   f 7 5 6 float-4-rep }
-    }
-] [
-    {
-        T{ ##fill-vector f 3 float-4-rep }
-        T{ ##xor-vector  f 4 0 3 float-4-rep }
-        T{ ##and-vector  f 5 4 1 float-4-rep }
-        T{ ##andn-vector f 6 4 2 float-4-rep }
-        T{ ##or-vector   f 7 5 6 float-4-rep }
-    } value-numbering-step
-] unit-test
-
-[
-    {
-        T{ ##not-vector  f 4 0   float-4-rep }
-        T{ ##andn-vector f 5 0 1 float-4-rep }
-        T{ ##and-vector  f 6 0 2 float-4-rep }
-        T{ ##or-vector   f 7 5 6 float-4-rep }
-    }
-] [
-    {
-        T{ ##not-vector  f 4 0   float-4-rep }
-        T{ ##and-vector  f 5 4 1 float-4-rep }
-        T{ ##andn-vector f 6 4 2 float-4-rep }
-        T{ ##or-vector   f 7 5 6 float-4-rep }
-    } value-numbering-step
-] unit-test
-
-! Branch folding
-: test-branch-folding ( insns -- insns' n )
-    <basic-block>
-    [ V{ 0 1 } clone >>successors basic-block set value-numbering-step ] keep
-    successors>> first ;
-
-[
-    {
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 2 }
-        T{ ##branch }
-    }
-    1
-] [
-    {
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 2 }
-        T{ ##compare-branch f 1 2 cc= }
-    } test-branch-folding
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 2 }
-        T{ ##branch }
-    }
-    0
-] [
-    {
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 2 }
-        T{ ##compare-branch f 1 2 cc/= }
-    } test-branch-folding
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 2 }
-        T{ ##branch }
-    }
-    0
-] [
-    {
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 2 }
-        T{ ##compare-integer-branch f 1 2 cc< }
-    } test-branch-folding
-] unit-test
-
-[
-    {
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 2 }
-        T{ ##branch }
-    }
-    1
-] [
-    {
-        T{ ##load-integer f 1 1 }
-        T{ ##load-integer f 2 2 }
-        T{ ##compare-integer-branch f 2 1 cc< }
-    } test-branch-folding
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##branch }
-    }
-    1
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare-integer-branch f 0 0 cc< }
-    } test-branch-folding
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##branch }
-    }
-    0
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare-integer-branch f 0 0 cc<= }
-    } test-branch-folding
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##branch }
-    }
-    1
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare-integer-branch f 0 0 cc> }
-    } test-branch-folding
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##branch }
-    }
-    0
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare-integer-branch f 0 0 cc>= }
-    } test-branch-folding
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##branch }
-    }
-    0
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare-integer-branch f 0 0 cc= }
-    } test-branch-folding
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##branch }
-    }
-    1
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare-integer-branch f 0 0 cc/= }
-    } test-branch-folding
-] unit-test
-
-[
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##load-reference f 1 t }
-        T{ ##branch }
-    }
-    0
-] [
-    {
-        T{ ##peek f 0 D 0 }
-        T{ ##compare f 1 0 0 cc<= }
-        T{ ##compare-imm-branch f 1 f cc/= }
-    } test-branch-folding
-] unit-test
-
-! More branch folding tests
-V{ T{ ##branch } } 0 test-bb
-
-V{
-    T{ ##peek f 0 D 0 }
-    T{ ##compare-integer-branch f 0 0 cc< }
-} 1 test-bb
-
-V{
-    T{ ##load-integer f 1 1 }
-    T{ ##branch }
-} 2 test-bb
-
-V{
-    T{ ##load-integer f 2 2 }
-    T{ ##branch }
-} 3 test-bb
-
-V{
-    T{ ##phi f 3 H{ { 2 1 } { 3 2 } } }
-    T{ ##replace f 3 D 0 }
-    T{ ##return }
-} 4 test-bb
-
-test-diamond
-
-[ ] [
-    cfg new 0 get >>entry dup cfg set
-    value-numbering
-    select-representations
-    destruct-ssa drop
-] unit-test
-
-[ 1 ] [ 1 get successors>> length ] unit-test
-
-[ t ] [ 1 get successors>> first 3 get eq? ] unit-test
-
-[ 2 ] [ 4 get instructions>> length ] unit-test
-
-V{
-    T{ ##peek f 0 D 0 }
-    T{ ##branch }
-} 0 test-bb
-
-V{
-    T{ ##peek f 1 D 1 }
-    T{ ##compare-integer-branch f 1 1 cc< }
-} 1 test-bb
-
-V{
-    T{ ##copy f 2 0 any-rep }
-    T{ ##branch }
-} 2 test-bb
-
-V{
-    T{ ##phi f 3 H{ { 1 1 } { 2 0 } } }
-    T{ ##branch }
-} 3 test-bb
-
-V{
-    T{ ##replace f 3 D 0 }
-    T{ ##return }
-} 4 test-bb
-
-test-diamond
-
-[ ] [
-    cfg new 0 get >>entry
-    value-numbering
-    eliminate-dead-code
-    drop
-] unit-test
-
-[ t ] [ 1 get successors>> first 3 get eq? ] unit-test
-
-[ 1 ] [ 3 get instructions>> first inputs>> assoc-size ] unit-test
-
-V{ T{ ##prologue } T{ ##branch } } 0 test-bb
-
-V{
-    T{ ##peek { dst 15 } { loc D 0 } }
-    T{ ##copy { dst 16 } { src 15 } { rep any-rep } }
-    T{ ##copy { dst 17 } { src 15 } { rep any-rep } }
-    T{ ##copy { dst 18 } { src 15 } { rep any-rep } }
-    T{ ##copy { dst 19 } { src 15 } { rep any-rep } }
-    T{ ##compare
-        { dst 20 }
-        { src1 18 }
-        { src2 19 }
-        { cc cc= }
-        { temp 22 }
-    }
-    T{ ##copy { dst 21 } { src 20 } { rep any-rep } }
-    T{ ##compare-imm-branch
-        { src1 21 }
-        { src2 f }
-        { cc cc/= }
-    }
-} 1 test-bb
-
-V{
-    T{ ##copy { dst 23 } { src 15 } { rep any-rep } }
-    T{ ##copy { dst 24 } { src 15 } { rep any-rep } }
-    T{ ##load-reference { dst 25 } { obj t } }
-    T{ ##branch }
-} 2 test-bb
-
-V{
-    T{ ##replace { src 25 } { loc D 0 } }
-    T{ ##epilogue }
-    T{ ##return }
-} 3 test-bb
-
-V{
-    T{ ##copy { dst 26 } { src 15 } { rep any-rep } }
-    T{ ##copy { dst 27 } { src 15 } { rep any-rep } }
-    T{ ##add
-        { dst 28 }
-        { src1 26 }
-        { src2 27 }
-    }
-    T{ ##branch }
-} 4 test-bb
-
-V{
-    T{ ##replace { src 28 } { loc D 0 } }
-    T{ ##epilogue }
-    T{ ##return }
-} 5 test-bb
-
-0 1 edge
-1 { 2 4 } edges
-2 3 edge
-4 5 edge
-
-[ ] [
-    cfg new 0 get >>entry
-    value-numbering eliminate-dead-code drop
-] unit-test
-
-[ f ] [ 1 get instructions>> [ ##peek? ] any? ] unit-test
-
-! Slot addressing optimization
-cpu x86? [
-    [
-        V{
-            T{ ##peek f 0 D 0 }
-            T{ ##peek f 1 D 1 }
-            T{ ##add-imm f 2 1 2 }
-            T{ ##slot f 3 0 1 $[ cell log2 ] $[ 7 2 cells - ] }
-        }
-    ] [
-        V{
-            T{ ##peek f 0 D 0 }
-            T{ ##peek f 1 D 1 }
-            T{ ##add-imm f 2 1 2 }
-            T{ ##slot f 3 0 2 $[ cell log2 ] 7 }
-        } value-numbering-step
-    ] unit-test
-] when
-
-! Alien addressing optimization
-
-! Base offset fusion on ##load/store-memory-imm
-[
-    V{
-        T{ ##peek f 1 D 0 }
-        T{ ##tagged>integer f 2 1 }
-        T{ ##add-imm f 3 2 10 }
-        T{ ##load-memory-imm f 4 2 10 int-rep c:uchar }
-    }
-] [
-    V{
-        T{ ##peek f 1 D 0 }
-        T{ ##tagged>integer f 2 1 }
-        T{ ##add-imm f 3 2 10 }
-        T{ ##load-memory-imm f 4 3 0 int-rep c:uchar }
-    } value-numbering-step
-] unit-test
-
-[
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##add-imm f 4 3 10 }
-        T{ ##store-memory-imm f 2 3 10 int-rep c:uchar }
-    }
-] [
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##add-imm f 4 3 10 }
-        T{ ##store-memory-imm f 2 4 0 int-rep c:uchar }
-    } value-numbering-step
-] unit-test
-
-! Displacement fusion on ##load/store-memory-imm
-[
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##add f 4 2 3 }
-        T{ ##load-memory f 5 2 3 0 0 int-rep c:uchar }
-    }
-] [
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##add f 4 2 3 }
-        T{ ##load-memory-imm f 5 4 0 int-rep c:uchar }
-    } value-numbering-step
-] unit-test
-
-[
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##add f 4 2 3 }
-        T{ ##store-memory f 5 2 3 0 0 int-rep c:uchar }
-    }
-] [
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##add f 4 2 3 }
-        T{ ##store-memory-imm f 5 4 0 int-rep c:uchar }
-    } value-numbering-step
-] unit-test
-
-! Base offset fusion on ##load/store-memory -- only on x86
-cpu x86?
-[
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##add-imm f 4 2 31337 }
-        T{ ##load-memory f 5 2 3 0 31337 int-rep c:uchar }
-    }
-]
-[
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##add-imm f 4 2 31337 }
-        T{ ##load-memory f 5 4 3 0 0 int-rep c:uchar }
-    }
-] ?
-[
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##add-imm f 4 2 31337 }
-        T{ ##load-memory f 5 4 3 0 0 int-rep c:uchar }
-    } value-numbering-step
-] unit-test
-
-! Displacement offset fusion on ##load/store-memory -- only on x86
-cpu x86?
-[
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##add-imm f 4 3 31337 }
-        T{ ##load-memory f 5 2 3 0 31338 int-rep c:uchar }
-    }
-]
-[
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##add-imm f 4 3 31337 }
-        T{ ##load-memory f 5 2 4 0 1 int-rep c:uchar }
-    }
-] ?
-[
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##add-imm f 4 3 31337 }
-        T{ ##load-memory f 5 2 4 0 1 int-rep c:uchar }
-    } value-numbering-step
-] unit-test
-
-! Displacement offset fusion should not occur on
-! ##load/store-memory with non-zero scale
-[ ] [
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##add-imm f 4 3 10 }
-        T{ ##load-memory f 5 2 4 1 1 int-rep c:uchar }
-    } dup value-numbering-step assert=
-] unit-test
-
-! Scale fusion on ##load/store-memory
-cpu x86?
-[
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##shl-imm f 4 3 2 }
-        T{ ##load-memory f 5 2 3 2 0 int-rep c:uchar }
-    }
-]
-[
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##shl-imm f 4 3 2 }
-        T{ ##load-memory f 5 2 4 0 0 int-rep c:uchar }
-    }
-] ?
-[
-    V{
-        T{ ##peek f 0 D 0 }
-        T{ ##peek f 1 D 1 }
-        T{ ##tagged>integer f 2 0 }
-        T{ ##tagged>integer f 3 1 }
-        T{ ##shl-imm f 4 3 2 }
-        T{ ##load-memory f 5 2 4 0 0 int-rep c:uchar }
-    } value-numbering-step
-] unit-test
-
-cpu x86? [
-    ! Don't do scale fusion if there's already a scale
-    [ ] [
-        V{
-            T{ ##peek f 0 D 0 }
-            T{ ##peek f 1 D 1 }
-            T{ ##tagged>integer f 2 0 }
-            T{ ##tagged>integer f 3 1 }
-            T{ ##shl-imm f 4 3 2 }
-            T{ ##load-memory f 5 2 4 1 0 int-rep c:uchar }
-        } dup value-numbering-step assert=
-    ] unit-test
-
-    ! Don't do scale fusion if the scale factor is out of range
-    [ ] [
-        V{
-            T{ ##peek f 0 D 0 }
-            T{ ##peek f 1 D 1 }
-            T{ ##tagged>integer f 2 0 }
-            T{ ##tagged>integer f 3 1 }
-            T{ ##shl-imm f 4 3 4 }
-            T{ ##load-memory f 5 2 4 0 0 int-rep c:uchar }
-        } dup value-numbering-step assert=
-    ] unit-test
-] when
diff --git a/basis/compiler/cfg/gvn/gvn.factor b/basis/compiler/cfg/gvn/gvn.factor
deleted file mode 100644 (file)
index aca40f5..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-! Copyright (C) 2008, 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: namespaces arrays assocs kernel accessors fry grouping
-sorting sets sequences locals
-cpu.architecture
-sequences.deep
-compiler.cfg
-compiler.cfg.rpo
-compiler.cfg.def-use
-compiler.cfg.utilities
-compiler.cfg.instructions
-compiler.cfg.gvn.alien
-compiler.cfg.gvn.comparisons
-compiler.cfg.gvn.graph
-compiler.cfg.gvn.math
-compiler.cfg.gvn.rewrite
-compiler.cfg.gvn.slots
-compiler.cfg.gvn.misc
-compiler.cfg.gvn.expressions ;
-IN: compiler.cfg.gvn
-
-GENERIC: process-instruction ( insn -- insn' )
-
-: redundant-instruction ( insn vn -- insn' )
-    [ dst>> ] dip [ swap set-vn ] [ <copy> ] 2bi ;
-
-:: useful-instruction ( insn expr -- insn' )
-    insn dst>> :> vn
-    vn vn set-vn
-    vn expr exprs>vns get set-at
-    insn vn vns>insns get set-at
-    insn ;
-
-: check-redundancy ( insn -- insn' )
-    dup >expr dup exprs>vns get at
-    [ redundant-instruction ] [ useful-instruction ] ?if ;
-
-M: insn process-instruction
-    dup rewrite [ process-instruction ] [ ] ?if ;
-
-M: foldable-insn process-instruction
-    dup rewrite
-    [ process-instruction ]
-    [ dup defs-vregs length 1 = [ check-redundancy ] when ] ?if ;
-
-M: ##copy process-instruction
-    dup [ src>> vreg>vn ] [ dst>> ] bi set-vn ;
-
-M: ##phi rewrite
-    [ dst>> ] [ inputs>> values [ vreg>vn ] map ] bi
-    dup sift
-    dup all-equal?  [
-        nip
-        [ drop f ]
-        [ first <copy> ] if-empty
-    ] [ 3drop f ] if ;
-
-M: ##phi process-instruction
-    dup rewrite
-    [ process-instruction ] [ check-redundancy ] ?if ;
-
-M: ##phi >expr
-    inputs>> values [ vreg>vn ] map \ ##phi prefix ;
-
-M: array process-instruction
-    [ process-instruction ] map ;
-
-: value-numbering-step ( insns -- insns' )
-    init-value-graph
-    ! [ process-instruction ] map flatten ;
-
-    ! idea: let rewrite do the constant/copy propagation (as
-    ! that eventually leads to better VNs), but don't actually
-    ! use them here, since changing the CFG mid-optimistic-GVN
-    ! won't be sound
-    dup [ process-instruction drop ] each ;
-
-: value-numbering ( cfg -- cfg )
-    dup
-    init-gvn
-    '[
-        changed? off
-        _ [ value-numbering-step ] simple-optimization
-        changed? get
-    ] loop
-
-    dup [ init-value-graph [ process-instruction ] map flatten ] simple-optimization
-    cfg-changed predecessors-changed ;
-
-USING: io math math.private prettyprint tools.annotations
-compiler.cfg.debugger
-compiler.cfg.graphviz
-compiler.cfg.tco
-compiler.cfg.useless-conditionals
-compiler.cfg.branch-splitting
-compiler.cfg.block-joining
-compiler.cfg.height
-compiler.cfg.ssa.construction
-compiler.cfg.alias-analysis
-compiler.cfg.copy-prop
-compiler.cfg.dce
-compiler.cfg.finalization ;
-
-SYMBOL: gvn-test
-
-[ 0 100 [ 1 fixnum+fast ] times ]
-test-builder first [
-    optimize-tail-calls
-    delete-useless-conditionals
-    split-branches
-    join-blocks
-    normalize-height
-    construct-ssa
-    alias-analysis
-] with-cfg gvn-test set-global
-
-: watch-gvn ( -- )
-    \ value-numbering-step
-    [
-        '[
-            _ call
-            "Basic block #" write basic-block get number>> .
-            "vregs>gvns: "  write vregs>gvns  get .
-            "vregs>vns: "   write vregs>vns   get .
-            "exprs>vns: "   write exprs>vns   get .
-            "vns>insns: "   write vns>insns   get .
-            "\n---\n" print
-        ]
-    ] annotate ;
-
-: reset-gvn ( -- )
-    \ value-numbering-step reset ;
-
-: test-gvn ( -- )
-    watch-gvn
-    gvn-test get-global [
-        dup "Before GVN" "1" (cfgviz)
-        value-numbering
-        dup "After GVN" "2" (cfgviz)
-        copy-propagation
-        dup "After CP" "3" (cfgviz)
-        eliminate-dead-code
-        dup "After DCE" "4" (cfgviz)
-        finalize-cfg
-        dup "Final CFG" "5" (cfgviz)
-        drop
-    ] with-cfg
-    reset-gvn ;
-
diff --git a/basis/compiler/cfg/gvn/math/authors.txt b/basis/compiler/cfg/gvn/math/authors.txt
deleted file mode 100644 (file)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/basis/compiler/cfg/gvn/math/math.factor b/basis/compiler/cfg/gvn/math/math.factor
deleted file mode 100644 (file)
index 63993a8..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-! Copyright (C) 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors combinators combinators.short-circuit
-cpu.architecture fry kernel layouts locals make math sequences
-compiler.cfg.instructions
-compiler.cfg.registers
-compiler.cfg.utilities
-compiler.cfg.gvn.folding
-compiler.cfg.gvn.graph
-compiler.cfg.gvn.rewrite ;
-IN: compiler.cfg.gvn.math
-
-: f-insn? ( insn -- ? )
-    { [ ##load-reference? ] [ obj>> not ] } 1&& ; inline
-
-: zero-insn? ( insn -- ? )
-    { [ ##load-integer? ] [ val>> 0 = ] } 1&& ; inline
-
-M: ##tagged>integer rewrite
-    [ dst>> ] [ src>> vreg>insn ] bi {
-        { [ dup ##load-integer? ] [ val>> tag-fixnum \ ##load-integer new-insn ] }
-        { [ dup f-insn? ] [ drop \ f type-number \ ##load-integer new-insn ] }
-        [ 2drop f ]
-    } cond ;
-
-: self-inverse ( insn -- insn' )
-    [ dst>> ] [ src>> vreg>insn src>> ] bi <copy> ;
-
-: identity ( insn -- insn' )
-    [ dst>> ] [ src1>> ] bi <copy> ;
-
-M: ##neg rewrite
-    {
-        { [ dup src>> vreg>insn ##neg? ] [ self-inverse ] }
-        { [ dup unary-constant-fold? ] [ unary-constant-fold ] }
-        [ drop f ]
-    } cond ;
-
-M: ##not rewrite
-    {
-        { [ dup src>> vreg>insn ##not? ] [ self-inverse ] }
-        { [ dup unary-constant-fold? ] [ unary-constant-fold ] }
-        [ drop f ]
-    } cond ;
-
-! Reassociation converts
-! ## *-imm 2 1 X
-! ## *-imm 3 2 Y
-! into
-! ## *-imm 3 1 (X $ Y)
-! If * is associative, then $ is the same operation as *.
-! In the case of shifts, $ is addition.
-: (reassociate) ( insn -- dst src1 src2' src2'' )
-    {
-        [ dst>> ]
-        [ src1>> vreg>insn [ src1>> ] [ src2>> ] bi ]
-        [ src2>> ]
-    } cleave ; inline
-
-: reassociate ( insn -- dst src1 src2 )
-    [ (reassociate) ] keep binary-constant-fold* ;
-
-: ?new-insn ( dst src1 src2 ? class -- insn/f )
-    '[ _ new-insn ] [ 3drop f ] if ; inline
-
-: reassociate-arithmetic ( insn new-insn -- insn/f )
-    [ reassociate dup immediate-arithmetic? ] dip ?new-insn ; inline
-
-: reassociate-bitwise ( insn new-insn -- insn/f )
-    [ reassociate dup immediate-bitwise? ] dip ?new-insn ; inline
-
-: reassociate-shift ( insn new-insn -- insn/f )
-    [ (reassociate) + dup immediate-shift-count? ] dip ?new-insn ; inline
-
-M: ##add-imm rewrite
-    {
-        { [ dup src2>> 0 = ] [ identity ] }
-        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
-        { [ dup src1>> vreg>insn ##add-imm? ] [ \ ##add-imm reassociate-arithmetic ] }
-        [ drop f ]
-    } cond ;
-
-: sub-imm>add-imm ( insn -- insn' )
-    [ dst>> ] [ src1>> ] [ src2>> neg ] tri
-    dup immediate-arithmetic?
-    \ ##add-imm ?new-insn ;
-
-M: ##sub-imm rewrite sub-imm>add-imm ;
-
-! Convert ##mul-imm -1 => ##neg
-: mul-to-neg? ( insn -- ? )
-    src2>> -1 = ;
-
-: mul-to-neg ( insn -- insn' )
-    [ dst>> ] [ src1>> ] bi \ ##neg new-insn ;
-
-! Convert ##mul-imm 2^X => ##shl-imm X
-: mul-to-shl? ( insn -- ? )
-    src2>> power-of-2? ;
-
-: mul-to-shl ( insn -- insn' )
-    [ [ dst>> ] [ src1>> ] bi ] [ src2>> log2 ] bi \ ##shl-imm new-insn ;
-
-! Distribution converts
-! ##+-imm 2 1 X
-! ##*-imm 3 2 Y
-! Into
-! ##*-imm 4 1 Y
-! ##+-imm 3 4 X*Y
-! Where * is mul or shl, + is add or sub
-! Have to make sure that X*Y fits in an immediate
-:: (distribute) ( outer inner imm temp add-op mul-op -- new-outers/f )
-    imm immediate-arithmetic? [
-        [
-            temp inner src1>> outer src2>> mul-op execute
-            outer dst>> temp imm add-op execute
-        ] { } make
-    ] [ f ] if ; inline
-
-: distribute-over-add? ( insn -- ? )
-    src1>> vreg>insn ##add-imm? ;
-
-: distribute-over-sub? ( insn -- ? )
-    src1>> vreg>insn ##sub-imm? ;
-
-: distribute ( insn add-op mul-op -- new-insns/f )
-    [
-        dup src1>> vreg>insn
-        2dup src2>> swap [ src2>> ] keep binary-constant-fold*
-        next-vreg
-    ] 2dip (distribute) ; inline
-
-M: ##mul-imm rewrite
-    {
-        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
-        { [ dup mul-to-neg? ] [ mul-to-neg ] }
-        { [ dup mul-to-shl? ] [ mul-to-shl ] }
-        { [ dup src1>> vreg>insn ##mul-imm? ] [ \ ##mul-imm reassociate-arithmetic ] }
-        { [ dup distribute-over-add? ] [ \ ##add-imm \ ##mul-imm distribute ] }
-        { [ dup distribute-over-sub? ] [ \ ##sub-imm \ ##mul-imm distribute ] }
-        [ drop f ]
-    } cond ;
-
-M: ##and-imm rewrite
-    {
-        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
-        { [ dup src1>> vreg>insn ##and-imm? ] [ \ ##and-imm reassociate-bitwise ] }
-        { [ dup src2>> 0 = ] [ dst>> 0 \ ##load-integer new-insn ] }
-        { [ dup src2>> -1 = ] [ identity ] }
-        [ drop f ]
-    } cond ;
-
-M: ##or-imm rewrite
-    {
-        { [ dup src2>> 0 = ] [ identity ] }
-        { [ dup src2>> -1 = ] [ dst>> -1 \ ##load-integer new-insn ] }
-        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
-        { [ dup src1>> vreg>insn ##or-imm? ] [ \ ##or-imm reassociate-bitwise ] }
-        [ drop f ]
-    } cond ;
-
-M: ##xor-imm rewrite
-    {
-        { [ dup src2>> 0 = ] [ identity ] }
-        { [ dup src2>> -1 = ] [ [ dst>> ] [ src1>> ] bi \ ##not new-insn ] }
-        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
-        { [ dup src1>> vreg>insn ##xor-imm? ] [ \ ##xor-imm reassociate-bitwise ] }
-        [ drop f ]
-    } cond ;
-
-M: ##shl-imm rewrite
-    {
-        { [ dup src2>> 0 = ] [ identity ] }
-        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
-        { [ dup src1>> vreg>insn ##shl-imm? ] [ \ ##shl-imm reassociate-shift ] }
-        { [ dup distribute-over-add? ] [ \ ##add-imm \ ##shl-imm distribute ] }
-        { [ dup distribute-over-sub? ] [ \ ##sub-imm \ ##shl-imm distribute ] }
-        [ drop f ]
-    } cond ;
-
-M: ##shr-imm rewrite
-    {
-        { [ dup src2>> 0 = ] [ identity ] }
-        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
-        { [ dup src1>> vreg>insn ##shr-imm? ] [ \ ##shr-imm reassociate-shift ] }
-        [ drop f ]
-    } cond ;
-
-M: ##sar-imm rewrite
-    {
-        { [ dup src2>> 0 = ] [ identity ] }
-        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
-        { [ dup src1>> vreg>insn ##sar-imm? ] [ \ ##sar-imm reassociate-shift ] }
-        [ drop f ]
-    } cond ;
-
-! Convert
-! ##load-integer 2 X
-! ##* 3 1 2
-! Where * is an operation with an -imm equivalent into
-! ##*-imm 3 1 X
-: insn>imm-insn ( insn op swap? -- new-insn )
-    swap [
-        [ [ dst>> ] [ src1>> ] [ src2>> ] tri ] dip
-        [ swap ] when vreg>integer
-    ] dip new-insn ; inline
-
-M: ##add rewrite
-    {
-        { [ dup src2>> vreg-immediate-arithmetic? ] [ \ ##add-imm f insn>imm-insn ] }
-        { [ dup src1>> vreg-immediate-arithmetic? ] [ \ ##add-imm t insn>imm-insn ] }
-        [ drop f ]
-    } cond ;
-
-: diagonal? ( insn -- ? )
-    [ src1>> vreg>vn ] [ src2>> vreg>vn ] bi = ; inline
-
-! ##sub 2 1 1 => ##load-integer 2 0
-: rewrite-subtraction-identity ( insn -- insn' )
-    dst>> 0 \ ##load-integer new-insn ;
-
-! ##load-integer 1 0
-! ##sub 3 1 2
-! =>
-! ##neg 3 2
-: sub-to-neg? ( ##sub -- ? )
-    src1>> vreg>insn zero-insn? ;
-
-: sub-to-neg ( ##sub -- insn )
-    [ dst>> ] [ src2>> ] bi \ ##neg new-insn ;
-
-M: ##sub rewrite
-    {
-        { [ dup sub-to-neg? ] [ sub-to-neg ] }
-        { [ dup diagonal? ] [ rewrite-subtraction-identity ] }
-        { [ dup src2>> vreg-immediate-arithmetic? ] [ \ ##sub-imm f insn>imm-insn ] }
-        [ drop f ]
-    } cond ;
-
-M: ##mul rewrite
-    {
-        { [ dup src2>> vreg-immediate-arithmetic? ] [ \ ##mul-imm f insn>imm-insn ] }
-        { [ dup src1>> vreg-immediate-arithmetic? ] [ \ ##mul-imm t insn>imm-insn ] }
-        [ drop f ]
-    } cond ;
-
-M: ##and rewrite
-    {
-        { [ dup diagonal? ] [ identity ] }
-        { [ dup src2>> vreg-immediate-bitwise? ] [ \ ##and-imm f insn>imm-insn ] }
-        { [ dup src1>> vreg-immediate-bitwise? ] [ \ ##and-imm t insn>imm-insn ] }
-        [ drop f ]
-    } cond ;
-
-M: ##or rewrite
-    {
-        { [ dup diagonal? ] [ identity ] }
-        { [ dup src2>> vreg-immediate-bitwise? ] [ \ ##or-imm f insn>imm-insn ] }
-        { [ dup src1>> vreg-immediate-bitwise? ] [ \ ##or-imm t insn>imm-insn ] }
-        [ drop f ]
-    } cond ;
-
-M: ##xor rewrite
-    {
-        { [ dup diagonal? ] [ dst>> 0 \ ##load-integer new-insn ] }
-        { [ dup src2>> vreg-immediate-bitwise? ] [ \ ##xor-imm f insn>imm-insn ] }
-        { [ dup src1>> vreg-immediate-bitwise? ] [ \ ##xor-imm t insn>imm-insn ] }
-        [ drop f ]
-    } cond ;
-
-M: ##shl rewrite
-    {
-        { [ dup src2>> vreg-immediate-bitwise? ] [ \ ##shl-imm f insn>imm-insn ] }
-        [ drop f ]
-    } cond ;
-
-M: ##shr rewrite
-    {
-        { [ dup src2>> vreg-immediate-bitwise? ] [ \ ##shr-imm f insn>imm-insn ] }
-        [ drop f ]
-    } cond ;
-
-M: ##sar rewrite
-    {
-        { [ dup src2>> vreg-immediate-bitwise? ] [ \ ##sar-imm f insn>imm-insn ] }
-        [ drop f ]
-    } cond ;
diff --git a/basis/compiler/cfg/gvn/misc/authors.txt b/basis/compiler/cfg/gvn/misc/authors.txt
deleted file mode 100644 (file)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/basis/compiler/cfg/gvn/misc/misc.factor b/basis/compiler/cfg/gvn/misc/misc.factor
deleted file mode 100644 (file)
index 970c39b..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-! Copyright (C) 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors cpu.architecture kernel
-compiler.cfg.instructions
-compiler.cfg.gvn.graph
-compiler.cfg.gvn.rewrite ;
-IN: compiler.cfg.gvn.misc
-
-M: ##replace rewrite
-    [ loc>> ] [ src>> vreg>insn ] bi
-    dup literal-insn? [
-        insn>literal dup immediate-store?
-        [ swap \ ##replace-imm new-insn ] [ 2drop f ] if
-    ] [ 2drop f ] if ;
diff --git a/basis/compiler/cfg/gvn/rewrite/rewrite.factor b/basis/compiler/cfg/gvn/rewrite/rewrite.factor
deleted file mode 100644 (file)
index dbbfe86..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-! Copyright (C) 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors combinators combinators.short-circuit kernel
-layouts math cpu.architecture
-compiler.cfg.instructions
-compiler.cfg.gvn.graph ;
-IN: compiler.cfg.gvn.rewrite
-
-! Outputs f to mean no change
-GENERIC: rewrite ( insn -- insn/f )
-
-M: insn rewrite drop f ;
-
-! Utilities
-GENERIC: insn>integer ( insn -- n )
-
-M: ##load-integer insn>integer val>> ;
-
-: vreg>integer ( vreg -- n ) vreg>insn insn>integer ; inline
-
-: vreg-immediate-arithmetic? ( vreg -- ? )
-    vreg>insn {
-        [ ##load-integer? ]
-        [ val>> immediate-arithmetic? ]
-    } 1&& ;
-
-: vreg-immediate-bitwise? ( vreg -- ? )
-    vreg>insn {
-        [ ##load-integer? ]
-        [ val>> immediate-bitwise? ]
-    } 1&& ;
-
-UNION: literal-insn ##load-integer ##load-reference ;
-
-GENERIC: insn>literal ( insn -- n )
-
-M: ##load-integer insn>literal val>> >fixnum ;
-
-M: ##load-reference insn>literal obj>> ;
-
-: vreg>literal ( vreg -- n ) vreg>insn insn>literal ; inline
-
-: vreg-immediate-comparand? ( vreg -- ? )
-    vreg>insn {
-        { [ dup ##load-integer? ] [ val>> tag-fixnum immediate-comparand? ] }
-        { [ dup ##load-reference? ] [ obj>> immediate-comparand? ] }
-        [ drop f ]
-    } cond ;
diff --git a/basis/compiler/cfg/gvn/rewrite/summary.txt b/basis/compiler/cfg/gvn/rewrite/summary.txt
deleted file mode 100644 (file)
index 8b13789..0000000
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/basis/compiler/cfg/gvn/simd/simd.factor b/basis/compiler/cfg/gvn/simd/simd.factor
deleted file mode 100644 (file)
index 14fd574..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-! Copyright (C) 2008, 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors combinators combinators.short-circuit arrays
-fry kernel layouts math namespaces sequences cpu.architecture
-math.bitwise math.order classes generalizations
-combinators.smart locals make alien.c-types io.binary grouping
-math.vectors.simd.intrinsics
-compiler.cfg
-compiler.cfg.registers
-compiler.cfg.utilities
-compiler.cfg.comparisons
-compiler.cfg.instructions
-compiler.cfg.gvn.math
-compiler.cfg.gvn.graph
-compiler.cfg.gvn.rewrite ;
-IN: compiler.cfg.gvn.simd
-
-! Some lame constant folding for SIMD intrinsics. Eventually this
-! should be redone completely.
-
-: useless-shuffle-vector-imm? ( insn -- ? )
-    [ shuffle>> ] [ rep>> rep-length iota ] bi sequence= ;
-
-: compose-shuffle-vector-imm ( outer inner -- insn' )
-    2dup [ rep>> ] bi@ eq? [
-        [ [ dst>> ] [ src>> ] bi* ]
-        [ [ shuffle>> ] bi@ nths ]
-        [ drop rep>> ]
-        2tri \ ##shuffle-vector-imm new-insn
-    ] [ 2drop f ] if ;
-
-: (fold-shuffle-vector-imm) ( shuffle bytes -- bytes' )
-    2dup length swap length /i group nths concat ;
-
-: fold-shuffle-vector-imm ( outer inner -- insn' )
-    [ [ dst>> ] [ shuffle>> ] bi ] [ obj>> ] bi*
-    (fold-shuffle-vector-imm) \ ##load-reference new-insn ;
-
-M: ##shuffle-vector-imm rewrite
-    dup src>> vreg>insn {
-        { [ over useless-shuffle-vector-imm? ] [ drop [ dst>> ] [ src>> ] bi <copy> ] }
-        { [ dup ##shuffle-vector-imm? ] [ compose-shuffle-vector-imm ] }
-        { [ dup ##load-reference? ] [ fold-shuffle-vector-imm ] }
-        [ 2drop f ]
-    } cond ;
-
-: scalar-value ( literal-insn rep -- byte-array )
-    {
-        { float-4-rep [ obj>> float>bits 4 >le ] }
-        { double-2-rep [ obj>> double>bits 8 >le ] }
-        [ [ val>> ] [ rep-component-type heap-size ] bi* >le ]
-    } case ;
-
-: (fold-scalar>vector) ( insn bytes -- insn' )
-    [ [ dst>> ] [ rep>> rep-length ] bi ] dip <repetition> concat
-    \ ##load-reference new-insn ;
-
-: fold-scalar>vector ( outer inner -- insn' )
-    over rep>> scalar-value (fold-scalar>vector) ;
-
-M: ##scalar>vector rewrite
-    dup src>> vreg>insn {
-        { [ dup literal-insn? ] [ fold-scalar>vector ] }
-        { [ dup ##vector>scalar? ] [ [ dst>> ] [ src>> ] bi* <copy> ] }
-        [ 2drop f ]
-    } cond ;
-
-:: fold-gather-vector-2 ( insn src1 src2 -- insn )
-    insn dst>>
-    src1 src2 [ insn rep>> scalar-value ] bi@ append
-    \ ##load-reference new-insn ;
-
-: rewrite-gather-vector-2 ( insn -- insn/f )
-    dup [ src1>> vreg>insn ] [ src2>> vreg>insn ] bi {
-        { [ 2dup [ literal-insn? ] both? ] [ fold-gather-vector-2 ] }
-        [ 3drop f ]
-    } cond ;
-
-M: ##gather-vector-2 rewrite rewrite-gather-vector-2 ;
-
-M: ##gather-int-vector-2 rewrite rewrite-gather-vector-2 ;
-
-:: fold-gather-vector-4 ( insn src1 src2 src3 src4 -- insn )
-    insn dst>>
-    [
-        src1 src2 src3 src4
-        [ insn rep>> scalar-value ] 4 napply
-    ] B{ } append-outputs-as
-    \ ##load-reference new-insn ;
-
-: rewrite-gather-vector-4 ( insn -- insn/f )
-    dup { [ src1>> ] [ src2>> ] [ src3>> ] [ src4>> ] } cleave [ vreg>insn ] 4 napply
-    {
-        { [ 4 ndup [ literal-insn? ] 4 napply and and and ] [ fold-gather-vector-4 ] }
-        [ 5 ndrop f ]
-    } cond ;
-
-M: ##gather-vector-4 rewrite rewrite-gather-vector-4 ;
-
-M: ##gather-int-vector-4 rewrite rewrite-gather-vector-4 ;
-
-: fold-shuffle-vector ( insn src1 src2 -- insn )
-    [ dst>> ] [ obj>> ] [ obj>> ] tri*
-    swap nths \ ##load-reference new-insn ;
-
-M: ##shuffle-vector rewrite
-    dup [ src>> vreg>insn ] [ shuffle>> vreg>insn ] bi
-    {
-        { [ 2dup [ ##load-reference? ] both? ] [ fold-shuffle-vector ] }
-        [ 3drop f ]
-    } cond ;
-
-M: ##xor-vector rewrite
-    dup diagonal?
-    [ [ dst>> ] [ rep>> ] bi \ ##zero-vector new-insn ] [ drop f ] if ;
-
-: vector-not? ( insn -- ? )
-    {
-        [ ##not-vector? ]
-        [ {
-            [ ##xor-vector? ]
-            [ [ src1>> ] [ src2>> ] bi [ vreg>insn ##fill-vector? ] either? ]
-        } 1&& ]
-    } 1|| ;
-
-GENERIC: vector-not-src ( insn -- vreg )
-
-M: ##not-vector vector-not-src
-    src>> ;
-
-M: ##xor-vector vector-not-src
-    dup src1>> vreg>insn ##fill-vector? [ src2>> ] [ src1>> ] if ;
-
-M: ##and-vector rewrite 
-    {
-        { [ dup src1>> vreg>insn vector-not? ] [
-            {
-                [ dst>> ]
-                [ src1>> vreg>insn vector-not-src ]
-                [ src2>> ]
-                [ rep>> ]
-            } cleave \ ##andn-vector new-insn
-        ] }
-        { [ dup src2>> vreg>insn vector-not? ] [
-            {
-                [ dst>> ]
-                [ src2>> vreg>insn vector-not-src ]
-                [ src1>> ]
-                [ rep>> ]
-            } cleave \ ##andn-vector new-insn
-        ] }
-        [ drop f ]
-    } cond ;
-
-M: ##andn-vector rewrite
-    dup src1>> vreg>insn vector-not? [
-        {
-            [ dst>> ]
-            [ src1>> vreg>insn vector-not-src ]
-            [ src2>> ]
-            [ rep>> ]
-        } cleave \ ##and-vector new-insn
-    ] [ drop f ] if ;
diff --git a/basis/compiler/cfg/gvn/slots/authors.txt b/basis/compiler/cfg/gvn/slots/authors.txt
deleted file mode 100644 (file)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/basis/compiler/cfg/gvn/slots/slots.factor b/basis/compiler/cfg/gvn/slots/slots.factor
deleted file mode 100644 (file)
index d994e19..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-! Copyright (C) 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors combinators.short-circuit cpu.architecture fry
-kernel math
-compiler.cfg.instructions
-compiler.cfg.gvn.graph
-compiler.cfg.gvn.rewrite ;
-IN: compiler.cfg.gvn.slots
-
-: simplify-slot-addressing? ( insn -- ? )
-    complex-addressing?
-    [ slot>> vreg>insn ##add-imm? ] [ drop f ] if ;
-
-: simplify-slot-addressing ( insn -- insn/f )
-    dup simplify-slot-addressing? [
-        dup slot>> vreg>insn
-        [ src1>> >>slot ]
-        [ src2>> over scale>> '[ _ _ shift - ] change-tag ]
-        bi
-    ] [ drop f ] if ;
-
-M: ##slot rewrite simplify-slot-addressing ;
-M: ##set-slot rewrite simplify-slot-addressing ;
-M: ##write-barrier rewrite simplify-slot-addressing ;
diff --git a/basis/compiler/cfg/gvn/summary.txt b/basis/compiler/cfg/gvn/summary.txt
deleted file mode 100644 (file)
index bee42e3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Global value numbering for common subexpression elimination
diff --git a/extra/compiler/cfg/graphviz/graphviz.factor b/extra/compiler/cfg/graphviz/graphviz.factor
new file mode 100644 (file)
index 0000000..0fd6ae1
--- /dev/null
@@ -0,0 +1,97 @@
+! Copyright (C) 2011 Alex Vondrak.
+! See http://factorcode.org/license.txt for BSD license
+
+USING: accessors fry io io.directories io.pathnames
+io.streams.string kernel math math.parser namespaces
+prettyprint sequences splitting strings tools.annotations
+
+compiler.cfg
+compiler.cfg.builder
+compiler.cfg.debugger
+compiler.cfg.linearization
+compiler.cfg.finalization
+compiler.cfg.optimizer
+compiler.cfg.rpo
+
+compiler.cfg.value-numbering
+compiler.cfg.value-numbering.graph
+
+graphviz
+graphviz.notation
+graphviz.render
+;
+FROM: compiler.cfg.linearization => number-blocks ;
+IN: compiler.cfg.graphviz
+
+: left-justify ( str -- str' )
+    string-lines "\\l" join ;
+
+: bb-label ( bb -- str )
+    [
+        instructions>> [ insn. ] each
+    ] with-string-writer left-justify ;
+
+: add-cfg-vertex ( graph bb -- graph' )
+    [ number>> <node> ]
+    [ bb-label =label ]
+    [ kill-block?>> [ "grey" =color "filled" =style ] when ]
+    tri add ;
+
+: add-cfg-edges ( graph bb -- graph' )
+    dup successors>> [
+        [ number>> ] bi@ ->
+    ] with each ;
+
+: cfgviz ( cfg -- graph )
+    <digraph>
+        graph[ "t" =labelloc ];
+        node[ "box" =shape "Courier" =fontname 10 =fontsize ];
+        swap [
+            [ add-cfg-vertex ] [ add-cfg-edges ] bi
+        ] each-basic-block ;
+
+: perform-pass ( cfg pass pass# -- cfg' )
+    drop def>> call( cfg -- cfg' ) ;
+
+: draw-cfg ( cfg pass pass# -- cfg )
+    [ dup cfgviz ]
+    [ name>> "After " prepend =label ]
+    [ number>string png ]
+    tri* ;
+
+: watch-pass ( cfg pass pass# -- cfg' )
+    [ perform-pass ] 2keep draw-cfg ;
+
+: begin-watching-passes ( cfg -- cfg )
+    \ build-cfg 0 draw-cfg ;
+
+: watch-passes ( cfg -- cfg' )
+    \ optimize-cfg def>> [ 1 + watch-pass ] each-index ;
+
+: finish-watching-passes ( cfg -- )
+    \ finalize-cfg
+    \ optimize-cfg def>> length 1 +
+    watch-pass drop ;
+
+: watch-cfg ( path cfg -- )
+    over make-directories
+    [
+        [
+            begin-watching-passes
+            watch-passes
+            finish-watching-passes
+        ] with-cfg
+    ] curry with-directory ;
+
+: watch-cfgs ( path cfgs -- )
+    [
+        number>string "cfg" prepend append-path
+        swap watch-cfg
+    ] with each-index ;
+
+: watch-optimizer* ( path quot -- )
+    test-builder
+    dup length 1 = [ first watch-cfg ] [ watch-cfgs ] if ;
+
+: watch-optimizer ( quot -- )
+    [ "" ] dip watch-optimizer* ;
diff --git a/extra/compiler/cfg/gvn/1.png b/extra/compiler/cfg/gvn/1.png
new file mode 100644 (file)
index 0000000..29234d5
Binary files /dev/null and b/extra/compiler/cfg/gvn/1.png differ
diff --git a/extra/compiler/cfg/gvn/2.png b/extra/compiler/cfg/gvn/2.png
new file mode 100644 (file)
index 0000000..0fd6bdd
Binary files /dev/null and b/extra/compiler/cfg/gvn/2.png differ
diff --git a/extra/compiler/cfg/gvn/3.png b/extra/compiler/cfg/gvn/3.png
new file mode 100644 (file)
index 0000000..6d4afc9
Binary files /dev/null and b/extra/compiler/cfg/gvn/3.png differ
diff --git a/extra/compiler/cfg/gvn/4.png b/extra/compiler/cfg/gvn/4.png
new file mode 100644 (file)
index 0000000..8c9683c
Binary files /dev/null and b/extra/compiler/cfg/gvn/4.png differ
diff --git a/extra/compiler/cfg/gvn/5.png b/extra/compiler/cfg/gvn/5.png
new file mode 100644 (file)
index 0000000..4feb312
Binary files /dev/null and b/extra/compiler/cfg/gvn/5.png differ
diff --git a/extra/compiler/cfg/gvn/alien/alien.factor b/extra/compiler/cfg/gvn/alien/alien.factor
new file mode 100644 (file)
index 0000000..a95a959
--- /dev/null
@@ -0,0 +1,131 @@
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators combinators.short-circuit fry
+kernel make math sequences
+cpu.architecture
+compiler.cfg.hats
+compiler.cfg.utilities
+compiler.cfg.registers
+compiler.cfg.instructions
+compiler.cfg.gvn.math
+compiler.cfg.gvn.graph
+compiler.cfg.gvn.rewrite ;
+IN: compiler.cfg.gvn.alien
+
+M: ##box-displaced-alien rewrite
+    dup displacement>> vreg>insn zero-insn?
+    [ [ dst>> ] [ base>> ] bi <copy> ] [ drop f ] if ;
+
+! ##box-displaced-alien f 1 2 3 <class>
+! ##unbox-c-ptr 4 1 <class>
+! =>
+! ##box-displaced-alien f 1 2 3 <class>
+! ##unbox-c-ptr 5 3 <class>
+! ##add 4 5 2
+
+: rewrite-unbox-alien ( insn box-insn -- insn )
+    [ dst>> ] [ src>> ] bi* <copy> ;
+
+: rewrite-unbox-displaced-alien ( insn box-insn -- insns )
+    [
+        [ dst>> ]
+        [ [ base>> ] [ base-class>> ] [ displacement>> ] tri ] bi*
+        [ ^^unbox-c-ptr ] dip
+        ##add
+    ] { } make ;
+
+: rewrite-unbox-any-c-ptr ( insn -- insn/f )
+    dup src>> vreg>insn
+    {
+        { [ dup ##box-alien? ] [ rewrite-unbox-alien ] }
+        { [ dup ##box-displaced-alien? ] [ rewrite-unbox-displaced-alien ] }
+        [ 2drop f ]
+    } cond ;
+
+M: ##unbox-any-c-ptr rewrite rewrite-unbox-any-c-ptr ;
+
+M: ##unbox-alien rewrite rewrite-unbox-any-c-ptr ;
+
+! Fuse ##add-imm into ##load-memory(-imm) and ##store-memory(-imm)
+! just update the offset in the instruction
+: fuse-base-offset? ( insn -- ? )
+    base>> vreg>insn ##add-imm? ;
+
+: fuse-base-offset ( insn -- insn' )
+    dup base>> vreg>insn
+    [ src1>> ] [ src2>> ] bi
+    [ >>base ] [ '[ _ + ] change-offset ] bi* ;
+
+! Fuse ##add-imm into ##load-memory and ##store-memory
+! just update the offset in the instruction
+: fuse-displacement-offset? ( insn -- ? )
+    { [ scale>> 0 = ] [ displacement>> vreg>insn ##add-imm? ] } 1&& ;
+
+: fuse-displacement-offset ( insn -- insn' )
+    dup displacement>> vreg>insn
+    [ src1>> ] [ src2>> ] bi
+    [ >>displacement ] [ '[ _ + ] change-offset ] bi* ;
+
+! Fuse ##add into ##load-memory-imm and ##store-memory-imm
+! construct a new ##load-memory or ##store-memory with the
+! ##add's operand as the displacement
+: fuse-displacement? ( insn -- ? )
+    {
+        [ offset>> 0 = complex-addressing? or ]
+        [ base>> vreg>insn ##add? ]
+    } 1&& ;
+
+GENERIC: alien-insn-value ( insn -- value )
+
+M: ##load-memory-imm alien-insn-value dst>> ;
+M: ##store-memory-imm alien-insn-value src>> ;
+
+GENERIC: new-alien-insn ( value base displacement scale offset rep c-type insn -- insn )
+
+M: ##load-memory-imm new-alien-insn drop \ ##load-memory new-insn ;
+M: ##store-memory-imm new-alien-insn drop \ ##store-memory new-insn ;
+
+: fuse-displacement ( insn -- insn' )
+    {
+        [ alien-insn-value ]
+        [ base>> vreg>insn [ src1>> ] [ src2>> ] bi ]
+        [ drop 0 ]
+        [ offset>> ]
+        [ rep>> ]
+        [ c-type>> ]
+        [ ]
+    } cleave new-alien-insn ;
+
+! Fuse ##shl-imm into ##load-memory or ##store-memory
+: scale-insn? ( insn -- ? )
+    { [ ##shl-imm? ] [ src2>> { 1 2 3 } member? ] } 1&& ;
+
+: fuse-scale? ( insn -- ? )
+    { [ scale>> 0 = ] [ displacement>> vreg>insn scale-insn? ] } 1&& ;
+
+: fuse-scale ( insn -- insn' )
+    dup displacement>> vreg>insn
+    [ src1>> ] [ src2>> ] bi
+    [ >>displacement ] [ >>scale ] bi* ;
+
+: rewrite-memory-op ( insn -- insn/f )
+    complex-addressing? [
+        {
+            { [ dup fuse-base-offset? ] [ fuse-base-offset ] }
+            { [ dup fuse-displacement-offset? ] [ fuse-displacement-offset ] }
+            { [ dup fuse-scale? ] [ fuse-scale ] }
+            [ drop f ]
+        } cond
+    ] [ drop f ] if ;
+
+: rewrite-memory-imm-op ( insn -- insn/f )
+    {
+        { [ dup fuse-base-offset? ] [ fuse-base-offset ] }
+        { [ dup fuse-displacement? ] [ fuse-displacement ] }
+        [ drop f ]
+    } cond ;
+
+M: ##load-memory rewrite rewrite-memory-op ;
+M: ##load-memory-imm rewrite rewrite-memory-imm-op ;
+M: ##store-memory rewrite rewrite-memory-op ;
+M: ##store-memory-imm rewrite rewrite-memory-imm-op ;
diff --git a/extra/compiler/cfg/gvn/alien/authors.txt b/extra/compiler/cfg/gvn/alien/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/extra/compiler/cfg/gvn/comparisons/authors.txt b/extra/compiler/cfg/gvn/comparisons/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/extra/compiler/cfg/gvn/comparisons/comparisons.factor b/extra/compiler/cfg/gvn/comparisons/comparisons.factor
new file mode 100644 (file)
index 0000000..531e4d5
--- /dev/null
@@ -0,0 +1,316 @@
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators kernel math math.order namespaces
+sequences vectors combinators.short-circuit
+cpu.architecture
+compiler.cfg
+compiler.cfg.comparisons
+compiler.cfg.instructions
+compiler.cfg.registers
+compiler.cfg.gvn.math
+compiler.cfg.gvn.graph
+compiler.cfg.gvn.rewrite ;
+IN: compiler.cfg.gvn.comparisons
+
+! Optimizations performed here:
+!
+! 1) Eliminating intermediate boolean values when the result of
+! a comparison is used by a compare-branch
+! 2) Folding comparisons where both inputs are literal
+! 3) Folding comparisons where both inputs are congruent
+! 4) Converting compare instructions into compare-imm instructions
+
+: fold-compare-imm? ( insn -- ? )
+    src1>> vreg>insn literal-insn? ;
+
+: evaluate-compare-imm ( insn -- ? )
+    [ src1>> vreg>literal ] [ src2>> ] [ cc>> ] tri
+    {
+        { cc= [ eq? ] }
+        { cc/= [ eq? not ] }
+    } case ;
+
+: fold-compare-integer-imm? ( insn -- ? )
+    src1>> vreg>insn ##load-integer? ;
+
+: evaluate-compare-integer-imm ( insn -- ? )
+    [ src1>> vreg>integer ] [ src2>> ] [ cc>> ] tri
+    [ <=> ] dip evaluate-cc ;
+
+: fold-test-imm? ( insn -- ? )
+    src1>> vreg>insn ##load-integer? ;
+
+: evaluate-test-imm ( insn -- ? )
+    [ src1>> vreg>integer ] [ src2>> ] [ cc>> ] tri
+    [ bitand ] dip {
+        { cc= [ 0 = ] }
+        { cc/= [ 0 = not ] }
+    } case ;
+
+: rewrite-into-test? ( insn -- ? )
+    {
+        [ drop test-instruction? ]
+        [ cc>> { cc= cc/= } member-eq? ]
+        [ src2>> 0 = ]
+    } 1&& ;
+
+: >compare< ( insn -- in1 in2 cc )
+    [ src1>> ] [ src2>> ] [ cc>> ] tri ; inline
+
+: >test-vector< ( insn -- src1 temp rep vcc )
+    {
+        [ src1>> ]
+        [ drop next-vreg ]
+        [ rep>> ]
+        [ vcc>> ]
+    } cleave ; inline
+
+UNION: scalar-compare-insn
+    ##compare
+    ##compare-imm
+    ##compare-integer
+    ##compare-integer-imm
+    ##test
+    ##test-imm
+    ##compare-float-unordered
+    ##compare-float-ordered ;
+
+UNION: general-compare-insn scalar-compare-insn ##test-vector ;
+
+: rewrite-boolean-comparison? ( insn -- ? )
+    {
+        [ src1>> vreg>insn general-compare-insn? ]
+        [ src2>> not ]
+        [ cc>> cc/= eq? ]
+    } 1&& ; inline
+
+: rewrite-boolean-comparison ( insn -- insn )
+    src1>> vreg>insn {
+        { [ dup ##compare? ] [ >compare< \ ##compare-branch new-insn ] }
+        { [ dup ##compare-imm? ] [ >compare< \ ##compare-imm-branch new-insn ] }
+        { [ dup ##compare-integer? ] [ >compare< \ ##compare-integer-branch new-insn ] }
+        { [ dup ##compare-integer-imm? ] [ >compare< \ ##compare-integer-imm-branch new-insn ] }
+        { [ dup ##test? ] [ >compare< \ ##test-branch new-insn ] }
+        { [ dup ##test-imm? ] [ >compare< \ ##test-imm-branch new-insn ] }
+        { [ dup ##compare-float-unordered? ] [ >compare< \ ##compare-float-unordered-branch new-insn ] }
+        { [ dup ##compare-float-ordered? ] [ >compare< \ ##compare-float-ordered-branch new-insn ] }
+        { [ dup ##test-vector? ] [ >test-vector< \ ##test-vector-branch new-insn ] }
+    } cond ;
+
+: fold-branch ( ? -- insn )
+    0 1 ?
+    basic-block get [ nth 1vector ] change-successors drop
+    \ ##branch new-insn ;
+
+: fold-compare-imm-branch ( insn -- insn/f )
+    evaluate-compare-imm fold-branch ;
+
+: >test-branch ( insn -- insn )
+    [ src1>> ] [ src1>> ] [ cc>> ] tri \ ##test-branch new-insn ;
+
+M: ##compare-imm-branch rewrite
+    {
+        { [ dup rewrite-boolean-comparison? ] [ rewrite-boolean-comparison ] }
+        { [ dup fold-compare-imm? ] [ fold-compare-imm-branch ] }
+        [ drop f ]
+    } cond ;
+
+: fold-compare-integer-imm-branch ( insn -- insn/f )
+    evaluate-compare-integer-imm fold-branch ;
+
+M: ##compare-integer-imm-branch rewrite
+    {
+        { [ dup fold-compare-integer-imm? ] [ fold-compare-integer-imm-branch ] }
+        { [ dup rewrite-into-test? ] [ >test-branch ] }
+        [ drop f ]
+    } cond ;
+
+: fold-test-imm-branch ( insn -- insn/f )
+    evaluate-test-imm fold-branch ;
+
+M: ##test-imm-branch rewrite
+    {
+        { [ dup fold-test-imm? ] [ fold-test-imm-branch ] }
+        [ drop f ]
+    } cond ;
+
+: swap-compare ( src1 src2 cc swap? -- src1 src2 cc )
+    [ [ swap ] dip swap-cc ] when ; inline
+
+: (>compare-imm-branch) ( insn swap? -- src1 src2 cc )
+    [ [ src1>> ] [ src2>> ] [ cc>> ] tri ] dip swap-compare ; inline
+
+: >compare-imm-branch ( insn swap? -- insn' )
+    (>compare-imm-branch)
+    [ vreg>literal ] dip
+    \ ##compare-imm-branch new-insn ; inline
+
+: >compare-integer-imm-branch ( insn swap? -- insn' )
+    (>compare-imm-branch)
+    [ vreg>integer ] dip
+    \ ##compare-integer-imm-branch new-insn ; inline
+
+: evaluate-self-compare ( insn -- ? )
+    cc>> { cc= cc<= cc>= } member-eq? ;
+
+: rewrite-self-compare-branch ( insn -- insn' )
+    evaluate-self-compare fold-branch ;
+
+M: ##compare-branch rewrite
+    {
+        { [ dup src1>> vreg-immediate-comparand? ] [ t >compare-imm-branch ] }
+        { [ dup src2>> vreg-immediate-comparand? ] [ f >compare-imm-branch ] }
+        { [ dup diagonal? ] [ rewrite-self-compare-branch ] }
+        [ drop f ]
+    } cond ;
+
+M: ##compare-integer-branch rewrite
+    {
+        { [ dup src1>> vreg-immediate-arithmetic? ] [ t >compare-integer-imm-branch ] }
+        { [ dup src2>> vreg-immediate-arithmetic? ] [ f >compare-integer-imm-branch ] }
+        { [ dup diagonal? ] [ rewrite-self-compare-branch ] }
+        [ drop f ]
+    } cond ;
+
+: (>compare-imm) ( insn swap? -- dst src1 src2 cc )
+    [ { [ dst>> ] [ src1>> ] [ src2>> ] [ cc>> ] } cleave ] dip
+    swap-compare ; inline
+
+: >compare-imm ( insn swap? -- insn' )
+    (>compare-imm)
+    [ vreg>literal ] dip
+    next-vreg \ ##compare-imm new-insn ; inline
+
+: >compare-integer-imm ( insn swap? -- insn' )
+    (>compare-imm)
+    [ vreg>integer ] dip
+    next-vreg \ ##compare-integer-imm new-insn ; inline
+
+: >boolean-insn ( insn ? -- insn' )
+    [ dst>> ] dip \ ##load-reference new-insn ;
+
+: rewrite-self-compare ( insn -- insn' )
+    dup evaluate-self-compare >boolean-insn ;
+
+M: ##compare rewrite
+    {
+        { [ dup src1>> vreg-immediate-comparand? ] [ t >compare-imm ] }
+        { [ dup src2>> vreg-immediate-comparand? ] [ f >compare-imm ] }
+        { [ dup diagonal? ] [ rewrite-self-compare ] }
+        [ drop f ]
+    } cond ;
+
+M: ##compare-integer rewrite
+    {
+        { [ dup src1>> vreg-immediate-arithmetic? ] [ t >compare-integer-imm ] }
+        { [ dup src2>> vreg-immediate-arithmetic? ] [ f >compare-integer-imm ] }
+        { [ dup diagonal? ] [ rewrite-self-compare ] }
+        [ drop f ]
+    } cond ;
+
+: rewrite-redundant-comparison? ( insn -- ? )
+    {
+        [ src1>> vreg>insn scalar-compare-insn? ]
+        [ src2>> not ]
+        [ cc>> { cc= cc/= } member? ]
+    } 1&& ; inline
+
+: rewrite-redundant-comparison ( insn -- insn' )
+    [ cc>> ] [ dst>> ] [ src1>> vreg>insn ] tri {
+        { [ dup ##compare? ] [ >compare< next-vreg \ ##compare new-insn ] }
+        { [ dup ##compare-imm? ] [ >compare< next-vreg \ ##compare-imm new-insn ] }
+        { [ dup ##compare-integer? ] [ >compare< next-vreg \ ##compare-integer new-insn ] }
+        { [ dup ##compare-integer-imm? ] [ >compare< next-vreg \ ##compare-integer-imm new-insn ] }
+        { [ dup ##test? ] [ >compare< next-vreg \ ##test new-insn ] }
+        { [ dup ##test-imm? ] [ >compare< next-vreg \ ##test-imm new-insn ] }
+        { [ dup ##compare-float-unordered? ] [ >compare< next-vreg \ ##compare-float-unordered new-insn ] }
+        { [ dup ##compare-float-ordered? ] [ >compare< next-vreg \ ##compare-float-ordered new-insn ] }
+    } cond
+    swap cc= eq? [ [ negate-cc ] change-cc ] when ;
+
+: fold-compare-imm ( insn -- insn' )
+    dup evaluate-compare-imm >boolean-insn ;
+
+M: ##compare-imm rewrite
+    {
+        { [ dup rewrite-redundant-comparison? ] [ rewrite-redundant-comparison ] }
+        { [ dup fold-compare-imm? ] [ fold-compare-imm ] }
+        [ drop f ]
+    } cond ;
+
+: fold-compare-integer-imm ( insn -- insn' )
+    dup evaluate-compare-integer-imm >boolean-insn ;
+
+: >test ( insn -- insn' )
+    { [ dst>> ] [ src1>> ] [ src1>> ] [ cc>> ] [ temp>> ] } cleave
+    \ ##test new-insn ;
+
+M: ##compare-integer-imm rewrite
+    {
+        { [ dup fold-compare-integer-imm? ] [ fold-compare-integer-imm ] }
+        { [ dup rewrite-into-test? ] [ >test ] }
+        [ drop f ]
+    } cond ;
+
+: (simplify-test) ( insn -- src1 src2 cc )
+    [ src1>> vreg>insn [ src1>> ] [ src2>> ] bi ] [ cc>> ] bi ; inline
+
+: simplify-test ( insn -- insn )
+    dup (simplify-test) drop [ >>src1 ] [ >>src2 ] bi* ; inline
+
+: simplify-test-branch ( insn -- insn )
+    dup (simplify-test) drop [ >>src1 ] [ >>src2 ] bi* ; inline
+
+: (simplify-test-imm) ( insn -- src1 src2 cc )
+    [ src1>> vreg>insn [ src1>> ] [ src2>> ] bi ] [ cc>> ] bi ; inline
+
+: simplify-test-imm ( insn -- insn )
+    [ dst>> ] [ (simplify-test-imm) ] [ temp>> ] tri \ ##test-imm new-insn ; inline
+
+: simplify-test-imm-branch ( insn -- insn )
+    (simplify-test-imm) \ ##test-imm-branch new-insn ; inline
+
+: >test-imm ( insn ? -- insn' )
+    (>compare-imm) [ vreg>integer ] dip next-vreg
+    \ ##test-imm new-insn ; inline
+
+: >test-imm-branch ( insn ? -- insn' )
+    (>compare-imm-branch) [ vreg>integer ] dip
+    \ ##test-imm-branch new-insn ; inline
+
+M: ##test rewrite
+    {
+        { [ dup src1>> vreg-immediate-comparand? ] [ t >test-imm ] }
+        { [ dup src2>> vreg-immediate-comparand? ] [ f >test-imm ] }
+        { [ dup diagonal? ] [
+            {
+                { [ dup src1>> vreg>insn ##and? ] [ simplify-test ] }
+                { [ dup src1>> vreg>insn ##and-imm? ] [ simplify-test-imm ] }
+                [ drop f ]
+            } cond
+        ] }
+        [ drop f ]
+    } cond ;
+
+M: ##test-branch rewrite
+    {
+        { [ dup src1>> vreg-immediate-comparand? ] [ t >test-imm-branch ] }
+        { [ dup src2>> vreg-immediate-comparand? ] [ f >test-imm-branch ] }
+        { [ dup diagonal? ] [
+            {
+                { [ dup src1>> vreg>insn ##and? ] [ simplify-test-branch ] }
+                { [ dup src1>> vreg>insn ##and-imm? ] [ simplify-test-imm-branch ] }
+                [ drop f ]
+            } cond
+        ] }
+        [ drop f ]
+    } cond ;
+
+: fold-test-imm ( insn -- insn' )
+    dup evaluate-test-imm >boolean-insn ;
+
+M: ##test-imm rewrite
+    {
+        { [ dup fold-test-imm? ] [ fold-test-imm ] }
+        [ drop f ]
+    } cond ;
diff --git a/extra/compiler/cfg/gvn/expressions/expressions.factor b/extra/compiler/cfg/gvn/expressions/expressions.factor
new file mode 100644 (file)
index 0000000..6af5dd0
--- /dev/null
@@ -0,0 +1,85 @@
+! Copyright (C) 2008, 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays classes classes.algebra combinators fry
+generic.parser kernel math namespaces quotations sequences slots
+words make sets
+compiler.cfg.instructions
+compiler.cfg.instructions.syntax
+compiler.cfg.gvn.graph ;
+FROM: sequences.private => set-array-nth ;
+IN: compiler.cfg.gvn.expressions
+
+<<
+
+GENERIC: >expr ( insn -- expr )
+
+: input-values ( slot-specs -- slot-specs' )
+    [ type>> { use literal } member-eq? ] filter ;
+
+: slot->expr-quot ( slot-spec -- quot )
+    [ name>> reader-word 1quotation ]
+    [
+        type>> {
+            { use [ [ vreg>vn ] ] }
+            { literal [ [ ] ] }
+        } case
+    ] bi append ;
+
+: narray-quot ( length -- quot )
+    [
+        [ , [ f <array> ] % ]
+        [ 
+            dup iota [
+                - 1 - , [ swap [ set-array-nth ] keep ] %
+            ] with each
+        ] bi
+    ] [ ] make ;
+
+: >expr-quot ( insn slot-specs -- quot )
+    [
+        [ literalize , \ swap , ]
+        [
+            [ [ slot->expr-quot ] map cleave>quot % ]
+            [ length 1 + narray-quot % ]
+            bi
+        ] bi*
+    ] [ ] make ;
+
+: define->expr-method ( insn slot-specs -- )
+    [ drop \ >expr create-method-in ] [ >expr-quot ] 2bi define ;
+
+insn-classes get
+[ foldable-insn class<= ] filter
+{ ##copy ##load-integer ##load-reference } diff
+[
+    dup "insn-slots" word-prop input-values
+    define->expr-method
+] each
+
+>>
+
+TUPLE: integer-expr value ;
+
+C: <integer-expr> integer-expr
+
+TUPLE: reference-expr value ;
+
+C: <reference-expr> reference-expr
+
+M: reference-expr equal?
+    over reference-expr? [
+        [ value>> ] bi@
+        2dup [ float? ] both?
+        [ fp-bitwise= ] [ eq? ] if
+    ] [ 2drop f ] if ;
+
+M: reference-expr hashcode*
+    nip value>> dup float? [ double>bits ] [ identity-hashcode ] if ;
+
+M: insn >expr drop input-expr-counter counter neg ;
+
+M: ##copy >expr "Fail" throw ;
+
+M: ##load-integer >expr val>> <integer-expr> ;
+
+M: ##load-reference >expr obj>> <reference-expr> ;
diff --git a/extra/compiler/cfg/gvn/expressions/summary.txt b/extra/compiler/cfg/gvn/expressions/summary.txt
new file mode 100644 (file)
index 0000000..22aacde
--- /dev/null
@@ -0,0 +1 @@
+Value numbering expressions
diff --git a/extra/compiler/cfg/gvn/folding/authors.txt b/extra/compiler/cfg/gvn/folding/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/extra/compiler/cfg/gvn/folding/folding.factor b/extra/compiler/cfg/gvn/folding/folding.factor
new file mode 100644 (file)
index 0000000..ca6c2ef
--- /dev/null
@@ -0,0 +1,39 @@
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel layouts math math.bitwise
+compiler.cfg.instructions
+compiler.cfg.gvn.graph
+compiler.cfg.gvn.rewrite ;
+IN: compiler.cfg.gvn.folding
+
+: binary-constant-fold? ( insn -- ? )
+    src1>> vreg>insn ##load-integer? ; inline
+
+GENERIC: binary-constant-fold* ( x y insn -- z )
+
+M: ##add-imm binary-constant-fold* drop + ;
+M: ##sub-imm binary-constant-fold* drop - ;
+M: ##mul-imm binary-constant-fold* drop * ;
+M: ##and-imm binary-constant-fold* drop bitand ;
+M: ##or-imm binary-constant-fold* drop bitor ;
+M: ##xor-imm binary-constant-fold* drop bitxor ;
+M: ##shr-imm binary-constant-fold* drop [ cell-bits 2^ wrap ] dip neg shift ;
+M: ##sar-imm binary-constant-fold* drop neg shift ;
+M: ##shl-imm binary-constant-fold* drop shift ;
+
+: binary-constant-fold ( insn -- insn' )
+    [ dst>> ]
+    [ [ src1>> vreg>integer ] [ src2>> ] [ ] tri binary-constant-fold* ] bi
+    \ ##load-integer new-insn ; inline
+
+: unary-constant-fold? ( insn -- ? )
+    src>> vreg>insn ##load-integer? ; inline
+
+GENERIC: unary-constant-fold* ( x insn -- y )
+
+M: ##not unary-constant-fold* drop bitnot ;
+M: ##neg unary-constant-fold* drop neg ;
+
+: unary-constant-fold ( insn -- insn' )
+    [ dst>> ] [ [ src>> vreg>integer ] [ ] bi unary-constant-fold* ] bi
+    \ ##load-integer new-insn ; inline
diff --git a/extra/compiler/cfg/gvn/graph/graph.factor b/extra/compiler/cfg/gvn/graph/graph.factor
new file mode 100644 (file)
index 0000000..e951d15
--- /dev/null
@@ -0,0 +1,49 @@
+! Copyright (C) 2008, 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel math namespaces assocs ;
+IN: compiler.cfg.gvn.graph
+
+SYMBOL: input-expr-counter
+
+! assoc mapping vregs to value numbers
+! this is the identity on canonical representatives
+SYMBOL: vregs>vns
+
+! assoc mapping expressions to value numbers
+SYMBOL: exprs>vns
+
+! assoc mapping value numbers to instructions
+SYMBOL: vns>insns
+
+! assoc mapping vregs to *global* value numbers
+SYMBOL: vregs>gvns
+
+SYMBOL: changed?
+
+: vn>insn ( vn -- insn ) vns>insns get at ;
+
+! : vreg>vn ( vreg -- vn ) vregs>vns get [ ] cache ;
+
+: vreg>vn ( vreg -- vn ) vregs>gvns get at ;
+
+! : set-vn ( vn vreg -- ) vregs>vns get set-at ;
+
+: local-vn ( vn vreg -- lvn )
+    vregs>vns get ?at
+    [ nip ]
+    [ dupd vregs>vns get set-at ] if ;
+
+: set-vn ( vn vreg -- )
+    [ local-vn ] keep
+    vregs>gvns get maybe-set-at [ changed? on ] when ;
+
+: vreg>insn ( vreg -- insn ) vreg>vn vn>insn ;
+
+: init-gvn ( -- )
+    H{ } clone vregs>gvns set ;
+
+: init-value-graph ( -- )
+    0 input-expr-counter set
+    H{ } clone vregs>vns set
+    H{ } clone exprs>vns set
+    H{ } clone vns>insns set ;
diff --git a/extra/compiler/cfg/gvn/graph/summary.txt b/extra/compiler/cfg/gvn/graph/summary.txt
new file mode 100644 (file)
index 0000000..f6fb58d
--- /dev/null
@@ -0,0 +1 @@
+Value numbering expression graph
diff --git a/extra/compiler/cfg/gvn/gvn-tests.factor b/extra/compiler/cfg/gvn/gvn-tests.factor
new file mode 100644 (file)
index 0000000..4732698
--- /dev/null
@@ -0,0 +1,3098 @@
+USING: compiler.cfg.gvn 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.predecessors locals compiler.cfg.dce
+compiler.cfg.ssa.destruction compiler.cfg.loop-detection
+compiler.cfg.representations compiler.cfg assocs vectors arrays
+layouts literals namespaces alien compiler.cfg.gvn.simd system
+;
+QUALIFIED-WITH: alien.c-types c
+IN: compiler.cfg.gvn.tests
+
+: trim-temps ( insns -- insns )
+    [
+        dup {
+            [ ##compare? ]
+            [ ##compare-imm? ]
+            [ ##compare-integer? ]
+            [ ##compare-integer-imm? ]
+            [ ##compare-float-unordered? ]
+            [ ##compare-float-ordered? ]
+            [ ##test? ]
+            [ ##test-imm? ]
+            [ ##test-vector? ]
+            [ ##test-vector-branch? ]
+        } 1|| [ f >>temp ] when
+    ] map ;
+
+! Folding constants together
+[
+    {
+        T{ ##load-reference f 0 0.0 }
+        T{ ##load-reference f 1 -0.0 }
+    }
+] [
+    {
+        T{ ##load-reference f 0 0.0 }
+        T{ ##load-reference f 1 -0.0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-reference f 0 0.0 }
+        T{ ##copy f 1 0 any-rep }
+    }
+] [
+    {
+        T{ ##load-reference f 0 0.0 }
+        T{ ##load-reference f 1 0.0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-reference f 0 t }
+        T{ ##copy f 1 0 any-rep }
+    }
+] [
+    {
+        T{ ##load-reference f 0 t }
+        T{ ##load-reference f 1 t }
+    } value-numbering-step
+] unit-test
+
+! ##load-reference/##replace fusion
+cpu x86? [
+    [
+        {
+            T{ ##load-integer f 0 10 }
+            T{ ##replace-imm f 10 D 0 }
+        }
+    ] [
+        {
+            T{ ##load-integer f 0 10 }
+            T{ ##replace f 0 D 0 }
+        } value-numbering-step
+    ] unit-test
+
+    [
+        {
+            T{ ##load-reference f 0 f }
+            T{ ##replace-imm f f D 0 }
+        }
+    ] [
+        {
+            T{ ##load-reference f 0 f }
+            T{ ##replace f 0 D 0 }
+        } value-numbering-step
+    ] unit-test
+] when
+
+cpu x86.32? [
+    [
+        {
+            T{ ##load-reference f 0 + }
+            T{ ##replace-imm f + D 0 }
+        }
+    ] [
+        {
+            T{ ##load-reference f 0 + }
+            T{ ##replace f 0 D 0 }
+        } value-numbering-step
+    ] unit-test
+] when
+
+cpu x86.64? [
+    [
+        {
+            T{ ##load-integer f 0 10,000,000,000 }
+            T{ ##replace f 0 D 0 }
+        }
+    ] [
+        {
+            T{ ##load-integer f 0 10,000,000,000 }
+            T{ ##replace f 0 D 0 }
+        } value-numbering-step
+    ] unit-test
+
+    ! Boundary case
+    [
+        {
+            T{ ##load-integer f 0 HEX: 7fffffff }
+            T{ ##replace f 0 D 0 }
+        }
+    ] [
+        {
+            T{ ##load-integer f 0 HEX: 7fffffff }
+            T{ ##replace f 0 D 0 }
+        } value-numbering-step
+    ] unit-test
+] when
+
+! Double compare elimination
+[
+    {
+        T{ ##peek f 1 D 1 }
+        T{ ##peek f 2 D 2 }
+        T{ ##compare f 4 2 1 cc= }
+        T{ ##copy f 6 4 any-rep }
+        T{ ##replace f 6 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 1 D 1 }
+        T{ ##peek f 2 D 2 }
+        T{ ##compare f 4 2 1 cc= }
+        T{ ##compare-imm f 6 4 f cc/= }
+        T{ ##replace f 6 D 0 }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 1 D 1 }
+        T{ ##compare-imm f 2 1 16 cc= }
+        T{ ##copy f 3 2 any-rep }
+        T{ ##replace f 3 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 1 D 1 }
+        T{ ##compare-imm f 2 1 16 cc= }
+        T{ ##compare-imm f 3 2 f cc/= }
+        T{ ##replace f 3 D 0 }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 1 D 1 }
+        T{ ##peek f 2 D 2 }
+        T{ ##compare-integer f 4 2 1 cc> }
+        T{ ##copy f 6 4 any-rep }
+        T{ ##replace f 6 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 1 D 1 }
+        T{ ##peek f 2 D 2 }
+        T{ ##compare-integer f 4 2 1 cc> }
+        T{ ##compare-imm f 6 4 f cc/= }
+        T{ ##replace f 6 D 0 }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 1 D 1 }
+        T{ ##peek f 2 D 2 }
+        T{ ##compare-integer f 4 2 1 cc<= }
+        T{ ##compare-integer f 6 2 1 cc/<= }
+        T{ ##replace f 6 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 1 D 1 }
+        T{ ##peek f 2 D 2 }
+        T{ ##compare-integer f 4 2 1 cc<= }
+        T{ ##compare-imm f 6 4 f cc= }
+        T{ ##replace f 6 D 0 }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 1 D 1 }
+        T{ ##compare-integer-imm f 2 1 100 cc<= }
+        T{ ##compare-integer-imm f 3 1 100 cc/<= }
+        T{ ##replace f 3 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 1 D 1 }
+        T{ ##compare-integer-imm f 2 1 100 cc<= }
+        T{ ##compare-imm f 3 2 f cc= }
+        T{ ##replace f 3 D 0 }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 8 D 0 }
+        T{ ##peek f 9 D -1 }
+        T{ ##compare-float-unordered f 12 8 9 cc< }
+        T{ ##compare-float-unordered f 14 8 9 cc/< }
+        T{ ##replace f 14 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 8 D 0 }
+        T{ ##peek f 9 D -1 }
+        T{ ##compare-float-unordered f 12 8 9 cc< }
+        T{ ##compare-imm f 14 12 f cc= }
+        T{ ##replace f 14 D 0 }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 29 D -1 }
+        T{ ##peek f 30 D -2 }
+        T{ ##compare f 33 29 30 cc= }
+        T{ ##compare-branch f 29 30 cc= }
+    }
+] [
+    {
+        T{ ##peek f 29 D -1 }
+        T{ ##peek f 30 D -2 }
+        T{ ##compare f 33 29 30 cc= }
+        T{ ##compare-imm-branch f 33 f cc/= }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 29 D -1 }
+        T{ ##peek f 30 D -2 }
+        T{ ##compare-integer f 33 29 30 cc<= }
+        T{ ##compare-integer-branch f 29 30 cc<= }
+    }
+] [
+    {
+        T{ ##peek f 29 D -1 }
+        T{ ##peek f 30 D -2 }
+        T{ ##compare-integer f 33 29 30 cc<= }
+        T{ ##compare-imm-branch f 33 f cc/= }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 29 D -1 }
+        T{ ##peek f 30 D -2 }
+        T{ ##test f 33 29 30 cc= }
+        T{ ##test-branch f 29 30 cc= }
+    }
+] [
+    {
+        T{ ##peek f 29 D -1 }
+        T{ ##peek f 30 D -2 }
+        T{ ##test f 33 29 30 cc= }
+        T{ ##compare-imm-branch f 33 f cc/= }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 29 D -1 }
+        T{ ##test-imm f 33 29 30 cc= }
+        T{ ##test-imm-branch f 29 30 cc= }
+    }
+] [
+    {
+        T{ ##peek f 29 D -1 }
+        T{ ##test-imm f 33 29 30 cc= }
+        T{ ##compare-imm-branch f 33 f cc/= }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 1 D -1 }
+        T{ ##test-vector f 2 1 f float-4-rep vcc-any }
+        T{ ##test-vector-branch f 1 f float-4-rep vcc-any }
+    }
+] [
+    {
+        T{ ##peek f 1 D -1 }
+        T{ ##test-vector f 2 1 f float-4-rep vcc-any }
+        T{ ##compare-imm-branch f 2 f cc/= }
+    } value-numbering-step trim-temps
+] unit-test
+
+cpu x86.32? [
+    [
+        {
+            T{ ##peek f 1 D 0 }
+            T{ ##compare-imm f 2 1 + cc= }
+            T{ ##compare-imm-branch f 1 + cc= }
+        }
+    ] [
+        {
+            T{ ##peek f 1 D 0 }
+            T{ ##compare-imm f 2 1 + cc= }
+            T{ ##compare-imm-branch f 2 f cc/= }
+        } value-numbering-step trim-temps
+    ] unit-test
+] when
+
+! Immediate operand fusion
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##add-imm f 2 0 100 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##add f 2 0 1 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##add-imm f 2 0 100 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##add f 2 1 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##add-imm f 2 0 -100 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##sub f 2 0 1 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##sub f 1 0 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##mul-imm f 2 0 100 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##mul f 2 0 1 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##mul-imm f 2 0 100 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##mul f 2 1 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 1 D 0 }
+        T{ ##shl-imm f 2 1 3 }
+    }
+] [
+    {
+        T{ ##peek f 1 D 0 }
+        T{ ##mul-imm f 2 1 8 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 -1 }
+        T{ ##neg f 2 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 -1 }
+        T{ ##mul f 2 0 1 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 -1 }
+        T{ ##neg f 2 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 -1 }
+        T{ ##mul f 2 1 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 0 }
+        T{ ##neg f 2 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 0 }
+        T{ ##sub f 2 1 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 0 }
+        T{ ##neg f 2 0 }
+        T{ ##copy f 3 0 any-rep }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 0 }
+        T{ ##sub f 2 1 0 }
+        T{ ##sub f 3 1 2 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##neg f 1 0 }
+        T{ ##copy f 2 0 any-rep }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##neg f 1 0 }
+        T{ ##neg f 2 1 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##not f 1 0 }
+        T{ ##copy f 2 0 any-rep }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##not f 1 0 }
+        T{ ##not f 2 1 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##and-imm f 2 0 100 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##and f 2 0 1 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##and-imm f 2 0 100 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##and f 2 1 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##or-imm f 2 0 100 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##or f 2 0 1 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##or-imm f 2 0 100 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##or f 2 1 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##xor-imm f 2 0 100 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##xor f 2 0 1 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##xor-imm f 2 0 100 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##xor f 2 1 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##compare-imm f 2 0 100 cc= }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##compare f 2 0 1 cc= }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##compare-integer-imm f 2 0 100 cc<= }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##compare-integer f 2 0 1 cc<= }
+    } value-numbering-step trim-temps
+] unit-test
+
+cpu x86.32? [
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-reference f 1 + }
+            T{ ##compare-imm f 2 0 + cc= }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-reference f 1 + }
+            T{ ##compare f 2 0 1 cc= }
+        } value-numbering-step trim-temps
+    ] unit-test
+
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-reference f 1 + }
+            T{ ##compare-imm-branch f 0 + cc= }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-reference f 1 + }
+            T{ ##compare-branch f 0 1 cc= }
+        } value-numbering-step trim-temps
+    ] unit-test
+] when
+
+cpu x86.32? [
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-reference f 1 3.5 }
+            T{ ##compare f 2 0 1 cc= }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-reference f 1 3.5 }
+            T{ ##compare f 2 0 1 cc= }
+        } value-numbering-step trim-temps
+    ] unit-test
+
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-reference f 1 3.5 }
+            T{ ##compare-branch f 0 1 cc= }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-reference f 1 3.5 }
+            T{ ##compare-branch f 0 1 cc= }
+        } value-numbering-step trim-temps
+    ] unit-test
+] unless
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##compare-integer-imm f 2 0 100 cc>= }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##compare-integer f 2 1 0 cc<= }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##compare-integer-imm-branch f 0 100 cc<= }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##compare-integer-branch f 0 1 cc<= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##compare-integer-imm-branch f 0 100 cc>= }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##compare-integer-branch f 1 0 cc<= }
+    } value-numbering-step trim-temps
+] unit-test
+
+! Compare folding
+[
+    {
+        T{ ##load-integer f 1 100 }
+        T{ ##load-integer f 2 200 }
+        T{ ##load-reference f 3 t }
+    }
+] [
+    {
+        T{ ##load-integer f 1 100 }
+        T{ ##load-integer f 2 200 }
+        T{ ##compare-integer f 3 1 2 cc<= }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 100 }
+        T{ ##load-integer f 2 200 }
+        T{ ##load-reference f 3 f }
+    }
+] [
+    {
+        T{ ##load-integer f 1 100 }
+        T{ ##load-integer f 2 200 }
+        T{ ##compare-integer f 3 1 2 cc= }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 100 }
+        T{ ##load-reference f 2 f }
+    }
+] [
+    {
+        T{ ##load-integer f 1 100 }
+        T{ ##compare-integer-imm f 2 1 123 cc= }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 10 }
+        T{ ##load-integer f 2 20 }
+        T{ ##load-reference f 3 f }
+    }
+] [
+    {
+        T{ ##load-integer f 1 10 }
+        T{ ##load-integer f 2 20 }
+        T{ ##compare-integer f 3 1 2 cc= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 2 }
+        T{ ##load-reference f 3 t }
+    }
+] [
+    {
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 2 }
+        T{ ##compare-integer f 3 1 2 cc/= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 2 }
+        T{ ##load-reference f 3 t }
+    }
+] [
+    {
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 2 }
+        T{ ##compare-integer f 3 1 2 cc< }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 10 }
+        T{ ##load-integer f 2 20 }
+        T{ ##load-reference f 3 f }
+    }
+] [
+    {
+        T{ ##load-integer f 1 10 }
+        T{ ##load-integer f 2 20 }
+        T{ ##compare-integer f 3 2 1 cc< }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-reference f 1 f }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare-integer f 1 0 0 cc< }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##copy f 1 0 any-rep }
+        T{ ##load-reference f 2 f }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##copy f 1 0 any-rep }
+        T{ ##compare-integer f 2 0 1 cc< }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-reference f 1 t }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare-integer f 1 0 0 cc<= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-reference f 1 f }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare-integer f 1 0 0 cc> }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-reference f 1 t }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare-integer f 1 0 0 cc>= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-reference f 1 f }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare-integer f 1 0 0 cc/= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-reference f 1 t }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare-integer f 1 0 0 cc= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 10 }
+        T{ ##load-reference f 2 t }
+    }
+] [
+    {
+        T{ ##load-integer f 1 10 }
+        T{ ##compare-imm f 2 1 10 cc= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 10 }
+        T{ ##load-reference f 2 f }
+    }
+] [
+    {
+        T{ ##load-integer f 1 10 }
+        T{ ##compare-imm f 2 1 20 cc= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 10 }
+        T{ ##load-reference f 2 t }
+    }
+] [
+    {
+        T{ ##load-integer f 1 10 }
+        T{ ##compare-imm f 2 1 100 cc/= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 10 }
+        T{ ##load-reference f 2 f }
+    }
+] [
+    {
+        T{ ##load-integer f 1 10 }
+        T{ ##compare-imm f 2 1 10 cc/= }
+    } value-numbering-step
+] unit-test
+
+cpu x86.32? [
+    [
+        {
+            T{ ##load-reference f 1 + }
+            T{ ##load-reference f 2 f }
+        }
+    ] [
+        {
+            T{ ##load-reference f 1 + }
+            T{ ##compare-imm f 2 1 + cc/= }
+        } value-numbering-step
+    ] unit-test
+
+    [
+        {
+            T{ ##load-reference f 1 + }
+            T{ ##load-reference f 2 t }
+        }
+    ] [
+        {
+            T{ ##load-reference f 1 + }
+            T{ ##compare-imm f 2 1 * cc/= }
+        } value-numbering-step
+    ] unit-test
+
+    [
+        {
+            T{ ##load-reference f 1 + }
+            T{ ##load-reference f 2 t }
+        }
+    ] [
+        {
+            T{ ##load-reference f 1 + }
+            T{ ##compare-imm f 2 1 + cc= }
+        } value-numbering-step
+    ] unit-test
+
+    [
+        {
+            T{ ##load-reference f 1 + }
+            T{ ##load-reference f 2 f }
+        }
+    ] [
+        {
+            T{ ##load-reference f 1 + }
+            T{ ##compare-imm f 2 1 * cc= }
+        } value-numbering-step
+    ] unit-test
+] when
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-reference f 1 t }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare f 1 0 0 cc= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-reference f 1 f }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare f 1 0 0 cc/= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 12 }
+        T{ ##load-reference f 3 t }
+    }
+] [
+    {
+        T{ ##load-integer f 1 12 }
+        T{ ##test-imm f 3 1 13 cc/= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 15 }
+        T{ ##load-reference f 3 f }
+    }
+] [
+    {
+        T{ ##load-integer f 1 15 }
+        T{ ##test-imm f 3 1 16 cc/= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 12 }
+        T{ ##load-reference f 3 f }
+    }
+] [
+    {
+        T{ ##load-integer f 1 12 }
+        T{ ##test-imm f 3 1 13 cc= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 15 }
+        T{ ##load-reference f 3 t }
+    }
+] [
+    {
+        T{ ##load-integer f 1 15 }
+        T{ ##test-imm f 3 1 16 cc= }
+    } value-numbering-step
+] unit-test
+
+! Rewriting a ##test of an ##and into a ##test
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##and f 2 0 1 }
+        T{ ##test f 3 0 1 cc= }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##and f 2 0 1 }
+        T{ ##test f 3 2 2 cc= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##and-imm f 2 0 12 }
+        T{ ##test-imm f 3 0 12 cc= }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##and-imm f 2 0 12 }
+        T{ ##test f 3 2 2 cc= }
+    } value-numbering-step
+] unit-test
+
+! Rewriting ##test into ##test-imm
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 10 }
+        T{ ##test-imm f 2 0 10 cc= }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 10 }
+        T{ ##test f 2 0 1 cc= }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 10 }
+        T{ ##test-imm f 2 0 10 cc= }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 10 }
+        T{ ##test f 2 1 0 cc= }
+    } value-numbering-step trim-temps
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 10 }
+        T{ ##test-imm-branch f 0 10 cc= }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 10 }
+        T{ ##test-branch f 0 1 cc= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 10 }
+        T{ ##test-imm-branch f 0 10 cc= }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 10 }
+        T{ ##test-branch f 1 0 cc= }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 10 }
+        T{ ##test-imm-branch f 0 10 cc= }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 10 }
+        T{ ##test-branch f 1 0 cc= }
+    } value-numbering-step
+] unit-test
+
+! Make sure the immediate fits
+cpu x86.64? [
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-integer f 1 100000000000 }
+            T{ ##test f 2 1 0 cc= }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-integer f 1 100000000000 }
+            T{ ##test f 2 1 0 cc= }
+        } value-numbering-step
+    ] unit-test
+
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-integer f 1 100000000000 }
+            T{ ##test-branch f 1 0 cc= }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-integer f 1 100000000000 }
+            T{ ##test-branch f 1 0 cc= }
+        } value-numbering-step
+    ] unit-test
+] when
+
+! Rewriting ##compare into ##test
+cpu x86? [
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##test f 1 0 0 cc= }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##compare-integer-imm f 1 0 0 cc= }
+        } value-numbering-step
+    ] unit-test
+
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##test f 1 0 0 cc/= }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##compare-integer-imm f 1 0 0 cc/= }
+        } value-numbering-step
+    ] unit-test
+
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##compare-integer-imm f 1 0 0 cc<= }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##compare-integer-imm f 1 0 0 cc<= }
+        } value-numbering-step
+    ] unit-test
+    
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##test-branch f 0 0 cc= }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##compare-integer-imm-branch f 0 0 cc= }
+        } value-numbering-step
+    ] unit-test
+
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##test-branch f 0 0 cc/= }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##compare-integer-imm-branch f 0 0 cc/= }
+        } value-numbering-step
+    ] unit-test
+
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##compare-integer-imm-branch f 0 0 cc<= }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##compare-integer-imm-branch f 0 0 cc<= }
+        } value-numbering-step
+    ] unit-test
+] when
+
+! Reassociation
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##add-imm f 2 0 100 }
+        T{ ##load-integer f 3 50 }
+        T{ ##add-imm f 4 0 150 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##add f 2 0 1 }
+        T{ ##load-integer f 3 50 }
+        T{ ##add f 4 2 3 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##add-imm f 2 0 100 }
+        T{ ##load-integer f 3 50 }
+        T{ ##add-imm f 4 0 150 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##add f 2 1 0 }
+        T{ ##load-integer f 3 50 }
+        T{ ##add f 4 3 2 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##add-imm f 2 0 100 }
+        T{ ##load-integer f 3 50 }
+        T{ ##add-imm f 4 0 50 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##add f 2 0 1 }
+        T{ ##load-integer f 3 50 }
+        T{ ##sub f 4 2 3 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##add-imm f 2 0 -100 }
+        T{ ##load-integer f 3 50 }
+        T{ ##add-imm f 4 0 -150 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##sub f 2 0 1 }
+        T{ ##load-integer f 3 50 }
+        T{ ##sub f 4 2 3 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##mul-imm f 2 0 100 }
+        T{ ##load-integer f 3 50 }
+        T{ ##mul-imm f 4 0 5000 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##mul f 2 0 1 }
+        T{ ##load-integer f 3 50 }
+        T{ ##mul f 4 2 3 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##mul-imm f 2 0 100 }
+        T{ ##load-integer f 3 50 }
+        T{ ##mul-imm f 4 0 5000 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##mul f 2 1 0 }
+        T{ ##load-integer f 3 50 }
+        T{ ##mul f 4 3 2 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##and-imm f 2 0 100 }
+        T{ ##load-integer f 3 50 }
+        T{ ##and-imm f 4 0 32 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##and f 2 0 1 }
+        T{ ##load-integer f 3 50 }
+        T{ ##and f 4 2 3 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##and-imm f 2 0 100 }
+        T{ ##load-integer f 3 50 }
+        T{ ##and-imm f 4 0 32 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##and f 2 1 0 }
+        T{ ##load-integer f 3 50 }
+        T{ ##and f 4 3 2 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##or-imm f 2 0 100 }
+        T{ ##load-integer f 3 50 }
+        T{ ##or-imm f 4 0 118 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##or f 2 0 1 }
+        T{ ##load-integer f 3 50 }
+        T{ ##or f 4 2 3 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##or-imm f 2 0 100 }
+        T{ ##load-integer f 3 50 }
+        T{ ##or-imm f 4 0 118 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##or f 2 1 0 }
+        T{ ##load-integer f 3 50 }
+        T{ ##or f 4 3 2 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##xor-imm f 2 0 100 }
+        T{ ##load-integer f 3 50 }
+        T{ ##xor-imm f 4 0 86 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##xor f 2 0 1 }
+        T{ ##load-integer f 3 50 }
+        T{ ##xor f 4 2 3 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##xor-imm f 2 0 100 }
+        T{ ##load-integer f 3 50 }
+        T{ ##xor-imm f 4 0 86 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 100 }
+        T{ ##xor f 2 1 0 }
+        T{ ##load-integer f 3 50 }
+        T{ ##xor f 4 3 2 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##shl-imm f 1 0 10 }
+        T{ ##shl-imm f 2 0 21 }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##shl-imm f 1 0 10 }
+        T{ ##shl-imm f 2 1 11 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##shl-imm f 1 0 10 }
+        T{ ##shl-imm f 2 1 $[ cell-bits 1 - ] }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##shl-imm f 1 0 10 }
+        T{ ##shl-imm f 2 1 $[ cell-bits 1 - ] }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##sar-imm f 1 0 10 }
+        T{ ##sar-imm f 2 0 21 }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##sar-imm f 1 0 10 }
+        T{ ##sar-imm f 2 1 11 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##sar-imm f 1 0 10 }
+        T{ ##sar-imm f 2 1 $[ cell-bits 1 - ] }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##sar-imm f 1 0 10 }
+        T{ ##sar-imm f 2 1 $[ cell-bits 1 - ] }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##shr-imm f 1 0 10 }
+        T{ ##shr-imm f 2 0 21 }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##shr-imm f 1 0 10 }
+        T{ ##shr-imm f 2 1 11 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##shr-imm f 1 0 10 }
+        T{ ##shr-imm f 2 1 $[ cell-bits 1 - ] }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##shr-imm f 1 0 10 }
+        T{ ##shr-imm f 2 1 $[ cell-bits 1 - ] }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##shr-imm f 1 0 10 }
+        T{ ##sar-imm f 2 1 11 }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##shr-imm f 1 0 10 }
+        T{ ##sar-imm f 2 1 11 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+! Distributive law
+2 \ vreg-counter set-global
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##add-imm f 1 0 10 }
+        T{ ##shl-imm f 3 0 2 }
+        T{ ##add-imm f 2 3 40 }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##add-imm f 1 0 10 }
+        T{ ##shl-imm f 2 1 2 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##add-imm f 1 0 10 }
+        T{ ##mul-imm f 4 0 3 }
+        T{ ##add-imm f 2 4 30 }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##add-imm f 1 0 10 }
+        T{ ##mul-imm f 2 1 3 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##add-imm f 1 0 -10 }
+        T{ ##shl-imm f 5 0 2 }
+        T{ ##add-imm f 2 5 -40 }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##sub-imm f 1 0 10 }
+        T{ ##shl-imm f 2 1 2 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##add-imm f 1 0 -10 }
+        T{ ##mul-imm f 6 0 3 }
+        T{ ##add-imm f 2 6 -30 }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##sub-imm f 1 0 10 }
+        T{ ##mul-imm f 2 1 3 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+! Simplification
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##copy f 3 0 any-rep }
+        T{ ##replace f 3 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##add-imm f 3 0 0 }
+        T{ ##replace f 3 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##copy f 3 0 any-rep }
+        T{ ##replace f 3 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##or-imm f 3 0 0 }
+        T{ ##replace f 3 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##copy f 3 0 any-rep }
+        T{ ##replace f 3 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##xor-imm f 3 0 0 }
+        T{ ##replace f 3 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##and-imm f 1 0 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##copy f 1 0 any-rep }
+        T{ ##replace f 1 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##and-imm f 1 0 -1 }
+        T{ ##replace f 1 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##copy f 1 0 any-rep }
+        T{ ##replace f 1 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##and f 1 0 0 }
+        T{ ##replace f 1 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##copy f 1 0 any-rep }
+        T{ ##replace f 1 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##or-imm f 1 0 0 }
+        T{ ##replace f 1 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 -1 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##or-imm f 1 0 -1 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##copy f 1 0 any-rep }
+        T{ ##replace f 1 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##or f 1 0 0 }
+        T{ ##replace f 1 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##copy f 1 0 any-rep }
+        T{ ##replace f 1 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##xor-imm f 1 0 0 }
+        T{ ##replace f 1 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##not f 1 0 }
+        T{ ##replace f 1 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##xor-imm f 1 0 -1 }
+        T{ ##replace f 1 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##xor f 1 0 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##copy f 2 0 any-rep }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##mul-imm f 2 0 1 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##copy f 2 0 any-rep }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##shl-imm f 2 0 0 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##copy f 2 0 any-rep }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##shr-imm f 2 0 0 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##copy f 2 0 any-rep }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##sar-imm f 2 0 0 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+! Constant folding
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 3 }
+        T{ ##load-integer f 3 4 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 3 }
+        T{ ##add f 3 1 2 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 3 }
+        T{ ##load-integer f 3 -2 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 3 }
+        T{ ##sub f 3 1 2 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 2 }
+        T{ ##load-integer f 2 3 }
+        T{ ##load-integer f 3 6 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 2 }
+        T{ ##load-integer f 2 3 }
+        T{ ##mul f 3 1 2 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 2 }
+        T{ ##load-integer f 2 1 }
+        T{ ##load-integer f 3 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 2 }
+        T{ ##load-integer f 2 1 }
+        T{ ##and f 3 1 2 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 2 }
+        T{ ##load-integer f 2 1 }
+        T{ ##load-integer f 3 3 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 2 }
+        T{ ##load-integer f 2 1 }
+        T{ ##or f 3 1 2 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 2 }
+        T{ ##load-integer f 2 3 }
+        T{ ##load-integer f 3 1 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 2 }
+        T{ ##load-integer f 2 3 }
+        T{ ##xor f 3 1 2 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 3 8 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 1 }
+        T{ ##shl-imm f 3 1 3 }
+    } value-numbering-step
+] unit-test
+
+cell 8 = [
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-integer f 1 -1 }
+            T{ ##load-integer f 3 HEX: ffffffffffff }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-integer f 1 -1 }
+            T{ ##shr-imm f 3 1 16 }
+        } value-numbering-step
+    ] unit-test
+] when
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 -8 }
+        T{ ##load-integer f 3 -4 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 -8 }
+        T{ ##sar-imm f 3 1 1 }
+    } value-numbering-step
+] unit-test
+
+cell 8 = [
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-integer f 1 65536 }
+            T{ ##load-integer f 2 140737488355328 }
+            T{ ##add f 3 0 2 }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-integer f 1 65536 }
+            T{ ##shl-imm f 2 1 31 }
+            T{ ##add f 3 0 2 }
+        } value-numbering-step
+    ] unit-test
+
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-integer f 2 140737488355328 }
+            T{ ##add f 3 0 2 }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-integer f 2 140737488355328 }
+            T{ ##add f 3 0 2 }
+        } value-numbering-step
+    ] unit-test
+
+    [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-integer f 2 2147483647 }
+            T{ ##add-imm f 3 0 2147483647 }
+            T{ ##add-imm f 4 3 2147483647 }
+        }
+    ] [
+        {
+            T{ ##peek f 0 D 0 }
+            T{ ##load-integer f 2 2147483647 }
+            T{ ##add f 3 0 2 }
+            T{ ##add f 4 3 2 }
+        } value-numbering-step
+    ] unit-test
+] when
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 -1 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 1 }
+        T{ ##neg f 2 1 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 -2 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 1 1 }
+        T{ ##not f 2 1 }
+    } value-numbering-step
+] unit-test
+
+! ##tagged>integer constant folding
+[
+    {
+        T{ ##load-reference f 1 f }
+        T{ ##load-integer f 2 $[ \ f type-number ] }
+        T{ ##copy f 3 2 any-rep }
+    }
+] [
+    {
+        T{ ##load-reference f 1 f }
+        T{ ##tagged>integer f 2 1 }
+        T{ ##and-imm f 3 2 15 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 100 }
+        T{ ##load-integer f 2 $[ 100 tag-fixnum ] }
+        T{ ##load-integer f 3 $[ 100 tag-fixnum 1 + ] }
+    }
+] [
+    {
+        T{ ##load-integer f 1 100 }
+        T{ ##tagged>integer f 2 1 }
+        T{ ##add-imm f 3 2 1 }
+    } value-numbering-step
+] unit-test
+
+! Alien boxing and unboxing
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##box-alien f 1 0 }
+        T{ ##copy f 2 0 any-rep }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##box-alien f 1 0 }
+        T{ ##unbox-alien f 2 1 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##box-alien f 1 0 }
+        T{ ##copy f 2 0 any-rep }
+        T{ ##replace f 2 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##box-alien f 1 0 }
+        T{ ##unbox-any-c-ptr f 2 1 }
+        T{ ##replace f 2 D 0 }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 2 0 }
+        T{ ##copy f 1 0 any-rep }
+        T{ ##replace f 1 D 0 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 2 0 }
+        T{ ##box-displaced-alien f 1 2 0 c-ptr }
+        T{ ##replace f 1 D 0 }
+    } value-numbering-step
+] unit-test
+
+3 vreg-counter set-global
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 2 16 }
+        T{ ##box-displaced-alien f 1 2 0 c-ptr }
+        T{ ##unbox-any-c-ptr f 4 0 }
+        T{ ##add-imm f 3 4 16 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 2 16 }
+        T{ ##box-displaced-alien f 1 2 0 c-ptr }
+        T{ ##unbox-any-c-ptr f 3 1 }
+    } value-numbering-step
+] unit-test
+
+4 vreg-counter set-global
+
+[
+    {
+        T{ ##box-alien f 0 1 }
+        T{ ##load-integer f 2 16 }
+        T{ ##box-displaced-alien f 3 2 0 c-ptr }
+        T{ ##copy f 5 1 any-rep }
+        T{ ##add-imm f 4 5 16 }
+    }
+] [
+    {
+        T{ ##box-alien f 0 1 }
+        T{ ##load-integer f 2 16 }
+        T{ ##box-displaced-alien f 3 2 0 c-ptr }
+        T{ ##unbox-any-c-ptr f 4 3 }
+    } value-numbering-step
+] unit-test
+
+3 vreg-counter set-global
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 2 0 }
+        T{ ##copy f 3 0 any-rep }
+        T{ ##replace f 3 D 1 }
+    }
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-integer f 2 0 }
+        T{ ##box-displaced-alien f 3 2 0 c-ptr }
+        T{ ##replace f 3 D 1 }
+    } value-numbering-step
+] unit-test
+
+! Various SIMD simplifications
+[
+    {
+        T{ ##vector>scalar f 1 0 float-4-rep }
+        T{ ##copy f 2 0 any-rep }
+    }
+] [
+    {
+        T{ ##vector>scalar f 1 0 float-4-rep }
+        T{ ##scalar>vector f 2 1 float-4-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##copy f 1 0 any-rep }
+    }
+] [
+    {
+        T{ ##shuffle-vector-imm f 1 0 { 0 1 2 3 } float-4-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##shuffle-vector-imm f 1 0 { 1 2 3 0 } float-4-rep }
+        T{ ##shuffle-vector-imm f 2 0 { 0 2 3 1 } float-4-rep }
+    }
+] [
+    {
+        T{ ##shuffle-vector-imm f 1 0 { 1 2 3 0 } float-4-rep }
+        T{ ##shuffle-vector-imm f 2 1 { 3 1 2 0 } float-4-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##shuffle-vector-imm f 1 0 { 1 2 3 0 } float-4-rep }
+        T{ ##shuffle-vector-imm f 2 1 { 1 0 } double-2-rep }
+    }
+] [
+    {
+        T{ ##shuffle-vector-imm f 1 0 { 1 2 3 0 } float-4-rep }
+        T{ ##shuffle-vector-imm f 2 1 { 1 0 } double-2-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 0 55 }
+        T{ ##load-reference f 1 B{ 55 0 0 0  55 0 0 0  55 0 0 0  55 0 0 0 } }
+        T{ ##load-reference f 2 B{ 55 0 0 0  55 0 0 0  55 0 0 0  55 0 0 0 } }
+    }
+] [
+    {
+        T{ ##load-integer f 0 55 }
+        T{ ##scalar>vector f 1 0 int-4-rep }
+        T{ ##shuffle-vector-imm f 2 1 { 0 0 0 0 } float-4-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-reference f 0 1.25 }
+        T{ ##load-reference f 1 B{ 0 0 160 63 0 0 160 63 0 0 160 63 0 0 160 63 } }
+        T{ ##load-reference f 2 B{ 0 0 160 63 0 0 160 63 0 0 160 63 0 0 160 63 } }
+    }
+] [
+    {
+        T{ ##load-reference f 0 1.25 }
+        T{ ##scalar>vector f 1 0 float-4-rep }
+        T{ ##shuffle-vector-imm f 2 1 { 0 0 0 0 } float-4-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-reference f 0 1.25 }
+        T{ ##load-reference f 1 B{ 0 0 160 63 0 0 160 63 0 0 160 63 0 0 160 63 } }
+        T{ ##load-reference f 2 B{ 0 0 160 63 0 0 160 63 0 0 160 63 0 0 160 63 } }
+    }
+] [
+    {
+        T{ ##load-reference f 0 1.25 }
+        T{ ##scalar>vector f 1 0 float-4-rep }
+        T{ ##shuffle-vector-imm f 2 1 { 0 0 0 0 } float-4-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 0 55 }
+        T{ ##load-reference f 1 B{ 55 0 55 0 55 0 55 0 55 0 55 0 55 0 55 0 } }
+        T{ ##load-reference f 2 B{ 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 } }
+        T{ ##load-reference f 3 B{ 0 55 0 55 0 55 0 55 0 55 0 55 0 55 0 55 } }
+    }
+] [
+    {
+        T{ ##load-integer f 0 55 }
+        T{ ##scalar>vector f 1 0 short-8-rep }
+        T{ ##load-reference f 2 B{ 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 } }
+        T{ ##shuffle-vector f 3 1 2 float-4-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-reference f 0 1.25 }
+        T{ ##load-reference f 2 3.75 }
+        T{ ##load-reference f 4 B{ 0 0 0 0 0 0 244 63 0 0 0 0 0 0 14 64 } }
+    }
+] [
+    {
+        T{ ##load-reference f 0 1.25 }
+        T{ ##load-reference f 2 3.75 }
+        T{ ##gather-vector-2 f 4 0 2 double-2-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 0 125 }
+        T{ ##load-integer f 2 375 }
+        T{ ##load-reference f 4 B{ 125 0 0 0 0 0 0 0 119 1 0 0 0 0 0 0 } }
+    }
+] [
+    {
+        T{ ##load-integer f 0 125 }
+        T{ ##load-integer f 2 375 }
+        T{ ##gather-vector-2 f 4 0 2 longlong-2-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-reference f 0 1.25 }
+        T{ ##load-reference f 1 2.50 }
+        T{ ##load-reference f 2 3.75 }
+        T{ ##load-reference f 3 5.00 }
+        T{ ##load-reference f 4 B{ 0 0 160 63 0 0 32 64 0 0 112 64 0 0 160 64 } }
+    }
+] [
+    {
+        T{ ##load-reference f 0 1.25 }
+        T{ ##load-reference f 1 2.50 }
+        T{ ##load-reference f 2 3.75 }
+        T{ ##load-reference f 3 5.00 }
+        T{ ##gather-vector-4 f 4 0 1 2 3 float-4-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 0 125 }
+        T{ ##load-integer f 1 250 }
+        T{ ##load-integer f 2 375 }
+        T{ ##load-integer f 3 500 }
+        T{ ##load-reference f 4 B{ 125 0 0 0 250 0 0 0 119 1 0 0 244 1 0 0 } }
+    }
+] [
+    {
+        T{ ##load-integer f 0 125 }
+        T{ ##load-integer f 1 250 }
+        T{ ##load-integer f 2 375 }
+        T{ ##load-integer f 3 500 }
+        T{ ##gather-vector-4 f 4 0 1 2 3 int-4-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##zero-vector f 2 float-4-rep }
+    }
+] [
+    {
+        T{ ##xor-vector f 2 1 1 float-4-rep }
+    } value-numbering-step
+] unit-test
+
+! NOT x AND y => x ANDN y
+
+[
+    {
+        T{ ##fill-vector f 3 float-4-rep }
+        T{ ##xor-vector  f 4 0 3 float-4-rep }
+        T{ ##andn-vector f 5 0 1 float-4-rep }
+    }
+] [
+    {
+        T{ ##fill-vector f 3 float-4-rep }
+        T{ ##xor-vector  f 4 0 3 float-4-rep }
+        T{ ##and-vector  f 5 4 1 float-4-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##not-vector  f 4 0 float-4-rep }
+        T{ ##andn-vector f 5 0 1 float-4-rep }
+    }
+] [
+    {
+        T{ ##not-vector  f 4 0 float-4-rep }
+        T{ ##and-vector  f 5 4 1 float-4-rep }
+    } value-numbering-step
+] unit-test
+
+! x AND NOT y => y ANDN x
+
+[
+    {
+        T{ ##fill-vector f 3 float-4-rep }
+        T{ ##xor-vector  f 4 0 3 float-4-rep }
+        T{ ##andn-vector f 5 0 1 float-4-rep }
+    }
+] [
+    {
+        T{ ##fill-vector f 3 float-4-rep }
+        T{ ##xor-vector  f 4 0 3 float-4-rep }
+        T{ ##and-vector  f 5 1 4 float-4-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##not-vector  f 4 0 float-4-rep }
+        T{ ##andn-vector f 5 0 1 float-4-rep }
+    }
+] [
+    {
+        T{ ##not-vector  f 4 0 float-4-rep }
+        T{ ##and-vector  f 5 1 4 float-4-rep }
+    } value-numbering-step
+] unit-test
+
+! NOT x ANDN y => x AND y
+
+[
+    {
+        T{ ##fill-vector f 3 float-4-rep }
+        T{ ##xor-vector  f 4 0 3 float-4-rep }
+        T{ ##and-vector  f 5 0 1 float-4-rep }
+    }
+] [
+    {
+        T{ ##fill-vector f 3 float-4-rep }
+        T{ ##xor-vector  f 4 0 3 float-4-rep }
+        T{ ##andn-vector f 5 4 1 float-4-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##not-vector  f 4 0 float-4-rep }
+        T{ ##and-vector  f 5 0 1 float-4-rep }
+    }
+] [
+    {
+        T{ ##not-vector  f 4 0 float-4-rep }
+        T{ ##andn-vector f 5 4 1 float-4-rep }
+    } value-numbering-step
+] unit-test
+
+! AND <=> ANDN
+
+[
+    {
+        T{ ##fill-vector f 3 float-4-rep }
+        T{ ##xor-vector  f 4 0 3 float-4-rep }
+        T{ ##andn-vector f 5 0 1 float-4-rep }
+        T{ ##and-vector  f 6 0 2 float-4-rep }
+        T{ ##or-vector   f 7 5 6 float-4-rep }
+    }
+] [
+    {
+        T{ ##fill-vector f 3 float-4-rep }
+        T{ ##xor-vector  f 4 0 3 float-4-rep }
+        T{ ##and-vector  f 5 4 1 float-4-rep }
+        T{ ##andn-vector f 6 4 2 float-4-rep }
+        T{ ##or-vector   f 7 5 6 float-4-rep }
+    } value-numbering-step
+] unit-test
+
+[
+    {
+        T{ ##not-vector  f 4 0   float-4-rep }
+        T{ ##andn-vector f 5 0 1 float-4-rep }
+        T{ ##and-vector  f 6 0 2 float-4-rep }
+        T{ ##or-vector   f 7 5 6 float-4-rep }
+    }
+] [
+    {
+        T{ ##not-vector  f 4 0   float-4-rep }
+        T{ ##and-vector  f 5 4 1 float-4-rep }
+        T{ ##andn-vector f 6 4 2 float-4-rep }
+        T{ ##or-vector   f 7 5 6 float-4-rep }
+    } value-numbering-step
+] unit-test
+
+! Branch folding
+: test-branch-folding ( insns -- insns' n )
+    <basic-block>
+    [ V{ 0 1 } clone >>successors basic-block set value-numbering-step ] keep
+    successors>> first ;
+
+[
+    {
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 2 }
+        T{ ##branch }
+    }
+    1
+] [
+    {
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 2 }
+        T{ ##compare-branch f 1 2 cc= }
+    } test-branch-folding
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 2 }
+        T{ ##branch }
+    }
+    0
+] [
+    {
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 2 }
+        T{ ##compare-branch f 1 2 cc/= }
+    } test-branch-folding
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 2 }
+        T{ ##branch }
+    }
+    0
+] [
+    {
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 2 }
+        T{ ##compare-integer-branch f 1 2 cc< }
+    } test-branch-folding
+] unit-test
+
+[
+    {
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 2 }
+        T{ ##branch }
+    }
+    1
+] [
+    {
+        T{ ##load-integer f 1 1 }
+        T{ ##load-integer f 2 2 }
+        T{ ##compare-integer-branch f 2 1 cc< }
+    } test-branch-folding
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##branch }
+    }
+    1
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare-integer-branch f 0 0 cc< }
+    } test-branch-folding
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##branch }
+    }
+    0
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare-integer-branch f 0 0 cc<= }
+    } test-branch-folding
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##branch }
+    }
+    1
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare-integer-branch f 0 0 cc> }
+    } test-branch-folding
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##branch }
+    }
+    0
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare-integer-branch f 0 0 cc>= }
+    } test-branch-folding
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##branch }
+    }
+    0
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare-integer-branch f 0 0 cc= }
+    } test-branch-folding
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##branch }
+    }
+    1
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare-integer-branch f 0 0 cc/= }
+    } test-branch-folding
+] unit-test
+
+[
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##load-reference f 1 t }
+        T{ ##branch }
+    }
+    0
+] [
+    {
+        T{ ##peek f 0 D 0 }
+        T{ ##compare f 1 0 0 cc<= }
+        T{ ##compare-imm-branch f 1 f cc/= }
+    } test-branch-folding
+] unit-test
+
+! More branch folding tests
+V{ T{ ##branch } } 0 test-bb
+
+V{
+    T{ ##peek f 0 D 0 }
+    T{ ##compare-integer-branch f 0 0 cc< }
+} 1 test-bb
+
+V{
+    T{ ##load-integer f 1 1 }
+    T{ ##branch }
+} 2 test-bb
+
+V{
+    T{ ##load-integer f 2 2 }
+    T{ ##branch }
+} 3 test-bb
+
+V{
+    T{ ##phi f 3 H{ { 2 1 } { 3 2 } } }
+    T{ ##replace f 3 D 0 }
+    T{ ##return }
+} 4 test-bb
+
+test-diamond
+
+[ ] [
+    cfg new 0 get >>entry dup cfg set
+    value-numbering
+    select-representations
+    destruct-ssa drop
+] unit-test
+
+[ 1 ] [ 1 get successors>> length ] unit-test
+
+[ t ] [ 1 get successors>> first 3 get eq? ] unit-test
+
+[ 2 ] [ 4 get instructions>> length ] unit-test
+
+V{
+    T{ ##peek f 0 D 0 }
+    T{ ##branch }
+} 0 test-bb
+
+V{
+    T{ ##peek f 1 D 1 }
+    T{ ##compare-integer-branch f 1 1 cc< }
+} 1 test-bb
+
+V{
+    T{ ##copy f 2 0 any-rep }
+    T{ ##branch }
+} 2 test-bb
+
+V{
+    T{ ##phi f 3 H{ { 1 1 } { 2 0 } } }
+    T{ ##branch }
+} 3 test-bb
+
+V{
+    T{ ##replace f 3 D 0 }
+    T{ ##return }
+} 4 test-bb
+
+test-diamond
+
+[ ] [
+    cfg new 0 get >>entry
+    value-numbering
+    eliminate-dead-code
+    drop
+] unit-test
+
+[ t ] [ 1 get successors>> first 3 get eq? ] unit-test
+
+[ 1 ] [ 3 get instructions>> first inputs>> assoc-size ] unit-test
+
+V{ T{ ##prologue } T{ ##branch } } 0 test-bb
+
+V{
+    T{ ##peek { dst 15 } { loc D 0 } }
+    T{ ##copy { dst 16 } { src 15 } { rep any-rep } }
+    T{ ##copy { dst 17 } { src 15 } { rep any-rep } }
+    T{ ##copy { dst 18 } { src 15 } { rep any-rep } }
+    T{ ##copy { dst 19 } { src 15 } { rep any-rep } }
+    T{ ##compare
+        { dst 20 }
+        { src1 18 }
+        { src2 19 }
+        { cc cc= }
+        { temp 22 }
+    }
+    T{ ##copy { dst 21 } { src 20 } { rep any-rep } }
+    T{ ##compare-imm-branch
+        { src1 21 }
+        { src2 f }
+        { cc cc/= }
+    }
+} 1 test-bb
+
+V{
+    T{ ##copy { dst 23 } { src 15 } { rep any-rep } }
+    T{ ##copy { dst 24 } { src 15 } { rep any-rep } }
+    T{ ##load-reference { dst 25 } { obj t } }
+    T{ ##branch }
+} 2 test-bb
+
+V{
+    T{ ##replace { src 25 } { loc D 0 } }
+    T{ ##epilogue }
+    T{ ##return }
+} 3 test-bb
+
+V{
+    T{ ##copy { dst 26 } { src 15 } { rep any-rep } }
+    T{ ##copy { dst 27 } { src 15 } { rep any-rep } }
+    T{ ##add
+        { dst 28 }
+        { src1 26 }
+        { src2 27 }
+    }
+    T{ ##branch }
+} 4 test-bb
+
+V{
+    T{ ##replace { src 28 } { loc D 0 } }
+    T{ ##epilogue }
+    T{ ##return }
+} 5 test-bb
+
+0 1 edge
+1 { 2 4 } edges
+2 3 edge
+4 5 edge
+
+[ ] [
+    cfg new 0 get >>entry
+    value-numbering eliminate-dead-code drop
+] unit-test
+
+[ f ] [ 1 get instructions>> [ ##peek? ] any? ] unit-test
+
+! Slot addressing optimization
+cpu x86? [
+    [
+        V{
+            T{ ##peek f 0 D 0 }
+            T{ ##peek f 1 D 1 }
+            T{ ##add-imm f 2 1 2 }
+            T{ ##slot f 3 0 1 $[ cell log2 ] $[ 7 2 cells - ] }
+        }
+    ] [
+        V{
+            T{ ##peek f 0 D 0 }
+            T{ ##peek f 1 D 1 }
+            T{ ##add-imm f 2 1 2 }
+            T{ ##slot f 3 0 2 $[ cell log2 ] 7 }
+        } value-numbering-step
+    ] unit-test
+] when
+
+! Alien addressing optimization
+
+! Base offset fusion on ##load/store-memory-imm
+[
+    V{
+        T{ ##peek f 1 D 0 }
+        T{ ##tagged>integer f 2 1 }
+        T{ ##add-imm f 3 2 10 }
+        T{ ##load-memory-imm f 4 2 10 int-rep c:uchar }
+    }
+] [
+    V{
+        T{ ##peek f 1 D 0 }
+        T{ ##tagged>integer f 2 1 }
+        T{ ##add-imm f 3 2 10 }
+        T{ ##load-memory-imm f 4 3 0 int-rep c:uchar }
+    } value-numbering-step
+] unit-test
+
+[
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##add-imm f 4 3 10 }
+        T{ ##store-memory-imm f 2 3 10 int-rep c:uchar }
+    }
+] [
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##add-imm f 4 3 10 }
+        T{ ##store-memory-imm f 2 4 0 int-rep c:uchar }
+    } value-numbering-step
+] unit-test
+
+! Displacement fusion on ##load/store-memory-imm
+[
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##add f 4 2 3 }
+        T{ ##load-memory f 5 2 3 0 0 int-rep c:uchar }
+    }
+] [
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##add f 4 2 3 }
+        T{ ##load-memory-imm f 5 4 0 int-rep c:uchar }
+    } value-numbering-step
+] unit-test
+
+[
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##add f 4 2 3 }
+        T{ ##store-memory f 5 2 3 0 0 int-rep c:uchar }
+    }
+] [
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##add f 4 2 3 }
+        T{ ##store-memory-imm f 5 4 0 int-rep c:uchar }
+    } value-numbering-step
+] unit-test
+
+! Base offset fusion on ##load/store-memory -- only on x86
+cpu x86?
+[
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##add-imm f 4 2 31337 }
+        T{ ##load-memory f 5 2 3 0 31337 int-rep c:uchar }
+    }
+]
+[
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##add-imm f 4 2 31337 }
+        T{ ##load-memory f 5 4 3 0 0 int-rep c:uchar }
+    }
+] ?
+[
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##add-imm f 4 2 31337 }
+        T{ ##load-memory f 5 4 3 0 0 int-rep c:uchar }
+    } value-numbering-step
+] unit-test
+
+! Displacement offset fusion on ##load/store-memory -- only on x86
+cpu x86?
+[
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##add-imm f 4 3 31337 }
+        T{ ##load-memory f 5 2 3 0 31338 int-rep c:uchar }
+    }
+]
+[
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##add-imm f 4 3 31337 }
+        T{ ##load-memory f 5 2 4 0 1 int-rep c:uchar }
+    }
+] ?
+[
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##add-imm f 4 3 31337 }
+        T{ ##load-memory f 5 2 4 0 1 int-rep c:uchar }
+    } value-numbering-step
+] unit-test
+
+! Displacement offset fusion should not occur on
+! ##load/store-memory with non-zero scale
+[ ] [
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##add-imm f 4 3 10 }
+        T{ ##load-memory f 5 2 4 1 1 int-rep c:uchar }
+    } dup value-numbering-step assert=
+] unit-test
+
+! Scale fusion on ##load/store-memory
+cpu x86?
+[
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##shl-imm f 4 3 2 }
+        T{ ##load-memory f 5 2 3 2 0 int-rep c:uchar }
+    }
+]
+[
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##shl-imm f 4 3 2 }
+        T{ ##load-memory f 5 2 4 0 0 int-rep c:uchar }
+    }
+] ?
+[
+    V{
+        T{ ##peek f 0 D 0 }
+        T{ ##peek f 1 D 1 }
+        T{ ##tagged>integer f 2 0 }
+        T{ ##tagged>integer f 3 1 }
+        T{ ##shl-imm f 4 3 2 }
+        T{ ##load-memory f 5 2 4 0 0 int-rep c:uchar }
+    } value-numbering-step
+] unit-test
+
+cpu x86? [
+    ! Don't do scale fusion if there's already a scale
+    [ ] [
+        V{
+            T{ ##peek f 0 D 0 }
+            T{ ##peek f 1 D 1 }
+            T{ ##tagged>integer f 2 0 }
+            T{ ##tagged>integer f 3 1 }
+            T{ ##shl-imm f 4 3 2 }
+            T{ ##load-memory f 5 2 4 1 0 int-rep c:uchar }
+        } dup value-numbering-step assert=
+    ] unit-test
+
+    ! Don't do scale fusion if the scale factor is out of range
+    [ ] [
+        V{
+            T{ ##peek f 0 D 0 }
+            T{ ##peek f 1 D 1 }
+            T{ ##tagged>integer f 2 0 }
+            T{ ##tagged>integer f 3 1 }
+            T{ ##shl-imm f 4 3 4 }
+            T{ ##load-memory f 5 2 4 0 0 int-rep c:uchar }
+        } dup value-numbering-step assert=
+    ] unit-test
+] when
diff --git a/extra/compiler/cfg/gvn/gvn.factor b/extra/compiler/cfg/gvn/gvn.factor
new file mode 100644 (file)
index 0000000..aca40f5
--- /dev/null
@@ -0,0 +1,149 @@
+! Copyright (C) 2008, 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: namespaces arrays assocs kernel accessors fry grouping
+sorting sets sequences locals
+cpu.architecture
+sequences.deep
+compiler.cfg
+compiler.cfg.rpo
+compiler.cfg.def-use
+compiler.cfg.utilities
+compiler.cfg.instructions
+compiler.cfg.gvn.alien
+compiler.cfg.gvn.comparisons
+compiler.cfg.gvn.graph
+compiler.cfg.gvn.math
+compiler.cfg.gvn.rewrite
+compiler.cfg.gvn.slots
+compiler.cfg.gvn.misc
+compiler.cfg.gvn.expressions ;
+IN: compiler.cfg.gvn
+
+GENERIC: process-instruction ( insn -- insn' )
+
+: redundant-instruction ( insn vn -- insn' )
+    [ dst>> ] dip [ swap set-vn ] [ <copy> ] 2bi ;
+
+:: useful-instruction ( insn expr -- insn' )
+    insn dst>> :> vn
+    vn vn set-vn
+    vn expr exprs>vns get set-at
+    insn vn vns>insns get set-at
+    insn ;
+
+: check-redundancy ( insn -- insn' )
+    dup >expr dup exprs>vns get at
+    [ redundant-instruction ] [ useful-instruction ] ?if ;
+
+M: insn process-instruction
+    dup rewrite [ process-instruction ] [ ] ?if ;
+
+M: foldable-insn process-instruction
+    dup rewrite
+    [ process-instruction ]
+    [ dup defs-vregs length 1 = [ check-redundancy ] when ] ?if ;
+
+M: ##copy process-instruction
+    dup [ src>> vreg>vn ] [ dst>> ] bi set-vn ;
+
+M: ##phi rewrite
+    [ dst>> ] [ inputs>> values [ vreg>vn ] map ] bi
+    dup sift
+    dup all-equal?  [
+        nip
+        [ drop f ]
+        [ first <copy> ] if-empty
+    ] [ 3drop f ] if ;
+
+M: ##phi process-instruction
+    dup rewrite
+    [ process-instruction ] [ check-redundancy ] ?if ;
+
+M: ##phi >expr
+    inputs>> values [ vreg>vn ] map \ ##phi prefix ;
+
+M: array process-instruction
+    [ process-instruction ] map ;
+
+: value-numbering-step ( insns -- insns' )
+    init-value-graph
+    ! [ process-instruction ] map flatten ;
+
+    ! idea: let rewrite do the constant/copy propagation (as
+    ! that eventually leads to better VNs), but don't actually
+    ! use them here, since changing the CFG mid-optimistic-GVN
+    ! won't be sound
+    dup [ process-instruction drop ] each ;
+
+: value-numbering ( cfg -- cfg )
+    dup
+    init-gvn
+    '[
+        changed? off
+        _ [ value-numbering-step ] simple-optimization
+        changed? get
+    ] loop
+
+    dup [ init-value-graph [ process-instruction ] map flatten ] simple-optimization
+    cfg-changed predecessors-changed ;
+
+USING: io math math.private prettyprint tools.annotations
+compiler.cfg.debugger
+compiler.cfg.graphviz
+compiler.cfg.tco
+compiler.cfg.useless-conditionals
+compiler.cfg.branch-splitting
+compiler.cfg.block-joining
+compiler.cfg.height
+compiler.cfg.ssa.construction
+compiler.cfg.alias-analysis
+compiler.cfg.copy-prop
+compiler.cfg.dce
+compiler.cfg.finalization ;
+
+SYMBOL: gvn-test
+
+[ 0 100 [ 1 fixnum+fast ] times ]
+test-builder first [
+    optimize-tail-calls
+    delete-useless-conditionals
+    split-branches
+    join-blocks
+    normalize-height
+    construct-ssa
+    alias-analysis
+] with-cfg gvn-test set-global
+
+: watch-gvn ( -- )
+    \ value-numbering-step
+    [
+        '[
+            _ call
+            "Basic block #" write basic-block get number>> .
+            "vregs>gvns: "  write vregs>gvns  get .
+            "vregs>vns: "   write vregs>vns   get .
+            "exprs>vns: "   write exprs>vns   get .
+            "vns>insns: "   write vns>insns   get .
+            "\n---\n" print
+        ]
+    ] annotate ;
+
+: reset-gvn ( -- )
+    \ value-numbering-step reset ;
+
+: test-gvn ( -- )
+    watch-gvn
+    gvn-test get-global [
+        dup "Before GVN" "1" (cfgviz)
+        value-numbering
+        dup "After GVN" "2" (cfgviz)
+        copy-propagation
+        dup "After CP" "3" (cfgviz)
+        eliminate-dead-code
+        dup "After DCE" "4" (cfgviz)
+        finalize-cfg
+        dup "Final CFG" "5" (cfgviz)
+        drop
+    ] with-cfg
+    reset-gvn ;
+
diff --git a/extra/compiler/cfg/gvn/math/authors.txt b/extra/compiler/cfg/gvn/math/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/extra/compiler/cfg/gvn/math/math.factor b/extra/compiler/cfg/gvn/math/math.factor
new file mode 100644 (file)
index 0000000..63993a8
--- /dev/null
@@ -0,0 +1,287 @@
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators combinators.short-circuit
+cpu.architecture fry kernel layouts locals make math sequences
+compiler.cfg.instructions
+compiler.cfg.registers
+compiler.cfg.utilities
+compiler.cfg.gvn.folding
+compiler.cfg.gvn.graph
+compiler.cfg.gvn.rewrite ;
+IN: compiler.cfg.gvn.math
+
+: f-insn? ( insn -- ? )
+    { [ ##load-reference? ] [ obj>> not ] } 1&& ; inline
+
+: zero-insn? ( insn -- ? )
+    { [ ##load-integer? ] [ val>> 0 = ] } 1&& ; inline
+
+M: ##tagged>integer rewrite
+    [ dst>> ] [ src>> vreg>insn ] bi {
+        { [ dup ##load-integer? ] [ val>> tag-fixnum \ ##load-integer new-insn ] }
+        { [ dup f-insn? ] [ drop \ f type-number \ ##load-integer new-insn ] }
+        [ 2drop f ]
+    } cond ;
+
+: self-inverse ( insn -- insn' )
+    [ dst>> ] [ src>> vreg>insn src>> ] bi <copy> ;
+
+: identity ( insn -- insn' )
+    [ dst>> ] [ src1>> ] bi <copy> ;
+
+M: ##neg rewrite
+    {
+        { [ dup src>> vreg>insn ##neg? ] [ self-inverse ] }
+        { [ dup unary-constant-fold? ] [ unary-constant-fold ] }
+        [ drop f ]
+    } cond ;
+
+M: ##not rewrite
+    {
+        { [ dup src>> vreg>insn ##not? ] [ self-inverse ] }
+        { [ dup unary-constant-fold? ] [ unary-constant-fold ] }
+        [ drop f ]
+    } cond ;
+
+! Reassociation converts
+! ## *-imm 2 1 X
+! ## *-imm 3 2 Y
+! into
+! ## *-imm 3 1 (X $ Y)
+! If * is associative, then $ is the same operation as *.
+! In the case of shifts, $ is addition.
+: (reassociate) ( insn -- dst src1 src2' src2'' )
+    {
+        [ dst>> ]
+        [ src1>> vreg>insn [ src1>> ] [ src2>> ] bi ]
+        [ src2>> ]
+    } cleave ; inline
+
+: reassociate ( insn -- dst src1 src2 )
+    [ (reassociate) ] keep binary-constant-fold* ;
+
+: ?new-insn ( dst src1 src2 ? class -- insn/f )
+    '[ _ new-insn ] [ 3drop f ] if ; inline
+
+: reassociate-arithmetic ( insn new-insn -- insn/f )
+    [ reassociate dup immediate-arithmetic? ] dip ?new-insn ; inline
+
+: reassociate-bitwise ( insn new-insn -- insn/f )
+    [ reassociate dup immediate-bitwise? ] dip ?new-insn ; inline
+
+: reassociate-shift ( insn new-insn -- insn/f )
+    [ (reassociate) + dup immediate-shift-count? ] dip ?new-insn ; inline
+
+M: ##add-imm rewrite
+    {
+        { [ dup src2>> 0 = ] [ identity ] }
+        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
+        { [ dup src1>> vreg>insn ##add-imm? ] [ \ ##add-imm reassociate-arithmetic ] }
+        [ drop f ]
+    } cond ;
+
+: sub-imm>add-imm ( insn -- insn' )
+    [ dst>> ] [ src1>> ] [ src2>> neg ] tri
+    dup immediate-arithmetic?
+    \ ##add-imm ?new-insn ;
+
+M: ##sub-imm rewrite sub-imm>add-imm ;
+
+! Convert ##mul-imm -1 => ##neg
+: mul-to-neg? ( insn -- ? )
+    src2>> -1 = ;
+
+: mul-to-neg ( insn -- insn' )
+    [ dst>> ] [ src1>> ] bi \ ##neg new-insn ;
+
+! Convert ##mul-imm 2^X => ##shl-imm X
+: mul-to-shl? ( insn -- ? )
+    src2>> power-of-2? ;
+
+: mul-to-shl ( insn -- insn' )
+    [ [ dst>> ] [ src1>> ] bi ] [ src2>> log2 ] bi \ ##shl-imm new-insn ;
+
+! Distribution converts
+! ##+-imm 2 1 X
+! ##*-imm 3 2 Y
+! Into
+! ##*-imm 4 1 Y
+! ##+-imm 3 4 X*Y
+! Where * is mul or shl, + is add or sub
+! Have to make sure that X*Y fits in an immediate
+:: (distribute) ( outer inner imm temp add-op mul-op -- new-outers/f )
+    imm immediate-arithmetic? [
+        [
+            temp inner src1>> outer src2>> mul-op execute
+            outer dst>> temp imm add-op execute
+        ] { } make
+    ] [ f ] if ; inline
+
+: distribute-over-add? ( insn -- ? )
+    src1>> vreg>insn ##add-imm? ;
+
+: distribute-over-sub? ( insn -- ? )
+    src1>> vreg>insn ##sub-imm? ;
+
+: distribute ( insn add-op mul-op -- new-insns/f )
+    [
+        dup src1>> vreg>insn
+        2dup src2>> swap [ src2>> ] keep binary-constant-fold*
+        next-vreg
+    ] 2dip (distribute) ; inline
+
+M: ##mul-imm rewrite
+    {
+        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
+        { [ dup mul-to-neg? ] [ mul-to-neg ] }
+        { [ dup mul-to-shl? ] [ mul-to-shl ] }
+        { [ dup src1>> vreg>insn ##mul-imm? ] [ \ ##mul-imm reassociate-arithmetic ] }
+        { [ dup distribute-over-add? ] [ \ ##add-imm \ ##mul-imm distribute ] }
+        { [ dup distribute-over-sub? ] [ \ ##sub-imm \ ##mul-imm distribute ] }
+        [ drop f ]
+    } cond ;
+
+M: ##and-imm rewrite
+    {
+        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
+        { [ dup src1>> vreg>insn ##and-imm? ] [ \ ##and-imm reassociate-bitwise ] }
+        { [ dup src2>> 0 = ] [ dst>> 0 \ ##load-integer new-insn ] }
+        { [ dup src2>> -1 = ] [ identity ] }
+        [ drop f ]
+    } cond ;
+
+M: ##or-imm rewrite
+    {
+        { [ dup src2>> 0 = ] [ identity ] }
+        { [ dup src2>> -1 = ] [ dst>> -1 \ ##load-integer new-insn ] }
+        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
+        { [ dup src1>> vreg>insn ##or-imm? ] [ \ ##or-imm reassociate-bitwise ] }
+        [ drop f ]
+    } cond ;
+
+M: ##xor-imm rewrite
+    {
+        { [ dup src2>> 0 = ] [ identity ] }
+        { [ dup src2>> -1 = ] [ [ dst>> ] [ src1>> ] bi \ ##not new-insn ] }
+        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
+        { [ dup src1>> vreg>insn ##xor-imm? ] [ \ ##xor-imm reassociate-bitwise ] }
+        [ drop f ]
+    } cond ;
+
+M: ##shl-imm rewrite
+    {
+        { [ dup src2>> 0 = ] [ identity ] }
+        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
+        { [ dup src1>> vreg>insn ##shl-imm? ] [ \ ##shl-imm reassociate-shift ] }
+        { [ dup distribute-over-add? ] [ \ ##add-imm \ ##shl-imm distribute ] }
+        { [ dup distribute-over-sub? ] [ \ ##sub-imm \ ##shl-imm distribute ] }
+        [ drop f ]
+    } cond ;
+
+M: ##shr-imm rewrite
+    {
+        { [ dup src2>> 0 = ] [ identity ] }
+        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
+        { [ dup src1>> vreg>insn ##shr-imm? ] [ \ ##shr-imm reassociate-shift ] }
+        [ drop f ]
+    } cond ;
+
+M: ##sar-imm rewrite
+    {
+        { [ dup src2>> 0 = ] [ identity ] }
+        { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
+        { [ dup src1>> vreg>insn ##sar-imm? ] [ \ ##sar-imm reassociate-shift ] }
+        [ drop f ]
+    } cond ;
+
+! Convert
+! ##load-integer 2 X
+! ##* 3 1 2
+! Where * is an operation with an -imm equivalent into
+! ##*-imm 3 1 X
+: insn>imm-insn ( insn op swap? -- new-insn )
+    swap [
+        [ [ dst>> ] [ src1>> ] [ src2>> ] tri ] dip
+        [ swap ] when vreg>integer
+    ] dip new-insn ; inline
+
+M: ##add rewrite
+    {
+        { [ dup src2>> vreg-immediate-arithmetic? ] [ \ ##add-imm f insn>imm-insn ] }
+        { [ dup src1>> vreg-immediate-arithmetic? ] [ \ ##add-imm t insn>imm-insn ] }
+        [ drop f ]
+    } cond ;
+
+: diagonal? ( insn -- ? )
+    [ src1>> vreg>vn ] [ src2>> vreg>vn ] bi = ; inline
+
+! ##sub 2 1 1 => ##load-integer 2 0
+: rewrite-subtraction-identity ( insn -- insn' )
+    dst>> 0 \ ##load-integer new-insn ;
+
+! ##load-integer 1 0
+! ##sub 3 1 2
+! =>
+! ##neg 3 2
+: sub-to-neg? ( ##sub -- ? )
+    src1>> vreg>insn zero-insn? ;
+
+: sub-to-neg ( ##sub -- insn )
+    [ dst>> ] [ src2>> ] bi \ ##neg new-insn ;
+
+M: ##sub rewrite
+    {
+        { [ dup sub-to-neg? ] [ sub-to-neg ] }
+        { [ dup diagonal? ] [ rewrite-subtraction-identity ] }
+        { [ dup src2>> vreg-immediate-arithmetic? ] [ \ ##sub-imm f insn>imm-insn ] }
+        [ drop f ]
+    } cond ;
+
+M: ##mul rewrite
+    {
+        { [ dup src2>> vreg-immediate-arithmetic? ] [ \ ##mul-imm f insn>imm-insn ] }
+        { [ dup src1>> vreg-immediate-arithmetic? ] [ \ ##mul-imm t insn>imm-insn ] }
+        [ drop f ]
+    } cond ;
+
+M: ##and rewrite
+    {
+        { [ dup diagonal? ] [ identity ] }
+        { [ dup src2>> vreg-immediate-bitwise? ] [ \ ##and-imm f insn>imm-insn ] }
+        { [ dup src1>> vreg-immediate-bitwise? ] [ \ ##and-imm t insn>imm-insn ] }
+        [ drop f ]
+    } cond ;
+
+M: ##or rewrite
+    {
+        { [ dup diagonal? ] [ identity ] }
+        { [ dup src2>> vreg-immediate-bitwise? ] [ \ ##or-imm f insn>imm-insn ] }
+        { [ dup src1>> vreg-immediate-bitwise? ] [ \ ##or-imm t insn>imm-insn ] }
+        [ drop f ]
+    } cond ;
+
+M: ##xor rewrite
+    {
+        { [ dup diagonal? ] [ dst>> 0 \ ##load-integer new-insn ] }
+        { [ dup src2>> vreg-immediate-bitwise? ] [ \ ##xor-imm f insn>imm-insn ] }
+        { [ dup src1>> vreg-immediate-bitwise? ] [ \ ##xor-imm t insn>imm-insn ] }
+        [ drop f ]
+    } cond ;
+
+M: ##shl rewrite
+    {
+        { [ dup src2>> vreg-immediate-bitwise? ] [ \ ##shl-imm f insn>imm-insn ] }
+        [ drop f ]
+    } cond ;
+
+M: ##shr rewrite
+    {
+        { [ dup src2>> vreg-immediate-bitwise? ] [ \ ##shr-imm f insn>imm-insn ] }
+        [ drop f ]
+    } cond ;
+
+M: ##sar rewrite
+    {
+        { [ dup src2>> vreg-immediate-bitwise? ] [ \ ##sar-imm f insn>imm-insn ] }
+        [ drop f ]
+    } cond ;
diff --git a/extra/compiler/cfg/gvn/misc/authors.txt b/extra/compiler/cfg/gvn/misc/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/extra/compiler/cfg/gvn/misc/misc.factor b/extra/compiler/cfg/gvn/misc/misc.factor
new file mode 100644 (file)
index 0000000..970c39b
--- /dev/null
@@ -0,0 +1,14 @@
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors cpu.architecture kernel
+compiler.cfg.instructions
+compiler.cfg.gvn.graph
+compiler.cfg.gvn.rewrite ;
+IN: compiler.cfg.gvn.misc
+
+M: ##replace rewrite
+    [ loc>> ] [ src>> vreg>insn ] bi
+    dup literal-insn? [
+        insn>literal dup immediate-store?
+        [ swap \ ##replace-imm new-insn ] [ 2drop f ] if
+    ] [ 2drop f ] if ;
diff --git a/extra/compiler/cfg/gvn/rewrite/rewrite.factor b/extra/compiler/cfg/gvn/rewrite/rewrite.factor
new file mode 100644 (file)
index 0000000..dbbfe86
--- /dev/null
@@ -0,0 +1,48 @@
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators combinators.short-circuit kernel
+layouts math cpu.architecture
+compiler.cfg.instructions
+compiler.cfg.gvn.graph ;
+IN: compiler.cfg.gvn.rewrite
+
+! Outputs f to mean no change
+GENERIC: rewrite ( insn -- insn/f )
+
+M: insn rewrite drop f ;
+
+! Utilities
+GENERIC: insn>integer ( insn -- n )
+
+M: ##load-integer insn>integer val>> ;
+
+: vreg>integer ( vreg -- n ) vreg>insn insn>integer ; inline
+
+: vreg-immediate-arithmetic? ( vreg -- ? )
+    vreg>insn {
+        [ ##load-integer? ]
+        [ val>> immediate-arithmetic? ]
+    } 1&& ;
+
+: vreg-immediate-bitwise? ( vreg -- ? )
+    vreg>insn {
+        [ ##load-integer? ]
+        [ val>> immediate-bitwise? ]
+    } 1&& ;
+
+UNION: literal-insn ##load-integer ##load-reference ;
+
+GENERIC: insn>literal ( insn -- n )
+
+M: ##load-integer insn>literal val>> >fixnum ;
+
+M: ##load-reference insn>literal obj>> ;
+
+: vreg>literal ( vreg -- n ) vreg>insn insn>literal ; inline
+
+: vreg-immediate-comparand? ( vreg -- ? )
+    vreg>insn {
+        { [ dup ##load-integer? ] [ val>> tag-fixnum immediate-comparand? ] }
+        { [ dup ##load-reference? ] [ obj>> immediate-comparand? ] }
+        [ drop f ]
+    } cond ;
diff --git a/extra/compiler/cfg/gvn/rewrite/summary.txt b/extra/compiler/cfg/gvn/rewrite/summary.txt
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/extra/compiler/cfg/gvn/simd/simd.factor b/extra/compiler/cfg/gvn/simd/simd.factor
new file mode 100644 (file)
index 0000000..14fd574
--- /dev/null
@@ -0,0 +1,163 @@
+! Copyright (C) 2008, 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators combinators.short-circuit arrays
+fry kernel layouts math namespaces sequences cpu.architecture
+math.bitwise math.order classes generalizations
+combinators.smart locals make alien.c-types io.binary grouping
+math.vectors.simd.intrinsics
+compiler.cfg
+compiler.cfg.registers
+compiler.cfg.utilities
+compiler.cfg.comparisons
+compiler.cfg.instructions
+compiler.cfg.gvn.math
+compiler.cfg.gvn.graph
+compiler.cfg.gvn.rewrite ;
+IN: compiler.cfg.gvn.simd
+
+! Some lame constant folding for SIMD intrinsics. Eventually this
+! should be redone completely.
+
+: useless-shuffle-vector-imm? ( insn -- ? )
+    [ shuffle>> ] [ rep>> rep-length iota ] bi sequence= ;
+
+: compose-shuffle-vector-imm ( outer inner -- insn' )
+    2dup [ rep>> ] bi@ eq? [
+        [ [ dst>> ] [ src>> ] bi* ]
+        [ [ shuffle>> ] bi@ nths ]
+        [ drop rep>> ]
+        2tri \ ##shuffle-vector-imm new-insn
+    ] [ 2drop f ] if ;
+
+: (fold-shuffle-vector-imm) ( shuffle bytes -- bytes' )
+    2dup length swap length /i group nths concat ;
+
+: fold-shuffle-vector-imm ( outer inner -- insn' )
+    [ [ dst>> ] [ shuffle>> ] bi ] [ obj>> ] bi*
+    (fold-shuffle-vector-imm) \ ##load-reference new-insn ;
+
+M: ##shuffle-vector-imm rewrite
+    dup src>> vreg>insn {
+        { [ over useless-shuffle-vector-imm? ] [ drop [ dst>> ] [ src>> ] bi <copy> ] }
+        { [ dup ##shuffle-vector-imm? ] [ compose-shuffle-vector-imm ] }
+        { [ dup ##load-reference? ] [ fold-shuffle-vector-imm ] }
+        [ 2drop f ]
+    } cond ;
+
+: scalar-value ( literal-insn rep -- byte-array )
+    {
+        { float-4-rep [ obj>> float>bits 4 >le ] }
+        { double-2-rep [ obj>> double>bits 8 >le ] }
+        [ [ val>> ] [ rep-component-type heap-size ] bi* >le ]
+    } case ;
+
+: (fold-scalar>vector) ( insn bytes -- insn' )
+    [ [ dst>> ] [ rep>> rep-length ] bi ] dip <repetition> concat
+    \ ##load-reference new-insn ;
+
+: fold-scalar>vector ( outer inner -- insn' )
+    over rep>> scalar-value (fold-scalar>vector) ;
+
+M: ##scalar>vector rewrite
+    dup src>> vreg>insn {
+        { [ dup literal-insn? ] [ fold-scalar>vector ] }
+        { [ dup ##vector>scalar? ] [ [ dst>> ] [ src>> ] bi* <copy> ] }
+        [ 2drop f ]
+    } cond ;
+
+:: fold-gather-vector-2 ( insn src1 src2 -- insn )
+    insn dst>>
+    src1 src2 [ insn rep>> scalar-value ] bi@ append
+    \ ##load-reference new-insn ;
+
+: rewrite-gather-vector-2 ( insn -- insn/f )
+    dup [ src1>> vreg>insn ] [ src2>> vreg>insn ] bi {
+        { [ 2dup [ literal-insn? ] both? ] [ fold-gather-vector-2 ] }
+        [ 3drop f ]
+    } cond ;
+
+M: ##gather-vector-2 rewrite rewrite-gather-vector-2 ;
+
+M: ##gather-int-vector-2 rewrite rewrite-gather-vector-2 ;
+
+:: fold-gather-vector-4 ( insn src1 src2 src3 src4 -- insn )
+    insn dst>>
+    [
+        src1 src2 src3 src4
+        [ insn rep>> scalar-value ] 4 napply
+    ] B{ } append-outputs-as
+    \ ##load-reference new-insn ;
+
+: rewrite-gather-vector-4 ( insn -- insn/f )
+    dup { [ src1>> ] [ src2>> ] [ src3>> ] [ src4>> ] } cleave [ vreg>insn ] 4 napply
+    {
+        { [ 4 ndup [ literal-insn? ] 4 napply and and and ] [ fold-gather-vector-4 ] }
+        [ 5 ndrop f ]
+    } cond ;
+
+M: ##gather-vector-4 rewrite rewrite-gather-vector-4 ;
+
+M: ##gather-int-vector-4 rewrite rewrite-gather-vector-4 ;
+
+: fold-shuffle-vector ( insn src1 src2 -- insn )
+    [ dst>> ] [ obj>> ] [ obj>> ] tri*
+    swap nths \ ##load-reference new-insn ;
+
+M: ##shuffle-vector rewrite
+    dup [ src>> vreg>insn ] [ shuffle>> vreg>insn ] bi
+    {
+        { [ 2dup [ ##load-reference? ] both? ] [ fold-shuffle-vector ] }
+        [ 3drop f ]
+    } cond ;
+
+M: ##xor-vector rewrite
+    dup diagonal?
+    [ [ dst>> ] [ rep>> ] bi \ ##zero-vector new-insn ] [ drop f ] if ;
+
+: vector-not? ( insn -- ? )
+    {
+        [ ##not-vector? ]
+        [ {
+            [ ##xor-vector? ]
+            [ [ src1>> ] [ src2>> ] bi [ vreg>insn ##fill-vector? ] either? ]
+        } 1&& ]
+    } 1|| ;
+
+GENERIC: vector-not-src ( insn -- vreg )
+
+M: ##not-vector vector-not-src
+    src>> ;
+
+M: ##xor-vector vector-not-src
+    dup src1>> vreg>insn ##fill-vector? [ src2>> ] [ src1>> ] if ;
+
+M: ##and-vector rewrite 
+    {
+        { [ dup src1>> vreg>insn vector-not? ] [
+            {
+                [ dst>> ]
+                [ src1>> vreg>insn vector-not-src ]
+                [ src2>> ]
+                [ rep>> ]
+            } cleave \ ##andn-vector new-insn
+        ] }
+        { [ dup src2>> vreg>insn vector-not? ] [
+            {
+                [ dst>> ]
+                [ src2>> vreg>insn vector-not-src ]
+                [ src1>> ]
+                [ rep>> ]
+            } cleave \ ##andn-vector new-insn
+        ] }
+        [ drop f ]
+    } cond ;
+
+M: ##andn-vector rewrite
+    dup src1>> vreg>insn vector-not? [
+        {
+            [ dst>> ]
+            [ src1>> vreg>insn vector-not-src ]
+            [ src2>> ]
+            [ rep>> ]
+        } cleave \ ##and-vector new-insn
+    ] [ drop f ] if ;
diff --git a/extra/compiler/cfg/gvn/slots/authors.txt b/extra/compiler/cfg/gvn/slots/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/extra/compiler/cfg/gvn/slots/slots.factor b/extra/compiler/cfg/gvn/slots/slots.factor
new file mode 100644 (file)
index 0000000..d994e19
--- /dev/null
@@ -0,0 +1,24 @@
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators.short-circuit cpu.architecture fry
+kernel math
+compiler.cfg.instructions
+compiler.cfg.gvn.graph
+compiler.cfg.gvn.rewrite ;
+IN: compiler.cfg.gvn.slots
+
+: simplify-slot-addressing? ( insn -- ? )
+    complex-addressing?
+    [ slot>> vreg>insn ##add-imm? ] [ drop f ] if ;
+
+: simplify-slot-addressing ( insn -- insn/f )
+    dup simplify-slot-addressing? [
+        dup slot>> vreg>insn
+        [ src1>> >>slot ]
+        [ src2>> over scale>> '[ _ _ shift - ] change-tag ]
+        bi
+    ] [ drop f ] if ;
+
+M: ##slot rewrite simplify-slot-addressing ;
+M: ##set-slot rewrite simplify-slot-addressing ;
+M: ##write-barrier rewrite simplify-slot-addressing ;
diff --git a/extra/compiler/cfg/gvn/summary.txt b/extra/compiler/cfg/gvn/summary.txt
new file mode 100644 (file)
index 0000000..bee42e3
--- /dev/null
@@ -0,0 +1 @@
+Global value numbering for common subexpression elimination