Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions chore/litgen/litgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ import (
"github.com/goplus/llgo/xtool/env/llvm"
)

var escapeChecks bool

func main() {
llvm.SetupPath()
flag.BoolVar(&escapeChecks, "escape", false, "generate checks after escape analysis")
flag.Usage = func() {
fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s <file-or-dir> [<file-or-dir>...]\n", filepath.Base(os.Args[0]))
flag.PrintDefaults()
Expand Down
3 changes: 3 additions & 0 deletions chore/litgen/rewrite.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ func genIR(target string) (ret string, err error) {
}
}
}()
if escapeChecks {
return llgen.GenFromWithEscape(target), nil
}
return llgen.GenFrom(target), nil
}

Expand Down
23 changes: 23 additions & 0 deletions cl/_testdata/print/in.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,29 @@ type stringStruct struct {
// CHECK-NEXT: ret %"{{.*}}/runtime/internal/runtime.Slice" %13
// CHECK-NEXT: }

// ESCAPE-LABEL: define %"{{.*}}/runtime/internal/runtime.Slice" @main.bytes(%"{{.*}}/runtime/internal/runtime.String" %0){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %1 = call ptr @"{{.*}}/runtime/internal/runtime.AllocZ"(i64 16)
// ESCAPE-NEXT: store %"{{.*}}/runtime/internal/runtime.String" %0, ptr %1, align 8
// ESCAPE-NEXT: %.stack = alloca i8, i64 24, align 8
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 24, i1 false)
// ESCAPE-NEXT: %2 = call ptr @main.stringStructOf(ptr %1)
// ESCAPE-NEXT: %3 = getelementptr inbounds %main.stringStruct, ptr %2, i32 0, i32 0
// ESCAPE-NEXT: %4 = load ptr, ptr %3, align 8
// ESCAPE-NEXT: %5 = getelementptr inbounds %main.slice, ptr %.stack, i32 0, i32 0
// ESCAPE-NEXT: store ptr %4, ptr %5, align 8
// ESCAPE-NEXT: %6 = getelementptr inbounds %main.stringStruct, ptr %2, i32 0, i32 1
// ESCAPE-NEXT: %7 = load i64, ptr %6, align 8
// ESCAPE-NEXT: %8 = getelementptr inbounds %main.slice, ptr %.stack, i32 0, i32 1
// ESCAPE-NEXT: store i64 %7, ptr %8, align 8
// ESCAPE-NEXT: %9 = getelementptr inbounds %main.stringStruct, ptr %2, i32 0, i32 1
// ESCAPE-NEXT: %10 = load i64, ptr %9, align 8
// ESCAPE-NEXT: %11 = getelementptr inbounds %main.slice, ptr %.stack, i32 0, i32 2
// ESCAPE-NEXT: store i64 %10, ptr %11, align 8
// ESCAPE-NEXT: %12 = load %"{{.*}}/runtime/internal/runtime.Slice", ptr %.stack, align 8
// ESCAPE-NEXT: ret %"{{.*}}/runtime/internal/runtime.Slice" %12
// ESCAPE-NEXT: }

func bytes(s string) (ret []byte) {
rp := (*slice)(unsafe.Pointer(&ret))
sp := stringStructOf(&s)
Expand Down
21 changes: 21 additions & 0 deletions cl/_testgo/alias/in.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,27 @@ func (p *Point) Scale(factor float64) {
p.y *= factor
}

// ESCAPE-LABEL: define void @main.main(){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 16, align 8
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 16, i1 false)
// ESCAPE-NEXT: %0 = getelementptr inbounds %main.Point, ptr %.stack, i32 0, i32 0
// ESCAPE-NEXT: %1 = getelementptr inbounds %main.Point, ptr %.stack, i32 0, i32 1
// ESCAPE-NEXT: store double 1.000000e+00, ptr %0, align 8
// ESCAPE-NEXT: store double 2.000000e+00, ptr %1, align 8
// ESCAPE-NEXT: call void @"main.(*Point).Scale"(ptr %.stack, double 2.000000e+00)
// ESCAPE-NEXT: call void @"main.(*Point).Move"(ptr %.stack, double 3.000000e+00, double 4.000000e+00)
// ESCAPE-NEXT: %2 = getelementptr inbounds %main.Point, ptr %.stack, i32 0, i32 0
// ESCAPE-NEXT: %3 = load double, ptr %2, align 8
// ESCAPE-NEXT: %4 = getelementptr inbounds %main.Point, ptr %.stack, i32 0, i32 1
// ESCAPE-NEXT: %5 = load double, ptr %4, align 8
// ESCAPE-NEXT: call void @"{{.*}}/runtime/internal/runtime.PrintFloat"(double %3)
// ESCAPE-NEXT: call void @"{{.*}}/runtime/internal/runtime.PrintByte"(i8 32)
// ESCAPE-NEXT: call void @"{{.*}}/runtime/internal/runtime.PrintFloat"(double %5)
// ESCAPE-NEXT: call void @"{{.*}}/runtime/internal/runtime.PrintByte"(i8 10)
// ESCAPE-NEXT: ret void
// ESCAPE-NEXT: }

