Commit 175463d75d

Isaac Freund <isaac.freund@coil.com>
2021-12-07 19:34:44
AstGen: implement @prefetch() builtin
1 parent 47c309c
lib/std/builtin.zig
@@ -651,6 +651,31 @@ pub const CallOptions = struct {
     };
 };
 
+/// This data structure is used by the Zig language code generation and
+/// therefore must be kept in sync with the compiler implementation.
+pub const PrefetchOptions = struct {
+    /// Whether the prefetch should prepare for a read or a write.
+    rw: Rw = .read,
+    /// 0 means no temporal locality. That is, the data can be immediately
+    /// dropped from the cache after it is accessed.
+    ///
+    /// 3 means high temporal locality. That is, the data should be kept in
+    /// the cache as it is likely to be accessed again soon.
+    locality: u2 = 3,
+    /// The cache that the prefetch should be preformed on.
+    cache: Cache = .data,
+
+    pub const Rw = enum {
+        read,
+        write,
+    };
+
+    pub const Cache = enum {
+        instruction,
+        data,
+    };
+};
+
 /// This data structure is used by the Zig language code generation and
 /// therefore must be kept in sync with the compiler implementation.
 pub const ExportOptions = struct {
src/AstGen.zig
@@ -7226,6 +7226,16 @@ fn builtinCall(
             });
             return rvalue(gz, rl, result, node);
         },
+        .prefetch => {
+            const ptr = try expr(gz, scope, .none, params[0]);
+            const options = try comptimeExpr(gz, scope, .{ .ty = .prefetch_options_type }, params[1]);
+            const result = try gz.addExtendedPayload(.prefetch, Zir.Inst.BinNode{
+                .node = gz.nodeIndexToRelative(node),
+                .lhs = ptr,
+                .rhs = options,
+            });
+            return rvalue(gz, rl, result, node);
+        },
     }
 }
 
src/BuiltinFn.zig
@@ -67,6 +67,7 @@ pub const Tag = enum {
     mul_with_overflow,
     panic,
     pop_count,
+    prefetch,
     ptr_cast,
     ptr_to_int,
     rem,
@@ -615,6 +616,13 @@ pub const list = list: {
                 .param_count = 2,
             },
         },
