cmd/compile: add variable length TRESULTS type for SSA use.
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>
diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go
index 43e501d..d4af451 100644
--- a/src/cmd/compile/internal/gc/fmt.go
+++ b/src/cmd/compile/internal/gc/fmt.go
@@ -711,6 +711,17 @@
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
diff --git a/src/cmd/compile/internal/types/etype_string.go b/src/cmd/compile/internal/types/etype_string.go
index 0ff05a8..14fd5b7 100644
--- a/src/cmd/compile/internal/types/etype_string.go
+++ b/src/cmd/compile/internal/types/etype_string.go
@@ -44,12 +44,13 @@
_ = 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) {
diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go
index a777a5f..9b05aef 100644
--- a/src/cmd/compile/internal/types/type.go
+++ b/src/cmd/compile/internal/types/type.go
@@ -66,8 +66,9 @@
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 @@
// 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 @@
t.Extra = new(Chan)
case TTUPLE:
t.Extra = new(Tuple)
+ case TRESULTS:
+ t.Extra = new(Results)
}
return t
}
@@ -512,6 +520,12 @@
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 @@
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 @@
}
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 @@
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) 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 @@
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