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: elimination of unused runtime calls #17216

Open
DmitriyMV opened this issue Sep 23, 2016 · 6 comments
Open

cmd/compile: elimination of unused runtime calls #17216

DmitriyMV opened this issue Sep 23, 2016 · 6 comments
Labels
binary-size compiler/runtime Issues related to the Go compiler and/or runtime. Performance
Milestone

Comments

@DmitriyMV
Copy link

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.7.1 windows/amd64

What operating system and processor architecture are you using (go env)?

set GOARCH=amd64
set GOBIN=
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\Dmitriy\Coding\Go\
set GORACE=
set GOROOT=C:\Dmitriy\Go
set GOTOOLDIR=C:\Dmitriy\Go\pkg\tool\windows_amd64
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0
set CXX=g++
set CGO_ENABLED=1

What did you do?

Compiled simple program with two unused parameters of type interface{} and empty body.
https://play.golang.org/p/TkLKdhLcXo

What did you expect to see?

Dead code elimination removing the call to empty and any unnecessary conversions.

What did you see instead?

The call to empty was removed, but conversions are left around:

TEXT main.main(SB) C:/Dmitriy/Coding/Go/src/github.com/DmitriyMV/ssa_test/main.go
    main.go:5   0x401040    65488b0c2528000000  GS MOVQ GS:0x28, CX
    main.go:5   0x401049    488b8900000000      MOVQ 0(CX), CX
    main.go:5   0x401050    483b6110        CMPQ 0x10(CX), SP
    main.go:5   0x401054    0f86c1000000        JBE 0x40111b
    main.go:5   0x40105a    4881ec80000000      SUBQ $0x80, SP
    main.go:5   0x401061    48896c2478      MOVQ BP, 0x78(SP)
    main.go:5   0x401066    488d6c2478      LEAQ 0x78(SP), BP
    main.go:6   0x40106b    48c74424300a000000  MOVQ $0xa, 0x30(SP)
    main.go:6   0x401074    488d1d97750900      LEAQ 0x97597(IP), BX
    main.go:6   0x40107b    48895c2468      MOVQ BX, 0x68(SP)
    main.go:6   0x401080    48c744247005000000  MOVQ $0x5, 0x70(SP)
    main.go:6   0x401089    48c744242800000000  MOVQ $0x0, 0x28(SP)
    main.go:6   0x401092    488d1de7e10700      LEAQ 0x7e1e7(IP), BX
    main.go:6   0x401099    48891c24        MOVQ BX, 0(SP)
    main.go:6   0x40109d    488d5c2430      LEAQ 0x30(SP), BX
    main.go:6   0x4010a2    48895c2408      MOVQ BX, 0x8(SP)
    main.go:6   0x4010a7    488d5c2428      LEAQ 0x28(SP), BX
    main.go:6   0x4010ac    48895c2410      MOVQ BX, 0x10(SP)
    main.go:6   0x4010b1    e86a930000      CALL runtime.convT2E(SB)
    main.go:6   0x4010b6    488b5c2418      MOVQ 0x18(SP), BX
    main.go:6   0x4010bb    48895c2458      MOVQ BX, 0x58(SP)
    main.go:6   0x4010c0    488b5c2420      MOVQ 0x20(SP), BX
    main.go:6   0x4010c5    48895c2460      MOVQ BX, 0x60(SP)
    main.go:6   0x4010ca    31db            XORL BX, BX
    main.go:6   0x4010cc    48895c2438      MOVQ BX, 0x38(SP)
    main.go:6   0x4010d1    48895c2440      MOVQ BX, 0x40(SP)
    main.go:6   0x4010d6    488d1d63e60700      LEAQ 0x7e663(IP), BX
    main.go:6   0x4010dd    48891c24        MOVQ BX, 0(SP)
    main.go:6   0x4010e1    488d5c2468      LEAQ 0x68(SP), BX
    main.go:6   0x4010e6    48895c2408      MOVQ BX, 0x8(SP)
    main.go:6   0x4010eb    488d5c2438      LEAQ 0x38(SP), BX
    main.go:6   0x4010f0    48895c2410      MOVQ BX, 0x10(SP)
    main.go:6   0x4010f5    e826930000      CALL runtime.convT2E(SB)
    main.go:6   0x4010fa    488b5c2418      MOVQ 0x18(SP), BX
    main.go:6   0x4010ff    48895c2448      MOVQ BX, 0x48(SP)
    main.go:6   0x401104    488b5c2420      MOVQ 0x20(SP), BX
    main.go:6   0x401109    48895c2450      MOVQ BX, 0x50(SP)
    main.go:7   0x40110e    488b6c2478      MOVQ 0x78(SP), BP
    main.go:7   0x401113    4881c480000000      ADDQ $0x80, SP
    main.go:7   0x40111a    c3          RET
    main.go:5   0x40111b    e890d10400      CALL runtime.morestack_noctxt(SB)
    main.go:5   0x401120    e91bffffff      JMP main.main(SB)

