aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types/type.go
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2020-07-13 14:44:14 -0400
committerDavid Chase <drchase@google.com>2020-09-17 19:16:49 +0000
commitf554eb7bc332cc265e6cc0490a7595b2f5873cba (patch)
treee4b7edb54d481d3810aeb48c84fcf3ba55b3e2c4 /src/cmd/compile/internal/types/type.go
parent07d5eb075b6f270ae4443e9689821d2e403b72b5 (diff)
downloadgo-f554eb7bc332cc265e6cc0490a7595b2f5873cba.tar.gz
go-f554eb7bc332cc265e6cc0490a7595b2f5873cba.zip
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>
Diffstat (limited to 'src/cmd/compile/internal/types/type.go')
-rw-r--r--src/cmd/compile/internal/types/type.go66
1 files changed, 59 insertions, 7 deletions
diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go
index a777a5fd90..9b05aef429 100644
--- a/src/cmd/compile/internal/types/type.go
+++ b/src/cmd/compile/internal/types/type.go
@@ -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