diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 29 | ||||
| -rw-r--r-- | src/Zcu/PerThread.zig | 21 | ||||
| -rw-r--r-- | src/arch/riscv64/CodeGen.zig | 17 | ||||
| -rw-r--r-- | src/link/Dwarf.zig | 78 | ||||
| -rw-r--r-- | src/print_zir.zig | 7 |
5 files changed, 79 insertions, 73 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 9687d28b33..fdf5eca764 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1361,6 +1361,7 @@ fn analyzeBodyInner( .value_placeholder => unreachable, // never appears in a body .field_parent_ptr => try sema.zirFieldParentPtr(block, extended), .builtin_value => try sema.zirBuiltinValue(extended), + .inplace_arith_result_ty => try sema.zirInplaceArithResultTy(extended), }; }, @@ -27344,6 +27345,33 @@ fn zirBuiltinValue(sema: *Sema, extended: Zir.Inst.Extended.InstData) CompileErr return Air.internedToRef(ty.toIntern()); } +fn zirInplaceArithResultTy(sema: *Sema, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { + const pt = sema.pt; + const zcu = pt.zcu; + + const lhs = try sema.resolveInst(@enumFromInt(extended.operand)); + const lhs_ty = sema.typeOf(lhs); + + const op: Zir.Inst.InplaceOp = @enumFromInt(extended.small); + const ty: Type = switch (op) { + .add_eq => ty: { + const ptr_size = lhs_ty.ptrSizeOrNull(zcu) orelse break :ty lhs_ty; + switch (ptr_size) { + .One, .Slice => break :ty lhs_ty, // invalid, let it error + .Many, .C => break :ty .usize, // `[*]T + usize` + } + }, + .sub_eq => ty: { + const ptr_size = lhs_ty.ptrSizeOrNull(zcu) orelse break :ty lhs_ty; + switch (ptr_size) { + .One, .Slice => break :ty lhs_ty, // invalid, let it error + .Many, .C => break :ty .generic_poison, // could be `[*]T - [*]T` or `[*]T - usize` + } + }, + }; + return Air.internedToRef(ty.toIntern()); +} + fn zirBranchHint(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { const pt = sema.pt; const zcu = pt.zcu; @@ -36283,6 +36311,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { /// be resolved. pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void { try sema.resolveStructLayout(ty); + try sema.resolveStructFieldInits(ty); const pt = sema.pt; const zcu = pt.zcu; diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 837895f783..a11910302d 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -1240,11 +1240,11 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { }; } - const nav_already_populated, const queue_linker_work, const resolve_type = switch (ip.indexToKey(decl_val.toIntern())) { - .func => |f| .{ f.owner_nav == nav_index, true, false }, - .variable => |v| .{ false, v.owner_nav == nav_index, true }, - .@"extern" => .{ false, false, false }, - else => .{ false, true, true }, + const nav_already_populated, const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) { + .func => |f| .{ f.owner_nav == nav_index, true }, + .variable => |v| .{ false, v.owner_nav == nav_index }, + .@"extern" => .{ false, false }, + else => .{ false, true }, }; if (nav_already_populated) { @@ -1317,16 +1317,7 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { queue_codegen: { if (!queue_linker_work) break :queue_codegen; - if (resolve_type) { - // Needed for codegen_nav which will call updateDecl and then the - // codegen backend wants full access to the Decl Type. - // We also need this for the `isFnOrHasRuntimeBits` check below. - // TODO: we could make the language more lenient by deferring this work - // to the `codegen_nav` job. - try decl_ty.resolveFully(pt); - } - - if (!resolve_type or !decl_ty.hasRuntimeBits(zcu)) { + if (!try decl_ty.hasRuntimeBitsSema(pt)) { if (zcu.comp.config.use_llvm) break :queue_codegen; if (file.mod.strip) break :queue_codegen; } diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index 0c6da840eb..73fa0460de 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -3897,7 +3897,7 @@ fn airArrayElemVal(func: *Func, inst: Air.Inst.Index) !void { if (array_ty.isVector(zcu)) { // we need to load the vector, vslidedown to get the element we want - // and store that element at in a load frame. + // and store that element in a load frame. const src_reg, const src_lock = try func.allocReg(.vector); defer func.register_manager.unlockReg(src_lock); @@ -3970,12 +3970,15 @@ fn airPtrElemVal(func: *Func, inst: Air.Inst.Index) !void { }; defer if (index_lock) |lock| func.register_manager.unlockReg(lock); - const elem_ptr_reg = if (base_ptr_mcv.isRegister() and func.liveness.operandDies(inst, 0)) - base_ptr_mcv.register - else - try func.copyToTmpRegister(base_ptr_ty, base_ptr_mcv); - const elem_ptr_lock = func.register_manager.lockRegAssumeUnused(elem_ptr_reg); - defer func.register_manager.unlockReg(elem_ptr_lock); + const elem_ptr_reg, const elem_ptr_lock = if (base_ptr_mcv.isRegister() and + func.liveness.operandDies(inst, 0)) + .{ base_ptr_mcv.register, null } + else blk: { + const reg, const lock = try func.allocReg(.int); + try func.genSetReg(base_ptr_ty, reg, base_ptr_mcv); + break :blk .{ reg, lock }; + }; + defer if (elem_ptr_lock) |lock| func.register_manager.unlockReg(lock); try func.genBinOp( .ptr_add, diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 9ec0fa3012..6efa708d05 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -2643,10 +2643,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool try uleb128(diw, nav_val.toType().abiAlignment(zcu).toByteUnits().?); for (0..loaded_struct.field_types.len) |field_index| { const is_comptime = loaded_struct.fieldIsComptime(ip, field_index); - const field_init = if (loaded_struct.haveFieldInits(ip)) - loaded_struct.fieldInit(ip, field_index) - else - .none; + const field_init = loaded_struct.fieldInit(ip, field_index); + assert(!(is_comptime and field_init == .none)); try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else if (field_init != .none) @@ -2658,20 +2656,14 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool defer dwarf.gpa.free(field_name); try wip_nav.strp(field_name); } - if (is_comptime and field_init == .none) { - // workaround frontend bug - try wip_nav.refType(Type.void); - try wip_nav.blockValue(nav_src_loc, Value.void); - } else { - const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); - try wip_nav.refType(field_type); - if (!is_comptime) { - try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]); - try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse - field_type.abiAlignment(zcu).toByteUnits().?); - } - if (field_init != .none) try wip_nav.blockValue(nav_src_loc, Value.fromInterned(field_init)); + const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); + try wip_nav.refType(field_type); + if (!is_comptime) { + try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]); + try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse + field_type.abiAlignment(zcu).toByteUnits().?); } + if (field_init != .none) try wip_nav.blockValue(nav_src_loc, Value.fromInterned(field_init)); } try uleb128(diw, @intFromEnum(AbbrevCode.null)); } @@ -3511,10 +3503,8 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?); for (0..loaded_struct.field_types.len) |field_index| { const is_comptime = loaded_struct.fieldIsComptime(ip, field_index); - const field_init = if (loaded_struct.haveFieldInits(ip)) - loaded_struct.fieldInit(ip, field_index) - else - .none; + const field_init = loaded_struct.fieldInit(ip, field_index); + assert(!(is_comptime and field_init == .none)); try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else if (field_init != .none) @@ -3526,20 +3516,14 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP defer dwarf.gpa.free(field_name); try wip_nav.strp(field_name); } - if (is_comptime and field_init == .none) { - // workaround frontend bug - try wip_nav.refType(Type.void); - try wip_nav.blockValue(ty_src_loc, Value.void); - } else { - const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); - try wip_nav.refType(field_type); - if (!is_comptime) { - try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]); - try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse - field_type.abiAlignment(zcu).toByteUnits().?); - } - if (field_init != .none) try wip_nav.blockValue(ty_src_loc, Value.fromInterned(field_init)); + const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); + try wip_nav.refType(field_type); + if (!is_comptime) { + try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]); + try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse + field_type.abiAlignment(zcu).toByteUnits().?); } + if (field_init != .none) try wip_nav.blockValue(ty_src_loc, Value.fromInterned(field_init)); } try uleb128(diw, @intFromEnum(AbbrevCode.null)); } @@ -3595,10 +3579,8 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?); for (0..loaded_struct.field_types.len) |field_index| { const is_comptime = loaded_struct.fieldIsComptime(ip, field_index); - const field_init = if (loaded_struct.haveFieldInits(ip)) - loaded_struct.fieldInit(ip, field_index) - else - .none; + const field_init = loaded_struct.fieldInit(ip, field_index); + assert(!(is_comptime and field_init == .none)); try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else if (field_init != .none) @@ -3610,20 +3592,14 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP defer dwarf.gpa.free(field_name); try wip_nav.strp(field_name); } - if (is_comptime and field_init == .none) { - // workaround frontend bug - try wip_nav.refType(Type.void); - try wip_nav.blockValue(ty_src_loc, Value.void); - } else { - const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); - try wip_nav.refType(field_type); - if (!is_comptime) { - try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]); - try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse - field_type.abiAlignment(zcu).toByteUnits().?); - } - if (field_init != .none) try wip_nav.blockValue(ty_src_loc, Value.fromInterned(field_init)); + const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); + try wip_nav.refType(field_type); + if (!is_comptime) { + try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]); + try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse + field_type.abiAlignment(zcu).toByteUnits().?); } + if (field_init != .none) try wip_nav.blockValue(ty_src_loc, Value.fromInterned(field_init)); } try uleb128(diw, @intFromEnum(AbbrevCode.null)); } diff --git a/src/print_zir.zig b/src/print_zir.zig index f5c83c98e2..c5f1517edd 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -620,6 +620,7 @@ const Writer = struct { .closure_get => try self.writeClosureGet(stream, extended), .field_parent_ptr => try self.writeFieldParentPtr(stream, extended), .builtin_value => try self.writeBuiltinValue(stream, extended), + .inplace_arith_result_ty => try self.writeInplaceArithResultTy(stream, extended), } } @@ -2781,6 +2782,12 @@ const Writer = struct { try self.writeSrcNode(stream, @bitCast(extended.operand)); } + fn writeInplaceArithResultTy(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { + const op: Zir.Inst.InplaceOp = @enumFromInt(extended.small); + try self.writeInstRef(stream, @enumFromInt(extended.operand)); + try stream.print(", {s}))", .{@tagName(op)}); + } + fn writeInstRef(self: *Writer, stream: anytype, ref: Zir.Inst.Ref) !void { if (ref == .none) { return stream.writeAll(".none"); |
