]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/ssa/_gen/dec.rules
2adf061874ccfd45e7f4c314183647836d117faf
[gostls13.git] / src / cmd / compile / internal / ssa / _gen / dec.rules
1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // This file contains rules to decompose builtin compound types
6 // (complex,string,slice,interface) into their constituent
7 // types.  These rules work together with the decomposeBuiltIn
8 // pass which handles phis of these types.
9
10 (Store {t} _ _ mem) && t.Size() == 0 => mem
11
12 // complex ops
13 (ComplexReal (ComplexMake real _  )) => real
14 (ComplexImag (ComplexMake _ imag )) => imag
15
16 (Load <t> ptr mem) && t.IsComplex() && t.Size() == 8 =>
17   (ComplexMake
18     (Load <typ.Float32> ptr mem)
19     (Load <typ.Float32>
20       (OffPtr <typ.Float32Ptr> [4] ptr)
21       mem)
22     )
23 (Store {t} dst (ComplexMake real imag) mem) && t.Size() == 8 =>
24   (Store {typ.Float32}
25     (OffPtr <typ.Float32Ptr> [4] dst)
26     imag
27     (Store {typ.Float32} dst real mem))
28 (Load <t> ptr mem) && t.IsComplex() && t.Size() == 16 =>
29   (ComplexMake
30     (Load <typ.Float64> ptr mem)
31     (Load <typ.Float64>
32       (OffPtr <typ.Float64Ptr> [8] ptr)
33       mem)
34     )
35 (Store {t} dst (ComplexMake real imag) mem) && t.Size() == 16 =>
36   (Store {typ.Float64}
37     (OffPtr <typ.Float64Ptr> [8] dst)
38     imag
39     (Store {typ.Float64} dst real mem))
40
41 // string ops
42 (StringPtr (StringMake ptr _)) => ptr
43 (StringLen (StringMake _ len)) => len
44
45 (Load <t> ptr mem) && t.IsString() =>
46   (StringMake
47     (Load <typ.BytePtr> ptr mem)
48     (Load <typ.Int>
49       (OffPtr <typ.IntPtr> [config.PtrSize] ptr)
50       mem))
51 (Store dst (StringMake ptr len) mem) =>
52   (Store {typ.Int}
53     (OffPtr <typ.IntPtr> [config.PtrSize] dst)
54     len
55     (Store {typ.BytePtr} dst ptr mem))
56
57 // slice ops
58 (SlicePtr (SliceMake ptr _ _ )) => ptr
59 (SliceLen (SliceMake _ len _)) => len
60 (SliceCap (SliceMake _ _ cap)) => cap
61 (SlicePtrUnchecked (SliceMake ptr _ _ )) => ptr
62
63 (Load <t> ptr mem) && t.IsSlice() =>
64   (SliceMake
65     (Load <t.Elem().PtrTo()> ptr mem)
66     (Load <typ.Int>
67       (OffPtr <typ.IntPtr> [config.PtrSize] ptr)
68       mem)
69     (Load <typ.Int>
70       (OffPtr <typ.IntPtr> [2*config.PtrSize] ptr)
71       mem))
72 (Store {t} dst (SliceMake ptr len cap) mem) =>
73   (Store {typ.Int}
74     (OffPtr <typ.IntPtr> [2*config.PtrSize] dst)
75     cap
76     (Store {typ.Int}
77       (OffPtr <typ.IntPtr> [config.PtrSize] dst)
78       len
79       (Store {t.Elem().PtrTo()} dst ptr mem)))
80
81 // interface ops
82 (ITab (IMake itab _)) => itab
83 (IData (IMake _ data)) => data
84
85 (Load <t> ptr mem) && t.IsInterface() =>
86   (IMake
87     (Load <typ.Uintptr> ptr mem)
88     (Load <typ.BytePtr>
89       (OffPtr <typ.BytePtrPtr> [config.PtrSize] ptr)
90       mem))
91 (Store dst (IMake itab data) mem) =>
92   (Store {typ.BytePtr}
93     (OffPtr <typ.BytePtrPtr> [config.PtrSize] dst)
94     data
95     (Store {typ.Uintptr} dst itab mem))
96
97 // Helpers for expand calls
98 // Some of these are copied from generic.rules
99
100 (IMake _typ (StructMake1 val)) => (IMake _typ val)
101 (StructSelect [0] (IData x)) => (IData x)
102
103 (StructSelect (StructMake1 x)) => x
104 (StructSelect [0] (StructMake2 x _)) => x
105 (StructSelect [1] (StructMake2 _ x)) => x
106 (StructSelect [0] (StructMake3 x _ _)) => x
107 (StructSelect [1] (StructMake3 _ x _)) => x
108 (StructSelect [2] (StructMake3 _ _ x)) => x
109 (StructSelect [0] (StructMake4 x _ _ _)) => x
110 (StructSelect [1] (StructMake4 _ x _ _)) => x
111 (StructSelect [2] (StructMake4 _ _ x _)) => x
112 (StructSelect [3] (StructMake4 _ _ _ x)) => x
113
114 // Special case coming from immediate interface rewriting
115 // Typical case: (StructSelect [0] (IData (IMake typ dat)) rewrites to (StructSelect [0] dat)
116 // but because the interface is immediate, the type of "IData" is a one-element struct containing
117 // a pointer that is not the pointer type of dat (can be a *uint8).
118 // More annoying case: (ArraySelect[0] (StructSelect[0] isAPtr))
119 // There, result of the StructSelect is an Array (not a pointer) and
120 // the pre-rewrite input to the ArraySelect is a struct, not a pointer.
121 (StructSelect [0] x) && x.Type.IsPtr()  => x
122 (ArraySelect [0] x) && x.Type.IsPtr()  => x
123
124 // These, too.  Bits is bits.
125 (ArrayMake1 x) && x.Type.IsPtr() => x
126 (StructMake1 x) && x.Type.IsPtr() => x
127
128 (Store dst (StructMake1 <t> f0) mem) =>
129   (Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)
130 (Store dst (StructMake2 <t> f0 f1) mem) =>
131   (Store {t.FieldType(1)}
132     (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
133     f1
134     (Store {t.FieldType(0)}
135       (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
136         f0 mem))
137 (Store dst (StructMake3 <t> f0 f1 f2) mem) =>
138   (Store {t.FieldType(2)}
139     (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
140     f2
141     (Store {t.FieldType(1)}
142       (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
143       f1
144       (Store {t.FieldType(0)}
145         (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
146           f0 mem)))
147 (Store dst (StructMake4 <t> f0 f1 f2 f3) mem) =>
148   (Store {t.FieldType(3)}
149     (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] dst)
150     f3
151     (Store {t.FieldType(2)}
152       (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
153       f2
154       (Store {t.FieldType(1)}
155         (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
156         f1
157         (Store {t.FieldType(0)}
158           (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
159             f0 mem))))
160
161 (ArraySelect (ArrayMake1 x)) => x
162 (ArraySelect [0] (IData x)) => (IData x)
163
164 (Store dst (ArrayMake1 e) mem) => (Store {e.Type} dst e mem)
165
166 // NOTE removed must-not-be-SSA condition.
167 (ArraySelect [i] x:(Load <t> ptr mem)) =>
168   @x.Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.Elem().Size()*i] ptr) mem)
169
170 (StringPtr x:(Load <t> ptr mem)) && t.IsString() => @x.Block (Load <typ.BytePtr> ptr mem)
171 (StringLen x:(Load <t> ptr mem)) && t.IsString() => @x.Block (Load <typ.Int>
172       (OffPtr <typ.IntPtr> [config.PtrSize] ptr)
173       mem)
174
175 // NOTE removed must-not-be-SSA condition.
176 (StructSelect [i] x:(Load <t> ptr mem)) =>
177   @x.Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.FieldOff(int(i))] ptr) mem)
178
179 (ITab x:(Load <t> ptr mem)) && t.IsInterface() => @x.Block (Load <typ.Uintptr> ptr mem)
180
181 (IData x:(Load <t> ptr mem)) && t.IsInterface() => @x.Block (Load <typ.BytePtr>
182       (OffPtr <typ.BytePtrPtr> [config.PtrSize] ptr)
183       mem)
184
185 (SlicePtr x:(Load <t> ptr mem)) && t.IsSlice() => @x.Block (Load <t.Elem().PtrTo()> ptr mem)
186 (SliceLen x:(Load <t> ptr mem)) && t.IsSlice() => @x.Block (Load <typ.Int>
187       (OffPtr <typ.IntPtr> [config.PtrSize] ptr)
188       mem)
189 (SliceCap x:(Load <t> ptr mem)) && t.IsSlice() => @x.Block (Load <typ.Int>
190       (OffPtr <typ.IntPtr> [2*config.PtrSize] ptr)
191       mem)
192
193 (ComplexReal x:(Load <t> ptr mem)) && t.IsComplex() && t.Size() == 8 => @x.Block (Load <typ.Float32> ptr mem)
194 (ComplexImag x:(Load <t> ptr mem)) && t.IsComplex() && t.Size() == 8 => @x.Block (Load <typ.Float32>
195       (OffPtr <typ.Float32Ptr> [4] ptr)
196       mem)
197
198 (ComplexReal x:(Load <t> ptr mem)) && t.IsComplex() && t.Size() == 16 => @x.Block (Load <typ.Float64> ptr mem)
199 (ComplexImag x:(Load <t> ptr mem)) && t.IsComplex() && t.Size() == 16 => @x.Block (Load <typ.Float64>
200       (OffPtr <typ.Float64Ptr> [8] ptr)
201       mem)