diff --git a/cl/_testgo/defer/in.go b/cl/_testgo/defer/in.go index b66b5444..82d34e31 100644 --- a/cl/_testgo/defer/in.go +++ b/cl/_testgo/defer/in.go @@ -4,24 +4,15 @@ func f(s string) bool { return len(s) > 2 } -func fail() { - panic("error") -} - func main() { defer func() { println("hi") - /* - if e := recover(); e != nil { - println(e.(string)) - } - */ }() if s := "hello"; f(s) { defer println(s) } else { defer println("world") - fail() + return } defer println("bye") } diff --git a/cl/_testgo/defer/out.ll b/cl/_testgo/defer/out.ll index 6ef57dab..d7649276 100644 --- a/cl/_testgo/defer/out.ll +++ b/cl/_testgo/defer/out.ll @@ -2,20 +2,17 @@ source_filename = "main" %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } -%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr } %"github.com/goplus/llgo/internal/runtime.Defer" = type { { ptr, ptr }, i64, ptr, i64 } @"main.init$guard" = global ptr null -@0 = private unnamed_addr constant [6 x i8] c"error\00", align 1 -@_llgo_string = linkonce global ptr null @__llgo_argc = global ptr null @__llgo_argv = global ptr null @__llgo_defer = linkonce global ptr null +@0 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 @1 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 -@2 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 -@3 = private unnamed_addr constant [4 x i8] c"bye\00", align 1 -@4 = private unnamed_addr constant [6 x i8] c"world\00", align 1 -@5 = private unnamed_addr constant [3 x i8] c"hi\00", align 1 +@2 = private unnamed_addr constant [4 x i8] c"bye\00", align 1 +@3 = private unnamed_addr constant [6 x i8] c"world\00", align 1 +@4 = private unnamed_addr constant [3 x i8] c"hi\00", align 1 define i1 @main.f(%"github.com/goplus/llgo/internal/runtime.String" %0) { _llgo_0: @@ -24,27 +21,6 @@ _llgo_0: ret i1 %2 } -define void @main.fail() { -_llgo_0: - %0 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %1 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i32 0, i32 0 - store ptr @0, ptr %1, align 8 - %2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i32 0, i32 1 - store i64 5, ptr %2, align 4 - %3 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %0, align 8 - %4 = load ptr, ptr @_llgo_string, align 8 - %5 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) - store %"github.com/goplus/llgo/internal/runtime.String" %3, ptr %5, align 8 - %6 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 - %7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %6, i32 0, i32 0 - store ptr %4, ptr %7, align 8 - %8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %6, i32 0, i32 1 - store ptr %5, ptr %8, align 8 - %9 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %6, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %9) - unreachable -} - define void @main.init() { _llgo_0: %0 = load i1, ptr @"main.init$guard", align 1 @@ -82,12 +58,12 @@ _llgo_0: store i64 %12, ptr %9, align 4 %13 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %14 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %13, i32 0, i32 0 - store ptr @1, ptr %14, align 8 + store ptr @0, ptr %14, align 8 %15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %13, i32 0, i32 1 store i64 5, ptr %15, align 4 %16 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %13, align 8 %17 = call i1 @main.f(%"github.com/goplus/llgo/internal/runtime.String" %16) - br i1 %17, label %_llgo_2, label %_llgo_4 + br i1 %17, label %_llgo_2, label %_llgo_3 _llgo_1: ; No predecessors! ret i32 0 @@ -95,19 +71,16 @@ _llgo_1: ; No predecessors! _llgo_2: ; preds = %_llgo_0 %18 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %18, i32 0, i32 0 - store ptr @2, ptr %19, align 8 + store ptr @1, ptr %19, align 8 %20 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %18, i32 0, i32 1 store i64 5, ptr %20, align 4 %21 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %18, align 8 %22 = load i64, ptr %9, align 4 %23 = or i64 %22, 2 store i64 %23, ptr %9, align 4 - br label %_llgo_3 - -_llgo_3: ; preds = %_llgo_4, %_llgo_2 %24 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %25 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %24, i32 0, i32 0 - store ptr @3, ptr %25, align 8 + store ptr @2, ptr %25, align 8 %26 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %24, i32 0, i32 1 store i64 3, ptr %26, align 4 %27 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %24, align 8 @@ -115,36 +88,39 @@ _llgo_3: ; preds = %_llgo_4, %_llgo_2 %29 = or i64 %28, 4 store i64 %29, ptr %9, align 4 store i64 0, ptr %10, align 4 - br label %_llgo_5 + br label %_llgo_4 -_llgo_4: ; preds = %_llgo_0 +_llgo_3: ; preds = %_llgo_0 %30 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %31 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %30, i32 0, i32 0 - store ptr @4, ptr %31, align 8 + store ptr @3, ptr %31, align 8 %32 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %30, i32 0, i32 1 store i64 5, ptr %32, align 4 %33 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %30, align 8 %34 = load i64, ptr %9, align 4 %35 = or i64 %34, 8 store i64 %35, ptr %9, align 4 - call void @main.fail() - br label %_llgo_3 + store i64 1, ptr %10, align 4 + br label %_llgo_4 -_llgo_5: ; preds = %_llgo_3 +_llgo_4: ; preds = %_llgo_3, %_llgo_2 %36 = load i64, ptr %9, align 4 %37 = and i64 %36, 8 %38 = icmp ne i64 %37, 0 br i1 %38, label %_llgo_7, label %_llgo_8 +_llgo_5: ; preds = %_llgo_14 + ret i32 0 + _llgo_6: ; preds = %_llgo_14 ret i32 0 -_llgo_7: ; preds = %_llgo_5 +_llgo_7: ; preds = %_llgo_4 call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %33) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) br label %_llgo_8 -_llgo_8: ; preds = %_llgo_7, %_llgo_5 +_llgo_8: ; preds = %_llgo_7, %_llgo_4 %39 = and i64 %36, 4 %40 = icmp ne i64 %39, 0 br i1 %40, label %_llgo_9, label %_llgo_10 @@ -178,47 +154,18 @@ _llgo_14: ; preds = %_llgo_13, %_llgo_12 %46 = extractvalue %"github.com/goplus/llgo/internal/runtime.Defer" %45, 2 %47 = call i32 @pthread_setspecific(ptr %2, ptr %46) %48 = load i64, ptr %10, align 4 - switch i64 %48, label %_llgo_6 [ + switch i64 %48, label %_llgo_5 [ + i64 1, label %_llgo_6 ] } -define void @"main.init$after"() { -_llgo_0: - %0 = load ptr, ptr @_llgo_string, align 8 - %1 = icmp eq ptr %0, null - br i1 %1, label %_llgo_1, label %_llgo_2 - -_llgo_1: ; preds = %_llgo_0 - %2 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 24) - store ptr %2, ptr @_llgo_string, align 8 - br label %_llgo_2 - -_llgo_2: ; preds = %_llgo_1, %_llgo_0 - %3 = load ptr, ptr @__llgo_defer, align 8 - %4 = icmp eq ptr %3, null - br i1 %4, label %_llgo_3, label %_llgo_4 - -_llgo_3: ; preds = %_llgo_2 - %5 = call i32 @pthread_key_create(ptr @__llgo_defer, ptr null) - br label %_llgo_4 - -_llgo_4: ; preds = %_llgo_3, %_llgo_2 - ret void -} - -declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64) - -declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64) - -declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface") - declare void @"github.com/goplus/llgo/internal/runtime.init"() define void @"main.main$1"() { _llgo_0: %0 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %1 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i32 0, i32 0 - store ptr @5, ptr %1, align 8 + store ptr @4, ptr %1, align 8 %2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i32 0, i32 1 store i64 2, ptr %2, align 4 %3 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %0, align 8 @@ -235,4 +182,18 @@ declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8) +define void @"main.init$after"() { +_llgo_0: + %0 = load ptr, ptr @__llgo_defer, align 8 + %1 = icmp eq ptr %0, null + br i1 %1, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %2 = call i32 @pthread_key_create(ptr @__llgo_defer, ptr null) + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + declare i32 @pthread_key_create(ptr, ptr) diff --git a/ssa/decl.go b/ssa/decl.go index 8abe0339..889f5aa1 100644 --- a/ssa/decl.go +++ b/ssa/decl.go @@ -247,10 +247,12 @@ func newParams(fn Type, prog Program) (params []Type, hasVArg bool) { return } +/* // Name returns the function's name. func (p Function) Name() string { return p.impl.Name() } +*/ // Params returns the function's ith parameter. func (p Function) Param(i int) Expr { diff --git a/ssa/package.go b/ssa/package.go index 98e471b6..e96a595d 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -131,14 +131,14 @@ type aProgram struct { rtSliceTy llvm.Type rtMapTy llvm.Type - anyTy Type - voidTy Type - voidPtr Type - voidPPtr Type - boolTy Type - cstrTy Type - cintTy Type - cintPtr Type + anyTy Type + voidTy Type + voidPtr Type + voidPPtr Type + boolTy Type + cstrTy Type + cintTy Type + //cintPtr Type stringTy Type uintptrTy Type intTy Type @@ -444,6 +444,7 @@ func (p Program) Any() Type { return p.anyTy } +/* // Eface returns the empty interface type. // It is equivalent to Any. func (p Program) Eface() Type { @@ -457,6 +458,7 @@ func (p Program) CIntPtr() Type { } return p.cintPtr } +*/ // CInt returns c.Int type. func (p Program) CInt() Type { @@ -649,13 +651,13 @@ func (p Package) afterBuilder() Builder { // AfterInit is called after the package is initialized (init all packages that depends on). func (p Package) AfterInit(b Builder, ret BasicBlock) { + p.deferInit() doAfterb := p.afterb != nil doPyLoadModSyms := p.pyHasModSyms() if doAfterb || doPyLoadModSyms { b.SetBlockEx(ret, afterInit, false) if doAfterb { afterb := Builder(p.afterb) - p.deferInit(afterb) afterb.Return() b.Call(afterb.Func.Expr) } diff --git a/ssa/ssa_test.go b/ssa/ssa_test.go index f861fb97..b9ef006d 100644 --- a/ssa/ssa_test.go +++ b/ssa/ssa_test.go @@ -27,6 +27,16 @@ import ( "github.com/goplus/llvm" ) +func TestEndDefer(t *testing.T) { + prog := NewProgram(nil) + pkg := prog.NewPackage("foo", "foo") + sigMain := types.NewSignatureType(nil, nil, nil, nil, nil, false) + fn := pkg.NewFunc("main", sigMain, InC) + b := fn.MakeBody(1) + fn.defer_ = &aDefer{} + fn.endDefer(b) +} + func TestUnsafeString(t *testing.T) { prog := NewProgram(nil) prog.SetRuntime(func() *types.Package { @@ -187,6 +197,7 @@ func TestVar(t *testing.T) { if pkg.NewVar("a", types.Typ[types.Int], InGo) != a { t.Fatal("NewVar(a) failed") } + pkg.NewVarEx("a", prog.Type(types.Typ[types.Int], InGo)) a.Init(prog.Val(100)) b := pkg.NewVar("b", types.Typ[types.Int], InGo) b.Init(a.Expr) diff --git a/ssa/stmt_builder.go b/ssa/stmt_builder.go index 17449b86..36da0a9d 100644 --- a/ssa/stmt_builder.go +++ b/ssa/stmt_builder.go @@ -163,7 +163,7 @@ func (p Program) tyDeferFunc() *types.Signature { } */ -func (p Package) deferInit(b Builder) { +func (p Package) deferInit() { keyVar := p.VarOf(deferKey) if keyVar == nil { return @@ -173,6 +173,7 @@ func (p Package) deferInit(b Builder) { keyVar.Init(keyNil) keyVar.impl.SetLinkage(llvm.LinkOnceAnyLinkage) + b := p.afterBuilder() eq := b.BinOp(token.EQL, b.Load(keyVar.Expr), keyNil) b.IfThen(eq, func() { b.pthreadKeyCreate(keyVar.Expr, prog.Null(prog.VoidPtr()))