mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: compute XOR's limits from argument's limits
This help to optimize code like this:
func f(buckets *[512]bucket, v value) {
a, b := v.computeSomething()
// assume a and b are proved < 512
b := &buckets[a ^ b] // pick a random bucket
b.store(v)
}
Change-Id: I1acf702f5a8137f9ded49081b4703922879b0288
Reviewed-on: https://go-review.googlesource.com/c/go/+/604455
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
9a4fe7e14a
commit
49621cc311
2 changed files with 26 additions and 2 deletions
|
|
@ -1688,6 +1688,10 @@ func (ft *factsTable) flowLimit(v *Value) bool {
|
|||
uint64(bits.Len8(uint8(a.umax))))
|
||||
|
||||
// Masks.
|
||||
|
||||
// TODO: if y.umax and y.umin share a leading bit pattern, y also has that leading bit pattern.
|
||||
// we could compare the patterns of always set bits in a and b and learn more about minimum and maximum.
|
||||
// But I doubt this help any real world code.
|
||||
case OpAnd64, OpAnd32, OpAnd16, OpAnd8:
|
||||
// AND can only make the value smaller.
|
||||
a := ft.limits[v.Args[0].ID]
|
||||
|
|
@ -1699,8 +1703,10 @@ func (ft *factsTable) flowLimit(v *Value) bool {
|
|||
b := ft.limits[v.Args[1].ID]
|
||||
return ft.unsignedMin(v, maxU(a.umin, b.umin))
|
||||
case OpXor64, OpXor32, OpXor16, OpXor8:
|
||||
// TODO: use leading/trailing zeroes?
|
||||
// Not sure if it is worth it.
|
||||
// XOR can't flip bits that are proved to be zero in both inputs.
|
||||
a := ft.limits[v.Args[0].ID]
|
||||
b := ft.limits[v.Args[1].ID]
|
||||
return ft.unsignedMax(v, 1<<bits.Len64(a.umax|b.umax)-1)
|
||||
|
||||
// Arithmetic.
|
||||
case OpAdd64:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue