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.Op != OpStructMake && data.Op != OpArrayMake1 => data
84 // Note: the conditional on data.Op ensures that StructMake/ArrayMake1 ops are
85 // unwrapped before the IMake is thrown away. See issue 77534.
86
87 (Load <t> ptr mem) && t.IsInterface() =>
88 (IMake
89 (Load <typ.Uintptr> ptr mem)
90 (Load <typ.BytePtr>
91 (OffPtr <typ.BytePtrPtr> [config.PtrSize] ptr)
92 mem))
93 (Store dst (IMake itab data) mem) =>
94 (Store {typ.BytePtr}
95 (OffPtr <typ.BytePtrPtr> [config.PtrSize] dst)
96 data
97 (Store {typ.Uintptr} dst itab mem))
98
99 // Helpers for expand calls
100 // Some of these are copied from generic.rules
101
102 (IMake _typ (StructMake ___)) => imakeOfStructMake(v)
103 (StructSelect (IData x)) && v.Type.Size() > 0 => (IData x)
104 (StructSelect (IData x)) && v.Type.Size() == 0 && v.Type.IsStruct() => (StructMake)
105 (StructSelect (IData x)) && v.Type.Size() == 0 && v.Type.IsArray() => (ArrayMake0)
106
107 (StructSelect [i] x:(StructMake ___)) => x.Args[i]
108
109 // Special case coming from immediate interface rewriting
110 // Typical case: (StructSelect [0] (IData (IMake typ dat)) rewrites to (StructSelect [0] dat)
111 // but because the interface is immediate, the type of "IData" is a one-element struct containing
112 // a pointer that is not the pointer type of dat (can be a *uint8).
113 // More annoying case: (ArraySelect[0] (StructSelect[0] isAPtr))
114 // There, result of the StructSelect is an Array (not a pointer) and
115 // the pre-rewrite input to the ArraySelect is a struct, not a pointer.
116 (StructSelect x) && x.Type.IsPtrShaped() => x
117 (ArraySelect [0] x) && x.Type.IsPtrShaped() => x
118
119 // These, too. Bits is bits.
120 (ArrayMake1 x) && x.Type.IsPtrShaped() => x
121 (StructMake x) && x.Type.IsPtrShaped() => x
122
123
124 (Store _ (StructMake ___) _) => rewriteStructStore(v)
125
126 (IMake _typ (ArrayMake1 val)) => (IMake _typ val)
127 (ArraySelect (ArrayMake1 x)) => x
128 (ArraySelect [0] (IData x)) => (IData x)
129
130 (Store dst (ArrayMake1 e) mem) => (Store {e.Type} dst e mem)
131
132 // NOTE removed must-not-be-SSA condition.
133 (ArraySelect [i] x:(Load <t> ptr mem)) =>
134 @x.Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.Elem().Size()*i] ptr) mem)
135
136 (StringPtr x:(Load <t> ptr mem)) && t.IsString() => @x.Block (Load <typ.BytePtr> ptr mem)
137 (StringLen x:(Load <t> ptr mem)) && t.IsString() => @x.Block (Load <typ.Int>
138 (OffPtr <typ.IntPtr> [config.PtrSize] ptr)
139 mem)
140
141 // NOTE removed must-not-be-SSA condition.
142 (StructSelect [i] x:(Load <t> ptr mem)) =>
143 @x.Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.FieldOff(int(i))] ptr) mem)
144
145 (ITab x:(Load <t> ptr mem)) && t.IsInterface() => @x.Block (Load <typ.Uintptr> ptr mem)
146
147 (IData x:(Load <t> ptr mem)) && t.IsInterface() => @x.Block (Load <typ.BytePtr>
148 (OffPtr <typ.BytePtrPtr> [config.PtrSize] ptr)
149 mem)
150
151 (SlicePtr x:(Load <t> ptr mem)) && t.IsSlice() => @x.Block (Load <t.Elem().PtrTo()> ptr mem)
152 (SliceLen x:(Load <t> ptr mem)) && t.IsSlice() => @x.Block (Load <typ.Int>
153 (OffPtr <typ.IntPtr> [config.PtrSize] ptr)
154 mem)
155 (SliceCap x:(Load <t> ptr mem)) && t.IsSlice() => @x.Block (Load <typ.Int>
156 (OffPtr <typ.IntPtr> [2*config.PtrSize] ptr)
157 mem)
158
159 (ComplexReal x:(Load <t> ptr mem)) && t.IsComplex() && t.Size() == 8 => @x.Block (Load <typ.Float32> ptr mem)
160 (ComplexImag x:(Load <t> ptr mem)) && t.IsComplex() && t.Size() == 8 => @x.Block (Load <typ.Float32>
161 (OffPtr <typ.Float32Ptr> [4] ptr)
162 mem)
163
164 (ComplexReal x:(Load <t> ptr mem)) && t.IsComplex() && t.Size() == 16 => @x.Block (Load <typ.Float64> ptr mem)
165 (ComplexImag x:(Load <t> ptr mem)) && t.IsComplex() && t.Size() == 16 => @x.Block (Load <typ.Float64>
166 (OffPtr <typ.Float64Ptr> [8] ptr)
167 mem)
168
View as plain text