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) 202