Initial commit: Go 1.23 release state
This commit is contained in:
45
src/cmd/compile/internal/inline/inlheur/testdata/dumpscores.go
vendored
Normal file
45
src/cmd/compile/internal/inline/inlheur/testdata/dumpscores.go
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package dumpscores
|
||||
|
||||
var G int
|
||||
|
||||
func inlinable(x int, f func(int) int) int {
|
||||
if x != 0 {
|
||||
return 1
|
||||
}
|
||||
G += noninl(x)
|
||||
return f(x)
|
||||
}
|
||||
|
||||
func inlinable2(x int) int {
|
||||
return noninl(-x)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func noninl(x int) int {
|
||||
return x + 1
|
||||
}
|
||||
|
||||
func tooLargeToInline(x int) int {
|
||||
if x > 101 {
|
||||
// Drive up the cost of inlining this func over the
|
||||
// regular threshold.
|
||||
return big(big(big(big(big(G + x)))))
|
||||
}
|
||||
if x < 100 {
|
||||
// make sure this callsite is scored properly
|
||||
G += inlinable(101, inlinable2)
|
||||
if G == 101 {
|
||||
return 0
|
||||
}
|
||||
panic(inlinable2(3))
|
||||
}
|
||||
return G
|
||||
}
|
||||
|
||||
func big(q int) int {
|
||||
return noninl(q) + noninl(-q)
|
||||
}
|
||||
77
src/cmd/compile/internal/inline/inlheur/testdata/props/README.txt
vendored
Normal file
77
src/cmd/compile/internal/inline/inlheur/testdata/props/README.txt
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
Notes on the format of the testcase files in
|
||||
cmd/compile/internal/inline/inlheur/testdata/props:
|
||||
|
||||
- each (compilable) file contains input Go code and expected results
|
||||
in the form of column-0 comments.
|
||||
|
||||
- functions or methods that begin with "T_" are targeted for testing,
|
||||
as well as "init" functions; all other functions are ignored.
|
||||
|
||||
- function header comments begin with a line containing
|
||||
the file name, function name, definition line, then index
|
||||
and a count of the number of funcs that share that same
|
||||
definition line (needed to support generics). Example:
|
||||
|
||||
// foo.go T_mumble 35 1 4
|
||||
|
||||
Here "T_mumble" is defined at line 35, and it is func 0
|
||||
out of the 4 funcs that share that same line.
|
||||
|
||||
- function property expected results appear as comments in immediately
|
||||
prior to the function. For example, here we have first the function
|
||||
name ("T_feeds_if_simple"), then human-readable dump of the function
|
||||
properties, as well as the JSON for the properties object, each
|
||||
section separated by a "<>" delimiter.
|
||||
|
||||
// params.go T_feeds_if_simple 35 0 1
|
||||
// RecvrParamFlags:
|
||||
// 0: ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"RecvrParamFlags":[8],"ReturnFlags":[]}
|
||||
// callsite: params.go:34:10|0 "CallSiteOnPanicPath" 2
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_simple(x int) {
|
||||
if x < 100 {
|
||||
os.Exit(1)
|
||||
}
|
||||
println(x)
|
||||
}
|
||||
|
||||
- when the test runs, it will compile the Go source file with an
|
||||
option to dump out function properties, then compare the new dump
|
||||
for each function with the JSON appearing in the header comment for
|
||||
the function (in the example above, the JSON appears between
|
||||
"<endpropsdump>" and "<endfuncpreamble>". The material prior to the
|
||||
dump is simply there for human consumption, so that a developer can
|
||||
easily see that "RecvrParamFlags":[8] means that the first parameter
|
||||
has flag ParamFeedsIfOrSwitch.
|
||||
|
||||
- when making changes to the compiler (which can alter the expected
|
||||
results) or edits/additions to the go code in the testcase files,
|
||||
you can remaster the results by running
|
||||
|
||||
go test -v -count=1 .
|
||||
|
||||
In the trace output of this run, you'll see messages of the form
|
||||
|
||||
=== RUN TestFuncProperties
|
||||
funcprops_test.go:NNN: update-expected: emitted updated file
|
||||
testdata/props/XYZ.go.new
|
||||
funcprops_test.go:MMM: please compare the two files, then overwrite
|
||||
testdata/props/XYZ.go with testdata/props/XYZ.go.new
|
||||
|
||||
at which point you can compare the old and new files by hand, then
|
||||
overwrite the *.go file with the *.go.new file if you are happy with
|
||||
the diffs.
|
||||
|
||||
- note that the remastering process will strip out any existing
|
||||
column-0 (unindented) comments; if you write comments that you
|
||||
want to see preserved, use "/* */" or indent them.
|
||||
|
||||
|
||||
|
||||
214
src/cmd/compile/internal/inline/inlheur/testdata/props/acrosscall.go
vendored
Normal file
214
src/cmd/compile/internal/inline/inlheur/testdata/props/acrosscall.go
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// DO NOT EDIT (use 'go test -v -update-expected' instead.)
|
||||
// See cmd/compile/internal/inline/inlheur/testdata/props/README.txt
|
||||
// for more information on the format of this file.
|
||||
// <endfilepreamble>
|
||||
package params
|
||||
|
||||
// acrosscall.go T_feeds_indirect_call_via_call_toplevel 19 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIndirectCall
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[8],"ResultFlags":null}
|
||||
// callsite: acrosscall.go:20:12|0 flagstr "" flagval 0 score 60 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_indirect_call_via_call_toplevel(f func(int)) {
|
||||
callsparam(f)
|
||||
}
|
||||
|
||||
// acrosscall.go T_feeds_indirect_call_via_call_conditional 31 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamMayFeedIndirectCall
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[16],"ResultFlags":null}
|
||||
// callsite: acrosscall.go:33:13|0 flagstr "" flagval 0 score 60 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_indirect_call_via_call_conditional(f func(int)) {
|
||||
if G != 101 {
|
||||
callsparam(f)
|
||||
}
|
||||
}
|
||||
|
||||
// acrosscall.go T_feeds_conditional_indirect_call_via_call_toplevel 45 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamMayFeedIndirectCall
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[16],"ResultFlags":null}
|
||||
// callsite: acrosscall.go:46:23|0 flagstr "" flagval 0 score 64 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_conditional_indirect_call_via_call_toplevel(f func(int)) {
|
||||
callsparamconditional(f)
|
||||
}
|
||||
|
||||
// acrosscall.go T_feeds_if_via_call 57 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
|
||||
// callsite: acrosscall.go:58:9|0 flagstr "" flagval 0 score 8 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_via_call(x int) {
|
||||
feedsif(x)
|
||||
}
|
||||
|
||||
// acrosscall.go T_feeds_if_via_call_conditional 69 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamMayFeedIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[64],"ResultFlags":null}
|
||||
// callsite: acrosscall.go:71:10|0 flagstr "" flagval 0 score 8 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_via_call_conditional(x int) {
|
||||
if G != 101 {
|
||||
feedsif(x)
|
||||
}
|
||||
}
|
||||
|
||||
// acrosscall.go T_feeds_conditional_if_via_call 83 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamMayFeedIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[64],"ResultFlags":null}
|
||||
// callsite: acrosscall.go:84:20|0 flagstr "" flagval 0 score 12 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_conditional_if_via_call(x int) {
|
||||
feedsifconditional(x)
|
||||
}
|
||||
|
||||
// acrosscall.go T_multifeeds1 97 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIndirectCall|ParamMayFeedIndirectCall
|
||||
// 1 ParamNoInfo
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[24,0],"ResultFlags":null}
|
||||
// callsite: acrosscall.go:98:12|0 flagstr "" flagval 0 score 60 mask 0 maskstr ""
|
||||
// callsite: acrosscall.go:99:23|1 flagstr "" flagval 0 score 64 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_multifeeds1(f1, f2 func(int)) {
|
||||
callsparam(f1)
|
||||
callsparamconditional(f1)
|
||||
}
|
||||
|
||||
// acrosscall.go T_acrosscall_returnsconstant 110 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultAlwaysSameConstant
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":null,"ResultFlags":[8]}
|
||||
// callsite: acrosscall.go:111:24|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_acrosscall_returnsconstant() int {
|
||||
return returnsconstant()
|
||||
}
|
||||
|
||||
// acrosscall.go T_acrosscall_returnsmem 122 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultIsAllocatedMem
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":null,"ResultFlags":[2]}
|
||||
// callsite: acrosscall.go:123:19|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_acrosscall_returnsmem() *int {
|
||||
return returnsmem()
|
||||
}
|
||||
|
||||
// acrosscall.go T_acrosscall_returnscci 134 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultIsConcreteTypeConvertedToInterface
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":null,"ResultFlags":[4]}
|
||||
// callsite: acrosscall.go:135:19|0 flagstr "" flagval 0 score 7 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_acrosscall_returnscci() I {
|
||||
return returnscci()
|
||||
}
|
||||
|
||||
// acrosscall.go T_acrosscall_multiret 144 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
|
||||
// callsite: acrosscall.go:146:25|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_acrosscall_multiret(q int) int {
|
||||
if q != G {
|
||||
return returnsconstant()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// acrosscall.go T_acrosscall_multiret2 158 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
|
||||
// callsite: acrosscall.go:160:25|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
|
||||
// callsite: acrosscall.go:162:25|1 flagstr "" flagval 0 score 2 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_acrosscall_multiret2(q int) int {
|
||||
if q == G {
|
||||
return returnsconstant()
|
||||
} else {
|
||||
return returnsconstant()
|
||||
}
|
||||
}
|
||||
|
||||
func callsparam(f func(int)) {
|
||||
f(2)
|
||||
}
|
||||
|
||||
func callsparamconditional(f func(int)) {
|
||||
if G != 101 {
|
||||
f(2)
|
||||
}
|
||||
}
|
||||
|
||||
func feedsif(x int) int {
|
||||
if x != 101 {
|
||||
return 42
|
||||
}
|
||||
return 43
|
||||
}
|
||||
|
||||
func feedsifconditional(x int) int {
|
||||
if G != 101 {
|
||||
if x != 101 {
|
||||
return 42
|
||||
}
|
||||
}
|
||||
return 43
|
||||
}
|
||||
|
||||
func returnsconstant() int {
|
||||
return 42
|
||||
}
|
||||
|
||||
func returnsmem() *int {
|
||||
return new(int)
|
||||
}
|
||||
|
||||
func returnscci() I {
|
||||
var q Q
|
||||
return q
|
||||
}
|
||||
|
||||
type I interface {
|
||||
Foo()
|
||||
}
|
||||
|
||||
type Q int
|
||||
|
||||
func (q Q) Foo() {
|
||||
}
|
||||
|
||||
var G int
|
||||
240
src/cmd/compile/internal/inline/inlheur/testdata/props/calls.go
vendored
Normal file
240
src/cmd/compile/internal/inline/inlheur/testdata/props/calls.go
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// DO NOT EDIT (use 'go test -v -update-expected' instead.)
|
||||
// See cmd/compile/internal/inline/inlheur/testdata/props/README.txt
|
||||
// for more information on the format of this file.
|
||||
// <endfilepreamble>
|
||||
package calls
|
||||
|
||||
import "os"
|
||||
|
||||
// calls.go T_call_in_panic_arg 19 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// callsite: calls.go:21:15|0 flagstr "CallSiteOnPanicPath" flagval 2 score 42 mask 1 maskstr "panicPathAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_call_in_panic_arg(x int) {
|
||||
if x < G {
|
||||
panic(callee(x))
|
||||
}
|
||||
}
|
||||
|
||||
// calls.go T_calls_in_loops 32 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
|
||||
// callsite: calls.go:34:9|0 flagstr "CallSiteInLoop" flagval 1 score -3 mask 4 maskstr "inLoopAdj"
|
||||
// callsite: calls.go:37:9|1 flagstr "CallSiteInLoop" flagval 1 score -3 mask 4 maskstr "inLoopAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_calls_in_loops(x int, q []string) {
|
||||
for i := 0; i < x; i++ {
|
||||
callee(i)
|
||||
}
|
||||
for _, s := range q {
|
||||
callee(len(s))
|
||||
}
|
||||
}
|
||||
|
||||
// calls.go T_calls_in_pseudo_loop 48 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
|
||||
// callsite: calls.go:50:9|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
|
||||
// callsite: calls.go:54:9|1 flagstr "" flagval 0 score 2 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_calls_in_pseudo_loop(x int, q []string) {
|
||||
for i := 0; i < x; i++ {
|
||||
callee(i)
|
||||
return
|
||||
}
|
||||
for _, s := range q {
|
||||
callee(len(s))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// calls.go T_calls_on_panic_paths 67 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
|
||||
// callsite: calls.go:69:9|0 flagstr "CallSiteOnPanicPath" flagval 2 score 42 mask 1 maskstr "panicPathAdj"
|
||||
// callsite: calls.go:73:9|1 flagstr "CallSiteOnPanicPath" flagval 2 score 42 mask 1 maskstr "panicPathAdj"
|
||||
// callsite: calls.go:77:12|2 flagstr "CallSiteOnPanicPath" flagval 2 score 102 mask 1 maskstr "panicPathAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_calls_on_panic_paths(x int, q []string) {
|
||||
if x+G == 101 {
|
||||
callee(x)
|
||||
panic("ouch")
|
||||
}
|
||||
if x < G-101 {
|
||||
callee(x)
|
||||
if len(q) == 0 {
|
||||
G++
|
||||
}
|
||||
callsexit(x)
|
||||
}
|
||||
}
|
||||
|
||||
// calls.go T_calls_not_on_panic_paths 93 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch|ParamMayFeedIfOrSwitch
|
||||
// 1 ParamNoInfo
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[96,0],"ResultFlags":null}
|
||||
// callsite: calls.go:103:9|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
|
||||
// callsite: calls.go:112:9|1 flagstr "" flagval 0 score 2 mask 0 maskstr ""
|
||||
// callsite: calls.go:115:9|2 flagstr "" flagval 0 score 2 mask 0 maskstr ""
|
||||
// callsite: calls.go:119:12|3 flagstr "CallSiteOnPanicPath" flagval 2 score 102 mask 1 maskstr "panicPathAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_calls_not_on_panic_paths(x int, q []string) {
|
||||
if x != G {
|
||||
panic("ouch")
|
||||
/* Notes: */
|
||||
/* - we only look for post-dominating panic/exit, so */
|
||||
/* this site will on fact not have a panicpath flag */
|
||||
/* - vet will complain about this site as unreachable */
|
||||
callee(x)
|
||||
}
|
||||
if x != G {
|
||||
callee(x)
|
||||
if x < 100 {
|
||||
panic("ouch")
|
||||
}
|
||||
}
|
||||
if x+G == 101 {
|
||||
if x < 100 {
|
||||
panic("ouch")
|
||||
}
|
||||
callee(x)
|
||||
}
|
||||
if x < -101 {
|
||||
callee(x)
|
||||
if len(q) == 0 {
|
||||
return
|
||||
}
|
||||
callsexit(x)
|
||||
}
|
||||
}
|
||||
|
||||
// calls.go init.0 129 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":null,"ResultFlags":null}
|
||||
// callsite: calls.go:130:16|0 flagstr "CallSiteInInitFunc" flagval 4 score 22 mask 2 maskstr "initFuncAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func init() {
|
||||
println(callee(5))
|
||||
}
|
||||
|
||||
// calls.go T_pass_inlinable_func_to_param_feeding_indirect_call 140 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
|
||||
// callsite: calls.go:141:19|0 flagstr "" flagval 0 score 16 mask 512 maskstr "passInlinableFuncToIndCallAdj"
|
||||
// callsite: calls.go:141:19|calls.go:232:10|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_pass_inlinable_func_to_param_feeding_indirect_call(x int) int {
|
||||
return callsParam(x, callee)
|
||||
}
|
||||
|
||||
// calls.go T_pass_noninlinable_func_to_param_feeding_indirect_call 150 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
|
||||
// callsite: calls.go:153:19|0 flagstr "" flagval 0 score 36 mask 128 maskstr "passFuncToIndCallAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_pass_noninlinable_func_to_param_feeding_indirect_call(x int) int {
|
||||
// if we inline callsParam we can convert the indirect call
|
||||
// to a direct call, but we can't inline it.
|
||||
return callsParam(x, calleeNoInline)
|
||||
}
|
||||
|
||||
// calls.go T_pass_inlinable_func_to_param_feeding_nested_indirect_call 165 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[0]}
|
||||
// callsite: calls.go:166:25|0 flagstr "" flagval 0 score 27 mask 1024 maskstr "passInlinableFuncToNestedIndCallAdj"
|
||||
// callsite: calls.go:166:25|calls.go:237:11|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_pass_inlinable_func_to_param_feeding_nested_indirect_call(x int) int {
|
||||
return callsParamNested(x, callee)
|
||||
}
|
||||
|
||||
// calls.go T_pass_noninlinable_func_to_param_feeding_nested_indirect_call 177 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[0]}
|
||||
// callsite: calls.go:178:25|0 flagstr "" flagval 0 score 47 mask 256 maskstr "passFuncToNestedIndCallAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_pass_noninlinable_func_to_param_feeding_nested_indirect_call(x int) int {
|
||||
return callsParamNested(x, calleeNoInline)
|
||||
}
|
||||
|
||||
// calls.go T_call_scoring_in_noninlinable_func 195 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[0]}
|
||||
// callsite: calls.go:209:14|0 flagstr "CallSiteOnPanicPath" flagval 2 score 42 mask 1 maskstr "panicPathAdj"
|
||||
// callsite: calls.go:210:15|1 flagstr "CallSiteOnPanicPath" flagval 2 score 42 mask 1 maskstr "panicPathAdj"
|
||||
// callsite: calls.go:212:19|2 flagstr "" flagval 0 score 16 mask 512 maskstr "passInlinableFuncToIndCallAdj"
|
||||
// callsite: calls.go:212:19|calls.go:232:10|0 flagstr "" flagval 0 score 4 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
// calls.go T_call_scoring_in_noninlinable_func.func1 212 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_call_scoring_in_noninlinable_func(x int, sl []int) int {
|
||||
if x == 101 {
|
||||
// Drive up the cost of inlining this funcfunc over the
|
||||
// regular threshold.
|
||||
for i := 0; i < 10; i++ {
|
||||
for j := 0; j < i; j++ {
|
||||
sl = append(sl, append(sl, append(sl, append(sl, x)...)...)...)
|
||||
sl = append(sl, sl[0], sl[1], sl[2])
|
||||
x += calleeNoInline(x)
|
||||
}
|
||||
}
|
||||
}
|
||||
if x < 100 {
|
||||
// make sure this callsite is scored properly
|
||||
G += callee(101)
|
||||
panic(callee(x))
|
||||
}
|
||||
return callsParam(x, func(y int) int { return y + x })
|
||||
}
|
||||
|
||||
var G int
|
||||
|
||||
func callee(x int) int {
|
||||
return x
|
||||
}
|
||||
|
||||
func calleeNoInline(x int) int {
|
||||
defer func() { G++ }()
|
||||
return x
|
||||
}
|
||||
|
||||
func callsexit(x int) {
|
||||
println(x)
|
||||
os.Exit(x)
|
||||
}
|
||||
|
||||
func callsParam(x int, f func(int) int) int {
|
||||
return f(x)
|
||||
}
|
||||
|
||||
func callsParamNested(x int, f func(int) int) int {
|
||||
if x < 0 {
|
||||
return f(x)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
341
src/cmd/compile/internal/inline/inlheur/testdata/props/funcflags.go
vendored
Normal file
341
src/cmd/compile/internal/inline/inlheur/testdata/props/funcflags.go
vendored
Normal file
@@ -0,0 +1,341 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// DO NOT EDIT (use 'go test -v -update-expected' instead.)
|
||||
// See cmd/compile/internal/inline/inlheur/testdata/props/README.txt
|
||||
// for more information on the format of this file.
|
||||
// <endfilepreamble>
|
||||
|
||||
package funcflags
|
||||
|
||||
import "os"
|
||||
|
||||
// funcflags.go T_simple 20 0 1
|
||||
// Flags FuncPropNeverReturns
|
||||
// <endpropsdump>
|
||||
// {"Flags":1,"ParamFlags":null,"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_simple() {
|
||||
panic("bad")
|
||||
}
|
||||
|
||||
// funcflags.go T_nested 32 0 1
|
||||
// Flags FuncPropNeverReturns
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":1,"ParamFlags":[32],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_nested(x int) {
|
||||
if x < 10 {
|
||||
panic("bad")
|
||||
} else {
|
||||
panic("good")
|
||||
}
|
||||
}
|
||||
|
||||
// funcflags.go T_block1 46 0 1
|
||||
// Flags FuncPropNeverReturns
|
||||
// <endpropsdump>
|
||||
// {"Flags":1,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_block1(x int) {
|
||||
panic("bad")
|
||||
if x < 10 {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// funcflags.go T_block2 60 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_block2(x int) {
|
||||
if x < 10 {
|
||||
return
|
||||
}
|
||||
panic("bad")
|
||||
}
|
||||
|
||||
// funcflags.go T_switches1 75 0 1
|
||||
// Flags FuncPropNeverReturns
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":1,"ParamFlags":[32],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_switches1(x int) {
|
||||
switch x {
|
||||
case 1:
|
||||
panic("one")
|
||||
case 2:
|
||||
panic("two")
|
||||
}
|
||||
panic("whatev")
|
||||
}
|
||||
|
||||
// funcflags.go T_switches1a 92 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_switches1a(x int) {
|
||||
switch x {
|
||||
case 2:
|
||||
panic("two")
|
||||
}
|
||||
}
|
||||
|
||||
// funcflags.go T_switches2 106 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_switches2(x int) {
|
||||
switch x {
|
||||
case 1:
|
||||
panic("one")
|
||||
case 2:
|
||||
panic("two")
|
||||
default:
|
||||
return
|
||||
}
|
||||
panic("whatev")
|
||||
}
|
||||
|
||||
// funcflags.go T_switches3 123 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_switches3(x interface{}) {
|
||||
switch x.(type) {
|
||||
case bool:
|
||||
panic("one")
|
||||
case float32:
|
||||
panic("two")
|
||||
}
|
||||
}
|
||||
|
||||
// funcflags.go T_switches4 138 0 1
|
||||
// Flags FuncPropNeverReturns
|
||||
// <endpropsdump>
|
||||
// {"Flags":1,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_switches4(x int) {
|
||||
switch x {
|
||||
case 1:
|
||||
x++
|
||||
fallthrough
|
||||
case 2:
|
||||
panic("two")
|
||||
fallthrough
|
||||
default:
|
||||
panic("bad")
|
||||
}
|
||||
panic("whatev")
|
||||
}
|
||||
|
||||
// funcflags.go T_recov 157 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_recov(x int) {
|
||||
if x := recover(); x != nil {
|
||||
panic(x)
|
||||
}
|
||||
}
|
||||
|
||||
// funcflags.go T_forloops1 169 0 1
|
||||
// Flags FuncPropNeverReturns
|
||||
// <endpropsdump>
|
||||
// {"Flags":1,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_forloops1(x int) {
|
||||
for {
|
||||
panic("wokketa")
|
||||
}
|
||||
}
|
||||
|
||||
// funcflags.go T_forloops2 180 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_forloops2(x int) {
|
||||
for {
|
||||
println("blah")
|
||||
if true {
|
||||
break
|
||||
}
|
||||
panic("warg")
|
||||
}
|
||||
}
|
||||
|
||||
// funcflags.go T_forloops3 195 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_forloops3(x int) {
|
||||
for i := 0; i < 101; i++ {
|
||||
println("blah")
|
||||
if true {
|
||||
continue
|
||||
}
|
||||
panic("plark")
|
||||
}
|
||||
for i := range [10]int{} {
|
||||
println(i)
|
||||
panic("plark")
|
||||
}
|
||||
panic("whatev")
|
||||
}
|
||||
|
||||
// funcflags.go T_hasgotos 215 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_hasgotos(x int, y int) {
|
||||
{
|
||||
xx := x
|
||||
panic("bad")
|
||||
lab1:
|
||||
goto lab2
|
||||
lab2:
|
||||
if false {
|
||||
goto lab1
|
||||
} else {
|
||||
goto lab4
|
||||
}
|
||||
lab4:
|
||||
if xx < y {
|
||||
lab3:
|
||||
if false {
|
||||
goto lab3
|
||||
}
|
||||
}
|
||||
println(9)
|
||||
}
|
||||
}
|
||||
|
||||
// funcflags.go T_break_with_label 246 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamMayFeedIfOrSwitch
|
||||
// 1 ParamNoInfo
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[64,0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_break_with_label(x int, y int) {
|
||||
// presence of break with label should pessimize this func
|
||||
// (similar to goto).
|
||||
panic("bad")
|
||||
lab1:
|
||||
for {
|
||||
println("blah")
|
||||
if x < 0 {
|
||||
break lab1
|
||||
}
|
||||
panic("hubba")
|
||||
}
|
||||
}
|
||||
|
||||
// funcflags.go T_callsexit 268 0 1
|
||||
// Flags FuncPropNeverReturns
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":1,"ParamFlags":[32],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_callsexit(x int) {
|
||||
if x < 0 {
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
// funcflags.go T_exitinexpr 281 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// callsite: funcflags.go:286:18|0 flagstr "CallSiteOnPanicPath" flagval 2 score 102 mask 1 maskstr "panicPathAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_exitinexpr(x int) {
|
||||
// This function does indeed unconditionally call exit, since the
|
||||
// first thing it does is invoke exprcallsexit, however from the
|
||||
// perspective of this function, the call is not at the statement
|
||||
// level, so we'll wind up missing it.
|
||||
if exprcallsexit(x) < 0 {
|
||||
println("foo")
|
||||
}
|
||||
}
|
||||
|
||||
// funcflags.go T_select_noreturn 297 0 1
|
||||
// Flags FuncPropNeverReturns
|
||||
// <endpropsdump>
|
||||
// {"Flags":1,"ParamFlags":[0,0,0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_select_noreturn(chi chan int, chf chan float32, p *int) {
|
||||
rv := 0
|
||||
select {
|
||||
case i := <-chi:
|
||||
rv = i
|
||||
case f := <-chf:
|
||||
rv = int(f)
|
||||
}
|
||||
*p = rv
|
||||
panic("bad")
|
||||
}
|
||||
|
||||
// funcflags.go T_select_mayreturn 314 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0,0],"ResultFlags":[0]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_select_mayreturn(chi chan int, chf chan float32, p *int) int {
|
||||
rv := 0
|
||||
select {
|
||||
case i := <-chi:
|
||||
rv = i
|
||||
return i
|
||||
case f := <-chf:
|
||||
rv = int(f)
|
||||
}
|
||||
*p = rv
|
||||
panic("bad")
|
||||
}
|
||||
|
||||
// funcflags.go T_calls_callsexit 334 0 1
|
||||
// Flags FuncPropNeverReturns
|
||||
// <endpropsdump>
|
||||
// {"Flags":1,"ParamFlags":[0],"ResultFlags":null}
|
||||
// callsite: funcflags.go:335:15|0 flagstr "CallSiteOnPanicPath" flagval 2 score 102 mask 1 maskstr "panicPathAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_calls_callsexit(x int) {
|
||||
exprcallsexit(x)
|
||||
}
|
||||
|
||||
func exprcallsexit(x int) int {
|
||||
os.Exit(x)
|
||||
return x
|
||||
}
|
||||
367
src/cmd/compile/internal/inline/inlheur/testdata/props/params.go
vendored
Normal file
367
src/cmd/compile/internal/inline/inlheur/testdata/props/params.go
vendored
Normal file
@@ -0,0 +1,367 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// DO NOT EDIT (use 'go test -v -update-expected' instead.)
|
||||
// See cmd/compile/internal/inline/inlheur/testdata/props/README.txt
|
||||
// for more information on the format of this file.
|
||||
// <endfilepreamble>
|
||||
package params
|
||||
|
||||
import "os"
|
||||
|
||||
// params.go T_feeds_if_simple 20 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_simple(x int) {
|
||||
if x < 100 {
|
||||
os.Exit(1)
|
||||
}
|
||||
println(x)
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_nested 35 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamMayFeedIfOrSwitch
|
||||
// 1 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[64,32],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_nested(x, y int) {
|
||||
if y != 0 {
|
||||
if x < 100 {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
println(x)
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_pointer 51 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_pointer(xp *int) {
|
||||
if xp != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
println(xp)
|
||||
}
|
||||
|
||||
// params.go T.T_feeds_if_simple_method 66 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// 1 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32,32],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func (r T) T_feeds_if_simple_method(x int) {
|
||||
if x < 100 {
|
||||
os.Exit(1)
|
||||
}
|
||||
if r != 99 {
|
||||
os.Exit(2)
|
||||
}
|
||||
println(x)
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_blanks 86 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamNoInfo
|
||||
// 1 ParamFeedsIfOrSwitch
|
||||
// 2 ParamNoInfo
|
||||
// 3 ParamNoInfo
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,32,0,0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_blanks(_ string, x int, _ bool, _ bool) {
|
||||
// blanks ignored; from a props perspective "x" is param 0
|
||||
if x < 100 {
|
||||
os.Exit(1)
|
||||
}
|
||||
println(x)
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_with_copy 101 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_with_copy(x int) {
|
||||
// simple copy here -- we get this case
|
||||
xx := x
|
||||
if xx < 100 {
|
||||
os.Exit(1)
|
||||
}
|
||||
println(x)
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_with_copy_expr 115 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_with_copy_expr(x int) {
|
||||
// this case (copy of expression) currently not handled.
|
||||
xx := x < 100
|
||||
if xx {
|
||||
os.Exit(1)
|
||||
}
|
||||
println(x)
|
||||
}
|
||||
|
||||
// params.go T_feeds_switch 131 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_switch(x int) {
|
||||
switch x {
|
||||
case 101:
|
||||
println(101)
|
||||
case 202:
|
||||
panic("bad")
|
||||
}
|
||||
println(x)
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_toocomplex 146 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_toocomplex(x int, y int) {
|
||||
// not handled at the moment; we only look for cases where
|
||||
// an "if" or "switch" can be simplified based on a single
|
||||
// constant param, not a combination of constant params.
|
||||
if x < y {
|
||||
panic("bad")
|
||||
}
|
||||
println(x + y)
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_redefined 161 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_redefined(x int) {
|
||||
if x < G {
|
||||
x++
|
||||
}
|
||||
if x == 101 {
|
||||
panic("bad")
|
||||
}
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_redefined2 175 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_redefined2(x int) {
|
||||
// this currently classifies "x" as "no info", since the analysis we
|
||||
// use to check for reassignments/redefinitions is not flow-sensitive,
|
||||
// but we could probably catch this case with better analysis or
|
||||
// high-level SSA.
|
||||
if x == 101 {
|
||||
panic("bad")
|
||||
}
|
||||
if x < G {
|
||||
x++
|
||||
}
|
||||
}
|
||||
|
||||
// params.go T_feeds_multi_if 196 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// 1 ParamNoInfo
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32,0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_multi_if(x int, y int) {
|
||||
// Here we have one "if" that is too complex (x < y) but one that is
|
||||
// simple enough. Currently we enable the heuristic for this. It's
|
||||
// possible to imagine this being a bad thing if the function in
|
||||
// question is sufficiently large, but if it's too large we probably
|
||||
// can't inline it anyhow.
|
||||
if x < y {
|
||||
panic("bad")
|
||||
}
|
||||
if x < 10 {
|
||||
panic("whatev")
|
||||
}
|
||||
println(x + y)
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_redefined_indirectwrite 216 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_redefined_indirectwrite(x int) {
|
||||
ax := &x
|
||||
if G != 2 {
|
||||
*ax = G
|
||||
}
|
||||
if x == 101 {
|
||||
panic("bad")
|
||||
}
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_redefined_indirectwrite_copy 231 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_redefined_indirectwrite_copy(x int) {
|
||||
// we don't catch this case, "x" is marked as no info,
|
||||
// since we're conservative about redefinitions.
|
||||
ax := &x
|
||||
cx := x
|
||||
if G != 2 {
|
||||
*ax = G
|
||||
}
|
||||
if cx == 101 {
|
||||
panic("bad")
|
||||
}
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_expr1 251 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_expr1(x int) {
|
||||
if x == 101 || x == 102 || x&0xf == 0 {
|
||||
panic("bad")
|
||||
}
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_expr2 262 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_expr2(x int) {
|
||||
if (x*x)-(x+x)%x == 101 || x&0xf == 0 {
|
||||
panic("bad")
|
||||
}
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_expr3 273 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_expr3(x int) {
|
||||
if x-(x&0x1)^378 > (1 - G) {
|
||||
panic("bad")
|
||||
}
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_shift_may_panic 284 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_shift_may_panic(x int) *int {
|
||||
// here if "x" is a constant like 2, we could simplify the "if",
|
||||
// but if we were to pass in a negative value for "x" we can't
|
||||
// fold the condition due to the need to panic on negative shift.
|
||||
if 1<<x > 1024 {
|
||||
return nil
|
||||
}
|
||||
return &G
|
||||
}
|
||||
|
||||
// params.go T_feeds_if_maybe_divide_by_zero 299 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_if_maybe_divide_by_zero(x int) {
|
||||
if 99/x == 3 {
|
||||
return
|
||||
}
|
||||
println("blarg")
|
||||
}
|
||||
|
||||
// params.go T_feeds_indcall 313 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamMayFeedIndirectCall
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[16],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_indcall(x func()) {
|
||||
if G != 20 {
|
||||
x()
|
||||
}
|
||||
}
|
||||
|
||||
// params.go T_feeds_indcall_and_if 326 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamMayFeedIndirectCall|ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[48],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_indcall_and_if(x func()) {
|
||||
if x != nil {
|
||||
x()
|
||||
}
|
||||
}
|
||||
|
||||
// params.go T_feeds_indcall_with_copy 339 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIndirectCall
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[8],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_indcall_with_copy(x func()) {
|
||||
xx := x
|
||||
if G < 10 {
|
||||
G--
|
||||
}
|
||||
xx()
|
||||
}
|
||||
|
||||
// params.go T_feeds_interface_method_call 354 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsInterfaceMethodCall
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[2],"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_feeds_interface_method_call(i I) {
|
||||
i.Blarg()
|
||||
}
|
||||
|
||||
var G int
|
||||
|
||||
type T int
|
||||
|
||||
type I interface {
|
||||
Blarg()
|
||||
}
|
||||
|
||||
func (r T) Blarg() {
|
||||
}
|
||||
370
src/cmd/compile/internal/inline/inlheur/testdata/props/returns.go
vendored
Normal file
370
src/cmd/compile/internal/inline/inlheur/testdata/props/returns.go
vendored
Normal file
@@ -0,0 +1,370 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// DO NOT EDIT (use 'go test -v -update-expected' instead.)
|
||||
// See cmd/compile/internal/inline/inlheur/testdata/props/README.txt
|
||||
// for more information on the format of this file.
|
||||
// <endfilepreamble>
|
||||
|
||||
package returns1
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// returns.go T_simple_allocmem 21 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultIsAllocatedMem
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":null,"ResultFlags":[2]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_simple_allocmem() *Bar {
|
||||
return &Bar{}
|
||||
}
|
||||
|
||||
// returns.go T_allocmem_two_returns 34 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// ResultFlags
|
||||
// 0 ResultIsAllocatedMem
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[2]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_allocmem_two_returns(x int) *Bar {
|
||||
// multiple returns
|
||||
if x < 0 {
|
||||
return new(Bar)
|
||||
} else {
|
||||
return &Bar{x: 2}
|
||||
}
|
||||
}
|
||||
|
||||
// returns.go T_allocmem_three_returns 52 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// ResultFlags
|
||||
// 0 ResultIsAllocatedMem
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[2]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_allocmem_three_returns(x int) []*Bar {
|
||||
// more multiple returns
|
||||
switch x {
|
||||
case 10, 11, 12:
|
||||
return make([]*Bar, 10)
|
||||
case 13:
|
||||
fallthrough
|
||||
case 15:
|
||||
return []*Bar{&Bar{x: 15}}
|
||||
}
|
||||
return make([]*Bar, 0, 10)
|
||||
}
|
||||
|
||||
// returns.go T_return_nil 72 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultAlwaysSameConstant
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":null,"ResultFlags":[8]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_return_nil() *Bar {
|
||||
// simple case: no alloc
|
||||
return nil
|
||||
}
|
||||
|
||||
// returns.go T_multi_return_nil 84 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultAlwaysSameConstant
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[8]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_multi_return_nil(x, y bool) *Bar {
|
||||
if x && y {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// returns.go T_multi_return_nil_anomoly 98 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultIsConcreteTypeConvertedToInterface
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[4]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_multi_return_nil_anomoly(x, y bool) Itf {
|
||||
if x && y {
|
||||
var qnil *Q
|
||||
return qnil
|
||||
}
|
||||
var barnil *Bar
|
||||
return barnil
|
||||
}
|
||||
|
||||
// returns.go T_multi_return_some_nil 112 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[0]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_multi_return_some_nil(x, y bool) *Bar {
|
||||
if x && y {
|
||||
return nil
|
||||
} else {
|
||||
return &GB
|
||||
}
|
||||
}
|
||||
|
||||
// returns.go T_mixed_returns 127 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[0]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_mixed_returns(x int) *Bar {
|
||||
// mix of alloc and non-alloc
|
||||
if x < 0 {
|
||||
return new(Bar)
|
||||
} else {
|
||||
return &GB
|
||||
}
|
||||
}
|
||||
|
||||
// returns.go T_mixed_returns_slice 143 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[0]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_mixed_returns_slice(x int) []*Bar {
|
||||
// mix of alloc and non-alloc
|
||||
switch x {
|
||||
case 10, 11, 12:
|
||||
return make([]*Bar, 10)
|
||||
case 13:
|
||||
fallthrough
|
||||
case 15:
|
||||
return []*Bar{&Bar{x: 15}}
|
||||
}
|
||||
ba := [...]*Bar{&GB, &GB}
|
||||
return ba[:]
|
||||
}
|
||||
|
||||
// returns.go T_maps_and_channels 167 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultNoInfo
|
||||
// 1 ResultNoInfo
|
||||
// 2 ResultNoInfo
|
||||
// 3 ResultAlwaysSameConstant
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[0,0,0,8]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_maps_and_channels(x int, b bool) (bool, map[int]int, chan bool, unsafe.Pointer) {
|
||||
// maps and channels
|
||||
return b, make(map[int]int), make(chan bool), nil
|
||||
}
|
||||
|
||||
// returns.go T_assignment_to_named_returns 179 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[0,0]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_assignment_to_named_returns(x int) (r1 *uint64, r2 *uint64) {
|
||||
// assignments to named returns and then "return" not supported
|
||||
r1 = new(uint64)
|
||||
if x < 1 {
|
||||
*r1 = 2
|
||||
}
|
||||
r2 = new(uint64)
|
||||
return
|
||||
}
|
||||
|
||||
// returns.go T_named_returns_but_return_explicit_values 199 0 1
|
||||
// ParamFlags
|
||||
// 0 ParamFeedsIfOrSwitch
|
||||
// ResultFlags
|
||||
// 0 ResultIsAllocatedMem
|
||||
// 1 ResultIsAllocatedMem
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[2,2]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_named_returns_but_return_explicit_values(x int) (r1 *uint64, r2 *uint64) {
|
||||
// named returns ok if all returns are non-empty
|
||||
rx1 := new(uint64)
|
||||
if x < 1 {
|
||||
*rx1 = 2
|
||||
}
|
||||
rx2 := new(uint64)
|
||||
return rx1, rx2
|
||||
}
|
||||
|
||||
// returns.go T_return_concrete_type_to_itf 216 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultIsConcreteTypeConvertedToInterface
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[4]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_return_concrete_type_to_itf(x, y int) Itf {
|
||||
return &Bar{}
|
||||
}
|
||||
|
||||
// returns.go T_return_concrete_type_to_itfwith_copy 227 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultIsConcreteTypeConvertedToInterface
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[4]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_return_concrete_type_to_itfwith_copy(x, y int) Itf {
|
||||
b := &Bar{}
|
||||
println("whee")
|
||||
return b
|
||||
}
|
||||
|
||||
// returns.go T_return_concrete_type_to_itf_mixed 238 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[0]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_return_concrete_type_to_itf_mixed(x, y int) Itf {
|
||||
if x < y {
|
||||
b := &Bar{}
|
||||
return b
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// returns.go T_return_same_func 253 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultAlwaysSameInlinableFunc
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":null,"ResultFlags":[32]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_return_same_func() func(int) int {
|
||||
if G < 10 {
|
||||
return foo
|
||||
} else {
|
||||
return foo
|
||||
}
|
||||
}
|
||||
|
||||
// returns.go T_return_different_funcs 266 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":null,"ResultFlags":[0]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_return_different_funcs() func(int) int {
|
||||
if G != 10 {
|
||||
return foo
|
||||
} else {
|
||||
return bar
|
||||
}
|
||||
}
|
||||
|
||||
// returns.go T_return_same_closure 286 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultAlwaysSameInlinableFunc
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":null,"ResultFlags":[32]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
// returns.go T_return_same_closure.func1 287 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_return_same_closure() func(int) int {
|
||||
p := func(q int) int { return q }
|
||||
if G < 10 {
|
||||
return p
|
||||
} else {
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
// returns.go T_return_different_closures 312 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":null,"ResultFlags":[0]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
// returns.go T_return_different_closures.func1 313 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
// returns.go T_return_different_closures.func2 317 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultAlwaysSameConstant
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[8]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_return_different_closures() func(int) int {
|
||||
p := func(q int) int { return q }
|
||||
if G < 10 {
|
||||
return p
|
||||
} else {
|
||||
return func(q int) int { return 101 }
|
||||
}
|
||||
}
|
||||
|
||||
// returns.go T_return_noninlinable 339 0 1
|
||||
// ResultFlags
|
||||
// 0 ResultAlwaysSameFunc
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[16]}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
// returns.go T_return_noninlinable.func1 340 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
|
||||
// callsite: returns.go:343:4|0 flagstr "" flagval 0 score 4 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
// returns.go T_return_noninlinable.func1.1 341 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":null,"ResultFlags":null}
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_return_noninlinable(x int) func(int) int {
|
||||
noti := func(q int) int {
|
||||
defer func() {
|
||||
println(q + x)
|
||||
}()
|
||||
return q
|
||||
}
|
||||
return noti
|
||||
}
|
||||
|
||||
type Bar struct {
|
||||
x int
|
||||
y string
|
||||
}
|
||||
|
||||
func (b *Bar) Plark() {
|
||||
}
|
||||
|
||||
type Q int
|
||||
|
||||
func (q *Q) Plark() {
|
||||
}
|
||||
|
||||
func foo(x int) int { return x }
|
||||
func bar(x int) int { return -x }
|
||||
|
||||
var G int
|
||||
var GB Bar
|
||||
|
||||
type Itf interface {
|
||||
Plark()
|
||||
}
|
||||
231
src/cmd/compile/internal/inline/inlheur/testdata/props/returns2.go
vendored
Normal file
231
src/cmd/compile/internal/inline/inlheur/testdata/props/returns2.go
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// DO NOT EDIT (use 'go test -v -update-expected' instead.)
|
||||
// See cmd/compile/internal/inline/inlheur/testdata/props/README.txt
|
||||
// for more information on the format of this file.
|
||||
// <endfilepreamble>
|
||||
|
||||
package returns2
|
||||
|
||||
// returns2.go T_return_feeds_iface_call 18 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":null,"ResultFlags":null}
|
||||
// callsite: returns2.go:19:13|0 flagstr "" flagval 0 score 1 mask 16384 maskstr "returnFeedsConcreteToInterfaceCallAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_return_feeds_iface_call() {
|
||||
b := newBar(10)
|
||||
b.Plark()
|
||||
}
|
||||
|
||||
// returns2.go T_multi_return_feeds_iface_call 29 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":null,"ResultFlags":null}
|
||||
// callsite: returns2.go:30:20|0 flagstr "" flagval 0 score 3 mask 16384 maskstr "returnFeedsConcreteToInterfaceCallAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_multi_return_feeds_iface_call() {
|
||||
_, b, _ := newBar2(10)
|
||||
b.Plark()
|
||||
}
|
||||
|
||||
// returns2.go T_returned_inlinable_func_feeds_indirect_call 41 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// callsite: returns2.go:42:18|0 flagstr "" flagval 0 score -51 mask 8200 maskstr "passConstToIfAdj|returnFeedsInlinableFuncToIndCallAdj"
|
||||
// callsite: returns2.go:44:20|1 flagstr "" flagval 0 score -23 mask 8192 maskstr "returnFeedsInlinableFuncToIndCallAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_returned_inlinable_func_feeds_indirect_call(q int) {
|
||||
f := returnsFunc(10)
|
||||
f(q)
|
||||
f2 := returnsFunc2()
|
||||
f2(q)
|
||||
}
|
||||
|
||||
// returns2.go T_returned_noninlineable_func_feeds_indirect_call 54 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// callsite: returns2.go:55:30|0 flagstr "" flagval 0 score -23 mask 4096 maskstr "returnFeedsFuncToIndCallAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_returned_noninlineable_func_feeds_indirect_call(q int) {
|
||||
f := returnsNonInlinableFunc()
|
||||
f(q)
|
||||
}
|
||||
|
||||
// returns2.go T_multi_return_feeds_indirect_call 65 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
|
||||
// callsite: returns2.go:66:29|0 flagstr "" flagval 0 score -21 mask 8192 maskstr "returnFeedsInlinableFuncToIndCallAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_multi_return_feeds_indirect_call(q int) {
|
||||
_, f, _ := multiReturnsFunc()
|
||||
f(q)
|
||||
}
|
||||
|
||||
// returns2.go T_return_feeds_ifswitch 76 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
|
||||
// callsite: returns2.go:77:14|0 flagstr "" flagval 0 score 10 mask 2048 maskstr "returnFeedsConstToIfAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_return_feeds_ifswitch(q int) int {
|
||||
x := meaning(q)
|
||||
if x < 42 {
|
||||
switch x {
|
||||
case 42:
|
||||
return 1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// returns2.go T_multi_return_feeds_ifswitch 93 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
|
||||
// callsite: returns2.go:94:21|0 flagstr "" flagval 0 score 9 mask 2048 maskstr "returnFeedsConstToIfAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_multi_return_feeds_ifswitch(q int) int {
|
||||
x, y, z := meanings(q)
|
||||
if x < y {
|
||||
switch x {
|
||||
case 42:
|
||||
return z
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// returns2.go T_two_calls_feed_ifswitch 111 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
|
||||
// callsite: returns2.go:115:14|0 flagstr "" flagval 0 score 25 mask 0 maskstr ""
|
||||
// callsite: returns2.go:116:14|1 flagstr "" flagval 0 score 25 mask 0 maskstr ""
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_two_calls_feed_ifswitch(q int) int {
|
||||
// This case we don't handle; for the heuristic to kick in,
|
||||
// all names in a given if/switch cond have to come from the
|
||||
// same callsite
|
||||
x := meaning(q)
|
||||
y := meaning(-q)
|
||||
if x < y {
|
||||
switch x + y {
|
||||
case 42:
|
||||
return 1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// returns2.go T_chained_indirect_call 132 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
|
||||
// callsite: returns2.go:135:18|0 flagstr "" flagval 0 score -31 mask 8192 maskstr "returnFeedsInlinableFuncToIndCallAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_chained_indirect_call(x, y int) {
|
||||
// Here 'returnsFunc' returns an inlinable func that feeds
|
||||
// directly into a call (no named intermediate).
|
||||
G += returnsFunc(x - y)(x + y)
|
||||
}
|
||||
|
||||
// returns2.go T_chained_conc_iface_call 144 0 1
|
||||
// <endpropsdump>
|
||||
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
|
||||
// callsite: returns2.go:148:8|0 flagstr "" flagval 0 score 1 mask 16384 maskstr "returnFeedsConcreteToInterfaceCallAdj"
|
||||
// <endcallsites>
|
||||
// <endfuncpreamble>
|
||||
func T_chained_conc_iface_call(x, y int) {
|
||||
// Similar to the case above, return from call returning concrete type
|
||||
// feeds directly into interface call. Note that only the first
|
||||
// iface call is interesting here.
|
||||
newBar(10).Plark().Plark()
|
||||
}
|
||||
|
||||
func returnsFunc(x int) func(int) int {
|
||||
if x < 0 {
|
||||
G++
|
||||
}
|
||||
return adder
|
||||
}
|
||||
|
||||
func returnsFunc2() func(int) int {
|
||||
return func(x int) int {
|
||||
return adder(x)
|
||||
}
|
||||
}
|
||||
|
||||
func returnsNonInlinableFunc() func(int) int {
|
||||
return adderNoInline
|
||||
}
|
||||
|
||||
func multiReturnsFunc() (int, func(int) int, int) {
|
||||
return 42, func(x int) int { G++; return 1 }, -42
|
||||
}
|
||||
|
||||
func adder(x int) int {
|
||||
G += 1
|
||||
return G
|
||||
}
|
||||
|
||||
func adderNoInline(x int) int {
|
||||
defer func() { G += x }()
|
||||
G += 1
|
||||
return G
|
||||
}
|
||||
|
||||
func meaning(q int) int {
|
||||
r := 0
|
||||
for i := 0; i < 42; i++ {
|
||||
r += q
|
||||
}
|
||||
G += r
|
||||
return 42
|
||||
}
|
||||
|
||||
func meanings(q int) (int, int, int) {
|
||||
r := 0
|
||||
for i := 0; i < 42; i++ {
|
||||
r += q
|
||||
}
|
||||
return 42, 43, r
|
||||
}
|
||||
|
||||
type Bar struct {
|
||||
x int
|
||||
y string
|
||||
}
|
||||
|
||||
func (b *Bar) Plark() Itf {
|
||||
return b
|
||||
}
|
||||
|
||||
type Itf interface {
|
||||
Plark() Itf
|
||||
}
|
||||
|
||||
func newBar(x int) Itf {
|
||||
s := 0
|
||||
for i := 0; i < x; i++ {
|
||||
s += i
|
||||
}
|
||||
return &Bar{
|
||||
x: s,
|
||||
}
|
||||
}
|
||||
|
||||
func newBar2(x int) (int, Itf, bool) {
|
||||
s := 0
|
||||
for i := 0; i < x; i++ {
|
||||
s += i
|
||||
}
|
||||
return 0, &Bar{x: s}, false
|
||||
}
|
||||
|
||||
var G int
|
||||
Reference in New Issue
Block a user