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)