diff --git a/cl/_testrt/concat/out.ll b/cl/_testrt/concat/out.ll index 764decd6..91d51114 100644 --- a/cl/_testrt/concat/out.ll +++ b/cl/_testrt/concat/out.ll @@ -21,27 +21,30 @@ _llgo_0: br label %_llgo_1 _llgo_1: ; preds = %_llgo_2, %_llgo_0 - %5 = phi ptr [ %3, %_llgo_0 ], [ %14, %_llgo_2 ] - %6 = phi i64 [ %4, %_llgo_0 ], [ %15, %_llgo_2 ] - %7 = phi i64 [ -1, %_llgo_0 ], [ %8, %_llgo_2 ] - %mrv = insertvalue %"github.com/goplus/llgo/internal/runtime.String" poison, ptr %5, 0 - %mrv1 = insertvalue %"github.com/goplus/llgo/internal/runtime.String" %mrv, i64 %6, 1 - ret %"github.com/goplus/llgo/internal/runtime.String" %mrv1 - %8 = add i64 %7, 1 - %9 = icmp slt i64 %8, %1 - br i1 %9, label %_llgo_2, label %_llgo_3 + %5 = phi ptr [ %3, %_llgo_0 ], [ %18, %_llgo_2 ] + %6 = phi i64 [ %4, %_llgo_0 ], [ %19, %_llgo_2 ] + %7 = phi i64 [ -1, %_llgo_0 ], [ %12, %_llgo_2 ] + %8 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %8, i32 0, i32 0 + store ptr %5, ptr %9, align 8 + %10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %8, i32 0, i32 1 + store i64 %6, ptr %10, align 4 + %11 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %8, align 8 + %12 = add i64 %7, 1 + %13 = icmp slt i64 %12, %1 + br i1 %13, label %_llgo_2, label %_llgo_3 _llgo_2: ; preds = %_llgo_1 - %10 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) - %11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %10, i64 %8 - %12 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %11, align 8 - %13 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(void , %"github.com/goplus/llgo/internal/runtime.String" %12) - %14 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %13, 0 - %15 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %13, 1 + %14 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) + %15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %14, i64 %12 + %16 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %15, align 8 + %17 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %11, %"github.com/goplus/llgo/internal/runtime.String" %16) + %18 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %17, 0 + %19 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %17, 1 br label %_llgo_1 _llgo_3: ; preds = %_llgo_1 - ret void + ret %"github.com/goplus/llgo/internal/runtime.String" %11 } define void @main.init() { @@ -86,7 +89,7 @@ declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/gop declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice") -declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.Slice") +declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String") declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64) diff --git a/internal/runtime/llgo_autogen.ll b/internal/runtime/llgo_autogen.ll index cdb2cbde..ce133348 100644 --- a/internal/runtime/llgo_autogen.ll +++ b/internal/runtime/llgo_autogen.ll @@ -265,65 +265,38 @@ _llgo_0: ret i64 %3 } -define %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { +define %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %0, %"github.com/goplus/llgo/internal/runtime.String" %1) { _llgo_0: - %1 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %2 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %3 = 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 - %4 = phi i64 [ 0, %_llgo_0 ], [ %13, %_llgo_2 ] - %5 = phi i64 [ -1, %_llgo_0 ], [ %6, %_llgo_2 ] - %6 = add i64 %5, 1 - %7 = icmp slt i64 %6, %3 - br i1 %7, label %_llgo_2, label %_llgo_3 - -_llgo_2: ; preds = %_llgo_1 - %8 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) - %9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %8, i64 %6 - %10 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %9, align 8 - store %"github.com/goplus/llgo/internal/runtime.String" %10, ptr %2, align 8 - %11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1 - %12 = load i64, ptr %11, align 4 - %13 = add i64 %4, %12 - br label %_llgo_1 - -_llgo_3: ; preds = %_llgo_1 - %14 = call ptr @"github.com/goplus/llgo/internal/runtime.Alloc"(i64 %4) - %15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %1, i32 0, i32 0 - store ptr %14, ptr %15, align 8 - %16 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %1, i32 0, i32 1 - store i64 %4, ptr %16, align 4 - %17 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %18 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) - br label %_llgo_4 - -_llgo_4: ; preds = %_llgo_5, %_llgo_3 - %19 = phi ptr [ %14, %_llgo_3 ], [ %33, %_llgo_5 ] - %20 = phi i64 [ -1, %_llgo_3 ], [ %21, %_llgo_5 ] - %21 = add i64 %20, 1 - %22 = icmp slt i64 %21, %18 - br i1 %22, label %_llgo_5, label %_llgo_6 - -_llgo_5: ; preds = %_llgo_4 - %23 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) - %24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %23, i64 %21 - %25 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %24, align 8 - store %"github.com/goplus/llgo/internal/runtime.String" %25, ptr %17, align 8 - %26 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %17, i32 0, i32 0 - %27 = load ptr, ptr %26, align 8 - %28 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %17, i32 0, i32 1 - %29 = load i64, ptr %28, align 4 - %30 = call ptr @memcpy(ptr %19, ptr %27, i64 %29) - %31 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %17, i32 0, i32 1 - %32 = load i64, ptr %31, align 4 - %33 = getelementptr i8, ptr %19, i64 %32 - br label %_llgo_4 - -_llgo_6: ; preds = %_llgo_4 - %34 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %1, align 8 - ret %"github.com/goplus/llgo/internal/runtime.String" %34 + store %"github.com/goplus/llgo/internal/runtime.String" %0, ptr %2, align 8 + %3 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + store %"github.com/goplus/llgo/internal/runtime.String" %1, ptr %3, align 8 + %4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1 + %5 = load i64, ptr %4, align 4 + %6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %3, i32 0, i32 1 + %7 = load i64, ptr %6, align 4 + %8 = add i64 %5, %7 + %9 = call ptr @"github.com/goplus/llgo/internal/runtime.Alloc"(i64 %8) + %10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 0 + %11 = load ptr, ptr %10, align 8 + %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1 + %13 = load i64, ptr %12, align 4 + %14 = call ptr @memcpy(ptr %9, ptr %11, i64 %13) + %15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1 + %16 = load i64, ptr %15, align 4 + %17 = getelementptr i8, ptr %9, i64 %16 + %18 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %3, i32 0, i32 0 + %19 = load ptr, ptr %18, align 8 + %20 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %3, i32 0, i32 1 + %21 = load i64, ptr %20, align 4 + %22 = call ptr @memcpy(ptr %17, ptr %19, i64 %21) + %23 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %23, i32 0, i32 0 + %25 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %23, i32 0, i32 1 + store ptr %9, ptr %24, align 8 + store i64 %8, ptr %25, align 4 + %26 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %23, align 8 + ret %"github.com/goplus/llgo/internal/runtime.String" %26 } define ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String" %0) { diff --git a/internal/runtime/z_string.go b/internal/runtime/z_string.go index e362da23..e7726c36 100644 --- a/internal/runtime/z_string.go +++ b/internal/runtime/z_string.go @@ -55,20 +55,13 @@ func StringData(s String) unsafe.Pointer { return s.data } -// StringCat concatenates strings. -func StringCat(args ...String) (ret String) { - n := 0 - for _, v := range args { - n += v.len - } +// StringCat concatenates two strings. +func StringCat(a, b String) String { + n := a.len + b.len dest := Alloc(uintptr(n)) - ret.data = dest - ret.len = n - for _, v := range args { - c.Memcpy(dest, v.data, uintptr(v.len)) - dest = c.Advance(dest, v.len) - } - return + c.Memcpy(dest, a.data, uintptr(a.len)) + c.Memcpy(c.Advance(dest, a.len), b.data, uintptr(b.len)) + return String{dest, n} } // ----------------------------------------------------------------------------- diff --git a/ssa/expr.go b/ssa/expr.go index 0c4c52b1..e7486ba9 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -55,8 +55,7 @@ func (v Expr) Do(b Builder) Expr { return vt.t.(delayExprTy)() case vkPhisExpr: e := vt.t.(*phisExprTy) - // TODO(xsw): to check CreateAggregateRet is correct or not - return Expr{b.impl.CreateAggregateRet(e.phis), e.Type} + return b.aggregateValue(e.Type, e.phis...) } return v } @@ -460,6 +459,20 @@ func (b Builder) Store(ptr, val Expr) Builder { return b } +// aggregateValue yields the value of the aggregate X with the fields +func (b Builder) aggregateValue(t Type, flds ...llvm.Value) Expr { + if debugInstr { + log.Printf("AggregateValue %v, %v\n", t, flds) + } + impl := b.impl + tll := t.ll + ptr := llvm.CreateAlloca(impl, tll) + for i, fld := range flds { + impl.CreateStore(fld, llvm.CreateStructGEP(impl, tll, ptr, i)) + } + return Expr{llvm.CreateLoad(b.impl, tll, ptr), t} +} + // The FieldAddr instruction yields the address of Field of *struct X. // // The field is identified by its index within the field list of the