Same thing happen with parameters of map[type]type. With parameter of ...interface{} the empty function itself doesn't get optimized away.

While it's not a bug, it can be a handy feature for debug prints that get optimized away if build tag doesn't present.

@DmitriyMV DmitriyMV changed the title cmd/compile Dead code elemination cmd/compile: Dead code elimination and parameters of interface{} Sep 23, 2016
@randall77
Copy link
Contributor

This is mostly fixed on tip. It now compiles to:

        tmp1.go:5       0x2040  4883ec20                SUBQ $0x20, SP          
        tmp1.go:5       0x2044  48896c2418              MOVQ BP, 0x18(SP)       
        tmp1.go:5       0x2049  488d6c2418              LEAQ 0x18(SP), BP       
        tmp1.go:6       0x204e  48c704240a000000        MOVQ $0xa, 0(SP)        
        tmp1.go:6       0x2056  488d0516220600          LEAQ 0x62216(IP), AX    
        tmp1.go:6       0x205d  4889442408              MOVQ AX, 0x8(SP)        
        tmp1.go:6       0x2062  48c744241005000000      MOVQ $0x5, 0x10(SP)     
        tmp1.go:7       0x206b  488b6c2418              MOVQ 0x18(SP), BP       
        tmp1.go:7       0x2070  4883c420                ADDQ $0x20, SP          
        tmp1.go:7       0x2074  c3                      RET                     

This is mostly due to https://go-review.googlesource.com/c/29373/ which inlines convT2E.
It won't handle all cases of conversions that end up being unused, but it handles this one.
The remaining stores you see here are temporaries which are unused but the compiler is not sure of that because their address is taken. This part is closely related to #13095 .

@randall77 randall77 added this to the Unplanned milestone Sep 23, 2016
@DmitriyMV
Copy link
Author

DmitriyMV commented Sep 24, 2016

Thanks @randall77 - yes, the current tip seems to be optimizing that. However if I change function signature from
func empty(_ interface{}, _ interface{}) {}
to
func empty(_ ...interface{}) {}

https://play.golang.org/p/KYp1jVhTvj

results become less appealing (compiled using current tip):

