Skip to content

Commit 4a7e363

Browse files
committed
cmd/compile: optimize Move with all-zero ro sym src to Zero
We set up static symbols during walk that we later make copies of to initialize local variables. It is difficult to ascertain at that time exactly when copying a symbol is profitable vs locally initializing an autotmp. During SSA, we are much better placed to optimize. This change recognizes when we are copying from a global readonly all-zero symbol and replaces it with direct zeroing. This often allows the all-zero symbol to be deadcode eliminated at link time. This is not ideal--it makes for large object files, and longer link times--but it is the cleanest fix I could find. This makes the final binary for the program in #38554 shrink from >500mb to ~2.2mb. It also shrinks the standard binaries: file before after Δ % addr2line 4412496 4404304 -8192 -0.186% buildid 2893816 2889720 -4096 -0.142% cgo 4841048 4832856 -8192 -0.169% compile 19926480 1992243 -4048 -0.020% cover 5281816 5277720 -4096 -0.078% link 6734648 6730552 -4096 -0.061% nm 4366240 4358048 -8192 -0.188% objdump 4755968 4747776 -8192 -0.172% pprof 14653060 14612100 -40960 -0.280% trace 11805940 1177726 -28672 -0.243% vet 7185560 7181416 -4144 -0.058% total 113588440 113465560 -122880 -0.108% And not just by removing unnecessary symbols; the program text shrinks a bit as well. Fixes #38554 Change-Id: I8381ae6084ae145a5e0cd9410c451e52c0dc51c8 Reviewed-on: https://go-review.googlesource.com/c/go/+/229704 Run-TryBot: Josh Bleecher Snyder <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent b3e8a00 commit 4a7e363

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

src/cmd/compile/internal/ssa/gen/generic.rules

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,6 +2020,7 @@
20202020
=> (Zero {t} [n] dst1 mem)
20212021
(Move {t} [n] dst1 src mem:(VarDef (Zero {t} [n] dst0 _))) && isSamePtr(src, dst0)
20222022
=> (Zero {t} [n] dst1 mem)
2023+
(Move {t} [n] dst (Addr {sym} (SB)) mem) && symIsROZero(sym) => (Zero {t} [n] dst mem)
20232024

20242025
// Don't Store to variables that are about to be overwritten by Move/Zero.
20252026
(Zero {t1} [n] p1 store:(Store {t2} (OffPtr [o2] p2) _ mem))

src/cmd/compile/internal/ssa/rewrite.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,20 @@ func symIsRO(sym interface{}) bool {
13811381
return lsym.Type == objabi.SRODATA && len(lsym.R) == 0
13821382
}
13831383

1384+
// symIsROZero reports whether sym is a read-only global whose data contains all zeros.
1385+
func symIsROZero(sym Sym) bool {
1386+
lsym := sym.(*obj.LSym)
1387+
if lsym.Type != objabi.SRODATA || len(lsym.R) != 0 {
1388+
return false
1389+
}
1390+
for _, b := range lsym.P {
1391+
if b != 0 {
1392+
return false
1393+
}
1394+
}
1395+
return true
1396+
}
1397+
13841398
// read8 reads one byte from the read-only global sym at offset off.
13851399
func read8(sym interface{}, off int64) uint8 {
13861400
lsym := sym.(*obj.LSym)

src/cmd/compile/internal/ssa/rewritegeneric.go

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/codegen/issue38554.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// asmcheck
2+
3+
// Copyright 2020 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
// Test that we are zeroing directly instead of
8+
// copying a large zero value. Issue 38554.
9+
10+
package codegen
11+
12+
func retlarge() [256]byte {
13+
// amd64:-"DUFFCOPY"
14+
return [256]byte{}
15+
}

0 commit comments

Comments
 (0)