1 ! Copyright (C) 2008, 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien.c-types combinators
4 combinators.short-circuit compiler.cfg.instructions
5 compiler.cfg.utilities compiler.cfg.value-numbering.graph
6 compiler.cfg.value-numbering.math
7 compiler.cfg.value-numbering.rewrite cpu.architecture
8 endian generalizations grouping kernel make math sequences ;
9 IN: compiler.cfg.value-numbering.simd
11 ! Some lame constant folding for SIMD intrinsics. Eventually this
12 ! should be redone completely.
14 : useless-shuffle-vector-imm? ( insn -- ? )
15 [ shuffle>> ] [ rep>> rep-length <iota> ] bi sequence= ;
17 : compose-shuffle-vector-imm ( outer inner -- insn' )
18 2dup [ rep>> ] bi@ eq? [
19 [ [ dst>> ] [ src>> ] bi* ]
20 [ [ shuffle>> ] bi@ nths ]
22 2tri ##shuffle-vector-imm new-insn
25 : (fold-shuffle-vector-imm) ( shuffle bytes -- bytes' )
26 2dup length swap length /i group nths concat ;
28 : fold-shuffle-vector-imm ( outer inner -- insn' )
29 [ [ dst>> ] [ shuffle>> ] bi ] [ obj>> ] bi*
30 (fold-shuffle-vector-imm) ##load-reference new-insn ;
32 M: ##shuffle-vector-imm rewrite
34 { [ over useless-shuffle-vector-imm? ] [ drop [ dst>> ] [ src>> ] bi <copy> ] }
35 { [ dup ##shuffle-vector-imm? ] [ compose-shuffle-vector-imm ] }
36 { [ dup ##load-reference? ] [ fold-shuffle-vector-imm ] }
40 : scalar-value ( literal-insn rep -- byte-array )
42 { float-4-rep [ obj>> float>bits 4 >le ] }
43 { double-2-rep [ obj>> double>bits 8 >le ] }
44 [ [ val>> ] [ rep-component-type heap-size ] bi* >le ]
47 : (fold-scalar>vector) ( insn bytes -- insn' )
48 [ [ dst>> ] [ rep>> rep-length ] bi ] dip <repetition> concat
49 ##load-reference new-insn ;
51 : fold-scalar>vector ( outer inner -- insn' )
52 over rep>> scalar-value (fold-scalar>vector) ;
54 M: ##scalar>vector rewrite
56 { [ dup literal-insn? ] [ fold-scalar>vector ] }
57 { [ dup ##vector>scalar? ] [ [ dst>> ] [ src>> ] bi* <copy> ] }
61 :: fold-gather-vector-2 ( insn src1 src2 -- insn )
63 src1 src2 [ insn rep>> scalar-value ] bi@ append
64 ##load-reference new-insn ;
66 : rewrite-gather-vector-2 ( insn -- insn/f )
67 dup [ src1>> vreg>insn ] [ src2>> vreg>insn ] bi {
68 { [ 2dup [ literal-insn? ] both? ] [ fold-gather-vector-2 ] }
72 M: ##gather-vector-2 rewrite rewrite-gather-vector-2 ;
74 M: ##gather-int-vector-2 rewrite rewrite-gather-vector-2 ;
76 :: fold-gather-vector-4 ( insn src1 src2 src3 src4 -- insn )
80 [ insn rep>> scalar-value % ] 4 napply
82 ##load-reference new-insn ;
84 : rewrite-gather-vector-4 ( insn -- insn/f )
85 dup { [ src1>> ] [ src2>> ] [ src3>> ] [ src4>> ] } cleave [ vreg>insn ] 4 napply
87 { [ 4dup [ literal-insn? ] 4 napply and and and ] [ fold-gather-vector-4 ] }
91 M: ##gather-vector-4 rewrite rewrite-gather-vector-4 ;
93 M: ##gather-int-vector-4 rewrite rewrite-gather-vector-4 ;
95 : fold-shuffle-vector ( insn src1 src2 -- insn )
96 [ dst>> ] [ obj>> ] [ obj>> ] tri*
97 swap nths ##load-reference new-insn ;
99 M: ##shuffle-vector rewrite
100 dup [ src>> vreg>insn ] [ shuffle>> vreg>insn ] bi
102 { [ 2dup [ ##load-reference? ] both? ] [ fold-shuffle-vector ] }
106 M: ##xor-vector rewrite
108 [ [ dst>> ] [ rep>> ] bi ##zero-vector new-insn ] [ drop f ] if ;
110 : vector-not? ( insn -- ? )
115 [ [ src1>> ] [ src2>> ] bi [ vreg>insn ##fill-vector? ] either? ]
119 GENERIC: vector-not-src ( insn -- vreg )
121 M: ##not-vector vector-not-src
124 M: ##xor-vector vector-not-src
125 dup src1>> vreg>insn ##fill-vector? [ src2>> ] [ src1>> ] if ;
127 M: ##and-vector rewrite
129 { [ dup src1>> vreg>insn vector-not? ] [
132 [ src1>> vreg>insn vector-not-src ]
135 } cleave ##andn-vector new-insn
137 { [ dup src2>> vreg>insn vector-not? ] [
140 [ src2>> vreg>insn vector-not-src ]
143 } cleave ##andn-vector new-insn
148 M: ##andn-vector rewrite
149 dup src1>> vreg>insn vector-not? [
152 [ src1>> vreg>insn vector-not-src ]
155 } cleave ##and-vector new-insn