diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index b8c4e0144..2263709c3 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -1682,16 +1682,15 @@ static LLVMValueRef llvm_recursive_set_value(GenContext *c, DesignatorElement ** } -void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref, Expr *expr) +void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref, ConstInitializer *initializer) { bool modified = false; // First create the constant value. - assert(expr_is_const_initializer(expr)); - LLVMValueRef value = llvm_emit_const_initializer(c, expr->const_expr.initializer); + LLVMValueRef value = llvm_emit_const_initializer(c, initializer); // Create a global const. - AlignSize alignment = type_alloca_alignment(expr->type); + AlignSize alignment = type_alloca_alignment(initializer->type); LLVMTypeRef type = LLVMTypeOf(value); LLVMValueRef global_copy = llvm_add_global_raw(c, ".__const", type, alignment); llvm_set_private_linkage(global_copy); @@ -1705,11 +1704,49 @@ void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref, llvm_value_addr(c, ref); // Perform the memcpy. - llvm_emit_memcpy(c, ref->value, ref->alignment, global_copy, alignment, type_size(expr->type)); + llvm_emit_memcpy(c, ref->value, ref->alignment, global_copy, alignment, type_size(initializer->type)); +} + +static inline void llvm_emit_const_initialize_bitstruct_ref(GenContext *c, BEValue *ref, ConstInitializer *initializer) +{ + if (initializer->kind == CONST_INIT_ZERO) + { + llvm_store_zero(c, ref); + return; + } + assert(initializer->kind == CONST_INIT_STRUCT); + llvm_store_raw(c, ref, llvm_emit_const_bitstruct(c, initializer)); } static void llvm_emit_const_init_ref(GenContext *c, BEValue *ref, ConstInitializer *const_init) { + if (const_init->type->type_kind == TYPE_VECTOR) + { + LLVMValueRef val = llvm_emit_const_initializer(c, const_init); + llvm_store_raw(c, ref, val); + return; + } + if (const_init->type->type_kind == TYPE_BITSTRUCT) + { + llvm_emit_const_initialize_bitstruct_ref(c, ref, const_init); + return; + } + if (const_init->kind == CONST_INIT_ZERO) + { + // In case of a zero, optimize. + llvm_store_zero(c, ref); + return; + } + // In case of small const initializers, or full arrays - use copy. + if (const_init->kind == CONST_INIT_ARRAY_FULL || type_size(const_init->type) <= 32) + { + llvm_emit_initialize_reference_temporary_const(c, ref, const_init); + return; + } + + // Make sure we have an address. + llvm_value_addr(c, ref); + switch (const_init->kind) { case CONST_INIT_ZERO: @@ -1800,16 +1837,6 @@ static void llvm_emit_const_init_ref(GenContext *c, BEValue *ref, ConstInitializ UNREACHABLE } -static inline void llvm_emit_const_initialize_struct_union_array(GenContext *c, BEValue *ref, Expr *expr) -{ - assert(expr_is_const_initializer(expr)); - ConstInitializer *initializer = expr->const_expr.initializer; - - // Make sure we have an address. - llvm_value_addr(c, ref); - llvm_emit_const_init_ref(c, ref, initializer); - -} static inline void llvm_emit_initialize_reference_vector(GenContext *c, BEValue *ref, Type *real_type, Expr **elements) { llvm_value_addr(c, ref); @@ -2244,16 +2271,6 @@ LLVMValueRef llvm_emit_const_bitstruct(GenContext *c, ConstInitializer *initiali return result; } -static inline void llvm_emit_const_initialize_bitstruct_ref(GenContext *c, BEValue *ref, ConstInitializer *initializer) -{ - if (initializer->kind == CONST_INIT_ZERO) - { - llvm_store_zero(c, ref); - return; - } - assert(initializer->kind == CONST_INIT_STRUCT); - llvm_store_raw(c, ref, llvm_emit_const_bitstruct(c, initializer)); -} /** * Initialize a constant aggregate type. @@ -2261,31 +2278,7 @@ static inline void llvm_emit_const_initialize_bitstruct_ref(GenContext *c, BEVal static inline void llvm_emit_const_initialize_reference(GenContext *c, BEValue *ref, Expr *expr) { assert(expr_is_const_initializer(expr)); - ConstInitializer *initializer = expr->const_expr.initializer; - if (initializer->type->type_kind == TYPE_VECTOR) - { - LLVMValueRef val = llvm_emit_const_initializer(c, initializer); - llvm_store_raw(c, ref, val); - return; - } - if (initializer->type->type_kind == TYPE_BITSTRUCT) - { - llvm_emit_const_initialize_bitstruct_ref(c, ref, initializer); - return; - } - if (initializer->kind == CONST_INIT_ZERO) - { - // In case of a zero, optimize. - llvm_store_zero(c, ref); - return; - } - // In case of small const initializers, or full arrays - use copy. - if (initializer->kind == CONST_INIT_ARRAY_FULL || type_size(expr->type) <= 32) - { - llvm_emit_initialize_reference_temporary_const(c, ref, expr); - return; - } - llvm_emit_const_initialize_struct_union_array(c, ref, expr); + llvm_emit_const_init_ref(c, ref, expr->const_expr.initializer); return; } diff --git a/src/compiler/llvm_codegen_internal.h b/src/compiler/llvm_codegen_internal.h index a12d98a43..c821f69e9 100644 --- a/src/compiler/llvm_codegen_internal.h +++ b/src/compiler/llvm_codegen_internal.h @@ -483,7 +483,7 @@ void llvm_emit_dynamic_functions(GenContext *context, Decl **funcs); BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *expr, LLVMValueRef optional); INLINE void llvm_emit_exprid(GenContext *c, BEValue *value, ExprId expr); INLINE void llvm_emit_statement_chain(GenContext *c, AstId current); -void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref, Expr *expr); +void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref, ConstInitializer *initializer); void llvm_emit_len_for_expr(GenContext *c, BEValue *be_value, BEValue *expr_to_len); LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl); LLVMValueRef llvm_emit_call_intrinsic(GenContext *c, unsigned intrinsic, LLVMTypeRef *types, unsigned type_count, LLVMValueRef *values, unsigned arg_count); diff --git a/src/version.h b/src/version.h index 60a5c0f65..35e0cac25 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.581" \ No newline at end of file +#define COMPILER_VERSION "0.4.582" \ No newline at end of file diff --git a/test/test_suite/expressions/pointer_access.c3t b/test/test_suite/expressions/pointer_access.c3t index c572cfa97..71bf0e36f 100644 --- a/test/test_suite/expressions/pointer_access.c3t +++ b/test/test_suite/expressions/pointer_access.c3t @@ -65,7 +65,7 @@ entry: %6 = getelementptr inbounds %c, ptr %2, i32 0, i32 3 store double 0.000000e+00, ptr %6, align 8 %7 = getelementptr inbounds %c, ptr %2, i32 0, i32 4 - store double 3.300000e+00, ptr %7, align 8 + call void @llvm.memcpy.p0.p0.i32(ptr align 8 %7, ptr align 8 @.__const, i32 8, i1 false) %8 = getelementptr inbounds %ExtraSimple, ptr %a, i32 0, i32 3 %9 = getelementptr inbounds %.anon, ptr %8, i32 0, i32 0 store i32 0, ptr %9, align 8 diff --git a/test/test_suite/struct/nested_struct_union_init.c3t b/test/test_suite/struct/nested_struct_union_init.c3t index e4dc71aee..e669bc45e 100644 --- a/test/test_suite/struct/nested_struct_union_init.c3t +++ b/test/test_suite/struct/nested_struct_union_init.c3t @@ -69,25 +69,25 @@ entry: %m2 = alloca %Matrix2x2_b, align 4 %0 = getelementptr inbounds %Matrix3x3, ptr %x, i32 0, i32 0 %1 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 0 - store float 1.000000e+00, ptr %1, align 4 + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %1, ptr align 4 @.__const, i32 4, i1 false) %2 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 1 - store float 2.000000e+00, ptr %2, align 4 + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %2, ptr align 4 @.__const.16, i32 4, i1 false) %3 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 2 - store float 3.000000e+00, ptr %3, align 4 + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %3, ptr align 4 @.__const.17, i32 4, i1 false) %4 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 3 - store float 4.000000e+00, ptr %4, align 4 + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %4, ptr align 4 @.__const.18, i32 4, i1 false) %5 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 4 - store float 5.000000e+00, ptr %5, align 4 + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %5, ptr align 4 @.__const.19, i32 4, i1 false) %6 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 5 - store float 6.000000e+00, ptr %6, align 4 + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %6, ptr align 4 @.__const.20, i32 4, i1 false) %7 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 6 - store float 7.000000e+00, ptr %7, align 4 + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %7, ptr align 4 @.__const.21, i32 4, i1 false) %8 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 7 - store float 8.000000e+00, ptr %8, align 4 + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %8, ptr align 4 @.__const.22, i32 4, i1 false) %9 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 8 - store float 9.000000e+00, ptr %9, align 4 - call void @llvm.memcpy.p0.p0.i32(ptr align 4 %m, ptr align 4 @.__const, i32 16, i1 false) - call void @llvm.memcpy.p0.p0.i32(ptr align 4 %m2, ptr align 4 @.__const.16, i32 16, i1 false) + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %9, ptr align 4 @.__const.23, i32 4, i1 false) + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %m, ptr align 4 @.__const.24, i32 16, i1 false) + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %m2, ptr align 4 @.__const.25, i32 16, i1 false) %10 = getelementptr inbounds %Matrix3x3, ptr %x, i32 0, i32 0 %11 = getelementptr inbounds %.anon.0, ptr %10, i32 0, i32 0 %12 = load float, ptr %11, align 4