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" {...@@ -1531,6 +1531,29 @@ test "array initialization with function calls" {
1531 {#code_end#}1531 {#code_end#}
1532 {#see_also|for|Slices#}1532 {#see_also|for|Slices#}
1533 {#header_close#}1533 {#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
1534 {#header_open|Pointers#}1557 {#header_open|Pointers#}
1535 <p>1558 <p>
1536 Zig has two kinds of pointers:1559 Zig has two kinds of pointers:
...@@ -6607,6 +6630,17 @@ pub const TypeInfo = union(TypeId) {...@@ -6607,6 +6630,17 @@ pub const TypeInfo = union(TypeId) {
6607 expression passed as an argument. The expression is evaluated.6630 expression passed as an argument. The expression is evaluated.
6608 </p>6631 </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>
6610 {#header_close#}6644 {#header_close#}
6611 {#header_close#}6645 {#header_close#}
66126646
src-self-hosted/type.zig+16
...@@ -44,6 +44,7 @@ pub const Type = struct {...@@ -44,6 +44,7 @@ pub const Type = struct {
44 Id.ArgTuple => @fieldParentPtr(ArgTuple, "base", base).destroy(comp),44 Id.ArgTuple => @fieldParentPtr(ArgTuple, "base", base).destroy(comp),
45 Id.Opaque => @fieldParentPtr(Opaque, "base", base).destroy(comp),45 Id.Opaque => @fieldParentPtr(Opaque, "base", base).destroy(comp),
46 Id.Promise => @fieldParentPtr(Promise, "base", base).destroy(comp),46 Id.Promise => @fieldParentPtr(Promise, "base", base).destroy(comp),
47 Id.Vector => @fieldParentPtr(Vector, "base", base).destroy(comp),
47 }48 }
48 }49 }
4950
...@@ -77,6 +78,7 @@ pub const Type = struct {...@@ -77,6 +78,7 @@ pub const Type = struct {
77 Id.ArgTuple => unreachable,78 Id.ArgTuple => unreachable,
78 Id.Opaque => return @fieldParentPtr(Opaque, "base", base).getLlvmType(allocator, llvm_context),79 Id.Opaque => return @fieldParentPtr(Opaque, "base", base).getLlvmType(allocator, llvm_context),
79 Id.Promise => return @fieldParentPtr(Promise, "base", base).getLlvmType(allocator, llvm_context),80 Id.Promise => return @fieldParentPtr(Promise, "base", base).getLlvmType(allocator, llvm_context),
81 Id.Vector => return @fieldParentPtr(Vector, "base", base).getLlvmType(allocator, llvm_context),
80 }82 }
81 }83 }
8284
...@@ -103,6 +105,7 @@ pub const Type = struct {...@@ -103,6 +105,7 @@ pub const Type = struct {
103 Id.Enum,105 Id.Enum,
104 Id.Fn,106 Id.Fn,
105 Id.Promise,107 Id.Promise,
108 Id.Vector,
106 => return false,109 => return false,
107110
108 Id.Struct => @panic("TODO"),111 Id.Struct => @panic("TODO"),
...@@ -135,6 +138,7 @@ pub const Type = struct {...@@ -135,6 +138,7 @@ pub const Type = struct {
135 Id.Float,138 Id.Float,
136 Id.Fn,139 Id.Fn,
137 Id.Promise,140 Id.Promise,
141 Id.Vector,
138 => return true,142 => return true,
139143
140 Id.Pointer => {144 Id.Pointer => {
...@@ -902,6 +906,18 @@ pub const Type = struct {...@@ -902,6 +906,18 @@ pub const Type = struct {
902 }906 }
903 };907 };
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
905 pub const ComptimeFloat = struct {921 pub const ComptimeFloat = struct {
906 base: Type,922 base: Type,
907923
src/all_types.hpp+26
...@@ -252,6 +252,10 @@ struct ConstArgTuple {...@@ -252,6 +252,10 @@ struct ConstArgTuple {
252 size_t end_index;252 size_t end_index;
253};253};
254254
255struct ConstVector {
256 ConstExprValue *elements;
257};
258
255enum ConstValSpecial {259enum ConstValSpecial {
256 ConstValSpecialRuntime,260 ConstValSpecialRuntime,
257 ConstValSpecialStatic,261 ConstValSpecialStatic,
...@@ -318,6 +322,7 @@ struct ConstExprValue {...@@ -318,6 +322,7 @@ struct ConstExprValue {
318 ConstPtrValue x_ptr;322 ConstPtrValue x_ptr;
319 ImportTableEntry *x_import;323 ImportTableEntry *x_import;
320 ConstArgTuple x_arg_tuple;324 ConstArgTuple x_arg_tuple;
325 ConstVector x_vector;
321326
322 // populated if special == ConstValSpecialRuntime327 // populated if special == ConstValSpecialRuntime
323 RuntimeHintErrorUnion rh_error_union;328 RuntimeHintErrorUnion rh_error_union;
...@@ -1210,6 +1215,12 @@ struct ZigTypePromise {...@@ -1210,6 +1215,12 @@ struct ZigTypePromise {
1210 ZigType *result_type;1215 ZigType *result_type;
1211};1216};
12121217
1218struct ZigTypeVector {
1219 // The type must be a pointer, integer, or float
1220 ZigType *elem_type;
1221 uint32_t len;
1222};
1223
1213enum ZigTypeId {1224enum ZigTypeId {
1214 ZigTypeIdInvalid,1225 ZigTypeIdInvalid,
1215 ZigTypeIdMetaType,1226 ZigTypeIdMetaType,
...@@ -1236,6 +1247,7 @@ enum ZigTypeId {...@@ -1236,6 +1247,7 @@ enum ZigTypeId {
1236 ZigTypeIdArgTuple,1247 ZigTypeIdArgTuple,
1237 ZigTypeIdOpaque,1248 ZigTypeIdOpaque,
1238 ZigTypeIdPromise,1249 ZigTypeIdPromise,
1250 ZigTypeIdVector,
1239};1251};
12401252
1241struct ZigType {1253struct ZigType {
...@@ -1262,6 +1274,7 @@ struct ZigType {...@@ -1262,6 +1274,7 @@ struct ZigType {
1262 ZigTypeFn fn;1274 ZigTypeFn fn;
1263 ZigTypeBoundFn bound_fn;1275 ZigTypeBoundFn bound_fn;
1264 ZigTypePromise promise;1276 ZigTypePromise promise;
1277 ZigTypeVector vector;
1265 } data;1278 } data;
12661279
1267 // use these fields to make sure we don't duplicate type table entries for the same type1280 // use these fields to make sure we don't duplicate type table entries for the same type
...@@ -1415,6 +1428,7 @@ enum BuiltinFnId {...@@ -1415,6 +1428,7 @@ enum BuiltinFnId {
1415 BuiltinFnIdEnumToInt,1428 BuiltinFnIdEnumToInt,
1416 BuiltinFnIdIntToEnum,1429 BuiltinFnIdIntToEnum,
1417 BuiltinFnIdIntType,1430 BuiltinFnIdIntType,
1431 BuiltinFnIdVectorType,
1418 BuiltinFnIdSetCold,1432 BuiltinFnIdSetCold,
1419 BuiltinFnIdSetRuntimeSafety,1433 BuiltinFnIdSetRuntimeSafety,
1420 BuiltinFnIdSetFloatMode,1434 BuiltinFnIdSetFloatMode,
...@@ -1505,6 +1519,10 @@ struct TypeId {...@@ -1505,6 +1519,10 @@ struct TypeId {
1505 ZigType *err_set_type;1519 ZigType *err_set_type;
1506 ZigType *payload_type;1520 ZigType *payload_type;
1507 } error_union;1521 } error_union;
1522 struct {
1523 ZigType *elem_type;
1524 uint32_t len;
1525 } vector;
1508 } data;1526 } data;
1509};1527};
15101528
...@@ -2139,6 +2157,7 @@ enum IrInstructionId {...@@ -2139,6 +2157,7 @@ enum IrInstructionId {
2139 IrInstructionIdFloatToInt,2157 IrInstructionIdFloatToInt,
2140 IrInstructionIdBoolToInt,2158 IrInstructionIdBoolToInt,
2141 IrInstructionIdIntType,2159 IrInstructionIdIntType,
2160 IrInstructionIdVectorType,
2142 IrInstructionIdBoolNot,2161 IrInstructionIdBoolNot,
2143 IrInstructionIdMemset,2162 IrInstructionIdMemset,
2144 IrInstructionIdMemcpy,2163 IrInstructionIdMemcpy,
...@@ -2807,6 +2826,13 @@ struct IrInstructionIntType {...@@ -2807,6 +2826,13 @@ struct IrInstructionIntType {
2807 IrInstruction *bit_count;2826 IrInstruction *bit_count;
2808};2827};
28092828
2829struct IrInstructionVectorType {
2830 IrInstruction base;
2831
2832 IrInstruction *len;
2833 IrInstruction *elem_type;
2834};
2835
2810struct IrInstructionBoolNot {2836struct IrInstructionBoolNot {
2811 IrInstruction base;2837 IrInstruction base;
28122838
src/analyze.cpp+85-6
...@@ -250,6 +250,7 @@ AstNode *type_decl_node(ZigType *type_entry) {...@@ -250,6 +250,7 @@ AstNode *type_decl_node(ZigType *type_entry) {
250 case ZigTypeIdBoundFn:250 case ZigTypeIdBoundFn:
251 case ZigTypeIdArgTuple:251 case ZigTypeIdArgTuple:
252 case ZigTypeIdPromise:252 case ZigTypeIdPromise:
253 case ZigTypeIdVector:
253 return nullptr;254 return nullptr;
254 }255 }
255 zig_unreachable();256 zig_unreachable();
...@@ -311,6 +312,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {...@@ -311,6 +312,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
311 case ZigTypeIdBoundFn:312 case ZigTypeIdBoundFn:
312 case ZigTypeIdArgTuple:313 case ZigTypeIdArgTuple:
313 case ZigTypeIdPromise:314 case ZigTypeIdPromise:
315 case ZigTypeIdVector:
314 return true;316 return true;
315 }317 }
316 zig_unreachable();318 zig_unreachable();
...@@ -1055,11 +1057,7 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1055,11 +1057,7 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {
1055 }1057 }
1056 if (g->zig_target.arch.arch == ZigLLVM_x86_64) {1058 if (g->zig_target.arch.arch == ZigLLVM_x86_64) {
1057 X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);1059 X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);
1058 if (abi_class == X64CABIClass_MEMORY) {1060 return 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));
1063 } else if (target_is_arm(&g->zig_target)) {1061 } else if (target_is_arm(&g->zig_target)) {
1064 return type_size(g, fn_type_id->return_type) > 16;1062 return type_size(g, fn_type_id->return_type) > 16;
1065 }1063 }
...@@ -1424,6 +1422,7 @@ static bool type_allowed_in_packed_struct(ZigType *type_entry) {...@@ -1424,6 +1422,7 @@ static bool type_allowed_in_packed_struct(ZigType *type_entry) {
1424 case ZigTypeIdPointer:1422 case ZigTypeIdPointer:
1425 case ZigTypeIdArray:1423 case ZigTypeIdArray:
1426 case ZigTypeIdFn:1424 case ZigTypeIdFn:
1425 case ZigTypeIdVector:
1427 return true;1426 return true;
1428 case ZigTypeIdStruct:1427 case ZigTypeIdStruct:
1429 return type_entry->data.structure.layout == ContainerLayoutPacked;1428 return type_entry->data.structure.layout == ContainerLayoutPacked;
...@@ -1472,6 +1471,8 @@ static bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {...@@ -1472,6 +1471,8 @@ static bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
1472 default:1471 default:
1473 return false;1472 return false;
1474 }1473 }
1474 case ZigTypeIdVector:
1475 return type_allowed_in_extern(g, type_entry->data.vector.elem_type);
1475 case ZigTypeIdFloat:1476 case ZigTypeIdFloat:
1476 return true;1477 return true;
1477 case ZigTypeIdArray:1478 case ZigTypeIdArray:
...@@ -1625,6 +1626,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc...@@ -1625,6 +1626,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
1625 case ZigTypeIdUnion:1626 case ZigTypeIdUnion:
1626 case ZigTypeIdFn:1627 case ZigTypeIdFn:
1627 case ZigTypeIdPromise:1628 case ZigTypeIdPromise:
1629 case ZigTypeIdVector:
1628 switch (type_requires_comptime(g, type_entry)) {1630 switch (type_requires_comptime(g, type_entry)) {
1629 case ReqCompTimeNo:1631 case ReqCompTimeNo:
1630 break;1632 break;
...@@ -1720,6 +1722,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc...@@ -1720,6 +1722,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
1720 case ZigTypeIdUnion:1722 case ZigTypeIdUnion:
1721 case ZigTypeIdFn:1723 case ZigTypeIdFn:
1722 case ZigTypeIdPromise:1724 case ZigTypeIdPromise:
1725 case ZigTypeIdVector:
1723 switch (type_requires_comptime(g, fn_type_id.return_type)) {1726 switch (type_requires_comptime(g, fn_type_id.return_type)) {
1724 case ReqCompTimeInvalid:1727 case ReqCompTimeInvalid:
1725 return g->builtin_types.entry_invalid;1728 return g->builtin_types.entry_invalid;
...@@ -3577,6 +3580,7 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry...@@ -3577,6 +3580,7 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry
3577 case ZigTypeIdFn:3580 case ZigTypeIdFn:
3578 case ZigTypeIdBoundFn:3581 case ZigTypeIdBoundFn:
3579 case ZigTypeIdPromise:3582 case ZigTypeIdPromise:
3583 case ZigTypeIdVector:
3580 return type_entry;3584 return type_entry;
3581 }3585 }
3582 zig_unreachable();3586 zig_unreachable();
...@@ -3943,6 +3947,7 @@ static bool is_container(ZigType *type_entry) {...@@ -3943,6 +3947,7 @@ static bool is_container(ZigType *type_entry) {
3943 case ZigTypeIdArgTuple:3947 case ZigTypeIdArgTuple:
3944 case ZigTypeIdOpaque:3948 case ZigTypeIdOpaque:
3945 case ZigTypeIdPromise:3949 case ZigTypeIdPromise:
3950 case ZigTypeIdVector:
3946 return false;3951 return false;
3947 }3952 }
3948 zig_unreachable();3953 zig_unreachable();
...@@ -4002,6 +4007,7 @@ void resolve_container_type(CodeGen *g, ZigType *type_entry) {...@@ -4002,6 +4007,7 @@ void resolve_container_type(CodeGen *g, ZigType *type_entry) {
4002 case ZigTypeIdArgTuple:4007 case ZigTypeIdArgTuple:
4003 case ZigTypeIdOpaque:4008 case ZigTypeIdOpaque:
4004 case ZigTypeIdPromise:4009 case ZigTypeIdPromise:
4010 case ZigTypeIdVector:
4005 zig_unreachable();4011 zig_unreachable();
4006 }4012 }
4007}4013}
...@@ -4451,6 +4457,34 @@ ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {...@@ -4451,6 +4457,34 @@ ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
4451 return new_entry;4457 return new_entry;
4452}4458}
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
4454ZigType **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type) {4488ZigType **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type) {
4455 return &g->builtin_types.entry_c_int[c_int_type];4489 return &g->builtin_types.entry_c_int[c_int_type];
4456}4490}
...@@ -4482,6 +4516,7 @@ bool handle_is_ptr(ZigType *type_entry) {...@@ -4482,6 +4516,7 @@ bool handle_is_ptr(ZigType *type_entry) {
4482 case ZigTypeIdFn:4516 case ZigTypeIdFn:
4483 case ZigTypeIdEnum:4517 case ZigTypeIdEnum:
4484 case ZigTypeIdPromise:4518 case ZigTypeIdPromise:
4519 case ZigTypeIdVector:
4485 return false;4520 return false;
4486 case ZigTypeIdArray:4521 case ZigTypeIdArray:
4487 case ZigTypeIdStruct:4522 case ZigTypeIdStruct:
...@@ -4914,6 +4949,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {...@@ -4914,6 +4949,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
4914 return hash_const_val_error_set(const_val);4949 return hash_const_val_error_set(const_val);
4915 case ZigTypeIdNamespace:4950 case ZigTypeIdNamespace:
4916 return hash_ptr(const_val->data.x_import);4951 return hash_ptr(const_val->data.x_import);
4952 case ZigTypeIdVector:
4953 // TODO better hashing algorithm
4954 return 3647867726;
4917 case ZigTypeIdBoundFn:4955 case ZigTypeIdBoundFn:
4918 case ZigTypeIdInvalid:4956 case ZigTypeIdInvalid:
4919 case ZigTypeIdUnreachable:4957 case ZigTypeIdUnreachable:
...@@ -4966,6 +5004,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {...@@ -4966,6 +5004,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
4966 case ZigTypeIdBool:5004 case ZigTypeIdBool:
4967 case ZigTypeIdUnreachable:5005 case ZigTypeIdUnreachable:
4968 case ZigTypeIdInt:5006 case ZigTypeIdInt:
5007 case ZigTypeIdVector:
4969 case ZigTypeIdFloat:5008 case ZigTypeIdFloat:
4970 case ZigTypeIdComptimeFloat:5009 case ZigTypeIdComptimeFloat:
4971 case ZigTypeIdComptimeInt:5010 case ZigTypeIdComptimeInt:
...@@ -5049,6 +5088,7 @@ static bool return_type_is_cacheable(ZigType *return_type) {...@@ -5049,6 +5088,7 @@ static bool return_type_is_cacheable(ZigType *return_type) {
5049 case ZigTypeIdErrorSet:5088 case ZigTypeIdErrorSet:
5050 case ZigTypeIdEnum:5089 case ZigTypeIdEnum:
5051 case ZigTypeIdPointer:5090 case ZigTypeIdPointer:
5091 case ZigTypeIdVector:
5052 return true;5092 return true;
50535093
5054 case ZigTypeIdArray:5094 case ZigTypeIdArray:
...@@ -5201,6 +5241,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {...@@ -5201,6 +5241,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
5201 case ZigTypeIdErrorSet:5241 case ZigTypeIdErrorSet:
5202 case ZigTypeIdEnum:5242 case ZigTypeIdEnum:
5203 case ZigTypeIdInt:5243 case ZigTypeIdInt:
5244 case ZigTypeIdVector:
5204 return type_has_bits(type_entry) ? OnePossibleValueNo : OnePossibleValueYes;5245 return type_has_bits(type_entry) ? OnePossibleValueNo : OnePossibleValueYes;
5205 case ZigTypeIdPointer:5246 case ZigTypeIdPointer:
5206 return type_has_one_possible_value(g, type_entry->data.pointer.child_type);5247 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) {...@@ -5251,6 +5292,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
5251 case ZigTypeIdErrorSet:5292 case ZigTypeIdErrorSet:
5252 case ZigTypeIdBool:5293 case ZigTypeIdBool:
5253 case ZigTypeIdInt:5294 case ZigTypeIdInt:
5295 case ZigTypeIdVector:
5254 case ZigTypeIdFloat:5296 case ZigTypeIdFloat:
5255 case ZigTypeIdVoid:5297 case ZigTypeIdVoid:
5256 case ZigTypeIdUnreachable:5298 case ZigTypeIdUnreachable:
...@@ -5777,7 +5819,7 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {...@@ -5777,7 +5819,7 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
5777 ConstExprValue *a_elems = a->data.x_array.data.s_none.elements;5819 ConstExprValue *a_elems = a->data.x_array.data.s_none.elements;
5778 ConstExprValue *b_elems = b->data.x_array.data.s_none.elements;5820 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) {
5781 if (!const_values_equal(g, &a_elems[i], &b_elems[i]))5823 if (!const_values_equal(g, &a_elems[i], &b_elems[i]))
5782 return false;5824 return false;
5783 }5825 }
...@@ -5811,6 +5853,20 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {...@@ -5811,6 +5853,20 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
5811 case ZigTypeIdArgTuple:5853 case ZigTypeIdArgTuple:
5812 return a->data.x_arg_tuple.start_index == b->data.x_arg_tuple.start_index &&5854 return a->data.x_arg_tuple.start_index == b->data.x_arg_tuple.start_index &&
5813 a->data.x_arg_tuple.end_index == b->data.x_arg_tuple.end_index;5855 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 }
5814 case ZigTypeIdBoundFn:5870 case ZigTypeIdBoundFn:
5815 case ZigTypeIdInvalid:5871 case ZigTypeIdInvalid:
5816 case ZigTypeIdUnreachable:5872 case ZigTypeIdUnreachable:
...@@ -6042,6 +6098,18 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -6042,6 +6098,18 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
6042 }6098 }
6043 }6099 }
6044 zig_unreachable();6100 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 }
6045 case ZigTypeIdNull:6113 case ZigTypeIdNull:
6046 {6114 {
6047 buf_appendf(buf, "null");6115 buf_appendf(buf, "null");
...@@ -6200,6 +6268,8 @@ uint32_t type_id_hash(TypeId x) {...@@ -6200,6 +6268,8 @@ uint32_t type_id_hash(TypeId x) {
6200 case ZigTypeIdInt:6268 case ZigTypeIdInt:
6201 return (x.data.integer.is_signed ? (uint32_t)2652528194 : (uint32_t)163929201) +6269 return (x.data.integer.is_signed ? (uint32_t)2652528194 : (uint32_t)163929201) +
6202 (((uint32_t)x.data.integer.bit_count) ^ (uint32_t)2998081557);6270 (((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);
6203 }6273 }
6204 zig_unreachable();6274 zig_unreachable();
6205}6275}
...@@ -6248,6 +6318,9 @@ bool type_id_eql(TypeId a, TypeId b) {...@@ -6248,6 +6318,9 @@ bool type_id_eql(TypeId a, TypeId b) {
6248 case ZigTypeIdInt:6318 case ZigTypeIdInt:
6249 return a.data.integer.is_signed == b.data.integer.is_signed &&6319 return a.data.integer.is_signed == b.data.integer.is_signed &&
6250 a.data.integer.bit_count == b.data.integer.bit_count;6320 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;
6251 }6324 }
6252 zig_unreachable();6325 zig_unreachable();
6253}6326}
...@@ -6382,6 +6455,7 @@ static const ZigTypeId all_type_ids[] = {...@@ -6382,6 +6455,7 @@ static const ZigTypeId all_type_ids[] = {
6382 ZigTypeIdArgTuple,6455 ZigTypeIdArgTuple,
6383 ZigTypeIdOpaque,6456 ZigTypeIdOpaque,
6384 ZigTypeIdPromise,6457 ZigTypeIdPromise,
6458 ZigTypeIdVector,
6385};6459};
63866460
6387ZigTypeId type_id_at_index(size_t index) {6461ZigTypeId type_id_at_index(size_t index) {
...@@ -6447,6 +6521,8 @@ size_t type_id_index(ZigType *entry) {...@@ -6447,6 +6521,8 @@ size_t type_id_index(ZigType *entry) {
6447 return 22;6521 return 22;
6448 case ZigTypeIdPromise:6522 case ZigTypeIdPromise:
6449 return 23;6523 return 23;
6524 case ZigTypeIdVector:
6525 return 24;
6450 }6526 }
6451 zig_unreachable();6527 zig_unreachable();
6452}6528}
...@@ -6503,6 +6579,8 @@ const char *type_id_name(ZigTypeId id) {...@@ -6503,6 +6579,8 @@ const char *type_id_name(ZigTypeId id) {
6503 return "Opaque";6579 return "Opaque";
6504 case ZigTypeIdPromise:6580 case ZigTypeIdPromise:
6505 return "Promise";6581 return "Promise";
6582 case ZigTypeIdVector:
6583 return "Vector";
6506 }6584 }
6507 zig_unreachable();6585 zig_unreachable();
6508}6586}
...@@ -6658,6 +6736,7 @@ X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) {...@@ -6658,6 +6736,7 @@ X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) {
6658 case ZigTypeIdBool:6736 case ZigTypeIdBool:
6659 return X64CABIClass_INTEGER;6737 return X64CABIClass_INTEGER;
6660 case ZigTypeIdFloat:6738 case ZigTypeIdFloat:
6739 case ZigTypeIdVector:
6661 return X64CABIClass_SSE;6740 return X64CABIClass_SSE;
6662 case ZigTypeIdStruct: {6741 case ZigTypeIdStruct: {
6663 // "If the size of an object is larger than four eightbytes, or it contains unaligned6742 // "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...@@ -20,6 +20,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
20uint64_t type_size(CodeGen *g, ZigType *type_entry);20uint64_t type_size(CodeGen *g, ZigType *type_entry);
21uint64_t type_size_bits(CodeGen *g, ZigType *type_entry);21uint64_t type_size_bits(CodeGen *g, ZigType *type_entry);
22ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);22ZigType *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);
23ZigType **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type);24ZigType **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type);
24ZigType *get_c_int_type(CodeGen *g, CIntType c_int_type);25ZigType *get_c_int_type(CodeGen *g, CIntType c_int_type);
25ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id);26ZigType *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_...@@ -1980,7 +1980,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
1980 break;1980 break;
1981 }1981 }
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 ||
1984 ty->id == ZigTypeIdInt // TODO investigate if we need to change this1984 ty->id == ZigTypeIdInt // TODO investigate if we need to change this
1985 ) {1985 ) {
1986 switch (fn_walk->id) {1986 switch (fn_walk->id) {
...@@ -2660,6 +2660,27 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -2660,6 +2660,27 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
2660 } else {2660 } else {
2661 return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, "");2661 return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, "");
2662 }2662 }
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 }
2663 } else {2684 } else {
2664 zig_unreachable();2685 zig_unreachable();
2665 }2686 }
...@@ -5211,6 +5232,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5211,6 +5232,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5211 case IrInstructionIdCUndef:5232 case IrInstructionIdCUndef:
5212 case IrInstructionIdEmbedFile:5233 case IrInstructionIdEmbedFile:
5213 case IrInstructionIdIntType:5234 case IrInstructionIdIntType:
5235 case IrInstructionIdVectorType:
5214 case IrInstructionIdMemberCount:5236 case IrInstructionIdMemberCount:
5215 case IrInstructionIdMemberType:5237 case IrInstructionIdMemberType:
5216 case IrInstructionIdMemberName:5238 case IrInstructionIdMemberName:
...@@ -5620,6 +5642,8 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con...@@ -5620,6 +5642,8 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
5620 }5642 }
5621 case ZigTypeIdArray:5643 case ZigTypeIdArray:
5622 zig_panic("TODO bit pack an array");5644 zig_panic("TODO bit pack an array");
5645 case ZigTypeIdVector:
5646 zig_panic("TODO bit pack a vector");
5623 case ZigTypeIdUnion:5647 case ZigTypeIdUnion:
5624 zig_panic("TODO bit pack a union");5648 zig_panic("TODO bit pack a union");
5625 case ZigTypeIdStruct:5649 case ZigTypeIdStruct:
...@@ -5992,6 +6016,14 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c...@@ -5992,6 +6016,14 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
5992 }6016 }
5993 }6017 }
5994 }6018 }
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 }
5995 case ZigTypeIdUnion:6027 case ZigTypeIdUnion:
5996 {6028 {
5997 LLVMTypeRef union_type_ref = type_entry->data.unionation.union_type_ref;6029 LLVMTypeRef union_type_ref = type_entry->data.unionation.union_type_ref;
...@@ -6927,6 +6959,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -6927,6 +6959,7 @@ static void define_builtin_fns(CodeGen *g) {
6927 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);6959 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);
6928 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);6960 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
6929 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int6961 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
6962 create_builtin_fn(g, BuiltinFnIdVectorType, "Vector", 2);
6930 create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1);6963 create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1);
6931 create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1);6964 create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1);
6932 create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 1);6965 create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 1);
...@@ -7152,6 +7185,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7152,6 +7185,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7152 " ArgTuple: void,\n"7185 " ArgTuple: void,\n"
7153 " Opaque: void,\n"7186 " Opaque: void,\n"
7154 " Promise: Promise,\n"7187 " Promise: Promise,\n"
7188 " Vector: Vector,\n"
7155 "\n\n"7189 "\n\n"
7156 " pub const Int = struct {\n"7190 " pub const Int = struct {\n"
7157 " is_signed: bool,\n"7191 " is_signed: bool,\n"
...@@ -7270,6 +7304,11 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7270,6 +7304,11 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7270 " child: ?type,\n"7304 " child: ?type,\n"
7271 " };\n"7305 " };\n"
7272 "\n"7306 "\n"
7307 " pub const Vector = struct {\n"
7308 " len: u32,\n"
7309 " child: type,\n"
7310 " };\n"
7311 "\n"
7273 " pub const Definition = struct {\n"7312 " pub const Definition = struct {\n"
7274 " name: []const u8,\n"7313 " name: []const u8,\n"
7275 " is_pub: bool,\n"7314 " is_pub: bool,\n"
...@@ -7841,6 +7880,9 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e...@@ -7841,6 +7880,9 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
7841 case ZigTypeIdArray:7880 case ZigTypeIdArray:
7842 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.array.child_type);7881 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.array.child_type);
7843 return;7882 return;
7883 case ZigTypeIdVector:
7884 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.vector.elem_type);
7885 return;
7844 case ZigTypeIdOptional:7886 case ZigTypeIdOptional:
7845 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.maybe.child_type);7887 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.maybe.child_type);
7846 return;7888 return;
...@@ -7972,6 +8014,8 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu...@@ -7972,6 +8014,8 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu
7972 buf_appendf(out_buf, "%s", buf_ptr(child_buf));8014 buf_appendf(out_buf, "%s", buf_ptr(child_buf));
7973 return;8015 return;
7974 }8016 }
8017 case ZigTypeIdVector:
8018 zig_panic("TODO implement get_c_type for vector types");
7975 case ZigTypeIdErrorUnion:8019 case ZigTypeIdErrorUnion:
7976 case ZigTypeIdErrorSet:8020 case ZigTypeIdErrorSet:
7977 case ZigTypeIdFn:8021 case ZigTypeIdFn:
...@@ -8137,6 +8181,7 @@ static void gen_h_file(CodeGen *g) {...@@ -8137,6 +8181,7 @@ static void gen_h_file(CodeGen *g) {
8137 case ZigTypeIdOptional:8181 case ZigTypeIdOptional:
8138 case ZigTypeIdFn:8182 case ZigTypeIdFn:
8139 case ZigTypeIdPromise:8183 case ZigTypeIdPromise:
8184 case ZigTypeIdVector:
8140 zig_unreachable();8185 zig_unreachable();
8141 case ZigTypeIdEnum:8186 case ZigTypeIdEnum:
8142 if (type_entry->data.enumeration.layout == ContainerLayoutExtern) {8187 if (type_entry->data.enumeration.layout == ContainerLayoutExtern) {
src/ir.cpp+168-45
...@@ -587,6 +587,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) {...@@ -587,6 +587,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) {
587 return IrInstructionIdIntType;587 return IrInstructionIdIntType;
588}588}
589589
590static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorType *) {
591 return IrInstructionIdVectorType;
592}
593
590static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) {594static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) {
591 return IrInstructionIdBoolNot;595 return IrInstructionIdBoolNot;
592}596}
...@@ -1953,6 +1957,19 @@ static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *s...@@ -1953,6 +1957,19 @@ static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *s
1953 return &instruction->base;1957 return &instruction->base;
1954}1958}
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
1956static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {1973static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1957 IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node);1974 IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node);
1958 instruction->value = value;1975 instruction->value = value;
...@@ -4230,6 +4247,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4230,6 +4247,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4230 IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value);4247 IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value);
4231 return ir_lval_wrap(irb, scope, int_type, lval);4248 return ir_lval_wrap(irb, scope, int_type, lval);
4232 }4249 }
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 }
4233 case BuiltinFnIdMemcpy:4265 case BuiltinFnIdMemcpy:
4234 {4266 {
4235 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);4267 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 *...@@ -11617,6 +11649,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
11617 case ZigTypeIdComptimeInt:11649 case ZigTypeIdComptimeInt:
11618 case ZigTypeIdInt:11650 case ZigTypeIdInt:
11619 case ZigTypeIdFloat:11651 case ZigTypeIdFloat:
11652 case ZigTypeIdVector:
11620 operator_allowed = true;11653 operator_allowed = true;
11621 break;11654 break;
1162211655
...@@ -12032,6 +12065,48 @@ static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *b...@@ -12032,6 +12065,48 @@ static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *b
12032 return result;12065 return result;
12033}12066}
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
12035static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) {12110static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) {
12036 IrInstruction *op1 = instruction->op1->child;12111 IrInstruction *op1 = instruction->op1->child;
12037 if (type_is_invalid(op1->value.type))12112 if (type_is_invalid(op1->value.type))
...@@ -12169,21 +12244,20 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp...@@ -12169,21 +12244,20 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
12169 op_id = IrBinOpRemRem;12244 op_id = IrBinOpRemRem;
12170 }12245 }
1217112246
12247 bool ok = false;
12172 if (is_int) {12248 if (is_int) {
12173 // int12249 ok = true;
12174 } else if (is_float &&12250 } else if (is_float && ok_float_op(op_id)) {
12175 (op_id == IrBinOpAdd ||12251 ok = true;
12176 op_id == IrBinOpSub ||12252 } else if (resolved_type->id == ZigTypeIdVector) {
12177 op_id == IrBinOpMult ||12253 ZigType *elem_type = resolved_type->data.vector.elem_type;
12178 op_id == IrBinOpDivUnspecified ||12254 if (elem_type->id == ZigTypeIdInt || elem_type->id == ZigTypeIdComptimeInt) {
12179 op_id == IrBinOpDivTrunc ||12255 ok = true;
12180 op_id == IrBinOpDivFloor ||12256 } else if ((elem_type->id == ZigTypeIdFloat || elem_type->id == ZigTypeIdComptimeFloat) && ok_float_op(op_id)) {
12181 op_id == IrBinOpDivExact ||12257 ok = true;
12182 op_id == IrBinOpRemRem ||12258 }
12183 op_id == IrBinOpRemMod))12259 }
12184 {12260 if (!ok) {
12185 // float
12186 } else {
12187 AstNode *source_node = instruction->base.source_node;12261 AstNode *source_node = instruction->base.source_node;
12188 ir_add_error_node(ira, source_node,12262 ir_add_error_node(ira, source_node,
12189 buf_sprintf("invalid operands to binary expression: '%s' and '%s'",12263 buf_sprintf("invalid operands to binary expression: '%s' and '%s'",
...@@ -12817,6 +12891,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio...@@ -12817,6 +12891,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
12817 case ZigTypeIdPointer:12891 case ZigTypeIdPointer:
12818 case ZigTypeIdArray:12892 case ZigTypeIdArray:
12819 case ZigTypeIdBool:12893 case ZigTypeIdBool:
12894 case ZigTypeIdVector:
12820 break;12895 break;
12821 case ZigTypeIdMetaType:12896 case ZigTypeIdMetaType:
12822 case ZigTypeIdVoid:12897 case ZigTypeIdVoid:
...@@ -12851,6 +12926,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio...@@ -12851,6 +12926,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
12851 case ZigTypeIdOptional:12926 case ZigTypeIdOptional:
12852 case ZigTypeIdErrorUnion:12927 case ZigTypeIdErrorUnion:
12853 case ZigTypeIdErrorSet:12928 case ZigTypeIdErrorSet:
12929 case ZigTypeIdVector:
12854 zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name));12930 zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name));
12855 case ZigTypeIdNamespace:12931 case ZigTypeIdNamespace:
12856 case ZigTypeIdBoundFn:12932 case ZigTypeIdBoundFn:
...@@ -14009,6 +14085,7 @@ static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_...@@ -14009,6 +14085,7 @@ static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_
14009 case ZigTypeIdVoid:14085 case ZigTypeIdVoid:
14010 case ZigTypeIdBool:14086 case ZigTypeIdBool:
14011 case ZigTypeIdInt:14087 case ZigTypeIdInt:
14088 case ZigTypeIdVector:
14012 case ZigTypeIdFloat:14089 case ZigTypeIdFloat:
14013 case ZigTypeIdPointer:14090 case ZigTypeIdPointer:
14014 case ZigTypeIdArray:14091 case ZigTypeIdArray:
...@@ -15383,37 +15460,7 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio...@@ -15383,37 +15460,7 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio
15383 ZigType *type_entry = expr_value->value.type;15460 ZigType *type_entry = expr_value->value.type;
15384 if (type_is_invalid(type_entry))15461 if (type_is_invalid(type_entry))
15385 return ira->codegen->invalid_instruction;15462 return ira->codegen->invalid_instruction;
15386 switch (type_entry->id) {15463 return ir_const_type(ira, &typeof_instruction->base, type_entry);
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();
15417}15464}
1541815465
15419static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira,15466static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira,
...@@ -15652,6 +15699,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,...@@ -15652,6 +15699,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
15652 case ZigTypeIdNamespace:15699 case ZigTypeIdNamespace:
15653 case ZigTypeIdBoundFn:15700 case ZigTypeIdBoundFn:
15654 case ZigTypeIdPromise:15701 case ZigTypeIdPromise:
15702 case ZigTypeIdVector:
15655 {15703 {
15656 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown)))15704 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown)))
15657 return ira->codegen->invalid_instruction;15705 return ira->codegen->invalid_instruction;
...@@ -15772,6 +15820,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,...@@ -15772,6 +15820,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,
15772 case ZigTypeIdNamespace:15820 case ZigTypeIdNamespace:
15773 case ZigTypeIdBoundFn:15821 case ZigTypeIdBoundFn:
15774 case ZigTypeIdPromise:15822 case ZigTypeIdPromise:
15823 case ZigTypeIdVector:
15775 {15824 {
15776 if ((err = ensure_complete_type(ira->codegen, child_type)))15825 if ((err = ensure_complete_type(ira->codegen, child_type)))
15777 return ira->codegen->invalid_instruction;15826 return ira->codegen->invalid_instruction;
...@@ -15838,6 +15887,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,...@@ -15838,6 +15887,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
15838 case ZigTypeIdUnion:15887 case ZigTypeIdUnion:
15839 case ZigTypeIdFn:15888 case ZigTypeIdFn:
15840 case ZigTypeIdPromise:15889 case ZigTypeIdPromise:
15890 case ZigTypeIdVector:
15841 {15891 {
15842 uint64_t size_in_bytes = type_size(ira->codegen, type_entry);15892 uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
15843 return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes);15893 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,...@@ -16307,6 +16357,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
16307 case ZigTypeIdBoundFn:16357 case ZigTypeIdBoundFn:
16308 case ZigTypeIdArgTuple:16358 case ZigTypeIdArgTuple:
16309 case ZigTypeIdOpaque:16359 case ZigTypeIdOpaque:
16360 case ZigTypeIdVector:
16310 ir_add_error(ira, &switch_target_instruction->base,16361 ir_add_error(ira, &switch_target_instruction->base,
16311 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));16362 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));
16312 return ira->codegen->invalid_instruction;16363 return ira->codegen->invalid_instruction;
...@@ -17496,6 +17547,27 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE...@@ -17496,6 +17547,27 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
1749617547
17497 break;17548 break;
17498 }17549 }
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 }
17499 case ZigTypeIdOptional:17571 case ZigTypeIdOptional:
17500 {17572 {
17501 result = create_const_vals(1);17573 result = create_const_vals(1);
...@@ -18671,6 +18743,30 @@ static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstruct...@@ -18671,6 +18743,30 @@ static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstruct
18671 return ir_const_type(ira, &instruction->base, get_int_type(ira->codegen, is_signed, (uint32_t)bit_count));18743 return ir_const_type(ira, &instruction->base, get_int_type(ira->codegen, is_signed, (uint32_t)bit_count));
18672}18744}
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
18674static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) {18770static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) {
18675 IrInstruction *value = instruction->value->child;18771 IrInstruction *value = instruction->value->child;
18676 if (type_is_invalid(value->value.type))18772 if (type_is_invalid(value->value.type))
...@@ -19474,6 +19570,7 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct...@@ -19474,6 +19570,7 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct
19474 case ZigTypeIdEnum:19570 case ZigTypeIdEnum:
19475 case ZigTypeIdUnion:19571 case ZigTypeIdUnion:
19476 case ZigTypeIdFn:19572 case ZigTypeIdFn:
19573 case ZigTypeIdVector:
19477 {19574 {
19478 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry);19575 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry);
19479 return ir_const_unsigned(ira, &instruction->base, align_in_bytes);19576 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...@@ -20311,6 +20408,15 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
20311 }20408 }
20312 }20409 }
20313 return;20410 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 }
20314 case ZigTypeIdStruct:20420 case ZigTypeIdStruct:
20315 zig_panic("TODO buf_write_value_bytes struct type");20421 zig_panic("TODO buf_write_value_bytes struct type");
20316 case ZigTypeIdOptional:20422 case ZigTypeIdOptional:
...@@ -20387,6 +20493,20 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou...@@ -20387,6 +20493,20 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
20387 }20493 }
20388 zig_unreachable();20494 zig_unreachable();
20389 }20495 }
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 }
20390 case ZigTypeIdEnum:20510 case ZigTypeIdEnum:
20391 switch (val->type->data.enumeration.layout) {20511 switch (val->type->data.enumeration.layout) {
20392 case ContainerLayoutAuto:20512 case ContainerLayoutAuto:
...@@ -21633,6 +21753,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -21633,6 +21753,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
21633 return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction);21753 return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction);
21634 case IrInstructionIdIntType:21754 case IrInstructionIdIntType:
21635 return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction);21755 return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction);
21756 case IrInstructionIdVectorType:
21757 return ir_analyze_instruction_vector_type(ira, (IrInstructionVectorType *)instruction);
21636 case IrInstructionIdBoolNot:21758 case IrInstructionIdBoolNot:
21637 return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction);21759 return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction);
21638 case IrInstructionIdMemset:21760 case IrInstructionIdMemset:
...@@ -21943,6 +22065,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -21943,6 +22065,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
21943 case IrInstructionIdEmbedFile:22065 case IrInstructionIdEmbedFile:
21944 case IrInstructionIdTruncate:22066 case IrInstructionIdTruncate:
21945 case IrInstructionIdIntType:22067 case IrInstructionIdIntType:
22068 case IrInstructionIdVectorType:
21946 case IrInstructionIdBoolNot:22069 case IrInstructionIdBoolNot:
21947 case IrInstructionIdSlice:22070 case IrInstructionIdSlice:
21948 case IrInstructionIdMemberCount:22071 case IrInstructionIdMemberCount:
src/ir_print.cpp+11
...@@ -719,6 +719,14 @@ static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) {...@@ -719,6 +719,14 @@ static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) {
719 fprintf(irp->f, ")");719 fprintf(irp->f, ")");
720}720}
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
722static void ir_print_bool_not(IrPrint *irp, IrInstructionBoolNot *instruction) {730static void ir_print_bool_not(IrPrint *irp, IrInstructionBoolNot *instruction) {
723 fprintf(irp->f, "! ");731 fprintf(irp->f, "! ");
724 ir_print_other_instruction(irp, instruction->value);732 ir_print_other_instruction(irp, instruction->value);
...@@ -1577,6 +1585,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1577,6 +1585,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1577 case IrInstructionIdIntType:1585 case IrInstructionIdIntType:
1578 ir_print_int_type(irp, (IrInstructionIntType *)instruction);1586 ir_print_int_type(irp, (IrInstructionIntType *)instruction);
1579 break;1587 break;
1588 case IrInstructionIdVectorType:
1589 ir_print_vector_type(irp, (IrInstructionVectorType *)instruction);
1590 break;
1580 case IrInstructionIdBoolNot:1591 case IrInstructionIdBoolNot:
1581 ir_print_bool_not(irp, (IrInstructionBoolNot *)instruction);1592 ir_print_bool_not(irp, (IrInstructionBoolNot *)instruction);
1582 break;1593 break;
src/zig_llvm.cpp+13
...@@ -263,6 +263,19 @@ ZigLLVMDIType *ZigLLVMCreateDebugBasicType(ZigLLVMDIBuilder *dibuilder, const ch...@@ -263,6 +263,19 @@ ZigLLVMDIType *ZigLLVMCreateDebugBasicType(ZigLLVMDIBuilder *dibuilder, const ch
263 return reinterpret_cast<ZigLLVMDIType*>(di_type);263 return reinterpret_cast<ZigLLVMDIType*>(di_type);
264}264}
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
266ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t size_in_bits,279ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t size_in_bits,
267 uint64_t align_in_bits, ZigLLVMDIType *elem_type, int elem_count)280 uint64_t align_in_bits, ZigLLVMDIType *elem_type, int elem_count)
268{281{
src/zig_llvm.h+3
...@@ -191,6 +191,9 @@ ZIG_EXTERN_C struct ZigLLVMDISubprogram *ZigLLVMCreateFunction(struct ZigLLVMDIB...@@ -191,6 +191,9 @@ ZIG_EXTERN_C struct ZigLLVMDISubprogram *ZigLLVMCreateFunction(struct ZigLLVMDIB
191 unsigned lineno, struct ZigLLVMDIType *fn_di_type, bool is_local_to_unit, bool is_definition,191 unsigned lineno, struct ZigLLVMDIType *fn_di_type, bool is_local_to_unit, bool is_definition,
192 unsigned scope_line, unsigned flags, bool is_optimized, struct ZigLLVMDISubprogram *decl_subprogram);192 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
194ZIG_EXTERN_C void ZigLLVMFnSetSubprogram(LLVMValueRef fn, struct ZigLLVMDISubprogram *subprogram);197ZIG_EXTERN_C void ZigLLVMFnSetSubprogram(LLVMValueRef fn, struct ZigLLVMDISubprogram *subprogram);
195198
196ZIG_EXTERN_C void ZigLLVMDIBuilderFinalize(struct ZigLLVMDIBuilder *dibuilder);199ZIG_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...@@ -508,6 +508,7 @@ pub fn autoHash(key: var, comptime rng: *std.rand.Random, comptime HashInt: type
508508
509 builtin.TypeId.Optional => @compileError("TODO auto hash for optionals"),509 builtin.TypeId.Optional => @compileError("TODO auto hash for optionals"),
510 builtin.TypeId.Array => @compileError("TODO auto hash for arrays"),510 builtin.TypeId.Array => @compileError("TODO auto hash for arrays"),
511 builtin.TypeId.Vector => @compileError("TODO auto hash for vectors"),
511 builtin.TypeId.Struct => @compileError("TODO auto hash for structs"),512 builtin.TypeId.Struct => @compileError("TODO auto hash for structs"),
512 builtin.TypeId.Union => @compileError("TODO auto hash for unions"),513 builtin.TypeId.Union => @compileError("TODO auto hash for unions"),
513 builtin.TypeId.ErrorUnion => @compileError("TODO auto hash for unions"),514 builtin.TypeId.ErrorUnion => @compileError("TODO auto hash for unions"),
...@@ -555,5 +556,6 @@ pub fn autoEql(a: var, b: @typeOf(a)) bool {...@@ -555,5 +556,6 @@ pub fn autoEql(a: var, b: @typeOf(a)) bool {
555 builtin.TypeId.Struct => @compileError("TODO auto eql for structs"),556 builtin.TypeId.Struct => @compileError("TODO auto eql for structs"),
556 builtin.TypeId.Union => @compileError("TODO auto eql for unions"),557 builtin.TypeId.Union => @compileError("TODO auto eql for unions"),
557 builtin.TypeId.ErrorUnion => @compileError("TODO auto eql for unions"),558 builtin.TypeId.ErrorUnion => @compileError("TODO auto eql for unions"),
559 builtin.TypeId.Vector => @compileError("TODO auto eql for vectors"),
558 }560 }
559}561}
test/stage1/behavior/type_info.zig+14-2
...@@ -171,11 +171,11 @@ fn testUnion() void {...@@ -171,11 +171,11 @@ fn testUnion() void {
171 assertOrPanic(TypeId(typeinfo_info) == TypeId.Union);171 assertOrPanic(TypeId(typeinfo_info) == TypeId.Union);
172 assertOrPanic(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);172 assertOrPanic(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
173 assertOrPanic(typeinfo_info.Union.tag_type.? == TypeId);173 assertOrPanic(typeinfo_info.Union.tag_type.? == TypeId);
174 assertOrPanic(typeinfo_info.Union.fields.len == 24);174 assertOrPanic(typeinfo_info.Union.fields.len == 25);
175 assertOrPanic(typeinfo_info.Union.fields[4].enum_field != null);175 assertOrPanic(typeinfo_info.Union.fields[4].enum_field != null);
176 assertOrPanic(typeinfo_info.Union.fields[4].enum_field.?.value == 4);176 assertOrPanic(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
177 assertOrPanic(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));177 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
180 const TestNoTagUnion = union {180 const TestNoTagUnion = union {
181 Foo: void,181 Foo: void,
...@@ -262,3 +262,15 @@ test "typeInfo with comptime parameter in struct fn def" {...@@ -262,3 +262,15 @@ test "typeInfo with comptime parameter in struct fn def" {
262 };262 };
263 comptime var info = @typeInfo(S);263 comptime var info = @typeInfo(S);
264}264}
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}