mirror of https://github.com/golang/go.git
cmd/compile: optimize unsafe.Slice generated code
We don't need a multiply when the element type is size 0 or 1. The panic functions don't return, so we don't need any post-call code (register restores, etc.). Change-Id: I0dcea5df56d29d7be26554ddca966b3903c672e5 Reviewed-on: https://go-review.googlesource.com/c/go/+/419754 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
ebf182c82d
commit
c2a9c55823
|
|
@ -165,6 +165,8 @@
|
|||
|
||||
// Convert x * 1 to x.
|
||||
(Mul(8|16|32|64) (Const(8|16|32|64) [1]) x) => x
|
||||
(Select0 (Mul(32|64)uover (Const(32|64) [1]) x)) => x
|
||||
(Select1 (Mul(32|64)uover (Const(32|64) [1]) x)) => (ConstBool [false])
|
||||
|
||||
// Convert x * -1 to -x.
|
||||
(Mul(8|16|32|64) (Const(8|16|32|64) [-1]) x) => (Neg(8|16|32|64) x)
|
||||
|
|
@ -531,6 +533,8 @@
|
|||
(Add(64|32|16|8) (Const(64|32|16|8) [0]) x) => x
|
||||
(Sub(64|32|16|8) x x) => (Const(64|32|16|8) [0])
|
||||
(Mul(64|32|16|8) (Const(64|32|16|8) [0]) _) => (Const(64|32|16|8) [0])
|
||||
(Select0 (Mul(64|32)uover (Const(64|32) [0]) x)) => (Const(64|32) [0])
|
||||
(Select1 (Mul(64|32)uover (Const(64|32) [0]) x)) => (ConstBool [false])
|
||||
|
||||
(Com(64|32|16|8) (Com(64|32|16|8) x)) => x
|
||||
(Com(64|32|16|8) (Const(64|32|16|8) [c])) => (Const(64|32|16|8) [^c])
|
||||
|
|
|
|||
|
|
@ -21260,6 +21260,82 @@ func rewriteValuegeneric_OpSelect0(v *Value) bool {
|
|||
v.AddArg2(lo, y)
|
||||
return true
|
||||
}
|
||||
// match: (Select0 (Mul32uover (Const32 [1]) x))
|
||||
// result: x
|
||||
for {
|
||||
if v_0.Op != OpMul32uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 1 {
|
||||
continue
|
||||
}
|
||||
x := v_0_1
|
||||
v.copyOf(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select0 (Mul64uover (Const64 [1]) x))
|
||||
// result: x
|
||||
for {
|
||||
if v_0.Op != OpMul64uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 1 {
|
||||
continue
|
||||
}
|
||||
x := v_0_1
|
||||
v.copyOf(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select0 (Mul64uover (Const64 [0]) x))
|
||||
// result: (Const64 [0])
|
||||
for {
|
||||
if v_0.Op != OpMul64uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpConst64)
|
||||
v.AuxInt = int64ToAuxInt(0)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select0 (Mul32uover (Const32 [0]) x))
|
||||
// result: (Const32 [0])
|
||||
for {
|
||||
if v_0.Op != OpMul32uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 0 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpConst32)
|
||||
v.AuxInt = int32ToAuxInt(0)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpSelect1(v *Value) bool {
|
||||
|
|
@ -21280,6 +21356,82 @@ func rewriteValuegeneric_OpSelect1(v *Value) bool {
|
|||
v.AddArg2(lo, y)
|
||||
return true
|
||||
}
|
||||
// match: (Select1 (Mul32uover (Const32 [1]) x))
|
||||
// result: (ConstBool [false])
|
||||
for {
|
||||
if v_0.Op != OpMul32uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 1 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = boolToAuxInt(false)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select1 (Mul64uover (Const64 [1]) x))
|
||||
// result: (ConstBool [false])
|
||||
for {
|
||||
if v_0.Op != OpMul64uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 1 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = boolToAuxInt(false)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select1 (Mul64uover (Const64 [0]) x))
|
||||
// result: (ConstBool [false])
|
||||
for {
|
||||
if v_0.Op != OpMul64uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = boolToAuxInt(false)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select1 (Mul32uover (Const32 [0]) x))
|
||||
// result: (ConstBool [false])
|
||||
for {
|
||||
if v_0.Op != OpMul32uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 0 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = boolToAuxInt(false)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpSelectN(v *Value) bool {
|
||||
|
|
|
|||
|
|
@ -1421,7 +1421,7 @@ func (s *state) stmt(n ir.Node) {
|
|||
s.callResult(n, callNormal)
|
||||
if n.Op() == ir.OCALLFUNC && n.X.Op() == ir.ONAME && n.X.(*ir.Name).Class == ir.PFUNC {
|
||||
if fn := n.X.Sym().Name; base.Flag.CompilingRuntime && fn == "throw" ||
|
||||
n.X.Sym().Pkg == ir.Pkgs.Runtime && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap") {
|
||||
n.X.Sym().Pkg == ir.Pkgs.Runtime && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap" || fn == "panicunsafeslicelen" || fn == "panicunsafeslicenilptr") {
|
||||
m := s.mem()
|
||||
b := s.endBlock()
|
||||
b.Kind = ssa.BlockExit
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
package codegen
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// This file contains code generation tests related to the handling of
|
||||
// slice types.
|
||||
|
||||
|
|
@ -368,3 +370,16 @@ func SliceWithSubtractBound(a []int, b int) []int {
|
|||
// ppc64:"SUBC",-"NEG"
|
||||
return a[(3 - b):]
|
||||
}
|
||||
|
||||
// --------------------------------------- //
|
||||
// Code generation for unsafe.Slice //
|
||||
// --------------------------------------- //
|
||||
|
||||
func Slice1(p *byte, i int) []byte {
|
||||
// amd64:-"MULQ"
|
||||
return unsafe.Slice(p, i)
|
||||
}
|
||||
func Slice0(p *struct{}, i int) []struct{} {
|
||||
// amd64:-"MULQ"
|
||||
return unsafe.Slice(p, i)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue