diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2025-05-28 22:45:19 -0400 |
|---|---|---|
| committer | Jacob Young <15544577+jacobly0@users.noreply.github.com> | 2025-05-29 03:57:48 -0400 |
| commit | c04be630d996a0e01fd3cf05e6cade006e4226ce (patch) | |
| tree | edd9d55ad05435b91bd3cb95208a76ead2001094 /src/codegen/c.zig | |
| parent | f25212a479c4f26566b6b851e245e49c6f508b96 (diff) | |
| download | zig-c04be630d996a0e01fd3cf05e6cade006e4226ce.tar.gz zig-c04be630d996a0e01fd3cf05e6cade006e4226ce.zip | |
Legalize: introduce a new pass before liveness
Each target can opt into different sets of legalize features.
By performing these transformations before liveness, instructions
that become unreferenced will have up-to-date liveness information.
Diffstat (limited to 'src/codegen/c.zig')
| -rw-r--r-- | src/codegen/c.zig | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 075d9ba303..8539efdbfe 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -14,7 +14,6 @@ const C = link.File.C; const Decl = Zcu.Decl; const trace = @import("../tracy.zig").trace; const Air = @import("../Air.zig"); -const Liveness = @import("../Liveness.zig"); const InternPool = @import("../InternPool.zig"); const Alignment = InternPool.Alignment; @@ -356,7 +355,7 @@ pub fn isMangledIdent(ident: []const u8, solo: bool) bool { /// It is not available when generating .h file. pub const Function = struct { air: Air, - liveness: Liveness, + liveness: Air.Liveness, value_map: CValueMap, blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, BlockData) = .empty, next_arg_index: u32 = 0, @@ -2323,9 +2322,9 @@ pub const DeclGen = struct { const pt = dg.pt; const zcu = pt.zcu; - const int_info = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else std.builtin.Type.Int{ + const int_info: std.builtin.Type.Int = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else .{ .signedness = .unsigned, - .bits = @as(u16, @intCast(ty.bitSize(zcu))), + .bits = @intCast(ty.bitSize(zcu)), }; if (is_big) try writer.print(", {}", .{int_info.signedness == .signed}); @@ -3179,7 +3178,7 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con // Remember how many locals there were before entering the body so that we can free any that // were newly introduced. Any new locals must necessarily be logically free after the then // branch is complete. - const pre_locals_len = @as(LocalIndex, @intCast(f.locals.items.len)); + const pre_locals_len: LocalIndex = @intCast(f.locals.items.len); for (leading_deaths) |death| { try die(f, inst, death.toRef()); @@ -4540,7 +4539,7 @@ fn airCall( const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; const extra = f.air.extraData(Air.Call, pl_op.payload); - const args = @as([]const Air.Inst.Ref, @ptrCast(f.air.extra[extra.end..][0..extra.data.args_len])); + const args: []const Air.Inst.Ref = @ptrCast(f.air.extra.items[extra.end..][0..extra.data.args_len]); const resolved_args = try gpa.alloc(CValue, args.len); defer gpa.free(resolved_args); @@ -4708,7 +4707,7 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue { const owner_nav = ip.getNav(zcu.funcInfo(extra.data.func).owner_nav); const writer = f.object.writer(); try writer.print("/* inline:{} */\n", .{owner_nav.fqn.fmt(&zcu.intern_pool)}); - return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len])); + return lowerBlock(f, inst, @ptrCast(f.air.extra.items[extra.end..][0..extra.data.body_len])); } fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { @@ -4729,7 +4728,7 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const extra = f.air.extraData(Air.Block, ty_pl.payload); - return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len])); + return lowerBlock(f, inst, @ptrCast(f.air.extra.items[extra.end..][0..extra.data.body_len])); } fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) !CValue { @@ -4781,7 +4780,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) fn airTry(f: *Function, inst: Air.Inst.Index) !CValue { const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; const extra = f.air.extraData(Air.Try, pl_op.payload); - const body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]); + const body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end..][0..extra.data.body_len]); const err_union_ty = f.typeOf(pl_op.operand); return lowerTry(f, inst, pl_op.operand, body, err_union_ty, false); } @@ -4791,7 +4790,7 @@ fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue { const zcu = pt.zcu; const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const extra = f.air.extraData(Air.TryPtr, ty_pl.payload); - const body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]); + const body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end..][0..extra.data.body_len]); const err_union_ty = f.typeOf(extra.data.ptr).childType(zcu); return lowerTry(f, inst, extra.data.ptr, body, err_union_ty, true); } @@ -5100,7 +5099,7 @@ fn airUnreach(f: *Function) !void { fn airLoop(f: *Function, inst: Air.Inst.Index) !void { const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const loop = f.air.extraData(Air.Block, ty_pl.payload); - const body: []const Air.Inst.Index = @ptrCast(f.air.extra[loop.end..][0..loop.data.body_len]); + const body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[loop.end..][0..loop.data.body_len]); const writer = f.object.writer(); // `repeat` instructions matching this loop will branch to @@ -5116,8 +5115,8 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !void { const cond = try f.resolveInst(pl_op.operand); try reap(f, inst, &.{pl_op.operand}); const extra = f.air.extraData(Air.CondBr, pl_op.payload); - const then_body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.then_body_len]); - const else_body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]); + const then_body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end..][0..extra.data.then_body_len]); + const else_body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end + then_body.len ..][0..extra.data.else_body_len]); const liveness_condbr = f.liveness.getCondBr(inst); const writer = f.object.writer(); @@ -5322,12 +5321,12 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const extra = f.air.extraData(Air.Asm, ty_pl.payload); const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0; - const clobbers_len = @as(u31, @truncate(extra.data.flags)); + const clobbers_len: u31 = @truncate(extra.data.flags); const gpa = f.object.dg.gpa; var extra_i: usize = extra.end; - const outputs = @as([]const Air.Inst.Ref, @ptrCast(f.air.extra[extra_i..][0..extra.data.outputs_len])); + const outputs: []const Air.Inst.Ref = @ptrCast(f.air.extra.items[extra_i..][0..extra.data.outputs_len]); extra_i += outputs.len; - const inputs = @as([]const Air.Inst.Ref, @ptrCast(f.air.extra[extra_i..][0..extra.data.inputs_len])); + const inputs: []const Air.Inst.Ref = @ptrCast(f.air.extra.items[extra_i..][0..extra.data.inputs_len]); extra_i += inputs.len; const result = result: { @@ -5347,10 +5346,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { break :local inst_local; } else .none; - const locals_begin = @as(LocalIndex, @intCast(f.locals.items.len)); + const locals_begin: LocalIndex = @intCast(f.locals.items.len); const constraints_extra_begin = extra_i; for (outputs) |output| { - const extra_bytes = mem.sliceAsBytes(f.air.extra[extra_i..]); + const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]); const constraint = mem.sliceTo(extra_bytes, 0); const name = mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); // This equation accounts for the fact that even if we have exactly 4 bytes @@ -5384,7 +5383,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { } } for (inputs) |input| { - const extra_bytes = mem.sliceAsBytes(f.air.extra[extra_i..]); + const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]); const constraint = mem.sliceTo(extra_bytes, 0); const name = mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); // This equation accounts for the fact that even if we have exactly 4 bytes @@ -5419,14 +5418,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { } } for (0..clobbers_len) |_| { - const clobber = mem.sliceTo(mem.sliceAsBytes(f.air.extra[extra_i..]), 0); + const clobber = mem.sliceTo(mem.sliceAsBytes(f.air.extra.items[extra_i..]), 0); // This equation accounts for the fact that even if we have exactly 4 bytes // for the string, we still use the next u32 for the null terminator. extra_i += clobber.len / 4 + 1; } { - const asm_source = mem.sliceAsBytes(f.air.extra[extra_i..])[0..extra.data.source_len]; + const asm_source = mem.sliceAsBytes(f.air.extra.items[extra_i..])[0..extra.data.source_len]; var stack = std.heap.stackFallback(256, f.object.dg.gpa); const allocator = stack.get(); @@ -5484,7 +5483,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { var locals_index = locals_begin; try writer.writeByte(':'); for (outputs, 0..) |output, index| { - const extra_bytes = mem.sliceAsBytes(f.air.extra[extra_i..]); + const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]); const constraint = mem.sliceTo(extra_bytes, 0); const name = mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); // This equation accounts for the fact that even if we have exactly 4 bytes @@ -5508,7 +5507,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { } try writer.writeByte(':'); for (inputs, 0..) |input, index| { - const extra_bytes = mem.sliceAsBytes(f.air.extra[extra_i..]); + const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]); const constraint = mem.sliceTo(extra_bytes, 0); const name = mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); // This equation accounts for the fact that even if we have exactly 4 bytes @@ -5531,7 +5530,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { } try writer.writeByte(':'); for (0..clobbers_len) |clobber_i| { - const clobber = mem.sliceTo(mem.sliceAsBytes(f.air.extra[extra_i..]), 0); + const clobber = mem.sliceTo(mem.sliceAsBytes(f.air.extra.items[extra_i..]), 0); // This equation accounts for the fact that even if we have exactly 4 bytes // for the string, we still use the next u32 for the null terminator. extra_i += clobber.len / 4 + 1; @@ -5546,7 +5545,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { extra_i = constraints_extra_begin; locals_index = locals_begin; for (outputs) |output| { - const extra_bytes = mem.sliceAsBytes(f.air.extra[extra_i..]); + const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]); const constraint = mem.sliceTo(extra_bytes, 0); const name = mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); // This equation accounts for the fact that even if we have exactly 4 bytes @@ -6725,7 +6724,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { const operand_mat = try Materialize.start(f, inst, ty, operand); try reap(f, inst, &.{ pl_op.operand, extra.operand }); - const repr_bits = @as(u16, @intCast(ty.abiSize(zcu) * 8)); + const repr_bits: u16 = @intCast(ty.abiSize(zcu) * 8); const is_float = ty.isRuntimeFloat(); const is_128 = repr_bits == 128; const repr_ty = if (is_float) pt.intType(.unsigned, repr_bits) catch unreachable else ty; @@ -7325,8 +7324,8 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { const ip = &zcu.intern_pool; const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const inst_ty = f.typeOfIndex(inst); - const len = @as(usize, @intCast(inst_ty.arrayLen(zcu))); - const elements = @as([]const Air.Inst.Ref, @ptrCast(f.air.extra[ty_pl.payload..][0..len])); + const len: usize = @intCast(inst_ty.arrayLen(zcu)); + const elements: []const Air.Inst.Ref = @ptrCast(f.air.extra.items[ty_pl.payload..][0..len]); const gpa = f.object.dg.gpa; const resolved_elements = try gpa.alloc(CValue, elements.len); defer gpa.free(resolved_elements); @@ -7830,7 +7829,7 @@ fn IndentWriter(comptime UnderlyingWriter: type) type { } pub fn write(self: *Self, bytes: []const u8) Error!usize { - if (bytes.len == 0) return @as(usize, 0); + if (bytes.len == 0) return 0; const current_indent = self.indent_count * Self.indent_delta; if (self.current_line_empty and current_indent > 0) { @@ -7860,7 +7859,7 @@ fn IndentWriter(comptime UnderlyingWriter: type) type { } fn writeNoIndent(self: *Self, bytes: []const u8) Error!usize { - if (bytes.len == 0) return @as(usize, 0); + if (bytes.len == 0) return 0; try self.underlying_writer.writeAll(bytes); if (bytes[bytes.len - 1] == '\n') { @@ -8048,7 +8047,7 @@ fn fmtStringLiteral(str: []const u8, sentinel: ?u8) std.fmt.Formatter(formatStri fn undefPattern(comptime IntType: type) IntType { const int_info = @typeInfo(IntType).int; const UnsignedType = std.meta.Int(.unsigned, int_info.bits); - return @as(IntType, @bitCast(@as(UnsignedType, (1 << (int_info.bits | 1)) / 3))); + return @bitCast(@as(UnsignedType, (1 << (int_info.bits | 1)) / 3)); } const FormatIntLiteralContext = struct { @@ -8188,9 +8187,9 @@ fn formatIntLiteral( wrap.len = wrap.limbs.len; const limbs_per_c_limb = @divExact(wrap.len, c_limb_info.count); - var c_limb_int_info = std.builtin.Type.Int{ + var c_limb_int_info: std.builtin.Type.Int = .{ .signedness = undefined, - .bits = @as(u16, @intCast(@divExact(c_bits, c_limb_info.count))), + .bits = @intCast(@divExact(c_bits, c_limb_info.count)), }; var c_limb_ctype: CType = undefined; @@ -8349,7 +8348,7 @@ fn lowersToArray(ty: Type, pt: Zcu.PerThread) bool { } fn reap(f: *Function, inst: Air.Inst.Index, operands: []const Air.Inst.Ref) !void { - assert(operands.len <= Liveness.bpi - 1); + assert(operands.len <= Air.Liveness.bpi - 1); var tomb_bits = f.liveness.getTombBits(inst); for (operands) |operand| { const dies = @as(u1, @truncate(tomb_bits)) != 0; @@ -8400,7 +8399,7 @@ fn freeLocal(f: *Function, inst: ?Air.Inst.Index, local_index: LocalIndex, ref_i const BigTomb = struct { f: *Function, inst: Air.Inst.Index, - lbt: Liveness.BigTomb, + lbt: Air.Liveness.BigTomb, fn feed(bt: *BigTomb, op_ref: Air.Inst.Ref) !void { const dies = bt.lbt.feed(); |
