mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
cmd/compile: use MakeResult in empty MakeSlice elimination
This gets eliminated by thoses rules above: // for rewriting results of some late-expanded rewrites (below) (SelectN [0] (MakeResult x ___)) => x (SelectN [1] (MakeResult x y ___)) => y (SelectN [2] (MakeResult x y z ___)) => z Fixes #58161 Change-Id: I4fbfd52c72c06b6b3db906bd9910b6dbb7fe8975 Reviewed-on: https://go-review.googlesource.com/c/go/+/463846 Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
9d81ccbf51
commit
0d8d181bd5
@ -2077,15 +2077,9 @@
|
||||
=> (Zero {types.Types[types.TUINT8]} [int64(c)] sptr mem)
|
||||
|
||||
// Recognise make([]T, 0) and replace it with a pointer to the zerobase
|
||||
(SelectN [0] call:(StaticLECall _ (Const(64|32) [0]) (Const(64|32) [0]) _))
|
||||
&& isSameCall(call.Aux, "runtime.makeslice")
|
||||
&& clobberIfDead(call)
|
||||
=> (Addr {ir.Syms.Zerobase} (SB))
|
||||
|
||||
(SelectN [1] call:(StaticLECall _ (Const(64|32) [0]) (Const(64|32) [0]) mem))
|
||||
&& isSameCall(call.Aux, "runtime.makeslice")
|
||||
&& clobberIfDead(call)
|
||||
=> mem
|
||||
(StaticLECall {callAux} _ (Const(64|32) [0]) (Const(64|32) [0]) mem)
|
||||
&& isSameCall(callAux, "runtime.makeslice")
|
||||
=> (MakeResult (Addr <v.Type.FieldType(0)> {ir.Syms.Zerobase} (SB)) mem)
|
||||
|
||||
// Evaluate constant address comparisons.
|
||||
(EqPtr x x) => (ConstBool [true])
|
||||
|
@ -26380,7 +26380,6 @@ func rewriteValuegeneric_OpSelectN(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (SelectN [0] (MakeResult x ___))
|
||||
// result: x
|
||||
for {
|
||||
@ -26467,104 +26466,6 @@ func rewriteValuegeneric_OpSelectN(v *Value) bool {
|
||||
v.AddArg2(sptr, mem)
|
||||
return true
|
||||
}
|
||||
// match: (SelectN [0] call:(StaticLECall _ (Const64 [0]) (Const64 [0]) _))
|
||||
// cond: isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)
|
||||
// result: (Addr {ir.Syms.Zerobase} (SB))
|
||||
for {
|
||||
if auxIntToInt64(v.AuxInt) != 0 {
|
||||
break
|
||||
}
|
||||
call := v_0
|
||||
if call.Op != OpStaticLECall || len(call.Args) != 4 {
|
||||
break
|
||||
}
|
||||
_ = call.Args[2]
|
||||
call_1 := call.Args[1]
|
||||
if call_1.Op != OpConst64 || auxIntToInt64(call_1.AuxInt) != 0 {
|
||||
break
|
||||
}
|
||||
call_2 := call.Args[2]
|
||||
if call_2.Op != OpConst64 || auxIntToInt64(call_2.AuxInt) != 0 || !(isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAddr)
|
||||
v.Aux = symToAux(ir.Syms.Zerobase)
|
||||
v0 := b.NewValue0(v.Pos, OpSB, typ.Uintptr)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (SelectN [0] call:(StaticLECall _ (Const32 [0]) (Const32 [0]) _))
|
||||
// cond: isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)
|
||||
// result: (Addr {ir.Syms.Zerobase} (SB))
|
||||
for {
|
||||
if auxIntToInt64(v.AuxInt) != 0 {
|
||||
break
|
||||
}
|
||||
call := v_0
|
||||
if call.Op != OpStaticLECall || len(call.Args) != 4 {
|
||||
break
|
||||
}
|
||||
_ = call.Args[2]
|
||||
call_1 := call.Args[1]
|
||||
if call_1.Op != OpConst32 || auxIntToInt32(call_1.AuxInt) != 0 {
|
||||
break
|
||||
}
|
||||
call_2 := call.Args[2]
|
||||
if call_2.Op != OpConst32 || auxIntToInt32(call_2.AuxInt) != 0 || !(isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAddr)
|
||||
v.Aux = symToAux(ir.Syms.Zerobase)
|
||||
v0 := b.NewValue0(v.Pos, OpSB, typ.Uintptr)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (SelectN [1] call:(StaticLECall _ (Const64 [0]) (Const64 [0]) mem))
|
||||
// cond: isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)
|
||||
// result: mem
|
||||
for {
|
||||
if auxIntToInt64(v.AuxInt) != 1 {
|
||||
break
|
||||
}
|
||||
call := v_0
|
||||
if call.Op != OpStaticLECall || len(call.Args) != 4 {
|
||||
break
|
||||
}
|
||||
mem := call.Args[3]
|
||||
call_1 := call.Args[1]
|
||||
if call_1.Op != OpConst64 || auxIntToInt64(call_1.AuxInt) != 0 {
|
||||
break
|
||||
}
|
||||
call_2 := call.Args[2]
|
||||
if call_2.Op != OpConst64 || auxIntToInt64(call_2.AuxInt) != 0 || !(isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)) {
|
||||
break
|
||||
}
|
||||
v.copyOf(mem)
|
||||
return true
|
||||
}
|
||||
// match: (SelectN [1] call:(StaticLECall _ (Const32 [0]) (Const32 [0]) mem))
|
||||
// cond: isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)
|
||||
// result: mem
|
||||
for {
|
||||
if auxIntToInt64(v.AuxInt) != 1 {
|
||||
break
|
||||
}
|
||||
call := v_0
|
||||
if call.Op != OpStaticLECall || len(call.Args) != 4 {
|
||||
break
|
||||
}
|
||||
mem := call.Args[3]
|
||||
call_1 := call.Args[1]
|
||||
if call_1.Op != OpConst32 || auxIntToInt32(call_1.AuxInt) != 0 {
|
||||
break
|
||||
}
|
||||
call_2 := call.Args[2]
|
||||
if call_2.Op != OpConst32 || auxIntToInt32(call_2.AuxInt) != 0 || !(isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)) {
|
||||
break
|
||||
}
|
||||
v.copyOf(mem)
|
||||
return true
|
||||
}
|
||||
// match: (SelectN [0] call:(StaticCall {sym} s1:(Store _ (Const64 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem)))))
|
||||
// cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)
|
||||
// result: (Move {types.Types[types.TUINT8]} [int64(sz)] dst src mem)
|
||||
@ -27463,6 +27364,56 @@ func rewriteValuegeneric_OpStaticLECall(v *Value) bool {
|
||||
v.AddArg2(v0, mem)
|
||||
return true
|
||||
}
|
||||
// match: (StaticLECall {callAux} _ (Const64 [0]) (Const64 [0]) mem)
|
||||
// cond: isSameCall(callAux, "runtime.makeslice")
|
||||
// result: (MakeResult (Addr <v.Type.FieldType(0)> {ir.Syms.Zerobase} (SB)) mem)
|
||||
for {
|
||||
if len(v.Args) != 4 {
|
||||
break
|
||||
}
|
||||
callAux := auxToCall(v.Aux)
|
||||
mem := v.Args[3]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != 0 {
|
||||
break
|
||||
}
|
||||
v_2 := v.Args[2]
|
||||
if v_2.Op != OpConst64 || auxIntToInt64(v_2.AuxInt) != 0 || !(isSameCall(callAux, "runtime.makeslice")) {
|
||||
break
|
||||
}
|
||||
v.reset(OpMakeResult)
|
||||
v0 := b.NewValue0(v.Pos, OpAddr, v.Type.FieldType(0))
|
||||
v0.Aux = symToAux(ir.Syms.Zerobase)
|
||||
v1 := b.NewValue0(v.Pos, OpSB, typ.Uintptr)
|
||||
v0.AddArg(v1)
|
||||
v.AddArg2(v0, mem)
|
||||
return true
|
||||
}
|
||||
// match: (StaticLECall {callAux} _ (Const32 [0]) (Const32 [0]) mem)
|
||||
// cond: isSameCall(callAux, "runtime.makeslice")
|
||||
// result: (MakeResult (Addr <v.Type.FieldType(0)> {ir.Syms.Zerobase} (SB)) mem)
|
||||
for {
|
||||
if len(v.Args) != 4 {
|
||||
break
|
||||
}
|
||||
callAux := auxToCall(v.Aux)
|
||||
mem := v.Args[3]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpConst32 || auxIntToInt32(v_1.AuxInt) != 0 {
|
||||
break
|
||||
}
|
||||
v_2 := v.Args[2]
|
||||
if v_2.Op != OpConst32 || auxIntToInt32(v_2.AuxInt) != 0 || !(isSameCall(callAux, "runtime.makeslice")) {
|
||||
break
|
||||
}
|
||||
v.reset(OpMakeResult)
|
||||
v0 := b.NewValue0(v.Pos, OpAddr, v.Type.FieldType(0))
|
||||
v0.Aux = symToAux(ir.Syms.Zerobase)
|
||||
v1 := b.NewValue0(v.Pos, OpSB, typ.Uintptr)
|
||||
v0.AddArg(v1)
|
||||
v.AddArg2(v0, mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpStore(v *Value) bool {
|
||||
|
15
test/fixedbugs/issue58161.go
Normal file
15
test/fixedbugs/issue58161.go
Normal file
@ -0,0 +1,15 @@
|
||||
// compile -d=ssa/check/seed=1
|
||||
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
func F[G int]() int {
|
||||
return len(make([]int, copy([]G{}, []G{})))
|
||||
}
|
||||
|
||||
func main() {
|
||||
F[int]()
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user