1
0
mirror of https://github.com/golang/go synced 2024-11-25 19:57:56 -07:00

cmd/compile: do constant folding for BitLen*

Change-Id: I56c27d606b55ea882f4db264fd4735b0cccdf7c6
Reviewed-on: https://go-review.googlesource.com/c/go/+/604015
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Jorropo 2024-08-07 21:40:43 +02:00 committed by Keith Randall
parent 0c7523ff59
commit 090f03fd2f
3 changed files with 162 additions and 0 deletions

View File

@ -58,6 +58,14 @@
(Round64F x:(Const64F)) => x
(CvtBoolToUint8 (ConstBool [false])) => (Const8 [0])
(CvtBoolToUint8 (ConstBool [true])) => (Const8 [1])
(BitLen64 (Const64 [c])) && config.PtrSize == 8 => (Const64 [int64(bits.Len64(uint64(c)))])
(BitLen32 (Const32 [c])) && config.PtrSize == 8 => (Const64 [int64(bits.Len32(uint32(c)))])
(BitLen16 (Const16 [c])) && config.PtrSize == 8 => (Const64 [int64(bits.Len16(uint16(c)))])
(BitLen8 (Const8 [c])) && config.PtrSize == 8 => (Const64 [int64(bits.Len8(uint8(c)))])
(BitLen64 (Const64 [c])) && config.PtrSize == 4 => (Const32 [int32(bits.Len64(uint64(c)))])
(BitLen32 (Const32 [c])) && config.PtrSize == 4 => (Const32 [int32(bits.Len32(uint32(c)))])
(BitLen16 (Const16 [c])) && config.PtrSize == 4 => (Const32 [int32(bits.Len16(uint16(c)))])
(BitLen8 (Const8 [c])) && config.PtrSize == 4 => (Const32 [int32(bits.Len8(uint8(c)))])
(Trunc16to8 (ZeroExt8to16 x)) => x
(Trunc32to8 (ZeroExt8to32 x)) => x

View File

@ -582,6 +582,7 @@ func fprint(w io.Writer, n Node) {
"fmt",
"internal/buildcfg",
"math",
"math/bits",
"cmd/internal/obj",
"cmd/compile/internal/base",
"cmd/compile/internal/types",

View File

@ -3,6 +3,7 @@
package ssa
import "math"
import "math/bits"
import "cmd/internal/obj"
import "cmd/compile/internal/types"
import "cmd/compile/internal/ir"
@ -35,6 +36,14 @@ func rewriteValuegeneric(v *Value) bool {
return rewriteValuegeneric_OpAndB(v)
case OpArraySelect:
return rewriteValuegeneric_OpArraySelect(v)
case OpBitLen16:
return rewriteValuegeneric_OpBitLen16(v)
case OpBitLen32:
return rewriteValuegeneric_OpBitLen32(v)
case OpBitLen64:
return rewriteValuegeneric_OpBitLen64(v)
case OpBitLen8:
return rewriteValuegeneric_OpBitLen8(v)
case OpCeil:
return rewriteValuegeneric_OpCeil(v)
case OpCom16:
@ -5288,6 +5297,150 @@ func rewriteValuegeneric_OpArraySelect(v *Value) bool {
}
return false
}
func rewriteValuegeneric_OpBitLen16(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (BitLen16 (Const16 [c]))
// cond: config.PtrSize == 8
// result: (Const64 [int64(bits.Len16(uint16(c)))])
for {
if v_0.Op != OpConst16 {
break
}
c := auxIntToInt16(v_0.AuxInt)
if !(config.PtrSize == 8) {
break
}
v.reset(OpConst64)
v.AuxInt = int64ToAuxInt(int64(bits.Len16(uint16(c))))
return true
}
// match: (BitLen16 (Const16 [c]))
// cond: config.PtrSize == 4
// result: (Const32 [int32(bits.Len16(uint16(c)))])
for {
if v_0.Op != OpConst16 {
break
}
c := auxIntToInt16(v_0.AuxInt)
if !(config.PtrSize == 4) {
break
}
v.reset(OpConst32)
v.AuxInt = int32ToAuxInt(int32(bits.Len16(uint16(c))))
return true
}
return false
}
func rewriteValuegeneric_OpBitLen32(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (BitLen32 (Const32 [c]))
// cond: config.PtrSize == 8
// result: (Const64 [int64(bits.Len32(uint32(c)))])
for {
if v_0.Op != OpConst32 {
break
}
c := auxIntToInt32(v_0.AuxInt)
if !(config.PtrSize == 8) {
break
}
v.reset(OpConst64)
v.AuxInt = int64ToAuxInt(int64(bits.Len32(uint32(c))))
return true
}
// match: (BitLen32 (Const32 [c]))
// cond: config.PtrSize == 4
// result: (Const32 [int32(bits.Len32(uint32(c)))])
for {
if v_0.Op != OpConst32 {
break
}
c := auxIntToInt32(v_0.AuxInt)
if !(config.PtrSize == 4) {
break
}
v.reset(OpConst32)
v.AuxInt = int32ToAuxInt(int32(bits.Len32(uint32(c))))
return true
}
return false
}
func rewriteValuegeneric_OpBitLen64(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (BitLen64 (Const64 [c]))
// cond: config.PtrSize == 8
// result: (Const64 [int64(bits.Len64(uint64(c)))])
for {
if v_0.Op != OpConst64 {
break
}
c := auxIntToInt64(v_0.AuxInt)
if !(config.PtrSize == 8) {
break
}
v.reset(OpConst64)
v.AuxInt = int64ToAuxInt(int64(bits.Len64(uint64(c))))
return true
}
// match: (BitLen64 (Const64 [c]))
// cond: config.PtrSize == 4
// result: (Const32 [int32(bits.Len64(uint64(c)))])
for {
if v_0.Op != OpConst64 {
break
}
c := auxIntToInt64(v_0.AuxInt)
if !(config.PtrSize == 4) {
break
}
v.reset(OpConst32)
v.AuxInt = int32ToAuxInt(int32(bits.Len64(uint64(c))))
return true
}
return false
}
func rewriteValuegeneric_OpBitLen8(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (BitLen8 (Const8 [c]))
// cond: config.PtrSize == 8
// result: (Const64 [int64(bits.Len8(uint8(c)))])
for {
if v_0.Op != OpConst8 {
break
}
c := auxIntToInt8(v_0.AuxInt)
if !(config.PtrSize == 8) {
break
}
v.reset(OpConst64)
v.AuxInt = int64ToAuxInt(int64(bits.Len8(uint8(c))))
return true
}
// match: (BitLen8 (Const8 [c]))
// cond: config.PtrSize == 4
// result: (Const32 [int32(bits.Len8(uint8(c)))])
for {
if v_0.Op != OpConst8 {
break
}
c := auxIntToInt8(v_0.AuxInt)
if !(config.PtrSize == 4) {
break
}
v.reset(OpConst32)
v.AuxInt = int32ToAuxInt(int32(bits.Len8(uint8(c))))
return true
}
return false
}
func rewriteValuegeneric_OpCeil(v *Value) bool {
v_0 := v.Args[0]
// match: (Ceil (Const64F [c]))