Browse Source

Fix key generation for constant strings in IR

Ginger Bill 8 years ago
parent
commit
d2e7d730ac
3 changed files with 18 additions and 3 deletions
  1. 10 0
      src/common.c
  2. 5 0
      src/exact_value.c
  3. 3 3
      src/ir.c

+ 10 - 0
src/common.c

@@ -19,6 +19,16 @@ gbAllocator heap_allocator(void) {
 #include "integer128.c"
 #include "murmurhash3.c"
 
+u128 fnv128a(void const *data, isize len) {
+	u128 o = u128_lo_hi(0x13bull, 0x1000000ull);
+	u128 h = u128_lo_hi(0x62b821756295c58dull, 0x6c62272e07bb0142ull);
+	u8 const *bytes = cast(u8 const *)data;
+	for (isize i = 0; i < len; i++) {
+		h = u128_mul(u128_xor(h, u128_from_u64(bytes[i])), o);
+	}
+	return h;
+}
+
 gb_global String global_module_path = {0};
 gb_global bool global_module_path_set = false;
 

+ 5 - 0
src/exact_value.c

@@ -71,6 +71,11 @@ ExactValue exact_value_i128(i128 i) {
 	result.value_integer = i;
 	return result;
 }
+ExactValue exact_value_u128(u128 i) {
+	ExactValue result = {ExactValue_Integer};
+	result.value_integer = *cast(i128 *)&i;
+	return result;
+}
 
 ExactValue exact_value_float(f64 f) {
 	ExactValue result = {ExactValue_Float};

+ 3 - 3
src/ir.c

@@ -1682,8 +1682,8 @@ irValue *ir_gen_map_key(irProcedure *proc, irValue *key, Type *key_type) {
 		if (str->kind == irValue_Constant) {
 			ExactValue ev = str->Constant.value;
 			GB_ASSERT(ev.kind == ExactValue_String);
-			u64 hs = gb_fnv64a(ev.value_string.text, ev.value_string.len);
-			hashed_str = ir_const_u64(proc->module->allocator, hs);
+			u128 hs = fnv128a(ev.value_string.text, ev.value_string.len);
+			hashed_str = ir_value_constant(proc->module->allocator, t_u128, exact_value_u128(hs));
 		} else {
 			irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 1);
 			args[0] = str;
@@ -1729,7 +1729,7 @@ Type *ir_addr_type(irAddr addr) {
 }
 
 irValue *ir_insert_dynamic_map_key_and_value(irProcedure *proc, irValue *addr, Type *map_type,
-                                     irValue *map_key, irValue *map_value) {
+                                             irValue *map_key, irValue *map_value) {
 	map_type = base_type(map_type);
 
 	irValue *h = ir_gen_map_header(proc, addr, map_type);