mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-20 05:20:28 +00:00
Improve emit store for large constants
This commit is contained in:
@@ -567,6 +567,13 @@ void lb_emit_slice_bounds_check(lbProcedure *p, Token token, lbValue low, lbValu
|
||||
}
|
||||
}
|
||||
|
||||
unsigned lb_try_get_alignment(LLVMValueRef addr_ptr, unsigned default_alignment) {
|
||||
if (LLVMIsAGlobalValue(addr_ptr) || LLVMIsAAllocaInst(addr_ptr) || LLVMIsALoadInst(addr_ptr)) {
|
||||
return LLVMGetAlignment(addr_ptr);
|
||||
}
|
||||
return default_alignment;
|
||||
}
|
||||
|
||||
bool lb_try_update_alignment(LLVMValueRef addr_ptr, unsigned alignment) {
|
||||
if (LLVMIsAGlobalValue(addr_ptr) || LLVMIsAAllocaInst(addr_ptr) || LLVMIsALoadInst(addr_ptr)) {
|
||||
if (LLVMGetAlignment(addr_ptr) < alignment) {
|
||||
@@ -914,16 +921,35 @@ void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) {
|
||||
|
||||
enum {MAX_STORE_SIZE = 64};
|
||||
|
||||
if (LLVMIsALoadInst(value.value) && lb_sizeof(LLVMTypeOf(value.value)) > MAX_STORE_SIZE) {
|
||||
LLVMValueRef dst_ptr = ptr.value;
|
||||
LLVMValueRef src_ptr = LLVMGetOperand(value.value, 0);
|
||||
src_ptr = LLVMBuildPointerCast(p->builder, src_ptr, LLVMTypeOf(dst_ptr), "");
|
||||
if (lb_sizeof(LLVMTypeOf(value.value)) > MAX_STORE_SIZE) {
|
||||
if (LLVMIsALoadInst(value.value)) {
|
||||
LLVMValueRef dst_ptr = ptr.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, 1,
|
||||
src_ptr, 1,
|
||||
LLVMConstInt(LLVMInt64TypeInContext(p->module->ctx), lb_sizeof(LLVMTypeOf(value.value)), false));
|
||||
return;
|
||||
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);
|
||||
LLVMValueRef global_data = addr.addr.value;
|
||||
// make it truly private data
|
||||
LLVMSetLinkage(global_data, LLVMPrivateLinkage);
|
||||
LLVMSetUnnamedAddress(global_data, LLVMGlobalUnnamedAddr);
|
||||
LLVMSetGlobalConstant(global_data, true);
|
||||
|
||||
LLVMValueRef dst_ptr = ptr.value;
|
||||
LLVMValueRef src_ptr = global_data;
|
||||
src_ptr = LLVMBuildPointerCast(p->builder, src_ptr, LLVMTypeOf(dst_ptr), "");
|
||||
|
||||
LLVMBuildMemMove(p->builder,
|
||||
dst_ptr, lb_try_get_alignment(dst_ptr, 1),
|
||||
src_ptr, lb_try_get_alignment(global_data, 1),
|
||||
LLVMConstInt(LLVMInt64TypeInContext(p->module->ctx), lb_sizeof(LLVMTypeOf(value.value)), false));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (lb_is_type_proc_recursive(a)) {
|
||||
|
||||
Reference in New Issue
Block a user