Skip to content

Commit

Permalink
cmd/compile: split TSLICE into separate Type kind
Browse files Browse the repository at this point in the history
Instead of using TARRAY for both arrays and slices, create a new
TSLICE kind to handle slices.

Also, get rid of the "DDDArray" distinction. While kinda ugly, it
seems likely we'll need to defer evaluating the constant bounds
expressions for golang.org/issue/13890.

Passes toolstash/buildall.

Change-Id: I8e45d4900e7df3a04cce59428ec8b38035d3cc3a
Reviewed-on: https://go-review.googlesource.com/22329
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
  • Loading branch information
mdempsky committed Apr 21, 2016
1 parent 5213cd7 commit 40f1d0c
Show file tree
Hide file tree
Showing 21 changed files with 168 additions and 251 deletions.
15 changes: 3 additions & 12 deletions src/cmd/compile/internal/gc/alg.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,10 @@ func algtype1(t *Type) (AlgKind, *Type) {
}
return AINTER, nil

case TARRAY:
if t.IsSlice() {
return ANOEQ, t
}
case TSLICE:
return ANOEQ, t

case TARRAY:
a, bad := algtype1(t.Elem())
switch a {
case AMEM:
Expand Down Expand Up @@ -219,10 +218,6 @@ func genhash(sym *Sym, t *Type) {
Fatalf("genhash %v", t)

case TARRAY:
if t.IsSlice() {
Fatalf("genhash %v", t)
}

// An array of pure memory would be handled by the
// standard algorithm, so the element type must not be
// pure memory.
Expand Down Expand Up @@ -399,10 +394,6 @@ func geneq(sym *Sym, t *Type) {
Fatalf("geneq %v", t)

case TARRAY:
if t.IsSlice() {
Fatalf("geneq %v", t)
}

// An array of pure memory would be handled by the
// standard memequal, so the element type must not be
// pure memory. Even if we unrolled the range loop,
Expand Down
38 changes: 20 additions & 18 deletions src/cmd/compile/internal/gc/align.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,29 +238,31 @@ func dowidth(t *Type) {
if t.Elem() == nil {
break
}
if t.IsArray() {
dowidth(t.Elem())
if t.Elem().Width != 0 {
cap := (uint64(Thearch.MAXWIDTH) - 1) / uint64(t.Elem().Width)
if uint64(t.NumElem()) > cap {
Yyerror("type %v larger than address space", Tconv(t, FmtLong))
}
}

w = t.NumElem() * t.Elem().Width
t.Align = t.Elem().Align
} else if t.IsSlice() {
w = int64(sizeof_Array)
checkwidth(t.Elem())
t.Align = uint8(Widthptr)
} else if t.isDDDArray() {
if t.isDDDArray() {
if !t.Broke {
Yyerror("use of [...] array outside of array literal")
t.Broke = true
}
} else {
Fatalf("dowidth %v", t) // probably [...]T
break
}

dowidth(t.Elem())
if t.Elem().Width != 0 {
cap := (uint64(Thearch.MAXWIDTH) - 1) / uint64(t.Elem().Width)
if uint64(t.NumElem()) > cap {
Yyerror("type %v larger than address space", Tconv(t, FmtLong))
}
}
w = t.NumElem() * t.Elem().Width
t.Align = t.Elem().Align

case TSLICE:
if t.Elem() == nil {
break
}
w = int64(sizeof_Array)
checkwidth(t.Elem())
t.Align = uint8(Widthptr)

case TSTRUCT:
if t.IsFuncArgStruct() {
Expand Down
12 changes: 6 additions & 6 deletions src/cmd/compile/internal/gc/bexport.go
Original file line number Diff line number Diff line change
Expand Up @@ -629,12 +629,12 @@ func (p *exporter) typ(t *Type) {
if t.isDDDArray() {
Fatalf("array bounds should be known at export time: %v", t)
}
if t.IsArray() {
p.tag(arrayTag)
p.int64(t.NumElem())
} else {
p.tag(sliceTag)
}
p.tag(arrayTag)
p.int64(t.NumElem())
p.typ(t.Elem())

case TSLICE:
p.tag(sliceTag)
p.typ(t.Elem())

case TDDDFIELD:
Expand Down
18 changes: 8 additions & 10 deletions src/cmd/compile/internal/gc/bimport.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,18 +369,16 @@ func (p *importer) typ() *Type {

dclcontext = savedContext

case arrayTag, sliceTag:
case arrayTag:
t = p.newtyp(TARRAY)
var bound int64
if i == arrayTag {
bound = p.int64()
}
bound := p.int64()
elem := p.typ()
if i == arrayTag {
t.Extra = &ArrayType{Elem: elem, Bound: bound}
} else {
t.Extra = SliceType{Elem: elem}
}
t.Extra = &ArrayType{Elem: elem, Bound: bound}

case sliceTag:
t = p.newtyp(TSLICE)
elem := p.typ()
t.Extra = SliceType{Elem: elem}

case dddTag:
t = p.newtyp(TDDDFIELD)
Expand Down
5 changes: 2 additions & 3 deletions src/cmd/compile/internal/gc/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,16 +284,15 @@ func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node {
return n

case TARRAY:
if !t.IsSlice() {
goto bad
}
goto bad

case TPTR32,
TPTR64,
TINTER,
TMAP,
TCHAN,
TFUNC,
TSLICE,
TUNSAFEPTR:
break

Expand Down
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/gc/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func reexportdep(n *Node) {
t := n.Type

switch t.Etype {
case TARRAY, TCHAN, TPTR32, TPTR64:
case TARRAY, TCHAN, TPTR32, TPTR64, TSLICE:
if t.Sym == nil {
t = t.Elem()
}
Expand Down Expand Up @@ -303,7 +303,7 @@ func dumpexporttype(t *Type) {
case TMAP:
dumpexporttype(t.Val())
dumpexporttype(t.Key())
case TARRAY, TCHAN, TPTR32, TPTR64:
case TARRAY, TCHAN, TPTR32, TPTR64, TSLICE:
dumpexporttype(t.Elem())
}

Expand Down
7 changes: 4 additions & 3 deletions src/cmd/compile/internal/gc/fmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ var etnames = []string{
TPTR64: "PTR64",
TFUNC: "FUNC",
TARRAY: "ARRAY",
TSLICE: "SLICE",
TSTRUCT: "STRUCT",
TCHAN: "CHAN",
TMAP: "MAP",
Expand Down Expand Up @@ -587,12 +588,12 @@ func typefmt(t *Type, flag FmtFlag) string {
return "*" + t.Elem().String()

case TARRAY:
if t.IsArray() {
return fmt.Sprintf("[%d]%v", t.NumElem(), t.Elem())
}
if t.isDDDArray() {
return "[...]" + t.Elem().String()
}
return fmt.Sprintf("[%d]%v", t.NumElem(), t.Elem())

case TSLICE:
return "[]" + t.Elem().String()

case TCHAN:
Expand Down
13 changes: 6 additions & 7 deletions src/cmd/compile/internal/gc/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -1031,7 +1031,7 @@ func componentgen_wb(nr, nl *Node, wb bool) bool {
// Emit vardef if needed.
if nl.Op == ONAME {
switch nl.Type.Etype {
case TARRAY, TSTRING, TINTER, TSTRUCT:
case TARRAY, TSLICE, TSTRING, TINTER, TSTRUCT:
Gvardef(nl)
}
}
Expand Down Expand Up @@ -1204,13 +1204,12 @@ func visitComponents(t *Type, startOffset int64, f func(elem *Type, elemOffset i
return f(Ptrto(Types[TUINT8]), startOffset) &&
f(Types[Simtype[TUINT]], startOffset+int64(Widthptr))

case TARRAY:
if t.IsSlice() {
return f(Ptrto(t.Elem()), startOffset+int64(Array_array)) &&
f(Types[Simtype[TUINT]], startOffset+int64(Array_nel)) &&
f(Types[Simtype[TUINT]], startOffset+int64(Array_cap))
}
case TSLICE:
return f(Ptrto(t.Elem()), startOffset+int64(Array_array)) &&
f(Types[Simtype[TUINT]], startOffset+int64(Array_nel)) &&
f(Types[Simtype[TUINT]], startOffset+int64(Array_cap))

case TARRAY:
// Short-circuit [1e6]struct{}.
if t.Elem().Width == 0 {
return true
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/gc/gsubr.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ func gused(n *Node) {
func Isfat(t *Type) bool {
if t != nil {
switch t.Etype {
case TSTRUCT, TARRAY, TSTRING,
case TSTRUCT, TARRAY, TSLICE, TSTRING,
TINTER: // maybe remove later
return true
}
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/gc/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ func orderstmt(n *Node, order *Order) {
default:
Fatalf("orderstmt range %v", n.Type)

case TARRAY:
case TARRAY, TSLICE:
if n.List.Len() < 2 || isblank(n.List.Second()) {
// for i := range x will only use x once, to compute len(x).
// No need to copy it.
Expand Down
21 changes: 10 additions & 11 deletions src/cmd/compile/internal/gc/plive.go
Original file line number Diff line number Diff line change
Expand Up @@ -918,18 +918,17 @@ func onebitwalktype1(t *Type, xoffset *int64, bv Bvec) {
bvset(bv, int32(*xoffset/int64(Widthptr)+1)) // pointer in second slot
*xoffset += t.Width

case TSLICE:
// struct { byte *array; uintgo len; uintgo cap; }
if *xoffset&int64(Widthptr-1) != 0 {
Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t)
}
bvset(bv, int32(*xoffset/int64(Widthptr))) // pointer in first slot (BitsPointer)
*xoffset += t.Width

case TARRAY:
if t.IsSlice() {
// struct { byte *array; uintgo len; uintgo cap; }
if *xoffset&int64(Widthptr-1) != 0 {
Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t)
}
bvset(bv, int32(*xoffset/int64(Widthptr))) // pointer in first slot (BitsPointer)
*xoffset += t.Width
} else {
for i := int64(0); i < t.NumElem(); i++ {
onebitwalktype1(t.Elem(), xoffset, bv)
}
for i := int64(0); i < t.NumElem(); i++ {
onebitwalktype1(t.Elem(), xoffset, bv)
}

case TSTRUCT:
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/gc/range.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func typecheckrange(n *Node) {
Yyerror("cannot range over %v", Nconv(n.Right, FmtLong))
goto out

case TARRAY:
case TARRAY, TSLICE:
t1 = Types[TINT]
t2 = t.Elem()

Expand Down Expand Up @@ -164,7 +164,7 @@ func walkrange(n *Node) {
default:
Fatalf("walkrange")

case TARRAY:
case TARRAY, TSLICE:
if memclrrange(n, v1, v2, a) {
lineno = lno
return
Expand Down
Loading

0 comments on commit 40f1d0c

Please sign in to comment.