From 173ed4524ecb47c90302f4bebbee96e10adacb99 Mon Sep 17 00:00:00 2001 From: lemon Date: Thu, 1 Sep 2022 21:32:18 +0200 Subject: [PATCH] gencopy (?) --- src/llvm.cff | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/llvm.cff b/src/llvm.cff index 83f3f10..44d4f57 100644 --- a/src/llvm.cff +++ b/src/llvm.cff @@ -248,6 +248,7 @@ enum union Ref { BitDot struct { lhs Value, fld *const BitFField } } +fn gencopy(f *Fn, ty *const Type, ref Ref, src *Expr) void; fn genref(f *Fn, ex *Expr) Ref { switch ex.u { case StrLit s; @@ -339,8 +340,7 @@ fn genref(f *Fn, ex *Expr) Ref { gen("\t%v = bitcast %t %v to %t\n", &ptr, tmp.ty, &tmp, ptr.ty); case else assert(#f, "?"); } - let it = convert(f, fld.ty, fex); - gen("\tstore %t %v, ptr %v\n", fld.ty, &it, &ptr); + gencopy(f, fld.ty, :Addr(ptr), fex); } return :Addr(tmp); @@ -352,8 +352,7 @@ fn genref(f *Fn, ex *Expr) Ref { let fex = &ini.exs[i]; let ptr = mktmp(mkptrtype(fex.ty)); gen("\t%v = getelementptr %t, %t %v, i32 0, i32 %d\n", &ptr, ty, tmp.ty, &tmp, idx); - let it = convert(f, ty.u.Arr.child, fex); - gen("\tstore %t %v, %t %v\n", fex.ty, &it, ptr.ty, &ptr); + gencopy(f, ty.u.Arr.child, :Addr(ptr), fex); } return :Addr(tmp); @@ -413,6 +412,20 @@ fn genstore(f *Fn, ref Ref, v Value) void { } } +fn gencopy(f *Fn, ty *const Type, ref Ref, src *Expr) void { + if (ty.u.#tag == :Agg or ty.u.#tag == :Arr) and src.u.#tag == :ZeroIni { + gen("\tcall void @llvm.memset.p0.%t(ptr %v, i8 0, %t %z, i1 false)\n", + ty_usize, &ref.Addr, ty_usize, ty.size); + // XXX: LLVM optimizations mess this up ? + // } else if (ty.u.#tag == :Agg or ty.u.#tag == :Arr) and ref.#tag == :Addr { + // let rhs = genref(f, src); + // gen("\tcall void @llvm.memmove.p0.p0.%t(ptr %v, ptr %v, %t %z, i1 false)\n", + // ty_usize, &ref.Addr, &rhs.Addr, ty_usize, ty.size); + } else { + genstore(f, ref, convert(f, ty, src)); + } +} + fn convert(f *Fn, to *const Type, ex *Expr) Value { to = unconstify(to); let from = unconstify(ex.ty); @@ -635,8 +648,7 @@ fn genexpr(f *Fn, ex *Expr) Value { case '>='; gencmp(ty2->is(:Flo) ? "oge" : ty2.u.Int.sgn ? "sge" : "uge"); case '='; let ref = genref(f, b.lhs); - let rhs = convert(f, b.lhs.ty, b.rhs); - genstore(f, ref, rhs); + gencopy(f, b.lhs.ty, ref, b.rhs); return genload(f, ref); // load again because value could have overflowed when storing it case '+='; @@ -979,13 +991,10 @@ fn genexpr(f *Fn, ex *Expr) Value { gen("\tcall void @llvm.memset.p0.%t(ptr %v, i8 0, %t %z, i1 false)\n", ty_usize, &t0, ty_usize, ex.ty.size); gen("\tstore %t %d, ptr %v\n", ex.ty.u.Agg.enumty, vidx, &t0); if ini.var.ty != #null { - let tini = convert(f, ini.var.ty, ini.ex); let t2 = gentmp(t0.ty, "getelementptr i8, ptr %v, i32 %z", &t0, ini.var.off); - gen("\tstore %t %v, ptr %v\n", tini.ty, &tini, &t2); + gencopy(f, ini.var.ty, :Addr(t2), ini.ex); } - let res = mktmp(ex.ty); - gen("\t%v = load %t, %t %v\n", &res, res.ty, t0.ty, &t0); - return res; + return gentmp(ex.ty, "load %t, %t %v", ex.ty, t0.ty, &t0); case VaStart ap; let ap = genref(f, ap).Addr; @@ -1165,8 +1174,7 @@ fn genstmt(f *Fn, block *Block, st *Stmt) void { } else { exaddr = mktmp(mkptrtype(sw.ex.ty)); gen("\t%v = alloca %t\n", &exaddr, sw.ex.ty); - let test = genexpr(f, &sw.ex); - gen("\tstore %t %v, %t %v\n", test.ty, &test, exaddr.ty, &exaddr); + gencopy(f, sw.ex.ty, :Addr(exaddr), &sw.ex); } let tag = (do let addr = mktmp(mkptrtype(sw.ex.ty.u.Agg.enumty)); @@ -1524,8 +1532,8 @@ extern fn llvm_fini() void { gen("declare void @llvm.va_start(ptr)\n"); gen("declare void @llvm.va_copy(ptr, ptr)\n"); gen("declare void @llvm.va_end(ptr)\n"); - gen("declare void @llvm.memset.p0.i32(ptr, i8, i32, i1)\n"); - gen("declare void @llvm.memset.p0.i64(ptr, i8, i64, i1)\n"); + gen("declare void @llvm.memset.p0.%t(ptr, i8, %t, i1)\n", ty_usize, ty_usize); + gen("declare void @llvm.memmove.p0.p0.%t(ptr, ptr, %t, i1)\n", ty_usize, ty_usize); vec_each(s, i, strs) { gen("@.str.%z = private unnamed_addr constant [%z x i8] c%S;\n", i, s.#len + 1, &s); } -- 2.38.5