mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-30 19:30:06 +00:00
[REFLECTION BREAKING] Modify the internals of the map type to increase performance
This commit is contained in:
@@ -2794,6 +2794,8 @@ void check_map_type(CheckerContext *ctx, Type *type, Ast *node) {
|
||||
|
||||
if (is_type_string(key)) {
|
||||
add_package_dependency(ctx, "runtime", "default_hash_string");
|
||||
} else {
|
||||
add_package_dependency(ctx, "runtime", "default_hash_ptr");
|
||||
}
|
||||
|
||||
|
||||
|
||||
+24
-33
@@ -3593,27 +3593,8 @@ irValue *ir_gen_map_key(irProcedure *proc, irValue *key, Type *key_type) {
|
||||
irValue *v = ir_add_local_generated(proc, t_map_key, true);
|
||||
Type *t = base_type(ir_type(key));
|
||||
key = ir_emit_conv(proc, key, key_type);
|
||||
if (is_type_integer(t)) {
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, key, hash_type));
|
||||
} else if (is_type_enum(t)) {
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, key, hash_type));
|
||||
} else if (is_type_typeid(t)) {
|
||||
irValue *i = ir_emit_bitcast(proc, key, t_uint);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, i, hash_type));
|
||||
} else if (is_type_pointer(t)) {
|
||||
irValue *p = ir_emit_conv(proc, key, t_uintptr);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, p, hash_type));
|
||||
} else if (is_type_float(t)) {
|
||||
irValue *bits = nullptr;
|
||||
i64 size = type_size_of(t);
|
||||
switch (8*size) {
|
||||
case 32: bits = ir_emit_transmute(proc, key, t_u32); break;
|
||||
case 64: bits = ir_emit_transmute(proc, key, t_u64); break;
|
||||
default: GB_PANIC("Unhandled float size: %lld bits", size); break;
|
||||
}
|
||||
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, bits, hash_type));
|
||||
} else if (is_type_string(t)) {
|
||||
if (is_type_string(t)) {
|
||||
irValue *str = ir_emit_conv(proc, key, t_string);
|
||||
irValue *hashed_str = nullptr;
|
||||
|
||||
@@ -3628,9 +3609,27 @@ irValue *ir_gen_map_key(irProcedure *proc, irValue *key, Type *key_type) {
|
||||
hashed_str = ir_emit_runtime_call(proc, "default_hash_string", args);
|
||||
}
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), hashed_str);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, v, 1), str);
|
||||
|
||||
irValue *key_data = ir_emit_struct_ep(proc, v, 1);
|
||||
key_data = ir_emit_conv(proc, key_data, alloc_type_pointer(key_type));
|
||||
ir_emit_store(proc, key_data, str);
|
||||
} else {
|
||||
GB_PANIC("Unhandled map key type");
|
||||
i64 sz = type_size_of(t);
|
||||
GB_ASSERT(sz <= 8);
|
||||
if (sz != 0) {
|
||||
auto args = array_make<irValue *>(ir_allocator(), 2);
|
||||
args[0] = ir_address_from_load_or_generate_local(proc, key);
|
||||
args[1] = ir_const_int(sz);
|
||||
irValue *hash = ir_emit_runtime_call(proc, "default_hash_ptr", args);
|
||||
|
||||
|
||||
irValue *hash_ptr = ir_emit_struct_ep(proc, v, 0);
|
||||
irValue *key_data = ir_emit_struct_ep(proc, v, 1);
|
||||
key_data = ir_emit_conv(proc, key_data, alloc_type_pointer(key_type));
|
||||
|
||||
ir_emit_store(proc, hash_ptr, hash);
|
||||
ir_emit_store(proc, key_data, key);
|
||||
}
|
||||
}
|
||||
|
||||
return ir_emit_load(proc, v);
|
||||
@@ -9818,8 +9817,6 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir
|
||||
break;
|
||||
}
|
||||
case Type_Map: {
|
||||
irValue *key = ir_add_local_generated(proc, expr_type->Map.key, true);
|
||||
|
||||
irValue *entries = ir_map_entries_ptr(proc, expr);
|
||||
irValue *elem = ir_emit_struct_ep(proc, entries, 0);
|
||||
elem = ir_emit_load(proc, elem);
|
||||
@@ -9827,15 +9824,9 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir
|
||||
irValue *entry = ir_emit_ptr_offset(proc, elem, idx);
|
||||
val = ir_emit_load(proc, ir_emit_struct_ep(proc, entry, 2));
|
||||
|
||||
irValue *hash = ir_emit_struct_ep(proc, entry, 0);
|
||||
if (is_type_string(expr_type->Map.key)) {
|
||||
irValue *str = ir_emit_struct_ep(proc, hash, 1);
|
||||
ir_emit_store(proc, key, ir_emit_load(proc, str));
|
||||
} else {
|
||||
irValue *hash_ptr = ir_emit_struct_ep(proc, hash, 0);
|
||||
hash_ptr = ir_emit_conv(proc, hash_ptr, ir_type(key));
|
||||
ir_emit_store(proc, key, ir_emit_load(proc, hash_ptr));
|
||||
}
|
||||
irValue *key_raw = ir_emit_struct_ep(proc, entry, 0);
|
||||
key_raw = ir_emit_struct_ep(proc, key_raw, 1);
|
||||
irValue *key = ir_emit_conv(proc, key_raw, alloc_type_pointer(expr_type->Map.key));
|
||||
|
||||
idx = ir_emit_load(proc, key);
|
||||
|
||||
|
||||
+31
-39
@@ -3077,8 +3077,6 @@ void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValu
|
||||
break;
|
||||
}
|
||||
case Type_Map: {
|
||||
lbAddr key = lb_add_local_generated(p, expr_type->Map.key, true);
|
||||
|
||||
lbValue entries = lb_map_entries_ptr(p, expr);
|
||||
lbValue elem = lb_emit_struct_ep(p, entries, 0);
|
||||
elem = lb_emit_load(p, elem);
|
||||
@@ -3086,17 +3084,11 @@ void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValu
|
||||
lbValue entry = lb_emit_ptr_offset(p, elem, idx);
|
||||
val = lb_emit_load(p, lb_emit_struct_ep(p, entry, 2));
|
||||
|
||||
lbValue hash = lb_emit_struct_ep(p, entry, 0);
|
||||
if (is_type_string(expr_type->Map.key)) {
|
||||
lbValue str = lb_emit_struct_ep(p, hash, 1);
|
||||
lb_addr_store(p, key, lb_emit_load(p, str));
|
||||
} else {
|
||||
lbValue hash_ptr = lb_emit_struct_ep(p, hash, 0);
|
||||
hash_ptr = lb_emit_conv(p, hash_ptr, key.addr.type);
|
||||
lb_addr_store(p, key, lb_emit_load(p, hash_ptr));
|
||||
}
|
||||
lbValue key_raw = lb_emit_struct_ep(p, entry, 0);
|
||||
key_raw = lb_emit_struct_ep(p, key_raw, 1);
|
||||
lbValue key = lb_emit_conv(p, key_raw, alloc_type_pointer(expr_type->Map.key));
|
||||
|
||||
idx = lb_addr_load(p, key);
|
||||
idx = lb_emit_load(p, key);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -9655,45 +9647,45 @@ lbValue lb_gen_map_header(lbProcedure *p, lbValue map_val_ptr, Type *map_type) {
|
||||
lbValue lb_gen_map_key(lbProcedure *p, lbValue key, Type *key_type) {
|
||||
Type *hash_type = t_u64;
|
||||
lbAddr v = lb_add_local_generated(p, t_map_key, true);
|
||||
lbValue vp = lb_addr_get_ptr(p, v);
|
||||
Type *t = base_type(key.type);
|
||||
key = lb_emit_conv(p, key, key_type);
|
||||
if (is_type_integer(t)) {
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, v.addr, 0), lb_emit_conv(p, key, hash_type));
|
||||
} else if (is_type_enum(t)) {
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, v.addr, 0), lb_emit_conv(p, key, hash_type));
|
||||
} else if (is_type_typeid(t)) {
|
||||
lbValue i = lb_emit_transmute(p, key, t_uint);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, v.addr, 0), lb_emit_conv(p, i, hash_type));
|
||||
} else if (is_type_pointer(t)) {
|
||||
lbValue ptr = lb_emit_conv(p, key, t_uintptr);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, v.addr, 0), lb_emit_conv(p, ptr, hash_type));
|
||||
} else if (is_type_float(t)) {
|
||||
lbValue bits = {};
|
||||
i64 size = type_size_of(t);
|
||||
switch (8*size) {
|
||||
case 32: bits = lb_emit_transmute(p, key, t_u32); break;
|
||||
case 64: bits = lb_emit_transmute(p, key, t_u64); break;
|
||||
default: GB_PANIC("Unhandled float size: %lld bits", size); break;
|
||||
}
|
||||
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, v.addr, 0), lb_emit_conv(p, bits, hash_type));
|
||||
} else if (is_type_string(t)) {
|
||||
if (is_type_string(t)) {
|
||||
lbValue str = lb_emit_conv(p, key, t_string);
|
||||
lbValue hashed_str = {};
|
||||
|
||||
if (false && lb_is_const(str)) {
|
||||
String value = lb_get_const_string(p->module, str);
|
||||
u64 hs = fnv64a(value.text, value.len);
|
||||
hashed_str = lb_const_value(p->module, t_u64, exact_value_u64(hs));
|
||||
if (lb_is_const(str)) {
|
||||
String v = lb_get_const_string(p->module, str);
|
||||
u64 hs = fnv64a(v.text, v.len);
|
||||
hashed_str = lb_const_int(p->module, t_u64, hs);
|
||||
} else {
|
||||
auto args = array_make<lbValue>(heap_allocator(), 1);
|
||||
args[0] = str;
|
||||
hashed_str = lb_emit_runtime_call(p, "default_hash_string", args);
|
||||
}
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, v.addr, 0), hashed_str);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, v.addr, 1), str);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, vp, 0), hashed_str);
|
||||
|
||||
lbValue key_data = lb_emit_struct_ep(p, vp, 1);
|
||||
key_data = lb_emit_conv(p, key_data, alloc_type_pointer(key_type));
|
||||
lb_emit_store(p, key_data, str);
|
||||
} else {
|
||||
GB_PANIC("Unhandled map key type");
|
||||
i64 sz = type_size_of(t);
|
||||
GB_ASSERT(sz <= 8);
|
||||
if (sz != 0) {
|
||||
auto args = array_make<lbValue>(heap_allocator(), 2);
|
||||
args[0] = lb_address_from_load_or_generate_local(p, key);
|
||||
args[1] = lb_const_int(p->module, t_int, sz);
|
||||
lbValue hash = lb_emit_runtime_call(p, "default_hash_ptr", args);
|
||||
|
||||
|
||||
lbValue hash_ptr = lb_emit_struct_ep(p, vp, 0);
|
||||
lbValue key_data = lb_emit_struct_ep(p, vp, 1);
|
||||
key_data = lb_emit_conv(p, key_data, alloc_type_pointer(key_type));
|
||||
|
||||
lb_emit_store(p, hash_ptr, hash);
|
||||
lb_emit_store(p, key_data, key);
|
||||
}
|
||||
}
|
||||
|
||||
return lb_addr_load(p, v);
|
||||
|
||||
Reference in New Issue
Block a user