github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/compile/ssa/_gen/dec.rules (about) 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.IsPtrShaped() => x 122 (ArraySelect [0] x) && x.Type.IsPtrShaped() => x 123 124 // These, too. Bits is bits. 125 (ArrayMake1 x) && x.Type.IsPtrShaped() => x 126 (StructMake1 x) && x.Type.IsPtrShaped() => 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)