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
Этот коммит содержится в:
родитель
c66d979ba3
коммит
7ed6b45149
3 изменённых файлов: 11 добавлений и 0 удалений
|
@ -865,6 +865,10 @@ func (c *Compiler) parseFunc(frame *Frame) {
|
||||||
// Add LLVM inline hint to functions with //go:inline pragma.
|
// Add LLVM inline hint to functions with //go:inline pragma.
|
||||||
inline := c.ctx.CreateEnumAttribute(llvm.AttributeKindID("inlinehint"), 0)
|
inline := c.ctx.CreateEnumAttribute(llvm.AttributeKindID("inlinehint"), 0)
|
||||||
frame.fn.LLVMFn.AddFunctionAttr(inline)
|
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.
|
// Add debug info, if needed.
|
||||||
|
|
6
ir/ir.go
6
ir/ir.go
|
@ -56,6 +56,10 @@ const (
|
||||||
// //go:inline). The compiler will be more likely to inline this function,
|
// //go:inline). The compiler will be more likely to inline this function,
|
||||||
// but it is not a guarantee.
|
// but it is not a guarantee.
|
||||||
InlineHint
|
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.
|
// Create and initialize a new *Program from a *ssa.Program.
|
||||||
|
@ -227,6 +231,8 @@ func (f *Function) parsePragmas() {
|
||||||
f.exported = true
|
f.exported = true
|
||||||
case "//go:inline":
|
case "//go:inline":
|
||||||
f.inline = InlineHint
|
f.inline = InlineHint
|
||||||
|
case "//go:noinline":
|
||||||
|
f.inline = InlineNone
|
||||||
case "//go:interrupt":
|
case "//go:interrupt":
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -203,6 +203,7 @@ func init() {
|
||||||
|
|
||||||
// alloc tries to find some free space on the heap, possibly doing a garbage
|
// 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.
|
// collection cycle if needed. If no space is free, it panics.
|
||||||
|
//go:noinline
|
||||||
func alloc(size uintptr) unsafe.Pointer {
|
func alloc(size uintptr) unsafe.Pointer {
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
return unsafe.Pointer(&zeroSizedAlloc)
|
return unsafe.Pointer(&zeroSizedAlloc)
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче