1
0
mirror of https://github.com/golang/go synced 2024-09-30 00:14:36 -06:00

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>
This commit is contained in:
David Chase 2020-07-13 14:44:14 -04:00
parent 07d5eb075b
commit f554eb7bc3
3 changed files with 74 additions and 10 deletions

View 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

View 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) {

View File

@ -68,6 +68,7 @@ const (
// SSA backend types
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) 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