Skip to content

Commit

Permalink
Refactor vector->array scalar->vector and slice->array casts to expre…
Browse files Browse the repository at this point in the history
…ssions.
  • Loading branch information
lerno committed Jan 5, 2025
1 parent 8612476 commit 8fd119e
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 71 deletions.
3 changes: 3 additions & 0 deletions src/compiler/c_codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/compiler_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/copying.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -546,9 +546,6 @@ typedef enum
CAST_BSBOOL,
CAST_ERROR,
CAST_EUER,
CAST_SLARR,
CAST_VECARR,
CAST_EXPVEC,
} CastKind;

typedef enum
Expand Down Expand Up @@ -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,
Expand Down
14 changes: 9 additions & 5 deletions src/compiler/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

}
Expand Down Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/json_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
121 changes: 61 additions & 60 deletions src/compiler/llvm_codegen_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
20 changes: 17 additions & 3 deletions src/compiler/sema_casts.c
Original file line number Diff line number Diff line change
Expand Up @@ -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); }
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down
12 changes: 12 additions & 0 deletions src/compiler/sema_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/sema_liveness.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,9 @@ static void sema_trace_expr_liveness(Expr *expr)
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:
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/sema_stmts.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 8fd119e

Please sign in to comment.