aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-07-24 20:22:50 +0100
committergingerBill <bill@gingerbill.org>2022-07-24 20:22:50 +0100
commite6ab4f48567175cc192a658fb6d7b067e38912d8 (patch)
tree0090f00932eff38514622702419322340ed4fd1b /src
parentc8ab1b7ee1b1ba6444a057c6afa6a9d6eb7a7dae (diff)
Force memset instead of store zeroinitializer when the value is large
Diffstat (limited to 'src')
-rw-r--r--src/llvm_backend.hpp4
-rw-r--r--src/llvm_backend_general.cpp12
-rw-r--r--src/llvm_backend_stmt.cpp3
-rw-r--r--src/llvm_backend_utility.cpp8
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), "");
}
}