authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-09-30 21:31:46-04:00
committergravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-10-01 16:46:28-04:00
log83dcd9f0386a6bd70cf8d7dee3892f3b8d31d506
tree6e531bf3dd6d39647a7971cae1d021900ea31055
parentb0e89ee499b8110bca6964e996c5862337147e32

stage2: emit Value.repeated for `**` where the array size is one

This takes advantage of the repeated value.

2 files changed, 20 insertions(+), 9 deletions(-)

src/Sema.zig+15-9
......@@ -6189,16 +6189,22 @@ fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
61896189 try Type.Tag.array.create(anon_decl.arena(), .{ .len = final_len, .elem_type = mulinfo.elem_type });
61906190 const buf = try anon_decl.arena().alloc(Value, final_len);
61916191
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 }
61996205 }
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 };
62026208 if (lhs_ty.zigTypeTag() == .Pointer) {
62036209 return sema.analyzeDeclRef(try anon_decl.finish(final_ty, val));
62046210 } else {
test/behavior/array.zig+5
......@@ -32,4 +32,9 @@ test "array init with mult" {
3232 const a = 'a';
3333 var i: [8]u8 = [2]u8{ a, 'b' } ** 4;
3434 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"));
3540}