From 809a400f57ac1178e4114b44e882d645131548cb Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 3 May 2024 23:49:52 +0800 Subject: [PATCH] llgo/ssa: Call to support closure --- cl/_testrt/_intgen/out.ll | 0 cl/_testrt/{_intgen => intgen}/in.go | 0 cl/_testrt/intgen/out.ll | 85 ++++++++++++++++++++++++++++ cl/compile.go | 9 +-- internal/runtime/z_closure.go | 10 ++++ ssa/expr.go | 12 ++-- 6 files changed, 106 insertions(+), 10 deletions(-) delete mode 100644 cl/_testrt/_intgen/out.ll rename cl/_testrt/{_intgen => intgen}/in.go (100%) create mode 100644 cl/_testrt/intgen/out.ll diff --git a/cl/_testrt/_intgen/out.ll b/cl/_testrt/_intgen/out.ll deleted file mode 100644 index e69de29b..00000000 diff --git a/cl/_testrt/_intgen/in.go b/cl/_testrt/intgen/in.go similarity index 100% rename from cl/_testrt/_intgen/in.go rename to cl/_testrt/intgen/in.go diff --git a/cl/_testrt/intgen/out.ll b/cl/_testrt/intgen/out.ll new file mode 100644 index 00000000..4e3109c8 --- /dev/null +++ b/cl/_testrt/intgen/out.ll @@ -0,0 +1,85 @@ +; ModuleID = 'main' +source_filename = "main" + +%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 } +%"github.com/goplus/llgo/internal/runtime.Closure" = type { ptr, ptr } + +@"main.init$guard" = global ptr null +@0 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 + +define %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 %0, %"github.com/goplus/llgo/internal/runtime.Closure" %1) { +_llgo_0: + %2 = mul i64 %0, 4 + %3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 %2) + %4 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %3, i64 %0, i64 %0) + %5 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %4) + br label %_llgo_1 + +_llgo_1: ; preds = %_llgo_2, %_llgo_0 + %6 = phi i64 [ -1, %_llgo_0 ], [ %7, %_llgo_2 ] + %7 = add i64 %6, 1 + %8 = icmp slt i64 %7, %5 + br i1 %8, label %_llgo_2, label %_llgo_3 + +_llgo_2: ; preds = %_llgo_1 + %9 = call addrspace(1) %"github.com/goplus/llgo/internal/runtime.Closure" %1() + %10 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %4) + %11 = getelementptr inbounds i32, ptr %10, i64 %7 + store ptr %9, ptr %11, align 8 + br label %_llgo_1 + +_llgo_3: ; preds = %_llgo_1 + ret %"github.com/goplus/llgo/internal/runtime.Slice" %4 +} + +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 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, ptr @main.Rand) + %1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) + br label %_llgo_1 + +_llgo_1: ; preds = %_llgo_2, %_llgo_0 + %2 = phi i64 [ -1, %_llgo_0 ], [ %3, %_llgo_2 ] + %3 = add i64 %2, 1 + %4 = icmp slt i64 %3, %1 + br i1 %4, label %_llgo_2, label %_llgo_3 + +_llgo_2: ; preds = %_llgo_1 + %5 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) + %6 = getelementptr inbounds i32, ptr %5, i64 %3 + %7 = load i32, ptr %6, align 4 + %8 = call i32 (ptr, ...) @printf(ptr @0, i32 %7) + br label %_llgo_1 + +_llgo_3: ; preds = %_llgo_1 + ret void +} + +declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) + +declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr, i64, i64) + +declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice") + +declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice") + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare i32 @main.Rand() + +declare i32 @printf(ptr, ...) diff --git a/cl/compile.go b/cl/compile.go index 62d11ad3..95dcb029 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -437,12 +437,9 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue panic("todo") } default: - panic("todo") - /* - fn := p.compileValue(b, cv) - args := p.compileValues(b, call.Args, kind) - ret = b.Call(fn, args...) - */ + fn := p.compileValue(b, cv) + args := p.compileValues(b, call.Args, kind) + ret = b.Call(fn, args...) } case *ssa.BinOp: x := p.compileValue(b, v.X) diff --git a/internal/runtime/z_closure.go b/internal/runtime/z_closure.go index 41899815..15c70a7c 100644 --- a/internal/runtime/z_closure.go +++ b/internal/runtime/z_closure.go @@ -30,3 +30,13 @@ type Closure struct { func NewClosure(f, data unsafe.Pointer) Closure { return Closure{f, data} } + +// ClosureF returns the function of a closure. +func ClosureF(c Closure) unsafe.Pointer { + return c.f +} + +// ClosureData returns the data of a closure. +func ClosureData(c Closure) unsafe.Pointer { + return c.data +} diff --git a/ssa/expr.go b/ssa/expr.go index 19c4d5ff..d252122a 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -681,7 +681,7 @@ func (b Builder) MakeSlice(t Type, len, cap Expr) (ret Expr) { if cap.IsNil() { cap = len } - elemSize := b.SizeOf(b.Prog.Elem(t)) + elemSize := b.SizeOf(b.Prog.Index(t)) size := b.BinOp(token.MUL, cap, elemSize) ptr := b.InlineCall(pkg.rtFunc("AllocZ"), size) ret.impl = b.InlineCall(pkg.rtFunc("NewSlice"), ptr, len, cap).impl @@ -1003,9 +1003,13 @@ func (b Builder) Call(fn Expr, args ...Expr) (ret Expr) { } log.Println(b.String()) } - switch t := fn.t.(type) { - case *types.Signature: - ret.Type = b.Prog.retType(t) + t := fn.t + switch fn.kind { + case vkClosure: + panic("todo") + case vkFuncDecl, vkFuncPtr: + sig := t.(*types.Signature) + ret.Type = b.Prog.retType(sig) default: panic("todo") }