| author | |
| committer | |
| log | 468ed7ada50c743eabe01b36d0ee9f090d80e00a |
| tree | fc5a703aaf6211db25355fcf79a945696564f3df |
| parent | 05d36fce9c7fde223e6657b3dc47105fbf065695 |
| parent | 83dcd9f0386a6bd70cf8d7dee3892f3b8d31d506 |
| signature |
stage2: emit Value.repeated for `**` with array len 13 files changed, 38 insertions(+), 10 deletions(-)
src/Sema.zig+15-9| ... | ... | @@ -6189,16 +6189,22 @@ fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 6189 | 6189 | try Type.Tag.array.create(anon_decl.arena(), .{ .len = final_len, .elem_type = mulinfo.elem_type }); |
| 6190 | 6190 | const buf = try anon_decl.arena().alloc(Value, final_len); |
| 6191 | 6191 | |
| 6192 | // the actual loop | |
| 6193 | var i: u64 = 0; | |
| 6194 | while (i < tomulby) : (i += 1) { | |
| 6195 | var j: u64 = 0; | |
| 6196 | while (j < mulinfo.len) : (j += 1) { | |
| 6197 | const val = try lhs_sub_val.elemValue(sema.arena, j); | |
| 6198 | buf[mulinfo.len * i + j] = try val.copy(anon_decl.arena()); | |
| 6192 | // handles the optimisation where arr.len == 0 : [_]T { X } ** N | |
| 6193 | const val = if (mulinfo.len == 1) blk: { | |
| 6194 | const copied_val = try (try lhs_sub_val.elemValue(sema.arena, 0)).copy(anon_decl.arena()); | |
| 6195 | break :blk try Value.Tag.repeated.create(anon_decl.arena(), copied_val); | |
| 6196 | } else blk: { | |
| 6197 | // the actual loop | |
| 6198 | var i: u64 = 0; | |
| 6199 | while (i < tomulby) : (i += 1) { | |
| 6200 | var j: u64 = 0; | |
| 6201 | while (j < mulinfo.len) : (j += 1) { | |
| 6202 | const val = try lhs_sub_val.elemValue(sema.arena, j); | |
| 6203 | buf[mulinfo.len * i + j] = try val.copy(anon_decl.arena()); | |
| 6204 | } | |
| 6199 | 6205 | } |
| 6200 | } | |
| 6201 | const val = try Value.Tag.array.create(anon_decl.arena(), buf); | |
| 6206 | break :blk try Value.Tag.array.create(anon_decl.arena(), buf); | |
| 6207 | }; | |
| 6202 | 6208 | if (lhs_ty.zigTypeTag() == .Pointer) { |
| 6203 | 6209 | return sema.analyzeDeclRef(try anon_decl.finish(final_ty, val)); |
| 6204 | 6210 | } else { |
src/codegen/llvm.zig+18-1| ... | ... | @@ -1024,6 +1024,7 @@ pub const DeclGen = struct { |
| 1024 | 1024 | else => |tag| return self.todo("implement const of pointer type '{}' ({})", .{ tv.ty, tag }), |
| 1025 | 1025 | }, |
| 1026 | 1026 | .Array => { |
| 1027 | const gpa = self.gpa; | |
| 1027 | 1028 | if (tv.val.castTag(.bytes)) |payload| { |
| 1028 | 1029 | const zero_sentinel = if (tv.ty.sentinel()) |sentinel| blk: { |
| 1029 | 1030 | if (sentinel.tag() == .zero) break :blk true; |
| ... | ... | @@ -1037,7 +1038,6 @@ pub const DeclGen = struct { |
| 1037 | 1038 | ); |
| 1038 | 1039 | } |
| 1039 | 1040 | if (tv.val.castTag(.array)) |payload| { |
| 1040 | const gpa = self.gpa; | |
| 1041 | 1041 | const elem_ty = tv.ty.elemType(); |
| 1042 | 1042 | const elem_vals = payload.data; |
| 1043 | 1043 | const sento = tv.ty.sentinel(); |
| ... | ... | @@ -1053,6 +1053,23 @@ pub const DeclGen = struct { |
| 1053 | 1053 | @intCast(c_uint, llvm_elems.len), |
| 1054 | 1054 | ); |
| 1055 | 1055 | } |
| 1056 | if (tv.val.castTag(.repeated)) |payload| { | |
| 1057 | const val = payload.data; | |
| 1058 | const elem_ty = tv.ty.elemType(); | |
| 1059 | const len = tv.ty.arrayLen(); | |
| 1060 | ||
| 1061 | const llvm_elems = try gpa.alloc(*const llvm.Value, len); | |
| 1062 | defer gpa.free(llvm_elems); | |
| 1063 | var i: u64 = 0; | |
| 1064 | while (i < len) : (i += 1) { | |
| 1065 | llvm_elems[i] = try self.genTypedValue(.{ .ty = elem_ty, .val = val }); | |
| 1066 | } | |
| 1067 | const llvm_elem_ty = try self.llvmType(elem_ty); | |
| 1068 | return llvm_elem_ty.constArray( | |
| 1069 | llvm_elems.ptr, | |
| 1070 | @intCast(c_uint, llvm_elems.len), | |
| 1071 | ); | |
| 1072 | } | |
| 1056 | 1073 | return self.todo("handle more array values", .{}); |
| 1057 | 1074 | }, |
| 1058 | 1075 | .Optional => { |
test/behavior/array.zig+5| ... | ... | @@ -32,4 +32,9 @@ test "array init with mult" { |
| 32 | 32 | const a = 'a'; |
| 33 | 33 | var i: [8]u8 = [2]u8{ a, 'b' } ** 4; |
| 34 | 34 | try expect(std.mem.eql(u8, &i, "abababab")); |
| 35 | ||
| 36 | // this should cause a Value.repeated to be emitted in AIR. | |
| 37 | // TODO: find a way to test that this is actually getting emmited | |
| 38 | var j: [4]u8 = [1]u8{'a'} ** 4; | |
| 39 | try expect(std.mem.eql(u8, &j, "aaaa")); | |
| 35 | 40 | } |