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:
parent
8bc439de18
commit
43a6897047
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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{}
|
||||||
|
|
Loading…
Reference in New Issue