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>
This commit is contained in:
Alan Donovan 2014-12-15 12:34:41 -05:00
parent 8bc439de18
commit 43a6897047
4 changed files with 40 additions and 5 deletions

View File

@ -241,6 +241,20 @@ func (b *builder) builtin(fn *Function, obj *types.Builtin, args []ast.Expr, typ
if len(args) == 3 { if len(args) == 3 {
m = b.expr(fn, args[2]) 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{ v := &MakeSlice{
Len: n, Len: n,
Cap: m, Cap: m,

View File

@ -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() { func init() {
var ptr *T var ptr *T
var i I = ptr var i I = ptr

View File

@ -90,9 +90,9 @@ func main() {
_ = v8ptr[0] // v8ptr::Alloc _ = v8ptr[0] // v8ptr::Alloc
_ = *v8ptr // v8ptr::Alloc _ = *v8ptr // v8ptr::Alloc
v8a := make([]int, 1) // v8a::MakeSlice v8a := make([]int, 1) // v8a::Slice
v8a[0] = 0 // v8a::MakeSlice v8a[0] = 0 // v8a::Slice
print(v8a[:]) // v8a::MakeSlice print(v8a[:]) // v8a::Slice
v9 := S{} // &v9::Alloc v9 := S{} // &v9::Alloc

View File

@ -33,7 +33,7 @@ func f(spilled, unspilled int) {
_ = /*@Phi*/ (y) _ = /*@Phi*/ (y)
map1 := /*@MakeMap*/ (make(map[string]string)) map1 := /*@MakeMap*/ (make(map[string]string))
_ = map1 _ = map1
_ = /*@MakeSlice*/ (make([]int, 0)) _ = /*@Slice*/ (make([]int, 0))
_ = /*@MakeClosure*/ (func() { print(spilled) }) _ = /*@MakeClosure*/ (func() { print(spilled) })
sl := []int{} sl := []int{}