TEXT main.main(SB) C:/Dmitriy/Coding/Go/src/github.com/DmitriyMV/ssa_test/main.go
    main.go:5   0x401050    65488b0c2528000000  GS MOVQ GS:0x28, CX         
    main.go:5   0x401059    488b8900000000      MOVQ 0(CX), CX              
    main.go:5   0x401060    483b6110        CMPQ 0x10(CX), SP           
    main.go:5   0x401064    0f8615010000        JBE 0x40117f                
    main.go:5   0x40106a    4883ec48        SUBQ $0x48, SP              
    main.go:5   0x40106e    48896c2440      MOVQ BP, 0x40(SP)           
    main.go:5   0x401073    488d6c2440      LEAQ 0x40(SP), BP           
    main.go:6   0x401078    48c74424200a000000  MOVQ $0xa, 0x20(SP)         
    main.go:6   0x401081    488d05be4e0900      LEAQ 0x94ebe(IP), AX            
    main.go:6   0x401088    4889442430      MOVQ AX, 0x30(SP)           
    main.go:6   0x40108d    48c744243805000000  MOVQ $0x5, 0x38(SP)         
    main.go:6   0x401096    488d0523d30700      LEAQ 0x7d323(IP), AX            
    main.go:6   0x40109d    48890424        MOVQ AX, 0(SP)              
    main.go:6   0x4010a1    e88abc0000      CALL runtime.newobject(SB)      
    main.go:6   0x4010a6    488b442408      MOVQ 0x8(SP), AX            
    main.go:6   0x4010ab    4889442428      MOVQ AX, 0x28(SP)           
    main.go:6   0x4010b0    488d0da9b70700      LEAQ 0x7b7a9(IP), CX            
    main.go:6   0x4010b7    48890c24        MOVQ CX, 0(SP)              
    main.go:6   0x4010bb    488d4c2420      LEAQ 0x20(SP), CX           
    main.go:6   0x4010c0    48894c2408      MOVQ CX, 0x8(SP)            
    main.go:6   0x4010c5    e8c68e0000      CALL runtime.convT2E(SB)        
    main.go:6   0x4010ca    488b442418      MOVQ 0x18(SP), AX           
    main.go:6   0x4010cf    488b4c2410      MOVQ 0x10(SP), CX           
    main.go:6   0x4010d4    488b542428      MOVQ 0x28(SP), DX           
    main.go:6   0x4010d9    48890a          MOVQ CX, 0(DX)              
    main.go:6   0x4010dc    8b0dceb70f00        MOVL 0xfb7ce(IP), CX            
    main.go:6   0x4010e2    85c9            TESTL CX, CX                
    main.go:6   0x4010e4    757d            JNE 0x401163                
    main.go:6   0x4010e6    48894208        MOVQ AX, 0x8(DX)            
    main.go:6   0x4010ea    488d052fbc0700      LEAQ 0x7bc2f(IP), AX            
    main.go:6   0x4010f1    48890424        MOVQ AX, 0(SP)              
    main.go:6   0x4010f5    488d442430      LEAQ 0x30(SP), AX           
    main.go:6   0x4010fa    4889442408      MOVQ AX, 0x8(SP)            
    main.go:6   0x4010ff    e88c8e0000      CALL runtime.convT2E(SB)        
    main.go:6   0x401104    488b442418      MOVQ 0x18(SP), AX           
    main.go:6   0x401109    488b4c2410      MOVQ 0x10(SP), CX           
    main.go:6   0x40110e    488b542428      MOVQ 0x28(SP), DX           
    main.go:6   0x401113    48894a10        MOVQ CX, 0x10(DX)           
    main.go:6   0x401117    8b0d93b70f00        MOVL 0xfb793(IP), CX            
    main.go:6   0x40111d    85c9            TESTL CX, CX                
    main.go:6   0x40111f    7529            JNE 0x40114a                
    main.go:6   0x401121    48894218        MOVQ AX, 0x18(DX)           
    main.go:6   0x401125    48891424        MOVQ DX, 0(SP)              
    main.go:6   0x401129    48c744240802000000  MOVQ $0x2, 0x8(SP)          
    main.go:6   0x401132    48c744241002000000  MOVQ $0x2, 0x10(SP)         
    main.go:6   0x40113b    e800ffffff      CALL main.empty(SB)         
    main.go:7   0x401140    488b6c2440      MOVQ 0x40(SP), BP           
    main.go:7   0x401145    4883c448        ADDQ $0x48, SP              
    main.go:7   0x401149    c3          RET                 
    main.go:6   0x40114a    488d4a18        LEAQ 0x18(DX), CX           
    main.go:6   0x40114e    48890c24        MOVQ CX, 0(SP)              
    main.go:6   0x401152    4889442408      MOVQ AX, 0x8(SP)            
    main.go:6   0x401157    e824c50000      CALL runtime.writebarrierptr(SB)    
    main.go:6   0x40115c    488b542428      MOVQ 0x28(SP), DX           
    main.go:6   0x401161    ebc2            JMP 0x401125                
    main.go:6   0x401163    488d4a08        LEAQ 0x8(DX), CX            
    main.go:6   0x401167    48890c24        MOVQ CX, 0(SP)              
    main.go:6   0x40116b    4889442408      MOVQ AX, 0x8(SP)            
    main.go:6   0x401170    e80bc50000      CALL runtime.writebarrierptr(SB)    
    main.go:6   0x401175    488b542428      MOVQ 0x28(SP), DX           
    main.go:6   0x40117a    e96bffffff      JMP 0x4010ea                
    main.go:5   0x40117f    e8bcae0400      CALL runtime.morestack_noctxt(SB)   
    main.go:5   0x401184    e9c7feffff      JMP main.main(SB)           
    :-1     0x401189    cc          INT $0x3                
    :-1     0x40118a    cc          INT $0x3                
    :-1     0x40118b    cc          INT $0x3                
    :-1     0x40118c    cc          INT $0x3                
    :-1     0x40118d    cc          INT $0x3                
    :-1     0x40118e    cc          INT $0x3                
    :-1     0x40118f    cc          INT $0x3                

And there is also map[type]type case (also compiled using current tip):
https://play.golang.org/p/xfgG21QBeC