+        .{
+            "@prefetch",
+            .{
+                .tag = .prefetch,
+                .param_count = 2,
+            },
+        },
         .{
             "@ptrCast",
             .{
src/print_zir.zig
@@ -477,7 +477,7 @@ const Writer = struct {
                 try self.writeSrc(stream, src);
             },
 
-            .builtin_extern, .c_define, .wasm_memory_grow => {
+            .builtin_extern, .c_define, .wasm_memory_grow, .prefetch => {
                 const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
                 const src: LazySrcLoc = .{ .node_offset = inst_data.node };
                 try self.writeInstRef(stream, inst_data.lhs);
src/Sema.zig
@@ -1042,6 +1042,7 @@ fn zirExtended(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
         .c_define           => return sema.zirCDefine(           block, extended),
         .wasm_memory_size   => return sema.zirWasmMemorySize(    block, extended),
         .wasm_memory_grow   => return sema.zirWasmMemoryGrow(    block, extended),
+        .prefetch           => return sema.zirPrefetch(          block, extended),
         // zig fmt: on
     }
 }
@@ -11104,6 +11105,16 @@ fn zirWasmMemoryGrow(
     return sema.fail(block, src, "TODO: implement Sema.zirWasmMemoryGrow", .{});
 }
 
+fn zirPrefetch(
+    sema: *Sema,
+    block: *Block,
+    extended: Zir.Inst.Extended.InstData,
+) CompileError!Air.Inst.Ref {
+    const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
+    const src: LazySrcLoc = .{ .node_offset = extra.node };
+    return sema.fail(block, src, "TODO: implement Sema.zirPrefetch", .{});
+}
+
 fn zirBuiltinExtern(
     sema: *Sema,
     block: *Block,
@@ -14231,6 +14242,7 @@ fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Comp
         .float_mode => return sema.resolveBuiltinTypeFields(block, src, "FloatMode"),
         .reduce_op => return sema.resolveBuiltinTypeFields(block, src, "ReduceOp"),
         .call_options => return sema.resolveBuiltinTypeFields(block, src, "CallOptions"),
+        .prefetch_options => return sema.resolveBuiltinTypeFields(block, src, "PrefetchOptions"),
 
         .@"union", .union_tagged => {
             const union_obj = ty.cast(Type.Payload.Union).?.data;
@@ -14819,6 +14831,7 @@ fn typeHasOnePossibleValue(
         .float_mode,
         .reduce_op,
         .call_options,
+        .prefetch_options,
         .export_options,
         .extern_options,
         .type_info,
@@ -15032,6 +15045,7 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
         .float_mode => return .float_mode_type,
         .reduce_op => return .reduce_op_type,
         .call_options => return .call_options_type,
+        .prefetch_options => return .prefetch_options_type,
         .export_options => return .export_options_type,
         .extern_options => return .extern_options_type,
         .type_info => return .type_info_type,
src/type.zig
@@ -123,6 +123,7 @@ pub const Type = extern union {
             .empty_struct_literal,
             .@"struct",
             .call_options,
+            .prefetch_options,
             .export_options,
             .extern_options,
             => return .Struct,
@@ -798,6 +799,7 @@ pub const Type = extern union {
             .float_mode,
             .reduce_op,
             .call_options,
+            .prefetch_options,
             .export_options,
             .extern_options,
             .type_info,
@@ -1027,6 +1029,7 @@ pub const Type = extern union {
                 .float_mode => return writer.writeAll("std.builtin.FloatMode"),
                 .reduce_op => return writer.writeAll("std.builtin.ReduceOp"),
                 .call_options => return writer.writeAll("std.builtin.CallOptions"),
+                .prefetch_options => return writer.writeAll("std.builtin.PrefetchOptions"),
                 .export_options => return writer.writeAll("std.builtin.ExportOptions"),
                 .extern_options => return writer.writeAll("std.builtin.ExternOptions"),
                 .type_info => return writer.writeAll("std.builtin.TypeInfo"),
@@ -1318,6 +1321,7 @@ pub const Type = extern union {
             .float_mode => return "FloatMode",
             .reduce_op => return "ReduceOp",
             .call_options => return "CallOptions",
+            .prefetch_options => return "PrefetchOptions",
             .export_options => return "ExportOptions",
             .extern_options => return "ExternOptions",
             .type_info => return "TypeInfo",
@@ -1376,6 +1380,7 @@ pub const Type = extern union {
             .float_mode,
             .reduce_op,
             .call_options,
+            .prefetch_options,
             .export_options,
             .extern_options,
             .manyptr_u8,
@@ -1502,6 +1507,7 @@ pub const Type = extern union {
             .float_mode => return Value.initTag(.float_mode_type),
             .reduce_op => return Value.initTag(.reduce_op_type),
             .call_options => return Value.initTag(.call_options_type),
+            .prefetch_options => return Value.initTag(.prefetch_options_type),
             .export_options => return Value.initTag(.export_options_type),
             .extern_options => return Value.initTag(.extern_options_type),
             .type_info => return Value.initTag(.type_info_type),
@@ -1563,6 +1569,7 @@ pub const Type = extern union {
             .float_mode,
             .reduce_op,
             .call_options,
+            .prefetch_options,
             .export_options,
             .extern_options,
             .@"anyframe",
@@ -1750,6 +1757,7 @@ pub const Type = extern union {
             .float_mode,
             .reduce_op,
             .call_options,
+            .prefetch_options,
             .export_options,
             .extern_options,
             => return 1,
@@ -1929,6 +1937,7 @@ pub const Type = extern union {
             .var_args_param => unreachable,
             .generic_poison => unreachable,
             .call_options => unreachable, // missing call to resolveTypeFields
+            .prefetch_options => unreachable, // missing call to resolveTypeFields
             .export_options => unreachable, // missing call to resolveTypeFields
             .extern_options => unreachable, // missing call to resolveTypeFields
             .type_info => unreachable, // missing call to resolveTypeFields
@@ -2269,6 +2278,7 @@ pub const Type = extern union {
             .float_mode,
             .reduce_op,
             .call_options,
+            .prefetch_options,
             .export_options,
             .extern_options,
             .type_info,
@@ -2794,6 +2804,7 @@ pub const Type = extern union {
             .float_mode,
             .reduce_op,
             .call_options,
+            .prefetch_options,
             .export_options,
             .extern_options,
             .type_info,
@@ -3294,6 +3305,7 @@ pub const Type = extern union {
             .float_mode,
             .reduce_op,
             .call_options,
+            .prefetch_options,
             .export_options,
             .extern_options,
             .type_info,
@@ -3502,6 +3514,7 @@ pub const Type = extern union {
             .float_mode,
             .reduce_op,
             .call_options,
+            .prefetch_options,
             .export_options,
             .extern_options,
             => @panic("TODO resolve std.builtin types"),
@@ -3577,6 +3590,7 @@ pub const Type = extern union {
             .float_mode,
             .reduce_op,
             .call_options,
+            .prefetch_options,
             .export_options,
             .extern_options,
             => @panic("TODO resolve std.builtin types"),
@@ -3701,6 +3715,7 @@ pub const Type = extern union {
             .float_mode,
             .reduce_op,
             .call_options,
+            .prefetch_options,
             .export_options,
             .extern_options,
             .type_info,
@@ -3741,6 +3756,7 @@ pub const Type = extern union {
             .float_mode,
             .reduce_op,
             .call_options,
+            .prefetch_options,
             .export_options,
             .extern_options,
             .type_info,
@@ -3801,6 +3817,7 @@ pub const Type = extern union {
             .float_mode,
             .reduce_op,
             .call_options,
+            .prefetch_options,
             .export_options,
             .extern_options,
             => @panic("TODO resolve std.builtin types"),
@@ -3862,6 +3879,7 @@ pub const Type = extern union {
         float_mode,
         reduce_op,
         call_options,
+        prefetch_options,
         export_options,
         extern_options,
         type_info,
@@ -3989,6 +4007,7 @@ pub const Type = extern union {
                 .float_mode,
                 .reduce_op,
                 .call_options,
+                .prefetch_options,
                 .export_options,
                 .extern_options,
                 .type_info,
src/value.zig
@@ -67,6 +67,7 @@ pub const Value = extern union {
         float_mode_type,
         reduce_op_type,
         call_options_type,
+        prefetch_options_type,
         export_options_type,
         extern_options_type,
         type_info_type,
@@ -244,6 +245,7 @@ pub const Value = extern union {
                 .float_mode_type,
                 .reduce_op_type,
                 .call_options_type,
+                .prefetch_options_type,
                 .export_options_type,
                 .extern_options_type,
                 .type_info_type,
@@ -434,6 +436,7 @@ pub const Value = extern union {
             .float_mode_type,
             .reduce_op_type,
             .call_options_type,
+            .prefetch_options_type,
             .export_options_type,
             .extern_options_type,
             .type_info_type,
@@ -652,6 +655,7 @@ pub const Value = extern union {
             .float_mode_type => return out_stream.writeAll("std.builtin.FloatMode"),
             .reduce_op_type => return out_stream.writeAll("std.builtin.ReduceOp"),
             .call_options_type => return out_stream.writeAll("std.builtin.CallOptions"),
+            .prefetch_options_type => return out_stream.writeAll("std.builtin.PrefetchOptions"),
             .export_options_type => return out_stream.writeAll("std.builtin.ExportOptions"),
             .extern_options_type => return out_stream.writeAll("std.builtin.ExternOptions"),
             .type_info_type => return out_stream.writeAll("std.builtin.TypeInfo"),
@@ -829,6 +833,7 @@ pub const Value = extern union {
             .float_mode_type => Type.initTag(.float_mode),
             .reduce_op_type => Type.initTag(.reduce_op),
             .call_options_type => Type.initTag(.call_options),
+            .prefetch_options_type => Type.initTag(.prefetch_options),
             .export_options_type => Type.initTag(.export_options),
             .extern_options_type => Type.initTag(.extern_options),
             .type_info_type => Type.initTag(.type_info),
src/Zir.zig
@@ -1572,6 +1572,9 @@ pub const Inst = struct {
         wasm_memory_size,
         /// `operand` is payload index to `BinNode`.
         wasm_memory_grow,
+        /// The `@prefetch` builtin.
+        /// `operand` is payload index to `BinNode`.
+        prefetch,
 
         pub const InstData = struct {
             opcode: Extended,
@@ -1648,6 +1651,7 @@ pub const Inst = struct {
         float_mode_type,
         reduce_op_type,
         call_options_type,
+        prefetch_options_type,
         export_options_type,
         extern_options_type,
         type_info_type,
@@ -1917,6 +1921,10 @@ pub const Inst = struct {
                 .ty = Type.initTag(.type),
                 .val = Value.initTag(.call_options_type),
             },
+            .prefetch_options_type = .{
+                .ty = Type.initTag(.type),
+                .val = Value.initTag(.prefetch_options_type),
+            },
             .export_options_type = .{
                 .ty = Type.initTag(.type),
                 .val = Value.initTag(.export_options_type),