cmd/compile: use int for field index
All of a struct's fields have to fit into memory anyway, so index them
with int instead of int64. This also makes it nicer for
cmd/compile/internal/gc to reuse the same NumFields function.
Change-Id: I210be804a0c33370ec9977414918c02c675b0fbe
Reviewed-on: https://go-review.googlesource.com/20691
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index 805420b..56f2474 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -1865,7 +1865,7 @@
t := n.Left.Type
if canSSAType(t) {
v := s.expr(n.Left)
- return s.newValue1I(ssa.OpStructSelect, n.Type, fieldIdx(n), v)
+ return s.newValue1I(ssa.OpStructSelect, n.Type, int64(fieldIdx(n)), v)
}
p := s.addr(n, false)
return s.newValue2(ssa.OpLoad, n.Type, p, s.mem())
@@ -1956,7 +1956,7 @@
// eface type could also be struct{p *byte; q [0]int}
continue
}
- data = s.newValue1I(ssa.OpStructSelect, f, i, data)
+ data = s.newValue1I(ssa.OpStructSelect, f, int64(i), data)
break
}
default:
@@ -2186,11 +2186,11 @@
new := s.newValue0(ssa.StructMakeOp(t.NumFields()), t)
// Add fields as args.
- for i := int64(0); i < nf; i++ {
+ for i := 0; i < nf; i++ {
if i == idx {
new.AddArg(right)
} else {
- new.AddArg(s.newValue1I(ssa.OpStructSelect, t.FieldType(i), i, old))
+ new.AddArg(s.newValue1I(ssa.OpStructSelect, t.FieldType(i), int64(i), old))
}
}
@@ -2280,7 +2280,7 @@
case t.IsStruct():
n := t.NumFields()
v := s.entryNewValue0(ssa.StructMakeOp(t.NumFields()), t)
- for i := int64(0); i < n; i++ {
+ for i := 0; i < n; i++ {
v.AddArg(s.zeroVal(t.FieldType(i).(*Type)))
}
return v
@@ -2883,10 +2883,10 @@
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, left, itab, s.mem())
case t.IsStruct():
n := t.NumFields()
- for i := int64(0); i < n; i++ {
+ for i := 0; i < n; i++ {
ft := t.FieldType(i)
addr := s.newValue1I(ssa.OpOffPtr, ft.PtrTo(), t.FieldOff(i), left)
- val := s.newValue1I(ssa.OpStructSelect, ft, i, right)
+ val := s.newValue1I(ssa.OpStructSelect, ft, int64(i), right)
s.storeTypeScalars(ft.(*Type), addr, val)
}
default:
@@ -2912,13 +2912,13 @@
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, idataAddr, idata, s.mem())
case t.IsStruct():
n := t.NumFields()
- for i := int64(0); i < n; i++ {
+ for i := 0; i < n; i++ {
ft := t.FieldType(i)
if !haspointers(ft.(*Type)) {
continue
}
addr := s.newValue1I(ssa.OpOffPtr, ft.PtrTo(), t.FieldOff(i), left)
- val := s.newValue1I(ssa.OpStructSelect, ft, i, right)
+ val := s.newValue1I(ssa.OpStructSelect, ft, int64(i), right)
s.storeTypePtrs(ft.(*Type), addr, val)
}
default:
@@ -2943,13 +2943,13 @@
s.rtcall(writebarrierptr, true, nil, idataAddr, idata)
case t.IsStruct():
n := t.NumFields()
- for i := int64(0); i < n; i++ {
+ for i := 0; i < n; i++ {
ft := t.FieldType(i)
if !haspointers(ft.(*Type)) {
continue
}
addr := s.newValue1I(ssa.OpOffPtr, ft.PtrTo(), t.FieldOff(i), left)
- val := s.newValue1I(ssa.OpStructSelect, ft, i, right)
+ val := s.newValue1I(ssa.OpStructSelect, ft, int64(i), right)
s.storeTypePtrsWB(ft.(*Type), addr, val)
}
default:
@@ -3935,14 +3935,14 @@
}
// fieldIdx finds the index of the field referred to by the ODOT node n.
-func fieldIdx(n *Node) int64 {
+func fieldIdx(n *Node) int {
t := n.Left.Type
f := n.Right
if t.Etype != TSTRUCT {
panic("ODOT's LHS is not a struct")
}
- var i int64
+ var i int
for t1, it := IterFields(t); t1 != nil; t1 = it.Next() {
if t1.Sym != f.Sym {
i++
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
index 004b9b1..df9702a 100644
--- a/src/cmd/compile/internal/gc/subr.go
+++ b/src/cmd/compile/internal/gc/subr.go
@@ -2199,15 +2199,6 @@
return n
}
-// return nelem of list
-func structcount(t *Type) int {
- v := 0
- for t, it := IterFields(t); t != nil; t = it.Next() {
- v++
- }
- return v
-}
-
// return power of 2 of the constant
// operand. -1 if it is not a power of 2.
// 1000+ if it is a -(power of 2)
diff --git a/src/cmd/compile/internal/gc/type.go b/src/cmd/compile/internal/gc/type.go
index 797174f..2f05f4e 100644
--- a/src/cmd/compile/internal/gc/type.go
+++ b/src/cmd/compile/internal/gc/type.go
@@ -643,14 +643,18 @@
return Ptrto(t)
}
-func (t *Type) NumFields() int64 {
- return int64(countfield(t))
+func (t *Type) NumFields() int {
+ n := 0
+ for f, it := IterFields(t); f != nil; f = it.Next() {
+ n++
+ }
+ return n
}
-func (t *Type) FieldType(i int64) ssa.Type {
- return t.Field(int(i)).Type
+func (t *Type) FieldType(i int) ssa.Type {
+ return t.Field(i).Type
}
-func (t *Type) FieldOff(i int64) int64 {
- return t.Field(int(i)).Width
+func (t *Type) FieldOff(i int) int64 {
+ return t.Field(i).Width
}
func (t *Type) NumElem() int64 {
@@ -663,3 +667,8 @@
func (t *Type) IsMemory() bool { return false }
func (t *Type) IsFlags() bool { return false }
func (t *Type) IsVoid() bool { return false }
+
+// TODO(mdempsky): Replace all of these with direct calls to t.NumFields().
+func countfield(t *Type) int { return t.NumFields() }
+func downcount(t *Type) int { return t.NumFields() }
+func structcount(t *Type) int { return t.NumFields() }
diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
index 7df04c8..cf3cadb 100644
--- a/src/cmd/compile/internal/gc/typecheck.go
+++ b/src/cmd/compile/internal/gc/typecheck.go
@@ -2577,17 +2577,6 @@
return false
}
-// downcount is the same as countfield
-// TODO decide if we want both (for semantic reasons)
-func downcount(t *Type) int {
- n := 0
- for tl, it := IterFields(t); tl != nil; tl = it.Next() {
- n++
- }
-
- return n
-}
-
// typecheck assignment: type list = expression list
func typecheckaste(op Op, call *Node, isddd bool, tstruct *Type, nl Nodes, desc func() string) {
var t *Type
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index aff6a77..b9f2b52 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -3072,14 +3072,6 @@
return n
}
-func countfield(t *Type) int {
- n := 0
- for t1, it := IterFields(t); t1 != nil; t1 = it.Next() {
- n++
- }
- return n
-}
-
func walkcompare(np **Node, init *Nodes) {
n := *np
diff --git a/src/cmd/compile/internal/ssa/decompose.go b/src/cmd/compile/internal/ssa/decompose.go
index 826eff1..ba84087 100644
--- a/src/cmd/compile/internal/ssa/decompose.go
+++ b/src/cmd/compile/internal/ssa/decompose.go
@@ -192,9 +192,9 @@
case t.IsStruct():
n := t.NumFields()
for _, v := range f.NamedValues[name] {
- for i := int64(0); i < n; i++ {
+ for i := 0; i < n; i++ {
fname := LocalSlot{name.N, t.FieldType(i), name.Off + t.FieldOff(i)} // TODO: use actual field name?
- x := v.Block.NewValue1I(v.Line, OpStructSelect, t.FieldType(i), i, v)
+ x := v.Block.NewValue1I(v.Line, OpStructSelect, t.FieldType(i), int64(i), v)
f.NamedValues[fname] = append(f.NamedValues[fname], x)
}
}
@@ -219,12 +219,12 @@
t := v.Type
n := t.NumFields()
var fields [MaxStruct]*Value
- for i := int64(0); i < n; i++ {
+ for i := 0; i < n; i++ {
fields[i] = v.Block.NewValue0(v.Line, OpPhi, t.FieldType(i))
}
for _, a := range v.Args {
- for i := int64(0); i < n; i++ {
- fields[i].AddArg(a.Block.NewValue1I(v.Line, OpStructSelect, t.FieldType(i), i, a))
+ for i := 0; i < n; i++ {
+ fields[i].AddArg(a.Block.NewValue1I(v.Line, OpStructSelect, t.FieldType(i), int64(i), a))
}
}
v.reset(StructMakeOp(n))
@@ -244,7 +244,7 @@
// StructMakeOp returns the opcode to construct a struct with the
// given number of fields.
-func StructMakeOp(nf int64) Op {
+func StructMakeOp(nf int) Op {
switch nf {
case 0:
return OpStructMake0
diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules
index 2186d89..47aa6de 100644
--- a/src/cmd/compile/internal/ssa/gen/generic.rules
+++ b/src/cmd/compile/internal/ssa/gen/generic.rules
@@ -473,7 +473,7 @@
(Load <t.FieldType(3)> (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] ptr) mem))
(StructSelect [i] (Load <t> ptr mem)) && !config.fe.CanSSA(t) ->
- @v.Args[0].Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.FieldOff(i)] ptr) mem)
+ @v.Args[0].Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.FieldOff(int(i))] ptr) mem)
(Store _ (StructMake0) mem) -> mem
(Store dst (StructMake1 <t> f0) mem) ->
diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go
index 116d11e..815468d 100644
--- a/src/cmd/compile/internal/ssa/rewritegeneric.go
+++ b/src/cmd/compile/internal/ssa/rewritegeneric.go
@@ -7517,7 +7517,7 @@
}
// match: (StructSelect [i] (Load <t> ptr mem))
// cond: !config.fe.CanSSA(t)
- // result: @v.Args[0].Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.FieldOff(i)] ptr) mem)
+ // result: @v.Args[0].Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.FieldOff(int(i))] ptr) mem)
for {
i := v.AuxInt
if v.Args[0].Op != OpLoad {
@@ -7536,7 +7536,7 @@
v1 := b.NewValue0(v.Line, OpOffPtr, v.Type.PtrTo())
v.reset(OpCopy)
v.AddArg(v1)
- v1.AuxInt = t.FieldOff(i)
+ v1.AuxInt = t.FieldOff(int(i))
v1.AddArg(ptr)
v0.AddArg(v1)
v0.AddArg(mem)
diff --git a/src/cmd/compile/internal/ssa/type.go b/src/cmd/compile/internal/ssa/type.go
index 427fb01..8851e35 100644
--- a/src/cmd/compile/internal/ssa/type.go
+++ b/src/cmd/compile/internal/ssa/type.go
@@ -31,9 +31,9 @@
ElemType() Type // given []T or *T or [n]T, return T
PtrTo() Type // given T, return *T
- NumFields() int64 // # of fields of a struct
- FieldType(i int64) Type // type of ith field of the struct
- FieldOff(i int64) int64 // offset of ith field of the struct
+ NumFields() int // # of fields of a struct
+ FieldType(i int) Type // type of ith field of the struct
+ FieldOff(i int) int64 // offset of ith field of the struct
NumElem() int64 // # of elements of an array
@@ -53,30 +53,30 @@
Int128 bool
}
-func (t *CompilerType) Size() int64 { return t.size } // Size in bytes
-func (t *CompilerType) Alignment() int64 { return 0 }
-func (t *CompilerType) IsBoolean() bool { return false }
-func (t *CompilerType) IsInteger() bool { return false }
-func (t *CompilerType) IsSigned() bool { return false }
-func (t *CompilerType) IsFloat() bool { return false }
-func (t *CompilerType) IsComplex() bool { return false }
-func (t *CompilerType) IsPtr() bool { return false }
-func (t *CompilerType) IsString() bool { return false }
-func (t *CompilerType) IsSlice() bool { return false }
-func (t *CompilerType) IsArray() bool { return false }
-func (t *CompilerType) IsStruct() bool { return false }
-func (t *CompilerType) IsInterface() bool { return false }
-func (t *CompilerType) IsMemory() bool { return t.Memory }
-func (t *CompilerType) IsFlags() bool { return t.Flags }
-func (t *CompilerType) IsVoid() bool { return t.Void }
-func (t *CompilerType) String() string { return t.Name }
-func (t *CompilerType) SimpleString() string { return t.Name }
-func (t *CompilerType) ElemType() Type { panic("not implemented") }
-func (t *CompilerType) PtrTo() Type { panic("not implemented") }
-func (t *CompilerType) NumFields() int64 { panic("not implemented") }
-func (t *CompilerType) FieldType(i int64) Type { panic("not implemented") }
-func (t *CompilerType) FieldOff(i int64) int64 { panic("not implemented") }
-func (t *CompilerType) NumElem() int64 { panic("not implemented") }
+func (t *CompilerType) Size() int64 { return t.size } // Size in bytes
+func (t *CompilerType) Alignment() int64 { return 0 }
+func (t *CompilerType) IsBoolean() bool { return false }
+func (t *CompilerType) IsInteger() bool { return false }
+func (t *CompilerType) IsSigned() bool { return false }
+func (t *CompilerType) IsFloat() bool { return false }
+func (t *CompilerType) IsComplex() bool { return false }
+func (t *CompilerType) IsPtr() bool { return false }
+func (t *CompilerType) IsString() bool { return false }
+func (t *CompilerType) IsSlice() bool { return false }
+func (t *CompilerType) IsArray() bool { return false }
+func (t *CompilerType) IsStruct() bool { return false }
+func (t *CompilerType) IsInterface() bool { return false }
+func (t *CompilerType) IsMemory() bool { return t.Memory }
+func (t *CompilerType) IsFlags() bool { return t.Flags }
+func (t *CompilerType) IsVoid() bool { return t.Void }
+func (t *CompilerType) String() string { return t.Name }
+func (t *CompilerType) SimpleString() string { return t.Name }
+func (t *CompilerType) ElemType() Type { panic("not implemented") }
+func (t *CompilerType) PtrTo() Type { panic("not implemented") }
+func (t *CompilerType) NumFields() int { panic("not implemented") }
+func (t *CompilerType) FieldType(i int) Type { panic("not implemented") }
+func (t *CompilerType) FieldOff(i int) int64 { panic("not implemented") }
+func (t *CompilerType) NumElem() int64 { panic("not implemented") }
// Cmp is a comparison between values a and b.
// -1 if a < b
diff --git a/src/cmd/compile/internal/ssa/type_test.go b/src/cmd/compile/internal/ssa/type_test.go
index 048eda5..bc55f8e 100644
--- a/src/cmd/compile/internal/ssa/type_test.go
+++ b/src/cmd/compile/internal/ssa/type_test.go
@@ -24,30 +24,30 @@
Name string
}
-func (t *TypeImpl) Size() int64 { return t.Size_ }
-func (t *TypeImpl) Alignment() int64 { return t.Align }
-func (t *TypeImpl) IsBoolean() bool { return t.Boolean }
-func (t *TypeImpl) IsInteger() bool { return t.Integer }
-func (t *TypeImpl) IsSigned() bool { return t.Signed }
-func (t *TypeImpl) IsFloat() bool { return t.Float }
-func (t *TypeImpl) IsComplex() bool { return t.Complex }
-func (t *TypeImpl) IsPtr() bool { return t.Ptr }
-func (t *TypeImpl) IsString() bool { return t.string }
-func (t *TypeImpl) IsSlice() bool { return t.slice }
-func (t *TypeImpl) IsArray() bool { return t.array }
-func (t *TypeImpl) IsStruct() bool { return t.struct_ }
-func (t *TypeImpl) IsInterface() bool { return t.inter }
-func (t *TypeImpl) IsMemory() bool { return false }
-func (t *TypeImpl) IsFlags() bool { return false }
-func (t *TypeImpl) IsVoid() bool { return false }
-func (t *TypeImpl) String() string { return t.Name }
-func (t *TypeImpl) SimpleString() string { return t.Name }
-func (t *TypeImpl) ElemType() Type { return t.Elem_ }
-func (t *TypeImpl) PtrTo() Type { panic("not implemented") }
-func (t *TypeImpl) NumFields() int64 { panic("not implemented") }
-func (t *TypeImpl) FieldType(i int64) Type { panic("not implemented") }
-func (t *TypeImpl) FieldOff(i int64) int64 { panic("not implemented") }
-func (t *TypeImpl) NumElem() int64 { panic("not implemented") }
+func (t *TypeImpl) Size() int64 { return t.Size_ }
+func (t *TypeImpl) Alignment() int64 { return t.Align }
+func (t *TypeImpl) IsBoolean() bool { return t.Boolean }
+func (t *TypeImpl) IsInteger() bool { return t.Integer }
+func (t *TypeImpl) IsSigned() bool { return t.Signed }
+func (t *TypeImpl) IsFloat() bool { return t.Float }
+func (t *TypeImpl) IsComplex() bool { return t.Complex }
+func (t *TypeImpl) IsPtr() bool { return t.Ptr }
+func (t *TypeImpl) IsString() bool { return t.string }
+func (t *TypeImpl) IsSlice() bool { return t.slice }
+func (t *TypeImpl) IsArray() bool { return t.array }
+func (t *TypeImpl) IsStruct() bool { return t.struct_ }
+func (t *TypeImpl) IsInterface() bool { return t.inter }
+func (t *TypeImpl) IsMemory() bool { return false }
+func (t *TypeImpl) IsFlags() bool { return false }
+func (t *TypeImpl) IsVoid() bool { return false }
+func (t *TypeImpl) String() string { return t.Name }
+func (t *TypeImpl) SimpleString() string { return t.Name }
+func (t *TypeImpl) ElemType() Type { return t.Elem_ }
+func (t *TypeImpl) PtrTo() Type { panic("not implemented") }
+func (t *TypeImpl) NumFields() int { panic("not implemented") }
+func (t *TypeImpl) FieldType(i int) Type { panic("not implemented") }
+func (t *TypeImpl) FieldOff(i int) int64 { panic("not implemented") }
+func (t *TypeImpl) NumElem() int64 { panic("not implemented") }
func (t *TypeImpl) Equal(u Type) bool {
x, ok := u.(*TypeImpl)