diff options
author | Alan Donovan <adonovan@google.com> | 2014-12-15 12:34:41 -0500 |
---|---|---|
committer | Alan Donovan <adonovan@google.com> | 2014-12-29 21:06:17 +0000 |
commit | 43a68970476908d921f2a423dca94402212a6f0c (patch) | |
tree | df626a0b50a90c3abb69dddae035686702a6bbf7 /go | |
parent | 8bc439de181cfdcb69c8ec9476254085349f28bc (diff) | |
download | tools-43a68970476908d921f2a423dca94402212a6f0c.tar.gz |
go/ssa: simplify make([]T, len, k) to new([k]T)[:len] for constant k
+ test.
Change-Id: I0255e38a0f95af95a32dc1d9cf18b26db85af36f
Reviewed-on: https://go-review.googlesource.com/1519
Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'go')
-rw-r--r-- | go/ssa/builder.go | 14 | ||||
-rw-r--r-- | go/ssa/interp/testdata/coverage.go | 23 | ||||
-rw-r--r-- | go/ssa/testdata/objlookup.go | 6 | ||||
-rw-r--r-- | go/ssa/testdata/valueforexpr.go | 2 |
4 files changed, 40 insertions, 5 deletions
diff --git a/go/ssa/builder.go b/go/ssa/builder.go index 6e1739c..1460d48 100644 --- a/go/ssa/builder.go +++ b/go/ssa/builder.go @@ -241,6 +241,20 @@ func (b *builder) builtin(fn *Function, obj *types.Builtin, args []ast.Expr, typ if len(args) == 3 { m = b.expr(fn, args[2]) } + if m, ok := m.(*Const); ok { + // treat make([]T, n, m) as new([m]T)[:n] + cap, _ := exact.Int64Val(m.Value) + at := types.NewArray(typ.Underlying().(*types.Slice).Elem(), cap) + alloc := emitNew(fn, at, pos) + alloc.Comment = "makeslice" + v := &Slice{ + X: alloc, + High: n, + } + v.setPos(pos) + v.setType(typ) + return fn.emit(v) + } v := &MakeSlice{ Len: n, Cap: m, diff --git a/go/ssa/interp/testdata/coverage.go b/go/ssa/interp/testdata/coverage.go index ca65643..dc094da 100644 --- a/go/ssa/interp/testdata/coverage.go +++ b/go/ssa/interp/testdata/coverage.go @@ -478,7 +478,28 @@ func init() { } } -// Test that a nice error is issue by indirection wrappers. +var one = 1 // not a constant + +// Test makeslice. +func init() { + check := func(s []string, wantLen, wantCap int) { + if len(s) != wantLen { + panic(len(s)) + } + if cap(s) != wantCap { + panic(cap(s)) + } + } + // SSA form: + check(make([]string, 10), 10, 10) // new([10]string)[:10] + check(make([]string, one), 1, 1) // make([]string, one, one) + check(make([]string, 0, 10), 0, 10) // new([10]string)[:0] + check(make([]string, 0, one), 0, 1) // make([]string, 0, one) + check(make([]string, one, 10), 1, 10) // new([10]string)[:one] + check(make([]string, one, one), 1, 1) // make([]string, one, one) +} + +// Test that a nice error is issued by indirection wrappers. func init() { var ptr *T var i I = ptr diff --git a/go/ssa/testdata/objlookup.go b/go/ssa/testdata/objlookup.go index bd266e4..1aaa417 100644 --- a/go/ssa/testdata/objlookup.go +++ b/go/ssa/testdata/objlookup.go @@ -90,9 +90,9 @@ func main() { _ = v8ptr[0] // v8ptr::Alloc _ = *v8ptr // v8ptr::Alloc - v8a := make([]int, 1) // v8a::MakeSlice - v8a[0] = 0 // v8a::MakeSlice - print(v8a[:]) // v8a::MakeSlice + v8a := make([]int, 1) // v8a::Slice + v8a[0] = 0 // v8a::Slice + print(v8a[:]) // v8a::Slice v9 := S{} // &v9::Alloc diff --git a/go/ssa/testdata/valueforexpr.go b/go/ssa/testdata/valueforexpr.go index 70906ca..0697ec6 100644 --- a/go/ssa/testdata/valueforexpr.go +++ b/go/ssa/testdata/valueforexpr.go @@ -33,7 +33,7 @@ func f(spilled, unspilled int) { _ = /*@Phi*/ (y) map1 := /*@MakeMap*/ (make(map[string]string)) _ = map1 - _ = /*@MakeSlice*/ (make([]int, 0)) + _ = /*@Slice*/ (make([]int, 0)) _ = /*@MakeClosure*/ (func() { print(spilled) }) sl := []int{} |