]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add 2 phiopt cases
authorJakub Ciolek <jakub@ciolek.dev>
Sat, 19 Apr 2025 10:31:26 +0000 (12:31 +0200)
committerGopher Robot <gobot@golang.org>
Thu, 8 May 2025 17:18:37 +0000 (10:18 -0700)
Add 2 more cases:

if a { x = value } else { x = a } => x = a && value
if a { x = a } else { x = value } => x = a || value

AND case goes from:

00006 (8) TESTB AX, AX
00007 (8) JNE 9
00008 (13) MOVL AX, BX
00009 (13) MOVL BX, AX
00010 (13) RET

to:

00006 (13) ANDL BX, AX
00007 (13) RET

OR goes from:

00006 (19) TESTB AX, AX
00007 (19) JNE 9
00008 (24) MOVL BX, AX
00009 (24) RET

to:

00006 (24) ORL BX, AX
00007 (24) RET

compilecmp linux/amd64:

runtime
runtime.lock2 847 -> 869  (+2.60%)
runtime.addspecial 542 -> 517  (-4.61%)
runtime.tracebackPCs changed
runtime.scanstack changed
runtime.mallocinit changed
runtime.traceback2 2238 -> 2206  (-1.43%)

runtime [cmd/compile]
runtime.lock2 860 -> 882  (+2.56%)
runtime.scanstack changed
runtime.addspecial 542 -> 517  (-4.61%)
runtime.traceback2 2238 -> 2206  (-1.43%)
runtime.lockWithRank 870 -> 890  (+2.30%)
runtime.tracebackPCs changed
runtime.mallocinit changed

strconv
strconv.ryuFtoaFixed32 changed
strconv.ryuFtoaFixed64 639 -> 638  (-0.16%)
strconv.readFloat changed
strconv.ryuFtoaShortest changed

strings
strings.(*Replacer).build changed

strconv [cmd/compile]
strconv.readFloat changed
strconv.ryuFtoaFixed64 639 -> 638  (-0.16%)
strconv.ryuFtoaFixed32 changed
strconv.ryuFtoaShortest changed

strings [cmd/compile]
strings.(*Replacer).build changed

regexp
regexp.makeOnePass.func1 changed

regexp [cmd/compile]
regexp.makeOnePass.func1 changed

encoding/json
encoding/json.indirect changed

database/sql
database/sql.driverArgsConnLocked changed

vendor/golang.org/x/text/unicode/norm
vendor/golang.org/x/text/unicode/norm.Form.transform changed

go/doc/comment
go/doc/comment.parseSpans changed

internal/diff
internal/diff.tgs changed

log/slog
log/slog.(*handleState).appendNonBuiltIns 1898 -> 1877  (-1.11%)

testing/fstest
testing/fstest.(*fsTester).checkGlob changed

runtime/pprof
runtime/pprof.(*profileBuilder).build changed

cmd/internal/dwarf
cmd/internal/dwarf.isEmptyInlinedCall 254 -> 244  (-3.94%)

go/printer
go/printer.keepTypeColumn 302 -> 270  (-10.60%)
go/printer.(*printer).binaryExpr changed

cmd/compile/internal/syntax
cmd/compile/internal/syntax.(*scanner).rune changed
cmd/compile/internal/syntax.(*scanner).number 2137 -> 2153  (+0.75%)

Change-Id: I7f95f54b03a35d0b616c40f38b415a7feb71be73
Reviewed-on: https://go-review.googlesource.com/c/go/+/666835
Reviewed-by: Keith Randall <khr@golang.org>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: Jakub Ciolek <jakub@ciolek.dev>
TryBot-Bypass: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/compile/internal/ssa/phiopt.go
test/codegen/bool.go
test/phiopt.go

index 037845eacf2db6afeb1fe683ce253f2ee4526e0a..034ee4c661046b2ffe63137a1b6c3e4776f2ec0b 100644 (file)
@@ -119,6 +119,33 @@ func phiopt(f *Func) {
                                        continue
                                }
                        }
+                       // Replaces
+                       //   if a { x = value } else { x = a } with x = a && value.
+                       // Requires that value dominates x.
+                       if v.Args[1-reverse] == b0.Controls[0] {
+                               if tmp := v.Args[reverse]; sdom.IsAncestorEq(tmp.Block, b) {
+                                       v.reset(OpAndB)
+                                       v.SetArgs2(b0.Controls[0], tmp)
+                                       if f.pass.debug > 0 {
+                                               f.Warnl(b.Pos, "converted OpPhi to %v", v.Op)
+                                       }
+                                       continue
+                               }
+                       }
+
+                       // Replaces
+                       //   if a { x = a } else { x = value } with x = a || value.
+                       // Requires that value dominates x.
+                       if v.Args[reverse] == b0.Controls[0] {
+                               if tmp := v.Args[1-reverse]; sdom.IsAncestorEq(tmp.Block, b) {
+                                       v.reset(OpOrB)
+                                       v.SetArgs2(b0.Controls[0], tmp)
+                                       if f.pass.debug > 0 {
+                                               f.Warnl(b.Pos, "converted OpPhi to %v", v.Op)
+                                       }
+                                       continue
+                               }
+                       }
                }
        }
        // strengthen phi optimization.
index 2024759a5c530f7d7296648de9d58432dc7960f8..760dbbcf7b55a79811eb3b50fdd8a33cb253349b 100644 (file)
@@ -62,6 +62,30 @@ func convertEqBool64(x uint64) bool {
        return x&1 == 0
 }
 
+func phiAnd(a, b bool) bool {
+       var x bool
+       // amd64:-"TESTB"
+       if a {
+               x = b
+       } else {
+               x = a
+       }
+       // amd64:"ANDL"
+       return x
+}
+
+func phiOr(a, b bool) bool {
+       var x bool
+       // amd64:-"TESTB"
+       if a {
+               x = a
+       } else {
+               x = b
+       }
+       // amd64:"ORL"
+       return x
+}
+
 func TestSetEq64(x uint64, y uint64) bool {
        // ppc64x/power10:"SETBC\tCR0EQ",-"ISEL"
        // ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0EQ"
index 9e21bfdba55aeab33ecf4d943043ff5485164861..206a117fbb2c4a5c3bcb76deab28a4c210cd5cd3 100644 (file)
@@ -129,5 +129,27 @@ func f9(a, b int) bool {
        return c
 }
 
+//go:noinline
+func f10and(a bool, b bool) bool {
+       var x bool
+       if a {
+               x = b
+       } else {
+               x = a
+       }
+       return x // ERROR "converted OpPhi to AndB$"
+}
+
+//go:noinline
+func f11or(a bool, b bool) bool {
+       var x bool
+       if a {
+               x = a
+       } else {
+               x = b
+       }
+       return x // ERROR "converted OpPhi to OrB$"
+}
+
 func main() {
 }