From 52a64a7770d9a7524e3080bda11cbd5cfe07fe9e Mon Sep 17 00:00:00 2001 From: xushiwei Date: Wed, 1 May 2024 21:18:28 +0800 Subject: [PATCH] cl: initLinknameByDoc --- cl/_testrt/concat/in.go | 9 +++++++++ cl/_testrt/concat/out.ll | 32 ++++++++++++++++++++++++++++++++ cl/_testrt/fprintf/in.go | 15 +++++++++++---- cl/_testrt/fprintf/out.ll | 6 +++--- cl/compile.go | 6 ++++-- cl/import.go | 31 ++++++++++++++++++++----------- 6 files changed, 79 insertions(+), 20 deletions(-) create mode 100644 cl/_testrt/concat/in.go create mode 100644 cl/_testrt/concat/out.ll diff --git a/cl/_testrt/concat/in.go b/cl/_testrt/concat/in.go new file mode 100644 index 00000000..5328026a --- /dev/null +++ b/cl/_testrt/concat/in.go @@ -0,0 +1,9 @@ +package main + +import ( + "github.com/goplus/llgo/internal/runtime/c" +) + +func main() { + c.Fprintf(c.Stderr, c.Str("Hello %d\n"), 100) +} diff --git a/cl/_testrt/concat/out.ll b/cl/_testrt/concat/out.ll new file mode 100644 index 00000000..ee0cd9d7 --- /dev/null +++ b/cl/_testrt/concat/out.ll @@ -0,0 +1,32 @@ +; ModuleID = 'main' +source_filename = "main" + +@"main.init$guard" = global ptr null +@__stderrp = external global ptr +@0 = private unnamed_addr constant [10 x i8] c"Hello %d\0A\00", align 1 + +define void @main.init() { +_llgo_0: + %0 = load i1, ptr @"main.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"main.init$guard", align 1 + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define void @main() { +_llgo_0: + call void @"github.com/goplus/llgo/internal/runtime.init"() + call void @main.init() + %0 = load ptr, ptr @__stderrp, align 8 + %1 = call i32 (ptr, ptr, ...) @fprintf(ptr %0, ptr @0, i64 100) + ret void +} + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare i32 @fprintf(ptr, ptr, ...) diff --git a/cl/_testrt/fprintf/in.go b/cl/_testrt/fprintf/in.go index 5328026a..b6821913 100644 --- a/cl/_testrt/fprintf/in.go +++ b/cl/_testrt/fprintf/in.go @@ -1,9 +1,16 @@ package main -import ( - "github.com/goplus/llgo/internal/runtime/c" -) +import "unsafe" + +//go:linkname cstr llgo.cstr +func cstr(string) *int8 + +//go:linkname stderr __stderrp +var stderr unsafe.Pointer + +//go:linkname fprintf C.fprintf +func fprintf(fp unsafe.Pointer, format *int8, __llgo_va_list ...any) func main() { - c.Fprintf(c.Stderr, c.Str("Hello %d\n"), 100) + fprintf(stderr, cstr("Hello %d\n"), 100) } diff --git a/cl/_testrt/fprintf/out.ll b/cl/_testrt/fprintf/out.ll index ee0cd9d7..03f4adf7 100644 --- a/cl/_testrt/fprintf/out.ll +++ b/cl/_testrt/fprintf/out.ll @@ -5,6 +5,8 @@ source_filename = "main" @__stderrp = external global ptr @0 = private unnamed_addr constant [10 x i8] c"Hello %d\0A\00", align 1 +declare void @fprintf(ptr, ptr, ...) + define void @main.init() { _llgo_0: %0 = load i1, ptr @"main.init$guard", align 1 @@ -23,10 +25,8 @@ _llgo_0: call void @"github.com/goplus/llgo/internal/runtime.init"() call void @main.init() %0 = load ptr, ptr @__stderrp, align 8 - %1 = call i32 (ptr, ptr, ...) @fprintf(ptr %0, ptr @0, i64 100) + call void (ptr, ptr, ...) @fprintf(ptr %0, ptr @0, i64 100) ret void } declare void @"github.com/goplus/llgo/internal/runtime.init"() - -declare i32 @fprintf(ptr, ptr, ...) diff --git a/cl/compile.go b/cl/compile.go index a8975ed7..c374a5d5 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -177,7 +177,7 @@ func (p *context) compileMethods(pkg llssa.Package, typ types.Type) { // Global variable. func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) { typ := gbl.Type() - name := p.varName(gbl.Pkg.Pkg, gbl) + name, isDef := p.varName(gbl.Pkg.Pkg, gbl) if ignoreName(name) || checkCgo(gbl.Name()) { return } @@ -185,7 +185,9 @@ func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) { log.Println("==> NewVar", name, typ) } g := pkg.NewVar(name, typ) - g.Init(p.prog.Null(g.Type)) + if isDef { + g.Init(p.prog.Null(g.Type)) + } } func (p *context) compileFunc(pkg llssa.Package, pkgTypes *types.Package, f *ssa.Function) { diff --git a/cl/import.go b/cl/import.go index 0404deb5..bdfa1050 100644 --- a/cl/import.go +++ b/cl/import.go @@ -107,20 +107,29 @@ func (p *context) importPkg(pkg *types.Package, i *pkgInfo) { func (p *context) initFiles(pkgPath string, files []*ast.File) { for _, file := range files { for _, decl := range file.Decls { - if decl, ok := decl.(*ast.FuncDecl); ok { + switch decl := decl.(type) { + case *ast.FuncDecl: if decl.Recv == nil { - if doc := decl.Doc; doc != nil { - if n := len(doc.List); n > 0 { - line := doc.List[n-1].Text - p.initLinkname(pkgPath, line, false) - } - } + p.initLinknameByDoc(decl.Doc, pkgPath, false) + } + case *ast.GenDecl: + if decl.Tok == token.VAR && len(decl.Specs) == 1 { + p.initLinknameByDoc(decl.Doc, pkgPath, true) } } } } } +func (p *context) initLinknameByDoc(doc *ast.CommentGroup, pkgPath string, isVar bool) { + if doc != nil { + if n := len(doc.List); n > 0 { + line := doc.List[n-1].Text + p.initLinkname(pkgPath, line, isVar) + } + } +} + func (p *context) initLinknameByPos(fset *token.FileSet, pos token.Pos, pkgPath string, contents contentMap, isVar bool) { f := fset.File(pos) if fp := f.Position(pos); fp.Line > 2 { @@ -210,12 +219,12 @@ func (p *context) funcName(pkg *types.Package, fn *ssa.Function, ignore bool) (s return name, goFunc } -func (p *context) varName(pkg *types.Package, v *ssa.Global) string { +func (p *context) varName(pkg *types.Package, v *ssa.Global) (vName string, isDef bool) { name := llssa.FullName(pkg, v.Name()) if v, ok := p.link[name]; ok { - return v + return v, false } - return name + return name, true } // funcOf returns a function by name and set ftype = goFunc, cFunc, etc. @@ -246,7 +255,7 @@ func (p *context) funcOf(fn *ssa.Function) (ret llssa.Function, ftype int) { func (p *context) varOf(v *ssa.Global) (ret llssa.Global) { pkgTypes := p.ensureLoaded(v.Pkg.Pkg) pkg := p.pkg - name := p.varName(pkgTypes, v) + name, _ := p.varName(pkgTypes, v) if ret = pkg.VarOf(name); ret == nil { ret = pkg.NewVar(name, v.Type()) }