From ed58374964889db91b38fe95db409111819790ca Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 8 Nov 2022 12:18:36 +0000 Subject: Make `Map_Info` store pointers to cell info rather than inline --- src/llvm_backend_proc.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/llvm_backend_proc.cpp') diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index a9de7b231..3881790e0 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -2324,6 +2324,9 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, case BuiltinProc_type_hasher_proc: return lb_get_hasher_proc_for_type(p->module, ce->args[0]->tav.type); + case BuiltinProc_type_map_info: + return lb_gen_map_info_ptr(p->module, ce->args[0]->tav.type); + case BuiltinProc_fixed_point_mul: case BuiltinProc_fixed_point_div: case BuiltinProc_fixed_point_mul_sat: -- cgit v1.2.3 From a74093784cea3637b445657541cb7fff2f374f50 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 8 Nov 2022 12:24:00 +0000 Subject: Add `intrinsics.map_cell_info` and `intrinsics.map_info` --- core/intrinsics/intrinsics.odin | 3 +++ core/runtime/dynamic_map_internal.odin | 23 ++++++++--------------- src/check_builtin.cpp | 14 ++++++++++++++ src/checker_builtin_procs.hpp | 8 +++++--- src/llvm_backend.cpp | 10 +++++----- src/llvm_backend.hpp | 1 + src/llvm_backend_proc.cpp | 4 ++++ 7 files changed, 40 insertions(+), 23 deletions(-) (limited to 'src/llvm_backend_proc.cpp') diff --git a/core/intrinsics/intrinsics.odin b/core/intrinsics/intrinsics.odin index 69f77cea2..38542d2fc 100644 --- a/core/intrinsics/intrinsics.odin +++ b/core/intrinsics/intrinsics.odin @@ -188,6 +188,9 @@ type_field_index_of :: proc($T: typeid, $name: string) -> uintptr --- type_equal_proc :: proc($T: typeid) -> (equal: proc "contextless" (rawptr, rawptr) -> bool) where type_is_comparable(T) --- type_hasher_proc :: proc($T: typeid) -> (hasher: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr) where type_is_comparable(T) --- +type_map_info :: proc($T: typeid/map[$K]$V) -> ^runtime.Map_Info --- +type_map_cell_info :: proc($T: typeid) -> ^runtime.Map_Cell_Info --- + type_convert_variants_to_pointers :: proc($T: typeid) -> typeid where type_is_union(T) --- constant_utf16_cstring :: proc($literal: string) -> [^]u16 --- diff --git a/core/runtime/dynamic_map_internal.odin b/core/runtime/dynamic_map_internal.odin index 79e1a4f30..983bfde35 100644 --- a/core/runtime/dynamic_map_internal.odin +++ b/core/runtime/dynamic_map_internal.odin @@ -103,6 +103,9 @@ Map_Cell_Info :: struct { elements_per_cell: uintptr, // 8-bytes on 64-bit, 4-bytes on 32-bits } +// map_cell_info :: proc "contextless" ($T: typeid) -> ^Map_Cell_Info {...} +map_cell_info :: intrinsics.type_map_cell_info + // Same as the above procedure but at runtime with the cell Map_Cell_Info value. map_cell_index_dynamic :: #force_inline proc "contextless" (base: uintptr, info: ^Map_Cell_Info, index: uintptr) -> uintptr { // Micro-optimize the common cases to save on integer division. @@ -229,18 +232,13 @@ Map_Info :: struct { map_info :: intrinsics.type_map_info map_kvh_data_dynamic :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Info) -> (ks: uintptr, vs: uintptr, hs: [^]Map_Hash, sk: uintptr, sv: uintptr) { - @static INFO_HS := Map_Cell_Info { - size_of(Map_Hash), - align_of(Map_Hash), - size_of(Map_Cell(Map_Hash)), - len(Map_Cell(Map_Hash){}.data), - } + INFO_HS := intrinsics.type_map_cell_info(Map_Hash) capacity := uintptr(1) << map_log2_cap(m) ks = map_data(m) vs = map_cell_index_dynamic(ks, info.ks, capacity) // Skip past ks to get start of vs hs_ := map_cell_index_dynamic(vs, info.vs, capacity) // Skip past vs to get start of hs - sk = map_cell_index_dynamic(hs_, &INFO_HS, capacity) // Skip past hs to get start of sk + sk = map_cell_index_dynamic(hs_, INFO_HS, capacity) // Skip past hs to get start of sk // Need to skip past two elements in the scratch key space to get to the start // of the scratch value space, of which there's only two elements as well. sv = map_cell_index_dynamic_const(sk, info.ks, 2) @@ -270,21 +268,16 @@ map_alloc_dynamic :: proc(info: ^Map_Info, log2_capacity: uintptr, allocator := capacity := uintptr(1) << max(log2_capacity, MAP_MIN_LOG2_CAPACITY) - @static INFO_HS := Map_Cell_Info { - size_of(Map_Hash), - align_of(Map_Hash), - size_of(Map_Cell(Map_Hash)), - len(Map_Cell(Map_Hash){}.data), - } - round :: #force_inline proc "contextless" (value: uintptr) -> uintptr { return (value + MAP_CACHE_LINE_SIZE - 1) &~ uintptr(MAP_CACHE_LINE_SIZE - 1) } + INFO_HS := intrinsics.type_map_cell_info(Map_Hash) + size := uintptr(0) size = round(map_cell_index_dynamic(size, info.ks, capacity)) size = round(map_cell_index_dynamic(size, info.vs, capacity)) - size = round(map_cell_index_dynamic(size, &INFO_HS, capacity)) + size = round(map_cell_index_dynamic(size, INFO_HS, capacity)) size = round(map_cell_index_dynamic(size, info.ks, 2)) // Two additional ks for scratch storage size = round(map_cell_index_dynamic(size, info.vs, 2)) // Two additional vs for scratch storage diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 457100d6e..890f7a39b 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -5385,6 +5385,20 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 operand->type = t_map_info_ptr; break; } + case BuiltinProc_type_map_cell_info: + { + Operand op = {}; + Type *bt = check_type(c, ce->args[0]); + Type *type = base_type(bt); + if (type == nullptr || type == t_invalid) { + error(ce->args[0], "Expected a type for '%.*s'", LIT(builtin_name)); + return false; + } + + operand->mode = Addressing_Value; + operand->type = t_map_cell_info_ptr; + break; + } case BuiltinProc_constant_utf16_cstring: { diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index 72639e071..e03e94ab4 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -278,6 +278,7 @@ BuiltinProc__type_simple_boolean_end, BuiltinProc_type_equal_proc, BuiltinProc_type_hasher_proc, BuiltinProc_type_map_info, + BuiltinProc_type_map_cell_info, BuiltinProc__type_end, @@ -571,9 +572,10 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_field_index_of"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_equal_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_hasher_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_map_info"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_equal_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_hasher_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_map_info"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_map_cell_info"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 960ef84f6..bce1fa1d1 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -501,10 +501,10 @@ lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, A } -LLVMValueRef lb_gen_map_cell_info(lbModule *m, Type *type) { +lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type) { lbAddr *found = map_get(&m->map_cell_info_map, type); if (found) { - return found->addr.value; + return found->addr; } i64 size = 0, len = 0; @@ -523,7 +523,7 @@ LLVMValueRef lb_gen_map_cell_info(lbModule *m, Type *type) { map_set(&m->map_cell_info_map, type, addr); - return addr.addr.value; + return addr.addr; } lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type) { map_type = base_type(map_type); @@ -537,8 +537,8 @@ lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type) { GB_ASSERT(t_map_info != nullptr); GB_ASSERT(t_map_cell_info != nullptr); - LLVMValueRef key_cell_info = lb_gen_map_cell_info(m, map_type->Map.key); - LLVMValueRef value_cell_info = lb_gen_map_cell_info(m, map_type->Map.value); + LLVMValueRef key_cell_info = lb_gen_map_cell_info_ptr(m, map_type->Map.key).value; + LLVMValueRef value_cell_info = lb_gen_map_cell_info_ptr(m, map_type->Map.value).value; LLVMValueRef const_values[4] = {}; const_values[0] = key_cell_info; diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 065bf4943..6c7c2e392 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -446,6 +446,7 @@ String lb_get_const_string(lbModule *m, lbValue value); lbValue lb_generate_local_array(lbProcedure *p, Type *elem_type, i64 count, bool zero_init=true); lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String prefix, i64 id); lbValue lb_gen_map_key_hash(lbProcedure *p, lbValue key, Type *key_type, lbValue *key_ptr_); +lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type); lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type); lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr, lbValue const &key); diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 3881790e0..6d7d7eecb 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -2327,6 +2327,10 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, case BuiltinProc_type_map_info: return lb_gen_map_info_ptr(p->module, ce->args[0]->tav.type); + case BuiltinProc_type_map_cell_info: + return lb_gen_map_cell_info_ptr(p->module, ce->args[0]->tav.type); + + case BuiltinProc_fixed_point_mul: case BuiltinProc_fixed_point_div: case BuiltinProc_fixed_point_mul_sat: -- cgit v1.2.3 From 8852d090b61fab27f97787b37b7cbd5b63a52083 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 10 Nov 2022 12:46:53 +0000 Subject: Correct static map get; make get take a pointer to simplify compiler internals --- core/runtime/dynamic_map_internal.odin | 21 ++++++------ src/llvm_backend.cpp | 58 +++++++++++++++++++--------------- src/llvm_backend.hpp | 4 +-- src/llvm_backend_expr.cpp | 2 +- src/llvm_backend_proc.cpp | 4 +-- src/llvm_backend_type.cpp | 4 +-- src/llvm_backend_utility.cpp | 2 +- 7 files changed, 50 insertions(+), 45 deletions(-) (limited to 'src/llvm_backend_proc.cpp') diff --git a/core/runtime/dynamic_map_internal.odin b/core/runtime/dynamic_map_internal.odin index f57dce885..aedd3f260 100644 --- a/core/runtime/dynamic_map_internal.odin +++ b/core/runtime/dynamic_map_internal.odin @@ -107,7 +107,7 @@ Map_Cell_Info :: struct { map_cell_info :: intrinsics.type_map_cell_info // Same as the above procedure but at runtime with the cell Map_Cell_Info value. -map_cell_index_dynamic :: #force_inline proc "contextless" (base: uintptr, info: ^Map_Cell_Info, index: uintptr) -> uintptr { +map_cell_index_dynamic :: #force_inline proc "contextless" (base: uintptr, #no_alias info: ^Map_Cell_Info, index: uintptr) -> uintptr { // Micro-optimize the common cases to save on integer division. elements_per_cell := uintptr(info.elements_per_cell) size_of_cell := uintptr(info.size_of_cell) @@ -355,13 +355,13 @@ map_alloc_dynamic :: proc "odin" (info: ^Map_Info, log2_capacity: uintptr, alloc // there is no type information. // // This procedure returns the address of the just inserted value. -map_insert_hash_dynamic :: proc "odin" (m: ^Raw_Map, #no_alias info: ^Map_Info, h: Map_Hash, ik: uintptr, iv: uintptr) -> (result: uintptr) { +map_insert_hash_dynamic :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, h: Map_Hash, ik: uintptr, iv: uintptr) -> (result: uintptr) { + h := h pos := map_desired_position(m^, h) distance := uintptr(0) mask := (uintptr(1) << map_log2_cap(m^)) - 1 ks, vs, hs, sk, sv := map_kvh_data_dynamic(m^, info) - _, _ = sk, sv // Avoid redundant loads of these values size_of_k := info.ks.size_of_type @@ -376,7 +376,6 @@ map_insert_hash_dynamic :: proc "odin" (m: ^Raw_Map, #no_alias info: ^Map_Info, tk := map_cell_index_dynamic(sk, info.ks, 1) tv := map_cell_index_dynamic(sv, info.vs, 1) - h := h for { hp := &hs[pos] @@ -660,19 +659,19 @@ map_get :: proc "contextless" (m: $T/map[$K]$V, key: K) -> (stored_key: K, store } } -__dynamic_map_get_with_hash :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Info, h: Map_Hash, key: rawptr) -> (ptr: rawptr) { +__dynamic_map_get_with_hash :: proc "contextless" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, h: Map_Hash, key: rawptr) -> (ptr: rawptr) { if m.len == 0 { return nil } - pos := map_desired_position(m, h) + pos := map_desired_position(m^, h) distance := uintptr(0) - mask := (uintptr(1) << map_log2_cap(m)) - 1 - ks, vs, hs, _, _ := map_kvh_data_dynamic(m, info) + mask := (uintptr(1) << map_log2_cap(m^)) - 1 + ks, vs, hs, _, _ := map_kvh_data_dynamic(m^, info) for { element_hash := hs[pos] if map_hash_is_empty(element_hash) { return nil - } else if distance > map_probe_distance(m, element_hash, pos) { + } else if distance > map_probe_distance(m^, element_hash, pos) { return nil } else if element_hash == h && info.key_equal(key, rawptr(map_cell_index_dynamic(ks, info.ks, pos))) { return rawptr(map_cell_index_dynamic(vs, info.vs, pos)) @@ -682,7 +681,7 @@ __dynamic_map_get_with_hash :: proc "contextless" (m: Raw_Map, #no_alias info: ^ } } -__dynamic_map_get :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Info, key: rawptr) -> (ptr: rawptr) { +__dynamic_map_get :: proc "contextless" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, key: rawptr) -> (ptr: rawptr) { if m.len == 0 { return nil } @@ -693,7 +692,7 @@ __dynamic_map_get :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Info, __dynamic_map_set :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, key, value: rawptr, loc := #caller_location) -> rawptr { hash := info.key_hasher(key, 0) - if found := __dynamic_map_get_with_hash(m^, info, hash, key); found != nil { + if found := __dynamic_map_get_with_hash(m, info, hash, key); found != nil { intrinsics.mem_copy_non_overlapping(found, value, info.vs.size_of_type) return found } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index e12a4c016..c313bc825 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -140,7 +140,7 @@ lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx) { } -lbValue lb_get_equal_proc_for_type(lbModule *m, Type *type) { +lbValue lb_equal_proc_for_type(lbModule *m, Type *type) { type = base_type(type); GB_ASSERT(is_type_comparable(type)); @@ -296,7 +296,7 @@ lbValue lb_simple_compare_hash(lbProcedure *p, Type *type, lbValue data, lbValue return lb_emit_runtime_call(p, "default_hasher_n", args); } -lbValue lb_get_hasher_proc_for_type(lbModule *m, Type *type) { +lbValue lb_hasher_proc_for_type(lbModule *m, Type *type) { type = core_type(type); GB_ASSERT_MSG(is_type_valid_for_keys(type), "%s", type_to_string(type)); @@ -343,7 +343,7 @@ lbValue lb_get_hasher_proc_for_type(lbModule *m, Type *type) { GB_ASSERT(type->Struct.offsets != nullptr); i64 offset = type->Struct.offsets[i]; Entity *field = type->Struct.fields[i]; - lbValue field_hasher = lb_get_hasher_proc_for_type(m, field->type); + lbValue field_hasher = lb_hasher_proc_for_type(m, field->type); lbValue ptr = lb_emit_ptr_offset(p, data, lb_const_int(m, t_uintptr, offset)); args[0] = ptr; @@ -356,7 +356,7 @@ lbValue lb_get_hasher_proc_for_type(lbModule *m, Type *type) { if (is_type_union_maybe_pointer(type)) { Type *v = type->Union.variants[0]; - lbValue variant_hasher = lb_get_hasher_proc_for_type(m, v); + lbValue variant_hasher = lb_hasher_proc_for_type(m, v); args[0] = data; args[1] = seed; @@ -379,7 +379,7 @@ lbValue lb_get_hasher_proc_for_type(lbModule *m, Type *type) { Type *v = type->Union.variants[i]; lbValue case_tag = lb_const_union_tag(p->module, type, v); - lbValue variant_hasher = lb_get_hasher_proc_for_type(m, v); + lbValue variant_hasher = lb_hasher_proc_for_type(m, v); args[0] = data; args[1] = seed; @@ -397,7 +397,7 @@ lbValue lb_get_hasher_proc_for_type(lbModule *m, Type *type) { lb_addr_store(p, pres, seed); auto args = array_make(permanent_allocator(), 2); - lbValue elem_hasher = lb_get_hasher_proc_for_type(m, type->Array.elem); + lbValue elem_hasher = lb_hasher_proc_for_type(m, type->Array.elem); auto loop_data = lb_loop_start(p, cast(isize)type->Array.count, t_i32); @@ -418,7 +418,7 @@ lbValue lb_get_hasher_proc_for_type(lbModule *m, Type *type) { lb_addr_store(p, res, seed); auto args = array_make(permanent_allocator(), 2); - lbValue elem_hasher = lb_get_hasher_proc_for_type(m, type->EnumeratedArray.elem); + lbValue elem_hasher = lb_hasher_proc_for_type(m, type->EnumeratedArray.elem); auto loop_data = lb_loop_start(p, cast(isize)type->EnumeratedArray.count, t_i32); @@ -454,7 +454,7 @@ lbValue lb_get_hasher_proc_for_type(lbModule *m, Type *type) { } -lbValue lb_get_map_get_proc_for_type(lbModule *m, Type *type) { +lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) { GB_ASSERT(build_context.use_static_map_calls); type = base_type(type); GB_ASSERT(type->kind == Type_Map); @@ -468,7 +468,7 @@ lbValue lb_get_map_get_proc_for_type(lbModule *m, Type *type) { static u32 proc_index = 0; char buf[32] = {}; - isize n = gb_snprintf(buf, 32, "__$map_get%u", ++proc_index); + isize n = gb_snprintf(buf, 32, "__$map_get_%u", ++proc_index); char *str = gb_alloc_str_len(permanent_allocator(), buf, n-1); String proc_name = make_string_c(str); @@ -489,9 +489,23 @@ lbValue lb_get_map_get_proc_for_type(lbModule *m, Type *type) { LLVMAddAttributeAtIndex(p->value, 1+1, nonnull_attr); LLVMAddAttributeAtIndex(p->value, 1+1, noalias_attr); + lbBlock *loop_block = lb_create_block(p, "loop"); + lbBlock *hash_block = lb_create_block(p, "hash"); + lbBlock *probe_block = lb_create_block(p, "probe"); + lbBlock *increment_block = lb_create_block(p, "increment"); + lbBlock *hash_compare_block = lb_create_block(p, "hash_compare"); + lbBlock *key_compare_block = lb_create_block(p, "key_compare"); + lbBlock *value_block = lb_create_block(p, "value"); + lbBlock *nil_block = lb_create_block(p, "nil"); + map_ptr = lb_emit_conv(p, map_ptr, t_raw_map_ptr); lbValue map = lb_emit_load(p, map_ptr); + lbValue length = lb_map_len(p, map); + + lb_emit_if(p, lb_emit_comp(p, Token_CmpEq, length, lb_const_nil(m, t_int)), nil_block, hash_block); + lb_start_block(p, hash_block); + key_ptr = lb_emit_conv(p, key_ptr, alloc_type_pointer(type->Map.key)); lbValue key = lb_emit_load(p, key_ptr); @@ -521,16 +535,8 @@ lbValue lb_get_map_get_proc_for_type(lbModule *m, Type *type) { // lbValue res = // LLVMBuildRet(p->builder, res.value); - lbBlock *loop = lb_create_block(p, "loop"); - lbBlock *probe_block = lb_create_block(p, "probe"); - lbBlock *increment_block = lb_create_block(p, "increment"); - lbBlock *hash_compare_block = lb_create_block(p, "hash_compare"); - lbBlock *key_compare_block = lb_create_block(p, "key_compare"); - lbBlock *value_block = lb_create_block(p, "value"); - lbBlock *nil_block = lb_create_block(p, "nil"); - - lb_emit_jump(p, loop); - lb_start_block(p, loop); + lb_emit_jump(p, loop_block); + lb_start_block(p, loop_block); lbValue element_hash = lb_emit_load(p, lb_emit_ptr_offset(p, hs, lb_addr_load(p, pos))); { @@ -577,7 +583,7 @@ lbValue lb_get_map_get_proc_for_type(lbModule *m, Type *type) { lb_addr_store(p, pos, pp); lb_emit_increment(p, distance.addr); } - lb_emit_jump(p, loop); + lb_emit_jump(p, loop_block); lb_start_block(p, nil_block); { @@ -678,8 +684,8 @@ lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type) { LLVMValueRef const_values[4] = {}; const_values[0] = key_cell_info; const_values[1] = value_cell_info; - const_values[2] = lb_get_hasher_proc_for_type(m, map_type->Map.key).value; - const_values[3] = lb_get_equal_proc_for_type(m, map_type->Map.key).value; + const_values[2] = lb_hasher_proc_for_type(m, map_type->Map.key).value; + const_values[3] = lb_equal_proc_for_type(m, map_type->Map.key).value; LLVMValueRef llvm_res = llvm_const_named_struct(m, t_map_info, const_values, gb_count_of(const_values)); lbValue res = {llvm_res, t_map_info}; @@ -746,7 +752,7 @@ lbValue lb_gen_map_key_hash(lbProcedure *p, lbValue key, Type *key_type, lbValue lbValue hashed_key = lb_const_hash(p->module, key, key_type); if (hashed_key.value == nullptr) { - lbValue hasher = lb_get_hasher_proc_for_type(p->module, key_type); + lbValue hasher = lb_hasher_proc_for_type(p->module, key_type); auto args = array_make(permanent_allocator(), 2); args[0] = key_ptr; @@ -767,16 +773,16 @@ lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr, key_ptr = lb_emit_conv(p, key_ptr, t_rawptr); if (build_context.use_static_map_calls) { - lbValue map_get_proc = lb_get_map_get_proc_for_type(p->module, map_type); + lbValue map_get_proc = lb_map_get_proc_for_type(p->module, map_type); auto args = array_make(permanent_allocator(), 2); - args[0] = map_ptr; + args[0] = lb_emit_conv(p, map_ptr, t_rawptr); args[1] = key_ptr; ptr = lb_emit_call(p, map_get_proc, args); } else { auto args = array_make(permanent_allocator(), 3); - args[0] = lb_emit_transmute(p, lb_emit_load(p, map_ptr), t_raw_map); + args[0] = lb_emit_transmute(p, map_ptr, t_raw_map_ptr); args[1] = lb_gen_map_info_ptr(p->module, map_type); args[2] = key_ptr; diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index f9fe6cff0..c4333e949 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -463,8 +463,8 @@ lbValue lb_emit_source_code_location_const(lbProcedure *p, String const &procedu lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const ¶m_value, TokenPos const &pos); -lbValue lb_get_equal_proc_for_type(lbModule *m, Type *type); -lbValue lb_get_hasher_proc_for_type(lbModule *m, Type *type); +lbValue lb_equal_proc_for_type(lbModule *m, Type *type); +lbValue lb_hasher_proc_for_type(lbModule *m, Type *type); lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t); LLVMMetadataRef lb_debug_type(lbModule *m, Type *type); diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 05a9fdfbf..aee87242c 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2215,7 +2215,7 @@ lbValue lb_compare_records(lbProcedure *p, TokenKind op_kind, lbValue left, lbVa args[2] = lb_const_int(p->module, t_int, type_size_of(type)); res = lb_emit_runtime_call(p, "memory_equal", args); } else { - lbValue value = lb_get_equal_proc_for_type(p->module, type); + lbValue value = lb_equal_proc_for_type(p->module, type); auto args = array_make(permanent_allocator(), 2); args[0] = lb_emit_conv(p, left_ptr, t_rawptr); args[1] = lb_emit_conv(p, right_ptr, t_rawptr); diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 6d7d7eecb..4b0323855 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -2319,10 +2319,10 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, case BuiltinProc_type_equal_proc: - return lb_get_equal_proc_for_type(p->module, ce->args[0]->tav.type); + return lb_equal_proc_for_type(p->module, ce->args[0]->tav.type); case BuiltinProc_type_hasher_proc: - return lb_get_hasher_proc_for_type(p->module, ce->args[0]->tav.type); + return lb_hasher_proc_for_type(p->module, ce->args[0]->tav.type); case BuiltinProc_type_map_info: return lb_gen_map_info_ptr(p->module, ce->args[0]->tav.type); diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 26f89f985..307d9304b 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -666,7 +666,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da } if (is_type_comparable(t) && !is_type_simple_compare(t)) { - vals[3] = lb_get_equal_proc_for_type(m, t).value; + vals[3] = lb_equal_proc_for_type(m, t).value; } vals[4] = lb_const_bool(m, t_bool, t->Union.custom_align != 0).value; @@ -702,7 +702,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da vals[6] = is_raw_union.value; vals[7] = is_custom_align.value; if (is_type_comparable(t) && !is_type_simple_compare(t)) { - vals[8] = lb_get_equal_proc_for_type(m, t).value; + vals[8] = lb_equal_proc_for_type(m, t).value; } diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 6d69021ce..30c531d71 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1434,7 +1434,7 @@ lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da) { } lbValue lb_map_len(lbProcedure *p, lbValue value) { - GB_ASSERT(is_type_map(value.type)); + GB_ASSERT_MSG(is_type_map(value.type) || are_types_identical(value.type, t_raw_map), "%s", type_to_string(value.type)); lbValue len = lb_emit_struct_ev(p, value, 1); return lb_emit_conv(p, len, t_int); } -- cgit v1.2.3 From a705a2e38bee035d6800999ba6eddd82792594f7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 13 Nov 2022 22:55:32 +0000 Subject: Minor improvement to multi return value reducing stack usage --- src/check_expr.cpp | 3 +++ src/check_stmt.cpp | 4 ++++ src/checker.hpp | 1 + src/llvm_backend_general.cpp | 24 ++++++++++++++---------- src/llvm_backend_opt.cpp | 35 ++++++++++++++++++++++++++++++++++- src/llvm_backend_proc.cpp | 42 ++++++++++++++++++++++++++++++++++-------- 6 files changed, 90 insertions(+), 19 deletions(-) (limited to 'src/llvm_backend_proc.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c58aac609..c819267fd 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6739,6 +6739,9 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *pr if (initial_entity != nullptr && initial_entity->kind == Entity_Procedure) { if (initial_entity->Procedure.deferred_procedure.entity != nullptr) { call->viral_state_flags |= ViralStateFlag_ContainsDeferredProcedure; + if (c->decl != nullptr) { + c->decl->defer_use_count += 1; + } } } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 9cacb4a35..8271ca451 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -2014,6 +2014,10 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { if (is_ast_decl(ds->stmt)) { error(ds->token, "You cannot defer a declaration"); } else { + if (ctx->decl != nullptr) { + ctx->decl->defer_use_count += 1; + } + bool out_in_defer = ctx->in_defer; ctx->in_defer = true; check_stmt(ctx, ds->stmt, 0); diff --git a/src/checker.hpp b/src/checker.hpp index badcd93d5..ded4a0ad6 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -158,6 +158,7 @@ struct DeclInfo { bool is_using; bool where_clauses_evaluated; bool proc_checked; + isize defer_use_count; CommentGroup *comment; CommentGroup *docs; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index f36dc1842..6f2253d01 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -936,23 +936,27 @@ void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) { LLVMValueRef src_ptr_original = LLVMGetOperand(value.value, 0); LLVMValueRef src_ptr = LLVMBuildPointerCast(p->builder, src_ptr_original, LLVMTypeOf(dst_ptr), ""); - LLVMBuildMemMove(p->builder, - dst_ptr, lb_try_get_alignment(dst_ptr, 1), - src_ptr, lb_try_get_alignment(src_ptr_original, 1), - LLVMConstInt(LLVMInt64TypeInContext(p->module->ctx), lb_sizeof(LLVMTypeOf(value.value)), false)); + if (dst_ptr != src_ptr && dst_ptr != src_ptr_original) { + LLVMBuildMemMove(p->builder, + dst_ptr, lb_try_get_alignment(dst_ptr, 1), + src_ptr, lb_try_get_alignment(src_ptr_original, 1), + LLVMConstInt(LLVMInt64TypeInContext(p->module->ctx), lb_sizeof(LLVMTypeOf(value.value)), false)); + } return; } else if (LLVMIsConstant(value.value)) { lbAddr addr = lb_add_global_generated(p->module, value.type, value, nullptr); lb_make_global_private_const(addr); LLVMValueRef dst_ptr = ptr.value; - LLVMValueRef src_ptr = addr.addr.value; - src_ptr = LLVMBuildPointerCast(p->builder, src_ptr, LLVMTypeOf(dst_ptr), ""); + LLVMValueRef src_ptr_original = addr.addr.value; + LLVMValueRef src_ptr = LLVMBuildPointerCast(p->builder, src_ptr_original, LLVMTypeOf(dst_ptr), ""); - LLVMBuildMemMove(p->builder, - dst_ptr, lb_try_get_alignment(dst_ptr, 1), - src_ptr, lb_try_get_alignment(src_ptr, 1), - LLVMConstInt(LLVMInt64TypeInContext(p->module->ctx), lb_sizeof(LLVMTypeOf(value.value)), false)); + if (dst_ptr != src_ptr && dst_ptr != src_ptr_original) { + LLVMBuildMemMove(p->builder, + dst_ptr, lb_try_get_alignment(dst_ptr, 1), + src_ptr, lb_try_get_alignment(src_ptr, 1), + LLVMConstInt(LLVMInt64TypeInContext(p->module->ctx), lb_sizeof(LLVMTypeOf(value.value)), false)); + } return; } } diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index e2f51b868..ba5a41871 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -267,6 +267,8 @@ void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPa **************************************************************************/ void lb_run_remove_dead_instruction_pass(lbProcedure *p) { + LLVMTypeRef llvm_void = LLVMVoidTypeInContext(p->module->ctx); + isize removal_count = 0; isize pass_count = 0; isize const max_pass_count = 10; @@ -322,7 +324,7 @@ void lb_run_remove_dead_instruction_pass(lbProcedure *p) { case LLVMOr: case LLVMXor: case LLVMAlloca: - case LLVMLoad: + case LLVMLoad: // TODO: should LLVMLoad be removed? case LLVMGetElementPtr: case LLVMTrunc: case LLVMZExt: @@ -347,6 +349,37 @@ void lb_run_remove_dead_instruction_pass(lbProcedure *p) { LLVMInstructionEraseFromParent(curr_instr); was_dead_instructions = true; break; + + case LLVMCall: + if (LLVMTypeOf(curr_instr) == llvm_void) { + LLVMValueRef the_proc = LLVMGetCalledValue(curr_instr); + unsigned id = LLVMGetIntrinsicID(the_proc); + if (id != 0) { + size_t text_len = 0; + char const *text = LLVMIntrinsicGetName(id, &text_len); + String name = make_string(cast(u8 const *)text, cast(isize)text_len); + if (name == "llvm.memmove" || name == "llvm.memcpy") { + LLVMValueRef dst = LLVMGetOperand(curr_instr, 0); + LLVMValueRef src = LLVMGetOperand(curr_instr, 1); + LLVMValueRef sz = LLVMGetOperand(curr_instr, 2); + if ((dst == src) || (LLVMIsConstant(sz) && LLVMConstIntGetZExtValue(sz) == 0)) { + removal_count += 1; + LLVMInstructionEraseFromParent(curr_instr); + was_dead_instructions = true; + break; + } + } else if (name == "llvm.memset") { + LLVMValueRef sz = LLVMGetOperand(curr_instr, 2); + if (LLVMIsConstant(sz) && LLVMConstIntGetZExtValue(sz) == 0) { + removal_count += 1; + LLVMInstructionEraseFromParent(curr_instr); + was_dead_instructions = true; + break; + } + } + } + } + break; } } } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index eaff6edc0..2e508a939 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -9,9 +9,15 @@ LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* a } void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) { + if (dst.value == src.value) { + return; + } dst = lb_emit_conv(p, dst, t_rawptr); src = lb_emit_conv(p, src, t_rawptr); len = lb_emit_conv(p, len, t_int); + if (dst.value == src.value) { + return; + } char const *name = "llvm.memmove"; if (LLVMIsConstant(len.value)) { @@ -38,9 +44,16 @@ void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue l void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) { + if (dst.value == src.value) { + return; + } dst = lb_emit_conv(p, dst, t_rawptr); src = lb_emit_conv(p, src, t_rawptr); len = lb_emit_conv(p, len, t_int); + if (dst.value == src.value) { + return; + } + char const *name = "llvm.memcpy"; if (LLVMIsConstant(len.value)) { @@ -580,18 +593,31 @@ void lb_begin_procedure_body(lbProcedure *p) { if (e->token.string != "") { GB_ASSERT(!is_blank_ident(e->token)); - // NOTE(bill): Don't even bother trying to optimize this with the return ptr value - // This will violate the defer rules if you do: - // foo :: proc() -> (x, y: T) { - // defer x = ... // defer is executed after the `defer` - // return // the values returned should be zeroed - // } - lbAddr res = lb_add_local(p, e->type, e); + lbAddr res = {}; + if (p->return_ptr.addr.value != nullptr && + p->entity != nullptr && + p->entity->decl_info != nullptr && + p->entity->decl_info->defer_use_count == 0) { + lbValue val = lb_emit_struct_ep(p, p->return_ptr.addr, cast(i32)i); + + lb_add_entity(p->module, e, val); + lb_add_debug_local_variable(p, val.value, e->type, e->token); + + // NOTE(bill): no need to zero initialize due to caller will zero return value + res = lb_addr(val); + } else { + // NOTE(bill): Don't even bother trying to optimize this with the return ptr value + // This will violate the defer rules if you do: + // foo :: proc() -> (x, y: T) { + // defer x = ... // defer is executed after the `defer` + // return // the values returned should be zeroed + // } + res = lb_add_local(p, e->type, e); + } if (e->Variable.param_value.kind != ParameterValue_Invalid) { lbValue c = lb_handle_param_value(p, e->type, e->Variable.param_value, e->token.pos); lb_addr_store(p, res, c); } - } } -- cgit v1.2.3 From d2019e3e4d4b45c34bdc0ef7cf7d630ee61a02fb Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 13 Nov 2022 23:50:45 +0000 Subject: Enforce pointer cast --- src/llvm_backend.cpp | 4 ++-- src/llvm_backend_expr.cpp | 3 ++- src/llvm_backend_proc.cpp | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/llvm_backend_proc.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 2ee292880..594224e6a 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -962,7 +962,7 @@ void lb_internal_dynamic_map_set(lbProcedure *p, lbValue const &map_ptr, Type *m } } -void lb_dynamic_map_reserve(lbProcedure *p, lbValue const &map_ptr, isize const capacity, TokenPos const &pos) { +lbValue lb_dynamic_map_reserve(lbProcedure *p, lbValue const &map_ptr, isize const capacity, TokenPos const &pos) { GB_ASSERT(!build_context.no_dynamic_literals); String proc_name = {}; @@ -975,7 +975,7 @@ void lb_dynamic_map_reserve(lbProcedure *p, lbValue const &map_ptr, isize const args[1] = lb_gen_map_info_ptr(p->module, type_deref(map_ptr.type)); args[2] = lb_const_int(p->module, t_uint, capacity); args[3] = lb_emit_source_code_location_as_global(p, proc_name, pos); - lb_emit_runtime_call(p, "__dynamic_map_reserve", args); + return lb_emit_runtime_call(p, "__dynamic_map_reserve", args); } diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index e58c84c9c..034682855 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -4131,7 +4131,8 @@ lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) { } GB_ASSERT(!build_context.no_dynamic_literals); - lb_dynamic_map_reserve(p, v.addr, 2*cl->elems.count, pos); + lbValue err = lb_dynamic_map_reserve(p, v.addr, 2*cl->elems.count, pos); + gb_unused(err); for_array(field_index, cl->elems) { Ast *elem = cl->elems[field_index]; diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 2e508a939..510479440 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -599,6 +599,7 @@ void lb_begin_procedure_body(lbProcedure *p) { p->entity->decl_info != nullptr && p->entity->decl_info->defer_use_count == 0) { lbValue val = lb_emit_struct_ep(p, p->return_ptr.addr, cast(i32)i); + val = lb_emit_conv(p, val, alloc_type_pointer(e->type)); lb_add_entity(p->module, e, val); lb_add_debug_local_variable(p, val.value, e->type, e->token); -- cgit v1.2.3 From 25bec19b1f91cac47544ec434b825bd2b9727a39 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 13 Nov 2022 23:56:05 +0000 Subject: Revert "Minor improvement to multi return value reducing stack usage" --- src/check_expr.cpp | 3 --- src/check_stmt.cpp | 4 ---- src/checker.hpp | 1 - src/llvm_backend_general.cpp | 24 ++++++++++-------------- src/llvm_backend_opt.cpp | 35 +---------------------------------- src/llvm_backend_proc.cpp | 44 +++++++++----------------------------------- 6 files changed, 20 insertions(+), 91 deletions(-) (limited to 'src/llvm_backend_proc.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c819267fd..c58aac609 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6739,9 +6739,6 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *pr if (initial_entity != nullptr && initial_entity->kind == Entity_Procedure) { if (initial_entity->Procedure.deferred_procedure.entity != nullptr) { call->viral_state_flags |= ViralStateFlag_ContainsDeferredProcedure; - if (c->decl != nullptr) { - c->decl->defer_use_count += 1; - } } } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 8271ca451..9cacb4a35 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -2014,10 +2014,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { if (is_ast_decl(ds->stmt)) { error(ds->token, "You cannot defer a declaration"); } else { - if (ctx->decl != nullptr) { - ctx->decl->defer_use_count += 1; - } - bool out_in_defer = ctx->in_defer; ctx->in_defer = true; check_stmt(ctx, ds->stmt, 0); diff --git a/src/checker.hpp b/src/checker.hpp index ded4a0ad6..badcd93d5 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -158,7 +158,6 @@ struct DeclInfo { bool is_using; bool where_clauses_evaluated; bool proc_checked; - isize defer_use_count; CommentGroup *comment; CommentGroup *docs; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 6f2253d01..f36dc1842 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -936,27 +936,23 @@ void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) { LLVMValueRef src_ptr_original = LLVMGetOperand(value.value, 0); LLVMValueRef src_ptr = LLVMBuildPointerCast(p->builder, src_ptr_original, LLVMTypeOf(dst_ptr), ""); - if (dst_ptr != src_ptr && dst_ptr != src_ptr_original) { - LLVMBuildMemMove(p->builder, - dst_ptr, lb_try_get_alignment(dst_ptr, 1), - src_ptr, lb_try_get_alignment(src_ptr_original, 1), - LLVMConstInt(LLVMInt64TypeInContext(p->module->ctx), lb_sizeof(LLVMTypeOf(value.value)), false)); - } + LLVMBuildMemMove(p->builder, + dst_ptr, lb_try_get_alignment(dst_ptr, 1), + src_ptr, lb_try_get_alignment(src_ptr_original, 1), + LLVMConstInt(LLVMInt64TypeInContext(p->module->ctx), lb_sizeof(LLVMTypeOf(value.value)), false)); return; } else if (LLVMIsConstant(value.value)) { lbAddr addr = lb_add_global_generated(p->module, value.type, value, nullptr); lb_make_global_private_const(addr); LLVMValueRef dst_ptr = ptr.value; - LLVMValueRef src_ptr_original = addr.addr.value; - LLVMValueRef src_ptr = LLVMBuildPointerCast(p->builder, src_ptr_original, LLVMTypeOf(dst_ptr), ""); + LLVMValueRef src_ptr = addr.addr.value; + src_ptr = LLVMBuildPointerCast(p->builder, src_ptr, LLVMTypeOf(dst_ptr), ""); - if (dst_ptr != src_ptr && dst_ptr != src_ptr_original) { - LLVMBuildMemMove(p->builder, - dst_ptr, lb_try_get_alignment(dst_ptr, 1), - src_ptr, lb_try_get_alignment(src_ptr, 1), - LLVMConstInt(LLVMInt64TypeInContext(p->module->ctx), lb_sizeof(LLVMTypeOf(value.value)), false)); - } + LLVMBuildMemMove(p->builder, + dst_ptr, lb_try_get_alignment(dst_ptr, 1), + src_ptr, lb_try_get_alignment(src_ptr, 1), + LLVMConstInt(LLVMInt64TypeInContext(p->module->ctx), lb_sizeof(LLVMTypeOf(value.value)), false)); return; } } diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index ba5a41871..e2f51b868 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -267,8 +267,6 @@ void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPa **************************************************************************/ void lb_run_remove_dead_instruction_pass(lbProcedure *p) { - LLVMTypeRef llvm_void = LLVMVoidTypeInContext(p->module->ctx); - isize removal_count = 0; isize pass_count = 0; isize const max_pass_count = 10; @@ -324,7 +322,7 @@ void lb_run_remove_dead_instruction_pass(lbProcedure *p) { case LLVMOr: case LLVMXor: case LLVMAlloca: - case LLVMLoad: // TODO: should LLVMLoad be removed? + case LLVMLoad: case LLVMGetElementPtr: case LLVMTrunc: case LLVMZExt: @@ -349,37 +347,6 @@ void lb_run_remove_dead_instruction_pass(lbProcedure *p) { LLVMInstructionEraseFromParent(curr_instr); was_dead_instructions = true; break; - - case LLVMCall: - if (LLVMTypeOf(curr_instr) == llvm_void) { - LLVMValueRef the_proc = LLVMGetCalledValue(curr_instr); - unsigned id = LLVMGetIntrinsicID(the_proc); - if (id != 0) { - size_t text_len = 0; - char const *text = LLVMIntrinsicGetName(id, &text_len); - String name = make_string(cast(u8 const *)text, cast(isize)text_len); - if (name == "llvm.memmove" || name == "llvm.memcpy") { - LLVMValueRef dst = LLVMGetOperand(curr_instr, 0); - LLVMValueRef src = LLVMGetOperand(curr_instr, 1); - LLVMValueRef sz = LLVMGetOperand(curr_instr, 2); - if ((dst == src) || (LLVMIsConstant(sz) && LLVMConstIntGetZExtValue(sz) == 0)) { - removal_count += 1; - LLVMInstructionEraseFromParent(curr_instr); - was_dead_instructions = true; - break; - } - } else if (name == "llvm.memset") { - LLVMValueRef sz = LLVMGetOperand(curr_instr, 2); - if (LLVMIsConstant(sz) && LLVMConstIntGetZExtValue(sz) == 0) { - removal_count += 1; - LLVMInstructionEraseFromParent(curr_instr); - was_dead_instructions = true; - break; - } - } - } - } - break; } } } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 510479440..7c83125ca 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -9,15 +9,9 @@ LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* a } void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) { - if (dst.value == src.value) { - return; - } dst = lb_emit_conv(p, dst, t_rawptr); src = lb_emit_conv(p, src, t_rawptr); len = lb_emit_conv(p, len, t_int); - if (dst.value == src.value) { - return; - } char const *name = "llvm.memmove"; if (LLVMIsConstant(len.value)) { @@ -44,16 +38,9 @@ void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue l void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) { - if (dst.value == src.value) { - return; - } dst = lb_emit_conv(p, dst, t_rawptr); src = lb_emit_conv(p, src, t_rawptr); len = lb_emit_conv(p, len, t_int); - if (dst.value == src.value) { - return; - } - char const *name = "llvm.memcpy"; if (LLVMIsConstant(len.value)) { @@ -593,32 +580,19 @@ void lb_begin_procedure_body(lbProcedure *p) { if (e->token.string != "") { GB_ASSERT(!is_blank_ident(e->token)); - lbAddr res = {}; - if (p->return_ptr.addr.value != nullptr && - p->entity != nullptr && - p->entity->decl_info != nullptr && - p->entity->decl_info->defer_use_count == 0) { - lbValue val = lb_emit_struct_ep(p, p->return_ptr.addr, cast(i32)i); - val = lb_emit_conv(p, val, alloc_type_pointer(e->type)); - - lb_add_entity(p->module, e, val); - lb_add_debug_local_variable(p, val.value, e->type, e->token); - - // NOTE(bill): no need to zero initialize due to caller will zero return value - res = lb_addr(val); - } else { - // NOTE(bill): Don't even bother trying to optimize this with the return ptr value - // This will violate the defer rules if you do: - // foo :: proc() -> (x, y: T) { - // defer x = ... // defer is executed after the `defer` - // return // the values returned should be zeroed - // } - res = lb_add_local(p, e->type, e); - } + // NOTE(bill): Don't even bother trying to optimize this with the return ptr value + // This will violate the defer rules if you do: + // foo :: proc() -> (x, y: T) { + // defer x = ... // defer is executed after the `defer` + // return // the values returned should be zeroed + // } + // NOTE(bill): REALLY, don't even bother. + lbAddr res = lb_add_local(p, e->type, e); if (e->Variable.param_value.kind != ParameterValue_Invalid) { lbValue c = lb_handle_param_value(p, e->type, e->Variable.param_value, e->token.pos); lb_addr_store(p, res, c); } + } } -- cgit v1.2.3