]> gitweb.factorcode.org Git - factor.git/commitdiff
compiler.cfg.value-numbering: new optimizations; reassociation for shifts and redistr...
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Fri, 23 Apr 2010 08:17:41 +0000 (04:17 -0400)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Mon, 3 May 2010 21:34:02 +0000 (17:34 -0400)
basis/compiler/cfg/value-numbering/math/math.factor
basis/compiler/cfg/value-numbering/value-numbering-tests.factor
basis/cpu/architecture/architecture.factor

index bbc2d5a169c3b274f3fdb5335ac0acce10e7adec..1ea2135db46c245bba05b7560e6be34146cf1f83 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors combinators cpu.architecture fry kernel layouts
-math sequences compiler.cfg.instructions
+locals make math sequences compiler.cfg.instructions
+compiler.cfg.registers
 compiler.cfg.value-numbering.expressions
 compiler.cfg.value-numbering.folding
 compiler.cfg.value-numbering.graph
@@ -9,10 +10,12 @@ compiler.cfg.value-numbering.rewrite
 compiler.cfg.value-numbering.simplify ;
 IN: compiler.cfg.value-numbering.math
 
+: f-expr? ( expr -- ? ) T{ reference-expr f f } = ;
+
 M: ##tagged>integer rewrite
     [ dst>> ] [ src>> vreg>expr ] bi {
         { [ dup integer-expr? ] [ value>> tag-fixnum \ ##load-integer new-insn ] }
-        { [ dup reference-expr? ] [ value>> [ drop f ] [ \ f type-number \ ##load-integer new-insn ] if ] }
+        { [ dup f-expr? ] [ \ f type-number \ ##load-integer new-insn ] }
         [ 2drop f ]
     } cond ;
 
@@ -22,13 +25,22 @@ M: ##neg rewrite
 M: ##not rewrite
     dup unary-constant-fold? [ unary-constant-fold ] [ drop f ] if ;
 
-: reassociate ( insn -- dst src1 src2 )
+! 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>expr [ src1>> vn>vreg ] [ src2>> vn>integer ] bi ]
         [ src2>> ]
-        [ ]
-    } cleave binary-constant-fold* ;
+    } 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
@@ -39,6 +51,9 @@ M: ##not rewrite
 : 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 binary-constant-fold? ] [ binary-constant-fold ] }
@@ -56,24 +71,57 @@ M: ##sub-imm rewrite
         [ sub-imm>add-imm ]
     } cond ;
 
+! 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) ( insn expr imm temp add-op mul-op -- new-insns/f )
+    imm immediate-arithmetic? [
+        [
+            temp expr src1>> vn>vreg insn src2>> mul-op execute
+            insn dst>> temp imm add-op execute
+        ] { } make
+    ] [ f ] if ;
+
+: distribute-over-add? ( insn -- ? )
+    src1>> vreg>expr add-imm-expr? ;
+
+: distribute-over-sub? ( insn -- ? )
+    src1>> vreg>expr sub-imm-expr? ;
+
+: distribute ( insn add-op mul-op -- new-insns/f )
+    [
+        dup src1>> vreg>expr
+        2dup src2>> vn>integer swap [ src2>> ] keep binary-constant-fold*
+        next-vreg
+    ] 2dip (distribute) ;
+
 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>expr mul-imm-expr? ] [ \ ##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 ;
 
@@ -101,21 +149,31 @@ M: ##xor-imm rewrite
 M: ##shl-imm rewrite
     {
         { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
+        { [ dup src1>> vreg>expr shl-imm-expr? ] [ \ ##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 binary-constant-fold? ] [ binary-constant-fold ] }
+        { [ dup src1>> vreg>expr shr-imm-expr? ] [ \ ##shr-imm reassociate-shift ] }
         [ drop f ]
     } cond ;
 
 M: ##sar-imm rewrite
     {
         { [ dup binary-constant-fold? ] [ binary-constant-fold ] }
+        { [ dup src1>> vreg>expr sar-imm-expr? ] [ \ ##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
@@ -129,12 +187,17 @@ M: ##add rewrite
         [ drop f ]
     } cond ;
 
+! ##sub 2 1 1 => ##load-integer 2 0
 : subtraction-identity? ( insn -- ? )
     [ src1>> ] [ src2>> ] bi [ vreg>vn ] bi@ eq? ;
 
 : 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>> vn>expr expr-zero? ;
 
index f18f00aa768abf41c4a58038c6cb1ee4bcdde6a7..bdf8b330af3486fb16bd7a925251368857d8b24e 100644 (file)
@@ -1125,6 +1125,189 @@ cpu x86.32? [
     } 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
 [
     {
index 57a04d4c65976883a9b89e2e2b7b91af92adbbbd..a2e5050edf8f5f347a23b96c84a2a464bdaacbee 100644 (file)
@@ -1,8 +1,9 @@
 ! Copyright (C) 2006, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays assocs generic kernel kernel.private
-math memory namespaces make sequences layouts system hashtables
-classes alien byte-arrays combinators words sets fry ;
+math math.order memory namespaces make sequences layouts system
+hashtables classes alien byte-arrays combinators words sets fry
+;
 IN: cpu.architecture
 
 ! Representations -- these are like low-level types
@@ -523,6 +524,9 @@ M: object immediate-comparand? ( n -- ? )
         [ drop f ]
     } cond ;
 
+: immediate-shift-count? ( n -- ? )
+    0 cell-bits 1 - between? ;
+
 ! What c-type describes the implicit struct return pointer for
 ! large structs?
 HOOK: struct-return-pointer-type cpu ( -- c-type )