stage2: free up 2 ZIR tags

cmpxchg_weak and cmpxchg_strong are not very common; demote them to
extended operations to make some headroom.

This commit does not change any behavior, only memory layout of the
compiler.
This commit is contained in:
Andrew Kelley 2022-09-20 19:31:43 -07:00
parent 902f6db67b
commit 85e3204344
5 changed files with 111 additions and 104 deletions

View File

@ -2439,8 +2439,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
.shr_exact,
.bit_offset_of,
.offset_of,
.cmpxchg_strong,
.cmpxchg_weak,
.splat,
.reduce,
.shuffle,
@ -7753,8 +7751,8 @@ fn builtinCall(
.c_undef => return simpleCBuiltin(gz, scope, rl, node, params[0], .c_undef),
.c_include => return simpleCBuiltin(gz, scope, rl, node, params[0], .c_include),
.cmpxchg_strong => return cmpxchg(gz, scope, rl, node, params, .cmpxchg_strong),
.cmpxchg_weak => return cmpxchg(gz, scope, rl, node, params, .cmpxchg_weak),
.cmpxchg_strong => return cmpxchg(gz, scope, rl, node, params, 1),
.cmpxchg_weak => return cmpxchg(gz, scope, rl, node, params, 0),
// zig fmt: on
.wasm_memory_size => {
@ -8080,11 +8078,12 @@ fn cmpxchg(
rl: ResultLoc,
node: Ast.Node.Index,
params: []const Ast.Node.Index,
tag: Zir.Inst.Tag,
small: u16,
) InnerError!Zir.Inst.Ref {
const int_type = try typeExpr(gz, scope, params[0]);
const result = try gz.addPlNode(tag, node, Zir.Inst.Cmpxchg{
const result = try gz.addExtendedPayloadSmall(.cmpxchg, small, Zir.Inst.Cmpxchg{
// zig fmt: off
.node = gz.nodeIndexToRelative(node),
.ptr = try expr(gz, scope, .none, params[1]),
.expected_value = try expr(gz, scope, .{ .ty = int_type }, params[2]),
.new_value = try expr(gz, scope, .{ .coerced_ty = int_type }, params[3]),
@ -10904,9 +10903,14 @@ const GenZir = struct {
return new_index;
}
fn addExtendedPayload(
fn addExtendedPayload(gz: *GenZir, opcode: Zir.Inst.Extended, extra: anytype) !Zir.Inst.Ref {
return addExtendedPayloadSmall(gz, opcode, undefined, extra);
}
fn addExtendedPayloadSmall(
gz: *GenZir,
opcode: Zir.Inst.Extended,
small: u16,
extra: anytype,
) !Zir.Inst.Ref {
const gpa = gz.astgen.gpa;
@ -10920,7 +10924,7 @@ const GenZir = struct {
.tag = .extended,
.data = .{ .extended = .{
.opcode = opcode,
.small = undefined,
.small = small,
.operand = payload_index,
} },
});

View File

@ -998,72 +998,6 @@ fn walkInstruction(
const un_tok = data[inst_index].un_tok;
return try self.walkRef(file, parent_scope, parent_src, un_tok.operand, need_type);
},
.cmpxchg_strong, .cmpxchg_weak => {
const pl_node = data[inst_index].pl_node;
const extra = file.zir.extraData(Zir.Inst.Cmpxchg, pl_node.payload_index);
const last_type_index = self.exprs.items.len;
const last_type = self.exprs.items[last_type_index - 1];
const type_index = self.exprs.items.len;
try self.exprs.append(self.arena, last_type);
const ptr_index = self.exprs.items.len;
var ptr: DocData.WalkResult = try self.walkRef(
file,
parent_scope,
parent_src,
extra.data.ptr,
false,
);
try self.exprs.append(self.arena, ptr.expr);
const expected_value_index = self.exprs.items.len;
var expected_value: DocData.WalkResult = try self.walkRef(
file,
parent_scope,
parent_src,
extra.data.expected_value,
false,
);
try self.exprs.append(self.arena, expected_value.expr);
const new_value_index = self.exprs.items.len;
var new_value: DocData.WalkResult = try self.walkRef(
file,
parent_scope,
parent_src,
extra.data.new_value,
false,
);
try self.exprs.append(self.arena, new_value.expr);
const success_order_index = self.exprs.items.len;
var success_order: DocData.WalkResult = try self.walkRef(
file,
parent_scope,
parent_src,
extra.data.success_order,
false,
);
try self.exprs.append(self.arena, success_order.expr);
const failure_order_index = self.exprs.items.len;
var failure_order: DocData.WalkResult = try self.walkRef(
file,
parent_scope,
parent_src,
extra.data.failure_order,
false,
);
try self.exprs.append(self.arena, failure_order.expr);
const cmpxchg_index = self.exprs.items.len;
try self.exprs.append(self.arena, .{ .cmpxchg = .{ .name = @tagName(tags[inst_index]), .type = type_index, .ptr = ptr_index, .expected_value = expected_value_index, .new_value = new_value_index, .success_order = success_order_index, .failure_order = failure_order_index } });
return DocData.WalkResult{
.typeRef = .{ .type = @enumToInt(Ref.type_type) },
.expr = .{ .cmpxchgIndex = cmpxchg_index },
};
},
.str => {
const str = data[inst_index].str.get(file.zir);
@ -3047,6 +2981,79 @@ fn walkInstruction(
.expr = .{ .builtinIndex = bin_index },
};
},
.cmpxchg => {
const extra = file.zir.extraData(Zir.Inst.Cmpxchg, extended.operand).data;
const last_type_index = self.exprs.items.len;
const last_type = self.exprs.items[last_type_index - 1];
const type_index = self.exprs.items.len;
try self.exprs.append(self.arena, last_type);
const ptr_index = self.exprs.items.len;
var ptr: DocData.WalkResult = try self.walkRef(
file,
parent_scope,
parent_src,
extra.ptr,
false,
);
try self.exprs.append(self.arena, ptr.expr);
const expected_value_index = self.exprs.items.len;
var expected_value: DocData.WalkResult = try self.walkRef(
file,
parent_scope,
parent_src,
extra.expected_value,
false,
);
try self.exprs.append(self.arena, expected_value.expr);
const new_value_index = self.exprs.items.len;
var new_value: DocData.WalkResult = try self.walkRef(
file,
parent_scope,
parent_src,
extra.new_value,
false,
);
try self.exprs.append(self.arena, new_value.expr);
const success_order_index = self.exprs.items.len;
var success_order: DocData.WalkResult = try self.walkRef(
file,
parent_scope,
parent_src,
extra.success_order,
false,
);
try self.exprs.append(self.arena, success_order.expr);
const failure_order_index = self.exprs.items.len;
var failure_order: DocData.WalkResult = try self.walkRef(
file,
parent_scope,
parent_src,
extra.failure_order,
false,
);
try self.exprs.append(self.arena, failure_order.expr);
const cmpxchg_index = self.exprs.items.len;
try self.exprs.append(self.arena, .{ .cmpxchg = .{
.name = @tagName(tags[inst_index]),
.type = type_index,
.ptr = ptr_index,
.expected_value = expected_value_index,
.new_value = new_value_index,
.success_order = success_order_index,
.failure_order = failure_order_index,
} });
return DocData.WalkResult{
.typeRef = .{ .type = @enumToInt(Ref.type_type) },
.expr = .{ .cmpxchgIndex = cmpxchg_index },
};
},
}
},
}

View File

@ -839,8 +839,6 @@ fn analyzeBodyInner(
.bit_reverse => try sema.zirBitReverse(block, inst),
.bit_offset_of => try sema.zirBitOffsetOf(block, inst),
.offset_of => try sema.zirOffsetOf(block, inst),
.cmpxchg_strong => try sema.zirCmpxchg(block, inst, .cmpxchg_strong),
.cmpxchg_weak => try sema.zirCmpxchg(block, inst, .cmpxchg_weak),
.splat => try sema.zirSplat(block, inst),
.reduce => try sema.zirReduce(block, inst),
.shuffle => try sema.zirShuffle(block, inst),
@ -957,6 +955,8 @@ fn analyzeBodyInner(
.int_to_error => try sema.zirIntToError( block, extended),
.reify => try sema.zirReify( block, extended, inst),
.builtin_async_call => try sema.zirBuiltinAsyncCall( block, extended),
.cmpxchg => try sema.zirCmpxchg( block, extended),
// zig fmt: on
.fence => {
try sema.zirFence(block, extended);
@ -18891,19 +18891,22 @@ fn resolveAtomicRmwOp(
fn zirCmpxchg(
sema: *Sema,
block: *Block,
inst: Zir.Inst.Index,
air_tag: Air.Inst.Tag,
extended: Zir.Inst.Extended.InstData,
) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const extra = sema.code.extraData(Zir.Inst.Cmpxchg, inst_data.payload_index).data;
const src = inst_data.src();
const extra = sema.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data;
const air_tag: Air.Inst.Tag = switch (extended.small) {
0 => .cmpxchg_weak,
1 => .cmpxchg_strong,
else => unreachable,
};
const src = LazySrcLoc.nodeOffset(extra.node);
// zig fmt: off
const elem_ty_src : LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
const expected_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
const new_value_src : LazySrcLoc = .{ .node_offset_builtin_call_arg3 = inst_data.src_node };
const success_order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg4 = inst_data.src_node };
const failure_order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg5 = inst_data.src_node };
const elem_ty_src : LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
const expected_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = extra.node };
const new_value_src : LazySrcLoc = .{ .node_offset_builtin_call_arg3 = extra.node };
const success_order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg4 = extra.node };
const failure_order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg5 = extra.node };
// zig fmt: on
const expected_value = try sema.resolveInst(extra.expected_value);
const elem_ty = sema.typeOf(expected_value);

View File

@ -890,12 +890,6 @@ pub const Inst = struct {
/// Implements the `@offsetOf` builtin.
/// Uses the `pl_node` union field with payload `Bin`.
offset_of,
/// Implements the `@cmpxchgStrong` builtin.
/// Uses the `pl_node` union field with payload `Cmpxchg`.
cmpxchg_strong,
/// Implements the `@cmpxchgWeak` builtin.
/// Uses the `pl_node` union field with payload `Cmpxchg`.
cmpxchg_weak,
/// Implements the `@splat` builtin.
/// Uses the `pl_node` union field with payload `Bin`.
splat,
@ -1211,8 +1205,6 @@ pub const Inst = struct {
.shr_exact,
.bit_offset_of,
.offset_of,
.cmpxchg_strong,
.cmpxchg_weak,
.splat,
.reduce,
.shuffle,
@ -1498,8 +1490,6 @@ pub const Inst = struct {
.shr_exact,
.bit_offset_of,
.offset_of,
.cmpxchg_strong,
.cmpxchg_weak,
.splat,
.reduce,
.shuffle,
@ -1781,8 +1771,6 @@ pub const Inst = struct {
.bit_offset_of = .pl_node,
.offset_of = .pl_node,
.cmpxchg_strong = .pl_node,
.cmpxchg_weak = .pl_node,
.splat = .pl_node,
.reduce = .pl_node,
.shuffle = .pl_node,
@ -1972,6 +1960,10 @@ pub const Inst = struct {
/// Implements the `@asyncCall` builtin.
/// `operand` is payload index to `AsyncCall`.
builtin_async_call,
/// Implements the `@cmpxchgStrong` and `@cmpxchgWeak` builtins.
/// `small` 0=>weak 1=>strong
/// `operand` is payload index to `Cmpxchg`.
cmpxchg,
pub const InstData = struct {
opcode: Extended,
@ -3392,6 +3384,7 @@ pub const Inst = struct {
};
pub const Cmpxchg = struct {
node: i32,
ptr: Ref,
expected_value: Ref,
new_value: Ref,

View File

@ -272,7 +272,6 @@ const Writer = struct {
.struct_init_ref,
=> try self.writeStructInit(stream, inst),
.cmpxchg_strong, .cmpxchg_weak => try self.writeCmpxchg(stream, inst),
.atomic_load => try self.writeAtomicLoad(stream, inst),
.atomic_store => try self.writeAtomicStore(stream, inst),
.atomic_rmw => try self.writeAtomicRmw(stream, inst),
@ -532,6 +531,7 @@ const Writer = struct {
try self.writeSrc(stream, src);
},
.builtin_async_call => try self.writeBuiltinAsyncCall(stream, extended),
.cmpxchg => try self.writeCmpxchg(stream, extended),
}
}
@ -912,9 +912,9 @@ const Writer = struct {
try self.writeSrc(stream, inst_data.src());
}
fn writeCmpxchg(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
const inst_data = self.code.instructions.items(.data)[inst].pl_node;
const extra = self.code.extraData(Zir.Inst.Cmpxchg, inst_data.payload_index).data;
fn writeCmpxchg(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
const extra = self.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data;
const src = LazySrcLoc.nodeOffset(extra.node);
try self.writeInstRef(stream, extra.ptr);
try stream.writeAll(", ");
@ -926,7 +926,7 @@ const Writer = struct {
try stream.writeAll(", ");
try self.writeInstRef(stream, extra.failure_order);
try stream.writeAll(") ");
try self.writeSrc(stream, inst_data.src());
try self.writeSrc(stream, src);
}
fn writeAtomicLoad(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {