Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: redundant jumps #14277

Closed
brtzsnr opened this issue Feb 9, 2016 · 5 comments
Closed

cmd/compile: redundant jumps #14277

brtzsnr opened this issue Feb 9, 2016 · 5 comments
Milestone

Comments

@brtzsnr
Copy link
Contributor

brtzsnr commented Feb 9, 2016

dev.ssa: The following code

// gostress -seed 31876
package main
import "fmt"
var b2i = map[bool]int{true:1}
func main() {
fmt.Println(f1_ssa(false, 0, 1, ))
}
func f1_ssa(a1 bool, a2 uint8, a3 int64, ) int {
switch {} // prevent inlining
a3 += a3 << 1 // int64
v1 := (a3 & a3) + (a3 | a3) + (a3 ^ (a3 - a3)) << ((1 * (2 + 3)) | 1) // int64
_ = v1
a2--
v2 := (a2 != a2) || (a1 && a1) || a1 || (v1 == v1) // bool
_ = v2
a2--
v2 = v2 // bool
v3 := (v1 * v1) ^ (a3 >> 1) * (a3 << (a2 | a2)) * v1 // int64
_ = v3
return 0 + (int(1) >> (2 - 1) * 2)
}

results in a lot of redundant jumps. After the trim pass:

b3:
v1 = InitMem <mem>
v9 = VarDef <mem> {~r3} v1
v2 = SP <uintptr> : SP
v10 = MOVQstoreconst <mem> {~r3} v2 v9
v85 = Arg <bool> {a1} : a1[bool]
v32 = LoadReg <bool> v85 : AX
v50 = TESTB <flags> v32 v32
NE v50 → b4 b4
b4: ← b3 b3
NE v50 → b10 b8
b10: ← b8 b8 b4
v52 = VarDef <mem> {~r3} v10
v53 = MOVQstoreconst <mem> {~r3} v2 v52
Ret v53
b8: ← b4
NE v50 → b10 b10

and the code generated

00070 (f.go:8)  TEXT    "".f1_ssa(SB), $0
00071 (f.go:8)  FUNCDATA    $0, "".gcargs·2(SB)
00072 (f.go:8)  FUNCDATA    $1, "".gclocals·3(SB)
00073 (f.go:8)  TYPE    "".a1(FP)type.bool, $1
00074 (f.go:8)  TYPE    "".a2+1(FP)type.uint8, $1
00075 (f.go:8)  TYPE    "".a3+8(FP)type.int64, $8
00076 (f.go:8)  TYPE    "".~r3+16(FP)type.int, $8
00077 (f.go:8)  TYPE    "".v1(SP)type.int64, $8
00078 (f.go:8)  TYPE    "".v2(SP)type.bool, $1
00079 (f.go:8)  TYPE    "".v3(SP)type.int64, $8
00080 (f.go:8)  TYPE "".autotmp_0006(SP)type.int64, $8
00081 (f.go:8)  TYPE "".autotmp_0007(SP)type.uint8, $1
00082 (f.go:8)  TYPE "".autotmp_0008(SP)type.uint8, $1
v9
00083 (f.go:8)  VARDEF  "".~r3+16(FP)
v10
00084 (f.go:8)  MOVQ    $0, "".~r3+16(FP)
v32
00085 (f.go:8)  MOVB    "".a1(FP), AX
v50
00086 (f.go:8)  TESTB   AX, AX
b3
00087 (f.go:14) JEQ 88
b4
00088 (f.go:14) JEQ 92
v52
00089 (f.go:20) VARDEF  "".~r3+16(FP)
v53
00090 (f.go:20) MOVQ    $0, "".~r3+16(FP)
b10
00091 (f.go:20) RET
b8
00092 (f.go:14) JNE 89
b8
00093 (f.go:14) JMP 89
00094 (<unknown line number>)   END

For example JEQ 92 branch cannot be taken.

@ianlancetaylor ianlancetaylor added this to the Go1.7 milestone Feb 9, 2016
@ianlancetaylor
Copy link
Contributor

CC @randall77

@gopherbot
Copy link

CL https://golang.org/cl/19414 mentions this issue.

@gopherbot
Copy link

CL https://golang.org/cl/19464 mentions this issue.

gopherbot pushed a commit that referenced this issue Feb 17, 2016
* In cases where we end up with empty branches like in
if a then jmp b else jmp b;
the flow can be replaced by a; jmp b.

The following functions is optimized as follows:
func f(a bool, x int) int {
        v := 0
        if a {
                v = -1
        } else {
                v = -1
        }
        return x | v
}

Before this change:
02819 (arith_ssa.go:362)  VARDEF "".~r2+16(FP)
02820 (arith_ssa.go:362)  MOVQ  $0, "".~r2+16(FP)
02821 (arith_ssa.go:362)  MOVB  "".a(FP), AX
02822 (arith_ssa.go:362)  TESTB AX, AX
02823 (arith_ssa.go:364)  JEQ 2824
02824 (arith_ssa.go:369)  VARDEF "".~r2+16(FP)
02825 (arith_ssa.go:369)  MOVQ  $-1, "".~r2+16(FP)
02826 (arith_ssa.go:369)  RET

After this change:
02819 (arith_ssa.go:362)  VARDEF "".~r2+16(FP)
02820 (arith_ssa.go:369)  VARDEF "".~r2+16(FP)
02821 (arith_ssa.go:369)  MOVQ  $-1, "".~r2+16(FP)
02822 (arith_ssa.go:369)  RET

Updates #14277

Change-Id: Ibe7d284f43406c704903632a4fcf2a4a64059686
Reviewed-on: https://go-review.googlesource.com/19464
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Alexandru Moșoi <alexandru@mosoi.ro>
TryBot-Result: Gobot Gobot <gobot@golang.org>
@brtzsnr
Copy link
Contributor Author

brtzsnr commented Feb 17, 2016

Not closing because a few cases are not handled yet. I'm looking for more examples.

@brtzsnr
Copy link
Contributor Author

brtzsnr commented Apr 1, 2016

Fixed now. The generated code looks very nice:

        a.go:20 0x401110        48c744241800000000      MOVQ $0x0, 0x18(SP)
        a.go:20 0x401119        c3                      RET

@brtzsnr brtzsnr closed this as completed Apr 1, 2016
@golang golang locked and limited conversation to collaborators Apr 2, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants