authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-06 13:20:15-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-07-06 13:20:15-04:00
log6ba843ee0fee75490655544bb9442f20e271cc2c
tree4400ca112e5638a9c7d201e50f9c8aeeda797e91
parentcff7ecee070df59683dbbe3ede04b494d4619f7f
parentf02ee7a9f5a72f24a645f36db7ae7828f29d3393
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #9310 from ziglang/stage1-better-hashing

Speed up stage 1 by improving hash functions

11 files changed, 539 insertions(+), 313 deletions(-)

src/stage1/all_types.hpp+4-4
...@@ -1879,8 +1879,8 @@ struct TypeId {...@@ -1879,8 +1879,8 @@ struct TypeId {
1879 } data;1879 } data;
1880};1880};
18811881
1882uint32_t type_id_hash(TypeId);1882uint32_t type_id_hash(TypeId const *);
1883bool type_id_eql(TypeId a, TypeId b);1883bool type_id_eql(TypeId const *a, TypeId const *b);
18841884
1885enum ZigLLVMFnId {1885enum ZigLLVMFnId {
1886 ZigLLVMFnIdCtz,1886 ZigLLVMFnIdCtz,
...@@ -1935,8 +1935,8 @@ struct ZigLLVMFnKey {...@@ -1935,8 +1935,8 @@ struct ZigLLVMFnKey {
1935 } data;1935 } data;
1936};1936};
19371937
1938uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey);1938uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey const *);
1939bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b);1939bool zig_llvm_fn_key_eql(ZigLLVMFnKey const *a, ZigLLVMFnKey const *b);
19401940
1941struct TimeEvent {1941struct TimeEvent {
1942 double time;1942 double time;
src/stage1/analyze.cpp+304-251
...@@ -5507,34 +5507,48 @@ bool handle_is_ptr(CodeGen *g, ZigType *type_entry) {...@@ -5507,34 +5507,48 @@ bool handle_is_ptr(CodeGen *g, ZigType *type_entry) {
5507 zig_unreachable();5507 zig_unreachable();
5508}5508}
55095509
5510static uint32_t hash_ptr(void *ptr) {5510static const uint32_t HASH_INIT = 0x811c9dc5U;
5511 return (uint32_t)(((uintptr_t)ptr) % UINT32_MAX);5511
5512template<typename T>
5513static uint32_t hash_combine(uint32_t hash, const T *value, size_t count = 1) {
5514 // Simple FNV32 hash
5515 size_t len = sizeof(T) * count;
5516 const unsigned char *char_bytes = (const unsigned char*)value;
5517 for (size_t c = 0; c < len; ++c) {
5518 hash ^= char_bytes[c];
5519 hash *= 0x01000193U;
5520 }
5521 return hash;
5522}
5523
5524static uint32_t hash_combine_bigint(uint32_t hash, const BigInt *value) {
5525 return hash_combine(hash, bigint_ptr(value), value->digit_count);
5512}5526}
55135527
5514static uint32_t hash_size(size_t x) {5528static uint32_t hash_combine_buf(uint32_t hash, const Buf *buf) {
5515 return (uint32_t)(x % UINT32_MAX);5529 return hash_combine(hash, buf_ptr(buf), buf_len(buf));
5516}5530}
55175531
5518uint32_t fn_table_entry_hash(ZigFn* value) {5532uint32_t fn_table_entry_hash(ZigFn* value) {
5519 return ptr_hash(value);5533 return hash_combine(HASH_INIT, &value);
5520}5534}
55215535
5522bool fn_table_entry_eql(ZigFn *a, ZigFn *b) {5536bool fn_table_entry_eql(ZigFn *a, ZigFn *b) {
5523 return ptr_eq(a, b);5537 return a == b;
5524}5538}
55255539
5526uint32_t fn_type_id_hash(FnTypeId *id) {5540uint32_t fn_type_id_hash(FnTypeId *id) {
5527 uint32_t result = 0;5541 uint32_t hash = HASH_INIT;
5528 result += ((uint32_t)(id->cc)) * (uint32_t)3349388391;5542 hash = hash_combine(hash, &id->cc);
5529 result += id->is_var_args ? (uint32_t)1931444534 : 0;5543 hash = hash_combine(hash, &id->is_var_args);
5530 result += hash_ptr(id->return_type);5544 hash = hash_combine(hash, &id->return_type);
5531 result += id->alignment * 0xd3b3f3e2;5545 hash = hash_combine(hash, &id->alignment);
5532 for (size_t i = 0; i < id->param_count; i += 1) {5546 for (size_t i = 0; i < id->param_count; i += 1) {
5533 FnTypeParamInfo *info = &id->param_info[i];5547 FnTypeParamInfo *info = &id->param_info[i];
5534 result += info->is_noalias ? (uint32_t)892356923 : 0;5548 hash = hash_combine(hash, &info->is_noalias);
5535 result += hash_ptr(info->type);5549 hash = hash_combine(hash, &info->type);
5536 }5550 }
5537 return result;5551 return hash;
5538}5552}
55395553
5540bool fn_type_id_eql(FnTypeId *a, FnTypeId *b) {5554bool fn_type_id_eql(FnTypeId *a, FnTypeId *b) {
...@@ -5559,194 +5573,200 @@ bool fn_type_id_eql(FnTypeId *a, FnTypeId *b) {...@@ -5559,194 +5573,200 @@ bool fn_type_id_eql(FnTypeId *a, FnTypeId *b) {
5559 return true;5573 return true;
5560}5574}
55615575
5562static uint32_t hash_const_val_error_set(ZigValue *const_val) {5576static uint32_t hash_combine_const_val_error_set(uint32_t hash_val, ZigValue *const_val) {
5563 assert(const_val->data.x_err_set != nullptr);5577 assert(const_val->data.x_err_set != nullptr);
5564 return const_val->data.x_err_set->value ^ 2630160122;5578 return hash_combine(hash_val, &const_val->data.x_err_set->value);
5565}5579}
55665580
5567static uint32_t hash_const_val_ptr(ZigValue *const_val) {5581static uint32_t hash_combine_const_val_ptr(uint32_t hash_val, ZigValue *const_val) {
5568 uint32_t hash_val = 0;5582 hash_val = hash_combine(hash_val, &const_val->data.x_ptr.special);
5569 switch (const_val->data.x_ptr.mut) {
5570 case ConstPtrMutRuntimeVar:
5571 hash_val += (uint32_t)3500721036;
5572 break;
5573 case ConstPtrMutComptimeConst:
5574 hash_val += (uint32_t)4214318515;
5575 break;
5576 case ConstPtrMutInfer:
5577 case ConstPtrMutComptimeVar:
5578 hash_val += (uint32_t)1103195694;
5579 break;
5580 }
5581 switch (const_val->data.x_ptr.special) {5583 switch (const_val->data.x_ptr.special) {
5582 case ConstPtrSpecialInvalid:5584 case ConstPtrSpecialInvalid:
5583 zig_unreachable();5585 zig_unreachable();
5584 case ConstPtrSpecialRef:5586 case ConstPtrSpecialRef:
5585 hash_val += (uint32_t)2478261866;5587 hash_val = hash_combine(hash_val, &const_val->data.x_ptr.data.ref.pointee);
5586 hash_val += hash_ptr(const_val->data.x_ptr.data.ref.pointee);
5587 return hash_val;5588 return hash_val;
5588 case ConstPtrSpecialBaseArray:5589 case ConstPtrSpecialBaseArray:
5589 hash_val += (uint32_t)1764906839;5590 hash_val = hash_combine(hash_val, &const_val->data.x_ptr.data.base_array.array_val);
5590 hash_val += hash_ptr(const_val->data.x_ptr.data.base_array.array_val);5591 hash_val = hash_combine(hash_val, &const_val->data.x_ptr.data.base_array.elem_index);
5591 hash_val += hash_size(const_val->data.x_ptr.data.base_array.elem_index);
5592 return hash_val;5592 return hash_val;
5593 case ConstPtrSpecialSubArray:5593 case ConstPtrSpecialSubArray:
5594 hash_val += (uint32_t)2643358777;5594 hash_val = hash_combine(hash_val, &const_val->data.x_ptr.data.base_array.array_val);
5595 hash_val += hash_ptr(const_val->data.x_ptr.data.base_array.array_val);5595 hash_val = hash_combine(hash_val, &const_val->data.x_ptr.data.base_array.elem_index);
5596 hash_val += hash_size(const_val->data.x_ptr.data.base_array.elem_index);
5597 return hash_val;5596 return hash_val;
5598 case ConstPtrSpecialBaseStruct:5597 case ConstPtrSpecialBaseStruct:
5599 hash_val += (uint32_t)3518317043;5598 hash_val = hash_combine(hash_val, &const_val->data.x_ptr.data.base_struct.struct_val);
5600 hash_val += hash_ptr(const_val->data.x_ptr.data.base_struct.struct_val);5599 hash_val = hash_combine(hash_val, &const_val->data.x_ptr.data.base_struct.field_index);
5601 hash_val += hash_size(const_val->data.x_ptr.data.base_struct.field_index);
5602 return hash_val;5600 return hash_val;
5603 case ConstPtrSpecialBaseErrorUnionCode:5601 case ConstPtrSpecialBaseErrorUnionCode:
5604 hash_val += (uint32_t)2994743799;5602 hash_val = hash_combine(hash_val, &const_val->data.x_ptr.data.base_err_union_code.err_union_val);
5605 hash_val += hash_ptr(const_val->data.x_ptr.data.base_err_union_code.err_union_val);
5606 return hash_val;5603 return hash_val;
5607 case ConstPtrSpecialBaseErrorUnionPayload:5604 case ConstPtrSpecialBaseErrorUnionPayload:
5608 hash_val += (uint32_t)3456080131;5605 hash_val = hash_combine(hash_val, &const_val->data.x_ptr.data.base_err_union_payload.err_union_val);
5609 hash_val += hash_ptr(const_val->data.x_ptr.data.base_err_union_payload.err_union_val);
5610 return hash_val;5606 return hash_val;
5611 case ConstPtrSpecialBaseOptionalPayload:5607 case ConstPtrSpecialBaseOptionalPayload:
5612 hash_val += (uint32_t)3163140517;5608 hash_val = hash_combine(hash_val, &const_val->data.x_ptr.data.base_optional_payload.optional_val);
5613 hash_val += hash_ptr(const_val->data.x_ptr.data.base_optional_payload.optional_val);
5614 return hash_val;5609 return hash_val;
5615 case ConstPtrSpecialHardCodedAddr:5610 case ConstPtrSpecialHardCodedAddr:
5616 hash_val += (uint32_t)4048518294;5611 hash_val = hash_combine(hash_val, &const_val->data.x_ptr.data.hard_coded_addr.addr);
5617 hash_val += hash_size(const_val->data.x_ptr.data.hard_coded_addr.addr);
5618 return hash_val;
5619 case ConstPtrSpecialDiscard:
5620 hash_val += 2010123162;
5621 return hash_val;5612 return hash_val;
5622 case ConstPtrSpecialFunction:5613 case ConstPtrSpecialFunction:
5623 hash_val += (uint32_t)2590901619;5614 hash_val = hash_combine(hash_val, &const_val->data.x_ptr.data.fn.fn_entry);
5624 hash_val += hash_ptr(const_val->data.x_ptr.data.fn.fn_entry);
5625 return hash_val;5615 return hash_val;
5616 case ConstPtrSpecialDiscard:
5626 case ConstPtrSpecialNull:5617 case ConstPtrSpecialNull:
5627 hash_val += (uint32_t)1486246455;5618 // No fields to hash
5628 return hash_val;5619 return hash_val;
5629 }5620 }
5630 zig_unreachable();5621 zig_unreachable();
5631}5622}
56325623
5633static uint32_t hash_const_val(ZigValue *const_val) {5624static uint32_t hash_combine_const_val(uint32_t hash_val, ZigValue *const_val);
5625static uint32_t hash_combine_const_val_array(uint32_t hash_val, ZigValue *array, size_t len) {
5626 if (array->data.x_array.special == ConstArraySpecialUndef) {
5627 char undef_tag = 56;
5628 return hash_combine(hash_val, &undef_tag);
5629 } else if (array->data.x_array.special == ConstArraySpecialBuf) {
5630 // Hash in a way that is compatible with standard byte arrays
5631 // If any of these asserts fails, the if after this needs to be modified
5632 // to handle the new type in SpecialBuf.
5633 assert(array->type->data.array.child_type->id == ZigTypeIdInt);
5634 assert(array->type->data.array.child_type->data.integral.bit_count == 8);
5635 assert(array->type->data.array.child_type->data.integral.is_signed == false);
5636 const char *buf_pos = buf_ptr(array->data.x_array.data.s_buf);
5637 const char *buf_end = buf_pos + buf_len(array->data.x_array.data.s_buf);
5638 while (buf_pos < buf_end) {
5639 hash_val = hash_combine(hash_val, buf_pos);
5640 buf_pos++;
5641 }
5642 return hash_val;
5643 } else if (array->type->data.array.child_type->id == ZigTypeIdInt &&
5644 array->type->data.array.child_type->data.integral.bit_count == 8 &&
5645 array->type->data.array.child_type->data.integral.is_signed == false) {
5646 // If the type is u8, we hash it as if it's a ConstArraySpecialBuf,
5647 // to maintain compatibility.
5648 ZigValue *elems = array->data.x_array.data.s_none.elements;
5649 for (size_t i = 0; i < len; i += 1) {
5650 ZigValue *value = &elems[i];
5651 assert(value->type == array->type->data.array.child_type);
5652 // N.B. Using char here instead of uint8_t to match the const char*
5653 // returned by buf_ptr.
5654 const char byte_value = (char) bigint_as_u8(&value->data.x_bigint);
5655 hash_val = hash_combine(hash_val, &byte_value);
5656 }
5657 return hash_val;
5658 } else {
5659 ZigValue *elems = array->data.x_array.data.s_none.elements;
5660 for (size_t i = 0; i < len; i += 1) {
5661 hash_val = hash_combine_const_val(hash_val, &elems[i]);
5662 }
5663 return hash_val;
5664 }
5665}
5666static uint32_t hash_combine_const_val(uint32_t hash_val, ZigValue *const_val) {
5667 hash_val = hash_combine(hash_val, &const_val->special);
5668 if (const_val->special == ConstValSpecialUndef) {
5669 return hash_val;
5670 }
5634 assert(const_val->special == ConstValSpecialStatic);5671 assert(const_val->special == ConstValSpecialStatic);
5672 hash_val = hash_combine(hash_val, &const_val->type->id);
5635 switch (const_val->type->id) {5673 switch (const_val->type->id) {
5636 case ZigTypeIdOpaque:5674 case ZigTypeIdOpaque:
5637 zig_unreachable();5675 zig_unreachable();
5638 case ZigTypeIdBool:5676 case ZigTypeIdBool:
5639 return const_val->data.x_bool ? (uint32_t)127863866 : (uint32_t)215080464;5677 return hash_combine(hash_val, &const_val->data.x_bool);
5640 case ZigTypeIdMetaType:5678 case ZigTypeIdMetaType:
5641 return hash_ptr(const_val->data.x_type);5679 return hash_combine(hash_val, &const_val->data.x_type);
5642 case ZigTypeIdVoid:
5643 return (uint32_t)4149439618;
5644 case ZigTypeIdInt:5680 case ZigTypeIdInt:
5645 case ZigTypeIdComptimeInt:5681 case ZigTypeIdComptimeInt:
5646 {5682 return hash_combine_bigint(hash_val, &const_val->data.x_bigint);
5647 uint32_t result = 1331471175;
5648 for (size_t i = 0; i < const_val->data.x_bigint.digit_count; i += 1) {
5649 uint64_t digit = bigint_ptr(&const_val->data.x_bigint)[i];
5650 result ^= ((uint32_t)(digit >> 32)) ^ (uint32_t)(result);
5651 }
5652 return result;
5653 }
5654 case ZigTypeIdEnumLiteral:5683 case ZigTypeIdEnumLiteral:
5655 return buf_hash(const_val->data.x_enum_literal) * (uint32_t)2691276464;5684 return hash_combine_buf(hash_val, const_val->data.x_enum_literal);
5656 case ZigTypeIdEnum:5685 case ZigTypeIdEnum:
5657 {5686 return hash_combine_bigint(hash_val, &const_val->data.x_enum_tag);
5658 uint32_t result = 31643936;
5659 for (size_t i = 0; i < const_val->data.x_enum_tag.digit_count; i += 1) {
5660 uint64_t digit = bigint_ptr(&const_val->data.x_enum_tag)[i];
5661 result ^= ((uint32_t)(digit >> 32)) ^ (uint32_t)(result);
5662 }
5663 return result;
5664 }
5665 case ZigTypeIdFloat:5687 case ZigTypeIdFloat:
5688 hash_val = hash_combine(hash_val, &const_val->type->data.floating.bit_count);
5666 switch (const_val->type->data.floating.bit_count) {5689 switch (const_val->type->data.floating.bit_count) {
5667 case 16:5690 case 16: return hash_combine(hash_val, &const_val->data.x_f16);
5668 {5691 case 32: return hash_combine(hash_val, &const_val->data.x_f32);
5669 uint16_t result;5692 case 64: return hash_combine(hash_val, &const_val->data.x_f64);
5670 static_assert(sizeof(result) == sizeof(const_val->data.x_f16), "");5693 case 128: return hash_combine(hash_val, &const_val->data.x_f128);
5671 memcpy(&result, &const_val->data.x_f16, sizeof(result));5694 default: zig_unreachable();
5672 return result * 65537u;
5673 }
5674 case 32:
5675 {
5676 uint32_t result;
5677 memcpy(&result, &const_val->data.x_f32, 4);
5678 return result ^ 4084870010;
5679 }
5680 case 64:
5681 {
5682 uint32_t ints[2];
5683 memcpy(&ints[0], &const_val->data.x_f64, 8);
5684 return ints[0] ^ ints[1] ^ 0x22ed43c6;
5685 }
5686 case 128:
5687 {
5688 uint32_t ints[4];
5689 memcpy(&ints[0], &const_val->data.x_f128, 16);
5690 return ints[0] ^ ints[1] ^ ints[2] ^ ints[3] ^ 0xb5ffef27;
5691 }
5692 default:
5693 zig_unreachable();
5694 }5695 }
5695 case ZigTypeIdComptimeFloat:5696 case ZigTypeIdComptimeFloat:
5696 {5697 return hash_combine(hash_val, &const_val->data.x_bigfloat.value);
5697 float128_t f128 = bigfloat_to_f128(&const_val->data.x_bigfloat);
5698 uint32_t ints[4];
5699 memcpy(&ints[0], &f128, 16);
5700 return ints[0] ^ ints[1] ^ ints[2] ^ ints[3] ^ 0xed8b3dfb;
5701 }
5702 case ZigTypeIdFn:5698 case ZigTypeIdFn:
5703 assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst);5699 assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst);
5704 assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction);5700 assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction);
5705 return 3677364617 ^ hash_ptr(const_val->data.x_ptr.data.fn.fn_entry);5701 return hash_combine(hash_val, &const_val->data.x_ptr.data.fn.fn_entry);
5706 case ZigTypeIdPointer:5702 case ZigTypeIdPointer:
5707 return hash_const_val_ptr(const_val);5703 return hash_combine_const_val_ptr(hash_val, const_val);
5704 case ZigTypeIdVoid:
5708 case ZigTypeIdUndefined:5705 case ZigTypeIdUndefined:
5709 return 162837799;
5710 case ZigTypeIdNull:5706 case ZigTypeIdNull:
5711 return 844854567;5707 return hash_val;
5712 case ZigTypeIdArray:5708 case ZigTypeIdArray:
5713 // TODO better hashing algorithm5709 return hash_combine_const_val_array(hash_val, const_val, const_val->type->data.array.len);
5714 return 1166190605;5710 case ZigTypeIdStruct: {
5715 case ZigTypeIdStruct:5711 size_t field_count = const_val->type->data.structure.src_field_count;
5716 // TODO better hashing algorithm5712 for (size_t i = 0; i < field_count; i += 1) {
5717 return 1532530855;5713 if (const_val->type->data.structure.fields[i]->is_comptime) {
5718 case ZigTypeIdUnion:5714 // The values of comptime struct fields are part of the
5719 // TODO better hashing algorithm5715 // type, not the value, so they do not participate in equality
5720 return 2709806591;5716 // or hash of comptime values.
5717 continue;
5718 }
5719 ZigValue *field = const_val->data.x_struct.fields[i];
5720 hash_val = hash_combine_const_val(hash_val, field);
5721 }
5722 return hash_val;
5723 }
5724 case ZigTypeIdUnion: {
5725 ConstUnionValue *union_value = &const_val->data.x_union;
5726 hash_val = hash_combine_bigint(hash_val, &union_value->tag);
5727 return hash_combine_const_val(hash_val, union_value->payload);
5728 }
5721 case ZigTypeIdOptional:5729 case ZigTypeIdOptional:
5722 if (get_src_ptr_type(const_val->type) != nullptr) {5730 if (get_src_ptr_type(const_val->type) != nullptr) {
5723 return hash_const_val_ptr(const_val) * (uint32_t)1992916303;5731 char tag = 1;
5732 hash_val = hash_combine(hash_val, &tag);
5733 return hash_combine_const_val_ptr(hash_val, const_val);
5724 } else if (const_val->type->data.maybe.child_type->id == ZigTypeIdErrorSet) {5734 } else if (const_val->type->data.maybe.child_type->id == ZigTypeIdErrorSet) {
5725 return hash_const_val_error_set(const_val) * (uint32_t)3147031929;5735 char tag = 2;
5736 hash_val = hash_combine(hash_val, &tag);
5737 return hash_combine_const_val_error_set(hash_val, const_val);
5738 } else if (const_val->data.x_optional) {
5739 char tag = 3;
5740 hash_val = hash_combine(hash_val, &tag);
5741 return hash_combine_const_val(hash_val, const_val->data.x_optional);
5726 } else {5742 } else {
5727 if (const_val->data.x_optional) {5743 char tag = 4;
5728 return hash_const_val(const_val->data.x_optional) * (uint32_t)1992916303;5744 hash_val = hash_combine(hash_val, &tag);
5729 } else {5745 return hash_val;
5730 return 4016830364;
5731 }
5732 }5746 }
5733 case ZigTypeIdErrorUnion:5747 case ZigTypeIdErrorUnion: {
5734 // TODO better hashing algorithm5748 bool is_err = const_val->data.x_err_union.error_set->data.x_err_set != nullptr;
5735 return 3415065496;5749 hash_val = hash_combine(hash_val, &is_err);
5750 if (is_err) {
5751 hash_val = hash_combine_const_val(hash_val, const_val->data.x_err_union.error_set);
5752 } else {
5753 hash_val = hash_combine_const_val(hash_val, const_val->data.x_err_union.payload);
5754 }
5755 return hash_val;
5756 }
5736 case ZigTypeIdErrorSet:5757 case ZigTypeIdErrorSet:
5737 return hash_const_val_error_set(const_val);5758 return hash_combine_const_val_error_set(hash_val, const_val);
5738 case ZigTypeIdVector:5759 case ZigTypeIdVector:
5739 // TODO better hashing algorithm5760 return hash_combine_const_val_array(hash_val, const_val, const_val->type->data.vector.len);
5740 return 3647867726;
5741 case ZigTypeIdFnFrame:5761 case ZigTypeIdFnFrame:
5742 // TODO better hashing algorithm5762 // TODO better hashing algorithm
5743 return 675741936;5763 return hash_val;
5744 case ZigTypeIdAnyFrame:5764 case ZigTypeIdAnyFrame:
5745 // TODO better hashing algorithm5765 // TODO better hashing algorithm
5746 return 3747294894;5766 return hash_val;
5747 case ZigTypeIdBoundFn: {5767 case ZigTypeIdBoundFn: {
5748 assert(const_val->data.x_bound_fn.fn != nullptr);5768 assert(const_val->data.x_bound_fn.fn != nullptr);
5749 return 3677364617 ^ hash_ptr(const_val->data.x_bound_fn.fn);5769 return hash_combine(hash_val, &const_val->data.x_bound_fn.fn);
5750 }5770 }
5751 case ZigTypeIdInvalid:5771 case ZigTypeIdInvalid:
5752 case ZigTypeIdUnreachable:5772 case ZigTypeIdUnreachable:
...@@ -5756,13 +5776,13 @@ static uint32_t hash_const_val(ZigValue *const_val) {...@@ -5756,13 +5776,13 @@ static uint32_t hash_const_val(ZigValue *const_val) {
5756}5776}
57575777
5758uint32_t generic_fn_type_id_hash(GenericFnTypeId *id) {5778uint32_t generic_fn_type_id_hash(GenericFnTypeId *id) {
5759 uint32_t result = 0;5779 uint32_t result = HASH_INIT;
5760 result += hash_ptr(id->fn_entry);5780 result = hash_combine(result, &id->fn_entry);
5761 for (size_t i = 0; i < id->param_count; i += 1) {5781 for (size_t i = 0; i < id->param_count; i += 1) {
5762 ZigValue *generic_param = &id->params[i];5782 ZigValue *generic_param = &id->params[i];
5763 if (generic_param->special != ConstValSpecialRuntime) {5783 if (generic_param->special != ConstValSpecialRuntime) {
5764 result += hash_const_val(generic_param);5784 result = hash_combine_const_val(result, generic_param);
5765 result += hash_ptr(generic_param->type);5785 result = hash_combine(result, &generic_param->type);
5766 }5786 }
5767 }5787 }
5768 return result;5788 return result;
...@@ -5957,15 +5977,15 @@ bool fn_eval_cacheable(Scope *scope, ZigType *return_type) {...@@ -5957,15 +5977,15 @@ bool fn_eval_cacheable(Scope *scope, ZigType *return_type) {
5957}5977}
59585978
5959uint32_t fn_eval_hash(Scope* scope) {5979uint32_t fn_eval_hash(Scope* scope) {
5960 uint32_t result = 0;5980 uint32_t hash = HASH_INIT;
5961 while (scope) {5981 while (scope) {
5962 if (scope->id == ScopeIdVarDecl) {5982 if (scope->id == ScopeIdVarDecl) {
5963 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;5983 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
5964 result += hash_const_val(var_scope->var->const_value);5984 hash = hash_combine_const_val(hash, var_scope->var->const_value);
5965 } else if (scope->id == ScopeIdFnDef) {5985 } else if (scope->id == ScopeIdFnDef) {
5966 ScopeFnDef *fn_scope = (ScopeFnDef *)scope;5986 ScopeFnDef *fn_scope = (ScopeFnDef *)scope;
5967 result += hash_ptr(fn_scope->fn_entry);5987 hash = hash_combine(hash, &fn_scope->fn_entry);
5968 return result;5988 return hash;
5969 } else {5989 } else {
5970 zig_unreachable();5990 zig_unreachable();
5971 }5991 }
...@@ -6151,7 +6171,8 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {...@@ -6151,7 +6171,8 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
6151 for (size_t i = 0; i < field_count; i += 1) {6171 for (size_t i = 0; i < field_count; i += 1) {
6152 TypeStructField *field = struct_type->data.structure.fields[i];6172 TypeStructField *field = struct_type->data.structure.fields[i];
6153 if (field->is_comptime) {6173 if (field->is_comptime) {
6154 copy_const_val(g, result->data.x_struct.fields[i], field->init_val);6174 // Comptime fields are part of the type, and do not need to
6175 // be initialized.
6155 continue;6176 continue;
6156 }6177 }
6157 ZigType *field_type = resolve_struct_field_type(g, field);6178 ZigType *field_type = resolve_struct_field_type(g, field);
...@@ -7260,6 +7281,8 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) {...@@ -7260,6 +7281,8 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) {
7260 case ZigTypeIdMetaType:7281 case ZigTypeIdMetaType:
7261 return a->data.x_type == b->data.x_type;7282 return a->data.x_type == b->data.x_type;
7262 case ZigTypeIdVoid:7283 case ZigTypeIdVoid:
7284 case ZigTypeIdUndefined:
7285 case ZigTypeIdNull:
7263 return true;7286 return true;
7264 case ZigTypeIdErrorSet:7287 case ZigTypeIdErrorSet:
7265 return a->data.x_err_set->value == b->data.x_err_set->value;7288 return a->data.x_err_set->value == b->data.x_err_set->value;
...@@ -7292,12 +7315,17 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) {...@@ -7292,12 +7315,17 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) {
7292 case ZigTypeIdVector:7315 case ZigTypeIdVector:
7293 assert(a->type->data.vector.len == b->type->data.vector.len);7316 assert(a->type->data.vector.len == b->type->data.vector.len);
7294 return const_values_equal_array(g, a, b, a->type->data.vector.len);7317 return const_values_equal_array(g, a, b, a->type->data.vector.len);
7295 case ZigTypeIdArray: {7318 case ZigTypeIdArray:
7296 assert(a->type->data.array.len == b->type->data.array.len);7319 assert(a->type->data.array.len == b->type->data.array.len);
7297 return const_values_equal_array(g, a, b, a->type->data.array.len);7320 return const_values_equal_array(g, a, b, a->type->data.array.len);
7298 }
7299 case ZigTypeIdStruct:7321 case ZigTypeIdStruct:
7300 for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) {7322 for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) {
7323 if (a->type->data.structure.fields[i]->is_comptime) {
7324 // The values of comptime struct fields are part of the
7325 // type, not the value, so they do not participate in equality
7326 // or hash of comptime values.
7327 continue;
7328 }
7301 ZigValue *field_a = a->data.x_struct.fields[i];7329 ZigValue *field_a = a->data.x_struct.fields[i];
7302 ZigValue *field_b = b->data.x_struct.fields[i];7330 ZigValue *field_b = b->data.x_struct.fields[i];
7303 if (!const_values_equal(g, field_a, field_b))7331 if (!const_values_equal(g, field_a, field_b))
...@@ -7308,10 +7336,6 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) {...@@ -7308,10 +7336,6 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) {
7308 zig_panic("TODO: const_values_equal ZigTypeIdFnFrame");7336 zig_panic("TODO: const_values_equal ZigTypeIdFnFrame");
7309 case ZigTypeIdAnyFrame:7337 case ZigTypeIdAnyFrame:
7310 zig_panic("TODO: const_values_equal ZigTypeIdAnyFrame");7338 zig_panic("TODO: const_values_equal ZigTypeIdAnyFrame");
7311 case ZigTypeIdUndefined:
7312 zig_panic("TODO: const_values_equal ZigTypeIdUndefined");
7313 case ZigTypeIdNull:
7314 zig_panic("TODO: const_values_equal ZigTypeIdNull");
7315 case ZigTypeIdOptional:7339 case ZigTypeIdOptional:
7316 if (get_src_ptr_type(a->type) != nullptr)7340 if (get_src_ptr_type(a->type) != nullptr)
7317 return const_values_equal_ptr(a, b);7341 return const_values_equal_ptr(a, b);
...@@ -7718,8 +7742,9 @@ ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {...@@ -7718,8 +7742,9 @@ ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
7718 return entry;7742 return entry;
7719}7743}
77207744
7721uint32_t type_id_hash(TypeId x) {7745uint32_t type_id_hash(TypeId const *x) {
7722 switch (x.id) {7746 uint32_t hash = hash_combine(HASH_INIT, &x->id);
7747 switch (x->id) {
7723 case ZigTypeIdInvalid:7748 case ZigTypeIdInvalid:
7724 case ZigTypeIdOpaque:7749 case ZigTypeIdOpaque:
7725 case ZigTypeIdMetaType:7750 case ZigTypeIdMetaType:
...@@ -7743,35 +7768,50 @@ uint32_t type_id_hash(TypeId x) {...@@ -7743,35 +7768,50 @@ uint32_t type_id_hash(TypeId x) {
7743 case ZigTypeIdAnyFrame:7768 case ZigTypeIdAnyFrame:
7744 zig_unreachable();7769 zig_unreachable();
7745 case ZigTypeIdErrorUnion:7770 case ZigTypeIdErrorUnion:
7746 return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type);7771 hash = hash_combine(hash, &x->data.error_union.err_set_type);
7772 hash = hash_combine(hash, &x->data.error_union.payload_type);
7773 return hash;
7747 case ZigTypeIdPointer:7774 case ZigTypeIdPointer:
7748 return hash_ptr(x.data.pointer.child_type) +7775 hash = hash_combine(hash, &x->data.pointer.child_type);
7749 (uint32_t)x.data.pointer.ptr_len * 1120226602u +7776 hash = hash_combine(hash, &x->data.pointer.ptr_len);
7750 (x.data.pointer.is_const ? (uint32_t)2749109194 : (uint32_t)4047371087) +7777 hash = hash_combine(hash, &x->data.pointer.is_const);
7751 (x.data.pointer.is_volatile ? (uint32_t)536730450 : (uint32_t)1685612214) +7778 hash = hash_combine(hash, &x->data.pointer.is_volatile);
7752 (x.data.pointer.allow_zero ? (uint32_t)3324284834 : (uint32_t)3584904923) +7779 hash = hash_combine(hash, &x->data.pointer.allow_zero);
7753 (((uint32_t)x.data.pointer.alignment) ^ (uint32_t)0x777fbe0e) +7780 hash = hash_combine(hash, &x->data.pointer.alignment);
7754 (((uint32_t)x.data.pointer.bit_offset_in_host) ^ (uint32_t)2639019452) +7781 hash = hash_combine(hash, &x->data.pointer.bit_offset_in_host);
7755 (((uint32_t)x.data.pointer.vector_index) ^ (uint32_t)0x19199716) +7782 hash = hash_combine(hash, &x->data.pointer.vector_index);
7756 (((uint32_t)x.data.pointer.host_int_bytes) ^ (uint32_t)529908881) *7783 hash = hash_combine(hash, &x->data.pointer.host_int_bytes);
7757 (x.data.pointer.sentinel ? hash_const_val(x.data.pointer.sentinel) : (uint32_t)2955491856);7784 if (x->data.pointer.sentinel != nullptr) {
7785 hash = hash_combine_const_val(hash, x->data.pointer.sentinel);
7786 }
7787 if (x->data.pointer.inferred_struct_field) {
7788 hash = hash_combine(hash, &x->data.pointer.inferred_struct_field->inferred_struct_type);
7789 hash = hash_combine_buf(hash, x->data.pointer.inferred_struct_field->field_name);
7790 }
7791 return hash;
7758 case ZigTypeIdArray:7792 case ZigTypeIdArray:
7759 return hash_ptr(x.data.array.child_type) *7793 hash = hash_combine(hash, &x->data.array.child_type);
7760 ((uint32_t)x.data.array.size ^ (uint32_t)2122979968) *7794 hash = hash_combine(hash, &x->data.array.size);
7761 (x.data.array.sentinel ? hash_const_val(x.data.array.sentinel) : (uint32_t)1927201585);7795 if (x->data.array.sentinel != nullptr) {
7796 hash = hash_combine_const_val(hash, x->data.array.sentinel);
7797 }
7798 return hash;
7762 case ZigTypeIdInt:7799 case ZigTypeIdInt:
7763 return (x.data.integer.is_signed ? (uint32_t)2652528194 : (uint32_t)163929201) +7800 hash = hash_combine(hash, &x->data.integer.is_signed);
7764 (((uint32_t)x.data.integer.bit_count) ^ (uint32_t)2998081557);7801 hash = hash_combine(hash, &x->data.integer.bit_count);
7802 return hash;
7765 case ZigTypeIdVector:7803 case ZigTypeIdVector:
7766 return hash_ptr(x.data.vector.elem_type) * (x.data.vector.len * 526582681);7804 hash = hash_combine(hash, &x->data.vector.elem_type);
7805 hash = hash_combine(hash, &x->data.vector.len);
7806 return hash;
7767 }7807 }
7768 zig_unreachable();7808 zig_unreachable();
7769}7809}
77707810
7771bool type_id_eql(TypeId a, TypeId b) {7811bool type_id_eql(TypeId const *a, TypeId const *b) {
7772 if (a.id != b.id)7812 if (a->id != b->id)
7773 return false;7813 return false;
7774 switch (a.id) {7814 switch (a->id) {
7775 case ZigTypeIdInvalid:7815 case ZigTypeIdInvalid:
7776 case ZigTypeIdMetaType:7816 case ZigTypeIdMetaType:
7777 case ZigTypeIdVoid:7817 case ZigTypeIdVoid:
...@@ -7795,107 +7835,107 @@ bool type_id_eql(TypeId a, TypeId b) {...@@ -7795,107 +7835,107 @@ bool type_id_eql(TypeId a, TypeId b) {
7795 case ZigTypeIdAnyFrame:7835 case ZigTypeIdAnyFrame:
7796 zig_unreachable();7836 zig_unreachable();
7797 case ZigTypeIdErrorUnion:7837 case ZigTypeIdErrorUnion:
7798 return a.data.error_union.err_set_type == b.data.error_union.err_set_type &&7838 return a->data.error_union.err_set_type == b->data.error_union.err_set_type &&
7799 a.data.error_union.payload_type == b.data.error_union.payload_type;7839 a->data.error_union.payload_type == b->data.error_union.payload_type;
78007840
7801 case ZigTypeIdPointer:7841 case ZigTypeIdPointer:
7802 return a.data.pointer.child_type == b.data.pointer.child_type &&7842 return a->data.pointer.child_type == b->data.pointer.child_type &&
7803 a.data.pointer.ptr_len == b.data.pointer.ptr_len &&7843 a->data.pointer.ptr_len == b->data.pointer.ptr_len &&
7804 a.data.pointer.is_const == b.data.pointer.is_const &&7844 a->data.pointer.is_const == b->data.pointer.is_const &&
7805 a.data.pointer.is_volatile == b.data.pointer.is_volatile &&7845 a->data.pointer.is_volatile == b->data.pointer.is_volatile &&
7806 a.data.pointer.allow_zero == b.data.pointer.allow_zero &&7846 a->data.pointer.allow_zero == b->data.pointer.allow_zero &&
7807 a.data.pointer.alignment == b.data.pointer.alignment &&7847 a->data.pointer.alignment == b->data.pointer.alignment &&
7808 a.data.pointer.bit_offset_in_host == b.data.pointer.bit_offset_in_host &&7848 a->data.pointer.bit_offset_in_host == b->data.pointer.bit_offset_in_host &&
7809 a.data.pointer.vector_index == b.data.pointer.vector_index &&7849 a->data.pointer.vector_index == b->data.pointer.vector_index &&
7810 a.data.pointer.host_int_bytes == b.data.pointer.host_int_bytes &&7850 a->data.pointer.host_int_bytes == b->data.pointer.host_int_bytes &&
7811 (7851 (
7812 a.data.pointer.sentinel == b.data.pointer.sentinel ||7852 a->data.pointer.sentinel == b->data.pointer.sentinel ||
7813 (a.data.pointer.sentinel != nullptr && b.data.pointer.sentinel != nullptr &&7853 (a->data.pointer.sentinel != nullptr && b->data.pointer.sentinel != nullptr &&
7814 const_values_equal(a.data.pointer.codegen, a.data.pointer.sentinel, b.data.pointer.sentinel))7854 const_values_equal(a->data.pointer.codegen, a->data.pointer.sentinel, b->data.pointer.sentinel))
7815 ) &&7855 ) &&
7816 (7856 (
7817 a.data.pointer.inferred_struct_field == b.data.pointer.inferred_struct_field ||7857 a->data.pointer.inferred_struct_field == b->data.pointer.inferred_struct_field ||
7818 (a.data.pointer.inferred_struct_field != nullptr &&7858 (a->data.pointer.inferred_struct_field != nullptr &&
7819 b.data.pointer.inferred_struct_field != nullptr &&7859 b->data.pointer.inferred_struct_field != nullptr &&
7820 a.data.pointer.inferred_struct_field->inferred_struct_type ==7860 a->data.pointer.inferred_struct_field->inferred_struct_type ==
7821 b.data.pointer.inferred_struct_field->inferred_struct_type &&7861 b->data.pointer.inferred_struct_field->inferred_struct_type &&
7822 buf_eql_buf(a.data.pointer.inferred_struct_field->field_name,7862 buf_eql_buf(a->data.pointer.inferred_struct_field->field_name,
7823 b.data.pointer.inferred_struct_field->field_name))7863 b->data.pointer.inferred_struct_field->field_name))
7824 );7864 );
7825 case ZigTypeIdArray:7865 case ZigTypeIdArray:
7826 return a.data.array.child_type == b.data.array.child_type &&7866 return a->data.array.child_type == b->data.array.child_type &&
7827 a.data.array.size == b.data.array.size &&7867 a->data.array.size == b->data.array.size &&
7828 (7868 (
7829 a.data.array.sentinel == b.data.array.sentinel ||7869 a->data.array.sentinel == b->data.array.sentinel ||
7830 (a.data.array.sentinel != nullptr && b.data.array.sentinel != nullptr &&7870 (a->data.array.sentinel != nullptr && b->data.array.sentinel != nullptr &&
7831 const_values_equal(a.data.array.codegen, a.data.array.sentinel, b.data.array.sentinel))7871 const_values_equal(a->data.array.codegen, a->data.array.sentinel, b->data.array.sentinel))
7832 );7872 );
7833 case ZigTypeIdInt:7873 case ZigTypeIdInt:
7834 return a.data.integer.is_signed == b.data.integer.is_signed &&7874 return a->data.integer.is_signed == b->data.integer.is_signed &&
7835 a.data.integer.bit_count == b.data.integer.bit_count;7875 a->data.integer.bit_count == b->data.integer.bit_count;
7836 case ZigTypeIdVector:7876 case ZigTypeIdVector:
7837 return a.data.vector.elem_type == b.data.vector.elem_type &&7877 return a->data.vector.elem_type == b->data.vector.elem_type &&
7838 a.data.vector.len == b.data.vector.len;7878 a->data.vector.len == b->data.vector.len;
7839 }7879 }
7840 zig_unreachable();7880 zig_unreachable();
7841}7881}
78427882
7843uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) {7883uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey const *x) {
7844 switch (x.id) {7884 switch (x->id) {
7845 case ZigLLVMFnIdCtz:7885 case ZigLLVMFnIdCtz:
7846 return (uint32_t)(x.data.ctz.bit_count) * (uint32_t)810453934;7886 return (uint32_t)(x->data.ctz.bit_count) * (uint32_t)810453934;
7847 case ZigLLVMFnIdClz:7887 case ZigLLVMFnIdClz:
7848 return (uint32_t)(x.data.clz.bit_count) * (uint32_t)2428952817;7888 return (uint32_t)(x->data.clz.bit_count) * (uint32_t)2428952817;
7849 case ZigLLVMFnIdPopCount:7889 case ZigLLVMFnIdPopCount:
7850 return (uint32_t)(x.data.clz.bit_count) * (uint32_t)101195049;7890 return (uint32_t)(x->data.clz.bit_count) * (uint32_t)101195049;
7851 case ZigLLVMFnIdFloatOp:7891 case ZigLLVMFnIdFloatOp:
7852 return (uint32_t)(x.data.floating.bit_count) * ((uint32_t)x.id + 1025) +7892 return (uint32_t)(x->data.floating.bit_count) * ((uint32_t)x->id + 1025) +
7853 (uint32_t)(x.data.floating.vector_len) * (((uint32_t)x.id << 5) + 1025) +7893 (uint32_t)(x->data.floating.vector_len) * (((uint32_t)x->id << 5) + 1025) +
7854 (uint32_t)(x.data.floating.op) * (uint32_t)43789879;7894 (uint32_t)(x->data.floating.op) * (uint32_t)43789879;
7855 case ZigLLVMFnIdFMA:7895 case ZigLLVMFnIdFMA:
7856 return (uint32_t)(x.data.floating.bit_count) * ((uint32_t)x.id + 1025) +7896 return (uint32_t)(x->data.floating.bit_count) * ((uint32_t)x->id + 1025) +
7857 (uint32_t)(x.data.floating.vector_len) * (((uint32_t)x.id << 5) + 1025);7897 (uint32_t)(x->data.floating.vector_len) * (((uint32_t)x->id << 5) + 1025);
7858 case ZigLLVMFnIdBswap:7898 case ZigLLVMFnIdBswap:
7859 return (uint32_t)(x.data.bswap.bit_count) * ((uint32_t)3661994335) +7899 return (uint32_t)(x->data.bswap.bit_count) * ((uint32_t)3661994335) +
7860 (uint32_t)(x.data.bswap.vector_len) * (((uint32_t)x.id << 5) + 1025);7900 (uint32_t)(x->data.bswap.vector_len) * (((uint32_t)x->id << 5) + 1025);
7861 case ZigLLVMFnIdBitReverse:7901 case ZigLLVMFnIdBitReverse:
7862 return (uint32_t)(x.data.bit_reverse.bit_count) * (uint32_t)2621398431;7902 return (uint32_t)(x->data.bit_reverse.bit_count) * (uint32_t)2621398431;
7863 case ZigLLVMFnIdOverflowArithmetic:7903 case ZigLLVMFnIdOverflowArithmetic:
7864 return ((uint32_t)(x.data.overflow_arithmetic.bit_count) * 87135777) +7904 return ((uint32_t)(x->data.overflow_arithmetic.bit_count) * 87135777) +
7865 ((uint32_t)(x.data.overflow_arithmetic.add_sub_mul) * 31640542) +7905 ((uint32_t)(x->data.overflow_arithmetic.add_sub_mul) * 31640542) +
7866 ((uint32_t)(x.data.overflow_arithmetic.is_signed) ? 1062315172 : 314955820) +7906 ((uint32_t)(x->data.overflow_arithmetic.is_signed) ? 1062315172 : 314955820) +
7867 x.data.overflow_arithmetic.vector_len * 1435156945;7907 x->data.overflow_arithmetic.vector_len * 1435156945;
7868 }7908 }
7869 zig_unreachable();7909 zig_unreachable();
7870}7910}
78717911
7872bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {7912bool zig_llvm_fn_key_eql(ZigLLVMFnKey const *a, ZigLLVMFnKey const *b) {
7873 if (a.id != b.id)7913 if (a->id != b->id)
7874 return false;7914 return false;
7875 switch (a.id) {7915 switch (a->id) {
7876 case ZigLLVMFnIdCtz:7916 case ZigLLVMFnIdCtz:
7877 return a.data.ctz.bit_count == b.data.ctz.bit_count;7917 return a->data.ctz.bit_count == b->data.ctz.bit_count;
7878 case ZigLLVMFnIdClz:7918 case ZigLLVMFnIdClz:
7879 return a.data.clz.bit_count == b.data.clz.bit_count;7919 return a->data.clz.bit_count == b->data.clz.bit_count;
7880 case ZigLLVMFnIdPopCount:7920 case ZigLLVMFnIdPopCount:
7881 return a.data.pop_count.bit_count == b.data.pop_count.bit_count;7921 return a->data.pop_count.bit_count == b->data.pop_count.bit_count;
7882 case ZigLLVMFnIdBswap:7922 case ZigLLVMFnIdBswap:
7883 return a.data.bswap.bit_count == b.data.bswap.bit_count &&7923 return a->data.bswap.bit_count == b->data.bswap.bit_count &&
7884 a.data.bswap.vector_len == b.data.bswap.vector_len;7924 a->data.bswap.vector_len == b->data.bswap.vector_len;
7885 case ZigLLVMFnIdBitReverse:7925 case ZigLLVMFnIdBitReverse:
7886 return a.data.bit_reverse.bit_count == b.data.bit_reverse.bit_count;7926 return a->data.bit_reverse.bit_count == b->data.bit_reverse.bit_count;
7887 case ZigLLVMFnIdFloatOp:7927 case ZigLLVMFnIdFloatOp:
7888 return a.data.floating.bit_count == b.data.floating.bit_count &&7928 return a->data.floating.bit_count == b->data.floating.bit_count &&
7889 a.data.floating.vector_len == b.data.floating.vector_len &&7929 a->data.floating.vector_len == b->data.floating.vector_len &&
7890 a.data.floating.op == b.data.floating.op;7930 a->data.floating.op == b->data.floating.op;
7891 case ZigLLVMFnIdFMA:7931 case ZigLLVMFnIdFMA:
7892 return a.data.floating.bit_count == b.data.floating.bit_count &&7932 return a->data.floating.bit_count == b->data.floating.bit_count &&
7893 a.data.floating.vector_len == b.data.floating.vector_len;7933 a->data.floating.vector_len == b->data.floating.vector_len;
7894 case ZigLLVMFnIdOverflowArithmetic:7934 case ZigLLVMFnIdOverflowArithmetic:
7895 return (a.data.overflow_arithmetic.bit_count == b.data.overflow_arithmetic.bit_count) &&7935 return (a->data.overflow_arithmetic.bit_count == b->data.overflow_arithmetic.bit_count) &&
7896 (a.data.overflow_arithmetic.add_sub_mul == b.data.overflow_arithmetic.add_sub_mul) &&7936 (a->data.overflow_arithmetic.add_sub_mul == b->data.overflow_arithmetic.add_sub_mul) &&
7897 (a.data.overflow_arithmetic.is_signed == b.data.overflow_arithmetic.is_signed) &&7937 (a->data.overflow_arithmetic.is_signed == b->data.overflow_arithmetic.is_signed) &&
7898 (a.data.overflow_arithmetic.vector_len == b.data.overflow_arithmetic.vector_len);7938 (a->data.overflow_arithmetic.vector_len == b->data.overflow_arithmetic.vector_len);
7899 }7939 }
7900 zig_unreachable();7940 zig_unreachable();
7901}7941}
...@@ -7915,6 +7955,13 @@ static void init_const_undefined(CodeGen *g, ZigValue *const_val) {...@@ -7915,6 +7955,13 @@ static void init_const_undefined(CodeGen *g, ZigValue *const_val) {
7915 size_t field_count = wanted_type->data.structure.src_field_count;7955 size_t field_count = wanted_type->data.structure.src_field_count;
7916 const_val->data.x_struct.fields = alloc_const_vals_ptrs(g, field_count);7956 const_val->data.x_struct.fields = alloc_const_vals_ptrs(g, field_count);
7917 for (size_t i = 0; i < field_count; i += 1) {7957 for (size_t i = 0; i < field_count; i += 1) {
7958 TypeStructField *field = wanted_type->data.structure.fields[i];
7959 if (field->is_comptime) {
7960 // Comptime fields are part of the type, and do not need to
7961 // be initialized.
7962 continue;
7963 }
7964
7918 ZigValue *field_val = const_val->data.x_struct.fields[i];7965 ZigValue *field_val = const_val->data.x_struct.fields[i];
7919 field_val->type = resolve_struct_field_type(g, wanted_type->data.structure.fields[i]);7966 field_val->type = resolve_struct_field_type(g, wanted_type->data.structure.fields[i]);
7920 assert(field_val->type);7967 assert(field_val->type);
...@@ -8155,7 +8202,7 @@ ZigType *get_align_amt_type(CodeGen *g) {...@@ -8155,7 +8202,7 @@ ZigType *get_align_amt_type(CodeGen *g) {
8155}8202}
81568203
8157uint32_t type_ptr_hash(const ZigType *ptr) {8204uint32_t type_ptr_hash(const ZigType *ptr) {
8158 return hash_ptr((void*)ptr);8205 return hash_combine(HASH_INIT, &ptr);
8159}8206}
81608207
8161bool type_ptr_eql(const ZigType *a, const ZigType *b) {8208bool type_ptr_eql(const ZigType *a, const ZigType *b) {
...@@ -8163,7 +8210,7 @@ bool type_ptr_eql(const ZigType *a, const ZigType *b) {...@@ -8163,7 +8210,7 @@ bool type_ptr_eql(const ZigType *a, const ZigType *b) {
8163}8210}
81648211
8165uint32_t pkg_ptr_hash(const ZigPackage *ptr) {8212uint32_t pkg_ptr_hash(const ZigPackage *ptr) {
8166 return hash_ptr((void*)ptr);8213 return hash_combine(HASH_INIT, &ptr);
8167}8214}
81688215
8169bool pkg_ptr_eql(const ZigPackage *a, const ZigPackage *b) {8216bool pkg_ptr_eql(const ZigPackage *a, const ZigPackage *b) {
...@@ -8171,7 +8218,7 @@ bool pkg_ptr_eql(const ZigPackage *a, const ZigPackage *b) {...@@ -8171,7 +8218,7 @@ bool pkg_ptr_eql(const ZigPackage *a, const ZigPackage *b) {
8171}8218}
81728219
8173uint32_t tld_ptr_hash(const Tld *ptr) {8220uint32_t tld_ptr_hash(const Tld *ptr) {
8174 return hash_ptr((void*)ptr);8221 return hash_combine(HASH_INIT, &ptr);
8175}8222}
81768223
8177bool tld_ptr_eql(const Tld *a, const Tld *b) {8224bool tld_ptr_eql(const Tld *a, const Tld *b) {
...@@ -8179,7 +8226,7 @@ bool tld_ptr_eql(const Tld *a, const Tld *b) {...@@ -8179,7 +8226,7 @@ bool tld_ptr_eql(const Tld *a, const Tld *b) {
8179}8226}
81808227
8181uint32_t node_ptr_hash(const AstNode *ptr) {8228uint32_t node_ptr_hash(const AstNode *ptr) {
8182 return hash_ptr((void*)ptr);8229 return hash_combine(HASH_INIT, &ptr);
8183}8230}
81848231
8185bool node_ptr_eql(const AstNode *a, const AstNode *b) {8232bool node_ptr_eql(const AstNode *a, const AstNode *b) {
...@@ -8187,7 +8234,7 @@ bool node_ptr_eql(const AstNode *a, const AstNode *b) {...@@ -8187,7 +8234,7 @@ bool node_ptr_eql(const AstNode *a, const AstNode *b) {
8187}8234}
81888235
8189uint32_t fn_ptr_hash(const ZigFn *ptr) {8236uint32_t fn_ptr_hash(const ZigFn *ptr) {
8190 return hash_ptr((void*)ptr);8237 return hash_combine(HASH_INIT, &ptr);
8191}8238}
81928239
8193bool fn_ptr_eql(const ZigFn *a, const ZigFn *b) {8240bool fn_ptr_eql(const ZigFn *a, const ZigFn *b) {
...@@ -8195,7 +8242,7 @@ bool fn_ptr_eql(const ZigFn *a, const ZigFn *b) {...@@ -8195,7 +8242,7 @@ bool fn_ptr_eql(const ZigFn *a, const ZigFn *b) {
8195}8242}
81968243
8197uint32_t err_ptr_hash(const ErrorTableEntry *ptr) {8244uint32_t err_ptr_hash(const ErrorTableEntry *ptr) {
8198 return hash_ptr((void*)ptr);8245 return hash_combine(HASH_INIT, &ptr);
8199}8246}
82008247
8201bool err_ptr_eql(const ErrorTableEntry *a, const ErrorTableEntry *b) {8248bool err_ptr_eql(const ErrorTableEntry *a, const ErrorTableEntry *b) {
...@@ -9914,10 +9961,13 @@ void copy_const_val(CodeGen *g, ZigValue *dest, ZigValue *src) {...@@ -9914,10 +9961,13 @@ void copy_const_val(CodeGen *g, ZigValue *dest, ZigValue *src) {
9914 dest->data.x_struct.fields = alloc_const_vals_ptrs(g, dest->type->data.structure.src_field_count);9961 dest->data.x_struct.fields = alloc_const_vals_ptrs(g, dest->type->data.structure.src_field_count);
9915 for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) {9962 for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) {
9916 TypeStructField *type_struct_field = dest->type->data.structure.fields[i];9963 TypeStructField *type_struct_field = dest->type->data.structure.fields[i];
9917 // comptime-known values are stored in the field init_val inside9964 if (type_struct_field->is_comptime) {
9918 // the struct type.9965 // comptime-known values are stored in the field init_val inside
9919 if (type_struct_field->is_comptime)9966 // the struct type. The data stored here is not supposed to be read
9967 // at all; the code should look at the type system and notice the field
9968 // is comptime and look at the type to learn the value.
9920 continue;9969 continue;
9970 }
9921 copy_const_val(g, dest->data.x_struct.fields[i], src->data.x_struct.fields[i]);9971 copy_const_val(g, dest->data.x_struct.fields[i], src->data.x_struct.fields[i]);
9922 dest->data.x_struct.fields[i]->parent.id = ConstParentIdStruct;9972 dest->data.x_struct.fields[i]->parent.id = ConstParentIdStruct;
9923 dest->data.x_struct.fields[i]->parent.data.p_struct.struct_val = dest;9973 dest->data.x_struct.fields[i]->parent.data.p_struct.struct_val = dest;
...@@ -10128,8 +10178,11 @@ static void dump_value_indent(ZigValue *val, int indent) {...@@ -10128,8 +10178,11 @@ static void dump_value_indent(ZigValue *val, int indent) {
10128 for (int j = 0; j < indent; j += 1) {10178 for (int j = 0; j < indent; j += 1) {
10129 fprintf(stderr, " ");10179 fprintf(stderr, " ");
10130 }10180 }
10131 fprintf(stderr, "%s: ", buf_ptr(val->type->data.structure.fields[i]->name));10181 TypeStructField *field = val->type->data.structure.fields[i];
10132 if (val->data.x_struct.fields == nullptr) {10182 fprintf(stderr, "%s: ", buf_ptr(field->name));
10183 if (field->is_comptime) {
10184 fprintf(stderr, "<comptime field>");
10185 } else if (val->data.x_struct.fields == nullptr) {
10133 fprintf(stderr, "<null>\n");10186 fprintf(stderr, "<null>\n");
10134 } else {10187 } else {
10135 dump_value_indent(val->data.x_struct.fields[i], 1);10188 dump_value_indent(val->data.x_struct.fields[i], 1);
src/stage1/bigint.cpp+12-5
...@@ -1694,6 +1694,13 @@ uint32_t bigint_as_u32(const BigInt *bigint) {...@@ -1694,6 +1694,13 @@ uint32_t bigint_as_u32(const BigInt *bigint) {
1694 return value32;1694 return value32;
1695}1695}
16961696
1697uint8_t bigint_as_u8(const BigInt *bigint) {
1698 uint64_t value64 = bigint_as_unsigned(bigint);
1699 uint8_t value8 = (uint8_t)value64;
1700 assert (value64 == value8);
1701 return value8;
1702}
1703
1697size_t bigint_as_usize(const BigInt *bigint) {1704size_t bigint_as_usize(const BigInt *bigint) {
1698 uint64_t value64 = bigint_as_unsigned(bigint);1705 uint64_t value64 = bigint_as_unsigned(bigint);
1699 size_t valueUsize = (size_t)value64;1706 size_t valueUsize = (size_t)value64;
...@@ -1726,16 +1733,16 @@ Cmp bigint_cmp_zero(const BigInt *op) {...@@ -1726,16 +1733,16 @@ Cmp bigint_cmp_zero(const BigInt *op) {
1726 return op->is_negative ? CmpLT : CmpGT;1733 return op->is_negative ? CmpLT : CmpGT;
1727}1734}
17281735
1729uint32_t bigint_hash(BigInt x) {1736uint32_t bigint_hash(BigInt const *x) {
1730 if (x.digit_count == 0) {1737 if (x->digit_count == 0) {
1731 return 0;1738 return 0;
1732 } else {1739 } else {
1733 return bigint_ptr(&x)[0];1740 return bigint_ptr(x)[0];
1734 }1741 }
1735}1742}
17361743
1737bool bigint_eql(BigInt a, BigInt b) {1744bool bigint_eql(BigInt const *a, BigInt const *b) {
1738 return bigint_cmp(&a, &b) == CmpEQ;1745 return bigint_cmp(a, b) == CmpEQ;
1739}1746}
17401747
1741void bigint_incr(BigInt *x) {1748void bigint_incr(BigInt *x) {
src/stage1/bigint.hpp+3-2
...@@ -39,6 +39,7 @@ void bigint_deinit(BigInt *bi);...@@ -39,6 +39,7 @@ void bigint_deinit(BigInt *bi);
39// panics if number won't fit39// panics if number won't fit
40uint64_t bigint_as_u64(const BigInt *bigint);40uint64_t bigint_as_u64(const BigInt *bigint);
41uint32_t bigint_as_u32(const BigInt *bigint);41uint32_t bigint_as_u32(const BigInt *bigint);
42uint8_t bigint_as_u8(const BigInt *bigint);
42size_t bigint_as_usize(const BigInt *bigint);43size_t bigint_as_usize(const BigInt *bigint);
4344
44int64_t bigint_as_signed(const BigInt *bigint);45int64_t bigint_as_signed(const BigInt *bigint);
...@@ -99,7 +100,7 @@ void bigint_decr(BigInt *value);...@@ -99,7 +100,7 @@ void bigint_decr(BigInt *value);
99100
100bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result);101bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result);
101102
102uint32_t bigint_hash(BigInt x);103uint32_t bigint_hash(BigInt const *x);
103bool bigint_eql(BigInt a, BigInt b);104bool bigint_eql(BigInt const *a, BigInt const *b);
104105
105#endif106#endif
src/stage1/buffer.hpp+1-1
...@@ -26,7 +26,7 @@ Buf *buf_sprintf(const char *format, ...)...@@ -26,7 +26,7 @@ Buf *buf_sprintf(const char *format, ...)
26 ATTRIBUTE_PRINTF(1, 2);26 ATTRIBUTE_PRINTF(1, 2);
27Buf *buf_vprintf(const char *format, va_list ap);27Buf *buf_vprintf(const char *format, va_list ap);
2828
29static inline size_t buf_len(Buf *buf) {29static inline size_t buf_len(const Buf *buf) {
30 assert(buf);30 assert(buf);
31 assert(buf->list.length);31 assert(buf->list.length);
32 return buf->list.length - 1;32 return buf->list.length - 1;
src/stage1/codegen.cpp+9-3
...@@ -3778,6 +3778,12 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val) {...@@ -3778,6 +3778,12 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val) {
3778 case ConstValSpecialStatic:3778 case ConstValSpecialStatic:
3779 if (const_val->type->id == ZigTypeIdStruct) {3779 if (const_val->type->id == ZigTypeIdStruct) {
3780 for (size_t i = 0; i < const_val->type->data.structure.src_field_count; i += 1) {3780 for (size_t i = 0; i < const_val->type->data.structure.src_field_count; i += 1) {
3781 TypeStructField *field = const_val->type->data.structure.fields[i];
3782 if (field->is_comptime) {
3783 // Comptime fields are part of the type, may be uninitialized,
3784 // and should not be inspected.
3785 continue;
3786 }
3781 if (!value_is_all_undef(g, const_val->data.x_struct.fields[i]))3787 if (!value_is_all_undef(g, const_val->data.x_struct.fields[i]))
3782 return false;3788 return false;
3783 }3789 }
...@@ -7285,7 +7291,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Zig...@@ -7285,7 +7291,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Zig
7285 size_t used_bits = 0;7291 size_t used_bits = 0;
7286 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {7292 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
7287 TypeStructField *field = type_entry->data.structure.fields[i];7293 TypeStructField *field = type_entry->data.structure.fields[i];
7288 if (field->gen_index == SIZE_MAX) {7294 if (field->gen_index == SIZE_MAX || field->is_comptime) {
7289 continue;7295 continue;
7290 }7296 }
7291 LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, const_val->data.x_struct.fields[i]);7297 LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, const_val->data.x_struct.fields[i]);
...@@ -7573,7 +7579,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n...@@ -7573,7 +7579,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n
7573 size_t src_field_index = 0;7579 size_t src_field_index = 0;
7574 while (src_field_index < src_field_count) {7580 while (src_field_index < src_field_count) {
7575 TypeStructField *type_struct_field = type_entry->data.structure.fields[src_field_index];7581 TypeStructField *type_struct_field = type_entry->data.structure.fields[src_field_index];
7576 if (type_struct_field->gen_index == SIZE_MAX) {7582 if (type_struct_field->gen_index == SIZE_MAX || type_struct_field->is_comptime) {
7577 src_field_index += 1;7583 src_field_index += 1;
7578 continue;7584 continue;
7579 }7585 }
...@@ -7642,7 +7648,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n...@@ -7642,7 +7648,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n
7642 } else {7648 } else {
7643 for (uint32_t i = 0; i < src_field_count; i += 1) {7649 for (uint32_t i = 0; i < src_field_count; i += 1) {
7644 TypeStructField *type_struct_field = type_entry->data.structure.fields[i];7650 TypeStructField *type_struct_field = type_entry->data.structure.fields[i];
7645 if (type_struct_field->gen_index == SIZE_MAX) {7651 if (type_struct_field->gen_index == SIZE_MAX || type_struct_field->is_comptime) {
7646 continue;7652 continue;
7647 }7653 }
7648 ZigValue *field_val = const_val->data.x_struct.fields[i];7654 ZigValue *field_val = const_val->data.x_struct.fields[i];
src/stage1/hash_map.hpp+38-12
...@@ -12,7 +12,33 @@...@@ -12,7 +12,33 @@
1212
13#include <stdint.h>13#include <stdint.h>
1414
15template<typename K, typename V, uint32_t (*HashFunction)(K key), bool (*EqualFn)(K a, K b)>15template<typename K>
16struct MakePointer {
17 typedef K const *Type;
18 static Type convert(K const &val) {
19 return &val;
20 }
21};
22
23template<typename K>
24struct MakePointer<K*> {
25 typedef K *Type;
26 static Type convert(K * const &val) {
27 return val;
28 }
29};
30
31template<typename K>
32struct MakePointer<K const *> {
33 typedef K const *Type;
34 static Type convert(K const * const &val) {
35 return val;
36 }
37};
38
39template<typename K, typename V,
40 uint32_t (*HashFunction)(typename MakePointer<K>::Type key),
41 bool (*EqualFn)(typename MakePointer<K>::Type a, typename MakePointer<K>::Type b)>
16class HashMap {42class HashMap {
17public:43public:
18 void init(int capacity) {44 void init(int capacity) {
...@@ -51,7 +77,7 @@ public:...@@ -51,7 +77,7 @@ public:
5177
52 if (_index_bytes == nullptr) {78 if (_index_bytes == nullptr) {
53 if (_entries.length < 16) {79 if (_entries.length < 16) {
54 _entries.append({HashFunction(key), 0, key, value});80 _entries.append({HashFunction(MakePointer<K>::convert(key)), 0, key, value});
55 return;81 return;
56 } else {82 } else {
57 _indexes_len = 32;83 _indexes_len = 32;
...@@ -131,9 +157,9 @@ public:...@@ -131,9 +157,9 @@ public:
131 bool maybe_remove(const K &key) {157 bool maybe_remove(const K &key) {
132 _modification_count += 1;158 _modification_count += 1;
133 if (_index_bytes == nullptr) {159 if (_index_bytes == nullptr) {
134 uint32_t hash = HashFunction(key);160 uint32_t hash = HashFunction(MakePointer<K>::convert(key));
135 for (size_t i = 0; i < _entries.length; i += 1) {161 for (size_t i = 0; i < _entries.length; i += 1) {
136 if (_entries.items[i].hash == hash && EqualFn(_entries.items[i].key, key)) {162 if (_entries.items[i].hash == hash && EqualFn(MakePointer<K>::convert(_entries.items[i].key), MakePointer<K>::convert(key))) {
137 _entries.swap_remove(i);163 _entries.swap_remove(i);
138 return true;164 return true;
139 }165 }
...@@ -223,7 +249,7 @@ private:...@@ -223,7 +249,7 @@ private:
223249
224 template <typename I>250 template <typename I>
225 void internal_put(const K &key, const V &value, I *indexes) {251 void internal_put(const K &key, const V &value, I *indexes) {
226 uint32_t hash = HashFunction(key);252 uint32_t hash = HashFunction(MakePointer<K>::convert(key));
227 uint32_t distance_from_start_index = 0;253 uint32_t distance_from_start_index = 0;
228 size_t start_index = hash_to_index(hash);254 size_t start_index = hash_to_index(hash);
229 for (size_t roll_over = 0; roll_over < _indexes_len;255 for (size_t roll_over = 0; roll_over < _indexes_len;
...@@ -241,7 +267,7 @@ private:...@@ -241,7 +267,7 @@ private:
241 // This pointer survives the following append because we call267 // This pointer survives the following append because we call
242 // _entries.ensure_capacity before internal_put.268 // _entries.ensure_capacity before internal_put.
243 Entry *entry = &_entries.items[index_data - 1];269 Entry *entry = &_entries.items[index_data - 1];
244 if (entry->hash == hash && EqualFn(entry->key, key)) {270 if (entry->hash == hash && EqualFn(MakePointer<K>::convert(entry->key), MakePointer<K>::convert(key))) {
245 *entry = {hash, distance_from_start_index, key, value};271 *entry = {hash, distance_from_start_index, key, value};
246 if (distance_from_start_index > _max_distance_from_start_index)272 if (distance_from_start_index > _max_distance_from_start_index)
247 _max_distance_from_start_index = distance_from_start_index;273 _max_distance_from_start_index = distance_from_start_index;
...@@ -322,9 +348,9 @@ private:...@@ -322,9 +348,9 @@ private:
322348
323 Entry *internal_get(const K &key) const {349 Entry *internal_get(const K &key) const {
324 if (_index_bytes == nullptr) {350 if (_index_bytes == nullptr) {
325 uint32_t hash = HashFunction(key);351 uint32_t hash = HashFunction(MakePointer<K>::convert(key));
326 for (size_t i = 0; i < _entries.length; i += 1) {352 for (size_t i = 0; i < _entries.length; i += 1) {
327 if (_entries.items[i].hash == hash && EqualFn(_entries.items[i].key, key)) {353 if (_entries.items[i].hash == hash && EqualFn(MakePointer<K>::convert(_entries.items[i].key), MakePointer<K>::convert(key))) {
328 return &_entries.items[i];354 return &_entries.items[i];
329 }355 }
330 }356 }
...@@ -340,7 +366,7 @@ private:...@@ -340,7 +366,7 @@ private:
340366
341 template <typename I>367 template <typename I>
342 Entry *internal_get2(const K &key, I *indexes) const {368 Entry *internal_get2(const K &key, I *indexes) const {
343 uint32_t hash = HashFunction(key);369 uint32_t hash = HashFunction(MakePointer<K>::convert(key));
344 size_t start_index = hash_to_index(hash);370 size_t start_index = hash_to_index(hash);
345 for (size_t roll_over = 0; roll_over <= _max_distance_from_start_index; roll_over += 1) {371 for (size_t roll_over = 0; roll_over <= _max_distance_from_start_index; roll_over += 1) {
346 size_t index_index = (start_index + roll_over) % _indexes_len;372 size_t index_index = (start_index + roll_over) % _indexes_len;
...@@ -349,7 +375,7 @@ private:...@@ -349,7 +375,7 @@ private:
349 return nullptr;375 return nullptr;
350376
351 Entry *entry = &_entries.items[index_data - 1];377 Entry *entry = &_entries.items[index_data - 1];
352 if (entry->hash == hash && EqualFn(entry->key, key))378 if (entry->hash == hash && EqualFn(MakePointer<K>::convert(entry->key), MakePointer<K>::convert(key)))
353 return entry;379 return entry;
354 }380 }
355 return nullptr;381 return nullptr;
...@@ -361,7 +387,7 @@ private:...@@ -361,7 +387,7 @@ private:
361387
362 template <typename I>388 template <typename I>
363 bool internal_remove(const K &key, I *indexes) {389 bool internal_remove(const K &key, I *indexes) {
364 uint32_t hash = HashFunction(key);390 uint32_t hash = HashFunction(MakePointer<K>::convert(key));
365 size_t start_index = hash_to_index(hash);391 size_t start_index = hash_to_index(hash);
366 for (size_t roll_over = 0; roll_over <= _max_distance_from_start_index; roll_over += 1) {392 for (size_t roll_over = 0; roll_over <= _max_distance_from_start_index; roll_over += 1) {
367 size_t index_index = (start_index + roll_over) % _indexes_len;393 size_t index_index = (start_index + roll_over) % _indexes_len;
...@@ -371,7 +397,7 @@ private:...@@ -371,7 +397,7 @@ private:
371397
372 size_t index = index_data - 1;398 size_t index = index_data - 1;
373 Entry *entry = &_entries.items[index];399 Entry *entry = &_entries.items[index];
374 if (entry->hash != hash || !EqualFn(entry->key, key))400 if (entry->hash != hash || !EqualFn(MakePointer<K>::convert(entry->key), MakePointer<K>::convert(key)))
375 continue;401 continue;
376402
377 size_t prev_index = index_index;403 size_t prev_index = index_index;
src/stage1/ir.cpp+164-4
...@@ -272,6 +272,10 @@ static bool value_cmp_numeric_val_all(ZigValue *left, Cmp predicate, ZigValue *r...@@ -272,6 +272,10 @@ static bool value_cmp_numeric_val_all(ZigValue *left, Cmp predicate, ZigValue *r
272static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field);272static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field);
273static void value_to_bigfloat(BigFloat *out, ZigValue *val);273static void value_to_bigfloat(BigFloat *out, ZigValue *val);
274274
275static Error ir_resolve_lazy_recurse(AstNode *source_node, ZigValue *val);
276static Error ir_resolve_lazy_recurse_array(AstNode *source_node, ZigValue *val, size_t len);
277
278
275static void ir_assert_impl(bool ok, IrInstGen *source_instruction, char const *file, unsigned int line) {279static void ir_assert_impl(bool ok, IrInstGen *source_instruction, char const *file, unsigned int line) {
276 if (ok) return;280 if (ok) return;
277 src_assert_impl(ok, source_instruction->source_node, file, line);281 src_assert_impl(ok, source_instruction->source_node, file, line);
...@@ -554,7 +558,10 @@ static ZigValue *const_ptr_pointee_unchecked_no_isf(CodeGen *g, ZigValue *const_...@@ -554,7 +558,10 @@ static ZigValue *const_ptr_pointee_unchecked_no_isf(CodeGen *g, ZigValue *const_
554 case ConstPtrSpecialBaseStruct: {558 case ConstPtrSpecialBaseStruct: {
555 ZigValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val;559 ZigValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val;
556 expand_undef_struct(g, struct_val);560 expand_undef_struct(g, struct_val);
557 result = struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index];561 size_t field_index = const_val->data.x_ptr.data.base_struct.field_index;
562 assert(struct_val->type->id == ZigTypeIdStruct);
563 assert(!struct_val->type->data.structure.fields[field_index]->is_comptime);
564 result = struct_val->data.x_struct.fields[field_index];
558 break;565 break;
559 }566 }
560 case ConstPtrSpecialBaseErrorUnionCode:567 case ConstPtrSpecialBaseErrorUnionCode:
...@@ -7018,6 +7025,17 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, Scope *sco...@@ -7018,6 +7025,17 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, Scope *sco
7018 buf_sprintf("field '%s' declared here", buf_ptr(src_field->name)));7025 buf_sprintf("field '%s' declared here", buf_ptr(src_field->name)));
7019 return ira->codegen->invalid_inst_gen;7026 return ira->codegen->invalid_inst_gen;
7020 }7027 }
7028 if (dst_field->is_comptime) {
7029 ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("field '%s' in struct '%s' is comptime, it cannot be assigned",
7030 buf_ptr(src_field->name), buf_ptr(&wanted_type->name)));
7031 if (wanted_type->data.structure.decl_node) {
7032 add_error_note(ira->codegen, msg, wanted_type->data.structure.decl_node,
7033 buf_sprintf("struct '%s' declared here", buf_ptr(&wanted_type->name)));
7034 }
7035 add_error_note(ira->codegen, msg, src_field->decl_node,
7036 buf_sprintf("field '%s' declared here", buf_ptr(src_field->name)));
7037 return ira->codegen->invalid_inst_gen;
7038 }
70217039
7022 src_assert(src_field->decl_node != nullptr, source_node);7040 src_assert(src_field->decl_node != nullptr, source_node);
7023 AstNode *existing_assign_node = field_assign_nodes[dst_field->src_index];7041 AstNode *existing_assign_node = field_assign_nodes[dst_field->src_index];
...@@ -7062,6 +7080,7 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, Scope *sco...@@ -7062,6 +7080,7 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, Scope *sco
70627080
7063 // look for a default field value7081 // look for a default field value
7064 TypeStructField *field = wanted_type->data.structure.fields[i];7082 TypeStructField *field = wanted_type->data.structure.fields[i];
7083 assert(!field->is_comptime); // field_assign_nodes[i] should be null for comptime fields
7065 memoize_field_init_val(ira->codegen, wanted_type, field);7084 memoize_field_init_val(ira->codegen, wanted_type, field);
7066 if (field->init_val == nullptr) {7085 if (field->init_val == nullptr) {
7067 ir_add_error_node(ira, source_node,7086 ir_add_error_node(ira, source_node,
...@@ -7097,6 +7116,9 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, Scope *sco...@@ -7097,6 +7116,9 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, Scope *sco
70977116
7098 for (size_t i = 0; i < actual_field_count; i += 1) {7117 for (size_t i = 0; i < actual_field_count; i += 1) {
7099 TypeStructField *field = wanted_type->data.structure.fields[i];7118 TypeStructField *field = wanted_type->data.structure.fields[i];
7119 if (field->is_comptime)
7120 continue;
7121
7100 IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, scope, source_node, field, result_loc_inst, wanted_type, true);7122 IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, scope, source_node, field, result_loc_inst, wanted_type, true);
7101 if (type_is_invalid(field_ptr->value->type))7123 if (type_is_invalid(field_ptr->value->type))
7102 return ira->codegen->invalid_inst_gen;7124 return ira->codegen->invalid_inst_gen;
...@@ -12750,6 +12772,29 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, Scope *scope, AstNode *sour...@@ -12750,6 +12772,29 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, Scope *scope, AstNode *sour
12750 bool cacheable = fn_eval_cacheable(exec_scope, return_type);12772 bool cacheable = fn_eval_cacheable(exec_scope, return_type);
12751 ZigValue *result = nullptr;12773 ZigValue *result = nullptr;
12752 if (cacheable) {12774 if (cacheable) {
12775 // We are about to put ZigValues into a hash map. The hash of a lazy value and a
12776 // fully resolved value must equal, and so we must resolve the lazy values here.
12777 // The hash function asserts that none of the values are lazy.
12778 {
12779 Scope *scope = exec_scope;
12780 while (scope) {
12781 if (scope->id == ScopeIdVarDecl) {
12782 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
12783 if ((err = ir_resolve_lazy_recurse(
12784 var_scope->var->decl_node,
12785 var_scope->var->const_value)))
12786 {
12787 return ira->codegen->invalid_inst_gen;
12788 }
12789 } else if (scope->id == ScopeIdFnDef) {
12790 break;
12791 } else {
12792 zig_unreachable();
12793 }
12794 scope = scope->parent;
12795 }
12796 }
12797
12753 auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope);12798 auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope);
12754 if (entry)12799 if (entry)
12755 result = entry->value;12800 result = entry->value;
...@@ -12935,6 +12980,18 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, Scope *scope, AstNode *sour...@@ -12935,6 +12980,18 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, Scope *scope, AstNode *sour
12935 break;12980 break;
12936 }12981 }
1293712982
12983 // We are about to put ZigValues into a hash map. The hash of a lazy value and a
12984 // fully resolved value must equal, and so we must resolve the lazy values here.
12985 // The hash function asserts that none of the values are lazy.
12986 for (size_t i = 0; i < generic_id->param_count; i += 1) {
12987 ZigValue *generic_param = &generic_id->params[i];
12988 if (generic_param->special != ConstValSpecialRuntime) {
12989 if ((err = ir_resolve_lazy_recurse(source_node, generic_param))) {
12990 return ira->codegen->invalid_inst_gen;
12991 }
12992 }
12993 }
12994
12938 auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn);12995 auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn);
12939 if (existing_entry) {12996 if (existing_entry) {
12940 // throw away all our work and use the existing function12997 // throw away all our work and use the existing function
...@@ -14873,6 +14930,8 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, Scope *scope, AstN...@@ -14873,6 +14930,8 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, Scope *scope, AstN
14873 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count);14930 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count);
14874 struct_val->special = ConstValSpecialStatic;14931 struct_val->special = ConstValSpecialStatic;
14875 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {14932 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {
14933 if (struct_type->data.structure.fields[i]->is_comptime)
14934 continue;
14876 ZigValue *field_val = struct_val->data.x_struct.fields[i];14935 ZigValue *field_val = struct_val->data.x_struct.fields[i];
14877 field_val->special = ConstValSpecialUndef;14936 field_val->special = ConstValSpecialUndef;
14878 field_val->type = resolve_struct_field_type(ira->codegen,14937 field_val->type = resolve_struct_field_type(ira->codegen,
...@@ -18247,7 +18306,9 @@ static ZigValue *get_const_field(IrAnalyze *ira, AstNode *source_node, ZigValue...@@ -18247,7 +18306,9 @@ static ZigValue *get_const_field(IrAnalyze *ira, AstNode *source_node, ZigValue
18247{18306{
18248 Error err;18307 Error err;
18249 ensure_field_index(struct_value->type, name, field_index);18308 ensure_field_index(struct_value->type, name, field_index);
18250 ZigValue *val = struct_value->data.x_struct.fields[field_index];18309 TypeStructField *field = struct_value->type->data.structure.fields[field_index];
18310 ZigValue *val = field->is_comptime ? field->init_val :
18311 struct_value->data.x_struct.fields[field_index];
18251 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_node, val, UndefBad)))18312 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_node, val, UndefBad)))
18252 return nullptr;18313 return nullptr;
18253 return val;18314 return val;
...@@ -22422,7 +22483,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val)...@@ -22422,7 +22483,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val)
22422 size_t src_field_count = val->type->data.structure.src_field_count;22483 size_t src_field_count = val->type->data.structure.src_field_count;
22423 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {22484 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
22424 TypeStructField *struct_field = val->type->data.structure.fields[field_i];22485 TypeStructField *struct_field = val->type->data.structure.fields[field_i];
22425 if (struct_field->gen_index == SIZE_MAX)22486 if (struct_field->gen_index == SIZE_MAX || struct_field->is_comptime)
22426 continue;22487 continue;
22427 ZigValue *field_val = val->data.x_struct.fields[field_i];22488 ZigValue *field_val = val->data.x_struct.fields[field_i];
22428 size_t offset = struct_field->offset;22489 size_t offset = struct_field->offset;
...@@ -22451,6 +22512,10 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val)...@@ -22451,6 +22512,10 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val)
22451 size_t used_bits = 0;22512 size_t used_bits = 0;
22452 while (src_i < src_field_count) {22513 while (src_i < src_field_count) {
22453 TypeStructField *field = val->type->data.structure.fields[src_i];22514 TypeStructField *field = val->type->data.structure.fields[src_i];
22515 if (field->is_comptime) {
22516 src_i += 1;
22517 continue;
22518 }
22454 assert(field->gen_index != SIZE_MAX);22519 assert(field->gen_index != SIZE_MAX);
22455 if (field->gen_index != gen_i)22520 if (field->gen_index != gen_i)
22456 break;22521 break;
...@@ -22599,9 +22664,11 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou...@@ -22599,9 +22664,11 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
22599 size_t src_field_count = val->type->data.structure.src_field_count;22664 size_t src_field_count = val->type->data.structure.src_field_count;
22600 val->data.x_struct.fields = alloc_const_vals_ptrs(codegen, src_field_count);22665 val->data.x_struct.fields = alloc_const_vals_ptrs(codegen, src_field_count);
22601 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {22666 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
22667 TypeStructField *struct_field = val->type->data.structure.fields[field_i];
22668 if (struct_field->is_comptime)
22669 continue;
22602 ZigValue *field_val = val->data.x_struct.fields[field_i];22670 ZigValue *field_val = val->data.x_struct.fields[field_i];
22603 field_val->special = ConstValSpecialStatic;22671 field_val->special = ConstValSpecialStatic;
22604 TypeStructField *struct_field = val->type->data.structure.fields[field_i];
22605 field_val->type = struct_field->type_entry;22672 field_val->type = struct_field->type_entry;
22606 if (struct_field->gen_index == SIZE_MAX)22673 if (struct_field->gen_index == SIZE_MAX)
22607 continue;22674 continue;
...@@ -22634,6 +22701,10 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou...@@ -22634,6 +22701,10 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
22634 uint64_t bit_offset = 0;22701 uint64_t bit_offset = 0;
22635 while (src_i < src_field_count) {22702 while (src_i < src_field_count) {
22636 TypeStructField *field = val->type->data.structure.fields[src_i];22703 TypeStructField *field = val->type->data.structure.fields[src_i];
22704 if (field->is_comptime) {
22705 src_i += 1;
22706 continue;
22707 }
22637 src_assert(field->gen_index != SIZE_MAX, source_node);22708 src_assert(field->gen_index != SIZE_MAX, source_node);
22638 if (field->gen_index != gen_i)22709 if (field->gen_index != gen_i)
22639 break;22710 break;
...@@ -25515,6 +25586,95 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {...@@ -25515,6 +25586,95 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
25515 zig_unreachable();25586 zig_unreachable();
25516}25587}
2551725588
25589static Error ir_resolve_lazy_recurse_array(AstNode *source_node, ZigValue *val, size_t len) {
25590 Error err;
25591 switch (val->data.x_array.special) {
25592 case ConstArraySpecialUndef:
25593 case ConstArraySpecialBuf:
25594 return ErrorNone;
25595 case ConstArraySpecialNone:
25596 break;
25597 }
25598 ZigValue *elems = val->data.x_array.data.s_none.elements;
25599
25600 for (size_t i = 0; i < len; i += 1) {
25601 if ((err = ir_resolve_lazy_recurse(source_node, &elems[i])))
25602 return err;
25603 }
25604
25605 return ErrorNone;
25606}
25607
25608static Error ir_resolve_lazy_recurse(AstNode *source_node, ZigValue *val) {
25609 Error err;
25610 if ((err = ir_resolve_lazy_raw(source_node, val)))
25611 return err;
25612 assert(val->special != ConstValSpecialRuntime);
25613 assert(val->special != ConstValSpecialLazy);
25614 if (val->special != ConstValSpecialStatic)
25615 return ErrorNone;
25616 switch (val->type->id) {
25617 case ZigTypeIdOpaque:
25618 case ZigTypeIdEnum:
25619 case ZigTypeIdMetaType:
25620 case ZigTypeIdBool:
25621 case ZigTypeIdVoid:
25622 case ZigTypeIdComptimeFloat:
25623 case ZigTypeIdInt:
25624 case ZigTypeIdComptimeInt:
25625 case ZigTypeIdEnumLiteral:
25626 case ZigTypeIdErrorSet:
25627 case ZigTypeIdUndefined:
25628 case ZigTypeIdNull:
25629 case ZigTypeIdPointer:
25630 case ZigTypeIdFn:
25631 case ZigTypeIdAnyFrame:
25632 case ZigTypeIdBoundFn:
25633 case ZigTypeIdInvalid:
25634 case ZigTypeIdUnreachable:
25635 case ZigTypeIdFloat:
25636 return ErrorNone;
25637 case ZigTypeIdFnFrame:
25638 zig_panic("TODO: ir_resolve_lazy_recurse ZigTypeIdFnFrame");
25639 case ZigTypeIdUnion: {
25640 ConstUnionValue *union_val = &val->data.x_union;
25641 return ir_resolve_lazy_recurse(source_node, union_val->payload);
25642 }
25643 case ZigTypeIdVector:
25644 return ir_resolve_lazy_recurse_array(source_node, val, val->type->data.vector.len);
25645 case ZigTypeIdArray:
25646 return ir_resolve_lazy_recurse_array(source_node, val, val->type->data.array.len);
25647 case ZigTypeIdStruct:
25648 for (size_t i = 0; i < val->type->data.structure.src_field_count; i += 1) {
25649 ZigValue *field = val->data.x_struct.fields[i];
25650 if (val->type->data.structure.fields[i]->is_comptime) {
25651 // comptime struct fields do not need to be resolved because
25652 // they are not part of the value.
25653 continue;
25654 }
25655 if ((err = ir_resolve_lazy_recurse(source_node, field)))
25656 return err;
25657 }
25658 return ErrorNone;
25659 case ZigTypeIdOptional:
25660 if (get_src_ptr_type(val->type) != nullptr)
25661 return ErrorNone;
25662 if (val->data.x_optional == nullptr)
25663 return ErrorNone;
25664
25665 return ir_resolve_lazy_recurse(source_node, val->data.x_optional);
25666 case ZigTypeIdErrorUnion: {
25667 bool is_err = val->data.x_err_union.error_set->data.x_err_set != nullptr;
25668 if (is_err) {
25669 return ir_resolve_lazy_recurse(source_node, val->data.x_err_union.error_set);
25670 } else {
25671 return ir_resolve_lazy_recurse(source_node, val->data.x_err_union.payload);
25672 }
25673 }
25674 }
25675 zig_unreachable();
25676}
25677
25518Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val) {25678Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val) {
25519 Error err;25679 Error err;
25520 if ((err = ir_resolve_lazy_raw(source_node, val))) {25680 if ((err = ir_resolve_lazy_raw(source_node, val))) {
src/stage1/util.cpp-23
...@@ -21,29 +21,6 @@ void zig_panic(const char *format, ...) {...@@ -21,29 +21,6 @@ void zig_panic(const char *format, ...) {
21 abort();21 abort();
22}22}
2323
24uint32_t int_hash(int i) {
25 return (uint32_t)(i % UINT32_MAX);
26}
27bool int_eq(int a, int b) {
28 return a == b;
29}
30
31uint32_t uint64_hash(uint64_t i) {
32 return (uint32_t)(i % UINT32_MAX);
33}
34
35bool uint64_eq(uint64_t a, uint64_t b) {
36 return a == b;
37}
38
39uint32_t ptr_hash(const void *ptr) {
40 return (uint32_t)(((uintptr_t)ptr) % UINT32_MAX);
41}
42
43bool ptr_eq(const void *a, const void *b) {
44 return a == b;
45}
46
47// Ported from std/mem.zig.24// Ported from std/mem.zig.
48bool SplitIterator_isSplitByte(SplitIterator *self, uint8_t byte) {25bool SplitIterator_isSplitByte(SplitIterator *self, uint8_t byte) {
49 for (size_t i = 0; i < self->split_bytes.len; i += 1) {26 for (size_t i = 0; i < self->split_bytes.len; i += 1) {
src/stage1/util.hpp-7
...@@ -129,13 +129,6 @@ static inline uint64_t round_to_next_power_of_2(uint64_t x) {...@@ -129,13 +129,6 @@ static inline uint64_t round_to_next_power_of_2(uint64_t x) {
129 return x + 1;129 return x + 1;
130}130}
131131
132uint32_t int_hash(int i);
133bool int_eq(int a, int b);
134uint32_t uint64_hash(uint64_t i);
135bool uint64_eq(uint64_t a, uint64_t b);
136uint32_t ptr_hash(const void *ptr);
137bool ptr_eq(const void *a, const void *b);
138
139static inline uint8_t log2_u64(uint64_t x) {132static inline uint8_t log2_u64(uint64_t x) {
140 return (63 - clzll(x));133 return (63 - clzll(x));
141}134}
src/stage1/zig0.cpp+4-1
...@@ -265,6 +265,7 @@ int main(int argc, char **argv) {...@@ -265,6 +265,7 @@ int main(int argc, char **argv) {
265 const char *override_lib_dir = nullptr;265 const char *override_lib_dir = nullptr;
266 const char *mcpu = nullptr;266 const char *mcpu = nullptr;
267 bool single_threaded = false;267 bool single_threaded = false;
268 bool is_test_build = false;
268269
269 for (int i = 1; i < argc; i += 1) {270 for (int i = 1; i < argc; i += 1) {
270 char *arg = argv[i];271 char *arg = argv[i];
...@@ -272,6 +273,8 @@ int main(int argc, char **argv) {...@@ -272,6 +273,8 @@ int main(int argc, char **argv) {
272 if (arg[0] == '-') {273 if (arg[0] == '-') {
273 if (strcmp(arg, "--") == 0) {274 if (strcmp(arg, "--") == 0) {
274 fprintf(stderr, "Unexpected end-of-parameter mark: %s\n", arg);275 fprintf(stderr, "Unexpected end-of-parameter mark: %s\n", arg);
276 } else if (strcmp(arg, "--test") == 0) {
277 is_test_build = true;
275 } else if (strcmp(arg, "-ODebug") == 0) {278 } else if (strcmp(arg, "-ODebug") == 0) {
276 optimize_mode = BuildModeDebug;279 optimize_mode = BuildModeDebug;
277 } else if (strcmp(arg, "-OReleaseFast") == 0) {280 } else if (strcmp(arg, "-OReleaseFast") == 0) {
...@@ -446,7 +449,7 @@ int main(int argc, char **argv) {...@@ -446,7 +449,7 @@ int main(int argc, char **argv) {
446 nullptr, 0,449 nullptr, 0,
447 in_file, strlen(in_file),450 in_file, strlen(in_file),
448 override_lib_dir, strlen(override_lib_dir),451 override_lib_dir, strlen(override_lib_dir),
449 &target, false);452 &target, is_test_build);
450453
451 stage1->main_progress_node = root_progress_node;454 stage1->main_progress_node = root_progress_node;
452 stage1->root_name_ptr = out_name;455 stage1->root_name_ptr = out_name;