]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add types.SoleComponent, use in convFuncName
authorJosh Bleecher Snyder <josharian@gmail.com>
Wed, 7 Nov 2018 00:27:58 +0000 (16:27 -0800)
committerJosh Bleecher Snyder <josharian@gmail.com>
Wed, 27 Feb 2019 18:07:42 +0000 (18:07 +0000)
The specialized conversion functions care only
about a type's layout in memory, so e.g.
[1]string is equivalent to string.

Add types.SoleComponent to assist with such use cases,
and use it for the specialized conversion functions.

Increases the number of convTstring calls by ~1%.

Change-Id: I09a392909f2037387b30642781e65f707a048af5
Reviewed-on: https://go-review.googlesource.com/c/148577
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/gc/walk.go
src/cmd/compile/internal/types/type.go

index 1d6321212ef16a4ac56986cbf2cf285d3ca27b3f..41a9d8e9dcc4706ee40fb97c4b34b74334c78a64 100644 (file)
@@ -398,10 +398,14 @@ func convFuncName(from, to *types.Type) (fnname string, needsaddr bool) {
                        return "convT32", false
                case from.Size() == 8 && from.Align == types.Types[TUINT64].Align && !types.Haspointers(from):
                        return "convT64", false
-               case from.IsString():
-                       return "convTstring", false
-               case from.IsSlice():
-                       return "convTslice", false
+               }
+               if sc := from.SoleComponent(); sc != nil {
+                       switch {
+                       case sc.IsString():
+                               return "convTstring", false
+                       case sc.IsSlice():
+                               return "convTslice", false
+                       }
                }
 
                switch tkind {
index 7d123e46105c3d8a5aaab1f27f913a0fbe3c512f..e2f3e66d8bffb7112f66d0cf32db95c55f0ca3b1 100644 (file)
@@ -1395,6 +1395,28 @@ func (t *Type) NumComponents(countBlank componentsIncludeBlankFields) int64 {
        return 1
 }
 
+// SoleComponent returns the only primitive component in t,
+// if there is exactly one. Otherwise, it returns nil.
+// Components are counted as in NumComponents, including blank fields.
+func (t *Type) SoleComponent() *Type {
+       switch t.Etype {
+       case TSTRUCT:
+               if t.IsFuncArgStruct() {
+                       Fatalf("SoleComponent func arg struct")
+               }
+               if t.NumFields() != 1 {
+                       return nil
+               }
+               return t.Field(0).Type.SoleComponent()
+       case TARRAY:
+               if t.NumElem() != 1 {
+                       return nil
+               }
+               return t.Elem().SoleComponent()
+       }
+       return t
+}
+
 // ChanDir returns the direction of a channel type t.
 // The direction will be one of Crecv, Csend, or Cboth.
 func (t *Type) ChanDir() ChanDir {