(RotateLeft(64|32|16|8) (RotateLeft(64|32|16|8) x c) d) && c.Type.Size() == 2 && d.Type.Size() == 2 => (RotateLeft(64|32|16|8) x (Add16 <c.Type> c d))
(RotateLeft(64|32|16|8) (RotateLeft(64|32|16|8) x c) d) && c.Type.Size() == 1 && d.Type.Size() == 1 => (RotateLeft(64|32|16|8) x (Add8 <c.Type> c d))
-// Loading constant values from dictionaries and itabs.
-(Load <typ.BytePtr> (OffPtr [off] (Addr {s} sb) ) _) && isFixedSym(s, off) => (Addr {fixedSym(b.Func, s, off)} sb)
-(Load <typ.BytePtr> (OffPtr [off] (Convert (Addr {s} sb) _) ) _) && isFixedSym(s, off) => (Addr {fixedSym(b.Func, s, off)} sb)
-(Load <typ.BytePtr> (OffPtr [off] (ITab (IMake (Addr {s} sb) _))) _) && isFixedSym(s, off) => (Addr {fixedSym(b.Func, s, off)} sb)
-(Load <typ.BytePtr> (OffPtr [off] (ITab (IMake (Convert (Addr {s} sb) _) _))) _) && isFixedSym(s, off) => (Addr {fixedSym(b.Func, s, off)} sb)
-(Load <typ.Uintptr> (OffPtr [off] (Addr {s} sb) ) _) && isFixedSym(s, off) => (Addr {fixedSym(b.Func, s, off)} sb)
-(Load <typ.Uintptr> (OffPtr [off] (Convert (Addr {s} sb) _) ) _) && isFixedSym(s, off) => (Addr {fixedSym(b.Func, s, off)} sb)
-(Load <typ.Uintptr> (OffPtr [off] (ITab (IMake (Addr {s} sb) _))) _) && isFixedSym(s, off) => (Addr {fixedSym(b.Func, s, off)} sb)
-(Load <typ.Uintptr> (OffPtr [off] (ITab (IMake (Convert (Addr {s} sb) _) _))) _) && isFixedSym(s, off) => (Addr {fixedSym(b.Func, s, off)} sb)
-
-// Loading constant values from dictionaries and itabs. For offset 0.
-(Load <typ.BytePtr> (Addr {s} sb) _) && isFixedSym(s, 0) => (Addr {fixedSym(b.Func, s, 0)} sb)
-(Load <typ.BytePtr> (Convert (Addr {s} sb) _) _) && isFixedSym(s, 0) => (Addr {fixedSym(b.Func, s, 0)} sb)
-(Load <typ.BytePtr> (ITab (IMake (Addr {s} sb) _)) _) && isFixedSym(s, 0) => (Addr {fixedSym(b.Func, s, 0)} sb)
-(Load <typ.BytePtr> (ITab (IMake (Convert (Addr {s} sb) _) _)) _) && isFixedSym(s, 0) => (Addr {fixedSym(b.Func, s, 0)} sb)
-(Load <typ.Uintptr> (Addr {s} sb) _) && isFixedSym(s, 0) => (Addr {fixedSym(b.Func, s, 0)} sb)
-(Load <typ.Uintptr> (Convert (Addr {s} sb) _) _) && isFixedSym(s, 0) => (Addr {fixedSym(b.Func, s, 0)} sb)
-(Load <typ.Uintptr> (ITab (IMake (Addr {s} sb) _)) _) && isFixedSym(s, 0) => (Addr {fixedSym(b.Func, s, 0)} sb)
-(Load <typ.Uintptr> (ITab (IMake (Convert (Addr {s} sb) _) _)) _) && isFixedSym(s, 0) => (Addr {fixedSym(b.Func, s, 0)} sb)
-
-// Loading constant values from abi.PtrType.Elem.
-(Load <t> (OffPtr [off] (Addr {s} sb) ) _) && t.IsPtr() && isPtrElem(s, off) => (Addr {ptrElem(b.Func, s, off)} sb)
-(Load <t> (OffPtr [off] (Convert (Addr {s} sb) _) ) _) && t.IsPtr() && isPtrElem(s, off) => (Addr {ptrElem(b.Func, s, off)} sb)
-(Load <t> (OffPtr [off] (ITab (IMake (Addr {s} sb) _))) _) && t.IsPtr() && isPtrElem(s, off) => (Addr {ptrElem(b.Func, s, off)} sb)
-(Load <t> (OffPtr [off] (ITab (IMake (Convert (Addr {s} sb) _) _))) _) && t.IsPtr() && isPtrElem(s, off) => (Addr {ptrElem(b.Func, s, off)} sb)
-
-// Loading constant values from runtime._type.hash.
-(Load <t> (OffPtr [off] (Addr {sym} _) ) _) && t.IsInteger() && t.Size() == 4 && isFixed32(config, sym, off) => (Const32 [fixed32(config, sym, off)])
-(Load <t> (OffPtr [off] (Convert (Addr {sym} _) _) ) _) && t.IsInteger() && t.Size() == 4 && isFixed32(config, sym, off) => (Const32 [fixed32(config, sym, off)])
-(Load <t> (OffPtr [off] (ITab (IMake (Addr {sym} _) _))) _) && t.IsInteger() && t.Size() == 4 && isFixed32(config, sym, off) => (Const32 [fixed32(config, sym, off)])
-(Load <t> (OffPtr [off] (ITab (IMake (Convert (Addr {sym} _) _) _))) _) && t.IsInteger() && t.Size() == 4 && isFixed32(config, sym, off) => (Const32 [fixed32(config, sym, off)])
+// Loading fixed addresses and constants.
+(Load (Addr {s} sb) _) && isFixedLoad(v, s, 0) => rewriteFixedLoad(v, s, sb, 0)
+(Load (Convert (Addr {s} sb) _) _) && isFixedLoad(v, s, 0) => rewriteFixedLoad(v, s, sb, 0)
+(Load (ITab (IMake (Addr {s} sb) _)) _) && isFixedLoad(v, s, 0) => rewriteFixedLoad(v, s, sb, 0)
+(Load (ITab (IMake (Convert (Addr {s} sb) _) _)) _) && isFixedLoad(v, s, 0) => rewriteFixedLoad(v, s, sb, 0)
+(Load (OffPtr [off] (Addr {s} sb) ) _) && isFixedLoad(v, s, off) => rewriteFixedLoad(v, s, sb, off)
+(Load (OffPtr [off] (Convert (Addr {s} sb) _) ) _) && isFixedLoad(v, s, off) => rewriteFixedLoad(v, s, sb, off)
+(Load (OffPtr [off] (ITab (IMake (Addr {s} sb) _))) _) && isFixedLoad(v, s, off) => rewriteFixedLoad(v, s, sb, off)
+(Load (OffPtr [off] (ITab (IMake (Convert (Addr {s} sb) _) _))) _) && isFixedLoad(v, s, off) => rewriteFixedLoad(v, s, sb, off)
// Calling cmpstring a second time with the same arguments in the
// same memory state can reuse the results of the first call.
return true
}
-// isFixed32 returns true if the int32 at offset off in symbol sym
-// is known and constant.
-func isFixed32(c *Config, sym Sym, off int64) bool {
- return isFixed(c, sym, off, 4)
-}
-
-// isFixed returns true if the range [off,off+size] of the symbol sym
-// is known and constant.
-func isFixed(c *Config, sym Sym, off, size int64) bool {
- lsym := sym.(*obj.LSym)
- if lsym.Extra == nil {
- return false
- }
- if _, ok := (*lsym.Extra).(*obj.TypeInfo); ok {
- if off == 2*c.PtrSize && size == 4 {
- return true // type hash field
- }
- }
- return false
-}
-func fixed32(c *Config, sym Sym, off int64) int32 {
+// isFixedLoad returns true if the load can be resolved to fixed address or constant,
+// and can be rewritten by rewriteFixedLoad.
+func isFixedLoad(v *Value, sym Sym, off int64) bool {
lsym := sym.(*obj.LSym)
- if ti, ok := (*lsym.Extra).(*obj.TypeInfo); ok {
- if off == 2*c.PtrSize {
- return int32(types.TypeHash(ti.Type.(*types.Type)))
+ if (v.Type.IsPtrShaped() || v.Type.IsUintptr()) && lsym.Type == objabi.SRODATA {
+ for _, r := range lsym.R {
+ if (r.Type == objabi.R_ADDR || r.Type == objabi.R_WEAKADDR) && int64(r.Off) == off && r.Add == 0 {
+ return true
+ }
}
+ return false
}
- base.Fatalf("fixed32 data not known for %s:%d", sym, off)
- return 0
-}
-// isPtrElem returns true if sym is an instance of abi.PtrType and off
-// is equal to the offset of its Elem field.
-func isPtrElem(sym Sym, off int64) bool {
- lsym := sym.(*obj.LSym)
- if strings.HasPrefix(lsym.Name, "type:*") {
- if ti, ok := (*lsym.Extra).(*obj.TypeInfo); ok {
- t := ti.Type.(*types.Type)
- if t.Kind() == types.TPTR {
- if off == rttype.PtrType.OffsetOf("Elem") {
+ if strings.HasPrefix(lsym.Name, "type:") {
+ // Type symbols do not contain information about their fields, unlike the cases above.
+ // Hand-implement field accesses.
+ // TODO: can this be replaced with reflectdata.writeType and just use the code above?
+
+ t := (*lsym.Extra).(*obj.TypeInfo).Type.(*types.Type)
+
+ for _, f := range rttype.Type.Fields() {
+ if f.Offset == off && copyCompatibleType(v.Type, f.Type) {
+ switch f.Sym.Name {
+ case "Hash":
return true
+ default:
+ // fmt.Println("unknown field", f.Sym.Name)
+ return false
}
}
}
+
+ if t.IsPtr() && off == rttype.PtrType.OffsetOf("Elem") {
+ return true
+ }
+
+ return false
}
+
return false
}
-func ptrElem(f *Func, sym Sym, off int64) Sym {
+
+// rewriteFixedLoad rewrites a load to a fixed address or constant, if isFixedLoad returns true.
+func rewriteFixedLoad(v *Value, sym Sym, sb *Value, off int64) *Value {
+ b := v.Block
+ f := b.Func
+
lsym := sym.(*obj.LSym)
- if strings.HasPrefix(lsym.Name, "type:*") {
- if ti, ok := (*lsym.Extra).(*obj.TypeInfo); ok {
- t := ti.Type.(*types.Type)
- if t.Kind() == types.TPTR {
- if off == rttype.PtrType.OffsetOf("Elem") {
- elemSym := reflectdata.TypeLinksym(t.Elem())
- reflectdata.MarkTypeSymUsedInInterface(elemSym, f.fe.Func().Linksym())
- return elemSym
+ if (v.Type.IsPtrShaped() || v.Type.IsUintptr()) && lsym.Type == objabi.SRODATA {
+ for _, r := range lsym.R {
+ if (r.Type == objabi.R_ADDR || r.Type == objabi.R_WEAKADDR) && int64(r.Off) == off && r.Add == 0 {
+ if strings.HasPrefix(r.Sym.Name, "type:") {
+ // In case we're loading a type out of a dictionary, we need to record
+ // that the containing function might put that type in an interface.
+ // That information is currently recorded in relocations in the dictionary,
+ // but if we perform this load at compile time then the dictionary
+ // might be dead.
+ reflectdata.MarkTypeSymUsedInInterface(r.Sym, f.fe.Func().Linksym())
+ } else if strings.HasPrefix(r.Sym.Name, "go:itab") {
+ // Same, but if we're using an itab we need to record that the
+ // itab._type might be put in an interface.
+ reflectdata.MarkTypeSymUsedInInterface(r.Sym, f.fe.Func().Linksym())
}
+ v.reset(OpAddr)
+ v.Aux = symToAux(r.Sym)
+ v.AddArg(sb)
+ return v
}
}
+ base.Fatalf("fixedLoad data not known for %s:%d", sym, off)
}
- base.Fatalf("ptrElem data not known for %s:%d", sym, off)
- return nil
-}
-// isFixedSym returns true if the contents of sym at the given offset
-// is known and is the constant address of another symbol.
-func isFixedSym(sym Sym, off int64) bool {
- lsym := sym.(*obj.LSym)
- switch {
- case lsym.Type == objabi.SRODATA:
- // itabs, dictionaries
- default:
- return false
- }
- for _, r := range lsym.R {
- if (r.Type == objabi.R_ADDR || r.Type == objabi.R_WEAKADDR) && int64(r.Off) == off && r.Add == 0 {
- return true
- }
- }
- return false
-}
-func fixedSym(f *Func, sym Sym, off int64) Sym {
- lsym := sym.(*obj.LSym)
- for _, r := range lsym.R {
- if (r.Type == objabi.R_ADDR || r.Type == objabi.R_WEAKADDR) && int64(r.Off) == off {
- if strings.HasPrefix(r.Sym.Name, "type:") {
- // In case we're loading a type out of a dictionary, we need to record
- // that the containing function might put that type in an interface.
- // That information is currently recorded in relocations in the dictionary,
- // but if we perform this load at compile time then the dictionary
- // might be dead.
- reflectdata.MarkTypeSymUsedInInterface(r.Sym, f.fe.Func().Linksym())
- } else if strings.HasPrefix(r.Sym.Name, "go:itab") {
- // Same, but if we're using an itab we need to record that the
- // itab._type might be put in an interface.
- reflectdata.MarkTypeSymUsedInInterface(r.Sym, f.fe.Func().Linksym())
+ if strings.HasPrefix(lsym.Name, "type:") {
+ // Type symbols do not contain information about their fields, unlike the cases above.
+ // Hand-implement field accesses.
+ // TODO: can this be replaced with reflectdata.writeType and just use the code above?
+
+ t := (*lsym.Extra).(*obj.TypeInfo).Type.(*types.Type)
+
+ for _, f := range rttype.Type.Fields() {
+ if f.Offset == off && copyCompatibleType(v.Type, f.Type) {
+ switch f.Sym.Name {
+ case "Hash":
+ v.reset(OpConst32)
+ v.AuxInt = int64(types.TypeHash(t))
+ return v
+ default:
+ base.Fatalf("unknown field %s for fixedLoad of %s at offset %d", f.Sym.Name, lsym.Name, off)
+ }
}
- return r.Sym
}
+
+ if t.IsPtr() && off == rttype.PtrType.OffsetOf("Elem") {
+ elemSym := reflectdata.TypeLinksym(t.Elem())
+ reflectdata.MarkTypeSymUsedInInterface(elemSym, f.fe.Func().Linksym())
+ v.reset(OpAddr)
+ v.Aux = symToAux(elemSym)
+ v.AddArg(sb)
+ return v
+ }
+
+ base.Fatalf("fixedLoad data not known for %s:%d", sym, off)
}
- base.Fatalf("fixedSym data not known for %s:%d", sym, off)
+
+ base.Fatalf("fixedLoad data not known for %s:%d", sym, off)
return nil
}
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
- config := b.Func.Config
- typ := &b.Func.Config.Types
// match: (Load <t1> p1 (Store {t2} p2 x _))
// cond: isSamePtr(p1, p2) && copyCompatibleType(t1, x.Type) && t1.Size() == t2.Size()
// result: x
v.AddArg(v0)
return true
}
- // match: (Load <typ.BytePtr> (OffPtr [off] (Addr {s} sb) ) _)
- // cond: isFixedSym(s, off)
- // result: (Addr {fixedSym(b.Func, s, off)} sb)
- for {
- if v.Type != typ.BytePtr || v_0.Op != OpOffPtr {
- break
- }
- off := auxIntToInt64(v_0.AuxInt)
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpAddr {
- break
- }
- s := auxToSym(v_0_0.Aux)
- sb := v_0_0.Args[0]
- if !(isFixedSym(s, off)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, off))
- v.AddArg(sb)
- return true
- }
- // match: (Load <typ.BytePtr> (OffPtr [off] (Convert (Addr {s} sb) _) ) _)
- // cond: isFixedSym(s, off)
- // result: (Addr {fixedSym(b.Func, s, off)} sb)
- for {
- if v.Type != typ.BytePtr || v_0.Op != OpOffPtr {
- break
- }
- off := auxIntToInt64(v_0.AuxInt)
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpConvert {
- break
- }
- v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAddr {
- break
- }
- s := auxToSym(v_0_0_0.Aux)
- sb := v_0_0_0.Args[0]
- if !(isFixedSym(s, off)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, off))
- v.AddArg(sb)
- return true
- }
- // match: (Load <typ.BytePtr> (OffPtr [off] (ITab (IMake (Addr {s} sb) _))) _)
- // cond: isFixedSym(s, off)
- // result: (Addr {fixedSym(b.Func, s, off)} sb)
- for {
- if v.Type != typ.BytePtr || v_0.Op != OpOffPtr {
- break
- }
- off := auxIntToInt64(v_0.AuxInt)
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpITab {
- break
- }
- v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpIMake {
- break
- }
- v_0_0_0_0 := v_0_0_0.Args[0]
- if v_0_0_0_0.Op != OpAddr {
- break
- }
- s := auxToSym(v_0_0_0_0.Aux)
- sb := v_0_0_0_0.Args[0]
- if !(isFixedSym(s, off)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, off))
- v.AddArg(sb)
- return true
- }
- // match: (Load <typ.BytePtr> (OffPtr [off] (ITab (IMake (Convert (Addr {s} sb) _) _))) _)
- // cond: isFixedSym(s, off)
- // result: (Addr {fixedSym(b.Func, s, off)} sb)
- for {
- if v.Type != typ.BytePtr || v_0.Op != OpOffPtr {
- break
- }
- off := auxIntToInt64(v_0.AuxInt)
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpITab {
- break
- }
- v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpIMake {
- break
- }
- v_0_0_0_0 := v_0_0_0.Args[0]
- if v_0_0_0_0.Op != OpConvert {
- break
- }
- v_0_0_0_0_0 := v_0_0_0_0.Args[0]
- if v_0_0_0_0_0.Op != OpAddr {
- break
- }
- s := auxToSym(v_0_0_0_0_0.Aux)
- sb := v_0_0_0_0_0.Args[0]
- if !(isFixedSym(s, off)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, off))
- v.AddArg(sb)
- return true
- }
- // match: (Load <typ.Uintptr> (OffPtr [off] (Addr {s} sb) ) _)
- // cond: isFixedSym(s, off)
- // result: (Addr {fixedSym(b.Func, s, off)} sb)
- for {
- if v.Type != typ.Uintptr || v_0.Op != OpOffPtr {
- break
- }
- off := auxIntToInt64(v_0.AuxInt)
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpAddr {
- break
- }
- s := auxToSym(v_0_0.Aux)
- sb := v_0_0.Args[0]
- if !(isFixedSym(s, off)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, off))
- v.AddArg(sb)
- return true
- }
- // match: (Load <typ.Uintptr> (OffPtr [off] (Convert (Addr {s} sb) _) ) _)
- // cond: isFixedSym(s, off)
- // result: (Addr {fixedSym(b.Func, s, off)} sb)
- for {
- if v.Type != typ.Uintptr || v_0.Op != OpOffPtr {
- break
- }
- off := auxIntToInt64(v_0.AuxInt)
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpConvert {
- break
- }
- v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAddr {
- break
- }
- s := auxToSym(v_0_0_0.Aux)
- sb := v_0_0_0.Args[0]
- if !(isFixedSym(s, off)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, off))
- v.AddArg(sb)
- return true
- }
- // match: (Load <typ.Uintptr> (OffPtr [off] (ITab (IMake (Addr {s} sb) _))) _)
- // cond: isFixedSym(s, off)
- // result: (Addr {fixedSym(b.Func, s, off)} sb)
- for {
- if v.Type != typ.Uintptr || v_0.Op != OpOffPtr {
- break
- }
- off := auxIntToInt64(v_0.AuxInt)
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpITab {
- break
- }
- v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpIMake {
- break
- }
- v_0_0_0_0 := v_0_0_0.Args[0]
- if v_0_0_0_0.Op != OpAddr {
- break
- }
- s := auxToSym(v_0_0_0_0.Aux)
- sb := v_0_0_0_0.Args[0]
- if !(isFixedSym(s, off)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, off))
- v.AddArg(sb)
- return true
- }
- // match: (Load <typ.Uintptr> (OffPtr [off] (ITab (IMake (Convert (Addr {s} sb) _) _))) _)
- // cond: isFixedSym(s, off)
- // result: (Addr {fixedSym(b.Func, s, off)} sb)
- for {
- if v.Type != typ.Uintptr || v_0.Op != OpOffPtr {
- break
- }
- off := auxIntToInt64(v_0.AuxInt)
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpITab {
- break
- }
- v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpIMake {
- break
- }
- v_0_0_0_0 := v_0_0_0.Args[0]
- if v_0_0_0_0.Op != OpConvert {
- break
- }
- v_0_0_0_0_0 := v_0_0_0_0.Args[0]
- if v_0_0_0_0_0.Op != OpAddr {
- break
- }
- s := auxToSym(v_0_0_0_0_0.Aux)
- sb := v_0_0_0_0_0.Args[0]
- if !(isFixedSym(s, off)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, off))
- v.AddArg(sb)
- return true
- }
- // match: (Load <typ.BytePtr> (Addr {s} sb) _)
- // cond: isFixedSym(s, 0)
- // result: (Addr {fixedSym(b.Func, s, 0)} sb)
- for {
- if v.Type != typ.BytePtr || v_0.Op != OpAddr {
- break
- }
- s := auxToSym(v_0.Aux)
- sb := v_0.Args[0]
- if !(isFixedSym(s, 0)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, 0))
- v.AddArg(sb)
- return true
- }
- // match: (Load <typ.BytePtr> (Convert (Addr {s} sb) _) _)
- // cond: isFixedSym(s, 0)
- // result: (Addr {fixedSym(b.Func, s, 0)} sb)
- for {
- if v.Type != typ.BytePtr || v_0.Op != OpConvert {
- break
- }
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpAddr {
- break
- }
- s := auxToSym(v_0_0.Aux)
- sb := v_0_0.Args[0]
- if !(isFixedSym(s, 0)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, 0))
- v.AddArg(sb)
- return true
- }
- // match: (Load <typ.BytePtr> (ITab (IMake (Addr {s} sb) _)) _)
- // cond: isFixedSym(s, 0)
- // result: (Addr {fixedSym(b.Func, s, 0)} sb)
+ // match: (Load (Addr {s} sb) _)
+ // cond: isFixedLoad(v, s, 0)
+ // result: rewriteFixedLoad(v, s, sb, 0)
for {
- if v.Type != typ.BytePtr || v_0.Op != OpITab {
- break
- }
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpIMake {
- break
- }
- v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAddr {
- break
- }
- s := auxToSym(v_0_0_0.Aux)
- sb := v_0_0_0.Args[0]
- if !(isFixedSym(s, 0)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, 0))
- v.AddArg(sb)
- return true
- }
- // match: (Load <typ.BytePtr> (ITab (IMake (Convert (Addr {s} sb) _) _)) _)
- // cond: isFixedSym(s, 0)
- // result: (Addr {fixedSym(b.Func, s, 0)} sb)
- for {
- if v.Type != typ.BytePtr || v_0.Op != OpITab {
- break
- }
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpIMake {
- break
- }
- v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpConvert {
- break
- }
- v_0_0_0_0 := v_0_0_0.Args[0]
- if v_0_0_0_0.Op != OpAddr {
- break
- }
- s := auxToSym(v_0_0_0_0.Aux)
- sb := v_0_0_0_0.Args[0]
- if !(isFixedSym(s, 0)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, 0))
- v.AddArg(sb)
- return true
- }
- // match: (Load <typ.Uintptr> (Addr {s} sb) _)
- // cond: isFixedSym(s, 0)
- // result: (Addr {fixedSym(b.Func, s, 0)} sb)
- for {
- if v.Type != typ.Uintptr || v_0.Op != OpAddr {
+ if v_0.Op != OpAddr {
break
}
s := auxToSym(v_0.Aux)
sb := v_0.Args[0]
- if !(isFixedSym(s, 0)) {
+ if !(isFixedLoad(v, s, 0)) {
break
}
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, 0))
- v.AddArg(sb)
+ v.copyOf(rewriteFixedLoad(v, s, sb, 0))
return true
}
- // match: (Load <typ.Uintptr> (Convert (Addr {s} sb) _) _)
- // cond: isFixedSym(s, 0)
- // result: (Addr {fixedSym(b.Func, s, 0)} sb)
+ // match: (Load (Convert (Addr {s} sb) _) _)
+ // cond: isFixedLoad(v, s, 0)
+ // result: rewriteFixedLoad(v, s, sb, 0)
for {
- if v.Type != typ.Uintptr || v_0.Op != OpConvert {
+ if v_0.Op != OpConvert {
break
}
v_0_0 := v_0.Args[0]
}
s := auxToSym(v_0_0.Aux)
sb := v_0_0.Args[0]
- if !(isFixedSym(s, 0)) {
+ if !(isFixedLoad(v, s, 0)) {
break
}
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, 0))
- v.AddArg(sb)
+ v.copyOf(rewriteFixedLoad(v, s, sb, 0))
return true
}
- // match: (Load <typ.Uintptr> (ITab (IMake (Addr {s} sb) _)) _)
- // cond: isFixedSym(s, 0)
- // result: (Addr {fixedSym(b.Func, s, 0)} sb)
+ // match: (Load (ITab (IMake (Addr {s} sb) _)) _)
+ // cond: isFixedLoad(v, s, 0)
+ // result: rewriteFixedLoad(v, s, sb, 0)
for {
- if v.Type != typ.Uintptr || v_0.Op != OpITab {
+ if v_0.Op != OpITab {
break
}
v_0_0 := v_0.Args[0]
}
s := auxToSym(v_0_0_0.Aux)
sb := v_0_0_0.Args[0]
- if !(isFixedSym(s, 0)) {
+ if !(isFixedLoad(v, s, 0)) {
break
}
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, 0))
- v.AddArg(sb)
+ v.copyOf(rewriteFixedLoad(v, s, sb, 0))
return true
}
- // match: (Load <typ.Uintptr> (ITab (IMake (Convert (Addr {s} sb) _) _)) _)
- // cond: isFixedSym(s, 0)
- // result: (Addr {fixedSym(b.Func, s, 0)} sb)
+ // match: (Load (ITab (IMake (Convert (Addr {s} sb) _) _)) _)
+ // cond: isFixedLoad(v, s, 0)
+ // result: rewriteFixedLoad(v, s, sb, 0)
for {
- if v.Type != typ.Uintptr || v_0.Op != OpITab {
+ if v_0.Op != OpITab {
break
}
v_0_0 := v_0.Args[0]
}
s := auxToSym(v_0_0_0_0.Aux)
sb := v_0_0_0_0.Args[0]
- if !(isFixedSym(s, 0)) {
+ if !(isFixedLoad(v, s, 0)) {
break
}
- v.reset(OpAddr)
- v.Aux = symToAux(fixedSym(b.Func, s, 0))
- v.AddArg(sb)
+ v.copyOf(rewriteFixedLoad(v, s, sb, 0))
return true
}
- // match: (Load <t> (OffPtr [off] (Addr {s} sb) ) _)
- // cond: t.IsPtr() && isPtrElem(s, off)
- // result: (Addr {ptrElem(b.Func, s, off)} sb)
+ // match: (Load (OffPtr [off] (Addr {s} sb) ) _)
+ // cond: isFixedLoad(v, s, off)
+ // result: rewriteFixedLoad(v, s, sb, off)
for {
- t := v.Type
if v_0.Op != OpOffPtr {
break
}
}
s := auxToSym(v_0_0.Aux)
sb := v_0_0.Args[0]
- if !(t.IsPtr() && isPtrElem(s, off)) {
+ if !(isFixedLoad(v, s, off)) {
break
}
- v.reset(OpAddr)
- v.Aux = symToAux(ptrElem(b.Func, s, off))
- v.AddArg(sb)
+ v.copyOf(rewriteFixedLoad(v, s, sb, off))
return true
}
- // match: (Load <t> (OffPtr [off] (Convert (Addr {s} sb) _) ) _)
- // cond: t.IsPtr() && isPtrElem(s, off)
- // result: (Addr {ptrElem(b.Func, s, off)} sb)
+ // match: (Load (OffPtr [off] (Convert (Addr {s} sb) _) ) _)
+ // cond: isFixedLoad(v, s, off)
+ // result: rewriteFixedLoad(v, s, sb, off)
for {
- t := v.Type
if v_0.Op != OpOffPtr {
break
}
}
s := auxToSym(v_0_0_0.Aux)
sb := v_0_0_0.Args[0]
- if !(t.IsPtr() && isPtrElem(s, off)) {
+ if !(isFixedLoad(v, s, off)) {
break
}
- v.reset(OpAddr)
- v.Aux = symToAux(ptrElem(b.Func, s, off))
- v.AddArg(sb)
+ v.copyOf(rewriteFixedLoad(v, s, sb, off))
return true
}
- // match: (Load <t> (OffPtr [off] (ITab (IMake (Addr {s} sb) _))) _)
- // cond: t.IsPtr() && isPtrElem(s, off)
- // result: (Addr {ptrElem(b.Func, s, off)} sb)
+ // match: (Load (OffPtr [off] (ITab (IMake (Addr {s} sb) _))) _)
+ // cond: isFixedLoad(v, s, off)
+ // result: rewriteFixedLoad(v, s, sb, off)
for {
- t := v.Type
if v_0.Op != OpOffPtr {
break
}
}
s := auxToSym(v_0_0_0_0.Aux)
sb := v_0_0_0_0.Args[0]
- if !(t.IsPtr() && isPtrElem(s, off)) {
+ if !(isFixedLoad(v, s, off)) {
break
}
- v.reset(OpAddr)
- v.Aux = symToAux(ptrElem(b.Func, s, off))
- v.AddArg(sb)
+ v.copyOf(rewriteFixedLoad(v, s, sb, off))
return true
}
- // match: (Load <t> (OffPtr [off] (ITab (IMake (Convert (Addr {s} sb) _) _))) _)
- // cond: t.IsPtr() && isPtrElem(s, off)
- // result: (Addr {ptrElem(b.Func, s, off)} sb)
+ // match: (Load (OffPtr [off] (ITab (IMake (Convert (Addr {s} sb) _) _))) _)
+ // cond: isFixedLoad(v, s, off)
+ // result: rewriteFixedLoad(v, s, sb, off)
for {
- t := v.Type
if v_0.Op != OpOffPtr {
break
}
}
s := auxToSym(v_0_0_0_0_0.Aux)
sb := v_0_0_0_0_0.Args[0]
- if !(t.IsPtr() && isPtrElem(s, off)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(ptrElem(b.Func, s, off))
- v.AddArg(sb)
- return true
- }
- // match: (Load <t> (OffPtr [off] (Addr {sym} _) ) _)
- // cond: t.IsInteger() && t.Size() == 4 && isFixed32(config, sym, off)
- // result: (Const32 [fixed32(config, sym, off)])
- for {
- t := v.Type
- if v_0.Op != OpOffPtr {
- break
- }
- off := auxIntToInt64(v_0.AuxInt)
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpAddr {
- break
- }
- sym := auxToSym(v_0_0.Aux)
- if !(t.IsInteger() && t.Size() == 4 && isFixed32(config, sym, off)) {
- break
- }
- v.reset(OpConst32)
- v.AuxInt = int32ToAuxInt(fixed32(config, sym, off))
- return true
- }
- // match: (Load <t> (OffPtr [off] (Convert (Addr {sym} _) _) ) _)
- // cond: t.IsInteger() && t.Size() == 4 && isFixed32(config, sym, off)
- // result: (Const32 [fixed32(config, sym, off)])
- for {
- t := v.Type
- if v_0.Op != OpOffPtr {
+ if !(isFixedLoad(v, s, off)) {
break
}
- off := auxIntToInt64(v_0.AuxInt)
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpConvert {
- break
- }
- v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAddr {
- break
- }
- sym := auxToSym(v_0_0_0.Aux)
- if !(t.IsInteger() && t.Size() == 4 && isFixed32(config, sym, off)) {
- break
- }
- v.reset(OpConst32)
- v.AuxInt = int32ToAuxInt(fixed32(config, sym, off))
- return true
- }
- // match: (Load <t> (OffPtr [off] (ITab (IMake (Addr {sym} _) _))) _)
- // cond: t.IsInteger() && t.Size() == 4 && isFixed32(config, sym, off)
- // result: (Const32 [fixed32(config, sym, off)])
- for {
- t := v.Type
- if v_0.Op != OpOffPtr {
- break
- }
- off := auxIntToInt64(v_0.AuxInt)
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpITab {
- break
- }
- v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpIMake {
- break
- }
- v_0_0_0_0 := v_0_0_0.Args[0]
- if v_0_0_0_0.Op != OpAddr {
- break
- }
- sym := auxToSym(v_0_0_0_0.Aux)
- if !(t.IsInteger() && t.Size() == 4 && isFixed32(config, sym, off)) {
- break
- }
- v.reset(OpConst32)
- v.AuxInt = int32ToAuxInt(fixed32(config, sym, off))
- return true
- }
- // match: (Load <t> (OffPtr [off] (ITab (IMake (Convert (Addr {sym} _) _) _))) _)
- // cond: t.IsInteger() && t.Size() == 4 && isFixed32(config, sym, off)
- // result: (Const32 [fixed32(config, sym, off)])
- for {
- t := v.Type
- if v_0.Op != OpOffPtr {
- break
- }
- off := auxIntToInt64(v_0.AuxInt)
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpITab {
- break
- }
- v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpIMake {
- break
- }
- v_0_0_0_0 := v_0_0_0.Args[0]
- if v_0_0_0_0.Op != OpConvert {
- break
- }
- v_0_0_0_0_0 := v_0_0_0_0.Args[0]
- if v_0_0_0_0_0.Op != OpAddr {
- break
- }
- sym := auxToSym(v_0_0_0_0_0.Aux)
- if !(t.IsInteger() && t.Size() == 4 && isFixed32(config, sym, off)) {
- break
- }
- v.reset(OpConst32)
- v.AuxInt = int32ToAuxInt(fixed32(config, sym, off))
+ v.copyOf(rewriteFixedLoad(v, s, sb, off))
return true
}
return false