1 ! Copyright (C) 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors combinators combinators.short-circuit fry
4 kernel make math sequences
9 compiler.cfg.instructions
11 compiler.cfg.gvn.graph
12 compiler.cfg.gvn.rewrite ;
13 IN: compiler.cfg.gvn.alien
15 M: ##box-displaced-alien rewrite
16 dup displacement>> vreg>insn zero-insn?
17 [ [ dst>> ] [ base>> ] bi <copy> ] [ drop f ] if ;
19 ! ##box-displaced-alien f 1 2 3 <class>
20 ! ##unbox-c-ptr 4 1 <class>
22 ! ##box-displaced-alien f 1 2 3 <class>
23 ! ##unbox-c-ptr 5 3 <class>
26 : rewrite-unbox-alien ( insn box-insn -- insn )
27 [ dst>> ] [ src>> ] bi* <copy> ;
29 : rewrite-unbox-displaced-alien ( insn box-insn -- insns )
32 [ [ base>> ] [ base-class>> ] [ displacement>> ] tri ] bi*
37 : rewrite-unbox-any-c-ptr ( insn -- insn/f )
40 { [ dup ##box-alien? ] [ rewrite-unbox-alien ] }
41 { [ dup ##box-displaced-alien? ] [ rewrite-unbox-displaced-alien ] }
45 M: ##unbox-any-c-ptr rewrite rewrite-unbox-any-c-ptr ;
47 M: ##unbox-alien rewrite rewrite-unbox-any-c-ptr ;
49 ! Fuse ##add-imm into ##load-memory(-imm) and ##store-memory(-imm)
50 ! just update the offset in the instruction
51 : fuse-base-offset? ( insn -- ? )
52 base>> vreg>insn ##add-imm? ;
54 : fuse-base-offset ( insn -- insn' )
55 clone dup base>> vreg>insn
56 [ src1>> ] [ src2>> ] bi
57 [ >>base ] [ '[ _ + ] change-offset ] bi* ;
59 ! Fuse ##add-imm into ##load-memory and ##store-memory
60 ! just update the offset in the instruction
61 : fuse-displacement-offset? ( insn -- ? )
62 { [ scale>> 0 = ] [ displacement>> vreg>insn ##add-imm? ] } 1&& ;
64 : fuse-displacement-offset ( insn -- insn' )
65 clone dup displacement>> vreg>insn
66 [ src1>> ] [ src2>> ] bi
67 [ >>displacement ] [ '[ _ + ] change-offset ] bi* ;
69 ! Fuse ##add into ##load-memory-imm and ##store-memory-imm
70 ! construct a new ##load-memory or ##store-memory with the
71 ! ##add's operand as the displacement
72 : fuse-displacement? ( insn -- ? )
74 [ offset>> 0 = complex-addressing? or ]
75 [ base>> vreg>insn ##add? ]
78 GENERIC: alien-insn-value ( insn -- value )
80 M: ##load-memory-imm alien-insn-value dst>> ;
81 M: ##store-memory-imm alien-insn-value src>> ;
83 GENERIC: new-alien-insn ( value base displacement scale offset rep c-type insn -- insn )
85 M: ##load-memory-imm new-alien-insn drop \ ##load-memory new-insn ;
86 M: ##store-memory-imm new-alien-insn drop \ ##store-memory new-insn ;
88 : fuse-displacement ( insn -- insn' )
91 [ base>> vreg>insn [ src1>> ] [ src2>> ] bi ]
97 } cleave new-alien-insn ;
99 ! Fuse ##shl-imm into ##load-memory or ##store-memory
100 : scale-insn? ( insn -- ? )
101 { [ ##shl-imm? ] [ src2>> { 1 2 3 } member? ] } 1&& ;
103 : fuse-scale? ( insn -- ? )
104 { [ scale>> 0 = ] [ displacement>> vreg>insn scale-insn? ] } 1&& ;
106 : fuse-scale ( insn -- insn' )
107 clone dup displacement>> vreg>insn
108 [ src1>> ] [ src2>> ] bi
109 [ >>displacement ] [ >>scale ] bi* ;
111 : rewrite-memory-op ( insn -- insn/f )
112 complex-addressing? [
114 { [ dup fuse-base-offset? ] [ fuse-base-offset ] }
115 { [ dup fuse-displacement-offset? ] [ fuse-displacement-offset ] }
116 { [ dup fuse-scale? ] [ fuse-scale ] }
121 : rewrite-memory-imm-op ( insn -- insn/f )
123 { [ dup fuse-base-offset? ] [ fuse-base-offset ] }
124 { [ dup fuse-displacement? ] [ fuse-displacement ] }
128 M: ##load-memory rewrite rewrite-memory-op ;
129 M: ##load-memory-imm rewrite rewrite-memory-imm-op ;
130 M: ##store-memory rewrite rewrite-memory-op ;
131 M: ##store-memory-imm rewrite rewrite-memory-imm-op ;