Commit a92543e1 authored by Todd Neal's avatar Todd Neal

cmd/compile: add support for a go:noinline directive

Some tests need to disable inlining of a function.  It's currently done
in one of a few ways (adding a function call, an empty switch, or a
defer).  Add support for a less fragile 'go:noinline' directive that
prevents inlining.

Fixes #12312

Change-Id: Ife444e13361b4a927709d81aa41e448f32eec8d4
Reviewed-on: https://go-review.googlesource.com/13911
Run-TryBot: Todd Neal <todd@tneal.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarJosh Bleecher Snyder <josharian@gmail.com>
parent c9b8cab1
......@@ -657,10 +657,11 @@ var instrumenting bool
// Pending annotations for next func declaration.
var (
noescape bool
noinline bool
norace bool
nosplit bool
nowritebarrier bool
systemstack bool
norace bool
)
var debuglive int
......
......@@ -1393,6 +1393,7 @@ xfndcl:
$$.Noescape = noescape;
$$.Func.Norace = norace;
$$.Func.Nosplit = nosplit;
$$.Func.Noinline = noinline;
$$.Func.Nowritebarrier = nowritebarrier;
$$.Func.Systemstack = systemstack;
funcbody($$);
......@@ -1579,8 +1580,9 @@ xdcl_list:
if nsyntaxerrors == 0 {
testdclstack();
}
nointerface = false
noescape = false
noinline = false
nointerface = false
norace = false
nosplit = false
nowritebarrier = false
......
......@@ -106,6 +106,11 @@ func caninl(fn *Node) {
Fatalf("caninl no nname %v", Nconv(fn, obj.FmtSign))
}
// If marked "go:noinline", don't inline
if fn.Func.Noinline {
return
}
// If fn has no body (is defined outside of Go), cannot inline it.
if fn.Nbody == nil {
return
......
......@@ -1662,6 +1662,11 @@ func getlinepragma() int {
return c
}
if verb == "go:noinline" {
noinline = true
return c
}
if verb == "go:systemstack" {
if compiling_runtime == 0 {
Yyerror("//go:systemstack only allowed in runtime")
......
......@@ -171,6 +171,7 @@ type Func struct {
Norace bool // func must not have race detector annotations
Nosplit bool // func should not execute on separate stack
Noinline bool // func should not be inlined
Nowritebarrier bool // emit compiler error instead of write barrier
Dupok bool // duplicate definitions ok
Wrapper bool // is method wrapper
......
This diff is collapsed.
......@@ -22,3 +22,12 @@ func add1(p unsafe.Pointer, x uintptr) unsafe.Pointer { // ERROR "can inline add
func f(x *byte) *byte { // ERROR "can inline f" "leaking param: x to result"
return add2(x, 1) // ERROR "inlining call to add2" "inlining call to add1"
}
//go:noinline
func g(x int) int {
return x + 1
}
func h(x int) int { // ERROR "can inline h"
return x + 2
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment