121 lines
3.8 KiB
Factor
121 lines
3.8 KiB
Factor
! Copyright (C) 2008, 2009 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
|
|
vectors locals make alien.c-types io.binary grouping
|
|
math.vectors.simd.intrinsics
|
|
compiler.cfg
|
|
compiler.cfg.registers
|
|
compiler.cfg.comparisons
|
|
compiler.cfg.instructions
|
|
compiler.cfg.value-numbering.expressions
|
|
compiler.cfg.value-numbering.graph
|
|
compiler.cfg.value-numbering.rewrite
|
|
compiler.cfg.value-numbering.simplify ;
|
|
IN: compiler.cfg.value-numbering.simd
|
|
|
|
M: ##alien-vector rewrite rewrite-alien-addressing ;
|
|
M: ##set-alien-vector rewrite rewrite-alien-addressing ;
|
|
|
|
! Some lame constant folding for SIMD intrinsics. Eventually this
|
|
! should be redone completely.
|
|
|
|
: rewrite-shuffle-vector-imm ( insn expr -- insn' )
|
|
2dup [ rep>> ] bi@ eq? [
|
|
[ [ dst>> ] [ src>> vn>vreg ] 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 ( insn expr -- insn' )
|
|
[ [ dst>> ] [ shuffle>> ] bi ] dip value>>
|
|
(fold-shuffle-vector-imm) \ ##load-constant new-insn ;
|
|
|
|
M: ##shuffle-vector-imm rewrite
|
|
dup src>> vreg>expr {
|
|
{ [ dup shuffle-vector-imm-expr? ] [ rewrite-shuffle-vector-imm ] }
|
|
{ [ dup reference-expr? ] [ fold-shuffle-vector-imm ] }
|
|
{ [ dup constant-expr? ] [ fold-shuffle-vector-imm ] }
|
|
[ 2drop f ]
|
|
} cond ;
|
|
|
|
: (fold-scalar>vector) ( insn bytes -- insn' )
|
|
[ [ dst>> ] [ rep>> rep-length ] bi ] dip <repetition> concat
|
|
\ ##load-constant new-insn ;
|
|
|
|
: fold-scalar>vector ( insn expr -- insn' )
|
|
value>> over rep>> {
|
|
{ float-4-rep [ float>bits 4 >le (fold-scalar>vector) ] }
|
|
{ double-2-rep [ double>bits 8 >le (fold-scalar>vector) ] }
|
|
[ [ untag-fixnum ] dip rep-component-type heap-size >le (fold-scalar>vector) ]
|
|
} case ;
|
|
|
|
M: ##scalar>vector rewrite
|
|
dup src>> vreg>expr dup constant-expr?
|
|
[ fold-scalar>vector ] [ 2drop f ] if ;
|
|
|
|
M: ##xor-vector rewrite
|
|
dup [ src1>> vreg>vn ] [ src2>> vreg>vn ] bi eq?
|
|
[ [ dst>> ] [ rep>> ] bi \ ##zero-vector new-insn ] [ drop f ] if ;
|
|
|
|
: vector-not? ( expr -- ? )
|
|
{
|
|
[ not-vector-expr? ]
|
|
[ {
|
|
[ xor-vector-expr? ]
|
|
[ [ src1>> ] [ src2>> ] bi [ vn>expr fill-vector-expr? ] either? ]
|
|
} 1&& ]
|
|
} 1|| ;
|
|
|
|
GENERIC: vector-not-src ( expr -- vreg )
|
|
M: not-vector-expr vector-not-src src>> vn>vreg ;
|
|
M: xor-vector-expr vector-not-src
|
|
dup src1>> vn>expr fill-vector-expr? [ src2>> ] [ src1>> ] if vn>vreg ;
|
|
|
|
M: ##and-vector rewrite
|
|
{
|
|
{ [ dup src1>> vreg>expr vector-not? ] [
|
|
{
|
|
[ dst>> ]
|
|
[ src1>> vreg>expr vector-not-src ]
|
|
[ src2>> ]
|
|
[ rep>> ]
|
|
} cleave \ ##andn-vector new-insn
|
|
] }
|
|
{ [ dup src2>> vreg>expr vector-not? ] [
|
|
{
|
|
[ dst>> ]
|
|
[ src2>> vreg>expr vector-not-src ]
|
|
[ src1>> ]
|
|
[ rep>> ]
|
|
} cleave \ ##andn-vector new-insn
|
|
] }
|
|
[ drop f ]
|
|
} cond ;
|
|
|
|
M: ##andn-vector rewrite
|
|
dup src1>> vreg>expr vector-not? [
|
|
{
|
|
[ dst>> ]
|
|
[ src1>> vreg>expr vector-not-src ]
|
|
[ src2>> ]
|
|
[ rep>> ]
|
|
} cleave \ ##and-vector new-insn
|
|
] [ drop f ] if ;
|
|
|
|
M: scalar>vector-expr simplify*
|
|
src>> vn>expr {
|
|
{ [ dup vector>scalar-expr? ] [ src>> ] }
|
|
[ drop f ]
|
|
} cond ;
|
|
|
|
M: shuffle-vector-imm-expr simplify*
|
|
[ src>> ] [ shuffle>> ] [ rep>> rep-length iota ] tri
|
|
sequence= [ drop f ] unless ;
|
|
|