mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile/internal/ssa: combine more shift and masking on PPC64
Investigating binaries, these patterns seem to show up frequently. Change-Id: I987251e4070e35c25e98da321e444ccaa1526912 Reviewed-on: https://go-review.googlesource.com/c/go/+/583302 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
This commit is contained in:
parent
bbdad50c09
commit
0222a028f1
4 changed files with 261 additions and 1 deletions
|
|
@ -1653,6 +1653,56 @@ func mergePPC64ClrlsldiRlwinm(sld int32, rlw int64) int64 {
|
|||
return encodePPC64RotateMask(r_3, int64(mask_3), 32)
|
||||
}
|
||||
|
||||
// Test if RLWINM feeding into an ANDconst can be merged. Return the encoded RLWINM constant,
|
||||
// or 0 if they cannot be merged.
|
||||
func mergePPC64AndRlwinm(mask uint32, rlw int64) int64 {
|
||||
r, _, _, mask_rlw := DecodePPC64RotateMask(rlw)
|
||||
mask_out := (mask_rlw & uint64(mask))
|
||||
|
||||
// Verify the result is still a valid bitmask of <= 32 bits.
|
||||
if !isPPC64WordRotateMask(int64(mask_out)) {
|
||||
return 0
|
||||
}
|
||||
return encodePPC64RotateMask(r, int64(mask_out), 32)
|
||||
}
|
||||
|
||||
// Test if AND feeding into an ANDconst can be merged. Return the encoded RLWINM constant,
|
||||
// or 0 if they cannot be merged.
|
||||
func mergePPC64RlwinmAnd(rlw int64, mask uint32) int64 {
|
||||
r, _, _, mask_rlw := DecodePPC64RotateMask(rlw)
|
||||
|
||||
// Rotate the input mask, combine with the rlwnm mask, and test if it is still a valid rlwinm mask.
|
||||
r_mask := bits.RotateLeft32(mask, int(r))
|
||||
|
||||
mask_out := (mask_rlw & uint64(r_mask))
|
||||
|
||||
// Verify the result is still a valid bitmask of <= 32 bits.
|
||||
if !isPPC64WordRotateMask(int64(mask_out)) {
|
||||
return 0
|
||||
}
|
||||
return encodePPC64RotateMask(r, int64(mask_out), 32)
|
||||
}
|
||||
|
||||
// Test if RLWINM feeding into SRDconst can be merged. Return the encoded RLIWNM constant,
|
||||
// or 0 if they cannot be merged.
|
||||
func mergePPC64SldiRlwinm(sldi, rlw int64) int64 {
|
||||
r_1, mb, me, mask_1 := DecodePPC64RotateMask(rlw)
|
||||
if mb > me || mb < sldi {
|
||||
// Wrapping masks cannot be merged as the upper 32 bits are effectively undefined in this case.
|
||||
// Likewise, if mb is less than the shift amount, it cannot be merged.
|
||||
return 0
|
||||
}
|
||||
// combine the masks, and adjust for the final left shift.
|
||||
mask_3 := mask_1 << sldi
|
||||
r_3 := (r_1 + sldi) & 31 // This can wrap.
|
||||
|
||||
// Verify the result is still a valid bitmask of <= 32 bits.
|
||||
if uint64(uint32(mask_3)) != mask_3 {
|
||||
return 0
|
||||
}
|
||||
return encodePPC64RotateMask(r_3, int64(mask_3), 32)
|
||||
}
|
||||
|
||||
// Compute the encoded RLWINM constant from combining (SLDconst [sld] (SRWconst [srw] x)),
|
||||
// or return 0 if they cannot be combined.
|
||||
func mergePPC64SldiSrw(sld, srw int64) int64 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue