authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-24 17:31:52-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-24 17:44:07-07:00
logff2ec0dc5ad272113379ff485bb71c6c1637d948
tree64a073251b80178a293434d8df9aa4cc5998bf4c
parente018e64a53eb7fdffedb3efadb862f400f9e9f70

AstGen: implement `@Vector`


5 files changed, 82 insertions(+), 15 deletions(-)

src/AstGen.zig+9
......@@ -1808,6 +1808,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
18081808 .array_mul,
18091809 .array_type,
18101810 .array_type_sentinel,
1811 .vector_type,
18111812 .elem_type,
18121813 .indexable_ptr_len,
18131814 .anyframe_type,
......@@ -6510,6 +6511,14 @@ fn builtinCall(
65106511 });
65116512 return rvalue(gz, scope, rl, result, node);
65126513 },
6514 .Vector => {
6515 const result = try gz.addPlNode(.vector_type, node, Zir.Inst.Bin{
6516 .lhs = try comptimeExpr(gz, scope, .{.ty = .u32_type}, params[0]),
6517 .rhs = try typeExpr(gz, scope, params[1]),
6518 });
6519 return rvalue(gz, scope, rl, result, node);
6520 },
6521
65136522 }
65146523 // zig fmt: on
65156524}
src/BuiltinFn.zig+8
......@@ -104,6 +104,7 @@ pub const Tag = enum {
104104 type_name,
105105 TypeOf,
106106 union_init,
107 Vector,
107108};
108109
109110tag: Tag,
......@@ -848,5 +849,12 @@ pub const list = list: {
848849 .param_count = 3,
849850 },
850851 },
852 .{
853 "@Vector",
854 .{
855 .tag = .Vector,
856 .param_count = 2,
857 },
858 },
851859 });
852860};
src/Sema.zig+16
......@@ -143,6 +143,7 @@ pub fn analyzeBody(
143143 .array_mul => try sema.zirArrayMul(block, inst),
144144 .array_type => try sema.zirArrayType(block, inst),
145145 .array_type_sentinel => try sema.zirArrayTypeSentinel(block, inst),
146 .vector_type => try sema.zirVectorType(block, inst),
146147 .as => try sema.zirAs(block, inst),
147148 .as_node => try sema.zirAsNode(block, inst),
148149 .bit_and => try sema.zirBitwise(block, inst, .bit_and),
......@@ -2143,6 +2144,21 @@ fn zirElemType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
21432144 return sema.mod.constType(sema.arena, src, elem_type);
21442145}
21452146
2147fn zirVectorType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
2148 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2149 const src = inst_data.src();
2150 const elem_type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
2151 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
2152 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2153 const len = try sema.resolveAlreadyCoercedInt(block, len_src, extra.lhs, u32);
2154 const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs);
2155 const vector_type = try Type.Tag.vector.create(sema.arena, .{
2156 .len = len,
2157 .elem_type = elem_type,
2158 });
2159 return sema.mod.constType(sema.arena, src, vector_type);
2160}
2161
21462162fn zirArrayType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
21472163 const tracy = trace(@src());
21482164 defer tracy.end();
src/Zir.zig+6
......@@ -158,6 +158,10 @@ pub const Inst = struct {
158158 /// `[N:S]T` syntax. No source location provided.
159159 /// Uses the `array_type_sentinel` field.
160160 array_type_sentinel,
161 /// `@Vector` builtin.
162 /// Uses the `pl_node` union field with `Bin` payload.
163 /// lhs is length, rhs is element type.
164 vector_type,
161165 /// Given an array type, returns the element type.
162166 /// Uses the `un_node` union field.
163167 elem_type,
......@@ -952,6 +956,7 @@ pub const Inst = struct {
952956 .array_mul,
953957 .array_type,
954958 .array_type_sentinel,
959 .vector_type,
955960 .elem_type,
956961 .indexable_ptr_len,
957962 .anyframe_type,
......@@ -2542,6 +2547,7 @@ const Writer = struct {
25422547 .atomic_load,
25432548 .bitcast,
25442549 .bitcast_result_ptr,
2550 .vector_type,
25452551 => try self.writePlNodeBin(stream, inst),
25462552
25472553 .@"export" => try self.writePlNodeExport(stream, inst),
src/type.zig+43-15
......@@ -69,7 +69,14 @@ pub const Type = extern union {
6969 .fn_ccc_void_no_args => return .Fn,
7070 .function => return .Fn,
7171
72 .array, .array_u8_sentinel_0, .array_u8, .array_sentinel => return .Array,
72 .array,
73 .array_u8_sentinel_0,
74 .array_u8,
75 .array_sentinel,
76 => return .Array,
77
78 .vector => return .Vector,
79
7380 .single_const_pointer_to_comptime_int,
7481 .const_slice_u8,
7582 .single_const_pointer,
......@@ -438,7 +445,7 @@ pub const Type = extern union {
438445 const info_b = b.intInfo(@as(Target, undefined));
439446 return info_a.signedness == info_b.signedness and info_a.bits == info_b.bits;
440447 },
441 .Array => {
448 .Array, .Vector => {
442449 if (a.arrayLen() != b.arrayLen())
443450 return false;
444451 if (!a.elemType().eql(b.elemType()))
......@@ -487,7 +494,6 @@ pub const Type = extern union {
487494 .BoundFn,
488495 .Opaque,
489496 .Frame,
490 .Vector,
491497 => std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }),
492498 }
493499 }
......@@ -522,7 +528,7 @@ pub const Type = extern union {
522528 std.hash.autoHash(&hasher, info.bits);
523529 }
524530 },
525 .Array => {
531 .Array, .Vector => {
526532 std.hash.autoHash(&hasher, self.arrayLen());
527533 std.hash.autoHash(&hasher, self.elemType().hash());
528534 // TODO hash array sentinel
......@@ -552,7 +558,6 @@ pub const Type = extern union {
552558 .Opaque,
553559 .Frame,
554560 .AnyFrame,
555 .Vector,
556561 .EnumLiteral,
557562 => {
558563 // TODO implement more type hashing
......@@ -647,6 +652,13 @@ pub const Type = extern union {
647652 .int_unsigned,
648653 => return self.copyPayloadShallow(allocator, Payload.Bits),
649654
655 .vector => {
656 const payload = self.castTag(.vector).?.data;
657 return Tag.vector.create(allocator, .{
658 .len = payload.len,
659 .elem_type = try payload.elem_type.copy(allocator),
660 });
661 },
650662 .array => {
651663 const payload = self.castTag(.array).?.data;
652664 return Tag.array.create(allocator, .{
......@@ -839,6 +851,12 @@ pub const Type = extern union {
839851 const len = ty.castTag(.array_u8_sentinel_0).?.data;
840852 return writer.print("[{d}:0]u8", .{len});
841853 },
854 .vector => {
855 const payload = ty.castTag(.vector).?.data;
856 try writer.print("@Vector({d}, ", .{payload.len});
857 try payload.elem_type.format("", .{}, writer);
858 return writer.writeAll(")");
859 },
842860 .array => {
843861 const payload = ty.castTag(.array).?.data;
844862 try writer.print("[{d}]", .{payload.len});
......@@ -1116,7 +1134,7 @@ pub const Type = extern union {
11161134 },
11171135
11181136 // TODO lazy types
1119 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
1137 .array, .vector => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
11201138 .array_u8 => self.arrayLen() != 0,
11211139 .array_sentinel, .single_const_pointer, .single_mut_pointer, .many_const_pointer, .many_mut_pointer, .c_const_pointer, .c_mut_pointer, .const_slice, .mut_slice, .pointer => self.elemType().hasCodeGenBits(),
11221140 .int_signed, .int_unsigned => self.cast(Payload.Bits).?.data != 0,
......@@ -1264,6 +1282,10 @@ pub const Type = extern union {
12641282
12651283 .array, .array_sentinel => return self.elemType().abiAlignment(target),
12661284
1285 // TODO audit this - is there any more complicated logic to determine
1286 // ABI alignment of vectors?
1287 .vector => return 16,
1288
12671289 .int_signed, .int_unsigned => {
12681290 const bits: u16 = self.cast(Payload.Bits).?.data;
12691291 return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8);
......@@ -1386,8 +1408,8 @@ pub const Type = extern union {
13861408
13871409 .array_u8 => self.castTag(.array_u8).?.data,
13881410 .array_u8_sentinel_0 => self.castTag(.array_u8_sentinel_0).?.data + 1,
1389 .array => {
1390 const payload = self.castTag(.array).?.data;
1411 .array, .vector => {
1412 const payload = self.cast(Payload.Array).?.data;
13911413 const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));
13921414 return payload.len * elem_size;
13931415 },
......@@ -1534,6 +1556,11 @@ pub const Type = extern union {
15341556
15351557 .bool => 1,
15361558
1559 .vector => {
1560 const payload = self.castTag(.vector).?.data;
1561 const elem_bit_size = payload.elem_type.bitSize(target);
1562 return elem_bit_size * payload.len;
1563 },
15371564 .array_u8 => 8 * self.castTag(.array_u8).?.data,
15381565 .array_u8_sentinel_0 => 8 * (self.castTag(.array_u8_sentinel_0).?.data + 1),
15391566 .array => {
......@@ -1811,7 +1838,6 @@ pub const Type = extern union {
18111838 .Enum,
18121839 .Frame,
18131840 .AnyFrame,
1814 .Vector,
18151841 => return true,
18161842
18171843 .Opaque => return is_extern,
......@@ -1830,7 +1856,7 @@ pub const Type = extern union {
18301856 var buf: Payload.ElemType = undefined;
18311857 return ty.optionalChild(&buf).isValidVarType(is_extern);
18321858 },
1833 .Pointer, .Array => ty = ty.elemType(),
1859 .Pointer, .Array, .Vector => ty = ty.elemType(),
18341860 .ErrorUnion => ty = ty.errorUnionChild(),
18351861
18361862 .Fn => @panic("TODO fn isValidVarType"),
......@@ -1846,6 +1872,7 @@ pub const Type = extern union {
18461872 /// Asserts the type is a pointer or array type.
18471873 pub fn elemType(self: Type) Type {
18481874 return switch (self.tag()) {
1875 .vector => self.castTag(.vector).?.data.elem_type,
18491876 .array => self.castTag(.array).?.data.elem_type,
18501877 .array_sentinel => self.castTag(.array_sentinel).?.data.elem_type,
18511878 .single_const_pointer,
......@@ -1936,6 +1963,7 @@ pub const Type = extern union {
19361963 /// Asserts the type is an array or vector.
19371964 pub fn arrayLen(self: Type) u64 {
19381965 return switch (self.tag()) {
1966 .vector => self.castTag(.vector).?.data.len,
19391967 .array => self.castTag(.array).?.data.len,
19401968 .array_sentinel => self.castTag(.array_sentinel).?.data.len,
19411969 .array_u8 => self.castTag(.array_u8).?.data,
......@@ -1955,6 +1983,7 @@ pub const Type = extern union {
19551983 .c_const_pointer,
19561984 .c_mut_pointer,
19571985 .single_const_pointer_to_comptime_int,
1986 .vector,
19581987 .array,
19591988 .array_u8,
19601989 .manyptr_u8,
......@@ -2325,7 +2354,7 @@ pub const Type = extern union {
23252354 return null;
23262355 }
23272356 },
2328 .array, .array_u8 => {
2357 .vector, .array, .array_u8 => {
23292358 if (ty.arrayLen() == 0)
23302359 return Value.initTag(.empty_array);
23312360 ty = ty.elemType();
......@@ -2730,6 +2759,7 @@ pub const Type = extern union {
27302759 array_u8_sentinel_0,
27312760 array,
27322761 array_sentinel,
2762 vector,
27332763 pointer,
27342764 single_const_pointer,
27352765 single_mut_pointer,
......@@ -2845,7 +2875,7 @@ pub const Type = extern union {
28452875
28462876 .error_set => Payload.ErrorSet,
28472877
2848 .array => Payload.Array,
2878 .array, .vector => Payload.Array,
28492879 .array_sentinel => Payload.ArraySentinel,
28502880 .pointer => Payload.Pointer,
28512881 .function => Payload.Function,
......@@ -2888,9 +2918,7 @@ pub const Type = extern union {
28882918 };
28892919
28902920 pub const Array = struct {
2891 pub const base_tag = Tag.array;
2892
2893 base: Payload = Payload{ .tag = base_tag },
2921 base: Payload,
28942922 data: struct {
28952923 len: u64,
28962924 elem_type: Type,