From 37460ad60af2601a0412426c229663443c8d8eaa Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 24 Mar 2023 00:23:03 +0100 Subject: [PATCH] compiler: support pragmas on generic functions --- compiler/symbol.go | 8 ++++++-- compiler/testdata/pragma.go | 16 ++++++++++++++++ compiler/testdata/pragma.ll | 13 +++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/compiler/symbol.go b/compiler/symbol.go index 29f0095208..32eb55107c 100644 --- a/compiler/symbol.go +++ b/compiler/symbol.go @@ -250,10 +250,14 @@ func (c *compilerContext) getFunctionInfo(f *ssa.Function) functionInfo { // parsePragmas is used by getFunctionInfo to parse function pragmas such as // //export or //go:noinline. func (c *compilerContext) parsePragmas(info *functionInfo, f *ssa.Function) { - if f.Syntax() == nil { + syntax := f.Syntax() + if f.Origin() != nil { + syntax = f.Origin().Syntax() + } + if syntax == nil { return } - if decl, ok := f.Syntax().(*ast.FuncDecl); ok && decl.Doc != nil { + if decl, ok := syntax.(*ast.FuncDecl); ok && decl.Doc != nil { for _, comment := range decl.Doc.List { text := comment.Text if strings.HasPrefix(text, "//export ") { diff --git a/compiler/testdata/pragma.go b/compiler/testdata/pragma.go index fa1d4b0e96..1f6badf7fb 100644 --- a/compiler/testdata/pragma.go +++ b/compiler/testdata/pragma.go @@ -48,6 +48,22 @@ func inlineFunc() { func noinlineFunc() { } +type Int interface { + int8 | int16 +} + +// Same for generic functions (but the compiler may miss the pragma due to it +// being generic). +// +//go:noinline +func noinlineGenericFunc[T Int]() { +} + +func useGeneric() { + // Make sure the generic function above is instantiated. + noinlineGenericFunc[int8]() +} + // This function should have the specified section. // //go:section .special_function_section diff --git a/compiler/testdata/pragma.ll b/compiler/testdata/pragma.ll index 3ee4078f1a..28e678359d 100644 --- a/compiler/testdata/pragma.ll +++ b/compiler/testdata/pragma.ll @@ -48,6 +48,19 @@ entry: ret void } +; Function Attrs: nounwind +define hidden void @main.useGeneric(ptr %context) unnamed_addr #2 { +entry: + call void @"main.noinlineGenericFunc[int8]"(ptr undef) + ret void +} + +; Function Attrs: noinline nounwind +define linkonce_odr hidden void @"main.noinlineGenericFunc[int8]"(ptr %context) unnamed_addr #5 { +entry: + ret void +} + ; Function Attrs: noinline nounwind define hidden void @main.functionInSection(ptr %context) unnamed_addr #5 section ".special_function_section" { entry: