This reverts commit
cd55f86b8dcfc139ee5c17d32530ac9e758c8bc0 (CL 681937)
Reason for revert: still causing compiler failures on Google test code
Change-Id: I5cd482fd607fd060a523257082d48821b5f965d6
Reviewed-on: https://go-review.googlesource.com/c/go/+/695016
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
@x.Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.FieldOff(int(i))] ptr) mem)
// Putting struct{*byte} and similar into direct interfaces.
-(IMake _typ (StructMake val)) => imakeOfStructMake(v)
-(StructSelect [_] (IData x)) => (IData x)
+(IMake _typ (StructMake val)) => (IMake _typ val)
+(StructSelect [0] (IData x)) => (IData x)
// un-SSAable values use mem->mem copies
(Store {t} dst (Load src mem) mem) && !CanSSA(t) =>
if a.Op == OpIMake {
data := a.Args[1]
for data.Op == OpStructMake || data.Op == OpArrayMake1 {
- // A struct make might have a few zero-sized fields.
- // Use the pointer-y one we know is there.
- for _, a := range data.Args {
- if a.Type.Size() > 0 {
- data = a
- break
- }
- }
+ data = data.Args[0]
}
return x.decomposeAsNecessary(pos, b, data, mem, rc.next(data.Type))
}
func panicBoundsCCToAux(p PanicBoundsCC) Aux {
return p
}
-
-// When v is (IMake typ (StructMake ...)), convert to
-// (IMake typ arg) where arg is the pointer-y argument to
-// the StructMake (there must be exactly one).
-func imakeOfStructMake(v *Value) *Value {
- var arg *Value
- for _, a := range v.Args[1].Args {
- if a.Type.Size() > 0 {
- arg = a
- break
- }
- }
- return v.Block.NewValue2(v.Pos, OpIMake, v.Type, v.Args[0], arg)
-}
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (IMake _typ (StructMake val))
- // result: imakeOfStructMake(v)
+ // result: (IMake _typ val)
for {
+ _typ := v_0
if v_1.Op != OpStructMake || len(v_1.Args) != 1 {
break
}
- v.copyOf(imakeOfStructMake(v))
+ val := v_1.Args[0]
+ v.reset(OpIMake)
+ v.AddArg2(_typ, val)
return true
}
// match: (IMake _typ (ArrayMake1 val))
v0.AddArg2(v1, mem)
return true
}
- // match: (StructSelect [_] (IData x))
+ // match: (StructSelect [0] (IData x))
// result: (IData x)
for {
- if v_0.Op != OpIData {
+ if auxIntToInt64(v.AuxInt) != 0 || v_0.Op != OpIData {
break
}
x := v_0.Args[0]
// Can this type be stored directly in an interface word?
// Yes, if the representation is a single pointer.
func IsDirectIface(t *Type) bool {
- return t.Size() == int64(PtrSize) && PtrDataSize(t) == int64(PtrSize)
+ switch t.Kind() {
+ case TPTR:
+ // Pointers to notinheap types must be stored indirectly. See issue 42076.
+ return !t.Elem().NotInHeap()
+ case TCHAN,
+ TMAP,
+ TFUNC,
+ TUNSAFEPTR:
+ return true
+
+ case TARRAY:
+ // Array of 1 direct iface type can be direct.
+ return t.NumElem() == 1 && IsDirectIface(t.Elem())
+
+ case TSTRUCT:
+ // Struct with 1 field of direct iface type can be direct.
+ return t.NumFields() == 1 && IsDirectIface(t.Field(0).Type)
+ }
+
+ return false
}
// IsInterfaceMethod reports whether (field) m is
TFlagGCMaskOnDemand TFlag = 1 << 4
// TFlagDirectIface means that a value of this type is stored directly
- // in the data field of an interface, instead of indirectly.
- // This flag is just a cached computation of Size_ == PtrBytes == goarch.PtrSize.
+ // in the data field of an interface, instead of indirectly. Normally
+ // this means the type is pointer-ish.
TFlagDirectIface TFlag = 1 << 5
// Leaving this breadcrumb behind for dlv. It should not be used, and no
}
switch {
- case typ.Size_ == goarch.PtrSize && typ.PtrBytes == goarch.PtrSize:
+ case len(fs) == 1 && fs[0].Typ.IsDirectIface():
+ // structs of 1 direct iface type can be direct
typ.TFlag |= abi.TFlagDirectIface
default:
typ.TFlag &^= abi.TFlagDirectIface
}
switch {
- case array.Size_ == goarch.PtrSize && array.PtrBytes == goarch.PtrSize:
+ case length == 1 && typ.IsDirectIface():
+ // array of 1 direct iface type can be direct
array.TFlag |= abi.TFlagDirectIface
default:
array.TFlag &^= abi.TFlagDirectIface