Commit 85e3204344

Andrew Kelley <andrew@ziglang.org>
2022-09-21 04:31:43
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.
1 parent 902f6db
src/AstGen.zig
@@ -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,
             } },
         });
src/Autodoc.zig
@@ -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 },
+                    };
+                },
             }
         },
     }
src/print_zir.zig
@@ -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 {
src/Sema.zig
@@ -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);
src/Zir.zig
@@ -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,