]> gitweb.factorcode.org Git - factor.git/commitdiff
Various improvements
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Thu, 23 Oct 2008 10:27:54 +0000 (05:27 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Thu, 23 Oct 2008 10:27:54 +0000 (05:27 -0500)
basis/compiler/cfg/alias-analysis/alias-analysis-tests.factor
basis/compiler/cfg/alias-analysis/alias-analysis.factor
basis/compiler/cfg/dead-code/dead-code-tests.factor [new file with mode: 0644]
basis/compiler/cfg/dead-code/dead-code.factor [new file with mode: 0644]
basis/compiler/cfg/height/height.factor
basis/compiler/cfg/intrinsics/intrinsics.factor
basis/compiler/cfg/optimizer/optimizer.factor
basis/compiler/cfg/value-numbering/rewrite/rewrite.factor
basis/compiler/cfg/value-numbering/simplify/simplify.factor
basis/compiler/cfg/value-numbering/value-numbering-tests.factor

index 1ac6fc8e6fe5a8686ae4331550e0fdc52cff8ff9..2f0649ed402351cb8a7ee700232b8680a0b50233 100644 (file)
@@ -10,52 +10,6 @@ IN: compiler.cfg.alias-analysis.tests
     } alias-analysis drop
 ] unit-test
 
-[
-    {
-        T{ ##peek f V int-regs 1 D 1 }
-        T{ ##replace f V int-regs 1 D 0 }
-    }
-] [
-    {
-        T{ ##peek f V int-regs 1 D 1 }
-        T{ ##replace f V int-regs 1 D 0 }
-        T{ ##replace f V int-regs 1 D 1 }
-    } alias-analysis
-] unit-test
-
-[
-    {
-        T{ ##peek f V int-regs 1 D 1 }
-        T{ ##copy f V int-regs 2 V int-regs 1 }
-        T{ ##replace f V int-regs 2 D 0 }
-    }
-] [
-    {
-        T{ ##peek f V int-regs 1 D 1 }
-        T{ ##copy f V int-regs 2 V int-regs 1 }
-        T{ ##replace f V int-regs 2 D 0 }
-        T{ ##replace f V int-regs 2 D 1 }
-    } alias-analysis
-] unit-test
-
-[
-    {
-        T{ ##peek f V int-regs 1 D 1 }
-        T{ ##peek f V int-regs 2 D 0 }
-        T{ ##copy f V int-regs 3 V int-regs 2 }
-        T{ ##copy f V int-regs 4 V int-regs 1 }
-    }
-] [
-    {
-        T{ ##peek f V int-regs 1 D 1 }
-        T{ ##peek f V int-regs 2 D 0 }
-        T{ ##copy f V int-regs 3 V int-regs 2 }
-        T{ ##copy f V int-regs 4 V int-regs 1 }
-        T{ ##replace f V int-regs 3 D 0 }
-        T{ ##replace f V int-regs 4 D 1 }
-    } alias-analysis
-] unit-test
-
 [
     {
         T{ ##peek f V int-regs 1 D 1 f }
@@ -71,42 +25,14 @@ IN: compiler.cfg.alias-analysis.tests
     } alias-analysis
 ] unit-test
 
-[
-    {
-        T{ ##peek f V int-regs 1 D 1 f }
-        T{ ##copy f V int-regs 3 V int-regs 1 f }
-    }
-] [
-    {
-        T{ ##peek f V int-regs 1 D 1 f }
-        T{ ##replace f V int-regs 1 D 1 f }
-        T{ ##peek f V int-regs 3 D 1 f }
-        T{ ##replace f V int-regs 4 D 1 f }
-    } alias-analysis
-] unit-test
-
-[
-    {
-        T{ ##peek f V int-regs 1 D 1 f }
-        T{ ##peek f V int-regs 2 D 0 f }
-    }
-] [
-    {
-        T{ ##peek f V int-regs 1 D 1 f }
-        T{ ##peek f V int-regs 2 D 0 f }
-        T{ ##replace f V int-regs 1 D 0 f }
-        T{ ##replace f V int-regs 2 D 1 f }
-        T{ ##replace f V int-regs 2 D 0 f }
-        T{ ##replace f V int-regs 1 D 1 f }
-    } alias-analysis
-] unit-test
-
 [
     {
         T{ ##peek f V int-regs 1 D 1 f }
         T{ ##peek f V int-regs 2 D 0 f }
         T{ ##copy f V int-regs 3 V int-regs 2 f }
         T{ ##copy f V int-regs 4 V int-regs 1 f }
+        T{ ##replace f V int-regs 3 D 0 f }
+        T{ ##replace f V int-regs 4 D 1 f }
     }
 ] [
     {
index e98f6e8beacc7d6d98655b151d3a9ab77a28cbcf..fdfa88c51acddc12e54777b9ca1671091409bb2d 100644 (file)
@@ -6,7 +6,7 @@ compiler.cfg.registers compiler.cfg.instructions
 compiler.cfg.instructions.syntax compiler.cfg.copy-prop ;
 IN: compiler.cfg.alias-analysis
 
-! Alias analysis -- must be run after compiler.cfg.height.
+! Alias analysis -- assumes compiler.cfg.height has already run.
 !
 ! We try to eliminate redundant slot and stack
 ! traffic using some simple heuristics.
diff --git a/basis/compiler/cfg/dead-code/dead-code-tests.factor b/basis/compiler/cfg/dead-code/dead-code-tests.factor
new file mode 100644 (file)
index 0000000..b9c3af5
--- /dev/null
@@ -0,0 +1,8 @@
+USING: compiler.cfg.dead-code compiler.cfg.instructions
+compiler.cfg.registers cpu.architecture tools.test ;
+IN: compiler.cfg.dead-code.tests
+
+[ { } ] [
+    { T{ ##load-immediate f V int-regs 134 16 } }
+    eliminate-dead-code
+] unit-test
diff --git a/basis/compiler/cfg/dead-code/dead-code.factor b/basis/compiler/cfg/dead-code/dead-code.factor
new file mode 100644 (file)
index 0000000..6ac5c1a
--- /dev/null
@@ -0,0 +1,62 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors assocs sets kernel namespaces sequences
+compiler.cfg.instructions compiler.cfg.instructions.syntax
+compiler.cfg.def-use ;
+IN: compiler.cfg.dead-code
+
+! Dead code elimination -- assumes compiler.cfg.alias-analysis
+! has already run.
+
+! Maps vregs to sequences of vregs
+SYMBOL: liveness-graph
+
+! vregs which participate in side effects and thus are always live
+SYMBOL: live-vregs
+
+! mapping vregs to stack locations
+SYMBOL: vregs>locs
+
+: init-dead-code ( -- )
+    H{ } clone liveness-graph set
+    H{ } clone live-vregs set
+    H{ } clone vregs>locs set ;
+
+GENERIC: compute-liveness ( insn -- )
+
+M: ##flushable compute-liveness
+    [ uses-vregs ] [ dst>> ] bi liveness-graph get set-at ;
+
+M: ##peek compute-liveness
+    [ [ loc>> ] [ dst>> ] bi vregs>locs get set-at ]
+    [ call-next-method ]
+    bi ;
+
+: live-replace? ( ##replace -- ? )
+    [ src>> vregs>locs get at ] [ loc>> ] bi = not ;
+
+M: ##replace compute-liveness
+    dup live-replace? [ call-next-method ] [ drop ] if ;
+
+: record-live ( vregs -- )
+    [
+        dup live-vregs get key? [ drop ] [
+            [ live-vregs get conjoin ]
+            [ liveness-graph get at record-live ]
+            bi
+        ] if
+    ] each ;
+
+M: insn compute-liveness uses-vregs record-live ;
+
+GENERIC: live-insn? ( insn -- ? )
+
+M: ##flushable live-insn? dst>> live-vregs get key? ;
+
+M: ##replace live-insn? live-replace? ;
+
+M: insn live-insn? drop t ;
+
+: eliminate-dead-code ( insns -- insns' )
+    init-dead-code
+    [ [ compute-liveness ] each ] [ [ live-insn? ] filter ] bi ;
index d14cf4afb4e5d5520ed616ef14f9156e4f7f0e45..1c3f1744b445d9d22ec61572668e2d1e13fd7bc4 100644 (file)
@@ -7,9 +7,6 @@ IN: compiler.cfg.height
 
 ! Combine multiple stack height changes into one at the
 ! start of the basic block.
-!
-! Alias analysis and value numbering assume this optimization
-! has been performed.
 
 SYMBOL: ds-height
 SYMBOL: rs-height
index f42b53a91eb0a201045d325793f0a5157a22a6da..338eaab9553b213713835ba931027ad2f1dc2ccf 100644 (file)
@@ -72,6 +72,10 @@ IN: compiler.cfg.intrinsics
         math.private:float/f
         math.private:fixnum>float
         math.private:float>fixnum
+        math.private:float<
+        math.private:float<=
+        math.private:float>
+        math.private:float>=
         alien.accessors:alien-float
         alien.accessors:set-alien-float
         alien.accessors:alien-double
index 598a4bfceac9816003fa77eec84bcf3d6acd6acf..05084e32a83981d1e0364d676b010e39f5cf83b2 100644 (file)
@@ -5,6 +5,7 @@ compiler.cfg.instructions
 compiler.cfg.height
 compiler.cfg.alias-analysis
 compiler.cfg.value-numbering
+compiler.cfg.dead-code
 compiler.cfg.write-barrier ;
 IN: compiler.cfg.optimizer
 
@@ -17,6 +18,7 @@ IN: compiler.cfg.optimizer
             normalize-height
             alias-analysis
             value-numbering
+            eliminate-dead-code
             eliminate-write-barriers
         ] unless
     ] change-basic-blocks ;
index a5fcc58365b42242e2d9030e22153c12427f4119..748a965d921529b9afd5765736c906975437d39e 100644 (file)
@@ -5,13 +5,23 @@ math
 compiler.cfg.instructions
 compiler.cfg.instructions.syntax
 compiler.cfg.value-numbering.graph
+compiler.cfg.value-numbering.simplify
 compiler.cfg.value-numbering.expressions ;
 IN: compiler.cfg.value-numbering.rewrite
 
 GENERIC: rewrite ( insn -- insn' )
 
+M: ##mul-imm rewrite
+    dup src2>> dup power-of-2? [
+        [ [ dst>> ] [ src1>> ] bi ] [ log2 ] bi* f \ ##shl-imm boa
+        dup number-values
+    ] [ drop ] if ;
+
 : ##branch-t? ( insn -- ? )
-    [ cc>> cc/= eq? ] [ src2>> \ f tag-number eq? ] bi and ; inline
+    dup ##compare-imm-branch? [
+        [ cc>> cc/= eq? ]
+        [ src2>> \ f tag-number eq? ] bi and
+    ] [ drop f ] if ; inline
 
 : rewrite-boolean-comparison? ( insn -- ? )
     dup ##branch-t? [
@@ -37,9 +47,11 @@ GENERIC: rewrite ( insn -- insn' )
 
 : rewrite-tagged-comparison? ( insn -- ? )
     #! Are we comparing two tagged fixnums? Then untag them.
-    [ src1>> vreg>expr tag-fixnum-expr? ]
-    [ src2>> tag-mask get bitand 0 = ]
-    bi and ; inline
+    dup ##compare-imm-branch? [
+        [ src1>> vreg>expr tag-fixnum-expr? ]
+        [ src2>> tag-mask get bitand 0 = ]
+        bi and
+    ] [ drop f ] if ; inline
 
 : rewrite-tagged-comparison ( insn -- insn' )
     [ src1>> vreg>expr in1>> vn>vreg ]
index e51b0d211f0c15838ade6eb7a2919276cf7a549e..d63b84a86f98591ad61ed379550efae46b3f3cd7 100644 (file)
@@ -10,11 +10,14 @@ IN: compiler.cfg.value-numbering.simplify
 ! Return value of f means we didn't simplify.
 GENERIC: simplify* ( expr -- vn/expr/f )
 
-: simplify-box-float ( in -- vn/expr/f )
-    dup op>> \ ##unbox-float = [ in>> ] [ drop f ] if ;
+: simplify-unbox ( in boxer -- vn/expr/f )
+    over op>> eq? [ in>> ] [ drop f ] if ; inline
 
 : simplify-unbox-float ( in -- vn/expr/f )
-    dup op>> \ ##box-float = [ in>> ] [ drop f ] if ;
+    \ ##box-float simplify-unbox ; inline
+
+: simplify-unbox-alien ( in -- vn/expr/f )
+    \ ##box-alien simplify-unbox ; inline
 
 M: unary-expr simplify*
     #! Note the copy propagation: a copy always simplifies to
@@ -22,8 +25,38 @@ M: unary-expr simplify*
     [ in>> vn>expr ] [ op>> ] bi {
         { \ ##copy [ ] }
         { \ ##copy-float [ ] }
-        { \ ##box-float [ simplify-box-float ] }
         { \ ##unbox-float [ simplify-unbox-float ] }
+        { \ ##unbox-alien [ simplify-unbox-alien ] }
+        { \ ##unbox-any-c-ptr [ simplify-unbox-alien ] }
+        [ 2drop f ]
+    } case ;
+
+: expr-zero? ( expr -- ? ) T{ constant-expr f f 0 } = ; inline
+
+: >binary-expr< ( expr -- in1 in2 )
+    [ in1>> vn>expr ] [ in2>> vn>expr ] bi ; inline
+
+: simplify-add ( expr -- vn/expr/f )
+    >binary-expr< {
+        { [ over expr-zero? ] [ nip ] }
+        { [ dup expr-zero? ] [ drop ] }
+        [ 2drop f ]
+    } cond ; inline
+
+: useless-shift? ( in1 in2 -- ? )
+    over op>> \ ##shl-imm eq?
+    [ [ in2>> ] [ expr>vn ] bi* = ] [ 2drop f ] if ; inline
+
+: simplify-shift ( expr -- vn/expr/f )
+    >binary-expr<
+    2dup useless-shift? [ drop in1>> ] [ 2drop f ] if ; inline
+
+M: binary-expr simplify*
+    dup op>> {
+        { \ ##add [ simplify-add ] }
+        { \ ##add-imm [ simplify-add ] }
+        { \ ##shr-imm [ simplify-shift ] }
+        { \ ##sar-imm [ simplify-shift ] }
         [ 2drop f ]
     } case ;
 
index c8a1d7884cf02054915831c0abba8cd7e2421467..a33c2f28c4217e5d642f0144e313457dc7d72cf6 100644 (file)
@@ -50,3 +50,19 @@ compiler.cfg.registers cpu.architecture tools.test kernel ;
         T{ ##replace f V int-regs 23 D 0 }
     } dup value-numbering =
 ] unit-test
+
+[
+    {
+        T{ ##peek f V int-regs 1 D 0 }
+        T{ ##shl-imm f V int-regs 2 V int-regs 1 3 }
+        T{ ##shr-imm f V int-regs 3 V int-regs 2 3 }
+        T{ ##replace f V int-regs 1 D 0 }
+    }
+] [
+    {
+        T{ ##peek f V int-regs 1 D 0 }
+        T{ ##mul-imm f V int-regs 2 V int-regs 1 8 }
+        T{ ##shr-imm f V int-regs 3 V int-regs 2 3 }
+        T{ ##replace f V int-regs 3 D 0 }
+    } value-numbering
+] unit-test