authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-01-30 23:36:52-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-01-30 23:39:25-05:00
log545064c1d9137a603e3e28aa066ce9e65a1ed4b6
tree1ab105ff0a2ec650c82aca4cb688b28ee54191b2
parent169a789b343e9070b4658de9c8bd96c6736c6edc
signature Commit is signed but in an unrecognized format.

introduce vector type for SIMD

See #903 * create with `@Vector(len, ElemType)` * only wrapping addition is implemented This feature is far from complete; this is only the beginning.

12 files changed, 419 insertions(+), 54 deletions(-)

doc/langref.html.in+34
......@@ -1531,6 +1531,29 @@ test "array initialization with function calls" {
15311531 {#code_end#}
15321532 {#see_also|for|Slices#}
15331533 {#header_close#}
1534
1535 {#header_open|Vectors#}
1536 <p>
1537 A vector is a group of {#link|Integers#}, {#link|Floats#}, or {#link|Pointers#} which are operated on
1538 in parallel using a single instruction ({#link|SIMD#}). Vector types are created with the builtin
1539 function {#link|@Vector#}.
1540 </p>
1541 <p>
1542 TODO talk about C ABI interop
1543 </p>
1544 {#header_open|SIMD#}
1545 <p>
1546 TODO Zig's SIMD abilities are just beginning to be fleshed out. Here are some talking points to update the
1547 docs with:
1548 * What kind of operations can you do? All the operations on integers and floats? What about mixing scalar and vector?
1549 * How to convert to/from vectors/arrays
1550 * How to access individual elements from vectors, how to loop over the elements
1551 * "shuffle"
1552 * Advice on writing high perf software, how to abstract the best way
1553 </p>
1554 {#header_close#}
1555 {#header_close#}
1556
15341557 {#header_open|Pointers#}
15351558 <p>
15361559 Zig has two kinds of pointers:
......@@ -6607,6 +6630,17 @@ pub const TypeInfo = union(TypeId) {
66076630 expression passed as an argument. The expression is evaluated.
66086631 </p>
66096632
6633 {#header_close#}
6634
6635 {#header_open|@Vector#}
6636 <pre>{#syntax#}@Vector(comptime len: u32, comptime ElemType: type) type{#endsyntax#}</pre>
6637 <p>
6638 This function returns a vector type for {#link|SIMD#}.
6639 </p>
6640 <p>
6641 {#syntax#}ElemType{#endsyntax#} must be an {#link|integer|Integers#}, a {#link|float|Floats#}, or a
6642 {#link|pointer|Pointers#}.
6643 </p>
66106644 {#header_close#}
66116645 {#header_close#}
66126646
src-self-hosted/type.zig+16
......@@ -44,6 +44,7 @@ pub const Type = struct {
4444 Id.ArgTuple => @fieldParentPtr(ArgTuple, "base", base).destroy(comp),
4545 Id.Opaque => @fieldParentPtr(Opaque, "base", base).destroy(comp),
4646 Id.Promise => @fieldParentPtr(Promise, "base", base).destroy(comp),
47 Id.Vector => @fieldParentPtr(Vector, "base", base).destroy(comp),
4748 }
4849 }
4950
......@@ -77,6 +78,7 @@ pub const Type = struct {
7778 Id.ArgTuple => unreachable,
7879 Id.Opaque => return @fieldParentPtr(Opaque, "base", base).getLlvmType(allocator, llvm_context),
7980 Id.Promise => return @fieldParentPtr(Promise, "base", base).getLlvmType(allocator, llvm_context),
81 Id.Vector => return @fieldParentPtr(Vector, "base", base).getLlvmType(allocator, llvm_context),
8082 }
8183 }
8284
......@@ -103,6 +105,7 @@ pub const Type = struct {
103105 Id.Enum,
104106 Id.Fn,
105107 Id.Promise,
108 Id.Vector,
106109 => return false,
107110
108111 Id.Struct => @panic("TODO"),
......@@ -135,6 +138,7 @@ pub const Type = struct {
135138 Id.Float,
136139 Id.Fn,
137140 Id.Promise,
141 Id.Vector,
138142 => return true,
139143
140144 Id.Pointer => {
......@@ -902,6 +906,18 @@ pub const Type = struct {
902906 }
903907 };
904908
909 pub const Vector = struct {
910 base: Type,
911
912 pub fn destroy(self: *Vector, comp: *Compilation) void {
913 comp.gpa().destroy(self);
914 }
915
916 pub fn getLlvmType(self: *Vector, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef {
917 @panic("TODO");
918 }
919 };
920
905921 pub const ComptimeFloat = struct {
906922 base: Type,
907923
src/all_types.hpp+26
......@@ -252,6 +252,10 @@ struct ConstArgTuple {
252252 size_t end_index;
253253};
254254
255struct ConstVector {
256 ConstExprValue *elements;
257};
258
255259enum ConstValSpecial {
256260 ConstValSpecialRuntime,
257261 ConstValSpecialStatic,
......@@ -318,6 +322,7 @@ struct ConstExprValue {
318322 ConstPtrValue x_ptr;
319323 ImportTableEntry *x_import;
320324 ConstArgTuple x_arg_tuple;
325 ConstVector x_vector;
321326
322327 // populated if special == ConstValSpecialRuntime
323328 RuntimeHintErrorUnion rh_error_union;
......@@ -1210,6 +1215,12 @@ struct ZigTypePromise {
12101215 ZigType *result_type;
12111216};
12121217
1218struct ZigTypeVector {
1219 // The type must be a pointer, integer, or float
1220 ZigType *elem_type;
1221 uint32_t len;
1222};
1223
12131224enum ZigTypeId {
12141225 ZigTypeIdInvalid,
12151226 ZigTypeIdMetaType,
......@@ -1236,6 +1247,7 @@ enum ZigTypeId {
12361247 ZigTypeIdArgTuple,
12371248 ZigTypeIdOpaque,
12381249 ZigTypeIdPromise,
1250 ZigTypeIdVector,
12391251};
12401252
12411253struct ZigType {
......@@ -1262,6 +1274,7 @@ struct ZigType {
12621274 ZigTypeFn fn;
12631275 ZigTypeBoundFn bound_fn;
12641276 ZigTypePromise promise;
1277 ZigTypeVector vector;
12651278 } data;
12661279
12671280 // use these fields to make sure we don't duplicate type table entries for the same type
......@@ -1415,6 +1428,7 @@ enum BuiltinFnId {
14151428 BuiltinFnIdEnumToInt,
14161429 BuiltinFnIdIntToEnum,
14171430 BuiltinFnIdIntType,
1431 BuiltinFnIdVectorType,
14181432 BuiltinFnIdSetCold,
14191433 BuiltinFnIdSetRuntimeSafety,
14201434 BuiltinFnIdSetFloatMode,
......@@ -1505,6 +1519,10 @@ struct TypeId {
15051519 ZigType *err_set_type;
15061520 ZigType *payload_type;
15071521 } error_union;
1522 struct {
1523 ZigType *elem_type;
1524 uint32_t len;
1525 } vector;
15081526 } data;
15091527};
15101528
......@@ -2139,6 +2157,7 @@ enum IrInstructionId {
21392157 IrInstructionIdFloatToInt,
21402158 IrInstructionIdBoolToInt,
21412159 IrInstructionIdIntType,
2160 IrInstructionIdVectorType,
21422161 IrInstructionIdBoolNot,
21432162 IrInstructionIdMemset,
21442163 IrInstructionIdMemcpy,
......@@ -2807,6 +2826,13 @@ struct IrInstructionIntType {
28072826 IrInstruction *bit_count;
28082827};
28092828
2829struct IrInstructionVectorType {
2830 IrInstruction base;
2831
2832 IrInstruction *len;
2833 IrInstruction *elem_type;
2834};
2835
28102836struct IrInstructionBoolNot {
28112837 IrInstruction base;
28122838
src/analyze.cpp+85-6
......@@ -250,6 +250,7 @@ AstNode *type_decl_node(ZigType *type_entry) {
250250 case ZigTypeIdBoundFn:
251251 case ZigTypeIdArgTuple:
252252 case ZigTypeIdPromise:
253 case ZigTypeIdVector:
253254 return nullptr;
254255 }
255256 zig_unreachable();
......@@ -311,6 +312,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
311312 case ZigTypeIdBoundFn:
312313 case ZigTypeIdArgTuple:
313314 case ZigTypeIdPromise:
315 case ZigTypeIdVector:
314316 return true;
315317 }
316318 zig_unreachable();
......@@ -1055,11 +1057,7 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {
10551057 }
10561058 if (g->zig_target.arch.arch == ZigLLVM_x86_64) {
10571059 X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);
1058 if (abi_class == X64CABIClass_MEMORY) {
1059 return true;
1060 }
1061 zig_panic("TODO implement C ABI for x86_64 return types. type '%s'\nSee https://github.com/ziglang/zig/issues/1481",
1062 buf_ptr(&fn_type_id->return_type->name));
1060 return abi_class == X64CABIClass_MEMORY;
10631061 } else if (target_is_arm(&g->zig_target)) {
10641062 return type_size(g, fn_type_id->return_type) > 16;
10651063 }
......@@ -1424,6 +1422,7 @@ static bool type_allowed_in_packed_struct(ZigType *type_entry) {
14241422 case ZigTypeIdPointer:
14251423 case ZigTypeIdArray:
14261424 case ZigTypeIdFn:
1425 case ZigTypeIdVector:
14271426 return true;
14281427 case ZigTypeIdStruct:
14291428 return type_entry->data.structure.layout == ContainerLayoutPacked;
......@@ -1472,6 +1471,8 @@ static bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
14721471 default:
14731472 return false;
14741473 }
1474 case ZigTypeIdVector:
1475 return type_allowed_in_extern(g, type_entry->data.vector.elem_type);
14751476 case ZigTypeIdFloat:
14761477 return true;
14771478 case ZigTypeIdArray:
......@@ -1625,6 +1626,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
16251626 case ZigTypeIdUnion:
16261627 case ZigTypeIdFn:
16271628 case ZigTypeIdPromise:
1629 case ZigTypeIdVector:
16281630 switch (type_requires_comptime(g, type_entry)) {
16291631 case ReqCompTimeNo:
16301632 break;
......@@ -1720,6 +1722,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
17201722 case ZigTypeIdUnion:
17211723 case ZigTypeIdFn:
17221724 case ZigTypeIdPromise:
1725 case ZigTypeIdVector:
17231726 switch (type_requires_comptime(g, fn_type_id.return_type)) {
17241727 case ReqCompTimeInvalid:
17251728 return g->builtin_types.entry_invalid;
......@@ -3577,6 +3580,7 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry
35773580 case ZigTypeIdFn:
35783581 case ZigTypeIdBoundFn:
35793582 case ZigTypeIdPromise:
3583 case ZigTypeIdVector:
35803584 return type_entry;
35813585 }
35823586 zig_unreachable();
......@@ -3943,6 +3947,7 @@ static bool is_container(ZigType *type_entry) {
39433947 case ZigTypeIdArgTuple:
39443948 case ZigTypeIdOpaque:
39453949 case ZigTypeIdPromise:
3950 case ZigTypeIdVector:
39463951 return false;
39473952 }
39483953 zig_unreachable();
......@@ -4002,6 +4007,7 @@ void resolve_container_type(CodeGen *g, ZigType *type_entry) {
40024007 case ZigTypeIdArgTuple:
40034008 case ZigTypeIdOpaque:
40044009 case ZigTypeIdPromise:
4010 case ZigTypeIdVector:
40054011 zig_unreachable();
40064012 }
40074013}
......@@ -4451,6 +4457,34 @@ ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
44514457 return new_entry;
44524458}
44534459
4460ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type) {
4461 TypeId type_id = {};
4462 type_id.id = ZigTypeIdVector;
4463 type_id.data.vector.len = len;
4464 type_id.data.vector.elem_type = elem_type;
4465
4466 {
4467 auto entry = g->type_table.maybe_get(type_id);
4468 if (entry)
4469 return entry->value;
4470 }
4471
4472 ZigType *entry = new_type_table_entry(ZigTypeIdVector);
4473 entry->zero_bits = (len == 0) || !type_has_bits(elem_type);
4474 entry->type_ref = entry->zero_bits ? LLVMVoidType() : LLVMVectorType(elem_type->type_ref, len);
4475 entry->data.vector.len = len;
4476 entry->data.vector.elem_type = elem_type;
4477
4478 buf_resize(&entry->name, 0);
4479 buf_appendf(&entry->name, "@Vector(%u, %s)", len, buf_ptr(&elem_type->name));
4480
4481 entry->di_type = ZigLLVMDIBuilderCreateVectorType(g->dbuilder, len,
4482 LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref), elem_type->di_type);
4483
4484 g->type_table.put(type_id, entry);
4485 return entry;
4486}
4487
44544488ZigType **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type) {
44554489 return &g->builtin_types.entry_c_int[c_int_type];
44564490}
......@@ -4482,6 +4516,7 @@ bool handle_is_ptr(ZigType *type_entry) {
44824516 case ZigTypeIdFn:
44834517 case ZigTypeIdEnum:
44844518 case ZigTypeIdPromise:
4519 case ZigTypeIdVector:
44854520 return false;
44864521 case ZigTypeIdArray:
44874522 case ZigTypeIdStruct:
......@@ -4914,6 +4949,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
49144949 return hash_const_val_error_set(const_val);
49154950 case ZigTypeIdNamespace:
49164951 return hash_ptr(const_val->data.x_import);
4952 case ZigTypeIdVector:
4953 // TODO better hashing algorithm
4954 return 3647867726;
49174955 case ZigTypeIdBoundFn:
49184956 case ZigTypeIdInvalid:
49194957 case ZigTypeIdUnreachable:
......@@ -4966,6 +5004,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
49665004 case ZigTypeIdBool:
49675005 case ZigTypeIdUnreachable:
49685006 case ZigTypeIdInt:
5007 case ZigTypeIdVector:
49695008 case ZigTypeIdFloat:
49705009 case ZigTypeIdComptimeFloat:
49715010 case ZigTypeIdComptimeInt:
......@@ -5049,6 +5088,7 @@ static bool return_type_is_cacheable(ZigType *return_type) {
50495088 case ZigTypeIdErrorSet:
50505089 case ZigTypeIdEnum:
50515090 case ZigTypeIdPointer:
5091 case ZigTypeIdVector:
50525092 return true;
50535093
50545094 case ZigTypeIdArray:
......@@ -5201,6 +5241,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
52015241 case ZigTypeIdErrorSet:
52025242 case ZigTypeIdEnum:
52035243 case ZigTypeIdInt:
5244 case ZigTypeIdVector:
52045245 return type_has_bits(type_entry) ? OnePossibleValueNo : OnePossibleValueYes;
52055246 case ZigTypeIdPointer:
52065247 return type_has_one_possible_value(g, type_entry->data.pointer.child_type);
......@@ -5251,6 +5292,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
52515292 case ZigTypeIdErrorSet:
52525293 case ZigTypeIdBool:
52535294 case ZigTypeIdInt:
5295 case ZigTypeIdVector:
52545296 case ZigTypeIdFloat:
52555297 case ZigTypeIdVoid:
52565298 case ZigTypeIdUnreachable:
......@@ -5777,7 +5819,7 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
57775819 ConstExprValue *a_elems = a->data.x_array.data.s_none.elements;
57785820 ConstExprValue *b_elems = b->data.x_array.data.s_none.elements;
57795821
5780 for (size_t i = 0; i < len; ++i) {
5822 for (size_t i = 0; i < len; i += 1) {
57815823 if (!const_values_equal(g, &a_elems[i], &b_elems[i]))
57825824 return false;
57835825 }
......@@ -5811,6 +5853,20 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
58115853 case ZigTypeIdArgTuple:
58125854 return a->data.x_arg_tuple.start_index == b->data.x_arg_tuple.start_index &&
58135855 a->data.x_arg_tuple.end_index == b->data.x_arg_tuple.end_index;
5856 case ZigTypeIdVector: {
5857 assert(a->type->data.vector.len == b->type->data.vector.len);
5858
5859 size_t len = a->type->data.vector.len;
5860 ConstExprValue *a_elems = a->data.x_vector.elements;
5861 ConstExprValue *b_elems = b->data.x_vector.elements;
5862
5863 for (size_t i = 0; i < len; i += 1) {
5864 if (!const_values_equal(g, &a_elems[i], &b_elems[i]))
5865 return false;
5866 }
5867
5868 return true;
5869 }
58145870 case ZigTypeIdBoundFn:
58155871 case ZigTypeIdInvalid:
58165872 case ZigTypeIdUnreachable:
......@@ -6042,6 +6098,18 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
60426098 }
60436099 }
60446100 zig_unreachable();
6101 case ZigTypeIdVector: {
6102 buf_appendf(buf, "%s{", buf_ptr(&type_entry->name));
6103 uint64_t len = type_entry->data.vector.len;
6104 for (uint32_t i = 0; i < len; i += 1) {
6105 if (i != 0)
6106 buf_appendf(buf, ",");
6107 ConstExprValue *child_value = &const_val->data.x_vector.elements[i];
6108 render_const_value(g, buf, child_value);
6109 }
6110 buf_appendf(buf, "}");
6111 return;
6112 }
60456113 case ZigTypeIdNull:
60466114 {
60476115 buf_appendf(buf, "null");
......@@ -6200,6 +6268,8 @@ uint32_t type_id_hash(TypeId x) {
62006268 case ZigTypeIdInt:
62016269 return (x.data.integer.is_signed ? (uint32_t)2652528194 : (uint32_t)163929201) +
62026270 (((uint32_t)x.data.integer.bit_count) ^ (uint32_t)2998081557);
6271 case ZigTypeIdVector:
6272 return hash_ptr(x.data.vector.elem_type) * (x.data.vector.len * 526582681);
62036273 }
62046274 zig_unreachable();
62056275}
......@@ -6248,6 +6318,9 @@ bool type_id_eql(TypeId a, TypeId b) {
62486318 case ZigTypeIdInt:
62496319 return a.data.integer.is_signed == b.data.integer.is_signed &&
62506320 a.data.integer.bit_count == b.data.integer.bit_count;
6321 case ZigTypeIdVector:
6322 return a.data.vector.elem_type == b.data.vector.elem_type &&
6323 a.data.vector.len == b.data.vector.len;
62516324 }
62526325 zig_unreachable();
62536326}
......@@ -6382,6 +6455,7 @@ static const ZigTypeId all_type_ids[] = {
63826455 ZigTypeIdArgTuple,
63836456 ZigTypeIdOpaque,
63846457 ZigTypeIdPromise,
6458 ZigTypeIdVector,
63856459};
63866460
63876461ZigTypeId type_id_at_index(size_t index) {
......@@ -6447,6 +6521,8 @@ size_t type_id_index(ZigType *entry) {
64476521 return 22;
64486522 case ZigTypeIdPromise:
64496523 return 23;
6524 case ZigTypeIdVector:
6525 return 24;
64506526 }
64516527 zig_unreachable();
64526528}
......@@ -6503,6 +6579,8 @@ const char *type_id_name(ZigTypeId id) {
65036579 return "Opaque";
65046580 case ZigTypeIdPromise:
65056581 return "Promise";
6582 case ZigTypeIdVector:
6583 return "Vector";
65066584 }
65076585 zig_unreachable();
65086586}
......@@ -6658,6 +6736,7 @@ X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) {
66586736 case ZigTypeIdBool:
66596737 return X64CABIClass_INTEGER;
66606738 case ZigTypeIdFloat:
6739 case ZigTypeIdVector:
66616740 return X64CABIClass_SSE;
66626741 case ZigTypeIdStruct: {
66636742 // "If the size of an object is larger than four eightbytes, or it contains unaligned
src/analyze.hpp+1
......@@ -20,6 +20,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
2020uint64_t type_size(CodeGen *g, ZigType *type_entry);
2121uint64_t type_size_bits(CodeGen *g, ZigType *type_entry);
2222ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
23ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type);
2324ZigType **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type);
2425ZigType *get_c_int_type(CodeGen *g, CIntType c_int_type);
2526ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id);
src/codegen.cpp+46-1
......@@ -1980,7 +1980,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
19801980 break;
19811981 }
19821982
1983 if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat ||
1983 if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat || ty->id == ZigTypeIdVector ||
19841984 ty->id == ZigTypeIdInt // TODO investigate if we need to change this
19851985 ) {
19861986 switch (fn_walk->id) {
......@@ -2660,6 +2660,27 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
26602660 } else {
26612661 return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, "");
26622662 }
2663 } else if (type_entry->id == ZigTypeIdVector) {
2664 ZigType *elem_type = type_entry->data.vector.elem_type;
2665 if (elem_type->id == ZigTypeIdFloat) {
2666 ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base));
2667 return LLVMBuildFAdd(g->builder, op1_value, op2_value, "");
2668 } else if (elem_type->id == ZigTypeIdPointer) {
2669 zig_panic("TODO codegen for pointers in vectors");
2670 } else if (elem_type->id == ZigTypeIdInt) {
2671 bool is_wrapping = (op_id == IrBinOpAddWrap);
2672 if (is_wrapping) {
2673 return LLVMBuildAdd(g->builder, op1_value, op2_value, "");
2674 } else if (want_runtime_safety) {
2675 zig_panic("TODO runtime safety for vector integer addition");
2676 } else if (elem_type->data.integral.is_signed) {
2677 return LLVMBuildNSWAdd(g->builder, op1_value, op2_value, "");
2678 } else {
2679 return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, "");
2680 }
2681 } else {
2682 zig_unreachable();
2683 }
26632684 } else {
26642685 zig_unreachable();
26652686 }
......@@ -5211,6 +5232,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
52115232 case IrInstructionIdCUndef:
52125233 case IrInstructionIdEmbedFile:
52135234 case IrInstructionIdIntType:
5235 case IrInstructionIdVectorType:
52145236 case IrInstructionIdMemberCount:
52155237 case IrInstructionIdMemberType:
52165238 case IrInstructionIdMemberName:
......@@ -5620,6 +5642,8 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
56205642 }
56215643 case ZigTypeIdArray:
56225644 zig_panic("TODO bit pack an array");
5645 case ZigTypeIdVector:
5646 zig_panic("TODO bit pack a vector");
56235647 case ZigTypeIdUnion:
56245648 zig_panic("TODO bit pack a union");
56255649 case ZigTypeIdStruct:
......@@ -5992,6 +6016,14 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
59926016 }
59936017 }
59946018 }
6019 case ZigTypeIdVector: {
6020 uint32_t len = type_entry->data.vector.len;
6021 LLVMValueRef *values = allocate<LLVMValueRef>(len);
6022 for (uint32_t i = 0; i < len; i += 1) {
6023 values[i] = gen_const_val(g, &const_val->data.x_vector.elements[i], "");
6024 }
6025 return LLVMConstVector(values, len);
6026 }
59956027 case ZigTypeIdUnion:
59966028 {
59976029 LLVMTypeRef union_type_ref = type_entry->data.unionation.union_type_ref;
......@@ -6927,6 +6959,7 @@ static void define_builtin_fns(CodeGen *g) {
69276959 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);
69286960 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
69296961 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
6962 create_builtin_fn(g, BuiltinFnIdVectorType, "Vector", 2);
69306963 create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1);
69316964 create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1);
69326965 create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 1);
......@@ -7152,6 +7185,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
71527185 " ArgTuple: void,\n"
71537186 " Opaque: void,\n"
71547187 " Promise: Promise,\n"
7188 " Vector: Vector,\n"
71557189 "\n\n"
71567190 " pub const Int = struct {\n"
71577191 " is_signed: bool,\n"
......@@ -7270,6 +7304,11 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
72707304 " child: ?type,\n"
72717305 " };\n"
72727306 "\n"
7307 " pub const Vector = struct {\n"
7308 " len: u32,\n"
7309 " child: type,\n"
7310 " };\n"
7311 "\n"
72737312 " pub const Definition = struct {\n"
72747313 " name: []const u8,\n"
72757314 " is_pub: bool,\n"
......@@ -7841,6 +7880,9 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
78417880 case ZigTypeIdArray:
78427881 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.array.child_type);
78437882 return;
7883 case ZigTypeIdVector:
7884 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.vector.elem_type);
7885 return;
78447886 case ZigTypeIdOptional:
78457887 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.maybe.child_type);
78467888 return;
......@@ -7972,6 +8014,8 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu
79728014 buf_appendf(out_buf, "%s", buf_ptr(child_buf));
79738015 return;
79748016 }
8017 case ZigTypeIdVector:
8018 zig_panic("TODO implement get_c_type for vector types");
79758019 case ZigTypeIdErrorUnion:
79768020 case ZigTypeIdErrorSet:
79778021 case ZigTypeIdFn:
......@@ -8137,6 +8181,7 @@ static void gen_h_file(CodeGen *g) {
81378181 case ZigTypeIdOptional:
81388182 case ZigTypeIdFn:
81398183 case ZigTypeIdPromise:
8184 case ZigTypeIdVector:
81408185 zig_unreachable();
81418186 case ZigTypeIdEnum:
81428187 if (type_entry->data.enumeration.layout == ContainerLayoutExtern) {
src/ir.cpp+168-45
......@@ -587,6 +587,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) {
587587 return IrInstructionIdIntType;
588588}
589589
590static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorType *) {
591 return IrInstructionIdVectorType;
592}
593
590594static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) {
591595 return IrInstructionIdBoolNot;
592596}
......@@ -1953,6 +1957,19 @@ static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *s
19531957 return &instruction->base;
19541958}
19551959
1960static IrInstruction *ir_build_vector_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *len,
1961 IrInstruction *elem_type)
1962{
1963 IrInstructionVectorType *instruction = ir_build_instruction<IrInstructionVectorType>(irb, scope, source_node);
1964 instruction->len = len;
1965 instruction->elem_type = elem_type;
1966
1967 ir_ref_instruction(len, irb->current_basic_block);
1968 ir_ref_instruction(elem_type, irb->current_basic_block);
1969
1970 return &instruction->base;
1971}
1972
19561973static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
19571974 IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node);
19581975 instruction->value = value;
......@@ -4230,6 +4247,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42304247 IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value);
42314248 return ir_lval_wrap(irb, scope, int_type, lval);
42324249 }
4250 case BuiltinFnIdVectorType:
4251 {
4252 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4253 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4254 if (arg0_value == irb->codegen->invalid_instruction)
4255 return arg0_value;
4256
4257 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4258 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4259 if (arg1_value == irb->codegen->invalid_instruction)
4260 return arg1_value;
4261
4262 IrInstruction *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value);
4263 return ir_lval_wrap(irb, scope, vector_type, lval);
4264 }
42334265 case BuiltinFnIdMemcpy:
42344266 {
42354267 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -11617,6 +11649,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
1161711649 case ZigTypeIdComptimeInt:
1161811650 case ZigTypeIdInt:
1161911651 case ZigTypeIdFloat:
11652 case ZigTypeIdVector:
1162011653 operator_allowed = true;
1162111654 break;
1162211655
......@@ -12032,6 +12065,48 @@ static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *b
1203212065 return result;
1203312066}
1203412067
12068static bool ok_float_op(IrBinOp op) {
12069 switch (op) {
12070 case IrBinOpInvalid:
12071 zig_unreachable();
12072 case IrBinOpAdd:
12073 case IrBinOpSub:
12074 case IrBinOpMult:
12075 case IrBinOpDivUnspecified:
12076 case IrBinOpDivTrunc:
12077 case IrBinOpDivFloor:
12078 case IrBinOpDivExact:
12079 case IrBinOpRemRem:
12080 case IrBinOpRemMod:
12081 return true;
12082
12083 case IrBinOpBoolOr:
12084 case IrBinOpBoolAnd:
12085 case IrBinOpCmpEq:
12086 case IrBinOpCmpNotEq:
12087 case IrBinOpCmpLessThan:
12088 case IrBinOpCmpGreaterThan:
12089 case IrBinOpCmpLessOrEq:
12090 case IrBinOpCmpGreaterOrEq:
12091 case IrBinOpBinOr:
12092 case IrBinOpBinXor:
12093 case IrBinOpBinAnd:
12094 case IrBinOpBitShiftLeftLossy:
12095 case IrBinOpBitShiftLeftExact:
12096 case IrBinOpBitShiftRightLossy:
12097 case IrBinOpBitShiftRightExact:
12098 case IrBinOpAddWrap:
12099 case IrBinOpSubWrap:
12100 case IrBinOpMultWrap:
12101 case IrBinOpRemUnspecified:
12102 case IrBinOpArrayCat:
12103 case IrBinOpArrayMult:
12104 case IrBinOpMergeErrorSets:
12105 return false;
12106 }
12107 zig_unreachable();
12108}
12109
1203512110static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) {
1203612111 IrInstruction *op1 = instruction->op1->child;
1203712112 if (type_is_invalid(op1->value.type))
......@@ -12169,21 +12244,20 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
1216912244 op_id = IrBinOpRemRem;
1217012245 }
1217112246
12247 bool ok = false;
1217212248 if (is_int) {
12173 // int
12174 } else if (is_float &&
12175 (op_id == IrBinOpAdd ||
12176 op_id == IrBinOpSub ||
12177 op_id == IrBinOpMult ||
12178 op_id == IrBinOpDivUnspecified ||
12179 op_id == IrBinOpDivTrunc ||
12180 op_id == IrBinOpDivFloor ||
12181 op_id == IrBinOpDivExact ||
12182 op_id == IrBinOpRemRem ||
12183 op_id == IrBinOpRemMod))
12184 {
12185 // float
12186 } else {
12249 ok = true;
12250 } else if (is_float && ok_float_op(op_id)) {
12251 ok = true;
12252 } else if (resolved_type->id == ZigTypeIdVector) {
12253 ZigType *elem_type = resolved_type->data.vector.elem_type;
12254 if (elem_type->id == ZigTypeIdInt || elem_type->id == ZigTypeIdComptimeInt) {
12255 ok = true;
12256 } else if ((elem_type->id == ZigTypeIdFloat || elem_type->id == ZigTypeIdComptimeFloat) && ok_float_op(op_id)) {
12257 ok = true;
12258 }
12259 }
12260 if (!ok) {
1218712261 AstNode *source_node = instruction->base.source_node;
1218812262 ir_add_error_node(ira, source_node,
1218912263 buf_sprintf("invalid operands to binary expression: '%s' and '%s'",
......@@ -12817,6 +12891,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
1281712891 case ZigTypeIdPointer:
1281812892 case ZigTypeIdArray:
1281912893 case ZigTypeIdBool:
12894 case ZigTypeIdVector:
1282012895 break;
1282112896 case ZigTypeIdMetaType:
1282212897 case ZigTypeIdVoid:
......@@ -12851,6 +12926,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
1285112926 case ZigTypeIdOptional:
1285212927 case ZigTypeIdErrorUnion:
1285312928 case ZigTypeIdErrorSet:
12929 case ZigTypeIdVector:
1285412930 zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name));
1285512931 case ZigTypeIdNamespace:
1285612932 case ZigTypeIdBoundFn:
......@@ -14009,6 +14085,7 @@ static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_
1400914085 case ZigTypeIdVoid:
1401014086 case ZigTypeIdBool:
1401114087 case ZigTypeIdInt:
14088 case ZigTypeIdVector:
1401214089 case ZigTypeIdFloat:
1401314090 case ZigTypeIdPointer:
1401414091 case ZigTypeIdArray:
......@@ -15383,37 +15460,7 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio
1538315460 ZigType *type_entry = expr_value->value.type;
1538415461 if (type_is_invalid(type_entry))
1538515462 return ira->codegen->invalid_instruction;
15386 switch (type_entry->id) {
15387 case ZigTypeIdInvalid:
15388 zig_unreachable(); // handled above
15389 case ZigTypeIdComptimeFloat:
15390 case ZigTypeIdComptimeInt:
15391 case ZigTypeIdUndefined:
15392 case ZigTypeIdNull:
15393 case ZigTypeIdNamespace:
15394 case ZigTypeIdBoundFn:
15395 case ZigTypeIdMetaType:
15396 case ZigTypeIdVoid:
15397 case ZigTypeIdBool:
15398 case ZigTypeIdUnreachable:
15399 case ZigTypeIdInt:
15400 case ZigTypeIdFloat:
15401 case ZigTypeIdPointer:
15402 case ZigTypeIdArray:
15403 case ZigTypeIdStruct:
15404 case ZigTypeIdOptional:
15405 case ZigTypeIdErrorUnion:
15406 case ZigTypeIdErrorSet:
15407 case ZigTypeIdEnum:
15408 case ZigTypeIdUnion:
15409 case ZigTypeIdFn:
15410 case ZigTypeIdArgTuple:
15411 case ZigTypeIdOpaque:
15412 case ZigTypeIdPromise:
15413 return ir_const_type(ira, &typeof_instruction->base, type_entry);
15414 }
15415
15416 zig_unreachable();
15463 return ir_const_type(ira, &typeof_instruction->base, type_entry);
1541715464}
1541815465
1541915466static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira,
......@@ -15652,6 +15699,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
1565215699 case ZigTypeIdNamespace:
1565315700 case ZigTypeIdBoundFn:
1565415701 case ZigTypeIdPromise:
15702 case ZigTypeIdVector:
1565515703 {
1565615704 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown)))
1565715705 return ira->codegen->invalid_instruction;
......@@ -15772,6 +15820,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,
1577215820 case ZigTypeIdNamespace:
1577315821 case ZigTypeIdBoundFn:
1577415822 case ZigTypeIdPromise:
15823 case ZigTypeIdVector:
1577515824 {
1577615825 if ((err = ensure_complete_type(ira->codegen, child_type)))
1577715826 return ira->codegen->invalid_instruction;
......@@ -15838,6 +15887,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
1583815887 case ZigTypeIdUnion:
1583915888 case ZigTypeIdFn:
1584015889 case ZigTypeIdPromise:
15890 case ZigTypeIdVector:
1584115891 {
1584215892 uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
1584315893 return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes);
......@@ -16307,6 +16357,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
1630716357 case ZigTypeIdBoundFn:
1630816358 case ZigTypeIdArgTuple:
1630916359 case ZigTypeIdOpaque:
16360 case ZigTypeIdVector:
1631016361 ir_add_error(ira, &switch_target_instruction->base,
1631116362 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));
1631216363 return ira->codegen->invalid_instruction;
......@@ -17496,6 +17547,27 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
1749617547
1749717548 break;
1749817549 }
17550 case ZigTypeIdVector: {
17551 result = create_const_vals(1);
17552 result->special = ConstValSpecialStatic;
17553 result->type = ir_type_info_get_type(ira, "Vector", nullptr);
17554
17555 ConstExprValue *fields = create_const_vals(2);
17556 result->data.x_struct.fields = fields;
17557
17558 // len: usize
17559 ensure_field_index(result->type, "len", 0);
17560 fields[0].special = ConstValSpecialStatic;
17561 fields[0].type = ira->codegen->builtin_types.entry_u32;
17562 bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.vector.len);
17563 // child: type
17564 ensure_field_index(result->type, "child", 1);
17565 fields[1].special = ConstValSpecialStatic;
17566 fields[1].type = ira->codegen->builtin_types.entry_type;
17567 fields[1].data.x_type = type_entry->data.vector.elem_type;
17568
17569 break;
17570 }
1749917571 case ZigTypeIdOptional:
1750017572 {
1750117573 result = create_const_vals(1);
......@@ -18671,6 +18743,30 @@ static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstruct
1867118743 return ir_const_type(ira, &instruction->base, get_int_type(ira->codegen, is_signed, (uint32_t)bit_count));
1867218744}
1867318745
18746static IrInstruction *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstructionVectorType *instruction) {
18747 uint64_t len;
18748 if (!ir_resolve_unsigned(ira, instruction->len->child, ira->codegen->builtin_types.entry_u32, &len))
18749 return ira->codegen->invalid_instruction;
18750
18751 ZigType *elem_type = ir_resolve_type(ira, instruction->elem_type->child);
18752 if (type_is_invalid(elem_type))
18753 return ira->codegen->invalid_instruction;
18754
18755 if (elem_type->id != ZigTypeIdInt &&
18756 elem_type->id != ZigTypeIdFloat &&
18757 get_codegen_ptr_type(elem_type) == nullptr)
18758 {
18759 ir_add_error(ira, instruction->elem_type,
18760 buf_sprintf("vector element type must be integer, float, or pointer; '%s' is invalid",
18761 buf_ptr(&elem_type->name)));
18762 return ira->codegen->invalid_instruction;
18763 }
18764
18765 ZigType *vector_type = get_vector_type(ira->codegen, len, elem_type);
18766
18767 return ir_const_type(ira, &instruction->base, vector_type);
18768}
18769
1867418770static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) {
1867518771 IrInstruction *value = instruction->value->child;
1867618772 if (type_is_invalid(value->value.type))
......@@ -19474,6 +19570,7 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct
1947419570 case ZigTypeIdEnum:
1947519571 case ZigTypeIdUnion:
1947619572 case ZigTypeIdFn:
19573 case ZigTypeIdVector:
1947719574 {
1947819575 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry);
1947919576 return ir_const_unsigned(ira, &instruction->base, align_in_bytes);
......@@ -20311,6 +20408,15 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
2031120408 }
2031220409 }
2031320410 return;
20411 case ZigTypeIdVector: {
20412 size_t buf_i = 0;
20413 for (uint32_t elem_i = 0; elem_i < val->type->data.vector.len; elem_i += 1) {
20414 ConstExprValue *elem = &val->data.x_vector.elements[elem_i];
20415 buf_write_value_bytes(codegen, &buf[buf_i], elem);
20416 buf_i += type_size(codegen, elem->type);
20417 }
20418 return;
20419 }
2031420420 case ZigTypeIdStruct:
2031520421 zig_panic("TODO buf_write_value_bytes struct type");
2031620422 case ZigTypeIdOptional:
......@@ -20387,6 +20493,20 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
2038720493 }
2038820494 zig_unreachable();
2038920495 }
20496 case ZigTypeIdVector: {
20497 uint64_t elem_size = type_size(codegen, val->type->data.vector.elem_type);
20498 uint32_t len = val->type->data.vector.len;
20499
20500 val->data.x_vector.elements = create_const_vals(len);
20501 for (uint32_t i = 0; i < len; i += 1) {
20502 ConstExprValue *elem = &val->data.x_vector.elements[i];
20503 elem->special = ConstValSpecialStatic;
20504 elem->type = val->type->data.vector.elem_type;
20505 if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem)))
20506 return err;
20507 }
20508 return ErrorNone;
20509 }
2039020510 case ZigTypeIdEnum:
2039120511 switch (val->type->data.enumeration.layout) {
2039220512 case ContainerLayoutAuto:
......@@ -21633,6 +21753,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2163321753 return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction);
2163421754 case IrInstructionIdIntType:
2163521755 return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction);
21756 case IrInstructionIdVectorType:
21757 return ir_analyze_instruction_vector_type(ira, (IrInstructionVectorType *)instruction);
2163621758 case IrInstructionIdBoolNot:
2163721759 return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction);
2163821760 case IrInstructionIdMemset:
......@@ -21943,6 +22065,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2194322065 case IrInstructionIdEmbedFile:
2194422066 case IrInstructionIdTruncate:
2194522067 case IrInstructionIdIntType:
22068 case IrInstructionIdVectorType:
2194622069 case IrInstructionIdBoolNot:
2194722070 case IrInstructionIdSlice:
2194822071 case IrInstructionIdMemberCount:
src/ir_print.cpp+11
......@@ -719,6 +719,14 @@ static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) {
719719 fprintf(irp->f, ")");
720720}
721721
722static void ir_print_vector_type(IrPrint *irp, IrInstructionVectorType *instruction) {
723 fprintf(irp->f, "@Vector(");
724 ir_print_other_instruction(irp, instruction->len);
725 fprintf(irp->f, ", ");
726 ir_print_other_instruction(irp, instruction->elem_type);
727 fprintf(irp->f, ")");
728}
729
722730static void ir_print_bool_not(IrPrint *irp, IrInstructionBoolNot *instruction) {
723731 fprintf(irp->f, "! ");
724732 ir_print_other_instruction(irp, instruction->value);
......@@ -1577,6 +1585,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
15771585 case IrInstructionIdIntType:
15781586 ir_print_int_type(irp, (IrInstructionIntType *)instruction);
15791587 break;
1588 case IrInstructionIdVectorType:
1589 ir_print_vector_type(irp, (IrInstructionVectorType *)instruction);
1590 break;
15801591 case IrInstructionIdBoolNot:
15811592 ir_print_bool_not(irp, (IrInstructionBoolNot *)instruction);
15821593 break;
src/zig_llvm.cpp+13
......@@ -263,6 +263,19 @@ ZigLLVMDIType *ZigLLVMCreateDebugBasicType(ZigLLVMDIBuilder *dibuilder, const ch
263263 return reinterpret_cast<ZigLLVMDIType*>(di_type);
264264}
265265
266struct ZigLLVMDIType *ZigLLVMDIBuilderCreateVectorType(struct ZigLLVMDIBuilder *dibuilder,
267 uint64_t Size, uint32_t AlignInBits, struct ZigLLVMDIType *Ty)
268{
269 SmallVector<Metadata *, 1> subrange;
270 subrange.push_back(reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateSubrange(0, Size));
271 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createVectorType(
272 Size,
273 AlignInBits,
274 reinterpret_cast<DIType*>(Ty),
275 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(subrange));
276 return reinterpret_cast<ZigLLVMDIType*>(di_type);
277}
278
266279ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t size_in_bits,
267280 uint64_t align_in_bits, ZigLLVMDIType *elem_type, int elem_count)
268281{
src/zig_llvm.h+3
......@@ -191,6 +191,9 @@ ZIG_EXTERN_C struct ZigLLVMDISubprogram *ZigLLVMCreateFunction(struct ZigLLVMDIB
191191 unsigned lineno, struct ZigLLVMDIType *fn_di_type, bool is_local_to_unit, bool is_definition,
192192 unsigned scope_line, unsigned flags, bool is_optimized, struct ZigLLVMDISubprogram *decl_subprogram);
193193
194ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMDIBuilderCreateVectorType(struct ZigLLVMDIBuilder *dibuilder,
195 uint64_t Size, uint32_t AlignInBits, struct ZigLLVMDIType *Ty);
196
194197ZIG_EXTERN_C void ZigLLVMFnSetSubprogram(LLVMValueRef fn, struct ZigLLVMDISubprogram *subprogram);
195198
196199ZIG_EXTERN_C void ZigLLVMDIBuilderFinalize(struct ZigLLVMDIBuilder *dibuilder);
std/hash_map.zig+2
......@@ -508,6 +508,7 @@ pub fn autoHash(key: var, comptime rng: *std.rand.Random, comptime HashInt: type
508508
509509 builtin.TypeId.Optional => @compileError("TODO auto hash for optionals"),
510510 builtin.TypeId.Array => @compileError("TODO auto hash for arrays"),
511 builtin.TypeId.Vector => @compileError("TODO auto hash for vectors"),
511512 builtin.TypeId.Struct => @compileError("TODO auto hash for structs"),
512513 builtin.TypeId.Union => @compileError("TODO auto hash for unions"),
513514 builtin.TypeId.ErrorUnion => @compileError("TODO auto hash for unions"),
......@@ -555,5 +556,6 @@ pub fn autoEql(a: var, b: @typeOf(a)) bool {
555556 builtin.TypeId.Struct => @compileError("TODO auto eql for structs"),
556557 builtin.TypeId.Union => @compileError("TODO auto eql for unions"),
557558 builtin.TypeId.ErrorUnion => @compileError("TODO auto eql for unions"),
559 builtin.TypeId.Vector => @compileError("TODO auto eql for vectors"),
558560 }
559561}
test/stage1/behavior/type_info.zig+14-2
......@@ -171,11 +171,11 @@ fn testUnion() void {
171171 assertOrPanic(TypeId(typeinfo_info) == TypeId.Union);
172172 assertOrPanic(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
173173 assertOrPanic(typeinfo_info.Union.tag_type.? == TypeId);
174 assertOrPanic(typeinfo_info.Union.fields.len == 24);
174 assertOrPanic(typeinfo_info.Union.fields.len == 25);
175175 assertOrPanic(typeinfo_info.Union.fields[4].enum_field != null);
176176 assertOrPanic(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
177177 assertOrPanic(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
178 assertOrPanic(typeinfo_info.Union.defs.len == 20);
178 assertOrPanic(typeinfo_info.Union.defs.len == 21);
179179
180180 const TestNoTagUnion = union {
181181 Foo: void,
......@@ -262,3 +262,15 @@ test "typeInfo with comptime parameter in struct fn def" {
262262 };
263263 comptime var info = @typeInfo(S);
264264}
265
266test "type info: vectors" {
267 testVector();
268 comptime testVector();
269}
270
271fn testVector() void {
272 const vec_info = @typeInfo(@Vector(4, i32));
273 assertOrPanic(TypeId(vec_info) == TypeId.Vector);
274 assertOrPanic(vec_info.Vector.len == 4);
275 assertOrPanic(vec_info.Vector.child == i32);
276}