From b0ebb479f6ae6dec14e1118ec6d6c98f8f22b83f Mon Sep 17 00:00:00 2001 From: visualfc Date: Wed, 4 Sep 2024 21:50:29 +0800 Subject: [PATCH] ssa: fix llgo:type c for typeparam named --- cl/_testrt/tpfunc/in.go | 26 +++++++++++++ cl/_testrt/tpfunc/out.ll | 80 ++++++++++++++++++++++++++++++++++++++++ ssa/package.go | 2 +- ssa/type.go | 2 +- ssa/type_cvt.go | 16 ++++++-- 5 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 cl/_testrt/tpfunc/in.go create mode 100644 cl/_testrt/tpfunc/out.ll diff --git a/cl/_testrt/tpfunc/in.go b/cl/_testrt/tpfunc/in.go new file mode 100644 index 00000000..44c8e8ef --- /dev/null +++ b/cl/_testrt/tpfunc/in.go @@ -0,0 +1,26 @@ +package main + +import ( + "unsafe" +) + +type Func func(*int) + +//llgo:type C +type CFunc func(*int) + +//llgo:type C +type Callback[T any] func(*T) + +func main() { + var fn1 Func = func(v *int) { + println(*v) + } + var fn2 CFunc = func(v *int) { + println(*v) + } + var fn3 Callback[int] = func(v *int) { + println(*v) + } + println(unsafe.Sizeof(fn1), unsafe.Sizeof(fn2), unsafe.Sizeof(fn3)) +} diff --git a/cl/_testrt/tpfunc/out.ll b/cl/_testrt/tpfunc/out.ll new file mode 100644 index 00000000..b737eee4 --- /dev/null +++ b/cl/_testrt/tpfunc/out.ll @@ -0,0 +1,80 @@ +; ModuleID = 'main' +source_filename = "main" + +%main.Func = type { ptr, ptr } + +@"main.init$guard" = global i1 false, align 1 +@__llgo_argc = global i32 0, align 4 +@__llgo_argv = global ptr null, align 8 + +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 i32 @main(i32 %0, ptr %1) { +_llgo_0: + store i32 %0, ptr @__llgo_argc, align 4 + store ptr %1, ptr @__llgo_argv, align 8 + call void @"github.com/goplus/llgo/internal/runtime.init"() + call void @main.init() + %2 = alloca %main.Func, align 8 + %3 = getelementptr inbounds %main.Func, ptr %2, i32 0, i32 0 + store ptr @"__llgo_stub.main.main$1", ptr %3, align 8 + %4 = getelementptr inbounds %main.Func, ptr %2, i32 0, i32 1 + store ptr null, ptr %4, align 8 + %5 = load %main.Func, ptr %2, align 8 + call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 16) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) + call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 8) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) + call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 8) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) + ret i32 0 +} + +define void @"main.main$1"(ptr %0) { +_llgo_0: + %1 = load i64, ptr %0, align 4 + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %1) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) + ret void +} + +define void @"main.main$2"(ptr %0) { +_llgo_0: + %1 = load i64, ptr %0, align 4 + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %1) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) + ret void +} + +define void @"main.main$3"(ptr %0) { +_llgo_0: + %1 = load i64, ptr %0, align 4 + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %1) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) + ret void +} + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +define linkonce void @"__llgo_stub.main.main$1"(ptr %0, ptr %1) { +_llgo_0: + tail call void @"main.main$1"(ptr %1) + ret void +} + +declare void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64) + +declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8) + +declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64) diff --git a/ssa/package.go b/ssa/package.go index 57b3ed1d..020cbda6 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -244,7 +244,7 @@ func (p Program) SetRuntime(runtime any) { } func (p Program) SetTypeBackground(fullName string, bg Background) { - p.gocvt.typbg[fullName] = bg + p.gocvt.typbg.Store(fullName, bg) } func (p Program) SetLinkname(name, link string) { diff --git a/ssa/type.go b/ssa/type.go index 122041c9..ab813e32 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -125,7 +125,7 @@ func (p *goProgram) extraSize(typ types.Type, ptrSize int64) (ret int64) { retry: switch t := typ.(type) { case *types.Named: - if p.gocvt.typbg[t.String()] == InC { + if v, ok := p.gocvt.typbg.Load(namedLinkname(t)); ok && v.(Background) == InC { return 0 } typ = t.Underlying() diff --git a/ssa/type_cvt.go b/ssa/type_cvt.go index 8aa10ee5..b696cfeb 100644 --- a/ssa/type_cvt.go +++ b/ssa/type_cvt.go @@ -20,6 +20,7 @@ import ( "fmt" "go/token" "go/types" + "sync" "unsafe" ) @@ -27,13 +28,12 @@ import ( type goTypes struct { typs map[unsafe.Pointer]unsafe.Pointer - typbg map[string]Background + typbg sync.Map } func newGoTypes() goTypes { typs := make(map[unsafe.Pointer]unsafe.Pointer) - typbk := make(map[string]Background) - return goTypes{typs, typbk} + return goTypes{typs: typs} } type Background int @@ -95,7 +95,7 @@ func (p goTypes) cvtType(typ types.Type) (raw types.Type, cvt bool) { case *types.Struct: return p.cvtStruct(t) case *types.Named: - if p.typbg[t.String()] == InC { + if v, ok := p.typbg.Load(namedLinkname(t)); ok && v.(Background) == InC { break } return p.cvtNamed(t) @@ -115,6 +115,14 @@ func (p goTypes) cvtType(typ types.Type) (raw types.Type, cvt bool) { return typ, false } +func namedLinkname(t *types.Named) string { + obj := t.Obj() + if obj.Pkg() != nil { + return obj.Pkg().Path() + "." + obj.Name() + } + return obj.Name() +} + func (p goTypes) cvtNamed(t *types.Named) (raw *types.Named, cvt bool) { if v, ok := p.typs[unsafe.Pointer(t)]; ok { raw = (*types.Named)(v)