diff --git a/src/compiler/c_codegen.c b/src/compiler/c_codegen.c index 03a5d7060..5a0c66575 100644 --- a/src/compiler/c_codegen.c +++ b/src/compiler/c_codegen.c @@ -395,6 +395,9 @@ static void c_emit_expr(GenContext *c, CValue *value, Expr *expr) { switch (expr->expr_kind) { + case EXPR_VECTOR_TO_ARRAY: + case EXPR_SLICE_TO_VEC_ARRAY: + case EXPR_SCALAR_TO_VECTOR: case EXPR_ENUM_FROM_ORD: case EXPR_PTR_ACCESS: case EXPR_INT_TO_FLOAT: diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 6aa1dc040..4be412de4 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -3371,6 +3371,9 @@ static inline void expr_set_span(Expr *expr, SourceSpan loc) return; case EXPR_SPLAT: case EXPR_PTR_ACCESS: + case EXPR_VECTOR_TO_ARRAY: + case EXPR_SLICE_TO_VEC_ARRAY: + case EXPR_SCALAR_TO_VECTOR: case EXPR_ENUM_FROM_ORD: case EXPR_INT_TO_FLOAT: case EXPR_INT_TO_PTR: diff --git a/src/compiler/copying.c b/src/compiler/copying.c index 5cc727091..b053bdf01 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -476,6 +476,9 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr) case EXPR_SPLAT: case EXPR_STRINGIFY: case EXPR_PTR_ACCESS: + case EXPR_VECTOR_TO_ARRAY: + case EXPR_SLICE_TO_VEC_ARRAY: + case EXPR_SCALAR_TO_VECTOR: case EXPR_ENUM_FROM_ORD: case EXPR_INT_TO_FLOAT: case EXPR_INT_TO_PTR: diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 319316e3f..53f3e49e3 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -546,9 +546,6 @@ typedef enum CAST_BSBOOL, CAST_ERROR, CAST_EUER, - CAST_SLARR, - CAST_VECARR, - CAST_EXPVEC, } CastKind; typedef enum @@ -757,6 +754,9 @@ typedef enum EXPR_DESIGNATOR, EXPR_DISCARD, EXPR_EMBED, + EXPR_VECTOR_TO_ARRAY, + EXPR_SLICE_TO_VEC_ARRAY, + EXPR_SCALAR_TO_VECTOR, EXPR_EXPRESSION_LIST, EXPR_EXPR_BLOCK, EXPR_FORCE_UNWRAP, diff --git a/src/compiler/expr.c b/src/compiler/expr.c index 4746f760f..cfa27c99a 100644 --- a/src/compiler/expr.c +++ b/src/compiler/expr.c @@ -83,6 +83,9 @@ bool expr_may_addr(Expr *expr) case EXPR_BENCHMARK_HOOK: case EXPR_TEST_HOOK: case EXPR_VECTOR_FROM_ARRAY: + case EXPR_VECTOR_TO_ARRAY: + case EXPR_SLICE_TO_VEC_ARRAY: + case EXPR_SCALAR_TO_VECTOR: case EXPR_PTR_ACCESS: case EXPR_ENUM_FROM_ORD: case EXPR_FLOAT_TO_INT: @@ -212,6 +215,9 @@ bool expr_is_runtime_const(Expr *expr) case EXPR_INT_TO_PTR: case EXPR_PTR_TO_INT: case EXPR_ENUM_FROM_ORD: + case EXPR_VECTOR_TO_ARRAY: + case EXPR_SLICE_TO_VEC_ARRAY: + case EXPR_SCALAR_TO_VECTOR: return expr_is_runtime_const(expr->inner_expr); case EXPR_MAKE_ANY: if (!expr_is_runtime_const(expr->make_any_expr.typeid)) return false; @@ -366,13 +372,8 @@ static inline bool expr_cast_is_runtime_const(Expr *expr) case CAST_ERROR: UNREACHABLE case CAST_EUER: - case CAST_VECARR: - return exprid_is_runtime_const(expr->cast_expr.expr); case CAST_APTSA: - case CAST_EXPVEC: - return exprid_is_runtime_const(expr->cast_expr.expr); case CAST_BSBOOL: - case CAST_SLARR: return exprid_is_runtime_const(expr->cast_expr.expr); } @@ -607,6 +608,9 @@ 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_TO_ARRAY: + case EXPR_SLICE_TO_VEC_ARRAY: + case EXPR_SCALAR_TO_VECTOR: case EXPR_ENUM_FROM_ORD: case EXPR_INT_TO_FLOAT: case EXPR_INT_TO_PTR: diff --git a/src/compiler/json_output.c b/src/compiler/json_output.c index 92173453a..89d08fafa 100644 --- a/src/compiler/json_output.c +++ b/src/compiler/json_output.c @@ -277,6 +277,9 @@ void print_var_expr(FILE *file, Expr *expr) case EXPR_INT_TO_PTR: case EXPR_PTR_TO_INT: case EXPR_ENUM_FROM_ORD: + case EXPR_VECTOR_TO_ARRAY: + case EXPR_SLICE_TO_VEC_ARRAY: + case EXPR_SCALAR_TO_VECTOR: TODO break; case EXPR_PTR_ACCESS: diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 18e176380..1e473e3d0 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -1284,46 +1284,6 @@ static void llvm_emit_arr_to_slice_cast(GenContext *c, BEValue *value, Type *to_ } -void llvm_emit_vector_to_array_cast(GenContext *c, BEValue *value, Type *to_type, Type *from_type) -{ - llvm_value_rvalue(c, value); - LLVMValueRef array = 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); - array = llvm_emit_insert_value(c, array, element, i); - } - llvm_value_set(value, array, to_type); -} - - - -void llvm_emit_slice_to_vec_array_cast(GenContext *c, BEValue *value, Type *to_type, Type *from_type) -{ - BEValue pointer; - Type *base = type_lowering(from_type)->array.base; - AlignSize element_alignment = type_abi_alignment(base); - llvm_emit_slice_pointer(c, value, &pointer); - llvm_value_rvalue(c, &pointer); - LLVMTypeRef type = llvm_get_type(c, to_type); - AlignSize alignment = llvm_abi_alignment(c, type); - LLVMValueRef temp = llvm_emit_alloca(c, type, alignment, ".temp"); - llvm_emit_memcpy(c, temp, alignment, pointer.value, element_alignment, llvm_abi_size(c, type)); - llvm_value_set_address(value, temp, to_type, alignment); -} - -void llvm_emit_expand_to_vec_cast(GenContext *c, BEValue *value, Type *to_type, Type *from_type) -{ - llvm_value_rvalue(c, value); - LLVMTypeRef type = llvm_get_type(c, to_type); - unsigned elements = LLVMGetVectorSize(type); - LLVMValueRef res = LLVMGetUndef(type); - for (unsigned i = 0; i < elements; i++) - { - res = LLVMBuildInsertElement(c->builder, res, value->value, llvm_const_int(c, type_usz, i), ""); - } - llvm_value_set(value, res, to_type); -} // Prune the common occurrence where the optional is not used. @@ -1449,20 +1409,11 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu case CAST_BSBOOL: llvm_emit_bitstruct_to_bool(c, value, to_type, from_type); return; - case CAST_SLARR: - llvm_emit_slice_to_vec_array_cast(c, value, to_type, from_type); - return; - case CAST_EXPVEC: - llvm_emit_expand_to_vec_cast(c, value, to_type, from_type); - return; case CAST_ERROR: UNREACHABLE case CAST_APTSA: llvm_emit_arr_to_slice_cast(c, value, to_type); break; - case CAST_VECARR: - llvm_emit_vector_to_array_cast(c, value, to_type, from_type); - break; case CAST_EUER: REMINDER("Improve fault to err comparison"); break; @@ -1560,16 +1511,6 @@ void llvm_emit_bool_cast(GenContext *c, Expr *expr, BEValue *value) UNREACHABLE } -static inline void llvm_emit_cast_expr(GenContext *context, BEValue *be_value, Expr *expr) -{ - llvm_emit_exprid(context, be_value, expr->cast_expr.expr); - llvm_emit_cast(context, - expr->cast_expr.kind, - expr, - be_value, - expr->type, - exprtype(expr->cast_expr.expr)); -} static LLVMValueRef llvm_recursive_set_value(GenContext *c, DesignatorElement **current_element_ptr, LLVMValueRef parent, DesignatorElement **last_element_ptr, Expr *value) @@ -7238,6 +7179,51 @@ void llvm_emit_enum_from_ord(GenContext *c, BEValue *value, Expr *expr) value->type = type_lowering(to_type); } +void llvm_emit_scalar_to_vector(GenContext *c, BEValue *value, Expr *expr) +{ + llvm_emit_expr(c, value, expr->inner_expr); + llvm_value_rvalue(c, value); + LLVMTypeRef type = llvm_get_type(c, expr->type); + unsigned elements = LLVMGetVectorSize(type); + LLVMValueRef res = LLVMGetUndef(type); + for (unsigned i = 0; i < elements; i++) + { + res = LLVMBuildInsertElement(c->builder, res, value->value, llvm_const_int(c, type_usz, i), ""); + } + llvm_value_set(value, res, expr->type); +} + +static inline void llvm_emit_vector_to_array(GenContext *c, BEValue *value, Expr *expr) +{ + llvm_emit_expr(c, value, expr->inner_expr); + llvm_value_rvalue(c, value); + Type *to_type = type_lowering(expr->type); + LLVMValueRef array = 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); + array = llvm_emit_insert_value(c, array, element, i); + } + llvm_value_set(value, array, to_type); +} + +void llvm_emit_slice_to_vec_array(GenContext *c, BEValue *value, Expr *expr) +{ + llvm_emit_expr(c, value, expr->inner_expr); + llvm_value_rvalue(c, value); + BEValue pointer; + Type *base = value->type->array.base; + AlignSize element_alignment = type_abi_alignment(base); + llvm_emit_slice_pointer(c, value, &pointer); + llvm_value_rvalue(c, &pointer); + Type *to_type = type_lowering(expr->type); + LLVMTypeRef type = llvm_get_type(c, to_type); + AlignSize alignment = llvm_abi_alignment(c, type); + LLVMValueRef temp = llvm_emit_alloca(c, type, alignment, ".temp"); + llvm_emit_memcpy(c, temp, alignment, pointer.value, element_alignment, llvm_abi_size(c, type)); + llvm_value_set_address(value, temp, to_type, alignment); +} + void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr) { EMIT_EXPR_LOC(c, expr); @@ -7256,6 +7242,15 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr) case EXPR_MEMBER_GET: case EXPR_NAMED_ARGUMENT: UNREACHABLE + case EXPR_VECTOR_TO_ARRAY: + llvm_emit_vector_to_array(c, value, expr); + return; + case EXPR_SLICE_TO_VEC_ARRAY: + llvm_emit_slice_to_vec_array(c, value, expr); + return; + case EXPR_SCALAR_TO_VECTOR: + llvm_emit_scalar_to_vector(c, value, expr); + return; case EXPR_ENUM_FROM_ORD: llvm_emit_enum_from_ord(c, value, expr); return; @@ -7451,7 +7446,13 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr) llvm_emit_expression_list_expr(c, value, expr); return; case EXPR_CAST: - llvm_emit_cast_expr(c, value, expr); + llvm_emit_exprid(c, value, expr->cast_expr.expr); + llvm_emit_cast(c, + expr->cast_expr.kind, + expr, + value, + expr->type, + exprtype(expr->cast_expr.expr)); return; case EXPR_BITACCESS: llvm_emit_bitaccess(c, value, expr); diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index c059bb7a7..ab6f6253a 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -1623,7 +1623,11 @@ static void cast_expand_to_vec(SemaContext *context, Expr *expr, Type *type) // Fold pointer casts if narrowing Type *base = type_get_indexed_type(type); cast_no_check(context, expr, base, IS_OPTIONAL(expr)); - insert_runtime_cast(expr, CAST_EXPVEC, type); + Expr *inner = expr_copy(expr); + expr->expr_kind = EXPR_SCALAR_TO_VECTOR; + expr->inner_expr = inner; + expr->type = type; + expr->resolve_status = RESOLVE_DONE; } static void cast_bitstruct_to_int_arr(SemaContext *context, Expr *expr, Type *type) { expr_rewrite_recast(expr, type); } @@ -1693,7 +1697,14 @@ static void cast_enum_to_int(SemaContext *context, Expr* expr, Type *to_type) */ static void cast_vec_to_arr(SemaContext *context, Expr *expr, Type *to_type) { - if (insert_runtime_cast_unless_const(expr, CAST_VECARR, to_type)) return; + if (!sema_cast_const(expr)) + { + expr->inner_expr = expr_copy(expr); + expr->expr_kind = EXPR_VECTOR_TO_ARRAY; + expr->type = to_type; + expr->resolve_status = RESOLVE_DONE; + return; + } ASSERT0(expr->const_expr.const_kind == CONST_INITIALIZER); ConstInitializer *list = expr->const_expr.initializer; @@ -2070,7 +2081,10 @@ static void cast_slice_to_vecarr(SemaContext *context, Expr *expr, Type *to_type } case EXPR_SLICE: { - insert_runtime_cast(expr, CAST_SLARR, to_type); + expr->inner_expr = expr_copy(expr); + expr->expr_kind = EXPR_SLICE_TO_VEC_ARRAY; + expr->type = to_type; + expr->resolve_status = RESOLVE_DONE; return; } default: diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index ce562186c..3908a5555 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -583,6 +583,9 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp case EXPR_TYPEINFO: case EXPR_VASPLAT: case EXPR_VECTOR_FROM_ARRAY: + case EXPR_VECTOR_TO_ARRAY: + case EXPR_SLICE_TO_VEC_ARRAY: + case EXPR_SCALAR_TO_VECTOR: goto ERR; } UNREACHABLE @@ -611,6 +614,9 @@ static bool expr_may_ref(Expr *expr) case EXPR_MEMBER_GET: case EXPR_EXT_TRUNC: case EXPR_PTR_ACCESS: + case EXPR_VECTOR_TO_ARRAY: + case EXPR_SLICE_TO_VEC_ARRAY: + case EXPR_SCALAR_TO_VECTOR: case EXPR_ENUM_FROM_ORD: case EXPR_FLOAT_TO_INT: case EXPR_INT_TO_FLOAT: @@ -8991,6 +8997,9 @@ static inline bool sema_expr_analyse_ct_defined(SemaContext *context, Expr *expr case EXPR_SPLAT: case EXPR_EXT_TRUNC: case EXPR_INT_TO_BOOL: + case EXPR_VECTOR_TO_ARRAY: + case EXPR_SLICE_TO_VEC_ARRAY: + case EXPR_SCALAR_TO_VECTOR: case EXPR_PTR_ACCESS: case EXPR_ENUM_FROM_ORD: case EXPR_SLICE_LEN: @@ -9390,6 +9399,9 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr, case EXPR_INT_TO_PTR: case EXPR_PTR_TO_INT: case EXPR_ENUM_FROM_ORD: + case EXPR_VECTOR_TO_ARRAY: + case EXPR_SLICE_TO_VEC_ARRAY: + case EXPR_SCALAR_TO_VECTOR: UNREACHABLE case EXPR_MAKE_ANY: if (!sema_analyse_expr(context, expr->make_any_expr.typeid)) return false; diff --git a/src/compiler/sema_liveness.c b/src/compiler/sema_liveness.c index 28ac40607..b00a562c6 100644 --- a/src/compiler/sema_liveness.c +++ b/src/compiler/sema_liveness.c @@ -329,6 +329,9 @@ RETRY: case EXPR_FORCE_UNWRAP: case EXPR_RETHROW: case EXPR_OPTIONAL: + case EXPR_VECTOR_TO_ARRAY: + case EXPR_SLICE_TO_VEC_ARRAY: + case EXPR_SCALAR_TO_VECTOR: case EXPR_PTR_ACCESS: case EXPR_ENUM_FROM_ORD: case EXPR_FLOAT_TO_INT: diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 7512198c4..c175ee931 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -764,6 +764,9 @@ static inline bool sema_expr_valid_try_expression(Expr *expr) case EXPR_DEFAULT_ARG: case EXPR_EXT_TRUNC: case EXPR_INT_TO_BOOL: + case EXPR_VECTOR_TO_ARRAY: + case EXPR_SLICE_TO_VEC_ARRAY: + case EXPR_SCALAR_TO_VECTOR: case EXPR_PTR_ACCESS: case EXPR_FLOAT_TO_INT: case EXPR_INT_TO_FLOAT: