compiler.cfg: use x86 TEST instruction to optimize 'bitand 0 ='
							parent
							
								
									22625469bc
								
							
						
					
					
						commit
						5a67711bfd
					
				| 
						 | 
				
			
			@ -713,6 +713,14 @@ INSN: ##compare-integer-imm-branch
 | 
			
		|||
use: src1/int-rep
 | 
			
		||||
literal: src2 cc ;
 | 
			
		||||
 | 
			
		||||
INSN: ##test-branch
 | 
			
		||||
use: src1/int-rep src2/int-rep
 | 
			
		||||
literal: cc ;
 | 
			
		||||
 | 
			
		||||
INSN: ##test-imm-branch
 | 
			
		||||
use: src1/int-rep
 | 
			
		||||
literal: src2 cc ;
 | 
			
		||||
 | 
			
		||||
PURE-INSN: ##compare-integer
 | 
			
		||||
def: dst/tagged-rep
 | 
			
		||||
use: src1/int-rep src2/int-rep
 | 
			
		||||
| 
						 | 
				
			
			@ -725,6 +733,18 @@ use: src1/int-rep
 | 
			
		|||
literal: src2 cc
 | 
			
		||||
temp: temp/int-rep ;
 | 
			
		||||
 | 
			
		||||
PURE-INSN: ##test
 | 
			
		||||
def: dst/tagged-rep
 | 
			
		||||
use: src1/int-rep src2/int-rep
 | 
			
		||||
literal: cc
 | 
			
		||||
temp: temp/int-rep ;
 | 
			
		||||
 | 
			
		||||
PURE-INSN: ##test-imm
 | 
			
		||||
def: dst/tagged-rep
 | 
			
		||||
use: src1/int-rep
 | 
			
		||||
literal: src2 cc
 | 
			
		||||
temp: temp/int-rep ;
 | 
			
		||||
 | 
			
		||||
! Float conditionals
 | 
			
		||||
INSN: ##compare-float-ordered-branch
 | 
			
		||||
use: src1/double-rep src2/double-rep
 | 
			
		||||
| 
						 | 
				
			
			@ -798,6 +818,8 @@ UNION: conditional-branch-insn
 | 
			
		|||
##compare-imm-branch
 | 
			
		||||
##compare-integer-branch
 | 
			
		||||
##compare-integer-imm-branch
 | 
			
		||||
##test-branch
 | 
			
		||||
##test-imm-branch
 | 
			
		||||
##compare-float-ordered-branch
 | 
			
		||||
##compare-float-unordered-branch
 | 
			
		||||
##test-vector-branch
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -211,24 +211,48 @@ M: ##compare-integer-imm optimize-insn
 | 
			
		|||
        [ call-next-method ]
 | 
			
		||||
    } cond ;
 | 
			
		||||
 | 
			
		||||
M: ##test-imm optimize-insn
 | 
			
		||||
    {
 | 
			
		||||
        { [ dup { [ src1-tagged? ] [ src2-tagged-bitwise? ] } 1&& ] [ >tagged-imm ] }
 | 
			
		||||
        [ call-next-method ]
 | 
			
		||||
    } cond ;
 | 
			
		||||
 | 
			
		||||
M: ##compare-integer-imm-branch optimize-insn
 | 
			
		||||
    {
 | 
			
		||||
        { [ dup { [ src1-tagged? ] [ src2-tagged-arithmetic? ] } 1&& ] [ >tagged-imm ] }
 | 
			
		||||
        [ call-next-method ]
 | 
			
		||||
    } cond ;
 | 
			
		||||
 | 
			
		||||
M: ##test-imm-branch optimize-insn
 | 
			
		||||
    {
 | 
			
		||||
        { [ dup { [ src1-tagged? ] [ src2-tagged-bitwise? ] } 1&& ] [ >tagged-imm ] }
 | 
			
		||||
        [ call-next-method ]
 | 
			
		||||
    } cond ;
 | 
			
		||||
 | 
			
		||||
M: ##compare-integer optimize-insn
 | 
			
		||||
    {
 | 
			
		||||
        { [ dup { [ src1-tagged? ] [ src2-tagged? ] } 1&& ] [ unchanged ] }
 | 
			
		||||
        [ call-next-method ]
 | 
			
		||||
    } cond ;
 | 
			
		||||
 | 
			
		||||
M: ##test optimize-insn
 | 
			
		||||
    {
 | 
			
		||||
        { [ dup { [ src1-tagged? ] [ src2-tagged? ] } 1&& ] [ unchanged ] }
 | 
			
		||||
        [ call-next-method ]
 | 
			
		||||
    } cond ;
 | 
			
		||||
 | 
			
		||||
M: ##compare-integer-branch optimize-insn
 | 
			
		||||
    {
 | 
			
		||||
        { [ dup { [ src1-tagged? ] [ src2-tagged? ] } 1&& ] [ unchanged ] }
 | 
			
		||||
        [ call-next-method ]
 | 
			
		||||
    } cond ;
 | 
			
		||||
 | 
			
		||||
M: ##test-branch optimize-insn
 | 
			
		||||
    {
 | 
			
		||||
        { [ dup { [ src1-tagged? ] [ src2-tagged? ] } 1&& ] [ unchanged ] }
 | 
			
		||||
        [ call-next-method ]
 | 
			
		||||
    } cond ;
 | 
			
		||||
 | 
			
		||||
! Identities:
 | 
			
		||||
! tag(neg(untag(x))) = x
 | 
			
		||||
! tag(neg(x)) = x * -2^tag-bits
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -632,7 +632,23 @@ cpu x86.64? [
 | 
			
		|||
    } test-peephole
 | 
			
		||||
] unit-test
 | 
			
		||||
 | 
			
		||||
! Tag/untag elimination for ##compare-integer
 | 
			
		||||
! Tag/untag elimination for ##compare-integer and ##test
 | 
			
		||||
[
 | 
			
		||||
    V{
 | 
			
		||||
        T{ ##peek f 0 D 0 }
 | 
			
		||||
        T{ ##peek f 1 D 1 }
 | 
			
		||||
        T{ ##test f 2 0 1 cc= }
 | 
			
		||||
        T{ ##replace f 2 D 0 }
 | 
			
		||||
    }
 | 
			
		||||
] [
 | 
			
		||||
    V{
 | 
			
		||||
        T{ ##peek f 0 D 0 }
 | 
			
		||||
        T{ ##peek f 1 D 1 }
 | 
			
		||||
        T{ ##test f 2 0 1 cc= }
 | 
			
		||||
        T{ ##replace f 2 D 0 }
 | 
			
		||||
    } test-peephole
 | 
			
		||||
] unit-test
 | 
			
		||||
 | 
			
		||||
[
 | 
			
		||||
    V{
 | 
			
		||||
        T{ ##peek f 0 D 0 }
 | 
			
		||||
| 
						 | 
				
			
			@ -663,6 +679,20 @@ cpu x86.64? [
 | 
			
		|||
    } test-peephole
 | 
			
		||||
] unit-test
 | 
			
		||||
 | 
			
		||||
[
 | 
			
		||||
    V{
 | 
			
		||||
        T{ ##peek f 0 D 0 }
 | 
			
		||||
        T{ ##peek f 1 D 1 }
 | 
			
		||||
        T{ ##test-branch f 0 1 cc= }
 | 
			
		||||
    }
 | 
			
		||||
] [
 | 
			
		||||
    V{
 | 
			
		||||
        T{ ##peek f 0 D 0 }
 | 
			
		||||
        T{ ##peek f 1 D 1 }
 | 
			
		||||
        T{ ##test-branch f 0 1 cc= }
 | 
			
		||||
    } test-peephole
 | 
			
		||||
] unit-test
 | 
			
		||||
 | 
			
		||||
[
 | 
			
		||||
    V{
 | 
			
		||||
        T{ ##peek f 0 D 0 }
 | 
			
		||||
| 
						 | 
				
			
			@ -677,6 +707,20 @@ cpu x86.64? [
 | 
			
		|||
    } test-peephole
 | 
			
		||||
] unit-test
 | 
			
		||||
 | 
			
		||||
[
 | 
			
		||||
    V{
 | 
			
		||||
        T{ ##peek f 0 D 0 }
 | 
			
		||||
        T{ ##peek f 1 D 1 }
 | 
			
		||||
        T{ ##test-imm-branch f 0 $[ 10 tag-fixnum ] cc= }
 | 
			
		||||
    }
 | 
			
		||||
] [
 | 
			
		||||
    V{
 | 
			
		||||
        T{ ##peek f 0 D 0 }
 | 
			
		||||
        T{ ##peek f 1 D 1 }
 | 
			
		||||
        T{ ##test-imm-branch f 0 10 cc= }
 | 
			
		||||
    } test-peephole
 | 
			
		||||
] unit-test
 | 
			
		||||
 | 
			
		||||
! Tag/untag elimination for ##neg
 | 
			
		||||
[
 | 
			
		||||
    V{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -123,6 +123,10 @@ M: ##compare-integer-imm has-peephole-opts? drop t ;
 | 
			
		|||
M: ##compare-integer has-peephole-opts? drop t ;
 | 
			
		||||
M: ##compare-integer-imm-branch has-peephole-opts? drop t ;
 | 
			
		||||
M: ##compare-integer-branch has-peephole-opts? drop t ;
 | 
			
		||||
M: ##test-imm has-peephole-opts? drop t ;
 | 
			
		||||
M: ##test has-peephole-opts? drop t ;
 | 
			
		||||
M: ##test-imm-branch has-peephole-opts? drop t ;
 | 
			
		||||
M: ##test-branch has-peephole-opts? drop t ;
 | 
			
		||||
 | 
			
		||||
GENERIC: compute-insn-costs ( insn -- )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,11 @@
 | 
			
		|||
! 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 compiler.cfg
 | 
			
		||||
compiler.cfg.comparisons compiler.cfg.instructions
 | 
			
		||||
sequences vectors combinators.short-circuit
 | 
			
		||||
cpu.architecture
 | 
			
		||||
compiler.cfg
 | 
			
		||||
compiler.cfg.comparisons
 | 
			
		||||
compiler.cfg.instructions
 | 
			
		||||
compiler.cfg.registers
 | 
			
		||||
compiler.cfg.value-numbering.math
 | 
			
		||||
compiler.cfg.value-numbering.graph
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +37,23 @@ IN: compiler.cfg.value-numbering.comparisons
 | 
			
		|||
    [ 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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -50,6 +70,8 @@ UNION: scalar-compare-insn
 | 
			
		|||
    ##compare-imm
 | 
			
		||||
    ##compare-integer
 | 
			
		||||
    ##compare-integer-imm
 | 
			
		||||
    ##test
 | 
			
		||||
    ##test-imm
 | 
			
		||||
    ##compare-float-unordered
 | 
			
		||||
    ##compare-float-ordered ;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -68,6 +90,8 @@ UNION: general-compare-insn scalar-compare-insn ##test-vector ;
 | 
			
		|||
        { [ 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 ] }
 | 
			
		||||
| 
						 | 
				
			
			@ -81,6 +105,9 @@ UNION: general-compare-insn scalar-compare-insn ##test-vector ;
 | 
			
		|||
: 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 ] }
 | 
			
		||||
| 
						 | 
				
			
			@ -94,6 +121,16 @@ M: ##compare-imm-branch rewrite
 | 
			
		|||
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 ;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -184,6 +221,8 @@ M: ##compare-integer rewrite
 | 
			
		|||
        { [ 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
 | 
			
		||||
| 
						 | 
				
			
			@ -202,8 +241,68 @@ M: ##compare-imm rewrite
 | 
			
		|||
: 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>insn ##load-integer? ] [ t >test-imm ] }
 | 
			
		||||
        { [ dup src2>> vreg>insn ##load-integer? ] [ f >test-imm ] }
 | 
			
		||||
        { [ dup diagonal? not ] [ drop f ] }
 | 
			
		||||
        { [ dup src1>> vreg>insn ##and? ] [ simplify-test ] }
 | 
			
		||||
        { [ dup src1>> vreg>insn ##and-imm? ] [ simplify-test-imm ] }
 | 
			
		||||
        [ drop f ]
 | 
			
		||||
    } cond ;
 | 
			
		||||
 | 
			
		||||
M: ##test-branch rewrite
 | 
			
		||||
    {
 | 
			
		||||
        { [ dup src1>> vreg>insn ##load-integer? ] [ t >test-imm-branch ] }
 | 
			
		||||
        { [ dup src2>> vreg>insn ##load-integer? ] [ f >test-imm-branch ] }
 | 
			
		||||
        { [ dup diagonal? not ] [ drop f ] }
 | 
			
		||||
        { [ dup src1>> vreg>insn ##and? ] [ simplify-test-branch ] }
 | 
			
		||||
        { [ dup src1>> vreg>insn ##and-imm? ] [ simplify-test-imm-branch ] }
 | 
			
		||||
        [ 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 ;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,8 @@ IN: compiler.cfg.value-numbering.tests
 | 
			
		|||
            [ ##compare-integer-imm? ]
 | 
			
		||||
            [ ##compare-float-unordered? ]
 | 
			
		||||
            [ ##compare-float-ordered? ]
 | 
			
		||||
            [ ##test? ]
 | 
			
		||||
            [ ##test-imm? ]
 | 
			
		||||
            [ ##test-vector? ]
 | 
			
		||||
            [ ##test-vector-branch? ]
 | 
			
		||||
        } 1|| [ f >>temp ] when
 | 
			
		||||
| 
						 | 
				
			
			@ -265,6 +267,36 @@ cpu x86.64? [
 | 
			
		|||
    } 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 }
 | 
			
		||||
| 
						 | 
				
			
			@ -995,6 +1027,217 @@ cpu x86.32? [
 | 
			
		|||
    } 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
 | 
			
		||||
 | 
			
		||||
! 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
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -242,6 +242,8 @@ CODEGEN: ##write-barrier %write-barrier
 | 
			
		|||
CODEGEN: ##write-barrier-imm %write-barrier-imm
 | 
			
		||||
CODEGEN: ##compare %compare
 | 
			
		||||
CODEGEN: ##compare-imm %compare-imm
 | 
			
		||||
CODEGEN: ##test %test
 | 
			
		||||
CODEGEN: ##test-imm %test-imm
 | 
			
		||||
CODEGEN: ##compare-integer %compare
 | 
			
		||||
CODEGEN: ##compare-integer-imm %compare-integer-imm
 | 
			
		||||
CODEGEN: ##compare-float-ordered %compare-float-ordered
 | 
			
		||||
| 
						 | 
				
			
			@ -268,6 +270,8 @@ CONDITIONAL: ##compare-branch %compare-branch
 | 
			
		|||
CONDITIONAL: ##compare-imm-branch %compare-imm-branch
 | 
			
		||||
CONDITIONAL: ##compare-integer-branch %compare-branch
 | 
			
		||||
CONDITIONAL: ##compare-integer-imm-branch %compare-integer-imm-branch
 | 
			
		||||
CONDITIONAL: ##test-branch %test-branch
 | 
			
		||||
CONDITIONAL: ##test-imm-branch %test-imm-branch
 | 
			
		||||
CONDITIONAL: ##compare-float-ordered-branch %compare-float-ordered-branch
 | 
			
		||||
CONDITIONAL: ##compare-float-unordered-branch %compare-float-unordered-branch
 | 
			
		||||
CONDITIONAL: ##test-vector-branch %test-vector-branch
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -475,15 +475,23 @@ HOOK: %call-gc cpu ( gc-roots -- )
 | 
			
		|||
HOOK: %prologue cpu ( n -- )
 | 
			
		||||
HOOK: %epilogue cpu ( n -- )
 | 
			
		||||
 | 
			
		||||
HOOK: %compare cpu ( dst temp cc src1 src2 -- )
 | 
			
		||||
HOOK: %compare-imm cpu ( dst temp cc src1 src2 -- )
 | 
			
		||||
HOOK: %compare-integer-imm cpu ( dst temp cc src1 src2 -- )
 | 
			
		||||
HOOK: %compare-float-ordered cpu ( dst temp cc src1 src2 -- )
 | 
			
		||||
HOOK: %compare-float-unordered cpu ( dst temp cc src1 src2 -- )
 | 
			
		||||
HOOK: test-instruction? cpu ( -- ? )
 | 
			
		||||
 | 
			
		||||
M: object test-instruction? f ;
 | 
			
		||||
 | 
			
		||||
HOOK: %compare cpu ( dst src1 src2 cc temp -- )
 | 
			
		||||
HOOK: %compare-imm cpu ( dst src1 src2 cc temp -- )
 | 
			
		||||
HOOK: %compare-integer-imm cpu ( dst src1 src2 cc temp -- )
 | 
			
		||||
HOOK: %test cpu ( dst src1 src2 cc temp -- )
 | 
			
		||||
HOOK: %test-imm cpu ( dst src1 src2 cc temp -- )
 | 
			
		||||
HOOK: %compare-float-ordered cpu ( dst src1 src2 cc temp -- )
 | 
			
		||||
HOOK: %compare-float-unordered cpu ( dst src1 src2 cc temp -- )
 | 
			
		||||
 | 
			
		||||
HOOK: %compare-branch cpu ( label cc src1 src2 -- )
 | 
			
		||||
HOOK: %compare-imm-branch cpu ( label cc src1 src2 -- )
 | 
			
		||||
HOOK: %compare-integer-imm-branch cpu ( label cc src1 src2 -- )
 | 
			
		||||
HOOK: %test-branch cpu ( label cc src1 src2 -- )
 | 
			
		||||
HOOK: %test-imm-branch cpu ( label cc src1 src2 -- )
 | 
			
		||||
HOOK: %compare-float-ordered-branch cpu ( label cc src1 src2 -- )
 | 
			
		||||
HOOK: %compare-float-unordered-branch cpu ( label cc src1 src2 -- )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,6 +72,8 @@ M: x86 complex-addressing? t ;
 | 
			
		|||
 | 
			
		||||
M: x86 fused-unboxing? t ;
 | 
			
		||||
 | 
			
		||||
M: x86 test-instruction? t ;
 | 
			
		||||
 | 
			
		||||
M: x86 immediate-store? immediate-comparand? ;
 | 
			
		||||
 | 
			
		||||
M: x86 %load-immediate dup 0 = [ drop dup XOR ] [ MOV ] if ;
 | 
			
		||||
| 
						 | 
				
			
			@ -525,28 +527,30 @@ M:: x86 %compare ( dst src1 src2 cc temp -- )
 | 
			
		|||
    src1 src2 CMP
 | 
			
		||||
    dst cc temp %boolean ;
 | 
			
		||||
 | 
			
		||||
: use-test? ( src1 src2 cc -- ? )
 | 
			
		||||
    [ register? ] [ 0 = ] [ { cc= cc/= } member? ] tri* and and ;
 | 
			
		||||
M:: x86 %test ( dst src1 src2 cc temp -- )
 | 
			
		||||
    src1 src2 TEST
 | 
			
		||||
    dst cc temp %boolean ;
 | 
			
		||||
 | 
			
		||||
: (%compare-tagged) ( src1 src2 -- )
 | 
			
		||||
    [ HEX: ffffffff CMP ] dip rc-absolute rel-literal ;
 | 
			
		||||
 | 
			
		||||
: (%compare-integer-imm) ( src1 src2 cc -- )
 | 
			
		||||
    3dup use-test? [ 2drop dup TEST ] [ drop CMP ] if ;
 | 
			
		||||
 | 
			
		||||
M:: x86 %compare-integer-imm ( dst src1 src2 cc temp -- )
 | 
			
		||||
    src1 src2 cc (%compare-integer-imm)
 | 
			
		||||
    src1 src2 CMP
 | 
			
		||||
    dst cc temp %boolean ;
 | 
			
		||||
 | 
			
		||||
: (%compare-imm) ( src1 src2 cc -- )
 | 
			
		||||
M:: x86 %test-imm ( dst src1 src2 cc temp -- )
 | 
			
		||||
    src1 src2 TEST
 | 
			
		||||
    dst cc temp %boolean ;
 | 
			
		||||
 | 
			
		||||
: (%compare-imm) ( src1 src2 -- )
 | 
			
		||||
    {
 | 
			
		||||
        { [ over fixnum? ] [ [ tag-fixnum ] dip (%compare-integer-imm) ] }
 | 
			
		||||
        { [ over not ] [ 2drop \ f type-number CMP ] }
 | 
			
		||||
        [ drop (%compare-tagged) ]
 | 
			
		||||
        { [ dup fixnum? ] [ tag-fixnum CMP ] }
 | 
			
		||||
        { [ dup not ] [ drop \ f type-number CMP ] }
 | 
			
		||||
        [ (%compare-tagged) ]
 | 
			
		||||
    } cond ;
 | 
			
		||||
 | 
			
		||||
M:: x86 %compare-imm ( dst src1 src2 cc temp -- )
 | 
			
		||||
    src1 src2 cc (%compare-imm)
 | 
			
		||||
    src1 src2 (%compare-imm)
 | 
			
		||||
    dst cc temp %boolean ;
 | 
			
		||||
 | 
			
		||||
: %branch ( label cc -- )
 | 
			
		||||
| 
						 | 
				
			
			@ -564,11 +568,19 @@ M:: x86 %compare-branch ( label src1 src2 cc -- )
 | 
			
		|||
    label cc %branch ;
 | 
			
		||||
 | 
			
		||||
M:: x86 %compare-integer-imm-branch ( label src1 src2 cc -- )
 | 
			
		||||
    src1 src2 cc (%compare-integer-imm)
 | 
			
		||||
    src1 src2 CMP
 | 
			
		||||
    label cc %branch ;
 | 
			
		||||
 | 
			
		||||
M:: x86 %test-branch ( label src1 src2 cc -- )
 | 
			
		||||
    src1 src2 TEST
 | 
			
		||||
    label cc %branch ;
 | 
			
		||||
 | 
			
		||||
M:: x86 %test-imm-branch ( label src1 src2 cc -- )
 | 
			
		||||
    src1 src2 TEST
 | 
			
		||||
    label cc %branch ;
 | 
			
		||||
 | 
			
		||||
M:: x86 %compare-imm-branch ( label src1 src2 cc -- )
 | 
			
		||||
    src1 src2 cc (%compare-imm)
 | 
			
		||||
    src1 src2 (%compare-imm)
 | 
			
		||||
    label cc %branch ;
 | 
			
		||||
 | 
			
		||||
M: x86 %add-float double-rep two-operand ADDSD ;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue