mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile/internal/ssa: on PPC64, merge (CMPconst [0] (op ...)) more aggressively
Generate the CC version of many opcodes whose result is compared against signed 0. The approach taken here works even if the opcode result is used in multiple places too. Add support for ADD, ADDconst, ANDN, SUB, NEG, CNTLZD, NOR conversions to their CC opcode variant. These are the most commonly used variants. Also, do not set clobberFlags of CNTLZD and CNTLZW, they do not clobber flags. This results in about 1% smaller text sections in kubernetes binaries, and no regressions in the crypto benchmarks. Change-Id: I9e0381944869c3774106bf348dead5ecb96dffda Reviewed-on: https://go-review.googlesource.com/c/go/+/538636 Run-TryBot: Paul Murphy <murp@ibm.com> TryBot-Result: Gopher Robot <gobot@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Jayanth Krishnamurthy <jayanth.krishnamurthy@ibm.com> Reviewed-by: Heschi Kreinick <heschi@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
This commit is contained in:
parent
30de0b5ef4
commit
773039ed5c
7 changed files with 662 additions and 73 deletions
|
|
@ -1630,6 +1630,52 @@ func mergePPC64SldiSrw(sld, srw int64) int64 {
|
|||
return encodePPC64RotateMask((32-srw+sld)&31, int64(mask), 32)
|
||||
}
|
||||
|
||||
// Convert a PPC64 opcode from the Op to OpCC form. This converts (op x y)
|
||||
// to (Select0 (opCC x y)) without having to explicitly fixup every user
|
||||
// of op.
|
||||
//
|
||||
// E.g consider the case:
|
||||
// a = (ADD x y)
|
||||
// b = (CMPconst [0] a)
|
||||
// c = (OR a z)
|
||||
//
|
||||
// A rule like (CMPconst [0] (ADD x y)) => (CMPconst [0] (Select0 (ADDCC x y)))
|
||||
// would produce:
|
||||
// a = (ADD x y)
|
||||
// a' = (ADDCC x y)
|
||||
// a” = (Select0 a')
|
||||
// b = (CMPconst [0] a”)
|
||||
// c = (OR a z)
|
||||
//
|
||||
// which makes it impossible to rewrite the second user. Instead the result
|
||||
// of this conversion is:
|
||||
// a' = (ADDCC x y)
|
||||
// a = (Select0 a')
|
||||
// b = (CMPconst [0] a)
|
||||
// c = (OR a z)
|
||||
//
|
||||
// Which makes it trivial to rewrite b using a lowering rule.
|
||||
func convertPPC64OpToOpCC(op *Value) *Value {
|
||||
ccOpMap := map[Op]Op{
|
||||
OpPPC64ADD: OpPPC64ADDCC,
|
||||
OpPPC64ADDconst: OpPPC64ADDCCconst,
|
||||
OpPPC64AND: OpPPC64ANDCC,
|
||||
OpPPC64ANDN: OpPPC64ANDNCC,
|
||||
OpPPC64CNTLZD: OpPPC64CNTLZDCC,
|
||||
OpPPC64OR: OpPPC64ORCC,
|
||||
OpPPC64SUB: OpPPC64SUBCC,
|
||||
OpPPC64NEG: OpPPC64NEGCC,
|
||||
OpPPC64NOR: OpPPC64NORCC,
|
||||
OpPPC64XOR: OpPPC64XORCC,
|
||||
}
|
||||
b := op.Block
|
||||
opCC := b.NewValue0I(op.Pos, ccOpMap[op.Op], types.NewTuple(op.Type, types.TypeFlags), op.AuxInt)
|
||||
opCC.AddArgs(op.Args...)
|
||||
op.reset(OpSelect0)
|
||||
op.AddArgs(opCC)
|
||||
return op
|
||||
}
|
||||
|
||||
// Convenience function to rotate a 32 bit constant value by another constant.
|
||||
func rotateLeft32(v, rotate int64) int64 {
|
||||
return int64(bits.RotateLeft32(uint32(v), int(rotate)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue