diff options
author | Ayke van Laethem <[email protected]> | 2019-07-07 15:51:52 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2019-07-08 00:02:28 +0200 |
commit | 7ed6b45149fdcff29f3149b8bc5a5d7fc857077d (patch) | |
tree | 1ff819cb8d4c398214e4a658f6c37c506f921462 | |
parent | c66d979ba310feb94bee49e264a1af9d9981127b (diff) | |
download | tinygo-7ed6b45149fdcff29f3149b8bc5a5d7fc857077d.tar.gz tinygo-7ed6b45149fdcff29f3149b8bc5a5d7fc857077d.zip |
compiler: add the //go:noinline pragma
This is directly useful to avoid some unsafety around runtime.alloc and
should be useful in general.
This pragma has the same form as in the main Go compiler:
https://github.com/golang/go/issues/12312
-rw-r--r-- | compiler/compiler.go | 4 | ||||
-rw-r--r-- | ir/ir.go | 6 | ||||
-rw-r--r-- | src/runtime/gc_conservative.go | 1 |
3 files changed, 11 insertions, 0 deletions
diff --git a/compiler/compiler.go b/compiler/compiler.go index 82aaee36e..1800f462a 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -865,6 +865,10 @@ func (c *Compiler) parseFunc(frame *Frame) { // Add LLVM inline hint to functions with //go:inline pragma. inline := c.ctx.CreateEnumAttribute(llvm.AttributeKindID("inlinehint"), 0) frame.fn.LLVMFn.AddFunctionAttr(inline) + case ir.InlineNone: + // Add LLVM attribute to always avoid inlining this function. + noinline := c.ctx.CreateEnumAttribute(llvm.AttributeKindID("noinline"), 0) + frame.fn.LLVMFn.AddFunctionAttr(noinline) } // Add debug info, if needed. @@ -56,6 +56,10 @@ const ( // //go:inline). The compiler will be more likely to inline this function, // but it is not a guarantee. InlineHint + + // Don't inline, just like the GCC noinline attribute. Signalled using + // //go:noinline. + InlineNone ) // Create and initialize a new *Program from a *ssa.Program. @@ -227,6 +231,8 @@ func (f *Function) parsePragmas() { f.exported = true case "//go:inline": f.inline = InlineHint + case "//go:noinline": + f.inline = InlineNone case "//go:interrupt": if len(parts) != 2 { continue diff --git a/src/runtime/gc_conservative.go b/src/runtime/gc_conservative.go index c8cb535a6..6b5b7a5cf 100644 --- a/src/runtime/gc_conservative.go +++ b/src/runtime/gc_conservative.go @@ -203,6 +203,7 @@ func init() { // alloc tries to find some free space on the heap, possibly doing a garbage // collection cycle if needed. If no space is free, it panics. +//go:noinline func alloc(size uintptr) unsafe.Pointer { if size == 0 { return unsafe.Pointer(&zeroSizedAlloc) |