TEXT main.main(SB) C:/Dmitriy/Coding/Go/src/github.com/DmitriyMV/ssa_test/main.go
    main.go:5   0x401040    65488b0c2528000000  GS MOVQ GS:0x28, CX         
    main.go:5   0x401049    488b8900000000      MOVQ 0(CX), CX              
    main.go:5   0x401050    483b6110        CMPQ 0x10(CX), SP           
    main.go:5   0x401054    0f86ae000000        JBE 0x401108                
    main.go:5   0x40105a    4883ec40        SUBQ $0x40, SP              
    main.go:5   0x40105e    48896c2438      MOVQ BP, 0x38(SP)           
    main.go:5   0x401063    488d6c2438      LEAQ 0x38(SP), BP           
    main.go:6   0x401068    488d05d1060800      LEAQ 0x806d1(IP), AX            
    main.go:6   0x40106f    48890424        MOVQ AX, 0(SP)              
    main.go:6   0x401073    48c744240801000000  MOVQ $0x1, 0x8(SP)          
    main.go:6   0x40107c    48c744241000000000  MOVQ $0x0, 0x10(SP)         
    main.go:6   0x401085    48c744241800000000  MOVQ $0x0, 0x18(SP)         
    main.go:6   0x40108e    e82d580000      CALL runtime.makemap(SB)        
    main.go:6   0x401093    488b442420      MOVQ 0x20(SP), AX           
    main.go:6   0x401098    4889442430      MOVQ AX, 0x30(SP)           
    main.go:6   0x40109d    31c9            XORL CX, CX             
    main.go:6   0x40109f    48894c2428      MOVQ CX, 0x28(SP)           
    main.go:6   0x4010a4    4883f901        CMPQ $0x1, CX               
    main.go:6   0x4010a8    7d54            JGE 0x4010fe                
    main.go:6   0x4010aa    488d158f060800      LEAQ 0x8068f(IP), DX            
    main.go:6   0x4010b1    48891424        MOVQ DX, 0(SP)              
    main.go:6   0x4010b5    4889442408      MOVQ AX, 0x8(SP)            
    main.go:6   0x4010ba    4889cb          MOVQ CX, BX             
    main.go:6   0x4010bd    48c1e104        SHLQ $0x4, CX               
    main.go:6   0x4010c1    488d3538090a00      LEAQ 0xa0938(IP), SI            
    main.go:6   0x4010c8    488d3c0e        LEAQ 0(SI)(CX*1), DI            
    main.go:6   0x4010cc    48897c2410      MOVQ DI, 0x10(SP)           
    main.go:6   0x4010d1    488d3d38090a00      LEAQ 0xa0938(IP), DI            
    main.go:6   0x4010d8    4801f9          ADDQ DI, CX             
    main.go:6   0x4010db    48894c2418      MOVQ CX, 0x18(SP)           
    main.go:6   0x4010e0    e83b5f0000      CALL runtime.mapassign1(SB)     
    main.go:6   0x4010e5    488b442428      MOVQ 0x28(SP), AX           
    main.go:6   0x4010ea    488d4801        LEAQ 0x1(AX), CX            
    main.go:6   0x4010ee    488b442430      MOVQ 0x30(SP), AX           
    main.go:6   0x4010f3    48894c2428      MOVQ CX, 0x28(SP)           
    main.go:6   0x4010f8    4883f901        CMPQ $0x1, CX               
    main.go:6   0x4010fc    7cac            JL 0x4010aa             
    main.go:7   0x4010fe    488b6c2438      MOVQ 0x38(SP), BP           
    main.go:7   0x401103    4883c440        ADDQ $0x40, SP              
    main.go:7   0x401107    c3          RET                 
    main.go:5   0x401108    e873ad0400      CALL runtime.morestack_noctxt(SB)   
    main.go:5   0x40110d    e92effffff      JMP main.main(SB)           
    :-1     0x401112    cc          INT $0x3                
    :-1     0x401113    cc          INT $0x3                
    :-1     0x401114    cc          INT $0x3                
    :-1     0x401115    cc          INT $0x3                
    :-1     0x401116    cc          INT $0x3                
    :-1     0x401117    cc          INT $0x3                
    :-1     0x401118    cc          INT $0x3                
    :-1     0x401119    cc          INT $0x3                
    :-1     0x40111a    cc          INT $0x3                
    :-1     0x40111b    cc          INT $0x3                
    :-1     0x40111c    cc          INT $0x3                
    :-1     0x40111d    cc          INT $0x3                
    :-1     0x40111e    cc          INT $0x3                
    :-1     0x40111f    cc          INT $0x3        

As far as I could tell - map doesn't have any "side effects" with user code (it's not truly side effect free tho), so if map is unused, it's creation can be eliminated if no functions were called during map creation. Same goes for ...type.

Or am I missing something here? Should I open another issue, btw?

@randall77
Copy link
Contributor

No, we can use this one. I'll update the title to be more descriptive of the existing suboptimal code.

@randall77 randall77 changed the title cmd/compile: Dead code elimination and parameters of interface{} cmd/compile: elimination of unused runtime calls Sep 24, 2016
@thanm
Copy link
Contributor

thanm commented Sep 26, 2016

Looks as though gccgo "-O" has issues as well (deletes the call but not the allocations).

@randall77
Copy link
Contributor

The original repro is now fixed as of CL 38746.
@mundaym

This issue is now solely about eliminating runtime calls whose results are not used.

@DmitriyMV
Copy link
Author

This appears to be fixed on 1.16/1.17
This still generates unused map code/objects.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
binary-size compiler/runtime Issues related to the Go compiler and/or runtime. Performance
Projects
None yet
Development

No branches or pull requests

5 participants