mirror of
https://github.com/golang/go
synced 2024-09-06 00:19:45 +00:00
![]() [This is a roll-forward of CL 479095, which was reverted due to a bad interaction between inlining and escape analysis, then later fixed first with an attempt in CL 482355, then again in CL 484859, and then one more time with CL 492135.] Currently, when the inliner is determining if a function is inlineable, it descends into the bodies of closures constructed by that function. This has several unfortunate consequences: - If the closure contains a disallowed operation (e.g., a defer), then the outer function can't be inlined. It makes sense that the *closure* can't be inlined in this case, but it doesn't make sense to punish the function that constructs the closure. - The hairiness of the closure counts against the inlining budget of the outer function. Since we currently copy the closure body when inlining the outer function, this makes sense from the perspective of export data size and binary size, but ultimately doesn't make much sense from the perspective of what should be inlineable. - Since the inliner walks into every closure created by an outer function in addition to starting a walk at every closure, this adds an n^2 factor to inlinability analysis. This CL simply drops this behavior. In std, this makes 57 more functions inlinable, and disallows inlining for 10 (due to the basic instability of our bottom-up inlining approach), for an net increase of 47 inlinable functions (+0.6%). This will help significantly with the performance of the functions to be added for #56102, which have a somewhat complicated nesting of closures with a performance-critical fast path. The downside of this seems to be a potential increase in export data and text size, but the practical impact of this seems to be negligible: │ before │ after │ │ bytes │ bytes vs base │ Go/binary 15.12Mi ± 0% 15.14Mi ± 0% +0.16% (n=1) Go/text 5.220Mi ± 0% 5.237Mi ± 0% +0.32% (n=1) Compile/binary 22.92Mi ± 0% 22.94Mi ± 0% +0.07% (n=1) Compile/text 8.428Mi ± 0% 8.435Mi ± 0% +0.08% (n=1) Change-Id: I5f75fcceb177f05853996b75184a486528eafe96 Reviewed-on: https://go-review.googlesource.com/c/go/+/492017 Reviewed-by: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Than McIntosh <thanm@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> |
||
---|---|---|
.. | ||
abi | ||
alias3.dir | ||
asmhdr.dir | ||
bench | ||
chan | ||
closure3.dir | ||
closure5.dir | ||
codegen | ||
ddd2.dir | ||
dwarf | ||
fixedbugs | ||
import2.dir | ||
import4.dir | ||
interface | ||
intrinsic.dir | ||
ken | ||
linkname.dir | ||
method4.dir | ||
retjmp.dir | ||
runtime | ||
stress | ||
syntax | ||
typeparam | ||
uintptrescapes.dir | ||
64bit.go | ||
235.go | ||
alg.go | ||
alias.go | ||
alias1.go | ||
alias2.go | ||
alias3.go | ||
align.go | ||
append.go | ||
append1.go | ||
args.go | ||
armimm.go | ||
asmhdr.go | ||
assign.go | ||
assign1.go | ||
atomicload.go | ||
bigalg.go | ||
bigmap.go | ||
blank.go | ||
blank1.go | ||
bom.go | ||
bombad.go | ||
bounds.go | ||
cannotassign.go | ||
chancap.go | ||
chanlinear.go | ||
char_lit.go | ||
char_lit1.go | ||
checkbce.go | ||
clear.go | ||
clearfat.go | ||
closedchan.go | ||
closure.go | ||
closure1.go | ||
closure2.go | ||
closure3.go | ||
closure4.go | ||
closure5.go | ||
closure6.go | ||
closure7.go | ||
cmp.go | ||
cmp6.go | ||
cmplx.go | ||
cmplxdivide.c | ||
cmplxdivide.go | ||
cmplxdivide1.go | ||
complit.go | ||
complit1.go | ||
compos.go | ||
const.go | ||
const1.go | ||
const2.go | ||
const3.go | ||
const4.go | ||
const5.go | ||
const6.go | ||
const7.go | ||
const8.go | ||
convert.go | ||
convert1.go | ||
convert2.go | ||
convert3.go | ||
convert4.go | ||
convinline.go | ||
convlit.go | ||
convlit1.go | ||
convT2X.go | ||
copy.go | ||
copy1.go | ||
crlf.go | ||
ddd.go | ||
ddd1.go | ||
ddd2.go | ||
decl.go | ||
declbad.go | ||
defer.go | ||
defererrcheck.go | ||
deferfin.go | ||
defernil.go | ||
deferprint.go | ||
deferprint.out | ||
devirt.go | ||
directive.go | ||
directive2.go | ||
divide.go | ||
divmod.go | ||
embedfunc.go | ||
embedvers.go | ||
empty.go | ||
env.go | ||
eof.go | ||
eof1.go | ||
escape.go | ||
escape2.go | ||
escape2n.go | ||
escape3.go | ||
escape4.go | ||
escape5.go | ||
escape_array.go | ||
escape_calls.go | ||
escape_closure.go | ||
escape_field.go | ||
escape_goto.go | ||
escape_hash_maphash.go | ||
escape_iface.go | ||
escape_iface_unified.go | ||
escape_indir.go | ||
escape_level.go | ||
escape_map.go | ||
escape_param.go | ||
escape_runtime_atomic.go | ||
escape_selfassign.go | ||
escape_slice.go | ||
escape_struct_param1.go | ||
escape_struct_param2.go | ||
escape_struct_return.go | ||
escape_sync_atomic.go | ||
escape_unsafe.go | ||
fibo.go | ||
finprofiled.go | ||
float_lit.go | ||
float_lit2.go | ||
float_lit3.go | ||
floatcmp.go | ||
for.go | ||
func.go | ||
func1.go | ||
func2.go | ||
func3.go | ||
func4.go | ||
func5.go | ||
func6.go | ||
func7.go | ||
func8.go | ||
funcdup.go | ||
funcdup2.go | ||
fuse.go | ||
gc.go | ||
gc1.go | ||
gc2.go | ||
gcgort.go | ||
gcstring.go | ||
goprint.go | ||
goprint.out | ||
goto.go | ||
heapsampling.go | ||
helloworld.go | ||
helloworld.out | ||
if.go | ||
import.go | ||
import1.go | ||
import2.go | ||
import4.go | ||
import5.go | ||
import6.go | ||
index.go | ||
index0.go | ||
index1.go | ||
index2.go | ||
indirect.go | ||
indirect1.go | ||
init.go | ||
init1.go | ||
initcomma.go | ||
initexp.go | ||
initialize.go | ||
initializerr.go | ||
initloop.go | ||
inline.go | ||
inline_big.go | ||
inline_caller.go | ||
inline_callers.go | ||
inline_endian.go | ||
inline_literal.go | ||
inline_math_bits_rotate.go | ||
inline_sync.go | ||
inline_unified.go | ||
inline_variadic.go | ||
int_lit.go | ||
intcvt.go | ||
intrinsic.go | ||
intrinsic_atomic.go | ||
iota.go | ||
label.go | ||
label1.go | ||
linkmain.go | ||
linkmain_run.go | ||
linkname.go | ||
linkname3.go | ||
linkobj.go | ||
linkx.go | ||
linkx_run.go | ||
literal.go | ||
literal2.go | ||
live.go | ||
live1.go | ||
live2.go | ||
live_regabi.go | ||
live_uintptrkeepalive.go | ||
loopbce.go | ||
mainsig.go | ||
makechan.go | ||
makemap.go | ||
makenew.go | ||
makeslice.go | ||
mallocfin.go | ||
map.go | ||
map1.go | ||
mapclear.go | ||
maplinear.go | ||
maymorestack.go | ||
mergemul.go | ||
method.go | ||
method1.go | ||
method2.go | ||
method3.go | ||
method4.go | ||
method5.go | ||
method6.go | ||
method7.go | ||
named.go | ||
named1.go | ||
nil.go | ||
nilcheck.go | ||
nilptr.go | ||
nilptr2.go | ||
nilptr3.go | ||
nilptr4.go | ||
nilptr5.go | ||
nilptr5_aix.go | ||
nilptr5_wasm.go | ||
nilptr_aix.go | ||
noinit.go | ||
nosplit.go | ||
nowritebarrier.go | ||
nul1.go | ||
opt_branchlikely.go | ||
parentype.go | ||
peano.go | ||
phiopt.go | ||
print.go | ||
print.out | ||
printbig.go | ||
printbig.out | ||
prove.go | ||
prove_constant_folding.go | ||
range.go | ||
README.md | ||
recover.go | ||
recover1.go | ||
recover2.go | ||
recover3.go | ||
recover4.go | ||
recover5.go | ||
reflectmethod1.go | ||
reflectmethod2.go | ||
reflectmethod3.go | ||
reflectmethod4.go | ||
reflectmethod5.go | ||
reflectmethod6.go | ||
reflectmethod7.go | ||
reflectmethod8.go | ||
rename.go | ||
rename1.go | ||
reorder.go | ||
reorder2.go | ||
retjmp.go | ||
return.go | ||
rotate.go | ||
rotate0.go | ||
rotate1.go | ||
rotate2.go | ||
rotate3.go | ||
rune.go | ||
runtime.go | ||
shift1.go | ||
shift2.go | ||
shift3.go | ||
sieve.go | ||
sigchld.go | ||
sigchld.out | ||
simassign.go | ||
sizeof.go | ||
slice3.go | ||
slice3err.go | ||
slicecap.go | ||
sliceopt.go | ||
solitaire.go | ||
stack.go | ||
stackobj.go | ||
stackobj2.go | ||
stackobj3.go | ||
strcopy.go | ||
strength.go | ||
string_lit.go | ||
stringrange.go | ||
struct0.go | ||
switch.go | ||
switch2.go | ||
switch3.go | ||
switch4.go | ||
switch5.go | ||
switch6.go | ||
switch7.go | ||
tinyfin.go | ||
torture.go | ||
turing.go | ||
typecheck.go | ||
typecheckloop.go | ||
typeswitch.go | ||
typeswitch1.go | ||
typeswitch2.go | ||
typeswitch2b.go | ||
typeswitch3.go | ||
uintptrescapes.go | ||
uintptrescapes2.go | ||
uintptrescapes3.go | ||
uintptrkeepalive.go | ||
undef.go | ||
unsafe_slice_data.go | ||
unsafe_string.go | ||
unsafe_string_data.go | ||
unsafebuiltins.go | ||
used.go | ||
utf.go | ||
varerr.go | ||
varinit.go | ||
winbatch.go | ||
writebarrier.go | ||
zerodivide.go | ||
zerosize.go |
The test directory contains tests of the Go tool chain and runtime. It includes black box tests, regression tests, and error output tests. They are run as part of all.bash.
To run just these tests, execute:
../bin/go test internal/testdir
To run just tests from specified files in this directory, execute:
../bin/go test internal/testdir -run='Test/(file1.go|file2.go|...)'
Standard library tests should be written as regular Go tests in the appropriate package.
The tool chain and runtime also have regular Go tests in their packages. The main reasons to add a new test to this directory are:
- it is most naturally expressed using the test runner; or
- it is also applicable to
gccgo
and other Go tool chains.