authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-26 13:21:46-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:55-07:00
logace5a5e3ccfce69c93426913f247ea7bad7703ff
tree339c19c31764c342333307cbea689158b727bca8
parent63dc0447fc4654324ef8efcfa65849f7ef682531

llvm: simplify control flow lowering structs


1 files changed, 56 insertions(+), 59 deletions(-)

src/codegen/llvm.zig+56-59
......@@ -3537,78 +3537,75 @@ pub const DeclGen = struct {
35373537 @intCast(c_uint, llvm_elems.len),
35383538 );
35393539 },
3540 .struct_type, .anon_struct_type => {
3541 const llvm_struct_ty = try dg.lowerType(tv.ty);
3540 .anon_struct_type => |tuple| {
35423541 const gpa = dg.gpa;
35433542
3544 const struct_type = switch (mod.intern_pool.indexToKey(tv.ty.toIntern())) {
3545 .anon_struct_type => |tuple| {
3546 var llvm_fields: std.ArrayListUnmanaged(*llvm.Value) = .{};
3547 defer llvm_fields.deinit(gpa);
3548
3549 try llvm_fields.ensureUnusedCapacity(gpa, tuple.types.len);
3543 var llvm_fields: std.ArrayListUnmanaged(*llvm.Value) = .{};
3544 defer llvm_fields.deinit(gpa);
35503545
3551 comptime assert(struct_layout_version == 2);
3552 var offset: u64 = 0;
3553 var big_align: u32 = 0;
3554 var need_unnamed = false;
3546 try llvm_fields.ensureUnusedCapacity(gpa, tuple.types.len);
35553547
3556 for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| {
3557 if (field_val != .none) continue;
3558 if (!field_ty.toType().hasRuntimeBitsIgnoreComptime(mod)) continue;
3548 comptime assert(struct_layout_version == 2);
3549 var offset: u64 = 0;
3550 var big_align: u32 = 0;
3551 var need_unnamed = false;
35593552
3560 const field_align = field_ty.toType().abiAlignment(mod);
3561 big_align = @max(big_align, field_align);
3562 const prev_offset = offset;
3563 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
3553 for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| {
3554 if (field_val != .none) continue;
3555 if (!field_ty.toType().hasRuntimeBitsIgnoreComptime(mod)) continue;
35643556
3565 const padding_len = offset - prev_offset;
3566 if (padding_len > 0) {
3567 const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
3568 // TODO make this and all other padding elsewhere in debug
3569 // builds be 0xaa not undef.
3570 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
3571 }
3557 const field_align = field_ty.toType().abiAlignment(mod);
3558 big_align = @max(big_align, field_align);
3559 const prev_offset = offset;
3560 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
35723561
3573 const field_llvm_val = try dg.lowerValue(.{
3574 .ty = field_ty.toType(),
3575 .val = try tv.val.fieldValue(mod, i),
3576 });
3562 const padding_len = offset - prev_offset;
3563 if (padding_len > 0) {
3564 const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
3565 // TODO make this and all other padding elsewhere in debug
3566 // builds be 0xaa not undef.
3567 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
3568 }
35773569
3578 need_unnamed = need_unnamed or dg.isUnnamedType(field_ty.toType(), field_llvm_val);
3570 const field_llvm_val = try dg.lowerValue(.{
3571 .ty = field_ty.toType(),
3572 .val = try tv.val.fieldValue(mod, i),
3573 });
35793574
3580 llvm_fields.appendAssumeCapacity(field_llvm_val);
3575 need_unnamed = need_unnamed or dg.isUnnamedType(field_ty.toType(), field_llvm_val);
35813576
3582 offset += field_ty.toType().abiSize(mod);
3583 }
3584 {
3585 const prev_offset = offset;
3586 offset = std.mem.alignForwardGeneric(u64, offset, big_align);
3587 const padding_len = offset - prev_offset;
3588 if (padding_len > 0) {
3589 const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
3590 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
3591 }
3592 }
3577 llvm_fields.appendAssumeCapacity(field_llvm_val);
35933578
3594 if (need_unnamed) {
3595 return dg.context.constStruct(
3596 llvm_fields.items.ptr,
3597 @intCast(c_uint, llvm_fields.items.len),
3598 .False,
3599 );
3600 } else {
3601 return llvm_struct_ty.constNamedStruct(
3602 llvm_fields.items.ptr,
3603 @intCast(c_uint, llvm_fields.items.len),
3604 );
3605 }
3606 },
3607 .struct_type => |struct_type| struct_type,
3608 else => unreachable,
3609 };
3579 offset += field_ty.toType().abiSize(mod);
3580 }
3581 {
3582 const prev_offset = offset;
3583 offset = std.mem.alignForwardGeneric(u64, offset, big_align);
3584 const padding_len = offset - prev_offset;
3585 if (padding_len > 0) {
3586 const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
3587 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
3588 }
3589 }
36103590
3591 if (need_unnamed) {
3592 return dg.context.constStruct(
3593 llvm_fields.items.ptr,
3594 @intCast(c_uint, llvm_fields.items.len),
3595 .False,
3596 );
3597 } else {
3598 const llvm_struct_ty = try dg.lowerType(tv.ty);
3599 return llvm_struct_ty.constNamedStruct(
3600 llvm_fields.items.ptr,
3601 @intCast(c_uint, llvm_fields.items.len),
3602 );
3603 }
3604 },
3605 .struct_type => |struct_type| {
36113606 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
3607 const llvm_struct_ty = try dg.lowerType(tv.ty);
3608 const gpa = dg.gpa;
36123609
36133610 if (struct_obj.layout == .Packed) {
36143611 assert(struct_obj.haveLayout());