DCE performed before inlining seems to eliminate the body of ifs where the condition can be proven to always evaluate to false, but fails to eliminate the if statement and the condition themselves. So, for example, the following code:
// code before if
if condition_known_to_be_false {
// code inside if
}
// code after if
that should be DCEd (before inlining) to:
// code before if
// (if statement has been completely removed)
// code after if
but currently DCE transforms it to:
// code before if
if condition_known_to_be_false { /* empty body */ }
// code after if
Found by going over the output of GO_GCFLAGS=-m ./make.bash (the following is just a sample, see #8421 (comment) for details):
src/math/bits/bits.go:283:6: can inline Len as: func(uint) int { if UintSize == 32 { }; return Len64(uint64(x)) }
src/runtime/cgocall.go:176:14: inlining call to dolockOSThread func() { if GOARCH == "wasm" { }; _g_ := getg(); _g_.m.lockedg.set(_g_); _g_.lockedm.set(_g_.m) }
src/runtime/stack.go:1277:24: inlining call to stackmapdata func(*stackmap, int32) bitvector { if stackDebug > 0 { }; return bitvector literal }
src/runtime/malloc.go:1105:6: can inline nextSample as: func() int32 { if GOOS == "plan9" { }; return fastexprand(MemProfileRate) }
src/go/token/position.go:452:15: inlining call to sync.(*RWMutex).RLock method(*sync.RWMutex) func() { if bool(false) { }; if atomic.AddInt32(&sync.rw.readerCount, int32(1)) < int32(0) { sync.runtime_SemacquireMutex(&sync.rw.readerSem, bool(false)) }; if bool(false) { } }
src/runtime/type.go:269:20: inlining call to reflectOffsUnlock func() { if raceenabled { }; unlock(&reflectOffs.lock) }
This is a problem because part of the inlining budget will be consumed by the vestigial ifs. If DCE before inlining completely removed those ifs more functions would likely become candidate for inlining.
Likely related to #23521 and possibly to #29095.
DCE performed before inlining seems to eliminate the body of
ifs where the condition can be proven to always evaluate tofalse, but fails to eliminate the if statement and the condition themselves. So, for example, the following code:that should be DCEd (before inlining) to:
but currently DCE transforms it to:
Found by going over the output of
GO_GCFLAGS=-m ./make.bash(the following is just a sample, see #8421 (comment) for details):src/math/bits/bits.go:283:6: can inline Len as: func(uint) int { if UintSize == 32 { }; return Len64(uint64(x)) } src/runtime/cgocall.go:176:14: inlining call to dolockOSThread func() { if GOARCH == "wasm" { }; _g_ := getg(); _g_.m.lockedg.set(_g_); _g_.lockedm.set(_g_.m) } src/runtime/stack.go:1277:24: inlining call to stackmapdata func(*stackmap, int32) bitvector { if stackDebug > 0 { }; return bitvector literal } src/runtime/malloc.go:1105:6: can inline nextSample as: func() int32 { if GOOS == "plan9" { }; return fastexprand(MemProfileRate) } src/go/token/position.go:452:15: inlining call to sync.(*RWMutex).RLock method(*sync.RWMutex) func() { if bool(false) { }; if atomic.AddInt32(&sync.rw.readerCount, int32(1)) < int32(0) { sync.runtime_SemacquireMutex(&sync.rw.readerSem, bool(false)) }; if bool(false) { } } src/runtime/type.go:269:20: inlining call to reflectOffsUnlock func() { if raceenabled { }; unlock(&reflectOffs.lock) }This is a problem because part of the inlining budget will be consumed by the vestigial
ifs. If DCE before inlining completely removed thoseifs more functions would likely become candidate for inlining.Likely related to #23521 and possibly to #29095.