]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add variable length TRESULTS type for SSA use.
authorDavid Chase <drchase@google.com>
Mon, 13 Jul 2020 18:44:14 +0000 (14:44 -0400)
committerDavid Chase <drchase@google.com>
Thu, 17 Sep 2020 19:16:49 +0000 (19:16 +0000)
This type is very much like TTUPLE, but not just for pairs.
Used to describe results of a pre-expansion function call.
(will later probably also be used to describe the incoming args).

Change-Id: I811850cfcc2b3de85085eb4c2eca217c04c330b3
Reviewed-on: https://go-review.googlesource.com/c/go/+/242360
Trust: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/compile/internal/gc/fmt.go
src/cmd/compile/internal/types/etype_string.go
src/cmd/compile/internal/types/type.go

index 43e501deaf15b8cef84e598fe37a0d0e01ad1f79..d4af451506ac266f3ffff243eb9d0de6dc038511 100644 (file)
@@ -711,6 +711,17 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
                return
        }
 
+       if t.Etype == types.TRESULTS {
+               tys := t.Extra.(*types.Results).Types
+               for i, et := range tys {
+                       if i > 0 {
+                               b.WriteByte(',')
+                       }
+                       b.WriteString(et.String())
+               }
+               return
+       }
+
        flag, mode = flag.update(mode)
        if mode == FTypeIdName {
                flag |= FmtUnsigned
index 0ff05a8c2ae2b3fe845e726a3be811d7997a4323..14fd5b71df801ef27ef8a2b0be2ea4f4bbd0a750 100644 (file)
@@ -44,12 +44,13 @@ func _() {
        _ = x[TCHANARGS-33]
        _ = x[TSSA-34]
        _ = x[TTUPLE-35]
-       _ = x[NTYPE-36]
+       _ = x[TRESULTS-36]
+       _ = x[NTYPE-37]
 }
 
-const _EType_name = "xxxINT8UINT8INT16UINT16INT32UINT32INT64UINT64INTUINTUINTPTRCOMPLEX64COMPLEX128FLOAT32FLOAT64BOOLPTRFUNCSLICEARRAYSTRUCTCHANMAPINTERFORWANYSTRINGUNSAFEPTRIDEALNILBLANKFUNCARGSCHANARGSSSATUPLENTYPE"
+const _EType_name = "xxxINT8UINT8INT16UINT16INT32UINT32INT64UINT64INTUINTUINTPTRCOMPLEX64COMPLEX128FLOAT32FLOAT64BOOLPTRFUNCSLICEARRAYSTRUCTCHANMAPINTERFORWANYSTRINGUNSAFEPTRIDEALNILBLANKFUNCARGSCHANARGSSSATUPLERESULTSNTYPE"
 
-var _EType_index = [...]uint8{0, 3, 7, 12, 17, 23, 28, 34, 39, 45, 48, 52, 59, 68, 78, 85, 92, 96, 99, 103, 108, 113, 119, 123, 126, 131, 135, 138, 144, 153, 158, 161, 166, 174, 182, 185, 190, 195}
+var _EType_index = [...]uint8{0, 3, 7, 12, 17, 23, 28, 34, 39, 45, 48, 52, 59, 68, 78, 85, 92, 96, 99, 103, 108, 113, 119, 123, 126, 131, 135, 138, 144, 153, 158, 161, 166, 174, 182, 185, 190, 197, 202}
 
 func (i EType) String() string {
        if i >= EType(len(_EType_index)-1) {
index a777a5fd90758a7ad7139203c28913062861ce90..9b05aef429f5ac1e22c59507368b24346ae453f6 100644 (file)
@@ -66,8 +66,9 @@ const (
        TCHANARGS
 
        // SSA backend types
-       TSSA   // internal types used by SSA backend (flags, memory, etc.)
-       TTUPLE // a pair of types, used by SSA backend
+       TSSA     // internal types used by SSA backend (flags, memory, etc.)
+       TTUPLE   // a pair of types, used by SSA backend
+       TRESULTS // multiuple types; the resulting of calling a function or method, plus a memory at the end.
 
        NTYPE
 )
@@ -330,6 +331,11 @@ type Tuple struct {
        // Any tuple with a memory type must put that memory type second.
 }
 
+type Results struct {
+       Types []*Type
+       // Any Results with a memory type must put that memory type last.
+}
+
 // Array contains Type fields specific to array types.
 type Array struct {
        Elem  *Type // element type
@@ -466,6 +472,8 @@ func New(et EType) *Type {
                t.Extra = new(Chan)
        case TTUPLE:
                t.Extra = new(Tuple)
+       case TRESULTS:
+               t.Extra = new(Results)
        }
        return t
 }
@@ -512,6 +520,12 @@ func NewTuple(t1, t2 *Type) *Type {
        return t
 }
 
+func NewResults(types []*Type) *Type {
+       t := New(TRESULTS)
+       t.Extra.(*Results).Types = types
+       return t
+}
+
 func newSSA(name string) *Type {
        t := New(TSSA)
        t.Extra = name
@@ -688,7 +702,7 @@ func (t *Type) copy() *Type {
        case TARRAY:
                x := *t.Extra.(*Array)
                nt.Extra = &x
-       case TTUPLE, TSSA:
+       case TTUPLE, TSSA, TRESULTS:
                Fatalf("ssa types cannot be copied")
        }
        // TODO(mdempsky): Find out why this is necessary and explain.
@@ -1051,6 +1065,23 @@ func (t *Type) cmp(x *Type) Cmp {
                }
                return ttup.second.Compare(xtup.second)
 
+       case TRESULTS:
+               xResults := x.Extra.(*Results)
+               tResults := t.Extra.(*Results)
+               xl, tl := len(xResults.Types), len(tResults.Types)
+               if tl != xl {
+                       if tl < xl {
+                               return CMPlt
+                       }
+                       return CMPgt
+               }
+               for i := 0; i < tl; i++ {
+                       if c := tResults.Types[i].Compare(xResults.Types[i]); c != CMPeq {
+                               return c
+                       }
+               }
+               return CMPeq
+
        case TMAP:
                if c := t.Key().cmp(x.Key()); c != CMPeq {
                        return c
@@ -1305,6 +1336,9 @@ func (t *Type) FieldType(i int) *Type {
                        panic("bad tuple index")
                }
        }
+       if t.Etype == TRESULTS {
+               return t.Extra.(*Results).Types[i]
+       }
        return t.Field(i).Type
 }
 func (t *Type) FieldOff(i int) int64 {
@@ -1382,11 +1416,20 @@ func (t *Type) ChanDir() ChanDir {
 }
 
 func (t *Type) IsMemory() bool {
-       return t == TypeMem || t.Etype == TTUPLE && t.Extra.(*Tuple).second == TypeMem
+       if t == TypeMem || t.Etype == TTUPLE && t.Extra.(*Tuple).second == TypeMem {
+               return true
+       }
+       if t.Etype == TRESULTS {
+               if types := t.Extra.(*Results).Types; len(types) > 0 && types[len(types)-1] == TypeMem {
+                       return true
+               }
+       }
+       return false
 }
-func (t *Type) IsFlags() bool { return t == TypeFlags }
-func (t *Type) IsVoid() bool  { return t == TypeVoid }
-func (t *Type) IsTuple() bool { return t.Etype == TTUPLE }
+func (t *Type) IsFlags() bool   { return t == TypeFlags }
+func (t *Type) IsVoid() bool    { return t == TypeVoid }
+func (t *Type) IsTuple() bool   { return t.Etype == TTUPLE }
+func (t *Type) IsResults() bool { return t.Etype == TRESULTS }
 
 // IsUntyped reports whether t is an untyped type.
 func (t *Type) IsUntyped() bool {
@@ -1431,6 +1474,15 @@ func (t *Type) HasPointers() bool {
        case TTUPLE:
                ttup := t.Extra.(*Tuple)
                return ttup.first.HasPointers() || ttup.second.HasPointers()
+
+       case TRESULTS:
+               types := t.Extra.(*Results).Types
+               for _, et := range types {
+                       if et.HasPointers() {
+                               return true
+                       }
+               }
+               return false
        }
 
        return true