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: inline of a predicate uses temporary bool #4397

Closed
gopherbot opened this issue Nov 16, 2012 · 14 comments
Closed

cmd/compile: inline of a predicate uses temporary bool #4397

gopherbot opened this issue Nov 16, 2012 · 14 comments

Comments

@gopherbot
Copy link

by jeff.allen:

What steps will reproduce the problem?
If possible, include a link to a program on play.golang.org.
1. here is a program that makes a call to a predicate:

package main

func eq(a,b string) bool {
    return len(a) == len(b)
}

func main() {
    a := ""
    b := ""
    if eq(a,b) {
        println("ok")
    }
}

Inlining the predicate results in assembly with duplicate initialization of temporaries
on the stack and jumps forward and back. 

Is this really correct behavior? It seems suspiciously ugly.

What is the expected output?

This is the assembly from manually inlining the code (i.e. replacing a call to eq(a,b)
with the expression len(a)==len(b))

--- prog list "main" ---
0010 (streq.go:7) TEXT    main+0(SB),$16-0
0011 (streq.go:8) LEAQ    go.string.""+0(SB),BX
0012 (streq.go:8) MOVQ    (BX),BP
0013 (streq.go:8) MOVQ    8(BX),CX
0014 (streq.go:9) MOVQ    (BX),BP
0015 (streq.go:9) MOVQ    8(BX),AX
0016 (streq.go:10) CMPQ    CX,AX
0017 (streq.go:10) JNE     ,26
0018 (streq.go:11) LEAQ    go.string."ok"+0(SB),BX
0019 (streq.go:11) LEAQ    (SP),BP
0020 (streq.go:11) MOVQ    BP,DI
0021 (streq.go:11) MOVQ    BX,SI
0022 (streq.go:11) MOVSQ   ,
0023 (streq.go:11) MOVSQ   ,
0024 (streq.go:11) CALL    ,runtime.printstring+0(SB)
0025 (streq.go:11) CALL    ,runtime.printnl+0(SB)
0026 (streq.go:13) RET     ,

What do you see instead?

This is the assembly from 6g with inlining. Note the useless MOVB $0,.anon2, which after
two jumps (!), is overwritten by MOV AX,.anon2, then compared to $0.

--- prog list "main" ---
0010 (streq.go:7) TEXT    main+0(SB),$24-0
0011 (streq.go:8) LEAQ    go.string.""+0(SB),BX
0012 (streq.go:8) MOVQ    (BX),SI
0013 (streq.go:8) MOVQ    8(BX),DX
0014 (streq.go:9) MOVQ    (BX),CX
0015 (streq.go:9) MOVQ    8(BX),BP
0016 (streq.go:10) MOVB    $0,.anon2+-1(SP)
0017 (streq.go:10) JMP     ,20
0018 (streq.go:10) MOVQ    $1,AX
0019 (streq.go:10) JMP     ,23
0020 (streq.go:10) CMPQ    DX,BP
0021 (streq.go:10) JEQ     ,18
0022 (streq.go:10) MOVQ    $0,AX
0023 (streq.go:10) MOVB    AX,.anon2+-1(SP)
0024 (streq.go:10) MOVBQZX .anon2+-1(SP),BX
0025 (streq.go:10) CMPB    BX,$0
0026 (streq.go:10) JEQ     ,35
0027 (streq.go:11) LEAQ    go.string."ok"+0(SB),BX
0028 (streq.go:11) LEAQ    (SP),BP
0029 (streq.go:11) MOVQ    BP,DI
0030 (streq.go:11) MOVQ    BX,SI
0031 (streq.go:11) MOVSQ   ,
0032 (streq.go:11) MOVSQ   ,
0033 (streq.go:11) CALL    ,runtime.printstring+0(SB)
0034 (streq.go:11) CALL    ,runtime.printnl+0(SB)
0035 (streq.go:13) RET     ,


Which compiler are you using (5g, 6g, 8g, gccgo)?

6g

Which operating system are you using?

Linux

Which version are you using?  (run 'go version')

14893:591fc8a0131a
@davecheney
Copy link
Contributor

Comment 1:

related discussion: https://groups.google.com/d/topic/golang-dev/NTuctRBO1aQ/discussion

@robpike
Copy link
Contributor

robpike commented Nov 16, 2012

Comment 2:

Here's what comes out of the linker:
002000  main.main            | (7)      TEXT    main.main+0(SB),$24
002000  65488b0c25a0080000   | (7)      MOVQ    2208(GS),CX
002009  483b21               | (7)      CMPQ    SP,(CX)
00200c  7705                 | (7)      JHI     ,2013
00200e  e82d130100           | (7)      CALL    ,13340+runtime.morestack00
002013  4883ec18             | (7)      SUBQ    $24,SP
002017  488d1c25e0b00100     | (8)      LEAQ    go.string.""+0(SB),BX
00201f  488b33               | (8)      MOVQ    (BX),SI
002022  488b5308             | (8)      MOVQ    8(BX),DX
002026  488b0b               | (9)      MOVQ    (BX),CX
002029  488b6b08             | (9)      MOVQ    8(BX),BP
00202d  c644241700           | (10)     MOVB    $0,main..anon2+23(SP)
002032  4839ea               | (10)     CMPQ    DX,BP
002035  7431                 | (10)     JEQ     ,2068
002037  4831c0               | (10)     MOVQ    $0,AX
00203a  88442417             | (10)     MOVB    AL,main..anon2+23(SP)
00203e  480fb65c2417         | (10)     MOVBQZX main..anon2+23(SP),BX
002044  80fb00               | (10)     CMPB    BL,$0
002047  741a                 | (10)     JEQ     ,2063
002049  488d342508bc0100     | (11)     LEAQ    go.string."ok"+0(SB),SI
002051  488d3c24             | (11)     LEAQ    (SP),DI
002055  48a5                 | (11)     MOVSQ   ,
002057  48a5                 | (11)     MOVSQ   ,
002059  e802900000           | (11)     CALL    ,b060+runtime.printstring
00205e  e86d900000           | (11)     CALL    ,b0d0+runtime.printnl
002063  4883c418             | (13)     ADDQ    $24,SP
002067  c3                   | (13)     RET     ,

@robpike
Copy link
Contributor

robpike commented Nov 16, 2012

Comment 3:

Labels changed: added priority-later, performance, removed priority-triage.

Status changed to Accepted.

@rsc
Copy link
Contributor

rsc commented Dec 10, 2012

Comment 4:

Labels changed: added size-l.

@rsc
Copy link
Contributor

rsc commented Feb 3, 2013

Comment 5:

The anons are gone in the latest copy of the code, but the inlined function is still
computing a value into AL and then the AL value gets tested after the "return". I don't
think this is terribly important, but maybe it will happen for Go 1.1.
002000  main.main            | (7)  TEXT    main.main+0(SB),$16
002000  65488b0c25a0080000   | (7)  MOVQ    2208(GS),CX
002009  483b21               | (7)  CMPQ    SP,(CX)
00200c  7705                 | (7)  JHI ,2013
00200e  e82d380100           | (7)  CALL    ,15840+runtime.morestack00
002013  4883ec10             | (7)  SUBQ    $16,SP
002017  488d1c25e0f00100     | (8)  LEAQ    go.string.""+0(SB),BX
00201f  488b3b               | (8)  MOVQ    (BX),DI
002022  488b5308             | (8)  MOVQ    8(BX),DX
002026  488b33               | (9)  MOVQ    (BX),SI
002029  488b6b08             | (9)  MOVQ    8(BX),BP
00202d  4831c0               | (10) MOVQ    $0,AX
002030  4839ea               | (10) CMPQ    DX,BP
002033  742d                 | (10) JEQ ,2062
002035  4831c0               | (10) MOVQ    $0,AX
002038  80f800               | (10) CMPB    AL,$0
00203b  7420                 | (10) JEQ ,205d
00203d  488d1c2588fd0100     | (11) LEAQ    go.string."ok"+0(SB),BX
002045  488d2c24             | (11) LEAQ    (SP),BP
002049  4889ef               | (11) MOVQ    BP,DI
00204c  4889de               | (11) MOVQ    BX,SI
00204f  48a5                 | (11) MOVSQ   ,
002051  48a5                 | (11) MOVSQ   ,
002053  e8a8ad0000           | (11) CALL    ,ce00+runtime.printstring
002058  e813ae0000           | (11) CALL    ,ce70+runtime.printnl
00205d  4883c410             | (13) ADDQ    $16,SP
002061  c3                   | (13) RET ,
002062  48c7c001000000       | (10) MOVQ    $1,AX
002069  ebcd                 | (10) JMP ,2038

Labels changed: added go1.1maybe, removed go1.1.

@robpike
Copy link
Contributor

robpike commented Mar 7, 2013

Comment 6:

Labels changed: removed go1.1maybe.

@rsc
Copy link
Contributor

rsc commented Jul 30, 2013

Comment 7:

Labels changed: added go1.2maybe.

@rsc
Copy link
Contributor

rsc commented Jul 30, 2013

Comment 8:

Labels changed: added feature.

@robpike
Copy link
Contributor

robpike commented Aug 29, 2013

Comment 9:

Not for 1.2.

Labels changed: removed go1.2maybe.

@rsc
Copy link
Contributor

rsc commented Nov 27, 2013

Comment 10:

Labels changed: added go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Nov 27, 2013

Comment 11:

Labels changed: removed feature.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 12:

Labels changed: added release-none, removed go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 13:

Labels changed: added repo-main.

@rsc rsc added this to the Unplanned milestone Apr 10, 2015
@rsc rsc changed the title cmd/6g: inline of a predicate uses temporary bool cmd/compile: inline of a predicate uses temporary bool Jun 8, 2015
@alexey-s-sidorov
Copy link

I think this is all right.
Tested on dev.ssa.
Fragment of objdumped binary:

0000000000401000 <main.main>:
401000: mov %fs:0xfffffffffffffff8,%rcx
401009: cmp 0x10(%rcx),%rsp
40100d: jbe 401040 <main.main+0x40>
40100f: sub $0x10,%rsp
401013: callq 4202d0 <runtime.printlock>
401018: lea 0x692b7(%rip),%rax # 46a2d6 <go.string.*+0xb6>
40101f: mov %rax,(%rsp)
401023: movq $0x2,0x8(%rsp)
40102c: callq 420b90 <runtime.printstring>
401031: callq 420560 <runtime.printnl>
401036: callq 420350 <runtime.printunlock>
40103b: add $0x10,%rsp
40103f: retq
401040: callq 443a70 <runtime.morestack_noctxt>
401045: jmp 401000 <main.main>
401047: int3
401048: int3
401049: int3
40104a: int3
40104b: int3
40104c: int3
40104d: int3
40104e: int3
40104f: int3

looks fixed.

@golang golang locked and limited conversation to collaborators Feb 28, 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

6 participants