mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 16:50:58 +00:00 
			
		
		
		
	 4f70a2a699
			
		
	
	
		4f70a2a699
		
	
	
	
	
		
			
			Calls to a closure held in a local, non-escaping, variable can be inlined, provided the closure body can be inlined and the variable is never written to. The current implementation has the following limitations: - closures with captured variables are not inlined because doing so naively triggers invariant violation in the SSA phase - re-assignment check is currently approximated by checking the Addrtaken property of the variable which should be safe but may miss optimization opportunities if the address is not used for a write before the invocation Updates #15561 Change-Id: I508cad5d28f027bd7e933b1f793c14dcfef8b5a1 Reviewed-on: https://go-review.googlesource.com/65071 Run-TryBot: Daniel Martà <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Hugues Bruant <hugues.bruant@gmail.com> Reviewed-by: Keith Randall <khr@golang.org>
		
			
				
	
	
		
			57 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			57 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // errorcheck -0 -m
 | |
| 
 | |
| // Copyright 2010 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.
 | |
| 
 | |
| // Test, using compiler diagnostic flags, that the escape analysis is working.
 | |
| // Compiles but does not run.  Inlining is enabled.
 | |
| 
 | |
| package foo
 | |
| 
 | |
| var p *int
 | |
| 
 | |
| func alloc(x int) *int { // ERROR "can inline alloc" "moved to heap: x"
 | |
| 	return &x // ERROR "&x escapes to heap"
 | |
| }
 | |
| 
 | |
| var f func()
 | |
| 
 | |
| func f1() {
 | |
| 	p = alloc(2) // ERROR "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
 | |
| 
 | |
| 	// Escape analysis used to miss inlined code in closures.
 | |
| 
 | |
| 	func() { // ERROR "can inline f1.func1"
 | |
| 		p = alloc(3) // ERROR "inlining call to alloc"
 | |
| 	}() // ERROR "inlining call to f1.func1" "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
 | |
| 
 | |
| 	f = func() { // ERROR "func literal escapes to heap" "can inline f1.func2"
 | |
| 		p = alloc(3) // ERROR "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
 | |
| 	}
 | |
| 	f()
 | |
| }
 | |
| 
 | |
| func f2() {} // ERROR "can inline f2"
 | |
| 
 | |
| // No inline for panic, recover.
 | |
| func f3() { panic(1) }
 | |
| func f4() { recover() }
 | |
| 
 | |
| func f5() *byte {
 | |
| 	type T struct {
 | |
| 		x [1]byte
 | |
| 	}
 | |
| 	t := new(T)    // ERROR "new.T. escapes to heap"
 | |
| 	return &t.x[0] // ERROR "&t.x.0. escapes to heap"
 | |
| }
 | |
| 
 | |
| func f6() *byte {
 | |
| 	type T struct {
 | |
| 		x struct {
 | |
| 			y byte
 | |
| 		}
 | |
| 	}
 | |
| 	t := new(T)   // ERROR "new.T. escapes to heap"
 | |
| 	return &t.x.y // ERROR "&t.x.y escapes to heap"
 | |
| }
 |