mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Refactor vector->array scalar->vector and slice->array casts to expressions.
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user