mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 07:03:11 +00:00
Merge pull request #9875 from g-w1/timestimes
stage2: emit Value.repeated for `**` with array len 1
This commit is contained in:
commit
468ed7ada5
24
src/Sema.zig
24
src/Sema.zig
@ -6189,16 +6189,22 @@ fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
|
||||
try Type.Tag.array.create(anon_decl.arena(), .{ .len = final_len, .elem_type = mulinfo.elem_type });
|
||||
const buf = try anon_decl.arena().alloc(Value, final_len);
|
||||
|
||||
// the actual loop
|
||||
var i: u64 = 0;
|
||||
while (i < tomulby) : (i += 1) {
|
||||
var j: u64 = 0;
|
||||
while (j < mulinfo.len) : (j += 1) {
|
||||
const val = try lhs_sub_val.elemValue(sema.arena, j);
|
||||
buf[mulinfo.len * i + j] = try val.copy(anon_decl.arena());
|
||||
// handles the optimisation where arr.len == 0 : [_]T { X } ** N
|
||||
const val = if (mulinfo.len == 1) blk: {
|
||||
const copied_val = try (try lhs_sub_val.elemValue(sema.arena, 0)).copy(anon_decl.arena());
|
||||
break :blk try Value.Tag.repeated.create(anon_decl.arena(), copied_val);
|
||||
} else blk: {
|
||||
// the actual loop
|
||||
var i: u64 = 0;
|
||||
while (i < tomulby) : (i += 1) {
|
||||
var j: u64 = 0;
|
||||
while (j < mulinfo.len) : (j += 1) {
|
||||
const val = try lhs_sub_val.elemValue(sema.arena, j);
|
||||
buf[mulinfo.len * i + j] = try val.copy(anon_decl.arena());
|
||||
}
|
||||
}
|
||||
}
|
||||
const val = try Value.Tag.array.create(anon_decl.arena(), buf);
|
||||
break :blk try Value.Tag.array.create(anon_decl.arena(), buf);
|
||||
};
|
||||
if (lhs_ty.zigTypeTag() == .Pointer) {
|
||||
return sema.analyzeDeclRef(try anon_decl.finish(final_ty, val));
|
||||
} else {
|
||||
|
||||
@ -1024,6 +1024,7 @@ pub const DeclGen = struct {
|
||||
else => |tag| return self.todo("implement const of pointer type '{}' ({})", .{ tv.ty, tag }),
|
||||
},
|
||||
.Array => {
|
||||
const gpa = self.gpa;
|
||||
if (tv.val.castTag(.bytes)) |payload| {
|
||||
const zero_sentinel = if (tv.ty.sentinel()) |sentinel| blk: {
|
||||
if (sentinel.tag() == .zero) break :blk true;
|
||||
@ -1037,7 +1038,6 @@ pub const DeclGen = struct {
|
||||
);
|
||||
}
|
||||
if (tv.val.castTag(.array)) |payload| {
|
||||
const gpa = self.gpa;
|
||||
const elem_ty = tv.ty.elemType();
|
||||
const elem_vals = payload.data;
|
||||
const sento = tv.ty.sentinel();
|
||||
@ -1053,6 +1053,23 @@ pub const DeclGen = struct {
|
||||
@intCast(c_uint, llvm_elems.len),
|
||||
);
|
||||
}
|
||||
if (tv.val.castTag(.repeated)) |payload| {
|
||||
const val = payload.data;
|
||||
const elem_ty = tv.ty.elemType();
|
||||
const len = tv.ty.arrayLen();
|
||||
|
||||
const llvm_elems = try gpa.alloc(*const llvm.Value, len);
|
||||
defer gpa.free(llvm_elems);
|
||||
var i: u64 = 0;
|
||||
while (i < len) : (i += 1) {
|
||||
llvm_elems[i] = try self.genTypedValue(.{ .ty = elem_ty, .val = val });
|
||||
}
|
||||
const llvm_elem_ty = try self.llvmType(elem_ty);
|
||||
return llvm_elem_ty.constArray(
|
||||
llvm_elems.ptr,
|
||||
@intCast(c_uint, llvm_elems.len),
|
||||
);
|
||||
}
|
||||
return self.todo("handle more array values", .{});
|
||||
},
|
||||
.Optional => {
|
||||
|
||||
@ -32,4 +32,9 @@ test "array init with mult" {
|
||||
const a = 'a';
|
||||
var i: [8]u8 = [2]u8{ a, 'b' } ** 4;
|
||||
try expect(std.mem.eql(u8, &i, "abababab"));
|
||||
|
||||
// this should cause a Value.repeated to be emitted in AIR.
|
||||
// TODO: find a way to test that this is actually getting emmited
|
||||
var j: [4]u8 = [1]u8{'a'} ** 4;
|
||||
try expect(std.mem.eql(u8, &j, "aaaa"));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user