mirror of
https://github.com/golang/go
synced 2024-11-02 13:21:55 +00:00
ed7a8332c4
We still disallow inlining for an immediately-recursive function, but allow inlining if a function is in a recursion chain. If all functions in the recursion chain are simple, then we could inline forever down the recursion chain (eventually running out of stack on the compiler), so we add a map to keep track of the functions we have already inlined at a call site. We stop inlining when we reach a function that we have already inlined in the recursive chain. Of course, normally the inlining will have stopped earlier, because of the cost function. We could also limit the depth of inlining by a simple count (say, limit max inlining of 10 at any given site). Would that limit other opportunities too much? Added a test in test/inline.go. runtime.BenchmarkStackCopyNoCache() is also already a good test that triggers the check to stop inlining when we reach the start of the recursive chain again. For the bent benchmark suite, the performance improvement was mostly not statistically significant, but the geomean averaged out to: -0.68%. The text size increase was less than .1% for all bent benchmarks. The cmd/go text size increase was 0.02% and the cmd/compile text size increase was .1%. Fixes #29737 Change-Id: I892fa84bb07a947b3125ec8f25ed0e508bf2bdf5 Reviewed-on: https://go-review.googlesource.com/c/go/+/226818 Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> |
||
---|---|---|
.. | ||
alias3.dir | ||
bench | ||
chan | ||
closure3.dir | ||
codegen | ||
ddd2.dir | ||
dwarf | ||
fixedbugs | ||
import2.dir | ||
import4.dir | ||
interface | ||
intrinsic.dir | ||
ken | ||
linkname.dir | ||
method4.dir | ||
oldescape_linkname.dir | ||
retjmp.dir | ||
runtime | ||
stress | ||
syntax | ||
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 | ||
assign.go | ||
assign1.go | ||
atomicload.go | ||
bigalg.go | ||
bigmap.go | ||
blank.go | ||
blank1.go | ||
bom.go | ||
bombad.go | ||
bounds.go | ||
chancap.go | ||
chanlinear.go | ||
char_lit.go | ||
char_lit1.go | ||
checkbce.go | ||
clearfat.go | ||
closedchan.go | ||
closure.go | ||
closure1.go | ||
closure2.go | ||
closure3.go | ||
closure4.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 | ||
convert.go | ||
convert1.go | ||
convert2.go | ||
convert3.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 | ||
divide.go | ||
divmod.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_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 | ||
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 | ||
initempty.go | ||
initialize.go | ||
initializerr.go | ||
initloop.go | ||
inline.go | ||
inline_big.go | ||
inline_caller.go | ||
inline_callers.go | ||
inline_literal.go | ||
inline_math_bits_rotate.go | ||
inline_sync.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 | ||
linkobj.go | ||
linkx.go | ||
linkx_run.go | ||
literal.go | ||
literal2.go | ||
live.go | ||
live1.go | ||
live2.go | ||
live_syscall.go | ||
locklinear.go | ||
loopbce.go | ||
makechan.go | ||
makemap.go | ||
makenew.go | ||
mallocfin.go | ||
map.go | ||
map1.go | ||
mapclear.go | ||
maplinear.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 | ||
nosplit.go | ||
notinheap.go | ||
notinheap2.go | ||
notinheap3.go | ||
nowritebarrier.go | ||
nul1.go | ||
opt_branchlikely.go | ||
parentype.go | ||
peano.go | ||
phiopt.go | ||
print.go | ||
print.out | ||
printbig.go | ||
printbig.out | ||
prove.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 | ||
rename.go | ||
rename1.go | ||
reorder.go | ||
reorder2.go | ||
retjmp.go | ||
return.go | ||
rotate.go | ||
rotate0.go | ||
rotate1.go | ||
rotate2.go | ||
rotate3.go | ||
run.go | ||
rune.go | ||
runtime.go | ||
shift1.go | ||
shift2.go | ||
sieve.go | ||
sigchld.go | ||
sigchld.out | ||
simassign.go | ||
sinit.go | ||
sinit_run.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 | ||
undef.go | ||
utf.go | ||
varerr.go | ||
varinit.go | ||
winbatch.go | ||
writebarrier.go | ||
zerodivide.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 run run.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.