From: Keith Randall Date: Thu, 5 Jan 2023 21:02:44 +0000 (-0800) Subject: cmd/compile: improve register overwrite decision for resultInArg0 ops X-Git-Tag: go1.21rc1~1796 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=3c7884a21b2929b5a42d6a1f237f5fee2ae72ba8;p=gostls13.git cmd/compile: improve register overwrite decision for resultInArg0 ops When we're compiling a resultInArg0 op, we need to clobber the register containing the input value. So we first make a register copy of the input value. We can then clobber either of the two registers the value is in and still have the original input value in a register for future uses. Before this CL, we always clobbered the original, not the copy. But that's not always the right decision - if the original is already in a specific register that it needs to be in later (typically, a return value register), clobber the copy instead. This optimization can remove a mov instruction. It saves 1376 bytes of instructions in cmd/go. Change-Id: I162870c84b9a180da6715bb24c296a902974fed3 Reviewed-on: https://go-review.googlesource.com/c/go/+/460656 Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot Reviewed-by: Matthew Dempsky Run-TryBot: Keith Randall --- diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go index 294c522a90..05765bb701 100644 --- a/src/cmd/compile/internal/ssa/regalloc.go +++ b/src/cmd/compile/internal/ssa/regalloc.go @@ -1544,6 +1544,7 @@ func (s *regAllocState) regalloc(f *Func) { } } } + // Avoid future fixed uses if we can. if m&^desired.avoid != 0 { m &^= desired.avoid @@ -1551,6 +1552,19 @@ func (s *regAllocState) regalloc(f *Func) { // Save input 0 to a new register so we can clobber it. c := s.allocValToReg(v.Args[0], m, true, v.Pos) s.copies[c] = false + + // Normally we use the register of the old copy of input 0 as the target. + // However, if input 0 is already in its desired register then we use + // the register of the new copy instead. + if rp, ok := s.f.getHome(args[0].ID).(*Register); ok { + r := register(rp.num) + for _, r2 := range dinfo[idx].in[0] { + if r == r2 { + args[0] = c + break + } + } + } } ok: