diff --git a/src/stage1/all_types.hpp b/src/stage1/all_types.hpp index 6385f18ec5..9161a46569 100644 --- a/src/stage1/all_types.hpp +++ b/src/stage1/all_types.hpp @@ -1879,8 +1879,8 @@ struct TypeId { } data; }; -uint32_t type_id_hash(TypeId); -bool type_id_eql(TypeId a, TypeId b); +uint32_t type_id_hash(TypeId const *); +bool type_id_eql(TypeId const *a, TypeId const *b); enum ZigLLVMFnId { ZigLLVMFnIdCtz, @@ -1935,8 +1935,8 @@ struct ZigLLVMFnKey { } data; }; -uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey); -bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b); +uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey const *); +bool zig_llvm_fn_key_eql(ZigLLVMFnKey const *a, ZigLLVMFnKey const *b); struct TimeEvent { double time; diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp index f77e217450..06bd1e1ed6 100644 --- a/src/stage1/analyze.cpp +++ b/src/stage1/analyze.cpp @@ -7742,9 +7742,9 @@ ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) { return entry; } -uint32_t type_id_hash(TypeId x) { - uint32_t hash = hash_combine(HASH_INIT, &x.id); - switch (x.id) { +uint32_t type_id_hash(TypeId const *x) { + uint32_t hash = hash_combine(HASH_INIT, &x->id); + switch (x->id) { case ZigTypeIdInvalid: case ZigTypeIdOpaque: case ZigTypeIdMetaType: @@ -7768,46 +7768,50 @@ uint32_t type_id_hash(TypeId x) { case ZigTypeIdAnyFrame: zig_unreachable(); case ZigTypeIdErrorUnion: - hash = hash_combine(hash, &x.data.error_union.err_set_type); - hash = hash_combine(hash, &x.data.error_union.payload_type); + hash = hash_combine(hash, &x->data.error_union.err_set_type); + hash = hash_combine(hash, &x->data.error_union.payload_type); return hash; case ZigTypeIdPointer: - hash = hash_combine(hash, &x.data.pointer.child_type); - hash = hash_combine(hash, &x.data.pointer.ptr_len); - hash = hash_combine(hash, &x.data.pointer.is_const); - hash = hash_combine(hash, &x.data.pointer.is_volatile); - hash = hash_combine(hash, &x.data.pointer.allow_zero); - hash = hash_combine(hash, &x.data.pointer.alignment); - hash = hash_combine(hash, &x.data.pointer.bit_offset_in_host); - hash = hash_combine(hash, &x.data.pointer.vector_index); - hash = hash_combine(hash, &x.data.pointer.host_int_bytes); - if (x.data.pointer.sentinel != nullptr) { - hash = hash_combine_const_val(hash, x.data.pointer.sentinel); + hash = hash_combine(hash, &x->data.pointer.child_type); + hash = hash_combine(hash, &x->data.pointer.ptr_len); + hash = hash_combine(hash, &x->data.pointer.is_const); + hash = hash_combine(hash, &x->data.pointer.is_volatile); + hash = hash_combine(hash, &x->data.pointer.allow_zero); + hash = hash_combine(hash, &x->data.pointer.alignment); + hash = hash_combine(hash, &x->data.pointer.bit_offset_in_host); + hash = hash_combine(hash, &x->data.pointer.vector_index); + hash = hash_combine(hash, &x->data.pointer.host_int_bytes); + if (x->data.pointer.sentinel != nullptr) { + hash = hash_combine_const_val(hash, x->data.pointer.sentinel); + } + if (x->data.pointer.inferred_struct_field) { + hash = hash_combine(hash, &x->data.pointer.inferred_struct_field->inferred_struct_type); + hash = hash_combine_buf(hash, x->data.pointer.inferred_struct_field->field_name); } return hash; case ZigTypeIdArray: - hash = hash_combine(hash, &x.data.array.child_type); - hash = hash_combine(hash, &x.data.array.size); - if (x.data.array.sentinel != nullptr) { - hash = hash_combine_const_val(hash, x.data.array.sentinel); + hash = hash_combine(hash, &x->data.array.child_type); + hash = hash_combine(hash, &x->data.array.size); + if (x->data.array.sentinel != nullptr) { + hash = hash_combine_const_val(hash, x->data.array.sentinel); } return hash; case ZigTypeIdInt: - hash = hash_combine(hash, &x.data.integer.is_signed); - hash = hash_combine(hash, &x.data.integer.bit_count); + hash = hash_combine(hash, &x->data.integer.is_signed); + hash = hash_combine(hash, &x->data.integer.bit_count); return hash; case ZigTypeIdVector: - hash = hash_combine(hash, &x.data.vector.elem_type); - hash = hash_combine(hash, &x.data.vector.len); + hash = hash_combine(hash, &x->data.vector.elem_type); + hash = hash_combine(hash, &x->data.vector.len); return hash; } zig_unreachable(); } -bool type_id_eql(TypeId a, TypeId b) { - if (a.id != b.id) +bool type_id_eql(TypeId const *a, TypeId const *b) { + if (a->id != b->id) return false; - switch (a.id) { + switch (a->id) { case ZigTypeIdInvalid: case ZigTypeIdMetaType: case ZigTypeIdVoid: @@ -7831,107 +7835,107 @@ bool type_id_eql(TypeId a, TypeId b) { case ZigTypeIdAnyFrame: zig_unreachable(); case ZigTypeIdErrorUnion: - return a.data.error_union.err_set_type == b.data.error_union.err_set_type && - a.data.error_union.payload_type == b.data.error_union.payload_type; + return a->data.error_union.err_set_type == b->data.error_union.err_set_type && + a->data.error_union.payload_type == b->data.error_union.payload_type; case ZigTypeIdPointer: - return a.data.pointer.child_type == b.data.pointer.child_type && - a.data.pointer.ptr_len == b.data.pointer.ptr_len && - a.data.pointer.is_const == b.data.pointer.is_const && - a.data.pointer.is_volatile == b.data.pointer.is_volatile && - a.data.pointer.allow_zero == b.data.pointer.allow_zero && - a.data.pointer.alignment == b.data.pointer.alignment && - a.data.pointer.bit_offset_in_host == b.data.pointer.bit_offset_in_host && - a.data.pointer.vector_index == b.data.pointer.vector_index && - a.data.pointer.host_int_bytes == b.data.pointer.host_int_bytes && + return a->data.pointer.child_type == b->data.pointer.child_type && + a->data.pointer.ptr_len == b->data.pointer.ptr_len && + a->data.pointer.is_const == b->data.pointer.is_const && + a->data.pointer.is_volatile == b->data.pointer.is_volatile && + a->data.pointer.allow_zero == b->data.pointer.allow_zero && + a->data.pointer.alignment == b->data.pointer.alignment && + a->data.pointer.bit_offset_in_host == b->data.pointer.bit_offset_in_host && + a->data.pointer.vector_index == b->data.pointer.vector_index && + a->data.pointer.host_int_bytes == b->data.pointer.host_int_bytes && ( - a.data.pointer.sentinel == b.data.pointer.sentinel || - (a.data.pointer.sentinel != nullptr && b.data.pointer.sentinel != nullptr && - const_values_equal(a.data.pointer.codegen, a.data.pointer.sentinel, b.data.pointer.sentinel)) + a->data.pointer.sentinel == b->data.pointer.sentinel || + (a->data.pointer.sentinel != nullptr && b->data.pointer.sentinel != nullptr && + const_values_equal(a->data.pointer.codegen, a->data.pointer.sentinel, b->data.pointer.sentinel)) ) && ( - a.data.pointer.inferred_struct_field == b.data.pointer.inferred_struct_field || - (a.data.pointer.inferred_struct_field != nullptr && - b.data.pointer.inferred_struct_field != nullptr && - a.data.pointer.inferred_struct_field->inferred_struct_type == - b.data.pointer.inferred_struct_field->inferred_struct_type && - buf_eql_buf(a.data.pointer.inferred_struct_field->field_name, - b.data.pointer.inferred_struct_field->field_name)) + a->data.pointer.inferred_struct_field == b->data.pointer.inferred_struct_field || + (a->data.pointer.inferred_struct_field != nullptr && + b->data.pointer.inferred_struct_field != nullptr && + a->data.pointer.inferred_struct_field->inferred_struct_type == + b->data.pointer.inferred_struct_field->inferred_struct_type && + buf_eql_buf(a->data.pointer.inferred_struct_field->field_name, + b->data.pointer.inferred_struct_field->field_name)) ); case ZigTypeIdArray: - return a.data.array.child_type == b.data.array.child_type && - a.data.array.size == b.data.array.size && + return a->data.array.child_type == b->data.array.child_type && + a->data.array.size == b->data.array.size && ( - a.data.array.sentinel == b.data.array.sentinel || - (a.data.array.sentinel != nullptr && b.data.array.sentinel != nullptr && - const_values_equal(a.data.array.codegen, a.data.array.sentinel, b.data.array.sentinel)) + a->data.array.sentinel == b->data.array.sentinel || + (a->data.array.sentinel != nullptr && b->data.array.sentinel != nullptr && + const_values_equal(a->data.array.codegen, a->data.array.sentinel, b->data.array.sentinel)) ); case ZigTypeIdInt: - return a.data.integer.is_signed == b.data.integer.is_signed && - a.data.integer.bit_count == b.data.integer.bit_count; + return a->data.integer.is_signed == b->data.integer.is_signed && + a->data.integer.bit_count == b->data.integer.bit_count; case ZigTypeIdVector: - return a.data.vector.elem_type == b.data.vector.elem_type && - a.data.vector.len == b.data.vector.len; + return a->data.vector.elem_type == b->data.vector.elem_type && + a->data.vector.len == b->data.vector.len; } zig_unreachable(); } -uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) { - switch (x.id) { +uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey const *x) { + switch (x->id) { case ZigLLVMFnIdCtz: - return (uint32_t)(x.data.ctz.bit_count) * (uint32_t)810453934; + return (uint32_t)(x->data.ctz.bit_count) * (uint32_t)810453934; case ZigLLVMFnIdClz: - return (uint32_t)(x.data.clz.bit_count) * (uint32_t)2428952817; + return (uint32_t)(x->data.clz.bit_count) * (uint32_t)2428952817; case ZigLLVMFnIdPopCount: - return (uint32_t)(x.data.clz.bit_count) * (uint32_t)101195049; + return (uint32_t)(x->data.clz.bit_count) * (uint32_t)101195049; case ZigLLVMFnIdFloatOp: - return (uint32_t)(x.data.floating.bit_count) * ((uint32_t)x.id + 1025) + - (uint32_t)(x.data.floating.vector_len) * (((uint32_t)x.id << 5) + 1025) + - (uint32_t)(x.data.floating.op) * (uint32_t)43789879; + return (uint32_t)(x->data.floating.bit_count) * ((uint32_t)x->id + 1025) + + (uint32_t)(x->data.floating.vector_len) * (((uint32_t)x->id << 5) + 1025) + + (uint32_t)(x->data.floating.op) * (uint32_t)43789879; case ZigLLVMFnIdFMA: - return (uint32_t)(x.data.floating.bit_count) * ((uint32_t)x.id + 1025) + - (uint32_t)(x.data.floating.vector_len) * (((uint32_t)x.id << 5) + 1025); + return (uint32_t)(x->data.floating.bit_count) * ((uint32_t)x->id + 1025) + + (uint32_t)(x->data.floating.vector_len) * (((uint32_t)x->id << 5) + 1025); case ZigLLVMFnIdBswap: - return (uint32_t)(x.data.bswap.bit_count) * ((uint32_t)3661994335) + - (uint32_t)(x.data.bswap.vector_len) * (((uint32_t)x.id << 5) + 1025); + return (uint32_t)(x->data.bswap.bit_count) * ((uint32_t)3661994335) + + (uint32_t)(x->data.bswap.vector_len) * (((uint32_t)x->id << 5) + 1025); case ZigLLVMFnIdBitReverse: - return (uint32_t)(x.data.bit_reverse.bit_count) * (uint32_t)2621398431; + return (uint32_t)(x->data.bit_reverse.bit_count) * (uint32_t)2621398431; case ZigLLVMFnIdOverflowArithmetic: - return ((uint32_t)(x.data.overflow_arithmetic.bit_count) * 87135777) + - ((uint32_t)(x.data.overflow_arithmetic.add_sub_mul) * 31640542) + - ((uint32_t)(x.data.overflow_arithmetic.is_signed) ? 1062315172 : 314955820) + - x.data.overflow_arithmetic.vector_len * 1435156945; + return ((uint32_t)(x->data.overflow_arithmetic.bit_count) * 87135777) + + ((uint32_t)(x->data.overflow_arithmetic.add_sub_mul) * 31640542) + + ((uint32_t)(x->data.overflow_arithmetic.is_signed) ? 1062315172 : 314955820) + + x->data.overflow_arithmetic.vector_len * 1435156945; } zig_unreachable(); } -bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) { - if (a.id != b.id) +bool zig_llvm_fn_key_eql(ZigLLVMFnKey const *a, ZigLLVMFnKey const *b) { + if (a->id != b->id) return false; - switch (a.id) { + switch (a->id) { case ZigLLVMFnIdCtz: - return a.data.ctz.bit_count == b.data.ctz.bit_count; + return a->data.ctz.bit_count == b->data.ctz.bit_count; case ZigLLVMFnIdClz: - return a.data.clz.bit_count == b.data.clz.bit_count; + return a->data.clz.bit_count == b->data.clz.bit_count; case ZigLLVMFnIdPopCount: - return a.data.pop_count.bit_count == b.data.pop_count.bit_count; + return a->data.pop_count.bit_count == b->data.pop_count.bit_count; case ZigLLVMFnIdBswap: - return a.data.bswap.bit_count == b.data.bswap.bit_count && - a.data.bswap.vector_len == b.data.bswap.vector_len; + return a->data.bswap.bit_count == b->data.bswap.bit_count && + a->data.bswap.vector_len == b->data.bswap.vector_len; case ZigLLVMFnIdBitReverse: - return a.data.bit_reverse.bit_count == b.data.bit_reverse.bit_count; + return a->data.bit_reverse.bit_count == b->data.bit_reverse.bit_count; case ZigLLVMFnIdFloatOp: - return a.data.floating.bit_count == b.data.floating.bit_count && - a.data.floating.vector_len == b.data.floating.vector_len && - a.data.floating.op == b.data.floating.op; + return a->data.floating.bit_count == b->data.floating.bit_count && + a->data.floating.vector_len == b->data.floating.vector_len && + a->data.floating.op == b->data.floating.op; case ZigLLVMFnIdFMA: - return a.data.floating.bit_count == b.data.floating.bit_count && - a.data.floating.vector_len == b.data.floating.vector_len; + return a->data.floating.bit_count == b->data.floating.bit_count && + a->data.floating.vector_len == b->data.floating.vector_len; case ZigLLVMFnIdOverflowArithmetic: - return (a.data.overflow_arithmetic.bit_count == b.data.overflow_arithmetic.bit_count) && - (a.data.overflow_arithmetic.add_sub_mul == b.data.overflow_arithmetic.add_sub_mul) && - (a.data.overflow_arithmetic.is_signed == b.data.overflow_arithmetic.is_signed) && - (a.data.overflow_arithmetic.vector_len == b.data.overflow_arithmetic.vector_len); + return (a->data.overflow_arithmetic.bit_count == b->data.overflow_arithmetic.bit_count) && + (a->data.overflow_arithmetic.add_sub_mul == b->data.overflow_arithmetic.add_sub_mul) && + (a->data.overflow_arithmetic.is_signed == b->data.overflow_arithmetic.is_signed) && + (a->data.overflow_arithmetic.vector_len == b->data.overflow_arithmetic.vector_len); } zig_unreachable(); } diff --git a/src/stage1/bigint.cpp b/src/stage1/bigint.cpp index 97181b6ad2..27ca148b7b 100644 --- a/src/stage1/bigint.cpp +++ b/src/stage1/bigint.cpp @@ -1730,16 +1730,16 @@ Cmp bigint_cmp_zero(const BigInt *op) { return op->is_negative ? CmpLT : CmpGT; } -uint32_t bigint_hash(BigInt x) { - if (x.digit_count == 0) { +uint32_t bigint_hash(BigInt const *x) { + if (x->digit_count == 0) { return 0; } else { - return bigint_ptr(&x)[0]; + return bigint_ptr(x)[0]; } } -bool bigint_eql(BigInt a, BigInt b) { - return bigint_cmp(&a, &b) == CmpEQ; +bool bigint_eql(BigInt const *a, BigInt const *b) { + return bigint_cmp(a, b) == CmpEQ; } void bigint_incr(BigInt *x) { diff --git a/src/stage1/bigint.hpp b/src/stage1/bigint.hpp index 521de25b1c..67f3ca1368 100644 --- a/src/stage1/bigint.hpp +++ b/src/stage1/bigint.hpp @@ -100,7 +100,7 @@ void bigint_decr(BigInt *value); bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result); -uint32_t bigint_hash(BigInt x); -bool bigint_eql(BigInt a, BigInt b); +uint32_t bigint_hash(BigInt const *x); +bool bigint_eql(BigInt const *a, BigInt const *b); #endif diff --git a/src/stage1/hash_map.hpp b/src/stage1/hash_map.hpp index 8681e5b761..0dad87289e 100644 --- a/src/stage1/hash_map.hpp +++ b/src/stage1/hash_map.hpp @@ -12,7 +12,33 @@ #include -template +template +struct MakePointer { + typedef K const *Type; + static Type convert(K const &val) { + return &val; + } +}; + +template +struct MakePointer { + typedef K *Type; + static Type convert(K * const &val) { + return val; + } +}; + +template +struct MakePointer { + typedef K const *Type; + static Type convert(K const * const &val) { + return val; + } +}; + +template::Type key), + bool (*EqualFn)(typename MakePointer::Type a, typename MakePointer::Type b)> class HashMap { public: void init(int capacity) { @@ -51,7 +77,7 @@ public: if (_index_bytes == nullptr) { if (_entries.length < 16) { - _entries.append({HashFunction(key), 0, key, value}); + _entries.append({HashFunction(MakePointer::convert(key)), 0, key, value}); return; } else { _indexes_len = 32; @@ -131,9 +157,9 @@ public: bool maybe_remove(const K &key) { _modification_count += 1; if (_index_bytes == nullptr) { - uint32_t hash = HashFunction(key); + uint32_t hash = HashFunction(MakePointer::convert(key)); for (size_t i = 0; i < _entries.length; i += 1) { - if (_entries.items[i].hash == hash && EqualFn(_entries.items[i].key, key)) { + if (_entries.items[i].hash == hash && EqualFn(MakePointer::convert(_entries.items[i].key), MakePointer::convert(key))) { _entries.swap_remove(i); return true; } @@ -223,7 +249,7 @@ private: template void internal_put(const K &key, const V &value, I *indexes) { - uint32_t hash = HashFunction(key); + uint32_t hash = HashFunction(MakePointer::convert(key)); uint32_t distance_from_start_index = 0; size_t start_index = hash_to_index(hash); for (size_t roll_over = 0; roll_over < _indexes_len; @@ -241,7 +267,7 @@ private: // This pointer survives the following append because we call // _entries.ensure_capacity before internal_put. Entry *entry = &_entries.items[index_data - 1]; - if (entry->hash == hash && EqualFn(entry->key, key)) { + if (entry->hash == hash && EqualFn(MakePointer::convert(entry->key), MakePointer::convert(key))) { *entry = {hash, distance_from_start_index, key, value}; if (distance_from_start_index > _max_distance_from_start_index) _max_distance_from_start_index = distance_from_start_index; @@ -322,9 +348,9 @@ private: Entry *internal_get(const K &key) const { if (_index_bytes == nullptr) { - uint32_t hash = HashFunction(key); + uint32_t hash = HashFunction(MakePointer::convert(key)); for (size_t i = 0; i < _entries.length; i += 1) { - if (_entries.items[i].hash == hash && EqualFn(_entries.items[i].key, key)) { + if (_entries.items[i].hash == hash && EqualFn(MakePointer::convert(_entries.items[i].key), MakePointer::convert(key))) { return &_entries.items[i]; } } @@ -340,7 +366,7 @@ private: template Entry *internal_get2(const K &key, I *indexes) const { - uint32_t hash = HashFunction(key); + uint32_t hash = HashFunction(MakePointer::convert(key)); size_t start_index = hash_to_index(hash); for (size_t roll_over = 0; roll_over <= _max_distance_from_start_index; roll_over += 1) { size_t index_index = (start_index + roll_over) % _indexes_len; @@ -349,7 +375,7 @@ private: return nullptr; Entry *entry = &_entries.items[index_data - 1]; - if (entry->hash == hash && EqualFn(entry->key, key)) + if (entry->hash == hash && EqualFn(MakePointer::convert(entry->key), MakePointer::convert(key))) return entry; } return nullptr; @@ -361,7 +387,7 @@ private: template bool internal_remove(const K &key, I *indexes) { - uint32_t hash = HashFunction(key); + uint32_t hash = HashFunction(MakePointer::convert(key)); size_t start_index = hash_to_index(hash); for (size_t roll_over = 0; roll_over <= _max_distance_from_start_index; roll_over += 1) { size_t index_index = (start_index + roll_over) % _indexes_len; @@ -371,7 +397,7 @@ private: size_t index = index_data - 1; Entry *entry = &_entries.items[index]; - if (entry->hash != hash || !EqualFn(entry->key, key)) + if (entry->hash != hash || !EqualFn(MakePointer::convert(entry->key), MakePointer::convert(key))) continue; size_t prev_index = index_index;