From 56d25cdeebc58c95b6228d1e25f1cc456a4bfced Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Fri, 3 Jan 2025 01:35:51 +0100 Subject: [PATCH] Remove array->vector casts --- src/compiler/c_codegen.c | 1 + src/compiler/compiler_internal.h | 3 +- src/compiler/copying.c | 1 + src/compiler/enums.h | 3 +- src/compiler/expr.c | 5 ++- src/compiler/json_output.c | 2 + src/compiler/llvm_codegen_expr.c | 42 +++++++++++-------- src/compiler/sema_casts.c | 7 +++- src/compiler/sema_expr.c | 4 ++ src/compiler/sema_liveness.c | 1 + src/compiler/sema_stmts.c | 1 + test/test_suite/slices/slice_init.c3t | 20 +++------ .../vector/vector_to_array_cast.c3t | 16 ++----- 13 files changed, 56 insertions(+), 50 deletions(-) diff --git a/src/compiler/c_codegen.c b/src/compiler/c_codegen.c index ed58176aa..c0b303d01 100644 --- a/src/compiler/c_codegen.c +++ b/src/compiler/c_codegen.c @@ -400,6 +400,7 @@ static void c_emit_expr(GenContext *c, CValue *value, Expr *expr) case EXPR_EXT_TRUNC: case EXPR_MAKE_ANY: case EXPR_INT_TO_BOOL: + case EXPR_VECTOR_FROM_ARRAY: break; case EXPR_ACCESS: break; diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 97943d142..6bb5c9e42 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -3368,6 +3368,8 @@ static inline void expr_set_span(Expr *expr, SourceSpan loc) expr_set_span(expr->make_any_expr.typeid, loc); return; case EXPR_SPLAT: + case EXPR_PTR_ACCESS: + case EXPR_VECTOR_FROM_ARRAY: expr_set_span(expr->inner_expr, loc); return; case EXPR_EXPRESSION_LIST: @@ -3437,7 +3439,6 @@ static inline void expr_set_span(Expr *expr, SourceSpan loc) case EXPR_DEFAULT_ARG: case EXPR_TYPECALL: case EXPR_MEMBER_GET: - case EXPR_PTR_ACCESS: case EXPR_RVALUE: break; } diff --git a/src/compiler/copying.c b/src/compiler/copying.c index cbabdcb08..6b667557b 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -476,6 +476,7 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr) case EXPR_SPLAT: case EXPR_STRINGIFY: case EXPR_PTR_ACCESS: + case EXPR_VECTOR_FROM_ARRAY: case EXPR_RVALUE: MACRO_COPY_EXPR(expr->inner_expr); return expr; diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 0ce25bb40..1e9f238e8 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -538,7 +538,6 @@ typedef enum typedef enum { CAST_APTSA, - CAST_ARRVEC, CAST_BOOLBOOL, CAST_BOOLFP, CAST_BSINTARR, @@ -558,7 +557,6 @@ typedef enum CAST_PTRBOOL, CAST_PTRINT, CAST_SLBOOL, - CAST_SLSL, CAST_SLARR, CAST_STINLINE, CAST_VECARR, @@ -816,6 +814,7 @@ typedef enum EXPR_TYPEINFO, EXPR_UNARY, EXPR_VASPLAT, + EXPR_VECTOR_FROM_ARRAY, EXPR_EXT_TRUNC, EXPR_INT_TO_BOOL, EXPR_LAST = EXPR_VASPLAT diff --git a/src/compiler/expr.c b/src/compiler/expr.c index d24765f89..660272009 100644 --- a/src/compiler/expr.c +++ b/src/compiler/expr.c @@ -82,6 +82,7 @@ bool expr_may_addr(Expr *expr) return true; case EXPR_BENCHMARK_HOOK: case EXPR_TEST_HOOK: + case EXPR_VECTOR_FROM_ARRAY: case EXPR_PTR_ACCESS: case EXPR_RVALUE: return false; @@ -191,6 +192,7 @@ bool expr_is_runtime_const(Expr *expr) case EXPR_COND: case EXPR_PTR_ACCESS: return false; + case EXPR_VECTOR_FROM_ARRAY: case EXPR_RVALUE: return expr_is_runtime_const(expr->inner_expr); case EXPR_MAKE_ANY: @@ -361,11 +363,9 @@ static inline bool expr_cast_is_runtime_const(Expr *expr) case CAST_SLBOOL: case CAST_STINLINE: case CAST_VECARR: - case CAST_ARRVEC: return exprid_is_runtime_const(expr->cast_expr.expr); case CAST_INTPTR: case CAST_APTSA: - case CAST_SLSL: case CAST_VOID: case CAST_ERPTR: case CAST_IDPTR: @@ -610,6 +610,7 @@ bool expr_is_pure(Expr *expr) case EXPR_MAKE_ANY: return expr_is_pure(expr->make_any_expr.inner) && expr_is_pure(expr->make_any_expr.typeid); case EXPR_PTR_ACCESS: + case EXPR_VECTOR_FROM_ARRAY: case EXPR_RVALUE: return expr_is_pure(expr->inner_expr); case EXPR_INT_TO_BOOL: diff --git a/src/compiler/json_output.c b/src/compiler/json_output.c index 47c652c8e..544f8c6ac 100644 --- a/src/compiler/json_output.c +++ b/src/compiler/json_output.c @@ -258,6 +258,8 @@ void print_var_expr(FILE *file, Expr *expr) print_var_expr(file, expr->access_expr.parent); fputs(")", file); break; + case EXPR_VECTOR_FROM_ARRAY: + TODO case EXPR_PTR_ACCESS: print_var_expr(file, expr->access_expr.parent); fputs(".ptr", file); diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 3cd1cbcdf..66b5b1a80 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -1279,17 +1279,6 @@ void llvm_emit_vector_to_array_cast(GenContext *c, BEValue *value, Type *to_type llvm_value_set(value, array, to_type); } -void llvm_emit_array_to_vector_cast(GenContext *c, BEValue *value, Type *to_type, Type *from_type) -{ - llvm_value_rvalue(c, value); - LLVMValueRef vector = llvm_get_undef(c, to_type); - for (unsigned i = 0; i < to_type->array.len; i++) - { - LLVMValueRef element = llvm_emit_extract_value(c, value->value, i); - vector = llvm_emit_insert_value(c, vector, element, i); - } - llvm_value_set(value, vector, to_type); -} void llvm_emit_slice_to_vec_array_cast(GenContext *c, BEValue *value, Type *to_type, Type *from_type) @@ -1449,9 +1438,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu case CAST_EXPVEC: llvm_emit_expand_to_vec_cast(c, value, to_type, from_type); return; - case CAST_ARRVEC: - llvm_emit_array_to_vector_cast(c, value, to_type, from_type); - return; case CAST_VOID: UNREACHABLE; case CAST_ERROR: @@ -1530,9 +1516,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu llvm_value_rvalue(c, value); value->value = LLVMBuildIntToPtr(c->builder, value->value, llvm_get_type(c, to_type), "intptr"); break; - case CAST_SLSL: - // Improve this - break; case CAST_STINLINE: llvm_value_addr(c, value); value->type = to_type; @@ -7270,6 +7253,28 @@ static void llvm_emit_int_to_bool(GenContext *c, BEValue *value, Expr *expr) expr->type); } +static void llvm_emit_vector_from_array(GenContext *c, BEValue *value, Expr *expr) +{ + Expr *inner = expr->inner_expr; + llvm_emit_expr(c, value, inner); + llvm_value_fold_optional(c, value); + + Type *to_type = type_lowering(expr->type); + if (llvm_value_is_addr(value)) + { + // Unaligned load + value->type = to_type; + llvm_value_rvalue(c, value); + return; + } + LLVMValueRef vector = llvm_get_undef(c, to_type); + for (unsigned i = 0; i < to_type->array.len; i++) + { + LLVMValueRef element = llvm_emit_extract_value(c, value->value, i); + vector = llvm_emit_insert_value(c, vector, element, i); + } + llvm_value_set(value, vector, to_type); +} static void llvm_emit_ptr_access(GenContext *c, BEValue *value, Expr *expr) { llvm_emit_expr(c, value, expr->inner_expr); @@ -7334,6 +7339,9 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr) llvm_value_rvalue(c, value); value->type = type_lowering(expr->type); return; + case EXPR_VECTOR_FROM_ARRAY: + llvm_emit_vector_from_array(c, value, expr); + return; case EXPR_PTR_ACCESS: llvm_emit_ptr_access(c, value, expr); return; diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index a131aecf1..027504918 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -1989,7 +1989,7 @@ static void cast_slice_to_slice(SemaContext *context, Expr *expr, Type *to_type) expr->type = to_type; return; } - insert_runtime_cast(expr, CAST_SLSL, to_type); + expr_rewrite_rvalue(expr, to_type); } static void cast_vecarr_to_slice(SemaContext *context, Expr *expr, Type *to_type) @@ -2100,7 +2100,10 @@ static void cast_arr_to_vec(SemaContext *context, Expr *expr, Type *to_type) } else { - insert_runtime_cast(expr, CAST_ARRVEC, to_temp); + Expr *inner = expr_copy(expr); + expr->expr_kind = EXPR_VECTOR_FROM_ARRAY; + expr->inner_expr = inner; + expr->type = to_temp; } if (to_temp != to_type) { diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 99b222abe..1dc26a269 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -571,6 +571,7 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp case EXPR_MEMBER_GET: case EXPR_NAMED_ARGUMENT: case EXPR_PTR_ACCESS: + case EXPR_VECTOR_FROM_ARRAY: case EXPR_RVALUE: case EXPR_MAKE_ANY: goto ERR; @@ -601,6 +602,7 @@ static bool expr_may_ref(Expr *expr) case EXPR_MEMBER_GET: case EXPR_EXT_TRUNC: case EXPR_PTR_ACCESS: + case EXPR_VECTOR_FROM_ARRAY: case EXPR_INT_TO_BOOL: case EXPR_RVALUE: return false; @@ -8969,6 +8971,7 @@ static inline bool sema_expr_analyse_ct_defined(SemaContext *context, Expr *expr case EXPR_EXT_TRUNC: case EXPR_INT_TO_BOOL: case EXPR_PTR_ACCESS: + case EXPR_VECTOR_FROM_ARRAY: case EXPR_RVALUE: case EXPR_MAKE_ANY: if (!sema_analyse_expr(active_context, main_expr)) goto FAIL; @@ -9359,6 +9362,7 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr, case EXPR_RVALUE: return sema_analyse_expr(context, expr->inner_expr); case EXPR_PTR_ACCESS: + case EXPR_VECTOR_FROM_ARRAY: return sema_analyse_expr(context, expr->inner_expr); case EXPR_INT_TO_BOOL: return sema_analyse_expr(context, expr->int_to_bool_expr.inner); diff --git a/src/compiler/sema_liveness.c b/src/compiler/sema_liveness.c index b6b7b8d7c..43c809041 100644 --- a/src/compiler/sema_liveness.c +++ b/src/compiler/sema_liveness.c @@ -330,6 +330,7 @@ RETRY: case EXPR_RETHROW: case EXPR_OPTIONAL: case EXPR_PTR_ACCESS: + case EXPR_VECTOR_FROM_ARRAY: case EXPR_RVALUE: expr = expr->inner_expr; goto RETRY; diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 3d86db9d7..eaa809cf5 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -763,6 +763,7 @@ static inline bool sema_expr_valid_try_expression(Expr *expr) case EXPR_EXT_TRUNC: case EXPR_INT_TO_BOOL: case EXPR_PTR_ACCESS: + case EXPR_VECTOR_FROM_ARRAY: case EXPR_RVALUE: return true; } diff --git a/test/test_suite/slices/slice_init.c3t b/test/test_suite/slices/slice_init.c3t index 455037f69..3a56d4d68 100644 --- a/test/test_suite/slices/slice_init.c3t +++ b/test/test_suite/slices/slice_init.c3t @@ -25,21 +25,13 @@ entry: %0 = insertvalue %"float[]" undef, ptr %ptradd, 0 %1 = insertvalue %"float[]" %0, i64 4, 1 %2 = extractvalue %"float[]" %1, 0 - %3 = load [4 x float], ptr %2, align 4 - %4 = extractvalue [4 x float] %3, 0 - %5 = insertelement <4 x float> undef, float %4, i64 0 - %6 = extractvalue [4 x float] %3, 1 - %7 = insertelement <4 x float> %5, float %6, i64 1 - %8 = extractvalue [4 x float] %3, 2 - %9 = insertelement <4 x float> %7, float %8, i64 2 - %10 = extractvalue [4 x float] %3, 3 - %11 = insertelement <4 x float> %9, float %10, i64 3 - store <4 x float> %11, ptr %x, align 16 + %3 = load <4 x float>, ptr %2, align 4 + store <4 x float> %3, ptr %x, align 16 call void @foo.get(ptr sret([20 x float]) align 4 %sretparam1) %ptradd2 = getelementptr inbounds i8, ptr %sretparam1, i64 8 - %12 = insertvalue %"float[]" undef, ptr %ptradd2, 0 - %13 = insertvalue %"float[]" %12, i64 4, 1 - %14 = extractvalue %"float[]" %13, 0 - call void @llvm.memcpy.p0.p0.i32(ptr align 16 %y, ptr align 4 %14, i32 16, i1 false) + %4 = insertvalue %"float[]" undef, ptr %ptradd2, 0 + %5 = insertvalue %"float[]" %4, i64 4, 1 + %6 = extractvalue %"float[]" %5, 0 + call void @llvm.memcpy.p0.p0.i32(ptr align 16 %y, ptr align 4 %6, i32 16, i1 false) ret void } diff --git a/test/test_suite/vector/vector_to_array_cast.c3t b/test/test_suite/vector/vector_to_array_cast.c3t index bf46f3753..ce6044389 100644 --- a/test/test_suite/vector/vector_to_array_cast.c3t +++ b/test/test_suite/vector/vector_to_array_cast.c3t @@ -30,18 +30,10 @@ entry: %3 = extractelement <2 x i32> %0, i64 1 %4 = insertvalue [2 x i32] %2, i32 %3, 1 store [2 x i32] %4, ptr %y, align 4 - %5 = load [2 x i32], ptr %y, align 4 - %6 = extractvalue [2 x i32] %5, 0 - %7 = insertelement <2 x i32> undef, i32 %6, i64 0 - %8 = extractvalue [2 x i32] %5, 1 - %9 = insertelement <2 x i32> %7, i32 %8, i64 1 - %sifp = sitofp <2 x i32> %9 to <2 x double> + %5 = load <2 x i32>, ptr %y, align 4 + %sifp = sitofp <2 x i32> %5 to <2 x double> store <2 x double> %sifp, ptr %zz, align 16 - %10 = load [2 x i32], ptr %y, align 4 - %11 = extractvalue [2 x i32] %10, 0 - %12 = insertelement <2 x i32> undef, i32 %11, i64 0 - %13 = extractvalue [2 x i32] %10, 1 - %14 = insertelement <2 x i32> %12, i32 %13, i64 1 - store <2 x i32> %14, ptr %x, align 8 + %6 = load <2 x i32>, ptr %y, align 4 + store <2 x i32> %6, ptr %x, align 8 ret void }