// CHECK-LABEL: define void @main.main(){{.*}} {
func main() {
// CHECK: call ptr @"{{.*}}AllocZ"(i64 16)
Expand Down
60 changes: 60 additions & 0 deletions cl/_testgo/cgobasic/cgobasic.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,66 @@ import (
// CHECK-NEXT: ret double %4
// CHECK-NEXT: }

// ESCAPE-LABEL: define double @main._Cfunc_cos(double %0){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %1 = load ptr, ptr @main._cgo_{{.*}}_Cfunc_cos, align 8
// ESCAPE-NEXT: %2 = load ptr, ptr %1, align 8
// ESCAPE-NEXT: %3 = call double %2(double %0)
// ESCAPE-NEXT: ret double %3
// ESCAPE-NEXT: }

// ESCAPE-LABEL: define [0 x i8] @main._Cfunc_free(ptr %0){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %1 = load ptr, ptr @main._cgo_{{.*}}_Cfunc_free, align 8
// ESCAPE-NEXT: %2 = load ptr, ptr %1, align 8
// ESCAPE-NEXT: %3 = call [0 x i8] %2(ptr %0)
// ESCAPE-NEXT: ret [0 x i8] %3
// ESCAPE-NEXT: }

// ESCAPE-LABEL: define double @main._Cfunc_log(double %0){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %1 = load ptr, ptr @main._cgo_{{.*}}_Cfunc_log, align 8
// ESCAPE-NEXT: %2 = load ptr, ptr %1, align 8
// ESCAPE-NEXT: %3 = call double %2(double %0)
// ESCAPE-NEXT: ret double %3
// ESCAPE-NEXT: }

// ESCAPE-LABEL: define i32 @main._Cfunc_puts(ptr %0){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %1 = load ptr, ptr @main._cgo_{{.*}}_Cfunc_puts, align 8
// ESCAPE-NEXT: %2 = load ptr, ptr %1, align 8
// ESCAPE-NEXT: %3 = call i32 %2(ptr %0)
// ESCAPE-NEXT: ret i32 %3
// ESCAPE-NEXT: }

// ESCAPE-LABEL: define double @main._Cfunc_sin(double %0){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %1 = load ptr, ptr @main._cgo_{{.*}}_Cfunc_sin, align 8
// ESCAPE-NEXT: %2 = load ptr, ptr %1, align 8
// ESCAPE-NEXT: %3 = call double %2(double %0)
// ESCAPE-NEXT: ret double %3
// ESCAPE-NEXT: }

// ESCAPE-LABEL: define double @main._Cfunc_sqrt(double %0){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %1 = load ptr, ptr @main._cgo_{{.*}}_Cfunc_sqrt, align 8
// ESCAPE-NEXT: %2 = load ptr, ptr %1, align 8
// ESCAPE-NEXT: %3 = call double %2(double %0)
// ESCAPE-NEXT: ret double %3
// ESCAPE-NEXT: }

// CHECK-LABEL: define void @main.init(){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %0 = load i1, ptr @"main.init$guard", align 1
Expand Down
10 changes: 10 additions & 0 deletions cl/_testgo/cgocfiles/cgocfiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ import "fmt"
// CHECK-NEXT: ret i32 %8
// CHECK-NEXT: }

// ESCAPE-LABEL: define i32 @main._Cfunc_test_structs(ptr %0, ptr %1, ptr %2, ptr %3, ptr %4){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %5 = load ptr, ptr @main._cgo_{{.*}}_Cfunc_test_structs, align 8
// ESCAPE-NEXT: %6 = load ptr, ptr %5, align 8
// ESCAPE-NEXT: %7 = call i32 %6(ptr %0, ptr %1, ptr %2, ptr %3, ptr %4)
// ESCAPE-NEXT: ret i32 %7
// ESCAPE-NEXT: }

// CHECK-LABEL: define void @main.main(){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %0 = call ptr @"{{.*}}/runtime/internal/runtime.AllocZ"(i64 4)
Expand Down
10 changes: 10 additions & 0 deletions cl/_testgo/cgodefer/cgodefer.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ import "C"
// CHECK-NEXT: ret [0 x i8] %4
// CHECK-NEXT: }

// ESCAPE-LABEL: define [0 x i8] @main._Cfunc_free(ptr %0){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %1 = load ptr, ptr @main._cgo_{{.*}}_Cfunc_free, align 8
// ESCAPE-NEXT: %2 = load ptr, ptr %1, align 8
// ESCAPE-NEXT: %3 = call [0 x i8] %2(ptr %0)
// ESCAPE-NEXT: ret [0 x i8] %3
// ESCAPE-NEXT: }

// CHECK-LABEL: define void @main.main(){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %0 = call ptr @"{{.*}}/runtime/internal/runtime.AllocZ"(i64 8)
Expand Down
56 changes: 56 additions & 0 deletions cl/_testgo/cgomacro/cgomacro.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,62 @@ import (
// CHECK-NEXT: ret ptr %2
// CHECK-NEXT: }

// ESCAPE-LABEL: define i32 @main._Cfunc_PyObject_Print(ptr %0, ptr %1, i32 %2){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %3 = load ptr, ptr @main._cgo_{{.*}}_Cfunc_PyObject_Print, align 8
// ESCAPE-NEXT: %4 = load ptr, ptr %3, align 8
// ESCAPE-NEXT: %5 = call i32 %4(ptr %0, ptr %1, i32 %2)
// ESCAPE-NEXT: ret i32 %5
// ESCAPE-NEXT: }

// ESCAPE-LABEL: define i32 @main._Cfunc_fputs(ptr %0, ptr %1){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %2 = load ptr, ptr @main._cgo_{{.*}}_Cfunc_fputs, align 8
// ESCAPE-NEXT: %3 = load ptr, ptr %2, align 8
// ESCAPE-NEXT: %4 = call i32 %3(ptr %0, ptr %1)
// ESCAPE-NEXT: ret i32 %4
// ESCAPE-NEXT: }

// ESCAPE-LABEL: define ptr @main._Cmacro_Py_False(){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %0 = load ptr, ptr @main._cgo_{{.*}}_Cmacro_Py_False, align 8
// ESCAPE-NEXT: %1 = load ptr, ptr %0, align 8
// ESCAPE-NEXT: ret ptr %1
// ESCAPE-NEXT: }

// ESCAPE-LABEL: define ptr @main._Cmacro_Py_None(){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %0 = load ptr, ptr @main._cgo_{{.*}}_Cmacro_Py_None, align 8
// ESCAPE-NEXT: %1 = load ptr, ptr %0, align 8
// ESCAPE-NEXT: ret ptr %1
// ESCAPE-NEXT: }

// ESCAPE-LABEL: define ptr @main._Cmacro_Py_True(){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %0 = load ptr, ptr @main._cgo_{{.*}}_Cmacro_Py_True, align 8
// ESCAPE-NEXT: %1 = load ptr, ptr %0, align 8
// ESCAPE-NEXT: ret ptr %1
// ESCAPE-NEXT: }

// ESCAPE-LABEL: define ptr @main._Cmacro_stdout(){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %0 = load ptr, ptr @main._cgo_{{.*}}_Cmacro_stdout, align 8
// ESCAPE-NEXT: %1 = load ptr, ptr %0, align 8
// ESCAPE-NEXT: ret ptr %1
// ESCAPE-NEXT: }

// CHECK-LABEL: define void @main.init(){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %0 = load i1, ptr @"main.init$guard", align 1
Expand Down
10 changes: 10 additions & 0 deletions cl/_testgo/cgopython/cgopython.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ import "C"
// CHECK-NEXT: ret i32 %4
// CHECK-NEXT: }

// ESCAPE-LABEL: define i32 @main._Cfunc_PyRun_SimpleString(ptr %0){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 1
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %1 = load ptr, ptr @main._cgo_{{.*}}_Cfunc_PyRun_SimpleString, align 8
// ESCAPE-NEXT: %2 = load ptr, ptr %1, align 8
// ESCAPE-NEXT: %3 = call i32 %2(ptr %0)
// ESCAPE-NEXT: ret i32 %3
// ESCAPE-NEXT: }

// CHECK-LABEL: define [0 x i8] @main._Cfunc_Py_Finalize(){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %0 = load ptr, ptr @main._cgo_{{.*}}_Cfunc_Py_Finalize, align 8
Expand Down
10 changes: 10 additions & 0 deletions cl/_testgo/cursor/in.go
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,16 @@ const (
// CHECK-NEXT: ret void
// CHECK-NEXT: }

// ESCAPE-LABEL: define void @main.main(){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 16, align 8
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 16, i1 false)
// ESCAPE-NEXT: %0 = getelementptr inbounds %main.Cursor, ptr %.stack, i32 0, i32 0
// ESCAPE-NEXT: %1 = call ptr @"{{.*}}/runtime/internal/runtime.AllocZ"(i64 24)
// ESCAPE-NEXT: store ptr %1, ptr %0, align 8
// ESCAPE-NEXT: ret void
// ESCAPE-NEXT: }

// CHECK-LABEL: define i64 @main.maskOf(%"{{.*}}/runtime/internal/runtime.Slice" %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %1 = extractvalue %"{{.*}}/runtime/internal/runtime.Slice" %0, 1
Expand Down
12 changes: 12 additions & 0 deletions cl/_testgo/returnorder/in.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ func main() {
// CHECK-NEXT: %4 = insertvalue { %main.state, i64 } undef, %main.state %3, 0
// CHECK-NEXT: %5 = insertvalue { %main.state, i64 } %4, i64 %2, 1
// CHECK-NEXT: ret { %main.state, i64 } %5
// ESCAPE-LABEL: define { %main.state, i64 } @main.returnStateAndMut(){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 8, align 8
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 8, i1 false)
// ESCAPE-NEXT: %0 = getelementptr inbounds %main.state, ptr %.stack, i32 0, i32 0
// ESCAPE-NEXT: store i64 1, ptr %0, align 8
// ESCAPE-NEXT: %1 = call i64 @"main.(*state).mutate"(ptr %.stack, i64 2)
// ESCAPE-NEXT: %2 = load %main.state, ptr %.stack, align 8
// ESCAPE-NEXT: %3 = insertvalue { %main.state, i64 } undef, %main.state %2, 0
// ESCAPE-NEXT: %4 = insertvalue { %main.state, i64 } %3, i64 %1, 1
// ESCAPE-NEXT: ret { %main.state, i64 } %4
// ESCAPE-NEXT: }
func returnStateAndMut() (state, int) {
x := state{v: 1}
return x, x.mutate(2)
Expand Down
19 changes: 19 additions & 0 deletions cl/_testgo/tprecurfn/in.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@ type My[T any] struct {
next *My[T]
}

// ESCAPE-LABEL: define void @main.main(){{.*}} {
// ESCAPE-NEXT: _llgo_0:
// ESCAPE-NEXT: %.stack = alloca i8, i64 24, align 8
// ESCAPE-NEXT: call void @llvm.memset.p0.i64(ptr %.stack, i8 0, i64 24, i1 false)
// ESCAPE-NEXT: %0 = getelementptr inbounds %"main.My[int]", ptr %.stack, i32 0, i32 1
// ESCAPE-NEXT: %1 = call ptr @"{{.*}}/runtime/internal/runtime.AllocZ"(i64 24)
// ESCAPE-NEXT: %2 = getelementptr inbounds %"main.My[int]", ptr %1, i32 0, i32 0
// ESCAPE-NEXT: store { ptr, ptr } { ptr @"__llgo_stub.main.main$1", ptr null }, ptr %2, align 8
// ESCAPE-NEXT: store ptr %1, ptr %0, align 8
// ESCAPE-NEXT: %3 = getelementptr inbounds %"main.My[int]", ptr %.stack, i32 0, i32 1
// ESCAPE-NEXT: %4 = load ptr, ptr %3, align 8
// ESCAPE-NEXT: %5 = getelementptr inbounds %"main.My[int]", ptr %4, i32 0, i32 0
// ESCAPE-NEXT: %6 = load { ptr, ptr }, ptr %5, align 8
// ESCAPE-NEXT: %7 = extractvalue { ptr, ptr } %6, 1
// ESCAPE-NEXT: %8 = extractvalue { ptr, ptr } %6, 0
// ESCAPE-NEXT: call void %8(ptr %7, i64 100)
// ESCAPE-NEXT: ret void
// ESCAPE-NEXT: }

// CHECK-LABEL: define void @main.main(){{.*}} {
func main() {
// CHECK: %0 = call ptr @"{{.*}}/runtime/internal/runtime.AllocZ"(i64 24)
Expand Down
Loading
Loading