Skip to content

Commit 7ed6b45

Browse files
aykevldeadprogram
authored andcommitted
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: golang/go#12312
1 parent c66d979 commit 7ed6b45

File tree

3 files changed

+11
-0
lines changed

3 files changed

+11
-0
lines changed

compiler/compiler.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,10 @@ func (c *Compiler) parseFunc(frame *Frame) {
865865
// Add LLVM inline hint to functions with //go:inline pragma.
866866
inline := c.ctx.CreateEnumAttribute(llvm.AttributeKindID("inlinehint"), 0)
867867
frame.fn.LLVMFn.AddFunctionAttr(inline)
868+
case ir.InlineNone:
869+
// Add LLVM attribute to always avoid inlining this function.
870+
noinline := c.ctx.CreateEnumAttribute(llvm.AttributeKindID("noinline"), 0)
871+
frame.fn.LLVMFn.AddFunctionAttr(noinline)
868872
}
869873

870874
// Add debug info, if needed.

ir/ir.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ const (
5656
// //go:inline). The compiler will be more likely to inline this function,
5757
// but it is not a guarantee.
5858
InlineHint
59+
60+
// Don't inline, just like the GCC noinline attribute. Signalled using
61+
// //go:noinline.
62+
InlineNone
5963
)
6064

6165
// Create and initialize a new *Program from a *ssa.Program.
@@ -227,6 +231,8 @@ func (f *Function) parsePragmas() {
227231
f.exported = true
228232
case "//go:inline":
229233
f.inline = InlineHint
234+
case "//go:noinline":
235+
f.inline = InlineNone
230236
case "//go:interrupt":
231237
if len(parts) != 2 {
232238
continue

src/runtime/gc_conservative.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ func init() {
203203

204204
// alloc tries to find some free space on the heap, possibly doing a garbage
205205
// collection cycle if needed. If no space is free, it panics.
206+
//go:noinline
206207
func alloc(size uintptr) unsafe.Pointer {
207208
if size == 0 {
208209
return unsafe.Pointer(&zeroSizedAlloc)

0 commit comments

Comments
 (0)