diff options
| author | gingerBill <bill@gingerbill.org> | 2022-07-24 20:22:50 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2022-07-24 20:22:50 +0100 |
| commit | e6ab4f48567175cc192a658fb6d7b067e38912d8 (patch) | |
| tree | 0090f00932eff38514622702419322340ed4fd1b /src | |
| parent | c8ab1b7ee1b1ba6444a057c6afa6a9d6eb7a7dae (diff) | |
Force memset instead of store zeroinitializer when the value is large
Diffstat (limited to 'src')
| -rw-r--r-- | src/llvm_backend.hpp | 4 | ||||
| -rw-r--r-- | src/llvm_backend_general.cpp | 12 | ||||
| -rw-r--r-- | src/llvm_backend_stmt.cpp | 3 | ||||
| -rw-r--r-- | src/llvm_backend_utility.cpp | 8 |
4 files changed, 19 insertions, 8 deletions
diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 745dbbbc7..a09286d0b 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -482,7 +482,11 @@ LLVMValueRef llvm_basic_shuffle(lbProcedure *p, LLVMValueRef vector, LLVMValueRe void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false); void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false); +LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len, unsigned alignment, bool is_volatile); +i64 lb_max_zero_init_size(void) { + return cast(i64)(4*build_context.word_size); +} #define LB_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime" #define LB_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info" diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index a4c2ce370..52787d427 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -855,7 +855,11 @@ void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) { if (LLVMIsNull(value.value)) { LLVMTypeRef src_t = LLVMGetElementType(LLVMTypeOf(ptr.value)); - LLVMBuildStore(p->builder, LLVMConstNull(src_t), ptr.value); + if (lb_sizeof(src_t) <= lb_max_zero_init_size()) { + LLVMBuildStore(p->builder, LLVMConstNull(src_t), ptr.value); + } else { + lb_mem_zero_ptr(p, ptr.value, a, LLVMGetAlignment(ptr.value)); + } return; } if (is_type_boolean(a)) { @@ -2737,13 +2741,15 @@ lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero_init, i32 p if (!zero_init && !force_no_init) { // If there is any padding of any kind, just zero init regardless of zero_init parameter LLVMTypeKind kind = LLVMGetTypeKind(llvm_type); + if (kind == LLVMArrayTypeKind) { + kind = LLVMGetTypeKind(lb_type(p->module, core_array_type(type))); + } + if (kind == LLVMStructTypeKind) { i64 sz = type_size_of(type); if (type_size_of_struct_pretend_is_packed(type) != sz) { zero_init = true; } - } else if (kind == LLVMArrayTypeKind) { - zero_init = true; } } diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index a8f543c1f..f131bb3db 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -2082,7 +2082,8 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { lbAddr lval = {}; if (!is_blank_ident(name)) { Entity *e = entity_of_node(name); - bool zero_init = true; // Always do it + // bool zero_init = true; // Always do it + bool zero_init = vd->values.count == 0; lval = lb_add_local(p, e->type, e, zero_init); } array_add(&lvals, lval); diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 2fa43bb0a..88ec2f22c 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -50,14 +50,14 @@ lbValue lb_correct_endianness(lbProcedure *p, lbValue value) { return value; } -void lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len, unsigned alignment, bool is_volatile) { +LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len, unsigned alignment, bool is_volatile) { bool is_inlinable = false; i64 const_len = 0; if (LLVMIsConstant(len)) { const_len = cast(i64)LLVMConstIntGetSExtValue(len); // TODO(bill): Determine when it is better to do the `*.inline` versions - if (const_len <= 4*build_context.word_size) { + if (const_len <= lb_max_zero_init_size()) { is_inlinable = true; } } @@ -83,7 +83,7 @@ void lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len args[2] = LLVMBuildIntCast2(p->builder, len, types[1], /*signed*/false, ""); args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), is_volatile, false); - LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); + return LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); } else { LLVMValueRef ip = lb_lookup_runtime_procedure(p->module, str_lit("memset")).value; @@ -92,7 +92,7 @@ void lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len args[1] = LLVMConstInt(LLVMInt32TypeInContext(p->module->ctx), 0, false); args[2] = LLVMBuildIntCast2(p->builder, len, types[1], /*signed*/false, ""); - LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); + return LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); } } |