150
cl/_testrt/qsortfn/in.go
Normal file
150
cl/_testrt/qsortfn/in.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
q "github.com/goplus/llgo/cl/internal/qsort"
|
||||
)
|
||||
|
||||
// llgo:type C
|
||||
type Comp func(a, b c.Pointer) c.Int
|
||||
|
||||
//go:linkname qsort C.qsort
|
||||
func qsort(base c.Pointer, count, elem uintptr, compar Comp)
|
||||
|
||||
//go:linkname qsort2 C.qsort
|
||||
func qsort2(base c.Pointer, count, elem uintptr, compar func(a, b c.Pointer) c.Int)
|
||||
|
||||
func main() {
|
||||
sort1a()
|
||||
sort1b()
|
||||
sort2a()
|
||||
sort2b()
|
||||
sort3a()
|
||||
sort3b()
|
||||
sort4a()
|
||||
sort4b()
|
||||
sort5a()
|
||||
sort5b()
|
||||
}
|
||||
|
||||
func sort1a() {
|
||||
c.Printf(c.Str("Comp => Comp\n"))
|
||||
a := [...]int{100, 8, 23, 2, 7}
|
||||
var fn Comp = func(a, b c.Pointer) c.Int {
|
||||
return c.Int(*(*int)(a) - *(*int)(b))
|
||||
}
|
||||
qsort(c.Pointer(&a[0]), 5, unsafe.Sizeof(0), fn)
|
||||
for _, v := range a {
|
||||
c.Printf(c.Str("%d\n"), v)
|
||||
}
|
||||
}
|
||||
|
||||
func sort1b() {
|
||||
c.Printf(c.Str("fn => Comp\n"))
|
||||
a := [...]int{100, 8, 23, 2, 7}
|
||||
var fn = func(a, b c.Pointer) c.Int {
|
||||
return c.Int(*(*int)(a) - *(*int)(b))
|
||||
}
|
||||
qsort(c.Pointer(&a[0]), 5, unsafe.Sizeof(0), fn)
|
||||
for _, v := range a {
|
||||
c.Printf(c.Str("%d\n"), v)
|
||||
}
|
||||
}
|
||||
|
||||
func sort2a() {
|
||||
c.Printf(c.Str("Comp => fn\n"))
|
||||
a := [...]int{100, 8, 23, 2, 7}
|
||||
var fn Comp = func(a, b c.Pointer) c.Int {
|
||||
return c.Int(*(*int)(a) - *(*int)(b))
|
||||
}
|
||||
qsort2(c.Pointer(&a[0]), 5, unsafe.Sizeof(0), fn)
|
||||
for _, v := range a {
|
||||
c.Printf(c.Str("%d\n"), v)
|
||||
}
|
||||
}
|
||||
|
||||
func sort2b() {
|
||||
c.Printf(c.Str("fn => fn\n"))
|
||||
a := [...]int{100, 8, 23, 2, 7}
|
||||
var fn = func(a, b c.Pointer) c.Int {
|
||||
return c.Int(*(*int)(a) - *(*int)(b))
|
||||
}
|
||||
qsort2(c.Pointer(&a[0]), 5, unsafe.Sizeof(0), fn)
|
||||
for _, v := range a {
|
||||
c.Printf(c.Str("%d\n"), v)
|
||||
}
|
||||
}
|
||||
|
||||
func sort3a() {
|
||||
c.Printf(c.Str("qsort.Comp => qsort.Comp\n"))
|
||||
a := [...]int{100, 8, 23, 2, 7}
|
||||
var fn q.Comp = func(a, b c.Pointer) c.Int {
|
||||
return c.Int(*(*int)(a) - *(*int)(b))
|
||||
}
|
||||
q.Qsort(c.Pointer(&a[0]), 5, unsafe.Sizeof(0), fn)
|
||||
for _, v := range a {
|
||||
c.Printf(c.Str("%d\n"), v)
|
||||
}
|
||||
}
|
||||
|
||||
func sort3b() {
|
||||
c.Printf(c.Str("fn => qsort.Comp\n"))
|
||||
a := [...]int{100, 8, 23, 2, 7}
|
||||
var fn = func(a, b c.Pointer) c.Int {
|
||||
return c.Int(*(*int)(a) - *(*int)(b))
|
||||
}
|
||||
q.Qsort(c.Pointer(&a[0]), 5, unsafe.Sizeof(0), fn)
|
||||
for _, v := range a {
|
||||
c.Printf(c.Str("%d\n"), v)
|
||||
}
|
||||
}
|
||||
|
||||
func sort4a() {
|
||||
c.Printf(c.Str("qsort.Comp => fn\n"))
|
||||
a := [...]int{100, 8, 23, 2, 7}
|
||||
var fn q.Comp = func(a, b c.Pointer) c.Int {
|
||||
return c.Int(*(*int)(a) - *(*int)(b))
|
||||
}
|
||||
qsort2(c.Pointer(&a[0]), 5, unsafe.Sizeof(0), fn)
|
||||
for _, v := range a {
|
||||
c.Printf(c.Str("%d\n"), v)
|
||||
}
|
||||
}
|
||||
|
||||
func sort4b() {
|
||||
c.Printf(c.Str("Comp => qsort.fn\n"))
|
||||
a := [...]int{100, 8, 23, 2, 7}
|
||||
var fn Comp = func(a, b c.Pointer) c.Int {
|
||||
return c.Int(*(*int)(a) - *(*int)(b))
|
||||
}
|
||||
q.Qsort2(c.Pointer(&a[0]), 5, unsafe.Sizeof(0), fn)
|
||||
for _, v := range a {
|
||||
c.Printf(c.Str("%d\n"), v)
|
||||
}
|
||||
}
|
||||
|
||||
func sort5a() {
|
||||
c.Printf(c.Str("qsort.Comp => Comp()\n"))
|
||||
a := [...]int{100, 8, 23, 2, 7}
|
||||
var fn q.Comp = func(a, b c.Pointer) c.Int {
|
||||
return c.Int(*(*int)(a) - *(*int)(b))
|
||||
}
|
||||
qsort(c.Pointer(&a[0]), 5, unsafe.Sizeof(0), Comp(fn))
|
||||
for _, v := range a {
|
||||
c.Printf(c.Str("%d\n"), v)
|
||||
}
|
||||
}
|
||||
|
||||
func sort5b() {
|
||||
c.Printf(c.Str("Comp => qsort.Comp()\n"))
|
||||
a := [...]int{100, 8, 23, 2, 7}
|
||||
var fn Comp = func(a, b c.Pointer) c.Int {
|
||||
return c.Int(*(*int)(a) - *(*int)(b))
|
||||
}
|
||||
q.Qsort(c.Pointer(&a[0]), 5, unsafe.Sizeof(0), q.Comp(fn))
|
||||
for _, v := range a {
|
||||
c.Printf(c.Str("%d\n"), v)
|
||||
}
|
||||
}
|
||||
596
cl/_testrt/qsortfn/out.ll
Normal file
596
cl/_testrt/qsortfn/out.ll
Normal file
@@ -0,0 +1,596 @@
|
||||
; ModuleID = 'main'
|
||||
source_filename = "main"
|
||||
|
||||
@"main.init$guard" = global i1 false, align 1
|
||||
@__llgo_argc = global i32 0, align 4
|
||||
@__llgo_argv = global ptr null, align 8
|
||||
@0 = private unnamed_addr constant [14 x i8] c"Comp => Comp\0A\00", align 1
|
||||
@1 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
|
||||
@2 = private unnamed_addr constant [12 x i8] c"fn => Comp\0A\00", align 1
|
||||
@3 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
|
||||
@4 = private unnamed_addr constant [12 x i8] c"Comp => fn\0A\00", align 1
|
||||
@5 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
|
||||
@6 = private unnamed_addr constant [10 x i8] c"fn => fn\0A\00", align 1
|
||||
@7 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
|
||||
@8 = private unnamed_addr constant [26 x i8] c"qsort.Comp => qsort.Comp\0A\00", align 1
|
||||
@9 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
|
||||
@10 = private unnamed_addr constant [18 x i8] c"fn => qsort.Comp\0A\00", align 1
|
||||
@11 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
|
||||
@12 = private unnamed_addr constant [18 x i8] c"qsort.Comp => fn\0A\00", align 1
|
||||
@13 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
|
||||
@14 = private unnamed_addr constant [18 x i8] c"Comp => qsort.fn\0A\00", align 1
|
||||
@15 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
|
||||
@16 = private unnamed_addr constant [22 x i8] c"qsort.Comp => Comp()\0A\00", align 1
|
||||
@17 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
|
||||
@18 = private unnamed_addr constant [22 x i8] c"Comp => qsort.Comp()\0A\00", align 1
|
||||
@19 = private unnamed_addr constant [4 x i8] c"%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 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()
|
||||
call void @main.sort1a()
|
||||
call void @main.sort1b()
|
||||
call void @main.sort2a()
|
||||
call void @main.sort2b()
|
||||
call void @main.sort3a()
|
||||
call void @main.sort3b()
|
||||
call void @main.sort4a()
|
||||
call void @main.sort4b()
|
||||
call void @main.sort5a()
|
||||
call void @main.sort5b()
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define void @main.sort1a() {
|
||||
_llgo_0:
|
||||
%0 = call i32 (ptr, ...) @printf(ptr @0)
|
||||
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 40)
|
||||
%2 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
%3 = getelementptr inbounds i64, ptr %1, i64 1
|
||||
%4 = getelementptr inbounds i64, ptr %1, i64 2
|
||||
%5 = getelementptr inbounds i64, ptr %1, i64 3
|
||||
%6 = getelementptr inbounds i64, ptr %1, i64 4
|
||||
store i64 100, ptr %2, align 4
|
||||
store i64 8, ptr %3, align 4
|
||||
store i64 23, ptr %4, align 4
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %7, i64 5, i64 8, ptr @"main.sort1a$1")
|
||||
%8 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%9 = phi i64 [ -1, %_llgo_0 ], [ %10, %_llgo_2 ]
|
||||
%10 = add i64 %9, 1
|
||||
%11 = icmp slt i64 %10, 5
|
||||
br i1 %11, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%12 = icmp slt i64 %10, 0
|
||||
%13 = icmp sge i64 %10, 5
|
||||
%14 = or i1 %13, %12
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %14)
|
||||
%15 = getelementptr inbounds i64, ptr %1, i64 %10
|
||||
%16 = load i64, ptr %15, align 4
|
||||
%17 = call i32 (ptr, ...) @printf(ptr @1, i64 %16)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @"main.sort1a$1"(ptr %0, ptr %1) {
|
||||
_llgo_0:
|
||||
%2 = load i64, ptr %0, align 4
|
||||
%3 = load i64, ptr %1, align 4
|
||||
%4 = sub i64 %2, %3
|
||||
%5 = trunc i64 %4 to i32
|
||||
ret i32 %5
|
||||
}
|
||||
|
||||
define void @main.sort1b() {
|
||||
_llgo_0:
|
||||
%0 = call i32 (ptr, ...) @printf(ptr @2)
|
||||
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 40)
|
||||
%2 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
%3 = getelementptr inbounds i64, ptr %1, i64 1
|
||||
%4 = getelementptr inbounds i64, ptr %1, i64 2
|
||||
%5 = getelementptr inbounds i64, ptr %1, i64 3
|
||||
%6 = getelementptr inbounds i64, ptr %1, i64 4
|
||||
store i64 100, ptr %2, align 4
|
||||
store i64 8, ptr %3, align 4
|
||||
store i64 23, ptr %4, align 4
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %7, i64 5, i64 8, ptr @"main.sort1b$1")
|
||||
%8 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%9 = phi i64 [ -1, %_llgo_0 ], [ %10, %_llgo_2 ]
|
||||
%10 = add i64 %9, 1
|
||||
%11 = icmp slt i64 %10, 5
|
||||
br i1 %11, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%12 = icmp slt i64 %10, 0
|
||||
%13 = icmp sge i64 %10, 5
|
||||
%14 = or i1 %13, %12
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %14)
|
||||
%15 = getelementptr inbounds i64, ptr %1, i64 %10
|
||||
%16 = load i64, ptr %15, align 4
|
||||
%17 = call i32 (ptr, ...) @printf(ptr @3, i64 %16)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @"main.sort1b$1"(ptr %0, ptr %1) {
|
||||
_llgo_0:
|
||||
%2 = load i64, ptr %0, align 4
|
||||
%3 = load i64, ptr %1, align 4
|
||||
%4 = sub i64 %2, %3
|
||||
%5 = trunc i64 %4 to i32
|
||||
ret i32 %5
|
||||
}
|
||||
|
||||
define void @main.sort2a() {
|
||||
_llgo_0:
|
||||
%0 = call i32 (ptr, ...) @printf(ptr @4)
|
||||
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 40)
|
||||
%2 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
%3 = getelementptr inbounds i64, ptr %1, i64 1
|
||||
%4 = getelementptr inbounds i64, ptr %1, i64 2
|
||||
%5 = getelementptr inbounds i64, ptr %1, i64 3
|
||||
%6 = getelementptr inbounds i64, ptr %1, i64 4
|
||||
store i64 100, ptr %2, align 4
|
||||
store i64 8, ptr %3, align 4
|
||||
store i64 23, ptr %4, align 4
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %7, i64 5, i64 8, ptr @"main.sort2a$1")
|
||||
%8 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%9 = phi i64 [ -1, %_llgo_0 ], [ %10, %_llgo_2 ]
|
||||
%10 = add i64 %9, 1
|
||||
%11 = icmp slt i64 %10, 5
|
||||
br i1 %11, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%12 = icmp slt i64 %10, 0
|
||||
%13 = icmp sge i64 %10, 5
|
||||
%14 = or i1 %13, %12
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %14)
|
||||
%15 = getelementptr inbounds i64, ptr %1, i64 %10
|
||||
%16 = load i64, ptr %15, align 4
|
||||
%17 = call i32 (ptr, ...) @printf(ptr @5, i64 %16)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @"main.sort2a$1"(ptr %0, ptr %1) {
|
||||
_llgo_0:
|
||||
%2 = load i64, ptr %0, align 4
|
||||
%3 = load i64, ptr %1, align 4
|
||||
%4 = sub i64 %2, %3
|
||||
%5 = trunc i64 %4 to i32
|
||||
ret i32 %5
|
||||
}
|
||||
|
||||
define void @main.sort2b() {
|
||||
_llgo_0:
|
||||
%0 = call i32 (ptr, ...) @printf(ptr @6)
|
||||
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 40)
|
||||
%2 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
%3 = getelementptr inbounds i64, ptr %1, i64 1
|
||||
%4 = getelementptr inbounds i64, ptr %1, i64 2
|
||||
%5 = getelementptr inbounds i64, ptr %1, i64 3
|
||||
%6 = getelementptr inbounds i64, ptr %1, i64 4
|
||||
store i64 100, ptr %2, align 4
|
||||
store i64 8, ptr %3, align 4
|
||||
store i64 23, ptr %4, align 4
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %7, i64 5, i64 8, ptr @"main.sort2b$1")
|
||||
%8 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%9 = phi i64 [ -1, %_llgo_0 ], [ %10, %_llgo_2 ]
|
||||
%10 = add i64 %9, 1
|
||||
%11 = icmp slt i64 %10, 5
|
||||
br i1 %11, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%12 = icmp slt i64 %10, 0
|
||||
%13 = icmp sge i64 %10, 5
|
||||
%14 = or i1 %13, %12
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %14)
|
||||
%15 = getelementptr inbounds i64, ptr %1, i64 %10
|
||||
%16 = load i64, ptr %15, align 4
|
||||
%17 = call i32 (ptr, ...) @printf(ptr @7, i64 %16)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @"main.sort2b$1"(ptr %0, ptr %1) {
|
||||
_llgo_0:
|
||||
%2 = load i64, ptr %0, align 4
|
||||
%3 = load i64, ptr %1, align 4
|
||||
%4 = sub i64 %2, %3
|
||||
%5 = trunc i64 %4 to i32
|
||||
ret i32 %5
|
||||
}
|
||||
|
||||
define void @main.sort3a() {
|
||||
_llgo_0:
|
||||
%0 = call i32 (ptr, ...) @printf(ptr @8)
|
||||
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 40)
|
||||
%2 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
%3 = getelementptr inbounds i64, ptr %1, i64 1
|
||||
%4 = getelementptr inbounds i64, ptr %1, i64 2
|
||||
%5 = getelementptr inbounds i64, ptr %1, i64 3
|
||||
%6 = getelementptr inbounds i64, ptr %1, i64 4
|
||||
store i64 100, ptr %2, align 4
|
||||
store i64 8, ptr %3, align 4
|
||||
store i64 23, ptr %4, align 4
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = alloca { ptr, ptr }, align 8
|
||||
%8 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 0
|
||||
store ptr @"__llgo_stub.main.sort3a$1", ptr %8, align 8
|
||||
%9 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 1
|
||||
store ptr null, ptr %9, align 8
|
||||
%10 = load { ptr, ptr }, ptr %7, align 8
|
||||
%11 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %11, i64 5, i64 8, { ptr, ptr } %10)
|
||||
%12 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%13 = phi i64 [ -1, %_llgo_0 ], [ %14, %_llgo_2 ]
|
||||
%14 = add i64 %13, 1
|
||||
%15 = icmp slt i64 %14, 5
|
||||
br i1 %15, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%16 = icmp slt i64 %14, 0
|
||||
%17 = icmp sge i64 %14, 5
|
||||
%18 = or i1 %17, %16
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %18)
|
||||
%19 = getelementptr inbounds i64, ptr %1, i64 %14
|
||||
%20 = load i64, ptr %19, align 4
|
||||
%21 = call i32 (ptr, ...) @printf(ptr @9, i64 %20)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @"main.sort3a$1"(ptr %0, ptr %1) {
|
||||
_llgo_0:
|
||||
%2 = load i64, ptr %0, align 4
|
||||
%3 = load i64, ptr %1, align 4
|
||||
%4 = sub i64 %2, %3
|
||||
%5 = trunc i64 %4 to i32
|
||||
ret i32 %5
|
||||
}
|
||||
|
||||
define void @main.sort3b() {
|
||||
_llgo_0:
|
||||
%0 = call i32 (ptr, ...) @printf(ptr @10)
|
||||
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 40)
|
||||
%2 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
%3 = getelementptr inbounds i64, ptr %1, i64 1
|
||||
%4 = getelementptr inbounds i64, ptr %1, i64 2
|
||||
%5 = getelementptr inbounds i64, ptr %1, i64 3
|
||||
%6 = getelementptr inbounds i64, ptr %1, i64 4
|
||||
store i64 100, ptr %2, align 4
|
||||
store i64 8, ptr %3, align 4
|
||||
store i64 23, ptr %4, align 4
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
%8 = alloca { ptr, ptr }, align 8
|
||||
%9 = getelementptr inbounds { ptr, ptr }, ptr %8, i32 0, i32 0
|
||||
store ptr @"__llgo_stub.main.sort3b$1", ptr %9, align 8
|
||||
%10 = getelementptr inbounds { ptr, ptr }, ptr %8, i32 0, i32 1
|
||||
store ptr null, ptr %10, align 8
|
||||
%11 = load { ptr, ptr }, ptr %8, align 8
|
||||
call void @qsort(ptr %7, i64 5, i64 8, { ptr, ptr } %11)
|
||||
%12 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%13 = phi i64 [ -1, %_llgo_0 ], [ %14, %_llgo_2 ]
|
||||
%14 = add i64 %13, 1
|
||||
%15 = icmp slt i64 %14, 5
|
||||
br i1 %15, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%16 = icmp slt i64 %14, 0
|
||||
%17 = icmp sge i64 %14, 5
|
||||
%18 = or i1 %17, %16
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %18)
|
||||
%19 = getelementptr inbounds i64, ptr %1, i64 %14
|
||||
%20 = load i64, ptr %19, align 4
|
||||
%21 = call i32 (ptr, ...) @printf(ptr @11, i64 %20)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @"main.sort3b$1"(ptr %0, ptr %1) {
|
||||
_llgo_0:
|
||||
%2 = load i64, ptr %0, align 4
|
||||
%3 = load i64, ptr %1, align 4
|
||||
%4 = sub i64 %2, %3
|
||||
%5 = trunc i64 %4 to i32
|
||||
ret i32 %5
|
||||
}
|
||||
|
||||
define void @main.sort4a() {
|
||||
_llgo_0:
|
||||
%0 = call i32 (ptr, ...) @printf(ptr @12)
|
||||
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 40)
|
||||
%2 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
%3 = getelementptr inbounds i64, ptr %1, i64 1
|
||||
%4 = getelementptr inbounds i64, ptr %1, i64 2
|
||||
%5 = getelementptr inbounds i64, ptr %1, i64 3
|
||||
%6 = getelementptr inbounds i64, ptr %1, i64 4
|
||||
store i64 100, ptr %2, align 4
|
||||
store i64 8, ptr %3, align 4
|
||||
store i64 23, ptr %4, align 4
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = alloca { ptr, ptr }, align 8
|
||||
%8 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 0
|
||||
store ptr @"__llgo_stub.main.sort4a$1", ptr %8, align 8
|
||||
%9 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 1
|
||||
store ptr null, ptr %9, align 8
|
||||
%10 = load { ptr, ptr }, ptr %7, align 8
|
||||
%11 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %11, i64 5, i64 8, { ptr, ptr } %10)
|
||||
%12 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%13 = phi i64 [ -1, %_llgo_0 ], [ %14, %_llgo_2 ]
|
||||
%14 = add i64 %13, 1
|
||||
%15 = icmp slt i64 %14, 5
|
||||
br i1 %15, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%16 = icmp slt i64 %14, 0
|
||||
%17 = icmp sge i64 %14, 5
|
||||
%18 = or i1 %17, %16
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %18)
|
||||
%19 = getelementptr inbounds i64, ptr %1, i64 %14
|
||||
%20 = load i64, ptr %19, align 4
|
||||
%21 = call i32 (ptr, ...) @printf(ptr @13, i64 %20)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @"main.sort4a$1"(ptr %0, ptr %1) {
|
||||
_llgo_0:
|
||||
%2 = load i64, ptr %0, align 4
|
||||
%3 = load i64, ptr %1, align 4
|
||||
%4 = sub i64 %2, %3
|
||||
%5 = trunc i64 %4 to i32
|
||||
ret i32 %5
|
||||
}
|
||||
|
||||
define void @main.sort4b() {
|
||||
_llgo_0:
|
||||
%0 = call i32 (ptr, ...) @printf(ptr @14)
|
||||
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 40)
|
||||
%2 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
%3 = getelementptr inbounds i64, ptr %1, i64 1
|
||||
%4 = getelementptr inbounds i64, ptr %1, i64 2
|
||||
%5 = getelementptr inbounds i64, ptr %1, i64 3
|
||||
%6 = getelementptr inbounds i64, ptr %1, i64 4
|
||||
store i64 100, ptr %2, align 4
|
||||
store i64 8, ptr %3, align 4
|
||||
store i64 23, ptr %4, align 4
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %7, i64 5, i64 8, ptr @"main.sort4b$1")
|
||||
%8 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%9 = phi i64 [ -1, %_llgo_0 ], [ %10, %_llgo_2 ]
|
||||
%10 = add i64 %9, 1
|
||||
%11 = icmp slt i64 %10, 5
|
||||
br i1 %11, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%12 = icmp slt i64 %10, 0
|
||||
%13 = icmp sge i64 %10, 5
|
||||
%14 = or i1 %13, %12
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %14)
|
||||
%15 = getelementptr inbounds i64, ptr %1, i64 %10
|
||||
%16 = load i64, ptr %15, align 4
|
||||
%17 = call i32 (ptr, ...) @printf(ptr @15, i64 %16)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @"main.sort4b$1"(ptr %0, ptr %1) {
|
||||
_llgo_0:
|
||||
%2 = load i64, ptr %0, align 4
|
||||
%3 = load i64, ptr %1, align 4
|
||||
%4 = sub i64 %2, %3
|
||||
%5 = trunc i64 %4 to i32
|
||||
ret i32 %5
|
||||
}
|
||||
|
||||
define void @main.sort5a() {
|
||||
_llgo_0:
|
||||
%0 = call i32 (ptr, ...) @printf(ptr @16)
|
||||
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 40)
|
||||
%2 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
%3 = getelementptr inbounds i64, ptr %1, i64 1
|
||||
%4 = getelementptr inbounds i64, ptr %1, i64 2
|
||||
%5 = getelementptr inbounds i64, ptr %1, i64 3
|
||||
%6 = getelementptr inbounds i64, ptr %1, i64 4
|
||||
store i64 100, ptr %2, align 4
|
||||
store i64 8, ptr %3, align 4
|
||||
store i64 23, ptr %4, align 4
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = alloca { ptr, ptr }, align 8
|
||||
%8 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 0
|
||||
store ptr @"__llgo_stub.main.sort5a$1", ptr %8, align 8
|
||||
%9 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 1
|
||||
store ptr null, ptr %9, align 8
|
||||
%10 = load { ptr, ptr }, ptr %7, align 8
|
||||
%11 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %11, i64 5, i64 8, { ptr, ptr } %10)
|
||||
%12 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%13 = phi i64 [ -1, %_llgo_0 ], [ %14, %_llgo_2 ]
|
||||
%14 = add i64 %13, 1
|
||||
%15 = icmp slt i64 %14, 5
|
||||
br i1 %15, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%16 = icmp slt i64 %14, 0
|
||||
%17 = icmp sge i64 %14, 5
|
||||
%18 = or i1 %17, %16
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %18)
|
||||
%19 = getelementptr inbounds i64, ptr %1, i64 %14
|
||||
%20 = load i64, ptr %19, align 4
|
||||
%21 = call i32 (ptr, ...) @printf(ptr @17, i64 %20)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @"main.sort5a$1"(ptr %0, ptr %1) {
|
||||
_llgo_0:
|
||||
%2 = load i64, ptr %0, align 4
|
||||
%3 = load i64, ptr %1, align 4
|
||||
%4 = sub i64 %2, %3
|
||||
%5 = trunc i64 %4 to i32
|
||||
ret i32 %5
|
||||
}
|
||||
|
||||
define void @main.sort5b() {
|
||||
_llgo_0:
|
||||
%0 = call i32 (ptr, ...) @printf(ptr @18)
|
||||
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 40)
|
||||
%2 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
%3 = getelementptr inbounds i64, ptr %1, i64 1
|
||||
%4 = getelementptr inbounds i64, ptr %1, i64 2
|
||||
%5 = getelementptr inbounds i64, ptr %1, i64 3
|
||||
%6 = getelementptr inbounds i64, ptr %1, i64 4
|
||||
store i64 100, ptr %2, align 4
|
||||
store i64 8, ptr %3, align 4
|
||||
store i64 23, ptr %4, align 4
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %7, i64 5, i64 8, ptr @"main.sort5b$1")
|
||||
%8 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%9 = phi i64 [ -1, %_llgo_0 ], [ %10, %_llgo_2 ]
|
||||
%10 = add i64 %9, 1
|
||||
%11 = icmp slt i64 %10, 5
|
||||
br i1 %11, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%12 = icmp slt i64 %10, 0
|
||||
%13 = icmp sge i64 %10, 5
|
||||
%14 = or i1 %13, %12
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %14)
|
||||
%15 = getelementptr inbounds i64, ptr %1, i64 %10
|
||||
%16 = load i64, ptr %15, align 4
|
||||
%17 = call i32 (ptr, ...) @printf(ptr @19, i64 %16)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @"main.sort5b$1"(ptr %0, ptr %1) {
|
||||
_llgo_0:
|
||||
%2 = load i64, ptr %0, align 4
|
||||
%3 = load i64, ptr %1, align 4
|
||||
%4 = sub i64 %2, %3
|
||||
%5 = trunc i64 %4 to i32
|
||||
ret i32 %5
|
||||
}
|
||||
|
||||
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||
|
||||
declare i32 @printf(ptr, ...)
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
|
||||
|
||||
declare void @qsort(ptr, i64, i64, ptr)
|
||||
|
||||
declare void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1)
|
||||
|
||||
define linkonce i32 @"__llgo_stub.main.sort3a$1"(ptr %0, ptr %1, ptr %2) {
|
||||
_llgo_0:
|
||||
%3 = tail call i32 @"main.sort3a$1"(ptr %1, ptr %2)
|
||||
ret i32 %3
|
||||
}
|
||||
|
||||
define linkonce i32 @"__llgo_stub.main.sort3b$1"(ptr %0, ptr %1, ptr %2) {
|
||||
_llgo_0:
|
||||
%3 = tail call i32 @"main.sort3b$1"(ptr %1, ptr %2)
|
||||
ret i32 %3
|
||||
}
|
||||
|
||||
define linkonce i32 @"__llgo_stub.main.sort4a$1"(ptr %0, ptr %1, ptr %2) {
|
||||
_llgo_0:
|
||||
%3 = tail call i32 @"main.sort4a$1"(ptr %1, ptr %2)
|
||||
ret i32 %3
|
||||
}
|
||||
|
||||
define linkonce i32 @"__llgo_stub.main.sort5a$1"(ptr %0, ptr %1, ptr %2) {
|
||||
_llgo_0:
|
||||
%3 = tail call i32 @"main.sort5a$1"(ptr %1, ptr %2)
|
||||
ret i32 %3
|
||||
}
|
||||
48
cl/import.go
48
cl/import.go
@@ -196,6 +196,15 @@ func (p *context) initFiles(pkgPath string, files []*ast.File) {
|
||||
p.collectSkipNames(line)
|
||||
}
|
||||
}
|
||||
case token.TYPE:
|
||||
if len(decl.Specs) == 1 {
|
||||
if hasTypec(decl.Doc) {
|
||||
inPkgName := decl.Specs[0].(*ast.TypeSpec).Name.Name
|
||||
if obj := p.goTyps.Scope().Lookup(inPkgName); obj != nil {
|
||||
p.prog.Type(obj.Type(), llssa.InC)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -544,4 +553,43 @@ func (p *context) initPyModule() {
|
||||
}
|
||||
}
|
||||
|
||||
// ParsePkgSyntax: check llgo:type C
|
||||
func ParsePkgSyntax(prog llssa.Program, pkg *types.Package, files []*ast.File) {
|
||||
for _, file := range files {
|
||||
for _, decl := range file.Decls {
|
||||
switch decl := decl.(type) {
|
||||
case *ast.GenDecl:
|
||||
switch decl.Tok {
|
||||
case token.TYPE:
|
||||
if len(decl.Specs) == 1 {
|
||||
if hasTypec(decl.Doc) {
|
||||
inPkgName := decl.Specs[0].(*ast.TypeSpec).Name.Name
|
||||
if obj := pkg.Scope().Lookup(inPkgName); obj != nil {
|
||||
prog.Type(obj.Type(), llssa.InC)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
llgotypec = "//llgo:type C"
|
||||
llgotypec2 = "// llgo:type C"
|
||||
)
|
||||
|
||||
func hasTypec(doc *ast.CommentGroup) bool {
|
||||
if doc != nil {
|
||||
if n := len(doc.List); n > 0 {
|
||||
line := doc.List[n-1].Text
|
||||
if strings.HasPrefix(line, llgotypec) || strings.HasPrefix(line, llgotypec2) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
20
cl/internal/qsort/qsort.go
Normal file
20
cl/internal/qsort/qsort.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package qsort
|
||||
|
||||
import (
|
||||
_ "unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
)
|
||||
|
||||
const (
|
||||
LLGoPackage = "decl"
|
||||
)
|
||||
|
||||
// llgo:type C
|
||||
type Comp func(a, b c.Pointer) c.Int
|
||||
|
||||
//go:linkname Qsort C.qsort
|
||||
func Qsort(base c.Pointer, count, elem uintptr, compar Comp)
|
||||
|
||||
//go:linkname Qsort2 C.qsort
|
||||
func Qsort2(base c.Pointer, count, elem uintptr, compar func(a, b c.Pointer) c.Int)
|
||||
@@ -247,10 +247,12 @@ func buildAllPkgs(ctx *context, initial []*packages.Package, verbose bool) (pkgs
|
||||
continue
|
||||
}
|
||||
built[pkg.PkgPath] = none{}
|
||||
//parsePkg(ctx, aPkg, verbose)
|
||||
switch kind, param := cl.PkgKindOf(pkg.Types); kind {
|
||||
case cl.PkgDeclOnly:
|
||||
// skip packages that only contain declarations
|
||||
// and set no export file
|
||||
cl.ParsePkgSyntax(ctx.prog, pkg.Types, pkg.Syntax)
|
||||
pkg.ExportFile = ""
|
||||
case cl.PkgLinkIR, cl.PkgLinkExtern, cl.PkgPyModule:
|
||||
if isPkgInLLGo(pkg.PkgPath) {
|
||||
@@ -427,6 +429,7 @@ func buildPkg(ctx *context, aPkg *aPackage, verbose bool) {
|
||||
llssa.SetDebug(llssa.DbgFlagAll)
|
||||
cl.SetDebug(cl.DbgFlagAll)
|
||||
}
|
||||
|
||||
ret, err := cl.NewPackageEx(ctx.prog, ctx.patches, aPkg.SSA, syntax)
|
||||
if showDetail {
|
||||
llssa.SetDebug(0)
|
||||
|
||||
10
ssa/expr.go
10
ssa/expr.go
@@ -704,11 +704,9 @@ func (b Builder) ChangeType(t Type, x Expr) (ret Expr) {
|
||||
if debugInstr {
|
||||
log.Printf("ChangeType %v, %v\n", t.RawType(), x.impl)
|
||||
}
|
||||
typ := t.raw.Type
|
||||
switch t.kind {
|
||||
case vkClosure:
|
||||
ret.impl = checkExpr(x, typ.Underlying(), b).impl
|
||||
default:
|
||||
if t.kind == vkClosure && x.kind == vkFuncDecl {
|
||||
ret.impl = checkExpr(x, t.raw.Type.Underlying(), b).impl
|
||||
} else {
|
||||
ret.impl = x.impl
|
||||
}
|
||||
ret.Type = t
|
||||
@@ -946,7 +944,7 @@ func (b Builder) Call(fn Expr, args ...Expr) (ret Expr) {
|
||||
raw = fn.raw.Type
|
||||
fallthrough
|
||||
case vkFuncPtr:
|
||||
sig = raw.(*types.Signature)
|
||||
sig = raw.Underlying().(*types.Signature)
|
||||
ll = b.Prog.FuncDecl(sig, InC).ll
|
||||
case vkFuncDecl:
|
||||
sig = raw.(*types.Signature)
|
||||
|
||||
Reference in New Issue
Block a user